diff options
author | Archit Taneja <archit@ti.com> | 2013-09-23 03:28:52 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-05-09 08:11:29 -0400 |
commit | 19289fdcbef8dae72f5c0f9f274490620feac222 (patch) | |
tree | 2f6b7633c6997305dd381abeedd9343dfd838064 /drivers/video | |
parent | 8955b727afb472125152508af2d4ec1d41442b0b (diff) |
OMAPDSS: HDMI: PHY changes for OMAP5
OMAP5 HDMI PHY has some differences compared to OMAP4 HDMI PHY. This
patch creates a features struct which help the driver configure the PHY
based on what SoC it is.
Some of the features aren't currenlty used, but will come in use later.
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/fbdev/omap2/dss/hdmi.h | 1 | ||||
-rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi_phy.c | 95 |
2 files changed, 94 insertions, 2 deletions
diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h index 0e5979ef933c..1819f93cd49e 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi.h +++ b/drivers/video/fbdev/omap2/dss/hdmi.h | |||
@@ -80,6 +80,7 @@ | |||
80 | #define HDMI_TXPHY_DIGITAL_CTRL 0x4 | 80 | #define HDMI_TXPHY_DIGITAL_CTRL 0x4 |
81 | #define HDMI_TXPHY_POWER_CTRL 0x8 | 81 | #define HDMI_TXPHY_POWER_CTRL 0x8 |
82 | #define HDMI_TXPHY_PAD_CFG_CTRL 0xC | 82 | #define HDMI_TXPHY_PAD_CFG_CTRL 0xC |
83 | #define HDMI_TXPHY_BIST_CONTROL 0x1C | ||
83 | 84 | ||
84 | enum hdmi_pll_pwr { | 85 | enum hdmi_pll_pwr { |
85 | HDMI_PLLPWRCMD_ALLOFF = 0, | 86 | HDMI_PLLPWRCMD_ALLOFF = 0, |
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_phy.c b/drivers/video/fbdev/omap2/dss/hdmi_phy.c index 8d13e422de5e..2614cf9dafb0 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi_phy.c +++ b/drivers/video/fbdev/omap2/dss/hdmi_phy.c | |||
@@ -12,11 +12,22 @@ | |||
12 | #include <linux/err.h> | 12 | #include <linux/err.h> |
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/slab.h> | ||
15 | #include <video/omapdss.h> | 16 | #include <video/omapdss.h> |
16 | 17 | ||
17 | #include "dss.h" | 18 | #include "dss.h" |
18 | #include "hdmi.h" | 19 | #include "hdmi.h" |
19 | 20 | ||
21 | struct hdmi_phy_features { | ||
22 | bool bist_ctrl; | ||
23 | bool calc_freqout; | ||
24 | bool ldo_voltage; | ||
25 | unsigned long dcofreq_min; | ||
26 | unsigned long max_phy; | ||
27 | }; | ||
28 | |||
29 | static const struct hdmi_phy_features *phy_feat; | ||
30 | |||
20 | void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s) | 31 | void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s) |
21 | { | 32 | { |
22 | #define DUMPPHY(r) seq_printf(s, "%-35s %08x\n", #r,\ | 33 | #define DUMPPHY(r) seq_printf(s, "%-35s %08x\n", #r,\ |
@@ -26,6 +37,8 @@ void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s) | |||
26 | DUMPPHY(HDMI_TXPHY_DIGITAL_CTRL); | 37 | DUMPPHY(HDMI_TXPHY_DIGITAL_CTRL); |
27 | DUMPPHY(HDMI_TXPHY_POWER_CTRL); | 38 | DUMPPHY(HDMI_TXPHY_POWER_CTRL); |
28 | DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL); | 39 | DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL); |
40 | if (phy_feat->bist_ctrl) | ||
41 | DUMPPHY(HDMI_TXPHY_BIST_CONTROL); | ||
29 | } | 42 | } |
30 | 43 | ||
31 | int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes) | 44 | int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes) |
@@ -121,6 +134,8 @@ static void hdmi_phy_configure_lanes(struct hdmi_phy_data *phy) | |||
121 | 134 | ||
122 | int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg) | 135 | int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg) |
123 | { | 136 | { |
137 | u8 freqout; | ||
138 | |||
124 | /* | 139 | /* |
125 | * Read address 0 in order to get the SCP reset done completed | 140 | * Read address 0 in order to get the SCP reset done completed |
126 | * Dummy access performed to make sure reset is done | 141 | * Dummy access performed to make sure reset is done |
@@ -128,16 +143,39 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg) | |||
128 | hdmi_read_reg(phy->base, HDMI_TXPHY_TX_CTRL); | 143 | hdmi_read_reg(phy->base, HDMI_TXPHY_TX_CTRL); |
129 | 144 | ||
130 | /* | 145 | /* |
146 | * In OMAP5+, the HFBITCLK must be divided by 2 before issuing the | ||
147 | * HDMI_PHYPWRCMD_LDOON command. | ||
148 | */ | ||
149 | if (phy_feat->bist_ctrl) | ||
150 | REG_FLD_MOD(phy->base, HDMI_TXPHY_BIST_CONTROL, 1, 11, 11); | ||
151 | |||
152 | if (phy_feat->calc_freqout) { | ||
153 | /* DCOCLK/10 is pixel clock, compare pclk with DCOCLK_MIN/10 */ | ||
154 | u32 dco_min = phy_feat->dcofreq_min / 10; | ||
155 | u32 pclk = cfg->timings.pixelclock; | ||
156 | |||
157 | if (pclk < dco_min) | ||
158 | freqout = 0; | ||
159 | else if ((pclk >= dco_min) && (pclk < phy_feat->max_phy)) | ||
160 | freqout = 1; | ||
161 | else | ||
162 | freqout = 2; | ||
163 | } else { | ||
164 | freqout = 1; | ||
165 | } | ||
166 | |||
167 | /* | ||
131 | * Write to phy address 0 to configure the clock | 168 | * Write to phy address 0 to configure the clock |
132 | * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field | 169 | * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field |
133 | */ | 170 | */ |
134 | REG_FLD_MOD(phy->base, HDMI_TXPHY_TX_CTRL, 0x1, 31, 30); | 171 | REG_FLD_MOD(phy->base, HDMI_TXPHY_TX_CTRL, freqout, 31, 30); |
135 | 172 | ||
136 | /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */ | 173 | /* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */ |
137 | hdmi_write_reg(phy->base, HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000); | 174 | hdmi_write_reg(phy->base, HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000); |
138 | 175 | ||
139 | /* Setup max LDO voltage */ | 176 | /* Setup max LDO voltage */ |
140 | REG_FLD_MOD(phy->base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0); | 177 | if (phy_feat->ldo_voltage) |
178 | REG_FLD_MOD(phy->base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0); | ||
141 | 179 | ||
142 | hdmi_phy_configure_lanes(phy); | 180 | hdmi_phy_configure_lanes(phy); |
143 | 181 | ||
@@ -147,11 +185,64 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg) | |||
147 | #define PHY_OFFSET 0x300 | 185 | #define PHY_OFFSET 0x300 |
148 | #define PHY_SIZE 0x100 | 186 | #define PHY_SIZE 0x100 |
149 | 187 | ||
188 | static const struct hdmi_phy_features omap44xx_phy_feats = { | ||
189 | .bist_ctrl = false, | ||
190 | .calc_freqout = false, | ||
191 | .ldo_voltage = true, | ||
192 | .dcofreq_min = 500000000, | ||
193 | .max_phy = 185675000, | ||
194 | }; | ||
195 | |||
196 | static const struct hdmi_phy_features omap54xx_phy_feats = { | ||
197 | .bist_ctrl = true, | ||
198 | .calc_freqout = true, | ||
199 | .ldo_voltage = false, | ||
200 | .dcofreq_min = 750000000, | ||
201 | .max_phy = 186000000, | ||
202 | }; | ||
203 | |||
204 | static int hdmi_phy_init_features(struct platform_device *pdev) | ||
205 | { | ||
206 | struct hdmi_phy_features *dst; | ||
207 | const struct hdmi_phy_features *src; | ||
208 | |||
209 | dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL); | ||
210 | if (!dst) { | ||
211 | dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n"); | ||
212 | return -ENOMEM; | ||
213 | } | ||
214 | |||
215 | switch (omapdss_get_version()) { | ||
216 | case OMAPDSS_VER_OMAP4430_ES1: | ||
217 | case OMAPDSS_VER_OMAP4430_ES2: | ||
218 | case OMAPDSS_VER_OMAP4: | ||
219 | src = &omap44xx_phy_feats; | ||
220 | break; | ||
221 | |||
222 | case OMAPDSS_VER_OMAP5: | ||
223 | src = &omap54xx_phy_feats; | ||
224 | break; | ||
225 | |||
226 | default: | ||
227 | return -ENODEV; | ||
228 | } | ||
229 | |||
230 | memcpy(dst, src, sizeof(*dst)); | ||
231 | phy_feat = dst; | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
150 | int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy) | 236 | int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy) |
151 | { | 237 | { |
238 | int r; | ||
152 | struct resource *res; | 239 | struct resource *res; |
153 | struct resource temp_res; | 240 | struct resource temp_res; |
154 | 241 | ||
242 | r = hdmi_phy_init_features(pdev); | ||
243 | if (r) | ||
244 | return r; | ||
245 | |||
155 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy"); | 246 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy"); |
156 | if (!res) { | 247 | if (!res) { |
157 | DSSDBG("can't get PHY mem resource by name\n"); | 248 | DSSDBG("can't get PHY mem resource by name\n"); |