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 26 #include "msm_drv.h" 27 #include "hdmi.xml.h" 28 29 30 struct hdmi_phy; 31 struct hdmi_platform_config; 32 33 struct hdmi { 34 struct kref refcount; 35 36 struct drm_device *dev; 37 struct platform_device *pdev; 38 39 const struct hdmi_platform_config *config; 40 41 void __iomem *mmio; 42 43 struct regulator *hpd_regs[2]; 44 struct regulator *pwr_regs[2]; 45 struct clk *hpd_clks[3]; 46 struct clk *pwr_clks[2]; 47 48 struct hdmi_phy *phy; 49 struct i2c_adapter *i2c; 50 struct drm_connector *connector; 51 struct drm_bridge *bridge; 52 53 /* the encoder we are hooked to (outside of hdmi block) */ 54 struct drm_encoder *encoder; 55 56 bool hdmi_mode; /* are we in hdmi mode? */ 57 58 int irq; 59 }; 60 61 /* platform config data (ie. from DT, or pdata) */ 62 struct hdmi_platform_config { 63 struct hdmi_phy *(*phy_init)(struct hdmi *hdmi); 64 const char *mmio_name; 65 66 /* regulators that need to be on for hpd: */ 67 const char **hpd_reg_names; 68 int hpd_reg_cnt; 69 70 /* regulators that need to be on for screen pwr: */ 71 const char **pwr_reg_names; 72 int pwr_reg_cnt; 73 74 /* clks that need to be on for hpd: */ 75 const char **hpd_clk_names; 76 int hpd_clk_cnt; 77 78 /* clks that need to be on for screen pwr (ie pixel clk): */ 79 const char **pwr_clk_names; 80 int pwr_clk_cnt; 81 82 /* gpio's: */ 83 int ddc_clk_gpio, ddc_data_gpio, hpd_gpio, mux_en_gpio, mux_sel_gpio; 84 85 /* older devices had their own irq, mdp5+ it is shared w/ mdp: */ 86 bool shared_irq; 87 }; 88 89 void hdmi_set_mode(struct hdmi *hdmi, bool power_on); 90 void hdmi_destroy(struct kref *kref); 91 92 static inline void hdmi_write(struct hdmi *hdmi, u32 reg, u32 data) 93 { 94 msm_writel(data, hdmi->mmio + reg); 95 } 96 97 static inline u32 hdmi_read(struct hdmi *hdmi, u32 reg) 98 { 99 return msm_readl(hdmi->mmio + reg); 100 } 101 102 static inline struct hdmi * hdmi_reference(struct hdmi *hdmi) 103 { 104 kref_get(&hdmi->refcount); 105 return hdmi; 106 } 107 108 static inline void hdmi_unreference(struct hdmi *hdmi) 109 { 110 kref_put(&hdmi->refcount, hdmi_destroy); 111 } 112 113 /* 114 * The phy appears to be different, for example between 8960 and 8x60, 115 * so split the phy related functions out and load the correct one at 116 * runtime: 117 */ 118 119 struct hdmi_phy_funcs { 120 void (*destroy)(struct hdmi_phy *phy); 121 void (*reset)(struct hdmi_phy *phy); 122 void (*powerup)(struct hdmi_phy *phy, unsigned long int pixclock); 123 void (*powerdown)(struct hdmi_phy *phy); 124 }; 125 126 struct hdmi_phy { 127 const struct hdmi_phy_funcs *funcs; 128 }; 129 130 struct hdmi_phy *hdmi_phy_8960_init(struct hdmi *hdmi); 131 struct hdmi_phy *hdmi_phy_8x60_init(struct hdmi *hdmi); 132 struct hdmi_phy *hdmi_phy_8x74_init(struct hdmi *hdmi); 133 134 /* 135 * hdmi bridge: 136 */ 137 138 struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi); 139 140 /* 141 * hdmi connector: 142 */ 143 144 void hdmi_connector_irq(struct drm_connector *connector); 145 struct drm_connector *hdmi_connector_init(struct hdmi *hdmi); 146 147 /* 148 * i2c adapter for ddc: 149 */ 150 151 void hdmi_i2c_irq(struct i2c_adapter *i2c); 152 void hdmi_i2c_destroy(struct i2c_adapter *i2c); 153 struct i2c_adapter *hdmi_i2c_init(struct hdmi *hdmi); 154 155 #endif /* __HDMI_CONNECTOR_H__ */ 156