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