Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+93 -133
+93 -133
drivers/gpu/drm/tegra/sor.c
··· 718 718 tegra_sor_writel(sor, value, SOR_DP_AUDIO_VBLANK_SYMBOLS); 719 719 } 720 720 721 + static 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 + 721 798 static int tegra_sor_detach(struct tegra_sor *sor) 722 799 { 723 800 unsigned long value, timeout; ··· 1327 1250 struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; 1328 1251 struct tegra_output *output = encoder_to_output(encoder); 1329 1252 struct tegra_dc *dc = to_tegra_dc(encoder->crtc); 1330 - unsigned int vbe, vse, hbe, hse, vbs, hbs, i; 1331 1253 struct tegra_sor *sor = to_sor(output); 1332 1254 struct tegra_sor_config config; 1255 + struct drm_display_info *info; 1333 1256 struct drm_dp_link link; 1334 1257 u8 rate, lanes; 1258 + unsigned int i; 1335 1259 int err = 0; 1336 1260 u32 value; 1261 + 1262 + info = &output->connector.display_info; 1337 1263 1338 1264 err = clk_prepare_enable(sor->clk); 1339 1265 if (err < 0) ··· 1585 1505 if (err < 0) 1586 1506 dev_err(sor->dev, "failed to power up SOR: %d\n", err); 1587 1507 1588 - /* 1589 - * configure panel (24bpp, vsync-, hsync-, DP-A protocol, complete 1590 - * raster, associate with display controller) 1591 - */ 1592 - value = SOR_STATE_ASY_PROTOCOL_DP_A | 1593 - SOR_STATE_ASY_CRC_MODE_COMPLETE | 1594 - SOR_STATE_ASY_OWNER(dc->pipe + 1); 1595 - 1596 - if (mode->flags & DRM_MODE_FLAG_PHSYNC) 1597 - value &= ~SOR_STATE_ASY_HSYNCPOL; 1598 - 1599 - if (mode->flags & DRM_MODE_FLAG_NHSYNC) 1600 - value |= SOR_STATE_ASY_HSYNCPOL; 1601 - 1602 - if (mode->flags & DRM_MODE_FLAG_PVSYNC) 1603 - value &= ~SOR_STATE_ASY_VSYNCPOL; 1604 - 1605 - if (mode->flags & DRM_MODE_FLAG_NVSYNC) 1606 - value |= SOR_STATE_ASY_VSYNCPOL; 1607 - 1608 - switch (config.bits_per_pixel) { 1609 - case 24: 1610 - value |= SOR_STATE_ASY_PIXELDEPTH_BPP_24_444; 1611 - break; 1612 - 1613 - case 18: 1614 - value |= SOR_STATE_ASY_PIXELDEPTH_BPP_18_444; 1615 - break; 1616 - 1617 - default: 1618 - BUG(); 1619 - break; 1620 - } 1621 - 1622 - tegra_sor_writel(sor, value, SOR_STATE1); 1623 - 1624 - /* 1625 - * TODO: The video timing programming below doesn't seem to match the 1626 - * register definitions. 1627 - */ 1628 - 1629 - value = ((mode->vtotal & 0x7fff) << 16) | (mode->htotal & 0x7fff); 1630 - tegra_sor_writel(sor, value, SOR_HEAD_STATE1(dc->pipe)); 1631 - 1632 - vse = mode->vsync_end - mode->vsync_start - 1; 1633 - hse = mode->hsync_end - mode->hsync_start - 1; 1634 - 1635 - value = ((vse & 0x7fff) << 16) | (hse & 0x7fff); 1636 - tegra_sor_writel(sor, value, SOR_HEAD_STATE2(dc->pipe)); 1637 - 1638 - vbe = vse + (mode->vsync_start - mode->vdisplay); 1639 - hbe = hse + (mode->hsync_start - mode->hdisplay); 1640 - 1641 - value = ((vbe & 0x7fff) << 16) | (hbe & 0x7fff); 1642 - tegra_sor_writel(sor, value, SOR_HEAD_STATE3(dc->pipe)); 1643 - 1644 - vbs = vbe + mode->vdisplay; 1645 - hbs = hbe + mode->hdisplay; 1646 - 1647 - value = ((vbs & 0x7fff) << 16) | (hbs & 0x7fff); 1648 - tegra_sor_writel(sor, value, SOR_HEAD_STATE4(dc->pipe)); 1649 - 1650 - tegra_sor_writel(sor, 0x1, SOR_HEAD_STATE5(dc->pipe)); 1651 - 1652 1508 /* CSTM (LVDS, link A/B, upper) */ 1653 1509 value = SOR_CSTM_LVDS | SOR_CSTM_LINK_ACT_A | SOR_CSTM_LINK_ACT_B | 1654 1510 SOR_CSTM_UPPER; 1655 1511 tegra_sor_writel(sor, value, SOR_CSTM); 1512 + 1513 + /* use DP-A protocol */ 1514 + value = tegra_sor_readl(sor, SOR_STATE1); 1515 + value &= ~SOR_STATE_ASY_PROTOCOL_MASK; 1516 + value |= SOR_STATE_ASY_PROTOCOL_DP_A; 1517 + tegra_sor_writel(sor, value, SOR_STATE1); 1518 + 1519 + tegra_sor_mode_set(sor, mode, info); 1656 1520 1657 1521 /* PWM setup */ 1658 1522 err = tegra_sor_setup_pwm(sor, 250); ··· 1813 1789 struct tegra_output *output = encoder_to_output(encoder); 1814 1790 unsigned int h_ref_to_sync = 1, pulse_start, max_ac; 1815 1791 struct tegra_dc *dc = to_tegra_dc(encoder->crtc); 1816 - unsigned int vbe, vse, hbe, hse, vbs, hbs, div; 1817 1792 struct tegra_sor_hdmi_settings *settings; 1818 1793 struct tegra_sor *sor = to_sor(output); 1819 1794 struct drm_display_mode *mode; 1820 1795 struct drm_display_info *info; 1796 + unsigned int div; 1821 1797 u32 value; 1822 1798 int err; 1823 1799 ··· 2075 2051 if (err < 0) 2076 2052 dev_err(sor->dev, "failed to power up SOR: %d\n", err); 2077 2053 2078 - /* configure mode */ 2079 - value = tegra_sor_readl(sor, SOR_STATE1); 2080 - value &= ~SOR_STATE_ASY_PIXELDEPTH_MASK; 2081 - value &= ~SOR_STATE_ASY_CRC_MODE_MASK; 2082 - value &= ~SOR_STATE_ASY_OWNER_MASK; 2083 - 2084 - value |= SOR_STATE_ASY_CRC_MODE_COMPLETE | 2085 - SOR_STATE_ASY_OWNER(dc->pipe + 1); 2086 - 2087 - if (mode->flags & DRM_MODE_FLAG_PHSYNC) 2088 - value &= ~SOR_STATE_ASY_HSYNCPOL; 2089 - 2090 - if (mode->flags & DRM_MODE_FLAG_NHSYNC) 2091 - value |= SOR_STATE_ASY_HSYNCPOL; 2092 - 2093 - if (mode->flags & DRM_MODE_FLAG_PVSYNC) 2094 - value &= ~SOR_STATE_ASY_VSYNCPOL; 2095 - 2096 - if (mode->flags & DRM_MODE_FLAG_NVSYNC) 2097 - value |= SOR_STATE_ASY_VSYNCPOL; 2098 - 2099 - switch (info->bpc) { 2100 - case 8: 2101 - value |= SOR_STATE_ASY_PIXELDEPTH_BPP_24_444; 2102 - break; 2103 - 2104 - case 6: 2105 - value |= SOR_STATE_ASY_PIXELDEPTH_BPP_18_444; 2106 - break; 2107 - 2108 - default: 2109 - BUG(); 2110 - break; 2111 - } 2112 - 2113 - tegra_sor_writel(sor, value, SOR_STATE1); 2114 - 2054 + /* configure dynamic range of output */ 2115 2055 value = tegra_sor_readl(sor, SOR_HEAD_STATE0(dc->pipe)); 2116 2056 value &= ~SOR_HEAD_STATE_RANGECOMPRESS_MASK; 2117 2057 value &= ~SOR_HEAD_STATE_DYNRANGE_MASK; 2118 2058 tegra_sor_writel(sor, value, SOR_HEAD_STATE0(dc->pipe)); 2119 2059 2060 + /* configure colorspace */ 2120 2061 value = tegra_sor_readl(sor, SOR_HEAD_STATE0(dc->pipe)); 2121 2062 value &= ~SOR_HEAD_STATE_COLORSPACE_MASK; 2122 2063 value |= SOR_HEAD_STATE_COLORSPACE_RGB; 2123 2064 tegra_sor_writel(sor, value, SOR_HEAD_STATE0(dc->pipe)); 2124 2065 2125 - /* 2126 - * TODO: The video timing programming below doesn't seem to match the 2127 - * register definitions. 2128 - */ 2129 - 2130 - value = ((mode->vtotal & 0x7fff) << 16) | (mode->htotal & 0x7fff); 2131 - tegra_sor_writel(sor, value, SOR_HEAD_STATE1(dc->pipe)); 2132 - 2133 - /* sync end = sync width - 1 */ 2134 - vse = mode->vsync_end - mode->vsync_start - 1; 2135 - hse = mode->hsync_end - mode->hsync_start - 1; 2136 - 2137 - value = ((vse & 0x7fff) << 16) | (hse & 0x7fff); 2138 - tegra_sor_writel(sor, value, SOR_HEAD_STATE2(dc->pipe)); 2139 - 2140 - /* blank end = sync end + back porch */ 2141 - vbe = vse + (mode->vtotal - mode->vsync_end); 2142 - hbe = hse + (mode->htotal - mode->hsync_end); 2143 - 2144 - value = ((vbe & 0x7fff) << 16) | (hbe & 0x7fff); 2145 - tegra_sor_writel(sor, value, SOR_HEAD_STATE3(dc->pipe)); 2146 - 2147 - /* blank start = blank end + active */ 2148 - vbs = vbe + mode->vdisplay; 2149 - hbs = hbe + mode->hdisplay; 2150 - 2151 - value = ((vbs & 0x7fff) << 16) | (hbs & 0x7fff); 2152 - tegra_sor_writel(sor, value, SOR_HEAD_STATE4(dc->pipe)); 2153 - 2154 - tegra_sor_writel(sor, 0x1, SOR_HEAD_STATE5(dc->pipe)); 2066 + tegra_sor_mode_set(sor, mode, info); 2155 2067 2156 2068 tegra_sor_update(sor); 2157 2069