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; }