diff options
| -rw-r--r-- | drivers/gpu/drm/drm_atomic_helper.c | 24 | ||||
| -rw-r--r-- | drivers/gpu/drm/rockchip/Makefile | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 24 | ||||
| -rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_fbdev.h | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 9 | ||||
| -rw-r--r-- | drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 16 | ||||
| -rw-r--r-- | include/drm/drm_atomic_helper.h | 4 |
9 files changed, 73 insertions, 30 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 57cccd68ca52..7c523060a076 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c | |||
| @@ -946,9 +946,23 @@ static void wait_for_fences(struct drm_device *dev, | |||
| 946 | } | 946 | } |
| 947 | } | 947 | } |
| 948 | 948 | ||
| 949 | static bool framebuffer_changed(struct drm_device *dev, | 949 | /** |
| 950 | struct drm_atomic_state *old_state, | 950 | * drm_atomic_helper_framebuffer_changed - check if framebuffer has changed |
| 951 | struct drm_crtc *crtc) | 951 | * @dev: DRM device |
| 952 | * @old_state: atomic state object with old state structures | ||
| 953 | * @crtc: DRM crtc | ||
| 954 | * | ||
| 955 | * Checks whether the framebuffer used for this CRTC changes as a result of | ||
| 956 | * the atomic update. This is useful for drivers which cannot use | ||
| 957 | * drm_atomic_helper_wait_for_vblanks() and need to reimplement its | ||
| 958 | * functionality. | ||
| 959 | * | ||
| 960 | * Returns: | ||
| 961 | * true if the framebuffer changed. | ||
| 962 | */ | ||
| 963 | bool drm_atomic_helper_framebuffer_changed(struct drm_device *dev, | ||
| 964 | struct drm_atomic_state *old_state, | ||
| 965 | struct drm_crtc *crtc) | ||
| 952 | { | 966 | { |
| 953 | struct drm_plane *plane; | 967 | struct drm_plane *plane; |
| 954 | struct drm_plane_state *old_plane_state; | 968 | struct drm_plane_state *old_plane_state; |
| @@ -965,6 +979,7 @@ static bool framebuffer_changed(struct drm_device *dev, | |||
| 965 | 979 | ||
| 966 | return false; | 980 | return false; |
| 967 | } | 981 | } |
| 982 | EXPORT_SYMBOL(drm_atomic_helper_framebuffer_changed); | ||
| 968 | 983 | ||
| 969 | /** | 984 | /** |
| 970 | * drm_atomic_helper_wait_for_vblanks - wait for vblank on crtcs | 985 | * drm_atomic_helper_wait_for_vblanks - wait for vblank on crtcs |
| @@ -999,7 +1014,8 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, | |||
| 999 | if (old_state->legacy_cursor_update) | 1014 | if (old_state->legacy_cursor_update) |
| 1000 | continue; | 1015 | continue; |
| 1001 | 1016 | ||
| 1002 | if (!framebuffer_changed(dev, old_state, crtc)) | 1017 | if (!drm_atomic_helper_framebuffer_changed(dev, |
| 1018 | old_state, crtc)) | ||
| 1003 | continue; | 1019 | continue; |
| 1004 | 1020 | ||
| 1005 | ret = drm_crtc_vblank_get(crtc); | 1021 | ret = drm_crtc_vblank_get(crtc); |
diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile index d1dc0f7b01db..f6a809afceec 100644 --- a/drivers/gpu/drm/rockchip/Makefile +++ b/drivers/gpu/drm/rockchip/Makefile | |||
| @@ -2,11 +2,11 @@ | |||
| 2 | # Makefile for the drm device driver. This driver provides support for the | 2 | # Makefile for the drm device driver. This driver provides support for the |
| 3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. | 3 | # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. |
| 4 | 4 | ||
| 5 | rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o rockchip_drm_fbdev.o \ | 5 | rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \ |
| 6 | rockchip_drm_gem.o | 6 | rockchip_drm_gem.o rockchip_drm_vop.o |
| 7 | rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o | ||
| 7 | 8 | ||
| 8 | obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o | 9 | obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o |
| 9 | obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o | 10 | obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o |
| 10 | 11 | ||
| 11 | obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o rockchip_drm_vop.o \ | 12 | obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o rockchip_vop_reg.o |
| 12 | rockchip_vop_reg.o | ||
diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c index 7bfe243c6173..f8f8f29fb7c3 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c | |||
| @@ -461,10 +461,11 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi) | |||
| 461 | 461 | ||
| 462 | static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi) | 462 | static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi) |
| 463 | { | 463 | { |
| 464 | unsigned int bpp, i, pre; | 464 | unsigned int i, pre; |
| 465 | unsigned long mpclk, pllref, tmp; | 465 | unsigned long mpclk, pllref, tmp; |
| 466 | unsigned int m = 1, n = 1, target_mbps = 1000; | 466 | unsigned int m = 1, n = 1, target_mbps = 1000; |
| 467 | unsigned int max_mbps = dptdin_map[ARRAY_SIZE(dptdin_map) - 1].max_mbps; | 467 | unsigned int max_mbps = dptdin_map[ARRAY_SIZE(dptdin_map) - 1].max_mbps; |
| 468 | int bpp; | ||
| 468 | 469 | ||
| 469 | bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); | 470 | bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); |
| 470 | if (bpp < 0) { | 471 | if (bpp < 0) { |
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index 8397d1b62ef9..a0d51ccb6ea4 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c | |||
| @@ -55,14 +55,12 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev, | |||
| 55 | 55 | ||
| 56 | return arm_iommu_attach_device(dev, mapping); | 56 | return arm_iommu_attach_device(dev, mapping); |
| 57 | } | 57 | } |
| 58 | EXPORT_SYMBOL_GPL(rockchip_drm_dma_attach_device); | ||
| 59 | 58 | ||
| 60 | void rockchip_drm_dma_detach_device(struct drm_device *drm_dev, | 59 | void rockchip_drm_dma_detach_device(struct drm_device *drm_dev, |
| 61 | struct device *dev) | 60 | struct device *dev) |
| 62 | { | 61 | { |
| 63 | arm_iommu_detach_device(dev); | 62 | arm_iommu_detach_device(dev); |
| 64 | } | 63 | } |
| 65 | EXPORT_SYMBOL_GPL(rockchip_drm_dma_detach_device); | ||
| 66 | 64 | ||
| 67 | int rockchip_register_crtc_funcs(struct drm_crtc *crtc, | 65 | int rockchip_register_crtc_funcs(struct drm_crtc *crtc, |
| 68 | const struct rockchip_crtc_funcs *crtc_funcs) | 66 | const struct rockchip_crtc_funcs *crtc_funcs) |
| @@ -77,7 +75,6 @@ int rockchip_register_crtc_funcs(struct drm_crtc *crtc, | |||
| 77 | 75 | ||
| 78 | return 0; | 76 | return 0; |
| 79 | } | 77 | } |
| 80 | EXPORT_SYMBOL_GPL(rockchip_register_crtc_funcs); | ||
| 81 | 78 | ||
| 82 | void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc) | 79 | void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc) |
| 83 | { | 80 | { |
| @@ -89,7 +86,6 @@ void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc) | |||
| 89 | 86 | ||
| 90 | priv->crtc_funcs[pipe] = NULL; | 87 | priv->crtc_funcs[pipe] = NULL; |
| 91 | } | 88 | } |
| 92 | EXPORT_SYMBOL_GPL(rockchip_unregister_crtc_funcs); | ||
| 93 | 89 | ||
| 94 | static struct drm_crtc *rockchip_crtc_from_pipe(struct drm_device *drm, | 90 | static struct drm_crtc *rockchip_crtc_from_pipe(struct drm_device *drm, |
| 95 | int pipe) | 91 | int pipe) |
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c index f7844883cb76..3b8f652698f8 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fb.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fb.c | |||
| @@ -39,7 +39,6 @@ struct drm_gem_object *rockchip_fb_get_gem_obj(struct drm_framebuffer *fb, | |||
| 39 | 39 | ||
| 40 | return rk_fb->obj[plane]; | 40 | return rk_fb->obj[plane]; |
| 41 | } | 41 | } |
| 42 | EXPORT_SYMBOL_GPL(rockchip_fb_get_gem_obj); | ||
| 43 | 42 | ||
| 44 | static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb) | 43 | static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb) |
| 45 | { | 44 | { |
| @@ -177,8 +176,23 @@ static void rockchip_crtc_wait_for_update(struct drm_crtc *crtc) | |||
| 177 | crtc_funcs->wait_for_update(crtc); | 176 | crtc_funcs->wait_for_update(crtc); |
| 178 | } | 177 | } |
| 179 | 178 | ||
| 179 | /* | ||
| 180 | * We can't use drm_atomic_helper_wait_for_vblanks() because rk3288 and rk3066 | ||
| 181 | * have hardware counters for neither vblanks nor scanlines, which results in | ||
| 182 | * a race where: | ||
| 183 | * | <-- HW vsync irq and reg take effect | ||
| 184 | * plane_commit --> | | ||
| 185 | * get_vblank and wait --> | | ||
| 186 | * | <-- handle_vblank, vblank->count + 1 | ||
| 187 | * cleanup_fb --> | | ||
| 188 | * iommu crash --> | | ||
| 189 | * | <-- HW vsync irq and reg take effect | ||
| 190 | * | ||
| 191 | * This function is equivalent but uses rockchip_crtc_wait_for_update() instead | ||
| 192 | * of waiting for vblank_count to change. | ||
| 193 | */ | ||
| 180 | static void | 194 | static void |
| 181 | rockchip_atomic_wait_for_complete(struct drm_atomic_state *old_state) | 195 | rockchip_atomic_wait_for_complete(struct drm_device *dev, struct drm_atomic_state *old_state) |
| 182 | { | 196 | { |
| 183 | struct drm_crtc_state *old_crtc_state; | 197 | struct drm_crtc_state *old_crtc_state; |
| 184 | struct drm_crtc *crtc; | 198 | struct drm_crtc *crtc; |
| @@ -194,6 +208,10 @@ rockchip_atomic_wait_for_complete(struct drm_atomic_state *old_state) | |||
| 194 | if (!crtc->state->active) | 208 | if (!crtc->state->active) |
| 195 | continue; | 209 | continue; |
| 196 | 210 | ||
| 211 | if (!drm_atomic_helper_framebuffer_changed(dev, | ||
| 212 | old_state, crtc)) | ||
| 213 | continue; | ||
| 214 | |||
| 197 | ret = drm_crtc_vblank_get(crtc); | 215 | ret = drm_crtc_vblank_get(crtc); |
| 198 | if (ret != 0) | 216 | if (ret != 0) |
| 199 | continue; | 217 | continue; |
| @@ -241,7 +259,7 @@ rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit) | |||
| 241 | 259 | ||
| 242 | drm_atomic_helper_commit_planes(dev, state, true); | 260 | drm_atomic_helper_commit_planes(dev, state, true); |
| 243 | 261 | ||
| 244 | rockchip_atomic_wait_for_complete(state); | 262 | rockchip_atomic_wait_for_complete(dev, state); |
| 245 | 263 | ||
| 246 | drm_atomic_helper_cleanup_planes(dev, state); | 264 | drm_atomic_helper_cleanup_planes(dev, state); |
| 247 | 265 | ||
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.h b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.h index 50432e9b5b37..73718c5f5bbf 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_fbdev.h | |||
| @@ -15,7 +15,18 @@ | |||
| 15 | #ifndef _ROCKCHIP_DRM_FBDEV_H | 15 | #ifndef _ROCKCHIP_DRM_FBDEV_H |
| 16 | #define _ROCKCHIP_DRM_FBDEV_H | 16 | #define _ROCKCHIP_DRM_FBDEV_H |
| 17 | 17 | ||
| 18 | #ifdef CONFIG_DRM_FBDEV_EMULATION | ||
| 18 | int rockchip_drm_fbdev_init(struct drm_device *dev); | 19 | int rockchip_drm_fbdev_init(struct drm_device *dev); |
| 19 | void rockchip_drm_fbdev_fini(struct drm_device *dev); | 20 | void rockchip_drm_fbdev_fini(struct drm_device *dev); |
| 21 | #else | ||
| 22 | static inline int rockchip_drm_fbdev_init(struct drm_device *dev) | ||
| 23 | { | ||
| 24 | return 0; | ||
| 25 | } | ||
| 26 | |||
| 27 | static inline void rockchip_drm_fbdev_fini(struct drm_device *dev) | ||
| 28 | { | ||
| 29 | } | ||
| 30 | #endif | ||
| 20 | 31 | ||
| 21 | #endif /* _ROCKCHIP_DRM_FBDEV_H */ | 32 | #endif /* _ROCKCHIP_DRM_FBDEV_H */ |
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c index d908321b94ce..18e07338c6e5 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_gem.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_gem.c | |||
| @@ -234,13 +234,8 @@ int rockchip_gem_dumb_create(struct drm_file *file_priv, | |||
| 234 | /* | 234 | /* |
| 235 | * align to 64 bytes since Mali requires it. | 235 | * align to 64 bytes since Mali requires it. |
| 236 | */ | 236 | */ |
| 237 | min_pitch = ALIGN(min_pitch, 64); | 237 | args->pitch = ALIGN(min_pitch, 64); |
| 238 | 238 | args->size = args->pitch * args->height; | |
| 239 | if (args->pitch < min_pitch) | ||
| 240 | args->pitch = min_pitch; | ||
| 241 | |||
| 242 | if (args->size < args->pitch * args->height) | ||
| 243 | args->size = args->pitch * args->height; | ||
| 244 | 239 | ||
| 245 | rk_obj = rockchip_gem_create_with_handle(file_priv, dev, args->size, | 240 | rk_obj = rockchip_gem_create_with_handle(file_priv, dev, args->size, |
| 246 | &args->handle); | 241 | &args->handle); |
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 46c2a8dfd8aa..fd370548d7d7 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c | |||
| @@ -43,8 +43,8 @@ | |||
| 43 | 43 | ||
| 44 | #define REG_SET(x, base, reg, v, mode) \ | 44 | #define REG_SET(x, base, reg, v, mode) \ |
| 45 | __REG_SET_##mode(x, base + reg.offset, reg.mask, reg.shift, v) | 45 | __REG_SET_##mode(x, base + reg.offset, reg.mask, reg.shift, v) |
| 46 | #define REG_SET_MASK(x, base, reg, v, mode) \ | 46 | #define REG_SET_MASK(x, base, reg, mask, v, mode) \ |
| 47 | __REG_SET_##mode(x, base + reg.offset, reg.mask, reg.shift, v) | 47 | __REG_SET_##mode(x, base + reg.offset, mask, reg.shift, v) |
| 48 | 48 | ||
| 49 | #define VOP_WIN_SET(x, win, name, v) \ | 49 | #define VOP_WIN_SET(x, win, name, v) \ |
| 50 | REG_SET(x, win->base, win->phy->name, v, RELAXED) | 50 | REG_SET(x, win->base, win->phy->name, v, RELAXED) |
| @@ -58,16 +58,18 @@ | |||
| 58 | #define VOP_INTR_GET(vop, name) \ | 58 | #define VOP_INTR_GET(vop, name) \ |
| 59 | vop_read_reg(vop, 0, &vop->data->ctrl->name) | 59 | vop_read_reg(vop, 0, &vop->data->ctrl->name) |
| 60 | 60 | ||
| 61 | #define VOP_INTR_SET(vop, name, v) \ | 61 | #define VOP_INTR_SET(vop, name, mask, v) \ |
| 62 | REG_SET(vop, 0, vop->data->intr->name, v, NORMAL) | 62 | REG_SET_MASK(vop, 0, vop->data->intr->name, mask, v, NORMAL) |
| 63 | #define VOP_INTR_SET_TYPE(vop, name, type, v) \ | 63 | #define VOP_INTR_SET_TYPE(vop, name, type, v) \ |
| 64 | do { \ | 64 | do { \ |
| 65 | int i, reg = 0; \ | 65 | int i, reg = 0, mask = 0; \ |
| 66 | for (i = 0; i < vop->data->intr->nintrs; i++) { \ | 66 | for (i = 0; i < vop->data->intr->nintrs; i++) { \ |
| 67 | if (vop->data->intr->intrs[i] & type) \ | 67 | if (vop->data->intr->intrs[i] & type) { \ |
| 68 | reg |= (v) << i; \ | 68 | reg |= (v) << i; \ |
| 69 | mask |= 1 << i; \ | ||
| 70 | } \ | ||
| 69 | } \ | 71 | } \ |
| 70 | VOP_INTR_SET(vop, name, reg); \ | 72 | VOP_INTR_SET(vop, name, mask, reg); \ |
| 71 | } while (0) | 73 | } while (0) |
| 72 | #define VOP_INTR_GET_TYPE(vop, name, type) \ | 74 | #define VOP_INTR_GET_TYPE(vop, name, type) \ |
| 73 | vop_get_intr_type(vop, &vop->data->intr->name, type) | 75 | vop_get_intr_type(vop, &vop->data->intr->name, type) |
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h index 89d008dc08e2..fe5efada9d68 100644 --- a/include/drm/drm_atomic_helper.h +++ b/include/drm/drm_atomic_helper.h | |||
| @@ -42,6 +42,10 @@ int drm_atomic_helper_commit(struct drm_device *dev, | |||
| 42 | struct drm_atomic_state *state, | 42 | struct drm_atomic_state *state, |
| 43 | bool async); | 43 | bool async); |
| 44 | 44 | ||
| 45 | bool drm_atomic_helper_framebuffer_changed(struct drm_device *dev, | ||
| 46 | struct drm_atomic_state *old_state, | ||
| 47 | struct drm_crtc *crtc); | ||
| 48 | |||
| 45 | void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, | 49 | void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, |
| 46 | struct drm_atomic_state *old_state); | 50 | struct drm_atomic_state *old_state); |
| 47 | 51 | ||
