aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/console/fbcon.c2
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-hdmi.c99
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c57
-rw-r--r--drivers/video/fbdev/omap2/dss/Kconfig7
-rw-r--r--drivers/video/fbdev/omap2/dss/Makefile2
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc.c20
-rw-r--r--drivers/video/fbdev/omap2/dss/dpi.c327
-rw-r--r--drivers/video/fbdev/omap2/dss/dsi.c659
-rw-r--r--drivers/video/fbdev/omap2/dss/dss-of.c58
-rw-r--r--drivers/video/fbdev/omap2/dss/dss.c123
-rw-r--r--drivers/video/fbdev/omap2/dss/dss.h225
-rw-r--r--drivers/video/fbdev/omap2/dss/dss_features.c42
-rw-r--r--drivers/video/fbdev/omap2/dss/dss_features.h12
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi.h71
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4.c338
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4_core.c14
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4_core.h4
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi5.c338
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi5_core.c11
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi5_core.h2
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_common.c2
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_phy.c31
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_pll.c313
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_wp.c16
-rw-r--r--drivers/video/fbdev/omap2/dss/output.c19
-rw-r--r--drivers/video/fbdev/omap2/dss/pll.c378
-rw-r--r--drivers/video/fbdev/omap2/dss/sdi.c2
-rw-r--r--drivers/video/fbdev/simplefb.c162
29 files changed, 1776 insertions, 1559 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index eb976ee3a02f..ea437245562e 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -3624,7 +3624,7 @@ static int __init fb_console_init(void)
3624 return 0; 3624 return 0;
3625} 3625}
3626 3626
3627module_init(fb_console_init); 3627fs_initcall(fb_console_init);
3628 3628
3629#ifdef MODULE 3629#ifdef MODULE
3630 3630
diff --git a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
index 7b25967a91eb..219f14f59672 100644
--- a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
@@ -170,98 +170,6 @@ static bool hdmic_detect(struct omap_dss_device *dssdev)
170 return in->ops.hdmi->detect(in); 170 return in->ops.hdmi->detect(in);
171} 171}
172 172
173static int hdmic_audio_enable(struct omap_dss_device *dssdev)
174{
175 struct panel_drv_data *ddata = to_panel_data(dssdev);
176 struct omap_dss_device *in = ddata->in;
177 int r;
178
179 /* enable audio only if the display is active */
180 if (!omapdss_device_is_enabled(dssdev))
181 return -EPERM;
182
183 r = in->ops.hdmi->audio_enable(in);
184 if (r)
185 return r;
186
187 dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
188
189 return 0;
190}
191
192static void hdmic_audio_disable(struct omap_dss_device *dssdev)
193{
194 struct panel_drv_data *ddata = to_panel_data(dssdev);
195 struct omap_dss_device *in = ddata->in;
196
197 in->ops.hdmi->audio_disable(in);
198
199 dssdev->audio_state = OMAP_DSS_AUDIO_DISABLED;
200}
201
202static int hdmic_audio_start(struct omap_dss_device *dssdev)
203{
204 struct panel_drv_data *ddata = to_panel_data(dssdev);
205 struct omap_dss_device *in = ddata->in;
206 int r;
207
208 /*
209 * No need to check the panel state. It was checked when trasitioning
210 * to AUDIO_ENABLED.
211 */
212 if (dssdev->audio_state != OMAP_DSS_AUDIO_ENABLED)
213 return -EPERM;
214
215 r = in->ops.hdmi->audio_start(in);
216 if (r)
217 return r;
218
219 dssdev->audio_state = OMAP_DSS_AUDIO_PLAYING;
220
221 return 0;
222}
223
224static void hdmic_audio_stop(struct omap_dss_device *dssdev)
225{
226 struct panel_drv_data *ddata = to_panel_data(dssdev);
227 struct omap_dss_device *in = ddata->in;
228
229 in->ops.hdmi->audio_stop(in);
230
231 dssdev->audio_state = OMAP_DSS_AUDIO_ENABLED;
232}
233
234static bool hdmic_audio_supported(struct omap_dss_device *dssdev)
235{
236 struct panel_drv_data *ddata = to_panel_data(dssdev);
237 struct omap_dss_device *in = ddata->in;
238
239 if (!omapdss_device_is_enabled(dssdev))
240 return false;
241
242 return in->ops.hdmi->audio_supported(in);
243}
244
245static int hdmic_audio_config(struct omap_dss_device *dssdev,
246 struct omap_dss_audio *audio)
247{
248 struct panel_drv_data *ddata = to_panel_data(dssdev);
249 struct omap_dss_device *in = ddata->in;
250 int r;
251
252 /* config audio only if the display is active */
253 if (!omapdss_device_is_enabled(dssdev))
254 return -EPERM;
255
256 r = in->ops.hdmi->audio_config(in, audio);
257 if (r)
258 return r;
259
260 dssdev->audio_state = OMAP_DSS_AUDIO_CONFIGURED;
261
262 return 0;
263}
264
265static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode) 173static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode)
266{ 174{
267 struct panel_drv_data *ddata = to_panel_data(dssdev); 175 struct panel_drv_data *ddata = to_panel_data(dssdev);
@@ -296,13 +204,6 @@ static struct omap_dss_driver hdmic_driver = {
296 .detect = hdmic_detect, 204 .detect = hdmic_detect,
297 .set_hdmi_mode = hdmic_set_hdmi_mode, 205 .set_hdmi_mode = hdmic_set_hdmi_mode,
298 .set_hdmi_infoframe = hdmic_set_infoframe, 206 .set_hdmi_infoframe = hdmic_set_infoframe,
299
300 .audio_enable = hdmic_audio_enable,
301 .audio_disable = hdmic_audio_disable,
302 .audio_start = hdmic_audio_start,
303 .audio_stop = hdmic_audio_stop,
304 .audio_supported = hdmic_audio_supported,
305 .audio_config = hdmic_audio_config,
306}; 207};
307 208
308static int hdmic_probe_pdata(struct platform_device *pdev) 209static int hdmic_probe_pdata(struct platform_device *pdev)
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
index 47ee7cdee1c5..e349064ed615 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
@@ -249,6 +249,7 @@ static int tfp410_probe(struct platform_device *pdev)
249 dssdev->output_type = OMAP_DISPLAY_TYPE_DVI; 249 dssdev->output_type = OMAP_DISPLAY_TYPE_DVI;
250 dssdev->owner = THIS_MODULE; 250 dssdev->owner = THIS_MODULE;
251 dssdev->phy.dpi.data_lines = ddata->data_lines; 251 dssdev->phy.dpi.data_lines = ddata->data_lines;
252 dssdev->port_num = 1;
252 253
253 r = omapdss_register_output(dssdev); 254 r = omapdss_register_output(dssdev);
254 if (r) { 255 if (r) {
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
index c4abd56dd846..c7a3ce2c5120 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
@@ -193,55 +193,6 @@ static bool tpd_detect(struct omap_dss_device *dssdev)
193 return gpio_get_value_cansleep(ddata->hpd_gpio); 193 return gpio_get_value_cansleep(ddata->hpd_gpio);
194} 194}
195 195
196static int tpd_audio_enable(struct omap_dss_device *dssdev)
197{
198 struct panel_drv_data *ddata = to_panel_data(dssdev);
199 struct omap_dss_device *in = ddata->in;
200
201 return in->ops.hdmi->audio_enable(in);
202}
203
204static void tpd_audio_disable(struct omap_dss_device *dssdev)
205{
206 struct panel_drv_data *ddata = to_panel_data(dssdev);
207 struct omap_dss_device *in = ddata->in;
208
209 in->ops.hdmi->audio_disable(in);
210}
211
212static int tpd_audio_start(struct omap_dss_device *dssdev)
213{
214 struct panel_drv_data *ddata = to_panel_data(dssdev);
215 struct omap_dss_device *in = ddata->in;
216
217 return in->ops.hdmi->audio_start(in);
218}
219
220static void tpd_audio_stop(struct omap_dss_device *dssdev)
221{
222 struct panel_drv_data *ddata = to_panel_data(dssdev);
223 struct omap_dss_device *in = ddata->in;
224
225 in->ops.hdmi->audio_stop(in);
226}
227
228static bool tpd_audio_supported(struct omap_dss_device *dssdev)
229{
230 struct panel_drv_data *ddata = to_panel_data(dssdev);
231 struct omap_dss_device *in = ddata->in;
232
233 return in->ops.hdmi->audio_supported(in);
234}
235
236static int tpd_audio_config(struct omap_dss_device *dssdev,
237 struct omap_dss_audio *audio)
238{
239 struct panel_drv_data *ddata = to_panel_data(dssdev);
240 struct omap_dss_device *in = ddata->in;
241
242 return in->ops.hdmi->audio_config(in, audio);
243}
244
245static int tpd_set_infoframe(struct omap_dss_device *dssdev, 196static int tpd_set_infoframe(struct omap_dss_device *dssdev,
246 const struct hdmi_avi_infoframe *avi) 197 const struct hdmi_avi_infoframe *avi)
247{ 198{
@@ -275,13 +226,6 @@ static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
275 .detect = tpd_detect, 226 .detect = tpd_detect,
276 .set_infoframe = tpd_set_infoframe, 227 .set_infoframe = tpd_set_infoframe,
277 .set_hdmi_mode = tpd_set_hdmi_mode, 228 .set_hdmi_mode = tpd_set_hdmi_mode,
278
279 .audio_enable = tpd_audio_enable,
280 .audio_disable = tpd_audio_disable,
281 .audio_start = tpd_audio_start,
282 .audio_stop = tpd_audio_stop,
283 .audio_supported = tpd_audio_supported,
284 .audio_config = tpd_audio_config,
285}; 229};
286 230
287static int tpd_probe_pdata(struct platform_device *pdev) 231static int tpd_probe_pdata(struct platform_device *pdev)
@@ -409,6 +353,7 @@ static int tpd_probe(struct platform_device *pdev)
409 dssdev->type = OMAP_DISPLAY_TYPE_HDMI; 353 dssdev->type = OMAP_DISPLAY_TYPE_HDMI;
410 dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI; 354 dssdev->output_type = OMAP_DISPLAY_TYPE_HDMI;
411 dssdev->owner = THIS_MODULE; 355 dssdev->owner = THIS_MODULE;
356 dssdev->port_num = 1;
412 357
413 in = ddata->in; 358 in = ddata->in;
414 359
diff --git a/drivers/video/fbdev/omap2/dss/Kconfig b/drivers/video/fbdev/omap2/dss/Kconfig
index 3d5eb6c36c22..d1fa730c7d54 100644
--- a/drivers/video/fbdev/omap2/dss/Kconfig
+++ b/drivers/video/fbdev/omap2/dss/Kconfig
@@ -74,9 +74,6 @@ config OMAP4_DSS_HDMI
74 help 74 help
75 HDMI support for OMAP4 based SoCs. 75 HDMI support for OMAP4 based SoCs.
76 76
77config OMAP4_DSS_HDMI_AUDIO
78 bool
79
80config OMAP5_DSS_HDMI 77config OMAP5_DSS_HDMI
81 bool "HDMI support for OMAP5" 78 bool "HDMI support for OMAP5"
82 default n 79 default n
@@ -86,10 +83,6 @@ config OMAP5_DSS_HDMI
86 Definition Multimedia Interface. See http://www.hdmi.org/ for HDMI 83 Definition Multimedia Interface. See http://www.hdmi.org/ for HDMI
87 specification. 84 specification.
88 85
89config OMAP5_DSS_HDMI_AUDIO
90 depends on OMAP5_DSS_HDMI
91 bool
92
93config OMAP2_DSS_SDI 86config OMAP2_DSS_SDI
94 bool "SDI support" 87 bool "SDI support"
95 default n 88 default n
diff --git a/drivers/video/fbdev/omap2/dss/Makefile b/drivers/video/fbdev/omap2/dss/Makefile
index 245f933060ee..2ea9d382354c 100644
--- a/drivers/video/fbdev/omap2/dss/Makefile
+++ b/drivers/video/fbdev/omap2/dss/Makefile
@@ -2,7 +2,7 @@ obj-$(CONFIG_OMAP2_DSS_INIT) += omapdss-boot-init.o
2obj-$(CONFIG_OMAP2_DSS) += omapdss.o 2obj-$(CONFIG_OMAP2_DSS) += omapdss.o
3# Core DSS files 3# Core DSS files
4omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ 4omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
5 output.o dss-of.o 5 output.o dss-of.o pll.o
6# DSS compat layer files 6# DSS compat layer files
7omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \ 7omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \
8 dispc-compat.o display-sysfs.o 8 dispc-compat.o display-sysfs.o
diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 0e9a74bb9fc2..0729c08ac75a 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -3028,7 +3028,7 @@ static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div,
3028 3028
3029unsigned long dispc_fclk_rate(void) 3029unsigned long dispc_fclk_rate(void)
3030{ 3030{
3031 struct platform_device *dsidev; 3031 struct dss_pll *pll;
3032 unsigned long r = 0; 3032 unsigned long r = 0;
3033 3033
3034 switch (dss_get_dispc_clk_source()) { 3034 switch (dss_get_dispc_clk_source()) {
@@ -3036,12 +3036,12 @@ unsigned long dispc_fclk_rate(void)
3036 r = dss_get_dispc_clk_rate(); 3036 r = dss_get_dispc_clk_rate();
3037 break; 3037 break;
3038 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 3038 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
3039 dsidev = dsi_get_dsidev_from_id(0); 3039 pll = dss_pll_find("dsi0");
3040 r = dsi_get_pll_hsdiv_dispc_rate(dsidev); 3040 r = pll->cinfo.clkout[0];
3041 break; 3041 break;
3042 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: 3042 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
3043 dsidev = dsi_get_dsidev_from_id(1); 3043 pll = dss_pll_find("dsi1");
3044 r = dsi_get_pll_hsdiv_dispc_rate(dsidev); 3044 r = pll->cinfo.clkout[0];
3045 break; 3045 break;
3046 default: 3046 default:
3047 BUG(); 3047 BUG();
@@ -3053,7 +3053,7 @@ unsigned long dispc_fclk_rate(void)
3053 3053
3054unsigned long dispc_mgr_lclk_rate(enum omap_channel channel) 3054unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
3055{ 3055{
3056 struct platform_device *dsidev; 3056 struct dss_pll *pll;
3057 int lcd; 3057 int lcd;
3058 unsigned long r; 3058 unsigned long r;
3059 u32 l; 3059 u32 l;
@@ -3068,12 +3068,12 @@ unsigned long dispc_mgr_lclk_rate(enum omap_channel channel)
3068 r = dss_get_dispc_clk_rate(); 3068 r = dss_get_dispc_clk_rate();
3069 break; 3069 break;
3070 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 3070 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
3071 dsidev = dsi_get_dsidev_from_id(0); 3071 pll = dss_pll_find("dsi0");
3072 r = dsi_get_pll_hsdiv_dispc_rate(dsidev); 3072 r = pll->cinfo.clkout[0];
3073 break; 3073 break;
3074 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: 3074 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
3075 dsidev = dsi_get_dsidev_from_id(1); 3075 pll = dss_pll_find("dsi1");
3076 r = dsi_get_pll_hsdiv_dispc_rate(dsidev); 3076 r = pll->cinfo.clkout[0];
3077 break; 3077 break;
3078 default: 3078 default:
3079 BUG(); 3079 BUG();
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index 4a3363dae74a..2edf5caa002f 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -31,17 +31,20 @@
31#include <linux/regulator/consumer.h> 31#include <linux/regulator/consumer.h>
32#include <linux/string.h> 32#include <linux/string.h>
33#include <linux/of.h> 33#include <linux/of.h>
34#include <linux/clk.h>
34 35
35#include <video/omapdss.h> 36#include <video/omapdss.h>
36 37
37#include "dss.h" 38#include "dss.h"
38#include "dss_features.h" 39#include "dss_features.h"
39 40
40static struct { 41#define HSDIV_DISPC 0
42
43struct dpi_data {
41 struct platform_device *pdev; 44 struct platform_device *pdev;
42 45
43 struct regulator *vdds_dsi_reg; 46 struct regulator *vdds_dsi_reg;
44 struct platform_device *dsidev; 47 struct dss_pll *pll;
45 48
46 struct mutex lock; 49 struct mutex lock;
47 50
@@ -52,9 +55,20 @@ static struct {
52 struct omap_dss_device output; 55 struct omap_dss_device output;
53 56
54 bool port_initialized; 57 bool port_initialized;
55} dpi; 58};
59
60static struct dpi_data *dpi_get_data_from_dssdev(struct omap_dss_device *dssdev)
61{
62 return container_of(dssdev, struct dpi_data, output);
63}
64
65/* only used in non-DT mode */
66static struct dpi_data *dpi_get_data_from_pdev(struct platform_device *pdev)
67{
68 return dev_get_drvdata(&pdev->dev);
69}
56 70
57static struct platform_device *dpi_get_dsidev(enum omap_channel channel) 71static struct dss_pll *dpi_get_pll(enum omap_channel channel)
58{ 72{
59 /* 73 /*
60 * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL 74 * XXX we can't currently use DSI PLL for DPI with OMAP3, as the DSI PLL
@@ -75,9 +89,9 @@ static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
75 case OMAPDSS_VER_OMAP4: 89 case OMAPDSS_VER_OMAP4:
76 switch (channel) { 90 switch (channel) {
77 case OMAP_DSS_CHANNEL_LCD: 91 case OMAP_DSS_CHANNEL_LCD:
78 return dsi_get_dsidev_from_id(0); 92 return dss_pll_find("dsi0");
79 case OMAP_DSS_CHANNEL_LCD2: 93 case OMAP_DSS_CHANNEL_LCD2:
80 return dsi_get_dsidev_from_id(1); 94 return dss_pll_find("dsi1");
81 default: 95 default:
82 return NULL; 96 return NULL;
83 } 97 }
@@ -85,9 +99,9 @@ static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
85 case OMAPDSS_VER_OMAP5: 99 case OMAPDSS_VER_OMAP5:
86 switch (channel) { 100 switch (channel) {
87 case OMAP_DSS_CHANNEL_LCD: 101 case OMAP_DSS_CHANNEL_LCD:
88 return dsi_get_dsidev_from_id(0); 102 return dss_pll_find("dsi0");
89 case OMAP_DSS_CHANNEL_LCD3: 103 case OMAP_DSS_CHANNEL_LCD3:
90 return dsi_get_dsidev_from_id(1); 104 return dss_pll_find("dsi1");
91 default: 105 default:
92 return NULL; 106 return NULL;
93 } 107 }
@@ -114,7 +128,7 @@ static enum omap_dss_clk_source dpi_get_alt_clk_src(enum omap_channel channel)
114} 128}
115 129
116struct dpi_clk_calc_ctx { 130struct dpi_clk_calc_ctx {
117 struct platform_device *dsidev; 131 struct dss_pll *pll;
118 132
119 /* inputs */ 133 /* inputs */
120 134
@@ -122,7 +136,7 @@ struct dpi_clk_calc_ctx {
122 136
123 /* outputs */ 137 /* outputs */
124 138
125 struct dsi_clock_info dsi_cinfo; 139 struct dss_pll_clock_info dsi_cinfo;
126 unsigned long fck; 140 unsigned long fck;
127 struct dispc_clock_info dispc_cinfo; 141 struct dispc_clock_info dispc_cinfo;
128}; 142};
@@ -154,7 +168,7 @@ static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
154} 168}
155 169
156 170
157static bool dpi_calc_hsdiv_cb(int regm_dispc, unsigned long dispc, 171static bool dpi_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
158 void *data) 172 void *data)
159{ 173{
160 struct dpi_clk_calc_ctx *ctx = data; 174 struct dpi_clk_calc_ctx *ctx = data;
@@ -164,30 +178,31 @@ static bool dpi_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
164 * shifted. So skip all odd dividers when the pixel clock is on the 178 * shifted. So skip all odd dividers when the pixel clock is on the
165 * higher side. 179 * higher side.
166 */ 180 */
167 if (regm_dispc > 1 && regm_dispc % 2 != 0 && ctx->pck_min >= 100000000) 181 if (m_dispc > 1 && m_dispc % 2 != 0 && ctx->pck_min >= 100000000)
168 return false; 182 return false;
169 183
170 ctx->dsi_cinfo.regm_dispc = regm_dispc; 184 ctx->dsi_cinfo.mX[HSDIV_DISPC] = m_dispc;
171 ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc; 185 ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc;
172 186
173 return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max, 187 return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max,
174 dpi_calc_dispc_cb, ctx); 188 dpi_calc_dispc_cb, ctx);
175} 189}
176 190
177 191
178static bool dpi_calc_pll_cb(int regn, int regm, unsigned long fint, 192static bool dpi_calc_pll_cb(int n, int m, unsigned long fint,
179 unsigned long pll, 193 unsigned long clkdco,
180 void *data) 194 void *data)
181{ 195{
182 struct dpi_clk_calc_ctx *ctx = data; 196 struct dpi_clk_calc_ctx *ctx = data;
183 197
184 ctx->dsi_cinfo.regn = regn; 198 ctx->dsi_cinfo.n = n;
185 ctx->dsi_cinfo.regm = regm; 199 ctx->dsi_cinfo.m = m;
186 ctx->dsi_cinfo.fint = fint; 200 ctx->dsi_cinfo.fint = fint;
187 ctx->dsi_cinfo.clkin4ddr = pll; 201 ctx->dsi_cinfo.clkdco = clkdco;
188 202
189 return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->pck_min, 203 return dss_pll_hsdiv_calc(ctx->pll, clkdco,
190 dpi_calc_hsdiv_cb, ctx); 204 ctx->pck_min, dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
205 dpi_calc_hsdiv_cb, ctx);
191} 206}
192 207
193static bool dpi_calc_dss_cb(unsigned long fck, void *data) 208static bool dpi_calc_dss_cb(unsigned long fck, void *data)
@@ -200,23 +215,23 @@ static bool dpi_calc_dss_cb(unsigned long fck, void *data)
200 dpi_calc_dispc_cb, ctx); 215 dpi_calc_dispc_cb, ctx);
201} 216}
202 217
203static bool dpi_dsi_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx) 218static bool dpi_dsi_clk_calc(struct dpi_data *dpi, unsigned long pck,
219 struct dpi_clk_calc_ctx *ctx)
204{ 220{
205 unsigned long clkin; 221 unsigned long clkin;
206 unsigned long pll_min, pll_max; 222 unsigned long pll_min, pll_max;
207 223
208 clkin = dsi_get_pll_clkin(dpi.dsidev);
209
210 memset(ctx, 0, sizeof(*ctx)); 224 memset(ctx, 0, sizeof(*ctx));
211 ctx->dsidev = dpi.dsidev; 225 ctx->pll = dpi->pll;
212 ctx->pck_min = pck - 1000; 226 ctx->pck_min = pck - 1000;
213 ctx->pck_max = pck + 1000; 227 ctx->pck_max = pck + 1000;
214 ctx->dsi_cinfo.clkin = clkin;
215 228
216 pll_min = 0; 229 pll_min = 0;
217 pll_max = 0; 230 pll_max = 0;
218 231
219 return dsi_pll_calc(dpi.dsidev, clkin, 232 clkin = clk_get_rate(ctx->pll->clkin);
233
234 return dss_pll_calc(ctx->pll, clkin,
220 pll_min, pll_max, 235 pll_min, pll_max,
221 dpi_calc_pll_cb, ctx); 236 dpi_calc_pll_cb, ctx);
222} 237}
@@ -252,7 +267,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
252 267
253 268
254 269
255static int dpi_set_dsi_clk(enum omap_channel channel, 270static int dpi_set_dsi_clk(struct dpi_data *dpi, enum omap_channel channel,
256 unsigned long pck_req, unsigned long *fck, int *lck_div, 271 unsigned long pck_req, unsigned long *fck, int *lck_div,
257 int *pck_div) 272 int *pck_div)
258{ 273{
@@ -260,28 +275,28 @@ static int dpi_set_dsi_clk(enum omap_channel channel,
260 int r; 275 int r;
261 bool ok; 276 bool ok;
262 277
263 ok = dpi_dsi_clk_calc(pck_req, &ctx); 278 ok = dpi_dsi_clk_calc(dpi, pck_req, &ctx);
264 if (!ok) 279 if (!ok)
265 return -EINVAL; 280 return -EINVAL;
266 281
267 r = dsi_pll_set_clock_div(dpi.dsidev, &ctx.dsi_cinfo); 282 r = dss_pll_set_config(dpi->pll, &ctx.dsi_cinfo);
268 if (r) 283 if (r)
269 return r; 284 return r;
270 285
271 dss_select_lcd_clk_source(channel, 286 dss_select_lcd_clk_source(channel,
272 dpi_get_alt_clk_src(channel)); 287 dpi_get_alt_clk_src(channel));
273 288
274 dpi.mgr_config.clock_info = ctx.dispc_cinfo; 289 dpi->mgr_config.clock_info = ctx.dispc_cinfo;
275 290
276 *fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 291 *fck = ctx.dsi_cinfo.clkout[HSDIV_DISPC];
277 *lck_div = ctx.dispc_cinfo.lck_div; 292 *lck_div = ctx.dispc_cinfo.lck_div;
278 *pck_div = ctx.dispc_cinfo.pck_div; 293 *pck_div = ctx.dispc_cinfo.pck_div;
279 294
280 return 0; 295 return 0;
281} 296}
282 297
283static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck, 298static int dpi_set_dispc_clk(struct dpi_data *dpi, unsigned long pck_req,
284 int *lck_div, int *pck_div) 299 unsigned long *fck, int *lck_div, int *pck_div)
285{ 300{
286 struct dpi_clk_calc_ctx ctx; 301 struct dpi_clk_calc_ctx ctx;
287 int r; 302 int r;
@@ -295,7 +310,7 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
295 if (r) 310 if (r)
296 return r; 311 return r;
297 312
298 dpi.mgr_config.clock_info = ctx.dispc_cinfo; 313 dpi->mgr_config.clock_info = ctx.dispc_cinfo;
299 314
300 *fck = ctx.fck; 315 *fck = ctx.fck;
301 *lck_div = ctx.dispc_cinfo.lck_div; 316 *lck_div = ctx.dispc_cinfo.lck_div;
@@ -304,19 +319,21 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
304 return 0; 319 return 0;
305} 320}
306 321
307static int dpi_set_mode(struct omap_overlay_manager *mgr) 322static int dpi_set_mode(struct dpi_data *dpi)
308{ 323{
309 struct omap_video_timings *t = &dpi.timings; 324 struct omap_dss_device *out = &dpi->output;
325 struct omap_overlay_manager *mgr = out->manager;
326 struct omap_video_timings *t = &dpi->timings;
310 int lck_div = 0, pck_div = 0; 327 int lck_div = 0, pck_div = 0;
311 unsigned long fck = 0; 328 unsigned long fck = 0;
312 unsigned long pck; 329 unsigned long pck;
313 int r = 0; 330 int r = 0;
314 331
315 if (dpi.dsidev) 332 if (dpi->pll)
316 r = dpi_set_dsi_clk(mgr->id, t->pixelclock, &fck, 333 r = dpi_set_dsi_clk(dpi, mgr->id, t->pixelclock, &fck,
317 &lck_div, &pck_div); 334 &lck_div, &pck_div);
318 else 335 else
319 r = dpi_set_dispc_clk(t->pixelclock, &fck, 336 r = dpi_set_dispc_clk(dpi, t->pixelclock, &fck,
320 &lck_div, &pck_div); 337 &lck_div, &pck_div);
321 if (r) 338 if (r)
322 return r; 339 return r;
@@ -335,28 +352,32 @@ static int dpi_set_mode(struct omap_overlay_manager *mgr)
335 return 0; 352 return 0;
336} 353}
337 354
338static void dpi_config_lcd_manager(struct omap_overlay_manager *mgr) 355static void dpi_config_lcd_manager(struct dpi_data *dpi)
339{ 356{
340 dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; 357 struct omap_dss_device *out = &dpi->output;
358 struct omap_overlay_manager *mgr = out->manager;
359
360 dpi->mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
341 361
342 dpi.mgr_config.stallmode = false; 362 dpi->mgr_config.stallmode = false;
343 dpi.mgr_config.fifohandcheck = false; 363 dpi->mgr_config.fifohandcheck = false;
344 364
345 dpi.mgr_config.video_port_width = dpi.data_lines; 365 dpi->mgr_config.video_port_width = dpi->data_lines;
346 366
347 dpi.mgr_config.lcden_sig_polarity = 0; 367 dpi->mgr_config.lcden_sig_polarity = 0;
348 368
349 dss_mgr_set_lcd_config(mgr, &dpi.mgr_config); 369 dss_mgr_set_lcd_config(mgr, &dpi->mgr_config);
350} 370}
351 371
352static int dpi_display_enable(struct omap_dss_device *dssdev) 372static int dpi_display_enable(struct omap_dss_device *dssdev)
353{ 373{
354 struct omap_dss_device *out = &dpi.output; 374 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
375 struct omap_dss_device *out = &dpi->output;
355 int r; 376 int r;
356 377
357 mutex_lock(&dpi.lock); 378 mutex_lock(&dpi->lock);
358 379
359 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi.vdds_dsi_reg) { 380 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && !dpi->vdds_dsi_reg) {
360 DSSERR("no VDSS_DSI regulator\n"); 381 DSSERR("no VDSS_DSI regulator\n");
361 r = -ENODEV; 382 r = -ENODEV;
362 goto err_no_reg; 383 goto err_no_reg;
@@ -369,7 +390,7 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
369 } 390 }
370 391
371 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) { 392 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
372 r = regulator_enable(dpi.vdds_dsi_reg); 393 r = regulator_enable(dpi->vdds_dsi_reg);
373 if (r) 394 if (r)
374 goto err_reg_enable; 395 goto err_reg_enable;
375 } 396 }
@@ -378,25 +399,21 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
378 if (r) 399 if (r)
379 goto err_get_dispc; 400 goto err_get_dispc;
380 401
381 r = dss_dpi_select_source(out->manager->id); 402 r = dss_dpi_select_source(out->port_num, out->manager->id);
382 if (r) 403 if (r)
383 goto err_src_sel; 404 goto err_src_sel;
384 405
385 if (dpi.dsidev) { 406 if (dpi->pll) {
386 r = dsi_runtime_get(dpi.dsidev); 407 r = dss_pll_enable(dpi->pll);
387 if (r)
388 goto err_get_dsi;
389
390 r = dsi_pll_init(dpi.dsidev, 0, 1);
391 if (r) 408 if (r)
392 goto err_dsi_pll_init; 409 goto err_dsi_pll_init;
393 } 410 }
394 411
395 r = dpi_set_mode(out->manager); 412 r = dpi_set_mode(dpi);
396 if (r) 413 if (r)
397 goto err_set_mode; 414 goto err_set_mode;
398 415
399 dpi_config_lcd_manager(out->manager); 416 dpi_config_lcd_manager(dpi);
400 417
401 mdelay(2); 418 mdelay(2);
402 419
@@ -404,78 +421,80 @@ static int dpi_display_enable(struct omap_dss_device *dssdev)
404 if (r) 421 if (r)
405 goto err_mgr_enable; 422 goto err_mgr_enable;
406 423
407 mutex_unlock(&dpi.lock); 424 mutex_unlock(&dpi->lock);
408 425
409 return 0; 426 return 0;
410 427
411err_mgr_enable: 428err_mgr_enable:
412err_set_mode: 429err_set_mode:
413 if (dpi.dsidev) 430 if (dpi->pll)
414 dsi_pll_uninit(dpi.dsidev, true); 431 dss_pll_disable(dpi->pll);
415err_dsi_pll_init: 432err_dsi_pll_init:
416 if (dpi.dsidev)
417 dsi_runtime_put(dpi.dsidev);
418err_get_dsi:
419err_src_sel: 433err_src_sel:
420 dispc_runtime_put(); 434 dispc_runtime_put();
421err_get_dispc: 435err_get_dispc:
422 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) 436 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
423 regulator_disable(dpi.vdds_dsi_reg); 437 regulator_disable(dpi->vdds_dsi_reg);
424err_reg_enable: 438err_reg_enable:
425err_no_out_mgr: 439err_no_out_mgr:
426err_no_reg: 440err_no_reg:
427 mutex_unlock(&dpi.lock); 441 mutex_unlock(&dpi->lock);
428 return r; 442 return r;
429} 443}
430 444
431static void dpi_display_disable(struct omap_dss_device *dssdev) 445static void dpi_display_disable(struct omap_dss_device *dssdev)
432{ 446{
433 struct omap_overlay_manager *mgr = dpi.output.manager; 447 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
448 struct omap_overlay_manager *mgr = dpi->output.manager;
434 449
435 mutex_lock(&dpi.lock); 450 mutex_lock(&dpi->lock);
436 451
437 dss_mgr_disable(mgr); 452 dss_mgr_disable(mgr);
438 453
439 if (dpi.dsidev) { 454 if (dpi->pll) {
440 dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK); 455 dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
441 dsi_pll_uninit(dpi.dsidev, true); 456 dss_pll_disable(dpi->pll);
442 dsi_runtime_put(dpi.dsidev);
443 } 457 }
444 458
445 dispc_runtime_put(); 459 dispc_runtime_put();
446 460
447 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) 461 if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
448 regulator_disable(dpi.vdds_dsi_reg); 462 regulator_disable(dpi->vdds_dsi_reg);
449 463
450 mutex_unlock(&dpi.lock); 464 mutex_unlock(&dpi->lock);
451} 465}
452 466
453static void dpi_set_timings(struct omap_dss_device *dssdev, 467static void dpi_set_timings(struct omap_dss_device *dssdev,
454 struct omap_video_timings *timings) 468 struct omap_video_timings *timings)
455{ 469{
470 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
471
456 DSSDBG("dpi_set_timings\n"); 472 DSSDBG("dpi_set_timings\n");
457 473
458 mutex_lock(&dpi.lock); 474 mutex_lock(&dpi->lock);
459 475
460 dpi.timings = *timings; 476 dpi->timings = *timings;
461 477
462 mutex_unlock(&dpi.lock); 478 mutex_unlock(&dpi->lock);
463} 479}
464 480
465static void dpi_get_timings(struct omap_dss_device *dssdev, 481static void dpi_get_timings(struct omap_dss_device *dssdev,
466 struct omap_video_timings *timings) 482 struct omap_video_timings *timings)
467{ 483{
468 mutex_lock(&dpi.lock); 484 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
485
486 mutex_lock(&dpi->lock);
469 487
470 *timings = dpi.timings; 488 *timings = dpi->timings;
471 489
472 mutex_unlock(&dpi.lock); 490 mutex_unlock(&dpi->lock);
473} 491}
474 492
475static int dpi_check_timings(struct omap_dss_device *dssdev, 493static int dpi_check_timings(struct omap_dss_device *dssdev,
476 struct omap_video_timings *timings) 494 struct omap_video_timings *timings)
477{ 495{
478 struct omap_overlay_manager *mgr = dpi.output.manager; 496 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
497 struct omap_overlay_manager *mgr = dpi->output.manager;
479 int lck_div, pck_div; 498 int lck_div, pck_div;
480 unsigned long fck; 499 unsigned long fck;
481 unsigned long pck; 500 unsigned long pck;
@@ -488,12 +507,12 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
488 if (timings->pixelclock == 0) 507 if (timings->pixelclock == 0)
489 return -EINVAL; 508 return -EINVAL;
490 509
491 if (dpi.dsidev) { 510 if (dpi->pll) {
492 ok = dpi_dsi_clk_calc(timings->pixelclock, &ctx); 511 ok = dpi_dsi_clk_calc(dpi, timings->pixelclock, &ctx);
493 if (!ok) 512 if (!ok)
494 return -EINVAL; 513 return -EINVAL;
495 514
496 fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 515 fck = ctx.dsi_cinfo.clkout[HSDIV_DISPC];
497 } else { 516 } else {
498 ok = dpi_dss_clk_calc(timings->pixelclock, &ctx); 517 ok = dpi_dss_clk_calc(timings->pixelclock, &ctx);
499 if (!ok) 518 if (!ok)
@@ -514,74 +533,69 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
514 533
515static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines) 534static void dpi_set_data_lines(struct omap_dss_device *dssdev, int data_lines)
516{ 535{
517 mutex_lock(&dpi.lock); 536 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
518 537
519 dpi.data_lines = data_lines; 538 mutex_lock(&dpi->lock);
520 539
521 mutex_unlock(&dpi.lock); 540 dpi->data_lines = data_lines;
541
542 mutex_unlock(&dpi->lock);
522} 543}
523 544
524static int dpi_verify_dsi_pll(struct platform_device *dsidev) 545static int dpi_verify_dsi_pll(struct dss_pll *pll)
525{ 546{
526 int r; 547 int r;
527 548
528 /* do initial setup with the PLL to see if it is operational */ 549 /* do initial setup with the PLL to see if it is operational */
529 550
530 r = dsi_runtime_get(dsidev); 551 r = dss_pll_enable(pll);
531 if (r) 552 if (r)
532 return r; 553 return r;
533 554
534 r = dsi_pll_init(dsidev, 0, 1); 555 dss_pll_disable(pll);
535 if (r) {
536 dsi_runtime_put(dsidev);
537 return r;
538 }
539
540 dsi_pll_uninit(dsidev, true);
541 dsi_runtime_put(dsidev);
542 556
543 return 0; 557 return 0;
544} 558}
545 559
546static int dpi_init_regulator(void) 560static int dpi_init_regulator(struct dpi_data *dpi)
547{ 561{
548 struct regulator *vdds_dsi; 562 struct regulator *vdds_dsi;
549 563
550 if (!dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) 564 if (!dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
551 return 0; 565 return 0;
552 566
553 if (dpi.vdds_dsi_reg) 567 if (dpi->vdds_dsi_reg)
554 return 0; 568 return 0;
555 569
556 vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi"); 570 vdds_dsi = devm_regulator_get(&dpi->pdev->dev, "vdds_dsi");
557 if (IS_ERR(vdds_dsi)) { 571 if (IS_ERR(vdds_dsi)) {
558 if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER) 572 if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
559 DSSERR("can't get VDDS_DSI regulator\n"); 573 DSSERR("can't get VDDS_DSI regulator\n");
560 return PTR_ERR(vdds_dsi); 574 return PTR_ERR(vdds_dsi);
561 } 575 }
562 576
563 dpi.vdds_dsi_reg = vdds_dsi; 577 dpi->vdds_dsi_reg = vdds_dsi;
564 578
565 return 0; 579 return 0;
566} 580}
567 581
568static void dpi_init_pll(void) 582static void dpi_init_pll(struct dpi_data *dpi)
569{ 583{
570 struct platform_device *dsidev; 584 struct dss_pll *pll;
571 585
572 if (dpi.dsidev) 586 if (dpi->pll)
573 return; 587 return;
574 588
575 dsidev = dpi_get_dsidev(dpi.output.dispc_channel); 589 pll = dpi_get_pll(dpi->output.dispc_channel);
576 if (!dsidev) 590 if (!pll)
577 return; 591 return;
578 592
579 if (dpi_verify_dsi_pll(dsidev)) { 593 if (dpi_verify_dsi_pll(pll)) {
580 DSSWARN("DSI PLL not operational\n"); 594 DSSWARN("DSI PLL not operational\n");
581 return; 595 return;
582 } 596 }
583 597
584 dpi.dsidev = dsidev; 598 dpi->pll = pll;
585} 599}
586 600
587/* 601/*
@@ -590,7 +604,7 @@ static void dpi_init_pll(void)
590 * the channel in some more dynamic manner, or get the channel as a user 604 * the channel in some more dynamic manner, or get the channel as a user
591 * parameter. 605 * parameter.
592 */ 606 */
593static enum omap_channel dpi_get_channel(void) 607static enum omap_channel dpi_get_channel(int port_num)
594{ 608{
595 switch (omapdss_get_version()) { 609 switch (omapdss_get_version()) {
596 case OMAPDSS_VER_OMAP24xx: 610 case OMAPDSS_VER_OMAP24xx:
@@ -618,14 +632,15 @@ static enum omap_channel dpi_get_channel(void)
618static int dpi_connect(struct omap_dss_device *dssdev, 632static int dpi_connect(struct omap_dss_device *dssdev,
619 struct omap_dss_device *dst) 633 struct omap_dss_device *dst)
620{ 634{
635 struct dpi_data *dpi = dpi_get_data_from_dssdev(dssdev);
621 struct omap_overlay_manager *mgr; 636 struct omap_overlay_manager *mgr;
622 int r; 637 int r;
623 638
624 r = dpi_init_regulator(); 639 r = dpi_init_regulator(dpi);
625 if (r) 640 if (r)
626 return r; 641 return r;
627 642
628 dpi_init_pll(); 643 dpi_init_pll(dpi);
629 644
630 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel); 645 mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
631 if (!mgr) 646 if (!mgr)
@@ -676,13 +691,14 @@ static const struct omapdss_dpi_ops dpi_ops = {
676 691
677static void dpi_init_output(struct platform_device *pdev) 692static void dpi_init_output(struct platform_device *pdev)
678{ 693{
679 struct omap_dss_device *out = &dpi.output; 694 struct dpi_data *dpi = dpi_get_data_from_pdev(pdev);
695 struct omap_dss_device *out = &dpi->output;
680 696
681 out->dev = &pdev->dev; 697 out->dev = &pdev->dev;
682 out->id = OMAP_DSS_OUTPUT_DPI; 698 out->id = OMAP_DSS_OUTPUT_DPI;
683 out->output_type = OMAP_DISPLAY_TYPE_DPI; 699 out->output_type = OMAP_DISPLAY_TYPE_DPI;
684 out->name = "dpi.0"; 700 out->name = "dpi.0";
685 out->dispc_channel = dpi_get_channel(); 701 out->dispc_channel = dpi_get_channel(0);
686 out->ops.dpi = &dpi_ops; 702 out->ops.dpi = &dpi_ops;
687 out->owner = THIS_MODULE; 703 out->owner = THIS_MODULE;
688 704
@@ -691,16 +707,69 @@ static void dpi_init_output(struct platform_device *pdev)
691 707
692static void __exit dpi_uninit_output(struct platform_device *pdev) 708static void __exit dpi_uninit_output(struct platform_device *pdev)
693{ 709{
694 struct omap_dss_device *out = &dpi.output; 710 struct dpi_data *dpi = dpi_get_data_from_pdev(pdev);
711 struct omap_dss_device *out = &dpi->output;
712
713 omapdss_unregister_output(out);
714}
715
716static void dpi_init_output_port(struct platform_device *pdev,
717 struct device_node *port)
718{
719 struct dpi_data *dpi = port->data;
720 struct omap_dss_device *out = &dpi->output;
721 int r;
722 u32 port_num;
723
724 r = of_property_read_u32(port, "reg", &port_num);
725 if (r)
726 port_num = 0;
727
728 switch (port_num) {
729 case 2:
730 out->name = "dpi.2";
731 break;
732 case 1:
733 out->name = "dpi.1";
734 break;
735 case 0:
736 default:
737 out->name = "dpi.0";
738 break;
739 }
740
741 out->dev = &pdev->dev;
742 out->id = OMAP_DSS_OUTPUT_DPI;
743 out->output_type = OMAP_DISPLAY_TYPE_DPI;
744 out->dispc_channel = dpi_get_channel(port_num);
745 out->port_num = port_num;
746 out->ops.dpi = &dpi_ops;
747 out->owner = THIS_MODULE;
748
749 omapdss_register_output(out);
750}
751
752static void __exit dpi_uninit_output_port(struct device_node *port)
753{
754 struct dpi_data *dpi = port->data;
755 struct omap_dss_device *out = &dpi->output;
695 756
696 omapdss_unregister_output(out); 757 omapdss_unregister_output(out);
697} 758}
698 759
699static int omap_dpi_probe(struct platform_device *pdev) 760static int omap_dpi_probe(struct platform_device *pdev)
700{ 761{
701 dpi.pdev = pdev; 762 struct dpi_data *dpi;
763
764 dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL);
765 if (!dpi)
766 return -ENOMEM;
702 767
703 mutex_init(&dpi.lock); 768 dpi->pdev = pdev;
769
770 dev_set_drvdata(&pdev->dev, dpi);
771
772 mutex_init(&dpi->lock);
704 773
705 dpi_init_output(pdev); 774 dpi_init_output(pdev);
706 775
@@ -736,10 +805,15 @@ void __exit dpi_uninit_platform_driver(void)
736 805
737int __init dpi_init_port(struct platform_device *pdev, struct device_node *port) 806int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
738{ 807{
808 struct dpi_data *dpi;
739 struct device_node *ep; 809 struct device_node *ep;
740 u32 datalines; 810 u32 datalines;
741 int r; 811 int r;
742 812
813 dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL);
814 if (!dpi)
815 return -ENOMEM;
816
743 ep = omapdss_of_get_next_endpoint(port, NULL); 817 ep = omapdss_of_get_next_endpoint(port, NULL);
744 if (!ep) 818 if (!ep)
745 return 0; 819 return 0;
@@ -750,17 +824,18 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
750 goto err_datalines; 824 goto err_datalines;
751 } 825 }
752 826
753 dpi.data_lines = datalines; 827 dpi->data_lines = datalines;
754 828
755 of_node_put(ep); 829 of_node_put(ep);
756 830
757 dpi.pdev = pdev; 831 dpi->pdev = pdev;
832 port->data = dpi;
758 833
759 mutex_init(&dpi.lock); 834 mutex_init(&dpi->lock);
760 835
761 dpi_init_output(pdev); 836 dpi_init_output_port(pdev, port);
762 837
763 dpi.port_initialized = true; 838 dpi->port_initialized = true;
764 839
765 return 0; 840 return 0;
766 841
@@ -770,10 +845,12 @@ err_datalines:
770 return r; 845 return r;
771} 846}
772 847
773void __exit dpi_uninit_port(void) 848void __exit dpi_uninit_port(struct device_node *port)
774{ 849{
775 if (!dpi.port_initialized) 850 struct dpi_data *dpi = port->data;
851
852 if (!dpi->port_initialized)
776 return; 853 return;
777 854
778 dpi_uninit_output(dpi.pdev); 855 dpi_uninit_output_port(port);
779} 856}
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index 0793bc67a275..73af35159468 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -219,6 +219,10 @@ static void dsi_display_uninit_dispc(struct platform_device *dsidev,
219 219
220static int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel); 220static int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
221 221
222/* DSI PLL HSDIV indices */
223#define HSDIV_DISPC 0
224#define HSDIV_DSI 1
225
222#define DSI_MAX_NR_ISRS 2 226#define DSI_MAX_NR_ISRS 2
223#define DSI_MAX_NR_LANES 5 227#define DSI_MAX_NR_LANES 5
224 228
@@ -271,6 +275,7 @@ struct dsi_isr_tables {
271 275
272struct dsi_clk_calc_ctx { 276struct dsi_clk_calc_ctx {
273 struct platform_device *dsidev; 277 struct platform_device *dsidev;
278 struct dss_pll *pll;
274 279
275 /* inputs */ 280 /* inputs */
276 281
@@ -280,13 +285,18 @@ struct dsi_clk_calc_ctx {
280 285
281 /* outputs */ 286 /* outputs */
282 287
283 struct dsi_clock_info dsi_cinfo; 288 struct dss_pll_clock_info dsi_cinfo;
284 struct dispc_clock_info dispc_cinfo; 289 struct dispc_clock_info dispc_cinfo;
285 290
286 struct omap_video_timings dispc_vm; 291 struct omap_video_timings dispc_vm;
287 struct omap_dss_dsi_videomode_timings dsi_vm; 292 struct omap_dss_dsi_videomode_timings dsi_vm;
288}; 293};
289 294
295struct dsi_lp_clock_info {
296 unsigned long lp_clk;
297 u16 lp_clk_div;
298};
299
290struct dsi_data { 300struct dsi_data {
291 struct platform_device *pdev; 301 struct platform_device *pdev;
292 void __iomem *proto_base; 302 void __iomem *proto_base;
@@ -300,12 +310,14 @@ struct dsi_data {
300 bool is_enabled; 310 bool is_enabled;
301 311
302 struct clk *dss_clk; 312 struct clk *dss_clk;
303 struct clk *sys_clk;
304 313
305 struct dispc_clock_info user_dispc_cinfo; 314 struct dispc_clock_info user_dispc_cinfo;
306 struct dsi_clock_info user_dsi_cinfo; 315 struct dss_pll_clock_info user_dsi_cinfo;
316
317 struct dsi_lp_clock_info user_lp_cinfo;
318 struct dsi_lp_clock_info current_lp_cinfo;
307 319
308 struct dsi_clock_info current_cinfo; 320 struct dss_pll pll;
309 321
310 bool vdds_dsi_enabled; 322 bool vdds_dsi_enabled;
311 struct regulator *vdds_dsi_reg; 323 struct regulator *vdds_dsi_reg;
@@ -321,8 +333,6 @@ struct dsi_data {
321 struct mutex lock; 333 struct mutex lock;
322 struct semaphore bus_lock; 334 struct semaphore bus_lock;
323 335
324 unsigned pll_locked;
325
326 spinlock_t irq_lock; 336 spinlock_t irq_lock;
327 struct dsi_isr_tables isr_tables; 337 struct dsi_isr_tables isr_tables;
328 /* space for a copy used by the interrupt handler */ 338 /* space for a copy used by the interrupt handler */
@@ -347,7 +357,7 @@ struct dsi_data {
347 357
348 unsigned long cache_req_pck; 358 unsigned long cache_req_pck;
349 unsigned long cache_clk_freq; 359 unsigned long cache_clk_freq;
350 struct dsi_clock_info cache_cinfo; 360 struct dss_pll_clock_info cache_cinfo;
351 361
352 u32 errors; 362 u32 errors;
353 spinlock_t errors_lock; 363 spinlock_t errors_lock;
@@ -362,11 +372,6 @@ struct dsi_data {
362 spinlock_t irq_stats_lock; 372 spinlock_t irq_stats_lock;
363 struct dsi_irq_stats irq_stats; 373 struct dsi_irq_stats irq_stats;
364#endif 374#endif
365 /* DSI PLL Parameter Ranges */
366 unsigned long regm_max, regn_max;
367 unsigned long regm_dispc_max, regm_dsi_max;
368 unsigned long fint_min, fint_max;
369 unsigned long lpdiv_max;
370 375
371 unsigned num_lanes_supported; 376 unsigned num_lanes_supported;
372 unsigned line_buffer_size; 377 unsigned line_buffer_size;
@@ -412,7 +417,7 @@ static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss
412 return to_platform_device(dssdev->dev); 417 return to_platform_device(dssdev->dev);
413} 418}
414 419
415struct platform_device *dsi_get_dsidev_from_id(int module) 420static struct platform_device *dsi_get_dsidev_from_id(int module)
416{ 421{
417 struct omap_dss_device *out; 422 struct omap_dss_device *out;
418 enum omap_dss_output_id id; 423 enum omap_dss_output_id id;
@@ -1134,7 +1139,7 @@ static u32 dsi_get_errors(struct platform_device *dsidev)
1134 return e; 1139 return e;
1135} 1140}
1136 1141
1137int dsi_runtime_get(struct platform_device *dsidev) 1142static int dsi_runtime_get(struct platform_device *dsidev)
1138{ 1143{
1139 int r; 1144 int r;
1140 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1145 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -1146,7 +1151,7 @@ int dsi_runtime_get(struct platform_device *dsidev)
1146 return r < 0 ? r : 0; 1151 return r < 0 ? r : 0;
1147} 1152}
1148 1153
1149void dsi_runtime_put(struct platform_device *dsidev) 1154static void dsi_runtime_put(struct platform_device *dsidev)
1150{ 1155{
1151 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1156 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1152 int r; 1157 int r;
@@ -1188,23 +1193,6 @@ static int dsi_regulator_init(struct platform_device *dsidev)
1188 return 0; 1193 return 0;
1189} 1194}
1190 1195
1191/* source clock for DSI PLL. this could also be PCLKFREE */
1192static inline void dsi_enable_pll_clock(struct platform_device *dsidev,
1193 bool enable)
1194{
1195 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1196
1197 if (enable)
1198 clk_prepare_enable(dsi->sys_clk);
1199 else
1200 clk_disable_unprepare(dsi->sys_clk);
1201
1202 if (enable && dsi->pll_locked) {
1203 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1)
1204 DSSERR("cannot lock PLL when enabling clocks\n");
1205 }
1206}
1207
1208static void _dsi_print_reset_status(struct platform_device *dsidev) 1196static void _dsi_print_reset_status(struct platform_device *dsidev)
1209{ 1197{
1210 u32 l; 1198 u32 l;
@@ -1256,25 +1244,25 @@ static inline int dsi_if_enable(struct platform_device *dsidev, bool enable)
1256 return 0; 1244 return 0;
1257} 1245}
1258 1246
1259unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev) 1247static unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
1260{ 1248{
1261 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1249 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1262 1250
1263 return dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk; 1251 return dsi->pll.cinfo.clkout[HSDIV_DISPC];
1264} 1252}
1265 1253
1266static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev) 1254static unsigned long dsi_get_pll_hsdiv_dsi_rate(struct platform_device *dsidev)
1267{ 1255{
1268 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1256 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1269 1257
1270 return dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk; 1258 return dsi->pll.cinfo.clkout[HSDIV_DSI];
1271} 1259}
1272 1260
1273static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev) 1261static unsigned long dsi_get_txbyteclkhs(struct platform_device *dsidev)
1274{ 1262{
1275 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1263 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1276 1264
1277 return dsi->current_cinfo.clkin4ddr / 16; 1265 return dsi->pll.cinfo.clkdco / 16;
1278} 1266}
1279 1267
1280static unsigned long dsi_fclk_rate(struct platform_device *dsidev) 1268static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
@@ -1293,10 +1281,10 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
1293 return r; 1281 return r;
1294} 1282}
1295 1283
1296static int dsi_lp_clock_calc(struct dsi_clock_info *cinfo, 1284static int dsi_lp_clock_calc(unsigned long dsi_fclk,
1297 unsigned long lp_clk_min, unsigned long lp_clk_max) 1285 unsigned long lp_clk_min, unsigned long lp_clk_max,
1286 struct dsi_lp_clock_info *lp_cinfo)
1298{ 1287{
1299 unsigned long dsi_fclk = cinfo->dsi_pll_hsdiv_dsi_clk;
1300 unsigned lp_clk_div; 1288 unsigned lp_clk_div;
1301 unsigned long lp_clk; 1289 unsigned long lp_clk;
1302 1290
@@ -1306,8 +1294,8 @@ static int dsi_lp_clock_calc(struct dsi_clock_info *cinfo,
1306 if (lp_clk < lp_clk_min || lp_clk > lp_clk_max) 1294 if (lp_clk < lp_clk_min || lp_clk > lp_clk_max)
1307 return -EINVAL; 1295 return -EINVAL;
1308 1296
1309 cinfo->lp_clk_div = lp_clk_div; 1297 lp_cinfo->lp_clk_div = lp_clk_div;
1310 cinfo->lp_clk = lp_clk; 1298 lp_cinfo->lp_clk = lp_clk;
1311 1299
1312 return 0; 1300 return 0;
1313} 1301}
@@ -1318,10 +1306,12 @@ static int dsi_set_lp_clk_divisor(struct platform_device *dsidev)
1318 unsigned long dsi_fclk; 1306 unsigned long dsi_fclk;
1319 unsigned lp_clk_div; 1307 unsigned lp_clk_div;
1320 unsigned long lp_clk; 1308 unsigned long lp_clk;
1309 unsigned lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
1310
1321 1311
1322 lp_clk_div = dsi->user_dsi_cinfo.lp_clk_div; 1312 lp_clk_div = dsi->user_lp_cinfo.lp_clk_div;
1323 1313
1324 if (lp_clk_div == 0 || lp_clk_div > dsi->lpdiv_max) 1314 if (lp_clk_div == 0 || lp_clk_div > lpdiv_max)
1325 return -EINVAL; 1315 return -EINVAL;
1326 1316
1327 dsi_fclk = dsi_fclk_rate(dsidev); 1317 dsi_fclk = dsi_fclk_rate(dsidev);
@@ -1329,8 +1319,8 @@ static int dsi_set_lp_clk_divisor(struct platform_device *dsidev)
1329 lp_clk = dsi_fclk / 2 / lp_clk_div; 1319 lp_clk = dsi_fclk / 2 / lp_clk_div;
1330 1320
1331 DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk); 1321 DSSDBG("LP_CLK_DIV %u, LP_CLK %lu\n", lp_clk_div, lp_clk);
1332 dsi->current_cinfo.lp_clk = lp_clk; 1322 dsi->current_lp_cinfo.lp_clk = lp_clk;
1333 dsi->current_cinfo.lp_clk_div = lp_clk_div; 1323 dsi->current_lp_cinfo.lp_clk_div = lp_clk_div;
1334 1324
1335 /* LP_CLK_DIVISOR */ 1325 /* LP_CLK_DIVISOR */
1336 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, lp_clk_div, 12, 0); 1326 REG_FLD_MOD(dsidev, DSI_CLK_CTRL, lp_clk_div, 12, 0);
@@ -1391,286 +1381,33 @@ static int dsi_pll_power(struct platform_device *dsidev,
1391 return 0; 1381 return 0;
1392} 1382}
1393 1383
1394unsigned long dsi_get_pll_clkin(struct platform_device *dsidev)
1395{
1396 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1397 return clk_get_rate(dsi->sys_clk);
1398}
1399
1400bool dsi_hsdiv_calc(struct platform_device *dsidev, unsigned long pll,
1401 unsigned long out_min, dsi_hsdiv_calc_func func, void *data)
1402{
1403 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1404 int regm, regm_start, regm_stop;
1405 unsigned long out_max;
1406 unsigned long out;
1407
1408 out_min = out_min ? out_min : 1;
1409 out_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
1410
1411 regm_start = max(DIV_ROUND_UP(pll, out_max), 1ul);
1412 regm_stop = min(pll / out_min, dsi->regm_dispc_max);
1413
1414 for (regm = regm_start; regm <= regm_stop; ++regm) {
1415 out = pll / regm;
1416
1417 if (func(regm, out, data))
1418 return true;
1419 }
1420
1421 return false;
1422}
1423
1424bool dsi_pll_calc(struct platform_device *dsidev, unsigned long clkin,
1425 unsigned long pll_min, unsigned long pll_max,
1426 dsi_pll_calc_func func, void *data)
1427{
1428 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1429 int regn, regn_start, regn_stop;
1430 int regm, regm_start, regm_stop;
1431 unsigned long fint, pll;
1432 const unsigned long pll_hw_max = 1800000000;
1433 unsigned long fint_hw_min, fint_hw_max;
1434
1435 fint_hw_min = dsi->fint_min;
1436 fint_hw_max = dsi->fint_max;
1437 1384
1438 regn_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul); 1385static void dsi_pll_calc_dsi_fck(struct dss_pll_clock_info *cinfo)
1439 regn_stop = min(clkin / fint_hw_min, dsi->regn_max);
1440
1441 pll_max = pll_max ? pll_max : ULONG_MAX;
1442
1443 for (regn = regn_start; regn <= regn_stop; ++regn) {
1444 fint = clkin / regn;
1445
1446 regm_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
1447 1ul);
1448 regm_stop = min3(pll_max / fint / 2,
1449 pll_hw_max / fint / 2,
1450 dsi->regm_max);
1451
1452 for (regm = regm_start; regm <= regm_stop; ++regm) {
1453 pll = 2 * regm * fint;
1454
1455 if (func(regn, regm, fint, pll, data))
1456 return true;
1457 }
1458 }
1459
1460 return false;
1461}
1462
1463/* calculate clock rates using dividers in cinfo */
1464static int dsi_calc_clock_rates(struct platform_device *dsidev,
1465 struct dsi_clock_info *cinfo)
1466{
1467 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1468
1469 if (cinfo->regn == 0 || cinfo->regn > dsi->regn_max)
1470 return -EINVAL;
1471
1472 if (cinfo->regm == 0 || cinfo->regm > dsi->regm_max)
1473 return -EINVAL;
1474
1475 if (cinfo->regm_dispc > dsi->regm_dispc_max)
1476 return -EINVAL;
1477
1478 if (cinfo->regm_dsi > dsi->regm_dsi_max)
1479 return -EINVAL;
1480
1481 cinfo->clkin = clk_get_rate(dsi->sys_clk);
1482 cinfo->fint = cinfo->clkin / cinfo->regn;
1483
1484 if (cinfo->fint > dsi->fint_max || cinfo->fint < dsi->fint_min)
1485 return -EINVAL;
1486
1487 cinfo->clkin4ddr = 2 * cinfo->regm * cinfo->fint;
1488
1489 if (cinfo->clkin4ddr > 1800 * 1000 * 1000)
1490 return -EINVAL;
1491
1492 if (cinfo->regm_dispc > 0)
1493 cinfo->dsi_pll_hsdiv_dispc_clk =
1494 cinfo->clkin4ddr / cinfo->regm_dispc;
1495 else
1496 cinfo->dsi_pll_hsdiv_dispc_clk = 0;
1497
1498 if (cinfo->regm_dsi > 0)
1499 cinfo->dsi_pll_hsdiv_dsi_clk =
1500 cinfo->clkin4ddr / cinfo->regm_dsi;
1501 else
1502 cinfo->dsi_pll_hsdiv_dsi_clk = 0;
1503
1504 return 0;
1505}
1506
1507static void dsi_pll_calc_dsi_fck(struct dsi_clock_info *cinfo)
1508{ 1386{
1509 unsigned long max_dsi_fck; 1387 unsigned long max_dsi_fck;
1510 1388
1511 max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK); 1389 max_dsi_fck = dss_feat_get_param_max(FEAT_PARAM_DSI_FCK);
1512 1390
1513 cinfo->regm_dsi = DIV_ROUND_UP(cinfo->clkin4ddr, max_dsi_fck); 1391 cinfo->mX[HSDIV_DSI] = DIV_ROUND_UP(cinfo->clkdco, max_dsi_fck);
1514 cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkin4ddr / cinfo->regm_dsi; 1392 cinfo->clkout[HSDIV_DSI] = cinfo->clkdco / cinfo->mX[HSDIV_DSI];
1515} 1393}
1516 1394
1517int dsi_pll_set_clock_div(struct platform_device *dsidev, 1395static int dsi_pll_enable(struct dss_pll *pll)
1518 struct dsi_clock_info *cinfo)
1519{ 1396{
1520 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1397 struct dsi_data *dsi = container_of(pll, struct dsi_data, pll);
1398 struct platform_device *dsidev = dsi->pdev;
1521 int r = 0; 1399 int r = 0;
1522 u32 l;
1523 int f = 0;
1524 u8 regn_start, regn_end, regm_start, regm_end;
1525 u8 regm_dispc_start, regm_dispc_end, regm_dsi_start, regm_dsi_end;
1526
1527 DSSDBG("DSI PLL clock config starts");
1528
1529 dsi->current_cinfo.clkin = cinfo->clkin;
1530 dsi->current_cinfo.fint = cinfo->fint;
1531 dsi->current_cinfo.clkin4ddr = cinfo->clkin4ddr;
1532 dsi->current_cinfo.dsi_pll_hsdiv_dispc_clk =
1533 cinfo->dsi_pll_hsdiv_dispc_clk;
1534 dsi->current_cinfo.dsi_pll_hsdiv_dsi_clk =
1535 cinfo->dsi_pll_hsdiv_dsi_clk;
1536
1537 dsi->current_cinfo.regn = cinfo->regn;
1538 dsi->current_cinfo.regm = cinfo->regm;
1539 dsi->current_cinfo.regm_dispc = cinfo->regm_dispc;
1540 dsi->current_cinfo.regm_dsi = cinfo->regm_dsi;
1541
1542 DSSDBG("DSI Fint %ld\n", cinfo->fint);
1543
1544 DSSDBG("clkin rate %ld\n", cinfo->clkin);
1545
1546 /* DSIPHY == CLKIN4DDR */
1547 DSSDBG("CLKIN4DDR = 2 * %d / %d * %lu = %lu\n",
1548 cinfo->regm,
1549 cinfo->regn,
1550 cinfo->clkin,
1551 cinfo->clkin4ddr);
1552
1553 DSSDBG("Data rate on 1 DSI lane %ld Mbps\n",
1554 cinfo->clkin4ddr / 1000 / 1000 / 2);
1555
1556 DSSDBG("Clock lane freq %ld Hz\n", cinfo->clkin4ddr / 4);
1557
1558 DSSDBG("regm_dispc = %d, %s (%s) = %lu\n", cinfo->regm_dispc,
1559 dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
1560 dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
1561 cinfo->dsi_pll_hsdiv_dispc_clk);
1562 DSSDBG("regm_dsi = %d, %s (%s) = %lu\n", cinfo->regm_dsi,
1563 dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
1564 dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
1565 cinfo->dsi_pll_hsdiv_dsi_clk);
1566
1567 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGN, &regn_start, &regn_end);
1568 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM, &regm_start, &regm_end);
1569 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DISPC, &regm_dispc_start,
1570 &regm_dispc_end);
1571 dss_feat_get_reg_field(FEAT_REG_DSIPLL_REGM_DSI, &regm_dsi_start,
1572 &regm_dsi_end);
1573
1574 /* DSI_PLL_AUTOMODE = manual */
1575 REG_FLD_MOD(dsidev, DSI_PLL_CONTROL, 0, 0, 0);
1576
1577 l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION1);
1578 l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */
1579 /* DSI_PLL_REGN */
1580 l = FLD_MOD(l, cinfo->regn - 1, regn_start, regn_end);
1581 /* DSI_PLL_REGM */
1582 l = FLD_MOD(l, cinfo->regm, regm_start, regm_end);
1583 /* DSI_CLOCK_DIV */
1584 l = FLD_MOD(l, cinfo->regm_dispc > 0 ? cinfo->regm_dispc - 1 : 0,
1585 regm_dispc_start, regm_dispc_end);
1586 /* DSIPROTO_CLOCK_DIV */
1587 l = FLD_MOD(l, cinfo->regm_dsi > 0 ? cinfo->regm_dsi - 1 : 0,
1588 regm_dsi_start, regm_dsi_end);
1589 dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION1, l);
1590
1591 BUG_ON(cinfo->fint < dsi->fint_min || cinfo->fint > dsi->fint_max);
1592
1593 l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2);
1594
1595 if (dss_has_feature(FEAT_DSI_PLL_FREQSEL)) {
1596 f = cinfo->fint < 1000000 ? 0x3 :
1597 cinfo->fint < 1250000 ? 0x4 :
1598 cinfo->fint < 1500000 ? 0x5 :
1599 cinfo->fint < 1750000 ? 0x6 :
1600 0x7;
1601
1602 l = FLD_MOD(l, f, 4, 1); /* DSI_PLL_FREQSEL */
1603 } else if (dss_has_feature(FEAT_DSI_PLL_SELFREQDCO)) {
1604 f = cinfo->clkin4ddr < 1000000000 ? 0x2 : 0x4;
1605
1606 l = FLD_MOD(l, f, 3, 1); /* PLL_SELFREQDCO */
1607 }
1608
1609 l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */
1610 l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */
1611 l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */
1612 if (dss_has_feature(FEAT_DSI_PLL_REFSEL))
1613 l = FLD_MOD(l, 3, 22, 21); /* REF_SYSCLK = sysclk */
1614 dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l);
1615
1616 REG_FLD_MOD(dsidev, DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */
1617
1618 if (wait_for_bit_change(dsidev, DSI_PLL_GO, 0, 0) != 0) {
1619 DSSERR("dsi pll go bit not going down.\n");
1620 r = -EIO;
1621 goto err;
1622 }
1623
1624 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 1, 1) != 1) {
1625 DSSERR("cannot lock PLL\n");
1626 r = -EIO;
1627 goto err;
1628 }
1629
1630 dsi->pll_locked = 1;
1631
1632 l = dsi_read_reg(dsidev, DSI_PLL_CONFIGURATION2);
1633 l = FLD_MOD(l, 0, 0, 0); /* DSI_PLL_IDLE */
1634 l = FLD_MOD(l, 0, 5, 5); /* DSI_PLL_PLLLPMODE */
1635 l = FLD_MOD(l, 0, 6, 6); /* DSI_PLL_LOWCURRSTBY */
1636 l = FLD_MOD(l, 0, 7, 7); /* DSI_PLL_TIGHTPHASELOCK */
1637 l = FLD_MOD(l, 0, 8, 8); /* DSI_PLL_DRIFTGUARDEN */
1638 l = FLD_MOD(l, 0, 10, 9); /* DSI_PLL_LOCKSEL */
1639 l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */
1640 l = FLD_MOD(l, 1, 14, 14); /* DSIPHY_CLKINEN */
1641 l = FLD_MOD(l, 0, 15, 15); /* DSI_BYPASSEN */
1642 l = FLD_MOD(l, 1, 16, 16); /* DSS_CLOCK_EN */
1643 l = FLD_MOD(l, 0, 17, 17); /* DSS_CLOCK_PWDN */
1644 l = FLD_MOD(l, 1, 18, 18); /* DSI_PROTO_CLOCK_EN */
1645 l = FLD_MOD(l, 0, 19, 19); /* DSI_PROTO_CLOCK_PWDN */
1646 l = FLD_MOD(l, 0, 20, 20); /* DSI_HSDIVBYPASS */
1647 dsi_write_reg(dsidev, DSI_PLL_CONFIGURATION2, l);
1648
1649 DSSDBG("PLL config done\n");
1650err:
1651 return r;
1652}
1653
1654int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
1655 bool enable_hsdiv)
1656{
1657 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1658 int r = 0;
1659 enum dsi_pll_power_state pwstate;
1660 1400
1661 DSSDBG("PLL init\n"); 1401 DSSDBG("PLL init\n");
1662 1402
1663 /*
1664 * It seems that on many OMAPs we need to enable both to have a
1665 * functional HSDivider.
1666 */
1667 enable_hsclk = enable_hsdiv = true;
1668
1669 r = dsi_regulator_init(dsidev); 1403 r = dsi_regulator_init(dsidev);
1670 if (r) 1404 if (r)
1671 return r; 1405 return r;
1672 1406
1673 dsi_enable_pll_clock(dsidev, 1); 1407 r = dsi_runtime_get(dsidev);
1408 if (r)
1409 return r;
1410
1674 /* 1411 /*
1675 * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4. 1412 * Note: SCP CLK is not required on OMAP3, but it is required on OMAP4.
1676 */ 1413 */
@@ -1697,16 +1434,7 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
1697 * fill the whole display. No idea about this */ 1434 * fill the whole display. No idea about this */
1698 dispc_pck_free_enable(0); 1435 dispc_pck_free_enable(0);
1699 1436
1700 if (enable_hsclk && enable_hsdiv) 1437 r = dsi_pll_power(dsidev, DSI_PLL_POWER_ON_ALL);
1701 pwstate = DSI_PLL_POWER_ON_ALL;
1702 else if (enable_hsclk)
1703 pwstate = DSI_PLL_POWER_ON_HSCLK;
1704 else if (enable_hsdiv)
1705 pwstate = DSI_PLL_POWER_ON_DIV;
1706 else
1707 pwstate = DSI_PLL_POWER_OFF;
1708
1709 r = dsi_pll_power(dsidev, pwstate);
1710 1438
1711 if (r) 1439 if (r)
1712 goto err1; 1440 goto err1;
@@ -1721,15 +1449,14 @@ err1:
1721 } 1449 }
1722err0: 1450err0:
1723 dsi_disable_scp_clk(dsidev); 1451 dsi_disable_scp_clk(dsidev);
1724 dsi_enable_pll_clock(dsidev, 0); 1452 dsi_runtime_put(dsidev);
1725 return r; 1453 return r;
1726} 1454}
1727 1455
1728void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes) 1456static void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
1729{ 1457{
1730 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1458 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1731 1459
1732 dsi->pll_locked = 0;
1733 dsi_pll_power(dsidev, DSI_PLL_POWER_OFF); 1460 dsi_pll_power(dsidev, DSI_PLL_POWER_OFF);
1734 if (disconnect_lanes) { 1461 if (disconnect_lanes) {
1735 WARN_ON(!dsi->vdds_dsi_enabled); 1462 WARN_ON(!dsi->vdds_dsi_enabled);
@@ -1738,18 +1465,27 @@ void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes)
1738 } 1465 }
1739 1466
1740 dsi_disable_scp_clk(dsidev); 1467 dsi_disable_scp_clk(dsidev);
1741 dsi_enable_pll_clock(dsidev, 0); 1468 dsi_runtime_put(dsidev);
1742 1469
1743 DSSDBG("PLL uninit done\n"); 1470 DSSDBG("PLL uninit done\n");
1744} 1471}
1745 1472
1473static void dsi_pll_disable(struct dss_pll *pll)
1474{
1475 struct dsi_data *dsi = container_of(pll, struct dsi_data, pll);
1476 struct platform_device *dsidev = dsi->pdev;
1477
1478 dsi_pll_uninit(dsidev, true);
1479}
1480
1746static void dsi_dump_dsidev_clocks(struct platform_device *dsidev, 1481static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
1747 struct seq_file *s) 1482 struct seq_file *s)
1748{ 1483{
1749 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1484 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1750 struct dsi_clock_info *cinfo = &dsi->current_cinfo; 1485 struct dss_pll_clock_info *cinfo = &dsi->pll.cinfo;
1751 enum omap_dss_clk_source dispc_clk_src, dsi_clk_src; 1486 enum omap_dss_clk_source dispc_clk_src, dsi_clk_src;
1752 int dsi_module = dsi->module_id; 1487 int dsi_module = dsi->module_id;
1488 struct dss_pll *pll = &dsi->pll;
1753 1489
1754 dispc_clk_src = dss_get_dispc_clk_source(); 1490 dispc_clk_src = dss_get_dispc_clk_source();
1755 dsi_clk_src = dss_get_dsi_clk_source(dsi_module); 1491 dsi_clk_src = dss_get_dsi_clk_source(dsi_module);
@@ -1759,28 +1495,28 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
1759 1495
1760 seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1); 1496 seq_printf(s, "- DSI%d PLL -\n", dsi_module + 1);
1761 1497
1762 seq_printf(s, "dsi pll clkin\t%lu\n", cinfo->clkin); 1498 seq_printf(s, "dsi pll clkin\t%lu\n", clk_get_rate(pll->clkin));
1763 1499
1764 seq_printf(s, "Fint\t\t%-16luregn %u\n", cinfo->fint, cinfo->regn); 1500 seq_printf(s, "Fint\t\t%-16lun %u\n", cinfo->fint, cinfo->n);
1765 1501
1766 seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n", 1502 seq_printf(s, "CLKIN4DDR\t%-16lum %u\n",
1767 cinfo->clkin4ddr, cinfo->regm); 1503 cinfo->clkdco, cinfo->m);
1768 1504
1769 seq_printf(s, "DSI_PLL_HSDIV_DISPC (%s)\t%-16luregm_dispc %u\t(%s)\n", 1505 seq_printf(s, "DSI_PLL_HSDIV_DISPC (%s)\t%-16lum_dispc %u\t(%s)\n",
1770 dss_feat_get_clk_source_name(dsi_module == 0 ? 1506 dss_feat_get_clk_source_name(dsi_module == 0 ?
1771 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC : 1507 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
1772 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC), 1508 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC),
1773 cinfo->dsi_pll_hsdiv_dispc_clk, 1509 cinfo->clkout[HSDIV_DISPC],
1774 cinfo->regm_dispc, 1510 cinfo->mX[HSDIV_DISPC],
1775 dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ? 1511 dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ?
1776 "off" : "on"); 1512 "off" : "on");
1777 1513
1778 seq_printf(s, "DSI_PLL_HSDIV_DSI (%s)\t%-16luregm_dsi %u\t(%s)\n", 1514 seq_printf(s, "DSI_PLL_HSDIV_DSI (%s)\t%-16lum_dsi %u\t(%s)\n",
1779 dss_feat_get_clk_source_name(dsi_module == 0 ? 1515 dss_feat_get_clk_source_name(dsi_module == 0 ?
1780 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI : 1516 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
1781 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI), 1517 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI),
1782 cinfo->dsi_pll_hsdiv_dsi_clk, 1518 cinfo->clkout[HSDIV_DSI],
1783 cinfo->regm_dsi, 1519 cinfo->mX[HSDIV_DSI],
1784 dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ? 1520 dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ?
1785 "off" : "on"); 1521 "off" : "on");
1786 1522
@@ -1793,11 +1529,11 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
1793 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev)); 1529 seq_printf(s, "DSI_FCLK\t%lu\n", dsi_fclk_rate(dsidev));
1794 1530
1795 seq_printf(s, "DDR_CLK\t\t%lu\n", 1531 seq_printf(s, "DDR_CLK\t\t%lu\n",
1796 cinfo->clkin4ddr / 4); 1532 cinfo->clkdco / 4);
1797 1533
1798 seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs(dsidev)); 1534 seq_printf(s, "TxByteClkHS\t%lu\n", dsi_get_txbyteclkhs(dsidev));
1799 1535
1800 seq_printf(s, "LP_CLK\t\t%lu\n", cinfo->lp_clk); 1536 seq_printf(s, "LP_CLK\t\t%lu\n", dsi->current_lp_cinfo.lp_clk);
1801 1537
1802 dsi_runtime_put(dsidev); 1538 dsi_runtime_put(dsidev);
1803} 1539}
@@ -2132,7 +1868,7 @@ static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns)
2132 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1868 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2133 1869
2134 /* convert time in ns to ddr ticks, rounding up */ 1870 /* convert time in ns to ddr ticks, rounding up */
2135 unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4; 1871 unsigned long ddr_clk = dsi->pll.cinfo.clkdco / 4;
2136 return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000; 1872 return (ns * (ddr_clk / 1000 / 1000) + 999) / 1000;
2137} 1873}
2138 1874
@@ -2140,7 +1876,7 @@ static inline unsigned ddr2ns(struct platform_device *dsidev, unsigned ddr)
2140{ 1876{
2141 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1877 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2142 1878
2143 unsigned long ddr_clk = dsi->current_cinfo.clkin4ddr / 4; 1879 unsigned long ddr_clk = dsi->pll.cinfo.clkdco / 4;
2144 return ddr * 1000 * 1000 / (ddr_clk / 1000); 1880 return ddr * 1000 * 1000 / (ddr_clk / 1000);
2145} 1881}
2146 1882
@@ -3730,7 +3466,7 @@ static void dsi_config_cmd_mode_interleaving(struct platform_device *dsidev)
3730 struct omap_video_timings *timings = &dsi->timings; 3466 struct omap_video_timings *timings = &dsi->timings;
3731 int bpp = dsi_get_pixel_size(dsi->pix_fmt); 3467 int bpp = dsi_get_pixel_size(dsi->pix_fmt);
3732 int ndl = dsi->num_lanes_used - 1; 3468 int ndl = dsi->num_lanes_used - 1;
3733 int dsi_fclk_hsdiv = dsi->user_dsi_cinfo.regm_dsi + 1; 3469 int dsi_fclk_hsdiv = dsi->user_dsi_cinfo.mX[HSDIV_DSI] + 1;
3734 int hsa_interleave_hs = 0, hsa_interleave_lp = 0; 3470 int hsa_interleave_hs = 0, hsa_interleave_lp = 0;
3735 int hfp_interleave_hs = 0, hfp_interleave_lp = 0; 3471 int hfp_interleave_hs = 0, hfp_interleave_lp = 0;
3736 int hbp_interleave_hs = 0, hbp_interleave_lp = 0; 3472 int hbp_interleave_hs = 0, hbp_interleave_lp = 0;
@@ -4441,18 +4177,12 @@ static void dsi_display_uninit_dispc(struct platform_device *dsidev,
4441static int dsi_configure_dsi_clocks(struct platform_device *dsidev) 4177static int dsi_configure_dsi_clocks(struct platform_device *dsidev)
4442{ 4178{
4443 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4179 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4444 struct dsi_clock_info cinfo; 4180 struct dss_pll_clock_info cinfo;
4445 int r; 4181 int r;
4446 4182
4447 cinfo = dsi->user_dsi_cinfo; 4183 cinfo = dsi->user_dsi_cinfo;
4448 4184
4449 r = dsi_calc_clock_rates(dsidev, &cinfo); 4185 r = dss_pll_set_config(&dsi->pll, &cinfo);
4450 if (r) {
4451 DSSERR("Failed to calc dsi clocks\n");
4452 return r;
4453 }
4454
4455 r = dsi_pll_set_clock_div(dsidev, &cinfo);
4456 if (r) { 4186 if (r) {
4457 DSSERR("Failed to set dsi clocks\n"); 4187 DSSERR("Failed to set dsi clocks\n");
4458 return r; 4188 return r;
@@ -4466,7 +4196,7 @@ static int dsi_display_init_dsi(struct platform_device *dsidev)
4466 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4196 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4467 int r; 4197 int r;
4468 4198
4469 r = dsi_pll_init(dsidev, true, true); 4199 r = dss_pll_enable(&dsi->pll);
4470 if (r) 4200 if (r)
4471 goto err0; 4201 goto err0;
4472 4202
@@ -4510,7 +4240,7 @@ err3:
4510err2: 4240err2:
4511 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); 4241 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
4512err1: 4242err1:
4513 dsi_pll_uninit(dsidev, true); 4243 dss_pll_disable(&dsi->pll);
4514err0: 4244err0:
4515 return r; 4245 return r;
4516} 4246}
@@ -4551,8 +4281,6 @@ static int dsi_display_enable(struct omap_dss_device *dssdev)
4551 if (r) 4281 if (r)
4552 goto err_get_dsi; 4282 goto err_get_dsi;
4553 4283
4554 dsi_enable_pll_clock(dsidev, 1);
4555
4556 _dsi_initialize_irq(dsidev); 4284 _dsi_initialize_irq(dsidev);
4557 4285
4558 r = dsi_display_init_dsi(dsidev); 4286 r = dsi_display_init_dsi(dsidev);
@@ -4564,7 +4292,6 @@ static int dsi_display_enable(struct omap_dss_device *dssdev)
4564 return 0; 4292 return 0;
4565 4293
4566err_init_dsi: 4294err_init_dsi:
4567 dsi_enable_pll_clock(dsidev, 0);
4568 dsi_runtime_put(dsidev); 4295 dsi_runtime_put(dsidev);
4569err_get_dsi: 4296err_get_dsi:
4570 mutex_unlock(&dsi->lock); 4297 mutex_unlock(&dsi->lock);
@@ -4592,7 +4319,6 @@ static void dsi_display_disable(struct omap_dss_device *dssdev,
4592 dsi_display_uninit_dsi(dsidev, disconnect_lanes, enter_ulps); 4319 dsi_display_uninit_dsi(dsidev, disconnect_lanes, enter_ulps);
4593 4320
4594 dsi_runtime_put(dsidev); 4321 dsi_runtime_put(dsidev);
4595 dsi_enable_pll_clock(dsidev, 0);
4596 4322
4597 mutex_unlock(&dsi->lock); 4323 mutex_unlock(&dsi->lock);
4598} 4324}
@@ -4713,29 +4439,30 @@ static bool dsi_cm_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
4713 return true; 4439 return true;
4714} 4440}
4715 4441
4716static bool dsi_cm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc, 4442static bool dsi_cm_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
4717 void *data) 4443 void *data)
4718{ 4444{
4719 struct dsi_clk_calc_ctx *ctx = data; 4445 struct dsi_clk_calc_ctx *ctx = data;
4720 4446
4721 ctx->dsi_cinfo.regm_dispc = regm_dispc; 4447 ctx->dsi_cinfo.mX[HSDIV_DISPC] = m_dispc;
4722 ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc; 4448 ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc;
4723 4449
4724 return dispc_div_calc(dispc, ctx->req_pck_min, ctx->req_pck_max, 4450 return dispc_div_calc(dispc, ctx->req_pck_min, ctx->req_pck_max,
4725 dsi_cm_calc_dispc_cb, ctx); 4451 dsi_cm_calc_dispc_cb, ctx);
4726} 4452}
4727 4453
4728static bool dsi_cm_calc_pll_cb(int regn, int regm, unsigned long fint, 4454static bool dsi_cm_calc_pll_cb(int n, int m, unsigned long fint,
4729 unsigned long pll, void *data) 4455 unsigned long clkdco, void *data)
4730{ 4456{
4731 struct dsi_clk_calc_ctx *ctx = data; 4457 struct dsi_clk_calc_ctx *ctx = data;
4732 4458
4733 ctx->dsi_cinfo.regn = regn; 4459 ctx->dsi_cinfo.n = n;
4734 ctx->dsi_cinfo.regm = regm; 4460 ctx->dsi_cinfo.m = m;
4735 ctx->dsi_cinfo.fint = fint; 4461 ctx->dsi_cinfo.fint = fint;
4736 ctx->dsi_cinfo.clkin4ddr = pll; 4462 ctx->dsi_cinfo.clkdco = clkdco;
4737 4463
4738 return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->req_pck_min, 4464 return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min,
4465 dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
4739 dsi_cm_calc_hsdiv_cb, ctx); 4466 dsi_cm_calc_hsdiv_cb, ctx);
4740} 4467}
4741 4468
@@ -4748,7 +4475,7 @@ static bool dsi_cm_calc(struct dsi_data *dsi,
4748 unsigned long pll_min, pll_max; 4475 unsigned long pll_min, pll_max;
4749 unsigned long pck, txbyteclk; 4476 unsigned long pck, txbyteclk;
4750 4477
4751 clkin = clk_get_rate(dsi->sys_clk); 4478 clkin = clk_get_rate(dsi->pll.clkin);
4752 bitspp = dsi_get_pixel_size(cfg->pixel_format); 4479 bitspp = dsi_get_pixel_size(cfg->pixel_format);
4753 ndl = dsi->num_lanes_used - 1; 4480 ndl = dsi->num_lanes_used - 1;
4754 4481
@@ -4764,16 +4491,16 @@ static bool dsi_cm_calc(struct dsi_data *dsi,
4764 4491
4765 memset(ctx, 0, sizeof(*ctx)); 4492 memset(ctx, 0, sizeof(*ctx));
4766 ctx->dsidev = dsi->pdev; 4493 ctx->dsidev = dsi->pdev;
4494 ctx->pll = &dsi->pll;
4767 ctx->config = cfg; 4495 ctx->config = cfg;
4768 ctx->req_pck_min = pck; 4496 ctx->req_pck_min = pck;
4769 ctx->req_pck_nom = pck; 4497 ctx->req_pck_nom = pck;
4770 ctx->req_pck_max = pck * 3 / 2; 4498 ctx->req_pck_max = pck * 3 / 2;
4771 ctx->dsi_cinfo.clkin = clkin;
4772 4499
4773 pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4); 4500 pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4);
4774 pll_max = cfg->hs_clk_max * 4; 4501 pll_max = cfg->hs_clk_max * 4;
4775 4502
4776 return dsi_pll_calc(dsi->pdev, clkin, 4503 return dss_pll_calc(ctx->pll, clkin,
4777 pll_min, pll_max, 4504 pll_min, pll_max,
4778 dsi_cm_calc_pll_cb, ctx); 4505 dsi_cm_calc_pll_cb, ctx);
4779} 4506}
@@ -4784,7 +4511,7 @@ static bool dsi_vm_calc_blanking(struct dsi_clk_calc_ctx *ctx)
4784 const struct omap_dss_dsi_config *cfg = ctx->config; 4511 const struct omap_dss_dsi_config *cfg = ctx->config;
4785 int bitspp = dsi_get_pixel_size(cfg->pixel_format); 4512 int bitspp = dsi_get_pixel_size(cfg->pixel_format);
4786 int ndl = dsi->num_lanes_used - 1; 4513 int ndl = dsi->num_lanes_used - 1;
4787 unsigned long hsclk = ctx->dsi_cinfo.clkin4ddr / 4; 4514 unsigned long hsclk = ctx->dsi_cinfo.clkdco / 4;
4788 unsigned long byteclk = hsclk / 4; 4515 unsigned long byteclk = hsclk / 4;
4789 4516
4790 unsigned long dispc_pck, req_pck_min, req_pck_nom, req_pck_max; 4517 unsigned long dispc_pck, req_pck_min, req_pck_nom, req_pck_max;
@@ -4999,14 +4726,14 @@ static bool dsi_vm_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
4999 return true; 4726 return true;
5000} 4727}
5001 4728
5002static bool dsi_vm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc, 4729static bool dsi_vm_calc_hsdiv_cb(int m_dispc, unsigned long dispc,
5003 void *data) 4730 void *data)
5004{ 4731{
5005 struct dsi_clk_calc_ctx *ctx = data; 4732 struct dsi_clk_calc_ctx *ctx = data;
5006 unsigned long pck_max; 4733 unsigned long pck_max;
5007 4734
5008 ctx->dsi_cinfo.regm_dispc = regm_dispc; 4735 ctx->dsi_cinfo.mX[HSDIV_DISPC] = m_dispc;
5009 ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc; 4736 ctx->dsi_cinfo.clkout[HSDIV_DISPC] = dispc;
5010 4737
5011 /* 4738 /*
5012 * In burst mode we can let the dispc pck be arbitrarily high, but it 4739 * In burst mode we can let the dispc pck be arbitrarily high, but it
@@ -5022,17 +4749,18 @@ static bool dsi_vm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
5022 dsi_vm_calc_dispc_cb, ctx); 4749 dsi_vm_calc_dispc_cb, ctx);
5023} 4750}
5024 4751
5025static bool dsi_vm_calc_pll_cb(int regn, int regm, unsigned long fint, 4752static bool dsi_vm_calc_pll_cb(int n, int m, unsigned long fint,
5026 unsigned long pll, void *data) 4753 unsigned long clkdco, void *data)
5027{ 4754{
5028 struct dsi_clk_calc_ctx *ctx = data; 4755 struct dsi_clk_calc_ctx *ctx = data;
5029 4756
5030 ctx->dsi_cinfo.regn = regn; 4757 ctx->dsi_cinfo.n = n;
5031 ctx->dsi_cinfo.regm = regm; 4758 ctx->dsi_cinfo.m = m;
5032 ctx->dsi_cinfo.fint = fint; 4759 ctx->dsi_cinfo.fint = fint;
5033 ctx->dsi_cinfo.clkin4ddr = pll; 4760 ctx->dsi_cinfo.clkdco = clkdco;
5034 4761
5035 return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->req_pck_min, 4762 return dss_pll_hsdiv_calc(ctx->pll, clkdco, ctx->req_pck_min,
4763 dss_feat_get_param_max(FEAT_PARAM_DSS_FCK),
5036 dsi_vm_calc_hsdiv_cb, ctx); 4764 dsi_vm_calc_hsdiv_cb, ctx);
5037} 4765}
5038 4766
@@ -5048,14 +4776,13 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
5048 int bitspp = dsi_get_pixel_size(cfg->pixel_format); 4776 int bitspp = dsi_get_pixel_size(cfg->pixel_format);
5049 unsigned long byteclk_min; 4777 unsigned long byteclk_min;
5050 4778
5051 clkin = clk_get_rate(dsi->sys_clk); 4779 clkin = clk_get_rate(dsi->pll.clkin);
5052 4780
5053 memset(ctx, 0, sizeof(*ctx)); 4781 memset(ctx, 0, sizeof(*ctx));
5054 ctx->dsidev = dsi->pdev; 4782 ctx->dsidev = dsi->pdev;
4783 ctx->pll = &dsi->pll;
5055 ctx->config = cfg; 4784 ctx->config = cfg;
5056 4785
5057 ctx->dsi_cinfo.clkin = clkin;
5058
5059 /* these limits should come from the panel driver */ 4786 /* these limits should come from the panel driver */
5060 ctx->req_pck_min = t->pixelclock - 1000; 4787 ctx->req_pck_min = t->pixelclock - 1000;
5061 ctx->req_pck_nom = t->pixelclock; 4788 ctx->req_pck_nom = t->pixelclock;
@@ -5074,7 +4801,7 @@ static bool dsi_vm_calc(struct dsi_data *dsi,
5074 pll_max = byteclk_max * 4 * 4; 4801 pll_max = byteclk_max * 4 * 4;
5075 } 4802 }
5076 4803
5077 return dsi_pll_calc(dsi->pdev, clkin, 4804 return dss_pll_calc(ctx->pll, clkin,
5078 pll_min, pll_max, 4805 pll_min, pll_max,
5079 dsi_vm_calc_pll_cb, ctx); 4806 dsi_vm_calc_pll_cb, ctx);
5080} 4807}
@@ -5106,8 +4833,8 @@ static int dsi_set_config(struct omap_dss_device *dssdev,
5106 4833
5107 dsi_pll_calc_dsi_fck(&ctx.dsi_cinfo); 4834 dsi_pll_calc_dsi_fck(&ctx.dsi_cinfo);
5108 4835
5109 r = dsi_lp_clock_calc(&ctx.dsi_cinfo, config->lp_clk_min, 4836 r = dsi_lp_clock_calc(ctx.dsi_cinfo.clkout[HSDIV_DSI],
5110 config->lp_clk_max); 4837 config->lp_clk_min, config->lp_clk_max, &dsi->user_lp_cinfo);
5111 if (r) { 4838 if (r) {
5112 DSSERR("failed to find suitable DSI LP clock settings\n"); 4839 DSSERR("failed to find suitable DSI LP clock settings\n");
5113 goto err; 4840 goto err;
@@ -5234,35 +4961,6 @@ static void dsi_release_vc(struct omap_dss_device *dssdev, int channel)
5234 } 4961 }
5235} 4962}
5236 4963
5237void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev)
5238{
5239 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 7, 1) != 1)
5240 DSSERR("%s (%s) not active\n",
5241 dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC),
5242 dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC));
5243}
5244
5245void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
5246{
5247 if (wait_for_bit_change(dsidev, DSI_PLL_STATUS, 8, 1) != 1)
5248 DSSERR("%s (%s) not active\n",
5249 dss_get_generic_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI),
5250 dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI));
5251}
5252
5253static void dsi_calc_clock_param_ranges(struct platform_device *dsidev)
5254{
5255 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
5256
5257 dsi->regn_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGN);
5258 dsi->regm_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM);
5259 dsi->regm_dispc_max =
5260 dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DISPC);
5261 dsi->regm_dsi_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_REGM_DSI);
5262 dsi->fint_min = dss_feat_get_param_min(FEAT_PARAM_DSIPLL_FINT);
5263 dsi->fint_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_FINT);
5264 dsi->lpdiv_max = dss_feat_get_param_max(FEAT_PARAM_DSIPLL_LPDIV);
5265}
5266 4964
5267static int dsi_get_clocks(struct platform_device *dsidev) 4965static int dsi_get_clocks(struct platform_device *dsidev)
5268{ 4966{
@@ -5277,14 +4975,6 @@ static int dsi_get_clocks(struct platform_device *dsidev)
5277 4975
5278 dsi->dss_clk = clk; 4976 dsi->dss_clk = clk;
5279 4977
5280 clk = devm_clk_get(&dsidev->dev, "sys_clk");
5281 if (IS_ERR(clk)) {
5282 DSSERR("can't get sys_clk\n");
5283 return PTR_ERR(clk);
5284 }
5285
5286 dsi->sys_clk = clk;
5287
5288 return 0; 4978 return 0;
5289} 4979}
5290 4980
@@ -5453,6 +5143,135 @@ err:
5453 return r; 5143 return r;
5454} 5144}
5455 5145
5146static const struct dss_pll_ops dsi_pll_ops = {
5147 .enable = dsi_pll_enable,
5148 .disable = dsi_pll_disable,
5149 .set_config = dss_pll_write_config_type_a,
5150};
5151
5152static const struct dss_pll_hw dss_omap3_dsi_pll_hw = {
5153 .n_max = (1 << 7) - 1,
5154 .m_max = (1 << 11) - 1,
5155 .mX_max = (1 << 4) - 1,
5156 .fint_min = 750000,
5157 .fint_max = 2100000,
5158 .clkdco_low = 1000000000,
5159 .clkdco_max = 1800000000,
5160
5161 .n_msb = 7,
5162 .n_lsb = 1,
5163 .m_msb = 18,
5164 .m_lsb = 8,
5165
5166 .mX_msb[0] = 22,
5167 .mX_lsb[0] = 19,
5168 .mX_msb[1] = 26,
5169 .mX_lsb[1] = 23,
5170
5171 .has_stopmode = true,
5172 .has_freqsel = true,
5173 .has_selfreqdco = false,
5174 .has_refsel = false,
5175};
5176
5177static const struct dss_pll_hw dss_omap4_dsi_pll_hw = {
5178 .n_max = (1 << 8) - 1,
5179 .m_max = (1 << 12) - 1,
5180 .mX_max = (1 << 5) - 1,
5181 .fint_min = 500000,
5182 .fint_max = 2500000,
5183 .clkdco_low = 1000000000,
5184 .clkdco_max = 1800000000,
5185
5186 .n_msb = 8,
5187 .n_lsb = 1,
5188 .m_msb = 20,
5189 .m_lsb = 9,
5190
5191 .mX_msb[0] = 25,
5192 .mX_lsb[0] = 21,
5193 .mX_msb[1] = 30,
5194 .mX_lsb[1] = 26,
5195
5196 .has_stopmode = true,
5197 .has_freqsel = false,
5198 .has_selfreqdco = false,
5199 .has_refsel = false,
5200};
5201
5202static const struct dss_pll_hw dss_omap5_dsi_pll_hw = {
5203 .n_max = (1 << 8) - 1,
5204 .m_max = (1 << 12) - 1,
5205 .mX_max = (1 << 5) - 1,
5206 .fint_min = 150000,
5207 .fint_max = 52000000,
5208 .clkdco_low = 1000000000,
5209 .clkdco_max = 1800000000,
5210
5211 .n_msb = 8,
5212 .n_lsb = 1,
5213 .m_msb = 20,
5214 .m_lsb = 9,
5215
5216 .mX_msb[0] = 25,
5217 .mX_lsb[0] = 21,
5218 .mX_msb[1] = 30,
5219 .mX_lsb[1] = 26,
5220
5221 .has_stopmode = true,
5222 .has_freqsel = false,
5223 .has_selfreqdco = true,
5224 .has_refsel = true,
5225};
5226
5227static int dsi_init_pll_data(struct platform_device *dsidev)
5228{
5229 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
5230 struct dss_pll *pll = &dsi->pll;
5231 struct clk *clk;
5232 int r;
5233
5234 clk = devm_clk_get(&dsidev->dev, "sys_clk");
5235 if (IS_ERR(clk)) {
5236 DSSERR("can't get sys_clk\n");
5237 return PTR_ERR(clk);
5238 }
5239
5240 pll->name = dsi->module_id == 0 ? "dsi0" : "dsi1";
5241 pll->clkin = clk;
5242 pll->base = dsi->pll_base;
5243
5244 switch (omapdss_get_version()) {
5245 case OMAPDSS_VER_OMAP34xx_ES1:
5246 case OMAPDSS_VER_OMAP34xx_ES3:
5247 case OMAPDSS_VER_OMAP3630:
5248 case OMAPDSS_VER_AM35xx:
5249 pll->hw = &dss_omap3_dsi_pll_hw;
5250 break;
5251
5252 case OMAPDSS_VER_OMAP4430_ES1:
5253 case OMAPDSS_VER_OMAP4430_ES2:
5254 case OMAPDSS_VER_OMAP4:
5255 pll->hw = &dss_omap4_dsi_pll_hw;
5256 break;
5257
5258 case OMAPDSS_VER_OMAP5:
5259 pll->hw = &dss_omap5_dsi_pll_hw;
5260 break;
5261
5262 default:
5263 return -ENODEV;
5264 }
5265
5266 pll->ops = &dsi_pll_ops;
5267
5268 r = dss_pll_register(pll);
5269 if (r)
5270 return r;
5271
5272 return 0;
5273}
5274
5456/* DSI1 HW IP initialisation */ 5275/* DSI1 HW IP initialisation */
5457static int omap_dsihw_probe(struct platform_device *dsidev) 5276static int omap_dsihw_probe(struct platform_device *dsidev)
5458{ 5277{
@@ -5598,12 +5417,12 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
5598 dsi->vc[i].vc_id = 0; 5417 dsi->vc[i].vc_id = 0;
5599 } 5418 }
5600 5419
5601 dsi_calc_clock_param_ranges(dsidev);
5602
5603 r = dsi_get_clocks(dsidev); 5420 r = dsi_get_clocks(dsidev);
5604 if (r) 5421 if (r)
5605 return r; 5422 return r;
5606 5423
5424 dsi_init_pll_data(dsidev);
5425
5607 pm_runtime_enable(&dsidev->dev); 5426 pm_runtime_enable(&dsidev->dev);
5608 5427
5609 r = dsi_runtime_get(dsidev); 5428 r = dsi_runtime_get(dsidev);
@@ -5672,6 +5491,8 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
5672 5491
5673 WARN_ON(dsi->scp_clk_refcount > 0); 5492 WARN_ON(dsi->scp_clk_refcount > 0);
5674 5493
5494 dss_pll_unregister(&dsi->pll);
5495
5675 dsi_uninit_output(dsidev); 5496 dsi_uninit_output(dsidev);
5676 5497
5677 pm_runtime_disable(&dsidev->dev); 5498 pm_runtime_disable(&dsidev->dev);
diff --git a/drivers/video/fbdev/omap2/dss/dss-of.c b/drivers/video/fbdev/omap2/dss/dss-of.c
index a4b20aaf6142..928ee639c0c1 100644
--- a/drivers/video/fbdev/omap2/dss/dss-of.c
+++ b/drivers/video/fbdev/omap2/dss/dss-of.c
@@ -20,6 +20,8 @@
20 20
21#include <video/omapdss.h> 21#include <video/omapdss.h>
22 22
23#include "dss.h"
24
23struct device_node * 25struct device_node *
24omapdss_of_get_next_port(const struct device_node *parent, 26omapdss_of_get_next_port(const struct device_node *parent,
25 struct device_node *prev) 27 struct device_node *prev)
@@ -84,20 +86,17 @@ omapdss_of_get_next_endpoint(const struct device_node *parent,
84} 86}
85EXPORT_SYMBOL_GPL(omapdss_of_get_next_endpoint); 87EXPORT_SYMBOL_GPL(omapdss_of_get_next_endpoint);
86 88
87static struct device_node * 89struct device_node *dss_of_port_get_parent_device(struct device_node *port)
88omapdss_of_get_remote_device_node(const struct device_node *node)
89{ 90{
90 struct device_node *np; 91 struct device_node *np;
91 int i; 92 int i;
92 93
93 np = of_parse_phandle(node, "remote-endpoint", 0); 94 if (!port)
94
95 if (!np)
96 return NULL; 95 return NULL;
97 96
98 np = of_get_next_parent(np); 97 np = of_get_next_parent(port);
99 98
100 for (i = 0; i < 3 && np; ++i) { 99 for (i = 0; i < 2 && np; ++i) {
101 struct property *prop; 100 struct property *prop;
102 101
103 prop = of_find_property(np, "compatible", NULL); 102 prop = of_find_property(np, "compatible", NULL);
@@ -111,6 +110,31 @@ omapdss_of_get_remote_device_node(const struct device_node *node)
111 return NULL; 110 return NULL;
112} 111}
113 112
113u32 dss_of_port_get_port_number(struct device_node *port)
114{
115 int r;
116 u32 reg;
117
118 r = of_property_read_u32(port, "reg", &reg);
119 if (r)
120 reg = 0;
121
122 return reg;
123}
124
125static struct device_node *omapdss_of_get_remote_port(const struct device_node *node)
126{
127 struct device_node *np;
128
129 np = of_parse_phandle(node, "remote-endpoint", 0);
130 if (!np)
131 return NULL;
132
133 np = of_get_next_parent(np);
134
135 return np;
136}
137
114struct device_node * 138struct device_node *
115omapdss_of_get_first_endpoint(const struct device_node *parent) 139omapdss_of_get_first_endpoint(const struct device_node *parent)
116{ 140{
@@ -133,27 +157,25 @@ struct omap_dss_device *
133omapdss_of_find_source_for_first_ep(struct device_node *node) 157omapdss_of_find_source_for_first_ep(struct device_node *node)
134{ 158{
135 struct device_node *ep; 159 struct device_node *ep;
136 struct device_node *src_node; 160 struct device_node *src_port;
137 struct omap_dss_device *src; 161 struct omap_dss_device *src;
138 162
139 ep = omapdss_of_get_first_endpoint(node); 163 ep = omapdss_of_get_first_endpoint(node);
140 if (!ep) 164 if (!ep)
141 return ERR_PTR(-EINVAL); 165 return ERR_PTR(-EINVAL);
142 166
143 src_node = omapdss_of_get_remote_device_node(ep); 167 src_port = omapdss_of_get_remote_port(ep);
144 168 if (!src_port) {
145 of_node_put(ep); 169 of_node_put(ep);
146
147 if (!src_node)
148 return ERR_PTR(-EINVAL); 170 return ERR_PTR(-EINVAL);
171 }
149 172
150 src = omap_dss_find_output_by_node(src_node); 173 of_node_put(ep);
151 174
152 of_node_put(src_node); 175 src = omap_dss_find_output_by_port_node(src_port);
153 176
154 if (!src) 177 of_node_put(src_port);
155 return ERR_PTR(-EPROBE_DEFER);
156 178
157 return src; 179 return src ? src : ERR_PTR(-EPROBE_DEFER);
158} 180}
159EXPORT_SYMBOL_GPL(omapdss_of_find_source_for_first_ep); 181EXPORT_SYMBOL_GPL(omapdss_of_find_source_for_first_ep);
diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
index 14bcd6c43f72..702c495083ed 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -70,7 +70,9 @@ struct dss_features {
70 u8 fck_div_max; 70 u8 fck_div_max;
71 u8 dss_fck_multiplier; 71 u8 dss_fck_multiplier;
72 const char *parent_clk_name; 72 const char *parent_clk_name;
73 int (*dpi_select_source)(enum omap_channel channel); 73 enum omap_display_type *ports;
74 int num_ports;
75 int (*dpi_select_source)(int port, enum omap_channel channel);
74}; 76};
75 77
76static struct { 78static struct {
@@ -294,7 +296,6 @@ static void dss_dump_regs(struct seq_file *s)
294 296
295static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src) 297static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
296{ 298{
297 struct platform_device *dsidev;
298 int b; 299 int b;
299 u8 start, end; 300 u8 start, end;
300 301
@@ -304,13 +305,9 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
304 break; 305 break;
305 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 306 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
306 b = 1; 307 b = 1;
307 dsidev = dsi_get_dsidev_from_id(0);
308 dsi_wait_pll_hsdiv_dispc_active(dsidev);
309 break; 308 break;
310 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: 309 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
311 b = 2; 310 b = 2;
312 dsidev = dsi_get_dsidev_from_id(1);
313 dsi_wait_pll_hsdiv_dispc_active(dsidev);
314 break; 311 break;
315 default: 312 default:
316 BUG(); 313 BUG();
@@ -327,7 +324,6 @@ static void dss_select_dispc_clk_source(enum omap_dss_clk_source clk_src)
327void dss_select_dsi_clk_source(int dsi_module, 324void dss_select_dsi_clk_source(int dsi_module,
328 enum omap_dss_clk_source clk_src) 325 enum omap_dss_clk_source clk_src)
329{ 326{
330 struct platform_device *dsidev;
331 int b, pos; 327 int b, pos;
332 328
333 switch (clk_src) { 329 switch (clk_src) {
@@ -337,14 +333,10 @@ void dss_select_dsi_clk_source(int dsi_module,
337 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI: 333 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI:
338 BUG_ON(dsi_module != 0); 334 BUG_ON(dsi_module != 0);
339 b = 1; 335 b = 1;
340 dsidev = dsi_get_dsidev_from_id(0);
341 dsi_wait_pll_hsdiv_dsi_active(dsidev);
342 break; 336 break;
343 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI: 337 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI:
344 BUG_ON(dsi_module != 1); 338 BUG_ON(dsi_module != 1);
345 b = 1; 339 b = 1;
346 dsidev = dsi_get_dsidev_from_id(1);
347 dsi_wait_pll_hsdiv_dsi_active(dsidev);
348 break; 340 break;
349 default: 341 default:
350 BUG(); 342 BUG();
@@ -360,7 +352,6 @@ void dss_select_dsi_clk_source(int dsi_module,
360void dss_select_lcd_clk_source(enum omap_channel channel, 352void dss_select_lcd_clk_source(enum omap_channel channel,
361 enum omap_dss_clk_source clk_src) 353 enum omap_dss_clk_source clk_src)
362{ 354{
363 struct platform_device *dsidev;
364 int b, ix, pos; 355 int b, ix, pos;
365 356
366 if (!dss_has_feature(FEAT_LCD_CLK_SRC)) { 357 if (!dss_has_feature(FEAT_LCD_CLK_SRC)) {
@@ -375,15 +366,11 @@ void dss_select_lcd_clk_source(enum omap_channel channel,
375 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC: 366 case OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC:
376 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD); 367 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD);
377 b = 1; 368 b = 1;
378 dsidev = dsi_get_dsidev_from_id(0);
379 dsi_wait_pll_hsdiv_dispc_active(dsidev);
380 break; 369 break;
381 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC: 370 case OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC:
382 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 && 371 BUG_ON(channel != OMAP_DSS_CHANNEL_LCD2 &&
383 channel != OMAP_DSS_CHANNEL_LCD3); 372 channel != OMAP_DSS_CHANNEL_LCD3);
384 b = 1; 373 b = 1;
385 dsidev = dsi_get_dsidev_from_id(1);
386 dsi_wait_pll_hsdiv_dispc_active(dsidev);
387 break; 374 break;
388 default: 375 default:
389 BUG(); 376 BUG();
@@ -564,7 +551,7 @@ enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void)
564 return REG_GET(DSS_CONTROL, 15, 15); 551 return REG_GET(DSS_CONTROL, 15, 15);
565} 552}
566 553
567static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel) 554static int dss_dpi_select_source_omap2_omap3(int port, enum omap_channel channel)
568{ 555{
569 if (channel != OMAP_DSS_CHANNEL_LCD) 556 if (channel != OMAP_DSS_CHANNEL_LCD)
570 return -EINVAL; 557 return -EINVAL;
@@ -572,7 +559,7 @@ static int dss_dpi_select_source_omap2_omap3(enum omap_channel channel)
572 return 0; 559 return 0;
573} 560}
574 561
575static int dss_dpi_select_source_omap4(enum omap_channel channel) 562static int dss_dpi_select_source_omap4(int port, enum omap_channel channel)
576{ 563{
577 int val; 564 int val;
578 565
@@ -592,7 +579,7 @@ static int dss_dpi_select_source_omap4(enum omap_channel channel)
592 return 0; 579 return 0;
593} 580}
594 581
595static int dss_dpi_select_source_omap5(enum omap_channel channel) 582static int dss_dpi_select_source_omap5(int port, enum omap_channel channel)
596{ 583{
597 int val; 584 int val;
598 585
@@ -618,9 +605,9 @@ static int dss_dpi_select_source_omap5(enum omap_channel channel)
618 return 0; 605 return 0;
619} 606}
620 607
621int dss_dpi_select_source(enum omap_channel channel) 608int dss_dpi_select_source(int port, enum omap_channel channel)
622{ 609{
623 return dss.feat->dpi_select_source(channel); 610 return dss.feat->dpi_select_source(port, channel);
624} 611}
625 612
626static int dss_get_clocks(void) 613static int dss_get_clocks(void)
@@ -689,6 +676,16 @@ void dss_debug_dump_clocks(struct seq_file *s)
689} 676}
690#endif 677#endif
691 678
679
680static enum omap_display_type omap2plus_ports[] = {
681 OMAP_DISPLAY_TYPE_DPI,
682};
683
684static enum omap_display_type omap34xx_ports[] = {
685 OMAP_DISPLAY_TYPE_DPI,
686 OMAP_DISPLAY_TYPE_SDI,
687};
688
692static const struct dss_features omap24xx_dss_feats __initconst = { 689static const struct dss_features omap24xx_dss_feats __initconst = {
693 /* 690 /*
694 * fck div max is really 16, but the divider range has gaps. The range 691 * fck div max is really 16, but the divider range has gaps. The range
@@ -698,6 +695,8 @@ static const struct dss_features omap24xx_dss_feats __initconst = {
698 .dss_fck_multiplier = 2, 695 .dss_fck_multiplier = 2,
699 .parent_clk_name = "core_ck", 696 .parent_clk_name = "core_ck",
700 .dpi_select_source = &dss_dpi_select_source_omap2_omap3, 697 .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
698 .ports = omap2plus_ports,
699 .num_ports = ARRAY_SIZE(omap2plus_ports),
701}; 700};
702 701
703static const struct dss_features omap34xx_dss_feats __initconst = { 702static const struct dss_features omap34xx_dss_feats __initconst = {
@@ -705,6 +704,8 @@ static const struct dss_features omap34xx_dss_feats __initconst = {
705 .dss_fck_multiplier = 2, 704 .dss_fck_multiplier = 2,
706 .parent_clk_name = "dpll4_ck", 705 .parent_clk_name = "dpll4_ck",
707 .dpi_select_source = &dss_dpi_select_source_omap2_omap3, 706 .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
707 .ports = omap34xx_ports,
708 .num_ports = ARRAY_SIZE(omap34xx_ports),
708}; 709};
709 710
710static const struct dss_features omap3630_dss_feats __initconst = { 711static const struct dss_features omap3630_dss_feats __initconst = {
@@ -712,6 +713,8 @@ static const struct dss_features omap3630_dss_feats __initconst = {
712 .dss_fck_multiplier = 1, 713 .dss_fck_multiplier = 1,
713 .parent_clk_name = "dpll4_ck", 714 .parent_clk_name = "dpll4_ck",
714 .dpi_select_source = &dss_dpi_select_source_omap2_omap3, 715 .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
716 .ports = omap2plus_ports,
717 .num_ports = ARRAY_SIZE(omap2plus_ports),
715}; 718};
716 719
717static const struct dss_features omap44xx_dss_feats __initconst = { 720static const struct dss_features omap44xx_dss_feats __initconst = {
@@ -719,6 +722,8 @@ static const struct dss_features omap44xx_dss_feats __initconst = {
719 .dss_fck_multiplier = 1, 722 .dss_fck_multiplier = 1,
720 .parent_clk_name = "dpll_per_x2_ck", 723 .parent_clk_name = "dpll_per_x2_ck",
721 .dpi_select_source = &dss_dpi_select_source_omap4, 724 .dpi_select_source = &dss_dpi_select_source_omap4,
725 .ports = omap2plus_ports,
726 .num_ports = ARRAY_SIZE(omap2plus_ports),
722}; 727};
723 728
724static const struct dss_features omap54xx_dss_feats __initconst = { 729static const struct dss_features omap54xx_dss_feats __initconst = {
@@ -726,6 +731,8 @@ static const struct dss_features omap54xx_dss_feats __initconst = {
726 .dss_fck_multiplier = 1, 731 .dss_fck_multiplier = 1,
727 .parent_clk_name = "dpll_per_x2_ck", 732 .parent_clk_name = "dpll_per_x2_ck",
728 .dpi_select_source = &dss_dpi_select_source_omap5, 733 .dpi_select_source = &dss_dpi_select_source_omap5,
734 .ports = omap2plus_ports,
735 .num_ports = ARRAY_SIZE(omap2plus_ports),
729}; 736};
730 737
731static const struct dss_features am43xx_dss_feats __initconst = { 738static const struct dss_features am43xx_dss_feats __initconst = {
@@ -733,6 +740,8 @@ static const struct dss_features am43xx_dss_feats __initconst = {
733 .dss_fck_multiplier = 0, 740 .dss_fck_multiplier = 0,
734 .parent_clk_name = NULL, 741 .parent_clk_name = NULL,
735 .dpi_select_source = &dss_dpi_select_source_omap2_omap3, 742 .dpi_select_source = &dss_dpi_select_source_omap2_omap3,
743 .ports = omap2plus_ports,
744 .num_ports = ARRAY_SIZE(omap2plus_ports),
736}; 745};
737 746
738static int __init dss_init_features(struct platform_device *pdev) 747static int __init dss_init_features(struct platform_device *pdev)
@@ -798,37 +807,77 @@ static int __init dss_init_ports(struct platform_device *pdev)
798 if (!port) 807 if (!port)
799 return 0; 808 return 0;
800 809
810 if (dss.feat->num_ports == 0)
811 return 0;
812
801 do { 813 do {
814 enum omap_display_type port_type;
802 u32 reg; 815 u32 reg;
803 816
804 r = of_property_read_u32(port, "reg", &reg); 817 r = of_property_read_u32(port, "reg", &reg);
805 if (r) 818 if (r)
806 reg = 0; 819 reg = 0;
807 820
808#ifdef CONFIG_OMAP2_DSS_DPI 821 if (reg >= dss.feat->num_ports)
809 if (reg == 0) 822 continue;
810 dpi_init_port(pdev, port);
811#endif
812 823
813#ifdef CONFIG_OMAP2_DSS_SDI 824 port_type = dss.feat->ports[reg];
814 if (reg == 1)
815 sdi_init_port(pdev, port);
816#endif
817 825
826 switch (port_type) {
827 case OMAP_DISPLAY_TYPE_DPI:
828 dpi_init_port(pdev, port);
829 break;
830 case OMAP_DISPLAY_TYPE_SDI:
831 sdi_init_port(pdev, port);
832 break;
833 default:
834 break;
835 }
818 } while ((port = omapdss_of_get_next_port(parent, port)) != NULL); 836 } while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
819 837
820 return 0; 838 return 0;
821} 839}
822 840
823static void __exit dss_uninit_ports(void) 841static void __exit dss_uninit_ports(struct platform_device *pdev)
824{ 842{
825#ifdef CONFIG_OMAP2_DSS_DPI 843 struct device_node *parent = pdev->dev.of_node;
826 dpi_uninit_port(); 844 struct device_node *port;
827#endif
828 845
829#ifdef CONFIG_OMAP2_DSS_SDI 846 if (parent == NULL)
830 sdi_uninit_port(); 847 return;
831#endif 848
849 port = omapdss_of_get_next_port(parent, NULL);
850 if (!port)
851 return;
852
853 if (dss.feat->num_ports == 0)
854 return;
855
856 do {
857 enum omap_display_type port_type;
858 u32 reg;
859 int r;
860
861 r = of_property_read_u32(port, "reg", &reg);
862 if (r)
863 reg = 0;
864
865 if (reg >= dss.feat->num_ports)
866 continue;
867
868 port_type = dss.feat->ports[reg];
869
870 switch (port_type) {
871 case OMAP_DISPLAY_TYPE_DPI:
872 dpi_uninit_port(port);
873 break;
874 case OMAP_DISPLAY_TYPE_SDI:
875 sdi_uninit_port(port);
876 break;
877 default:
878 break;
879 }
880 } while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
832} 881}
833 882
834/* DSS HW IP initialisation */ 883/* DSS HW IP initialisation */
@@ -910,7 +959,7 @@ err_setup_clocks:
910 959
911static int __exit omap_dsshw_remove(struct platform_device *pdev) 960static int __exit omap_dsshw_remove(struct platform_device *pdev)
912{ 961{
913 dss_uninit_ports(); 962 dss_uninit_ports(pdev);
914 963
915 pm_runtime_disable(&pdev->dev); 964 pm_runtime_disable(&pdev->dev);
916 965
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 8ff22c134c62..14fb0c23f4a2 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -100,35 +100,77 @@ enum dss_writeback_channel {
100 DSS_WB_LCD3_MGR = 7, 100 DSS_WB_LCD3_MGR = 7,
101}; 101};
102 102
103struct dispc_clock_info { 103struct dss_pll;
104
105#define DSS_PLL_MAX_HSDIVS 4
106
107/*
108 * Type-A PLLs: clkout[]/mX[] refer to hsdiv outputs m4, m5, m6, m7.
109 * Type-B PLLs: clkout[0] refers to m2.
110 */
111struct dss_pll_clock_info {
104 /* rates that we get with dividers below */ 112 /* rates that we get with dividers below */
105 unsigned long lck; 113 unsigned long fint;
106 unsigned long pck; 114 unsigned long clkdco;
115 unsigned long clkout[DSS_PLL_MAX_HSDIVS];
107 116
108 /* dividers */ 117 /* dividers */
109 u16 lck_div; 118 u16 n;
110 u16 pck_div; 119 u16 m;
120 u32 mf;
121 u16 mX[DSS_PLL_MAX_HSDIVS];
122 u16 sd;
123};
124
125struct dss_pll_ops {
126 int (*enable)(struct dss_pll *pll);
127 void (*disable)(struct dss_pll *pll);
128 int (*set_config)(struct dss_pll *pll,
129 const struct dss_pll_clock_info *cinfo);
130};
131
132struct dss_pll_hw {
133 unsigned n_max;
134 unsigned m_min;
135 unsigned m_max;
136 unsigned mX_max;
137
138 unsigned long fint_min, fint_max;
139 unsigned long clkdco_min, clkdco_low, clkdco_max;
140
141 u8 n_msb, n_lsb;
142 u8 m_msb, m_lsb;
143 u8 mX_msb[DSS_PLL_MAX_HSDIVS], mX_lsb[DSS_PLL_MAX_HSDIVS];
144
145 bool has_stopmode;
146 bool has_freqsel;
147 bool has_selfreqdco;
148 bool has_refsel;
111}; 149};
112 150
113struct dsi_clock_info { 151struct dss_pll {
152 const char *name;
153
154 struct clk *clkin;
155 struct regulator *regulator;
156
157 void __iomem *base;
158
159 const struct dss_pll_hw *hw;
160
161 const struct dss_pll_ops *ops;
162
163 struct dss_pll_clock_info cinfo;
164};
165
166struct dispc_clock_info {
114 /* rates that we get with dividers below */ 167 /* rates that we get with dividers below */
115 unsigned long fint; 168 unsigned long lck;
116 unsigned long clkin4ddr; 169 unsigned long pck;
117 unsigned long clkin;
118 unsigned long dsi_pll_hsdiv_dispc_clk; /* OMAP3: DSI1_PLL_CLK
119 * OMAP4: PLLx_CLK1 */
120 unsigned long dsi_pll_hsdiv_dsi_clk; /* OMAP3: DSI2_PLL_CLK
121 * OMAP4: PLLx_CLK2 */
122 unsigned long lp_clk;
123 170
124 /* dividers */ 171 /* dividers */
125 u16 regn; 172 u16 lck_div;
126 u16 regm; 173 u16 pck_div;
127 u16 regm_dispc; /* OMAP3: REGM3
128 * OMAP4: REGM4 */
129 u16 regm_dsi; /* OMAP3: REGM4
130 * OMAP4: REGM5 */
131 u16 lp_clk_div;
132}; 174};
133 175
134struct dss_lcd_mgr_config { 176struct dss_lcd_mgr_config {
@@ -209,12 +251,16 @@ int dss_init_platform_driver(void) __init;
209void dss_uninit_platform_driver(void); 251void dss_uninit_platform_driver(void);
210 252
211unsigned long dss_get_dispc_clk_rate(void); 253unsigned long dss_get_dispc_clk_rate(void);
212int dss_dpi_select_source(enum omap_channel channel); 254int dss_dpi_select_source(int port, enum omap_channel channel);
213void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select); 255void dss_select_hdmi_venc_clk_source(enum dss_hdmi_venc_clk_source_select);
214enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void); 256enum dss_hdmi_venc_clk_source_select dss_get_hdmi_venc_clk_source(void);
215const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src); 257const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src);
216void dss_dump_clocks(struct seq_file *s); 258void dss_dump_clocks(struct seq_file *s);
217 259
260/* dss-of */
261struct device_node *dss_of_port_get_parent_device(struct device_node *port);
262u32 dss_of_port_get_port_number(struct device_node *port);
263
218#if defined(CONFIG_OMAP2_DSS_DEBUGFS) 264#if defined(CONFIG_OMAP2_DSS_DEBUGFS)
219void dss_debug_dump_clocks(struct seq_file *s); 265void dss_debug_dump_clocks(struct seq_file *s);
220#endif 266#endif
@@ -244,16 +290,22 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
244int sdi_init_platform_driver(void) __init; 290int sdi_init_platform_driver(void) __init;
245void sdi_uninit_platform_driver(void) __exit; 291void sdi_uninit_platform_driver(void) __exit;
246 292
293#ifdef CONFIG_OMAP2_DSS_SDI
247int sdi_init_port(struct platform_device *pdev, struct device_node *port) __init; 294int sdi_init_port(struct platform_device *pdev, struct device_node *port) __init;
248void sdi_uninit_port(void) __exit; 295void sdi_uninit_port(struct device_node *port) __exit;
296#else
297static inline int __init sdi_init_port(struct platform_device *pdev,
298 struct device_node *port)
299{
300 return 0;
301}
302static inline void __exit sdi_uninit_port(struct device_node *port)
303{
304}
305#endif
249 306
250/* DSI */ 307/* DSI */
251 308
252typedef bool (*dsi_pll_calc_func)(int regn, int regm, unsigned long fint,
253 unsigned long pll, void *data);
254typedef bool (*dsi_hsdiv_calc_func)(int regm_dispc, unsigned long dispc,
255 void *data);
256
257#ifdef CONFIG_OMAP2_DSS_DSI 309#ifdef CONFIG_OMAP2_DSS_DSI
258 310
259struct dentry; 311struct dentry;
@@ -262,104 +314,36 @@ struct file_operations;
262int dsi_init_platform_driver(void) __init; 314int dsi_init_platform_driver(void) __init;
263void dsi_uninit_platform_driver(void) __exit; 315void dsi_uninit_platform_driver(void) __exit;
264 316
265int dsi_runtime_get(struct platform_device *dsidev);
266void dsi_runtime_put(struct platform_device *dsidev);
267
268void dsi_dump_clocks(struct seq_file *s); 317void dsi_dump_clocks(struct seq_file *s);
269 318
270void dsi_irq_handler(void); 319void dsi_irq_handler(void);
271u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt); 320u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt);
272 321
273unsigned long dsi_get_pll_clkin(struct platform_device *dsidev);
274
275bool dsi_hsdiv_calc(struct platform_device *dsidev, unsigned long pll,
276 unsigned long out_min, dsi_hsdiv_calc_func func, void *data);
277bool dsi_pll_calc(struct platform_device *dsidev, unsigned long clkin,
278 unsigned long pll_min, unsigned long pll_max,
279 dsi_pll_calc_func func, void *data);
280
281unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
282int dsi_pll_set_clock_div(struct platform_device *dsidev,
283 struct dsi_clock_info *cinfo);
284int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
285 bool enable_hsdiv);
286void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
287void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev);
288void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev);
289struct platform_device *dsi_get_dsidev_from_id(int module);
290#else 322#else
291static inline int dsi_runtime_get(struct platform_device *dsidev)
292{
293 return 0;
294}
295static inline void dsi_runtime_put(struct platform_device *dsidev)
296{
297}
298static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt) 323static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
299{ 324{
300 WARN("%s: DSI not compiled in, returning pixel_size as 0\n", __func__); 325 WARN("%s: DSI not compiled in, returning pixel_size as 0\n", __func__);
301 return 0; 326 return 0;
302} 327}
303static inline unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev)
304{
305 WARN("%s: DSI not compiled in, returning rate as 0\n", __func__);
306 return 0;
307}
308static inline int dsi_pll_set_clock_div(struct platform_device *dsidev,
309 struct dsi_clock_info *cinfo)
310{
311 WARN("%s: DSI not compiled in\n", __func__);
312 return -ENODEV;
313}
314static inline int dsi_pll_init(struct platform_device *dsidev,
315 bool enable_hsclk, bool enable_hsdiv)
316{
317 WARN("%s: DSI not compiled in\n", __func__);
318 return -ENODEV;
319}
320static inline void dsi_pll_uninit(struct platform_device *dsidev,
321 bool disconnect_lanes)
322{
323}
324static inline void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev)
325{
326}
327static inline void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev)
328{
329}
330static inline struct platform_device *dsi_get_dsidev_from_id(int module)
331{
332 return NULL;
333}
334
335static inline unsigned long dsi_get_pll_clkin(struct platform_device *dsidev)
336{
337 return 0;
338}
339
340static inline bool dsi_hsdiv_calc(struct platform_device *dsidev,
341 unsigned long pll, unsigned long out_min,
342 dsi_hsdiv_calc_func func, void *data)
343{
344 return false;
345}
346
347static inline bool dsi_pll_calc(struct platform_device *dsidev,
348 unsigned long clkin,
349 unsigned long pll_min, unsigned long pll_max,
350 dsi_pll_calc_func func, void *data)
351{
352 return false;
353}
354
355#endif 328#endif
356 329
357/* DPI */ 330/* DPI */
358int dpi_init_platform_driver(void) __init; 331int dpi_init_platform_driver(void) __init;
359void dpi_uninit_platform_driver(void) __exit; 332void dpi_uninit_platform_driver(void) __exit;
360 333
334#ifdef CONFIG_OMAP2_DSS_DPI
361int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init; 335int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init;
362void dpi_uninit_port(void) __exit; 336void dpi_uninit_port(struct device_node *port) __exit;
337#else
338static inline int __init dpi_init_port(struct platform_device *pdev,
339 struct device_node *port)
340{
341 return 0;
342}
343static inline void __exit dpi_uninit_port(struct device_node *port)
344{
345}
346#endif
363 347
364/* DISPC */ 348/* DISPC */
365int dispc_init_platform_driver(void) __init; 349int dispc_init_platform_driver(void) __init;
@@ -438,4 +422,29 @@ static inline void dss_collect_irq_stats(u32 irqstatus, unsigned *irq_arr)
438} 422}
439#endif 423#endif
440 424
425/* PLL */
426typedef bool (*dss_pll_calc_func)(int n, int m, unsigned long fint,
427 unsigned long clkdco, void *data);
428typedef bool (*dss_hsdiv_calc_func)(int m_dispc, unsigned long dispc,
429 void *data);
430
431int dss_pll_register(struct dss_pll *pll);
432void dss_pll_unregister(struct dss_pll *pll);
433struct dss_pll *dss_pll_find(const char *name);
434int dss_pll_enable(struct dss_pll *pll);
435void dss_pll_disable(struct dss_pll *pll);
436int dss_pll_set_config(struct dss_pll *pll,
437 const struct dss_pll_clock_info *cinfo);
438
439bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco,
440 unsigned long out_min, unsigned long out_max,
441 dss_hsdiv_calc_func func, void *data);
442bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin,
443 unsigned long pll_min, unsigned long pll_max,
444 dss_pll_calc_func func, void *data);
445int dss_pll_write_config_type_a(struct dss_pll *pll,
446 const struct dss_pll_clock_info *cinfo);
447int dss_pll_write_config_type_b(struct dss_pll *pll,
448 const struct dss_pll_clock_info *cinfo);
449
441#endif 450#endif
diff --git a/drivers/video/fbdev/omap2/dss/dss_features.c b/drivers/video/fbdev/omap2/dss/dss_features.c
index 15088df7bd16..0e3da809473c 100644
--- a/drivers/video/fbdev/omap2/dss/dss_features.c
+++ b/drivers/video/fbdev/omap2/dss/dss_features.c
@@ -72,10 +72,6 @@ static const struct dss_reg_field omap2_dss_reg_fields[] = {
72 [FEAT_REG_HORIZONTALACCU] = { 9, 0 }, 72 [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
73 [FEAT_REG_VERTICALACCU] = { 25, 16 }, 73 [FEAT_REG_VERTICALACCU] = { 25, 16 },
74 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 }, 74 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
75 [FEAT_REG_DSIPLL_REGN] = { 0, 0 },
76 [FEAT_REG_DSIPLL_REGM] = { 0, 0 },
77 [FEAT_REG_DSIPLL_REGM_DISPC] = { 0, 0 },
78 [FEAT_REG_DSIPLL_REGM_DSI] = { 0, 0 },
79}; 75};
80 76
81static const struct dss_reg_field omap3_dss_reg_fields[] = { 77static const struct dss_reg_field omap3_dss_reg_fields[] = {
@@ -87,10 +83,6 @@ static const struct dss_reg_field omap3_dss_reg_fields[] = {
87 [FEAT_REG_HORIZONTALACCU] = { 9, 0 }, 83 [FEAT_REG_HORIZONTALACCU] = { 9, 0 },
88 [FEAT_REG_VERTICALACCU] = { 25, 16 }, 84 [FEAT_REG_VERTICALACCU] = { 25, 16 },
89 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 }, 85 [FEAT_REG_DISPC_CLK_SWITCH] = { 0, 0 },
90 [FEAT_REG_DSIPLL_REGN] = { 7, 1 },
91 [FEAT_REG_DSIPLL_REGM] = { 18, 8 },
92 [FEAT_REG_DSIPLL_REGM_DISPC] = { 22, 19 },
93 [FEAT_REG_DSIPLL_REGM_DSI] = { 26, 23 },
94}; 86};
95 87
96static const struct dss_reg_field am43xx_dss_reg_fields[] = { 88static const struct dss_reg_field am43xx_dss_reg_fields[] = {
@@ -113,10 +105,6 @@ static const struct dss_reg_field omap4_dss_reg_fields[] = {
113 [FEAT_REG_HORIZONTALACCU] = { 10, 0 }, 105 [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
114 [FEAT_REG_VERTICALACCU] = { 26, 16 }, 106 [FEAT_REG_VERTICALACCU] = { 26, 16 },
115 [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 }, 107 [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 8 },
116 [FEAT_REG_DSIPLL_REGN] = { 8, 1 },
117 [FEAT_REG_DSIPLL_REGM] = { 20, 9 },
118 [FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 },
119 [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
120}; 108};
121 109
122static const struct dss_reg_field omap5_dss_reg_fields[] = { 110static const struct dss_reg_field omap5_dss_reg_fields[] = {
@@ -128,10 +116,6 @@ static const struct dss_reg_field omap5_dss_reg_fields[] = {
128 [FEAT_REG_HORIZONTALACCU] = { 10, 0 }, 116 [FEAT_REG_HORIZONTALACCU] = { 10, 0 },
129 [FEAT_REG_VERTICALACCU] = { 26, 16 }, 117 [FEAT_REG_VERTICALACCU] = { 26, 16 },
130 [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 7 }, 118 [FEAT_REG_DISPC_CLK_SWITCH] = { 9, 7 },
131 [FEAT_REG_DSIPLL_REGN] = { 8, 1 },
132 [FEAT_REG_DSIPLL_REGM] = { 20, 9 },
133 [FEAT_REG_DSIPLL_REGM_DISPC] = { 25, 21 },
134 [FEAT_REG_DSIPLL_REGM_DSI] = { 30, 26 },
135}; 119};
136 120
137static const enum omap_display_type omap2_dss_supported_displays[] = { 121static const enum omap_display_type omap2_dss_supported_displays[] = {
@@ -437,12 +421,6 @@ static const char * const omap5_dss_clk_source_names[] = {
437static const struct dss_param_range omap2_dss_param_range[] = { 421static const struct dss_param_range omap2_dss_param_range[] = {
438 [FEAT_PARAM_DSS_FCK] = { 0, 133000000 }, 422 [FEAT_PARAM_DSS_FCK] = { 0, 133000000 },
439 [FEAT_PARAM_DSS_PCD] = { 2, 255 }, 423 [FEAT_PARAM_DSS_PCD] = { 2, 255 },
440 [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 },
441 [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
442 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, 0 },
443 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, 0 },
444 [FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
445 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
446 [FEAT_PARAM_DOWNSCALE] = { 1, 2 }, 424 [FEAT_PARAM_DOWNSCALE] = { 1, 2 },
447 /* 425 /*
448 * Assuming the line width buffer to be 768 pixels as OMAP2 DISPC 426 * Assuming the line width buffer to be 768 pixels as OMAP2 DISPC
@@ -454,11 +432,6 @@ static const struct dss_param_range omap2_dss_param_range[] = {
454static const struct dss_param_range omap3_dss_param_range[] = { 432static const struct dss_param_range omap3_dss_param_range[] = {
455 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, 433 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 },
456 [FEAT_PARAM_DSS_PCD] = { 1, 255 }, 434 [FEAT_PARAM_DSS_PCD] = { 1, 255 },
457 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 7) - 1 },
458 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 11) - 1 },
459 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 4) - 1 },
460 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 4) - 1 },
461 [FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
462 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1}, 435 [FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
463 [FEAT_PARAM_DSI_FCK] = { 0, 173000000 }, 436 [FEAT_PARAM_DSI_FCK] = { 0, 173000000 },
464 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 437 [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
@@ -475,11 +448,6 @@ static const struct dss_param_range am43xx_dss_param_range[] = {
475static const struct dss_param_range omap4_dss_param_range[] = { 448static const struct dss_param_range omap4_dss_param_range[] = {
476 [FEAT_PARAM_DSS_FCK] = { 0, 186000000 }, 449 [FEAT_PARAM_DSS_FCK] = { 0, 186000000 },
477 [FEAT_PARAM_DSS_PCD] = { 1, 255 }, 450 [FEAT_PARAM_DSS_PCD] = { 1, 255 },
478 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
479 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
480 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
481 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
482 [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
483 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, 451 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
484 [FEAT_PARAM_DSI_FCK] = { 0, 170000000 }, 452 [FEAT_PARAM_DSI_FCK] = { 0, 170000000 },
485 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 453 [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
@@ -489,11 +457,6 @@ static const struct dss_param_range omap4_dss_param_range[] = {
489static const struct dss_param_range omap5_dss_param_range[] = { 457static const struct dss_param_range omap5_dss_param_range[] = {
490 [FEAT_PARAM_DSS_FCK] = { 0, 209250000 }, 458 [FEAT_PARAM_DSS_FCK] = { 0, 209250000 },
491 [FEAT_PARAM_DSS_PCD] = { 1, 255 }, 459 [FEAT_PARAM_DSS_PCD] = { 1, 255 },
492 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
493 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
494 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
495 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
496 [FEAT_PARAM_DSIPLL_FINT] = { 150000, 52000000 },
497 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, 460 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
498 [FEAT_PARAM_DSI_FCK] = { 0, 209250000 }, 461 [FEAT_PARAM_DSI_FCK] = { 0, 209250000 },
499 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 462 [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
@@ -517,7 +480,6 @@ static const enum dss_feat_id omap3430_dss_feat_list[] = {
517 FEAT_LINEBUFFERSPLIT, 480 FEAT_LINEBUFFERSPLIT,
518 FEAT_ROWREPEATENABLE, 481 FEAT_ROWREPEATENABLE,
519 FEAT_RESIZECONF, 482 FEAT_RESIZECONF,
520 FEAT_DSI_PLL_FREQSEL,
521 FEAT_DSI_REVERSE_TXCLKESC, 483 FEAT_DSI_REVERSE_TXCLKESC,
522 FEAT_VENC_REQUIRES_TV_DAC_CLK, 484 FEAT_VENC_REQUIRES_TV_DAC_CLK,
523 FEAT_CPR, 485 FEAT_CPR,
@@ -537,7 +499,6 @@ static const enum dss_feat_id am35xx_dss_feat_list[] = {
537 FEAT_LINEBUFFERSPLIT, 499 FEAT_LINEBUFFERSPLIT,
538 FEAT_ROWREPEATENABLE, 500 FEAT_ROWREPEATENABLE,
539 FEAT_RESIZECONF, 501 FEAT_RESIZECONF,
540 FEAT_DSI_PLL_FREQSEL,
541 FEAT_DSI_REVERSE_TXCLKESC, 502 FEAT_DSI_REVERSE_TXCLKESC,
542 FEAT_VENC_REQUIRES_TV_DAC_CLK, 503 FEAT_VENC_REQUIRES_TV_DAC_CLK,
543 FEAT_CPR, 504 FEAT_CPR,
@@ -572,7 +533,6 @@ static const enum dss_feat_id omap3630_dss_feat_list[] = {
572 FEAT_ROWREPEATENABLE, 533 FEAT_ROWREPEATENABLE,
573 FEAT_RESIZECONF, 534 FEAT_RESIZECONF,
574 FEAT_DSI_PLL_PWR_BUG, 535 FEAT_DSI_PLL_PWR_BUG,
575 FEAT_DSI_PLL_FREQSEL,
576 FEAT_CPR, 536 FEAT_CPR,
577 FEAT_PRELOAD, 537 FEAT_PRELOAD,
578 FEAT_FIR_COEF_V, 538 FEAT_FIR_COEF_V,
@@ -654,8 +614,6 @@ static const enum dss_feat_id omap5_dss_feat_list[] = {
654 FEAT_ALPHA_FREE_ZORDER, 614 FEAT_ALPHA_FREE_ZORDER,
655 FEAT_FIFO_MERGE, 615 FEAT_FIFO_MERGE,
656 FEAT_BURST_2D, 616 FEAT_BURST_2D,
657 FEAT_DSI_PLL_SELFREQDCO,
658 FEAT_DSI_PLL_REFSEL,
659 FEAT_DSI_PHY_DCC, 617 FEAT_DSI_PHY_DCC,
660 FEAT_MFLAG, 618 FEAT_MFLAG,
661}; 619};
diff --git a/drivers/video/fbdev/omap2/dss/dss_features.h b/drivers/video/fbdev/omap2/dss/dss_features.h
index e3ef3b714896..100f7a2d0638 100644
--- a/drivers/video/fbdev/omap2/dss/dss_features.h
+++ b/drivers/video/fbdev/omap2/dss/dss_features.h
@@ -41,7 +41,6 @@ enum dss_feat_id {
41 FEAT_LCD_CLK_SRC, 41 FEAT_LCD_CLK_SRC,
42 /* DSI-PLL power command 0x3 is not working */ 42 /* DSI-PLL power command 0x3 is not working */
43 FEAT_DSI_PLL_PWR_BUG, 43 FEAT_DSI_PLL_PWR_BUG,
44 FEAT_DSI_PLL_FREQSEL,
45 FEAT_DSI_DCS_CMD_CONFIG_VC, 44 FEAT_DSI_DCS_CMD_CONFIG_VC,
46 FEAT_DSI_VC_OCP_WIDTH, 45 FEAT_DSI_VC_OCP_WIDTH,
47 FEAT_DSI_REVERSE_TXCLKESC, 46 FEAT_DSI_REVERSE_TXCLKESC,
@@ -61,8 +60,6 @@ enum dss_feat_id {
61 /* An unknown HW bug causing the normal FIFO thresholds not to work */ 60 /* An unknown HW bug causing the normal FIFO thresholds not to work */
62 FEAT_OMAP3_DSI_FIFO_BUG, 61 FEAT_OMAP3_DSI_FIFO_BUG,
63 FEAT_BURST_2D, 62 FEAT_BURST_2D,
64 FEAT_DSI_PLL_SELFREQDCO,
65 FEAT_DSI_PLL_REFSEL,
66 FEAT_DSI_PHY_DCC, 63 FEAT_DSI_PHY_DCC,
67 FEAT_MFLAG, 64 FEAT_MFLAG,
68}; 65};
@@ -77,20 +74,11 @@ enum dss_feat_reg_field {
77 FEAT_REG_HORIZONTALACCU, 74 FEAT_REG_HORIZONTALACCU,
78 FEAT_REG_VERTICALACCU, 75 FEAT_REG_VERTICALACCU,
79 FEAT_REG_DISPC_CLK_SWITCH, 76 FEAT_REG_DISPC_CLK_SWITCH,
80 FEAT_REG_DSIPLL_REGN,
81 FEAT_REG_DSIPLL_REGM,
82 FEAT_REG_DSIPLL_REGM_DISPC,
83 FEAT_REG_DSIPLL_REGM_DSI,
84}; 77};
85 78
86enum dss_range_param { 79enum dss_range_param {
87 FEAT_PARAM_DSS_FCK, 80 FEAT_PARAM_DSS_FCK,
88 FEAT_PARAM_DSS_PCD, 81 FEAT_PARAM_DSS_PCD,
89 FEAT_PARAM_DSIPLL_REGN,
90 FEAT_PARAM_DSIPLL_REGM,
91 FEAT_PARAM_DSIPLL_REGM_DISPC,
92 FEAT_PARAM_DSIPLL_REGM_DSI,
93 FEAT_PARAM_DSIPLL_FINT,
94 FEAT_PARAM_DSIPLL_LPDIV, 82 FEAT_PARAM_DSIPLL_LPDIV,
95 FEAT_PARAM_DSI_FCK, 83 FEAT_PARAM_DSI_FCK,
96 FEAT_PARAM_DOWNSCALE, 84 FEAT_PARAM_DOWNSCALE,
diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h
index 262771b9b76b..e4a32fe77b02 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
@@ -101,13 +101,6 @@ enum hdmi_core_hdmi_dvi {
101 HDMI_HDMI = 1 101 HDMI_HDMI = 1
102}; 102};
103 103
104enum hdmi_clk_refsel {
105 HDMI_REFSEL_PCLK = 0,
106 HDMI_REFSEL_REF1 = 1,
107 HDMI_REFSEL_REF2 = 2,
108 HDMI_REFSEL_SYSCLK = 3
109};
110
111enum hdmi_packing_mode { 104enum hdmi_packing_mode {
112 HDMI_PACK_10b_RGB_YUV444 = 0, 105 HDMI_PACK_10b_RGB_YUV444 = 0,
113 HDMI_PACK_24b_RGB_YUV444_YUV422 = 1, 106 HDMI_PACK_24b_RGB_YUV444_YUV422 = 1,
@@ -160,7 +153,8 @@ enum hdmi_audio_blk_strt_end_sig {
160 153
161enum hdmi_core_audio_layout { 154enum hdmi_core_audio_layout {
162 HDMI_AUDIO_LAYOUT_2CH = 0, 155 HDMI_AUDIO_LAYOUT_2CH = 0,
163 HDMI_AUDIO_LAYOUT_8CH = 1 156 HDMI_AUDIO_LAYOUT_8CH = 1,
157 HDMI_AUDIO_LAYOUT_6CH = 2
164}; 158};
165 159
166enum hdmi_core_cts_mode { 160enum hdmi_core_cts_mode {
@@ -191,17 +185,6 @@ struct hdmi_config {
191 enum hdmi_core_hdmi_dvi hdmi_dvi_mode; 185 enum hdmi_core_hdmi_dvi hdmi_dvi_mode;
192}; 186};
193 187
194/* HDMI PLL structure */
195struct hdmi_pll_info {
196 u16 regn;
197 u16 regm;
198 u32 regmf;
199 u16 regm2;
200 u16 regsd;
201 u16 dcofreq;
202 enum hdmi_clk_refsel refsel;
203};
204
205struct hdmi_audio_format { 188struct hdmi_audio_format {
206 enum hdmi_stereo_channels stereo_channels; 189 enum hdmi_stereo_channels stereo_channels;
207 u8 active_chnnls_msk; 190 u8 active_chnnls_msk;
@@ -249,12 +232,15 @@ struct hdmi_core_audio_config {
249 232
250struct hdmi_wp_data { 233struct hdmi_wp_data {
251 void __iomem *base; 234 void __iomem *base;
235 phys_addr_t phys_base;
252}; 236};
253 237
254struct hdmi_pll_data { 238struct hdmi_pll_data {
239 struct dss_pll pll;
240
255 void __iomem *base; 241 void __iomem *base;
256 242
257 struct hdmi_pll_info info; 243 struct hdmi_wp_data *wp;
258}; 244};
259 245
260struct hdmi_phy_data { 246struct hdmi_phy_data {
@@ -316,16 +302,19 @@ void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp,
316void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt, 302void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
317 struct omap_video_timings *timings, struct hdmi_config *param); 303 struct omap_video_timings *timings, struct hdmi_config *param);
318int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp); 304int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp);
305phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp);
319 306
320/* HDMI PLL funcs */ 307/* HDMI PLL funcs */
321int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp);
322void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp);
323void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s); 308void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s);
324void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy); 309void hdmi_pll_compute(struct hdmi_pll_data *pll,
325int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll); 310 unsigned long target_tmds, struct dss_pll_clock_info *pi);
311int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
312 struct hdmi_wp_data *wp);
313void hdmi_pll_uninit(struct hdmi_pll_data *hpll);
326 314
327/* HDMI PHY funcs */ 315/* HDMI PHY funcs */
328int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg); 316int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
317 unsigned long lfbitclk);
329void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s); 318void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s);
330int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy); 319int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy);
331int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes); 320int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes);
@@ -334,7 +323,7 @@ int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes);
334int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep, 323int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
335 struct hdmi_phy_data *phy); 324 struct hdmi_phy_data *phy);
336 325
337#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) || defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) 326/* Audio funcs */
338int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts); 327int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts);
339int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable); 328int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable);
340int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable); 329int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable);
@@ -342,9 +331,33 @@ void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp,
342 struct hdmi_audio_format *aud_fmt); 331 struct hdmi_audio_format *aud_fmt);
343void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp, 332void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp,
344 struct hdmi_audio_dma *aud_dma); 333 struct hdmi_audio_dma *aud_dma);
345static inline bool hdmi_mode_has_audio(int mode) 334static inline bool hdmi_mode_has_audio(struct hdmi_config *cfg)
346{ 335{
347 return mode == HDMI_HDMI ? true : false; 336 return cfg->hdmi_dvi_mode == HDMI_HDMI ? true : false;
348} 337}
349#endif 338
339/* HDMI DRV data */
340struct omap_hdmi {
341 struct mutex lock;
342 struct platform_device *pdev;
343
344 struct hdmi_wp_data wp;
345 struct hdmi_pll_data pll;
346 struct hdmi_phy_data phy;
347 struct hdmi_core_data core;
348
349 struct hdmi_config cfg;
350
351 struct regulator *vdda_reg;
352
353 bool core_enabled;
354 bool display_enabled;
355
356 struct omap_dss_device output;
357
358 struct platform_device *audio_pdev;
359 void (*audio_abort_cb)(struct device *dev);
360 int wp_idlemode;
361};
362
350#endif 363#endif
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 9a8713ca090c..f1a02bf938ee 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -33,29 +33,14 @@
33#include <linux/gpio.h> 33#include <linux/gpio.h>
34#include <linux/regulator/consumer.h> 34#include <linux/regulator/consumer.h>
35#include <video/omapdss.h> 35#include <video/omapdss.h>
36#include <sound/omap-hdmi-audio.h>
36 37
37#include "hdmi4_core.h" 38#include "hdmi4_core.h"
38#include "dss.h" 39#include "dss.h"
39#include "dss_features.h" 40#include "dss_features.h"
41#include "hdmi.h"
40 42
41static struct { 43static struct omap_hdmi hdmi;
42 struct mutex lock;
43 struct platform_device *pdev;
44
45 struct hdmi_wp_data wp;
46 struct hdmi_pll_data pll;
47 struct hdmi_phy_data phy;
48 struct hdmi_core_data core;
49
50 struct hdmi_config cfg;
51
52 struct clk *sys_clk;
53 struct regulator *vdda_hdmi_dac_reg;
54
55 bool core_enabled;
56
57 struct omap_dss_device output;
58} hdmi;
59 44
60static int hdmi_runtime_get(void) 45static int hdmi_runtime_get(void)
61{ 46{
@@ -117,7 +102,7 @@ static int hdmi_init_regulator(void)
117 int r; 102 int r;
118 struct regulator *reg; 103 struct regulator *reg;
119 104
120 if (hdmi.vdda_hdmi_dac_reg != NULL) 105 if (hdmi.vdda_reg != NULL)
121 return 0; 106 return 0;
122 107
123 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda"); 108 reg = devm_regulator_get(&hdmi.pdev->dev, "vdda");
@@ -137,7 +122,7 @@ static int hdmi_init_regulator(void)
137 } 122 }
138 } 123 }
139 124
140 hdmi.vdda_hdmi_dac_reg = reg; 125 hdmi.vdda_reg = reg;
141 126
142 return 0; 127 return 0;
143} 128}
@@ -146,7 +131,7 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
146{ 131{
147 int r; 132 int r;
148 133
149 r = regulator_enable(hdmi.vdda_hdmi_dac_reg); 134 r = regulator_enable(hdmi.vdda_reg);
150 if (r) 135 if (r)
151 return r; 136 return r;
152 137
@@ -162,7 +147,7 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
162 return 0; 147 return 0;
163 148
164err_runtime_get: 149err_runtime_get:
165 regulator_disable(hdmi.vdda_hdmi_dac_reg); 150 regulator_disable(hdmi.vdda_reg);
166 151
167 return r; 152 return r;
168} 153}
@@ -172,7 +157,7 @@ static void hdmi_power_off_core(struct omap_dss_device *dssdev)
172 hdmi.core_enabled = false; 157 hdmi.core_enabled = false;
173 158
174 hdmi_runtime_put(); 159 hdmi_runtime_put();
175 regulator_disable(hdmi.vdda_hdmi_dac_reg); 160 regulator_disable(hdmi.vdda_reg);
176} 161}
177 162
178static int hdmi_power_on_full(struct omap_dss_device *dssdev) 163static int hdmi_power_on_full(struct omap_dss_device *dssdev)
@@ -180,8 +165,8 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
180 int r; 165 int r;
181 struct omap_video_timings *p; 166 struct omap_video_timings *p;
182 struct omap_overlay_manager *mgr = hdmi.output.manager; 167 struct omap_overlay_manager *mgr = hdmi.output.manager;
183 unsigned long phy;
184 struct hdmi_wp_data *wp = &hdmi.wp; 168 struct hdmi_wp_data *wp = &hdmi.wp;
169 struct dss_pll_clock_info hdmi_cinfo = { 0 };
185 170
186 r = hdmi_power_on_core(dssdev); 171 r = hdmi_power_on_core(dssdev);
187 if (r) 172 if (r)
@@ -195,19 +180,22 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
195 180
196 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); 181 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
197 182
198 /* the functions below use kHz pixel clock. TODO: change to Hz */ 183 hdmi_pll_compute(&hdmi.pll, p->pixelclock, &hdmi_cinfo);
199 phy = p->pixelclock / 1000;
200
201 hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy);
202 184
203 /* config the PLL and PHY hdmi_set_pll_pwrfirst */ 185 r = dss_pll_enable(&hdmi.pll.pll);
204 r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp);
205 if (r) { 186 if (r) {
206 DSSDBG("Failed to lock PLL\n"); 187 DSSERR("Failed to enable PLL\n");
207 goto err_pll_enable; 188 goto err_pll_enable;
208 } 189 }
209 190
210 r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg); 191 r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo);
192 if (r) {
193 DSSERR("Failed to configure PLL\n");
194 goto err_pll_cfg;
195 }
196
197 r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco,
198 hdmi_cinfo.clkout[0]);
211 if (r) { 199 if (r) {
212 DSSDBG("Failed to configure PHY\n"); 200 DSSDBG("Failed to configure PHY\n");
213 goto err_phy_cfg; 201 goto err_phy_cfg;
@@ -244,7 +232,8 @@ err_vid_enable:
244err_phy_cfg: 232err_phy_cfg:
245 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 233 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
246err_phy_pwr: 234err_phy_pwr:
247 hdmi_pll_disable(&hdmi.pll, &hdmi.wp); 235err_pll_cfg:
236 dss_pll_disable(&hdmi.pll.pll);
248err_pll_enable: 237err_pll_enable:
249 hdmi_power_off_core(dssdev); 238 hdmi_power_off_core(dssdev);
250 return -EIO; 239 return -EIO;
@@ -262,7 +251,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
262 251
263 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 252 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
264 253
265 hdmi_pll_disable(&hdmi.pll, &hdmi.wp); 254 dss_pll_disable(&hdmi.pll.pll);
266 255
267 hdmi_power_off_core(dssdev); 256 hdmi_power_off_core(dssdev);
268} 257}
@@ -352,6 +341,8 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
352 goto err0; 341 goto err0;
353 } 342 }
354 343
344 hdmi.display_enabled = true;
345
355 mutex_unlock(&hdmi.lock); 346 mutex_unlock(&hdmi.lock);
356 return 0; 347 return 0;
357 348
@@ -366,8 +357,13 @@ static void hdmi_display_disable(struct omap_dss_device *dssdev)
366 357
367 mutex_lock(&hdmi.lock); 358 mutex_lock(&hdmi.lock);
368 359
360 if (hdmi.audio_pdev && hdmi.audio_abort_cb)
361 hdmi.audio_abort_cb(&hdmi.audio_pdev->dev);
362
369 hdmi_power_off_full(dssdev); 363 hdmi_power_off_full(dssdev);
370 364
365 hdmi.display_enabled = false;
366
371 mutex_unlock(&hdmi.lock); 367 mutex_unlock(&hdmi.lock);
372} 368}
373 369
@@ -404,21 +400,6 @@ static void hdmi_core_disable(struct omap_dss_device *dssdev)
404 mutex_unlock(&hdmi.lock); 400 mutex_unlock(&hdmi.lock);
405} 401}
406 402
407static int hdmi_get_clocks(struct platform_device *pdev)
408{
409 struct clk *clk;
410
411 clk = devm_clk_get(&pdev->dev, "sys_clk");
412 if (IS_ERR(clk)) {
413 DSSERR("can't get sys_clk\n");
414 return PTR_ERR(clk);
415 }
416
417 hdmi.sys_clk = clk;
418
419 return 0;
420}
421
422static int hdmi_connect(struct omap_dss_device *dssdev, 403static int hdmi_connect(struct omap_dss_device *dssdev,
423 struct omap_dss_device *dst) 404 struct omap_dss_device *dst)
424{ 405{
@@ -484,112 +465,6 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev,
484 return r; 465 return r;
485} 466}
486 467
487#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
488static int hdmi_audio_enable(struct omap_dss_device *dssdev)
489{
490 int r;
491
492 mutex_lock(&hdmi.lock);
493
494 if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
495 r = -EPERM;
496 goto err;
497 }
498
499 r = hdmi_wp_audio_enable(&hdmi.wp, true);
500 if (r)
501 goto err;
502
503 mutex_unlock(&hdmi.lock);
504 return 0;
505
506err:
507 mutex_unlock(&hdmi.lock);
508 return r;
509}
510
511static void hdmi_audio_disable(struct omap_dss_device *dssdev)
512{
513 hdmi_wp_audio_enable(&hdmi.wp, false);
514}
515
516static int hdmi_audio_start(struct omap_dss_device *dssdev)
517{
518 return hdmi4_audio_start(&hdmi.core, &hdmi.wp);
519}
520
521static void hdmi_audio_stop(struct omap_dss_device *dssdev)
522{
523 hdmi4_audio_stop(&hdmi.core, &hdmi.wp);
524}
525
526static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
527{
528 bool r;
529
530 mutex_lock(&hdmi.lock);
531
532 r = hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode);
533
534 mutex_unlock(&hdmi.lock);
535 return r;
536}
537
538static int hdmi_audio_config(struct omap_dss_device *dssdev,
539 struct omap_dss_audio *audio)
540{
541 int r;
542 u32 pclk = hdmi.cfg.timings.pixelclock;
543
544 mutex_lock(&hdmi.lock);
545
546 if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
547 r = -EPERM;
548 goto err;
549 }
550
551 r = hdmi4_audio_config(&hdmi.core, &hdmi.wp, audio, pclk);
552 if (r)
553 goto err;
554
555 mutex_unlock(&hdmi.lock);
556 return 0;
557
558err:
559 mutex_unlock(&hdmi.lock);
560 return r;
561}
562#else
563static int hdmi_audio_enable(struct omap_dss_device *dssdev)
564{
565 return -EPERM;
566}
567
568static void hdmi_audio_disable(struct omap_dss_device *dssdev)
569{
570}
571
572static int hdmi_audio_start(struct omap_dss_device *dssdev)
573{
574 return -EPERM;
575}
576
577static void hdmi_audio_stop(struct omap_dss_device *dssdev)
578{
579}
580
581static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
582{
583 return false;
584}
585
586static int hdmi_audio_config(struct omap_dss_device *dssdev,
587 struct omap_dss_audio *audio)
588{
589 return -EPERM;
590}
591#endif
592
593static int hdmi_set_infoframe(struct omap_dss_device *dssdev, 468static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
594 const struct hdmi_avi_infoframe *avi) 469 const struct hdmi_avi_infoframe *avi)
595{ 470{
@@ -618,13 +493,6 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
618 .read_edid = hdmi_read_edid, 493 .read_edid = hdmi_read_edid,
619 .set_infoframe = hdmi_set_infoframe, 494 .set_infoframe = hdmi_set_infoframe,
620 .set_hdmi_mode = hdmi_set_hdmi_mode, 495 .set_hdmi_mode = hdmi_set_hdmi_mode,
621
622 .audio_enable = hdmi_audio_enable,
623 .audio_disable = hdmi_audio_disable,
624 .audio_start = hdmi_audio_start,
625 .audio_stop = hdmi_audio_stop,
626 .audio_supported = hdmi_audio_supported,
627 .audio_config = hdmi_audio_config,
628}; 496};
629 497
630static void hdmi_init_output(struct platform_device *pdev) 498static void hdmi_init_output(struct platform_device *pdev)
@@ -642,7 +510,7 @@ static void hdmi_init_output(struct platform_device *pdev)
642 omapdss_register_output(out); 510 omapdss_register_output(out);
643} 511}
644 512
645static void __exit hdmi_uninit_output(struct platform_device *pdev) 513static void hdmi_uninit_output(struct platform_device *pdev)
646{ 514{
647 struct omap_dss_device *out = &hdmi.output; 515 struct omap_dss_device *out = &hdmi.output;
648 516
@@ -671,6 +539,112 @@ err:
671 return r; 539 return r;
672} 540}
673 541
542/* Audio callbacks */
543static int hdmi_audio_startup(struct device *dev,
544 void (*abort_cb)(struct device *dev))
545{
546 struct omap_hdmi *hd = dev_get_drvdata(dev);
547 int ret = 0;
548
549 mutex_lock(&hd->lock);
550
551 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
552 ret = -EPERM;
553 goto out;
554 }
555
556 hd->audio_abort_cb = abort_cb;
557
558out:
559 mutex_unlock(&hd->lock);
560
561 return ret;
562}
563
564static int hdmi_audio_shutdown(struct device *dev)
565{
566 struct omap_hdmi *hd = dev_get_drvdata(dev);
567
568 mutex_lock(&hd->lock);
569 hd->audio_abort_cb = NULL;
570 mutex_unlock(&hd->lock);
571
572 return 0;
573}
574
575static int hdmi_audio_start(struct device *dev)
576{
577 struct omap_hdmi *hd = dev_get_drvdata(dev);
578
579 WARN_ON(!hdmi_mode_has_audio(&hd->cfg));
580 WARN_ON(!hd->display_enabled);
581
582 hdmi_wp_audio_enable(&hd->wp, true);
583 hdmi4_audio_start(&hd->core, &hd->wp);
584
585 return 0;
586}
587
588static void hdmi_audio_stop(struct device *dev)
589{
590 struct omap_hdmi *hd = dev_get_drvdata(dev);
591
592 WARN_ON(!hdmi_mode_has_audio(&hd->cfg));
593 WARN_ON(!hd->display_enabled);
594
595 hdmi4_audio_stop(&hd->core, &hd->wp);
596 hdmi_wp_audio_enable(&hd->wp, false);
597}
598
599static int hdmi_audio_config(struct device *dev,
600 struct omap_dss_audio *dss_audio)
601{
602 struct omap_hdmi *hd = dev_get_drvdata(dev);
603 int ret;
604
605 mutex_lock(&hd->lock);
606
607 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
608 ret = -EPERM;
609 goto out;
610 }
611
612 ret = hdmi4_audio_config(&hd->core, &hd->wp, dss_audio,
613 hd->cfg.timings.pixelclock);
614
615out:
616 mutex_unlock(&hd->lock);
617
618 return ret;
619}
620
621static const struct omap_hdmi_audio_ops hdmi_audio_ops = {
622 .audio_startup = hdmi_audio_startup,
623 .audio_shutdown = hdmi_audio_shutdown,
624 .audio_start = hdmi_audio_start,
625 .audio_stop = hdmi_audio_stop,
626 .audio_config = hdmi_audio_config,
627};
628
629static int hdmi_audio_register(struct device *dev)
630{
631 struct omap_hdmi_audio_pdata pdata = {
632 .dev = dev,
633 .dss_version = omapdss_get_version(),
634 .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
635 .ops = &hdmi_audio_ops,
636 };
637
638 hdmi.audio_pdev = platform_device_register_data(
639 dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO,
640 &pdata, sizeof(pdata));
641
642 if (IS_ERR(hdmi.audio_pdev))
643 return PTR_ERR(hdmi.audio_pdev);
644
645 return 0;
646}
647
674/* HDMI HW IP initialisation */ 648/* HDMI HW IP initialisation */
675static int omapdss_hdmihw_probe(struct platform_device *pdev) 649static int omapdss_hdmihw_probe(struct platform_device *pdev)
676{ 650{
@@ -678,6 +652,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
678 int irq; 652 int irq;
679 653
680 hdmi.pdev = pdev; 654 hdmi.pdev = pdev;
655 dev_set_drvdata(&pdev->dev, &hdmi);
681 656
682 mutex_init(&hdmi.lock); 657 mutex_init(&hdmi.lock);
683 658
@@ -691,28 +666,23 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
691 if (r) 666 if (r)
692 return r; 667 return r;
693 668
694 r = hdmi_pll_init(pdev, &hdmi.pll); 669 r = hdmi_pll_init(pdev, &hdmi.pll, &hdmi.wp);
695 if (r) 670 if (r)
696 return r; 671 return r;
697 672
698 r = hdmi_phy_init(pdev, &hdmi.phy); 673 r = hdmi_phy_init(pdev, &hdmi.phy);
699 if (r) 674 if (r)
700 return r; 675 goto err;
701 676
702 r = hdmi4_core_init(pdev, &hdmi.core); 677 r = hdmi4_core_init(pdev, &hdmi.core);
703 if (r) 678 if (r)
704 return r; 679 goto err;
705
706 r = hdmi_get_clocks(pdev);
707 if (r) {
708 DSSERR("can't get clocks\n");
709 return r;
710 }
711 680
712 irq = platform_get_irq(pdev, 0); 681 irq = platform_get_irq(pdev, 0);
713 if (irq < 0) { 682 if (irq < 0) {
714 DSSERR("platform_get_irq failed\n"); 683 DSSERR("platform_get_irq failed\n");
715 return -ENODEV; 684 r = -ENODEV;
685 goto err;
716 } 686 }
717 687
718 r = devm_request_threaded_irq(&pdev->dev, irq, 688 r = devm_request_threaded_irq(&pdev->dev, irq,
@@ -720,22 +690,38 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
720 IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); 690 IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp);
721 if (r) { 691 if (r) {
722 DSSERR("HDMI IRQ request failed\n"); 692 DSSERR("HDMI IRQ request failed\n");
723 return r; 693 goto err;
724 } 694 }
725 695
726 pm_runtime_enable(&pdev->dev); 696 pm_runtime_enable(&pdev->dev);
727 697
728 hdmi_init_output(pdev); 698 hdmi_init_output(pdev);
729 699
700 r = hdmi_audio_register(&pdev->dev);
701 if (r) {
702 DSSERR("Registering HDMI audio failed\n");
703 hdmi_uninit_output(pdev);
704 pm_runtime_disable(&pdev->dev);
705 return r;
706 }
707
730 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 708 dss_debugfs_create_file("hdmi", hdmi_dump_regs);
731 709
732 return 0; 710 return 0;
711err:
712 hdmi_pll_uninit(&hdmi.pll);
713 return r;
733} 714}
734 715
735static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) 716static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
736{ 717{
718 if (hdmi.audio_pdev)
719 platform_device_unregister(hdmi.audio_pdev);
720
737 hdmi_uninit_output(pdev); 721 hdmi_uninit_output(pdev);
738 722
723 hdmi_pll_uninit(&hdmi.pll);
724
739 pm_runtime_disable(&pdev->dev); 725 pm_runtime_disable(&pdev->dev);
740 726
741 return 0; 727 return 0;
@@ -743,8 +729,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
743 729
744static int hdmi_runtime_suspend(struct device *dev) 730static int hdmi_runtime_suspend(struct device *dev)
745{ 731{
746 clk_disable_unprepare(hdmi.sys_clk);
747
748 dispc_runtime_put(); 732 dispc_runtime_put();
749 733
750 return 0; 734 return 0;
@@ -758,8 +742,6 @@ static int hdmi_runtime_resume(struct device *dev)
758 if (r < 0) 742 if (r < 0)
759 return r; 743 return r;
760 744
761 clk_prepare_enable(hdmi.sys_clk);
762
763 return 0; 745 return 0;
764} 746}
765 747
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.c b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
index 4ad39cfce254..7eafea5b8e19 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
@@ -31,10 +31,8 @@
31#include <linux/platform_device.h> 31#include <linux/platform_device.h>
32#include <linux/string.h> 32#include <linux/string.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
35#include <sound/asound.h> 34#include <sound/asound.h>
36#include <sound/asoundef.h> 35#include <sound/asoundef.h>
37#endif
38 36
39#include "hdmi4_core.h" 37#include "hdmi4_core.h"
40#include "dss_features.h" 38#include "dss_features.h"
@@ -530,7 +528,6 @@ void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s)
530 DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID); 528 DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID);
531} 529}
532 530
533#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
534static void hdmi_core_audio_config(struct hdmi_core_data *core, 531static void hdmi_core_audio_config(struct hdmi_core_data *core,
535 struct hdmi_core_audio_config *cfg) 532 struct hdmi_core_audio_config *cfg)
536{ 533{
@@ -877,17 +874,6 @@ void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp)
877 hdmi_wp_audio_core_req_enable(wp, false); 874 hdmi_wp_audio_core_req_enable(wp, false);
878} 875}
879 876
880int hdmi4_audio_get_dma_port(u32 *offset, u32 *size)
881{
882 if (!offset || !size)
883 return -EINVAL;
884 *offset = HDMI_WP_AUDIO_DATA;
885 *size = 4;
886 return 0;
887}
888
889#endif
890
891int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core) 877int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core)
892{ 878{
893 struct resource *res; 879 struct resource *res;
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.h b/drivers/video/fbdev/omap2/dss/hdmi4_core.h
index 827909eb6c50..a069f96ec6f6 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4_core.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.h
@@ -266,12 +266,8 @@ void hdmi4_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
266void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s); 266void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s);
267int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core); 267int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core);
268 268
269#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
270int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp); 269int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp);
271void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp); 270void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp);
272int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, 271int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
273 struct omap_dss_audio *audio, u32 pclk); 272 struct omap_dss_audio *audio, u32 pclk);
274int hdmi4_audio_get_dma_port(u32 *offset, u32 *size);
275#endif
276
277#endif 273#endif
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c
index 169b764bb9d4..d9d0d781625a 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5.c
@@ -38,29 +38,13 @@
38#include <linux/gpio.h> 38#include <linux/gpio.h>
39#include <linux/regulator/consumer.h> 39#include <linux/regulator/consumer.h>
40#include <video/omapdss.h> 40#include <video/omapdss.h>
41#include <sound/omap-hdmi-audio.h>
41 42
42#include "hdmi5_core.h" 43#include "hdmi5_core.h"
43#include "dss.h" 44#include "dss.h"
44#include "dss_features.h" 45#include "dss_features.h"
45 46
46static struct { 47static struct omap_hdmi hdmi;
47 struct mutex lock;
48 struct platform_device *pdev;
49
50 struct hdmi_wp_data wp;
51 struct hdmi_pll_data pll;
52 struct hdmi_phy_data phy;
53 struct hdmi_core_data core;
54
55 struct hdmi_config cfg;
56
57 struct clk *sys_clk;
58 struct regulator *vdda_reg;
59
60 bool core_enabled;
61
62 struct omap_dss_device output;
63} hdmi;
64 48
65static int hdmi_runtime_get(void) 49static int hdmi_runtime_get(void)
66{ 50{
@@ -198,7 +182,7 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
198 int r; 182 int r;
199 struct omap_video_timings *p; 183 struct omap_video_timings *p;
200 struct omap_overlay_manager *mgr = hdmi.output.manager; 184 struct omap_overlay_manager *mgr = hdmi.output.manager;
201 unsigned long phy; 185 struct dss_pll_clock_info hdmi_cinfo = { 0 };
202 186
203 r = hdmi_power_on_core(dssdev); 187 r = hdmi_power_on_core(dssdev);
204 if (r) 188 if (r)
@@ -208,24 +192,27 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
208 192
209 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); 193 DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
210 194
211 /* the functions below use kHz pixel clock. TODO: change to Hz */ 195 hdmi_pll_compute(&hdmi.pll, p->pixelclock, &hdmi_cinfo);
212 phy = p->pixelclock / 1000;
213
214 hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy);
215 196
216 /* disable and clear irqs */ 197 /* disable and clear irqs */
217 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); 198 hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff);
218 hdmi_wp_set_irqstatus(&hdmi.wp, 199 hdmi_wp_set_irqstatus(&hdmi.wp,
219 hdmi_wp_get_irqstatus(&hdmi.wp)); 200 hdmi_wp_get_irqstatus(&hdmi.wp));
220 201
221 /* config the PLL and PHY hdmi_set_pll_pwrfirst */ 202 r = dss_pll_enable(&hdmi.pll.pll);
222 r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp);
223 if (r) { 203 if (r) {
224 DSSDBG("Failed to lock PLL\n"); 204 DSSERR("Failed to enable PLL\n");
225 goto err_pll_enable; 205 goto err_pll_enable;
226 } 206 }
227 207
228 r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg); 208 r = dss_pll_set_config(&hdmi.pll.pll, &hdmi_cinfo);
209 if (r) {
210 DSSERR("Failed to configure PLL\n");
211 goto err_pll_cfg;
212 }
213
214 r = hdmi_phy_configure(&hdmi.phy, hdmi_cinfo.clkdco,
215 hdmi_cinfo.clkout[0]);
229 if (r) { 216 if (r) {
230 DSSDBG("Failed to start PHY\n"); 217 DSSDBG("Failed to start PHY\n");
231 goto err_phy_cfg; 218 goto err_phy_cfg;
@@ -262,7 +249,8 @@ err_vid_enable:
262 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 249 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
263err_phy_pwr: 250err_phy_pwr:
264err_phy_cfg: 251err_phy_cfg:
265 hdmi_pll_disable(&hdmi.pll, &hdmi.wp); 252err_pll_cfg:
253 dss_pll_disable(&hdmi.pll.pll);
266err_pll_enable: 254err_pll_enable:
267 hdmi_power_off_core(dssdev); 255 hdmi_power_off_core(dssdev);
268 return -EIO; 256 return -EIO;
@@ -280,7 +268,7 @@ static void hdmi_power_off_full(struct omap_dss_device *dssdev)
280 268
281 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 269 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
282 270
283 hdmi_pll_disable(&hdmi.pll, &hdmi.wp); 271 dss_pll_disable(&hdmi.pll.pll);
284 272
285 hdmi_power_off_core(dssdev); 273 hdmi_power_off_core(dssdev);
286} 274}
@@ -290,6 +278,10 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
290{ 278{
291 struct omap_dss_device *out = &hdmi.output; 279 struct omap_dss_device *out = &hdmi.output;
292 280
281 /* TODO: proper interlace support */
282 if (timings->interlace)
283 return -EINVAL;
284
293 if (!dispc_mgr_timings_ok(out->dispc_channel, timings)) 285 if (!dispc_mgr_timings_ok(out->dispc_channel, timings))
294 return -EINVAL; 286 return -EINVAL;
295 287
@@ -377,6 +369,8 @@ static int hdmi_display_enable(struct omap_dss_device *dssdev)
377 goto err0; 369 goto err0;
378 } 370 }
379 371
372 hdmi.display_enabled = true;
373
380 mutex_unlock(&hdmi.lock); 374 mutex_unlock(&hdmi.lock);
381 return 0; 375 return 0;
382 376
@@ -391,8 +385,13 @@ static void hdmi_display_disable(struct omap_dss_device *dssdev)
391 385
392 mutex_lock(&hdmi.lock); 386 mutex_lock(&hdmi.lock);
393 387
388 if (hdmi.audio_pdev && hdmi.audio_abort_cb)
389 hdmi.audio_abort_cb(&hdmi.audio_pdev->dev);
390
394 hdmi_power_off_full(dssdev); 391 hdmi_power_off_full(dssdev);
395 392
393 hdmi.display_enabled = false;
394
396 mutex_unlock(&hdmi.lock); 395 mutex_unlock(&hdmi.lock);
397} 396}
398 397
@@ -429,21 +428,6 @@ static void hdmi_core_disable(struct omap_dss_device *dssdev)
429 mutex_unlock(&hdmi.lock); 428 mutex_unlock(&hdmi.lock);
430} 429}
431 430
432static int hdmi_get_clocks(struct platform_device *pdev)
433{
434 struct clk *clk;
435
436 clk = devm_clk_get(&pdev->dev, "sys_clk");
437 if (IS_ERR(clk)) {
438 DSSERR("can't get sys_clk\n");
439 return PTR_ERR(clk);
440 }
441
442 hdmi.sys_clk = clk;
443
444 return 0;
445}
446
447static int hdmi_connect(struct omap_dss_device *dssdev, 431static int hdmi_connect(struct omap_dss_device *dssdev,
448 struct omap_dss_device *dst) 432 struct omap_dss_device *dst)
449{ 433{
@@ -509,112 +493,6 @@ static int hdmi_read_edid(struct omap_dss_device *dssdev,
509 return r; 493 return r;
510} 494}
511 495
512#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
513static int hdmi_audio_enable(struct omap_dss_device *dssdev)
514{
515 int r;
516
517 mutex_lock(&hdmi.lock);
518
519 if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
520 r = -EPERM;
521 goto err;
522 }
523
524 r = hdmi_wp_audio_enable(&hdmi.wp, true);
525 if (r)
526 goto err;
527
528 mutex_unlock(&hdmi.lock);
529 return 0;
530
531err:
532 mutex_unlock(&hdmi.lock);
533 return r;
534}
535
536static void hdmi_audio_disable(struct omap_dss_device *dssdev)
537{
538 hdmi_wp_audio_enable(&hdmi.wp, false);
539}
540
541static int hdmi_audio_start(struct omap_dss_device *dssdev)
542{
543 return hdmi_wp_audio_core_req_enable(&hdmi.wp, true);
544}
545
546static void hdmi_audio_stop(struct omap_dss_device *dssdev)
547{
548 hdmi_wp_audio_core_req_enable(&hdmi.wp, false);
549}
550
551static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
552{
553 bool r;
554
555 mutex_lock(&hdmi.lock);
556
557 r = hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode);
558
559 mutex_unlock(&hdmi.lock);
560 return r;
561}
562
563static int hdmi_audio_config(struct omap_dss_device *dssdev,
564 struct omap_dss_audio *audio)
565{
566 int r;
567 u32 pclk = hdmi.cfg.timings.pixelclock;
568
569 mutex_lock(&hdmi.lock);
570
571 if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
572 r = -EPERM;
573 goto err;
574 }
575
576 r = hdmi5_audio_config(&hdmi.core, &hdmi.wp, audio, pclk);
577 if (r)
578 goto err;
579
580 mutex_unlock(&hdmi.lock);
581 return 0;
582
583err:
584 mutex_unlock(&hdmi.lock);
585 return r;
586}
587#else
588static int hdmi_audio_enable(struct omap_dss_device *dssdev)
589{
590 return -EPERM;
591}
592
593static void hdmi_audio_disable(struct omap_dss_device *dssdev)
594{
595}
596
597static int hdmi_audio_start(struct omap_dss_device *dssdev)
598{
599 return -EPERM;
600}
601
602static void hdmi_audio_stop(struct omap_dss_device *dssdev)
603{
604}
605
606static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
607{
608 return false;
609}
610
611static int hdmi_audio_config(struct omap_dss_device *dssdev,
612 struct omap_dss_audio *audio)
613{
614 return -EPERM;
615}
616#endif
617
618static int hdmi_set_infoframe(struct omap_dss_device *dssdev, 496static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
619 const struct hdmi_avi_infoframe *avi) 497 const struct hdmi_avi_infoframe *avi)
620{ 498{
@@ -643,13 +521,6 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
643 .read_edid = hdmi_read_edid, 521 .read_edid = hdmi_read_edid,
644 .set_infoframe = hdmi_set_infoframe, 522 .set_infoframe = hdmi_set_infoframe,
645 .set_hdmi_mode = hdmi_set_hdmi_mode, 523 .set_hdmi_mode = hdmi_set_hdmi_mode,
646
647 .audio_enable = hdmi_audio_enable,
648 .audio_disable = hdmi_audio_disable,
649 .audio_start = hdmi_audio_start,
650 .audio_stop = hdmi_audio_stop,
651 .audio_supported = hdmi_audio_supported,
652 .audio_config = hdmi_audio_config,
653}; 524};
654 525
655static void hdmi_init_output(struct platform_device *pdev) 526static void hdmi_init_output(struct platform_device *pdev)
@@ -667,7 +538,7 @@ static void hdmi_init_output(struct platform_device *pdev)
667 omapdss_register_output(out); 538 omapdss_register_output(out);
668} 539}
669 540
670static void __exit hdmi_uninit_output(struct platform_device *pdev) 541static void hdmi_uninit_output(struct platform_device *pdev)
671{ 542{
672 struct omap_dss_device *out = &hdmi.output; 543 struct omap_dss_device *out = &hdmi.output;
673 544
@@ -696,6 +567,119 @@ err:
696 return r; 567 return r;
697} 568}
698 569
570/* Audio callbacks */
571static int hdmi_audio_startup(struct device *dev,
572 void (*abort_cb)(struct device *dev))
573{
574 struct omap_hdmi *hd = dev_get_drvdata(dev);
575 int ret = 0;
576
577 mutex_lock(&hd->lock);
578
579 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
580 ret = -EPERM;
581 goto out;
582 }
583
584 hd->audio_abort_cb = abort_cb;
585
586out:
587 mutex_unlock(&hd->lock);
588
589 return ret;
590}
591
592static int hdmi_audio_shutdown(struct device *dev)
593{
594 struct omap_hdmi *hd = dev_get_drvdata(dev);
595
596 mutex_lock(&hd->lock);
597 hd->audio_abort_cb = NULL;
598 mutex_unlock(&hd->lock);
599
600 return 0;
601}
602
603static int hdmi_audio_start(struct device *dev)
604{
605 struct omap_hdmi *hd = dev_get_drvdata(dev);
606
607 WARN_ON(!hdmi_mode_has_audio(&hd->cfg));
608 WARN_ON(!hd->display_enabled);
609
610 /* No-idle while playing audio, store the old value */
611 hd->wp_idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2);
612 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2);
613
614 hdmi_wp_audio_enable(&hd->wp, true);
615 hdmi_wp_audio_core_req_enable(&hd->wp, true);
616
617 return 0;
618}
619
620static void hdmi_audio_stop(struct device *dev)
621{
622 struct omap_hdmi *hd = dev_get_drvdata(dev);
623
624 WARN_ON(!hdmi_mode_has_audio(&hd->cfg));
625 WARN_ON(!hd->display_enabled);
626
627 hdmi_wp_audio_core_req_enable(&hd->wp, false);
628 hdmi_wp_audio_enable(&hd->wp, false);
629
630 /* Playback stopped, restore original idlemode */
631 REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, hd->wp_idlemode, 3, 2);
632}
633
634static int hdmi_audio_config(struct device *dev,
635 struct omap_dss_audio *dss_audio)
636{
637 struct omap_hdmi *hd = dev_get_drvdata(dev);
638 int ret;
639
640 mutex_lock(&hd->lock);
641
642 if (!hdmi_mode_has_audio(&hd->cfg) || !hd->display_enabled) {
643 ret = -EPERM;
644 goto out;
645 }
646
647 ret = hdmi5_audio_config(&hd->core, &hd->wp, dss_audio,
648 hd->cfg.timings.pixelclock);
649
650out:
651 mutex_unlock(&hd->lock);
652
653 return ret;
654}
655
656static const struct omap_hdmi_audio_ops hdmi_audio_ops = {
657 .audio_startup = hdmi_audio_startup,
658 .audio_shutdown = hdmi_audio_shutdown,
659 .audio_start = hdmi_audio_start,
660 .audio_stop = hdmi_audio_stop,
661 .audio_config = hdmi_audio_config,
662};
663
664static int hdmi_audio_register(struct device *dev)
665{
666 struct omap_hdmi_audio_pdata pdata = {
667 .dev = dev,
668 .dss_version = omapdss_get_version(),
669 .audio_dma_addr = hdmi_wp_get_audio_dma_addr(&hdmi.wp),
670 .ops = &hdmi_audio_ops,
671 };
672
673 hdmi.audio_pdev = platform_device_register_data(
674 dev, "omap-hdmi-audio", PLATFORM_DEVID_AUTO,
675 &pdata, sizeof(pdata));
676
677 if (IS_ERR(hdmi.audio_pdev))
678 return PTR_ERR(hdmi.audio_pdev);
679
680 return 0;
681}
682
699/* HDMI HW IP initialisation */ 683/* HDMI HW IP initialisation */
700static int omapdss_hdmihw_probe(struct platform_device *pdev) 684static int omapdss_hdmihw_probe(struct platform_device *pdev)
701{ 685{
@@ -703,6 +687,7 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
703 int irq; 687 int irq;
704 688
705 hdmi.pdev = pdev; 689 hdmi.pdev = pdev;
690 dev_set_drvdata(&pdev->dev, &hdmi);
706 691
707 mutex_init(&hdmi.lock); 692 mutex_init(&hdmi.lock);
708 693
@@ -716,28 +701,23 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
716 if (r) 701 if (r)
717 return r; 702 return r;
718 703
719 r = hdmi_pll_init(pdev, &hdmi.pll); 704 r = hdmi_pll_init(pdev, &hdmi.pll, &hdmi.wp);
720 if (r) 705 if (r)
721 return r; 706 return r;
722 707
723 r = hdmi_phy_init(pdev, &hdmi.phy); 708 r = hdmi_phy_init(pdev, &hdmi.phy);
724 if (r) 709 if (r)
725 return r; 710 goto err;
726 711
727 r = hdmi5_core_init(pdev, &hdmi.core); 712 r = hdmi5_core_init(pdev, &hdmi.core);
728 if (r) 713 if (r)
729 return r; 714 goto err;
730
731 r = hdmi_get_clocks(pdev);
732 if (r) {
733 DSSERR("can't get clocks\n");
734 return r;
735 }
736 715
737 irq = platform_get_irq(pdev, 0); 716 irq = platform_get_irq(pdev, 0);
738 if (irq < 0) { 717 if (irq < 0) {
739 DSSERR("platform_get_irq failed\n"); 718 DSSERR("platform_get_irq failed\n");
740 return -ENODEV; 719 r = -ENODEV;
720 goto err;
741 } 721 }
742 722
743 r = devm_request_threaded_irq(&pdev->dev, irq, 723 r = devm_request_threaded_irq(&pdev->dev, irq,
@@ -745,22 +725,38 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
745 IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); 725 IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp);
746 if (r) { 726 if (r) {
747 DSSERR("HDMI IRQ request failed\n"); 727 DSSERR("HDMI IRQ request failed\n");
748 return r; 728 goto err;
749 } 729 }
750 730
751 pm_runtime_enable(&pdev->dev); 731 pm_runtime_enable(&pdev->dev);
752 732
753 hdmi_init_output(pdev); 733 hdmi_init_output(pdev);
754 734
735 r = hdmi_audio_register(&pdev->dev);
736 if (r) {
737 DSSERR("Registering HDMI audio failed %d\n", r);
738 hdmi_uninit_output(pdev);
739 pm_runtime_disable(&pdev->dev);
740 return r;
741 }
742
755 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 743 dss_debugfs_create_file("hdmi", hdmi_dump_regs);
756 744
757 return 0; 745 return 0;
746err:
747 hdmi_pll_uninit(&hdmi.pll);
748 return r;
758} 749}
759 750
760static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) 751static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
761{ 752{
753 if (hdmi.audio_pdev)
754 platform_device_unregister(hdmi.audio_pdev);
755
762 hdmi_uninit_output(pdev); 756 hdmi_uninit_output(pdev);
763 757
758 hdmi_pll_uninit(&hdmi.pll);
759
764 pm_runtime_disable(&pdev->dev); 760 pm_runtime_disable(&pdev->dev);
765 761
766 return 0; 762 return 0;
@@ -768,8 +764,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
768 764
769static int hdmi_runtime_suspend(struct device *dev) 765static int hdmi_runtime_suspend(struct device *dev)
770{ 766{
771 clk_disable_unprepare(hdmi.sys_clk);
772
773 dispc_runtime_put(); 767 dispc_runtime_put();
774 768
775 return 0; 769 return 0;
@@ -783,8 +777,6 @@ static int hdmi_runtime_resume(struct device *dev)
783 if (r < 0) 777 if (r < 0)
784 return r; 778 return r;
785 779
786 clk_prepare_enable(hdmi.sys_clk);
787
788 return 0; 780 return 0;
789} 781}
790 782
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.c b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
index 83acbf7a8c89..a3cfe3d708f7 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
@@ -30,10 +30,8 @@
30#include <linux/string.h> 30#include <linux/string.h>
31#include <linux/seq_file.h> 31#include <linux/seq_file.h>
32#include <drm/drm_edid.h> 32#include <drm/drm_edid.h>
33#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
34#include <sound/asound.h> 33#include <sound/asound.h>
35#include <sound/asoundef.h> 34#include <sound/asoundef.h>
36#endif
37 35
38#include "hdmi5_core.h" 36#include "hdmi5_core.h"
39 37
@@ -644,9 +642,6 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
644 hdmi_core_enable_interrupts(core); 642 hdmi_core_enable_interrupts(core);
645} 643}
646 644
647
648#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
649
650static void hdmi5_core_audio_config(struct hdmi_core_data *core, 645static void hdmi5_core_audio_config(struct hdmi_core_data *core,
651 struct hdmi_core_audio_config *cfg) 646 struct hdmi_core_audio_config *cfg)
652{ 647{
@@ -721,7 +716,7 @@ static void hdmi5_core_audio_config(struct hdmi_core_data *core,
721 716
722 /* Source number */ 717 /* Source number */
723 val = cfg->iec60958_cfg->status[2] & IEC958_AES2_CON_SOURCE; 718 val = cfg->iec60958_cfg->status[2] & IEC958_AES2_CON_SOURCE;
724 REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(2), val, 3, 4); 719 REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(2), val, 3, 0);
725 720
726 /* Channel number right 0 */ 721 /* Channel number right 0 */
727 REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(3), 2, 3, 0); 722 REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(3), 2, 3, 0);
@@ -879,6 +874,9 @@ int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
879 /* only LPCM atm */ 874 /* only LPCM atm */
880 audio_format.type = HDMI_AUDIO_TYPE_LPCM; 875 audio_format.type = HDMI_AUDIO_TYPE_LPCM;
881 876
877 /* only allowed option */
878 audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST;
879
882 /* disable start/stop signals of IEC 60958 blocks */ 880 /* disable start/stop signals of IEC 60958 blocks */
883 audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON; 881 audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON;
884 882
@@ -894,7 +892,6 @@ int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
894 892
895 return 0; 893 return 0;
896} 894}
897#endif
898 895
899int hdmi5_core_init(struct platform_device *pdev, struct hdmi_core_data *core) 896int hdmi5_core_init(struct platform_device *pdev, struct hdmi_core_data *core)
900{ 897{
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.h b/drivers/video/fbdev/omap2/dss/hdmi5_core.h
index ce7e9f376f04..f2f1022c5516 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5_core.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.h
@@ -299,8 +299,6 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
299 struct hdmi_config *cfg); 299 struct hdmi_config *cfg);
300int hdmi5_core_init(struct platform_device *pdev, struct hdmi_core_data *core); 300int hdmi5_core_init(struct platform_device *pdev, struct hdmi_core_data *core);
301 301
302#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
303int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, 302int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
304 struct omap_dss_audio *audio, u32 pclk); 303 struct omap_dss_audio *audio, u32 pclk);
305#endif 304#endif
306#endif
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_common.c b/drivers/video/fbdev/omap2/dss/hdmi_common.c
index 7d5f1039de9f..1b8fcc6c4ba1 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_common.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_common.c
@@ -48,7 +48,6 @@ int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
48 return 0; 48 return 0;
49} 49}
50 50
51#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
52int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts) 51int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts)
53{ 52{
54 u32 deep_color; 53 u32 deep_color;
@@ -147,4 +146,3 @@ int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts)
147 146
148 return 0; 147 return 0;
149} 148}
150#endif
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_phy.c b/drivers/video/fbdev/omap2/dss/hdmi_phy.c
index e007ac892d79..bc9e07d2afbe 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_phy.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_phy.c
@@ -20,9 +20,7 @@
20 20
21struct hdmi_phy_features { 21struct hdmi_phy_features {
22 bool bist_ctrl; 22 bool bist_ctrl;
23 bool calc_freqout;
24 bool ldo_voltage; 23 bool ldo_voltage;
25 unsigned long dcofreq_min;
26 unsigned long max_phy; 24 unsigned long max_phy;
27}; 25};
28 26
@@ -132,7 +130,8 @@ static void hdmi_phy_configure_lanes(struct hdmi_phy_data *phy)
132 REG_FLD_MOD(phy->base, HDMI_TXPHY_PAD_CFG_CTRL, pol_val, 30, 27); 130 REG_FLD_MOD(phy->base, HDMI_TXPHY_PAD_CFG_CTRL, pol_val, 30, 27);
133} 131}
134 132
135int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg) 133int hdmi_phy_configure(struct hdmi_phy_data *phy, unsigned long hfbitclk,
134 unsigned long lfbitclk)
136{ 135{
137 u8 freqout; 136 u8 freqout;
138 137
@@ -149,20 +148,16 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg)
149 if (phy_feat->bist_ctrl) 148 if (phy_feat->bist_ctrl)
150 REG_FLD_MOD(phy->base, HDMI_TXPHY_BIST_CONTROL, 1, 11, 11); 149 REG_FLD_MOD(phy->base, HDMI_TXPHY_BIST_CONTROL, 1, 11, 11);
151 150
152 if (phy_feat->calc_freqout) { 151 /*
153 /* DCOCLK/10 is pixel clock, compare pclk with DCOCLK_MIN/10 */ 152 * If the hfbitclk != lfbitclk, it means the lfbitclk was configured
154 u32 dco_min = phy_feat->dcofreq_min / 10; 153 * to be used for TMDS.
155 u32 pclk = cfg->timings.pixelclock; 154 */
156 155 if (hfbitclk != lfbitclk)
157 if (pclk < dco_min) 156 freqout = 0;
158 freqout = 0; 157 else if (hfbitclk / 10 < phy_feat->max_phy)
159 else if ((pclk >= dco_min) && (pclk < phy_feat->max_phy))
160 freqout = 1;
161 else
162 freqout = 2;
163 } else {
164 freqout = 1; 158 freqout = 1;
165 } 159 else
160 freqout = 2;
166 161
167 /* 162 /*
168 * Write to phy address 0 to configure the clock 163 * Write to phy address 0 to configure the clock
@@ -184,17 +179,13 @@ int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg)
184 179
185static const struct hdmi_phy_features omap44xx_phy_feats = { 180static const struct hdmi_phy_features omap44xx_phy_feats = {
186 .bist_ctrl = false, 181 .bist_ctrl = false,
187 .calc_freqout = false,
188 .ldo_voltage = true, 182 .ldo_voltage = true,
189 .dcofreq_min = 500000000,
190 .max_phy = 185675000, 183 .max_phy = 185675000,
191}; 184};
192 185
193static const struct hdmi_phy_features omap54xx_phy_feats = { 186static const struct hdmi_phy_features omap54xx_phy_feats = {
194 .bist_ctrl = true, 187 .bist_ctrl = true,
195 .calc_freqout = true,
196 .ldo_voltage = false, 188 .ldo_voltage = false,
197 .dcofreq_min = 750000000,
198 .max_phy = 186000000, 189 .max_phy = 186000000,
199}; 190};
200 191
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
index 6d92bb32fe51..87accdb59c81 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_pll.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
@@ -15,26 +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#define HDMI_DEFAULT_REGN 16
24#define HDMI_DEFAULT_REGM2 1
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
38void 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)
39{ 26{
40#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\ 27#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\
@@ -51,228 +38,189 @@ void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s)
51 DUMPPLL(PLLCTRL_CFG4); 38 DUMPPLL(PLLCTRL_CFG4);
52} 39}
53 40
54void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy) 41void hdmi_pll_compute(struct hdmi_pll_data *pll,
42 unsigned long target_tmds, struct dss_pll_clock_info *pi)
55{ 43{
56 struct hdmi_pll_info *pi = &pll->info; 44 unsigned long fint, clkdco, clkout;
57 unsigned long refclk; 45 unsigned long target_bitclk, target_clkdco;
58 u32 mf; 46 unsigned long min_dco;
47 unsigned n, m, mf, m2, sd;
48 unsigned long clkin;
49 const struct dss_pll_hw *hw = pll->pll.hw;
59 50
60 /* use our funky units */ 51 clkin = clk_get_rate(pll->pll.clkin);
61 clkin /= 10000;
62 52
63 /* 53 DSSDBG("clkin %lu, target tmds %lu\n", clkin, target_tmds);
64 * Input clock is predivided by N + 1
65 * out put of which is reference clk
66 */
67 54
68 pi->regn = HDMI_DEFAULT_REGN; 55 target_bitclk = target_tmds * 10;
69 56
70 refclk = clkin / pi->regn; 57 /* Fint */
58 n = DIV_ROUND_UP(clkin, hw->fint_max);
59 fint = clkin / n;
71 60
72 /* temorary hack to make sure DCO freq isn't calculated too low */ 61 /* adjust m2 so that the clkdco will be high enough */
73 if (pll_feat->bound_dcofreq && phy <= 65000) 62 min_dco = roundup(hw->clkdco_min, fint);
74 pi->regm2 = 3; 63 m2 = DIV_ROUND_UP(min_dco, target_bitclk);
75 else 64 if (m2 == 0)
76 pi->regm2 = HDMI_DEFAULT_REGM2; 65 m2 = 1;
77
78 /*
79 * multiplier is pixel_clk/ref_clk
80 * Multiplying by 100 to avoid fractional part removal
81 */
82 pi->regm = phy * pi->regm2 / refclk;
83
84 /*
85 * fractional multiplier is remainder of the difference between
86 * multiplier and actual phy(required pixel clock thus should be
87 * multiplied by 2^18(262144) divided by the reference clock
88 */
89 mf = (phy - pi->regm / pi->regm2 * refclk) * 262144;
90 pi->regmf = pi->regm2 * mf / refclk;
91
92 /*
93 * Dcofreq should be set to 1 if required pixel clock
94 * is greater than 1000MHz
95 */
96 pi->dcofreq = phy > 1000 * 100;
97 pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10;
98
99 /* Set the reference clock to sysclk reference */
100 pi->refsel = HDMI_REFSEL_SYSCLK;
101
102 DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf);
103 DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd);
104}
105 66
67 target_clkdco = target_bitclk * m2;
68 m = target_clkdco / fint;
106 69
107static int hdmi_pll_config(struct hdmi_pll_data *pll) 70 clkdco = fint * m;
108{
109 u32 r;
110 struct hdmi_pll_info *fmt = &pll->info;
111 71
112 /* PLL start always use manual mode */ 72 /* adjust clkdco with fractional mf */
113 REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, 0x0, 0, 0); 73 if (WARN_ON(target_clkdco - clkdco > fint))
114 74 mf = 0;
115 r = hdmi_read_reg(pll->base, PLLCTRL_CFG1);
116 r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */
117 r = FLD_MOD(r, fmt->regn - 1, 8, 1); /* CFG1_PLL_REGN */
118 hdmi_write_reg(pll->base, PLLCTRL_CFG1, r);
119
120 r = hdmi_read_reg(pll->base, PLLCTRL_CFG2);
121
122 r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
123 r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */
124 r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */
125 r = FLD_MOD(r, fmt->refsel, 22, 21); /* REFSEL */
126
127 if (fmt->dcofreq)
128 r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
129 else 75 else
130 r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */ 76 mf = (u32)div_u64(262144ull * (target_clkdco - clkdco), fint);
131
132 hdmi_write_reg(pll->base, PLLCTRL_CFG2, r);
133
134 REG_FLD_MOD(pll->base, PLLCTRL_CFG3, fmt->regsd, 17, 10);
135 77
136 r = hdmi_read_reg(pll->base, PLLCTRL_CFG4); 78 if (mf > 0)
137 r = FLD_MOD(r, fmt->regm2, 24, 18); 79 clkdco += (u32)div_u64((u64)mf * fint, 262144);
138 r = FLD_MOD(r, fmt->regmf, 17, 0);
139 hdmi_write_reg(pll->base, PLLCTRL_CFG4, r);
140 80
141 /* go now */ 81 clkout = clkdco / m2;
142 REG_FLD_MOD(pll->base, PLLCTRL_PLL_GO, 0x1, 0, 0);
143 82
144 /* wait for bit change */ 83 /* sigma-delta */
145 if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_GO, 84 sd = DIV_ROUND_UP(fint * m, 250000000);
146 0, 0, 0) != 0) {
147 DSSERR("PLL GO bit not clearing\n");
148 return -ETIMEDOUT;
149 }
150 85
151 /* Wait till the lock bit is set in PLL status */ 86 DSSDBG("N = %u, M = %u, M.f = %u, M2 = %u, SD = %u\n",
152 if (hdmi_wait_for_bit_change(pll->base, 87 n, m, mf, m2, sd);
153 PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) { 88 DSSDBG("Fint %lu, clkdco %lu, clkout %lu\n", fint, clkdco, clkout);
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 89
164 DSSDBG("PLL locked!\n"); 90 pi->n = n;
91 pi->m = m;
92 pi->mf = mf;
93 pi->mX[0] = m2;
94 pi->sd = sd;
165 95
166 return 0; 96 pi->fint = fint;
97 pi->clkdco = clkdco;
98 pi->clkout[0] = clkout;
167} 99}
168 100
169static int hdmi_pll_reset(struct hdmi_pll_data *pll) 101static int hdmi_pll_enable(struct dss_pll *dsspll)
170{
171 /* SYSRESET controlled by power FSM */
172 REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, pll_feat->sys_reset, 3, 3);
173
174 /* READ 0x0 reset is in progress */
175 if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 0, 0, 1)
176 != 1) {
177 DSSERR("Failed to sysreset PLL\n");
178 return -ETIMEDOUT;
179 }
180
181 return 0;
182}
183
184int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp)
185{ 102{
103 struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
104 struct hdmi_wp_data *wp = pll->wp;
186 u16 r = 0; 105 u16 r = 0;
187 106
188 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
189 if (r)
190 return r;
191
192 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); 107 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
193 if (r) 108 if (r)
194 return r; 109 return r;
195 110
196 r = hdmi_pll_reset(pll);
197 if (r)
198 return r;
199
200 r = hdmi_pll_config(pll);
201 if (r)
202 return r;
203
204 return 0; 111 return 0;
205} 112}
206 113
207void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp) 114static void hdmi_pll_disable(struct dss_pll *dsspll)
208{ 115{
116 struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
117 struct hdmi_wp_data *wp = pll->wp;
118
209 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); 119 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
210} 120}
211 121
212static const struct hdmi_pll_features omap44xx_pll_feats = { 122static const struct dss_pll_ops dsi_pll_ops = {
213 .sys_reset = false, 123 .enable = hdmi_pll_enable,
214 .bound_dcofreq = false, 124 .disable = hdmi_pll_disable,
215 .fint_min = 500000, 125 .set_config = dss_pll_write_config_type_b,
216 .fint_max = 2500000,
217 .regm_max = 4095,
218 .dcofreq_low_min = 500000000,
219 .dcofreq_low_max = 1000000000,
220 .dcofreq_high_min = 1000000000,
221 .dcofreq_high_max = 2000000000,
222}; 126};
223 127
224static const struct hdmi_pll_features omap54xx_pll_feats = { 128static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = {
225 .sys_reset = true, 129 .n_max = 255,
226 .bound_dcofreq = true, 130 .m_min = 20,
227 .fint_min = 620000, 131 .m_max = 4095,
228 .fint_max = 2500000, 132 .mX_max = 127,
229 .regm_max = 2046, 133 .fint_min = 500000,
230 .dcofreq_low_min = 750000000, 134 .fint_max = 2500000,
231 .dcofreq_low_max = 1500000000, 135 .clkdco_max = 1800000000,
232 .dcofreq_high_min = 1250000000, 136
233 .dcofreq_high_max = 2500000000UL, 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,
234}; 150};
235 151
236static int hdmi_pll_init_features(struct platform_device *pdev) 152static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = {
153 .n_max = 255,
154 .m_min = 20,
155 .m_max = 2045,
156 .mX_max = 127,
157 .fint_min = 620000,
158 .fint_max = 2500000,
159 .clkdco_max = 1800000000,
160
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,
175};
176
177static int dsi_init_pll_data(struct platform_device *pdev, struct hdmi_pll_data *hpll)
237{ 178{
238 struct hdmi_pll_features *dst; 179 struct dss_pll *pll = &hpll->pll;
239 const struct hdmi_pll_features *src; 180 struct clk *clk;
181 int r;
240 182
241 dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL); 183 clk = devm_clk_get(&pdev->dev, "sys_clk");
242 if (!dst) { 184 if (IS_ERR(clk)) {
243 dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n"); 185 DSSERR("can't get sys_clk\n");
244 return -ENOMEM; 186 return PTR_ERR(clk);
245 } 187 }
246 188
189 pll->name = "hdmi";
190 pll->base = hpll->base;
191 pll->clkin = clk;
192
247 switch (omapdss_get_version()) { 193 switch (omapdss_get_version()) {
248 case OMAPDSS_VER_OMAP4430_ES1: 194 case OMAPDSS_VER_OMAP4430_ES1:
249 case OMAPDSS_VER_OMAP4430_ES2: 195 case OMAPDSS_VER_OMAP4430_ES2:
250 case OMAPDSS_VER_OMAP4: 196 case OMAPDSS_VER_OMAP4:
251 src = &omap44xx_pll_feats; 197 pll->hw = &dss_omap4_hdmi_pll_hw;
252 break; 198 break;
253 199
254 case OMAPDSS_VER_OMAP5: 200 case OMAPDSS_VER_OMAP5:
255 src = &omap54xx_pll_feats; 201 pll->hw = &dss_omap5_hdmi_pll_hw;
256 break; 202 break;
257 203
258 default: 204 default:
259 return -ENODEV; 205 return -ENODEV;
260 } 206 }
261 207
262 memcpy(dst, src, sizeof(*dst)); 208 pll->ops = &dsi_pll_ops;
263 pll_feat = dst; 209
210 r = dss_pll_register(pll);
211 if (r)
212 return r;
264 213
265 return 0; 214 return 0;
266} 215}
267 216
268int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll) 217int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll,
218 struct hdmi_wp_data *wp)
269{ 219{
270 int r; 220 int r;
271 struct resource *res; 221 struct resource *res;
272 222
273 r = hdmi_pll_init_features(pdev); 223 pll->wp = wp;
274 if (r)
275 return r;
276 224
277 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll"); 225 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll");
278 if (!res) { 226 if (!res) {
@@ -286,5 +234,18 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll)
286 return PTR_ERR(pll->base); 234 return PTR_ERR(pll->base);
287 } 235 }
288 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
289 return 0; 243 return 0;
290} 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}
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_wp.c b/drivers/video/fbdev/omap2/dss/hdmi_wp.c
index 496327e2b21b..c15377e242cc 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_wp.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_wp.c
@@ -185,7 +185,6 @@ void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
185 timings->interlace = param->timings.interlace; 185 timings->interlace = param->timings.interlace;
186} 186}
187 187
188#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) || defined(CONFIG_OMAP5_DSS_HDMI_AUDIO)
189void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp, 188void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp,
190 struct hdmi_audio_format *aud_fmt) 189 struct hdmi_audio_format *aud_fmt)
191{ 190{
@@ -194,8 +193,12 @@ void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp,
194 DSSDBG("Enter hdmi_wp_audio_config_format\n"); 193 DSSDBG("Enter hdmi_wp_audio_config_format\n");
195 194
196 r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG); 195 r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG);
197 r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24); 196 if (omapdss_get_version() == OMAPDSS_VER_OMAP4430_ES1 ||
198 r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16); 197 omapdss_get_version() == OMAPDSS_VER_OMAP4430_ES2 ||
198 omapdss_get_version() == OMAPDSS_VER_OMAP4) {
199 r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24);
200 r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16);
201 }
199 r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5); 202 r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5);
200 r = FLD_MOD(r, aud_fmt->type, 4, 4); 203 r = FLD_MOD(r, aud_fmt->type, 4, 4);
201 r = FLD_MOD(r, aud_fmt->justification, 3, 3); 204 r = FLD_MOD(r, aud_fmt->justification, 3, 3);
@@ -236,7 +239,6 @@ int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable)
236 239
237 return 0; 240 return 0;
238} 241}
239#endif
240 242
241int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp) 243int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
242{ 244{
@@ -247,6 +249,7 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
247 DSSERR("can't get WP mem resource\n"); 249 DSSERR("can't get WP mem resource\n");
248 return -EINVAL; 250 return -EINVAL;
249 } 251 }
252 wp->phys_base = res->start;
250 253
251 wp->base = devm_ioremap_resource(&pdev->dev, res); 254 wp->base = devm_ioremap_resource(&pdev->dev, res);
252 if (IS_ERR(wp->base)) { 255 if (IS_ERR(wp->base)) {
@@ -256,3 +259,8 @@ int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp)
256 259
257 return 0; 260 return 0;
258} 261}
262
263phys_addr_t hdmi_wp_get_audio_dma_addr(struct hdmi_wp_data *wp)
264{
265 return wp->phys_base + HDMI_WP_AUDIO_DATA;
266}
diff --git a/drivers/video/fbdev/omap2/dss/output.c b/drivers/video/fbdev/omap2/dss/output.c
index 2ab3afa615e8..16072159bd24 100644
--- a/drivers/video/fbdev/omap2/dss/output.c
+++ b/drivers/video/fbdev/omap2/dss/output.c
@@ -19,6 +19,7 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/of.h>
22 23
23#include <video/omapdss.h> 24#include <video/omapdss.h>
24 25
@@ -131,18 +132,30 @@ struct omap_dss_device *omap_dss_find_output(const char *name)
131} 132}
132EXPORT_SYMBOL(omap_dss_find_output); 133EXPORT_SYMBOL(omap_dss_find_output);
133 134
134struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node) 135struct omap_dss_device *omap_dss_find_output_by_port_node(struct device_node *port)
135{ 136{
137 struct device_node *src_node;
136 struct omap_dss_device *out; 138 struct omap_dss_device *out;
139 u32 reg;
140
141 src_node = dss_of_port_get_parent_device(port);
142 if (!src_node)
143 return NULL;
144
145 reg = dss_of_port_get_port_number(port);
137 146
138 list_for_each_entry(out, &output_list, list) { 147 list_for_each_entry(out, &output_list, list) {
139 if (out->dev->of_node == node) 148 if (out->dev->of_node == src_node && out->port_num == reg) {
149 of_node_put(src_node);
140 return omap_dss_get_device(out); 150 return omap_dss_get_device(out);
151 }
141 } 152 }
142 153
154 of_node_put(src_node);
155
143 return NULL; 156 return NULL;
144} 157}
145EXPORT_SYMBOL(omap_dss_find_output_by_node); 158EXPORT_SYMBOL(omap_dss_find_output_by_port_node);
146 159
147struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev) 160struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev)
148{ 161{
diff --git a/drivers/video/fbdev/omap2/dss/pll.c b/drivers/video/fbdev/omap2/dss/pll.c
new file mode 100644
index 000000000000..50bc62c5d367
--- /dev/null
+++ b/drivers/video/fbdev/omap2/dss/pll.c
@@ -0,0 +1,378 @@
1/*
2 * Copyright (C) 2014 Texas Instruments Incorporated
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 as published by
6 * the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#define DSS_SUBSYS_NAME "PLL"
18
19#include <linux/clk.h>
20#include <linux/io.h>
21#include <linux/kernel.h>
22#include <linux/regulator/consumer.h>
23#include <linux/sched.h>
24
25#include <video/omapdss.h>
26
27#include "dss.h"
28
29#define PLL_CONTROL 0x0000
30#define PLL_STATUS 0x0004
31#define PLL_GO 0x0008
32#define PLL_CONFIGURATION1 0x000C
33#define PLL_CONFIGURATION2 0x0010
34#define PLL_CONFIGURATION3 0x0014
35#define PLL_SSC_CONFIGURATION1 0x0018
36#define PLL_SSC_CONFIGURATION2 0x001C
37#define PLL_CONFIGURATION4 0x0020
38
39static struct dss_pll *dss_plls[4];
40
41int dss_pll_register(struct dss_pll *pll)
42{
43 int i;
44
45 for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
46 if (!dss_plls[i]) {
47 dss_plls[i] = pll;
48 return 0;
49 }
50 }
51
52 return -EBUSY;
53}
54
55void dss_pll_unregister(struct dss_pll *pll)
56{
57 int i;
58
59 for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
60 if (dss_plls[i] == pll) {
61 dss_plls[i] = NULL;
62 return;
63 }
64 }
65}
66
67struct dss_pll *dss_pll_find(const char *name)
68{
69 int i;
70
71 for (i = 0; i < ARRAY_SIZE(dss_plls); ++i) {
72 if (dss_plls[i] && strcmp(dss_plls[i]->name, name) == 0)
73 return dss_plls[i];
74 }
75
76 return NULL;
77}
78
79int dss_pll_enable(struct dss_pll *pll)
80{
81 int r;
82
83 r = clk_prepare_enable(pll->clkin);
84 if (r)
85 return r;
86
87 if (pll->regulator) {
88 r = regulator_enable(pll->regulator);
89 if (r)
90 goto err_reg;
91 }
92
93 r = pll->ops->enable(pll);
94 if (r)
95 goto err_enable;
96
97 return 0;
98
99err_enable:
100 regulator_disable(pll->regulator);
101err_reg:
102 clk_disable_unprepare(pll->clkin);
103 return r;
104}
105
106void dss_pll_disable(struct dss_pll *pll)
107{
108 pll->ops->disable(pll);
109
110 if (pll->regulator)
111 regulator_disable(pll->regulator);
112
113 clk_disable_unprepare(pll->clkin);
114
115 memset(&pll->cinfo, 0, sizeof(pll->cinfo));
116}
117
118int dss_pll_set_config(struct dss_pll *pll, const struct dss_pll_clock_info *cinfo)
119{
120 int r;
121
122 r = pll->ops->set_config(pll, cinfo);
123 if (r)
124 return r;
125
126 pll->cinfo = *cinfo;
127
128 return 0;
129}
130
131bool dss_pll_hsdiv_calc(const struct dss_pll *pll, unsigned long clkdco,
132 unsigned long out_min, unsigned long out_max,
133 dss_hsdiv_calc_func func, void *data)
134{
135 const struct dss_pll_hw *hw = pll->hw;
136 int m, m_start, m_stop;
137 unsigned long out;
138
139 out_min = out_min ? out_min : 1;
140 out_max = out_max ? out_max : ULONG_MAX;
141
142 m_start = max(DIV_ROUND_UP(clkdco, out_max), 1ul);
143
144 m_stop = min((unsigned)(clkdco / out_min), hw->mX_max);
145
146 for (m = m_start; m <= m_stop; ++m) {
147 out = clkdco / m;
148
149 if (func(m, out, data))
150 return true;
151 }
152
153 return false;
154}
155
156bool dss_pll_calc(const struct dss_pll *pll, unsigned long clkin,
157 unsigned long pll_min, unsigned long pll_max,
158 dss_pll_calc_func func, void *data)
159{
160 const struct dss_pll_hw *hw = pll->hw;
161 int n, n_start, n_stop;
162 int m, m_start, m_stop;
163 unsigned long fint, clkdco;
164 unsigned long pll_hw_max;
165 unsigned long fint_hw_min, fint_hw_max;
166
167 pll_hw_max = hw->clkdco_max;
168
169 fint_hw_min = hw->fint_min;
170 fint_hw_max = hw->fint_max;
171
172 n_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
173 n_stop = min((unsigned)(clkin / fint_hw_min), hw->n_max);
174
175 pll_max = pll_max ? pll_max : ULONG_MAX;
176
177 for (n = n_start; n <= n_stop; ++n) {
178 fint = clkin / n;
179
180 m_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
181 1ul);
182 m_stop = min3((unsigned)(pll_max / fint / 2),
183 (unsigned)(pll_hw_max / fint / 2),
184 hw->m_max);
185
186 for (m = m_start; m <= m_stop; ++m) {
187 clkdco = 2 * m * fint;
188
189 if (func(n, m, fint, clkdco, data))
190 return true;
191 }
192 }
193
194 return false;
195}
196
197static int wait_for_bit_change(void __iomem *reg, int bitnum, int value)
198{
199 unsigned long timeout;
200 ktime_t wait;
201 int t;
202
203 /* first busyloop to see if the bit changes right away */
204 t = 100;
205 while (t-- > 0) {
206 if (FLD_GET(readl_relaxed(reg), bitnum, bitnum) == value)
207 return value;
208 }
209
210 /* then loop for 500ms, sleeping for 1ms in between */
211 timeout = jiffies + msecs_to_jiffies(500);
212 while (time_before(jiffies, timeout)) {
213 if (FLD_GET(readl_relaxed(reg), bitnum, bitnum) == value)
214 return value;
215
216 wait = ns_to_ktime(1000 * 1000);
217 set_current_state(TASK_UNINTERRUPTIBLE);
218 schedule_hrtimeout(&wait, HRTIMER_MODE_REL);
219 }
220
221 return !value;
222}
223
224static int dss_wait_hsdiv_ack(struct dss_pll *pll, u32 hsdiv_ack_mask)
225{
226 int t = 100;
227
228 while (t-- > 0) {
229 u32 v = readl_relaxed(pll->base + PLL_STATUS);
230 v &= hsdiv_ack_mask;
231 if (v == hsdiv_ack_mask)
232 return 0;
233 }
234
235 return -ETIMEDOUT;
236}
237
238int dss_pll_write_config_type_a(struct dss_pll *pll,
239 const struct dss_pll_clock_info *cinfo)
240{
241 const struct dss_pll_hw *hw = pll->hw;
242 void __iomem *base = pll->base;
243 int r = 0;
244 u32 l;
245
246 l = 0;
247 if (hw->has_stopmode)
248 l = FLD_MOD(l, 1, 0, 0); /* PLL_STOPMODE */
249 l = FLD_MOD(l, cinfo->n - 1, hw->n_msb, hw->n_lsb); /* PLL_REGN */
250 l = FLD_MOD(l, cinfo->m, hw->m_msb, hw->m_lsb); /* PLL_REGM */
251 /* M4 */
252 l = FLD_MOD(l, cinfo->mX[0] ? cinfo->mX[0] - 1 : 0,
253 hw->mX_msb[0], hw->mX_lsb[0]);
254 /* M5 */
255 l = FLD_MOD(l, cinfo->mX[1] ? cinfo->mX[1] - 1 : 0,
256 hw->mX_msb[1], hw->mX_lsb[1]);
257 writel_relaxed(l, base + PLL_CONFIGURATION1);
258
259 l = 0;
260 /* M6 */
261 l = FLD_MOD(l, cinfo->mX[2] ? cinfo->mX[2] - 1 : 0,
262 hw->mX_msb[2], hw->mX_lsb[2]);
263 /* M7 */
264 l = FLD_MOD(l, cinfo->mX[3] ? cinfo->mX[3] - 1 : 0,
265 hw->mX_msb[3], hw->mX_lsb[3]);
266 writel_relaxed(l, base + PLL_CONFIGURATION3);
267
268 l = readl_relaxed(base + PLL_CONFIGURATION2);
269 if (hw->has_freqsel) {
270 u32 f = cinfo->fint < 1000000 ? 0x3 :
271 cinfo->fint < 1250000 ? 0x4 :
272 cinfo->fint < 1500000 ? 0x5 :
273 cinfo->fint < 1750000 ? 0x6 :
274 0x7;
275
276 l = FLD_MOD(l, f, 4, 1); /* PLL_FREQSEL */
277 } else if (hw->has_selfreqdco) {
278 u32 f = cinfo->clkdco < hw->clkdco_low ? 0x2 : 0x4;
279
280 l = FLD_MOD(l, f, 3, 1); /* PLL_SELFREQDCO */
281 }
282 l = FLD_MOD(l, 1, 13, 13); /* PLL_REFEN */
283 l = FLD_MOD(l, 0, 14, 14); /* PHY_CLKINEN */
284 l = FLD_MOD(l, 0, 16, 16); /* M4_CLOCK_EN */
285 l = FLD_MOD(l, 0, 18, 18); /* M5_CLOCK_EN */
286 l = FLD_MOD(l, 1, 20, 20); /* HSDIVBYPASS */
287 if (hw->has_refsel)
288 l = FLD_MOD(l, 3, 22, 21); /* REFSEL = sysclk */
289 l = FLD_MOD(l, 0, 23, 23); /* M6_CLOCK_EN */
290 l = FLD_MOD(l, 0, 25, 25); /* M7_CLOCK_EN */
291 writel_relaxed(l, base + PLL_CONFIGURATION2);
292
293 writel_relaxed(1, base + PLL_GO); /* PLL_GO */
294
295 if (wait_for_bit_change(base + PLL_GO, 0, 0) != 0) {
296 DSSERR("DSS DPLL GO bit not going down.\n");
297 r = -EIO;
298 goto err;
299 }
300
301 if (wait_for_bit_change(base + PLL_STATUS, 1, 1) != 1) {
302 DSSERR("cannot lock DSS DPLL\n");
303 r = -EIO;
304 goto err;
305 }
306
307 l = readl_relaxed(base + PLL_CONFIGURATION2);
308 l = FLD_MOD(l, 1, 14, 14); /* PHY_CLKINEN */
309 l = FLD_MOD(l, cinfo->mX[0] ? 1 : 0, 16, 16); /* M4_CLOCK_EN */
310 l = FLD_MOD(l, cinfo->mX[1] ? 1 : 0, 18, 18); /* M5_CLOCK_EN */
311 l = FLD_MOD(l, 0, 20, 20); /* HSDIVBYPASS */
312 l = FLD_MOD(l, cinfo->mX[2] ? 1 : 0, 23, 23); /* M6_CLOCK_EN */
313 l = FLD_MOD(l, cinfo->mX[3] ? 1 : 0, 25, 25); /* M7_CLOCK_EN */
314 writel_relaxed(l, base + PLL_CONFIGURATION2);
315
316 r = dss_wait_hsdiv_ack(pll,
317 (cinfo->mX[0] ? BIT(7) : 0) |
318 (cinfo->mX[1] ? BIT(8) : 0) |
319 (cinfo->mX[2] ? BIT(10) : 0) |
320 (cinfo->mX[3] ? BIT(11) : 0));
321 if (r) {
322 DSSERR("failed to enable HSDIV clocks\n");
323 goto err;
324 }
325
326err:
327 return r;
328}
329
330int dss_pll_write_config_type_b(struct dss_pll *pll,
331 const struct dss_pll_clock_info *cinfo)
332{
333 const struct dss_pll_hw *hw = pll->hw;
334 void __iomem *base = pll->base;
335 u32 l;
336
337 l = 0;
338 l = FLD_MOD(l, cinfo->m, 20, 9); /* PLL_REGM */
339 l = FLD_MOD(l, cinfo->n - 1, 8, 1); /* PLL_REGN */
340 writel_relaxed(l, base + PLL_CONFIGURATION1);
341
342 l = readl_relaxed(base + PLL_CONFIGURATION2);
343 l = FLD_MOD(l, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */
344 l = FLD_MOD(l, 0x1, 13, 13); /* PLL_REFEN */
345 l = FLD_MOD(l, 0x0, 14, 14); /* PHY_CLKINEN */
346 if (hw->has_refsel)
347 l = FLD_MOD(l, 0x3, 22, 21); /* REFSEL = SYSCLK */
348
349 /* PLL_SELFREQDCO */
350 if (cinfo->clkdco > hw->clkdco_low)
351 l = FLD_MOD(l, 0x4, 3, 1);
352 else
353 l = FLD_MOD(l, 0x2, 3, 1);
354 writel_relaxed(l, base + PLL_CONFIGURATION2);
355
356 l = readl_relaxed(base + PLL_CONFIGURATION3);
357 l = FLD_MOD(l, cinfo->sd, 17, 10); /* PLL_REGSD */
358 writel_relaxed(l, base + PLL_CONFIGURATION3);
359
360 l = readl_relaxed(base + PLL_CONFIGURATION4);
361 l = FLD_MOD(l, cinfo->mX[0], 24, 18); /* PLL_REGM2 */
362 l = FLD_MOD(l, cinfo->mf, 17, 0); /* PLL_REGM_F */
363 writel_relaxed(l, base + PLL_CONFIGURATION4);
364
365 writel_relaxed(1, base + PLL_GO); /* PLL_GO */
366
367 if (wait_for_bit_change(base + PLL_GO, 0, 0) != 0) {
368 DSSERR("DSS DPLL GO bit not going down.\n");
369 return -EIO;
370 }
371
372 if (wait_for_bit_change(base + PLL_STATUS, 1, 1) != 1) {
373 DSSERR("cannot lock DSS DPLL\n");
374 return -ETIMEDOUT;
375 }
376
377 return 0;
378}
diff --git a/drivers/video/fbdev/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c
index 4c9c46d4ea60..d9b10f27be20 100644
--- a/drivers/video/fbdev/omap2/dss/sdi.c
+++ b/drivers/video/fbdev/omap2/dss/sdi.c
@@ -425,7 +425,7 @@ err_datapairs:
425 return r; 425 return r;
426} 426}
427 427
428void __exit sdi_uninit_port(void) 428void __exit sdi_uninit_port(struct device_node *port)
429{ 429{
430 if (!sdi.port_initialized) 430 if (!sdi.port_initialized)
431 return; 431 return;
diff --git a/drivers/video/fbdev/simplefb.c b/drivers/video/fbdev/simplefb.c
index 210f3a02121a..b2ae9254fd75 100644
--- a/drivers/video/fbdev/simplefb.c
+++ b/drivers/video/fbdev/simplefb.c
@@ -26,6 +26,8 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/platform_data/simplefb.h> 27#include <linux/platform_data/simplefb.h>
28#include <linux/platform_device.h> 28#include <linux/platform_device.h>
29#include <linux/clk-provider.h>
30#include <linux/of_platform.h>
29 31
30static struct fb_fix_screeninfo simplefb_fix = { 32static struct fb_fix_screeninfo simplefb_fix = {
31 .id = "simple", 33 .id = "simple",
@@ -41,6 +43,8 @@ static struct fb_var_screeninfo simplefb_var = {
41 .vmode = FB_VMODE_NONINTERLACED, 43 .vmode = FB_VMODE_NONINTERLACED,
42}; 44};
43 45
46#define PSEUDO_PALETTE_SIZE 16
47
44static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 48static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
45 u_int transp, struct fb_info *info) 49 u_int transp, struct fb_info *info)
46{ 50{
@@ -50,7 +54,7 @@ static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
50 u32 cb = blue >> (16 - info->var.blue.length); 54 u32 cb = blue >> (16 - info->var.blue.length);
51 u32 value; 55 u32 value;
52 56
53 if (regno >= 16) 57 if (regno >= PSEUDO_PALETTE_SIZE)
54 return -EINVAL; 58 return -EINVAL;
55 59
56 value = (cr << info->var.red.offset) | 60 value = (cr << info->var.red.offset) |
@@ -163,11 +167,113 @@ static int simplefb_parse_pd(struct platform_device *pdev,
163 return 0; 167 return 0;
164} 168}
165 169
170struct simplefb_par {
171 u32 palette[PSEUDO_PALETTE_SIZE];
172#if defined CONFIG_OF && defined CONFIG_COMMON_CLK
173 int clk_count;
174 struct clk **clks;
175#endif
176};
177
178#if defined CONFIG_OF && defined CONFIG_COMMON_CLK
179/*
180 * Clock handling code.
181 *
182 * Here we handle the clocks property of our "simple-framebuffer" dt node.
183 * This is necessary so that we can make sure that any clocks needed by
184 * the display engine that the bootloader set up for us (and for which it
185 * provided a simplefb dt node), stay up, for the life of the simplefb
186 * driver.
187 *
188 * When the driver unloads, we cleanly disable, and then release the clocks.
189 *
190 * We only complain about errors here, no action is taken as the most likely
191 * error can only happen due to a mismatch between the bootloader which set
192 * up simplefb, and the clock definitions in the device tree. Chances are
193 * that there are no adverse effects, and if there are, a clean teardown of
194 * the fb probe will not help us much either. So just complain and carry on,
195 * and hope that the user actually gets a working fb at the end of things.
196 */
197static int simplefb_clocks_init(struct simplefb_par *par,
198 struct platform_device *pdev)
199{
200 struct device_node *np = pdev->dev.of_node;
201 struct clk *clock;
202 int i, ret;
203
204 if (dev_get_platdata(&pdev->dev) || !np)
205 return 0;
206
207 par->clk_count = of_clk_get_parent_count(np);
208 if (par->clk_count <= 0)
209 return 0;
210
211 par->clks = kcalloc(par->clk_count, sizeof(struct clk *), GFP_KERNEL);
212 if (!par->clks)
213 return -ENOMEM;
214
215 for (i = 0; i < par->clk_count; i++) {
216 clock = of_clk_get(np, i);
217 if (IS_ERR(clock)) {
218 if (PTR_ERR(clock) == -EPROBE_DEFER) {
219 while (--i >= 0) {
220 if (par->clks[i])
221 clk_put(par->clks[i]);
222 }
223 kfree(par->clks);
224 return -EPROBE_DEFER;
225 }
226 dev_err(&pdev->dev, "%s: clock %d not found: %ld\n",
227 __func__, i, PTR_ERR(clock));
228 continue;
229 }
230 par->clks[i] = clock;
231 }
232
233 for (i = 0; i < par->clk_count; i++) {
234 if (par->clks[i]) {
235 ret = clk_prepare_enable(par->clks[i]);
236 if (ret) {
237 dev_err(&pdev->dev,
238 "%s: failed to enable clock %d: %d\n",
239 __func__, i, ret);
240 clk_put(par->clks[i]);
241 par->clks[i] = NULL;
242 }
243 }
244 }
245
246 return 0;
247}
248
249static void simplefb_clocks_destroy(struct simplefb_par *par)
250{
251 int i;
252
253 if (!par->clks)
254 return;
255
256 for (i = 0; i < par->clk_count; i++) {
257 if (par->clks[i]) {
258 clk_disable_unprepare(par->clks[i]);
259 clk_put(par->clks[i]);
260 }
261 }
262
263 kfree(par->clks);
264}
265#else
266static int simplefb_clocks_init(struct simplefb_par *par,
267 struct platform_device *pdev) { return 0; }
268static void simplefb_clocks_destroy(struct simplefb_par *par) { }
269#endif
270
166static int simplefb_probe(struct platform_device *pdev) 271static int simplefb_probe(struct platform_device *pdev)
167{ 272{
168 int ret; 273 int ret;
169 struct simplefb_params params; 274 struct simplefb_params params;
170 struct fb_info *info; 275 struct fb_info *info;
276 struct simplefb_par *par;
171 struct resource *mem; 277 struct resource *mem;
172 278
173 if (fb_get_options("simplefb", NULL)) 279 if (fb_get_options("simplefb", NULL))
@@ -188,11 +294,13 @@ static int simplefb_probe(struct platform_device *pdev)
188 return -EINVAL; 294 return -EINVAL;
189 } 295 }
190 296
191 info = framebuffer_alloc(sizeof(u32) * 16, &pdev->dev); 297 info = framebuffer_alloc(sizeof(struct simplefb_par), &pdev->dev);
192 if (!info) 298 if (!info)
193 return -ENOMEM; 299 return -ENOMEM;
194 platform_set_drvdata(pdev, info); 300 platform_set_drvdata(pdev, info);
195 301
302 par = info->par;
303
196 info->fix = simplefb_fix; 304 info->fix = simplefb_fix;
197 info->fix.smem_start = mem->start; 305 info->fix.smem_start = mem->start;
198 info->fix.smem_len = resource_size(mem); 306 info->fix.smem_len = resource_size(mem);
@@ -211,8 +319,8 @@ static int simplefb_probe(struct platform_device *pdev)
211 319
212 info->apertures = alloc_apertures(1); 320 info->apertures = alloc_apertures(1);
213 if (!info->apertures) { 321 if (!info->apertures) {
214 framebuffer_release(info); 322 ret = -ENOMEM;
215 return -ENOMEM; 323 goto error_fb_release;
216 } 324 }
217 info->apertures->ranges[0].base = info->fix.smem_start; 325 info->apertures->ranges[0].base = info->fix.smem_start;
218 info->apertures->ranges[0].size = info->fix.smem_len; 326 info->apertures->ranges[0].size = info->fix.smem_len;
@@ -222,10 +330,14 @@ static int simplefb_probe(struct platform_device *pdev)
222 info->screen_base = ioremap_wc(info->fix.smem_start, 330 info->screen_base = ioremap_wc(info->fix.smem_start,
223 info->fix.smem_len); 331 info->fix.smem_len);
224 if (!info->screen_base) { 332 if (!info->screen_base) {
225 framebuffer_release(info); 333 ret = -ENOMEM;
226 return -ENODEV; 334 goto error_fb_release;
227 } 335 }
228 info->pseudo_palette = (void *)(info + 1); 336 info->pseudo_palette = par->palette;
337
338 ret = simplefb_clocks_init(par, pdev);
339 if (ret < 0)
340 goto error_unmap;
229 341
230 dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes, mapped to 0x%p\n", 342 dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes, mapped to 0x%p\n",
231 info->fix.smem_start, info->fix.smem_len, 343 info->fix.smem_start, info->fix.smem_len,
@@ -238,21 +350,29 @@ static int simplefb_probe(struct platform_device *pdev)
238 ret = register_framebuffer(info); 350 ret = register_framebuffer(info);
239 if (ret < 0) { 351 if (ret < 0) {
240 dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret); 352 dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret);
241 iounmap(info->screen_base); 353 goto error_clocks;
242 framebuffer_release(info);
243 return ret;
244 } 354 }
245 355
246 dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node); 356 dev_info(&pdev->dev, "fb%d: simplefb registered!\n", info->node);
247 357
248 return 0; 358 return 0;
359
360error_clocks:
361 simplefb_clocks_destroy(par);
362error_unmap:
363 iounmap(info->screen_base);
364error_fb_release:
365 framebuffer_release(info);
366 return ret;
249} 367}
250 368
251static int simplefb_remove(struct platform_device *pdev) 369static int simplefb_remove(struct platform_device *pdev)
252{ 370{
253 struct fb_info *info = platform_get_drvdata(pdev); 371 struct fb_info *info = platform_get_drvdata(pdev);
372 struct simplefb_par *par = info->par;
254 373
255 unregister_framebuffer(info); 374 unregister_framebuffer(info);
375 simplefb_clocks_destroy(par);
256 framebuffer_release(info); 376 framebuffer_release(info);
257 377
258 return 0; 378 return 0;
@@ -273,7 +393,27 @@ static struct platform_driver simplefb_driver = {
273 .probe = simplefb_probe, 393 .probe = simplefb_probe,
274 .remove = simplefb_remove, 394 .remove = simplefb_remove,
275}; 395};
276module_platform_driver(simplefb_driver); 396
397static int __init simplefb_init(void)
398{
399 int ret;
400 struct device_node *np;
401
402 ret = platform_driver_register(&simplefb_driver);
403 if (ret)
404 return ret;
405
406 if (IS_ENABLED(CONFIG_OF) && of_chosen) {
407 for_each_child_of_node(of_chosen, np) {
408 if (of_device_is_compatible(np, "simple-framebuffer"))
409 of_platform_device_create(np, NULL, NULL);
410 }
411 }
412
413 return 0;
414}
415
416fs_initcall(simplefb_init);
277 417
278MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>"); 418MODULE_AUTHOR("Stephen Warren <swarren@wwwdotorg.org>");
279MODULE_DESCRIPTION("Simple framebuffer driver"); 419MODULE_DESCRIPTION("Simple framebuffer driver");