From b7d88c9ce3b8ba6207911d2f7d9d7cf7af818382 Mon Sep 17 00:00:00 2001 From: Hugh Cole-Baker Date: Sun, 11 Jun 2017 22:53:33 +0000 Subject: [PATCH] WIP, hack in VGA666 as a dumb-vga-dac bridge --- arch/arm/boot/dts/bcm2835-rpi.dtsi | 10 ++++ arch/arm/boot/dts/bcm283x.dtsi | 55 +++++++++++++++++++ .../drm/panel/panel-raspberrypi-touchscreen.c | 3 + drivers/gpu/drm/vc4/vc4_dpi.c | 26 ++++++++- 4 files changed, 91 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/bcm2835-rpi.dtsi b/arch/arm/boot/dts/bcm2835-rpi.dtsi index a7b5ce133784f1..fcc54244a7a7e3 100644 --- a/arch/arm/boot/dts/bcm2835-rpi.dtsi +++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi @@ -9,6 +9,9 @@ leds { compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&vga666_pins>; + act { label = "ACT"; default-state = "keep"; @@ -42,6 +45,13 @@ brcm,pins = <4 5 7 8 9 10 11 14 15>; brcm,function = ; }; + + vga666_pins: vga666_pins { + brcm,pins = <2 3 4 5 6 7 8 9 10 11 12 + 13 14 15 16 17 18 19 20 21>; + brcm,function = <6>; /* alt2 */ + brcm,pull = <0>; /* no pull */ + }; }; &i2c0 { diff --git a/arch/arm/boot/dts/bcm283x.dtsi b/arch/arm/boot/dts/bcm283x.dtsi index 4c6f16e5378ce9..9a503fa99e3b2e 100644 --- a/arch/arm/boot/dts/bcm283x.dtsi +++ b/arch/arm/boot/dts/bcm283x.dtsi @@ -422,6 +422,24 @@ }; + /* begin added DPI */ + dpi: dpi@7e208000 { + compatible = "brcm,bcm2835-dpi"; + reg = <0x7e208000 0x8c>; + clocks = <&clocks BCM2835_CLOCK_VPU>, + <&clocks BCM2835_CLOCK_DPI>; + clock-names = "core", "pixel"; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + port { + dpi_out: endpoint@0 { + remote-endpoint = <&vga_bridge_in>; + }; + }; + }; + /* end added DPI */ + thermal: thermal@7e212000 { compatible = "brcm,bcm2835-thermal"; reg = <0x7e212000 0x8>; @@ -627,4 +645,41 @@ clock-frequency = <480000000>; }; }; + + bridge { + compatible = "dumb-vga-dac"; + #address-cells = <1>; + #size-cells = <0>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + vga_bridge_in: endpoint { + remote-endpoint = <&dpi_out>; + }; + }; + + port@1 { + reg = <1>; + + vga_bridge_out: endpoint { + remote-endpoint = <&vga_con_in>; + }; + }; + }; + }; + + vga { + compatible = "vga-connector"; + + port { + vga_con_in: endpoint { + remote-endpoint = <&vga_bridge_out>; + }; + }; + }; }; diff --git a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c index 1a536fe4d040f5..5d6bfd81b07a11 100644 --- a/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +++ b/drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c @@ -399,6 +399,9 @@ static struct i2c_client *rpi_touchscreen_get_i2c(struct device *dev, of_node_put(node); + if (!client) + return ERR_PTR(-EPROBE_DEFER); + return client; } diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c index 2e0fe46aeb2e19..e7e826277f98f0 100644 --- a/drivers/gpu/drm/vc4/vc4_dpi.c +++ b/drivers/gpu/drm/vc4/vc4_dpi.c @@ -161,7 +161,11 @@ static void vc4_dpi_encoder_disable(struct drm_encoder *encoder) struct vc4_dpi_encoder *vc4_encoder = to_vc4_dpi_encoder(encoder); struct vc4_dpi *dpi = vc4_encoder->dpi; + drm_bridge_disable(dpi->bridge); + clk_disable_unprepare(dpi->pixel_clock); + + drm_bridge_post_disable(dpi->bridge); } static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) @@ -172,7 +176,9 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) u32 dpi_c = DPI_ENABLE | DPI_OUTPUT_ENABLE_MODE; int ret; - if (dpi->connector->display_info.num_bus_formats) { + drm_bridge_pre_enable(dpi->bridge); + + if (dpi->connector && dpi->connector->display_info.num_bus_formats) { u32 bus_format = dpi->connector->display_info.bus_formats[0]; switch (bus_format) { @@ -201,8 +207,13 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) DRM_ERROR("Unknown media bus format %d\n", bus_format); break; } + } else { + DRM_ERROR("mode=%p vc4_encoder=%p dpi=%p dpi->connector=%p\n", + mode, vc4_encoder, dpi, dpi->connector); + dpi_c |= VC4_SET_FIELD(DPI_FORMAT_18BIT_666_RGB_1, DPI_FORMAT); } + /* if (mode->flags & DRM_MODE_FLAG_NHSYNC) dpi_c |= DPI_HSYNC_INVERT; else if (!(mode->flags & DRM_MODE_FLAG_PHSYNC)) @@ -212,6 +223,7 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) dpi_c |= DPI_VSYNC_INVERT; else if (!(mode->flags & DRM_MODE_FLAG_PVSYNC)) dpi_c |= DPI_VSYNC_DISABLE; + */ DPI_WRITE(DPI_C, dpi_c); @@ -222,6 +234,8 @@ static void vc4_dpi_encoder_enable(struct drm_encoder *encoder) ret = clk_prepare_enable(dpi->pixel_clock); if (ret) DRM_ERROR("Failed to set clock rate: %d\n", ret); + + drm_bridge_enable(dpi->bridge); } static bool vc4_dpi_encoder_mode_fixup(struct drm_encoder *encoder, @@ -298,8 +312,10 @@ static int vc4_dpi_bind(struct device *dev, struct device *master, void *data) dpi->pdev = pdev; dpi->regs = vc4_ioremap_regs(pdev, 0); - if (IS_ERR(dpi->regs)) + if (IS_ERR(dpi->regs)) { + dev_err(dev, "DPI reg error: %ld\n", PTR_ERR(dpi->regs)); return PTR_ERR(dpi->regs); + } if (DPI_READ(DPI_ID) != DPI_ID_VALUE) { dev_err(dev, "Port returned 0x%08x for ID instead of 0x%08x\n", @@ -310,6 +326,7 @@ static int vc4_dpi_bind(struct device *dev, struct device *master, void *data) dpi->core_clock = devm_clk_get(dev, "core"); if (IS_ERR(dpi->core_clock)) { ret = PTR_ERR(dpi->core_clock); + dev_err(dev, "DPI core clock error: %d\n", ret); if (ret != -EPROBE_DEFER) DRM_ERROR("Failed to get core clock: %d\n", ret); return ret; @@ -317,6 +334,7 @@ static int vc4_dpi_bind(struct device *dev, struct device *master, void *data) dpi->pixel_clock = devm_clk_get(dev, "pixel"); if (IS_ERR(dpi->pixel_clock)) { ret = PTR_ERR(dpi->pixel_clock); + dev_err(dev, "DPI pixel clock error: %d\n", ret); if (ret != -EPROBE_DEFER) DRM_ERROR("Failed to get pixel clock: %d\n", ret); return ret; @@ -331,8 +349,10 @@ static int vc4_dpi_bind(struct device *dev, struct device *master, void *data) drm_encoder_helper_add(dpi->encoder, &vc4_dpi_encoder_helper_funcs); ret = vc4_dpi_init_bridge(dpi); - if (ret) + if (ret) { + dev_err(dev, "DPI bridge init error: %d\n", ret); goto err_destroy_encoder; + } dev_set_drvdata(dev, dpi);