]> Git Repo - linux.git/commitdiff
Merge tag 'omapdrm-4.7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba...
authorDave Airlie <[email protected]>
Fri, 3 Jun 2016 04:35:00 +0000 (14:35 +1000)
committerDave Airlie <[email protected]>
Fri, 3 Jun 2016 04:35:00 +0000 (14:35 +1000)
omapdrm fixes for 4.7

* multiple compile break fixes for missing includes, bad kconfig dependencies.
* remove regulator API misuse causing deprecation warnings
* OMAP5 HDMI fixes for DDC and AVI infoframe
* OMAP4 HDMI fix for CEC

* tag 'omapdrm-4.7-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux:
  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
  OMAPDSS: HDMI5: Fix AVI infoframe
  drm/omap: fix OMAP4 hdmi_core_powerdown_disable()
  drm/omap: Fix missing includes
  drm/omapdrm: include pinctrl/consumer.h where needed

21 files changed:
Documentation/devicetree/bindings/display/imx/ldb.txt
drivers/gpu/drm/arm/hdlcd_crtc.c
drivers/gpu/drm/arm/hdlcd_drv.c
drivers/gpu/drm/arm/hdlcd_drv.h
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
drivers/gpu/drm/drm_atomic.c
drivers/gpu/drm/drm_crtc.c
drivers/gpu/drm/drm_fb_cma_helper.c
drivers/gpu/drm/drm_gem_cma_helper.c
drivers/gpu/drm/drm_modes.c
drivers/gpu/drm/imx/imx-drm-core.c
drivers/gpu/drm/imx/imx-drm.h
drivers/gpu/drm/imx/imx-ldb.c
drivers/gpu/drm/imx/imx-tve.c
drivers/gpu/drm/imx/ipuv3-crtc.c
drivers/gpu/drm/imx/ipuv3-plane.c
drivers/gpu/drm/imx/parallel-display.c
drivers/gpu/drm/mediatek/mtk_dpi.c
drivers/gpu/drm/mediatek/mtk_dsi.c
drivers/gpu/drm/mgag200/mgag200_mode.c
drivers/gpu/drm/sti/sti_crtc.c

index 0a175d991b52b26a5c81d9166329558713e45406..a407462c885e43f31eefcbf22d209f785a8d9ebe 100644 (file)
@@ -62,6 +62,7 @@ Required properties:
    display-timings are used instead.
 
 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
    Documentation/devicetree/bindings/display/display-timing.txt.
  - fsl,data-mapping : should be "spwg" or "jeida"
index fef1b04c2aab4fef4411ac0cc10249c98caab0f5..0813c2f069319967458fdafdfd8f5a57421d558b 100644 (file)
  *
  */
 
+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 = {
-       .destroy = drm_crtc_cleanup,
+       .destroy = hdlcd_crtc_cleanup,
        .set_config = drm_atomic_helper_set_config,
        .page_flip = drm_atomic_helper_page_flip,
        .reset = drm_atomic_helper_crtc_reset,
@@ -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 drm_display_mode *m = &crtc->state->adjusted_mode;
        struct videomode vm;
-       unsigned int polarities, line_length, err;
+       unsigned int polarities, err;
 
        vm.vfront_porch = m->crtc_vsync_start - m->crtc_vdisplay;
        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)
        if (m->flags & DRM_MODE_FLAG_PVSYNC)
                polarities |= HDLCD_POLARITY_VSYNC;
 
-       line_length = crtc->primary->state->fb->pitches[0];
-
        /* Allow max number of outstanding requests and largest burst size */
        hdlcd_write(hdlcd, HDLCD_REG_BUS_OPTIONS,
                    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_BACK_PORCH, vm.vback_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_H_DATA, m->crtc_hdisplay - 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_SYNC, vm.hsync_len - 1);
-       hdlcd_write(hdlcd, HDLCD_REG_H_DATA, m->crtc_hdisplay - 1);
        hdlcd_write(hdlcd, HDLCD_REG_POLARITIES, polarities);
 
        err = hdlcd_set_pxl_fmt(crtc);
