aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2013-10-08 03:37:00 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2013-10-09 05:42:11 -0400
commit5cac5aee18568579931267d3211371a176efa476 (patch)
treec35391f24c28b11c30de9ae8f684240fce6db415 /drivers/video
parentc1577c1ea01732fea5bc18f05a9e005c0dce6261 (diff)
omapdss: HDMI: create a PHY library
HDMI PHY is a block common to DSS in OMAP4, OMAP5 and DRA7x. Move the existing functions from ti_hdmi_4xxx_ip.c to a separate file. These funcs are called directly from the hdmi driver rather than hdmi_ip_ops function pointer calls. Add the PHY library function declarations to ti_hdmi.h. These will be shared amongst the omap4/5 hdmi platform drivers. Remove the PHY function pointer ops from the ti_hdmi_ip_ops struct. The DT/hwmod information for hdmi doesn't split the address space according to the required sub blocks. Keep the address offset and size information in the driver for now. This will be removed when the driver gets the information correctly from DT/hwmod. Signed-off-by: Archit Taneja <archit@ti.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/dss/Makefile3
-rw-r--r--drivers/video/omap2/dss/dss_features.c3
-rw-r--r--drivers/video/omap2/dss/hdmi.c19
-rw-r--r--drivers/video/omap2/dss/hdmi_phy.c194
-rw-r--r--drivers/video/omap2/dss/ti_hdmi.h26
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c109
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
10omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o 10omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
11omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o 11omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
12omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o 12omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
13omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o hdmi_wp.o hdmi_pll.o ti_hdmi_4xxx_ip.o 13omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o hdmi_wp.o hdmi_pll.o hdmi_phy.o \
14 ti_hdmi_4xxx_ip.o
14ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG 15ccflags-$(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 = {
794static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { 794static 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)
514err_mgr_enable: 514err_mgr_enable:
515 hdmi_wp_video_stop(&hdmi.ip_data.wp); 515 hdmi_wp_video_stop(&hdmi.ip_data.wp);
516err_vid_enable: 516err_vid_enable:
517 hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); 517 hdmi_phy_disable(&hdmi.ip_data.phy, &hdmi.ip_data.wp);
518err_phy_enable: 518err_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);
520err_pll_enable: 520err_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
25static 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
31static 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
42static 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
54void 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
65static 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
96int 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
146void 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
156int 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
220struct hdmi_phy_data {
221 void __iomem *base;
222
223 int irq;
224};
225
226struct hdmi_ip_data { 226struct 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);
266void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy); 266void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy);
267int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll); 267int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll);
268 268
269int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data); 269/* HDMI PHY funcs */
270void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); 270int hdmi_phy_enable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp,
271 struct hdmi_config *cfg);
272void hdmi_phy_disable(struct hdmi_phy_data *phy, struct hdmi_wp_data *wp);
273void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s);
274int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy);
275
271int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len); 276int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len);
272void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data); 277void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data);
273void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); 278void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
274void 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)
276int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts); 280int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts);
277int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable); 281int 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
43static inline void hdmi_write_reg(void __iomem *base_addr, 40static 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
73static 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
78static inline void __iomem *hdmi_av_base(struct hdmi_ip_data *ip_data) 70static 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
88static 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
119int 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
169void 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
176static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data) 80static 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
529void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) 431void 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
772void 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)
784static void ti_hdmi_4xxx_core_audio_config(struct hdmi_ip_data *ip_data, 675static 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)