Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * HDMI driver definition for TI OMAP4 Processor.
0004  *
0005  * Copyright (C) 2010-2011 Texas Instruments Incorporated - https://www.ti.com/
0006  */
0007 
0008 #ifndef _HDMI_H
0009 #define _HDMI_H
0010 
0011 #include <linux/delay.h>
0012 #include <linux/io.h>
0013 #include <linux/platform_device.h>
0014 #include <linux/hdmi.h>
0015 #include <sound/omap-hdmi-audio.h>
0016 #include <media/cec.h>
0017 #include <drm/drm_bridge.h>
0018 
0019 #include "omapdss.h"
0020 #include "dss.h"
0021 
0022 struct dss_device;
0023 
0024 /* HDMI Wrapper */
0025 
0026 #define HDMI_WP_REVISION            0x0
0027 #define HDMI_WP_SYSCONFIG           0x10
0028 #define HDMI_WP_IRQSTATUS_RAW           0x24
0029 #define HDMI_WP_IRQSTATUS           0x28
0030 #define HDMI_WP_IRQENABLE_SET           0x2C
0031 #define HDMI_WP_IRQENABLE_CLR           0x30
0032 #define HDMI_WP_IRQWAKEEN           0x34
0033 #define HDMI_WP_PWR_CTRL            0x40
0034 #define HDMI_WP_DEBOUNCE            0x44
0035 #define HDMI_WP_VIDEO_CFG           0x50
0036 #define HDMI_WP_VIDEO_SIZE          0x60
0037 #define HDMI_WP_VIDEO_TIMING_H          0x68
0038 #define HDMI_WP_VIDEO_TIMING_V          0x6C
0039 #define HDMI_WP_CLK             0x70
0040 #define HDMI_WP_AUDIO_CFG           0x80
0041 #define HDMI_WP_AUDIO_CFG2          0x84
0042 #define HDMI_WP_AUDIO_CTRL          0x88
0043 #define HDMI_WP_AUDIO_DATA          0x8C
0044 
0045 /* HDMI WP IRQ flags */
0046 #define HDMI_IRQ_CORE               (1 << 0)
0047 #define HDMI_IRQ_OCP_TIMEOUT            (1 << 4)
0048 #define HDMI_IRQ_AUDIO_FIFO_UNDERFLOW       (1 << 8)
0049 #define HDMI_IRQ_AUDIO_FIFO_OVERFLOW        (1 << 9)
0050 #define HDMI_IRQ_AUDIO_FIFO_SAMPLE_REQ      (1 << 10)
0051 #define HDMI_IRQ_VIDEO_VSYNC            (1 << 16)
0052 #define HDMI_IRQ_VIDEO_FRAME_DONE       (1 << 17)
0053 #define HDMI_IRQ_PHY_LINE5V_ASSERT      (1 << 24)
0054 #define HDMI_IRQ_LINK_CONNECT           (1 << 25)
0055 #define HDMI_IRQ_LINK_DISCONNECT        (1 << 26)
0056 #define HDMI_IRQ_PLL_LOCK           (1 << 29)
0057 #define HDMI_IRQ_PLL_UNLOCK         (1 << 30)
0058 #define HDMI_IRQ_PLL_RECAL          (1 << 31)
0059 
0060 /* HDMI PLL */
0061 
0062 #define PLLCTRL_PLL_CONTROL         0x0
0063 #define PLLCTRL_PLL_STATUS          0x4
0064 #define PLLCTRL_PLL_GO              0x8
0065 #define PLLCTRL_CFG1                0xC
0066 #define PLLCTRL_CFG2                0x10
0067 #define PLLCTRL_CFG3                0x14
0068 #define PLLCTRL_SSC_CFG1            0x18
0069 #define PLLCTRL_SSC_CFG2            0x1C
0070 #define PLLCTRL_CFG4                0x20
0071 
0072 /* HDMI PHY */
0073 
0074 #define HDMI_TXPHY_TX_CTRL          0x0
0075 #define HDMI_TXPHY_DIGITAL_CTRL         0x4
0076 #define HDMI_TXPHY_POWER_CTRL           0x8
0077 #define HDMI_TXPHY_PAD_CFG_CTRL         0xC
0078 #define HDMI_TXPHY_BIST_CONTROL         0x1C
0079 
0080 enum hdmi_pll_pwr {
0081     HDMI_PLLPWRCMD_ALLOFF = 0,
0082     HDMI_PLLPWRCMD_PLLONLY = 1,
0083     HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2,
0084     HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3
0085 };
0086 
0087 enum hdmi_phy_pwr {
0088     HDMI_PHYPWRCMD_OFF = 0,
0089     HDMI_PHYPWRCMD_LDOON = 1,
0090     HDMI_PHYPWRCMD_TXON = 2
0091 };
0092 
0093 enum hdmi_core_hdmi_dvi {
0094     HDMI_DVI = 0,
0095     HDMI_HDMI = 1
0096 };
0097 
0098 enum hdmi_packing_mode {
0099     HDMI_PACK_10b_RGB_YUV444 = 0,
0100     HDMI_PACK_24b_RGB_YUV444_YUV422 = 1,
0101     HDMI_PACK_20b_YUV422 = 2,
0102     HDMI_PACK_ALREADYPACKED = 7
0103 };
0104 
0105 enum hdmi_stereo_channels {
0106     HDMI_AUDIO_STEREO_NOCHANNELS = 0,
0107     HDMI_AUDIO_STEREO_ONECHANNEL = 1,
0108     HDMI_AUDIO_STEREO_TWOCHANNELS = 2,
0109     HDMI_AUDIO_STEREO_THREECHANNELS = 3,
0110     HDMI_AUDIO_STEREO_FOURCHANNELS = 4
0111 };
0112 
0113 enum hdmi_audio_type {
0114     HDMI_AUDIO_TYPE_LPCM = 0,
0115     HDMI_AUDIO_TYPE_IEC = 1
0116 };
0117 
0118 enum hdmi_audio_justify {
0119     HDMI_AUDIO_JUSTIFY_LEFT = 0,
0120     HDMI_AUDIO_JUSTIFY_RIGHT = 1
0121 };
0122 
0123 enum hdmi_audio_sample_order {
0124     HDMI_AUDIO_SAMPLE_RIGHT_FIRST = 0,
0125     HDMI_AUDIO_SAMPLE_LEFT_FIRST = 1
0126 };
0127 
0128 enum hdmi_audio_samples_perword {
0129     HDMI_AUDIO_ONEWORD_ONESAMPLE = 0,
0130     HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1
0131 };
0132 
0133 enum hdmi_audio_sample_size_omap {
0134     HDMI_AUDIO_SAMPLE_16BITS = 0,
0135     HDMI_AUDIO_SAMPLE_24BITS = 1
0136 };
0137 
0138 enum hdmi_audio_transf_mode {
0139     HDMI_AUDIO_TRANSF_DMA = 0,
0140     HDMI_AUDIO_TRANSF_IRQ = 1
0141 };
0142 
0143 enum hdmi_audio_blk_strt_end_sig {
0144     HDMI_AUDIO_BLOCK_SIG_STARTEND_ON = 0,
0145     HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF = 1
0146 };
0147 
0148 enum hdmi_core_audio_layout {
0149     HDMI_AUDIO_LAYOUT_2CH = 0,
0150     HDMI_AUDIO_LAYOUT_8CH = 1,
0151     HDMI_AUDIO_LAYOUT_6CH = 2
0152 };
0153 
0154 enum hdmi_core_cts_mode {
0155     HDMI_AUDIO_CTS_MODE_HW = 0,
0156     HDMI_AUDIO_CTS_MODE_SW = 1
0157 };
0158 
0159 enum hdmi_audio_mclk_mode {
0160     HDMI_AUDIO_MCLK_128FS = 0,
0161     HDMI_AUDIO_MCLK_256FS = 1,
0162     HDMI_AUDIO_MCLK_384FS = 2,
0163     HDMI_AUDIO_MCLK_512FS = 3,
0164     HDMI_AUDIO_MCLK_768FS = 4,
0165     HDMI_AUDIO_MCLK_1024FS = 5,
0166     HDMI_AUDIO_MCLK_1152FS = 6,
0167     HDMI_AUDIO_MCLK_192FS = 7
0168 };
0169 
0170 struct hdmi_video_format {
0171     enum hdmi_packing_mode  packing_mode;
0172     u32         y_res;  /* Line per panel */
0173     u32         x_res;  /* pixel per line */
0174 };
0175 
0176 struct hdmi_config {
0177     struct videomode vm;
0178     struct hdmi_avi_infoframe infoframe;
0179     enum hdmi_core_hdmi_dvi hdmi_dvi_mode;
0180 };
0181 
0182 struct hdmi_audio_format {
0183     enum hdmi_stereo_channels       stereo_channels;
0184     u8                  active_chnnls_msk;
0185     enum hdmi_audio_type            type;
0186     enum hdmi_audio_justify         justification;
0187     enum hdmi_audio_sample_order        sample_order;
0188     enum hdmi_audio_samples_perword     samples_per_word;
0189     enum hdmi_audio_sample_size_omap    sample_size;
0190     enum hdmi_audio_blk_strt_end_sig    en_sig_blk_strt_end;
0191 };
0192 
0193 struct hdmi_audio_dma {
0194     u8              transfer_size;
0195     u8              block_size;
0196     enum hdmi_audio_transf_mode mode;
0197     u16             fifo_threshold;
0198 };
0199 
0200 struct hdmi_core_audio_i2s_config {
0201     u8 in_length_bits;
0202     u8 justification;
0203     u8 sck_edge_mode;
0204     u8 vbit;
0205     u8 direction;
0206     u8 shift;
0207     u8 active_sds;
0208 };
0209 
0210 struct hdmi_core_audio_config {
0211     struct hdmi_core_audio_i2s_config   i2s_cfg;
0212     struct snd_aes_iec958           *iec60958_cfg;
0213     bool                    fs_override;
0214     u32                 n;
0215     u32                 cts;
0216     u32                 aud_par_busclk;
0217     enum hdmi_core_audio_layout     layout;
0218     enum hdmi_core_cts_mode         cts_mode;
0219     bool                    use_mclk;
0220     enum hdmi_audio_mclk_mode       mclk_mode;
0221     bool                    en_acr_pkt;
0222     bool                    en_dsd_audio;
0223     bool                    en_parallel_aud_input;
0224     bool                    en_spdif;
0225 };
0226 
0227 struct hdmi_wp_data {
0228     void __iomem *base;
0229     phys_addr_t phys_base;
0230     unsigned int version;
0231 };
0232 
0233 struct hdmi_pll_data {
0234     struct dss_pll pll;
0235 
0236     void __iomem *base;
0237 
0238     struct platform_device *pdev;
0239     struct hdmi_wp_data *wp;
0240 };
0241 
0242 struct hdmi_phy_features {
0243     bool bist_ctrl;
0244     bool ldo_voltage;
0245     unsigned long max_phy;
0246 };
0247 
0248 struct hdmi_phy_data {
0249     void __iomem *base;
0250 
0251     const struct hdmi_phy_features *features;
0252     u8 lane_function[4];
0253     u8 lane_polarity[4];
0254 };
0255 
0256 struct hdmi_core_data {
0257     void __iomem *base;
0258     bool cts_swmode;
0259     bool audio_use_mclk;
0260 
0261     struct hdmi_wp_data *wp;
0262     unsigned int core_pwr_cnt;
0263     struct cec_adapter *adap;
0264 };
0265 
0266 static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx,
0267         u32 val)
0268 {
0269     __raw_writel(val, base_addr + idx);
0270 }
0271 
0272 static inline u32 hdmi_read_reg(void __iomem *base_addr, const u32 idx)
0273 {
0274     return __raw_readl(base_addr + idx);
0275 }
0276 
0277 #define REG_FLD_MOD(base, idx, val, start, end) \
0278     hdmi_write_reg(base, idx, FLD_MOD(hdmi_read_reg(base, idx),\
0279                             val, start, end))
0280 #define REG_GET(base, idx, start, end) \
0281     FLD_GET(hdmi_read_reg(base, idx), start, end)
0282 
0283 static inline int hdmi_wait_for_bit_change(void __iomem *base_addr,
0284         const u32 idx, int b2, int b1, u32 val)
0285 {
0286     u32 t = 0, v;
0287     while (val != (v = REG_GET(base_addr, idx, b2, b1))) {
0288         if (t++ > 10000)
0289             return v;
0290         udelay(1);
0291     }
0292     return v;
0293 }
0294 
0295 /* HDMI wrapper funcs */
0296 int hdmi_wp_video_start(struct hdmi_wp_data *wp);
0297 void hdmi_wp_video_stop(struct hdmi_wp_data *wp);
0298 void hdmi_wp_dump(struct hdmi_wp_data *wp, struct seq_file *s);
0299 u32 hdmi_wp_get_irqstatus(struct hdmi_wp_data *wp);
0300 void hdmi_wp_set_irqstatus(struct hdmi_wp_data *wp, u32 irqstatus);
0301 void hdmi_wp_set_irqenable(struct hdmi_wp_data *wp, u32 mask);
0302 void hdmi_wp_clear_irqenable(struct hdmi_wp_data *wp, u32 mask);
0303 int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val);
0304 int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val);
0305 void hdmi_wp_video_config_format(struct hdmi_wp_data *wp,
0306         const struct hdmi_video_format *video_fmt);
0307 void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp,
0308         const struct videomode *vm);
0309 void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
0310         const struct videomode *vm);
0311 void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
0312         struct videomode *vm, const struct hdmi_config *param);
0313 int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp,
0314          unsigned int version);
0315 phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp);
0316 
0317 /* HDMI PLL funcs */
0318 void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s);
0319 int hdmi_pll_init(struct dss_device *dss, struct platform_device *pdev,
0320           struct hdmi_pll_data *pll, struct hdmi_wp_data *wp);
0321 void hdmi_pll_uninit(struct hdmi_pll_data *hpll);
0322 
0323 /* HDMI PHY funcs */
0324 int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
0325     unsigned long lfbitclk);
0326 void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s);
0327 int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy,
0328           unsigned int version);
0329 int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes);
0330 
0331 /* HDMI common funcs */
0332 int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
0333     struct hdmi_phy_data *phy);
0334 
0335 /* Audio funcs */
0336 int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts);
0337 int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable);
0338 int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable);
0339 void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp,
0340         struct hdmi_audio_format *aud_fmt);
0341 void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp,
0342         struct hdmi_audio_dma *aud_dma);
0343 static inline bool hdmi_mode_has_audio(struct hdmi_config *cfg)
0344 {
0345     return cfg->hdmi_dvi_mode == HDMI_HDMI ? true : false;
0346 }
0347 
0348 /* HDMI DRV data */
0349 struct omap_hdmi {
0350     struct mutex lock;
0351     struct platform_device *pdev;
0352     struct dss_device *dss;
0353 
0354     struct dss_debugfs_entry *debugfs;
0355 
0356     struct hdmi_wp_data wp;
0357     struct hdmi_pll_data    pll;
0358     struct hdmi_phy_data    phy;
0359     struct hdmi_core_data   core;
0360 
0361     struct hdmi_config cfg;
0362 
0363     struct regulator *vdda_reg;
0364 
0365     bool core_enabled;
0366 
0367     struct omap_dss_device output;
0368     struct drm_bridge bridge;
0369 
0370     struct platform_device *audio_pdev;
0371     void (*audio_abort_cb)(struct device *dev);
0372     int wp_idlemode;
0373 
0374     bool audio_configured;
0375     struct omap_dss_audio audio_config;
0376 
0377     /* This lock should be taken when booleans below are touched. */
0378     spinlock_t audio_playing_lock;
0379     bool audio_playing;
0380     bool display_enabled;
0381 };
0382 
0383 #define drm_bridge_to_hdmi(b) container_of(b, struct omap_hdmi, bridge)
0384 
0385 #endif