Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2013 Red Hat
0004  * Author: Rob Clark <robdclark@gmail.com>
0005  */
0006 
0007 #ifndef __HDMI_CONNECTOR_H__
0008 #define __HDMI_CONNECTOR_H__
0009 
0010 #include <linux/i2c.h>
0011 #include <linux/clk.h>
0012 #include <linux/platform_device.h>
0013 #include <linux/regulator/consumer.h>
0014 #include <linux/gpio/consumer.h>
0015 #include <linux/hdmi.h>
0016 
0017 #include <drm/drm_bridge.h>
0018 
0019 #include "msm_drv.h"
0020 #include "hdmi.xml.h"
0021 
0022 struct hdmi_phy;
0023 struct hdmi_platform_config;
0024 
0025 struct hdmi_audio {
0026     bool enabled;
0027     struct hdmi_audio_infoframe infoframe;
0028     int rate;
0029 };
0030 
0031 struct hdmi_hdcp_ctrl;
0032 
0033 struct hdmi {
0034     struct drm_device *dev;
0035     struct platform_device *pdev;
0036     struct platform_device *audio_pdev;
0037 
0038     const struct hdmi_platform_config *config;
0039 
0040     /* audio state: */
0041     struct hdmi_audio audio;
0042 
0043     /* video state: */
0044     bool power_on;
0045     unsigned long int pixclock;
0046 
0047     void __iomem *mmio;
0048     void __iomem *qfprom_mmio;
0049     phys_addr_t mmio_phy_addr;
0050 
0051     struct regulator_bulk_data *hpd_regs;
0052     struct regulator_bulk_data *pwr_regs;
0053     struct clk **hpd_clks;
0054     struct clk **pwr_clks;
0055 
0056     struct gpio_desc *hpd_gpiod;
0057 
0058     struct hdmi_phy *phy;
0059     struct device *phy_dev;
0060 
0061     struct i2c_adapter *i2c;
0062     struct drm_connector *connector;
0063     struct drm_bridge *bridge;
0064 
0065     struct drm_bridge *next_bridge;
0066 
0067     /* the encoder we are hooked to (outside of hdmi block) */
0068     struct drm_encoder *encoder;
0069 
0070     bool hdmi_mode;               /* are we in hdmi mode? */
0071 
0072     int irq;
0073     struct workqueue_struct *workq;
0074 
0075     struct hdmi_hdcp_ctrl *hdcp_ctrl;
0076 
0077     /*
0078     * spinlock to protect registers shared by different execution
0079     * REG_HDMI_CTRL
0080     * REG_HDMI_DDC_ARBITRATION
0081     * REG_HDMI_HDCP_INT_CTRL
0082     * REG_HDMI_HPD_CTRL
0083     */
0084     spinlock_t reg_lock;
0085 };
0086 
0087 /* platform config data (ie. from DT, or pdata) */
0088 struct hdmi_platform_config {
0089     const char *mmio_name;
0090     const char *qfprom_mmio_name;
0091 
0092     /* regulators that need to be on for hpd: */
0093     const char **hpd_reg_names;
0094     int hpd_reg_cnt;
0095 
0096     /* regulators that need to be on for screen pwr: */
0097     const char **pwr_reg_names;
0098     int pwr_reg_cnt;
0099 
0100     /* clks that need to be on for hpd: */
0101     const char **hpd_clk_names;
0102     const long unsigned *hpd_freq;
0103     int hpd_clk_cnt;
0104 
0105     /* clks that need to be on for screen pwr (ie pixel clk): */
0106     const char **pwr_clk_names;
0107     int pwr_clk_cnt;
0108 };
0109 
0110 struct hdmi_bridge {
0111     struct drm_bridge base;
0112     struct hdmi *hdmi;
0113     struct work_struct hpd_work;
0114 };
0115 #define to_hdmi_bridge(x) container_of(x, struct hdmi_bridge, base)
0116 
0117 void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on);
0118 
0119 static inline void hdmi_write(struct hdmi *hdmi, u32 reg, u32 data)
0120 {
0121     msm_writel(data, hdmi->mmio + reg);
0122 }
0123 
0124 static inline u32 hdmi_read(struct hdmi *hdmi, u32 reg)
0125 {
0126     return msm_readl(hdmi->mmio + reg);
0127 }
0128 
0129 static inline u32 hdmi_qfprom_read(struct hdmi *hdmi, u32 reg)
0130 {
0131     return msm_readl(hdmi->qfprom_mmio + reg);
0132 }
0133 
0134 /*
0135  * hdmi phy:
0136  */
0137 
0138 enum hdmi_phy_type {
0139     MSM_HDMI_PHY_8x60,
0140     MSM_HDMI_PHY_8960,
0141     MSM_HDMI_PHY_8x74,
0142     MSM_HDMI_PHY_8996,
0143     MSM_HDMI_PHY_MAX,
0144 };
0145 
0146 struct hdmi_phy_cfg {
0147     enum hdmi_phy_type type;
0148     void (*powerup)(struct hdmi_phy *phy, unsigned long int pixclock);
0149     void (*powerdown)(struct hdmi_phy *phy);
0150     const char * const *reg_names;
0151     int num_regs;
0152     const char * const *clk_names;
0153     int num_clks;
0154 };
0155 
0156 extern const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg;
0157 extern const struct hdmi_phy_cfg msm_hdmi_phy_8960_cfg;
0158 extern const struct hdmi_phy_cfg msm_hdmi_phy_8x74_cfg;
0159 extern const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg;
0160 
0161 struct hdmi_phy {
0162     struct platform_device *pdev;
0163     void __iomem *mmio;
0164     struct hdmi_phy_cfg *cfg;
0165     const struct hdmi_phy_funcs *funcs;
0166     struct regulator_bulk_data *regs;
0167     struct clk **clks;
0168 };
0169 
0170 static inline void hdmi_phy_write(struct hdmi_phy *phy, u32 reg, u32 data)
0171 {
0172     msm_writel(data, phy->mmio + reg);
0173 }
0174 
0175 static inline u32 hdmi_phy_read(struct hdmi_phy *phy, u32 reg)
0176 {
0177     return msm_readl(phy->mmio + reg);
0178 }
0179 
0180 int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy);
0181 void msm_hdmi_phy_resource_disable(struct hdmi_phy *phy);
0182 void msm_hdmi_phy_powerup(struct hdmi_phy *phy, unsigned long int pixclock);
0183 void msm_hdmi_phy_powerdown(struct hdmi_phy *phy);
0184 void __init msm_hdmi_phy_driver_register(void);
0185 void __exit msm_hdmi_phy_driver_unregister(void);
0186 
0187 #ifdef CONFIG_COMMON_CLK
0188 int msm_hdmi_pll_8960_init(struct platform_device *pdev);
0189 int msm_hdmi_pll_8996_init(struct platform_device *pdev);
0190 #else
0191 static inline int msm_hdmi_pll_8960_init(struct platform_device *pdev)
0192 {
0193     return -ENODEV;
0194 }
0195 
0196 static inline int msm_hdmi_pll_8996_init(struct platform_device *pdev)
0197 {
0198     return -ENODEV;
0199 }
0200 #endif
0201 
0202 /*
0203  * audio:
0204  */
0205 /* Supported HDMI Audio channels and rates */
0206 #define MSM_HDMI_AUDIO_CHANNEL_2    0
0207 #define MSM_HDMI_AUDIO_CHANNEL_4    1
0208 #define MSM_HDMI_AUDIO_CHANNEL_6    2
0209 #define MSM_HDMI_AUDIO_CHANNEL_8    3
0210 
0211 #define HDMI_SAMPLE_RATE_32KHZ      0
0212 #define HDMI_SAMPLE_RATE_44_1KHZ    1
0213 #define HDMI_SAMPLE_RATE_48KHZ      2
0214 #define HDMI_SAMPLE_RATE_88_2KHZ    3
0215 #define HDMI_SAMPLE_RATE_96KHZ      4
0216 #define HDMI_SAMPLE_RATE_176_4KHZ   5
0217 #define HDMI_SAMPLE_RATE_192KHZ     6
0218 
0219 int msm_hdmi_audio_update(struct hdmi *hdmi);
0220 int msm_hdmi_audio_info_setup(struct hdmi *hdmi, bool enabled,
0221     uint32_t num_of_channels, uint32_t channel_allocation,
0222     uint32_t level_shift, bool down_mix);
0223 void msm_hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate);
0224 
0225 
0226 /*
0227  * hdmi bridge:
0228  */
0229 
0230 struct drm_bridge *msm_hdmi_bridge_init(struct hdmi *hdmi);
0231 void msm_hdmi_bridge_destroy(struct drm_bridge *bridge);
0232 
0233 void msm_hdmi_hpd_irq(struct drm_bridge *bridge);
0234 enum drm_connector_status msm_hdmi_bridge_detect(
0235         struct drm_bridge *bridge);
0236 int msm_hdmi_hpd_enable(struct drm_bridge *bridge);
0237 void msm_hdmi_hpd_disable(struct hdmi_bridge *hdmi_bridge);
0238 
0239 /*
0240  * i2c adapter for ddc:
0241  */
0242 
0243 void msm_hdmi_i2c_irq(struct i2c_adapter *i2c);
0244 void msm_hdmi_i2c_destroy(struct i2c_adapter *i2c);
0245 struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi);
0246 
0247 /*
0248  * hdcp
0249  */
0250 #ifdef CONFIG_DRM_MSM_HDMI_HDCP
0251 struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi);
0252 void msm_hdmi_hdcp_destroy(struct hdmi *hdmi);
0253 void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl);
0254 void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl);
0255 void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl);
0256 #else
0257 static inline struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi)
0258 {
0259     return ERR_PTR(-ENXIO);
0260 }
0261 static inline void msm_hdmi_hdcp_destroy(struct hdmi *hdmi) {}
0262 static inline void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
0263 static inline void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
0264 static inline void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) {}
0265 #endif
0266 
0267 #endif /* __HDMI_CONNECTOR_H__ */