aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
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");