@@ -144,20 +148,19 @@ static void hdlcd_crtc_enable(struct drm_crtc *crtc)
        struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
 
        clk_prepare_enable(hdlcd->clk);
+       hdlcd_crtc_mode_set_nofb(crtc);
        hdlcd_write(hdlcd, HDLCD_REG_COMMAND, 1);
-       drm_crtc_vblank_on(crtc);
 }
 
 static void hdlcd_crtc_disable(struct drm_crtc *crtc)
 {
        struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
 
-       if (!crtc->primary->fb)
+       if (!crtc->state->active)
                return;
 
-       clk_disable_unprepare(hdlcd->clk);
        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,
@@ -179,20 +182,17 @@ static int hdlcd_crtc_atomic_check(struct drm_crtc *crtc,
 static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
                                    struct drm_crtc_state *state)
 {
-       struct hdlcd_drm_private *hdlcd = crtc_to_hdlcd_priv(crtc);
-       unsigned long flags;
-
-       if (crtc->state->event) {
-               struct drm_pending_vblank_event *event = crtc->state->event;
+       struct drm_pending_vblank_event *event = crtc->state->event;
 
+       if (event) {
                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);
-               list_add_tail(&event->base.link, &hdlcd->event_list);
-               spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+               spin_lock_irq(&crtc->dev->event_lock);
+               if (drm_crtc_vblank_get(crtc) == 0)
+                       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 = {
 static int hdlcd_plane_atomic_check(struct drm_plane *plane,
                                    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;
 }
 
@@ -233,20 +242,31 @@ static void hdlcd_plane_atomic_update(struct drm_plane *plane,
 {
        struct hdlcd_drm_private *hdlcd;
        struct drm_gem_cma_object *gem;
+       unsigned int depth, bpp;
+       u32 src_w, src_h, dest_w, dest_h;
        dma_addr_t scanout_start;
 
-       if (!plane->state->crtc || !plane->state->fb)
+       if (!plane->state->fb)
                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);
-       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);
 }
 
 static const struct drm_plane_helper_funcs hdlcd_plane_helper_funcs = {
-       .prepare_fb = NULL,
-       .cleanup_fb = NULL,
        .atomic_check = hdlcd_plane_atomic_check,
        .atomic_update = hdlcd_plane_atomic_update,
 };
@@ -294,16 +314,6 @@ static struct drm_plane *hdlcd_plane_init(struct drm_device *drm)
        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)
 {
        struct hdlcd_drm_private *hdlcd = drm->dev_private;
index b987c63ba8d6a63612f7d14ab56ad5e82c15b05a..a6ca36f0096f3225ff7f61b78eabc012e85f5d95 100644 (file)
@@ -49,8 +49,6 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags)
        atomic_set(&hdlcd->dma_end_count, 0);
 #endif
 
-       INIT_LIST_HEAD(&hdlcd->event_list);
-
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        hdlcd->mmio = devm_ioremap_resource(drm->dev, res);
        if (IS_ERR(hdlcd->mmio)) {
@@ -84,11 +82,7 @@ static int hdlcd_load(struct drm_device *drm, unsigned long flags)
                goto setup_fail;
        }
 
-       pm_runtime_enable(drm->dev);
-
-       pm_runtime_get_sync(drm->dev);
        ret = drm_irq_install(drm, platform_get_irq(pdev, 0));
-       pm_runtime_put_sync(drm->dev);
        if (ret < 0) {
                DRM_ERROR("failed to install IRQ handler\n");
                goto irq_fail;
@@ -164,24 +158,9 @@ static irqreturn_t hdlcd_irq(int irq, void *arg)
                atomic_inc(&hdlcd->vsync_count);
 
 #endif
-       if (irq_status & HDLCD_INTERRUPT_VSYNC) {
-               bool events_sent = false;
-               unsigned long flags;
-               struct drm_pending_vblank_event *e, *t;
-
+       if (irq_status & HDLCD_INTERRUPT_VSYNC)
                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) */
        hdlcd_write(hdlcd, HDLCD_REG_INT_CLEAR, irq_status);
 
@@ -275,6 +254,7 @@ static int hdlcd_show_pxlclock(struct seq_file *m, void *arg)
 static struct drm_info_list hdlcd_debugfs_list[] = {
        { "interrupt_count", hdlcd_show_underrun_count, 0 },
        { "clocks", hdlcd_show_pxlclock, 0 },
+       { "fb", drm_fb_cma_debugfs_show, 0 },
 };
 
 static int hdlcd_debugfs_init(struct drm_minor *minor)
@@ -357,6 +337,8 @@ static int hdlcd_drm_bind(struct device *dev)
                return -ENOMEM;
 
        drm->dev_private = hdlcd;
+       dev_set_drvdata(dev, drm);
+
        hdlcd_setup_mode_config(drm);
        ret = hdlcd_load(drm, 0);
        if (ret)
@@ -366,14 +348,18 @@ static int hdlcd_drm_bind(struct device *dev)
        if (ret)
                goto err_unload;
 
-       dev_set_drvdata(dev, drm);
-
        ret = component_bind_all(dev, drm);
        if (ret) {
                DRM_ERROR("Failed to bind all components\n");
                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);
        if (ret < 0) {
                DRM_ERROR("failed to initialise vblank\n");
@@ -399,16 +385,16 @@ err_fbdev:
        drm_mode_config_cleanup(drm);
        drm_vblank_cleanup(drm);
 err_vblank:
+       pm_runtime_disable(drm->dev);
+err_pm_active:
        component_unbind_all(dev, drm);
 err_unregister:
        drm_dev_unregister(drm);
 err_unload:
-       pm_runtime_get_sync(drm->dev);
        drm_irq_uninstall(drm);
-       pm_runtime_put_sync(drm->dev);
-       pm_runtime_disable(drm->dev);
        of_reserved_mem_device_release(drm->dev);
 err_free:
+       dev_set_drvdata(dev, NULL);
        drm_dev_unref(drm);
 
        return ret;
@@ -495,30 +481,34 @@ MODULE_DEVICE_TABLE(of, hdlcd_of_match);
 static int __maybe_unused hdlcd_pm_suspend(struct device *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;
 
-       drm_modeset_lock_all(drm);
-       list_for_each_entry(crtc, &drm->mode_config.crtc_list, head)
-               hdlcd_crtc_suspend(crtc);
-       drm_modeset_unlock_all(drm);
+       drm_kms_helper_poll_disable(drm);
+
+       hdlcd->state = drm_atomic_helper_suspend(drm);
+       if (IS_ERR(hdlcd->state)) {
+               drm_kms_helper_poll_enable(drm);
+               return PTR_ERR(hdlcd->state);
+       }
+
        return 0;
 }
 
 static int __maybe_unused hdlcd_pm_resume(struct device *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;
 
-       drm_modeset_lock_all(drm);
-       list_for_each_entry(crtc, &drm->mode_config.crtc_list, head)
-               hdlcd_crtc_resume(crtc);
-       drm_modeset_unlock_all(drm);
+       drm_atomic_helper_resume(drm, hdlcd->state);
+       drm_kms_helper_poll_enable(drm);
+       pm_runtime_set_active(dev);
+
        return 0;
 }
 
index aa234784f0537fde1e248afeace94c898c3d1752..e3950a0711524a13d637f7fc0ec6a9100b9c6219 100644 (file)
@@ -9,10 +9,9 @@ struct hdlcd_drm_private {
        void __iomem                    *mmio;
        struct clk                      *clk;
        struct drm_fbdev_cma            *fbdev;
-       struct drm_framebuffer          *fb;
-       struct list_head                event_list;
        struct drm_crtc                 crtc;
        struct drm_plane                *plane;
+       struct drm_atomic_state         *state;
 #ifdef CONFIG_DEBUG_FS
        atomic_t buffer_underrun_count;
        atomic_t bus_error_count;
@@ -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);
 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__ */
index cf23a755f777f8b4df9fcc6b3032c01415c14bd8..bd12231ab0cdeeb431b8eba261d1a18459556da5 100644 (file)
@@ -391,12 +391,11 @@ void atmel_hlcdc_crtc_reset(struct drm_crtc *crtc)
 {
        struct atmel_hlcdc_crtc_state *state;
 
-       if (crtc->state && crtc->state->mode_blob)
-               drm_property_unreference_blob(crtc->state->mode_blob);
-
        if (crtc->state) {
+               __drm_atomic_helper_crtc_destroy_state(crtc->state);
                state = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state);
                kfree(state);
+               crtc->state = NULL;
        }
 
        state = kzalloc(sizeof(*state), GFP_KERNEL);
@@ -415,8 +414,9 @@ atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc)
                return NULL;
 
        state = kmalloc(sizeof(*state), GFP_KERNEL);
-       if (state)
-               __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
+       if (!state)
+               return NULL;
+       __drm_atomic_helper_crtc_duplicate_state(crtc, &state->base);
 
        cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state);
        state->output_mode = cur->output_mode;
index 3ff1ed7b33dbeb74aa036204f90931958eb5ee23..c204ef32df16425bc0c18bd10735baf4414e6530 100644 (file)
@@ -351,6 +351,8 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
        drm_property_unreference_blob(state->mode_blob);
        state->mode_blob = NULL;
 
+       memset(&state->mode, 0, sizeof(state->mode));
+
        if (blob) {
                if (blob->length != sizeof(struct drm_mode_modeinfo) ||
                    drm_mode_convert_umode(&state->mode,
@@ -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",
                                 state->mode.name, state);
        } else {
-               memset(&state->mode, 0, sizeof(state->mode));
                state->enable = false;
                DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n",
                                 state);
index d2a6d958ca76068bf45b59e98dbe2a709ecf8817..0e3cc66aa8b7d45803e39d36cb26faac494a3568 100644 (file)
@@ -2821,8 +2821,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
                        goto out;
                }
 
-               drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
-
                /*
                 * Check whether the primary plane supports the fb pixel format.
                 * Drivers not implementing the universal planes API use a
@@ -4841,7 +4839,8 @@ bool drm_property_change_valid_get(struct drm_property *property,
                if (value == 0)
                        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++)
index 172cafe11c7109397f554d50fcc1da9ba550937f..5075fae3c4e207da059773cb8bd57f70746bfccd 100644 (file)
@@ -445,7 +445,7 @@ err_cma_destroy:
 err_fb_info_destroy:
        drm_fb_helper_release_fbi(helper);
 err_gem_free_object:
-       dev->driver->gem_free_object(&obj->base);
+       drm_gem_object_unreference_unlocked(&obj->base);
        return ret;
 }
 EXPORT_SYMBOL(drm_fbdev_cma_create_with_funcs);
index e1ab008b3f0841675d5b06ae6ceb4fc037b985f5..1d6c335584ec37d1ea399ccb4a07fd6e0120064e 100644 (file)
@@ -121,7 +121,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
        return cma_obj;
 
 error:
-       drm->driver->gem_free_object(&cma_obj->base);
+       drm_gem_object_unreference_unlocked(&cma_obj->base);
        return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(drm_gem_cma_create);
@@ -162,18 +162,12 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv,
         * and handle has the id what user can see.
         */
        ret = drm_gem_handle_create(file_priv, gem_obj, handle);
-       if (ret)
-               goto err_handle_create;
-
        /* drop reference from allocate - handle holds it now. */
        drm_gem_object_unreference_unlocked(gem_obj);
+       if (ret)
+               return ERR_PTR(ret);
 
        return cma_obj;
-
-err_handle_create:
-       drm->driver->gem_free_object(gem_obj);
-
-       return ERR_PTR(ret);
 }
 
 /**
index 7def3d58da188990390ee84fcca75b312ea22735..e5e6f504d8ccafbd9ffe3bacad547279f09ae00c 100644 (file)
@@ -1518,6 +1518,8 @@ int drm_mode_convert_umode(struct drm_display_mode *out,
        if (out->status != MODE_OK)
                goto out;
 
+       drm_mode_set_crtcinfo(out, CRTC_INTERLACE_HALVE_V);
+
        ret = 0;
 
 out:
index 1f14b602882b539500203c2c5b1573d82a0128f5..82656654fb2181e2cbbb38e2b091727e9d97451e 100644 (file)
@@ -97,8 +97,8 @@ static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
        return NULL;
 }
 
-int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format,
-               int hsync_pin, int vsync_pin)
+int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format,
+               int hsync_pin, int vsync_pin, u32 bus_flags)
 {
        struct imx_drm_crtc_helper_funcs *helper;
        struct imx_drm_crtc *imx_crtc;
@@ -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;
        if (helper->set_interface_pix_fmt)
                return helper->set_interface_pix_fmt(encoder->crtc,
-                                       bus_format, hsync_pin, vsync_pin);
+                                       bus_format, hsync_pin, vsync_pin,
+                                       bus_flags);
        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)
 {
-       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);
 
index b0241b9d13342f516d01cb2e3b53f6afb9dbf47a..74320a1723b70122bfd85d34cd5a013cbbe57105 100644 (file)
@@ -19,7 +19,8 @@ struct imx_drm_crtc_helper_funcs {
        int (*enable_vblank)(struct drm_crtc *crtc);
        void (*disable_vblank)(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_funcs *crtc_funcs;
 };
@@ -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);
 
-int imx_drm_set_bus_format_pins(struct drm_encoder *encoder,
-               u32 bus_format, int hsync_pin, int vsync_pin);
+int imx_drm_set_bus_config(struct drm_encoder *encoder, u32 bus_format,
+               int hsync_pin, int vsync_pin, u32 bus_flags);
 int imx_drm_set_bus_format(struct drm_encoder *encoder,
                u32 bus_format);
 
index a58eee59550ab43d058dd64cc85ba43ea753a1dd..beff793bb717592daf045b45e171ca72dab737bd 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
 #include <linux/of_device.h>
 #include <linux/of_graph.h>
+#include <video/of_display_timing.h>
 #include <video/of_videomode.h>
 #include <linux/regmap.h>
 #include <linux/videodev2.h>
@@ -59,6 +60,7 @@ struct imx_ldb_channel {
        struct drm_encoder encoder;
        struct drm_panel *panel;
        struct device_node *child;
+       struct i2c_adapter *ddc;
        int chno;
        void *edid;
        int edid_len;
@@ -107,6 +109,9 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector)
                        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) {
                drm_mode_connector_update_edid_property(connector,
                                                        imx_ldb_ch->edid);
@@ -553,7 +558,8 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
 
        for_each_child_of_node(np, child) {
                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);
                if (ret || i < 0 || i > 1)
@@ -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
                 * port@2 with the internal 2-port mux.
                 */
-               port = of_graph_get_port_by_id(child, imx_ldb->lvds_mux ? 4 : 2);
-               if (port) {
-                       struct device_node *endpoint, *remote;
-
-                       endpoint = of_get_child_by_name(port, "endpoint");
-                       if (endpoint) {
-                               remote = of_graph_get_remote_port_parent(endpoint);
-                               if (remote)
-                                       channel->panel = of_drm_find_panel(remote);
-                               else
-                                       return -EPROBE_DEFER;
-                               if (!channel->panel) {
-                                       dev_err(dev, "panel not found: %s\n",
-                                               remote->full_name);
-                                       return -EPROBE_DEFER;
-                               }
+               ep = of_graph_get_endpoint_by_regs(child,
+                                                  imx_ldb->lvds_mux ? 4 : 2,
+                                                  -1);
+               if (ep) {
+                       struct device_node *remote;
+
+                       remote = of_graph_get_remote_port_parent(ep);
+                       of_node_put(ep);
+                       if (remote)
+                               channel->panel = of_drm_find_panel(remote);
+                       else
+                               return -EPROBE_DEFER;
+                       of_node_put(remote);
+                       if (!channel->panel) {
+                               dev_err(dev, "panel not found: %s\n",
+                                       remote->full_name);
+                               return -EPROBE_DEFER;
                        }
                }
 
-               edidp = of_get_property(child, "edid", &channel->edid_len);
-               if (edidp) {
-                       channel->edid = kmemdup(edidp, channel->edid_len,
-                                               GFP_KERNEL);
-               } else if (!channel->panel) {
-                       ret = of_get_drm_display_mode(child, &channel->mode, 0);
-                       if (!ret)
-                               channel->mode_valid = 1;
+               ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0);
+               if (ddc_node) {
+                       channel->ddc = of_find_i2c_adapter_by_node(ddc_node);
+                       of_node_put(ddc_node);
+                       if (!channel->ddc) {
+                               dev_warn(dev, "failed to get ddc i2c adapter\n");
+                               return -EPROBE_DEFER;
+                       }
+               }
+
+               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);
@@ -647,6 +674,7 @@ static void imx_ldb_unbind(struct device *dev, struct device *master,
                channel->encoder.funcs->destroy(&channel->encoder);
 
                kfree(channel->edid);
+               i2c_put_adapter(channel->ddc);
        }
 }
 
index ae7a9fb3b8a229404c2d4725e936b04ec1bdd52b..baf788121287ec8af7147d86d497872d742007c1 100644 (file)
@@ -294,8 +294,10 @@ static void imx_tve_encoder_prepare(struct drm_encoder *encoder)
 
        switch (tve->mode) {
        case TVE_MODE_VGA:
-               imx_drm_set_bus_format_pins(encoder, MEDIA_BUS_FMT_GBR888_1X24,
-                                           tve->hsync_pin, tve->vsync_pin);
+               imx_drm_set_bus_config(encoder, MEDIA_BUS_FMT_GBR888_1X24,
+                                      tve->hsync_pin, tve->vsync_pin,
+                                      DRM_BUS_FLAG_DE_HIGH |
+                                      DRM_BUS_FLAG_PIXDATA_NEGEDGE);
                break;
        case TVE_MODE_TVOUT:
                imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24);
index b2c30b8d981646719cbf3f3a1620aec834549b73..fc040417e1e8366cddf116cad95b058df80489ab 100644 (file)
@@ -66,6 +66,7 @@ struct ipu_crtc {
        struct ipu_flip_work    *flip_work;
        int                     irq;
        u32                     bus_format;
+       u32                     bus_flags;
        int                     di_hsync_pin;
        int                     di_vsync_pin;
 };
@@ -271,8 +272,10 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
        else
                sig_cfg.clkflags = 0;
 
-       sig_cfg.enable_pol = 1;
-       sig_cfg.clk_pol = 0;
+       sig_cfg.enable_pol = !(ipu_crtc->bus_flags & DRM_BUS_FLAG_DE_LOW);
+       /* 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.v_to_h_sync = 0;
        sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
@@ -396,11 +399,12 @@ static void ipu_disable_vblank(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);
 
        ipu_crtc->bus_format = bus_format;
+       ipu_crtc->bus_flags = bus_flags;
        ipu_crtc->di_hsync_pin = hsync_pin;
        ipu_crtc->di_vsync_pin = vsync_pin;
 
index 681ec6eb77d916fc3be6a47d783fab54ed1f07fb..a4bb44118d331179385b3a7824347cebde7db3dc 100644 (file)
@@ -38,6 +38,8 @@ static const uint32_t ipu_plane_formats[] = {
        DRM_FORMAT_RGBX8888,
        DRM_FORMAT_BGRA8888,
        DRM_FORMAT_BGRA8888,
+       DRM_FORMAT_UYVY,
+       DRM_FORMAT_VYUY,
        DRM_FORMAT_YUYV,
        DRM_FORMAT_YVYU,
        DRM_FORMAT_YUV420,
@@ -428,7 +430,6 @@ static int ipu_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
        if (crtc != plane->crtc)
                dev_dbg(plane->dev->dev, "crtc change: %p -> %p\n",
                                plane->crtc, crtc);
-       plane->crtc = crtc;
 
        if (!ipu_plane->enabled)
                ipu_plane_enable(ipu_plane);
@@ -461,7 +462,7 @@ static void ipu_plane_destroy(struct drm_plane *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,
        .disable_plane  = ipu_disable_plane,
        .destroy        = ipu_plane_destroy,
index 363e2c7741e2ea736e1cea604323116dc4ae0d75..2d1fd02cd3d663c672fffd8c5d4b6eb60e63e195 100644 (file)
@@ -35,7 +35,6 @@ struct imx_parallel_display {
        void *edid;
        int edid_len;
        u32 bus_format;
-       int mode_valid;
        struct drm_display_mode mode;
        struct drm_panel *panel;
 };
@@ -68,17 +67,6 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
                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) {
                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)
 static void imx_pd_encoder_prepare(struct drm_encoder *encoder)
 {
        struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
-
-       imx_drm_set_bus_format(encoder, imxpd->bus_format);
+       imx_drm_set_bus_config(encoder, imxpd->bus_format, 2, 3,
+                              imxpd->connector.display_info.bus_flags);
 }
 
 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)
 {
        struct drm_device *drm = data;
        struct device_node *np = dev->of_node;
-       struct device_node *port;
+       struct device_node *ep;
        const u8 *edidp;
        struct imx_parallel_display *imxpd;
        int ret;
@@ -230,18 +218,18 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
        }
 
        /* port@1 is the output port */
-       port = of_graph_get_port_by_id(np, 1);
-       if (port) {
-               struct device_node *endpoint, *remote;
-
-               endpoint = of_get_child_by_name(port, "endpoint");
-               if (endpoint) {
-                       remote = of_graph_get_remote_port_parent(endpoint);
-                       if (remote)
-                               imxpd->panel = of_drm_find_panel(remote);
-                       if (!imxpd->panel)
-                               return -EPROBE_DEFER;
+       ep = of_graph_get_endpoint_by_regs(np, 1, -1);
+       if (ep) {
+               struct device_node *remote;
+
+               remote = of_graph_get_remote_port_parent(ep);
+               of_node_put(ep);
+               if (remote) {
+                       imxpd->panel = of_drm_find_panel(remote);
+                       of_node_put(remote);
                }
+               if (!imxpd->panel)
+                       return -EPROBE_DEFER;
        }
 
        imxpd->dev = dev;
index d05ca7901315354e36994aa280f417dfa4fe203d..0186e500d2a544d8c90769428c7673bec1cd68c0 100644 (file)
@@ -432,11 +432,6 @@ static int mtk_dpi_set_display_mode(struct mtk_dpi *dpi,
        unsigned long pll_rate;
        unsigned int factor;
 
-       if (!dpi) {
-               dev_err(dpi->dev, "invalid argument\n");
-               return -EINVAL;
-       }
-
        pix_rate = 1000UL * mode->clock;
        if (mode->clock <= 74000)
                factor = 8 * 3;
index 2d808e59fefd388867cd66172bbc6fb08d162639..769559124562528ef8c4d217e47533511a47e523 100644 (file)
@@ -695,10 +695,8 @@ static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi)
 {
        drm_encoder_cleanup(&dsi->encoder);
        /* Skip connector cleanup if creation was delegated to the bridge */
-       if (dsi->conn.dev) {
-               drm_connector_unregister(&dsi->conn);
+       if (dsi->conn.dev)
                drm_connector_cleanup(&dsi->conn);
-       }
 }
 
 static void mtk_dsi_ddp_start(struct mtk_ddp_comp *comp)
index 14e64e08909ed1769e39d88d3a10124bfe2c2a2a..d347dca17267eca63c60cff0df63b5e854333dc9 100644 (file)
@@ -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;
 
                if (fvv > 15)
@@ -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_N, n);
        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;
 }
 
index 505620c7c2c8fbde2afd79295ecb36231496e64e..e04deedabd4a143f6bbeaec220bfa747d6ffdb95 100644 (file)
@@ -51,15 +51,6 @@ static void sti_crtc_disabling(struct drm_crtc *crtc)
        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
 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,
 static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
        .enable = sti_crtc_enable,
        .disable = sti_crtc_disabling,
-       .mode_fixup = sti_crtc_mode_fixup,
        .mode_set = drm_helper_crtc_mode_set,
        .mode_set_nofb = sti_crtc_mode_set_nofb,
        .mode_set_base = drm_helper_crtc_mode_set_base,
This page took 0.0988059999999999 seconds and 4 git commands to generate.