diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-10-22 08:02:17 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-11-12 06:40:27 -0500 |
commit | c84c3a5bb78ff271787a1fec9218768aed555e8d (patch) | |
tree | 98c64021765bcaf1b5389a9082ae98487c7f9c2b /drivers/video | |
parent | d13cbb32c50019b38fb3ab030a8ab435b6f2440a (diff) |
OMAPDSS: HDMI: use common DSS PLL support
Now that we have the common DSS PLL support, change HDMI to use it. This
results in quite a lot of changes, but almost all of them are trivial
name changes.
The function to program the PLL settings can be removed from hdmi_pll.c,
as the common PLL API contains the same functionality.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi.h | 24 | ||||
-rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi4.c | 55 | ||||
-rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi5.c | 56 | ||||
-rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi_pll.c | 225 |
4 files changed, 146 insertions, 214 deletions
diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h index 7595274a9bcf..3c42823e934b 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi.h +++ b/drivers/video/fbdev/omap2/dss/hdmi.h | |||
@@ -184,18 +184,6 @@ struct hdmi_config { | |||
184 | enum hdmi_core_hdmi_dvi hdmi_dvi_mode; | 184 | enum hdmi_core_hdmi_dvi hdmi_dvi_mode; |
185 | }; | 185 | }; |
186 | 186 | ||
187 | /* HDMI PLL structure */ | ||
188 | struct hdmi_pll_info { | ||
189 | u16 regn; | ||
190 | u16 regm; | ||
191 | u32 regmf; | ||
192 | u16 regm2; | ||
193 | u16 regsd; | ||
194 | |||
195 | unsigned long clkdco; | ||
196 | unsigned long clkout; | ||
197 | }; | ||
198 | |||
199 | struct hdmi_audio_format { | 187 | struct hdmi_audio_format { |
200 | enum hdmi_stereo_channels stereo_channels; | 188 | enum hdmi_stereo_channels stereo_channels; |
201 | u8 active_chnnls_msk; | 189 | u8 active_chnnls_msk; |
@@ -246,11 +234,11 @@ struct hdmi_wp_data { | |||
246 | }; | 234 | }; |
247 | 235 | ||
248 | struct hdmi_pll_data { | 236 | struct hdmi_pll_data { |
237 | struct dss_pll pll; | ||
238 | |||
249 | void __iomem *base; | 239 | void __iomem *base; |
250 | 240 | ||
251 | struct hdmi_wp_data *wp; | 241 | struct hdmi_wp_data *wp; |
252 | |||
253 | struct hdmi_pll_info info; | ||
254 | }; | 242 | }; |
255 | 243 | ||
256 | struct hdmi_phy_data { | 244 | struct hdmi_phy_data { |
@@ -314,14 +302,12 @@ void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt, | |||
314 | int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp); | 302 | int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp); |
315 | 303 | ||
316 | /* HDMI PLL funcs */ | 304 | /* HDMI PLL funcs */ |
317 | int hdmi_pll_enable(struct hdmi_pll_data *pll); | ||
318 | void hdmi_pll_disable(struct hdmi_pll_data *pll); | ||
319 | int hdmi_pll_set_config(struct hdmi_pll_data *pll); | ||
320 | void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s); | 305 | void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s); |
321 | void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, | 306 | void hdmi_pll_compute(struct hdmi_pll_data *pll, |
322 | unsigned long target_tmds); | 307 | unsigned long target_tmds, struct dss_pll_clock_info *pi); |
323 | int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll, | 308 | int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll, |
324 | struct hdmi_wp_data *wp); | 309 | struct hdmi_wp_data *wp); |
310 | void hdmi_pll_uninit(struct hdmi_pll_data *hpll); | ||
325 | 311 | ||
326 | /* HDMI PHY funcs */ | 312 | /* HDMI PHY funcs */ |
327 | int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk, | 313 | int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk, |
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c index 98aa910241b8..46dcc71ce058 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi4.c +++ b/drivers/video/fbdev/omap2/dss/hdmi4.c | |||
@@ -49,7 +49,6 @@ static struct { | |||
49 | 49 | ||
50 | struct hdmi_config cfg; | 50 | struct hdmi_config cfg; |
51 | 51 | ||
52 | struct clk *sys_clk; | ||
53 | struct regulator *vdda_hdmi_dac_reg; | 52 | struct regulator *vdda_hdmi_dac_reg; |
54 | 53 | ||
55 | bool core_enabled; | 54 | bool core_enabled; |
@@ -181,6 +180,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) | |||
181 | struct omap_video_timings *p; | 180 | struct omap_video_timings *p; |
182 | struct omap_overlay_manager *mgr = hdmi.output.manager; | 181 | struct omap_overlay_manager *mgr = hdmi.output.manager; |
183 | struct hdmi_wp_data *wp = &hdmi.wp; | 182 | struct hdmi_wp_data *wp = &hdmi.wp; |
183 | struct dss_pll_clock_info hdmi_cinfo = { 0 }; | ||
184 | 184 | ||
185 | r = hdmi_power_on_core(dssdev); | 185 | r = hdmi_power_on_core(dssdev); |
186 | if (r) | 186 | if (r) |
@@ -194,22 +194,22 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) | |||
194 | 194 | ||
195 | DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); | 195 | DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); |
196 | 196 | ||
197 | hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), p->pixelclock); | 197 | hdmi_pll_compute(&hdmi.pll, p->pixelclock, &hdmi_cinfo); |
198 | 198 | ||
199 | r = hdmi_pll_enable(&hdmi.pll); | 199 | r = dss_pll_enable(&hdmi.pll.pll); |
200 | if (r) { | 200 | if (r) { |
201 | DSSERR("Failed to enable PLL\n"); | 201 | DSSERR("Failed to enable PLL\n"); |
202 | goto err_pll_enable; | 202 | goto err_pll_enable; |
203 | } | 203 | } |
204 | 204 | ||
205 | r = hdmi_pll_set_config(&hdmi.pll); | 205 | r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo); |
206 | if (r) { | 206 | if (r) { |
207 | DSSERR("Failed to configure PLL\n"); | 207 | DSSERR("Failed to configure PLL\n"); |
208 | goto err_pll_cfg; | 208 | goto err_pll_cfg; |
209 | } | 209 | } |
210 | 210 | ||
211 | r = hdmi_phy_configure(&hdmi.phy, hdmi.pll.info.clkdco, | 211 | r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco, |
212 | hdmi.pll.info.clkout); | 212 | hdmi_cinfo.clkout[0]); |
213 | if (r) { | 213 | if (r) { |
214 | DSSDBG("Failed to configure PHY\n"); | 214 | DSSDBG("Failed to configure PHY\n"); |
215 | goto err_phy_cfg; | 215 | goto err_phy_cfg; |
@@ -247,7 +247,7 @@ err_phy_cfg: | |||
247 | hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); | 247 | hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); |
248 | err_phy_pwr: | 248 | err_phy_pwr: |
249 | err_pll_cfg: | 249 | err_pll_cfg: |
250 | hdmi_pll_disable(&hdmi.pll); | 250 | dss_pll_disable(&hdmi.pll.pll); |
251 | err_pll_enable: | 251 | err_pll_enable: |
252 | hdmi_power_off_core(dssdev); | 252 | hdmi_power_off_core(dssdev); |
253 | return -EIO; | 253 | return -EIO; |
@@ -265,7 +265,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev) | |||
265 | 265 | ||
266 | hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); | 266 | hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); |
267 | 267 | ||
268 | hdmi_pll_disable(&hdmi.pll); | 268 | dss_pll_disable(&hdmi.pll.pll); |
269 | 269 | ||
270 | hdmi_power_off_core(dssdev); | 270 | hdmi_power_off_core(dssdev); |
271 | } | 271 | } |
@@ -407,21 +407,6 @@ static void hdmi_core_disable(struct omap_dss_device *dssdev) | |||
407 | mutex_unlock(&hdmi.lock); | 407 | mutex_unlock(&hdmi.lock); |
408 | } | 408 | } |
409 | 409 | ||
410 | static int hdmi_get_clocks(struct platform_device *pdev) | ||
411 | { | ||
412 | struct clk *clk; | ||
413 | |||
414 | clk = devm_clk_get(&pdev->dev, "sys_clk"); | ||
415 | if (IS_ERR(clk)) { | ||
416 | DSSERR("can't get sys_clk\n"); | ||
417 | return PTR_ERR(clk); | ||
418 | } | ||
419 | |||
420 | hdmi.sys_clk = clk; | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | static int hdmi_connect(struct omap_dss_device *dssdev, | 410 | static int hdmi_connect(struct omap_dss_device *dssdev, |
426 | struct omap_dss_device *dst) | 411 | struct omap_dss_device *dst) |
427 | { | 412 | { |
@@ -700,22 +685,17 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) | |||
700 | 685 | ||
701 | r = hdmi_phy_init(pdev, &hdmi.phy); | 686 | r = hdmi_phy_init(pdev, &hdmi.phy); |
702 | if (r) | 687 | if (r) |
703 | return r; | 688 | goto err; |
704 | 689 | ||
705 | r = hdmi4_core_init(pdev, &hdmi.core); | 690 | r = hdmi4_core_init(pdev, &hdmi.core); |
706 | if (r) | 691 | if (r) |
707 | return r; | 692 | goto err; |
708 | |||
709 | r = hdmi_get_clocks(pdev); | ||
710 | if (r) { | ||
711 | DSSERR("can't get clocks\n"); | ||
712 | return r; | ||
713 | } | ||
714 | 693 | ||
715 | irq = platform_get_irq(pdev, 0); | 694 | irq = platform_get_irq(pdev, 0); |
716 | if (irq < 0) { | 695 | if (irq < 0) { |
717 | DSSERR("platform_get_irq failed\n"); | 696 | DSSERR("platform_get_irq failed\n"); |
718 | return -ENODEV; | 697 | r = -ENODEV; |
698 | goto err; | ||
719 | } | 699 | } |
720 | 700 | ||
721 | r = devm_request_threaded_irq(&pdev->dev, irq, | 701 | r = devm_request_threaded_irq(&pdev->dev, irq, |
@@ -723,7 +703,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) | |||
723 | IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); | 703 | IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); |
724 | if (r) { | 704 | if (r) { |
725 | DSSERR("HDMI IRQ request failed\n"); | 705 | DSSERR("HDMI IRQ request failed\n"); |
726 | return r; | 706 | goto err; |
727 | } | 707 | } |
728 | 708 | ||
729 | pm_runtime_enable(&pdev->dev); | 709 | pm_runtime_enable(&pdev->dev); |
@@ -733,12 +713,17 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) | |||
733 | dss_debugfs_create_file("hdmi", hdmi_dump_regs); | 713 | dss_debugfs_create_file("hdmi", hdmi_dump_regs); |
734 | 714 | ||
735 | return 0; | 715 | return 0; |
716 | err: | ||
717 | hdmi_pll_uninit(&hdmi.pll); | ||
718 | return r; | ||
736 | } | 719 | } |
737 | 720 | ||
738 | static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) | 721 | static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) |
739 | { | 722 | { |
740 | hdmi_uninit_output(pdev); | 723 | hdmi_uninit_output(pdev); |
741 | 724 | ||
725 | hdmi_pll_uninit(&hdmi.pll); | ||
726 | |||
742 | pm_runtime_disable(&pdev->dev); | 727 | pm_runtime_disable(&pdev->dev); |
743 | 728 | ||
744 | return 0; | 729 | return 0; |
@@ -746,8 +731,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) | |||
746 | 731 | ||
747 | static int hdmi_runtime_suspend(struct device *dev) | 732 | static int hdmi_runtime_suspend(struct device *dev) |
748 | { | 733 | { |
749 | clk_disable_unprepare(hdmi.sys_clk); | ||
750 | |||
751 | dispc_runtime_put(); | 734 | dispc_runtime_put(); |
752 | 735 | ||
753 | return 0; | 736 | return 0; |
@@ -761,8 +744,6 @@ static int hdmi_runtime_resume(struct device *dev) | |||
761 | if (r < 0) | 744 | if (r < 0) |
762 | return r; | 745 | return r; |
763 | 746 | ||
764 | clk_prepare_enable(hdmi.sys_clk); | ||
765 | |||
766 | return 0; | 747 | return 0; |
767 | } | 748 | } |
768 | 749 | ||
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c index facc4e070520..67facf87b370 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi5.c +++ b/drivers/video/fbdev/omap2/dss/hdmi5.c | |||
@@ -54,8 +54,8 @@ static struct { | |||
54 | 54 | ||
55 | struct hdmi_config cfg; | 55 | struct hdmi_config cfg; |
56 | 56 | ||
57 | struct clk *sys_clk; | ||
58 | struct regulator *vdda_reg; | 57 | struct regulator *vdda_reg; |
58 | struct clk *sys_clk; | ||
59 | 59 | ||
60 | bool core_enabled; | 60 | bool core_enabled; |
61 | 61 | ||
@@ -198,6 +198,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) | |||
198 | int r; | 198 | int r; |
199 | struct omap_video_timings *p; | 199 | struct omap_video_timings *p; |
200 | struct omap_overlay_manager *mgr = hdmi.output.manager; | 200 | struct omap_overlay_manager *mgr = hdmi.output.manager; |
201 | struct dss_pll_clock_info hdmi_cinfo = { 0 }; | ||
201 | 202 | ||
202 | r = hdmi_power_on_core(dssdev); | 203 | r = hdmi_power_on_core(dssdev); |
203 | if (r) | 204 | if (r) |
@@ -207,27 +208,27 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev) | |||
207 | 208 | ||
208 | DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); | 209 | DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); |
209 | 210 | ||
210 | hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), p->pixelclock); | 211 | hdmi_pll_compute(&hdmi.pll, p->pixelclock, &hdmi_cinfo); |
211 | 212 | ||
212 | /* disable and clear irqs */ | 213 | /* disable and clear irqs */ |
213 | hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); | 214 | hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); |
214 | hdmi_wp_set_irqstatus(&hdmi.wp, | 215 | hdmi_wp_set_irqstatus(&hdmi.wp, |
215 | hdmi_wp_get_irqstatus(&hdmi.wp)); | 216 | hdmi_wp_get_irqstatus(&hdmi.wp)); |
216 | 217 | ||
217 | r = hdmi_pll_enable(&hdmi.pll); | 218 | r = dss_pll_enable(&hdmi.pll.pll); |
218 | if (r) { | 219 | if (r) { |
219 | DSSERR("Failed to enable PLL\n"); | 220 | DSSERR("Failed to enable PLL\n"); |
220 | goto err_pll_enable; | 221 | goto err_pll_enable; |
221 | } | 222 | } |
222 | 223 | ||
223 | r = hdmi_pll_set_config(&hdmi.pll); | 224 | r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo); |
224 | if (r) { | 225 | if (r) { |
225 | DSSERR("Failed to configure PLL\n"); | 226 | DSSERR("Failed to configure PLL\n"); |
226 | goto err_pll_cfg; | 227 | goto err_pll_cfg; |
227 | } | 228 | } |
228 | 229 | ||
229 | r = hdmi_phy_configure(&hdmi.phy, hdmi.pll.info.clkdco, | 230 | r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco, |
230 | hdmi.pll.info.clkout); | 231 | hdmi_cinfo.clkout[0]); |
231 | if (r) { | 232 | if (r) { |
232 | DSSDBG("Failed to start PHY\n"); | 233 | DSSDBG("Failed to start PHY\n"); |
233 | goto err_phy_cfg; | 234 | goto err_phy_cfg; |
@@ -265,7 +266,7 @@ err_vid_enable: | |||
265 | err_phy_pwr: | 266 | err_phy_pwr: |
266 | err_phy_cfg: | 267 | err_phy_cfg: |
267 | err_pll_cfg: | 268 | err_pll_cfg: |
268 | hdmi_pll_disable(&hdmi.pll); | 269 | dss_pll_disable(&hdmi.pll.pll); |
269 | err_pll_enable: | 270 | err_pll_enable: |
270 | hdmi_power_off_core(dssdev); | 271 | hdmi_power_off_core(dssdev); |
271 | return -EIO; | 272 | return -EIO; |
@@ -283,7 +284,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev) | |||
283 | 284 | ||
284 | hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); | 285 | hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); |
285 | 286 | ||
286 | hdmi_pll_disable(&hdmi.pll); | 287 | dss_pll_disable(&hdmi.pll.pll); |
287 | 288 | ||
288 | hdmi_power_off_core(dssdev); | 289 | hdmi_power_off_core(dssdev); |
289 | } | 290 | } |
@@ -436,21 +437,6 @@ static void hdmi_core_disable(struct omap_dss_device *dssdev) | |||
436 | mutex_unlock(&hdmi.lock); | 437 | mutex_unlock(&hdmi.lock); |
437 | } | 438 | } |
438 | 439 | ||
439 | static int hdmi_get_clocks(struct platform_device *pdev) | ||
440 | { | ||
441 | struct clk *clk; | ||
442 | |||
443 | clk = devm_clk_get(&pdev->dev, "sys_clk"); | ||
444 | if (IS_ERR(clk)) { | ||
445 | DSSERR("can't get sys_clk\n"); | ||
446 | return PTR_ERR(clk); | ||
447 | } | ||
448 | |||
449 | hdmi.sys_clk = clk; | ||
450 | |||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | static int hdmi_connect(struct omap_dss_device *dssdev, | 440 | static int hdmi_connect(struct omap_dss_device *dssdev, |
455 | struct omap_dss_device *dst) | 441 | struct omap_dss_device *dst) |
456 | { | 442 | { |
@@ -729,22 +715,17 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) | |||
729 | 715 | ||
730 | r = hdmi_phy_init(pdev, &hdmi.phy); | 716 | r = hdmi_phy_init(pdev, &hdmi.phy); |
731 | if (r) | 717 | if (r) |
732 | return r; | 718 | goto err; |
733 | 719 | ||
734 | r = hdmi5_core_init(pdev, &hdmi.core); | 720 | r = hdmi5_core_init(pdev, &hdmi.core); |
735 | if (r) | 721 | if (r) |
736 | return r; | 722 | goto err; |
737 | |||
738 | r = hdmi_get_clocks(pdev); | ||
739 | if (r) { | ||
740 | DSSERR("can't get clocks\n"); | ||
741 | return r; | ||
742 | } | ||
743 | 723 | ||
744 | irq = platform_get_irq(pdev, 0); | 724 | irq = platform_get_irq(pdev, 0); |
745 | if (irq < 0) { | 725 | if (irq < 0) { |
746 | DSSERR("platform_get_irq failed\n"); | 726 | DSSERR("platform_get_irq failed\n"); |
747 | return -ENODEV; | 727 | r = -ENODEV; |
728 | goto err; | ||
748 | } | 729 | } |
749 | 730 | ||
750 | r = devm_request_threaded_irq(&pdev->dev, irq, | 731 | r = devm_request_threaded_irq(&pdev->dev, irq, |
@@ -752,7 +733,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) | |||
752 | IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); | 733 | IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); |
753 | if (r) { | 734 | if (r) { |
754 | DSSERR("HDMI IRQ request failed\n"); | 735 | DSSERR("HDMI IRQ request failed\n"); |
755 | return r; | 736 | goto err; |
756 | } | 737 | } |
757 | 738 | ||
758 | pm_runtime_enable(&pdev->dev); | 739 | pm_runtime_enable(&pdev->dev); |
@@ -762,12 +743,17 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) | |||
762 | dss_debugfs_create_file("hdmi", hdmi_dump_regs); | 743 | dss_debugfs_create_file("hdmi", hdmi_dump_regs); |
763 | 744 | ||
764 | return 0; | 745 | return 0; |
746 | err: | ||
747 | hdmi_pll_uninit(&hdmi.pll); | ||
748 | return r; | ||
765 | } | 749 | } |
766 | 750 | ||
767 | static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) | 751 | static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) |
768 | { | 752 | { |
769 | hdmi_uninit_output(pdev); | 753 | hdmi_uninit_output(pdev); |
770 | 754 | ||
755 | hdmi_pll_uninit(&hdmi.pll); | ||
756 | |||
771 | pm_runtime_disable(&pdev->dev); | 757 | pm_runtime_disable(&pdev->dev); |
772 | 758 | ||
773 | return 0; | 759 | return 0; |
@@ -775,8 +761,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) | |||
775 | 761 | ||
776 | static int hdmi_runtime_suspend(struct device *dev) | 762 | static int hdmi_runtime_suspend(struct device *dev) |
777 | { | 763 | { |
778 | clk_disable_unprepare(hdmi.sys_clk); | ||
779 | |||
780 | dispc_runtime_put(); | 764 | dispc_runtime_put(); |
781 | 765 | ||
782 | return 0; | 766 | return 0; |
@@ -790,8 +774,6 @@ static int hdmi_runtime_resume(struct device *dev) | |||
790 | if (r < 0) | 774 | if (r < 0) |
791 | return r; | 775 | return r; |
792 | 776 | ||
793 | clk_prepare_enable(hdmi.sys_clk); | ||
794 | |||
795 | return 0; | 777 | return 0; |
796 | } | 778 | } |
797 | 779 | ||
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c index 92d22252f86a..87accdb59c81 100644 --- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c +++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c | |||
@@ -15,22 +15,13 @@ | |||
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/clk.h> | ||
19 | |||
18 | #include <video/omapdss.h> | 20 | #include <video/omapdss.h> |
19 | 21 | ||
20 | #include "dss.h" | 22 | #include "dss.h" |
21 | #include "hdmi.h" | 23 | #include "hdmi.h" |
22 | 24 | ||
23 | struct hdmi_pll_features { | ||
24 | bool has_refsel; | ||
25 | bool sys_reset; | ||
26 | unsigned long fint_min, fint_max; | ||
27 | u16 regm_max; | ||
28 | unsigned long dcofreq_low_min, dcofreq_low_max; | ||
29 | unsigned long dcofreq_high_min, dcofreq_high_max; | ||
30 | }; | ||
31 | |||
32 | static const struct hdmi_pll_features *pll_feat; | ||
33 | |||
34 | void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s) | 25 | void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s) |
35 | { | 26 | { |
36 | #define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\ | 27 | #define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\ |
@@ -47,25 +38,28 @@ void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s) | |||
47 | DUMPPLL(PLLCTRL_CFG4); | 38 | DUMPPLL(PLLCTRL_CFG4); |
48 | } | 39 | } |
49 | 40 | ||
50 | void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, | 41 | void hdmi_pll_compute(struct hdmi_pll_data *pll, |
51 | unsigned long target_tmds) | 42 | unsigned long target_tmds, struct dss_pll_clock_info *pi) |
52 | { | 43 | { |
53 | struct hdmi_pll_info *pi = &pll->info; | ||
54 | unsigned long fint, clkdco, clkout; | 44 | unsigned long fint, clkdco, clkout; |
55 | unsigned long target_bitclk, target_clkdco; | 45 | unsigned long target_bitclk, target_clkdco; |
56 | unsigned long min_dco; | 46 | unsigned long min_dco; |
57 | unsigned n, m, mf, m2, sd; | 47 | unsigned n, m, mf, m2, sd; |
48 | unsigned long clkin; | ||
49 | const struct dss_pll_hw *hw = pll->pll.hw; | ||
50 | |||
51 | clkin = clk_get_rate(pll->pll.clkin); | ||
58 | 52 | ||
59 | DSSDBG("clkin %lu, target tmds %lu\n", clkin, target_tmds); | 53 | DSSDBG("clkin %lu, target tmds %lu\n", clkin, target_tmds); |
60 | 54 | ||
61 | target_bitclk = target_tmds * 10; | 55 | target_bitclk = target_tmds * 10; |
62 | 56 | ||
63 | /* Fint */ | 57 | /* Fint */ |
64 | n = DIV_ROUND_UP(clkin, pll_feat->fint_max); | 58 | n = DIV_ROUND_UP(clkin, hw->fint_max); |
65 | fint = clkin / n; | 59 | fint = clkin / n; |
66 | 60 | ||
67 | /* adjust m2 so that the clkdco will be high enough */ | 61 | /* adjust m2 so that the clkdco will be high enough */ |
68 | min_dco = roundup(pll_feat->dcofreq_low_min, fint); | 62 | min_dco = roundup(hw->clkdco_min, fint); |
69 | m2 = DIV_ROUND_UP(min_dco, target_bitclk); | 63 | m2 = DIV_ROUND_UP(min_dco, target_bitclk); |
70 | if (m2 == 0) | 64 | if (m2 == 0) |
71 | m2 = 1; | 65 | m2 = 1; |
@@ -93,81 +87,20 @@ void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, | |||
93 | n, m, mf, m2, sd); | 87 | n, m, mf, m2, sd); |
94 | DSSDBG("Fint %lu, clkdco %lu, clkout %lu\n", fint, clkdco, clkout); | 88 | DSSDBG("Fint %lu, clkdco %lu, clkout %lu\n", fint, clkdco, clkout); |
95 | 89 | ||
96 | pi->regn = n; | 90 | pi->n = n; |
97 | pi->regm = m; | 91 | pi->m = m; |
98 | pi->regmf = mf; | 92 | pi->mf = mf; |
99 | pi->regm2 = m2; | 93 | pi->mX[0] = m2; |
100 | pi->regsd = sd; | 94 | pi->sd = sd; |
101 | 95 | ||
96 | pi->fint = fint; | ||
102 | pi->clkdco = clkdco; | 97 | pi->clkdco = clkdco; |
103 | pi->clkout = clkout; | 98 | pi->clkout[0] = clkout; |
104 | } | ||
105 | |||
106 | int hdmi_pll_set_config(struct hdmi_pll_data *pll) | ||
107 | { | ||
108 | u32 r; | ||
109 | struct hdmi_pll_info *fmt = &pll->info; | ||
110 | |||
111 | /* PLL start always use manual mode */ | ||
112 | REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, 0x0, 0, 0); | ||
113 | |||
114 | r = hdmi_read_reg(pll->base, PLLCTRL_CFG1); | ||
115 | r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */ | ||
116 | r = FLD_MOD(r, fmt->regn - 1, 8, 1); /* CFG1_PLL_REGN */ | ||
117 | hdmi_write_reg(pll->base, PLLCTRL_CFG1, r); | ||
118 | |||
119 | r = hdmi_read_reg(pll->base, PLLCTRL_CFG2); | ||
120 | |||
121 | r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */ | ||
122 | r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */ | ||
123 | r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */ | ||
124 | if (pll_feat->has_refsel) | ||
125 | r = FLD_MOD(r, 0x3, 22, 21); /* REFSEL = SYSCLK */ | ||
126 | |||
127 | if (fmt->clkdco > pll_feat->dcofreq_low_max) | ||
128 | r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */ | ||
129 | else | ||
130 | r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */ | ||
131 | |||
132 | hdmi_write_reg(pll->base, PLLCTRL_CFG2, r); | ||
133 | |||
134 | REG_FLD_MOD(pll->base, PLLCTRL_CFG3, fmt->regsd, 17, 10); | ||
135 | |||
136 | r = hdmi_read_reg(pll->base, PLLCTRL_CFG4); | ||
137 | r = FLD_MOD(r, fmt->regm2, 24, 18); | ||
138 | r = FLD_MOD(r, fmt->regmf, 17, 0); | ||
139 | hdmi_write_reg(pll->base, PLLCTRL_CFG4, r); | ||
140 | |||
141 | /* go now */ | ||
142 | REG_FLD_MOD(pll->base, PLLCTRL_PLL_GO, 0x1, 0, 0); | ||
143 | |||
144 | /* wait for bit change */ | ||
145 | if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_GO, | ||
146 | 0, 0, 0) != 0) { | ||
147 | DSSERR("PLL GO bit not clearing\n"); | ||
148 | return -ETIMEDOUT; | ||
149 | } | ||
150 | |||
151 | /* Wait till the lock bit is set in PLL status */ | ||
152 | if (hdmi_wait_for_bit_change(pll->base, | ||
153 | PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) { | ||
154 | DSSERR("cannot lock PLL\n"); | ||
155 | DSSERR("CFG1 0x%x\n", | ||
156 | hdmi_read_reg(pll->base, PLLCTRL_CFG1)); | ||
157 | DSSERR("CFG2 0x%x\n", | ||
158 | hdmi_read_reg(pll->base, PLLCTRL_CFG2)); | ||
159 | DSSERR("CFG4 0x%x\n", | ||
160 | hdmi_read_reg(pll->base, PLLCTRL_CFG4)); | ||
161 | return -ETIMEDOUT; | ||
162 | } | ||
163 | |||
164 | DSSDBG("PLL locked!\n"); | ||
165 | |||
166 | return 0; | ||
167 | } | 99 | } |
168 | 100 | ||
169 | int hdmi_pll_enable(struct hdmi_pll_data *pll) | 101 | static int hdmi_pll_enable(struct dss_pll *dsspll) |
170 | { | 102 | { |
103 | struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll); | ||
171 | struct hdmi_wp_data *wp = pll->wp; | 104 | struct hdmi_wp_data *wp = pll->wp; |
172 | u16 r = 0; | 105 | u16 r = 0; |
173 | 106 | ||
@@ -178,64 +111,105 @@ int hdmi_pll_enable(struct hdmi_pll_data *pll) | |||
178 | return 0; | 111 | return 0; |
179 | } | 112 | } |
180 | 113 | ||
181 | void hdmi_pll_disable(struct hdmi_pll_data *pll) | 114 | static void hdmi_pll_disable(struct dss_pll *dsspll) |
182 | { | 115 | { |
116 | struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll); | ||
183 | struct hdmi_wp_data *wp = pll->wp; | 117 | struct hdmi_wp_data *wp = pll->wp; |
184 | 118 | ||
185 | hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); | 119 | hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); |
186 | } | 120 | } |
187 | 121 | ||
188 | static const struct hdmi_pll_features omap44xx_pll_feats = { | 122 | static const struct dss_pll_ops dsi_pll_ops = { |
189 | .sys_reset = false, | 123 | .enable = hdmi_pll_enable, |
190 | .fint_min = 500000, | 124 | .disable = hdmi_pll_disable, |
191 | .fint_max = 2500000, | 125 | .set_config = dss_pll_write_config_type_b, |
192 | .regm_max = 4095, | 126 | }; |
193 | .dcofreq_low_min = 500000000, | 127 | |
194 | .dcofreq_low_max = 1000000000, | 128 | static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = { |
195 | .dcofreq_high_min = 1000000000, | 129 | .n_max = 255, |
196 | .dcofreq_high_max = 2000000000, | 130 | .m_min = 20, |
131 | .m_max = 4095, | ||
132 | .mX_max = 127, | ||
133 | .fint_min = 500000, | ||
134 | .fint_max = 2500000, | ||
135 | .clkdco_max = 1800000000, | ||
136 | |||
137 | .clkdco_min = 500000000, | ||
138 | .clkdco_low = 1000000000, | ||
139 | .clkdco_max = 2000000000, | ||
140 | |||
141 | .n_msb = 8, | ||
142 | .n_lsb = 1, | ||
143 | .m_msb = 20, | ||
144 | .m_lsb = 9, | ||
145 | |||
146 | .mX_msb[0] = 24, | ||
147 | .mX_lsb[0] = 18, | ||
148 | |||
149 | .has_selfreqdco = true, | ||
197 | }; | 150 | }; |
198 | 151 | ||
199 | static const struct hdmi_pll_features omap54xx_pll_feats = { | 152 | static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = { |
200 | .has_refsel = true, | 153 | .n_max = 255, |
201 | .sys_reset = true, | 154 | .m_min = 20, |
202 | .fint_min = 620000, | 155 | .m_max = 2045, |
203 | .fint_max = 2500000, | 156 | .mX_max = 127, |
204 | .regm_max = 2046, | 157 | .fint_min = 620000, |
205 | .dcofreq_low_min = 750000000, | 158 | .fint_max = 2500000, |
206 | .dcofreq_low_max = 1500000000, | 159 | .clkdco_max = 1800000000, |
207 | .dcofreq_high_min = 1250000000, | 160 | |
208 | .dcofreq_high_max = 2500000000UL, | 161 | .clkdco_min = 750000000, |
162 | .clkdco_low = 1500000000, | ||
163 | .clkdco_max = 2500000000UL, | ||
164 | |||
165 | .n_msb = 8, | ||
166 | .n_lsb = 1, | ||
167 | .m_msb = 20, | ||
168 | .m_lsb = 9, | ||
169 | |||
170 | .mX_msb[0] = 24, | ||
171 | .mX_lsb[0] = 18, | ||
172 | |||
173 | .has_selfreqdco = true, | ||
174 | .has_refsel = true, | ||
209 | }; | 175 | }; |
210 | 176 | ||
211 | static int hdmi_pll_init_features(struct platform_device *pdev) | 177 | static int dsi_init_pll_data(struct platform_device *pdev, struct hdmi_pll_data *hpll) |
212 | { | 178 | { |
213 | struct hdmi_pll_features *dst; | 179 | struct dss_pll *pll = &hpll->pll; |
214 | const struct hdmi_pll_features *src; | 180 | struct clk *clk; |
181 | int r; | ||
215 | 182 | ||
216 | dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL); | 183 | clk = devm_clk_get(&pdev->dev, "sys_clk"); |
217 | if (!dst) { | 184 | if (IS_ERR(clk)) { |
218 | dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n"); | 185 | DSSERR("can't get sys_clk\n"); |
219 | return -ENOMEM; | 186 | return PTR_ERR(clk); |
220 | } | 187 | } |
221 | 188 | ||
189 | pll->name = "hdmi"; | ||
190 | pll->base = hpll->base; | ||
191 | pll->clkin = clk; | ||
192 | |||
222 | switch (omapdss_get_version()) { | 193 | switch (omapdss_get_version()) { |
223 | case OMAPDSS_VER_OMAP4430_ES1: | 194 | case OMAPDSS_VER_OMAP4430_ES1: |
224 | case OMAPDSS_VER_OMAP4430_ES2: | 195 | case OMAPDSS_VER_OMAP4430_ES2: |
225 | case OMAPDSS_VER_OMAP4: | 196 | case OMAPDSS_VER_OMAP4: |
226 | src = &omap44xx_pll_feats; | 197 | pll->hw = &dss_omap4_hdmi_pll_hw; |
227 | break; | 198 | break; |
228 | 199 | ||
229 | case OMAPDSS_VER_OMAP5: | 200 | case OMAPDSS_VER_OMAP5: |
230 | src = &omap54xx_pll_feats; | 201 | pll->hw = &dss_omap5_hdmi_pll_hw; |
231 | break; | 202 | break; |
232 | 203 | ||
233 | default: | 204 | default: |
234 | return -ENODEV; | 205 | return -ENODEV; |
235 | } | 206 | } |
236 | 207 | ||
237 | memcpy(dst, src, sizeof(*dst)); | 208 | pll->ops = &dsi_pll_ops; |
238 | pll_feat = dst; | 209 | |
210 | r = dss_pll_register(pll); | ||
211 | if (r) | ||
212 | return r; | ||
239 | 213 | ||
240 | return 0; | 214 | return 0; |
241 | } | 215 | } |
@@ -248,10 +222,6 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll, | |||
248 | 222 | ||
249 | pll->wp = wp; | 223 | pll->wp = wp; |
250 | 224 | ||
251 | r = hdmi_pll_init_features(pdev); | ||
252 | if (r) | ||
253 | return r; | ||
254 | |||
255 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll"); | 225 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll"); |
256 | if (!res) { | 226 | if (!res) { |
257 | DSSERR("can't get PLL mem resource\n"); | 227 | DSSERR("can't get PLL mem resource\n"); |
@@ -264,5 +234,18 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll, | |||
264 | return PTR_ERR(pll->base); | 234 | return PTR_ERR(pll->base); |
265 | } | 235 | } |
266 | 236 | ||
237 | r = dsi_init_pll_data(pdev, pll); | ||
238 | if (r) { | ||
239 | DSSERR("failed to init HDMI PLL\n"); | ||
240 | return r; | ||
241 | } | ||
242 | |||
267 | return 0; | 243 | return 0; |
268 | } | 244 | } |
245 | |||
246 | void hdmi_pll_uninit(struct hdmi_pll_data *hpll) | ||
247 | { | ||
248 | struct dss_pll *pll = &hpll->pll; | ||
249 | |||
250 | dss_pll_unregister(pll); | ||
251 | } | ||