aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/display/fsl,dcu.txt9
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c2
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h3
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c68
4 files changed, 57 insertions, 25 deletions
diff --git a/Documentation/devicetree/bindings/display/fsl,dcu.txt b/Documentation/devicetree/bindings/display/fsl,dcu.txt
index ae55cde1b69e..63ec2a624aa9 100644
--- a/Documentation/devicetree/bindings/display/fsl,dcu.txt
+++ b/Documentation/devicetree/bindings/display/fsl,dcu.txt
@@ -12,7 +12,7 @@ Required properties:
12- clock-names: Should be "dcu" and "pix" 12- clock-names: Should be "dcu" and "pix"
13 See ../clocks/clock-bindings.txt for details. 13 See ../clocks/clock-bindings.txt for details.
14- big-endian Boolean property, LS1021A DCU registers are big-endian. 14- big-endian Boolean property, LS1021A DCU registers are big-endian.
15- fsl,panel: The phandle to panel node. 15- port Video port for the panel output
16 16
17Optional properties: 17Optional properties:
18- fsl,tcon: The phandle to the timing controller node. 18- fsl,tcon: The phandle to the timing controller node.
@@ -24,6 +24,11 @@ dcu: dcu@2ce0000 {
24 clocks = <&platform_clk 0>, <&platform_clk 0>; 24 clocks = <&platform_clk 0>, <&platform_clk 0>;
25 clock-names = "dcu", "pix"; 25 clock-names = "dcu", "pix";
26 big-endian; 26 big-endian;
27 fsl,panel = <&panel>;
28 fsl,tcon = <&tcon>; 27 fsl,tcon = <&tcon>;
28
29 port {
30 dcu_out: endpoint {
31 remote-endpoint = <&panel_out>;
32 };
33 };
29}; 34};
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c
index a6e4cd591960..d9d6cc1c8e39 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c
@@ -43,7 +43,7 @@ int fsl_dcu_drm_modeset_init(struct fsl_dcu_drm_device *fsl_dev)
43 if (ret) 43 if (ret)
44 goto err; 44 goto err;
45 45
46 ret = fsl_dcu_drm_connector_create(fsl_dev, &fsl_dev->encoder); 46 ret = fsl_dcu_create_outputs(fsl_dev);
47 if (ret) 47 if (ret)
48 goto err; 48 goto err;
49 49
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h
index 7093109fbc21..5a7b88e19e44 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_output.h
@@ -25,9 +25,8 @@ to_fsl_dcu_connector(struct drm_connector *con)
25 : NULL; 25 : NULL;
26} 26}
27 27
28int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device *fsl_dev,
29 struct drm_encoder *encoder);
30int fsl_dcu_drm_encoder_create(struct fsl_dcu_drm_device *fsl_dev, 28int fsl_dcu_drm_encoder_create(struct fsl_dcu_drm_device *fsl_dev,
31 struct drm_crtc *crtc); 29 struct drm_crtc *crtc);
30int fsl_dcu_create_outputs(struct fsl_dcu_drm_device *fsl_dev);
32 31
33#endif /* __FSL_DCU_DRM_CONNECTOR_H__ */ 32#endif /* __FSL_DCU_DRM_CONNECTOR_H__ */
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
index 0b0989e503ea..32eff990d199 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/backlight.h> 12#include <linux/backlight.h>
13#include <linux/of_graph.h>
13 14
14#include <drm/drmP.h> 15#include <drm/drmP.h>
15#include <drm/drm_atomic_helper.h> 16#include <drm/drm_atomic_helper.h>
@@ -132,12 +133,12 @@ static const struct drm_connector_helper_funcs connector_helper_funcs = {
132 .mode_valid = fsl_dcu_drm_connector_mode_valid, 133 .mode_valid = fsl_dcu_drm_connector_mode_valid,
133}; 134};
134 135
135int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device *fsl_dev, 136static int fsl_dcu_attach_panel(struct fsl_dcu_drm_device *fsl_dev,
136 struct drm_encoder *encoder) 137 struct drm_panel *panel)
137{ 138{
139 struct drm_encoder *encoder = &fsl_dev->encoder;
138 struct drm_connector *connector = &fsl_dev->connector.base; 140 struct drm_connector *connector = &fsl_dev->connector.base;
139 struct drm_mode_config *mode_config = &fsl_dev->drm->mode_config; 141 struct drm_mode_config *mode_config = &fsl_dev->drm->mode_config;
140 struct device_node *panel_node;
141 int ret; 142 int ret;
142 143
143 fsl_dev->connector.encoder = encoder; 144 fsl_dev->connector.encoder = encoder;
@@ -161,21 +162,7 @@ int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device *fsl_dev,
161 mode_config->dpms_property, 162 mode_config->dpms_property,
162 DRM_MODE_DPMS_OFF); 163 DRM_MODE_DPMS_OFF);
163 164
164 panel_node = of_parse_phandle(fsl_dev->np, "fsl,panel", 0); 165 ret = drm_panel_attach(panel, connector);
165 if (!panel_node) {
166 dev_err(fsl_dev->dev, "fsl,panel property not found\n");
167 ret = -ENODEV;
168 goto err_sysfs;
169 }
170
171 fsl_dev->connector.panel = of_drm_find_panel(panel_node);
172 if (!fsl_dev->connector.panel) {
173 ret = -EPROBE_DEFER;
174 goto err_panel;
175 }
176 of_node_put(panel_node);
177
178 ret = drm_panel_attach(fsl_dev->connector.panel, connector);
179 if (ret) { 166 if (ret) {
180 dev_err(fsl_dev->dev, "failed to attach panel\n"); 167 dev_err(fsl_dev->dev, "failed to attach panel\n");
181 goto err_sysfs; 168 goto err_sysfs;
@@ -183,11 +170,52 @@ int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device *fsl_dev,
183 170
184 return 0; 171 return 0;
185 172
186err_panel:
187 of_node_put(panel_node);
188err_sysfs: 173err_sysfs:
189 drm_connector_unregister(connector); 174 drm_connector_unregister(connector);
190err_cleanup: 175err_cleanup:
191 drm_connector_cleanup(connector); 176 drm_connector_cleanup(connector);
192 return ret; 177 return ret;
193} 178}
179
180static int fsl_dcu_attach_endpoint(struct fsl_dcu_drm_device *fsl_dev,
181 const struct of_endpoint *ep)
182{
183 struct device_node *np;
184
185 np = of_graph_get_remote_port_parent(ep->local_node);
186
187 fsl_dev->connector.panel = of_drm_find_panel(np);
188 of_node_put(np);
189 if (fsl_dev->connector.panel)
190 return fsl_dcu_attach_panel(fsl_dev, fsl_dev->connector.panel);
191
192 return -ENODEV;
193}
194
195int fsl_dcu_create_outputs(struct fsl_dcu_drm_device *fsl_dev)
196{
197 struct of_endpoint ep;
198 struct device_node *ep_node, *panel_node;
199 int ret;
200
201 /* This is for backward compatibility */
202 panel_node = of_parse_phandle(fsl_dev->np, "fsl,panel", 0);
203 if (panel_node) {
204 fsl_dev->connector.panel = of_drm_find_panel(panel_node);
205 of_node_put(panel_node);
206 if (!fsl_dev->connector.panel)
207 return -EPROBE_DEFER;
208 return fsl_dcu_attach_panel(fsl_dev, fsl_dev->connector.panel);
209 }
210
211 ep_node = of_graph_get_next_endpoint(fsl_dev->np, NULL);
212 if (!ep_node)
213 return -ENODEV;
214
215 ret = of_graph_parse_endpoint(ep_node, &ep);
216 of_node_put(ep_node);
217 if (ret)
218 return -ENODEV;
219
220 return fsl_dcu_attach_endpoint(fsl_dev, &ep);
221}