aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2015-08-03 09:46:15 -0400
committerThierry Reding <treding@nvidia.com>2016-07-04 05:31:22 -0400
commit2bd1dd399fcd2e23efb1583df3ba846b20429739 (patch)
treedf261b36112856380b6e46184a36ee2e7efc2a82
parent402f6bcd94fa3437b833931da8e1fbfc1fb6c444 (diff)
drm/tegra: sor: Extract tegra_sor_mode_set()
The code to set a video mode is common to all types of outputs that the SOR can drive. Extract it into a separate function so that it can be shared. Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/gpu/drm/tegra/sor.c226
1 files changed, 93 insertions, 133 deletions
diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c
index 5d9a9f2ba4de..01b31805f719 100644
--- a/drivers/gpu/drm/tegra/sor.c
+++ b/drivers/gpu/drm/tegra/sor.c
@@ -718,6 +718,83 @@ static void tegra_sor_apply_config(struct tegra_sor *sor,
718 tegra_sor_writel(sor, value, SOR_DP_AUDIO_VBLANK_SYMBOLS); 718 tegra_sor_writel(sor, value, SOR_DP_AUDIO_VBLANK_SYMBOLS);
719} 719}
720 720
721static void tegra_sor_mode_set(struct tegra_sor *sor,
722 const struct drm_display_mode *mode,
723 const struct drm_display_info *info)
724{
725 struct tegra_dc *dc = to_tegra_dc(sor->output.encoder.crtc);
726 unsigned int vbe, vse, hbe, hse, vbs, hbs;
727 u32 value;
728
729 value = tegra_sor_readl(sor, SOR_STATE1);
730 value &= ~SOR_STATE_ASY_PIXELDEPTH_MASK;
731 value &= ~SOR_STATE_ASY_CRC_MODE_MASK;
732 value &= ~SOR_STATE_ASY_OWNER_MASK;
733
734 value |= SOR_STATE_ASY_CRC_MODE_COMPLETE |
735 SOR_STATE_ASY_OWNER(dc->pipe + 1);
736
737 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
738 value &= ~SOR_STATE_ASY_HSYNCPOL;
739
740 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
741 value |= SOR_STATE_ASY_HSYNCPOL;
742
743 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
744 value &= ~SOR_STATE_ASY_VSYNCPOL;
745
746 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
747 value |= SOR_STATE_ASY_VSYNCPOL;
748
749 switch (info->bpc) {
750 case 8:
751 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_24_444;
752 break;
753
754 case 6:
755 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_18_444;
756 break;
757
758 default:
759 BUG();
760 break;
761 }
762
763 tegra_sor_writel(sor, value, SOR_STATE1);
764
765 /*
766 * TODO: The video timing programming below doesn't seem to match the
767 * register definitions.
768 */
769
770 value = ((mode->vtotal & 0x7fff) << 16) | (mode->htotal & 0x7fff);
771 tegra_sor_writel(sor, value, SOR_HEAD_STATE1(dc->pipe));
772
773 /* sync end = sync width - 1 */
774 vse = mode->vsync_end - mode->vsync_start - 1;
775 hse = mode->hsync_end - mode->hsync_start - 1;
776
777 value = ((vse & 0x7fff) << 16) | (hse & 0x7fff);
778 tegra_sor_writel(sor, value, SOR_HEAD_STATE2(dc->pipe));
779
780 /* blank end = sync end + back porch */
781 vbe = vse + (mode->vtotal - mode->vsync_end);
782 hbe = hse + (mode->htotal - mode->hsync_end);
783
784 value = ((vbe & 0x7fff) << 16) | (hbe & 0x7fff);
785 tegra_sor_writel(sor, value, SOR_HEAD_STATE3(dc->pipe));
786
787 /* blank start = blank end + active */
788 vbs = vbe + mode->vdisplay;
789 hbs = hbe + mode->hdisplay;
790
791 value = ((vbs & 0x7fff) << 16) | (hbs & 0x7fff);
792 tegra_sor_writel(sor, value, SOR_HEAD_STATE4(dc->pipe));
793
794 /* XXX interlacing support */
795 tegra_sor_writel(sor, 0x001, SOR_HEAD_STATE5(dc->pipe));
796}
797
721static int tegra_sor_detach(struct tegra_sor *sor) 798static int tegra_sor_detach(struct tegra_sor *sor)
722{ 799{
723 unsigned long value, timeout; 800 unsigned long value, timeout;
@@ -1250,14 +1327,17 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
1250 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; 1327 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
1251 struct tegra_output *output = encoder_to_output(encoder); 1328 struct tegra_output *output = encoder_to_output(encoder);
1252 struct tegra_dc *dc = to_tegra_dc(encoder->crtc); 1329 struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
1253 unsigned int vbe, vse, hbe, hse, vbs, hbs, i;
1254 struct tegra_sor *sor = to_sor(output); 1330 struct tegra_sor *sor = to_sor(output);
1255 struct tegra_sor_config config; 1331 struct tegra_sor_config config;
1332 struct drm_display_info *info;
1256 struct drm_dp_link link; 1333 struct drm_dp_link link;
1257 u8 rate, lanes; 1334 u8 rate, lanes;
1335 unsigned int i;
1258 int err = 0; 1336 int err = 0;
1259 u32 value; 1337 u32 value;
1260 1338
1339 info = &output->connector.display_info;
1340
1261 err = clk_prepare_enable(sor->clk); 1341 err = clk_prepare_enable(sor->clk);
1262 if (err < 0) 1342 if (err < 0)
1263 dev_err(sor->dev, "failed to enable clock: %d\n", err); 1343 dev_err(sor->dev, "failed to enable clock: %d\n", err);
@@ -1505,75 +1585,19 @@ static void tegra_sor_edp_enable(struct drm_encoder *encoder)
1505 if (err < 0) 1585 if (err < 0)
1506 dev_err(sor->dev, "failed to power up SOR: %d\n", err); 1586 dev_err(sor->dev, "failed to power up SOR: %d\n", err);
1507 1587
1508 /*
1509 * configure panel (24bpp, vsync-, hsync-, DP-A protocol, complete
1510 * raster, associate with display controller)
1511 */
1512 value = SOR_STATE_ASY_PROTOCOL_DP_A |
1513 SOR_STATE_ASY_CRC_MODE_COMPLETE |
1514 SOR_STATE_ASY_OWNER(dc->pipe + 1);
1515
1516 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
1517 value &= ~SOR_STATE_ASY_HSYNCPOL;
1518
1519 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
1520 value |= SOR_STATE_ASY_HSYNCPOL;
1521
1522 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
1523 value &= ~SOR_STATE_ASY_VSYNCPOL;
1524
1525 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
1526 value |= SOR_STATE_ASY_VSYNCPOL;
1527
1528 switch (config.bits_per_pixel) {
1529 case 24:
1530 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_24_444;
1531 break;
1532
1533 case 18:
1534 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_18_444;
1535 break;
1536
1537 default:
1538 BUG();
1539 break;
1540 }
1541
1542 tegra_sor_writel(sor, value, SOR_STATE1);
1543
1544 /*
1545 * TODO: The video timing programming below doesn't seem to match the
1546 * register definitions.
1547 */
1548
1549 value = ((mode->vtotal & 0x7fff) << 16) | (mode->htotal & 0x7fff);
1550 tegra_sor_writel(sor, value, SOR_HEAD_STATE1(dc->pipe));
1551
1552 vse = mode->vsync_end - mode->vsync_start - 1;
1553 hse = mode->hsync_end - mode->hsync_start - 1;
1554
1555 value = ((vse & 0x7fff) << 16) | (hse & 0x7fff);
1556 tegra_sor_writel(sor, value, SOR_HEAD_STATE2(dc->pipe));
1557
1558 vbe = vse + (mode->vsync_start - mode->vdisplay);
1559 hbe = hse + (mode->hsync_start - mode->hdisplay);
1560
1561 value = ((vbe & 0x7fff) << 16) | (hbe & 0x7fff);
1562 tegra_sor_writel(sor, value, SOR_HEAD_STATE3(dc->pipe));
1563
1564 vbs = vbe + mode->vdisplay;
1565 hbs = hbe + mode->hdisplay;
1566
1567 value = ((vbs & 0x7fff) << 16) | (hbs & 0x7fff);
1568 tegra_sor_writel(sor, value, SOR_HEAD_STATE4(dc->pipe));
1569
1570 tegra_sor_writel(sor, 0x1, SOR_HEAD_STATE5(dc->pipe));
1571
1572 /* CSTM (LVDS, link A/B, upper) */ 1588 /* CSTM (LVDS, link A/B, upper) */
1573 value = SOR_CSTM_LVDS | SOR_CSTM_LINK_ACT_A | SOR_CSTM_LINK_ACT_B | 1589 value = SOR_CSTM_LVDS | SOR_CSTM_LINK_ACT_A | SOR_CSTM_LINK_ACT_B |
1574 SOR_CSTM_UPPER; 1590 SOR_CSTM_UPPER;
1575 tegra_sor_writel(sor, value, SOR_CSTM); 1591 tegra_sor_writel(sor, value, SOR_CSTM);
1576 1592
1593 /* use DP-A protocol */
1594 value = tegra_sor_readl(sor, SOR_STATE1);
1595 value &= ~SOR_STATE_ASY_PROTOCOL_MASK;
1596 value |= SOR_STATE_ASY_PROTOCOL_DP_A;
1597 tegra_sor_writel(sor, value, SOR_STATE1);
1598
1599 tegra_sor_mode_set(sor, mode, info);
1600
1577 /* PWM setup */ 1601 /* PWM setup */
1578 err = tegra_sor_setup_pwm(sor, 250); 1602 err = tegra_sor_setup_pwm(sor, 250);
1579 if (err < 0) 1603 if (err < 0)
@@ -1789,11 +1813,11 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
1789 struct tegra_output *output = encoder_to_output(encoder); 1813 struct tegra_output *output = encoder_to_output(encoder);
1790 unsigned int h_ref_to_sync = 1, pulse_start, max_ac; 1814 unsigned int h_ref_to_sync = 1, pulse_start, max_ac;
1791 struct tegra_dc *dc = to_tegra_dc(encoder->crtc); 1815 struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
1792 unsigned int vbe, vse, hbe, hse, vbs, hbs, div;
1793 struct tegra_sor_hdmi_settings *settings; 1816 struct tegra_sor_hdmi_settings *settings;
1794 struct tegra_sor *sor = to_sor(output); 1817 struct tegra_sor *sor = to_sor(output);
1795 struct drm_display_mode *mode; 1818 struct drm_display_mode *mode;
1796 struct drm_display_info *info; 1819 struct drm_display_info *info;
1820 unsigned int div;
1797 u32 value; 1821 u32 value;
1798 int err; 1822 int err;
1799 1823
@@ -2051,83 +2075,19 @@ static void tegra_sor_hdmi_enable(struct drm_encoder *encoder)
2051 if (err < 0) 2075 if (err < 0)
2052 dev_err(sor->dev, "failed to power up SOR: %d\n", err); 2076 dev_err(sor->dev, "failed to power up SOR: %d\n", err);
2053 2077
2054 /* configure mode */ 2078 /* configure dynamic range of output */
2055 value = tegra_sor_readl(sor, SOR_STATE1);
2056 value &= ~SOR_STATE_ASY_PIXELDEPTH_MASK;
2057 value &= ~SOR_STATE_ASY_CRC_MODE_MASK;
2058 value &= ~SOR_STATE_ASY_OWNER_MASK;
2059
2060 value |= SOR_STATE_ASY_CRC_MODE_COMPLETE |
2061 SOR_STATE_ASY_OWNER(dc->pipe + 1);
2062
2063 if (mode->flags & DRM_MODE_FLAG_PHSYNC)
2064 value &= ~SOR_STATE_ASY_HSYNCPOL;
2065
2066 if (mode->flags & DRM_MODE_FLAG_NHSYNC)
2067 value |= SOR_STATE_ASY_HSYNCPOL;
2068
2069 if (mode->flags & DRM_MODE_FLAG_PVSYNC)
2070 value &= ~SOR_STATE_ASY_VSYNCPOL;
2071
2072 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
2073 value |= SOR_STATE_ASY_VSYNCPOL;
2074
2075 switch (info->bpc) {
2076 case 8:
2077 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_24_444;
2078 break;
2079
2080 case 6:
2081 value |= SOR_STATE_ASY_PIXELDEPTH_BPP_18_444;
2082 break;
2083
2084 default:
2085 BUG();
2086 break;
2087 }
2088
2089 tegra_sor_writel(sor, value, SOR_STATE1);
2090
2091 value = tegra_sor_readl(sor, SOR_HEAD_STATE0(dc->pipe)); 2079 value = tegra_sor_readl(sor, SOR_HEAD_STATE0(dc->pipe));
2092 value &= ~SOR_HEAD_STATE_RANGECOMPRESS_MASK; 2080 value &= ~SOR_HEAD_STATE_RANGECOMPRESS_MASK;
2093 value &= ~SOR_HEAD_STATE_DYNRANGE_MASK; 2081 value &= ~SOR_HEAD_STATE_DYNRANGE_MASK;
2094 tegra_sor_writel(sor, value, SOR_HEAD_STATE0(dc->pipe)); 2082 tegra_sor_writel(sor, value, SOR_HEAD_STATE0(dc->pipe));
2095 2083
2084 /* configure colorspace */
2096 value = tegra_sor_readl(sor, SOR_HEAD_STATE0(dc->pipe)); 2085 value = tegra_sor_readl(sor, SOR_HEAD_STATE0(dc->pipe));
2097 value &= ~SOR_HEAD_STATE_COLORSPACE_MASK; 2086 value &= ~SOR_HEAD_STATE_COLORSPACE_MASK;
2098 value |= SOR_HEAD_STATE_COLORSPACE_RGB; 2087 value |= SOR_HEAD_STATE_COLORSPACE_RGB;
2099 tegra_sor_writel(sor, value, SOR_HEAD_STATE0(dc->pipe)); 2088 tegra_sor_writel(sor, value, SOR_HEAD_STATE0(dc->pipe));
2100 2089
2101 /* 2090 tegra_sor_mode_set(sor, mode, info);
2102 * TODO: The video timing programming below doesn't seem to match the
2103 * register definitions.
2104 */
2105
2106 value = ((mode->vtotal & 0x7fff) << 16) | (mode->htotal & 0x7fff);
2107 tegra_sor_writel(sor, value, SOR_HEAD_STATE1(dc->pipe));
2108
2109 /* sync end = sync width - 1 */
2110 vse = mode->vsync_end - mode->vsync_start - 1;
2111 hse = mode->hsync_end - mode->hsync_start - 1;
2112
2113 value = ((vse & 0x7fff) << 16) | (hse & 0x7fff);
2114 tegra_sor_writel(sor, value, SOR_HEAD_STATE2(dc->pipe));
2115
2116 /* blank end = sync end + back porch */
2117 vbe = vse + (mode->vtotal - mode->vsync_end);
2118 hbe = hse + (mode->htotal - mode->hsync_end);
2119
2120 value = ((vbe & 0x7fff) << 16) | (hbe & 0x7fff);
2121 tegra_sor_writel(sor, value, SOR_HEAD_STATE3(dc->pipe));
2122
2123 /* blank start = blank end + active */
2124 vbs = vbe + mode->vdisplay;
2125 hbs = hbe + mode->hdisplay;
2126
2127 value = ((vbs & 0x7fff) << 16) | (hbs & 0x7fff);
2128 tegra_sor_writel(sor, value, SOR_HEAD_STATE4(dc->pipe));
2129
2130 tegra_sor_writel(sor, 0x1, SOR_HEAD_STATE5(dc->pipe));
2131 2091
2132 tegra_sor_update(sor); 2092 tegra_sor_update(sor);
2133 2093