提交 d8b8eb82 编写于 作者: D Dave Airlie

Merge branch 'drm-rockchip-next-fixes-2016-01-22' of...

Merge branch 'drm-rockchip-next-fixes-2016-01-22' of https://github.com/markyzq/kernel-drm-rockchip into drm-fixes

Here are some fixes for drm/rockchip, these fixes base on drm-next.

These fixes works on my popmetal(rk3288) board.

About patch: drm/atomic-helper: Export framebuffer_changed()
Daniel Vetter ack for merging it through rockchip git trees, so framebuffer_changed() can be reused by drm/rockchip.

All others looks good, so I'd like you can land them.

* 'drm-rockchip-next-fixes-2016-01-22' of https://github.com/markyzq/kernel-drm-rockchip:
  drm/rockchip: respect CONFIG_DRM_FBDEV_EMULATION
  drm/rockchip: fix wrong pitch/size using on gem
  drm/rockchip: explain why we can't wait_for_vblanks
  drm/rockchip: don't wait for vblank if fb hasn't changed
  drm/atomic-helper: Export framebuffer_changed()
  drm/rockchip/dsi: fix handling mipi_dsi_pixel_format_to_bpp result
  drm/rockchip: vop: fix mask when updating interrupts
  drm/rockchip: cleanup unnecessary export symbol
  drm/rockchip: Don't build rockchip_drm_vop as modules
