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