diff options
| author | Dave Airlie <airlied@redhat.com> | 2015-01-20 19:16:24 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2015-01-20 19:16:24 -0500 |
| commit | b2eb0489809cf0b824357b6fa85aab1aabe3f063 (patch) | |
| tree | d6b4bf3f4bd2f63f00bbcb9afdf2c39f396504b5 | |
| parent | 4f4d89af78682f2ed1cf6745794804817f867bba (diff) | |
| parent | 906eff7fcada4186cde54eb89572fb774ab294a0 (diff) | |
Merge branch 'drm/next/du' of git://linuxtv.org/pinchartl/fbdev into drm-next
* 'drm/next/du' of git://linuxtv.org/pinchartl/fbdev:
drm: rcar-du: Implement support for interlaced modes
drm: rcar-du: Clamp DPMS states to on and off
drm: rcar-du: Enable hotplug detection on HDMI connector
drm: rcar-du: Output HSYNC instead of CSYNC
drm: rcar-du: Add support for external pixel clock
drm: rcar-du: Refactor DEFR8 feature
drm: rcar-du: Remove LVDS and HDMI encoders chaining restriction
drm: rcar-du: Configure pitch for chroma plane of multiplanar formats
drm: rcar-du: Don't fail probe in case of partial encoder init error
drm: adv7511: Remove interlaced mode check
| -rw-r--r-- | Documentation/devicetree/bindings/video/renesas,du.txt | 4 | ||||
| -rw-r--r-- | drivers/gpu/drm/i2c/adv7511.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 95 | ||||
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_drv.c | 6 | ||||
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_drv.h | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 34 | ||||
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_group.c | 21 | ||||
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c | 2 | ||||
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c | 18 | ||||
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_kms.c | 15 | ||||
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_plane.c | 20 | ||||
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_regs.h | 5 | ||||
| -rw-r--r-- | drivers/gpu/drm/rcar-du/rcar_du_vgacon.c | 1 |
14 files changed, 180 insertions, 47 deletions
diff --git a/Documentation/devicetree/bindings/video/renesas,du.txt b/Documentation/devicetree/bindings/video/renesas,du.txt index 5102830f2760..c902323928f7 100644 --- a/Documentation/devicetree/bindings/video/renesas,du.txt +++ b/Documentation/devicetree/bindings/video/renesas,du.txt | |||
| @@ -26,6 +26,10 @@ Required Properties: | |||
| 26 | per LVDS encoder. The functional clocks must be named "du.x" with "x" | 26 | per LVDS encoder. The functional clocks must be named "du.x" with "x" |
| 27 | being the channel numerical index. The LVDS clocks must be named | 27 | being the channel numerical index. The LVDS clocks must be named |
| 28 | "lvds.x" with "x" being the LVDS encoder numerical index. | 28 | "lvds.x" with "x" being the LVDS encoder numerical index. |
| 29 | - In addition to the functional and encoder clocks, all DU versions also | ||
| 30 | support externally supplied pixel clocks. Those clocks are optional. | ||
| 31 | When supplied they must be named "dclkin.x" with "x" being the input | ||
| 32 | clock numerical index. | ||
| 29 | 33 | ||
| 30 | Required nodes: | 34 | Required nodes: |
| 31 | 35 | ||
diff --git a/drivers/gpu/drm/i2c/adv7511.c b/drivers/gpu/drm/i2c/adv7511.c index faf1c0c5ab2e..fa140e04d5fa 100644 --- a/drivers/gpu/drm/i2c/adv7511.c +++ b/drivers/gpu/drm/i2c/adv7511.c | |||
| @@ -644,9 +644,6 @@ static int adv7511_encoder_mode_valid(struct drm_encoder *encoder, | |||
| 644 | if (mode->clock > 165000) | 644 | if (mode->clock > 165000) |
| 645 | return MODE_CLOCK_HIGH; | 645 | return MODE_CLOCK_HIGH; |
| 646 | 646 | ||
| 647 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
| 648 | return MODE_NO_INTERLACE; | ||
| 649 | |||
| 650 | return MODE_OK; | 647 | return MODE_OK; |
| 651 | } | 648 | } |
| 652 | 649 | ||
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c index 23cc910951f4..25c7a998fc2c 100644 --- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c | |||
| @@ -74,39 +74,77 @@ static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc) | |||
| 74 | if (ret < 0) | 74 | if (ret < 0) |
| 75 | return ret; | 75 | return ret; |
| 76 | 76 | ||
| 77 | ret = clk_prepare_enable(rcrtc->extclock); | ||
| 78 | if (ret < 0) | ||
| 79 | goto error_clock; | ||
| 80 | |||
| 77 | ret = rcar_du_group_get(rcrtc->group); | 81 | ret = rcar_du_group_get(rcrtc->group); |
| 78 | if (ret < 0) | 82 | if (ret < 0) |
| 79 | clk_disable_unprepare(rcrtc->clock); | 83 | goto error_group; |
| 84 | |||
| 85 | return 0; | ||
| 80 | 86 | ||
| 87 | error_group: | ||
| 88 | clk_disable_unprepare(rcrtc->extclock); | ||
| 89 | error_clock: | ||
| 90 | clk_disable_unprepare(rcrtc->clock); | ||
| 81 | return ret; | 91 | return ret; |
| 82 | } | 92 | } |
| 83 | 93 | ||
| 84 | static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc) | 94 | static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc) |
| 85 | { | 95 | { |
| 86 | rcar_du_group_put(rcrtc->group); | 96 | rcar_du_group_put(rcrtc->group); |
| 97 | |||
| 98 | clk_disable_unprepare(rcrtc->extclock); | ||
| 87 | clk_disable_unprepare(rcrtc->clock); | 99 | clk_disable_unprepare(rcrtc->clock); |
| 88 | } | 100 | } |
| 89 | 101 | ||
| 90 | static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) | 102 | static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) |
| 91 | { | 103 | { |
| 92 | const struct drm_display_mode *mode = &rcrtc->crtc.mode; | 104 | const struct drm_display_mode *mode = &rcrtc->crtc.mode; |
| 105 | unsigned long mode_clock = mode->clock * 1000; | ||
| 93 | unsigned long clk; | 106 | unsigned long clk; |
| 94 | u32 value; | 107 | u32 value; |
| 108 | u32 escr; | ||
| 95 | u32 div; | 109 | u32 div; |
| 96 | 110 | ||
| 97 | /* Dot clock */ | 111 | /* Compute the clock divisor and select the internal or external dot |
| 112 | * clock based on the requested frequency. | ||
| 113 | */ | ||
| 98 | clk = clk_get_rate(rcrtc->clock); | 114 | clk = clk_get_rate(rcrtc->clock); |
| 99 | div = DIV_ROUND_CLOSEST(clk, mode->clock * 1000); | 115 | div = DIV_ROUND_CLOSEST(clk, mode_clock); |
| 100 | div = clamp(div, 1U, 64U) - 1; | 116 | div = clamp(div, 1U, 64U) - 1; |
| 117 | escr = div | ESCR_DCLKSEL_CLKS; | ||
| 118 | |||
| 119 | if (rcrtc->extclock) { | ||
| 120 | unsigned long extclk; | ||
| 121 | unsigned long extrate; | ||
| 122 | unsigned long rate; | ||
| 123 | u32 extdiv; | ||
| 124 | |||
| 125 | extclk = clk_get_rate(rcrtc->extclock); | ||
| 126 | extdiv = DIV_ROUND_CLOSEST(extclk, mode_clock); | ||
| 127 | extdiv = clamp(extdiv, 1U, 64U) - 1; | ||
| 128 | |||
| 129 | rate = clk / (div + 1); | ||
| 130 | extrate = extclk / (extdiv + 1); | ||
| 131 | |||
| 132 | if (abs((long)extrate - (long)mode_clock) < | ||
| 133 | abs((long)rate - (long)mode_clock)) { | ||
| 134 | dev_dbg(rcrtc->group->dev->dev, | ||
| 135 | "crtc%u: using external clock\n", rcrtc->index); | ||
| 136 | escr = extdiv | ESCR_DCLKSEL_DCLKIN; | ||
| 137 | } | ||
| 138 | } | ||
| 101 | 139 | ||
| 102 | rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR, | 140 | rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR, |
| 103 | ESCR_DCLKSEL_CLKS | div); | 141 | escr); |
| 104 | rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0); | 142 | rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0); |
| 105 | 143 | ||
| 106 | /* Signal polarities */ | 144 | /* Signal polarities */ |
| 107 | value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : DSMR_VSL) | 145 | value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : DSMR_VSL) |
| 108 | | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : DSMR_HSL) | 146 | | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : DSMR_HSL) |
| 109 | | DSMR_DIPM_DE; | 147 | | DSMR_DIPM_DE | DSMR_CSPM; |
| 110 | rcar_du_crtc_write(rcrtc, DSMR, value); | 148 | rcar_du_crtc_write(rcrtc, DSMR, value); |
| 111 | 149 | ||
| 112 | /* Display timings */ | 150 | /* Display timings */ |
| @@ -117,12 +155,15 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) | |||
| 117 | mode->hsync_start - 1); | 155 | mode->hsync_start - 1); |
| 118 | rcar_du_crtc_write(rcrtc, HCR, mode->htotal - 1); | 156 | rcar_du_crtc_write(rcrtc, HCR, mode->htotal - 1); |
| 119 | 157 | ||
| 120 | rcar_du_crtc_write(rcrtc, VDSR, mode->vtotal - mode->vsync_end - 2); | 158 | rcar_du_crtc_write(rcrtc, VDSR, mode->crtc_vtotal - |
| 121 | rcar_du_crtc_write(rcrtc, VDER, mode->vtotal - mode->vsync_end + | 159 | mode->crtc_vsync_end - 2); |
| 122 | mode->vdisplay - 2); | 160 | rcar_du_crtc_write(rcrtc, VDER, mode->crtc_vtotal - |
| 123 | rcar_du_crtc_write(rcrtc, VSPR, mode->vtotal - mode->vsync_end + | 161 | mode->crtc_vsync_end + |
| 124 | mode->vsync_start - 1); | 162 | mode->crtc_vdisplay - 2); |
| 125 | rcar_du_crtc_write(rcrtc, VCR, mode->vtotal - 1); | 163 | rcar_du_crtc_write(rcrtc, VSPR, mode->crtc_vtotal - |
| 164 | mode->crtc_vsync_end + | ||
| 165 | mode->crtc_vsync_start - 1); | ||
| 166 | rcar_du_crtc_write(rcrtc, VCR, mode->crtc_vtotal - 1); | ||
| 126 | 167 | ||
| 127 | rcar_du_crtc_write(rcrtc, DESR, mode->htotal - mode->hsync_start); | 168 | rcar_du_crtc_write(rcrtc, DESR, mode->htotal - mode->hsync_start); |
| 128 | rcar_du_crtc_write(rcrtc, DEWR, mode->hdisplay); | 169 | rcar_du_crtc_write(rcrtc, DEWR, mode->hdisplay); |
| @@ -139,9 +180,10 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc, | |||
| 139 | */ | 180 | */ |
| 140 | rcrtc->outputs |= BIT(output); | 181 | rcrtc->outputs |= BIT(output); |
| 141 | 182 | ||
| 142 | /* Store RGB routing to DPAD0 for R8A7790. */ | 183 | |
