aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/backlight/Kconfig1
-rw-r--r--drivers/video/backlight/lp855x_bl.c55
-rw-r--r--drivers/video/backlight/pwm_bl.c5
-rw-r--r--drivers/video/console/fbcon.c21
-rw-r--r--drivers/video/console/vgacon.c24
-rw-r--r--drivers/video/fbdev/Kconfig19
-rw-r--r--drivers/video/fbdev/amba-clcd.c1
-rw-r--r--drivers/video/fbdev/arkfb.c2
-rw-r--r--drivers/video/fbdev/atmel_lcdfb.c1
-rw-r--r--drivers/video/fbdev/exynos/exynos_mipi_dsi.c2
-rw-r--r--drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c2
-rw-r--r--drivers/video/fbdev/gbefb.c3
-rw-r--r--drivers/video/fbdev/mmp/core.c6
-rw-r--r--drivers/video/fbdev/mmp/hw/mmp_ctrl.c3
-rw-r--r--drivers/video/fbdev/mx3fb.c3
-rw-r--r--drivers/video/fbdev/mxsfb.c19
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c3
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-dvi.c10
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-hdmi.c100
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c2
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c58
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-dpi.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c1
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c1
-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/apply.c2
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc.c28
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc.h3
-rw-r--r--drivers/video/fbdev/omap2/dss/dpi.c328
-rw-r--r--drivers/video/fbdev/omap2/dss/dsi.c660
-rw-r--r--drivers/video/fbdev/omap2/dss/dss-of.c58
-rw-r--r--drivers/video/fbdev/omap2/dss/dss.c124
-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.c339
-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.c339
-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.c316
-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/rfbi.c1
-rw-r--r--drivers/video/fbdev/omap2/dss/sdi.c3
-rw-r--r--drivers/video/fbdev/omap2/dss/venc.c1
-rw-r--r--drivers/video/fbdev/omap2/omapfb/omapfb-main.c18
-rw-r--r--drivers/video/fbdev/s3fb.c2
-rw-r--r--drivers/video/fbdev/sh_mobile_lcdcfb.c3
-rw-r--r--drivers/video/fbdev/simplefb.c162
-rw-r--r--drivers/video/fbdev/sis/sis_main.c14
-rw-r--r--drivers/video/fbdev/sm501fb.c1
-rw-r--r--drivers/video/fbdev/smscufx.c6
-rw-r--r--drivers/video/fbdev/udlfb.c9
-rw-r--r--drivers/video/fbdev/uvesafb.c6
-rw-r--r--drivers/video/fbdev/vermilion/vermilion.c6
-rw-r--r--drivers/video/fbdev/via/viafbdev.c3
-rw-r--r--drivers/video/fbdev/vt8623fb.c2
69 files changed, 1931 insertions, 1687 deletions
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 8d03924749b8..efb09046a8cf 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -168,7 +168,6 @@ if BACKLIGHT_CLASS_DEVICE
168config BACKLIGHT_ATMEL_LCDC 168config BACKLIGHT_ATMEL_LCDC
169 bool "Atmel LCDC Contrast-as-Backlight control" 169 bool "Atmel LCDC Contrast-as-Backlight control"
170 depends on FB_ATMEL 170 depends on FB_ATMEL
171 default y if MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK || MACH_AT91SAM9263EK
172 help 171 help
173 This provides a backlight control internal to the Atmel LCDC 172 This provides a backlight control internal to the Atmel LCDC
174 driver. If the LCD "contrast control" on your board is wired 173 driver. If the LCD "contrast control" on your board is wired
diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c
index 25fb8e3d75b1..a26d3bb25650 100644
--- a/drivers/video/backlight/lp855x_bl.c
+++ b/drivers/video/backlight/lp855x_bl.c
@@ -17,6 +17,7 @@
17#include <linux/of.h> 17#include <linux/of.h>
18#include <linux/platform_data/lp855x.h> 18#include <linux/platform_data/lp855x.h>
19#include <linux/pwm.h> 19#include <linux/pwm.h>
20#include <linux/regulator/consumer.h>
20 21
21/* LP8550/1/2/3/6 Registers */ 22/* LP8550/1/2/3/6 Registers */
22#define LP855X_BRIGHTNESS_CTRL 0x00 23#define LP855X_BRIGHTNESS_CTRL 0x00
@@ -341,8 +342,10 @@ static const struct attribute_group lp855x_attr_group = {
341}; 342};
342 343
343#ifdef CONFIG_OF 344#ifdef CONFIG_OF
344static int lp855x_parse_dt(struct device *dev, struct device_node *node) 345static int lp855x_parse_dt(struct lp855x *lp)
345{ 346{
347 struct device *dev = lp->dev;
348 struct device_node *node = dev->of_node;
346 struct lp855x_platform_data *pdata; 349 struct lp855x_platform_data *pdata;
347 int rom_length; 350 int rom_length;
348 351
@@ -381,12 +384,19 @@ static int lp855x_parse_dt(struct device *dev, struct device_node *node)
381 pdata->rom_data = &rom[0]; 384 pdata->rom_data = &rom[0];
382 } 385 }
383 386
384 dev->platform_data = pdata; 387 pdata->supply = devm_regulator_get(dev, "power");
388 if (IS_ERR(pdata->supply)) {
389 if (PTR_ERR(pdata->supply) == -EPROBE_DEFER)
390 return -EPROBE_DEFER;
391 pdata->supply = NULL;
392 }
393
394 lp->pdata = pdata;
385 395
386 return 0; 396 return 0;
387} 397}
388#else 398#else
389static int lp855x_parse_dt(struct device *dev, struct device_node *node) 399static int lp855x_parse_dt(struct lp855x *lp)
390{ 400{
391 return -EINVAL; 401 return -EINVAL;
392} 402}
@@ -395,18 +405,8 @@ static int lp855x_parse_dt(struct device *dev, struct device_node *node)
395static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id) 405static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
396{ 406{
397 struct lp855x *lp; 407 struct lp855x *lp;
398 struct lp855x_platform_data *pdata = dev_get_platdata(&cl->dev);
399 struct device_node *node = cl->dev.of_node;
400 int ret; 408 int ret;
401 409
402 if (!pdata) {
403 ret = lp855x_parse_dt(&cl->dev, node);
404 if (ret < 0)
405 return ret;
406
407 pdata = dev_get_platdata(&cl->dev);
408 }
409
410 if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) 410 if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
411 return -EIO; 411 return -EIO;
412 412
@@ -414,16 +414,31 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
414 if (!lp) 414 if (!lp)
415 return -ENOMEM; 415 return -ENOMEM;
416 416
417 if (pdata->period_ns > 0)
418 lp->mode = PWM_BASED;
419 else
420 lp->mode = REGISTER_BASED;
421
422 lp->client = cl; 417 lp->client = cl;
423 lp->dev = &cl->dev; 418 lp->dev = &cl->dev;
424 lp->pdata = pdata;
425 lp->chipname = id->name; 419 lp->chipname = id->name;
426 lp->chip_id = id->driver_data; 420 lp->chip_id = id->driver_data;
421 lp->pdata = dev_get_platdata(&cl->dev);
422
423 if (!lp->pdata) {
424 ret = lp855x_parse_dt(lp);
425 if (ret < 0)
426 return ret;
427 }
428
429 if (lp->pdata->period_ns > 0)
430 lp->mode = PWM_BASED;
431 else
432 lp->mode = REGISTER_BASED;
433
434 if (lp->pdata->supply) {
435 ret = regulator_enable(lp->pdata->supply);
436 if (ret < 0) {
437 dev_err(&cl->dev, "failed to enable supply: %d\n", ret);
438 return ret;
439 }
440 }
441
427 i2c_set_clientdata(cl, lp); 442 i2c_set_clientdata(cl, lp);
428 443
429 ret = lp855x_configure(lp); 444 ret = lp855x_configure(lp);
@@ -455,6 +470,8 @@ static int lp855x_remove(struct i2c_client *cl)
455 470
456 lp->bl->props.brightness = 0; 471 lp->bl->props.brightness = 0;
457 backlight_update_status(lp->bl); 472 backlight_update_status(lp->bl);
473 if (lp->pdata->supply)
474 regulator_disable(lp->pdata->supply);
458 sysfs_remove_group(&lp->dev->kobj, &lp855x_attr_group); 475 sysfs_remove_group(&lp->dev->kobj, &lp855x_attr_group);
459 476
460 return 0; 477 return 0;
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index cb5ae4c08469..3a145a643e0d 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -34,6 +34,7 @@ struct pwm_bl_data {
34 struct regulator *power_supply; 34 struct regulator *power_supply;
35 struct gpio_desc *enable_gpio; 35 struct gpio_desc *enable_gpio;
36 unsigned int scale; 36 unsigned int scale;
37 bool legacy;
37 int (*notify)(struct device *, 38 int (*notify)(struct device *,
38 int brightness); 39 int brightness);
39 void (*notify_after)(struct device *, 40 void (*notify_after)(struct device *,
@@ -274,7 +275,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
274 pb->pwm = devm_pwm_get(&pdev->dev, NULL); 275 pb->pwm = devm_pwm_get(&pdev->dev, NULL);
275 if (IS_ERR(pb->pwm)) { 276 if (IS_ERR(pb->pwm)) {
276 dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n"); 277 dev_err(&pdev->dev, "unable to request PWM, trying legacy API\n");
277 278 pb->legacy = true;
278 pb->pwm = pwm_request(data->pwm_id, "pwm-backlight"); 279 pb->pwm = pwm_request(data->pwm_id, "pwm-backlight");
279 if (IS_ERR(pb->pwm)) { 280 if (IS_ERR(pb->pwm)) {
280 dev_err(&pdev->dev, "unable to request legacy PWM\n"); 281 dev_err(&pdev->dev, "unable to request legacy PWM\n");
@@ -339,6 +340,8 @@ static int pwm_backlight_remove(struct platform_device *pdev)
339 340
340 if (pb->exit) 341 if (pb->exit)
341 pb->exit(&pdev->dev); 342 pb->exit(&pdev->dev);
343 if (pb->legacy)
344 pwm_free(pb->pwm);
342 345
343 return 0; 346 return 0;
344} 347}
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 57b1d44acbfe..ea437245562e 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -448,8 +448,10 @@ static int __init fb_console_setup(char *this_opt)
448 return 1; 448 return 1;
449 449
450 while ((options = strsep(&this_opt, ",")) != NULL) { 450 while ((options = strsep(&this_opt, ",")) != NULL) {
451 if (!strncmp(options, "font:", 5)) 451 if (!strncmp(options, "font:", 5)) {
452 strlcpy(fontname, options + 5, sizeof(fontname)); 452 strlcpy(fontname, options + 5, sizeof(fontname));
453 continue;
454 }
453 455
454 if (!strncmp(options, "scrollback:", 11)) { 456 if (!strncmp(options, "scrollback:", 11)) {
455 options += 11; 457 options += 11;
@@ -457,13 +459,9 @@ static int __init fb_console_setup(char *this_opt)
457 fbcon_softback_size = simple_strtoul(options, &options, 0); 459 fbcon_softback_size = simple_strtoul(options, &options, 0);
458 if (*options == 'k' || *options == 'K') { 460 if (*options == 'k' || *options == 'K') {
459 fbcon_softback_size *= 1024; 461 fbcon_softback_size *= 1024;
460 options++;
461 } 462 }
462 if (*options != ',') 463 }
463 return 1; 464 continue;
464 options++;
465 } else
466 return 1;
467 } 465 }
468 466
469 if (!strncmp(options, "map:", 4)) { 467 if (!strncmp(options, "map:", 4)) {
@@ -478,8 +476,7 @@ static int __init fb_console_setup(char *this_opt)
478 476
479 fbcon_map_override(); 477 fbcon_map_override();
480 } 478 }
481 479 continue;
482 return 1;
483 } 480 }
484 481
485 if (!strncmp(options, "vc:", 3)) { 482 if (!strncmp(options, "vc:", 3)) {
@@ -491,7 +488,8 @@ static int __init fb_console_setup(char *this_opt)
491 if (*options++ == '-') 488 if (*options++ == '-')
492 last_fb_vc = simple_strtoul(options, &options, 10) - 1; 489 last_fb_vc = simple_strtoul(options, &options, 10) - 1;
493 fbcon_is_default = 0; 490 fbcon_is_default = 0;
494 } 491 continue;
492 }
495 493
496 if (!strncmp(options, "rotate:", 7)) { 494 if (!strncmp(options, "rotate:", 7)) {
497 options += 7; 495 options += 7;
@@ -499,6 +497,7 @@ static int __init fb_console_setup(char *this_opt)
499 initial_rotation = simple_strtoul(options, &options, 0); 497 initial_rotation = simple_strtoul(options, &options, 0);
500 if (initial_rotation > 3) 498 if (initial_rotation > 3)
501 initial_rotation = 0; 499 initial_rotation = 0;
500 continue;
502 } 501 }
503 } 502 }
504 return 1; 503 return 1;
@@ -3625,7 +3624,7 @@ static int __init fb_console_init(void)
3625 return 0; 3624 return 0;
3626} 3625}
3627 3626
3628module_init(fb_console_init); 3627fs_initcall(fb_console_init);
3629 3628
3630#ifdef MODULE 3629#ifdef MODULE
3631 3630
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 6e6aa704fe84..517f565b65d7 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -56,7 +56,7 @@ static int cursor_size_lastfrom;
56static int cursor_size_lastto; 56static int cursor_size_lastto;
57static u32 vgacon_xres; 57static u32 vgacon_xres;
58static u32 vgacon_yres; 58static u32 vgacon_yres;
59static struct vgastate state; 59static struct vgastate vgastate;
60 60
61#define BLANK 0x0020 61#define BLANK 0x0020
62 62
@@ -400,7 +400,7 @@ static const char *vgacon_startup(void)
400 400
401 vga_video_num_lines = screen_info.orig_video_lines; 401 vga_video_num_lines = screen_info.orig_video_lines;
402 vga_video_num_columns = screen_info.orig_video_cols; 402 vga_video_num_columns = screen_info.orig_video_cols;
403 state.vgabase = NULL; 403 vgastate.vgabase = NULL;
404 404
405 if (screen_info.orig_video_mode == 7) { 405 if (screen_info.orig_video_mode == 7) {
406 /* Monochrome display */ 406 /* Monochrome display */
@@ -851,12 +851,12 @@ static void vga_set_palette(struct vc_data *vc, unsigned char *table)
851{ 851{
852 int i, j; 852 int i, j;
853 853
854 vga_w(state.vgabase, VGA_PEL_MSK, 0xff); 854 vga_w(vgastate.vgabase, VGA_PEL_MSK, 0xff);
855 for (i = j = 0; i < 16; i++) { 855 for (i = j = 0; i < 16; i++) {
856 vga_w(state.vgabase, VGA_PEL_IW, table[i]); 856 vga_w(vgastate.vgabase, VGA_PEL_IW, table[i]);
857 vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); 857 vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
858 vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); 858 vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
859 vga_w(state.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2); 859 vga_w(vgastate.vgabase, VGA_PEL_D, vc->vc_palette[j++] >> 2);
860 } 860 }
861} 861}
862 862
@@ -1008,7 +1008,7 @@ static int vgacon_blank(struct vc_data *c, int blank, int mode_switch)
1008 switch (blank) { 1008 switch (blank) {
1009 case 0: /* Unblank */ 1009 case 0: /* Unblank */
1010 if (vga_vesa_blanked) { 1010 if (vga_vesa_blanked) {
1011 vga_vesa_unblank(&state); 1011 vga_vesa_unblank(&vgastate);
1012 vga_vesa_blanked = 0; 1012 vga_vesa_blanked = 0;
1013 } 1013 }
1014 if (vga_palette_blanked) { 1014 if (vga_palette_blanked) {
@@ -1022,7 +1022,7 @@ static int vgacon_blank(struct vc_data *c, int blank, int mode_switch)
1022 case 1: /* Normal blanking */ 1022 case 1: /* Normal blanking */
1023 case -1: /* Obsolete */ 1023 case -1: /* Obsolete */
1024 if (!mode_switch && vga_video_type == VIDEO_TYPE_VGAC) { 1024 if (!mode_switch && vga_video_type == VIDEO_TYPE_VGAC) {
1025 vga_pal_blank(&state); 1025 vga_pal_blank(&vgastate);
1026 vga_palette_blanked = 1; 1026 vga_palette_blanked = 1;
1027 return 0; 1027 return 0;
1028 } 1028 }
@@ -1034,7 +1034,7 @@ static int vgacon_blank(struct vc_data *c, int blank, int mode_switch)
1034 return 1; 1034 return 1;
1035 default: /* VESA blanking */ 1035 default: /* VESA blanking */
1036 if (vga_video_type == VIDEO_TYPE_VGAC) { 1036 if (vga_video_type == VIDEO_TYPE_VGAC) {
1037 vga_vesa_blank(&state, blank - 1); 1037 vga_vesa_blank(&vgastate, blank - 1);
1038 vga_vesa_blanked = blank; 1038 vga_vesa_blanked = blank;
1039 } 1039 }
1040 return 0; 1040 return 0;
@@ -1280,7 +1280,7 @@ static int vgacon_font_set(struct vc_data *c, struct console_font *font, unsigne
1280 (charcount != 256 && charcount != 512)) 1280 (charcount != 256 && charcount != 512))
1281 return -EINVAL; 1281 return -EINVAL;
1282 1282
1283 rc = vgacon_do_font_op(&state, font->data, 1, charcount == 512); 1283 rc = vgacon_do_font_op(&vgastate, font->data, 1, charcount == 512);
1284 if (rc) 1284 if (rc)
1285 return rc; 1285 return rc;
1286 1286
@@ -1299,7 +1299,7 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font)
1299 font->charcount = vga_512_chars ? 512 : 256; 1299 font->charcount = vga_512_chars ? 512 : 256;
1300 if (!font->data) 1300 if (!font->data)
1301 return 0; 1301 return 0;
1302 return vgacon_do_font_op(&state, font->data, 0, vga_512_chars); 1302 return vgacon_do_font_op(&vgastate, font->data, 0, vga_512_chars);
1303} 1303}
1304 1304
1305#else 1305#else
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index c7bf606a8706..4916c97216f8 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -999,23 +999,6 @@ config FB_ATMEL
999 help 999 help
1000 This enables support for the AT91/AT32 LCD Controller. 1000 This enables support for the AT91/AT32 LCD Controller.
1001 1001
1002config FB_INTSRAM
1003 bool "Frame Buffer in internal SRAM"
1004 depends on FB_ATMEL && ARCH_AT91SAM9261
1005 help
1006 Say Y if you want to map Frame Buffer in internal SRAM. Say N if you want
1007 to let frame buffer in external SDRAM.
1008
1009config FB_ATMEL_STN
1010 bool "Use a STN display with AT91/AT32 LCD Controller"
1011 depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK)
1012 default n
1013 help
1014 Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD
1015 Controller. Say N if you want to connect a TFT.
1016
1017 If unsure, say N.
1018
1019config FB_NVIDIA 1002config FB_NVIDIA
1020 tristate "nVidia Framebuffer Support" 1003 tristate "nVidia Framebuffer Support"
1021 depends on FB && PCI 1004 depends on FB && PCI
@@ -2425,7 +2408,7 @@ config FB_JZ4740
2425 2408
2426config FB_MXS 2409config FB_MXS
2427 tristate "MXS LCD framebuffer support" 2410 tristate "MXS LCD framebuffer support"
2428 depends on FB && ARCH_MXS 2411 depends on FB && (ARCH_MXS || ARCH_MXC)
2429 select FB_CFB_FILLRECT 2412 select FB_CFB_FILLRECT
2430 select FB_CFB_COPYAREA 2413 select FB_CFB_COPYAREA
2431 select FB_CFB_IMAGEBLIT 2414 select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/fbdev/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c
index 6ad23bd3523a..32c0b6b28097 100644
--- a/drivers/video/fbdev/amba-clcd.c
+++ b/drivers/video/fbdev/amba-clcd.c
@@ -27,7 +27,6 @@
27#include <linux/bitops.h> 27#include <linux/bitops.h>
28#include <linux/clk.h> 28#include <linux/clk.h>
29#include <linux/hardirq.h> 29#include <linux/hardirq.h>
30#include <linux/dma-mapping.h>
31#include <linux/of.h> 30#include <linux/of.h>
32#include <linux/of_address.h> 31#include <linux/of_address.h>
33#include <linux/of_graph.h> 32#include <linux/of_graph.h>
diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c
index adc4ea2cc5a0..b305a1e7cc76 100644
--- a/drivers/video/fbdev/arkfb.c
+++ b/drivers/video/fbdev/arkfb.c
@@ -1016,7 +1016,7 @@ static int ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
1016 1016
1017 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg); 1017 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg);
1018 1018
1019 par->state.vgabase = (void __iomem *) vga_res.start; 1019 par->state.vgabase = (void __iomem *) (unsigned long) vga_res.start;
1020 1020
1021 /* FIXME get memsize */ 1021 /* FIXME get memsize */
1022 regval = vga_rseq(par->state.vgabase, 0x10); 1022 regval = vga_rseq(par->state.vgabase, 0x10);
diff --git a/drivers/video/fbdev/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
index 3bf403150a2d..9ec81d46fc57 100644
--- a/drivers/video/fbdev/atmel_lcdfb.c
+++ b/drivers/video/fbdev/atmel_lcdfb.c
@@ -27,7 +27,6 @@
27#include <linux/regulator/consumer.h> 27#include <linux/regulator/consumer.h>
28#include <video/videomode.h> 28#include <video/videomode.h>
29 29
30#include <mach/cpu.h>
31#include <asm/gpio.h> 30#include <asm/gpio.h>
32 31
33#include <video/atmel_lcdc.h> 32#include <video/atmel_lcdc.h>
diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c
index cee9602f9a7b..716bfad6a1c0 100644
--- a/drivers/video/fbdev/exynos/exynos_mipi_dsi.c
+++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c
@@ -570,5 +570,5 @@ static struct platform_driver exynos_mipi_dsi_driver = {
570module_platform_driver(exynos_mipi_dsi_driver); 570module_platform_driver(exynos_mipi_dsi_driver);
571 571
572MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>"); 572MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
573MODULE_DESCRIPTION("Samusung SoC MIPI-DSI driver"); 573MODULE_DESCRIPTION("Samsung SoC MIPI-DSI driver");
574MODULE_LICENSE("GPL"); 574MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c
index 85edabfdef5a..2358a2fbbbcd 100644
--- a/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c
+++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c
@@ -876,5 +876,5 @@ int exynos_mipi_dsi_fifo_clear(struct mipi_dsim_device *dsim,
876} 876}
877 877
878MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>"); 878MODULE_AUTHOR("InKi Dae <inki.dae@samsung.com>");
879MODULE_DESCRIPTION("Samusung SoC MIPI-DSI common driver"); 879MODULE_DESCRIPTION("Samsung SoC MIPI-DSI common driver");
880MODULE_LICENSE("GPL"); 880MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbdev/gbefb.c b/drivers/video/fbdev/gbefb.c
index 4aa56ba78f32..6d9ef39810c8 100644
--- a/drivers/video/fbdev/gbefb.c
+++ b/drivers/video/fbdev/gbefb.c
@@ -54,7 +54,8 @@ struct gbefb_par {
54#endif 54#endif
55#endif 55#endif
56#ifdef CONFIG_X86 56#ifdef CONFIG_X86
57#define pgprot_fb(_prot) ((_prot) | _PAGE_PCD) 57#define pgprot_fb(_prot) (((_prot) & ~_PAGE_CACHE_MASK) | \
58 cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS))
58#endif 59#endif
59 60
60/* 61/*
diff --git a/drivers/video/fbdev/mmp/core.c b/drivers/video/fbdev/mmp/core.c
index b563b920f159..a0f496049db7 100644
--- a/drivers/video/fbdev/mmp/core.c
+++ b/drivers/video/fbdev/mmp/core.c
@@ -223,10 +223,10 @@ struct mmp_path *mmp_register_path(struct mmp_path_info *info)
223EXPORT_SYMBOL_GPL(mmp_register_path); 223EXPORT_SYMBOL_GPL(mmp_register_path);
224 224
225/* 225/*
226 * mmp_unregister_path - unregister and destory path 226 * mmp_unregister_path - unregister and destroy path
227 * @p: path to be destoried. 227 * @p: path to be destroyed.
228 * 228 *
229 * this function registers path and destorys it. 229 * this function registers path and destroys it.
230 */ 230 */
231void mmp_unregister_path(struct mmp_path *path) 231void mmp_unregister_path(struct mmp_path *path)
232{ 232{
diff --git a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
index 8621a9f2bdcc..3c12bd83b561 100644
--- a/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
+++ b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
@@ -441,8 +441,7 @@ static void path_deinit(struct mmphw_path_plat *path_plat)
441 if (!path_plat) 441 if (!path_plat)
442 return; 442 return;
443 443
444 if (path_plat->path) 444 mmp_unregister_path(path_plat->path);
445 mmp_unregister_path(path_plat->path);
446} 445}
447 446
448static int mmphw_probe(struct platform_device *pdev) 447static int mmphw_probe(struct platform_device *pdev)
diff --git a/drivers/video/fbdev/mx3fb.c b/drivers/video/fbdev/mx3fb.c
index 23ec781e9a61..f23fca0be9d7 100644
--- a/drivers/video/fbdev/mx3fb.c
+++ b/drivers/video/fbdev/mx3fb.c
@@ -334,8 +334,7 @@ static void mx3fb_init_backlight(struct mx3fb_data *fbd)
334 334
335static void mx3fb_exit_backlight(struct mx3fb_data *fbd) 335static void mx3fb_exit_backlight(struct mx3fb_data *fbd)
336{ 336{
337 if (fbd->bl) 337 backlight_device_unregister(fbd->bl);
338 backlight_device_unregister(fbd->bl);
339} 338}
340 339
341static void mx3fb_dma_done(void *); 340static void mx3fb_dma_done(void *);
diff --git a/drivers/video/fbdev/mxsfb.c b/drivers/video/fbdev/mxsfb.c
index accf48a2cce4..f8ac4a452f26 100644
--- a/drivers/video/fbdev/mxsfb.c
+++ b/drivers/video/fbdev/mxsfb.c
@@ -172,6 +172,8 @@ struct mxsfb_info {
172 struct fb_info fb_info; 172 struct fb_info fb_info;
173 struct platform_device *pdev; 173 struct platform_device *pdev;
174 struct clk *clk; 174 struct clk *clk;
175 struct clk *clk_axi;
176 struct clk *clk_disp_axi;
175 void __iomem *base; /* registers */ 177 void __iomem *base; /* registers */
176 unsigned allocated_size; 178 unsigned allocated_size;
177 int enabled; 179 int enabled;
@@ -331,6 +333,11 @@ static void mxsfb_enable_controller(struct fb_info *fb_info)
331 } 333 }
332 } 334 }
333 335
336 if (host->clk_axi)
337 clk_prepare_enable(host->clk_axi);
338
339 if (host->clk_disp_axi)
340 clk_prepare_enable(host->clk_disp_axi);
334 clk_prepare_enable(host->clk); 341 clk_prepare_enable(host->clk);
335 clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U); 342 clk_set_rate(host->clk, PICOS2KHZ(fb_info->var.pixclock) * 1000U);
336 343
@@ -374,6 +381,10 @@ static void mxsfb_disable_controller(struct fb_info *fb_info)
374 writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4); 381 writel(reg & ~VDCTRL4_SYNC_SIGNALS_ON, host->base + LCDC_VDCTRL4);
375 382
376 clk_disable_unprepare(host->clk); 383 clk_disable_unprepare(host->clk);
384 if (host->clk_disp_axi)
385 clk_disable_unprepare(host->clk_disp_axi);
386 if (host->clk_axi)
387 clk_disable_unprepare(host->clk_axi);
377 388
378 host->enabled = 0; 389 host->enabled = 0;
379 390
@@ -867,6 +878,14 @@ static int mxsfb_probe(struct platform_device *pdev)
867 goto fb_release; 878 goto fb_release;
868 } 879 }
869 880
881 host->clk_axi = devm_clk_get(&host->pdev->dev, "axi");
882 if (IS_ERR(host->clk_axi))
883 host->clk_axi = NULL;
884
885 host->clk_disp_axi = devm_clk_get(&host->pdev->dev, "disp_axi");
886 if (IS_ERR(host->clk_disp_axi))
887 host->clk_disp_axi = NULL;
888
870 host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd"); 889 host->reg_lcd = devm_regulator_get(&pdev->dev, "lcd");
871 if (IS_ERR(host->reg_lcd)) 890 if (IS_ERR(host->reg_lcd))
872 host->reg_lcd = NULL; 891 host->reg_lcd = NULL;
diff --git a/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
index 5ee3b5505f7f..91921665b98b 100644
--- a/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
@@ -301,6 +301,8 @@ static const struct of_device_id tvc_of_match[] = {
301 {}, 301 {},
302}; 302};
303 303
304MODULE_DEVICE_TABLE(of, tvc_of_match);
305
304static struct platform_driver tvc_connector_driver = { 306static struct platform_driver tvc_connector_driver = {
305 .probe = tvc_probe, 307 .probe = tvc_probe,
306 .remove = __exit_p(tvc_remove), 308 .remove = __exit_p(tvc_remove),
@@ -308,6 +310,7 @@ static struct platform_driver tvc_connector_driver = {
308 .name = "connector-analog-tv", 310 .name = "connector-analog-tv",
309 .owner = THIS_MODULE, 311 .owner = THIS_MODULE,
310 .of_match_table = tvc_of_match, 312 .of_match_table = tvc_of_match,
313 .suppress_bind_attrs = true,
311 }, 314 },
312}; 315};
313 316
diff --git a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
index 74de2bc50c4f..3d38e478bc64 100644
--- a/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
@@ -262,8 +262,7 @@ static int dvic_probe_pdata(struct platform_device *pdev)
262 262
263 in = omap_dss_find_output(pdata->source); 263 in = omap_dss_find_output(pdata->source);
264 if (in == NULL) { 264 if (in == NULL) {
265 if (ddata->i2c_adapter) 265 i2c_put_adapter(ddata->i2c_adapter);
266 i2c_put_adapter(ddata->i2c_adapter);
267 266
268 dev_err(&pdev->dev, "Failed to find video source\n"); 267 dev_err(&pdev->dev, "Failed to find video source\n");
269 return -EPROBE_DEFER; 268 return -EPROBE_DEFER;
@@ -352,8 +351,7 @@ static int dvic_probe(struct platform_device *pdev)
352err_reg: 351err_reg:
353 omap_dss_put_device(ddata->in); 352 omap_dss_put_device(ddata->in);
354 353
355 if (ddata->i2c_adapter) 354 i2c_put_adapter(ddata->i2c_adapter);
356 i2c_put_adapter(ddata->i2c_adapter);
357 355
358 return r; 356 return r;
359} 357}
@@ -371,8 +369,7 @@ static int __exit dvic_remove(struct platform_device *pdev)
371 369
372 omap_dss_put_device(in); 370 omap_dss_put_device(in);
373 371
374 if (ddata->i2c_adapter) 372 i2c_put_adapter(ddata->i2c_adapter);
375 i2c_put_adapter(ddata->i2c_adapter);
376 373
377 return 0; 374 return 0;
378} 375}
@@ -391,6 +388,7 @@ static struct platform_driver dvi_connector_driver = {
391 .name = "connector-dvi", 388 .name = "connector-dvi",
392 .owner = THIS_MODULE, 389 .owner = THIS_MODULE,
393 .of_match_table = dvic_of_match, 390 .of_match_table = dvic_of_match,
391 .suppress_bind_attrs = true,
394 }, 392 },
395}; 393};
396 394
diff --git a/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
index 131c6e260898..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)
@@ -437,6 +338,7 @@ static struct platform_driver hdmi_connector_driver = {
437 .name = "connector-hdmi", 338 .name = "connector-hdmi",
438 .owner = THIS_MODULE, 339 .owner = THIS_MODULE,
439 .of_match_table = hdmic_of_match, 340 .of_match_table = hdmic_of_match,
341 .suppress_bind_attrs = true,
440 }, 342 },
441}; 343};
442 344
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
index b4e9a42a79e6..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) {
@@ -298,6 +299,7 @@ static struct platform_driver tfp410_driver = {
298 .name = "tfp410", 299 .name = "tfp410",
299 .owner = THIS_MODULE, 300 .owner = THIS_MODULE,
300 .of_match_table = tfp410_of_match, 301 .of_match_table = tfp410_of_match,
302 .suppress_bind_attrs = true,
301 }, 303 },
302}; 304};
303 305
diff --git a/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
index c891d8f84cb2..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
@@ -461,6 +406,7 @@ static struct platform_driver tpd_driver = {
461 .name = "tpd12s015", 406 .name = "tpd12s015",
462 .owner = THIS_MODULE, 407 .owner = THIS_MODULE,
463 .of_match_table = tpd_of_match, 408 .of_match_table = tpd_of_match,
409 .suppress_bind_attrs = true,
464 }, 410 },
465}; 411};
466 412
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-dpi.c b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c
index 3636b61dc9b4..a9c3dcf0f6b5 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-dpi.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c
@@ -327,6 +327,7 @@ static struct platform_driver panel_dpi_driver = {
327 .name = "panel-dpi", 327 .name = "panel-dpi",
328 .owner = THIS_MODULE, 328 .owner = THIS_MODULE,
329 .of_match_table = panel_dpi_of_match, 329 .of_match_table = panel_dpi_of_match,
330 .suppress_bind_attrs = true,
330 }, 331 },
331}; 332};
332 333
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c b/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c
index d6f14e8717e8..899cb1ab523d 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c
@@ -1378,6 +1378,7 @@ static struct platform_driver dsicm_driver = {
1378 .name = "panel-dsi-cm", 1378 .name = "panel-dsi-cm",
1379 .owner = THIS_MODULE, 1379 .owner = THIS_MODULE,
1380 .of_match_table = dsicm_of_match, 1380 .of_match_table = dsicm_of_match,
1381 .suppress_bind_attrs = true,
1381 }, 1382 },
1382}; 1383};
1383 1384
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 cc5b5124e0b4..27d4fcfa1824 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
@@ -394,6 +394,7 @@ static struct spi_driver lb035q02_spi_driver = {
394 .name = "panel_lgphilips_lb035q02", 394 .name = "panel_lgphilips_lb035q02",
395 .owner = THIS_MODULE, 395 .owner = THIS_MODULE,
396 .of_match_table = lb035q02_of_match, 396 .of_match_table = lb035q02_of_match,
397 .suppress_bind_attrs = true,
397 }, 398 },
398}; 399};
399 400
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c b/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c
index 3595f111aa35..ccf3f4f3c703 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c
@@ -424,6 +424,7 @@ static struct spi_driver nec_8048_driver = {
424 .owner = THIS_MODULE, 424 .owner = THIS_MODULE,
425 .pm = NEC_8048_PM_OPS, 425 .pm = NEC_8048_PM_OPS,
426 .of_match_table = nec_8048_of_match, 426 .of_match_table = nec_8048_of_match,
427 .suppress_bind_attrs = true,
427 }, 428 },
428 .probe = nec_8048_probe, 429 .probe = nec_8048_probe,
429 .remove = nec_8048_remove, 430 .remove = nec_8048_remove,
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 f1f72ce50a17..234142cc3764 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
@@ -410,6 +410,7 @@ static struct platform_driver sharp_ls_driver = {
410 .name = "panel-sharp-ls037v7dw01", 410 .name = "panel-sharp-ls037v7dw01",
411 .owner = THIS_MODULE, 411 .owner = THIS_MODULE,
412 .of_match_table = sharp_ls_of_match, 412 .of_match_table = sharp_ls_of_match,
413 .suppress_bind_attrs = true,
413 }, 414 },
414}; 415};
415 416
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
index 617f8d2f5127..337ccc5c0f5e 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
@@ -904,6 +904,7 @@ static struct spi_driver acx565akm_driver = {
904 .name = "acx565akm", 904 .name = "acx565akm",
905 .owner = THIS_MODULE, 905 .owner = THIS_MODULE,
906 .of_match_table = acx565akm_of_match, 906 .of_match_table = acx565akm_of_match,
907 .suppress_bind_attrs = true,
907 }, 908 },
908 .probe = acx565akm_probe, 909 .probe = acx565akm_probe,
909 .remove = acx565akm_remove, 910 .remove = acx565akm_remove,
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
index 728808bcceeb..fbba0b8ca871 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
@@ -500,6 +500,7 @@ static struct spi_driver td028ttec1_spi_driver = {
500 .name = "panel-tpo-td028ttec1", 500 .name = "panel-tpo-td028ttec1",
501 .owner = THIS_MODULE, 501 .owner = THIS_MODULE,
502 .of_match_table = td028ttec1_of_match, 502 .of_match_table = td028ttec1_of_match,
503 .suppress_bind_attrs = true,
503 }, 504 },
504}; 505};
505 506
diff --git a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c
index de78ab0caaa8..5aba76bca25a 100644
--- a/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c
@@ -673,6 +673,7 @@ static struct spi_driver tpo_td043_spi_driver = {
673 .owner = THIS_MODULE, 673 .owner = THIS_MODULE,
674 .pm = &tpo_td043_spi_pm, 674 .pm = &tpo_td043_spi_pm,
675 .of_match_table = tpo_td043_of_match, 675 .of_match_table = tpo_td043_of_match,
676 .suppress_bind_attrs = true,
676 }, 677 },
677 .probe = tpo_td043_probe, 678 .probe = tpo_td043_probe,
678 .remove = tpo_td043_remove, 679 .remove = tpo_td043_remove,
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/apply.c b/drivers/video/fbdev/omap2/dss/apply.c
index 0a0b084ce65d..663ccc3bf4e5 100644
--- a/drivers/video/fbdev/omap2/dss/apply.c
+++ b/drivers/video/fbdev/omap2/dss/apply.c
@@ -1132,6 +1132,8 @@ static void dss_mgr_disable_compat(struct omap_overlay_manager *mgr)
1132 if (!mp->enabled) 1132 if (!mp->enabled)
1133 goto out; 1133 goto out;
1134 1134
1135 wait_pending_extra_info_updates();
1136
1135 if (!mgr_manual_update(mgr)) 1137 if (!mgr_manual_update(mgr))
1136 dispc_mgr_disable_sync(mgr->id); 1138 dispc_mgr_disable_sync(mgr->id);
1137 1139
diff --git a/drivers/video/fbdev/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index be053aa80880..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();
@@ -3290,8 +3290,11 @@ static void dispc_dump_regs(struct seq_file *s)
3290 DUMPREG(i, DISPC_OVL_FIFO_SIZE_STATUS); 3290 DUMPREG(i, DISPC_OVL_FIFO_SIZE_STATUS);
3291 DUMPREG(i, DISPC_OVL_ROW_INC); 3291 DUMPREG(i, DISPC_OVL_ROW_INC);
3292 DUMPREG(i, DISPC_OVL_PIXEL_INC); 3292 DUMPREG(i, DISPC_OVL_PIXEL_INC);
3293
3293 if (dss_has_feature(FEAT_PRELOAD)) 3294 if (dss_has_feature(FEAT_PRELOAD))
3294 DUMPREG(i, DISPC_OVL_PRELOAD); 3295 DUMPREG(i, DISPC_OVL_PRELOAD);
3296 if (dss_has_feature(FEAT_MFLAG))
3297 DUMPREG(i, DISPC_OVL_MFLAG_THRESHOLD);
3295 3298
3296 if (i == OMAP_DSS_GFX) { 3299 if (i == OMAP_DSS_GFX) {
3297 DUMPREG(i, DISPC_OVL_WINDOW_SKIP); 3300 DUMPREG(i, DISPC_OVL_WINDOW_SKIP);
@@ -3312,10 +3315,6 @@ static void dispc_dump_regs(struct seq_file *s)
3312 } 3315 }
3313 if (dss_has_feature(FEAT_ATTR2)) 3316 if (dss_has_feature(FEAT_ATTR2))
3314 DUMPREG(i, DISPC_OVL_ATTRIBUTES2); 3317 DUMPREG(i, DISPC_OVL_ATTRIBUTES2);
3315 if (dss_has_feature(FEAT_PRELOAD))
3316 DUMPREG(i, DISPC_OVL_PRELOAD);
3317 if (dss_has_feature(FEAT_MFLAG))
3318 DUMPREG(i, DISPC_OVL_MFLAG_THRESHOLD);
3319 } 3318 }
3320 3319
3321#undef DISPC_REG 3320#undef DISPC_REG
@@ -3843,6 +3842,7 @@ static struct platform_driver omap_dispchw_driver = {
3843 .owner = THIS_MODULE, 3842 .owner = THIS_MODULE,
3844 .pm = &dispc_pm_ops, 3843 .pm = &dispc_pm_ops,
3845 .of_match_table = dispc_of_match, 3844 .of_match_table = dispc_of_match,
3845 .suppress_bind_attrs = true,
3846 }, 3846 },
3847}; 3847};
3848 3848
diff --git a/drivers/video/fbdev/omap2/dss/dispc.h b/drivers/video/fbdev/omap2/dss/dispc.h
index 78edb449c763..3043d6e0a5f9 100644
--- a/drivers/video/fbdev/omap2/dss/dispc.h
+++ b/drivers/video/fbdev/omap2/dss/dispc.h
@@ -101,8 +101,7 @@
101 DISPC_FIR_COEF_V2_OFFSET(n, i)) 101 DISPC_FIR_COEF_V2_OFFSET(n, i))
102#define DISPC_OVL_PRELOAD(n) (DISPC_OVL_BASE(n) + \ 102#define DISPC_OVL_PRELOAD(n) (DISPC_OVL_BASE(n) + \
103 DISPC_PRELOAD_OFFSET(n)) 103 DISPC_PRELOAD_OFFSET(n))
104#define DISPC_OVL_MFLAG_THRESHOLD(n) (DISPC_OVL_BASE(n) + \ 104#define DISPC_OVL_MFLAG_THRESHOLD(n) DISPC_MFLAG_THRESHOLD_OFFSET(n)
105 DISPC_MFLAG_THRESHOLD_OFFSET(n))
106 105
107/* DISPC up/downsampling FIR filter coefficient structure */ 106/* DISPC up/downsampling FIR filter coefficient structure */
108struct dispc_coef { 107struct dispc_coef {
diff --git a/drivers/video/fbdev/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index 9368972d6962..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
@@ -720,6 +789,7 @@ static struct platform_driver omap_dpi_driver = {
720 .driver = { 789 .driver = {
721 .name = "omapdss_dpi", 790 .name = "omapdss_dpi",
722 .owner = THIS_MODULE, 791 .owner = THIS_MODULE,
792 .suppress_bind_attrs = true,
723 }, 793 },
724}; 794};
725 795
@@ -735,10 +805,15 @@ void __exit dpi_uninit_platform_driver(void)
735 805
736int __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)
737{ 807{
808 struct dpi_data *dpi;
738 struct device_node *ep; 809 struct device_node *ep;
739 u32 datalines; 810 u32 datalines;
740 int r; 811 int r;
741 812
813 dpi = devm_kzalloc(&pdev->dev, sizeof(*dpi), GFP_KERNEL);
814 if (!dpi)
815 return -ENOMEM;
816
742 ep = omapdss_of_get_next_endpoint(port, NULL); 817 ep = omapdss_of_get_next_endpoint(port, NULL);
743 if (!ep) 818 if (!ep)
744 return 0; 819 return 0;
@@ -749,17 +824,18 @@ int __init dpi_init_port(struct platform_device *pdev, struct device_node *port)
749 goto err_datalines; 824 goto err_datalines;
750 } 825 }
751 826
752 dpi.data_lines = datalines; 827 dpi->data_lines = datalines;
753 828
754 of_node_put(ep); 829 of_node_put(ep);
755 830
756 dpi.pdev = pdev; 831 dpi->pdev = pdev;
832 port->data = dpi;
757 833
758 mutex_init(&dpi.lock); 834 mutex_init(&dpi->lock);
759 835
760 dpi_init_output(pdev); 836 dpi_init_output_port(pdev, port);
761 837
762 dpi.port_initialized = true; 838 dpi->port_initialized = true;
763 839
764 return 0; 840 return 0;
765 841
@@ -769,10 +845,12 @@ err_datalines:
769 return r; 845 return r;
770} 846}
771 847
772void __exit dpi_uninit_port(void) 848void __exit dpi_uninit_port(struct device_node *port)
773{ 849{
774 if (!dpi.port_initialized) 850 struct dpi_data *dpi = port->data;
851
852 if (!dpi->port_initialized)
775 return; 853 return;
776 854
777 dpi_uninit_output(dpi.pdev); 855 dpi_uninit_output_port(port);
778} 856}
diff --git a/drivers/video/fbdev/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index b6f6ae1d4664..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, 4, 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);
@@ -5754,6 +5575,7 @@ static struct platform_driver omap_dsihw_driver = {
5754 .owner = THIS_MODULE, 5575 .owner = THIS_MODULE,
5755 .pm = &dsi_pm_ops, 5576 .pm = &dsi_pm_ops,
5756 .of_match_table = dsi_of_match, 5577 .of_match_table = dsi_of_match,
5578 .suppress_bind_attrs = true,
5757 }, 5579 },
5758}; 5580};
5759 5581
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 6daeb7ed44c6..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
@@ -966,6 +1015,7 @@ static struct platform_driver omap_dsshw_driver = {
966 .owner = THIS_MODULE, 1015 .owner = THIS_MODULE,
967 .pm = &dss_pm_ops, 1016 .pm = &dss_pm_ops,
968 .of_match_table = dss_of_match, 1017 .of_match_table = dss_of_match,
1018 .suppress_bind_attrs = true,
969 }, 1019 },
970}; 1020};
971 1021
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 6a8550cf43e5..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
@@ -781,6 +763,7 @@ static struct platform_driver omapdss_hdmihw_driver = {
781 .owner = THIS_MODULE, 763 .owner = THIS_MODULE,
782 .pm = &hdmi_pm_ops, 764 .pm = &hdmi_pm_ops,
783 .of_match_table = hdmi_of_match, 765 .of_match_table = hdmi_of_match,
766 .suppress_bind_attrs = true,
784 }, 767 },
785}; 768};
786 769
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 32d02ec34d23..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
@@ -806,6 +798,7 @@ static struct platform_driver omapdss_hdmihw_driver = {
806 .owner = THIS_MODULE, 798 .owner = THIS_MODULE,
807 .pm = &hdmi_pm_ops, 799 .pm = &hdmi_pm_ops,
808 .of_match_table = hdmi_of_match, 800 .of_match_table = hdmi_of_match,
801 .suppress_bind_attrs = true,
809 }, 802 },
810}; 803};
811 804
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 54df12a8d744..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,229 +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;
59 47 unsigned n, m, mf, m2, sd;
60 /* use our funky units */ 48 unsigned long clkin;
61 clkin /= 10000; 49 const struct dss_pll_hw *hw = pll->pll.hw;
62
63 /*
64 * Input clock is predivided by N + 1
65 * out put of which is reference clk
66 */
67 50
68 pi->regn = HDMI_DEFAULT_REGN; 51 clkin = clk_get_rate(pll->pll.clkin);
69 52
70 refclk = clkin / pi->regn; 53 DSSDBG("clkin %lu, target tmds %lu\n", clkin, target_tmds);
71 54
72 /* temorary hack to make sure DCO freq isn't calculated too low */ 55 target_bitclk = target_tmds * 10;
73 if (pll_feat->bound_dcofreq && phy <= 65000)
74 pi->regm2 = 3;
75 else
76 pi->regm2 = HDMI_DEFAULT_REGM2;
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 56
57 /* Fint */
58 n = DIV_ROUND_UP(clkin, hw->fint_max);
59 fint = clkin / n;
106 60
107static int hdmi_pll_config(struct hdmi_pll_data *pll) 61 /* adjust m2 so that the clkdco will be high enough */
108{ 62 min_dco = roundup(hw->clkdco_min, fint);
109 u32 r; 63 m2 = DIV_ROUND_UP(min_dco, target_bitclk);
110 struct hdmi_pll_info *fmt = &pll->info; 64 if (m2 == 0)
111 65 m2 = 1;
112 /* PLL start always use manual mode */
113 REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, 0x0, 0, 0);
114
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 /* divider programming for frequency beyond 1000Mhz */
129 REG_FLD_MOD(pll->base, PLLCTRL_CFG3, fmt->regsd, 17, 10);
130 r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */
131 } else {
132 r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */
133 }
134 66
135 hdmi_write_reg(pll->base, PLLCTRL_CFG2, r); 67 target_clkdco = target_bitclk * m2;
68 m = target_clkdco / fint;
136 69
137 r = hdmi_read_reg(pll->base, PLLCTRL_CFG4); 70 clkdco = fint * m;
138 r = FLD_MOD(r, fmt->regm2, 24, 18);
139 r = FLD_MOD(r, fmt->regmf, 17, 0);
140 hdmi_write_reg(pll->base, PLLCTRL_CFG4, r);
141 71
142 /* go now */ 72 /* adjust clkdco with fractional mf */
143 REG_FLD_MOD(pll->base, PLLCTRL_PLL_GO, 0x1, 0, 0); 73 if (WARN_ON(target_clkdco - clkdco > fint))
74 mf = 0;
75 else
76 mf = (u32)div_u64(262144ull * (target_clkdco - clkdco), fint);
144 77
145 /* wait for bit change */ 78 if (mf > 0)
146 if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_GO, 79 clkdco += (u32)div_u64((u64)mf * fint, 262144);
147 0, 0, 1) != 1) {
148 DSSERR("PLL GO bit not set\n");
149 return -ETIMEDOUT;
150 }
151 80
152 /* Wait till the lock bit is set in PLL status */ 81 clkout = clkdco / m2;
153 if (hdmi_wait_for_bit_change(pll->base,
154 PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) {
155 DSSERR("cannot lock PLL\n");
156 DSSERR("CFG1 0x%x\n",
157 hdmi_read_reg(pll->base, PLLCTRL_CFG1));
158 DSSERR("CFG2 0x%x\n",
159 hdmi_read_reg(pll->base, PLLCTRL_CFG2));
160 DSSERR("CFG4 0x%x\n",
161 hdmi_read_reg(pll->base, PLLCTRL_CFG4));
162 return -ETIMEDOUT;
163 }
164 82
165 DSSDBG("PLL locked!\n"); 83 /* sigma-delta */
84 sd = DIV_ROUND_UP(fint * m, 250000000);
166 85
167 return 0; 86 DSSDBG("N = %u, M = %u, M.f = %u, M2 = %u, SD = %u\n",
168} 87 n, m, mf, m2, sd);
88 DSSDBG("Fint %lu, clkdco %lu, clkout %lu\n", fint, clkdco, clkout);
169 89
170static int hdmi_pll_reset(struct hdmi_pll_data *pll) 90 pi->n = n;
171{ 91 pi->m = m;
172 /* SYSRESET controlled by power FSM */ 92 pi->mf = mf;
173 REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, pll_feat->sys_reset, 3, 3); 93 pi->mX[0] = m2;
174 94 pi->sd = sd;
175 /* READ 0x0 reset is in progress */
176 if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 0, 0, 1)
177 != 1) {
178 DSSERR("Failed to sysreset PLL\n");
179 return -ETIMEDOUT;
180 }
181 95
182 return 0; 96 pi->fint = fint;
97 pi->clkdco = clkdco;
98 pi->clkout[0] = clkout;
183} 99}
184 100
185int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp) 101static int hdmi_pll_enable(struct dss_pll *dsspll)
186{ 102{
103 struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
104 struct hdmi_wp_data *wp = pll->wp;
187 u16 r = 0; 105 u16 r = 0;
188 106
189 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
190 if (r)
191 return r;
192
193 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); 107 r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS);
194 if (r) 108 if (r)
195 return r; 109 return r;
196 110
197 r = hdmi_pll_reset(pll);
198 if (r)
199 return r;
200
201 r = hdmi_pll_config(pll);
202 if (r)
203 return r;
204
205 return 0; 111 return 0;
206} 112}
207 113
208void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp) 114static void hdmi_pll_disable(struct dss_pll *dsspll)
209{ 115{
116 struct hdmi_pll_data *pll = container_of(dsspll, struct hdmi_pll_data, pll);
117 struct hdmi_wp_data *wp = pll->wp;
118
210 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); 119 hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF);
211} 120}
212 121
213static const struct hdmi_pll_features omap44xx_pll_feats = { 122static const struct dss_pll_ops dsi_pll_ops = {
214 .sys_reset = false, 123 .enable = hdmi_pll_enable,
215 .bound_dcofreq = false, 124 .disable = hdmi_pll_disable,
216 .fint_min = 500000, 125 .set_config = dss_pll_write_config_type_b,
217 .fint_max = 2500000, 126};
218 .regm_max = 4095, 127
219 .dcofreq_low_min = 500000000, 128static const struct dss_pll_hw dss_omap4_hdmi_pll_hw = {
220 .dcofreq_low_max = 1000000000, 129 .n_max = 255,
221 .dcofreq_high_min = 1000000000, 130 .m_min = 20,
222 .dcofreq_high_max = 2000000000, 131 .m_max = 4095,
132 .mX_max = 127,
133 .fint_min = 500000,
134 .fint_max = 2500000,
135 .clkdco_max = 1800000000,
136
137 .clkdco_min = 500000000,
138 .clkdco_low = 1000000000,
139 .clkdco_max = 2000000000,
140
141 .n_msb = 8,
142 .n_lsb = 1,
143 .m_msb = 20,
144 .m_lsb = 9,
145
146 .mX_msb[0] = 24,
147 .mX_lsb[0] = 18,
148
149 .has_selfreqdco = true,
223}; 150};
224 151
225static const struct hdmi_pll_features omap54xx_pll_feats = { 152static const struct dss_pll_hw dss_omap5_hdmi_pll_hw = {
226 .sys_reset = true, 153 .n_max = 255,
227 .bound_dcofreq = true, 154 .m_min = 20,
228 .fint_min = 620000, 155 .m_max = 2045,
229 .fint_max = 2500000, 156 .mX_max = 127,
230 .regm_max = 2046, 157 .fint_min = 620000,
231 .dcofreq_low_min = 750000000, 158 .fint_max = 2500000,
232 .dcofreq_low_max = 1500000000, 159 .clkdco_max = 1800000000,
233 .dcofreq_high_min = 1250000000, 160
234 .dcofreq_high_max = 2500000000UL, 161 .clkdco_min = 750000000,
162 .clkdco_low = 1500000000,
163 .clkdco_max = 2500000000UL,
164
165 .n_msb = 8,
166 .n_lsb = 1,
167 .m_msb = 20,
168 .m_lsb = 9,
169
170 .mX_msb[0] = 24,
171 .mX_lsb[0] = 18,
172
173 .has_selfreqdco = true,
174 .has_refsel = true,
235}; 175};
236 176
237static int hdmi_pll_init_features(struct platform_device *pdev) 177static int dsi_init_pll_data(struct platform_device *pdev, struct hdmi_pll_data *hpll)
238{ 178{
239 struct hdmi_pll_features *dst; 179 struct dss_pll *pll = &hpll->pll;
240 const struct hdmi_pll_features *src; 180 struct clk *clk;
181 int r;
241 182
242 dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL); 183 clk = devm_clk_get(&pdev->dev, "sys_clk");
243 if (!dst) { 184 if (IS_ERR(clk)) {
244 dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n"); 185 DSSERR("can't get sys_clk\n");
245 return -ENOMEM; 186 return PTR_ERR(clk);
246 } 187 }
247 188
189 pll->name = "hdmi";
190 pll->base = hpll->base;
191 pll->clkin = clk;
192
248 switch (omapdss_get_version()) { 193 switch (omapdss_get_version()) {
249 case OMAPDSS_VER_OMAP4430_ES1: 194 case OMAPDSS_VER_OMAP4430_ES1:
250 case OMAPDSS_VER_OMAP4430_ES2: 195 case OMAPDSS_VER_OMAP4430_ES2:
251 case OMAPDSS_VER_OMAP4: 196 case OMAPDSS_VER_OMAP4:
252 src = &omap44xx_pll_feats; 197 pll->hw = &dss_omap4_hdmi_pll_hw;
253 break; 198 break;
254 199
255 case OMAPDSS_VER_OMAP5: 200 case OMAPDSS_VER_OMAP5:
256 src = &omap54xx_pll_feats; 201 pll->hw = &dss_omap5_hdmi_pll_hw;
257 break; 202 break;
258 203
259 default: 204 default:
260 return -ENODEV; 205 return -ENODEV;
261 } 206 }
262 207
263 memcpy(dst, src, sizeof(*dst)); 208 pll->ops = &dsi_pll_ops;
264 pll_feat = dst; 209
210 r = dss_pll_register(pll);
211 if (r)
212 return r;
265 213
266 return 0; 214 return 0;
267} 215}
268 216
269int 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)
270{ 219{
271 int r; 220 int r;
272 struct resource *res; 221 struct resource *res;
273 222
274 r = hdmi_pll_init_features(pdev); 223 pll->wp = wp;
275 if (r)
276 return r;
277 224
278 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll"); 225 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll");
279 if (!res) { 226 if (!res) {
@@ -287,5 +234,18 @@ int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll)
287 return PTR_ERR(pll->base); 234 return PTR_ERR(pll->base);
288 } 235 }
289 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
290 return 0; 243 return 0;
291} 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/rfbi.c b/drivers/video/fbdev/omap2/dss/rfbi.c
index c8a81a2b879c..878273f58839 100644
--- a/drivers/video/fbdev/omap2/dss/rfbi.c
+++ b/drivers/video/fbdev/omap2/dss/rfbi.c
@@ -1044,6 +1044,7 @@ static struct platform_driver omap_rfbihw_driver = {
1044 .name = "omapdss_rfbi", 1044 .name = "omapdss_rfbi",
1045 .owner = THIS_MODULE, 1045 .owner = THIS_MODULE,
1046 .pm = &rfbi_pm_ops, 1046 .pm = &rfbi_pm_ops,
1047 .suppress_bind_attrs = true,
1047 }, 1048 },
1048}; 1049};
1049 1050
diff --git a/drivers/video/fbdev/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c
index 911dcc9173a6..d9b10f27be20 100644
--- a/drivers/video/fbdev/omap2/dss/sdi.c
+++ b/drivers/video/fbdev/omap2/dss/sdi.c
@@ -377,6 +377,7 @@ static struct platform_driver omap_sdi_driver = {
377 .driver = { 377 .driver = {
378 .name = "omapdss_sdi", 378 .name = "omapdss_sdi",
379 .owner = THIS_MODULE, 379 .owner = THIS_MODULE,
380 .suppress_bind_attrs = true,
380 }, 381 },
381}; 382};
382 383
@@ -424,7 +425,7 @@ err_datapairs:
424 return r; 425 return r;
425} 426}
426 427
427void __exit sdi_uninit_port(void) 428void __exit sdi_uninit_port(struct device_node *port)
428{ 429{
429 if (!sdi.port_initialized) 430 if (!sdi.port_initialized)
430 return; 431 return;
diff --git a/drivers/video/fbdev/omap2/dss/venc.c b/drivers/video/fbdev/omap2/dss/venc.c
index 21d81113962b..d077d8a75ddc 100644
--- a/drivers/video/fbdev/omap2/dss/venc.c
+++ b/drivers/video/fbdev/omap2/dss/venc.c
@@ -966,6 +966,7 @@ static struct platform_driver omap_venchw_driver = {
966 .owner = THIS_MODULE, 966 .owner = THIS_MODULE,
967 .pm = &venc_pm_ops, 967 .pm = &venc_pm_ops,
968 .of_match_table = venc_of_match, 968 .of_match_table = venc_of_match,
969 .suppress_bind_attrs = true,
969 }, 970 },
970}; 971};
971 972
diff --git a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
index 15872433e0c6..ce8a70570756 100644
--- a/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
@@ -1833,14 +1833,13 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)
1833 if (fbdev == NULL) 1833 if (fbdev == NULL)
1834 return; 1834 return;
1835 1835
1836 for (i = 0; i < fbdev->num_fbs; i++) { 1836 for (i = 0; i < fbdev->num_overlays; i++) {
1837 struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); 1837 struct omap_overlay *ovl = fbdev->overlays[i];
1838 int j;
1839 1838
1840 for (j = 0; j < ofbi->num_overlays; j++) { 1839 ovl->disable(ovl);
1841 struct omap_overlay *ovl = ofbi->overlays[j]; 1840
1842 ovl->disable(ovl); 1841 if (ovl->manager)
1843 } 1842 ovl->unset_manager(ovl);
1844 } 1843 }
1845 1844
1846 for (i = 0; i < fbdev->num_fbs; i++) 1845 for (i = 0; i < fbdev->num_fbs; i++)
@@ -2619,7 +2618,7 @@ err0:
2619 return r; 2618 return r;
2620} 2619}
2621 2620
2622static int __exit omapfb_remove(struct platform_device *pdev) 2621static int omapfb_remove(struct platform_device *pdev)
2623{ 2622{
2624 struct omapfb2_device *fbdev = platform_get_drvdata(pdev); 2623 struct omapfb2_device *fbdev = platform_get_drvdata(pdev);
2625 2624
@@ -2636,7 +2635,7 @@ static int __exit omapfb_remove(struct platform_device *pdev)
2636 2635
2637static struct platform_driver omapfb_driver = { 2636static struct platform_driver omapfb_driver = {
2638 .probe = omapfb_probe, 2637 .probe = omapfb_probe,
2639 .remove = __exit_p(omapfb_remove), 2638 .remove = omapfb_remove,
2640 .driver = { 2639 .driver = {
2641 .name = "omapfb", 2640 .name = "omapfb",
2642 .owner = THIS_MODULE, 2641 .owner = THIS_MODULE,
@@ -2651,6 +2650,7 @@ module_param_named(mirror, def_mirror, bool, 0);
2651 2650
2652module_platform_driver(omapfb_driver); 2651module_platform_driver(omapfb_driver);
2653 2652
2653MODULE_ALIAS("platform:omapfb");
2654MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>"); 2654MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
2655MODULE_DESCRIPTION("OMAP2/3 Framebuffer"); 2655MODULE_DESCRIPTION("OMAP2/3 Framebuffer");
2656MODULE_LICENSE("GPL v2"); 2656MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/fbdev/s3fb.c b/drivers/video/fbdev/s3fb.c
index c43b969e1e23..f0ae61a37f04 100644
--- a/drivers/video/fbdev/s3fb.c
+++ b/drivers/video/fbdev/s3fb.c
@@ -1182,7 +1182,7 @@ static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
1182 1182
1183 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg); 1183 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg);
1184 1184
1185 par->state.vgabase = (void __iomem *) vga_res.start; 1185 par->state.vgabase = (void __iomem *) (unsigned long) vga_res.start;
1186 1186
1187 /* Unlock regs */ 1187 /* Unlock regs */
1188 cr38 = vga_rcrt(par->state.vgabase, 0x38); 1188 cr38 = vga_rcrt(par->state.vgabase, 0x38);
diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c
index 2bcc84ac18c7..cfde21d81c15 100644
--- a/drivers/video/fbdev/sh_mobile_lcdcfb.c
+++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c
@@ -2181,8 +2181,7 @@ sh_mobile_lcdc_channel_fb_cleanup(struct sh_mobile_lcdc_chan *ch)
2181 if (!info || !info->device) 2181 if (!info || !info->device)
2182 return; 2182 return;
2183 2183
2184 if (ch->sglist) 2184 vfree(ch->sglist);
2185 vfree(ch->sglist);
2186 2185
2187 fb_dealloc_cmap(&info->cmap); 2186 fb_dealloc_cmap(&info->cmap);
2188 framebuffer_release(info); 2187 framebuffer_release(info);
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");
diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c
index e5d11b1892e8..fcf610edf217 100644
--- a/drivers/video/fbdev/sis/sis_main.c
+++ b/drivers/video/fbdev/sis/sis_main.c
@@ -5989,7 +5989,7 @@ static int sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
5989 5989
5990 if(!ivideo->sisvga_enabled) { 5990 if(!ivideo->sisvga_enabled) {
5991 if(pci_enable_device(pdev)) { 5991 if(pci_enable_device(pdev)) {
5992 if(ivideo->nbridge) pci_dev_put(ivideo->nbridge); 5992 pci_dev_put(ivideo->nbridge);
5993 framebuffer_release(sis_fb_info); 5993 framebuffer_release(sis_fb_info);
5994 return -EIO; 5994 return -EIO;
5995 } 5995 }
@@ -6202,10 +6202,8 @@ error_0: iounmap(ivideo->video_vbase);
6202error_1: release_mem_region(ivideo->video_base, ivideo->video_size); 6202error_1: release_mem_region(ivideo->video_base, ivideo->video_size);
6203error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size); 6203error_2: release_mem_region(ivideo->mmio_base, ivideo->mmio_size);
6204error_3: vfree(ivideo->bios_abase); 6204error_3: vfree(ivideo->bios_abase);
6205 if(ivideo->lpcdev) 6205 pci_dev_put(ivideo->lpcdev);
6206 pci_dev_put(ivideo->lpcdev); 6206 pci_dev_put(ivideo->nbridge);
6207 if(ivideo->nbridge)
6208 pci_dev_put(ivideo->nbridge);
6209 if(!ivideo->sisvga_enabled) 6207 if(!ivideo->sisvga_enabled)
6210 pci_disable_device(pdev); 6208 pci_disable_device(pdev);
6211 framebuffer_release(sis_fb_info); 6209 framebuffer_release(sis_fb_info);
@@ -6505,11 +6503,9 @@ static void sisfb_remove(struct pci_dev *pdev)
6505 6503
6506 vfree(ivideo->bios_abase); 6504 vfree(ivideo->bios_abase);
6507 6505
6508 if(ivideo->lpcdev) 6506 pci_dev_put(ivideo->lpcdev);
6509 pci_dev_put(ivideo->lpcdev);
6510 6507
6511 if(ivideo->nbridge) 6508 pci_dev_put(ivideo->nbridge);
6512 pci_dev_put(ivideo->nbridge);
6513 6509
6514#ifdef CONFIG_MTRR 6510#ifdef CONFIG_MTRR
6515 /* Release MTRR region */ 6511 /* Release MTRR region */
diff --git a/drivers/video/fbdev/sm501fb.c b/drivers/video/fbdev/sm501fb.c
index 9e74e8fbe074..8b98b011fc04 100644
--- a/drivers/video/fbdev/sm501fb.c
+++ b/drivers/video/fbdev/sm501fb.c
@@ -1988,6 +1988,7 @@ static int sm501fb_probe(struct platform_device *pdev)
1988 if (info->fb[HEAD_PANEL] == NULL && 1988 if (info->fb[HEAD_PANEL] == NULL &&
1989 info->fb[HEAD_CRT] == NULL) { 1989 info->fb[HEAD_CRT] == NULL) {
1990 dev_err(dev, "no framebuffers found\n"); 1990 dev_err(dev, "no framebuffers found\n");
1991 ret = -ENODEV;
1991 goto err_alloc; 1992 goto err_alloc;
1992 } 1993 }
1993 1994
diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
index d513ed6a49f2..9279e5f6696e 100644
--- a/drivers/video/fbdev/smscufx.c
+++ b/drivers/video/fbdev/smscufx.c
@@ -1142,8 +1142,7 @@ static void ufx_free_framebuffer_work(struct work_struct *work)
1142 fb_dealloc_cmap(&info->cmap); 1142 fb_dealloc_cmap(&info->cmap);
1143 if (info->monspecs.modedb) 1143 if (info->monspecs.modedb)
1144 fb_destroy_modedb(info->monspecs.modedb); 1144 fb_destroy_modedb(info->monspecs.modedb);
1145 if (info->screen_base) 1145 vfree(info->screen_base);
1146 vfree(info->screen_base);
1147 1146
1148 fb_destroy_modelist(&info->modelist); 1147 fb_destroy_modelist(&info->modelist);
1149 1148
@@ -1743,8 +1742,7 @@ error:
1743 fb_dealloc_cmap(&info->cmap); 1742 fb_dealloc_cmap(&info->cmap);
1744 if (info->monspecs.modedb) 1743 if (info->monspecs.modedb)
1745 fb_destroy_modedb(info->monspecs.modedb); 1744 fb_destroy_modedb(info->monspecs.modedb);
1746 if (info->screen_base) 1745 vfree(info->screen_base);
1747 vfree(info->screen_base);
1748 1746
1749 fb_destroy_modelist(&info->modelist); 1747 fb_destroy_modelist(&info->modelist);
1750 1748
diff --git a/drivers/video/fbdev/udlfb.c b/drivers/video/fbdev/udlfb.c
index 046d51d83d74..ff2b8731a2dc 100644
--- a/drivers/video/fbdev/udlfb.c
+++ b/drivers/video/fbdev/udlfb.c
@@ -922,8 +922,7 @@ static void dlfb_free(struct kref *kref)
922{ 922{
923 struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref); 923 struct dlfb_data *dev = container_of(kref, struct dlfb_data, kref);
924 924
925 if (dev->backing_buffer) 925 vfree(dev->backing_buffer);
926 vfree(dev->backing_buffer);
927 926
928 kfree(dev->edid); 927 kfree(dev->edid);
929 928
@@ -953,8 +952,7 @@ static void dlfb_free_framebuffer(struct dlfb_data *dev)
953 fb_dealloc_cmap(&info->cmap); 952 fb_dealloc_cmap(&info->cmap);
954 if (info->monspecs.modedb) 953 if (info->monspecs.modedb)
955 fb_destroy_modedb(info->monspecs.modedb); 954 fb_destroy_modedb(info->monspecs.modedb);
956 if (info->screen_base) 955 vfree(info->screen_base);
957 vfree(info->screen_base);
958 956
959 fb_destroy_modelist(&info->modelist); 957 fb_destroy_modelist(&info->modelist);
960 958
@@ -1203,8 +1201,7 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)
1203 if (!new_back) 1201 if (!new_back)
1204 pr_info("No shadow/backing buffer allocated\n"); 1202 pr_info("No shadow/backing buffer allocated\n");
1205 else { 1203 else {
1206 if (dev->backing_buffer) 1204 vfree(dev->backing_buffer);
1207 vfree(dev->backing_buffer);
1208 dev->backing_buffer = new_back; 1205 dev->backing_buffer = new_back;
1209 } 1206 }
1210 } 1207 }
diff --git a/drivers/video/fbdev/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 509d452e8f91..d32d1c4d1b99 100644
--- a/drivers/video/fbdev/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
@@ -1219,8 +1219,7 @@ static int uvesafb_release(struct fb_info *info, int user)
1219 uvesafb_vbe_state_restore(par, par->vbe_state_orig); 1219 uvesafb_vbe_state_restore(par, par->vbe_state_orig);
1220out: 1220out:
1221 atomic_dec(&par->ref_count); 1221 atomic_dec(&par->ref_count);
1222 if (task) 1222 uvesafb_free(task);
1223 uvesafb_free(task);
1224 return 0; 1223 return 0;
1225} 1224}
1226 1225
@@ -1923,8 +1922,7 @@ static int uvesafb_init(void)
1923 err = -ENOMEM; 1922 err = -ENOMEM;
1924 1923
1925 if (err) { 1924 if (err) {
1926 if (uvesafb_device) 1925 platform_device_put(uvesafb_device);
1927 platform_device_put(uvesafb_device);
1928 platform_driver_unregister(&uvesafb_driver); 1926 platform_driver_unregister(&uvesafb_driver);
1929 cn_del_callback(&uvesafb_cn_id); 1927 cn_del_callback(&uvesafb_cn_id);
1930 return err; 1928 return err;
diff --git a/drivers/video/fbdev/vermilion/vermilion.c b/drivers/video/fbdev/vermilion/vermilion.c
index 5f930aeccf1f..6b70d7f62b2f 100644
--- a/drivers/video/fbdev/vermilion/vermilion.c
+++ b/drivers/video/fbdev/vermilion/vermilion.c
@@ -1003,13 +1003,15 @@ static int vmlfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
1003 struct vml_info *vinfo = container_of(info, struct vml_info, info); 1003 struct vml_info *vinfo = container_of(info, struct vml_info, info);
1004 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 1004 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
1005 int ret; 1005 int ret;
1006 unsigned long prot;
1006 1007
1007 ret = vmlfb_vram_offset(vinfo, offset); 1008 ret = vmlfb_vram_offset(vinfo, offset);
1008 if (ret) 1009 if (ret)
1009 return -EINVAL; 1010 return -EINVAL;
1010 1011
1011 pgprot_val(vma->vm_page_prot) |= _PAGE_PCD; 1012 prot = pgprot_val(vma->vm_page_prot) & ~_PAGE_CACHE_MASK;
1012 pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT; 1013 pgprot_val(vma->vm_page_prot) =
1014 prot | cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS);
1013 1015
1014 return vm_iomap_memory(vma, vinfo->vram_start, 1016 return vm_iomap_memory(vma, vinfo->vram_start,
1015 vinfo->vram_contig_size); 1017 vinfo->vram_contig_size);
diff --git a/drivers/video/fbdev/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c
index 325c43c6ff97..f9718f012aae 100644
--- a/drivers/video/fbdev/via/viafbdev.c
+++ b/drivers/video/fbdev/via/viafbdev.c
@@ -1937,8 +1937,7 @@ out_fb1_unreg_lcd_cle266:
1937out_dealloc_cmap: 1937out_dealloc_cmap:
1938 fb_dealloc_cmap(&viafbinfo->cmap); 1938 fb_dealloc_cmap(&viafbinfo->cmap);
1939out_fb1_release: 1939out_fb1_release:
1940 if (viafbinfo1) 1940 framebuffer_release(viafbinfo1);
1941 framebuffer_release(viafbinfo1);
1942out_fb_release: 1941out_fb_release:
1943 i2c_bus_free(viaparinfo->shared); 1942 i2c_bus_free(viaparinfo->shared);
1944 framebuffer_release(viafbinfo); 1943 framebuffer_release(viafbinfo);
diff --git a/drivers/video/fbdev/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c
index 5c7cbc6c6236..ea7f056ed5fe 100644
--- a/drivers/video/fbdev/vt8623fb.c
+++ b/drivers/video/fbdev/vt8623fb.c
@@ -731,7 +731,7 @@ static int vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
731 731
732 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg); 732 pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg);
733 733
734 par->state.vgabase = (void __iomem *) vga_res.start; 734 par->state.vgabase = (void __iomem *) (unsigned long) vga_res.start;
735 735
736 /* Find how many physical memory there is on card */ 736 /* Find how many physical memory there is on card */
737 memsize1 = (vga_rseq(par->state.vgabase, 0x34) + 1) >> 1; 737 memsize1 = (vga_rseq(par->state.vgabase, 0x34) + 1) >> 1;