History

drm: renesas: shmobile: Add DT support

Add DT support, by: 1. Creating a panel bridge from DT, and attaching it to the encoder, 2. Replacing the custom connector with a bridge connector, 3. Obtaining clock configuration based on the compatible value. Note that for now the driver uses a fixed clock configuration selecting the bus clock, as the current code to select other clock inputs needs changes to support any other SoCs than SH7724.

Geert Uytterhoeven committed 3 years ago

Commit 1399eba1 parent b2b2f7b4 files · +74 −16Browse files

Unified · Split

4 files
  1. drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c +43 −13
  2. drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h +1 −0
  3. drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c +24 −3
  4. drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h +6 −0
drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.c+43−13
@@ -9,12 +9,16 @@ · 8 unmodified lines
99
1010 #include <linux/clk.h>
1111 #include <linux/media-bus-format.h>
12+#include <linux/of.h>
13+#include <linux/of_graph.h>
1214 #include <linux/pm_runtime.h>
1315
1416 #include <drm/drm_atomic.h>
1517 #include <drm/drm_atomic_helper.h>
1618 #include <drm/drm_atomic_state_helper.h>
1719 #include <drm/drm_atomic_uapi.h>
20+#include <drm/drm_bridge.h>
21+#include <drm/drm_bridge_connector.h>
1822 #include <drm/drm_crtc.h>
1923 #include <drm/drm_crtc_helper.h>
2024 #include <drm/drm_fb_dma_helper.h>
@@ -23,6 +27,7 @@ · 2 unmodified lines
2327 #include <drm/drm_gem_dma_helper.h>
2428 #include <drm/drm_modeset_helper.h>
2529 #include <drm/drm_modeset_helper_vtables.h>
30+#include <drm/drm_panel.h>
2631 #include <drm/drm_probe_helper.h>
2732 #include <drm/drm_simple_kms_helper.h>
2833 #include <drm/drm_vblank.h>
@@ -35,10 +40,6 @@ · 6 unmodified lines
3540 #include "shmob_drm_plane.h"
3641 #include "shmob_drm_regs.h"
3742
38−/*
39− * TODO: panel support
40− */
41−
4243 /* -----------------------------------------------------------------------------
4344 * Page Flip
4445 */
@@ -201,7 +202,7 @@ static void shmob_drm_crtc_atomic_enable(struct drm_crtc *crtc, · 156 unmodified lines
201202 {
202203 struct shmob_drm_crtc *scrtc = to_shmob_crtc(crtc);
203204 struct shmob_drm_device *sdev = to_shmob_device(crtc->dev);
204− const struct shmob_drm_interface_data *idata = &sdev->pdata->iface;
205+ unsigned int clk_div = sdev->config.clk_div;
205206 struct device *dev = sdev->dev;
206207 u32 value;
207208 int ret;
@@ -223,17 +224,17 @@ static void shmob_drm_crtc_atomic_enable(struct drm_crtc *crtc, · 15 unmodified lines
223224 lcdc_write(sdev, LDPMR, 0);
224225
225226 value = sdev->lddckr;
226− if (idata->clk_div) {
227+ if (clk_div) {
227228 /* FIXME: sh7724 can only use 42, 48, 54 and 60 for the divider
228229 * denominator.
229230 */
230231 lcdc_write(sdev, LDDCKPAT1R, 0);
231− lcdc_write(sdev, LDDCKPAT2R, (1 << (idata->clk_div / 2)) - 1);
232+ lcdc_write(sdev, LDDCKPAT2R, (1 << (clk_div / 2)) - 1);
232233
233− if (idata->clk_div == 1)
234+ if (clk_div == 1)
234235 value |= LDDCKR_MOSEL;
235236 else
236− value |= idata->clk_div;
237+ value |= clk_div;
237238 }
238239
239240 lcdc_write(sdev, LDDCKR, value);
@@ -406,7 +407,7 @@ int shmob_drm_crtc_create(struct shmob_drm_device *sdev) · 166 unmodified lines
406407 }
407408
408409 /* -----------------------------------------------------------------------------
409− * Encoder
410+ * Legacy Encoder
410411 */
411412
412413 static bool shmob_drm_encoder_mode_fixup(struct drm_encoder *encoder,
@@ -435,9 +436,14 @@ static const struct drm_encoder_helper_funcs encoder_helper_funcs = { · 22 unmodified lines
435436 .mode_fixup = shmob_drm_encoder_mode_fixup,
436437 };
437438
439+/* -----------------------------------------------------------------------------
440+ * Encoder
441+ */
442+
438443 int shmob_drm_encoder_create(struct shmob_drm_device *sdev)
439444 {
440445 struct drm_encoder *encoder = &sdev->encoder;
446+ struct drm_bridge *bridge;
441447 int ret;
442448
443449 encoder->possible_crtcs = 1;
@@ -447,13 +453,30 @@ int shmob_drm_encoder_create(struct shmob_drm_device *sdev) · 3 unmodified lines
447453 if (ret < 0)
448454 return ret;
449455
450− drm_encoder_helper_add(encoder, &encoder_helper_funcs);
456+ if (sdev->pdata) {
457+ drm_encoder_helper_add(encoder, &encoder_helper_funcs);
458+ return 0;
459+ }
460+
461+ /* Create a panel bridge */
462+ bridge = devm_drm_of_get_bridge(sdev->dev, sdev->dev->of_node, 0, 0);
463+ if (IS_ERR(bridge))
464+ return PTR_ERR(bridge);
465+
466+ /* Attach the bridge to the encoder */
467+ ret = drm_bridge_attach(encoder, bridge, NULL,
468+ DRM_BRIDGE_ATTACH_NO_CONNECTOR);
469+ if (ret) {
470+ dev_err(sdev->dev, "failed to attach bridge: %pe\n",
471+ ERR_PTR(ret));
472+ return ret;
473+ }
451474
452475 return 0;
453476 }
454477
455478 /* -----------------------------------------------------------------------------
456− * Connector
479+ * Legacy Connector
457480 */
458481
459482 static inline struct shmob_drm_connector *to_shmob_connector(struct drm_connector *connector)
@@ -563,13 +586,20 @@ shmob_drm_connector_init(struct shmob_drm_device *sdev, · 103 unmodified lines
563586 return connector;
564587 }
565588
589+/* -----------------------------------------------------------------------------
590+ * Connector
591+ */
592+
566593 int shmob_drm_connector_create(struct shmob_drm_device *sdev,
567594 struct drm_encoder *encoder)
568595 {
569596 struct drm_connector *connector;
570597 int ret;
571598
572− connector = shmob_drm_connector_init(sdev, encoder);
599+ if (sdev->pdata)
600+ connector = shmob_drm_connector_init(sdev, encoder);
601+ else
602+ connector = drm_bridge_connector_init(&sdev->ddev, encoder);
573603 if (IS_ERR(connector)) {
574604 dev_err(sdev->dev, "failed to created connector: %pe\n",
575605 connector);
drivers/gpu/drm/renesas/shmobile/shmob_drm_crtc.h+1−0
@@ -29,6 +29,7 @@ struct shmob_drm_crtc { · 28 unmodified lines
2929 wait_queue_head_t flip_wait;
3030 };
3131
32+/* Legacy connector */
3233 struct shmob_drm_connector {
3334 struct drm_connector base;
3435 struct drm_encoder *encoder;
drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.c+24−3
@@ -11,6 +11,7 @@ · 10 unmodified lines
1111 #include <linux/io.h>
1212 #include <linux/mm.h>
1313 #include <linux/module.h>
14+#include <linux/of.h>
1415 #include <linux/platform_device.h>
1516 #include <linux/pm.h>
1617 #include <linux/pm_runtime.h>
@@ -173,11 +174,13 @@ static void shmob_drm_remove(struct platform_device *pdev) · 156 unmodified lines
173174 static int shmob_drm_probe(struct platform_device *pdev)
174175 {
175176 struct shmob_drm_platform_data *pdata = pdev->dev.platform_data;
177+ const struct shmob_drm_config *config;
176178 struct shmob_drm_device *sdev;
177179 struct drm_device *ddev;
178180 int ret;
179181
180− if (pdata == NULL) {
182+ config = of_device_get_match_data(&pdev->dev);
183+ if (!config && !pdata) {
181184 dev_err(&pdev->dev, "no platform data\n");
182185 return -EINVAL;
183186 }
@@ -193,7 +196,13 @@ static int shmob_drm_probe(struct platform_device *pdev) · 9 unmodified lines
193196
194197 ddev = &sdev->ddev;
195198 sdev->dev = &pdev->dev;
196− sdev->pdata = pdata;
199+ if (config) {
200+ sdev->config = *config;
201+ } else {
202+ sdev->pdata = pdata;
203+ sdev->config.clk_source = pdata->clk_source;
204+ sdev->config.clk_div = pdata->iface.clk_div;
205+ }
197206 spin_lock_init(&sdev->irq_lock);
198207
199208 platform_set_drvdata(pdev, sdev);
@@ -202,7 +211,7 @@ static int shmob_drm_probe(struct platform_device *pdev) · 2 unmodified lines
202211 if (IS_ERR(sdev->mmio))
203212 return PTR_ERR(sdev->mmio);
204213
205− ret = shmob_drm_setup_clocks(sdev, pdata->clk_source);
214+ ret = shmob_drm_setup_clocks(sdev, sdev->config.clk_source);
206215 if (ret < 0)
207216 return ret;
208217
@@ -250,11 +259,23 @@ err_modeset_cleanup: · 41 unmodified lines
250259 return ret;
251260 }
252261
262+static const struct shmob_drm_config shmob_arm_config = {
263+ .clk_source = SHMOB_DRM_CLK_BUS,
264+ .clk_div = 5,
265+};
266+
267+static const struct of_device_id shmob_drm_of_table[] __maybe_unused = {
268+ { .compatible = "renesas,r8a7740-lcdc", .data = &shmob_arm_config, },
269+ { .compatible = "renesas,sh73a0-lcdc", .data = &shmob_arm_config, },
270+ { /* sentinel */ }
271+};
272+
253273 static struct platform_driver shmob_drm_platform_driver = {
254274 .probe = shmob_drm_probe,
255275 .remove_new = shmob_drm_remove,
256276 .driver = {
257277 .name = "shmob-drm",
278+ .of_match_table = of_match_ptr(shmob_drm_of_table),
258279 .pm = &shmob_drm_pm_ops,
259280 },
260281 };
drivers/gpu/drm/renesas/shmobile/shmob_drm_drv.h+6−0
@@ -20,9 +20,15 @@ struct clk; · 19 unmodified lines
2020 struct device;
2121 struct drm_device;
2222
23+struct shmob_drm_config {
24+ enum shmob_drm_clk_source clk_source;
25+ unsigned int clk_div;
26+};
27+
2328 struct shmob_drm_device {
2429 struct device *dev;
2530 const struct shmob_drm_platform_data *pdata;
31+ struct shmob_drm_config config;
2632
2733 void __iomem *mmio;
2834 struct clk *clock;