From de1bd7d7910455e6d5f988c2729b886232b9d4de Mon Sep 17 00:00:00 2001 From: Sandy Huang Date: Tue, 10 Apr 2018 16:22:59 +0800 Subject: [PATCH] drm/rockchip: get kvaddr for some SPI panel some low solutation SPI panel, the display content should be send through the SPI interface, so add to get the kernel virtual address, which can be accessed by cpu and SPI interface. Change-Id: I9823162e682819309bf61d3b132eb452b73fdd3a Signed-off-by: Sandy Huang --- drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 1 + drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 1 + drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 13 +++++++++++++ drivers/gpu/drm/rockchip/rockchip_drm_fb.h | 1 + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 8 ++++++++ 5 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index f50add350628..40eb85456cb2 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -249,6 +249,7 @@ static int init_loader_memory(struct drm_device *drm_dev) if (!logo) return -ENOMEM; + logo->kvaddr = phys_to_virt(start); nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT; pages = kmalloc_array(nr_pages, sizeof(*pages), GFP_KERNEL); if (!pages) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index cd1500604f36..2bcee548734f 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -151,6 +151,7 @@ struct rockchip_logo { struct sg_table *sgt; struct drm_mm_node mm; dma_addr_t dma_addr; + void *kvaddr; phys_addr_t start; phys_addr_t size; size_t iommu_map_size; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c index b8a011977e71..ee50aef6b16c 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c @@ -32,6 +32,7 @@ struct rockchip_drm_fb { struct drm_framebuffer fb; dma_addr_t dma_addr[ROCKCHIP_MAX_FB_BUFFER]; + void *kvaddr[ROCKCHIP_MAX_FB_BUFFER]; struct drm_gem_object *obj[ROCKCHIP_MAX_FB_BUFFER]; struct rockchip_logo *logo; }; @@ -54,6 +55,16 @@ dma_addr_t rockchip_fb_get_dma_addr(struct drm_framebuffer *fb, return rk_fb->dma_addr[plane]; } +void *rockchip_fb_get_kvaddr(struct drm_framebuffer *fb, unsigned int plane) +{ + struct rockchip_drm_fb *rk_fb = to_rockchip_fb(fb); + + if (WARN_ON(plane >= ROCKCHIP_MAX_FB_BUFFER)) + return 0; + + return rk_fb->kvaddr[plane]; +} + static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb) { struct rockchip_drm_fb *rockchip_fb = to_rockchip_fb(fb); @@ -123,10 +134,12 @@ rockchip_fb_alloc(struct drm_device *dev, struct drm_mode_fb_cmd2 *mode_cmd, for (i = 0; i < num_planes; i++) { rk_obj = to_rockchip_obj(obj[i]); rockchip_fb->dma_addr[i] = rk_obj->dma_addr; + rockchip_fb->kvaddr[i] = rk_obj->kvaddr; } #ifndef MODULE } else if (logo) { rockchip_fb->dma_addr[0] = logo->dma_addr; + rockchip_fb->kvaddr[0] = logo->kvaddr; rockchip_fb->logo = logo; logo->count++; #endif diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.h b/drivers/gpu/drm/rockchip/rockchip_drm_fb.h index addd06c70393..ea96bf359b2a 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.h @@ -31,6 +31,7 @@ rockchip_fb_alloc(struct drm_device *dev, struct drm_mode_fb_cmd2 *mode_cmd, dma_addr_t rockchip_fb_get_dma_addr(struct drm_framebuffer *fb, unsigned int plane); +void *rockchip_fb_get_kvaddr(struct drm_framebuffer *fb, unsigned int plane); #ifdef CONFIG_ARM_ROCKCHIP_DMC_DEVFREQ int rockchip_dmcfreq_vop_bandwidth_request(struct devfreq *devfreq, diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 70c7a3e1bee7..6f5fd511e85f 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -157,6 +157,7 @@ struct vop_plane_state { struct drm_rect dest; dma_addr_t yrgb_mst; dma_addr_t uv_mst; + void *yrgb_kvaddr; const uint32_t *y2r_table; const uint32_t *r2r_table; const uint32_t *r2y_table; @@ -1438,6 +1439,7 @@ static int vop_plane_atomic_check(struct drm_plane *plane, DRM_PLANE_HELPER_NO_SCALING; unsigned long offset; dma_addr_t dma_addr; + void *kvaddr; u16 vdisplay; crtc = crtc ? crtc : plane->state->crtc; @@ -1514,7 +1516,9 @@ static int vop_plane_atomic_check(struct drm_plane *plane, offset += (src->y1 >> 16) * fb->pitches[0]; dma_addr = rockchip_fb_get_dma_addr(fb, 0); + kvaddr = rockchip_fb_get_kvaddr(fb, 0); vop_plane_state->yrgb_mst = dma_addr + offset + fb->offsets[0]; + vop_plane_state->yrgb_kvaddr = kvaddr + offset + fb->offsets[0]; if (is_yuv_support(fb->pixel_format)) { int hsub = drm_format_horz_chroma_subsampling(fb->pixel_format); int vsub = drm_format_vert_chroma_subsampling(fb->pixel_format); @@ -1697,6 +1701,10 @@ static void vop_plane_atomic_update(struct drm_plane *plane, VOP_WIN_SET(vop, win, enable, 1); VOP_WIN_SET(vop, win, gate, 1); spin_unlock(&vop->reg_lock); + /* + * spi interface(vop_plane_state->yrgb_kvaddr, fb->pixel_format, + * actual_w, actual_h) + */ vop->is_iommu_needed = true; }