aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/fbdev/omap2
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/fbdev/omap2')
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-opa362.c12
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-dpi.c13
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c7
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c9
-rw-r--r--drivers/video/fbdev/omap2/dss/core.c80
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc.c156
-rw-r--r--drivers/video/fbdev/omap2/dss/display-sysfs.c2
-rw-r--r--drivers/video/fbdev/omap2/dss/dpi.c36
-rw-r--r--drivers/video/fbdev/omap2/dss/dsi.c27
-rw-r--r--drivers/video/fbdev/omap2/dss/dss.c232
-rw-r--r--drivers/video/fbdev/omap2/dss/dss.h32
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4.c30
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4_core.c12
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi5.c28
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi5_core.c5
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_wp.c16
-rw-r--r--drivers/video/fbdev/omap2/dss/rfbi.c32
-rw-r--r--drivers/video/fbdev/omap2/dss/sdi.c35
-rw-r--r--drivers/video/fbdev/omap2/dss/venc.c31
19 files changed, 548 insertions, 247 deletions
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-opa362.c b/drivers/video/fbdev/omap2/displays-new/encoder-opa362.c
index 84a6b3367124..a14d993f719d 100644
--- a/drivers/video/fbdev/omap2/displays-new/encoder-opa362.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-opa362.c
@@ -201,15 +201,9 @@ static int opa362_probe(struct platform_device *pdev)
201 201
202 platform_set_drvdata(pdev, ddata); 202 platform_set_drvdata(pdev, ddata);
203 203
204 gpio = devm_gpiod_get(&pdev->dev, "enable"); 204 gpio = devm_gpiod_get_optional(&pdev->dev, "enable", GPIOD_OUT_LOW);
205 if (IS_ERR(gpio)) { 205 if (IS_ERR(gpio))
206 if (PTR_ERR(gpio) != -ENOENT) 206 return PTR_ERR(gpio);
207 return PTR_ERR(gpio);
208
209 gpio = NULL;
210 } else {
211 gpiod_direction_output(gpio, 0);
212 }
213 207
214 ddata->enable_gpio = gpio; 208 ddata->enable_gpio = gpio;
215 209
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-dpi.c b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c
index eb8fd8140ad0..f7be3489f744 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-dpi.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c
@@ -209,16 +209,9 @@ static int panel_dpi_probe_of(struct platform_device *pdev)
209 struct videomode vm; 209 struct videomode vm;
210 struct gpio_desc *gpio; 210 struct gpio_desc *gpio;
211 211
212 gpio = devm_gpiod_get(&pdev->dev, "enable"); 212 gpio = devm_gpiod_get_optional(&pdev->dev, "enable", GPIOD_OUT_LOW);
213 213 if (IS_ERR(gpio))
214 if (IS_ERR(gpio)) { 214 return PTR_ERR(gpio);
215 if (PTR_ERR(gpio) != -ENOENT)
216 return PTR_ERR(gpio);
217 else
218 gpio = NULL;
219 } else {
220 gpiod_direction_output(gpio, 0);
221 }
222 215
223 ddata->enable_gpio = gpio; 216 ddata->enable_gpio = gpio;
224 217
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
index 9974a37a11af..6a1b6a89a928 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
@@ -285,15 +285,14 @@ static int lb035q02_probe_of(struct spi_device *spi)
285 struct omap_dss_device *in; 285 struct omap_dss_device *in;
286 struct gpio_desc *gpio; 286 struct gpio_desc *gpio;
287 287
288 gpio = devm_gpiod_get(&spi->dev, "enable"); 288 gpio = devm_gpiod_get(&spi->dev, "enable", GPIOD_OUT_LOW);
289 if (IS_ERR(gpio)) { 289 if (IS_ERR(gpio)) {
290 dev_err(&spi->dev, "failed to parse enable gpio\n"); 290 dev_err(&spi->dev, "failed to parse enable gpio\n");
291 return PTR_ERR(gpio); 291 return PTR_ERR(gpio);
292 } else {
293 gpiod_direction_output(gpio, 0);
294 ddata->enable_gpio = gpio;
295 } 292 }
296 293
294 ddata->enable_gpio = gpio;
295
297 ddata->backlight_gpio = -ENOENT; 296 ddata->backlight_gpio = -ENOENT;
298 297
299 in = omapdss_of_find_source_for_first_ep(node); 298 in = omapdss_of_find_source_for_first_ep(node);
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
index eae263702964..abfd1f6e3327 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
@@ -268,17 +268,12 @@ static int sharp_ls_get_gpio_of(struct device *dev, int index, int val,
268 const char *desc, struct gpio_desc **gpiod) 268 const char *desc, struct gpio_desc **gpiod)
269{ 269{
270 struct gpio_desc *gd; 270 struct gpio_desc *gd;
271 int r;
272 271
273 *gpiod = NULL; 272 *gpiod = NULL;
274 273
275 gd = devm_gpiod_get_index(dev, desc, index); 274 gd = devm_gpiod_get_index(dev, desc, index, GPIOD_OUT_LOW);
276 if (IS_ERR(gd)) 275 if (IS_ERR(gd))
277 return PTR_ERR(gd) == -ENOENT ? 0 : PTR_ERR(gd); 276 return PTR_ERR(gd);
278
279 r = gpiod_direction_output(gd, val);
280 if (r)
281 return r;
282 277
283 *gpiod = gd; 278 *gpiod = gd;
284 return 0; 279 return 0;
diff --git a/drivers/video/fbdev/omap2/dss/core.c b/drivers/video/fbdev/omap2/dss/core.c
index 16751755d433..54eeb507f9b3 100644
--- a/drivers/video/fbdev/omap2/dss/core.c
+++ b/drivers/video/fbdev/omap2/dss/core.c
@@ -50,8 +50,6 @@ static char *def_disp_name;
50module_param_named(def_disp, def_disp_name, charp, 0); 50module_param_named(def_disp, def_disp_name, charp, 0);
51MODULE_PARM_DESC(def_disp, "default display name"); 51MODULE_PARM_DESC(def_disp, "default display name");
52 52
53static bool dss_initialized;
54
55const char *omapdss_get_default_display_name(void) 53const char *omapdss_get_default_display_name(void)
56{ 54{
57 return core.default_display_name; 55 return core.default_display_name;
@@ -65,12 +63,6 @@ enum omapdss_version omapdss_get_version(void)
65} 63}
66EXPORT_SYMBOL(omapdss_get_version); 64EXPORT_SYMBOL(omapdss_get_version);
67 65
68bool omapdss_is_initialized(void)
69{
70 return dss_initialized;
71}
72EXPORT_SYMBOL(omapdss_is_initialized);
73
74struct platform_device *dss_get_core_pdev(void) 66struct platform_device *dss_get_core_pdev(void)
75{ 67{
76 return core.pdev; 68 return core.pdev;
@@ -253,6 +245,8 @@ static struct platform_driver omap_dss_driver = {
253 245
254/* INIT */ 246/* INIT */
255static int (*dss_output_drv_reg_funcs[])(void) __initdata = { 247static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
248 dss_init_platform_driver,
249 dispc_init_platform_driver,
256#ifdef CONFIG_OMAP2_DSS_DSI 250#ifdef CONFIG_OMAP2_DSS_DSI
257 dsi_init_platform_driver, 251 dsi_init_platform_driver,
258#endif 252#endif
@@ -276,32 +270,32 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = {
276#endif 270#endif
277}; 271};
278 272
279static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = { 273static void (*dss_output_drv_unreg_funcs[])(void) = {
280#ifdef CONFIG_OMAP2_DSS_DSI 274#ifdef CONFIG_OMAP5_DSS_HDMI
281 dsi_uninit_platform_driver, 275 hdmi5_uninit_platform_driver,
282#endif 276#endif
283#ifdef CONFIG_OMAP2_DSS_DPI 277#ifdef CONFIG_OMAP4_DSS_HDMI
284 dpi_uninit_platform_driver, 278 hdmi4_uninit_platform_driver,
285#endif 279#endif
286#ifdef CONFIG_OMAP2_DSS_SDI 280#ifdef CONFIG_OMAP2_DSS_VENC
287 sdi_uninit_platform_driver, 281 venc_uninit_platform_driver,
288#endif 282#endif
289#ifdef CONFIG_OMAP2_DSS_RFBI 283#ifdef CONFIG_OMAP2_DSS_RFBI
290 rfbi_uninit_platform_driver, 284 rfbi_uninit_platform_driver,
291#endif 285#endif
292#ifdef CONFIG_OMAP2_DSS_VENC 286#ifdef CONFIG_OMAP2_DSS_SDI
293 venc_uninit_platform_driver, 287 sdi_uninit_platform_driver,
294#endif 288#endif
295#ifdef CONFIG_OMAP4_DSS_HDMI 289#ifdef CONFIG_OMAP2_DSS_DPI
296 hdmi4_uninit_platform_driver, 290 dpi_uninit_platform_driver,
297#endif 291#endif
298#ifdef CONFIG_OMAP5_DSS_HDMI 292#ifdef CONFIG_OMAP2_DSS_DSI
299 hdmi5_uninit_platform_driver, 293 dsi_uninit_platform_driver,
300#endif 294#endif
295 dispc_uninit_platform_driver,
296 dss_uninit_platform_driver,
301}; 297};
302 298
303static bool dss_output_drv_loaded[ARRAY_SIZE(dss_output_drv_reg_funcs)];
304
305static int __init omap_dss_init(void) 299static int __init omap_dss_init(void)
306{ 300{
307 int r; 301 int r;
@@ -311,35 +305,20 @@ static int __init omap_dss_init(void)
311 if (r) 305 if (r)
312 return r; 306 return r;
313 307
314 r = dss_init_platform_driver();
315 if (r) {
316 DSSERR("Failed to initialize DSS platform driver\n");
317 goto err_dss;
318 }
319
320 r = dispc_init_platform_driver();
321 if (r) {
322 DSSERR("Failed to initialize dispc platform driver\n");
323 goto err_dispc;
324 }
325
326 /*
327 * It's ok if the output-driver register fails. It happens, for example,
328 * when there is no output-device (e.g. SDI for OMAP4).
329 */
330 for (i = 0; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) { 308 for (i = 0; i < ARRAY_SIZE(dss_output_drv_reg_funcs); ++i) {
331 r = dss_output_drv_reg_funcs[i](); 309 r = dss_output_drv_reg_funcs[i]();
332 if (r == 0) 310 if (r)
333 dss_output_drv_loaded[i] = true; 311 goto err_reg;
334 } 312 }
335 313
336 dss_initialized = true;
337
338 return 0; 314 return 0;
339 315
340err_dispc: 316err_reg:
341 dss_uninit_platform_driver(); 317 for (i = ARRAY_SIZE(dss_output_drv_reg_funcs) - i;
342err_dss: 318 i < ARRAY_SIZE(dss_output_drv_reg_funcs);
319 ++i)
320 dss_output_drv_unreg_funcs[i]();
321
343 platform_driver_unregister(&omap_dss_driver); 322 platform_driver_unregister(&omap_dss_driver);
344 323
345 return r; 324 return r;
@@ -349,13 +328,8 @@ static void __exit omap_dss_exit(void)
349{ 328{
350 int i; 329 int i;
351 330
352 for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i) { 331 for (i = 0; i < ARRAY_SIZE(dss_output_drv_unreg_funcs); ++i)
353 if (dss_output_drv_loaded[i]) 332 dss_output_drv_unreg_funcs[i]();
354 dss_output_drv_unreg_funcs[i]();
355 }
356
357 dispc_uninit_platform_driver();
358 dss_uninit_platform_driver();
359 333
360 platform_driver_unregister(&omap_dss_driver); 334 platform_driver_unregister(&omap_dss_driver);
361} 335}
diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index f4fc77d9d3bf..be716c9ffb88 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -39,6 +39,7 @@
39#include <linux/mfd/syscon.h> 39#include <linux/mfd/syscon.h>
40#include <linux/regmap.h> 40#include <linux/regmap.h>
41#include <linux/of.h> 41#include <linux/of.h>
42#include <linux/component.h>
42 43
43#include <video/omapdss.h> 44#include <video/omapdss.h>
44 45
@@ -95,6 +96,9 @@ struct dispc_features {
95 bool mstandby_workaround:1; 96 bool mstandby_workaround:1;
96 97
97 bool set_max_preload:1; 98 bool set_max_preload:1;
99
100 /* PIXEL_INC is not added to the last pixel of a line */
101 bool last_pixel_inc_missing:1;
98}; 102};
99 103
100#define DISPC_MAX_NR_FIFOS 5 104#define DISPC_MAX_NR_FIFOS 5
@@ -1741,6 +1745,15 @@ static void dispc_ovl_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1741 row_repeat = false; 1745 row_repeat = false;
1742 } 1746 }
1743 1747
1748 /*
1749 * OMAP4/5 Errata i631:
1750 * NV12 in 1D mode must use ROTATION=1. Otherwise DSS will fetch extra
1751 * rows beyond the framebuffer, which may cause OCP error.
1752 */
1753 if (color_mode == OMAP_DSS_COLOR_NV12 &&
1754 rotation_type != OMAP_DSS_ROT_TILER)
1755 vidrot = 1;
1756
1744 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), vidrot, 13, 12); 1757 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), vidrot, 13, 12);
1745 if (dss_has_feature(FEAT_ROWREPEATENABLE)) 1758 if (dss_has_feature(FEAT_ROWREPEATENABLE))
1746 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 1759 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane),
@@ -2154,7 +2167,7 @@ static unsigned long calc_core_clk_five_taps(unsigned long pclk,
2154 if (height > out_height) { 2167 if (height > out_height) {
2155 unsigned int ppl = mgr_timings->x_res; 2168 unsigned int ppl = mgr_timings->x_res;
2156 2169
2157 tmp = pclk * height * out_width; 2170 tmp = (u64)pclk * height * out_width;
2158 do_div(tmp, 2 * out_height * ppl); 2171 do_div(tmp, 2 * out_height * ppl);
2159 core_clk = tmp; 2172 core_clk = tmp;
2160 2173
@@ -2162,14 +2175,14 @@ static unsigned long calc_core_clk_five_taps(unsigned long pclk,
2162 if (ppl == out_width) 2175 if (ppl == out_width)
2163 return 0; 2176 return 0;
2164 2177
2165 tmp = pclk * (height - 2 * out_height) * out_width; 2178 tmp = (u64)pclk * (height - 2 * out_height) * out_width;
2166 do_div(tmp, 2 * out_height * (ppl - out_width)); 2179 do_div(tmp, 2 * out_height * (ppl - out_width));
2167 core_clk = max_t(u32, core_clk, tmp); 2180 core_clk = max_t(u32, core_clk, tmp);
2168 } 2181 }
2169 } 2182 }
2170 2183
2171 if (width > out_width) { 2184 if (width > out_width) {
2172 tmp = pclk * width; 2185 tmp = (u64)pclk * width;
2173 do_div(tmp, out_width); 2186 do_div(tmp, out_width);
2174 core_clk = max_t(u32, core_clk, tmp); 2187 core_clk = max_t(u32, core_clk, tmp);
2175 2188
@@ -2267,6 +2280,11 @@ static int dispc_ovl_calc_scaling_24xx(unsigned long pclk, unsigned long lclk,
2267 } 2280 }
2268 } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error); 2281 } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
2269 2282
2283 if (error) {
2284 DSSERR("failed to find scaling settings\n");
2285 return -EINVAL;
2286 }
2287
2270 if (in_width > maxsinglelinewidth) { 2288 if (in_width > maxsinglelinewidth) {
2271 DSSERR("Cannot scale max input width exceeded"); 2289 DSSERR("Cannot scale max input width exceeded");
2272 return -EINVAL; 2290 return -EINVAL;
@@ -2283,7 +2301,6 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,
2283{ 2301{
2284 int error; 2302 int error;
2285 u16 in_width, in_height; 2303 u16 in_width, in_height;
2286 int min_factor = min(*decim_x, *decim_y);
2287 const int maxsinglelinewidth = 2304 const int maxsinglelinewidth =
2288 dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH); 2305 dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
2289 2306
@@ -2317,20 +2334,32 @@ again:
2317 error = (error || in_width > maxsinglelinewidth * 2 || 2334 error = (error || in_width > maxsinglelinewidth * 2 ||
2318 (in_width > maxsinglelinewidth && *five_taps) || 2335 (in_width > maxsinglelinewidth && *five_taps) ||
2319 !*core_clk || *core_clk > dispc_core_clk_rate()); 2336 !*core_clk || *core_clk > dispc_core_clk_rate());
2320 if (error) { 2337
2321 if (*decim_x == *decim_y) { 2338 if (!error) {
2322 *decim_x = min_factor; 2339 /* verify that we're inside the limits of scaler */
2323 ++*decim_y; 2340 if (in_width / 4 > out_width)
2341 error = 1;
2342
2343 if (*five_taps) {
2344 if (in_height / 4 > out_height)
2345 error = 1;
2324 } else { 2346 } else {
2325 swap(*decim_x, *decim_y); 2347 if (in_height / 2 > out_height)
2326 if (*decim_x < *decim_y) 2348 error = 1;
2327 ++*decim_x;
2328 } 2349 }
2329 } 2350 }
2351
2352 if (error)
2353 ++*decim_y;
2330 } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error); 2354 } while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);
2331 2355
2332 if (check_horiz_timing_omap3(pclk, lclk, mgr_timings, pos_x, width, 2356 if (error) {
2333 height, out_width, out_height, *five_taps)) { 2357 DSSERR("failed to find scaling settings\n");
2358 return -EINVAL;
2359 }
2360
2361 if (check_horiz_timing_omap3(pclk, lclk, mgr_timings, pos_x, in_width,
2362 in_height, out_width, out_height, *five_taps)) {
2334 DSSERR("horizontal timing too tight\n"); 2363 DSSERR("horizontal timing too tight\n");
2335 return -EINVAL; 2364 return -EINVAL;
2336 } 2365 }
@@ -2390,6 +2419,9 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk,
2390 return 0; 2419 return 0;
2391} 2420}
2392 2421
2422#define DIV_FRAC(dividend, divisor) \
2423 ((dividend) * 100 / (divisor) - ((dividend) / (divisor) * 100))
2424
2393static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk, 2425static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
2394 enum omap_overlay_caps caps, 2426 enum omap_overlay_caps caps,
2395 const struct omap_video_timings *mgr_timings, 2427 const struct omap_video_timings *mgr_timings,
@@ -2449,8 +2481,19 @@ static int dispc_ovl_calc_scaling(unsigned long pclk, unsigned long lclk,
2449 if (ret) 2481 if (ret)
2450 return ret; 2482 return ret;
2451 2483
2452 DSSDBG("required core clk rate = %lu Hz\n", core_clk); 2484 DSSDBG("%dx%d -> %dx%d (%d.%02d x %d.%02d), decim %dx%d %dx%d (%d.%02d x %d.%02d), taps %d, req clk %lu, cur clk %lu\n",
2453 DSSDBG("current core clk rate = %lu Hz\n", dispc_core_clk_rate()); 2485 width, height,
2486 out_width, out_height,
2487 out_width / width, DIV_FRAC(out_width, width),
2488 out_height / height, DIV_FRAC(out_height, height),
2489
2490 decim_x, decim_y,
2491 width / decim_x, height / decim_y,
2492 out_width / (width / decim_x), DIV_FRAC(out_width, width / decim_x),
2493 out_height / (height / decim_y), DIV_FRAC(out_height, height / decim_y),
2494
2495 *five_taps ? 5 : 3,
2496 core_clk, dispc_core_clk_rate());
2454 2497
2455 if (!core_clk || core_clk > dispc_core_clk_rate()) { 2498 if (!core_clk || core_clk > dispc_core_clk_rate()) {
2456 DSSERR("failed to set up scaling, " 2499 DSSERR("failed to set up scaling, "
@@ -2533,6 +2576,21 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
2533 if (paddr == 0 && rotation_type != OMAP_DSS_ROT_TILER) 2576 if (paddr == 0 && rotation_type != OMAP_DSS_ROT_TILER)
2534 return -EINVAL; 2577 return -EINVAL;
2535 2578
2579 switch (color_mode) {
2580 case OMAP_DSS_COLOR_YUV2:
2581 case OMAP_DSS_COLOR_UYVY:
2582 case OMAP_DSS_COLOR_NV12:
2583 if (in_width & 1) {
2584 DSSERR("input width %d is not even for YUV format\n",
2585 in_width);
2586 return -EINVAL;
2587 }
2588 break;
2589
2590 default:
2591 break;
2592 }
2593
2536 out_width = out_width == 0 ? width : out_width; 2594 out_width = out_width == 0 ? width : out_width;
2537 out_height = out_height == 0 ? height : out_height; 2595 out_height = out_height == 0 ? height : out_height;
2538 2596
@@ -2563,6 +2621,27 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
2563 in_width = in_width / x_predecim; 2621 in_width = in_width / x_predecim;
2564 in_height = in_height / y_predecim; 2622 in_height = in_height / y_predecim;
2565 2623
2624 if (x_predecim > 1 || y_predecim > 1)
2625 DSSDBG("predecimation %d x %x, new input size %d x %d\n",
2626 x_predecim, y_predecim, in_width, in_height);
2627
2628 switch (color_mode) {
2629 case OMAP_DSS_COLOR_YUV2:
2630 case OMAP_DSS_COLOR_UYVY:
2631 case OMAP_DSS_COLOR_NV12:
2632 if (in_width & 1) {
2633 DSSDBG("predecimated input width is not even for YUV format\n");
2634 DSSDBG("adjusting input width %d -> %d\n",
2635 in_width, in_width & ~1);
2636
2637 in_width &= ~1;
2638 }
2639 break;
2640
2641 default:
2642 break;
2643 }
2644
2566 if (color_mode == OMAP_DSS_COLOR_YUV2 || 2645 if (color_mode == OMAP_DSS_COLOR_YUV2 ||
2567 color_mode == OMAP_DSS_COLOR_UYVY || 2646 color_mode == OMAP_DSS_COLOR_UYVY ||
2568 color_mode == OMAP_DSS_COLOR_NV12) 2647 color_mode == OMAP_DSS_COLOR_NV12)
@@ -2632,6 +2711,9 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
2632 dispc_ovl_set_ba1_uv(plane, p_uv_addr + offset1); 2711 dispc_ovl_set_ba1_uv(plane, p_uv_addr + offset1);
2633 } 2712 }
2634 2713
2714 if (dispc.feat->last_pixel_inc_missing)
2715 row_inc += pix_inc - 1;
2716
2635 dispc_ovl_set_row_inc(plane, row_inc); 2717 dispc_ovl_set_row_inc(plane, row_inc);
2636 dispc_ovl_set_pix_inc(plane, pix_inc); 2718 dispc_ovl_set_pix_inc(plane, pix_inc);
2637 2719
@@ -3692,7 +3774,7 @@ static void _omap_dispc_initial_config(void)
3692 dispc_init_mflag(); 3774 dispc_init_mflag();
3693} 3775}
3694 3776
3695static const struct dispc_features omap24xx_dispc_feats __initconst = { 3777static const struct dispc_features omap24xx_dispc_feats = {
3696 .sw_start = 5, 3778 .sw_start = 5,
3697 .fp_start = 15, 3779 .fp_start = 15,
3698 .bp_start = 27, 3780 .bp_start = 27,
@@ -3709,9 +3791,10 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
3709 .num_fifos = 3, 3791 .num_fifos = 3,
3710 .no_framedone_tv = true, 3792 .no_framedone_tv = true,
3711 .set_max_preload = false, 3793 .set_max_preload = false,
3794 .last_pixel_inc_missing = true,
3712}; 3795};
3713 3796
3714static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = { 3797static const struct dispc_features omap34xx_rev1_0_dispc_feats = {
3715 .sw_start = 5, 3798 .sw_start = 5,
3716 .fp_start = 15, 3799 .fp_start = 15,
3717 .bp_start = 27, 3800 .bp_start = 27,
@@ -3729,9 +3812,10 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
3729 .num_fifos = 3, 3812 .num_fifos = 3,
3730 .no_framedone_tv = true, 3813 .no_framedone_tv = true,
3731 .set_max_preload = false, 3814 .set_max_preload = false,
3815 .last_pixel_inc_missing = true,
3732}; 3816};
3733 3817
3734static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = { 3818static const struct dispc_features omap34xx_rev3_0_dispc_feats = {
3735 .sw_start = 7, 3819 .sw_start = 7,
3736 .fp_start = 19, 3820 .fp_start = 19,
3737 .bp_start = 31, 3821 .bp_start = 31,
@@ -3749,9 +3833,10 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
3749 .num_fifos = 3, 3833 .num_fifos = 3,
3750 .no_framedone_tv = true, 3834 .no_framedone_tv = true,
3751 .set_max_preload = false, 3835 .set_max_preload = false,
3836 .last_pixel_inc_missing = true,
3752}; 3837};
3753 3838
3754static const struct dispc_features omap44xx_dispc_feats __initconst = { 3839static const struct dispc_features omap44xx_dispc_feats = {
3755 .sw_start = 7, 3840 .sw_start = 7,
3756 .fp_start = 19, 3841 .fp_start = 19,
3757 .bp_start = 31, 3842 .bp_start = 31,
@@ -3771,7 +3856,7 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
3771 .set_max_preload = true, 3856 .set_max_preload = true,
3772}; 3857};
3773 3858
3774static const struct dispc_features omap54xx_dispc_feats __initconst = { 3859static const struct dispc_features omap54xx_dispc_feats = {
3775 .sw_start = 7, 3860 .sw_start = 7,
3776 .fp_start = 19, 3861 .fp_start = 19,
3777 .bp_start = 31, 3862 .bp_start = 31,
@@ -3792,7 +3877,7 @@ static const struct dispc_features omap54xx_dispc_feats __initconst = {
3792 .set_max_preload = true, 3877 .set_max_preload = true,
3793}; 3878};
3794 3879
3795static int __init dispc_init_features(struct platform_device *pdev) 3880static int dispc_init_features(struct platform_device *pdev)
3796{ 3881{
3797 const struct dispc_features *src; 3882 const struct dispc_features *src;
3798 struct dispc_features *dst; 3883 struct dispc_features *dst;
@@ -3882,8 +3967,9 @@ void dispc_free_irq(void *dev_id)
3882EXPORT_SYMBOL(dispc_free_irq); 3967EXPORT_SYMBOL(dispc_free_irq);
3883 3968
3884/* DISPC HW IP initialisation */ 3969/* DISPC HW IP initialisation */
3885static int __init omap_dispchw_probe(struct platform_device *pdev) 3970static int dispc_bind(struct device *dev, struct device *master, void *data)
3886{ 3971{
3972 struct platform_device *pdev = to_platform_device(dev);
3887 u32 rev; 3973 u32 rev;
3888 int r = 0; 3974 int r = 0;
3889 struct resource *dispc_mem; 3975 struct resource *dispc_mem;
@@ -3955,12 +4041,27 @@ err_runtime_get:
3955 return r; 4041 return r;
3956} 4042}
3957 4043
3958static int __exit omap_dispchw_remove(struct platform_device *pdev) 4044static void dispc_unbind(struct device *dev, struct device *master,
4045 void *data)
3959{ 4046{
3960 pm_runtime_disable(&pdev->dev); 4047 pm_runtime_disable(dev);
3961 4048
3962 dss_uninit_overlay_managers(); 4049 dss_uninit_overlay_managers();
4050}
4051
4052static const struct component_ops dispc_component_ops = {
4053 .bind = dispc_bind,
4054 .unbind = dispc_unbind,
4055};
3963 4056
4057static int dispc_probe(struct platform_device *pdev)
4058{
4059 return component_add(&pdev->dev, &dispc_component_ops);
4060}
4061
4062static int dispc_remove(struct platform_device *pdev)
4063{
4064 component_del(&pdev->dev, &dispc_component_ops);
3964 return 0; 4065 return 0;
3965} 4066}
3966 4067
@@ -4013,7 +4114,8 @@ static const struct of_device_id dispc_of_match[] = {
4013}; 4114};
4014 4115
4015static struct platform_driver omap_dispchw_driver = { 4116static struct platform_driver omap_dispchw_driver = {
4016 .remove = __exit_p(omap_dispchw_remove), 4117 .probe = dispc_probe,
4118 .remove = dispc_remove,
4017 .driver = { 4119 .driver = {
4018 .name = "omapdss_dispc", 4120 .name = "omapdss_dispc",
4019 .pm = &dispc_pm_ops, 4121 .pm = &dispc_pm_ops,
@@ -4024,10 +4126,10 @@ static struct platform_driver omap_dispchw_driver = {
4024 4126
4025int __init dispc_init_platform_driver(void) 4127int __init dispc_init_platform_driver(void)
4026{ 4128{
4027 return platform_driver_probe(&omap_dispchw_driver, omap_dispchw_probe); 4129 return platform_driver_register(&omap_dispchw_driver);
4028} 4130}
4029 4131
4030void __exit dispc_uninit_platform_driver(void) 4132void dispc_uninit_platform_driver(void)
4031{ 4133{
4032 platform_driver_unregister(&omap_dispchw_driver); 4134 platform_driver_unregister(&omap_dispchw_driver);
4033} 4135}
diff --git a/drivers/video/fbdev/omap2/dss/display-sysfs.c b/drivers/video/fbdev/omap2/dss/display-sysfs.c
index 12186557a9d4..6ad0991f8259 100644
--- a/drivers/video/fbdev/omap2/dss/display-sysfs.c
+++ b/drivers/video/fbdev/omap2/dss/display-sysfs.c
@@ -324,7 +324,7 @@ int display_init_sysfs(struct platform_device *pdev)
324 324
325 for_each_dss_dev(dssdev) { 325 for_each_dss_dev(dssdev) {
326 r = kobject_init_and_add(&dssdev->kobj, &display_ktype, 326 r = kobject_init_and_add(&dssdev->kobj, &display_ktype,
327 &pdev->dev.kobj, dssdev->alias); 327 &pdev->dev.kobj, "%s", dssdev->alias);
328 if (r) { 328 if (r) {
329 DSSERR("failed to create sysfs files\n"); 329 DSSERR("failed to create sysfs files\n");
330 omap_dss_put_device(dssdev); 330 omap_dss_put_device(dssdev);
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index f83e7b030249..fb45b6432968 100644
--- a/drivers/video/fbdev/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
@@ -32,6 +32,7 @@
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#include <linux/clk.h>
35#include <linux/component.h>
35 36
36#include <video/omapdss.h> 37#include <video/omapdss.h>
37 38
@@ -731,7 +732,7 @@ static void dpi_init_output(struct platform_device *pdev)
731 omapdss_register_output(out); 732 omapdss_register_output(out);
732} 733}
733 734
734static void __exit dpi_uninit_output(struct platform_device *pdev) 735static void dpi_uninit_output(struct platform_device *pdev)
735{ 736{
736 struct dpi_data *dpi = dpi_get_data_from_pdev(pdev); 737 struct dpi_data *dpi = dpi_get_data_from_pdev(pdev);
737 struct omap_dss_device *out = &dpi->output; 738 struct omap_dss_device *out = &dpi->output;
@@ -775,7 +776,7 @@ static void dpi_init_output_port(struct platform_device *pdev,
775 omapdss_register_output(out); 776 omapdss_register_output(out);
776} 777}
777 778
778static void __exit dpi_uninit_output_port(struct device_node *port) 779static void dpi_uninit_output_port(struct device_node *port)
779{ 780{
780 struct dpi_data *dpi = port->data; 781 struct dpi_data *dpi = port->data;
781 struct omap_dss_device *out = &dpi->output; 782 struct omap_dss_device *out = &dpi->output;
@@ -783,8 +784,9 @@ static void __exit dpi_uninit_output_port(struct device_node *port)
783 omapdss_unregister_output(out); 784 omapdss_unregister_output(out);
784} 785}
785 786
786static int omap_dpi_probe(struct platform_device *pdev) 787static int dpi_bind(struct device *dev, struct device *master, void *data)
787{ 788{
789 struct platform_device *pdev = to_platform_device(dev);
788 struct dpi_data *dpi; 790 struct dpi_data *dpi;
789 791
790 dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL); 792 dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL);
@@ -802,16 +804,32 @@ static int omap_dpi_probe(struct platform_device *pdev)
802 return 0; 804 return 0;
803} 805}
804 806
805static int __exit omap_dpi_remove(struct platform_device *pdev) 807static void dpi_unbind(struct device *dev, struct device *master, void *data)
806{ 808{
809 struct platform_device *pdev = to_platform_device(dev);
810
807 dpi_uninit_output(pdev); 811 dpi_uninit_output(pdev);
812}
813
814static const struct component_ops dpi_component_ops = {
815 .bind = dpi_bind,
816 .unbind = dpi_unbind,
817};
808 818
819static int dpi_probe(struct platform_device *pdev)
820{
821 return component_add(&pdev->dev, &dpi_component_ops);
822}
823
824static int dpi_remove(struct platform_device *pdev)
825{
826 component_del(&pdev->dev, &dpi_component_ops);
809 return 0; 827 return 0;
810} 828}
811 829
812static struct platform_driver omap_dpi_driver = { 830static struct platform_driver omap_dpi_driver = {
813 .probe = omap_dpi_probe, 831 .probe = dpi_probe,
814 .remove = __exit_p(omap_dpi_remove), 832 .remove = dpi_remove,
815 .driver = { 833 .driver = {
816 .name = "omapdss_dpi", 834 .name = "omapdss_dpi",
817 .suppress_bind_attrs = true, 835 .suppress_bind_attrs = true,
@@ -823,12 +841,12 @@ int __init dpi_init_platform_driver(void)
823 return platform_driver_register(&omap_dpi_driver); 841 return platform_driver_register(&omap_dpi_driver);
824} 842}
825 843
826void __exit dpi_uninit_platform_driver(void) 844void dpi_uninit_platform_driver(void)
827{ 845{
828 platform_driver_unregister(&omap_dpi_driver); 846 platform_driver_unregister(&omap_dpi_driver);
829} 847}
830 848
831int __init dpi_init_port(struct platform_device *pdev, struct device_node *port) 849int dpi_init_port(struct platform_device *pdev, struct device_node *port)
832{ 850{
833 struct dpi_data *dpi; 851 struct dpi_data *dpi;
834 struct device_node *ep; 852 struct device_node *ep;
@@ -870,7 +888,7 @@ err_datalines:
870 return r; 888 return r;
871} 889}
872 890
873void __exit dpi_uninit_port(struct device_node *port) 891void dpi_uninit_port(struct device_node *port)
874{ 892{
875 struct dpi_data *dpi = port->data; 893 struct dpi_data *dpi = port->data;
876 894
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index 28b0bc11669d..b3606def5b7b 100644
--- a/drivers/video/fbdev/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -40,6 +40,7 @@
40#include <linux/pm_runtime.h> 40#include <linux/pm_runtime.h>
41#include <linux/of.h> 41#include <linux/of.h>
42#include <linux/of_platform.h> 42#include <linux/of_platform.h>
43#include <linux/component.h>
43 44
44#include <video/omapdss.h> 45#include <video/omapdss.h>
45#include <video/mipi_display.h> 46#include <video/mipi_display.h>
@@ -5274,8 +5275,9 @@ static int dsi_init_pll_data(struct platform_device *dsidev)
5274} 5275}
5275 5276
5276/* DSI1 HW IP initialisation */ 5277/* DSI1 HW IP initialisation */
5277static int omap_dsihw_probe(struct platform_device *dsidev) 5278static int dsi_bind(struct device *dev, struct device *master, void *data)
5278{ 5279{
5280 struct platform_device *dsidev = to_platform_device(dev);
5279 u32 rev; 5281 u32 rev;
5280 int r, i; 5282 int r, i;
5281 struct dsi_data *dsi; 5283 struct dsi_data *dsi;
@@ -5484,8 +5486,9 @@ err_runtime_get:
5484 return r; 5486 return r;
5485} 5487}
5486 5488
5487static int __exit omap_dsihw_remove(struct platform_device *dsidev) 5489static void dsi_unbind(struct device *dev, struct device *master, void *data)
5488{ 5490{
5491 struct platform_device *dsidev = to_platform_device(dev);
5489 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 5492 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
5490 5493
5491 of_platform_depopulate(&dsidev->dev); 5494 of_platform_depopulate(&dsidev->dev);
@@ -5502,7 +5505,21 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
5502 regulator_disable(dsi->vdds_dsi_reg); 5505 regulator_disable(dsi->vdds_dsi_reg);
5503 dsi->vdds_dsi_enabled = false; 5506 dsi->vdds_dsi_enabled = false;
5504 } 5507 }
5508}
5509
5510static const struct component_ops dsi_component_ops = {
5511 .bind = dsi_bind,
5512 .unbind = dsi_unbind,
5513};
5505 5514
5515static int dsi_probe(struct platform_device *pdev)
5516{
5517 return component_add(&pdev->dev, &dsi_component_ops);
5518}
5519
5520static int dsi_remove(struct platform_device *pdev)
5521{
5522 component_del(&pdev->dev, &dsi_component_ops);
5506 return 0; 5523 return 0;
5507} 5524}
5508 5525
@@ -5569,8 +5586,8 @@ static const struct of_device_id dsi_of_match[] = {
5569}; 5586};
5570 5587
5571static struct platform_driver omap_dsihw_driver = { 5588static struct platform_driver omap_dsihw_driver = {
5572 .probe = omap_dsihw_probe, 5589 .probe = dsi_probe,
5573 .remove = __exit_p(omap_dsihw_remove), 5590 .remove = dsi_remove,
5574 .driver = { 5591 .driver = {
5575 .name = "omapdss_dsi", 5592 .name = "omapdss_dsi",
5576 .pm = &dsi_pm_ops, 5593 .pm = &dsi_pm_ops,
@@ -5584,7 +5601,7 @@ int __init dsi_init_platform_driver(void)
5584 return platform_driver_register(&omap_dsihw_driver); 5601 return platform_driver_register(&omap_dsihw_driver);
5585} 5602}
5586 5603
5587void __exit dsi_uninit_platform_driver(void) 5604void dsi_uninit_platform_driver(void)
5588{ 5605{
5589 platform_driver_unregister(&omap_dsihw_driver); 5606 platform_driver_unregister(&omap_dsihw_driver);
5590} 5607}
diff --git a/drivers/video/fbdev/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
index 7f978b6a34e8..9200a8668b49 100644
--- a/drivers/video/fbdev/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -39,6 +39,7 @@
39#include <linux/of.h> 39#include <linux/of.h>
40#include <linux/regulator/consumer.h> 40#include <linux/regulator/consumer.h>
41#include <linux/suspend.h> 41#include <linux/suspend.h>
42#include <linux/component.h>
42 43
43#include <video/omapdss.h> 44#include <video/omapdss.h>
44 45
@@ -111,6 +112,14 @@ static const char * const dss_generic_clk_source_names[] = {
111 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DSI_PLL2_HSDIV_DSI", 112 [OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI] = "DSI_PLL2_HSDIV_DSI",
112}; 113};
113 114
115static bool dss_initialized;
116
117bool omapdss_is_initialized(void)
118{
119 return dss_initialized;
120}
121EXPORT_SYMBOL(omapdss_is_initialized);
122
114static inline void dss_write_reg(const struct dss_reg idx, u32 val) 123static inline void dss_write_reg(const struct dss_reg idx, u32 val)
115{ 124{
116 __raw_writel(val, dss.base + idx.idx); 125 __raw_writel(val, dss.base + idx.idx);
@@ -811,7 +820,7 @@ static const enum omap_display_type dra7xx_ports[] = {
811 OMAP_DISPLAY_TYPE_DPI, 820 OMAP_DISPLAY_TYPE_DPI,
812}; 821};
813 822
814static const struct dss_features omap24xx_dss_feats __initconst = { 823static const struct dss_features omap24xx_dss_feats = {
815 /* 824 /*
816 * fck div max is really 16, but the divider range has gaps. The range 825 * fck div max is really 16, but the divider range has gaps. The range
817 * from 1 to 6 has no gaps, so let's use that as a max. 826 * from 1 to 6 has no gaps, so let's use that as a max.
@@ -824,7 +833,7 @@ static const struct dss_features omap24xx_dss_feats __initconst = {
824 .num_ports = ARRAY_SIZE(omap2plus_ports), 833 .num_ports = ARRAY_SIZE(omap2plus_ports),
825}; 834};
826 835
827static const struct dss_features omap34xx_dss_feats __initconst = { 836static const struct dss_features omap34xx_dss_feats = {
828 .fck_div_max = 16, 837 .fck_div_max = 16,
829 .dss_fck_multiplier = 2, 838 .dss_fck_multiplier = 2,
830 .parent_clk_name = "dpll4_ck", 839 .parent_clk_name = "dpll4_ck",
@@ -833,7 +842,7 @@ static const struct dss_features omap34xx_dss_feats __initconst = {
833 .num_ports = ARRAY_SIZE(omap34xx_ports), 842 .num_ports = ARRAY_SIZE(omap34xx_ports),
834}; 843};
835 844
836static const struct dss_features omap3630_dss_feats __initconst = { 845static const struct dss_features omap3630_dss_feats = {
837 .fck_div_max = 32, 846 .fck_div_max = 32,
838 .dss_fck_multiplier = 1, 847 .dss_fck_multiplier = 1,
839 .parent_clk_name = "dpll4_ck", 848 .parent_clk_name = "dpll4_ck",
@@ -842,7 +851,7 @@ static const struct dss_features omap3630_dss_feats __initconst = {
842 .num_ports = ARRAY_SIZE(omap2plus_ports), 851 .num_ports = ARRAY_SIZE(omap2plus_ports),
843}; 852};
844 853
845static const struct dss_features omap44xx_dss_feats __initconst = { 854static const struct dss_features omap44xx_dss_feats = {
846 .fck_div_max = 32, 855 .fck_div_max = 32,
847 .dss_fck_multiplier = 1, 856 .dss_fck_multiplier = 1,
848 .parent_clk_name = "dpll_per_x2_ck", 857 .parent_clk_name = "dpll_per_x2_ck",
@@ -851,7 +860,7 @@ static const struct dss_features omap44xx_dss_feats __initconst = {
851 .num_ports = ARRAY_SIZE(omap2plus_ports), 860 .num_ports = ARRAY_SIZE(omap2plus_ports),
852}; 861};
853 862
854static const struct dss_features omap54xx_dss_feats __initconst = { 863static const struct dss_features omap54xx_dss_feats = {
855 .fck_div_max = 64, 864 .fck_div_max = 64,
856 .dss_fck_multiplier = 1, 865 .dss_fck_multiplier = 1,
857 .parent_clk_name = "dpll_per_x2_ck", 866 .parent_clk_name = "dpll_per_x2_ck",
@@ -860,7 +869,7 @@ static const struct dss_features omap54xx_dss_feats __initconst = {
860 .num_ports = ARRAY_SIZE(omap2plus_ports), 869 .num_ports = ARRAY_SIZE(omap2plus_ports),
861}; 870};
862 871
863static const struct dss_features am43xx_dss_feats __initconst = { 872static const struct dss_features am43xx_dss_feats = {
864 .fck_div_max = 0, 873 .fck_div_max = 0,
865 .dss_fck_multiplier = 0, 874 .dss_fck_multiplier = 0,
866 .parent_clk_name = NULL, 875 .parent_clk_name = NULL,
@@ -869,7 +878,7 @@ static const struct dss_features am43xx_dss_feats __initconst = {
869 .num_ports = ARRAY_SIZE(omap2plus_ports), 878 .num_ports = ARRAY_SIZE(omap2plus_ports),
870}; 879};
871 880
872static const struct dss_features dra7xx_dss_feats __initconst = { 881static const struct dss_features dra7xx_dss_feats = {
873 .fck_div_max = 64, 882 .fck_div_max = 64,
874 .dss_fck_multiplier = 1, 883 .dss_fck_multiplier = 1,
875 .parent_clk_name = "dpll_per_x2_ck", 884 .parent_clk_name = "dpll_per_x2_ck",
@@ -878,7 +887,7 @@ static const struct dss_features dra7xx_dss_feats __initconst = {
878 .num_ports = ARRAY_SIZE(dra7xx_ports), 887 .num_ports = ARRAY_SIZE(dra7xx_ports),
879}; 888};
880 889
881static int __init dss_init_features(struct platform_device *pdev) 890static int dss_init_features(struct platform_device *pdev)
882{ 891{
883 const struct dss_features *src; 892 const struct dss_features *src;
884 struct dss_features *dst; 893 struct dss_features *dst;
@@ -932,7 +941,7 @@ static int __init dss_init_features(struct platform_device *pdev)
932 return 0; 941 return 0;
933} 942}
934 943
935static int __init dss_init_ports(struct platform_device *pdev) 944static int dss_init_ports(struct platform_device *pdev)
936{ 945{
937 struct device_node *parent = pdev->dev.of_node; 946 struct device_node *parent = pdev->dev.of_node;
938 struct device_node *port; 947 struct device_node *port;
@@ -976,7 +985,7 @@ static int __init dss_init_ports(struct platform_device *pdev)
976 return 0; 985 return 0;
977} 986}
978 987
979static void __exit dss_uninit_ports(struct platform_device *pdev) 988static void dss_uninit_ports(struct platform_device *pdev)
980{ 989{
981 struct device_node *parent = pdev->dev.of_node; 990 struct device_node *parent = pdev->dev.of_node;
982 struct device_node *port; 991 struct device_node *port;
@@ -1018,14 +1027,74 @@ static void __exit dss_uninit_ports(struct platform_device *pdev)
1018 } while ((port = omapdss_of_get_next_port(parent, port)) != NULL); 1027 } while ((port = omapdss_of_get_next_port(parent, port)) != NULL);
1019} 1028}
1020 1029
1030static int dss_video_pll_probe(struct platform_device *pdev)
1031{
1032 struct device_node *np = pdev->dev.of_node;
1033 struct regulator *pll_regulator;
1034 int r;
1035
1036 if (!np)
1037 return 0;
1038
1039 if (of_property_read_bool(np, "syscon-pll-ctrl")) {
1040 dss.syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np,
1041 "syscon-pll-ctrl");
1042 if (IS_ERR(dss.syscon_pll_ctrl)) {
1043 dev_err(&pdev->dev,
1044 "failed to get syscon-pll-ctrl regmap\n");
1045 return PTR_ERR(dss.syscon_pll_ctrl);
1046 }
1047
1048 if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1,
1049 &dss.syscon_pll_ctrl_offset)) {
1050 dev_err(&pdev->dev,
1051 "failed to get syscon-pll-ctrl offset\n");
1052 return -EINVAL;
1053 }
1054 }
1055
1056 pll_regulator = devm_regulator_get(&pdev->dev, "vdda_video");
1057 if (IS_ERR(pll_regulator)) {
1058 r = PTR_ERR(pll_regulator);
1059
1060 switch (r) {
1061 case -ENOENT:
1062 pll_regulator = NULL;
1063 break;
1064
1065 case -EPROBE_DEFER:
1066 return -EPROBE_DEFER;
1067
1068 default:
1069 DSSERR("can't get DPLL VDDA regulator\n");
1070 return r;
1071 }
1072 }
1073
1074 if (of_property_match_string(np, "reg-names", "pll1") >= 0) {
1075 dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator);
1076 if (IS_ERR(dss.video1_pll))
1077 return PTR_ERR(dss.video1_pll);
1078 }
1079
1080 if (of_property_match_string(np, "reg-names", "pll2") >= 0) {
1081 dss.video2_pll = dss_video_pll_init(pdev, 1, pll_regulator);
1082 if (IS_ERR(dss.video2_pll)) {
1083 dss_video_pll_uninit(dss.video1_pll);
1084 return PTR_ERR(dss.video2_pll);
1085 }
1086 }
1087
1088 return 0;
1089}
1090
1021/* DSS HW IP initialisation */ 1091/* DSS HW IP initialisation */
1022static int __init omap_dsshw_probe(struct platform_device *pdev) 1092static int dss_bind(struct device *dev)
1023{ 1093{
1094 struct platform_device *pdev = to_platform_device(dev);
1024 struct resource *dss_mem; 1095 struct resource *dss_mem;
1025 struct device_node *np = pdev->dev.of_node;
1026 u32 rev; 1096 u32 rev;
1027 int r; 1097 int r;
1028 struct regulator *pll_regulator;
1029 1098
1030 dss.pdev = pdev; 1099 dss.pdev = pdev;
1031 1100
@@ -1054,6 +1123,14 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
1054 if (r) 1123 if (r)
1055 goto err_setup_clocks; 1124 goto err_setup_clocks;
1056 1125
1126 r = dss_video_pll_probe(pdev);
1127 if (r)
1128 goto err_pll_init;
1129
1130 r = dss_init_ports(pdev);
1131 if (r)
1132 goto err_init_ports;
1133
1057 pm_runtime_enable(&pdev->dev); 1134 pm_runtime_enable(&pdev->dev);
1058 1135
1059 r = dss_runtime_get(); 1136 r = dss_runtime_get();
@@ -1078,86 +1155,48 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)
1078 dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK; 1155 dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;
1079 dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; 1156 dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK;
1080 1157
1081 dss_init_ports(pdev);
1082
1083 if (np && of_property_read_bool(np, "syscon-pll-ctrl")) {
1084 dss.syscon_pll_ctrl = syscon_regmap_lookup_by_phandle(np,
1085 "syscon-pll-ctrl");
1086 if (IS_ERR(dss.syscon_pll_ctrl)) {
1087 dev_err(&pdev->dev,
1088 "failed to get syscon-pll-ctrl regmap\n");
1089 return PTR_ERR(dss.syscon_pll_ctrl);
1090 }
1091
1092 if (of_property_read_u32_index(np, "syscon-pll-ctrl", 1,
1093 &dss.syscon_pll_ctrl_offset)) {
1094 dev_err(&pdev->dev,
1095 "failed to get syscon-pll-ctrl offset\n");
1096 return -EINVAL;
1097 }
1098 }
1099
1100 pll_regulator = devm_regulator_get(&pdev->dev, "vdda_video");
1101 if (IS_ERR(pll_regulator)) {
1102 r = PTR_ERR(pll_regulator);
1103
1104 switch (r) {
1105 case -ENOENT:
1106 pll_regulator = NULL;
1107 break;
1108
1109 case -EPROBE_DEFER:
1110 return -EPROBE_DEFER;
1111
1112 default:
1113 DSSERR("can't get DPLL VDDA regulator\n");
1114 return r;
1115 }
1116 }
1117
1118 if (of_property_match_string(np, "reg-names", "pll1") >= 0) {
1119 dss.video1_pll = dss_video_pll_init(pdev, 0, pll_regulator);
1120 if (IS_ERR(dss.video1_pll)) {
1121 r = PTR_ERR(dss.video1_pll);
1122 goto err_pll_init;
1123 }
1124 }
1125
1126 if (of_property_match_string(np, "reg-names", "pll2") >= 0) {
1127 dss.video2_pll = dss_video_pll_init(pdev, 1, pll_regulator);
1128 if (IS_ERR(dss.video2_pll)) {
1129 r = PTR_ERR(dss.video2_pll);
1130 goto err_pll_init;
1131 }
1132 }
1133
1134 rev = dss_read_reg(DSS_REVISION); 1158 rev = dss_read_reg(DSS_REVISION);
1135 printk(KERN_INFO "OMAP DSS rev %d.%d\n", 1159 printk(KERN_INFO "OMAP DSS rev %d.%d\n",
1136 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); 1160 FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
1137 1161
1138 dss_runtime_put(); 1162 dss_runtime_put();
1139 1163
1164 r = component_bind_all(&pdev->dev, NULL);
1165 if (r)
1166 goto err_component;
1167
1140 dss_debugfs_create_file("dss", dss_dump_regs); 1168 dss_debugfs_create_file("dss", dss_dump_regs);
1141 1169
1142 pm_set_vt_switch(0); 1170 pm_set_vt_switch(0);
1143 1171
1172 dss_initialized = true;
1173
1144 return 0; 1174 return 0;
1145 1175
1146err_pll_init: 1176err_component:
1177err_runtime_get:
1178 pm_runtime_disable(&pdev->dev);
1179 dss_uninit_ports(pdev);
1180err_init_ports:
1147 if (dss.video1_pll) 1181 if (dss.video1_pll)
1148 dss_video_pll_uninit(dss.video1_pll); 1182 dss_video_pll_uninit(dss.video1_pll);
1149 1183
1150 if (dss.video2_pll) 1184 if (dss.video2_pll)
1151 dss_video_pll_uninit(dss.video2_pll); 1185 dss_video_pll_uninit(dss.video2_pll);
1152err_runtime_get: 1186err_pll_init:
1153 pm_runtime_disable(&pdev->dev);
1154err_setup_clocks: 1187err_setup_clocks:
1155 dss_put_clocks(); 1188 dss_put_clocks();
1156 return r; 1189 return r;
1157} 1190}
1158 1191
1159static int __exit omap_dsshw_remove(struct platform_device *pdev) 1192static void dss_unbind(struct device *dev)
1160{ 1193{
1194 struct platform_device *pdev = to_platform_device(dev);
1195
1196 dss_initialized = false;
1197
1198 component_unbind_all(&pdev->dev, NULL);
1199
1161 if (dss.video1_pll) 1200 if (dss.video1_pll)
1162 dss_video_pll_uninit(dss.video1_pll); 1201 dss_video_pll_uninit(dss.video1_pll);
1163 1202
@@ -1169,7 +1208,55 @@ static int __exit omap_dsshw_remove(struct platform_device *pdev)
1169 pm_runtime_disable(&pdev->dev); 1208 pm_runtime_disable(&pdev->dev);
1170 1209
1171 dss_put_clocks(); 1210 dss_put_clocks();
1211}
1212
1213static const struct component_master_ops dss_component_ops = {
1214 .bind = dss_bind,
1215 .unbind = dss_unbind,
1216};
1172 1217
1218static int dss_component_compare(struct device *dev, void *data)
1219{
1220 struct device *child = data;
1221 return dev == child;
1222}
1223
1224static int dss_add_child_component(struct device *dev, void *data)
1225{
1226 struct component_match **match = data;
1227
1228 /*
1229 * HACK
1230 * We don't have a working driver for rfbi, so skip it here always.
1231 * Otherwise dss will never get probed successfully, as it will wait
1232 * for rfbi to get probed.
1233 */
1234 if (strstr(dev_name(dev), "rfbi"))
1235 return 0;
1236
1237 component_match_add(dev->parent, match, dss_component_compare, dev);
1238
1239 return 0;
1240}
1241
1242static int dss_probe(struct platform_device *pdev)
1243{
1244 struct component_match *match = NULL;
1245 int r;
1246
1247 /* add all the child devices as components */
1248 device_for_each_child(&pdev->dev, &match, dss_add_child_component);
1249
1250 r = component_master_add_with_match(&pdev->dev, &dss_component_ops, match);
1251 if (r)
1252 return r;
1253
1254 return 0;
1255}
1256
1257static int dss_remove(struct platform_device *pdev)
1258{
1259 component_master_del(&pdev->dev, &dss_component_ops);
1173 return 0; 1260 return 0;
1174} 1261}
1175 1262
@@ -1215,7 +1302,8 @@ static const struct of_device_id dss_of_match[] = {
1215MODULE_DEVICE_TABLE(of, dss_of_match); 1302MODULE_DEVICE_TABLE(of, dss_of_match);
1216 1303
1217static struct platform_driver omap_dsshw_driver = { 1304static struct platform_driver omap_dsshw_driver = {
1218 .remove = __exit_p(omap_dsshw_remove), 1305 .probe = dss_probe,
1306 .remove = dss_remove,
1219 .driver = { 1307 .driver = {
1220 .name = "omapdss_dss", 1308 .name = "omapdss_dss",
1221 .pm = &dss_pm_ops, 1309 .pm = &dss_pm_ops,
@@ -1226,7 +1314,7 @@ static struct platform_driver omap_dsshw_driver = {
1226 1314
1227int __init dss_init_platform_driver(void) 1315int __init dss_init_platform_driver(void)
1228{ 1316{
1229 return platform_driver_probe(&omap_dsshw_driver, omap_dsshw_probe); 1317 return platform_driver_register(&omap_dsshw_driver);
1230} 1318}
1231 1319
1232void dss_uninit_platform_driver(void) 1320void dss_uninit_platform_driver(void)
diff --git a/drivers/video/fbdev/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 4812eee2622a..2406bcdb831a 100644
--- a/drivers/video/fbdev/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -309,18 +309,18 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
309 309
310/* SDI */ 310/* SDI */
311int sdi_init_platform_driver(void) __init; 311int sdi_init_platform_driver(void) __init;
312void sdi_uninit_platform_driver(void) __exit; 312void sdi_uninit_platform_driver(void);
313 313
314#ifdef CONFIG_OMAP2_DSS_SDI 314#ifdef CONFIG_OMAP2_DSS_SDI
315int sdi_init_port(struct platform_device *pdev, struct device_node *port) __init; 315int sdi_init_port(struct platform_device *pdev, struct device_node *port);
316void sdi_uninit_port(struct device_node *port) __exit; 316void sdi_uninit_port(struct device_node *port);
317#else 317#else
318static inline int __init sdi_init_port(struct platform_device *pdev, 318static inline int sdi_init_port(struct platform_device *pdev,
319 struct device_node *port) 319 struct device_node *port)
320{ 320{
321 return 0; 321 return 0;
322} 322}
323static inline void __exit sdi_uninit_port(struct device_node *port) 323static inline void sdi_uninit_port(struct device_node *port)
324{ 324{
325} 325}
326#endif 326#endif
@@ -333,7 +333,7 @@ struct dentry;
333struct file_operations; 333struct file_operations;
334 334
335int dsi_init_platform_driver(void) __init; 335int dsi_init_platform_driver(void) __init;
336void dsi_uninit_platform_driver(void) __exit; 336void dsi_uninit_platform_driver(void);
337 337
338void dsi_dump_clocks(struct seq_file *s); 338void dsi_dump_clocks(struct seq_file *s);
339 339
@@ -350,25 +350,25 @@ static inline u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
350 350
351/* DPI */ 351/* DPI */
352int dpi_init_platform_driver(void) __init; 352int dpi_init_platform_driver(void) __init;
353void dpi_uninit_platform_driver(void) __exit; 353void dpi_uninit_platform_driver(void);
354 354
355#ifdef CONFIG_OMAP2_DSS_DPI 355#ifdef CONFIG_OMAP2_DSS_DPI
356int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init; 356int dpi_init_port(struct platform_device *pdev, struct device_node *port);
357void dpi_uninit_port(struct device_node *port) __exit; 357void dpi_uninit_port(struct device_node *port);
358#else 358#else
359static inline int __init dpi_init_port(struct platform_device *pdev, 359static inline int dpi_init_port(struct platform_device *pdev,
360 struct device_node *port) 360 struct device_node *port)
361{ 361{
362 return 0; 362 return 0;
363} 363}
364static inline void __exit dpi_uninit_port(struct device_node *port) 364static inline void dpi_uninit_port(struct device_node *port)
365{ 365{
366} 366}
367#endif 367#endif
368 368
369/* DISPC */ 369/* DISPC */
370int dispc_init_platform_driver(void) __init; 370int dispc_init_platform_driver(void) __init;
371void dispc_uninit_platform_driver(void) __exit; 371void dispc_uninit_platform_driver(void);
372void dispc_dump_clocks(struct seq_file *s); 372void dispc_dump_clocks(struct seq_file *s);
373 373
374void dispc_enable_sidle(void); 374void dispc_enable_sidle(void);
@@ -418,18 +418,18 @@ int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
418 418
419/* VENC */ 419/* VENC */
420int venc_init_platform_driver(void) __init; 420int venc_init_platform_driver(void) __init;
421void venc_uninit_platform_driver(void) __exit; 421void venc_uninit_platform_driver(void);
422 422
423/* HDMI */ 423/* HDMI */
424int hdmi4_init_platform_driver(void) __init; 424int hdmi4_init_platform_driver(void) __init;
425void hdmi4_uninit_platform_driver(void) __exit; 425void hdmi4_uninit_platform_driver(void);
426 426
427int hdmi5_init_platform_driver(void) __init; 427int hdmi5_init_platform_driver(void) __init;
428void hdmi5_uninit_platform_driver(void) __exit; 428void hdmi5_uninit_platform_driver(void);
429 429
430/* RFBI */ 430/* RFBI */
431int rfbi_init_platform_driver(void) __init; 431int rfbi_init_platform_driver(void) __init;
432void rfbi_uninit_platform_driver(void) __exit; 432void rfbi_uninit_platform_driver(void);
433 433
434 434
435#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS 435#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c
index 916d47978f41..6d3aa3f51c20 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
@@ -32,6 +32,7 @@
32#include <linux/clk.h> 32#include <linux/clk.h>
33#include <linux/gpio.h> 33#include <linux/gpio.h>
34#include <linux/regulator/consumer.h> 34#include <linux/regulator/consumer.h>
35#include <linux/component.h>
35#include <video/omapdss.h> 36#include <video/omapdss.h>
36#include <sound/omap-hdmi-audio.h> 37#include <sound/omap-hdmi-audio.h>
37 38
@@ -229,9 +230,9 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
229err_mgr_enable: 230err_mgr_enable:
230 hdmi_wp_video_stop(&hdmi.wp); 231 hdmi_wp_video_stop(&hdmi.wp);
231err_vid_enable: 232err_vid_enable:
232err_phy_cfg:
233 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); 233 hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF);
234err_phy_pwr: 234err_phy_pwr:
235err_phy_cfg:
235err_pll_cfg: 236err_pll_cfg:
236 dss_pll_disable(&hdmi.pll.pll); 237 dss_pll_disable(&hdmi.pll.pll);
237err_pll_enable: 238err_pll_enable:
@@ -646,8 +647,9 @@ static int hdmi_audio_register(struct device *dev)
646} 647}
647 648
648/* HDMI HW IP initialisation */ 649/* HDMI HW IP initialisation */
649static int omapdss_hdmihw_probe(struct platform_device *pdev) 650static int hdmi4_bind(struct device *dev, struct device *master, void *data)
650{ 651{
652 struct platform_device *pdev = to_platform_device(dev);
651 int r; 653 int r;
652 int irq; 654 int irq;
653 655
@@ -713,8 +715,10 @@ err:
713 return r; 715 return r;
714} 716}
715 717
716static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) 718static void hdmi4_unbind(struct device *dev, struct device *master, void *data)
717{ 719{
720 struct platform_device *pdev = to_platform_device(dev);
721
718 if (hdmi.audio_pdev) 722 if (hdmi.audio_pdev)
719 platform_device_unregister(hdmi.audio_pdev); 723 platform_device_unregister(hdmi.audio_pdev);
720 724
@@ -723,7 +727,21 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
723 hdmi_pll_uninit(&hdmi.pll); 727 hdmi_pll_uninit(&hdmi.pll);
724 728
725 pm_runtime_disable(&pdev->dev); 729 pm_runtime_disable(&pdev->dev);
730}
731
732static const struct component_ops hdmi4_component_ops = {
733 .bind = hdmi4_bind,
734 .unbind = hdmi4_unbind,
735};
726 736
737static int hdmi4_probe(struct platform_device *pdev)
738{
739 return component_add(&pdev->dev, &hdmi4_component_ops);
740}
741
742static int hdmi4_remove(struct platform_device *pdev)
743{
744 component_del(&pdev->dev, &hdmi4_component_ops);
727 return 0; 745 return 0;
728} 746}
729 747
@@ -756,8 +774,8 @@ static const struct of_device_id hdmi_of_match[] = {
756}; 774};
757 775
758static struct platform_driver omapdss_hdmihw_driver = { 776static struct platform_driver omapdss_hdmihw_driver = {
759 .probe = omapdss_hdmihw_probe, 777 .probe = hdmi4_probe,
760 .remove = __exit_p(omapdss_hdmihw_remove), 778 .remove = hdmi4_remove,
761 .driver = { 779 .driver = {
762 .name = "omapdss_hdmi", 780 .name = "omapdss_hdmi",
763 .pm = &hdmi_pm_ops, 781 .pm = &hdmi_pm_ops,
@@ -771,7 +789,7 @@ int __init hdmi4_init_platform_driver(void)
771 return platform_driver_register(&omapdss_hdmihw_driver); 789 return platform_driver_register(&omapdss_hdmihw_driver);
772} 790}
773 791
774void __exit hdmi4_uninit_platform_driver(void) 792void hdmi4_uninit_platform_driver(void)
775{ 793{
776 platform_driver_unregister(&omapdss_hdmihw_driver); 794 platform_driver_unregister(&omapdss_hdmihw_driver);
777} 795}
diff --git a/drivers/video/fbdev/omap2/dss/hdmi4_core.c b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
index 7eafea5b8e19..fa72e735dad2 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi4_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
@@ -654,6 +654,13 @@ static void hdmi_core_audio_infoframe_cfg(struct hdmi_core_data *core,
654 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), info_aud->db3); 654 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(2), info_aud->db3);
655 sum += info_aud->db3; 655 sum += info_aud->db3;
656 656
657 /*
658 * The OMAP HDMI IP requires to use the 8-channel channel code when
659 * transmitting more than two channels.
660 */
661 if (info_aud->db4_ca != 0x00)
662 info_aud->db4_ca = 0x13;
663
657 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), info_aud->db4_ca); 664 hdmi_write_reg(av_base, HDMI_CORE_AV_AUD_DBYTE(3), info_aud->db4_ca);
658 sum += info_aud->db4_ca; 665 sum += info_aud->db4_ca;
659 666
@@ -795,7 +802,9 @@ int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
795 802
796 /* 803 /*
797 * the HDMI IP needs to enable four stereo channels when transmitting 804 * the HDMI IP needs to enable four stereo channels when transmitting
798 * more than 2 audio channels 805 * more than 2 audio channels. Similarly, the channel count in the
806 * Audio InfoFrame has to match the sample_present bits (some channels
807 * are padded with zeroes)
799 */ 808 */
800 if (channel_count == 2) { 809 if (channel_count == 2) {
801 audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL; 810 audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL;
@@ -807,6 +816,7 @@ int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
807 HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN | 816 HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN |
808 HDMI_AUDIO_I2S_SD3_EN; 817 HDMI_AUDIO_I2S_SD3_EN;
809 acore.layout = HDMI_AUDIO_LAYOUT_8CH; 818 acore.layout = HDMI_AUDIO_LAYOUT_8CH;
819 audio->cea->db1_ct_cc = 7;
810 } 820 }
811 821
812 acore.en_spdif = false; 822 acore.en_spdif = false;
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c
index 3f0b34a7031a..7f875788edbc 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5.c
@@ -37,6 +37,7 @@
37#include <linux/clk.h> 37#include <linux/clk.h>
38#include <linux/gpio.h> 38#include <linux/gpio.h>
39#include <linux/regulator/consumer.h> 39#include <linux/regulator/consumer.h>
40#include <linux/component.h>
40#include <video/omapdss.h> 41#include <video/omapdss.h>
41#include <sound/omap-hdmi-audio.h> 42#include <sound/omap-hdmi-audio.h>
42 43
@@ -681,8 +682,9 @@ static int hdmi_audio_register(struct device *dev)
681} 682}
682 683
683/* HDMI HW IP initialisation */ 684/* HDMI HW IP initialisation */
684static int omapdss_hdmihw_probe(struct platform_device *pdev) 685static int hdmi5_bind(struct device *dev, struct device *master, void *data)
685{ 686{
687 struct platform_device *pdev = to_platform_device(dev);
686 int r; 688 int r;
687 int irq; 689 int irq;
688 690
@@ -748,8 +750,10 @@ err:
748 return r; 750 return r;
749} 751}
750 752
751static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) 753static void hdmi5_unbind(struct device *dev, struct device *master, void *data)
752{ 754{
755 struct platform_device *pdev = to_platform_device(dev);
756
753 if (hdmi.audio_pdev) 757 if (hdmi.audio_pdev)
754 platform_device_unregister(hdmi.audio_pdev); 758 platform_device_unregister(hdmi.audio_pdev);
755 759
@@ -758,7 +762,21 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
758 hdmi_pll_uninit(&hdmi.pll); 762 hdmi_pll_uninit(&hdmi.pll);
759 763
760 pm_runtime_disable(&pdev->dev); 764 pm_runtime_disable(&pdev->dev);
765}
766
767static const struct component_ops hdmi5_component_ops = {
768 .bind = hdmi5_bind,
769 .unbind = hdmi5_unbind,
770};
761 771
772static int hdmi5_probe(struct platform_device *pdev)
773{
774 return component_add(&pdev->dev, &hdmi5_component_ops);
775}
776
777static int hdmi5_remove(struct platform_device *pdev)
778{
779 component_del(&pdev->dev, &hdmi5_component_ops);
762 return 0; 780 return 0;
763} 781}
764 782
@@ -792,8 +810,8 @@ static const struct of_device_id hdmi_of_match[] = {
792}; 810};
793 811
794static struct platform_driver omapdss_hdmihw_driver = { 812static struct platform_driver omapdss_hdmihw_driver = {
795 .probe = omapdss_hdmihw_probe, 813 .probe = hdmi5_probe,
796 .remove = __exit_p(omapdss_hdmihw_remove), 814 .remove = hdmi5_remove,
797 .driver = { 815 .driver = {
798 .name = "omapdss_hdmi5", 816 .name = "omapdss_hdmi5",
799 .pm = &hdmi_pm_ops, 817 .pm = &hdmi_pm_ops,
@@ -807,7 +825,7 @@ int __init hdmi5_init_platform_driver(void)
807 return platform_driver_register(&omapdss_hdmihw_driver); 825 return platform_driver_register(&omapdss_hdmihw_driver);
808} 826}
809 827
810void __exit hdmi5_uninit_platform_driver(void) 828void hdmi5_uninit_platform_driver(void)
811{ 829{
812 platform_driver_unregister(&omapdss_hdmihw_driver); 830 platform_driver_unregister(&omapdss_hdmihw_driver);
813} 831}
diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.c b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
index bfc0c4c297d6..8ea531d2652c 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi5_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.c
@@ -790,7 +790,9 @@ static void hdmi5_core_audio_infoframe_cfg(struct hdmi_core_data *core,
790 790
791 hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF1, info_aud->db2_sf_ss); 791 hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF1, info_aud->db2_sf_ss);
792 hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF2, info_aud->db4_ca); 792 hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF2, info_aud->db4_ca);
793 hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF3, info_aud->db5_dminh_lsv); 793 hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF3,
794 (info_aud->db5_dminh_lsv & CEA861_AUDIO_INFOFRAME_DB5_DM_INH) >> 3 |
795 (info_aud->db5_dminh_lsv & CEA861_AUDIO_INFOFRAME_DB5_LSV));
794} 796}
795 797
796int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, 798int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
@@ -870,6 +872,7 @@ int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
870 audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES; 872 audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES;
871 audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS; 873 audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS;
872 audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT; 874 audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT;
875 audio_format.sample_order = HDMI_AUDIO_SAMPLE_LEFT_FIRST;
873 876
874 /* only LPCM atm */ 877 /* only LPCM atm */
875 audio_format.type = HDMI_AUDIO_TYPE_LPCM; 878 audio_format.type = HDMI_AUDIO_TYPE_LPCM;
diff --git a/drivers/video/fbdev/omap2/dss/hdmi_wp.c b/drivers/video/fbdev/omap2/dss/hdmi_wp.c
index c15377e242cc..7c544bc56fb5 100644
--- a/drivers/video/fbdev/omap2/dss/hdmi_wp.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_wp.c
@@ -110,7 +110,23 @@ int hdmi_wp_video_start(struct hdmi_wp_data *wp)
110 110
111void hdmi_wp_video_stop(struct hdmi_wp_data *wp) 111void hdmi_wp_video_stop(struct hdmi_wp_data *wp)
112{ 112{
113 int i;
114
115 hdmi_write_reg(wp->base, HDMI_WP_IRQSTATUS, HDMI_IRQ_VIDEO_FRAME_DONE);
116
113 REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, false, 31, 31); 117 REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, false, 31, 31);
118
119 for (i = 0; i < 50; ++i) {
120 u32 v;
121
122 msleep(20);
123
124 v = hdmi_read_reg(wp->base, HDMI_WP_IRQSTATUS_RAW);
125 if (v & HDMI_IRQ_VIDEO_FRAME_DONE)
126 return;
127 }
128
129 DSSERR("no HDMI FRAMEDONE when disabling output\n");
114} 130}
115 131
116void hdmi_wp_video_config_format(struct hdmi_wp_data *wp, 132void hdmi_wp_video_config_format(struct hdmi_wp_data *wp,
diff --git a/drivers/video/fbdev/omap2/dss/rfbi.c b/drivers/video/fbdev/omap2/dss/rfbi.c
index 065effca9236..1525a494d057 100644
--- a/drivers/video/fbdev/omap2/dss/rfbi.c
+++ b/drivers/video/fbdev/omap2/dss/rfbi.c
@@ -36,6 +36,7 @@
36#include <linux/semaphore.h> 36#include <linux/semaphore.h>
37#include <linux/platform_device.h> 37#include <linux/platform_device.h>
38#include <linux/pm_runtime.h> 38#include <linux/pm_runtime.h>
39#include <linux/component.h>
39 40
40#include <video/omapdss.h> 41#include <video/omapdss.h>
41#include "dss.h" 42#include "dss.h"
@@ -938,7 +939,7 @@ static void rfbi_init_output(struct platform_device *pdev)
938 omapdss_register_output(out); 939 omapdss_register_output(out);
939} 940}
940 941
941static void __exit rfbi_uninit_output(struct platform_device *pdev) 942static void rfbi_uninit_output(struct platform_device *pdev)
942{ 943{
943 struct omap_dss_device *out = &rfbi.output; 944 struct omap_dss_device *out = &rfbi.output;
944 945
@@ -946,8 +947,9 @@ static void __exit rfbi_uninit_output(struct platform_device *pdev)
946} 947}
947 948
948/* RFBI HW IP initialisation */ 949/* RFBI HW IP initialisation */
949static int omap_rfbihw_probe(struct platform_device *pdev) 950static int rfbi_bind(struct device *dev, struct device *master, void *data)
950{ 951{
952 struct platform_device *pdev = to_platform_device(dev);
951 u32 rev; 953 u32 rev;
952 struct resource *rfbi_mem; 954 struct resource *rfbi_mem;
953 struct clk *clk; 955 struct clk *clk;
@@ -1005,8 +1007,10 @@ err_runtime_get:
1005 return r; 1007 return r;
1006} 1008}
1007 1009
1008static int __exit omap_rfbihw_remove(struct platform_device *pdev) 1010static void rfbi_unbind(struct device *dev, struct device *master, void *data)
1009{ 1011{
1012 struct platform_device *pdev = to_platform_device(dev);
1013
1010 rfbi_uninit_output(pdev); 1014 rfbi_uninit_output(pdev);
1011 1015
1012 pm_runtime_disable(&pdev->dev); 1016 pm_runtime_disable(&pdev->dev);
@@ -1014,6 +1018,22 @@ static int __exit omap_rfbihw_remove(struct platform_device *pdev)
1014 return 0; 1018 return 0;
1015} 1019}
1016 1020
1021static const struct component_ops rfbi_component_ops = {
1022 .bind = rfbi_bind,
1023 .unbind = rfbi_unbind,
1024};
1025
1026static int rfbi_probe(struct platform_device *pdev)
1027{
1028 return component_add(&pdev->dev, &rfbi_component_ops);
1029}
1030
1031static int rfbi_remove(struct platform_device *pdev)
1032{
1033 component_del(&pdev->dev, &rfbi_component_ops);
1034 return 0;
1035}
1036
1017static int rfbi_runtime_suspend(struct device *dev) 1037static int rfbi_runtime_suspend(struct device *dev)
1018{ 1038{
1019 dispc_runtime_put(); 1039 dispc_runtime_put();
@@ -1038,8 +1058,8 @@ static const struct dev_pm_ops rfbi_pm_ops = {
1038}; 1058};
1039 1059
1040static struct platform_driver omap_rfbihw_driver = { 1060static struct platform_driver omap_rfbihw_driver = {
1041 .probe = omap_rfbihw_probe, 1061 .probe = rfbi_probe,
1042 .remove = __exit_p(omap_rfbihw_remove), 1062 .remove = rfbi_remove,
1043 .driver = { 1063 .driver = {
1044 .name = "omapdss_rfbi", 1064 .name = "omapdss_rfbi",
1045 .pm = &rfbi_pm_ops, 1065 .pm = &rfbi_pm_ops,
@@ -1052,7 +1072,7 @@ int __init rfbi_init_platform_driver(void)
1052 return platform_driver_register(&omap_rfbihw_driver); 1072 return platform_driver_register(&omap_rfbihw_driver);
1053} 1073}
1054 1074
1055void __exit rfbi_uninit_platform_driver(void) 1075void rfbi_uninit_platform_driver(void)
1056{ 1076{
1057 platform_driver_unregister(&omap_rfbihw_driver); 1077 platform_driver_unregister(&omap_rfbihw_driver);
1058} 1078}
diff --git a/drivers/video/fbdev/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c
index 5c2ccab5a958..5843580a1deb 100644
--- a/drivers/video/fbdev/omap2/dss/sdi.c
+++ b/drivers/video/fbdev/omap2/dss/sdi.c
@@ -27,6 +27,7 @@
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/string.h> 28#include <linux/string.h>
29#include <linux/of.h> 29#include <linux/of.h>
30#include <linux/component.h>
30 31
31#include <video/omapdss.h> 32#include <video/omapdss.h>
32#include "dss.h" 33#include "dss.h"
@@ -350,15 +351,17 @@ static void sdi_init_output(struct platform_device *pdev)
350 omapdss_register_output(out); 351 omapdss_register_output(out);
351} 352}
352 353
353static void __exit sdi_uninit_output(struct platform_device *pdev) 354static void sdi_uninit_output(struct platform_device *pdev)
354{ 355{
355 struct omap_dss_device *out = &sdi.output; 356 struct omap_dss_device *out = &sdi.output;
356 357
357 omapdss_unregister_output(out); 358 omapdss_unregister_output(out);
358} 359}
359 360
360static int omap_sdi_probe(struct platform_device *pdev) 361static int sdi_bind(struct device *dev, struct device *master, void *data)
361{ 362{
363 struct platform_device *pdev = to_platform_device(dev);
364
362 sdi.pdev = pdev; 365 sdi.pdev = pdev;
363 366
364 sdi_init_output(pdev); 367 sdi_init_output(pdev);
@@ -366,16 +369,32 @@ static int omap_sdi_probe(struct platform_device *pdev)
366 return 0; 369 return 0;
367} 370}
368 371
369static int __exit omap_sdi_remove(struct platform_device *pdev) 372static void sdi_unbind(struct device *dev, struct device *master, void *data)
370{ 373{
374 struct platform_device *pdev = to_platform_device(dev);
375
371 sdi_uninit_output(pdev); 376 sdi_uninit_output(pdev);
377}
378
379static const struct component_ops sdi_component_ops = {
380 .bind = sdi_bind,
381 .unbind = sdi_unbind,
382};
372 383
384static int sdi_probe(struct platform_device *pdev)
385{
386 return component_add(&pdev->dev, &sdi_component_ops);
387}
388
389static int sdi_remove(struct platform_device *pdev)
390{
391 component_del(&pdev->dev, &sdi_component_ops);
373 return 0; 392 return 0;
374} 393}
375 394
376static struct platform_driver omap_sdi_driver = { 395static struct platform_driver omap_sdi_driver = {
377 .probe = omap_sdi_probe, 396 .probe = sdi_probe,
378 .remove = __exit_p(omap_sdi_remove), 397 .remove = sdi_remove,
379 .driver = { 398 .driver = {
380 .name = "omapdss_sdi", 399 .name = "omapdss_sdi",
381 .suppress_bind_attrs = true, 400 .suppress_bind_attrs = true,
@@ -387,12 +406,12 @@ int __init sdi_init_platform_driver(void)
387 return platform_driver_register(&omap_sdi_driver); 406 return platform_driver_register(&omap_sdi_driver);
388} 407}
389 408
390void __exit sdi_uninit_platform_driver(void) 409void sdi_uninit_platform_driver(void)
391{ 410{
392 platform_driver_unregister(&omap_sdi_driver); 411 platform_driver_unregister(&omap_sdi_driver);
393} 412}
394 413
395int __init sdi_init_port(struct platform_device *pdev, struct device_node *port) 414int sdi_init_port(struct platform_device *pdev, struct device_node *port)
396{ 415{
397 struct device_node *ep; 416 struct device_node *ep;
398 u32 datapairs; 417 u32 datapairs;
@@ -426,7 +445,7 @@ err_datapairs:
426 return r; 445 return r;
427} 446}
428 447
429void __exit sdi_uninit_port(struct device_node *port) 448void sdi_uninit_port(struct device_node *port)
430{ 449{
431 if (!sdi.port_initialized) 450 if (!sdi.port_initialized)
432 return; 451 return;
diff --git a/drivers/video/fbdev/omap2/dss/venc.c b/drivers/video/fbdev/omap2/dss/venc.c
index ef7fd925e7f2..99ca268c1cdd 100644
--- a/drivers/video/fbdev/omap2/dss/venc.c
+++ b/drivers/video/fbdev/omap2/dss/venc.c
@@ -35,6 +35,7 @@
35#include <linux/regulator/consumer.h> 35#include <linux/regulator/consumer.h>
36#include <linux/pm_runtime.h> 36#include <linux/pm_runtime.h>
37#include <linux/of.h> 37#include <linux/of.h>
38#include <linux/component.h>
38 39
39#include <video/omapdss.h> 40#include <video/omapdss.h>
40 41
@@ -802,7 +803,7 @@ static void venc_init_output(struct platform_device *pdev)
802 omapdss_register_output(out); 803 omapdss_register_output(out);
803} 804}
804 805
805static void __exit venc_uninit_output(struct platform_device *pdev) 806static void venc_uninit_output(struct platform_device *pdev)
806{ 807{
807 struct omap_dss_device *out = &venc.output; 808 struct omap_dss_device *out = &venc.output;
808 809
@@ -852,8 +853,9 @@ err:
852} 853}
853 854
854/* VENC HW IP initialisation */ 855/* VENC HW IP initialisation */
855static int omap_venchw_probe(struct platform_device *pdev) 856static int venc_bind(struct device *dev, struct device *master, void *data)
856{ 857{
858 struct platform_device *pdev = to_platform_device(dev);
857 u8 rev_id; 859 u8 rev_id;
858 struct resource *venc_mem; 860 struct resource *venc_mem;
859 int r; 861 int r;
@@ -912,12 +914,28 @@ err_runtime_get:
912 return r; 914 return r;
913} 915}
914 916
915static int __exit omap_venchw_remove(struct platform_device *pdev) 917static void venc_unbind(struct device *dev, struct device *master, void *data)
916{ 918{
919 struct platform_device *pdev = to_platform_device(dev);
920
917 venc_uninit_output(pdev); 921 venc_uninit_output(pdev);
918 922
919 pm_runtime_disable(&pdev->dev); 923 pm_runtime_disable(&pdev->dev);
924}
920 925
926static const struct component_ops venc_component_ops = {
927 .bind = venc_bind,
928 .unbind = venc_unbind,
929};
930
931static int venc_probe(struct platform_device *pdev)
932{
933 return component_add(&pdev->dev, &venc_component_ops);
934}
935
936static int venc_remove(struct platform_device *pdev)
937{
938 component_del(&pdev->dev, &venc_component_ops);
921 return 0; 939 return 0;
922} 940}
923 941
@@ -950,7 +968,6 @@ static const struct dev_pm_ops venc_pm_ops = {
950 .runtime_resume = venc_runtime_resume, 968 .runtime_resume = venc_runtime_resume,
951}; 969};
952 970
953
954static const struct of_device_id venc_of_match[] = { 971static const struct of_device_id venc_of_match[] = {
955 { .compatible = "ti,omap2-venc", }, 972 { .compatible = "ti,omap2-venc", },
956 { .compatible = "ti,omap3-venc", }, 973 { .compatible = "ti,omap3-venc", },
@@ -959,8 +976,8 @@ static const struct of_device_id venc_of_match[] = {
959}; 976};
960 977
961static struct platform_driver omap_venchw_driver = { 978static struct platform_driver omap_venchw_driver = {
962 .probe = omap_venchw_probe, 979 .probe = venc_probe,
963 .remove = __exit_p(omap_venchw_remove), 980 .remove = venc_remove,
964 .driver = { 981 .driver = {
965 .name = "omapdss_venc", 982 .name = "omapdss_venc",
966 .pm = &venc_pm_ops, 983 .pm = &venc_pm_ops,
@@ -974,7 +991,7 @@ int __init venc_init_platform_driver(void)
974 return platform_driver_register(&omap_venchw_driver); 991 return platform_driver_register(&omap_venchw_driver);
975} 992}
976 993
977void __exit venc_uninit_platform_driver(void) 994void venc_uninit_platform_driver(void)
978{ 995{
979 platform_driver_unregister(&omap_venchw_driver); 996 platform_driver_unregister(&omap_venchw_driver);
980} 997}