diff options
author | Neil Armstrong <narmstrong@baylibre.com> | 2019-08-30 14:09:24 +0200 |
---|---|---|
committer | Neil Armstrong <narmstrong@baylibre.com> | 2019-10-18 11:42:55 +0200 |
commit | 573687c3be80be60f678597757814f9644c99ae6 (patch) | |
tree | 8c86df9a231ac09e2cb924048a1b71a9f050d660 /drivers/video/meson/meson_dw_hdmi.c | |
parent | 0a3561119faac22be5befdbe3fe261c0dfbe8011 (diff) |
video: meson: sync with linux drm-misc tree
Synchronize the Amlogic Meson Video driver back with the latest
DRM misc tree, adding G12A platform support, from the latest commit:
528a25d040bc ("drm: meson: use match data to detect vpu compatibility")
The sync includes the following changes from Linux adapted to U-Boot:
- Add support for VIC alternate timings
- Switch PLL to 5.94GHz base for 297Mhz pixel clock
- Add registers for G12A SoC
- Add G12A Support for VPP setup
- Add G12A Support for VIU setup
- Add G12A support for OSD1 Plane
- Add G12A support for plane handling in CRTC driver
- Add G12A support for CVBS Encoder
- Add G12A Video Clock setup
- Add G12A support for the DW-HDMI Glue
- fix G12A HDMI PLL settings for 4K60 1000/1001 variations
- fix primary plane disabling
- fix G12A primary plane disabling
- mask value when writing bits relaxed
- crtc: drv: vpp: viu: venc: use proper macros instead of magic constants
- global clean-up
- add macro used to enable HDMI PLL
- venc: set the correct macrovision max amplitude value
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Anatolij Gustschin <agust@denx.de>
Diffstat (limited to 'drivers/video/meson/meson_dw_hdmi.c')
-rw-r--r-- | drivers/video/meson/meson_dw_hdmi.c | 61 |
1 files changed, 54 insertions, 7 deletions
diff --git a/drivers/video/meson/meson_dw_hdmi.c b/drivers/video/meson/meson_dw_hdmi.c index 9831d978fc..ae2e6288f3 100644 --- a/drivers/video/meson/meson_dw_hdmi.c +++ b/drivers/video/meson/meson_dw_hdmi.c @@ -24,6 +24,7 @@ #define HDMITX_TOP_ADDR_REG 0x0 #define HDMITX_TOP_DATA_REG 0x4 #define HDMITX_TOP_CTRL_REG 0x8 +#define HDMITX_TOP_G12A_OFFSET 0x8000 /* Controller Communication Channel */ #define HDMITX_DWC_ADDR_REG 0x10 @@ -37,6 +38,8 @@ #define HHI_HDMI_PHY_CNTL1 0x3a4 /* 0xe9 */ #define HHI_HDMI_PHY_CNTL2 0x3a8 /* 0xea */ #define HHI_HDMI_PHY_CNTL3 0x3ac /* 0xeb */ +#define HHI_HDMI_PHY_CNTL4 0x3b0 /* 0xec */ +#define HHI_HDMI_PHY_CNTL5 0x3b4 /* 0xed */ struct meson_dw_hdmi { struct udevice *dev; @@ -48,6 +51,7 @@ enum hdmi_compatible { HDMI_COMPATIBLE_GXBB = 0, HDMI_COMPATIBLE_GXL = 1, HDMI_COMPATIBLE_GXM = 2, + HDMI_COMPATIBLE_G12A = 3, }; static inline bool meson_hdmi_is_compatible(struct meson_dw_hdmi *priv, @@ -60,8 +64,14 @@ static inline bool meson_hdmi_is_compatible(struct meson_dw_hdmi *priv, static unsigned int dw_hdmi_top_read(struct dw_hdmi *hdmi, unsigned int addr) { + struct meson_dw_hdmi *priv = container_of(hdmi, struct meson_dw_hdmi, + hdmi); unsigned int data; + if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) + return readl(hdmi->ioaddr + + HDMITX_TOP_G12A_OFFSET + (addr << 2)); + /* ADDR must be written twice */ writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG); writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG); @@ -76,6 +86,15 @@ static unsigned int dw_hdmi_top_read(struct dw_hdmi *hdmi, unsigned int addr) static inline void dw_hdmi_top_write(struct dw_hdmi *hdmi, unsigned int addr, unsigned int data) { + struct meson_dw_hdmi *priv = container_of(hdmi, struct meson_dw_hdmi, + hdmi); + + if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) { + writel(data, hdmi->ioaddr + + HDMITX_TOP_G12A_OFFSET + (addr << 2)); + return; + } + /* ADDR must be written twice */ writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG); writel(addr & 0xffff, hdmi->ioaddr + HDMITX_TOP_ADDR_REG); @@ -237,7 +256,7 @@ static void meson_dw_hdmi_phy_setup_mode(struct meson_dw_hdmi *priv, hhi_write(HHI_HDMI_PHY_CNTL0, 0x33604142); hhi_write(HHI_HDMI_PHY_CNTL3, 0x0016315b); } - } else { + } else if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXBB)) { if (pixel_clock >= 371250) { /* 5.94Gbps, 3.7125Gbps */ hhi_write(HHI_HDMI_PHY_CNTL0, 0x33353245); @@ -251,6 +270,23 @@ static void meson_dw_hdmi_phy_setup_mode(struct meson_dw_hdmi *priv, hhi_write(HHI_HDMI_PHY_CNTL0, 0x33632122); hhi_write(HHI_HDMI_PHY_CNTL3, 0x2000115b); } + } else if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) { + if (pixel_clock >= 371250) { + /* 5.94Gbps, 3.7125Gbps */ + hhi_write(HHI_HDMI_PHY_CNTL0, 0x37eb65c4); + hhi_write(HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); + hhi_write(HHI_HDMI_PHY_CNTL5, 0x0000080b); + } else if (pixel_clock >= 297000) { + /* 2.97Gbps */ + hhi_write(HHI_HDMI_PHY_CNTL0, 0x33eb6262); + hhi_write(HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); + hhi_write(HHI_HDMI_PHY_CNTL5, 0x00000003); + } else { + /* 1.485Gbps, and below */ + hhi_write(HHI_HDMI_PHY_CNTL0, 0x33eb4242); + hhi_write(HHI_HDMI_PHY_CNTL3, 0x2ab0ff3b); + hhi_write(HHI_HDMI_PHY_CNTL5, 0x00000003); + } } } @@ -292,7 +328,8 @@ static int meson_dw_hdmi_phy_init(struct dw_hdmi *hdmi, uint pixel_clock) /* BIT_INVERT */ if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXL) || - meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXM)) + meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_GXM) || + meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) dw_hdmi_hhi_update_bits(priv, HHI_HDMI_PHY_CNTL1, BIT(17), 0); else dw_hdmi_hhi_update_bits(priv, HHI_HDMI_PHY_CNTL1, @@ -356,8 +393,12 @@ static int meson_dw_hdmi_probe(struct udevice *dev) priv->hdmi.hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; priv->hdmi.hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_YUV8_1X24; priv->hdmi.phy_set = meson_dw_hdmi_phy_init; - priv->hdmi.write_reg = dw_hdmi_dwc_write; - priv->hdmi.read_reg = dw_hdmi_dwc_read; + if (meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) + priv->hdmi.reg_io_width = 1; + else { + priv->hdmi.write_reg = dw_hdmi_dwc_write; + priv->hdmi.read_reg = dw_hdmi_dwc_read; + } priv->hdmi.i2c_clk_high = 0x67; priv->hdmi.i2c_clk_low = 0x78; @@ -409,9 +450,13 @@ static int meson_dw_hdmi_probe(struct udevice *dev) if (ret) return ret; - /* Enable APB3 fail on error */ - writel_bits(BIT(15), BIT(15), priv->hdmi.ioaddr + HDMITX_TOP_CTRL_REG); - writel_bits(BIT(15), BIT(15), priv->hdmi.ioaddr + HDMITX_DWC_CTRL_REG); + if (!meson_hdmi_is_compatible(priv, HDMI_COMPATIBLE_G12A)) { + /* Enable APB3 fail on error */ + writel_bits(BIT(15), BIT(15), + priv->hdmi.ioaddr + HDMITX_TOP_CTRL_REG); + writel_bits(BIT(15), BIT(15), + priv->hdmi.ioaddr + HDMITX_DWC_CTRL_REG); + } /* Bring out of reset */ dw_hdmi_top_write(&priv->hdmi, HDMITX_TOP_SW_RESET, 0); @@ -448,6 +493,8 @@ static const struct udevice_id meson_dw_hdmi_ids[] = { .data = HDMI_COMPATIBLE_GXL }, { .compatible = "amlogic,meson-gxm-dw-hdmi", .data = HDMI_COMPATIBLE_GXM }, + { .compatible = "amlogic,meson-g12a-dw-hdmi", + .data = HDMI_COMPATIBLE_G12A }, { } }; |