aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2013-09-23 03:28:52 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2014-05-09 08:11:29 -0400
commit19289fdcbef8dae72f5c0f9f274490620feac222 (patch)
tree2f6b7633c6997305dd381abeedd9343dfd838064 /drivers/video
parent8955b727afb472125152508af2d4ec1d41442b0b (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.h1
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_phy.c95
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
84enum hdmi_pll_pwr { 85enum 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
21struct 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
29static const struct hdmi_phy_features *phy_feat;
30
20void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s) 31void 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
31int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes) 44int 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
122int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg) 135int 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
188static 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
196static 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
204static 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
150int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy) 236int 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");