diff --git a/Documentation/devicetree/bindings/display/bridge/renesas,r8a779g0-dsc.yaml b/Documentation/devicetree/bindings/display/bridge/renesas,r8a779g0-dsc.yaml new file mode 100644 index 000000000000..6ce2444409a2 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/renesas,r8a779g0-dsc.yaml @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/renesas,r8a779g0-dsc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Renesas R-Car DSC Display Stream Compression + +maintainers: + - Marek Vasut + +description: | + This binding describes the VESA DSC Display Stream Compression encoder + embedded in the Renesas R-Car V4H SoC. The encoder supports all DSC1.1 + encoding mechanisms, configurable bits-per-pixel, resolution up to 8k. + +properties: + compatible: + const: renesas,r8a779g0-dsc + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + interrupts: + maxItems: 1 + + power-domains: + maxItems: 1 + + resets: + maxItems: 1 + + ports: + $ref: /schemas/graph.yaml#/properties/ports + + properties: + port@0: + $ref: /schemas/graph.yaml#/properties/port + description: R-Car DU input port + + port@1: + $ref: /schemas/graph.yaml#/properties/port + description: R-Car DSI output port + + required: + - port@0 + - port@1 + +required: + - compatible + - reg + - clocks + - interrupts + - power-domains + - resets + - ports + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + + bridge@feb8d000 { + compatible = "renesas,r8a779g0-dsc"; + reg = <0xfeb8d000 0x400>; + interrupts = ; + clocks = <&cpg CPG_MOD 2819>; + power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; + resets = <&cpg 2819>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dsc_in_dsi1: endpoint { + remote-endpoint = <&du_out_dsi1>; + }; + }; + + port@1 { + reg = <1>; + dsc_out_dsi1: endpoint { + remote-endpoint = <&dsi1_in>; + }; + }; + }; + }; +... diff --git a/Documentation/devicetree/bindings/display/solomon,ssd1351.yaml b/Documentation/devicetree/bindings/display/solomon,ssd1351.yaml new file mode 100644 index 000000000000..80850c2ab5b3 --- /dev/null +++ b/Documentation/devicetree/bindings/display/solomon,ssd1351.yaml @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/solomon,ssd1351.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Solomon SSD1351 OLED Display Controller + +maintainers: + - Amit Barzilai + - Javier Martinez Canillas + +allOf: + - $ref: solomon,ssd-common.yaml# + +properties: + compatible: + enum: + - solomon,ssd1351 + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + #include + + spi { + #address-cells = <1>; + #size-cells = <0>; + + oled@0 { + compatible = "solomon,ssd1351"; + reg = <0x0>; + reset-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>; + dc-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>; + spi-max-frequency = <10000000>; + }; + }; diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst index 94cfc26acecc..400cd0112713 100644 --- a/Documentation/gpu/drm-kms-helpers.rst +++ b/Documentation/gpu/drm-kms-helpers.rst @@ -118,12 +118,21 @@ fbdev Helper Functions Reference .. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c :export: -format Helper Functions Reference +Draw Helper Functions Reference ================================= +Format-Conversion Helper Reference +---------------------------------- + .. kernel-doc:: drivers/gpu/drm/drm_format_helper.c :export: +Panic Helper Reference +---------------------- + +.. kernel-doc:: drivers/gpu/drm/drm_panic_helper.c + :export: + Framebuffer DMA Helper Functions Reference ========================================== diff --git a/Documentation/gpu/drm-kms.rst b/Documentation/gpu/drm-kms.rst index 0dd440a14946..8988fd64369b 100644 --- a/Documentation/gpu/drm-kms.rst +++ b/Documentation/gpu/drm-kms.rst @@ -421,6 +421,9 @@ Plane Panic Functions Reference .. kernel-doc:: include/drm/drm_panic.h :internal: +.. kernel-doc:: drivers/gpu/drm/drm_panic_internal.h + :internal: + .. kernel-doc:: drivers/gpu/drm/drm_panic.c :export: diff --git a/MAINTAINERS b/MAINTAINERS index 6abef8f1a59c..63c4c3c1164a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9118,9 +9118,12 @@ S: Supported T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: drivers/gpu/drm/drm_draw.c F: drivers/gpu/drm/drm_draw_internal.h -F: drivers/gpu/drm/drm_panic*.c -F: drivers/gpu/drm/tests/drm_panic_test.c -F: include/drm/drm_panic* +F: drivers/gpu/drm/drm_panic.c +F: drivers/gpu/drm/drm_panic_helper.c +F: drivers/gpu/drm/drm_panic_internal.h +F: drivers/gpu/drm/tests/drm_panic_helper_test.c +F: include/drm/drm_panic.h +F: include/drm/drm_panic_helper.h DRM PANIC QR CODE M: Jocelyn Falempe @@ -9129,7 +9132,7 @@ L: dri-devel@lists.freedesktop.org L: rust-for-linux@vger.kernel.org S: Supported T: git https://gitlab.freedesktop.org/drm/misc/kernel.git -F: drivers/gpu/drm/drm_panic_qr.rs +F: drivers/gpu/drm/drm_panic_helper_qr.rs DRM PRIVACY-SCREEN CLASS M: Hans de Goede diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c index 3f05fa8811af..5a1a2ee261b7 100644 --- a/drivers/accel/amdxdna/amdxdna_gem.c +++ b/drivers/accel/amdxdna/amdxdna_gem.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include "amdxdna_cbuf.h" @@ -490,16 +491,16 @@ static int amdxdna_insert_pages(struct amdxdna_gem_obj *abo, { struct amdxdna_dev *xdna = to_xdna_dev(to_gobj(abo)->dev); unsigned long num_pages = vma_pages(vma); - unsigned long offset = 0; int ret; - if (!is_import_bo(abo)) { - ret = drm_gem_shmem_mmap(&abo->base, vma); - if (ret) { - XDNA_ERR(xdna, "Failed shmem mmap %d", ret); - return ret; - } - } else { + /* + * Until today there is not any use case to mmap with non-zero + * offset. Put an explicit check here. + */ + if (vma->vm_pgoff - drm_vma_node_start(&to_gobj(abo)->vma_node)) + return -EINVAL; + + if (is_import_bo(abo)) { vma->vm_private_data = NULL; vma->vm_ops = NULL; ret = dma_buf_mmap(abo->dma_buf, vma, 0); @@ -508,23 +509,28 @@ static int amdxdna_insert_pages(struct amdxdna_gem_obj *abo, return ret; } + amdxdna_mark_mapp_invalid(abo, vma); + /* Drop the reference drm_gem_mmap_obj() acquired.*/ drm_gem_object_put(to_gobj(abo)); + return 0; } - do { - vm_fault_t fault_ret; + ret = drm_gem_shmem_mmap(&abo->base, vma); + if (ret) { + XDNA_ERR(xdna, "Failed shmem mmap %d", ret); + return ret; + } - fault_ret = handle_mm_fault(vma, vma->vm_start + offset, - FAULT_FLAG_WRITE, NULL); - if (fault_ret & VM_FAULT_ERROR) { - XDNA_ERR(xdna, "Fault in page failed"); - amdxdna_mark_mapp_invalid(abo, vma); - break; - } - - offset += PAGE_SIZE; - } while (--num_pages); + vm_flags_mod(vma, VM_MIXEDMAP, VM_PFNMAP); + ret = vm_insert_pages(vma, vma->vm_start, abo->base.pages, &num_pages); + if (ret) { + XDNA_ERR(xdna, "Failed to insert pages %d", ret); + dma_resv_lock(to_gobj(abo)->resv, NULL); + drm_gem_shmem_put_pages_locked(&abo->base); + dma_resv_unlock(to_gobj(abo)->resv); + return ret; + } return 0; } @@ -536,6 +542,10 @@ static int amdxdna_gem_obj_mmap(struct drm_gem_object *gobj, struct amdxdna_gem_obj *abo = to_xdna_obj(gobj); int ret; + XDNA_DBG(xdna, "BO map_offset 0x%llx type %d userptr 0x%lx size 0x%lx", + drm_vma_node_offset_addr(&gobj->vma_node), abo->type, + vma->vm_start, gobj->size); + ret = amdxdna_hmm_register(abo, vma); if (ret) return ret; @@ -546,9 +556,6 @@ static int amdxdna_gem_obj_mmap(struct drm_gem_object *gobj, goto hmm_unreg; } - XDNA_DBG(xdna, "BO map_offset 0x%llx type %d userptr 0x%lx size 0x%lx", - drm_vma_node_offset_addr(&gobj->vma_node), abo->type, - vma->vm_start, gobj->size); return 0; hmm_unreg: @@ -556,14 +563,99 @@ static int amdxdna_gem_obj_mmap(struct drm_gem_object *gobj, return ret; } +/* + * VM operations for amdxdna shmem VMAs that use VM_MIXEDMAP. + * + * drm_gem_shmem_vm_ops cannot be used on VM_MIXEDMAP VMAs because its fault + * handler calls vmf_insert_pfn() → vmf_insert_pfn_prot() which contains: + * BUG_ON((vma->vm_flags & VM_MIXEDMAP) && pfn_valid(pfn)) + * All amdxdna shmem pages are ordinary struct pages so pfn_valid() is always + * true, making the combination fatal. + * + * These ops use vmf_insert_page() (struct-page based) instead, which is the + * correct API for VM_MIXEDMAP VMAs backed by real struct pages. The open and + * close handlers replicate drm_gem_shmem_vm_open/close using only exported + * symbols. + */ +static vm_fault_t amdxdna_gem_mixedmap_fault(struct vm_fault *vmf) +{ + struct vm_area_struct *vma = vmf->vma; + struct drm_gem_object *gobj = vma->vm_private_data; + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(gobj); + loff_t num_pages = gobj->size >> PAGE_SHIFT; + vm_fault_t ret = VM_FAULT_SIGBUS; + pgoff_t page_offset; + struct page *page; + + /* + * Partial free of vma is unexpected. Otherwise, the wrong page + * will be faulted in and the user application may crash itself. + */ + page_offset = linear_page_delta(vma, vmf->address); + + dma_resv_lock(gobj->resv, NULL); + + if (!shmem->pages || shmem->madv < 0 || page_offset >= num_pages) + goto out; + + page = shmem->pages[page_offset]; + if (WARN_ON_ONCE(!page)) + goto out; + + /* + * Use vmf_insert_page() (struct-page path) not vmf_insert_pfn() + * (PFN path) because this VMA carries VM_MIXEDMAP. + */ + ret = vmf_insert_page(vma, vmf->address, page); + if (ret == VM_FAULT_NOPAGE) + folio_mark_accessed(page_folio(page)); + +out: + dma_resv_unlock(gobj->resv); + return ret; +} + +static void amdxdna_gem_mixedmap_vm_open(struct vm_area_struct *vma) +{ + struct drm_gem_object *gobj = vma->vm_private_data; + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(gobj); + + /* + * Bump pages_use_count so the page array stays alive for the new + * mapping copy created by fork(). Mirrors drm_gem_shmem_vm_open(). + */ + dma_resv_lock(gobj->resv, NULL); + drm_WARN_ON_ONCE(gobj->dev, !refcount_inc_not_zero(&shmem->pages_use_count)); + dma_resv_unlock(gobj->resv); + + drm_gem_vm_open(vma); +} + +static void amdxdna_gem_mixedmap_vm_close(struct vm_area_struct *vma) +{ + struct drm_gem_object *gobj = vma->vm_private_data; + struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(gobj); + + dma_resv_lock(gobj->resv, NULL); + drm_gem_shmem_put_pages_locked(shmem); + dma_resv_unlock(gobj->resv); + + drm_gem_vm_close(vma); +} + +static const struct vm_operations_struct amdxdna_gem_mixedmap_vm_ops = { + .fault = amdxdna_gem_mixedmap_fault, + .open = amdxdna_gem_mixedmap_vm_open, + .close = amdxdna_gem_mixedmap_vm_close, +}; + static int amdxdna_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma) { struct drm_gem_object *gobj = dma_buf->priv; struct amdxdna_gem_obj *abo = to_xdna_obj(gobj); - unsigned long num_pages = vma_pages(vma); int ret; - vma->vm_ops = &drm_gem_shmem_vm_ops; + vma->vm_ops = &amdxdna_gem_mixedmap_vm_ops; vma->vm_private_data = gobj; drm_gem_object_get(gobj); @@ -573,16 +665,9 @@ static int amdxdna_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struc /* The buffer is based on memory pages. Fix the flag. */ vm_flags_mod(vma, VM_MIXEDMAP, VM_PFNMAP); - ret = vm_insert_pages(vma, vma->vm_start, abo->base.pages, - &num_pages); - if (ret) - goto close_vma; return 0; -close_vma: - vma->vm_ops->close(vma); - return ret; put_obj: drm_gem_object_put(gobj); return ret; @@ -641,10 +726,8 @@ amdxdna_gem_skip_bo_usage(struct amdxdna_gem_obj *abo) } static void -amdxdna_gem_add_bo_usage(struct amdxdna_gem_obj *abo) +amdxdna_gem_add_bo_usage(struct amdxdna_client *client, struct amdxdna_gem_obj *abo) { - struct amdxdna_client *client = abo->client; - if (amdxdna_gem_skip_bo_usage(abo)) return; @@ -656,10 +739,8 @@ amdxdna_gem_add_bo_usage(struct amdxdna_gem_obj *abo) } static void -amdxdna_gem_del_bo_usage(struct amdxdna_gem_obj *abo) +amdxdna_gem_del_bo_usage(struct amdxdna_client *client, struct amdxdna_gem_obj *abo) { - struct amdxdna_client *client = abo->client; - if (amdxdna_gem_skip_bo_usage(abo)) return; @@ -694,12 +775,20 @@ static int amdxdna_gem_obj_open(struct drm_gem_object *gobj, struct drm_file *fi { struct amdxdna_dev *xdna = to_xdna_dev(gobj->dev); struct amdxdna_gem_obj *abo = to_xdna_obj(gobj); + struct amdxdna_client *client; int ret; - guard(mutex)(&abo->lock); + mutex_lock(&abo->lock); + if (abo->open_ref > 0 && filp->driver_priv != abo->client) { + mutex_unlock(&abo->lock); + return -EPERM; + } + abo->open_ref++; - if (abo->open_ref > 1) + if (abo->open_ref > 1) { + mutex_unlock(&abo->lock); return 0; + } /* Attached to the client when first opened by it. */ abo->client = filp->driver_priv; @@ -710,26 +799,34 @@ static int amdxdna_gem_obj_open(struct drm_gem_object *gobj, struct drm_file *fi if (ret) { abo->open_ref--; abo->client = NULL; + mutex_unlock(&abo->lock); return ret; } } + client = abo->client; + mutex_unlock(&abo->lock); - amdxdna_gem_add_bo_usage(abo); + amdxdna_gem_add_bo_usage(client, abo); return 0; } static void amdxdna_gem_obj_close(struct drm_gem_object *gobj, struct drm_file *filp) { struct amdxdna_gem_obj *abo = to_xdna_obj(gobj); + struct amdxdna_client *client = NULL; - guard(mutex)(&abo->lock); + mutex_lock(&abo->lock); abo->open_ref--; if (abo->open_ref == 0) { - amdxdna_gem_del_bo_usage(abo); /* Detach from the client when last closed by it. */ + client = abo->client; abo->client = NULL; } + mutex_unlock(&abo->lock); + + if (client) + amdxdna_gem_del_bo_usage(client, abo); } static int amdxdna_gem_obj_vmap(struct drm_gem_object *obj, struct iosys_map *map) @@ -866,7 +963,7 @@ static const struct drm_gem_object_funcs amdxdna_gem_shmem_funcs = { .vmap = amdxdna_gem_obj_vmap, .vunmap = amdxdna_gem_obj_vunmap, .mmap = amdxdna_gem_obj_mmap, - .vm_ops = &drm_gem_shmem_vm_ops, + .vm_ops = &amdxdna_gem_mixedmap_vm_ops, .export = amdxdna_gem_prime_export, }; diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c index 95120957f42a..0f215392d42d 100644 --- a/drivers/accel/ivpu/ivpu_drv.c +++ b/drivers/accel/ivpu/ivpu_drv.c @@ -205,6 +205,7 @@ bool ivpu_is_capable(struct ivpu_device *vdev, u32 capability) case DRM_IVPU_CAP_BO_CREATE_FROM_USERPTR: return true; case DRM_IVPU_CAP_MANAGE_CMDQ: + case DRM_IVPU_CAP_CMDQ_SET_PRIORITY: return vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW; default: return false; @@ -273,6 +274,9 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f case DRM_IVPU_PARAM_PREEMPT_BUFFER_SIZE: args->value = ivpu_fw_preempt_buf_size(vdev); break; + case DRM_IVPU_PARAM_CMDQ_PRIORITY: + ret = ivpu_cmdq_get_priority(file_priv, args->index, &args->value); + break; default: ret = -EINVAL; break; @@ -284,14 +288,23 @@ static int ivpu_get_param_ioctl(struct drm_device *dev, void *data, struct drm_f static int ivpu_set_param_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { + struct ivpu_file_priv *file_priv = file->driver_priv; struct drm_ivpu_param *args = data; int ret = 0; + int idx; + + if (!drm_dev_enter(dev, &idx)) + return -ENODEV; switch (args->param) { + case DRM_IVPU_PARAM_CMDQ_PRIORITY: + ret = ivpu_cmdq_set_priority(file_priv, args->index, args->value); + break; default: ret = -EINVAL; } + drm_dev_exit(idx); return ret; } diff --git a/drivers/accel/ivpu/ivpu_drv.h b/drivers/accel/ivpu/ivpu_drv.h index 8f29f1dc52b9..3b26a64ed04f 100644 --- a/drivers/accel/ivpu/ivpu_drv.h +++ b/drivers/accel/ivpu/ivpu_drv.h @@ -186,6 +186,9 @@ struct ivpu_device { int autosuspend; int d0i3_entry_msg; int state_dump_msg; + int mmu_reg; + int mmu_queue; + int pwr_island_status; } timeout; }; diff --git a/drivers/accel/ivpu/ivpu_hw.c b/drivers/accel/ivpu/ivpu_hw.c index 647dc045c231..47ed9beeb3fb 100644 --- a/drivers/accel/ivpu/ivpu_hw.c +++ b/drivers/accel/ivpu/ivpu_hw.c @@ -99,13 +99,21 @@ static void wa_init(struct ivpu_device *vdev) static void timeouts_init(struct ivpu_device *vdev) { if (ivpu_test_mode & IVPU_TEST_MODE_DISABLE_TIMEOUTS) { + /* in milliseconds, negative value disables the timeout */ vdev->timeout.boot = -1; vdev->timeout.jsm = -1; vdev->timeout.tdr = -1; vdev->timeout.inference = -1; vdev->timeout.autosuspend = -1; vdev->timeout.d0i3_entry_msg = -1; + /* fixed delay, not a timeout - has to remain finite */ + vdev->timeout.state_dump_msg = 100; + /* in microseconds, zero disables the timeout */ + vdev->timeout.mmu_reg = 0; + vdev->timeout.mmu_queue = 0; + vdev->timeout.pwr_island_status = 0; } else if (ivpu_is_fpga(vdev)) { + /* in milliseconds */ vdev->timeout.boot = 50; vdev->timeout.jsm = 15000; vdev->timeout.tdr = 30000; @@ -113,7 +121,12 @@ static void timeouts_init(struct ivpu_device *vdev) vdev->timeout.autosuspend = -1; vdev->timeout.d0i3_entry_msg = 500; vdev->timeout.state_dump_msg = 10000; + /* in microseconds */ + vdev->timeout.mmu_reg = 100 * USEC_PER_MSEC; + vdev->timeout.mmu_queue = 1000 * USEC_PER_MSEC; + vdev->timeout.pwr_island_status = 5 * USEC_PER_MSEC; } else if (ivpu_is_simics(vdev)) { + /* in milliseconds */ vdev->timeout.boot = 50; vdev->timeout.jsm = 500; vdev->timeout.tdr = 10000; @@ -121,7 +134,12 @@ static void timeouts_init(struct ivpu_device *vdev) vdev->timeout.autosuspend = 100; vdev->timeout.d0i3_entry_msg = 100; vdev->timeout.state_dump_msg = 10; + /* in microseconds */ + vdev->timeout.mmu_reg = 10 * USEC_PER_MSEC; + vdev->timeout.mmu_queue = 100 * USEC_PER_MSEC; + vdev->timeout.pwr_island_status = 5 * USEC_PER_MSEC; } else { + /* in milliseconds */ vdev->timeout.boot = 1000; vdev->timeout.jsm = 500; vdev->timeout.tdr = 2000; @@ -132,6 +150,10 @@ static void timeouts_init(struct ivpu_device *vdev) vdev->timeout.autosuspend = 100; vdev->timeout.d0i3_entry_msg = 5; vdev->timeout.state_dump_msg = 100; + /* in microseconds */ + vdev->timeout.mmu_reg = 10 * USEC_PER_MSEC; + vdev->timeout.mmu_queue = 100 * USEC_PER_MSEC; + vdev->timeout.pwr_island_status = 5 * USEC_PER_MSEC; } } diff --git a/drivers/accel/ivpu/ivpu_hw_ip.c b/drivers/accel/ivpu/ivpu_hw_ip.c index 81f0b1f8f5a6..46661fbf9d05 100644 --- a/drivers/accel/ivpu/ivpu_hw_ip.c +++ b/drivers/accel/ivpu/ivpu_hw_ip.c @@ -15,8 +15,6 @@ #include "ivpu_mmu.h" #include "ivpu_pm.h" -#define PWR_ISLAND_STATUS_TIMEOUT_US (5 * USEC_PER_MSEC) - #define TIM_SAFE_ENABLE 0xf1d0dead #define TIM_WATCHDOG_RESET_VALUE 0xffffffff @@ -350,10 +348,10 @@ static int wait_for_pwr_island_status(struct ivpu_device *vdev, u32 exp_val) if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) return REGV_POLL_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_STATUS0, MSS_CPU, exp_val, - PWR_ISLAND_STATUS_TIMEOUT_US); + vdev->timeout.pwr_island_status); else return REGV_POLL_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_STATUS0, CSS_CPU, exp_val, - PWR_ISLAND_STATUS_TIMEOUT_US); + vdev->timeout.pwr_island_status); } static void pwr_island_isolation_drive_37xx(struct ivpu_device *vdev, bool enable) diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index ebb2c865b09a..96023221eb55 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -323,6 +323,11 @@ static inline u8 ivpu_job_to_jsm_priority(u8 priority) return priority - 1; } +static inline u8 ivpu_jsm_to_job_priority(u8 priority) +{ + return priority + 1; +} + static void ivpu_cmdq_destroy(struct ivpu_file_priv *file_priv, struct ivpu_cmdq *cmdq) { lockdep_assert_held(&file_priv->lock); @@ -1127,6 +1132,86 @@ int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file return ret; } +static int ivpu_cmdq_priority_args_check(struct ivpu_device *vdev, u32 cmdq_id, u64 priority) +{ + if (!ivpu_is_capable(vdev, DRM_IVPU_CAP_CMDQ_SET_PRIORITY)) { + ivpu_dbg(vdev, IOCTL, "Command queue priority not supported\n"); + return -ENODEV; + } + + if (cmdq_id < IVPU_CMDQ_MIN_ID || cmdq_id > IVPU_CMDQ_MAX_ID) { + ivpu_dbg(vdev, IOCTL, "Invalid command queue ID %u\n", cmdq_id); + return -EINVAL; + } + + if (priority > DRM_IVPU_JOB_PRIORITY_REALTIME) + return -EINVAL; + + return 0; +} + +int ivpu_cmdq_get_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 *priority) +{ + struct ivpu_device *vdev = file_priv->vdev; + struct ivpu_cmdq *cmdq; + int ret; + + ret = ivpu_cmdq_priority_args_check(vdev, cmdq_id, DRM_IVPU_JOB_PRIORITY_NORMAL); + if (ret) + return ret; + + guard(mutex)(&file_priv->lock); + + cmdq = ivpu_cmdq_acquire(file_priv, cmdq_id); + if (!cmdq || cmdq->is_legacy) + return -EINVAL; + + *priority = ivpu_jsm_to_job_priority(cmdq->priority); + return 0; +} + +int ivpu_cmdq_set_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 priority) +{ + struct ivpu_device *vdev = file_priv->vdev; + struct ivpu_cmdq *cmdq; + u8 jsm_priority; + int ret = 0; + + ret = ivpu_cmdq_priority_args_check(vdev, cmdq_id, priority); + if (ret) + return ret; + + ret = ivpu_rpm_get(vdev); + if (ret < 0) + return ret; + + mutex_lock(&file_priv->lock); + + cmdq = ivpu_cmdq_acquire(file_priv, cmdq_id); + if (!cmdq || cmdq->is_legacy) { + ret = -EINVAL; + goto out; + } + + jsm_priority = ivpu_job_to_jsm_priority(priority); + if (cmdq->priority == jsm_priority) + goto out; + + if (cmdq->db_id) { + ret = ivpu_jsm_hws_set_context_sched_properties(vdev, file_priv->ctx.id, cmdq_id, + jsm_priority); + if (ret) + goto out; + } + + cmdq->priority = jsm_priority; + +out: + mutex_unlock(&file_priv->lock); + ivpu_rpm_put(vdev); + return ret; +} + static void ivpu_job_done_callback(struct ivpu_device *vdev, struct ivpu_ipc_hdr *ipc_hdr, struct vpu_jsm_msg *jsm_msg) @@ -1216,9 +1301,12 @@ void ivpu_context_abort_work_fn(struct work_struct *work) unsigned long ctx_id; unsigned long id; - if (drm_WARN_ON(&vdev->drm, pm_runtime_get_if_active(vdev->drm.dev) <= 0)) + if (!down_read_trylock(&vdev->pm->reset_lock)) return; + if (drm_WARN_ON(&vdev->drm, pm_runtime_get_if_active(vdev->drm.dev) <= 0)) + goto unlock; + if (vdev->fw->sched_mode == VPU_SCHEDULING_MODE_HW) if (reset_engine_and_mark_faulty_contexts(vdev)) goto runtime_put; @@ -1259,4 +1347,6 @@ void ivpu_context_abort_work_fn(struct work_struct *work) runtime_put: pm_runtime_put_autosuspend(vdev->drm.dev); +unlock: + up_read(&vdev->pm->reset_lock); } diff --git a/drivers/accel/ivpu/ivpu_job.h b/drivers/accel/ivpu/ivpu_job.h index d8dbce82447a..6e32fea1eb62 100644 --- a/drivers/accel/ivpu/ivpu_job.h +++ b/drivers/accel/ivpu/ivpu_job.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (C) 2020-2025 Intel Corporation + * Copyright (C) 2020-2026 Intel Corporation */ #ifndef __IVPU_JOB_H__ @@ -81,6 +81,9 @@ int ivpu_cmdq_create_ioctl(struct drm_device *dev, void *data, struct drm_file * int ivpu_cmdq_destroy_ioctl(struct drm_device *dev, void *data, struct drm_file *file); int ivpu_cmdq_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file); +int ivpu_cmdq_get_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 *priority); +int ivpu_cmdq_set_priority(struct ivpu_file_priv *file_priv, u32 cmdq_id, u64 priority); + void ivpu_context_abort_locked(struct ivpu_file_priv *file_priv); void ivpu_cmdq_release_all_locked(struct ivpu_file_priv *file_priv); diff --git a/drivers/accel/ivpu/ivpu_mmu.c b/drivers/accel/ivpu/ivpu_mmu.c index 41efd8985fa6..1908375ff128 100644 --- a/drivers/accel/ivpu/ivpu_mmu.c +++ b/drivers/accel/ivpu/ivpu_mmu.c @@ -220,9 +220,6 @@ #define IVPU_MMU_STE_1_S1DSS GENMASK_ULL(1, 0) #define IVPU_MMU_STE_1_S1DSS_TERMINATE 0x0 -#define IVPU_MMU_REG_TIMEOUT_US (10 * USEC_PER_MSEC) -#define IVPU_MMU_QUEUE_TIMEOUT_US (100 * USEC_PER_MSEC) - #define IVPU_MMU_GERROR_ERR_MASK ((REG_FLD(IVPU_MMU_REG_GERROR, CMDQ)) | \ (REG_FLD(IVPU_MMU_REG_GERROR, EVTQ_ABT)) | \ (REG_FLD(IVPU_MMU_REG_GERROR, PRIQ_ABT)) | \ @@ -438,14 +435,14 @@ static int ivpu_mmu_reg_write_cr0(struct ivpu_device *vdev, u32 val) { REGV_WR32(IVPU_MMU_REG_CR0, val); - return REGV_POLL_FLD(IVPU_MMU_REG_CR0ACK, VAL, val, IVPU_MMU_REG_TIMEOUT_US); + return REGV_POLL_FLD(IVPU_MMU_REG_CR0ACK, VAL, val, vdev->timeout.mmu_reg); } static int ivpu_mmu_reg_write_irq_ctrl(struct ivpu_device *vdev, u32 val) { REGV_WR32(IVPU_MMU_REG_IRQ_CTRL, val); - return REGV_POLL_FLD(IVPU_MMU_REG_IRQ_CTRLACK, VAL, val, IVPU_MMU_REG_TIMEOUT_US); + return REGV_POLL_FLD(IVPU_MMU_REG_IRQ_CTRLACK, VAL, val, vdev->timeout.mmu_reg); } static int ivpu_mmu_irqs_setup(struct ivpu_device *vdev) @@ -465,8 +462,7 @@ static int ivpu_mmu_cmdq_wait_for_cons(struct ivpu_device *vdev) struct ivpu_mmu_queue *cmdq = &vdev->mmu->cmdq; int ret; - ret = REGV_POLL_FLD(IVPU_MMU_REG_CMDQ_CONS, VAL, cmdq->prod, - IVPU_MMU_QUEUE_TIMEOUT_US); + ret = REGV_POLL_FLD(IVPU_MMU_REG_CMDQ_CONS, VAL, cmdq->prod, vdev->timeout.mmu_queue); if (ret) return ret; @@ -880,7 +876,7 @@ static int ivpu_mmu_evtq_set(struct ivpu_device *vdev, bool enable) val = REG_CLR_FLD(IVPU_MMU_REG_CR0, EVTQEN, val); REGV_WR32(IVPU_MMU_REG_CR0, val); - return REGV_POLL_FLD(IVPU_MMU_REG_CR0ACK, VAL, val, IVPU_MMU_REG_TIMEOUT_US); + return REGV_POLL_FLD(IVPU_MMU_REG_CR0ACK, VAL, val, vdev->timeout.mmu_reg); } static int ivpu_mmu_evtq_enable(struct ivpu_device *vdev) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 323422861e8f..65d46dfa7266 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -45,6 +45,7 @@ config DRM_MIPI_DSI config DRM_KMS_HELPER tristate depends on DRM + select DRM_PANIC_HELPER if DRM_PANIC select FB_CORE if DRM_FBDEV_EMULATION help CRTC helpers for KMS drivers. @@ -56,8 +57,6 @@ config DRM_DRAW config DRM_PANIC bool "Display a user-friendly message when a kernel panic occurs" depends on DRM && PRINTK - select FONT_SUPPORT - select DRM_DRAW help Enable a drm panic handler, which will display a user-friendly message when a kernel panic occurs. It's useful when using a user-space @@ -130,6 +129,12 @@ config DRM_PANIC_SCREEN_QR_VERSION Smaller QR code are easier to read, but will contain less debugging data. Default is 40. +config DRM_PANIC_HELPER + bool + depends on DRM + select DRM_DRAW + select FONT_SUPPORT + config DRM_RAS bool "DRM RAS support" depends on DRM diff --git a/drivers/gpu/drm/Kconfig.debug b/drivers/gpu/drm/Kconfig.debug index 1f4c98cbf090..b909cd0a619f 100644 --- a/drivers/gpu/drm/Kconfig.debug +++ b/drivers/gpu/drm/Kconfig.debug @@ -69,6 +69,7 @@ config DRM_KUNIT_TEST select DRM_EXPORT_FOR_TESTS if m select DRM_GEM_SHMEM_HELPER select DRM_KUNIT_TEST_HELPERS + select DRM_PANIC_HELPER select DRM_SYSFB_HELPER select PRIME_NUMBERS default KUNIT_ALL_TESTS diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index e635fcffd379..f0c340aa2ec6 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -92,7 +92,6 @@ drm-$(CONFIG_DRM_PRIVACY_SCREEN) += \ drm-$(CONFIG_DRM_ACCEL) += ../../accel/drm_accel.o drm-$(CONFIG_DRM_PANIC) += drm_panic.o drm-$(CONFIG_DRM_DRAW) += drm_draw.o -drm-$(CONFIG_DRM_PANIC_SCREEN_QR_CODE) += drm_panic_qr.o drm-$(CONFIG_DRM_RAS) += drm_ras.o drm_ras_nl.o drm_ras_genl_family.o obj-$(CONFIG_DRM) += drm.o @@ -157,6 +156,8 @@ drm_kms_helper-y := \ drm_simple_kms_helper.o \ drm_vblank_helper.o drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o +drm_kms_helper-$(CONFIG_DRM_PANIC_HELPER) += drm_panic_helper.o +drm_kms_helper-$(CONFIG_DRM_PANIC_SCREEN_QR_CODE) += drm_panic_helper_qr.o drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 0426118a9279..25ce45b2aef1 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -1739,10 +1739,17 @@ static bool amdgpu_switcheroo_can_switch(struct pci_dev *pdev) return atomic_read(&dev->open_count) == 0; } +static void amdgpu_switcheroo_pre_switch(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + + drm_client_dev_acquire_outputs(dev); +} + static const struct vga_switcheroo_client_ops amdgpu_switcheroo_ops = { .set_gpu_state = amdgpu_switcheroo_set_state, - .reprobe = NULL, .can_switch = amdgpu_switcheroo_can_switch, + .pre_switch = amdgpu_switcheroo_pre_switch, }; /** diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c index d6b51b3f216b..5c5fdbec93c2 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vkms.c @@ -47,7 +47,7 @@ static const struct drm_crtc_funcs amdgpu_vkms_crtc_funcs = { .set_config = drm_atomic_helper_set_config, .destroy = drm_crtc_cleanup, .page_flip = drm_atomic_helper_page_flip, - .reset = drm_atomic_helper_crtc_reset, + .atomic_create_state = drm_atomic_helper_crtc_create_state, .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, DRM_CRTC_VBLANK_TIMER_FUNCS, @@ -144,7 +144,7 @@ static const struct drm_plane_funcs amdgpu_vkms_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .destroy = drm_plane_cleanup, - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, }; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index 4b8530d734e5..686da9c477db 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -490,20 +490,19 @@ STATIC_IFN_KUNIT void amdgpu_dm_crtc_destroy(struct drm_crtc *crtc) } EXPORT_IF_KUNIT(amdgpu_dm_crtc_destroy); -STATIC_IFN_KUNIT void amdgpu_dm_crtc_reset_state(struct drm_crtc *crtc) +STATIC_IFN_KUNIT struct drm_crtc_state *amdgpu_dm_crtc_create_state(struct drm_crtc *crtc) { struct dm_crtc_state *state; state = kzalloc_obj(*state); if (!state) - return; + return ERR_PTR(-ENOMEM); - if (crtc->state) - amdgpu_dm_crtc_destroy_state(crtc, crtc->state); + __drm_atomic_helper_crtc_state_init(&state->base, crtc); - __drm_atomic_helper_crtc_reset(crtc, &state->base); + return &state->base; } -EXPORT_IF_KUNIT(amdgpu_dm_crtc_reset_state); +EXPORT_IF_KUNIT(amdgpu_dm_crtc_create_state); #ifdef CONFIG_DEBUG_FS STATIC_IFN_KUNIT int amdgpu_dm_crtc_late_register(struct drm_crtc *crtc) @@ -581,7 +580,7 @@ amdgpu_dm_atomic_crtc_get_property(struct drm_crtc *crtc, /* Implemented only the options currently available for the driver */ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { - .reset = amdgpu_dm_crtc_reset_state, + .atomic_create_state = amdgpu_dm_crtc_create_state, .destroy = amdgpu_dm_crtc_destroy, .set_config = drm_atomic_helper_set_config, .page_flip = drm_atomic_helper_page_flip, @@ -798,9 +797,18 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, drm_crtc_helper_add(&acrtc->base, &amdgpu_dm_crtc_helper_funcs); - /* Create (reset) the plane state */ - if (acrtc->base.funcs->reset) - acrtc->base.funcs->reset(&acrtc->base); + /* Create the plane state */ + if (acrtc->base.funcs->atomic_create_state) { + struct drm_crtc_state *crtc_state; + + crtc_state = acrtc->base.funcs->atomic_create_state(&acrtc->base); + if (IS_ERR(crtc_state)) { + res = PTR_ERR(crtc_state); + goto error_ism_fini; + } + + acrtc->base.state = crtc_state; + } acrtc->max_cursor_width = dm->adev->dm.dc->caps.max_cursor_size; acrtc->max_cursor_height = dm->adev->dm.dc->caps.max_cursor_size; @@ -832,6 +840,9 @@ int amdgpu_dm_crtc_init(struct amdgpu_display_manager *dm, #endif return 0; +error_ism_fini: + amdgpu_dm_ism_fini(&acrtc->ism); + drm_crtc_cleanup(&acrtc->base); fail: kfree(acrtc); kfree(cursor_plane); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h index 91fdd262c2d2..223ef34c5591 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.h @@ -49,8 +49,8 @@ bool amdgpu_dm_crtc_helper_mode_fixup(struct drm_crtc *crtc, void amdgpu_dm_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *state); struct drm_crtc_state *amdgpu_dm_crtc_duplicate_state(struct drm_crtc *crtc); +struct drm_crtc_state *amdgpu_dm_crtc_create_state(struct drm_crtc *crtc); void amdgpu_dm_crtc_destroy(struct drm_crtc *crtc); -void amdgpu_dm_crtc_reset_state(struct drm_crtc *crtc); int amdgpu_dm_crtc_count_crtc_active_planes(struct drm_crtc_state *new_crtc_state); void amdgpu_dm_crtc_update_crtc_active_planes(struct drm_crtc *crtc, struct drm_crtc_state *new_crtc_state); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c index 91994fe37cbf..d357afcb0e93 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c @@ -28,6 +28,7 @@ #include #include "drm/drm_framebuffer.h" #include +#include #include #include #include @@ -1798,24 +1799,23 @@ static const struct drm_plane_helper_funcs dm_primary_plane_helper_funcs = { .panic_flush = amdgpu_dm_plane_panic_flush, }; -STATIC_IFN_KUNIT void amdgpu_dm_plane_drm_plane_reset(struct drm_plane *plane) +STATIC_IFN_KUNIT struct drm_plane_state *amdgpu_dm_plane_drm_plane_create_state(struct drm_plane *plane) { struct dm_plane_state *amdgpu_state; amdgpu_state = kzalloc_obj(*amdgpu_state); if (!amdgpu_state) - return; + return ERR_PTR(-ENOMEM); - if (plane->state) - plane->funcs->atomic_destroy_state(plane, plane->state); - - __drm_atomic_helper_plane_reset(plane, &amdgpu_state->base); + __drm_atomic_helper_plane_state_init(&amdgpu_state->base, plane); amdgpu_state->degamma_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT; amdgpu_state->hdr_mult = AMDGPU_HDR_MULT_DEFAULT; amdgpu_state->shaper_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT; amdgpu_state->blend_tf = AMDGPU_TRANSFER_FUNCTION_DEFAULT; + + return &amdgpu_state->base; } -EXPORT_IF_KUNIT(amdgpu_dm_plane_drm_plane_reset); +EXPORT_IF_KUNIT(amdgpu_dm_plane_drm_plane_create_state); STATIC_IFN_KUNIT struct drm_plane_state * amdgpu_dm_plane_drm_plane_duplicate_state(struct drm_plane *plane) @@ -2178,7 +2178,7 @@ static const struct drm_plane_funcs dm_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .destroy = drm_plane_helper_destroy, - .reset = amdgpu_dm_plane_drm_plane_reset, + .atomic_create_state = amdgpu_dm_plane_drm_plane_create_state, .atomic_duplicate_state = amdgpu_dm_plane_drm_plane_duplicate_state, .atomic_destroy_state = amdgpu_dm_plane_drm_plane_destroy_state, .format_mod_supported = amdgpu_dm_plane_format_mod_supported, @@ -2187,6 +2187,7 @@ static const struct drm_plane_funcs dm_plane_funcs = { .atomic_set_property = dm_atomic_plane_set_property, .atomic_get_property = dm_atomic_plane_get_property, #endif + DRM_PANIC_PLANE_FUNCS, }; int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, @@ -2313,9 +2314,16 @@ int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm, return res; #endif - /* Create (reset) the plane state */ - if (plane->funcs->reset) - plane->funcs->reset(plane); + /* Create the plane state */ + if (plane->funcs->atomic_create_state) { + struct drm_plane_state *plane_state; + + plane_state = plane->funcs->atomic_create_state(plane); + if (IS_ERR(plane_state)) + return PTR_ERR(plane_state); + + plane->state = plane_state; + } return 0; } diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h index 18b500585bed..3469a49d5f56 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.h @@ -117,7 +117,7 @@ int amdgpu_dm_plane_atomic_async_check(struct drm_plane *plane, int amdgpu_dm_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_commit *state); void amdgpu_dm_plane_panic_flush(struct drm_plane *plane); -void amdgpu_dm_plane_drm_plane_reset(struct drm_plane *plane); +struct drm_plane_state *amdgpu_dm_plane_drm_plane_create_state(struct drm_plane *plane); struct drm_plane_state *amdgpu_dm_plane_drm_plane_duplicate_state(struct drm_plane *plane); void amdgpu_dm_plane_drm_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c index bc2b115b48b0..9b15f53a9c62 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_crtc_test.c @@ -1604,18 +1604,18 @@ static void dm_test_crtc_destroy_cleans_up_and_frees(struct kunit *test) KUNIT_EXPECT_EQ(test, adev->ddev.mode_config.num_crtc, 0); } -/* Tests for amdgpu_dm_crtc_reset_state() */ +/* Tests for amdgpu_dm_crtc_create_state() */ /** - * dm_test_crtc_reset_state_allocates_state - Test reset installs a fresh state + * dm_test_crtc_create_state_allocates_state - Test create_state allocates a fresh state * @test: The KUnit test context * - * Resetting a CRTC with no existing state must allocate and install a new - * drm_crtc_state. + * Creating state for a CRTC must allocate a new drm_crtc_state. */ -static void dm_test_crtc_reset_state_allocates_state(struct kunit *test) +static void dm_test_crtc_create_state_allocates_state(struct kunit *test) { struct amdgpu_device *adev = dm_kunit_alloc_adev(test); + struct drm_crtc_state *crtc_state; struct drm_crtc *crtc; crtc = kunit_kzalloc(test, sizeof(*crtc), GFP_KERNEL); @@ -1623,12 +1623,11 @@ static void dm_test_crtc_reset_state_allocates_state(struct kunit *test) crtc->dev = &adev->ddev; crtc->state = NULL; - amdgpu_dm_crtc_reset_state(crtc); + crtc_state = amdgpu_dm_crtc_create_state(crtc); + KUNIT_EXPECT_NOT_ERR_OR_NULL(test, crtc_state); - KUNIT_EXPECT_NOT_NULL(test, crtc->state); - - if (crtc->state) - amdgpu_dm_crtc_destroy_state(crtc, crtc->state); + if (!IS_ERR(crtc_state)) + amdgpu_dm_crtc_destroy_state(crtc, crtc_state); } /** @@ -2638,9 +2637,8 @@ static struct kunit_case amdgpu_dm_crtc_tests[] = { KUNIT_CASE(dm_test_crtc_duplicate_state_null_state_returns_null), /* amdgpu_dm_crtc_destroy */ KUNIT_CASE(dm_test_crtc_destroy_cleans_up_and_frees), - /* amdgpu_dm_crtc_reset_state */ - KUNIT_CASE(dm_test_crtc_reset_state_allocates_state), - KUNIT_CASE(dm_test_crtc_reset_state_replaces_existing), + /* amdgpu_dm_crtc_create_state */ + KUNIT_CASE(dm_test_crtc_create_state_allocates_state), /* amdgpu_dm_crtc_destroy_state */ KUNIT_CASE(dm_test_crtc_destroy_state_no_stream), KUNIT_CASE(dm_test_crtc_destroy_state_releases_stream), diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c index 5ae627bb55cc..1b0d3f16ef1a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/tests/amdgpu_dm_plane_test.c @@ -2937,36 +2937,28 @@ static const struct drm_plane_funcs dm_test_plane_reset_funcs = { }; /** - * dm_test_plane_reset_initializes_state() - Verify reset installs default state. + * dm_test_plane_create_state_initializes_state() - Verify create_state allocates default state. * @test: KUnit test context. * - * Verify amdgpu_dm_plane_drm_plane_reset() destroys the existing plane state, - * allocates a fresh dm_plane_state, and initializes the AMD-specific transfer - * function and HDR multiplier defaults. + * Verify amdgpu_dm_plane_drm_plane_create_state() allocates a fresh + * dm_plane_state, and initializes the AMD-specific transfer function and HDR + * multiplier defaults. */ -static void dm_test_plane_reset_initializes_state(struct kunit *test) +static void dm_test_plane_create_state_initializes_state(struct kunit *test) { - struct dm_plane_state *old_state; + struct drm_plane_state *plane_state; struct dm_plane_state *new_state; struct drm_plane *plane; plane = kunit_kzalloc(test, sizeof(*plane), GFP_KERNEL); KUNIT_ASSERT_NOT_NULL(test, plane); - /* - * Provide an existing state plus a funcs table so reset exercises the - * destroy-existing-state path. The destroy hook frees this state, so it - * must be a plain (non-KUnit-managed) allocation. - */ - old_state = kzalloc_obj(*old_state); - KUNIT_ASSERT_NOT_NULL(test, old_state); plane->funcs = &dm_test_plane_reset_funcs; - plane->state = &old_state->base; - amdgpu_dm_plane_drm_plane_reset(plane); + plane_state = amdgpu_dm_plane_drm_plane_create_state(plane); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, plane_state); - KUNIT_ASSERT_NOT_NULL(test, plane->state); - new_state = to_dm_plane_state(plane->state); + new_state = to_dm_plane_state(plane_state); KUNIT_EXPECT_EQ(test, new_state->degamma_tf, AMDGPU_TRANSFER_FUNCTION_DEFAULT); KUNIT_EXPECT_EQ(test, new_state->hdr_mult, AMDGPU_HDR_MULT_DEFAULT); KUNIT_EXPECT_EQ(test, new_state->shaper_tf, AMDGPU_TRANSFER_FUNCTION_DEFAULT); @@ -3765,8 +3757,8 @@ static struct kunit_case amdgpu_dm_plane_test_cases[] = { KUNIT_CASE(dm_test_atomic_check_scaling_failure), /* amdgpu_dm_plane_panic_flush() */ KUNIT_CASE(dm_test_panic_flush_no_dc_state), - /* amdgpu_dm_plane_drm_plane_reset() */ - KUNIT_CASE(dm_test_plane_reset_initializes_state), + /* amdgpu_dm_plane_drm_plane_create_state() */ + KUNIT_CASE(dm_test_plane_create_state_initializes_state), /* amdgpu_dm_plane_drm_plane_duplicate_state() */ KUNIT_CASE(dm_test_plane_duplicate_state_copies_fields), KUNIT_CASE(dm_test_plane_duplicate_state_copies_resources), diff --git a/drivers/gpu/drm/armada/armada_overlay.c b/drivers/gpu/drm/armada/armada_overlay.c index 3da0b857ef95..e75706b85dd1 100644 --- a/drivers/gpu/drm/armada/armada_overlay.c +++ b/drivers/gpu/drm/armada/armada_overlay.c @@ -301,30 +301,27 @@ armada_overlay_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, return ret; } -static void armada_overlay_reset(struct drm_plane *plane) +static struct drm_plane_state *armada_overlay_create_state(struct drm_plane *plane) { struct armada_overlay_state *state; - if (plane->state) - __drm_atomic_helper_plane_destroy_state(plane->state); - kfree(plane->state); - plane->state = NULL; - state = kzalloc_obj(*state); - if (state) { - state->colorkey_yr = 0xfefefe00; - state->colorkey_ug = 0x01010100; - state->colorkey_vb = 0x01010100; - state->colorkey_mode = CFG_CKMODE(CKMODE_RGB) | - CFG_ALPHAM_GRA | CFG_ALPHA(0); - state->colorkey_enable = ADV_GRACOLORKEY; - state->brightness = DEFAULT_BRIGHTNESS; - state->contrast = DEFAULT_CONTRAST; - state->saturation = DEFAULT_SATURATION; - __drm_atomic_helper_plane_reset(plane, &state->base.base); - state->base.base.color_encoding = DEFAULT_ENCODING; - state->base.base.color_range = DRM_COLOR_YCBCR_LIMITED_RANGE; - } + if (!state) + return ERR_PTR(-ENOMEM); + + state->colorkey_yr = 0xfefefe00; + state->colorkey_ug = 0x01010100; + state->colorkey_vb = 0x01010100; + state->colorkey_mode = CFG_CKMODE(CKMODE_RGB) | CFG_ALPHAM_GRA | CFG_ALPHA(0); + state->colorkey_enable = ADV_GRACOLORKEY; + state->brightness = DEFAULT_BRIGHTNESS; + state->contrast = DEFAULT_CONTRAST; + state->saturation = DEFAULT_SATURATION; + __drm_atomic_helper_plane_state_init(&state->base.base, plane); + state->base.base.color_encoding = DEFAULT_ENCODING; + state->base.base.color_range = DRM_COLOR_YCBCR_LIMITED_RANGE; + + return &state->base.base; } static struct drm_plane_state * @@ -466,7 +463,7 @@ static const struct drm_plane_funcs armada_ovl_plane_funcs = { .update_plane = armada_overlay_plane_update, .disable_plane = drm_atomic_helper_disable_plane, .destroy = drm_plane_helper_destroy, - .reset = armada_overlay_reset, + .atomic_create_state = armada_overlay_create_state, .atomic_duplicate_state = armada_overlay_duplicate_state, .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, .atomic_set_property = armada_overlay_set_property, diff --git a/drivers/gpu/drm/armada/armada_plane.c b/drivers/gpu/drm/armada/armada_plane.c index fe46a8e4508a..1f5172d6816b 100644 --- a/drivers/gpu/drm/armada/armada_plane.c +++ b/drivers/gpu/drm/armada/armada_plane.c @@ -256,15 +256,16 @@ static const struct drm_plane_helper_funcs armada_primary_plane_helper_funcs = { .atomic_disable = armada_drm_primary_plane_atomic_disable, }; -void armada_plane_reset(struct drm_plane *plane) +struct drm_plane_state *armada_plane_create_state(struct drm_plane *plane) { struct armada_plane_state *st; - if (plane->state) - __drm_atomic_helper_plane_destroy_state(plane->state); - kfree(plane->state); st = kzalloc_obj(*st); - if (st) - __drm_atomic_helper_plane_reset(plane, &st->base); + if (!st) + return ERR_PTR(-ENOMEM); + + __drm_atomic_helper_plane_state_init(&st->base, plane); + + return &st->base; } struct drm_plane_state *armada_plane_duplicate_state(struct drm_plane *plane) @@ -285,7 +286,7 @@ static const struct drm_plane_funcs armada_primary_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .destroy = drm_plane_helper_destroy, - .reset = armada_plane_reset, + .atomic_create_state = armada_plane_create_state, .atomic_duplicate_state = armada_plane_duplicate_state, .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, }; diff --git a/drivers/gpu/drm/armada/armada_plane.h b/drivers/gpu/drm/armada/armada_plane.h index 69bef09ea028..be2b1eaafad7 100644 --- a/drivers/gpu/drm/armada/armada_plane.h +++ b/drivers/gpu/drm/armada/armada_plane.h @@ -25,7 +25,7 @@ void armada_drm_plane_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *old_state); int armada_drm_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_commit *state); -void armada_plane_reset(struct drm_plane *plane); +struct drm_plane_state *armada_plane_create_state(struct drm_plane *plane); struct drm_plane_state *armada_plane_duplicate_state(struct drm_plane *plane); void armada_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state); diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx.h b/drivers/gpu/drm/aspeed/aspeed_gfx.h index 4e6a442c3886..273528d30b4c 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx.h +++ b/drivers/gpu/drm/aspeed/aspeed_gfx.h @@ -2,7 +2,6 @@ /* Copyright 2018 IBM Corporation */ #include -#include struct aspeed_gfx { struct drm_device drm; @@ -17,10 +16,16 @@ struct aspeed_gfx { u32 throd_val; u32 scan_line_max; - struct drm_simple_display_pipe pipe; + struct drm_plane plane; + struct drm_crtc crtc; + struct drm_encoder encoder; struct drm_connector connector; }; -#define to_aspeed_gfx(x) container_of(x, struct aspeed_gfx, drm) + +static inline struct aspeed_gfx *to_aspeed_gfx(struct drm_device *drm) +{ + return container_of(drm, struct aspeed_gfx, drm); +} int aspeed_gfx_create_pipe(struct drm_device *drm); int aspeed_gfx_create_output(struct drm_device *drm); diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c b/drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c index 7877a57b8e26..918b8b4dc863 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c +++ b/drivers/gpu/drm/aspeed/aspeed_gfx_crtc.c @@ -5,6 +5,8 @@ #include #include +#include +#include #include #include #include @@ -12,22 +14,17 @@ #include #include #include -#include #include #include "aspeed_gfx.h" -static struct aspeed_gfx * -drm_pipe_to_aspeed_gfx(struct drm_simple_display_pipe *pipe) +static int aspeed_gfx_set_pixel_fmt(struct aspeed_gfx *priv, + struct drm_plane_state *plane_state, + u32 *bpp) { - return container_of(pipe, struct aspeed_gfx, pipe); -} - -static int aspeed_gfx_set_pixel_fmt(struct aspeed_gfx *priv, u32 *bpp) -{ - struct drm_crtc *crtc = &priv->pipe.crtc; + struct drm_crtc *crtc = &priv->crtc; struct drm_device *drm = crtc->dev; - const u32 format = crtc->primary->state->fb->format->format; + const u32 format = plane_state->fb->format->format; u32 ctrl1; ctrl1 = readl(priv->base + CRT_CTRL1); @@ -77,13 +74,15 @@ static void aspeed_gfx_disable_controller(struct aspeed_gfx *priv) regmap_update_bits(priv->scu, priv->dac_reg, BIT(16), 0); } -static void aspeed_gfx_crtc_mode_set_nofb(struct aspeed_gfx *priv) +static void aspeed_gfx_crtc_mode_set_nofb(struct aspeed_gfx *priv, + struct drm_crtc_state *crtc_state, + struct drm_plane_state *plane_state) { - struct drm_display_mode *m = &priv->pipe.crtc.state->adjusted_mode; + struct drm_display_mode *m = &crtc_state->adjusted_mode; u32 ctrl1, d_offset, t_count, bpp; int err; - err = aspeed_gfx_set_pixel_fmt(priv, &bpp); + err = aspeed_gfx_set_pixel_fmt(priv, plane_state, &bpp); if (err) return; @@ -139,48 +138,35 @@ static void aspeed_gfx_crtc_mode_set_nofb(struct aspeed_gfx *priv) writel(priv->throd_val, priv->base + CRT_THROD); } -static void aspeed_gfx_pipe_enable(struct drm_simple_display_pipe *pipe, - struct drm_crtc_state *crtc_state, - struct drm_plane_state *plane_state) +static void aspeed_gfx_crtc_helper_atomic_enable(struct drm_crtc *crtc, + struct drm_atomic_commit *commit) { - struct aspeed_gfx *priv = drm_pipe_to_aspeed_gfx(pipe); - struct drm_crtc *crtc = &pipe->crtc; + struct aspeed_gfx *priv = to_aspeed_gfx(crtc->dev); + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(commit, crtc); + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(commit, &priv->plane); - aspeed_gfx_crtc_mode_set_nofb(priv); + aspeed_gfx_crtc_mode_set_nofb(priv, crtc_state, plane_state); aspeed_gfx_enable_controller(priv); drm_crtc_vblank_on(crtc); } -static void aspeed_gfx_pipe_disable(struct drm_simple_display_pipe *pipe) +static void aspeed_gfx_crtc_helper_atomic_disable(struct drm_crtc *crtc, + struct drm_atomic_commit *commit) { - struct aspeed_gfx *priv = drm_pipe_to_aspeed_gfx(pipe); - struct drm_crtc *crtc = &pipe->crtc; + struct aspeed_gfx *priv = to_aspeed_gfx(crtc->dev); drm_crtc_vblank_off(crtc); aspeed_gfx_disable_controller(priv); } -static void aspeed_gfx_pipe_update(struct drm_simple_display_pipe *pipe, - struct drm_plane_state *plane_state) +static void aspeed_gfx_plane_helper_atomic_update(struct drm_plane *plane, + struct drm_atomic_commit *commit) { - struct aspeed_gfx *priv = drm_pipe_to_aspeed_gfx(pipe); - struct drm_crtc *crtc = &pipe->crtc; - struct drm_framebuffer *fb = pipe->plane.state->fb; - struct drm_pending_vblank_event *event; + struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(commit, plane); + struct aspeed_gfx *priv = to_aspeed_gfx(plane->dev); + struct drm_framebuffer *fb = new_plane_state->fb; struct drm_gem_dma_object *gem; - spin_lock_irq(&crtc->dev->event_lock); - event = crtc->state->event; - if (event) { - crtc->state->event = NULL; - - if (drm_crtc_vblank_get(crtc) == 0) - drm_crtc_arm_vblank_event(crtc, event); - else - drm_crtc_send_vblank_event(crtc, event); - } - spin_unlock_irq(&crtc->dev->event_lock); - if (!fb) return; @@ -190,9 +176,9 @@ static void aspeed_gfx_pipe_update(struct drm_simple_display_pipe *pipe, writel(gem->dma_addr, priv->base + CRT_ADDR); } -static int aspeed_gfx_enable_vblank(struct drm_simple_display_pipe *pipe) +static int aspeed_gfx_crtc_enable_vblank(struct drm_crtc *crtc) { - struct aspeed_gfx *priv = drm_pipe_to_aspeed_gfx(pipe); + struct aspeed_gfx *priv = to_aspeed_gfx(crtc->dev); u32 reg = readl(priv->base + CRT_CTRL1); /* Clear pending VBLANK IRQ */ @@ -204,9 +190,9 @@ static int aspeed_gfx_enable_vblank(struct drm_simple_display_pipe *pipe) return 0; } -static void aspeed_gfx_disable_vblank(struct drm_simple_display_pipe *pipe) +static void aspeed_gfx_crtc_disable_vblank(struct drm_crtc *crtc) { - struct aspeed_gfx *priv = drm_pipe_to_aspeed_gfx(pipe); + struct aspeed_gfx *priv = to_aspeed_gfx(crtc->dev); u32 reg = readl(priv->base + CRT_CTRL1); reg &= ~CRT_CTRL_VERTICAL_INTR_EN; @@ -216,12 +202,93 @@ static void aspeed_gfx_disable_vblank(struct drm_simple_display_pipe *pipe) writel(reg | CRT_CTRL_VERTICAL_INTR_STS, priv->base + CRT_CTRL1); } -static const struct drm_simple_display_pipe_funcs aspeed_gfx_funcs = { - .enable = aspeed_gfx_pipe_enable, - .disable = aspeed_gfx_pipe_disable, - .update = aspeed_gfx_pipe_update, - .enable_vblank = aspeed_gfx_enable_vblank, - .disable_vblank = aspeed_gfx_disable_vblank, +static int aspeed_gfx_plane_helper_atomic_check(struct drm_plane *plane, + struct drm_atomic_commit *commit) +{ + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(commit, plane); + struct drm_crtc_state *crtc_state = NULL; + + if (plane_state->crtc) { + crtc_state = drm_atomic_get_crtc_state(commit, plane_state->crtc); + if (IS_ERR(crtc_state)) + return PTR_ERR(crtc_state); + } + + return drm_atomic_helper_check_plane_state(plane_state, crtc_state, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, + false, false); +} + +static const struct drm_plane_helper_funcs aspeed_gfx_plane_helper_funcs = { + .prepare_fb = drm_gem_plane_helper_prepare_fb, + .atomic_check = aspeed_gfx_plane_helper_atomic_check, + .atomic_update = aspeed_gfx_plane_helper_atomic_update, +}; + +static const struct drm_plane_funcs aspeed_gfx_plane_funcs = { + .update_plane = drm_atomic_helper_update_plane, + .disable_plane = drm_atomic_helper_disable_plane, + .destroy = drm_plane_cleanup, + .atomic_create_state = drm_atomic_helper_plane_create_state, + .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, +}; + +static int aspeed_gfx_crtc_helper_atomic_check(struct drm_crtc *crtc, + struct drm_atomic_commit *commit) +{ + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(commit, crtc); + int ret; + + if (crtc_state->enable) { + ret = drm_atomic_helper_check_crtc_primary_plane(crtc_state); + if (ret) + return ret; + } + + return drm_atomic_add_affected_planes(commit, crtc); +} + +static void aspeed_gfx_crtc_helper_atomic_flush(struct drm_crtc *crtc, + struct drm_atomic_commit *commit) +{ + struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(commit, crtc); + struct drm_pending_vblank_event *event = new_crtc_state->event; + + if (!event) + return; + + new_crtc_state->event = NULL; + + spin_lock_irq(&crtc->dev->event_lock); + if (drm_crtc_vblank_get(crtc) == 0) + drm_crtc_arm_vblank_event(crtc, event); + else + drm_crtc_send_vblank_event(crtc, event); + spin_unlock_irq(&crtc->dev->event_lock); +} + +static const struct drm_crtc_helper_funcs aspeed_gfx_crtc_helper_funcs = { + .atomic_check = aspeed_gfx_crtc_helper_atomic_check, + .atomic_enable = aspeed_gfx_crtc_helper_atomic_enable, + .atomic_disable = aspeed_gfx_crtc_helper_atomic_disable, + .atomic_flush = aspeed_gfx_crtc_helper_atomic_flush, +}; + +static const struct drm_crtc_funcs aspeed_gfx_crtc_funcs = { + .atomic_create_state = drm_atomic_helper_crtc_create_state, + .destroy = drm_crtc_cleanup, + .set_config = drm_atomic_helper_set_config, + .page_flip = drm_atomic_helper_page_flip, + .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, + .enable_vblank = aspeed_gfx_crtc_enable_vblank, + .disable_vblank = aspeed_gfx_crtc_disable_vblank, +}; + +static const struct drm_encoder_funcs aspeed_gfx_encoder_funcs = { + .destroy = drm_encoder_cleanup, }; static const uint32_t aspeed_gfx_formats[] = { @@ -232,10 +299,36 @@ static const uint32_t aspeed_gfx_formats[] = { int aspeed_gfx_create_pipe(struct drm_device *drm) { struct aspeed_gfx *priv = to_aspeed_gfx(drm); + struct drm_plane *plane = &priv->plane; + struct drm_crtc *crtc = &priv->crtc; + struct drm_encoder *encoder = &priv->encoder; + int ret; - return drm_simple_display_pipe_init(drm, &priv->pipe, &aspeed_gfx_funcs, - aspeed_gfx_formats, - ARRAY_SIZE(aspeed_gfx_formats), - NULL, - &priv->connector); + ret = drm_universal_plane_init(drm, plane, 0, + &aspeed_gfx_plane_funcs, + aspeed_gfx_formats, + ARRAY_SIZE(aspeed_gfx_formats), + NULL, + DRM_PLANE_TYPE_PRIMARY, NULL); + if (ret) + return ret; + drm_plane_helper_add(plane, &aspeed_gfx_plane_helper_funcs); + + ret = drm_crtc_init_with_planes(drm, crtc, plane, NULL, + &aspeed_gfx_crtc_funcs, NULL); + if (ret) + return ret; + drm_crtc_helper_add(crtc, &aspeed_gfx_crtc_helper_funcs); + + ret = drm_encoder_init(drm, encoder, &aspeed_gfx_encoder_funcs, + DRM_MODE_ENCODER_NONE, NULL); + if (ret) + return ret; + encoder->possible_crtcs = drm_crtc_mask(crtc); + + ret = drm_connector_attach_encoder(&priv->connector, encoder); + if (ret) + return ret; + + return 0; } diff --git a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c index d4577663a1f0..c8746766f258 100644 --- a/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c +++ b/drivers/gpu/drm/aspeed/aspeed_gfx_drv.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -129,7 +128,7 @@ static irqreturn_t aspeed_gfx_irq_handler(int irq, void *data) reg = readl(priv->base + CRT_CTRL1); if (reg & CRT_CTRL_VERTICAL_INTR_STS) { - drm_crtc_handle_vblank(&priv->pipe.crtc); + drm_crtc_handle_vblank(&priv->crtc); writel(reg, priv->base + priv->int_clr_reg); return IRQ_HANDLED; } diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index ea0ef8096aa9..08db132acae8 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include @@ -652,6 +653,7 @@ static const struct drm_plane_funcs ast_primary_plane_funcs = { .disable_plane = drm_atomic_helper_disable_plane, .destroy = drm_plane_cleanup, DRM_GEM_SHADOW_PLANE_FUNCS, + DRM_PANIC_PLANE_FUNCS, }; static int ast_primary_plane_init(struct ast_device *ast) diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c index f17a832351e9..e09ce6342085 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c @@ -1183,36 +1183,31 @@ static void atmel_hlcdc_plane_atomic_destroy_state(struct drm_plane *p, kfree(state); } -static void atmel_hlcdc_plane_reset(struct drm_plane *p) +static struct drm_plane_state *atmel_hlcdc_plane_create_state(struct drm_plane *p) { struct atmel_hlcdc_plane_state *state; - struct atmel_hlcdc_dc *dc = p->dev->dev_private; - struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); - - if (p->state) { - atmel_hlcdc_plane_atomic_destroy_state(p, p->state); - p->state = NULL; - } + int ret; state = kzalloc_obj(*state); - if (state) { - if (atmel_hlcdc_plane_alloc_dscrs(p, state)) { - kfree(state); - drm_err(p->dev, - "Failed to allocate initial plane state\n"); - return; - } - __drm_atomic_helper_plane_reset(p, &state->base); + if (!state) + return ERR_PTR(-ENOMEM); + + ret = atmel_hlcdc_plane_alloc_dscrs(p, state); + if (ret) { + kfree(state); + drm_err(p->dev, "Failed to allocate initial plane state\n"); + return ERR_PTR(ret); } - if (plane->layer.desc->layout.csc) - dc->desc->ops->lcdc_csc_init(plane, plane->layer.desc); + __drm_atomic_helper_plane_state_init(&state->base, p); + + return &state->base; } static const struct drm_plane_funcs layer_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, - .reset = atmel_hlcdc_plane_reset, + .atomic_create_state = atmel_hlcdc_plane_create_state, .atomic_duplicate_state = atmel_hlcdc_plane_atomic_duplicate_state, .atomic_destroy_state = atmel_hlcdc_plane_atomic_destroy_state, }; diff --git a/drivers/gpu/drm/clients/drm_fbdev_client.c b/drivers/gpu/drm/clients/drm_fbdev_client.c index 91d196a397cf..827f32668714 100644 --- a/drivers/gpu/drm/clients/drm_fbdev_client.c +++ b/drivers/gpu/drm/clients/drm_fbdev_client.c @@ -47,6 +47,14 @@ static int drm_fbdev_client_restore(struct drm_client_dev *client, bool force) return 0; } +static void drm_fbdev_client_acquire_outputs(struct drm_client_dev *client) +{ + struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); + + if (fb_helper->info) + fb_switch_outputs(fb_helper->info); +} + static int drm_fbdev_client_hotplug(struct drm_client_dev *client) { struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client); @@ -95,13 +103,14 @@ static int drm_fbdev_client_resume(struct drm_client_dev *client) } static const struct drm_client_funcs drm_fbdev_client_funcs = { - .owner = THIS_MODULE, - .free = drm_fbdev_client_free, - .unregister = drm_fbdev_client_unregister, - .restore = drm_fbdev_client_restore, - .hotplug = drm_fbdev_client_hotplug, - .suspend = drm_fbdev_client_suspend, - .resume = drm_fbdev_client_resume, + .owner = THIS_MODULE, + .free = drm_fbdev_client_free, + .unregister = drm_fbdev_client_unregister, + .restore = drm_fbdev_client_restore, + .acquire_outputs = drm_fbdev_client_acquire_outputs, + .hotplug = drm_fbdev_client_hotplug, + .suspend = drm_fbdev_client_suspend, + .resume = drm_fbdev_client_resume, }; /** diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c index 45df6376f408..9bb761eda59f 100644 --- a/drivers/gpu/drm/drm_atomic.c +++ b/drivers/gpu/drm/drm_atomic.c @@ -293,8 +293,10 @@ void drm_atomic_commit_default_clear(struct drm_atomic_commit *state) if (!connector) continue; - connector->funcs->atomic_destroy_state(connector, - state->connectors[i].state_to_destroy); + if (state->connectors[i].state_to_destroy) + connector->funcs->atomic_destroy_state(connector, + state->connectors[i].state_to_destroy); + state->connectors[i].ptr = NULL; state->connectors[i].state_to_destroy = NULL; state->connectors[i].old_state = NULL; @@ -308,8 +310,9 @@ void drm_atomic_commit_default_clear(struct drm_atomic_commit *state) if (!crtc) continue; - crtc->funcs->atomic_destroy_state(crtc, - state->crtcs[i].state_to_destroy); + if (state->crtcs[i].state_to_destroy) + crtc->funcs->atomic_destroy_state(crtc, + state->crtcs[i].state_to_destroy); state->crtcs[i].ptr = NULL; state->crtcs[i].state_to_destroy = NULL; @@ -328,8 +331,10 @@ void drm_atomic_commit_default_clear(struct drm_atomic_commit *state) if (!plane) continue; - plane->funcs->atomic_destroy_state(plane, - state->planes[i].state_to_destroy); + if (state->planes[i].state_to_destroy) + plane->funcs->atomic_destroy_state(plane, + state->planes[i].state_to_destroy); + state->planes[i].ptr = NULL; state->planes[i].state_to_destroy = NULL; state->planes[i].old_state = NULL; @@ -343,9 +348,9 @@ void drm_atomic_commit_default_clear(struct drm_atomic_commit *state) continue; drm_colorop_atomic_destroy_state(colorop, - state->colorops[i].state); + state->colorops[i].state_to_destroy); state->colorops[i].ptr = NULL; - state->colorops[i].state = NULL; + state->colorops[i].state_to_destroy = NULL; state->colorops[i].old_state = NULL; state->colorops[i].new_state = NULL; } @@ -353,8 +358,13 @@ void drm_atomic_commit_default_clear(struct drm_atomic_commit *state) for (i = 0; i < state->num_private_objs; i++) { struct drm_private_obj *obj = state->private_objs[i].ptr; - obj->funcs->atomic_destroy_state(obj, - state->private_objs[i].state_to_destroy); + if (!obj) + continue; + + if (state->private_objs[i].state_to_destroy) + obj->funcs->atomic_destroy_state(obj, + state->private_objs[i].state_to_destroy); + state->private_objs[i].ptr = NULL; state->private_objs[i].state_to_destroy = NULL; state->private_objs[i].old_state = NULL; @@ -708,7 +718,7 @@ drm_atomic_get_colorop_state(struct drm_atomic_commit *state, if (!colorop_state) return ERR_PTR(-ENOMEM); - state->colorops[index].state = colorop_state; + state->colorops[index].state_to_destroy = colorop_state; state->colorops[index].ptr = colorop; state->colorops[index].old_state = colorop->state; state->colorops[index].new_state = colorop_state; diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 285aac3554df..9d006f98413a 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include @@ -49,6 +48,7 @@ #include "drm_crtc_helper_internal.h" #include "drm_crtc_internal.h" +#include "drm_panic_internal.h" /** * DOC: overview @@ -2037,7 +2037,7 @@ void drm_atomic_helper_commit_tail_rpm(struct drm_atomic_commit *state) } EXPORT_SYMBOL(drm_atomic_helper_commit_tail_rpm); -static void commit_tail(struct drm_atomic_commit *state) +static void commit_tail(struct drm_atomic_commit *state, bool nonblock) { struct drm_device *dev = state->dev; const struct drm_mode_config_helper_funcs *funcs; @@ -2095,7 +2095,7 @@ static void commit_work(struct work_struct *work) struct drm_atomic_commit *state = container_of(work, struct drm_atomic_commit, commit_work); - commit_tail(state); + commit_tail(state, true); } /** @@ -2315,7 +2315,7 @@ int drm_atomic_helper_commit(struct drm_device *dev, if (nonblock) queue_work(system_dfl_wq, &state->commit_work); else - commit_tail(state); + commit_tail(state, false); return 0; @@ -3351,7 +3351,7 @@ int drm_atomic_helper_swap_state(struct drm_atomic_commit *state, old_colorop_state->state = state; new_colorop_state->state = NULL; - state->colorops[i].state = old_colorop_state; + state->colorops[i].state_to_destroy = old_colorop_state; colorop->state = new_colorop_state; } diff --git a/drivers/gpu/drm/drm_atomic_state_helper.c b/drivers/gpu/drm/drm_atomic_state_helper.c index a2ef272e9f27..406157a3660f 100644 --- a/drivers/gpu/drm/drm_atomic_state_helper.c +++ b/drivers/gpu/drm/drm_atomic_state_helper.c @@ -79,51 +79,6 @@ __drm_atomic_helper_crtc_state_init(struct drm_crtc_state *crtc_state, } EXPORT_SYMBOL(__drm_atomic_helper_crtc_state_init); -/** - * __drm_atomic_helper_crtc_reset - reset state on CRTC - * @crtc: drm CRTC - * @crtc_state: CRTC state to assign - * - * Initializes the newly allocated @crtc_state and assigns it to - * the &drm_crtc->state pointer of @crtc, usually required when - * initializing the drivers or when called from the &drm_crtc_funcs.reset - * hook. - * - * This is useful for drivers that subclass the CRTC state. - */ -void -__drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, - struct drm_crtc_state *crtc_state) -{ - if (crtc_state) - __drm_atomic_helper_crtc_state_init(crtc_state, crtc); - - if (drm_dev_has_vblank(crtc->dev)) - drm_crtc_vblank_reset(crtc); - - crtc->state = crtc_state; -} -EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset); - -/** - * drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs - * @crtc: drm CRTC - * - * Resets the atomic state for @crtc by freeing the state pointer (which might - * be NULL, e.g. at driver load time) and allocating a new empty state object. - */ -void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc) -{ - struct drm_crtc_state *crtc_state = - kzalloc_obj(*crtc->state); - - if (crtc->state) - crtc->funcs->atomic_destroy_state(crtc, crtc->state); - - __drm_atomic_helper_crtc_reset(crtc, crtc_state); -} -EXPORT_SYMBOL(drm_atomic_helper_crtc_reset); - /** * drm_atomic_helper_crtc_create_state - default &drm_crtc_funcs.atomic_create_state hook for crtcs * @crtc: crtc object @@ -331,47 +286,6 @@ void __drm_atomic_helper_plane_state_init(struct drm_plane_state *plane_state, } EXPORT_SYMBOL(__drm_atomic_helper_plane_state_init); -/** - * __drm_atomic_helper_plane_reset - reset state on plane - * @plane: drm plane - * @plane_state: plane state to assign - * - * Initializes the newly allocated @plane_state and assigns it to - * the &drm_plane->state pointer of @plane, usually required when - * initializing the drivers or when called from the &drm_plane_funcs.reset - * hook. - * - * This is useful for drivers that subclass the plane state. - */ -void __drm_atomic_helper_plane_reset(struct drm_plane *plane, - struct drm_plane_state *plane_state) -{ - if (plane_state) - __drm_atomic_helper_plane_state_init(plane_state, plane); - - plane->state = plane_state; -} -EXPORT_SYMBOL(__drm_atomic_helper_plane_reset); - -/** - * drm_atomic_helper_plane_reset - default &drm_plane_funcs.reset hook for planes - * @plane: drm plane - * - * Resets the atomic state for @plane by freeing the state pointer (which might - * be NULL, e.g. at driver load time) and allocating a new empty state object. - */ -void drm_atomic_helper_plane_reset(struct drm_plane *plane) -{ - if (plane->state) - __drm_atomic_helper_plane_destroy_state(plane->state); - - kfree(plane->state); - plane->state = kzalloc_obj(*plane->state); - if (plane->state) - __drm_atomic_helper_plane_reset(plane, plane->state); -} -EXPORT_SYMBOL(drm_atomic_helper_plane_reset); - /** * drm_atomic_helper_plane_create_state - default &drm_plane_funcs.atomic_create_state hook for planes * @plane: plane object diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c index 83f1809a5d37..649f6b6ab5c8 100644 --- a/drivers/gpu/drm/drm_bridge.c +++ b/drivers/gpu/drm/drm_bridge.c @@ -549,10 +549,31 @@ drm_bridge_atomic_create_priv_state(struct drm_private_obj *obj) return &state->base; } +static void +drm_bridge_atomic_print_priv_state(struct drm_printer *p, + const struct drm_private_state *s) +{ + const struct drm_bridge_state *state = drm_priv_to_bridge_state(s); + struct drm_bridge *bridge = drm_priv_to_bridge(s->obj); + + if (bridge->of_node) + drm_printf(p, "bridge: %ps (%pOFfc)\n", bridge->funcs, bridge->of_node); + else + drm_printf(p, "bridge: %ps\n", bridge->funcs); + + drm_printf_indent(p, 1, "input bus configuration:"); + drm_printf_indent(p, 2, "code: %04x", state->input_bus_cfg.format); + drm_printf_indent(p, 2, "flags: %08x", state->input_bus_cfg.flags); + drm_printf_indent(p, 1, "output bus configuration:"); + drm_printf_indent(p, 2, "code: %04x", state->output_bus_cfg.format); + drm_printf_indent(p, 2, "flags: %08x", state->output_bus_cfg.flags); +} + static const struct drm_private_state_funcs drm_bridge_priv_state_funcs = { .atomic_create_state = drm_bridge_atomic_create_priv_state, .atomic_duplicate_state = drm_bridge_atomic_duplicate_priv_state, .atomic_destroy_state = drm_bridge_atomic_destroy_priv_state, + .atomic_print_state = drm_bridge_atomic_print_priv_state, }; /** diff --git a/drivers/gpu/drm/drm_client_event.c b/drivers/gpu/drm/drm_client_event.c index 7b3e362f7926..f0af584da23c 100644 --- a/drivers/gpu/drm/drm_client_event.c +++ b/drivers/gpu/drm/drm_client_event.c @@ -123,6 +123,24 @@ void drm_client_dev_restore(struct drm_device *dev, bool force) mutex_unlock(&dev->clientlist_mutex); } +void drm_client_dev_acquire_outputs(struct drm_device *dev) +{ + struct drm_client_dev *client; + + if (!drm_core_check_feature(dev, DRIVER_MODESET)) + return; + + mutex_lock(&dev->clientlist_mutex); + list_for_each_entry(client, &dev->clientlist, list) { + if (!client->funcs || !client->funcs->acquire_outputs) + continue; + + client->funcs->acquire_outputs(client); + } + mutex_unlock(&dev->clientlist_mutex); +} +EXPORT_SYMBOL(drm_client_dev_acquire_outputs); + static int drm_client_suspend(struct drm_client_dev *client) { struct drm_device *dev = client->dev; diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index 83146ffef00c..3492787c3697 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -322,13 +322,11 @@ bool drm_panic_is_enabled(struct drm_device *dev); void drm_panic_register(struct drm_device *dev); void drm_panic_unregister(struct drm_device *dev); void drm_panic_init(void); -void drm_panic_exit(void); #else static inline bool drm_panic_is_enabled(struct drm_device *dev) { return false; } static inline void drm_panic_register(struct drm_device *dev) {} static inline void drm_panic_unregister(struct drm_device *dev) {} static inline void drm_panic_init(void) {} -static inline void drm_panic_exit(void) {} #endif #endif /* __DRM_CRTC_INTERNAL_H__ */ diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index 8c0879c336e5..0cdc606af8d1 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -51,13 +51,13 @@ #include #include #include -#include #include #include #include #include "drm_crtc_internal.h" #include "drm_internal.h" +#include "drm_panic_internal.h" MODULE_AUTHOR("Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl"); MODULE_DESCRIPTION("DRM shared core routines"); @@ -1255,7 +1255,6 @@ static void drm_core_exit(void) { drm_ras_genl_family_unregister(); drm_privacy_screen_lookup_exit(); - drm_panic_exit(); accel_core_exit(); unregister_chrdev(DRM_MAJOR, "drm"); drm_debugfs_remove_root(); diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 1331efb4876c..3148038747b6 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -32,6 +32,7 @@ #include #include #include +#include /* for KHZ2PICOS() */ #include #include #include diff --git a/drivers/gpu/drm/drm_gem_atomic_helper.c b/drivers/gpu/drm/drm_gem_atomic_helper.c index 3bb6bfd560d3..dd9efa7e3216 100644 --- a/drivers/gpu/drm/drm_gem_atomic_helper.c +++ b/drivers/gpu/drm/drm_gem_atomic_helper.c @@ -319,26 +319,6 @@ void drm_gem_destroy_shadow_plane_state(struct drm_plane *plane, } EXPORT_SYMBOL(drm_gem_destroy_shadow_plane_state); -/** - * __drm_gem_reset_shadow_plane - resets a shadow-buffered plane - * @plane: the plane - * @shadow_plane_state: the shadow-buffered plane state - * - * This function resets state for shadow-buffered planes. Helpful - * for drivers that subclass struct drm_shadow_plane_state. - */ -void __drm_gem_reset_shadow_plane(struct drm_plane *plane, - struct drm_shadow_plane_state *shadow_plane_state) -{ - if (shadow_plane_state) { - __drm_atomic_helper_plane_reset(plane, &shadow_plane_state->base); - drm_format_conv_state_init(&shadow_plane_state->fmtcnv_state); - } else { - __drm_atomic_helper_plane_reset(plane, NULL); - } -} -EXPORT_SYMBOL(__drm_gem_reset_shadow_plane); - /** * drm_gem_begin_shadow_fb_access - prepares shadow framebuffers for CPU access * @plane: the plane diff --git a/drivers/gpu/drm/drm_kms_helper_common.c b/drivers/gpu/drm/drm_kms_helper_common.c index 0c7550c0462b..b5d5b469b444 100644 --- a/drivers/gpu/drm/drm_kms_helper_common.c +++ b/drivers/gpu/drm/drm_kms_helper_common.c @@ -27,6 +27,20 @@ #include +#include "drm_panic_internal.h" + +static int __init drm_kms_helper_init(void) +{ + return drm_panic_helper_init(); +} +module_init(drm_kms_helper_init); + +static void __exit drm_kms_helper_exit(void) +{ + drm_panic_helper_exit(); +} +module_exit(drm_kms_helper_exit); + MODULE_AUTHOR("David Airlie, Jesse Barnes"); MODULE_DESCRIPTION("DRM KMS helper"); MODULE_LICENSE("GPL and additional rights"); diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c index 366f6d821242..48a56f23dadb 100644 --- a/drivers/gpu/drm/drm_mode_config.c +++ b/drivers/gpu/drm/drm_mode_config.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -230,12 +231,22 @@ static int drm_mode_config_crtc_create_state(struct drm_crtc *crtc) static int drm_mode_config_crtc_reset_with_create_state(struct drm_crtc *crtc) { + const struct drm_crtc_helper_funcs *helper_funcs = crtc->helper_private; + int ret; + if (crtc->state) { crtc->funcs->atomic_destroy_state(crtc, crtc->state); crtc->state = NULL; } - return drm_mode_config_crtc_create_state(crtc); + ret = drm_mode_config_crtc_create_state(crtc); + if (ret) + return ret; + + if (helper_funcs && helper_funcs->hw_reset) + helper_funcs->hw_reset(crtc); + + return 0; } static int drm_mode_config_connector_create_state(struct drm_connector *connector) @@ -289,16 +300,12 @@ void drm_mode_config_reset(struct drm_device *dev) drm_colorop_reset(colorop); drm_for_each_plane(plane, dev) { - if (plane->funcs->reset) - plane->funcs->reset(plane); - else if (plane->funcs->atomic_create_state) + if (plane->funcs->atomic_create_state) drm_mode_config_plane_reset_with_create_state(plane); } drm_for_each_crtc(crtc, dev) { - if (crtc->funcs->reset) - crtc->funcs->reset(crtc); - else if (crtc->funcs->atomic_create_state) + if (crtc->funcs->atomic_create_state) drm_mode_config_crtc_reset_with_create_state(crtc); } diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c index e54584da4c3d..cca623eb23e5 100644 --- a/drivers/gpu/drm/drm_modeset_helper.c +++ b/drivers/gpu/drm/drm_modeset_helper.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -113,6 +114,7 @@ static const uint32_t safe_modeset_formats[] = { static const struct drm_plane_funcs primary_plane_funcs = { DRM_PLANE_NON_ATOMIC_FUNCS, + DRM_PANIC_PLANE_FUNCS, }; /** diff --git a/drivers/gpu/drm/drm_panic.c b/drivers/gpu/drm/drm_panic.c index e576c4791861..9fe97c4eda6c 100644 --- a/drivers/gpu/drm/drm_panic.c +++ b/drivers/gpu/drm/drm_panic.c @@ -7,33 +7,23 @@ */ #include -#include -#include #include -#include #include #include -#include #include #include #include #include #include #include -#include -#include #include -#include -#include -#include #include #include #include -#include #include "drm_crtc_internal.h" -#include "drm_draw_internal.h" +#include "drm_panic_internal.h" MODULE_AUTHOR("Jocelyn Falempe"); MODULE_DESCRIPTION("DRM panic handler"); @@ -42,783 +32,25 @@ MODULE_LICENSE("GPL"); /** * DOC: overview * - * To enable DRM panic for a driver, the primary plane must implement a - * &drm_plane_helper_funcs.get_scanout_buffer helper function. It is then - * automatically registered to the drm panic handler. - * When a panic occurs, the &drm_plane_helper_funcs.get_scanout_buffer will be - * called, and the driver can provide a framebuffer so the panic handler can - * draw the panic screen on it. Currently only linear buffer and a few color - * formats are supported. - * Optionally the driver can also provide a &drm_plane_helper_funcs.panic_flush - * callback, that will be called after that, to send additional commands to the - * hardware to make the scanout buffer visible. - */ - -/* - * This module displays a user friendly message on screen when a kernel panic - * occurs. This is conflicting with fbcon, so you can only enable it when fbcon - * is disabled. - * It's intended for end-user, so have minimal technical/debug information. + * This module displays a user friendly message on screen when a kernel + * panic occurs. It's intended for end users and therefore have minimal + * technical/debug information. * - * Implementation details: + * To enable DRM panic for a driver, the at least one primary plane must + * implement struct &drm_plane_funcs.display_panic_screen. The plane is + * then automatically registered to the drm panic handler. * - * It is a panic handler, so it can't take lock, allocate memory, run tasks/irq, - * or attempt to sleep. It's a best effort, and it may not be able to display - * the message in all situations (like if the panic occurs in the middle of a - * modesetting). - * It will display only one static frame, so performance optimizations are low - * priority as the machine is already in an unusable state. + * When a panic occurs, the DRM panic handler calls struct + * &drm_plane_funcs.display_panic_screen. See + * drm_plane_helper_display_panic_screen() for a generic implementation. */ -struct drm_panic_line { - u32 len; - const char *txt; -}; - -#define PANIC_LINE(s) {.len = sizeof(s) - 1, .txt = s} - -static struct drm_panic_line panic_msg[] = { - PANIC_LINE("KERNEL PANIC!"), - PANIC_LINE(""), - PANIC_LINE("Please reboot your computer."), - PANIC_LINE(""), - PANIC_LINE(""), /* will be replaced by the panic description */ -}; - -static const size_t panic_msg_lines = ARRAY_SIZE(panic_msg); - -static const struct drm_panic_line logo_ascii[] = { - PANIC_LINE(" .--. _"), - PANIC_LINE(" |o_o | | |"), - PANIC_LINE(" |:_/ | | |"), - PANIC_LINE(" // \\ \\ |_|"), - PANIC_LINE(" (| | ) _"), - PANIC_LINE(" /'\\_ _/`\\ (_)"), - PANIC_LINE(" \\___)=(___/"), -}; - -static const size_t logo_ascii_lines = ARRAY_SIZE(logo_ascii); - -#if defined(CONFIG_LOGO) && !defined(MODULE) -static const struct linux_logo *logo_mono; - -static int drm_panic_setup_logo(void) -{ - const struct linux_logo *logo = fb_find_logo(1); - const unsigned char *logo_data; - struct linux_logo *logo_dup; - - if (!logo || logo->type != LINUX_LOGO_MONO) - return 0; - - /* The logo is __init, so we must make a copy for later use */ - logo_data = kmemdup(logo->data, - size_mul(DIV_ROUND_UP(logo->width, BITS_PER_BYTE), logo->height), - GFP_KERNEL); - if (!logo_data) - return -ENOMEM; - - logo_dup = kmemdup(logo, sizeof(*logo), GFP_KERNEL); - if (!logo_dup) { - kfree(logo_data); - return -ENOMEM; - } - - logo_dup->data = logo_data; - logo_mono = logo_dup; - - return 0; -} - -device_initcall(drm_panic_setup_logo); -#else -#define logo_mono ((const struct linux_logo *)NULL) -#endif - -/* - * Blit & Fill functions - */ -static void drm_panic_blit_pixel(struct drm_scanout_buffer *sb, struct drm_rect *clip, - const u8 *sbuf8, unsigned int spitch, unsigned int scale, - u32 fg_color) -{ - unsigned int y, x; - - for (y = 0; y < drm_rect_height(clip); y++) - for (x = 0; x < drm_rect_width(clip); x++) - if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) - sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, fg_color); -} - -static void drm_panic_write_pixel16(void *vaddr, unsigned int offset, u16 color) -{ - u16 *p = vaddr + offset; - - *p = color; -} - -static void drm_panic_write_pixel24(void *vaddr, unsigned int offset, u32 color) -{ - u8 *p = vaddr + offset; - - *p++ = color & 0xff; - color >>= 8; - *p++ = color & 0xff; - color >>= 8; - *p = color & 0xff; -} - -/* - * Special case if the pixel crosses page boundaries - */ -static void drm_panic_write_pixel24_xpage(void *vaddr, struct page *next_page, - unsigned int offset, u32 color) -{ - u8 *vaddr2; - u8 *p = vaddr + offset; - - vaddr2 = kmap_local_page_try_from_panic(next_page); - - *p++ = color & 0xff; - color >>= 8; - - if (offset == PAGE_SIZE - 1) - p = vaddr2; - - *p++ = color & 0xff; - color >>= 8; - - if (offset == PAGE_SIZE - 2) - p = vaddr2; - - *p = color & 0xff; - kunmap_local(vaddr2); -} - -static void drm_panic_write_pixel32(void *vaddr, unsigned int offset, u32 color) -{ - u32 *p = vaddr + offset; - - *p = color; -} - -static void drm_panic_write_pixel(void *vaddr, unsigned int offset, u32 color, unsigned int cpp) -{ - switch (cpp) { - case 2: - drm_panic_write_pixel16(vaddr, offset, color); - break; - case 3: - drm_panic_write_pixel24(vaddr, offset, color); - break; - case 4: - drm_panic_write_pixel32(vaddr, offset, color); - break; - default: - pr_debug_once("Can't blit with pixel width %d\n", cpp); - } -} - -/* - * The scanout buffer pages are not mapped, so for each pixel, - * use kmap_local_page_try_from_panic() to map the page, and write the pixel. - * Try to keep the map from the previous pixel, to avoid too much map/unmap. - */ -static void drm_panic_blit_page(struct page **pages, unsigned int dpitch, - unsigned int cpp, const u8 *sbuf8, - unsigned int spitch, struct drm_rect *clip, - unsigned int scale, u32 fg32) -{ - unsigned int y, x; - unsigned int page = ~0; - unsigned int height = drm_rect_height(clip); - unsigned int width = drm_rect_width(clip); - void *vaddr = NULL; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) { - unsigned int new_page; - unsigned int offset; - - offset = (y + clip->y1) * dpitch + (x + clip->x1) * cpp; - new_page = offset >> PAGE_SHIFT; - offset = offset % PAGE_SIZE; - if (new_page != page) { - if (!pages[new_page]) - continue; - if (vaddr) - kunmap_local(vaddr); - page = new_page; - vaddr = kmap_local_page_try_from_panic(pages[page]); - } - if (!vaddr) - continue; - - // Special case for 24bit, as a pixel might cross page boundaries - if (cpp == 3 && offset + 3 > PAGE_SIZE) - drm_panic_write_pixel24_xpage(vaddr, pages[page + 1], - offset, fg32); - else - drm_panic_write_pixel(vaddr, offset, fg32, cpp); - } - } - } - if (vaddr) - kunmap_local(vaddr); -} - -/* - * drm_panic_blit - convert a monochrome image to a linear framebuffer - * @sb: destination scanout buffer - * @clip: destination rectangle - * @sbuf8: source buffer, in monochrome format, 8 pixels per byte. - * @spitch: source pitch in bytes - * @scale: integer scale, source buffer is scale time smaller than destination - * rectangle - * @fg_color: foreground color, in destination format - * - * This can be used to draw a font character, which is a monochrome image, to a - * framebuffer in other supported format. - */ -static void drm_panic_blit(struct drm_scanout_buffer *sb, struct drm_rect *clip, - const u8 *sbuf8, unsigned int spitch, - unsigned int scale, u32 fg_color) - -{ - struct iosys_map map; - - if (sb->set_pixel) - return drm_panic_blit_pixel(sb, clip, sbuf8, spitch, scale, fg_color); - - if (sb->pages) - return drm_panic_blit_page(sb->pages, sb->pitch[0], sb->format->cpp[0], - sbuf8, spitch, clip, scale, fg_color); - - map = sb->map[0]; - iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]); - - switch (sb->format->cpp[0]) { - case 2: - drm_draw_blit16(&map, sb->pitch[0], sbuf8, spitch, - drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); - break; - case 3: - drm_draw_blit24(&map, sb->pitch[0], sbuf8, spitch, - drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); - break; - case 4: - drm_draw_blit32(&map, sb->pitch[0], sbuf8, spitch, - drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); - break; - default: - WARN_ONCE(1, "Can't blit with pixel width %d\n", sb->format->cpp[0]); - } -} - -static void drm_panic_fill_pixel(struct drm_scanout_buffer *sb, - struct drm_rect *clip, - u32 color) -{ - unsigned int y, x; - - for (y = 0; y < drm_rect_height(clip); y++) - for (x = 0; x < drm_rect_width(clip); x++) - sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, color); -} - -static void drm_panic_fill_page(struct page **pages, unsigned int dpitch, - unsigned int cpp, struct drm_rect *clip, - u32 color) -{ - unsigned int y, x; - unsigned int page = ~0; - void *vaddr = NULL; - - for (y = clip->y1; y < clip->y2; y++) { - for (x = clip->x1; x < clip->x2; x++) { - unsigned int new_page; - unsigned int offset; - - offset = y * dpitch + x * cpp; - new_page = offset >> PAGE_SHIFT; - offset = offset % PAGE_SIZE; - if (new_page != page) { - if (vaddr) - kunmap_local(vaddr); - page = new_page; - vaddr = kmap_local_page_try_from_panic(pages[page]); - } - if (!vaddr) - continue; - - // Special case for 24bit, as a pixel might cross page boundaries - if (cpp == 3 && offset + 3 > PAGE_SIZE) - drm_panic_write_pixel24_xpage(vaddr, pages[page + 1], - offset, color); - else - drm_panic_write_pixel(vaddr, offset, color, cpp); - } - } - if (vaddr) - kunmap_local(vaddr); -} - -/* - * drm_panic_fill - Fill a rectangle with a color - * @sb: destination scanout buffer - * @clip: destination rectangle - * @color: foreground color, in destination format - * - * Fill a rectangle with a color, in a linear framebuffer. - */ -static void drm_panic_fill(struct drm_scanout_buffer *sb, struct drm_rect *clip, - u32 color) -{ - struct iosys_map map; - - if (sb->set_pixel) - return drm_panic_fill_pixel(sb, clip, color); - - if (sb->pages) - return drm_panic_fill_page(sb->pages, sb->pitch[0], sb->format->cpp[0], - clip, color); - - map = sb->map[0]; - iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]); - - switch (sb->format->cpp[0]) { - case 2: - drm_draw_fill16(&map, sb->pitch[0], drm_rect_height(clip), - drm_rect_width(clip), color); - break; - case 3: - drm_draw_fill24(&map, sb->pitch[0], drm_rect_height(clip), - drm_rect_width(clip), color); - break; - case 4: - drm_draw_fill32(&map, sb->pitch[0], drm_rect_height(clip), - drm_rect_width(clip), color); - break; - default: - WARN_ONCE(1, "Can't fill with pixel width %d\n", sb->format->cpp[0]); - } -} - -static unsigned int get_max_line_len(const struct drm_panic_line *lines, int len) -{ - int i; - unsigned int max = 0; - - for (i = 0; i < len; i++) - max = max(lines[i].len, max); - return max; -} - -/* - * Draw a text in a rectangle on a framebuffer. The text is truncated if it overflows the rectangle - */ -static void draw_txt_rectangle(struct drm_scanout_buffer *sb, - const struct font_desc *font, - const struct drm_panic_line *msg, - unsigned int msg_lines, - bool centered, - struct drm_rect *clip, - u32 color) -{ - int i, j; - const u8 *src; - size_t font_pitch = DIV_ROUND_UP(font->width, 8); - struct drm_rect rec; - - msg_lines = min(msg_lines, drm_rect_height(clip) / font->height); - for (i = 0; i < msg_lines; i++) { - size_t line_len = min(msg[i].len, drm_rect_width(clip) / font->width); - - rec.y1 = clip->y1 + i * font->height; - rec.y2 = rec.y1 + font->height; - rec.x1 = clip->x1; - - if (centered) - rec.x1 += (drm_rect_width(clip) - (line_len * font->width)) / 2; - - for (j = 0; j < line_len; j++) { - src = font_data_glyph_buf(font->data, font->width, font->height, - (unsigned char)msg[i].txt[j]); - rec.x2 = rec.x1 + font->width; - if (src) - drm_panic_blit(sb, &rec, src, font_pitch, 1, color); - rec.x1 += font->width; - } - } -} - -static void drm_panic_logo_rect(struct drm_rect *rect, const struct font_desc *font) -{ - if (logo_mono) { - drm_rect_init(rect, 0, 0, logo_mono->width, logo_mono->height); - } else { - int logo_width = get_max_line_len(logo_ascii, logo_ascii_lines) * font->width; - - drm_rect_init(rect, 0, 0, logo_width, logo_ascii_lines * font->height); - } -} - -static void drm_panic_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *rect, - const struct font_desc *font, u32 fg_color) -{ - if (rect->x2 > sb->width || rect->y2 > sb->height) - return; - - if (logo_mono) - drm_panic_blit(sb, rect, logo_mono->data, - DIV_ROUND_UP(drm_rect_width(rect), 8), 1, fg_color); - else - draw_txt_rectangle(sb, font, logo_ascii, logo_ascii_lines, false, rect, - fg_color); -} - -static void draw_panic_screen_user(struct drm_scanout_buffer *sb) -{ - u32 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR, - sb->format->format); - u32 bg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, - sb->format->format); - const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL); - struct drm_rect r_screen, r_logo, r_msg; - unsigned int msg_width, msg_height; - - if (!font) - return; - - r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); - drm_panic_logo_rect(&r_logo, font); - - msg_width = min(get_max_line_len(panic_msg, panic_msg_lines) * font->width, sb->width); - msg_height = min(panic_msg_lines * font->height, sb->height); - r_msg = DRM_RECT_INIT(0, 0, msg_width, msg_height); - - /* Center the panic message */ - drm_rect_translate(&r_msg, (sb->width - r_msg.x2) / 2, (sb->height - r_msg.y2) / 2); - - /* Fill with the background color, and draw text on top */ - drm_panic_fill(sb, &r_screen, bg_color); - - if (!drm_rect_overlap(&r_logo, &r_msg)) - drm_panic_logo_draw(sb, &r_logo, font, fg_color); - - draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color); -} - -/* - * Draw one line of kmsg, and handle wrapping if it won't fit in the screen width. - * Return the y-offset of the next line. - */ -static int draw_line_with_wrap(struct drm_scanout_buffer *sb, const struct font_desc *font, - struct drm_panic_line *line, int yoffset, u32 fg_color) -{ - int chars_per_row = sb->width / font->width; - struct drm_rect r_txt = DRM_RECT_INIT(0, yoffset, sb->width, font->height); - struct drm_panic_line line_wrap; - - if (line->len > chars_per_row) { - line_wrap.len = line->len % chars_per_row; - line_wrap.txt = line->txt + line->len - line_wrap.len; - draw_txt_rectangle(sb, font, &line_wrap, 1, false, &r_txt, fg_color); - r_txt.y1 -= font->height; - if (r_txt.y1 < 0) - return r_txt.y1; - while (line_wrap.txt > line->txt) { - line_wrap.txt -= chars_per_row; - line_wrap.len = chars_per_row; - draw_txt_rectangle(sb, font, &line_wrap, 1, false, &r_txt, fg_color); - r_txt.y1 -= font->height; - if (r_txt.y1 < 0) - return r_txt.y1; - } - } else { - draw_txt_rectangle(sb, font, line, 1, false, &r_txt, fg_color); - r_txt.y1 -= font->height; - } - return r_txt.y1; -} - -/* - * Draw the kmsg buffer to the screen, starting from the youngest message at the bottom, - * and going up until reaching the top of the screen. - */ -static void draw_panic_screen_kmsg(struct drm_scanout_buffer *sb) -{ - u32 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR, - sb->format->format); - u32 bg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, - sb->format->format); - const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL); - struct drm_rect r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); - struct kmsg_dump_iter iter; - char kmsg_buf[512]; - size_t kmsg_len; - struct drm_panic_line line; - int yoffset; - - if (!font || font->width > sb->width) - return; - - yoffset = sb->height - font->height - (sb->height % font->height) / 2; - - /* Fill with the background color, and draw text on top */ - drm_panic_fill(sb, &r_screen, bg_color); - - kmsg_dump_rewind(&iter); - while (kmsg_dump_get_buffer(&iter, false, kmsg_buf, sizeof(kmsg_buf), &kmsg_len)) { - char *start; - char *end; - - /* ignore terminating NUL and newline */ - start = kmsg_buf + kmsg_len - 2; - end = kmsg_buf + kmsg_len - 1; - while (start > kmsg_buf && yoffset >= 0) { - while (start > kmsg_buf && *start != '\n') - start--; - /* don't count the newline character */ - line.txt = start + (start == kmsg_buf ? 0 : 1); - line.len = end - line.txt; - - yoffset = draw_line_with_wrap(sb, font, &line, yoffset, fg_color); - end = start; - start--; - } - } -} - #if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE) -/* - * It is unwise to allocate memory in the panic callback, so the buffers are - * pre-allocated. Only 2 buffers and the zlib workspace are needed. - * Two buffers are enough, using the following buffer usage: - * 1) kmsg messages are dumped in buffer1 - * 2) kmsg is zlib-compressed into buffer2 - * 3) compressed kmsg is encoded as QR-code Numeric stream in buffer1 - * 4) QR-code image is generated in buffer2 - * The Max QR code size is V40, 177x177, 4071 bytes for image, 2956 bytes for - * data segments. - * - * Typically, ~7500 bytes of kmsg, are compressed into 2800 bytes, which fits in - * a V40 QR-code (177x177). - * - * If CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL is not set, the kmsg data will be put - * directly in the QR code. - * 1) kmsg messages are dumped in buffer1 - * 2) kmsg message is encoded as byte stream in buffer2 - * 3) QR-code image is generated in buffer1 - */ - static uint panic_qr_version = CONFIG_DRM_PANIC_SCREEN_QR_VERSION; module_param(panic_qr_version, uint, 0644); MODULE_PARM_DESC(panic_qr_version, "maximum version (size) of the QR code"); - -#define MAX_QR_DATA 2956 -#define MAX_ZLIB_RATIO 3 -#define QR_BUFFER1_SIZE (MAX_ZLIB_RATIO * MAX_QR_DATA) /* Must also be > 4071 */ -#define QR_BUFFER2_SIZE 4096 -#define QR_MARGIN 4 /* 4 modules of foreground color around the qr code */ - -/* Compression parameters */ -#define COMPR_LEVEL 6 -#define WINDOW_BITS 12 -#define MEM_LEVEL 4 - -static char *qrbuf1; -static char *qrbuf2; -static struct z_stream_s stream; - -static void __init drm_panic_qr_init(void) -{ - qrbuf1 = kmalloc(QR_BUFFER1_SIZE, GFP_KERNEL); - qrbuf2 = kmalloc(QR_BUFFER2_SIZE, GFP_KERNEL); - stream.workspace = kmalloc(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL), - GFP_KERNEL); -} - -static void drm_panic_qr_exit(void) -{ - kfree(qrbuf1); - qrbuf1 = NULL; - kfree(qrbuf2); - qrbuf2 = NULL; - kfree(stream.workspace); - stream.workspace = NULL; -} - -static int drm_panic_get_qr_code_url(u8 **qr_image) -{ - struct kmsg_dump_iter iter; - char url[256]; - size_t kmsg_len, max_kmsg_size; - char *kmsg; - int max_qr_data_size, url_len; - - url_len = snprintf(url, sizeof(url), CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL "?a=%s&v=%s&z=", - utsname()->machine, utsname()->release); - - max_qr_data_size = drm_panic_qr_max_data_size(panic_qr_version, url_len); - max_kmsg_size = min(MAX_ZLIB_RATIO * max_qr_data_size, QR_BUFFER1_SIZE); - - /* get kmsg to buffer 1 */ - kmsg_dump_rewind(&iter); - kmsg_dump_get_buffer(&iter, false, qrbuf1, max_kmsg_size, &kmsg_len); - - if (!kmsg_len) - return -ENODATA; - kmsg = qrbuf1; - -try_again: - if (zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS, - MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK) - return -EINVAL; - - stream.next_in = kmsg; - stream.avail_in = kmsg_len; - stream.total_in = 0; - stream.next_out = qrbuf2; - stream.avail_out = QR_BUFFER2_SIZE; - stream.total_out = 0; - - if (zlib_deflate(&stream, Z_FINISH) != Z_STREAM_END) - return -EINVAL; - - if (zlib_deflateEnd(&stream) != Z_OK) - return -EINVAL; - - if (stream.total_out > max_qr_data_size) { - /* too much data for the QR code, so skip the first line and try again */ - kmsg = strchr(kmsg, '\n'); - if (!kmsg) - return -EINVAL; - /* skip the first \n */ - kmsg += 1; - kmsg_len = strlen(kmsg); - goto try_again; - } - *qr_image = qrbuf2; - - /* generate qr code image in buffer2 */ - return drm_panic_qr_generate(url, qrbuf2, stream.total_out, QR_BUFFER2_SIZE, - qrbuf1, QR_BUFFER1_SIZE); -} - -static int drm_panic_get_qr_code_raw(u8 **qr_image) -{ - struct kmsg_dump_iter iter; - size_t kmsg_len; - size_t max_kmsg_size = min(drm_panic_qr_max_data_size(panic_qr_version, 0), - QR_BUFFER1_SIZE); - - kmsg_dump_rewind(&iter); - kmsg_dump_get_buffer(&iter, false, qrbuf1, max_kmsg_size, &kmsg_len); - if (!kmsg_len) - return -ENODATA; - - *qr_image = qrbuf1; - return drm_panic_qr_generate(NULL, qrbuf1, kmsg_len, QR_BUFFER1_SIZE, - qrbuf2, QR_BUFFER2_SIZE); -} - -static int drm_panic_get_qr_code(u8 **qr_image) -{ - if (strlen(CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL) > 0) - return drm_panic_get_qr_code_url(qr_image); - else - return drm_panic_get_qr_code_raw(qr_image); -} - -/* - * Draw the panic message at the center of the screen, with a QR Code - */ -static int _draw_panic_screen_qr_code(struct drm_scanout_buffer *sb) -{ - u32 fg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_FOREGROUND_COLOR, - sb->format->format); - u32 bg_color = drm_draw_color_from_xrgb8888(CONFIG_DRM_PANIC_BACKGROUND_COLOR, - sb->format->format); - const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL); - struct drm_rect r_screen, r_logo, r_msg, r_qr, r_qr_canvas; - unsigned int max_qr_size, scale; - unsigned int msg_width, msg_height; - int qr_width, qr_canvas_width, qr_pitch, v_margin; - u8 *qr_image; - - if (!font || !qrbuf1 || !qrbuf2 || !stream.workspace) - return -ENOMEM; - - r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); - - drm_panic_logo_rect(&r_logo, font); - - msg_width = min(get_max_line_len(panic_msg, panic_msg_lines) * font->width, sb->width); - msg_height = min(panic_msg_lines * font->height, sb->height); - r_msg = DRM_RECT_INIT(0, 0, msg_width, msg_height); - - max_qr_size = min(3 * sb->width / 4, 3 * sb->height / 4); - - qr_width = drm_panic_get_qr_code(&qr_image); - if (qr_width <= 0) - return -ENOSPC; - - qr_canvas_width = qr_width + QR_MARGIN * 2; - scale = max_qr_size / qr_canvas_width; - /* QR code is not readable if not scaled at least by 2 */ - if (scale < 2) - return -ENOSPC; - - pr_debug("QR width %d and scale %d\n", qr_width, scale); - r_qr_canvas = DRM_RECT_INIT(0, 0, qr_canvas_width * scale, qr_canvas_width * scale); - - v_margin = sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg); - if (v_margin < 0) - return -ENOSPC; - v_margin /= 5; - - drm_rect_translate(&r_qr_canvas, (sb->width - r_qr_canvas.x2) / 2, 2 * v_margin); - r_qr = DRM_RECT_INIT(r_qr_canvas.x1 + QR_MARGIN * scale, r_qr_canvas.y1 + QR_MARGIN * scale, - qr_width * scale, qr_width * scale); - - /* Center the panic message */ - drm_rect_translate(&r_msg, (sb->width - r_msg.x2) / 2, - 3 * v_margin + drm_rect_height(&r_qr_canvas)); - - /* Fill with the background color, and draw text on top */ - drm_panic_fill(sb, &r_screen, bg_color); - - if (!drm_rect_overlap(&r_logo, &r_msg) && !drm_rect_overlap(&r_logo, &r_qr_canvas)) - drm_panic_logo_draw(sb, &r_logo, font, fg_color); - - draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color); - - /* Draw the qr code */ - qr_pitch = DIV_ROUND_UP(qr_width, 8); - drm_panic_fill(sb, &r_qr_canvas, fg_color); - drm_panic_fill(sb, &r_qr, bg_color); - drm_panic_blit(sb, &r_qr, qr_image, qr_pitch, scale, fg_color); - return 0; -} - -static void draw_panic_screen_qr_code(struct drm_scanout_buffer *sb) -{ - if (_draw_panic_screen_qr_code(sb)) - draw_panic_screen_user(sb); -} -#else -static void drm_panic_qr_init(void) {}; -static void drm_panic_qr_exit(void) {}; #endif -enum drm_panic_type { - DRM_PANIC_TYPE_KMSG, - DRM_PANIC_TYPE_USER, - DRM_PANIC_TYPE_QR, -}; - static enum drm_panic_type drm_panic_type = -1; static const char *drm_panic_type_map[] = { @@ -863,91 +95,34 @@ MODULE_PARM_DESC(panic_screen, #endif CONFIG_DRM_PANIC_SCREEN "]"); -/* - * drm_panic_is_format_supported() - * @format: a fourcc color code - * Returns: true if supported, false otherwise. - * - * Check if drm_panic will be able to use this color format. - */ -static bool drm_panic_is_format_supported(const struct drm_format_info *format) -{ - if (format->num_planes != 1) - return false; - return drm_draw_can_convert_from_xrgb8888(format->format); -} +#define drm_panic_trylock(dev, flags) \ + raw_spin_trylock_irqsave(&(dev)->mode_config.panic_lock, flags) -static void draw_panic_dispatch(struct drm_scanout_buffer *sb) +static void drm_panic_display_panic_screen(struct drm_plane *plane, const char *description) { - switch (drm_panic_type) { - case DRM_PANIC_TYPE_KMSG: - draw_panic_screen_kmsg(sb); - break; - -#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE) - case DRM_PANIC_TYPE_QR: - draw_panic_screen_qr_code(sb); - break; +#if defined(CONFIG_DRM_PANIC_FOREGROUND_COLOR) + u32 fg_color = CONFIG_DRM_PANIC_FOREGROUND_COLOR; +#else + u32 fg_color = 0x00ffffff; #endif - - case DRM_PANIC_TYPE_USER: - default: - draw_panic_screen_user(sb); - } -} - -static void drm_panic_set_description(const char *description) -{ - u32 len; - - if (description) { - struct drm_panic_line *desc_line = &panic_msg[panic_msg_lines - 1]; - - desc_line->txt = description; - len = strlen(description); - /* ignore the last newline character */ - if (len && description[len - 1] == '\n') - len -= 1; - desc_line->len = len; - } -} - -static void drm_panic_clear_description(void) -{ - struct drm_panic_line *desc_line = &panic_msg[panic_msg_lines - 1]; - - desc_line->len = 0; - desc_line->txt = NULL; -} - -static void draw_panic_plane(struct drm_plane *plane, const char *description) -{ - struct drm_scanout_buffer sb = { }; - int ret; +#if defined(CONFIG_DRM_PANIC_BACKGROUND_COLOR) + u32 bg_color = CONFIG_DRM_PANIC_BACKGROUND_COLOR; +#else + u32 bg_color = 0x00000000; +#endif +#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE) + unsigned int qr_version = panic_qr_version; +#else + unsigned int qr_version = 0; +#endif + struct drm_device *dev = plane->dev; unsigned long flags; - if (!drm_panic_trylock(plane->dev, flags)) - return; - - ret = plane->helper_private->get_scanout_buffer(plane, &sb); - - if (ret || !drm_panic_is_format_supported(sb.format)) - goto unlock; - - /* One of these should be set, or it can't draw pixels */ - if (!sb.set_pixel && !sb.pages && iosys_map_is_null(&sb.map[0])) - goto unlock; - - drm_panic_set_description(description); - - draw_panic_dispatch(&sb); - if (plane->helper_private->panic_flush) - plane->helper_private->panic_flush(plane); - - drm_panic_clear_description(); - -unlock: - drm_panic_unlock(plane->dev, flags); + if (drm_panic_trylock(dev, flags)) { + plane->funcs->display_panic_screen(plane, description, drm_panic_type, + fg_color, bg_color, qr_version); + drm_panic_unlock(dev, flags); + } } static struct drm_plane *to_drm_plane(struct kmsg_dumper *kd) @@ -960,10 +135,9 @@ static void drm_panic(struct kmsg_dumper *dumper, struct kmsg_dump_detail *detai struct drm_plane *plane = to_drm_plane(dumper); if (detail->reason == KMSG_DUMP_PANIC) - draw_panic_plane(plane, detail->description); + drm_panic_display_panic_screen(plane, detail->description); } - /* * DEBUG FS, This is currently unsafe. * Create one file per plane, so it's possible to debug one plane at a time. @@ -980,7 +154,7 @@ static ssize_t debugfs_trigger_write(struct file *file, const char __user *user_ if (kstrtobool_from_user(user_buf, count, &run) == 0 && run) { struct drm_plane *plane = file->private_data; - draw_panic_plane(plane, "Test from debugfs"); + drm_panic_display_panic_screen(plane, "Test from debugfs"); } return count; } @@ -1016,9 +190,13 @@ bool drm_panic_is_enabled(struct drm_device *dev) if (!dev->mode_config.num_total_plane) return false; - drm_for_each_plane(plane, dev) - if (plane->helper_private && plane->helper_private->get_scanout_buffer) - return true; + drm_for_each_plane(plane, dev) { + if (plane->type != DRM_PLANE_TYPE_PRIMARY) + continue; + if (!plane->funcs || !plane->funcs->display_panic_screen) + continue; + return true; + } return false; } EXPORT_SYMBOL(drm_panic_is_enabled); @@ -1036,7 +214,9 @@ void drm_panic_register(struct drm_device *dev) return; drm_for_each_plane(plane, dev) { - if (!plane->helper_private || !plane->helper_private->get_scanout_buffer) + if (plane->type != DRM_PLANE_TYPE_PRIMARY) + continue; + if (!plane->funcs || !plane->funcs->display_panic_screen) continue; plane->kmsg_panic.dump = drm_panic; plane->kmsg_panic.max_reason = KMSG_DUMP_PANIC; @@ -1063,7 +243,9 @@ void drm_panic_unregister(struct drm_device *dev) return; drm_for_each_plane(plane, dev) { - if (!plane->helper_private || !plane->helper_private->get_scanout_buffer) + if (plane->type != DRM_PLANE_TYPE_PRIMARY) + continue; + if (!plane->funcs || !plane->funcs->display_panic_screen) continue; kmsg_dump_unregister(&plane->kmsg_panic); } @@ -1079,17 +261,4 @@ void __init drm_panic_init(void) CONFIG_DRM_PANIC_SCREEN); drm_panic_type = DRM_PANIC_TYPE_USER; } - drm_panic_qr_init(); } - -/** - * drm_panic_exit() - Free the resources taken by drm_panic_exit() - */ -void drm_panic_exit(void) -{ - drm_panic_qr_exit(); -} - -#ifdef CONFIG_DRM_KUNIT_TEST -#include "tests/drm_panic_test.c" -#endif diff --git a/drivers/gpu/drm/drm_panic_helper.c b/drivers/gpu/drm/drm_panic_helper.c new file mode 100644 index 000000000000..8913c3d22e8d --- /dev/null +++ b/drivers/gpu/drm/drm_panic_helper.c @@ -0,0 +1,919 @@ +// SPDX-License-Identifier: GPL-2.0 or MIT + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "drm_draw_internal.h" +#include "drm_panic_internal.h" + +struct drm_panic_line { + u32 len; + const char *txt; +}; + +#define PANIC_LINE(s) {.len = sizeof(s) - 1, .txt = s} + +static struct drm_panic_line panic_msg[] = { + PANIC_LINE("KERNEL PANIC!"), + PANIC_LINE(""), + PANIC_LINE("Please reboot your computer."), + PANIC_LINE(""), + PANIC_LINE(""), /* will be replaced by the panic description */ +}; + +static const size_t panic_msg_lines = ARRAY_SIZE(panic_msg); + +static const struct drm_panic_line logo_ascii[] = { + PANIC_LINE(" .--. _"), + PANIC_LINE(" |o_o | | |"), + PANIC_LINE(" |:_/ | | |"), + PANIC_LINE(" // \\ \\ |_|"), + PANIC_LINE(" (| | ) _"), + PANIC_LINE(" /'\\_ _/`\\ (_)"), + PANIC_LINE(" \\___)=(___/"), +}; + +static const size_t logo_ascii_lines = ARRAY_SIZE(logo_ascii); + +#if defined(CONFIG_LOGO) && !defined(MODULE) +static const struct linux_logo *logo_mono; + +static int __init drm_panic_helper_setup_logo(void) +{ + const struct linux_logo *logo = fb_find_logo(1); + const unsigned char *logo_data; + struct linux_logo *logo_dup; + + if (!logo || logo->type != LINUX_LOGO_MONO) + return 0; + + /* The logo is __init, so we must make a copy for later use */ + logo_data = kmemdup(logo->data, + size_mul(DIV_ROUND_UP(logo->width, BITS_PER_BYTE), logo->height), + GFP_KERNEL); + if (!logo_data) + return -ENOMEM; + + logo_dup = kmemdup(logo, sizeof(*logo), GFP_KERNEL); + if (!logo_dup) { + kfree(logo_data); + return -ENOMEM; + } + + logo_dup->data = logo_data; + logo_mono = logo_dup; + + return 0; +} +#else +#define logo_mono ((const struct linux_logo *)NULL) +static int __init drm_panic_helper_setup_logo(void) +{ + return 0; +} +#endif + +/* + * Blit & Fill functions + */ +static void drm_panic_helper_blit_pixel(struct drm_scanout_buffer *sb, struct drm_rect *clip, + const u8 *sbuf8, unsigned int spitch, unsigned int scale, + u32 fg_color) +{ + unsigned int y, x; + + for (y = 0; y < drm_rect_height(clip); y++) + for (x = 0; x < drm_rect_width(clip); x++) + if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) + sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, fg_color); +} + +static void drm_panic_helper_write_pixel16(void *vaddr, unsigned int offset, u16 color) +{ + u16 *p = vaddr + offset; + + *p = color; +} + +static void drm_panic_helper_write_pixel24(void *vaddr, unsigned int offset, u32 color) +{ + u8 *p = vaddr + offset; + + *p++ = color & 0xff; + color >>= 8; + *p++ = color & 0xff; + color >>= 8; + *p = color & 0xff; +} + +/* + * Special case if the pixel crosses page boundaries + */ +static void drm_panic_helper_write_pixel24_xpage(void *vaddr, struct page *next_page, + unsigned int offset, u32 color) +{ + u8 *vaddr2; + u8 *p = vaddr + offset; + + vaddr2 = kmap_local_page_try_from_panic(next_page); + if (!vaddr2) + return; + + *p++ = color & 0xff; + color >>= 8; + + if (offset == PAGE_SIZE - 1) + p = vaddr2; + + *p++ = color & 0xff; + color >>= 8; + + if (offset == PAGE_SIZE - 2) + p = vaddr2; + + *p = color & 0xff; + kunmap_local(vaddr2); +} + +static void drm_panic_helper_write_pixel32(void *vaddr, unsigned int offset, u32 color) +{ + u32 *p = vaddr + offset; + + *p = color; +} + +static void drm_panic_helper_write_pixel(void *vaddr, unsigned int offset, u32 color, + unsigned int cpp) +{ + switch (cpp) { + case 2: + drm_panic_helper_write_pixel16(vaddr, offset, color); + break; + case 3: + drm_panic_helper_write_pixel24(vaddr, offset, color); + break; + case 4: + drm_panic_helper_write_pixel32(vaddr, offset, color); + break; + default: + pr_debug_once("Can't blit with pixel width %d\n", cpp); + } +} + +/* + * The scanout buffer pages are not mapped, so for each pixel, + * use kmap_local_page_try_from_panic() to map the page, and write the pixel. + * Try to keep the map from the previous pixel, to avoid too much map/unmap. + */ +static void drm_panic_helper_blit_page(struct page **pages, unsigned int dpitch, + unsigned int cpp, const u8 *sbuf8, + unsigned int spitch, struct drm_rect *clip, + unsigned int scale, u32 fg32) +{ + unsigned int y, x; + unsigned int page = ~0; + unsigned int height = drm_rect_height(clip); + unsigned int width = drm_rect_width(clip); + void *vaddr = NULL; + + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + if (drm_draw_is_pixel_fg(sbuf8, spitch, x / scale, y / scale)) { + unsigned int new_page; + unsigned int offset; + + offset = (y + clip->y1) * dpitch + (x + clip->x1) * cpp; + new_page = offset >> PAGE_SHIFT; + offset = offset % PAGE_SIZE; + if (new_page != page) { + if (!pages[new_page]) + continue; + if (vaddr) + kunmap_local(vaddr); + page = new_page; + vaddr = kmap_local_page_try_from_panic(pages[page]); + } + if (!vaddr) + continue; + + // Special case for 24bit, as a pixel might cross page boundaries + if (cpp == 3 && offset + 3 > PAGE_SIZE) + drm_panic_helper_write_pixel24_xpage(vaddr, + pages[page + 1], + offset, fg32); + else + drm_panic_helper_write_pixel(vaddr, offset, fg32, cpp); + } + } + } + if (vaddr) + kunmap_local(vaddr); +} + +/* + * drm_panic_helper_blit - convert a monochrome image to a linear framebuffer + * @sb: destination scanout buffer + * @clip: destination rectangle + * @sbuf8: source buffer, in monochrome format, 8 pixels per byte. + * @spitch: source pitch in bytes + * @scale: integer scale, source buffer is scale time smaller than destination + * rectangle + * @fg_color: foreground color, in destination format + * + * This can be used to draw a font character, which is a monochrome image, to a + * framebuffer in other supported format. + */ +static void drm_panic_helper_blit(struct drm_scanout_buffer *sb, struct drm_rect *clip, + const u8 *sbuf8, unsigned int spitch, + unsigned int scale, u32 fg_color) + +{ + struct iosys_map map; + + if (sb->set_pixel) + return drm_panic_helper_blit_pixel(sb, clip, sbuf8, spitch, scale, fg_color); + + if (sb->pages) + return drm_panic_helper_blit_page(sb->pages, sb->pitch[0], sb->format->cpp[0], + sbuf8, spitch, clip, scale, fg_color); + + map = sb->map[0]; + iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]); + + switch (sb->format->cpp[0]) { + case 2: + drm_draw_blit16(&map, sb->pitch[0], sbuf8, spitch, + drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); + break; + case 3: + drm_draw_blit24(&map, sb->pitch[0], sbuf8, spitch, + drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); + break; + case 4: + drm_draw_blit32(&map, sb->pitch[0], sbuf8, spitch, + drm_rect_height(clip), drm_rect_width(clip), scale, fg_color); + break; + default: + WARN_ONCE(1, "Can't blit with pixel width %d\n", sb->format->cpp[0]); + } +} + +static void drm_panic_helper_fill_pixel(struct drm_scanout_buffer *sb, + struct drm_rect *clip, + u32 color) +{ + unsigned int y, x; + + for (y = 0; y < drm_rect_height(clip); y++) + for (x = 0; x < drm_rect_width(clip); x++) + sb->set_pixel(sb, clip->x1 + x, clip->y1 + y, color); +} + +static void drm_panic_helper_fill_page(struct page **pages, unsigned int dpitch, + unsigned int cpp, struct drm_rect *clip, + u32 color) +{ + unsigned int y, x; + unsigned int page = ~0; + void *vaddr = NULL; + + for (y = clip->y1; y < clip->y2; y++) { + for (x = clip->x1; x < clip->x2; x++) { + unsigned int new_page; + unsigned int offset; + + offset = y * dpitch + x * cpp; + new_page = offset >> PAGE_SHIFT; + offset = offset % PAGE_SIZE; + if (new_page != page) { + if (vaddr) + kunmap_local(vaddr); + page = new_page; + vaddr = kmap_local_page_try_from_panic(pages[page]); + } + if (!vaddr) + continue; + + // Special case for 24bit, as a pixel might cross page boundaries + if (cpp == 3 && offset + 3 > PAGE_SIZE) + drm_panic_helper_write_pixel24_xpage(vaddr, pages[page + 1], + offset, color); + else + drm_panic_helper_write_pixel(vaddr, offset, color, cpp); + } + } + if (vaddr) + kunmap_local(vaddr); +} + +/* + * drm_panic_helper_fill - Fill a rectangle with a color + * @sb: destination scanout buffer + * @clip: destination rectangle + * @color: foreground color, in destination format + * + * Fill a rectangle with a color, in a linear framebuffer. + */ +static void drm_panic_helper_fill(struct drm_scanout_buffer *sb, struct drm_rect *clip, + u32 color) +{ + struct iosys_map map; + + if (sb->set_pixel) + return drm_panic_helper_fill_pixel(sb, clip, color); + + if (sb->pages) + return drm_panic_helper_fill_page(sb->pages, sb->pitch[0], sb->format->cpp[0], + clip, color); + + map = sb->map[0]; + iosys_map_incr(&map, clip->y1 * sb->pitch[0] + clip->x1 * sb->format->cpp[0]); + + switch (sb->format->cpp[0]) { + case 2: + drm_draw_fill16(&map, sb->pitch[0], drm_rect_height(clip), + drm_rect_width(clip), color); + break; + case 3: + drm_draw_fill24(&map, sb->pitch[0], drm_rect_height(clip), + drm_rect_width(clip), color); + break; + case 4: + drm_draw_fill32(&map, sb->pitch[0], drm_rect_height(clip), + drm_rect_width(clip), color); + break; + default: + WARN_ONCE(1, "Can't fill with pixel width %d\n", sb->format->cpp[0]); + } +} + +static unsigned int get_max_line_len(const struct drm_panic_line *lines, int len) +{ + int i; + unsigned int max = 0; + + for (i = 0; i < len; i++) + max = max(lines[i].len, max); + return max; +} + +/* + * Draw a text in a rectangle on a framebuffer. The text is truncated if it overflows the rectangle + */ +static void draw_txt_rectangle(struct drm_scanout_buffer *sb, + const struct font_desc *font, + const struct drm_panic_line *msg, + unsigned int msg_lines, + bool centered, + struct drm_rect *clip, + u32 color) +{ + int i, j; + const u8 *src; + size_t font_pitch = DIV_ROUND_UP(font->width, 8); + struct drm_rect rec; + + msg_lines = min(msg_lines, drm_rect_height(clip) / font->height); + for (i = 0; i < msg_lines; i++) { + size_t line_len = min(msg[i].len, drm_rect_width(clip) / font->width); + + rec.y1 = clip->y1 + i * font->height; + rec.y2 = rec.y1 + font->height; + rec.x1 = clip->x1; + + if (centered) + rec.x1 += (drm_rect_width(clip) - (line_len * font->width)) / 2; + + for (j = 0; j < line_len; j++) { + src = font_data_glyph_buf(font->data, font->width, font->height, + (unsigned char)msg[i].txt[j]); + rec.x2 = rec.x1 + font->width; + if (src) + drm_panic_helper_blit(sb, &rec, src, font_pitch, 1, color); + rec.x1 += font->width; + } + } +} + +static void drm_panic_helper_logo_rect(struct drm_rect *rect, const struct font_desc *font) +{ + if (logo_mono) { + drm_rect_init(rect, 0, 0, logo_mono->width, logo_mono->height); + } else { + int logo_width = get_max_line_len(logo_ascii, logo_ascii_lines) * font->width; + + drm_rect_init(rect, 0, 0, logo_width, logo_ascii_lines * font->height); + } +} + +static void drm_panic_helper_logo_draw(struct drm_scanout_buffer *sb, struct drm_rect *rect, + const struct font_desc *font, u32 fg_color) +{ + if (rect->x2 > sb->width || rect->y2 > sb->height) + return; + + if (logo_mono) + drm_panic_helper_blit(sb, rect, logo_mono->data, + DIV_ROUND_UP(drm_rect_width(rect), 8), 1, fg_color); + else + draw_txt_rectangle(sb, font, logo_ascii, logo_ascii_lines, false, rect, + fg_color); +} + +VISIBLE_IF_KUNIT int drm_panic_helper_draw_screen_user(struct drm_scanout_buffer *sb, + u32 fg_color, u32 bg_color) +{ + const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL); + struct drm_rect r_screen, r_logo, r_msg; + unsigned int msg_width, msg_height; + + if (!font || font->width > sb->width || font->height > sb->height) + return -EINVAL; + + fg_color = drm_draw_color_from_xrgb8888(fg_color, sb->format->format); + bg_color = drm_draw_color_from_xrgb8888(bg_color, sb->format->format); + + r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); + drm_panic_helper_logo_rect(&r_logo, font); + + msg_width = min(get_max_line_len(panic_msg, panic_msg_lines) * font->width, sb->width); + msg_height = min(panic_msg_lines * font->height, sb->height); + r_msg = DRM_RECT_INIT(0, 0, msg_width, msg_height); + + /* Center the panic message */ + drm_rect_translate(&r_msg, (sb->width - r_msg.x2) / 2, (sb->height - r_msg.y2) / 2); + + /* Fill with the background color, and draw text on top */ + drm_panic_helper_fill(sb, &r_screen, bg_color); + + if (!drm_rect_overlap(&r_logo, &r_msg)) + drm_panic_helper_logo_draw(sb, &r_logo, font, fg_color); + + draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color); + + return 0; +} +EXPORT_SYMBOL_IF_KUNIT(drm_panic_helper_draw_screen_user); + +/* + * Draw one line of kmsg, and handle wrapping if it won't fit in the screen width. + * Return the y-offset of the next line. + */ +static int draw_line_with_wrap(struct drm_scanout_buffer *sb, const struct font_desc *font, + struct drm_panic_line *line, int yoffset, u32 fg_color) +{ + int chars_per_row = sb->width / font->width; + struct drm_rect r_txt = DRM_RECT_INIT(0, yoffset, sb->width, font->height); + struct drm_panic_line line_wrap; + + if (line->len > chars_per_row) { + line_wrap.len = line->len % chars_per_row; + line_wrap.txt = line->txt + line->len - line_wrap.len; + draw_txt_rectangle(sb, font, &line_wrap, 1, false, &r_txt, fg_color); + r_txt.y1 -= font->height; + if (r_txt.y1 < 0) + return r_txt.y1; + while (line_wrap.txt > line->txt) { + line_wrap.txt -= chars_per_row; + line_wrap.len = chars_per_row; + draw_txt_rectangle(sb, font, &line_wrap, 1, false, &r_txt, fg_color); + r_txt.y1 -= font->height; + if (r_txt.y1 < 0) + return r_txt.y1; + } + } else { + draw_txt_rectangle(sb, font, line, 1, false, &r_txt, fg_color); + r_txt.y1 -= font->height; + } + return r_txt.y1; +} + +/* + * Draw the kmsg buffer to the screen, starting from the youngest message at the bottom, + * and going up until reaching the top of the screen. + */ +VISIBLE_IF_KUNIT int drm_panic_helper_draw_screen_kmsg(struct drm_scanout_buffer *sb, + u32 fg_color, u32 bg_color) +{ + const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL); + struct drm_rect r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); + struct kmsg_dump_iter iter; + char kmsg_buf[512]; + size_t kmsg_len; + struct drm_panic_line line; + int yoffset; + + if (!font || font->width > sb->width || font->height > sb->height) + return -EINVAL; + + fg_color = drm_draw_color_from_xrgb8888(fg_color, sb->format->format); + bg_color = drm_draw_color_from_xrgb8888(bg_color, sb->format->format); + + yoffset = sb->height - font->height - (sb->height % font->height) / 2; + + /* Fill with the background color, and draw text on top */ + drm_panic_helper_fill(sb, &r_screen, bg_color); + + kmsg_dump_rewind(&iter); + while (kmsg_dump_get_buffer(&iter, false, kmsg_buf, sizeof(kmsg_buf), &kmsg_len)) { + char *start; + char *end; + + /* ignore terminating NUL and newline */ + start = kmsg_buf + kmsg_len - 2; + end = kmsg_buf + kmsg_len - 1; + while (start > kmsg_buf && yoffset >= 0) { + while (start > kmsg_buf && *start != '\n') + start--; + /* don't count the newline character */ + line.txt = start + (start == kmsg_buf ? 0 : 1); + line.len = end - line.txt; + + yoffset = draw_line_with_wrap(sb, font, &line, yoffset, fg_color); + end = start; + start--; + } + } + + return 0; +} +EXPORT_SYMBOL_IF_KUNIT(drm_panic_helper_draw_screen_kmsg); + +#if defined(CONFIG_DRM_PANIC_SCREEN_QR_CODE) +/* + * It is unwise to allocate memory in the panic callback, so the buffers are + * pre-allocated. Only 2 buffers and the zlib workspace are needed. + * Two buffers are enough, using the following buffer usage: + * 1) kmsg messages are dumped in buffer1 + * 2) kmsg is zlib-compressed into buffer2 + * 3) compressed kmsg is encoded as QR-code Numeric stream in buffer1 + * 4) QR-code image is generated in buffer2 + * The Max QR code size is V40, 177x177, 4071 bytes for image, 2956 bytes for + * data segments. + * + * Typically, ~7500 bytes of kmsg, are compressed into 2800 bytes, which fits in + * a V40 QR-code (177x177). + * + * If CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL is not set, the kmsg data will be put + * directly in the QR code. + * 1) kmsg messages are dumped in buffer1 + * 2) kmsg message is encoded as byte stream in buffer2 + * 3) QR-code image is generated in buffer1 + */ + +#define MAX_QR_DATA 2956 +#define MAX_ZLIB_RATIO 3 +#define QR_BUFFER1_SIZE (MAX_ZLIB_RATIO * MAX_QR_DATA) /* Must also be > 4071 */ +#define QR_BUFFER2_SIZE 4096 +#define QR_MARGIN 4 /* 4 modules of foreground color around the qr code */ + +/* Compression parameters */ +#define COMPR_LEVEL 6 +#define WINDOW_BITS 12 +#define MEM_LEVEL 4 + +static char *qrbuf1; +static char *qrbuf2; +static struct z_stream_s stream; + +static void __init drm_panic_helper_qr_init(void) +{ + qrbuf1 = kmalloc(QR_BUFFER1_SIZE, GFP_KERNEL); + qrbuf2 = kmalloc(QR_BUFFER2_SIZE, GFP_KERNEL); + stream.workspace = kmalloc(zlib_deflate_workspacesize(WINDOW_BITS, MEM_LEVEL), + GFP_KERNEL); +} + +static void drm_panic_helper_qr_exit(void) +{ + kfree(qrbuf1); + qrbuf1 = NULL; + kfree(qrbuf2); + qrbuf2 = NULL; + kfree(stream.workspace); + stream.workspace = NULL; +} + +static int drm_panic_helper_get_qr_code_url(u8 **qr_image, unsigned int qr_version) +{ + struct kmsg_dump_iter iter; + char url[256]; + size_t kmsg_len, max_kmsg_size; + char *kmsg; + int max_qr_data_size, url_len; + + url_len = snprintf(url, sizeof(url), "%s?a=%s&v=%s&z=", + CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL, + utsname()->machine, utsname()->release); + + max_qr_data_size = drm_panic_helper_qr_max_data_size(qr_version, url_len); + max_kmsg_size = min(MAX_ZLIB_RATIO * max_qr_data_size, QR_BUFFER1_SIZE); + + /* get kmsg to buffer 1 */ + kmsg_dump_rewind(&iter); + kmsg_dump_get_buffer(&iter, false, qrbuf1, max_kmsg_size, &kmsg_len); + + if (!kmsg_len) + return -ENODATA; + kmsg = qrbuf1; + +try_again: + if (zlib_deflateInit2(&stream, COMPR_LEVEL, Z_DEFLATED, WINDOW_BITS, + MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK) + return -EINVAL; + + stream.next_in = kmsg; + stream.avail_in = kmsg_len; + stream.total_in = 0; + stream.next_out = qrbuf2; + stream.avail_out = QR_BUFFER2_SIZE; + stream.total_out = 0; + + if (zlib_deflate(&stream, Z_FINISH) != Z_STREAM_END) + return -EINVAL; + + if (zlib_deflateEnd(&stream) != Z_OK) + return -EINVAL; + + if (stream.total_out > max_qr_data_size) { + /* too much data for the QR code, so skip the first line and try again */ + kmsg = strchr(kmsg, '\n'); + if (!kmsg) + return -EINVAL; + /* skip the first \n */ + kmsg += 1; + kmsg_len = strlen(kmsg); + goto try_again; + } + *qr_image = qrbuf2; + + /* generate qr code image in buffer2 */ + return drm_panic_helper_qr_generate(url, qrbuf2, stream.total_out, QR_BUFFER2_SIZE, + qrbuf1, QR_BUFFER1_SIZE); +} + +static int drm_panic_helper_get_qr_code_raw(u8 **qr_image, unsigned int qr_version) +{ + struct kmsg_dump_iter iter; + size_t kmsg_len; + size_t max_kmsg_size = min(drm_panic_helper_qr_max_data_size(qr_version, 0), + QR_BUFFER1_SIZE); + + kmsg_dump_rewind(&iter); + kmsg_dump_get_buffer(&iter, false, qrbuf1, max_kmsg_size, &kmsg_len); + if (!kmsg_len) + return -ENODATA; + + *qr_image = qrbuf1; + return drm_panic_helper_qr_generate(NULL, qrbuf1, kmsg_len, QR_BUFFER1_SIZE, + qrbuf2, QR_BUFFER2_SIZE); +} + +static int drm_panic_helper_get_qr_code(u8 **qr_image, unsigned int qr_version) +{ + if (strlen(CONFIG_DRM_PANIC_SCREEN_QR_CODE_URL) > 0) + return drm_panic_helper_get_qr_code_url(qr_image, qr_version); + else + return drm_panic_helper_get_qr_code_raw(qr_image, qr_version); +} + +/* + * Draw the panic message at the center of the screen, with a QR Code + */ +VISIBLE_IF_KUNIT int drm_panic_helper_draw_screen_qr_code(struct drm_scanout_buffer *sb, + u32 fg_color, u32 bg_color, + unsigned int qr_version) +{ + const struct font_desc *font = get_default_font(sb->width, sb->height, NULL, NULL); + struct drm_rect r_screen, r_logo, r_msg, r_qr, r_qr_canvas; + unsigned int max_qr_size, scale; + unsigned int msg_width, msg_height; + int qr_width, qr_canvas_width, qr_pitch, v_margin; + u8 *qr_image; + + if (!qrbuf1 || !qrbuf2 || !stream.workspace) + return -ENOMEM; + if (!font) + return -EINVAL; + + fg_color = drm_draw_color_from_xrgb8888(fg_color, sb->format->format); + bg_color = drm_draw_color_from_xrgb8888(bg_color, sb->format->format); + + r_screen = DRM_RECT_INIT(0, 0, sb->width, sb->height); + + drm_panic_helper_logo_rect(&r_logo, font); + + msg_width = min(get_max_line_len(panic_msg, panic_msg_lines) * font->width, sb->width); + msg_height = min(panic_msg_lines * font->height, sb->height); + r_msg = DRM_RECT_INIT(0, 0, msg_width, msg_height); + + max_qr_size = min(3 * sb->width / 4, 3 * sb->height / 4); + + qr_width = drm_panic_helper_get_qr_code(&qr_image, qr_version); + if (qr_width < 0) + return qr_width; + else if (!qr_width) + return -ENOSPC; + + qr_canvas_width = qr_width + QR_MARGIN * 2; + scale = max_qr_size / qr_canvas_width; + /* QR code is not readable if not scaled at least by 2 */ + if (scale < 2) + return -ENOSPC; + + pr_debug("QR width %d and scale %d\n", qr_width, scale); + r_qr_canvas = DRM_RECT_INIT(0, 0, qr_canvas_width * scale, qr_canvas_width * scale); + + v_margin = sb->height - drm_rect_height(&r_qr_canvas) - drm_rect_height(&r_msg); + if (v_margin < 0) + return -ENOSPC; + v_margin /= 5; + + drm_rect_translate(&r_qr_canvas, (sb->width - r_qr_canvas.x2) / 2, 2 * v_margin); + r_qr = DRM_RECT_INIT(r_qr_canvas.x1 + QR_MARGIN * scale, r_qr_canvas.y1 + QR_MARGIN * scale, + qr_width * scale, qr_width * scale); + + /* Center the panic message */ + drm_rect_translate(&r_msg, (sb->width - r_msg.x2) / 2, + 3 * v_margin + drm_rect_height(&r_qr_canvas)); + + /* Fill with the background color, and draw text on top */ + drm_panic_helper_fill(sb, &r_screen, bg_color); + + if (!drm_rect_overlap(&r_logo, &r_msg) && !drm_rect_overlap(&r_logo, &r_qr_canvas)) + drm_panic_helper_logo_draw(sb, &r_logo, font, fg_color); + + draw_txt_rectangle(sb, font, panic_msg, panic_msg_lines, true, &r_msg, fg_color); + + /* Draw the qr code */ + qr_pitch = DIV_ROUND_UP(qr_width, 8); + drm_panic_helper_fill(sb, &r_qr_canvas, fg_color); + drm_panic_helper_fill(sb, &r_qr, bg_color); + drm_panic_helper_blit(sb, &r_qr, qr_image, qr_pitch, scale, fg_color); + return 0; +} +EXPORT_SYMBOL_IF_KUNIT(drm_panic_helper_draw_screen_qr_code); +#else +static void __init drm_panic_helper_qr_init(void) { }; +static void __exit drm_panic_helper_qr_exit(void) { }; +#endif + +/* + * drm_panic_helper_format_is_supported() + * @format: a fourcc color code + * Returns: true if supported, false otherwise. + * + * Check if drm_panic will be able to use this color format. + */ +static bool drm_panic_helper_format_is_supported(const struct drm_format_info *format) +{ + if (format->num_planes != 1) + return false; + return drm_draw_can_convert_from_xrgb8888(format->format); +} + +static int draw_panic_helper_dispatch(struct drm_scanout_buffer *sb, + enum drm_panic_type panic_type, + u32 fg_color, u32 bg_color, + unsigned int qr_version) +{ + int ret; + +retry: + switch (panic_type) { + case DRM_PANIC_TYPE_KMSG: + ret = drm_panic_helper_draw_screen_kmsg(sb, fg_color, bg_color); + if (ret) { + panic_type = DRM_PANIC_TYPE_USER; + goto retry; + } + break; +#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE) + case DRM_PANIC_TYPE_QR: + ret = drm_panic_helper_draw_screen_qr_code(sb, fg_color, bg_color, qr_version); + if (ret) { + panic_type = DRM_PANIC_TYPE_USER; + goto retry; + } + break; +#endif + case DRM_PANIC_TYPE_USER: + default: + ret = drm_panic_helper_draw_screen_user(sb, fg_color, bg_color); + } + + return ret; +} + +VISIBLE_IF_KUNIT void drm_panic_helper_set_description(const char *description) +{ + u32 len; + + if (description) { + struct drm_panic_line *desc_line = &panic_msg[panic_msg_lines - 1]; + + desc_line->txt = description; + len = strlen(description); + /* ignore the last newline character */ + if (len && description[len - 1] == '\n') + len -= 1; + desc_line->len = len; + } +} +EXPORT_SYMBOL_IF_KUNIT(drm_panic_helper_set_description); + +VISIBLE_IF_KUNIT void drm_panic_helper_clear_description(void) +{ + struct drm_panic_line *desc_line = &panic_msg[panic_msg_lines - 1]; + + desc_line->len = 0; + desc_line->txt = NULL; +} +EXPORT_SYMBOL_IF_KUNIT(drm_panic_helper_clear_description); + +/** + * drm_plane_helper_display_panic_screen - Displays a panic screen according to the given settings + * @plane: the DRM plane to display to + * @description: error message to display + * @panic_type: type of panic screen + * @fg_color: text foreground color + * @bg_color: text background color + * @qr_version: version of the QR code, if any + * + * This helper display a panic screen on common primary planes. The panic + * screen can either display a kernel message, a user message or a QR code. + * + * The helper uses struct drm_plane_helper_funcs.get_scanout_buffer, where + * the plane can provide a scanout buffer that the panic handler can draw to. + * Currently only linear buffer and a few color formats are supported. + * + * Optionally the plane can also provide a &drm_plane_helper_funcs.panic_flush + * callback, which the DRM panic handler calls after drawing to send additional + * commands to the hardware to make the scanout buffer visible. + */ +int drm_plane_helper_display_panic_screen(struct drm_plane *plane, const char *description, + enum drm_panic_type panic_type, + u32 fg_color, u32 bg_color, unsigned int qr_version) +{ + struct drm_scanout_buffer sb = { }; + int ret; + + if (!plane->helper_private || !plane->helper_private->get_scanout_buffer) + return -EINVAL; + + ret = plane->helper_private->get_scanout_buffer(plane, &sb); + if (ret) + return ret; + + if (!drm_panic_helper_format_is_supported(sb.format)) + return -EINVAL; + + /* One of these should be set, or it can't draw pixels */ + if (!sb.set_pixel && !sb.pages && iosys_map_is_null(&sb.map[0])) + return -EINVAL; + + drm_panic_helper_set_description(description); + + ret = draw_panic_helper_dispatch(&sb, panic_type, fg_color, bg_color, qr_version); + if (!ret) { + /* + * Only flush if we have a panic screen to display. Otherwise + * it's probably better to leave the display output as-is. + */ + if (plane->helper_private->panic_flush) + plane->helper_private->panic_flush(plane); + } + + drm_panic_helper_clear_description(); + + return ret; +} +EXPORT_SYMBOL(drm_plane_helper_display_panic_screen); + +int __init drm_panic_helper_init(void) +{ + drm_panic_helper_setup_logo(); + drm_panic_helper_qr_init(); + + return 0; +} + +void __exit drm_panic_helper_exit(void) +{ + drm_panic_helper_qr_exit(); +} diff --git a/drivers/gpu/drm/drm_panic_qr.rs b/drivers/gpu/drm/drm_panic_helper_qr.rs similarity index 99% rename from drivers/gpu/drm/drm_panic_qr.rs rename to drivers/gpu/drm/drm_panic_helper_qr.rs index ac27e86c601c..22966956331e 100644 --- a/drivers/gpu/drm/drm_panic_qr.rs +++ b/drivers/gpu/drm/drm_panic_helper_qr.rs @@ -938,7 +938,7 @@ fn draw_all(&mut self, data: impl Iterator) { /// /// They must remain valid for the duration of the function call. #[export] -pub unsafe extern "C" fn drm_panic_qr_generate( +pub unsafe extern "C" fn drm_panic_helper_qr_generate( url: *const kernel::ffi::c_char, data: *mut u8, data_len: usize, @@ -994,7 +994,7 @@ fn draw_all(&mut self, data: impl Iterator) { /// Always safe to call. // Required to be unsafe due to the `#[export]` annotation. #[export] -pub unsafe extern "C" fn drm_panic_qr_max_data_size(version: u8, url_len: usize) -> usize { +pub unsafe extern "C" fn drm_panic_helper_qr_max_data_size(version: u8, url_len: usize) -> usize { #[expect(clippy::manual_range_contains)] if version < 1 || version > 40 { return 0; diff --git a/drivers/gpu/drm/drm_panic_internal.h b/drivers/gpu/drm/drm_panic_internal.h new file mode 100644 index 000000000000..fe6d514a0833 --- /dev/null +++ b/drivers/gpu/drm/drm_panic_internal.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0 or MIT */ + +/* + * Copyright (c) 2024 Intel + * Copyright (c) 2024 Red Hat + */ + +#ifndef __DRM_PANIC_INTERNAL_H__ +#define __DRM_PANIC_INTERNAL_H__ + +#include + +struct drm_device; + +#ifdef CONFIG_DRM_PANIC + +/** + * drm_panic_lock - protect panic printing relevant state + * @dev: struct drm_device + * @flags: unsigned long irq flags you need to pass to the unlock() counterpart + * + * This function must be called to protect software and hardware state that the + * panic printing code must be able to rely on. The protected sections must be + * as small as possible. It uses the irqsave/irqrestore variant, and can be + * called from irq handler. Examples include: + * + * - Access to peek/poke or other similar registers, if that is the way the + * driver prints the pixels into the scanout buffer at panic time. + * + * - Updates to pointers like &drm_plane.state, allowing the panic handler to + * safely deference these. This is done in drm_atomic_helper_swap_state(). + * + * - An state that isn't invariant and that the driver must be able to access + * during panic printing. + */ +#define drm_panic_lock(dev, flags) \ + raw_spin_lock_irqsave(&(dev)->mode_config.panic_lock, flags) + +/** + * drm_panic_unlock - end of the panic printing critical section + * @dev: struct drm_device + * @flags: irq flags that were returned when acquiring the lock + * + * Unlocks the raw spinlock acquired by either drm_panic_lock() or + * drm_panic_trylock(). + */ +#define drm_panic_unlock(dev, flags) \ + raw_spin_unlock_irqrestore(&(dev)->mode_config.panic_lock, flags) + +#else +static inline void drm_panic_lock(struct drm_device *dev, unsigned long flags) {} +static inline void drm_panic_unlock(struct drm_device *dev, unsigned long flags) {} +#endif + +#if IS_ENABLED(CONFIG_DRM_PANIC_HELPER) +/* drm_panic_helper.c */ +int __init drm_panic_helper_init(void); +void __exit drm_panic_helper_exit(void); +#else +static inline int __init drm_panic_helper_init(void) +{ + return 0; +} + +static inline void __exit drm_panic_helper_exit(void) +{ } +#endif + +#endif /* __DRM_PANIC_INTERNAL_H__ */ diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c index ef4e923a8728..7b16d32b6ff6 100644 --- a/drivers/gpu/drm/drm_sysfs.c +++ b/drivers/gpu/drm/drm_sysfs.c @@ -589,35 +589,3 @@ struct device *drm_sysfs_minor_alloc(struct drm_minor *minor) put_device(kdev); return ERR_PTR(r); } - -/** - * drm_class_device_register - register new device with the DRM sysfs class - * @dev: device to register - * - * Registers a new &struct device within the DRM sysfs class. Essentially only - * used by ttm to have a place for its global settings. Drivers should never use - * this. - */ -int drm_class_device_register(struct device *dev) -{ - if (!drm_class || IS_ERR(drm_class)) - return -ENOENT; - - dev->class = drm_class; - return device_register(dev); -} -EXPORT_SYMBOL_GPL(drm_class_device_register); - -/** - * drm_class_device_unregister - unregister device with the DRM sysfs class - * @dev: device to unregister - * - * Unregisters a &struct device from the DRM sysfs class. Essentially only used - * by ttm to have a place for its global settings. Drivers should never use - * this. - */ -void drm_class_device_unregister(struct device *dev) -{ - return device_unregister(dev); -} -EXPORT_SYMBOL_GPL(drm_class_device_unregister); diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c index 5c04ef87e400..020e8c9cf7de 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_plane.c +++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c @@ -122,23 +122,19 @@ static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state) exynos_state->crtc.w, exynos_state->crtc.h); } -static void exynos_drm_plane_reset(struct drm_plane *plane) +static struct drm_plane_state *exynos_drm_plane_create_state(struct drm_plane *plane) { struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); struct exynos_drm_plane_state *exynos_state; - if (plane->state) { - exynos_state = to_exynos_plane_state(plane->state); - __drm_atomic_helper_plane_destroy_state(plane->state); - kfree(exynos_state); - plane->state = NULL; - } - exynos_state = kzalloc_obj(*exynos_state); - if (exynos_state) { - __drm_atomic_helper_plane_reset(plane, &exynos_state->base); - plane->state->zpos = exynos_plane->config->zpos; - } + if (!exynos_state) + return ERR_PTR(-ENOMEM); + + __drm_atomic_helper_plane_state_init(&exynos_state->base, plane); + exynos_state->base.zpos = exynos_plane->config->zpos; + + return &exynos_state->base; } static struct drm_plane_state * @@ -169,7 +165,7 @@ static struct drm_plane_funcs exynos_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .destroy = drm_plane_cleanup, - .reset = exynos_drm_plane_reset, + .atomic_create_state = exynos_drm_plane_create_state, .atomic_duplicate_state = exynos_drm_plane_duplicate_state, .atomic_destroy_state = exynos_drm_plane_destroy_state, }; diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c index b34f880c1e09..92794b337512 100644 --- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c +++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c @@ -177,7 +177,7 @@ static const struct drm_plane_funcs fsl_dcu_drm_plane_funcs = { .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, .destroy = drm_plane_helper_destroy, .disable_plane = drm_atomic_helper_disable_plane, - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, .update_plane = drm_atomic_helper_update_plane, }; diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c index 5f4e738bc94e..bca839dd600b 100644 --- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_ade.c @@ -837,7 +837,7 @@ static struct drm_plane_funcs ade_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .destroy = drm_plane_cleanup, - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, }; diff --git a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c index 3261e730c69d..523d1c7ea072 100644 --- a/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c +++ b/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -237,6 +238,7 @@ static const struct drm_plane_funcs hv_drm_plane_funcs = { .disable_plane = drm_atomic_helper_disable_plane, .destroy = drm_plane_cleanup, DRM_GEM_SHADOW_PLANE_FUNCS, + DRM_PANIC_PLANE_FUNCS, }; static const struct drm_encoder_funcs hv_drm_simple_encoder_funcs_cleanup = { diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c index df6da1c6a359..0902b17d0269 100644 --- a/drivers/gpu/drm/i915/display/i9xx_plane.c +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "i9xx_plane.h" @@ -887,6 +888,7 @@ static const struct drm_plane_funcs i965_plane_funcs = { .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = i965_plane_format_mod_supported, .format_mod_supported_async = intel_plane_format_mod_supported_async, + DRM_PANIC_PLANE_FUNCS, }; static const struct drm_plane_funcs i8xx_plane_funcs = { @@ -897,6 +899,7 @@ static const struct drm_plane_funcs i8xx_plane_funcs = { .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = i8xx_plane_format_mod_supported, .format_mod_supported_async = intel_plane_format_mod_supported_async, + DRM_PANIC_PLANE_FUNCS, }; static void i9xx_disable_tiling(struct intel_plane *plane) diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c index 5cda1ab90e40..8c0f414badf3 100644 --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -2712,6 +2713,7 @@ static const struct drm_plane_funcs skl_plane_funcs = { .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = skl_plane_format_mod_supported, .format_mod_supported_async = intel_plane_format_mod_supported_async, + DRM_PANIC_PLANE_FUNCS, }; static const struct drm_plane_funcs icl_plane_funcs = { @@ -2722,6 +2724,7 @@ static const struct drm_plane_funcs icl_plane_funcs = { .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = icl_plane_format_mod_supported, .format_mod_supported_async = intel_plane_format_mod_supported_async, + DRM_PANIC_PLANE_FUNCS, }; static const struct drm_plane_funcs tgl_plane_funcs = { @@ -2732,6 +2735,7 @@ static const struct drm_plane_funcs tgl_plane_funcs = { .atomic_destroy_state = intel_plane_destroy_state, .format_mod_supported = tgl_plane_format_mod_supported, .format_mod_supported_async = intel_plane_format_mod_supported_async, + DRM_PANIC_PLANE_FUNCS, }; static void diff --git a/drivers/gpu/drm/i915/i915_switcheroo.c b/drivers/gpu/drm/i915/i915_switcheroo.c index 7e0791024282..d97057722fde 100644 --- a/drivers/gpu/drm/i915/i915_switcheroo.c +++ b/drivers/gpu/drm/i915/i915_switcheroo.c @@ -5,6 +5,7 @@ #include +#include #include #include "display/intel_display_device.h" @@ -58,10 +59,18 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev) atomic_read(&i915->drm.open_count) == 0; } +static void i915_switcheroo_pre_switch(struct pci_dev *pdev) +{ + struct drm_i915_private *i915 = pdev_to_i915(pdev); + + if (i915 && intel_display_device_present(i915->display)) + drm_client_dev_acquire_outputs(&i915->drm); +} + static const struct vga_switcheroo_client_ops i915_switcheroo_ops = { .set_gpu_state = i915_switcheroo_set_state, - .reprobe = NULL, .can_switch = i915_switcheroo_can_switch, + .pre_switch = i915_switcheroo_pre_switch, }; int i915_switcheroo_register(struct drm_i915_private *i915) diff --git a/drivers/gpu/drm/imagination/pvr_ccb.c b/drivers/gpu/drm/imagination/pvr_ccb.c index b702d122d791..e408df74853d 100644 --- a/drivers/gpu/drm/imagination/pvr_ccb.c +++ b/drivers/gpu/drm/imagination/pvr_ccb.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -82,11 +83,6 @@ pvr_ccb_init(struct pvr_device *pvr_dev, struct pvr_ccb *pvr_ccb, pvr_fw_object_get_fw_addr(pvr_ccb->ctrl_obj, &pvr_ccb->ctrl_fw_addr); pvr_fw_object_get_fw_addr(pvr_ccb->ccb_obj, &pvr_ccb->ccb_fw_addr); - WRITE_ONCE(pvr_ccb->ctrl->write_offset, 0); - WRITE_ONCE(pvr_ccb->ctrl->read_offset, 0); - WRITE_ONCE(pvr_ccb->ctrl->wrap_mask, num_cmds - 1); - WRITE_ONCE(pvr_ccb->ctrl->cmd_size, cmd_size); - return 0; err_free_ctrl: @@ -527,6 +523,7 @@ void pvr_kccb_wake_up_waiters(struct pvr_device *pvr_dev) */ void pvr_kccb_fini(struct pvr_device *pvr_dev) { + pvr_fw_object_unmap_and_destroy(pvr_dev->kccb.rtn_obj); pvr_ccb_fini(&pvr_dev->kccb.ccb); WARN_ON(!list_empty(&pvr_dev->kccb.waiters)); WARN_ON(pvr_dev->kccb.reserved_count); @@ -543,14 +540,42 @@ void pvr_kccb_fini(struct pvr_device *pvr_dev) int pvr_kccb_init(struct pvr_device *pvr_dev) { - pvr_dev->kccb.slot_count = 1 << ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT; + const u32 num_slots_log2 = ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT; + const u32 num_slots = 1 << num_slots_log2; + u32 rtn_size; + int err; + + /* + * The inputs here are compile-time constants; there's no reason to try + * to gracefully handle overflow at runtime. + */ + BUILD_BUG_ON(check_mul_overflow(num_slots, sizeof(*pvr_dev->kccb.rtn), &rtn_size)); + + pvr_dev->kccb.slot_count = num_slots; INIT_LIST_HEAD(&pvr_dev->kccb.waiters); pvr_dev->kccb.fence_ctx.id = dma_fence_context_alloc(1); spin_lock_init(&pvr_dev->kccb.fence_ctx.lock); - return pvr_ccb_init(pvr_dev, &pvr_dev->kccb.ccb, - ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT, - sizeof(struct rogue_fwif_kccb_cmd)); + err = pvr_ccb_init(pvr_dev, &pvr_dev->kccb.ccb, num_slots_log2, + sizeof(struct rogue_fwif_kccb_cmd)); + if (err) + return err; + + /* Allocate memory for KCCB return slots. */ + pvr_dev->kccb.rtn = pvr_fw_object_create_and_map(pvr_dev, rtn_size, + PVR_BO_FW_FLAGS_DEVICE_UNCACHED, + NULL, NULL, &pvr_dev->kccb.rtn_obj); + if (IS_ERR(pvr_dev->kccb.rtn)) { + err = PTR_ERR(pvr_dev->kccb.rtn); + goto err_ccb_fini; + } + + return 0; + +err_ccb_fini: + pvr_ccb_fini(&pvr_dev->kccb.ccb); + + return err; } /** diff --git a/drivers/gpu/drm/imagination/pvr_device.c b/drivers/gpu/drm/imagination/pvr_device.c index 54fe4180c73c..35eaa54f75ed 100644 --- a/drivers/gpu/drm/imagination/pvr_device.c +++ b/drivers/gpu/drm/imagination/pvr_device.c @@ -697,25 +697,7 @@ pvr_device_gpu_init(struct pvr_device *pvr_dev) if (err) return err; - if (pvr_dev->fw_dev.processor_type != PVR_FW_PROCESSOR_TYPE_MIPS) { - pvr_dev->kernel_vm_ctx = pvr_vm_create_context(pvr_dev, false); - if (IS_ERR(pvr_dev->kernel_vm_ctx)) - return PTR_ERR(pvr_dev->kernel_vm_ctx); - } - - err = pvr_fw_init(pvr_dev); - if (err) - goto err_vm_ctx_put; - - return 0; - -err_vm_ctx_put: - if (pvr_dev->fw_dev.processor_type != PVR_FW_PROCESSOR_TYPE_MIPS) { - pvr_vm_context_put(pvr_dev->kernel_vm_ctx); - pvr_dev->kernel_vm_ctx = NULL; - } - - return err; + return pvr_fw_init(pvr_dev); } /** @@ -726,11 +708,6 @@ static void pvr_device_gpu_fini(struct pvr_device *pvr_dev) { pvr_fw_fini(pvr_dev); - - if (pvr_dev->fw_dev.processor_type != PVR_FW_PROCESSOR_TYPE_MIPS) { - WARN_ON(!pvr_vm_context_put(pvr_dev->kernel_vm_ctx)); - pvr_dev->kernel_vm_ctx = NULL; - } } /** diff --git a/drivers/gpu/drm/imagination/pvr_fw.c b/drivers/gpu/drm/imagination/pvr_fw.c index 850a3ec8e775..c6c77b152342 100644 --- a/drivers/gpu/drm/imagination/pvr_fw.c +++ b/drivers/gpu/drm/imagination/pvr_fw.c @@ -945,8 +945,6 @@ pvr_fw_init(struct pvr_device *pvr_dev) [PVR_FW_PROCESSOR_TYPE_RISCV] = &pvr_fw_defs_riscv, }; - u32 kccb_size_log2 = ROGUE_FWIF_KCCB_NUMCMDS_LOG2_DEFAULT; - u32 kccb_rtn_size = (1 << kccb_size_log2) * sizeof(*pvr_dev->kccb.rtn); struct pvr_fw_device *fw_dev = &pvr_dev->fw_dev; int err; @@ -981,18 +979,9 @@ pvr_fw_init(struct pvr_device *pvr_dev) if (err) goto err_kccb_fini; - /* Allocate memory for KCCB return slots. */ - pvr_dev->kccb.rtn = pvr_fw_object_create_and_map(pvr_dev, kccb_rtn_size, - PVR_BO_FW_FLAGS_DEVICE_UNCACHED, - NULL, NULL, &pvr_dev->kccb.rtn_obj); - if (IS_ERR(pvr_dev->kccb.rtn)) { - err = PTR_ERR(pvr_dev->kccb.rtn); - goto err_fwccb_fini; - } - err = pvr_fw_create_structures(pvr_dev); if (err) - goto err_kccb_rtn_release; + goto err_fwccb_fini; err = pvr_fw_start(pvr_dev); if (err) @@ -1014,9 +1003,6 @@ pvr_fw_init(struct pvr_device *pvr_dev) err_destroy_structures: pvr_fw_destroy_structures(pvr_dev); -err_kccb_rtn_release: - pvr_fw_object_unmap_and_destroy(pvr_dev->kccb.rtn_obj); - err_fwccb_fini: pvr_ccb_fini(&pvr_dev->fwccb); @@ -1029,8 +1015,7 @@ pvr_fw_init(struct pvr_device *pvr_dev) err_mm_takedown: drm_mm_takedown(&fw_dev->fw_mm); - if (fw_dev->defs->fini) - fw_dev->defs->fini(pvr_dev); + fw_dev->defs->fini(pvr_dev); return err; } @@ -1047,7 +1032,6 @@ pvr_fw_fini(struct pvr_device *pvr_dev) WRITE_ONCE(fw_dev->initialised, false); pvr_fw_destroy_structures(pvr_dev); - pvr_fw_object_unmap_and_destroy(pvr_dev->kccb.rtn_obj); /* * Ensure FWCCB worker has finished executing before destroying FWCCB. The IRQ handler has @@ -1063,8 +1047,7 @@ pvr_fw_fini(struct pvr_device *pvr_dev) drm_mm_takedown(&fw_dev->fw_mm); - if (fw_dev->defs->fini) - fw_dev->defs->fini(pvr_dev); + fw_dev->defs->fini(pvr_dev); } /** diff --git a/drivers/gpu/drm/imagination/pvr_fw.h b/drivers/gpu/drm/imagination/pvr_fw.h index 3390c84e4fd3..4b25291135b6 100644 --- a/drivers/gpu/drm/imagination/pvr_fw.h +++ b/drivers/gpu/drm/imagination/pvr_fw.h @@ -86,7 +86,7 @@ struct pvr_fw_defs { * FW processor specific finalisation. * @pvr_dev: Target PowerVR device. * - * This function is optional. + * This function is mandatory. */ void (*fini)(struct pvr_device *pvr_dev); diff --git a/drivers/gpu/drm/imagination/pvr_fw_meta.c b/drivers/gpu/drm/imagination/pvr_fw_meta.c index 9ff03bc60a08..84f568b5510f 100644 --- a/drivers/gpu/drm/imagination/pvr_fw_meta.c +++ b/drivers/gpu/drm/imagination/pvr_fw_meta.c @@ -500,18 +500,33 @@ pvr_meta_init(struct pvr_device *pvr_dev) { pvr_fw_heap_info_init(pvr_dev, ROGUE_FW_HEAP_META_SHIFT, 0); + pvr_dev->kernel_vm_ctx = pvr_vm_create_context(pvr_dev, false); + if (IS_ERR(pvr_dev->kernel_vm_ctx)) + return PTR_ERR(pvr_dev->kernel_vm_ctx); + return 0; } +static void +pvr_meta_fini(struct pvr_device *pvr_dev) +{ + WARN_ON(!pvr_vm_context_put(pvr_dev->kernel_vm_ctx)); + pvr_dev->kernel_vm_ctx = NULL; +} + static u32 pvr_meta_get_fw_addr_with_offset(struct pvr_fw_object *fw_obj, u32 offset) { u32 fw_addr = fw_obj->fw_addr_offset + offset + ROGUE_FW_SEGMMU_DATA_BASE_ADDRESS; /* META cacheability is determined by address. */ - if (fw_obj->gem->flags & PVR_BO_FW_FLAGS_DEVICE_UNCACHED) + if (fw_obj->gem->flags & PVR_BO_FW_FLAGS_DEVICE_UNCACHED) { fw_addr |= ROGUE_FW_SEGMMU_DATA_META_UNCACHED | ROGUE_FW_SEGMMU_DATA_VIVT_SLC_UNCACHED; + } else { + fw_addr |= ROGUE_FW_SEGMMU_DATA_META_CACHED | + ROGUE_FW_SEGMMU_DATA_VIVT_SLC_CACHED; + } return fw_addr; } @@ -550,6 +565,7 @@ pvr_meta_irq_clear(struct pvr_device *pvr_dev) const struct pvr_fw_defs pvr_fw_defs_meta = { .init = pvr_meta_init, + .fini = pvr_meta_fini, .fw_process = pvr_meta_fw_process, .vm_map = pvr_meta_vm_map, .vm_unmap = pvr_meta_vm_unmap, diff --git a/drivers/gpu/drm/imagination/pvr_fw_riscv.c b/drivers/gpu/drm/imagination/pvr_fw_riscv.c index fc13d483be9a..cd84635bb88d 100644 --- a/drivers/gpu/drm/imagination/pvr_fw_riscv.c +++ b/drivers/gpu/drm/imagination/pvr_fw_riscv.c @@ -23,27 +23,33 @@ static int pvr_riscv_wrapper_init(struct pvr_device *pvr_dev) { const u64 common_opts = - ((u64)(ROGUE_FW_HEAP_RISCV_SIZE >> FWCORE_ADDR_REMAP_CONFIG0_SIZE_ALIGNSHIFT) - << ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_SIZE_SHIFT) | + ((u64)(ROGUE_FW_HEAP_RISCV_SIZE + >> ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_SIZE_ALIGNSHIFT) + << ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_SIZE_SHIFT) | ((u64)MMU_CONTEXT_MAPPING_FWPRIV - << FWCORE_ADDR_REMAP_CONFIG0_MMU_CONTEXT_SHIFT); + << ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_CBASE_SHIFT); u64 code_addr = pvr_fw_obj_get_gpu_addr(pvr_dev->fw_dev.mem.code_obj); u64 data_addr = pvr_fw_obj_get_gpu_addr(pvr_dev->fw_dev.mem.data_obj); /* This condition allows us to OR the addresses into the register directly. */ - static_assert(ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_SHIFT == - ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_ALIGNSHIFT); + static_assert(ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_DEVVADDR_SHIFT == + ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_DEVVADDR_ALIGNSHIFT); - WARN_ON(code_addr & ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_CLRMSK); - WARN_ON(data_addr & ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_CLRMSK); + WARN_ON(code_addr & ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_DEVVADDR_CLRMSK); + WARN_ON(data_addr & ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_DEVVADDR_CLRMSK); - pvr_cr_write64(pvr_dev, ROGUE_RISCVFW_REGION_REMAP_CR(BOOTLDR_CODE), - code_addr | common_opts | ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_FETCH_EN_EN); + pvr_cr_write64(pvr_dev, + PVR_CR_REPEAT_X(ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG, + ROGUE_RISCV_REGION_BOOTLDR_CODE), + code_addr | common_opts | + ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_FETCH_EN_EN); - pvr_cr_write64(pvr_dev, ROGUE_RISCVFW_REGION_REMAP_CR(BOOTLDR_DATA), + pvr_cr_write64(pvr_dev, + PVR_CR_REPEAT_X(ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG, + ROGUE_RISCV_REGION_BOOTLDR_DATA), data_addr | common_opts | - ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_LOAD_STORE_EN_EN); + ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_LOAD_STORE_EN_EN); /* Garten IDLE bit controlled by RISC-V. */ pvr_cr_write64(pvr_dev, ROGUE_CR_MTS_GARTEN_WRAPPER_CONFIG, @@ -103,9 +109,20 @@ pvr_riscv_init(struct pvr_device *pvr_dev) { pvr_fw_heap_info_init(pvr_dev, ROGUE_FW_HEAP_RISCV_SHIFT, 0); + pvr_dev->kernel_vm_ctx = pvr_vm_create_context(pvr_dev, false); + if (IS_ERR(pvr_dev->kernel_vm_ctx)) + return PTR_ERR(pvr_dev->kernel_vm_ctx); + return 0; } +static void +pvr_riscv_fini(struct pvr_device *pvr_dev) +{ + WARN_ON(!pvr_vm_context_put(pvr_dev->kernel_vm_ctx)); + pvr_dev->kernel_vm_ctx = NULL; +} + static u32 pvr_riscv_get_fw_addr_with_offset(struct pvr_fw_object *fw_obj, u32 offset) { @@ -154,6 +171,7 @@ pvr_riscv_irq_clear(struct pvr_device *pvr_dev) const struct pvr_fw_defs pvr_fw_defs_riscv = { .init = pvr_riscv_init, + .fini = pvr_riscv_fini, .fw_process = pvr_riscv_fw_process, .vm_map = pvr_riscv_vm_map, .vm_unmap = pvr_riscv_vm_unmap, diff --git a/drivers/gpu/drm/imagination/pvr_fw_startstop.c b/drivers/gpu/drm/imagination/pvr_fw_startstop.c index e24ed6fc4362..98ca2692239d 100644 --- a/drivers/gpu/drm/imagination/pvr_fw_startstop.c +++ b/drivers/gpu/drm/imagination/pvr_fw_startstop.c @@ -43,19 +43,25 @@ rogue_bif_init(struct pvr_device *pvr_dev) pc_dma_addr = pvr_vm_get_page_table_root_addr(pvr_dev->kernel_vm_ctx); /* Write the kernel catalogue base. */ - pc_addr = ((((u64)pc_dma_addr >> ROGUE_CR_BIF_CAT_BASE0_ADDR_ALIGNSHIFT) - << ROGUE_CR_BIF_CAT_BASE0_ADDR_SHIFT) & - ~ROGUE_CR_BIF_CAT_BASE0_ADDR_CLRMSK); + pc_addr = ((((u64)pc_dma_addr >> ROGUE_CR_BIF_CAT_BASEx_ADDR_ALIGNSHIFT) + << ROGUE_CR_BIF_CAT_BASEx_ADDR_SHIFT) & + ~ROGUE_CR_BIF_CAT_BASEx_ADDR_CLRMSK); - pvr_cr_write64(pvr_dev, BIF_CAT_BASEX(MMU_CONTEXT_MAPPING_FWPRIV), + pvr_cr_write64(pvr_dev, + PVR_CR_REPEAT_X(ROGUE_CR_BIF_CAT_BASE, + MMU_CONTEXT_MAPPING_FWPRIV), pc_addr); if (pvr_dev->fw_dev.processor_type == PVR_FW_PROCESSOR_TYPE_RISCV) { - pc_addr = (((u64)pc_dma_addr >> ROGUE_CR_FWCORE_MEM_CAT_BASE0_ADDR_ALIGNSHIFT) - << ROGUE_CR_FWCORE_MEM_CAT_BASE0_ADDR_SHIFT) & - ~ROGUE_CR_FWCORE_MEM_CAT_BASE0_ADDR_CLRMSK; + pc_addr = (((u64)pc_dma_addr + >> ROGUE_CR_FWCORE_MEM_CAT_BASEx_ADDR_ALIGNSHIFT) + << ROGUE_CR_FWCORE_MEM_CAT_BASEx_ADDR_SHIFT) & + ~ROGUE_CR_FWCORE_MEM_CAT_BASEx_ADDR_CLRMSK; - pvr_cr_write64(pvr_dev, FWCORE_MEM_CAT_BASEX(MMU_CONTEXT_MAPPING_FWPRIV), pc_addr); + pvr_cr_write64(pvr_dev, + PVR_CR_REPEAT_X(ROGUE_CR_FWCORE_MEM_CAT_BASE, + MMU_CONTEXT_MAPPING_FWPRIV), + pc_addr); } } diff --git a/drivers/gpu/drm/imagination/pvr_fw_trace.c b/drivers/gpu/drm/imagination/pvr_fw_trace.c index 805d9f9bc1dd..6fe478f64f02 100644 --- a/drivers/gpu/drm/imagination/pvr_fw_trace.c +++ b/drivers/gpu/drm/imagination/pvr_fw_trace.c @@ -101,7 +101,6 @@ tracebuf_ctrl_init(void *cpu_ptr, void *priv) pvr_fw_object_get_fw_addr(trace_buffer->buf_obj, &tracebuf_space->trace_buffer_fw_addr); - tracebuf_space->trace_buffer = trace_buffer->buf; tracebuf_space->trace_pointer = 0; } } diff --git a/drivers/gpu/drm/imagination/pvr_rogue_cr_defs.h b/drivers/gpu/drm/imagination/pvr_rogue_cr_defs.h index 790c97f80a2a..45d784f2a82c 100644 --- a/drivers/gpu/drm/imagination/pvr_rogue_cr_defs.h +++ b/drivers/gpu/drm/imagination/pvr_rogue_cr_defs.h @@ -2344,101 +2344,48 @@ #define ROGUE_CR_ISP_STATUS_EOR_EN 0x00000001U /* Register group: ROGUE_CR_ISP_XTP_RESUME, with 64 repeats */ -#define ROGUE_CR_ISP_XTP_RESUME_REPEATCOUNT 64U -/* Register ROGUE_CR_ISP_XTP_RESUME0 */ -#define ROGUE_CR_ISP_XTP_RESUME0 0x3A00U -#define ROGUE_CR_ISP_XTP_RESUME0_MASKFULL 0x00000000003FF3FFULL -#define ROGUE_CR_ISP_XTP_RESUME0_TILE_X_SHIFT 12U -#define ROGUE_CR_ISP_XTP_RESUME0_TILE_X_CLRMSK 0xFFC00FFFU -#define ROGUE_CR_ISP_XTP_RESUME0_TILE_Y_SHIFT 0U -#define ROGUE_CR_ISP_XTP_RESUME0_TILE_Y_CLRMSK 0xFFFFFC00U +#define ROGUE_CR_ISP_XTP_RESUME_REPEAT_COUNT 64U +#define ROGUE_CR_ISP_XTP_RESUME_REPEAT_OFFSET 0x0008U +#define ROGUE_CR_ISP_XTP_RESUME_REPEAT_BASE 0x3A00U +/* Register ROGUE_CR_ISP_XTP_RESUMEx */ +#define ROGUE_CR_ISP_XTP_RESUMEx_MASKFULL 0x00000000003FF3FFULL +#define ROGUE_CR_ISP_XTP_RESUMEx_TILE_X_SHIFT 12U +#define ROGUE_CR_ISP_XTP_RESUMEx_TILE_X_CLRMSK 0xFFC00FFFU +#define ROGUE_CR_ISP_XTP_RESUMEx_TILE_Y_SHIFT 0U +#define ROGUE_CR_ISP_XTP_RESUMEx_TILE_Y_CLRMSK 0xFFFFFC00U /* Register group: ROGUE_CR_ISP_XTP_STORE, with 32 repeats */ -#define ROGUE_CR_ISP_XTP_STORE_REPEATCOUNT 32U -/* Register ROGUE_CR_ISP_XTP_STORE0 */ -#define ROGUE_CR_ISP_XTP_STORE0 0x3C00U -#define ROGUE_CR_ISP_XTP_STORE0_MASKFULL 0x000000007F3FF3FFULL -#define ROGUE_CR_ISP_XTP_STORE0_ACTIVE_SHIFT 30U -#define ROGUE_CR_ISP_XTP_STORE0_ACTIVE_CLRMSK 0xBFFFFFFFU -#define ROGUE_CR_ISP_XTP_STORE0_ACTIVE_EN 0x40000000U -#define ROGUE_CR_ISP_XTP_STORE0_EOR_SHIFT 29U -#define ROGUE_CR_ISP_XTP_STORE0_EOR_CLRMSK 0xDFFFFFFFU -#define ROGUE_CR_ISP_XTP_STORE0_EOR_EN 0x20000000U -#define ROGUE_CR_ISP_XTP_STORE0_TILE_LAST_SHIFT 28U -#define ROGUE_CR_ISP_XTP_STORE0_TILE_LAST_CLRMSK 0xEFFFFFFFU -#define ROGUE_CR_ISP_XTP_STORE0_TILE_LAST_EN 0x10000000U -#define ROGUE_CR_ISP_XTP_STORE0_MT_SHIFT 24U -#define ROGUE_CR_ISP_XTP_STORE0_MT_CLRMSK 0xF0FFFFFFU -#define ROGUE_CR_ISP_XTP_STORE0_TILE_X_SHIFT 12U -#define ROGUE_CR_ISP_XTP_STORE0_TILE_X_CLRMSK 0xFFC00FFFU -#define ROGUE_CR_ISP_XTP_STORE0_TILE_Y_SHIFT 0U -#define ROGUE_CR_ISP_XTP_STORE0_TILE_Y_CLRMSK 0xFFFFFC00U +#define ROGUE_CR_ISP_XTP_STORE_REPEAT_COUNT 32U +#define ROGUE_CR_ISP_XTP_STORE_REPEAT_OFFSET 0x0008U +#define ROGUE_CR_ISP_XTP_STORE_REPEAT_BASE 0x3C00U +/* Register ROGUE_CR_ISP_XTP_STOREx */ +#define ROGUE_CR_ISP_XTP_STOREx_MASKFULL 0x000000007F3FF3FFULL +#define ROGUE_CR_ISP_XTP_STOREx_ACTIVE_SHIFT 30U +#define ROGUE_CR_ISP_XTP_STOREx_ACTIVE_CLRMSK 0xBFFFFFFFU +#define ROGUE_CR_ISP_XTP_STOREx_ACTIVE_EN 0x40000000U +#define ROGUE_CR_ISP_XTP_STOREx_EOR_SHIFT 29U +#define ROGUE_CR_ISP_XTP_STOREx_EOR_CLRMSK 0xDFFFFFFFU +#define ROGUE_CR_ISP_XTP_STOREx_EOR_EN 0x20000000U +#define ROGUE_CR_ISP_XTP_STOREx_TILE_LAST_SHIFT 28U +#define ROGUE_CR_ISP_XTP_STOREx_TILE_LAST_CLRMSK 0xEFFFFFFFU +#define ROGUE_CR_ISP_XTP_STOREx_TILE_LAST_EN 0x10000000U +#define ROGUE_CR_ISP_XTP_STOREx_MT_SHIFT 24U +#define ROGUE_CR_ISP_XTP_STOREx_MT_CLRMSK 0xF0FFFFFFU +#define ROGUE_CR_ISP_XTP_STOREx_TILE_X_SHIFT 12U +#define ROGUE_CR_ISP_XTP_STOREx_TILE_X_CLRMSK 0xFFC00FFFU +#define ROGUE_CR_ISP_XTP_STOREx_TILE_Y_SHIFT 0U +#define ROGUE_CR_ISP_XTP_STOREx_TILE_Y_CLRMSK 0xFFFFFC00U /* Register group: ROGUE_CR_BIF_CAT_BASE, with 8 repeats */ -#define ROGUE_CR_BIF_CAT_BASE_REPEATCOUNT 8U -/* Register ROGUE_CR_BIF_CAT_BASE0 */ -#define ROGUE_CR_BIF_CAT_BASE0 0x1200U -#define ROGUE_CR_BIF_CAT_BASE0_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_BIF_CAT_BASE0_ADDR_SHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE0_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_BIF_CAT_BASE0_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE0_ADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_BIF_CAT_BASE1 */ -#define ROGUE_CR_BIF_CAT_BASE1 0x1208U -#define ROGUE_CR_BIF_CAT_BASE1_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_BIF_CAT_BASE1_ADDR_SHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE1_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_BIF_CAT_BASE1_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE1_ADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_BIF_CAT_BASE2 */ -#define ROGUE_CR_BIF_CAT_BASE2 0x1210U -#define ROGUE_CR_BIF_CAT_BASE2_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_BIF_CAT_BASE2_ADDR_SHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE2_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_BIF_CAT_BASE2_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE2_ADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_BIF_CAT_BASE3 */ -#define ROGUE_CR_BIF_CAT_BASE3 0x1218U -#define ROGUE_CR_BIF_CAT_BASE3_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_BIF_CAT_BASE3_ADDR_SHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE3_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_BIF_CAT_BASE3_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE3_ADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_BIF_CAT_BASE4 */ -#define ROGUE_CR_BIF_CAT_BASE4 0x1220U -#define ROGUE_CR_BIF_CAT_BASE4_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_BIF_CAT_BASE4_ADDR_SHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE4_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_BIF_CAT_BASE4_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE4_ADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_BIF_CAT_BASE5 */ -#define ROGUE_CR_BIF_CAT_BASE5 0x1228U -#define ROGUE_CR_BIF_CAT_BASE5_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_BIF_CAT_BASE5_ADDR_SHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE5_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_BIF_CAT_BASE5_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE5_ADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_BIF_CAT_BASE6 */ -#define ROGUE_CR_BIF_CAT_BASE6 0x1230U -#define ROGUE_CR_BIF_CAT_BASE6_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_BIF_CAT_BASE6_ADDR_SHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE6_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_BIF_CAT_BASE6_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE6_ADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_BIF_CAT_BASE7 */ -#define ROGUE_CR_BIF_CAT_BASE7 0x1238U -#define ROGUE_CR_BIF_CAT_BASE7_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_BIF_CAT_BASE7_ADDR_SHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE7_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_BIF_CAT_BASE7_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_CAT_BASE7_ADDR_ALIGNSIZE 4096U +#define ROGUE_CR_BIF_CAT_BASE_REPEAT_COUNT 8U +#define ROGUE_CR_BIF_CAT_BASE_REPEAT_OFFSET 0x0008U +#define ROGUE_CR_BIF_CAT_BASE_REPEAT_BASE 0x1200U +/* Register ROGUE_CR_BIF_CAT_BASEx */ +#define ROGUE_CR_BIF_CAT_BASEx_MASKFULL 0x000000FFFFFFF000ULL +#define ROGUE_CR_BIF_CAT_BASEx_ADDR_SHIFT 12U +#define ROGUE_CR_BIF_CAT_BASEx_ADDR_CLRMSK 0xFFFFFF0000000FFFULL +#define ROGUE_CR_BIF_CAT_BASEx_ADDR_ALIGNSHIFT 12U +#define ROGUE_CR_BIF_CAT_BASEx_ADDR_ALIGNSIZE 4096U /* Register ROGUE_CR_BIF_CAT_BASE_INDEX */ #define ROGUE_CR_BIF_CAT_BASE_INDEX 0x1240U @@ -2715,142 +2662,24 @@ #define ROGUE_CR_BIF_MMU_STATUS_BUSY_EN 0x00000001U /* Register group: ROGUE_CR_BIF_TILING_CFG, with 8 repeats */ -#define ROGUE_CR_BIF_TILING_CFG_REPEATCOUNT 8U -/* Register ROGUE_CR_BIF_TILING_CFG0 */ -#define ROGUE_CR_BIF_TILING_CFG0 0x12D8U -#define ROGUE_CR_BIF_TILING_CFG0_MASKFULL 0xFFFFFFFF0FFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG0_XSTRIDE_SHIFT 61U -#define ROGUE_CR_BIF_TILING_CFG0_XSTRIDE_CLRMSK 0x1FFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG0_ENABLE_SHIFT 60U -#define ROGUE_CR_BIF_TILING_CFG0_ENABLE_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG0_ENABLE_EN 0x1000000000000000ULL -#define ROGUE_CR_BIF_TILING_CFG0_MAX_ADDRESS_SHIFT 32U -#define ROGUE_CR_BIF_TILING_CFG0_MAX_ADDRESS_CLRMSK 0xF0000000FFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG0_MAX_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG0_MAX_ADDRESS_ALIGNSIZE 4096U -#define ROGUE_CR_BIF_TILING_CFG0_MIN_ADDRESS_SHIFT 0U -#define ROGUE_CR_BIF_TILING_CFG0_MIN_ADDRESS_CLRMSK 0xFFFFFFFFF0000000ULL -#define ROGUE_CR_BIF_TILING_CFG0_MIN_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG0_MIN_ADDRESS_ALIGNSIZE 4096U - -/* Register ROGUE_CR_BIF_TILING_CFG1 */ -#define ROGUE_CR_BIF_TILING_CFG1 0x12E0U -#define ROGUE_CR_BIF_TILING_CFG1_MASKFULL 0xFFFFFFFF0FFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG1_XSTRIDE_SHIFT 61U -#define ROGUE_CR_BIF_TILING_CFG1_XSTRIDE_CLRMSK 0x1FFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG1_ENABLE_SHIFT 60U -#define ROGUE_CR_BIF_TILING_CFG1_ENABLE_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG1_ENABLE_EN 0x1000000000000000ULL -#define ROGUE_CR_BIF_TILING_CFG1_MAX_ADDRESS_SHIFT 32U -#define ROGUE_CR_BIF_TILING_CFG1_MAX_ADDRESS_CLRMSK 0xF0000000FFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG1_MAX_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG1_MAX_ADDRESS_ALIGNSIZE 4096U -#define ROGUE_CR_BIF_TILING_CFG1_MIN_ADDRESS_SHIFT 0U -#define ROGUE_CR_BIF_TILING_CFG1_MIN_ADDRESS_CLRMSK 0xFFFFFFFFF0000000ULL -#define ROGUE_CR_BIF_TILING_CFG1_MIN_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG1_MIN_ADDRESS_ALIGNSIZE 4096U - -/* Register ROGUE_CR_BIF_TILING_CFG2 */ -#define ROGUE_CR_BIF_TILING_CFG2 0x12E8U -#define ROGUE_CR_BIF_TILING_CFG2_MASKFULL 0xFFFFFFFF0FFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG2_XSTRIDE_SHIFT 61U -#define ROGUE_CR_BIF_TILING_CFG2_XSTRIDE_CLRMSK 0x1FFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG2_ENABLE_SHIFT 60U -#define ROGUE_CR_BIF_TILING_CFG2_ENABLE_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG2_ENABLE_EN 0x1000000000000000ULL -#define ROGUE_CR_BIF_TILING_CFG2_MAX_ADDRESS_SHIFT 32U -#define ROGUE_CR_BIF_TILING_CFG2_MAX_ADDRESS_CLRMSK 0xF0000000FFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG2_MAX_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG2_MAX_ADDRESS_ALIGNSIZE 4096U -#define ROGUE_CR_BIF_TILING_CFG2_MIN_ADDRESS_SHIFT 0U -#define ROGUE_CR_BIF_TILING_CFG2_MIN_ADDRESS_CLRMSK 0xFFFFFFFFF0000000ULL -#define ROGUE_CR_BIF_TILING_CFG2_MIN_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG2_MIN_ADDRESS_ALIGNSIZE 4096U - -/* Register ROGUE_CR_BIF_TILING_CFG3 */ -#define ROGUE_CR_BIF_TILING_CFG3 0x12F0U -#define ROGUE_CR_BIF_TILING_CFG3_MASKFULL 0xFFFFFFFF0FFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG3_XSTRIDE_SHIFT 61U -#define ROGUE_CR_BIF_TILING_CFG3_XSTRIDE_CLRMSK 0x1FFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG3_ENABLE_SHIFT 60U -#define ROGUE_CR_BIF_TILING_CFG3_ENABLE_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG3_ENABLE_EN 0x1000000000000000ULL -#define ROGUE_CR_BIF_TILING_CFG3_MAX_ADDRESS_SHIFT 32U -#define ROGUE_CR_BIF_TILING_CFG3_MAX_ADDRESS_CLRMSK 0xF0000000FFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG3_MAX_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG3_MAX_ADDRESS_ALIGNSIZE 4096U -#define ROGUE_CR_BIF_TILING_CFG3_MIN_ADDRESS_SHIFT 0U -#define ROGUE_CR_BIF_TILING_CFG3_MIN_ADDRESS_CLRMSK 0xFFFFFFFFF0000000ULL -#define ROGUE_CR_BIF_TILING_CFG3_MIN_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG3_MIN_ADDRESS_ALIGNSIZE 4096U - -/* Register ROGUE_CR_BIF_TILING_CFG4 */ -#define ROGUE_CR_BIF_TILING_CFG4 0x12F8U -#define ROGUE_CR_BIF_TILING_CFG4_MASKFULL 0xFFFFFFFF0FFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG4_XSTRIDE_SHIFT 61U -#define ROGUE_CR_BIF_TILING_CFG4_XSTRIDE_CLRMSK 0x1FFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG4_ENABLE_SHIFT 60U -#define ROGUE_CR_BIF_TILING_CFG4_ENABLE_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG4_ENABLE_EN 0x1000000000000000ULL -#define ROGUE_CR_BIF_TILING_CFG4_MAX_ADDRESS_SHIFT 32U -#define ROGUE_CR_BIF_TILING_CFG4_MAX_ADDRESS_CLRMSK 0xF0000000FFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG4_MAX_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG4_MAX_ADDRESS_ALIGNSIZE 4096U -#define ROGUE_CR_BIF_TILING_CFG4_MIN_ADDRESS_SHIFT 0U -#define ROGUE_CR_BIF_TILING_CFG4_MIN_ADDRESS_CLRMSK 0xFFFFFFFFF0000000ULL -#define ROGUE_CR_BIF_TILING_CFG4_MIN_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG4_MIN_ADDRESS_ALIGNSIZE 4096U - -/* Register ROGUE_CR_BIF_TILING_CFG5 */ -#define ROGUE_CR_BIF_TILING_CFG5 0x1300U -#define ROGUE_CR_BIF_TILING_CFG5_MASKFULL 0xFFFFFFFF0FFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG5_XSTRIDE_SHIFT 61U -#define ROGUE_CR_BIF_TILING_CFG5_XSTRIDE_CLRMSK 0x1FFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG5_ENABLE_SHIFT 60U -#define ROGUE_CR_BIF_TILING_CFG5_ENABLE_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG5_ENABLE_EN 0x1000000000000000ULL -#define ROGUE_CR_BIF_TILING_CFG5_MAX_ADDRESS_SHIFT 32U -#define ROGUE_CR_BIF_TILING_CFG5_MAX_ADDRESS_CLRMSK 0xF0000000FFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG5_MAX_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG5_MAX_ADDRESS_ALIGNSIZE 4096U -#define ROGUE_CR_BIF_TILING_CFG5_MIN_ADDRESS_SHIFT 0U -#define ROGUE_CR_BIF_TILING_CFG5_MIN_ADDRESS_CLRMSK 0xFFFFFFFFF0000000ULL -#define ROGUE_CR_BIF_TILING_CFG5_MIN_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG5_MIN_ADDRESS_ALIGNSIZE 4096U - -/* Register ROGUE_CR_BIF_TILING_CFG6 */ -#define ROGUE_CR_BIF_TILING_CFG6 0x1308U -#define ROGUE_CR_BIF_TILING_CFG6_MASKFULL 0xFFFFFFFF0FFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG6_XSTRIDE_SHIFT 61U -#define ROGUE_CR_BIF_TILING_CFG6_XSTRIDE_CLRMSK 0x1FFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG6_ENABLE_SHIFT 60U -#define ROGUE_CR_BIF_TILING_CFG6_ENABLE_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG6_ENABLE_EN 0x1000000000000000ULL -#define ROGUE_CR_BIF_TILING_CFG6_MAX_ADDRESS_SHIFT 32U -#define ROGUE_CR_BIF_TILING_CFG6_MAX_ADDRESS_CLRMSK 0xF0000000FFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG6_MAX_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG6_MAX_ADDRESS_ALIGNSIZE 4096U -#define ROGUE_CR_BIF_TILING_CFG6_MIN_ADDRESS_SHIFT 0U -#define ROGUE_CR_BIF_TILING_CFG6_MIN_ADDRESS_CLRMSK 0xFFFFFFFFF0000000ULL -#define ROGUE_CR_BIF_TILING_CFG6_MIN_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG6_MIN_ADDRESS_ALIGNSIZE 4096U - -/* Register ROGUE_CR_BIF_TILING_CFG7 */ -#define ROGUE_CR_BIF_TILING_CFG7 0x1310U -#define ROGUE_CR_BIF_TILING_CFG7_MASKFULL 0xFFFFFFFF0FFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG7_XSTRIDE_SHIFT 61U -#define ROGUE_CR_BIF_TILING_CFG7_XSTRIDE_CLRMSK 0x1FFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG7_ENABLE_SHIFT 60U -#define ROGUE_CR_BIF_TILING_CFG7_ENABLE_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG7_ENABLE_EN 0x1000000000000000ULL -#define ROGUE_CR_BIF_TILING_CFG7_MAX_ADDRESS_SHIFT 32U -#define ROGUE_CR_BIF_TILING_CFG7_MAX_ADDRESS_CLRMSK 0xF0000000FFFFFFFFULL -#define ROGUE_CR_BIF_TILING_CFG7_MAX_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG7_MAX_ADDRESS_ALIGNSIZE 4096U -#define ROGUE_CR_BIF_TILING_CFG7_MIN_ADDRESS_SHIFT 0U -#define ROGUE_CR_BIF_TILING_CFG7_MIN_ADDRESS_CLRMSK 0xFFFFFFFFF0000000ULL -#define ROGUE_CR_BIF_TILING_CFG7_MIN_ADDRESS_ALIGNSHIFT 12U -#define ROGUE_CR_BIF_TILING_CFG7_MIN_ADDRESS_ALIGNSIZE 4096U +#define ROGUE_CR_BIF_TILING_CFG_REPEAT_COUNT 8U +#define ROGUE_CR_BIF_TILING_CFG_REPEAT_OFFSET 0x0008U +#define ROGUE_CR_BIF_TILING_CFG_REPEAT_BASE 0x12D8U +/* Register ROGUE_CR_BIF_TILING_CFGx */ +#define ROGUE_CR_BIF_TILING_CFGx_MASKFULL 0xFFFFFFFF0FFFFFFFULL +#define ROGUE_CR_BIF_TILING_CFGx_XSTRIDE_SHIFT 61U +#define ROGUE_CR_BIF_TILING_CFGx_XSTRIDE_CLRMSK 0x1FFFFFFFFFFFFFFFULL +#define ROGUE_CR_BIF_TILING_CFGx_ENABLE_SHIFT 60U +#define ROGUE_CR_BIF_TILING_CFGx_ENABLE_CLRMSK 0xEFFFFFFFFFFFFFFFULL +#define ROGUE_CR_BIF_TILING_CFGx_ENABLE_EN 0x1000000000000000ULL +#define ROGUE_CR_BIF_TILING_CFGx_MAX_ADDRESS_SHIFT 32U +#define ROGUE_CR_BIF_TILING_CFGx_MAX_ADDRESS_CLRMSK 0xF0000000FFFFFFFFULL +#define ROGUE_CR_BIF_TILING_CFGx_MAX_ADDRESS_ALIGNSHIFT 12U +#define ROGUE_CR_BIF_TILING_CFGx_MAX_ADDRESS_ALIGNSIZE 4096U +#define ROGUE_CR_BIF_TILING_CFGx_MIN_ADDRESS_SHIFT 0U +#define ROGUE_CR_BIF_TILING_CFGx_MIN_ADDRESS_CLRMSK 0xFFFFFFFFF0000000ULL +#define ROGUE_CR_BIF_TILING_CFGx_MIN_ADDRESS_ALIGNSHIFT 12U +#define ROGUE_CR_BIF_TILING_CFGx_MIN_ADDRESS_ALIGNSIZE 4096U /* Register ROGUE_CR_BIF_READS_EXT_STATUS */ #define ROGUE_CR_BIF_READS_EXT_STATUS 0x1320U @@ -2951,102 +2780,13 @@ #define ROGUE_CR_MCU_FENCE_ADDR_ALIGNSIZE 32U /* Register group: ROGUE_CR_SCRATCH, with 16 repeats */ -#define ROGUE_CR_SCRATCH_REPEATCOUNT 16U -/* Register ROGUE_CR_SCRATCH0 */ -#define ROGUE_CR_SCRATCH0 0x1A00U -#define ROGUE_CR_SCRATCH0_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH0_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH0_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH1 */ -#define ROGUE_CR_SCRATCH1 0x1A08U -#define ROGUE_CR_SCRATCH1_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH1_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH1_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH2 */ -#define ROGUE_CR_SCRATCH2 0x1A10U -#define ROGUE_CR_SCRATCH2_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH2_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH2_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH3 */ -#define ROGUE_CR_SCRATCH3 0x1A18U -#define ROGUE_CR_SCRATCH3_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH3_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH3_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH4 */ -#define ROGUE_CR_SCRATCH4 0x1A20U -#define ROGUE_CR_SCRATCH4_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH4_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH4_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH5 */ -#define ROGUE_CR_SCRATCH5 0x1A28U -#define ROGUE_CR_SCRATCH5_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH5_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH5_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH6 */ -#define ROGUE_CR_SCRATCH6 0x1A30U -#define ROGUE_CR_SCRATCH6_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH6_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH6_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH7 */ -#define ROGUE_CR_SCRATCH7 0x1A38U -#define ROGUE_CR_SCRATCH7_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH7_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH7_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH8 */ -#define ROGUE_CR_SCRATCH8 0x1A40U -#define ROGUE_CR_SCRATCH8_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH8_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH8_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH9 */ -#define ROGUE_CR_SCRATCH9 0x1A48U -#define ROGUE_CR_SCRATCH9_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH9_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH9_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH10 */ -#define ROGUE_CR_SCRATCH10 0x1A50U -#define ROGUE_CR_SCRATCH10_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH10_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH10_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH11 */ -#define ROGUE_CR_SCRATCH11 0x1A58U -#define ROGUE_CR_SCRATCH11_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH11_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH11_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH12 */ -#define ROGUE_CR_SCRATCH12 0x1A60U -#define ROGUE_CR_SCRATCH12_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH12_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH12_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH13 */ -#define ROGUE_CR_SCRATCH13 0x1A68U -#define ROGUE_CR_SCRATCH13_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH13_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH13_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH14 */ -#define ROGUE_CR_SCRATCH14 0x1A70U -#define ROGUE_CR_SCRATCH14_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH14_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH14_DATA_CLRMSK 0x00000000U - -/* Register ROGUE_CR_SCRATCH15 */ -#define ROGUE_CR_SCRATCH15 0x1A78U -#define ROGUE_CR_SCRATCH15_MASKFULL 0x00000000FFFFFFFFULL -#define ROGUE_CR_SCRATCH15_DATA_SHIFT 0U -#define ROGUE_CR_SCRATCH15_DATA_CLRMSK 0x00000000U +#define ROGUE_CR_SCRATCH_REPEAT_COUNT 16U +#define ROGUE_CR_SCRATCH_REPEAT_OFFSET 0x0008U +#define ROGUE_CR_SCRATCH_REPEAT_BASE 0x1A00U +/* Register ROGUE_CR_SCRATCHx */ +#define ROGUE_CR_SCRATCHx_MASKFULL 0x00000000FFFFFFFFULL +#define ROGUE_CR_SCRATCHx_DATA_SHIFT 0U +#define ROGUE_CR_SCRATCHx_DATA_CLRMSK 0x00000000U /* Register group: ROGUE_CR_OS0_SCRATCH, with 2 repeats */ #define ROGUE_CR_OS0_SCRATCH_REPEATCOUNT 2U @@ -3273,342 +3013,30 @@ #define ROGUE_CR_SPFILTER_SIGNAL_DESCR_MIN_ADDR_ALIGNSIZE 16U /* Register group: ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG, with 16 repeats */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG_REPEATCOUNT 16U -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0 0x3000U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1 0x3008U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG1_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2 0x3010U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG2_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3 0x3018U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG3_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4 0x3020U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG4_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5 0x3028U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG5_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6 0x3030U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG6_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7 0x3038U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG7_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8 0x3040U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG8_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9 0x3048U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG9_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10 0x3050U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG10_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11 0x3058U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG11_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12 0x3060U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG12_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13 0x3068U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG13_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14 0x3070U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG14_DEVVADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15 */ -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15 0x3078U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_MASKFULL 0x7FFFF7FFFFFFF000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_TRUSTED_SHIFT 62U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_TRUSTED_EN 0x4000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_LOAD_STORE_EN_SHIFT 61U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_LOAD_STORE_EN_EN 0x2000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_FETCH_EN_SHIFT 60U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_FETCH_EN_EN 0x1000000000000000ULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_SIZE_SHIFT 44U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_CBASE_SHIFT 40U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_DEVVADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_DEVVADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG15_DEVVADDR_ALIGNSIZE 4096U +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG_REPEAT_COUNT 16U +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG_REPEAT_OFFSET 0x0008U +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG_REPEAT_BASE 0x3000U +/* Register ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx */ +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_MASKFULL 0x7FFFF7FFFFFFF000ULL +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_TRUSTED_SHIFT 62U +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_TRUSTED_CLRMSK 0xBFFFFFFFFFFFFFFFULL +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_TRUSTED_EN 0x4000000000000000ULL +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_LOAD_STORE_EN_SHIFT 61U +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_LOAD_STORE_EN_CLRMSK 0xDFFFFFFFFFFFFFFFULL +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_LOAD_STORE_EN_EN 0x2000000000000000ULL +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_FETCH_EN_SHIFT 60U +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_FETCH_EN_CLRMSK 0xEFFFFFFFFFFFFFFFULL +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_FETCH_EN_EN 0x1000000000000000ULL +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_SIZE_SHIFT 44U +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_SIZE_CLRMSK 0xF0000FFFFFFFFFFFULL +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_SIZE_ALIGNSHIFT 12U +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_SIZE_ALIGNSIZE 4096U +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_CBASE_SHIFT 40U +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_CBASE_CLRMSK 0xFFFFF8FFFFFFFFFFULL +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_DEVVADDR_SHIFT 12U +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_DEVVADDR_CLRMSK 0xFFFFFF0000000FFFULL +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_DEVVADDR_ALIGNSHIFT 12U +#define ROGUE_CR_FWCORE_ADDR_REMAP_CONFIGx_DEVVADDR_ALIGNSIZE 4096U /* Register ROGUE_CR_FWCORE_BOOT */ #define ROGUE_CR_FWCORE_BOOT 0x3090U @@ -3726,70 +3154,15 @@ #define ROGUE_CR_FWCORE_WRAPPER_FENCE_ID_EN 0x00000001U /* Register group: ROGUE_CR_FWCORE_MEM_CAT_BASE, with 8 repeats */ -#define ROGUE_CR_FWCORE_MEM_CAT_BASE_REPEATCOUNT 8U -/* Register ROGUE_CR_FWCORE_MEM_CAT_BASE0 */ -#define ROGUE_CR_FWCORE_MEM_CAT_BASE0 0x30F0U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE0_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE0_ADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE0_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE0_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE0_ADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_MEM_CAT_BASE1 */ -#define ROGUE_CR_FWCORE_MEM_CAT_BASE1 0x30F8U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE1_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE1_ADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE1_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE1_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE1_ADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_MEM_CAT_BASE2 */ -#define ROGUE_CR_FWCORE_MEM_CAT_BASE2 0x3100U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE2_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE2_ADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE2_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE2_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE2_ADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_MEM_CAT_BASE3 */ -#define ROGUE_CR_FWCORE_MEM_CAT_BASE3 0x3108U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE3_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE3_ADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE3_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE3_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE3_ADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_MEM_CAT_BASE4 */ -#define ROGUE_CR_FWCORE_MEM_CAT_BASE4 0x3110U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE4_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE4_ADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE4_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE4_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE4_ADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_MEM_CAT_BASE5 */ -#define ROGUE_CR_FWCORE_MEM_CAT_BASE5 0x3118U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE5_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE5_ADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE5_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE5_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE5_ADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_MEM_CAT_BASE6 */ -#define ROGUE_CR_FWCORE_MEM_CAT_BASE6 0x3120U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE6_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE6_ADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE6_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE6_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE6_ADDR_ALIGNSIZE 4096U - -/* Register ROGUE_CR_FWCORE_MEM_CAT_BASE7 */ -#define ROGUE_CR_FWCORE_MEM_CAT_BASE7 0x3128U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE7_MASKFULL 0x000000FFFFFFF000ULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE7_ADDR_SHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE7_ADDR_CLRMSK 0xFFFFFF0000000FFFULL -#define ROGUE_CR_FWCORE_MEM_CAT_BASE7_ADDR_ALIGNSHIFT 12U -#define ROGUE_CR_FWCORE_MEM_CAT_BASE7_ADDR_ALIGNSIZE 4096U +#define ROGUE_CR_FWCORE_MEM_CAT_BASE_REPEAT_COUNT 8U +#define ROGUE_CR_FWCORE_MEM_CAT_BASE_REPEAT_OFFSET 0x0008U +#define ROGUE_CR_FWCORE_MEM_CAT_BASE_REPEAT_BASE 0x30F0U +/* Register ROGUE_CR_FWCORE_MEM_CAT_BASEx */ +#define ROGUE_CR_FWCORE_MEM_CAT_BASEx_MASKFULL 0x000000FFFFFFF000ULL +#define ROGUE_CR_FWCORE_MEM_CAT_BASEx_ADDR_SHIFT 12U +#define ROGUE_CR_FWCORE_MEM_CAT_BASEx_ADDR_CLRMSK 0xFFFFFF0000000FFFULL +#define ROGUE_CR_FWCORE_MEM_CAT_BASEx_ADDR_ALIGNSHIFT 12U +#define ROGUE_CR_FWCORE_MEM_CAT_BASEx_ADDR_ALIGNSIZE 4096U /* Register ROGUE_CR_FWCORE_WDT_RESET */ #define ROGUE_CR_FWCORE_WDT_RESET 0x3130U @@ -3816,22 +3189,11 @@ #define ROGUE_CR_FWCORE_WDT_COUNT_VALUE_CLRMSK 0x00000000U /* Register group: ROGUE_CR_FWCORE_DMI_RESERVED0, with 4 repeats */ -#define ROGUE_CR_FWCORE_DMI_RESERVED0_REPEATCOUNT 4U -/* Register ROGUE_CR_FWCORE_DMI_RESERVED00 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED00 0x3400U -#define ROGUE_CR_FWCORE_DMI_RESERVED00_MASKFULL 0x0000000000000000ULL - -/* Register ROGUE_CR_FWCORE_DMI_RESERVED01 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED01 0x3408U -#define ROGUE_CR_FWCORE_DMI_RESERVED01_MASKFULL 0x0000000000000000ULL - -/* Register ROGUE_CR_FWCORE_DMI_RESERVED02 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED02 0x3410U -#define ROGUE_CR_FWCORE_DMI_RESERVED02_MASKFULL 0x0000000000000000ULL - -/* Register ROGUE_CR_FWCORE_DMI_RESERVED03 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED03 0x3418U -#define ROGUE_CR_FWCORE_DMI_RESERVED03_MASKFULL 0x0000000000000000ULL +#define ROGUE_CR_FWCORE_DMI_RESERVED0_REPEAT_COUNT 4U +#define ROGUE_CR_FWCORE_DMI_RESERVED0_REPEAT_OFFSET 0x0008U +#define ROGUE_CR_FWCORE_DMI_RESERVED0_REPEAT_BASE 0x3400U +/* Register ROGUE_CR_FWCORE_DMI_RESERVED0x */ +#define ROGUE_CR_FWCORE_DMI_RESERVED0x_MASKFULL 0x0000000000000000ULL /* Register ROGUE_CR_FWCORE_DMI_DATA0 */ #define ROGUE_CR_FWCORE_DMI_DATA0 0x3420U @@ -3842,26 +3204,11 @@ #define ROGUE_CR_FWCORE_DMI_DATA1_MASKFULL 0x0000000000000000ULL /* Register group: ROGUE_CR_FWCORE_DMI_RESERVED1, with 5 repeats */ -#define ROGUE_CR_FWCORE_DMI_RESERVED1_REPEATCOUNT 5U -/* Register ROGUE_CR_FWCORE_DMI_RESERVED10 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED10 0x3430U -#define ROGUE_CR_FWCORE_DMI_RESERVED10_MASKFULL 0x0000000000000000ULL - -/* Register ROGUE_CR_FWCORE_DMI_RESERVED11 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED11 0x3438U -#define ROGUE_CR_FWCORE_DMI_RESERVED11_MASKFULL 0x0000000000000000ULL - -/* Register ROGUE_CR_FWCORE_DMI_RESERVED12 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED12 0x3440U -#define ROGUE_CR_FWCORE_DMI_RESERVED12_MASKFULL 0x0000000000000000ULL - -/* Register ROGUE_CR_FWCORE_DMI_RESERVED13 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED13 0x3448U -#define ROGUE_CR_FWCORE_DMI_RESERVED13_MASKFULL 0x0000000000000000ULL - -/* Register ROGUE_CR_FWCORE_DMI_RESERVED14 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED14 0x3450U -#define ROGUE_CR_FWCORE_DMI_RESERVED14_MASKFULL 0x0000000000000000ULL +#define ROGUE_CR_FWCORE_DMI_RESERVED1_REPEAT_COUNT 5U +#define ROGUE_CR_FWCORE_DMI_RESERVED1_REPEAT_OFFSET 0x0008U +#define ROGUE_CR_FWCORE_DMI_RESERVED1_REPEAT_BASE 0x3430U +/* Register ROGUE_CR_FWCORE_DMI_RESERVED1x */ +#define ROGUE_CR_FWCORE_DMI_RESERVED1x_MASKFULL 0x0000000000000000ULL /* Register ROGUE_CR_FWCORE_DMI_DMCONTROL */ #define ROGUE_CR_FWCORE_DMI_DMCONTROL 0x3480U @@ -3872,22 +3219,11 @@ #define ROGUE_CR_FWCORE_DMI_DMSTATUS_MASKFULL 0x0000000000000000ULL /* Register group: ROGUE_CR_FWCORE_DMI_RESERVED2, with 4 repeats */ -#define ROGUE_CR_FWCORE_DMI_RESERVED2_REPEATCOUNT 4U -/* Register ROGUE_CR_FWCORE_DMI_RESERVED20 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED20 0x3490U -#define ROGUE_CR_FWCORE_DMI_RESERVED20_MASKFULL 0x0000000000000000ULL - -/* Register ROGUE_CR_FWCORE_DMI_RESERVED21 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED21 0x3498U -#define ROGUE_CR_FWCORE_DMI_RESERVED21_MASKFULL 0x0000000000000000ULL - -/* Register ROGUE_CR_FWCORE_DMI_RESERVED22 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED22 0x34A0U -#define ROGUE_CR_FWCORE_DMI_RESERVED22_MASKFULL 0x0000000000000000ULL - -/* Register ROGUE_CR_FWCORE_DMI_RESERVED23 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED23 0x34A8U -#define ROGUE_CR_FWCORE_DMI_RESERVED23_MASKFULL 0x0000000000000000ULL +#define ROGUE_CR_FWCORE_DMI_RESERVED2_REPEAT_COUNT 4U +#define ROGUE_CR_FWCORE_DMI_RESERVED2_REPEAT_OFFSET 0x0008U +#define ROGUE_CR_FWCORE_DMI_RESERVED2_REPEAT_BASE 0x3490U +/* Register ROGUE_CR_FWCORE_DMI_RESERVED2x */ +#define ROGUE_CR_FWCORE_DMI_RESERVED2x_MASKFULL 0x0000000000000000ULL /* Register ROGUE_CR_FWCORE_DMI_ABSTRACTCS */ #define ROGUE_CR_FWCORE_DMI_ABSTRACTCS 0x34B0U @@ -3906,32 +3242,18 @@ #define ROGUE_CR_FWCORE_DMI_SBADDRESS0_MASKFULL 0x0000000000000000ULL /* Register group: ROGUE_CR_FWCORE_DMI_RESERVED3, with 2 repeats */ -#define ROGUE_CR_FWCORE_DMI_RESERVED3_REPEATCOUNT 2U -/* Register ROGUE_CR_FWCORE_DMI_RESERVED30 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED30 0x34D0U -#define ROGUE_CR_FWCORE_DMI_RESERVED30_MASKFULL 0x0000000000000000ULL - -/* Register ROGUE_CR_FWCORE_DMI_RESERVED31 */ -#define ROGUE_CR_FWCORE_DMI_RESERVED31 0x34D8U -#define ROGUE_CR_FWCORE_DMI_RESERVED31_MASKFULL 0x0000000000000000ULL +#define ROGUE_CR_FWCORE_DMI_RESERVED3_REPEAT_COUNT 2U +#define ROGUE_CR_FWCORE_DMI_RESERVED3_REPEAT_OFFSET 0x0008U +#define ROGUE_CR_FWCORE_DMI_RESERVED3_REPEAT_BASE 0x34D0U +/* Register ROGUE_CR_FWCORE_DMI_RESERVED3x */ +#define ROGUE_CR_FWCORE_DMI_RESERVED3x_MASKFULL 0x0000000000000000ULL /* Register group: ROGUE_CR_FWCORE_DMI_SBDATA, with 4 repeats */ -#define ROGUE_CR_FWCORE_DMI_SBDATA_REPEATCOUNT 4U -/* Register ROGUE_CR_FWCORE_DMI_SBDATA0 */ -#define ROGUE_CR_FWCORE_DMI_SBDATA0 0x35E0U -#define ROGUE_CR_FWCORE_DMI_SBDATA0_MASKFULL 0x0000000000000000ULL - -/* Register ROGUE_CR_FWCORE_DMI_SBDATA1 */ -#define ROGUE_CR_FWCORE_DMI_SBDATA1 0x35E8U -#define ROGUE_CR_FWCORE_DMI_SBDATA1_MASKFULL 0x0000000000000000ULL - -/* Register ROGUE_CR_FWCORE_DMI_SBDATA2 */ -#define ROGUE_CR_FWCORE_DMI_SBDATA2 0x35F0U -#define ROGUE_CR_FWCORE_DMI_SBDATA2_MASKFULL 0x0000000000000000ULL - -/* Register ROGUE_CR_FWCORE_DMI_SBDATA3 */ -#define ROGUE_CR_FWCORE_DMI_SBDATA3 0x35F8U -#define ROGUE_CR_FWCORE_DMI_SBDATA3_MASKFULL 0x0000000000000000ULL +#define ROGUE_CR_FWCORE_DMI_SBDATA_REPEAT_COUNT 4U +#define ROGUE_CR_FWCORE_DMI_SBDATA_REPEAT_OFFSET 0x0008U +#define ROGUE_CR_FWCORE_DMI_SBDATA_REPEAT_BASE 0x35E0U +/* Register ROGUE_CR_FWCORE_DMI_SBDATAx */ +#define ROGUE_CR_FWCORE_DMI_SBDATAx_MASKFULL 0x0000000000000000ULL /* Register ROGUE_CR_FWCORE_DMI_HALTSUM0 */ #define ROGUE_CR_FWCORE_DMI_HALTSUM0 0x3600U diff --git a/drivers/gpu/drm/imagination/pvr_rogue_defs.h b/drivers/gpu/drm/imagination/pvr_rogue_defs.h index 932b01686008..f09ab85e590a 100644 --- a/drivers/gpu/drm/imagination/pvr_rogue_defs.h +++ b/drivers/gpu/drm/imagination/pvr_rogue_defs.h @@ -93,26 +93,8 @@ #define MMU_CONTEXT_MAPPING_FWPRIV (0x0) /* FW code/private data */ #define MMU_CONTEXT_MAPPING_FWIF (0x0) /* Host/FW data */ -/* - * Utility macros to calculate CAT_BASE register addresses - */ -#define BIF_CAT_BASEX(n) \ - (ROGUE_CR_BIF_CAT_BASE0 + \ - (n) * (ROGUE_CR_BIF_CAT_BASE1 - ROGUE_CR_BIF_CAT_BASE0)) - -#define FWCORE_MEM_CAT_BASEX(n) \ - (ROGUE_CR_FWCORE_MEM_CAT_BASE0 + \ - (n) * (ROGUE_CR_FWCORE_MEM_CAT_BASE1 - \ - ROGUE_CR_FWCORE_MEM_CAT_BASE0)) - -/* - * FWCORE wrapper register defines - */ -#define FWCORE_ADDR_REMAP_CONFIG0_MMU_CONTEXT_SHIFT \ - ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_CBASE_SHIFT -#define FWCORE_ADDR_REMAP_CONFIG0_MMU_CONTEXT_CLRMSK \ - ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0_CBASE_CLRMSK -#define FWCORE_ADDR_REMAP_CONFIG0_SIZE_ALIGNSHIFT (12U) +/* Utility macro for accessing instances of repeated registers */ +#define PVR_CR_REPEAT_X(REG, N) ((REG##_REPEAT_BASE) + (N) * (REG##_REPEAT_OFFSET)) #define ROGUE_MAX_COMPUTE_SHARED_REGISTERS (2 * 1024) #define ROGUE_MAX_VERTEX_SHARED_REGISTERS 1024 diff --git a/drivers/gpu/drm/imagination/pvr_rogue_riscv.h b/drivers/gpu/drm/imagination/pvr_rogue_riscv.h index 9a070e24fa6a..d971729e18a4 100644 --- a/drivers/gpu/drm/imagination/pvr_rogue_riscv.h +++ b/drivers/gpu/drm/imagination/pvr_rogue_riscv.h @@ -35,7 +35,5 @@ enum rogue_riscvfw_region { }; #define ROGUE_RISCVFW_REGION_BASE(r) ((u32)(ROGUE_RISCV_REGION_##r) << ROGUE_RISCVFW_REGION_SHIFT) -#define ROGUE_RISCVFW_REGION_REMAP_CR(r) \ - (ROGUE_CR_FWCORE_ADDR_REMAP_CONFIG0 + (u32)(ROGUE_RISCV_REGION_##r) * 8U) #endif /* PVR_ROGUE_RISCV_H */ diff --git a/drivers/gpu/drm/imx/dc/dc-plane.c b/drivers/gpu/drm/imx/dc/dc-plane.c index dea7404fe659..62dd0576fadc 100644 --- a/drivers/gpu/drm/imx/dc/dc-plane.c +++ b/drivers/gpu/drm/imx/dc/dc-plane.c @@ -39,7 +39,7 @@ static const struct drm_plane_funcs dc_plane_funcs = { .update_plane = drm_atomic_helper_update_plane, .disable_plane = drm_atomic_helper_disable_plane, .destroy = drm_plane_cleanup, - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, }; diff --git a/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c index c7ec09e557c1..67e78a5ac881 100644 --- a/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3/ipuv3-plane.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include