Commit e19ba3d996f22ad8cc7187b30c18347aba0d594d

Authored by Dan Murphy

Merge branch 'audio-display-ti-linux-3.14.y' of git://git.ti.com/~darrene/ti-lin…

…ux-kernel/audio-display-linux-feature-tree into ti-linux-3.14.y

TI-Feature: audio-display
TI-Tree: git://git.ti.com/~darrene/ti-linux-kernel/audio-display-linux-feature-tree.git
TI-Branch: audio-display-ti-linux-3.14.y

* 'audio-display-ti-linux-3.14.y' of git://git.ti.com/~darrene/ti-linux-kernel/audio-display-linux-feature-tree:
  OMAPDSS: HDMI: Do not abort audio playback when display is turned off

Signed-off-by: Dan Murphy <DMurphy@ti.com>

Showing 2 changed files Inline Diff

drivers/video/fbdev/omap2/dss/hdmi4.c
1 /* 1 /*
2 * HDMI interface DSS driver for TI's OMAP4 family of SoCs. 2 * HDMI interface DSS driver for TI's OMAP4 family of SoCs.
3 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ 3 * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/
4 * Authors: Yong Zhi 4 * Authors: Yong Zhi
5 * Mythri pk <mythripk@ti.com> 5 * Mythri pk <mythripk@ti.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by 8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation. 9 * the Free Software Foundation.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT 11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details. 14 * more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License along with 16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>. 17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */ 18 */
19 19
20 #define DSS_SUBSYS_NAME "HDMI" 20 #define DSS_SUBSYS_NAME "HDMI"
21 21
22 #include <linux/kernel.h> 22 #include <linux/kernel.h>
23 #include <linux/module.h> 23 #include <linux/module.h>
24 #include <linux/err.h> 24 #include <linux/err.h>
25 #include <linux/io.h> 25 #include <linux/io.h>
26 #include <linux/interrupt.h> 26 #include <linux/interrupt.h>
27 #include <linux/mutex.h> 27 #include <linux/mutex.h>
28 #include <linux/delay.h> 28 #include <linux/delay.h>
29 #include <linux/string.h> 29 #include <linux/string.h>
30 #include <linux/platform_device.h> 30 #include <linux/platform_device.h>
31 #include <linux/pm_runtime.h> 31 #include <linux/pm_runtime.h>
32 #include <linux/clk.h> 32 #include <linux/clk.h>
33 #include <linux/gpio.h> 33 #include <linux/gpio.h>
34 #include <linux/regulator/consumer.h> 34 #include <linux/regulator/consumer.h>
35 #include <video/omapdss.h> 35 #include <video/omapdss.h>
36 #include <sound/omap-hdmi-audio.h> 36 #include <sound/omap-hdmi-audio.h>
37 37
38 #include "hdmi4_core.h" 38 #include "hdmi4_core.h"
39 #include "dss.h" 39 #include "dss.h"
40 #include "dss_features.h" 40 #include "dss_features.h"
41 #include "hdmi.h" 41 #include "hdmi.h"
42 42
43 static struct omap_hdmi hdmi; 43 static struct omap_hdmi hdmi;
44 44
45 static int hdmi_runtime_get(void) 45 static int hdmi_runtime_get(void)
46 { 46 {
47 int r; 47 int r;
48 48
49 DSSDBG("hdmi_runtime_get\n"); 49 DSSDBG("hdmi_runtime_get\n");
50 50
51 r = pm_runtime_get_sync(&hdmi.pdev->dev); 51 r = pm_runtime_get_sync(&hdmi.pdev->dev);
52 WARN_ON(r < 0); 52 WARN_ON(r < 0);
53 if (r < 0) 53 if (r < 0)
54 return r; 54 return r;
55 55
56 return 0; 56 return 0;
57 } 57 }
58 58
59 static void hdmi_runtime_put(void) 59 static void hdmi_runtime_put(void)
60 { 60 {
61 int r; 61 int r;
62 62
63 DSSDBG("hdmi_runtime_put\n"); 63 DSSDBG("hdmi_runtime_put\n");
64 64
65 r = pm_runtime_put_sync(&hdmi.pdev->dev); 65 r = pm_runtime_put_sync(&hdmi.pdev->dev);
66 WARN_ON(r < 0 && r != -ENOSYS); 66 WARN_ON(r < 0 && r != -ENOSYS);
67 } 67 }
68 68
69 static irqreturn_t hdmi_irq_handler(int irq, void *data) 69 static irqreturn_t hdmi_irq_handler(int irq, void *data)
70 { 70 {
71 struct hdmi_wp_data *wp = data; 71 struct hdmi_wp_data *wp = data;
72 u32 irqstatus; 72 u32 irqstatus;
73 73
74 irqstatus = hdmi_wp_get_irqstatus(wp); 74 irqstatus = hdmi_wp_get_irqstatus(wp);
75 hdmi_wp_set_irqstatus(wp, irqstatus); 75 hdmi_wp_set_irqstatus(wp, irqstatus);
76 76
77 if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && 77 if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
78 irqstatus & HDMI_IRQ_LINK_DISCONNECT) { 78 irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
79 /* 79 /*
80 * If we get both connect and disconnect interrupts at the same 80 * If we get both connect and disconnect interrupts at the same
81 * time, turn off the PHY, clear interrupts, and restart, which 81 * time, turn off the PHY, clear interrupts, and restart, which
82 * raises connect interrupt if a cable is connected, or nothing 82 * raises connect interrupt if a cable is connected, or nothing
83 * if cable is not connected. 83 * if cable is not connected.
84 */ 84 */
85 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); 85 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
86 86
87 hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT | 87 hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT |
88 HDMI_IRQ_LINK_DISCONNECT); 88 HDMI_IRQ_LINK_DISCONNECT);
89 89
90 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 90 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
91 } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { 91 } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
92 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON); 92 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON);
93 } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { 93 } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
94 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 94 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
95 } 95 }
96 96
97 return IRQ_HANDLED; 97 return IRQ_HANDLED;
98 } 98 }
99 99
100 static int hdmi_init_regulator(void) 100 static int hdmi_init_regulator(void)
101 { 101 {
102 int r; 102 int r;
103 struct regulator *reg; 103 struct regulator *reg;
104 104
105 if (hdmi.vdda_reg != NULL) 105 if (hdmi.vdda_reg != NULL)
106 return 0; 106 return 0;
107 107
108 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda"); 108 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda");
109 109
110 if (IS_ERR(reg)) { 110 if (IS_ERR(reg)) {
111 if (PTR_ERR(reg) != -EPROBE_DEFER) 111 if (PTR_ERR(reg) != -EPROBE_DEFER)
112 DSSERR("can't get VDDA regulator\n"); 112 DSSERR("can't get VDDA regulator\n");
113 return PTR_ERR(reg); 113 return PTR_ERR(reg);
114 } 114 }
115 115
116 if (regulator_can_change_voltage(reg)) { 116 if (regulator_can_change_voltage(reg)) {
117 r = regulator_set_voltage(reg, 1800000, 1800000); 117 r = regulator_set_voltage(reg, 1800000, 1800000);
118 if (r) { 118 if (r) {
119 devm_regulator_put(reg); 119 devm_regulator_put(reg);
120 DSSWARN("can't set the regulator voltage\n"); 120 DSSWARN("can't set the regulator voltage\n");
121 return r; 121 return r;
122 } 122 }
123 } 123 }
124 124
125 hdmi.vdda_reg = reg; 125 hdmi.vdda_reg = reg;
126 126
127 return 0; 127 return 0;
128 } 128 }
129 129
130 static int hdmi_pll_enable(struct pll_data *pll, struct hdmi_wp_data *wp, 130 static int hdmi_pll_enable(struct pll_data *pll, struct hdmi_wp_data *wp,
131 struct pll_params *p) 131 struct pll_params *p)
132 { 132 {
133 u16 r = 0; 133 u16 r = 0;
134 134
135 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); 135 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
136 if (r) 136 if (r)
137 return r; 137 return r;
138 138
139 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); 139 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
140 if (r) 140 if (r)
141 return r; 141 return r;
142 142
143 pll_sysreset(pll); 143 pll_sysreset(pll);
144 144
145 r = pll_wait_reset(pll); 145 r = pll_wait_reset(pll);
146 if (r) 146 if (r)
147 return r; 147 return r;
148 148
149 r = pll_calc_and_check_clock_rates(pll, p); 149 r = pll_calc_and_check_clock_rates(pll, p);
150 if (r) 150 if (r)
151 return r; 151 return r;
152 152
153 r = pll_set_clock_div(pll, p); 153 r = pll_set_clock_div(pll, p);
154 if (r) 154 if (r)
155 return r; 155 return r;
156 156
157 return 0; 157 return 0;
158 } 158 }
159 159
160 static void hdmi_pll_disable(struct hdmi_wp_data *wp) 160 static void hdmi_pll_disable(struct hdmi_wp_data *wp)
161 { 161 {
162 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); 162 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
163 } 163 }
164 164
165 static int hdmi_power_on_core(struct omap_dss_device *dssdev) 165 static int hdmi_power_on_core(struct omap_dss_device *dssdev)
166 { 166 {
167 int r; 167 int r;
168 168
169 r = regulator_enable(hdmi.vdda_reg); 169 r = regulator_enable(hdmi.vdda_reg);
170 if (r) 170 if (r)
171 return r; 171 return r;
172 172
173 r = hdmi_runtime_get(); 173 r = hdmi_runtime_get();
174 if (r) 174 if (r)
175 goto err_runtime_get; 175 goto err_runtime_get;
176 176
177 /* Make selection of HDMI in DSS */ 177 /* Make selection of HDMI in DSS */
178 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); 178 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
179 179
180 hdmi.core_enabled = true; 180 hdmi.core_enabled = true;
181 181
182 return 0; 182 return 0;
183 183
184 err_runtime_get: 184 err_runtime_get:
185 regulator_disable(hdmi.vdda_reg); 185 regulator_disable(hdmi.vdda_reg);
186 186
187 return r; 187 return r;
188 } 188 }
189 189
190 static void hdmi_power_off_core(struct omap_dss_device *dssdev) 190 static void hdmi_power_off_core(struct omap_dss_device *dssdev)
191 { 191 {
192 hdmi.core_enabled = false; 192 hdmi.core_enabled = false;
193 193
194 hdmi_runtime_put(); 194 hdmi_runtime_put();
195 regulator_disable(hdmi.vdda_reg); 195 regulator_disable(hdmi.vdda_reg);
196 } 196 }
197 197
198 static int hdmi_power_on_full(struct omap_dss_device *dssdev) 198 static int hdmi_power_on_full(struct omap_dss_device *dssdev)
199 { 199 {
200 int r; 200 int r;
201 struct omap_video_timings *p; 201 struct omap_video_timings *p;
202 struct omap_overlay_manager *mgr = hdmi.output.manager; 202 struct omap_overlay_manager *mgr = hdmi.output.manager;
203 unsigned long phy; 203 unsigned long phy;
204 struct hdmi_wp_data *wp = &hdmi.wp; 204 struct hdmi_wp_data *wp = &hdmi.wp;
205 struct pll_params param; 205 struct pll_params param;
206 bool ok; 206 bool ok;
207 207
208 r = hdmi_power_on_core(dssdev); 208 r = hdmi_power_on_core(dssdev);
209 if (r) 209 if (r)
210 return r; 210 return r;
211 211
212 /* disable and clear irqs */ 212 /* disable and clear irqs */
213 hdmi_wp_clear_irqenable(wp, 0xffffffff); 213 hdmi_wp_clear_irqenable(wp, 0xffffffff);
214 hdmi_wp_set_irqstatus(wp, 0xffffffff); 214 hdmi_wp_set_irqstatus(wp, 0xffffffff);
215 215
216 p = &hdmi.cfg.timings; 216 p = &hdmi.cfg.timings;
217 217
218 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); 218 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
219 219
220 phy = p->pixelclock * 10; 220 phy = p->pixelclock * 10;
221 221
222 memset(&param, 0, sizeof(param)); 222 memset(&param, 0, sizeof(param));
223 223
224 ok = pll_calc(hdmi.pll, phy, phy, NULL, &param); 224 ok = pll_calc(hdmi.pll, phy, phy, NULL, &param);
225 if (!ok) { 225 if (!ok) {
226 DSSDBG("Failed to calculate PLL settings\n"); 226 DSSDBG("Failed to calculate PLL settings\n");
227 goto err_pll_enable; 227 goto err_pll_enable;
228 } 228 }
229 229
230 /* config the PLL and PHY hdmi_set_pll_pwrfirst */ 230 /* config the PLL and PHY hdmi_set_pll_pwrfirst */
231 r = hdmi_pll_enable(hdmi.pll, &hdmi.wp, &param); 231 r = hdmi_pll_enable(hdmi.pll, &hdmi.wp, &param);
232 if (r) { 232 if (r) {
233 DSSDBG("Failed to lock PLL\n"); 233 DSSDBG("Failed to lock PLL\n");
234 goto err_pll_enable; 234 goto err_pll_enable;
235 } 235 }
236 236
237 r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg); 237 r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg);
238 if (r) { 238 if (r) {
239 DSSDBG("Failed to configure PHY\n"); 239 DSSDBG("Failed to configure PHY\n");
240 goto err_phy_cfg; 240 goto err_phy_cfg;
241 } 241 }
242 242
243 r = hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 243 r = hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
244 if (r) 244 if (r)
245 goto err_phy_pwr; 245 goto err_phy_pwr;
246 246
247 hdmi4_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); 247 hdmi4_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg);
248 248
249 /* bypass TV gamma table */ 249 /* bypass TV gamma table */
250 dispc_enable_gamma_table(0); 250 dispc_enable_gamma_table(0);
251 251
252 /* tv size */ 252 /* tv size */
253 dss_mgr_set_timings(mgr, p); 253 dss_mgr_set_timings(mgr, p);
254 254
255 r = dss_mgr_enable(mgr); 255 r = dss_mgr_enable(mgr);
256 if (r) 256 if (r)
257 goto err_mgr_enable; 257 goto err_mgr_enable;
258 258
259 r = hdmi_wp_video_start(&hdmi.wp); 259 r = hdmi_wp_video_start(&hdmi.wp);
260 if (r) 260 if (r)
261 goto err_vid_enable; 261 goto err_vid_enable;
262 262
263 hdmi_wp_set_irqenable(wp, 263 hdmi_wp_set_irqenable(wp,
264 HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); 264 HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
265 265
266 return 0; 266 return 0;
267 267
268 err_vid_enable: 268 err_vid_enable:
269 dss_mgr_disable(mgr); 269 dss_mgr_disable(mgr);
270 err_mgr_enable: 270 err_mgr_enable:
271 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 271 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
272 err_phy_pwr: 272 err_phy_pwr:
273 err_phy_cfg: 273 err_phy_cfg:
274 hdmi_pll_disable(&hdmi.wp); 274 hdmi_pll_disable(&hdmi.wp);
275 err_pll_enable: 275 err_pll_enable:
276 hdmi_power_off_core(dssdev); 276 hdmi_power_off_core(dssdev);
277 return -EIO; 277 return -EIO;
278 } 278 }
279 279
280 static void hdmi_power_off_full(struct omap_dss_device *dssdev) 280 static void hdmi_power_off_full(struct omap_dss_device *dssdev)
281 { 281 {
282 struct omap_overlay_manager *mgr = hdmi.output.manager; 282 struct omap_overlay_manager *mgr = hdmi.output.manager;
283 283
284 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); 284 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
285 285
286 hdmi_wp_video_stop(&hdmi.wp); 286 hdmi_wp_video_stop(&hdmi.wp);
287 287
288 dss_mgr_disable(mgr); 288 dss_mgr_disable(mgr);
289 289
290 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 290 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
291 291
292 hdmi_pll_disable(&hdmi.wp); 292 hdmi_pll_disable(&hdmi.wp);
293 293
294 hdmi_power_off_core(dssdev); 294 hdmi_power_off_core(dssdev);
295 } 295 }
296 296
297 static int hdmi_display_check_timing(struct omap_dss_device *dssdev, 297 static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
298 struct omap_video_timings *timings) 298 struct omap_video_timings *timings)
299 { 299 {
300 struct omap_dss_device *out = &hdmi.output; 300 struct omap_dss_device *out = &hdmi.output;
301 301
302 if (!dispc_mgr_timings_ok(out->dispc_channel, timings)) 302 if (!dispc_mgr_timings_ok(out->dispc_channel, timings))
303 return -EINVAL; 303 return -EINVAL;
304 304
305 return 0; 305 return 0;
306 } 306 }
307 307
308 static void hdmi_display_set_timing(struct omap_dss_device *dssdev, 308 static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
309 struct omap_video_timings *timings) 309 struct omap_video_timings *timings)
310 { 310 {
311 mutex_lock(&hdmi.lock); 311 mutex_lock(&hdmi.lock);
312 312
313 hdmi.cfg.timings = *timings; 313 hdmi.cfg.timings = *timings;
314 314
315 dispc_set_tv_pclk(timings->pixelclock); 315 dispc_set_tv_pclk(timings->pixelclock);
316 316
317 mutex_unlock(&hdmi.lock); 317 mutex_unlock(&hdmi.lock);
318 } 318 }
319 319
320 static void hdmi_display_get_timings(struct omap_dss_device *dssdev, 320 static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
321 struct omap_video_timings *timings) 321 struct omap_video_timings *timings)
322 { 322 {
323 *timings = hdmi.cfg.timings; 323 *timings = hdmi.cfg.timings;
324 } 324 }
325 325
326 static void hdmi_dump_regs(struct seq_file *s) 326 static void hdmi_dump_regs(struct seq_file *s)
327 { 327 {
328 mutex_lock(&hdmi.lock); 328 mutex_lock(&hdmi.lock);
329 329
330 if (hdmi_runtime_get()) { 330 if (hdmi_runtime_get()) {
331 mutex_unlock(&hdmi.lock); 331 mutex_unlock(&hdmi.lock);
332 return; 332 return;
333 } 333 }
334 334
335 hdmi_wp_dump(&hdmi.wp, s); 335 hdmi_wp_dump(&hdmi.wp, s);
336 pll_dump(hdmi.pll, s); 336 pll_dump(hdmi.pll, s);
337 hdmi_phy_dump(&hdmi.phy, s); 337 hdmi_phy_dump(&hdmi.phy, s);
338 hdmi4_core_dump(&hdmi.core, s); 338 hdmi4_core_dump(&hdmi.core, s);
339 339
340 hdmi_runtime_put(); 340 hdmi_runtime_put();
341 mutex_unlock(&hdmi.lock); 341 mutex_unlock(&hdmi.lock);
342 } 342 }
343 343
344 static int read_edid(u8 *buf, int len) 344 static int read_edid(u8 *buf, int len)
345 { 345 {
346 int r; 346 int r;
347 347
348 mutex_lock(&hdmi.lock); 348 mutex_lock(&hdmi.lock);
349 349
350 r = hdmi_runtime_get(); 350 r = hdmi_runtime_get();
351 BUG_ON(r); 351 BUG_ON(r);
352 352
353 r = hdmi4_read_edid(&hdmi.core, buf, len); 353 r = hdmi4_read_edid(&hdmi.core, buf, len);
354 354
355 hdmi_runtime_put(); 355 hdmi_runtime_put();
356 mutex_unlock(&hdmi.lock); 356 mutex_unlock(&hdmi.lock);
357 357
358 return r; 358 return r;
359 } 359 }
360 360
361 static int hdmi_display_enable(struct omap_dss_device *dssdev) 361 static int hdmi_display_enable(struct omap_dss_device *dssdev)
362 { 362 {
363 struct omap_dss_device *out = &hdmi.output; 363 struct omap_dss_device *out = &hdmi.output;
364 int r = 0; 364 int r = 0;
365 365
366 DSSDBG("ENTER hdmi_display_enable\n"); 366 DSSDBG("ENTER hdmi_display_enable\n");
367 367
368 mutex_lock(&hdmi.lock); 368 mutex_lock(&hdmi.lock);
369 369
370 if (out == NULL || out->manager == NULL) { 370 if (out == NULL || out->manager == NULL) {
371 DSSERR("failed to enable display: no output/manager\n"); 371 DSSERR("failed to enable display: no output/manager\n");
372 r = -ENODEV; 372 r = -ENODEV;
373 goto err0; 373 goto err0;
374 } 374 }
375 375
376 r = hdmi_power_on_full(dssdev); 376 r = hdmi_power_on_full(dssdev);
377 if (r) { 377 if (r) {
378 DSSERR("failed to power on device\n"); 378 DSSERR("failed to power on device\n");
379 goto err0; 379 goto err0;
380 } 380 }
381 381
382 hdmi.display_enabled = true; 382 hdmi.display_enabled = true;
383 383
384 mutex_unlock(&hdmi.lock); 384 mutex_unlock(&hdmi.lock);
385 return 0; 385 return 0;
386 386
387 err0: 387 err0:
388 mutex_unlock(&hdmi.lock); 388 mutex_unlock(&hdmi.lock);
389 return r; 389 return r;
390 } 390 }
391 391
392 static void hdmi_display_disable(struct omap_dss_device *dssdev) 392 static void hdmi_display_disable(struct omap_dss_device *dssdev)
393 { 393 {
394 DSSDBG("Enter hdmi_display_disable\n"); 394 DSSDBG("Enter hdmi_display_disable\n");
395 395
396 mutex_lock(&hdmi.lock); 396 mutex_lock(&hdmi.lock);
397 397
398 if (hdmi.audio_abort_cb) 398 /* If set hdmi.audio_abort_cb(&hdmi.pdev->dev) should be
399 hdmi.audio_abort_cb(&hdmi.pdev->dev); 399 * called here, if audio abort functionality is needed. */
400 400
401 hdmi_power_off_full(dssdev); 401 hdmi_power_off_full(dssdev);
402 402
403 hdmi.display_enabled = false; 403 hdmi.display_enabled = false;
404 404
405 mutex_unlock(&hdmi.lock); 405 mutex_unlock(&hdmi.lock);
406 } 406 }
407 407
408 static int hdmi_core_enable(struct omap_dss_device *dssdev) 408 static int hdmi_core_enable(struct omap_dss_device *dssdev)
409 { 409 {
410 int r = 0; 410 int r = 0;
411 411
412 DSSDBG("ENTER omapdss_hdmi_core_enable\n"); 412 DSSDBG("ENTER omapdss_hdmi_core_enable\n");
413 413
414 mutex_lock(&hdmi.lock); 414 mutex_lock(&hdmi.lock);
415 415
416 r = hdmi_power_on_core(dssdev); 416 r = hdmi_power_on_core(dssdev);
417 if (r) { 417 if (r) {
418 DSSERR("failed to power on device\n"); 418 DSSERR("failed to power on device\n");
419 goto err0; 419 goto err0;
420 } 420 }
421 421
422 mutex_unlock(&hdmi.lock); 422 mutex_unlock(&hdmi.lock);
423 return 0; 423 return 0;
424 424
425 err0: 425 err0:
426 mutex_unlock(&hdmi.lock); 426 mutex_unlock(&hdmi.lock);
427 return r; 427 return r;
428 } 428 }
429 429
430 static void hdmi_core_disable(struct omap_dss_device *dssdev) 430 static void hdmi_core_disable(struct omap_dss_device *dssdev)
431 { 431 {
432 DSSDBG("Enter omapdss_hdmi_core_disable\n"); 432 DSSDBG("Enter omapdss_hdmi_core_disable\n");
433 433
434 mutex_lock(&hdmi.lock); 434 mutex_lock(&hdmi.lock);
435 435
436 hdmi_power_off_core(dssdev); 436 hdmi_power_off_core(dssdev);
437 437
438 mutex_unlock(&hdmi.lock); 438 mutex_unlock(&hdmi.lock);
439 } 439 }
440 440
441 static int hdmi_connect(struct omap_dss_device *dssdev, 441 static int hdmi_connect(struct omap_dss_device *dssdev,
442 struct omap_dss_device *dst) 442 struct omap_dss_device *dst)
443 { 443 {
444 struct omap_overlay_manager *mgr; 444 struct omap_overlay_manager *mgr;
445 int r; 445 int r;
446 446
447 r = hdmi_init_regulator(); 447 r = hdmi_init_regulator();
448 if (r) 448 if (r)
449 return r; 449 return r;
450 450
451 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel); 451 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
452 if (!mgr) 452 if (!mgr)
453 return -ENODEV; 453 return -ENODEV;
454 454
455 r = dss_mgr_connect(mgr, dssdev); 455 r = dss_mgr_connect(mgr, dssdev);
456 if (r) 456 if (r)
457 return r; 457 return r;
458 458
459 r = omapdss_output_set_device(dssdev, dst); 459 r = omapdss_output_set_device(dssdev, dst);
460 if (r) { 460 if (r) {
461 DSSERR("failed to connect output to new device: %s\n", 461 DSSERR("failed to connect output to new device: %s\n",
462 dst->name); 462 dst->name);
463 dss_mgr_disconnect(mgr, dssdev); 463 dss_mgr_disconnect(mgr, dssdev);
464 return r; 464 return r;
465 } 465 }
466 466
467 return 0; 467 return 0;
468 } 468 }
469 469
470 static void hdmi_disconnect(struct omap_dss_device *dssdev, 470 static void hdmi_disconnect(struct omap_dss_device *dssdev,
471 struct omap_dss_device *dst) 471 struct omap_dss_device *dst)
472 { 472 {
473 WARN_ON(dst != dssdev->dst); 473 WARN_ON(dst != dssdev->dst);
474 474
475 if (dst != dssdev->dst) 475 if (dst != dssdev->dst)
476 return; 476 return;
477 477
478 omapdss_output_unset_device(dssdev); 478 omapdss_output_unset_device(dssdev);
479 479
480 if (dssdev->manager) 480 if (dssdev->manager)
481 dss_mgr_disconnect(dssdev->manager, dssdev); 481 dss_mgr_disconnect(dssdev->manager, dssdev);
482 } 482 }
483 483
484 static int hdmi_read_edid(struct omap_dss_device *dssdev, 484 static int hdmi_read_edid(struct omap_dss_device *dssdev,
485 u8 *edid, int len) 485 u8 *edid, int len)
486 { 486 {
487 bool need_enable; 487 bool need_enable;
488 int r; 488 int r;
489 489
490 need_enable = hdmi.core_enabled == false; 490 need_enable = hdmi.core_enabled == false;
491 491
492 if (need_enable) { 492 if (need_enable) {
493 r = hdmi_core_enable(dssdev); 493 r = hdmi_core_enable(dssdev);
494 if (r) 494 if (r)
495 return r; 495 return r;
496 } 496 }
497 497
498 r = read_edid(edid, len); 498 r = read_edid(edid, len);
499 499
500 if (need_enable) 500 if (need_enable)
501 hdmi_core_disable(dssdev); 501 hdmi_core_disable(dssdev);
502 502
503 return r; 503 return r;
504 } 504 }
505 505
506 static int hdmi_set_infoframe(struct omap_dss_device *dssdev, 506 static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
507 const struct hdmi_avi_infoframe *avi) 507 const struct hdmi_avi_infoframe *avi)
508 { 508 {
509 hdmi.cfg.infoframe = *avi; 509 hdmi.cfg.infoframe = *avi;
510 return 0; 510 return 0;
511 } 511 }
512 512
513 static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev, 513 static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
514 bool hdmi_mode) 514 bool hdmi_mode)
515 { 515 {
516 hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI; 516 hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
517 return 0; 517 return 0;
518 } 518 }
519 519
520 static const struct omapdss_hdmi_ops hdmi_ops = { 520 static const struct omapdss_hdmi_ops hdmi_ops = {
521 .connect = hdmi_connect, 521 .connect = hdmi_connect,
522 .disconnect = hdmi_disconnect, 522 .disconnect = hdmi_disconnect,
523 523
524 .enable = hdmi_display_enable, 524 .enable = hdmi_display_enable,
525 .disable = hdmi_display_disable, 525 .disable = hdmi_display_disable,
526 526
527 .check_timings = hdmi_display_check_timing, 527 .check_timings = hdmi_display_check_timing,
528 .set_timings = hdmi_display_set_timing, 528 .set_timings = hdmi_display_set_timing,
529 .get_timings = hdmi_display_get_timings, 529 .get_timings = hdmi_display_get_timings,
530 530
531 .read_edid = hdmi_read_edid, 531 .read_edid = hdmi_read_edid,
532 .set_infoframe = hdmi_set_infoframe, 532 .set_infoframe = hdmi_set_infoframe,
533 .set_hdmi_mode = hdmi_set_hdmi_mode, 533 .set_hdmi_mode = hdmi_set_hdmi_mode,
534 }; 534 };
535 535
536 static void hdmi_init_output(struct platform_device *pdev) 536 static void hdmi_init_output(struct platform_device *pdev)
537 { 537 {
538 struct omap_dss_device *out = &hdmi.output; 538 struct omap_dss_device *out = &hdmi.output;
539 539
540 out->dev = &pdev->dev; 540 out->dev = &pdev->dev;
541 out->id = OMAP_DSS_OUTPUT_HDMI; 541 out->id = OMAP_DSS_OUTPUT_HDMI;
542 out->output_type = OMAP_DISPLAY_TYPE_HDMI; 542 out->output_type = OMAP_DISPLAY_TYPE_HDMI;
543 out->name = "hdmi.0"; 543 out->name = "hdmi.0";
544 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; 544 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
545 out->ops.hdmi = &hdmi_ops; 545 out->ops.hdmi = &hdmi_ops;
546 out->owner = THIS_MODULE; 546 out->owner = THIS_MODULE;
547 547
548 omapdss_register_output(out); 548 omapdss_register_output(out);
549 } 549 }
550 550
551 static void __exit hdmi_uninit_output(struct platform_device *pdev) 551 static void __exit hdmi_uninit_output(struct platform_device *pdev)
552 { 552 {
553 struct omap_dss_device *out = &hdmi.output; 553 struct omap_dss_device *out = &hdmi.output;
554 554
555 omapdss_unregister_output(out); 555 omapdss_unregister_output(out);
556 } 556 }
557 557
558 static int hdmi_probe_of(struct platform_device *pdev) 558 static int hdmi_probe_of(struct platform_device *pdev)
559 { 559 {
560 struct device_node *node = pdev->dev.of_node; 560 struct device_node *node = pdev->dev.of_node;
561 struct device_node *ep; 561 struct device_node *ep;
562 int r; 562 int r;
563 563
564 ep = omapdss_of_get_first_endpoint(node); 564 ep = omapdss_of_get_first_endpoint(node);
565 if (!ep) 565 if (!ep)
566 return 0; 566 return 0;
567 567
568 r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy); 568 r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy);
569 if (r) 569 if (r)
570 goto err; 570 goto err;
571 571
572 of_node_put(ep); 572 of_node_put(ep);
573 return 0; 573 return 0;
574 574
575 err: 575 err:
576 of_node_put(ep); 576 of_node_put(ep);
577 return r; 577 return r;
578 } 578 }
579 579
580 #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) 580 #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
581 static int audio_startup(struct device *dev, 581 static int audio_startup(struct device *dev,
582 void (*abort_cb)(struct device *dev)) 582 void (*abort_cb)(struct device *dev))
583 { 583 {
584 struct omap_hdmi *hd = dev_get_drvdata(dev); 584 struct omap_hdmi *hd = dev_get_drvdata(dev);
585 int ret = 0; 585 int ret = 0;
586 586
587 mutex_lock(&hd->lock); 587 mutex_lock(&hd->lock);
588 588
589 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) { 589 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
590 ret = -EPERM; 590 ret = -EPERM;
591 goto out; 591 goto out;
592 } 592 }
593 593
594 hd->audio_abort_cb = abort_cb; 594 hd->audio_abort_cb = abort_cb;
595 595
596 out: 596 out:
597 mutex_unlock(&hd->lock); 597 mutex_unlock(&hd->lock);
598 598
599 return ret; 599 return ret;
600 } 600 }
601 601
602 static int audio_enable(struct device *dev, bool enable) 602 static int audio_enable(struct device *dev, bool enable)
603 { 603 {
604 struct omap_hdmi *hd = dev_get_drvdata(dev); 604 struct omap_hdmi *hd = dev_get_drvdata(dev);
605 int ret; 605 int ret;
606 606
607 mutex_lock(&hd->lock); 607 mutex_lock(&hd->lock);
608 608
609 ret = hdmi_wp_audio_enable(&hd->wp, enable); 609 ret = hdmi_wp_audio_enable(&hd->wp, enable);
610 610
611 if (!enable) 611 if (!enable)
612 hd->audio_abort_cb = NULL; 612 hd->audio_abort_cb = NULL;
613 613
614 mutex_unlock(&hd->lock); 614 mutex_unlock(&hd->lock);
615 615
616 return ret; 616 return ret;
617 } 617 }
618 618
619 static int audio_start(struct device *dev, bool enable) 619 static int audio_start(struct device *dev, bool enable)
620 { 620 {
621 struct omap_hdmi *hd = dev_get_drvdata(dev); 621 struct omap_hdmi *hd = dev_get_drvdata(dev);
622 int ret = 0; 622 int ret = 0;
623 623
624 if (enable) 624 if (enable)
625 ret = hdmi4_audio_start(&hd->core, &hd->wp); 625 ret = hdmi4_audio_start(&hd->core, &hd->wp);
626 else 626 else
627 hdmi4_audio_stop(&hd->core, &hd->wp); 627 hdmi4_audio_stop(&hd->core, &hd->wp);
628 628
629 return ret; 629 return ret;
630 } 630 }
631 631
632 static int audio_config(struct device *dev, struct omap_dss_audio *dss_audio) 632 static int audio_config(struct device *dev, struct omap_dss_audio *dss_audio)
633 { 633 {
634 struct omap_hdmi *hd = dev_get_drvdata(dev); 634 struct omap_hdmi *hd = dev_get_drvdata(dev);
635 int ret; 635 int ret;
636 636
637 mutex_lock(&hd->lock); 637 mutex_lock(&hd->lock);
638 if (!hdmi_mode_has_audio(&hd->cfg)) 638 if (!hdmi_mode_has_audio(&hd->cfg))
639 ret = -EPERM; 639 ret = -EPERM;
640 else 640 else
641 ret = hdmi4_audio_config(&hd->core, &hd->wp, dss_audio, 641 ret = hdmi4_audio_config(&hd->core, &hd->wp, dss_audio,
642 hd->cfg.timings.pixelclock); 642 hd->cfg.timings.pixelclock);
643 mutex_unlock(&hd->lock); 643 mutex_unlock(&hd->lock);
644 644
645 return ret; 645 return ret;
646 } 646 }
647 647
648 static int hdmi_audio_register(struct device *dev) 648 static int hdmi_audio_register(struct device *dev)
649 { 649 {
650 struct omap_hdmi_audio ha = { 650 struct omap_hdmi_audio ha = {
651 .dev = dev, 651 .dev = dev,
652 .hw_version = OMAP4_HDMI, 652 .hw_version = OMAP4_HDMI,
653 .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp), 653 .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
654 .audio_startup = audio_startup, 654 .audio_startup = audio_startup,
655 .audio_enable = audio_enable, 655 .audio_enable = audio_enable,
656 .audio_start = audio_start, 656 .audio_start = audio_start,
657 .audio_config = audio_config, 657 .audio_config = audio_config,
658 }; 658 };
659 659
660 return omap_hdmi_audio_register(&ha); 660 return omap_hdmi_audio_register(&ha);
661 } 661 }
662 #else /* CONFIG_OMAP4_DSS_HDMI_AUDIO */ 662 #else /* CONFIG_OMAP4_DSS_HDMI_AUDIO */
663 static int hdmi_audio_register(struct device *dev) 663 static int hdmi_audio_register(struct device *dev)
664 { 664 {
665 return 0; 665 return 0;
666 } 666 }
667 #endif 667 #endif
668 668
669 /* HDMI HW IP initialisation */ 669 /* HDMI HW IP initialisation */
670 static int omapdss_hdmihw_probe(struct platform_device *pdev) 670 static int omapdss_hdmihw_probe(struct platform_device *pdev)
671 { 671 {
672 int r; 672 int r;
673 int irq; 673 int irq;
674 674
675 hdmi.pdev = pdev; 675 hdmi.pdev = pdev;
676 dev_set_drvdata(&pdev->dev, &hdmi); 676 dev_set_drvdata(&pdev->dev, &hdmi);
677 677
678 mutex_init(&hdmi.lock); 678 mutex_init(&hdmi.lock);
679 679
680 if (pdev->dev.of_node) { 680 if (pdev->dev.of_node) {
681 r = hdmi_probe_of(pdev); 681 r = hdmi_probe_of(pdev);
682 if (r) 682 if (r)
683 return r; 683 return r;
684 } 684 }
685 685
686 r = hdmi_wp_init(pdev, &hdmi.wp); 686 r = hdmi_wp_init(pdev, &hdmi.wp);
687 if (r) 687 if (r)
688 return r; 688 return r;
689 689
690 hdmi.pll = pll_create(pdev, "pll", "sys_clk", DSS_PLL_TYPE_HDMI, 690 hdmi.pll = pll_create(pdev, "pll", "sys_clk", DSS_PLL_TYPE_HDMI,
691 NULL, 0); 691 NULL, 0);
692 if (!hdmi.pll) 692 if (!hdmi.pll)
693 return -ENODEV; 693 return -ENODEV;
694 694
695 r = hdmi_phy_init(pdev, &hdmi.phy); 695 r = hdmi_phy_init(pdev, &hdmi.phy);
696 if (r) 696 if (r)
697 return r; 697 return r;
698 698
699 r = hdmi4_core_init(pdev, &hdmi.core); 699 r = hdmi4_core_init(pdev, &hdmi.core);
700 if (r) 700 if (r)
701 return r; 701 return r;
702 702
703 irq = platform_get_irq(pdev, 0); 703 irq = platform_get_irq(pdev, 0);
704 if (irq < 0) { 704 if (irq < 0) {
705 DSSERR("platform_get_irq failed\n"); 705 DSSERR("platform_get_irq failed\n");
706 return -ENODEV; 706 return -ENODEV;
707 } 707 }
708 708
709 r = devm_request_threaded_irq(&pdev->dev, irq, 709 r = devm_request_threaded_irq(&pdev->dev, irq,
710 NULL, hdmi_irq_handler, 710 NULL, hdmi_irq_handler,
711 IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); 711 IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp);
712 if (r) { 712 if (r) {
713 DSSERR("HDMI IRQ request failed\n"); 713 DSSERR("HDMI IRQ request failed\n");
714 return r; 714 return r;
715 } 715 }
716 716
717 pm_runtime_enable(&pdev->dev); 717 pm_runtime_enable(&pdev->dev);
718 718
719 hdmi_init_output(pdev); 719 hdmi_init_output(pdev);
720 720
721 r = hdmi_audio_register(&pdev->dev); 721 r = hdmi_audio_register(&pdev->dev);
722 if (r) { 722 if (r) {
723 DSSERR("Registering HDMI audio failed\n"); 723 DSSERR("Registering HDMI audio failed\n");
724 hdmi_uninit_output(pdev); 724 hdmi_uninit_output(pdev);
725 pm_runtime_disable(&pdev->dev); 725 pm_runtime_disable(&pdev->dev);
726 return r; 726 return r;
727 } 727 }
728 728
729 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 729 dss_debugfs_create_file("hdmi", hdmi_dump_regs);
730 730
731 return 0; 731 return 0;
732 } 732 }
733 733
734 static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) 734 static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
735 { 735 {
736 omap_hdmi_audio_unregister(&pdev->dev); 736 omap_hdmi_audio_unregister(&pdev->dev);
737 737
738 hdmi_uninit_output(pdev); 738 hdmi_uninit_output(pdev);
739 739
740 pm_runtime_disable(&pdev->dev); 740 pm_runtime_disable(&pdev->dev);
741 741
742 return 0; 742 return 0;
743 } 743 }
744 744
745 static int hdmi_runtime_suspend(struct device *dev) 745 static int hdmi_runtime_suspend(struct device *dev)
746 { 746 {
747 pll_enable_clock(hdmi.pll, false); 747 pll_enable_clock(hdmi.pll, false);
748 748
749 dispc_runtime_put(); 749 dispc_runtime_put();
750 750
751 return 0; 751 return 0;
752 } 752 }
753 753
754 static int hdmi_runtime_resume(struct device *dev) 754 static int hdmi_runtime_resume(struct device *dev)
755 { 755 {
756 int r; 756 int r;
757 757
758 r = dispc_runtime_get(); 758 r = dispc_runtime_get();
759 if (r < 0) 759 if (r < 0)
760 return r; 760 return r;
761 761
762 pll_enable_clock(hdmi.pll, true); 762 pll_enable_clock(hdmi.pll, true);
763 763
764 return 0; 764 return 0;
765 } 765 }
766 766
767 static const struct dev_pm_ops hdmi_pm_ops = { 767 static const struct dev_pm_ops hdmi_pm_ops = {
768 .runtime_suspend = hdmi_runtime_suspend, 768 .runtime_suspend = hdmi_runtime_suspend,
769 .runtime_resume = hdmi_runtime_resume, 769 .runtime_resume = hdmi_runtime_resume,
770 }; 770 };
771 771
772 static const struct of_device_id hdmi_of_match[] = { 772 static const struct of_device_id hdmi_of_match[] = {
773 { .compatible = "ti,omap4-hdmi", }, 773 { .compatible = "ti,omap4-hdmi", },
774 {}, 774 {},
775 }; 775 };
776 776
777 static struct platform_driver omapdss_hdmihw_driver = { 777 static struct platform_driver omapdss_hdmihw_driver = {
778 .probe = omapdss_hdmihw_probe, 778 .probe = omapdss_hdmihw_probe,
779 .remove = __exit_p(omapdss_hdmihw_remove), 779 .remove = __exit_p(omapdss_hdmihw_remove),
780 .driver = { 780 .driver = {
781 .name = "omapdss_hdmi", 781 .name = "omapdss_hdmi",
782 .owner = THIS_MODULE, 782 .owner = THIS_MODULE,
783 .pm = &hdmi_pm_ops, 783 .pm = &hdmi_pm_ops,
784 .of_match_table = hdmi_of_match, 784 .of_match_table = hdmi_of_match,
785 }, 785 },
786 }; 786 };
787 787
788 int __init hdmi4_init_platform_driver(void) 788 int __init hdmi4_init_platform_driver(void)
789 { 789 {
790 return platform_driver_register(&omapdss_hdmihw_driver); 790 return platform_driver_register(&omapdss_hdmihw_driver);
791 } 791 }
792 792
793 void __exit hdmi4_uninit_platform_driver(void) 793 void __exit hdmi4_uninit_platform_driver(void)
794 { 794 {
795 platform_driver_unregister(&omapdss_hdmihw_driver); 795 platform_driver_unregister(&omapdss_hdmihw_driver);
796 } 796 }
797 797
drivers/video/fbdev/omap2/dss/hdmi5.c
1 /* 1 /*
2 * HDMI driver for OMAP5 2 * HDMI driver for OMAP5
3 * 3 *
4 * Copyright (C) 2014 Texas Instruments Incorporated 4 * Copyright (C) 2014 Texas Instruments Incorporated
5 * 5 *
6 * Authors: 6 * Authors:
7 * Yong Zhi 7 * Yong Zhi
8 * Mythri pk 8 * Mythri pk
9 * Archit Taneja <archit@ti.com> 9 * Archit Taneja <archit@ti.com>
10 * Tomi Valkeinen <tomi.valkeinen@ti.com> 10 * Tomi Valkeinen <tomi.valkeinen@ti.com>
11 * 11 *
12 * This program is free software; you can redistribute it and/or modify it 12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License version 2 as published by 13 * under the terms of the GNU General Public License version 2 as published by
14 * the Free Software Foundation. 14 * the Free Software Foundation.
15 * 15 *
16 * This program is distributed in the hope that it will be useful, but WITHOUT 16 * This program is distributed in the hope that it will be useful, but WITHOUT
17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 18 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19 * more details. 19 * more details.
20 * 20 *
21 * You should have received a copy of the GNU General Public License along with 21 * You should have received a copy of the GNU General Public License along with
22 * this program. If not, see <http://www.gnu.org/licenses/>. 22 * this program. If not, see <http://www.gnu.org/licenses/>.
23 */ 23 */
24 24
25 #define DSS_SUBSYS_NAME "HDMI" 25 #define DSS_SUBSYS_NAME "HDMI"
26 26
27 #include <linux/kernel.h> 27 #include <linux/kernel.h>
28 #include <linux/module.h> 28 #include <linux/module.h>
29 #include <linux/err.h> 29 #include <linux/err.h>
30 #include <linux/io.h> 30 #include <linux/io.h>
31 #include <linux/interrupt.h> 31 #include <linux/interrupt.h>
32 #include <linux/mutex.h> 32 #include <linux/mutex.h>
33 #include <linux/delay.h> 33 #include <linux/delay.h>
34 #include <linux/string.h> 34 #include <linux/string.h>
35 #include <linux/platform_device.h> 35 #include <linux/platform_device.h>
36 #include <linux/pm_runtime.h> 36 #include <linux/pm_runtime.h>
37 #include <linux/clk.h> 37 #include <linux/clk.h>
38 #include <linux/gpio.h> 38 #include <linux/gpio.h>
39 #include <linux/regulator/consumer.h> 39 #include <linux/regulator/consumer.h>
40 #include <video/omapdss.h> 40 #include <video/omapdss.h>
41 #include <sound/omap-hdmi-audio.h> 41 #include <sound/omap-hdmi-audio.h>
42 42
43 #include "hdmi5_core.h" 43 #include "hdmi5_core.h"
44 #include "dss.h" 44 #include "dss.h"
45 #include "dss_features.h" 45 #include "dss_features.h"
46 46
47 static struct omap_hdmi hdmi; 47 static struct omap_hdmi hdmi;
48 48
49 static int hdmi_runtime_get(void) 49 static int hdmi_runtime_get(void)
50 { 50 {
51 int r; 51 int r;
52 52
53 DSSDBG("hdmi_runtime_get\n"); 53 DSSDBG("hdmi_runtime_get\n");
54 54
55 r = pm_runtime_get_sync(&hdmi.pdev->dev); 55 r = pm_runtime_get_sync(&hdmi.pdev->dev);
56 WARN_ON(r < 0); 56 WARN_ON(r < 0);
57 if (r < 0) 57 if (r < 0)
58 return r; 58 return r;
59 59
60 return 0; 60 return 0;
61 } 61 }
62 62
63 static void hdmi_runtime_put(void) 63 static void hdmi_runtime_put(void)
64 { 64 {
65 int r; 65 int r;
66 66
67 DSSDBG("hdmi_runtime_put\n"); 67 DSSDBG("hdmi_runtime_put\n");
68 68
69 r = pm_runtime_put_sync(&hdmi.pdev->dev); 69 r = pm_runtime_put_sync(&hdmi.pdev->dev);
70 WARN_ON(r < 0 && r != -ENOSYS); 70 WARN_ON(r < 0 && r != -ENOSYS);
71 } 71 }
72 72
73 static irqreturn_t hdmi_irq_handler(int irq, void *data) 73 static irqreturn_t hdmi_irq_handler(int irq, void *data)
74 { 74 {
75 struct hdmi_wp_data *wp = data; 75 struct hdmi_wp_data *wp = data;
76 u32 irqstatus; 76 u32 irqstatus;
77 77
78 irqstatus = hdmi_wp_get_irqstatus(wp); 78 irqstatus = hdmi_wp_get_irqstatus(wp);
79 hdmi_wp_set_irqstatus(wp, irqstatus); 79 hdmi_wp_set_irqstatus(wp, irqstatus);
80 80
81 if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && 81 if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
82 irqstatus & HDMI_IRQ_LINK_DISCONNECT) { 82 irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
83 u32 v; 83 u32 v;
84 /* 84 /*
85 * If we get both connect and disconnect interrupts at the same 85 * If we get both connect and disconnect interrupts at the same
86 * time, turn off the PHY, clear interrupts, and restart, which 86 * time, turn off the PHY, clear interrupts, and restart, which
87 * raises connect interrupt if a cable is connected, or nothing 87 * raises connect interrupt if a cable is connected, or nothing
88 * if cable is not connected. 88 * if cable is not connected.
89 */ 89 */
90 90
91 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); 91 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF);
92 92
93 /* 93 /*
94 * We always get bogus CONNECT & DISCONNECT interrupts when 94 * We always get bogus CONNECT & DISCONNECT interrupts when
95 * setting the PHY to LDOON. To ignore those, we force the RXDET 95 * setting the PHY to LDOON. To ignore those, we force the RXDET
96 * line to 0 until the PHY power state has been changed. 96 * line to 0 until the PHY power state has been changed.
97 */ 97 */
98 v = hdmi_read_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL); 98 v = hdmi_read_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL);
99 v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */ 99 v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */
100 v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */ 100 v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */
101 hdmi_write_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v); 101 hdmi_write_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v);
102 102
103 hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT | 103 hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT |
104 HDMI_IRQ_LINK_DISCONNECT); 104 HDMI_IRQ_LINK_DISCONNECT);
105 105
106 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 106 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
107 107
108 REG_FLD_MOD(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15); 108 REG_FLD_MOD(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15);
109 109
110 } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { 110 } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
111 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON); 111 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON);
112 } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { 112 } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
113 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); 113 hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON);
114 } 114 }
115 115
116 return IRQ_HANDLED; 116 return IRQ_HANDLED;
117 } 117 }
118 118
119 static int hdmi_init_regulator(void) 119 static int hdmi_init_regulator(void)
120 { 120 {
121 int r; 121 int r;
122 struct regulator *reg; 122 struct regulator *reg;
123 123
124 if (hdmi.vdda_reg != NULL) 124 if (hdmi.vdda_reg != NULL)
125 return 0; 125 return 0;
126 126
127 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda"); 127 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda");
128 if (IS_ERR(reg)) { 128 if (IS_ERR(reg)) {
129 DSSERR("can't get VDDA regulator\n"); 129 DSSERR("can't get VDDA regulator\n");
130 return PTR_ERR(reg); 130 return PTR_ERR(reg);
131 } 131 }
132 132
133 if (regulator_can_change_voltage(reg)) { 133 if (regulator_can_change_voltage(reg)) {
134 r = regulator_set_voltage(reg, 1800000, 1800000); 134 r = regulator_set_voltage(reg, 1800000, 1800000);
135 if (r) { 135 if (r) {
136 devm_regulator_put(reg); 136 devm_regulator_put(reg);
137 DSSWARN("can't set the regulator voltage\n"); 137 DSSWARN("can't set the regulator voltage\n");
138 return r; 138 return r;
139 } 139 }
140 } 140 }
141 141
142 hdmi.vdda_reg = reg; 142 hdmi.vdda_reg = reg;
143 143
144 return 0; 144 return 0;
145 } 145 }
146 146
147 static int hdmi_pll_enable(struct pll_data *pll, struct hdmi_wp_data *wp, 147 static int hdmi_pll_enable(struct pll_data *pll, struct hdmi_wp_data *wp,
148 struct pll_params *p) 148 struct pll_params *p)
149 { 149 {
150 u16 r = 0; 150 u16 r = 0;
151 151
152 dss_ctrl_hdmi_pll_enable(true); 152 dss_ctrl_hdmi_pll_enable(true);
153 153
154 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); 154 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
155 if (r) 155 if (r)
156 return r; 156 return r;
157 157
158 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); 158 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
159 if (r) 159 if (r)
160 return r; 160 return r;
161 161
162 pll_sysreset(pll); 162 pll_sysreset(pll);
163 163
164 r = pll_wait_reset(pll); 164 r = pll_wait_reset(pll);
165 if (r) 165 if (r)
166 return r; 166 return r;
167 167
168 r = pll_calc_and_check_clock_rates(pll, p); 168 r = pll_calc_and_check_clock_rates(pll, p);
169 if (r) 169 if (r)
170 return r; 170 return r;
171 171
172 r = pll_set_clock_div(pll, p); 172 r = pll_set_clock_div(pll, p);
173 if (r) 173 if (r)
174 return r; 174 return r;
175 175
176 return 0; 176 return 0;
177 } 177 }
178 178
179 static void hdmi_pll_disable(struct hdmi_wp_data *wp) 179 static void hdmi_pll_disable(struct hdmi_wp_data *wp)
180 { 180 {
181 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); 181 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
182 182
183 dss_ctrl_hdmi_pll_enable(false); 183 dss_ctrl_hdmi_pll_enable(false);
184 } 184 }
185 185
186 static int hdmi_power_on_core(struct omap_dss_device *dssdev) 186 static int hdmi_power_on_core(struct omap_dss_device *dssdev)
187 { 187 {
188 int r; 188 int r;
189 189
190 r = regulator_enable(hdmi.vdda_reg); 190 r = regulator_enable(hdmi.vdda_reg);
191 if (r) 191 if (r)
192 return r; 192 return r;
193 193
194 r = hdmi_runtime_get(); 194 r = hdmi_runtime_get();
195 if (r) 195 if (r)
196 goto err_runtime_get; 196 goto err_runtime_get;
197 197
198 /* Make selection of HDMI in DSS */ 198 /* Make selection of HDMI in DSS */
199 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); 199 dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
200 200
201 hdmi.core_enabled = true; 201 hdmi.core_enabled = true;
202 202
203 return 0; 203 return 0;
204 204
205 err_runtime_get: 205 err_runtime_get:
206 regulator_disable(hdmi.vdda_reg); 206 regulator_disable(hdmi.vdda_reg);
207 207
208 return r; 208 return r;
209 } 209 }
210 210
211 static void hdmi_power_off_core(struct omap_dss_device *dssdev) 211 static void hdmi_power_off_core(struct omap_dss_device *dssdev)
212 { 212 {
213 hdmi.core_enabled = false; 213 hdmi.core_enabled = false;
214 214
215 hdmi_runtime_put(); 215 hdmi_runtime_put();
216 regulator_disable(hdmi.vdda_reg); 216 regulator_disable(hdmi.vdda_reg);
217 } 217 }
218 218
219 static int hdmi_power_on_full(struct omap_dss_device *dssdev) 219 static int hdmi_power_on_full(struct omap_dss_device *dssdev)
220 { 220 {
221 int r; 221 int r;
222 struct omap_video_timings *p; 222 struct omap_video_timings *p;
223 struct omap_overlay_manager *mgr = hdmi.output.manager; 223 struct omap_overlay_manager *mgr = hdmi.output.manager;
224 unsigned long phy; 224 unsigned long phy;
225 struct pll_params param; 225 struct pll_params param;
226 bool ok; 226 bool ok;
227 227
228 r = hdmi_power_on_core(dssdev); 228 r = hdmi_power_on_core(dssdev);
229 if (r) 229 if (r)
230 return r; 230 return r;
231 231
232 p = &hdmi.cfg.timings; 232 p = &hdmi.cfg.timings;
233 233
234 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); 234 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
235 235
236 phy = p->pixelclock * 10; 236 phy = p->pixelclock * 10;
237 237
238 memset(&param, 0, sizeof(param)); 238 memset(&param, 0, sizeof(param));
239 239
240 ok = pll_calc(hdmi.pll, phy, phy, NULL, &param); 240 ok = pll_calc(hdmi.pll, phy, phy, NULL, &param);
241 if (!ok) { 241 if (!ok) {
242 DSSDBG("Failed to calculate PLL settings\n"); 242 DSSDBG("Failed to calculate PLL settings\n");
243 goto err_pll_enable; 243 goto err_pll_enable;
244 } 244 }
245 245
246 /* disable and clear irqs */ 246 /* disable and clear irqs */
247 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); 247 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
248 hdmi_wp_set_irqstatus(&hdmi.wp, 248 hdmi_wp_set_irqstatus(&hdmi.wp,
249 hdmi_wp_get_irqstatus(&hdmi.wp)); 249 hdmi_wp_get_irqstatus(&hdmi.wp));
250 250
251 /* config the PLL and PHY hdmi_set_pll_pwrfirst */ 251 /* config the PLL and PHY hdmi_set_pll_pwrfirst */
252 r = hdmi_pll_enable(hdmi.pll, &hdmi.wp, &param); 252 r = hdmi_pll_enable(hdmi.pll, &hdmi.wp, &param);
253 if (r) { 253 if (r) {
254 DSSDBG("Failed to lock PLL\n"); 254 DSSDBG("Failed to lock PLL\n");
255 goto err_pll_enable; 255 goto err_pll_enable;
256 } 256 }
257 257
258 r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg); 258 r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg);
259 if (r) { 259 if (r) {
260 DSSDBG("Failed to start PHY\n"); 260 DSSDBG("Failed to start PHY\n");
261 goto err_phy_cfg; 261 goto err_phy_cfg;
262 } 262 }
263 263
264 r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON); 264 r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON);
265 if (r) 265 if (r)
266 goto err_phy_pwr; 266 goto err_phy_pwr;
267 267
268 hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); 268 hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg);
269 269
270 /* bypass TV gamma table */ 270 /* bypass TV gamma table */
271 dispc_enable_gamma_table(0); 271 dispc_enable_gamma_table(0);
272 272
273 /* tv size */ 273 /* tv size */
274 dss_mgr_set_timings(mgr, p); 274 dss_mgr_set_timings(mgr, p);
275 275
276 r = dss_mgr_enable(mgr); 276 r = dss_mgr_enable(mgr);
277 if (r) 277 if (r)
278 goto err_mgr_enable; 278 goto err_mgr_enable;
279 279
280 r = hdmi_wp_video_start(&hdmi.wp); 280 r = hdmi_wp_video_start(&hdmi.wp);
281 if (r) 281 if (r)
282 goto err_vid_enable; 282 goto err_vid_enable;
283 283
284 hdmi_wp_set_irqenable(&hdmi.wp, 284 hdmi_wp_set_irqenable(&hdmi.wp,
285 HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); 285 HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
286 286
287 return 0; 287 return 0;
288 288
289 err_vid_enable: 289 err_vid_enable:
290 dss_mgr_disable(mgr); 290 dss_mgr_disable(mgr);
291 err_mgr_enable: 291 err_mgr_enable:
292 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 292 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
293 err_phy_pwr: 293 err_phy_pwr:
294 err_phy_cfg: 294 err_phy_cfg:
295 hdmi_pll_disable(&hdmi.wp); 295 hdmi_pll_disable(&hdmi.wp);
296 err_pll_enable: 296 err_pll_enable:
297 hdmi_power_off_core(dssdev); 297 hdmi_power_off_core(dssdev);
298 return -EIO; 298 return -EIO;
299 } 299 }
300 300
301 static void hdmi_power_off_full(struct omap_dss_device *dssdev) 301 static void hdmi_power_off_full(struct omap_dss_device *dssdev)
302 { 302 {
303 struct omap_overlay_manager *mgr = hdmi.output.manager; 303 struct omap_overlay_manager *mgr = hdmi.output.manager;
304 304
305 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); 305 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
306 306
307 hdmi_wp_video_stop(&hdmi.wp); 307 hdmi_wp_video_stop(&hdmi.wp);
308 308
309 dss_mgr_disable(mgr); 309 dss_mgr_disable(mgr);
310 310
311 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 311 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
312 312
313 hdmi_pll_disable(&hdmi.wp); 313 hdmi_pll_disable(&hdmi.wp);
314 314
315 hdmi_power_off_core(dssdev); 315 hdmi_power_off_core(dssdev);
316 } 316 }
317 317
318 static int hdmi_display_check_timing(struct omap_dss_device *dssdev, 318 static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
319 struct omap_video_timings *timings) 319 struct omap_video_timings *timings)
320 { 320 {
321 struct omap_dss_device *out = &hdmi.output; 321 struct omap_dss_device *out = &hdmi.output;
322 322
323 if (!dispc_mgr_timings_ok(out->dispc_channel, timings)) 323 if (!dispc_mgr_timings_ok(out->dispc_channel, timings))
324 return -EINVAL; 324 return -EINVAL;
325 325
326 return 0; 326 return 0;
327 } 327 }
328 328
329 static void hdmi_display_set_timing(struct omap_dss_device *dssdev, 329 static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
330 struct omap_video_timings *timings) 330 struct omap_video_timings *timings)
331 { 331 {
332 mutex_lock(&hdmi.lock); 332 mutex_lock(&hdmi.lock);
333 333
334 hdmi.cfg.timings = *timings; 334 hdmi.cfg.timings = *timings;
335 335
336 dispc_set_tv_pclk(timings->pixelclock); 336 dispc_set_tv_pclk(timings->pixelclock);
337 337
338 mutex_unlock(&hdmi.lock); 338 mutex_unlock(&hdmi.lock);
339 } 339 }
340 340
341 static void hdmi_display_get_timings(struct omap_dss_device *dssdev, 341 static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
342 struct omap_video_timings *timings) 342 struct omap_video_timings *timings)
343 { 343 {
344 *timings = hdmi.cfg.timings; 344 *timings = hdmi.cfg.timings;
345 } 345 }
346 346
347 static void hdmi_dump_regs(struct seq_file *s) 347 static void hdmi_dump_regs(struct seq_file *s)
348 { 348 {
349 mutex_lock(&hdmi.lock); 349 mutex_lock(&hdmi.lock);
350 350
351 if (hdmi_runtime_get()) { 351 if (hdmi_runtime_get()) {
352 mutex_unlock(&hdmi.lock); 352 mutex_unlock(&hdmi.lock);
353 return; 353 return;
354 } 354 }
355 355
356 hdmi_wp_dump(&hdmi.wp, s); 356 hdmi_wp_dump(&hdmi.wp, s);
357 pll_dump(hdmi.pll, s); 357 pll_dump(hdmi.pll, s);
358 hdmi_phy_dump(&hdmi.phy, s); 358 hdmi_phy_dump(&hdmi.phy, s);
359 hdmi5_core_dump(&hdmi.core, s); 359 hdmi5_core_dump(&hdmi.core, s);
360 360
361 hdmi_runtime_put(); 361 hdmi_runtime_put();
362 mutex_unlock(&hdmi.lock); 362 mutex_unlock(&hdmi.lock);
363 } 363 }
364 364
365 static int read_edid(u8 *buf, int len) 365 static int read_edid(u8 *buf, int len)
366 { 366 {
367 int r; 367 int r;
368 int idlemode; 368 int idlemode;
369 369
370 mutex_lock(&hdmi.lock); 370 mutex_lock(&hdmi.lock);
371 371
372 r = hdmi_runtime_get(); 372 r = hdmi_runtime_get();
373 BUG_ON(r); 373 BUG_ON(r);
374 374
375 idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2); 375 idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2);
376 /* No-idle mode */ 376 /* No-idle mode */
377 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2); 377 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
378 378
379 r = hdmi5_read_edid(&hdmi.core, buf, len); 379 r = hdmi5_read_edid(&hdmi.core, buf, len);
380 380
381 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2); 381 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2);
382 382
383 hdmi_runtime_put(); 383 hdmi_runtime_put();
384 mutex_unlock(&hdmi.lock); 384 mutex_unlock(&hdmi.lock);
385 385
386 return r; 386 return r;
387 } 387 }
388 388
389 static int hdmi_display_enable(struct omap_dss_device *dssdev) 389 static int hdmi_display_enable(struct omap_dss_device *dssdev)
390 { 390 {
391 struct omap_dss_device *out = &hdmi.output; 391 struct omap_dss_device *out = &hdmi.output;
392 int r = 0; 392 int r = 0;
393 393
394 DSSDBG("ENTER hdmi_display_enable\n"); 394 DSSDBG("ENTER hdmi_display_enable\n");
395 395
396 mutex_lock(&hdmi.lock); 396 mutex_lock(&hdmi.lock);
397 397
398 if (out == NULL || out->manager == NULL) { 398 if (out == NULL || out->manager == NULL) {
399 DSSERR("failed to enable display: no output/manager\n"); 399 DSSERR("failed to enable display: no output/manager\n");
400 r = -ENODEV; 400 r = -ENODEV;
401 goto err0; 401 goto err0;
402 } 402 }
403 403
404 r = hdmi_power_on_full(dssdev); 404 r = hdmi_power_on_full(dssdev);
405 if (r) { 405 if (r) {
406 DSSERR("failed to power on device\n"); 406 DSSERR("failed to power on device\n");
407 goto err0; 407 goto err0;
408 } 408 }
409 409
410 hdmi.display_enabled = true; 410 hdmi.display_enabled = true;
411 411
412 mutex_unlock(&hdmi.lock); 412 mutex_unlock(&hdmi.lock);
413 return 0; 413 return 0;
414 414
415 err0: 415 err0:
416 mutex_unlock(&hdmi.lock); 416 mutex_unlock(&hdmi.lock);
417 return r; 417 return r;
418 } 418 }
419 419
420 static void hdmi_display_disable(struct omap_dss_device *dssdev) 420 static void hdmi_display_disable(struct omap_dss_device *dssdev)
421 { 421 {
422 DSSDBG("Enter hdmi_display_disable\n"); 422 DSSDBG("Enter hdmi_display_disable\n");
423 423
424 mutex_lock(&hdmi.lock); 424 mutex_lock(&hdmi.lock);
425 425
426 if (hdmi.audio_abort_cb) 426 /* If set hdmi.audio_abort_cb(&hdmi.pdev->dev) should be
427 hdmi.audio_abort_cb(&hdmi.pdev->dev); 427 * called here, if audio abort functionality is needed. */
428 428
429 hdmi_power_off_full(dssdev); 429 hdmi_power_off_full(dssdev);
430 430
431 hdmi.display_enabled = false; 431 hdmi.display_enabled = false;
432 432
433 mutex_unlock(&hdmi.lock); 433 mutex_unlock(&hdmi.lock);
434 } 434 }
435 435
436 static int hdmi_core_enable(struct omap_dss_device *dssdev) 436 static int hdmi_core_enable(struct omap_dss_device *dssdev)
437 { 437 {
438 int r = 0; 438 int r = 0;
439 439
440 DSSDBG("ENTER omapdss_hdmi_core_enable\n"); 440 DSSDBG("ENTER omapdss_hdmi_core_enable\n");
441 441
442 mutex_lock(&hdmi.lock); 442 mutex_lock(&hdmi.lock);
443 443
444 r = hdmi_power_on_core(dssdev); 444 r = hdmi_power_on_core(dssdev);
445 if (r) { 445 if (r) {
446 DSSERR("failed to power on device\n"); 446 DSSERR("failed to power on device\n");
447 goto err0; 447 goto err0;
448 } 448 }
449 449
450 mutex_unlock(&hdmi.lock); 450 mutex_unlock(&hdmi.lock);
451 return 0; 451 return 0;
452 452
453 err0: 453 err0:
454 mutex_unlock(&hdmi.lock); 454 mutex_unlock(&hdmi.lock);
455 return r; 455 return r;
456 } 456 }
457 457
458 static void hdmi_core_disable(struct omap_dss_device *dssdev) 458 static void hdmi_core_disable(struct omap_dss_device *dssdev)
459 { 459 {
460 DSSDBG("Enter omapdss_hdmi_core_disable\n"); 460 DSSDBG("Enter omapdss_hdmi_core_disable\n");
461 461
462 mutex_lock(&hdmi.lock); 462 mutex_lock(&hdmi.lock);
463 463
464 hdmi_power_off_core(dssdev); 464 hdmi_power_off_core(dssdev);
465 465
466 mutex_unlock(&hdmi.lock); 466 mutex_unlock(&hdmi.lock);
467 } 467 }
468 468
469 static int hdmi_connect(struct omap_dss_device *dssdev, 469 static int hdmi_connect(struct omap_dss_device *dssdev,
470 struct omap_dss_device *dst) 470 struct omap_dss_device *dst)
471 { 471 {
472 struct omap_overlay_manager *mgr; 472 struct omap_overlay_manager *mgr;
473 int r; 473 int r;
474 474
475 r = hdmi_init_regulator(); 475 r = hdmi_init_regulator();
476 if (r) 476 if (r)
477 return r; 477 return r;
478 478
479 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel); 479 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
480 if (!mgr) 480 if (!mgr)
481 return -ENODEV; 481 return -ENODEV;
482 482
483 r = dss_mgr_connect(mgr, dssdev); 483 r = dss_mgr_connect(mgr, dssdev);
484 if (r) 484 if (r)
485 return r; 485 return r;
486 486
487 r = omapdss_output_set_device(dssdev, dst); 487 r = omapdss_output_set_device(dssdev, dst);
488 if (r) { 488 if (r) {
489 DSSERR("failed to connect output to new device: %s\n", 489 DSSERR("failed to connect output to new device: %s\n",
490 dst->name); 490 dst->name);
491 dss_mgr_disconnect(mgr, dssdev); 491 dss_mgr_disconnect(mgr, dssdev);
492 return r; 492 return r;
493 } 493 }
494 494
495 return 0; 495 return 0;
496 } 496 }
497 497
498 static void hdmi_disconnect(struct omap_dss_device *dssdev, 498 static void hdmi_disconnect(struct omap_dss_device *dssdev,
499 struct omap_dss_device *dst) 499 struct omap_dss_device *dst)
500 { 500 {
501 WARN_ON(dst != dssdev->dst); 501 WARN_ON(dst != dssdev->dst);
502 502
503 if (dst != dssdev->dst) 503 if (dst != dssdev->dst)
504 return; 504 return;
505 505
506 omapdss_output_unset_device(dssdev); 506 omapdss_output_unset_device(dssdev);
507 507
508 if (dssdev->manager) 508 if (dssdev->manager)
509 dss_mgr_disconnect(dssdev->manager, dssdev); 509 dss_mgr_disconnect(dssdev->manager, dssdev);
510 } 510 }
511 511
512 static int hdmi_read_edid(struct omap_dss_device *dssdev, 512 static int hdmi_read_edid(struct omap_dss_device *dssdev,
513 u8 *edid, int len) 513 u8 *edid, int len)
514 { 514 {
515 bool need_enable; 515 bool need_enable;
516 int r; 516 int r;
517 517
518 need_enable = hdmi.core_enabled == false; 518 need_enable = hdmi.core_enabled == false;
519 519
520 if (need_enable) { 520 if (need_enable) {
521 r = hdmi_core_enable(dssdev); 521 r = hdmi_core_enable(dssdev);
522 if (r) 522 if (r)
523 return r; 523 return r;
524 } 524 }
525 525
526 r = read_edid(edid, len); 526 r = read_edid(edid, len);
527 527
528 if (need_enable) 528 if (need_enable)
529 hdmi_core_disable(dssdev); 529 hdmi_core_disable(dssdev);
530 530
531 return r; 531 return r;
532 } 532 }
533 533
534 static int hdmi_set_infoframe(struct omap_dss_device *dssdev, 534 static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
535 const struct hdmi_avi_infoframe *avi) 535 const struct hdmi_avi_infoframe *avi)
536 { 536 {
537 hdmi.cfg.infoframe = *avi; 537 hdmi.cfg.infoframe = *avi;
538 return 0; 538 return 0;
539 } 539 }
540 540
541 static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev, 541 static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
542 bool hdmi_mode) 542 bool hdmi_mode)
543 { 543 {
544 hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI; 544 hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
545 return 0; 545 return 0;
546 } 546 }
547 547
548 static const struct omapdss_hdmi_ops hdmi_ops = { 548 static const struct omapdss_hdmi_ops hdmi_ops = {
549 .connect = hdmi_connect, 549 .connect = hdmi_connect,
550 .disconnect = hdmi_disconnect, 550 .disconnect = hdmi_disconnect,
551 551
552 .enable = hdmi_display_enable, 552 .enable = hdmi_display_enable,
553 .disable = hdmi_display_disable, 553 .disable = hdmi_display_disable,
554 554
555 .check_timings = hdmi_display_check_timing, 555 .check_timings = hdmi_display_check_timing,
556 .set_timings = hdmi_display_set_timing, 556 .set_timings = hdmi_display_set_timing,
557 .get_timings = hdmi_display_get_timings, 557 .get_timings = hdmi_display_get_timings,
558 558
559 .read_edid = hdmi_read_edid, 559 .read_edid = hdmi_read_edid,
560 .set_infoframe = hdmi_set_infoframe, 560 .set_infoframe = hdmi_set_infoframe,
561 .set_hdmi_mode = hdmi_set_hdmi_mode, 561 .set_hdmi_mode = hdmi_set_hdmi_mode,
562 }; 562 };
563 563
564 static void hdmi_init_output(struct platform_device *pdev) 564 static void hdmi_init_output(struct platform_device *pdev)
565 { 565 {
566 struct omap_dss_device *out = &hdmi.output; 566 struct omap_dss_device *out = &hdmi.output;
567 567
568 out->dev = &pdev->dev; 568 out->dev = &pdev->dev;
569 out->id = OMAP_DSS_OUTPUT_HDMI; 569 out->id = OMAP_DSS_OUTPUT_HDMI;
570 out->output_type = OMAP_DISPLAY_TYPE_HDMI; 570 out->output_type = OMAP_DISPLAY_TYPE_HDMI;
571 out->name = "hdmi.0"; 571 out->name = "hdmi.0";
572 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; 572 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
573 out->ops.hdmi = &hdmi_ops; 573 out->ops.hdmi = &hdmi_ops;
574 out->owner = THIS_MODULE; 574 out->owner = THIS_MODULE;
575 575
576 omapdss_register_output(out); 576 omapdss_register_output(out);
577 } 577 }
578 578
579 static void __exit hdmi_uninit_output(struct platform_device *pdev) 579 static void __exit hdmi_uninit_output(struct platform_device *pdev)
580 { 580 {
581 struct omap_dss_device *out = &hdmi.output; 581 struct omap_dss_device *out = &hdmi.output;
582 582
583 omapdss_unregister_output(out); 583 omapdss_unregister_output(out);
584 } 584 }
585 585
586 static int hdmi_probe_of(struct platform_device *pdev) 586 static int hdmi_probe_of(struct platform_device *pdev)
587 { 587 {
588 struct device_node *node = pdev->dev.of_node; 588 struct device_node *node = pdev->dev.of_node;
589 struct device_node *ep; 589 struct device_node *ep;
590 int r; 590 int r;
591 591
592 ep = omapdss_of_get_first_endpoint(node); 592 ep = omapdss_of_get_first_endpoint(node);
593 if (!ep) 593 if (!ep)
594 return 0; 594 return 0;
595 595
596 r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy); 596 r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy);
597 if (r) 597 if (r)
598 goto err; 598 goto err;
599 599
600 of_node_put(ep); 600 of_node_put(ep);
601 return 0; 601 return 0;
602 602
603 err: 603 err:
604 of_node_put(ep); 604 of_node_put(ep);
605 return r; 605 return r;
606 } 606 }
607 607
608 #if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) 608 #if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
609 static int audio_startup(struct device *dev, 609 static int audio_startup(struct device *dev,
610 void (*abort_cb)(struct device *dev)) 610 void (*abort_cb)(struct device *dev))
611 { 611 {
612 struct omap_hdmi *hd = dev_get_drvdata(dev); 612 struct omap_hdmi *hd = dev_get_drvdata(dev);
613 int ret = 0; 613 int ret = 0;
614 614
615 mutex_lock(&hd->lock); 615 mutex_lock(&hd->lock);
616 616
617 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) { 617 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
618 ret = -EPERM; 618 ret = -EPERM;
619 goto out; 619 goto out;
620 } 620 }
621 621
622 hd->audio_abort_cb = abort_cb; 622 hd->audio_abort_cb = abort_cb;
623 623
624 out: 624 out:
625 mutex_unlock(&hd->lock); 625 mutex_unlock(&hd->lock);
626 626
627 return ret; 627 return ret;
628 } 628 }
629 629
630 static int audio_enable(struct device *dev, bool enable) 630 static int audio_enable(struct device *dev, bool enable)
631 { 631 {
632 struct omap_hdmi *hd = dev_get_drvdata(dev); 632 struct omap_hdmi *hd = dev_get_drvdata(dev);
633 int ret; 633 int ret;
634 634
635 mutex_lock(&hd->lock); 635 mutex_lock(&hd->lock);
636 636
637 if (enable) { 637 if (enable) {
638 /* No idle while playing audio */ 638 /* No idle while playing audio */
639 hd->wp_idlemode = 639 hd->wp_idlemode =
640 REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2); 640 REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2);
641 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2); 641 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
642 } 642 }
643 643
644 ret = hdmi_wp_audio_enable(&hd->wp, enable); 644 ret = hdmi_wp_audio_enable(&hd->wp, enable);
645 645
646 if (!enable) { 646 if (!enable) {
647 /* Playback stopped, restore original idlemode */ 647 /* Playback stopped, restore original idlemode */
648 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode, 648 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode,
649 3, 2); 649 3, 2);
650 650
651 hd->audio_abort_cb = NULL; 651 hd->audio_abort_cb = NULL;
652 } 652 }
653 653
654 mutex_unlock(&hd->lock); 654 mutex_unlock(&hd->lock);
655 655
656 return ret; 656 return ret;
657 } 657 }
658 658
659 static int audio_start(struct device *dev, bool enable) 659 static int audio_start(struct device *dev, bool enable)
660 { 660 {
661 struct omap_hdmi *hd = dev_get_drvdata(dev); 661 struct omap_hdmi *hd = dev_get_drvdata(dev);
662 662
663 return hdmi_wp_audio_core_req_enable(&hd->wp, enable); 663 return hdmi_wp_audio_core_req_enable(&hd->wp, enable);
664 } 664 }
665 665
666 static int audio_config(struct device *dev, struct omap_dss_audio *dss_audio) 666 static int audio_config(struct device *dev, struct omap_dss_audio *dss_audio)
667 { 667 {
668 struct omap_hdmi *hd = dev_get_drvdata(dev); 668 struct omap_hdmi *hd = dev_get_drvdata(dev);
669 int ret; 669 int ret;
670 670
671 mutex_lock(&hd->lock); 671 mutex_lock(&hd->lock);
672 if (!hdmi_mode_has_audio(&hd->cfg)) 672 if (!hdmi_mode_has_audio(&hd->cfg))
673 ret = -EPERM; 673 ret = -EPERM;
674 else 674 else
675 ret = hdmi5_audio_config(&hd->core, &hd->wp, dss_audio, 675 ret = hdmi5_audio_config(&hd->core, &hd->wp, dss_audio,
676 hd->cfg.timings.pixelclock); 676 hd->cfg.timings.pixelclock);
677 mutex_unlock(&hd->lock); 677 mutex_unlock(&hd->lock);
678 678
679 return ret; 679 return ret;
680 } 680 }
681 681
682 static int hdmi_audio_register(struct device *dev) 682 static int hdmi_audio_register(struct device *dev)
683 { 683 {
684 struct omap_hdmi_audio ha = { 684 struct omap_hdmi_audio ha = {
685 .dev = dev, 685 .dev = dev,
686 .hw_version = OMAP5_HDMI, 686 .hw_version = OMAP5_HDMI,
687 .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp), 687 .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
688 .audio_startup = audio_startup, 688 .audio_startup = audio_startup,
689 .audio_enable = audio_enable, 689 .audio_enable = audio_enable,
690 .audio_start = audio_start, 690 .audio_start = audio_start,
691 .audio_config = audio_config, 691 .audio_config = audio_config,
692 }; 692 };
693 693
694 return omap_hdmi_audio_register(&ha); 694 return omap_hdmi_audio_register(&ha);
695 } 695 }
696 #else /* CONFIG_OMAP5_DSS_HDMI_AUDIO */ 696 #else /* CONFIG_OMAP5_DSS_HDMI_AUDIO */
697 static int hdmi_audio_register(struct device *dev) 697 static int hdmi_audio_register(struct device *dev)
698 { 698 {
699 return 0; 699 return 0;
700 } 700 }
701 #endif 701 #endif
702 702
703 /* HDMI HW IP initialisation */ 703 /* HDMI HW IP initialisation */
704 static int omapdss_hdmihw_probe(struct platform_device *pdev) 704 static int omapdss_hdmihw_probe(struct platform_device *pdev)
705 { 705 {
706 int r; 706 int r;
707 int irq; 707 int irq;
708 708
709 hdmi.pdev = pdev; 709 hdmi.pdev = pdev;
710 dev_set_drvdata(&pdev->dev, &hdmi); 710 dev_set_drvdata(&pdev->dev, &hdmi);
711 711
712 mutex_init(&hdmi.lock); 712 mutex_init(&hdmi.lock);
713 713
714 if (pdev->dev.of_node) { 714 if (pdev->dev.of_node) {
715 r = hdmi_probe_of(pdev); 715 r = hdmi_probe_of(pdev);
716 if (r) 716 if (r)
717 return r; 717 return r;
718 } 718 }
719 719
720 r = hdmi_wp_init(pdev, &hdmi.wp); 720 r = hdmi_wp_init(pdev, &hdmi.wp);
721 if (r) 721 if (r)
722 return r; 722 return r;
723 723
724 hdmi.pll = pll_create(pdev, "pll", "sys_clk", DSS_PLL_TYPE_HDMI, 724 hdmi.pll = pll_create(pdev, "pll", "sys_clk", DSS_PLL_TYPE_HDMI,
725 NULL, 0); 725 NULL, 0);
726 if (!hdmi.pll) 726 if (!hdmi.pll)
727 return -ENODEV; 727 return -ENODEV;
728 728
729 r = hdmi_phy_init(pdev, &hdmi.phy); 729 r = hdmi_phy_init(pdev, &hdmi.phy);
730 if (r) 730 if (r)
731 return r; 731 return r;
732 732
733 r = hdmi5_core_init(pdev, &hdmi.core); 733 r = hdmi5_core_init(pdev, &hdmi.core);
734 if (r) 734 if (r)
735 return r; 735 return r;
736 736
737 irq = platform_get_irq(pdev, 0); 737 irq = platform_get_irq(pdev, 0);
738 if (irq < 0) { 738 if (irq < 0) {
739 DSSERR("platform_get_irq failed\n"); 739 DSSERR("platform_get_irq failed\n");
740 return -ENODEV; 740 return -ENODEV;
741 } 741 }
742 742
743 r = devm_request_threaded_irq(&pdev->dev, irq, 743 r = devm_request_threaded_irq(&pdev->dev, irq,
744 NULL, hdmi_irq_handler, 744 NULL, hdmi_irq_handler,
745 IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); 745 IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp);
746 if (r) { 746 if (r) {
747 DSSERR("HDMI IRQ request failed\n"); 747 DSSERR("HDMI IRQ request failed\n");
748 return r; 748 return r;
749 } 749 }
750 750
751 pm_runtime_enable(&pdev->dev); 751 pm_runtime_enable(&pdev->dev);
752 752
753 hdmi_init_output(pdev); 753 hdmi_init_output(pdev);
754 754
755 r = hdmi_audio_register(&pdev->dev); 755 r = hdmi_audio_register(&pdev->dev);
756 if (r) { 756 if (r) {
757 DSSERR("Registering HDMI audio failed\n"); 757 DSSERR("Registering HDMI audio failed\n");
758 hdmi_uninit_output(pdev); 758 hdmi_uninit_output(pdev);
759 pm_runtime_disable(&pdev->dev); 759 pm_runtime_disable(&pdev->dev);
760 return r; 760 return r;
761 } 761 }
762 762
763 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 763 dss_debugfs_create_file("hdmi", hdmi_dump_regs);
764 764
765 return 0; 765 return 0;
766 } 766 }
767 767
768 static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) 768 static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
769 { 769 {
770 omap_hdmi_audio_unregister(&pdev->dev); 770 omap_hdmi_audio_unregister(&pdev->dev);
771 771
772 hdmi_uninit_output(pdev); 772 hdmi_uninit_output(pdev);
773 773
774 pm_runtime_disable(&pdev->dev); 774 pm_runtime_disable(&pdev->dev);
775 775
776 return 0; 776 return 0;
777 } 777 }
778 778
779 static int hdmi_runtime_suspend(struct device *dev) 779 static int hdmi_runtime_suspend(struct device *dev)
780 { 780 {
781 pll_enable_clock(hdmi.pll, false); 781 pll_enable_clock(hdmi.pll, false);
782 782
783 dispc_runtime_put(); 783 dispc_runtime_put();
784 784
785 return 0; 785 return 0;
786 } 786 }
787 787
788 static int hdmi_runtime_resume(struct device *dev) 788 static int hdmi_runtime_resume(struct device *dev)
789 { 789 {
790 int r; 790 int r;
791 791
792 r = dispc_runtime_get(); 792 r = dispc_runtime_get();
793 if (r < 0) 793 if (r < 0)
794 return r; 794 return r;
795 795
796 pll_enable_clock(hdmi.pll, true); 796 pll_enable_clock(hdmi.pll, true);
797 797
798 return 0; 798 return 0;
799 } 799 }
800 800
801 static const struct dev_pm_ops hdmi_pm_ops = { 801 static const struct dev_pm_ops hdmi_pm_ops = {
802 .runtime_suspend = hdmi_runtime_suspend, 802 .runtime_suspend = hdmi_runtime_suspend,
803 .runtime_resume = hdmi_runtime_resume, 803 .runtime_resume = hdmi_runtime_resume,
804 }; 804 };
805 805
806 static const struct of_device_id hdmi_of_match[] = { 806 static const struct of_device_id hdmi_of_match[] = {
807 { .compatible = "ti,omap5-hdmi", }, 807 { .compatible = "ti,omap5-hdmi", },
808 { .compatible = "ti,dra7-hdmi", }, 808 { .compatible = "ti,dra7-hdmi", },
809 {}, 809 {},
810 }; 810 };
811 811
812 static struct platform_driver omapdss_hdmihw_driver = { 812 static struct platform_driver omapdss_hdmihw_driver = {
813 .probe = omapdss_hdmihw_probe, 813 .probe = omapdss_hdmihw_probe,
814 .remove = __exit_p(omapdss_hdmihw_remove), 814 .remove = __exit_p(omapdss_hdmihw_remove),
815 .driver = { 815 .driver = {
816 .name = "omapdss_hdmi5", 816 .name = "omapdss_hdmi5",
817 .owner = THIS_MODULE, 817 .owner = THIS_MODULE,
818 .pm = &hdmi_pm_ops, 818 .pm = &hdmi_pm_ops,
819 .of_match_table = hdmi_of_match, 819 .of_match_table = hdmi_of_match,
820 }, 820 },
821 }; 821 };
822 822
823 int __init hdmi5_init_platform_driver(void) 823 int __init hdmi5_init_platform_driver(void)
824 { 824 {
825 return platform_driver_register(&omapdss_hdmihw_driver); 825 return platform_driver_register(&omapdss_hdmihw_driver);
826 } 826 }
827 827
828 void __exit hdmi5_uninit_platform_driver(void) 828 void __exit hdmi5_uninit_platform_driver(void)
829 { 829 {
830 platform_driver_unregister(&omapdss_hdmihw_driver); 830 platform_driver_unregister(&omapdss_hdmihw_driver);
831 } 831 }
832 832