Commit 049ec1b5 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'drm-fixes-for-v4.7-rc2' of git://people.freedesktop.org/~airlied/linux

Pull drm fixes from Dave Airlie:
 "A bunch of ARM drivers got into the fixes vibe this time around, so
  this contains a bunch of fixes for imx, atmel hlcdc, arm hdlcd (only
  so many combos of hlcd), mediatek and omap drm.

  Other than that there is one mgag200 fix and a few core drm regression
  fixes"

* tag 'drm-fixes-for-v4.7-rc2' of git://people.freedesktop.org/~airlied/linux: (34 commits)
  drm/omap: fix unused variable warning.
  drm: hdlcd: Add information about the underlying framebuffers in debugfs
  drm: hdlcd: Cleanup the atomic plane operations
  drm/hdlcd: Fix up crtc_state->event handling
  drm: hdlcd: Revamp runtime power management
  drm/mediatek: mtk_dsi: Remove spurious drm_connector_unregister
  drm/mediatek: mtk_dpi: remove invalid error message
  drm: atmel-hlcdc: fix a NULL check
  drm: atmel-hlcdc: fix atmel_hlcdc_crtc_reset() implementation
  drm/mgag200: Black screen fix for G200e rev 4
  drm: Wrap direct calls to driver->gem_free_object from CMA
  drm: fix fb refcount issue with atomic modesetting
  drm: make drm_atomic_set_mode_prop_for_crtc() more reliable
  drm/sti: remove extra mode fixup
  drm: add missing drm_mode_set_crtcinfo call
  drm/omap: include gpio/consumer.h where needed
  drm/omap: include linux/seq_file.h where needed
  Revert "drm/omap: no need to select OMAP2_DSS"
  drm/omap: Remove regulator API abuse
  OMAPDSS: HDMI5: Change DDC timings
  ...
