|
6 | 6 | */ |
7 | 7 |
|
8 | 8 | #include <linux/export.h> |
| 9 | +#include <linux/iopoll.h> |
9 | 10 |
|
10 | 11 | #include <drm/drm_modes.h> |
11 | 12 |
|
@@ -1557,6 +1558,205 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic, |
1557 | 1558 | } |
1558 | 1559 | EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set); |
1559 | 1560 |
|
| 1561 | +static unsigned short meson_encl_gamma_table[256] = { |
| 1562 | + 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, |
| 1563 | + 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, |
| 1564 | + 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188, |
| 1565 | + 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252, |
| 1566 | + 256, 260, 264, 268, 272, 276, 280, 284, 288, 292, 296, 300, 304, 308, 312, 316, |
| 1567 | + 320, 324, 328, 332, 336, 340, 344, 348, 352, 356, 360, 364, 368, 372, 376, 380, |
| 1568 | + 384, 388, 392, 396, 400, 404, 408, 412, 416, 420, 424, 428, 432, 436, 440, 444, |
| 1569 | + 448, 452, 456, 460, 464, 468, 472, 476, 480, 484, 488, 492, 496, 500, 504, 508, |
| 1570 | + 512, 516, 520, 524, 528, 532, 536, 540, 544, 548, 552, 556, 560, 564, 568, 572, |
| 1571 | + 576, 580, 584, 588, 592, 596, 600, 604, 608, 612, 616, 620, 624, 628, 632, 636, |
| 1572 | + 640, 644, 648, 652, 656, 660, 664, 668, 672, 676, 680, 684, 688, 692, 696, 700, |
| 1573 | + 704, 708, 712, 716, 720, 724, 728, 732, 736, 740, 744, 748, 752, 756, 760, 764, |
| 1574 | + 768, 772, 776, 780, 784, 788, 792, 796, 800, 804, 808, 812, 816, 820, 824, 828, |
| 1575 | + 832, 836, 840, 844, 848, 852, 856, 860, 864, 868, 872, 876, 880, 884, 888, 892, |
| 1576 | + 896, 900, 904, 908, 912, 916, 920, 924, 928, 932, 936, 940, 944, 948, 952, 956, |
| 1577 | + 960, 964, 968, 972, 976, 980, 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016, 1020, |
| 1578 | +}; |
| 1579 | + |
| 1580 | +static void meson_encl_set_gamma_table(struct meson_drm *priv, u16 *data, |
| 1581 | + u32 rgb_mask) |
| 1582 | +{ |
| 1583 | + int i, ret; |
| 1584 | + u32 reg; |
| 1585 | + |
| 1586 | + writel_bits_relaxed(L_GAMMA_CNTL_PORT_EN, 0, |
| 1587 | + priv->io_base + _REG(L_GAMMA_CNTL_PORT)); |
| 1588 | + |
| 1589 | + ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT), |
| 1590 | + reg, reg & L_GAMMA_CNTL_PORT_ADR_RDY, 10, 10000); |
| 1591 | + if (ret) |
| 1592 | + pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__); |
| 1593 | + |
| 1594 | + writel_relaxed(L_GAMMA_ADDR_PORT_AUTO_INC | rgb_mask | |
| 1595 | + FIELD_PREP(L_GAMMA_ADDR_PORT_ADDR, 0), |
| 1596 | + priv->io_base + _REG(L_GAMMA_ADDR_PORT)); |
| 1597 | + |
| 1598 | + for (i = 0; i < 256; i++) { |
| 1599 | + ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT), |
| 1600 | + reg, reg & L_GAMMA_CNTL_PORT_WR_RDY, |
| 1601 | + 10, 10000); |
| 1602 | + if (ret) |
| 1603 | + pr_warn_once("%s: GAMMA WR_RDY timeout\n", __func__); |
| 1604 | + |
| 1605 | + writel_relaxed(data[i], priv->io_base + _REG(L_GAMMA_DATA_PORT)); |
| 1606 | + } |
| 1607 | + |
| 1608 | + ret = readl_relaxed_poll_timeout(priv->io_base + _REG(L_GAMMA_CNTL_PORT), |
| 1609 | + reg, reg & L_GAMMA_CNTL_PORT_ADR_RDY, 10, 10000); |
| 1610 | + if (ret) |
| 1611 | + pr_warn("%s: GAMMA ADR_RDY timeout\n", __func__); |
| 1612 | + |
| 1613 | + writel_relaxed(L_GAMMA_ADDR_PORT_AUTO_INC | rgb_mask | |
| 1614 | + FIELD_PREP(L_GAMMA_ADDR_PORT_ADDR, 0x23), |
| 1615 | + priv->io_base + _REG(L_GAMMA_ADDR_PORT)); |
| 1616 | +} |
| 1617 | + |
| 1618 | +void meson_encl_load_gamma(struct meson_drm *priv) |
| 1619 | +{ |
| 1620 | + meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_R); |
| 1621 | + meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_G); |
| 1622 | + meson_encl_set_gamma_table(priv, meson_encl_gamma_table, L_GAMMA_ADDR_PORT_SEL_B); |
| 1623 | + |
| 1624 | + writel_bits_relaxed(L_GAMMA_CNTL_PORT_EN, L_GAMMA_CNTL_PORT_EN, |
| 1625 | + priv->io_base + _REG(L_GAMMA_CNTL_PORT)); |
| 1626 | +} |
| 1627 | + |
| 1628 | +void meson_venc_mipi_dsi_mode_set(struct meson_drm *priv, |
| 1629 | + const struct drm_display_mode *mode) |
| 1630 | +{ |
| 1631 | + unsigned int max_pxcnt; |
| 1632 | + unsigned int max_lncnt; |
| 1633 | + unsigned int havon_begin; |
| 1634 | + unsigned int havon_end; |
| 1635 | + unsigned int vavon_bline; |
| 1636 | + unsigned int vavon_eline; |
| 1637 | + unsigned int hso_begin; |
| 1638 | + unsigned int hso_end; |
| 1639 | + unsigned int vso_begin; |
| 1640 | + unsigned int vso_end; |
| 1641 | + unsigned int vso_bline; |
| 1642 | + unsigned int vso_eline; |
| 1643 | + |
| 1644 | + max_pxcnt = mode->htotal - 1; |
| 1645 | + max_lncnt = mode->vtotal - 1; |
| 1646 | + havon_begin = mode->htotal - mode->hsync_start; |
| 1647 | + havon_end = havon_begin + mode->hdisplay - 1; |
| 1648 | + vavon_bline = mode->vtotal - mode->vsync_start; |
| 1649 | + vavon_eline = vavon_bline + mode->vdisplay - 1; |
| 1650 | + hso_begin = 0; |
| 1651 | + hso_end = mode->hsync_end - mode->hsync_start; |
| 1652 | + vso_begin = 0; |
| 1653 | + vso_end = 0; |
| 1654 | + vso_bline = 0; |
| 1655 | + vso_eline = mode->vsync_end - mode->vsync_start; |
| 1656 | + |
| 1657 | + meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCL); |
| 1658 | + |
| 1659 | + writel_relaxed(0, priv->io_base + _REG(ENCL_VIDEO_EN)); |
| 1660 | + |
| 1661 | + writel_relaxed(ENCL_PX_LN_CNT_SHADOW_EN, priv->io_base + _REG(ENCL_VIDEO_MODE)); |
| 1662 | + writel_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN | |
| 1663 | + ENCL_VIDEO_MODE_ADV_GAIN_HDTV | |
| 1664 | + ENCL_SEL_GAMMA_RGB_IN, priv->io_base + _REG(ENCL_VIDEO_MODE_ADV)); |
| 1665 | + |
| 1666 | + writel_relaxed(ENCL_VIDEO_FILT_CTRL_BYPASS_FILTER, |
| 1667 | + priv->io_base + _REG(ENCL_VIDEO_FILT_CTRL)); |
| 1668 | + writel_relaxed(max_pxcnt, priv->io_base + _REG(ENCL_VIDEO_MAX_PXCNT)); |
| 1669 | + writel_relaxed(max_lncnt, priv->io_base + _REG(ENCL_VIDEO_MAX_LNCNT)); |
| 1670 | + writel_relaxed(havon_begin, priv->io_base + _REG(ENCL_VIDEO_HAVON_BEGIN)); |
| 1671 | + writel_relaxed(havon_end, priv->io_base + _REG(ENCL_VIDEO_HAVON_END)); |
| 1672 | + writel_relaxed(vavon_bline, priv->io_base + _REG(ENCL_VIDEO_VAVON_BLINE)); |
| 1673 | + writel_relaxed(vavon_eline, priv->io_base + _REG(ENCL_VIDEO_VAVON_ELINE)); |
| 1674 | + |
| 1675 | + writel_relaxed(hso_begin, priv->io_base + _REG(ENCL_VIDEO_HSO_BEGIN)); |
| 1676 | + writel_relaxed(hso_end, priv->io_base + _REG(ENCL_VIDEO_HSO_END)); |
| 1677 | + writel_relaxed(vso_begin, priv->io_base + _REG(ENCL_VIDEO_VSO_BEGIN)); |
| 1678 | + writel_relaxed(vso_end, priv->io_base + _REG(ENCL_VIDEO_VSO_END)); |
| 1679 | + writel_relaxed(vso_bline, priv->io_base + _REG(ENCL_VIDEO_VSO_BLINE)); |
| 1680 | + writel_relaxed(vso_eline, priv->io_base + _REG(ENCL_VIDEO_VSO_ELINE)); |
| 1681 | + writel_relaxed(ENCL_VIDEO_RGBIN_RGB | ENCL_VIDEO_RGBIN_ZBLK, |
| 1682 | + priv->io_base + _REG(ENCL_VIDEO_RGBIN_CTRL)); |
| 1683 | + |
| 1684 | + /* default black pattern */ |
| 1685 | + writel_relaxed(0, priv->io_base + _REG(ENCL_TST_MDSEL)); |
| 1686 | + writel_relaxed(0, priv->io_base + _REG(ENCL_TST_Y)); |
| 1687 | + writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CB)); |
| 1688 | + writel_relaxed(0, priv->io_base + _REG(ENCL_TST_CR)); |
| 1689 | + writel_relaxed(1, priv->io_base + _REG(ENCL_TST_EN)); |
| 1690 | + writel_bits_relaxed(ENCL_VIDEO_MODE_ADV_VFIFO_EN, 0, |
| 1691 | + priv->io_base + _REG(ENCL_VIDEO_MODE_ADV)); |
| 1692 | + |
| 1693 | + writel_relaxed(1, priv->io_base + _REG(ENCL_VIDEO_EN)); |
| 1694 | + |
| 1695 | + writel_relaxed(0, priv->io_base + _REG(L_RGB_BASE_ADDR)); |
| 1696 | + writel_relaxed(0x400, priv->io_base + _REG(L_RGB_COEFF_ADDR)); /* Magic value */ |
| 1697 | + |
| 1698 | + writel_relaxed(L_DITH_CNTL_DITH10_EN, priv->io_base + _REG(L_DITH_CNTL_ADDR)); |
| 1699 | + |
| 1700 | + /* DE signal for TTL */ |
| 1701 | + writel_relaxed(havon_begin, priv->io_base + _REG(L_OEH_HS_ADDR)); |
| 1702 | + writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEH_HE_ADDR)); |
| 1703 | + writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEH_VS_ADDR)); |
| 1704 | + writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEH_VE_ADDR)); |
| 1705 | + |
| 1706 | + /* DE signal for TTL */ |
| 1707 | + writel_relaxed(havon_begin, priv->io_base + _REG(L_OEV1_HS_ADDR)); |
| 1708 | + writel_relaxed(havon_end + 1, priv->io_base + _REG(L_OEV1_HE_ADDR)); |
| 1709 | + writel_relaxed(vavon_bline, priv->io_base + _REG(L_OEV1_VS_ADDR)); |
| 1710 | + writel_relaxed(vavon_eline, priv->io_base + _REG(L_OEV1_VE_ADDR)); |
| 1711 | + |
| 1712 | + /* Hsync signal for TTL */ |
| 1713 | + if (mode->flags & DRM_MODE_FLAG_PHSYNC) { |
| 1714 | + writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HS_ADDR)); |
| 1715 | + writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HE_ADDR)); |
| 1716 | + } else { |
| 1717 | + writel_relaxed(hso_end, priv->io_base + _REG(L_STH1_HS_ADDR)); |
| 1718 | + writel_relaxed(hso_begin, priv->io_base + _REG(L_STH1_HE_ADDR)); |
| 1719 | + } |
| 1720 | + writel_relaxed(0, priv->io_base + _REG(L_STH1_VS_ADDR)); |
| 1721 | + writel_relaxed(max_lncnt, priv->io_base + _REG(L_STH1_VE_ADDR)); |
| 1722 | + |
| 1723 | + /* Vsync signal for TTL */ |
| 1724 | + writel_relaxed(vso_begin, priv->io_base + _REG(L_STV1_HS_ADDR)); |
| 1725 | + writel_relaxed(vso_end, priv->io_base + _REG(L_STV1_HE_ADDR)); |
| 1726 | + if (mode->flags & DRM_MODE_FLAG_PVSYNC) { |
| 1727 | + writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VS_ADDR)); |
| 1728 | + writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VE_ADDR)); |
| 1729 | + } else { |
| 1730 | + writel_relaxed(vso_eline, priv->io_base + _REG(L_STV1_VS_ADDR)); |
| 1731 | + writel_relaxed(vso_bline, priv->io_base + _REG(L_STV1_VE_ADDR)); |
| 1732 | + } |
| 1733 | + |
| 1734 | + /* DE signal */ |
| 1735 | + writel_relaxed(havon_begin, priv->io_base + _REG(L_DE_HS_ADDR)); |
| 1736 | + writel_relaxed(havon_end + 1, priv->io_base + _REG(L_DE_HE_ADDR)); |
| 1737 | + writel_relaxed(vavon_bline, priv->io_base + _REG(L_DE_VS_ADDR)); |
| 1738 | + writel_relaxed(vavon_eline, priv->io_base + _REG(L_DE_VE_ADDR)); |
| 1739 | + |
| 1740 | + /* Hsync signal */ |
| 1741 | + writel_relaxed(hso_begin, priv->io_base + _REG(L_HSYNC_HS_ADDR)); |
| 1742 | + writel_relaxed(hso_end, priv->io_base + _REG(L_HSYNC_HE_ADDR)); |
| 1743 | + writel_relaxed(0, priv->io_base + _REG(L_HSYNC_VS_ADDR)); |
| 1744 | + writel_relaxed(max_lncnt, priv->io_base + _REG(L_HSYNC_VE_ADDR)); |
| 1745 | + |
| 1746 | + /* Vsync signal */ |
| 1747 | + writel_relaxed(vso_begin, priv->io_base + _REG(L_VSYNC_HS_ADDR)); |
| 1748 | + writel_relaxed(vso_end, priv->io_base + _REG(L_VSYNC_HE_ADDR)); |
| 1749 | + writel_relaxed(vso_bline, priv->io_base + _REG(L_VSYNC_VS_ADDR)); |
| 1750 | + writel_relaxed(vso_eline, priv->io_base + _REG(L_VSYNC_VE_ADDR)); |
| 1751 | + |
| 1752 | + writel_relaxed(0, priv->io_base + _REG(L_INV_CNT_ADDR)); |
| 1753 | + writel_relaxed(L_TCON_MISC_SEL_STV1 | L_TCON_MISC_SEL_STV2, |
| 1754 | + priv->io_base + _REG(L_TCON_MISC_SEL_ADDR)); |
| 1755 | + |
| 1756 | + priv->venc.current_mode = MESON_VENC_MODE_MIPI_DSI; |
| 1757 | +} |
| 1758 | +EXPORT_SYMBOL_GPL(meson_venc_mipi_dsi_mode_set); |
| 1759 | + |
1560 | 1760 | void meson_venci_cvbs_mode_set(struct meson_drm *priv, |
1561 | 1761 | struct meson_cvbs_enci_mode *mode) |
1562 | 1762 | { |
@@ -1747,8 +1947,15 @@ unsigned int meson_venci_get_field(struct meson_drm *priv) |
1747 | 1947 |
|
1748 | 1948 | void meson_venc_enable_vsync(struct meson_drm *priv) |
1749 | 1949 | { |
1750 | | - writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN, |
1751 | | - priv->io_base + _REG(VENC_INTCTRL)); |
| 1950 | + switch (priv->venc.current_mode) { |
| 1951 | + case MESON_VENC_MODE_MIPI_DSI: |
| 1952 | + writel_relaxed(VENC_INTCTRL_ENCP_LNRST_INT_EN, |
| 1953 | + priv->io_base + _REG(VENC_INTCTRL)); |
| 1954 | + break; |
| 1955 | + default: |
| 1956 | + writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN, |
| 1957 | + priv->io_base + _REG(VENC_INTCTRL)); |
| 1958 | + } |
1752 | 1959 | regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25)); |
1753 | 1960 | } |
1754 | 1961 |
|
|
0 commit comments