1 /* 2 * Copyright (C) 2013 Red Hat 3 * Author: Rob Clark <robdclark@gmail.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published by 7 * the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 #ifndef __HDMI_CONNECTOR_H__ 19 #define __HDMI_CONNECTOR_H__ 20 21 #include <linux/i2c.h> 22 #include <linux/clk.h> 23 #include <linux/platform_device.h> 24 #include <linux/regulator/consumer.h> 25 #include <linux/hdmi.h> 26 27 #include "msm_drv.h" 28 #include "hdmi.xml.h" 29 30 #define HDMI_MAX_NUM_GPIO 6 31 32 struct hdmi_phy; 33 struct hdmi_platform_config; 34 35 struct hdmi_gpio_data { 36 int num; 37 bool output; 38 int value; 39 const char *label; 40 }; 41 42 struct hdmi_audio { 43 bool enabled; 44 struct hdmi_audio_infoframe infoframe; 45 int rate; 46 }; 47 48 struct hdmi_hdcp_ctrl; 49 50 struct hdmi { 51 struct drm_device *dev; 52 struct platform_device *pdev; 53 54 const struct hdmi_platform_config *config; 55 56 /* audio state: */ 57 struct hdmi_audio audio; 58 59 /* video state: */ 60 bool power_on; 61 unsigned long int pixclock; 62 63 void __iomem *mmio; 64 void __iomem *qfprom_mmio; 65 phys_addr_t mmio_phy_addr; 66 67 struct regulator **hpd_regs; 68 struct regulator **pwr_regs; 69 struct clk **hpd_clks; 70 struct clk **pwr_clks; 71 72 struct hdmi_phy *phy; 73 struct device *phy_dev; 74 75 struct i2c_adapter *i2c; 76 struct drm_connector *connector; 77 struct drm_bridge *bridge; 78 79 /* the encoder we are hooked to (outside of hdmi block) */ 80 struct drm_encoder *encoder; 81 82 bool hdmi_mode; /* are we in hdmi mode? */ 83 84 int irq; 85 struct workqueue_struct *workq; 86 87 struct hdmi_hdcp_ctrl *hdcp_ctrl; 88 89 /* 90 * spinlock to protect registers shared by different execution 91 * REG_HDMI_CTRL 92 * REG_HDMI_DDC_ARBITRATION 93 * REG_HDMI_HDCP_INT_CTRL 94 * REG_HDMI_HPD_CTRL 95 */ 96 spinlock_t reg_lock; 97 }; 98 99 /* platform config data (ie. from DT, or pdata) */ 100 struct hdmi_platform_config { 101 const char *mmio_name; 102 const char *qfprom_mmio_name; 103 104 /* regulators that need to be on for hpd: */ 105 const char **hpd_reg_names; 106 int hpd_reg_cnt; 107 108 /* regulators that need to be on for screen pwr: */ 109 const char **pwr_reg_names; 110 int pwr_reg_cnt; 111 112 /* clks that need to be on for hpd: */ 113 const char **hpd_clk_names; 114 const long unsigned *hpd_freq; 115 int hpd_clk_cnt; 116 117 /* clks that need to be on for screen pwr (ie pixel clk): */ 118 const char **pwr_clk_names; 119 int pwr_clk_cnt; 120 121 /* gpio's: */ 122 struct hdmi_gpio_data gpios[HDMI_MAX_NUM_GPIO]; 123 }; 124 125 void msm_hdmi_set_mode(struct hdmi *hdmi, bool power_on); 126 127 static inline void hdmi_write(struct hdmi *hdmi, u32 reg, u32 data) 128 { 129 msm_writel(data, hdmi->mmio + reg); 130 } 131 132 static inline u32 hdmi_read(struct hdmi *hdmi, u32 reg) 133 { 134 return msm_readl(hdmi->mmio + reg); 135 } 136 137 static inline u32 hdmi_qfprom_read(struct hdmi *hdmi, u32 reg) 138 { 139 return msm_readl(hdmi->qfprom_mmio + reg); 140 } 141 142 /* 143 * hdmi phy: 144 */ 145 146 enum hdmi_phy_type { 147 MSM_HDMI_PHY_8x60, 148 MSM_HDMI_PHY_8960, 149 MSM_HDMI_PHY_8x74, 150 MSM_HDMI_PHY_8996, 151 MSM_HDMI_PHY_MAX, 152 }; 153 154 struct hdmi_phy_cfg { 155 enum hdmi_phy_type type; 156 void (*powerup)(struct hdmi_phy *phy, unsigned long int pixclock); 157 void (*powerdown)(struct hdmi_phy *phy); 158 const char * const *reg_names; 159 int num_regs; 160 const char * const *clk_names; 161 int num_clks; 162 }; 163 164 extern const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg; 165 extern const struct hdmi_phy_cfg msm_hdmi_phy_8960_cfg; 166 extern const struct hdmi_phy_cfg msm_hdmi_phy_8x74_cfg; 167 extern const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg; 168 169 struct hdmi_phy { 170 struct platform_device *pdev; 171 void __iomem *mmio; 172 struct hdmi_phy_cfg *cfg; 173 const struct hdmi_phy_funcs *funcs; 174 struct regulator **regs; 175 struct clk **clks; 176 }; 177 178 static inline void hdmi_phy_write(struct hdmi_phy *phy, u32 reg, u32 data) 179 { 180 msm_writel(data, phy->mmio + reg); 181 } 182 183 static inline u32 hdmi_phy_read(struct hdmi_phy *phy, u32 reg) 184 { 185 return msm_readl(phy->mmio + reg); 186 } 187 188 int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy); 189 void msm_hdmi_phy_resource_disable(struct hdmi_phy *phy); 190 void msm_hdmi_phy_powerup(struct hdmi_phy *phy, unsigned long int pixclock); 191 void msm_hdmi_phy_powerdown(struct hdmi_phy *phy); 192 void __init msm_hdmi_phy_driver_register(void); 193 void __exit msm_hdmi_phy_driver_unregister(void); 194 195 #ifdef CONFIG_COMMON_CLK 196 int msm_hdmi_pll_8960_init(struct platform_device *pdev); 197 int msm_hdmi_pll_8996_init(struct platform_device *pdev); 198 #else 199 static inline int msm_hdmi_pll_8960_init(struct platform_device *pdev) 200 { 201 return -ENODEV; 202 } 203 204 static inline int msm_hdmi_pll_8996_init(struct platform_device *pdev) 205 { 206 return -ENODEV; 207 } 208 #endif 209 210 /* 211 * audio: 212 */ 213 214 int msm_hdmi_audio_update(struct hdmi *hdmi); 215 int msm_hdmi_audio_info_setup(struct hdmi *hdmi, bool enabled, 216 uint32_t num_of_channels, uint32_t channel_allocation, 217 uint32_t level_shift, bool down_mix); 218 void msm_hdmi_audio_set_sample_rate(struct hdmi *hdmi, int rate); 219 220 221 /* 222 * hdmi bridge: 223 */ 224 225 struct drm_bridge *msm_hdmi_bridge_init(struct hdmi *hdmi); 226 void msm_hdmi_bridge_destroy(struct drm_bridge *bridge); 227 228 /* 229 * hdmi connector: 230 */ 231 232 void msm_hdmi_connector_irq(struct drm_connector *connector); 233 struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi); 234 235 /* 236 * i2c adapter for ddc: 237 */ 238 239 void msm_hdmi_i2c_irq(struct i2c_adapter *i2c); 240 void msm_hdmi_i2c_destroy(struct i2c_adapter *i2c); 241 struct i2c_adapter *msm_hdmi_i2c_init(struct hdmi *hdmi); 242 243 /* 244 * hdcp 245 */ 246 #ifdef CONFIG_DRM_MSM_HDMI_HDCP 247 struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi); 248 void msm_hdmi_hdcp_destroy(struct hdmi *hdmi); 249 void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl); 250 void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl); 251 void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl); 252 #else 253 static inline struct hdmi_hdcp_ctrl *msm_hdmi_hdcp_init(struct hdmi *hdmi) 254 { 255 return ERR_PTR(-ENXIO); 256 } 257 static inline void msm_hdmi_hdcp_destroy(struct hdmi *hdmi) {} 258 static inline void msm_hdmi_hdcp_on(struct hdmi_hdcp_ctrl *hdcp_ctrl) {} 259 static inline void msm_hdmi_hdcp_off(struct hdmi_hdcp_ctrl *hdcp_ctrl) {} 260 static inline void msm_hdmi_hdcp_irq(struct hdmi_hdcp_ctrl *hdcp_ctrl) {} 261 #endif 262 263 #endif /* __HDMI_CONNECTOR_H__ */ 264