aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorArchit Taneja <archit@ti.com>2013-09-23 05:42:34 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2014-05-09 08:11:29 -0400
commit2d64b1b314bb52463b444e9c5aa1a2d399e694d2 (patch)
tree2d26ba135e31dc112f7a6829c9a7320c71d5cb25 /drivers/video
parent19289fdcbef8dae72f5c0f9f274490620feac222 (diff)
OMAPDSS: HDMI: PLL changes for OMAP5
Add a features struct to differentiate between the HDMI PLLs on OMAP4 and OMAP5. The OMAP5 PLL is more sensitive when it comes to locking. We need to ensure that the DCO freq isn't too low for lower pixel clocks. Modify the PLL computation slightly to ensure the HDMI PLL locks for lower frequencies. This will be later replaced by a more complex computation which makes sure all the PLL constraints are met. 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_pll.c81
1 files changed, 79 insertions, 2 deletions
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
index 5fc71215c303..2b910cb9eee4 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
@@ -23,6 +23,18 @@
23#define HDMI_DEFAULT_REGN 16 23#define HDMI_DEFAULT_REGN 16
24#define HDMI_DEFAULT_REGM2 1 24#define HDMI_DEFAULT_REGM2 1
25 25
26struct hdmi_pll_features {
27 bool sys_reset;
28 /* this is a hack, need to replace it with a better computation of M2 */
29 bool bound_dcofreq;
30 unsigned long fint_min, fint_max;
31 u16 regm_max;
32 unsigned long dcofreq_low_min, dcofreq_low_max;
33 unsigned long dcofreq_high_min, dcofreq_high_max;
34};
35
36static const struct hdmi_pll_features *pll_feat;
37
26void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s) 38void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s)
27{ 39{
28#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\ 40#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\
@@ -57,7 +69,11 @@ void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy)
57 69
58 refclk = clkin / pi->regn; 70 refclk = clkin / pi->regn;
59 71
60 pi->regm2 = HDMI_DEFAULT_REGM2; 72 /* temorary hack to make sure DCO freq isn't calculated too low */
73 if (pll_feat->bound_dcofreq && phy <= 65000)
74 pi->regm2 = 3;
75 else
76 pi->regm2 = HDMI_DEFAULT_REGM2;
61 77
62 /* 78 /*
63 * multiplier is pixel_clk/ref_clk 79 * multiplier is pixel_clk/ref_clk
@@ -154,7 +170,7 @@ static int hdmi_pll_config(struct hdmi_pll_data *pll)
154static int hdmi_pll_reset(struct hdmi_pll_data *pll) 170static int hdmi_pll_reset(struct hdmi_pll_data *pll)
155{ 171{
156 /* SYSRESET controlled by power FSM */ 172 /* SYSRESET controlled by power FSM */
157 REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, 0x0, 3, 3); 173 REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, pll_feat->sys_reset, 3, 3);
158 174
159 /* READ 0x0 reset is in progress */ 175 /* READ 0x0 reset is in progress */
160 if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 0, 0, 1) 176 if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 0, 0, 1)
@@ -197,11 +213,72 @@ void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp)
197#define PLL_OFFSET 0x200 213#define PLL_OFFSET 0x200
198#define PLL_SIZE 0x100 214#define PLL_SIZE 0x100
199 215
216static const struct hdmi_pll_features omap44xx_pll_feats = {
217 .sys_reset = false,
218 .bound_dcofreq = false,
219 .fint_min = 500000,
220 .fint_max = 2500000,
221 .regm_max = 4095,
222 .dcofreq_low_min = 500000000,
223 .dcofreq_low_max = 1000000000,
224 .dcofreq_high_min = 1000000000,
225 .dcofreq_high_max = 2000000000,
226};
227
228static const struct hdmi_pll_features omap54xx_pll_feats = {
229 .sys_reset = true,
230 .bound_dcofreq = true,
231 .fint_min = 620000,
232 .fint_max = 2500000,
233 .regm_max = 2046,
234 .dcofreq_low_min = 750000000,
235 .dcofreq_low_max = 1500000000,
236 .dcofreq_high_min = 1250000000,
237 .dcofreq_high_max = 2500000000UL,
238};
239
240static int hdmi_pll_init_features(struct platform_device *pdev)
241{
242 struct hdmi_pll_features *dst;
243 const struct hdmi_pll_features *src;
244
245 dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL);
246 if (!dst) {
247 dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n");
248 return -ENOMEM;
249 }
250
251 switch (omapdss_get_version()) {
252 case OMAPDSS_VER_OMAP4430_ES1:
253 case OMAPDSS_VER_OMAP4430_ES2:
254 case OMAPDSS_VER_OMAP4:
255 src = &omap44xx_pll_feats;
256 break;
257
258 case OMAPDSS_VER_OMAP5:
259 src = &omap54xx_pll_feats;
260 break;
261
262 default:
263 return -ENODEV;
264 }
265
266 memcpy(dst, src, sizeof(*dst));
267 pll_feat = dst;
268
269 return 0;
270}
271
200int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll) 272int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll)
201{ 273{
274 int r;
202 struct resource *res; 275 struct resource *res;
203 struct resource temp_res; 276 struct resource temp_res;
204 277
278 r = hdmi_pll_init_features(pdev);
279 if (r)
280 return r;
281
205 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll"); 282 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll");
206 if (!res) { 283 if (!res) {
207 DSSDBG("can't get PLL mem resource by name\n"); 284 DSSDBG("can't get PLL mem resource by name\n");