aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@ti.com>2014-10-22 08:02:17 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2014-11-12 06:40:27 -0500
commitc84c3a5bb78ff271787a1fec9218768aed555e8d (patch)
tree98c64021765bcaf1b5389a9082ae98487c7f9c2b /drivers/video
parentd13cbb32c50019b38fb3ab030a8ab435b6f2440a (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.h24
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4.c55
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi5.c56
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_pll.c225
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 */
188struct 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
199struct hdmi_audio_format { 187struct 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
248struct hdmi_pll_data { 236struct 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
256struct hdmi_phy_data { 244struct hdmi_phy_data {
@@ -314,14 +302,12 @@ void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
314int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp); 302int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp);
315 303
316/* HDMI PLL funcs */ 304/* HDMI PLL funcs */
317int hdmi_pll_enable(struct hdmi_pll_data *pll);
318void hdmi_pll_disable(struct hdmi_pll_data *pll);
319int hdmi_pll_set_config(struct hdmi_pll_data *pll);
320void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s); 305void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s);
321void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, 306void hdmi_pll_compute(struct hdmi_pll_data *pll,
322 unsigned long target_tmds); 307 unsigned long target_tmds, struct dss_pll_clock_info *pi);
323int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll, 308int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
324 struct hdmi_wp_data *wp); 309 struct hdmi_wp_data *wp);
310void hdmi_pll_uninit(struct hdmi_pll_data *hpll);
325 311
326/* HDMI PHY funcs */ 312/* HDMI PHY funcs */
327int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk, 313int 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);
248err_phy_pwr: 248err_phy_pwr:
249err_pll_cfg: 249err_pll_cfg:
250 hdmi_pll_disable(&hdmi.pll); 250 dss_pll_disable(&hdmi.pll.pll);
251err_pll_enable: 251err_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
410static 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
425static int hdmi_connect(struct omap_dss_device *dssdev, 410static 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;
716err:
717 hdmi_pll_uninit(&hdmi.pll);
718 return r;
736} 719}
737 720
738static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) 721static 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
747static int hdmi_runtime_suspend(struct device *dev) 732static 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:
265err_phy_pwr: 266err_phy_pwr:
266err_phy_cfg: 267err_phy_cfg:
267err_pll_cfg: 268err_pll_cfg:
268 hdmi_pll_disable(&hdmi.pll); 269 dss_pll_disable(&hdmi.pll.pll);
269err_pll_enable: 270err_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
439static 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
454static int hdmi_connect(struct omap_dss_device *dssdev, 440static 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;
746err:
747 hdmi_pll_uninit(&hdmi.pll);
748 return r;
765} 749}
766 750
767static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) 751static 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
776static int hdmi_runtime_suspend(struct device *dev) 762static 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
23struct 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
32static const struct hdmi_pll_features *pll_feat;
33
34void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s) 25void 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
50void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, 41void 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
106int 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
169int hdmi_pll_enable(struct hdmi_pll_data *pll) 101static 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
181void hdmi_pll_disable(struct hdmi_pll_data *pll) 114static 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
188static const struct hdmi_pll_features omap44xx_pll_feats = { 122static 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, 128static 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
199static const struct hdmi_pll_features omap54xx_pll_feats = { 152static 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
211static int hdmi_pll_init_features(struct platform_device *pdev) 177static 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
246void hdmi_pll_uninit(struct hdmi_pll_data *hpll)
247{
248 struct dss_pll *pll = &hpll->pll;
249
250 dss_pll_unregister(pll);
251}