diff options
-rw-r--r-- | drivers/video/omap2/dss/Makefile | 3 | ||||
-rw-r--r-- | drivers/video/omap2/dss/dss_features.c | 3 | ||||
-rw-r--r-- | drivers/video/omap2/dss/hdmi.c | 19 | ||||
-rw-r--r-- | drivers/video/omap2/dss/hdmi_phy.c | 194 | ||||
-rw-r--r-- | drivers/video/omap2/dss/ti_hdmi.h | 26 | ||||
-rw-r--r-- | drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | 109 |
6 files changed, 219 insertions, 135 deletions
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile index 5ea65d327cfb..d88e93870e15 100644 --- a/drivers/video/omap2/dss/Makefile +++ b/drivers/video/omap2/dss/Makefile | |||
@@ -10,5 +10,6 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o | |||
10 | omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o | 10 | omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o |
11 | omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o | 11 | omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o |
12 | omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o | 12 | omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o |
13 | omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o hdmi_wp.o hdmi_pll.o ti_hdmi_4xxx_ip.o | 13 | omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o hdmi_wp.o hdmi_pll.o hdmi_phy.o \ |
14 | ti_hdmi_4xxx_ip.o | ||
14 | ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG | 15 | ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG |
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index 9ee92e90caff..2777eb6d603b 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c | |||
@@ -794,11 +794,8 @@ static const struct omap_dss_features omap5_dss_features = { | |||
794 | static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { | 794 | static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { |
795 | 795 | ||
796 | .video_configure = ti_hdmi_4xxx_basic_configure, | 796 | .video_configure = ti_hdmi_4xxx_basic_configure, |
797 | .phy_enable = ti_hdmi_4xxx_phy_enable, | ||
798 | .phy_disable = ti_hdmi_4xxx_phy_disable, | ||
799 | .read_edid = ti_hdmi_4xxx_read_edid, | 797 | .read_edid = ti_hdmi_4xxx_read_edid, |
800 | .dump_core = ti_hdmi_4xxx_core_dump, | 798 | .dump_core = ti_hdmi_4xxx_core_dump, |
801 | .dump_phy = ti_hdmi_4xxx_phy_dump, | ||
802 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | 799 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) |
803 | .audio_start = ti_hdmi_4xxx_audio_start, | 800 | .audio_start = ti_hdmi_4xxx_audio_start, |
804 | .audio_stop = ti_hdmi_4xxx_audio_stop, | 801 | .audio_stop = ti_hdmi_4xxx_audio_stop, |
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index f6a2eba244e7..f7e2ac6861b6 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c | |||
@@ -42,7 +42,6 @@ | |||
42 | 42 | ||
43 | #define HDMI_CORE_SYS 0x400 | 43 | #define HDMI_CORE_SYS 0x400 |
44 | #define HDMI_CORE_AV 0x900 | 44 | #define HDMI_CORE_AV 0x900 |
45 | #define HDMI_PHY 0x300 | ||
46 | 45 | ||
47 | /* HDMI EDID Length move this */ | 46 | /* HDMI EDID Length move this */ |
48 | #define HDMI_EDID_MAX_LENGTH 256 | 47 | #define HDMI_EDID_MAX_LENGTH 256 |
@@ -487,7 +486,8 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) | |||
487 | goto err_pll_enable; | 486 | goto err_pll_enable; |
488 | } | 487 | } |
489 | 488 | ||
490 | r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data); | 489 | r = hdmi_phy_enable(&hdmi.ip_data.phy, &hdmi.ip_data.wp, |
490 | &hdmi.ip_data.cfg); | ||
491 | if (r) { | 491 | if (r) { |
492 | DSSDBG("Failed to start PHY\n"); | 492 | DSSDBG("Failed to start PHY\n"); |
493 | goto err_phy_enable; | 493 | goto err_phy_enable; |
@@ -514,7 +514,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) | |||
514 | err_mgr_enable: | 514 | err_mgr_enable: |
515 | hdmi_wp_video_stop(&hdmi.ip_data.wp); | 515 | hdmi_wp_video_stop(&hdmi.ip_data.wp); |
516 | err_vid_enable: | 516 | err_vid_enable: |
517 | hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); | 517 | hdmi_phy_disable(&hdmi.ip_data.phy, &hdmi.ip_data.wp); |
518 | err_phy_enable: | 518 | err_phy_enable: |
519 | hdmi_pll_disable(&hdmi.ip_data.pll, &hdmi.ip_data.wp); | 519 | hdmi_pll_disable(&hdmi.ip_data.pll, &hdmi.ip_data.wp); |
520 | err_pll_enable: | 520 | err_pll_enable: |
@@ -529,7 +529,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev) | |||
529 | dss_mgr_disable(mgr); | 529 | dss_mgr_disable(mgr); |
530 | 530 | ||
531 | hdmi_wp_video_stop(&hdmi.ip_data.wp); | 531 | hdmi_wp_video_stop(&hdmi.ip_data.wp); |
532 | hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); | 532 | hdmi_phy_disable(&hdmi.ip_data.phy, &hdmi.ip_data.wp); |
533 | hdmi_pll_disable(&hdmi.ip_data.pll, &hdmi.ip_data.wp); | 533 | hdmi_pll_disable(&hdmi.ip_data.pll, &hdmi.ip_data.wp); |
534 | 534 | ||
535 | hdmi_power_off_core(dssdev); | 535 | hdmi_power_off_core(dssdev); |
@@ -593,7 +593,7 @@ static void hdmi_dump_regs(struct seq_file *s) | |||
593 | 593 | ||
594 | hdmi_wp_dump(&hdmi.ip_data.wp, s); | 594 | hdmi_wp_dump(&hdmi.ip_data.wp, s); |
595 | hdmi_pll_dump(&hdmi.ip_data.pll, s); | 595 | hdmi_pll_dump(&hdmi.ip_data.pll, s); |
596 | hdmi.ip_data.ops->dump_phy(&hdmi.ip_data, s); | 596 | hdmi_phy_dump(&hdmi.ip_data.phy, s); |
597 | hdmi.ip_data.ops->dump_core(&hdmi.ip_data, s); | 597 | hdmi.ip_data.ops->dump_core(&hdmi.ip_data, s); |
598 | 598 | ||
599 | hdmi_runtime_put(); | 599 | hdmi_runtime_put(); |
@@ -1049,11 +1049,9 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) | |||
1049 | if (r) | 1049 | if (r) |
1050 | return r; | 1050 | return r; |
1051 | 1051 | ||
1052 | hdmi.ip_data.irq = platform_get_irq(pdev, 0); | 1052 | r = hdmi_phy_init(pdev, &hdmi.ip_data.phy); |
1053 | if (hdmi.ip_data.irq < 0) { | 1053 | if (r) |
1054 | DSSERR("platform_get_irq failed\n"); | 1054 | return r; |
1055 | return -ENODEV; | ||
1056 | } | ||
1057 | 1055 | ||
1058 | r = hdmi_get_clocks(pdev); | 1056 | r = hdmi_get_clocks(pdev); |
1059 | if (r) { | 1057 | if (r) { |
@@ -1065,7 +1063,6 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) | |||
1065 | 1063 | ||
1066 | hdmi.ip_data.core_sys_offset = HDMI_CORE_SYS; | 1064 | hdmi.ip_data.core_sys_offset = HDMI_CORE_SYS; |
1067 | hdmi.ip_data.core_av_offset = HDMI_CORE_AV; | 1065 | hdmi.ip_data.core_av_offset = HDMI_CORE_AV; |
1068 | hdmi.ip_data.phy_offset = HDMI_PHY; | ||
1069 | 1066 | ||
1070 | hdmi_init_output(pdev); | 1067 | hdmi_init_output(pdev); |
1071 | 1068 | ||
diff --git a/drivers/video/omap2/dss/hdmi_phy.c b/drivers/video/omap2/dss/hdmi_phy.c new file mode 100644 index 000000000000..48bdba8d7031 --- /dev/null +++ b/drivers/video/omap2/dss/hdmi_phy.c | |||
@@ -0,0 +1,194 @@ | |||
1 | /* | ||
2 | * HDMI PHY | ||
3 | * | ||
4 | * Copyright (C) 2013 Texas Instruments Incorporated | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published by | ||
8 | * the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/delay.h> | ||
13 | #include <linux/err.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <video/omapdss.h> | ||
17 | |||
18 | #include "dss.h" | ||
19 | #include "ti_hdmi.h" | ||
20 | #include "ti_hdmi_4xxx_ip.h" | ||
21 | |||
22 | #define HDMI_IRQ_LINK_CONNECT (1 << 25) | ||
23 | #define HDMI_IRQ_LINK_DISCONNECT (1 << 26) | ||
24 | |||
25 | static inline void hdmi_write_reg(void __iomem *base_addr, const u16 idx, | ||
26 | u32 val) | ||
27 | { | ||
28 | __raw_writel(val, base_addr + idx); | ||
29 | } | ||
30 | |||
31 | static inline u32 hdmi_read_reg(void __iomem *base_addr, const u16 idx) | ||
32 | { | ||
33 | return __raw_readl(base_addr + idx); | ||
34 | } | ||
35 | |||
36 | #define REG_FLD_MOD(base, idx, val, start, end) \ | ||
37 | hdmi_write_reg(base, idx, FLD_MOD(hdmi_read_reg(base, idx),\ | ||
38 | val, start, end)) | ||
39 | #define REG_GET(base, idx, start, end) \ | ||
40 | FLD_GET(hdmi_read_reg(base, idx), start, end) | ||
41 | |||
42 | static inline int hdmi_wait_for_bit_change(void __iomem *base_addr, | ||
43 | const u16 idx, int b2, int b1, u32 val) | ||
44 | { | ||
45 | u32 t = 0; | ||
46 | while (val != REG_GET(base_addr, idx, b2, b1)) { | ||
47 | udelay(1); | ||
48 | if (t++ > 10000) | ||
49 | return !val; | ||
50 | } | ||
51 | return val; | ||
52 | } | ||
53 | |||
54 | void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s) | ||
55 | { | ||
56 | #define DUMPPHY(r) seq_printf(s, "%-35s %08x\n", #r,\ | ||
57 | hdmi_read_reg(phy->base, r)) | ||
58 | |||
59 | DUMPPHY(HDMI_TXPHY_TX_CTRL); | ||
60 | DUMPPHY(HDMI_TXPHY_DIGITAL_CTRL); | ||
61 | DUMPPHY(HDMI_TXPHY_POWER_CTRL); | ||
62 | DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL); | ||
63 | } | ||
64 | |||
65 | static irqreturn_t hdmi_irq_handler(int irq, void *data) | ||
66 | { | ||
67 | struct hdmi_wp_data *wp = data; | ||
68 | u32 irqstatus; | ||
69 | |||
70 | irqstatus = hdmi_wp_get_irqstatus(wp); | ||
71 | hdmi_wp_set_irqstatus(wp, irqstatus); | ||
72 | |||
73 | if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && | ||
74 | irqstatus & HDMI_IRQ_LINK_DISCONNECT) { | ||
75 | /* | ||
76 | * If we get both connect and disconnect interrupts at the same | ||
77 | * time, turn off the PHY, clear interrupts, and restart, which | ||
78 | * raises connect interrupt if a cable is connected, or nothing | ||
79 | * if cable is not connected. | ||
80 | */ | ||
81 | hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); | ||
82 | |||
83 | hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT | | ||
84 | HDMI_IRQ_LINK_DISCONNECT); | ||
85 | |||
86 | hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); | ||
87 | } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { | ||
88 | hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON); | ||
89 | } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { | ||
90 | hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); | ||
91 | } | ||
92 | |||
93 | return IRQ_HANDLED; | ||
94 | } | ||
95 | |||
96 | int hdmi_phy_enable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp, | ||
97 | struct hdmi_config *cfg) | ||
98 | { | ||
99 | u16 r = 0; | ||
100 | u32 irqstatus; | ||
101 | |||
102 | hdmi_wp_clear_irqenable(wp, 0xffffffff); | ||
103 | |||
104 | irqstatus = hdmi_wp_get_irqstatus(wp); | ||
105 | hdmi_wp_set_irqstatus(wp, irqstatus); | ||
106 | |||
107 | r = hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); | ||
108 | if (r) | ||
109 | return r; | ||
110 | |||
111 | /* | ||
112 | * Read address 0 in order to get the SCP reset done completed | ||
113 | * Dummy access performed to make sure reset is done | ||
114 | */ | ||
115 | hdmi_read_reg(phy->base, HDMI_TXPHY_TX_CTRL); | ||
116 | |||
117 | /* | ||
118 | * Write to phy address 0 to configure the clock | ||
119 | * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field | ||
120 | */ | ||
121 | REG_FLD_MOD(phy->base, HDMI_TXPHY_TX_CTRL, 0x1, 31, 30); | ||
122 | |||
123 | /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */ | ||
124 | hdmi_write_reg(phy->base, HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000); | ||
125 | |||
126 | /* Setup max LDO voltage */ | ||
127 | REG_FLD_MOD(phy->base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0); | ||
128 | |||
129 | /* Write to phy address 3 to change the polarity control */ | ||
130 | REG_FLD_MOD(phy->base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27); | ||
131 | |||
132 | r = request_threaded_irq(phy->irq, NULL, hdmi_irq_handler, | ||
133 | IRQF_ONESHOT, "OMAP HDMI", wp); | ||
134 | if (r) { | ||
135 | DSSERR("HDMI IRQ request failed\n"); | ||
136 | hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); | ||
137 | return r; | ||
138 | } | ||
139 | |||
140 | hdmi_wp_set_irqenable(wp, | ||
141 | HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); | ||
142 | |||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | void hdmi_phy_disable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp) | ||
147 | { | ||
148 | free_irq(phy->irq, wp); | ||
149 | |||
150 | hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); | ||
151 | } | ||
152 | |||
153 | #define PHY_OFFSET 0x300 | ||
154 | #define PHY_SIZE 0x100 | ||
155 | |||
156 | int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy) | ||
157 | { | ||
158 | struct resource *res; | ||
159 | struct resource temp_res; | ||
160 | |||
161 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi_txphy"); | ||
162 | if (!res) { | ||
163 | DSSDBG("can't get PHY mem resource by name\n"); | ||
164 | /* | ||
165 | * if hwmod/DT doesn't have the memory resource information | ||
166 | * split into HDMI sub blocks by name, we try again by getting | ||
167 | * the platform's first resource. this code will be removed when | ||
168 | * the driver can get the mem resources by name | ||
169 | */ | ||
170 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
171 | if (!res) { | ||
172 | DSSERR("can't get PHY mem resource\n"); | ||
173 | return -EINVAL; | ||
174 | } | ||
175 | |||
176 | temp_res.start = res->start + PHY_OFFSET; | ||
177 | temp_res.end = temp_res.start + PHY_SIZE - 1; | ||
178 | res = &temp_res; | ||
179 | } | ||
180 | |||
181 | phy->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | ||
182 | if (!phy->base) { | ||
183 | DSSERR("can't ioremap TX PHY\n"); | ||
184 | return -ENOMEM; | ||
185 | } | ||
186 | |||
187 | phy->irq = platform_get_irq(pdev, 0); | ||
188 | if (phy->irq < 0) { | ||
189 | DSSERR("platform_get_irq failed\n"); | ||
190 | return -ENODEV; | ||
191 | } | ||
192 | |||
193 | return 0; | ||
194 | } | ||
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h index 62a83c79628e..716bac450ef0 100644 --- a/drivers/video/omap2/dss/ti_hdmi.h +++ b/drivers/video/omap2/dss/ti_hdmi.h | |||
@@ -149,16 +149,10 @@ struct ti_hdmi_ip_ops { | |||
149 | 149 | ||
150 | void (*video_configure)(struct hdmi_ip_data *ip_data); | 150 | void (*video_configure)(struct hdmi_ip_data *ip_data); |
151 | 151 | ||
152 | int (*phy_enable)(struct hdmi_ip_data *ip_data); | ||
153 | |||
154 | void (*phy_disable)(struct hdmi_ip_data *ip_data); | ||
155 | |||
156 | int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len); | 152 | int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len); |
157 | 153 | ||
158 | void (*dump_core)(struct hdmi_ip_data *ip_data, struct seq_file *s); | 154 | void (*dump_core)(struct hdmi_ip_data *ip_data, struct seq_file *s); |
159 | 155 | ||
160 | void (*dump_phy)(struct hdmi_ip_data *ip_data, struct seq_file *s); | ||
161 | |||
162 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | 156 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) |
163 | int (*audio_start)(struct hdmi_ip_data *ip_data); | 157 | int (*audio_start)(struct hdmi_ip_data *ip_data); |
164 | 158 | ||
@@ -223,14 +217,20 @@ struct hdmi_pll_data { | |||
223 | struct hdmi_pll_info info; | 217 | struct hdmi_pll_info info; |
224 | }; | 218 | }; |
225 | 219 | ||
220 | struct hdmi_phy_data { | ||
221 | void __iomem *base; | ||
222 | |||
223 | int irq; | ||
224 | }; | ||
225 | |||
226 | struct hdmi_ip_data { | 226 | struct hdmi_ip_data { |
227 | struct hdmi_wp_data wp; | 227 | struct hdmi_wp_data wp; |
228 | struct hdmi_pll_data pll; | 228 | struct hdmi_pll_data pll; |
229 | struct hdmi_phy_data phy; | ||
229 | 230 | ||
230 | unsigned long core_sys_offset; | 231 | unsigned long core_sys_offset; |
231 | unsigned long core_av_offset; | 232 | unsigned long core_av_offset; |
232 | unsigned long phy_offset; | 233 | |
233 | int irq; | ||
234 | const struct ti_hdmi_ip_ops *ops; | 234 | const struct ti_hdmi_ip_ops *ops; |
235 | struct hdmi_config cfg; | 235 | struct hdmi_config cfg; |
236 | struct hdmi_core_infoframe_avi avi_cfg; | 236 | struct hdmi_core_infoframe_avi avi_cfg; |
@@ -266,12 +266,16 @@ void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s); | |||
266 | void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy); | 266 | void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy); |
267 | int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll); | 267 | int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll); |
268 | 268 | ||
269 | int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data); | 269 | /* HDMI PHY funcs */ |
270 | void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); | 270 | int hdmi_phy_enable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp, |
271 | struct hdmi_config *cfg); | ||
272 | void hdmi_phy_disable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp); | ||
273 | void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s); | ||
274 | int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy); | ||
275 | |||
271 | int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len); | 276 | int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len); |
272 | void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data); | 277 | void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data); |
273 | void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); | 278 | void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); |
274 | void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); | ||
275 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | 279 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) |
276 | int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts); | 280 | int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts); |
277 | int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable); | 281 | int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable); |
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c index 8cfb54b39688..c705aa113aac 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | |||
@@ -37,9 +37,6 @@ | |||
37 | #include "dss.h" | 37 | #include "dss.h" |
38 | #include "dss_features.h" | 38 | #include "dss_features.h" |
39 | 39 | ||
40 | #define HDMI_IRQ_LINK_CONNECT (1 << 25) | ||
41 | #define HDMI_IRQ_LINK_DISCONNECT (1 << 26) | ||
42 | |||
43 | static inline void hdmi_write_reg(void __iomem *base_addr, | 40 | static inline void hdmi_write_reg(void __iomem *base_addr, |
44 | const u16 idx, u32 val) | 41 | const u16 idx, u32 val) |
45 | { | 42 | { |
@@ -70,11 +67,6 @@ static inline int hdmi_wait_for_bit_change(void __iomem *base_addr, | |||
70 | return val; | 67 | return val; |
71 | } | 68 | } |
72 | 69 | ||
73 | static inline void __iomem *hdmi_phy_base(struct hdmi_ip_data *ip_data) | ||
74 | { | ||
75 | return ip_data->wp.base + ip_data->phy_offset; | ||
76 | } | ||
77 | |||
78 | static inline void __iomem *hdmi_av_base(struct hdmi_ip_data *ip_data) | 70 | static inline void __iomem *hdmi_av_base(struct hdmi_ip_data *ip_data) |
79 | { | 71 | { |
80 | return ip_data->wp.base + ip_data->core_av_offset; | 72 | return ip_data->wp.base + ip_data->core_av_offset; |
@@ -85,94 +77,6 @@ static inline void __iomem *hdmi_core_sys_base(struct hdmi_ip_data *ip_data) | |||
85 | return ip_data->wp.base + ip_data->core_sys_offset; | 77 | return ip_data->wp.base + ip_data->core_sys_offset; |
86 | } | 78 | } |
87 | 79 | ||
88 | static irqreturn_t hdmi_irq_handler(int irq, void *data) | ||
89 | { | ||
90 | struct hdmi_ip_data *ip_data = data; | ||
91 | u32 irqstatus; | ||
92 | |||
93 | irqstatus = hdmi_wp_get_irqstatus(&ip_data->wp); | ||
94 | hdmi_wp_set_irqstatus(&ip_data->wp, irqstatus); | ||
95 | |||
96 | if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && | ||
97 | irqstatus & HDMI_IRQ_LINK_DISCONNECT) { | ||
98 | /* | ||
99 | * If we get both connect and disconnect interrupts at the same | ||
100 | * time, turn off the PHY, clear interrupts, and restart, which | ||
101 | * raises connect interrupt if a cable is connected, or nothing | ||
102 | * if cable is not connected. | ||
103 | */ | ||
104 | hdmi_wp_set_phy_pwr(&ip_data->wp, HDMI_PHYPWRCMD_OFF); | ||
105 | |||
106 | hdmi_wp_set_irqstatus(&ip_data->wp, HDMI_IRQ_LINK_CONNECT | | ||
107 | HDMI_IRQ_LINK_DISCONNECT); | ||
108 | |||
109 | hdmi_wp_set_phy_pwr(&ip_data->wp, HDMI_PHYPWRCMD_LDOON); | ||
110 | } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { | ||
111 | hdmi_wp_set_phy_pwr(&ip_data->wp, HDMI_PHYPWRCMD_TXON); | ||
112 | } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { | ||
113 | hdmi_wp_set_phy_pwr(&ip_data->wp, HDMI_PHYPWRCMD_LDOON); | ||
114 | } | ||
115 | |||
116 | return IRQ_HANDLED; | ||
117 | } | ||
118 | |||
119 | int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data) | ||
120 | { | ||
121 | u16 r = 0; | ||
122 | u32 irqstatus; | ||
123 | void __iomem *phy_base = hdmi_phy_base(ip_data); | ||
124 | |||
125 | hdmi_wp_clear_irqenable(&ip_data->wp, 0xffffffff); | ||
126 | |||
127 | irqstatus = hdmi_wp_get_irqstatus(&ip_data->wp); | ||
128 | hdmi_wp_set_irqstatus(&ip_data->wp, irqstatus); | ||
129 | |||
130 | r = hdmi_wp_set_phy_pwr(&ip_data->wp, HDMI_PHYPWRCMD_LDOON); | ||
131 | if (r) | ||
132 | return r; | ||
133 | |||
134 | /* | ||
135 | * Read address 0 in order to get the SCP reset done completed | ||
136 | * Dummy access performed to make sure reset is done | ||
137 | */ | ||
138 | hdmi_read_reg(phy_base, HDMI_TXPHY_TX_CTRL); | ||
139 | |||
140 | /* | ||
141 | * Write to phy address 0 to configure the clock | ||
142 | * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field | ||
143 | */ | ||
144 | REG_FLD_MOD(phy_base, HDMI_TXPHY_TX_CTRL, 0x1, 31, 30); | ||
145 | |||
146 | /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */ | ||
147 | hdmi_write_reg(phy_base, HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000); | ||
148 | |||
149 | /* Setup max LDO voltage */ | ||
150 | REG_FLD_MOD(phy_base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0); | ||
151 | |||
152 | /* Write to phy address 3 to change the polarity control */ | ||
153 | REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27); | ||
154 | |||
155 | r = request_threaded_irq(ip_data->irq, NULL, hdmi_irq_handler, | ||
156 | IRQF_ONESHOT, "OMAP HDMI", ip_data); | ||
157 | if (r) { | ||
158 | DSSERR("HDMI IRQ request failed\n"); | ||
159 | hdmi_wp_set_phy_pwr(&ip_data->wp, HDMI_PHYPWRCMD_OFF); | ||
160 | return r; | ||
161 | } | ||
162 | |||
163 | hdmi_wp_set_irqenable(&ip_data->wp, | ||
164 | HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data) | ||
170 | { | ||
171 | free_irq(ip_data->irq, ip_data); | ||
172 | |||
173 | hdmi_wp_set_phy_pwr(&ip_data->wp, HDMI_PHYPWRCMD_OFF); | ||
174 | } | ||
175 | |||
176 | static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data) | 80 | static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data) |
177 | { | 81 | { |
178 | void __iomem *base = hdmi_core_sys_base(ip_data); | 82 | void __iomem *base = hdmi_core_sys_base(ip_data); |
@@ -524,8 +428,6 @@ static void hdmi_core_av_packet_config(struct hdmi_ip_data *ip_data, | |||
524 | (repeat_cfg.generic_pkt_repeat)); | 428 | (repeat_cfg.generic_pkt_repeat)); |
525 | } | 429 | } |
526 | 430 | ||
527 | |||
528 | |||
529 | void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) | 431 | void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) |
530 | { | 432 | { |
531 | /* HDMI */ | 433 | /* HDMI */ |
@@ -769,17 +671,6 @@ void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) | |||
769 | DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID); | 671 | DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID); |
770 | } | 672 | } |
771 | 673 | ||
772 | void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) | ||
773 | { | ||
774 | #define DUMPPHY(r) seq_printf(s, "%-35s %08x\n", #r,\ | ||
775 | hdmi_read_reg(hdmi_phy_base(ip_data), r)) | ||
776 | |||
777 | DUMPPHY(HDMI_TXPHY_TX_CTRL); | ||
778 | DUMPPHY(HDMI_TXPHY_DIGITAL_CTRL); | ||
779 | DUMPPHY(HDMI_TXPHY_POWER_CTRL); | ||
780 | DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL); | ||
781 | } | ||
782 | |||
783 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) | 674 | #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) |
784 | static void ti_hdmi_4xxx_core_audio_config(struct hdmi_ip_data *ip_data, | 675 | static void ti_hdmi_4xxx_core_audio_config(struct hdmi_ip_data *ip_data, |
785 | struct hdmi_core_audio_config *cfg) | 676 | struct hdmi_core_audio_config *cfg) |