parents f2c6b9e4 ab3ab684
...@@ -62,6 +62,7 @@ Required properties: ...@@ -62,6 +62,7 @@ Required properties:
display-timings are used instead. display-timings are used instead.
Optional properties (required if display-timings are used): Optional properties (required if display-timings are used):
- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
- display-timings : A node that describes the display timings as defined in - display-timings : A node that describes the display timings as defined in
Documentation/devicetree/bindings/display/display-timing.txt. Documentation/devicetree/bindings/display/display-timing.txt.
- fsl,data-mapping : should be "spwg" or "jeida" - fsl,data-mapping : should be "spwg" or "jeida"
......
...@@ -33,8 +33,17 @@ ...@@ -33,8 +33,17 @@
* *
*/ */
static void hdlcd_crtc_cleanup(struct drm_crtc *crtc)
{
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
/* stop the controller on cleanup */
hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
drm_crtc_cleanup(crtc);
}
static const struct drm_crtc_funcs hdlcd_crtc_funcs = { static const struct drm_crtc_funcs hdlcd_crtc_funcs = {
.destroy = drm_crtc_cleanup, .destroy = hdlcd_crtc_cleanup,
.set_config = drm_atomic_helper_set_config, .set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip, .page_flip = drm_atomic_helper_page_flip,
.reset = drm_atomic_helper_crtc_reset, .reset = drm_atomic_helper_crtc_reset,
...@@ -97,7 +106,7 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc) ...@@ -97,7 +106,7 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
struct drm_display_mode *m = &crtc->state->adjusted_mode; struct drm_display_mode *m = &crtc->state->adjusted_mode;
struct videomode vm; struct videomode vm;
unsigned int polarities, line_length, err; unsigned int polarities, err;
vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay; vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay;
vm.vback_porch = m->crtc_vtotal - m->crtc_vsync_end; vm.vback_porch = m->crtc_vtotal - m->crtc_vsync_end;
...@@ -113,23 +122,18 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc) ...@@ -113,23 +122,18 @@ static void hdlcd_crtc_mode_set_nofb(struct drm_crtc *crtc)
if (m->flags & DRM_MODE_FLAG_PVSYNC) if (m->flags & DRM_MODE_FLAG_PVSYNC)
polarities |= HDLCD_POLARITY_VSYNC; polarities |= HDLCD_POLARITY_VSYNC;
line_length = crtc->primary->state->fb->pitches[0];
/* Allow max number of outstanding requests and largest burst size */ /* Allow max number of outstanding requests and largest burst size */
hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS, hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS,
HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16); HDLCD_BUS_MAX_OUTSTAND | HDLCD_BUS_BURST_16);
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, line_length);
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, line_length);
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, m->crtc_vdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_DATA, m->crtc_vdisplay - 1); hdlcd_write(hdlcd, HDLCD_REG_V_DATA, m->crtc_vdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH, vm.vback_porch - 1); hdlcd_write(hdlcd, HDLCD_REG_V_BACK_PORCH, vm.vback_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH, vm.vfront_porch - 1); hdlcd_write(hdlcd, HDLCD_REG_V_FRONT_PORCH, vm.vfront_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_V_SYNC, vm.vsync_len - 1); hdlcd_write(hdlcd, HDLCD_REG_V_SYNC, vm.vsync_len - 1);
hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH, vm.hback_porch - 1); hdlcd_write(hdlcd, HDLCD_REG_H_BACK_PORCH, vm.hback_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH, vm.hfront_porch - 1); hdlcd_write(hdlcd, HDLCD_REG_H_FRONT_PORCH, vm.hfront_porch - 1);
hdlcd_write(hdlcd, HDLCD_REG_H_SYNC, vm.hsync_len - 1); hdlcd_write(hdlcd, HDLCD_REG_H_SYNC, vm.hsync_len - 1);
hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1);
hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities); hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities);
err = hdlcd_set_pxl_fmt(crtc); err = hdlcd_set_pxl_fmt(crtc);
...@@ -144,20 +148,19 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc) ...@@ -144,20 +148,19 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc)
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
clk_prepare_enable(hdlcd->clk); clk_prepare_enable(hdlcd->clk);
hdlcd_crtc_mode_set_nofb(crtc);
hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1); hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1);
drm_crtc_vblank_on(crtc);
} }
static void hdlcd_crtc_disable(struct drm_crtc *crtc) static void hdlcd_crtc_disable(struct drm_crtc *crtc)
{ {
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
if (!crtc->primary->fb) if (!crtc->state->active)
return; return;
clk_disable_unprepare(hdlcd->clk);
hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0); hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 0);
drm_crtc_vblank_off(crtc); clk_disable_unprepare(hdlcd->clk);
} }
static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc, static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc,
...@@ -179,20 +182,17 @@ static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc, ...@@ -179,20 +182,17 @@ static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc,
static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc, static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
struct drm_crtc_state *state) struct drm_crtc_state *state)
{ {
struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc); struct drm_pending_vblank_event *event = crtc->state->event;
unsigned long flags;
if (crtc->state->event) {
struct drm_pending_vblank_event *event = crtc->state->event;
if (event) {
crtc->state->event = NULL; crtc->state->event = NULL;
event->pipe = drm_crtc_index(crtc);
WARN_ON(drm_crtc_vblank_get(crtc) != 0);
spin_lock_irqsave(&crtc->dev->event_lock, flags); spin_lock_irq(&crtc->dev->event_lock);
list_add_tail(&event->base.link, &hdlcd->event_list); if (drm_crtc_vblank_get(crtc) == 0)
spin_unlock_irqrestore(&crtc->dev->event_lock, flags); drm_crtc_arm_vblank_event(crtc, event);
else
drm_crtc_send_vblank_event(crtc, event);
spin_unlock_irq(&crtc->dev->event_lock);
} }
} }
...@@ -225,6 +225,15 @@ static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = { ...@@ -225,6 +225,15 @@ static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
static int hdlcd_plane_atomic_check(struct drm_plane *plane, static int hdlcd_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state) struct drm_plane_state *state)
{ {
u32 src_w, src_h;
src_w = state->src_w >> 16;
src_h = state->src_h >> 16;
/* we can't do any scaling of the plane source */
if ((src_w != state->crtc_w) || (src_h != state->crtc_h))
return -EINVAL;
return 0; return 0;
} }
...@@ -233,20 +242,31 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane, ...@@ -233,20 +242,31 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane,
{ {
struct hdlcd_drm_private *hdlcd; struct hdlcd_drm_private *hdlcd;
struct drm_gem_cma_object *gem; struct drm_gem_cma_object *gem;
unsigned int depth, bpp;
u32 src_w, src_h, dest_w, dest_h;
dma_addr_t scanout_start; dma_addr_t scanout_start;
if (!plane->state->crtc || !plane->state->fb) if (!plane->state->fb)
return; return;
hdlcd = crtc_to_hdlcd_priv(plane->state->crtc); drm_fb_get_bpp_depth(plane->state->fb->pixel_format, &depth, &bpp);
src_w = plane->state->src_w >> 16;
src_h = plane->state->src_h >> 16;
dest_w = plane->state->crtc_w;
dest_h = plane->state->crtc_h;
gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0); gem = drm_fb_cma_get_gem_obj(plane->state->fb, 0);
scanout_start = gem->paddr; scanout_start = gem->paddr + plane->state->fb->offsets[0] +
plane->state->crtc_y * plane->state->fb->pitches[0] +
plane->state->crtc_x * bpp / 8;
hdlcd = plane->dev->dev_private;
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_LENGTH, plane->state->fb->pitches[0]);
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_PITCH, plane->state->fb->pitches[0]);
hdlcd_write(hdlcd, HDLCD_REG_FB_LINE_COUNT, dest_h - 1);
hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start); hdlcd_write(hdlcd, HDLCD_REG_FB_BASE, scanout_start);
} }
static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = { static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = {
.prepare_fb = NULL,
.cleanup_fb = NULL,
.atomic_check = hdlcd_plane_atomic_check, .atomic_check = hdlcd_plane_atomic_check,
.atomic_update = hdlcd_plane_atomic_update, .atomic_update = hdlcd_plane_atomic_update,
}; };
...@@ -294,16 +314,6 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm) ...@@ -294,16 +314,6 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm)
return plane; return plane;
} }
void hdlcd_crtc_suspend(struct drm_crtc *crtc)
{
hdlcd_crtc_disable(crtc);
}
void hdlcd_crtc_resume(struct drm_crtc *crtc)
{
hdlcd_crtc_enable(crtc);
}
int hdlcd_setup_crtc(struct drm_device *drm) int hdlcd_setup_crtc(struct drm_device *drm)
{ {
struct hdlcd_drm_private *hdlcd = drm->dev_private; struct hdlcd_drm_private *hdlcd = drm->dev_private;
......
...@@ -49,8 +49,6 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) ...@@ -49,8 +49,6 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags)
atomic_set(&hdlcd->dma_end_count, 0); atomic_set(&hdlcd->dma_end_count, 0);
#endif #endif
INIT_LIST_HEAD(&hdlcd->event_list);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
hdlcd->mmio = devm_ioremap_resource(drm->dev, res); hdlcd->mmio = devm_ioremap_resource(drm->dev, res);
if (IS_ERR(hdlcd->mmio)) { if (IS_ERR(hdlcd->mmio)) {
...@@ -84,11 +82,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags) ...@@ -84,11 +82,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags)
goto setup_fail; goto setup_fail;
} }
pm_runtime_enable(drm->dev);
pm_runtime_get_sync(drm->dev);
ret = drm_irq_install(drm, platform_get_irq(pdev, 0)); ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
pm_runtime_put_sync(drm->dev);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("failed to install IRQ handler\n"); DRM_ERROR("failed to install IRQ handler\n");
goto irq_fail; goto irq_fail;
...@@ -164,24 +158,9 @@ static irqreturn_t hdlcd_irq(int irq, void *arg) ...@@ -164,24 +158,9 @@ static irqreturn_t hdlcd_irq(int irq, void *arg)
atomic_inc(&hdlcd->vsync_count); atomic_inc(&hdlcd->vsync_count);
#endif #endif
if (irq_status & HDLCD_INTERRUPT_VSYNC) { if (irq_status & HDLCD_INTERRUPT_VSYNC)
bool events_sent = false;
unsigned long flags;
struct drm_pending_vblank_event *e, *t;
drm_crtc_handle_vblank(&hdlcd->crtc); drm_crtc_handle_vblank(&hdlcd->crtc);
spin_lock_irqsave(&drm->event_lock, flags);
list_for_each_entry_safe(e, t, &hdlcd->event_list, base.link) {
list_del(&e->base.link);
drm_crtc_send_vblank_event(&hdlcd->crtc, e);
events_sent = true;
}
if (events_sent)
drm_crtc_vblank_put(&hdlcd->crtc);
spin_unlock_irqrestore(&drm->event_lock, flags);
}
/* acknowledge interrupt(s) */ /* acknowledge interrupt(s) */
hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status); hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
...@@ -275,6 +254,7 @@ static int hdlcd_show_pxlclock(struct seq_file *m, void *arg) ...@@ -275,6 +254,7 @@ static int hdlcd_show_pxlclock(struct seq_file *m, void *arg)
static struct drm_info_list hdlcd_debugfs_list[] = { static struct drm_info_list hdlcd_debugfs_list[] = {
{ "interrupt_count", hdlcd_show_underrun_count, 0 }, { "interrupt_count", hdlcd_show_underrun_count, 0 },
{ "clocks", hdlcd_show_pxlclock, 0 }, { "clocks", hdlcd_show_pxlclock, 0 },
{ "fb", drm_fb_cma_debugfs_show, 0 },
}; };
static int hdlcd_debugfs_init(struct drm_minor *minor) static int hdlcd_debugfs_init(struct drm_minor *minor)
...@@ -357,6 +337,8 @@ static int hdlcd_drm_bind(struct device *dev) ...@@ -357,6 +337,8 @@ static int hdlcd_drm_bind(struct device *dev)
return -ENOMEM; return -ENOMEM;
drm->dev_private = hdlcd; drm->dev_private = hdlcd;
dev_set_drvdata(dev, drm);
hdlcd_setup_mode_config(drm); hdlcd_setup_mode_config(drm);
ret = hdlcd_load(drm, 0); ret = hdlcd_load(drm, 0);
if (ret) if (ret)
...@@ -366,14 +348,18 @@ static int hdlcd_drm_bind(struct device *dev) ...@@ -366,14 +348,18 @@ static int hdlcd_drm_bind(struct device *dev)
if (ret) if (ret)
goto err_unload; goto err_unload;
dev_set_drvdata(dev, drm);
ret = component_bind_all(dev, drm); ret = component_bind_all(dev, drm);
if (ret) { if (ret) {
DRM_ERROR("Failed to bind all components\n"); DRM_ERROR("Failed to bind all components\n");
goto err_unregister; goto err_unregister;
} }
ret = pm_runtime_set_active(dev);
if (ret)
goto err_pm_active;
pm_runtime_enable(dev);
ret = drm_vblank_init(drm, drm->mode_config.num_crtc); ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
if (ret < 0) { if (ret < 0) {
DRM_ERROR("failed to initialise vblank\n"); DRM_ERROR("failed to initialise vblank\n");
...@@ -399,16 +385,16 @@ static int hdlcd_drm_bind(struct device *dev) ...@@ -399,16 +385,16 @@ static int hdlcd_drm_bind(struct device *dev)
drm_mode_config_cleanup(drm); drm_mode_config_cleanup(drm);
drm_vblank_cleanup(drm); drm_vblank_cleanup(drm);
err_vblank: err_vblank:
pm_runtime_disable(drm->dev);
err_pm_active:
component_unbind_all(dev, drm); component_unbind_all(dev, drm);
err_unregister: err_unregister:
drm_dev_unregister(drm); drm_dev_unregister(drm);
err_unload: err_unload:
pm_runtime_get_sync(drm->dev);
drm_irq_uninstall(drm); drm_irq_uninstall(drm);
pm_runtime_put_sync(drm->dev);
pm_runtime_disable(drm->dev);
of_reserved_mem_device_release(drm->dev); of_reserved_mem_device_release(drm->dev);
err_free: err_free:
dev_set_drvdata(dev, NULL);
drm_dev_unref(drm); drm_dev_unref(drm);
return ret; return ret;
...@@ -495,30 +481,34 @@ MODULE_DEVICE_TABLE(of, hdlcd_of_match); ...@@ -495,30 +481,34 @@ MODULE_DEVICE_TABLE(of, hdlcd_of_match);
static int __maybe_unused hdlcd_pm_suspend(struct device *dev) static int __maybe_unused hdlcd_pm_suspend(struct device *dev)
{ {
struct drm_device *drm = dev_get_drvdata(dev); struct drm_device *drm = dev_get_drvdata(dev);
struct drm_crtc *crtc; struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL;
if (pm_runtime_suspended(dev)) if (!hdlcd)
return 0; return 0;
drm_modeset_lock_all(drm); drm_kms_helper_poll_disable(drm);
list_for_each_entry(crtc, &drm->mode_config.crtc_list, head)
hdlcd_crtc_suspend(crtc); hdlcd->state = drm_atomic_helper_suspend(drm);
drm_modeset_unlock_all(drm); if (IS_ERR(hdlcd->state)) {
drm_kms_helper_poll_enable(drm);
return PTR_ERR(hdlcd->state);
}
return 0; return 0;
} }
static int __maybe_unused hdlcd_pm_resume(struct device *dev) static int __maybe_unused hdlcd_pm_resume(struct device *dev)
{ {
struct drm_device *drm = dev_get_drvdata(dev); struct drm_device *drm = dev_get_drvdata(dev);
struct drm_crtc *crtc; struct hdlcd_drm_private *hdlcd = drm ? drm->dev_private : NULL;
if (!pm_runtime_suspended(dev)) if (!hdlcd)
return 0; return 0;
drm_modeset_lock_all(drm); drm_atomic_helper_resume(drm, hdlcd->state);
list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) drm_kms_helper_poll_enable(drm);
hdlcd_crtc_resume(crtc); pm_runtime_set_active(dev);
drm_modeset_unlock_all(drm);
return 0; return 0;
} }
......
...@@ -9,10 +9,9 @@ struct hdlcd_drm_private { ...@@ -9,10 +9,9 @@ struct hdlcd_drm_private {
void __iomem *mmio; void __iomem *mmio;
struct clk *clk; struct clk *clk;
struct drm_fbdev_cma *fbdev; struct drm_fbdev_cma *fbdev;
struct drm_framebuffer *fb;
struct list_head event_list;
struct drm_crtc crtc; struct drm_crtc crtc;
struct drm_plane *plane; struct drm_plane *plane;
struct drm_atomic_state *state;
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
atomic_t buffer_underrun_count; atomic_t buffer_underrun_count;
atomic_t bus_error_count; atomic_t bus_error_count;
...@@ -36,7 +35,5 @@ static inline u32 hdlcd_read(struct hdlcd_drm_private *hdlcd, unsigned int reg) ...@@ -36,7 +35,5 @@ static inline u32 hdlcd_read(struct hdlcd_drm_private *hdlcd, unsigned int reg)
int hdlcd_setup_crtc(struct drm_device *dev); int hdlcd_setup_crtc(struct drm_device *dev);
void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd); void hdlcd_set_scanout(struct hdlcd_drm_private *hdlcd);
void hdlcd_crtc_suspend(struct drm_crtc *crtc);
void hdlcd_crtc_resume(struct drm_crtc *crtc);
#endif /* __HDLCD_DRV_H__ */ #endif /* __HDLCD_DRV_H__ */
...@@ -391,12 +391,11 @@ void atmel_hlcdc_crtc_reset(struct drm_crtc *crtc) ...@@ -391,12 +391,11 @@ void atmel_hlcdc_crtc_reset(struct drm_crtc *crtc)
{ {
struct atmel_hlcdc_crtc_state *state; struct atmel_hlcdc_crtc_state *state;
if (crtc->state && crtc->state->mode_blob)
drm_property_unreference_blob(crtc->state->mode_blob);
if (crtc->state) { if (crtc->state) {
__drm_atomic_helper_crtc_destroy_state(crtc->state);
state = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state); state = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state);
kfree(state); kfree(state);
crtc->state = NULL;
} }
state = kzalloc(sizeof(*state), GFP_KERNEL); state = kzalloc(sizeof(*state), GFP_KERNEL);
...@@ -415,8 +414,9 @@ atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc) ...@@ -415,8 +414,9 @@ atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc)
return NULL; return NULL;
state = kmalloc(sizeof(*state), GFP_KERNEL); state = kmalloc(sizeof(*state), GFP_KERNEL);
if (state) if (!state)
__drm_atomic_helper_crtc_duplicate_state(crtc, &state->base); return NULL;
__drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state); cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state);
state->output_mode = cur->output_mode; state->output_mode = cur->output_mode;
......
...@@ -351,6 +351,8 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, ...@@ -351,6 +351,8 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
drm_property_unreference_blob(state->mode_blob); drm_property_unreference_blob(state->mode_blob);
state->mode_blob = NULL; state->mode_blob = NULL;
memset(&state->mode, 0, sizeof(state->mode));
if (blob) { if (blob) {
if (blob->length != sizeof(struct drm_mode_modeinfo) || if (blob->length != sizeof(struct drm_mode_modeinfo) ||
drm_mode_convert_umode(&state->mode, drm_mode_convert_umode(&state->mode,
...@@ -363,7 +365,6 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state, ...@@ -363,7 +365,6 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n", DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
state->mode.name, state); state->mode.name, state);
} else { } else {
memset(&state->mode, 0, sizeof(state->mode));
state->enable = false; state->enable = false;
DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n", DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n",
state); state);
......
...@@ -2821,8 +2821,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data, ...@@ -2821,8 +2821,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
goto out; goto out;
} }
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
/* /*
* Check whether the primary plane supports the fb pixel format. * Check whether the primary plane supports the fb pixel format.
* Drivers not implementing the universal planes API use a * Drivers not implementing the universal planes API use a
...@@ -4841,7 +4839,8 @@ bool drm_property_change_valid_get(struct drm_property *property, ...@@ -4841,7 +4839,8 @@ bool drm_property_change_valid_get(struct drm_property *property,
if (value == 0) if (value == 0)
return true; return true;
return _object_find(property->dev, value, property->values[0]) != NULL; *ref = _object_find(property->dev, value, property->values[0]);
return *ref != NULL;
} }
for (i = 0; i < property->num_values; i++) for (i = 0; i < property->num_values; i++)
......
...@@ -445,7 +445,7 @@ int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper, ...@@ -445,7 +445,7 @@ int drm_fbdev_cma_create_with_funcs(struct drm_fb_helper *helper,
err_fb_info_destroy: err_fb_info_destroy:
drm_fb_helper_release_fbi(helper); drm_fb_helper_release_fbi(helper);
err_gem_free_object: err_gem_free_object:
dev->driver->gem_free_object(&obj->base); drm_gem_object_unreference_unlocked(&obj->base);
return ret; return ret;
} }
EXPORT_SYMBOL(drm_fbdev_cma_create_with_funcs); EXPORT_SYMBOL(drm_fbdev_cma_create_with_funcs);
......
...@@ -121,7 +121,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, ...@@ -121,7 +121,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
return cma_obj; return cma_obj;
error: error:
drm->driver->gem_free_object(&cma_obj->base); drm_gem_object_unreference_unlocked(&cma_obj->base);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
EXPORT_SYMBOL_GPL(drm_gem_cma_create); EXPORT_SYMBOL_GPL(drm_gem_cma_create);
...@@ -162,18 +162,12 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv, ...@@ -162,18 +162,12 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv,
* and handle has the id what user can see. * and handle has the id what user can see.
*/ */
ret = drm_gem_handle_create(file_priv, gem_obj, handle); ret = drm_gem_handle_create(file_priv, gem_obj, handle);
if (ret)
goto err_handle_create;
/* drop reference from allocate - handle holds it now. */ /* drop reference from allocate - handle holds it now. */
drm_gem_object_unreference_unlocked(gem_obj); drm_gem_object_unreference_unlocked(gem_obj);
if (ret)
return ERR_PTR(ret);
return cma_obj; return cma_obj;
err_handle_create:
drm->driver->gem_free_object(gem_obj);
return ERR_PTR(ret);
} }
/** /**
......
...@@ -1518,6 +1518,8 @@ int drm_mode_convert_umode(struct drm_display_mode *out, ...@@ -1518,6 +1518,8 @@ int drm_mode_convert_umode(struct drm_display_mode *out,
if (out->status != MODE_OK) if (out->status != MODE_OK)
goto out; goto out;
drm_mode_set_crtcinfo(out, CRTC_INTERLACE_HALVE_V);
ret = 0; ret = 0;
out: out:
......
...@@ -97,8 +97,8 @@ static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc) ...@@ -97,8 +97,8 @@ static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
return NULL; return NULL;
} }
int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format, int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format,
int hsync_pin, int vsync_pin) int hsync_pin, int vsync_pin, u32 bus_flags)
{ {
struct imx_drm_crtc_helper_funcs *helper; struct imx_drm_crtc_helper_funcs *helper;
struct imx_drm_crtc *imx_crtc; struct imx_drm_crtc *imx_crtc;
...@@ -110,14 +110,17 @@ int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format, ...@@ -110,14 +110,17 @@ int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format,
helper = &imx_crtc->imx_drm_helper_funcs; helper = &imx_crtc->imx_drm_helper_funcs;
if (helper->set_interface_pix_fmt) if (helper->set_interface_pix_fmt)
return helper->set_interface_pix_fmt(encoder->crtc, return helper->set_interface_pix_fmt(encoder->crtc,
bus_format, hsync_pin, vsync_pin); bus_format, hsync_pin, vsync_pin,
bus_flags);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(imx_drm_set_bus_format_pins); EXPORT_SYMBOL_GPL(imx_drm_set_bus_config);
int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format) int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format)
{ {
return imx_drm_set_bus_format_pins(encoder, bus_format, 2, 3); return imx_drm_set_bus_config(encoder, bus_format, 2, 3,
DRM_BUS_FLAG_DE_HIGH |
DRM_BUS_FLAG_PIXDATA_NEGEDGE);
} }
EXPORT_SYMBOL_GPL(imx_drm_set_bus_format); EXPORT_SYMBOL_GPL(imx_drm_set_bus_format);
......
...@@ -19,7 +19,8 @@ struct imx_drm_crtc_helper_funcs { ...@@ -19,7 +19,8 @@ struct imx_drm_crtc_helper_funcs {
int (*enable_vblank)(struct drm_crtc *crtc); int (*enable_vblank)(struct drm_crtc *crtc);
void (*disable_vblank)(struct drm_crtc *crtc); void (*disable_vblank)(struct drm_crtc *crtc);
int (*set_interface_pix_fmt)(struct drm_crtc *crtc, int (*set_interface_pix_fmt)(struct drm_crtc *crtc,
u32 bus_format, int hsync_pin, int vsync_pin); u32 bus_format, int hsync_pin, int vsync_pin,
u32 bus_flags);
const struct drm_crtc_helper_funcs *crtc_helper_funcs; const struct drm_crtc_helper_funcs *crtc_helper_funcs;
const struct drm_crtc_funcs *crtc_funcs; const struct drm_crtc_funcs *crtc_funcs;
}; };
...@@ -41,8 +42,8 @@ void imx_drm_mode_config_init(struct drm_device *drm); ...@@ -41,8 +42,8 @@ void imx_drm_mode_config_init(struct drm_device *drm);
struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb); struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb);
int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format,
u32 bus_format, int hsync_pin, int vsync_pin); int hsync_pin, int vsync_pin, u32 bus_flags);
int imx_drm_set_bus_format(struct drm_encoder *encoder, int imx_drm_set_bus_format(struct drm_encoder *encoder,
u32 bus_format); u32 bus_format);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/of_device.h> #include <linux/of_device.h>
#include <linux/of_graph.h> #include <linux/of_graph.h>
#include <video/of_display_timing.h>
#include <video/of_videomode.h> #include <video/of_videomode.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/videodev2.h> #include <linux/videodev2.h>
...@@ -59,6 +60,7 @@ struct imx_ldb_channel { ...@@ -59,6 +60,7 @@ struct imx_ldb_channel {
struct drm_encoder encoder; struct drm_encoder encoder;
struct drm_panel *panel; struct drm_panel *panel;
struct device_node *child; struct device_node *child;
struct i2c_adapter *ddc;
int chno; int chno;
void *edid; void *edid;
int edid_len; int edid_len;
...@@ -107,6 +109,9 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) ...@@ -107,6 +109,9 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector)
return num_modes; return num_modes;
} }
if (!imx_ldb_ch->edid && imx_ldb_ch->ddc)
imx_ldb_ch->edid = drm_get_edid(connector, imx_ldb_ch->ddc);
if (imx_ldb_ch->edid) { if (imx_ldb_ch->edid) {
drm_mode_connector_update_edid_property(connector, drm_mode_connector_update_edid_property(connector,
imx_ldb_ch->edid); imx_ldb_ch->edid);
...@@ -553,7 +558,8 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) ...@@ -553,7 +558,8 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
for_each_child_of_node(np, child) { for_each_child_of_node(np, child) {
struct imx_ldb_channel *channel; struct imx_ldb_channel *channel;
struct device_node *port; struct device_node *ddc_node;
struct device_node *ep;
ret = of_property_read_u32(child, "reg", &i); ret = of_property_read_u32(child, "reg", &i);
if (ret || i < 0 || i > 1) if (ret || i < 0 || i > 1)
...@@ -576,33 +582,54 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) ...@@ -576,33 +582,54 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
* The output port is port@4 with an external 4-port mux or * The output port is port@4 with an external 4-port mux or
* port@2 with the internal 2-port mux. * port@2 with the internal 2-port mux.
*/ */
port = of_graph_get_port_by_id(child, imx_ldb->lvds_mux ? 4 : 2); ep = of_graph_get_endpoint_by_regs(child,
if (port) { imx_ldb->lvds_mux ? 4 : 2,
struct device_node *endpoint, *remote; -1);
if (ep) {
endpoint = of_get_child_by_name(port, "endpoint"); struct device_node *remote;
if (endpoint) {
remote = of_graph_get_remote_port_parent(endpoint); remote = of_graph_get_remote_port_parent(ep);
if (remote) of_node_put(ep);
channel->panel = of_drm_find_panel(remote); if (remote)
else channel->panel = of_drm_find_panel(remote);
return -EPROBE_DEFER; else
if (!channel->panel) { return -EPROBE_DEFER;
dev_err(dev, "panel not found: %s\n", of_node_put(remote);
remote->full_name); if (!channel->panel) {
return -EPROBE_DEFER; dev_err(dev, "panel not found: %s\n",
} remote->full_name);
return -EPROBE_DEFER;
} }
} }
edidp = of_get_property(child, "edid", &channel->edid_len); ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0);
if (edidp) { if (ddc_node) {
channel->edid = kmemdup(edidp, channel->edid_len, channel->ddc = of_find_i2c_adapter_by_node(ddc_node);
GFP_KERNEL); of_node_put(ddc_node);
} else if (!channel->panel) { if (!channel->ddc) {
ret = of_get_drm_display_mode(child, &channel->mode, 0); dev_warn(dev, "failed to get ddc i2c adapter\n");
if (!ret) return -EPROBE_DEFER;
channel->mode_valid = 1; }
}
if (!channel->ddc) {
/* if no DDC available, fallback to hardcoded EDID */
dev_dbg(dev, "no ddc available\n");
edidp = of_get_property(child, "edid",
&channel->edid_len);
if (edidp) {
channel->edid = kmemdup(edidp,
channel->edid_len,
GFP_KERNEL);
} else if (!channel->panel) {
/* fallback to display-timings node */
ret = of_get_drm_display_mode(child,
&channel->mode,
OF_USE_NATIVE_MODE);
if (!ret)
channel->mode_valid = 1;
}
} }
channel->bus_format = of_get_bus_format(dev, child); channel->bus_format = of_get_bus_format(dev, child);
...@@ -647,6 +674,7 @@ static void imx_ldb_unbind(struct device *dev, struct device *master, ...@@ -647,6 +674,7 @@ static void imx_ldb_unbind(struct device *dev, struct device *master,
channel->encoder.funcs->destroy(&channel->encoder); channel->encoder.funcs->destroy(&channel->encoder);
kfree(channel->edid); kfree(channel->edid);
i2c_put_adapter(channel->ddc);
} }
} }
......
...@@ -294,8 +294,10 @@ static void imx_tve_encoder_prepare(struct drm_encoder *encoder) ...@@ -294,8 +294,10 @@ static void imx_tve_encoder_prepare(struct drm_encoder *encoder)
switch (tve->mode) { switch (tve->mode) {
case TVE_MODE_VGA: case TVE_MODE_VGA:
imx_drm_set_bus_format_pins(encoder, MEDIA_BUS_FMT_GBR888_1X24, imx_drm_set_bus_config(encoder, MEDIA_BUS_FMT_GBR888_1X24,
tve->hsync_pin, tve->vsync_pin); tve->hsync_pin, tve->vsync_pin,
DRM_BUS_FLAG_DE_HIGH |
DRM_BUS_FLAG_PIXDATA_NEGEDGE);
break; break;
case TVE_MODE_TVOUT: case TVE_MODE_TVOUT:
imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24); imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24);
......
...@@ -66,6 +66,7 @@ struct ipu_crtc { ...@@ -66,6 +66,7 @@ struct ipu_crtc {
struct ipu_flip_work *flip_work; struct ipu_flip_work *flip_work;
int irq; int irq;
u32 bus_format; u32 bus_format;
u32 bus_flags;
int di_hsync_pin; int di_hsync_pin;
int di_vsync_pin; int di_vsync_pin;
}; };
...@@ -271,8 +272,10 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc, ...@@ -271,8 +272,10 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
else else
sig_cfg.clkflags = 0; sig_cfg.clkflags = 0;
sig_cfg.enable_pol = 1; sig_cfg.enable_pol = !(ipu_crtc->bus_flags & DRM_BUS_FLAG_DE_LOW);
sig_cfg.clk_pol = 0; /* Default to driving pixel data on negative clock edges */
sig_cfg.clk_pol = !!(ipu_crtc->bus_flags &
DRM_BUS_FLAG_PIXDATA_POSEDGE);
sig_cfg.bus_format = ipu_crtc->bus_format; sig_cfg.bus_format = ipu_crtc->bus_format;
sig_cfg.v_to_h_sync = 0; sig_cfg.v_to_h_sync = 0;
sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin; sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
...@@ -396,11 +399,12 @@ static void ipu_disable_vblank(struct drm_crtc *crtc) ...@@ -396,11 +399,12 @@ static void ipu_disable_vblank(struct drm_crtc *crtc)
} }
static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc,
u32 bus_format, int hsync_pin, int vsync_pin) u32 bus_format, int hsync_pin, int vsync_pin, u32 bus_flags)
{ {
struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
ipu_crtc->bus_format = bus_format; ipu_crtc->bus_format = bus_format;
ipu_crtc->bus_flags = bus_flags;
ipu_crtc->di_hsync_pin = hsync_pin; ipu_crtc->di_hsync_pin = hsync_pin;
ipu_crtc->di_vsync_pin = vsync_pin; ipu_crtc->di_vsync_pin = vsync_pin;
......
...@@ -38,6 +38,8 @@ static const uint32_t ipu_plane_formats[] = { ...@@ -38,6 +38,8 @@ static const uint32_t ipu_plane_formats[] = {
DRM_FORMAT_RGBX8888, DRM_FORMAT_RGBX8888,
DRM_FORMAT_BGRA8888, DRM_FORMAT_BGRA8888,
DRM_FORMAT_BGRA8888, DRM_FORMAT_BGRA8888,
DRM_FORMAT_UYVY,
DRM_FORMAT_VYUY,
DRM_FORMAT_YUYV, DRM_FORMAT_YUYV,
DRM_FORMAT_YVYU, DRM_FORMAT_YVYU,
DRM_FORMAT_YUV420, DRM_FORMAT_YUV420,
...@@ -428,7 +430,6 @@ static int ipu_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, ...@@ -428,7 +430,6 @@ static int ipu_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
if (crtc != plane->crtc) if (crtc != plane->crtc)
dev_dbg(plane->dev->dev, "crtc change: %p -> %p\n", dev_dbg(plane->dev->dev, "crtc change: %p -> %p\n",
plane->crtc, crtc); plane->crtc, crtc);
plane->crtc = crtc;
if (!ipu_plane->enabled) if (!ipu_plane->enabled)
ipu_plane_enable(ipu_plane); ipu_plane_enable(ipu_plane);
...@@ -461,7 +462,7 @@ static void ipu_plane_destroy(struct drm_plane *plane) ...@@ -461,7 +462,7 @@ static void ipu_plane_destroy(struct drm_plane *plane)
kfree(ipu_plane); kfree(ipu_plane);
} }
static struct drm_plane_funcs ipu_plane_funcs = { static const struct drm_plane_funcs ipu_plane_funcs = {
.update_plane = ipu_update_plane, .update_plane = ipu_update_plane,
.disable_plane = ipu_disable_plane, .disable_plane = ipu_disable_plane,
.destroy = ipu_plane_destroy, .destroy = ipu_plane_destroy,
......
...@@ -35,7 +35,6 @@ struct imx_parallel_display { ...@@ -35,7 +35,6 @@ struct imx_parallel_display {
void *edid; void *edid;
int edid_len; int edid_len;
u32 bus_format; u32 bus_format;
int mode_valid;
struct drm_display_mode mode; struct drm_display_mode mode;
struct drm_panel *panel; struct drm_panel *panel;
}; };
...@@ -68,17 +67,6 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) ...@@ -68,17 +67,6 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
num_modes = drm_add_edid_modes(connector, imxpd->edid); num_modes = drm_add_edid_modes(connector, imxpd->edid);
} }
if (imxpd->mode_valid) {
struct drm_display_mode *mode = drm_mode_create(connector->dev);
if (!mode)
return -EINVAL;
drm_mode_copy(mode, &imxpd->mode);
mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED,
drm_mode_probed_add(connector, mode);
num_modes++;
}
if (np) { if (np) {
struct drm_display_mode *mode = drm_mode_create(connector->dev); struct drm_display_mode *mode = drm_mode_create(connector->dev);
...@@ -115,8 +103,8 @@ static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode) ...@@ -115,8 +103,8 @@ static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode)
static void imx_pd_encoder_prepare(struct drm_encoder *encoder) static void imx_pd_encoder_prepare(struct drm_encoder *encoder)
{ {
struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
imx_drm_set_bus_config(encoder, imxpd->bus_format, 2, 3,
imx_drm_set_bus_format(encoder, imxpd->bus_format); imxpd->connector.display_info.bus_flags);
} }
static void imx_pd_encoder_commit(struct drm_encoder *encoder) static void imx_pd_encoder_commit(struct drm_encoder *encoder)
...@@ -203,7 +191,7 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) ...@@ -203,7 +191,7 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
{ {
struct drm_device *drm = data; struct drm_device *drm = data;
struct device_node *np = dev->of_node; struct device_node *np = dev->of_node;
struct device_node *port; struct device_node *ep;
const u8 *edidp; const u8 *edidp;
struct imx_parallel_display *imxpd; struct imx_parallel_display *imxpd;
int ret; int ret;
...@@ -230,18 +218,18 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data) ...@@ -230,18 +218,18 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
} }
/* port@1 is the output port */ /* port@1 is the output port */
port = of_graph_get_port_by_id(np, 1); ep = of_graph_get_endpoint_by_regs(np, 1, -1);
if (port) { if (ep) {
struct device_node *endpoint, *remote; struct device_node *remote;
endpoint = of_get_child_by_name(port, "endpoint"); remote = of_graph_get_remote_port_parent(ep);
if (endpoint) { of_node_put(ep);
remote = of_graph_get_remote_port_parent(endpoint); if (remote) {
if (remote) imxpd->panel = of_drm_find_panel(remote);
imxpd->panel = of_drm_find_panel(remote); of_node_put(remote);
if (!imxpd->panel)
return -EPROBE_DEFER;
} }
if (!imxpd->panel)
return -EPROBE_DEFER;
} }
imxpd->dev = dev; imxpd->dev = dev;
......
...@@ -432,11 +432,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi, ...@@ -432,11 +432,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
unsigned long pll_rate; unsigned long pll_rate;
unsigned int factor; unsigned int factor;
if (!dpi) {
dev_err(dpi->dev, "invalid argument\n");
return -EINVAL;
}
pix_rate = 1000UL * mode->clock; pix_rate = 1000UL * mode->clock;
if (mode->clock <= 74000) if (mode->clock <= 74000)
factor = 8 * 3; factor = 8 * 3;
......
...@@ -695,10 +695,8 @@ static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi) ...@@ -695,10 +695,8 @@ static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi)
{ {
drm_encoder_cleanup(&dsi->encoder); drm_encoder_cleanup(&dsi->encoder);
/* Skip connector cleanup if creation was delegated to the bridge */ /* Skip connector cleanup if creation was delegated to the bridge */
if (dsi->conn.dev) { if (dsi->conn.dev)
drm_connector_unregister(&dsi->conn);
drm_connector_cleanup(&dsi->conn); drm_connector_cleanup(&dsi->conn);
}
} }
static void mtk_dsi_ddp_start(struct mtk_ddp_comp *comp) static void mtk_dsi_ddp_start(struct mtk_ddp_comp *comp)
......
...@@ -182,7 +182,7 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock) ...@@ -182,7 +182,7 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
} }
} }
fvv = pllreffreq * testn / testm; fvv = pllreffreq * (n + 1) / (m + 1);
fvv = (fvv - 800000) / 50000; fvv = (fvv - 800000) / 50000;
if (fvv > 15) if (fvv > 15)
...@@ -202,6 +202,14 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock) ...@@ -202,6 +202,14 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
WREG_DAC(MGA1064_PIX_PLLC_M, m); WREG_DAC(MGA1064_PIX_PLLC_M, m);
WREG_DAC(MGA1064_PIX_PLLC_N, n); WREG_DAC(MGA1064_PIX_PLLC_N, n);
WREG_DAC(MGA1064_PIX_PLLC_P, p); WREG_DAC(MGA1064_PIX_PLLC_P, p);
if (mdev->unique_rev_id >= 0x04) {
WREG_DAC(0x1a, 0x09);
msleep(20);
WREG_DAC(0x1a, 0x01);
}
return 0; return 0;
} }
......
...@@ -2,6 +2,7 @@ config DRM_OMAP ...@@ -2,6 +2,7 @@ config DRM_OMAP
tristate "OMAP DRM" tristate "OMAP DRM"
depends on DRM depends on DRM
depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM depends on ARCH_OMAP2PLUS || ARCH_MULTIPLATFORM
select OMAP2_DSS
select DRM_KMS_HELPER select DRM_KMS_HELPER
select DRM_KMS_FB_HELPER select DRM_KMS_FB_HELPER
select FB_SYS_FILLRECT select FB_SYS_FILLRECT
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
* the Free Software Foundation. * the Free Software Foundation.
*/ */
#include <linux/gpio/consumer.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* the Free Software Foundation. * the Free Software Foundation.
*/ */
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* the Free Software Foundation. * the Free Software Foundation.
*/ */
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* the Free Software Foundation. * the Free Software Foundation.
*/ */
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include <linux/backlight.h> #include <linux/backlight.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/jiffies.h> #include <linux/jiffies.h>
#include <linux/module.h> #include <linux/module.h>
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <video/omapdss.h> #include <video/omapdss.h>
#include <video/omap-panel-data.h> #include <video/omap-panel-data.h>
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <video/omapdss.h> #include <video/omapdss.h>
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
*/ */
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/backlight.h> #include <linux/backlight.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/gpio.h> #include <linux/gpio/consumer.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
......
...@@ -1180,15 +1180,6 @@ static int dsi_regulator_init(struct platform_device *dsidev) ...@@ -1180,15 +1180,6 @@ static int dsi_regulator_init(struct platform_device *dsidev)
return PTR_ERR(vdds_dsi); return PTR_ERR(vdds_dsi);
} }
if (regulator_can_change_voltage(vdds_dsi)) {
r = regulator_set_voltage(vdds_dsi, 1800000, 1800000);
if (r) {
devm_regulator_put(vdds_dsi);
DSSERR("can't set the DSI regulator voltage\n");
return r;
}
}
dsi->vdds_dsi_reg = vdds_dsi; dsi->vdds_dsi_reg = vdds_dsi;
return 0; return 0;
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/gfp.h> #include <linux/gfp.h>
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/component.h> #include <linux/component.h>
#include <linux/of.h>
#include <video/omapdss.h> #include <video/omapdss.h>
#include <sound/omap-hdmi-audio.h> #include <sound/omap-hdmi-audio.h>
...@@ -100,7 +101,6 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data) ...@@ -100,7 +101,6 @@ static irqreturn_t hdmi_irq_handler(int irq, void *data)
static int hdmi_init_regulator(void) static int hdmi_init_regulator(void)
{ {
int r;
struct regulator *reg; struct regulator *reg;
if (hdmi.vdda_reg != NULL) if (hdmi.vdda_reg != NULL)
...@@ -114,15 +114,6 @@ static int hdmi_init_regulator(void) ...@@ -114,15 +114,6 @@ static int hdmi_init_regulator(void)
return PTR_ERR(reg); return PTR_ERR(reg);
} }
if (regulator_can_change_voltage(reg)) {
r = regulator_set_voltage(reg, 1800000, 1800000);
if (r) {
devm_regulator_put(reg);
DSSWARN("can't set the regulator voltage\n");
return r;
}
}
hdmi.vdda_reg = reg; hdmi.vdda_reg = reg;
return 0; return 0;
......
...@@ -211,7 +211,7 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg) ...@@ -211,7 +211,7 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg)
static void hdmi_core_powerdown_disable(struct hdmi_core_data *core) static void hdmi_core_powerdown_disable(struct hdmi_core_data *core)
{ {
DSSDBG("Enter hdmi_core_powerdown_disable\n"); DSSDBG("Enter hdmi_core_powerdown_disable\n");
REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x0, 0, 0); REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x1, 0, 0);
} }
static void hdmi_core_swreset_release(struct hdmi_core_data *core) static void hdmi_core_swreset_release(struct hdmi_core_data *core)
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/component.h> #include <linux/component.h>
#include <linux/of.h>
#include <video/omapdss.h> #include <video/omapdss.h>
#include <sound/omap-hdmi-audio.h> #include <sound/omap-hdmi-audio.h>
...@@ -131,15 +132,6 @@ static int hdmi_init_regulator(void) ...@@ -131,15 +132,6 @@ static int hdmi_init_regulator(void)
return PTR_ERR(reg); return PTR_ERR(reg);
} }
if (regulator_can_change_voltage(reg)) {
r = regulator_set_voltage(reg, 1800000, 1800000);
if (r) {
devm_regulator_put(reg);
DSSWARN("can't set the regulator voltage\n");
return r;
}
}
hdmi.vdda_reg = reg; hdmi.vdda_reg = reg;
return 0; return 0;
......
...@@ -51,8 +51,8 @@ static void hdmi_core_ddc_init(struct hdmi_core_data *core) ...@@ -51,8 +51,8 @@ static void hdmi_core_ddc_init(struct hdmi_core_data *core)
{ {
void __iomem *base = core->base; void __iomem *base = core->base;
const unsigned long long iclk = 266000000; /* DSS L3 ICLK */ const unsigned long long iclk = 266000000; /* DSS L3 ICLK */
const unsigned ss_scl_high = 4000; /* ns */ const unsigned ss_scl_high = 4600; /* ns */
const unsigned ss_scl_low = 4700; /* ns */ const unsigned ss_scl_low = 5400; /* ns */
const unsigned fs_scl_high = 600; /* ns */ const unsigned fs_scl_high = 600; /* ns */
const unsigned fs_scl_low = 1300; /* ns */ const unsigned fs_scl_low = 1300; /* ns */
const unsigned sda_hold = 1000; /* ns */ const unsigned sda_hold = 1000; /* ns */
...@@ -458,7 +458,7 @@ static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core, ...@@ -458,7 +458,7 @@ static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core,
c = (ptr[1] >> 6) & 0x3; c = (ptr[1] >> 6) & 0x3;
m = (ptr[1] >> 4) & 0x3; m = (ptr[1] >> 4) & 0x3;
r = (ptr[1] >> 0) & 0x3; r = (ptr[1] >> 0) & 0xf;
itc = (ptr[2] >> 7) & 0x1; itc = (ptr[2] >> 7) & 0x1;
ec = (ptr[2] >> 4) & 0x7; ec = (ptr[2] >> 4) & 0x7;
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/seq_file.h>
#include <video/omapdss.h> #include <video/omapdss.h>
#include "dss.h" #include "dss.h"
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/seq_file.h>
#include <video/omapdss.h> #include <video/omapdss.h>
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/seq_file.h>
#include <video/omapdss.h> #include <video/omapdss.h>
#include "dss.h" #include "dss.h"
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
* this program. If not, see <http://www.gnu.org/licenses/>. * this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <linux/seq_file.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> /* platform_device() */ #include <linux/platform_device.h> /* platform_device() */
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
* this program. If not, see <http://www.gnu.org/licenses/>. * this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <linux/seq_file.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
* this program. If not, see <http://www.gnu.org/licenses/>. * this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <linux/seq_file.h>
#include <linux/shmem_fs.h> #include <linux/shmem_fs.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/pfn_t.h> #include <linux/pfn_t.h>
......
...@@ -51,15 +51,6 @@ static void sti_crtc_disabling(struct drm_crtc *crtc) ...@@ -51,15 +51,6 @@ static void sti_crtc_disabling(struct drm_crtc *crtc)
mixer->status = STI_MIXER_DISABLING; mixer->status = STI_MIXER_DISABLING;
} }
static bool sti_crtc_mode_fixup(struct drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
/* accept the provided drm_display_mode, do not fix it up */
drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
return true;
}
static int static int
sti_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode) sti_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode)
{ {
...@@ -230,7 +221,6 @@ static void sti_crtc_atomic_flush(struct drm_crtc *crtc, ...@@ -230,7 +221,6 @@ static void sti_crtc_atomic_flush(struct drm_crtc *crtc,
static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = { static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
.enable = sti_crtc_enable, .enable = sti_crtc_enable,
.disable = sti_crtc_disabling, .disable = sti_crtc_disabling,
.mode_fixup = sti_crtc_mode_fixup,
.mode_set = drm_helper_crtc_mode_set, .mode_set = drm_helper_crtc_mode_set,
.mode_set_nofb = sti_crtc_mode_set_nofb, .mode_set_nofb = sti_crtc_mode_set_nofb,
.mode_set_base = drm_helper_crtc_mode_set_base, .mode_set_base = drm_helper_crtc_mode_set_base,
......
...@@ -51,8 +51,8 @@ static void hdmi_core_ddc_init(struct hdmi_core_data *core) ...@@ -51,8 +51,8 @@ static void hdmi_core_ddc_init(struct hdmi_core_data *core)
{ {
void __iomem *base = core->base; void __iomem *base = core->base;
const unsigned long long iclk = 266000000; /* DSS L3 ICLK */ const unsigned long long iclk = 266000000; /* DSS L3 ICLK */
const unsigned ss_scl_high = 4000; /* ns */ const unsigned ss_scl_high = 4600; /* ns */
const unsigned ss_scl_low = 4700; /* ns */ const unsigned ss_scl_low = 5400; /* ns */
const unsigned fs_scl_high = 600; /* ns */ const unsigned fs_scl_high = 600; /* ns */
const unsigned fs_scl_low = 1300; /* ns */ const unsigned fs_scl_low = 1300; /* ns */
const unsigned sda_hold = 1000; /* ns */ const unsigned sda_hold = 1000; /* ns */
...@@ -442,7 +442,7 @@ static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core, ...@@ -442,7 +442,7 @@ static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core,
c = (ptr[1] >> 6) & 0x3; c = (ptr[1] >> 6) & 0x3;
m = (ptr[1] >> 4) & 0x3; m = (ptr[1] >> 4) & 0x3;
r = (ptr[1] >> 0) & 0x3; r = (ptr[1] >> 0) & 0xf;
itc = (ptr[2] >> 7) & 0x1; itc = (ptr[2] >> 7) & 0x1;
ec = (ptr[2] >> 4) & 0x7; ec = (ptr[2] >> 4) & 0x7;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment