From a18f17248944fb068283c4bf819758fb0c9c987b Mon Sep 17 00:00:00 2001 From: Jacek Lawrynowicz Date: Fri, 1 Sep 2023 11:49:54 +0200 Subject: accel/ivpu: Add ivpu_bo_vaddr() and ivpu_bo_size() Use: - ivpu_bo_vaddr(bo) instead of bo->kvaddr - ivpu_bo_size(bo) instead of bo->base.size This is a preparation for switch to a drm_gem_shmem_object as a base for ivpu_bo, where: - bo->kvaddr becomes bo->base.vaddr - bo->base.size becomes bo->base.base.size Using ivpu_bo_vaddr() and ivpu_bo_size() increases the readability of the code. Signed-off-by: Jacek Lawrynowicz Reviewed-by: Stanislaw Gruszka Reviewed-by: Jeffrey Hugo Signed-off-by: Stanislaw Gruszka Link: https://patchwork.freedesktop.org/patch/msgid/20230901094957.168898-9-stanislaw.gruszka@linux.intel.com --- drivers/accel/ivpu/ivpu_fw.c | 18 +++++++++--------- drivers/accel/ivpu/ivpu_fw_log.c | 6 +++--- drivers/accel/ivpu/ivpu_gem.c | 30 +++++++++++++++--------------- drivers/accel/ivpu/ivpu_gem.h | 22 ++++++++++++++++------ drivers/accel/ivpu/ivpu_ipc.c | 6 +++--- drivers/accel/ivpu/ivpu_job.c | 8 ++++---- drivers/accel/ivpu/ivpu_pm.c | 2 +- 7 files changed, 51 insertions(+), 41 deletions(-) diff --git a/drivers/accel/ivpu/ivpu_fw.c b/drivers/accel/ivpu/ivpu_fw.c index d57e103aae1c..6142b09cf55a 100644 --- a/drivers/accel/ivpu/ivpu_fw.c +++ b/drivers/accel/ivpu/ivpu_fw.c @@ -321,13 +321,13 @@ void ivpu_fw_load(struct ivpu_device *vdev) struct ivpu_fw_info *fw = vdev->fw; u64 image_end_offset = fw->image_load_offset + fw->image_size; - memset(fw->mem->kvaddr, 0, fw->image_load_offset); - memcpy(fw->mem->kvaddr + fw->image_load_offset, + memset(ivpu_bo_vaddr(fw->mem), 0, fw->image_load_offset); + memcpy(ivpu_bo_vaddr(fw->mem) + fw->image_load_offset, fw->file->data + FW_FILE_IMAGE_OFFSET, fw->image_size); if (IVPU_WA(clear_runtime_mem)) { - u8 *start = fw->mem->kvaddr + image_end_offset; - u64 size = fw->mem->base.size - image_end_offset; + u8 *start = ivpu_bo_vaddr(fw->mem) + image_end_offset; + u64 size = ivpu_bo_size(fw->mem) - image_end_offset; memset(start, 0, size); } @@ -450,10 +450,10 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params vdev->hw->ranges.global.start; boot_params->ipc_header_area_start = ipc_mem_rx->vpu_addr; - boot_params->ipc_header_area_size = ipc_mem_rx->base.size / 2; + boot_params->ipc_header_area_size = ivpu_bo_size(ipc_mem_rx) / 2; - boot_params->ipc_payload_area_start = ipc_mem_rx->vpu_addr + ipc_mem_rx->base.size / 2; - boot_params->ipc_payload_area_size = ipc_mem_rx->base.size / 2; + boot_params->ipc_payload_area_start = ipc_mem_rx->vpu_addr + ivpu_bo_size(ipc_mem_rx) / 2; + boot_params->ipc_payload_area_size = ivpu_bo_size(ipc_mem_rx) / 2; boot_params->global_aliased_pio_base = vdev->hw->ranges.user.start; boot_params->global_aliased_pio_size = ivpu_hw_range_size(&vdev->hw->ranges.user); @@ -485,9 +485,9 @@ void ivpu_fw_boot_params_setup(struct ivpu_device *vdev, struct vpu_boot_params boot_params->trace_destination_mask = vdev->fw->trace_destination_mask; boot_params->trace_hw_component_mask = vdev->fw->trace_hw_component_mask; boot_params->crit_tracing_buff_addr = vdev->fw->mem_log_crit->vpu_addr; - boot_params->crit_tracing_buff_size = vdev->fw->mem_log_crit->base.size; + boot_params->crit_tracing_buff_size = ivpu_bo_size(vdev->fw->mem_log_crit); boot_params->verbose_tracing_buff_addr = vdev->fw->mem_log_verb->vpu_addr; - boot_params->verbose_tracing_buff_size = vdev->fw->mem_log_verb->base.size; + boot_params->verbose_tracing_buff_size = ivpu_bo_size(vdev->fw->mem_log_verb); boot_params->punit_telemetry_sram_base = ivpu_hw_reg_telemetry_offset_get(vdev); boot_params->punit_telemetry_sram_size = ivpu_hw_reg_telemetry_size_get(vdev); diff --git a/drivers/accel/ivpu/ivpu_fw_log.c b/drivers/accel/ivpu/ivpu_fw_log.c index 95065cac9fbd..f6770f5e82a2 100644 --- a/drivers/accel/ivpu/ivpu_fw_log.c +++ b/drivers/accel/ivpu/ivpu_fw_log.c @@ -31,10 +31,10 @@ static int fw_log_ptr(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset, { struct vpu_tracing_buffer_header *log; - if ((*offset + sizeof(*log)) > bo->base.size) + if ((*offset + sizeof(*log)) > ivpu_bo_size(bo)) return -EINVAL; - log = bo->kvaddr + *offset; + log = ivpu_bo_vaddr(bo) + *offset; if (log->vpu_canary_start != VPU_TRACING_BUFFER_CANARY) return -EINVAL; @@ -43,7 +43,7 @@ static int fw_log_ptr(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset, ivpu_dbg(vdev, FW_BOOT, "Invalid header size 0x%x\n", log->header_size); return -EINVAL; } - if ((char *)log + log->size > (char *)bo->kvaddr + bo->base.size) { + if ((char *)log + log->size > (char *)ivpu_bo_vaddr(bo) + ivpu_bo_size(bo)) { ivpu_dbg(vdev, FW_BOOT, "Invalid log size 0x%x\n", log->size); return -EINVAL; } diff --git a/drivers/accel/ivpu/ivpu_gem.c b/drivers/accel/ivpu/ivpu_gem.c index d09f13b35902..c91852f2edc8 100644 --- a/drivers/accel/ivpu/ivpu_gem.c +++ b/drivers/accel/ivpu/ivpu_gem.c @@ -69,7 +69,7 @@ static const struct ivpu_bo_ops prime_ops = { static int __must_check shmem_alloc_pages_locked(struct ivpu_bo *bo) { - int npages = bo->base.size >> PAGE_SHIFT; + int npages = ivpu_bo_size(bo) >> PAGE_SHIFT; struct page **pages; pages = drm_gem_get_pages(&bo->base); @@ -88,7 +88,7 @@ static int __must_check shmem_alloc_pages_locked(struct ivpu_bo *bo) static void shmem_free_pages_locked(struct ivpu_bo *bo) { if (ivpu_bo_cache_mode(bo) != DRM_IVPU_BO_CACHED) - set_pages_array_wb(bo->pages, bo->base.size >> PAGE_SHIFT); + set_pages_array_wb(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT); drm_gem_put_pages(&bo->base, bo->pages, true, false); bo->pages = NULL; @@ -96,7 +96,7 @@ static void shmem_free_pages_locked(struct ivpu_bo *bo) static int ivpu_bo_map_pages_locked(struct ivpu_bo *bo) { - int npages = bo->base.size >> PAGE_SHIFT; + int npages = ivpu_bo_size(bo) >> PAGE_SHIFT; struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); struct sg_table *sgt; int ret; @@ -142,7 +142,7 @@ static const struct ivpu_bo_ops shmem_ops = { static int __must_check internal_alloc_pages_locked(struct ivpu_bo *bo) { - unsigned int i, npages = bo->base.size >> PAGE_SHIFT; + unsigned int i, npages = ivpu_bo_size(bo) >> PAGE_SHIFT; struct page **pages; int ret; @@ -171,10 +171,10 @@ err_free_pages: static void internal_free_pages_locked(struct ivpu_bo *bo) { - unsigned int i, npages = bo->base.size >> PAGE_SHIFT; + unsigned int i, npages = ivpu_bo_size(bo) >> PAGE_SHIFT; if (ivpu_bo_cache_mode(bo) != DRM_IVPU_BO_CACHED) - set_pages_array_wb(bo->pages, bo->base.size >> PAGE_SHIFT); + set_pages_array_wb(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT); for (i = 0; i < npages; i++) put_page(bo->pages[i]); @@ -291,7 +291,7 @@ ivpu_bo_alloc_vpu_addr(struct ivpu_bo *bo, struct ivpu_mmu_context *ctx, } mutex_lock(&ctx->lock); - ret = ivpu_mmu_context_insert_node_locked(ctx, range, bo->base.size, &bo->mm_node); + ret = ivpu_mmu_context_insert_node_locked(ctx, range, ivpu_bo_size(bo), &bo->mm_node); if (!ret) { bo->ctx = ctx; bo->vpu_addr = bo->mm_node.start; @@ -438,7 +438,7 @@ static int ivpu_bo_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma) struct ivpu_device *vdev = ivpu_bo_to_vdev(bo); ivpu_dbg(vdev, BO, "mmap: ctx %u handle %u vpu_addr 0x%llx size %zu type %s", - bo->ctx->id, bo->handle, bo->vpu_addr, bo->base.size, bo->ops->name); + bo->ctx->id, bo->handle, bo->vpu_addr, ivpu_bo_size(bo), bo->ops->name); if (obj->import_attach) { /* Drop the reference drm_gem_mmap_obj() acquired.*/ @@ -553,7 +553,7 @@ ivpu_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file) drm_gem_object_put(&bo->base); ivpu_dbg(vdev, BO, "alloc shmem: ctx %u vpu_addr 0x%llx size %zu flags 0x%x\n", - file_priv->ctx.id, bo->vpu_addr, bo->base.size, bo->flags); + file_priv->ctx.id, bo->vpu_addr, ivpu_bo_size(bo), bo->flags); return ret; } @@ -590,22 +590,22 @@ ivpu_bo_alloc_internal(struct ivpu_device *vdev, u64 vpu_addr, u64 size, u32 fla goto err_put; if (ivpu_bo_cache_mode(bo) != DRM_IVPU_BO_CACHED) - drm_clflush_pages(bo->pages, bo->base.size >> PAGE_SHIFT); + drm_clflush_pages(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT); if (bo->flags & DRM_IVPU_BO_WC) - set_pages_array_wc(bo->pages, bo->base.size >> PAGE_SHIFT); + set_pages_array_wc(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT); else if (bo->flags & DRM_IVPU_BO_UNCACHED) - set_pages_array_uc(bo->pages, bo->base.size >> PAGE_SHIFT); + set_pages_array_uc(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT); prot = ivpu_bo_pgprot(bo, PAGE_KERNEL); - bo->kvaddr = vmap(bo->pages, bo->base.size >> PAGE_SHIFT, VM_MAP, prot); + bo->kvaddr = vmap(bo->pages, ivpu_bo_size(bo) >> PAGE_SHIFT, VM_MAP, prot); if (!bo->kvaddr) { ivpu_err(vdev, "Failed to map BO into kernel virtual memory\n"); goto err_put; } ivpu_dbg(vdev, BO, "alloc internal: ctx 0 vpu_addr 0x%llx size %zu flags 0x%x\n", - bo->vpu_addr, bo->base.size, flags); + bo->vpu_addr, ivpu_bo_size(bo), flags); return bo; @@ -718,7 +718,7 @@ static void ivpu_bo_print_info(struct ivpu_bo *bo, struct drm_printer *p) dma_refcount = atomic_long_read(&bo->base.dma_buf->file->f_count); drm_printf(p, "%5u %6d %16llx %10lu %10u %12lu %14s\n", - bo->ctx->id, bo->handle, bo->vpu_addr, bo->base.size, + bo->ctx->id, bo->handle, bo->vpu_addr, ivpu_bo_size(bo), kref_read(&bo->base.refcount), dma_refcount, bo->ops->name); } diff --git a/drivers/accel/ivpu/ivpu_gem.h b/drivers/accel/ivpu/ivpu_gem.h index 6b0ceda5f253..a0b4d4a32b3b 100644 --- a/drivers/accel/ivpu/ivpu_gem.h +++ b/drivers/accel/ivpu/ivpu_gem.h @@ -68,9 +68,19 @@ static inline struct ivpu_bo *to_ivpu_bo(struct drm_gem_object *obj) return container_of(obj, struct ivpu_bo, base); } +static inline void *ivpu_bo_vaddr(struct ivpu_bo *bo) +{ + return bo->kvaddr; +} + +static inline size_t ivpu_bo_size(struct ivpu_bo *bo) +{ + return bo->base.size; +} + static inline struct page *ivpu_bo_get_page(struct ivpu_bo *bo, u64 offset) { - if (offset > bo->base.size || !bo->pages) + if (offset > ivpu_bo_size(bo) || !bo->pages) return NULL; return bo->pages[offset / PAGE_SIZE]; @@ -107,21 +117,21 @@ static inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u32 vpu_addr) if (vpu_addr < bo->vpu_addr) return NULL; - if (vpu_addr >= (bo->vpu_addr + bo->base.size)) + if (vpu_addr >= (bo->vpu_addr + ivpu_bo_size(bo))) return NULL; - return bo->kvaddr + (vpu_addr - bo->vpu_addr); + return ivpu_bo_vaddr(bo) + (vpu_addr - bo->vpu_addr); } static inline u32 cpu_to_vpu_addr(struct ivpu_bo *bo, void *cpu_addr) { - if (cpu_addr < bo->kvaddr) + if (cpu_addr < ivpu_bo_vaddr(bo)) return 0; - if (cpu_addr >= (bo->kvaddr + bo->base.size)) + if (cpu_addr >= (ivpu_bo_vaddr(bo) + ivpu_bo_size(bo))) return 0; - return bo->vpu_addr + (cpu_addr - bo->kvaddr); + return bo->vpu_addr + (cpu_addr - ivpu_bo_vaddr(bo)); } #endif /* __IVPU_GEM_H__ */ diff --git a/drivers/accel/ivpu/ivpu_ipc.c b/drivers/accel/ivpu/ivpu_ipc.c index 6b2e9dbb284a..c2541035a30f 100644 --- a/drivers/accel/ivpu/ivpu_ipc.c +++ b/drivers/accel/ivpu/ivpu_ipc.c @@ -449,7 +449,7 @@ int ivpu_ipc_init(struct ivpu_device *vdev) goto err_free_rx; } - ret = gen_pool_add(ipc->mm_tx, ipc->mem_tx->vpu_addr, ipc->mem_tx->base.size, -1); + ret = gen_pool_add(ipc->mm_tx, ipc->mem_tx->vpu_addr, ivpu_bo_size(ipc->mem_tx), -1); if (ret) { ivpu_err(vdev, "gen_pool_add failed, ret %d\n", ret); goto err_free_rx; @@ -505,8 +505,8 @@ void ivpu_ipc_reset(struct ivpu_device *vdev) mutex_lock(&ipc->lock); - memset(ipc->mem_tx->kvaddr, 0, ipc->mem_tx->base.size); - memset(ipc->mem_rx->kvaddr, 0, ipc->mem_rx->base.size); + memset(ivpu_bo_vaddr(ipc->mem_tx), 0, ivpu_bo_size(ipc->mem_tx)); + memset(ivpu_bo_vaddr(ipc->mem_rx), 0, ivpu_bo_size(ipc->mem_rx)); wmb(); /* Flush WC buffers for TX and RX rings */ mutex_unlock(&ipc->lock); diff --git a/drivers/accel/ivpu/ivpu_job.c b/drivers/accel/ivpu/ivpu_job.c index de9e69f70af7..689dc0d13b8f 100644 --- a/drivers/accel/ivpu/ivpu_job.c +++ b/drivers/accel/ivpu/ivpu_job.c @@ -48,10 +48,10 @@ static struct ivpu_cmdq *ivpu_cmdq_alloc(struct ivpu_file_priv *file_priv, u16 e goto cmdq_free; cmdq->db_id = file_priv->ctx.id + engine * ivpu_get_context_count(vdev); - cmdq->entry_count = (u32)((cmdq->mem->base.size - sizeof(struct vpu_job_queue_header)) / + cmdq->entry_count = (u32)((ivpu_bo_size(cmdq->mem) - sizeof(struct vpu_job_queue_header)) / sizeof(struct vpu_job_queue_entry)); - cmdq->jobq = (struct vpu_job_queue *)cmdq->mem->kvaddr; + cmdq->jobq = (struct vpu_job_queue *)ivpu_bo_vaddr(cmdq->mem); jobq_header = &cmdq->jobq->header; jobq_header->engine_idx = engine; jobq_header->head = 0; @@ -93,7 +93,7 @@ static struct ivpu_cmdq *ivpu_cmdq_acquire(struct ivpu_file_priv *file_priv, u16 return cmdq; ret = ivpu_jsm_register_db(vdev, file_priv->ctx.id, cmdq->db_id, - cmdq->mem->vpu_addr, cmdq->mem->base.size); + cmdq->mem->vpu_addr, ivpu_bo_size(cmdq->mem)); if (ret) return NULL; @@ -453,7 +453,7 @@ ivpu_job_prepare_bos_for_submit(struct drm_file *file, struct ivpu_job *job, u32 return -EBUSY; } - if (commands_offset >= bo->base.size) { + if (commands_offset >= ivpu_bo_size(bo)) { ivpu_warn(vdev, "Invalid command buffer offset %u\n", commands_offset); return -EINVAL; } diff --git a/drivers/accel/ivpu/ivpu_pm.c b/drivers/accel/ivpu/ivpu_pm.c index 28a0d1111e12..e359ba36a9c3 100644 --- a/drivers/accel/ivpu/ivpu_pm.c +++ b/drivers/accel/ivpu/ivpu_pm.c @@ -37,7 +37,7 @@ static void ivpu_pm_prepare_cold_boot(struct ivpu_device *vdev) static void ivpu_pm_prepare_warm_boot(struct ivpu_device *vdev) { struct ivpu_fw_info *fw = vdev->fw; - struct vpu_boot_params *bp = fw->mem->kvaddr; + struct vpu_boot_params *bp = ivpu_bo_vaddr(fw->mem); if (!bp->save_restore_ret_address) { ivpu_pm_prepare_cold_boot(vdev); -- cgit v1.2.3 From e0eb7db49764306a969183e0ed16659b24be89c1 Mon Sep 17 00:00:00 2001 From: Ian Ray Date: Thu, 21 Sep 2023 13:47:50 +0300 Subject: drm/bridge: megachips-stdpxxxx-ge-b850v3-fw: switch to drm_do_get_edid() Migrate away from custom EDID parsing and validity checks. Note: This is a follow-up to the original RFC by Jani [1]. The first submission in this series should have been marked v2. [1] https://patchwork.freedesktop.org/patch/msgid/20230901102400.552254-1-jani.nikula@intel.com Co-developed-by: Jani Nikula Signed-off-by: Jani Nikula Signed-off-by: Ian Ray Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230921104751.56544-1-ian.ray@ge.com --- .../drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c | 57 ++++------------------ 1 file changed, 9 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c index 460db3c8a08c..e93083bbec9d 100644 --- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c +++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c @@ -65,12 +65,11 @@ struct ge_b850v3_lvds { static struct ge_b850v3_lvds *ge_b850v3_lvds_ptr; -static u8 *stdp2690_get_edid(struct i2c_client *client) +static int stdp2690_read_block(void *context, u8 *buf, unsigned int block, size_t len) { + struct i2c_client *client = context; struct i2c_adapter *adapter = client->adapter; - unsigned char start = 0x00; - unsigned int total_size; - u8 *block = kmalloc(EDID_LENGTH, GFP_KERNEL); + unsigned char start = block * EDID_LENGTH; struct i2c_msg msgs[] = { { @@ -81,53 +80,15 @@ static u8 *stdp2690_get_edid(struct i2c_client *client) }, { .addr = client->addr, .flags = I2C_M_RD, - .len = EDID_LENGTH, - .buf = block, + .len = len, + .buf = buf, } }; - if (!block) - return NULL; + if (i2c_transfer(adapter, msgs, 2) != 2) + return -1; - if (i2c_transfer(adapter, msgs, 2) != 2) { - DRM_ERROR("Unable to read EDID.\n"); - goto err; - } - - if (!drm_edid_block_valid(block, 0, false, NULL)) { - DRM_ERROR("Invalid EDID data\n"); - goto err; - } - - total_size = (block[EDID_EXT_BLOCK_CNT] + 1) * EDID_LENGTH; - if (total_size > EDID_LENGTH) { - kfree(block); - block = kmalloc(total_size, GFP_KERNEL); - if (!block) - return NULL; - - /* Yes, read the entire buffer, and do not skip the first - * EDID_LENGTH bytes. - */ - start = 0x00; - msgs[1].len = total_size; - msgs[1].buf = block; - - if (i2c_transfer(adapter, msgs, 2) != 2) { - DRM_ERROR("Unable to read EDID extension blocks.\n"); - goto err; - } - if (!drm_edid_block_valid(block, 1, false, NULL)) { - DRM_ERROR("Invalid EDID data\n"); - goto err; - } - } - - return block; - -err: - kfree(block); - return NULL; + return 0; } static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge, @@ -137,7 +98,7 @@ static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge, client = ge_b850v3_lvds_ptr->stdp2690_i2c; - return (struct edid *)stdp2690_get_edid(client); + return drm_do_get_edid(connector, stdp2690_read_block, client); } static int ge_b850v3_lvds_get_modes(struct drm_connector *connector) -- cgit v1.2.3 From e755d439c1b7f579dfb7a36e6c2d14d426e14b3a Mon Sep 17 00:00:00 2001 From: Ian Ray Date: Thu, 21 Sep 2023 13:47:51 +0300 Subject: MAINTAINERS: Update entry for megachips-stdpxxxx-ge-b850v3-fw Replace Martin, who has left GE. Signed-off-by: Ian Ray Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230921104751.56544-2-ian.ray@ge.com --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index f4823d792b49..987152e3be02 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13544,7 +13544,7 @@ F: drivers/usb/mtu3/ MEGACHIPS STDPXXXX-GE-B850V3-FW LVDS/DP++ BRIDGES M: Peter Senna Tschudin -M: Martin Donnelly +M: Ian Ray M: Martyn Welch S: Maintained F: Documentation/devicetree/bindings/display/bridge/megachips-stdpxxxx-ge-b850v3-fw.txt -- cgit v1.2.3 From a48e2cc92835fa1d9b373b804b2173c779387b8e Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Mon, 9 Oct 2023 16:06:35 +0200 Subject: drm/ssd130x: Fix atomic_check for disabled planes The plane's atomic_check returns -EINVAL if the CRTC has not been set. This is the case for disabled planes, for which atomic_check should return 0. For disabled planes, it also omits the mandatory call to drm_atomic_helper_check_plane_state(). Replace the test with the boiler-plate code that first invokes drm_atomic_helper_check_plane_state() and then tests for the plane to be visible. Return early for non-visible planes. Signed-off-by: Thomas Zimmermann Fixes: d51f9fbd98b6 ("drm/ssd130x: Store the HW buffer in the driver-private CRTC state") Reviewed-by: Javier Martinez Canillas Tested-by: Javier Martinez Canillas Cc: Geert Uytterhoeven Cc: Javier Martinez Canillas Cc: Maxime Ripard Signed-off-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20231009141018.11291-7-tzimmermann@suse.de --- drivers/gpu/drm/solomon/ssd130x.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 6dcf3e041113..0c716136c538 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -638,21 +638,22 @@ static int ssd130x_primary_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state); struct drm_crtc *crtc = plane_state->crtc; - struct drm_crtc_state *crtc_state; + struct drm_crtc_state *crtc_state = NULL; const struct drm_format_info *fi; unsigned int pitch; int ret; - if (!crtc) - return -EINVAL; - - crtc_state = drm_atomic_get_crtc_state(state, crtc); - if (IS_ERR(crtc_state)) - return PTR_ERR(crtc_state); + if (crtc) + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); - ret = drm_plane_helper_atomic_check(plane, state); + ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, + false, false); if (ret) return ret; + else if (!plane_state->visible) + return 0; fi = drm_format_info(DRM_FORMAT_R1); if (!fi) -- cgit v1.2.3 From d12d635bb03c7cb4830acb641eb176ee9ff2aa89 Mon Sep 17 00:00:00 2001 From: Ondrej Jirman Date: Sat, 11 Feb 2023 18:17:48 +0100 Subject: drm/panel: st7703: Pick different reset sequence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switching to a different reset sequence, enabling IOVCC before enabling VCC. There also needs to be a delay after enabling the supplies and before deasserting the reset. The datasheet specifies 1ms after the supplies reach the required voltage. Use 10-20ms to also give the power supplies some time to reach the required voltage, too. This fixes intermittent panel initialization failures and screen corruption during resume from sleep on panel xingbangda,xbd599 (e.g. used in PinePhone). Signed-off-by: Ondrej Jirman Signed-off-by: Frank Oltmanns Reported-by: Samuel Holland Reviewed-by: Guido Günther Tested-by: Guido Günther Signed-off-by: Guido Günther Link: https://patchwork.freedesktop.org/patch/msgid/20230211171748.36692-2-frank@oltmanns.dev --- drivers/gpu/drm/panel/panel-sitronix-st7703.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c index 6a3945639535..7bb723d445ad 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c @@ -506,29 +506,30 @@ static int st7703_prepare(struct drm_panel *panel) return 0; dev_dbg(ctx->dev, "Resetting the panel\n"); - ret = regulator_enable(ctx->vcc); + gpiod_set_value_cansleep(ctx->reset_gpio, 1); + + ret = regulator_enable(ctx->iovcc); if (ret < 0) { - dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret); + dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret); return ret; } - ret = regulator_enable(ctx->iovcc); + + ret = regulator_enable(ctx->vcc); if (ret < 0) { - dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret); - goto disable_vcc; + dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret); + regulator_disable(ctx->iovcc); + return ret; } - gpiod_set_value_cansleep(ctx->reset_gpio, 1); - usleep_range(20, 40); + /* Give power supplies time to stabilize before deasserting reset. */ + usleep_range(10000, 20000); + gpiod_set_value_cansleep(ctx->reset_gpio, 0); - msleep(20); + usleep_range(15000, 20000); ctx->prepared = true; return 0; - -disable_vcc: - regulator_disable(ctx->vcc); - return ret; } static const u32 mantix_bus_formats[] = { -- cgit v1.2.3 From 0ddd30471a5dd78ff762ffb9eeae1d573283243a Mon Sep 17 00:00:00 2001 From: Frank Oltmanns Date: Mon, 13 Feb 2023 13:32:38 +0100 Subject: drm/panel: st7703: Fix timings when entering/exiting sleep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix flickering of the pinephone's XDB599 panel that happens after resume. Extend the delay after issuing the command to exit sleep mode from 60 to 120 msec as per the controller's specification. Introduce a 120 msec delay after issuing the command to enter sleep mode. This is needed in order for the controller to reliably finalize the sleep in sequence before switching of power supply. In contrast to the JH057N panel, the XBD599 panel does not require a 20 msec delay after initialization and exiting sleep mode. Therefore, move the delay into the already existing device specific initialization function. The XDB599 does not require a 20 msec delay between the SETBGP and SETVCOM commands. Therefore, remove the delay from the device specific initialization function. Signed-off-by: Frank Oltmanns Cc: Ondrej Jirman Reported-by: Samuel Holland Reviewed-by: Guido Günther Tested-by: Guido Günther Signed-off-by: Guido Günther Link: https://patchwork.freedesktop.org/patch/msgid/20230213123238.76889-2-frank@oltmanns.dev --- drivers/gpu/drm/panel/panel-sitronix-st7703.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c index 7bb723d445ad..79d56725b010 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c @@ -130,6 +130,7 @@ static int jh057n_init_sequence(struct st7703 *ctx) 0x18, 0x00, 0x09, 0x0E, 0x29, 0x2D, 0x3C, 0x41, 0x37, 0x07, 0x0B, 0x0D, 0x10, 0x11, 0x0F, 0x10, 0x11, 0x18); + msleep(20); return 0; } @@ -276,7 +277,6 @@ static int xbd599_init_sequence(struct st7703 *ctx) mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 0x07, /* VREF_SEL = 4.2V */ 0x07 /* NVREF_SEL = 4.2V */); - msleep(20); mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 0x2C, /* VCOMDC_F = -0.67V */ @@ -445,16 +445,14 @@ static int st7703_enable(struct drm_panel *panel) return ret; } - msleep(20); - ret = mipi_dsi_dcs_exit_sleep_mode(dsi); if (ret < 0) { dev_err(ctx->dev, "Failed to exit sleep mode: %d\n", ret); return ret; } - /* Panel is operational 120 msec after reset */ - msleep(60); + /* It takes the controller 120 msec to wake up after sleep. */ + msleep(120); ret = mipi_dsi_dcs_set_display_on(dsi); if (ret) @@ -479,6 +477,9 @@ static int st7703_disable(struct drm_panel *panel) if (ret < 0) dev_err(ctx->dev, "Failed to enter sleep mode: %d\n", ret); + /* It takes the controller 120 msec to enter sleep mode. */ + msleep(120); + return 0; } -- cgit v1.2.3 From 19e77c7aef5754e680ac77013538e2a3c0c173e4 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:51 +0100 Subject: drm: adv7511: Add struct adv7511_chip_info and use i2c_get_match_data() Add struct adv7511_chip_info to handle hw differences between various chips rather checking against the 'type' variable in various places. Replace 'adv->type'->'info->type' by moving variable 'type' from struct adv7511 to struct adv7511_chip_info and add adv7511_chip_info as device data for both OF and ID tables instead of the device type. Simplify the probe() by replacing of_device_get_match_data() and ID lookup for retrieving match data with i2c_get_match_data(). Signed-off-by: Biju Das Tested-by: Fabio Estevam Reviewed-by: Adam Ford Reviewed-by: Laurent Pinchart Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-2-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 6 ++- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 65 +++++++++++++++------------- drivers/gpu/drm/bridge/adv7511/adv7533.c | 4 +- 3 files changed, 43 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 17445800248d..59e8ef10d72e 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -333,6 +333,10 @@ enum adv7511_type { #define ADV7511_MAX_ADDRS 3 +struct adv7511_chip_info { + enum adv7511_type type; +}; + struct adv7511 { struct i2c_client *i2c_main; struct i2c_client *i2c_edid; @@ -377,7 +381,7 @@ struct adv7511 { u8 num_dsi_lanes; bool use_timing_gen; - enum adv7511_type type; + const struct adv7511_chip_info *info; struct platform_device *audio_pdev; struct cec_adapter *cec_adap; diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index d518de88b5c3..a8508e86b391 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511 *adv7511) * first few seconds after enabling the output. On the other hand * adv7535 require to enable HPD Override bit for proper HPD. */ - if (adv7511->type == ADV7535) + if (adv7511->info->type == ADV7535) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -373,7 +373,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) */ regcache_sync(adv7511->regmap); - if (adv7511->type == ADV7533 || adv7511->type == ADV7535) + if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) adv7533_dsi_power_on(adv7511); adv7511->powered = true; } @@ -381,7 +381,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) static void __adv7511_power_off(struct adv7511 *adv7511) { /* TODO: setup additional power down modes */ - if (adv7511->type == ADV7535) + if (adv7511->info->type == ADV7535) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, 0); @@ -397,7 +397,7 @@ static void __adv7511_power_off(struct adv7511 *adv7511) static void adv7511_power_off(struct adv7511 *adv7511) { __adv7511_power_off(adv7511); - if (adv7511->type == ADV7533 || adv7511->type == ADV7535) + if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) adv7533_dsi_power_off(adv7511); adv7511->powered = false; } @@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector) status = connector_status_disconnected; } else { /* Renable HPD sensing */ - if (adv7511->type == ADV7535) + if (adv7511->info->type == ADV7535) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -786,7 +786,7 @@ static void adv7511_mode_set(struct adv7511 *adv7511, else low_refresh_rate = ADV7511_LOW_REFRESH_RATE_NONE; - if (adv7511->type == ADV7511) + if (adv7511->info->type == ADV7511) regmap_update_bits(adv7511->regmap, 0xfb, 0x6, low_refresh_rate << 1); else @@ -921,7 +921,7 @@ static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge, { struct adv7511 *adv = bridge_to_adv7511(bridge); - if (adv->type == ADV7533 || adv->type == ADV7535) + if (adv->info->type == ADV7533 || adv->info->type == ADV7535) return adv7533_mode_valid(adv, mode); else return adv7511_mode_valid(adv, mode); @@ -1009,7 +1009,7 @@ static int adv7511_init_regulators(struct adv7511 *adv) unsigned int i; int ret; - if (adv->type == ADV7511) { + if (adv->info->type == ADV7511) { supply_names = adv7511_supply_names; adv->num_supplies = ARRAY_SIZE(adv7511_supply_names); } else { @@ -1093,7 +1093,7 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv) goto err; } - if (adv->type == ADV7533 || adv->type == ADV7535) { + if (adv->info->type == ADV7533 || adv->info->type == ADV7535) { ret = adv7533_patch_cec_registers(adv); if (ret) goto err; @@ -1192,7 +1192,6 @@ static int adv7511_parse_dt(struct device_node *np, static int adv7511_probe(struct i2c_client *i2c) { - const struct i2c_device_id *id = i2c_client_get_device_id(i2c); struct adv7511_link_config link_config; struct adv7511 *adv7511; struct device *dev = &i2c->dev; @@ -1209,15 +1208,11 @@ static int adv7511_probe(struct i2c_client *i2c) adv7511->i2c_main = i2c; adv7511->powered = false; adv7511->status = connector_status_disconnected; - - if (dev->of_node) - adv7511->type = (enum adv7511_type)of_device_get_match_data(dev); - else - adv7511->type = id->driver_data; + adv7511->info = i2c_get_match_data(i2c); memset(&link_config, 0, sizeof(link_config)); - if (adv7511->type == ADV7511) + if (adv7511->info->type == ADV7511) ret = adv7511_parse_dt(dev->of_node, &link_config); else ret = adv7533_parse_dt(dev->of_node, adv7511); @@ -1254,7 +1249,7 @@ static int adv7511_probe(struct i2c_client *i2c) goto uninit_regulators; dev_dbg(dev, "Rev. %d\n", val); - if (adv7511->type == ADV7511) + if (adv7511->info->type == ADV7511) ret = regmap_register_patch(adv7511->regmap, adv7511_fixed_registers, ARRAY_SIZE(adv7511_fixed_registers)); @@ -1306,7 +1301,7 @@ static int adv7511_probe(struct i2c_client *i2c) i2c_set_clientdata(i2c, adv7511); - if (adv7511->type == ADV7511) + if (adv7511->info->type == ADV7511) adv7511_set_link_config(adv7511, &link_config); ret = adv7511_cec_init(dev, adv7511); @@ -1325,7 +1320,7 @@ static int adv7511_probe(struct i2c_client *i2c) adv7511_audio_init(dev, adv7511); - if (adv7511->type == ADV7533 || adv7511->type == ADV7535) { + if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) { ret = adv7533_attach_dsi(adv7511); if (ret) goto err_unregister_audio; @@ -1368,22 +1363,34 @@ static void adv7511_remove(struct i2c_client *i2c) i2c_unregister_device(adv7511->i2c_edid); } +static const struct adv7511_chip_info adv7511_chip_info = { + .type = ADV7511, +}; + +static const struct adv7511_chip_info adv7533_chip_info = { + .type = ADV7533, +}; + +static const struct adv7511_chip_info adv7535_chip_info = { + .type = ADV7535, +}; + static const struct i2c_device_id adv7511_i2c_ids[] = { - { "adv7511", ADV7511 }, - { "adv7511w", ADV7511 }, - { "adv7513", ADV7511 }, - { "adv7533", ADV7533 }, - { "adv7535", ADV7535 }, + { "adv7511", (kernel_ulong_t)&adv7511_chip_info }, + { "adv7511w", (kernel_ulong_t)&adv7511_chip_info }, + { "adv7513", (kernel_ulong_t)&adv7511_chip_info }, + { "adv7533", (kernel_ulong_t)&adv7533_chip_info }, + { "adv7535", (kernel_ulong_t)&adv7535_chip_info }, { } }; MODULE_DEVICE_TABLE(i2c, adv7511_i2c_ids); static const struct of_device_id adv7511_of_ids[] = { - { .compatible = "adi,adv7511", .data = (void *)ADV7511 }, - { .compatible = "adi,adv7511w", .data = (void *)ADV7511 }, - { .compatible = "adi,adv7513", .data = (void *)ADV7511 }, - { .compatible = "adi,adv7533", .data = (void *)ADV7533 }, - { .compatible = "adi,adv7535", .data = (void *)ADV7535 }, + { .compatible = "adi,adv7511", .data = &adv7511_chip_info }, + { .compatible = "adi,adv7511w", .data = &adv7511_chip_info }, + { .compatible = "adi,adv7513", .data = &adv7511_chip_info }, + { .compatible = "adi,adv7533", .data = &adv7533_chip_info }, + { .compatible = "adi,adv7535", .data = &adv7535_chip_info }, { } }; MODULE_DEVICE_TABLE(of, adv7511_of_ids); diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c index 7e3e56441aed..c452c4dc1c3f 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -108,11 +108,11 @@ enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); /* Check max clock for either 7533 or 7535 */ - if (mode->clock > (adv->type == ADV7533 ? 80000 : 148500)) + if (mode->clock > (adv->info->type == ADV7533 ? 80000 : 148500)) return MODE_CLOCK_HIGH; /* Check max clock for each lane */ - max_lane_freq = (adv->type == ADV7533 ? 800000 : 891000); + max_lane_freq = (adv->info->type == ADV7533 ? 800000 : 891000); if (mode->clock * bpp > max_lane_freq * adv->num_dsi_lanes) return MODE_CLOCK_HIGH; -- cgit v1.2.3 From 11ae4e406dd9ab799da6f5951c3a6f8ec6b1e321 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:52 +0100 Subject: drm: adv7511: Add max_mode_clock_khz variable to struct adv7511_chip_info The ADV7533 supports a maximum pixel clock of 80MHz whereas it is 148.5MHz for ADV7535. Add max_mode_clock_khz variable to struct adv7511_chip_info to handle this difference. Signed-off-by: Biju Das Reviewed-by: Adam Ford Tested-by: Adam Ford #imx8mm-beacon Reviewed-by: Laurent Pinchart Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-3-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 2 ++ drivers/gpu/drm/bridge/adv7511/adv7533.c | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 59e8ef10d72e..b9c6c1e8a353 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -335,6 +335,7 @@ enum adv7511_type { struct adv7511_chip_info { enum adv7511_type type; + unsigned int max_mode_clock_khz; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index a8508e86b391..4ee90a754202 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1369,10 +1369,12 @@ static const struct adv7511_chip_info adv7511_chip_info = { static const struct adv7511_chip_info adv7533_chip_info = { .type = ADV7533, + .max_mode_clock_khz = 80000, }; static const struct adv7511_chip_info adv7535_chip_info = { .type = ADV7535, + .max_mode_clock_khz = 148500, }; static const struct i2c_device_id adv7511_i2c_ids[] = { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c index c452c4dc1c3f..1d113489754c 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -108,7 +108,7 @@ enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); /* Check max clock for either 7533 or 7535 */ - if (mode->clock > (adv->info->type == ADV7533 ? 80000 : 148500)) + if (mode->clock > adv->info->max_mode_clock_khz) return MODE_CLOCK_HIGH; /* Check max clock for each lane */ -- cgit v1.2.3 From 399562fc02d8e782f62cfc3791269d29e0b78085 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:53 +0100 Subject: drm: adv7511: Add max_lane_freq_khz variable to struct adv7511_chip_info The ADV7533 supports a maximum lane clock of 800MHz whereas it is 891MHz for ADV7535. Add max_lane_freq_khz variable to struct adv7511_chip_info to handle this difference. While at it, drop the unused local variable max_lane_freq. Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-4-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 2 ++ drivers/gpu/drm/bridge/adv7511/adv7533.c | 5 +---- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index b9c6c1e8a353..f8d61f2fa30e 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -336,6 +336,7 @@ enum adv7511_type { struct adv7511_chip_info { enum adv7511_type type; unsigned int max_mode_clock_khz; + unsigned int max_lane_freq_khz; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 4ee90a754202..4fff3e26e3d9 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1370,11 +1370,13 @@ static const struct adv7511_chip_info adv7511_chip_info = { static const struct adv7511_chip_info adv7533_chip_info = { .type = ADV7533, .max_mode_clock_khz = 80000, + .max_lane_freq_khz = 800000, }; static const struct adv7511_chip_info adv7535_chip_info = { .type = ADV7535, .max_mode_clock_khz = 148500, + .max_lane_freq_khz = 891000, }; static const struct i2c_device_id adv7511_i2c_ids[] = { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7533.c b/drivers/gpu/drm/bridge/adv7511/adv7533.c index 1d113489754c..4481489aaf5e 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7533.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7533.c @@ -103,7 +103,6 @@ void adv7533_dsi_power_off(struct adv7511 *adv) enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, const struct drm_display_mode *mode) { - unsigned long max_lane_freq; struct mipi_dsi_device *dsi = adv->dsi; u8 bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); @@ -112,9 +111,7 @@ enum drm_mode_status adv7533_mode_valid(struct adv7511 *adv, return MODE_CLOCK_HIGH; /* Check max clock for each lane */ - max_lane_freq = (adv->info->type == ADV7533 ? 800000 : 891000); - - if (mode->clock * bpp > max_lane_freq * adv->num_dsi_lanes) + if (mode->clock * bpp > adv->info->max_lane_freq_khz * adv->num_dsi_lanes) return MODE_CLOCK_HIGH; return MODE_OK; -- cgit v1.2.3 From 9ac196fb9a173dd13bf6e0cf4a7edb66fc0a3797 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:54 +0100 Subject: drm: adv7511: Add supply_names and num_supplies variables to struct adv7511_chip_info The ADV7511 has 5 power supplies compared to 7 that of ADV75{33,35}. Add supply_names and num_supplies variables to struct adv7511_chip_info to handle this difference. Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-5-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 3 ++- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 27 +++++++++++++-------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index f8d61f2fa30e..edf7be9c21d3 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -337,6 +337,8 @@ struct adv7511_chip_info { enum adv7511_type type; unsigned int max_mode_clock_khz; unsigned int max_lane_freq_khz; + const char * const *supply_names; + unsigned int num_supplies; }; struct adv7511 { @@ -375,7 +377,6 @@ struct adv7511 { struct gpio_desc *gpio_pd; struct regulator_bulk_data *supplies; - unsigned int num_supplies; /* ADV7533 DSI RX related params */ struct device_node *host_node; diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 4fff3e26e3d9..6c223f0eb4dc 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1004,37 +1004,30 @@ static const char * const adv7533_supply_names[] = { static int adv7511_init_regulators(struct adv7511 *adv) { + const char * const *supply_names = adv->info->supply_names; + unsigned int num_supplies = adv->info->num_supplies; struct device *dev = &adv->i2c_main->dev; - const char * const *supply_names; unsigned int i; int ret; - if (adv->info->type == ADV7511) { - supply_names = adv7511_supply_names; - adv->num_supplies = ARRAY_SIZE(adv7511_supply_names); - } else { - supply_names = adv7533_supply_names; - adv->num_supplies = ARRAY_SIZE(adv7533_supply_names); - } - - adv->supplies = devm_kcalloc(dev, adv->num_supplies, + adv->supplies = devm_kcalloc(dev, num_supplies, sizeof(*adv->supplies), GFP_KERNEL); if (!adv->supplies) return -ENOMEM; - for (i = 0; i < adv->num_supplies; i++) + for (i = 0; i < num_supplies; i++) adv->supplies[i].supply = supply_names[i]; - ret = devm_regulator_bulk_get(dev, adv->num_supplies, adv->supplies); + ret = devm_regulator_bulk_get(dev, num_supplies, adv->supplies); if (ret) return ret; - return regulator_bulk_enable(adv->num_supplies, adv->supplies); + return regulator_bulk_enable(num_supplies, adv->supplies); } static void adv7511_uninit_regulators(struct adv7511 *adv) { - regulator_bulk_disable(adv->num_supplies, adv->supplies); + regulator_bulk_disable(adv->info->num_supplies, adv->supplies); } static bool adv7511_cec_register_volatile(struct device *dev, unsigned int reg) @@ -1365,18 +1358,24 @@ static void adv7511_remove(struct i2c_client *i2c) static const struct adv7511_chip_info adv7511_chip_info = { .type = ADV7511, + .supply_names = adv7511_supply_names, + .num_supplies = ARRAY_SIZE(adv7511_supply_names), }; static const struct adv7511_chip_info adv7533_chip_info = { .type = ADV7533, .max_mode_clock_khz = 80000, .max_lane_freq_khz = 800000, + .supply_names = adv7533_supply_names, + .num_supplies = ARRAY_SIZE(adv7533_supply_names), }; static const struct adv7511_chip_info adv7535_chip_info = { .type = ADV7535, .max_mode_clock_khz = 148500, .max_lane_freq_khz = 891000, + .supply_names = adv7533_supply_names, + .num_supplies = ARRAY_SIZE(adv7533_supply_names), }; static const struct i2c_device_id adv7511_i2c_ids[] = { -- cgit v1.2.3 From 8d6cf571901148d0af549f4a7ae8c5b4a0f3e996 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:55 +0100 Subject: drm: adv7511: Add reg_cec_offset variable to struct adv7511_chip_info The ADV7533 and ADV7535 have an offset(0x70) for the CEC register map compared to ADV7511. Add the reg_cec_offset variable to struct adv7511_chip_info to handle this difference and drop the reg_cec_offset variable from struct adv7511. This will avoid assigning reg_cec_offset based on chip type and also testing for multiple chip types by calling adv7533_patch_cec_registers(). Signed-off-by: Biju Das Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-6-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 2 +- drivers/gpu/drm/bridge/adv7511/adv7511_cec.c | 14 +++++++------- drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index edf7be9c21d3..a728bfb33d03 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -339,6 +339,7 @@ struct adv7511_chip_info { unsigned int max_lane_freq_khz; const char * const *supply_names; unsigned int num_supplies; + unsigned int reg_cec_offset; }; struct adv7511 { @@ -349,7 +350,6 @@ struct adv7511 { struct regmap *regmap; struct regmap *regmap_cec; - unsigned int reg_cec_offset; enum drm_connector_status status; bool powered; diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c index 2a6b91f752cb..44451a9658a3 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_cec.c @@ -33,7 +33,7 @@ static const u8 ADV7511_REG_CEC_RX_FRAME_LEN[] = { static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; unsigned int val; if (regmap_read(adv7511->regmap_cec, @@ -84,7 +84,7 @@ static void adv_cec_tx_raw_status(struct adv7511 *adv7511, u8 tx_raw_status) static void adv7511_cec_rx(struct adv7511 *adv7511, int rx_buf) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; struct cec_msg msg = {}; unsigned int len; unsigned int val; @@ -121,7 +121,7 @@ static void adv7511_cec_rx(struct adv7511 *adv7511, int rx_buf) void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; const u32 irq_tx_mask = ADV7511_INT1_CEC_TX_READY | ADV7511_INT1_CEC_TX_ARBIT_LOST | ADV7511_INT1_CEC_TX_RETRY_TIMEOUT; @@ -177,7 +177,7 @@ void adv7511_cec_irq_process(struct adv7511 *adv7511, unsigned int irq1) static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable) { struct adv7511 *adv7511 = cec_get_drvdata(adap); - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; if (adv7511->i2c_cec == NULL) return -EIO; @@ -223,7 +223,7 @@ static int adv7511_cec_adap_enable(struct cec_adapter *adap, bool enable) static int adv7511_cec_adap_log_addr(struct cec_adapter *adap, u8 addr) { struct adv7511 *adv7511 = cec_get_drvdata(adap); - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; unsigned int i, free_idx = ADV7511_MAX_ADDRS; if (!adv7511->cec_enabled_adap) @@ -292,7 +292,7 @@ static int adv7511_cec_adap_transmit(struct cec_adapter *adap, u8 attempts, u32 signal_free_time, struct cec_msg *msg) { struct adv7511 *adv7511 = cec_get_drvdata(adap); - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; u8 len = msg->len; unsigned int i; @@ -345,7 +345,7 @@ static int adv7511_cec_parse_dt(struct device *dev, struct adv7511 *adv7511) int adv7511_cec_init(struct device *dev, struct adv7511 *adv7511) { - unsigned int offset = adv7511->reg_cec_offset; + unsigned int offset = adv7511->info->reg_cec_offset; int ret = adv7511_cec_parse_dt(dev, adv7511); if (ret) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 6c223f0eb4dc..45dcfc9d9212 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1035,7 +1035,7 @@ static bool adv7511_cec_register_volatile(struct device *dev, unsigned int reg) struct i2c_client *i2c = to_i2c_client(dev); struct adv7511 *adv7511 = i2c_get_clientdata(i2c); - reg -= adv7511->reg_cec_offset; + reg -= adv7511->info->reg_cec_offset; switch (reg) { case ADV7511_REG_CEC_RX1_FRAME_HDR: @@ -1086,12 +1086,10 @@ static int adv7511_init_cec_regmap(struct adv7511 *adv) goto err; } - if (adv->info->type == ADV7533 || adv->info->type == ADV7535) { + if (adv->info->reg_cec_offset == ADV7533_REG_CEC_OFFSET) { ret = adv7533_patch_cec_registers(adv); if (ret) goto err; - - adv->reg_cec_offset = ADV7533_REG_CEC_OFFSET; } return 0; @@ -1368,6 +1366,7 @@ static const struct adv7511_chip_info adv7533_chip_info = { .max_lane_freq_khz = 800000, .supply_names = adv7533_supply_names, .num_supplies = ARRAY_SIZE(adv7533_supply_names), + .reg_cec_offset = ADV7533_REG_CEC_OFFSET, }; static const struct adv7511_chip_info adv7535_chip_info = { @@ -1376,6 +1375,7 @@ static const struct adv7511_chip_info adv7535_chip_info = { .max_lane_freq_khz = 891000, .supply_names = adv7533_supply_names, .num_supplies = ARRAY_SIZE(adv7533_supply_names), + .reg_cec_offset = ADV7533_REG_CEC_OFFSET, }; static const struct i2c_device_id adv7511_i2c_ids[] = { -- cgit v1.2.3 From c75551214858384d5128cd874a0b346e0a624b56 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:56 +0100 Subject: drm: adv7511: Add has_dsi variable to struct adv7511_chip_info The ADV7533 and ADV7535 have DSI support. Add a variable has_dsi to struct adv7511_chip_info for handling configuration related to DSI. Signed-off-by: Biju Das Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-7-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 10 ++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index a728bfb33d03..0dd56e311039 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -340,6 +340,7 @@ struct adv7511_chip_info { const char * const *supply_names; unsigned int num_supplies; unsigned int reg_cec_offset; + bool has_dsi; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 45dcfc9d9212..5a3adaf95f0d 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -373,7 +373,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) */ regcache_sync(adv7511->regmap); - if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) + if (adv7511->info->has_dsi) adv7533_dsi_power_on(adv7511); adv7511->powered = true; } @@ -397,7 +397,7 @@ static void __adv7511_power_off(struct adv7511 *adv7511) static void adv7511_power_off(struct adv7511 *adv7511) { __adv7511_power_off(adv7511); - if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) + if (adv7511->info->has_dsi) adv7533_dsi_power_off(adv7511); adv7511->powered = false; } @@ -921,7 +921,7 @@ static enum drm_mode_status adv7511_bridge_mode_valid(struct drm_bridge *bridge, { struct adv7511 *adv = bridge_to_adv7511(bridge); - if (adv->info->type == ADV7533 || adv->info->type == ADV7535) + if (adv->info->has_dsi) return adv7533_mode_valid(adv, mode); else return adv7511_mode_valid(adv, mode); @@ -1311,7 +1311,7 @@ static int adv7511_probe(struct i2c_client *i2c) adv7511_audio_init(dev, adv7511); - if (adv7511->info->type == ADV7533 || adv7511->info->type == ADV7535) { + if (adv7511->info->has_dsi) { ret = adv7533_attach_dsi(adv7511); if (ret) goto err_unregister_audio; @@ -1367,6 +1367,7 @@ static const struct adv7511_chip_info adv7533_chip_info = { .supply_names = adv7533_supply_names, .num_supplies = ARRAY_SIZE(adv7533_supply_names), .reg_cec_offset = ADV7533_REG_CEC_OFFSET, + .has_dsi = true, }; static const struct adv7511_chip_info adv7535_chip_info = { @@ -1376,6 +1377,7 @@ static const struct adv7511_chip_info adv7535_chip_info = { .supply_names = adv7533_supply_names, .num_supplies = ARRAY_SIZE(adv7533_supply_names), .reg_cec_offset = ADV7533_REG_CEC_OFFSET, + .has_dsi = true, }; static const struct i2c_device_id adv7511_i2c_ids[] = { -- cgit v1.2.3 From 7618aa3ab38e1130268cca6aab408cd4fefeba0c Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:57 +0100 Subject: drm: adv7511: Add link_config variable to struct adv7511_chip_info The ADV7511 needs link configuration whereas ADV75{33,35} does not need it. Add a variable link_config to struct adv7511_chip_info to handle this difference. Signed-off-by: Biju Das Reviewed-by: Laurent Pinchart Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-8-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 0dd56e311039..0d39e32b0793 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -341,6 +341,7 @@ struct adv7511_chip_info { unsigned int num_supplies; unsigned int reg_cec_offset; bool has_dsi; + bool link_config; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index 5a3adaf95f0d..d076cee05e68 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -1203,7 +1203,7 @@ static int adv7511_probe(struct i2c_client *i2c) memset(&link_config, 0, sizeof(link_config)); - if (adv7511->info->type == ADV7511) + if (adv7511->info->link_config) ret = adv7511_parse_dt(dev->of_node, &link_config); else ret = adv7533_parse_dt(dev->of_node, adv7511); @@ -1292,7 +1292,7 @@ static int adv7511_probe(struct i2c_client *i2c) i2c_set_clientdata(i2c, adv7511); - if (adv7511->info->type == ADV7511) + if (adv7511->info->link_config) adv7511_set_link_config(adv7511, &link_config); ret = adv7511_cec_init(dev, adv7511); @@ -1358,6 +1358,7 @@ static const struct adv7511_chip_info adv7511_chip_info = { .type = ADV7511, .supply_names = adv7511_supply_names, .num_supplies = ARRAY_SIZE(adv7511_supply_names), + .link_config = true, }; static const struct adv7511_chip_info adv7533_chip_info = { -- cgit v1.2.3 From e12c4703cec0f07bae2f7cd1538ba9354e92b754 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Wed, 30 Aug 2023 15:23:58 +0100 Subject: drm: adv7511: Add hpd_override_enable variable to struct adv7511_chip_info As per spec, it is allowed to pulse the HPD signal to indicate that the EDID information has changed. Some monitors do this when they wake up from standby or are enabled. When the HPD goes low the adv7511 is reset and the outputs are disabled which might cause the monitor to go to standby again. To avoid this we ignore the HPD pin for the first few seconds after enabling the output. On the other hand, adv7535 require to enable HPD Override bit for proper HPD. Add hpd_override_enable variable to struct adv7511_chip_info to handle this scenario. Signed-off-by: Biju Das Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230830142358.275459-9-biju.das.jz@bp.renesas.com --- drivers/gpu/drm/bridge/adv7511/adv7511.h | 1 + drivers/gpu/drm/bridge/adv7511/adv7511_drv.c | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511.h b/drivers/gpu/drm/bridge/adv7511/adv7511.h index 0d39e32b0793..39c9ece373b0 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511.h +++ b/drivers/gpu/drm/bridge/adv7511/adv7511.h @@ -342,6 +342,7 @@ struct adv7511_chip_info { unsigned int reg_cec_offset; bool has_dsi; bool link_config; + bool hpd_override_enable; }; struct adv7511 { diff --git a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c index d076cee05e68..8be235144f6d 100644 --- a/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c +++ b/drivers/gpu/drm/bridge/adv7511/adv7511_drv.c @@ -354,7 +354,7 @@ static void __adv7511_power_on(struct adv7511 *adv7511) * first few seconds after enabling the output. On the other hand * adv7535 require to enable HPD Override bit for proper HPD. */ - if (adv7511->info->type == ADV7535) + if (adv7511->info->hpd_override_enable) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -381,7 +381,7 @@ static void adv7511_power_on(struct adv7511 *adv7511) static void __adv7511_power_off(struct adv7511 *adv7511) { /* TODO: setup additional power down modes */ - if (adv7511->info->type == ADV7535) + if (adv7511->info->hpd_override_enable) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, 0); @@ -682,7 +682,7 @@ adv7511_detect(struct adv7511 *adv7511, struct drm_connector *connector) status = connector_status_disconnected; } else { /* Renable HPD sensing */ - if (adv7511->info->type == ADV7535) + if (adv7511->info->hpd_override_enable) regmap_update_bits(adv7511->regmap, ADV7511_REG_POWER2, ADV7535_REG_POWER2_HPD_OVERRIDE, ADV7535_REG_POWER2_HPD_OVERRIDE); @@ -1379,6 +1379,7 @@ static const struct adv7511_chip_info adv7535_chip_info = { .num_supplies = ARRAY_SIZE(adv7533_supply_names), .reg_cec_offset = ADV7533_REG_CEC_OFFSET, .has_dsi = true, + .hpd_override_enable = true, }; static const struct i2c_device_id adv7511_i2c_ids[] = { -- cgit v1.2.3 From ec20c510ee2d2a7f0d0a00e4bfd55c28e500d3b7 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:00 +0800 Subject: drm/bridge: synopsys: dw-mipi-dsi: Add dw_mipi_dsi_get_bridge() helper Add dw_mipi_dsi_get_bridge() helper so that it can be used by vendor drivers which implement vendor specific extensions to Synopsys DW MIPI DSI. Signed-off-by: Liu Ying Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-2-victor.liu@nxp.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 6 ++++++ include/drm/bridge/dw_mipi_dsi.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index a8dd2a2e7c7b..591a75f59150 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -1209,6 +1209,12 @@ void dw_mipi_dsi_set_slave(struct dw_mipi_dsi *dsi, struct dw_mipi_dsi *slave) } EXPORT_SYMBOL_GPL(dw_mipi_dsi_set_slave); +struct drm_bridge *dw_mipi_dsi_get_bridge(struct dw_mipi_dsi *dsi) +{ + return &dsi->bridge; +} +EXPORT_SYMBOL_GPL(dw_mipi_dsi_get_bridge); + /* * Probe/remove API, used from platforms based on the DRM bridge API. */ diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h index 5286a53a1875..f54621b17a69 100644 --- a/include/drm/bridge/dw_mipi_dsi.h +++ b/include/drm/bridge/dw_mipi_dsi.h @@ -11,6 +11,7 @@ #include +#include #include struct drm_display_mode; @@ -68,5 +69,6 @@ void dw_mipi_dsi_remove(struct dw_mipi_dsi *dsi); int dw_mipi_dsi_bind(struct dw_mipi_dsi *dsi, struct drm_encoder *encoder); void dw_mipi_dsi_unbind(struct dw_mipi_dsi *dsi); void dw_mipi_dsi_set_slave(struct dw_mipi_dsi *dsi, struct dw_mipi_dsi *slave); +struct drm_bridge *dw_mipi_dsi_get_bridge(struct dw_mipi_dsi *dsi); #endif /* __DW_MIPI_DSI__ */ -- cgit v1.2.3 From 0de852d4c23a39d3ebff73d0c0c1b488eac6c5a8 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:01 +0800 Subject: drm/bridge: synopsys: dw-mipi-dsi: Add input bus format negotiation support Introduce ->get_input_bus_fmts() callback to struct dw_mipi_dsi_plat_data so that vendor drivers can implement specific methods to get input bus formats for Synopsys DW MIPI DSI. While at it, implement a generic callback for ->atomic_get_input_bus_fmts(), where we try to get the input bus formats through pdata->get_input_bus_fmts() first. If it's unavailable, fall back to the only format - MEDIA_BUS_FMT_FIXED, which matches the default behavior if ->atomic_get_input_bus_fmts() is not implemented as ->atomic_get_input_bus_fmts()'s kerneldoc indicates. Signed-off-by: Liu Ying Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-3-victor.liu@nxp.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 30 +++++++++++++++++++++++++++ include/drm/bridge/dw_mipi_dsi.h | 11 ++++++++++ 2 files changed, 41 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 591a75f59150..fbd0ae58a951 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -538,6 +539,34 @@ static const struct mipi_dsi_host_ops dw_mipi_dsi_host_ops = { .transfer = dw_mipi_dsi_host_transfer, }; +static u32 * +dw_mipi_dsi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); + const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data; + u32 *input_fmts; + + if (pdata->get_input_bus_fmts) + return pdata->get_input_bus_fmts(pdata->priv_data, + bridge, bridge_state, + crtc_state, conn_state, + output_fmt, num_input_fmts); + + /* Fall back to MEDIA_BUS_FMT_FIXED as the only input format. */ + input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + if (!input_fmts) + return NULL; + input_fmts[0] = MEDIA_BUS_FMT_FIXED; + *num_input_fmts = 1; + + return input_fmts; +} + static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) { u32 val; @@ -1006,6 +1035,7 @@ static int dw_mipi_dsi_bridge_attach(struct drm_bridge *bridge, static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = { .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_get_input_bus_fmts = dw_mipi_dsi_bridge_atomic_get_input_bus_fmts, .atomic_reset = drm_atomic_helper_bridge_reset, .atomic_pre_enable = dw_mipi_dsi_bridge_atomic_pre_enable, .atomic_enable = dw_mipi_dsi_bridge_atomic_enable, diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h index f54621b17a69..246650f2814f 100644 --- a/include/drm/bridge/dw_mipi_dsi.h +++ b/include/drm/bridge/dw_mipi_dsi.h @@ -11,7 +11,10 @@ #include +#include #include +#include +#include #include struct drm_display_mode; @@ -56,6 +59,14 @@ struct dw_mipi_dsi_plat_data { unsigned long mode_flags, u32 lanes, u32 format); + u32 *(*get_input_bus_fmts)(void *priv_data, + struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts); + const struct dw_mipi_dsi_phy_ops *phy_ops; const struct dw_mipi_dsi_host_ops *host_ops; -- cgit v1.2.3 From d5116fb29dc09bd4b9d9175f4f571e6eac539c93 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:02 +0800 Subject: drm/bridge: synopsys: dw-mipi-dsi: Force input bus flags The DATAEN_ACTIVE_LOW bit in DSI_DPI_CFG_POL register is set to zero, so set the DRM_BUS_FLAG_DE_HIGH flag in input_bus_cfg.flags. It appears that the DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE flag also makes sense, so set it in input_bus_cfg.flags too. With this patch, the flags set by drm_atomic_bridge_propagate_bus_flags() are overridden (see comment in that function) in case any downstream bridges propagates invalid flags to this bridge. A real problematic case is to connect a RM67191 MIPI DSI panel whose driver sets DRM_BUS_FLAG_DE_LOW and DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE bus flags. Signed-off-by: Liu Ying Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-4-victor.liu@nxp.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index fbd0ae58a951..4e5171b5978a 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -567,6 +568,17 @@ dw_mipi_dsi_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, return input_fmts; } +static int dw_mipi_dsi_bridge_atomic_check(struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + bridge_state->input_bus_cfg.flags = + DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE; + + return 0; +} + static void dw_mipi_dsi_video_mode_config(struct dw_mipi_dsi *dsi) { u32 val; @@ -1036,6 +1048,7 @@ static const struct drm_bridge_funcs dw_mipi_dsi_bridge_funcs = { .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .atomic_get_input_bus_fmts = dw_mipi_dsi_bridge_atomic_get_input_bus_fmts, + .atomic_check = dw_mipi_dsi_bridge_atomic_check, .atomic_reset = drm_atomic_helper_bridge_reset, .atomic_pre_enable = dw_mipi_dsi_bridge_atomic_pre_enable, .atomic_enable = dw_mipi_dsi_bridge_atomic_enable, -- cgit v1.2.3 From 5a67ec8c64ec88b5c34060b347ccec4a31af3369 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:03 +0800 Subject: drm/bridge: synopsys: dw-mipi-dsi: Add mode fixup support Vendor drivers may need to fixup mode due to pixel clock tree limitation, so introduce the ->mode_fixup() callcack to struct dw_mipi_dsi_plat_data and call it at atomic check stage if available. Signed-off-by: Liu Ying Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-5-victor.liu@nxp.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 14 ++++++++++++++ include/drm/bridge/dw_mipi_dsi.h | 3 +++ 2 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 4e5171b5978a..40d699428b1b 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -573,9 +573,23 @@ static int dw_mipi_dsi_bridge_atomic_check(struct drm_bridge *bridge, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { + struct dw_mipi_dsi *dsi = bridge_to_dsi(bridge); + const struct dw_mipi_dsi_plat_data *pdata = dsi->plat_data; + bool ret; + bridge_state->input_bus_cfg.flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE; + if (pdata->mode_fixup) { + ret = pdata->mode_fixup(pdata->priv_data, &crtc_state->mode, + &crtc_state->adjusted_mode); + if (!ret) { + DRM_DEBUG_DRIVER("failed to fixup mode " DRM_MODE_FMT "\n", + DRM_MODE_ARG(&crtc_state->mode)); + return -EINVAL; + } + } + return 0; } diff --git a/include/drm/bridge/dw_mipi_dsi.h b/include/drm/bridge/dw_mipi_dsi.h index 246650f2814f..65d5e68065e3 100644 --- a/include/drm/bridge/dw_mipi_dsi.h +++ b/include/drm/bridge/dw_mipi_dsi.h @@ -59,6 +59,9 @@ struct dw_mipi_dsi_plat_data { unsigned long mode_flags, u32 lanes, u32 format); + bool (*mode_fixup)(void *priv_data, const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode); + u32 *(*get_input_bus_fmts)(void *priv_data, struct drm_bridge *bridge, struct drm_bridge_state *bridge_state, -- cgit v1.2.3 From ac87d23694f44af44a98d21dd77016f2756b6b1b Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:04 +0800 Subject: drm/bridge: synopsys: dw-mipi-dsi: Use pixel clock rate to calculate lbcc To get better accuration, use pixel clock rate to calculate lbcc instead of lane_mbps since the pixel clock rate is in KHz while lane_mbps is in MHz. Without this, distorted image can be seen on a HDMI monitor connected with i.MX93 11x11 EVK through ADV7535 DSI to HDMI bridge in 1920x1080p@60 video mode. Signed-off-by: Liu Ying Reviewed-by: Neil Armstrong Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-6-victor.liu@nxp.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 40d699428b1b..b21ad4ea9dca 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -764,8 +765,15 @@ static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi, u32 hcomponent) { u32 frac, lbcc; + int bpp; - lbcc = hcomponent * dsi->lane_mbps * MSEC_PER_SEC / 8; + bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); + if (bpp < 0) { + dev_err(dsi->dev, "failed to get bpp\n"); + return 0; + } + + lbcc = div_u64((u64)hcomponent * mode->clock * bpp, dsi->lanes * 8); frac = lbcc % mode->clock; lbcc = lbcc / mode->clock; -- cgit v1.2.3 From d22e9a6df2db6a5b0ab7ff9123831e05c3e77899 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:05 +0800 Subject: drm/bridge: synopsys: dw-mipi-dsi: Set minimum lane byte clock cycles for HSA and HBP According to Synopsys support channel, each region of HSA, HBP and HFP must have minimum number of 10 bytes where constant 4 bytes are for HSS or HSE and 6 bytes are for blanking packet(header + CRC). Hence, the below table comes in. +------------+----------+-------+ | data lanes | min lbcc | bytes | +------------+----------+-------+ | 1 | 10 | 1*10 | +------------+----------+-------+ | 2 | 5 | 2*5 | +------------+----------+-------+ | 3 | 4 | 3*4 | +------------+----------+-------+ | 4 | 3 | 4*3 | +------------+----------+-------+ Implement the minimum lbcc numbers to make sure that the values programmed into DSI_VID_HSA_TIME and DSI_VID_HBP_TIME registers meet the minimum number requirement. For DSI_VID_HLINE_TIME register, it seems that the value programmed should be based on mode->htotal as-is, instead of sum up HSA, HBP, HFP and HDISPLAY. This helps the case where Raydium RM67191 DSI panel is connected, since it's video timing for hsync length is only 2 pixels and without this patch the programmed value for DSI_VID_HSA_TIME is only 2 with 4 data lanes. Signed-off-by: Liu Ying Reviewed-by: Neil Armstrong Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-7-victor.liu@nxp.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index b21ad4ea9dca..2fd01b299f73 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -759,12 +759,19 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi) dsi_write(dsi, DSI_MODE_CFG, ENABLE_CMD_MODE); } +static const u32 minimum_lbccs[] = {10, 5, 4, 3}; + +static inline u32 dw_mipi_dsi_get_minimum_lbcc(struct dw_mipi_dsi *dsi) +{ + return minimum_lbccs[dsi->lanes - 1]; +} + /* Get lane byte clock cycles. */ static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi, const struct drm_display_mode *mode, u32 hcomponent) { - u32 frac, lbcc; + u32 frac, lbcc, minimum_lbcc; int bpp; bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); @@ -780,6 +787,11 @@ static u32 dw_mipi_dsi_get_hcomponent_lbcc(struct dw_mipi_dsi *dsi, if (frac) lbcc++; + minimum_lbcc = dw_mipi_dsi_get_minimum_lbcc(dsi); + + if (lbcc < minimum_lbcc) + lbcc = minimum_lbcc; + return lbcc; } -- cgit v1.2.3 From 743bf594a3b1903a93f21f2060e3cdc5514e066c Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:06 +0800 Subject: drm/bridge: synopsys: dw-mipi-dsi: Disable HSTX and LPRX timeout check According to Synopsys DW MIPI DSI host databook, HSTX and LPRX timeout contention detections are measured in TO_CLK_DIVISION cycles. However, the current driver programs magic values to TO_CLK_DIVISION, HSTX_TO_CNT and LPRX_TO_CNT register fields, which makes timeout error event wrongly happen for some video modes, at least for the typical 1920x1080p@60 video mode read from a HDMI monitor driven by ADV7535 DSI to HDMI bridge. While at it, the current driver doesn't enable interrupt to handle or complain about the error status, so true error just happens silently except for display distortions by visual check. Disable the timeout check by setting those timeout register fields to zero for now until someone comes along with better computations for the timeout values. Although the databook doesn't mention what happens when they are set to zero, it turns out the false error doesn't happen for the 1920x1080p@60 video mode at least. Signed-off-by: Liu Ying Reviewed-by: Neil Armstrong Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-8-victor.liu@nxp.com --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index 2fd01b299f73..8789eca26188 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -686,7 +686,7 @@ static void dw_mipi_dsi_init(struct dw_mipi_dsi *dsi) * timeout clock division should be computed with the * high speed transmission counter timeout and byte lane... */ - dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(10) | + dsi_write(dsi, DSI_CLKMGR_CFG, TO_CLK_DIVISION(0) | TX_ESC_CLK_DIVISION(esc_clk_division)); } @@ -749,7 +749,7 @@ static void dw_mipi_dsi_command_mode_config(struct dw_mipi_dsi *dsi) * compute high speed transmission counter timeout according * to the timeout clock division (TO_CLK_DIVISION) and byte lane... */ - dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(1000) | LPRX_TO_CNT(1000)); + dsi_write(dsi, DSI_TO_CNT_CFG, HSTX_TO_CNT(0) | LPRX_TO_CNT(0)); /* * TODO dw drv improvements * the Bus-Turn-Around Timeout Counter should be computed -- cgit v1.2.3 From db95a55ccec749719ffe61a76c9a1d0a173c207c Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:07 +0800 Subject: dt-bindings: display: bridge: Document Freescale i.MX93 MIPI DSI Freescale i.MX93 SoC embeds a Synopsys Designware MIPI DSI host controller and a Synopsys Designware MIPI DPHY. Some configurations and extensions to them are controlled by i.MX93 media blk-ctrl. Signed-off-by: Liu Ying Reviewed-by: Rob Herring Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-9-victor.liu@nxp.com --- .../display/bridge/fsl,imx93-mipi-dsi.yaml | 115 +++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml new file mode 100644 index 000000000000..d6e51d0cf546 --- /dev/null +++ b/Documentation/devicetree/bindings/display/bridge/fsl,imx93-mipi-dsi.yaml @@ -0,0 +1,115 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/bridge/fsl,imx93-mipi-dsi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Freescale i.MX93 specific extensions to Synopsys Designware MIPI DSI + +maintainers: + - Liu Ying + +description: | + There is a Synopsys Designware MIPI DSI Host Controller and a Synopsys + Designware MIPI DPHY embedded in Freescale i.MX93 SoC. Some configurations + and extensions to them are controlled by i.MX93 media blk-ctrl. + +allOf: + - $ref: snps,dw-mipi-dsi.yaml# + +properties: + compatible: + const: fsl,imx93-mipi-dsi + + clocks: + items: + - description: apb clock + - description: pixel clock + - description: PHY configuration clock + - description: PHY reference clock + + clock-names: + items: + - const: pclk + - const: pix + - const: phy_cfg + - const: phy_ref + + interrupts: + maxItems: 1 + + fsl,media-blk-ctrl: + $ref: /schemas/types.yaml#/definitions/phandle + description: + i.MX93 media blk-ctrl, as a syscon, controls pixel component bit map + configurations from LCDIF display controller to the MIPI DSI host + controller and MIPI DPHY PLL related configurations through PLL SoC + interface. + + power-domains: + maxItems: 1 + +required: + - compatible + - interrupts + - fsl,media-blk-ctrl + - power-domains + +unevaluatedProperties: false + +examples: + - | + #include + #include + #include + #include + + dsi@4ae10000 { + compatible = "fsl,imx93-mipi-dsi"; + reg = <0x4ae10000 0x10000>; + interrupts = ; + clocks = <&clk IMX93_CLK_MIPI_DSI_GATE>, + <&clk IMX93_CLK_MEDIA_DISP_PIX>, + <&clk IMX93_CLK_MIPI_PHY_CFG>, + <&clk IMX93_CLK_24M>; + clock-names = "pclk", "pix", "phy_cfg", "phy_ref"; + fsl,media-blk-ctrl = <&media_blk_ctrl>; + power-domains = <&media_blk_ctrl IMX93_MEDIABLK_PD_MIPI_DSI>; + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "raydium,rm67191"; + reg = <0>; + reset-gpios = <&adp5585gpio 6 GPIO_ACTIVE_LOW>; + dsi-lanes = <4>; + video-mode = <2>; + + port { + panel_in: endpoint { + remote-endpoint = <&dsi_out>; + }; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dsi_to_lcdif: endpoint { + remote-endpoint = <&lcdif_to_dsi>; + }; + }; + + port@1 { + reg = <1>; + + dsi_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; + }; -- cgit v1.2.3 From ce62f8ea7e3f8a8e788c3b5ea0195f1224575b66 Mon Sep 17 00:00:00 2001 From: Liu Ying Date: Mon, 21 Aug 2023 11:40:08 +0800 Subject: drm/bridge: imx: Add i.MX93 MIPI DSI support Freescale i.MX93 SoC embeds a Synopsys Designware MIPI DSI host controller and a Synopsys Designware MIPI DPHY. Some configurations and extensions to them are controlled by i.MX93 media blk-ctrl. Add a DRM bridge for i.MX93 MIPI DSI by using existing DW MIPI DSI bridge helpers and implementing i.MX93 MIPI DSI specific extensions. Signed-off-by: Liu Ying Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20230821034008.3876938-10-victor.liu@nxp.com --- drivers/gpu/drm/bridge/imx/Kconfig | 11 + drivers/gpu/drm/bridge/imx/Makefile | 1 + drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c | 917 ++++++++++++++++++++++++++++ 3 files changed, 929 insertions(+) create mode 100644 drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c diff --git a/drivers/gpu/drm/bridge/imx/Kconfig b/drivers/gpu/drm/bridge/imx/Kconfig index 9fae28db6aa7..5a4f3d58501e 100644 --- a/drivers/gpu/drm/bridge/imx/Kconfig +++ b/drivers/gpu/drm/bridge/imx/Kconfig @@ -49,4 +49,15 @@ config DRM_IMX8QXP_PIXEL_LINK_TO_DPI Choose this to enable pixel link to display pixel interface(PXL2DPI) found in Freescale i.MX8qxp processor. +config DRM_IMX93_MIPI_DSI + tristate "Freescale i.MX93 specific extensions for Synopsys DW MIPI DSI" + depends on OF + depends on COMMON_CLK + select DRM_DW_MIPI_DSI + select GENERIC_PHY + select GENERIC_PHY_MIPI_DPHY + help + Choose this to enable MIPI DSI controller found in Freescale i.MX93 + processor. + endif # ARCH_MXC || COMPILE_TEST diff --git a/drivers/gpu/drm/bridge/imx/Makefile b/drivers/gpu/drm/bridge/imx/Makefile index 8e2ebf3399a1..2b0c2e44aa1b 100644 --- a/drivers/gpu/drm/bridge/imx/Makefile +++ b/drivers/gpu/drm/bridge/imx/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_DRM_IMX8QXP_LDB) += imx8qxp-ldb.o obj-$(CONFIG_DRM_IMX8QXP_PIXEL_COMBINER) += imx8qxp-pixel-combiner.o obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK) += imx8qxp-pixel-link.o obj-$(CONFIG_DRM_IMX8QXP_PIXEL_LINK_TO_DPI) += imx8qxp-pxl2dpi.o +obj-$(CONFIG_DRM_IMX93_MIPI_DSI) += imx93-mipi-dsi.o diff --git a/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c new file mode 100644 index 000000000000..3ff30ce80c5b --- /dev/null +++ b/drivers/gpu/drm/bridge/imx/imx93-mipi-dsi.c @@ -0,0 +1,917 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Copyright 2022,2023 NXP + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* DPHY PLL configuration registers */ +#define DSI_REG 0x4c +#define CFGCLKFREQRANGE_MASK GENMASK(5, 0) +#define CFGCLKFREQRANGE(x) FIELD_PREP(CFGCLKFREQRANGE_MASK, (x)) +#define CLKSEL_MASK GENMASK(7, 6) +#define CLKSEL_STOP FIELD_PREP(CLKSEL_MASK, 0) +#define CLKSEL_GEN FIELD_PREP(CLKSEL_MASK, 1) +#define CLKSEL_EXT FIELD_PREP(CLKSEL_MASK, 2) +#define HSFREQRANGE_MASK GENMASK(14, 8) +#define HSFREQRANGE(x) FIELD_PREP(HSFREQRANGE_MASK, (x)) +#define UPDATE_PLL BIT(17) +#define SHADOW_CLR BIT(18) +#define CLK_EXT BIT(19) + +#define DSI_WRITE_REG0 0x50 +#define M_MASK GENMASK(9, 0) +#define M(x) FIELD_PREP(M_MASK, ((x) - 2)) +#define N_MASK GENMASK(13, 10) +#define N(x) FIELD_PREP(N_MASK, ((x) - 1)) +#define VCO_CTRL_MASK GENMASK(19, 14) +#define VCO_CTRL(x) FIELD_PREP(VCO_CTRL_MASK, (x)) +#define PROP_CTRL_MASK GENMASK(25, 20) +#define PROP_CTRL(x) FIELD_PREP(PROP_CTRL_MASK, (x)) +#define INT_CTRL_MASK GENMASK(31, 26) +#define INT_CTRL(x) FIELD_PREP(INT_CTRL_MASK, (x)) + +#define DSI_WRITE_REG1 0x54 +#define GMP_CTRL_MASK GENMASK(1, 0) +#define GMP_CTRL(x) FIELD_PREP(GMP_CTRL_MASK, (x)) +#define CPBIAS_CTRL_MASK GENMASK(8, 2) +#define CPBIAS_CTRL(x) FIELD_PREP(CPBIAS_CTRL_MASK, (x)) +#define PLL_SHADOW_CTRL BIT(9) + +/* display mux control register */ +#define DISPLAY_MUX 0x60 +#define MIPI_DSI_RGB666_MAP_CFG GENMASK(7, 6) +#define RGB666_CONFIG1 FIELD_PREP(MIPI_DSI_RGB666_MAP_CFG, 0) +#define RGB666_CONFIG2 FIELD_PREP(MIPI_DSI_RGB666_MAP_CFG, 1) +#define MIPI_DSI_RGB565_MAP_CFG GENMASK(5, 4) +#define RGB565_CONFIG1 FIELD_PREP(MIPI_DSI_RGB565_MAP_CFG, 0) +#define RGB565_CONFIG2 FIELD_PREP(MIPI_DSI_RGB565_MAP_CFG, 1) +#define RGB565_CONFIG3 FIELD_PREP(MIPI_DSI_RGB565_MAP_CFG, 2) +#define LCDIF_CROSS_LINE_PATTERN GENMASK(3, 0) +#define RGB888_TO_RGB888 FIELD_PREP(LCDIF_CROSS_LINE_PATTERN, 0) +#define RGB888_TO_RGB666 FIELD_PREP(LCDIF_CROSS_LINE_PATTERN, 6) +#define RGB565_TO_RGB565 FIELD_PREP(LCDIF_CROSS_LINE_PATTERN, 7) + +#define MHZ(x) ((x) * 1000000UL) + +#define REF_CLK_RATE_MAX MHZ(64) +#define REF_CLK_RATE_MIN MHZ(2) +#define FOUT_MAX MHZ(1250) +#define FOUT_MIN MHZ(40) +#define FVCO_DIV_FACTOR MHZ(80) + +#define MBPS(x) ((x) * 1000000UL) + +#define DATA_RATE_MAX_SPEED MBPS(2500) +#define DATA_RATE_MIN_SPEED MBPS(80) + +#define M_MAX 625UL +#define M_MIN 64UL + +#define N_MAX 16U +#define N_MIN 1U + +struct imx93_dsi { + struct device *dev; + struct regmap *regmap; + struct clk *clk_pixel; + struct clk *clk_ref; + struct clk *clk_cfg; + struct dw_mipi_dsi *dmd; + struct dw_mipi_dsi_plat_data pdata; + union phy_configure_opts phy_cfg; + unsigned long ref_clk_rate; + u32 format; +}; + +struct dphy_pll_cfg { + u32 m; /* PLL Feedback Multiplication Ratio */ + u32 n; /* PLL Input Frequency Division Ratio */ +}; + +struct dphy_pll_vco_prop { + unsigned long max_fout; + u8 vco_cntl; + u8 prop_cntl; +}; + +struct dphy_pll_hsfreqrange { + unsigned long max_mbps; + u8 hsfreqrange; +}; + +/* DPHY Databook Table 3-13 Charge-pump Programmability */ +static const struct dphy_pll_vco_prop vco_prop_map[] = { + { 55, 0x3f, 0x0d }, + { 82, 0x37, 0x0d }, + { 110, 0x2f, 0x0d }, + { 165, 0x27, 0x0d }, + { 220, 0x1f, 0x0d }, + { 330, 0x17, 0x0d }, + { 440, 0x0f, 0x0d }, + { 660, 0x07, 0x0d }, + { 1149, 0x03, 0x0d }, + { 1152, 0x01, 0x0d }, + { 1250, 0x01, 0x0e }, +}; + +/* DPHY Databook Table 5-7 Frequency Ranges and Defaults */ +static const struct dphy_pll_hsfreqrange hsfreqrange_map[] = { + { 89, 0x00 }, + { 99, 0x10 }, + { 109, 0x20 }, + { 119, 0x30 }, + { 129, 0x01 }, + { 139, 0x11 }, + { 149, 0x21 }, + { 159, 0x31 }, + { 169, 0x02 }, + { 179, 0x12 }, + { 189, 0x22 }, + { 204, 0x32 }, + { 219, 0x03 }, + { 234, 0x13 }, + { 249, 0x23 }, + { 274, 0x33 }, + { 299, 0x04 }, + { 324, 0x14 }, + { 349, 0x25 }, + { 399, 0x35 }, + { 449, 0x05 }, + { 499, 0x16 }, + { 549, 0x26 }, + { 599, 0x37 }, + { 649, 0x07 }, + { 699, 0x18 }, + { 749, 0x28 }, + { 799, 0x39 }, + { 849, 0x09 }, + { 899, 0x19 }, + { 949, 0x29 }, + { 999, 0x3a }, + { 1049, 0x0a }, + { 1099, 0x1a }, + { 1149, 0x2a }, + { 1199, 0x3b }, + { 1249, 0x0b }, + { 1299, 0x1b }, + { 1349, 0x2b }, + { 1399, 0x3c }, + { 1449, 0x0c }, + { 1499, 0x1c }, + { 1549, 0x2c }, + { 1599, 0x3d }, + { 1649, 0x0d }, + { 1699, 0x1d }, + { 1749, 0x2e }, + { 1799, 0x3e }, + { 1849, 0x0e }, + { 1899, 0x1e }, + { 1949, 0x2f }, + { 1999, 0x3f }, + { 2049, 0x0f }, + { 2099, 0x40 }, + { 2149, 0x41 }, + { 2199, 0x42 }, + { 2249, 0x43 }, + { 2299, 0x44 }, + { 2349, 0x45 }, + { 2399, 0x46 }, + { 2449, 0x47 }, + { 2499, 0x48 }, + { 2500, 0x49 }, +}; + +static void dphy_pll_write(struct imx93_dsi *dsi, unsigned int reg, u32 value) +{ + int ret; + + ret = regmap_write(dsi->regmap, reg, value); + if (ret < 0) + dev_err(dsi->dev, "failed to write 0x%08x to pll reg 0x%x: %d\n", + value, reg, ret); +} + +static inline unsigned long data_rate_to_fout(unsigned long data_rate) +{ + /* Fout is half of data rate */ + return data_rate / 2; +} + +static int +dphy_pll_get_configure_from_opts(struct imx93_dsi *dsi, + struct phy_configure_opts_mipi_dphy *dphy_opts, + struct dphy_pll_cfg *cfg) +{ + struct device *dev = dsi->dev; + unsigned long fin = dsi->ref_clk_rate; + unsigned long fout; + unsigned long best_fout = 0; + unsigned int fvco_div; + unsigned int min_n, max_n, n, best_n; + unsigned long m, best_m; + unsigned long min_delta = ULONG_MAX; + unsigned long delta; + u64 tmp; + + if (dphy_opts->hs_clk_rate < DATA_RATE_MIN_SPEED || + dphy_opts->hs_clk_rate > DATA_RATE_MAX_SPEED) { + dev_dbg(dev, "invalid data rate per lane: %lu\n", + dphy_opts->hs_clk_rate); + return -EINVAL; + } + + fout = data_rate_to_fout(dphy_opts->hs_clk_rate); + + /* DPHY Databook 3.3.6.1 Output Frequency */ + /* Fout = Fvco / Fvco_div = (Fin * M) / (Fvco_div * N) */ + /* Fvco_div could be 1/2/4/8 according to Fout range. */ + fvco_div = 8UL / min(DIV_ROUND_UP(fout, FVCO_DIV_FACTOR), 8UL); + + /* limitation: 2MHz <= Fin / N <= 8MHz */ + min_n = DIV_ROUND_UP_ULL((u64)fin, MHZ(8)); + max_n = DIV_ROUND_DOWN_ULL((u64)fin, MHZ(2)); + + /* clamp possible N(s) */ + min_n = clamp(min_n, N_MIN, N_MAX); + max_n = clamp(max_n, N_MIN, N_MAX); + + dev_dbg(dev, "Fout = %lu, Fvco_div = %u, n_range = [%u, %u]\n", + fout, fvco_div, min_n, max_n); + + for (n = min_n; n <= max_n; n++) { + /* M = (Fout * N * Fvco_div) / Fin */ + m = DIV_ROUND_CLOSEST(fout * n * fvco_div, fin); + + /* check M range */ + if (m < M_MIN || m > M_MAX) + continue; + + /* calculate temporary Fout */ + tmp = m * fin; + do_div(tmp, n * fvco_div); + if (tmp < FOUT_MIN || tmp > FOUT_MAX) + continue; + + delta = abs(fout - tmp); + if (delta < min_delta) { + best_n = n; + best_m = m; + min_delta = delta; + best_fout = tmp; + } + } + + if (best_fout) { + cfg->m = best_m; + cfg->n = best_n; + dev_dbg(dev, "best Fout = %lu, m = %u, n = %u\n", + best_fout, cfg->m, cfg->n); + } else { + dev_dbg(dev, "failed to find best Fout\n"); + return -EINVAL; + } + + return 0; +} + +static void dphy_pll_clear_shadow(struct imx93_dsi *dsi) +{ + /* Reference DPHY Databook Figure 3-3 Initialization Timing Diagram. */ + /* Select clock generation first. */ + dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN); + + /* Clear shadow after clock selection is done a while. */ + fsleep(1); + dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN | SHADOW_CLR); + + /* A minimum pulse of 5ns on shadow_clear signal. */ + fsleep(1); + dphy_pll_write(dsi, DSI_REG, CLKSEL_GEN); +} + +static unsigned long dphy_pll_get_cfgclkrange(struct imx93_dsi *dsi) +{ + /* + * DPHY Databook Table 4-4 System Control Signals mentions an equation + * for cfgclkfreqrange[5:0]. + */ + return (clk_get_rate(dsi->clk_cfg) / MHZ(1) - 17) * 4; +} + +static u8 +dphy_pll_get_hsfreqrange(struct phy_configure_opts_mipi_dphy *dphy_opts) +{ + unsigned long mbps = dphy_opts->hs_clk_rate / MHZ(1); + int i; + + for (i = 0; i < ARRAY_SIZE(hsfreqrange_map); i++) + if (mbps <= hsfreqrange_map[i].max_mbps) + return hsfreqrange_map[i].hsfreqrange; + + return 0; +} + +static u8 dphy_pll_get_vco(struct phy_configure_opts_mipi_dphy *dphy_opts) +{ + unsigned long fout = data_rate_to_fout(dphy_opts->hs_clk_rate) / MHZ(1); + int i; + + for (i = 0; i < ARRAY_SIZE(vco_prop_map); i++) + if (fout <= vco_prop_map[i].max_fout) + return vco_prop_map[i].vco_cntl; + + return 0; +} + +static u8 dphy_pll_get_prop(struct phy_configure_opts_mipi_dphy *dphy_opts) +{ + unsigned long fout = data_rate_to_fout(dphy_opts->hs_clk_rate) / MHZ(1); + int i; + + for (i = 0; i < ARRAY_SIZE(vco_prop_map); i++) + if (fout <= vco_prop_map[i].max_fout) + return vco_prop_map[i].prop_cntl; + + return 0; +} + +static int dphy_pll_update(struct imx93_dsi *dsi) +{ + int ret; + + ret = regmap_update_bits(dsi->regmap, DSI_REG, UPDATE_PLL, UPDATE_PLL); + if (ret < 0) { + dev_err(dsi->dev, "failed to set UPDATE_PLL: %d\n", ret); + return ret; + } + + /* + * The updatepll signal should be asserted for a minimum of four clkin + * cycles, according to DPHY Databook Figure 3-3 Initialization Timing + * Diagram. + */ + fsleep(10); + + ret = regmap_update_bits(dsi->regmap, DSI_REG, UPDATE_PLL, 0); + if (ret < 0) { + dev_err(dsi->dev, "failed to clear UPDATE_PLL: %d\n", ret); + return ret; + } + + return 0; +} + +static int dphy_pll_configure(struct imx93_dsi *dsi, union phy_configure_opts *opts) +{ + struct dphy_pll_cfg cfg = { 0 }; + u32 val; + int ret; + + ret = dphy_pll_get_configure_from_opts(dsi, &opts->mipi_dphy, &cfg); + if (ret) { + dev_err(dsi->dev, "failed to get phy pll cfg %d\n", ret); + return ret; + } + + dphy_pll_clear_shadow(dsi); + + /* DSI_REG */ + val = CLKSEL_GEN | + CFGCLKFREQRANGE(dphy_pll_get_cfgclkrange(dsi)) | + HSFREQRANGE(dphy_pll_get_hsfreqrange(&opts->mipi_dphy)); + dphy_pll_write(dsi, DSI_REG, val); + + /* DSI_WRITE_REG0 */ + val = M(cfg.m) | N(cfg.n) | INT_CTRL(0) | + VCO_CTRL(dphy_pll_get_vco(&opts->mipi_dphy)) | + PROP_CTRL(dphy_pll_get_prop(&opts->mipi_dphy)); + dphy_pll_write(dsi, DSI_WRITE_REG0, val); + + /* DSI_WRITE_REG1 */ + dphy_pll_write(dsi, DSI_WRITE_REG1, GMP_CTRL(1) | CPBIAS_CTRL(0x10)); + + ret = clk_prepare_enable(dsi->clk_ref); + if (ret < 0) { + dev_err(dsi->dev, "failed to enable ref clock: %d\n", ret); + return ret; + } + + /* + * At least 10 refclk cycles are required before updatePLL assertion, + * according to DPHY Databook Figure 3-3 Initialization Timing Diagram. + */ + fsleep(10); + + ret = dphy_pll_update(dsi); + if (ret < 0) { + clk_disable_unprepare(dsi->clk_ref); + return ret; + } + + return 0; +} + +static void dphy_pll_clear_reg(struct imx93_dsi *dsi) +{ + dphy_pll_write(dsi, DSI_REG, 0); + dphy_pll_write(dsi, DSI_WRITE_REG0, 0); + dphy_pll_write(dsi, DSI_WRITE_REG1, 0); +} + +static int dphy_pll_init(struct imx93_dsi *dsi) +{ + int ret; + + ret = clk_prepare_enable(dsi->clk_cfg); + if (ret < 0) { + dev_err(dsi->dev, "failed to enable config clock: %d\n", ret); + return ret; + } + + dphy_pll_clear_reg(dsi); + + return 0; +} + +static void dphy_pll_uninit(struct imx93_dsi *dsi) +{ + dphy_pll_clear_reg(dsi); + clk_disable_unprepare(dsi->clk_cfg); +} + +static void dphy_pll_power_off(struct imx93_dsi *dsi) +{ + dphy_pll_clear_reg(dsi); + clk_disable_unprepare(dsi->clk_ref); +} + +static int imx93_dsi_get_phy_configure_opts(struct imx93_dsi *dsi, + const struct drm_display_mode *mode, + union phy_configure_opts *phy_cfg, + u32 lanes, u32 format) +{ + struct device *dev = dsi->dev; + int bpp; + int ret; + + bpp = mipi_dsi_pixel_format_to_bpp(format); + if (bpp < 0) { + dev_dbg(dev, "failed to get bpp for pixel format %d\n", format); + return -EINVAL; + } + + ret = phy_mipi_dphy_get_default_config(mode->clock * MSEC_PER_SEC, bpp, + lanes, &phy_cfg->mipi_dphy); + if (ret < 0) { + dev_dbg(dev, "failed to get default phy cfg %d\n", ret); + return ret; + } + + return 0; +} + +static enum drm_mode_status +imx93_dsi_validate_mode(struct imx93_dsi *dsi, const struct drm_display_mode *mode) +{ + struct drm_bridge *bridge = dw_mipi_dsi_get_bridge(dsi->dmd); + + /* Get the last bridge */ + while (drm_bridge_get_next_bridge(bridge)) + bridge = drm_bridge_get_next_bridge(bridge); + + if ((bridge->ops & DRM_BRIDGE_OP_DETECT) && + (bridge->ops & DRM_BRIDGE_OP_EDID)) { + unsigned long pixel_clock_rate = mode->clock * 1000; + unsigned long rounded_rate; + + /* Allow +/-0.5% pixel clock rate deviation */ + rounded_rate = clk_round_rate(dsi->clk_pixel, pixel_clock_rate); + if (rounded_rate < pixel_clock_rate * 995 / 1000 || + rounded_rate > pixel_clock_rate * 1005 / 1000) { + dev_dbg(dsi->dev, "failed to round clock for mode " DRM_MODE_FMT "\n", + DRM_MODE_ARG(mode)); + return MODE_NOCLOCK; + } + } + + return MODE_OK; +} + +static enum drm_mode_status +imx93_dsi_validate_phy(struct imx93_dsi *dsi, const struct drm_display_mode *mode, + unsigned long mode_flags, u32 lanes, u32 format) +{ + union phy_configure_opts phy_cfg; + struct dphy_pll_cfg cfg = { 0 }; + struct device *dev = dsi->dev; + int ret; + + ret = imx93_dsi_get_phy_configure_opts(dsi, mode, &phy_cfg, lanes, + format); + if (ret < 0) { + dev_dbg(dev, "failed to get phy cfg opts %d\n", ret); + return MODE_ERROR; + } + + ret = dphy_pll_get_configure_from_opts(dsi, &phy_cfg.mipi_dphy, &cfg); + if (ret < 0) { + dev_dbg(dev, "failed to get phy pll cfg %d\n", ret); + return MODE_NOCLOCK; + } + + return MODE_OK; +} + +static enum drm_mode_status +imx93_dsi_mode_valid(void *priv_data, const struct drm_display_mode *mode, + unsigned long mode_flags, u32 lanes, u32 format) +{ + struct imx93_dsi *dsi = priv_data; + struct device *dev = dsi->dev; + enum drm_mode_status ret; + + ret = imx93_dsi_validate_mode(dsi, mode); + if (ret != MODE_OK) { + dev_dbg(dev, "failed to validate mode " DRM_MODE_FMT "\n", + DRM_MODE_ARG(mode)); + return ret; + } + + ret = imx93_dsi_validate_phy(dsi, mode, mode_flags, lanes, format); + if (ret != MODE_OK) { + dev_dbg(dev, "failed to validate phy for mode " DRM_MODE_FMT "\n", + DRM_MODE_ARG(mode)); + return ret; + } + + return MODE_OK; +} + +static bool imx93_dsi_mode_fixup(void *priv_data, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) +{ + struct imx93_dsi *dsi = priv_data; + unsigned long pixel_clock_rate; + unsigned long rounded_rate; + + pixel_clock_rate = mode->clock * 1000; + rounded_rate = clk_round_rate(dsi->clk_pixel, pixel_clock_rate); + + memcpy(adjusted_mode, mode, sizeof(*mode)); + adjusted_mode->clock = rounded_rate / 1000; + + dev_dbg(dsi->dev, "adj clock %d for mode " DRM_MODE_FMT "\n", + adjusted_mode->clock, DRM_MODE_ARG(mode)); + + return true; +} + +static u32 *imx93_dsi_get_input_bus_fmts(void *priv_data, + struct drm_bridge *bridge, + struct drm_bridge_state *bridge_state, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state, + u32 output_fmt, + unsigned int *num_input_fmts) +{ + u32 *input_fmts, input_fmt; + + *num_input_fmts = 0; + + switch (output_fmt) { + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_RGB666_1X18: + case MEDIA_BUS_FMT_FIXED: + input_fmt = MEDIA_BUS_FMT_RGB888_1X24; + break; + case MEDIA_BUS_FMT_RGB565_1X16: + input_fmt = output_fmt; + break; + default: + return NULL; + } + + input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); + if (!input_fmts) + return NULL; + input_fmts[0] = input_fmt; + *num_input_fmts = 1; + + return input_fmts; +} + +static int imx93_dsi_phy_init(void *priv_data) +{ + struct imx93_dsi *dsi = priv_data; + unsigned int fmt = 0; + int ret; + + switch (dsi->format) { + case MIPI_DSI_FMT_RGB888: + fmt = RGB888_TO_RGB888; + break; + case MIPI_DSI_FMT_RGB666: + fmt = RGB888_TO_RGB666; + regmap_update_bits(dsi->regmap, DISPLAY_MUX, + MIPI_DSI_RGB666_MAP_CFG, RGB666_CONFIG2); + break; + case MIPI_DSI_FMT_RGB666_PACKED: + fmt = RGB888_TO_RGB666; + regmap_update_bits(dsi->regmap, DISPLAY_MUX, + MIPI_DSI_RGB666_MAP_CFG, RGB666_CONFIG1); + break; + case MIPI_DSI_FMT_RGB565: + fmt = RGB565_TO_RGB565; + regmap_update_bits(dsi->regmap, DISPLAY_MUX, + MIPI_DSI_RGB565_MAP_CFG, RGB565_CONFIG1); + break; + } + + regmap_update_bits(dsi->regmap, DISPLAY_MUX, LCDIF_CROSS_LINE_PATTERN, fmt); + + ret = dphy_pll_init(dsi); + if (ret < 0) { + dev_err(dsi->dev, "failed to init phy pll: %d\n", ret); + return ret; + } + + ret = dphy_pll_configure(dsi, &dsi->phy_cfg); + if (ret < 0) { + dev_err(dsi->dev, "failed to configure phy pll: %d\n", ret); + dphy_pll_uninit(dsi); + return ret; + } + + return 0; +} + +static void imx93_dsi_phy_power_off(void *priv_data) +{ + struct imx93_dsi *dsi = priv_data; + + dphy_pll_power_off(dsi); + dphy_pll_uninit(dsi); +} + +static int +imx93_dsi_get_lane_mbps(void *priv_data, const struct drm_display_mode *mode, + unsigned long mode_flags, u32 lanes, u32 format, + unsigned int *lane_mbps) +{ + struct imx93_dsi *dsi = priv_data; + union phy_configure_opts phy_cfg; + struct device *dev = dsi->dev; + int ret; + + ret = imx93_dsi_get_phy_configure_opts(dsi, mode, &phy_cfg, lanes, + format); + if (ret < 0) { + dev_dbg(dev, "failed to get phy cfg opts %d\n", ret); + return ret; + } + + *lane_mbps = DIV_ROUND_UP(phy_cfg.mipi_dphy.hs_clk_rate, USEC_PER_SEC); + + memcpy(&dsi->phy_cfg, &phy_cfg, sizeof(phy_cfg)); + + dev_dbg(dev, "get lane_mbps %u for mode " DRM_MODE_FMT "\n", + *lane_mbps, DRM_MODE_ARG(mode)); + + return 0; +} + +/* High-Speed Transition Times */ +struct hstt { + unsigned int maxfreq; + struct dw_mipi_dsi_dphy_timing timing; +}; + +#define HSTT(_maxfreq, _c_lp2hs, _c_hs2lp, _d_lp2hs, _d_hs2lp) \ +{ \ + .maxfreq = (_maxfreq), \ + .timing = { \ + .clk_lp2hs = (_c_lp2hs), \ + .clk_hs2lp = (_c_hs2lp), \ + .data_lp2hs = (_d_lp2hs), \ + .data_hs2lp = (_d_hs2lp), \ + } \ +} + +/* DPHY Databook Table A-4 High-Speed Transition Times */ +static const struct hstt hstt_table[] = { + HSTT(80, 21, 17, 15, 10), + HSTT(90, 23, 17, 16, 10), + HSTT(100, 22, 17, 16, 10), + HSTT(110, 25, 18, 17, 11), + HSTT(120, 26, 20, 18, 11), + HSTT(130, 27, 19, 19, 11), + HSTT(140, 27, 19, 19, 11), + HSTT(150, 28, 20, 20, 12), + HSTT(160, 30, 21, 22, 13), + HSTT(170, 30, 21, 23, 13), + HSTT(180, 31, 21, 23, 13), + HSTT(190, 32, 22, 24, 13), + HSTT(205, 35, 22, 25, 13), + HSTT(220, 37, 26, 27, 15), + HSTT(235, 38, 28, 27, 16), + HSTT(250, 41, 29, 30, 17), + HSTT(275, 43, 29, 32, 18), + HSTT(300, 45, 32, 35, 19), + HSTT(325, 48, 33, 36, 18), + HSTT(350, 51, 35, 40, 20), + HSTT(400, 59, 37, 44, 21), + HSTT(450, 65, 40, 49, 23), + HSTT(500, 71, 41, 54, 24), + HSTT(550, 77, 44, 57, 26), + HSTT(600, 82, 46, 64, 27), + HSTT(650, 87, 48, 67, 28), + HSTT(700, 94, 52, 71, 29), + HSTT(750, 99, 52, 75, 31), + HSTT(800, 105, 55, 82, 32), + HSTT(850, 110, 58, 85, 32), + HSTT(900, 115, 58, 88, 35), + HSTT(950, 120, 62, 93, 36), + HSTT(1000, 128, 63, 99, 38), + HSTT(1050, 132, 65, 102, 38), + HSTT(1100, 138, 67, 106, 39), + HSTT(1150, 146, 69, 112, 42), + HSTT(1200, 151, 71, 117, 43), + HSTT(1250, 153, 74, 120, 45), + HSTT(1300, 160, 73, 124, 46), + HSTT(1350, 165, 76, 130, 47), + HSTT(1400, 172, 78, 134, 49), + HSTT(1450, 177, 80, 138, 49), + HSTT(1500, 183, 81, 143, 52), + HSTT(1550, 191, 84, 147, 52), + HSTT(1600, 194, 85, 152, 52), + HSTT(1650, 201, 86, 155, 53), + HSTT(1700, 208, 88, 161, 53), + HSTT(1750, 212, 89, 165, 53), + HSTT(1800, 220, 90, 171, 54), + HSTT(1850, 223, 92, 175, 54), + HSTT(1900, 231, 91, 180, 55), + HSTT(1950, 236, 95, 185, 56), + HSTT(2000, 243, 97, 190, 56), + HSTT(2050, 248, 99, 194, 58), + HSTT(2100, 252, 100, 199, 59), + HSTT(2150, 259, 102, 204, 61), + HSTT(2200, 266, 105, 210, 62), + HSTT(2250, 269, 109, 213, 63), + HSTT(2300, 272, 109, 217, 65), + HSTT(2350, 281, 112, 225, 66), + HSTT(2400, 283, 115, 226, 66), + HSTT(2450, 282, 115, 226, 67), + HSTT(2500, 281, 118, 227, 67), +}; + +static int imx93_dsi_phy_get_timing(void *priv_data, unsigned int lane_mbps, + struct dw_mipi_dsi_dphy_timing *timing) +{ + struct imx93_dsi *dsi = priv_data; + struct device *dev = dsi->dev; + int i; + + for (i = 0; i < ARRAY_SIZE(hstt_table); i++) + if (lane_mbps <= hstt_table[i].maxfreq) + break; + + if (i == ARRAY_SIZE(hstt_table)) { + dev_err(dev, "failed to get phy timing for lane_mbps %u\n", + lane_mbps); + return -EINVAL; + } + + *timing = hstt_table[i].timing; + + dev_dbg(dev, "get phy timing for %u <= %u (lane_mbps)\n", + lane_mbps, hstt_table[i].maxfreq); + + return 0; +} + +static const struct dw_mipi_dsi_phy_ops imx93_dsi_phy_ops = { + .init = imx93_dsi_phy_init, + .power_off = imx93_dsi_phy_power_off, + .get_lane_mbps = imx93_dsi_get_lane_mbps, + .get_timing = imx93_dsi_phy_get_timing, +}; + +static int imx93_dsi_host_attach(void *priv_data, struct mipi_dsi_device *device) +{ + struct imx93_dsi *dsi = priv_data; + + dsi->format = device->format; + + return 0; +} + +static const struct dw_mipi_dsi_host_ops imx93_dsi_host_ops = { + .attach = imx93_dsi_host_attach, +}; + +static int imx93_dsi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct imx93_dsi *dsi; + int ret; + + dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL); + if (!dsi) + return -ENOMEM; + + dsi->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,media-blk-ctrl"); + if (IS_ERR(dsi->regmap)) { + ret = PTR_ERR(dsi->regmap); + dev_err(dev, "failed to get block ctrl regmap: %d\n", ret); + return ret; + } + + dsi->clk_pixel = devm_clk_get(dev, "pix"); + if (IS_ERR(dsi->clk_pixel)) + return dev_err_probe(dev, PTR_ERR(dsi->clk_pixel), + "failed to get pixel clock\n"); + + dsi->clk_cfg = devm_clk_get(dev, "phy_cfg"); + if (IS_ERR(dsi->clk_cfg)) + return dev_err_probe(dev, PTR_ERR(dsi->clk_cfg), + "failed to get phy cfg clock\n"); + + dsi->clk_ref = devm_clk_get(dev, "phy_ref"); + if (IS_ERR(dsi->clk_ref)) + return dev_err_probe(dev, PTR_ERR(dsi->clk_ref), + "failed to get phy ref clock\n"); + + dsi->ref_clk_rate = clk_get_rate(dsi->clk_ref); + if (dsi->ref_clk_rate < REF_CLK_RATE_MIN || + dsi->ref_clk_rate > REF_CLK_RATE_MAX) { + dev_err(dev, "invalid phy ref clock rate %lu\n", + dsi->ref_clk_rate); + return -EINVAL; + } + dev_dbg(dev, "phy ref clock rate: %lu\n", dsi->ref_clk_rate); + + dsi->dev = dev; + dsi->pdata.max_data_lanes = 4; + dsi->pdata.mode_valid = imx93_dsi_mode_valid; + dsi->pdata.mode_fixup = imx93_dsi_mode_fixup; + dsi->pdata.get_input_bus_fmts = imx93_dsi_get_input_bus_fmts; + dsi->pdata.phy_ops = &imx93_dsi_phy_ops; + dsi->pdata.host_ops = &imx93_dsi_host_ops; + dsi->pdata.priv_data = dsi; + platform_set_drvdata(pdev, dsi); + + dsi->dmd = dw_mipi_dsi_probe(pdev, &dsi->pdata); + if (IS_ERR(dsi->dmd)) + return dev_err_probe(dev, PTR_ERR(dsi->dmd), + "failed to probe dw_mipi_dsi\n"); + + return 0; +} + +static void imx93_dsi_remove(struct platform_device *pdev) +{ + struct imx93_dsi *dsi = platform_get_drvdata(pdev); + + dw_mipi_dsi_remove(dsi->dmd); +} + +static const struct of_device_id imx93_dsi_dt_ids[] = { + { .compatible = "fsl,imx93-mipi-dsi", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx93_dsi_dt_ids); + +static struct platform_driver imx93_dsi_driver = { + .probe = imx93_dsi_probe, + .remove_new = imx93_dsi_remove, + .driver = { + .of_match_table = imx93_dsi_dt_ids, + .name = "imx93_mipi_dsi", + }, +}; +module_platform_driver(imx93_dsi_driver); + +MODULE_DESCRIPTION("Freescale i.MX93 MIPI DSI driver"); +MODULE_AUTHOR("Liu Ying "); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 15fe53be46eaf4f6339cd433972ecc90513e3076 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Thu, 12 Oct 2023 01:00:02 +0300 Subject: drm/bridge: lt9611uxc: fix the race in the error path If DSI host attachment fails, the LT9611UXC driver will remove the bridge without ensuring that there is no outstanding HPD work being done. In rare cases this can result in the warnings regarding the mutex being incorrect. Fix this by forcebly freing IRQ and flushing the work. DEBUG_LOCKS_WARN_ON(lock->magic != lock) WARNING: CPU: 0 PID: 10 at kernel/locking/mutex.c:582 __mutex_lock+0x468/0x77c Modules linked in: CPU: 0 PID: 10 Comm: kworker/0:1 Tainted: G U 6.6.0-rc5-next-20231011-gd81f81c2b682-dirty #1206 Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT) Workqueue: events lt9611uxc_hpd_work pstate: 60400005 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : __mutex_lock+0x468/0x77c lr : __mutex_lock+0x468/0x77c sp : ffff8000800a3c70 x29: ffff8000800a3c70 x28: 0000000000000000 x27: ffffd595fe333000 x26: ffff7c2f0002c005 x25: ffffd595ff1b3000 x24: ffffd595fccda5a0 x23: 0000000000000000 x22: 0000000000000002 x21: ffff7c2f056d91c8 x20: 0000000000000000 x19: ffff7c2f056d91c8 x18: fffffffffffe8db0 x17: 000000040044ffff x16: 005000f2b5503510 x15: 0000000000000000 x14: 000000000006efb8 x13: 0000000000000000 x12: 0000000000000037 x11: 0000000000000001 x10: 0000000000001470 x9 : ffff8000800a3ae0 x8 : ffff7c2f0027f8d0 x7 : ffff7c2f0027e400 x6 : ffffd595fc702b54 x5 : 0000000000000000 x4 : ffff8000800a0000 x3 : 0000000000000000 x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff7c2f0027e400 Call trace: __mutex_lock+0x468/0x77c mutex_lock_nested+0x24/0x30 drm_bridge_hpd_notify+0x2c/0x5c lt9611uxc_hpd_work+0x6c/0x80 process_one_work+0x1ec/0x51c worker_thread+0x1ec/0x3e4 kthread+0x120/0x124 ret_from_fork+0x10/0x20 irq event stamp: 15799 hardirqs last enabled at (15799): [] finish_task_switch.isra.0+0xa8/0x278 hardirqs last disabled at (15798): [] __schedule+0x7b8/0xbd8 softirqs last enabled at (15794): [] __do_softirq+0x498/0x4e0 softirqs last disabled at (15771): [] ____do_softirq+0x10/0x1c Fixes: bc6fa8676ebb ("drm/bridge/lontium-lt9611uxc: move HPD notification out of IRQ handler") Signed-off-by: Dmitry Baryshkov Reviewed-by: Robert Foss Signed-off-by: Robert Foss Link: https://patchwork.freedesktop.org/patch/msgid/20231011220002.382422-1-dmitry.baryshkov@linaro.org --- drivers/gpu/drm/bridge/lontium-lt9611uxc.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c index 7835738a532e..e971b75e90ad 100644 --- a/drivers/gpu/drm/bridge/lontium-lt9611uxc.c +++ b/drivers/gpu/drm/bridge/lontium-lt9611uxc.c @@ -929,9 +929,9 @@ retry: init_waitqueue_head(<9611uxc->wq); INIT_WORK(<9611uxc->work, lt9611uxc_hpd_work); - ret = devm_request_threaded_irq(dev, client->irq, NULL, - lt9611uxc_irq_thread_handler, - IRQF_ONESHOT, "lt9611uxc", lt9611uxc); + ret = request_threaded_irq(client->irq, NULL, + lt9611uxc_irq_thread_handler, + IRQF_ONESHOT, "lt9611uxc", lt9611uxc); if (ret) { dev_err(dev, "failed to request irq\n"); goto err_disable_regulators; @@ -967,6 +967,8 @@ retry: return lt9611uxc_audio_init(dev, lt9611uxc); err_remove_bridge: + free_irq(client->irq, lt9611uxc); + cancel_work_sync(<9611uxc->work); drm_bridge_remove(<9611uxc->bridge); err_disable_regulators: @@ -983,7 +985,7 @@ static void lt9611uxc_remove(struct i2c_client *client) { struct lt9611uxc *lt9611uxc = i2c_get_clientdata(client); - disable_irq(client->irq); + free_irq(client->irq, lt9611uxc); cancel_work_sync(<9611uxc->work); lt9611uxc_audio_exit(lt9611uxc); drm_bridge_remove(<9611uxc->bridge); -- cgit v1.2.3 From 6471da5ee311d53ef46eebcb7725bc94266cc0cf Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 11 Oct 2023 11:01:48 +0300 Subject: drm/rockchip: Fix type promotion bug in rockchip_gem_iommu_map() The "ret" variable is declared as ssize_t and it can hold negative error codes but the "rk_obj->base.size" variable is type size_t. This means that when we compare them, they are both type promoted to size_t and the negative error code becomes a high unsigned value and is treated as success. Add a cast to fix this. Fixes: 38f993b7c59e ("drm/rockchip: Do not use DMA mapping API if attached to IOMMU domain") Signed-off-by: Dan Carpenter Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/2bfa28b5-145d-4b9e-a18a-98819dd686ce@moroto.mountain --- drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index b8f8b45ebf59..93ed841f5dce 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c @@ -40,7 +40,7 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj) ret = iommu_map_sgtable(private->domain, rk_obj->dma_addr, rk_obj->sgt, prot); - if (ret < rk_obj->base.size) { + if (ret < (ssize_t)rk_obj->base.size) { DRM_ERROR("failed to map buffer: size=%zd request_size=%zd\n", ret, rk_obj->base.size); ret = -ENOMEM; -- cgit v1.2.3 From ac1c11c23fc51c1ba51a3ed586df40ffe6b1de35 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Fri, 13 Oct 2023 20:20:36 +0800 Subject: drm/rockchip: remove unused struct in vop2 These structs are undefined and un used. Fixes: 604be85547ce ("drm/rockchip: Add VOP2 driver") Signed-off-by: Andy Yan Reviewed-by: Sascha Hauer Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20231013122036.1594090-1-andyshrk@163.com --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 2 -- drivers/gpu/drm/rockchip/rockchip_drm_vop2.h | 3 --- 2 files changed, 5 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index ec7e0e6149af..c5b8d716e493 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -160,7 +160,6 @@ struct vop2_video_port { struct vop2 *vop2; struct clk *dclk; unsigned int id; - const struct vop2_video_port_regs *regs; const struct vop2_video_port_data *data; struct completion dsp_hold_completion; @@ -2273,7 +2272,6 @@ static int vop2_create_crtcs(struct vop2 *vop2) vp = &vop2->vps[i]; vp->vop2 = vop2; vp->id = vp_data->id; - vp->regs = vp_data->regs; vp->data = vp_data; snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h index f1234a151130..56fd31e05238 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.h @@ -134,16 +134,13 @@ struct vop2_video_port_data { u16 cubic_lut_len; struct vop_rect max_output; const u8 pre_scan_max_dly[4]; - const struct vop2_video_port_regs *regs; unsigned int offset; }; struct vop2_data { u8 nr_vps; - const struct vop2_ctrl *ctrl; const struct vop2_win_data *win; const struct vop2_video_port_data *vp; - const struct vop_csc_table *csc_table; struct vop_rect max_input; struct vop_rect max_output; -- cgit v1.2.3 From dc00748adcf03d754bf43035c668bc5b20fb6597 Mon Sep 17 00:00:00 2001 From: Andy Yan Date: Fri, 13 Oct 2023 20:20:51 +0800 Subject: drm/rockchip: remove NR_LAYERS macro on vop2 There are 8 layers on rk3588, so a fix defined macro is not appropriate. Signed-off-by: Andy Yan Reviewed-by: Sascha Hauer Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20231013122051.1594164-1-andyshrk@163.com --- drivers/gpu/drm/rockchip/rockchip_drm_vop2.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c index c5b8d716e493..cce9183d750d 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop2.c @@ -2250,8 +2250,6 @@ static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2) return NULL; } -#define NR_LAYERS 6 - static int vop2_create_crtcs(struct vop2 *vop2) { const struct vop2_data *vop2_data = vop2->data; @@ -2370,7 +2368,7 @@ static int vop2_create_crtcs(struct vop2 *vop2) struct vop2_video_port *vp = &vop2->vps[i]; if (vp->crtc.port) - vp->nlayers = NR_LAYERS / nvps; + vp->nlayers = vop2_data->win_size / nvps; } return 0; -- cgit v1.2.3 From 00e395c8edf7fb6fa0830125d91c2b4bc381eefd Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Fri, 13 Oct 2023 13:39:14 -0500 Subject: dt-bindings: vendor-prefixes: document Powkiddy Document Powkiddy (https://powkiddy.com/). Signed-off-by: Chris Morgan Acked-by: Krzysztof Kozlowski Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20231013183918.225666-2-macroalpha82@gmail.com --- Documentation/devicetree/bindings/vendor-prefixes.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index 573578db9509..25fd2dc378f5 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1081,6 +1081,8 @@ patternProperties: description: Powertip Tech. Corp. "^powervr,.*": description: PowerVR (deprecated, use img) + "^powkiddy,.*": + description: Powkiddy "^primux,.*": description: Primux Trading, S.L. "^probox2,.*": -- cgit v1.2.3 From daee0320a13724e5a584726b693eee87bbd96172 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Fri, 13 Oct 2023 13:39:15 -0500 Subject: dt-bindings: panel: Add Powkiddy RGB30 panel compatible The Powkiddy RGB30 panel is a 4 inch 720x720 MIPI-DSI LCD panel. It appears to be based on the ST7703 LCD controller (this is assumed from the init sequence similarity between this and other displays). Powkiddy would not share the part number or name for the display from the bill of materials and there were no obvious external markings, so name the panel for the device (Powkiddy RGB30). Signed-off-by: Chris Morgan Acked-by: Krzysztof Kozlowski Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20231013183918.225666-3-macroalpha82@gmail.com --- .../devicetree/bindings/display/panel/rocktech,jh057n00900.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml b/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml index 5ea74426b1d5..97cccd8a8479 100644 --- a/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml +++ b/Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml @@ -22,6 +22,8 @@ properties: enum: # Anberic RG353V-V2 5.0" 640x480 TFT LCD panel - anbernic,rg353v-panel-v2 + # Powkiddy RGB30 3.0" 720x720 TFT LCD panel + - powkiddy,rgb30-panel # Rocktech JH057N00900 5.5" 720x1440 TFT LCD panel - rocktech,jh057n00900 # Xingbangda XBD599 5.99" 720x1440 TFT LCD panel -- cgit v1.2.3 From 636a989eb4d022e1756009592445aedaaf7424d8 Mon Sep 17 00:00:00 2001 From: Chris Morgan Date: Fri, 13 Oct 2023 13:39:16 -0500 Subject: drm/panel: st7703: Add Powkiddy RGB30 Panel Support The Powkiddy RGB30 4 inch panel is a 4 inch 720x720 DSI panel used in the Powkiddy RGB30 handheld gaming device. Add support for it. Signed-off-by: Chris Morgan Signed-off-by: Heiko Stuebner Link: https://patchwork.freedesktop.org/patch/msgid/20231013183918.225666-4-macroalpha82@gmail.com --- drivers/gpu/drm/panel/panel-sitronix-st7703.c | 89 +++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/drivers/gpu/drm/panel/panel-sitronix-st7703.c b/drivers/gpu/drm/panel/panel-sitronix-st7703.c index 79d56725b010..b55bafd1a8be 100644 --- a/drivers/gpu/drm/panel/panel-sitronix-st7703.c +++ b/drivers/gpu/drm/panel/panel-sitronix-st7703.c @@ -433,6 +433,94 @@ static const struct st7703_panel_desc rg353v2_desc = { .init_sequence = rg353v2_init_sequence, }; +static int rgb30panel_init_sequence(struct st7703 *ctx) +{ + struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); + + /* Init sequence extracted from Powkiddy RGB30 BSP kernel. */ + + /* + * For some reason this specific panel must be taken out of sleep + * before the full init sequence, or else it will not display. + */ + mipi_dsi_dcs_exit_sleep_mode(dsi); + msleep(250); + + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEXTC, 0xf1, 0x12, 0x83); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETMIPI, 0x33, 0x81, 0x05, 0xf9, + 0x0e, 0x0e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x44, 0x25, 0x00, 0x90, 0x0a, 0x00, + 0x00, 0x01, 0x4f, 0x01, 0x00, 0x00, 0x37); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER_EXT, 0x25, 0x22, 0xf0, + 0x63); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_UNKNOWN_BF, 0x02, 0x11, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETRGBIF, 0x10, 0x10, 0x28, + 0x28, 0x03, 0xff, 0x00, 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETSCR, 0x73, 0x73, 0x50, 0x50, + 0x00, 0x00, 0x12, 0x70, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVDC, 0x46); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPANEL, 0x0b); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETCYC, 0x80); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETDISP, 0x3c, 0x12, 0x30); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETEQ, 0x07, 0x07, 0x0b, 0x0b, + 0x03, 0x0b, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xc0, 0x10); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETPOWER, 0x36, 0x00, 0x32, + 0x32, 0x77, 0xf1, 0xcc, 0xcc, 0x77, 0x77, 0x33, + 0x33); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETBGP, 0x0a, 0x0a); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETVCOM, 0x88, 0x88); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP1, 0xc8, 0x10, 0x0a, 0x10, + 0x0f, 0xa1, 0x80, 0x12, 0x31, 0x23, 0x47, 0x86, + 0xa1, 0x80, 0x47, 0x08, 0x00, 0x00, 0x0d, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, + 0x48, 0x02, 0x8b, 0xaf, 0x46, 0x02, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x48, 0x13, 0x8b, 0xaf, 0x57, + 0x13, 0x88, 0x88, 0x88, 0x88, 0x88, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGIP2, 0x96, 0x12, 0x01, 0x01, + 0x01, 0x78, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4f, 0x31, 0x8b, 0xa8, 0x31, 0x75, 0x88, 0x88, + 0x88, 0x88, 0x88, 0x4f, 0x20, 0x8b, 0xa8, 0x20, + 0x64, 0x88, 0x88, 0x88, 0x88, 0x88, 0x23, 0x00, + 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0xa1, 0x80, 0x00, 0x00, 0x00, + 0x00); + mipi_dsi_dcs_write_seq(dsi, ST7703_CMD_SETGAMMA, 0x00, 0x0a, 0x0f, + 0x29, 0x3b, 0x3f, 0x42, 0x39, 0x06, 0x0d, 0x10, + 0x13, 0x15, 0x14, 0x15, 0x10, 0x17, 0x00, 0x0a, + 0x0f, 0x29, 0x3b, 0x3f, 0x42, 0x39, 0x06, 0x0d, + 0x10, 0x13, 0x15, 0x14, 0x15, 0x10, 0x17); + + return 0; +} + +static const struct drm_display_mode rgb30panel_mode = { + .hdisplay = 720, + .hsync_start = 720 + 45, + .hsync_end = 720 + 45 + 4, + .htotal = 720 + 45 + 4 + 45, + .vdisplay = 720, + .vsync_start = 720 + 15, + .vsync_end = 720 + 15 + 3, + .vtotal = 720 + 15 + 3 + 11, + .clock = 36570, + .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, + .width_mm = 76, + .height_mm = 76, +}; + +static const struct st7703_panel_desc rgb30panel_desc = { + .mode = &rgb30panel_mode, + .lanes = 4, + .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | + MIPI_DSI_MODE_NO_EOT_PACKET | MIPI_DSI_MODE_LPM, + .format = MIPI_DSI_FMT_RGB888, + .init_sequence = rgb30panel_init_sequence, +}; + static int st7703_enable(struct drm_panel *panel) { struct st7703 *ctx = panel_to_st7703(panel); @@ -696,6 +784,7 @@ static void st7703_remove(struct mipi_dsi_device *dsi) static const struct of_device_id st7703_of_match[] = { { .compatible = "anbernic,rg353v-panel-v2", .data = &rg353v2_desc }, + { .compatible = "powkiddy,rgb30-panel", .data = &rgb30panel_desc }, { .compatible = "rocktech,jh057n00900", .data = &jh057n00900_panel_desc }, { .compatible = "xingbangda,xbd599", .data = &xbd599_desc }, { /* sentinel */ } -- cgit v1.2.3 From 6f2eeef4a0aa9791bbba9d353641a6e067bb86c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= Date: Thu, 12 Oct 2023 15:25:52 +0200 Subject: Documentation/gpu: Add a VM_BIND async document MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a motivation for and description of asynchronous VM_BIND operation v2: - Fix typos (Nirmoy Das) - Improve the description of a memory fence (Oak Zeng) - Add a reference to the document in the Xe RFC. - Add pointers to sample uAPI suggestions v3: - Address review comments (Danilo Krummrich) - Formatting fixes v4: - Address typos (Francois Dugast) - Explain why in-fences are not allowed for VM_BIND operations for long- running workloads (Matthew Brost) v5: - More typo- and style fixing - Further clarify the implications of disallowing in-fences for VM_BIND operations for long-running workloads (Matthew Brost) v6: - Point out that a gpu_vm is a virtual GPU Address space. (Danilo Krummrich) - For an explanation of dma-fences point to the dma-fence documentation. (Paulo Zanoni) - Clarify that VM_BIND errors are reported synchronously. (Paulo Zanoni) - Use an rst doc reference when pointing to the async vm_bind document from the xe merge plan. - Add the VM_BIND documentation to the drm documentation table-of-content, using an intermediate "Misc DRM driver uAPI- and feature implementation guidelines" v7: - Update the error handling documentation to remove the VM error state. v8: - Clarify error handling and difference in operation support between async VM_BIND and sync VM_BIND. (Paulo Zanoni) - Update the sample uAPI with a self-contained example. (Paulo Zanoni) Cc: Paulo R Zanoni Signed-off-by: Thomas Hellström Acked-by: Nirmoy Das Reviewed-by: Danilo Krummrich Reviewed-by: Matthew Brost Reviewed-by: Rodrigo Vivi Reviewed-by: Paulo Zanoni Link: https://patchwork.freedesktop.org/patch/msgid/20231012132552.20196-1-thomas.hellstrom@linux.intel.com --- Documentation/gpu/drm-vm-bind-async.rst | 309 ++++++++++++++++++++++++ Documentation/gpu/implementation_guidelines.rst | 9 + Documentation/gpu/index.rst | 1 + Documentation/gpu/rfc/xe.rst | 4 +- 4 files changed, 321 insertions(+), 2 deletions(-) create mode 100644 Documentation/gpu/drm-vm-bind-async.rst create mode 100644 Documentation/gpu/implementation_guidelines.rst diff --git a/Documentation/gpu/drm-vm-bind-async.rst b/Documentation/gpu/drm-vm-bind-async.rst new file mode 100644 index 000000000000..3d709d02099c --- /dev/null +++ b/Documentation/gpu/drm-vm-bind-async.rst @@ -0,0 +1,309 @@ +.. SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +==================== +Asynchronous VM_BIND +==================== + +Nomenclature: +============= + +* ``VRAM``: On-device memory. Sometimes referred to as device local memory. + +* ``gpu_vm``: A virtual GPU address space. Typically per process, but + can be shared by multiple processes. + +* ``VM_BIND``: An operation or a list of operations to modify a gpu_vm using + an IOCTL. The operations include mapping and unmapping system- or + VRAM memory. + +* ``syncobj``: A container that abstracts synchronization objects. The + synchronization objects can be either generic, like dma-fences or + driver specific. A syncobj typically indicates the type of the + underlying synchronization object. + +* ``in-syncobj``: Argument to a VM_BIND IOCTL, the VM_BIND operation waits + for these before starting. + +* ``out-syncobj``: Argument to a VM_BIND_IOCTL, the VM_BIND operation + signals these when the bind operation is complete. + +* ``dma-fence``: A cross-driver synchronization object. A basic + understanding of dma-fences is required to digest this + document. Please refer to the ``DMA Fences`` section of the + :doc:`dma-buf doc `. + +* ``memory fence``: A synchronization object, different from a dma-fence. + A memory fence uses the value of a specified memory location to determine + signaled status. A memory fence can be awaited and signaled by both + the GPU and CPU. Memory fences are sometimes referred to as + user-fences, userspace-fences or gpu futexes and do not necessarily obey + the dma-fence rule of signaling within a "reasonable amount of time". + The kernel should thus avoid waiting for memory fences with locks held. + +* ``long-running workload``: A workload that may take more than the + current stipulated dma-fence maximum signal delay to complete and + which therefore needs to set the gpu_vm or the GPU execution context in + a certain mode that disallows completion dma-fences. + +* ``exec function``: An exec function is a function that revalidates all + affected gpu_vmas, submits a GPU command batch and registers the + dma_fence representing the GPU command's activity with all affected + dma_resvs. For completeness, although not covered by this document, + it's worth mentioning that an exec function may also be the + revalidation worker that is used by some drivers in compute / + long-running mode. + +* ``bind context``: A context identifier used for the VM_BIND + operation. VM_BIND operations that use the same bind context can be + assumed, where it matters, to complete in order of submission. No such + assumptions can be made for VM_BIND operations using separate bind contexts. + +* ``UMD``: User-mode driver. + +* ``KMD``: Kernel-mode driver. + + +Synchronous / Asynchronous VM_BIND operation +============================================ + +Synchronous VM_BIND +___________________ +With Synchronous VM_BIND, the VM_BIND operations all complete before the +IOCTL returns. A synchronous VM_BIND takes neither in-fences nor +out-fences. Synchronous VM_BIND may block and wait for GPU operations; +for example swap-in or clearing, or even previous binds. + +Asynchronous VM_BIND +____________________ +Asynchronous VM_BIND accepts both in-syncobjs and out-syncobjs. While the +IOCTL may return immediately, the VM_BIND operations wait for the in-syncobjs +before modifying the GPU page-tables, and signal the out-syncobjs when +the modification is done in the sense that the next exec function that +awaits for the out-syncobjs will see the change. Errors are reported +synchronously. +In low-memory situations the implementation may block, performing the +VM_BIND synchronously, because there might not be enough memory +immediately available for preparing the asynchronous operation. + +If the VM_BIND IOCTL takes a list or an array of operations as an argument, +the in-syncobjs needs to signal before the first operation starts to +execute, and the out-syncobjs signal after the last operation +completes. Operations in the operation list can be assumed, where it +matters, to complete in order. + +Since asynchronous VM_BIND operations may use dma-fences embedded in +out-syncobjs and internally in KMD to signal bind completion, any +memory fences given as VM_BIND in-fences need to be awaited +synchronously before the VM_BIND ioctl returns, since dma-fences, +required to signal in a reasonable amount of time, can never be made +to depend on memory fences that don't have such a restriction. + +The purpose of an Asynchronous VM_BIND operation is for user-mode +drivers to be able to pipeline interleaved gpu_vm modifications and +exec functions. For long-running workloads, such pipelining of a bind +operation is not allowed and any in-fences need to be awaited +synchronously. The reason for this is twofold. First, any memory +fences gated by a long-running workload and used as in-syncobjs for the +VM_BIND operation will need to be awaited synchronously anyway (see +above). Second, any dma-fences used as in-syncobjs for VM_BIND +operations for long-running workloads will not allow for pipelining +anyway since long-running workloads don't allow for dma-fences as +out-syncobjs, so while theoretically possible the use of them is +questionable and should be rejected until there is a valuable use-case. +Note that this is not a limitation imposed by dma-fence rules, but +rather a limitation imposed to keep KMD implementation simple. It does +not affect using dma-fences as dependencies for the long-running +workload itself, which is allowed by dma-fence rules, but rather for +the VM_BIND operation only. + +An asynchronous VM_BIND operation may take substantial time to +complete and signal the out_fence. In particular if the operation is +deeply pipelined behind other VM_BIND operations and workloads +submitted using exec functions. In that case, UMD might want to avoid a +subsequent VM_BIND operation to be queued behind the first one if +there are no explicit dependencies. In order to circumvent such a queue-up, a +VM_BIND implementation may allow for VM_BIND contexts to be +created. For each context, VM_BIND operations will be guaranteed to +complete in the order they were submitted, but that is not the case +for VM_BIND operations executing on separate VM_BIND contexts. Instead +KMD will attempt to execute such VM_BIND operations in parallel but +leaving no guarantee that they will actually be executed in +parallel. There may be internal implicit dependencies that only KMD knows +about, for example page-table structure changes. A way to attempt +to avoid such internal dependencies is to have different VM_BIND +contexts use separate regions of a VM. + +Also for VM_BINDS for long-running gpu_vms the user-mode driver should typically +select memory fences as out-fences since that gives greater flexibility for +the kernel mode driver to inject other operations into the bind / +unbind operations. Like for example inserting breakpoints into batch +buffers. The workload execution can then easily be pipelined behind +the bind completion using the memory out-fence as the signal condition +for a GPU semaphore embedded by UMD in the workload. + +There is no difference in the operations supported or in +multi-operation support between asynchronous VM_BIND and synchronous VM_BIND. + +Multi-operation VM_BIND IOCTL error handling and interrupts +=========================================================== + +The VM_BIND operations of the IOCTL may error for various reasons, for +example due to lack of resources to complete and due to interrupted +waits. +In these situations UMD should preferably restart the IOCTL after +taking suitable action. +If UMD has over-committed a memory resource, an -ENOSPC error will be +returned, and UMD may then unbind resources that are not used at the +moment and rerun the IOCTL. On -EINTR, UMD should simply rerun the +IOCTL and on -ENOMEM user-space may either attempt to free known +system memory resources or fail. In case of UMD deciding to fail a +bind operation, due to an error return, no additional action is needed +to clean up the failed operation, and the VM is left in the same state +as it was before the failing IOCTL. +Unbind operations are guaranteed not to return any errors due to +resource constraints, but may return errors due to, for example, +invalid arguments or the gpu_vm being banned. +In the case an unexpected error happens during the asynchronous bind +process, the gpu_vm will be banned, and attempts to use it after banning +will return -ENOENT. + +Example: The Xe VM_BIND uAPI +============================ + +Starting with the VM_BIND operation struct, the IOCTL call can take +zero, one or many such operations. A zero number means only the +synchronization part of the IOCTL is carried out: an asynchronous +VM_BIND updates the syncobjects, whereas a sync VM_BIND waits for the +implicit dependencies to be fulfilled. + +.. code-block:: c + + struct drm_xe_vm_bind_op { + /** + * @obj: GEM object to operate on, MBZ for MAP_USERPTR, MBZ for UNMAP + */ + __u32 obj; + + /** @pad: MBZ */ + __u32 pad; + + union { + /** + * @obj_offset: Offset into the object for MAP. + */ + __u64 obj_offset; + + /** @userptr: user virtual address for MAP_USERPTR */ + __u64 userptr; + }; + + /** + * @range: Number of bytes from the object to bind to addr, MBZ for UNMAP_ALL + */ + __u64 range; + + /** @addr: Address to operate on, MBZ for UNMAP_ALL */ + __u64 addr; + + /** + * @tile_mask: Mask for which tiles to create binds for, 0 == All tiles, + * only applies to creating new VMAs + */ + __u64 tile_mask; + + /* Map (parts of) an object into the GPU virtual address range. + #define XE_VM_BIND_OP_MAP 0x0 + /* Unmap a GPU virtual address range */ + #define XE_VM_BIND_OP_UNMAP 0x1 + /* + * Map a CPU virtual address range into a GPU virtual + * address range. + */ + #define XE_VM_BIND_OP_MAP_USERPTR 0x2 + /* Unmap a gem object from the VM. */ + #define XE_VM_BIND_OP_UNMAP_ALL 0x3 + /* + * Make the backing memory of an address range resident if + * possible. Note that this doesn't pin backing memory. + */ + #define XE_VM_BIND_OP_PREFETCH 0x4 + + /* Make the GPU map readonly. */ + #define XE_VM_BIND_FLAG_READONLY (0x1 << 16) + /* + * Valid on a faulting VM only, do the MAP operation immediately rather + * than deferring the MAP to the page fault handler. + */ + #define XE_VM_BIND_FLAG_IMMEDIATE (0x1 << 17) + /* + * When the NULL flag is set, the page tables are setup with a special + * bit which indicates writes are dropped and all reads return zero. In + * the future, the NULL flags will only be valid for XE_VM_BIND_OP_MAP + * operations, the BO handle MBZ, and the BO offset MBZ. This flag is + * intended to implement VK sparse bindings. + */ + #define XE_VM_BIND_FLAG_NULL (0x1 << 18) + /** @op: Operation to perform (lower 16 bits) and flags (upper 16 bits) */ + __u32 op; + + /** @mem_region: Memory region to prefetch VMA to, instance not a mask */ + __u32 region; + + /** @reserved: Reserved */ + __u64 reserved[2]; + }; + + +The VM_BIND IOCTL argument itself, looks like follows. Note that for +synchronous VM_BIND, the num_syncs and syncs fields must be zero. Here +the ``exec_queue_id`` field is the VM_BIND context discussed previously +that is used to facilitate out-of-order VM_BINDs. + +.. code-block:: c + + struct drm_xe_vm_bind { + /** @extensions: Pointer to the first extension struct, if any */ + __u64 extensions; + + /** @vm_id: The ID of the VM to bind to */ + __u32 vm_id; + + /** + * @exec_queue_id: exec_queue_id, must be of class DRM_XE_ENGINE_CLASS_VM_BIND + * and exec queue must have same vm_id. If zero, the default VM bind engine + * is used. + */ + __u32 exec_queue_id; + + /** @num_binds: number of binds in this IOCTL */ + __u32 num_binds; + + /* If set, perform an async VM_BIND, if clear a sync VM_BIND */ + #define XE_VM_BIND_IOCTL_FLAG_ASYNC (0x1 << 0) + + /** @flag: Flags controlling all operations in this ioctl. */ + __u32 flags; + + union { + /** @bind: used if num_binds == 1 */ + struct drm_xe_vm_bind_op bind; + + /** + * @vector_of_binds: userptr to array of struct + * drm_xe_vm_bind_op if num_binds > 1 + */ + __u64 vector_of_binds; + }; + + /** @num_syncs: amount of syncs to wait for or to signal on completion. */ + __u32 num_syncs; + + /** @pad2: MBZ */ + __u32 pad2; + + /** @syncs: pointer to struct drm_xe_sync array */ + __u64 syncs; + + /** @reserved: Reserved */ + __u64 reserved[2]; + }; diff --git a/Documentation/gpu/implementation_guidelines.rst b/Documentation/gpu/implementation_guidelines.rst new file mode 100644 index 000000000000..138e637dcc6b --- /dev/null +++ b/Documentation/gpu/implementation_guidelines.rst @@ -0,0 +1,9 @@ +.. SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +=========================================================== +Misc DRM driver uAPI- and feature implementation guidelines +=========================================================== + +.. toctree:: + + drm-vm-bind-async diff --git a/Documentation/gpu/index.rst b/Documentation/gpu/index.rst index e45ff0915246..37e383ccf73f 100644 --- a/Documentation/gpu/index.rst +++ b/Documentation/gpu/index.rst @@ -18,6 +18,7 @@ GPU Driver Developer's Guide vga-switcheroo vgaarbiter automated_testing + implementation_guidelines todo rfc/index diff --git a/Documentation/gpu/rfc/xe.rst b/Documentation/gpu/rfc/xe.rst index b67f8e6a1825..c29113a0ac30 100644 --- a/Documentation/gpu/rfc/xe.rst +++ b/Documentation/gpu/rfc/xe.rst @@ -97,8 +97,8 @@ memory fences. Ideally with helper support so people don't get it wrong in all possible ways. As a key measurable result, the benefits of ASYNC VM_BIND and a discussion of -various flavors, error handling and a sample API should be documented here or in -a separate document pointed to by this document. +various flavors, error handling and sample API suggestions are documented in +:doc:`The ASYNC VM_BIND document `. Userptr integration and vm_bind ------------------------------- -- cgit v1.2.3 From f7749a549b4f4db0c02e6b3d3800ea400dd76c12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Hellstr=C3=B6m?= Date: Tue, 10 Oct 2023 16:27:24 +0200 Subject: drm/gpuvm: Dual-licence the drm_gpuvm code GPL-2.0 OR MIT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dual-licence in order to make it possible for other non-GPL os'es to re-implement the code. The use of EXPORT_SYMBOL_GPL() is intentionally left untouched to prevent use of drm_gpuvm as a proxy for non-GPL drivers to access GPL-only kernel symbols. Much of the ideas and algorithms used in the drm_gpuvm code is already present in one way or another in MIT-licensed code. Cc: Danilo Krummrich Cc: airlied@gmail.com Cc: daniel@ffwll.ch Cc: linux-kernel@vger.kernel.org Signed-off-by: Thomas Hellström Acked-by: Danilo Krummrich Reviewed-by: Francois Dugast Link: https://patchwork.freedesktop.org/patch/msgid/20231010142725.8920-1-thomas.hellstrom@linux.intel.com --- drivers/gpu/drm/drm_gpuvm.c | 2 +- include/drm/drm_gpuvm.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/drm_gpuvm.c b/drivers/gpu/drm/drm_gpuvm.c index 02ce6baacdad..08c088319652 100644 --- a/drivers/gpu/drm/drm_gpuvm.c +++ b/drivers/gpu/drm/drm_gpuvm.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0-only +// SPDX-License-Identifier: GPL-2.0 OR MIT /* * Copyright (c) 2022 Red Hat. * diff --git a/include/drm/drm_gpuvm.h b/include/drm/drm_gpuvm.h index c7ed6bf441d4..bdfafc4a7705 100644 --- a/include/drm/drm_gpuvm.h +++ b/include/drm/drm_gpuvm.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ #ifndef __DRM_GPUVM_H__ #define __DRM_GPUVM_H__ -- cgit v1.2.3 From ec5dceb8180f0cb110dc7029d55d6a83d0583015 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 14 Oct 2023 09:15:03 +0200 Subject: drm/ssd130x: Replace .page_height field in device info with a constant This deemed useful to avoid hardcoding a page height and allow to support other Solomon controller families, but dividing the screen in pages seems to be something that is specific to the SSD130x chip family. For example, SSD132x chip family divides the screen in segments (columns) and common outputs (rows), so the concept of screen pages does not exist for the SSD132x family. Let's drop this field from the device info struct and just use a constant SSD130X_PAGE_HEIGHT macro to define the page height. While being there, replace hardcoded 8 values in places where it is used as the page height. Signed-off-by: Javier Martinez Canillas Reviewed-by: Geert Uytterhoeven Acked-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20231014071520.1342189-2-javierm@redhat.com --- drivers/gpu/drm/solomon/ssd130x.c | 37 ++++++++++++++++++------------------- drivers/gpu/drm/solomon/ssd130x.h | 1 - 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 0c716136c538..d530d13eef5a 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -42,6 +42,8 @@ #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 +#define SSD130X_PAGE_HEIGHT 8 + #define SSD130X_PAGE_COL_START_LOW 0x00 #define SSD130X_PAGE_COL_START_HIGH 0x10 #define SSD130X_SET_ADDRESS_MODE 0x20 @@ -102,7 +104,6 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_width = 132, .default_height = 64, .page_mode_only = 1, - .page_height = 8, }, [SSD1305_ID] = { .default_vcomh = 0x34, @@ -110,7 +111,6 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_dclk_frq = 7, .default_width = 132, .default_height = 64, - .page_height = 8, }, [SSD1306_ID] = { .default_vcomh = 0x20, @@ -119,7 +119,6 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .need_chargepump = 1, .default_width = 128, .default_height = 64, - .page_height = 8, }, [SSD1307_ID] = { .default_vcomh = 0x20, @@ -128,7 +127,6 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .need_pwm = 1, .default_width = 128, .default_height = 39, - .page_height = 8, }, [SSD1309_ID] = { .default_vcomh = 0x34, @@ -136,7 +134,6 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_dclk_frq = 10, .default_width = 128, .default_height = 64, - .page_height = 8, } }; EXPORT_SYMBOL_NS_GPL(ssd130x_variants, DRM_SSD130X); @@ -465,13 +462,13 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, unsigned int width = drm_rect_width(rect); unsigned int height = drm_rect_height(rect); unsigned int line_length = DIV_ROUND_UP(width, 8); - unsigned int page_height = ssd130x->device_info->page_height; + unsigned int page_height = SSD130X_PAGE_HEIGHT; unsigned int pages = DIV_ROUND_UP(height, page_height); struct drm_device *drm = &ssd130x->drm; u32 array_idx = 0; int ret, i, j, k; - drm_WARN_ONCE(drm, y % 8 != 0, "y must be aligned to screen page\n"); + drm_WARN_ONCE(drm, y % page_height != 0, "y must be aligned to screen page\n"); /* * The screen is divided in pages, each having a height of 8 @@ -503,27 +500,32 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, */ if (!ssd130x->page_address_mode) { + u8 page_start; + /* Set address range for horizontal addressing mode */ ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset + x, width); if (ret < 0) return ret; - ret = ssd130x_set_page_range(ssd130x, ssd130x->page_offset + y / 8, pages); + page_start = ssd130x->page_offset + y / page_height; + ret = ssd130x_set_page_range(ssd130x, page_start, pages); if (ret < 0) return ret; } for (i = 0; i < pages; i++) { - int m = 8; + int m = page_height; /* Last page may be partial */ - if (8 * (y / 8 + i + 1) > ssd130x->height) - m = ssd130x->height % 8; + if (page_height * (y / page_height + i + 1) > ssd130x->height) + m = ssd130x->height % page_height; + for (j = 0; j < width; j++) { u8 data = 0; for (k = 0; k < m; k++) { - u8 byte = buf[(8 * i + k) * line_length + j / 8]; + u32 idx = (page_height * i + k) * line_length + j / 8; + u8 byte = buf[idx]; u8 bit = (byte >> (j % 8)) & 1; data |= bit << k; @@ -559,8 +561,7 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array) { - unsigned int page_height = ssd130x->device_info->page_height; - unsigned int pages = DIV_ROUND_UP(ssd130x->height, page_height); + unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT); unsigned int width = ssd130x->width; int ret, i; @@ -605,14 +606,13 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, u8 *buf, u8 *data_array) { struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev); - unsigned int page_height = ssd130x->device_info->page_height; struct iosys_map dst; unsigned int dst_pitch; int ret = 0; /* Align y to display page boundaries */ - rect->y1 = round_down(rect->y1, page_height); - rect->y2 = min_t(unsigned int, round_up(rect->y2, page_height), ssd130x->height); + rect->y1 = round_down(rect->y1, SSD130X_PAGE_HEIGHT); + rect->y2 = min_t(unsigned int, round_up(rect->y2, SSD130X_PAGE_HEIGHT), ssd130x->height); dst_pitch = DIV_ROUND_UP(drm_rect_width(rect), 8); @@ -815,8 +815,7 @@ static int ssd130x_crtc_atomic_check(struct drm_crtc *crtc, struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state); - unsigned int page_height = ssd130x->device_info->page_height; - unsigned int pages = DIV_ROUND_UP(ssd130x->height, page_height); + unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT); int ret; ret = drm_crtc_helper_atomic_check(crtc, state); diff --git a/drivers/gpu/drm/solomon/ssd130x.h b/drivers/gpu/drm/solomon/ssd130x.h index aa39b13615eb..bbe374453605 100644 --- a/drivers/gpu/drm/solomon/ssd130x.h +++ b/drivers/gpu/drm/solomon/ssd130x.h @@ -39,7 +39,6 @@ struct ssd130x_deviceinfo { u32 default_dclk_frq; u32 default_width; u32 default_height; - u32 page_height; bool need_pwm; bool need_chargepump; bool page_mode_only; -- cgit v1.2.3 From e6663dd42a79a8d0440530ce91dd8667fe41ff03 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 14 Oct 2023 09:15:04 +0200 Subject: drm/ssd130x: Add a controller family id to the device info data To allow the driver to have a per Solomon display controller modesetting pipeline and support aother controller families besides SSD130x. Signed-off-by: Javier Martinez Canillas Acked-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20231014071520.1342189-3-javierm@redhat.com --- drivers/gpu/drm/solomon/ssd130x-i2c.c | 1 + drivers/gpu/drm/solomon/ssd130x-spi.c | 2 ++ drivers/gpu/drm/solomon/ssd130x.c | 5 +++++ drivers/gpu/drm/solomon/ssd130x.h | 7 +++++++ 4 files changed, 15 insertions(+) diff --git a/drivers/gpu/drm/solomon/ssd130x-i2c.c b/drivers/gpu/drm/solomon/ssd130x-i2c.c index b4eb2d64bf6e..8f89b89d553f 100644 --- a/drivers/gpu/drm/solomon/ssd130x-i2c.c +++ b/drivers/gpu/drm/solomon/ssd130x-i2c.c @@ -54,6 +54,7 @@ static void ssd130x_i2c_shutdown(struct i2c_client *client) } static const struct of_device_id ssd130x_of_match[] = { + /* ssd130x family */ { .compatible = "sinowealth,sh1106", .data = &ssd130x_variants[SH1106_ID], diff --git a/drivers/gpu/drm/solomon/ssd130x-spi.c b/drivers/gpu/drm/solomon/ssd130x-spi.c index 19ab4942cb33..257819bccbc8 100644 --- a/drivers/gpu/drm/solomon/ssd130x-spi.c +++ b/drivers/gpu/drm/solomon/ssd130x-spi.c @@ -108,6 +108,7 @@ static void ssd130x_spi_shutdown(struct spi_device *spi) } static const struct of_device_id ssd130x_of_match[] = { + /* ssd130x family */ { .compatible = "sinowealth,sh1106", .data = &ssd130x_variants[SH1106_ID], @@ -142,6 +143,7 @@ MODULE_DEVICE_TABLE(of, ssd130x_of_match); * not be needed for this driver to match the registered SPI devices. */ static const struct spi_device_id ssd130x_spi_table[] = { + /* ssd130x family */ { "sh1106", SH1106_ID }, { "ssd1305", SSD1305_ID }, { "ssd1306", SSD1306_ID }, diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index d530d13eef5a..84093bcc8584 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -104,6 +104,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_width = 132, .default_height = 64, .page_mode_only = 1, + .family_id = SSD130X_FAMILY, }, [SSD1305_ID] = { .default_vcomh = 0x34, @@ -111,6 +112,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_dclk_frq = 7, .default_width = 132, .default_height = 64, + .family_id = SSD130X_FAMILY, }, [SSD1306_ID] = { .default_vcomh = 0x20, @@ -119,6 +121,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .need_chargepump = 1, .default_width = 128, .default_height = 64, + .family_id = SSD130X_FAMILY, }, [SSD1307_ID] = { .default_vcomh = 0x20, @@ -127,6 +130,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .need_pwm = 1, .default_width = 128, .default_height = 39, + .family_id = SSD130X_FAMILY, }, [SSD1309_ID] = { .default_vcomh = 0x34, @@ -134,6 +138,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_dclk_frq = 10, .default_width = 128, .default_height = 64, + .family_id = SSD130X_FAMILY, } }; EXPORT_SYMBOL_NS_GPL(ssd130x_variants, DRM_SSD130X); diff --git a/drivers/gpu/drm/solomon/ssd130x.h b/drivers/gpu/drm/solomon/ssd130x.h index bbe374453605..c562c2d00c16 100644 --- a/drivers/gpu/drm/solomon/ssd130x.h +++ b/drivers/gpu/drm/solomon/ssd130x.h @@ -24,7 +24,12 @@ #define SSD130X_DATA 0x40 #define SSD130X_COMMAND 0x80 +enum ssd130x_family_ids { + SSD130X_FAMILY +}; + enum ssd130x_variants { + /* ssd130x family */ SH1106_ID, SSD1305_ID, SSD1306_ID, @@ -42,6 +47,8 @@ struct ssd130x_deviceinfo { bool need_pwm; bool need_chargepump; bool page_mode_only; + + enum ssd130x_family_ids family_id; }; struct ssd130x_device { -- cgit v1.2.3 From 9081d21a5a6b575551bfd6281981537140b55338 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 14 Oct 2023 09:15:05 +0200 Subject: drm/ssd130x: Rename commands that are shared across chip families There are some commands that are shared between the SSD130x and SSD132x controller families, define these as a common SSD13XX set of commands. Signed-off-by: Javier Martinez Canillas Acked-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20231014071520.1342189-4-javierm@redhat.com --- drivers/gpu/drm/solomon/ssd130x-spi.c | 4 +-- drivers/gpu/drm/solomon/ssd130x.c | 47 +++++++++++++++++++---------------- drivers/gpu/drm/solomon/ssd130x.h | 4 +-- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/solomon/ssd130x-spi.c b/drivers/gpu/drm/solomon/ssd130x-spi.c index 257819bccbc8..89989da705d7 100644 --- a/drivers/gpu/drm/solomon/ssd130x-spi.c +++ b/drivers/gpu/drm/solomon/ssd130x-spi.c @@ -34,10 +34,10 @@ static int ssd130x_spi_write(void *context, const void *data, size_t count) struct spi_device *spi = t->spi; const u8 *reg = data; - if (*reg == SSD130X_COMMAND) + if (*reg == SSD13XX_COMMAND) gpiod_set_value_cansleep(t->dc, 0); - if (*reg == SSD130X_DATA) + if (*reg == SSD13XX_DATA) gpiod_set_value_cansleep(t->dc, 1); /* Remove control byte since is not used in a 4-wire SPI interface */ diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 84093bcc8584..e11f16bf795e 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -44,18 +44,24 @@ #define SSD130X_PAGE_HEIGHT 8 +/* ssd13xx commands */ +#define SSD13XX_CONTRAST 0x81 +#define SSD13XX_SET_SEG_REMAP 0xa0 +#define SSD13XX_SET_MULTIPLEX_RATIO 0xa8 +#define SSD13XX_DISPLAY_OFF 0xae +#define SSD13XX_DISPLAY_ON 0xaf + +#define SSD13XX_SET_SEG_REMAP_MASK GENMASK(0, 0) +#define SSD13XX_SET_SEG_REMAP_SET(val) FIELD_PREP(SSD13XX_SET_SEG_REMAP_MASK, (val)) + +/* ssd130x commands */ #define SSD130X_PAGE_COL_START_LOW 0x00 #define SSD130X_PAGE_COL_START_HIGH 0x10 #define SSD130X_SET_ADDRESS_MODE 0x20 #define SSD130X_SET_COL_RANGE 0x21 #define SSD130X_SET_PAGE_RANGE 0x22 -#define SSD130X_CONTRAST 0x81 #define SSD130X_SET_LOOKUP_TABLE 0x91 #define SSD130X_CHARGE_PUMP 0x8d -#define SSD130X_SET_SEG_REMAP 0xa0 -#define SSD130X_DISPLAY_OFF 0xae -#define SSD130X_SET_MULTIPLEX_RATIO 0xa8 -#define SSD130X_DISPLAY_ON 0xaf #define SSD130X_START_PAGE_ADDRESS 0xb0 #define SSD130X_SET_COM_SCAN_DIR 0xc0 #define SSD130X_SET_DISPLAY_OFFSET 0xd3 @@ -65,13 +71,12 @@ #define SSD130X_SET_COM_PINS_CONFIG 0xda #define SSD130X_SET_VCOMH 0xdb +/* ssd130x commands accessors */ #define SSD130X_PAGE_COL_START_MASK GENMASK(3, 0) #define SSD130X_PAGE_COL_START_HIGH_SET(val) FIELD_PREP(SSD130X_PAGE_COL_START_MASK, (val) >> 4) #define SSD130X_PAGE_COL_START_LOW_SET(val) FIELD_PREP(SSD130X_PAGE_COL_START_MASK, (val)) #define SSD130X_START_PAGE_ADDRESS_MASK GENMASK(2, 0) #define SSD130X_START_PAGE_ADDRESS_SET(val) FIELD_PREP(SSD130X_START_PAGE_ADDRESS_MASK, (val)) -#define SSD130X_SET_SEG_REMAP_MASK GENMASK(0, 0) -#define SSD130X_SET_SEG_REMAP_SET(val) FIELD_PREP(SSD130X_SET_SEG_REMAP_MASK, (val)) #define SSD130X_SET_COM_SCAN_DIR_MASK GENMASK(3, 3) #define SSD130X_SET_COM_SCAN_DIR_SET(val) FIELD_PREP(SSD130X_SET_COM_SCAN_DIR_MASK, (val)) #define SSD130X_SET_CLOCK_DIV_MASK GENMASK(3, 0) @@ -171,20 +176,20 @@ static inline struct ssd130x_device *drm_to_ssd130x(struct drm_device *drm) } /* - * Helper to write data (SSD130X_DATA) to the device. + * Helper to write data (SSD13XX_DATA) to the device. */ static int ssd130x_write_data(struct ssd130x_device *ssd130x, u8 *values, int count) { - return regmap_bulk_write(ssd130x->regmap, SSD130X_DATA, values, count); + return regmap_bulk_write(ssd130x->regmap, SSD13XX_DATA, values, count); } /* - * Helper to write command (SSD130X_COMMAND). The fist variadic argument + * Helper to write command (SSD13XX_COMMAND). The fist variadic argument * is the command to write and the following are the command options. * - * Note that the ssd130x protocol requires each command and option to be - * written as a SSD130X_COMMAND device register value. That is why a call - * to regmap_write(..., SSD130X_COMMAND, ...) is done for each argument. + * Note that the ssd13xx protocol requires each command and option to be + * written as a SSD13XX_COMMAND device register value. That is why a call + * to regmap_write(..., SSD13XX_COMMAND, ...) is done for each argument. */ static int ssd130x_write_cmd(struct ssd130x_device *ssd130x, int count, /* u8 cmd, u8 option, ... */...) @@ -197,7 +202,7 @@ static int ssd130x_write_cmd(struct ssd130x_device *ssd130x, int count, do { value = va_arg(ap, int); - ret = regmap_write(ssd130x->regmap, SSD130X_COMMAND, value); + ret = regmap_write(ssd130x->regmap, SSD13XX_COMMAND, value); if (ret) goto out_end; } while (--count); @@ -341,13 +346,13 @@ static int ssd130x_init(struct ssd130x_device *ssd130x) int ret; /* Set initial contrast */ - ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_CONTRAST, ssd130x->contrast); + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_CONTRAST, ssd130x->contrast); if (ret < 0) return ret; /* Set segment re-map */ - seg_remap = (SSD130X_SET_SEG_REMAP | - SSD130X_SET_SEG_REMAP_SET(ssd130x->seg_remap)); + seg_remap = (SSD13XX_SET_SEG_REMAP | + SSD13XX_SET_SEG_REMAP_SET(ssd130x->seg_remap)); ret = ssd130x_write_cmd(ssd130x, 1, seg_remap); if (ret < 0) return ret; @@ -360,7 +365,7 @@ static int ssd130x_init(struct ssd130x_device *ssd130x) return ret; /* Set multiplex ratio value */ - ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_MULTIPLEX_RATIO, ssd130x->height - 1); + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1); if (ret < 0) return ret; @@ -915,7 +920,7 @@ static void ssd130x_encoder_atomic_enable(struct drm_encoder *encoder, if (ret) goto power_off; - ssd130x_write_cmd(ssd130x, 1, SSD130X_DISPLAY_ON); + ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON); backlight_enable(ssd130x->bl_dev); @@ -934,7 +939,7 @@ static void ssd130x_encoder_atomic_disable(struct drm_encoder *encoder, backlight_disable(ssd130x->bl_dev); - ssd130x_write_cmd(ssd130x, 1, SSD130X_DISPLAY_OFF); + ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_OFF); ssd130x_power_off(ssd130x); } @@ -1010,7 +1015,7 @@ static int ssd130x_update_bl(struct backlight_device *bdev) ssd130x->contrast = brightness; - ret = ssd130x_write_cmd(ssd130x, 1, SSD130X_CONTRAST); + ret = ssd130x_write_cmd(ssd130x, 1, SSD13XX_CONTRAST); if (ret < 0) return ret; diff --git a/drivers/gpu/drm/solomon/ssd130x.h b/drivers/gpu/drm/solomon/ssd130x.h index c562c2d00c16..a5a25e054d2f 100644 --- a/drivers/gpu/drm/solomon/ssd130x.h +++ b/drivers/gpu/drm/solomon/ssd130x.h @@ -21,8 +21,8 @@ #include -#define SSD130X_DATA 0x40 -#define SSD130X_COMMAND 0x80 +#define SSD13XX_DATA 0x40 +#define SSD13XX_COMMAND 0x80 enum ssd130x_family_ids { SSD130X_FAMILY -- cgit v1.2.3 From fdd591e00a9c9d64a5f1d74779b72218c22bf15d Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 14 Oct 2023 09:15:06 +0200 Subject: drm/ssd130x: Add support for the SSD132x OLED controller family The Solomon SSD132x controllers (such as the SSD1322, SSD1325 and SSD1327) are used by 16 grayscale dot matrix OLED panels, extend the driver to also support this chip family. Instead adding an indirection level to allow the same modesetting pipeline to be used by both controller families, add another pipeline for SSD132x. This leads to some code duplication but it makes the driver easier to read and reason about. Once other controller families are added (e.g: SSD133x), some common code can be factored out in driver helpers to be shared by the different families. But that can be done later once these patterns emerge. Signed-off-by: Javier Martinez Canillas Acked-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20231014071520.1342189-5-javierm@redhat.com --- drivers/gpu/drm/solomon/Kconfig | 12 +- drivers/gpu/drm/solomon/ssd130x-i2c.c | 17 +- drivers/gpu/drm/solomon/ssd130x-spi.c | 21 +- drivers/gpu/drm/solomon/ssd130x.c | 419 ++++++++++++++++++++++++++++++++-- drivers/gpu/drm/solomon/ssd130x.h | 7 +- 5 files changed, 449 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/solomon/Kconfig b/drivers/gpu/drm/solomon/Kconfig index e170716d976b..c3ee956c2bb9 100644 --- a/drivers/gpu/drm/solomon/Kconfig +++ b/drivers/gpu/drm/solomon/Kconfig @@ -1,31 +1,31 @@ config DRM_SSD130X - tristate "DRM support for Solomon SSD130x OLED displays" + tristate "DRM support for Solomon SSD13xx OLED displays" depends on DRM && MMU select BACKLIGHT_CLASS_DEVICE select DRM_GEM_SHMEM_HELPER select DRM_KMS_HELPER help - DRM driver for the SSD130x Solomon and SINO WEALTH SH110x OLED + DRM driver for the SSD13xx Solomon and SINO WEALTH SH110x OLED controllers. This is only for the core driver, a driver for the appropriate bus transport in your chip also must be selected. If M is selected the module will be called ssd130x. config DRM_SSD130X_I2C - tristate "DRM support for Solomon SSD130x OLED displays (I2C bus)" + tristate "DRM support for Solomon SSD13xx OLED displays (I2C bus)" depends on DRM_SSD130X && I2C select REGMAP_I2C help - Say Y here if the SSD130x or SH110x OLED display is connected via + Say Y here if the SSD13xx or SH110x OLED display is connected via I2C bus. If M is selected the module will be called ssd130x-i2c. config DRM_SSD130X_SPI - tristate "DRM support for Solomon SSD130X OLED displays (SPI bus)" + tristate "DRM support for Solomon SSD13xx OLED displays (SPI bus)" depends on DRM_SSD130X && SPI select REGMAP help - Say Y here if the SSD130x OLED display is connected via SPI bus. + Say Y here if the SSD13xx OLED display is connected via SPI bus. If M is selected the module will be called ssd130x-spi. diff --git a/drivers/gpu/drm/solomon/ssd130x-i2c.c b/drivers/gpu/drm/solomon/ssd130x-i2c.c index 8f89b89d553f..f2ccab9c06d9 100644 --- a/drivers/gpu/drm/solomon/ssd130x-i2c.c +++ b/drivers/gpu/drm/solomon/ssd130x-i2c.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * DRM driver for Solomon SSD130x OLED displays (I2C bus) + * DRM driver for Solomon SSD13xx OLED displays (I2C bus) * * Copyright 2022 Red Hat Inc. * Author: Javier Martinez Canillas @@ -14,7 +14,7 @@ #include "ssd130x.h" #define DRIVER_NAME "ssd130x-i2c" -#define DRIVER_DESC "DRM driver for Solomon SSD130x OLED displays (I2C)" +#define DRIVER_DESC "DRM driver for Solomon SSD13xx OLED displays (I2C)" static const struct regmap_config ssd130x_i2c_regmap_config = { .reg_bits = 8, @@ -92,6 +92,19 @@ static const struct of_device_id ssd130x_of_match[] = { .compatible = "solomon,ssd1309fb-i2c", .data = &ssd130x_variants[SSD1309_ID], }, + /* ssd132x family */ + { + .compatible = "solomon,ssd1322", + .data = &ssd130x_variants[SSD1322_ID], + }, + { + .compatible = "solomon,ssd1325", + .data = &ssd130x_variants[SSD1325_ID], + }, + { + .compatible = "solomon,ssd1327", + .data = &ssd130x_variants[SSD1327_ID], + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ssd130x_of_match); diff --git a/drivers/gpu/drm/solomon/ssd130x-spi.c b/drivers/gpu/drm/solomon/ssd130x-spi.c index 89989da705d7..84e035a7ab3f 100644 --- a/drivers/gpu/drm/solomon/ssd130x-spi.c +++ b/drivers/gpu/drm/solomon/ssd130x-spi.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * DRM driver for Solomon SSD130X OLED displays (SPI bus) + * DRM driver for Solomon SSD13xx OLED displays (SPI bus) * * Copyright 2022 Red Hat Inc. * Authors: Javier Martinez Canillas @@ -11,7 +11,7 @@ #include "ssd130x.h" #define DRIVER_NAME "ssd130x-spi" -#define DRIVER_DESC "DRM driver for Solomon SSD130X OLED displays (SPI)" +#define DRIVER_DESC "DRM driver for Solomon SSD13xx OLED displays (SPI)" struct ssd130x_spi_transport { struct spi_device *spi; @@ -129,6 +129,19 @@ static const struct of_device_id ssd130x_of_match[] = { .compatible = "solomon,ssd1309", .data = &ssd130x_variants[SSD1309_ID], }, + /* ssd132x family */ + { + .compatible = "solomon,ssd1322", + .data = &ssd130x_variants[SSD1322_ID], + }, + { + .compatible = "solomon,ssd1325", + .data = &ssd130x_variants[SSD1325_ID], + }, + { + .compatible = "solomon,ssd1327", + .data = &ssd130x_variants[SSD1327_ID], + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, ssd130x_of_match); @@ -149,6 +162,10 @@ static const struct spi_device_id ssd130x_spi_table[] = { { "ssd1306", SSD1306_ID }, { "ssd1307", SSD1307_ID }, { "ssd1309", SSD1309_ID }, + /* ssd132x family */ + { "ssd1322", SSD1322_ID }, + { "ssd1325", SSD1325_ID }, + { "ssd1327", SSD1327_ID }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(spi, ssd130x_spi_table); diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index e11f16bf795e..32f0857aec9f 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * DRM driver for Solomon SSD130x OLED displays + * DRM driver for Solomon SSD13xx OLED displays * * Copyright 2022 Red Hat Inc. * Author: Javier Martinez Canillas @@ -37,13 +37,15 @@ #include "ssd130x.h" #define DRIVER_NAME "ssd130x" -#define DRIVER_DESC "DRM driver for Solomon SSD130x OLED displays" +#define DRIVER_DESC "DRM driver for Solomon SSD13xx OLED displays" #define DRIVER_DATE "20220131" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 #define SSD130X_PAGE_HEIGHT 8 +#define SSD132X_SEGMENT_WIDTH 2 + /* ssd13xx commands */ #define SSD13XX_CONTRAST 0x81 #define SSD13XX_SET_SEG_REMAP 0xa0 @@ -99,6 +101,24 @@ #define SSD130X_SET_AREA_COLOR_MODE_ENABLE 0x1e #define SSD130X_SET_AREA_COLOR_MODE_LOW_POWER 0x05 +/* ssd132x commands */ +#define SSD132X_SET_COL_RANGE 0x15 +#define SSD132X_SET_DEACTIVATE_SCROLL 0x2e +#define SSD132X_SET_ROW_RANGE 0x75 +#define SSD132X_SET_DISPLAY_START 0xa1 +#define SSD132X_SET_DISPLAY_OFFSET 0xa2 +#define SSD132X_SET_DISPLAY_NORMAL 0xa4 +#define SSD132X_SET_FUNCTION_SELECT_A 0xab +#define SSD132X_SET_PHASE_LENGTH 0xb1 +#define SSD132X_SET_CLOCK_FREQ 0xb3 +#define SSD132X_SET_GPIO 0xb5 +#define SSD132X_SET_PRECHARGE_PERIOD 0xb6 +#define SSD132X_SET_GRAY_SCALE_TABLE 0xb8 +#define SSD132X_SELECT_DEFAULT_TABLE 0xb9 +#define SSD132X_SET_PRECHARGE_VOLTAGE 0xbc +#define SSD130X_SET_VCOMH_VOLTAGE 0xbe +#define SSD132X_SET_FUNCTION_SELECT_B 0xd5 + #define MAX_CONTRAST 255 const struct ssd130x_deviceinfo ssd130x_variants[] = { @@ -144,6 +164,22 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .default_width = 128, .default_height = 64, .family_id = SSD130X_FAMILY, + }, + /* ssd132x family */ + [SSD1322_ID] = { + .default_width = 480, + .default_height = 128, + .family_id = SSD132X_FAMILY, + }, + [SSD1325_ID] = { + .default_width = 128, + .default_height = 80, + .family_id = SSD132X_FAMILY, + }, + [SSD1327_ID] = { + .default_width = 128, + .default_height = 128, + .family_id = SSD132X_FAMILY, } }; EXPORT_SYMBOL_NS_GPL(ssd130x_variants, DRM_SSD130X); @@ -463,6 +499,96 @@ static int ssd130x_init(struct ssd130x_device *ssd130x) SSD130X_SET_ADDRESS_MODE_HORIZONTAL); } +static int ssd132x_init(struct ssd130x_device *ssd130x) +{ + int ret; + + /* Set initial contrast */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_CONTRAST, 0x80); + if (ret < 0) + return ret; + + /* Set column start and end */ + ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, 0x00, + ssd130x->width / SSD132X_SEGMENT_WIDTH - 1); + if (ret < 0) + return ret; + + /* Set row start and end */ + ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, 0x00, ssd130x->height - 1); + if (ret < 0) + return ret; + /* + * Horizontal Address Increment + * Re-map for Column Address, Nibble and COM + * COM Split Odd Even + */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_SEG_REMAP, 0x53); + if (ret < 0) + return ret; + + /* Set display start and offset */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_DISPLAY_START, 0x00); + if (ret < 0) + return ret; + + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_DISPLAY_OFFSET, 0x00); + if (ret < 0) + return ret; + + /* Set display mode normal */ + ret = ssd130x_write_cmd(ssd130x, 1, SSD132X_SET_DISPLAY_NORMAL); + if (ret < 0) + return ret; + + /* Set multiplex ratio value */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1); + if (ret < 0) + return ret; + + /* Set phase length */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PHASE_LENGTH, 0x55); + if (ret < 0) + return ret; + + /* Select default linear gray scale table */ + ret = ssd130x_write_cmd(ssd130x, 1, SSD132X_SELECT_DEFAULT_TABLE); + if (ret < 0) + return ret; + + /* Set clock frequency */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_CLOCK_FREQ, 0x01); + if (ret < 0) + return ret; + + /* Enable internal VDD regulator */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_FUNCTION_SELECT_A, 0x1); + if (ret < 0) + return ret; + + /* Set pre-charge period */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_PERIOD, 0x01); + if (ret < 0) + return ret; + + /* Set pre-charge voltage */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_VOLTAGE, 0x08); + if (ret < 0) + return ret; + + /* Set VCOMH voltage */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_VCOMH_VOLTAGE, 0x07); + if (ret < 0) + return ret; + + /* Enable second pre-charge and internal VSL */ + ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_FUNCTION_SELECT_B, 0x62); + if (ret < 0) + return ret; + + return 0; +} + static int ssd130x_update_rect(struct ssd130x_device *ssd130x, struct drm_rect *rect, u8 *buf, u8 *data_array) @@ -569,6 +695,64 @@ static int ssd130x_update_rect(struct ssd130x_device *ssd130x, return ret; } +static int ssd132x_update_rect(struct ssd130x_device *ssd130x, + struct drm_rect *rect, u8 *buf, + u8 *data_array) +{ + unsigned int x = rect->x1; + unsigned int y = rect->y1; + unsigned int segment_width = SSD132X_SEGMENT_WIDTH; + unsigned int width = drm_rect_width(rect); + unsigned int height = drm_rect_height(rect); + unsigned int columns = DIV_ROUND_UP(width, segment_width); + unsigned int rows = height; + struct drm_device *drm = &ssd130x->drm; + u32 array_idx = 0; + unsigned int i, j; + int ret; + + drm_WARN_ONCE(drm, x % segment_width != 0, "x must be aligned to screen segment\n"); + + /* + * The screen is divided in Segment and Common outputs, where + * COM0 to COM[N - 1] are the rows and SEG0 to SEG[M - 1] are + * the columns. + * + * Each Segment has a 4-bit pixel and each Common output has a + * row of pixels. When using the (default) horizontal address + * increment mode, each byte of data sent to the controller has + * two Segments (e.g: SEG0 and SEG1) that are stored in the lower + * and higher nibbles of a single byte representing one column. + * That is, the first byte are SEG0 (D0[3:0]) and SEG1 (D0[7:4]), + * the second byte are SEG2 (D1[3:0]) and SEG3 (D1[7:4]) and so on. + */ + + /* Set column start and end */ + ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, x / segment_width, columns - 1); + if (ret < 0) + return ret; + + /* Set row start and end */ + ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, y, rows - 1); + if (ret < 0) + return ret; + + for (i = 0; i < height; i++) { + /* Process pair of pixels and combine them into a single byte */ + for (j = 0; j < width; j += segment_width) { + u8 n1 = buf[i * width + j]; + u8 n2 = buf[i * width + j + 1]; + + data_array[array_idx++] = (n2 << 4) | n1; + } + } + + /* Write out update in one go since horizontal addressing mode is used */ + ret = ssd130x_write_data(ssd130x, data_array, columns * rows); + + return ret; +} + static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array) { unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT); @@ -610,6 +794,17 @@ static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array) } } +static void ssd132x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array) +{ + unsigned int columns = DIV_ROUND_UP(ssd130x->height, SSD132X_SEGMENT_WIDTH); + unsigned int height = ssd130x->height; + + memset(data_array, 0, columns * height); + + /* Write out update in one go since horizontal addressing mode is used */ + ssd130x_write_data(ssd130x, data_array, columns * height); +} + static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, const struct iosys_map *vmap, struct drm_rect *rect, @@ -640,6 +835,35 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, return ret; } +static int ssd132x_fb_blit_rect(struct drm_framebuffer *fb, + const struct iosys_map *vmap, + struct drm_rect *rect, u8 *buf, + u8 *data_array) +{ + struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev); + unsigned int dst_pitch = drm_rect_width(rect); + struct iosys_map dst; + int ret = 0; + + /* Align x to display segment boundaries */ + rect->x1 = round_down(rect->x1, SSD132X_SEGMENT_WIDTH); + rect->x2 = min_t(unsigned int, round_up(rect->x2, SSD132X_SEGMENT_WIDTH), + ssd130x->width); + + ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); + if (ret) + return ret; + + iosys_map_set_vaddr(&dst, buf); + drm_fb_xrgb8888_to_gray8(&dst, &dst_pitch, vmap, fb, rect); + + drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); + + ssd132x_update_rect(ssd130x, rect, buf, data_array); + + return ret; +} + static int ssd130x_primary_plane_atomic_check(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -678,6 +902,44 @@ static int ssd130x_primary_plane_atomic_check(struct drm_plane *plane, return 0; } +static int ssd132x_primary_plane_atomic_check(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_device *drm = plane->dev; + struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state); + struct drm_crtc *crtc = plane_state->crtc; + struct drm_crtc_state *crtc_state; + const struct drm_format_info *fi; + unsigned int pitch; + int ret; + + if (crtc) + crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + + ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state, + DRM_PLANE_NO_SCALING, + DRM_PLANE_NO_SCALING, + false, false); + if (ret) + return ret; + else if (!plane_state->visible) + return 0; + + fi = drm_format_info(DRM_FORMAT_R8); + if (!fi) + return -EINVAL; + + pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width); + + ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL); + if (!ssd130x_state->buffer) + return -ENOMEM; + + return 0; +} + static void ssd130x_primary_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -712,6 +974,40 @@ static void ssd130x_primary_plane_atomic_update(struct drm_plane *plane, drm_dev_exit(idx); } +static void ssd132x_primary_plane_atomic_update(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane); + struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state); + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc); + struct ssd130x_crtc_state *ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state); + struct ssd130x_plane_state *ssd130x_plane_state = to_ssd130x_plane_state(plane_state); + struct drm_framebuffer *fb = plane_state->fb; + struct drm_atomic_helper_damage_iter iter; + struct drm_device *drm = plane->dev; + struct drm_rect dst_clip; + struct drm_rect damage; + int idx; + + if (!drm_dev_enter(drm, &idx)) + return; + + drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); + drm_atomic_for_each_plane_damage(&iter, &damage) { + dst_clip = plane_state->dst; + + if (!drm_rect_intersect(&dst_clip, &damage)) + continue; + + ssd132x_fb_blit_rect(fb, &shadow_plane_state->data[0], &dst_clip, + ssd130x_plane_state->buffer, + ssd130x_crtc_state->data_array); + } + + drm_dev_exit(idx); +} + static void ssd130x_primary_plane_atomic_disable(struct drm_plane *plane, struct drm_atomic_state *state) { @@ -736,6 +1032,30 @@ static void ssd130x_primary_plane_atomic_disable(struct drm_plane *plane, drm_dev_exit(idx); } +static void ssd132x_primary_plane_atomic_disable(struct drm_plane *plane, + struct drm_atomic_state *state) +{ + struct drm_device *drm = plane->dev; + struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); + struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane); + struct drm_crtc_state *crtc_state; + struct ssd130x_crtc_state *ssd130x_crtc_state; + int idx; + + if (!plane_state->crtc) + return; + + crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc); + ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state); + + if (!drm_dev_enter(drm, &idx)) + return; + + ssd132x_clear_screen(ssd130x, ssd130x_crtc_state->data_array); + + drm_dev_exit(idx); +} + /* Called during init to allocate the plane's atomic state. */ static void ssd130x_primary_plane_reset(struct drm_plane *plane) { @@ -786,11 +1106,19 @@ static void ssd130x_primary_plane_destroy_state(struct drm_plane *plane, kfree(ssd130x_state); } -static const struct drm_plane_helper_funcs ssd130x_primary_plane_helper_funcs = { - DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, - .atomic_check = ssd130x_primary_plane_atomic_check, - .atomic_update = ssd130x_primary_plane_atomic_update, - .atomic_disable = ssd130x_primary_plane_atomic_disable, +static const struct drm_plane_helper_funcs ssd130x_primary_plane_helper_funcs[] = { + [SSD130X_FAMILY] = { + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, + .atomic_check = ssd130x_primary_plane_atomic_check, + .atomic_update = ssd130x_primary_plane_atomic_update, + .atomic_disable = ssd130x_primary_plane_atomic_disable, + }, + [SSD132X_FAMILY] = { + DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, + .atomic_check = ssd132x_primary_plane_atomic_check, + .atomic_update = ssd132x_primary_plane_atomic_update, + .atomic_disable = ssd132x_primary_plane_atomic_disable, + } }; static const struct drm_plane_funcs ssd130x_primary_plane_funcs = { @@ -839,6 +1167,27 @@ static int ssd130x_crtc_atomic_check(struct drm_crtc *crtc, return 0; } +static int ssd132x_crtc_atomic_check(struct drm_crtc *crtc, + struct drm_atomic_state *state) +{ + struct drm_device *drm = crtc->dev; + struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); + struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); + struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state); + unsigned int columns = DIV_ROUND_UP(ssd130x->width, SSD132X_SEGMENT_WIDTH); + int ret; + + ret = drm_crtc_helper_atomic_check(crtc, state); + if (ret) + return ret; + + ssd130x_state->data_array = kmalloc(columns * ssd130x->height, GFP_KERNEL); + if (!ssd130x_state->data_array) + return -ENOMEM; + + return 0; +} + /* Called during init to allocate the CRTC's atomic state. */ static void ssd130x_crtc_reset(struct drm_crtc *crtc) { @@ -891,9 +1240,15 @@ static void ssd130x_crtc_destroy_state(struct drm_crtc *crtc, * the primary plane's atomic_update function. Disabling clears * the screen in the primary plane's atomic_disable function. */ -static const struct drm_crtc_helper_funcs ssd130x_crtc_helper_funcs = { - .mode_valid = ssd130x_crtc_mode_valid, - .atomic_check = ssd130x_crtc_atomic_check, +static const struct drm_crtc_helper_funcs ssd130x_crtc_helper_funcs[] = { + [SSD130X_FAMILY] = { + .mode_valid = ssd130x_crtc_mode_valid, + .atomic_check = ssd130x_crtc_atomic_check, + }, + [SSD132X_FAMILY] = { + .mode_valid = ssd130x_crtc_mode_valid, + .atomic_check = ssd132x_crtc_atomic_check, + }, }; static const struct drm_crtc_funcs ssd130x_crtc_funcs = { @@ -931,6 +1286,31 @@ power_off: return; } +static void ssd132x_encoder_atomic_enable(struct drm_encoder *encoder, + struct drm_atomic_state *state) +{ + struct drm_device *drm = encoder->dev; + struct ssd130x_device *ssd130x = drm_to_ssd130x(drm); + int ret; + + ret = ssd130x_power_on(ssd130x); + if (ret) + return; + + ret = ssd132x_init(ssd130x); + if (ret) + goto power_off; + + ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON); + + backlight_enable(ssd130x->bl_dev); + + return; + +power_off: + ssd130x_power_off(ssd130x); +} + static void ssd130x_encoder_atomic_disable(struct drm_encoder *encoder, struct drm_atomic_state *state) { @@ -944,9 +1324,15 @@ static void ssd130x_encoder_atomic_disable(struct drm_encoder *encoder, ssd130x_power_off(ssd130x); } -static const struct drm_encoder_helper_funcs ssd130x_encoder_helper_funcs = { - .atomic_enable = ssd130x_encoder_atomic_enable, - .atomic_disable = ssd130x_encoder_atomic_disable, +static const struct drm_encoder_helper_funcs ssd130x_encoder_helper_funcs[] = { + [SSD130X_FAMILY] = { + .atomic_enable = ssd130x_encoder_atomic_enable, + .atomic_disable = ssd130x_encoder_atomic_disable, + }, + [SSD132X_FAMILY] = { + .atomic_enable = ssd132x_encoder_atomic_enable, + .atomic_disable = ssd130x_encoder_atomic_disable, + } }; static const struct drm_encoder_funcs ssd130x_encoder_funcs = { @@ -1080,6 +1466,7 @@ static void ssd130x_parse_properties(struct ssd130x_device *ssd130x) static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) { + enum ssd130x_family_ids family_id = ssd130x->device_info->family_id; struct drm_display_mode *mode = &ssd130x->mode; struct device *dev = ssd130x->dev; struct drm_device *drm = &ssd130x->drm; @@ -1130,7 +1517,7 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) return ret; } - drm_plane_helper_add(primary_plane, &ssd130x_primary_plane_helper_funcs); + drm_plane_helper_add(primary_plane, &ssd130x_primary_plane_helper_funcs[family_id]); drm_plane_enable_fb_damage_clips(primary_plane); @@ -1144,7 +1531,7 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) return ret; } - drm_crtc_helper_add(crtc, &ssd130x_crtc_helper_funcs); + drm_crtc_helper_add(crtc, &ssd130x_crtc_helper_funcs[family_id]); /* Encoder */ @@ -1156,7 +1543,7 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) return ret; } - drm_encoder_helper_add(encoder, &ssd130x_encoder_helper_funcs); + drm_encoder_helper_add(encoder, &ssd130x_encoder_helper_funcs[family_id]); encoder->possible_crtcs = drm_crtc_mask(crtc); diff --git a/drivers/gpu/drm/solomon/ssd130x.h b/drivers/gpu/drm/solomon/ssd130x.h index a5a25e054d2f..acf7cedf0c1a 100644 --- a/drivers/gpu/drm/solomon/ssd130x.h +++ b/drivers/gpu/drm/solomon/ssd130x.h @@ -25,7 +25,8 @@ #define SSD13XX_COMMAND 0x80 enum ssd130x_family_ids { - SSD130X_FAMILY + SSD130X_FAMILY, + SSD132X_FAMILY }; enum ssd130x_variants { @@ -35,6 +36,10 @@ enum ssd130x_variants { SSD1306_ID, SSD1307_ID, SSD1309_ID, + /* ssd132x family */ + SSD1322_ID, + SSD1325_ID, + SSD1327_ID, NR_SSD130X_VARIANTS }; -- cgit v1.2.3 From 7618b8659438c42baabb5678b2519abde4b4352a Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 14 Oct 2023 09:15:07 +0200 Subject: dt-bindings: display: Split common Solomon properties in their own schema There are DT properties that can be shared across different Solomon OLED Display Controller families. Split them into a separate common schema to avoid these properties to be duplicated in different DT bindings schemas. Suggested-by: Rob Herring Signed-off-by: Javier Martinez Canillas Reviewed-by: Rob Herring Acked-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20231014071520.1342189-6-javierm@redhat.com --- .../bindings/display/solomon,ssd-common.yaml | 42 ++++++++++++++++++++++ .../bindings/display/solomon,ssd1307fb.yaml | 28 +-------------- MAINTAINERS | 1 + 3 files changed, 44 insertions(+), 27 deletions(-) create mode 100644 Documentation/devicetree/bindings/display/solomon,ssd-common.yaml diff --git a/Documentation/devicetree/bindings/display/solomon,ssd-common.yaml b/Documentation/devicetree/bindings/display/solomon,ssd-common.yaml new file mode 100644 index 000000000000..3e6998481a75 --- /dev/null +++ b/Documentation/devicetree/bindings/display/solomon,ssd-common.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,ssd-common.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Common properties for Solomon OLED Display Controllers + +maintainers: + - Javier Martinez Canillas + +properties: + reg: + maxItems: 1 + + reset-gpios: + maxItems: 1 + + # Only required for SPI + dc-gpios: + description: + GPIO connected to the controller's D/C# (Data/Command) pin, + that is needed for 4-wire SPI to tell the controller if the + data sent is for a command register or the display data RAM + maxItems: 1 + + solomon,height: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Height in pixel of the screen driven by the controller. + The default value is controller-dependent. + + solomon,width: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Width in pixel of the screen driven by the controller. + The default value is controller-dependent. + +allOf: + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +additionalProperties: true diff --git a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml index 20e2bd15d4d2..3afbb52d1b7f 100644 --- a/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml +++ b/Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml @@ -27,38 +27,12 @@ properties: - solomon,ssd1307 - solomon,ssd1309 - reg: - maxItems: 1 - pwms: maxItems: 1 - reset-gpios: - maxItems: 1 - - # Only required for SPI - dc-gpios: - description: - GPIO connected to the controller's D/C# (Data/Command) pin, - that is needed for 4-wire SPI to tell the controller if the - data sent is for a command register or the display data RAM - maxItems: 1 - vbat-supply: description: The supply for VBAT - solomon,height: - $ref: /schemas/types.yaml#/definitions/uint32 - description: - Height in pixel of the screen driven by the controller. - The default value is controller-dependent. - - solomon,width: - $ref: /schemas/types.yaml#/definitions/uint32 - description: - Width in pixel of the screen driven by the controller. - The default value is controller-dependent. - solomon,page-offset: $ref: /schemas/types.yaml#/definitions/uint32 default: 1 @@ -148,7 +122,7 @@ required: - reg allOf: - - $ref: /schemas/spi/spi-peripheral-props.yaml# + - $ref: solomon,ssd-common.yaml# - if: properties: diff --git a/MAINTAINERS b/MAINTAINERS index 987152e3be02..c63649e9ba58 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6765,6 +6765,7 @@ DRM DRIVER FOR SOLOMON SSD130X OLED DISPLAYS M: Javier Martinez Canillas S: Maintained T: git git://anongit.freedesktop.org/drm/drm-misc +F: Documentation/devicetree/bindings/display/solomon,ssd-common.yaml F: Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml F: drivers/gpu/drm/solomon/ssd130x* -- cgit v1.2.3 From 2d23e7d6bacb779c4a740dbd5e18978fb075d15e Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Sat, 14 Oct 2023 09:15:08 +0200 Subject: dt-bindings: display: Add SSD132x OLED controllers Add a Device Tree binding schema for the OLED panels based on the Solomon SSD132x family of controllers. Signed-off-by: Javier Martinez Canillas Reviewed-by: Rob Herring Acked-by: Thomas Zimmermann Link: https://patchwork.freedesktop.org/patch/msgid/20231014071520.1342189-7-javierm@redhat.com --- .../bindings/display/solomon,ssd132x.yaml | 89 ++++++++++++++++++++++ MAINTAINERS | 2 +- 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/display/solomon,ssd132x.yaml diff --git a/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml b/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml new file mode 100644 index 000000000000..0aa41bd9ddca --- /dev/null +++ b/Documentation/devicetree/bindings/display/solomon,ssd132x.yaml @@ -0,0 +1,89 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/solomon,ssd132x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Solomon SSD132x OLED Display Controllers + +maintainers: + - Javier Martinez Canillas + +properties: + compatible: + - enum: + - solomon,ssd1322 + - solomon,ssd1325 + - solomon,ssd1327 + +required: + - compatible + - reg + +allOf: + - $ref: solomon,ssd-common.yaml# + + - if: + properties: + compatible: + contains: + const: solomon,ssd1322 + then: + properties: + width: + default: 480 + height: + default: 128 + + - if: + properties: + compatible: + contains: + const: solomon,ssd1325 + then: + properties: + width: + default: 128 + height: + default: 80 + + - if: + properties: + compatible: + contains: + const: solomon,ssd1327 + then: + properties: + width: + default: 128 + height: + default: 128 + +unevaluatedProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + oled@3c { + compatible = "solomon,ssd1327"; + reg = <0x3c>; + reset-gpios = <&gpio2 7>; + }; + + }; + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + oled@0 { + compatible = "solomon,ssd1327"; + reg = <0x0>; + reset-gpios = <&gpio2 7>; + dc-gpios = <&gpio2 8>; + spi-max-frequency = <10000000>; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index c63649e9ba58..4b518429458b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6766,7 +6766,7 @@ M: Javier Martinez Canillas S: Maintained T: git git://anongit.freedesktop.org/drm/drm-misc F: Documentation/devicetree/bindings/display/solomon,ssd-common.yaml -F: Documentation/devicetree/bindings/display/solomon,ssd1307fb.yaml +F: Documentation/devicetree/bindings/display/solomon,ssd13*.yaml F: drivers/gpu/drm/solomon/ssd130x* DRM DRIVER FOR ST-ERICSSON MCDE -- cgit v1.2.3 From 6b180f66c0dd6266eeb2f74b59ee79a9f14fe430 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:34 +0200 Subject: fbdev: Provide I/O-memory helpers as module Provide helpers for accessing I/O memory in a helper module. The fbdev core uses these helpers, so select the module unconditionally for fbdev. Drivers will later be able to select the module individually and the helpers will become optional. Signed-off-by: Thomas Zimmermann Reviewed-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-2-tzimmermann@suse.de --- drivers/video/fbdev/core/Kconfig | 6 ++++++ drivers/video/fbdev/core/Makefile | 3 ++- drivers/video/fbdev/core/fb_io_fops.c | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/core/Kconfig b/drivers/video/fbdev/core/Kconfig index e80d6429f76a..6017b7e54ede 100644 --- a/drivers/video/fbdev/core/Kconfig +++ b/drivers/video/fbdev/core/Kconfig @@ -4,6 +4,7 @@ # config FB_CORE + select FB_IOMEM_FOPS select VIDEO_CMDLINE tristate @@ -144,12 +145,17 @@ config FB_DMAMEM_HELPERS select FB_SYS_FOPS select FB_SYS_IMAGEBLIT +config FB_IOMEM_FOPS + tristate + depends on FB_CORE + config FB_IOMEM_HELPERS bool depends on FB_CORE select FB_CFB_COPYAREA select FB_CFB_FILLRECT select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS config FB_IOMEM_HELPERS_DEFERRED bool diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile index 36d3156dc759..c1d657601b2b 100644 --- a/drivers/video/fbdev/core/Makefile +++ b/drivers/video/fbdev/core/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_FB_NOTIFY) += fb_notify.o obj-$(CONFIG_FB_CORE) += fb.o fb-y := fb_info.o \ fbmem.o fbcmap.o \ - modedb.o fbcvt.o fb_cmdline.o fb_io_fops.o + modedb.o fbcvt.o fb_cmdline.o ifdef CONFIG_FB fb-y += fb_backlight.o fbmon.o endif @@ -28,6 +28,7 @@ fb-$(CONFIG_LOGO) += fb_logo.o obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o +obj-$(CONFIG_FB_IOMEM_FOPS) += fb_io_fops.o obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o diff --git a/drivers/video/fbdev/core/fb_io_fops.c b/drivers/video/fbdev/core/fb_io_fops.c index 5985e5e1b040..871b829521af 100644 --- a/drivers/video/fbdev/core/fb_io_fops.c +++ b/drivers/video/fbdev/core/fb_io_fops.c @@ -131,3 +131,6 @@ ssize_t fb_io_write(struct fb_info *info, const char __user *buf, size_t count, return (cnt) ? cnt : err; } EXPORT_SYMBOL(fb_io_write); + +MODULE_DESCRIPTION("Fbdev helpers for framebuffers in I/O memory"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 5a5015aaaac50b7ac9d2f97a98dc5c7a523d972f Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:35 +0200 Subject: fbdev/68328fb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-3-tzimmermann@suse.de --- drivers/video/fbdev/68328fb.c | 5 ++--- drivers/video/fbdev/Kconfig | 4 +--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/video/fbdev/68328fb.c b/drivers/video/fbdev/68328fb.c index 956dd2399cc0..c24156eb3d0f 100644 --- a/drivers/video/fbdev/68328fb.c +++ b/drivers/video/fbdev/68328fb.c @@ -95,13 +95,12 @@ static int mc68x328fb_mmap(struct fb_info *info, struct vm_area_struct *vma); static const struct fb_ops mc68x328fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = mc68x328fb_check_var, .fb_set_par = mc68x328fb_set_par, .fb_setcolreg = mc68x328fb_setcolreg, .fb_pan_display = mc68x328fb_pan_display, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_mmap = mc68x328fb_mmap, }; diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index e2a8d9bc0679..baba49e64982 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1541,9 +1541,7 @@ config FB_G364 config FB_68328 bool "Motorola 68328 native frame buffer support" depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS help Say Y here if you want to support the built-in frame buffer of the Motorola 68328 CPU family. -- cgit v1.2.3 From b910005c98a81cb69a7479f577005a329f08bccd Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:36 +0200 Subject: fbdev/amba-clcd: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-4-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 4 +--- drivers/video/fbdev/amba-clcd.c | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index baba49e64982..73c973ea59e6 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -118,9 +118,7 @@ config FB_ARMCLCD tristate "ARM PrimeCell PL110 support" depends on ARM || ARM64 || COMPILE_TEST depends on FB && ARM_AMBA && HAS_IOMEM - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS select FB_MODE_HELPERS if OF select VIDEOMODE_HELPERS if OF select BACKLIGHT_CLASS_DEVICE if OF diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index 24d89e6fb780..0399db369e70 100644 --- a/drivers/video/fbdev/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c @@ -412,13 +412,12 @@ static int clcdfb_mmap(struct fb_info *info, static const struct fb_ops clcdfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = clcdfb_check_var, .fb_set_par = clcdfb_set_par, .fb_setcolreg = clcdfb_setcolreg, .fb_blank = clcdfb_blank, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_mmap = clcdfb_mmap, }; -- cgit v1.2.3 From 48c3734d416ec1c729cb9d81631ae5c325413e93 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:37 +0200 Subject: fbdev/amifb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-5-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/amifb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 73c973ea59e6..8ff31da533bf 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -225,6 +225,7 @@ config FB_Q40 config FB_AMIGA tristate "Amiga native chipset support" depends on FB && AMIGA + select FB_IOMEM_FOPS help This is the frame buffer device driver for the builtin graphics chipset found in Amigas. diff --git a/drivers/video/fbdev/amifb.c b/drivers/video/fbdev/amifb.c index 441e7a8dbe58..b18c6b4f129a 100644 --- a/drivers/video/fbdev/amifb.c +++ b/drivers/video/fbdev/amifb.c @@ -3488,6 +3488,7 @@ static irqreturn_t amifb_interrupt(int irq, void *dev_id) static const struct fb_ops amifb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = amifb_check_var, .fb_set_par = amifb_set_par, .fb_setcolreg = amifb_setcolreg, @@ -3497,6 +3498,7 @@ static const struct fb_ops amifb_ops = { .fb_copyarea = amifb_copyarea, .fb_imageblit = amifb_imageblit, .fb_ioctl = amifb_ioctl, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; -- cgit v1.2.3 From 7421a6303edc13cf3b54c465c6848bdd440e51b7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:38 +0200 Subject: fbdev/arkfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-6-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/arkfb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 8ff31da533bf..4be65024c614 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1381,6 +1381,7 @@ config FB_ARK select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select FB_TILEBLITTING select FB_SVGALIB select VGASTATE diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c index 60a96fdb5dd8..dca9c0325b3f 100644 --- a/drivers/video/fbdev/arkfb.c +++ b/drivers/video/fbdev/arkfb.c @@ -924,6 +924,7 @@ static const struct fb_ops arkfb_ops = { .owner = THIS_MODULE, .fb_open = arkfb_open, .fb_release = arkfb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = arkfb_check_var, .fb_set_par = arkfb_set_par, .fb_setcolreg = arkfb_setcolreg, @@ -932,6 +933,7 @@ static const struct fb_ops arkfb_ops = { .fb_fillrect = arkfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = arkfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, .fb_get_caps = svga_get_caps, }; -- cgit v1.2.3 From 425562be861b46ba8dac78e3927c1cbff5fbb514 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:39 +0200 Subject: fbdev/atafb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-7-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/atafb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 4be65024c614..6bc46f97a75a 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -289,6 +289,7 @@ config FB_ATARI select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS help This is the frame buffer device driver for the builtin graphics chipset found in Ataris. diff --git a/drivers/video/fbdev/atafb.c b/drivers/video/fbdev/atafb.c index c4a420b791b9..b8ed1c537293 100644 --- a/drivers/video/fbdev/atafb.c +++ b/drivers/video/fbdev/atafb.c @@ -2665,6 +2665,7 @@ static int atafb_set_par(struct fb_info *info) static struct fb_ops atafb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = atafb_check_var, .fb_set_par = atafb_set_par, .fb_blank = atafb_blank, @@ -2673,6 +2674,7 @@ static struct fb_ops atafb_ops = { .fb_copyarea = atafb_copyarea, .fb_imageblit = atafb_imageblit, .fb_ioctl = atafb_ioctl, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static void check_default_par(int detected_mode) -- cgit v1.2.3 From 94cab8f6b243981604d8f89f4ce03a58d604c936 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:40 +0200 Subject: fbdev/atyfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-8-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/aty/atyfb_base.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 6bc46f97a75a..568108dfcedb 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1086,6 +1086,7 @@ config FB_ATY select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_BACKLIGHT if FB_ATY_BACKLIGHT + select FB_IOMEM_FOPS select FB_MACMODES if PPC select FB_ATY_CT if SPARC64 && PCI select VIDEO_NOMODESET diff --git a/drivers/video/fbdev/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index 5c87817a4f4c..aee96fa45857 100644 --- a/drivers/video/fbdev/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -301,6 +301,7 @@ static struct fb_ops atyfb_ops = { .owner = THIS_MODULE, .fb_open = atyfb_open, .fb_release = atyfb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = atyfb_check_var, .fb_set_par = atyfb_set_par, .fb_setcolreg = atyfb_setcolreg, @@ -315,6 +316,8 @@ static struct fb_ops atyfb_ops = { .fb_imageblit = atyfb_imageblit, #ifdef __sparc__ .fb_mmap = atyfb_mmap, +#else + __FB_DEFAULT_IOMEM_OPS_MMAP, #endif .fb_sync = atyfb_sync, }; -- cgit v1.2.3 From 93ede59ccd9455412fdbc5cc813fc86162e21165 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:41 +0200 Subject: fbdev/au1100fb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-9-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 4 +--- drivers/video/fbdev/au1100fb.c | 8 +++----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 568108dfcedb..72b6cdfbe162 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1434,9 +1434,7 @@ endchoice config FB_AU1100 bool "Au1100 LCD Driver" depends on (FB = y) && MIPS_ALCHEMY - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS help This is the framebuffer driver for the AMD Au1100 SOC. It can drive various panels and CRTs by passing in kernel cmd line option diff --git a/drivers/video/fbdev/au1100fb.c b/drivers/video/fbdev/au1100fb.c index 648d6cac86e8..a9c8d33a6ef7 100644 --- a/drivers/video/fbdev/au1100fb.c +++ b/drivers/video/fbdev/au1100fb.c @@ -348,15 +348,13 @@ int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) fbdev->fb_len); } -static const struct fb_ops au1100fb_ops = -{ +static const struct fb_ops au1100fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_setcolreg = au1100fb_fb_setcolreg, .fb_blank = au1100fb_fb_blank, .fb_pan_display = au1100fb_fb_pan_display, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_mmap = au1100fb_fb_mmap, }; -- cgit v1.2.3 From 0296ddfe57c3d801d2a50aca4fec2066eaa2f652 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:42 +0200 Subject: fbdev/cirrusfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-10-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/cirrusfb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 72b6cdfbe162..43372e13b61f 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -74,6 +74,7 @@ config FB_CIRRUS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select VIDEO_NOMODESET help This enables support for Cirrus Logic GD542x/543x based boards on diff --git a/drivers/video/fbdev/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c index 9d369b6a4dcc..e29217e476ea 100644 --- a/drivers/video/fbdev/cirrusfb.c +++ b/drivers/video/fbdev/cirrusfb.c @@ -1961,6 +1961,7 @@ static const struct fb_ops cirrusfb_ops = { .owner = THIS_MODULE, .fb_open = cirrusfb_open, .fb_release = cirrusfb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_setcolreg = cirrusfb_setcolreg, .fb_check_var = cirrusfb_check_var, .fb_set_par = cirrusfb_set_par, @@ -1970,6 +1971,7 @@ static const struct fb_ops cirrusfb_ops = { .fb_copyarea = cirrusfb_copyarea, .fb_sync = cirrusfb_sync, .fb_imageblit = cirrusfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int cirrusfb_set_fbinfo(struct fb_info *info) -- cgit v1.2.3 From d47f9775c1a6d3200d99ff8e7ea90c81af502c96 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:43 +0200 Subject: fbdev/cobalt-lcd: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-11-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/cobalt_lcdfb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 43372e13b61f..b46a0665e4ca 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1752,6 +1752,7 @@ config FB_GOLDFISH config FB_COBALT tristate "Cobalt server LCD frame buffer support" depends on FB && MIPS_COBALT + select FB_IOMEM_HELPERS config FB_SH7760 bool "SH7760/SH7763/SH7720/SH7721 LCDC support" diff --git a/drivers/video/fbdev/cobalt_lcdfb.c b/drivers/video/fbdev/cobalt_lcdfb.c index b94e7c97264c..c2b8f894799c 100644 --- a/drivers/video/fbdev/cobalt_lcdfb.c +++ b/drivers/video/fbdev/cobalt_lcdfb.c @@ -280,7 +280,9 @@ static const struct fb_ops cobalt_lcd_fbops = { .fb_read = cobalt_lcdfb_read, .fb_write = cobalt_lcdfb_write, .fb_blank = cobalt_lcdfb_blank, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_cursor = cobalt_lcdfb_cursor, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int cobalt_lcdfb_probe(struct platform_device *dev) -- cgit v1.2.3 From 076b705df15ebbee0fe65502551c357b8e3117db Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:44 +0200 Subject: fbdev/controlfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-12-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 4 +--- drivers/video/fbdev/controlfb.c | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index b46a0665e4ca..3599064be66f 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -309,9 +309,7 @@ config FB_OF config FB_CONTROL bool "Apple \"control\" display support" depends on (FB = y) && ((PPC_PMAC && PPC32) || COMPILE_TEST) - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS select FB_MACMODES help This driver supports a frame buffer for the graphics adapter in the diff --git a/drivers/video/fbdev/controlfb.c b/drivers/video/fbdev/controlfb.c index 717134c141ff..5c5284e8ae0e 100644 --- a/drivers/video/fbdev/controlfb.c +++ b/drivers/video/fbdev/controlfb.c @@ -755,15 +755,14 @@ static int controlfb_mmap(struct fb_info *info, static const struct fb_ops controlfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = controlfb_check_var, .fb_set_par = controlfb_set_par, .fb_setcolreg = controlfb_setcolreg, .fb_pan_display = controlfb_pan_display, .fb_blank = controlfb_blank, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_mmap = controlfb_mmap, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, }; /* -- cgit v1.2.3 From d6583f5b78329274830b6e6ae4ed97f171269d25 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:45 +0200 Subject: fbdev/cyber2000fb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-13-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/cyber2000fb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 3599064be66f..43753f150b37 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -184,6 +184,7 @@ config FB_CYBER2000 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select VIDEO_NOMODESET help This enables support for the Integraphics CyberPro 20x0 and 5000 diff --git a/drivers/video/fbdev/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c index 98ea56a9abf1..52105dc1a72f 100644 --- a/drivers/video/fbdev/cyber2000fb.c +++ b/drivers/video/fbdev/cyber2000fb.c @@ -1061,6 +1061,7 @@ static int cyber2000fb_blank(int blank, struct fb_info *info) static const struct fb_ops cyber2000fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = cyber2000fb_check_var, .fb_set_par = cyber2000fb_set_par, .fb_setcolreg = cyber2000fb_setcolreg, @@ -1070,6 +1071,7 @@ static const struct fb_ops cyber2000fb_ops = { .fb_copyarea = cyber2000fb_copyarea, .fb_imageblit = cyber2000fb_imageblit, .fb_sync = cyber2000fb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* -- cgit v1.2.3 From a7942a325b103c80210e8577b1a27c0363df5e8f Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:46 +0200 Subject: fbdev/dnfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-14-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/dnfb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 43753f150b37..0ad8ef735e5e 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -217,6 +217,7 @@ config FB_APOLLO default y select FB_CFB_FILLRECT select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS config FB_Q40 bool diff --git a/drivers/video/fbdev/dnfb.c b/drivers/video/fbdev/dnfb.c index 18405c402ec1..c4d24540d9ef 100644 --- a/drivers/video/fbdev/dnfb.c +++ b/drivers/video/fbdev/dnfb.c @@ -110,10 +110,12 @@ static void dnfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); static const struct fb_ops dn_fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_blank = dnfb_blank, .fb_fillrect = cfb_fillrect, .fb_copyarea = dnfb_copyarea, .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static const struct fb_var_screeninfo dnfb_var = { -- cgit v1.2.3 From 244c2b55bf7b245d2030d3d1cba0c7d2000b75c9 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:47 +0200 Subject: fbdev/ep93xx-fb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-15-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 4 +--- drivers/video/fbdev/ep93xx-fb.c | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 0ad8ef735e5e..c13050bebaf4 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1866,9 +1866,7 @@ config FB_MB862XX_I2C config FB_EP93XX tristate "EP93XX frame buffer support" depends on FB && ARCH_EP93XX - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS help Framebuffer driver for the Cirrus Logic EP93XX series of processors. This driver is also available as a module. The module will be called diff --git a/drivers/video/fbdev/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c index d94e3e8d14a1..cae00deee001 100644 --- a/drivers/video/fbdev/ep93xx-fb.c +++ b/drivers/video/fbdev/ep93xx-fb.c @@ -404,12 +404,11 @@ static int ep93xxfb_setcolreg(unsigned int regno, unsigned int red, static const struct fb_ops ep93xxfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = ep93xxfb_check_var, .fb_set_par = ep93xxfb_set_par, .fb_blank = ep93xxfb_blank, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_setcolreg = ep93xxfb_setcolreg, .fb_mmap = ep93xxfb_mmap, }; -- cgit v1.2.3 From e7011bf87d6dc3ac045bd3d0a73a9e520974adcf Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:48 +0200 Subject: fbdev/gbefb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-16-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 4 +--- drivers/video/fbdev/gbefb.c | 7 +++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index c13050bebaf4..5b2fbb76686a 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -498,9 +498,7 @@ config FB_GBE bool "SGI Graphics Backend frame buffer support" depends on (FB = y) && HAS_IOMEM depends on SGI_IP32 || COMPILE_TEST - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS help This is the frame buffer device driver for SGI Graphics Backend. This chip is used in SGI O2 and Visual Workstation 320/540. diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c index 4fccdccbc364..e89e5579258e 100644 --- a/drivers/video/fbdev/gbefb.c +++ b/drivers/video/fbdev/gbefb.c @@ -1044,14 +1044,13 @@ static int gbefb_mmap(struct fb_info *info, static const struct fb_ops gbefb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = gbefb_check_var, .fb_set_par = gbefb_set_par, .fb_setcolreg = gbefb_setcolreg, - .fb_mmap = gbefb_mmap, .fb_blank = gbefb_blank, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, + .fb_mmap = gbefb_mmap, }; /* -- cgit v1.2.3 From 2195155117a1fa828b0c7d5ab3bba02128863a79 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:49 +0200 Subject: fbdev/hgafb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Cc: Ferenc Bakonyi Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-17-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/hgafb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 5b2fbb76686a..370239f375f5 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -485,6 +485,7 @@ config FB_N411 config FB_HGA tristate "Hercules mono graphics support" depends on FB && X86 + select FB_IOMEM_FOPS help Say Y here if you have a Hercules mono graphics card. diff --git a/drivers/video/fbdev/hgafb.c b/drivers/video/fbdev/hgafb.c index 6a64e6d7255e..10728259dac2 100644 --- a/drivers/video/fbdev/hgafb.c +++ b/drivers/video/fbdev/hgafb.c @@ -532,12 +532,14 @@ static const struct fb_ops hgafb_ops = { .owner = THIS_MODULE, .fb_open = hgafb_open, .fb_release = hgafb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_setcolreg = hgafb_setcolreg, .fb_pan_display = hgafb_pan_display, .fb_blank = hgafb_blank, .fb_fillrect = hgafb_fillrect, .fb_copyarea = hgafb_copyarea, .fb_imageblit = hgafb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* ------------------------------------------------------------------------- * -- cgit v1.2.3 From a1a1c3fa1340cf7305bc83496baacc009d73c7e7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:50 +0200 Subject: fbdev/hitfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-18-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 2 +- drivers/video/fbdev/hitfb.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 370239f375f5..cdd421f5cf25 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1490,8 +1490,8 @@ config FB_HIT tristate "HD64461 Frame Buffer support" depends on FB && HD64461 select FB_CFB_FILLRECT - select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS help This is the frame buffer device driver for the Hitachi HD64461 LCD frame buffer card. diff --git a/drivers/video/fbdev/hitfb.c b/drivers/video/fbdev/hitfb.c index 17715eaf0673..b64b74b76c71 100644 --- a/drivers/video/fbdev/hitfb.c +++ b/drivers/video/fbdev/hitfb.c @@ -328,8 +328,9 @@ static int hitfb_set_par(struct fb_info *info) static const struct fb_ops hitfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = hitfb_check_var, - .fb_set_par = hitfb_set_par, + .fb_set_par = hitfb_set_par, .fb_setcolreg = hitfb_setcolreg, .fb_blank = hitfb_blank, .fb_sync = hitfb_sync, @@ -337,6 +338,7 @@ static const struct fb_ops hitfb_ops = { .fb_fillrect = hitfb_fillrect, .fb_copyarea = hitfb_copyarea, .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int hitfb_probe(struct platform_device *dev) -- cgit v1.2.3 From b933456c25353a935714cb63f36090808f26ba5d Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:51 +0200 Subject: fbdev/hpfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-19-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/hpfb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index cdd421f5cf25..aef3e3f5af93 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -407,6 +407,7 @@ config FB_HP300 bool depends on (FB = y) && DIO select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS default y config FB_TGA diff --git a/drivers/video/fbdev/hpfb.c b/drivers/video/fbdev/hpfb.c index 406c1383cbda..66fac8e5393e 100644 --- a/drivers/video/fbdev/hpfb.c +++ b/drivers/video/fbdev/hpfb.c @@ -186,12 +186,14 @@ static int hpfb_sync(struct fb_info *info) static const struct fb_ops hpfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_setcolreg = hpfb_setcolreg, .fb_blank = hpfb_blank, .fb_fillrect = hpfb_fillrect, .fb_copyarea = hpfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_sync = hpfb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* Common to all HP framebuffers */ -- cgit v1.2.3 From 7e568f77d2c96e05c68a9e141ac4a204c62f4bcd Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:52 +0200 Subject: fbdev/i810fb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Cc: Antonino Daplas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-20-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 4 +--- drivers/video/fbdev/i810/i810_main.c | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index aef3e3f5af93..2adc3aa2d40d 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -793,10 +793,8 @@ config FB_I740 config FB_I810 tristate "Intel 810/815 support" depends on FB && PCI && X86_32 && AGP_INTEL + select FB_IOMEM_FOPS select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT select VGASTATE select VIDEO_NOMODESET help diff --git a/drivers/video/fbdev/i810/i810_main.c b/drivers/video/fbdev/i810/i810_main.c index f5511bb4fadc..d73a795fe1be 100644 --- a/drivers/video/fbdev/i810/i810_main.c +++ b/drivers/video/fbdev/i810/i810_main.c @@ -1547,6 +1547,7 @@ static const struct fb_ops i810fb_ops = { .owner = THIS_MODULE, .fb_open = i810fb_open, .fb_release = i810fb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = i810fb_check_var, .fb_set_par = i810fb_set_par, .fb_setcolreg = i810fb_setcolreg, @@ -1557,6 +1558,7 @@ static const struct fb_ops i810fb_ops = { .fb_imageblit = i810fb_imageblit, .fb_cursor = i810fb_cursor, .fb_sync = i810fb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /*********************************************************************** -- cgit v1.2.3 From 80ac1058e4c0acc4303fd8bb42d5702433867359 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:53 +0200 Subject: fbdev/imsttfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-21-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/imsttfb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 2adc3aa2d40d..7be947c811a5 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -356,6 +356,7 @@ config FB_IMSTT bool "IMS Twin Turbo display support" depends on (FB = y) && PCI select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select FB_MACMODES if PPC_PMAC select VIDEO_NOMODESET help diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c index f4c8677488fb..e7e03e920729 100644 --- a/drivers/video/fbdev/imsttfb.c +++ b/drivers/video/fbdev/imsttfb.c @@ -1336,6 +1336,7 @@ static struct pci_driver imsttfb_pci_driver = { static const struct fb_ops imsttfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = imsttfb_check_var, .fb_set_par = imsttfb_set_par, .fb_setcolreg = imsttfb_setcolreg, @@ -1345,6 +1346,7 @@ static const struct fb_ops imsttfb_ops = { .fb_copyarea = imsttfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_ioctl = imsttfb_ioctl, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int init_imstt(struct fb_info *info) -- cgit v1.2.3 From 68deeb025fbfb809aabfecf84331c8d872a101a3 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:54 +0200 Subject: fbdev/intelfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Cc: Maik Broemme Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-22-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 3 ++- drivers/video/fbdev/intelfb/intelfbdrv.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 7be947c811a5..2a16ce0ff0cf 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -861,10 +861,11 @@ config FB_CARILLO_RANCH config FB_INTEL tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support" depends on FB && PCI && X86 && AGP_INTEL && EXPERT - select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS + select FB_MODE_HELPERS select BOOT_VESA_SUPPORT if FB_INTEL = y select VIDEO_NOMODESET depends on !DRM_I915 diff --git a/drivers/video/fbdev/intelfb/intelfbdrv.c b/drivers/video/fbdev/intelfb/intelfbdrv.c index 3d334f171959..d29d80a16295 100644 --- a/drivers/video/fbdev/intelfb/intelfbdrv.c +++ b/drivers/video/fbdev/intelfb/intelfbdrv.c @@ -198,6 +198,7 @@ static const struct fb_ops intel_fb_ops = { .owner = THIS_MODULE, .fb_open = intelfb_open, .fb_release = intelfb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = intelfb_check_var, .fb_set_par = intelfb_set_par, .fb_setcolreg = intelfb_setcolreg, @@ -208,7 +209,8 @@ static const struct fb_ops intel_fb_ops = { .fb_imageblit = intelfb_imageblit, .fb_cursor = intelfb_cursor, .fb_sync = intelfb_sync, - .fb_ioctl = intelfb_ioctl + .fb_ioctl = intelfb_ioctl, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* PCI driver module table */ -- cgit v1.2.3 From dc9c80b0c6ca04fa7fde6c0fab00c624f51ec396 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:55 +0200 Subject: fbdev/matroxfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize each instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-23-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 2 ++ drivers/video/fbdev/matrox/matroxfb_base.c | 2 ++ drivers/video/fbdev/matrox/matroxfb_crtc2.c | 4 +--- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 2a16ce0ff0cf..58c743baeeb0 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -903,6 +903,7 @@ config FB_MATROX select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select FB_TILEBLITTING select FB_MACMODES if PPC_PMAC select VIDEO_NOMODESET @@ -989,6 +990,7 @@ config FB_MATROX_I2C config FB_MATROX_MAVEN tristate "G400 second head support" depends on FB_MATROX_G && FB_MATROX_I2C + select FB_IOMEM_HELPERS help WARNING !!! This support does not work with G450 !!! diff --git a/drivers/video/fbdev/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c index a043a737ea9f..81603ce05a22 100644 --- a/drivers/video/fbdev/matrox/matroxfb_base.c +++ b/drivers/video/fbdev/matrox/matroxfb_base.c @@ -1204,6 +1204,7 @@ static const struct fb_ops matroxfb_ops = { .owner = THIS_MODULE, .fb_open = matroxfb_open, .fb_release = matroxfb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = matroxfb_check_var, .fb_set_par = matroxfb_set_par, .fb_setcolreg = matroxfb_setcolreg, @@ -1214,6 +1215,7 @@ static const struct fb_ops matroxfb_ops = { /* .fb_copyarea = , */ /* .fb_imageblit = , */ /* .fb_cursor = , */ + __FB_DEFAULT_IOMEM_OPS_MMAP, }; #define RSDepth(X) (((X) >> 8) & 0x0F) diff --git a/drivers/video/fbdev/matrox/matroxfb_crtc2.c b/drivers/video/fbdev/matrox/matroxfb_crtc2.c index 372197c124de..417fc692468d 100644 --- a/drivers/video/fbdev/matrox/matroxfb_crtc2.c +++ b/drivers/video/fbdev/matrox/matroxfb_crtc2.c @@ -567,15 +567,13 @@ static const struct fb_ops matroxfb_dh_ops = { .owner = THIS_MODULE, .fb_open = matroxfb_dh_open, .fb_release = matroxfb_dh_release, + FB_DEFAULT_IOMEM_OPS, .fb_check_var = matroxfb_dh_check_var, .fb_set_par = matroxfb_dh_set_par, .fb_setcolreg = matroxfb_dh_setcolreg, .fb_pan_display =matroxfb_dh_pan_display, .fb_blank = matroxfb_dh_blank, .fb_ioctl = matroxfb_dh_ioctl, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, }; static struct fb_var_screeninfo matroxfb_dh_defined = { -- cgit v1.2.3 From eb9d5c19dcc383479326890702edc04649c430ac Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:56 +0200 Subject: fbdev/neofb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-24-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 3 ++- drivers/video/fbdev/neofb.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 58c743baeeb0..4502960ef89c 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1268,10 +1268,11 @@ endif config FB_NEOMAGIC tristate "NeoMagic display support" depends on FB && PCI - select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS + select FB_MODE_HELPERS select VGASTATE select VIDEO_NOMODESET help diff --git a/drivers/video/fbdev/neofb.c b/drivers/video/fbdev/neofb.c index b58b11015c0c..632ba2455913 100644 --- a/drivers/video/fbdev/neofb.c +++ b/drivers/video/fbdev/neofb.c @@ -1614,6 +1614,7 @@ static const struct fb_ops neofb_ops = { .owner = THIS_MODULE, .fb_open = neofb_open, .fb_release = neofb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = neofb_check_var, .fb_set_par = neofb_set_par, .fb_setcolreg = neofb_setcolreg, @@ -1623,6 +1624,7 @@ static const struct fb_ops neofb_ops = { .fb_fillrect = neofb_fillrect, .fb_copyarea = neofb_copyarea, .fb_imageblit = neofb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* --------------------------------------------------------------------- */ -- cgit v1.2.3 From 50182ed4eb2232bab18567dd460b02c98bcb0580 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:57 +0200 Subject: fbdev/nvidiafb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Cc: Antonino Daplas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-25-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 2 +- drivers/video/fbdev/nvidia/nvidia.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 4502960ef89c..d0a217c2e4d5 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -689,10 +689,10 @@ config FB_NVIDIA tristate "nVidia Framebuffer Support" depends on FB && PCI select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT - select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select BITREVERSE select VGASTATE select VIDEO_NOMODESET diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c index 907c22408652..8900f181f195 100644 --- a/drivers/video/fbdev/nvidia/nvidia.c +++ b/drivers/video/fbdev/nvidia/nvidia.c @@ -1028,6 +1028,7 @@ static struct fb_ops nvidia_fb_ops = { .owner = THIS_MODULE, .fb_open = nvidiafb_open, .fb_release = nvidiafb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = nvidiafb_check_var, .fb_set_par = nvidiafb_set_par, .fb_setcolreg = nvidiafb_setcolreg, @@ -1038,6 +1039,7 @@ static struct fb_ops nvidia_fb_ops = { .fb_imageblit = nvidiafb_imageblit, .fb_cursor = nvidiafb_cursor, .fb_sync = nvidiafb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int nvidiafb_suspend_late(struct device *dev, pm_message_t mesg) -- cgit v1.2.3 From b7ba90ac14c1ce047e8e4ad308779d5fcdca9dca Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:58 +0200 Subject: fbdev/omapfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-26-tzimmermann@suse.de --- drivers/video/fbdev/omap2/omapfb/Kconfig | 4 +--- drivers/video/fbdev/omap2/omapfb/omapfb-main.c | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/video/fbdev/omap2/omapfb/Kconfig b/drivers/video/fbdev/omap2/omapfb/Kconfig index 21069fdb7cc2..f4cdf999a080 100644 --- a/drivers/video/fbdev/omap2/omapfb/Kconfig +++ b/drivers/video/fbdev/omap2/omapfb/Kconfig @@ -10,9 +10,7 @@ menuconfig FB_OMAP2 depends on GPIOLIB select FB_OMAP2_DSS select OMAP2_VRFB if ARCH_OMAP2 || ARCH_OMAP3 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS help Frame buffer driver for OMAP2+ based boards. diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c index b5acad8eb279..c9fd0ad352d7 100644 --- a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c @@ -1280,10 +1280,9 @@ static const struct fb_ops omapfb_ops = { .owner = THIS_MODULE, .fb_open = omapfb_open, .fb_release = omapfb_release, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_blank = omapfb_blank, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_ioctl = omapfb_ioctl, .fb_check_var = omapfb_check_var, .fb_set_par = omapfb_set_par, -- cgit v1.2.3 From a9b0061fb3cf4d4d82bd32192ed66492e545535b Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:26:59 +0200 Subject: fbdev/pm2fb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-27-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/pm2fb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index d0a217c2e4d5..12a86a04ce36 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -94,6 +94,7 @@ config FB_PM2 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select VIDEO_NOMODESET help This is the frame buffer device driver for cards based on diff --git a/drivers/video/fbdev/pm2fb.c b/drivers/video/fbdev/pm2fb.c index 5a79a12efd8e..f34429829b7d 100644 --- a/drivers/video/fbdev/pm2fb.c +++ b/drivers/video/fbdev/pm2fb.c @@ -1492,6 +1492,7 @@ static int pm2fb_cursor(struct fb_info *info, struct fb_cursor *cursor) static const struct fb_ops pm2fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = pm2fb_check_var, .fb_set_par = pm2fb_set_par, .fb_setcolreg = pm2fb_setcolreg, @@ -1502,6 +1503,7 @@ static const struct fb_ops pm2fb_ops = { .fb_imageblit = pm2fb_imageblit, .fb_sync = pm2fb_sync, .fb_cursor = pm2fb_cursor, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* -- cgit v1.2.3 From 5dc84f309c4a70008d6ddb3662fdc81456a4e1d1 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:00 +0200 Subject: fbdev/pm3fb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-28-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/pm3fb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 12a86a04ce36..584c9b2b8b02 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1404,6 +1404,7 @@ config FB_PM3 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select VIDEO_NOMODESET help This is the frame buffer device driver for the 3DLabs Permedia3 diff --git a/drivers/video/fbdev/pm3fb.c b/drivers/video/fbdev/pm3fb.c index 16577d0e41b1..6e55e42514d6 100644 --- a/drivers/video/fbdev/pm3fb.c +++ b/drivers/video/fbdev/pm3fb.c @@ -1203,6 +1203,7 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info) static const struct fb_ops pm3fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = pm3fb_check_var, .fb_set_par = pm3fb_set_par, .fb_setcolreg = pm3fb_setcolreg, @@ -1213,6 +1214,7 @@ static const struct fb_ops pm3fb_ops = { .fb_blank = pm3fb_blank, .fb_sync = pm3fb_sync, .fb_cursor = pm3fb_cursor, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* ------------------------------------------------------------------------- */ -- cgit v1.2.3 From 4232739709060703e9dd6f5d6839c37e008d389d Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:01 +0200 Subject: fbdev/pvr2fb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-29-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/pvr2fb.c | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 584c9b2b8b02..42cd5e3a6942 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -634,6 +634,7 @@ config FB_PVR2 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select VIDEO_NOMODESET help Say Y here if you have a PowerVR 2 card in your box. If you plan to diff --git a/drivers/video/fbdev/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c index 6307364e4a49..cbdb1caf61bd 100644 --- a/drivers/video/fbdev/pvr2fb.c +++ b/drivers/video/fbdev/pvr2fb.c @@ -725,16 +725,18 @@ out_unmap: static const struct fb_ops pvr2fb_ops = { .owner = THIS_MODULE, +#ifdef CONFIG_PVR2_DMA + .fb_read = fb_io_read, + .fb_write = pvr2fb_write, +#else + __FB_DEFAULT_IOMEM_OPS_RDWR, +#endif .fb_setcolreg = pvr2fb_setcolreg, .fb_blank = pvr2fb_blank, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_check_var = pvr2fb_check_var, .fb_set_par = pvr2fb_set_par, -#ifdef CONFIG_PVR2_DMA - .fb_write = pvr2fb_write, -#endif - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; #ifndef MODULE -- cgit v1.2.3 From c6e8f889c75a28d113fad2b815d91c4c103ed054 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:02 +0200 Subject: fbdev/radeon: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Cc: Benjamin Herrenschmidt Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-30-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 3 ++- drivers/video/fbdev/aty/radeon_base.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 42cd5e3a6942..c73c66d9ddd5 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1025,11 +1025,12 @@ config FB_RADEON tristate "ATI Radeon display support" depends on FB && PCI select FB_BACKLIGHT if FB_RADEON_BACKLIGHT - select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select FB_MACMODES if PPC + select FB_MODE_HELPERS select VIDEO_NOMODESET help Choose this option if you want to use an ATI Radeon graphics card as diff --git a/drivers/video/fbdev/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c index 93fd1773402c..36bfb6deb8ab 100644 --- a/drivers/video/fbdev/aty/radeon_base.c +++ b/drivers/video/fbdev/aty/radeon_base.c @@ -1952,6 +1952,7 @@ static int radeonfb_set_par(struct fb_info *info) static const struct fb_ops radeonfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = radeonfb_check_var, .fb_set_par = radeonfb_set_par, .fb_setcolreg = radeonfb_setcolreg, @@ -1963,6 +1964,7 @@ static const struct fb_ops radeonfb_ops = { .fb_fillrect = radeonfb_fillrect, .fb_copyarea = radeonfb_copyarea, .fb_imageblit = radeonfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; -- cgit v1.2.3 From 9880753349b8056c84a9c2dbf96522192d2d725a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:03 +0200 Subject: fbdev/rivafb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Cc: Antonino Daplas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-31-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 3 ++- drivers/video/fbdev/riva/fbdev.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index c73c66d9ddd5..eaad007c8ad5 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -739,10 +739,11 @@ config FB_RIVA tristate "nVidia Riva support" depends on FB && PCI select FB_BACKLIGHT if FB_RIVA_BACKLIGHT - select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS + select FB_MODE_HELPERS select BITREVERSE select VGASTATE select VIDEO_NOMODESET diff --git a/drivers/video/fbdev/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c index 99576ba3ce6e..237db738af13 100644 --- a/drivers/video/fbdev/riva/fbdev.c +++ b/drivers/video/fbdev/riva/fbdev.c @@ -1670,6 +1670,7 @@ static const struct fb_ops riva_fb_ops = { .owner = THIS_MODULE, .fb_open = rivafb_open, .fb_release = rivafb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = rivafb_check_var, .fb_set_par = rivafb_set_par, .fb_setcolreg = rivafb_setcolreg, @@ -1680,6 +1681,7 @@ static const struct fb_ops riva_fb_ops = { .fb_imageblit = rivafb_imageblit, .fb_cursor = rivafb_cursor, .fb_sync = rivafb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int riva_set_fbinfo(struct fb_info *info) -- cgit v1.2.3 From bf0f401f8ae344a6ebf196f77210a12b72c648f5 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:04 +0200 Subject: fbdev/s1d13xxxfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. To simplify the conversion, provide a dedicated fb_ops instance for accelerated devices. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Cc: Kristoffer Ericson Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-32-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/s1d13xxxfb.c | 25 ++++++++++++++++--------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index eaad007c8ad5..0a15bedb0b44 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -671,6 +671,7 @@ config FB_S1D13XXX select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS help Support for S1D13XXX framebuffer device family (currently only working with S1D13806). Product specs at diff --git a/drivers/video/fbdev/s1d13xxxfb.c b/drivers/video/fbdev/s1d13xxxfb.c index c7d221cce06d..0e871197c6de 100644 --- a/drivers/video/fbdev/s1d13xxxfb.c +++ b/drivers/video/fbdev/s1d13xxxfb.c @@ -596,18 +596,26 @@ s1d13xxxfb_bitblt_solidfill(struct fb_info *info, const struct fb_fillrect *rect } /* framebuffer information structures */ -static struct fb_ops s1d13xxxfb_fbops = { +static const struct fb_ops s1d13xxxfb_fbops = { .owner = THIS_MODULE, + FB_DEFAULT_IOMEM_OPS, .fb_set_par = s1d13xxxfb_set_par, .fb_setcolreg = s1d13xxxfb_setcolreg, .fb_blank = s1d13xxxfb_blank, - .fb_pan_display = s1d13xxxfb_pan_display, +}; - /* gets replaced at chip detection time */ - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, +static const struct fb_ops s1d13xxxfb_fbops_s1d13506 = { + .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, + .fb_set_par = s1d13xxxfb_set_par, + .fb_setcolreg = s1d13xxxfb_setcolreg, + .fb_blank = s1d13xxxfb_blank, + .fb_pan_display = s1d13xxxfb_pan_display, + .fb_fillrect = s1d13xxxfb_bitblt_solidfill, + .fb_copyarea = s1d13xxxfb_bitblt_copyarea, .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int s1d13xxxfb_width_tab[2][4] = { @@ -869,17 +877,16 @@ static int s1d13xxxfb_probe(struct platform_device *pdev) default_par->regs, info->fix.smem_len / 1024, info->screen_base); info->par = default_par; - info->flags = FBINFO_HWACCEL_YPAN; - info->fbops = &s1d13xxxfb_fbops; switch(prod_id) { case S1D13506_PROD_ID: /* activate acceleration */ - s1d13xxxfb_fbops.fb_fillrect = s1d13xxxfb_bitblt_solidfill; - s1d13xxxfb_fbops.fb_copyarea = s1d13xxxfb_bitblt_copyarea; info->flags = FBINFO_HWACCEL_YPAN | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_COPYAREA; + info->fbops = &s1d13xxxfb_fbops_s1d13506; break; default: + info->flags = FBINFO_HWACCEL_YPAN; + info->fbops = &s1d13xxxfb_fbops; break; } -- cgit v1.2.3 From 633ca05f6c3c3be51908795290c7ecbddabf6ede Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:05 +0200 Subject: fbdev/s3fb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-33-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/s3fb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 0a15bedb0b44..ea63ad8b5be7 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1145,6 +1145,7 @@ config FB_S3 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select FB_TILEBLITTING select FB_SVGALIB select VGASTATE diff --git a/drivers/video/fbdev/s3fb.c b/drivers/video/fbdev/s3fb.c index 7d257489edcc..589b349cb63e 100644 --- a/drivers/video/fbdev/s3fb.c +++ b/drivers/video/fbdev/s3fb.c @@ -1047,6 +1047,7 @@ static const struct fb_ops s3fb_ops = { .owner = THIS_MODULE, .fb_open = s3fb_open, .fb_release = s3fb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = s3fb_check_var, .fb_set_par = s3fb_set_par, .fb_setcolreg = s3fb_setcolreg, @@ -1055,6 +1056,7 @@ static const struct fb_ops s3fb_ops = { .fb_fillrect = s3fb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = s3fb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, .fb_get_caps = svga_get_caps, }; -- cgit v1.2.3 From 3bf4f1b3de8030d743ef692f94c004b10883e344 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:06 +0200 Subject: fbdev/sa1100fb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-34-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 4 +--- drivers/video/fbdev/sa1100fb.c | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index ea63ad8b5be7..cf4c599b390a 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -159,9 +159,7 @@ config FB_CLPS711X config FB_SA1100 bool "SA-1100 LCD support" depends on (FB = y) && ARM && ARCH_SA1100 - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS help This is a framebuffer device for the SA-1100 LCD Controller. See for information on framebuffer diff --git a/drivers/video/fbdev/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c index 3d76ce111488..446b44e172e1 100644 --- a/drivers/video/fbdev/sa1100fb.c +++ b/drivers/video/fbdev/sa1100fb.c @@ -575,14 +575,13 @@ static int sa1100fb_mmap(struct fb_info *info, static const struct fb_ops sa1100fb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = sa1100fb_check_var, .fb_set_par = sa1100fb_set_par, // .fb_set_cmap = sa1100fb_set_cmap, .fb_setcolreg = sa1100fb_setcolreg, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, .fb_blank = sa1100fb_blank, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_mmap = sa1100fb_mmap, }; -- cgit v1.2.3 From cee250bce6264ee3e48b0e22585d6bdbbb0dceb9 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:07 +0200 Subject: fbdev/savagefb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Cc: Antonino Daplas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-35-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 3 ++- drivers/video/fbdev/savage/savagefb_driver.c | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index cf4c599b390a..312c302617ae 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1163,10 +1163,11 @@ config FB_S3_DDC config FB_SAVAGE tristate "S3 Savage support" depends on FB && PCI - select FB_MODE_HELPERS select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS + select FB_MODE_HELPERS select VGASTATE select VIDEO_NOMODESET help diff --git a/drivers/video/fbdev/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c index b5f84bd4804b..dddd6afcb972 100644 --- a/drivers/video/fbdev/savage/savagefb_driver.c +++ b/drivers/video/fbdev/savage/savagefb_driver.c @@ -1641,6 +1641,7 @@ static const struct fb_ops savagefb_ops = { .owner = THIS_MODULE, .fb_open = savagefb_open, .fb_release = savagefb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = savagefb_check_var, .fb_set_par = savagefb_set_par, .fb_setcolreg = savagefb_setcolreg, @@ -1652,10 +1653,9 @@ static const struct fb_ops savagefb_ops = { .fb_imageblit = savagefb_imageblit, .fb_sync = savagefb_sync, #else - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, #endif + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* --------------------------------------------------------------------- */ -- cgit v1.2.3 From 3fa0ee772b9a1b1dfe9c2c6a8d8187945b6cde47 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:08 +0200 Subject: fbdev/sisfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-36-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 3 ++- drivers/video/fbdev/sis/sis_main.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 312c302617ae..fd0dba398c2d 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1203,10 +1203,11 @@ config FB_SAVAGE_ACCEL config FB_SIS tristate "SiS/XGI display support" depends on FB && PCI + select BOOT_VESA_SUPPORT if FB_SIS = y select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select BOOT_VESA_SUPPORT if FB_SIS = y + select FB_IOMEM_FOPS select FB_SIS_300 if !FB_SIS_315 select VIDEO_NOMODESET help diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c index 0f5374f6ef05..6ad47b6b6004 100644 --- a/drivers/video/fbdev/sis/sis_main.c +++ b/drivers/video/fbdev/sis/sis_main.c @@ -1911,6 +1911,7 @@ static const struct fb_ops sisfb_ops = { .owner = THIS_MODULE, .fb_open = sisfb_open, .fb_release = sisfb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = sisfb_check_var, .fb_set_par = sisfb_set_par, .fb_setcolreg = sisfb_setcolreg, @@ -1923,7 +1924,8 @@ static const struct fb_ops sisfb_ops = { #ifdef SIS_NEW_CONFIG_COMPAT .fb_compat_ioctl= sisfb_ioctl, #endif - .fb_ioctl = sisfb_ioctl + .fb_ioctl = sisfb_ioctl, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* ---------------- Chip generation dependent routines ---------------- */ -- cgit v1.2.3 From 30543d363dc91e569d573fd4e2bb7404adbc6299 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:09 +0200 Subject: fbdev/sm501fb: Initialize fb_ops to fbdev I/O-memory helpers Initialize each instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-37-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/sm501fb.c | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index fd0dba398c2d..e58fe64578db 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1667,6 +1667,7 @@ config FB_SM501 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS help Frame buffer driver for the CRT and LCD controllers in the Silicon Motion SM501. diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c index 65c799ac5604..d6fdc1737cd2 100644 --- a/drivers/video/fbdev/sm501fb.c +++ b/drivers/video/fbdev/sm501fb.c @@ -1452,6 +1452,7 @@ static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rec static struct fb_ops sm501fb_ops_crt = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = sm501fb_check_var_crt, .fb_set_par = sm501fb_set_par_crt, .fb_blank = sm501fb_blank_crt, @@ -1462,10 +1463,12 @@ static struct fb_ops sm501fb_ops_crt = { .fb_copyarea = sm501fb_copyarea, .fb_imageblit = cfb_imageblit, .fb_sync = sm501fb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static struct fb_ops sm501fb_ops_pnl = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = sm501fb_check_var_pnl, .fb_set_par = sm501fb_set_par_pnl, .fb_pan_display = sm501fb_pan_pnl, @@ -1476,6 +1479,7 @@ static struct fb_ops sm501fb_ops_pnl = { .fb_copyarea = sm501fb_copyarea, .fb_imageblit = cfb_imageblit, .fb_sync = sm501fb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; /* sm501_init_cursor -- cgit v1.2.3 From 586132cf1d3871f7eb19eae4f78e58cdb52a52d8 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:10 +0200 Subject: fbdev/sm712fb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Cc: Sudip Mukherjee Cc: Teddy Wang Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-38-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 4 +--- drivers/video/fbdev/sm712fb.c | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index e58fe64578db..98c5dfc6f26e 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1938,9 +1938,7 @@ config FB_SSD1307 config FB_SM712 tristate "Silicon Motion SM712 framebuffer support" depends on FB && PCI - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT + select FB_IOMEM_HELPERS select VIDEO_NOMODESET help Frame buffer driver for the Silicon Motion SM710, SM712, SM721 diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c index db129ed3b2f7..3f8ef50e3209 100644 --- a/drivers/video/fbdev/sm712fb.c +++ b/drivers/video/fbdev/sm712fb.c @@ -1347,6 +1347,7 @@ static int smtc_set_par(struct fb_info *info) static const struct fb_ops smtcfb_ops = { .owner = THIS_MODULE, + FB_DEFAULT_IOMEM_OPS, .fb_check_var = smtc_check_var, .fb_set_par = smtc_set_par, .fb_setcolreg = smtc_setcolreg, -- cgit v1.2.3 From 6cdc804e41dde955b305d86b18327567bdaf0d26 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:11 +0200 Subject: fbdev/stifb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Cc: "James E.J. Bottomley" Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-39-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/stifb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 98c5dfc6f26e..3ed07f983be6 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -384,6 +384,7 @@ config FB_STI select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select STI_CORE default y help diff --git a/drivers/video/fbdev/stifb.c b/drivers/video/fbdev/stifb.c index c746deb79afc..548d992f8cb1 100644 --- a/drivers/video/fbdev/stifb.c +++ b/drivers/video/fbdev/stifb.c @@ -1167,12 +1167,14 @@ stifb_init_display(struct stifb_info *fb) static const struct fb_ops stifb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = stifb_check_var, .fb_setcolreg = stifb_setcolreg, .fb_blank = stifb_blank, .fb_fillrect = stifb_fillrect, .fb_copyarea = stifb_copyarea, .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; -- cgit v1.2.3 From 188a8646b95a68f65906d835475b1ef66c11afc8 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:12 +0200 Subject: fbdev/sunxvr500: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-40-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/sunxvr500.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 3ed07f983be6..f5e87f6885c1 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -596,6 +596,7 @@ config FB_XVR500 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select VIDEO_NOMODESET help This is the framebuffer device for the Sun XVR-500 and similar diff --git a/drivers/video/fbdev/sunxvr500.c b/drivers/video/fbdev/sunxvr500.c index 3b7dcdae9f83..fef008b728dd 100644 --- a/drivers/video/fbdev/sunxvr500.c +++ b/drivers/video/fbdev/sunxvr500.c @@ -189,10 +189,12 @@ static void e3d_copyarea(struct fb_info *info, const struct fb_copyarea *area) static const struct fb_ops e3d_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_setcolreg = e3d_setcolreg, .fb_fillrect = e3d_fillrect, .fb_copyarea = e3d_copyarea, .fb_imageblit = e3d_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int e3d_set_fbinfo(struct e3d_info *ep) -- cgit v1.2.3 From 309ede0f945c1b6f85f0a6735c40b736d2b49f27 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:13 +0200 Subject: fbdev/tdfxfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-41-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 3 ++- drivers/video/fbdev/tdfxfb.c | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index f5e87f6885c1..fed8298c79ca 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1305,9 +1305,10 @@ config FB_KYRO config FB_3DFX tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support" depends on FB && PCI - select FB_CFB_IMAGEBLIT select FB_CFB_FILLRECT select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select FB_MODE_HELPERS select VIDEO_NOMODESET help diff --git a/drivers/video/fbdev/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c index 68e2a82220f3..22aa953138b0 100644 --- a/drivers/video/fbdev/tdfxfb.c +++ b/drivers/video/fbdev/tdfxfb.c @@ -1142,6 +1142,7 @@ static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) static const struct fb_ops tdfxfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = tdfxfb_check_var, .fb_set_par = tdfxfb_set_par, .fb_setcolreg = tdfxfb_setcolreg, @@ -1154,10 +1155,9 @@ static const struct fb_ops tdfxfb_ops = { .fb_copyarea = tdfxfb_copyarea, .fb_imageblit = tdfxfb_imageblit, #else - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, #endif + __FB_DEFAULT_IOMEM_OPS_MMAP, }; #ifdef CONFIG_FB_3DFX_I2C -- cgit v1.2.3 From 153fc9bbac8c3338e4b0d5037c2b8c58e8e0e13b Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:14 +0200 Subject: fbdev/tgafb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-42-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 3 ++- drivers/video/fbdev/tgafb.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index fed8298c79ca..7215aaeb4ac7 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -416,10 +416,11 @@ config FB_TGA depends on FB depends on PCI || TC depends on ALPHA || TC + select BITREVERSE select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT - select BITREVERSE + select FB_IOMEM_FOPS select VIDEO_NOMODESET help This is the frame buffer device driver for generic TGA and SFB+ diff --git a/drivers/video/fbdev/tgafb.c b/drivers/video/fbdev/tgafb.c index fc2d08dd1b45..ca43774f3156 100644 --- a/drivers/video/fbdev/tgafb.c +++ b/drivers/video/fbdev/tgafb.c @@ -73,6 +73,7 @@ static struct tc_driver tgafb_tc_driver; static const struct fb_ops tgafb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = tgafb_check_var, .fb_set_par = tgafb_set_par, .fb_setcolreg = tgafb_setcolreg, @@ -81,6 +82,7 @@ static const struct fb_ops tgafb_ops = { .fb_fillrect = tgafb_fillrect, .fb_copyarea = tgafb_copyarea, .fb_imageblit = tgafb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; -- cgit v1.2.3 From 5e5943fef29632b2a48e4110845dcc8256dcfde2 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:15 +0200 Subject: fbdev/tridentfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-43-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/tridentfb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 7215aaeb4ac7..5dc2a56c9398 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1375,6 +1375,7 @@ config FB_TRIDENT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT select FB_DDC + select FB_IOMEM_FOPS select FB_MODE_HELPERS select VIDEO_NOMODESET help diff --git a/drivers/video/fbdev/tridentfb.c b/drivers/video/fbdev/tridentfb.c index 1ba157530af2..816d40b6f689 100644 --- a/drivers/video/fbdev/tridentfb.c +++ b/drivers/video/fbdev/tridentfb.c @@ -1444,6 +1444,7 @@ static int tridentfb_blank(int blank_mode, struct fb_info *info) static const struct fb_ops tridentfb_ops = { .owner = THIS_MODULE, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_setcolreg = tridentfb_setcolreg, .fb_pan_display = tridentfb_pan_display, .fb_blank = tridentfb_blank, @@ -1453,6 +1454,7 @@ static const struct fb_ops tridentfb_ops = { .fb_copyarea = tridentfb_copyarea, .fb_imageblit = tridentfb_imageblit, .fb_sync = tridentfb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int trident_pci_probe(struct pci_dev *dev, -- cgit v1.2.3 From c74575424463ace02fa8a3496f0385b68a13ebf3 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:16 +0200 Subject: fbdev/vermilionfb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-44-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 4 +--- drivers/video/fbdev/vermilion/vermilion.c | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 5dc2a56c9398..4f5e9f625a89 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -849,10 +849,8 @@ config FB_I810_I2C config FB_LE80578 tristate "Intel LE80578 (Vermilion) support" depends on FB && PCI && X86 + select FB_IOMEM_HELPERS select FB_MODE_HELPERS - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT select VIDEO_NOMODESET help This driver supports the LE80578 (Vermilion Range) chipset diff --git a/drivers/video/fbdev/vermilion/vermilion.c b/drivers/video/fbdev/vermilion/vermilion.c index 71584c775efd..840ead69654b 100644 --- a/drivers/video/fbdev/vermilion/vermilion.c +++ b/drivers/video/fbdev/vermilion/vermilion.c @@ -1024,13 +1024,12 @@ static struct fb_ops vmlfb_ops = { .owner = THIS_MODULE, .fb_open = vmlfb_open, .fb_release = vmlfb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = vmlfb_check_var, .fb_set_par = vmlfb_set_par, .fb_blank = vmlfb_blank, .fb_pan_display = vmlfb_pan_display, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, + __FB_DEFAULT_IOMEM_OPS_DRAW, .fb_cursor = vmlfb_cursor, .fb_sync = vmlfb_sync, .fb_mmap = vmlfb_mmap, -- cgit v1.2.3 From e47e199cc23ee466005ee61bda9afc736c00d9d4 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:17 +0200 Subject: fbdev/vga16fb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-45-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/vga16fb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 4f5e9f625a89..f05c9b2a4f1a 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -369,6 +369,7 @@ config FB_VGA16 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select VGASTATE select FONT_8x16 if FRAMEBUFFER_CONSOLE help diff --git a/drivers/video/fbdev/vga16fb.c b/drivers/video/fbdev/vga16fb.c index b43c874c199f..ac21942d5311 100644 --- a/drivers/video/fbdev/vga16fb.c +++ b/drivers/video/fbdev/vga16fb.c @@ -1291,6 +1291,7 @@ static const struct fb_ops vga16fb_ops = { .owner = THIS_MODULE, .fb_open = vga16fb_open, .fb_release = vga16fb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_destroy = vga16fb_destroy, .fb_check_var = vga16fb_check_var, .fb_set_par = vga16fb_set_par, @@ -1300,6 +1301,7 @@ static const struct fb_ops vga16fb_ops = { .fb_fillrect = vga16fb_fillrect, .fb_copyarea = vga16fb_copyarea, .fb_imageblit = vga16fb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; static int vga16fb_probe(struct platform_device *dev) -- cgit v1.2.3 From fb159df356d82db2ddb8658802bd1749480c0194 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:18 +0200 Subject: fbdev/viafb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Cc: Florian Tobias Schandinat Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-46-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/via/viafbdev.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index f05c9b2a4f1a..11a0acbf816d 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1240,6 +1240,7 @@ config FB_VIA select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select I2C_ALGOBIT select VIDEO_NOMODESET help diff --git a/drivers/video/fbdev/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c index 190fddee62e6..58868f8880d6 100644 --- a/drivers/video/fbdev/via/viafbdev.c +++ b/drivers/video/fbdev/via/viafbdev.c @@ -2054,6 +2054,7 @@ static struct fb_ops viafb_ops = { .owner = THIS_MODULE, .fb_open = viafb_open, .fb_release = viafb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = viafb_check_var, .fb_set_par = viafb_set_par, .fb_setcolreg = viafb_setcolreg, @@ -2065,6 +2066,7 @@ static struct fb_ops viafb_ops = { .fb_cursor = viafb_cursor, .fb_ioctl = viafb_ioctl, .fb_sync = viafb_sync, + __FB_DEFAULT_IOMEM_OPS_MMAP, }; -- cgit v1.2.3 From 2770ea00081a4fbdc30c403a7bdd1680dffb4ff2 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Wed, 27 Sep 2023 09:27:19 +0200 Subject: fbdev/vt8623fb: Initialize fb_ops to fbdev I/O-memory helpers Initialize the instance of struct fb_ops with fbdev initializer macros for framebuffers in I/O address space. Set the read/write, draw and mmap callbacks to the correct implementation and avoid implicit defaults. Also select the necessary I/O helpers in Kconfig. Fbdev drivers sometimes rely on the callbacks being NULL for a default implementation to be invoked; hence requiring the I/O helpers to be built in any case. Setting all callbacks in all drivers explicitly will allow to make the I/O helpers optional. This benefits systems that do not use these functions. No functional changes. Signed-off-by: Thomas Zimmermann Acked-by: Javier Martinez Canillas Link: https://patchwork.freedesktop.org/patch/msgid/20230927074722.6197-47-tzimmermann@suse.de --- drivers/video/fbdev/Kconfig | 1 + drivers/video/fbdev/vt8623fb.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig index 11a0acbf816d..7c07ca06818a 100644 --- a/drivers/video/fbdev/Kconfig +++ b/drivers/video/fbdev/Kconfig @@ -1359,6 +1359,7 @@ config FB_VT8623 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT + select FB_IOMEM_FOPS select FB_TILEBLITTING select FB_SVGALIB select VGASTATE diff --git a/drivers/video/fbdev/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c index 034333ee6e45..f8d022cb61e8 100644 --- a/drivers/video/fbdev/vt8623fb.c +++ b/drivers/video/fbdev/vt8623fb.c @@ -644,6 +644,7 @@ static const struct fb_ops vt8623fb_ops = { .owner = THIS_MODULE, .fb_open = vt8623fb_open, .fb_release = vt8623fb_release, + __FB_DEFAULT_IOMEM_OPS_RDWR, .fb_check_var = vt8623fb_check_var, .fb_set_par = vt8623fb_set_par, .fb_setcolreg = vt8623fb_setcolreg, @@ -652,6 +653,7 @@ static const struct fb_ops vt8623fb_ops = { .fb_fillrect = vt8623fb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = vt8623fb_imageblit, + __FB_DEFAULT_IOMEM_OPS_MMAP, .fb_get_caps = svga_get_caps, }; -- cgit v1.2.3 From 53f410d3698fc96eb657b80e1758ba9b71d96628 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:31:57 +0200 Subject: drm/ast: Rename AST_IO_AR_PORT_WRITE to AST_IO_VGAARI_W Rename AST_IO_AR_PORT_WRITE to AST_IO_VGAARI_W to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-2-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 848a9f1403e8..3d64dc356d69 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -259,7 +259,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define IS_AST_GEN6(__ast) __ast_gen_is_eq(__ast, 6) #define IS_AST_GEN7(__ast) __ast_gen_is_eq(__ast, 7) -#define AST_IO_AR_PORT_WRITE (0x40) +#define AST_IO_VGAARI_W (0x40) #define AST_IO_MISC_PORT_WRITE (0x42) #define AST_IO_VGA_ENABLE_PORT (0x43) #define AST_IO_SEQ_PORT (0x44) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 32f04ec6c386..1ccbfdf27356 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -321,14 +321,14 @@ static void ast_set_std_reg(struct ast_device *ast, jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); for (i = 0; i < 20; i++) { jreg = stdtable->ar[i]; - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, (u8)i); - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, jreg); + ast_io_write8(ast, AST_IO_VGAARI_W, (u8)i); + ast_io_write8(ast, AST_IO_VGAARI_W, jreg); } - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x14); - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x00); + ast_io_write8(ast, AST_IO_VGAARI_W, 0x14); + ast_io_write8(ast, AST_IO_VGAARI_W, 0x00); jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); - ast_io_write8(ast, AST_IO_AR_PORT_WRITE, 0x20); + ast_io_write8(ast, AST_IO_VGAARI_W, 0x20); /* Set GR */ for (i = 0; i < 9; i++) -- cgit v1.2.3 From b3945edd707289191d483c930ab7961c1bd0dc0e Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:31:58 +0200 Subject: drm/ast: Rename AST_IO_MISC_PORT_WRITE to AST_IO_VGAMR_W Rename AST_IO_MISC_PORT_WRITE to AST_IO_VGAMR_W to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-3-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_main.c | 2 +- drivers/gpu/drm/ast/ast_mode.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 3d64dc356d69..ff86db3604cd 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -260,7 +260,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define IS_AST_GEN7(__ast) __ast_gen_is_eq(__ast, 7) #define AST_IO_VGAARI_W (0x40) -#define AST_IO_MISC_PORT_WRITE (0x42) +#define AST_IO_VGAMR_W (0x42) #define AST_IO_VGA_ENABLE_PORT (0x43) #define AST_IO_SEQ_PORT (0x44) #define AST_IO_DAC_INDEX_READ (0x47) diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index dae365ed3969..f8a682c4cbd0 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -50,7 +50,7 @@ static void ast_enable_vga(struct drm_device *dev) struct ast_device *ast = to_ast_device(dev); ast_io_write8(ast, AST_IO_VGA_ENABLE_PORT, 0x01); - ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, 0x01); + ast_io_write8(ast, AST_IO_VGAMR_W, 0x01); } /* diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 1ccbfdf27356..3f52648c20a0 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -298,7 +298,7 @@ static void ast_set_std_reg(struct ast_device *ast, stdtable = vbios_mode->std_table; jreg = stdtable->misc; - ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg); + ast_io_write8(ast, AST_IO_VGAMR_W, jreg); /* Set SEQ; except Screen Disable field */ ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03); @@ -537,7 +537,7 @@ static void ast_set_sync_reg(struct ast_device *ast, jreg |= 0x80; if (vbios_mode->enh_table->flags & NHSync) jreg |= 0x40; - ast_io_write8(ast, AST_IO_MISC_PORT_WRITE, jreg); + ast_io_write8(ast, AST_IO_VGAMR_W, jreg); } static void ast_set_start_address_crt1(struct ast_device *ast, -- cgit v1.2.3 From ba51b3ed170dabc34a1356c12302d33dc25d83e7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:31:59 +0200 Subject: drm/ast: Rename AST_IO_VGA_ENABLE_PORT to AST_IO_VGAER Rename AST_IO_VGA_ENABLE_PORT to AST_IO_VGAER to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-4-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_main.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index ff86db3604cd..e31ba929f18d 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -261,7 +261,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGAARI_W (0x40) #define AST_IO_VGAMR_W (0x42) -#define AST_IO_VGA_ENABLE_PORT (0x43) +#define AST_IO_VGAER (0x43) #define AST_IO_SEQ_PORT (0x44) #define AST_IO_DAC_INDEX_READ (0x47) #define AST_IO_DAC_INDEX_WRITE (0x48) diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index f8a682c4cbd0..7db1f5004454 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -40,7 +40,7 @@ static bool ast_is_vga_enabled(struct drm_device *dev) struct ast_device *ast = to_ast_device(dev); u8 ch; - ch = ast_io_read8(ast, AST_IO_VGA_ENABLE_PORT); + ch = ast_io_read8(ast, AST_IO_VGAER); return !!(ch & 0x01); } @@ -49,7 +49,7 @@ static void ast_enable_vga(struct drm_device *dev) { struct ast_device *ast = to_ast_device(dev); - ast_io_write8(ast, AST_IO_VGA_ENABLE_PORT, 0x01); + ast_io_write8(ast, AST_IO_VGAER, 0x01); ast_io_write8(ast, AST_IO_VGAMR_W, 0x01); } -- cgit v1.2.3 From 2a5481e3d35c378bf2523b307e948756f8d3e5de Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:00 +0200 Subject: drm/ast: Rename AST_IO_SEQ_PORT to AST_IO_VGASRI Rename AST_IO_VGA_SEQ_PORT to AST_IO_VGASRI to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-5-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index e31ba929f18d..dc8b4d86ca9a 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -262,7 +262,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGAARI_W (0x40) #define AST_IO_VGAMR_W (0x42) #define AST_IO_VGAER (0x43) -#define AST_IO_SEQ_PORT (0x44) +#define AST_IO_VGASRI (0x44) #define AST_IO_DAC_INDEX_READ (0x47) #define AST_IO_DAC_INDEX_WRITE (0x48) #define AST_IO_DAC_DATA (0x49) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 3f52648c20a0..6f8375dd80a3 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -56,13 +56,13 @@ static inline void ast_load_palette_index(struct ast_device *ast, u8 blue) { ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index); - ast_io_read8(ast, AST_IO_SEQ_PORT); + ast_io_read8(ast, AST_IO_VGASRI); ast_io_write8(ast, AST_IO_DAC_DATA, red); - ast_io_read8(ast, AST_IO_SEQ_PORT); + ast_io_read8(ast, AST_IO_VGASRI); ast_io_write8(ast, AST_IO_DAC_DATA, green); - ast_io_read8(ast, AST_IO_SEQ_PORT); + ast_io_read8(ast, AST_IO_VGASRI); ast_io_write8(ast, AST_IO_DAC_DATA, blue); - ast_io_read8(ast, AST_IO_SEQ_PORT); + ast_io_read8(ast, AST_IO_VGASRI); } static void ast_crtc_set_gamma_linear(struct ast_device *ast, @@ -301,11 +301,11 @@ static void ast_set_std_reg(struct ast_device *ast, ast_io_write8(ast, AST_IO_VGAMR_W, jreg); /* Set SEQ; except Screen Disable field */ - ast_set_index_reg(ast, AST_IO_SEQ_PORT, 0x00, 0x03); - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, stdtable->seq[0]); + ast_set_index_reg(ast, AST_IO_VGASRI, 0x00, 0x03); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, stdtable->seq[0]); for (i = 1; i < 4; i++) { jreg = stdtable->seq[i]; - ast_set_index_reg(ast, AST_IO_SEQ_PORT, (i + 1), jreg); + ast_set_index_reg(ast, AST_IO_VGASRI, (i + 1), jreg); } /* Set CRTC; except base address and offset */ @@ -689,7 +689,7 @@ static void ast_primary_plane_helper_atomic_enable(struct drm_plane *plane, * Therefore only reprogram the address after enabling the plane. */ ast_set_start_address_crt1(ast, (u32)ast_plane->offset); - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x00); } static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane, @@ -697,7 +697,7 @@ static void ast_primary_plane_helper_atomic_disable(struct drm_plane *plane, { struct ast_device *ast = to_ast_device(plane->dev); - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x1, 0xdf, 0x20); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x1, 0xdf, 0x20); } static const struct drm_plane_helper_funcs ast_primary_plane_helper_funcs = { @@ -1014,7 +1014,7 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) */ switch (mode) { case DRM_MODE_DPMS_ON: - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0); ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, 0); if (ast->tx_chip_types & AST_TX_DP501_BIT) ast_set_dp501_video_output(crtc->dev, 1); @@ -1051,7 +1051,7 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) ast_dp_power_on_off(crtc->dev, AST_DP_POWER_OFF); } - ast_set_index_reg_mask(ast, AST_IO_SEQ_PORT, 0x01, 0xdf, 0x20); + ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0x20); ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, ch); break; } -- cgit v1.2.3 From 9f662e1edecdadb770e0f1cb8ec1edbc68f62a5f Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:01 +0200 Subject: drm/ast: Rename AST_IO_DAC_INDEX_READ to AST_IO_VGADRR Rename AST_IO_DAC_INDEX_READ to AST_IO_VGADRR to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-6-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index dc8b4d86ca9a..ff95b8f088f8 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -263,7 +263,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGAMR_W (0x42) #define AST_IO_VGAER (0x43) #define AST_IO_VGASRI (0x44) -#define AST_IO_DAC_INDEX_READ (0x47) +#define AST_IO_VGADRR (0x47) #define AST_IO_DAC_INDEX_WRITE (0x48) #define AST_IO_DAC_DATA (0x49) #define AST_IO_GR_PORT (0x4E) -- cgit v1.2.3 From 7b0be4b94b693bc2d32a6f27d534995735bd8c95 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:02 +0200 Subject: drm/ast: Rename AST_IO_DAC_INDEX_WRITE to AST_IO_VGADWR Rename AST_IO_DAC_INDEX_WRITE to AST_IO_VGADWR to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-7-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index ff95b8f088f8..2b46fafd3467 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -264,7 +264,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGAER (0x43) #define AST_IO_VGASRI (0x44) #define AST_IO_VGADRR (0x47) -#define AST_IO_DAC_INDEX_WRITE (0x48) +#define AST_IO_VGADWR (0x48) #define AST_IO_DAC_DATA (0x49) #define AST_IO_GR_PORT (0x4E) #define AST_IO_CRTC_PORT (0x54) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 6f8375dd80a3..a719f6c9493d 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -55,7 +55,7 @@ static inline void ast_load_palette_index(struct ast_device *ast, u8 index, u8 red, u8 green, u8 blue) { - ast_io_write8(ast, AST_IO_DAC_INDEX_WRITE, index); + ast_io_write8(ast, AST_IO_VGADWR, index); ast_io_read8(ast, AST_IO_VGASRI); ast_io_write8(ast, AST_IO_DAC_DATA, red); ast_io_read8(ast, AST_IO_VGASRI); -- cgit v1.2.3 From a075e1682fdeffdab80fa1cfb2f5f781f3c7c62a Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:03 +0200 Subject: drm/ast: Rename AST_IO_DAC_DATA to AST_IO_VGAPDR Rename AST_IO_DAC_DATA to AST_IO_VGAPDR to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-8-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 2b46fafd3467..43d1861d6262 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -265,7 +265,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGASRI (0x44) #define AST_IO_VGADRR (0x47) #define AST_IO_VGADWR (0x48) -#define AST_IO_DAC_DATA (0x49) +#define AST_IO_VGAPDR (0x49) #define AST_IO_GR_PORT (0x4E) #define AST_IO_CRTC_PORT (0x54) #define AST_IO_INPUT_STATUS1_READ (0x5A) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index a719f6c9493d..fa21cdfd6c4f 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -57,11 +57,11 @@ static inline void ast_load_palette_index(struct ast_device *ast, { ast_io_write8(ast, AST_IO_VGADWR, index); ast_io_read8(ast, AST_IO_VGASRI); - ast_io_write8(ast, AST_IO_DAC_DATA, red); + ast_io_write8(ast, AST_IO_VGAPDR, red); ast_io_read8(ast, AST_IO_VGASRI); - ast_io_write8(ast, AST_IO_DAC_DATA, green); + ast_io_write8(ast, AST_IO_VGAPDR, green); ast_io_read8(ast, AST_IO_VGASRI); - ast_io_write8(ast, AST_IO_DAC_DATA, blue); + ast_io_write8(ast, AST_IO_VGAPDR, blue); ast_io_read8(ast, AST_IO_VGASRI); } -- cgit v1.2.3 From 272bfa3a18c5ded5a12068fe0cf041275a00db66 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:04 +0200 Subject: drm/ast: Rename AST_IO_GR_PORT to AST_IO_VGAGRI Rename AST_IO_GR_PORT to AST_IO_VGAGRI to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-9-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 43d1861d6262..86860ab54711 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -266,7 +266,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGADRR (0x47) #define AST_IO_VGADWR (0x48) #define AST_IO_VGAPDR (0x49) -#define AST_IO_GR_PORT (0x4E) +#define AST_IO_VGAGRI (0x4E) #define AST_IO_CRTC_PORT (0x54) #define AST_IO_INPUT_STATUS1_READ (0x5A) #define AST_IO_MISC_PORT_READ (0x4C) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index fa21cdfd6c4f..19dc050d6e81 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -332,7 +332,7 @@ static void ast_set_std_reg(struct ast_device *ast, /* Set GR */ for (i = 0; i < 9; i++) - ast_set_index_reg(ast, AST_IO_GR_PORT, i, stdtable->gr[i]); + ast_set_index_reg(ast, AST_IO_VGAGRI, i, stdtable->gr[i]); } static void ast_set_crtc_reg(struct ast_device *ast, -- cgit v1.2.3 From c79479fa215c56b4bf59add12e1a92ca6310e611 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:05 +0200 Subject: drm/ast: Rename AST_IO_CRTC_PORT to AST_IO_VGACRI Rename AST_IO_CRTC_PORT to AST_IO_VGACRI to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-10-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_dp.c | 70 +++++++++---------- drivers/gpu/drm/ast/ast_dp501.c | 38 +++++------ drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_i2c.c | 20 +++--- drivers/gpu/drm/ast/ast_main.c | 18 ++--- drivers/gpu/drm/ast/ast_mm.c | 4 +- drivers/gpu/drm/ast/ast_mode.c | 146 ++++++++++++++++++++-------------------- drivers/gpu/drm/ast/ast_post.c | 26 +++---- 8 files changed, 162 insertions(+), 162 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_dp.c b/drivers/gpu/drm/ast/ast_dp.c index fdd9a493aa9c..ebb6d8ebd44e 100644 --- a/drivers/gpu/drm/ast/ast_dp.c +++ b/drivers/gpu/drm/ast/ast_dp.c @@ -9,11 +9,11 @@ bool ast_astdp_is_connected(struct ast_device *ast) { - if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING)) + if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING)) return false; - if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD)) + if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD)) return false; - if (!ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS)) + if (!ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS)) return false; return true; } @@ -29,22 +29,22 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) * CRDF[b0]: DP HPD * CRE5[b0]: Host reading EDID process is done */ - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING) && + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS) && + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD) && + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK))) { goto err_astdp_edid_not_ready; } - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, 0x00); for (i = 0; i < 32; i++) { /* * CRE4[7:0]: Read-Pointer for EDID (Unit: 4bytes); valid range: 0~64 */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE4, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE4, ASTDP_AND_CLEAR_MASK, (u8)i); j = 0; @@ -52,9 +52,9 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) * CRD7[b0]: valid flag for EDID * CRD6[b0]: mirror read pointer for EDID */ - while ((ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD7, + while ((ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD7, ASTDP_EDID_VALID_FLAG_MASK) != 0x01) || - (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD6, + (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD6, ASTDP_EDID_READ_POINTER_MASK) != i)) { /* * Delay are getting longer with each retry. @@ -64,11 +64,11 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) */ mdelay(j+1); - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD))) { + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD))) { goto err_astdp_jump_out_loop_of_edid; } @@ -77,13 +77,13 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) goto err_astdp_jump_out_loop_of_edid; } - *(ediddata) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, + *(ediddata) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD8, ASTDP_EDID_READ_DATA_MASK); - *(ediddata + 1) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD9, + *(ediddata + 1) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD9, ASTDP_EDID_READ_DATA_MASK); - *(ediddata + 2) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDA, + *(ediddata + 2) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDA, ASTDP_EDID_READ_DATA_MASK); - *(ediddata + 3) = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDB, + *(ediddata + 3) = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDB, ASTDP_EDID_READ_DATA_MASK); if (i == 31) { @@ -103,25 +103,25 @@ int ast_astdp_read_edid(struct drm_device *dev, u8 *ediddata) ediddata += 4; } - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, ASTDP_HOST_EDID_READ_DONE); return 0; err_astdp_jump_out_loop_of_edid: - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, ASTDP_HOST_EDID_READ_DONE); return (~(j+256) + 1); err_astdp_edid_not_ready: - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING))) + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING))) return (~0xD1 + 1); - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS))) + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS))) return (~0xDC + 1); - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD))) + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD))) return (~0xDF + 1); - if (!(ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK))) + if (!(ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, ASTDP_HOST_EDID_READ_DONE_MASK))) return (~0xE5 + 1); return 0; @@ -137,7 +137,7 @@ void ast_dp_launch(struct drm_device *dev) struct ast_device *ast = to_ast_device(dev); // Wait one second then timeout. - while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, ASTDP_MCU_FW_EXECUTING) != + while (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, ASTDP_MCU_FW_EXECUTING) != ASTDP_MCU_FW_EXECUTING) { i++; // wait 100 ms @@ -153,7 +153,7 @@ void ast_dp_launch(struct drm_device *dev) if (!bDPExecute) drm_err(dev, "Wait DPMCU executing timeout\n"); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE5, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE5, (u8) ~ASTDP_HOST_EDID_READ_DONE_MASK, ASTDP_HOST_EDID_READ_DONE); } @@ -164,14 +164,14 @@ void ast_dp_power_on_off(struct drm_device *dev, bool on) { struct ast_device *ast = to_ast_device(dev); // Read and Turn off DP PHY sleep - u8 bE3 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, AST_DP_VIDEO_ENABLE); + u8 bE3 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, AST_DP_VIDEO_ENABLE); // Turn on DP PHY sleep if (!on) bE3 |= AST_DP_PHY_SLEEP; // DP Power on/off - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, (u8) ~AST_DP_PHY_SLEEP, bE3); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_PHY_SLEEP, bE3); } @@ -182,13 +182,13 @@ void ast_dp_set_on_off(struct drm_device *dev, bool on) u8 video_on_off = on; // Video On/Off - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE3, (u8) ~AST_DP_VIDEO_ENABLE, on); // If DP plug in and link successful then check video on / off status - if (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDC, ASTDP_LINK_SUCCESS) && - ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, ASTDP_HPD)) { + if (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDC, ASTDP_LINK_SUCCESS) && + ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_HPD)) { video_on_off <<= 4; - while (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xDF, + while (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xDF, ASTDP_MIRROR_VIDEO_ENABLE) != video_on_off) { // wait 1 ms mdelay(1); @@ -264,8 +264,8 @@ void ast_dp_set_mode(struct drm_crtc *crtc, struct ast_vbios_mode_info *vbios_mo * CRE1[7:0]: MISC1 (default: 0x00) * CRE2[7:0]: video format index (0x00 ~ 0x20 or 0x40 ~ 0x50) */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE0, ASTDP_AND_CLEAR_MASK, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE0, ASTDP_AND_CLEAR_MASK, ASTDP_MISC0_24bpp); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE1, ASTDP_AND_CLEAR_MASK, ASTDP_MISC1); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xE2, ASTDP_AND_CLEAR_MASK, ModeIdx); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE1, ASTDP_AND_CLEAR_MASK, ASTDP_MISC1); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xE2, ASTDP_AND_CLEAR_MASK, ModeIdx); } diff --git a/drivers/gpu/drm/ast/ast_dp501.c b/drivers/gpu/drm/ast/ast_dp501.c index f10d53b0c94f..9a4c3a0963f9 100644 --- a/drivers/gpu/drm/ast/ast_dp501.c +++ b/drivers/gpu/drm/ast/ast_dp501.c @@ -31,17 +31,17 @@ static int ast_load_dp501_microcode(struct drm_device *dev) static void send_ack(struct ast_device *ast) { u8 sendack; - sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff); + sendack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0xff); sendack |= 0x80; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0x00, sendack); } static void send_nack(struct ast_device *ast) { u8 sendack; - sendack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0xff); + sendack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0xff); sendack &= ~0x80; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, 0x00, sendack); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, 0x00, sendack); } static bool wait_ack(struct ast_device *ast) @@ -49,7 +49,7 @@ static bool wait_ack(struct ast_device *ast) u8 waitack; u32 retry = 0; do { - waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); + waitack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd2, 0xff); waitack &= 0x80; udelay(100); } while ((!waitack) && (retry++ < 1000)); @@ -65,7 +65,7 @@ static bool wait_nack(struct ast_device *ast) u8 waitack; u32 retry = 0; do { - waitack = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); + waitack = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd2, 0xff); waitack &= 0x80; udelay(100); } while ((waitack) && (retry++ < 1000)); @@ -78,12 +78,12 @@ static bool wait_nack(struct ast_device *ast) static void set_cmd_trigger(struct ast_device *ast) { - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x40); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, ~0x40, 0x40); } static void clear_cmd_trigger(struct ast_device *ast) { - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9b, ~0x40, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9b, ~0x40, 0x00); } #if 0 @@ -92,7 +92,7 @@ static bool wait_fw_ready(struct ast_device *ast) u8 waitready; u32 retry = 0; do { - waitready = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd2, 0xff); + waitready = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd2, 0xff); waitready &= 0x40; udelay(100); } while ((!waitready) && (retry++ < 1000)); @@ -110,7 +110,7 @@ static bool ast_write_cmd(struct drm_device *dev, u8 data) int retry = 0; if (wait_nack(ast)) { send_nack(ast); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, data); send_ack(ast); set_cmd_trigger(ast); do { @@ -132,7 +132,7 @@ static bool ast_write_data(struct drm_device *dev, u8 data) if (wait_nack(ast)) { send_nack(ast); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, data); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, data); send_ack(ast); if (wait_ack(ast)) { send_nack(ast); @@ -153,7 +153,7 @@ static bool ast_read_data(struct drm_device *dev, u8 *data) if (wait_ack(ast) == false) return false; - tmp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd3, 0xff); + tmp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd3, 0xff); *data = tmp; if (wait_nack(ast) == false) { send_nack(ast); @@ -166,7 +166,7 @@ static bool ast_read_data(struct drm_device *dev, u8 *data) static void clear_cmd(struct ast_device *ast) { send_nack(ast); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x9a, 0x00, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x9a, 0x00, 0x00); } #endif @@ -265,9 +265,9 @@ static bool ast_launch_m68k(struct drm_device *dev) data |= 0x800; ast_moutdwm(ast, 0x1e6e2040, data); - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */ + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x99, 0xfc); /* D[1:0]: Reserved Video Buffer */ jreg |= 0x02; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x99, jreg); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x99, jreg); } return true; } @@ -354,7 +354,7 @@ static bool ast_init_dvo(struct drm_device *dev) ast_write32(ast, 0xf000, 0x1); ast_write32(ast, 0x12000, 0x1688a8a8); - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if (!(jreg & 0x80)) { /* Init SCU DVO Settings */ data = ast_read32(ast, 0x12008); @@ -413,7 +413,7 @@ static bool ast_init_dvo(struct drm_device *dev) ast_write32(ast, 0x1202c, data); /* Init VGA DVO Settings */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); return true; } @@ -442,7 +442,7 @@ static void ast_init_analog(struct drm_device *dev) ast_write32(ast, 0, data); /* Disable DVO */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x00); } void ast_init_3rdtx(struct drm_device *dev) @@ -451,7 +451,7 @@ void ast_init_3rdtx(struct drm_device *dev) u8 jreg; if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast)) { - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); switch (jreg & 0x0e) { case 0x04: ast_init_dvo(dev); diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 86860ab54711..a8bcb1903294 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -267,7 +267,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGADWR (0x48) #define AST_IO_VGAPDR (0x49) #define AST_IO_VGAGRI (0x4E) -#define AST_IO_CRTC_PORT (0x54) +#define AST_IO_VGACRI (0x54) #define AST_IO_INPUT_STATUS1_READ (0x5A) #define AST_IO_MISC_PORT_READ (0x4C) diff --git a/drivers/gpu/drm/ast/ast_i2c.c b/drivers/gpu/drm/ast/ast_i2c.c index d64045c0b849..0e845e7acd9b 100644 --- a/drivers/gpu/drm/ast/ast_i2c.c +++ b/drivers/gpu/drm/ast/ast_i2c.c @@ -35,8 +35,8 @@ static void ast_i2c_setsda(void *i2c_priv, int data) for (i = 0; i < 0x10000; i++) { ujcrb7 = ((data & 0x01) ? 0 : 1) << 2; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf1, ujcrb7); - jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x04); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0xf1, ujcrb7); + jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x04); if (ujcrb7 == jtemp) break; } @@ -51,8 +51,8 @@ static void ast_i2c_setscl(void *i2c_priv, int clock) for (i = 0; i < 0x10000; i++) { ujcrb7 = ((clock & 0x01) ? 0 : 1); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0xf4, ujcrb7); - jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x01); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0xf4, ujcrb7); + jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x01); if (ujcrb7 == jtemp) break; } @@ -66,14 +66,14 @@ static int ast_i2c_getsda(void *i2c_priv) count = 0; pass = 0; - val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x20) >> 5) & 0x01; do { - val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + val2 = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x20) >> 5) & 0x01; if (val == val2) { pass++; } else { pass = 0; - val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x20) >> 5) & 0x01; + val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x20) >> 5) & 0x01; } } while ((pass < 5) && (count++ < 0x10000)); @@ -88,14 +88,14 @@ static int ast_i2c_getscl(void *i2c_priv) count = 0; pass = 0; - val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x10) >> 4) & 0x01; do { - val2 = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + val2 = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x10) >> 4) & 0x01; if (val == val2) { pass++; } else { pass = 0; - val = (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x10) >> 4) & 0x01; + val = (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x10) >> 4) & 0x01; } } while ((pass < 5) && (count++ < 0x10000)); diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c index 7db1f5004454..f4ab40e22cea 100644 --- a/drivers/gpu/drm/ast/ast_main.c +++ b/drivers/gpu/drm/ast/ast_main.c @@ -62,21 +62,21 @@ static void ast_enable_mmio_release(void *data) struct ast_device *ast = data; /* enable standard VGA decode */ - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x04); } static int ast_enable_mmio(struct ast_device *ast) { struct drm_device *dev = &ast->base; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06); return devm_add_action_or_reset(dev->dev, ast_enable_mmio_release, ast); } static void ast_open_key(struct ast_device *ast) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x80, 0xA8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x80, 0xA8); } static int ast_device_config_init(struct ast_device *ast) @@ -105,8 +105,8 @@ static int ast_device_config_init(struct ast_device *ast) * is disabled. We force using P2A if VGA only mode bit * is set D[7] */ - jregd0 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); - jregd1 = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); + jregd0 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); + jregd1 = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); if (!(jregd0 & 0x80) || !(jregd1 & 0x10)) { /* @@ -219,7 +219,7 @@ static void ast_detect_widescreen(struct ast_device *ast) ast->support_wide_screen = false; break; default: - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if (!(jreg & 0x80)) ast->support_wide_screen = true; else if (jreg & 0x01) @@ -256,7 +256,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) * SIL164 when there is none. */ if (!need_post) { - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xff); if (jreg & 0x80) ast->tx_chip_types = AST_TX_SIL164_BIT; } @@ -267,7 +267,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) * the SOC scratch register #1 bits 11:8 (interestingly marked * as "reserved" in the spec) */ - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); switch (jreg) { case 0x04: ast->tx_chip_types = AST_TX_SIL164_BIT; @@ -286,7 +286,7 @@ static void ast_detect_tx_chip(struct ast_device *ast, bool need_post) ast->tx_chip_types = AST_TX_DP501_BIT; } } else if (IS_AST_GEN7(ast)) { - if (ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xD1, TX_TYPE_MASK) == + if (ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xD1, TX_TYPE_MASK) == ASTDP_DPMCU_TX) { ast->tx_chip_types = AST_TX_ASTDP_BIT; ast_dp_launch(&ast->base); diff --git a/drivers/gpu/drm/ast/ast_mm.c b/drivers/gpu/drm/ast/ast_mm.c index bc174bd933b9..6dfe6d9777d4 100644 --- a/drivers/gpu/drm/ast/ast_mm.c +++ b/drivers/gpu/drm/ast/ast_mm.c @@ -39,7 +39,7 @@ static u32 ast_get_vram_size(struct ast_device *ast) u32 vram_size; vram_size = AST_VIDMEM_DEFAULT_SIZE; - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xaa, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xaa, 0xff); switch (jreg & 3) { case 0: vram_size = AST_VIDMEM_SIZE_8M; @@ -55,7 +55,7 @@ static u32 ast_get_vram_size(struct ast_device *ast) break; } - jreg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x99, 0xff); + jreg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0x99, 0xff); switch (jreg & 0x03) { case 1: vram_size -= 0x100000; diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 19dc050d6e81..c4381342af04 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -253,13 +253,13 @@ static void ast_set_vbios_color_reg(struct ast_device *ast, return; } - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8c, (u8)((color_index & 0x0f) << 4)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x8c, (u8)((color_index & 0x0f) << 4)); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0x00); if (vbios_mode->enh_table->flags & NewModeInfo) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x92, format->cpp[0] * 8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0xa8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x92, format->cpp[0] * 8); } } @@ -272,18 +272,18 @@ static void ast_set_vbios_mode_reg(struct ast_device *ast, refresh_rate_index = vbios_mode->enh_table->refresh_rate_index; mode_id = vbios_mode->enh_table->mode_id; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8d, refresh_rate_index & 0xff); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x8e, mode_id & 0xff); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x8d, refresh_rate_index & 0xff); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x8e, mode_id & 0xff); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0x00); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0x00); if (vbios_mode->enh_table->flags & NewModeInfo) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x91, 0xa8); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x93, adjusted_mode->clock / 1000); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x94, adjusted_mode->crtc_hdisplay); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x95, adjusted_mode->crtc_hdisplay >> 8); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x96, adjusted_mode->crtc_vdisplay); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x97, adjusted_mode->crtc_vdisplay >> 8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x91, 0xa8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x93, adjusted_mode->clock / 1000); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x94, adjusted_mode->crtc_hdisplay); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x95, adjusted_mode->crtc_hdisplay >> 8); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x96, adjusted_mode->crtc_vdisplay); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x97, adjusted_mode->crtc_vdisplay >> 8); } } @@ -309,13 +309,13 @@ static void ast_set_std_reg(struct ast_device *ast, } /* Set CRTC; except base address and offset */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x7f, 0x00); for (i = 0; i < 12; i++) - ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); + ast_set_index_reg(ast, AST_IO_VGACRI, i, stdtable->crtc[i]); for (i = 14; i < 19; i++) - ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); + ast_set_index_reg(ast, AST_IO_VGACRI, i, stdtable->crtc[i]); for (i = 20; i < 25; i++) - ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, stdtable->crtc[i]); + ast_set_index_reg(ast, AST_IO_VGACRI, i, stdtable->crtc[i]); /* set AR */ jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); @@ -346,48 +346,48 @@ static void ast_set_crtc_reg(struct ast_device *ast, (vbios_mode->enh_table->flags & AST2500PreCatchCRT)) precache = 40; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x7f, 0x00); temp = (mode->crtc_htotal >> 3) - 5; if (temp & 0x100) jregAC |= 0x01; /* HT D[8] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x00, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x00, 0x00, temp); temp = (mode->crtc_hdisplay >> 3) - 1; if (temp & 0x100) jregAC |= 0x04; /* HDE D[8] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x01, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x01, 0x00, temp); temp = (mode->crtc_hblank_start >> 3) - 1; if (temp & 0x100) jregAC |= 0x10; /* HBS D[8] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x02, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x02, 0x00, temp); temp = ((mode->crtc_hblank_end >> 3) - 1) & 0x7f; if (temp & 0x20) jreg05 |= 0x80; /* HBE D[5] */ if (temp & 0x40) jregAD |= 0x01; /* HBE D[5] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x03, 0xE0, (temp & 0x1f)); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x03, 0xE0, (temp & 0x1f)); temp = ((mode->crtc_hsync_start-precache) >> 3) - 1; if (temp & 0x100) jregAC |= 0x40; /* HRS D[5] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x04, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x04, 0x00, temp); temp = (((mode->crtc_hsync_end-precache) >> 3) - 1) & 0x3f; if (temp & 0x20) jregAD |= 0x04; /* HRE D[5] */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05)); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x05, 0x60, (u8)((temp & 0x1f) | jreg05)); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAC, 0x00, jregAC); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAD, 0x00, jregAD); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAC, 0x00, jregAC); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAD, 0x00, jregAD); // Workaround for HSync Time non octave pixels (1920x1080@60Hz HSync 44 pixels); if (IS_AST_GEN7(ast) && (mode->crtc_vdisplay == 1080)) - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x02); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xFC, 0xFD, 0x02); else - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xFC, 0xFD, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xFC, 0xFD, 0x00); /* vert timings */ temp = (mode->crtc_vtotal) - 2; @@ -397,7 +397,7 @@ static void ast_set_crtc_reg(struct ast_device *ast, jreg07 |= 0x20; if (temp & 0x400) jregAE |= 0x01; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x06, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x06, 0x00, temp); temp = (mode->crtc_vsync_start) - 1; if (temp & 0x100) @@ -406,14 +406,14 @@ static void ast_set_crtc_reg(struct ast_device *ast, jreg07 |= 0x80; if (temp & 0x400) jregAE |= 0x08; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x10, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x10, 0x00, temp); temp = (mode->crtc_vsync_end - 1) & 0x3f; if (temp & 0x10) jregAE |= 0x20; if (temp & 0x20) jregAE |= 0x40; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x70, temp & 0xf); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x70, temp & 0xf); temp = mode->crtc_vdisplay - 1; if (temp & 0x100) @@ -422,7 +422,7 @@ static void ast_set_crtc_reg(struct ast_device *ast, jreg07 |= 0x40; if (temp & 0x400) jregAE |= 0x02; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x12, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x12, 0x00, temp); temp = mode->crtc_vblank_start - 1; if (temp & 0x100) @@ -431,23 +431,23 @@ static void ast_set_crtc_reg(struct ast_device *ast, jreg09 |= 0x20; if (temp & 0x400) jregAE |= 0x04; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x15, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x15, 0x00, temp); temp = mode->crtc_vblank_end - 1; if (temp & 0x100) jregAE |= 0x10; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x16, 0x00, temp); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x16, 0x00, temp); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x07, 0x00, jreg07); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x09, 0xdf, jreg09); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xAE, 0x00, (jregAE | 0x80)); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x07, 0x00, jreg07); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x09, 0xdf, jreg09); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xAE, 0x00, (jregAE | 0x80)); if (precache) - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x80); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0x3f, 0x80); else - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0x3f, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0x3f, 0x00); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x11, 0x7f, 0x80); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x11, 0x7f, 0x80); } static void ast_set_offset_reg(struct ast_device *ast, @@ -456,8 +456,8 @@ static void ast_set_offset_reg(struct ast_device *ast, u16 offset; offset = fb->pitches[0] >> 3; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x13, (offset & 0xff)); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xb0, (offset >> 8) & 0x3f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x13, (offset & 0xff)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xb0, (offset >> 8) & 0x3f); } static void ast_set_dclk_reg(struct ast_device *ast, @@ -471,9 +471,9 @@ static void ast_set_dclk_reg(struct ast_device *ast, else clk_info = &dclk_table[vbios_mode->enh_table->dclk_index]; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc0, 0x00, clk_info->param1); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xc1, 0x00, clk_info->param2); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xbb, 0x0f, + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xc0, 0x00, clk_info->param1); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xc1, 0x00, clk_info->param2); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xbb, 0x0f, (clk_info->param3 & 0xc0) | ((clk_info->param3 & 0x3) << 4)); } @@ -502,26 +502,26 @@ static void ast_set_color_reg(struct ast_device *ast, break; } - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa0, 0x8f, jregA0); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xf0, jregA3); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa8, 0xfd, jregA8); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa0, 0x8f, jregA0); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xf0, jregA3); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa8, 0xfd, jregA8); } static void ast_set_crtthd_reg(struct ast_device *ast) { /* Set Threshold */ if (IS_AST_GEN7(ast)) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0xe0); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0xa0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0xe0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0xa0); } else if (IS_AST_GEN6(ast) || IS_AST_GEN5(ast) || IS_AST_GEN4(ast)) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x78); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x60); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x78); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x60); } else if (IS_AST_GEN3(ast) || IS_AST_GEN2(ast)) { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x3f); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x2f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x3f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x2f); } else { - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa7, 0x2f); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa6, 0x1f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa7, 0x2f); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa6, 0x1f); } } @@ -546,9 +546,9 @@ static void ast_set_start_address_crt1(struct ast_device *ast, u32 addr; addr = offset >> 2; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0d, (u8)(addr & 0xff)); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0x0c, (u8)((addr >> 8) & 0xff)); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xaf, (u8)((addr >> 16) & 0xff)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x0d, (u8)(addr & 0xff)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0x0c, (u8)((addr >> 8) & 0xff)); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xaf, (u8)((addr >> 16) & 0xff)); } @@ -814,9 +814,9 @@ static void ast_set_cursor_base(struct ast_device *ast, u64 address) u8 addr1 = (address >> 11) & 0xff; u8 addr2 = (address >> 19) & 0xff; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc8, addr0); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc9, addr1); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xca, addr2); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc8, addr0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc9, addr1); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xca, addr2); } static void ast_set_cursor_location(struct ast_device *ast, u16 x, u16 y, @@ -827,12 +827,12 @@ static void ast_set_cursor_location(struct ast_device *ast, u16 x, u16 y, u8 y0 = (y & 0x00ff); u8 y1 = (y & 0x0700) >> 8; - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc2, x_offset); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc3, y_offset); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc4, x0); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc5, x1); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc6, y0); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xc7, y1); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc2, x_offset); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc3, y_offset); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc4, x0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc5, x1); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc6, y0); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xc7, y1); } static void ast_set_cursor_enabled(struct ast_device *ast, bool enabled) @@ -845,7 +845,7 @@ static void ast_set_cursor_enabled(struct ast_device *ast, bool enabled) if (enabled) vgacrcb |= AST_IO_VGACRCB_HWC_ENABLED; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xcb, mask, vgacrcb); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xcb, mask, vgacrcb); } static const uint32_t ast_cursor_plane_formats[] = { @@ -1015,7 +1015,7 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) switch (mode) { case DRM_MODE_DPMS_ON: ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, 0); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, 0); if (ast->tx_chip_types & AST_TX_DP501_BIT) ast_set_dp501_video_output(crtc->dev, 1); @@ -1052,7 +1052,7 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) } ast_set_index_reg_mask(ast, AST_IO_VGASRI, 0x01, 0xdf, 0x20); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xfc, ch); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xfc, ch); break; } } @@ -1086,7 +1086,7 @@ ast_crtc_helper_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode return MODE_OK; if ((mode->hdisplay == 1920) && (mode->vdisplay == 1200)) { - jtemp = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd1, 0xff); + jtemp = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd1, 0xff); if (jtemp & 0x01) return MODE_NOMODE; else @@ -1219,7 +1219,7 @@ static void ast_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atom struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; ast_set_vbios_mode_reg(ast, adjusted_mode, vbios_mode_info); - ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x06); + ast_set_index_reg(ast, AST_IO_VGACRI, 0xa1, 0x06); ast_set_std_reg(ast, adjusted_mode, vbios_mode_info); ast_set_crtc_reg(ast, adjusted_mode, vbios_mode_info); ast_set_dclk_reg(ast, adjusted_mode, vbios_mode_info); diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c index 13e15173f2c5..7a993a384314 100644 --- a/drivers/gpu/drm/ast/ast_post.c +++ b/drivers/gpu/drm/ast/ast_post.c @@ -49,7 +49,7 @@ ast_set_def_ext_reg(struct drm_device *dev) /* reset scratch */ for (i = 0x81; i <= 0x9f; i++) - ast_set_index_reg(ast, AST_IO_CRTC_PORT, i, 0x00); + ast_set_index_reg(ast, AST_IO_VGACRI, i, 0x00); if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || IS_AST_GEN6(ast)) ext_reg_info = extreginfo_ast2300; @@ -58,23 +58,23 @@ ast_set_def_ext_reg(struct drm_device *dev) index = 0xa0; while (*ext_reg_info != 0xff) { - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, index, 0x00, *ext_reg_info); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, index, 0x00, *ext_reg_info); index++; ext_reg_info++; } /* disable standard IO/MEM decode if secondary */ - /* ast_set_index_reg-mask(ast, AST_IO_CRTC_PORT, 0xa1, 0xff, 0x3); */ + /* ast_set_index_reg-mask(ast, AST_IO_VGACRI, 0xa1, 0xff, 0x3); */ /* Set Ext. Default */ - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0x8c, 0x00, 0x01); - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb7, 0x00, 0x00); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0x8c, 0x00, 0x01); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb7, 0x00, 0x00); /* Enable RAMDAC for A1 */ reg = 0x04; if (IS_AST_GEN4(ast) || IS_AST_GEN5(ast) || IS_AST_GEN6(ast)) reg |= 0x20; - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xb6, 0xff, reg); + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xb6, 0xff, reg); } u32 ast_mindwm(struct ast_device *ast, u32 r) @@ -245,7 +245,7 @@ static void ast_init_dram_reg(struct drm_device *dev) u32 data, temp, i; const struct ast_dramstruct *dram_reg_info; - j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if ((j & 0x80) == 0) { /* VGA only */ if (IS_AST_GEN1(ast)) { @@ -325,7 +325,7 @@ static void ast_init_dram_reg(struct drm_device *dev) /* wait ready */ do { - j = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + j = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); } while ((j & 0x40) == 0); } @@ -349,7 +349,7 @@ void ast_post_gpu(struct drm_device *dev) ast_init_3rdtx(dev); } else { if (ast->tx_chip_types & AST_TX_SIL164_BIT) - ast_set_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xa3, 0xcf, 0x80); /* Enable DVO */ + ast_set_index_reg_mask(ast, AST_IO_VGACRI, 0xa3, 0xcf, 0x80); /* Enable DVO */ } } @@ -1562,7 +1562,7 @@ static void ast_post_chip_2300(struct drm_device *dev) u32 temp; u8 reg; - reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if ((reg & 0x80) == 0) {/* vga only */ ast_write32(ast, 0xf004, 0x1e6e0000); ast_write32(ast, 0xf000, 0x1); @@ -1634,7 +1634,7 @@ static void ast_post_chip_2300(struct drm_device *dev) /* wait ready */ do { - reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); } while ((reg & 0x40) == 0); } @@ -2027,7 +2027,7 @@ void ast_post_chip_2500(struct drm_device *dev) u32 temp; u8 reg; - reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); if ((reg & AST_VRAM_INIT_STATUS_MASK) == 0) {/* vga only */ /* Clear bus lock condition */ ast_patch_ahb_2500(ast); @@ -2075,6 +2075,6 @@ void ast_post_chip_2500(struct drm_device *dev) /* wait ready */ do { - reg = ast_get_index_reg_mask(ast, AST_IO_CRTC_PORT, 0xd0, 0xff); + reg = ast_get_index_reg_mask(ast, AST_IO_VGACRI, 0xd0, 0xff); } while ((reg & 0x40) == 0); } -- cgit v1.2.3 From 224bf236ca6d6d49e559565c5eba65f7acc6bbd9 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:06 +0200 Subject: drm/ast: Rename AST_IO_INPUT_STATUS1_READ to AST_IO_VGAIR1_R Rename AST_IO_INPUT_STATUS1_READ to AST_IO_VGAIR1_R to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-11-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index a8bcb1903294..03f1edf95e73 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -268,7 +268,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGAPDR (0x49) #define AST_IO_VGAGRI (0x4E) #define AST_IO_VGACRI (0x54) -#define AST_IO_INPUT_STATUS1_READ (0x5A) +#define AST_IO_VGAIR1_R (0x5A) #define AST_IO_MISC_PORT_READ (0x4C) #define AST_IO_MM_OFFSET (0x380) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index c4381342af04..289e32227f6b 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -318,7 +318,7 @@ static void ast_set_std_reg(struct ast_device *ast, ast_set_index_reg(ast, AST_IO_VGACRI, i, stdtable->crtc[i]); /* set AR */ - jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); + jreg = ast_io_read8(ast, AST_IO_VGAIR1_R); for (i = 0; i < 20; i++) { jreg = stdtable->ar[i]; ast_io_write8(ast, AST_IO_VGAARI_W, (u8)i); @@ -327,7 +327,7 @@ static void ast_set_std_reg(struct ast_device *ast, ast_io_write8(ast, AST_IO_VGAARI_W, 0x14); ast_io_write8(ast, AST_IO_VGAARI_W, 0x00); - jreg = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); + jreg = ast_io_read8(ast, AST_IO_VGAIR1_R); ast_io_write8(ast, AST_IO_VGAARI_W, 0x20); /* Set GR */ @@ -558,7 +558,7 @@ static void ast_wait_for_vretrace(struct ast_device *ast) u8 vgair1; do { - vgair1 = ast_io_read8(ast, AST_IO_INPUT_STATUS1_READ); + vgair1 = ast_io_read8(ast, AST_IO_VGAIR1_R); } while (!(vgair1 & AST_IO_VGAIR1_VREFRESH) && time_before(jiffies, timeout)); } -- cgit v1.2.3 From 8811bcbf28cc270aba8d0067bdb8f44c5cc5fad7 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:07 +0200 Subject: drm/ast: Rename AST_IO_MISC_PORT_READ to AST_IO_VGAMR_R Rename AST_IO_MISC_PORT_READ to AST_IO_VGAMR_R to align naming in the driver with documentation. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-12-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 2 +- drivers/gpu/drm/ast/ast_mode.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 03f1edf95e73..214bfac0798a 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -269,7 +269,7 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define AST_IO_VGAGRI (0x4E) #define AST_IO_VGACRI (0x54) #define AST_IO_VGAIR1_R (0x5A) -#define AST_IO_MISC_PORT_READ (0x4C) +#define AST_IO_VGAMR_R (0x4C) #define AST_IO_MM_OFFSET (0x380) diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c index 289e32227f6b..cb9614984285 100644 --- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -531,7 +531,7 @@ static void ast_set_sync_reg(struct ast_device *ast, { u8 jreg; - jreg = ast_io_read8(ast, AST_IO_MISC_PORT_READ); + jreg = ast_io_read8(ast, AST_IO_VGAMR_R); jreg &= ~0xC0; if (vbios_mode->enh_table->flags & NVSync) jreg |= 0x80; -- cgit v1.2.3 From 6c73f1dbd9bf91130c2ee0b9c65afb7c3c90bf23 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 17 Oct 2023 10:32:08 +0200 Subject: drm/ast: Move register constants to ast_reg.h Improve readability by putting all register constants into a separate header file. No functional changes. Signed-off-by: Thomas Zimmermann Reviewed-by: Jocelyn Falempe Link: https://patchwork.freedesktop.org/patch/msgid/20231017083653.10063-13-tzimmermann@suse.de --- drivers/gpu/drm/ast/ast_drv.h | 83 +----------------------------------- drivers/gpu/drm/ast/ast_reg.h | 99 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 81 deletions(-) create mode 100644 drivers/gpu/drm/ast/ast_reg.h diff --git a/drivers/gpu/drm/ast/ast_drv.h b/drivers/gpu/drm/ast/ast_drv.h index 214bfac0798a..2aee32344f4a 100644 --- a/drivers/gpu/drm/ast/ast_drv.h +++ b/drivers/gpu/drm/ast/ast_drv.h @@ -39,6 +39,8 @@ #include #include +#include "ast_reg.h" + #define DRIVER_AUTHOR "Dave Airlie" #define DRIVER_NAME "ast" @@ -259,25 +261,6 @@ static inline bool __ast_gen_is_eq(struct ast_device *ast, unsigned long gen) #define IS_AST_GEN6(__ast) __ast_gen_is_eq(__ast, 6) #define IS_AST_GEN7(__ast) __ast_gen_is_eq(__ast, 7) -#define AST_IO_VGAARI_W (0x40) -#define AST_IO_VGAMR_W (0x42) -#define AST_IO_VGAER (0x43) -#define AST_IO_VGASRI (0x44) -#define AST_IO_VGADRR (0x47) -#define AST_IO_VGADWR (0x48) -#define AST_IO_VGAPDR (0x49) -#define AST_IO_VGAGRI (0x4E) -#define AST_IO_VGACRI (0x54) -#define AST_IO_VGAIR1_R (0x5A) -#define AST_IO_VGAMR_R (0x4C) - -#define AST_IO_MM_OFFSET (0x380) - -#define AST_IO_VGAIR1_VREFRESH BIT(3) - -#define AST_IO_VGACRCB_HWC_ENABLED BIT(1) -#define AST_IO_VGACRCB_HWC_16BPP BIT(0) /* set: ARGB4444, cleared: 2bpp palette */ - static inline u32 ast_read32(struct ast_device *ast, u32 reg) { return ioread32(ast->regs + reg); @@ -399,71 +382,9 @@ int ast_mode_config_init(struct ast_device *ast); #define AST_DP501_LINKRATE 0xf014 #define AST_DP501_EDID_DATA 0xf020 -/* - * Display Transmitter Type: - */ -#define TX_TYPE_MASK GENMASK(3, 1) -#define NO_TX (0 << 1) -#define ITE66121_VBIOS_TX (1 << 1) -#define SI164_VBIOS_TX (2 << 1) -#define CH7003_VBIOS_TX (3 << 1) -#define DP501_VBIOS_TX (4 << 1) -#define ANX9807_VBIOS_TX (5 << 1) -#define TX_FW_EMBEDDED_FW_TX (6 << 1) -#define ASTDP_DPMCU_TX (7 << 1) - -#define AST_VRAM_INIT_STATUS_MASK GENMASK(7, 6) -//#define AST_VRAM_INIT_BY_BMC BIT(7) -//#define AST_VRAM_INIT_READY BIT(6) - -/* Define for Soc scratched reg used on ASTDP */ -#define AST_DP_PHY_SLEEP BIT(4) -#define AST_DP_VIDEO_ENABLE BIT(0) - #define AST_DP_POWER_ON true #define AST_DP_POWER_OFF false -/* - * CRD1[b5]: DP MCU FW is executing - * CRDC[b0]: DP link success - * CRDF[b0]: DP HPD - * CRE5[b0]: Host reading EDID process is done - */ -#define ASTDP_MCU_FW_EXECUTING BIT(5) -#define ASTDP_LINK_SUCCESS BIT(0) -#define ASTDP_HPD BIT(0) -#define ASTDP_HOST_EDID_READ_DONE BIT(0) -#define ASTDP_HOST_EDID_READ_DONE_MASK GENMASK(0, 0) - -/* - * CRB8[b1]: Enable VSYNC off - * CRB8[b0]: Enable HSYNC off - */ -#define AST_DPMS_VSYNC_OFF BIT(1) -#define AST_DPMS_HSYNC_OFF BIT(0) - -/* - * CRDF[b4]: Mirror of AST_DP_VIDEO_ENABLE - * Precondition: A. ~AST_DP_PHY_SLEEP && - * B. DP_HPD && - * C. DP_LINK_SUCCESS - */ -#define ASTDP_MIRROR_VIDEO_ENABLE BIT(4) - -#define ASTDP_EDID_READ_POINTER_MASK GENMASK(7, 0) -#define ASTDP_EDID_VALID_FLAG_MASK GENMASK(0, 0) -#define ASTDP_EDID_READ_DATA_MASK GENMASK(7, 0) - -/* - * ASTDP setmode registers: - * CRE0[7:0]: MISC0 ((0x00: 18-bpp) or (0x20: 24-bpp) - * CRE1[7:0]: MISC1 (default: 0x00) - * CRE2[7:0]: video format index (0x00 ~ 0x20 or 0x40 ~ 0x50) - */ -#define ASTDP_MISC0_24bpp BIT(5) -#define ASTDP_MISC1 0 -#define ASTDP_AND_CLEAR_MASK 0x00 - /* * ASTDP resoultion table: * EX: ASTDP_A_B_C: diff --git a/drivers/gpu/drm/ast/ast_reg.h b/drivers/gpu/drm/ast/ast_reg.h new file mode 100644 index 000000000000..555286ecf520 --- /dev/null +++ b/drivers/gpu/drm/ast/ast_reg.h @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef __AST_REG_H__ +#define __AST_REG_H__ + +#include + +/* + * Modesetting + */ + +#define AST_IO_MM_OFFSET (0x380) + +#define AST_IO_VGAARI_W (0x40) +#define AST_IO_VGAMR_W (0x42) +#define AST_IO_VGAER (0x43) +#define AST_IO_VGASRI (0x44) +#define AST_IO_VGADRR (0x47) +#define AST_IO_VGADWR (0x48) +#define AST_IO_VGAPDR (0x49) +#define AST_IO_VGAGRI (0x4E) + +#define AST_IO_VGACRI (0x54) +#define AST_IO_VGACRCB_HWC_16BPP BIT(0) /* set: ARGB4444, cleared: 2bpp palette */ +#define AST_IO_VGACRCB_HWC_ENABLED BIT(1) + +#define AST_IO_VGAIR1_R (0x5A) +#define AST_IO_VGAIR1_VREFRESH BIT(3) + +#define AST_IO_VGAMR_R (0x4C) + +/* + * Display Transmitter Type + */ + +#define TX_TYPE_MASK GENMASK(3, 1) +#define NO_TX (0 << 1) +#define ITE66121_VBIOS_TX (1 << 1) +#define SI164_VBIOS_TX (2 << 1) +#define CH7003_VBIOS_TX (3 << 1) +#define DP501_VBIOS_TX (4 << 1) +#define ANX9807_VBIOS_TX (5 << 1) +#define TX_FW_EMBEDDED_FW_TX (6 << 1) +#define ASTDP_DPMCU_TX (7 << 1) + +#define AST_VRAM_INIT_STATUS_MASK GENMASK(7, 6) +//#define AST_VRAM_INIT_BY_BMC BIT(7) +//#define AST_VRAM_INIT_READY BIT(6) + +/* + * AST DisplayPort + */ + +/* Define for Soc scratched reg used on ASTDP */ +#define AST_DP_PHY_SLEEP BIT(4) +#define AST_DP_VIDEO_ENABLE BIT(0) + +/* + * CRD1[b5]: DP MCU FW is executing + * CRDC[b0]: DP link success + * CRDF[b0]: DP HPD + * CRE5[b0]: Host reading EDID process is done + */ +#define ASTDP_MCU_FW_EXECUTING BIT(5) +#define ASTDP_LINK_SUCCESS BIT(0) +#define ASTDP_HPD BIT(0) +#define ASTDP_HOST_EDID_READ_DONE BIT(0) +#define ASTDP_HOST_EDID_READ_DONE_MASK GENMASK(0, 0) + +/* + * CRB8[b1]: Enable VSYNC off + * CRB8[b0]: Enable HSYNC off + */ +#define AST_DPMS_VSYNC_OFF BIT(1) +#define AST_DPMS_HSYNC_OFF BIT(0) + +/* + * CRDF[b4]: Mirror of AST_DP_VIDEO_ENABLE + * Precondition: A. ~AST_DP_PHY_SLEEP && + * B. DP_HPD && + * C. DP_LINK_SUCCESS + */ +#define ASTDP_MIRROR_VIDEO_ENABLE BIT(4) + +#define ASTDP_EDID_READ_POINTER_MASK GENMASK(7, 0) +#define ASTDP_EDID_VALID_FLAG_MASK GENMASK(0, 0) +#define ASTDP_EDID_READ_DATA_MASK GENMASK(7, 0) + +/* + * ASTDP setmode registers: + * CRE0[7:0]: MISC0 ((0x00: 18-bpp) or (0x20: 24-bpp) + * CRE1[7:0]: MISC1 (default: 0x00) + * CRE2[7:0]: video format index (0x00 ~ 0x20 or 0x40 ~ 0x50) + */ +#define ASTDP_MISC0_24bpp BIT(5) +#define ASTDP_MISC1 0 +#define ASTDP_AND_CLEAR_MASK 0x00 + +#endif -- cgit v1.2.3 From e2450d32e5fb5f89bf93e52f4ce694ad655cdc66 Mon Sep 17 00:00:00 2001 From: Cong Yang Date: Fri, 13 Oct 2023 17:18:42 +0800 Subject: drm/panel: ili9882t: Break out as separate driver The Starry ILI9882t-based panel should never have been part of the boe tv101wum driver, it is clearly based on the Ilitek ILI9882t display controller and if you look at the custom command sequences for the panel these clearly contain the signature Ilitek page switch (0xff) commands. The hardware has nothing in common with the other panels supported by this driver. Break this out into a separate driver and config symbol instead. If the placement here is out of convenience for using similar code, we should consider creating a helper library instead. Co-developed-by: Linus Walleij Signed-off-by: Linus Walleij Reviewed-by: Linus Walleij Reviewed-by: Douglas Anderson Signed-off-by: Cong Yang Signed-off-by: Douglas Anderson Link: https://patchwork.freedesktop.org/patch/msgid/20231013091844.804310-2-yangcong5@huaqin.corp-partner.google.com --- drivers/gpu/drm/panel/Kconfig | 9 + drivers/gpu/drm/panel/Makefile | 1 + drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c | 371 ------------ drivers/gpu/drm/panel/panel-ilitek-ili9882t.c | 759 +++++++++++++++++++++++++ 4 files changed, 769 insertions(+), 371 deletions(-) create mode 100644 drivers/gpu/drm/panel/panel-ilitek-ili9882t.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index ecb22ea326cb..99e14dc212ec 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -203,6 +203,15 @@ config DRM_PANEL_ILITEK_ILI9881C Say Y if you want to enable support for panels based on the Ilitek ILI9881c controller. +config DRM_PANEL_ILITEK_ILI9882T + tristate "Ilitek ILI9882t-based panels" + depends on OF + depends on DRM_MIPI_DSI + depends on BACKLIGHT_CLASS_DEVICE + help + Say Y if you want to enable support for panels based on the + Ilitek ILI9882t controller. + config DRM_PANEL_INNOLUX_EJ030NA tristate "Innolux EJ030NA 320x480 LCD panel" depends on OF && SPI diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index e14ce55a0875..d10c3de51c6d 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_DRM_PANEL_HIMAX_HX8394) += panel-himax-hx8394.o obj-$(CONFIG_DRM_PANEL_ILITEK_IL9322) += panel-ilitek-ili9322.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9341) += panel-ilitek-ili9341.o obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9881C) += panel-ilitek-ili9881c.o +obj-$(CONFIG_DRM_PANEL_ILITEK_ILI9882T) += panel-ilitek-ili9882t.o obj-$(CONFIG_DRM_PANEL_INNOLUX_EJ030NA) += panel-innolux-ej030na.o obj-$(CONFIG_DRM_PANEL_INNOLUX_P079ZCA) += panel-innolux-p079zca.o obj-$(CONFIG_DRM_PANEL_JADARD_JD9365DA_H3) += panel-jadard-jd9365da-h3.o diff --git a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c index 5ac926281d2c..4f370bc6dca8 100644 --- a/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +++ b/drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c @@ -1370,346 +1370,6 @@ static const struct panel_init_cmd starry_himax83102_j02_init_cmd[] = { {}, }; -static const struct panel_init_cmd starry_ili9882t_init_cmd[] = { - _INIT_DELAY_CMD(5), - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x01), - _INIT_DCS_CMD(0x00, 0x42), - _INIT_DCS_CMD(0x01, 0x11), - _INIT_DCS_CMD(0x02, 0x00), - _INIT_DCS_CMD(0x03, 0x00), - - _INIT_DCS_CMD(0x04, 0x01), - _INIT_DCS_CMD(0x05, 0x11), - _INIT_DCS_CMD(0x06, 0x00), - _INIT_DCS_CMD(0x07, 0x00), - - _INIT_DCS_CMD(0x08, 0x80), - _INIT_DCS_CMD(0x09, 0x81), - _INIT_DCS_CMD(0x0A, 0x71), - _INIT_DCS_CMD(0x0B, 0x00), - - _INIT_DCS_CMD(0x0C, 0x00), - _INIT_DCS_CMD(0x0E, 0x1A), - - _INIT_DCS_CMD(0x24, 0x00), - _INIT_DCS_CMD(0x25, 0x00), - _INIT_DCS_CMD(0x26, 0x00), - _INIT_DCS_CMD(0x27, 0x00), - - _INIT_DCS_CMD(0x2C, 0xD4), - _INIT_DCS_CMD(0xB9, 0x40), - - _INIT_DCS_CMD(0xB0, 0x11), - - _INIT_DCS_CMD(0xE6, 0x32), - _INIT_DCS_CMD(0xD1, 0x30), - - _INIT_DCS_CMD(0xD6, 0x55), - - _INIT_DCS_CMD(0xD0, 0x01), - _INIT_DCS_CMD(0xE3, 0x93), - _INIT_DCS_CMD(0xE4, 0x00), - _INIT_DCS_CMD(0xE5, 0x80), - - _INIT_DCS_CMD(0x31, 0x07), - _INIT_DCS_CMD(0x32, 0x07), - _INIT_DCS_CMD(0x33, 0x07), - _INIT_DCS_CMD(0x34, 0x07), - _INIT_DCS_CMD(0x35, 0x07), - _INIT_DCS_CMD(0x36, 0x01), - _INIT_DCS_CMD(0x37, 0x00), - _INIT_DCS_CMD(0x38, 0x28), - _INIT_DCS_CMD(0x39, 0x29), - _INIT_DCS_CMD(0x3A, 0x11), - _INIT_DCS_CMD(0x3B, 0x13), - _INIT_DCS_CMD(0x3C, 0x15), - _INIT_DCS_CMD(0x3D, 0x17), - _INIT_DCS_CMD(0x3E, 0x09), - _INIT_DCS_CMD(0x3F, 0x0D), - _INIT_DCS_CMD(0x40, 0x02), - _INIT_DCS_CMD(0x41, 0x02), - _INIT_DCS_CMD(0x42, 0x02), - _INIT_DCS_CMD(0x43, 0x02), - _INIT_DCS_CMD(0x44, 0x02), - _INIT_DCS_CMD(0x45, 0x02), - _INIT_DCS_CMD(0x46, 0x02), - - _INIT_DCS_CMD(0x47, 0x07), - _INIT_DCS_CMD(0x48, 0x07), - _INIT_DCS_CMD(0x49, 0x07), - _INIT_DCS_CMD(0x4A, 0x07), - _INIT_DCS_CMD(0x4B, 0x07), - _INIT_DCS_CMD(0x4C, 0x01), - _INIT_DCS_CMD(0x4D, 0x00), - _INIT_DCS_CMD(0x4E, 0x28), - _INIT_DCS_CMD(0x4F, 0x29), - _INIT_DCS_CMD(0x50, 0x10), - _INIT_DCS_CMD(0x51, 0x12), - _INIT_DCS_CMD(0x52, 0x14), - _INIT_DCS_CMD(0x53, 0x16), - _INIT_DCS_CMD(0x54, 0x08), - _INIT_DCS_CMD(0x55, 0x0C), - _INIT_DCS_CMD(0x56, 0x02), - _INIT_DCS_CMD(0x57, 0x02), - _INIT_DCS_CMD(0x58, 0x02), - _INIT_DCS_CMD(0x59, 0x02), - _INIT_DCS_CMD(0x5A, 0x02), - _INIT_DCS_CMD(0x5B, 0x02), - _INIT_DCS_CMD(0x5C, 0x02), - - _INIT_DCS_CMD(0x61, 0x07), - _INIT_DCS_CMD(0x62, 0x07), - _INIT_DCS_CMD(0x63, 0x07), - _INIT_DCS_CMD(0x64, 0x07), - _INIT_DCS_CMD(0x65, 0x07), - _INIT_DCS_CMD(0x66, 0x01), - _INIT_DCS_CMD(0x67, 0x00), - _INIT_DCS_CMD(0x68, 0x28), - _INIT_DCS_CMD(0x69, 0x29), - _INIT_DCS_CMD(0x6A, 0x16), - _INIT_DCS_CMD(0x6B, 0x14), - _INIT_DCS_CMD(0x6C, 0x12), - _INIT_DCS_CMD(0x6D, 0x10), - _INIT_DCS_CMD(0x6E, 0x0C), - _INIT_DCS_CMD(0x6F, 0x08), - _INIT_DCS_CMD(0x70, 0x02), - _INIT_DCS_CMD(0x71, 0x02), - _INIT_DCS_CMD(0x72, 0x02), - _INIT_DCS_CMD(0x73, 0x02), - _INIT_DCS_CMD(0x74, 0x02), - _INIT_DCS_CMD(0x75, 0x02), - _INIT_DCS_CMD(0x76, 0x02), - - _INIT_DCS_CMD(0x77, 0x07), - _INIT_DCS_CMD(0x78, 0x07), - _INIT_DCS_CMD(0x79, 0x07), - _INIT_DCS_CMD(0x7A, 0x07), - _INIT_DCS_CMD(0x7B, 0x07), - _INIT_DCS_CMD(0x7C, 0x01), - _INIT_DCS_CMD(0x7D, 0x00), - _INIT_DCS_CMD(0x7E, 0x28), - _INIT_DCS_CMD(0x7F, 0x29), - _INIT_DCS_CMD(0x80, 0x17), - _INIT_DCS_CMD(0x81, 0x15), - _INIT_DCS_CMD(0x82, 0x13), - _INIT_DCS_CMD(0x83, 0x11), - _INIT_DCS_CMD(0x84, 0x0D), - _INIT_DCS_CMD(0x85, 0x09), - _INIT_DCS_CMD(0x86, 0x02), - _INIT_DCS_CMD(0x87, 0x07), - _INIT_DCS_CMD(0x88, 0x07), - _INIT_DCS_CMD(0x89, 0x07), - _INIT_DCS_CMD(0x8A, 0x07), - _INIT_DCS_CMD(0x8B, 0x07), - _INIT_DCS_CMD(0x8C, 0x07), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x02), - _INIT_DCS_CMD(0x29, 0x3A), - _INIT_DCS_CMD(0x2A, 0x3B), - - _INIT_DCS_CMD(0x06, 0x01), - _INIT_DCS_CMD(0x07, 0x01), - _INIT_DCS_CMD(0x08, 0x0C), - _INIT_DCS_CMD(0x09, 0x44), - - _INIT_DCS_CMD(0x3C, 0x0A), - _INIT_DCS_CMD(0x39, 0x11), - _INIT_DCS_CMD(0x3D, 0x00), - _INIT_DCS_CMD(0x3A, 0x0C), - _INIT_DCS_CMD(0x3B, 0x44), - - _INIT_DCS_CMD(0x53, 0x1F), - _INIT_DCS_CMD(0x5E, 0x40), - _INIT_DCS_CMD(0x84, 0x00), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x03), - _INIT_DCS_CMD(0x20, 0x01), - _INIT_DCS_CMD(0x21, 0x3C), - _INIT_DCS_CMD(0x22, 0xFA), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0A), - _INIT_DCS_CMD(0xE0, 0x01), - _INIT_DCS_CMD(0xE2, 0x01), - _INIT_DCS_CMD(0xE5, 0x91), - _INIT_DCS_CMD(0xE6, 0x3C), - _INIT_DCS_CMD(0xE7, 0x00), - _INIT_DCS_CMD(0xE8, 0xFA), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x12), - _INIT_DCS_CMD(0x87, 0x2C), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x05), - _INIT_DCS_CMD(0x73, 0xE5), - _INIT_DCS_CMD(0x7F, 0x6B), - _INIT_DCS_CMD(0x6D, 0xA4), - _INIT_DCS_CMD(0x79, 0x54), - _INIT_DCS_CMD(0x69, 0x97), - _INIT_DCS_CMD(0x6A, 0x97), - _INIT_DCS_CMD(0xA5, 0x3F), - _INIT_DCS_CMD(0x61, 0xDA), - _INIT_DCS_CMD(0xA7, 0xF1), - _INIT_DCS_CMD(0x5F, 0x01), - _INIT_DCS_CMD(0x62, 0x3F), - _INIT_DCS_CMD(0x1D, 0x90), - _INIT_DCS_CMD(0x86, 0x87), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x06), - _INIT_DCS_CMD(0xC0, 0x80), - _INIT_DCS_CMD(0xC1, 0x07), - _INIT_DCS_CMD(0xCA, 0x58), - _INIT_DCS_CMD(0xCB, 0x02), - _INIT_DCS_CMD(0xCE, 0x58), - _INIT_DCS_CMD(0xCF, 0x02), - _INIT_DCS_CMD(0x67, 0x60), - _INIT_DCS_CMD(0x10, 0x00), - _INIT_DCS_CMD(0x92, 0x22), - _INIT_DCS_CMD(0xD3, 0x08), - _INIT_DCS_CMD(0xD6, 0x55), - _INIT_DCS_CMD(0xDC, 0x38), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x08), - _INIT_DCS_CMD(0xE0, 0x00, 0x10, 0x2A, 0x4D, 0x61, 0x56, 0x6A, 0x6E, 0x79, 0x76, 0x8F, 0x95, 0x98, 0xAE, 0xAA, 0xB2, 0xBB, 0xCE, 0xC6, 0xBD, 0xD5, 0xE2, 0xE8), - _INIT_DCS_CMD(0xE1, 0x00, 0x10, 0x2A, 0x4D, 0x61, 0x56, 0x6A, 0x6E, 0x79, 0x76, 0x8F, 0x95, 0x98, 0xAE, 0xAA, 0xB2, 0xBB, 0xCE, 0xC6, 0xBD, 0xD5, 0xE2, 0xE8), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x04), - _INIT_DCS_CMD(0xBA, 0x81), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0C), - _INIT_DCS_CMD(0x00, 0x02), - _INIT_DCS_CMD(0x01, 0x00), - _INIT_DCS_CMD(0x02, 0x03), - _INIT_DCS_CMD(0x03, 0x01), - _INIT_DCS_CMD(0x04, 0x03), - _INIT_DCS_CMD(0x05, 0x02), - _INIT_DCS_CMD(0x06, 0x04), - _INIT_DCS_CMD(0x07, 0x03), - _INIT_DCS_CMD(0x08, 0x03), - _INIT_DCS_CMD(0x09, 0x04), - _INIT_DCS_CMD(0x0A, 0x04), - _INIT_DCS_CMD(0x0B, 0x05), - _INIT_DCS_CMD(0x0C, 0x04), - _INIT_DCS_CMD(0x0D, 0x06), - _INIT_DCS_CMD(0x0E, 0x05), - _INIT_DCS_CMD(0x0F, 0x07), - _INIT_DCS_CMD(0x10, 0x04), - _INIT_DCS_CMD(0x11, 0x08), - _INIT_DCS_CMD(0x12, 0x05), - _INIT_DCS_CMD(0x13, 0x09), - _INIT_DCS_CMD(0x14, 0x05), - _INIT_DCS_CMD(0x15, 0x0A), - _INIT_DCS_CMD(0x16, 0x06), - _INIT_DCS_CMD(0x17, 0x0B), - _INIT_DCS_CMD(0x18, 0x05), - _INIT_DCS_CMD(0x19, 0x0C), - _INIT_DCS_CMD(0x1A, 0x06), - _INIT_DCS_CMD(0x1B, 0x0D), - _INIT_DCS_CMD(0x1C, 0x06), - _INIT_DCS_CMD(0x1D, 0x0E), - _INIT_DCS_CMD(0x1E, 0x07), - _INIT_DCS_CMD(0x1F, 0x0F), - _INIT_DCS_CMD(0x20, 0x06), - _INIT_DCS_CMD(0x21, 0x10), - _INIT_DCS_CMD(0x22, 0x07), - _INIT_DCS_CMD(0x23, 0x11), - _INIT_DCS_CMD(0x24, 0x07), - _INIT_DCS_CMD(0x25, 0x12), - _INIT_DCS_CMD(0x26, 0x08), - _INIT_DCS_CMD(0x27, 0x13), - _INIT_DCS_CMD(0x28, 0x07), - _INIT_DCS_CMD(0x29, 0x14), - _INIT_DCS_CMD(0x2A, 0x08), - _INIT_DCS_CMD(0x2B, 0x15), - _INIT_DCS_CMD(0x2C, 0x08), - _INIT_DCS_CMD(0x2D, 0x16), - _INIT_DCS_CMD(0x2E, 0x09), - _INIT_DCS_CMD(0x2F, 0x17), - _INIT_DCS_CMD(0x30, 0x08), - _INIT_DCS_CMD(0x31, 0x18), - _INIT_DCS_CMD(0x32, 0x09), - _INIT_DCS_CMD(0x33, 0x19), - _INIT_DCS_CMD(0x34, 0x09), - _INIT_DCS_CMD(0x35, 0x1A), - _INIT_DCS_CMD(0x36, 0x0A), - _INIT_DCS_CMD(0x37, 0x1B), - _INIT_DCS_CMD(0x38, 0x0A), - _INIT_DCS_CMD(0x39, 0x1C), - _INIT_DCS_CMD(0x3A, 0x0A), - _INIT_DCS_CMD(0x3B, 0x1D), - _INIT_DCS_CMD(0x3C, 0x0A), - _INIT_DCS_CMD(0x3D, 0x1E), - _INIT_DCS_CMD(0x3E, 0x0A), - _INIT_DCS_CMD(0x3F, 0x1F), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x04), - _INIT_DCS_CMD(0xBA, 0x01), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0E), - _INIT_DCS_CMD(0x02, 0x0C), - _INIT_DCS_CMD(0x20, 0x10), - _INIT_DCS_CMD(0x25, 0x16), - _INIT_DCS_CMD(0x26, 0xE0), - _INIT_DCS_CMD(0x27, 0x00), - _INIT_DCS_CMD(0x29, 0x71), - _INIT_DCS_CMD(0x2A, 0x46), - _INIT_DCS_CMD(0x2B, 0x1F), - _INIT_DCS_CMD(0x2D, 0xC7), - _INIT_DCS_CMD(0x31, 0x02), - _INIT_DCS_CMD(0x32, 0xDF), - _INIT_DCS_CMD(0x33, 0x5A), - _INIT_DCS_CMD(0x34, 0xC0), - _INIT_DCS_CMD(0x35, 0x5A), - _INIT_DCS_CMD(0x36, 0xC0), - _INIT_DCS_CMD(0x38, 0x65), - _INIT_DCS_CMD(0x80, 0x3E), - _INIT_DCS_CMD(0x81, 0xA0), - _INIT_DCS_CMD(0xB0, 0x01), - _INIT_DCS_CMD(0xB1, 0xCC), - _INIT_DCS_CMD(0xC0, 0x12), - _INIT_DCS_CMD(0xC2, 0xCC), - _INIT_DCS_CMD(0xC3, 0xCC), - _INIT_DCS_CMD(0xC4, 0xCC), - _INIT_DCS_CMD(0xC5, 0xCC), - _INIT_DCS_CMD(0xC6, 0xCC), - _INIT_DCS_CMD(0xC7, 0xCC), - _INIT_DCS_CMD(0xC8, 0xCC), - _INIT_DCS_CMD(0xC9, 0xCC), - _INIT_DCS_CMD(0x30, 0x00), - _INIT_DCS_CMD(0x00, 0x81), - _INIT_DCS_CMD(0x08, 0x02), - _INIT_DCS_CMD(0x09, 0x00), - _INIT_DCS_CMD(0x07, 0x21), - _INIT_DCS_CMD(0x04, 0x10), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x1E), - _INIT_DCS_CMD(0x60, 0x00), - _INIT_DCS_CMD(0x64, 0x00), - _INIT_DCS_CMD(0x6D, 0x00), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x0B), - _INIT_DCS_CMD(0xA6, 0x44), - _INIT_DCS_CMD(0xA7, 0xB6), - _INIT_DCS_CMD(0xA8, 0x03), - _INIT_DCS_CMD(0xA9, 0x03), - _INIT_DCS_CMD(0xAA, 0x51), - _INIT_DCS_CMD(0xAB, 0x51), - _INIT_DCS_CMD(0xAC, 0x04), - _INIT_DCS_CMD(0xBD, 0x92), - _INIT_DCS_CMD(0xBE, 0xA1), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x05), - _INIT_DCS_CMD(0x86, 0x87), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x06), - _INIT_DCS_CMD(0x92, 0x22), - - _INIT_DCS_CMD(0xFF, 0x98, 0x82, 0x00), - _INIT_DCS_CMD(0x11), - _INIT_DELAY_CMD(120), - _INIT_DCS_CMD(0x29), - _INIT_DELAY_CMD(20), - {}, -}; - static inline struct boe_panel *to_boe_panel(struct drm_panel *panel) { return container_of(panel, struct boe_panel, base); @@ -2135,34 +1795,6 @@ static const struct panel_desc starry_himax83102_j02_desc = { .lp11_before_reset = true, }; -static const struct drm_display_mode starry_ili9882t_default_mode = { - .clock = 165280, - .hdisplay = 1200, - .hsync_start = 1200 + 72, - .hsync_end = 1200 + 72 + 30, - .htotal = 1200 + 72 + 30 + 72, - .vdisplay = 1920, - .vsync_start = 1920 + 68, - .vsync_end = 1920 + 68 + 2, - .vtotal = 1920 + 68 + 2 + 10, - .type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, -}; - -static const struct panel_desc starry_ili9882t_desc = { - .modes = &starry_ili9882t_default_mode, - .bpc = 8, - .size = { - .width_mm = 141, - .height_mm = 226, - }, - .lanes = 4, - .format = MIPI_DSI_FMT_RGB888, - .mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | - MIPI_DSI_MODE_LPM, - .init_cmds = starry_ili9882t_init_cmd, - .lp11_before_reset = true, -}; - static int boe_panel_get_modes(struct drm_panel *panel, struct drm_connector *connector) { @@ -2339,9 +1971,6 @@ static const struct of_device_id boe_of_match[] = { { .compatible = "starry,himax83102-j02", .data = &starry_himax83102_j02_desc }, - { .compatible = "starry,ili9882t", - .data = &starry_ili9882t_desc - }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, boe_of_match); diff --git a/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c new file mode 100644 index 000000000000..93a40c2f1483 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-ilitek-ili9882t.c @@ -0,0 +1,759 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Panels based on the Ilitek ILI9882T display controller. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include