diff options
author | Robert Chiras <robert.chiras@nxp.com> | 2017-11-24 14:03:51 +0200 |
---|---|---|
committer | Leonard Crestez <leonard.crestez@nxp.com> | 2018-08-24 12:41:33 +0300 |
commit | 213bd9a50f3ea65a5edad1b00517e21c1afc145e (patch) | |
tree | 57614b1403cb6922ce02d158c7903fa006fc166c /drivers/gpu/drm/mxsfb | |
parent | 9a0f2d3885491260ca8faf0fd9b4d29726ff3e4b (diff) |
MLK-16986-3: drm: mxsfb: fix connector handling
Since the MXSFB initially was just a simple display pipe using a
drm_panel, the drm_connector was created "in-house", by mxsfb driver.
But, with latest changes, mxsfb also supports a bridge. In case of a
drm_bridge, the the connector is created and initialized by that bridge.
So, for a proper initialization during start-up, we need to take into
consideration that connector, instead of our "in-house" connector.
The connector created and initialized by mxsfb will be used only when
this driver will have a panel.
Signed-off-by: Robert Chiras <robert.chiras@nxp.com>
Reviewed-by: Laurentiu Palcu <laurentiu.palcu@nxp.com>
Diffstat (limited to 'drivers/gpu/drm/mxsfb')
-rw-r--r-- | drivers/gpu/drm/mxsfb/mxsfb_crtc.c | 14 | ||||
-rw-r--r-- | drivers/gpu/drm/mxsfb/mxsfb_drv.c | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/mxsfb/mxsfb_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/mxsfb/mxsfb_out.c | 12 |
4 files changed, 48 insertions, 13 deletions
diff --git a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c index a940e22fae8e..1ac03213f1c8 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_crtc.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_crtc.c @@ -96,8 +96,11 @@ static void mxsfb_set_bus_fmt(struct mxsfb_drm_private *mxsfb) reg = readl(mxsfb->base + LCDC_CTRL); - if (mxsfb->connector.display_info.num_bus_formats) - bus_format = mxsfb->connector.display_info.bus_formats[0]; + if (mxsfb->connector->display_info.num_bus_formats) + bus_format = mxsfb->connector->display_info.bus_formats[0]; + + DRM_DEV_DEBUG_DRIVER(mxsfb->dev, + "Using bus_format: 0x%08X\n", bus_format); reg &= ~CTRL_BUS_WIDTH_MASK; switch (bus_format) { @@ -174,7 +177,7 @@ static void mxsfb_disable_controller(struct mxsfb_drm_private *mxsfb) static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb) { struct drm_display_mode *m = &mxsfb->pipe.crtc.state->adjusted_mode; - const u32 bus_flags = mxsfb->connector.display_info.bus_flags; + const u32 bus_flags = mxsfb->connector->display_info.bus_flags; u32 hbp = m->crtc_hblank_end - m->crtc_hsync_end; u32 vbp = m->crtc_vblank_end - m->crtc_vsync_end; u32 vdctrl0, vsync_pulse_len, hsync_pulse_len; @@ -196,6 +199,11 @@ static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb) clk_set_rate(mxsfb->clk, m->crtc_clock * 1000); + DRM_DEV_DEBUG_DRIVER(mxsfb->dev, + "Connector bus_flags: 0x%08X\n", bus_flags); + DRM_DEV_DEBUG_DRIVER(mxsfb->dev, + "Mode flags: 0x%08X\n", m->flags); + writel(TRANSFER_COUNT_SET_VCOUNT(m->crtc_vdisplay) | TRANSFER_COUNT_SET_HCOUNT(m->crtc_hdisplay), mxsfb->base + mxsfb->devdata->transfer_count); diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.c b/drivers/gpu/drm/mxsfb/mxsfb_drv.c index 4ec6d311cd31..f37dd51a9f25 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.c @@ -104,8 +104,23 @@ static const struct drm_mode_config_funcs mxsfb_mode_config_funcs = { static void mxsfb_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc_state *crtc_state) { + struct drm_device *drm = pipe->encoder.dev; + struct drm_connector *connector; struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe); + if (!mxsfb->connector) { + drm_for_each_connector(connector, drm) + if (connector->encoder == &(mxsfb->pipe.encoder)) { + mxsfb->connector = connector; + break; + } + } + + if (!mxsfb->connector) { + dev_warn(drm->dev, "No connector attached, using default\n"); + mxsfb->connector = &mxsfb->panel_connector; + } + mxsfb_crtc_enable(mxsfb); pm_runtime_get_sync(mxsfb->dev); } @@ -116,6 +131,9 @@ static void mxsfb_pipe_disable(struct drm_simple_display_pipe *pipe) mxsfb_crtc_disable(mxsfb); pm_runtime_put_sync(mxsfb->dev); + + if (mxsfb->connector != &mxsfb->panel_connector) + mxsfb->connector = NULL; } static void mxsfb_pipe_update(struct drm_simple_display_pipe *pipe, @@ -200,15 +218,22 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags) ret = drm_simple_display_pipe_init(drm, &mxsfb->pipe, &mxsfb_funcs, mxsfb_formats, ARRAY_SIZE(mxsfb_formats), - &mxsfb->connector); + mxsfb->connector); if (ret < 0) { dev_err(drm->dev, "Cannot setup simple display pipe\n"); goto err_vblank; } - /* Attach panel only if there is one */ + /* + * Attach panel only if there is one. + * If there is no panel attach, it must be a bridge. In this case, we + * need a reference to its connector for a proper initialization. + * We will do this check in pipe->enable(), since the connector won't + * be attached to an encoder until then. + */ + if (mxsfb->panel) { - ret = drm_panel_attach(mxsfb->panel, &mxsfb->connector); + ret = drm_panel_attach(mxsfb->panel, mxsfb->connector); if (ret) { dev_err(drm->dev, "Cannot connect panel\n"); goto err_vblank; @@ -220,7 +245,6 @@ static int mxsfb_load(struct drm_device *drm, unsigned long flags) dev_err(drm->dev, "Cannot connect bridge\n"); goto err_vblank; } - } drm->mode_config.min_width = MXSFB_MIN_XRES; diff --git a/drivers/gpu/drm/mxsfb/mxsfb_drv.h b/drivers/gpu/drm/mxsfb/mxsfb_drv.h index 71e62b0267da..baf35b35049a 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_drv.h +++ b/drivers/gpu/drm/mxsfb/mxsfb_drv.h @@ -37,7 +37,8 @@ struct mxsfb_drm_private { struct clk *clk_disp_axi; struct drm_simple_display_pipe pipe; - struct drm_connector connector; + struct drm_connector panel_connector; + struct drm_connector *connector; struct drm_panel *panel; struct drm_bridge *bridge; struct drm_fbdev_cma *fbdev; diff --git a/drivers/gpu/drm/mxsfb/mxsfb_out.c b/drivers/gpu/drm/mxsfb/mxsfb_out.c index cecbd08dcacb..5587341862ab 100644 --- a/drivers/gpu/drm/mxsfb/mxsfb_out.c +++ b/drivers/gpu/drm/mxsfb/mxsfb_out.c @@ -29,7 +29,8 @@ static struct mxsfb_drm_private * drm_connector_to_mxsfb_drm_private(struct drm_connector *connector) { - return container_of(connector, struct mxsfb_drm_private, connector); + return container_of(connector, struct mxsfb_drm_private, + panel_connector); } static int mxsfb_panel_get_modes(struct drm_connector *connector) @@ -99,11 +100,12 @@ static int mxsfb_attach_endpoint(struct drm_device *drm, return -EPROBE_DEFER; if (mxsfb->panel) { - mxsfb->connector.dpms = DRM_MODE_DPMS_OFF; - mxsfb->connector.polled = 0; - drm_connector_helper_add(&mxsfb->connector, + mxsfb->connector = &mxsfb->panel_connector; + mxsfb->connector->dpms = DRM_MODE_DPMS_OFF; + mxsfb->connector->polled = 0; + drm_connector_helper_add(mxsfb->connector, &mxsfb_panel_connector_helper_funcs); - ret = drm_connector_init(drm, &mxsfb->connector, + ret = drm_connector_init(drm, mxsfb->connector, &mxsfb_panel_connector_funcs, DRM_MODE_CONNECTOR_Unknown); } |