...@@ -946,9 +946,23 @@ static void wait_for_fences(struct drm_device *dev, ...@@ -946,9 +946,23 @@ static void wait_for_fences(struct drm_device *dev,
} }
} }
static bool framebuffer_changed(struct drm_device *dev, /**
struct drm_atomic_state *old_state, * drm_atomic_helper_framebuffer_changed - check if framebuffer has changed
struct drm_crtc *crtc) * @dev: DRM device
* @old_state: atomic state object with old state structures
* @crtc: DRM crtc
*
* Checks whether the framebuffer used for this CRTC changes as a result of
* the atomic update. This is useful for drivers which cannot use
* drm_atomic_helper_wait_for_vblanks() and need to reimplement its
* functionality.
*
* Returns:
* true if the framebuffer changed.
*/
bool drm_atomic_helper_framebuffer_changed(struct drm_device *dev,
struct drm_atomic_state *old_state,
struct drm_crtc *crtc)
{ {
struct drm_plane *plane; struct drm_plane *plane;
struct drm_plane_state *old_plane_state; struct drm_plane_state *old_plane_state;
...@@ -965,6 +979,7 @@ static bool framebuffer_changed(struct drm_device *dev, ...@@ -965,6 +979,7 @@ static bool framebuffer_changed(struct drm_device *dev,
return false; return false;
} }
EXPORT_SYMBOL(drm_atomic_helper_framebuffer_changed);
/** /**
* drm_atomic_helper_wait_for_vblanks - wait for vblank on crtcs * 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,7 +1014,8 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
if (old_state->legacy_cursor_update) if (old_state->legacy_cursor_update)
continue; continue;
if (!framebuffer_changed(dev, old_state, crtc)) if (!drm_atomic_helper_framebuffer_changed(dev,
old_state, crtc))
continue; continue;
ret = drm_crtc_vblank_get(crtc); ret = drm_crtc_vblank_get(crtc);
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
# Makefile for the drm device driver. This driver provides support for the # Makefile for the drm device driver. This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o rockchip_drm_fbdev.o \ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
rockchip_drm_gem.o rockchip_drm_gem.o rockchip_drm_vop.o
rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o rockchip_drm_vop.o \ obj-$(CONFIG_DRM_ROCKCHIP) += rockchipdrm.o rockchip_vop_reg.o
rockchip_vop_reg.o
...@@ -461,10 +461,11 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi) ...@@ -461,10 +461,11 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi)
static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi) static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi)
{ {
unsigned int bpp, i, pre; unsigned int i, pre;
unsigned long mpclk, pllref, tmp; unsigned long mpclk, pllref, tmp;
unsigned int m = 1, n = 1, target_mbps = 1000; unsigned int m = 1, n = 1, target_mbps = 1000;
unsigned int max_mbps = dptdin_map[ARRAY_SIZE(dptdin_map) - 1].max_mbps; unsigned int max_mbps = dptdin_map[ARRAY_SIZE(dptdin_map) - 1].max_mbps;
int bpp;
bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
if (bpp < 0) { if (bpp < 0) {
......
...@@ -55,14 +55,12 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev, ...@@ -55,14 +55,12 @@ int rockchip_drm_dma_attach_device(struct drm_device *drm_dev,
return arm_iommu_attach_device(dev, mapping); return arm_iommu_attach_device(dev, mapping);
} }
EXPORT_SYMBOL_GPL(rockchip_drm_dma_attach_device);
void rockchip_drm_dma_detach_device(struct drm_device *drm_dev, void rockchip_drm_dma_detach_device(struct drm_device *drm_dev,
struct device *dev) struct device *dev)
{ {
arm_iommu_detach_device(dev); arm_iommu_detach_device(dev);
} }
EXPORT_SYMBOL_GPL(rockchip_drm_dma_detach_device);
int rockchip_register_crtc_funcs(struct drm_crtc *crtc, int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
const struct rockchip_crtc_funcs *crtc_funcs) const struct rockchip_crtc_funcs *crtc_funcs)
...@@ -77,7 +75,6 @@ int rockchip_register_crtc_funcs(struct drm_crtc *crtc, ...@@ -77,7 +75,6 @@ int rockchip_register_crtc_funcs(struct drm_crtc *crtc,
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(rockchip_register_crtc_funcs);
void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc) void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc)
{ {
...@@ -89,7 +86,6 @@ void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc) ...@@ -89,7 +86,6 @@ void rockchip_unregister_crtc_funcs(struct drm_crtc *crtc)
priv->crtc_funcs[pipe] = NULL; priv->crtc_funcs[pipe] = NULL;
} }
EXPORT_SYMBOL_GPL(rockchip_unregister_crtc_funcs);
static struct drm_crtc *rockchip_crtc_from_pipe(struct drm_device *drm, static struct drm_crtc *rockchip_crtc_from_pipe(struct drm_device *drm,
int pipe) int pipe)
......
...@@ -39,7 +39,6 @@ struct drm_gem_object *rockchip_fb_get_gem_obj(struct drm_framebuffer *fb, ...@@ -39,7 +39,6 @@ struct drm_gem_object *rockchip_fb_get_gem_obj(struct drm_framebuffer *fb,
return rk_fb->obj[plane]; return rk_fb->obj[plane];
} }
EXPORT_SYMBOL_GPL(rockchip_fb_get_gem_obj);
static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb) static void rockchip_drm_fb_destroy(struct drm_framebuffer *fb)
{ {
...@@ -177,8 +176,23 @@ static void rockchip_crtc_wait_for_update(struct drm_crtc *crtc) ...@@ -177,8 +176,23 @@ static void rockchip_crtc_wait_for_update(struct drm_crtc *crtc)
crtc_funcs->wait_for_update(crtc); crtc_funcs->wait_for_update(crtc);
} }
/*
* We can't use drm_atomic_helper_wait_for_vblanks() because rk3288 and rk3066
* have hardware counters for neither vblanks nor scanlines, which results in
* a race where:
* | <-- HW vsync irq and reg take effect
* plane_commit --> |
* get_vblank and wait --> |
* | <-- handle_vblank, vblank->count + 1
* cleanup_fb --> |
* iommu crash --> |
* | <-- HW vsync irq and reg take effect
*
* This function is equivalent but uses rockchip_crtc_wait_for_update() instead
* of waiting for vblank_count to change.
*/
static void static void
rockchip_atomic_wait_for_complete(struct drm_atomic_state *old_state) rockchip_atomic_wait_for_complete(struct drm_device *dev, struct drm_atomic_state *old_state)
{ {
struct drm_crtc_state *old_crtc_state; struct drm_crtc_state *old_crtc_state;
struct drm_crtc *crtc; struct drm_crtc *crtc;
...@@ -194,6 +208,10 @@ rockchip_atomic_wait_for_complete(struct drm_atomic_state *old_state) ...@@ -194,6 +208,10 @@ rockchip_atomic_wait_for_complete(struct drm_atomic_state *old_state)
if (!crtc->state->active) if (!crtc->state->active)
continue; continue;
if (!drm_atomic_helper_framebuffer_changed(dev,
old_state, crtc))
continue;
ret = drm_crtc_vblank_get(crtc); ret = drm_crtc_vblank_get(crtc);
if (ret != 0) if (ret != 0)
continue; continue;
...@@ -241,7 +259,7 @@ rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit) ...@@ -241,7 +259,7 @@ rockchip_atomic_commit_complete(struct rockchip_atomic_commit *commit)
drm_atomic_helper_commit_planes(dev, state, true); drm_atomic_helper_commit_planes(dev, state, true);
rockchip_atomic_wait_for_complete(state); rockchip_atomic_wait_for_complete(dev, state);
drm_atomic_helper_cleanup_planes(dev, state); drm_atomic_helper_cleanup_planes(dev, state);
......
...@@ -15,7 +15,18 @@ ...@@ -15,7 +15,18 @@
#ifndef _ROCKCHIP_DRM_FBDEV_H #ifndef _ROCKCHIP_DRM_FBDEV_H
#define _ROCKCHIP_DRM_FBDEV_H #define _ROCKCHIP_DRM_FBDEV_H
#ifdef CONFIG_DRM_FBDEV_EMULATION
int rockchip_drm_fbdev_init(struct drm_device *dev); int rockchip_drm_fbdev_init(struct drm_device *dev);
void rockchip_drm_fbdev_fini(struct drm_device *dev); void rockchip_drm_fbdev_fini(struct drm_device *dev);
#else
static inline int rockchip_drm_fbdev_init(struct drm_device *dev)
{
return 0;
}
static inline void rockchip_drm_fbdev_fini(struct drm_device *dev)
{
}
#endif
#endif /* _ROCKCHIP_DRM_FBDEV_H */ #endif /* _ROCKCHIP_DRM_FBDEV_H */
...@@ -234,13 +234,8 @@ int rockchip_gem_dumb_create(struct drm_file *file_priv, ...@@ -234,13 +234,8 @@ int rockchip_gem_dumb_create(struct drm_file *file_priv,
/* /*
* align to 64 bytes since Mali requires it. * align to 64 bytes since Mali requires it.
*/ */
min_pitch = ALIGN(min_pitch, 64); args->pitch = ALIGN(min_pitch, 64);
args->size = args->pitch * args->height;
if (args->pitch < min_pitch)
args->pitch = min_pitch;
if (args->size < args->pitch * args->height)
args->size = args->pitch * args->height;
rk_obj = rockchip_gem_create_with_handle(file_priv, dev, args->size, rk_obj = rockchip_gem_create_with_handle(file_priv, dev, args->size,
&args->handle); &args->handle);
......
...@@ -43,8 +43,8 @@ ...@@ -43,8 +43,8 @@
#define REG_SET(x, base, reg, v, mode) \ #define REG_SET(x, base, reg, v, mode) \
__REG_SET_##mode(x, base + reg.offset, reg.mask, reg.shift, v) __REG_SET_##mode(x, base + reg.offset, reg.mask, reg.shift, v)
#define REG_SET_MASK(x, base, reg, v, mode) \ #define REG_SET_MASK(x, base, reg, mask, v, mode) \
__REG_SET_##mode(x, base + reg.offset, reg.mask, reg.shift, v) __REG_SET_##mode(x, base + reg.offset, mask, reg.shift, v)
#define VOP_WIN_SET(x, win, name, v) \ #define VOP_WIN_SET(x, win, name, v) \
REG_SET(x, win->base, win->phy->name, v, RELAXED) REG_SET(x, win->base, win->phy->name, v, RELAXED)
...@@ -58,16 +58,18 @@ ...@@ -58,16 +58,18 @@
#define VOP_INTR_GET(vop, name) \ #define VOP_INTR_GET(vop, name) \
vop_read_reg(vop, 0, &vop->data->ctrl->name) vop_read_reg(vop, 0, &vop->data->ctrl->name)
#define VOP_INTR_SET(vop, name, v) \ #define VOP_INTR_SET(vop, name, mask, v) \
REG_SET(vop, 0, vop->data->intr->name, v, NORMAL) REG_SET_MASK(vop, 0, vop->data->intr->name, mask, v, NORMAL)
#define VOP_INTR_SET_TYPE(vop, name, type, v) \ #define VOP_INTR_SET_TYPE(vop, name, type, v) \
do { \ do { \
int i, reg = 0; \ int i, reg = 0, mask = 0; \
for (i = 0; i < vop->data->intr->nintrs; i++) { \ for (i = 0; i < vop->data->intr->nintrs; i++) { \
if (vop->data->intr->intrs[i] & type) \ if (vop->data->intr->intrs[i] & type) { \
reg |= (v) << i; \ reg |= (v) << i; \
mask |= 1 << i; \
} \
} \ } \
VOP_INTR_SET(vop, name, reg); \ VOP_INTR_SET(vop, name, mask, reg); \
} while (0) } while (0)
#define VOP_INTR_GET_TYPE(vop, name, type) \ #define VOP_INTR_GET_TYPE(vop, name, type) \
vop_get_intr_type(vop, &vop->data->intr->name, type) vop_get_intr_type(vop, &vop->data->intr->name, type)
......
...@@ -42,6 +42,10 @@ int drm_atomic_helper_commit(struct drm_device *dev, ...@@ -42,6 +42,10 @@ int drm_atomic_helper_commit(struct drm_device *dev,
struct drm_atomic_state *state, struct drm_atomic_state *state,
bool async); bool async);
bool drm_atomic_helper_framebuffer_changed(struct drm_device *dev,
struct drm_atomic_state *old_state,
struct drm_crtc *crtc);
void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, void drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
struct drm_atomic_state *old_state); struct drm_atomic_state *old_state);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册