diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2018-12-07 16:08:35 -0500 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2019-03-18 05:42:14 -0400 |
commit | 30b71761957c541cd9dfd6cd10e3feb21a8ddca1 (patch) | |
tree | f4f836e13195c5e982035a6ae64218f9e8e482de /drivers/gpu/drm/omapdrm/omap_encoder.c | |
parent | 79107f274b2fc6bce13f687de33c8d0b70994558 (diff) |
drm/omap: Add support for drm_panel
Hook up drm_panel support in the omapdrm driver. The change is
relatively simply as the way has been paved by drm_bridge support
already. In addition to looking up, attaching to and detaching from the
panel, we only need to add panel support in the connector .get_modes()
handler, take connector bus flags (set by the panel) into account, and
enable/disable the panel in the encoder enable/disable operations
handlers.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Tested-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_encoder.c')
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_encoder.c | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c index 9eb3db9ba23f..40512419642b 100644 --- a/drivers/gpu/drm/omapdrm/omap_encoder.c +++ b/drivers/gpu/drm/omapdrm/omap_encoder.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <drm/drm_crtc.h> | 20 | #include <drm/drm_crtc.h> |
21 | #include <drm/drm_modeset_helper_vtables.h> | 21 | #include <drm/drm_modeset_helper_vtables.h> |
22 | #include <drm/drm_edid.h> | 22 | #include <drm/drm_edid.h> |
23 | #include <drm/drm_panel.h> | ||
23 | 24 | ||
24 | #include "omap_drv.h" | 25 | #include "omap_drv.h" |
25 | 26 | ||
@@ -79,22 +80,15 @@ static void omap_encoder_update_videomode_flags(struct videomode *vm, | |||
79 | } | 80 | } |
80 | } | 81 | } |
81 | 82 | ||
82 | static void omap_encoder_hdmi_mode_set(struct drm_encoder *encoder, | 83 | static void omap_encoder_hdmi_mode_set(struct drm_connector *connector, |
84 | struct drm_encoder *encoder, | ||
83 | struct drm_display_mode *adjusted_mode) | 85 | struct drm_display_mode *adjusted_mode) |
84 | { | 86 | { |
85 | struct drm_device *dev = encoder->dev; | ||
86 | struct omap_encoder *omap_encoder = to_omap_encoder(encoder); | 87 | struct omap_encoder *omap_encoder = to_omap_encoder(encoder); |
87 | struct omap_dss_device *dssdev = omap_encoder->output; | 88 | struct omap_dss_device *dssdev = omap_encoder->output; |
88 | struct drm_connector *connector; | ||
89 | bool hdmi_mode; | 89 | bool hdmi_mode; |
90 | 90 | ||
91 | hdmi_mode = false; | 91 | hdmi_mode = omap_connector_get_hdmi_mode(connector); |
92 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
93 | if (connector->encoder == encoder) { | ||
94 | hdmi_mode = omap_connector_get_hdmi_mode(connector); | ||
95 | break; | ||
96 | } | ||
97 | } | ||
98 | 92 | ||
99 | if (dssdev->ops->hdmi.set_hdmi_mode) | 93 | if (dssdev->ops->hdmi.set_hdmi_mode) |
100 | dssdev->ops->hdmi.set_hdmi_mode(dssdev, hdmi_mode); | 94 | dssdev->ops->hdmi.set_hdmi_mode(dssdev, hdmi_mode); |
@@ -117,8 +111,16 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, | |||
117 | struct omap_encoder *omap_encoder = to_omap_encoder(encoder); | 111 | struct omap_encoder *omap_encoder = to_omap_encoder(encoder); |
118 | struct omap_dss_device *output = omap_encoder->output; | 112 | struct omap_dss_device *output = omap_encoder->output; |
119 | struct omap_dss_device *dssdev; | 113 | struct omap_dss_device *dssdev; |
114 | struct drm_device *dev = encoder->dev; | ||
115 | struct drm_connector *connector; | ||
120 | struct drm_bridge *bridge; | 116 | struct drm_bridge *bridge; |
121 | struct videomode vm = { 0 }; | 117 | struct videomode vm = { 0 }; |
118 | u32 bus_flags; | ||
119 | |||
120 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
121 | if (connector->encoder == encoder) | ||
122 | break; | ||
123 | } | ||
122 | 124 | ||
123 | drm_display_mode_to_videomode(adjusted_mode, &vm); | 125 | drm_display_mode_to_videomode(adjusted_mode, &vm); |
124 | 126 | ||
@@ -135,8 +137,6 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, | |||
135 | omap_encoder_update_videomode_flags(&vm, dssdev->bus_flags); | 137 | omap_encoder_update_videomode_flags(&vm, dssdev->bus_flags); |
136 | 138 | ||
137 | for (bridge = output->bridge; bridge; bridge = bridge->next) { | 139 | for (bridge = output->bridge; bridge; bridge = bridge->next) { |
138 | u32 bus_flags; | ||
139 | |||
140 | if (!bridge->timings) | 140 | if (!bridge->timings) |
141 | continue; | 141 | continue; |
142 | 142 | ||
@@ -144,6 +144,9 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, | |||
144 | omap_encoder_update_videomode_flags(&vm, bus_flags); | 144 | omap_encoder_update_videomode_flags(&vm, bus_flags); |
145 | } | 145 | } |
146 | 146 | ||
147 | bus_flags = connector->display_info.bus_flags; | ||
148 | omap_encoder_update_videomode_flags(&vm, bus_flags); | ||
149 | |||
147 | /* Set timings for all devices in the display pipeline. */ | 150 | /* Set timings for all devices in the display pipeline. */ |
148 | dss_mgr_set_timings(output, &vm); | 151 | dss_mgr_set_timings(output, &vm); |
149 | 152 | ||
@@ -154,7 +157,7 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder, | |||
154 | 157 | ||
155 | /* Set the HDMI mode and HDMI infoframe if applicable. */ | 158 | /* Set the HDMI mode and HDMI infoframe if applicable. */ |
156 | if (output->type == OMAP_DISPLAY_TYPE_HDMI) | 159 | if (output->type == OMAP_DISPLAY_TYPE_HDMI) |
157 | omap_encoder_hdmi_mode_set(encoder, adjusted_mode); | 160 | omap_encoder_hdmi_mode_set(connector, encoder, adjusted_mode); |
158 | } | 161 | } |
159 | 162 | ||
160 | static void omap_encoder_disable(struct drm_encoder *encoder) | 163 | static void omap_encoder_disable(struct drm_encoder *encoder) |
@@ -165,6 +168,12 @@ static void omap_encoder_disable(struct drm_encoder *encoder) | |||
165 | 168 | ||
166 | dev_dbg(dev->dev, "disable(%s)\n", dssdev->name); | 169 | dev_dbg(dev->dev, "disable(%s)\n", dssdev->name); |
167 | 170 | ||
171 | /* Disable the panel if present. */ | ||
172 | if (dssdev->panel) { | ||
173 | drm_panel_disable(dssdev->panel); | ||
174 | drm_panel_unprepare(dssdev->panel); | ||
175 | } | ||
176 | |||
168 | /* | 177 | /* |
169 | * Disable the chain of external devices, starting at the one at the | 178 | * Disable the chain of external devices, starting at the one at the |
170 | * internal encoder's output. | 179 | * internal encoder's output. |
@@ -214,6 +223,12 @@ static void omap_encoder_enable(struct drm_encoder *encoder) | |||
214 | * internal encoder's output. | 223 | * internal encoder's output. |
215 | */ | 224 | */ |
216 | omapdss_device_enable(dssdev->next); | 225 | omapdss_device_enable(dssdev->next); |
226 | |||
227 | /* Enable the panel if present. */ | ||
228 | if (dssdev->panel) { | ||
229 | drm_panel_prepare(dssdev->panel); | ||
230 | drm_panel_enable(dssdev->panel); | ||
231 | } | ||
217 | } | 232 | } |
218 | 233 | ||
219 | static int omap_encoder_atomic_check(struct drm_encoder *encoder, | 234 | static int omap_encoder_atomic_check(struct drm_encoder *encoder, |