diff options
Diffstat (limited to 'drivers/video')
| -rw-r--r-- | drivers/video/Kconfig | 2477 | ||||
| -rw-r--r-- | drivers/video/Makefile | 168 | ||||
| -rw-r--r-- | drivers/video/backlight/88pm860x_bl.c | 18 | ||||
| -rw-r--r-- | drivers/video/backlight/Kconfig | 18 | ||||
| -rw-r--r-- | drivers/video/backlight/Makefile | 2 | ||||
| -rw-r--r-- | drivers/video/backlight/aat2870_bl.c | 15 | ||||
| -rw-r--r-- | drivers/video/backlight/adp5520_bl.c | 11 | ||||
| -rw-r--r-- | drivers/video/backlight/adp8860_bl.c | 21 | ||||
| -rw-r--r-- | drivers/video/backlight/adp8870_bl.c | 21 | ||||
| -rw-r--r-- | drivers/video/backlight/ams369fg06.c | 24 | ||||
| -rw-r--r-- | drivers/video/backlight/as3711_bl.c | 26 | ||||
| -rw-r--r-- | drivers/video/backlight/atmel-pwm-bl.c | 105 | ||||
| -rw-r--r-- | drivers/video/backlight/backlight.c | 101 | ||||
| -rw-r--r-- | drivers/video/backlight/bd6107.c | 6 | ||||
| -rw-r--r-- | drivers/video/backlight/corgi_lcd.c | 34 | ||||
| -rw-r--r-- | drivers/video/backlight/cr_bllcd.c | 13 | ||||
| -rw-r--r-- | drivers/video/backlight/da903x_bl.c | 16 | ||||
| -rw-r--r-- | drivers/video/backlight/da9052_bl.c | 6 | ||||
| -rw-r--r-- | drivers/video/backlight/ep93xx_bl.c | 13 | ||||
| -rw-r--r-- | drivers/video/backlight/generic_bl.c | 8 | ||||
| -rw-r--r-- | drivers/video/backlight/gpio_backlight.c | 76 | ||||
| -rw-r--r-- | drivers/video/backlight/hp680_bl.c | 6 | ||||
| -rw-r--r-- | drivers/video/backlight/hx8357.c | 24 | ||||
| -rw-r--r-- | drivers/video/backlight/ili922x.c | 11 | ||||
| -rw-r--r-- | drivers/video/backlight/ili9320.c | 19 | ||||
| -rw-r--r-- | drivers/video/backlight/jornada720_bl.c | 15 | ||||
| -rw-r--r-- | drivers/video/backlight/jornada720_lcd.c | 13 | ||||
| -rw-r--r-- | drivers/video/backlight/kb3886_bl.c | 22 | ||||
| -rw-r--r-- | drivers/video/backlight/l4f00242t03.c | 18 | ||||
| -rw-r--r-- | drivers/video/backlight/lcd.c | 2 | ||||
| -rw-r--r-- | drivers/video/backlight/ld9040.c | 23 | ||||
| -rw-r--r-- | drivers/video/backlight/ld9040_gamma.h | 4 | ||||
| -rw-r--r-- | drivers/video/backlight/lm3533_bl.c | 17 | ||||
| -rw-r--r-- | drivers/video/backlight/lm3630_bl.c | 475 | ||||
| -rw-r--r-- | drivers/video/backlight/lm3630a_bl.c | 483 | ||||
| -rw-r--r-- | drivers/video/backlight/lm3639_bl.c | 30 | ||||
| -rw-r--r-- | drivers/video/backlight/lms283gf05.c | 21 | ||||
| -rw-r--r-- | drivers/video/backlight/lms501kf03.c | 8 | ||||
| -rw-r--r-- | drivers/video/backlight/lp855x_bl.c | 43 | ||||
| -rw-r--r-- | drivers/video/backlight/lp8788_bl.c | 8 | ||||
| -rw-r--r-- | drivers/video/backlight/ltv350qv.c | 11 | ||||
| -rw-r--r-- | drivers/video/backlight/lv5207lp.c | 9 | ||||
| -rw-r--r-- | drivers/video/backlight/max8925_bl.c | 17 | ||||
| -rw-r--r-- | drivers/video/backlight/omap1_bl.c | 16 | ||||
| -rw-r--r-- | drivers/video/backlight/ot200_bl.c | 9 | ||||
| -rw-r--r-- | drivers/video/backlight/pandora_bl.c | 12 | ||||
| -rw-r--r-- | drivers/video/backlight/pcf50633-backlight.c | 15 | ||||
| -rw-r--r-- | drivers/video/backlight/platform_lcd.c | 26 | ||||
| -rw-r--r-- | drivers/video/backlight/pwm_bl.c | 174 | ||||
| -rw-r--r-- | drivers/video/backlight/s6e63m0.c | 24 | ||||
| -rw-r--r-- | drivers/video/backlight/tdo24m.c | 14 | ||||
| -rw-r--r-- | drivers/video/backlight/tosa_bl.c | 9 | ||||
| -rw-r--r-- | drivers/video/backlight/tosa_lcd.c | 12 | ||||
| -rw-r--r-- | drivers/video/backlight/tps65217_bl.c | 22 | ||||
| -rw-r--r-- | drivers/video/backlight/wm831x_bl.c | 21 | ||||
| -rw-r--r-- | drivers/video/console/Kconfig | 3 | ||||
| -rw-r--r-- | drivers/video/console/dummycon.c | 1 | ||||
| -rw-r--r-- | drivers/video/console/fbcon.c | 33 | ||||
| -rw-r--r-- | drivers/video/console/sticon.c | 2 | ||||
| -rw-r--r-- | drivers/video/console/sticore.c | 168 | ||||
| -rw-r--r-- | drivers/video/console/vgacon.c | 18 | ||||
| -rw-r--r-- | drivers/video/exynos/exynos_dp_core.c | 1214 | ||||
| -rw-r--r-- | drivers/video/exynos/exynos_dp_core.h | 210 | ||||
| -rw-r--r-- | drivers/video/exynos/exynos_dp_reg.c | 1245 | ||||
| -rw-r--r-- | drivers/video/exynos/exynos_dp_reg.h | 366 | ||||
| -rw-r--r-- | drivers/video/fbdev/68328fb.c (renamed from drivers/video/68328fb.c) | 9 | ||||
| -rw-r--r-- | drivers/video/fbdev/Kconfig | 2479 | ||||
| -rw-r--r-- | drivers/video/fbdev/Makefile | 152 | ||||
| -rw-r--r-- | drivers/video/fbdev/acornfb.c (renamed from drivers/video/acornfb.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/acornfb.h (renamed from drivers/video/acornfb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/amba-clcd.c (renamed from drivers/video/amba-clcd.c) | 9 | ||||
| -rw-r--r-- | drivers/video/fbdev/amifb.c (renamed from drivers/video/amifb.c) | 8 | ||||
| -rw-r--r-- | drivers/video/fbdev/arcfb.c (renamed from drivers/video/arcfb.c) | 8 | ||||
| -rw-r--r-- | drivers/video/fbdev/arkfb.c (renamed from drivers/video/arkfb.c) | 51 | ||||
| -rw-r--r-- | drivers/video/fbdev/asiliantfb.c (renamed from drivers/video/asiliantfb.c) | 5 | ||||
| -rw-r--r-- | drivers/video/fbdev/atafb.c (renamed from drivers/video/atafb.c) | 56 | ||||
| -rw-r--r-- | drivers/video/fbdev/atafb.h (renamed from drivers/video/atafb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/atafb_iplan2p2.c (renamed from drivers/video/atafb_iplan2p2.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/atafb_iplan2p4.c (renamed from drivers/video/atafb_iplan2p4.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/atafb_iplan2p8.c (renamed from drivers/video/atafb_iplan2p8.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/atafb_mfb.c (renamed from drivers/video/atafb_mfb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/atafb_utils.h (renamed from drivers/video/atafb_utils.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/atmel_lcdfb.c (renamed from drivers/video/atmel_lcdfb.c) | 351 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/Makefile (renamed from drivers/video/aty/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/ati_ids.h (renamed from drivers/video/aty/ati_ids.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/aty128fb.c (renamed from drivers/video/aty/aty128fb.c) | 12 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/atyfb.h (renamed from drivers/video/aty/atyfb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/atyfb_base.c (renamed from drivers/video/aty/atyfb_base.c) | 8 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/mach64_accel.c (renamed from drivers/video/aty/mach64_accel.c) | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/mach64_ct.c (renamed from drivers/video/aty/mach64_ct.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/mach64_cursor.c (renamed from drivers/video/aty/mach64_cursor.c) | 22 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/mach64_gx.c (renamed from drivers/video/aty/mach64_gx.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/radeon_accel.c (renamed from drivers/video/aty/radeon_accel.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/radeon_backlight.c (renamed from drivers/video/aty/radeon_backlight.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/radeon_base.c (renamed from drivers/video/aty/radeon_base.c) | 5 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/radeon_i2c.c (renamed from drivers/video/aty/radeon_i2c.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/radeon_monitor.c (renamed from drivers/video/aty/radeon_monitor.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/radeon_pm.c (renamed from drivers/video/aty/radeon_pm.c) | 22 | ||||
| -rw-r--r-- | drivers/video/fbdev/aty/radeonfb.h (renamed from drivers/video/aty/radeonfb.h) | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/au1100fb.c (renamed from drivers/video/au1100fb.c) | 42 | ||||
| -rw-r--r-- | drivers/video/fbdev/au1100fb.h (renamed from drivers/video/au1100fb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/au1200fb.c (renamed from drivers/video/au1200fb.c) | 39 | ||||
| -rw-r--r-- | drivers/video/fbdev/au1200fb.h (renamed from drivers/video/au1200fb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/auo_k1900fb.c (renamed from drivers/video/auo_k1900fb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/auo_k1901fb.c (renamed from drivers/video/auo_k1901fb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/auo_k190x.c (renamed from drivers/video/auo_k190x.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/auo_k190x.h (renamed from drivers/video/auo_k190x.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/bf537-lq035.c (renamed from drivers/video/bf537-lq035.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/bf54x-lq043fb.c (renamed from drivers/video/bf54x-lq043fb.c) | 18 | ||||
| -rw-r--r-- | drivers/video/fbdev/bfin-lq035q1-fb.c (renamed from drivers/video/bfin-lq035q1-fb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/bfin-t350mcqb-fb.c (renamed from drivers/video/bfin-t350mcqb-fb.c) | 14 | ||||
| -rw-r--r-- | drivers/video/fbdev/bfin_adv7393fb.c (renamed from drivers/video/bfin_adv7393fb.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/bfin_adv7393fb.h (renamed from drivers/video/bfin_adv7393fb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/broadsheetfb.c (renamed from drivers/video/broadsheetfb.c) | 19 | ||||
| -rw-r--r-- | drivers/video/fbdev/bt431.h (renamed from drivers/video/bt431.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/bt455.h (renamed from drivers/video/bt455.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/bw2.c (renamed from drivers/video/bw2.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/c2p.h (renamed from drivers/video/c2p.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/c2p_core.h (renamed from drivers/video/c2p_core.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/c2p_iplan2.c (renamed from drivers/video/c2p_iplan2.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/c2p_planar.c (renamed from drivers/video/c2p_planar.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/carminefb.c (renamed from drivers/video/carminefb.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/carminefb.h (renamed from drivers/video/carminefb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/carminefb_regs.h (renamed from drivers/video/carminefb_regs.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/cg14.c (renamed from drivers/video/cg14.c) | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/cg3.c (renamed from drivers/video/cg3.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/cg6.c (renamed from drivers/video/cg6.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/chipsfb.c (renamed from drivers/video/chipsfb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/cirrusfb.c (renamed from drivers/video/cirrusfb.c) | 10 | ||||
| -rw-r--r-- | drivers/video/fbdev/clps711xfb.c (renamed from drivers/video/clps711xfb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/cobalt_lcdfb.c (renamed from drivers/video/cobalt_lcdfb.c) | 17 | ||||
| -rw-r--r-- | drivers/video/fbdev/controlfb.c (renamed from drivers/video/controlfb.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/controlfb.h (renamed from drivers/video/controlfb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/Makefile | 16 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/cfbcopyarea.c (renamed from drivers/video/cfbcopyarea.c) | 153 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/cfbfillrect.c (renamed from drivers/video/cfbfillrect.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/cfbimgblt.c (renamed from drivers/video/cfbimgblt.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/fb_ddc.c (renamed from drivers/video/fb_ddc.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/fb_defio.c (renamed from drivers/video/fb_defio.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/fb_draw.h (renamed from drivers/video/fb_draw.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/fb_notify.c (renamed from drivers/video/fb_notify.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/fb_sys_fops.c (renamed from drivers/video/fb_sys_fops.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/fbcmap.c (renamed from drivers/video/fbcmap.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/fbcvt.c (renamed from drivers/video/fbcvt.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/fbmem.c (renamed from drivers/video/fbmem.c) | 94 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/fbmon.c (renamed from drivers/video/fbmon.c) | 11 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/fbsysfs.c (renamed from drivers/video/fbsysfs.c) | 19 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/modedb.c (renamed from drivers/video/modedb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/svgalib.c (renamed from drivers/video/svgalib.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/syscopyarea.c (renamed from drivers/video/syscopyarea.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/sysfillrect.c (renamed from drivers/video/sysfillrect.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/core/sysimgblt.c (renamed from drivers/video/sysimgblt.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/cyber2000fb.c (renamed from drivers/video/cyber2000fb.c) | 75 | ||||
| -rw-r--r-- | drivers/video/fbdev/cyber2000fb.h (renamed from drivers/video/cyber2000fb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/da8xx-fb.c (renamed from drivers/video/da8xx-fb.c) | 67 | ||||
| -rw-r--r-- | drivers/video/fbdev/dnfb.c (renamed from drivers/video/dnfb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/edid.h (renamed from drivers/video/edid.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/efifb.c (renamed from drivers/video/efifb.c) | 20 | ||||
| -rw-r--r-- | drivers/video/fbdev/ep93xx-fb.c (renamed from drivers/video/ep93xx-fb.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/exynos/Kconfig (renamed from drivers/video/exynos/Kconfig) | 13 | ||||
| -rw-r--r-- | drivers/video/fbdev/exynos/Makefile (renamed from drivers/video/exynos/Makefile) | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/exynos/exynos_mipi_dsi.c (renamed from drivers/video/exynos/exynos_mipi_dsi.c) | 20 | ||||
| -rw-r--r-- | drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c (renamed from drivers/video/exynos/exynos_mipi_dsi_common.c) | 7 | ||||
| -rw-r--r-- | drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h (renamed from drivers/video/exynos/exynos_mipi_dsi_common.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.c (renamed from drivers/video/exynos/exynos_mipi_dsi_lowlevel.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.h (renamed from drivers/video/exynos/exynos_mipi_dsi_lowlevel.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/exynos/exynos_mipi_dsi_regs.h (renamed from drivers/video/exynos/exynos_mipi_dsi_regs.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/exynos/s6e8ax0.c (renamed from drivers/video/exynos/s6e8ax0.c) | 13 | ||||
| -rw-r--r-- | drivers/video/fbdev/fb-puv3.c (renamed from drivers/video/fb-puv3.c) | 7 | ||||
| -rw-r--r-- | drivers/video/fbdev/ffb.c (renamed from drivers/video/ffb.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/fm2fb.c (renamed from drivers/video/fm2fb.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/fsl-diu-fb.c (renamed from drivers/video/fsl-diu-fb.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/g364fb.c (renamed from drivers/video/g364fb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/gbefb.c (renamed from drivers/video/gbefb.c) | 12 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/Kconfig (renamed from drivers/video/geode/Kconfig) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/Makefile (renamed from drivers/video/geode/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/display_gx.c (renamed from drivers/video/geode/display_gx.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/display_gx1.c (renamed from drivers/video/geode/display_gx1.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/display_gx1.h (renamed from drivers/video/geode/display_gx1.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/geodefb.h (renamed from drivers/video/geode/geodefb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/gx1fb_core.c (renamed from drivers/video/geode/gx1fb_core.c) | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/gxfb.h (renamed from drivers/video/geode/gxfb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/gxfb_core.c (renamed from drivers/video/geode/gxfb_core.c) | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/lxfb.h (renamed from drivers/video/geode/lxfb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/lxfb_core.c (renamed from drivers/video/geode/lxfb_core.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/lxfb_ops.c (renamed from drivers/video/geode/lxfb_ops.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/suspend_gx.c (renamed from drivers/video/geode/suspend_gx.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/video_cs5530.c (renamed from drivers/video/geode/video_cs5530.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/video_cs5530.h (renamed from drivers/video/geode/video_cs5530.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/geode/video_gx.c (renamed from drivers/video/geode/video_gx.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/goldfishfb.c (renamed from drivers/video/goldfishfb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/grvga.c (renamed from drivers/video/grvga.c) | 19 | ||||
| -rw-r--r-- | drivers/video/fbdev/gxt4500.c (renamed from drivers/video/gxt4500.c) | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/hecubafb.c (renamed from drivers/video/hecubafb.c) | 19 | ||||
| -rw-r--r-- | drivers/video/fbdev/hgafb.c (renamed from drivers/video/hgafb.c) | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/hitfb.c (renamed from drivers/video/hitfb.c) | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/hpfb.c (renamed from drivers/video/hpfb.c) | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/hyperv_fb.c (renamed from drivers/video/hyperv_fb.c) | 133 | ||||
| -rw-r--r-- | drivers/video/fbdev/i740_reg.h (renamed from drivers/video/i740_reg.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/i740fb.c (renamed from drivers/video/i740fb.c) | 9 | ||||
| -rw-r--r-- | drivers/video/fbdev/i810/Makefile (renamed from drivers/video/i810/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/i810/i810-i2c.c (renamed from drivers/video/i810/i810-i2c.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/i810/i810.h (renamed from drivers/video/i810/i810.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/i810/i810_accel.c (renamed from drivers/video/i810/i810_accel.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/i810/i810_dvt.c (renamed from drivers/video/i810/i810_dvt.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/i810/i810_gtf.c (renamed from drivers/video/i810/i810_gtf.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/i810/i810_main.c (renamed from drivers/video/i810/i810_main.c) | 5 | ||||
| -rw-r--r-- | drivers/video/fbdev/i810/i810_main.h (renamed from drivers/video/i810/i810_main.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/i810/i810_regs.h (renamed from drivers/video/i810/i810_regs.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/igafb.c (renamed from drivers/video/igafb.c) | 5 | ||||
| -rw-r--r-- | drivers/video/fbdev/imsttfb.c (renamed from drivers/video/imsttfb.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/imxfb.c (renamed from drivers/video/imxfb.c) | 386 | ||||
| -rw-r--r-- | drivers/video/fbdev/intelfb/Makefile (renamed from drivers/video/intelfb/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/intelfb/intelfb.h (renamed from drivers/video/intelfb/intelfb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/intelfb/intelfb_i2c.c (renamed from drivers/video/intelfb/intelfb_i2c.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/intelfb/intelfbdrv.c (renamed from drivers/video/intelfb/intelfbdrv.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/intelfb/intelfbhw.c (renamed from drivers/video/intelfb/intelfbhw.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/intelfb/intelfbhw.h (renamed from drivers/video/intelfb/intelfbhw.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/jz4740_fb.c (renamed from drivers/video/jz4740_fb.c) | 29 | ||||
| -rw-r--r-- | drivers/video/fbdev/kyro/Makefile (renamed from drivers/video/kyro/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/kyro/STG4000InitDevice.c (renamed from drivers/video/kyro/STG4000InitDevice.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/kyro/STG4000Interface.h (renamed from drivers/video/kyro/STG4000Interface.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/kyro/STG4000OverlayDevice.c (renamed from drivers/video/kyro/STG4000OverlayDevice.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/kyro/STG4000Ramdac.c (renamed from drivers/video/kyro/STG4000Ramdac.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/kyro/STG4000Reg.h (renamed from drivers/video/kyro/STG4000Reg.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/kyro/STG4000VTG.c (renamed from drivers/video/kyro/STG4000VTG.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/kyro/fbdev.c (renamed from drivers/video/kyro/fbdev.c) | 16 | ||||
| -rw-r--r-- | drivers/video/fbdev/leo.c (renamed from drivers/video/leo.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/macfb.c (renamed from drivers/video/macfb.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/macmodes.c (renamed from drivers/video/macmodes.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/macmodes.h (renamed from drivers/video/macmodes.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/Makefile (renamed from drivers/video/matrox/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/g450_pll.c (renamed from drivers/video/matrox/g450_pll.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/g450_pll.h (renamed from drivers/video/matrox/g450_pll.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/i2c-matroxfb.c (renamed from drivers/video/matrox/i2c-matroxfb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_DAC1064.c (renamed from drivers/video/matrox/matroxfb_DAC1064.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_DAC1064.h (renamed from drivers/video/matrox/matroxfb_DAC1064.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_Ti3026.c (renamed from drivers/video/matrox/matroxfb_Ti3026.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_Ti3026.h (renamed from drivers/video/matrox/matroxfb_Ti3026.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_accel.c (renamed from drivers/video/matrox/matroxfb_accel.c) | 38 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_accel.h (renamed from drivers/video/matrox/matroxfb_accel.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_base.c (renamed from drivers/video/matrox/matroxfb_base.c) | 9 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_base.h (renamed from drivers/video/matrox/matroxfb_base.h) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_crtc2.c (renamed from drivers/video/matrox/matroxfb_crtc2.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_crtc2.h (renamed from drivers/video/matrox/matroxfb_crtc2.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_g450.c (renamed from drivers/video/matrox/matroxfb_g450.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_g450.h (renamed from drivers/video/matrox/matroxfb_g450.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_maven.c (renamed from drivers/video/matrox/matroxfb_maven.c) | 14 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_maven.h (renamed from drivers/video/matrox/matroxfb_maven.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_misc.c (renamed from drivers/video/matrox/matroxfb_misc.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/matrox/matroxfb_misc.h (renamed from drivers/video/matrox/matroxfb_misc.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/maxinefb.c (renamed from drivers/video/maxinefb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mb862xx/Makefile (renamed from drivers/video/mb862xx/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mb862xx/mb862xx-i2c.c (renamed from drivers/video/mb862xx/mb862xx-i2c.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mb862xx/mb862xx_reg.h (renamed from drivers/video/mb862xx/mb862xx_reg.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mb862xx/mb862xxfb.h (renamed from drivers/video/mb862xx/mb862xxfb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mb862xx/mb862xxfb_accel.c (renamed from drivers/video/mb862xx/mb862xxfb_accel.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mb862xx/mb862xxfb_accel.h (renamed from drivers/video/mb862xx/mb862xxfb_accel.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mb862xx/mb862xxfbdrv.c (renamed from drivers/video/mb862xx/mb862xxfbdrv.c) | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/mbx/Makefile | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/mbx/mbxdebugfs.c (renamed from drivers/video/mbx/mbxdebugfs.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/mbx/mbxfb.c (renamed from drivers/video/mbx/mbxfb.c) | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/mbx/reg_bits.h (renamed from drivers/video/mbx/reg_bits.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mbx/regs.h (renamed from drivers/video/mbx/regs.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/metronomefb.c (renamed from drivers/video/metronomefb.c) | 17 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/Kconfig | 11 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/Makefile (renamed from drivers/video/mmp/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/core.c (renamed from drivers/video/mmp/core.c) | 9 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/fb/Kconfig (renamed from drivers/video/mmp/fb/Kconfig) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/fb/Makefile (renamed from drivers/video/mmp/fb/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/fb/mmpfb.c (renamed from drivers/video/mmp/fb/mmpfb.c) | 43 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/fb/mmpfb.h (renamed from drivers/video/mmp/fb/mmpfb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/hw/Kconfig (renamed from drivers/video/mmp/hw/Kconfig) | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/hw/Makefile (renamed from drivers/video/mmp/hw/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/hw/mmp_ctrl.c (renamed from drivers/video/mmp/hw/mmp_ctrl.c) | 88 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/hw/mmp_ctrl.h (renamed from drivers/video/mmp/hw/mmp_ctrl.h) | 37 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/hw/mmp_spi.c (renamed from drivers/video/mmp/hw/mmp_spi.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/panel/Kconfig (renamed from drivers/video/mmp/panel/Kconfig) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/panel/Makefile (renamed from drivers/video/mmp/panel/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c (renamed from drivers/video/mmp/panel/tpo_tj032md01bw.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/Makefile (renamed from drivers/video/msm/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mddi.c (renamed from drivers/video/msm/mddi.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mddi_client_dummy.c (renamed from drivers/video/msm/mddi_client_dummy.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mddi_client_nt35399.c (renamed from drivers/video/msm/mddi_client_nt35399.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mddi_client_toshiba.c (renamed from drivers/video/msm/mddi_client_toshiba.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mddi_hw.h (renamed from drivers/video/msm/mddi_hw.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdp.c (renamed from drivers/video/msm/mdp.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdp_csc_table.h (renamed from drivers/video/msm/mdp_csc_table.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdp_hw.h (renamed from drivers/video/msm/mdp_hw.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdp_ppp.c (renamed from drivers/video/msm/mdp_ppp.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdp_scale_tables.c (renamed from drivers/video/msm/mdp_scale_tables.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdp_scale_tables.h (renamed from drivers/video/msm/mdp_scale_tables.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/msm_fb.c (renamed from drivers/video/msm/msm_fb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/mx3fb.c (renamed from drivers/video/mx3fb.c) | 91 | ||||
| -rw-r--r-- | drivers/video/fbdev/mxsfb.c (renamed from drivers/video/mxsfb.c) | 127 | ||||
| -rw-r--r-- | drivers/video/fbdev/n411.c (renamed from drivers/video/n411.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/neofb.c (renamed from drivers/video/neofb.c) | 13 | ||||
| -rw-r--r-- | drivers/video/fbdev/nuc900fb.c (renamed from drivers/video/nuc900fb.c) | 9 | ||||
| -rw-r--r-- | drivers/video/fbdev/nuc900fb.h (renamed from drivers/video/nuc900fb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/nvidia/Makefile (renamed from drivers/video/nvidia/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/nvidia/nv_accel.c (renamed from drivers/video/nvidia/nv_accel.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/nvidia/nv_backlight.c (renamed from drivers/video/nvidia/nv_backlight.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/nvidia/nv_dma.h (renamed from drivers/video/nvidia/nv_dma.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/nvidia/nv_hw.c (renamed from drivers/video/nvidia/nv_hw.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/nvidia/nv_i2c.c (renamed from drivers/video/nvidia/nv_i2c.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/nvidia/nv_local.h (renamed from drivers/video/nvidia/nv_local.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/nvidia/nv_of.c (renamed from drivers/video/nvidia/nv_of.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/nvidia/nv_proto.h (renamed from drivers/video/nvidia/nv_proto.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/nvidia/nv_setup.c (renamed from drivers/video/nvidia/nv_setup.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/nvidia/nv_type.h (renamed from drivers/video/nvidia/nv_type.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/nvidia/nvidia.c (renamed from drivers/video/nvidia/nvidia.c) | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/ocfb.c | 440 | ||||
| -rw-r--r-- | drivers/video/fbdev/offb.c (renamed from drivers/video/offb.c) | 21 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/Kconfig (renamed from drivers/video/omap/Kconfig) | 9 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/Makefile | 27 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/hwa742.c (renamed from drivers/video/omap/hwa742.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/lcd_ams_delta.c (renamed from drivers/video/omap/lcd_ams_delta.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/lcd_h3.c (renamed from drivers/video/omap/lcd_h3.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/lcd_htcherald.c (renamed from drivers/video/omap/lcd_htcherald.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/lcd_inn1510.c (renamed from drivers/video/omap/lcd_inn1510.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/lcd_inn1610.c (renamed from drivers/video/omap/lcd_inn1610.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/lcd_mipid.c (renamed from drivers/video/omap/lcd_mipid.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/lcd_osk.c (renamed from drivers/video/omap/lcd_osk.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/lcd_palmte.c (renamed from drivers/video/omap/lcd_palmte.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/lcd_palmtt.c (renamed from drivers/video/omap/lcd_palmtt.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/lcd_palmz71.c (renamed from drivers/video/omap/lcd_palmz71.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/lcdc.c (renamed from drivers/video/omap/lcdc.c) | 67 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/lcdc.h (renamed from drivers/video/omap/lcdc.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/omapfb.h (renamed from drivers/video/omap/omapfb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/omapfb_main.c (renamed from drivers/video/omap/omapfb_main.c) | 5 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap/sossi.c (renamed from drivers/video/omap/sossi.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/Makefile (renamed from drivers/video/omap2/Makefile) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/Kconfig (renamed from drivers/video/omap2/displays-new/Kconfig) | 7 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/Makefile (renamed from drivers/video/omap2/displays-new/Makefile) | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c (renamed from drivers/video/omap2/displays-new/connector-analog-tv.c) | 47 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/connector-dvi.c (renamed from drivers/video/omap2/displays-new/connector-dvi.c) | 54 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/connector-hdmi.c (renamed from drivers/video/omap2/displays-new/connector-hdmi.c) | 59 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c (renamed from drivers/video/omap2/displays-new/encoder-tfp410.c) | 43 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c (renamed from drivers/video/omap2/displays-new/encoder-tpd12s015.c) | 58 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/panel-dpi.c (renamed from drivers/video/omap2/displays-new/panel-dpi.c) | 95 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c (renamed from drivers/video/omap2/displays-new/panel-dsi-cm.c) | 64 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c (renamed from drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c) | 79 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c (renamed from drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c) | 49 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c (renamed from drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c) | 212 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c (renamed from drivers/video/omap2/displays-new/panel-sony-acx565akm.c) | 76 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c | 511 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c (renamed from drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c) | 44 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/Kconfig (renamed from drivers/video/omap2/dss/Kconfig) | 26 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/Makefile (renamed from drivers/video/omap2/dss/Makefile) | 8 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/apply.c (renamed from drivers/video/omap2/dss/apply.c) | 11 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/core.c (renamed from drivers/video/omap2/dss/core.c) | 10 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/dispc-compat.c (renamed from drivers/video/omap2/dss/dispc-compat.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/dispc-compat.h (renamed from drivers/video/omap2/dss/dispc-compat.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/dispc.c (renamed from drivers/video/omap2/dss/dispc.c) | 204 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/dispc.h (renamed from drivers/video/omap2/dss/dispc.h) | 20 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/dispc_coefs.c (renamed from drivers/video/omap2/dss/dispc_coefs.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/display-sysfs.c (renamed from drivers/video/omap2/dss/display-sysfs.c) | 8 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/display.c (renamed from drivers/video/omap2/dss/display.c) | 34 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/dpi.c (renamed from drivers/video/omap2/dss/dpi.c) | 94 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/dsi.c (renamed from drivers/video/omap2/dss/dsi.c) | 434 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/dss-of.c | 159 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/dss.c (renamed from drivers/video/omap2/dss/dss.c) | 255 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/dss.h (renamed from drivers/video/omap2/dss/dss.h) | 38 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/dss_features.c (renamed from drivers/video/omap2/dss/dss_features.c) | 115 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/dss_features.h (renamed from drivers/video/omap2/dss/dss_features.h) | 9 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi.h | 447 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi4.c | 804 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi4_core.c (renamed from drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c) | 769 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi4_core.h (renamed from drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h) | 303 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi5.c | 829 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi5_core.c | 922 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi5_core.h | 306 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi_common.c | 466 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi_phy.c | 255 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi_pll.c | 291 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/hdmi_wp.c | 258 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/manager-sysfs.c (renamed from drivers/video/omap2/dss/manager-sysfs.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/manager.c (renamed from drivers/video/omap2/dss/manager.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/omapdss-boot-init.c | 231 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/output.c (renamed from drivers/video/omap2/dss/output.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/overlay-sysfs.c (renamed from drivers/video/omap2/dss/overlay-sysfs.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/overlay.c (renamed from drivers/video/omap2/dss/overlay.c) | 5 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/rfbi.c (renamed from drivers/video/omap2/dss/rfbi.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/sdi.c (renamed from drivers/video/omap2/dss/sdi.c) | 80 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/dss/venc.c (renamed from drivers/video/omap2/dss/venc.c) | 73 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/omapfb/Kconfig (renamed from drivers/video/omap2/omapfb/Kconfig) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/omapfb/Makefile (renamed from drivers/video/omap2/omapfb/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c (renamed from drivers/video/omap2/omapfb/omapfb-ioctl.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/omapfb/omapfb-main.c (renamed from drivers/video/omap2/omapfb/omapfb-main.c) | 94 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c (renamed from drivers/video/omap2/omapfb/omapfb-sysfs.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/omapfb/omapfb.h (renamed from drivers/video/omap2/omapfb/omapfb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/omap2/vrfb.c (renamed from drivers/video/omap2/vrfb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/p9100.c (renamed from drivers/video/p9100.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/platinumfb.c (renamed from drivers/video/platinumfb.c) | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/platinumfb.h (renamed from drivers/video/platinumfb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/pm2fb.c (renamed from drivers/video/pm2fb.c) | 5 | ||||
| -rw-r--r-- | drivers/video/fbdev/pm3fb.c (renamed from drivers/video/pm3fb.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/pmag-aa-fb.c (renamed from drivers/video/pmag-aa-fb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/pmag-ba-fb.c (renamed from drivers/video/pmag-ba-fb.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/pmagb-b-fb.c (renamed from drivers/video/pmagb-b-fb.c) | 9 | ||||
| -rw-r--r-- | drivers/video/fbdev/ps3fb.c (renamed from drivers/video/ps3fb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/pvr2fb.c (renamed from drivers/video/pvr2fb.c) | 25 | ||||
| -rw-r--r-- | drivers/video/fbdev/pxa168fb.c (renamed from drivers/video/pxa168fb.c) | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/pxa168fb.h (renamed from drivers/video/pxa168fb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/pxa3xx-gcu.c (renamed from drivers/video/pxa3xx-gcu.c) | 191 | ||||
| -rw-r--r-- | drivers/video/fbdev/pxa3xx-gcu.h (renamed from drivers/video/pxa3xx-gcu.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/pxafb.c (renamed from drivers/video/pxafb.c) | 16 | ||||
| -rw-r--r-- | drivers/video/fbdev/pxafb.h (renamed from drivers/video/pxafb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/q40fb.c (renamed from drivers/video/q40fb.c) | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/riva/Makefile (renamed from drivers/video/riva/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/riva/fbdev.c (renamed from drivers/video/riva/fbdev.c) | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/riva/nv_driver.c (renamed from drivers/video/riva/nv_driver.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/riva/nv_type.h (renamed from drivers/video/riva/nv_type.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/riva/nvreg.h (renamed from drivers/video/riva/nvreg.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/riva/riva_hw.c (renamed from drivers/video/riva/riva_hw.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/riva/riva_hw.h (renamed from drivers/video/riva/riva_hw.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/riva/riva_tbl.h (renamed from drivers/video/riva/riva_tbl.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/riva/rivafb-i2c.c (renamed from drivers/video/riva/rivafb-i2c.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/riva/rivafb.h (renamed from drivers/video/riva/rivafb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/s1d13xxxfb.c (renamed from drivers/video/s1d13xxxfb.c) | 15 | ||||
| -rw-r--r-- | drivers/video/fbdev/s3c-fb.c (renamed from drivers/video/s3c-fb.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/s3c2410fb.c (renamed from drivers/video/s3c2410fb.c) | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/s3c2410fb.h (renamed from drivers/video/s3c2410fb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/s3fb.c (renamed from drivers/video/s3fb.c) | 77 | ||||
| -rw-r--r-- | drivers/video/fbdev/sa1100fb.c (renamed from drivers/video/sa1100fb.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/sa1100fb.h (renamed from drivers/video/sa1100fb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/savage/Makefile (renamed from drivers/video/savage/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/savage/savagefb-i2c.c (renamed from drivers/video/savage/savagefb-i2c.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/savage/savagefb.h (renamed from drivers/video/savage/savagefb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/savage/savagefb_accel.c (renamed from drivers/video/savage/savagefb_accel.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/savage/savagefb_driver.c (renamed from drivers/video/savage/savagefb_driver.c) | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/sbuslib.c (renamed from drivers/video/sbuslib.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/sbuslib.h (renamed from drivers/video/sbuslib.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sh7760fb.c (renamed from drivers/video/sh7760fb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sh_mipi_dsi.c (renamed from drivers/video/sh_mipi_dsi.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sh_mobile_hdmi.c (renamed from drivers/video/sh_mobile_hdmi.c) | 19 | ||||
| -rw-r--r-- | drivers/video/fbdev/sh_mobile_lcdcfb.c (renamed from drivers/video/sh_mobile_lcdcfb.c) | 16 | ||||
| -rw-r--r-- | drivers/video/fbdev/sh_mobile_lcdcfb.h (renamed from drivers/video/sh_mobile_lcdcfb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sh_mobile_meram.c (renamed from drivers/video/sh_mobile_meram.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/simplefb.c (renamed from drivers/video/simplefb.c) | 24 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/300vtbl.h (renamed from drivers/video/sis/300vtbl.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/310vtbl.h (renamed from drivers/video/sis/310vtbl.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/Makefile (renamed from drivers/video/sis/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/init.c (renamed from drivers/video/sis/init.c) | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/init.h (renamed from drivers/video/sis/init.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/init301.c (renamed from drivers/video/sis/init301.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/init301.h (renamed from drivers/video/sis/init301.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/initdef.h (renamed from drivers/video/sis/initdef.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/initextlfb.c (renamed from drivers/video/sis/initextlfb.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/oem300.h (renamed from drivers/video/sis/oem300.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/oem310.h (renamed from drivers/video/sis/oem310.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/sis.h (renamed from drivers/video/sis/sis.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/sis_accel.c (renamed from drivers/video/sis/sis_accel.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/sis_accel.h (renamed from drivers/video/sis/sis_accel.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/sis_main.c (renamed from drivers/video/sis/sis_main.c) | 8 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/sis_main.h (renamed from drivers/video/sis/sis_main.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/vgatypes.h (renamed from drivers/video/sis/vgatypes.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sis/vstruct.h (renamed from drivers/video/sis/vstruct.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/skeletonfb.c (renamed from drivers/video/skeletonfb.c) | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/sm501fb.c (renamed from drivers/video/sm501fb.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/smscufx.c (renamed from drivers/video/smscufx.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/ssd1307fb.c (renamed from drivers/video/ssd1307fb.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/sstfb.c (renamed from drivers/video/sstfb.c) | 8 | ||||
| -rw-r--r-- | drivers/video/fbdev/sticore.h (renamed from drivers/video/sticore.h) | 62 | ||||
| -rw-r--r-- | drivers/video/fbdev/stifb.c (renamed from drivers/video/stifb.c) | 14 | ||||
| -rw-r--r-- | drivers/video/fbdev/sunxvr1000.c (renamed from drivers/video/sunxvr1000.c) | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/sunxvr2500.c (renamed from drivers/video/sunxvr2500.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/sunxvr500.c (renamed from drivers/video/sunxvr500.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/tcx.c (renamed from drivers/video/tcx.c) | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/tdfxfb.c (renamed from drivers/video/tdfxfb.c) | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/tgafb.c (renamed from drivers/video/tgafb.c) | 309 | ||||
| -rw-r--r-- | drivers/video/fbdev/tmiofb.c (renamed from drivers/video/tmiofb.c) | 13 | ||||
| -rw-r--r-- | drivers/video/fbdev/tridentfb.c (renamed from drivers/video/tridentfb.c) | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/udlfb.c (renamed from drivers/video/udlfb.c) | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/uvesafb.c (renamed from drivers/video/uvesafb.c) | 38 | ||||
| -rw-r--r-- | drivers/video/fbdev/valkyriefb.c (renamed from drivers/video/valkyriefb.c) | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/valkyriefb.h (renamed from drivers/video/valkyriefb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/vermilion/Makefile (renamed from drivers/video/vermilion/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/vermilion/cr_pll.c (renamed from drivers/video/vermilion/cr_pll.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/vermilion/vermilion.c (renamed from drivers/video/vermilion/vermilion.c) | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/vermilion/vermilion.h (renamed from drivers/video/vermilion/vermilion.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/vesafb.c (renamed from drivers/video/vesafb.c) | 16 | ||||
| -rw-r--r-- | drivers/video/fbdev/vfb.c (renamed from drivers/video/vfb.c) | 10 | ||||
| -rw-r--r-- | drivers/video/fbdev/vga16fb.c (renamed from drivers/video/vga16fb.c) | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/Makefile (renamed from drivers/video/via/Makefile) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/accel.c (renamed from drivers/video/via/accel.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/accel.h (renamed from drivers/video/via/accel.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/chip.h (renamed from drivers/video/via/chip.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/debug.h (renamed from drivers/video/via/debug.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/dvi.c (renamed from drivers/video/via/dvi.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/dvi.h (renamed from drivers/video/via/dvi.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/global.c (renamed from drivers/video/via/global.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/global.h (renamed from drivers/video/via/global.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/hw.c (renamed from drivers/video/via/hw.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/hw.h (renamed from drivers/video/via/hw.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/ioctl.c (renamed from drivers/video/via/ioctl.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/ioctl.h (renamed from drivers/video/via/ioctl.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/lcd.c (renamed from drivers/video/via/lcd.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/lcd.h (renamed from drivers/video/via/lcd.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/share.h (renamed from drivers/video/via/share.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/tblDPASetting.c (renamed from drivers/video/via/tblDPASetting.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/tblDPASetting.h (renamed from drivers/video/via/tblDPASetting.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via-core.c (renamed from drivers/video/via/via-core.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via-gpio.c (renamed from drivers/video/via/via-gpio.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_aux.c (renamed from drivers/video/via/via_aux.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_aux.h (renamed from drivers/video/via/via_aux.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_aux_ch7301.c (renamed from drivers/video/via/via_aux_ch7301.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_aux_edid.c (renamed from drivers/video/via/via_aux_edid.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_aux_sii164.c (renamed from drivers/video/via/via_aux_sii164.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_aux_vt1621.c (renamed from drivers/video/via/via_aux_vt1621.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_aux_vt1622.c (renamed from drivers/video/via/via_aux_vt1622.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_aux_vt1625.c (renamed from drivers/video/via/via_aux_vt1625.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_aux_vt1631.c (renamed from drivers/video/via/via_aux_vt1631.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_aux_vt1632.c (renamed from drivers/video/via/via_aux_vt1632.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_aux_vt1636.c (renamed from drivers/video/via/via_aux_vt1636.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_clock.c (renamed from drivers/video/via/via_clock.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_clock.h (renamed from drivers/video/via/via_clock.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_i2c.c (renamed from drivers/video/via/via_i2c.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_modesetting.c (renamed from drivers/video/via/via_modesetting.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_modesetting.h (renamed from drivers/video/via/via_modesetting.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_utility.c (renamed from drivers/video/via/via_utility.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/via_utility.h (renamed from drivers/video/via/via_utility.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/viafbdev.c (renamed from drivers/video/via/viafbdev.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/viafbdev.h (renamed from drivers/video/via/viafbdev.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/viamode.c (renamed from drivers/video/via/viamode.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/viamode.h (renamed from drivers/video/via/viamode.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/vt1636.c (renamed from drivers/video/via/vt1636.c) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/via/vt1636.h (renamed from drivers/video/via/vt1636.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/vt8500lcdfb.c (renamed from drivers/video/vt8500lcdfb.c) | 29 | ||||
| -rw-r--r-- | drivers/video/fbdev/vt8500lcdfb.h (renamed from drivers/video/vt8500lcdfb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/vt8623fb.c (renamed from drivers/video/vt8623fb.c) | 43 | ||||
| -rw-r--r-- | drivers/video/fbdev/w100fb.c (renamed from drivers/video/w100fb.c) | 7 | ||||
| -rw-r--r-- | drivers/video/fbdev/w100fb.h (renamed from drivers/video/w100fb.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/wm8505fb.c (renamed from drivers/video/wm8505fb.c) | 16 | ||||
| -rw-r--r-- | drivers/video/fbdev/wm8505fb_regs.h (renamed from drivers/video/wm8505fb_regs.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/wmt_ge_rops.c (renamed from drivers/video/wmt_ge_rops.c) | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/wmt_ge_rops.h (renamed from drivers/video/wmt_ge_rops.h) | 0 | ||||
| -rw-r--r-- | drivers/video/fbdev/xen-fbfront.c (renamed from drivers/video/xen-fbfront.c) | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/xilinxfb.c (renamed from drivers/video/xilinxfb.c) | 76 | ||||
| -rw-r--r-- | drivers/video/logo/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/video/logo/logo.c | 6 | ||||
| -rw-r--r-- | drivers/video/mbx/Makefile | 4 | ||||
| -rw-r--r-- | drivers/video/mmp/Kconfig | 11 | ||||
| -rw-r--r-- | drivers/video/of_display_timing.c | 14 | ||||
| -rw-r--r-- | drivers/video/omap/Makefile | 26 | ||||
| -rw-r--r-- | drivers/video/omap2/Kconfig | 10 | ||||
| -rw-r--r-- | drivers/video/omap2/dss/hdmi.c | 1184 | ||||
| -rw-r--r-- | drivers/video/omap2/dss/ti_hdmi.h | 187 | ||||
| -rw-r--r-- | drivers/video/omap2/dss/venc_panel.c | 232 | ||||
| -rw-r--r-- | drivers/video/output.c | 133 | ||||
| -rw-r--r-- | drivers/video/sgivwfb.c | 889 | 
552 files changed, 13672 insertions, 12914 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 84b685f7ab6..8bf495ffb02 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -19,2492 +19,37 @@ source "drivers/char/agp/Kconfig"  source "drivers/gpu/vga/Kconfig" +source "drivers/gpu/host1x/Kconfig" +source "drivers/gpu/ipu-v3/Kconfig" + +menu "Direct Rendering Manager"  source "drivers/gpu/drm/Kconfig" +endmenu -source "drivers/gpu/host1x/Kconfig" +menu "Frame buffer Devices" +source "drivers/video/fbdev/Kconfig" +endmenu + +source "drivers/video/backlight/Kconfig"  config VGASTATE         tristate         default n -config VIDEO_OUTPUT_CONTROL -	tristate "Lowlevel video output switch controls" -	help -	  This framework adds support for low-level control of the video  -	  output switch. -  config VIDEOMODE_HELPERS  	bool  config HDMI  	bool -menuconfig FB -	tristate "Support for frame buffer devices" -	---help--- -	  The frame buffer device provides an abstraction for the graphics -	  hardware. It represents the frame buffer of some video hardware and -	  allows application software to access the graphics hardware through -	  a well-defined interface, so the software doesn't need to know -	  anything about the low-level (hardware register) stuff. - -	  Frame buffer devices work identically across the different -	  architectures supported by Linux and make the implementation of -	  application programs easier and more portable; at this point, an X -	  server exists which uses the frame buffer device exclusively. -	  On several non-X86 architectures, the frame buffer device is the -	  only way to use the graphics hardware. - -	  The device is accessed through special device nodes, usually located -	  in the /dev directory, i.e. /dev/fb*. - -	  You need an utility program called fbset to make full use of frame -	  buffer devices. Please read <file:Documentation/fb/framebuffer.txt> -	  and the Framebuffer-HOWTO at -	  <http://www.munted.org.uk/programming/Framebuffer-HOWTO-1.3.html> for more -	  information. - -	  Say Y here and to the driver for your graphics board below if you -	  are compiling a kernel for a non-x86 architecture. - -	  If you are compiling for the x86 architecture, you can say Y if you -	  want to play with it, but it is not essential. Please note that -	  running graphical applications that directly touch the hardware -	  (e.g. an accelerated X server) and that are not frame buffer -	  device-aware may cause unexpected results. If unsure, say N. - -config FIRMWARE_EDID -       bool "Enable firmware EDID" -       depends on FB -       default n -       ---help--- -         This enables access to the EDID transferred from the firmware. -	 On the i386, this is from the Video BIOS. Enable this if DDC/I2C -	 transfers do not work for your driver and if you are using -	 nvidiafb, i810fb or savagefb. - -	 In general, choosing Y for this option is safe.  If you -	 experience extremely long delays while booting before you get -	 something on your display, try setting this to N.  Matrox cards in -	 combination with certain motherboards and monitors are known to -	 suffer from this problem. - -config FB_DDC -       tristate -       depends on FB -       select I2C_ALGOBIT -       select I2C -       default n - -config FB_BOOT_VESA_SUPPORT -	bool -	depends on FB -	default n -	---help--- -	  If true, at least one selected framebuffer driver can take advantage -	  of VESA video modes set at an early boot stage via the vga= parameter. - -config FB_CFB_FILLRECT -	tristate -	depends on FB -	default n -	---help--- -	  Include the cfb_fillrect function for generic software rectangle -	  filling. This is used by drivers that don't provide their own -	  (accelerated) version. - -config FB_CFB_COPYAREA -	tristate -	depends on FB -	default n -	---help--- -	  Include the cfb_copyarea function for generic software area copying. -	  This is used by drivers that don't provide their own (accelerated) -	  version. - -config FB_CFB_IMAGEBLIT -	tristate -	depends on FB -	default n -	---help--- -	  Include the cfb_imageblit function for generic software image -	  blitting. This is used by drivers that don't provide their own -	  (accelerated) version. - -config FB_CFB_REV_PIXELS_IN_BYTE -	bool -	depends on FB -	default n -	---help--- -	  Allow generic frame-buffer functions to work on displays with 1, 2 -	  and 4 bits per pixel depths which has opposite order of pixels in -	  byte order to bytes in long order. - -config FB_SYS_FILLRECT -	tristate -	depends on FB -	default n -	---help--- -	  Include the sys_fillrect function for generic software rectangle -	  filling. This is used by drivers that don't provide their own -	  (accelerated) version and the framebuffer is in system RAM. - -config FB_SYS_COPYAREA -	tristate -	depends on FB -	default n -	---help--- -	  Include the sys_copyarea function for generic software area copying. -	  This is used by drivers that don't provide their own (accelerated) -	  version and the framebuffer is in system RAM. - -config FB_SYS_IMAGEBLIT -	tristate -	depends on FB -	default n -	---help--- -	  Include the sys_imageblit function for generic software image -	  blitting. This is used by drivers that don't provide their own -	  (accelerated) version and the framebuffer is in system RAM. - -menuconfig FB_FOREIGN_ENDIAN -	bool "Framebuffer foreign endianness support" -	depends on FB -	---help--- -	  This menu will let you enable support for the framebuffers with -	  non-native endianness (e.g. Little-Endian framebuffer on a -	  Big-Endian machine). Most probably you don't have such hardware, -	  so it's safe to say "n" here. - -choice -	prompt "Choice endianness support" -	depends on FB_FOREIGN_ENDIAN - -config FB_BOTH_ENDIAN -	bool "Support for Big- and Little-Endian framebuffers" - -config FB_BIG_ENDIAN -	bool "Support for Big-Endian framebuffers only" - -config FB_LITTLE_ENDIAN -	bool "Support for Little-Endian framebuffers only" - -endchoice - -config FB_SYS_FOPS -       tristate -       depends on FB -       default n - -config FB_DEFERRED_IO -	bool -	depends on FB - -config FB_HECUBA -	tristate -	depends on FB -	depends on FB_DEFERRED_IO - -config FB_SVGALIB -	tristate -	depends on FB -	default n -	---help--- -	  Common utility functions useful to fbdev drivers of VGA-based -	  cards. - -config FB_MACMODES -       tristate -       depends on FB -       default n - -config FB_BACKLIGHT -	bool -	depends on FB -	select BACKLIGHT_LCD_SUPPORT -	select BACKLIGHT_CLASS_DEVICE -	default n - -config FB_MODE_HELPERS -        bool "Enable Video Mode Handling Helpers" -        depends on FB -	default n -	---help--- -	  This enables functions for handling video modes using the -	  Generalized Timing Formula and the EDID parser. A few drivers rely -          on this feature such as the radeonfb, rivafb, and the i810fb. If -	  your driver does not take advantage of this feature, choosing Y will -	  just increase the kernel size by about 5K. - -config FB_TILEBLITTING -       bool "Enable Tile Blitting Support" -       depends on FB -       default n -       ---help--- -         This enables tile blitting.  Tile blitting is a drawing technique -	 where the screen is divided into rectangular sections (tiles), whereas -	 the standard blitting divides the screen into pixels. Because the -	 default drawing element is a tile, drawing functions will be passed -	 parameters in terms of number of tiles instead of number of pixels. -	 For example, to draw a single character, instead of using bitmaps, -	 an index to an array of bitmaps will be used.  To clear or move a -	 rectangular section of a screen, the rectangle will be described in -	 terms of number of tiles in the x- and y-axis. - -	 This is particularly important to one driver, matroxfb.  If -	 unsure, say N. - -comment "Frame buffer hardware drivers" -	depends on FB - -config FB_GRVGA -	tristate "Aeroflex Gaisler framebuffer support" -	depends on FB && SPARC -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler. - -config FB_CIRRUS -	tristate "Cirrus Logic support" -	depends on FB && (ZORRO || PCI) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  This enables support for Cirrus Logic GD542x/543x based boards on -	  Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. - -	  If you have a PCI-based system, this enables support for these -	  chips: GD-543x, GD-544x, GD-5480. - -	  Please read the file <file:Documentation/fb/cirrusfb.txt>. - -	  Say N unless you have such a graphics board or plan to get one -	  before you next recompile the kernel. - -config FB_PM2 -	tristate "Permedia2 support" -	depends on FB && ((AMIGA && BROKEN) || PCI) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for cards based on -	  the 3D Labs Permedia, Permedia 2 and Permedia 2V chips. -	  The driver was tested on the following cards: -		Diamond FireGL 1000 PRO AGP -		ELSA Gloria Synergy PCI -		Appian Jeronimo PRO (both heads) PCI -		3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI -		Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC -		ASK Graphic Blaster Exxtreme AGP - -	  To compile this driver as a module, choose M here: the -	  module will be called pm2fb. - -config FB_PM2_FIFO_DISCONNECT -	bool "enable FIFO disconnect feature" -	depends on FB_PM2 && PCI -	help -	  Support the Permedia2 FIFO disconnect feature. - -config FB_ARMCLCD -	tristate "ARM PrimeCell PL110 support" -	depends on FB && ARM && ARM_AMBA -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This framebuffer device driver is for the ARM PrimeCell PL110 -	  Colour LCD controller.  ARM PrimeCells provide the building -	  blocks for System on a Chip devices. - -	  If you want to compile this as a module (=code which can be -	  inserted into and removed from the running kernel), say M -	  here and read <file:Documentation/kbuild/modules.txt>.  The module -	  will be called amba-clcd. - -config FB_ACORN -	bool "Acorn VIDC support" -	depends on (FB = y) && ARM && ARCH_ACORN -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the Acorn VIDC graphics -	  hardware found in Acorn RISC PCs and other ARM-based machines.  If -	  unsure, say N. - -config FB_CLPS711X -	bool "CLPS711X LCD support" -	depends on (FB = y) && ARM && ARCH_CLPS711X -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  Say Y to enable the Framebuffer driver for the CLPS7111 and -	  EP7212 processors. - -config FB_SA1100 -	bool "SA-1100 LCD support" -	depends on (FB = y) && ARM && ARCH_SA1100 -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is a framebuffer device for the SA-1100 LCD Controller. -	  See <http://www.linux-fbdev.org/> for information on framebuffer -	  devices. - -	  If you plan to use the LCD display with your SA-1100 system, say -	  Y here. - -config FB_IMX -	tristate "Freescale i.MX1/21/25/27 LCD support" -	depends on FB && IMX_HAVE_PLATFORM_IMX_FB -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_MODE_HELPERS -	select VIDEOMODE_HELPERS - -config FB_CYBER2000 -	tristate "CyberPro 2000/2010/5000 support" -	depends on FB && PCI && (BROKEN || !SPARC64) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This enables support for the Integraphics CyberPro 20x0 and 5000 -	  VGA chips used in the Rebel.com Netwinder and other machines. -	  Say Y if you have a NetWinder or a graphics card containing this -	  device, otherwise say N. - -config FB_CYBER2000_DDC -	bool "DDC for CyberPro support" -	depends on FB_CYBER2000 -	select FB_DDC -	default y -	help -	  Say Y here if you want DDC support for your CyberPro graphics -	  card. This is only I2C bus support, driver does not use EDID. - -config FB_CYBER2000_I2C -	bool "CyberPro 2000/2010/5000 I2C support" -	depends on FB_CYBER2000 && I2C && ARCH_NETWINDER -	select I2C_ALGOBIT -	help -	  Enable support for the I2C video decoder interface on the -	  Integraphics CyberPro 20x0 and 5000 VGA chips.  This is used -	  on the Netwinder machines for the SAA7111 video capture. - -config FB_APOLLO -	bool -	depends on (FB = y) && APOLLO -	default y -	select FB_CFB_FILLRECT -	select FB_CFB_IMAGEBLIT - -config FB_Q40 -	bool -	depends on (FB = y) && Q40 -	default y -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT - -config FB_AMIGA -	tristate "Amiga native chipset support" -	depends on FB && AMIGA -	help -	  This is the frame buffer device driver for the builtin graphics -	  chipset found in Amigas. - -	  To compile this driver as a module, choose M here: the -	  module will be called amifb. - -config FB_AMIGA_OCS -	bool "Amiga OCS chipset support" -	depends on FB_AMIGA -	help -	  This enables support for the original Agnus and Denise video chips, -	  found in the Amiga 1000 and most A500's and A2000's. If you intend -	  to run Linux on any of these systems, say Y; otherwise say N. - -config FB_AMIGA_ECS -	bool "Amiga ECS chipset support" -	depends on FB_AMIGA -	help -	  This enables support for the Enhanced Chip Set, found in later -	  A500's, later A2000's, the A600, the A3000, the A3000T and CDTV. If -	  you intend to run Linux on any of these systems, say Y; otherwise -	  say N. - -config FB_AMIGA_AGA -	bool "Amiga AGA chipset support" -	depends on FB_AMIGA -	help -	  This enables support for the Advanced Graphics Architecture (also -	  known as the AGA or AA) Chip Set, found in the A1200, A4000, A4000T -	  and CD32. If you intend to run Linux on any of these systems, say Y; -	  otherwise say N. - -config FB_FM2 -	bool "Amiga FrameMaster II/Rainbow II support" -	depends on (FB = y) && ZORRO -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the Amiga FrameMaster -	  card from BSC (exhibited 1992 but not shipped as a CBM product). - -config FB_ARC -	tristate "Arc Monochrome LCD board support" -	depends on FB && X86 -	select FB_SYS_FILLRECT -	select FB_SYS_COPYAREA -	select FB_SYS_IMAGEBLIT -	select FB_SYS_FOPS -	help -	  This enables support for the Arc Monochrome LCD board. The board -	  is based on the KS-108 lcd controller and is typically a matrix -	  of 2*n chips. This driver was tested with a 128x64 panel. This -	  driver supports it for use with x86 SBCs through a 16 bit GPIO -	  interface (8 bit data, 8 bit control). If you anticipate using -	  this driver, say Y or M; otherwise say N. You must specify the -	  GPIO IO address to be used for setting control and data. - -config FB_ATARI -	bool "Atari native chipset support" -	depends on (FB = y) && ATARI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the builtin graphics -	  chipset found in Ataris. - -config FB_OF -	bool "Open Firmware frame buffer device support" -	depends on (FB = y) && (PPC64 || PPC_OF) && (!PPC_PSERIES || PCI) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_MACMODES -	help -	  Say Y if you want support with Open Firmware for your graphics -	  board. - -config FB_CONTROL -	bool "Apple \"control\" display support" -	depends on (FB = y) && PPC_PMAC && PPC32 -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_MACMODES -	help -	  This driver supports a frame buffer for the graphics adapter in the -	  Power Macintosh 7300 and others. - -config FB_PLATINUM -	bool "Apple \"platinum\" display support" -	depends on (FB = y) && PPC_PMAC && PPC32 -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_MACMODES -	help -	  This driver supports a frame buffer for the "platinum" graphics -	  adapter in some Power Macintoshes. - -config FB_VALKYRIE -	bool "Apple \"valkyrie\" display support" -	depends on (FB = y) && (MAC || (PPC_PMAC && PPC32)) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_MACMODES -	help -	  This driver supports a frame buffer for the "valkyrie" graphics -	  adapter in some Power Macintoshes. - -config FB_CT65550 -	bool "Chips 65550 display support" -	depends on (FB = y) && PPC32 && PCI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the Chips & Technologies -	  65550 graphics chip in PowerBooks. - -config FB_ASILIANT -	bool "Asiliant (Chips) 69000 display support" -	depends on (FB = y) && PCI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the Asiliant 69030 chipset - -config FB_IMSTT -	bool "IMS Twin Turbo display support" -	depends on (FB = y) && PCI -	select FB_CFB_IMAGEBLIT -	select FB_MACMODES if PPC -	help -	  The IMS Twin Turbo is a PCI-based frame buffer card bundled with -	  many Macintosh and compatible computers. - -config FB_VGA16 -	tristate "VGA 16-color graphics support" -	depends on FB && (X86 || PPC) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select VGASTATE -	select FONT_8x16 if FRAMEBUFFER_CONSOLE -	help -	  This is the frame buffer device driver for VGA 16 color graphic -	  cards. Say Y if you have such a card. - -	  To compile this driver as a module, choose M here: the -	  module will be called vga16fb. - -config FB_BF54X_LQ043 -	tristate "SHARP LQ043 TFT LCD (BF548 EZKIT)" -	depends on FB && (BF54x) && !BF542 -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	 This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD - -config FB_BFIN_T350MCQB -	tristate "Varitronix COG-T350MCQB TFT LCD display (BF527 EZKIT)" -	depends on FB && BLACKFIN -	select BFIN_GPTIMERS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	 This is the framebuffer device driver for a Varitronix VL-PS-COG-T350MCQB-01 display TFT LCD -	 This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI -	 It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK. - -config FB_BFIN_LQ035Q1 -	tristate "SHARP LQ035Q1DH02 TFT LCD" -	depends on FB && BLACKFIN && SPI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select BFIN_GPTIMERS -	help -	  This is the framebuffer device driver for a SHARP LQ035Q1DH02 TFT display found on -	  the Blackfin Landscape LCD EZ-Extender Card. -	  This display is a QVGA 320x240 18-bit RGB display interfaced by an 16-bit wide PPI -	  It uses PPI[0..15] PPI_FS1, PPI_FS2 and PPI_CLK. - -	  To compile this driver as a module, choose M here: the -	  module will be called bfin-lq035q1-fb. - -config FB_BF537_LQ035 -	tristate "SHARP LQ035 TFT LCD (BF537 STAMP)" -	depends on FB && (BF534 || BF536 || BF537) && I2C_BLACKFIN_TWI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select BFIN_GPTIMERS -	help -	  This is the framebuffer device for a SHARP LQ035Q7DB03 TFT LCD -	  attached to a BF537. - -	  To compile this driver as a module, choose M here: the -	  module will be called bf537-lq035. - -config FB_BFIN_7393 -	tristate "Blackfin ADV7393 Video encoder" -	depends on FB && BLACKFIN -	select I2C -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the framebuffer device for a ADV7393 video encoder -	  attached to a Blackfin on the PPI port. -	  If your Blackfin board has a ADV7393 select Y. - -	  To compile this driver as a module, choose M here: the -	  module will be called bfin_adv7393fb. - -choice -	prompt  "Video mode support" -	depends on FB_BFIN_7393 -	default NTSC - -config NTSC -	bool 'NTSC 720x480' - -config PAL -	bool 'PAL 720x576' - -config NTSC_640x480 -	bool 'NTSC 640x480 (Experimental)' - -config PAL_640x480 -	bool 'PAL 640x480 (Experimental)' - -config NTSC_YCBCR -	bool 'NTSC 720x480 YCbCR input' - -config PAL_YCBCR -	bool 'PAL 720x576 YCbCR input' - -endchoice - -choice -	prompt  "Size of ADV7393 frame buffer memory Single/Double Size" -	depends on (FB_BFIN_7393) -	default ADV7393_1XMEM - -config ADV7393_1XMEM -	bool 'Single' - -config ADV7393_2XMEM -	bool 'Double' -endchoice - -config FB_STI -	tristate "HP STI frame buffer device support" -	depends on FB && PARISC -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select STI_CONSOLE -	select VT -	default y -	---help--- -	  STI refers to the HP "Standard Text Interface" which is a set of -	  BIOS routines contained in a ROM chip in HP PA-RISC based machines. -	  Enabling this option will implement the linux framebuffer device -	  using calls to the STI BIOS routines for initialisation. -	 -	  If you enable this option, you will get a planar framebuffer device -	  /dev/fb which will work on the most common HP graphic cards of the -	  NGLE family, including the artist chips (in the 7xx and Bxxx series), -	  HCRX, HCRX24, CRX, CRX24 and VisEG series. - -	  It is safe to enable this option, so you should probably say "Y". - -config FB_MAC -	bool "Generic Macintosh display support" -	depends on (FB = y) && MAC -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_MACMODES - -config FB_HP300 -	bool -	depends on (FB = y) && DIO -	select FB_CFB_IMAGEBLIT -	default y - -config FB_TGA -	tristate "TGA/SFB+ framebuffer support" -	depends on FB && (ALPHA || TC) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select BITREVERSE -	---help--- -	  This is the frame buffer device driver for generic TGA and SFB+ -	  graphic cards.  These include DEC ZLXp-E1, -E2 and -E3 PCI cards, -	  also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3 -	  TURBOchannel cards, also known as PMAGD-A, -B and -C. - -	  Due to hardware limitations ZLX-E2 and E3 cards are not supported -	  for DECstation 5000/200 systems.  Additionally due to firmware -	  limitations these cards may cause troubles with booting DECstation -	  5000/240 and /260 systems, but are fully supported under Linux if -	  you manage to get it going. ;-) - -	  Say Y if you have one of those. - -config FB_UVESA -	tristate "Userspace VESA VGA graphics support" -	depends on FB && CONNECTOR -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_MODE_HELPERS -	help -	  This is the frame buffer driver for generic VBE 2.0 compliant -	  graphic cards. It can also take advantage of VBE 3.0 features, -	  such as refresh rate adjustment. - -	  This driver generally provides more features than vesafb but -	  requires a userspace helper application called 'v86d'. See -	  <file:Documentation/fb/uvesafb.txt> for more information. - -	  If unsure, say N. - -config FB_VESA -	bool "VESA VGA graphics support" -	depends on (FB = y) && X86 -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_BOOT_VESA_SUPPORT -	help -	  This is the frame buffer device driver for generic VESA 2.0 -	  compliant graphic cards. The older VESA 1.2 cards are not supported. -	  You will get a boot time penguin logo at no additional cost. Please -	  read <file:Documentation/fb/vesafb.txt>. If unsure, say Y. - -config FB_EFI -	bool "EFI-based Framebuffer Support" -	depends on (FB = y) && X86 && EFI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the EFI frame buffer device driver. If the firmware on -	  your platform is EFI 1.10 or UEFI 2.0, select Y to add support for -	  using the EFI framebuffer as your console. - -config FB_N411 -       tristate "N411 Apollo/Hecuba devkit support" -       depends on FB && X86 && MMU -       select FB_SYS_FILLRECT -       select FB_SYS_COPYAREA -       select FB_SYS_IMAGEBLIT -       select FB_SYS_FOPS -       select FB_DEFERRED_IO -       select FB_HECUBA -       help -         This enables support for the Apollo display controller in its -         Hecuba form using the n411 devkit. - -config FB_HGA -	tristate "Hercules mono graphics support" -	depends on FB && X86 -	help -	  Say Y here if you have a Hercules mono graphics card. - -	  To compile this driver as a module, choose M here: the -	  module will be called hgafb. - -	  As this card technology is at least 25 years old, -	  most people will answer N here. - -config FB_SGIVW -	tristate "SGI Visual Workstation framebuffer support" -	depends on FB && X86_VISWS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  SGI Visual Workstation support for framebuffer graphics. - -config FB_GBE -	bool "SGI Graphics Backend frame buffer support" -	depends on (FB = y) && (SGI_IP32 || X86_VISWS) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT - 	help -	  This is the frame buffer device driver for SGI Graphics Backend. -	  This chip is used in SGI O2 and Visual Workstation 320/540. - -config FB_GBE_MEM -	int "Video memory size in MB" -	depends on FB_GBE -	default 4 -	help -	  This is the amount of memory reserved for the framebuffer, -	  which can be any value between 1MB and 8MB. - -config FB_SBUS -	bool "SBUS and UPA framebuffers" -	depends on (FB = y) && SPARC -	help -	  Say Y if you want support for SBUS or UPA based frame buffer device. - -config FB_BW2 -	bool "BWtwo support" -	depends on (FB = y) && (SPARC && FB_SBUS) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the BWtwo frame buffer. - -config FB_CG3 -	bool "CGthree support" -	depends on (FB = y) && (SPARC && FB_SBUS) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the CGthree frame buffer. - -config FB_CG6 -	bool "CGsix (GX,TurboGX) support" -	depends on (FB = y) && (SPARC && FB_SBUS) -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the CGsix (GX, TurboGX) -	  frame buffer. - -config FB_FFB -	bool "Creator/Creator3D/Elite3D support" -	depends on FB_SBUS && SPARC64 -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the Creator, Creator3D, -	  and Elite3D graphics boards. - -config FB_TCX -	bool "TCX (SS4/SS5 only) support" -	depends on FB_SBUS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the TCX 24/8bit frame -	  buffer. - -config FB_CG14 -	bool "CGfourteen (SX) support" -	depends on FB_SBUS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the CGfourteen frame -	  buffer on Desktop SPARCsystems with the SX graphics option. - -config FB_P9100 -	bool "P9100 (Sparcbook 3 only) support" -	depends on FB_SBUS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the P9100 card -	  supported on Sparcbook 3 machines. - -config FB_LEO -	bool "Leo (ZX) support" -	depends on FB_SBUS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the SBUS-based Sun ZX -	  (leo) frame buffer cards. - -config FB_IGA -	bool "IGA 168x display support" -	depends on (FB = y) && SPARC32 -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the framebuffer device for the INTERGRAPHICS 1680 and -	  successor frame buffer cards. - -config FB_XVR500 -	bool "Sun XVR-500 3DLABS Wildcat support" -	depends on (FB = y) && PCI && SPARC64 -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the framebuffer device for the Sun XVR-500 and similar -	  graphics cards based upon the 3DLABS Wildcat chipset.  The driver -	  only works on sparc64 systems where the system firmware has -	  mostly initialized the card already.  It is treated as a -	  completely dumb framebuffer device. - -config FB_XVR2500 -	bool "Sun XVR-2500 3DLABS Wildcat support" -	depends on (FB = y) && PCI && SPARC64 -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the framebuffer device for the Sun XVR-2500 and similar -	  graphics cards based upon the 3DLABS Wildcat chipset.  The driver -	  only works on sparc64 systems where the system firmware has -	  mostly initialized the card already.  It is treated as a -	  completely dumb framebuffer device. - -config FB_XVR1000 -	bool "Sun XVR-1000 support" -	depends on (FB = y) && SPARC64 -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the framebuffer device for the Sun XVR-1000 and similar -	  graphics cards.  The driver only works on sparc64 systems where -	  the system firmware has mostly initialized the card already.  It -	  is treated as a completely dumb framebuffer device. - -config FB_PVR2 -	tristate "NEC PowerVR 2 display support" -	depends on FB && SH_DREAMCAST -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Say Y here if you have a PowerVR 2 card in your box.  If you plan to -	  run linux on your Dreamcast, you will have to say Y here. -	  This driver may or may not work on other PowerVR 2 cards, but is -	  totally untested.  Use at your own risk.  If unsure, say N. - -	  To compile this driver as a module, choose M here: the -	  module will be called pvr2fb. - -	  You can pass several parameters to the driver at boot time or at -	  module load time.  The parameters look like "video=pvr2:XXX", where -	  the meaning of XXX can be found at the end of the main source file -	  (<file:drivers/video/pvr2fb.c>). Please see the file -	  <file:Documentation/fb/pvr2fb.txt>. - -config FB_S1D13XXX -	tristate "Epson S1D13XXX framebuffer support" -	depends on FB -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  Support for S1D13XXX framebuffer device family (currently only -	  working with S1D13806). Product specs at -	  <http://vdc.epson.com/> - -config FB_ATMEL -	tristate "AT91/AT32 LCD Controller support" -	depends on FB && HAVE_FB_ATMEL -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This enables support for the AT91/AT32 LCD Controller. - -config FB_INTSRAM -	bool "Frame Buffer in internal SRAM" -	depends on FB_ATMEL && ARCH_AT91SAM9261 -	help -	  Say Y if you want to map Frame Buffer in internal SRAM. Say N if you want -	  to let frame buffer in external SDRAM. - -config FB_ATMEL_STN -	bool "Use a STN display with AT91/AT32 LCD Controller" -	depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK) -	default n -	help -	  Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD -	  Controller. Say N if you want to connect a TFT. - -	  If unsure, say N. - -config FB_NVIDIA -	tristate "nVidia Framebuffer Support" -	depends on FB && PCI -	select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT -	select FB_MODE_HELPERS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select BITREVERSE -	select VGASTATE -	help -	  This driver supports graphics boards with the nVidia chips, TNT -	  and newer. For very old chipsets, such as the RIVA128, then use -	  the rivafb. -	  Say Y if you have such a graphics board. - -	  To compile this driver as a module, choose M here: the -	  module will be called nvidiafb. - -config FB_NVIDIA_I2C -       bool "Enable DDC Support" -       depends on FB_NVIDIA -       select FB_DDC -       help -	  This enables I2C support for nVidia Chipsets.  This is used -	  only for getting EDID information from the attached display -	  allowing for robust video mode handling and switching. - -	  Because fbdev-2.6 requires that drivers must be able to -	  independently validate video mode parameters, you should say Y -	  here. - -config FB_NVIDIA_DEBUG -	bool "Lots of debug output" -	depends on FB_NVIDIA -	default n -	help -	  Say Y here if you want the nVidia driver to output all sorts -	  of debugging information to provide to the maintainer when -	  something goes wrong. - -config FB_NVIDIA_BACKLIGHT -	bool "Support for backlight control" -	depends on FB_NVIDIA -	default y -	help -	  Say Y here if you want to control the backlight of your display. - -config FB_RIVA -	tristate "nVidia Riva support" -	depends on FB && PCI -	select FB_BACKLIGHT if FB_RIVA_BACKLIGHT -	select FB_MODE_HELPERS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select BITREVERSE -	select VGASTATE -	help -	  This driver supports graphics boards with the nVidia Riva/Geforce -	  chips. -	  Say Y if you have such a graphics board. - -	  To compile this driver as a module, choose M here: the -	  module will be called rivafb. - -config FB_RIVA_I2C -       bool "Enable DDC Support" -       depends on FB_RIVA -       select FB_DDC -       help -	  This enables I2C support for nVidia Chipsets.  This is used -	  only for getting EDID information from the attached display -	  allowing for robust video mode handling and switching. - -	  Because fbdev-2.6 requires that drivers must be able to -	  independently validate video mode parameters, you should say Y -	  here. - -config FB_RIVA_DEBUG -	bool "Lots of debug output" -	depends on FB_RIVA -	default n -	help -	  Say Y here if you want the Riva driver to output all sorts -	  of debugging information to provide to the maintainer when -	  something goes wrong. - -config FB_RIVA_BACKLIGHT -	bool "Support for backlight control" -	depends on FB_RIVA -	default y -	help -	  Say Y here if you want to control the backlight of your display. - -config FB_I740 -	tristate "Intel740 support" -	depends on FB && PCI -	select FB_MODE_HELPERS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select VGASTATE -	select FB_DDC -	help -	  This driver supports graphics cards based on Intel740 chip. - -config FB_I810 -	tristate "Intel 810/815 support" -	depends on FB && PCI && X86_32 && AGP_INTEL -	select FB_MODE_HELPERS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select VGASTATE -	help -	  This driver supports the on-board graphics built in to the Intel 810  -          and 815 chipsets.  Say Y if you have and plan to use such a board. - -          To compile this driver as a module, choose M here: the -	  module will be called i810fb. - -          For more information, please read  -	  <file:Documentation/fb/intel810.txt> - -config FB_I810_GTF -	bool "use VESA Generalized Timing Formula" -	depends on FB_I810 -	help -	  If you say Y, then the VESA standard, Generalized Timing Formula  -          or GTF, will be used to calculate the required video timing values -	  per video mode.  Since the GTF allows nondiscrete timings  -          (nondiscrete being a range of values as opposed to discrete being a -          set of values), you'll be able to use any combination of horizontal  -	  and vertical resolutions, and vertical refresh rates without having -	  to specify your own timing parameters.  This is especially useful -	  to maximize the performance of an aging display, or if you just  -          have a display with nonstandard dimensions. A VESA compliant  -	  monitor is recommended, but can still work with non-compliant ones. -	  If you need or want this, then select this option. The timings may  -	  not be compliant with Intel's recommended values. Use at your own  -	  risk. - -          If you say N, the driver will revert to discrete video timings  -	  using a set recommended by Intel in their documentation. -   -          If unsure, say N. - -config FB_I810_I2C -	bool "Enable DDC Support" -	depends on FB_I810 && FB_I810_GTF -	select FB_DDC -	help - -config FB_LE80578 -	tristate "Intel LE80578 (Vermilion) support" -	depends on FB && PCI && X86 -	select FB_MODE_HELPERS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This driver supports the LE80578 (Vermilion Range) chipset - -config FB_CARILLO_RANCH -	tristate "Intel Carillo Ranch support" -	depends on FB_LE80578 && FB && PCI && X86 -	help -	  This driver supports the LE80578 (Carillo Ranch) board - -config FB_INTEL -	tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support" -	depends on FB && PCI && X86 && AGP_INTEL && EXPERT -	select FB_MODE_HELPERS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_BOOT_VESA_SUPPORT if FB_INTEL = y -	depends on !DRM_I915 -	help -	  This driver supports the on-board graphics built in to the Intel -          830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. -          Say Y if you have and plan to use such a board. - -	  To make FB_INTELFB=Y work you need to say AGP_INTEL=y too. - -	  To compile this driver as a module, choose M here: the -	  module will be called intelfb. - -	  For more information, please read <file:Documentation/fb/intelfb.txt> - -config FB_INTEL_DEBUG -	bool "Intel driver Debug Messages" -	depends on FB_INTEL -	---help--- -	  Say Y here if you want the Intel driver to output all sorts -	  of debugging information to provide to the maintainer when -	  something goes wrong. - -config FB_INTEL_I2C -	bool "DDC/I2C for Intel framebuffer support" -	depends on FB_INTEL -	select FB_DDC -	default y -	help -	  Say Y here if you want DDC/I2C support for your on-board Intel graphics. - -config FB_MATROX -	tristate "Matrox acceleration" -	depends on FB && PCI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_TILEBLITTING -	select FB_MACMODES if PPC_PMAC -	---help--- -	  Say Y here if you have a Matrox Millennium, Matrox Millennium II, -	  Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox -	  Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video, -	  Matrox G400, G450 or G550 card in your box. - -	  To compile this driver as a module, choose M here: the -	  module will be called matroxfb. - -	  You can pass several parameters to the driver at boot time or at -	  module load time. The parameters look like "video=matroxfb:XXX", and -	  are described in <file:Documentation/fb/matroxfb.txt>. - -config FB_MATROX_MILLENIUM -	bool "Millennium I/II support" -	depends on FB_MATROX -	help -	  Say Y here if you have a Matrox Millennium or Matrox Millennium II -	  video card. If you select "Advanced lowlevel driver options" below, -	  you should check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp -	  packed pixel, 24 bpp packed pixel and 32 bpp packed pixel. You can -	  also use font widths different from 8. - -config FB_MATROX_MYSTIQUE -	bool "Mystique support" -	depends on FB_MATROX -	help -	  Say Y here if you have a Matrox Mystique or Matrox Mystique 220 -	  video card. If you select "Advanced lowlevel driver options" below, -	  you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp -	  packed pixel and 32 bpp packed pixel. You can also use font widths -	  different from 8. - -config FB_MATROX_G -	bool "G100/G200/G400/G450/G550 support" -	depends on FB_MATROX -	---help--- -	  Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based -	  video card. If you select "Advanced lowlevel driver options", you -	  should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed -	  pixel and 32 bpp packed pixel. You can also use font widths -	  different from 8. - -	  If you need support for G400 secondary head, you must say Y to -	  "Matrox I2C support" and "G400 second head support" right below. -	  G450/G550 secondary head and digital output are supported without -	  additional modules. - -	  The driver starts in monitor mode. You must use the matroxset tool  -	  (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to  -	  swap primary and secondary head outputs, or to change output mode.   -	  Secondary head driver always start in 640x480 resolution and you  -	  must use fbset to change it. - -	  Do not forget that second head supports only 16 and 32 bpp -	  packed pixels, so it is a good idea to compile them into the kernel -	  too. You can use only some font widths, as the driver uses generic -	  painting procedures (the secondary head does not use acceleration -	  engine). - -	  G450/G550 hardware can display TV picture only from secondary CRTC, -	  and it performs no scaling, so picture must have 525 or 625 lines. - -config FB_MATROX_I2C -	tristate "Matrox I2C support" -	depends on FB_MATROX -	select FB_DDC -	---help--- -	  This drivers creates I2C buses which are needed for accessing the -	  DDC (I2C) bus present on all Matroxes, an I2C bus which -	  interconnects Matrox optional devices, like MGA-TVO on G200 and -	  G400, and the secondary head DDC bus, present on G400 only. - -	  You can say Y or M here if you want to experiment with monitor -	  detection code. You must say Y or M here if you want to use either -	  second head of G400 or MGA-TVO on G200 or G400. - -	  If you compile it as module, it will create a module named -	  i2c-matroxfb. - -config FB_MATROX_MAVEN -	tristate "G400 second head support" -	depends on FB_MATROX_G && FB_MATROX_I2C -	---help--- -	  WARNING !!! This support does not work with G450 !!! - -	  Say Y or M here if you want to use a secondary head (meaning two -	  monitors in parallel) on G400 or MGA-TVO add-on on G200. Secondary -	  head is not compatible with accelerated XFree 3.3.x SVGA servers - -	  secondary head output is blanked while you are in X. With XFree -	  3.9.17 preview you can use both heads if you use SVGA over fbdev or -	  the fbdev driver on first head and the fbdev driver on second head. - -	  If you compile it as module, two modules are created, -	  matroxfb_crtc2 and matroxfb_maven. Matroxfb_maven is needed for -	  both G200 and G400, matroxfb_crtc2 is needed only by G400. You must -	  also load i2c-matroxfb to get it to run. - -	  The driver starts in monitor mode and you must use the matroxset -	  tool (available at -	  <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to switch it to -	  PAL or NTSC or to swap primary and secondary head outputs. -	  Secondary head driver also always start in 640x480 resolution, you -	  must use fbset to change it. - -	  Also do not forget that second head supports only 16 and 32 bpp -	  packed pixels, so it is a good idea to compile them into the kernel -	  too.  You can use only some font widths, as the driver uses generic -	  painting procedures (the secondary head does not use acceleration -	  engine). - -config FB_RADEON -	tristate "ATI Radeon display support" -	depends on FB && PCI -	select FB_BACKLIGHT if FB_RADEON_BACKLIGHT -	select FB_MODE_HELPERS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_MACMODES if PPC_OF -	help -	  Choose this option if you want to use an ATI Radeon graphics card as -	  a framebuffer device.  There are both PCI and AGP versions.  You -	  don't need to choose this to run the Radeon in plain VGA mode. - -	  There is a product page at -	  http://products.amd.com/en-us/GraphicCardResult.aspx - -config FB_RADEON_I2C -	bool "DDC/I2C for ATI Radeon support" -	depends on FB_RADEON -	select FB_DDC -	default y -	help -	  Say Y here if you want DDC/I2C support for your Radeon board.  - -config FB_RADEON_BACKLIGHT -	bool "Support for backlight control" -	depends on FB_RADEON -	default y -	help -	  Say Y here if you want to control the backlight of your display. - -config FB_RADEON_DEBUG -	bool "Lots of debug output from Radeon driver" -	depends on FB_RADEON -	default n -	help -	  Say Y here if you want the Radeon driver to output all sorts -	  of debugging information to provide to the maintainer when -	  something goes wrong. - -config FB_ATY128 -	tristate "ATI Rage128 display support" -	depends on FB && PCI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_BACKLIGHT if FB_ATY128_BACKLIGHT -	select FB_MACMODES if PPC_PMAC -	help -	  This driver supports graphics boards with the ATI Rage128 chips. -	  Say Y if you have such a graphics board and read -	  <file:Documentation/fb/aty128fb.txt>. - -	  To compile this driver as a module, choose M here: the -	  module will be called aty128fb. - -config FB_ATY128_BACKLIGHT -	bool "Support for backlight control" -	depends on FB_ATY128 -	default y -	help -	  Say Y here if you want to control the backlight of your display. - -config FB_ATY -	tristate "ATI Mach64 display support" if PCI || ATARI -	depends on FB && !SPARC32 -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_BACKLIGHT if FB_ATY_BACKLIGHT -	select FB_MACMODES if PPC -	help -	  This driver supports graphics boards with the ATI Mach64 chips. -	  Say Y if you have such a graphics board. - -	  To compile this driver as a module, choose M here: the -	  module will be called atyfb. - -config FB_ATY_CT -	bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support" -	depends on PCI && FB_ATY -	default y if SPARC64 && PCI -	help -	  Say Y here to support use of ATI's 64-bit Rage boards (or other -	  boards based on the Mach64 CT, VT, GT, and LT chipsets) as a -	  framebuffer device.  The ATI product support page for these boards -	  is at <http://support.ati.com/products/pc/mach64/mach64.html>. - -config FB_ATY_GENERIC_LCD -	bool "Mach64 generic LCD support" -	depends on FB_ATY_CT -	help -	  Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility, -	  Rage XC, or Rage XL chipset. - -config FB_ATY_GX -	bool "Mach64 GX support" if PCI -	depends on FB_ATY -	default y if ATARI -	help -	  Say Y here to support use of the ATI Mach64 Graphics Expression -	  board (or other boards based on the Mach64 GX chipset) as a -	  framebuffer device.  The ATI product support page for these boards -	  is at -	  <http://support.ati.com/products/pc/mach64/graphics_xpression.html>. - -config FB_ATY_BACKLIGHT -	bool "Support for backlight control" -	depends on FB_ATY -	default y -	help -	  Say Y here if you want to control the backlight of your display. - -config FB_S3 -	tristate "S3 Trio/Virge support" -	depends on FB && PCI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_TILEBLITTING -	select FB_SVGALIB -	select VGASTATE -	select FONT_8x16 if FRAMEBUFFER_CONSOLE -	---help--- -	  Driver for graphics boards with S3 Trio / S3 Virge chip. - -config FB_S3_DDC -	bool "DDC for S3 support" -	depends on FB_S3 -	select FB_DDC -	default y -	help -	  Say Y here if you want DDC support for your S3 graphics card. - -config FB_SAVAGE -	tristate "S3 Savage support" -	depends on FB && PCI -	select FB_MODE_HELPERS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select VGASTATE -	help -	  This driver supports notebooks and computers with S3 Savage PCI/AGP -	  chips. - -	  Say Y if you have such a graphics card. - -	  To compile this driver as a module, choose M here; the module -	  will be called savagefb. - -config FB_SAVAGE_I2C -       bool "Enable DDC2 Support" -       depends on FB_SAVAGE -       select FB_DDC -       help -	  This enables I2C support for S3 Savage Chipsets.  This is used -	  only for getting EDID information from the attached display -	  allowing for robust video mode handling and switching. - -	  Because fbdev-2.6 requires that drivers must be able to -	  independently validate video mode parameters, you should say Y -	  here. - -config FB_SAVAGE_ACCEL -       bool "Enable Console Acceleration" -       depends on FB_SAVAGE -       default n -       help -          This option will compile in console acceleration support. If -          the resulting framebuffer console has bothersome glitches, then -          choose N here. - -config FB_SIS -	tristate "SiS/XGI display support" -	depends on FB && PCI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_BOOT_VESA_SUPPORT if FB_SIS = y -	help -	  This is the frame buffer device driver for the SiS 300, 315, 330 -	  and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets. -	  Specs available at <http://www.sis.com> and <http://www.xgitech.com>. - -	  To compile this driver as a module, choose M here; the module -	  will be called sisfb. - -config FB_SIS_300 -	bool "SiS 300 series support" -	depends on FB_SIS -	help -	  Say Y here to support use of the SiS 300/305, 540, 630 and 730. - -config FB_SIS_315 -	bool "SiS 315/330/340 series and XGI support" -	depends on FB_SIS -	help -	  Say Y here to support use of the SiS 315, 330 and 340 series -	  (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well -	  as XGI V3XT, V5, V8 and Z7. - -config FB_VIA -       tristate "VIA UniChrome (Pro) and Chrome9 display support" -       depends on FB && PCI && X86 -       select FB_CFB_FILLRECT -       select FB_CFB_COPYAREA -       select FB_CFB_IMAGEBLIT -       select I2C_ALGOBIT -       select I2C -       select GPIOLIB -       help -	  This is the frame buffer device driver for Graphics chips of VIA -	  UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/ -	  CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896 - 	  /P4M900,VX800) -	  Say Y if you have a VIA UniChrome graphics board. - -	  To compile this driver as a module, choose M here: the -	  module will be called viafb. - -if FB_VIA - -config FB_VIA_DIRECT_PROCFS -	bool "direct hardware access via procfs (DEPRECATED)(DANGEROUS)" -	depends on FB_VIA -	default n -	help -	  Allow direct hardware access to some output registers via procfs. -	  This is dangerous but may provide the only chance to get the -	  correct output device configuration. -	  Its use is strongly discouraged. - -config FB_VIA_X_COMPATIBILITY -	bool "X server compatibility" -	depends on FB_VIA -	default n -	help -	  This option reduces the functionality (power saving, ...) of the -	  framebuffer to avoid negative impact on the OpenChrome X server. -	  If you use any X server other than fbdev you should enable this -	  otherwise it should be safe to disable it and allow using all -	  features. - -endif - -config FB_NEOMAGIC -	tristate "NeoMagic display support" -	depends on FB && PCI -	select FB_MODE_HELPERS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select VGASTATE -	help -	  This driver supports notebooks with NeoMagic PCI chips. -	  Say Y if you have such a graphics card.  - -	  To compile this driver as a module, choose M here: the -	  module will be called neofb. - -config FB_KYRO -	tristate "IMG Kyro support" -	depends on FB && PCI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  Say Y here if you have a STG4000 / Kyro / PowerVR 3 based -	  graphics board. - -	  To compile this driver as a module, choose M here: the -	  module will be called kyrofb. - -config FB_3DFX -	tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support" -	depends on FB && PCI -	select FB_CFB_IMAGEBLIT -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_MODE_HELPERS -	help -	  This driver supports graphics boards with the 3Dfx Banshee, -	  Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have -	  such a graphics board. - -	  To compile this driver as a module, choose M here: the -	  module will be called tdfxfb. - -config FB_3DFX_ACCEL -	bool "3Dfx Acceleration functions" -	depends on FB_3DFX -	---help--- -	This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer -	device driver with acceleration functions. - -config FB_3DFX_I2C -	bool "Enable DDC/I2C support" -	depends on FB_3DFX -	select FB_DDC -	default y -	help -	  Say Y here if you want DDC/I2C support for your 3dfx Voodoo3. - -config FB_VOODOO1 -	tristate "3Dfx Voodoo Graphics (sst1) support" -	depends on FB && PCI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or  -	  Voodoo2 (cvg) based graphics card. - -	  To compile this driver as a module, choose M here: the -	  module will be called sstfb. - -	  WARNING: Do not use any application that uses the 3D engine -	  (namely glide) while using this driver. -	  Please read the <file:Documentation/fb/sstfb.txt> for supported -	  options and other important info  support. - -config FB_VT8623 -	tristate "VIA VT8623 support" -	depends on FB && PCI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_TILEBLITTING -	select FB_SVGALIB -	select VGASTATE -	select FONT_8x16 if FRAMEBUFFER_CONSOLE -	---help--- -	  Driver for CastleRock integrated graphics core in the -	  VIA VT8623 [Apollo CLE266] chipset. - -config FB_TRIDENT -	tristate "Trident/CyberXXX/CyberBlade support" -	depends on FB && PCI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  This is the frame buffer device driver for Trident PCI/AGP chipsets. -	  Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D -	  and Blade XP. -	  There are also integrated versions of these chips called CyberXXXX, -	  CyberImage or CyberBlade. These chips are mostly found in laptops -	  but also on some motherboards including early VIA EPIA motherboards. -	  For more information, read <file:Documentation/fb/tridentfb.txt> - -	  Say Y if you have such a graphics board. - -	  To compile this driver as a module, choose M here: the -	  module will be called tridentfb. - -config FB_ARK -	tristate "ARK 2000PV support" -	depends on FB && PCI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_TILEBLITTING -	select FB_SVGALIB -	select VGASTATE -	select FONT_8x16 if FRAMEBUFFER_CONSOLE -	---help--- -	  Driver for PCI graphics boards with ARK 2000PV chip -	  and ICS 5342 RAMDAC. - -config FB_PM3 -	tristate "Permedia3 support" -	depends on FB && PCI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the 3DLabs Permedia3 -	  chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 & -	  similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000 -	  and maybe other boards. - -config FB_CARMINE -	tristate "Fujitsu carmine frame buffer support" -	depends on FB && PCI -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the Fujitsu Carmine chip. -	  The driver provides two independent frame buffer devices. - -choice -	depends on FB_CARMINE -	prompt "DRAM timing" -	default FB_CARMINE_DRAM_EVAL - -config FB_CARMINE_DRAM_EVAL -	bool "Eval board timings" -	help -	  Use timings which work on the eval card. - -config CARMINE_DRAM_CUSTOM -	bool "Custom board timings" -	help -	  Use custom board timings. -endchoice - -config FB_AU1100 -	bool "Au1100 LCD Driver" -	depends on (FB = y) && MIPS_ALCHEMY -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the framebuffer driver for the AMD Au1100 SOC.  It can drive -	  various panels and CRTs by passing in kernel cmd line option -	  au1100fb:panel=<name>. - -config FB_AU1200 -	bool "Au1200/Au1300 LCD Driver" -	depends on (FB = y) && MIPS_ALCHEMY -	select FB_SYS_FILLRECT -	select FB_SYS_COPYAREA -	select FB_SYS_IMAGEBLIT -	select FB_SYS_FOPS -	help -	  This is the framebuffer driver for the Au1200/Au1300 SOCs. -	  It can drive various panels and CRTs by passing in kernel cmd line -	  option au1200fb:panel=<name>. - -config FB_VT8500 -	bool "VIA VT8500 framebuffer support" -	depends on (FB = y) && ARM && ARCH_VT8500 -	select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS) -	select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS) -	select FB_SYS_IMAGEBLIT -	select FB_MODE_HELPERS -	select VIDEOMODE_HELPERS -	help -	  This is the framebuffer driver for VIA VT8500 integrated LCD -	  controller. - -config FB_WM8505 -	bool "Wondermedia WM8xxx-series frame buffer support" -	depends on (FB = y) && ARM && ARCH_VT8500 -	select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS) -	select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS) -	select FB_SYS_IMAGEBLIT -	select FB_MODE_HELPERS -	select VIDEOMODE_HELPERS -	help -	  This is the framebuffer driver for WonderMedia WM8xxx-series -	  integrated LCD controller. This driver covers the WM8505, WM8650 -	  and WM8850 SoCs. - -config FB_WMT_GE_ROPS -	bool "VT8500/WM8xxx accelerated raster ops support" -	depends on (FB = y) && (FB_VT8500 || FB_WM8505) -	default n -	help -	  This adds support for accelerated raster operations on the -	  VIA VT8500 and Wondermedia 85xx series SoCs. - -source "drivers/video/geode/Kconfig" - -config FB_HIT -	tristate "HD64461 Frame Buffer support" -	depends on FB && HD64461 -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This is the frame buffer device driver for the Hitachi HD64461 LCD -	  frame buffer card. - -config FB_PMAG_AA -	bool "PMAG-AA TURBOchannel framebuffer support" -	depends on (FB = y) && TC - 	select FB_CFB_FILLRECT - 	select FB_CFB_COPYAREA - 	select FB_CFB_IMAGEBLIT -	help -	  Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1) -	  used mainly in the MIPS-based DECstation series. - -config FB_PMAG_BA -	tristate "PMAG-BA TURBOchannel framebuffer support" -	depends on FB && TC - 	select FB_CFB_FILLRECT - 	select FB_CFB_COPYAREA - 	select FB_CFB_IMAGEBLIT -	help -	  Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8) -	  used mainly in the MIPS-based DECstation series. - -config FB_PMAGB_B -	tristate "PMAGB-B TURBOchannel framebuffer support" -	depends on FB && TC - 	select FB_CFB_FILLRECT - 	select FB_CFB_COPYAREA - 	select FB_CFB_IMAGEBLIT -	help -	  Support for the PMAGB-B TURBOchannel framebuffer card used mainly -	  in the MIPS-based DECstation series. The card is currently only -	  supported in 1280x1024x8 mode. - -config FB_MAXINE -	bool "Maxine (Personal DECstation) onboard framebuffer support" -	depends on (FB = y) && MACH_DECSTATION - 	select FB_CFB_FILLRECT - 	select FB_CFB_COPYAREA - 	select FB_CFB_IMAGEBLIT -	help -	  Support for the onboard framebuffer (1024x768x8) in the Personal -	  DECstation series (Personal DECstation 5000/20, /25, /33, /50, -	  Codename "Maxine"). - -config FB_G364 -	bool "G364 frame buffer support" -	depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700) - 	select FB_CFB_FILLRECT - 	select FB_CFB_COPYAREA - 	select FB_CFB_IMAGEBLIT -	help -	  The G364 driver is the framebuffer used in MIPS Magnum 4000 and -	  Olivetti M700-10 systems. - -config FB_68328 -	bool "Motorola 68328 native frame buffer support" -	depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328) - 	select FB_CFB_FILLRECT - 	select FB_CFB_COPYAREA - 	select FB_CFB_IMAGEBLIT -	help -	  Say Y here if you want to support the built-in frame buffer of -	  the Motorola 68328 CPU family. - -config FB_PXA168 -	tristate "PXA168/910 LCD framebuffer support" -	depends on FB && (CPU_PXA168 || CPU_PXA910) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Frame buffer driver for the built-in LCD controller in the Marvell -	  MMP processor. - -config FB_PXA -	tristate "PXA LCD framebuffer support" -	depends on FB && ARCH_PXA -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Frame buffer driver for the built-in LCD controller in the Intel -	  PXA2x0 processor. - -	  This driver is also available as a module ( = code which can be -	  inserted and removed from the running kernel whenever you want). The -	  module will be called pxafb. If you want to compile it as a module, -	  say M here and read <file:Documentation/kbuild/modules.txt>. - -	  If unsure, say N. - -config FB_PXA_OVERLAY -	bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer" -	default n -	depends on FB_PXA && (PXA27x || PXA3xx) - -config FB_PXA_SMARTPANEL -	bool "PXA Smartpanel LCD support" -	default n -	depends on FB_PXA - -config FB_PXA_PARAMETERS -	bool "PXA LCD command line parameters" -	default n -	depends on FB_PXA -	---help--- -	  Enable the use of kernel command line or module parameters -	  to configure the physical properties of the LCD panel when -	  using the PXA LCD driver. - -	  This option allows you to override the panel parameters -	  supplied by the platform in order to support multiple -	  different models of flatpanel. If you will only be using a -	  single model of flatpanel then you can safely leave this -	  option disabled. - -	  <file:Documentation/fb/pxafb.txt> describes the available parameters. - -config PXA3XX_GCU -	tristate "PXA3xx 2D graphics accelerator driver" -	depends on FB_PXA -	help -	  Kernelspace driver for the 2D graphics controller unit (GCU) -	  found on PXA3xx processors. There is a counterpart driver in the -	  DirectFB suite, see http://www.directfb.org/ - -	  If you compile this as a module, it will be called pxa3xx_gcu. - -config FB_MBX -	tristate "2700G LCD framebuffer support" -	depends on FB && ARCH_PXA -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Framebuffer driver for the Intel 2700G (Marathon) Graphics -	  Accelerator - -config FB_MBX_DEBUG -       bool "Enable debugging info via debugfs" -       depends on FB_MBX && DEBUG_FS -       default n -       ---help--- -         Enable this if you want debugging information using the debug -         filesystem (debugfs) - -         If unsure, say N. - -config FB_FSL_DIU -	tristate "Freescale DIU framebuffer support" -	depends on FB && FSL_SOC -	select FB_MODE_HELPERS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select PPC_LIB_RHEAP -	---help--- -	  Framebuffer driver for the Freescale SoC DIU - -config FB_W100 -	tristate "W100 frame buffer support" -	depends on FB && ARCH_PXA - 	select FB_CFB_FILLRECT - 	select FB_CFB_COPYAREA - 	select FB_CFB_IMAGEBLIT -	---help--- -	  Frame buffer driver for the w100 as found on the Sharp SL-Cxx series. -	  It can also drive the w3220 chip found on iPAQ hx4700. - -	  This driver is also available as a module ( = code which can be -	  inserted and removed from the running kernel whenever you want). The -	  module will be called w100fb. If you want to compile it as a module, -	  say M here and read <file:Documentation/kbuild/modules.txt>. - -	  If unsure, say N. - -config FB_SH_MOBILE_LCDC -	tristate "SuperH Mobile LCDC framebuffer support" -	depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK -	select FB_SYS_FILLRECT -	select FB_SYS_COPYAREA -	select FB_SYS_IMAGEBLIT -	select FB_SYS_FOPS -	select FB_DEFERRED_IO -	select FB_BACKLIGHT -	select SH_MIPI_DSI if SH_LCD_MIPI_DSI -	---help--- -	  Frame buffer driver for the on-chip SH-Mobile LCD controller. - -config FB_SH_MOBILE_HDMI -	tristate "SuperH Mobile HDMI controller support" -	depends on FB_SH_MOBILE_LCDC -	select FB_MODE_HELPERS -	select SOUND -	select SND -	select SND_SOC -	---help--- -	  Driver for the on-chip SH-Mobile HDMI controller. - -config FB_TMIO -	tristate "Toshiba Mobile IO FrameBuffer support" -	depends on FB && MFD_CORE -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Frame buffer driver for the Toshiba Mobile IO integrated as found -	  on the Sharp SL-6000 series - -	  This driver is also available as a module ( = code which can be -	  inserted and removed from the running kernel whenever you want). The -	  module will be called tmiofb. If you want to compile it as a module, -	  say M here and read <file:Documentation/kbuild/modules.txt>. - -	  If unsure, say N. - -config FB_TMIO_ACCELL -	bool "tmiofb acceleration" -	depends on FB_TMIO -	default y - -config FB_S3C -	tristate "Samsung S3C framebuffer support" -	depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || ARCH_S5P64X0 || \ -		ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Frame buffer driver for the built-in FB controller in the Samsung -	  SoC line from the S3C2443 onwards, including the S3C2416, S3C2450, -	  and the S3C64XX series such as the S3C6400 and S3C6410. - -	  These chips all have the same basic framebuffer design with the -	  actual capabilities depending on the chip. For instance the S3C6400 -	  and S3C6410 support 4 hardware windows whereas the S3C24XX series -	  currently only have two. - -	  Currently the support is only for the S3C6400 and S3C6410 SoCs. - -config FB_S3C_DEBUG_REGWRITE -       bool "Debug register writes" -       depends on FB_S3C -       ---help--- -         Show all register writes via pr_debug() - -config FB_S3C2410 -	tristate "S3C2410 LCD framebuffer support" -	depends on FB && ARCH_S3C24XX -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Frame buffer driver for the built-in LCD controller in the Samsung -	  S3C2410 processor. - -	  This driver is also available as a module ( = code which can be -	  inserted and removed from the running kernel whenever you want). The -	  module will be called s3c2410fb. If you want to compile it as a module, -	  say M here and read <file:Documentation/kbuild/modules.txt>. - -	  If unsure, say N. -config FB_S3C2410_DEBUG -	bool "S3C2410 lcd debug messages" -	depends on FB_S3C2410 -	help -	  Turn on debugging messages. Note that you can set/unset at run time -	  through sysfs - -config FB_NUC900 -        bool "NUC900 LCD framebuffer support" -        depends on FB && ARCH_W90X900 -        select FB_CFB_FILLRECT -        select FB_CFB_COPYAREA -        select FB_CFB_IMAGEBLIT -        ---help--- -          Frame buffer driver for the built-in LCD controller in the Nuvoton -          NUC900 processor - -config GPM1040A0_320X240 -        bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD" -        depends on FB_NUC900 - -config FB_SM501 -	tristate "Silicon Motion SM501 framebuffer support" -	depends on FB && MFD_SM501 -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Frame buffer driver for the CRT and LCD controllers in the Silicon -	  Motion SM501. - -	  This driver is also available as a module ( = code which can be -	  inserted and removed from the running kernel whenever you want). The -	  module will be called sm501fb. If you want to compile it as a module, -	  say M here and read <file:Documentation/kbuild/modules.txt>. - -	  If unsure, say N. - -config FB_SMSCUFX -	tristate "SMSC UFX6000/7000 USB Framebuffer support" -	depends on FB && USB -	select FB_MODE_HELPERS -	select FB_SYS_FILLRECT -	select FB_SYS_COPYAREA -	select FB_SYS_IMAGEBLIT -	select FB_SYS_FOPS -	select FB_DEFERRED_IO -	---help--- -	  This is a kernel framebuffer driver for SMSC UFX USB devices. -	  Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and -	  mplayer -vo fbdev. Supports both UFX6000 (USB 2.0) and UFX7000 -	  (USB 3.0) devices. -	  To compile as a module, choose M here: the module name is smscufx. - -config FB_UDL -	tristate "Displaylink USB Framebuffer support" -	depends on FB && USB -	select FB_MODE_HELPERS -	select FB_SYS_FILLRECT -	select FB_SYS_COPYAREA -	select FB_SYS_IMAGEBLIT -	select FB_SYS_FOPS -	select FB_DEFERRED_IO -	---help--- -	  This is a kernel framebuffer driver for DisplayLink USB devices. -	  Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and -	  mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices. -	  To compile as a module, choose M here: the module name is udlfb. - -config FB_IBM_GXT4500 -	tristate "Framebuffer support for IBM GXT4000P/4500P/6000P/6500P adaptors" -	depends on FB && PPC -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Say Y here to enable support for the IBM GXT4000P/6000P and -	  GXT4500P/6500P display adaptor based on Raster Engine RC1000, -	  found on some IBM System P (pSeries) machines. This driver -	  doesn't use Geometry Engine GT1000. - -config FB_PS3 -	tristate "PS3 GPU framebuffer driver" -	depends on FB && PS3_PS3AV -	select FB_SYS_FILLRECT -	select FB_SYS_COPYAREA -	select FB_SYS_IMAGEBLIT -	select FB_SYS_FOPS -	select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE -	---help--- -	  Include support for the virtual frame buffer in the PS3 platform. - -config FB_PS3_DEFAULT_SIZE_M -	int "PS3 default frame buffer size (in MiB)" -	depends on FB_PS3 -	default 9 -	---help--- -	  This is the default size (in MiB) of the virtual frame buffer in -	  the PS3. -	  The default value can be overridden on the kernel command line -	  using the "ps3fb" option (e.g. "ps3fb=9M"); - -config FB_XILINX -	tristate "Xilinx frame buffer support" -	depends on FB && (XILINX_VIRTEX || MICROBLAZE || ARCH_ZYNQ) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Include support for the Xilinx ML300/ML403 reference design -	  framebuffer. ML300 carries a 640*480 LCD display on the board, -	  ML403 uses a standard DB15 VGA connector. - -config FB_GOLDFISH -	tristate "Goldfish Framebuffer" -	depends on FB && HAS_DMA -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Framebuffer driver for Goldfish Virtual Platform - -config FB_COBALT -	tristate "Cobalt server LCD frame buffer support" -	depends on FB && (MIPS_COBALT || MIPS_SEAD3) - -config FB_SH7760 -	bool "SH7760/SH7763/SH7720/SH7721 LCDC support" -	depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ -		|| CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Support for the SH7760/SH7763/SH7720/SH7721 integrated -	  (D)STN/TFT LCD Controller. -	  Supports display resolutions up to 1024x1024 pixel, grayscale and -	  color operation, with depths ranging from 1 bpp to 8 bpp monochrome -	  and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for -	  panels <= 320 pixel horizontal resolution. - -config FB_DA8XX -	tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support" -	depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_CFB_REV_PIXELS_IN_BYTE -	select FB_MODE_HELPERS -	select VIDEOMODE_HELPERS -	---help--- -	  This is the frame buffer device driver for the TI LCD controller -	  found on DA8xx/OMAP-L1xx/AM335x SoCs. -	  If unsure, say N. - -config FB_VIRTUAL -	tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" -	depends on FB -	select FB_SYS_FILLRECT -	select FB_SYS_COPYAREA -	select FB_SYS_IMAGEBLIT -	select FB_SYS_FOPS -	---help--- -	  This is a `virtual' frame buffer device. It operates on a chunk of -	  unswappable kernel memory instead of on the memory of a graphics -	  board. This means you cannot see any output sent to this frame -	  buffer device, while it does consume precious memory. The main use -	  of this frame buffer device is testing and debugging the frame -	  buffer subsystem. Do NOT enable it for normal systems! To protect -	  the innocent, it has to be enabled explicitly at boot time using the -	  kernel option `video=vfb:'. - -	  To compile this driver as a module, choose M here: the -	  module will be called vfb. In order to load it, you must use -	  the vfb_enable=1 option. - -	  If unsure, say N. - -config XEN_FBDEV_FRONTEND -	tristate "Xen virtual frame buffer support" -	depends on FB && XEN -	select FB_SYS_FILLRECT -	select FB_SYS_COPYAREA -	select FB_SYS_IMAGEBLIT -	select FB_SYS_FOPS -	select FB_DEFERRED_IO -	select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC -	select XEN_XENBUS_FRONTEND -	default y -	help -	  This driver implements the front-end of the Xen virtual -	  frame buffer driver.  It communicates with a back-end -	  in another domain. - -config FB_METRONOME -	tristate "E-Ink Metronome/8track controller support" -	depends on FB -	select FB_SYS_FILLRECT -	select FB_SYS_COPYAREA -	select FB_SYS_IMAGEBLIT -	select FB_SYS_FOPS -	select FB_DEFERRED_IO -	help -	  This driver implements support for the E-Ink Metronome -	  controller. The pre-release name for this device was 8track -	  and could also have been called by some vendors as PVI-nnnn. - -config FB_MB862XX -	tristate "Fujitsu MB862xx GDC support" -	depends on FB -	depends on PCI || (OF && PPC) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers. - -choice -	prompt "GDC variant" -	depends on FB_MB862XX - -config FB_MB862XX_PCI_GDC -	bool "Carmine/Coral-P(A) GDC" -	depends on PCI -	---help--- -	  This enables framebuffer support for Fujitsu Carmine/Coral-P(A) -	  PCI graphics controller devices. - -config FB_MB862XX_LIME -	bool "Lime GDC" -	depends on OF && PPC -	select FB_FOREIGN_ENDIAN -	select FB_LITTLE_ENDIAN -	---help--- -	  Framebuffer support for Fujitsu Lime GDC on host CPU bus. - -endchoice - -config FB_MB862XX_I2C -	bool "Support I2C bus on MB862XX GDC" -	depends on FB_MB862XX && I2C -	default y -	help -	  Selecting this option adds Coral-P(A)/Lime GDC I2C bus adapter -	  driver to support accessing I2C devices on controller's I2C bus. -	  These are usually some video decoder chips. - -config FB_EP93XX -	tristate "EP93XX frame buffer support" -	depends on FB && ARCH_EP93XX -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	---help--- -	  Framebuffer driver for the Cirrus Logic EP93XX series of processors. -	  This driver is also available as a module. The module will be called -	  ep93xx-fb. - -config FB_PRE_INIT_FB -	bool "Don't reinitialize, use bootloader's GDC/Display configuration" -	depends on FB && FB_MB862XX_LIME -	---help--- -	  Select this option if display contents should be inherited as set by -	  the bootloader. - -config FB_MSM -	tristate "MSM Framebuffer support" -	depends on FB && ARCH_MSM -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT - -config FB_MX3 -	tristate "MX3 Framebuffer support" -	depends on FB && MX3_IPU -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	default y -	help -	  This is a framebuffer device for the i.MX31 LCD Controller. So -	  far only synchronous displays are supported. If you plan to use -	  an LCD display with your i.MX31 system, say Y here. - -config FB_BROADSHEET -	tristate "E-Ink Broadsheet/Epson S1D13521 controller support" -	depends on FB -	select FB_SYS_FILLRECT -	select FB_SYS_COPYAREA -	select FB_SYS_IMAGEBLIT -	select FB_SYS_FOPS -	select FB_DEFERRED_IO -	help -	  This driver implements support for the E-Ink Broadsheet -	  controller. The release name for this device was Epson S1D13521 -	  and could also have been called by other names when coupled with -	  a bridge adapter. - -config FB_AUO_K190X -	tristate "AUO-K190X EPD controller support" -	depends on FB -	select FB_SYS_FILLRECT -	select FB_SYS_COPYAREA -	select FB_SYS_IMAGEBLIT -	select FB_SYS_FOPS -	select FB_DEFERRED_IO -	help -	  Provides support for epaper controllers from the K190X series -	  of AUO. These controllers can be used to drive epaper displays -	  from Sipix. - -	  This option enables the common support, shared by the individual -	  controller drivers. You will also have to enable the driver -	  for the controller type used in your device. - -config FB_AUO_K1900 -	tristate "AUO-K1900 EPD controller support" -	depends on FB && FB_AUO_K190X -	help -	  This driver implements support for the AUO K1900 epd-controller. -	  This controller can drive Sipix epaper displays but can only do -	  serial updates, reducing the number of possible frames per second. - -config FB_AUO_K1901 -	tristate "AUO-K1901 EPD controller support" -	depends on FB && FB_AUO_K190X -	help -	  This driver implements support for the AUO K1901 epd-controller. -	  This controller can drive Sipix epaper displays and supports -	  concurrent updates, making higher frames per second possible. - -config FB_JZ4740 -	tristate "JZ4740 LCD framebuffer support" -	depends on FB && MACH_JZ4740 -	select FB_SYS_FILLRECT -	select FB_SYS_COPYAREA -	select FB_SYS_IMAGEBLIT -	help -	  Framebuffer support for the JZ4740 SoC. - -config FB_MXS -	tristate "MXS LCD framebuffer support" -	depends on FB && ARCH_MXS -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	select FB_MODE_HELPERS -	select VIDEOMODE_HELPERS -	help -	  Framebuffer support for the MXS SoC. - -config FB_PUV3_UNIGFX -	tristate "PKUnity v3 Unigfx framebuffer support" -	depends on FB && UNICORE32 && ARCH_PUV3 -	select FB_SYS_FILLRECT -	select FB_SYS_COPYAREA -	select FB_SYS_IMAGEBLIT -	select FB_SYS_FOPS -	help -	  Choose this option if you want to use the Unigfx device as a -	  framebuffer device. Without the support of PCI & AGP. - -config FB_HYPERV -	tristate "Microsoft Hyper-V Synthetic Video support" -	depends on FB && HYPERV -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  This framebuffer driver supports Microsoft Hyper-V Synthetic Video. - -config FB_SIMPLE -	bool "Simple framebuffer support" -	depends on (FB = y) -	select FB_CFB_FILLRECT -	select FB_CFB_COPYAREA -	select FB_CFB_IMAGEBLIT -	help -	  Say Y if you want support for a simple frame-buffer. - -	  This driver assumes that the display hardware has been initialized -	  before the kernel boots, and the kernel will simply render to the -	  pre-allocated frame buffer surface. - -	  Configuration re: surface address, size, and format must be provided -	  through device tree, or plain old platform data. - -source "drivers/video/omap/Kconfig" -source "drivers/video/omap2/Kconfig" -source "drivers/video/exynos/Kconfig" -source "drivers/video/mmp/Kconfig" -source "drivers/video/backlight/Kconfig" -  if VT  	source "drivers/video/console/Kconfig"  endif  if FB || SGI_NEWPORT_CONSOLE  	source "drivers/video/logo/Kconfig" -endif -config FB_SH_MOBILE_MERAM -	tristate "SuperH Mobile MERAM read ahead support" -	depends on (SUPERH || ARCH_SHMOBILE) -	select GENERIC_ALLOCATOR -	---help--- -	  Enable MERAM support for the SuperH controller. - -	  This will allow for caching of the framebuffer to provide more -	  reliable access under heavy main memory bus traffic situations. -	  Up to 4 memory channels can be configured, allowing 4 RGB or -	  2 YCbCr framebuffers to be configured. +endif -config FB_SSD1307 -	tristate "Solomon SSD1307 framebuffer support" -	depends on FB && I2C -	depends on OF -	depends on GPIOLIB -	select FB_SYS_FOPS -	select FB_SYS_FILLRECT -	select FB_SYS_COPYAREA -	select FB_SYS_IMAGEBLIT -	select FB_DEFERRED_IO -	select PWM -	help -	  This driver implements support for the Solomon SSD1307 -	  OLED controller over I2C.  endmenu diff --git a/drivers/video/Makefile b/drivers/video/Makefile index e8bae8dd480..9ad3c17d645 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -1,178 +1,12 @@ -# Makefile for the Linux video drivers. -# 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net> -# Rewritten to use lists instead of if-statements. - -# Each configuration option enables a list of files. -  obj-$(CONFIG_VGASTATE)            += vgastate.o  obj-$(CONFIG_HDMI)                += hdmi.o -obj-y                             += fb_notify.o -obj-$(CONFIG_FB)                  += fb.o -fb-y                              := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ -                                     modedb.o fbcvt.o -fb-objs                           := $(fb-y)  obj-$(CONFIG_VT)		  += console/  obj-$(CONFIG_LOGO)		  += logo/  obj-y				  += backlight/ -obj-$(CONFIG_EXYNOS_VIDEO)     += exynos/ - -obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o -obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o -obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o -obj-$(CONFIG_FB_SYS_FILLRECT)  += sysfillrect.o -obj-$(CONFIG_FB_SYS_COPYAREA)  += syscopyarea.o -obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o -obj-$(CONFIG_FB_SYS_FOPS)      += fb_sys_fops.o -obj-$(CONFIG_FB_SVGALIB)       += svgalib.o -obj-$(CONFIG_FB_MACMODES)      += macmodes.o -obj-$(CONFIG_FB_DDC)           += fb_ddc.o -obj-$(CONFIG_FB_DEFERRED_IO)   += fb_defio.o -obj-$(CONFIG_FB_WMT_GE_ROPS)   += wmt_ge_rops.o - -# Hardware specific drivers go first -obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o -obj-$(CONFIG_FB_ARC)              += arcfb.o -obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o -obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o -obj-$(CONFIG_FB_GRVGA)            += grvga.o -obj-$(CONFIG_FB_PM2)              += pm2fb.o -obj-$(CONFIG_FB_PM3)		  += pm3fb.o - -obj-$(CONFIG_FB_I740)		  += i740fb.o -obj-$(CONFIG_FB_MATROX)		  += matrox/ -obj-$(CONFIG_FB_RIVA)		  += riva/ -obj-$(CONFIG_FB_NVIDIA)		  += nvidia/ -obj-$(CONFIG_FB_ATY)		  += aty/ macmodes.o -obj-$(CONFIG_FB_ATY128)		  += aty/ macmodes.o -obj-$(CONFIG_FB_RADEON)		  += aty/ -obj-$(CONFIG_FB_SIS)		  += sis/ -obj-$(CONFIG_FB_VIA)		  += via/ -obj-$(CONFIG_FB_KYRO)             += kyro/ -obj-$(CONFIG_FB_SAVAGE)		  += savage/ -obj-$(CONFIG_FB_GEODE)		  += geode/ -obj-$(CONFIG_FB_MBX)		  += mbx/ -obj-$(CONFIG_FB_NEOMAGIC)         += neofb.o -obj-$(CONFIG_FB_3DFX)             += tdfxfb.o -obj-$(CONFIG_FB_CONTROL)          += controlfb.o -obj-$(CONFIG_FB_PLATINUM)         += platinumfb.o -obj-$(CONFIG_FB_VALKYRIE)         += valkyriefb.o -obj-$(CONFIG_FB_CT65550)          += chipsfb.o -obj-$(CONFIG_FB_IMSTT)            += imsttfb.o -obj-$(CONFIG_FB_FM2)              += fm2fb.o -obj-$(CONFIG_FB_VT8623)           += vt8623fb.o -obj-$(CONFIG_FB_TRIDENT)          += tridentfb.o -obj-$(CONFIG_FB_LE80578)          += vermilion/ -obj-$(CONFIG_FB_S3)               += s3fb.o -obj-$(CONFIG_FB_ARK)              += arkfb.o -obj-$(CONFIG_FB_STI)              += stifb.o -obj-$(CONFIG_FB_FFB)              += ffb.o sbuslib.o -obj-$(CONFIG_FB_CG6)              += cg6.o sbuslib.o -obj-$(CONFIG_FB_CG3)              += cg3.o sbuslib.o -obj-$(CONFIG_FB_BW2)              += bw2.o sbuslib.o -obj-$(CONFIG_FB_CG14)             += cg14.o sbuslib.o -obj-$(CONFIG_FB_P9100)            += p9100.o sbuslib.o -obj-$(CONFIG_FB_TCX)              += tcx.o sbuslib.o -obj-$(CONFIG_FB_LEO)              += leo.o sbuslib.o -obj-$(CONFIG_FB_SGIVW)            += sgivwfb.o -obj-$(CONFIG_FB_ACORN)            += acornfb.o -obj-$(CONFIG_FB_ATARI)            += atafb.o c2p_iplan2.o atafb_mfb.o \ -                                     atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o -obj-$(CONFIG_FB_MAC)              += macfb.o -obj-$(CONFIG_FB_HECUBA)           += hecubafb.o -obj-$(CONFIG_FB_N411)             += n411.o -obj-$(CONFIG_FB_HGA)              += hgafb.o -obj-$(CONFIG_FB_XVR500)           += sunxvr500.o -obj-$(CONFIG_FB_XVR2500)          += sunxvr2500.o -obj-$(CONFIG_FB_XVR1000)          += sunxvr1000.o -obj-$(CONFIG_FB_IGA)              += igafb.o -obj-$(CONFIG_FB_APOLLO)           += dnfb.o -obj-$(CONFIG_FB_Q40)              += q40fb.o -obj-$(CONFIG_FB_TGA)              += tgafb.o -obj-$(CONFIG_FB_HP300)            += hpfb.o -obj-$(CONFIG_FB_G364)             += g364fb.o -obj-$(CONFIG_FB_EP93XX)		  += ep93xx-fb.o -obj-$(CONFIG_FB_SA1100)           += sa1100fb.o -obj-$(CONFIG_FB_HIT)              += hitfb.o -obj-$(CONFIG_FB_ATMEL)		  += atmel_lcdfb.o -obj-$(CONFIG_FB_PVR2)             += pvr2fb.o -obj-$(CONFIG_FB_VOODOO1)          += sstfb.o -obj-$(CONFIG_FB_ARMCLCD)	  += amba-clcd.o -obj-$(CONFIG_FB_GOLDFISH)         += goldfishfb.o -obj-$(CONFIG_FB_68328)            += 68328fb.o -obj-$(CONFIG_FB_GBE)              += gbefb.o -obj-$(CONFIG_FB_CIRRUS)		  += cirrusfb.o -obj-$(CONFIG_FB_ASILIANT)	  += asiliantfb.o -obj-$(CONFIG_FB_PXA)		  += pxafb.o -obj-$(CONFIG_FB_PXA168)		  += pxa168fb.o -obj-$(CONFIG_PXA3XX_GCU)	  += pxa3xx-gcu.o -obj-$(CONFIG_MMP_DISP)           += mmp/ -obj-$(CONFIG_FB_W100)		  += w100fb.o -obj-$(CONFIG_FB_TMIO)		  += tmiofb.o -obj-$(CONFIG_FB_AU1100)		  += au1100fb.o -obj-$(CONFIG_FB_AU1200)		  += au1200fb.o -obj-$(CONFIG_FB_VT8500)		  += vt8500lcdfb.o -obj-$(CONFIG_FB_WM8505)		  += wm8505fb.o -obj-$(CONFIG_FB_PMAG_AA)	  += pmag-aa-fb.o -obj-$(CONFIG_FB_PMAG_BA)	  += pmag-ba-fb.o -obj-$(CONFIG_FB_PMAGB_B)	  += pmagb-b-fb.o -obj-$(CONFIG_FB_MAXINE)		  += maxinefb.o -obj-$(CONFIG_FB_METRONOME)        += metronomefb.o -obj-$(CONFIG_FB_BROADSHEET)       += broadsheetfb.o -obj-$(CONFIG_FB_AUO_K190X)	  += auo_k190x.o -obj-$(CONFIG_FB_AUO_K1900)	  += auo_k1900fb.o -obj-$(CONFIG_FB_AUO_K1901)	  += auo_k1901fb.o -obj-$(CONFIG_FB_S1D13XXX)	  += s1d13xxxfb.o -obj-$(CONFIG_FB_SH7760)		  += sh7760fb.o -obj-$(CONFIG_FB_IMX)              += imxfb.o -obj-$(CONFIG_FB_S3C)		  += s3c-fb.o -obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o -obj-$(CONFIG_FB_FSL_DIU)	  += fsl-diu-fb.o -obj-$(CONFIG_FB_COBALT)           += cobalt_lcdfb.o -obj-$(CONFIG_FB_IBM_GXT4500)	  += gxt4500.o -obj-$(CONFIG_FB_PS3)		  += ps3fb.o -obj-$(CONFIG_FB_SM501)            += sm501fb.o -obj-$(CONFIG_FB_UDL)		  += udlfb.o -obj-$(CONFIG_FB_SMSCUFX)	  += smscufx.o -obj-$(CONFIG_FB_XILINX)           += xilinxfb.o -obj-$(CONFIG_SH_MIPI_DSI)	  += sh_mipi_dsi.o -obj-$(CONFIG_FB_SH_MOBILE_HDMI)	  += sh_mobile_hdmi.o -obj-$(CONFIG_FB_SH_MOBILE_MERAM)  += sh_mobile_meram.o -obj-$(CONFIG_FB_SH_MOBILE_LCDC)	  += sh_mobile_lcdcfb.o -obj-$(CONFIG_FB_OMAP)             += omap/ -obj-y                             += omap2/ -obj-$(CONFIG_XEN_FBDEV_FRONTEND)  += xen-fbfront.o -obj-$(CONFIG_FB_CARMINE)          += carminefb.o -obj-$(CONFIG_FB_MB862XX)	  += mb862xx/ -obj-$(CONFIG_FB_MSM)              += msm/ -obj-$(CONFIG_FB_NUC900)           += nuc900fb.o -obj-$(CONFIG_FB_JZ4740)		  += jz4740_fb.o -obj-$(CONFIG_FB_PUV3_UNIGFX)      += fb-puv3.o -obj-$(CONFIG_FB_HYPERV)		  += hyperv_fb.o - -# Platform or fallback drivers go here -obj-$(CONFIG_FB_UVESA)            += uvesafb.o -obj-$(CONFIG_FB_VESA)             += vesafb.o -obj-$(CONFIG_FB_EFI)              += efifb.o -obj-$(CONFIG_FB_VGA16)            += vga16fb.o -obj-$(CONFIG_FB_OF)               += offb.o -obj-$(CONFIG_FB_BF537_LQ035)      += bf537-lq035.o -obj-$(CONFIG_FB_BF54X_LQ043)	  += bf54x-lq043fb.o -obj-$(CONFIG_FB_BFIN_LQ035Q1)     += bfin-lq035q1-fb.o -obj-$(CONFIG_FB_BFIN_T350MCQB)	  += bfin-t350mcqb-fb.o -obj-$(CONFIG_FB_BFIN_7393)        += bfin_adv7393fb.o -obj-$(CONFIG_FB_MX3)		  += mx3fb.o -obj-$(CONFIG_FB_DA8XX)		  += da8xx-fb.o -obj-$(CONFIG_FB_MXS)		  += mxsfb.o -obj-$(CONFIG_FB_SSD1307)	  += ssd1307fb.o -obj-$(CONFIG_FB_SIMPLE)           += simplefb.o - -# the test framebuffer is last -obj-$(CONFIG_FB_VIRTUAL)          += vfb.o +obj-y				  += fbdev/ -#video output switch sysfs driver -obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o  obj-$(CONFIG_VIDEOMODE_HELPERS) += display_timing.o videomode.o  ifeq ($(CONFIG_OF),y)  obj-$(CONFIG_VIDEOMODE_HELPERS) += of_display_timing.o of_videomode.o diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c index 2cd63507ed7..7db5234462d 100644 --- a/drivers/video/backlight/88pm860x_bl.c +++ b/drivers/video/backlight/88pm860x_bl.c @@ -196,7 +196,7 @@ static int pm860x_backlight_dt_init(struct platform_device *pdev,  static int pm860x_backlight_probe(struct platform_device *pdev)  {  	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); -	struct pm860x_backlight_pdata *pdata = pdev->dev.platform_data; +	struct pm860x_backlight_pdata *pdata = dev_get_platdata(&pdev->dev);  	struct pm860x_backlight_data *data;  	struct backlight_device *bl;  	struct resource *res; @@ -243,7 +243,7 @@ static int pm860x_backlight_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = MAX_BRIGHTNESS; -	bl = backlight_device_register(name, &pdev->dev, data, +	bl = devm_backlight_device_register(&pdev->dev, name, &pdev->dev, data,  					&pm860x_backlight_ops, &props);  	if (IS_ERR(bl)) {  		dev_err(&pdev->dev, "failed to register backlight\n"); @@ -256,21 +256,10 @@ static int pm860x_backlight_probe(struct platform_device *pdev)  	/* read current backlight */  	ret = pm860x_backlight_get_brightness(bl);  	if (ret < 0) -		goto out_brt; +		return ret;  	backlight_update_status(bl);  	return 0; -out_brt: -	backlight_device_unregister(bl); -	return ret; -} - -static int pm860x_backlight_remove(struct platform_device *pdev) -{ -	struct backlight_device *bl = platform_get_drvdata(pdev); - -	backlight_device_unregister(bl); -	return 0;  }  static struct platform_driver pm860x_backlight_driver = { @@ -279,7 +268,6 @@ static struct platform_driver pm860x_backlight_driver = {  		.owner	= THIS_MODULE,  	},  	.probe		= pm860x_backlight_probe, -	.remove		= pm860x_backlight_remove,  };  module_platform_driver(pm860x_backlight_driver); diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index d4a7a351d67..5d449059a55 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -29,7 +29,7 @@ if LCD_CLASS_DEVICE  config LCD_CORGI  	tristate "LCD Panel support for SHARP corgi/spitz model" -	depends on SPI_MASTER && PXA_SHARPSL +	depends on SPI_MASTER && PXA_SHARPSL && BACKLIGHT_CLASS_DEVICE  	help  	  Say y here to support the LCD panels usually found on SHARP  	  corgi (C7x0) and spitz (Cxx00) models. @@ -368,12 +368,12 @@ config BACKLIGHT_AAT2870  	  If you have a AnalogicTech AAT2870 say Y to enable the  	  backlight driver. -config BACKLIGHT_LM3630 -	tristate "Backlight Driver for LM3630" -	depends on BACKLIGHT_CLASS_DEVICE && I2C +config BACKLIGHT_LM3630A +	tristate "Backlight Driver for LM3630A" +	depends on BACKLIGHT_CLASS_DEVICE && I2C && PWM  	select REGMAP_I2C  	help -	  This supports TI LM3630 Backlight Driver +	  This supports TI LM3630A Backlight Driver  config BACKLIGHT_LM3639  	tristate "Backlight Driver for LM3639" @@ -386,14 +386,14 @@ config BACKLIGHT_LM3639  config BACKLIGHT_LP855X  	tristate "Backlight driver for TI LP855X" -	depends on BACKLIGHT_CLASS_DEVICE && I2C +	depends on BACKLIGHT_CLASS_DEVICE && I2C && PWM  	help -	  This supports TI LP8550, LP8551, LP8552, LP8553, LP8556 and LP8557 -	  backlight driver. +	  This supports TI LP8550, LP8551, LP8552, LP8553, LP8555, LP8556 and +	  LP8557 backlight driver.  config BACKLIGHT_LP8788  	tristate "Backlight driver for TI LP8788 MFD" -	depends on BACKLIGHT_CLASS_DEVICE && MFD_LP8788 +	depends on BACKLIGHT_CLASS_DEVICE && MFD_LP8788 && PWM  	help  	  This supports TI LP8788 backlight driver. diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile index 38e1babb194..bb820024f34 100644 --- a/drivers/video/backlight/Makefile +++ b/drivers/video/backlight/Makefile @@ -37,7 +37,7 @@ obj-$(CONFIG_BACKLIGHT_GPIO)		+= gpio_backlight.o  obj-$(CONFIG_BACKLIGHT_HP680)		+= hp680_bl.o  obj-$(CONFIG_BACKLIGHT_HP700)		+= jornada720_bl.o  obj-$(CONFIG_BACKLIGHT_LM3533)		+= lm3533_bl.o -obj-$(CONFIG_BACKLIGHT_LM3630)		+= lm3630_bl.o +obj-$(CONFIG_BACKLIGHT_LM3630A)		+= lm3630a_bl.o  obj-$(CONFIG_BACKLIGHT_LM3639)		+= lm3639_bl.o  obj-$(CONFIG_BACKLIGHT_LOCOMO)		+= locomolcd.o  obj-$(CONFIG_BACKLIGHT_LP855X)		+= lp855x_bl.o diff --git a/drivers/video/backlight/aat2870_bl.c b/drivers/video/backlight/aat2870_bl.c index c6fc668d623..ec5350f2c28 100644 --- a/drivers/video/backlight/aat2870_bl.c +++ b/drivers/video/backlight/aat2870_bl.c @@ -127,7 +127,7 @@ static const struct backlight_ops aat2870_bl_ops = {  static int aat2870_bl_probe(struct platform_device *pdev)  { -	struct aat2870_bl_platform_data *pdata = pdev->dev.platform_data; +	struct aat2870_bl_platform_data *pdata = dev_get_platdata(&pdev->dev);  	struct aat2870_bl_driver_data *aat2870_bl;  	struct backlight_device *bd;  	struct backlight_properties props; @@ -149,8 +149,6 @@ static int aat2870_bl_probe(struct platform_device *pdev)  				  sizeof(struct aat2870_bl_driver_data),  				  GFP_KERNEL);  	if (!aat2870_bl) { -		dev_err(&pdev->dev, -			"Failed to allocate memory for aat2870 backlight\n");  		ret = -ENOMEM;  		goto out;  	} @@ -158,8 +156,9 @@ static int aat2870_bl_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW; -	bd = backlight_device_register("aat2870-backlight", &pdev->dev, -				       aat2870_bl, &aat2870_bl_ops, &props); +	bd = devm_backlight_device_register(&pdev->dev, "aat2870-backlight", +					&pdev->dev, aat2870_bl, &aat2870_bl_ops, +					&props);  	if (IS_ERR(bd)) {  		dev_err(&pdev->dev,  			"Failed allocate memory for backlight device\n"); @@ -194,13 +193,11 @@ static int aat2870_bl_probe(struct platform_device *pdev)  	ret = aat2870_bl_update_status(bd);  	if (ret < 0) {  		dev_err(&pdev->dev, "Failed to initialize\n"); -		goto out_bl_dev_unregister; +		return ret;  	}  	return 0; -out_bl_dev_unregister: -	backlight_device_unregister(bd);  out:  	return ret;  } @@ -214,8 +211,6 @@ static int aat2870_bl_remove(struct platform_device *pdev)  	bd->props.brightness = 0;  	backlight_update_status(bd); -	backlight_device_unregister(bd); -  	return 0;  } diff --git a/drivers/video/backlight/adp5520_bl.c b/drivers/video/backlight/adp5520_bl.c index c84701b7ca6..f37097a261a 100644 --- a/drivers/video/backlight/adp5520_bl.c +++ b/drivers/video/backlight/adp5520_bl.c @@ -297,7 +297,7 @@ static int adp5520_bl_probe(struct platform_device *pdev)  		return -ENOMEM;  	data->master = pdev->dev.parent; -	data->pdata = pdev->dev.platform_data; +	data->pdata = dev_get_platdata(&pdev->dev);  	if (data->pdata  == NULL) {  		dev_err(&pdev->dev, "missing platform data\n"); @@ -312,8 +312,9 @@ static int adp5520_bl_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = ADP5020_MAX_BRIGHTNESS; -	bl = backlight_device_register(pdev->name, data->master, data, -				       &adp5520_bl_ops, &props); +	bl = devm_backlight_device_register(&pdev->dev, pdev->name, +					data->master, data, &adp5520_bl_ops, +					&props);  	if (IS_ERR(bl)) {  		dev_err(&pdev->dev, "failed to register backlight\n");  		return PTR_ERR(bl); @@ -326,7 +327,7 @@ static int adp5520_bl_probe(struct platform_device *pdev)  	if (ret) {  		dev_err(&pdev->dev, "failed to register sysfs\n"); -		backlight_device_unregister(bl); +		return ret;  	}  	platform_set_drvdata(pdev, bl); @@ -347,8 +348,6 @@ static int adp5520_bl_remove(struct platform_device *pdev)  		sysfs_remove_group(&bl->dev.kobj,  				&adp5520_bl_attr_group); -	backlight_device_unregister(bl); -  	return 0;  } diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c index 75b10f87612..be8d83deca7 100644 --- a/drivers/video/backlight/adp8860_bl.c +++ b/drivers/video/backlight/adp8860_bl.c @@ -216,7 +216,7 @@ static int adp8860_led_setup(struct adp8860_led *led)  static int adp8860_led_probe(struct i2c_client *client)  {  	struct adp8860_backlight_platform_data *pdata = -		client->dev.platform_data; +		dev_get_platdata(&client->dev);  	struct adp8860_bl *data = i2c_get_clientdata(client);  	struct adp8860_led *led, *led_dat;  	struct led_info *cur_led; @@ -224,10 +224,8 @@ static int adp8860_led_probe(struct i2c_client *client)  	led = devm_kzalloc(&client->dev, sizeof(*led) * pdata->num_leds,  				GFP_KERNEL); -	if (led == NULL) { -		dev_err(&client->dev, "failed to alloc memory\n"); +	if (led == NULL)  		return -ENOMEM; -	}  	ret = adp8860_write(client, ADP8860_ISCFR, pdata->led_fade_law);  	ret = adp8860_write(client, ADP8860_ISCT1, @@ -300,7 +298,7 @@ static int adp8860_led_probe(struct i2c_client *client)  static int adp8860_led_remove(struct i2c_client *client)  {  	struct adp8860_backlight_platform_data *pdata = -		client->dev.platform_data; +		dev_get_platdata(&client->dev);  	struct adp8860_bl *data = i2c_get_clientdata(client);  	int i; @@ -658,7 +656,7 @@ static int adp8860_probe(struct i2c_client *client,  	struct backlight_device *bl;  	struct adp8860_bl *data;  	struct adp8860_backlight_platform_data *pdata = -		client->dev.platform_data; +		dev_get_platdata(&client->dev);  	struct backlight_properties props;  	uint8_t reg_val;  	int ret; @@ -711,8 +709,9 @@ static int adp8860_probe(struct i2c_client *client,  	mutex_init(&data->lock); -	bl = backlight_device_register(dev_driver_string(&client->dev), -			&client->dev, data, &adp8860_bl_ops, &props); +	bl = devm_backlight_device_register(&client->dev, +				dev_driver_string(&client->dev), +				&client->dev, data, &adp8860_bl_ops, &props);  	if (IS_ERR(bl)) {  		dev_err(&client->dev, "failed to register backlight\n");  		return PTR_ERR(bl); @@ -728,7 +727,7 @@ static int adp8860_probe(struct i2c_client *client,  	if (ret) {  		dev_err(&client->dev, "failed to register sysfs\n"); -		goto out1; +		return ret;  	}  	ret = adp8860_bl_setup(bl); @@ -751,8 +750,6 @@ out:  	if (data->en_ambl_sens)  		sysfs_remove_group(&data->bl->dev.kobj,  			&adp8860_bl_attr_group); -out1: -	backlight_device_unregister(bl);  	return ret;  } @@ -770,8 +767,6 @@ static int adp8860_remove(struct i2c_client *client)  		sysfs_remove_group(&data->bl->dev.kobj,  			&adp8860_bl_attr_group); -	backlight_device_unregister(data->bl); -  	return 0;  } diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c index 90049d7b5c6..251af4d38d8 100644 --- a/drivers/video/backlight/adp8870_bl.c +++ b/drivers/video/backlight/adp8870_bl.c @@ -238,7 +238,7 @@ static int adp8870_led_setup(struct adp8870_led *led)  static int adp8870_led_probe(struct i2c_client *client)  {  	struct adp8870_backlight_platform_data *pdata = -		client->dev.platform_data; +		dev_get_platdata(&client->dev);  	struct adp8870_bl *data = i2c_get_clientdata(client);  	struct adp8870_led *led, *led_dat;  	struct led_info *cur_led; @@ -246,10 +246,8 @@ static int adp8870_led_probe(struct i2c_client *client)  	led = devm_kzalloc(&client->dev, pdata->num_leds * sizeof(*led),  				GFP_KERNEL); -	if (led == NULL) { -		dev_err(&client->dev, "failed to alloc memory\n"); +	if (led == NULL)  		return -ENOMEM; -	}  	ret = adp8870_write(client, ADP8870_ISCLAW, pdata->led_fade_law);  	if (ret) @@ -325,7 +323,7 @@ static int adp8870_led_probe(struct i2c_client *client)  static int adp8870_led_remove(struct i2c_client *client)  {  	struct adp8870_backlight_platform_data *pdata = -		client->dev.platform_data; +		dev_get_platdata(&client->dev);  	struct adp8870_bl *data = i2c_get_clientdata(client);  	int i; @@ -848,7 +846,7 @@ static int adp8870_probe(struct i2c_client *client,  	struct backlight_device *bl;  	struct adp8870_bl *data;  	struct adp8870_backlight_platform_data *pdata = -		client->dev.platform_data; +		dev_get_platdata(&client->dev);  	uint8_t reg_val;  	int ret; @@ -888,8 +886,9 @@ static int adp8870_probe(struct i2c_client *client,  	memset(&props, 0, sizeof(props));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = props.brightness = ADP8870_MAX_BRIGHTNESS; -	bl = backlight_device_register(dev_driver_string(&client->dev), -			&client->dev, data, &adp8870_bl_ops, &props); +	bl = devm_backlight_device_register(&client->dev, +				dev_driver_string(&client->dev), +				&client->dev, data, &adp8870_bl_ops, &props);  	if (IS_ERR(bl)) {  		dev_err(&client->dev, "failed to register backlight\n");  		return PTR_ERR(bl); @@ -902,7 +901,7 @@ static int adp8870_probe(struct i2c_client *client,  			&adp8870_bl_attr_group);  		if (ret) {  			dev_err(&client->dev, "failed to register sysfs\n"); -			goto out1; +			return ret;  		}  	} @@ -925,8 +924,6 @@ out:  	if (data->pdata->en_ambl_sens)  		sysfs_remove_group(&data->bl->dev.kobj,  			&adp8870_bl_attr_group); -out1: -	backlight_device_unregister(bl);  	return ret;  } @@ -944,8 +941,6 @@ static int adp8870_remove(struct i2c_client *client)  		sysfs_remove_group(&data->bl->dev.kobj,  			&adp8870_bl_attr_group); -	backlight_device_unregister(data->bl); -  	return 0;  } diff --git a/drivers/video/backlight/ams369fg06.c b/drivers/video/backlight/ams369fg06.c index 319fef6cb42..d8952c4aa68 100644 --- a/drivers/video/backlight/ams369fg06.c +++ b/drivers/video/backlight/ams369fg06.c @@ -471,14 +471,14 @@ static int ams369fg06_probe(struct spi_device *spi)  	lcd->spi = spi;  	lcd->dev = &spi->dev; -	lcd->lcd_pd = spi->dev.platform_data; +	lcd->lcd_pd = dev_get_platdata(&spi->dev);  	if (!lcd->lcd_pd) {  		dev_err(&spi->dev, "platform data is NULL\n");  		return -EINVAL;  	} -	ld = lcd_device_register("ams369fg06", &spi->dev, lcd, -		&ams369fg06_lcd_ops); +	ld = devm_lcd_device_register(&spi->dev, "ams369fg06", &spi->dev, lcd, +					&ams369fg06_lcd_ops);  	if (IS_ERR(ld))  		return PTR_ERR(ld); @@ -488,12 +488,11 @@ static int ams369fg06_probe(struct spi_device *spi)  	props.type = BACKLIGHT_RAW;  	props.max_brightness = MAX_BRIGHTNESS; -	bd = backlight_device_register("ams369fg06-bl", &spi->dev, lcd, -		&ams369fg06_backlight_ops, &props); -	if (IS_ERR(bd)) { -		ret =  PTR_ERR(bd); -		goto out_lcd_unregister; -	} +	bd = devm_backlight_device_register(&spi->dev, "ams369fg06-bl", +					&spi->dev, lcd, +					&ams369fg06_backlight_ops, &props); +	if (IS_ERR(bd)) +		return PTR_ERR(bd);  	bd->props.brightness = DEFAULT_BRIGHTNESS;  	lcd->bd = bd; @@ -516,10 +515,6 @@ static int ams369fg06_probe(struct spi_device *spi)  	dev_info(&spi->dev, "ams369fg06 panel driver has been probed.\n");  	return 0; - -out_lcd_unregister: -	lcd_device_unregister(ld); -	return ret;  }  static int ams369fg06_remove(struct spi_device *spi) @@ -527,9 +522,6 @@ static int ams369fg06_remove(struct spi_device *spi)  	struct ams369fg06 *lcd = spi_get_drvdata(spi);  	ams369fg06_power(lcd, FB_BLANK_POWERDOWN); -	backlight_device_unregister(lcd->bd); -	lcd_device_unregister(lcd->ld); -  	return 0;  } diff --git a/drivers/video/backlight/as3711_bl.c b/drivers/video/backlight/as3711_bl.c index 123887cd76b..bb1fc45b754 100644 --- a/drivers/video/backlight/as3711_bl.c +++ b/drivers/video/backlight/as3711_bl.c @@ -240,7 +240,8 @@ static int as3711_bl_register(struct platform_device *pdev,  	/* max tuning I = 31uA for voltage- and 38250uA for current-feedback */  	props.max_brightness = max_brightness; -	bl = backlight_device_register(su->type == AS3711_BL_SU1 ? +	bl = devm_backlight_device_register(&pdev->dev, +				       su->type == AS3711_BL_SU1 ?  				       "as3711-su1" : "as3711-su2",  				       &pdev->dev, su,  				       &as3711_bl_ops, &props); @@ -432,8 +433,7 @@ static int as3711_backlight_probe(struct platform_device *pdev)  		case AS3711_SU2_LX_SD4:  			break;  		default: -			ret = -EINVAL; -			goto esu2; +			return -EINVAL;  		}  		switch (pdata->su2_feedback) { @@ -447,8 +447,7 @@ static int as3711_backlight_probe(struct platform_device *pdev)  			max_brightness = min(pdata->su2_max_uA / 150, 255);  			break;  		default: -			ret = -EINVAL; -			goto esu2; +			return -EINVAL;  		}  		ret = as3711_bl_init_su2(supply); @@ -457,26 +456,12 @@ static int as3711_backlight_probe(struct platform_device *pdev)  		ret = as3711_bl_register(pdev, max_brightness, su);  		if (ret < 0) -			goto esu2; +			return ret;  	}  	platform_set_drvdata(pdev, supply);  	return 0; - -esu2: -	backlight_device_unregister(supply->su1.bl); -	return ret; -} - -static int as3711_backlight_remove(struct platform_device *pdev) -{ -	struct as3711_bl_supply *supply = platform_get_drvdata(pdev); - -	backlight_device_unregister(supply->su1.bl); -	backlight_device_unregister(supply->su2.bl); - -	return 0;  }  static struct platform_driver as3711_backlight_driver = { @@ -485,7 +470,6 @@ static struct platform_driver as3711_backlight_driver = {  		.owner	= THIS_MODULE,  	},  	.probe		= as3711_backlight_probe, -	.remove		= as3711_backlight_remove,  };  module_platform_driver(as3711_backlight_driver); diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c index 0393d827dd4..261b1a4ec3d 100644 --- a/drivers/video/backlight/atmel-pwm-bl.c +++ b/drivers/video/backlight/atmel-pwm-bl.c @@ -12,7 +12,6 @@  #include <linux/module.h>  #include <linux/platform_device.h>  #include <linux/fb.h> -#include <linux/clk.h>  #include <linux/gpio.h>  #include <linux/backlight.h>  #include <linux/atmel_pwm.h> @@ -27,6 +26,14 @@ struct atmel_pwm_bl {  	int					gpio_on;  }; +static void atmel_pwm_bl_set_gpio_on(struct atmel_pwm_bl *pwmbl, int on) +{ +	if (!gpio_is_valid(pwmbl->gpio_on)) +		return; + +	gpio_set_value(pwmbl->gpio_on, on ^ pwmbl->pdata->on_active_low); +} +  static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)  {  	struct atmel_pwm_bl *pwmbl = bl_get_data(bd); @@ -49,19 +56,13 @@ static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)  		pwm_duty = pwmbl->pdata->pwm_duty_min;  	if (!intensity) { -		if (pwmbl->gpio_on != -1) { -			gpio_set_value(pwmbl->gpio_on, -					0 ^ pwmbl->pdata->on_active_low); -		} +		atmel_pwm_bl_set_gpio_on(pwmbl, 0);  		pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);  		pwm_channel_disable(&pwmbl->pwmc);  	} else {  		pwm_channel_enable(&pwmbl->pwmc);  		pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty); -		if (pwmbl->gpio_on != -1) { -			gpio_set_value(pwmbl->gpio_on, -					1 ^ pwmbl->pdata->on_active_low); -		} +		atmel_pwm_bl_set_gpio_on(pwmbl, 1);  	}  	return 0; @@ -70,17 +71,16 @@ static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)  static int atmel_pwm_bl_get_intensity(struct backlight_device *bd)  {  	struct atmel_pwm_bl *pwmbl = bl_get_data(bd); -	u8 intensity; +	u32 cdty; +	u32 intensity; -	if (pwmbl->pdata->pwm_active_low) { -		intensity = pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY) - -			pwmbl->pdata->pwm_duty_min; -	} else { -		intensity = pwmbl->pdata->pwm_duty_max - -			pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY); -	} +	cdty = pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY); +	if (pwmbl->pdata->pwm_active_low) +		intensity = cdty - pwmbl->pdata->pwm_duty_min; +	else +		intensity = pwmbl->pdata->pwm_duty_max - cdty; -	return intensity; +	return intensity & 0xffff;  }  static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl) @@ -118,52 +118,46 @@ static const struct backlight_ops atmel_pwm_bl_ops = {  	.update_status  = atmel_pwm_bl_set_intensity,  }; -static int __init atmel_pwm_bl_probe(struct platform_device *pdev) +static int atmel_pwm_bl_probe(struct platform_device *pdev)  {  	struct backlight_properties props;  	const struct atmel_pwm_bl_platform_data *pdata;  	struct backlight_device *bldev;  	struct atmel_pwm_bl *pwmbl; +	unsigned long flags;  	int retval; +	pdata = dev_get_platdata(&pdev->dev); +	if (!pdata) +		return -ENODEV; + +	if (pdata->pwm_compare_max < pdata->pwm_duty_max || +			pdata->pwm_duty_min > pdata->pwm_duty_max || +			pdata->pwm_frequency == 0) +		return -EINVAL; +  	pwmbl = devm_kzalloc(&pdev->dev, sizeof(struct atmel_pwm_bl),  				GFP_KERNEL);  	if (!pwmbl)  		return -ENOMEM;  	pwmbl->pdev = pdev; - -	pdata = pdev->dev.platform_data; -	if (!pdata) { -		retval = -ENODEV; -		goto err_free_mem; -	} - -	if (pdata->pwm_compare_max < pdata->pwm_duty_max || -			pdata->pwm_duty_min > pdata->pwm_duty_max || -			pdata->pwm_frequency == 0) { -		retval = -EINVAL; -		goto err_free_mem; -	} -  	pwmbl->pdata = pdata;  	pwmbl->gpio_on = pdata->gpio_on;  	retval = pwm_channel_alloc(pdata->pwm_channel, &pwmbl->pwmc);  	if (retval) -		goto err_free_mem; - -	if (pwmbl->gpio_on != -1) { -		retval = devm_gpio_request(&pdev->dev, pwmbl->gpio_on, -					"gpio_atmel_pwm_bl"); -		if (retval) { -			pwmbl->gpio_on = -1; -			goto err_free_pwm; -		} +		return retval; +	if (gpio_is_valid(pwmbl->gpio_on)) {  		/* Turn display off by default. */ -		retval = gpio_direction_output(pwmbl->gpio_on, -				0 ^ pdata->on_active_low); +		if (pdata->on_active_low) +			flags = GPIOF_OUT_INIT_HIGH; +		else +			flags = GPIOF_OUT_INIT_LOW; + +		retval = devm_gpio_request_one(&pdev->dev, pwmbl->gpio_on, +						flags, "gpio_atmel_pwm_bl");  		if (retval)  			goto err_free_pwm;  	} @@ -171,8 +165,9 @@ static int __init atmel_pwm_bl_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min; -	bldev = backlight_device_register("atmel-pwm-bl", &pdev->dev, pwmbl, -					  &atmel_pwm_bl_ops, &props); +	bldev = devm_backlight_device_register(&pdev->dev, "atmel-pwm-bl", +					&pdev->dev, pwmbl, &atmel_pwm_bl_ops, +					&props);  	if (IS_ERR(bldev)) {  		retval = PTR_ERR(bldev);  		goto err_free_pwm; @@ -188,29 +183,25 @@ static int __init atmel_pwm_bl_probe(struct platform_device *pdev)  	retval = atmel_pwm_bl_init_pwm(pwmbl);  	if (retval) -		goto err_free_bl_dev; +		goto err_free_pwm;  	atmel_pwm_bl_set_intensity(bldev);  	return 0; -err_free_bl_dev: -	backlight_device_unregister(bldev);  err_free_pwm:  	pwm_channel_free(&pwmbl->pwmc); -err_free_mem: +  	return retval;  } -static int __exit atmel_pwm_bl_remove(struct platform_device *pdev) +static int atmel_pwm_bl_remove(struct platform_device *pdev)  {  	struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev); -	if (pwmbl->gpio_on != -1) -		gpio_set_value(pwmbl->gpio_on, 0); +	atmel_pwm_bl_set_gpio_on(pwmbl, 0);  	pwm_channel_disable(&pwmbl->pwmc);  	pwm_channel_free(&pwmbl->pwmc); -	backlight_device_unregister(pwmbl->bldev);  	return 0;  } @@ -220,11 +211,13 @@ static struct platform_driver atmel_pwm_bl_driver = {  		.name = "atmel-pwm-bl",  	},  	/* REVISIT add suspend() and resume() */ -	.remove = __exit_p(atmel_pwm_bl_remove), +	.probe = atmel_pwm_bl_probe, +	.remove = atmel_pwm_bl_remove,  }; -module_platform_driver_probe(atmel_pwm_bl_driver, atmel_pwm_bl_probe); +module_platform_driver(atmel_pwm_bl_driver);  MODULE_AUTHOR("Hans-Christian egtvedt <hans-christian.egtvedt@atmel.com>");  MODULE_DESCRIPTION("Atmel PWM backlight driver");  MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:atmel-pwm-bl"); diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 94a403a9717..428089009cd 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c @@ -21,6 +21,10 @@  #include <asm/backlight.h>  #endif +static struct list_head backlight_dev_list; +static struct mutex backlight_dev_list_mutex; +static struct blocking_notifier_head backlight_notifier; +  static const char *const backlight_types[] = {  	[BACKLIGHT_RAW] = "raw",  	[BACKLIGHT_PLATFORM] = "platform", @@ -31,13 +35,15 @@ static const char *const backlight_types[] = {  			   defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE))  /* This callback gets called when something important happens inside a   * framebuffer driver. We're looking if that important event is blanking, - * and if it is, we're switching backlight power as well ... + * and if it is and necessary, we're switching backlight power as well ...   */  static int fb_notifier_callback(struct notifier_block *self,  				unsigned long event, void *data)  {  	struct backlight_device *bd;  	struct fb_event *evdata = data; +	int node = evdata->info->node; +	int fb_blank = 0;  	/* If we aren't interested in this event, skip it immediately ... */  	if (event != FB_EVENT_BLANK && event != FB_EVENT_CONBLANK) @@ -48,12 +54,24 @@ static int fb_notifier_callback(struct notifier_block *self,  	if (bd->ops)  		if (!bd->ops->check_fb ||  		    bd->ops->check_fb(bd, evdata->info)) { -			bd->props.fb_blank = *(int *)evdata->data; -			if (bd->props.fb_blank == FB_BLANK_UNBLANK) -				bd->props.state &= ~BL_CORE_FBBLANK; -			else -				bd->props.state |= BL_CORE_FBBLANK; -			backlight_update_status(bd); +			fb_blank = *(int *)evdata->data; +			if (fb_blank == FB_BLANK_UNBLANK && +			    !bd->fb_bl_on[node]) { +				bd->fb_bl_on[node] = true; +				if (!bd->use_count++) { +					bd->props.state &= ~BL_CORE_FBBLANK; +					bd->props.fb_blank = FB_BLANK_UNBLANK; +					backlight_update_status(bd); +				} +			} else if (fb_blank != FB_BLANK_UNBLANK && +				   bd->fb_bl_on[node]) { +				bd->fb_bl_on[node] = false; +				if (!(--bd->use_count)) { +					bd->props.state |= BL_CORE_FBBLANK; +					bd->props.fb_blank = fb_blank; +					backlight_update_status(bd); +				} +			}  		}  	mutex_unlock(&bd->ops_lock);  	return 0; @@ -330,7 +348,7 @@ struct backlight_device *backlight_device_register(const char *name,  	rc = device_register(&new_bd->dev);  	if (rc) { -		kfree(new_bd); +		put_device(&new_bd->dev);  		return ERR_PTR(rc);  	} @@ -349,10 +367,35 @@ struct backlight_device *backlight_device_register(const char *name,  	mutex_unlock(&pmac_backlight_mutex);  #endif +	mutex_lock(&backlight_dev_list_mutex); +	list_add(&new_bd->entry, &backlight_dev_list); +	mutex_unlock(&backlight_dev_list_mutex); + +	blocking_notifier_call_chain(&backlight_notifier, +				     BACKLIGHT_REGISTERED, new_bd); +  	return new_bd;  }  EXPORT_SYMBOL(backlight_device_register); +bool backlight_device_registered(enum backlight_type type) +{ +	bool found = false; +	struct backlight_device *bd; + +	mutex_lock(&backlight_dev_list_mutex); +	list_for_each_entry(bd, &backlight_dev_list, entry) { +		if (bd->props.type == type) { +			found = true; +			break; +		} +	} +	mutex_unlock(&backlight_dev_list_mutex); + +	return found; +} +EXPORT_SYMBOL(backlight_device_registered); +  /**   * backlight_device_unregister - unregisters a backlight device object.   * @bd: the backlight device object to be unregistered and freed. @@ -364,12 +407,20 @@ void backlight_device_unregister(struct backlight_device *bd)  	if (!bd)  		return; +	mutex_lock(&backlight_dev_list_mutex); +	list_del(&bd->entry); +	mutex_unlock(&backlight_dev_list_mutex); +  #ifdef CONFIG_PMAC_BACKLIGHT  	mutex_lock(&pmac_backlight_mutex);  	if (pmac_backlight == bd)  		pmac_backlight = NULL;  	mutex_unlock(&pmac_backlight_mutex);  #endif + +	blocking_notifier_call_chain(&backlight_notifier, +				     BACKLIGHT_UNREGISTERED, bd); +  	mutex_lock(&bd->ops_lock);  	bd->ops = NULL;  	mutex_unlock(&bd->ops_lock); @@ -395,6 +446,36 @@ static int devm_backlight_device_match(struct device *dev, void *res,  }  /** + * backlight_register_notifier - get notified of backlight (un)registration + * @nb: notifier block with the notifier to call on backlight (un)registration + * + * @return 0 on success, otherwise a negative error code + * + * Register a notifier to get notified when backlight devices get registered + * or unregistered. + */ +int backlight_register_notifier(struct notifier_block *nb) +{ +	return blocking_notifier_chain_register(&backlight_notifier, nb); +} +EXPORT_SYMBOL(backlight_register_notifier); + +/** + * backlight_unregister_notifier - unregister a backlight notifier + * @nb: notifier block to unregister + * + * @return 0 on success, otherwise a negative error code + * + * Register a notifier to get notified when backlight devices get registered + * or unregistered. + */ +int backlight_unregister_notifier(struct notifier_block *nb) +{ +	return blocking_notifier_chain_unregister(&backlight_notifier, nb); +} +EXPORT_SYMBOL(backlight_unregister_notifier); + +/**   * devm_backlight_device_register - resource managed backlight_device_register()   * @dev: the device to register   * @name: the name of the device @@ -499,6 +580,10 @@ static int __init backlight_class_init(void)  	backlight_class->dev_groups = bl_device_groups;  	backlight_class->pm = &backlight_class_dev_pm_ops; +	INIT_LIST_HEAD(&backlight_dev_list); +	mutex_init(&backlight_dev_list_mutex); +	BLOCKING_INIT_NOTIFIER_HEAD(&backlight_notifier); +  	return 0;  } diff --git a/drivers/video/backlight/bd6107.c b/drivers/video/backlight/bd6107.c index 15e3294b29f..16dd9bc625b 100644 --- a/drivers/video/backlight/bd6107.c +++ b/drivers/video/backlight/bd6107.c @@ -128,7 +128,7 @@ static const struct backlight_ops bd6107_backlight_ops = {  static int bd6107_probe(struct i2c_client *client,  			  const struct i2c_device_id *id)  { -	struct bd6107_platform_data *pdata = client->dev.platform_data; +	struct bd6107_platform_data *pdata = dev_get_platdata(&client->dev);  	struct backlight_device *backlight;  	struct backlight_properties props;  	struct bd6107 *bd; @@ -166,7 +166,8 @@ static int bd6107_probe(struct i2c_client *client,  	props.brightness = clamp_t(unsigned int, pdata->def_value, 0,  				   props.max_brightness); -	backlight = backlight_device_register(dev_name(&client->dev), +	backlight = devm_backlight_device_register(&client->dev, +					      dev_name(&client->dev),  					      &bd->client->dev, bd,  					      &bd6107_backlight_ops, &props);  	if (IS_ERR(backlight)) { @@ -186,7 +187,6 @@ static int bd6107_remove(struct i2c_client *client)  	backlight->props.brightness = 0;  	backlight_update_status(backlight); -	backlight_device_unregister(backlight);  	return 0;  } diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c index c97867a717a..51d18d637e2 100644 --- a/drivers/video/backlight/corgi_lcd.c +++ b/drivers/video/backlight/corgi_lcd.c @@ -533,7 +533,7 @@ static int setup_gpio_backlight(struct corgi_lcd *lcd,  static int corgi_lcd_probe(struct spi_device *spi)  {  	struct backlight_properties props; -	struct corgi_lcd_platform_data *pdata = spi->dev.platform_data; +	struct corgi_lcd_platform_data *pdata = dev_get_platdata(&spi->dev);  	struct corgi_lcd *lcd;  	int ret = 0; @@ -543,15 +543,13 @@ static int corgi_lcd_probe(struct spi_device *spi)  	}  	lcd = devm_kzalloc(&spi->dev, sizeof(struct corgi_lcd), GFP_KERNEL); -	if (!lcd) { -		dev_err(&spi->dev, "failed to allocate memory\n"); +	if (!lcd)  		return -ENOMEM; -	}  	lcd->spi_dev = spi; -	lcd->lcd_dev = lcd_device_register("corgi_lcd", &spi->dev, -					lcd, &corgi_lcd_ops); +	lcd->lcd_dev = devm_lcd_device_register(&spi->dev, "corgi_lcd", +						&spi->dev, lcd, &corgi_lcd_ops);  	if (IS_ERR(lcd->lcd_dev))  		return PTR_ERR(lcd->lcd_dev); @@ -561,18 +559,18 @@ static int corgi_lcd_probe(struct spi_device *spi)  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = pdata->max_intensity; -	lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, lcd, -						&corgi_bl_ops, &props); -	if (IS_ERR(lcd->bl_dev)) { -		ret = PTR_ERR(lcd->bl_dev); -		goto err_unregister_lcd; -	} +	lcd->bl_dev = devm_backlight_device_register(&spi->dev, "corgi_bl", +						&spi->dev, lcd, &corgi_bl_ops, +						&props); +	if (IS_ERR(lcd->bl_dev)) +		return PTR_ERR(lcd->bl_dev); +  	lcd->bl_dev->props.brightness = pdata->default_intensity;  	lcd->bl_dev->props.power = FB_BLANK_UNBLANK;  	ret = setup_gpio_backlight(lcd, pdata);  	if (ret) -		goto err_unregister_bl; +		return ret;  	lcd->kick_battery = pdata->kick_battery; @@ -583,12 +581,6 @@ static int corgi_lcd_probe(struct spi_device *spi)  	lcd->limit_mask = pdata->limit_mask;  	the_corgi_lcd = lcd;  	return 0; - -err_unregister_bl: -	backlight_device_unregister(lcd->bl_dev); -err_unregister_lcd: -	lcd_device_unregister(lcd->lcd_dev); -	return ret;  }  static int corgi_lcd_remove(struct spi_device *spi) @@ -598,11 +590,7 @@ static int corgi_lcd_remove(struct spi_device *spi)  	lcd->bl_dev->props.power = FB_BLANK_UNBLANK;  	lcd->bl_dev->props.brightness = 0;  	backlight_update_status(lcd->bl_dev); -	backlight_device_unregister(lcd->bl_dev); -  	corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN); -	lcd_device_unregister(lcd->lcd_dev); -  	return 0;  } diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c index 37bae801e23..f3fed9ef745 100644 --- a/drivers/video/backlight/cr_bllcd.c +++ b/drivers/video/backlight/cr_bllcd.c @@ -195,16 +195,17 @@ static int cr_backlight_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW; -	bdp = backlight_device_register("cr-backlight", &pdev->dev, NULL, -					&cr_backlight_ops, &props); +	bdp = devm_backlight_device_register(&pdev->dev, "cr-backlight", +					&pdev->dev, NULL, &cr_backlight_ops, +					&props);  	if (IS_ERR(bdp)) {  		pci_dev_put(lpc_dev);  		return PTR_ERR(bdp);  	} -	ldp = lcd_device_register("cr-lcd", &pdev->dev, NULL, &cr_lcd_ops); +	ldp = devm_lcd_device_register(&pdev->dev, "cr-lcd", &pdev->dev, NULL, +					&cr_lcd_ops);  	if (IS_ERR(ldp)) { -		backlight_device_unregister(bdp);  		pci_dev_put(lpc_dev);  		return PTR_ERR(ldp);  	} @@ -215,8 +216,6 @@ static int cr_backlight_probe(struct platform_device *pdev)  	crp = devm_kzalloc(&pdev->dev, sizeof(*crp), GFP_KERNEL);  	if (!crp) { -		lcd_device_unregister(ldp); -		backlight_device_unregister(bdp);  		pci_dev_put(lpc_dev);  		return -ENOMEM;  	} @@ -241,8 +240,6 @@ static int cr_backlight_remove(struct platform_device *pdev)  	crp->cr_backlight_device->props.max_brightness = 0;  	cr_backlight_set_intensity(crp->cr_backlight_device);  	cr_lcd_set_power(crp->cr_lcd_device, FB_BLANK_POWERDOWN); -	backlight_device_unregister(crp->cr_backlight_device); -	lcd_device_unregister(crp->cr_lcd_device);  	pci_dev_put(lpc_dev);  	return 0; diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c index 67cadd30e27..12c5d840c59 100644 --- a/drivers/video/backlight/da903x_bl.c +++ b/drivers/video/backlight/da903x_bl.c @@ -109,7 +109,7 @@ static const struct backlight_ops da903x_backlight_ops = {  static int da903x_backlight_probe(struct platform_device *pdev)  { -	struct da9034_backlight_pdata *pdata = pdev->dev.platform_data; +	struct da9034_backlight_pdata *pdata = dev_get_platdata(&pdev->dev);  	struct da903x_backlight_data *data;  	struct backlight_device *bl;  	struct backlight_properties props; @@ -144,8 +144,9 @@ static int da903x_backlight_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(props));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = max_brightness; -	bl = backlight_device_register(pdev->name, data->da903x_dev, data, -				       &da903x_backlight_ops, &props); +	bl = devm_backlight_device_register(&pdev->dev, pdev->name, +					data->da903x_dev, data, +					&da903x_backlight_ops, &props);  	if (IS_ERR(bl)) {  		dev_err(&pdev->dev, "failed to register backlight\n");  		return PTR_ERR(bl); @@ -158,21 +159,12 @@ static int da903x_backlight_probe(struct platform_device *pdev)  	return 0;  } -static int da903x_backlight_remove(struct platform_device *pdev) -{ -	struct backlight_device *bl = platform_get_drvdata(pdev); - -	backlight_device_unregister(bl); -	return 0; -} -  static struct platform_driver da903x_backlight_driver = {  	.driver		= {  		.name	= "da903x-backlight",  		.owner	= THIS_MODULE,  	},  	.probe		= da903x_backlight_probe, -	.remove		= da903x_backlight_remove,  };  module_platform_driver(da903x_backlight_driver); diff --git a/drivers/video/backlight/da9052_bl.c b/drivers/video/backlight/da9052_bl.c index 842da5a3ac4..20d55becaa7 100644 --- a/drivers/video/backlight/da9052_bl.c +++ b/drivers/video/backlight/da9052_bl.c @@ -125,8 +125,9 @@ static int da9052_backlight_probe(struct platform_device *pdev)  	props.type = BACKLIGHT_RAW;  	props.max_brightness = DA9052_MAX_BRIGHTNESS; -	bl = backlight_device_register(pdev->name, wleds->da9052->dev, wleds, -				       &da9052_backlight_ops, &props); +	bl = devm_backlight_device_register(&pdev->dev, pdev->name, +					wleds->da9052->dev, wleds, +					&da9052_backlight_ops, &props);  	if (IS_ERR(bl)) {  		dev_err(&pdev->dev, "Failed to register backlight\n");  		return PTR_ERR(bl); @@ -147,7 +148,6 @@ static int da9052_backlight_remove(struct platform_device *pdev)  	wleds->brightness = 0;  	wleds->state = DA9052_WLEDS_OFF;  	da9052_adjust_wled_brightness(wleds); -	backlight_device_unregister(bl);  	return 0;  } diff --git a/drivers/video/backlight/ep93xx_bl.c b/drivers/video/backlight/ep93xx_bl.c index 018368ba412..0d1f633c648 100644 --- a/drivers/video/backlight/ep93xx_bl.c +++ b/drivers/video/backlight/ep93xx_bl.c @@ -92,8 +92,8 @@ static int ep93xxbl_probe(struct platform_device *dev)  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = EP93XX_MAX_BRIGHT; -	bl = backlight_device_register(dev->name, &dev->dev, ep93xxbl, -				       &ep93xxbl_ops, &props); +	bl = devm_backlight_device_register(&dev->dev, dev->name, &dev->dev, +					ep93xxbl, &ep93xxbl_ops, &props);  	if (IS_ERR(bl))  		return PTR_ERR(bl); @@ -106,14 +106,6 @@ static int ep93xxbl_probe(struct platform_device *dev)  	return 0;  } -static int ep93xxbl_remove(struct platform_device *dev) -{ -	struct backlight_device *bl = platform_get_drvdata(dev); - -	backlight_device_unregister(bl); -	return 0; -} -  #ifdef CONFIG_PM_SLEEP  static int ep93xxbl_suspend(struct device *dev)  { @@ -140,7 +132,6 @@ static struct platform_driver ep93xxbl_driver = {  		.pm	= &ep93xxbl_pm_ops,  	},  	.probe		= ep93xxbl_probe, -	.remove		= ep93xxbl_remove,  };  module_platform_driver(ep93xxbl_driver); diff --git a/drivers/video/backlight/generic_bl.c b/drivers/video/backlight/generic_bl.c index 19e393b4143..5d8d65200db 100644 --- a/drivers/video/backlight/generic_bl.c +++ b/drivers/video/backlight/generic_bl.c @@ -79,7 +79,7 @@ static const struct backlight_ops genericbl_ops = {  static int genericbl_probe(struct platform_device *pdev)  {  	struct backlight_properties props; -	struct generic_bl_info *machinfo = pdev->dev.platform_data; +	struct generic_bl_info *machinfo = dev_get_platdata(&pdev->dev);  	const char *name = "generic-bl";  	struct backlight_device *bd; @@ -93,8 +93,8 @@ static int genericbl_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = machinfo->max_intensity; -	bd = backlight_device_register(name, &pdev->dev, NULL, &genericbl_ops, -				       &props); +	bd = devm_backlight_device_register(&pdev->dev, name, &pdev->dev, +					NULL, &genericbl_ops, &props);  	if (IS_ERR(bd))  		return PTR_ERR(bd); @@ -118,8 +118,6 @@ static int genericbl_remove(struct platform_device *pdev)  	bd->props.brightness = 0;  	backlight_update_status(bd); -	backlight_device_unregister(bd); -  	dev_info(&pdev->dev, "Generic Backlight Driver Unloaded\n");  	return 0;  } diff --git a/drivers/video/backlight/gpio_backlight.c b/drivers/video/backlight/gpio_backlight.c index 5fa217f9f44..1cea68848f1 100644 --- a/drivers/video/backlight/gpio_backlight.c +++ b/drivers/video/backlight/gpio_backlight.c @@ -13,6 +13,8 @@  #include <linux/init.h>  #include <linux/kernel.h>  #include <linux/module.h> +#include <linux/of.h> +#include <linux/of_gpio.h>  #include <linux/platform_data/gpio_backlight.h>  #include <linux/platform_device.h>  #include <linux/slab.h> @@ -23,6 +25,7 @@ struct gpio_backlight {  	int gpio;  	int active; +	int def_value;  };  static int gpio_backlight_update_status(struct backlight_device *bl) @@ -35,7 +38,8 @@ static int gpio_backlight_update_status(struct backlight_device *bl)  	    bl->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK))  		brightness = 0; -	gpio_set_value(gbl->gpio, brightness ? gbl->active : !gbl->active); +	gpio_set_value_cansleep(gbl->gpio, +				brightness ? gbl->active : !gbl->active);  	return 0;  } @@ -60,16 +64,42 @@ static const struct backlight_ops gpio_backlight_ops = {  	.check_fb	= gpio_backlight_check_fb,  }; +static int gpio_backlight_probe_dt(struct platform_device *pdev, +				   struct gpio_backlight *gbl) +{ +	struct device_node *np = pdev->dev.of_node; +	enum of_gpio_flags gpio_flags; + +	gbl->gpio = of_get_gpio_flags(np, 0, &gpio_flags); + +	if (!gpio_is_valid(gbl->gpio)) { +		if (gbl->gpio != -EPROBE_DEFER) { +			dev_err(&pdev->dev, +				"Error: The gpios parameter is missing or invalid.\n"); +		} +		return gbl->gpio; +	} + +	gbl->active = (gpio_flags & OF_GPIO_ACTIVE_LOW) ? 0 : 1; + +	gbl->def_value = of_property_read_bool(np, "default-on"); + +	return 0; +} +  static int gpio_backlight_probe(struct platform_device *pdev)  { -	struct gpio_backlight_platform_data *pdata = pdev->dev.platform_data; +	struct gpio_backlight_platform_data *pdata = +		dev_get_platdata(&pdev->dev);  	struct backlight_properties props;  	struct backlight_device *bl;  	struct gpio_backlight *gbl; +	struct device_node *np = pdev->dev.of_node;  	int ret; -	if (!pdata) { -		dev_err(&pdev->dev, "failed to find platform data\n"); +	if (!pdata && !np) { +		dev_err(&pdev->dev, +			"failed to find platform data or device tree node.\n");  		return -ENODEV;  	} @@ -78,14 +108,22 @@ static int gpio_backlight_probe(struct platform_device *pdev)  		return -ENOMEM;  	gbl->dev = &pdev->dev; -	gbl->fbdev = pdata->fbdev; -	gbl->gpio = pdata->gpio; -	gbl->active = pdata->active_low ? 0 : 1; + +	if (np) { +		ret = gpio_backlight_probe_dt(pdev, gbl); +		if (ret) +			return ret; +	} else { +		gbl->fbdev = pdata->fbdev; +		gbl->gpio = pdata->gpio; +		gbl->active = pdata->active_low ? 0 : 1; +		gbl->def_value = pdata->def_value; +	}  	ret = devm_gpio_request_one(gbl->dev, gbl->gpio, GPIOF_DIR_OUT |  				    (gbl->active ? GPIOF_INIT_LOW  						 : GPIOF_INIT_HIGH), -				    pdata->name); +				    pdata ? pdata->name : "backlight");  	if (ret < 0) {  		dev_err(&pdev->dev, "unable to request GPIO\n");  		return ret; @@ -94,35 +132,35 @@ static int gpio_backlight_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(props));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = 1; -	bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, gbl, -				       &gpio_backlight_ops, &props); +	bl = devm_backlight_device_register(&pdev->dev, dev_name(&pdev->dev), +					&pdev->dev, gbl, &gpio_backlight_ops, +					&props);  	if (IS_ERR(bl)) {  		dev_err(&pdev->dev, "failed to register backlight\n");  		return PTR_ERR(bl);  	} -	bl->props.brightness = pdata->def_value; +	bl->props.brightness = gbl->def_value;  	backlight_update_status(bl);  	platform_set_drvdata(pdev, bl);  	return 0;  } -static int gpio_backlight_remove(struct platform_device *pdev) -{ -	struct backlight_device *bl = platform_get_drvdata(pdev); - -	backlight_device_unregister(bl); -	return 0; -} +#ifdef CONFIG_OF +static struct of_device_id gpio_backlight_of_match[] = { +	{ .compatible = "gpio-backlight" }, +	{ /* sentinel */ } +}; +#endif  static struct platform_driver gpio_backlight_driver = {  	.driver		= {  		.name		= "gpio-backlight",  		.owner		= THIS_MODULE, +		.of_match_table = of_match_ptr(gpio_backlight_of_match),  	},  	.probe		= gpio_backlight_probe, -	.remove		= gpio_backlight_remove,  };  module_platform_driver(gpio_backlight_driver); diff --git a/drivers/video/backlight/hp680_bl.c b/drivers/video/backlight/hp680_bl.c index 00076ecfe9b..8ea42b8d9bc 100644 --- a/drivers/video/backlight/hp680_bl.c +++ b/drivers/video/backlight/hp680_bl.c @@ -110,8 +110,8 @@ static int hp680bl_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = HP680_MAX_INTENSITY; -	bd = backlight_device_register("hp680-bl", &pdev->dev, NULL, -				       &hp680bl_ops, &props); +	bd = devm_backlight_device_register(&pdev->dev, "hp680-bl", &pdev->dev, +					NULL, &hp680bl_ops, &props);  	if (IS_ERR(bd))  		return PTR_ERR(bd); @@ -131,8 +131,6 @@ static int hp680bl_remove(struct platform_device *pdev)  	bd->props.power = 0;  	hp680bl_send_intensity(bd); -	backlight_device_unregister(bd); -  	return 0;  } diff --git a/drivers/video/backlight/hx8357.c b/drivers/video/backlight/hx8357.c index c7af8c45ab8..23f50b92a93 100644 --- a/drivers/video/backlight/hx8357.c +++ b/drivers/video/backlight/hx8357.c @@ -587,10 +587,8 @@ static int hx8357_probe(struct spi_device *spi)  	int i, ret;  	lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL); -	if (!lcd) { -		dev_err(&spi->dev, "Couldn't allocate lcd internal structure!\n"); +	if (!lcd)  		return -ENOMEM; -	}  	ret = spi_setup(spi);  	if (ret < 0) { @@ -648,7 +646,8 @@ static int hx8357_probe(struct spi_device *spi)  		lcd->use_im_pins = 0;  	} -	lcdev = lcd_device_register("mxsfb", &spi->dev, lcd, &hx8357_ops); +	lcdev = devm_lcd_device_register(&spi->dev, "mxsfb", &spi->dev, lcd, +					&hx8357_ops);  	if (IS_ERR(lcdev)) {  		ret = PTR_ERR(lcdev);  		return ret; @@ -660,32 +659,19 @@ static int hx8357_probe(struct spi_device *spi)  	ret = ((int (*)(struct lcd_device *))match->data)(lcdev);  	if (ret) {  		dev_err(&spi->dev, "Couldn't initialize panel\n"); -		goto init_error; +		return ret;  	}  	dev_info(&spi->dev, "Panel probed\n");  	return 0; - -init_error: -	lcd_device_unregister(lcdev); -	return ret; -} - -static int hx8357_remove(struct spi_device *spi) -{ -	struct lcd_device *lcdev = spi_get_drvdata(spi); - -	lcd_device_unregister(lcdev); -	return 0;  }  static struct spi_driver hx8357_driver = {  	.probe  = hx8357_probe, -	.remove = hx8357_remove,  	.driver = {  		.name = "hx8357", -		.of_match_table = of_match_ptr(hx8357_dt_ids), +		.of_match_table = hx8357_dt_ids,  	},  }; diff --git a/drivers/video/backlight/ili922x.c b/drivers/video/backlight/ili922x.c index d9f65c2d9b0..ea67fe199e3 100644 --- a/drivers/video/backlight/ili922x.c +++ b/drivers/video/backlight/ili922x.c @@ -482,10 +482,8 @@ static int ili922x_probe(struct spi_device *spi)  	u16 reg = 0;  	ili = devm_kzalloc(&spi->dev, sizeof(*ili), GFP_KERNEL); -	if (!ili) { -		dev_err(&spi->dev, "cannot alloc priv data\n"); +	if (!ili)  		return -ENOMEM; -	}  	ili->spi = spi;  	spi_set_drvdata(spi, ili); @@ -513,8 +511,8 @@ static int ili922x_probe(struct spi_device *spi)  	ili->power = FB_BLANK_POWERDOWN; -	lcd = lcd_device_register("ili922xlcd", &spi->dev, ili, -				  &ili922x_ops); +	lcd = devm_lcd_device_register(&spi->dev, "ili922xlcd", &spi->dev, ili, +					&ili922x_ops);  	if (IS_ERR(lcd)) {  		dev_err(&spi->dev, "cannot register LCD\n");  		return PTR_ERR(lcd); @@ -530,10 +528,7 @@ static int ili922x_probe(struct spi_device *spi)  static int ili922x_remove(struct spi_device *spi)  { -	struct ili922x *ili = spi_get_drvdata(spi); -  	ili922x_poweroff(spi); -	lcd_device_unregister(ili->ld);  	return 0;  } diff --git a/drivers/video/backlight/ili9320.c b/drivers/video/backlight/ili9320.c index f8be90c5ded..2cf39e6d519 100644 --- a/drivers/video/backlight/ili9320.c +++ b/drivers/video/backlight/ili9320.c @@ -198,7 +198,7 @@ static void ili9320_setup_spi(struct ili9320 *ili,  int ili9320_probe_spi(struct spi_device *spi,  				struct ili9320_client *client)  { -	struct ili9320_platdata *cfg = spi->dev.platform_data; +	struct ili9320_platdata *cfg = dev_get_platdata(&spi->dev);  	struct device *dev = &spi->dev;  	struct ili9320 *ili;  	struct lcd_device *lcd; @@ -219,10 +219,8 @@ int ili9320_probe_spi(struct spi_device *spi,  	/* allocate and initialse our state */  	ili = devm_kzalloc(&spi->dev, sizeof(struct ili9320), GFP_KERNEL); -	if (ili == NULL) { -		dev_err(dev, "no memory for device\n"); +	if (ili == NULL)  		return -ENOMEM; -	}  	ili->access.spi.id = ILI9320_SPI_IDCODE | ILI9320_SPI_ID(1); @@ -235,7 +233,8 @@ int ili9320_probe_spi(struct spi_device *spi,  	ili9320_setup_spi(ili, spi); -	lcd = lcd_device_register("ili9320", dev, ili, &ili9320_ops); +	lcd = devm_lcd_device_register(&spi->dev, "ili9320", dev, ili, +					&ili9320_ops);  	if (IS_ERR(lcd)) {  		dev_err(dev, "failed to register lcd device\n");  		return PTR_ERR(lcd); @@ -248,24 +247,16 @@ int ili9320_probe_spi(struct spi_device *spi,  	ret = ili9320_power(ili, FB_BLANK_UNBLANK);  	if (ret != 0) {  		dev_err(dev, "failed to set lcd power state\n"); -		goto err_unregister; +		return ret;  	}  	return 0; - - err_unregister: -	lcd_device_unregister(lcd); - -	return ret;  }  EXPORT_SYMBOL_GPL(ili9320_probe_spi);  int ili9320_remove(struct ili9320 *ili)  {  	ili9320_power(ili, FB_BLANK_POWERDOWN); - -	lcd_device_unregister(ili->lcd); -  	return 0;  }  EXPORT_SYMBOL_GPL(ili9320_remove); diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c index 3ccb89340f2..6ce96b4a879 100644 --- a/drivers/video/backlight/jornada720_bl.c +++ b/drivers/video/backlight/jornada720_bl.c @@ -115,9 +115,10 @@ static int jornada_bl_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = BL_MAX_BRIGHT; -	bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, -				       &jornada_bl_ops, &props); +	bd = devm_backlight_device_register(&pdev->dev, S1D_DEVICENAME, +					&pdev->dev, NULL, &jornada_bl_ops, +					&props);  	if (IS_ERR(bd)) {  		ret = PTR_ERR(bd);  		dev_err(&pdev->dev, "failed to register device, err=%x\n", ret); @@ -139,18 +140,8 @@ static int jornada_bl_probe(struct platform_device *pdev)  	return 0;  } -static int jornada_bl_remove(struct platform_device *pdev) -{ -	struct backlight_device *bd = platform_get_drvdata(pdev); - -	backlight_device_unregister(bd); - -	return 0; -} -  static struct platform_driver jornada_bl_driver = {  	.probe		= jornada_bl_probe, -	.remove		= jornada_bl_remove,  	.driver	= {  		.name	= "jornada_bl",  	}, diff --git a/drivers/video/backlight/jornada720_lcd.c b/drivers/video/backlight/jornada720_lcd.c index b061413f1a6..da3876c9b3a 100644 --- a/drivers/video/backlight/jornada720_lcd.c +++ b/drivers/video/backlight/jornada720_lcd.c @@ -100,7 +100,8 @@ static int jornada_lcd_probe(struct platform_device *pdev)  	struct lcd_device *lcd_device;  	int ret; -	lcd_device = lcd_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_lcd_props); +	lcd_device = devm_lcd_device_register(&pdev->dev, S1D_DEVICENAME, +					&pdev->dev, NULL, &jornada_lcd_props);  	if (IS_ERR(lcd_device)) {  		ret = PTR_ERR(lcd_device); @@ -119,18 +120,8 @@ static int jornada_lcd_probe(struct platform_device *pdev)  	return 0;  } -static int jornada_lcd_remove(struct platform_device *pdev) -{ -	struct lcd_device *lcd_device = platform_get_drvdata(pdev); - -	lcd_device_unregister(lcd_device); - -	return 0; -} -  static struct platform_driver jornada_lcd_driver = {  	.probe	= jornada_lcd_probe, -	.remove	= jornada_lcd_remove,  	.driver	= {  		.name	= "jornada_lcd",  	}, diff --git a/drivers/video/backlight/kb3886_bl.c b/drivers/video/backlight/kb3886_bl.c index bca6ccc74df..84a110a719c 100644 --- a/drivers/video/backlight/kb3886_bl.c +++ b/drivers/video/backlight/kb3886_bl.c @@ -78,7 +78,7 @@ static struct kb3886bl_machinfo *bl_machinfo;  static unsigned long kb3886bl_flags;  #define KB3886BL_SUSPENDED     0x01 -static struct dmi_system_id __initdata kb3886bl_device_table[] = { +static struct dmi_system_id kb3886bl_device_table[] __initdata = {  	{  		.ident = "Sahara Touch-iT",  		.matches = { @@ -141,7 +141,7 @@ static const struct backlight_ops kb3886bl_ops = {  static int kb3886bl_probe(struct platform_device *pdev)  {  	struct backlight_properties props; -	struct kb3886bl_machinfo *machinfo = pdev->dev.platform_data; +	struct kb3886bl_machinfo *machinfo = dev_get_platdata(&pdev->dev);  	bl_machinfo = machinfo;  	if (!machinfo->limit_mask) @@ -150,10 +150,10 @@ static int kb3886bl_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = machinfo->max_intensity; -	kb3886_backlight_device = backlight_device_register("kb3886-bl", -							    &pdev->dev, NULL, -							    &kb3886bl_ops, -							    &props); +	kb3886_backlight_device = devm_backlight_device_register(&pdev->dev, +							"kb3886-bl", &pdev->dev, +							NULL, &kb3886bl_ops, +							&props);  	if (IS_ERR(kb3886_backlight_device))  		return PTR_ERR(kb3886_backlight_device); @@ -166,18 +166,8 @@ static int kb3886bl_probe(struct platform_device *pdev)  	return 0;  } -static int kb3886bl_remove(struct platform_device *pdev) -{ -	struct backlight_device *bd = platform_get_drvdata(pdev); - -	backlight_device_unregister(bd); - -	return 0; -} -  static struct platform_driver kb3886bl_driver = {  	.probe		= kb3886bl_probe, -	.remove		= kb3886bl_remove,  	.driver		= {  		.name	= "kb3886-bl",  		.pm	= &kb3886bl_pm_ops, diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c index a35a38c709c..5fa2649c963 100644 --- a/drivers/video/backlight/l4f00242t03.c +++ b/drivers/video/backlight/l4f00242t03.c @@ -48,7 +48,7 @@ static void l4f00242t03_reset(unsigned int gpio)  static void l4f00242t03_lcd_init(struct spi_device *spi)  { -	struct l4f00242t03_pdata *pdata = spi->dev.platform_data; +	struct l4f00242t03_pdata *pdata = dev_get_platdata(&spi->dev);  	struct l4f00242t03_priv *priv = spi_get_drvdata(spi);  	const u16 cmd[] = { 0x36, param(0), 0x3A, param(0x60) };  	int ret; @@ -88,7 +88,7 @@ static void l4f00242t03_lcd_init(struct spi_device *spi)  static void l4f00242t03_lcd_powerdown(struct spi_device *spi)  { -	struct l4f00242t03_pdata *pdata = spi->dev.platform_data; +	struct l4f00242t03_pdata *pdata = dev_get_platdata(&spi->dev);  	struct l4f00242t03_priv *priv = spi_get_drvdata(spi);  	dev_dbg(&spi->dev, "Powering down LCD\n"); @@ -171,7 +171,7 @@ static struct lcd_ops l4f_ops = {  static int l4f00242t03_probe(struct spi_device *spi)  {  	struct l4f00242t03_priv *priv; -	struct l4f00242t03_pdata *pdata = spi->dev.platform_data; +	struct l4f00242t03_pdata *pdata = dev_get_platdata(&spi->dev);  	int ret;  	if (pdata == NULL) { @@ -181,11 +181,8 @@ static int l4f00242t03_probe(struct spi_device *spi)  	priv = devm_kzalloc(&spi->dev, sizeof(struct l4f00242t03_priv),  				GFP_KERNEL); - -	if (priv == NULL) { -		dev_err(&spi->dev, "No memory for this device.\n"); +	if (priv == NULL)  		return -ENOMEM; -	}  	spi_set_drvdata(spi, priv);  	spi->bits_per_word = 9; @@ -223,8 +220,8 @@ static int l4f00242t03_probe(struct spi_device *spi)  		return PTR_ERR(priv->core_reg);  	} -	priv->ld = lcd_device_register("l4f00242t03", -					&spi->dev, priv, &l4f_ops); +	priv->ld = devm_lcd_device_register(&spi->dev, "l4f00242t03", &spi->dev, +					priv, &l4f_ops);  	if (IS_ERR(priv->ld))  		return PTR_ERR(priv->ld); @@ -243,9 +240,6 @@ static int l4f00242t03_remove(struct spi_device *spi)  	struct l4f00242t03_priv *priv = spi_get_drvdata(spi);  	l4f00242t03_lcd_power_set(priv->ld, FB_BLANK_POWERDOWN); -	lcd_device_unregister(priv->ld); -	spi_set_drvdata(spi, NULL); -  	return 0;  } diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 93cf15efc71..7de847df224 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c @@ -228,7 +228,7 @@ struct lcd_device *lcd_device_register(const char *name, struct device *parent,  	rc = device_register(&new_ld->dev);  	if (rc) { -		kfree(new_ld); +		put_device(&new_ld->dev);  		return ERR_PTR(rc);  	} diff --git a/drivers/video/backlight/ld9040.c b/drivers/video/backlight/ld9040.c index 1e0a3093ce5..506a6c23603 100644 --- a/drivers/video/backlight/ld9040.c +++ b/drivers/video/backlight/ld9040.c @@ -702,7 +702,7 @@ static int ld9040_probe(struct spi_device *spi)  	lcd->spi = spi;  	lcd->dev = &spi->dev; -	lcd->lcd_pd = spi->dev.platform_data; +	lcd->lcd_pd = dev_get_platdata(&spi->dev);  	if (!lcd->lcd_pd) {  		dev_err(&spi->dev, "platform data is NULL.\n");  		return -EINVAL; @@ -716,7 +716,8 @@ static int ld9040_probe(struct spi_device *spi)  		return ret;  	} -	ld = lcd_device_register("ld9040", &spi->dev, lcd, &ld9040_lcd_ops); +	ld = devm_lcd_device_register(&spi->dev, "ld9040", &spi->dev, lcd, +					&ld9040_lcd_ops);  	if (IS_ERR(ld))  		return PTR_ERR(ld); @@ -726,12 +727,10 @@ static int ld9040_probe(struct spi_device *spi)  	props.type = BACKLIGHT_RAW;  	props.max_brightness = MAX_BRIGHTNESS; -	bd = backlight_device_register("ld9040-bl", &spi->dev, -		lcd, &ld9040_backlight_ops, &props); -	if (IS_ERR(bd)) { -		ret = PTR_ERR(bd); -		goto out_unregister_lcd; -	} +	bd = devm_backlight_device_register(&spi->dev, "ld9040-bl", &spi->dev, +					lcd, &ld9040_backlight_ops, &props); +	if (IS_ERR(bd)) +		return PTR_ERR(bd);  	bd->props.brightness = MAX_BRIGHTNESS;  	lcd->bd = bd; @@ -757,11 +756,6 @@ static int ld9040_probe(struct spi_device *spi)  	dev_info(&spi->dev, "ld9040 panel driver has been probed.\n");  	return 0; - -out_unregister_lcd: -	lcd_device_unregister(lcd->ld); - -	return ret;  }  static int ld9040_remove(struct spi_device *spi) @@ -769,9 +763,6 @@ static int ld9040_remove(struct spi_device *spi)  	struct ld9040 *lcd = spi_get_drvdata(spi);  	ld9040_power(lcd, FB_BLANK_POWERDOWN); -	backlight_device_unregister(lcd->bd); -	lcd_device_unregister(lcd->ld); -  	return 0;  } diff --git a/drivers/video/backlight/ld9040_gamma.h b/drivers/video/backlight/ld9040_gamma.h index 038d9c86ec0..c5e586d9738 100644 --- a/drivers/video/backlight/ld9040_gamma.h +++ b/drivers/video/backlight/ld9040_gamma.h @@ -169,7 +169,9 @@ static const unsigned int ld9040_22_50[] = {  struct ld9040_gamma {  	unsigned int *gamma_22_table[MAX_GAMMA_LEVEL]; -} gamma_table = { +}; + +static struct ld9040_gamma gamma_table = {  	.gamma_22_table[0] = (unsigned int *)&ld9040_22_50,  	.gamma_22_table[1] = (unsigned int *)&ld9040_22_70,  	.gamma_22_table[2] = (unsigned int *)&ld9040_22_80, diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c index 1d1dbfb789e..cff1fbe89a1 100644 --- a/drivers/video/backlight/lm3533_bl.c +++ b/drivers/video/backlight/lm3533_bl.c @@ -284,7 +284,7 @@ static int lm3533_bl_probe(struct platform_device *pdev)  	if (!lm3533)  		return -EINVAL; -	pdata = pdev->dev.platform_data; +	pdata = dev_get_platdata(&pdev->dev);  	if (!pdata) {  		dev_err(&pdev->dev, "no platform data\n");  		return -EINVAL; @@ -296,11 +296,8 @@ static int lm3533_bl_probe(struct platform_device *pdev)  	}  	bl = devm_kzalloc(&pdev->dev, sizeof(*bl), GFP_KERNEL); -	if (!bl) { -		dev_err(&pdev->dev, -				"failed to allocate memory for backlight\n"); +	if (!bl)  		return -ENOMEM; -	}  	bl->lm3533 = lm3533;  	bl->id = pdev->id; @@ -313,8 +310,9 @@ static int lm3533_bl_probe(struct platform_device *pdev)  	props.type = BACKLIGHT_RAW;  	props.max_brightness = LM3533_BL_MAX_BRIGHTNESS;  	props.brightness = pdata->default_brightness; -	bd = backlight_device_register(pdata->name, pdev->dev.parent, bl, -						&lm3533_bl_ops, &props); +	bd = devm_backlight_device_register(&pdev->dev, pdata->name, +					pdev->dev.parent, bl, &lm3533_bl_ops, +					&props);  	if (IS_ERR(bd)) {  		dev_err(&pdev->dev, "failed to register backlight device\n");  		return PTR_ERR(bd); @@ -328,7 +326,7 @@ static int lm3533_bl_probe(struct platform_device *pdev)  	ret = sysfs_create_group(&bd->dev.kobj, &lm3533_bl_attribute_group);  	if (ret < 0) {  		dev_err(&pdev->dev, "failed to create sysfs attributes\n"); -		goto err_unregister; +		return ret;  	}  	backlight_update_status(bd); @@ -345,8 +343,6 @@ static int lm3533_bl_probe(struct platform_device *pdev)  err_sysfs_remove:  	sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group); -err_unregister: -	backlight_device_unregister(bd);  	return ret;  } @@ -363,7 +359,6 @@ static int lm3533_bl_remove(struct platform_device *pdev)  	lm3533_ctrlbank_disable(&bl->cb);  	sysfs_remove_group(&bd->dev.kobj, &lm3533_bl_attribute_group); -	backlight_device_unregister(bd);  	return 0;  } diff --git a/drivers/video/backlight/lm3630_bl.c b/drivers/video/backlight/lm3630_bl.c deleted file mode 100644 index 76a62e978fc..00000000000 --- a/drivers/video/backlight/lm3630_bl.c +++ /dev/null @@ -1,475 +0,0 @@ -/* -* Simple driver for Texas Instruments LM3630 Backlight driver chip -* Copyright (C) 2012 Texas Instruments -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License version 2 as -* published by the Free Software Foundation. -* -*/ -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/i2c.h> -#include <linux/backlight.h> -#include <linux/err.h> -#include <linux/delay.h> -#include <linux/uaccess.h> -#include <linux/interrupt.h> -#include <linux/regmap.h> -#include <linux/platform_data/lm3630_bl.h> - -#define REG_CTRL	0x00 -#define REG_CONFIG	0x01 -#define REG_BRT_A	0x03 -#define REG_BRT_B	0x04 -#define REG_INT_STATUS	0x09 -#define REG_INT_EN	0x0A -#define REG_FAULT	0x0B -#define REG_PWM_OUTLOW	0x12 -#define REG_PWM_OUTHIGH	0x13 -#define REG_MAX		0x1F - -#define INT_DEBOUNCE_MSEC	10 - -enum lm3630_leds { -	BLED_ALL = 0, -	BLED_1, -	BLED_2 -}; - -static const char * const bled_name[] = { -	[BLED_ALL] = "lm3630_bled",	/*Bank1 controls all string */ -	[BLED_1] = "lm3630_bled1",	/*Bank1 controls bled1 */ -	[BLED_2] = "lm3630_bled2",	/*Bank1 or 2 controls bled2 */ -}; - -struct lm3630_chip_data { -	struct device *dev; -	struct delayed_work work; -	int irq; -	struct workqueue_struct *irqthread; -	struct lm3630_platform_data *pdata; -	struct backlight_device *bled1; -	struct backlight_device *bled2; -	struct regmap *regmap; -}; - -/* initialize chip */ -static int lm3630_chip_init(struct lm3630_chip_data *pchip) -{ -	int ret; -	unsigned int reg_val; -	struct lm3630_platform_data *pdata = pchip->pdata; - -	/*pwm control */ -	reg_val = ((pdata->pwm_active & 0x01) << 2) | (pdata->pwm_ctrl & 0x03); -	ret = regmap_update_bits(pchip->regmap, REG_CONFIG, 0x07, reg_val); -	if (ret < 0) -		goto out; - -	/* bank control */ -	reg_val = ((pdata->bank_b_ctrl & 0x01) << 1) | -			(pdata->bank_a_ctrl & 0x07); -	ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x07, reg_val); -	if (ret < 0) -		goto out; - -	ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); -	if (ret < 0) -		goto out; - -	/* set initial brightness */ -	if (pdata->bank_a_ctrl != BANK_A_CTRL_DISABLE) { -		ret = regmap_write(pchip->regmap, -				   REG_BRT_A, pdata->init_brt_led1); -		if (ret < 0) -			goto out; -	} - -	if (pdata->bank_b_ctrl != BANK_B_CTRL_DISABLE) { -		ret = regmap_write(pchip->regmap, -				   REG_BRT_B, pdata->init_brt_led2); -		if (ret < 0) -			goto out; -	} -	return ret; - -out: -	dev_err(pchip->dev, "i2c failed to access register\n"); -	return ret; -} - -/* interrupt handling */ -static void lm3630_delayed_func(struct work_struct *work) -{ -	int ret; -	unsigned int reg_val; -	struct lm3630_chip_data *pchip; - -	pchip = container_of(work, struct lm3630_chip_data, work.work); - -	ret = regmap_read(pchip->regmap, REG_INT_STATUS, ®_val); -	if (ret < 0) { -		dev_err(pchip->dev, -			"i2c failed to access REG_INT_STATUS Register\n"); -		return; -	} - -	dev_info(pchip->dev, "REG_INT_STATUS Register is 0x%x\n", reg_val); -} - -static irqreturn_t lm3630_isr_func(int irq, void *chip) -{ -	int ret; -	struct lm3630_chip_data *pchip = chip; -	unsigned long delay = msecs_to_jiffies(INT_DEBOUNCE_MSEC); - -	queue_delayed_work(pchip->irqthread, &pchip->work, delay); - -	ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); -	if (ret < 0) -		goto out; - -	return IRQ_HANDLED; -out: -	dev_err(pchip->dev, "i2c failed to access register\n"); -	return IRQ_HANDLED; -} - -static int lm3630_intr_config(struct lm3630_chip_data *pchip) -{ -	INIT_DELAYED_WORK(&pchip->work, lm3630_delayed_func); -	pchip->irqthread = create_singlethread_workqueue("lm3630-irqthd"); -	if (!pchip->irqthread) { -		dev_err(pchip->dev, "create irq thread fail...\n"); -		return -1; -	} -	if (request_threaded_irq -	    (pchip->irq, NULL, lm3630_isr_func, -	     IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "lm3630_irq", pchip)) { -		dev_err(pchip->dev, "request threaded irq fail..\n"); -		return -1; -	} -	return 0; -} - -static bool -set_intensity(struct backlight_device *bl, struct lm3630_chip_data *pchip) -{ -	if (!pchip->pdata->pwm_set_intensity) -		return false; -	pchip->pdata->pwm_set_intensity(bl->props.brightness - 1, -					pchip->pdata->pwm_period); -	return true; -} - -/* update and get brightness */ -static int lm3630_bank_a_update_status(struct backlight_device *bl) -{ -	int ret; -	struct lm3630_chip_data *pchip = bl_get_data(bl); -	enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; - -	/* brightness 0 means disable */ -	if (!bl->props.brightness) { -		ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x04, 0x00); -		if (ret < 0) -			goto out; -		return bl->props.brightness; -	} - -	/* pwm control */ -	if (pwm_ctrl == PWM_CTRL_BANK_A || pwm_ctrl == PWM_CTRL_BANK_ALL) { -		if (!set_intensity(bl, pchip)) -			dev_err(pchip->dev, "No pwm control func. in plat-data\n"); -	} else { - -		/* i2c control */ -		ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); -		if (ret < 0) -			goto out; -		mdelay(1); -		ret = regmap_write(pchip->regmap, -				   REG_BRT_A, bl->props.brightness - 1); -		if (ret < 0) -			goto out; -	} -	return bl->props.brightness; -out: -	dev_err(pchip->dev, "i2c failed to access REG_CTRL\n"); -	return bl->props.brightness; -} - -static int lm3630_bank_a_get_brightness(struct backlight_device *bl) -{ -	unsigned int reg_val; -	int brightness, ret; -	struct lm3630_chip_data *pchip = bl_get_data(bl); -	enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; - -	if (pwm_ctrl == PWM_CTRL_BANK_A || pwm_ctrl == PWM_CTRL_BANK_ALL) { -		ret = regmap_read(pchip->regmap, REG_PWM_OUTHIGH, ®_val); -		if (ret < 0) -			goto out; -		brightness = reg_val & 0x01; -		ret = regmap_read(pchip->regmap, REG_PWM_OUTLOW, ®_val); -		if (ret < 0) -			goto out; -		brightness = ((brightness << 8) | reg_val) + 1; -	} else { -		ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); -		if (ret < 0) -			goto out; -		mdelay(1); -		ret = regmap_read(pchip->regmap, REG_BRT_A, ®_val); -		if (ret < 0) -			goto out; -		brightness = reg_val + 1; -	} -	bl->props.brightness = brightness; -	return bl->props.brightness; -out: -	dev_err(pchip->dev, "i2c failed to access register\n"); -	return 0; -} - -static const struct backlight_ops lm3630_bank_a_ops = { -	.options = BL_CORE_SUSPENDRESUME, -	.update_status = lm3630_bank_a_update_status, -	.get_brightness = lm3630_bank_a_get_brightness, -}; - -static int lm3630_bank_b_update_status(struct backlight_device *bl) -{ -	int ret; -	struct lm3630_chip_data *pchip = bl_get_data(bl); -	enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; - -	if (pwm_ctrl == PWM_CTRL_BANK_B || pwm_ctrl == PWM_CTRL_BANK_ALL) { -		if (!set_intensity(bl, pchip)) -			dev_err(pchip->dev, -				"no pwm control func. in plat-data\n"); -	} else { -		ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); -		if (ret < 0) -			goto out; -		mdelay(1); -		ret = regmap_write(pchip->regmap, -				   REG_BRT_B, bl->props.brightness - 1); -	} -	return bl->props.brightness; -out: -	dev_err(pchip->dev, "i2c failed to access register\n"); -	return bl->props.brightness; -} - -static int lm3630_bank_b_get_brightness(struct backlight_device *bl) -{ -	unsigned int reg_val; -	int brightness, ret; -	struct lm3630_chip_data *pchip = bl_get_data(bl); -	enum lm3630_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; - -	if (pwm_ctrl == PWM_CTRL_BANK_B || pwm_ctrl == PWM_CTRL_BANK_ALL) { -		ret = regmap_read(pchip->regmap, REG_PWM_OUTHIGH, ®_val); -		if (ret < 0) -			goto out; -		brightness = reg_val & 0x01; -		ret = regmap_read(pchip->regmap, REG_PWM_OUTLOW, ®_val); -		if (ret < 0) -			goto out; -		brightness = ((brightness << 8) | reg_val) + 1; -	} else { -		ret = regmap_update_bits(pchip->regmap, REG_CTRL, 0x80, 0x00); -		if (ret < 0) -			goto out; -		mdelay(1); -		ret = regmap_read(pchip->regmap, REG_BRT_B, ®_val); -		if (ret < 0) -			goto out; -		brightness = reg_val + 1; -	} -	bl->props.brightness = brightness; - -	return bl->props.brightness; -out: -	dev_err(pchip->dev, "i2c failed to access register\n"); -	return bl->props.brightness; -} - -static const struct backlight_ops lm3630_bank_b_ops = { -	.options = BL_CORE_SUSPENDRESUME, -	.update_status = lm3630_bank_b_update_status, -	.get_brightness = lm3630_bank_b_get_brightness, -}; - -static int lm3630_backlight_register(struct lm3630_chip_data *pchip, -				     enum lm3630_leds ledno) -{ -	const char *name = bled_name[ledno]; -	struct backlight_properties props; -	struct lm3630_platform_data *pdata = pchip->pdata; - -	props.type = BACKLIGHT_RAW; -	switch (ledno) { -	case BLED_1: -	case BLED_ALL: -		props.brightness = pdata->init_brt_led1; -		props.max_brightness = pdata->max_brt_led1; -		pchip->bled1 = -		    backlight_device_register(name, pchip->dev, pchip, -					      &lm3630_bank_a_ops, &props); -		if (IS_ERR(pchip->bled1)) -			return PTR_ERR(pchip->bled1); -		break; -	case BLED_2: -		props.brightness = pdata->init_brt_led2; -		props.max_brightness = pdata->max_brt_led2; -		pchip->bled2 = -		    backlight_device_register(name, pchip->dev, pchip, -					      &lm3630_bank_b_ops, &props); -		if (IS_ERR(pchip->bled2)) -			return PTR_ERR(pchip->bled2); -		break; -	} -	return 0; -} - -static void lm3630_backlight_unregister(struct lm3630_chip_data *pchip) -{ -	if (pchip->bled1) -		backlight_device_unregister(pchip->bled1); -	if (pchip->bled2) -		backlight_device_unregister(pchip->bled2); -} - -static const struct regmap_config lm3630_regmap = { -	.reg_bits = 8, -	.val_bits = 8, -	.max_register = REG_MAX, -}; - -static int lm3630_probe(struct i2c_client *client, -				  const struct i2c_device_id *id) -{ -	struct lm3630_platform_data *pdata = client->dev.platform_data; -	struct lm3630_chip_data *pchip; -	int ret; - -	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { -		dev_err(&client->dev, "fail : i2c functionality check...\n"); -		return -EOPNOTSUPP; -	} - -	if (pdata == NULL) { -		dev_err(&client->dev, "fail : no platform data.\n"); -		return -ENODATA; -	} - -	pchip = devm_kzalloc(&client->dev, sizeof(struct lm3630_chip_data), -			     GFP_KERNEL); -	if (!pchip) -		return -ENOMEM; -	pchip->pdata = pdata; -	pchip->dev = &client->dev; - -	pchip->regmap = devm_regmap_init_i2c(client, &lm3630_regmap); -	if (IS_ERR(pchip->regmap)) { -		ret = PTR_ERR(pchip->regmap); -		dev_err(&client->dev, "fail : allocate register map: %d\n", -			ret); -		return ret; -	} -	i2c_set_clientdata(client, pchip); - -	/* chip initialize */ -	ret = lm3630_chip_init(pchip); -	if (ret < 0) { -		dev_err(&client->dev, "fail : init chip\n"); -		goto err_chip_init; -	} - -	switch (pdata->bank_a_ctrl) { -	case BANK_A_CTRL_ALL: -		ret = lm3630_backlight_register(pchip, BLED_ALL); -		pdata->bank_b_ctrl = BANK_B_CTRL_DISABLE; -		break; -	case BANK_A_CTRL_LED1: -		ret = lm3630_backlight_register(pchip, BLED_1); -		break; -	case BANK_A_CTRL_LED2: -		ret = lm3630_backlight_register(pchip, BLED_2); -		pdata->bank_b_ctrl = BANK_B_CTRL_DISABLE; -		break; -	default: -		break; -	} - -	if (ret < 0) -		goto err_bl_reg; - -	if (pdata->bank_b_ctrl && pchip->bled2 == NULL) { -		ret = lm3630_backlight_register(pchip, BLED_2); -		if (ret < 0) -			goto err_bl_reg; -	} - -	/* interrupt enable  : irq 0 is not allowed for lm3630 */ -	pchip->irq = client->irq; -	if (pchip->irq) -		lm3630_intr_config(pchip); - -	dev_info(&client->dev, "LM3630 backlight register OK.\n"); -	return 0; - -err_bl_reg: -	dev_err(&client->dev, "fail : backlight register.\n"); -	lm3630_backlight_unregister(pchip); -err_chip_init: -	return ret; -} - -static int lm3630_remove(struct i2c_client *client) -{ -	int ret; -	struct lm3630_chip_data *pchip = i2c_get_clientdata(client); - -	ret = regmap_write(pchip->regmap, REG_BRT_A, 0); -	if (ret < 0) -		dev_err(pchip->dev, "i2c failed to access register\n"); - -	ret = regmap_write(pchip->regmap, REG_BRT_B, 0); -	if (ret < 0) -		dev_err(pchip->dev, "i2c failed to access register\n"); - -	lm3630_backlight_unregister(pchip); -	if (pchip->irq) { -		free_irq(pchip->irq, pchip); -		flush_workqueue(pchip->irqthread); -		destroy_workqueue(pchip->irqthread); -	} -	return 0; -} - -static const struct i2c_device_id lm3630_id[] = { -	{LM3630_NAME, 0}, -	{} -}; - -MODULE_DEVICE_TABLE(i2c, lm3630_id); - -static struct i2c_driver lm3630_i2c_driver = { -	.driver = { -		   .name = LM3630_NAME, -		   }, -	.probe = lm3630_probe, -	.remove = lm3630_remove, -	.id_table = lm3630_id, -}; - -module_i2c_driver(lm3630_i2c_driver); - -MODULE_DESCRIPTION("Texas Instruments Backlight driver for LM3630"); -MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>"); -MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/video/backlight/lm3630a_bl.c b/drivers/video/backlight/lm3630a_bl.c new file mode 100644 index 00000000000..35fe4825a45 --- /dev/null +++ b/drivers/video/backlight/lm3630a_bl.c @@ -0,0 +1,483 @@ +/* +* Simple driver for Texas Instruments LM3630A Backlight driver chip +* Copyright (C) 2012 Texas Instruments +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +*/ +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/i2c.h> +#include <linux/backlight.h> +#include <linux/err.h> +#include <linux/delay.h> +#include <linux/uaccess.h> +#include <linux/interrupt.h> +#include <linux/regmap.h> +#include <linux/pwm.h> +#include <linux/platform_data/lm3630a_bl.h> + +#define REG_CTRL	0x00 +#define REG_BOOST	0x02 +#define REG_CONFIG	0x01 +#define REG_BRT_A	0x03 +#define REG_BRT_B	0x04 +#define REG_I_A		0x05 +#define REG_I_B		0x06 +#define REG_INT_STATUS	0x09 +#define REG_INT_EN	0x0A +#define REG_FAULT	0x0B +#define REG_PWM_OUTLOW	0x12 +#define REG_PWM_OUTHIGH	0x13 +#define REG_MAX		0x1F + +#define INT_DEBOUNCE_MSEC	10 +struct lm3630a_chip { +	struct device *dev; +	struct delayed_work work; + +	int irq; +	struct workqueue_struct *irqthread; +	struct lm3630a_platform_data *pdata; +	struct backlight_device *bleda; +	struct backlight_device *bledb; +	struct regmap *regmap; +	struct pwm_device *pwmd; +}; + +/* i2c access */ +static int lm3630a_read(struct lm3630a_chip *pchip, unsigned int reg) +{ +	int rval; +	unsigned int reg_val; + +	rval = regmap_read(pchip->regmap, reg, ®_val); +	if (rval < 0) +		return rval; +	return reg_val & 0xFF; +} + +static int lm3630a_write(struct lm3630a_chip *pchip, +			 unsigned int reg, unsigned int data) +{ +	return regmap_write(pchip->regmap, reg, data); +} + +static int lm3630a_update(struct lm3630a_chip *pchip, +			  unsigned int reg, unsigned int mask, +			  unsigned int data) +{ +	return regmap_update_bits(pchip->regmap, reg, mask, data); +} + +/* initialize chip */ +static int lm3630a_chip_init(struct lm3630a_chip *pchip) +{ +	int rval; +	struct lm3630a_platform_data *pdata = pchip->pdata; + +	usleep_range(1000, 2000); +	/* set Filter Strength Register */ +	rval = lm3630a_write(pchip, 0x50, 0x03); +	/* set Cofig. register */ +	rval |= lm3630a_update(pchip, REG_CONFIG, 0x07, pdata->pwm_ctrl); +	/* set boost control */ +	rval |= lm3630a_write(pchip, REG_BOOST, 0x38); +	/* set current A */ +	rval |= lm3630a_update(pchip, REG_I_A, 0x1F, 0x1F); +	/* set current B */ +	rval |= lm3630a_write(pchip, REG_I_B, 0x1F); +	/* set control */ +	rval |= lm3630a_update(pchip, REG_CTRL, 0x14, pdata->leda_ctrl); +	rval |= lm3630a_update(pchip, REG_CTRL, 0x0B, pdata->ledb_ctrl); +	usleep_range(1000, 2000); +	/* set brightness A and B */ +	rval |= lm3630a_write(pchip, REG_BRT_A, pdata->leda_init_brt); +	rval |= lm3630a_write(pchip, REG_BRT_B, pdata->ledb_init_brt); + +	if (rval < 0) +		dev_err(pchip->dev, "i2c failed to access register\n"); +	return rval; +} + +/* interrupt handling */ +static void lm3630a_delayed_func(struct work_struct *work) +{ +	int rval; +	struct lm3630a_chip *pchip; + +	pchip = container_of(work, struct lm3630a_chip, work.work); + +	rval = lm3630a_read(pchip, REG_INT_STATUS); +	if (rval < 0) { +		dev_err(pchip->dev, +			"i2c failed to access REG_INT_STATUS Register\n"); +		return; +	} + +	dev_info(pchip->dev, "REG_INT_STATUS Register is 0x%x\n", rval); +} + +static irqreturn_t lm3630a_isr_func(int irq, void *chip) +{ +	int rval; +	struct lm3630a_chip *pchip = chip; +	unsigned long delay = msecs_to_jiffies(INT_DEBOUNCE_MSEC); + +	queue_delayed_work(pchip->irqthread, &pchip->work, delay); + +	rval = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); +	if (rval < 0) { +		dev_err(pchip->dev, "i2c failed to access register\n"); +		return IRQ_NONE; +	} +	return IRQ_HANDLED; +} + +static int lm3630a_intr_config(struct lm3630a_chip *pchip) +{ +	int rval; + +	rval = lm3630a_write(pchip, REG_INT_EN, 0x87); +	if (rval < 0) +		return rval; + +	INIT_DELAYED_WORK(&pchip->work, lm3630a_delayed_func); +	pchip->irqthread = create_singlethread_workqueue("lm3630a-irqthd"); +	if (!pchip->irqthread) { +		dev_err(pchip->dev, "create irq thread fail\n"); +		return -ENOMEM; +	} +	if (request_threaded_irq +	    (pchip->irq, NULL, lm3630a_isr_func, +	     IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "lm3630a_irq", pchip)) { +		dev_err(pchip->dev, "request threaded irq fail\n"); +		destroy_workqueue(pchip->irqthread); +		return -ENOMEM; +	} +	return rval; +} + +static void lm3630a_pwm_ctrl(struct lm3630a_chip *pchip, int br, int br_max) +{ +	unsigned int period = pwm_get_period(pchip->pwmd); +	unsigned int duty = br * period / br_max; + +	pwm_config(pchip->pwmd, duty, period); +	if (duty) +		pwm_enable(pchip->pwmd); +	else +		pwm_disable(pchip->pwmd); +} + +/* update and get brightness */ +static int lm3630a_bank_a_update_status(struct backlight_device *bl) +{ +	int ret; +	struct lm3630a_chip *pchip = bl_get_data(bl); +	enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; + +	/* pwm control */ +	if ((pwm_ctrl & LM3630A_PWM_BANK_A) != 0) { +		lm3630a_pwm_ctrl(pchip, bl->props.brightness, +				 bl->props.max_brightness); +		return bl->props.brightness; +	} + +	/* disable sleep */ +	ret = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); +	if (ret < 0) +		goto out_i2c_err; +	usleep_range(1000, 2000); +	/* minimum brightness is 0x04 */ +	ret = lm3630a_write(pchip, REG_BRT_A, bl->props.brightness); +	if (bl->props.brightness < 0x4) +		ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDA_ENABLE, 0); +	else +		ret |= lm3630a_update(pchip, REG_CTRL, +				      LM3630A_LEDA_ENABLE, LM3630A_LEDA_ENABLE); +	if (ret < 0) +		goto out_i2c_err; +	return bl->props.brightness; + +out_i2c_err: +	dev_err(pchip->dev, "i2c failed to access\n"); +	return bl->props.brightness; +} + +static int lm3630a_bank_a_get_brightness(struct backlight_device *bl) +{ +	int brightness, rval; +	struct lm3630a_chip *pchip = bl_get_data(bl); +	enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; + +	if ((pwm_ctrl & LM3630A_PWM_BANK_A) != 0) { +		rval = lm3630a_read(pchip, REG_PWM_OUTHIGH); +		if (rval < 0) +			goto out_i2c_err; +		brightness = (rval & 0x01) << 8; +		rval = lm3630a_read(pchip, REG_PWM_OUTLOW); +		if (rval < 0) +			goto out_i2c_err; +		brightness |= rval; +		goto out; +	} + +	/* disable sleep */ +	rval = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); +	if (rval < 0) +		goto out_i2c_err; +	usleep_range(1000, 2000); +	rval = lm3630a_read(pchip, REG_BRT_A); +	if (rval < 0) +		goto out_i2c_err; +	brightness = rval; + +out: +	bl->props.brightness = brightness; +	return bl->props.brightness; +out_i2c_err: +	dev_err(pchip->dev, "i2c failed to access register\n"); +	return 0; +} + +static const struct backlight_ops lm3630a_bank_a_ops = { +	.options = BL_CORE_SUSPENDRESUME, +	.update_status = lm3630a_bank_a_update_status, +	.get_brightness = lm3630a_bank_a_get_brightness, +}; + +/* update and get brightness */ +static int lm3630a_bank_b_update_status(struct backlight_device *bl) +{ +	int ret; +	struct lm3630a_chip *pchip = bl_get_data(bl); +	enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; + +	/* pwm control */ +	if ((pwm_ctrl & LM3630A_PWM_BANK_B) != 0) { +		lm3630a_pwm_ctrl(pchip, bl->props.brightness, +				 bl->props.max_brightness); +		return bl->props.brightness; +	} + +	/* disable sleep */ +	ret = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); +	if (ret < 0) +		goto out_i2c_err; +	usleep_range(1000, 2000); +	/* minimum brightness is 0x04 */ +	ret = lm3630a_write(pchip, REG_BRT_B, bl->props.brightness); +	if (bl->props.brightness < 0x4) +		ret |= lm3630a_update(pchip, REG_CTRL, LM3630A_LEDB_ENABLE, 0); +	else +		ret |= lm3630a_update(pchip, REG_CTRL, +				      LM3630A_LEDB_ENABLE, LM3630A_LEDB_ENABLE); +	if (ret < 0) +		goto out_i2c_err; +	return bl->props.brightness; + +out_i2c_err: +	dev_err(pchip->dev, "i2c failed to access REG_CTRL\n"); +	return bl->props.brightness; +} + +static int lm3630a_bank_b_get_brightness(struct backlight_device *bl) +{ +	int brightness, rval; +	struct lm3630a_chip *pchip = bl_get_data(bl); +	enum lm3630a_pwm_ctrl pwm_ctrl = pchip->pdata->pwm_ctrl; + +	if ((pwm_ctrl & LM3630A_PWM_BANK_B) != 0) { +		rval = lm3630a_read(pchip, REG_PWM_OUTHIGH); +		if (rval < 0) +			goto out_i2c_err; +		brightness = (rval & 0x01) << 8; +		rval = lm3630a_read(pchip, REG_PWM_OUTLOW); +		if (rval < 0) +			goto out_i2c_err; +		brightness |= rval; +		goto out; +	} + +	/* disable sleep */ +	rval = lm3630a_update(pchip, REG_CTRL, 0x80, 0x00); +	if (rval < 0) +		goto out_i2c_err; +	usleep_range(1000, 2000); +	rval = lm3630a_read(pchip, REG_BRT_B); +	if (rval < 0) +		goto out_i2c_err; +	brightness = rval; + +out: +	bl->props.brightness = brightness; +	return bl->props.brightness; +out_i2c_err: +	dev_err(pchip->dev, "i2c failed to access register\n"); +	return 0; +} + +static const struct backlight_ops lm3630a_bank_b_ops = { +	.options = BL_CORE_SUSPENDRESUME, +	.update_status = lm3630a_bank_b_update_status, +	.get_brightness = lm3630a_bank_b_get_brightness, +}; + +static int lm3630a_backlight_register(struct lm3630a_chip *pchip) +{ +	struct backlight_properties props; +	struct lm3630a_platform_data *pdata = pchip->pdata; + +	props.type = BACKLIGHT_RAW; +	if (pdata->leda_ctrl != LM3630A_LEDA_DISABLE) { +		props.brightness = pdata->leda_init_brt; +		props.max_brightness = pdata->leda_max_brt; +		pchip->bleda = +		    devm_backlight_device_register(pchip->dev, "lm3630a_leda", +						   pchip->dev, pchip, +						   &lm3630a_bank_a_ops, &props); +		if (IS_ERR(pchip->bleda)) +			return PTR_ERR(pchip->bleda); +	} + +	if ((pdata->ledb_ctrl != LM3630A_LEDB_DISABLE) && +	    (pdata->ledb_ctrl != LM3630A_LEDB_ON_A)) { +		props.brightness = pdata->ledb_init_brt; +		props.max_brightness = pdata->ledb_max_brt; +		pchip->bledb = +		    devm_backlight_device_register(pchip->dev, "lm3630a_ledb", +						   pchip->dev, pchip, +						   &lm3630a_bank_b_ops, &props); +		if (IS_ERR(pchip->bledb)) +			return PTR_ERR(pchip->bledb); +	} +	return 0; +} + +static const struct regmap_config lm3630a_regmap = { +	.reg_bits = 8, +	.val_bits = 8, +	.max_register = REG_MAX, +}; + +static int lm3630a_probe(struct i2c_client *client, +			 const struct i2c_device_id *id) +{ +	struct lm3630a_platform_data *pdata = dev_get_platdata(&client->dev); +	struct lm3630a_chip *pchip; +	int rval; + +	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { +		dev_err(&client->dev, "fail : i2c functionality check\n"); +		return -EOPNOTSUPP; +	} + +	pchip = devm_kzalloc(&client->dev, sizeof(struct lm3630a_chip), +			     GFP_KERNEL); +	if (!pchip) +		return -ENOMEM; +	pchip->dev = &client->dev; + +	pchip->regmap = devm_regmap_init_i2c(client, &lm3630a_regmap); +	if (IS_ERR(pchip->regmap)) { +		rval = PTR_ERR(pchip->regmap); +		dev_err(&client->dev, "fail : allocate reg. map: %d\n", rval); +		return rval; +	} + +	i2c_set_clientdata(client, pchip); +	if (pdata == NULL) { +		pdata = devm_kzalloc(pchip->dev, +				     sizeof(struct lm3630a_platform_data), +				     GFP_KERNEL); +		if (pdata == NULL) +			return -ENOMEM; +		/* default values */ +		pdata->leda_ctrl = LM3630A_LEDA_ENABLE; +		pdata->ledb_ctrl = LM3630A_LEDB_ENABLE; +		pdata->leda_max_brt = LM3630A_MAX_BRIGHTNESS; +		pdata->ledb_max_brt = LM3630A_MAX_BRIGHTNESS; +		pdata->leda_init_brt = LM3630A_MAX_BRIGHTNESS; +		pdata->ledb_init_brt = LM3630A_MAX_BRIGHTNESS; +	} +	pchip->pdata = pdata; + +	/* chip initialize */ +	rval = lm3630a_chip_init(pchip); +	if (rval < 0) { +		dev_err(&client->dev, "fail : init chip\n"); +		return rval; +	} +	/* backlight register */ +	rval = lm3630a_backlight_register(pchip); +	if (rval < 0) { +		dev_err(&client->dev, "fail : backlight register.\n"); +		return rval; +	} +	/* pwm */ +	if (pdata->pwm_ctrl != LM3630A_PWM_DISABLE) { +		pchip->pwmd = devm_pwm_get(pchip->dev, "lm3630a-pwm"); +		if (IS_ERR(pchip->pwmd)) { +			dev_err(&client->dev, "fail : get pwm device\n"); +			return PTR_ERR(pchip->pwmd); +		} +	} +	pchip->pwmd->period = pdata->pwm_period; + +	/* interrupt enable  : irq 0 is not allowed */ +	pchip->irq = client->irq; +	if (pchip->irq) { +		rval = lm3630a_intr_config(pchip); +		if (rval < 0) +			return rval; +	} +	dev_info(&client->dev, "LM3630A backlight register OK.\n"); +	return 0; +} + +static int lm3630a_remove(struct i2c_client *client) +{ +	int rval; +	struct lm3630a_chip *pchip = i2c_get_clientdata(client); + +	rval = lm3630a_write(pchip, REG_BRT_A, 0); +	if (rval < 0) +		dev_err(pchip->dev, "i2c failed to access register\n"); + +	rval = lm3630a_write(pchip, REG_BRT_B, 0); +	if (rval < 0) +		dev_err(pchip->dev, "i2c failed to access register\n"); + +	if (pchip->irq) { +		free_irq(pchip->irq, pchip); +		flush_workqueue(pchip->irqthread); +		destroy_workqueue(pchip->irqthread); +	} +	return 0; +} + +static const struct i2c_device_id lm3630a_id[] = { +	{LM3630A_NAME, 0}, +	{} +}; + +MODULE_DEVICE_TABLE(i2c, lm3630a_id); + +static struct i2c_driver lm3630a_i2c_driver = { +	.driver = { +		   .name = LM3630A_NAME, +		   }, +	.probe = lm3630a_probe, +	.remove = lm3630a_remove, +	.id_table = lm3630a_id, +}; + +module_i2c_driver(lm3630a_i2c_driver); + +MODULE_DESCRIPTION("Texas Instruments Backlight driver for LM3630A"); +MODULE_AUTHOR("Daniel Jeong <gshark.jeong@gmail.com>"); +MODULE_AUTHOR("LDD MLP <ldd-mlp@list.ti.com>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c index 053964da8dd..5f36808d214 100644 --- a/drivers/video/backlight/lm3639_bl.c +++ b/drivers/video/backlight/lm3639_bl.c @@ -76,10 +76,13 @@ static int lm3639_chip_init(struct lm3639_chip_data *pchip)  		goto out;  	/* output pins config. */ -	if (!pdata->init_brt_led) -		reg_val = pdata->fled_pins | pdata->bled_pins; -	else -		reg_val = pdata->fled_pins | pdata->bled_pins | 0x01; +	if (!pdata->init_brt_led) { +		reg_val = pdata->fled_pins; +		reg_val |= pdata->bled_pins; +	} else { +		reg_val = pdata->fled_pins; +		reg_val |= pdata->bled_pins | 0x01; +	}  	ret = regmap_update_bits(pchip->regmap, REG_ENABLE, 0x79, reg_val);  	if (ret < 0) @@ -304,7 +307,7 @@ static int lm3639_probe(struct i2c_client *client,  {  	int ret;  	struct lm3639_chip_data *pchip; -	struct lm3639_platform_data *pdata = client->dev.platform_data; +	struct lm3639_platform_data *pdata = dev_get_platdata(&client->dev);  	struct backlight_properties props;  	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { @@ -346,8 +349,9 @@ static int lm3639_probe(struct i2c_client *client,  	props.brightness = pdata->init_brt_led;  	props.max_brightness = pdata->max_brt_led;  	pchip->bled = -	    backlight_device_register("lm3639_bled", pchip->dev, pchip, -				      &lm3639_bled_ops, &props); +	    devm_backlight_device_register(pchip->dev, "lm3639_bled", +					   pchip->dev, pchip, &lm3639_bled_ops, +					   &props);  	if (IS_ERR(pchip->bled)) {  		dev_err(&client->dev, "fail : backlight register\n");  		ret = PTR_ERR(pchip->bled); @@ -357,7 +361,7 @@ static int lm3639_probe(struct i2c_client *client,  	ret = device_create_file(&(pchip->bled->dev), &dev_attr_bled_mode);  	if (ret < 0) {  		dev_err(&client->dev, "failed : add sysfs entries\n"); -		goto err_bled_mode; +		goto err_out;  	}  	/* flash */ @@ -388,8 +392,6 @@ err_torch:  	led_classdev_unregister(&pchip->cdev_flash);  err_flash:  	device_remove_file(&(pchip->bled->dev), &dev_attr_bled_mode); -err_bled_mode: -	backlight_device_unregister(pchip->bled);  err_out:  	return ret;  } @@ -404,10 +406,8 @@ static int lm3639_remove(struct i2c_client *client)  		led_classdev_unregister(&pchip->cdev_torch);  	if (&pchip->cdev_flash)  		led_classdev_unregister(&pchip->cdev_flash); -	if (pchip->bled) { +	if (pchip->bled)  		device_remove_file(&(pchip->bled->dev), &dev_attr_bled_mode); -		backlight_device_unregister(pchip->bled); -	}  	return 0;  } @@ -429,6 +429,6 @@ static struct i2c_driver lm3639_i2c_driver = {  module_i2c_driver(lm3639_i2c_driver);  MODULE_DESCRIPTION("Texas Instruments Backlight+Flash LED driver for LM3639"); -MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>"); -MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>"); +MODULE_AUTHOR("Daniel Jeong <gshark.jeong@gmail.com>"); +MODULE_AUTHOR("Ldd Mlp <ldd-mlp@list.ti.com>");  MODULE_LICENSE("GPL v2"); diff --git a/drivers/video/backlight/lms283gf05.c b/drivers/video/backlight/lms283gf05.c index 4eec47261cd..14590c54aed 100644 --- a/drivers/video/backlight/lms283gf05.c +++ b/drivers/video/backlight/lms283gf05.c @@ -128,7 +128,7 @@ static int lms283gf05_power_set(struct lcd_device *ld, int power)  {  	struct lms283gf05_state *st = lcd_get_data(ld);  	struct spi_device *spi = st->spi; -	struct lms283gf05_pdata *pdata = spi->dev.platform_data; +	struct lms283gf05_pdata *pdata = dev_get_platdata(&spi->dev);  	if (power <= FB_BLANK_NORMAL) {  		if (pdata) @@ -153,7 +153,7 @@ static struct lcd_ops lms_ops = {  static int lms283gf05_probe(struct spi_device *spi)  {  	struct lms283gf05_state *st; -	struct lms283gf05_pdata *pdata = spi->dev.platform_data; +	struct lms283gf05_pdata *pdata = dev_get_platdata(&spi->dev);  	struct lcd_device *ld;  	int ret = 0; @@ -168,12 +168,11 @@ static int lms283gf05_probe(struct spi_device *spi)  	st = devm_kzalloc(&spi->dev, sizeof(struct lms283gf05_state),  				GFP_KERNEL); -	if (st == NULL) { -		dev_err(&spi->dev, "No memory for device state\n"); +	if (st == NULL)  		return -ENOMEM; -	} -	ld = lcd_device_register("lms283gf05", &spi->dev, st, &lms_ops); +	ld = devm_lcd_device_register(&spi->dev, "lms283gf05", &spi->dev, st, +					&lms_ops);  	if (IS_ERR(ld))  		return PTR_ERR(ld); @@ -190,22 +189,12 @@ static int lms283gf05_probe(struct spi_device *spi)  	return 0;  } -static int lms283gf05_remove(struct spi_device *spi) -{ -	struct lms283gf05_state *st = spi_get_drvdata(spi); - -	lcd_device_unregister(st->ld); - -	return 0; -} -  static struct spi_driver lms283gf05_driver = {  	.driver = {  		.name	= "lms283gf05",  		.owner	= THIS_MODULE,  	},  	.probe		= lms283gf05_probe, -	.remove		= lms283gf05_remove,  };  module_spi_driver(lms283gf05_driver); diff --git a/drivers/video/backlight/lms501kf03.c b/drivers/video/backlight/lms501kf03.c index cf01b9ac813..77258b7b04b 100644 --- a/drivers/video/backlight/lms501kf03.c +++ b/drivers/video/backlight/lms501kf03.c @@ -344,14 +344,14 @@ static int lms501kf03_probe(struct spi_device *spi)  	lcd->spi = spi;  	lcd->dev = &spi->dev; -	lcd->lcd_pd = spi->dev.platform_data; +	lcd->lcd_pd = dev_get_platdata(&spi->dev);  	if (!lcd->lcd_pd) {  		dev_err(&spi->dev, "platform data is NULL\n");  		return -EINVAL;  	} -	ld = lcd_device_register("lms501kf03", &spi->dev, lcd, -				&lms501kf03_lcd_ops); +	ld = devm_lcd_device_register(&spi->dev, "lms501kf03", &spi->dev, lcd, +					&lms501kf03_lcd_ops);  	if (IS_ERR(ld))  		return PTR_ERR(ld); @@ -382,8 +382,6 @@ static int lms501kf03_remove(struct spi_device *spi)  	struct lms501kf03 *lcd = spi_get_drvdata(spi);  	lms501kf03_power(lcd, FB_BLANK_POWERDOWN); -	lcd_device_unregister(lcd->ld); -  	return 0;  } diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c index c0b41f13bd4..2ca3a040007 100644 --- a/drivers/video/backlight/lp855x_bl.c +++ b/drivers/video/backlight/lp855x_bl.c @@ -26,13 +26,15 @@  #define LP8556_EPROM_START		0xA0  #define LP8556_EPROM_END		0xAF -/* LP8557 Registers */ +/* LP8555/7 Registers */  #define LP8557_BL_CMD			0x00  #define LP8557_BL_MASK			0x01  #define LP8557_BL_ON			0x01  #define LP8557_BL_OFF			0x00  #define LP8557_BRIGHTNESS_CTRL		0x04  #define LP8557_CONFIG			0x10 +#define LP8555_EPROM_START		0x10 +#define LP8555_EPROM_END		0x7A  #define LP8557_EPROM_START		0x10  #define LP8557_EPROM_END		0x1E @@ -111,6 +113,10 @@ static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)  		start = LP8556_EPROM_START;  		end = LP8556_EPROM_END;  		break; +	case LP8555: +		start = LP8555_EPROM_START; +		end = LP8555_EPROM_END; +		break;  	case LP8557:  		start = LP8557_EPROM_START;  		end = LP8557_EPROM_END; @@ -119,7 +125,7 @@ static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)  		return false;  	} -	return (addr >= start && addr <= end); +	return addr >= start && addr <= end;  }  static int lp8557_bl_off(struct lp855x *lp) @@ -165,9 +171,14 @@ static int lp855x_configure(struct lp855x *lp)  	struct lp855x_platform_data *pd = lp->pdata;  	switch (lp->chip_id) { -	case LP8550 ... LP8556: +	case LP8550: +	case LP8551: +	case LP8552: +	case LP8553: +	case LP8556:  		lp->cfg = &lp855x_dev_cfg;  		break; +	case LP8555:  	case LP8557:  		lp->cfg = &lp8557_dev_cfg;  		break; @@ -289,7 +300,7 @@ static int lp855x_backlight_register(struct lp855x *lp)  	props.brightness = pdata->initial_brightness; -	bl = backlight_device_register(name, lp->dev, lp, +	bl = devm_backlight_device_register(lp->dev, name, lp->dev, lp,  				       &lp855x_bl_ops, &props);  	if (IS_ERR(bl))  		return PTR_ERR(bl); @@ -299,12 +310,6 @@ static int lp855x_backlight_register(struct lp855x *lp)  	return 0;  } -static void lp855x_backlight_unregister(struct lp855x *lp) -{ -	if (lp->bl) -		backlight_device_unregister(lp->bl); -} -  static ssize_t lp855x_get_chip_id(struct device *dev,  				struct device_attribute *attr, char *buf)  { @@ -394,7 +399,7 @@ static int lp855x_parse_dt(struct device *dev, struct device_node *node)  static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)  {  	struct lp855x *lp; -	struct lp855x_platform_data *pdata = cl->dev.platform_data; +	struct lp855x_platform_data *pdata = dev_get_platdata(&cl->dev);  	struct device_node *node = cl->dev.of_node;  	int ret; @@ -403,7 +408,7 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)  		if (ret < 0)  			return ret; -		pdata = cl->dev.platform_data; +		pdata = dev_get_platdata(&cl->dev);  	}  	if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) @@ -428,29 +433,24 @@ static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)  	ret = lp855x_configure(lp);  	if (ret) {  		dev_err(lp->dev, "device config err: %d", ret); -		goto err_dev; +		return ret;  	}  	ret = lp855x_backlight_register(lp);  	if (ret) {  		dev_err(lp->dev,  			"failed to register backlight. err: %d\n", ret); -		goto err_dev; +		return ret;  	}  	ret = sysfs_create_group(&lp->dev->kobj, &lp855x_attr_group);  	if (ret) {  		dev_err(lp->dev, "failed to register sysfs. err: %d\n", ret); -		goto err_sysfs; +		return ret;  	}  	backlight_update_status(lp->bl);  	return 0; - -err_sysfs: -	lp855x_backlight_unregister(lp); -err_dev: -	return ret;  }  static int lp855x_remove(struct i2c_client *cl) @@ -460,7 +460,6 @@ static int lp855x_remove(struct i2c_client *cl)  	lp->bl->props.brightness = 0;  	backlight_update_status(lp->bl);  	sysfs_remove_group(&lp->dev->kobj, &lp855x_attr_group); -	lp855x_backlight_unregister(lp);  	return 0;  } @@ -470,6 +469,7 @@ static const struct of_device_id lp855x_dt_ids[] = {  	{ .compatible = "ti,lp8551", },  	{ .compatible = "ti,lp8552", },  	{ .compatible = "ti,lp8553", }, +	{ .compatible = "ti,lp8555", },  	{ .compatible = "ti,lp8556", },  	{ .compatible = "ti,lp8557", },  	{ } @@ -481,6 +481,7 @@ static const struct i2c_device_id lp855x_ids[] = {  	{"lp8551", LP8551},  	{"lp8552", LP8552},  	{"lp8553", LP8553}, +	{"lp8555", LP8555},  	{"lp8556", LP8556},  	{"lp8557", LP8557},  	{ } diff --git a/drivers/video/backlight/lp8788_bl.c b/drivers/video/backlight/lp8788_bl.c index 980855ec9bb..daba34dc46d 100644 --- a/drivers/video/backlight/lp8788_bl.c +++ b/drivers/video/backlight/lp8788_bl.c @@ -52,7 +52,7 @@ struct lp8788_bl {  	struct pwm_device *pwm;  }; -struct lp8788_bl_config default_bl_config = { +static struct lp8788_bl_config default_bl_config = {  	.bl_mode    = LP8788_BL_REGISTER_ONLY,  	.dim_mode   = LP8788_DIM_EXPONENTIAL,  	.full_scale = LP8788_FULLSCALE_1900uA, @@ -63,13 +63,13 @@ struct lp8788_bl_config default_bl_config = {  static inline bool is_brightness_ctrl_by_pwm(enum lp8788_bl_ctrl_mode mode)  { -	return (mode == LP8788_BL_COMB_PWM_BASED); +	return mode == LP8788_BL_COMB_PWM_BASED;  }  static inline bool is_brightness_ctrl_by_register(enum lp8788_bl_ctrl_mode mode)  { -	return (mode == LP8788_BL_REGISTER_ONLY || -		mode == LP8788_BL_COMB_REGISTER_BASED); +	return mode == LP8788_BL_REGISTER_ONLY || +		mode == LP8788_BL_COMB_REGISTER_BASED;  }  static int lp8788_backlight_configure(struct lp8788_bl *bl) diff --git a/drivers/video/backlight/ltv350qv.c b/drivers/video/backlight/ltv350qv.c index ed1b3926813..383f550e165 100644 --- a/drivers/video/backlight/ltv350qv.c +++ b/drivers/video/backlight/ltv350qv.c @@ -242,7 +242,8 @@ static int ltv350qv_probe(struct spi_device *spi)  	if (!lcd->buffer)  		return -ENOMEM; -	ld = lcd_device_register("ltv350qv", &spi->dev, lcd, <v_ops); +	ld = devm_lcd_device_register(&spi->dev, "ltv350qv", &spi->dev, lcd, +					<v_ops);  	if (IS_ERR(ld))  		return PTR_ERR(ld); @@ -250,15 +251,11 @@ static int ltv350qv_probe(struct spi_device *spi)  	ret = ltv350qv_power(lcd, FB_BLANK_UNBLANK);  	if (ret) -		goto out_unregister; +		return ret;  	spi_set_drvdata(spi, lcd);  	return 0; - -out_unregister: -	lcd_device_unregister(ld); -	return ret;  }  static int ltv350qv_remove(struct spi_device *spi) @@ -266,8 +263,6 @@ static int ltv350qv_remove(struct spi_device *spi)  	struct ltv350qv *lcd = spi_get_drvdata(spi);  	ltv350qv_power(lcd, FB_BLANK_POWERDOWN); -	lcd_device_unregister(lcd->ld); -  	return 0;  } diff --git a/drivers/video/backlight/lv5207lp.c b/drivers/video/backlight/lv5207lp.c index 498fd73d59b..1802b2d1357 100644 --- a/drivers/video/backlight/lv5207lp.c +++ b/drivers/video/backlight/lv5207lp.c @@ -93,7 +93,7 @@ static const struct backlight_ops lv5207lp_backlight_ops = {  static int lv5207lp_probe(struct i2c_client *client,  			  const struct i2c_device_id *id)  { -	struct lv5207lp_platform_data *pdata = client->dev.platform_data; +	struct lv5207lp_platform_data *pdata = dev_get_platdata(&client->dev);  	struct backlight_device *backlight;  	struct backlight_properties props;  	struct lv5207lp *lv; @@ -124,9 +124,9 @@ static int lv5207lp_probe(struct i2c_client *client,  	props.brightness = clamp_t(unsigned int, pdata->def_value, 0,  				   props.max_brightness); -	backlight = backlight_device_register(dev_name(&client->dev), -					      &lv->client->dev, lv, -					      &lv5207lp_backlight_ops, &props); +	backlight = devm_backlight_device_register(&client->dev, +				dev_name(&client->dev), &lv->client->dev, +				lv, &lv5207lp_backlight_ops, &props);  	if (IS_ERR(backlight)) {  		dev_err(&client->dev, "failed to register backlight\n");  		return PTR_ERR(backlight); @@ -144,7 +144,6 @@ static int lv5207lp_remove(struct i2c_client *client)  	backlight->props.brightness = 0;  	backlight_update_status(backlight); -	backlight_device_unregister(backlight);  	return 0;  } diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c index 886e797f75f..66fa08c920d 100644 --- a/drivers/video/backlight/max8925_bl.c +++ b/drivers/video/backlight/max8925_bl.c @@ -163,7 +163,8 @@ static int max8925_backlight_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = MAX_BRIGHTNESS; -	bl = backlight_device_register("max8925-backlight", &pdev->dev, data, +	bl = devm_backlight_device_register(&pdev->dev, "max8925-backlight", +					&pdev->dev, data,  					&max8925_backlight_ops, &props);  	if (IS_ERR(bl)) {  		dev_err(&pdev->dev, "failed to register backlight\n"); @@ -188,20 +189,9 @@ static int max8925_backlight_probe(struct platform_device *pdev)  	}  	ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 0xfe, value);  	if (ret < 0) -		goto out_brt; +		return ret;  	backlight_update_status(bl);  	return 0; -out_brt: -	backlight_device_unregister(bl); -	return ret; -} - -static int max8925_backlight_remove(struct platform_device *pdev) -{ -	struct backlight_device *bl = platform_get_drvdata(pdev); - -	backlight_device_unregister(bl); -	return 0;  }  static struct platform_driver max8925_backlight_driver = { @@ -210,7 +200,6 @@ static struct platform_driver max8925_backlight_driver = {  		.owner	= THIS_MODULE,  	},  	.probe		= max8925_backlight_probe, -	.remove		= max8925_backlight_remove,  };  module_platform_driver(max8925_backlight_driver); diff --git a/drivers/video/backlight/omap1_bl.c b/drivers/video/backlight/omap1_bl.c index 812e22e35ca..a0dcd88ac74 100644 --- a/drivers/video/backlight/omap1_bl.c +++ b/drivers/video/backlight/omap1_bl.c @@ -133,7 +133,7 @@ static int omapbl_probe(struct platform_device *pdev)  	struct backlight_properties props;  	struct backlight_device *dev;  	struct omap_backlight *bl; -	struct omap_backlight_config *pdata = pdev->dev.platform_data; +	struct omap_backlight_config *pdata = dev_get_platdata(&pdev->dev);  	if (!pdata)  		return -ENXIO; @@ -146,8 +146,8 @@ static int omapbl_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = OMAPBL_MAX_INTENSITY; -	dev = backlight_device_register("omap-bl", &pdev->dev, bl, &omapbl_ops, -					&props); +	dev = devm_backlight_device_register(&pdev->dev, "omap-bl", &pdev->dev, +					bl, &omapbl_ops, &props);  	if (IS_ERR(dev))  		return PTR_ERR(dev); @@ -170,20 +170,10 @@ static int omapbl_probe(struct platform_device *pdev)  	return 0;  } -static int omapbl_remove(struct platform_device *pdev) -{ -	struct backlight_device *dev = platform_get_drvdata(pdev); - -	backlight_device_unregister(dev); - -	return 0; -} -  static SIMPLE_DEV_PM_OPS(omapbl_pm_ops, omapbl_suspend, omapbl_resume);  static struct platform_driver omapbl_driver = {  	.probe		= omapbl_probe, -	.remove		= omapbl_remove,  	.driver		= {  		.name	= "omap-bl",  		.pm	= &omapbl_pm_ops, diff --git a/drivers/video/backlight/ot200_bl.c b/drivers/video/backlight/ot200_bl.c index fdbb6ee5027..f5a5202dd79 100644 --- a/drivers/video/backlight/ot200_bl.c +++ b/drivers/video/backlight/ot200_bl.c @@ -118,8 +118,9 @@ static int ot200_backlight_probe(struct platform_device *pdev)  	props.brightness = 100;  	props.type = BACKLIGHT_RAW; -	bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, data, -					&ot200_backlight_ops, &props); +	bl = devm_backlight_device_register(&pdev->dev, dev_name(&pdev->dev), +					&pdev->dev, data, &ot200_backlight_ops, +					&props);  	if (IS_ERR(bl)) {  		dev_err(&pdev->dev, "failed to register backlight\n");  		retval = PTR_ERR(bl); @@ -137,10 +138,6 @@ error_devm_kzalloc:  static int ot200_backlight_remove(struct platform_device *pdev)  { -	struct backlight_device *bl = platform_get_drvdata(pdev); - -	backlight_device_unregister(bl); -  	/* on module unload set brightness to 100% */  	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_COUNTER, 0);  	cs5535_mfgpt_write(pwm_timer, MFGPT_REG_SETUP, MFGPT_SETUP_CNTEN); diff --git a/drivers/video/backlight/pandora_bl.c b/drivers/video/backlight/pandora_bl.c index 633b0a22fd6..2098c5d6efb 100644 --- a/drivers/video/backlight/pandora_bl.c +++ b/drivers/video/backlight/pandora_bl.c @@ -120,8 +120,8 @@ static int pandora_backlight_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(props));  	props.max_brightness = MAX_USER_VALUE;  	props.type = BACKLIGHT_RAW; -	bl = backlight_device_register(pdev->name, &pdev->dev, -			NULL, &pandora_backlight_ops, &props); +	bl = devm_backlight_device_register(&pdev->dev, pdev->name, &pdev->dev, +					NULL, &pandora_backlight_ops, &props);  	if (IS_ERR(bl)) {  		dev_err(&pdev->dev, "failed to register backlight\n");  		return PTR_ERR(bl); @@ -145,20 +145,12 @@ static int pandora_backlight_probe(struct platform_device *pdev)  	return 0;  } -static int pandora_backlight_remove(struct platform_device *pdev) -{ -	struct backlight_device *bl = platform_get_drvdata(pdev); -	backlight_device_unregister(bl); -	return 0; -} -  static struct platform_driver pandora_backlight_driver = {  	.driver		= {  		.name	= "pandora-backlight",  		.owner	= THIS_MODULE,  	},  	.probe		= pandora_backlight_probe, -	.remove		= pandora_backlight_remove,  };  module_platform_driver(pandora_backlight_driver); diff --git a/drivers/video/backlight/pcf50633-backlight.c b/drivers/video/backlight/pcf50633-backlight.c index 6ed76be18f1..b95d3b0aaff 100644 --- a/drivers/video/backlight/pcf50633-backlight.c +++ b/drivers/video/backlight/pcf50633-backlight.c @@ -103,7 +103,7 @@ static int pcf50633_bl_probe(struct platform_device *pdev)  {  	struct pcf50633_bl *pcf_bl;  	struct device *parent = pdev->dev.parent; -	struct pcf50633_platform_data *pcf50633_data = parent->platform_data; +	struct pcf50633_platform_data *pcf50633_data = dev_get_platdata(parent);  	struct pcf50633_bl_platform_data *pdata = pcf50633_data->backlight_data;  	struct backlight_properties bl_props; @@ -126,7 +126,8 @@ static int pcf50633_bl_probe(struct platform_device *pdev)  	pcf_bl->pcf = dev_to_pcf50633(pdev->dev.parent); -	pcf_bl->bl = backlight_device_register(pdev->name, &pdev->dev, pcf_bl, +	pcf_bl->bl = devm_backlight_device_register(&pdev->dev, pdev->name, +						&pdev->dev, pcf_bl,  						&pcf50633_bl_ops, &bl_props);  	if (IS_ERR(pcf_bl->bl)) @@ -147,18 +148,8 @@ static int pcf50633_bl_probe(struct platform_device *pdev)  	return 0;  } -static int pcf50633_bl_remove(struct platform_device *pdev) -{ -	struct pcf50633_bl *pcf_bl = platform_get_drvdata(pdev); - -	backlight_device_unregister(pcf_bl->bl); - -	return 0; -} -  static struct platform_driver pcf50633_bl_driver = {  	.probe =	pcf50633_bl_probe, -	.remove =	pcf50633_bl_remove,  	.driver = {  		.name = "pcf50633-backlight",  	}, diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c index 05683670670..c3d2e209fc8 100644 --- a/drivers/video/backlight/platform_lcd.c +++ b/drivers/video/backlight/platform_lcd.c @@ -80,7 +80,7 @@ static int platform_lcd_probe(struct platform_device *pdev)  	struct device *dev = &pdev->dev;  	int err; -	pdata = pdev->dev.platform_data; +	pdata = dev_get_platdata(&pdev->dev);  	if (!pdata) {  		dev_err(dev, "no platform data supplied\n");  		return -EINVAL; @@ -94,37 +94,22 @@ static int platform_lcd_probe(struct platform_device *pdev)  	plcd = devm_kzalloc(&pdev->dev, sizeof(struct platform_lcd),  			    GFP_KERNEL); -	if (!plcd) { -		dev_err(dev, "no memory for state\n"); +	if (!plcd)  		return -ENOMEM; -	}  	plcd->us = dev;  	plcd->pdata = pdata; -	plcd->lcd = lcd_device_register(dev_name(dev), dev, -					plcd, &platform_lcd_ops); +	plcd->lcd = devm_lcd_device_register(&pdev->dev, dev_name(dev), dev, +						plcd, &platform_lcd_ops);  	if (IS_ERR(plcd->lcd)) {  		dev_err(dev, "cannot register lcd device\n"); -		err = PTR_ERR(plcd->lcd); -		goto err; +		return PTR_ERR(plcd->lcd);  	}  	platform_set_drvdata(pdev, plcd);  	platform_lcd_set_power(plcd->lcd, FB_BLANK_NORMAL);  	return 0; - - err: -	return err; -} - -static int platform_lcd_remove(struct platform_device *pdev) -{ -	struct platform_lcd *plcd = platform_get_drvdata(pdev); - -	lcd_device_unregister(plcd->lcd); - -	return 0;  }  #ifdef CONFIG_PM_SLEEP @@ -168,7 +153,6 @@ static struct platform_driver platform_lcd_driver = {  		.of_match_table = of_match_ptr(platform_lcd_of_match),  	},  	.probe		= platform_lcd_probe, -	.remove		= platform_lcd_remove,  };  module_platform_driver(platform_lcd_driver); diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c index 1fea627394d..38ca88bc5c3 100644 --- a/drivers/video/backlight/pwm_bl.c +++ b/drivers/video/backlight/pwm_bl.c @@ -10,6 +10,8 @@   * published by the Free Software Foundation.   */ +#include <linux/gpio/consumer.h> +#include <linux/gpio.h>  #include <linux/module.h>  #include <linux/kernel.h>  #include <linux/init.h> @@ -19,6 +21,7 @@  #include <linux/err.h>  #include <linux/pwm.h>  #include <linux/pwm_backlight.h> +#include <linux/regulator/consumer.h>  #include <linux/slab.h>  struct pwm_bl_data { @@ -27,6 +30,10 @@ struct pwm_bl_data {  	unsigned int		period;  	unsigned int		lth_brightness;  	unsigned int		*levels; +	bool			enabled; +	struct regulator	*power_supply; +	struct gpio_desc	*enable_gpio; +	unsigned int		scale;  	int			(*notify)(struct device *,  					  int brightness);  	void			(*notify_after)(struct device *, @@ -35,11 +42,57 @@ struct pwm_bl_data {  	void			(*exit)(struct device *);  }; +static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness) +{ +	int err; + +	if (pb->enabled) +		return; + +	err = regulator_enable(pb->power_supply); +	if (err < 0) +		dev_err(pb->dev, "failed to enable power supply\n"); + +	if (pb->enable_gpio) +		gpiod_set_value(pb->enable_gpio, 1); + +	pwm_enable(pb->pwm); +	pb->enabled = true; +} + +static void pwm_backlight_power_off(struct pwm_bl_data *pb) +{ +	if (!pb->enabled) +		return; + +	pwm_config(pb->pwm, 0, pb->period); +	pwm_disable(pb->pwm); + +	if (pb->enable_gpio) +		gpiod_set_value(pb->enable_gpio, 0); + +	regulator_disable(pb->power_supply); +	pb->enabled = false; +} + +static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness) +{ +	unsigned int lth = pb->lth_brightness; +	int duty_cycle; + +	if (pb->levels) +		duty_cycle = pb->levels[brightness]; +	else +		duty_cycle = brightness; + +	return (duty_cycle * (pb->period - lth) / pb->scale) + lth; +} +  static int pwm_backlight_update_status(struct backlight_device *bl)  {  	struct pwm_bl_data *pb = bl_get_data(bl);  	int brightness = bl->props.brightness; -	int max = bl->props.max_brightness; +	int duty_cycle;  	if (bl->props.power != FB_BLANK_UNBLANK ||  	    bl->props.fb_blank != FB_BLANK_UNBLANK || @@ -49,24 +102,12 @@ static int pwm_backlight_update_status(struct backlight_device *bl)  	if (pb->notify)  		brightness = pb->notify(pb->dev, brightness); -	if (brightness == 0) { -		pwm_config(pb->pwm, 0, pb->period); -		pwm_disable(pb->pwm); -	} else { -		int duty_cycle; - -		if (pb->levels) { -			duty_cycle = pb->levels[brightness]; -			max = pb->levels[max]; -		} else { -			duty_cycle = brightness; -		} - -		duty_cycle = pb->lth_brightness + -		     (duty_cycle * (pb->period - pb->lth_brightness) / max); +	if (brightness > 0) { +		duty_cycle = compute_duty_cycle(pb, brightness);  		pwm_config(pb->pwm, duty_cycle, pb->period); -		pwm_enable(pb->pwm); -	} +		pwm_backlight_power_on(pb, brightness); +	} else +		pwm_backlight_power_off(pb);  	if (pb->notify_after)  		pb->notify_after(pb->dev, brightness); @@ -138,12 +179,6 @@ static int pwm_backlight_parse_dt(struct device *dev,  		data->max_brightness--;  	} -	/* -	 * TODO: Most users of this driver use a number of GPIOs to control -	 *       backlight power. Support for specifying these needs to be -	 *       added. -	 */ -  	return 0;  } @@ -163,12 +198,11 @@ static int pwm_backlight_parse_dt(struct device *dev,  static int pwm_backlight_probe(struct platform_device *pdev)  { -	struct platform_pwm_backlight_data *data = pdev->dev.platform_data; +	struct platform_pwm_backlight_data *data = dev_get_platdata(&pdev->dev);  	struct platform_pwm_backlight_data defdata;  	struct backlight_properties props;  	struct backlight_device *bl;  	struct pwm_bl_data *pb; -	unsigned int max;  	int ret;  	if (!data) { @@ -189,22 +223,61 @@ static int pwm_backlight_probe(struct platform_device *pdev)  	pb = devm_kzalloc(&pdev->dev, sizeof(*pb), GFP_KERNEL);  	if (!pb) { -		dev_err(&pdev->dev, "no memory for state\n");  		ret = -ENOMEM;  		goto err_alloc;  	}  	if (data->levels) { -		max = data->levels[data->max_brightness]; +		unsigned int i; + +		for (i = 0; i <= data->max_brightness; i++) +			if (data->levels[i] > pb->scale) +				pb->scale = data->levels[i]; +  		pb->levels = data->levels;  	} else -		max = data->max_brightness; +		pb->scale = data->max_brightness;  	pb->notify = data->notify;  	pb->notify_after = data->notify_after;  	pb->check_fb = data->check_fb;  	pb->exit = data->exit;  	pb->dev = &pdev->dev; +	pb->enabled = false; + +	pb->enable_gpio = devm_gpiod_get(&pdev->dev, "enable"); +	if (IS_ERR(pb->enable_gpio)) { +		ret = PTR_ERR(pb->enable_gpio); +		if (ret == -ENOENT) +			pb->enable_gpio = NULL; +		else +			goto err_alloc; +	} + +	/* +	 * Compatibility fallback for drivers still using the integer GPIO +	 * platform data. Must go away soon. +	 */ +	if (!pb->enable_gpio && gpio_is_valid(data->enable_gpio)) { +		ret = devm_gpio_request_one(&pdev->dev, data->enable_gpio, +					    GPIOF_OUT_INIT_HIGH, "enable"); +		if (ret < 0) { +			dev_err(&pdev->dev, "failed to request GPIO#%d: %d\n", +				data->enable_gpio, ret); +			goto err_alloc; +		} + +		pb->enable_gpio = gpio_to_desc(data->enable_gpio); +	} + +	if (pb->enable_gpio) +		gpiod_direction_output(pb->enable_gpio, 1); + +	pb->power_supply = devm_regulator_get(&pdev->dev, "power"); +	if (IS_ERR(pb->power_supply)) { +		ret = PTR_ERR(pb->power_supply); +		goto err_alloc; +	}  	pb->pwm = devm_pwm_get(&pdev->dev, NULL);  	if (IS_ERR(pb->pwm)) { @@ -223,13 +296,16 @@ static int pwm_backlight_probe(struct platform_device *pdev)  	/*  	 * The DT case will set the pwm_period_ns field to 0 and store the  	 * period, parsed from the DT, in the PWM device. For the non-DT case, -	 * set the period from platform data. +	 * set the period from platform data if it has not already been set +	 * via the PWM lookup table.  	 */ -	if (data->pwm_period_ns > 0) +	pb->period = pwm_get_period(pb->pwm); +	if (!pb->period && (data->pwm_period_ns > 0)) { +		pb->period = data->pwm_period_ns;  		pwm_set_period(pb->pwm, data->pwm_period_ns); +	} -	pb->period = pwm_get_period(pb->pwm); -	pb->lth_brightness = data->lth_brightness * (pb->period / max); +	pb->lth_brightness = data->lth_brightness * (pb->period / pb->scale);  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW; @@ -267,13 +343,22 @@ static int pwm_backlight_remove(struct platform_device *pdev)  	struct pwm_bl_data *pb = bl_get_data(bl);  	backlight_device_unregister(bl); -	pwm_config(pb->pwm, 0, pb->period); -	pwm_disable(pb->pwm); +	pwm_backlight_power_off(pb); +  	if (pb->exit)  		pb->exit(&pdev->dev); +  	return 0;  } +static void pwm_backlight_shutdown(struct platform_device *pdev) +{ +	struct backlight_device *bl = platform_get_drvdata(pdev); +	struct pwm_bl_data *pb = bl_get_data(bl); + +	pwm_backlight_power_off(pb); +} +  #ifdef CONFIG_PM_SLEEP  static int pwm_backlight_suspend(struct device *dev)  { @@ -282,10 +367,12 @@ static int pwm_backlight_suspend(struct device *dev)  	if (pb->notify)  		pb->notify(pb->dev, 0); -	pwm_config(pb->pwm, 0, pb->period); -	pwm_disable(pb->pwm); + +	pwm_backlight_power_off(pb); +  	if (pb->notify_after)  		pb->notify_after(pb->dev, 0); +  	return 0;  } @@ -294,12 +381,19 @@ static int pwm_backlight_resume(struct device *dev)  	struct backlight_device *bl = dev_get_drvdata(dev);  	backlight_update_status(bl); +  	return 0;  }  #endif -static SIMPLE_DEV_PM_OPS(pwm_backlight_pm_ops, pwm_backlight_suspend, -			 pwm_backlight_resume); +static const struct dev_pm_ops pwm_backlight_pm_ops = { +#ifdef CONFIG_PM_SLEEP +	.suspend = pwm_backlight_suspend, +	.resume = pwm_backlight_resume, +	.poweroff = pwm_backlight_suspend, +	.restore = pwm_backlight_resume, +#endif +};  static struct platform_driver pwm_backlight_driver = {  	.driver		= { @@ -310,6 +404,7 @@ static struct platform_driver pwm_backlight_driver = {  	},  	.probe		= pwm_backlight_probe,  	.remove		= pwm_backlight_remove, +	.shutdown	= pwm_backlight_shutdown,  };  module_platform_driver(pwm_backlight_driver); @@ -317,4 +412,3 @@ module_platform_driver(pwm_backlight_driver);  MODULE_DESCRIPTION("PWM based Backlight Driver");  MODULE_LICENSE("GPL");  MODULE_ALIAS("platform:pwm-backlight"); - diff --git a/drivers/video/backlight/s6e63m0.c b/drivers/video/backlight/s6e63m0.c index b37bb1854bf..2d6d48196c6 100644 --- a/drivers/video/backlight/s6e63m0.c +++ b/drivers/video/backlight/s6e63m0.c @@ -703,7 +703,7 @@ static ssize_t s6e63m0_sysfs_show_gamma_table(struct device *dev,  	struct s6e63m0 *lcd = dev_get_drvdata(dev);  	char temp[3]; -	sprintf(temp, "%d\n", lcd->gamma_table_count); +	sprintf(temp, "%u\n", lcd->gamma_table_count);  	strcpy(buf, temp);  	return strlen(buf); @@ -735,13 +735,14 @@ static int s6e63m0_probe(struct spi_device *spi)  	lcd->spi = spi;  	lcd->dev = &spi->dev; -	lcd->lcd_pd = spi->dev.platform_data; +	lcd->lcd_pd = dev_get_platdata(&spi->dev);  	if (!lcd->lcd_pd) {  		dev_err(&spi->dev, "platform data is NULL.\n");  		return -EINVAL;  	} -	ld = lcd_device_register("s6e63m0", &spi->dev, lcd, &s6e63m0_lcd_ops); +	ld = devm_lcd_device_register(&spi->dev, "s6e63m0", &spi->dev, lcd, +				&s6e63m0_lcd_ops);  	if (IS_ERR(ld))  		return PTR_ERR(ld); @@ -751,12 +752,11 @@ static int s6e63m0_probe(struct spi_device *spi)  	props.type = BACKLIGHT_RAW;  	props.max_brightness = MAX_BRIGHTNESS; -	bd = backlight_device_register("s6e63m0bl-bl", &spi->dev, lcd, -		&s6e63m0_backlight_ops, &props); -	if (IS_ERR(bd)) { -		ret =  PTR_ERR(bd); -		goto out_lcd_unregister; -	} +	bd = devm_backlight_device_register(&spi->dev, "s6e63m0bl-bl", +					&spi->dev, lcd, &s6e63m0_backlight_ops, +					&props); +	if (IS_ERR(bd)) +		return PTR_ERR(bd);  	bd->props.brightness = MAX_BRIGHTNESS;  	lcd->bd = bd; @@ -798,10 +798,6 @@ static int s6e63m0_probe(struct spi_device *spi)  	dev_info(&spi->dev, "s6e63m0 panel driver has been probed.\n");  	return 0; - -out_lcd_unregister: -	lcd_device_unregister(ld); -	return ret;  }  static int s6e63m0_remove(struct spi_device *spi) @@ -811,8 +807,6 @@ static int s6e63m0_remove(struct spi_device *spi)  	s6e63m0_power(lcd, FB_BLANK_POWERDOWN);  	device_remove_file(&spi->dev, &dev_attr_gamma_table);  	device_remove_file(&spi->dev, &dev_attr_gamma_mode); -	backlight_device_unregister(lcd->bd); -	lcd_device_unregister(lcd->ld);  	return 0;  } diff --git a/drivers/video/backlight/tdo24m.c b/drivers/video/backlight/tdo24m.c index 18cdf466d50..908016fc582 100644 --- a/drivers/video/backlight/tdo24m.c +++ b/drivers/video/backlight/tdo24m.c @@ -338,7 +338,7 @@ static int tdo24m_probe(struct spi_device *spi)  	enum tdo24m_model model;  	int err; -	pdata = spi->dev.platform_data; +	pdata = dev_get_platdata(&spi->dev);  	if (pdata)  		model = pdata->model;  	else @@ -385,21 +385,17 @@ static int tdo24m_probe(struct spi_device *spi)  		return -EINVAL;  	} -	lcd->lcd_dev = lcd_device_register("tdo24m", &spi->dev, -					lcd, &tdo24m_ops); +	lcd->lcd_dev = devm_lcd_device_register(&spi->dev, "tdo24m", &spi->dev, +						lcd, &tdo24m_ops);  	if (IS_ERR(lcd->lcd_dev))  		return PTR_ERR(lcd->lcd_dev);  	spi_set_drvdata(spi, lcd);  	err = tdo24m_power(lcd, FB_BLANK_UNBLANK);  	if (err) -		goto out_unregister; +		return err;  	return 0; - -out_unregister: -	lcd_device_unregister(lcd->lcd_dev); -	return err;  }  static int tdo24m_remove(struct spi_device *spi) @@ -407,8 +403,6 @@ static int tdo24m_remove(struct spi_device *spi)  	struct tdo24m *lcd = spi_get_drvdata(spi);  	tdo24m_power(lcd, FB_BLANK_POWERDOWN); -	lcd_device_unregister(lcd->lcd_dev); -  	return 0;  } diff --git a/drivers/video/backlight/tosa_bl.c b/drivers/video/backlight/tosa_bl.c index 9df66ac68b3..3ad676558c8 100644 --- a/drivers/video/backlight/tosa_bl.c +++ b/drivers/video/backlight/tosa_bl.c @@ -38,7 +38,7 @@ struct tosa_bl_data {  static void tosa_bl_set_backlight(struct tosa_bl_data *data, int brightness)  { -	struct spi_device *spi = data->i2c->dev.platform_data; +	struct spi_device *spi = dev_get_platdata(&data->i2c->dev);  	i2c_smbus_write_byte_data(data->i2c, DAC_CH1, data->comadj); @@ -105,8 +105,9 @@ static int tosa_bl_probe(struct i2c_client *client,  	memset(&props, 0, sizeof(struct backlight_properties));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = 512 - 1; -	data->bl = backlight_device_register("tosa-bl", &client->dev, data, -					     &bl_ops, &props); +	data->bl = devm_backlight_device_register(&client->dev, "tosa-bl", +						&client->dev, data, &bl_ops, +						&props);  	if (IS_ERR(data->bl)) {  		ret = PTR_ERR(data->bl);  		goto err_reg; @@ -128,9 +129,7 @@ static int tosa_bl_remove(struct i2c_client *client)  {  	struct tosa_bl_data *data = i2c_get_clientdata(client); -	backlight_device_unregister(data->bl);  	data->bl = NULL; -  	return 0;  } diff --git a/drivers/video/backlight/tosa_lcd.c b/drivers/video/backlight/tosa_lcd.c index bf081573e5b..f08d641ccd0 100644 --- a/drivers/video/backlight/tosa_lcd.c +++ b/drivers/video/backlight/tosa_lcd.c @@ -198,7 +198,7 @@ static int tosa_lcd_probe(struct spi_device *spi)  	ret = devm_gpio_request_one(&spi->dev, TOSA_GPIO_TG_ON,  				GPIOF_OUT_INIT_LOW, "tg #pwr");  	if (ret < 0) -		goto err_gpio_tg; +		return ret;  	mdelay(60); @@ -206,8 +206,8 @@ static int tosa_lcd_probe(struct spi_device *spi)  	tosa_lcd_tg_on(data); -	data->lcd = lcd_device_register("tosa-lcd", &spi->dev, data, -			&tosa_lcd_ops); +	data->lcd = devm_lcd_device_register(&spi->dev, "tosa-lcd", &spi->dev, +					data, &tosa_lcd_ops);  	if (IS_ERR(data->lcd)) {  		ret = PTR_ERR(data->lcd); @@ -219,8 +219,6 @@ static int tosa_lcd_probe(struct spi_device *spi)  err_register:  	tosa_lcd_tg_off(data); -err_gpio_tg: -	spi_set_drvdata(spi, NULL);  	return ret;  } @@ -228,15 +226,11 @@ static int tosa_lcd_remove(struct spi_device *spi)  {  	struct tosa_lcd_data *data = spi_get_drvdata(spi); -	lcd_device_unregister(data->lcd); -  	if (data->i2c)  		i2c_unregister_device(data->i2c);  	tosa_lcd_tg_off(data); -	spi_set_drvdata(spi, NULL); -  	return 0;  } diff --git a/drivers/video/backlight/tps65217_bl.c b/drivers/video/backlight/tps65217_bl.c index 05782312aeb..595dcf56102 100644 --- a/drivers/video/backlight/tps65217_bl.c +++ b/drivers/video/backlight/tps65217_bl.c @@ -200,7 +200,6 @@ tps65217_bl_parse_dt(struct platform_device *pdev)  	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);  	if (!pdata) { -		dev_err(&pdev->dev, "failed to allocate platform data\n");  		err = ERR_PTR(-ENOMEM);  		goto err;  	} @@ -287,20 +286,17 @@ static int tps65217_bl_probe(struct platform_device *pdev)  		if (IS_ERR(pdata))  			return PTR_ERR(pdata);  	} else { -		if (!pdev->dev.platform_data) { +		pdata = dev_get_platdata(&pdev->dev); +		if (!pdata) {  			dev_err(&pdev->dev, "no platform data provided\n");  			return -EINVAL;  		} - -		pdata = pdev->dev.platform_data;  	}  	tps65217_bl = devm_kzalloc(&pdev->dev, sizeof(*tps65217_bl),  				GFP_KERNEL); -	if (tps65217_bl == NULL) { -		dev_err(&pdev->dev, "allocation of struct tps65217_bl failed\n"); +	if (tps65217_bl == NULL)  		return -ENOMEM; -	}  	tps65217_bl->tps = tps;  	tps65217_bl->dev = &pdev->dev; @@ -314,7 +310,7 @@ static int tps65217_bl_probe(struct platform_device *pdev)  	bl_props.type = BACKLIGHT_RAW;  	bl_props.max_brightness = 100; -	tps65217_bl->bl = backlight_device_register(pdev->name, +	tps65217_bl->bl = devm_backlight_device_register(&pdev->dev, pdev->name,  						tps65217_bl->dev, tps65217_bl,  						&tps65217_bl_ops, &bl_props);  	if (IS_ERR(tps65217_bl->bl)) { @@ -330,18 +326,8 @@ static int tps65217_bl_probe(struct platform_device *pdev)  	return 0;  } -static int tps65217_bl_remove(struct platform_device *pdev) -{ -	struct tps65217_bl *tps65217_bl = platform_get_drvdata(pdev); - -	backlight_device_unregister(tps65217_bl->bl); - -	return 0; -} -  static struct platform_driver tps65217_bl_driver = {  	.probe		= tps65217_bl_probe, -	.remove		= tps65217_bl_remove,  	.driver		= {  		.owner	= THIS_MODULE,  		.name	= "tps65217-bl", diff --git a/drivers/video/backlight/wm831x_bl.c b/drivers/video/backlight/wm831x_bl.c index 9e5517a3a52..8b9455e9306 100644 --- a/drivers/video/backlight/wm831x_bl.c +++ b/drivers/video/backlight/wm831x_bl.c @@ -123,7 +123,7 @@ static const struct backlight_ops wm831x_backlight_ops = {  static int wm831x_backlight_probe(struct platform_device *pdev)  {  	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); -	struct wm831x_pdata *wm831x_pdata; +	struct wm831x_pdata *wm831x_pdata = dev_get_platdata(pdev->dev.parent);  	struct wm831x_backlight_pdata *pdata;  	struct wm831x_backlight_data *data;  	struct backlight_device *bl; @@ -131,12 +131,10 @@ static int wm831x_backlight_probe(struct platform_device *pdev)  	int ret, i, max_isel, isink_reg, dcdc_cfg;  	/* We need platform data */ -	if (pdev->dev.parent->platform_data) { -		wm831x_pdata = pdev->dev.parent->platform_data; +	if (wm831x_pdata)  		pdata = wm831x_pdata->backlight; -	} else { +	else  		pdata = NULL; -	}  	if (!pdata) {  		dev_err(&pdev->dev, "No platform data supplied\n"); @@ -197,8 +195,8 @@ static int wm831x_backlight_probe(struct platform_device *pdev)  	memset(&props, 0, sizeof(props));  	props.type = BACKLIGHT_RAW;  	props.max_brightness = max_isel; -	bl = backlight_device_register("wm831x", &pdev->dev, data, -				       &wm831x_backlight_ops, &props); +	bl = devm_backlight_device_register(&pdev->dev, "wm831x", &pdev->dev, +					data, &wm831x_backlight_ops, &props);  	if (IS_ERR(bl)) {  		dev_err(&pdev->dev, "failed to register backlight\n");  		return PTR_ERR(bl); @@ -216,21 +214,12 @@ static int wm831x_backlight_probe(struct platform_device *pdev)  	return 0;  } -static int wm831x_backlight_remove(struct platform_device *pdev) -{ -	struct backlight_device *bl = platform_get_drvdata(pdev); - -	backlight_device_unregister(bl); -	return 0; -} -  static struct platform_driver wm831x_backlight_driver = {  	.driver		= {  		.name	= "wm831x-backlight",  		.owner	= THIS_MODULE,  	},  	.probe		= wm831x_backlight_probe, -	.remove		= wm831x_backlight_remove,  };  module_platform_driver(wm831x_backlight_driver); diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 846caab75a4..fe1cd0148e1 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -8,7 +8,8 @@ config VGA_CONSOLE  	bool "VGA text console" if EXPERT || !X86  	depends on !4xx && !8xx && !SPARC && !M68K && !PARISC && !FRV && \  		!SUPERH && !BLACKFIN && !AVR32 && !MN10300 && !CRIS && \ -		(!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) +		(!ARM || ARCH_FOOTBRIDGE || ARCH_INTEGRATOR || ARCH_NETWINDER) && \ +		!ARM64  	default y  	help  	  Saying Y here will allow you to use Linux in text mode through a diff --git a/drivers/video/console/dummycon.c b/drivers/video/console/dummycon.c index b63860f7bea..40bec8d64b0 100644 --- a/drivers/video/console/dummycon.c +++ b/drivers/video/console/dummycon.c @@ -77,3 +77,4 @@ const struct consw dummy_con = {      .con_set_palette =	DUMMY,      .con_scrolldelta =	DUMMY,  }; +EXPORT_SYMBOL_GPL(dummy_con); diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index cd8a8027f8a..57b1d44acbf 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -748,6 +748,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,  		fbcon_del_cursor_timer(oldinfo);  		kfree(ops->cursor_state.mask);  		kfree(ops->cursor_data); +		kfree(ops->cursor_src);  		kfree(ops->fontbuffer);  		kfree(oldinfo->fbcon_par);  		oldinfo->fbcon_par = NULL; @@ -759,7 +760,7 @@ static int con2fb_release_oldinfo(struct vc_data *vc, struct fb_info *oldinfo,  		  newinfo in an undefined state. Thus, a call to  		  fb_set_par() may be needed for the newinfo.  		*/ -		if (newinfo->fbops->fb_set_par) { +		if (newinfo && newinfo->fbops->fb_set_par) {  			ret = newinfo->fbops->fb_set_par(newinfo);  			if (ret) @@ -3028,8 +3029,31 @@ static int fbcon_fb_unbind(int idx)  			if (con2fb_map[i] == idx)  				set_con2fb_map(i, new_idx, 0);  		} -	} else +	} else { +		struct fb_info *info = registered_fb[idx]; + +		/* This is sort of like set_con2fb_map, except it maps +		 * the consoles to no device and then releases the +		 * oldinfo to free memory and cancel the cursor blink +		 * timer. I can imagine this just becoming part of +		 * set_con2fb_map where new_idx is -1 +		 */ +		for (i = first_fb_vc; i <= last_fb_vc; i++) { +			if (con2fb_map[i] == idx) { +				con2fb_map[i] = -1; +				if (!search_fb_in_map(idx)) { +					ret = con2fb_release_oldinfo(vc_cons[i].d, +								     info, NULL, i, +								     idx, 0); +					if (ret) { +						con2fb_map[i] = idx; +						return ret; +					} +				} +			} +		}  		ret = fbcon_unbind(); +	}  	return ret;  } @@ -3547,8 +3571,10 @@ static void fbcon_exit(void)  			"no"));  		for (j = first_fb_vc; j <= last_fb_vc; j++) { -			if (con2fb_map[j] == i) +			if (con2fb_map[j] == i) {  				mapped = 1; +				break; +			}  		}  		if (mapped) { @@ -3561,6 +3587,7 @@ static void fbcon_exit(void)  				fbcon_del_cursor_timer(info);  				kfree(ops->cursor_src); +				kfree(ops->cursor_state.mask);  				kfree(info->fbcon_par);  				info->fbcon_par = NULL;  			} diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c index 5f65ca3d856..026fd121593 100644 --- a/drivers/video/console/sticon.c +++ b/drivers/video/console/sticon.c @@ -46,7 +46,7 @@  #include <asm/io.h> -#include "../sticore.h" +#include "../fbdev/sticore.h"  /* switching to graphics mode */  #define BLANK 0 diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 35687fd5645..7da1ad03acb 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -3,7 +3,7 @@   *	core code for console driver using HP's STI firmware   *   *	Copyright (C) 2000 Philipp Rumpf <prumpf@tux.org> - *	Copyright (C) 2001-2003 Helge Deller <deller@gmx.de> + *	Copyright (C) 2001-2013 Helge Deller <deller@gmx.de>   *	Copyright (C) 2001-2002 Thomas Bogendoerfer <tsbogend@alpha.franken.de>   *    * TODO: @@ -28,9 +28,9 @@  #include <asm/cacheflush.h>  #include <asm/grfioctl.h> -#include "../sticore.h" +#include "../fbdev/sticore.h" -#define STI_DRIVERVERSION "Version 0.9a" +#define STI_DRIVERVERSION "Version 0.9b"  static struct sti_struct *default_sti __read_mostly; @@ -73,28 +73,34 @@ static const struct sti_init_flags default_init_flags = {  static int sti_init_graph(struct sti_struct *sti)  { -	struct sti_init_inptr_ext inptr_ext = { 0, }; -	struct sti_init_inptr inptr = { -		.text_planes	= 3, /* # of text planes (max 3 for STI) */ -		.ext_ptr	= STI_PTR(&inptr_ext) -	}; -	struct sti_init_outptr outptr = { 0, }; +	struct sti_init_inptr *inptr = &sti->sti_data->init_inptr; +	struct sti_init_inptr_ext *inptr_ext = &sti->sti_data->init_inptr_ext; +	struct sti_init_outptr *outptr = &sti->sti_data->init_outptr;  	unsigned long flags; -	int ret; +	int ret, err;  	spin_lock_irqsave(&sti->lock, flags); -	ret = STI_CALL(sti->init_graph, &default_init_flags, &inptr, -		&outptr, sti->glob_cfg); +	memset(inptr, 0, sizeof(*inptr)); +	inptr->text_planes = 3; /* # of text planes (max 3 for STI) */ +	memset(inptr_ext, 0, sizeof(*inptr_ext)); +	inptr->ext_ptr = STI_PTR(inptr_ext); +	outptr->errno = 0; + +	ret = sti_call(sti, sti->init_graph, &default_init_flags, inptr, +		outptr, sti->glob_cfg); + +	if (ret >= 0) +		sti->text_planes = outptr->text_planes; +	err = outptr->errno;  	spin_unlock_irqrestore(&sti->lock, flags);  	if (ret < 0) { -		printk(KERN_ERR "STI init_graph failed (ret %d, errno %d)\n",ret,outptr.errno); +		pr_err("STI init_graph failed (ret %d, errno %d)\n", ret, err);  		return -1;  	} -	sti->text_planes = outptr.text_planes;  	return 0;  } @@ -104,16 +110,18 @@ static const struct sti_conf_flags default_conf_flags = {  static void sti_inq_conf(struct sti_struct *sti)  { -	struct sti_conf_inptr inptr = { 0, }; +	struct sti_conf_inptr *inptr = &sti->sti_data->inq_inptr; +	struct sti_conf_outptr *outptr = &sti->sti_data->inq_outptr;  	unsigned long flags;  	s32 ret; -	sti->outptr.ext_ptr = STI_PTR(&sti->outptr_ext); +	outptr->ext_ptr = STI_PTR(&sti->sti_data->inq_outptr_ext);  	do {  		spin_lock_irqsave(&sti->lock, flags); -		ret = STI_CALL(sti->inq_conf, &default_conf_flags, -			&inptr, &sti->outptr, sti->glob_cfg); +		memset(inptr, 0, sizeof(*inptr)); +		ret = sti_call(sti, sti->inq_conf, &default_conf_flags, +			inptr, outptr, sti->glob_cfg);  		spin_unlock_irqrestore(&sti->lock, flags);  	} while (ret == 1);  } @@ -126,7 +134,8 @@ static const struct sti_font_flags default_font_flags = {  void  sti_putc(struct sti_struct *sti, int c, int y, int x)  { -	struct sti_font_inptr inptr = { +	struct sti_font_inptr *inptr = &sti->sti_data->font_inptr; +	struct sti_font_inptr inptr_default = {  		.font_start_addr= STI_PTR(sti->font->raw),  		.index		= c_index(sti, c),  		.fg_color	= c_fg(sti, c), @@ -134,14 +143,15 @@ sti_putc(struct sti_struct *sti, int c, int y, int x)  		.dest_x		= x * sti->font_width,  		.dest_y		= y * sti->font_height,  	}; -	struct sti_font_outptr outptr = { 0, }; +	struct sti_font_outptr *outptr = &sti->sti_data->font_outptr;  	s32 ret;  	unsigned long flags;  	do {  		spin_lock_irqsave(&sti->lock, flags); -		ret = STI_CALL(sti->font_unpmv, &default_font_flags, -			&inptr, &outptr, sti->glob_cfg); +		*inptr = inptr_default; +		ret = sti_call(sti, sti->font_unpmv, &default_font_flags, +			inptr, outptr, sti->glob_cfg);  		spin_unlock_irqrestore(&sti->lock, flags);  	} while (ret == 1);  } @@ -156,7 +166,8 @@ void  sti_set(struct sti_struct *sti, int src_y, int src_x,  	int height, int width, u8 color)  { -	struct sti_blkmv_inptr inptr = { +	struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr; +	struct sti_blkmv_inptr inptr_default = {  		.fg_color	= color,  		.bg_color	= color,  		.src_x		= src_x, @@ -166,14 +177,15 @@ sti_set(struct sti_struct *sti, int src_y, int src_x,  		.width		= width,  		.height		= height,  	}; -	struct sti_blkmv_outptr outptr = { 0, }; +	struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;  	s32 ret;  	unsigned long flags;  	do {  		spin_lock_irqsave(&sti->lock, flags); -		ret = STI_CALL(sti->block_move, &clear_blkmv_flags, -			&inptr, &outptr, sti->glob_cfg); +		*inptr = inptr_default; +		ret = sti_call(sti, sti->block_move, &clear_blkmv_flags, +			inptr, outptr, sti->glob_cfg);  		spin_unlock_irqrestore(&sti->lock, flags);  	} while (ret == 1);  } @@ -182,7 +194,8 @@ void  sti_clear(struct sti_struct *sti, int src_y, int src_x,  	  int height, int width, int c)  { -	struct sti_blkmv_inptr inptr = { +	struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr; +	struct sti_blkmv_inptr inptr_default = {  		.fg_color	= c_fg(sti, c),  		.bg_color	= c_bg(sti, c),  		.src_x		= src_x * sti->font_width, @@ -192,14 +205,15 @@ sti_clear(struct sti_struct *sti, int src_y, int src_x,  		.width		= width * sti->font_width,  		.height		= height* sti->font_height,  	}; -	struct sti_blkmv_outptr outptr = { 0, }; +	struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;  	s32 ret;  	unsigned long flags;  	do {  		spin_lock_irqsave(&sti->lock, flags); -		ret = STI_CALL(sti->block_move, &clear_blkmv_flags, -			&inptr, &outptr, sti->glob_cfg); +		*inptr = inptr_default; +		ret = sti_call(sti, sti->block_move, &clear_blkmv_flags, +			inptr, outptr, sti->glob_cfg);  		spin_unlock_irqrestore(&sti->lock, flags);  	} while (ret == 1);  } @@ -212,7 +226,8 @@ void  sti_bmove(struct sti_struct *sti, int src_y, int src_x,  	  int dst_y, int dst_x, int height, int width)  { -	struct sti_blkmv_inptr inptr = { +	struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr; +	struct sti_blkmv_inptr inptr_default = {  		.src_x		= src_x * sti->font_width,  		.src_y		= src_y * sti->font_height,  		.dest_x		= dst_x * sti->font_width, @@ -220,14 +235,15 @@ sti_bmove(struct sti_struct *sti, int src_y, int src_x,  		.width		= width * sti->font_width,  		.height		= height* sti->font_height,  	}; -	struct sti_blkmv_outptr outptr = { 0, }; +	struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr;  	s32 ret;  	unsigned long flags;  	do {  		spin_lock_irqsave(&sti->lock, flags); -		ret = STI_CALL(sti->block_move, &default_blkmv_flags, -			&inptr, &outptr, sti->glob_cfg); +		*inptr = inptr_default; +		ret = sti_call(sti, sti->block_move, &default_blkmv_flags, +			inptr, outptr, sti->glob_cfg);  		spin_unlock_irqrestore(&sti->lock, flags);  	} while (ret == 1);  } @@ -284,7 +300,7 @@ __setup("sti=", sti_setup); -static char *font_name[MAX_STI_ROMS] = { "VGA8x16", }; +static char *font_name[MAX_STI_ROMS];  static int font_index[MAX_STI_ROMS],  	   font_height[MAX_STI_ROMS],  	   font_width[MAX_STI_ROMS]; @@ -389,10 +405,10 @@ static void sti_dump_outptr(struct sti_struct *sti)  		"%d used bits\n"  		"%d planes\n"  		"attributes %08x\n", -		 sti->outptr.bits_per_pixel, -		 sti->outptr.bits_used, -		 sti->outptr.planes, -		 sti->outptr.attributes)); +		 sti->sti_data->inq_outptr.bits_per_pixel, +		 sti->sti_data->inq_outptr.bits_used, +		 sti->sti_data->inq_outptr.planes, +		 sti->sti_data->inq_outptr.attributes));  }  static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, @@ -402,24 +418,21 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,  	struct sti_glob_cfg_ext *glob_cfg_ext;  	void *save_addr;  	void *sti_mem_addr; -	const int save_addr_size = 1024;	/* XXX */ -	int i; +	int i, size; -	if (!sti->sti_mem_request) +	if (sti->sti_mem_request < 256)  		sti->sti_mem_request = 256; /* STI default */ -	glob_cfg = kzalloc(sizeof(*sti->glob_cfg), GFP_KERNEL); -	glob_cfg_ext = kzalloc(sizeof(*glob_cfg_ext), GFP_KERNEL); -	save_addr = kzalloc(save_addr_size, GFP_KERNEL); -	sti_mem_addr = kzalloc(sti->sti_mem_request, GFP_KERNEL); +	size = sizeof(struct sti_all_data) + sti->sti_mem_request - 256; -	if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) { -		kfree(glob_cfg); -		kfree(glob_cfg_ext); -		kfree(save_addr); -		kfree(sti_mem_addr); +	sti->sti_data = kzalloc(size, STI_LOWMEM); +	if (!sti->sti_data)  		return -ENOMEM; -	} + +	glob_cfg	= &sti->sti_data->glob_cfg; +	glob_cfg_ext	= &sti->sti_data->glob_cfg_ext; +	save_addr	= &sti->sti_data->save_addr; +	sti_mem_addr	= &sti->sti_data->sti_mem_addr;  	glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext);  	glob_cfg->save_addr = STI_PTR(save_addr); @@ -475,32 +488,31 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address,  	return 0;  } -#ifdef CONFIG_FB +#ifdef CONFIG_FONT_SUPPORT  static struct sti_cooked_font *  sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name)  { -	const struct font_desc *fbfont; +	const struct font_desc *fbfont = NULL;  	unsigned int size, bpc;  	void *dest;  	struct sti_rom_font *nf;  	struct sti_cooked_font *cooked_font; -	if (!fbfont_name || !strlen(fbfont_name)) -		return NULL; -	fbfont = find_font(fbfont_name); +	if (fbfont_name && strlen(fbfont_name)) +		fbfont = find_font(fbfont_name);  	if (!fbfont)  		fbfont = get_default_font(1024,768, ~(u32)0, ~(u32)0);  	if (!fbfont)  		return NULL; -	DPRINTK((KERN_DEBUG "selected %dx%d fb-font %s\n", -			fbfont->width, fbfont->height, fbfont->name)); +	pr_info("STI selected %dx%d framebuffer font %s for sticon\n", +			fbfont->width, fbfont->height, fbfont->name);  	bpc = ((fbfont->width+7)/8) * fbfont->height;   	size = bpc * 256;  	size += sizeof(struct sti_rom_font); -	nf = kzalloc(size, GFP_KERNEL); +	nf = kzalloc(size, STI_LOWMEM);  	if (!nf)  		return NULL; @@ -637,7 +649,7 @@ static void *sti_bmode_font_raw(struct sti_cooked_font *f)  	unsigned char *n, *p, *q;  	int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font); -	n = kzalloc (4*size, GFP_KERNEL); +	n = kzalloc(4*size, STI_LOWMEM);  	if (!n)  		return NULL;  	p = n + 3; @@ -673,7 +685,7 @@ static struct sti_rom *sti_get_bmode_rom (unsigned long address)  	sti_bmode_rom_copy(address + BMODE_LAST_ADDR_OFFS, sizeof(size), &size);  	size = (size+3) / 4; -	raw = kmalloc(size, GFP_KERNEL); +	raw = kmalloc(size, STI_LOWMEM);  	if (raw) {  		sti_bmode_rom_copy(address, size, raw);  		memmove (&raw->res004, &raw->type[0], 0x3c); @@ -707,7 +719,7 @@ static struct sti_rom *sti_get_wmode_rom(unsigned long address)  	/* read the ROM size directly from the struct in ROM */   	size = gsc_readl(address + offsetof(struct sti_rom,last_addr)); -	raw = kmalloc(size, GFP_KERNEL); +	raw = kmalloc(size, STI_LOWMEM);  	if (raw)  		sti_rom_copy(address, size, raw); @@ -743,6 +755,10 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti,  	address = (unsigned long) STI_PTR(raw); +	pr_info("STI ROM supports 32 %sbit firmware functions.\n", +		raw->alt_code_type == ALT_CODE_TYPE_PA_RISC_64 +		? "and 64 " : ""); +  	sti->font_unpmv = address + (raw->font_unpmv & 0x03ffffff);  	sti->block_move = address + (raw->block_move & 0x03ffffff);  	sti->init_graph = address + (raw->init_graph & 0x03ffffff); @@ -901,7 +917,8 @@ test_rom:  	sti_dump_globcfg(sti->glob_cfg, sti->sti_mem_request);  	sti_dump_outptr(sti); -	printk(KERN_INFO "    graphics card name: %s\n", sti->outptr.dev_name ); +	pr_info("    graphics card name: %s\n", +		sti->sti_data->inq_outptr.dev_name);  	sti_roms[num_sti_roms] = sti;  	num_sti_roms++; @@ -1073,6 +1090,29 @@ struct sti_struct * sti_get_rom(unsigned int index)  }  EXPORT_SYMBOL(sti_get_rom); + +int sti_call(const struct sti_struct *sti, unsigned long func, +		const void *flags, void *inptr, void *outptr, +		struct sti_glob_cfg *glob_cfg) +{ +	unsigned long _flags = STI_PTR(flags); +	unsigned long _inptr = STI_PTR(inptr); +	unsigned long _outptr = STI_PTR(outptr); +	unsigned long _glob_cfg = STI_PTR(glob_cfg); +	int ret; + +#ifdef CONFIG_64BIT +	/* Check for overflow when using 32bit STI on 64bit kernel. */ +	if (WARN_ONCE(_flags>>32 || _inptr>>32 || _outptr>>32 || _glob_cfg>>32, +			"Out of 32bit-range pointers!")) +		return -1; +#endif + +	ret = pdc_sti_call(func, _flags, _inptr, _outptr, _glob_cfg); + +	return ret; +} +  MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer");  MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines");  MODULE_LICENSE("GPL v2"); diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 9d8feac6763..6e6aa704fe8 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -87,7 +87,8 @@ static void vgacon_save_screen(struct vc_data *c);  static int vgacon_scroll(struct vc_data *c, int t, int b, int dir,  			 int lines);  static void vgacon_invert_region(struct vc_data *c, u16 * p, int count); -static unsigned long vgacon_uni_pagedir[2]; +static struct uni_pagedir *vgacon_uni_pagedir; +static int vgacon_refcount;  /* Description of the hardware situation */  static int		vga_init_done		__read_mostly; @@ -553,7 +554,7 @@ static const char *vgacon_startup(void)  static void vgacon_init(struct vc_data *c, int init)  { -	unsigned long p; +	struct uni_pagedir *p;  	/*  	 * We cannot be loaded as a module, therefore init is always 1, @@ -575,12 +576,12 @@ static void vgacon_init(struct vc_data *c, int init)  	if (vga_512_chars)  		c->vc_hi_font_mask = 0x0800;  	p = *c->vc_uni_pagedir_loc; -	if (c->vc_uni_pagedir_loc == &c->vc_uni_pagedir || -	    !--c->vc_uni_pagedir_loc[1]) +	if (c->vc_uni_pagedir_loc != &vgacon_uni_pagedir) {  		con_free_unimap(c); -	c->vc_uni_pagedir_loc = vgacon_uni_pagedir; -	vgacon_uni_pagedir[1]++; -	if (!vgacon_uni_pagedir[0] && p) +		c->vc_uni_pagedir_loc = &vgacon_uni_pagedir; +		vgacon_refcount++; +	} +	if (!vgacon_uni_pagedir && p)  		con_set_default_unimap(c);  	/* Only set the default if the user didn't deliberately override it */ @@ -597,7 +598,7 @@ static void vgacon_deinit(struct vc_data *c)  		vga_set_mem_top(c);  	} -	if (!--vgacon_uni_pagedir[1]) +	if (!--vgacon_refcount)  		con_free_unimap(c);  	c->vc_uni_pagedir_loc = &c->vc_uni_pagedir;  	con_set_default_unimap(c); @@ -1440,5 +1441,6 @@ const struct consw vga_con = {  	.con_build_attr = vgacon_build_attr,  	.con_invert_region = vgacon_invert_region,  }; +EXPORT_SYMBOL(vga_con);  MODULE_LICENSE("GPL"); diff --git a/drivers/video/exynos/exynos_dp_core.c b/drivers/video/exynos/exynos_dp_core.c deleted file mode 100644 index 12bbede3b09..00000000000 --- a/drivers/video/exynos/exynos_dp_core.c +++ /dev/null @@ -1,1214 +0,0 @@ -/* - * Samsung SoC DP (Display Port) interface driver. - * - * Copyright (C) 2012 Samsung Electronics Co., Ltd. - * Author: Jingoo Han <jg1.han@samsung.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/of.h> - -#include <video/exynos_dp.h> - -#include "exynos_dp_core.h" - -static int exynos_dp_init_dp(struct exynos_dp_device *dp) -{ -	exynos_dp_reset(dp); - -	exynos_dp_swreset(dp); - -	exynos_dp_init_analog_param(dp); -	exynos_dp_init_interrupt(dp); - -	/* SW defined function Normal operation */ -	exynos_dp_enable_sw_function(dp); - -	exynos_dp_config_interrupt(dp); -	exynos_dp_init_analog_func(dp); - -	exynos_dp_init_hpd(dp); -	exynos_dp_init_aux(dp); - -	return 0; -} - -static int exynos_dp_detect_hpd(struct exynos_dp_device *dp) -{ -	int timeout_loop = 0; - -	while (exynos_dp_get_plug_in_status(dp) != 0) { -		timeout_loop++; -		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { -			dev_err(dp->dev, "failed to get hpd plug status\n"); -			return -ETIMEDOUT; -		} -		usleep_range(10, 11); -	} - -	return 0; -} - -static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data) -{ -	int i; -	unsigned char sum = 0; - -	for (i = 0; i < EDID_BLOCK_LENGTH; i++) -		sum = sum + edid_data[i]; - -	return sum; -} - -static int exynos_dp_read_edid(struct exynos_dp_device *dp) -{ -	unsigned char edid[EDID_BLOCK_LENGTH * 2]; -	unsigned int extend_block = 0; -	unsigned char sum; -	unsigned char test_vector; -	int retval; - -	/* -	 * EDID device address is 0x50. -	 * However, if necessary, you must have set upper address -	 * into E-EDID in I2C device, 0x30. -	 */ - -	/* Read Extension Flag, Number of 128-byte EDID extension blocks */ -	retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR, -				EDID_EXTENSION_FLAG, -				&extend_block); -	if (retval) -		return retval; - -	if (extend_block > 0) { -		dev_dbg(dp->dev, "EDID data includes a single extension!\n"); - -		/* Read EDID data */ -		retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR, -						EDID_HEADER_PATTERN, -						EDID_BLOCK_LENGTH, -						&edid[EDID_HEADER_PATTERN]); -		if (retval != 0) { -			dev_err(dp->dev, "EDID Read failed!\n"); -			return -EIO; -		} -		sum = exynos_dp_calc_edid_check_sum(edid); -		if (sum != 0) { -			dev_err(dp->dev, "EDID bad checksum!\n"); -			return -EIO; -		} - -		/* Read additional EDID data */ -		retval = exynos_dp_read_bytes_from_i2c(dp, -				I2C_EDID_DEVICE_ADDR, -				EDID_BLOCK_LENGTH, -				EDID_BLOCK_LENGTH, -				&edid[EDID_BLOCK_LENGTH]); -		if (retval != 0) { -			dev_err(dp->dev, "EDID Read failed!\n"); -			return -EIO; -		} -		sum = exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]); -		if (sum != 0) { -			dev_err(dp->dev, "EDID bad checksum!\n"); -			return -EIO; -		} - -		exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_TEST_REQUEST, -					&test_vector); -		if (test_vector & DPCD_TEST_EDID_READ) { -			exynos_dp_write_byte_to_dpcd(dp, -				DPCD_ADDR_TEST_EDID_CHECKSUM, -				edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]); -			exynos_dp_write_byte_to_dpcd(dp, -				DPCD_ADDR_TEST_RESPONSE, -				DPCD_TEST_EDID_CHECKSUM_WRITE); -		} -	} else { -		dev_info(dp->dev, "EDID data does not include any extensions.\n"); - -		/* Read EDID data */ -		retval = exynos_dp_read_bytes_from_i2c(dp, -				I2C_EDID_DEVICE_ADDR, -				EDID_HEADER_PATTERN, -				EDID_BLOCK_LENGTH, -				&edid[EDID_HEADER_PATTERN]); -		if (retval != 0) { -			dev_err(dp->dev, "EDID Read failed!\n"); -			return -EIO; -		} -		sum = exynos_dp_calc_edid_check_sum(edid); -		if (sum != 0) { -			dev_err(dp->dev, "EDID bad checksum!\n"); -			return -EIO; -		} - -		exynos_dp_read_byte_from_dpcd(dp, -			DPCD_ADDR_TEST_REQUEST, -			&test_vector); -		if (test_vector & DPCD_TEST_EDID_READ) { -			exynos_dp_write_byte_to_dpcd(dp, -				DPCD_ADDR_TEST_EDID_CHECKSUM, -				edid[EDID_CHECKSUM]); -			exynos_dp_write_byte_to_dpcd(dp, -				DPCD_ADDR_TEST_RESPONSE, -				DPCD_TEST_EDID_CHECKSUM_WRITE); -		} -	} - -	dev_err(dp->dev, "EDID Read success!\n"); -	return 0; -} - -static int exynos_dp_handle_edid(struct exynos_dp_device *dp) -{ -	u8 buf[12]; -	int i; -	int retval; - -	/* Read DPCD DPCD_ADDR_DPCD_REV~RECEIVE_PORT1_CAP_1 */ -	retval = exynos_dp_read_bytes_from_dpcd(dp, DPCD_ADDR_DPCD_REV, -				12, buf); -	if (retval) -		return retval; - -	/* Read EDID */ -	for (i = 0; i < 3; i++) { -		retval = exynos_dp_read_edid(dp); -		if (!retval) -			break; -	} - -	return retval; -} - -static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp, -						bool enable) -{ -	u8 data; - -	exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET, &data); - -	if (enable) -		exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET, -			DPCD_ENHANCED_FRAME_EN | -			DPCD_LANE_COUNT_SET(data)); -	else -		exynos_dp_write_byte_to_dpcd(dp, DPCD_ADDR_LANE_COUNT_SET, -			DPCD_LANE_COUNT_SET(data)); -} - -static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp) -{ -	u8 data; -	int retval; - -	exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data); -	retval = DPCD_ENHANCED_FRAME_CAP(data); - -	return retval; -} - -static void exynos_dp_set_enhanced_mode(struct exynos_dp_device *dp) -{ -	u8 data; - -	data = exynos_dp_is_enhanced_mode_available(dp); -	exynos_dp_enable_rx_to_enhanced_mode(dp, data); -	exynos_dp_enable_enhanced_mode(dp, data); -} - -static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp) -{ -	exynos_dp_set_training_pattern(dp, DP_NONE); - -	exynos_dp_write_byte_to_dpcd(dp, -		DPCD_ADDR_TRAINING_PATTERN_SET, -		DPCD_TRAINING_PATTERN_DISABLED); -} - -static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp, -					int pre_emphasis, int lane) -{ -	switch (lane) { -	case 0: -		exynos_dp_set_lane0_pre_emphasis(dp, pre_emphasis); -		break; -	case 1: -		exynos_dp_set_lane1_pre_emphasis(dp, pre_emphasis); -		break; - -	case 2: -		exynos_dp_set_lane2_pre_emphasis(dp, pre_emphasis); -		break; - -	case 3: -		exynos_dp_set_lane3_pre_emphasis(dp, pre_emphasis); -		break; -	} -} - -static int exynos_dp_link_start(struct exynos_dp_device *dp) -{ -	u8 buf[4]; -	int lane, lane_count, pll_tries, retval; - -	lane_count = dp->link_train.lane_count; - -	dp->link_train.lt_state = CLOCK_RECOVERY; -	dp->link_train.eq_loop = 0; - -	for (lane = 0; lane < lane_count; lane++) -		dp->link_train.cr_loop[lane] = 0; - -	/* Set link rate and count as you want to establish*/ -	exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate); -	exynos_dp_set_lane_count(dp, dp->link_train.lane_count); - -	/* Setup RX configuration */ -	buf[0] = dp->link_train.link_rate; -	buf[1] = dp->link_train.lane_count; -	retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_LINK_BW_SET, -				2, buf); -	if (retval) -		return retval; - -	/* Set TX pre-emphasis to minimum */ -	for (lane = 0; lane < lane_count; lane++) -		exynos_dp_set_lane_lane_pre_emphasis(dp, -			PRE_EMPHASIS_LEVEL_0, lane); - -	/* Wait for PLL lock */ -	pll_tries = 0; -	while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { -		if (pll_tries == DP_TIMEOUT_LOOP_COUNT) { -			dev_err(dp->dev, "Wait for PLL lock timed out\n"); -			return -ETIMEDOUT; -		} - -		pll_tries++; -		usleep_range(90, 120); -	} - -	/* Set training pattern 1 */ -	exynos_dp_set_training_pattern(dp, TRAINING_PTN1); - -	/* Set RX training pattern */ -	retval = exynos_dp_write_byte_to_dpcd(dp, -			DPCD_ADDR_TRAINING_PATTERN_SET, -			DPCD_SCRAMBLING_DISABLED | DPCD_TRAINING_PATTERN_1); -	if (retval) -		return retval; - -	for (lane = 0; lane < lane_count; lane++) -		buf[lane] = DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0 | -			    DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0; - -	retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET, -			lane_count, buf); - -	return retval; -} - -static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane) -{ -	int shift = (lane & 1) * 4; -	u8 link_value = link_status[lane>>1]; - -	return (link_value >> shift) & 0xf; -} - -static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count) -{ -	int lane; -	u8 lane_status; - -	for (lane = 0; lane < lane_count; lane++) { -		lane_status = exynos_dp_get_lane_status(link_status, lane); -		if ((lane_status & DPCD_LANE_CR_DONE) == 0) -			return -EINVAL; -	} -	return 0; -} - -static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align, -				int lane_count) -{ -	int lane; -	u8 lane_status; - -	if ((link_align & DPCD_INTERLANE_ALIGN_DONE) == 0) -		return -EINVAL; - -	for (lane = 0; lane < lane_count; lane++) { -		lane_status = exynos_dp_get_lane_status(link_status, lane); -		lane_status &= DPCD_CHANNEL_EQ_BITS; -		if (lane_status != DPCD_CHANNEL_EQ_BITS) -			return -EINVAL; -	} - -	return 0; -} - -static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2], -							int lane) -{ -	int shift = (lane & 1) * 4; -	u8 link_value = adjust_request[lane>>1]; - -	return (link_value >> shift) & 0x3; -} - -static unsigned char exynos_dp_get_adjust_request_pre_emphasis( -					u8 adjust_request[2], -					int lane) -{ -	int shift = (lane & 1) * 4; -	u8 link_value = adjust_request[lane>>1]; - -	return ((link_value >> shift) & 0xc) >> 2; -} - -static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp, -					u8 training_lane_set, int lane) -{ -	switch (lane) { -	case 0: -		exynos_dp_set_lane0_link_training(dp, training_lane_set); -		break; -	case 1: -		exynos_dp_set_lane1_link_training(dp, training_lane_set); -		break; - -	case 2: -		exynos_dp_set_lane2_link_training(dp, training_lane_set); -		break; - -	case 3: -		exynos_dp_set_lane3_link_training(dp, training_lane_set); -		break; -	} -} - -static unsigned int exynos_dp_get_lane_link_training( -				struct exynos_dp_device *dp, -				int lane) -{ -	u32 reg; - -	switch (lane) { -	case 0: -		reg = exynos_dp_get_lane0_link_training(dp); -		break; -	case 1: -		reg = exynos_dp_get_lane1_link_training(dp); -		break; -	case 2: -		reg = exynos_dp_get_lane2_link_training(dp); -		break; -	case 3: -		reg = exynos_dp_get_lane3_link_training(dp); -		break; -	default: -		WARN_ON(1); -		return 0; -	} - -	return reg; -} - -static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp) -{ -	exynos_dp_training_pattern_dis(dp); -	exynos_dp_set_enhanced_mode(dp); - -	dp->link_train.lt_state = FAILED; -} - -static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp, -					u8 adjust_request[2]) -{ -	int lane, lane_count; -	u8 voltage_swing, pre_emphasis, training_lane; - -	lane_count = dp->link_train.lane_count; -	for (lane = 0; lane < lane_count; lane++) { -		voltage_swing = exynos_dp_get_adjust_request_voltage( -						adjust_request, lane); -		pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( -						adjust_request, lane); -		training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) | -				DPCD_PRE_EMPHASIS_SET(pre_emphasis); - -		if (voltage_swing == VOLTAGE_LEVEL_3) -			training_lane |= DPCD_MAX_SWING_REACHED; -		if (pre_emphasis == PRE_EMPHASIS_LEVEL_3) -			training_lane |= DPCD_MAX_PRE_EMPHASIS_REACHED; - -		dp->link_train.training_lane[lane] = training_lane; -	} -} - -static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp) -{ -	int lane, lane_count, retval; -	u8 voltage_swing, pre_emphasis, training_lane; -	u8 link_status[2], adjust_request[2]; - -	usleep_range(100, 101); - -	lane_count = dp->link_train.lane_count; - -	retval =  exynos_dp_read_bytes_from_dpcd(dp, -			DPCD_ADDR_LANE0_1_STATUS, 2, link_status); -	if (retval) -		return retval; - -	retval =  exynos_dp_read_bytes_from_dpcd(dp, -			DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request); -	if (retval) -		return retval; - -	if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) { -		/* set training pattern 2 for EQ */ -		exynos_dp_set_training_pattern(dp, TRAINING_PTN2); - -		retval = exynos_dp_write_byte_to_dpcd(dp, -				DPCD_ADDR_TRAINING_PATTERN_SET, -				DPCD_SCRAMBLING_DISABLED | -				DPCD_TRAINING_PATTERN_2); -		if (retval) -			return retval; - -		dev_info(dp->dev, "Link Training Clock Recovery success\n"); -		dp->link_train.lt_state = EQUALIZER_TRAINING; -	} else { -		for (lane = 0; lane < lane_count; lane++) { -			training_lane = exynos_dp_get_lane_link_training( -							dp, lane); -			voltage_swing = exynos_dp_get_adjust_request_voltage( -							adjust_request, lane); -			pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( -							adjust_request, lane); - -			if (DPCD_VOLTAGE_SWING_GET(training_lane) == -					voltage_swing && -			    DPCD_PRE_EMPHASIS_GET(training_lane) == -					pre_emphasis) -				dp->link_train.cr_loop[lane]++; - -			if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP || -			    voltage_swing == VOLTAGE_LEVEL_3 || -			    pre_emphasis == PRE_EMPHASIS_LEVEL_3) { -				dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n", -					dp->link_train.cr_loop[lane], -					voltage_swing, pre_emphasis); -				exynos_dp_reduce_link_rate(dp); -				return -EIO; -			} -		} -	} - -	exynos_dp_get_adjust_training_lane(dp, adjust_request); - -	for (lane = 0; lane < lane_count; lane++) -		exynos_dp_set_lane_link_training(dp, -			dp->link_train.training_lane[lane], lane); - -	retval = exynos_dp_write_bytes_to_dpcd(dp, -			DPCD_ADDR_TRAINING_LANE0_SET, lane_count, -			dp->link_train.training_lane); -	if (retval) -		return retval; - -	return retval; -} - -static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp) -{ -	int lane, lane_count, retval; -	u32 reg; -	u8 link_align, link_status[2], adjust_request[2]; - -	usleep_range(400, 401); - -	lane_count = dp->link_train.lane_count; - -	retval = exynos_dp_read_bytes_from_dpcd(dp, -			DPCD_ADDR_LANE0_1_STATUS, 2, link_status); -	if (retval) -		return retval; - -	if (exynos_dp_clock_recovery_ok(link_status, lane_count)) { -		exynos_dp_reduce_link_rate(dp); -		return -EIO; -	} - -	retval = exynos_dp_read_bytes_from_dpcd(dp, -			DPCD_ADDR_ADJUST_REQUEST_LANE0_1, 2, adjust_request); -	if (retval) -		return retval; - -	retval = exynos_dp_read_byte_from_dpcd(dp, -			DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED, &link_align); -	if (retval) -		return retval; - -	exynos_dp_get_adjust_training_lane(dp, adjust_request); - -	if (!exynos_dp_channel_eq_ok(link_status, link_align, lane_count)) { -		/* traing pattern Set to Normal */ -		exynos_dp_training_pattern_dis(dp); - -		dev_info(dp->dev, "Link Training success!\n"); - -		exynos_dp_get_link_bandwidth(dp, ®); -		dp->link_train.link_rate = reg; -		dev_dbg(dp->dev, "final bandwidth = %.2x\n", -			dp->link_train.link_rate); - -		exynos_dp_get_lane_count(dp, ®); -		dp->link_train.lane_count = reg; -		dev_dbg(dp->dev, "final lane count = %.2x\n", -			dp->link_train.lane_count); - -		/* set enhanced mode if available */ -		exynos_dp_set_enhanced_mode(dp); -		dp->link_train.lt_state = FINISHED; - -		return 0; -	} - -	/* not all locked */ -	dp->link_train.eq_loop++; - -	if (dp->link_train.eq_loop > MAX_EQ_LOOP) { -		dev_err(dp->dev, "EQ Max loop\n"); -		exynos_dp_reduce_link_rate(dp); -		return -EIO; -	} - -	for (lane = 0; lane < lane_count; lane++) -		exynos_dp_set_lane_link_training(dp, -			dp->link_train.training_lane[lane], lane); - -	retval = exynos_dp_write_bytes_to_dpcd(dp, DPCD_ADDR_TRAINING_LANE0_SET, -			lane_count, dp->link_train.training_lane); - -	return retval; -} - -static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp, -					u8 *bandwidth) -{ -	u8 data; - -	/* -	 * For DP rev.1.1, Maximum link rate of Main Link lanes -	 * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps -	 */ -	exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LINK_RATE, &data); -	*bandwidth = data; -} - -static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp, -					u8 *lane_count) -{ -	u8 data; - -	/* -	 * For DP rev.1.1, Maximum number of Main Link lanes -	 * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes -	 */ -	exynos_dp_read_byte_from_dpcd(dp, DPCD_ADDR_MAX_LANE_COUNT, &data); -	*lane_count = DPCD_MAX_LANE_COUNT(data); -} - -static void exynos_dp_init_training(struct exynos_dp_device *dp, -			enum link_lane_count_type max_lane, -			enum link_rate_type max_rate) -{ -	/* -	 * MACRO_RST must be applied after the PLL_LOCK to avoid -	 * the DP inter pair skew issue for at least 10 us -	 */ -	exynos_dp_reset_macro(dp); - -	/* Initialize by reading RX's DPCD */ -	exynos_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate); -	exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count); - -	if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) && -	   (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) { -		dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n", -			dp->link_train.link_rate); -		dp->link_train.link_rate = LINK_RATE_1_62GBPS; -	} - -	if (dp->link_train.lane_count == 0) { -		dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n", -			dp->link_train.lane_count); -		dp->link_train.lane_count = (u8)LANE_COUNT1; -	} - -	/* Setup TX lane count & rate */ -	if (dp->link_train.lane_count > max_lane) -		dp->link_train.lane_count = max_lane; -	if (dp->link_train.link_rate > max_rate) -		dp->link_train.link_rate = max_rate; - -	/* All DP analog module power up */ -	exynos_dp_set_analog_power_down(dp, POWER_ALL, 0); -} - -static int exynos_dp_sw_link_training(struct exynos_dp_device *dp) -{ -	int retval = 0, training_finished = 0; - -	dp->link_train.lt_state = START; - -	/* Process here */ -	while (!retval && !training_finished) { -		switch (dp->link_train.lt_state) { -		case START: -			retval = exynos_dp_link_start(dp); -			if (retval) -				dev_err(dp->dev, "LT link start failed!\n"); -			break; -		case CLOCK_RECOVERY: -			retval = exynos_dp_process_clock_recovery(dp); -			if (retval) -				dev_err(dp->dev, "LT CR failed!\n"); -			break; -		case EQUALIZER_TRAINING: -			retval = exynos_dp_process_equalizer_training(dp); -			if (retval) -				dev_err(dp->dev, "LT EQ failed!\n"); -			break; -		case FINISHED: -			training_finished = 1; -			break; -		case FAILED: -			return -EREMOTEIO; -		} -	} -	if (retval) -		dev_err(dp->dev, "eDP link training failed (%d)\n", retval); - -	return retval; -} - -static int exynos_dp_set_link_train(struct exynos_dp_device *dp, -				u32 count, -				u32 bwtype) -{ -	int i; -	int retval; - -	for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) { -		exynos_dp_init_training(dp, count, bwtype); -		retval = exynos_dp_sw_link_training(dp); -		if (retval == 0) -			break; - -		usleep_range(100, 110); -	} - -	return retval; -} - -static int exynos_dp_config_video(struct exynos_dp_device *dp) -{ -	int retval = 0; -	int timeout_loop = 0; -	int done_count = 0; - -	exynos_dp_config_video_slave_mode(dp); - -	exynos_dp_set_video_color_format(dp); - -	if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { -		dev_err(dp->dev, "PLL is not locked yet.\n"); -		return -EINVAL; -	} - -	for (;;) { -		timeout_loop++; -		if (exynos_dp_is_slave_video_stream_clock_on(dp) == 0) -			break; -		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { -			dev_err(dp->dev, "Timeout of video streamclk ok\n"); -			return -ETIMEDOUT; -		} - -		usleep_range(1, 2); -	} - -	/* Set to use the register calculated M/N video */ -	exynos_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0); - -	/* For video bist, Video timing must be generated by register */ -	exynos_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE); - -	/* Disable video mute */ -	exynos_dp_enable_video_mute(dp, 0); - -	/* Configure video slave mode */ -	exynos_dp_enable_video_master(dp, 0); - -	/* Enable video */ -	exynos_dp_start_video(dp); - -	timeout_loop = 0; - -	for (;;) { -		timeout_loop++; -		if (exynos_dp_is_video_stream_on(dp) == 0) { -			done_count++; -			if (done_count > 10) -				break; -		} else if (done_count) { -			done_count = 0; -		} -		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { -			dev_err(dp->dev, "Timeout of video streamclk ok\n"); -			return -ETIMEDOUT; -		} - -		usleep_range(1000, 1001); -	} - -	if (retval != 0) -		dev_err(dp->dev, "Video stream is not detected!\n"); - -	return retval; -} - -static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable) -{ -	u8 data; - -	if (enable) { -		exynos_dp_enable_scrambling(dp); - -		exynos_dp_read_byte_from_dpcd(dp, -			DPCD_ADDR_TRAINING_PATTERN_SET, -			&data); -		exynos_dp_write_byte_to_dpcd(dp, -			DPCD_ADDR_TRAINING_PATTERN_SET, -			(u8)(data & ~DPCD_SCRAMBLING_DISABLED)); -	} else { -		exynos_dp_disable_scrambling(dp); - -		exynos_dp_read_byte_from_dpcd(dp, -			DPCD_ADDR_TRAINING_PATTERN_SET, -			&data); -		exynos_dp_write_byte_to_dpcd(dp, -			DPCD_ADDR_TRAINING_PATTERN_SET, -			(u8)(data | DPCD_SCRAMBLING_DISABLED)); -	} -} - -static irqreturn_t exynos_dp_irq_handler(int irq, void *arg) -{ -	struct exynos_dp_device *dp = arg; - -	enum dp_irq_type irq_type; - -	irq_type = exynos_dp_get_irq_type(dp); -	switch (irq_type) { -	case DP_IRQ_TYPE_HP_CABLE_IN: -		dev_dbg(dp->dev, "Received irq - cable in\n"); -		schedule_work(&dp->hotplug_work); -		exynos_dp_clear_hotplug_interrupts(dp); -		break; -	case DP_IRQ_TYPE_HP_CABLE_OUT: -		dev_dbg(dp->dev, "Received irq - cable out\n"); -		exynos_dp_clear_hotplug_interrupts(dp); -		break; -	case DP_IRQ_TYPE_HP_CHANGE: -		/* -		 * We get these change notifications once in a while, but there -		 * is nothing we can do with them. Just ignore it for now and -		 * only handle cable changes. -		 */ -		dev_dbg(dp->dev, "Received irq - hotplug change; ignoring.\n"); -		exynos_dp_clear_hotplug_interrupts(dp); -		break; -	default: -		dev_err(dp->dev, "Received irq - unknown type!\n"); -		break; -	} -	return IRQ_HANDLED; -} - -static void exynos_dp_hotplug(struct work_struct *work) -{ -	struct exynos_dp_device *dp; -	int ret; - -	dp = container_of(work, struct exynos_dp_device, hotplug_work); - -	ret = exynos_dp_detect_hpd(dp); -	if (ret) { -		/* Cable has been disconnected, we're done */ -		return; -	} - -	ret = exynos_dp_handle_edid(dp); -	if (ret) { -		dev_err(dp->dev, "unable to handle edid\n"); -		return; -	} - -	ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count, -					dp->video_info->link_rate); -	if (ret) { -		dev_err(dp->dev, "unable to do link train\n"); -		return; -	} - -	exynos_dp_enable_scramble(dp, 1); -	exynos_dp_enable_rx_to_enhanced_mode(dp, 1); -	exynos_dp_enable_enhanced_mode(dp, 1); - -	exynos_dp_set_lane_count(dp, dp->video_info->lane_count); -	exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate); - -	exynos_dp_init_video(dp); -	ret = exynos_dp_config_video(dp); -	if (ret) -		dev_err(dp->dev, "unable to config video\n"); -} - -#ifdef CONFIG_OF -static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev) -{ -	struct device_node *dp_node = dev->of_node; -	struct exynos_dp_platdata *pd; -	struct video_info *dp_video_config; - -	pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL); -	if (!pd) { -		dev_err(dev, "memory allocation for pdata failed\n"); -		return ERR_PTR(-ENOMEM); -	} -	dp_video_config = devm_kzalloc(dev, -				sizeof(*dp_video_config), GFP_KERNEL); - -	if (!dp_video_config) { -		dev_err(dev, "memory allocation for video config failed\n"); -		return ERR_PTR(-ENOMEM); -	} -	pd->video_info = dp_video_config; - -	dp_video_config->h_sync_polarity = -		of_property_read_bool(dp_node, "hsync-active-high"); - -	dp_video_config->v_sync_polarity = -		of_property_read_bool(dp_node, "vsync-active-high"); - -	dp_video_config->interlaced = -		of_property_read_bool(dp_node, "interlaced"); - -	if (of_property_read_u32(dp_node, "samsung,color-space", -				&dp_video_config->color_space)) { -		dev_err(dev, "failed to get color-space\n"); -		return ERR_PTR(-EINVAL); -	} - -	if (of_property_read_u32(dp_node, "samsung,dynamic-range", -				&dp_video_config->dynamic_range)) { -		dev_err(dev, "failed to get dynamic-range\n"); -		return ERR_PTR(-EINVAL); -	} - -	if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff", -				&dp_video_config->ycbcr_coeff)) { -		dev_err(dev, "failed to get ycbcr-coeff\n"); -		return ERR_PTR(-EINVAL); -	} - -	if (of_property_read_u32(dp_node, "samsung,color-depth", -				&dp_video_config->color_depth)) { -		dev_err(dev, "failed to get color-depth\n"); -		return ERR_PTR(-EINVAL); -	} - -	if (of_property_read_u32(dp_node, "samsung,link-rate", -				&dp_video_config->link_rate)) { -		dev_err(dev, "failed to get link-rate\n"); -		return ERR_PTR(-EINVAL); -	} - -	if (of_property_read_u32(dp_node, "samsung,lane-count", -				&dp_video_config->lane_count)) { -		dev_err(dev, "failed to get lane-count\n"); -		return ERR_PTR(-EINVAL); -	} - -	return pd; -} - -static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) -{ -	struct device_node *dp_phy_node = of_node_get(dp->dev->of_node); -	u32 phy_base; -	int ret = 0; - -	dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy"); -	if (!dp_phy_node) { -		dev_err(dp->dev, "could not find dptx-phy node\n"); -		return -ENODEV; -	} - -	if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) { -		dev_err(dp->dev, "failed to get reg for dptx-phy\n"); -		ret = -EINVAL; -		goto err; -	} - -	if (of_property_read_u32(dp_phy_node, "samsung,enable-mask", -				&dp->enable_mask)) { -		dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n"); -		ret = -EINVAL; -		goto err; -	} - -	dp->phy_addr = ioremap(phy_base, SZ_4); -	if (!dp->phy_addr) { -		dev_err(dp->dev, "failed to ioremap dp-phy\n"); -		ret = -ENOMEM; -		goto err; -	} - -err: -	of_node_put(dp_phy_node); - -	return ret; -} - -static void exynos_dp_phy_init(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = __raw_readl(dp->phy_addr); -	reg |= dp->enable_mask; -	__raw_writel(reg, dp->phy_addr); -} - -static void exynos_dp_phy_exit(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = __raw_readl(dp->phy_addr); -	reg &= ~(dp->enable_mask); -	__raw_writel(reg, dp->phy_addr); -} -#else -static struct exynos_dp_platdata *exynos_dp_dt_parse_pdata(struct device *dev) -{ -	return NULL; -} - -static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp) -{ -	return -EINVAL; -} - -static void exynos_dp_phy_init(struct exynos_dp_device *dp) -{ -	return; -} - -static void exynos_dp_phy_exit(struct exynos_dp_device *dp) -{ -	return; -} -#endif /* CONFIG_OF */ - -static int exynos_dp_probe(struct platform_device *pdev) -{ -	struct resource *res; -	struct exynos_dp_device *dp; -	struct exynos_dp_platdata *pdata; - -	int ret = 0; - -	dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device), -				GFP_KERNEL); -	if (!dp) { -		dev_err(&pdev->dev, "no memory for device data\n"); -		return -ENOMEM; -	} - -	dp->dev = &pdev->dev; - -	if (pdev->dev.of_node) { -		pdata = exynos_dp_dt_parse_pdata(&pdev->dev); -		if (IS_ERR(pdata)) -			return PTR_ERR(pdata); - -		ret = exynos_dp_dt_parse_phydata(dp); -		if (ret) -			return ret; -	} else { -		pdata = pdev->dev.platform_data; -		if (!pdata) { -			dev_err(&pdev->dev, "no platform data\n"); -			return -EINVAL; -		} -	} - -	dp->clock = devm_clk_get(&pdev->dev, "dp"); -	if (IS_ERR(dp->clock)) { -		dev_err(&pdev->dev, "failed to get clock\n"); -		return PTR_ERR(dp->clock); -	} - -	clk_prepare_enable(dp->clock); - -	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - -	dp->reg_base = devm_ioremap_resource(&pdev->dev, res); -	if (IS_ERR(dp->reg_base)) -		return PTR_ERR(dp->reg_base); - -	dp->irq = platform_get_irq(pdev, 0); -	if (dp->irq == -ENXIO) { -		dev_err(&pdev->dev, "failed to get irq\n"); -		return -ENODEV; -	} - -	INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug); - -	dp->video_info = pdata->video_info; - -	if (pdev->dev.of_node) { -		if (dp->phy_addr) -			exynos_dp_phy_init(dp); -	} else { -		if (pdata->phy_init) -			pdata->phy_init(); -	} - -	exynos_dp_init_dp(dp); - -	ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 0, -				"exynos-dp", dp); -	if (ret) { -		dev_err(&pdev->dev, "failed to request irq\n"); -		return ret; -	} - -	platform_set_drvdata(pdev, dp); - -	return 0; -} - -static int exynos_dp_remove(struct platform_device *pdev) -{ -	struct exynos_dp_platdata *pdata = pdev->dev.platform_data; -	struct exynos_dp_device *dp = platform_get_drvdata(pdev); - -	flush_work(&dp->hotplug_work); - -	if (pdev->dev.of_node) { -		if (dp->phy_addr) -			exynos_dp_phy_exit(dp); -	} else { -		if (pdata->phy_exit) -			pdata->phy_exit(); -	} - -	clk_disable_unprepare(dp->clock); - - -	return 0; -} - -#ifdef CONFIG_PM_SLEEP -static int exynos_dp_suspend(struct device *dev) -{ -	struct exynos_dp_platdata *pdata = dev->platform_data; -	struct exynos_dp_device *dp = dev_get_drvdata(dev); - -	disable_irq(dp->irq); - -	flush_work(&dp->hotplug_work); - -	if (dev->of_node) { -		if (dp->phy_addr) -			exynos_dp_phy_exit(dp); -	} else { -		if (pdata->phy_exit) -			pdata->phy_exit(); -	} - -	clk_disable_unprepare(dp->clock); - -	return 0; -} - -static int exynos_dp_resume(struct device *dev) -{ -	struct exynos_dp_platdata *pdata = dev->platform_data; -	struct exynos_dp_device *dp = dev_get_drvdata(dev); - -	if (dev->of_node) { -		if (dp->phy_addr) -			exynos_dp_phy_init(dp); -	} else { -		if (pdata->phy_init) -			pdata->phy_init(); -	} - -	clk_prepare_enable(dp->clock); - -	exynos_dp_init_dp(dp); - -	enable_irq(dp->irq); - -	return 0; -} -#endif - -static const struct dev_pm_ops exynos_dp_pm_ops = { -	SET_SYSTEM_SLEEP_PM_OPS(exynos_dp_suspend, exynos_dp_resume) -}; - -static const struct of_device_id exynos_dp_match[] = { -	{ .compatible = "samsung,exynos5-dp" }, -	{}, -}; -MODULE_DEVICE_TABLE(of, exynos_dp_match); - -static struct platform_driver exynos_dp_driver = { -	.probe		= exynos_dp_probe, -	.remove		= exynos_dp_remove, -	.driver		= { -		.name	= "exynos-dp", -		.owner	= THIS_MODULE, -		.pm	= &exynos_dp_pm_ops, -		.of_match_table = of_match_ptr(exynos_dp_match), -	}, -}; - -module_platform_driver(exynos_dp_driver); - -MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>"); -MODULE_DESCRIPTION("Samsung SoC DP Driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/video/exynos/exynos_dp_core.h b/drivers/video/exynos/exynos_dp_core.h deleted file mode 100644 index 6c567bbf2fb..00000000000 --- a/drivers/video/exynos/exynos_dp_core.h +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Header file for Samsung DP (Display Port) interface driver. - * - * Copyright (C) 2012 Samsung Electronics Co., Ltd. - * Author: Jingoo Han <jg1.han@samsung.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#ifndef _EXYNOS_DP_CORE_H -#define _EXYNOS_DP_CORE_H - -enum dp_irq_type { -	DP_IRQ_TYPE_HP_CABLE_IN, -	DP_IRQ_TYPE_HP_CABLE_OUT, -	DP_IRQ_TYPE_HP_CHANGE, -	DP_IRQ_TYPE_UNKNOWN, -}; - -struct link_train { -	int eq_loop; -	int cr_loop[4]; - -	u8 link_rate; -	u8 lane_count; -	u8 training_lane[4]; - -	enum link_training_state lt_state; -}; - -struct exynos_dp_device { -	struct device		*dev; -	struct clk		*clock; -	unsigned int		irq; -	void __iomem		*reg_base; -	void __iomem		*phy_addr; -	unsigned int		enable_mask; - -	struct video_info	*video_info; -	struct link_train	link_train; -	struct work_struct	hotplug_work; -}; - -/* exynos_dp_reg.c */ -void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable); -void exynos_dp_stop_video(struct exynos_dp_device *dp); -void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable); -void exynos_dp_init_analog_param(struct exynos_dp_device *dp); -void exynos_dp_init_interrupt(struct exynos_dp_device *dp); -void exynos_dp_reset(struct exynos_dp_device *dp); -void exynos_dp_swreset(struct exynos_dp_device *dp); -void exynos_dp_config_interrupt(struct exynos_dp_device *dp); -enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp); -void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable); -void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp, -				enum analog_power_block block, -				bool enable); -void exynos_dp_init_analog_func(struct exynos_dp_device *dp); -void exynos_dp_init_hpd(struct exynos_dp_device *dp); -enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp); -void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp); -void exynos_dp_reset_aux(struct exynos_dp_device *dp); -void exynos_dp_init_aux(struct exynos_dp_device *dp); -int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp); -void exynos_dp_enable_sw_function(struct exynos_dp_device *dp); -int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp); -int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp, -				unsigned int reg_addr, -				unsigned char data); -int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp, -				unsigned int reg_addr, -				unsigned char *data); -int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp, -				unsigned int reg_addr, -				unsigned int count, -				unsigned char data[]); -int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp, -				unsigned int reg_addr, -				unsigned int count, -				unsigned char data[]); -int exynos_dp_select_i2c_device(struct exynos_dp_device *dp, -				unsigned int device_addr, -				unsigned int reg_addr); -int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp, -				unsigned int device_addr, -				unsigned int reg_addr, -				unsigned int *data); -int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp, -				unsigned int device_addr, -				unsigned int reg_addr, -				unsigned int count, -				unsigned char edid[]); -void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype); -void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype); -void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count); -void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count); -void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable); -void exynos_dp_set_training_pattern(struct exynos_dp_device *dp, -				 enum pattern_set pattern); -void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level); -void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level); -void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level); -void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level); -void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp, -				u32 training_lane); -void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp, -				u32 training_lane); -void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp, -				u32 training_lane); -void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp, -				u32 training_lane); -u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp); -u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp); -u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp); -u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp); -void exynos_dp_reset_macro(struct exynos_dp_device *dp); -void exynos_dp_init_video(struct exynos_dp_device *dp); - -void exynos_dp_set_video_color_format(struct exynos_dp_device *dp); -int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp); -void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp, -			enum clock_recovery_m_value_type type, -			u32 m_value, -			u32 n_value); -void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type); -void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable); -void exynos_dp_start_video(struct exynos_dp_device *dp); -int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp); -void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp); -void exynos_dp_enable_scrambling(struct exynos_dp_device *dp); -void exynos_dp_disable_scrambling(struct exynos_dp_device *dp); - -/* I2C EDID Chip ID, Slave Address */ -#define I2C_EDID_DEVICE_ADDR			0x50 -#define I2C_E_EDID_DEVICE_ADDR			0x30 - -#define EDID_BLOCK_LENGTH			0x80 -#define EDID_HEADER_PATTERN			0x00 -#define EDID_EXTENSION_FLAG			0x7e -#define EDID_CHECKSUM				0x7f - -/* Definition for DPCD Register */ -#define DPCD_ADDR_DPCD_REV			0x0000 -#define DPCD_ADDR_MAX_LINK_RATE			0x0001 -#define DPCD_ADDR_MAX_LANE_COUNT		0x0002 -#define DPCD_ADDR_LINK_BW_SET			0x0100 -#define DPCD_ADDR_LANE_COUNT_SET		0x0101 -#define DPCD_ADDR_TRAINING_PATTERN_SET		0x0102 -#define DPCD_ADDR_TRAINING_LANE0_SET		0x0103 -#define DPCD_ADDR_LANE0_1_STATUS		0x0202 -#define DPCD_ADDR_LANE_ALIGN_STATUS_UPDATED	0x0204 -#define DPCD_ADDR_ADJUST_REQUEST_LANE0_1	0x0206 -#define DPCD_ADDR_ADJUST_REQUEST_LANE2_3	0x0207 -#define DPCD_ADDR_TEST_REQUEST			0x0218 -#define DPCD_ADDR_TEST_RESPONSE			0x0260 -#define DPCD_ADDR_TEST_EDID_CHECKSUM		0x0261 -#define DPCD_ADDR_SINK_POWER_STATE		0x0600 - -/* DPCD_ADDR_MAX_LANE_COUNT */ -#define DPCD_ENHANCED_FRAME_CAP(x)		(((x) >> 7) & 0x1) -#define DPCD_MAX_LANE_COUNT(x)			((x) & 0x1f) - -/* DPCD_ADDR_LANE_COUNT_SET */ -#define DPCD_ENHANCED_FRAME_EN			(0x1 << 7) -#define DPCD_LANE_COUNT_SET(x)			((x) & 0x1f) - -/* DPCD_ADDR_TRAINING_PATTERN_SET */ -#define DPCD_SCRAMBLING_DISABLED		(0x1 << 5) -#define DPCD_SCRAMBLING_ENABLED			(0x0 << 5) -#define DPCD_TRAINING_PATTERN_2			(0x2 << 0) -#define DPCD_TRAINING_PATTERN_1			(0x1 << 0) -#define DPCD_TRAINING_PATTERN_DISABLED		(0x0 << 0) - -/* DPCD_ADDR_TRAINING_LANE0_SET */ -#define DPCD_MAX_PRE_EMPHASIS_REACHED		(0x1 << 5) -#define DPCD_PRE_EMPHASIS_SET(x)		(((x) & 0x3) << 3) -#define DPCD_PRE_EMPHASIS_GET(x)		(((x) >> 3) & 0x3) -#define DPCD_PRE_EMPHASIS_PATTERN2_LEVEL0	(0x0 << 3) -#define DPCD_MAX_SWING_REACHED			(0x1 << 2) -#define DPCD_VOLTAGE_SWING_SET(x)		(((x) & 0x3) << 0) -#define DPCD_VOLTAGE_SWING_GET(x)		(((x) >> 0) & 0x3) -#define DPCD_VOLTAGE_SWING_PATTERN1_LEVEL0	(0x0 << 0) - -/* DPCD_ADDR_LANE0_1_STATUS */ -#define DPCD_LANE_SYMBOL_LOCKED			(0x1 << 2) -#define DPCD_LANE_CHANNEL_EQ_DONE		(0x1 << 1) -#define DPCD_LANE_CR_DONE			(0x1 << 0) -#define DPCD_CHANNEL_EQ_BITS			(DPCD_LANE_CR_DONE|	\ -						 DPCD_LANE_CHANNEL_EQ_DONE|\ -						 DPCD_LANE_SYMBOL_LOCKED) - -/* DPCD_ADDR_LANE_ALIGN__STATUS_UPDATED */ -#define DPCD_LINK_STATUS_UPDATED		(0x1 << 7) -#define DPCD_DOWNSTREAM_PORT_STATUS_CHANGED	(0x1 << 6) -#define DPCD_INTERLANE_ALIGN_DONE		(0x1 << 0) - -/* DPCD_ADDR_TEST_REQUEST */ -#define DPCD_TEST_EDID_READ			(0x1 << 2) - -/* DPCD_ADDR_TEST_RESPONSE */ -#define DPCD_TEST_EDID_CHECKSUM_WRITE		(0x1 << 2) - -/* DPCD_ADDR_SINK_POWER_STATE */ -#define DPCD_SET_POWER_STATE_D0			(0x1 << 0) -#define DPCD_SET_POWER_STATE_D4			(0x2 << 0) - -#endif /* _EXYNOS_DP_CORE_H */ diff --git a/drivers/video/exynos/exynos_dp_reg.c b/drivers/video/exynos/exynos_dp_reg.c deleted file mode 100644 index 29d9d035c73..00000000000 --- a/drivers/video/exynos/exynos_dp_reg.c +++ /dev/null @@ -1,1245 +0,0 @@ -/* - * Samsung DP (Display port) register interface driver. - * - * Copyright (C) 2012 Samsung Electronics Co., Ltd. - * Author: Jingoo Han <jg1.han@samsung.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include <linux/device.h> -#include <linux/io.h> -#include <linux/delay.h> - -#include <video/exynos_dp.h> - -#include "exynos_dp_core.h" -#include "exynos_dp_reg.h" - -#define COMMON_INT_MASK_1	0 -#define COMMON_INT_MASK_2	0 -#define COMMON_INT_MASK_3	0 -#define COMMON_INT_MASK_4	(HOTPLUG_CHG | HPD_LOST | PLUG) -#define INT_STA_MASK		INT_HPD - -void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable) -{ -	u32 reg; - -	if (enable) { -		reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); -		reg |= HDCP_VIDEO_MUTE; -		writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); -	} else { -		reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); -		reg &= ~HDCP_VIDEO_MUTE; -		writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); -	} -} - -void exynos_dp_stop_video(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); -	reg &= ~VIDEO_EN; -	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); -} - -void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable) -{ -	u32 reg; - -	if (enable) -		reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 | -			LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3; -	else -		reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 | -			LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0; - -	writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP); -} - -void exynos_dp_init_analog_param(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = TX_TERMINAL_CTRL_50_OHM; -	writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_1); - -	reg = SEL_24M | TX_DVDD_BIT_1_0625V; -	writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_2); - -	reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO; -	writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3); - -	reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM | -		TX_CUR1_2X | TX_CUR_16_MA; -	writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1); - -	reg = CH3_AMP_400_MV | CH2_AMP_400_MV | -		CH1_AMP_400_MV | CH0_AMP_400_MV; -	writel(reg, dp->reg_base + EXYNOS_DP_TX_AMP_TUNING_CTL); -} - -void exynos_dp_init_interrupt(struct exynos_dp_device *dp) -{ -	/* Set interrupt pin assertion polarity as high */ -	writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL); - -	/* Clear pending regisers */ -	writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); -	writel(0x4f, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_2); -	writel(0xe0, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_3); -	writel(0xe7, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); -	writel(0x63, dp->reg_base + EXYNOS_DP_INT_STA); - -	/* 0:mask,1: unmask */ -	writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1); -	writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2); -	writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3); -	writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4); -	writel(0x00, dp->reg_base + EXYNOS_DP_INT_STA_MASK); -} - -void exynos_dp_reset(struct exynos_dp_device *dp) -{ -	u32 reg; - -	exynos_dp_stop_video(dp); -	exynos_dp_enable_video_mute(dp, 0); - -	reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N | -		AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N | -		HDCP_FUNC_EN_N | SW_FUNC_EN_N; -	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); - -	reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N | -		SERDES_FIFO_FUNC_EN_N | -		LS_CLK_DOMAIN_FUNC_EN_N; -	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); - -	usleep_range(20, 30); - -	exynos_dp_lane_swap(dp, 0); - -	writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_1); -	writel(0x40, dp->reg_base + EXYNOS_DP_SYS_CTL_2); -	writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_3); -	writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_4); - -	writel(0x0, dp->reg_base + EXYNOS_DP_PKT_SEND_CTL); -	writel(0x0, dp->reg_base + EXYNOS_DP_HDCP_CTL); - -	writel(0x5e, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_L); -	writel(0x1a, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_H); - -	writel(0x10, dp->reg_base + EXYNOS_DP_LINK_DEBUG_CTL); - -	writel(0x0, dp->reg_base + EXYNOS_DP_PHY_TEST); - -	writel(0x0, dp->reg_base + EXYNOS_DP_VIDEO_FIFO_THRD); -	writel(0x20, dp->reg_base + EXYNOS_DP_AUDIO_MARGIN); - -	writel(0x4, dp->reg_base + EXYNOS_DP_M_VID_GEN_FILTER_TH); -	writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH); - -	writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); -} - -void exynos_dp_swreset(struct exynos_dp_device *dp) -{ -	writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET); -} - -void exynos_dp_config_interrupt(struct exynos_dp_device *dp) -{ -	u32 reg; - -	/* 0: mask, 1: unmask */ -	reg = COMMON_INT_MASK_1; -	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1); - -	reg = COMMON_INT_MASK_2; -	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2); - -	reg = COMMON_INT_MASK_3; -	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3); - -	reg = COMMON_INT_MASK_4; -	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4); - -	reg = INT_STA_MASK; -	writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK); -} - -enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL); -	if (reg & PLL_LOCK) -		return PLL_LOCKED; -	else -		return PLL_UNLOCKED; -} - -void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable) -{ -	u32 reg; - -	if (enable) { -		reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL); -		reg |= DP_PLL_PD; -		writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL); -	} else { -		reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL); -		reg &= ~DP_PLL_PD; -		writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL); -	} -} - -void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp, -				enum analog_power_block block, -				bool enable) -{ -	u32 reg; - -	switch (block) { -	case AUX_BLOCK: -		if (enable) { -			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); -			reg |= AUX_PD; -			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); -		} else { -			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); -			reg &= ~AUX_PD; -			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); -		} -		break; -	case CH0_BLOCK: -		if (enable) { -			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); -			reg |= CH0_PD; -			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); -		} else { -			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); -			reg &= ~CH0_PD; -			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); -		} -		break; -	case CH1_BLOCK: -		if (enable) { -			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); -			reg |= CH1_PD; -			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); -		} else { -			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); -			reg &= ~CH1_PD; -			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); -		} -		break; -	case CH2_BLOCK: -		if (enable) { -			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); -			reg |= CH2_PD; -			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); -		} else { -			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); -			reg &= ~CH2_PD; -			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); -		} -		break; -	case CH3_BLOCK: -		if (enable) { -			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); -			reg |= CH3_PD; -			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); -		} else { -			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); -			reg &= ~CH3_PD; -			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); -		} -		break; -	case ANALOG_TOTAL: -		if (enable) { -			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); -			reg |= DP_PHY_PD; -			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); -		} else { -			reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); -			reg &= ~DP_PHY_PD; -			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); -		} -		break; -	case POWER_ALL: -		if (enable) { -			reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD | -				CH1_PD | CH0_PD; -			writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); -		} else { -			writel(0x00, dp->reg_base + EXYNOS_DP_PHY_PD); -		} -		break; -	default: -		break; -	} -} - -void exynos_dp_init_analog_func(struct exynos_dp_device *dp) -{ -	u32 reg; -	int timeout_loop = 0; - -	exynos_dp_set_analog_power_down(dp, POWER_ALL, 0); - -	reg = PLL_LOCK_CHG; -	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); - -	reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL); -	reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL); -	writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL); - -	/* Power up PLL */ -	if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { -		exynos_dp_set_pll_power_down(dp, 0); - -		while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { -			timeout_loop++; -			if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { -				dev_err(dp->dev, "failed to get pll lock status\n"); -				return; -			} -			usleep_range(10, 20); -		} -	} - -	/* Enable Serdes FIFO function and Link symbol clock domain module */ -	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); -	reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N -		| AUX_FUNC_EN_N); -	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); -} - -void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = HOTPLUG_CHG | HPD_LOST | PLUG; -	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); - -	reg = INT_HPD; -	writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); -} - -void exynos_dp_init_hpd(struct exynos_dp_device *dp) -{ -	u32 reg; - -	exynos_dp_clear_hotplug_interrupts(dp); - -	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); -	reg &= ~(F_HPD | HPD_CTRL); -	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); -} - -enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp) -{ -	u32 reg; - -	/* Parse hotplug interrupt status register */ -	reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); - -	if (reg & PLUG) -		return DP_IRQ_TYPE_HP_CABLE_IN; - -	if (reg & HPD_LOST) -		return DP_IRQ_TYPE_HP_CABLE_OUT; - -	if (reg & HOTPLUG_CHG) -		return DP_IRQ_TYPE_HP_CHANGE; - -	return DP_IRQ_TYPE_UNKNOWN; -} - -void exynos_dp_reset_aux(struct exynos_dp_device *dp) -{ -	u32 reg; - -	/* Disable AUX channel module */ -	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); -	reg |= AUX_FUNC_EN_N; -	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); -} - -void exynos_dp_init_aux(struct exynos_dp_device *dp) -{ -	u32 reg; - -	/* Clear inerrupts related to AUX channel */ -	reg = RPLY_RECEIV | AUX_ERR; -	writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); - -	exynos_dp_reset_aux(dp); - -	/* Disable AUX transaction H/W retry */ -	reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)| -		AUX_HW_RETRY_INTERVAL_600_MICROSECONDS; -	writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL) ; - -	/* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */ -	reg = DEFER_CTRL_EN | DEFER_COUNT(1); -	writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_DEFER_CTL); - -	/* Enable AUX channel module */ -	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); -	reg &= ~AUX_FUNC_EN_N; -	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); -} - -int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); -	if (reg & HPD_STATUS) -		return 0; - -	return -EINVAL; -} - -void exynos_dp_enable_sw_function(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1); -	reg &= ~SW_FUNC_EN_N; -	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); -} - -int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp) -{ -	int reg; -	int retval = 0; -	int timeout_loop = 0; - -	/* Enable AUX CH operation */ -	reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); -	reg |= AUX_EN; -	writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); - -	/* Is AUX CH command reply received? */ -	reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); -	while (!(reg & RPLY_RECEIV)) { -		timeout_loop++; -		if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { -			dev_err(dp->dev, "AUX CH command reply failed!\n"); -			return -ETIMEDOUT; -		} -		reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); -		usleep_range(10, 11); -	} - -	/* Clear interrupt source for AUX CH command reply */ -	writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA); - -	/* Clear interrupt source for AUX CH access error */ -	reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); -	if (reg & AUX_ERR) { -		writel(AUX_ERR, dp->reg_base + EXYNOS_DP_INT_STA); -		return -EREMOTEIO; -	} - -	/* Check AUX CH error access status */ -	reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_STA); -	if ((reg & AUX_STATUS_MASK) != 0) { -		dev_err(dp->dev, "AUX CH error happens: %d\n\n", -			reg & AUX_STATUS_MASK); -		return -EREMOTEIO; -	} - -	return retval; -} - -int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp, -				unsigned int reg_addr, -				unsigned char data) -{ -	u32 reg; -	int i; -	int retval; - -	for (i = 0; i < 3; i++) { -		/* Clear AUX CH data buffer */ -		reg = BUF_CLR; -		writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); - -		/* Select DPCD device address */ -		reg = AUX_ADDR_7_0(reg_addr); -		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); -		reg = AUX_ADDR_15_8(reg_addr); -		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); -		reg = AUX_ADDR_19_16(reg_addr); -		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); - -		/* Write data buffer */ -		reg = (unsigned int)data; -		writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0); - -		/* -		 * Set DisplayPort transaction and write 1 byte -		 * If bit 3 is 1, DisplayPort transaction. -		 * If Bit 3 is 0, I2C transaction. -		 */ -		reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; -		writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); - -		/* Start AUX transaction */ -		retval = exynos_dp_start_aux_transaction(dp); -		if (retval == 0) -			break; -		else -			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", -				__func__); -	} - -	return retval; -} - -int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp, -				unsigned int reg_addr, -				unsigned char *data) -{ -	u32 reg; -	int i; -	int retval; - -	for (i = 0; i < 3; i++) { -		/* Clear AUX CH data buffer */ -		reg = BUF_CLR; -		writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); - -		/* Select DPCD device address */ -		reg = AUX_ADDR_7_0(reg_addr); -		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); -		reg = AUX_ADDR_15_8(reg_addr); -		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); -		reg = AUX_ADDR_19_16(reg_addr); -		writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); - -		/* -		 * Set DisplayPort transaction and read 1 byte -		 * If bit 3 is 1, DisplayPort transaction. -		 * If Bit 3 is 0, I2C transaction. -		 */ -		reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; -		writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); - -		/* Start AUX transaction */ -		retval = exynos_dp_start_aux_transaction(dp); -		if (retval == 0) -			break; -		else -			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", -				__func__); -	} - -	/* Read data buffer */ -	reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0); -	*data = (unsigned char)(reg & 0xff); - -	return retval; -} - -int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp, -				unsigned int reg_addr, -				unsigned int count, -				unsigned char data[]) -{ -	u32 reg; -	unsigned int start_offset; -	unsigned int cur_data_count; -	unsigned int cur_data_idx; -	int i; -	int retval = 0; - -	/* Clear AUX CH data buffer */ -	reg = BUF_CLR; -	writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); - -	start_offset = 0; -	while (start_offset < count) { -		/* Buffer size of AUX CH is 16 * 4bytes */ -		if ((count - start_offset) > 16) -			cur_data_count = 16; -		else -			cur_data_count = count - start_offset; - -		for (i = 0; i < 3; i++) { -			/* Select DPCD device address */ -			reg = AUX_ADDR_7_0(reg_addr + start_offset); -			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); -			reg = AUX_ADDR_15_8(reg_addr + start_offset); -			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); -			reg = AUX_ADDR_19_16(reg_addr + start_offset); -			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); - -			for (cur_data_idx = 0; cur_data_idx < cur_data_count; -			     cur_data_idx++) { -				reg = data[start_offset + cur_data_idx]; -				writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0 -							  + 4 * cur_data_idx); -			} - -			/* -			 * Set DisplayPort transaction and write -			 * If bit 3 is 1, DisplayPort transaction. -			 * If Bit 3 is 0, I2C transaction. -			 */ -			reg = AUX_LENGTH(cur_data_count) | -				AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; -			writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); - -			/* Start AUX transaction */ -			retval = exynos_dp_start_aux_transaction(dp); -			if (retval == 0) -				break; -			else -				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", -					__func__); -		} - -		start_offset += cur_data_count; -	} - -	return retval; -} - -int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp, -				unsigned int reg_addr, -				unsigned int count, -				unsigned char data[]) -{ -	u32 reg; -	unsigned int start_offset; -	unsigned int cur_data_count; -	unsigned int cur_data_idx; -	int i; -	int retval = 0; - -	/* Clear AUX CH data buffer */ -	reg = BUF_CLR; -	writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); - -	start_offset = 0; -	while (start_offset < count) { -		/* Buffer size of AUX CH is 16 * 4bytes */ -		if ((count - start_offset) > 16) -			cur_data_count = 16; -		else -			cur_data_count = count - start_offset; - -		/* AUX CH Request Transaction process */ -		for (i = 0; i < 3; i++) { -			/* Select DPCD device address */ -			reg = AUX_ADDR_7_0(reg_addr + start_offset); -			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); -			reg = AUX_ADDR_15_8(reg_addr + start_offset); -			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); -			reg = AUX_ADDR_19_16(reg_addr + start_offset); -			writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); - -			/* -			 * Set DisplayPort transaction and read -			 * If bit 3 is 1, DisplayPort transaction. -			 * If Bit 3 is 0, I2C transaction. -			 */ -			reg = AUX_LENGTH(cur_data_count) | -				AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; -			writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); - -			/* Start AUX transaction */ -			retval = exynos_dp_start_aux_transaction(dp); -			if (retval == 0) -				break; -			else -				dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", -					__func__); -		} - -		for (cur_data_idx = 0; cur_data_idx < cur_data_count; -		    cur_data_idx++) { -			reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0 -						 + 4 * cur_data_idx); -			data[start_offset + cur_data_idx] = -				(unsigned char)reg; -		} - -		start_offset += cur_data_count; -	} - -	return retval; -} - -int exynos_dp_select_i2c_device(struct exynos_dp_device *dp, -				unsigned int device_addr, -				unsigned int reg_addr) -{ -	u32 reg; -	int retval; - -	/* Set EDID device address */ -	reg = device_addr; -	writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); -	writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); -	writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); - -	/* Set offset from base address of EDID device */ -	writel(reg_addr, dp->reg_base + EXYNOS_DP_BUF_DATA_0); - -	/* -	 * Set I2C transaction and write address -	 * If bit 3 is 1, DisplayPort transaction. -	 * If Bit 3 is 0, I2C transaction. -	 */ -	reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT | -		AUX_TX_COMM_WRITE; -	writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); - -	/* Start AUX transaction */ -	retval = exynos_dp_start_aux_transaction(dp); -	if (retval != 0) -		dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); - -	return retval; -} - -int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp, -				unsigned int device_addr, -				unsigned int reg_addr, -				unsigned int *data) -{ -	u32 reg; -	int i; -	int retval; - -	for (i = 0; i < 3; i++) { -		/* Clear AUX CH data buffer */ -		reg = BUF_CLR; -		writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); - -		/* Select EDID device */ -		retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr); -		if (retval != 0) -			continue; - -		/* -		 * Set I2C transaction and read data -		 * If bit 3 is 1, DisplayPort transaction. -		 * If Bit 3 is 0, I2C transaction. -		 */ -		reg = AUX_TX_COMM_I2C_TRANSACTION | -			AUX_TX_COMM_READ; -		writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); - -		/* Start AUX transaction */ -		retval = exynos_dp_start_aux_transaction(dp); -		if (retval == 0) -			break; -		else -			dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", -				__func__); -	} - -	/* Read data */ -	if (retval == 0) -		*data = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0); - -	return retval; -} - -int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp, -				unsigned int device_addr, -				unsigned int reg_addr, -				unsigned int count, -				unsigned char edid[]) -{ -	u32 reg; -	unsigned int i, j; -	unsigned int cur_data_idx; -	unsigned int defer = 0; -	int retval = 0; - -	for (i = 0; i < count; i += 16) { -		for (j = 0; j < 3; j++) { -			/* Clear AUX CH data buffer */ -			reg = BUF_CLR; -			writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); - -			/* Set normal AUX CH command */ -			reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); -			reg &= ~ADDR_ONLY; -			writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); - -			/* -			 * If Rx sends defer, Tx sends only reads -			 * request without sending address -			 */ -			if (!defer) -				retval = exynos_dp_select_i2c_device(dp, -						device_addr, reg_addr + i); -			else -				defer = 0; - -			if (retval == 0) { -				/* -				 * Set I2C transaction and write data -				 * If bit 3 is 1, DisplayPort transaction. -				 * If Bit 3 is 0, I2C transaction. -				 */ -				reg = AUX_LENGTH(16) | -					AUX_TX_COMM_I2C_TRANSACTION | -					AUX_TX_COMM_READ; -				writel(reg, dp->reg_base + -					EXYNOS_DP_AUX_CH_CTL_1); - -				/* Start AUX transaction */ -				retval = exynos_dp_start_aux_transaction(dp); -				if (retval == 0) -					break; -				else -					dev_dbg(dp->dev, -						"%s: Aux Transaction fail!\n", -						__func__); -			} -			/* Check if Rx sends defer */ -			reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM); -			if (reg == AUX_RX_COMM_AUX_DEFER || -				reg == AUX_RX_COMM_I2C_DEFER) { -				dev_err(dp->dev, "Defer: %d\n\n", reg); -				defer = 1; -			} -		} - -		for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) { -			reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0 -						 + 4 * cur_data_idx); -			edid[i + cur_data_idx] = (unsigned char)reg; -		} -	} - -	return retval; -} - -void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype) -{ -	u32 reg; - -	reg = bwtype; -	if ((bwtype == LINK_RATE_2_70GBPS) || (bwtype == LINK_RATE_1_62GBPS)) -		writel(reg, dp->reg_base + EXYNOS_DP_LINK_BW_SET); -} - -void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_LINK_BW_SET); -	*bwtype = reg; -} - -void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count) -{ -	u32 reg; - -	reg = count; -	writel(reg, dp->reg_base + EXYNOS_DP_LANE_COUNT_SET); -} - -void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_LANE_COUNT_SET); -	*count = reg; -} - -void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable) -{ -	u32 reg; - -	if (enable) { -		reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); -		reg |= ENHANCED; -		writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); -	} else { -		reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); -		reg &= ~ENHANCED; -		writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); -	} -} - -void exynos_dp_set_training_pattern(struct exynos_dp_device *dp, -				 enum pattern_set pattern) -{ -	u32 reg; - -	switch (pattern) { -	case PRBS7: -		reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7; -		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); -		break; -	case D10_2: -		reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2; -		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); -		break; -	case TRAINING_PTN1: -		reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1; -		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); -		break; -	case TRAINING_PTN2: -		reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2; -		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); -		break; -	case DP_NONE: -		reg = SCRAMBLING_ENABLE | -			LINK_QUAL_PATTERN_SET_DISABLE | -			SW_TRAINING_PATTERN_SET_NORMAL; -		writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); -		break; -	default: -		break; -	} -} - -void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); -	reg &= ~PRE_EMPHASIS_SET_MASK; -	reg |= level << PRE_EMPHASIS_SET_SHIFT; -	writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); -} - -void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); -	reg &= ~PRE_EMPHASIS_SET_MASK; -	reg |= level << PRE_EMPHASIS_SET_SHIFT; -	writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); -} - -void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); -	reg &= ~PRE_EMPHASIS_SET_MASK; -	reg |= level << PRE_EMPHASIS_SET_SHIFT; -	writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); -} - -void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); -	reg &= ~PRE_EMPHASIS_SET_MASK; -	reg |= level << PRE_EMPHASIS_SET_SHIFT; -	writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); -} - -void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp, -					u32 training_lane) -{ -	u32 reg; - -	reg = training_lane; -	writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); -} - -void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp, -					u32 training_lane) -{ -	u32 reg; - -	reg = training_lane; -	writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); -} - -void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp, -					u32 training_lane) -{ -	u32 reg; - -	reg = training_lane; -	writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); -} - -void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp, -					u32 training_lane) -{ -	u32 reg; - -	reg = training_lane; -	writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); -} - -u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); -	return reg; -} - -u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); -	return reg; -} - -u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); -	return reg; -} - -u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); -	return reg; -} - -void exynos_dp_reset_macro(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_PHY_TEST); -	reg |= MACRO_RST; -	writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); - -	/* 10 us is the minimum reset time. */ -	usleep_range(10, 20); - -	reg &= ~MACRO_RST; -	writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); -} - -void exynos_dp_init_video(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG; -	writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); - -	reg = 0x0; -	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1); - -	reg = CHA_CRI(4) | CHA_CTRL; -	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2); - -	reg = 0x0; -	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); - -	reg = VID_HRES_TH(2) | VID_VRES_TH(0); -	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8); -} - -void exynos_dp_set_video_color_format(struct exynos_dp_device *dp) -{ -	u32 reg; - -	/* Configure the input color depth, color space, dynamic range */ -	reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) | -		(dp->video_info->color_depth << IN_BPC_SHIFT) | -		(dp->video_info->color_space << IN_COLOR_F_SHIFT); -	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2); - -	/* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */ -	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); -	reg &= ~IN_YC_COEFFI_MASK; -	if (dp->video_info->ycbcr_coeff) -		reg |= IN_YC_COEFFI_ITU709; -	else -		reg |= IN_YC_COEFFI_ITU601; -	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); -} - -int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1); -	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1); - -	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1); - -	if (!(reg & DET_STA)) { -		dev_dbg(dp->dev, "Input stream clock not detected.\n"); -		return -EINVAL; -	} - -	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2); -	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2); - -	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2); -	dev_dbg(dp->dev, "wait SYS_CTL_2.\n"); - -	if (reg & CHA_STA) { -		dev_dbg(dp->dev, "Input stream clk is changing\n"); -		return -EINVAL; -	} - -	return 0; -} - -void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp, -		enum clock_recovery_m_value_type type, -		u32 m_value, -		u32 n_value) -{ -	u32 reg; - -	if (type == REGISTER_M) { -		reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); -		reg |= FIX_M_VID; -		writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); -		reg = m_value & 0xff; -		writel(reg, dp->reg_base + EXYNOS_DP_M_VID_0); -		reg = (m_value >> 8) & 0xff; -		writel(reg, dp->reg_base + EXYNOS_DP_M_VID_1); -		reg = (m_value >> 16) & 0xff; -		writel(reg, dp->reg_base + EXYNOS_DP_M_VID_2); - -		reg = n_value & 0xff; -		writel(reg, dp->reg_base + EXYNOS_DP_N_VID_0); -		reg = (n_value >> 8) & 0xff; -		writel(reg, dp->reg_base + EXYNOS_DP_N_VID_1); -		reg = (n_value >> 16) & 0xff; -		writel(reg, dp->reg_base + EXYNOS_DP_N_VID_2); -	} else  { -		reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); -		reg &= ~FIX_M_VID; -		writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); - -		writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_0); -		writel(0x80, dp->reg_base + EXYNOS_DP_N_VID_1); -		writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_2); -	} -} - -void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type) -{ -	u32 reg; - -	if (type == VIDEO_TIMING_FROM_CAPTURE) { -		reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); -		reg &= ~FORMAT_SEL; -		writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); -	} else { -		reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); -		reg |= FORMAT_SEL; -		writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); -	} -} - -void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable) -{ -	u32 reg; - -	if (enable) { -		reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); -		reg &= ~VIDEO_MODE_MASK; -		reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE; -		writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); -	} else { -		reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); -		reg &= ~VIDEO_MODE_MASK; -		reg |= VIDEO_MODE_SLAVE_MODE; -		writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); -	} -} - -void exynos_dp_start_video(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); -	reg |= VIDEO_EN; -	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); -} - -int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); -	writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); - -	reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); -	if (!(reg & STRM_VALID)) { -		dev_dbg(dp->dev, "Input video stream is not detected.\n"); -		return -EINVAL; -	} - -	return 0; -} - -void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1); -	reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N); -	reg |= MASTER_VID_FUNC_EN_N; -	writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); - -	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); -	reg &= ~INTERACE_SCAN_CFG; -	reg |= (dp->video_info->interlaced << 2); -	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); - -	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); -	reg &= ~VSYNC_POLARITY_CFG; -	reg |= (dp->video_info->v_sync_polarity << 1); -	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); - -	reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); -	reg &= ~HSYNC_POLARITY_CFG; -	reg |= (dp->video_info->h_sync_polarity << 0); -	writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); - -	reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE; -	writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); -} - -void exynos_dp_enable_scrambling(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); -	reg &= ~SCRAMBLING_DISABLE; -	writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); -} - -void exynos_dp_disable_scrambling(struct exynos_dp_device *dp) -{ -	u32 reg; - -	reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); -	reg |= SCRAMBLING_DISABLE; -	writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); -} diff --git a/drivers/video/exynos/exynos_dp_reg.h b/drivers/video/exynos/exynos_dp_reg.h deleted file mode 100644 index 2e9bd0e0b9f..00000000000 --- a/drivers/video/exynos/exynos_dp_reg.h +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Register definition file for Samsung DP driver - * - * Copyright (C) 2012 Samsung Electronics Co., Ltd. - * Author: Jingoo Han <jg1.han@samsung.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef _EXYNOS_DP_REG_H -#define _EXYNOS_DP_REG_H - -#define EXYNOS_DP_TX_SW_RESET			0x14 -#define EXYNOS_DP_FUNC_EN_1			0x18 -#define EXYNOS_DP_FUNC_EN_2			0x1C -#define EXYNOS_DP_VIDEO_CTL_1			0x20 -#define EXYNOS_DP_VIDEO_CTL_2			0x24 -#define EXYNOS_DP_VIDEO_CTL_3			0x28 - -#define EXYNOS_DP_VIDEO_CTL_8			0x3C -#define EXYNOS_DP_VIDEO_CTL_10			0x44 - -#define EXYNOS_DP_LANE_MAP			0x35C - -#define EXYNOS_DP_ANALOG_CTL_1			0x370 -#define EXYNOS_DP_ANALOG_CTL_2			0x374 -#define EXYNOS_DP_ANALOG_CTL_3			0x378 -#define EXYNOS_DP_PLL_FILTER_CTL_1		0x37C -#define EXYNOS_DP_TX_AMP_TUNING_CTL		0x380 - -#define EXYNOS_DP_AUX_HW_RETRY_CTL		0x390 - -#define EXYNOS_DP_COMMON_INT_STA_1		0x3C4 -#define EXYNOS_DP_COMMON_INT_STA_2		0x3C8 -#define EXYNOS_DP_COMMON_INT_STA_3		0x3CC -#define EXYNOS_DP_COMMON_INT_STA_4		0x3D0 -#define EXYNOS_DP_INT_STA			0x3DC -#define EXYNOS_DP_COMMON_INT_MASK_1		0x3E0 -#define EXYNOS_DP_COMMON_INT_MASK_2		0x3E4 -#define EXYNOS_DP_COMMON_INT_MASK_3		0x3E8 -#define EXYNOS_DP_COMMON_INT_MASK_4		0x3EC -#define EXYNOS_DP_INT_STA_MASK			0x3F8 -#define EXYNOS_DP_INT_CTL			0x3FC - -#define EXYNOS_DP_SYS_CTL_1			0x600 -#define EXYNOS_DP_SYS_CTL_2			0x604 -#define EXYNOS_DP_SYS_CTL_3			0x608 -#define EXYNOS_DP_SYS_CTL_4			0x60C - -#define EXYNOS_DP_PKT_SEND_CTL			0x640 -#define EXYNOS_DP_HDCP_CTL			0x648 - -#define EXYNOS_DP_LINK_BW_SET			0x680 -#define EXYNOS_DP_LANE_COUNT_SET		0x684 -#define EXYNOS_DP_TRAINING_PTN_SET		0x688 -#define EXYNOS_DP_LN0_LINK_TRAINING_CTL		0x68C -#define EXYNOS_DP_LN1_LINK_TRAINING_CTL		0x690 -#define EXYNOS_DP_LN2_LINK_TRAINING_CTL		0x694 -#define EXYNOS_DP_LN3_LINK_TRAINING_CTL		0x698 - -#define EXYNOS_DP_DEBUG_CTL			0x6C0 -#define EXYNOS_DP_HPD_DEGLITCH_L		0x6C4 -#define EXYNOS_DP_HPD_DEGLITCH_H		0x6C8 -#define EXYNOS_DP_LINK_DEBUG_CTL		0x6E0 - -#define EXYNOS_DP_M_VID_0			0x700 -#define EXYNOS_DP_M_VID_1			0x704 -#define EXYNOS_DP_M_VID_2			0x708 -#define EXYNOS_DP_N_VID_0			0x70C -#define EXYNOS_DP_N_VID_1			0x710 -#define EXYNOS_DP_N_VID_2			0x714 - -#define EXYNOS_DP_PLL_CTL			0x71C -#define EXYNOS_DP_PHY_PD			0x720 -#define EXYNOS_DP_PHY_TEST			0x724 - -#define EXYNOS_DP_VIDEO_FIFO_THRD		0x730 -#define EXYNOS_DP_AUDIO_MARGIN			0x73C - -#define EXYNOS_DP_M_VID_GEN_FILTER_TH		0x764 -#define EXYNOS_DP_M_AUD_GEN_FILTER_TH		0x778 -#define EXYNOS_DP_AUX_CH_STA			0x780 -#define EXYNOS_DP_AUX_CH_DEFER_CTL		0x788 -#define EXYNOS_DP_AUX_RX_COMM			0x78C -#define EXYNOS_DP_BUFFER_DATA_CTL		0x790 -#define EXYNOS_DP_AUX_CH_CTL_1			0x794 -#define EXYNOS_DP_AUX_ADDR_7_0			0x798 -#define EXYNOS_DP_AUX_ADDR_15_8			0x79C -#define EXYNOS_DP_AUX_ADDR_19_16		0x7A0 -#define EXYNOS_DP_AUX_CH_CTL_2			0x7A4 - -#define EXYNOS_DP_BUF_DATA_0			0x7C0 - -#define EXYNOS_DP_SOC_GENERAL_CTL		0x800 - -/* EXYNOS_DP_TX_SW_RESET */ -#define RESET_DP_TX				(0x1 << 0) - -/* EXYNOS_DP_FUNC_EN_1 */ -#define MASTER_VID_FUNC_EN_N			(0x1 << 7) -#define SLAVE_VID_FUNC_EN_N			(0x1 << 5) -#define AUD_FIFO_FUNC_EN_N			(0x1 << 4) -#define AUD_FUNC_EN_N				(0x1 << 3) -#define HDCP_FUNC_EN_N				(0x1 << 2) -#define CRC_FUNC_EN_N				(0x1 << 1) -#define SW_FUNC_EN_N				(0x1 << 0) - -/* EXYNOS_DP_FUNC_EN_2 */ -#define SSC_FUNC_EN_N				(0x1 << 7) -#define AUX_FUNC_EN_N				(0x1 << 2) -#define SERDES_FIFO_FUNC_EN_N			(0x1 << 1) -#define LS_CLK_DOMAIN_FUNC_EN_N			(0x1 << 0) - -/* EXYNOS_DP_VIDEO_CTL_1 */ -#define VIDEO_EN				(0x1 << 7) -#define HDCP_VIDEO_MUTE				(0x1 << 6) - -/* EXYNOS_DP_VIDEO_CTL_1 */ -#define IN_D_RANGE_MASK				(0x1 << 7) -#define IN_D_RANGE_SHIFT			(7) -#define IN_D_RANGE_CEA				(0x1 << 7) -#define IN_D_RANGE_VESA				(0x0 << 7) -#define IN_BPC_MASK				(0x7 << 4) -#define IN_BPC_SHIFT				(4) -#define IN_BPC_12_BITS				(0x3 << 4) -#define IN_BPC_10_BITS				(0x2 << 4) -#define IN_BPC_8_BITS				(0x1 << 4) -#define IN_BPC_6_BITS				(0x0 << 4) -#define IN_COLOR_F_MASK				(0x3 << 0) -#define IN_COLOR_F_SHIFT			(0) -#define IN_COLOR_F_YCBCR444			(0x2 << 0) -#define IN_COLOR_F_YCBCR422			(0x1 << 0) -#define IN_COLOR_F_RGB				(0x0 << 0) - -/* EXYNOS_DP_VIDEO_CTL_3 */ -#define IN_YC_COEFFI_MASK			(0x1 << 7) -#define IN_YC_COEFFI_SHIFT			(7) -#define IN_YC_COEFFI_ITU709			(0x1 << 7) -#define IN_YC_COEFFI_ITU601			(0x0 << 7) -#define VID_CHK_UPDATE_TYPE_MASK		(0x1 << 4) -#define VID_CHK_UPDATE_TYPE_SHIFT		(4) -#define VID_CHK_UPDATE_TYPE_1			(0x1 << 4) -#define VID_CHK_UPDATE_TYPE_0			(0x0 << 4) - -/* EXYNOS_DP_VIDEO_CTL_8 */ -#define VID_HRES_TH(x)				(((x) & 0xf) << 4) -#define VID_VRES_TH(x)				(((x) & 0xf) << 0) - -/* EXYNOS_DP_VIDEO_CTL_10 */ -#define FORMAT_SEL				(0x1 << 4) -#define INTERACE_SCAN_CFG			(0x1 << 2) -#define VSYNC_POLARITY_CFG			(0x1 << 1) -#define HSYNC_POLARITY_CFG			(0x1 << 0) - -/* EXYNOS_DP_LANE_MAP */ -#define LANE3_MAP_LOGIC_LANE_0			(0x0 << 6) -#define LANE3_MAP_LOGIC_LANE_1			(0x1 << 6) -#define LANE3_MAP_LOGIC_LANE_2			(0x2 << 6) -#define LANE3_MAP_LOGIC_LANE_3			(0x3 << 6) -#define LANE2_MAP_LOGIC_LANE_0			(0x0 << 4) -#define LANE2_MAP_LOGIC_LANE_1			(0x1 << 4) -#define LANE2_MAP_LOGIC_LANE_2			(0x2 << 4) -#define LANE2_MAP_LOGIC_LANE_3			(0x3 << 4) -#define LANE1_MAP_LOGIC_LANE_0			(0x0 << 2) -#define LANE1_MAP_LOGIC_LANE_1			(0x1 << 2) -#define LANE1_MAP_LOGIC_LANE_2			(0x2 << 2) -#define LANE1_MAP_LOGIC_LANE_3			(0x3 << 2) -#define LANE0_MAP_LOGIC_LANE_0			(0x0 << 0) -#define LANE0_MAP_LOGIC_LANE_1			(0x1 << 0) -#define LANE0_MAP_LOGIC_LANE_2			(0x2 << 0) -#define LANE0_MAP_LOGIC_LANE_3			(0x3 << 0) - -/* EXYNOS_DP_ANALOG_CTL_1 */ -#define TX_TERMINAL_CTRL_50_OHM			(0x1 << 4) - -/* EXYNOS_DP_ANALOG_CTL_2 */ -#define SEL_24M					(0x1 << 3) -#define TX_DVDD_BIT_1_0625V			(0x4 << 0) - -/* EXYNOS_DP_ANALOG_CTL_3 */ -#define DRIVE_DVDD_BIT_1_0625V			(0x4 << 5) -#define VCO_BIT_600_MICRO			(0x5 << 0) - -/* EXYNOS_DP_PLL_FILTER_CTL_1 */ -#define PD_RING_OSC				(0x1 << 6) -#define AUX_TERMINAL_CTRL_50_OHM		(0x2 << 4) -#define TX_CUR1_2X				(0x1 << 2) -#define TX_CUR_16_MA				(0x3 << 0) - -/* EXYNOS_DP_TX_AMP_TUNING_CTL */ -#define CH3_AMP_400_MV				(0x0 << 24) -#define CH2_AMP_400_MV				(0x0 << 16) -#define CH1_AMP_400_MV				(0x0 << 8) -#define CH0_AMP_400_MV				(0x0 << 0) - -/* EXYNOS_DP_AUX_HW_RETRY_CTL */ -#define AUX_BIT_PERIOD_EXPECTED_DELAY(x)	(((x) & 0x7) << 8) -#define AUX_HW_RETRY_INTERVAL_MASK		(0x3 << 3) -#define AUX_HW_RETRY_INTERVAL_600_MICROSECONDS	(0x0 << 3) -#define AUX_HW_RETRY_INTERVAL_800_MICROSECONDS	(0x1 << 3) -#define AUX_HW_RETRY_INTERVAL_1000_MICROSECONDS	(0x2 << 3) -#define AUX_HW_RETRY_INTERVAL_1800_MICROSECONDS	(0x3 << 3) -#define AUX_HW_RETRY_COUNT_SEL(x)		(((x) & 0x7) << 0) - -/* EXYNOS_DP_COMMON_INT_STA_1 */ -#define VSYNC_DET				(0x1 << 7) -#define PLL_LOCK_CHG				(0x1 << 6) -#define SPDIF_ERR				(0x1 << 5) -#define SPDIF_UNSTBL				(0x1 << 4) -#define VID_FORMAT_CHG				(0x1 << 3) -#define AUD_CLK_CHG				(0x1 << 2) -#define VID_CLK_CHG				(0x1 << 1) -#define SW_INT					(0x1 << 0) - -/* EXYNOS_DP_COMMON_INT_STA_2 */ -#define ENC_EN_CHG				(0x1 << 6) -#define HW_BKSV_RDY				(0x1 << 3) -#define HW_SHA_DONE				(0x1 << 2) -#define HW_AUTH_STATE_CHG			(0x1 << 1) -#define HW_AUTH_DONE				(0x1 << 0) - -/* EXYNOS_DP_COMMON_INT_STA_3 */ -#define AFIFO_UNDER				(0x1 << 7) -#define AFIFO_OVER				(0x1 << 6) -#define R0_CHK_FLAG				(0x1 << 5) - -/* EXYNOS_DP_COMMON_INT_STA_4 */ -#define PSR_ACTIVE				(0x1 << 7) -#define PSR_INACTIVE				(0x1 << 6) -#define SPDIF_BI_PHASE_ERR			(0x1 << 5) -#define HOTPLUG_CHG				(0x1 << 2) -#define HPD_LOST				(0x1 << 1) -#define PLUG					(0x1 << 0) - -/* EXYNOS_DP_INT_STA */ -#define INT_HPD					(0x1 << 6) -#define HW_TRAINING_FINISH			(0x1 << 5) -#define RPLY_RECEIV				(0x1 << 1) -#define AUX_ERR					(0x1 << 0) - -/* EXYNOS_DP_INT_CTL */ -#define SOFT_INT_CTRL				(0x1 << 2) -#define INT_POL1				(0x1 << 1) -#define INT_POL0				(0x1 << 0) - -/* EXYNOS_DP_SYS_CTL_1 */ -#define DET_STA					(0x1 << 2) -#define FORCE_DET				(0x1 << 1) -#define DET_CTRL				(0x1 << 0) - -/* EXYNOS_DP_SYS_CTL_2 */ -#define CHA_CRI(x)				(((x) & 0xf) << 4) -#define CHA_STA					(0x1 << 2) -#define FORCE_CHA				(0x1 << 1) -#define CHA_CTRL				(0x1 << 0) - -/* EXYNOS_DP_SYS_CTL_3 */ -#define HPD_STATUS				(0x1 << 6) -#define F_HPD					(0x1 << 5) -#define HPD_CTRL				(0x1 << 4) -#define HDCP_RDY				(0x1 << 3) -#define STRM_VALID				(0x1 << 2) -#define F_VALID					(0x1 << 1) -#define VALID_CTRL				(0x1 << 0) - -/* EXYNOS_DP_SYS_CTL_4 */ -#define FIX_M_AUD				(0x1 << 4) -#define ENHANCED				(0x1 << 3) -#define FIX_M_VID				(0x1 << 2) -#define M_VID_UPDATE_CTRL			(0x3 << 0) - -/* EXYNOS_DP_TRAINING_PTN_SET */ -#define SCRAMBLER_TYPE				(0x1 << 9) -#define HW_LINK_TRAINING_PATTERN		(0x1 << 8) -#define SCRAMBLING_DISABLE			(0x1 << 5) -#define SCRAMBLING_ENABLE			(0x0 << 5) -#define LINK_QUAL_PATTERN_SET_MASK		(0x3 << 2) -#define LINK_QUAL_PATTERN_SET_PRBS7		(0x3 << 2) -#define LINK_QUAL_PATTERN_SET_D10_2		(0x1 << 2) -#define LINK_QUAL_PATTERN_SET_DISABLE		(0x0 << 2) -#define SW_TRAINING_PATTERN_SET_MASK		(0x3 << 0) -#define SW_TRAINING_PATTERN_SET_PTN2		(0x2 << 0) -#define SW_TRAINING_PATTERN_SET_PTN1		(0x1 << 0) -#define SW_TRAINING_PATTERN_SET_NORMAL		(0x0 << 0) - -/* EXYNOS_DP_LN0_LINK_TRAINING_CTL */ -#define PRE_EMPHASIS_SET_MASK			(0x3 << 3) -#define PRE_EMPHASIS_SET_SHIFT			(3) - -/* EXYNOS_DP_DEBUG_CTL */ -#define PLL_LOCK				(0x1 << 4) -#define F_PLL_LOCK				(0x1 << 3) -#define PLL_LOCK_CTRL				(0x1 << 2) -#define PN_INV					(0x1 << 0) - -/* EXYNOS_DP_PLL_CTL */ -#define DP_PLL_PD				(0x1 << 7) -#define DP_PLL_RESET				(0x1 << 6) -#define DP_PLL_LOOP_BIT_DEFAULT			(0x1 << 4) -#define DP_PLL_REF_BIT_1_1250V			(0x5 << 0) -#define DP_PLL_REF_BIT_1_2500V			(0x7 << 0) - -/* EXYNOS_DP_PHY_PD */ -#define DP_PHY_PD				(0x1 << 5) -#define AUX_PD					(0x1 << 4) -#define CH3_PD					(0x1 << 3) -#define CH2_PD					(0x1 << 2) -#define CH1_PD					(0x1 << 1) -#define CH0_PD					(0x1 << 0) - -/* EXYNOS_DP_PHY_TEST */ -#define MACRO_RST				(0x1 << 5) -#define CH1_TEST				(0x1 << 1) -#define CH0_TEST				(0x1 << 0) - -/* EXYNOS_DP_AUX_CH_STA */ -#define AUX_BUSY				(0x1 << 4) -#define AUX_STATUS_MASK				(0xf << 0) - -/* EXYNOS_DP_AUX_CH_DEFER_CTL */ -#define DEFER_CTRL_EN				(0x1 << 7) -#define DEFER_COUNT(x)				(((x) & 0x7f) << 0) - -/* EXYNOS_DP_AUX_RX_COMM */ -#define AUX_RX_COMM_I2C_DEFER			(0x2 << 2) -#define AUX_RX_COMM_AUX_DEFER			(0x2 << 0) - -/* EXYNOS_DP_BUFFER_DATA_CTL */ -#define BUF_CLR					(0x1 << 7) -#define BUF_DATA_COUNT(x)			(((x) & 0x1f) << 0) - -/* EXYNOS_DP_AUX_CH_CTL_1 */ -#define AUX_LENGTH(x)				(((x - 1) & 0xf) << 4) -#define AUX_TX_COMM_MASK			(0xf << 0) -#define AUX_TX_COMM_DP_TRANSACTION		(0x1 << 3) -#define AUX_TX_COMM_I2C_TRANSACTION		(0x0 << 3) -#define AUX_TX_COMM_MOT				(0x1 << 2) -#define AUX_TX_COMM_WRITE			(0x0 << 0) -#define AUX_TX_COMM_READ			(0x1 << 0) - -/* EXYNOS_DP_AUX_ADDR_7_0 */ -#define AUX_ADDR_7_0(x)				(((x) >> 0) & 0xff) - -/* EXYNOS_DP_AUX_ADDR_15_8 */ -#define AUX_ADDR_15_8(x)			(((x) >> 8) & 0xff) - -/* EXYNOS_DP_AUX_ADDR_19_16 */ -#define AUX_ADDR_19_16(x)			(((x) >> 16) & 0x0f) - -/* EXYNOS_DP_AUX_CH_CTL_2 */ -#define ADDR_ONLY				(0x1 << 1) -#define AUX_EN					(0x1 << 0) - -/* EXYNOS_DP_SOC_GENERAL_CTL */ -#define AUDIO_MODE_SPDIF_MODE			(0x1 << 8) -#define AUDIO_MODE_MASTER_MODE			(0x0 << 8) -#define MASTER_VIDEO_INTERLACE_EN		(0x1 << 4) -#define VIDEO_MASTER_CLK_SEL			(0x1 << 2) -#define VIDEO_MASTER_MODE_EN			(0x1 << 1) -#define VIDEO_MODE_MASK				(0x1 << 0) -#define VIDEO_MODE_SLAVE_MODE			(0x1 << 0) -#define VIDEO_MODE_MASTER_MODE			(0x0 << 0) - -#endif /* _EXYNOS_DP_REG_H */ diff --git a/drivers/video/68328fb.c b/drivers/video/fbdev/68328fb.c index fa44fbed397..552258c8f99 100644 --- a/drivers/video/68328fb.c +++ b/drivers/video/fbdev/68328fb.c @@ -478,11 +478,10 @@ int __init mc68x328fb_init(void)  		return -EINVAL;  	} -	printk(KERN_INFO -		"fb%d: %s frame buffer device\n", fb_info.node,	fb_info.fix.id); -	printk(KERN_INFO -		"fb%d: %dx%dx%d at 0x%08lx\n", fb_info.node, -		mc68x328fb_default.xres_virtual, mc68x328fb_default.yres_virtual, +	fb_info(&fb_info, "%s frame buffer device\n", fb_info.fix.id); +	fb_info(&fb_info, "%dx%dx%d at 0x%08lx\n", +		mc68x328fb_default.xres_virtual, +		mc68x328fb_default.yres_virtual,  		1 << mc68x328fb_default.bits_per_pixel, videomemory);  	return 0; diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig new file mode 100644 index 00000000000..59c98bfd5a8 --- /dev/null +++ b/drivers/video/fbdev/Kconfig @@ -0,0 +1,2479 @@ +# +# fbdev configuration +# + +menuconfig FB +	tristate "Support for frame buffer devices" +	---help--- +	  The frame buffer device provides an abstraction for the graphics +	  hardware. It represents the frame buffer of some video hardware and +	  allows application software to access the graphics hardware through +	  a well-defined interface, so the software doesn't need to know +	  anything about the low-level (hardware register) stuff. + +	  Frame buffer devices work identically across the different +	  architectures supported by Linux and make the implementation of +	  application programs easier and more portable; at this point, an X +	  server exists which uses the frame buffer device exclusively. +	  On several non-X86 architectures, the frame buffer device is the +	  only way to use the graphics hardware. + +	  The device is accessed through special device nodes, usually located +	  in the /dev directory, i.e. /dev/fb*. + +	  You need an utility program called fbset to make full use of frame +	  buffer devices. Please read <file:Documentation/fb/framebuffer.txt> +	  and the Framebuffer-HOWTO at +	  <http://www.munted.org.uk/programming/Framebuffer-HOWTO-1.3.html> for more +	  information. + +	  Say Y here and to the driver for your graphics board below if you +	  are compiling a kernel for a non-x86 architecture. + +	  If you are compiling for the x86 architecture, you can say Y if you +	  want to play with it, but it is not essential. Please note that +	  running graphical applications that directly touch the hardware +	  (e.g. an accelerated X server) and that are not frame buffer +	  device-aware may cause unexpected results. If unsure, say N. + +config FIRMWARE_EDID +       bool "Enable firmware EDID" +       depends on FB +       default n +       ---help--- +         This enables access to the EDID transferred from the firmware. +	 On the i386, this is from the Video BIOS. Enable this if DDC/I2C +	 transfers do not work for your driver and if you are using +	 nvidiafb, i810fb or savagefb. + +	 In general, choosing Y for this option is safe.  If you +	 experience extremely long delays while booting before you get +	 something on your display, try setting this to N.  Matrox cards in +	 combination with certain motherboards and monitors are known to +	 suffer from this problem. + +config FB_DDC +       tristate +       depends on FB +       select I2C_ALGOBIT +       select I2C +       default n + +config FB_BOOT_VESA_SUPPORT +	bool +	depends on FB +	default n +	---help--- +	  If true, at least one selected framebuffer driver can take advantage +	  of VESA video modes set at an early boot stage via the vga= parameter. + +config FB_CFB_FILLRECT +	tristate +	depends on FB +	default n +	---help--- +	  Include the cfb_fillrect function for generic software rectangle +	  filling. This is used by drivers that don't provide their own +	  (accelerated) version. + +config FB_CFB_COPYAREA +	tristate +	depends on FB +	default n +	---help--- +	  Include the cfb_copyarea function for generic software area copying. +	  This is used by drivers that don't provide their own (accelerated) +	  version. + +config FB_CFB_IMAGEBLIT +	tristate +	depends on FB +	default n +	---help--- +	  Include the cfb_imageblit function for generic software image +	  blitting. This is used by drivers that don't provide their own +	  (accelerated) version. + +config FB_CFB_REV_PIXELS_IN_BYTE +	bool +	depends on FB +	default n +	---help--- +	  Allow generic frame-buffer functions to work on displays with 1, 2 +	  and 4 bits per pixel depths which has opposite order of pixels in +	  byte order to bytes in long order. + +config FB_SYS_FILLRECT +	tristate +	depends on FB +	default n +	---help--- +	  Include the sys_fillrect function for generic software rectangle +	  filling. This is used by drivers that don't provide their own +	  (accelerated) version and the framebuffer is in system RAM. + +config FB_SYS_COPYAREA +	tristate +	depends on FB +	default n +	---help--- +	  Include the sys_copyarea function for generic software area copying. +	  This is used by drivers that don't provide their own (accelerated) +	  version and the framebuffer is in system RAM. + +config FB_SYS_IMAGEBLIT +	tristate +	depends on FB +	default n +	---help--- +	  Include the sys_imageblit function for generic software image +	  blitting. This is used by drivers that don't provide their own +	  (accelerated) version and the framebuffer is in system RAM. + +menuconfig FB_FOREIGN_ENDIAN +	bool "Framebuffer foreign endianness support" +	depends on FB +	---help--- +	  This menu will let you enable support for the framebuffers with +	  non-native endianness (e.g. Little-Endian framebuffer on a +	  Big-Endian machine). Most probably you don't have such hardware, +	  so it's safe to say "n" here. + +choice +	prompt "Choice endianness support" +	depends on FB_FOREIGN_ENDIAN + +config FB_BOTH_ENDIAN +	bool "Support for Big- and Little-Endian framebuffers" + +config FB_BIG_ENDIAN +	bool "Support for Big-Endian framebuffers only" + +config FB_LITTLE_ENDIAN +	bool "Support for Little-Endian framebuffers only" + +endchoice + +config FB_SYS_FOPS +       tristate +       depends on FB +       default n + +config FB_DEFERRED_IO +	bool +	depends on FB + +config FB_HECUBA +	tristate +	depends on FB +	depends on FB_DEFERRED_IO + +config FB_SVGALIB +	tristate +	depends on FB +	default n +	---help--- +	  Common utility functions useful to fbdev drivers of VGA-based +	  cards. + +config FB_MACMODES +       tristate +       depends on FB +       default n + +config FB_BACKLIGHT +	bool +	depends on FB +	select BACKLIGHT_LCD_SUPPORT +	select BACKLIGHT_CLASS_DEVICE +	default n + +config FB_MODE_HELPERS +        bool "Enable Video Mode Handling Helpers" +        depends on FB +	default n +	---help--- +	  This enables functions for handling video modes using the +	  Generalized Timing Formula and the EDID parser. A few drivers rely +          on this feature such as the radeonfb, rivafb, and the i810fb. If +	  your driver does not take advantage of this feature, choosing Y will +	  just increase the kernel size by about 5K. + +config FB_TILEBLITTING +       bool "Enable Tile Blitting Support" +       depends on FB +       default n +       ---help--- +         This enables tile blitting.  Tile blitting is a drawing technique +	 where the screen is divided into rectangular sections (tiles), whereas +	 the standard blitting divides the screen into pixels. Because the +	 default drawing element is a tile, drawing functions will be passed +	 parameters in terms of number of tiles instead of number of pixels. +	 For example, to draw a single character, instead of using bitmaps, +	 an index to an array of bitmaps will be used.  To clear or move a +	 rectangular section of a screen, the rectangle will be described in +	 terms of number of tiles in the x- and y-axis. + +	 This is particularly important to one driver, matroxfb.  If +	 unsure, say N. + +comment "Frame buffer hardware drivers" +	depends on FB + +config FB_GRVGA +	tristate "Aeroflex Gaisler framebuffer support" +	depends on FB && SPARC +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler. + +config FB_CIRRUS +	tristate "Cirrus Logic support" +	depends on FB && (ZORRO || PCI) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  This enables support for Cirrus Logic GD542x/543x based boards on +	  Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum. + +	  If you have a PCI-based system, this enables support for these +	  chips: GD-543x, GD-544x, GD-5480. + +	  Please read the file <file:Documentation/fb/cirrusfb.txt>. + +	  Say N unless you have such a graphics board or plan to get one +	  before you next recompile the kernel. + +config FB_PM2 +	tristate "Permedia2 support" +	depends on FB && ((AMIGA && BROKEN) || PCI) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for cards based on +	  the 3D Labs Permedia, Permedia 2 and Permedia 2V chips. +	  The driver was tested on the following cards: +		Diamond FireGL 1000 PRO AGP +		ELSA Gloria Synergy PCI +		Appian Jeronimo PRO (both heads) PCI +		3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI +		Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC +		ASK Graphic Blaster Exxtreme AGP + +	  To compile this driver as a module, choose M here: the +	  module will be called pm2fb. + +config FB_PM2_FIFO_DISCONNECT +	bool "enable FIFO disconnect feature" +	depends on FB_PM2 && PCI +	help +	  Support the Permedia2 FIFO disconnect feature. + +config FB_ARMCLCD +	tristate "ARM PrimeCell PL110 support" +	depends on ARM || ARM64 || COMPILE_TEST +	depends on FB && ARM_AMBA +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This framebuffer device driver is for the ARM PrimeCell PL110 +	  Colour LCD controller.  ARM PrimeCells provide the building +	  blocks for System on a Chip devices. + +	  If you want to compile this as a module (=code which can be +	  inserted into and removed from the running kernel), say M +	  here and read <file:Documentation/kbuild/modules.txt>.  The module +	  will be called amba-clcd. + +config FB_ACORN +	bool "Acorn VIDC support" +	depends on (FB = y) && ARM && ARCH_ACORN +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the Acorn VIDC graphics +	  hardware found in Acorn RISC PCs and other ARM-based machines.  If +	  unsure, say N. + +config FB_CLPS711X +	bool "CLPS711X LCD support" +	depends on (FB = y) && ARM && ARCH_CLPS711X +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  Say Y to enable the Framebuffer driver for the CLPS7111 and +	  EP7212 processors. + +config FB_SA1100 +	bool "SA-1100 LCD support" +	depends on (FB = y) && ARM && ARCH_SA1100 +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is a framebuffer device for the SA-1100 LCD Controller. +	  See <http://www.linux-fbdev.org/> for information on framebuffer +	  devices. + +	  If you plan to use the LCD display with your SA-1100 system, say +	  Y here. + +config FB_IMX +	tristate "Freescale i.MX1/21/25/27 LCD support" +	depends on FB && ARCH_MXC +	select BACKLIGHT_LCD_SUPPORT +	select LCD_CLASS_DEVICE +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_MODE_HELPERS +	select VIDEOMODE_HELPERS + +config FB_CYBER2000 +	tristate "CyberPro 2000/2010/5000 support" +	depends on FB && PCI && (BROKEN || !SPARC64) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This enables support for the Integraphics CyberPro 20x0 and 5000 +	  VGA chips used in the Rebel.com Netwinder and other machines. +	  Say Y if you have a NetWinder or a graphics card containing this +	  device, otherwise say N. + +config FB_CYBER2000_DDC +	bool "DDC for CyberPro support" +	depends on FB_CYBER2000 +	select FB_DDC +	default y +	help +	  Say Y here if you want DDC support for your CyberPro graphics +	  card. This is only I2C bus support, driver does not use EDID. + +config FB_CYBER2000_I2C +	bool "CyberPro 2000/2010/5000 I2C support" +	depends on FB_CYBER2000 && I2C && ARCH_NETWINDER +	depends on I2C=y || FB_CYBER2000=m +	select I2C_ALGOBIT +	help +	  Enable support for the I2C video decoder interface on the +	  Integraphics CyberPro 20x0 and 5000 VGA chips.  This is used +	  on the Netwinder machines for the SAA7111 video capture. + +config FB_APOLLO +	bool +	depends on (FB = y) && APOLLO +	default y +	select FB_CFB_FILLRECT +	select FB_CFB_IMAGEBLIT + +config FB_Q40 +	bool +	depends on (FB = y) && Q40 +	default y +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT + +config FB_AMIGA +	tristate "Amiga native chipset support" +	depends on FB && AMIGA +	help +	  This is the frame buffer device driver for the builtin graphics +	  chipset found in Amigas. + +	  To compile this driver as a module, choose M here: the +	  module will be called amifb. + +config FB_AMIGA_OCS +	bool "Amiga OCS chipset support" +	depends on FB_AMIGA +	help +	  This enables support for the original Agnus and Denise video chips, +	  found in the Amiga 1000 and most A500's and A2000's. If you intend +	  to run Linux on any of these systems, say Y; otherwise say N. + +config FB_AMIGA_ECS +	bool "Amiga ECS chipset support" +	depends on FB_AMIGA +	help +	  This enables support for the Enhanced Chip Set, found in later +	  A500's, later A2000's, the A600, the A3000, the A3000T and CDTV. If +	  you intend to run Linux on any of these systems, say Y; otherwise +	  say N. + +config FB_AMIGA_AGA +	bool "Amiga AGA chipset support" +	depends on FB_AMIGA +	help +	  This enables support for the Advanced Graphics Architecture (also +	  known as the AGA or AA) Chip Set, found in the A1200, A4000, A4000T +	  and CD32. If you intend to run Linux on any of these systems, say Y; +	  otherwise say N. + +config FB_FM2 +	bool "Amiga FrameMaster II/Rainbow II support" +	depends on (FB = y) && ZORRO +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the Amiga FrameMaster +	  card from BSC (exhibited 1992 but not shipped as a CBM product). + +config FB_ARC +	tristate "Arc Monochrome LCD board support" +	depends on FB && X86 +	select FB_SYS_FILLRECT +	select FB_SYS_COPYAREA +	select FB_SYS_IMAGEBLIT +	select FB_SYS_FOPS +	help +	  This enables support for the Arc Monochrome LCD board. The board +	  is based on the KS-108 lcd controller and is typically a matrix +	  of 2*n chips. This driver was tested with a 128x64 panel. This +	  driver supports it for use with x86 SBCs through a 16 bit GPIO +	  interface (8 bit data, 8 bit control). If you anticipate using +	  this driver, say Y or M; otherwise say N. You must specify the +	  GPIO IO address to be used for setting control and data. + +config FB_ATARI +	bool "Atari native chipset support" +	depends on (FB = y) && ATARI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the builtin graphics +	  chipset found in Ataris. + +config FB_OF +	bool "Open Firmware frame buffer device support" +	depends on (FB = y) && (PPC64 || PPC_OF) && (!PPC_PSERIES || PCI) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_MACMODES +	help +	  Say Y if you want support with Open Firmware for your graphics +	  board. + +config FB_CONTROL +	bool "Apple \"control\" display support" +	depends on (FB = y) && PPC_PMAC && PPC32 +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_MACMODES +	help +	  This driver supports a frame buffer for the graphics adapter in the +	  Power Macintosh 7300 and others. + +config FB_PLATINUM +	bool "Apple \"platinum\" display support" +	depends on (FB = y) && PPC_PMAC && PPC32 +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_MACMODES +	help +	  This driver supports a frame buffer for the "platinum" graphics +	  adapter in some Power Macintoshes. + +config FB_VALKYRIE +	bool "Apple \"valkyrie\" display support" +	depends on (FB = y) && (MAC || (PPC_PMAC && PPC32)) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_MACMODES +	help +	  This driver supports a frame buffer for the "valkyrie" graphics +	  adapter in some Power Macintoshes. + +config FB_CT65550 +	bool "Chips 65550 display support" +	depends on (FB = y) && PPC32 && PCI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the Chips & Technologies +	  65550 graphics chip in PowerBooks. + +config FB_ASILIANT +	bool "Asiliant (Chips) 69000 display support" +	depends on (FB = y) && PCI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the Asiliant 69030 chipset + +config FB_IMSTT +	bool "IMS Twin Turbo display support" +	depends on (FB = y) && PCI +	select FB_CFB_IMAGEBLIT +	select FB_MACMODES if PPC +	help +	  The IMS Twin Turbo is a PCI-based frame buffer card bundled with +	  many Macintosh and compatible computers. + +config FB_VGA16 +	tristate "VGA 16-color graphics support" +	depends on FB && (X86 || PPC) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select VGASTATE +	select FONT_8x16 if FRAMEBUFFER_CONSOLE +	help +	  This is the frame buffer device driver for VGA 16 color graphic +	  cards. Say Y if you have such a card. + +	  To compile this driver as a module, choose M here: the +	  module will be called vga16fb. + +config FB_BF54X_LQ043 +	tristate "SHARP LQ043 TFT LCD (BF548 EZKIT)" +	depends on FB && (BF54x) && !BF542 +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	 This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD + +config FB_BFIN_T350MCQB +	tristate "Varitronix COG-T350MCQB TFT LCD display (BF527 EZKIT)" +	depends on FB && BLACKFIN +	select BFIN_GPTIMERS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	 This is the framebuffer device driver for a Varitronix VL-PS-COG-T350MCQB-01 display TFT LCD +	 This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI +	 It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK. + +config FB_BFIN_LQ035Q1 +	tristate "SHARP LQ035Q1DH02 TFT LCD" +	depends on FB && BLACKFIN && SPI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select BFIN_GPTIMERS +	help +	  This is the framebuffer device driver for a SHARP LQ035Q1DH02 TFT display found on +	  the Blackfin Landscape LCD EZ-Extender Card. +	  This display is a QVGA 320x240 18-bit RGB display interfaced by an 16-bit wide PPI +	  It uses PPI[0..15] PPI_FS1, PPI_FS2 and PPI_CLK. + +	  To compile this driver as a module, choose M here: the +	  module will be called bfin-lq035q1-fb. + +config FB_BF537_LQ035 +	tristate "SHARP LQ035 TFT LCD (BF537 STAMP)" +	depends on FB && (BF534 || BF536 || BF537) && I2C_BLACKFIN_TWI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select BFIN_GPTIMERS +	help +	  This is the framebuffer device for a SHARP LQ035Q7DB03 TFT LCD +	  attached to a BF537. + +	  To compile this driver as a module, choose M here: the +	  module will be called bf537-lq035. + +config FB_BFIN_7393 +	tristate "Blackfin ADV7393 Video encoder" +	depends on FB && BLACKFIN +	select I2C +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the framebuffer device for a ADV7393 video encoder +	  attached to a Blackfin on the PPI port. +	  If your Blackfin board has a ADV7393 select Y. + +	  To compile this driver as a module, choose M here: the +	  module will be called bfin_adv7393fb. + +choice +	prompt  "Video mode support" +	depends on FB_BFIN_7393 +	default NTSC + +config NTSC +	bool 'NTSC 720x480' + +config PAL +	bool 'PAL 720x576' + +config NTSC_640x480 +	bool 'NTSC 640x480 (Experimental)' + +config PAL_640x480 +	bool 'PAL 640x480 (Experimental)' + +config NTSC_YCBCR +	bool 'NTSC 720x480 YCbCR input' + +config PAL_YCBCR +	bool 'PAL 720x576 YCbCR input' + +endchoice + +choice +	prompt  "Size of ADV7393 frame buffer memory Single/Double Size" +	depends on (FB_BFIN_7393) +	default ADV7393_1XMEM + +config ADV7393_1XMEM +	bool 'Single' + +config ADV7393_2XMEM +	bool 'Double' +endchoice + +config FB_STI +	tristate "HP STI frame buffer device support" +	depends on FB && PARISC +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select STI_CONSOLE +	select VT +	default y +	---help--- +	  STI refers to the HP "Standard Text Interface" which is a set of +	  BIOS routines contained in a ROM chip in HP PA-RISC based machines. +	  Enabling this option will implement the linux framebuffer device +	  using calls to the STI BIOS routines for initialisation. +	 +	  If you enable this option, you will get a planar framebuffer device +	  /dev/fb which will work on the most common HP graphic cards of the +	  NGLE family, including the artist chips (in the 7xx and Bxxx series), +	  HCRX, HCRX24, CRX, CRX24 and VisEG series. + +	  It is safe to enable this option, so you should probably say "Y". + +config FB_MAC +	bool "Generic Macintosh display support" +	depends on (FB = y) && MAC +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_MACMODES + +config FB_HP300 +	bool +	depends on (FB = y) && DIO +	select FB_CFB_IMAGEBLIT +	default y + +config FB_TGA +	tristate "TGA/SFB+ framebuffer support" +	depends on FB && (ALPHA || TC) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select BITREVERSE +	---help--- +	  This is the frame buffer device driver for generic TGA and SFB+ +	  graphic cards.  These include DEC ZLXp-E1, -E2 and -E3 PCI cards, +	  also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3 +	  TURBOchannel cards, also known as PMAGD-A, -B and -C. + +	  Due to hardware limitations ZLX-E2 and E3 cards are not supported +	  for DECstation 5000/200 systems.  Additionally due to firmware +	  limitations these cards may cause troubles with booting DECstation +	  5000/240 and /260 systems, but are fully supported under Linux if +	  you manage to get it going. ;-) + +	  Say Y if you have one of those. + +config FB_UVESA +	tristate "Userspace VESA VGA graphics support" +	depends on FB && CONNECTOR +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_MODE_HELPERS +	help +	  This is the frame buffer driver for generic VBE 2.0 compliant +	  graphic cards. It can also take advantage of VBE 3.0 features, +	  such as refresh rate adjustment. + +	  This driver generally provides more features than vesafb but +	  requires a userspace helper application called 'v86d'. See +	  <file:Documentation/fb/uvesafb.txt> for more information. + +	  If unsure, say N. + +config FB_VESA +	bool "VESA VGA graphics support" +	depends on (FB = y) && X86 +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_BOOT_VESA_SUPPORT +	help +	  This is the frame buffer device driver for generic VESA 2.0 +	  compliant graphic cards. The older VESA 1.2 cards are not supported. +	  You will get a boot time penguin logo at no additional cost. Please +	  read <file:Documentation/fb/vesafb.txt>. If unsure, say Y. + +config FB_EFI +	bool "EFI-based Framebuffer Support" +	depends on (FB = y) && X86 && EFI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the EFI frame buffer device driver. If the firmware on +	  your platform is EFI 1.10 or UEFI 2.0, select Y to add support for +	  using the EFI framebuffer as your console. + +config FB_N411 +       tristate "N411 Apollo/Hecuba devkit support" +       depends on FB && X86 && MMU +       select FB_SYS_FILLRECT +       select FB_SYS_COPYAREA +       select FB_SYS_IMAGEBLIT +       select FB_SYS_FOPS +       select FB_DEFERRED_IO +       select FB_HECUBA +       help +         This enables support for the Apollo display controller in its +         Hecuba form using the n411 devkit. + +config FB_HGA +	tristate "Hercules mono graphics support" +	depends on FB && X86 +	help +	  Say Y here if you have a Hercules mono graphics card. + +	  To compile this driver as a module, choose M here: the +	  module will be called hgafb. + +	  As this card technology is at least 25 years old, +	  most people will answer N here. + +config FB_GBE +	bool "SGI Graphics Backend frame buffer support" +	depends on (FB = y) && SGI_IP32 +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT + 	help +	  This is the frame buffer device driver for SGI Graphics Backend. +	  This chip is used in SGI O2 and Visual Workstation 320/540. + +config FB_GBE_MEM +	int "Video memory size in MB" +	depends on FB_GBE +	default 4 +	help +	  This is the amount of memory reserved for the framebuffer, +	  which can be any value between 1MB and 8MB. + +config FB_SBUS +	bool "SBUS and UPA framebuffers" +	depends on (FB = y) && SPARC +	help +	  Say Y if you want support for SBUS or UPA based frame buffer device. + +config FB_BW2 +	bool "BWtwo support" +	depends on (FB = y) && (SPARC && FB_SBUS) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the BWtwo frame buffer. + +config FB_CG3 +	bool "CGthree support" +	depends on (FB = y) && (SPARC && FB_SBUS) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the CGthree frame buffer. + +config FB_CG6 +	bool "CGsix (GX,TurboGX) support" +	depends on (FB = y) && (SPARC && FB_SBUS) +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the CGsix (GX, TurboGX) +	  frame buffer. + +config FB_FFB +	bool "Creator/Creator3D/Elite3D support" +	depends on FB_SBUS && SPARC64 +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the Creator, Creator3D, +	  and Elite3D graphics boards. + +config FB_TCX +	bool "TCX (SS4/SS5 only) support" +	depends on FB_SBUS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the TCX 24/8bit frame +	  buffer. + +config FB_CG14 +	bool "CGfourteen (SX) support" +	depends on FB_SBUS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the CGfourteen frame +	  buffer on Desktop SPARCsystems with the SX graphics option. + +config FB_P9100 +	bool "P9100 (Sparcbook 3 only) support" +	depends on FB_SBUS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the P9100 card +	  supported on Sparcbook 3 machines. + +config FB_LEO +	bool "Leo (ZX) support" +	depends on FB_SBUS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the SBUS-based Sun ZX +	  (leo) frame buffer cards. + +config FB_IGA +	bool "IGA 168x display support" +	depends on (FB = y) && SPARC32 +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the framebuffer device for the INTERGRAPHICS 1680 and +	  successor frame buffer cards. + +config FB_XVR500 +	bool "Sun XVR-500 3DLABS Wildcat support" +	depends on (FB = y) && PCI && SPARC64 +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the framebuffer device for the Sun XVR-500 and similar +	  graphics cards based upon the 3DLABS Wildcat chipset.  The driver +	  only works on sparc64 systems where the system firmware has +	  mostly initialized the card already.  It is treated as a +	  completely dumb framebuffer device. + +config FB_XVR2500 +	bool "Sun XVR-2500 3DLABS Wildcat support" +	depends on (FB = y) && PCI && SPARC64 +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the framebuffer device for the Sun XVR-2500 and similar +	  graphics cards based upon the 3DLABS Wildcat chipset.  The driver +	  only works on sparc64 systems where the system firmware has +	  mostly initialized the card already.  It is treated as a +	  completely dumb framebuffer device. + +config FB_XVR1000 +	bool "Sun XVR-1000 support" +	depends on (FB = y) && SPARC64 +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the framebuffer device for the Sun XVR-1000 and similar +	  graphics cards.  The driver only works on sparc64 systems where +	  the system firmware has mostly initialized the card already.  It +	  is treated as a completely dumb framebuffer device. + +config FB_PVR2 +	tristate "NEC PowerVR 2 display support" +	depends on FB && SH_DREAMCAST +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Say Y here if you have a PowerVR 2 card in your box.  If you plan to +	  run linux on your Dreamcast, you will have to say Y here. +	  This driver may or may not work on other PowerVR 2 cards, but is +	  totally untested.  Use at your own risk.  If unsure, say N. + +	  To compile this driver as a module, choose M here: the +	  module will be called pvr2fb. + +	  You can pass several parameters to the driver at boot time or at +	  module load time.  The parameters look like "video=pvr2:XXX", where +	  the meaning of XXX can be found at the end of the main source file +	  (<file:drivers/video/pvr2fb.c>). Please see the file +	  <file:Documentation/fb/pvr2fb.txt>. + +config FB_OPENCORES +	tristate "OpenCores VGA/LCD core 2.0 framebuffer support" +	depends on FB && HAS_DMA +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This enables support for the OpenCores VGA/LCD core. + +	  The OpenCores VGA/LCD core is typically used together with +	  softcore CPUs (e.g. OpenRISC or Microblaze) or hard processor +	  systems (e.g. Altera socfpga or Xilinx Zynq) on FPGAs. + +	  The source code and specification for the core is available at +	  <http://opencores.org/project,vga_lcd> + +config FB_S1D13XXX +	tristate "Epson S1D13XXX framebuffer support" +	depends on FB +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  Support for S1D13XXX framebuffer device family (currently only +	  working with S1D13806). Product specs at +	  <http://vdc.epson.com/> + +config FB_ATMEL +	tristate "AT91/AT32 LCD Controller support" +	depends on FB && HAVE_FB_ATMEL +	select FB_BACKLIGHT +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_MODE_HELPERS +	select VIDEOMODE_HELPERS +	help +	  This enables support for the AT91/AT32 LCD Controller. + +config FB_INTSRAM +	bool "Frame Buffer in internal SRAM" +	depends on FB_ATMEL && ARCH_AT91SAM9261 +	help +	  Say Y if you want to map Frame Buffer in internal SRAM. Say N if you want +	  to let frame buffer in external SDRAM. + +config FB_ATMEL_STN +	bool "Use a STN display with AT91/AT32 LCD Controller" +	depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK) +	default n +	help +	  Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD +	  Controller. Say N if you want to connect a TFT. + +	  If unsure, say N. + +config FB_NVIDIA +	tristate "nVidia Framebuffer Support" +	depends on FB && PCI +	select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT +	select FB_MODE_HELPERS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select BITREVERSE +	select VGASTATE +	help +	  This driver supports graphics boards with the nVidia chips, TNT +	  and newer. For very old chipsets, such as the RIVA128, then use +	  the rivafb. +	  Say Y if you have such a graphics board. + +	  To compile this driver as a module, choose M here: the +	  module will be called nvidiafb. + +config FB_NVIDIA_I2C +       bool "Enable DDC Support" +       depends on FB_NVIDIA +       select FB_DDC +       help +	  This enables I2C support for nVidia Chipsets.  This is used +	  only for getting EDID information from the attached display +	  allowing for robust video mode handling and switching. + +	  Because fbdev-2.6 requires that drivers must be able to +	  independently validate video mode parameters, you should say Y +	  here. + +config FB_NVIDIA_DEBUG +	bool "Lots of debug output" +	depends on FB_NVIDIA +	default n +	help +	  Say Y here if you want the nVidia driver to output all sorts +	  of debugging information to provide to the maintainer when +	  something goes wrong. + +config FB_NVIDIA_BACKLIGHT +	bool "Support for backlight control" +	depends on FB_NVIDIA +	default y +	help +	  Say Y here if you want to control the backlight of your display. + +config FB_RIVA +	tristate "nVidia Riva support" +	depends on FB && PCI +	select FB_BACKLIGHT if FB_RIVA_BACKLIGHT +	select FB_MODE_HELPERS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select BITREVERSE +	select VGASTATE +	help +	  This driver supports graphics boards with the nVidia Riva/Geforce +	  chips. +	  Say Y if you have such a graphics board. + +	  To compile this driver as a module, choose M here: the +	  module will be called rivafb. + +config FB_RIVA_I2C +       bool "Enable DDC Support" +       depends on FB_RIVA +       select FB_DDC +       help +	  This enables I2C support for nVidia Chipsets.  This is used +	  only for getting EDID information from the attached display +	  allowing for robust video mode handling and switching. + +	  Because fbdev-2.6 requires that drivers must be able to +	  independently validate video mode parameters, you should say Y +	  here. + +config FB_RIVA_DEBUG +	bool "Lots of debug output" +	depends on FB_RIVA +	default n +	help +	  Say Y here if you want the Riva driver to output all sorts +	  of debugging information to provide to the maintainer when +	  something goes wrong. + +config FB_RIVA_BACKLIGHT +	bool "Support for backlight control" +	depends on FB_RIVA +	default y +	help +	  Say Y here if you want to control the backlight of your display. + +config FB_I740 +	tristate "Intel740 support" +	depends on FB && PCI +	select FB_MODE_HELPERS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select VGASTATE +	select FB_DDC +	help +	  This driver supports graphics cards based on Intel740 chip. + +config FB_I810 +	tristate "Intel 810/815 support" +	depends on FB && PCI && X86_32 && AGP_INTEL +	select FB_MODE_HELPERS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select VGASTATE +	help +	  This driver supports the on-board graphics built in to the Intel 810  +          and 815 chipsets.  Say Y if you have and plan to use such a board. + +          To compile this driver as a module, choose M here: the +	  module will be called i810fb. + +          For more information, please read  +	  <file:Documentation/fb/intel810.txt> + +config FB_I810_GTF +	bool "use VESA Generalized Timing Formula" +	depends on FB_I810 +	help +	  If you say Y, then the VESA standard, Generalized Timing Formula  +          or GTF, will be used to calculate the required video timing values +	  per video mode.  Since the GTF allows nondiscrete timings  +          (nondiscrete being a range of values as opposed to discrete being a +          set of values), you'll be able to use any combination of horizontal  +	  and vertical resolutions, and vertical refresh rates without having +	  to specify your own timing parameters.  This is especially useful +	  to maximize the performance of an aging display, or if you just  +          have a display with nonstandard dimensions. A VESA compliant  +	  monitor is recommended, but can still work with non-compliant ones. +	  If you need or want this, then select this option. The timings may  +	  not be compliant with Intel's recommended values. Use at your own  +	  risk. + +          If you say N, the driver will revert to discrete video timings  +	  using a set recommended by Intel in their documentation. +   +          If unsure, say N. + +config FB_I810_I2C +	bool "Enable DDC Support" +	depends on FB_I810 && FB_I810_GTF +	select FB_DDC +	help + +config FB_LE80578 +	tristate "Intel LE80578 (Vermilion) support" +	depends on FB && PCI && X86 +	select FB_MODE_HELPERS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This driver supports the LE80578 (Vermilion Range) chipset + +config FB_CARILLO_RANCH +	tristate "Intel Carillo Ranch support" +	depends on FB_LE80578 && FB && PCI && X86 +	help +	  This driver supports the LE80578 (Carillo Ranch) board + +config FB_INTEL +	tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support" +	depends on FB && PCI && X86 && AGP_INTEL && EXPERT +	select FB_MODE_HELPERS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_BOOT_VESA_SUPPORT if FB_INTEL = y +	depends on !DRM_I915 +	help +	  This driver supports the on-board graphics built in to the Intel +          830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets. +          Say Y if you have and plan to use such a board. + +	  To make FB_INTELFB=Y work you need to say AGP_INTEL=y too. + +	  To compile this driver as a module, choose M here: the +	  module will be called intelfb. + +	  For more information, please read <file:Documentation/fb/intelfb.txt> + +config FB_INTEL_DEBUG +	bool "Intel driver Debug Messages" +	depends on FB_INTEL +	---help--- +	  Say Y here if you want the Intel driver to output all sorts +	  of debugging information to provide to the maintainer when +	  something goes wrong. + +config FB_INTEL_I2C +	bool "DDC/I2C for Intel framebuffer support" +	depends on FB_INTEL +	select FB_DDC +	default y +	help +	  Say Y here if you want DDC/I2C support for your on-board Intel graphics. + +config FB_MATROX +	tristate "Matrox acceleration" +	depends on FB && PCI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_TILEBLITTING +	select FB_MACMODES if PPC_PMAC +	---help--- +	  Say Y here if you have a Matrox Millennium, Matrox Millennium II, +	  Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox +	  Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video, +	  Matrox G400, G450 or G550 card in your box. + +	  To compile this driver as a module, choose M here: the +	  module will be called matroxfb. + +	  You can pass several parameters to the driver at boot time or at +	  module load time. The parameters look like "video=matroxfb:XXX", and +	  are described in <file:Documentation/fb/matroxfb.txt>. + +config FB_MATROX_MILLENIUM +	bool "Millennium I/II support" +	depends on FB_MATROX +	help +	  Say Y here if you have a Matrox Millennium or Matrox Millennium II +	  video card. If you select "Advanced lowlevel driver options" below, +	  you should check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp +	  packed pixel, 24 bpp packed pixel and 32 bpp packed pixel. You can +	  also use font widths different from 8. + +config FB_MATROX_MYSTIQUE +	bool "Mystique support" +	depends on FB_MATROX +	help +	  Say Y here if you have a Matrox Mystique or Matrox Mystique 220 +	  video card. If you select "Advanced lowlevel driver options" below, +	  you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp +	  packed pixel and 32 bpp packed pixel. You can also use font widths +	  different from 8. + +config FB_MATROX_G +	bool "G100/G200/G400/G450/G550 support" +	depends on FB_MATROX +	---help--- +	  Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based +	  video card. If you select "Advanced lowlevel driver options", you +	  should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed +	  pixel and 32 bpp packed pixel. You can also use font widths +	  different from 8. + +	  If you need support for G400 secondary head, you must say Y to +	  "Matrox I2C support" and "G400 second head support" right below. +	  G450/G550 secondary head and digital output are supported without +	  additional modules. + +	  The driver starts in monitor mode. You must use the matroxset tool  +	  (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to  +	  swap primary and secondary head outputs, or to change output mode.   +	  Secondary head driver always start in 640x480 resolution and you  +	  must use fbset to change it. + +	  Do not forget that second head supports only 16 and 32 bpp +	  packed pixels, so it is a good idea to compile them into the kernel +	  too. You can use only some font widths, as the driver uses generic +	  painting procedures (the secondary head does not use acceleration +	  engine). + +	  G450/G550 hardware can display TV picture only from secondary CRTC, +	  and it performs no scaling, so picture must have 525 or 625 lines. + +config FB_MATROX_I2C +	tristate "Matrox I2C support" +	depends on FB_MATROX +	select FB_DDC +	---help--- +	  This drivers creates I2C buses which are needed for accessing the +	  DDC (I2C) bus present on all Matroxes, an I2C bus which +	  interconnects Matrox optional devices, like MGA-TVO on G200 and +	  G400, and the secondary head DDC bus, present on G400 only. + +	  You can say Y or M here if you want to experiment with monitor +	  detection code. You must say Y or M here if you want to use either +	  second head of G400 or MGA-TVO on G200 or G400. + +	  If you compile it as module, it will create a module named +	  i2c-matroxfb. + +config FB_MATROX_MAVEN +	tristate "G400 second head support" +	depends on FB_MATROX_G && FB_MATROX_I2C +	---help--- +	  WARNING !!! This support does not work with G450 !!! + +	  Say Y or M here if you want to use a secondary head (meaning two +	  monitors in parallel) on G400 or MGA-TVO add-on on G200. Secondary +	  head is not compatible with accelerated XFree 3.3.x SVGA servers - +	  secondary head output is blanked while you are in X. With XFree +	  3.9.17 preview you can use both heads if you use SVGA over fbdev or +	  the fbdev driver on first head and the fbdev driver on second head. + +	  If you compile it as module, two modules are created, +	  matroxfb_crtc2 and matroxfb_maven. Matroxfb_maven is needed for +	  both G200 and G400, matroxfb_crtc2 is needed only by G400. You must +	  also load i2c-matroxfb to get it to run. + +	  The driver starts in monitor mode and you must use the matroxset +	  tool (available at +	  <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to switch it to +	  PAL or NTSC or to swap primary and secondary head outputs. +	  Secondary head driver also always start in 640x480 resolution, you +	  must use fbset to change it. + +	  Also do not forget that second head supports only 16 and 32 bpp +	  packed pixels, so it is a good idea to compile them into the kernel +	  too.  You can use only some font widths, as the driver uses generic +	  painting procedures (the secondary head does not use acceleration +	  engine). + +config FB_RADEON +	tristate "ATI Radeon display support" +	depends on FB && PCI +	select FB_BACKLIGHT if FB_RADEON_BACKLIGHT +	select FB_MODE_HELPERS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_MACMODES if PPC_OF +	help +	  Choose this option if you want to use an ATI Radeon graphics card as +	  a framebuffer device.  There are both PCI and AGP versions.  You +	  don't need to choose this to run the Radeon in plain VGA mode. + +	  There is a product page at +	  http://products.amd.com/en-us/GraphicCardResult.aspx + +config FB_RADEON_I2C +	bool "DDC/I2C for ATI Radeon support" +	depends on FB_RADEON +	select FB_DDC +	default y +	help +	  Say Y here if you want DDC/I2C support for your Radeon board.  + +config FB_RADEON_BACKLIGHT +	bool "Support for backlight control" +	depends on FB_RADEON +	default y +	help +	  Say Y here if you want to control the backlight of your display. + +config FB_RADEON_DEBUG +	bool "Lots of debug output from Radeon driver" +	depends on FB_RADEON +	default n +	help +	  Say Y here if you want the Radeon driver to output all sorts +	  of debugging information to provide to the maintainer when +	  something goes wrong. + +config FB_ATY128 +	tristate "ATI Rage128 display support" +	depends on FB && PCI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_BACKLIGHT if FB_ATY128_BACKLIGHT +	select FB_MACMODES if PPC_PMAC +	help +	  This driver supports graphics boards with the ATI Rage128 chips. +	  Say Y if you have such a graphics board and read +	  <file:Documentation/fb/aty128fb.txt>. + +	  To compile this driver as a module, choose M here: the +	  module will be called aty128fb. + +config FB_ATY128_BACKLIGHT +	bool "Support for backlight control" +	depends on FB_ATY128 +	default y +	help +	  Say Y here if you want to control the backlight of your display. + +config FB_ATY +	tristate "ATI Mach64 display support" if PCI || ATARI +	depends on FB && !SPARC32 +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_BACKLIGHT if FB_ATY_BACKLIGHT +	select FB_MACMODES if PPC +	help +	  This driver supports graphics boards with the ATI Mach64 chips. +	  Say Y if you have such a graphics board. + +	  To compile this driver as a module, choose M here: the +	  module will be called atyfb. + +config FB_ATY_CT +	bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support" +	depends on PCI && FB_ATY +	default y if SPARC64 && PCI +	help +	  Say Y here to support use of ATI's 64-bit Rage boards (or other +	  boards based on the Mach64 CT, VT, GT, and LT chipsets) as a +	  framebuffer device.  The ATI product support page for these boards +	  is at <http://support.ati.com/products/pc/mach64/mach64.html>. + +config FB_ATY_GENERIC_LCD +	bool "Mach64 generic LCD support" +	depends on FB_ATY_CT +	help +	  Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility, +	  Rage XC, or Rage XL chipset. + +config FB_ATY_GX +	bool "Mach64 GX support" if PCI +	depends on FB_ATY +	default y if ATARI +	help +	  Say Y here to support use of the ATI Mach64 Graphics Expression +	  board (or other boards based on the Mach64 GX chipset) as a +	  framebuffer device.  The ATI product support page for these boards +	  is at +	  <http://support.ati.com/products/pc/mach64/graphics_xpression.html>. + +config FB_ATY_BACKLIGHT +	bool "Support for backlight control" +	depends on FB_ATY +	default y +	help +	  Say Y here if you want to control the backlight of your display. + +config FB_S3 +	tristate "S3 Trio/Virge support" +	depends on FB && PCI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_TILEBLITTING +	select FB_SVGALIB +	select VGASTATE +	select FONT_8x16 if FRAMEBUFFER_CONSOLE +	---help--- +	  Driver for graphics boards with S3 Trio / S3 Virge chip. + +config FB_S3_DDC +	bool "DDC for S3 support" +	depends on FB_S3 +	select FB_DDC +	default y +	help +	  Say Y here if you want DDC support for your S3 graphics card. + +config FB_SAVAGE +	tristate "S3 Savage support" +	depends on FB && PCI +	select FB_MODE_HELPERS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select VGASTATE +	help +	  This driver supports notebooks and computers with S3 Savage PCI/AGP +	  chips. + +	  Say Y if you have such a graphics card. + +	  To compile this driver as a module, choose M here; the module +	  will be called savagefb. + +config FB_SAVAGE_I2C +       bool "Enable DDC2 Support" +       depends on FB_SAVAGE +       select FB_DDC +       help +	  This enables I2C support for S3 Savage Chipsets.  This is used +	  only for getting EDID information from the attached display +	  allowing for robust video mode handling and switching. + +	  Because fbdev-2.6 requires that drivers must be able to +	  independently validate video mode parameters, you should say Y +	  here. + +config FB_SAVAGE_ACCEL +       bool "Enable Console Acceleration" +       depends on FB_SAVAGE +       default n +       help +          This option will compile in console acceleration support. If +          the resulting framebuffer console has bothersome glitches, then +          choose N here. + +config FB_SIS +	tristate "SiS/XGI display support" +	depends on FB && PCI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_BOOT_VESA_SUPPORT if FB_SIS = y +	help +	  This is the frame buffer device driver for the SiS 300, 315, 330 +	  and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets. +	  Specs available at <http://www.sis.com> and <http://www.xgitech.com>. + +	  To compile this driver as a module, choose M here; the module +	  will be called sisfb. + +config FB_SIS_300 +	bool "SiS 300 series support" +	depends on FB_SIS +	help +	  Say Y here to support use of the SiS 300/305, 540, 630 and 730. + +config FB_SIS_315 +	bool "SiS 315/330/340 series and XGI support" +	depends on FB_SIS +	help +	  Say Y here to support use of the SiS 315, 330 and 340 series +	  (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well +	  as XGI V3XT, V5, V8 and Z7. + +config FB_VIA +       tristate "VIA UniChrome (Pro) and Chrome9 display support" +       depends on FB && PCI && X86 +       select FB_CFB_FILLRECT +       select FB_CFB_COPYAREA +       select FB_CFB_IMAGEBLIT +       select I2C_ALGOBIT +       select I2C +       select GPIOLIB +       help +	  This is the frame buffer device driver for Graphics chips of VIA +	  UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/ +	  CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896 + 	  /P4M900,VX800) +	  Say Y if you have a VIA UniChrome graphics board. + +	  To compile this driver as a module, choose M here: the +	  module will be called viafb. + +if FB_VIA + +config FB_VIA_DIRECT_PROCFS +	bool "direct hardware access via procfs (DEPRECATED)(DANGEROUS)" +	depends on FB_VIA +	default n +	help +	  Allow direct hardware access to some output registers via procfs. +	  This is dangerous but may provide the only chance to get the +	  correct output device configuration. +	  Its use is strongly discouraged. + +config FB_VIA_X_COMPATIBILITY +	bool "X server compatibility" +	depends on FB_VIA +	default n +	help +	  This option reduces the functionality (power saving, ...) of the +	  framebuffer to avoid negative impact on the OpenChrome X server. +	  If you use any X server other than fbdev you should enable this +	  otherwise it should be safe to disable it and allow using all +	  features. + +endif + +config FB_NEOMAGIC +	tristate "NeoMagic display support" +	depends on FB && PCI +	select FB_MODE_HELPERS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select VGASTATE +	help +	  This driver supports notebooks with NeoMagic PCI chips. +	  Say Y if you have such a graphics card.  + +	  To compile this driver as a module, choose M here: the +	  module will be called neofb. + +config FB_KYRO +	tristate "IMG Kyro support" +	depends on FB && PCI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  Say Y here if you have a STG4000 / Kyro / PowerVR 3 based +	  graphics board. + +	  To compile this driver as a module, choose M here: the +	  module will be called kyrofb. + +config FB_3DFX +	tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support" +	depends on FB && PCI +	select FB_CFB_IMAGEBLIT +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_MODE_HELPERS +	help +	  This driver supports graphics boards with the 3Dfx Banshee, +	  Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have +	  such a graphics board. + +	  To compile this driver as a module, choose M here: the +	  module will be called tdfxfb. + +config FB_3DFX_ACCEL +	bool "3Dfx Acceleration functions" +	depends on FB_3DFX +	---help--- +	This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer +	device driver with acceleration functions. + +config FB_3DFX_I2C +	bool "Enable DDC/I2C support" +	depends on FB_3DFX +	select FB_DDC +	default y +	help +	  Say Y here if you want DDC/I2C support for your 3dfx Voodoo3. + +config FB_VOODOO1 +	tristate "3Dfx Voodoo Graphics (sst1) support" +	depends on FB && PCI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or  +	  Voodoo2 (cvg) based graphics card. + +	  To compile this driver as a module, choose M here: the +	  module will be called sstfb. + +	  WARNING: Do not use any application that uses the 3D engine +	  (namely glide) while using this driver. +	  Please read the <file:Documentation/fb/sstfb.txt> for supported +	  options and other important info  support. + +config FB_VT8623 +	tristate "VIA VT8623 support" +	depends on FB && PCI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_TILEBLITTING +	select FB_SVGALIB +	select VGASTATE +	select FONT_8x16 if FRAMEBUFFER_CONSOLE +	---help--- +	  Driver for CastleRock integrated graphics core in the +	  VIA VT8623 [Apollo CLE266] chipset. + +config FB_TRIDENT +	tristate "Trident/CyberXXX/CyberBlade support" +	depends on FB && PCI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  This is the frame buffer device driver for Trident PCI/AGP chipsets. +	  Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D +	  and Blade XP. +	  There are also integrated versions of these chips called CyberXXXX, +	  CyberImage or CyberBlade. These chips are mostly found in laptops +	  but also on some motherboards including early VIA EPIA motherboards. +	  For more information, read <file:Documentation/fb/tridentfb.txt> + +	  Say Y if you have such a graphics board. + +	  To compile this driver as a module, choose M here: the +	  module will be called tridentfb. + +config FB_ARK +	tristate "ARK 2000PV support" +	depends on FB && PCI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_TILEBLITTING +	select FB_SVGALIB +	select VGASTATE +	select FONT_8x16 if FRAMEBUFFER_CONSOLE +	---help--- +	  Driver for PCI graphics boards with ARK 2000PV chip +	  and ICS 5342 RAMDAC. + +config FB_PM3 +	tristate "Permedia3 support" +	depends on FB && PCI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the 3DLabs Permedia3 +	  chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 & +	  similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000 +	  and maybe other boards. + +config FB_CARMINE +	tristate "Fujitsu carmine frame buffer support" +	depends on FB && PCI +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the Fujitsu Carmine chip. +	  The driver provides two independent frame buffer devices. + +choice +	depends on FB_CARMINE +	prompt "DRAM timing" +	default FB_CARMINE_DRAM_EVAL + +config FB_CARMINE_DRAM_EVAL +	bool "Eval board timings" +	help +	  Use timings which work on the eval card. + +config CARMINE_DRAM_CUSTOM +	bool "Custom board timings" +	help +	  Use custom board timings. +endchoice + +config FB_AU1100 +	bool "Au1100 LCD Driver" +	depends on (FB = y) && MIPS_ALCHEMY +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the framebuffer driver for the AMD Au1100 SOC.  It can drive +	  various panels and CRTs by passing in kernel cmd line option +	  au1100fb:panel=<name>. + +config FB_AU1200 +	bool "Au1200/Au1300 LCD Driver" +	depends on (FB = y) && MIPS_ALCHEMY +	select FB_SYS_FILLRECT +	select FB_SYS_COPYAREA +	select FB_SYS_IMAGEBLIT +	select FB_SYS_FOPS +	help +	  This is the framebuffer driver for the Au1200/Au1300 SOCs. +	  It can drive various panels and CRTs by passing in kernel cmd line +	  option au1200fb:panel=<name>. + +config FB_VT8500 +	bool "VIA VT8500 framebuffer support" +	depends on (FB = y) && ARM && ARCH_VT8500 +	select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS) +	select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS) +	select FB_SYS_IMAGEBLIT +	select FB_MODE_HELPERS +	select VIDEOMODE_HELPERS +	help +	  This is the framebuffer driver for VIA VT8500 integrated LCD +	  controller. + +config FB_WM8505 +	bool "Wondermedia WM8xxx-series frame buffer support" +	depends on (FB = y) && ARM && ARCH_VT8500 +	select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS) +	select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS) +	select FB_SYS_IMAGEBLIT +	select FB_MODE_HELPERS +	select VIDEOMODE_HELPERS +	help +	  This is the framebuffer driver for WonderMedia WM8xxx-series +	  integrated LCD controller. This driver covers the WM8505, WM8650 +	  and WM8850 SoCs. + +config FB_WMT_GE_ROPS +	bool "VT8500/WM8xxx accelerated raster ops support" +	depends on (FB = y) && (FB_VT8500 || FB_WM8505) +	default n +	help +	  This adds support for accelerated raster operations on the +	  VIA VT8500 and Wondermedia 85xx series SoCs. + +source "drivers/video/fbdev/geode/Kconfig" + +config FB_HIT +	tristate "HD64461 Frame Buffer support" +	depends on FB && HD64461 +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This is the frame buffer device driver for the Hitachi HD64461 LCD +	  frame buffer card. + +config FB_PMAG_AA +	bool "PMAG-AA TURBOchannel framebuffer support" +	depends on (FB = y) && TC + 	select FB_CFB_FILLRECT + 	select FB_CFB_COPYAREA + 	select FB_CFB_IMAGEBLIT +	help +	  Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1) +	  used mainly in the MIPS-based DECstation series. + +config FB_PMAG_BA +	tristate "PMAG-BA TURBOchannel framebuffer support" +	depends on FB && TC + 	select FB_CFB_FILLRECT + 	select FB_CFB_COPYAREA + 	select FB_CFB_IMAGEBLIT +	help +	  Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8) +	  used mainly in the MIPS-based DECstation series. + +config FB_PMAGB_B +	tristate "PMAGB-B TURBOchannel framebuffer support" +	depends on FB && TC + 	select FB_CFB_FILLRECT + 	select FB_CFB_COPYAREA + 	select FB_CFB_IMAGEBLIT +	help +	  Support for the PMAGB-B TURBOchannel framebuffer card used mainly +	  in the MIPS-based DECstation series. The card is currently only +	  supported in 1280x1024x8 mode. + +config FB_MAXINE +	bool "Maxine (Personal DECstation) onboard framebuffer support" +	depends on (FB = y) && MACH_DECSTATION + 	select FB_CFB_FILLRECT + 	select FB_CFB_COPYAREA + 	select FB_CFB_IMAGEBLIT +	help +	  Support for the onboard framebuffer (1024x768x8) in the Personal +	  DECstation series (Personal DECstation 5000/20, /25, /33, /50, +	  Codename "Maxine"). + +config FB_G364 +	bool "G364 frame buffer support" +	depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700) + 	select FB_CFB_FILLRECT + 	select FB_CFB_COPYAREA + 	select FB_CFB_IMAGEBLIT +	help +	  The G364 driver is the framebuffer used in MIPS Magnum 4000 and +	  Olivetti M700-10 systems. + +config FB_68328 +	bool "Motorola 68328 native frame buffer support" +	depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328) + 	select FB_CFB_FILLRECT + 	select FB_CFB_COPYAREA + 	select FB_CFB_IMAGEBLIT +	help +	  Say Y here if you want to support the built-in frame buffer of +	  the Motorola 68328 CPU family. + +config FB_PXA168 +	tristate "PXA168/910 LCD framebuffer support" +	depends on FB && (CPU_PXA168 || CPU_PXA910) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Frame buffer driver for the built-in LCD controller in the Marvell +	  MMP processor. + +config FB_PXA +	tristate "PXA LCD framebuffer support" +	depends on FB && ARCH_PXA +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Frame buffer driver for the built-in LCD controller in the Intel +	  PXA2x0 processor. + +	  This driver is also available as a module ( = code which can be +	  inserted and removed from the running kernel whenever you want). The +	  module will be called pxafb. If you want to compile it as a module, +	  say M here and read <file:Documentation/kbuild/modules.txt>. + +	  If unsure, say N. + +config FB_PXA_OVERLAY +	bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer" +	default n +	depends on FB_PXA && (PXA27x || PXA3xx) + +config FB_PXA_SMARTPANEL +	bool "PXA Smartpanel LCD support" +	default n +	depends on FB_PXA + +config FB_PXA_PARAMETERS +	bool "PXA LCD command line parameters" +	default n +	depends on FB_PXA +	---help--- +	  Enable the use of kernel command line or module parameters +	  to configure the physical properties of the LCD panel when +	  using the PXA LCD driver. + +	  This option allows you to override the panel parameters +	  supplied by the platform in order to support multiple +	  different models of flatpanel. If you will only be using a +	  single model of flatpanel then you can safely leave this +	  option disabled. + +	  <file:Documentation/fb/pxafb.txt> describes the available parameters. + +config PXA3XX_GCU +	tristate "PXA3xx 2D graphics accelerator driver" +	depends on FB_PXA +	help +	  Kernelspace driver for the 2D graphics controller unit (GCU) +	  found on PXA3xx processors. There is a counterpart driver in the +	  DirectFB suite, see http://www.directfb.org/ + +	  If you compile this as a module, it will be called pxa3xx_gcu. + +config FB_MBX +	tristate "2700G LCD framebuffer support" +	depends on FB && ARCH_PXA +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Framebuffer driver for the Intel 2700G (Marathon) Graphics +	  Accelerator + +config FB_MBX_DEBUG +       bool "Enable debugging info via debugfs" +       depends on FB_MBX && DEBUG_FS +       default n +       ---help--- +         Enable this if you want debugging information using the debug +         filesystem (debugfs) + +         If unsure, say N. + +config FB_FSL_DIU +	tristate "Freescale DIU framebuffer support" +	depends on FB && FSL_SOC +	select FB_MODE_HELPERS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select PPC_LIB_RHEAP +	---help--- +	  Framebuffer driver for the Freescale SoC DIU + +config FB_W100 +	tristate "W100 frame buffer support" +	depends on FB && ARCH_PXA + 	select FB_CFB_FILLRECT + 	select FB_CFB_COPYAREA + 	select FB_CFB_IMAGEBLIT +	---help--- +	  Frame buffer driver for the w100 as found on the Sharp SL-Cxx series. +	  It can also drive the w3220 chip found on iPAQ hx4700. + +	  This driver is also available as a module ( = code which can be +	  inserted and removed from the running kernel whenever you want). The +	  module will be called w100fb. If you want to compile it as a module, +	  say M here and read <file:Documentation/kbuild/modules.txt>. + +	  If unsure, say N. + +config FB_SH_MOBILE_LCDC +	tristate "SuperH Mobile LCDC framebuffer support" +	depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK +	depends on FB_SH_MOBILE_MERAM || !FB_SH_MOBILE_MERAM +	select FB_SYS_FILLRECT +	select FB_SYS_COPYAREA +	select FB_SYS_IMAGEBLIT +	select FB_SYS_FOPS +	select FB_DEFERRED_IO +	select FB_BACKLIGHT +	select SH_MIPI_DSI if SH_LCD_MIPI_DSI +	---help--- +	  Frame buffer driver for the on-chip SH-Mobile LCD controller. + +config FB_SH_MOBILE_HDMI +	tristate "SuperH Mobile HDMI controller support" +	depends on FB_SH_MOBILE_LCDC +	select FB_MODE_HELPERS +	select SOUND +	select SND +	select SND_SOC +	---help--- +	  Driver for the on-chip SH-Mobile HDMI controller. + +config FB_TMIO +	tristate "Toshiba Mobile IO FrameBuffer support" +	depends on FB && (MFD_TMIO || COMPILE_TEST) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Frame buffer driver for the Toshiba Mobile IO integrated as found +	  on the Sharp SL-6000 series + +	  This driver is also available as a module ( = code which can be +	  inserted and removed from the running kernel whenever you want). The +	  module will be called tmiofb. If you want to compile it as a module, +	  say M here and read <file:Documentation/kbuild/modules.txt>. + +	  If unsure, say N. + +config FB_TMIO_ACCELL +	bool "tmiofb acceleration" +	depends on FB_TMIO +	default y + +config FB_S3C +	tristate "Samsung S3C framebuffer support" +	depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || ARCH_S5P64X0 || \ +		ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Frame buffer driver for the built-in FB controller in the Samsung +	  SoC line from the S3C2443 onwards, including the S3C2416, S3C2450, +	  and the S3C64XX series such as the S3C6400 and S3C6410. + +	  These chips all have the same basic framebuffer design with the +	  actual capabilities depending on the chip. For instance the S3C6400 +	  and S3C6410 support 4 hardware windows whereas the S3C24XX series +	  currently only have two. + +	  Currently the support is only for the S3C6400 and S3C6410 SoCs. + +config FB_S3C_DEBUG_REGWRITE +       bool "Debug register writes" +       depends on FB_S3C +       ---help--- +         Show all register writes via pr_debug() + +config FB_S3C2410 +	tristate "S3C2410 LCD framebuffer support" +	depends on FB && ARCH_S3C24XX +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Frame buffer driver for the built-in LCD controller in the Samsung +	  S3C2410 processor. + +	  This driver is also available as a module ( = code which can be +	  inserted and removed from the running kernel whenever you want). The +	  module will be called s3c2410fb. If you want to compile it as a module, +	  say M here and read <file:Documentation/kbuild/modules.txt>. + +	  If unsure, say N. +config FB_S3C2410_DEBUG +	bool "S3C2410 lcd debug messages" +	depends on FB_S3C2410 +	help +	  Turn on debugging messages. Note that you can set/unset at run time +	  through sysfs + +config FB_NUC900 +        tristate "NUC900 LCD framebuffer support" +        depends on FB && ARCH_W90X900 +        select FB_CFB_FILLRECT +        select FB_CFB_COPYAREA +        select FB_CFB_IMAGEBLIT +        ---help--- +          Frame buffer driver for the built-in LCD controller in the Nuvoton +          NUC900 processor + +config GPM1040A0_320X240 +        bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD" +        depends on FB_NUC900 + +config FB_SM501 +	tristate "Silicon Motion SM501 framebuffer support" +	depends on FB && MFD_SM501 +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Frame buffer driver for the CRT and LCD controllers in the Silicon +	  Motion SM501. + +	  This driver is also available as a module ( = code which can be +	  inserted and removed from the running kernel whenever you want). The +	  module will be called sm501fb. If you want to compile it as a module, +	  say M here and read <file:Documentation/kbuild/modules.txt>. + +	  If unsure, say N. + +config FB_SMSCUFX +	tristate "SMSC UFX6000/7000 USB Framebuffer support" +	depends on FB && USB +	select FB_MODE_HELPERS +	select FB_SYS_FILLRECT +	select FB_SYS_COPYAREA +	select FB_SYS_IMAGEBLIT +	select FB_SYS_FOPS +	select FB_DEFERRED_IO +	---help--- +	  This is a kernel framebuffer driver for SMSC UFX USB devices. +	  Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and +	  mplayer -vo fbdev. Supports both UFX6000 (USB 2.0) and UFX7000 +	  (USB 3.0) devices. +	  To compile as a module, choose M here: the module name is smscufx. + +config FB_UDL +	tristate "Displaylink USB Framebuffer support" +	depends on FB && USB +	select FB_MODE_HELPERS +	select FB_SYS_FILLRECT +	select FB_SYS_COPYAREA +	select FB_SYS_IMAGEBLIT +	select FB_SYS_FOPS +	select FB_DEFERRED_IO +	---help--- +	  This is a kernel framebuffer driver for DisplayLink USB devices. +	  Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and +	  mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices. +	  To compile as a module, choose M here: the module name is udlfb. + +config FB_IBM_GXT4500 +	tristate "Framebuffer support for IBM GXT4000P/4500P/6000P/6500P adaptors" +	depends on FB && PPC +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Say Y here to enable support for the IBM GXT4000P/6000P and +	  GXT4500P/6500P display adaptor based on Raster Engine RC1000, +	  found on some IBM System P (pSeries) machines. This driver +	  doesn't use Geometry Engine GT1000. + +config FB_PS3 +	tristate "PS3 GPU framebuffer driver" +	depends on FB && PS3_PS3AV +	select FB_SYS_FILLRECT +	select FB_SYS_COPYAREA +	select FB_SYS_IMAGEBLIT +	select FB_SYS_FOPS +	select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE +	---help--- +	  Include support for the virtual frame buffer in the PS3 platform. + +config FB_PS3_DEFAULT_SIZE_M +	int "PS3 default frame buffer size (in MiB)" +	depends on FB_PS3 +	default 9 +	---help--- +	  This is the default size (in MiB) of the virtual frame buffer in +	  the PS3. +	  The default value can be overridden on the kernel command line +	  using the "ps3fb" option (e.g. "ps3fb=9M"); + +config FB_XILINX +	tristate "Xilinx frame buffer support" +	depends on FB && (XILINX_VIRTEX || MICROBLAZE || ARCH_ZYNQ) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Include support for the Xilinx ML300/ML403 reference design +	  framebuffer. ML300 carries a 640*480 LCD display on the board, +	  ML403 uses a standard DB15 VGA connector. + +config FB_GOLDFISH +	tristate "Goldfish Framebuffer" +	depends on FB && HAS_DMA && (GOLDFISH || COMPILE_TEST) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Framebuffer driver for Goldfish Virtual Platform + +config FB_COBALT +	tristate "Cobalt server LCD frame buffer support" +	depends on FB && (MIPS_COBALT || MIPS_SEAD3) + +config FB_SH7760 +	bool "SH7760/SH7763/SH7720/SH7721 LCDC support" +	depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \ +		|| CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Support for the SH7760/SH7763/SH7720/SH7721 integrated +	  (D)STN/TFT LCD Controller. +	  Supports display resolutions up to 1024x1024 pixel, grayscale and +	  color operation, with depths ranging from 1 bpp to 8 bpp monochrome +	  and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for +	  panels <= 320 pixel horizontal resolution. + +config FB_DA8XX +	tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support" +	depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_CFB_REV_PIXELS_IN_BYTE +	select FB_MODE_HELPERS +	select VIDEOMODE_HELPERS +	---help--- +	  This is the frame buffer device driver for the TI LCD controller +	  found on DA8xx/OMAP-L1xx/AM335x SoCs. +	  If unsure, say N. + +config FB_VIRTUAL +	tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" +	depends on FB +	select FB_SYS_FILLRECT +	select FB_SYS_COPYAREA +	select FB_SYS_IMAGEBLIT +	select FB_SYS_FOPS +	---help--- +	  This is a `virtual' frame buffer device. It operates on a chunk of +	  unswappable kernel memory instead of on the memory of a graphics +	  board. This means you cannot see any output sent to this frame +	  buffer device, while it does consume precious memory. The main use +	  of this frame buffer device is testing and debugging the frame +	  buffer subsystem. Do NOT enable it for normal systems! To protect +	  the innocent, it has to be enabled explicitly at boot time using the +	  kernel option `video=vfb:'. + +	  To compile this driver as a module, choose M here: the +	  module will be called vfb. In order to load it, you must use +	  the vfb_enable=1 option. + +	  If unsure, say N. + +config XEN_FBDEV_FRONTEND +	tristate "Xen virtual frame buffer support" +	depends on FB && XEN +	select FB_SYS_FILLRECT +	select FB_SYS_COPYAREA +	select FB_SYS_IMAGEBLIT +	select FB_SYS_FOPS +	select FB_DEFERRED_IO +	select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC +	select XEN_XENBUS_FRONTEND +	default y +	help +	  This driver implements the front-end of the Xen virtual +	  frame buffer driver.  It communicates with a back-end +	  in another domain. + +config FB_METRONOME +	tristate "E-Ink Metronome/8track controller support" +	depends on FB +	select FB_SYS_FILLRECT +	select FB_SYS_COPYAREA +	select FB_SYS_IMAGEBLIT +	select FB_SYS_FOPS +	select FB_DEFERRED_IO +	help +	  This driver implements support for the E-Ink Metronome +	  controller. The pre-release name for this device was 8track +	  and could also have been called by some vendors as PVI-nnnn. + +config FB_MB862XX +	tristate "Fujitsu MB862xx GDC support" +	depends on FB +	depends on PCI || (OF && PPC) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers. + +choice +	prompt "GDC variant" +	depends on FB_MB862XX + +config FB_MB862XX_PCI_GDC +	bool "Carmine/Coral-P(A) GDC" +	depends on PCI +	---help--- +	  This enables framebuffer support for Fujitsu Carmine/Coral-P(A) +	  PCI graphics controller devices. + +config FB_MB862XX_LIME +	bool "Lime GDC" +	depends on OF && PPC +	select FB_FOREIGN_ENDIAN +	select FB_LITTLE_ENDIAN +	---help--- +	  Framebuffer support for Fujitsu Lime GDC on host CPU bus. + +endchoice + +config FB_MB862XX_I2C +	bool "Support I2C bus on MB862XX GDC" +	depends on FB_MB862XX && I2C +	depends on FB_MB862XX=m || I2C=y +	default y +	help +	  Selecting this option adds Coral-P(A)/Lime GDC I2C bus adapter +	  driver to support accessing I2C devices on controller's I2C bus. +	  These are usually some video decoder chips. + +config FB_EP93XX +	tristate "EP93XX frame buffer support" +	depends on FB && ARCH_EP93XX +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	---help--- +	  Framebuffer driver for the Cirrus Logic EP93XX series of processors. +	  This driver is also available as a module. The module will be called +	  ep93xx-fb. + +config FB_PRE_INIT_FB +	bool "Don't reinitialize, use bootloader's GDC/Display configuration" +	depends on FB && FB_MB862XX_LIME +	---help--- +	  Select this option if display contents should be inherited as set by +	  the bootloader. + +config FB_MSM +	tristate "MSM Framebuffer support" +	depends on FB && ARCH_MSM +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT + +config FB_MX3 +	tristate "MX3 Framebuffer support" +	depends on FB && MX3_IPU +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select BACKLIGHT_CLASS_DEVICE +	default y +	help +	  This is a framebuffer device for the i.MX31 LCD Controller. So +	  far only synchronous displays are supported. If you plan to use +	  an LCD display with your i.MX31 system, say Y here. + +config FB_BROADSHEET +	tristate "E-Ink Broadsheet/Epson S1D13521 controller support" +	depends on FB +	select FB_SYS_FILLRECT +	select FB_SYS_COPYAREA +	select FB_SYS_IMAGEBLIT +	select FB_SYS_FOPS +	select FB_DEFERRED_IO +	help +	  This driver implements support for the E-Ink Broadsheet +	  controller. The release name for this device was Epson S1D13521 +	  and could also have been called by other names when coupled with +	  a bridge adapter. + +config FB_AUO_K190X +	tristate "AUO-K190X EPD controller support" +	depends on FB +	select FB_SYS_FILLRECT +	select FB_SYS_COPYAREA +	select FB_SYS_IMAGEBLIT +	select FB_SYS_FOPS +	select FB_DEFERRED_IO +	help +	  Provides support for epaper controllers from the K190X series +	  of AUO. These controllers can be used to drive epaper displays +	  from Sipix. + +	  This option enables the common support, shared by the individual +	  controller drivers. You will also have to enable the driver +	  for the controller type used in your device. + +config FB_AUO_K1900 +	tristate "AUO-K1900 EPD controller support" +	depends on FB && FB_AUO_K190X +	help +	  This driver implements support for the AUO K1900 epd-controller. +	  This controller can drive Sipix epaper displays but can only do +	  serial updates, reducing the number of possible frames per second. + +config FB_AUO_K1901 +	tristate "AUO-K1901 EPD controller support" +	depends on FB && FB_AUO_K190X +	help +	  This driver implements support for the AUO K1901 epd-controller. +	  This controller can drive Sipix epaper displays and supports +	  concurrent updates, making higher frames per second possible. + +config FB_JZ4740 +	tristate "JZ4740 LCD framebuffer support" +	depends on FB && MACH_JZ4740 +	select FB_SYS_FILLRECT +	select FB_SYS_COPYAREA +	select FB_SYS_IMAGEBLIT +	help +	  Framebuffer support for the JZ4740 SoC. + +config FB_MXS +	tristate "MXS LCD framebuffer support" +	depends on FB && ARCH_MXS +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	select FB_MODE_HELPERS +	select VIDEOMODE_HELPERS +	help +	  Framebuffer support for the MXS SoC. + +config FB_PUV3_UNIGFX +	tristate "PKUnity v3 Unigfx framebuffer support" +	depends on FB && UNICORE32 && ARCH_PUV3 +	select FB_SYS_FILLRECT +	select FB_SYS_COPYAREA +	select FB_SYS_IMAGEBLIT +	select FB_SYS_FOPS +	help +	  Choose this option if you want to use the Unigfx device as a +	  framebuffer device. Without the support of PCI & AGP. + +config FB_HYPERV +	tristate "Microsoft Hyper-V Synthetic Video support" +	depends on FB && HYPERV +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  This framebuffer driver supports Microsoft Hyper-V Synthetic Video. + +config FB_SIMPLE +	bool "Simple framebuffer support" +	depends on (FB = y) +	select FB_CFB_FILLRECT +	select FB_CFB_COPYAREA +	select FB_CFB_IMAGEBLIT +	help +	  Say Y if you want support for a simple frame-buffer. + +	  This driver assumes that the display hardware has been initialized +	  before the kernel boots, and the kernel will simply render to the +	  pre-allocated frame buffer surface. + +	  Configuration re: surface address, size, and format must be provided +	  through device tree, or plain old platform data. + +source "drivers/video/fbdev/omap/Kconfig" +source "drivers/video/fbdev/omap2/Kconfig" +source "drivers/video/fbdev/exynos/Kconfig" +source "drivers/video/fbdev/mmp/Kconfig" + +config FB_SH_MOBILE_MERAM +	tristate "SuperH Mobile MERAM read ahead support" +	depends on (SUPERH || ARCH_SHMOBILE) +	select GENERIC_ALLOCATOR +	---help--- +	  Enable MERAM support for the SuperH controller. + +	  This will allow for caching of the framebuffer to provide more +	  reliable access under heavy main memory bus traffic situations. +	  Up to 4 memory channels can be configured, allowing 4 RGB or +	  2 YCbCr framebuffers to be configured. + +config FB_SSD1307 +	tristate "Solomon SSD1307 framebuffer support" +	depends on FB && I2C +	depends on OF +	depends on GPIOLIB +	select FB_SYS_FOPS +	select FB_SYS_FILLRECT +	select FB_SYS_COPYAREA +	select FB_SYS_IMAGEBLIT +	select FB_DEFERRED_IO +	select PWM +	help +	  This driver implements support for the Solomon SSD1307 +	  OLED controller over I2C. diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile new file mode 100644 index 00000000000..0284f2a1253 --- /dev/null +++ b/drivers/video/fbdev/Makefile @@ -0,0 +1,152 @@ +# Makefile for the Linux video drivers. +# 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net> +# Rewritten to use lists instead of if-statements. + +# Each configuration option enables a list of files. + +obj-y				+= core/ + +obj-$(CONFIG_EXYNOS_VIDEO)     += exynos/ + +obj-$(CONFIG_FB_MACMODES)      += macmodes.o +obj-$(CONFIG_FB_WMT_GE_ROPS)   += wmt_ge_rops.o + +# Hardware specific drivers go first +obj-$(CONFIG_FB_AMIGA)            += amifb.o c2p_planar.o +obj-$(CONFIG_FB_ARC)              += arcfb.o +obj-$(CONFIG_FB_CLPS711X)         += clps711xfb.o +obj-$(CONFIG_FB_CYBER2000)        += cyber2000fb.o +obj-$(CONFIG_FB_GRVGA)            += grvga.o +obj-$(CONFIG_FB_PM2)              += pm2fb.o +obj-$(CONFIG_FB_PM3)		  += pm3fb.o + +obj-$(CONFIG_FB_I740)		  += i740fb.o +obj-$(CONFIG_FB_MATROX)		  += matrox/ +obj-$(CONFIG_FB_RIVA)		  += riva/ +obj-$(CONFIG_FB_NVIDIA)		  += nvidia/ +obj-$(CONFIG_FB_ATY)		  += aty/ macmodes.o +obj-$(CONFIG_FB_ATY128)		  += aty/ macmodes.o +obj-$(CONFIG_FB_RADEON)		  += aty/ +obj-$(CONFIG_FB_SIS)		  += sis/ +obj-$(CONFIG_FB_VIA)		  += via/ +obj-$(CONFIG_FB_KYRO)             += kyro/ +obj-$(CONFIG_FB_SAVAGE)		  += savage/ +obj-$(CONFIG_FB_GEODE)		  += geode/ +obj-$(CONFIG_FB_MBX)		  += mbx/ +obj-$(CONFIG_FB_NEOMAGIC)         += neofb.o +obj-$(CONFIG_FB_3DFX)             += tdfxfb.o +obj-$(CONFIG_FB_CONTROL)          += controlfb.o +obj-$(CONFIG_FB_PLATINUM)         += platinumfb.o +obj-$(CONFIG_FB_VALKYRIE)         += valkyriefb.o +obj-$(CONFIG_FB_CT65550)          += chipsfb.o +obj-$(CONFIG_FB_IMSTT)            += imsttfb.o +obj-$(CONFIG_FB_FM2)              += fm2fb.o +obj-$(CONFIG_FB_VT8623)           += vt8623fb.o +obj-$(CONFIG_FB_TRIDENT)          += tridentfb.o +obj-$(CONFIG_FB_LE80578)          += vermilion/ +obj-$(CONFIG_FB_S3)               += s3fb.o +obj-$(CONFIG_FB_ARK)              += arkfb.o +obj-$(CONFIG_FB_STI)              += stifb.o +obj-$(CONFIG_FB_FFB)              += ffb.o sbuslib.o +obj-$(CONFIG_FB_CG6)              += cg6.o sbuslib.o +obj-$(CONFIG_FB_CG3)              += cg3.o sbuslib.o +obj-$(CONFIG_FB_BW2)              += bw2.o sbuslib.o +obj-$(CONFIG_FB_CG14)             += cg14.o sbuslib.o +obj-$(CONFIG_FB_P9100)            += p9100.o sbuslib.o +obj-$(CONFIG_FB_TCX)              += tcx.o sbuslib.o +obj-$(CONFIG_FB_LEO)              += leo.o sbuslib.o +obj-$(CONFIG_FB_ACORN)            += acornfb.o +obj-$(CONFIG_FB_ATARI)            += atafb.o c2p_iplan2.o atafb_mfb.o \ +                                     atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o +obj-$(CONFIG_FB_MAC)              += macfb.o +obj-$(CONFIG_FB_HECUBA)           += hecubafb.o +obj-$(CONFIG_FB_N411)             += n411.o +obj-$(CONFIG_FB_HGA)              += hgafb.o +obj-$(CONFIG_FB_XVR500)           += sunxvr500.o +obj-$(CONFIG_FB_XVR2500)          += sunxvr2500.o +obj-$(CONFIG_FB_XVR1000)          += sunxvr1000.o +obj-$(CONFIG_FB_IGA)              += igafb.o +obj-$(CONFIG_FB_APOLLO)           += dnfb.o +obj-$(CONFIG_FB_Q40)              += q40fb.o +obj-$(CONFIG_FB_TGA)              += tgafb.o +obj-$(CONFIG_FB_HP300)            += hpfb.o +obj-$(CONFIG_FB_G364)             += g364fb.o +obj-$(CONFIG_FB_EP93XX)		  += ep93xx-fb.o +obj-$(CONFIG_FB_SA1100)           += sa1100fb.o +obj-$(CONFIG_FB_HIT)              += hitfb.o +obj-$(CONFIG_FB_ATMEL)		  += atmel_lcdfb.o +obj-$(CONFIG_FB_PVR2)             += pvr2fb.o +obj-$(CONFIG_FB_VOODOO1)          += sstfb.o +obj-$(CONFIG_FB_ARMCLCD)	  += amba-clcd.o +obj-$(CONFIG_FB_GOLDFISH)         += goldfishfb.o +obj-$(CONFIG_FB_68328)            += 68328fb.o +obj-$(CONFIG_FB_GBE)              += gbefb.o +obj-$(CONFIG_FB_CIRRUS)		  += cirrusfb.o +obj-$(CONFIG_FB_ASILIANT)	  += asiliantfb.o +obj-$(CONFIG_FB_PXA)		  += pxafb.o +obj-$(CONFIG_FB_PXA168)		  += pxa168fb.o +obj-$(CONFIG_PXA3XX_GCU)	  += pxa3xx-gcu.o +obj-$(CONFIG_MMP_DISP)           += mmp/ +obj-$(CONFIG_FB_W100)		  += w100fb.o +obj-$(CONFIG_FB_TMIO)		  += tmiofb.o +obj-$(CONFIG_FB_AU1100)		  += au1100fb.o +obj-$(CONFIG_FB_AU1200)		  += au1200fb.o +obj-$(CONFIG_FB_VT8500)		  += vt8500lcdfb.o +obj-$(CONFIG_FB_WM8505)		  += wm8505fb.o +obj-$(CONFIG_FB_PMAG_AA)	  += pmag-aa-fb.o +obj-$(CONFIG_FB_PMAG_BA)	  += pmag-ba-fb.o +obj-$(CONFIG_FB_PMAGB_B)	  += pmagb-b-fb.o +obj-$(CONFIG_FB_MAXINE)		  += maxinefb.o +obj-$(CONFIG_FB_METRONOME)        += metronomefb.o +obj-$(CONFIG_FB_BROADSHEET)       += broadsheetfb.o +obj-$(CONFIG_FB_AUO_K190X)	  += auo_k190x.o +obj-$(CONFIG_FB_AUO_K1900)	  += auo_k1900fb.o +obj-$(CONFIG_FB_AUO_K1901)	  += auo_k1901fb.o +obj-$(CONFIG_FB_S1D13XXX)	  += s1d13xxxfb.o +obj-$(CONFIG_FB_SH7760)		  += sh7760fb.o +obj-$(CONFIG_FB_IMX)              += imxfb.o +obj-$(CONFIG_FB_S3C)		  += s3c-fb.o +obj-$(CONFIG_FB_S3C2410)	  += s3c2410fb.o +obj-$(CONFIG_FB_FSL_DIU)	  += fsl-diu-fb.o +obj-$(CONFIG_FB_COBALT)           += cobalt_lcdfb.o +obj-$(CONFIG_FB_IBM_GXT4500)	  += gxt4500.o +obj-$(CONFIG_FB_PS3)		  += ps3fb.o +obj-$(CONFIG_FB_SM501)            += sm501fb.o +obj-$(CONFIG_FB_UDL)		  += udlfb.o +obj-$(CONFIG_FB_SMSCUFX)	  += smscufx.o +obj-$(CONFIG_FB_XILINX)           += xilinxfb.o +obj-$(CONFIG_SH_MIPI_DSI)	  += sh_mipi_dsi.o +obj-$(CONFIG_FB_SH_MOBILE_HDMI)	  += sh_mobile_hdmi.o +obj-$(CONFIG_FB_SH_MOBILE_MERAM)  += sh_mobile_meram.o +obj-$(CONFIG_FB_SH_MOBILE_LCDC)	  += sh_mobile_lcdcfb.o +obj-$(CONFIG_FB_OMAP)             += omap/ +obj-y                             += omap2/ +obj-$(CONFIG_XEN_FBDEV_FRONTEND)  += xen-fbfront.o +obj-$(CONFIG_FB_CARMINE)          += carminefb.o +obj-$(CONFIG_FB_MB862XX)	  += mb862xx/ +obj-$(CONFIG_FB_MSM)              += msm/ +obj-$(CONFIG_FB_NUC900)           += nuc900fb.o +obj-$(CONFIG_FB_JZ4740)		  += jz4740_fb.o +obj-$(CONFIG_FB_PUV3_UNIGFX)      += fb-puv3.o +obj-$(CONFIG_FB_HYPERV)		  += hyperv_fb.o +obj-$(CONFIG_FB_OPENCORES)	  += ocfb.o + +# Platform or fallback drivers go here +obj-$(CONFIG_FB_UVESA)            += uvesafb.o +obj-$(CONFIG_FB_VESA)             += vesafb.o +obj-$(CONFIG_FB_EFI)              += efifb.o +obj-$(CONFIG_FB_VGA16)            += vga16fb.o +obj-$(CONFIG_FB_OF)               += offb.o +obj-$(CONFIG_FB_BF537_LQ035)      += bf537-lq035.o +obj-$(CONFIG_FB_BF54X_LQ043)	  += bf54x-lq043fb.o +obj-$(CONFIG_FB_BFIN_LQ035Q1)     += bfin-lq035q1-fb.o +obj-$(CONFIG_FB_BFIN_T350MCQB)	  += bfin-t350mcqb-fb.o +obj-$(CONFIG_FB_BFIN_7393)        += bfin_adv7393fb.o +obj-$(CONFIG_FB_MX3)		  += mx3fb.o +obj-$(CONFIG_FB_DA8XX)		  += da8xx-fb.o +obj-$(CONFIG_FB_MXS)		  += mxsfb.o +obj-$(CONFIG_FB_SSD1307)	  += ssd1307fb.o +obj-$(CONFIG_FB_SIMPLE)           += simplefb.o + +# the test framebuffer is last +obj-$(CONFIG_FB_VIRTUAL)          += vfb.o diff --git a/drivers/video/acornfb.c b/drivers/video/fbdev/acornfb.c index 7e8346ec9cd..a305caea58e 100644 --- a/drivers/video/acornfb.c +++ b/drivers/video/fbdev/acornfb.c @@ -949,9 +949,7 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end)  		 * the page.  		 */  		page = virt_to_page(virtual_start); -		ClearPageReserved(page); -		init_page_count(page); -		free_page(virtual_start); +		__free_reserved_page(page);  		virtual_start += PAGE_SIZE;  		mb_freed += PAGE_SIZE / 1024; diff --git a/drivers/video/acornfb.h b/drivers/video/fbdev/acornfb.h index 175c8ff3367..175c8ff3367 100644 --- a/drivers/video/acornfb.h +++ b/drivers/video/fbdev/acornfb.h diff --git a/drivers/video/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c index 0a2cce7285b..14d6b3793e0 100644 --- a/drivers/video/amba-clcd.c +++ b/drivers/video/fbdev/amba-clcd.c @@ -10,6 +10,7 @@   *   *  ARM PrimeCell PL110 Color LCD Controller   */ +#include <linux/dma-mapping.h>  #include <linux/module.h>  #include <linux/kernel.h>  #include <linux/errno.h> @@ -544,13 +545,17 @@ static int clcdfb_register(struct clcd_fb *fb)  static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)  { -	struct clcd_board *board = dev->dev.platform_data; +	struct clcd_board *board = dev_get_platdata(&dev->dev);  	struct clcd_fb *fb;  	int ret;  	if (!board)  		return -EINVAL; +	ret = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32)); +	if (ret) +		goto out; +  	ret = amba_request_regions(dev, NULL);  	if (ret) {  		printk(KERN_ERR "CLCD: unable to reserve regs region\n"); @@ -594,8 +599,6 @@ static int clcdfb_remove(struct amba_device *dev)  {  	struct clcd_fb *fb = amba_get_drvdata(dev); -	amba_set_drvdata(dev, NULL); -  	clcdfb_disable(fb);  	unregister_framebuffer(&fb->fb);  	if (fb->fb.cmap.len) diff --git a/drivers/video/amifb.c b/drivers/video/fbdev/amifb.c index a6780eecff0..518f790ef88 100644 --- a/drivers/video/amifb.c +++ b/drivers/video/fbdev/amifb.c @@ -3710,7 +3710,7 @@ default_chipset:  	if (!videomemory) {  		dev_warn(&pdev->dev,  			 "Unable to map videomem cached writethrough\n"); -		info->screen_base = (char *)ZTWO_VADDR(info->fix.smem_start); +		info->screen_base = ZTWO_VADDR(info->fix.smem_start);  	} else  		info->screen_base = (char *)videomemory; @@ -3742,13 +3742,12 @@ default_chipset:  	if (err)  		goto unset_drvdata; -	printk("fb%d: %s frame buffer device, using %dK of video memory\n", -	       info->node, info->fix.id, info->fix.smem_len>>10); +	fb_info(info, "%s frame buffer device, using %dK of video memory\n", +		info->fix.id, info->fix.smem_len>>10);  	return 0;  unset_drvdata: -	dev_set_drvdata(&pdev->dev, NULL);  	fb_dealloc_cmap(&info->cmap);  free_irq:  	free_irq(IRQ_AMIGA_COPPER, info->par); @@ -3768,7 +3767,6 @@ static int __exit amifb_remove(struct platform_device *pdev)  	struct fb_info *info = dev_get_drvdata(&pdev->dev);  	unregister_framebuffer(info); -	dev_set_drvdata(&pdev->dev, NULL);  	fb_dealloc_cmap(&info->cmap);  	free_irq(IRQ_AMIGA_COPPER, info->par);  	custom.dmacon = DMAF_ALL | DMAF_MASTER; diff --git a/drivers/video/arcfb.c b/drivers/video/fbdev/arcfb.c index e43401afdd0..1b0b233b8b3 100644 --- a/drivers/video/arcfb.c +++ b/drivers/video/fbdev/arcfb.c @@ -556,9 +556,8 @@ static int arcfb_probe(struct platform_device *dev)  			goto err1;  		}  	} -	printk(KERN_INFO -	       "fb%d: Arc frame buffer device, using %dK of video memory\n", -	       info->node, videomemorysize >> 10); +	fb_info(info, "Arc frame buffer device, using %dK of video memory\n", +		videomemorysize >> 10);  	/* this inits the lcd but doesn't clear dirty pixels */  	for (i = 0; i < num_cols * num_rows; i++) { @@ -572,8 +571,7 @@ static int arcfb_probe(struct platform_device *dev)  	/* if we were told to splash the screen, we just clear it */  	if (!nosplash) {  		for (i = 0; i < num_cols * num_rows; i++) { -			printk(KERN_INFO "fb%d: splashing lcd %d\n", -				info->node, i); +			fb_info(info, "splashing lcd %d\n", i);  			ks108_set_start_line(par, i, 0);  			ks108_clear_lcd(par, i);  		} diff --git a/drivers/video/arkfb.c b/drivers/video/fbdev/arkfb.c index 94a51f1ef90..adc4ea2cc5a 100644 --- a/drivers/video/arkfb.c +++ b/drivers/video/fbdev/arkfb.c @@ -137,8 +137,7 @@ static void arkfb_settile(struct fb_info *info, struct fb_tilemap *map)  	if ((map->width != 8) || (map->height != 16) ||  	    (map->depth != 1) || (map->length != 256)) { -	    	printk(KERN_ERR "fb%d: unsupported font parameters: width %d, " -		       "height %d, depth %d, length %d\n", info->node, +		fb_err(info, "unsupported font parameters: width %d, height %d, depth %d, length %d\n",  		       map->width, map->height, map->depth, map->length);  		return;  	} @@ -517,7 +516,7 @@ static void ark_set_pixclock(struct fb_info *info, u32 pixclock)  	int rv = dac_set_freq(par->dac, 0, 1000000000 / pixclock);  	if (rv < 0) { -		printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node); +		fb_err(info, "cannot set requested pixclock, keeping old value\n");  		return;  	} @@ -584,7 +583,7 @@ static int arkfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)  	rv = svga_match_format (arkfb_formats, var, NULL);  	if (rv < 0)  	{ -		printk(KERN_ERR "fb%d: unsupported mode requested\n", info->node); +		fb_err(info, "unsupported mode requested\n");  		return rv;  	} @@ -604,14 +603,15 @@ static int arkfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)  	mem = ((var->bits_per_pixel * var->xres_virtual) >> 3) * var->yres_virtual;  	if (mem > info->screen_size)  	{ -		printk(KERN_ERR "fb%d: not enough framebuffer memory (%d kB requested , %d kB available)\n", info->node, mem >> 10, (unsigned int) (info->screen_size >> 10)); +		fb_err(info, "not enough framebuffer memory (%d kB requested, %d kB available)\n", +		       mem >> 10, (unsigned int) (info->screen_size >> 10));  		return -EINVAL;  	}  	rv = svga_check_timings (&ark_timing_regs, var, info->node);  	if (rv < 0)  	{ -		printk(KERN_ERR "fb%d: invalid timings requested\n", info->node); +		fb_err(info, "invalid timings requested\n");  		return rv;  	} @@ -693,7 +693,7 @@ static int arkfb_set_par(struct fb_info *info)  	vga_wseq(par->state.vgabase, 0x18, regval);  	/* Set the offset register */ -	pr_debug("fb%d: offset register       : %d\n", info->node, offset_value); +	fb_dbg(info, "offset register       : %d\n", offset_value);  	svga_wcrt_multi(par->state.vgabase, ark_offset_regs, offset_value);  	/* fix for hi-res textmode */ @@ -716,7 +716,7 @@ static int arkfb_set_par(struct fb_info *info)  	/* Set mode-specific register values */  	switch (mode) {  	case 0: -		pr_debug("fb%d: text mode\n", info->node); +		fb_dbg(info, "text mode\n");  		svga_set_textmode_vga_regs(par->state.vgabase);  		vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */ @@ -725,7 +725,7 @@ static int arkfb_set_par(struct fb_info *info)  		break;  	case 1: -		pr_debug("fb%d: 4 bit pseudocolor\n", info->node); +		fb_dbg(info, "4 bit pseudocolor\n");  		vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);  		vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */ @@ -733,44 +733,44 @@ static int arkfb_set_par(struct fb_info *info)  		dac_set_mode(par->dac, DAC_PSEUDO8_8);  		break;  	case 2: -		pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); +		fb_dbg(info, "4 bit pseudocolor, planar\n");  		vga_wseq(par->state.vgabase, 0x11, 0x10); /* basic VGA mode */  		svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */  		dac_set_mode(par->dac, DAC_PSEUDO8_8);  		break;  	case 3: -		pr_debug("fb%d: 8 bit pseudocolor\n", info->node); +		fb_dbg(info, "8 bit pseudocolor\n");  		vga_wseq(par->state.vgabase, 0x11, 0x16); /* 8bpp accel mode */  		if (info->var.pixclock > 20000) { -			pr_debug("fb%d: not using multiplex\n", info->node); +			fb_dbg(info, "not using multiplex\n");  			svga_wcrt_mask(par->state.vgabase, 0x46, 0x00, 0x04); /* 8bit pixel path */  			dac_set_mode(par->dac, DAC_PSEUDO8_8);  		} else { -			pr_debug("fb%d: using multiplex\n", info->node); +			fb_dbg(info, "using multiplex\n");  			svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */  			dac_set_mode(par->dac, DAC_PSEUDO8_16);  			hdiv = 2;  		}  		break;  	case 4: -		pr_debug("fb%d: 5/5/5 truecolor\n", info->node); +		fb_dbg(info, "5/5/5 truecolor\n");  		vga_wseq(par->state.vgabase, 0x11, 0x1A); /* 16bpp accel mode */  		svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */  		dac_set_mode(par->dac, DAC_RGB1555_16);  		break;  	case 5: -		pr_debug("fb%d: 5/6/5 truecolor\n", info->node); +		fb_dbg(info, "5/6/5 truecolor\n");  		vga_wseq(par->state.vgabase, 0x11, 0x1A); /* 16bpp accel mode */  		svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */  		dac_set_mode(par->dac, DAC_RGB0565_16);  		break;  	case 6: -		pr_debug("fb%d: 8/8/8 truecolor\n", info->node); +		fb_dbg(info, "8/8/8 truecolor\n");  		vga_wseq(par->state.vgabase, 0x11, 0x16); /* 8bpp accel mode ??? */  		svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */ @@ -779,7 +779,7 @@ static int arkfb_set_par(struct fb_info *info)  		hdiv = 2;  		break;  	case 7: -		pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node); +		fb_dbg(info, "8/8/8/8 truecolor\n");  		vga_wseq(par->state.vgabase, 0x11, 0x1E); /* 32bpp accel mode */  		svga_wcrt_mask(par->state.vgabase, 0x46, 0x04, 0x04); /* 16bit pixel path */ @@ -787,7 +787,7 @@ static int arkfb_set_par(struct fb_info *info)  		hmul = 2;  		break;  	default: -		printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node); +		fb_err(info, "unsupported mode - bug\n");  		return -EINVAL;  	} @@ -879,19 +879,19 @@ static int arkfb_blank(int blank_mode, struct fb_info *info)  	switch (blank_mode) {  	case FB_BLANK_UNBLANK: -		pr_debug("fb%d: unblank\n", info->node); +		fb_dbg(info, "unblank\n");  		svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);  		svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);  		break;  	case FB_BLANK_NORMAL: -		pr_debug("fb%d: blank\n", info->node); +		fb_dbg(info, "blank\n");  		svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);  		svga_wcrt_mask(par->state.vgabase, 0x17, 0x80, 0x80);  		break;  	case FB_BLANK_POWERDOWN:  	case FB_BLANK_HSYNC_SUSPEND:  	case FB_BLANK_VSYNC_SUSPEND: -		pr_debug("fb%d: sync down\n", info->node); +		fb_dbg(info, "sync down\n");  		svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);  		svga_wcrt_mask(par->state.vgabase, 0x17, 0x00, 0x80);  		break; @@ -1014,7 +1014,7 @@ static int ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  	vga_res.flags = IORESOURCE_IO; -	pcibios_bus_to_resource(dev, &vga_res, &bus_reg); +	pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg);  	par->state.vgabase = (void __iomem *) vga_res.start; @@ -1048,12 +1048,12 @@ static int ark_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  	rc = register_framebuffer(info);  	if (rc < 0) { -		dev_err(info->device, "cannot register framebugger\n"); +		dev_err(info->device, "cannot register framebuffer\n");  		goto err_reg_fb;  	} -	printk(KERN_INFO "fb%d: %s on %s, %d MB RAM\n", info->node, info->fix.id, -		 pci_name(dev), info->fix.smem_len >> 20); +	fb_info(info, "%s on %s, %d MB RAM\n", +		info->fix.id, pci_name(dev), info->fix.smem_len >> 20);  	/* Record a reference to the driver data */  	pci_set_drvdata(dev, info); @@ -1108,7 +1108,6 @@ static void ark_pci_remove(struct pci_dev *dev)  		pci_release_regions(dev);  /*		pci_disable_device(dev); */ -		pci_set_drvdata(dev, NULL);  		framebuffer_release(info);  	}  } diff --git a/drivers/video/asiliantfb.c b/drivers/video/fbdev/asiliantfb.c index d5a37d62847..7e8ddf00ccc 100644 --- a/drivers/video/asiliantfb.c +++ b/drivers/video/fbdev/asiliantfb.c @@ -527,8 +527,8 @@ static int init_asiliant(struct fb_info *p, unsigned long addr)  		return err;  	} -	printk(KERN_INFO "fb%d: Asiliant 69000 frame buffer (%dK RAM detected)\n", -		p->node, p->fix.smem_len / 1024); +	fb_info(p, "Asiliant 69000 frame buffer (%dK RAM detected)\n", +		p->fix.smem_len / 1024);  	writeb(0xff, mmio_base + 0x78c);  	chips_hw_init(p); @@ -589,7 +589,6 @@ static void asiliantfb_remove(struct pci_dev *dp)  	fb_dealloc_cmap(&p->cmap);  	iounmap(p->screen_base);  	release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0)); -	pci_set_drvdata(dp, NULL);  	framebuffer_release(p);  } diff --git a/drivers/video/atafb.c b/drivers/video/fbdev/atafb.c index 64e41f5448c..4953b657635 100644 --- a/drivers/video/atafb.c +++ b/drivers/video/fbdev/atafb.c @@ -191,7 +191,7 @@ static struct fb_info fb_info = {  };  static void *screen_base;	/* base address of screen */ -static void *real_screen_base;	/* (only for Overscan) */ +static unsigned long phys_screen_base;	/* (only for Overscan) */  static int screen_len; @@ -213,7 +213,8 @@ static unsigned int external_yres;   */  static unsigned int external_depth;  static int external_pmode; -static void *external_addr; +static void *external_screen_base; +static unsigned long external_addr;  static unsigned long external_len;  static unsigned long external_vgaiobase;  static unsigned int external_bitspercol = 6; @@ -592,7 +593,7 @@ static int tt_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par)  	int mode;  	strcpy(fix->id, "Atari Builtin"); -	fix->smem_start = (unsigned long)real_screen_base; +	fix->smem_start = phys_screen_base;  	fix->smem_len = screen_len;  	fix->type = FB_TYPE_INTERLEAVED_PLANES;  	fix->type_aux = 2; @@ -790,7 +791,7 @@ static void tt_get_par(struct atafb_par *par)  	addr = ((shifter.bas_hi & 0xff) << 16) |  	       ((shifter.bas_md & 0xff) << 8)  |  	       ((shifter.bas_lo & 0xff)); -	par->screen_base = phys_to_virt(addr); +	par->screen_base = atari_stram_to_virt(addr);  }  static void tt_set_par(struct atafb_par *par) @@ -888,7 +889,7 @@ static int falcon_encode_fix(struct fb_fix_screeninfo *fix,  			     struct atafb_par *par)  {  	strcpy(fix->id, "Atari Builtin"); -	fix->smem_start = (unsigned long)real_screen_base; +	fix->smem_start = phys_screen_base;  	fix->smem_len = screen_len;  	fix->type = FB_TYPE_INTERLEAVED_PLANES;  	fix->type_aux = 2; @@ -1584,7 +1585,7 @@ static void falcon_get_par(struct atafb_par *par)  	addr = (shifter.bas_hi & 0xff) << 16 |  	       (shifter.bas_md & 0xff) << 8  |  	       (shifter.bas_lo & 0xff); -	par->screen_base = phys_to_virt(addr); +	par->screen_base = atari_stram_to_virt(addr);  	/* derived parameters */  	hw->ste_mode = (hw->f_shift & 0x510) == 0 && hw->st_shift == 0x100; @@ -1814,7 +1815,7 @@ static int stste_encode_fix(struct fb_fix_screeninfo *fix,  	int mode;  	strcpy(fix->id, "Atari Builtin"); -	fix->smem_start = (unsigned long)real_screen_base; +	fix->smem_start = phys_screen_base;  	fix->smem_len = screen_len;  	fix->type = FB_TYPE_INTERLEAVED_PLANES;  	fix->type_aux = 2; @@ -1980,7 +1981,7 @@ static void stste_get_par(struct atafb_par *par)  	       ((shifter.bas_md & 0xff) << 8);  	if (ATARIHW_PRESENT(EXTD_SHIFTER))  		addr |= (shifter.bas_lo & 0xff); -	par->screen_base = phys_to_virt(addr); +	par->screen_base = atari_stram_to_virt(addr);  }  static void stste_set_par(struct atafb_par *par) @@ -2039,7 +2040,7 @@ static int stste_detect(void)  static void stste_set_screen_base(void *s_base)  {  	unsigned long addr; -	addr = virt_to_phys(s_base); +	addr = atari_stram_to_phys(s_base);  	/* Setup Screen Memory */  	shifter.bas_hi = (unsigned char)((addr & 0xff0000) >> 16);  	shifter.bas_md = (unsigned char)((addr & 0x00ff00) >> 8); @@ -2113,7 +2114,7 @@ static void st_ovsc_switch(void)  static int ext_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par)  {  	strcpy(fix->id, "Unknown Extern"); -	fix->smem_start = (unsigned long)external_addr; +	fix->smem_start = external_addr;  	fix->smem_len = PAGE_ALIGN(external_len);  	if (external_depth == 1) {  		fix->type = FB_TYPE_PACKED_PIXELS; @@ -2213,7 +2214,7 @@ static int ext_encode_var(struct fb_var_screeninfo *var, struct atafb_par *par)  static void ext_get_par(struct atafb_par *par)  { -	par->screen_base = external_addr; +	par->screen_base = external_screen_base;  }  static void ext_set_par(struct atafb_par *par) @@ -2286,7 +2287,7 @@ static void set_screen_base(void *s_base)  {  	unsigned long addr; -	addr = virt_to_phys(s_base); +	addr = atari_stram_to_phys(s_base);  	/* Setup Screen Memory */  	shifter.bas_hi = (unsigned char)((addr & 0xff0000) >> 16);  	shifter.bas_md = (unsigned char)((addr & 0x00ff00) >> 8); @@ -2433,7 +2434,9 @@ static void atafb_set_disp(struct fb_info *info)  	atafb_get_var(&info->var, info);  	atafb_get_fix(&info->fix, info); -	info->screen_base = (void *)info->fix.smem_start; +	/* Note: smem_start derives from phys_screen_base, not screen_base! */ +	info->screen_base = (external_addr ? external_screen_base : +				atari_stram_to_virt(info->fix.smem_start));  }  static int atafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, @@ -2904,7 +2907,7 @@ static void __init atafb_setup_ext(char *spec)  	external_yres = yres;  	external_depth = depth;  	external_pmode = planes; -	external_addr = (void *)addr; +	external_addr = addr;  	external_len = len;  	if (external_card_type == IS_MV300) { @@ -3166,30 +3169,30 @@ int __init atafb_init(void)  		memset(screen_base, 0, mem_req);  		pad = -(unsigned long)screen_base & (PAGE_SIZE - 1);  		screen_base += pad; -		real_screen_base = screen_base + ovsc_offset; +		phys_screen_base = atari_stram_to_phys(screen_base + ovsc_offset);  		screen_len = (mem_req - pad - ovsc_offset) & PAGE_MASK;  		st_ovsc_switch();  		if (CPU_IS_040_OR_060) {  			/* On a '040+, the cache mode of video RAM must be set to  			 * write-through also for internal video hardware! */ -			cache_push(virt_to_phys(screen_base), screen_len); +			cache_push(atari_stram_to_phys(screen_base), screen_len);  			kernel_set_cachemode(screen_base, screen_len,  					     IOMAP_WRITETHROUGH);  		} -		printk("atafb: screen_base %p real_screen_base %p screen_len %d\n", -			screen_base, real_screen_base, screen_len); +		printk("atafb: screen_base %p phys_screen_base %lx screen_len %d\n", +			screen_base, phys_screen_base, screen_len);  #ifdef ATAFB_EXT  	} else {  		/* Map the video memory (physical address given) to somewhere  		 * in the kernel address space.  		 */ -		external_addr = ioremap_writethrough((unsigned long)external_addr, +		external_screen_base = ioremap_writethrough(external_addr,  						     external_len);  		if (external_vgaiobase)  			external_vgaiobase =  			  (unsigned long)ioremap(external_vgaiobase, 0x10000); -		screen_base = -		real_screen_base = external_addr; +		screen_base = external_screen_base; +		phys_screen_base = external_addr;  		screen_len = external_len & PAGE_MASK;  		memset (screen_base, 0, external_len);  	} @@ -3235,8 +3238,8 @@ int __init atafb_init(void)  	if (register_framebuffer(&fb_info) < 0) {  #ifdef ATAFB_EXT  		if (external_addr) { -			iounmap(external_addr); -			external_addr = NULL; +			iounmap(external_screen_base); +			external_addr = 0;  		}  		if (external_vgaiobase) {  			iounmap((void*)external_vgaiobase); @@ -3246,11 +3249,8 @@ int __init atafb_init(void)  		return -EINVAL;  	} -	// FIXME: mode needs setting! -	//printk("fb%d: %s frame buffer device, using %dK of video memory\n", -	//       fb_info.node, fb_info.mode->name, screen_len>>10); -	printk("fb%d: frame buffer device, using %dK of video memory\n", -	       fb_info.node, screen_len >> 10); +	fb_info(&fb_info, "frame buffer device, using %dK of video memory\n", +		screen_len >> 10);  	/* TODO: This driver cannot be unloaded yet */  	return 0; diff --git a/drivers/video/atafb.h b/drivers/video/fbdev/atafb.h index 014e05906cb..014e05906cb 100644 --- a/drivers/video/atafb.h +++ b/drivers/video/fbdev/atafb.h diff --git a/drivers/video/atafb_iplan2p2.c b/drivers/video/fbdev/atafb_iplan2p2.c index 8cc9c50379d..8cc9c50379d 100644 --- a/drivers/video/atafb_iplan2p2.c +++ b/drivers/video/fbdev/atafb_iplan2p2.c diff --git a/drivers/video/atafb_iplan2p4.c b/drivers/video/fbdev/atafb_iplan2p4.c index bee0d89463f..bee0d89463f 100644 --- a/drivers/video/atafb_iplan2p4.c +++ b/drivers/video/fbdev/atafb_iplan2p4.c diff --git a/drivers/video/atafb_iplan2p8.c b/drivers/video/fbdev/atafb_iplan2p8.c index 356fb52ce44..356fb52ce44 100644 --- a/drivers/video/atafb_iplan2p8.c +++ b/drivers/video/fbdev/atafb_iplan2p8.c diff --git a/drivers/video/atafb_mfb.c b/drivers/video/fbdev/atafb_mfb.c index 6a352d62eec..6a352d62eec 100644 --- a/drivers/video/atafb_mfb.c +++ b/drivers/video/fbdev/atafb_mfb.c diff --git a/drivers/video/atafb_utils.h b/drivers/video/fbdev/atafb_utils.h index ac9e19dc505..ac9e19dc505 100644 --- a/drivers/video/atafb_utils.h +++ b/drivers/video/fbdev/atafb_utils.h diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c index 088511a58a2..d36e830d6fc 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/fbdev/atmel_lcdfb.c @@ -20,12 +20,55 @@  #include <linux/gfp.h>  #include <linux/module.h>  #include <linux/platform_data/atmel.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h> +#include <video/of_display_timing.h> +#include <video/videomode.h>  #include <mach/cpu.h>  #include <asm/gpio.h>  #include <video/atmel_lcdc.h> +struct atmel_lcdfb_config { +	bool have_alt_pixclock; +	bool have_hozval; +	bool have_intensity_bit; +}; + + /* LCD Controller info data structure, stored in device platform_data */ +struct atmel_lcdfb_info { +	spinlock_t		lock; +	struct fb_info		*info; +	void __iomem		*mmio; +	int			irq_base; +	struct work_struct	task; + +	unsigned int		smem_len; +	struct platform_device	*pdev; +	struct clk		*bus_clk; +	struct clk		*lcdc_clk; + +	struct backlight_device	*backlight; +	u8			bl_power; +	u8			saved_lcdcon; + +	u32			pseudo_palette[16]; +	bool			have_intensity_bit; + +	struct atmel_lcdfb_pdata pdata; + +	struct atmel_lcdfb_config *config; +}; + +struct atmel_lcdfb_power_ctrl_gpio { +	int gpio; +	int active_low; + +	struct list_head list; +}; +  #define lcdc_readl(sinfo, reg)		__raw_readl((sinfo)->mmio+(reg))  #define lcdc_writel(sinfo, reg, val)	__raw_writel((val), (sinfo)->mmio+(reg)) @@ -34,12 +77,6 @@  #define ATMEL_LCDC_DMA_BURST_LEN	8	/* words */  #define ATMEL_LCDC_FIFO_SIZE		512	/* words */ -struct atmel_lcdfb_config { -	bool have_alt_pixclock; -	bool have_hozval; -	bool have_intensity_bit; -}; -  static struct atmel_lcdfb_config at91sam9261_config = {  	.have_hozval		= true,  	.have_intensity_bit	= true, @@ -94,6 +131,7 @@ static const struct platform_device_id atmel_lcdfb_devtypes[] = {  		/* terminator */  	}  }; +MODULE_DEVICE_TABLE(platform, atmel_lcdfb_devtypes);  static struct atmel_lcdfb_config *  atmel_lcdfb_get_config(struct platform_device *pdev) @@ -248,18 +286,27 @@ static void exit_backlight(struct atmel_lcdfb_info *sinfo)  static void init_contrast(struct atmel_lcdfb_info *sinfo)  { +	struct atmel_lcdfb_pdata *pdata = &sinfo->pdata; +  	/* contrast pwm can be 'inverted' */ -	if (sinfo->lcdcon_pol_negative) +	if (pdata->lcdcon_pol_negative)  			contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);  	/* have some default contrast/backlight settings */  	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);  	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT); -	if (sinfo->lcdcon_is_backlight) +	if (pdata->lcdcon_is_backlight)  		init_backlight(sinfo);  } +static inline void atmel_lcdfb_power_control(struct atmel_lcdfb_info *sinfo, int on) +{ +	struct atmel_lcdfb_pdata *pdata = &sinfo->pdata; + +	if (pdata->atmel_lcdfb_power_control) +		pdata->atmel_lcdfb_power_control(pdata, on); +}  static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = {  	.type		= FB_TYPE_PACKED_PIXELS, @@ -299,9 +346,11 @@ static unsigned long compute_hozval(struct atmel_lcdfb_info *sinfo,  static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo)  { +	struct atmel_lcdfb_pdata *pdata = &sinfo->pdata; +  	/* Turn off the LCD controller and the DMA controller */  	lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, -			sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); +			pdata->guard_time << ATMEL_LCDC_GUARDT_OFFSET);  	/* Wait for the LCDC core to become idle */  	while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) @@ -321,9 +370,11 @@ static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo)  static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo)  { -	lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon); +	struct atmel_lcdfb_pdata *pdata = &sinfo->pdata; + +	lcdc_writel(sinfo, ATMEL_LCDC_DMACON, pdata->default_dmacon);  	lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, -		(sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) +		(pdata->guard_time << ATMEL_LCDC_GUARDT_OFFSET)  		| ATMEL_LCDC_PWR);  } @@ -424,6 +475,7 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,  {  	struct device *dev = info->device;  	struct atmel_lcdfb_info *sinfo = info->par; +	struct atmel_lcdfb_pdata *pdata = &sinfo->pdata;  	unsigned long clk_value_khz;  	clk_value_khz = clk_get_rate(sinfo->lcdc_clk) / 1000; @@ -510,7 +562,7 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,  		else  			var->green.length = 6; -		if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) { +		if (pdata->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {  			/* RGB:5X5 mode */  			var->red.offset = var->green.length + 5;  			var->blue.offset = 0; @@ -527,7 +579,7 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var,  		var->transp.length = 8;  		/* fall through */  	case 24: -		if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) { +		if (pdata->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {  			/* RGB:888 mode */  			var->red.offset = 16;  			var->blue.offset = 0; @@ -576,6 +628,7 @@ static void atmel_lcdfb_reset(struct atmel_lcdfb_info *sinfo)  static int atmel_lcdfb_set_par(struct fb_info *info)  {  	struct atmel_lcdfb_info *sinfo = info->par; +	struct atmel_lcdfb_pdata *pdata = &sinfo->pdata;  	unsigned long hozval_linesz;  	unsigned long value;  	unsigned long clk_value_khz; @@ -637,7 +690,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info)  	/* Initialize control register 2 */ -	value = sinfo->default_lcdcon2; +	value = pdata->default_lcdcon2;  	if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))  		value |= ATMEL_LCDC_INVLINE_INVERTED; @@ -741,6 +794,7 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red,  			     unsigned int transp, struct fb_info *info)  {  	struct atmel_lcdfb_info *sinfo = info->par; +	struct atmel_lcdfb_pdata *pdata = &sinfo->pdata;  	unsigned int val;  	u32 *pal;  	int ret = 1; @@ -777,8 +831,7 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red,  				 */  			} else {  				/* new style BGR:565 / RGB:565 */ -				if (sinfo->lcd_wiring_mode == -				    ATMEL_LCDC_WIRING_RGB) { +				if (pdata->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) {  					val  = ((blue >> 11) & 0x001f);  					val |= ((red  >>  0) & 0xf800);  				} else { @@ -912,16 +965,189 @@ static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo)  	clk_disable_unprepare(sinfo->lcdc_clk);  } +#ifdef CONFIG_OF +static const struct of_device_id atmel_lcdfb_dt_ids[] = { +	{ .compatible = "atmel,at91sam9261-lcdc" , .data = &at91sam9261_config, }, +	{ .compatible = "atmel,at91sam9263-lcdc" , .data = &at91sam9263_config, }, +	{ .compatible = "atmel,at91sam9g10-lcdc" , .data = &at91sam9g10_config, }, +	{ .compatible = "atmel,at91sam9g45-lcdc" , .data = &at91sam9g45_config, }, +	{ .compatible = "atmel,at91sam9g45es-lcdc" , .data = &at91sam9g45es_config, }, +	{ .compatible = "atmel,at91sam9rl-lcdc" , .data = &at91sam9rl_config, }, +	{ .compatible = "atmel,at32ap-lcdc" , .data = &at32ap_config, }, +	{ /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, atmel_lcdfb_dt_ids); + +static const char *atmel_lcdfb_wiring_modes[] = { +	[ATMEL_LCDC_WIRING_BGR]	= "BRG", +	[ATMEL_LCDC_WIRING_RGB]	= "RGB", +}; + +const int atmel_lcdfb_get_of_wiring_modes(struct device_node *np) +{ +	const char *mode; +	int err, i; + +	err = of_property_read_string(np, "atmel,lcd-wiring-mode", &mode); +	if (err < 0) +		return ATMEL_LCDC_WIRING_BGR; + +	for (i = 0; i < ARRAY_SIZE(atmel_lcdfb_wiring_modes); i++) +		if (!strcasecmp(mode, atmel_lcdfb_wiring_modes[i])) +			return i; + +	return -ENODEV; +} + +static void atmel_lcdfb_power_control_gpio(struct atmel_lcdfb_pdata *pdata, int on) +{ +	struct atmel_lcdfb_power_ctrl_gpio *og; + +	list_for_each_entry(og, &pdata->pwr_gpios, list) +		gpio_set_value(og->gpio, on); +} + +static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo) +{ +	struct fb_info *info = sinfo->info; +	struct atmel_lcdfb_pdata *pdata = &sinfo->pdata; +	struct fb_var_screeninfo *var = &info->var; +	struct device *dev = &sinfo->pdev->dev; +	struct device_node *np =dev->of_node; +	struct device_node *display_np; +	struct device_node *timings_np; +	struct display_timings *timings; +	enum of_gpio_flags flags; +	struct atmel_lcdfb_power_ctrl_gpio *og; +	bool is_gpio_power = false; +	int ret = -ENOENT; +	int i, gpio; + +	sinfo->config = (struct atmel_lcdfb_config*) +		of_match_device(atmel_lcdfb_dt_ids, dev)->data; + +	display_np = of_parse_phandle(np, "display", 0); +	if (!display_np) { +		dev_err(dev, "failed to find display phandle\n"); +		return -ENOENT; +	} + +	ret = of_property_read_u32(display_np, "bits-per-pixel", &var->bits_per_pixel); +	if (ret < 0) { +		dev_err(dev, "failed to get property bits-per-pixel\n"); +		goto put_display_node; +	} + +	ret = of_property_read_u32(display_np, "atmel,guard-time", &pdata->guard_time); +	if (ret < 0) { +		dev_err(dev, "failed to get property atmel,guard-time\n"); +		goto put_display_node; +	} + +	ret = of_property_read_u32(display_np, "atmel,lcdcon2", &pdata->default_lcdcon2); +	if (ret < 0) { +		dev_err(dev, "failed to get property atmel,lcdcon2\n"); +		goto put_display_node; +	} + +	ret = of_property_read_u32(display_np, "atmel,dmacon", &pdata->default_dmacon); +	if (ret < 0) { +		dev_err(dev, "failed to get property bits-per-pixel\n"); +		goto put_display_node; +	} + +	INIT_LIST_HEAD(&pdata->pwr_gpios); +	ret = -ENOMEM; +	for (i = 0; i < of_gpio_named_count(display_np, "atmel,power-control-gpio"); i++) { +		gpio = of_get_named_gpio_flags(display_np, "atmel,power-control-gpio", +					       i, &flags); +		if (gpio < 0) +			continue; + +		og = devm_kzalloc(dev, sizeof(*og), GFP_KERNEL); +		if (!og) +			goto put_display_node; + +		og->gpio = gpio; +		og->active_low = flags & OF_GPIO_ACTIVE_LOW; +		is_gpio_power = true; +		ret = devm_gpio_request(dev, gpio, "lcd-power-control-gpio"); +		if (ret) { +			dev_err(dev, "request gpio %d failed\n", gpio); +			goto put_display_node; +		} + +		ret = gpio_direction_output(gpio, og->active_low); +		if (ret) { +			dev_err(dev, "set direction output gpio %d failed\n", gpio); +			goto put_display_node; +		} +		list_add(&og->list, &pdata->pwr_gpios); +	} + +	if (is_gpio_power) +		pdata->atmel_lcdfb_power_control = atmel_lcdfb_power_control_gpio; + +	ret = atmel_lcdfb_get_of_wiring_modes(display_np); +	if (ret < 0) { +		dev_err(dev, "invalid atmel,lcd-wiring-mode\n"); +		goto put_display_node; +	} +	pdata->lcd_wiring_mode = ret; + +	pdata->lcdcon_is_backlight = of_property_read_bool(display_np, "atmel,lcdcon-backlight"); + +	timings = of_get_display_timings(display_np); +	if (!timings) { +		dev_err(dev, "failed to get display timings\n"); +		goto put_display_node; +	} + +	timings_np = of_find_node_by_name(display_np, "display-timings"); +	if (!timings_np) { +		dev_err(dev, "failed to find display-timings node\n"); +		goto put_display_node; +	} + +	for (i = 0; i < of_get_child_count(timings_np); i++) { +		struct videomode vm; +		struct fb_videomode fb_vm; + +		ret = videomode_from_timings(timings, &vm, i); +		if (ret < 0) +			goto put_timings_node; +		ret = fb_videomode_from_videomode(&vm, &fb_vm); +		if (ret < 0) +			goto put_timings_node; + +		fb_add_videomode(&fb_vm, &info->modelist); +	} + +	return 0; + +put_timings_node: +	of_node_put(timings_np); +put_display_node: +	of_node_put(display_np); +	return ret; +} +#else +static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo) +{ +	return 0; +} +#endif  static int __init atmel_lcdfb_probe(struct platform_device *pdev)  {  	struct device *dev = &pdev->dev;  	struct fb_info *info;  	struct atmel_lcdfb_info *sinfo; -	struct atmel_lcdfb_info *pdata_sinfo; -	struct fb_videomode fbmode; +	struct atmel_lcdfb_pdata *pdata = NULL;  	struct resource *regs = NULL;  	struct resource *map = NULL; +	struct fb_modelist *modelist;  	int ret;  	dev_dbg(dev, "%s BEGIN\n", __func__); @@ -934,36 +1160,44 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)  	}  	sinfo = info->par; +	sinfo->pdev = pdev; +	sinfo->info = info; + +	INIT_LIST_HEAD(&info->modelist); + +	if (pdev->dev.of_node) { +		ret = atmel_lcdfb_of_init(sinfo); +		if (ret) +			goto free_info; +	} else if (dev_get_platdata(dev)) { +		struct fb_monspecs *monspecs; +		int i; -	if (dev->platform_data) { -		pdata_sinfo = (struct atmel_lcdfb_info *)dev->platform_data; -		sinfo->default_bpp = pdata_sinfo->default_bpp; -		sinfo->default_dmacon = pdata_sinfo->default_dmacon; -		sinfo->default_lcdcon2 = pdata_sinfo->default_lcdcon2; -		sinfo->default_monspecs = pdata_sinfo->default_monspecs; -		sinfo->atmel_lcdfb_power_control = pdata_sinfo->atmel_lcdfb_power_control; -		sinfo->guard_time = pdata_sinfo->guard_time; -		sinfo->smem_len = pdata_sinfo->smem_len; -		sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight; -		sinfo->lcdcon_pol_negative = pdata_sinfo->lcdcon_pol_negative; -		sinfo->lcd_wiring_mode = pdata_sinfo->lcd_wiring_mode; +		pdata = dev_get_platdata(dev); +		monspecs = pdata->default_monspecs; +		sinfo->pdata = *pdata; + +		for (i = 0; i < monspecs->modedb_len; i++) +			fb_add_videomode(&monspecs->modedb[i], &info->modelist); + +		sinfo->config = atmel_lcdfb_get_config(pdev); + +		info->var.bits_per_pixel = pdata->default_bpp ? pdata->default_bpp : 16; +		memcpy(&info->monspecs, pdata->default_monspecs, sizeof(info->monspecs));  	} else {  		dev_err(dev, "cannot get default configuration\n");  		goto free_info;  	} -	sinfo->info = info; -	sinfo->pdev = pdev; -	sinfo->config = atmel_lcdfb_get_config(pdev); +  	if (!sinfo->config)  		goto free_info; -	strcpy(info->fix.id, sinfo->pdev->name);  	info->flags = ATMEL_LCDFB_FBINFO_DEFAULT;  	info->pseudo_palette = sinfo->pseudo_palette;  	info->fbops = &atmel_lcdfb_ops; -	memcpy(&info->monspecs, sinfo->default_monspecs, sizeof(info->monspecs));  	info->fix = atmel_lcdfb_fix; +	strcpy(info->fix.id, sinfo->pdev->name);  	/* Enable LCDC Clocks */  	sinfo->bus_clk = clk_get(dev, "hclk"); @@ -978,14 +1212,11 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)  	}  	atmel_lcdfb_start_clock(sinfo); -	ret = fb_find_mode(&info->var, info, NULL, info->monspecs.modedb, -			info->monspecs.modedb_len, info->monspecs.modedb, -			sinfo->default_bpp); -	if (!ret) { -		dev_err(dev, "no suitable video mode found\n"); -		goto stop_clk; -	} +	modelist = list_first_entry(&info->modelist, +			struct fb_modelist, list); +	fb_videomode_to_var(&info->var, &modelist->mode); +	atmel_lcdfb_check_var(&info->var, info);  	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	if (!regs) { @@ -1069,16 +1300,10 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)  		goto unregister_irqs;  	} -	/* -	 * This makes sure that our colour bitfield -	 * descriptors are correctly initialised. -	 */ -	atmel_lcdfb_check_var(&info->var, info); - -	ret = fb_set_var(info, &info->var); -	if (ret) { -		dev_warn(dev, "unable to set display parameters\n"); -		goto free_cmap; +	ret = atmel_lcdfb_set_par(info); +	if (ret < 0) { +		dev_err(dev, "set par failed: %d\n", ret); +		goto unregister_irqs;  	}  	dev_set_drvdata(dev, info); @@ -1092,13 +1317,8 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)  		goto reset_drvdata;  	} -	/* add selected videomode to modelist */ -	fb_var_to_videomode(&fbmode, &info->var); -	fb_add_videomode(&fbmode, &info->modelist); -  	/* Power up the LCDC screen */ -	if (sinfo->atmel_lcdfb_power_control) -		sinfo->atmel_lcdfb_power_control(1); +	atmel_lcdfb_power_control(sinfo, 1);  	dev_info(dev, "fb%d: Atmel LCDC at 0x%08lx (mapped at %p), irq %d\n",  		       info->node, info->fix.mmio_start, sinfo->mmio, sinfo->irq_base); @@ -1107,7 +1327,6 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)  reset_drvdata:  	dev_set_drvdata(dev, NULL); -free_cmap:  	fb_dealloc_cmap(&info->cmap);  unregister_irqs:  	cancel_work_sync(&sinfo->task); @@ -1143,15 +1362,16 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev)  	struct device *dev = &pdev->dev;  	struct fb_info *info = dev_get_drvdata(dev);  	struct atmel_lcdfb_info *sinfo; +	struct atmel_lcdfb_pdata *pdata;  	if (!info || !info->par)  		return 0;  	sinfo = info->par; +	pdata = &sinfo->pdata;  	cancel_work_sync(&sinfo->task);  	exit_backlight(sinfo); -	if (sinfo->atmel_lcdfb_power_control) -		sinfo->atmel_lcdfb_power_control(0); +	atmel_lcdfb_power_control(sinfo, 0);  	unregister_framebuffer(info);  	atmel_lcdfb_stop_clock(sinfo);  	clk_put(sinfo->lcdc_clk); @@ -1167,7 +1387,6 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev)  		atmel_lcdfb_free_video_memory(sinfo);  	} -	dev_set_drvdata(dev, NULL);  	framebuffer_release(info);  	return 0; @@ -1188,9 +1407,7 @@ static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg)  	sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_CTR);  	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0); -	if (sinfo->atmel_lcdfb_power_control) -		sinfo->atmel_lcdfb_power_control(0); - +	atmel_lcdfb_power_control(sinfo, 0);  	atmel_lcdfb_stop(sinfo);  	atmel_lcdfb_stop_clock(sinfo); @@ -1204,8 +1421,7 @@ static int atmel_lcdfb_resume(struct platform_device *pdev)  	atmel_lcdfb_start_clock(sinfo);  	atmel_lcdfb_start(sinfo); -	if (sinfo->atmel_lcdfb_power_control) -		sinfo->atmel_lcdfb_power_control(1); +	atmel_lcdfb_power_control(sinfo, 1);  	lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon);  	/* Enable FIFO & DMA errors */ @@ -1228,6 +1444,7 @@ static struct platform_driver atmel_lcdfb_driver = {  	.driver		= {  		.name	= "atmel_lcdfb",  		.owner	= THIS_MODULE, +		.of_match_table	= of_match_ptr(atmel_lcdfb_dt_ids),  	},  }; diff --git a/drivers/video/aty/Makefile b/drivers/video/fbdev/aty/Makefile index a6cc0e9ec79..a6cc0e9ec79 100644 --- a/drivers/video/aty/Makefile +++ b/drivers/video/fbdev/aty/Makefile diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/fbdev/aty/ati_ids.h index 3e9d28bcd9f..3e9d28bcd9f 100644 --- a/drivers/video/aty/ati_ids.h +++ b/drivers/video/fbdev/aty/ati_ids.h diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c index a4dfe8cb0a0..52108be69e7 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/fbdev/aty/aty128fb.c @@ -357,11 +357,13 @@ static int default_lcd_on = 1;  static bool mtrr = true;  #endif +#ifdef CONFIG_FB_ATY128_BACKLIGHT  #ifdef CONFIG_PMAC_BACKLIGHT  static int backlight = 1;  #else  static int backlight = 0;  #endif +#endif  /* PLL constants */  struct aty128_constants { @@ -413,7 +415,6 @@ struct aty128fb_par {  	int blitter_may_be_busy;  	int fifo_slots;                 /* free slots in FIFO (64 max) */ -	int	pm_reg;  	int crt_on, lcd_on;  	struct pci_dev *pdev;  	struct fb_info *next; @@ -1672,7 +1673,9 @@ static int aty128fb_setup(char *options)  			default_crt_on = simple_strtoul(this_opt+4, NULL, 0);  			continue;  		} else if (!strncmp(this_opt, "backlight:", 10)) { +#ifdef CONFIG_FB_ATY128_BACKLIGHT  			backlight = simple_strtoul(this_opt+10, NULL, 0); +#endif  			continue;  		}  #ifdef CONFIG_MTRR @@ -2016,7 +2019,6 @@ static int aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent)  	aty128_init_engine(par); -	par->pm_reg = pdev->pm_cap;  	par->pdev = pdev;  	par->asleep = 0;  	par->lock_blank = 0; @@ -2029,8 +2031,8 @@ static int aty128_init(struct pci_dev *pdev, const struct pci_device_id *ent)  	if (register_framebuffer(info) < 0)  		return 0; -	printk(KERN_INFO "fb%d: %s frame buffer device on %s\n", -	       info->node, info->fix.id, video_card); +	fb_info(info, "%s frame buffer device on %s\n", +		info->fix.id, video_card);  	return 1;	/* success! */  } @@ -2397,7 +2399,7 @@ static void aty128_set_suspend(struct aty128fb_par *par, int suspend)  	u32	pmgt;  	struct pci_dev *pdev = par->pdev; -	if (!par->pm_reg) +	if (!par->pdev->pm_cap)  		return;  	/* Set the chip into the appropriate suspend mode (we use D2, diff --git a/drivers/video/aty/atyfb.h b/drivers/video/fbdev/aty/atyfb.h index 1f39a62f899..1f39a62f899 100644 --- a/drivers/video/aty/atyfb.h +++ b/drivers/video/fbdev/aty/atyfb.h diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c index 9b0f12c5c28..c3d0074a32d 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/fbdev/aty/atyfb_base.c @@ -862,8 +862,8 @@ static int aty_var_to_crtc(const struct fb_info *info,  	h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;  	v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; -	if ((xres > 1600) || (yres > 1200)) { -		FAIL("MACH64 chips are designed for max 1600x1200\n" +	if ((xres > 1920) || (yres > 1200)) { +		FAIL("MACH64 chips are designed for max 1920x1200\n"  		     "select another resolution.");  	}  	h_sync_strt = h_disp + var->right_margin; @@ -1848,7 +1848,6 @@ static int atyfb_ioctl(struct fb_info *info, u_int cmd, u_long arg)  			return aty_waitforvblank(par, crtc);  		} -		break;  #if defined(DEBUG) && defined(CONFIG_FB_ATY_CT)  	case ATYIO_CLKR: @@ -2654,7 +2653,8 @@ static int aty_init(struct fb_info *info)  		      FBINFO_HWACCEL_IMAGEBLIT |  		      FBINFO_HWACCEL_FILLRECT  |  		      FBINFO_HWACCEL_COPYAREA  | -		      FBINFO_HWACCEL_YPAN; +		      FBINFO_HWACCEL_YPAN      | +		      FBINFO_READS_FAST;  #ifdef CONFIG_PMAC_BACKLIGHT  	if (M64_HAS(G3_PB_1_1) && of_machine_is_compatible("PowerBook1,1")) { diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/fbdev/aty/mach64_accel.c index e45833ce975..182bd680141 100644 --- a/drivers/video/aty/mach64_accel.c +++ b/drivers/video/fbdev/aty/mach64_accel.c @@ -4,6 +4,7 @@   */  #include <linux/delay.h> +#include <asm/unaligned.h>  #include <linux/fb.h>  #include <video/mach64.h>  #include "atyfb.h" @@ -419,7 +420,7 @@ void atyfb_imageblit(struct fb_info *info, const struct fb_image *image)  		u32 *pbitmap, dwords = (src_bytes + 3) / 4;  		for (pbitmap = (u32*)(image->data); dwords; dwords--, pbitmap++) {  			wait_for_fifo(1, par); -			aty_st_le32(HOST_DATA0, le32_to_cpup(pbitmap), par); +			aty_st_le32(HOST_DATA0, get_unaligned_le32(pbitmap), par);  		}  	} diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/fbdev/aty/mach64_ct.c index 51f29d627ce..51f29d627ce 100644 --- a/drivers/video/aty/mach64_ct.c +++ b/drivers/video/fbdev/aty/mach64_ct.c diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/fbdev/aty/mach64_cursor.c index 95ec042ddbf..2fa0317ab3c 100644 --- a/drivers/video/aty/mach64_cursor.c +++ b/drivers/video/fbdev/aty/mach64_cursor.c @@ -5,6 +5,7 @@  #include <linux/fb.h>  #include <linux/init.h>  #include <linux/string.h> +#include "../core/fb_draw.h"  #include <asm/io.h> @@ -157,24 +158,33 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)  	    for (i = 0; i < height; i++) {  		for (j = 0; j < width; j++) { +			u16 l = 0xaaaa;  			b = *src++;  			m = *msk++;  			switch (cursor->rop) {  			case ROP_XOR:  			    // Upper 4 bits of mask data -			    fb_writeb(cursor_bits_lookup[(b ^ m) >> 4], dst++); +			    l = cursor_bits_lookup[(b ^ m) >> 4] |  			    // Lower 4 bits of mask -			    fb_writeb(cursor_bits_lookup[(b ^ m) & 0x0f], -				      dst++); +				    (cursor_bits_lookup[(b ^ m) & 0x0f] << 8);  			    break;  			case ROP_COPY:  			    // Upper 4 bits of mask data -			    fb_writeb(cursor_bits_lookup[(b & m) >> 4], dst++); +			    l = cursor_bits_lookup[(b & m) >> 4] |  			    // Lower 4 bits of mask -			    fb_writeb(cursor_bits_lookup[(b & m) & 0x0f], -				      dst++); +				    (cursor_bits_lookup[(b & m) & 0x0f] << 8);  			    break;  			} +			/* +			 * If cursor size is not a multiple of 8 characters +			 * we must pad it with transparent pattern (0xaaaa). +			 */ +			if ((j + 1) * 8 > cursor->image.width) { +				l = comp(l, 0xaaaa, +				    (1 << ((cursor->image.width & 7) * 2)) - 1); +			} +			fb_writeb(l & 0xff, dst++); +			fb_writeb(l >> 8, dst++);  		}  		dst += offset;  	    } diff --git a/drivers/video/aty/mach64_gx.c b/drivers/video/fbdev/aty/mach64_gx.c index 10c988aef58..10c988aef58 100644 --- a/drivers/video/aty/mach64_gx.c +++ b/drivers/video/fbdev/aty/mach64_gx.c diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/fbdev/aty/radeon_accel.c index a469a3d6edc..a469a3d6edc 100644 --- a/drivers/video/aty/radeon_accel.c +++ b/drivers/video/fbdev/aty/radeon_accel.c diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/fbdev/aty/radeon_backlight.c index db572df7e1e..db572df7e1e 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/fbdev/aty/radeon_backlight.c diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c index 1e30b2b3e79..26d80a4486f 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/fbdev/aty/radeon_base.c @@ -819,11 +819,6 @@ static int radeonfb_check_var (struct fb_var_screeninfo *var, struct fb_info *in  	if (v.xres_virtual < v.xres)  		v.xres = v.xres_virtual; -	if (v.xoffset < 0) -                v.xoffset = 0; -        if (v.yoffset < 0) -                v.yoffset = 0; -                   if (v.xoffset > v.xres_virtual - v.xres)                  v.xoffset = v.xres_virtual - v.xres - 1; diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/fbdev/aty/radeon_i2c.c index ab1d0fd7631..ab1d0fd7631 100644 --- a/drivers/video/aty/radeon_i2c.c +++ b/drivers/video/fbdev/aty/radeon_i2c.c diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/fbdev/aty/radeon_monitor.c index bc078d50d8f..bc078d50d8f 100644 --- a/drivers/video/aty/radeon_monitor.c +++ b/drivers/video/fbdev/aty/radeon_monitor.c diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/fbdev/aty/radeon_pm.c index f7091ece580..46a12f1a93c 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/fbdev/aty/radeon_pm.c @@ -1427,6 +1427,8 @@ static void radeon_pm_full_reset_sdram(struct radeonfb_info *rinfo)  	mdelay( 15);  } +#if defined(CONFIG_PM) +#if defined(CONFIG_X86) || defined(CONFIG_PPC_PMAC)  static void radeon_pm_reset_pad_ctlr_strength(struct radeonfb_info *rinfo)  {  	u32 tmp, tmp2; @@ -1939,9 +1941,10 @@ static void radeon_reinitialize_M10(struct radeonfb_info *rinfo)  	 */  	radeon_pm_m10_enable_lvds_spread_spectrum(rinfo);  } +#endif  #ifdef CONFIG_PPC_OF - +#ifdef CONFIG_PPC_PMAC  static void radeon_pm_m9p_reconfigure_mc(struct radeonfb_info *rinfo)  {  	OUTREG(MC_CNTL, rinfo->save_regs[46]); @@ -2202,6 +2205,8 @@ static void radeon_reinitialize_M9P(struct radeonfb_info *rinfo)  	radeon_pm_restore_pixel_pll(rinfo);  	radeon_pm_m10_enable_lvds_spread_spectrum(rinfo);  } +#endif +#endif  #if 0 /* Not ready yet */  static void radeon_reinitialize_QW(struct radeonfb_info *rinfo) @@ -2515,13 +2520,13 @@ static void radeonfb_whack_power_state(struct radeonfb_info *rinfo, pci_power_t  	for (;;) {  		pci_read_config_word(rinfo->pdev, -				     rinfo->pm_reg+PCI_PM_CTRL, +				     rinfo->pdev->pm_cap + PCI_PM_CTRL,  				     &pwr_cmd); -		if (pwr_cmd & 2) +		if (pwr_cmd & state)  			break; -		pwr_cmd = (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | 2; +		pwr_cmd = (pwr_cmd & ~PCI_PM_CTRL_STATE_MASK) | state;  		pci_write_config_word(rinfo->pdev, -				      rinfo->pm_reg+PCI_PM_CTRL, +				      rinfo->pdev->pm_cap + PCI_PM_CTRL,  				      pwr_cmd);  		msleep(500);  	} @@ -2532,7 +2537,7 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)  {  	u32 tmp; -	if (!rinfo->pm_reg) +	if (!rinfo->pdev->pm_cap)  		return;  	/* Set the chip into appropriate suspend mode (we use D2, @@ -2804,9 +2809,6 @@ static void radeonfb_early_resume(void *data)  void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep)  { -	/* Find PM registers in config space if any*/ -	rinfo->pm_reg = rinfo->pdev->pm_cap; -  	/* Enable/Disable dynamic clocks: TODO add sysfs access */  	if (rinfo->family == CHIP_FAMILY_RS480)  		rinfo->dynclk = -1; @@ -2830,7 +2832,7 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlis  	 * reason. --BenH  	 */  	if (machine_is(powermac) && rinfo->of_node) { -		if (rinfo->is_mobility && rinfo->pm_reg && +		if (rinfo->is_mobility && rinfo->pdev->pm_cap &&  		    rinfo->family <= CHIP_FAMILY_RV250)  			rinfo->pm_mode |= radeon_pm_d2; diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/fbdev/aty/radeonfb.h index 7351e66c7f5..cb846044f57 100644 --- a/drivers/video/aty/radeonfb.h +++ b/drivers/video/fbdev/aty/radeonfb.h @@ -342,7 +342,6 @@ struct radeonfb_info {  	int			mtrr_hdl; -	int			pm_reg;  	u32			save_regs[100];  	int			asleep;  	int			lock_blank; diff --git a/drivers/video/au1100fb.c b/drivers/video/fbdev/au1100fb.c index a54ccdc4d66..372d4aea9d1 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/fbdev/au1100fb.c @@ -361,37 +361,13 @@ void au1100fb_fb_rotate(struct fb_info *fbi, int angle)  int au1100fb_fb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)  {  	struct au1100fb_device *fbdev; -	unsigned int len; -	unsigned long start=0, off;  	fbdev = to_au1100fb_device(fbi); -	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) { -		return -EINVAL; -	} - -	start = fbdev->fb_phys & PAGE_MASK; -	len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len); - -	off = vma->vm_pgoff << PAGE_SHIFT; - -	if ((vma->vm_end - vma->vm_start + off) > len) { -		return -EINVAL; -	} - -	off += start; -	vma->vm_pgoff = off >> PAGE_SHIFT; -  	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);  	pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6 -	if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, -				vma->vm_end - vma->vm_start, -				vma->vm_page_prot)) { -		return -EAGAIN; -	} - -	return 0; +	return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len);  }  static struct fb_ops au1100fb_ops = @@ -588,7 +564,7 @@ int au1100fb_drv_remove(struct platform_device *dev)  	if (!dev)  		return -ENODEV; -	fbdev = (struct au1100fb_device *) platform_get_drvdata(dev); +	fbdev = platform_get_drvdata(dev);  #if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)  	au1100fb_fb_blank(VESA_POWERDOWN, &fbdev->info); @@ -660,19 +636,7 @@ static struct platform_driver au1100fb_driver = {  	.suspend	= au1100fb_drv_suspend,          .resume		= au1100fb_drv_resume,  }; - -static int __init au1100fb_load(void) -{ -	return platform_driver_register(&au1100fb_driver); -} - -static void __exit au1100fb_unload(void) -{ -	platform_driver_unregister(&au1100fb_driver); -} - -module_init(au1100fb_load); -module_exit(au1100fb_unload); +module_platform_driver(au1100fb_driver);  MODULE_DESCRIPTION(DRIVER_DESC);  MODULE_LICENSE("GPL"); diff --git a/drivers/video/au1100fb.h b/drivers/video/fbdev/au1100fb.h index 12d9642d546..12d9642d546 100644 --- a/drivers/video/au1100fb.h +++ b/drivers/video/fbdev/au1100fb.h diff --git a/drivers/video/au1200fb.c b/drivers/video/fbdev/au1200fb.c index 301224ecc95..4cfba78a145 100644 --- a/drivers/video/au1200fb.c +++ b/drivers/video/fbdev/au1200fb.c @@ -1233,34 +1233,13 @@ static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi)   * method mainly to allow the use of the TLB streaming flag (CCA=6)   */  static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma) -  { -	unsigned int len; -	unsigned long start=0, off;  	struct au1200fb_device *fbdev = info->par; -	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) { -		return -EINVAL; -	} - -	start = fbdev->fb_phys & PAGE_MASK; -	len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len); - -	off = vma->vm_pgoff << PAGE_SHIFT; - -	if ((vma->vm_end - vma->vm_start + off) > len) { -		return -EINVAL; -	} - -	off += start; -	vma->vm_pgoff = off >> PAGE_SHIFT; -  	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);  	pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */ -	return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, -				  vma->vm_end - vma->vm_start, -				  vma->vm_page_prot); +	return vm_iomap_memory(vma, fbdev->fb_phys, fbdev->fb_len);  }  static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata) @@ -1874,21 +1853,7 @@ static struct platform_driver au1200fb_driver = {  	.probe		= au1200fb_drv_probe,  	.remove		= au1200fb_drv_remove,  }; - -/*-------------------------------------------------------------------------*/ - -static int __init au1200fb_init(void) -{ -	return platform_driver_register(&au1200fb_driver); -} - -static void __exit au1200fb_cleanup(void) -{ -	platform_driver_unregister(&au1200fb_driver); -} - -module_init(au1200fb_init); -module_exit(au1200fb_cleanup); +module_platform_driver(au1200fb_driver);  MODULE_DESCRIPTION(DRIVER_DESC);  MODULE_LICENSE("GPL"); diff --git a/drivers/video/au1200fb.h b/drivers/video/fbdev/au1200fb.h index e2672714d8d..e2672714d8d 100644 --- a/drivers/video/au1200fb.h +++ b/drivers/video/fbdev/au1200fb.h diff --git a/drivers/video/auo_k1900fb.c b/drivers/video/fbdev/auo_k1900fb.c index f5b668e77af..f5b668e77af 100644 --- a/drivers/video/auo_k1900fb.c +++ b/drivers/video/fbdev/auo_k1900fb.c diff --git a/drivers/video/auo_k1901fb.c b/drivers/video/fbdev/auo_k1901fb.c index 12b9adcb75c..12b9adcb75c 100644 --- a/drivers/video/auo_k1901fb.c +++ b/drivers/video/fbdev/auo_k1901fb.c diff --git a/drivers/video/auo_k190x.c b/drivers/video/fbdev/auo_k190x.c index 8d2499d1caf..8d2499d1caf 100644 --- a/drivers/video/auo_k190x.c +++ b/drivers/video/fbdev/auo_k190x.c diff --git a/drivers/video/auo_k190x.h b/drivers/video/fbdev/auo_k190x.h index e35af1f51b2..e35af1f51b2 100644 --- a/drivers/video/auo_k190x.h +++ b/drivers/video/fbdev/auo_k190x.h diff --git a/drivers/video/bf537-lq035.c b/drivers/video/fbdev/bf537-lq035.c index a82d2578d97..a82d2578d97 100644 --- a/drivers/video/bf537-lq035.c +++ b/drivers/video/fbdev/bf537-lq035.c diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/fbdev/bf54x-lq043fb.c index 87f288bfc58..adbef542c99 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/fbdev/bf54x-lq043fb.c @@ -49,13 +49,13 @@  #include <linux/spinlock.h>  #include <linux/dma-mapping.h>  #include <linux/platform_device.h> +#include <linux/gpio.h>  #include <asm/blackfin.h>  #include <asm/irq.h>  #include <asm/dpmc.h>  #include <asm/dma-mapping.h>  #include <asm/dma.h> -#include <asm/gpio.h>  #include <asm/portmux.h>  #include <mach/bf54x-lq043.h> @@ -717,8 +717,6 @@ static int bfin_bf54x_remove(struct platform_device *pdev)  #ifdef CONFIG_PM  static int bfin_bf54x_suspend(struct platform_device *pdev, pm_message_t state)  { -	struct fb_info *fbinfo = platform_get_drvdata(pdev); -  	bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() & ~EPPI_EN);  	disable_dma(CH_EPPI0);  	bfin_write_EPPI0_STATUS(0xFFFF); @@ -761,19 +759,7 @@ static struct platform_driver bfin_bf54x_driver = {  		   .owner = THIS_MODULE,  		   },  }; - -static int __init bfin_bf54x_driver_init(void) -{ -	return platform_driver_register(&bfin_bf54x_driver); -} - -static void __exit bfin_bf54x_driver_cleanup(void) -{ -	platform_driver_unregister(&bfin_bf54x_driver); -} +module_platform_driver(bfin_bf54x_driver);  MODULE_DESCRIPTION("Blackfin BF54x TFT LCD Driver");  MODULE_LICENSE("GPL"); - -module_init(bfin_bf54x_driver_init); -module_exit(bfin_bf54x_driver_cleanup); diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/fbdev/bfin-lq035q1-fb.c index b594a58ff21..b594a58ff21 100644 --- a/drivers/video/bfin-lq035q1-fb.c +++ b/drivers/video/fbdev/bfin-lq035q1-fb.c diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/fbdev/bfin-t350mcqb-fb.c index 48c0c4e38a6..b5cf1307a3d 100644 --- a/drivers/video/bfin-t350mcqb-fb.c +++ b/drivers/video/fbdev/bfin-t350mcqb-fb.c @@ -664,19 +664,7 @@ static struct platform_driver bfin_t350mcqb_driver = {  		   .owner = THIS_MODULE,  		   },  }; - -static int __init bfin_t350mcqb_driver_init(void) -{ -	return platform_driver_register(&bfin_t350mcqb_driver); -} - -static void __exit bfin_t350mcqb_driver_cleanup(void) -{ -	platform_driver_unregister(&bfin_t350mcqb_driver); -} +module_platform_driver(bfin_t350mcqb_driver);  MODULE_DESCRIPTION("Blackfin TFT LCD Driver");  MODULE_LICENSE("GPL"); - -module_init(bfin_t350mcqb_driver_init); -module_exit(bfin_t350mcqb_driver_cleanup); diff --git a/drivers/video/bfin_adv7393fb.c b/drivers/video/fbdev/bfin_adv7393fb.c index a54f7f7d763..8fe41caac38 100644 --- a/drivers/video/bfin_adv7393fb.c +++ b/drivers/video/fbdev/bfin_adv7393fb.c @@ -408,7 +408,7 @@ static int bfin_adv7393_fb_probe(struct i2c_client *client,  	/* Workaround "PPI Does Not Start Properly In Specific Mode" */  	if (ANOMALY_05000400) {  		ret = gpio_request_one(P_IDENT(P_PPI0_FS3), GPIOF_OUT_INIT_LOW, -					"PPI0_FS3") +					"PPI0_FS3");  		if (ret) {  			dev_err(&client->dev, "PPI0_FS3 GPIO request failed\n");  			ret = -EBUSY; diff --git a/drivers/video/bfin_adv7393fb.h b/drivers/video/fbdev/bfin_adv7393fb.h index cd591b5152a..cd591b5152a 100644 --- a/drivers/video/bfin_adv7393fb.h +++ b/drivers/video/fbdev/bfin_adv7393fb.h diff --git a/drivers/video/broadsheetfb.c b/drivers/video/fbdev/broadsheetfb.c index b09701c7943..8556264b16b 100644 --- a/drivers/video/broadsheetfb.c +++ b/drivers/video/fbdev/broadsheetfb.c @@ -1167,9 +1167,8 @@ static int broadsheetfb_probe(struct platform_device *dev)  	if (retval < 0)  		goto err_unreg_fb; -	printk(KERN_INFO -	       "fb%d: Broadsheet frame buffer, using %dK of video memory\n", -	       info->node, videomemorysize >> 10); +	fb_info(info, "Broadsheet frame buffer, using %dK of video memory\n", +		videomemorysize >> 10);  	return 0; @@ -1217,19 +1216,7 @@ static struct platform_driver broadsheetfb_driver = {  		.name	= "broadsheetfb",  	},  }; - -static int __init broadsheetfb_init(void) -{ -	return platform_driver_register(&broadsheetfb_driver); -} - -static void __exit broadsheetfb_exit(void) -{ -	platform_driver_unregister(&broadsheetfb_driver); -} - -module_init(broadsheetfb_init); -module_exit(broadsheetfb_exit); +module_platform_driver(broadsheetfb_driver);  MODULE_DESCRIPTION("fbdev driver for Broadsheet controller");  MODULE_AUTHOR("Jaya Kumar"); diff --git a/drivers/video/bt431.h b/drivers/video/fbdev/bt431.h index 04e0cfbba53..04e0cfbba53 100644 --- a/drivers/video/bt431.h +++ b/drivers/video/fbdev/bt431.h diff --git a/drivers/video/bt455.h b/drivers/video/fbdev/bt455.h index 80f61b03e9a..80f61b03e9a 100644 --- a/drivers/video/bt455.h +++ b/drivers/video/fbdev/bt455.h diff --git a/drivers/video/bw2.c b/drivers/video/fbdev/bw2.c index 60017fc634b..bc123d6947a 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/fbdev/bw2.c @@ -363,8 +363,6 @@ static int bw2_remove(struct platform_device *op)  	framebuffer_release(info); -	dev_set_drvdata(&op->dev, NULL); -  	return 0;  } diff --git a/drivers/video/c2p.h b/drivers/video/fbdev/c2p.h index 6c38d40427d..6c38d40427d 100644 --- a/drivers/video/c2p.h +++ b/drivers/video/fbdev/c2p.h diff --git a/drivers/video/c2p_core.h b/drivers/video/fbdev/c2p_core.h index e1035a865fb..e1035a865fb 100644 --- a/drivers/video/c2p_core.h +++ b/drivers/video/fbdev/c2p_core.h diff --git a/drivers/video/c2p_iplan2.c b/drivers/video/fbdev/c2p_iplan2.c index 19156dc6158..19156dc6158 100644 --- a/drivers/video/c2p_iplan2.c +++ b/drivers/video/fbdev/c2p_iplan2.c diff --git a/drivers/video/c2p_planar.c b/drivers/video/fbdev/c2p_planar.c index ec7ac8526f0..ec7ac8526f0 100644 --- a/drivers/video/c2p_planar.c +++ b/drivers/video/fbdev/c2p_planar.c diff --git a/drivers/video/carminefb.c b/drivers/video/fbdev/carminefb.c index 153dd65b0ae..65f7c15f5fd 100644 --- a/drivers/video/carminefb.c +++ b/drivers/video/fbdev/carminefb.c @@ -585,8 +585,7 @@ static int alloc_carmine_fb(void __iomem *regs, void __iomem *smem_base,  	if (ret < 0)  		goto err_dealloc_cmap; -	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, -			info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	*rinfo = info;  	return 0; @@ -746,7 +745,6 @@ static void carminefb_remove(struct pci_dev *dev)  	iounmap(hw->v_regs);  	release_mem_region(fix.mmio_start, fix.mmio_len); -	pci_set_drvdata(dev, NULL);  	pci_disable_device(dev);  	kfree(hw);  } diff --git a/drivers/video/carminefb.h b/drivers/video/fbdev/carminefb.h index 05306de0c6b..05306de0c6b 100644 --- a/drivers/video/carminefb.h +++ b/drivers/video/fbdev/carminefb.h diff --git a/drivers/video/carminefb_regs.h b/drivers/video/fbdev/carminefb_regs.h index 045215600b7..045215600b7 100644 --- a/drivers/video/carminefb_regs.h +++ b/drivers/video/fbdev/carminefb_regs.h diff --git a/drivers/video/cg14.c b/drivers/video/fbdev/cg14.c index ed3b8891e00..c79745b136b 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/fbdev/cg14.c @@ -330,7 +330,7 @@ static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)  		default:  			ret = -ENOSYS;  			break; -		}; +		}  		if (!ret) {  			sbus_writeb(cur_mode, ®s->mcr);  			par->mode = mode; @@ -343,7 +343,7 @@ static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)  					  FBTYPE_MDICOLOR, 8,  					  info->fix.smem_len);  		break; -	}; +	}  	return ret;  } @@ -583,8 +583,6 @@ static int cg14_remove(struct platform_device *op)  	framebuffer_release(info); -	dev_set_drvdata(&op->dev, NULL); -  	return 0;  } diff --git a/drivers/video/cg3.c b/drivers/video/fbdev/cg3.c index 9f63507ded3..64a89d5747e 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/fbdev/cg3.c @@ -446,8 +446,6 @@ static int cg3_remove(struct platform_device *op)  	framebuffer_release(info); -	dev_set_drvdata(&op->dev, NULL); -  	return 0;  } diff --git a/drivers/video/cg6.c b/drivers/video/fbdev/cg6.c index 3545decc748..70781fea092 100644 --- a/drivers/video/cg6.c +++ b/drivers/video/fbdev/cg6.c @@ -624,7 +624,7 @@ static void cg6_init_fix(struct fb_info *info, int linebytes)  	default:  		cg6_cpu_name = "i386";  		break; -	}; +	}  	if (((conf >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK) >= 11) {  		if (info->fix.smem_len <= 0x100000)  			cg6_card_name = "TGX"; @@ -839,8 +839,6 @@ static int cg6_remove(struct platform_device *op)  	framebuffer_release(info); -	dev_set_drvdata(&op->dev, NULL); -  	return 0;  } diff --git a/drivers/video/chipsfb.c b/drivers/video/fbdev/chipsfb.c index 206a66b6107..206a66b6107 100644 --- a/drivers/video/chipsfb.c +++ b/drivers/video/fbdev/chipsfb.c diff --git a/drivers/video/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c index 97db3ba8f23..d992aa5eb3f 100644 --- a/drivers/video/cirrusfb.c +++ b/drivers/video/fbdev/cirrusfb.c @@ -595,11 +595,6 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,  		return -EINVAL;  	} -	if (var->xoffset < 0) -		var->xoffset = 0; -	if (var->yoffset < 0) -		var->yoffset = 0; -  	/* truncate xoffset and yoffset to maximum if too high */  	if (var->xoffset > var->xres_virtual - var->xres)  		var->xoffset = var->xres_virtual - var->xres - 1; @@ -2159,7 +2154,6 @@ static int cirrusfb_pci_register(struct pci_dev *pdev,  	if (!ret)  		return 0; -	pci_set_drvdata(pdev, NULL);  	iounmap(info->screen_base);  err_release_legacy:  	if (release_io_ports) @@ -2262,7 +2256,7 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,  	info->fix.mmio_start = regbase;  	cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024) -					    : (caddr_t)ZTWO_VADDR(regbase); +					    : ZTWO_VADDR(regbase);  	if (!cinfo->regbase) {  		dev_err(info->device, "Cannot map registers\n");  		error = -EIO; @@ -2272,7 +2266,7 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,  	info->fix.smem_start = rambase;  	info->screen_size = ramsize;  	info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize) -					       : (caddr_t)ZTWO_VADDR(rambase); +					       : ZTWO_VADDR(rambase);  	if (!info->screen_base) {  		dev_err(info->device, "Cannot map video RAM\n");  		error = -EIO; diff --git a/drivers/video/clps711xfb.c b/drivers/video/fbdev/clps711xfb.c index f00980607b8..f00980607b8 100644 --- a/drivers/video/clps711xfb.c +++ b/drivers/video/fbdev/clps711xfb.c diff --git a/drivers/video/cobalt_lcdfb.c b/drivers/video/fbdev/cobalt_lcdfb.c index a9031498e10..d5533f4db1c 100644 --- a/drivers/video/cobalt_lcdfb.c +++ b/drivers/video/fbdev/cobalt_lcdfb.c @@ -368,8 +368,7 @@ static int cobalt_lcdfb_probe(struct platform_device *dev)  	lcd_clear(info); -	printk(KERN_INFO "fb%d: Cobalt server LCD frame buffer device\n", -		info->node); +	fb_info(info, "Cobalt server LCD frame buffer device\n");  	return 0;  } @@ -395,19 +394,7 @@ static struct platform_driver cobalt_lcdfb_driver = {  		.owner	= THIS_MODULE,  	},  }; - -static int __init cobalt_lcdfb_init(void) -{ -	return platform_driver_register(&cobalt_lcdfb_driver); -} - -static void __exit cobalt_lcdfb_exit(void) -{ -	platform_driver_unregister(&cobalt_lcdfb_driver); -} - -module_init(cobalt_lcdfb_init); -module_exit(cobalt_lcdfb_exit); +module_platform_driver(cobalt_lcdfb_driver);  MODULE_LICENSE("GPL v2");  MODULE_AUTHOR("Yoichi Yuasa"); diff --git a/drivers/video/controlfb.c b/drivers/video/fbdev/controlfb.c index 67b77b40aa7..fdadef97923 100644 --- a/drivers/video/controlfb.c +++ b/drivers/video/fbdev/controlfb.c @@ -471,8 +471,8 @@ try_again:  	/* Register with fbdev layer */  	if (register_framebuffer(&p->info) < 0)  		return -ENXIO; -	 -	printk(KERN_INFO "fb%d: control display adapter\n", p->info.node);	 + +	fb_info(&p->info, "control display adapter\n");  	return 0;  } diff --git a/drivers/video/controlfb.h b/drivers/video/fbdev/controlfb.h index 6026c60fc10..6026c60fc10 100644 --- a/drivers/video/controlfb.h +++ b/drivers/video/fbdev/controlfb.h diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile new file mode 100644 index 00000000000..fa306538dac --- /dev/null +++ b/drivers/video/fbdev/core/Makefile @@ -0,0 +1,16 @@ +obj-y                             += fb_notify.o +obj-$(CONFIG_FB)                  += fb.o +fb-y                              := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ +                                     modedb.o fbcvt.o +fb-objs                           := $(fb-y) + +obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o +obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o +obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o +obj-$(CONFIG_FB_SYS_FILLRECT)  += sysfillrect.o +obj-$(CONFIG_FB_SYS_COPYAREA)  += syscopyarea.o +obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o +obj-$(CONFIG_FB_SYS_FOPS)      += fb_sys_fops.o +obj-$(CONFIG_FB_SVGALIB)       += svgalib.o +obj-$(CONFIG_FB_DDC)           += fb_ddc.o +obj-$(CONFIG_FB_DEFERRED_IO)   += fb_defio.o diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/fbdev/core/cfbcopyarea.c index bb5a96b1645..bcb57235fcc 100644 --- a/drivers/video/cfbcopyarea.c +++ b/drivers/video/fbdev/core/cfbcopyarea.c @@ -43,13 +43,22 @@       */  static void -bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx, -		const unsigned long __iomem *src, int src_idx, int bits, +bitcpy(struct fb_info *p, unsigned long __iomem *dst, unsigned dst_idx, +		const unsigned long __iomem *src, unsigned src_idx, int bits,  		unsigned n, u32 bswapmask)  {  	unsigned long first, last;  	int const shift = dst_idx-src_idx; -	int left, right; + +#if 0 +	/* +	 * If you suspect bug in this function, compare it with this simple +	 * memmove implementation. +	 */ +	fb_memmove((char *)dst + ((dst_idx & (bits - 1))) / 8, +		   (char *)src + ((src_idx & (bits - 1))) / 8, n / 8); +	return; +#endif  	first = fb_shifted_pixels_mask_long(p, dst_idx, bswapmask);  	last = ~fb_shifted_pixels_mask_long(p, (dst_idx+n) % bits, bswapmask); @@ -98,9 +107,8 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,  		unsigned long d0, d1;  		int m; -		right = shift & (bits - 1); -		left = -shift & (bits - 1); -		bswapmask &= shift; +		int const left = shift & (bits - 1); +		int const right = -shift & (bits - 1);  		if (dst_idx+n <= bits) {  			// Single destination word @@ -110,15 +118,15 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,  			d0 = fb_rev_pixels_in_long(d0, bswapmask);  			if (shift > 0) {  				// Single source word -				d0 >>= right; +				d0 <<= left;  			} else if (src_idx+n <= bits) {  				// Single source word -				d0 <<= left; +				d0 >>= right;  			} else {  				// 2 source words  				d1 = FB_READL(src + 1);  				d1 = fb_rev_pixels_in_long(d1, bswapmask); -				d0 = d0<<left | d1>>right; +				d0 = d0 >> right | d1 << left;  			}  			d0 = fb_rev_pixels_in_long(d0, bswapmask);  			FB_WRITEL(comp(d0, FB_READL(dst), first), dst); @@ -135,60 +143,59 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,  			if (shift > 0) {  				// Single source word  				d1 = d0; -				d0 >>= right; -				dst++; +				d0 <<= left;  				n -= bits - dst_idx;  			} else {  				// 2 source words  				d1 = FB_READL(src++);  				d1 = fb_rev_pixels_in_long(d1, bswapmask); -				d0 = d0<<left | d1>>right; -				dst++; +				d0 = d0 >> right | d1 << left;  				n -= bits - dst_idx;  			}  			d0 = fb_rev_pixels_in_long(d0, bswapmask);  			FB_WRITEL(comp(d0, FB_READL(dst), first), dst);  			d0 = d1; +			dst++;  			// Main chunk  			m = n % bits;  			n /= bits;  			while ((n >= 4) && !bswapmask) {  				d1 = FB_READL(src++); -				FB_WRITEL(d0 << left | d1 >> right, dst++); +				FB_WRITEL(d0 >> right | d1 << left, dst++);  				d0 = d1;  				d1 = FB_READL(src++); -				FB_WRITEL(d0 << left | d1 >> right, dst++); +				FB_WRITEL(d0 >> right | d1 << left, dst++);  				d0 = d1;  				d1 = FB_READL(src++); -				FB_WRITEL(d0 << left | d1 >> right, dst++); +				FB_WRITEL(d0 >> right | d1 << left, dst++);  				d0 = d1;  				d1 = FB_READL(src++); -				FB_WRITEL(d0 << left | d1 >> right, dst++); +				FB_WRITEL(d0 >> right | d1 << left, dst++);  				d0 = d1;  				n -= 4;  			}  			while (n--) {  				d1 = FB_READL(src++);  				d1 = fb_rev_pixels_in_long(d1, bswapmask); -				d0 = d0 << left | d1 >> right; +				d0 = d0 >> right | d1 << left;  				d0 = fb_rev_pixels_in_long(d0, bswapmask);  				FB_WRITEL(d0, dst++);  				d0 = d1;  			}  			// Trailing bits -			if (last) { -				if (m <= right) { +			if (m) { +				if (m <= bits - right) {  					// Single source word -					d0 <<= left; +					d0 >>= right;  				} else {  					// 2 source words  					d1 = FB_READL(src);  					d1 = fb_rev_pixels_in_long(d1,  								bswapmask); -					d0 = d0<<left | d1>>right; +					d0 = d0 >> right | d1 << left;  				}  				d0 = fb_rev_pixels_in_long(d0, bswapmask);  				FB_WRITEL(comp(d0, FB_READL(dst), last), dst); @@ -202,43 +209,46 @@ bitcpy(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,       */  static void -bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx, -		const unsigned long __iomem *src, int src_idx, int bits, +bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, unsigned dst_idx, +		const unsigned long __iomem *src, unsigned src_idx, int bits,  		unsigned n, u32 bswapmask)  {  	unsigned long first, last;  	int shift; -	dst += (n-1)/bits; -	src += (n-1)/bits; -	if ((n-1) % bits) { -		dst_idx += (n-1) % bits; -		dst += dst_idx >> (ffs(bits) - 1); -		dst_idx &= bits - 1; -		src_idx += (n-1) % bits; -		src += src_idx >> (ffs(bits) - 1); -		src_idx &= bits - 1; -	} +#if 0 +	/* +	 * If you suspect bug in this function, compare it with this simple +	 * memmove implementation. +	 */ +	fb_memmove((char *)dst + ((dst_idx & (bits - 1))) / 8, +		   (char *)src + ((src_idx & (bits - 1))) / 8, n / 8); +	return; +#endif + +	dst += (dst_idx + n - 1) / bits; +	src += (src_idx + n - 1) / bits; +	dst_idx = (dst_idx + n - 1) % bits; +	src_idx = (src_idx + n - 1) % bits;  	shift = dst_idx-src_idx; -	first = fb_shifted_pixels_mask_long(p, bits - 1 - dst_idx, bswapmask); -	last = ~fb_shifted_pixels_mask_long(p, bits - 1 - ((dst_idx-n) % bits), -					    bswapmask); +	first = ~fb_shifted_pixels_mask_long(p, (dst_idx + 1) % bits, bswapmask); +	last = fb_shifted_pixels_mask_long(p, (bits + dst_idx + 1 - n) % bits, bswapmask);  	if (!shift) {  		// Same alignment for source and dest  		if ((unsigned long)dst_idx+1 >= n) {  			// Single word -			if (last) -				first &= last; -			FB_WRITEL( comp( FB_READL(src), FB_READL(dst), first), dst); +			if (first) +				last &= first; +			FB_WRITEL( comp( FB_READL(src), FB_READL(dst), last), dst);  		} else {  			// Multiple destination words  			// Leading bits -			if (first != ~0UL) { +			if (first) {  				FB_WRITEL( comp( FB_READL(src), FB_READL(dst), first), dst);  				dst--;  				src--; @@ -262,7 +272,7 @@ bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,  				FB_WRITEL(FB_READL(src--), dst--);  			// Trailing bits -			if (last) +			if (last != -1UL)  				FB_WRITEL( comp( FB_READL(src), FB_READL(dst), last), dst);  		}  	} else { @@ -270,29 +280,28 @@ bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,  		unsigned long d0, d1;  		int m; -		int const left = -shift & (bits-1); -		int const right = shift & (bits-1); -		bswapmask &= shift; +		int const left = shift & (bits-1); +		int const right = -shift & (bits-1);  		if ((unsigned long)dst_idx+1 >= n) {  			// Single destination word -			if (last) -				first &= last; +			if (first) +				last &= first;  			d0 = FB_READL(src);  			if (shift < 0) {  				// Single source word -				d0 <<= left; +				d0 >>= right;  			} else if (1+(unsigned long)src_idx >= n) {  				// Single source word -				d0 >>= right; +				d0 <<= left;  			} else {  				// 2 source words  				d1 = FB_READL(src - 1);  				d1 = fb_rev_pixels_in_long(d1, bswapmask); -				d0 = d0>>right | d1<<left; +				d0 = d0 << left | d1 >> right;  			}  			d0 = fb_rev_pixels_in_long(d0, bswapmask); -			FB_WRITEL(comp(d0, FB_READL(dst), first), dst); +			FB_WRITEL(comp(d0, FB_READL(dst), last), dst);  		} else {  			// Multiple destination words  			/** We must always remember the last value read, because in case @@ -307,12 +316,12 @@ bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,  			if (shift < 0) {  				// Single source word  				d1 = d0; -				d0 <<= left; +				d0 >>= right;  			} else {  				// 2 source words  				d1 = FB_READL(src--);  				d1 = fb_rev_pixels_in_long(d1, bswapmask); -				d0 = d0>>right | d1<<left; +				d0 = d0 << left | d1 >> right;  			}  			d0 = fb_rev_pixels_in_long(d0, bswapmask);  			FB_WRITEL(comp(d0, FB_READL(dst), first), dst); @@ -325,39 +334,39 @@ bitcpy_rev(struct fb_info *p, unsigned long __iomem *dst, int dst_idx,  			n /= bits;  			while ((n >= 4) && !bswapmask) {  				d1 = FB_READL(src--); -				FB_WRITEL(d0 >> right | d1 << left, dst--); +				FB_WRITEL(d0 << left | d1 >> right, dst--);  				d0 = d1;  				d1 = FB_READL(src--); -				FB_WRITEL(d0 >> right | d1 << left, dst--); +				FB_WRITEL(d0 << left | d1 >> right, dst--);  				d0 = d1;  				d1 = FB_READL(src--); -				FB_WRITEL(d0 >> right | d1 << left, dst--); +				FB_WRITEL(d0 << left | d1 >> right, dst--);  				d0 = d1;  				d1 = FB_READL(src--); -				FB_WRITEL(d0 >> right | d1 << left, dst--); +				FB_WRITEL(d0 << left | d1 >> right, dst--);  				d0 = d1;  				n -= 4;  			}  			while (n--) {  				d1 = FB_READL(src--);  				d1 = fb_rev_pixels_in_long(d1, bswapmask); -				d0 = d0 >> right | d1 << left; +				d0 = d0 << left | d1 >> right;  				d0 = fb_rev_pixels_in_long(d0, bswapmask);  				FB_WRITEL(d0, dst--);  				d0 = d1;  			}  			// Trailing bits -			if (last) { -				if (m <= left) { +			if (m) { +				if (m <= bits - left) {  					// Single source word -					d0 >>= right; +					d0 <<= left;  				} else {  					// 2 source words  					d1 = FB_READL(src);  					d1 = fb_rev_pixels_in_long(d1,  								bswapmask); -					d0 = d0>>right | d1<<left; +					d0 = d0 << left | d1 >> right;  				}  				d0 = fb_rev_pixels_in_long(d0, bswapmask);  				FB_WRITEL(comp(d0, FB_READL(dst), last), dst); @@ -371,9 +380,9 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)  	u32 dx = area->dx, dy = area->dy, sx = area->sx, sy = area->sy;  	u32 height = area->height, width = area->width;  	unsigned long const bits_per_line = p->fix.line_length*8u; -	unsigned long __iomem *dst = NULL, *src = NULL; +	unsigned long __iomem *base = NULL;  	int bits = BITS_PER_LONG, bytes = bits >> 3; -	int dst_idx = 0, src_idx = 0, rev_copy = 0; +	unsigned dst_idx = 0, src_idx = 0, rev_copy = 0;  	u32 bswapmask = fb_compute_bswapmask(p);  	if (p->state != FBINFO_STATE_RUNNING) @@ -389,7 +398,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)  	// split the base of the framebuffer into a long-aligned address and the  	// index of the first bit -	dst = src = (unsigned long __iomem *)((unsigned long)p->screen_base & ~(bytes-1)); +	base = (unsigned long __iomem *)((unsigned long)p->screen_base & ~(bytes-1));  	dst_idx = src_idx = 8*((unsigned long)p->screen_base & (bytes-1));  	// add offset of source and target area  	dst_idx += dy*bits_per_line + dx*p->var.bits_per_pixel; @@ -402,20 +411,14 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)  		while (height--) {  			dst_idx -= bits_per_line;  			src_idx -= bits_per_line; -			dst += dst_idx >> (ffs(bits) - 1); -			dst_idx &= (bytes - 1); -			src += src_idx >> (ffs(bits) - 1); -			src_idx &= (bytes - 1); -			bitcpy_rev(p, dst, dst_idx, src, src_idx, bits, +			bitcpy_rev(p, base + (dst_idx / bits), dst_idx % bits, +				base + (src_idx / bits), src_idx % bits, bits,  				width*p->var.bits_per_pixel, bswapmask);  		}  	} else {  		while (height--) { -			dst += dst_idx >> (ffs(bits) - 1); -			dst_idx &= (bytes - 1); -			src += src_idx >> (ffs(bits) - 1); -			src_idx &= (bytes - 1); -			bitcpy(p, dst, dst_idx, src, src_idx, bits, +			bitcpy(p, base + (dst_idx / bits), dst_idx % bits, +				base + (src_idx / bits), src_idx % bits, bits,  				width*p->var.bits_per_pixel, bswapmask);  			dst_idx += bits_per_line;  			src_idx += bits_per_line; diff --git a/drivers/video/cfbfillrect.c b/drivers/video/fbdev/core/cfbfillrect.c index ba9f58b2a5e..ba9f58b2a5e 100644 --- a/drivers/video/cfbfillrect.c +++ b/drivers/video/fbdev/core/cfbfillrect.c diff --git a/drivers/video/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c index baed57d3cff..a2bb276a8b2 100644 --- a/drivers/video/cfbimgblt.c +++ b/drivers/video/fbdev/core/cfbimgblt.c @@ -181,7 +181,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *  			}  			shift += bpp;  			shift &= (32 - 1); -			if (!l) { l = 8; s++; }; +			if (!l) { l = 8; s++; }  		}  		/* write trailing bits */ diff --git a/drivers/video/fb_ddc.c b/drivers/video/fbdev/core/fb_ddc.c index 2b106f046fd..94322ccfedd 100644 --- a/drivers/video/fb_ddc.c +++ b/drivers/video/fbdev/core/fb_ddc.c @@ -15,7 +15,7 @@  #include <linux/i2c-algo-bit.h>  #include <linux/slab.h> -#include "edid.h" +#include "../edid.h"  #define DDC_ADDR	0x50 diff --git a/drivers/video/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c index 900aa4ecd61..900aa4ecd61 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fbdev/core/fb_defio.c diff --git a/drivers/video/fb_draw.h b/drivers/video/fbdev/core/fb_draw.h index 624ee115f12..624ee115f12 100644 --- a/drivers/video/fb_draw.h +++ b/drivers/video/fbdev/core/fb_draw.h diff --git a/drivers/video/fb_notify.c b/drivers/video/fbdev/core/fb_notify.c index 74c2da52888..74c2da52888 100644 --- a/drivers/video/fb_notify.c +++ b/drivers/video/fbdev/core/fb_notify.c diff --git a/drivers/video/fb_sys_fops.c b/drivers/video/fbdev/core/fb_sys_fops.c index ff275d7f3ea..ff275d7f3ea 100644 --- a/drivers/video/fb_sys_fops.c +++ b/drivers/video/fbdev/core/fb_sys_fops.c diff --git a/drivers/video/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c index f89245b8ba8..f89245b8ba8 100644 --- a/drivers/video/fbcmap.c +++ b/drivers/video/fbdev/core/fbcmap.c diff --git a/drivers/video/fbcvt.c b/drivers/video/fbdev/core/fbcvt.c index 7cb715dfc0e..7cb715dfc0e 100644 --- a/drivers/video/fbcvt.c +++ b/drivers/video/fbdev/core/fbcvt.c diff --git a/drivers/video/fbmem.c b/drivers/video/fbdev/core/fbmem.c index dacaf74256a..b5e85f6c1c2 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -433,7 +433,7 @@ static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,  			image->dx += image->width + 8;  		}  	} else if (rotate == FB_ROTATE_UD) { -		for (x = 0; x < num && image->dx >= 0; x++) { +		for (x = 0; x < num; x++) {  			info->fbops->fb_imageblit(info, image);  			image->dx -= image->width + 8;  		} @@ -445,7 +445,7 @@ static void fb_do_show_logo(struct fb_info *info, struct fb_image *image,  			image->dy += image->height + 8;  		}  	} else if (rotate == FB_ROTATE_CCW) { -		for (x = 0; x < num && image->dy >= 0; x++) { +		for (x = 0; x < num; x++) {  			info->fbops->fb_imageblit(info, image);  			image->dy -= image->height + 8;  		} @@ -674,6 +674,7 @@ int fb_show_logo(struct fb_info *info, int rotate)  int fb_prepare_logo(struct fb_info *info, int rotate) { return 0; }  int fb_show_logo(struct fb_info *info, int rotate) { return 0; }  #endif /* CONFIG_LOGO */ +EXPORT_SYMBOL(fb_prepare_logo);  EXPORT_SYMBOL(fb_show_logo);  static void *fb_seq_start(struct seq_file *m, loff_t *pos) @@ -1108,14 +1109,16 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,  	case FBIOPUT_VSCREENINFO:  		if (copy_from_user(&var, argp, sizeof(var)))  			return -EFAULT; -		if (!lock_fb_info(info)) -			return -ENODEV;  		console_lock(); +		if (!lock_fb_info(info)) { +			console_unlock(); +			return -ENODEV; +		}  		info->flags |= FBINFO_MISC_USEREVENT;  		ret = fb_set_var(info, &var);  		info->flags &= ~FBINFO_MISC_USEREVENT; -		console_unlock();  		unlock_fb_info(info); +		console_unlock();  		if (!ret && copy_to_user(argp, &var, sizeof(var)))  			ret = -EFAULT;  		break; @@ -1144,12 +1147,14 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,  	case FBIOPAN_DISPLAY:  		if (copy_from_user(&var, argp, sizeof(var)))  			return -EFAULT; -		if (!lock_fb_info(info)) -			return -ENODEV;  		console_lock(); +		if (!lock_fb_info(info)) { +			console_unlock(); +			return -ENODEV; +		}  		ret = fb_pan_display(info, &var); -		console_unlock();  		unlock_fb_info(info); +		console_unlock();  		if (ret == 0 && copy_to_user(argp, &var, sizeof(var)))  			return -EFAULT;  		break; @@ -1175,7 +1180,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,  			return -EFAULT;  		if (con2fb.console < 1 || con2fb.console > MAX_NR_CONSOLES)  			return -EINVAL; -		if (con2fb.framebuffer < 0 || con2fb.framebuffer >= FB_MAX) +		if (con2fb.framebuffer >= FB_MAX)  			return -EINVAL;  		if (!registered_fb[con2fb.framebuffer])  			request_module("fb%d", con2fb.framebuffer); @@ -1184,23 +1189,27 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,  			break;  		}  		event.data = &con2fb; -		if (!lock_fb_info(info)) -			return -ENODEV;  		console_lock(); +		if (!lock_fb_info(info)) { +			console_unlock(); +			return -ENODEV; +		}  		event.info = info;  		ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event); -		console_unlock();  		unlock_fb_info(info); +		console_unlock();  		break;  	case FBIOBLANK: -		if (!lock_fb_info(info)) -			return -ENODEV;  		console_lock(); +		if (!lock_fb_info(info)) { +			console_unlock(); +			return -ENODEV; +		}  		info->flags |= FBINFO_MISC_USEREVENT;  		ret = fb_blank(info, arg);  		info->flags &= ~FBINFO_MISC_USEREVENT; -		console_unlock();  		unlock_fb_info(info); +		console_unlock();  		break;  	default:  		if (!lock_fb_info(info)) @@ -1569,10 +1578,10 @@ static bool fb_do_apertures_overlap(struct apertures_struct *gena,  static int do_unregister_framebuffer(struct fb_info *fb_info);  #define VGA_FB_PHYS 0xA0000 -static void do_remove_conflicting_framebuffers(struct apertures_struct *a, -				     const char *name, bool primary) +static int do_remove_conflicting_framebuffers(struct apertures_struct *a, +					      const char *name, bool primary)  { -	int i; +	int i, ret;  	/* check all firmware fbs and kick off if the base addr overlaps */  	for (i = 0 ; i < FB_MAX; i++) { @@ -1588,25 +1597,31 @@ static void do_remove_conflicting_framebuffers(struct apertures_struct *a,  			(primary && gen_aper && gen_aper->count &&  			 gen_aper->ranges[0].base == VGA_FB_PHYS)) { -			printk(KERN_INFO "fb: conflicting fb hw usage " -			       "%s vs %s - removing generic driver\n", +			printk(KERN_INFO "fb: switching to %s from %s\n",  			       name, registered_fb[i]->fix.id); -			do_unregister_framebuffer(registered_fb[i]); +			ret = do_unregister_framebuffer(registered_fb[i]); +			if (ret) +				return ret;  		}  	} + +	return 0;  }  static int do_register_framebuffer(struct fb_info *fb_info)  { -	int i; +	int i, ret;  	struct fb_event event;  	struct fb_videomode mode;  	if (fb_check_foreignness(fb_info))  		return -ENOSYS; -	do_remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id, -					 fb_is_primary_device(fb_info)); +	ret = do_remove_conflicting_framebuffers(fb_info->apertures, +						 fb_info->fix.id, +						 fb_is_primary_device(fb_info)); +	if (ret) +		return ret;  	if (num_registered_fb == FB_MAX)  		return -ENXIO; @@ -1660,12 +1675,15 @@ static int do_register_framebuffer(struct fb_info *fb_info)  	registered_fb[i] = fb_info;  	event.info = fb_info; -	if (!lock_fb_info(fb_info)) -		return -ENODEV;  	console_lock(); +	if (!lock_fb_info(fb_info)) { +		console_unlock(); +		return -ENODEV; +	} +  	fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); -	console_unlock();  	unlock_fb_info(fb_info); +	console_unlock();  	return 0;  } @@ -1678,13 +1696,16 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)  	if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)  		return -EINVAL; -	if (!lock_fb_info(fb_info)) -		return -ENODEV;  	console_lock(); +	if (!lock_fb_info(fb_info)) { +		console_unlock(); +		return -ENODEV; +	} +  	event.info = fb_info;  	ret = fb_notifier_call_chain(FB_EVENT_FB_UNBIND, &event); -	console_unlock();  	unlock_fb_info(fb_info); +	console_unlock();  	if (ret)  		return -EINVAL; @@ -1725,12 +1746,16 @@ int unlink_framebuffer(struct fb_info *fb_info)  }  EXPORT_SYMBOL(unlink_framebuffer); -void remove_conflicting_framebuffers(struct apertures_struct *a, -				     const char *name, bool primary) +int remove_conflicting_framebuffers(struct apertures_struct *a, +				    const char *name, bool primary)  { +	int ret; +  	mutex_lock(®istration_lock); -	do_remove_conflicting_framebuffers(a, name, primary); +	ret = do_remove_conflicting_framebuffers(a, name, primary);  	mutex_unlock(®istration_lock); + +	return ret;  }  EXPORT_SYMBOL(remove_conflicting_framebuffers); @@ -1916,6 +1941,9 @@ int fb_get_options(const char *name, char **option)  				options = opt + name_len + 1;  		}  	} +	/* No match, pass global option */ +	if (!options && option && fb_mode_option) +		options = kstrdup(fb_mode_option, GFP_KERNEL);  	if (options && !strncmp(options, "off", 3))  		retval = 1; diff --git a/drivers/video/fbmon.c b/drivers/video/fbdev/core/fbmon.c index 6103fa6fb54..5b0e313849b 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbdev/core/fbmon.c @@ -37,7 +37,7 @@  #include <asm/prom.h>  #include <asm/pci-bridge.h>  #endif -#include "edid.h" +#include "../edid.h"  /*   * EDID parser @@ -1012,13 +1012,20 @@ void fb_edid_add_monspecs(unsigned char *edid, struct fb_monspecs *specs)  	while (pos < edid[2]) {  		u8 len = edid[pos] & 0x1f, type = (edid[pos] >> 5) & 7;  		pr_debug("Data block %u of %u bytes\n", type, len); -		if (type == 2) +		if (type == 2) {  			for (i = pos; i < pos + len; i++) {  				u8 idx = edid[pos + i] & 0x7f;  				svd[svd_n++] = idx;  				pr_debug("N%sative mode #%d\n",  					 edid[pos + i] & 0x80 ? "" : "on-n", idx);  			} +		} else if (type == 3 && len >= 3) { +			/* Check Vendor Specific Data Block.  For HDMI, +			   it is always 00-0C-03 for HDMI Licensing, LLC. */ +			if (edid[pos + 1] == 3 && edid[pos + 2] == 0xc && +			    edid[pos + 3] == 0) +				specs->misc |= FB_MISC_HDMI; +		}  		pos += len + 1;  	} diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c index ef476b02fbe..53444ac19fe 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbdev/core/fbsysfs.c @@ -177,9 +177,12 @@ static ssize_t store_modes(struct device *device,  	if (i * sizeof(struct fb_videomode) != count)  		return -EINVAL; -	if (!lock_fb_info(fb_info)) -		return -ENODEV;  	console_lock(); +	if (!lock_fb_info(fb_info)) { +		console_unlock(); +		return -ENODEV; +	} +  	list_splice(&fb_info->modelist, &old_list);  	fb_videomode_to_modelist((const struct fb_videomode *)buf, i,  				 &fb_info->modelist); @@ -189,8 +192,8 @@ static ssize_t store_modes(struct device *device,  	} else  		fb_destroy_modelist(&old_list); -	console_unlock();  	unlock_fb_info(fb_info); +	console_unlock();  	return 0;  } @@ -404,12 +407,16 @@ static ssize_t store_fbstate(struct device *device,  	state = simple_strtoul(buf, &last, 0); -	if (!lock_fb_info(fb_info)) -		return -ENODEV;  	console_lock(); +	if (!lock_fb_info(fb_info)) { +		console_unlock(); +		return -ENODEV; +	} +  	fb_set_suspend(fb_info, (int)state); -	console_unlock(); +  	unlock_fb_info(fb_info); +	console_unlock();  	return count;  } diff --git a/drivers/video/modedb.c b/drivers/video/fbdev/core/modedb.c index a9a907c440d..a9a907c440d 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/fbdev/core/modedb.c diff --git a/drivers/video/svgalib.c b/drivers/video/fbdev/core/svgalib.c index 33df9ec9179..9e01322fabe 100644 --- a/drivers/video/svgalib.c +++ b/drivers/video/fbdev/core/svgalib.c @@ -198,8 +198,8 @@ void svga_settile(struct fb_info *info, struct fb_tilemap *map)  	if ((map->width != 8) || (map->height != 16) ||  	    (map->depth != 1) || (map->length != 256)) { -	    	printk(KERN_ERR "fb%d: unsupported font parameters: width %d, height %d, depth %d, length %d\n", -			info->node, map->width, map->height, map->depth, map->length); +		fb_err(info, "unsupported font parameters: width %d, height %d, depth %d, length %d\n", +		       map->width, map->height, map->depth, map->length);  		return;  	} diff --git a/drivers/video/syscopyarea.c b/drivers/video/fbdev/core/syscopyarea.c index 844a32fd38e..844a32fd38e 100644 --- a/drivers/video/syscopyarea.c +++ b/drivers/video/fbdev/core/syscopyarea.c diff --git a/drivers/video/sysfillrect.c b/drivers/video/fbdev/core/sysfillrect.c index 33ee3d34f9d..33ee3d34f9d 100644 --- a/drivers/video/sysfillrect.c +++ b/drivers/video/fbdev/core/sysfillrect.c diff --git a/drivers/video/sysimgblt.c b/drivers/video/fbdev/core/sysimgblt.c index 186c6f607be..a4d05b1b17d 100644 --- a/drivers/video/sysimgblt.c +++ b/drivers/video/fbdev/core/sysimgblt.c @@ -152,7 +152,7 @@ static void slow_imageblit(const struct fb_image *image, struct fb_info *p,  			}  			shift += bpp;  			shift &= (32 - 1); -			if (!l) { l = 8; s++; }; +			if (!l) { l = 8; s++; }  		}  		/* write trailing bits */ diff --git a/drivers/video/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c index 57886787ead..b0a950f3697 100644 --- a/drivers/video/cyber2000fb.c +++ b/drivers/video/fbdev/cyber2000fb.c @@ -1641,67 +1641,6 @@ static void cyberpro_common_resume(struct cfb_info *cfb)  	cyber2000fb_set_par(&cfb->fb);  } -#ifdef CONFIG_ARCH_SHARK - -#include <mach/framebuffer.h> - -static int cyberpro_vl_probe(void) -{ -	struct cfb_info *cfb; -	int err = -ENOMEM; - -	if (!request_mem_region(FB_START, FB_SIZE, "CyberPro2010")) -		return err; - -	cfb = cyberpro_alloc_fb_info(ID_CYBERPRO_2010, "CyberPro2010"); -	if (!cfb) -		goto failed_release; - -	cfb->irq = -1; -	cfb->region = ioremap(FB_START, FB_SIZE); -	if (!cfb->region) -		goto failed_ioremap; - -	cfb->regs = cfb->region + MMIO_OFFSET; -	cfb->fb.device = NULL; -	cfb->fb.fix.mmio_start = FB_START + MMIO_OFFSET; -	cfb->fb.fix.smem_start = FB_START; - -	/* -	 * Bring up the hardware.  This is expected to enable access -	 * to the linear memory region, and allow access to the memory -	 * mapped registers.  Also, mem_ctl1 and mem_ctl2 must be -	 * initialised. -	 */ -	cyber2000fb_writeb(0x18, 0x46e8, cfb); -	cyber2000fb_writeb(0x01, 0x102, cfb); -	cyber2000fb_writeb(0x08, 0x46e8, cfb); -	cyber2000fb_writeb(EXT_BIU_MISC, 0x3ce, cfb); -	cyber2000fb_writeb(EXT_BIU_MISC_LIN_ENABLE, 0x3cf, cfb); - -	cfb->mclk_mult = 0xdb; -	cfb->mclk_div  = 0x54; - -	err = cyberpro_common_probe(cfb); -	if (err) -		goto failed; - -	if (int_cfb_info == NULL) -		int_cfb_info = cfb; - -	return 0; - -failed: -	iounmap(cfb->region); -failed_ioremap: -	cyberpro_free_fb_info(cfb); -failed_release: -	release_mem_region(FB_START, FB_SIZE); - -	return err; -} -#endif /* CONFIG_ARCH_SHARK */ -  /*   * PCI specific support.   */ @@ -1871,11 +1810,6 @@ static void cyberpro_pci_remove(struct pci_dev *dev)  		iounmap(cfb->region);  		cyberpro_free_fb_info(cfb); -		/* -		 * Ensure that the driver data is no longer -		 * valid. -		 */ -		pci_set_drvdata(dev, NULL);  		if (cfb == int_cfb_info)  			int_cfb_info = NULL; @@ -1948,28 +1882,19 @@ static int __init cyber2000fb_init(void)  	cyber2000fb_setup(option);  #endif -#ifdef CONFIG_ARCH_SHARK -	err = cyberpro_vl_probe(); -	if (!err) -		ret = 0; -#endif -#ifdef CONFIG_PCI  	err = pci_register_driver(&cyberpro_driver);  	if (!err)  		ret = 0; -#endif  	return ret ? err : 0;  }  module_init(cyber2000fb_init); -#ifndef CONFIG_ARCH_SHARK  static void __exit cyberpro_exit(void)  {  	pci_unregister_driver(&cyberpro_driver);  }  module_exit(cyberpro_exit); -#endif  MODULE_AUTHOR("Russell King");  MODULE_DESCRIPTION("CyberPro 2000, 2010 and 5000 framebuffer driver"); diff --git a/drivers/video/cyber2000fb.h b/drivers/video/fbdev/cyber2000fb.h index bad69102e77..bad69102e77 100644 --- a/drivers/video/cyber2000fb.h +++ b/drivers/video/fbdev/cyber2000fb.h diff --git a/drivers/video/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c index e030e17a83f..a8484f768d0 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/fbdev/da8xx-fb.c @@ -129,7 +129,6 @@  #define LCD_NUM_BUFFERS	2 -#define WSI_TIMEOUT	50  #define PALETTE_SIZE	256  #define	CLK_MIN_DIV	2 @@ -243,6 +242,20 @@ static struct fb_videomode known_lcd_panels[] = {  		.sync           = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,  		.flag           = 0,  	}, +	[3] = { +		/* Densitron 84-0023-001T */ +		.name           = "Densitron_84-0023-001T", +		.xres           = 320, +		.yres           = 240, +		.pixclock       = KHZ2PICOS(6400), +		.left_margin    = 0, +		.right_margin   = 0, +		.upper_margin   = 0, +		.lower_margin   = 0, +		.hsync_len      = 30, +		.vsync_len      = 3, +		.sync           = 0, +	},  };  static bool da8xx_fb_is_raster_enabled(void) @@ -664,15 +677,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,  			(green << info->var.green.offset) |  			(blue << info->var.blue.offset); -		switch (info->var.bits_per_pixel) { -		case 16: -			((u16 *) (info->pseudo_palette))[regno] = v; -			break; -		case 24: -		case 32: -			((u32 *) (info->pseudo_palette))[regno] = v; -			break; -		} +		((u32 *) (info->pseudo_palette))[regno] = v;  		if (palette[0] != 0x4000) {  			update_hw = 1;  			palette[0] = 0x4000; @@ -1314,7 +1319,7 @@ static struct fb_ops da8xx_fb_ops = {  static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)  { -	struct da8xx_lcdc_platform_data *fb_pdata = dev->dev.platform_data; +	struct da8xx_lcdc_platform_data *fb_pdata = dev_get_platdata(&dev->dev);  	struct fb_videomode *lcdc_info;  	int i; @@ -1336,7 +1341,7 @@ static struct fb_videomode *da8xx_fb_get_videomode(struct platform_device *dev)  static int fb_probe(struct platform_device *device)  {  	struct da8xx_lcdc_platform_data *fb_pdata = -						device->dev.platform_data; +						dev_get_platdata(&device->dev);  	static struct resource *lcdc_regs;  	struct lcd_ctrl_config *lcd_cfg;  	struct fb_videomode *lcdc_info; @@ -1547,8 +1552,8 @@ err_pm_runtime_disable:  	return ret;  } -#ifdef CONFIG_PM -struct lcdc_context { +#ifdef CONFIG_PM_SLEEP +static struct lcdc_context {  	u32 clk_enable;  	u32 ctrl;  	u32 dma_ctrl; @@ -1611,9 +1616,9 @@ static void lcd_context_restore(void)  	return;  } -static int fb_suspend(struct platform_device *dev, pm_message_t state) +static int fb_suspend(struct device *dev)  { -	struct fb_info *info = platform_get_drvdata(dev); +	struct fb_info *info = dev_get_drvdata(dev);  	struct da8xx_fb_par *par = info->par;  	console_lock(); @@ -1623,18 +1628,18 @@ static int fb_suspend(struct platform_device *dev, pm_message_t state)  	fb_set_suspend(info, 1);  	lcd_disable_raster(DA8XX_FRAME_WAIT);  	lcd_context_save(); -	pm_runtime_put_sync(&dev->dev); +	pm_runtime_put_sync(dev);  	console_unlock();  	return 0;  } -static int fb_resume(struct platform_device *dev) +static int fb_resume(struct device *dev)  { -	struct fb_info *info = platform_get_drvdata(dev); +	struct fb_info *info = dev_get_drvdata(dev);  	struct da8xx_fb_par *par = info->par;  	console_lock(); -	pm_runtime_get_sync(&dev->dev); +	pm_runtime_get_sync(dev);  	lcd_context_restore();  	if (par->blank == FB_BLANK_UNBLANK) {  		lcd_enable_raster(); @@ -1648,34 +1653,20 @@ static int fb_resume(struct platform_device *dev)  	return 0;  } -#else -#define fb_suspend NULL -#define fb_resume NULL  #endif +static SIMPLE_DEV_PM_OPS(fb_pm_ops, fb_suspend, fb_resume); +  static struct platform_driver da8xx_fb_driver = {  	.probe = fb_probe,  	.remove = fb_remove, -	.suspend = fb_suspend, -	.resume = fb_resume,  	.driver = {  		   .name = DRIVER_NAME,  		   .owner = THIS_MODULE, +		   .pm	= &fb_pm_ops,  		   },  }; - -static int __init da8xx_fb_init(void) -{ -	return platform_driver_register(&da8xx_fb_driver); -} - -static void __exit da8xx_fb_cleanup(void) -{ -	platform_driver_unregister(&da8xx_fb_driver); -} - -module_init(da8xx_fb_init); -module_exit(da8xx_fb_cleanup); +module_platform_driver(da8xx_fb_driver);  MODULE_DESCRIPTION("Framebuffer driver for TI da8xx/omap-l1xx");  MODULE_AUTHOR("Texas Instruments"); diff --git a/drivers/video/dnfb.c b/drivers/video/fbdev/dnfb.c index 3526899da61..3526899da61 100644 --- a/drivers/video/dnfb.c +++ b/drivers/video/fbdev/dnfb.c diff --git a/drivers/video/edid.h b/drivers/video/fbdev/edid.h index d03a232d90b..d03a232d90b 100644 --- a/drivers/video/edid.h +++ b/drivers/video/fbdev/edid.h diff --git a/drivers/video/efifb.c b/drivers/video/fbdev/efifb.c index 7f9ff75d0db..ae9618ff673 100644 --- a/drivers/video/efifb.c +++ b/drivers/video/fbdev/efifb.c @@ -73,7 +73,6 @@ static void efifb_destroy(struct fb_info *info)  		release_mem_region(info->apertures->ranges[0].base,  				   info->apertures->ranges[0].size);  	fb_dealloc_cmap(&info->cmap); -	framebuffer_release(info);  }  static struct fb_ops efifb_ops = { @@ -108,8 +107,8 @@ static int efifb_setup(char *options)  			if (!*this_opt) continue;  			for (i = 0; i < M_UNKNOWN; i++) { -				if (!strcmp(this_opt, efifb_dmi_list[i].optname) && -				    efifb_dmi_list[i].base != 0) { +				if (efifb_dmi_list[i].base != 0 && +				    !strcmp(this_opt, efifb_dmi_list[i].optname)) {  					screen_info.lfb_base = efifb_dmi_list[i].base;  					screen_info.lfb_linelength = efifb_dmi_list[i].stride;  					screen_info.lfb_width = efifb_dmi_list[i].width; @@ -244,6 +243,7 @@ static int efifb_probe(struct platform_device *dev)  		err = -ENOMEM;  		goto err_release_mem;  	} +	platform_set_drvdata(dev, info);  	info->pseudo_palette = info->par;  	info->par = NULL; @@ -322,8 +322,7 @@ static int efifb_probe(struct platform_device *dev)  		printk(KERN_ERR "efifb: cannot register framebuffer\n");  		goto err_fb_dealoc;  	} -	printk(KERN_INFO "fb%d: %s frame buffer device\n", -		info->node, info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	return 0;  err_fb_dealoc: @@ -338,12 +337,23 @@ err_release_mem:  	return err;  } +static int efifb_remove(struct platform_device *pdev) +{ +	struct fb_info *info = platform_get_drvdata(pdev); + +	unregister_framebuffer(info); +	framebuffer_release(info); + +	return 0; +} +  static struct platform_driver efifb_driver = {  	.driver = {  		.name = "efi-framebuffer",  		.owner = THIS_MODULE,  	},  	.probe = efifb_probe, +	.remove = efifb_remove,  };  module_platform_driver(efifb_driver); diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c index 28a837dfddd..35a0f533f1a 100644 --- a/drivers/video/ep93xx-fb.c +++ b/drivers/video/fbdev/ep93xx-fb.c @@ -487,7 +487,7 @@ static void ep93xxfb_dealloc_videomem(struct fb_info *info)  static int ep93xxfb_probe(struct platform_device *pdev)  { -	struct ep93xxfb_mach_info *mach_info = pdev->dev.platform_data; +	struct ep93xxfb_mach_info *mach_info = dev_get_platdata(&pdev->dev);  	struct fb_info *info;  	struct ep93xx_fbi *fbi;  	struct resource *res; diff --git a/drivers/video/exynos/Kconfig b/drivers/video/fbdev/exynos/Kconfig index 1b035b2eb6b..1f16b4678c7 100644 --- a/drivers/video/exynos/Kconfig +++ b/drivers/video/fbdev/exynos/Kconfig @@ -4,6 +4,7 @@  menuconfig EXYNOS_VIDEO  	bool "Exynos Video driver support" +	depends on ARCH_S5PV210 || ARCH_EXYNOS  	help  	  This enables support for EXYNOS Video device. @@ -15,23 +16,17 @@ if EXYNOS_VIDEO  config EXYNOS_MIPI_DSI  	bool "EXYNOS MIPI DSI driver support." -	depends on ARCH_S5PV210 || ARCH_EXYNOS +	select GENERIC_PHY  	help  	  This enables support for MIPI-DSI device.  config EXYNOS_LCD_S6E8AX0  	bool "S6E8AX0 MIPI AMOLED LCD Driver" -	depends on (EXYNOS_MIPI_DSI && BACKLIGHT_CLASS_DEVICE && LCD_CLASS_DEVICE) +	depends on EXYNOS_MIPI_DSI && BACKLIGHT_CLASS_DEVICE +	depends on (LCD_CLASS_DEVICE = y)  	default n  	help  	  If you have an S6E8AX0 MIPI AMOLED LCD Panel, say Y to enable its  	  LCD control driver. -config EXYNOS_DP -	bool "EXYNOS DP driver support" -	depends on ARCH_EXYNOS -	default n -	help -	  This enables support for DP device. -  endif # EXYNOS_VIDEO diff --git a/drivers/video/exynos/Makefile b/drivers/video/fbdev/exynos/Makefile index ec7772e452a..b5b1bd228ab 100644 --- a/drivers/video/exynos/Makefile +++ b/drivers/video/fbdev/exynos/Makefile @@ -5,4 +5,3 @@  obj-$(CONFIG_EXYNOS_MIPI_DSI)		+= exynos_mipi_dsi.o exynos_mipi_dsi_common.o \  				     	exynos_mipi_dsi_lowlevel.o  obj-$(CONFIG_EXYNOS_LCD_S6E8AX0)	+= s6e8ax0.o -obj-$(CONFIG_EXYNOS_DP)			+= exynos_dp_core.o exynos_dp_reg.o diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c index 32e540600f9..cee9602f9a7 100644 --- a/drivers/video/exynos/exynos_mipi_dsi.c +++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c @@ -30,6 +30,7 @@  #include <linux/interrupt.h>  #include <linux/kthread.h>  #include <linux/notifier.h> +#include <linux/phy/phy.h>  #include <linux/regulator/consumer.h>  #include <linux/pm_runtime.h>  #include <linux/err.h> @@ -140,7 +141,6 @@ static int exynos_mipi_dsi_early_blank_mode(struct mipi_dsim_device *dsim,  static int exynos_mipi_dsi_blank_mode(struct mipi_dsim_device *dsim, int power)  { -	struct platform_device *pdev = to_platform_device(dsim->dev);  	struct mipi_dsim_lcd_driver *client_drv = dsim->dsim_lcd_drv;  	struct mipi_dsim_lcd_device *client_dev = dsim->dsim_lcd_dev; @@ -156,8 +156,7 @@ static int exynos_mipi_dsi_blank_mode(struct mipi_dsim_device *dsim, int power)  		exynos_mipi_regulator_enable(dsim);  		/* enable MIPI-DSI PHY. */ -		if (dsim->pd->phy_enable) -			dsim->pd->phy_enable(pdev, true); +		phy_power_on(dsim->phy);  		clk_enable(dsim->clock); @@ -373,6 +372,10 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)  		return ret;  	} +	dsim->phy = devm_phy_get(&pdev->dev, "dsim"); +	if (IS_ERR(dsim->phy)) +		return PTR_ERR(dsim->phy); +  	dsim->clock = devm_clk_get(&pdev->dev, "dsim0");  	if (IS_ERR(dsim->clock)) {  		dev_err(&pdev->dev, "failed to get dsim clock source\n"); @@ -439,8 +442,7 @@ static int exynos_mipi_dsi_probe(struct platform_device *pdev)  	exynos_mipi_regulator_enable(dsim);  	/* enable MIPI-DSI PHY. */ -	if (dsim->pd->phy_enable) -		dsim->pd->phy_enable(pdev, true); +	phy_power_on(dsim->phy);  	exynos_mipi_update_cfg(dsim); @@ -504,9 +506,8 @@ static int exynos_mipi_dsi_suspend(struct device *dev)  	if (client_drv && client_drv->suspend)  		client_drv->suspend(client_dev); -	/* enable MIPI-DSI PHY. */ -	if (dsim->pd->phy_enable) -		dsim->pd->phy_enable(pdev, false); +	/* disable MIPI-DSI PHY. */ +	phy_power_off(dsim->phy);  	clk_disable(dsim->clock); @@ -536,8 +537,7 @@ static int exynos_mipi_dsi_resume(struct device *dev)  	exynos_mipi_regulator_enable(dsim);  	/* enable MIPI-DSI PHY. */ -	if (dsim->pd->phy_enable) -		dsim->pd->phy_enable(pdev, true); +	phy_power_on(dsim->phy);  	clk_enable(dsim->clock); diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c index 520fc9bd887..85edabfdef5 100644 --- a/drivers/video/exynos/exynos_mipi_dsi_common.c +++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c @@ -220,7 +220,7 @@ int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,  	case MIPI_DSI_DCS_LONG_WRITE:  	{  		unsigned int size, payload = 0; -		INIT_COMPLETION(dsim_wr_comp); +		reinit_completion(&dsim_wr_comp);  		size = data_size * 4; @@ -356,7 +356,7 @@ int exynos_mipi_dsi_rd_data(struct mipi_dsim_device *dsim, unsigned int data_id,  	msleep(20);  	mutex_lock(&dsim->lock); -	INIT_COMPLETION(dsim_rd_comp); +	reinit_completion(&dsim_rd_comp);  	exynos_mipi_dsi_rd_tx_header(dsim,  		MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, req_size); @@ -376,6 +376,7 @@ int exynos_mipi_dsi_rd_data(struct mipi_dsim_device *dsim, unsigned int data_id,  			"data id %x is not supported current DSI spec.\n",  			data_id); +		mutex_unlock(&dsim->lock);  		return -EINVAL;  	} @@ -667,7 +668,7 @@ int exynos_mipi_dsi_init_dsim(struct mipi_dsim_device *dsim)  	default:  		dev_info(dsim->dev, "data lane is invalid.\n");  		return -EINVAL; -	}; +	}  	exynos_mipi_dsi_sw_reset(dsim);  	exynos_mipi_dsi_func_reset(dsim); diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h index 412552274df..412552274df 100644 --- a/drivers/video/exynos/exynos_mipi_dsi_common.h +++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.c index c148d06540c..c148d06540c 100644 --- a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c +++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.c diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.h index 85460701c7e..85460701c7e 100644 --- a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h +++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.h diff --git a/drivers/video/exynos/exynos_mipi_dsi_regs.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_regs.h index 4227106d3fd..4227106d3fd 100644 --- a/drivers/video/exynos/exynos_mipi_dsi_regs.h +++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi_regs.h diff --git a/drivers/video/exynos/s6e8ax0.c b/drivers/video/fbdev/exynos/s6e8ax0.c index ca2602413aa..29e70ed3f15 100644 --- a/drivers/video/exynos/s6e8ax0.c +++ b/drivers/video/fbdev/exynos/s6e8ax0.c @@ -794,19 +794,18 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)  		return ret;  	} -	lcd->ld = lcd_device_register("s6e8ax0", lcd->dev, lcd, +	lcd->ld = devm_lcd_device_register(lcd->dev, "s6e8ax0", lcd->dev, lcd,  			&s6e8ax0_lcd_ops);  	if (IS_ERR(lcd->ld)) {  		dev_err(lcd->dev, "failed to register lcd ops.\n");  		return PTR_ERR(lcd->ld);  	} -	lcd->bd = backlight_device_register("s6e8ax0-bl", lcd->dev, lcd, -			&s6e8ax0_backlight_ops, NULL); +	lcd->bd = devm_backlight_device_register(lcd->dev, "s6e8ax0-bl", +				lcd->dev, lcd, &s6e8ax0_backlight_ops, NULL);  	if (IS_ERR(lcd->bd)) {  		dev_err(lcd->dev, "failed to register backlight ops.\n"); -		ret = PTR_ERR(lcd->bd); -		goto err_backlight_register; +		return PTR_ERR(lcd->bd);  	}  	lcd->bd->props.max_brightness = MAX_BRIGHTNESS; @@ -834,10 +833,6 @@ static int s6e8ax0_probe(struct mipi_dsim_lcd_device *dsim_dev)  	dev_dbg(lcd->dev, "probed s6e8ax0 panel driver.\n");  	return 0; - -err_backlight_register: -	lcd_device_unregister(lcd->ld); -	return ret;  }  #ifdef CONFIG_PM diff --git a/drivers/video/fb-puv3.c b/drivers/video/fbdev/fb-puv3.c index 27fc956166f..88fa2e70a0b 100644 --- a/drivers/video/fb-puv3.c +++ b/drivers/video/fbdev/fb-puv3.c @@ -18,8 +18,10 @@  #include <linux/fb.h>  #include <linux/init.h>  #include <linux/console.h> +#include <linux/mm.h>  #include <asm/sizes.h> +#include <asm/pgtable.h>  #include <mach/hardware.h>  /* Platform_data reserved for unifb registers. */ @@ -713,9 +715,8 @@ static int unifb_probe(struct platform_device *dev)  	platform_set_drvdata(dev, info);  	platform_device_add_data(dev, unifb_regs, sizeof(u32) * UNIFB_REGS_NUM); -	printk(KERN_INFO -	       "fb%d: Virtual frame buffer device, using %dM of video memory\n", -	       info->node, UNIFB_MEMSIZE >> 20); +	fb_info(info, "Virtual frame buffer device, using %dM of video memory\n", +		UNIFB_MEMSIZE >> 20);  	return 0;  err2:  	fb_dealloc_cmap(&info->cmap); diff --git a/drivers/video/ffb.c b/drivers/video/fbdev/ffb.c index 6d2744794dd..4c4ffa61ae2 100644 --- a/drivers/video/ffb.c +++ b/drivers/video/fbdev/ffb.c @@ -1035,8 +1035,6 @@ static int ffb_remove(struct platform_device *op)  	framebuffer_release(info); -	dev_set_drvdata(&op->dev, NULL); -  	return 0;  } diff --git a/drivers/video/fm2fb.c b/drivers/video/fbdev/fm2fb.c index c99c9671302..e69d47af993 100644 --- a/drivers/video/fm2fb.c +++ b/drivers/video/fbdev/fm2fb.c @@ -289,7 +289,7 @@ static int fm2fb_probe(struct zorro_dev *z, const struct zorro_device_id *id)  		zorro_release_device(z);  		return -EINVAL;  	} -	printk("fb%d: %s frame buffer device\n", info->node, fb_fix.id); +	fb_info(info, "%s frame buffer device\n", fb_fix.id);  	return 0;  } diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fbdev/fsl-diu-fb.c index 6dd72250111..e8758b9c3bc 100644 --- a/drivers/video/fsl-diu-fb.c +++ b/drivers/video/fbdev/fsl-diu-fb.c @@ -31,6 +31,8 @@  #include <linux/uaccess.h>  #include <linux/vmalloc.h>  #include <linux/spinlock.h> +#include <linux/of_address.h> +#include <linux/of_irq.h>  #include <sysdev/fsl_soc.h>  #include <linux/fsl-diu-fb.h> @@ -1102,7 +1104,7 @@ static int fsl_diu_cursor(struct fb_info *info, struct fb_cursor *cursor)  		fsl_diu_load_cursor_image(info, image, bg, fg,  			cursor->image.width, cursor->image.height); -	}; +	}  	/*  	 * Show or hide the cursor.  The cursor data is always stored in the diff --git a/drivers/video/g364fb.c b/drivers/video/fbdev/g364fb.c index 223896cc5f7..223896cc5f7 100644 --- a/drivers/video/g364fb.c +++ b/drivers/video/fbdev/g364fb.c diff --git a/drivers/video/gbefb.c b/drivers/video/fbdev/gbefb.c index ceab37020ff..4aa56ba78f3 100644 --- a/drivers/video/gbefb.c +++ b/drivers/video/fbdev/gbefb.c @@ -45,10 +45,6 @@ struct gbefb_par {  #define GBE_BASE	0x16000000 /* SGI O2 */  #endif -#ifdef CONFIG_X86_VISWS -#define GBE_BASE	0xd0000000 /* SGI Visual Workstation */ -#endif -  /* macro for fastest write-though access to the framebuffer */  #ifdef CONFIG_MIPS  #ifdef CONFIG_CPU_R10000 @@ -1072,7 +1068,7 @@ static struct fb_ops gbefb_ops = {  static ssize_t gbefb_show_memsize(struct device *dev, struct device_attribute *attr, char *buf)  { -	return snprintf(buf, PAGE_SIZE, "%d\n", gbe_mem_size); +	return snprintf(buf, PAGE_SIZE, "%u\n", gbe_mem_size);  }  static DEVICE_ATTR(size, S_IRUGO, gbefb_show_memsize, NULL); @@ -1236,9 +1232,9 @@ static int gbefb_probe(struct platform_device *p_dev)  	platform_set_drvdata(p_dev, info);  	gbefb_create_sysfs(&p_dev->dev); -	printk(KERN_INFO "fb%d: %s rev %d @ 0x%08x using %dkB memory\n", -	       info->node, info->fix.id, gbe_revision, (unsigned) GBE_BASE, -	       gbe_mem_size >> 10); +	fb_info(info, "%s rev %d @ 0x%08x using %dkB memory\n", +		info->fix.id, gbe_revision, (unsigned)GBE_BASE, +		gbe_mem_size >> 10);  	return 0; diff --git a/drivers/video/geode/Kconfig b/drivers/video/fbdev/geode/Kconfig index 1e855528478..1e855528478 100644 --- a/drivers/video/geode/Kconfig +++ b/drivers/video/fbdev/geode/Kconfig diff --git a/drivers/video/geode/Makefile b/drivers/video/fbdev/geode/Makefile index 5c98da12688..5c98da12688 100644 --- a/drivers/video/geode/Makefile +++ b/drivers/video/fbdev/geode/Makefile diff --git a/drivers/video/geode/display_gx.c b/drivers/video/fbdev/geode/display_gx.c index f0af911a096..f0af911a096 100644 --- a/drivers/video/geode/display_gx.c +++ b/drivers/video/fbdev/geode/display_gx.c diff --git a/drivers/video/geode/display_gx1.c b/drivers/video/fbdev/geode/display_gx1.c index 926d53eeb54..926d53eeb54 100644 --- a/drivers/video/geode/display_gx1.c +++ b/drivers/video/fbdev/geode/display_gx1.c diff --git a/drivers/video/geode/display_gx1.h b/drivers/video/fbdev/geode/display_gx1.h index 671c05558c7..671c05558c7 100644 --- a/drivers/video/geode/display_gx1.h +++ b/drivers/video/fbdev/geode/display_gx1.h diff --git a/drivers/video/geode/geodefb.h b/drivers/video/fbdev/geode/geodefb.h index ae04820e0c5..ae04820e0c5 100644 --- a/drivers/video/geode/geodefb.h +++ b/drivers/video/fbdev/geode/geodefb.h diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/fbdev/geode/gx1fb_core.c index ebbaada7b94..2794ba11f33 100644 --- a/drivers/video/geode/gx1fb_core.c +++ b/drivers/video/fbdev/geode/gx1fb_core.c @@ -357,7 +357,7 @@ static int gx1fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)  		goto err;  	}  	pci_set_drvdata(pdev, info); -	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	return 0;    err: @@ -399,7 +399,6 @@ static void gx1fb_remove(struct pci_dev *pdev)  	release_mem_region(gx1_gx_base() + 0x8300, 0x100);  	fb_dealloc_cmap(&info->cmap); -	pci_set_drvdata(pdev, NULL);  	framebuffer_release(info);  } diff --git a/drivers/video/geode/gxfb.h b/drivers/video/fbdev/geode/gxfb.h index d19e9378b0c..d19e9378b0c 100644 --- a/drivers/video/geode/gxfb.h +++ b/drivers/video/fbdev/geode/gxfb.h diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/fbdev/geode/gxfb_core.c index 19f0c1add74..1790f14bab1 100644 --- a/drivers/video/geode/gxfb_core.c +++ b/drivers/video/fbdev/geode/gxfb_core.c @@ -423,7 +423,7 @@ static int gxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)  		goto err;  	}  	pci_set_drvdata(pdev, info); -	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	return 0;    err: @@ -471,7 +471,6 @@ static void gxfb_remove(struct pci_dev *pdev)  	pci_release_region(pdev, 1);  	fb_dealloc_cmap(&info->cmap); -	pci_set_drvdata(pdev, NULL);  	framebuffer_release(info);  } diff --git a/drivers/video/geode/lxfb.h b/drivers/video/fbdev/geode/lxfb.h index cfcd8090f31..cfcd8090f31 100644 --- a/drivers/video/geode/lxfb.h +++ b/drivers/video/fbdev/geode/lxfb.h diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/fbdev/geode/lxfb_core.c index 4dd7b556696..9e1d19d673a 100644 --- a/drivers/video/geode/lxfb_core.c +++ b/drivers/video/fbdev/geode/lxfb_core.c @@ -555,8 +555,7 @@ static int lxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)  		goto err;  	}  	pci_set_drvdata(pdev, info); -	printk(KERN_INFO "fb%d: %s frame buffer device\n", -		info->node, info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	return 0; @@ -606,7 +605,6 @@ static void lxfb_remove(struct pci_dev *pdev)  	pci_release_region(pdev, 3);  	fb_dealloc_cmap(&info->cmap); -	pci_set_drvdata(pdev, NULL);  	framebuffer_release(info);  } diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/fbdev/geode/lxfb_ops.c index 79e9abc72b8..79e9abc72b8 100644 --- a/drivers/video/geode/lxfb_ops.c +++ b/drivers/video/fbdev/geode/lxfb_ops.c diff --git a/drivers/video/geode/suspend_gx.c b/drivers/video/fbdev/geode/suspend_gx.c index 1bb043d70c6..1bb043d70c6 100644 --- a/drivers/video/geode/suspend_gx.c +++ b/drivers/video/fbdev/geode/suspend_gx.c diff --git a/drivers/video/geode/video_cs5530.c b/drivers/video/fbdev/geode/video_cs5530.c index 649c3943d43..649c3943d43 100644 --- a/drivers/video/geode/video_cs5530.c +++ b/drivers/video/fbdev/geode/video_cs5530.c diff --git a/drivers/video/geode/video_cs5530.h b/drivers/video/fbdev/geode/video_cs5530.h index 56cecca7f1c..56cecca7f1c 100644 --- a/drivers/video/geode/video_cs5530.h +++ b/drivers/video/fbdev/geode/video_cs5530.h diff --git a/drivers/video/geode/video_gx.c b/drivers/video/fbdev/geode/video_gx.c index 6082f653c68..6082f653c68 100644 --- a/drivers/video/geode/video_gx.c +++ b/drivers/video/fbdev/geode/video_gx.c diff --git a/drivers/video/goldfishfb.c b/drivers/video/fbdev/goldfishfb.c index 7f6c9e6cfc6..7f6c9e6cfc6 100644 --- a/drivers/video/goldfishfb.c +++ b/drivers/video/fbdev/goldfishfb.c diff --git a/drivers/video/grvga.c b/drivers/video/fbdev/grvga.c index 861109e7de1..2db5bb1a33e 100644 --- a/drivers/video/grvga.c +++ b/drivers/video/fbdev/grvga.c @@ -496,7 +496,6 @@ static int grvga_probe(struct platform_device *dev)  	return 0;  free_mem: -	dev_set_drvdata(&dev->dev, NULL);  	if (grvga_fix_addr)  		iounmap((void *)virtual_start);  	else @@ -515,9 +514,10 @@ free_fb:  static int grvga_remove(struct platform_device *device)  {  	struct fb_info *info = dev_get_drvdata(&device->dev); -	struct grvga_par *par = info->par; +	struct grvga_par *par;  	if (info) { +		par = info->par;  		unregister_framebuffer(info);  		fb_dealloc_cmap(&info->cmap); @@ -530,7 +530,6 @@ static int grvga_remove(struct platform_device *device)  			kfree((void *)info->screen_base);  		framebuffer_release(info); -		dev_set_drvdata(&device->dev, NULL);  	}  	return 0; @@ -557,19 +556,7 @@ static struct platform_driver grvga_driver = {  	.remove		= grvga_remove,  }; - -static int __init grvga_init(void) -{ -	return platform_driver_register(&grvga_driver); -} - -static void __exit grvga_exit(void) -{ -	platform_driver_unregister(&grvga_driver); -} - -module_init(grvga_init); -module_exit(grvga_exit); +module_platform_driver(grvga_driver);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Aeroflex Gaisler"); diff --git a/drivers/video/gxt4500.c b/drivers/video/fbdev/gxt4500.c index c35663f6a54..135d78a0258 100644 --- a/drivers/video/gxt4500.c +++ b/drivers/video/fbdev/gxt4500.c @@ -698,8 +698,7 @@ static int gxt4500_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  		dev_err(&pdev->dev, "gxt4500: cannot register framebuffer\n");  		goto err_free_cmap;  	} -	printk(KERN_INFO "fb%d: %s frame buffer device\n", -	       info->node, info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	return 0; diff --git a/drivers/video/hecubafb.c b/drivers/video/fbdev/hecubafb.c index 59d23181fdb..f64120ec919 100644 --- a/drivers/video/hecubafb.c +++ b/drivers/video/fbdev/hecubafb.c @@ -261,9 +261,8 @@ static int hecubafb_probe(struct platform_device *dev)  		goto err_fbreg;  	platform_set_drvdata(dev, info); -	printk(KERN_INFO -	       "fb%d: Hecuba frame buffer device, using %dK of video memory\n", -	       info->node, videomemorysize >> 10); +	fb_info(info, "Hecuba frame buffer device, using %dK of video memory\n", +		videomemorysize >> 10);  	/* this inits the dpy */  	retval = par->board->init(par); @@ -305,19 +304,7 @@ static struct platform_driver hecubafb_driver = {  		.name	= "hecubafb",  	},  }; - -static int __init hecubafb_init(void) -{ -	return platform_driver_register(&hecubafb_driver); -} - -static void __exit hecubafb_exit(void) -{ -	platform_driver_unregister(&hecubafb_driver); -} - -module_init(hecubafb_init); -module_exit(hecubafb_exit); +module_platform_driver(hecubafb_driver);  MODULE_DESCRIPTION("fbdev driver for Hecuba/Apollo controller");  MODULE_AUTHOR("Jaya Kumar"); diff --git a/drivers/video/hgafb.c b/drivers/video/fbdev/hgafb.c index 1e9e2d819d1..5ff9fe2116a 100644 --- a/drivers/video/hgafb.c +++ b/drivers/video/fbdev/hgafb.c @@ -586,8 +586,7 @@ static int hgafb_probe(struct platform_device *pdev)  		return -EINVAL;  	} -        printk(KERN_INFO "fb%d: %s frame buffer device\n", -               info->node, info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	platform_set_drvdata(pdev, info);  	return 0;  } diff --git a/drivers/video/hitfb.c b/drivers/video/fbdev/hitfb.c index c2414d6ab64..a648d5186c6 100644 --- a/drivers/video/hitfb.c +++ b/drivers/video/fbdev/hitfb.c @@ -405,8 +405,7 @@ static int hitfb_probe(struct platform_device *dev)  	platform_set_drvdata(dev, info); -	printk(KERN_INFO "fb%d: %s frame buffer device\n", -	       info->node, info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	return 0; diff --git a/drivers/video/hpfb.c b/drivers/video/fbdev/hpfb.c index b802f93cef5..a1b7e5fa9b0 100644 --- a/drivers/video/hpfb.c +++ b/drivers/video/fbdev/hpfb.c @@ -298,8 +298,7 @@ static int hpfb_init_one(unsigned long phys_base, unsigned long virt_base)  	if (ret < 0)  		goto dealloc_cmap; -	printk(KERN_INFO "fb%d: %s frame buffer device\n", -	       fb_info.node, fb_info.fix.id); +	fb_info(&fb_info, "%s frame buffer device\n", fb_info.fix.id);  	return 0; diff --git a/drivers/video/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c index 8ac99b87c07..e23392ec5af 100644 --- a/drivers/video/hyperv_fb.c +++ b/drivers/video/fbdev/hyperv_fb.c @@ -42,6 +42,7 @@  #include <linux/completion.h>  #include <linux/fb.h>  #include <linux/pci.h> +#include <linux/efi.h>  #include <linux/hyperv.h> @@ -212,6 +213,7 @@ struct synthvid_msg {  struct hvfb_par {  	struct fb_info *info; +	struct resource mem;  	bool fb_ready; /* fb device is ready */  	struct completion wait;  	u32 synthvid_version; @@ -460,13 +462,13 @@ static int synthvid_connect_vsp(struct hv_device *hdev)  		goto error;  	} -	if (par->synthvid_version == SYNTHVID_VERSION_WIN7) { +	if (par->synthvid_version == SYNTHVID_VERSION_WIN7)  		screen_depth = SYNTHVID_DEPTH_WIN7; -		screen_fb_size = SYNTHVID_FB_SIZE_WIN7; -	} else { +	else  		screen_depth = SYNTHVID_DEPTH_WIN8; -		screen_fb_size = SYNTHVID_FB_SIZE_WIN8; -	} + +	screen_fb_size = hdev->channel->offermsg.offer. +				mmio_megabytes * 1024 * 1024;  	return 0; @@ -575,6 +577,10 @@ static int hvfb_setcolreg(unsigned regno, unsigned red, unsigned green,  	return 0;  } +static int hvfb_blank(int blank, struct fb_info *info) +{ +	return 1;	/* get fb_blank to set the colormap to all black */ +}  static struct fb_ops hvfb_ops = {  	.owner = THIS_MODULE, @@ -584,6 +590,7 @@ static struct fb_ops hvfb_ops = {  	.fb_fillrect = cfb_fillrect,  	.fb_copyarea = cfb_copyarea,  	.fb_imageblit = cfb_imageblit, +	.fb_blank = hvfb_blank,  }; @@ -622,26 +629,46 @@ static void hvfb_get_option(struct fb_info *info)  /* Get framebuffer memory from Hyper-V video pci space */  static int hvfb_getmem(struct fb_info *info)  { -	struct pci_dev *pdev; -	ulong fb_phys; +	struct hvfb_par *par = info->par; +	struct pci_dev *pdev  = NULL;  	void __iomem *fb_virt; +	int gen2vm = efi_enabled(EFI_BOOT); +	int ret; -	pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT, +	par->mem.name = KBUILD_MODNAME; +	par->mem.flags = IORESOURCE_MEM | IORESOURCE_BUSY; +	if (gen2vm) { +		ret = allocate_resource(&hyperv_mmio, &par->mem, +					screen_fb_size, +					0, -1, +					screen_fb_size, +					NULL, NULL); +		if (ret != 0) { +			pr_err("Unable to allocate framebuffer memory\n"); +			return -ENODEV; +		} +	} else { +		pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,  			      PCI_DEVICE_ID_HYPERV_VIDEO, NULL); -	if (!pdev) { -		pr_err("Unable to find PCI Hyper-V video\n"); -		return -ENODEV; -	} +		if (!pdev) { +			pr_err("Unable to find PCI Hyper-V video\n"); +			return -ENODEV; +		} -	if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) || -	    pci_resource_len(pdev, 0) < screen_fb_size) -		goto err1; +		if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) || +		    pci_resource_len(pdev, 0) < screen_fb_size) +			goto err1; -	fb_phys = pci_resource_end(pdev, 0) - screen_fb_size + 1; -	if (!request_mem_region(fb_phys, screen_fb_size, KBUILD_MODNAME)) -		goto err1; +		par->mem.end = pci_resource_end(pdev, 0); +		par->mem.start = par->mem.end - screen_fb_size + 1; +		ret = request_resource(&pdev->resource[0], &par->mem); +		if (ret != 0) { +			pr_err("Unable to request framebuffer memory\n"); +			goto err1; +		} +	} -	fb_virt = ioremap(fb_phys, screen_fb_size); +	fb_virt = ioremap(par->mem.start, screen_fb_size);  	if (!fb_virt)  		goto err2; @@ -649,30 +676,44 @@ static int hvfb_getmem(struct fb_info *info)  	if (!info->apertures)  		goto err3; -	info->apertures->ranges[0].base = pci_resource_start(pdev, 0); -	info->apertures->ranges[0].size = pci_resource_len(pdev, 0); -	info->fix.smem_start = fb_phys; +	if (gen2vm) { +		info->apertures->ranges[0].base = screen_info.lfb_base; +		info->apertures->ranges[0].size = screen_info.lfb_size; +		remove_conflicting_framebuffers(info->apertures, +						KBUILD_MODNAME, false); +	} else { +		info->apertures->ranges[0].base = pci_resource_start(pdev, 0); +		info->apertures->ranges[0].size = pci_resource_len(pdev, 0); +	} + +	info->fix.smem_start = par->mem.start;  	info->fix.smem_len = screen_fb_size;  	info->screen_base = fb_virt;  	info->screen_size = screen_fb_size; -	pci_dev_put(pdev); +	if (!gen2vm) +		pci_dev_put(pdev); +  	return 0;  err3:  	iounmap(fb_virt);  err2: -	release_mem_region(fb_phys, screen_fb_size); +	release_resource(&par->mem);  err1: -	pci_dev_put(pdev); +	if (!gen2vm) +		pci_dev_put(pdev); +  	return -ENOMEM;  }  /* Release the framebuffer */  static void hvfb_putmem(struct fb_info *info)  { +	struct hvfb_par *par = info->par; +  	iounmap(info->screen_base); -	release_mem_region(info->fix.smem_start, screen_fb_size); +	release_resource(&par->mem);  } @@ -795,12 +836,21 @@ static int hvfb_remove(struct hv_device *hdev)  } +static DEFINE_PCI_DEVICE_TABLE(pci_stub_id_table) = { +	{ +		.vendor      = PCI_VENDOR_ID_MICROSOFT, +		.device      = PCI_DEVICE_ID_HYPERV_VIDEO, +	}, +	{ /* end of list */ } +}; +  static const struct hv_vmbus_device_id id_table[] = {  	/* Synthetic Video Device GUID */  	{HV_SYNTHVID_GUID},  	{}  }; +MODULE_DEVICE_TABLE(pci, pci_stub_id_table);  MODULE_DEVICE_TABLE(vmbus, id_table);  static struct hv_driver hvfb_drv = { @@ -810,14 +860,43 @@ static struct hv_driver hvfb_drv = {  	.remove = hvfb_remove,  }; +static int hvfb_pci_stub_probe(struct pci_dev *pdev, +			       const struct pci_device_id *ent) +{ +	return 0; +} + +static void hvfb_pci_stub_remove(struct pci_dev *pdev) +{ +} + +static struct pci_driver hvfb_pci_stub_driver = { +	.name =		KBUILD_MODNAME, +	.id_table =	pci_stub_id_table, +	.probe =	hvfb_pci_stub_probe, +	.remove =	hvfb_pci_stub_remove, +};  static int __init hvfb_drv_init(void)  { -	return vmbus_driver_register(&hvfb_drv); +	int ret; + +	ret = vmbus_driver_register(&hvfb_drv); +	if (ret != 0) +		return ret; + +	ret = pci_register_driver(&hvfb_pci_stub_driver); +	if (ret != 0) { +		vmbus_driver_unregister(&hvfb_drv); +		return ret; +	} + +	return 0;  }  static void __exit hvfb_drv_exit(void)  { +	pci_unregister_driver(&hvfb_pci_stub_driver);  	vmbus_driver_unregister(&hvfb_drv);  } diff --git a/drivers/video/i740_reg.h b/drivers/video/fbdev/i740_reg.h index 91bac76549d..91bac76549d 100644 --- a/drivers/video/i740_reg.h +++ b/drivers/video/fbdev/i740_reg.h diff --git a/drivers/video/i740fb.c b/drivers/video/fbdev/i740fb.c index 6c483881895..ca7c9df193b 100644 --- a/drivers/video/i740fb.c +++ b/drivers/video/fbdev/i740fb.c @@ -203,8 +203,7 @@ static int i740fb_release(struct fb_info *info, int user)  	mutex_lock(&(par->open_lock));  	if (par->ref_count == 0) { -		printk(KERN_ERR "fb%d: release called with zero refcount\n", -			info->node); +		fb_err(info, "release called with zero refcount\n");  		mutex_unlock(&(par->open_lock));  		return -EINVAL;  	} @@ -1067,7 +1066,7 @@ static int i740fb_probe(struct pci_dev *dev, const struct pci_device_id *ent)  	par->has_sgram = !((tmp & DRAM_RAS_TIMING) ||  			   (tmp & DRAM_RAS_PRECHARGE)); -	printk(KERN_INFO "fb%d: Intel740 on %s, %ld KB %s\n", info->node, +	fb_info(info, "Intel740 on %s, %ld KB %s\n",  		pci_name(dev), info->screen_size >> 10,  		par->has_sgram ? "SGRAM" : "SDRAM"); @@ -1143,8 +1142,7 @@ static int i740fb_probe(struct pci_dev *dev, const struct pci_device_id *ent)  		goto err_reg_framebuffer;  	} -	printk(KERN_INFO "fb%d: %s frame buffer device\n", -		info->node, info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	pci_set_drvdata(dev, info);  #ifdef CONFIG_MTRR  	if (mtrr) { @@ -1194,7 +1192,6 @@ static void i740fb_remove(struct pci_dev *dev)  		pci_iounmap(dev, info->screen_base);  		pci_release_regions(dev);  /*		pci_disable_device(dev); */ -		pci_set_drvdata(dev, NULL);  		framebuffer_release(info);  	}  } diff --git a/drivers/video/i810/Makefile b/drivers/video/fbdev/i810/Makefile index 96e08c8ded9..96e08c8ded9 100644 --- a/drivers/video/i810/Makefile +++ b/drivers/video/fbdev/i810/Makefile diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/fbdev/i810/i810-i2c.c index 7db17d0d8a8..7db17d0d8a8 100644 --- a/drivers/video/i810/i810-i2c.c +++ b/drivers/video/fbdev/i810/i810-i2c.c diff --git a/drivers/video/i810/i810.h b/drivers/video/fbdev/i810/i810.h index 1414b73ac55..1414b73ac55 100644 --- a/drivers/video/i810/i810.h +++ b/drivers/video/fbdev/i810/i810.h diff --git a/drivers/video/i810/i810_accel.c b/drivers/video/fbdev/i810/i810_accel.c index 7672d2ea9b3..7672d2ea9b3 100644 --- a/drivers/video/i810/i810_accel.c +++ b/drivers/video/fbdev/i810/i810_accel.c diff --git a/drivers/video/i810/i810_dvt.c b/drivers/video/fbdev/i810/i810_dvt.c index b4b3670667a..b4b3670667a 100644 --- a/drivers/video/i810/i810_dvt.c +++ b/drivers/video/fbdev/i810/i810_dvt.c diff --git a/drivers/video/i810/i810_gtf.c b/drivers/video/fbdev/i810/i810_gtf.c index 9743d51e7f8..9743d51e7f8 100644 --- a/drivers/video/i810/i810_gtf.c +++ b/drivers/video/fbdev/i810/i810_gtf.c diff --git a/drivers/video/i810/i810_main.c b/drivers/video/fbdev/i810/i810_main.c index 4ce3438ade6..bb674e43174 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/fbdev/i810/i810_main.c @@ -2011,9 +2011,7 @@ static int i810fb_init_pci(struct pci_dev *dev,  	struct fb_info    *info;  	struct i810fb_par *par = NULL;  	struct fb_videomode mode; -	int i, err = -1, vfreq, hfreq, pixclock; - -	i = 0; +	int err = -1, vfreq, hfreq, pixclock;  	info = framebuffer_alloc(sizeof(struct i810fb_par), &dev->dev);  	if (!info) @@ -2129,7 +2127,6 @@ static void __exit i810fb_remove_pci(struct pci_dev *dev)  	unregister_framebuffer(info);    	i810fb_release_resource(info, par); -	pci_set_drvdata(dev, NULL);  	printk("cleanup_module:  unloaded i810 framebuffer device\n");  }                                                	 diff --git a/drivers/video/i810/i810_main.h b/drivers/video/fbdev/i810/i810_main.h index a25afaa534b..a25afaa534b 100644 --- a/drivers/video/i810/i810_main.h +++ b/drivers/video/fbdev/i810/i810_main.h diff --git a/drivers/video/i810/i810_regs.h b/drivers/video/fbdev/i810/i810_regs.h index 91c6bd9d0d0..91c6bd9d0d0 100644 --- a/drivers/video/i810/i810_regs.h +++ b/drivers/video/fbdev/i810/i810_regs.h diff --git a/drivers/video/igafb.c b/drivers/video/fbdev/igafb.c index 79cbfa7d1a9..486f1889741 100644 --- a/drivers/video/igafb.c +++ b/drivers/video/fbdev/igafb.c @@ -360,9 +360,8 @@ static int __init iga_init(struct fb_info *info, struct iga_par *par)  	if (register_framebuffer(info) < 0)  		return 0; -	printk("fb%d: %s frame buffer device at 0x%08lx [%dMB VRAM]\n", -	       info->node, info->fix.id,  -	       par->frame_buffer_phys, info->fix.smem_len >> 20); +	fb_info(info, "%s frame buffer device at 0x%08lx [%dMB VRAM]\n", +		info->fix.id, par->frame_buffer_phys, info->fix.smem_len >> 20);  	iga_blank_border(par);   	return 1; diff --git a/drivers/video/imsttfb.c b/drivers/video/fbdev/imsttfb.c index d5220cc90e9..aae10ce74f1 100644 --- a/drivers/video/imsttfb.c +++ b/drivers/video/fbdev/imsttfb.c @@ -1461,8 +1461,8 @@ static void init_imstt(struct fb_info *info)  	}  	tmp = (read_reg_le32(par->dc_regs, SSTATUS) & 0x0f00) >> 8; -	printk("fb%u: %s frame buffer; %uMB vram; chip version %u\n", -		info->node, info->fix.id, info->fix.smem_len >> 20, tmp); +	fb_info(info, "%s frame buffer; %uMB vram; chip version %u\n", +		info->fix.id, info->fix.smem_len >> 20, tmp);  }  static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) diff --git a/drivers/video/imxfb.c b/drivers/video/fbdev/imxfb.c index 38733ac2b69..f6e62168495 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/fbdev/imxfb.c @@ -30,10 +30,13 @@  #include <linux/platform_device.h>  #include <linux/dma-mapping.h>  #include <linux/io.h> +#include <linux/lcd.h>  #include <linux/math64.h>  #include <linux/of.h>  #include <linux/of_device.h> +#include <linux/regulator/consumer.h> +  #include <video/of_display_timing.h>  #include <video/of_videomode.h>  #include <video/videomode.h> @@ -45,12 +48,6 @@   */  #define DEBUG_VAR 1 -#if defined(CONFIG_BACKLIGHT_CLASS_DEVICE) || \ -	(defined(CONFIG_BACKLIGHT_CLASS_DEVICE_MODULE) && \ -		defined(CONFIG_FB_IMX_MODULE)) -#define PWMR_BACKLIGHT_AVAILABLE -#endif -  #define DRIVER_NAME "imx-fb"  #define LCDC_SSA	0x00 @@ -153,11 +150,8 @@ struct imxfb_info {  	 * the framebuffer memory region to.  	 */  	dma_addr_t		map_dma; -	u_char			*map_cpu;  	u_int			map_size; -	u_char			*screen_cpu; -	dma_addr_t		screen_dma;  	u_int			palette_size;  	dma_addr_t		dbar1; @@ -167,18 +161,13 @@ struct imxfb_info {  	u_int			pwmr;  	u_int			lscr1;  	u_int			dmacr; -	u_int			cmap_inverse:1, -				cmap_static:1, -				unused:30; +	bool			cmap_inverse; +	bool			cmap_static;  	struct imx_fb_videomode *mode;  	int			num_modes; -#ifdef PWMR_BACKLIGHT_AVAILABLE -	struct backlight_device *bl; -#endif -	void (*lcd_power)(int); -	void (*backlight_power)(int); +	struct regulator	*lcd_pwr;  };  static struct platform_device_id imxfb_devtype[] = { @@ -484,83 +473,6 @@ static int imxfb_set_par(struct fb_info *info)  	return 0;  } -#ifdef PWMR_BACKLIGHT_AVAILABLE -static int imxfb_bl_get_brightness(struct backlight_device *bl) -{ -	struct imxfb_info *fbi = bl_get_data(bl); - -	return readl(fbi->regs + LCDC_PWMR) & 0xFF; -} - -static int imxfb_bl_update_status(struct backlight_device *bl) -{ -	struct imxfb_info *fbi = bl_get_data(bl); -	int brightness = bl->props.brightness; - -	if (!fbi->pwmr) -		return 0; - -	if (bl->props.power != FB_BLANK_UNBLANK) -		brightness = 0; -	if (bl->props.fb_blank != FB_BLANK_UNBLANK) -		brightness = 0; - -	fbi->pwmr = (fbi->pwmr & ~0xFF) | brightness; - -	if (bl->props.fb_blank != FB_BLANK_UNBLANK) { -		clk_prepare_enable(fbi->clk_ipg); -		clk_prepare_enable(fbi->clk_ahb); -		clk_prepare_enable(fbi->clk_per); -	} -	writel(fbi->pwmr, fbi->regs + LCDC_PWMR); -	if (bl->props.fb_blank != FB_BLANK_UNBLANK) { -		clk_disable_unprepare(fbi->clk_per); -		clk_disable_unprepare(fbi->clk_ahb); -		clk_disable_unprepare(fbi->clk_ipg); -	} - -	return 0; -} - -static const struct backlight_ops imxfb_lcdc_bl_ops = { -	.update_status = imxfb_bl_update_status, -	.get_brightness = imxfb_bl_get_brightness, -}; - -static void imxfb_init_backlight(struct imxfb_info *fbi) -{ -	struct backlight_properties props; -	struct backlight_device	*bl; - -	if (fbi->bl) -		return; - -	memset(&props, 0, sizeof(struct backlight_properties)); -	props.max_brightness = 0xff; -	props.type = BACKLIGHT_RAW; -	writel(fbi->pwmr, fbi->regs + LCDC_PWMR); - -	bl = backlight_device_register("imxfb-bl", &fbi->pdev->dev, fbi, -				       &imxfb_lcdc_bl_ops, &props); -	if (IS_ERR(bl)) { -		dev_err(&fbi->pdev->dev, "error %ld on backlight register\n", -				PTR_ERR(bl)); -		return; -	} - -	fbi->bl = bl; -	bl->props.power = FB_BLANK_UNBLANK; -	bl->props.fb_blank = FB_BLANK_UNBLANK; -	bl->props.brightness = imxfb_bl_get_brightness(bl); -} - -static void imxfb_exit_backlight(struct imxfb_info *fbi) -{ -	if (fbi->bl) -		backlight_device_unregister(fbi->bl); -} -#endif -  static void imxfb_enable_controller(struct imxfb_info *fbi)  { @@ -569,7 +481,7 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)  	pr_debug("Enabling LCD controller\n"); -	writel(fbi->screen_dma, fbi->regs + LCDC_SSA); +	writel(fbi->map_dma, fbi->regs + LCDC_SSA);  	/* panning offset 0 (0 pixel offset)        */  	writel(0x00000000, fbi->regs + LCDC_POS); @@ -588,11 +500,6 @@ static void imxfb_enable_controller(struct imxfb_info *fbi)  	clk_prepare_enable(fbi->clk_ahb);  	clk_prepare_enable(fbi->clk_per);  	fbi->enabled = true; - -	if (fbi->backlight_power) -		fbi->backlight_power(1); -	if (fbi->lcd_power) -		fbi->lcd_power(1);  }  static void imxfb_disable_controller(struct imxfb_info *fbi) @@ -602,11 +509,6 @@ static void imxfb_disable_controller(struct imxfb_info *fbi)  	pr_debug("Disabling LCD controller\n"); -	if (fbi->backlight_power) -		fbi->backlight_power(0); -	if (fbi->lcd_power) -		fbi->lcd_power(0); -  	clk_disable_unprepare(fbi->clk_per);  	clk_disable_unprepare(fbi->clk_ipg);  	clk_disable_unprepare(fbi->clk_ahb); @@ -709,10 +611,8 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf  			fbi->regs + LCDC_SIZE);  	writel(fbi->pcr, fbi->regs + LCDC_PCR); -#ifndef PWMR_BACKLIGHT_AVAILABLE  	if (fbi->pwmr)  		writel(fbi->pwmr, fbi->regs + LCDC_PWMR); -#endif  	writel(fbi->lscr1, fbi->regs + LCDC_LSCR1);  	/* dmacr = 0 is no valid value, as we need DMA control marks. */ @@ -722,40 +622,9 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf  	return 0;  } -#ifdef CONFIG_PM -/* - * Power management hooks.  Note that we won't be called from IRQ context, - * unlike the blank functions above, so we may sleep. - */ -static int imxfb_suspend(struct platform_device *dev, pm_message_t state) -{ -	struct fb_info *info = platform_get_drvdata(dev); -	struct imxfb_info *fbi = info->par; - -	pr_debug("%s\n", __func__); - -	imxfb_disable_controller(fbi); -	return 0; -} - -static int imxfb_resume(struct platform_device *dev) -{ -	struct fb_info *info = platform_get_drvdata(dev); -	struct imxfb_info *fbi = info->par; - -	pr_debug("%s\n", __func__); - -	imxfb_enable_controller(fbi); -	return 0; -} -#else -#define imxfb_suspend	NULL -#define imxfb_resume	NULL -#endif -  static int imxfb_init_fbinfo(struct platform_device *pdev)  { -	struct imx_fb_platform_data *pdata = pdev->dev.platform_data; +	struct imx_fb_platform_data *pdata = dev_get_platdata(&pdev->dev);  	struct fb_info *info = dev_get_drvdata(&pdev->dev);  	struct imxfb_info *fbi = info->par;  	struct device_node *np; @@ -790,14 +659,9 @@ static int imxfb_init_fbinfo(struct platform_device *pdev)  	info->flags			= FBINFO_FLAG_DEFAULT |  					  FBINFO_READS_FAST;  	if (pdata) { -		info->var.grayscale		= pdata->cmap_greyscale; -		fbi->cmap_inverse		= pdata->cmap_inverse; -		fbi->cmap_static		= pdata->cmap_static;  		fbi->lscr1			= pdata->lscr1;  		fbi->dmacr			= pdata->dmacr;  		fbi->pwmr			= pdata->pwmr; -		fbi->lcd_power			= pdata->lcd_power; -		fbi->backlight_power		= pdata->backlight_power;  	} else {  		np = pdev->dev.of_node;  		info->var.grayscale = of_property_read_bool(np, @@ -806,14 +670,12 @@ static int imxfb_init_fbinfo(struct platform_device *pdev)  		fbi->cmap_static = of_property_read_bool(np, "cmap-static");  		fbi->lscr1 = IMXFB_LSCR1_DEFAULT; + +		of_property_read_u32(np, "fsl,lpccr", &fbi->pwmr); +  		of_property_read_u32(np, "fsl,lscr1", &fbi->lscr1);  		of_property_read_u32(np, "fsl,dmacr", &fbi->dmacr); - -		/* These two function pointers could be used by some specific -		 * platforms. */ -		fbi->lcd_power = NULL; -		fbi->backlight_power = NULL;  	}  	return 0; @@ -856,9 +718,98 @@ static int imxfb_of_read_mode(struct device *dev, struct device_node *np,  	return 0;  } +static int imxfb_lcd_check_fb(struct lcd_device *lcddev, struct fb_info *fi) +{ +	struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev); + +	if (!fi || fi->par == fbi) +		return 1; + +	return 0; +} + +static int imxfb_lcd_get_contrast(struct lcd_device *lcddev) +{ +	struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev); + +	return fbi->pwmr & 0xff; +} + +static int imxfb_lcd_set_contrast(struct lcd_device *lcddev, int contrast) +{ +	struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev); + +	if (fbi->pwmr && fbi->enabled) { +		if (contrast > 255) +			contrast = 255; +		else if (contrast < 0) +			contrast = 0; + +		fbi->pwmr &= ~0xff; +		fbi->pwmr |= contrast; + +		writel(fbi->pwmr, fbi->regs + LCDC_PWMR); +	} + +	return 0; +} + +static int imxfb_lcd_get_power(struct lcd_device *lcddev) +{ +	struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev); + +	if (!IS_ERR(fbi->lcd_pwr)) +		return regulator_is_enabled(fbi->lcd_pwr); + +	return 1; +} + +static int imxfb_lcd_set_power(struct lcd_device *lcddev, int power) +{ +	struct imxfb_info *fbi = dev_get_drvdata(&lcddev->dev); + +	if (!IS_ERR(fbi->lcd_pwr)) { +		if (power) +			return regulator_enable(fbi->lcd_pwr); +		else +			return regulator_disable(fbi->lcd_pwr); +	} + +	return 0; +} + +static struct lcd_ops imxfb_lcd_ops = { +	.check_fb	= imxfb_lcd_check_fb, +	.get_contrast	= imxfb_lcd_get_contrast, +	.set_contrast	= imxfb_lcd_set_contrast, +	.get_power	= imxfb_lcd_get_power, +	.set_power	= imxfb_lcd_set_power, +}; + +static int imxfb_setup(void) +{ +	char *opt, *options = NULL; + +	if (fb_get_options("imxfb", &options)) +		return -ENODEV; + +	if (!options || !*options) +		return 0; + +	while ((opt = strsep(&options, ",")) != NULL) { +		if (!*opt) +			continue; +		else +			fb_mode = opt; +	} + +	return 0; +} +  static int imxfb_probe(struct platform_device *pdev)  {  	struct imxfb_info *fbi; +	struct lcd_device *lcd;  	struct fb_info *info;  	struct imx_fb_platform_data *pdata;  	struct resource *res; @@ -869,6 +820,10 @@ static int imxfb_probe(struct platform_device *pdev)  	dev_info(&pdev->dev, "i.MX Framebuffer driver\n"); +	ret = imxfb_setup(); +	if (ret < 0) +		return ret; +  	of_id = of_match_device(imxfb_of_dev_id, &pdev->dev);  	if (of_id)  		pdev->id_entry = of_id->data; @@ -877,7 +832,7 @@ static int imxfb_probe(struct platform_device *pdev)  	if (!res)  		return -ENODEV; -	pdata = pdev->dev.platform_data; +	pdata = dev_get_platdata(&pdev->dev);  	info = framebuffer_alloc(sizeof(struct imxfb_info), &pdev->dev);  	if (!info) @@ -966,32 +921,18 @@ static int imxfb_probe(struct platform_device *pdev)  		goto failed_ioremap;  	} -	/* Seems not being used by anyone, so no support for oftree */ -	if (!pdata || !pdata->fixed_screen_cpu) { -		fbi->map_size = PAGE_ALIGN(info->fix.smem_len); -		fbi->map_cpu = dma_alloc_writecombine(&pdev->dev, -				fbi->map_size, &fbi->map_dma, GFP_KERNEL); +	fbi->map_size = PAGE_ALIGN(info->fix.smem_len); +	info->screen_base = dma_alloc_writecombine(&pdev->dev, fbi->map_size, +						   &fbi->map_dma, GFP_KERNEL); -		if (!fbi->map_cpu) { -			dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret); -			ret = -ENOMEM; -			goto failed_map; -		} - -		info->screen_base = fbi->map_cpu; -		fbi->screen_cpu = fbi->map_cpu; -		fbi->screen_dma = fbi->map_dma; -		info->fix.smem_start = fbi->screen_dma; -	} else { -		/* Fixed framebuffer mapping enables location of the screen in eSRAM */ -		fbi->map_cpu = pdata->fixed_screen_cpu; -		fbi->map_dma = pdata->fixed_screen_dma; -		info->screen_base = fbi->map_cpu; -		fbi->screen_cpu = fbi->map_cpu; -		fbi->screen_dma = fbi->map_dma; -		info->fix.smem_start = fbi->screen_dma; +	if (!info->screen_base) { +		dev_err(&pdev->dev, "Failed to allocate video RAM: %d\n", ret); +		ret = -ENOMEM; +		goto failed_map;  	} +	info->fix.smem_start = fbi->map_dma; +  	if (pdata && pdata->init) {  		ret = pdata->init(fbi->pdev);  		if (ret) @@ -1020,23 +961,37 @@ static int imxfb_probe(struct platform_device *pdev)  		goto failed_register;  	} +	fbi->lcd_pwr = devm_regulator_get(&pdev->dev, "lcd"); +	if (IS_ERR(fbi->lcd_pwr) && (PTR_ERR(fbi->lcd_pwr) == -EPROBE_DEFER)) { +		ret = -EPROBE_DEFER; +		goto failed_lcd; +	} + +	lcd = devm_lcd_device_register(&pdev->dev, "imxfb-lcd", &pdev->dev, fbi, +				       &imxfb_lcd_ops); +	if (IS_ERR(lcd)) { +		ret = PTR_ERR(lcd); +		goto failed_lcd; +	} + +	lcd->props.max_contrast = 0xff; +  	imxfb_enable_controller(fbi);  	fbi->pdev = pdev; -#ifdef PWMR_BACKLIGHT_AVAILABLE -	imxfb_init_backlight(fbi); -#endif  	return 0; +failed_lcd: +	unregister_framebuffer(info); +  failed_register:  	fb_dealloc_cmap(&info->cmap);  failed_cmap:  	if (pdata && pdata->exit)  		pdata->exit(fbi->pdev);  failed_platform_init: -	if (pdata && !pdata->fixed_screen_cpu) -		dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu, -			fbi->map_dma); +	dma_free_writecombine(&pdev->dev, fbi->map_size, info->screen_base, +			      fbi->map_dma);  failed_map:  	iounmap(fbi->regs);  failed_ioremap: @@ -1061,12 +1016,9 @@ static int imxfb_remove(struct platform_device *pdev)  	imxfb_disable_controller(fbi); -#ifdef PWMR_BACKLIGHT_AVAILABLE -	imxfb_exit_backlight(fbi); -#endif  	unregister_framebuffer(info); -	pdata = pdev->dev.platform_data; +	pdata = dev_get_platdata(&pdev->dev);  	if (pdata && pdata->exit)  		pdata->exit(fbi->pdev); @@ -1074,69 +1026,49 @@ static int imxfb_remove(struct platform_device *pdev)  	kfree(info->pseudo_palette);  	framebuffer_release(info); +	dma_free_writecombine(&pdev->dev, fbi->map_size, info->screen_base, +			      fbi->map_dma); +  	iounmap(fbi->regs);  	release_mem_region(res->start, resource_size(res));  	return 0;  } -static void imxfb_shutdown(struct platform_device *dev) +static int __maybe_unused imxfb_suspend(struct device *dev)  { -	struct fb_info *info = platform_get_drvdata(dev); +	struct fb_info *info = dev_get_drvdata(dev);  	struct imxfb_info *fbi = info->par; -	imxfb_disable_controller(fbi); -} - -static struct platform_driver imxfb_driver = { -	.suspend	= imxfb_suspend, -	.resume		= imxfb_resume, -	.remove		= imxfb_remove, -	.shutdown	= imxfb_shutdown, -	.driver		= { -		.name	= DRIVER_NAME, -		.of_match_table = imxfb_of_dev_id, -	}, -	.id_table	= imxfb_devtype, -}; - -static int imxfb_setup(void) -{ -#ifndef MODULE -	char *opt, *options = NULL; -	if (fb_get_options("imxfb", &options)) -		return -ENODEV; - -	if (!options || !*options) -		return 0; +	imxfb_disable_controller(fbi); -	while ((opt = strsep(&options, ",")) != NULL) { -		if (!*opt) -			continue; -		else -			fb_mode = opt; -	} -#endif  	return 0;  } -static int __init imxfb_init(void) +static int __maybe_unused imxfb_resume(struct device *dev)  { -	int ret = imxfb_setup(); +	struct fb_info *info = dev_get_drvdata(dev); +	struct imxfb_info *fbi = info->par; -	if (ret < 0) -		return ret; +	imxfb_enable_controller(fbi); -	return platform_driver_probe(&imxfb_driver, imxfb_probe); +	return 0;  } -static void __exit imxfb_cleanup(void) -{ -	platform_driver_unregister(&imxfb_driver); -} +static SIMPLE_DEV_PM_OPS(imxfb_pm_ops, imxfb_suspend, imxfb_resume); -module_init(imxfb_init); -module_exit(imxfb_cleanup); +static struct platform_driver imxfb_driver = { +	.driver		= { +		.name	= DRIVER_NAME, +		.of_match_table = imxfb_of_dev_id, +		.owner	= THIS_MODULE, +		.pm	= &imxfb_pm_ops, +	}, +	.probe		= imxfb_probe, +	.remove		= imxfb_remove, +	.id_table	= imxfb_devtype, +}; +module_platform_driver(imxfb_driver);  MODULE_DESCRIPTION("Freescale i.MX framebuffer driver");  MODULE_AUTHOR("Sascha Hauer, Pengutronix"); diff --git a/drivers/video/intelfb/Makefile b/drivers/video/fbdev/intelfb/Makefile index f7d631ebee8..f7d631ebee8 100644 --- a/drivers/video/intelfb/Makefile +++ b/drivers/video/fbdev/intelfb/Makefile diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/fbdev/intelfb/intelfb.h index 6b51175629c..6b51175629c 100644 --- a/drivers/video/intelfb/intelfb.h +++ b/drivers/video/fbdev/intelfb/intelfb.h diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/fbdev/intelfb/intelfb_i2c.c index 3300bd31d9d..3300bd31d9d 100644 --- a/drivers/video/intelfb/intelfb_i2c.c +++ b/drivers/video/fbdev/intelfb/intelfb_i2c.c diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/fbdev/intelfb/intelfbdrv.c index 8209e46c5d2..b847d530471 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/fbdev/intelfb/intelfbdrv.c @@ -931,8 +931,6 @@ static void intelfb_pci_unregister(struct pci_dev *pdev)  		return;  	cleanup(dinfo); - -	pci_set_drvdata(pdev, NULL);  }  /*************************************************************** diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/fbdev/intelfb/intelfbhw.c index fbad61da359..fbad61da359 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/fbdev/intelfb/intelfbhw.c diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/fbdev/intelfb/intelfbhw.h index 216ca20f259..216ca20f259 100644 --- a/drivers/video/intelfb/intelfbhw.h +++ b/drivers/video/fbdev/intelfb/intelfbhw.h diff --git a/drivers/video/jz4740_fb.c b/drivers/video/fbdev/jz4740_fb.c index 2c49112fdd6..87790e9644d 100644 --- a/drivers/video/jz4740_fb.c +++ b/drivers/video/fbdev/jz4740_fb.c @@ -99,9 +99,9 @@  #define JZ_LCD_CTRL_BPP_15_16		0x4  #define JZ_LCD_CTRL_BPP_18_24		0x5 -#define JZ_LCD_CMD_SOF_IRQ BIT(15) -#define JZ_LCD_CMD_EOF_IRQ BIT(16) -#define JZ_LCD_CMD_ENABLE_PAL BIT(12) +#define JZ_LCD_CMD_SOF_IRQ BIT(31) +#define JZ_LCD_CMD_EOF_IRQ BIT(30) +#define JZ_LCD_CMD_ENABLE_PAL BIT(28)  #define JZ_LCD_SYNC_MASK 0x3ff @@ -471,7 +471,7 @@ static int jzfb_set_par(struct fb_info *info)  	writel(ctrl, jzfb->base + JZ_REG_LCD_CTRL);  	if (!jzfb->is_enabled) -		clk_disable(jzfb->ldclk); +		clk_disable_unprepare(jzfb->ldclk);  	mutex_unlock(&jzfb->lock); @@ -485,7 +485,7 @@ static void jzfb_enable(struct jzfb *jzfb)  {  	uint32_t ctrl; -	clk_enable(jzfb->ldclk); +	clk_prepare_enable(jzfb->ldclk);  	jz_gpio_bulk_resume(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));  	jz_gpio_bulk_resume(jz_lcd_data_pins, jzfb_num_data_pins(jzfb)); @@ -514,7 +514,7 @@ static void jzfb_disable(struct jzfb *jzfb)  	jz_gpio_bulk_suspend(jz_lcd_ctrl_pins, jzfb_num_ctrl_pins(jzfb));  	jz_gpio_bulk_suspend(jz_lcd_data_pins, jzfb_num_data_pins(jzfb)); -	clk_disable(jzfb->ldclk); +	clk_disable_unprepare(jzfb->ldclk);  }  static int jzfb_blank(int blank_mode, struct fb_info *info) @@ -693,7 +693,7 @@ static int jzfb_probe(struct platform_device *pdev)  	fb_alloc_cmap(&fb->cmap, 256, 0); -	clk_enable(jzfb->ldclk); +	clk_prepare_enable(jzfb->ldclk);  	jzfb->is_enabled = 1;  	writel(jzfb->framedesc->next, jzfb->base + JZ_REG_LCD_DA0); @@ -763,7 +763,7 @@ static int jzfb_suspend(struct device *dev)  static int jzfb_resume(struct device *dev)  {  	struct jzfb *jzfb = dev_get_drvdata(dev); -	clk_enable(jzfb->ldclk); +	clk_prepare_enable(jzfb->ldclk);  	mutex_lock(&jzfb->lock);  	if (jzfb->is_enabled) @@ -798,18 +798,7 @@ static struct platform_driver jzfb_driver = {  		.pm = JZFB_PM_OPS,  	},  }; - -static int __init jzfb_init(void) -{ -	return platform_driver_register(&jzfb_driver); -} -module_init(jzfb_init); - -static void __exit jzfb_exit(void) -{ -	platform_driver_unregister(&jzfb_driver); -} -module_exit(jzfb_exit); +module_platform_driver(jzfb_driver);  MODULE_LICENSE("GPL");  MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); diff --git a/drivers/video/kyro/Makefile b/drivers/video/fbdev/kyro/Makefile index 2fd66f551ba..2fd66f551ba 100644 --- a/drivers/video/kyro/Makefile +++ b/drivers/video/fbdev/kyro/Makefile diff --git a/drivers/video/kyro/STG4000InitDevice.c b/drivers/video/fbdev/kyro/STG4000InitDevice.c index 1d3f2080aa6..1d3f2080aa6 100644 --- a/drivers/video/kyro/STG4000InitDevice.c +++ b/drivers/video/fbdev/kyro/STG4000InitDevice.c diff --git a/drivers/video/kyro/STG4000Interface.h b/drivers/video/fbdev/kyro/STG4000Interface.h index b7c83d5dfb1..b7c83d5dfb1 100644 --- a/drivers/video/kyro/STG4000Interface.h +++ b/drivers/video/fbdev/kyro/STG4000Interface.h diff --git a/drivers/video/kyro/STG4000OverlayDevice.c b/drivers/video/fbdev/kyro/STG4000OverlayDevice.c index 0aeeaa10708..0aeeaa10708 100644 --- a/drivers/video/kyro/STG4000OverlayDevice.c +++ b/drivers/video/fbdev/kyro/STG4000OverlayDevice.c diff --git a/drivers/video/kyro/STG4000Ramdac.c b/drivers/video/fbdev/kyro/STG4000Ramdac.c index e6ad037e439..e6ad037e439 100644 --- a/drivers/video/kyro/STG4000Ramdac.c +++ b/drivers/video/fbdev/kyro/STG4000Ramdac.c diff --git a/drivers/video/kyro/STG4000Reg.h b/drivers/video/fbdev/kyro/STG4000Reg.h index 50f4670e925..50f4670e925 100644 --- a/drivers/video/kyro/STG4000Reg.h +++ b/drivers/video/fbdev/kyro/STG4000Reg.h diff --git a/drivers/video/kyro/STG4000VTG.c b/drivers/video/fbdev/kyro/STG4000VTG.c index bd389709d23..bd389709d23 100644 --- a/drivers/video/kyro/STG4000VTG.c +++ b/drivers/video/fbdev/kyro/STG4000VTG.c diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c index 6157f74ac60..65041e15fd5 100644 --- a/drivers/video/kyro/fbdev.c +++ b/drivers/video/fbdev/kyro/fbdev.c @@ -623,17 +623,16 @@ static int kyrofb_ioctl(struct fb_info *info,  				"command instead.\n");  			return -EINVAL;  		} -		break;  	case KYRO_IOCTL_UVSTRIDE: -		if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(unsigned long))) +		if (copy_to_user(argp, &deviceInfo.ulOverlayUVStride, sizeof(deviceInfo.ulOverlayUVStride)))  			return -EFAULT;  		break;  	case KYRO_IOCTL_STRIDE: -		if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(unsigned long))) +		if (copy_to_user(argp, &deviceInfo.ulOverlayStride, sizeof(deviceInfo.ulOverlayStride)))  			return -EFAULT;  		break;  	case KYRO_IOCTL_OVERLAY_OFFSET: -		if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(unsigned long))) +		if (copy_to_user(argp, &deviceInfo.ulOverlayOffset, sizeof(deviceInfo.ulOverlayOffset)))  			return -EFAULT;  		break;  	} @@ -736,10 +735,10 @@ static int kyrofb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	if (register_framebuffer(info) < 0)  		goto out_unmap; -	printk("fb%d: %s frame buffer device, at %dx%d@%d using %ldk/%ldk of VRAM\n", -	       info->node, info->fix.id, info->var.xres, -	       info->var.yres, info->var.bits_per_pixel, size >> 10, -	       (unsigned long)info->fix.smem_len >> 10); +	fb_info(info, "%s frame buffer device, at %dx%d@%d using %ldk/%ldk of VRAM\n", +		info->fix.id, +		info->var.xres, info->var.yres, info->var.bits_per_pixel, +		size >> 10, (unsigned long)info->fix.smem_len >> 10);  	pci_set_drvdata(pdev, info); @@ -779,7 +778,6 @@ static void kyrofb_remove(struct pci_dev *pdev)  #endif  	unregister_framebuffer(info); -	pci_set_drvdata(pdev, NULL);  	framebuffer_release(info);  } diff --git a/drivers/video/leo.c b/drivers/video/fbdev/leo.c index b17f5009a43..2c7f7d479fe 100644 --- a/drivers/video/leo.c +++ b/drivers/video/fbdev/leo.c @@ -469,7 +469,7 @@ static void leo_wid_put(struct fb_info *info, struct fb_wid_list *wl)  		default:  			continue; -		}; +		}  		sbus_writel(0x5800 + j, &lx_krn->krn_type);  		sbus_writel(wi->wi_values[0], &lx_krn->krn_value);  	} @@ -648,8 +648,6 @@ static int leo_remove(struct platform_device *op)  	framebuffer_release(info); -	dev_set_drvdata(&op->dev, NULL); -  	return 0;  } diff --git a/drivers/video/macfb.c b/drivers/video/fbdev/macfb.c index fe01add3700..cda7587cbc8 100644 --- a/drivers/video/macfb.c +++ b/drivers/video/fbdev/macfb.c @@ -34,7 +34,6 @@  #include <linux/fb.h>  #include <asm/setup.h> -#include <asm/bootinfo.h>  #include <asm/macintosh.h>  #include <asm/io.h> @@ -913,8 +912,7 @@ static int __init macfb_init(void)  	if (err)  		goto fail_dealloc; -	pr_info("fb%d: %s frame buffer device\n", -	        fb_info.node, fb_info.fix.id); +	fb_info(&fb_info, "%s frame buffer device\n", fb_info.fix.id);  	return 0; diff --git a/drivers/video/macmodes.c b/drivers/video/fbdev/macmodes.c index af86c081d2b..af86c081d2b 100644 --- a/drivers/video/macmodes.c +++ b/drivers/video/fbdev/macmodes.c diff --git a/drivers/video/macmodes.h b/drivers/video/fbdev/macmodes.h index b86ba08aac9..b86ba08aac9 100644 --- a/drivers/video/macmodes.h +++ b/drivers/video/fbdev/macmodes.h diff --git a/drivers/video/matrox/Makefile b/drivers/video/fbdev/matrox/Makefile index f9c00ebe253..f9c00ebe253 100644 --- a/drivers/video/matrox/Makefile +++ b/drivers/video/fbdev/matrox/Makefile diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/fbdev/matrox/g450_pll.c index c15f8a57498..c15f8a57498 100644 --- a/drivers/video/matrox/g450_pll.c +++ b/drivers/video/fbdev/matrox/g450_pll.c diff --git a/drivers/video/matrox/g450_pll.h b/drivers/video/fbdev/matrox/g450_pll.h index aac615d1844..aac615d1844 100644 --- a/drivers/video/matrox/g450_pll.h +++ b/drivers/video/fbdev/matrox/g450_pll.h diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/fbdev/matrox/i2c-matroxfb.c index 0fb280ead3d..0fb280ead3d 100644 --- a/drivers/video/matrox/i2c-matroxfb.c +++ b/drivers/video/fbdev/matrox/i2c-matroxfb.c diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/fbdev/matrox/matroxfb_DAC1064.c index 1717623aabc..a01147fdf27 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.c +++ b/drivers/video/fbdev/matrox/matroxfb_DAC1064.c @@ -494,7 +494,7 @@ static int m1064_compute(void* out, struct my_timming* m) {  			if (inDAC1064(minfo, M1064_XPIXPLLSTAT) & 0x40)  				break;  			udelay(10); -		}; +		}  		CRITEND @@ -639,7 +639,7 @@ static void MGAG100_progPixClock(const struct matrox_fb_info *minfo, int flags,  		if (inDAC1064(minfo, M1064_XPIXPLLSTAT) & 0x40)  			break;  		udelay(10); -	}; +	}  	if (!clk)  		printk(KERN_ERR "matroxfb: Pixel PLL%c not locked after usual time\n", (reg-M1064_XPIXPLLAM-2)/4 + 'A');  	selClk = inDAC1064(minfo, M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_SRC_MASK; diff --git a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/fbdev/matrox/matroxfb_DAC1064.h index 1e6e45b57b7..1e6e45b57b7 100644 --- a/drivers/video/matrox/matroxfb_DAC1064.h +++ b/drivers/video/fbdev/matrox/matroxfb_DAC1064.h diff --git a/drivers/video/matrox/matroxfb_Ti3026.c b/drivers/video/fbdev/matrox/matroxfb_Ti3026.c index 9a44cec394b..195ad7cac1b 100644 --- a/drivers/video/matrox/matroxfb_Ti3026.c +++ b/drivers/video/fbdev/matrox/matroxfb_Ti3026.c @@ -473,7 +473,7 @@ static void ti3026_setMCLK(struct matrox_fb_info *minfo, int fout)  		if (inTi3026(minfo, TVP3026_XPIXPLLDATA) & 0x40)  			break;  		udelay(10); -	}; +	}  	if (!tmout)  		printk(KERN_ERR "matroxfb: Temporary pixel PLL not locked after 5 secs\n"); diff --git a/drivers/video/matrox/matroxfb_Ti3026.h b/drivers/video/fbdev/matrox/matroxfb_Ti3026.h index 27872aaa0a1..27872aaa0a1 100644 --- a/drivers/video/matrox/matroxfb_Ti3026.h +++ b/drivers/video/fbdev/matrox/matroxfb_Ti3026.h diff --git a/drivers/video/matrox/matroxfb_accel.c b/drivers/video/fbdev/matrox/matroxfb_accel.c index 8335a6fe303..0d5cb85d071 100644 --- a/drivers/video/matrox/matroxfb_accel.c +++ b/drivers/video/fbdev/matrox/matroxfb_accel.c @@ -192,10 +192,18 @@ void matrox_cfbX_init(struct matrox_fb_info *minfo)  	minfo->accel.m_dwg_rect = M_DWG_TRAP | M_DWG_SOLID | M_DWG_ARZERO | M_DWG_SGNZERO | M_DWG_SHIFTZERO;  	if (isMilleniumII(minfo)) minfo->accel.m_dwg_rect |= M_DWG_TRANSC;  	minfo->accel.m_opmode = mopmode; +	minfo->accel.m_access = maccess; +	minfo->accel.m_pitch = mpitch;  }  EXPORT_SYMBOL(matrox_cfbX_init); +static void matrox_accel_restore_maccess(struct matrox_fb_info *minfo) +{ +	mga_outl(M_MACCESS, minfo->accel.m_access); +	mga_outl(M_PITCH, minfo->accel.m_pitch); +} +  static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy,  			       int sx, int dy, int dx, int height, int width)  { @@ -207,7 +215,8 @@ static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy,  	CRITBEGIN  	if ((dy < sy) || ((dy == sy) && (dx <= sx))) { -		mga_fifo(2); +		mga_fifo(4); +		matrox_accel_restore_maccess(minfo);  		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_SGNZERO |  			 M_DWG_BFCOL | M_DWG_REPLACE);  		mga_outl(M_AR5, vxres); @@ -215,7 +224,8 @@ static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy,  		start = sy*vxres+sx+curr_ydstorg(minfo);  		end = start+width;  	} else { -		mga_fifo(3); +		mga_fifo(5); +		matrox_accel_restore_maccess(minfo);  		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_BFCOL | M_DWG_REPLACE);  		mga_outl(M_SGN, 5);  		mga_outl(M_AR5, -vxres); @@ -224,7 +234,8 @@ static void matrox_accel_bmove(struct matrox_fb_info *minfo, int vxres, int sy,  		start = end+width;  		dy += height-1;  	} -	mga_fifo(4); +	mga_fifo(6); +	matrox_accel_restore_maccess(minfo);  	mga_outl(M_AR0, end);  	mga_outl(M_AR3, start);  	mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx); @@ -246,7 +257,8 @@ static void matrox_accel_bmove_lin(struct matrox_fb_info *minfo, int vxres,  	CRITBEGIN  	if ((dy < sy) || ((dy == sy) && (dx <= sx))) { -		mga_fifo(2); +		mga_fifo(4); +		matrox_accel_restore_maccess(minfo);  		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_SGNZERO |  			M_DWG_BFCOL | M_DWG_REPLACE);  		mga_outl(M_AR5, vxres); @@ -254,7 +266,8 @@ static void matrox_accel_bmove_lin(struct matrox_fb_info *minfo, int vxres,  		start = sy*vxres+sx+curr_ydstorg(minfo);  		end = start+width;  	} else { -		mga_fifo(3); +		mga_fifo(5); +		matrox_accel_restore_maccess(minfo);  		mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SHIFTZERO | M_DWG_BFCOL | M_DWG_REPLACE);  		mga_outl(M_SGN, 5);  		mga_outl(M_AR5, -vxres); @@ -263,7 +276,8 @@ static void matrox_accel_bmove_lin(struct matrox_fb_info *minfo, int vxres,  		start = end+width;  		dy += height-1;  	} -	mga_fifo(5); +	mga_fifo(7); +	matrox_accel_restore_maccess(minfo);  	mga_outl(M_AR0, end);  	mga_outl(M_AR3, start);  	mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx); @@ -298,7 +312,8 @@ static void matroxfb_accel_clear(struct matrox_fb_info *minfo, u_int32_t color,  	CRITBEGIN -	mga_fifo(5); +	mga_fifo(7); +	matrox_accel_restore_maccess(minfo);  	mga_outl(M_DWGCTL, minfo->accel.m_dwg_rect | M_DWG_REPLACE);  	mga_outl(M_FCOL, color);  	mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx); @@ -341,7 +356,8 @@ static void matroxfb_cfb4_clear(struct matrox_fb_info *minfo, u_int32_t bgx,  	width >>= 1;  	sx >>= 1;  	if (width) { -		mga_fifo(5); +		mga_fifo(7); +		matrox_accel_restore_maccess(minfo);  		mga_outl(M_DWGCTL, minfo->accel.m_dwg_rect | M_DWG_REPLACE2);  		mga_outl(M_FCOL, bgx);  		mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx); @@ -415,7 +431,8 @@ static void matroxfb_1bpp_imageblit(struct matrox_fb_info *minfo, u_int32_t fgx,  	CRITBEGIN -	mga_fifo(3); +	mga_fifo(5); +	matrox_accel_restore_maccess(minfo);  	if (easy)  		mga_outl(M_DWGCTL, M_DWG_ILOAD | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);  	else @@ -425,7 +442,8 @@ static void matroxfb_1bpp_imageblit(struct matrox_fb_info *minfo, u_int32_t fgx,  	fxbndry = ((xx + width - 1) << 16) | xx;  	mmio = minfo->mmio.vbase; -	mga_fifo(6); +	mga_fifo(8); +	matrox_accel_restore_maccess(minfo);  	mga_writel(mmio, M_FXBNDRY, fxbndry);  	mga_writel(mmio, M_AR0, ar0);  	mga_writel(mmio, M_AR3, 0); diff --git a/drivers/video/matrox/matroxfb_accel.h b/drivers/video/fbdev/matrox/matroxfb_accel.h index 1e418e62c22..1e418e62c22 100644 --- a/drivers/video/matrox/matroxfb_accel.h +++ b/drivers/video/fbdev/matrox/matroxfb_accel.h diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c index 24565291165..7116c5309c7 100644 --- a/drivers/video/matrox/matroxfb_base.c +++ b/drivers/video/fbdev/matrox/matroxfb_base.c @@ -1773,7 +1773,8 @@ static int initMatrox2(struct matrox_fb_info *minfo, struct board *b)  				      FBINFO_HWACCEL_FILLRECT |  /* And fillrect */  				      FBINFO_HWACCEL_IMAGEBLIT | /* And imageblit */  				      FBINFO_HWACCEL_XPAN |      /* And we support both horizontal */ -				      FBINFO_HWACCEL_YPAN;       /* And vertical panning */ +				      FBINFO_HWACCEL_YPAN |      /* And vertical panning */ +				      FBINFO_READS_FAST;  	minfo->video.len_usable &= PAGE_MASK;  	fb_alloc_cmap(&minfo->fbcon.cmap, 256, 1); @@ -1893,14 +1894,12 @@ static int initMatrox2(struct matrox_fb_info *minfo, struct board *b)  	if (register_framebuffer(&minfo->fbcon) < 0) {  		goto failVideoIO;  	} -	printk("fb%d: %s frame buffer device\n", -	       minfo->fbcon.node, minfo->fbcon.fix.id); +	fb_info(&minfo->fbcon, "%s frame buffer device\n", minfo->fbcon.fix.id);  	/* there is no console on this fb... but we have to initialize hardware  	 * until someone tells me what is proper thing to do */  	if (!minfo->initialized) { -		printk(KERN_INFO "fb%d: initializing hardware\n", -		       minfo->fbcon.node); +		fb_info(&minfo->fbcon, "initializing hardware\n");  		/* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var  		 * already before, so register_framebuffer works correctly. */  		vesafb_defined.activate |= FB_ACTIVATE_FORCE; diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/fbdev/matrox/matroxfb_base.h index 11ed57bb704..89a8a89a5eb 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/fbdev/matrox/matroxfb_base.h @@ -307,6 +307,8 @@ struct matrox_accel_data {  #endif  	u_int32_t	m_dwg_rect;  	u_int32_t	m_opmode; +	u_int32_t	m_access; +	u_int32_t	m_pitch;  };  struct v4l2_queryctrl; @@ -696,7 +698,7 @@ void matroxfb_unregister_driver(struct matroxfb_driver* drv);  #define mga_fifo(n)	do {} while ((mga_inl(M_FIFOSTATUS) & 0xFF) < (n)) -#define WaitTillIdle()	do {} while (mga_inl(M_STATUS) & 0x10000) +#define WaitTillIdle()	do { mga_inl(M_STATUS); do {} while (mga_inl(M_STATUS) & 0x10000); } while (0)  /* code speedup */  #ifdef CONFIG_FB_MATROX_MILLENIUM diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/fbdev/matrox/matroxfb_crtc2.c index 02796a4317a..02796a4317a 100644 --- a/drivers/video/matrox/matroxfb_crtc2.c +++ b/drivers/video/fbdev/matrox/matroxfb_crtc2.c diff --git a/drivers/video/matrox/matroxfb_crtc2.h b/drivers/video/fbdev/matrox/matroxfb_crtc2.h index 1005582e843..1005582e843 100644 --- a/drivers/video/matrox/matroxfb_crtc2.h +++ b/drivers/video/fbdev/matrox/matroxfb_crtc2.h diff --git a/drivers/video/matrox/matroxfb_g450.c b/drivers/video/fbdev/matrox/matroxfb_g450.c index cff0546ea6f..cff0546ea6f 100644 --- a/drivers/video/matrox/matroxfb_g450.c +++ b/drivers/video/fbdev/matrox/matroxfb_g450.c diff --git a/drivers/video/matrox/matroxfb_g450.h b/drivers/video/fbdev/matrox/matroxfb_g450.h index 3a3e654444b..3a3e654444b 100644 --- a/drivers/video/matrox/matroxfb_g450.h +++ b/drivers/video/fbdev/matrox/matroxfb_g450.h diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/fbdev/matrox/matroxfb_maven.c index fd289745569..ee41a0f276b 100644 --- a/drivers/video/matrox/matroxfb_maven.c +++ b/drivers/video/fbdev/matrox/matroxfb_maven.c @@ -1295,19 +1295,7 @@ static struct i2c_driver maven_driver={  	.id_table	= maven_id,  }; -static int __init matroxfb_maven_init(void) -{ -	return i2c_add_driver(&maven_driver); -} - -static void __exit matroxfb_maven_exit(void) -{ -	i2c_del_driver(&maven_driver); -} - +module_i2c_driver(maven_driver);  MODULE_AUTHOR("(c) 1999-2002 Petr Vandrovec <vandrove@vc.cvut.cz>");  MODULE_DESCRIPTION("Matrox G200/G400 Matrox MGA-TVO driver");  MODULE_LICENSE("GPL"); -module_init(matroxfb_maven_init); -module_exit(matroxfb_maven_exit); -/* we do not have __setup() yet */ diff --git a/drivers/video/matrox/matroxfb_maven.h b/drivers/video/fbdev/matrox/matroxfb_maven.h index 99eddec9f30..99eddec9f30 100644 --- a/drivers/video/matrox/matroxfb_maven.h +++ b/drivers/video/fbdev/matrox/matroxfb_maven.h diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/fbdev/matrox/matroxfb_misc.c index 9948ca2a304..9948ca2a304 100644 --- a/drivers/video/matrox/matroxfb_misc.c +++ b/drivers/video/fbdev/matrox/matroxfb_misc.c diff --git a/drivers/video/matrox/matroxfb_misc.h b/drivers/video/fbdev/matrox/matroxfb_misc.h index 351c823f1f7..351c823f1f7 100644 --- a/drivers/video/matrox/matroxfb_misc.h +++ b/drivers/video/fbdev/matrox/matroxfb_misc.h diff --git a/drivers/video/maxinefb.c b/drivers/video/fbdev/maxinefb.c index 5cf52d3c8e7..5cf52d3c8e7 100644 --- a/drivers/video/maxinefb.c +++ b/drivers/video/fbdev/maxinefb.c diff --git a/drivers/video/mb862xx/Makefile b/drivers/video/fbdev/mb862xx/Makefile index 5707ed0e31a..5707ed0e31a 100644 --- a/drivers/video/mb862xx/Makefile +++ b/drivers/video/fbdev/mb862xx/Makefile diff --git a/drivers/video/mb862xx/mb862xx-i2c.c b/drivers/video/fbdev/mb862xx/mb862xx-i2c.c index c87e17afb3e..c87e17afb3e 100644 --- a/drivers/video/mb862xx/mb862xx-i2c.c +++ b/drivers/video/fbdev/mb862xx/mb862xx-i2c.c diff --git a/drivers/video/mb862xx/mb862xx_reg.h b/drivers/video/fbdev/mb862xx/mb862xx_reg.h index 9df48b8edc9..9df48b8edc9 100644 --- a/drivers/video/mb862xx/mb862xx_reg.h +++ b/drivers/video/fbdev/mb862xx/mb862xx_reg.h diff --git a/drivers/video/mb862xx/mb862xxfb.h b/drivers/video/fbdev/mb862xx/mb862xxfb.h index 8550630c1e0..8550630c1e0 100644 --- a/drivers/video/mb862xx/mb862xxfb.h +++ b/drivers/video/fbdev/mb862xx/mb862xxfb.h diff --git a/drivers/video/mb862xx/mb862xxfb_accel.c b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c index fe92eed6da7..fe92eed6da7 100644 --- a/drivers/video/mb862xx/mb862xxfb_accel.c +++ b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c diff --git a/drivers/video/mb862xx/mb862xxfb_accel.h b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.h index 96a2dfef0f6..96a2dfef0f6 100644 --- a/drivers/video/mb862xx/mb862xxfb_accel.h +++ b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.h diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c index 91c59c9fb08..0cd4c331851 100644 --- a/drivers/video/mb862xx/mb862xxfbdrv.c +++ b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c @@ -781,7 +781,6 @@ rel_reg:  irqdisp:  	irq_dispose_mapping(par->irq);  fbrel: -	dev_set_drvdata(dev, NULL);  	framebuffer_release(info);  	return ret;  } @@ -814,7 +813,6 @@ static int of_platform_mb862xx_remove(struct platform_device *ofdev)  	iounmap(par->mmio_base);  	iounmap(par->fb_base); -	dev_set_drvdata(&ofdev->dev, NULL);  	release_mem_region(par->res->start, res_size);  	framebuffer_release(fbi);  	return 0; @@ -1157,7 +1155,6 @@ static void mb862xx_pci_remove(struct pci_dev *pdev)  	device_remove_file(&pdev->dev, &dev_attr_dispregs); -	pci_set_drvdata(pdev, NULL);  	unregister_framebuffer(fbi);  	fb_dealloc_cmap(&fbi->cmap); diff --git a/drivers/video/fbdev/mbx/Makefile b/drivers/video/fbdev/mbx/Makefile new file mode 100644 index 00000000000..d7ae5a9bb37 --- /dev/null +++ b/drivers/video/fbdev/mbx/Makefile @@ -0,0 +1,3 @@ +# Makefile for the 2700G controller driver. + +obj-y 			+= mbxfb.o diff --git a/drivers/video/mbx/mbxdebugfs.c b/drivers/video/fbdev/mbx/mbxdebugfs.c index 4449f249b0e..e3bc00a7529 100644 --- a/drivers/video/mbx/mbxdebugfs.c +++ b/drivers/video/fbdev/mbx/mbxdebugfs.c @@ -17,7 +17,7 @@ struct mbxfb_debugfs_data {  static int open_file_generic(struct inode *inode, struct file *file)  { -	file->private_data = inode->u.generic_ip; +	file->private_data = inode->i_private;  	return 0;  } diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/fbdev/mbx/mbxfb.c index 0c1a874ffd2..2bd52ed8832 100644 --- a/drivers/video/mbx/mbxfb.c +++ b/drivers/video/fbdev/mbx/mbxfb.c @@ -877,6 +877,8 @@ static int mbxfb_resume(struct platform_device *dev)  #ifndef CONFIG_FB_MBX_DEBUG  #define mbxfb_debugfs_init(x)	do {} while(0)  #define mbxfb_debugfs_remove(x)	do {} while(0) +#else +#include "mbxdebugfs.c"  #endif  #define res_size(_r) (((_r)->end - (_r)->start) + 1) @@ -890,7 +892,7 @@ static int mbxfb_probe(struct platform_device *dev)  	dev_dbg(&dev->dev, "mbxfb_probe\n"); -	pdata = dev->dev.platform_data; +	pdata = dev_get_platdata(&dev->dev);  	if (!pdata) {  		dev_err(&dev->dev, "platform data is required\n");  		return -EINVAL; @@ -976,7 +978,7 @@ static int mbxfb_probe(struct platform_device *dev)  	platform_set_drvdata(dev, fbi); -	printk(KERN_INFO "fb%d: mbx frame buffer device\n", fbi->node); +	fb_info(fbi, "mbx frame buffer device\n");  	if (mfbi->platform_probe)  		mfbi->platform_probe(fbi); diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/fbdev/mbx/reg_bits.h index 5f14b4befd7..5f14b4befd7 100644 --- a/drivers/video/mbx/reg_bits.h +++ b/drivers/video/fbdev/mbx/reg_bits.h diff --git a/drivers/video/mbx/regs.h b/drivers/video/fbdev/mbx/regs.h index 063099d4883..063099d4883 100644 --- a/drivers/video/mbx/regs.h +++ b/drivers/video/fbdev/mbx/regs.h diff --git a/drivers/video/metronomefb.c b/drivers/video/fbdev/metronomefb.c index f30150d71be..195cc2db4c2 100644 --- a/drivers/video/metronomefb.c +++ b/drivers/video/fbdev/metronomefb.c @@ -690,7 +690,8 @@ static int metronomefb_probe(struct platform_device *dev)  		goto err_csum_table;  	} -	if (board->setup_irq(info)) +	retval = board->setup_irq(info); +	if (retval)  		goto err_csum_table;  	retval = metronome_init_regs(par); @@ -769,23 +770,11 @@ static struct platform_driver metronomefb_driver = {  		.name	= "metronomefb",  	},  }; - -static int __init metronomefb_init(void) -{ -	return platform_driver_register(&metronomefb_driver); -} - -static void __exit metronomefb_exit(void) -{ -	platform_driver_unregister(&metronomefb_driver); -} +module_platform_driver(metronomefb_driver);  module_param(user_wfm_size, uint, 0);  MODULE_PARM_DESC(user_wfm_size, "Set custom waveform size"); -module_init(metronomefb_init); -module_exit(metronomefb_exit); -  MODULE_DESCRIPTION("fbdev driver for Metronome controller");  MODULE_AUTHOR("Jaya Kumar");  MODULE_LICENSE("GPL"); diff --git a/drivers/video/fbdev/mmp/Kconfig b/drivers/video/fbdev/mmp/Kconfig new file mode 100644 index 00000000000..f56a7e2e813 --- /dev/null +++ b/drivers/video/fbdev/mmp/Kconfig @@ -0,0 +1,11 @@ +menuconfig MMP_DISP +        tristate "Marvell MMP Display Subsystem support" +        depends on CPU_PXA910 || CPU_MMP2 +        help +	  Marvell Display Subsystem support. + +if MMP_DISP +source "drivers/video/fbdev/mmp/hw/Kconfig" +source "drivers/video/fbdev/mmp/panel/Kconfig" +source "drivers/video/fbdev/mmp/fb/Kconfig" +endif diff --git a/drivers/video/mmp/Makefile b/drivers/video/fbdev/mmp/Makefile index a014cb358bf..a014cb358bf 100644 --- a/drivers/video/mmp/Makefile +++ b/drivers/video/fbdev/mmp/Makefile diff --git a/drivers/video/mmp/core.c b/drivers/video/fbdev/mmp/core.c index 84de2632857..b563b920f15 100644 --- a/drivers/video/mmp/core.c +++ b/drivers/video/fbdev/mmp/core.c @@ -30,7 +30,7 @@ static struct mmp_overlay *path_get_overlay(struct mmp_path *path,  {  	if (path && overlay_id < path->overlay_num)  		return &path->overlays[overlay_id]; -	return 0; +	return NULL;  }  static int path_check_status(struct mmp_path *path) @@ -173,7 +173,7 @@ struct mmp_path *mmp_register_path(struct mmp_path_info *info)  		+ sizeof(struct mmp_overlay) * info->overlay_num;  	path = kzalloc(size, GFP_KERNEL);  	if (!path) -		goto failed; +		return NULL;  	/* path set */  	mutex_init(&path->access_ok); @@ -219,11 +219,6 @@ struct mmp_path *mmp_register_path(struct mmp_path_info *info)  	mutex_unlock(&disp_lock);  	return path; - -failed: -	kfree(path); -	mutex_unlock(&disp_lock); -	return NULL;  }  EXPORT_SYMBOL_GPL(mmp_register_path); diff --git a/drivers/video/mmp/fb/Kconfig b/drivers/video/fbdev/mmp/fb/Kconfig index 9b0141f105f..9b0141f105f 100644 --- a/drivers/video/mmp/fb/Kconfig +++ b/drivers/video/fbdev/mmp/fb/Kconfig diff --git a/drivers/video/mmp/fb/Makefile b/drivers/video/fbdev/mmp/fb/Makefile index 709fd1f76ab..709fd1f76ab 100644 --- a/drivers/video/mmp/fb/Makefile +++ b/drivers/video/fbdev/mmp/fb/Makefile diff --git a/drivers/video/mmp/fb/mmpfb.c b/drivers/video/fbdev/mmp/fb/mmpfb.c index 4ab95b8daed..910fcc6ecec 100644 --- a/drivers/video/mmp/fb/mmpfb.c +++ b/drivers/video/fbdev/mmp/fb/mmpfb.c @@ -392,12 +392,29 @@ static int var_update(struct fb_info *info)  	return 0;  } +static void mmpfb_set_win(struct fb_info *info) +{ +	struct mmpfb_info *fbi = info->par; +	struct fb_var_screeninfo *var = &info->var; +	struct mmp_win win; +	u32 stride; + +	memset(&win, 0, sizeof(win)); +	win.xsrc = win.xdst = fbi->mode.xres; +	win.ysrc = win.ydst = fbi->mode.yres; +	win.pix_fmt = fbi->pix_fmt; +	stride = pixfmt_to_stride(win.pix_fmt); +	win.pitch[0] = var->xres_virtual * stride; +	win.pitch[1] = win.pitch[2] = +		(stride == 1) ? (var->xres_virtual >> 1) : 0; +	mmp_overlay_set_win(fbi->overlay, &win); +} +  static int mmpfb_set_par(struct fb_info *info)  {  	struct mmpfb_info *fbi = info->par;  	struct fb_var_screeninfo *var = &info->var;  	struct mmp_addr addr; -	struct mmp_win win;  	struct mmp_mode mode;  	int ret; @@ -409,11 +426,8 @@ static int mmpfb_set_par(struct fb_info *info)  	fbmode_to_mmpmode(&mode, &fbi->mode, fbi->output_fmt);  	mmp_path_set_mode(fbi->path, &mode); -	memset(&win, 0, sizeof(win)); -	win.xsrc = win.xdst = fbi->mode.xres; -	win.ysrc = win.ydst = fbi->mode.yres; -	win.pix_fmt = fbi->pix_fmt; -	mmp_overlay_set_win(fbi->overlay, &win); +	/* set window related info */ +	mmpfb_set_win(info);  	/* set address always */  	memset(&addr, 0, sizeof(addr)); @@ -427,16 +441,12 @@ static int mmpfb_set_par(struct fb_info *info)  static void mmpfb_power(struct mmpfb_info *fbi, int power)  {  	struct mmp_addr addr; -	struct mmp_win win;  	struct fb_var_screeninfo *var = &fbi->fb_info->var;  	/* for power on, always set address/window again */  	if (power) { -		memset(&win, 0, sizeof(win)); -		win.xsrc = win.xdst = fbi->mode.xres; -		win.ysrc = win.ydst = fbi->mode.yres; -		win.pix_fmt = fbi->pix_fmt; -		mmp_overlay_set_win(fbi->overlay, &win); +		/* set window related info */ +		mmpfb_set_win(fbi->fb_info);  		/* set address always */  		memset(&addr, 0, sizeof(addr)); @@ -544,8 +554,8 @@ static void fb_info_clear(struct fb_info *info)  static int mmpfb_probe(struct platform_device *pdev)  {  	struct mmp_buffer_driver_mach_info *mi; -	struct fb_info *info = 0; -	struct mmpfb_info *fbi = 0; +	struct fb_info *info; +	struct mmpfb_info *fbi;  	int ret, modes_num;  	mi = pdev->dev.platform_data; @@ -559,10 +569,6 @@ static int mmpfb_probe(struct platform_device *pdev)  	if (info == NULL)  		return -ENOMEM;  	fbi = info->par; -	if (!fbi) { -		ret = -EINVAL; -		goto failed; -	}  	/* init fb */  	fbi->fb_info = info; @@ -657,7 +663,6 @@ failed_free_buff:  		fbi->fb_start_dma);  failed_destroy_mutex:  	mutex_destroy(&fbi->access_ok); -failed:  	dev_err(fbi->dev, "mmp-fb: frame buffer device init failed\n");  	framebuffer_release(info); diff --git a/drivers/video/mmp/fb/mmpfb.h b/drivers/video/fbdev/mmp/fb/mmpfb.h index 88c23c10a9e..88c23c10a9e 100644 --- a/drivers/video/mmp/fb/mmpfb.h +++ b/drivers/video/fbdev/mmp/fb/mmpfb.h diff --git a/drivers/video/mmp/hw/Kconfig b/drivers/video/fbdev/mmp/hw/Kconfig index 02f109a20cd..c735d133895 100644 --- a/drivers/video/mmp/hw/Kconfig +++ b/drivers/video/fbdev/mmp/hw/Kconfig @@ -2,12 +2,12 @@ if MMP_DISP  config MMP_DISP_CONTROLLER  	bool "mmp display controller hw support" -	depends on CPU_PXA910 || CPU_MMP2 || CPU_MMP3 || CPU_PXA988 +	depends on CPU_PXA910 || CPU_MMP2  	default n  	help  		Marvell MMP display hw controller support -		this controller is used on Marvell PXA910, -		MMP2, MMP3, PXA988 chips +		this controller is used on Marvell PXA910 and +		MMP2 chips  config MMP_DISP_SPI  	bool "mmp display controller spi port" diff --git a/drivers/video/mmp/hw/Makefile b/drivers/video/fbdev/mmp/hw/Makefile index 0000a714fed..0000a714fed 100644 --- a/drivers/video/mmp/hw/Makefile +++ b/drivers/video/fbdev/mmp/hw/Makefile diff --git a/drivers/video/mmp/hw/mmp_ctrl.c b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c index 75dca19bf21..8621a9f2bdc 100644 --- a/drivers/video/mmp/hw/mmp_ctrl.c +++ b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c @@ -53,15 +53,14 @@ static irqreturn_t ctrl_handle_irq(int irq, void *dev_id)  		tmp = readl_relaxed(ctrl->reg_base + SPU_IRQ_ISR);  		if (tmp & isr)  			writel_relaxed(~isr, ctrl->reg_base + SPU_IRQ_ISR); -	} while ((isr = readl(ctrl->reg_base + SPU_IRQ_ISR)) & imask); +	} while ((isr = readl_relaxed(ctrl->reg_base + SPU_IRQ_ISR)) & imask);  	return IRQ_HANDLED;  }  static u32 fmt_to_reg(struct mmp_overlay *overlay, int pix_fmt)  { -	u32 link_config = path_to_path_plat(overlay->path)->link_config; -	u32 rbswap, uvswap = 0, yuvswap = 0, +	u32 rbswap = 0, uvswap = 0, yuvswap = 0,  		csc_en = 0, val = 0,  		vid = overlay_is_vid(overlay); @@ -71,27 +70,23 @@ static u32 fmt_to_reg(struct mmp_overlay *overlay, int pix_fmt)  	case PIXFMT_RGB888PACK:  	case PIXFMT_RGB888UNPACK:  	case PIXFMT_RGBA888: -		rbswap = !(link_config & 0x1); +		rbswap = 1;  		break;  	case PIXFMT_VYUY:  	case PIXFMT_YVU422P:  	case PIXFMT_YVU420P: -		rbswap = link_config & 0x1;  		uvswap = 1;  		break;  	case PIXFMT_YUYV: -		rbswap = link_config & 0x1;  		yuvswap = 1;  		break;  	default: -		rbswap = link_config & 0x1;  		break;  	}  	switch (pix_fmt) {  	case PIXFMT_RGB565:  	case PIXFMT_BGR565: -		val = 0;  		break;  	case PIXFMT_RGB1555:  	case PIXFMT_BGR1555: @@ -147,17 +142,27 @@ static void dmafetch_set_fmt(struct mmp_overlay *overlay)  static void overlay_set_win(struct mmp_overlay *overlay, struct mmp_win *win)  {  	struct lcd_regs *regs = path_regs(overlay->path); -	u32 pitch;  	/* assert win supported */  	memcpy(&overlay->win, win, sizeof(struct mmp_win));  	mutex_lock(&overlay->access_ok); -	pitch = win->xsrc * pixfmt_to_stride(win->pix_fmt); -	writel_relaxed(pitch, ®s->g_pitch); -	writel_relaxed((win->ysrc << 16) | win->xsrc, ®s->g_size); -	writel_relaxed((win->ydst << 16) | win->xdst, ®s->g_size_z); -	writel_relaxed(0, ®s->g_start); + +	if (overlay_is_vid(overlay)) { +		writel_relaxed(win->pitch[0], ®s->v_pitch_yc); +		writel_relaxed(win->pitch[2] << 16 | +				win->pitch[1], ®s->v_pitch_uv); + +		writel_relaxed((win->ysrc << 16) | win->xsrc, ®s->v_size); +		writel_relaxed((win->ydst << 16) | win->xdst, ®s->v_size_z); +		writel_relaxed(win->ypos << 16 | win->xpos, ®s->v_start); +	} else { +		writel_relaxed(win->pitch[0], ®s->g_pitch); + +		writel_relaxed((win->ysrc << 16) | win->xsrc, ®s->g_size); +		writel_relaxed((win->ydst << 16) | win->xdst, ®s->g_size_z); +		writel_relaxed(win->ypos << 16 | win->xpos, ®s->g_start); +	}  	dmafetch_set_fmt(overlay);  	mutex_unlock(&overlay->access_ok); @@ -239,7 +244,13 @@ static int overlay_set_addr(struct mmp_overlay *overlay, struct mmp_addr *addr)  	/* FIXME: assert addr supported */  	memcpy(&overlay->addr, addr, sizeof(struct mmp_addr)); -	writel(addr->phys[0], ®s->g_0); + +	if (overlay_is_vid(overlay)) { +		writel_relaxed(addr->phys[0], ®s->v_y0); +		writel_relaxed(addr->phys[1], ®s->v_u0); +		writel_relaxed(addr->phys[2], ®s->v_v0); +	} else +		writel_relaxed(addr->phys[0], ®s->g_0);  	return overlay->addr.phys[0];  } @@ -248,7 +259,8 @@ static void path_set_mode(struct mmp_path *path, struct mmp_mode *mode)  {  	struct lcd_regs *regs = path_regs(path);  	u32 total_x, total_y, vsync_ctrl, tmp, sclk_src, sclk_div, -		link_config = path_to_path_plat(path)->link_config; +		link_config = path_to_path_plat(path)->link_config, +		dsi_rbswap = path_to_path_plat(path)->link_config;  	/* FIXME: assert videomode supported */  	memcpy(&path->mode, mode, sizeof(struct mmp_mode)); @@ -263,6 +275,12 @@ static void path_set_mode(struct mmp_path *path, struct mmp_mode *mode)  	tmp |= CFG_DUMB_ENA(1);  	writel_relaxed(tmp, ctrl_regs(path) + intf_ctrl(path->id)); +	/* interface rb_swap setting */ +	tmp = readl_relaxed(ctrl_regs(path) + intf_rbswap_ctrl(path->id)) & +		(~(CFG_INTFRBSWAP_MASK)); +	tmp |= dsi_rbswap & CFG_INTFRBSWAP_MASK; +	writel_relaxed(tmp, ctrl_regs(path) + intf_rbswap_ctrl(path->id)); +  	writel_relaxed((mode->yres << 16) | mode->xres, ®s->screen_active);  	writel_relaxed((mode->left_margin << 16) | mode->right_margin,  		®s->screen_h_porch); @@ -370,20 +388,12 @@ static void path_set_default(struct mmp_path *path)  	 * bus arbiter for faster read if not tv path;  	 * 2.enable horizontal smooth filter;  	 */ -	if (PATH_PN == path->id) { -		mask = CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK -			| CFG_ARBFAST_ENA(1); -		tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id)); -		tmp |= mask; -		writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id)); -	} else if (PATH_TV == path->id) { -		mask = CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK -			| CFG_ARBFAST_ENA(1); -		tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id)); -		tmp &= ~mask; -		tmp |= CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK; -		writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id)); -	} +	mask = CFG_GRA_HSMOOTH_MASK | CFG_DMA_HSMOOTH_MASK | CFG_ARBFAST_ENA(1); +	tmp = readl_relaxed(ctrl_regs(path) + dma_ctrl(0, path->id)); +	tmp |= mask; +	if (PATH_TV == path->id) +		tmp &= ~CFG_ARBFAST_ENA(1); +	writel_relaxed(tmp, ctrl_regs(path) + dma_ctrl(0, path->id));  }  static int path_init(struct mmphw_path_plat *path_plat, @@ -419,6 +429,7 @@ static int path_init(struct mmphw_path_plat *path_plat,  	path_plat->path = path;  	path_plat->path_config = config->path_config;  	path_plat->link_config = config->link_config; +	path_plat->dsi_rbswap = config->dsi_rbswap;  	path_set_default(path);  	kfree(path_info); @@ -514,7 +525,7 @@ static int mmphw_probe(struct platform_device *pdev)  	if (IS_ERR(ctrl->clk)) {  		dev_err(ctrl->dev, "unable to get clk %s\n", mi->clk_name);  		ret = -ENOENT; -		goto failed_get_clk; +		goto failed;  	}  	clk_prepare_enable(ctrl->clk); @@ -551,21 +562,8 @@ failed_path_init:  		path_deinit(path_plat);  	} -	if (ctrl->clk) { -		devm_clk_put(ctrl->dev, ctrl->clk); -		clk_disable_unprepare(ctrl->clk); -	} -failed_get_clk: -	devm_free_irq(ctrl->dev, ctrl->irq, ctrl); +	clk_disable_unprepare(ctrl->clk);  failed: -	if (ctrl) { -		if (ctrl->reg_base) -			devm_iounmap(ctrl->dev, ctrl->reg_base); -		devm_release_mem_region(ctrl->dev, res->start, -				resource_size(res)); -		devm_kfree(ctrl->dev, ctrl); -	} -  	dev_err(&pdev->dev, "device init failed\n");  	return ret; diff --git a/drivers/video/mmp/hw/mmp_ctrl.h b/drivers/video/fbdev/mmp/hw/mmp_ctrl.h index edd2002b0e9..56fdeab3435 100644 --- a/drivers/video/mmp/hw/mmp_ctrl.h +++ b/drivers/video/fbdev/mmp/hw/mmp_ctrl.h @@ -163,13 +163,11 @@ struct lcd_regs {  #define LCD_SCLK(path) ((PATH_PN == path->id) ? LCD_CFG_SCLK_DIV :\  	((PATH_TV == path->id) ? LCD_TCLK_DIV : LCD_PN2_SCLK_DIV)) +#define intf_rbswap_ctrl(id)	((id) ? (((id) & 1) ? LCD_TVIF_CTRL : \ +				PN2_IOPAD_CONTROL) : LCD_TOP_CTRL)  /* dither configure */ -#ifdef CONFIG_CPU_PXA988 -#define LCD_DITHER_CTRL				(0x01EC) -#else  #define LCD_DITHER_CTRL				(0x00A0) -#endif  #define DITHER_TBL_INDEX_SEL(s)		((s) << 16)  #define DITHER_MODE2(m)				((m) << 12) @@ -184,15 +182,6 @@ struct lcd_regs {  #define DITHER_EN1					(1)  /* dither table data was fixed by video bpp of input and output*/ -#ifdef CONFIG_CPU_PXA988 -#define DITHER_TB_4X4_INDEX0		(0x6e4ca280) -#define DITHER_TB_4X4_INDEX1		(0x5d7f91b3) -#define DITHER_TB_4X8_INDEX0		(0xb391a280) -#define DITHER_TB_4X8_INDEX1		(0x7f5d6e4c) -#define DITHER_TB_4X8_INDEX2		(0x80a291b3) -#define DITHER_TB_4X8_INDEX3		(0x4c6e5d7f) -#define LCD_DITHER_TBL_DATA		(0x01F0) -#else  #define DITHER_TB_4X4_INDEX0		(0x3b19f7d5)  #define DITHER_TB_4X4_INDEX1		(0x082ac4e6)  #define DITHER_TB_4X8_INDEX0		(0xf7d508e6) @@ -200,7 +189,6 @@ struct lcd_regs {  #define DITHER_TB_4X8_INDEX2		(0xc4e6d5f7)  #define DITHER_TB_4X8_INDEX3		(0x082a193b)  #define LCD_DITHER_TBL_DATA		(0x00A4) -#endif  /* Video Frame 0&1 start address registers */  #define	LCD_SPU_DMA_START_ADDR_Y0	0x00C0 @@ -615,6 +603,8 @@ struct lcd_regs {  #define LCD_SPU_DUMB_CTRL			0x01B8  #define	 CFG_DUMBMODE(mode)			((mode)<<28)  #define	 CFG_DUMBMODE_MASK			0xF0000000 +#define	 CFG_INTFRBSWAP(mode)			((mode)<<24) +#define	 CFG_INTFRBSWAP_MASK			0x0F000000  #define	 CFG_LCDGPIO_O(data)			((data)<<20)  #define	 CFG_LCDGPIO_O_MASK			0x0FF00000  #define	 CFG_LCDGPIO_ENA(gpio)			((gpio)<<12) @@ -929,16 +919,9 @@ struct lcd_regs {  #define LCD_PN2_SQULN2_CTRL			(0x02F0)  #define ALL_LAYER_ALPHA_SEL			(0x02F4) -/* pxa988 has different MASTER_CTRL from MMP3/MMP2 */ -#ifdef CONFIG_CPU_PXA988 -#define TIMING_MASTER_CONTROL			(0x01F4) -#define MASTER_ENH(id)				(1 << ((id) + 5)) -#define MASTER_ENV(id)				(1 << ((id) + 6)) -#else  #define TIMING_MASTER_CONTROL			(0x02F8)  #define MASTER_ENH(id)				(1 << (id))  #define MASTER_ENV(id)				(1 << ((id) + 4)) -#endif  #define DSI_START_SEL_SHIFT(id)		(((id) << 1) + 8)  #define timing_master_config(path, dsi_id, lcd_id) \ @@ -1308,19 +1291,8 @@ struct dsi_regs {  #define	DSI_PHY_TIME_3_CFG_CSR_TIME_REQRDY_MASK		(0xff)  #define	DSI_PHY_TIME_3_CFG_CSR_TIME_REQRDY_SHIFT	0 -/* - * DSI timings - * PXA988 has diffrent ESC CLK with MMP2/MMP3 - * it will be used in dsi_set_dphy() in pxa688_phy.c - * as low power mode clock. - */ -#ifdef CONFIG_CPU_PXA988 -#define DSI_ESC_CLK				52  /* Unit: Mhz */ -#define DSI_ESC_CLK_T				19  /* Unit: ns */ -#else  #define DSI_ESC_CLK				66  /* Unit: Mhz */  #define DSI_ESC_CLK_T				15  /* Unit: ns */ -#endif  /* LVDS */  /* LVDS_PHY_CTRL */ @@ -1427,6 +1399,7 @@ struct mmphw_path_plat {  	struct mmp_path *path;  	u32 path_config;  	u32 link_config; +	u32 dsi_rbswap;  };  /* mmp ctrl describes mmp controller related info */ diff --git a/drivers/video/mmp/hw/mmp_spi.c b/drivers/video/fbdev/mmp/hw/mmp_spi.c index e62ca7bf0d5..e62ca7bf0d5 100644 --- a/drivers/video/mmp/hw/mmp_spi.c +++ b/drivers/video/fbdev/mmp/hw/mmp_spi.c diff --git a/drivers/video/mmp/panel/Kconfig b/drivers/video/fbdev/mmp/panel/Kconfig index 4b2c4f457b1..4b2c4f457b1 100644 --- a/drivers/video/mmp/panel/Kconfig +++ b/drivers/video/fbdev/mmp/panel/Kconfig diff --git a/drivers/video/mmp/panel/Makefile b/drivers/video/fbdev/mmp/panel/Makefile index 2f91611c7e5..2f91611c7e5 100644 --- a/drivers/video/mmp/panel/Makefile +++ b/drivers/video/fbdev/mmp/panel/Makefile diff --git a/drivers/video/mmp/panel/tpo_tj032md01bw.c b/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c index 998978b08f5..998978b08f5 100644 --- a/drivers/video/mmp/panel/tpo_tj032md01bw.c +++ b/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c diff --git a/drivers/video/msm/Makefile b/drivers/video/fbdev/msm/Makefile index 802d6ae523f..802d6ae523f 100644 --- a/drivers/video/msm/Makefile +++ b/drivers/video/fbdev/msm/Makefile diff --git a/drivers/video/msm/mddi.c b/drivers/video/fbdev/msm/mddi.c index e0f8011a3c4..e0f8011a3c4 100644 --- a/drivers/video/msm/mddi.c +++ b/drivers/video/fbdev/msm/mddi.c diff --git a/drivers/video/msm/mddi_client_dummy.c b/drivers/video/fbdev/msm/mddi_client_dummy.c index f1b0dfcc971..f1b0dfcc971 100644 --- a/drivers/video/msm/mddi_client_dummy.c +++ b/drivers/video/fbdev/msm/mddi_client_dummy.c diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/fbdev/msm/mddi_client_nt35399.c index f96df32e550..f96df32e550 100644 --- a/drivers/video/msm/mddi_client_nt35399.c +++ b/drivers/video/fbdev/msm/mddi_client_nt35399.c diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/fbdev/msm/mddi_client_toshiba.c index 061d7dfebbf..061d7dfebbf 100644 --- a/drivers/video/msm/mddi_client_toshiba.c +++ b/drivers/video/fbdev/msm/mddi_client_toshiba.c diff --git a/drivers/video/msm/mddi_hw.h b/drivers/video/fbdev/msm/mddi_hw.h index 45cc01fc1e7..45cc01fc1e7 100644 --- a/drivers/video/msm/mddi_hw.h +++ b/drivers/video/fbdev/msm/mddi_hw.h diff --git a/drivers/video/msm/mdp.c b/drivers/video/fbdev/msm/mdp.c index 113c7876c85..113c7876c85 100644 --- a/drivers/video/msm/mdp.c +++ b/drivers/video/fbdev/msm/mdp.c diff --git a/drivers/video/msm/mdp_csc_table.h b/drivers/video/fbdev/msm/mdp_csc_table.h index d1cde30ead5..d1cde30ead5 100644 --- a/drivers/video/msm/mdp_csc_table.h +++ b/drivers/video/fbdev/msm/mdp_csc_table.h diff --git a/drivers/video/msm/mdp_hw.h b/drivers/video/fbdev/msm/mdp_hw.h index 35848d74100..35848d74100 100644 --- a/drivers/video/msm/mdp_hw.h +++ b/drivers/video/fbdev/msm/mdp_hw.h diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/fbdev/msm/mdp_ppp.c index be6079cdfbb..be6079cdfbb 100644 --- a/drivers/video/msm/mdp_ppp.c +++ b/drivers/video/fbdev/msm/mdp_ppp.c diff --git a/drivers/video/msm/mdp_scale_tables.c b/drivers/video/fbdev/msm/mdp_scale_tables.c index 604783b2e17..604783b2e17 100644 --- a/drivers/video/msm/mdp_scale_tables.c +++ b/drivers/video/fbdev/msm/mdp_scale_tables.c diff --git a/drivers/video/msm/mdp_scale_tables.h b/drivers/video/fbdev/msm/mdp_scale_tables.h index 34077b1af60..34077b1af60 100644 --- a/drivers/video/msm/mdp_scale_tables.h +++ b/drivers/video/fbdev/msm/mdp_scale_tables.h diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/fbdev/msm/msm_fb.c index 1374803fbcd..1374803fbcd 100644 --- a/drivers/video/msm/msm_fb.c +++ b/drivers/video/fbdev/msm/msm_fb.c diff --git a/drivers/video/mx3fb.c b/drivers/video/fbdev/mx3fb.c index cfdb380ec81..c645a0a0c34 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/fbdev/mx3fb.c @@ -27,6 +27,7 @@  #include <linux/clk.h>  #include <linux/mutex.h>  #include <linux/dma/ipu-dma.h> +#include <linux/backlight.h>  #include <linux/platform_data/dma-imx.h>  #include <linux/platform_data/video-mx3fb.h> @@ -241,6 +242,7 @@ struct mx3fb_data {  	void __iomem		*reg_base;  	spinlock_t		lock;  	struct device		*dev; +	struct backlight_device	*bl;  	uint32_t		h_start_width;  	uint32_t		v_start_width; @@ -271,6 +273,71 @@ struct mx3fb_info {  	struct fb_var_screeninfo	cur_var; /* current var info */  }; +static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value); +static u32 sdc_get_brightness(struct mx3fb_data *mx3fb); + +static int mx3fb_bl_get_brightness(struct backlight_device *bl) +{ +	struct mx3fb_data *fbd = bl_get_data(bl); + +	return sdc_get_brightness(fbd); +} + +static int mx3fb_bl_update_status(struct backlight_device *bl) +{ +	struct mx3fb_data *fbd = bl_get_data(bl); +	int brightness = bl->props.brightness; + +	if (bl->props.power != FB_BLANK_UNBLANK) +		brightness = 0; +	if (bl->props.fb_blank != FB_BLANK_UNBLANK) +		brightness = 0; + +	fbd->backlight_level = (fbd->backlight_level & ~0xFF) | brightness; + +	sdc_set_brightness(fbd, fbd->backlight_level); + +	return 0; +} + +static const struct backlight_ops mx3fb_lcdc_bl_ops = { +	.update_status = mx3fb_bl_update_status, +	.get_brightness = mx3fb_bl_get_brightness, +}; + +static void mx3fb_init_backlight(struct mx3fb_data *fbd) +{ +	struct backlight_properties props; +	struct backlight_device	*bl; + +	if (fbd->bl) +		return; + +	memset(&props, 0, sizeof(struct backlight_properties)); +	props.max_brightness = 0xff; +	props.type = BACKLIGHT_RAW; +	sdc_set_brightness(fbd, fbd->backlight_level); + +	bl = backlight_device_register("mx3fb-bl", fbd->dev, fbd, +				       &mx3fb_lcdc_bl_ops, &props); +	if (IS_ERR(bl)) { +		dev_err(fbd->dev, "error %ld on backlight register\n", +				PTR_ERR(bl)); +		return; +	} + +	fbd->bl = bl; +	bl->props.power = FB_BLANK_UNBLANK; +	bl->props.fb_blank = FB_BLANK_UNBLANK; +	bl->props.brightness = mx3fb_bl_get_brightness(bl); +} + +static void mx3fb_exit_backlight(struct mx3fb_data *fbd) +{ +	if (fbd->bl) +		backlight_device_unregister(fbd->bl); +} +  static void mx3fb_dma_done(void *);  /* Used fb-mode and bpp. Can be set on kernel command line, therefore file-static. */ @@ -628,6 +695,16 @@ static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t a  	return 0;  } +static u32 sdc_get_brightness(struct mx3fb_data *mx3fb) +{ +	u32 brightness; + +	brightness = mx3fb_read_reg(mx3fb, SDC_PWM_CTRL); +	brightness = (brightness >> 16) & 0xFF; + +	return brightness; +} +  static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value)  {  	dev_dbg(mx3fb->dev, "%s: value = %d\n", __func__, value); @@ -1263,7 +1340,7 @@ static int mx3fb_map_video_memory(struct fb_info *fbi, unsigned int mem_len,  	fbi->screen_base = dma_alloc_writecombine(fbi->device,  						  mem_len, -						  &addr, GFP_DMA); +						  &addr, GFP_DMA | GFP_KERNEL);  	if (!fbi->screen_base) {  		dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", @@ -1354,7 +1431,7 @@ static struct fb_info *mx3fb_init_fbinfo(struct device *dev, struct fb_ops *ops)  static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan)  {  	struct device *dev = mx3fb->dev; -	struct mx3fb_platform_data *mx3fb_pdata = dev->platform_data; +	struct mx3fb_platform_data *mx3fb_pdata = dev_get_platdata(dev);  	const char *name = mx3fb_pdata->name;  	unsigned int irq;  	struct fb_info *fbi; @@ -1462,7 +1539,7 @@ static bool chan_filter(struct dma_chan *chan, void *arg)  		return false;  	dev = rq->mx3fb->dev; -	mx3fb_pdata = dev->platform_data; +	mx3fb_pdata = dev_get_platdata(dev);  	return rq->id == chan->chan_id &&  		mx3fb_pdata->dma_dev == chan->device->dev; @@ -1496,7 +1573,7 @@ static int mx3fb_probe(struct platform_device *pdev)  	if (!sdc_reg)  		return -EINVAL; -	mx3fb = kzalloc(sizeof(*mx3fb), GFP_KERNEL); +	mx3fb = devm_kzalloc(&pdev->dev, sizeof(*mx3fb), GFP_KERNEL);  	if (!mx3fb)  		return -ENOMEM; @@ -1534,6 +1611,8 @@ static int mx3fb_probe(struct platform_device *pdev)  	if (ret < 0)  		goto eisdc0; +	mx3fb_init_backlight(mx3fb); +  	return 0;  eisdc0: @@ -1542,7 +1621,6 @@ ersdc0:  	dmaengine_put();  	iounmap(mx3fb->reg_base);  eremap: -	kfree(mx3fb);  	dev_err(dev, "mx3fb: failed to register fb\n");  	return ret;  } @@ -1557,11 +1635,12 @@ static int mx3fb_remove(struct platform_device *dev)  	chan = &mx3_fbi->idmac_channel->dma_chan;  	release_fbi(fbi); +	mx3fb_exit_backlight(mx3fb); +  	dma_release_channel(chan);  	dmaengine_put();  	iounmap(mx3fb->reg_base); -	kfree(mx3fb);  	return 0;  } diff --git a/drivers/video/mxsfb.c b/drivers/video/fbdev/mxsfb.c index d250ed0f806..accf48a2cce 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/fbdev/mxsfb.c @@ -49,6 +49,7 @@  #include <linux/fb.h>  #include <linux/regulator/consumer.h>  #include <video/of_display_timing.h> +#include <video/of_videomode.h>  #include <video/videomode.h>  #define REG_SET	4 @@ -297,7 +298,7 @@ static int mxsfb_check_var(struct fb_var_screeninfo *var,  		}  		break;  	default: -		pr_debug("Unsupported colour depth: %u\n", var->bits_per_pixel); +		pr_err("Unsupported colour depth: %u\n", var->bits_per_pixel);  		return -EINVAL;  	} @@ -426,7 +427,7 @@ static int mxsfb_set_par(struct fb_info *fb_info)  		ctrl |= CTRL_SET_WORD_LENGTH(3);  		switch (host->ld_intf_width) {  		case STMLCDIF_8BIT: -			dev_dbg(&host->pdev->dev, +			dev_err(&host->pdev->dev,  					"Unsupported LCD bus width mapping\n");  			return -EINVAL;  		case STMLCDIF_16BIT: @@ -439,7 +440,7 @@ static int mxsfb_set_par(struct fb_info *fb_info)  		writel(CTRL1_SET_BYTE_PACKAGING(0x7), host->base + LCDC_CTRL1);  		break;  	default: -		dev_dbg(&host->pdev->dev, "Unhandled color depth of %u\n", +		dev_err(&host->pdev->dev, "Unhandled color depth of %u\n",  				fb_info->var.bits_per_pixel);  		return -EINVAL;  	} @@ -589,7 +590,8 @@ static struct fb_ops mxsfb_ops = {  	.fb_imageblit = cfb_imageblit,  }; -static int mxsfb_restore_mode(struct mxsfb_info *host) +static int mxsfb_restore_mode(struct mxsfb_info *host, +			struct fb_videomode *vmode)  {  	struct fb_info *fb_info = &host->fb_info;  	unsigned line_count; @@ -597,7 +599,6 @@ static int mxsfb_restore_mode(struct mxsfb_info *host)  	unsigned long pa, fbsize;  	int bits_per_pixel, ofs;  	u32 transfer_count, vdctrl0, vdctrl2, vdctrl3, vdctrl4, ctrl; -	struct fb_videomode vmode;  	/* Only restore the mode when the controller is running */  	ctrl = readl(host->base + LCDC_CTRL); @@ -611,8 +612,8 @@ static int mxsfb_restore_mode(struct mxsfb_info *host)  	transfer_count = readl(host->base + host->devdata->transfer_count); -	vmode.xres = TRANSFER_COUNT_GET_HCOUNT(transfer_count); -	vmode.yres = TRANSFER_COUNT_GET_VCOUNT(transfer_count); +	vmode->xres = TRANSFER_COUNT_GET_HCOUNT(transfer_count); +	vmode->yres = TRANSFER_COUNT_GET_VCOUNT(transfer_count);  	switch (CTRL_GET_WORD_LENGTH(ctrl)) {  	case 0: @@ -620,6 +621,7 @@ static int mxsfb_restore_mode(struct mxsfb_info *host)  		break;  	case 3:  		bits_per_pixel = 32; +		break;  	case 1:  	default:  		return -EINVAL; @@ -627,40 +629,39 @@ static int mxsfb_restore_mode(struct mxsfb_info *host)  	fb_info->var.bits_per_pixel = bits_per_pixel; -	vmode.pixclock = KHZ2PICOS(clk_get_rate(host->clk) / 1000U); -	vmode.hsync_len = get_hsync_pulse_width(host, vdctrl2); -	vmode.left_margin = GET_HOR_WAIT_CNT(vdctrl3) - vmode.hsync_len; -	vmode.right_margin = VDCTRL2_GET_HSYNC_PERIOD(vdctrl2) - vmode.hsync_len - -		vmode.left_margin - vmode.xres; -	vmode.vsync_len = VDCTRL0_GET_VSYNC_PULSE_WIDTH(vdctrl0); +	vmode->pixclock = KHZ2PICOS(clk_get_rate(host->clk) / 1000U); +	vmode->hsync_len = get_hsync_pulse_width(host, vdctrl2); +	vmode->left_margin = GET_HOR_WAIT_CNT(vdctrl3) - vmode->hsync_len; +	vmode->right_margin = VDCTRL2_GET_HSYNC_PERIOD(vdctrl2) - +		vmode->hsync_len - vmode->left_margin - vmode->xres; +	vmode->vsync_len = VDCTRL0_GET_VSYNC_PULSE_WIDTH(vdctrl0);  	period = readl(host->base + LCDC_VDCTRL1); -	vmode.upper_margin = GET_VERT_WAIT_CNT(vdctrl3) - vmode.vsync_len; -	vmode.lower_margin = period - vmode.vsync_len - vmode.upper_margin - vmode.yres; +	vmode->upper_margin = GET_VERT_WAIT_CNT(vdctrl3) - vmode->vsync_len; +	vmode->lower_margin = period - vmode->vsync_len - +		vmode->upper_margin - vmode->yres; -	vmode.vmode = FB_VMODE_NONINTERLACED; +	vmode->vmode = FB_VMODE_NONINTERLACED; -	vmode.sync = 0; +	vmode->sync = 0;  	if (vdctrl0 & VDCTRL0_HSYNC_ACT_HIGH) -		vmode.sync |= FB_SYNC_HOR_HIGH_ACT; +		vmode->sync |= FB_SYNC_HOR_HIGH_ACT;  	if (vdctrl0 & VDCTRL0_VSYNC_ACT_HIGH) -		vmode.sync |= FB_SYNC_VERT_HIGH_ACT; +		vmode->sync |= FB_SYNC_VERT_HIGH_ACT;  	pr_debug("Reconstructed video mode:\n");  	pr_debug("%dx%d, hsync: %u left: %u, right: %u, vsync: %u, upper: %u, lower: %u\n", -			vmode.xres, vmode.yres, -			vmode.hsync_len, vmode.left_margin, vmode.right_margin, -			vmode.vsync_len, vmode.upper_margin, vmode.lower_margin); -	pr_debug("pixclk: %ldkHz\n", PICOS2KHZ(vmode.pixclock)); - -	fb_add_videomode(&vmode, &fb_info->modelist); +		vmode->xres, vmode->yres, vmode->hsync_len, vmode->left_margin, +		vmode->right_margin, vmode->vsync_len, vmode->upper_margin, +		vmode->lower_margin); +	pr_debug("pixclk: %ldkHz\n", PICOS2KHZ(vmode->pixclock));  	host->ld_intf_width = CTRL_GET_BUS_WIDTH(ctrl);  	host->dotclk_delay = VDCTRL4_GET_DOTCLK_DLY(vdctrl4); -	fb_info->fix.line_length = vmode.xres * (bits_per_pixel >> 3); +	fb_info->fix.line_length = vmode->xres * (bits_per_pixel >> 3);  	pa = readl(host->base + host->devdata->cur_buf); -	fbsize = fb_info->fix.line_length * vmode.yres; +	fbsize = fb_info->fix.line_length * vmode->yres;  	if (pa < fb_info->fix.smem_start)  		return -EINVAL;  	if (pa + fbsize > fb_info->fix.smem_start + fb_info->fix.smem_len) @@ -680,18 +681,17 @@ static int mxsfb_restore_mode(struct mxsfb_info *host)  	return 0;  } -static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host) +static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host, +				struct fb_videomode *vmode)  {  	struct fb_info *fb_info = &host->fb_info;  	struct fb_var_screeninfo *var = &fb_info->var;  	struct device *dev = &host->pdev->dev;  	struct device_node *np = host->pdev->dev.of_node;  	struct device_node *display_np; -	struct device_node *timings_np; -	struct display_timings *timings; +	struct videomode vm;  	u32 width; -	int i; -	int ret = 0; +	int ret;  	display_np = of_parse_phandle(np, "display", 0);  	if (!display_np) { @@ -731,54 +731,35 @@ static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host)  		goto put_display_node;  	} -	timings = of_get_display_timings(display_np); -	if (!timings) { -		dev_err(dev, "failed to get display timings\n"); -		ret = -ENOENT; +	ret = of_get_videomode(display_np, &vm, OF_USE_NATIVE_MODE); +	if (ret) { +		dev_err(dev, "failed to get videomode from DT\n");  		goto put_display_node;  	} -	timings_np = of_find_node_by_name(display_np, -					  "display-timings"); -	if (!timings_np) { -		dev_err(dev, "failed to find display-timings node\n"); -		ret = -ENOENT; +	ret = fb_videomode_from_videomode(&vm, vmode); +	if (ret < 0)  		goto put_display_node; -	} -	for (i = 0; i < of_get_child_count(timings_np); i++) { -		struct videomode vm; -		struct fb_videomode fb_vm; - -		ret = videomode_from_timings(timings, &vm, i); -		if (ret < 0) -			goto put_timings_node; -		ret = fb_videomode_from_videomode(&vm, &fb_vm); -		if (ret < 0) -			goto put_timings_node; - -		if (vm.flags & DISPLAY_FLAGS_DE_HIGH) -			host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT; -		if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) -			host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT; -		fb_add_videomode(&fb_vm, &fb_info->modelist); -	} +	if (vm.flags & DISPLAY_FLAGS_DE_HIGH) +		host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT; +	if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) +		host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT; -put_timings_node: -	of_node_put(timings_np);  put_display_node:  	of_node_put(display_np);  	return ret;  } -static int mxsfb_init_fbinfo(struct mxsfb_info *host) +static int mxsfb_init_fbinfo(struct mxsfb_info *host, +			struct fb_videomode *vmode)  { +	int ret;  	struct fb_info *fb_info = &host->fb_info;  	struct fb_var_screeninfo *var = &fb_info->var;  	dma_addr_t fb_phys;  	void *fb_virt;  	unsigned fb_size; -	int ret;  	fb_info->fbops = &mxsfb_ops;  	fb_info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST; @@ -788,7 +769,7 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host)  	fb_info->fix.visual = FB_VISUAL_TRUECOLOR,  	fb_info->fix.accel = FB_ACCEL_NONE; -	ret = mxsfb_init_fbinfo_dt(host); +	ret = mxsfb_init_fbinfo_dt(host, vmode);  	if (ret)  		return ret; @@ -809,7 +790,7 @@ static int mxsfb_init_fbinfo(struct mxsfb_info *host)  	fb_info->screen_base = fb_virt;  	fb_info->screen_size = fb_info->fix.smem_len = fb_size; -	if (mxsfb_restore_mode(host)) +	if (mxsfb_restore_mode(host, vmode))  		memset(fb_virt, 0, fb_size);  	return 0; @@ -849,7 +830,7 @@ static int mxsfb_probe(struct platform_device *pdev)  	struct resource *res;  	struct mxsfb_info *host;  	struct fb_info *fb_info; -	struct fb_modelist *modelist; +	struct fb_videomode *mode;  	int ret;  	if (of_id) @@ -861,6 +842,11 @@ static int mxsfb_probe(struct platform_device *pdev)  		return -ENOMEM;  	} +	mode = devm_kzalloc(&pdev->dev, sizeof(struct fb_videomode), +			GFP_KERNEL); +	if (mode == NULL) +		return -ENOMEM; +  	host = to_imxfb_host(fb_info);  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -892,15 +878,11 @@ static int mxsfb_probe(struct platform_device *pdev)  		goto fb_release;  	} -	INIT_LIST_HEAD(&fb_info->modelist); - -	ret = mxsfb_init_fbinfo(host); +	ret = mxsfb_init_fbinfo(host, mode);  	if (ret != 0)  		goto fb_release; -	modelist = list_first_entry(&fb_info->modelist, -			struct fb_modelist, list); -	fb_videomode_to_var(&fb_info->var, &modelist->mode); +	fb_videomode_to_var(&fb_info->var, mode);  	/* init the color fields */  	mxsfb_check_var(&fb_info->var, fb_info); @@ -926,7 +908,6 @@ static int mxsfb_probe(struct platform_device *pdev)  fb_destroy:  	if (host->enabled)  		clk_disable_unprepare(host->clk); -	fb_destroy_modelist(&fb_info->modelist);  fb_release:  	framebuffer_release(fb_info); diff --git a/drivers/video/n411.c b/drivers/video/fbdev/n411.c index 935830fea7b..935830fea7b 100644 --- a/drivers/video/n411.c +++ b/drivers/video/fbdev/n411.c diff --git a/drivers/video/neofb.c b/drivers/video/fbdev/neofb.c index 7ef079c146e..44f99a60bb9 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/fbdev/neofb.c @@ -2075,6 +2075,7 @@ static int neofb_probe(struct pci_dev *dev, const struct pci_device_id *id)  	if (!fb_find_mode(&info->var, info, mode_option, NULL, 0,  			info->monspecs.modedb, 16)) {  		printk(KERN_ERR "neofb: Unable to find usable video mode.\n"); +		err = -EINVAL;  		goto err_map_video;  	} @@ -2097,15 +2098,15 @@ static int neofb_probe(struct pci_dev *dev, const struct pci_device_id *id)  	       info->fix.smem_len >> 10, info->var.xres,  	       info->var.yres, h_sync / 1000, h_sync % 1000, v_sync); -	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) +	err = fb_alloc_cmap(&info->cmap, 256, 0); +	if (err < 0)  		goto err_map_video;  	err = register_framebuffer(info);  	if (err < 0)  		goto err_reg_fb; -	printk(KERN_INFO "fb%d: %s frame buffer device\n", -	       info->node, info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	/*  	 * Our driver data @@ -2146,12 +2147,6 @@ static void neofb_remove(struct pci_dev *dev)  		fb_destroy_modedb(info->monspecs.modedb);  		neo_unmap_mmio(info);  		neo_free_fb_info(info); - -		/* -		 * Ensure that the driver data is no longer -		 * valid. -		 */ -		pci_set_drvdata(dev, NULL);  	}  } diff --git a/drivers/video/nuc900fb.c b/drivers/video/fbdev/nuc900fb.c index 796e5112cee..478f9808dee 100644 --- a/drivers/video/nuc900fb.c +++ b/drivers/video/fbdev/nuc900fb.c @@ -91,7 +91,7 @@ static int nuc900fb_check_var(struct fb_var_screeninfo *var,  			       struct fb_info *info)  {  	struct nuc900fb_info *fbi = info->par; -	struct nuc900fb_mach_info *mach_info = fbi->dev->platform_data; +	struct nuc900fb_mach_info *mach_info = dev_get_platdata(fbi->dev);  	struct nuc900fb_display *display = NULL;  	struct nuc900fb_display *default_display = mach_info->displays +  						   mach_info->default_display; @@ -358,7 +358,7 @@ static inline void modify_gpio(void __iomem *reg,  static int nuc900fb_init_registers(struct fb_info *info)  {  	struct nuc900fb_info *fbi = info->par; -	struct nuc900fb_mach_info *mach_info = fbi->dev->platform_data; +	struct nuc900fb_mach_info *mach_info = dev_get_platdata(fbi->dev);  	void __iomem *regs = fbi->io;  	/*reset the display engine*/ @@ -512,7 +512,7 @@ static int nuc900fb_probe(struct platform_device *pdev)  	int size;  	dev_dbg(&pdev->dev, "devinit\n"); -	mach_info = pdev->dev.platform_data; +	mach_info = dev_get_platdata(&pdev->dev);  	if (mach_info == NULL) {  		dev_err(&pdev->dev,  			"no platform data for lcd, cannot attach\n"); @@ -647,8 +647,7 @@ static int nuc900fb_probe(struct platform_device *pdev)  		goto free_cpufreq;  	} -	printk(KERN_INFO "fb%d: %s frame buffer device\n", -		fbinfo->node, fbinfo->fix.id); +	fb_info(fbinfo, "%s frame buffer device\n", fbinfo->fix.id);  	return 0; diff --git a/drivers/video/nuc900fb.h b/drivers/video/fbdev/nuc900fb.h index 9a1ca6dbb6b..9a1ca6dbb6b 100644 --- a/drivers/video/nuc900fb.h +++ b/drivers/video/fbdev/nuc900fb.h diff --git a/drivers/video/nvidia/Makefile b/drivers/video/fbdev/nvidia/Makefile index ca47432113e..ca47432113e 100644 --- a/drivers/video/nvidia/Makefile +++ b/drivers/video/fbdev/nvidia/Makefile diff --git a/drivers/video/nvidia/nv_accel.c b/drivers/video/fbdev/nvidia/nv_accel.c index ad6472a894e..ad6472a894e 100644 --- a/drivers/video/nvidia/nv_accel.c +++ b/drivers/video/fbdev/nvidia/nv_accel.c diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/fbdev/nvidia/nv_backlight.c index 8471008aa6f..8471008aa6f 100644 --- a/drivers/video/nvidia/nv_backlight.c +++ b/drivers/video/fbdev/nvidia/nv_backlight.c diff --git a/drivers/video/nvidia/nv_dma.h b/drivers/video/fbdev/nvidia/nv_dma.h index a7ed1c0acbb..a7ed1c0acbb 100644 --- a/drivers/video/nvidia/nv_dma.h +++ b/drivers/video/fbdev/nvidia/nv_dma.h diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/fbdev/nvidia/nv_hw.c index ed20a9871b3..81c80ac3c76 100644 --- a/drivers/video/nvidia/nv_hw.c +++ b/drivers/video/fbdev/nvidia/nv_hw.c @@ -1300,7 +1300,7 @@ void NVLoadStateExt(struct nvidia_par *par, RIVA_HW_STATE * state)  					break;  				default:  					break; -				}; +				}  				NV_WR32(par->PGRAPH, 0x0b38, 0x2ffff800);  				NV_WR32(par->PGRAPH, 0x0b3c, 0x00006000); diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/fbdev/nvidia/nv_i2c.c index d7994a17324..d7994a17324 100644 --- a/drivers/video/nvidia/nv_i2c.c +++ b/drivers/video/fbdev/nvidia/nv_i2c.c diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/fbdev/nvidia/nv_local.h index 68e508daa41..68e508daa41 100644 --- a/drivers/video/nvidia/nv_local.h +++ b/drivers/video/fbdev/nvidia/nv_local.h diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/fbdev/nvidia/nv_of.c index 3bc13df4b12..3bc13df4b12 100644 --- a/drivers/video/nvidia/nv_of.c +++ b/drivers/video/fbdev/nvidia/nv_of.c diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/fbdev/nvidia/nv_proto.h index ff5c410355e..ff5c410355e 100644 --- a/drivers/video/nvidia/nv_proto.h +++ b/drivers/video/fbdev/nvidia/nv_proto.h diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/fbdev/nvidia/nv_setup.c index 2f2e162134f..2f2e162134f 100644 --- a/drivers/video/nvidia/nv_setup.c +++ b/drivers/video/fbdev/nvidia/nv_setup.c diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/fbdev/nvidia/nv_type.h index c03f7f55c76..c03f7f55c76 100644 --- a/drivers/video/nvidia/nv_type.h +++ b/drivers/video/fbdev/nvidia/nv_type.h diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c index ff228713425..def04120467 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/fbdev/nvidia/nvidia.c @@ -1461,7 +1461,6 @@ static void nvidiafb_remove(struct pci_dev *pd)  	pci_release_regions(pd);  	kfree(info->pixmap.addr);  	framebuffer_release(info); -	pci_set_drvdata(pd, NULL);  	NVTRACE_LEAVE();  } diff --git a/drivers/video/fbdev/ocfb.c b/drivers/video/fbdev/ocfb.c new file mode 100644 index 00000000000..7f9dc9bec30 --- /dev/null +++ b/drivers/video/fbdev/ocfb.c @@ -0,0 +1,440 @@ +/* + * OpenCores VGA/LCD 2.0 core frame buffer driver + * + * Copyright (C) 2013 Stefan Kristiansson, stefan.kristiansson@saunalahti.fi + * + * This file is licensed under the terms of the GNU General Public License + * version 2.  This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#include <linux/delay.h> +#include <linux/dma-mapping.h> +#include <linux/errno.h> +#include <linux/fb.h> +#include <linux/init.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/string.h> +#include <linux/slab.h> + +/* OCFB register defines */ +#define OCFB_CTRL	0x000 +#define OCFB_STAT	0x004 +#define OCFB_HTIM	0x008 +#define OCFB_VTIM	0x00c +#define OCFB_HVLEN	0x010 +#define OCFB_VBARA	0x014 +#define OCFB_PALETTE	0x800 + +#define OCFB_CTRL_VEN	0x00000001 /* Video Enable */ +#define OCFB_CTRL_HIE	0x00000002 /* HSync Interrupt Enable */ +#define OCFB_CTRL_PC	0x00000800 /* 8-bit Pseudo Color Enable*/ +#define OCFB_CTRL_CD8	0x00000000 /* Color Depth 8 */ +#define OCFB_CTRL_CD16	0x00000200 /* Color Depth 16 */ +#define OCFB_CTRL_CD24	0x00000400 /* Color Depth 24 */ +#define OCFB_CTRL_CD32	0x00000600 /* Color Depth 32 */ +#define OCFB_CTRL_VBL1	0x00000000 /* Burst Length 1 */ +#define OCFB_CTRL_VBL2	0x00000080 /* Burst Length 2 */ +#define OCFB_CTRL_VBL4	0x00000100 /* Burst Length 4 */ +#define OCFB_CTRL_VBL8	0x00000180 /* Burst Length 8 */ + +#define PALETTE_SIZE	256 + +#define OCFB_NAME	"OC VGA/LCD" + +static char *mode_option; + +static const struct fb_videomode default_mode = { +	/* 640x480 @ 60 Hz, 31.5 kHz hsync */ +	NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, +	0, FB_VMODE_NONINTERLACED +}; + +struct ocfb_dev { +	struct fb_info info; +	void __iomem *regs; +	/* flag indicating whether the regs are little endian accessed */ +	int little_endian; +	/* Physical and virtual addresses of framebuffer */ +	phys_addr_t fb_phys; +	void __iomem *fb_virt; +	u32 pseudo_palette[PALETTE_SIZE]; +}; + +#ifndef MODULE +static int __init ocfb_setup(char *options) +{ +	char *curr_opt; + +	if (!options || !*options) +		return 0; + +	while ((curr_opt = strsep(&options, ",")) != NULL) { +		if (!*curr_opt) +			continue; +		mode_option = curr_opt; +	} + +	return 0; +} +#endif + +static inline u32 ocfb_readreg(struct ocfb_dev *fbdev, loff_t offset) +{ +	if (fbdev->little_endian) +		return ioread32(fbdev->regs + offset); +	else +		return ioread32be(fbdev->regs + offset); +} + +static void ocfb_writereg(struct ocfb_dev *fbdev, loff_t offset, u32 data) +{ +	if (fbdev->little_endian) +		iowrite32(data, fbdev->regs + offset); +	else +		iowrite32be(data, fbdev->regs + offset); +} + +static int ocfb_setupfb(struct ocfb_dev *fbdev) +{ +	unsigned long bpp_config; +	struct fb_var_screeninfo *var = &fbdev->info.var; +	struct device *dev = fbdev->info.device; +	u32 hlen; +	u32 vlen; + +	/* Disable display */ +	ocfb_writereg(fbdev, OCFB_CTRL, 0); + +	/* Register framebuffer address */ +	fbdev->little_endian = 0; +	ocfb_writereg(fbdev, OCFB_VBARA, fbdev->fb_phys); + +	/* Detect endianess */ +	if (ocfb_readreg(fbdev, OCFB_VBARA) != fbdev->fb_phys) { +		fbdev->little_endian = 1; +		ocfb_writereg(fbdev, OCFB_VBARA, fbdev->fb_phys); +	} + +	/* Horizontal timings */ +	ocfb_writereg(fbdev, OCFB_HTIM, (var->hsync_len - 1) << 24 | +		      (var->right_margin - 1) << 16 | (var->xres - 1)); + +	/* Vertical timings */ +	ocfb_writereg(fbdev, OCFB_VTIM, (var->vsync_len - 1) << 24 | +		      (var->lower_margin - 1) << 16 | (var->yres - 1)); + +	/* Total length of frame */ +	hlen = var->left_margin + var->right_margin + var->hsync_len + +		var->xres; + +	vlen = var->upper_margin + var->lower_margin + var->vsync_len + +		var->yres; + +	ocfb_writereg(fbdev, OCFB_HVLEN, (hlen - 1) << 16 | (vlen - 1)); + +	bpp_config = OCFB_CTRL_CD8; +	switch (var->bits_per_pixel) { +	case 8: +		if (!var->grayscale) +			bpp_config |= OCFB_CTRL_PC;  /* enable palette */ +		break; + +	case 16: +		bpp_config |= OCFB_CTRL_CD16; +		break; + +	case 24: +		bpp_config |= OCFB_CTRL_CD24; +		break; + +	case 32: +		bpp_config |= OCFB_CTRL_CD32; +		break; + +	default: +		dev_err(dev, "no bpp specified\n"); +		break; +	} + +	/* maximum (8) VBL (video memory burst length) */ +	bpp_config |= OCFB_CTRL_VBL8; + +	/* Enable output */ +	ocfb_writereg(fbdev, OCFB_CTRL, (OCFB_CTRL_VEN | bpp_config)); + +	return 0; +} + +static int ocfb_setcolreg(unsigned regno, unsigned red, unsigned green, +			  unsigned blue, unsigned transp, +			  struct fb_info *info) +{ +	struct ocfb_dev *fbdev = (struct ocfb_dev *)info->par; +	u32 color; + +	if (regno >= info->cmap.len) { +		dev_err(info->device, "regno >= cmap.len\n"); +		return 1; +	} + +	if (info->var.grayscale) { +		/* grayscale = 0.30*R + 0.59*G + 0.11*B */ +		red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; +	} + +	red >>= (16 - info->var.red.length); +	green >>= (16 - info->var.green.length); +	blue >>= (16 - info->var.blue.length); +	transp >>= (16 - info->var.transp.length); + +	if (info->var.bits_per_pixel == 8 && !info->var.grayscale) { +		regno <<= 2; +		color = (red << 16) | (green << 8) | blue; +		ocfb_writereg(fbdev, OCFB_PALETTE + regno, color); +	} else { +		((u32 *)(info->pseudo_palette))[regno] = +			(red << info->var.red.offset) | +			(green << info->var.green.offset) | +			(blue << info->var.blue.offset) | +			(transp << info->var.transp.offset); +	} + +	return 0; +} + +static int ocfb_init_fix(struct ocfb_dev *fbdev) +{ +	struct fb_var_screeninfo *var = &fbdev->info.var; +	struct fb_fix_screeninfo *fix = &fbdev->info.fix; + +	strcpy(fix->id, OCFB_NAME); + +	fix->line_length = var->xres * var->bits_per_pixel/8; +	fix->smem_len = fix->line_length * var->yres; +	fix->type = FB_TYPE_PACKED_PIXELS; + +	if (var->bits_per_pixel == 8 && !var->grayscale) +		fix->visual = FB_VISUAL_PSEUDOCOLOR; +	else +		fix->visual = FB_VISUAL_TRUECOLOR; + +	return 0; +} + +static int ocfb_init_var(struct ocfb_dev *fbdev) +{ +	struct fb_var_screeninfo *var = &fbdev->info.var; + +	var->accel_flags = FB_ACCEL_NONE; +	var->activate = FB_ACTIVATE_NOW; +	var->xres_virtual = var->xres; +	var->yres_virtual = var->yres; + +	switch (var->bits_per_pixel) { +	case 8: +		var->transp.offset = 0; +		var->transp.length = 0; +		var->red.offset = 0; +		var->red.length = 8; +		var->green.offset = 0; +		var->green.length = 8; +		var->blue.offset = 0; +		var->blue.length = 8; +		break; + +	case 16: +		var->transp.offset = 0; +		var->transp.length = 0; +		var->red.offset = 11; +		var->red.length = 5; +		var->green.offset = 5; +		var->green.length = 6; +		var->blue.offset = 0; +		var->blue.length  = 5; +		break; + +	case 24: +		var->transp.offset = 0; +		var->transp.length = 0; +		var->red.offset = 16; +		var->red.length = 8; +		var->green.offset = 8; +		var->green.length = 8; +		var->blue.offset = 0; +		var->blue.length = 8; +		break; + +	case 32: +		var->transp.offset = 24; +		var->transp.length = 8; +		var->red.offset = 16; +		var->red.length = 8; +		var->green.offset = 8; +		var->green.length = 8; +		var->blue.offset = 0; +		var->blue.length = 8; +		break; +	} + +	return 0; +} + +static struct fb_ops ocfb_ops = { +	.owner		= THIS_MODULE, +	.fb_setcolreg	= ocfb_setcolreg, +	.fb_fillrect	= cfb_fillrect, +	.fb_copyarea	= cfb_copyarea, +	.fb_imageblit	= cfb_imageblit, +}; + +static int ocfb_probe(struct platform_device *pdev) +{ +	int ret = 0; +	struct ocfb_dev *fbdev; +	struct resource *res; +	int fbsize; + +	fbdev = devm_kzalloc(&pdev->dev, sizeof(*fbdev), GFP_KERNEL); +	if (!fbdev) +		return -ENOMEM; + +	platform_set_drvdata(pdev, fbdev); + +	fbdev->info.fbops = &ocfb_ops; +	fbdev->info.device = &pdev->dev; +	fbdev->info.par = fbdev; + +	/* Video mode setup */ +	if (!fb_find_mode(&fbdev->info.var, &fbdev->info, mode_option, +			  NULL, 0, &default_mode, 16)) { +		dev_err(&pdev->dev, "No valid video modes found\n"); +		return -EINVAL; +	} +	ocfb_init_var(fbdev); +	ocfb_init_fix(fbdev); + +	/* Request I/O resource */ +	res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	if (!res) { +		dev_err(&pdev->dev, "I/O resource request failed\n"); +		return -ENXIO; +	} +	res->flags &= ~IORESOURCE_CACHEABLE; +	fbdev->regs = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(fbdev->regs)) +		return PTR_ERR(fbdev->regs); + +	/* Allocate framebuffer memory */ +	fbsize = fbdev->info.fix.smem_len; +	fbdev->fb_virt = dma_alloc_coherent(&pdev->dev, PAGE_ALIGN(fbsize), +					    &fbdev->fb_phys, GFP_KERNEL); +	if (!fbdev->fb_virt) { +		dev_err(&pdev->dev, +			"Frame buffer memory allocation failed\n"); +		return -ENOMEM; +	} +	fbdev->info.fix.smem_start = fbdev->fb_phys; +	fbdev->info.screen_base = fbdev->fb_virt; +	fbdev->info.pseudo_palette = fbdev->pseudo_palette; + +	/* Clear framebuffer */ +	memset_io(fbdev->fb_virt, 0, fbsize); + +	/* Setup and enable the framebuffer */ +	ocfb_setupfb(fbdev); + +	if (fbdev->little_endian) +		fbdev->info.flags |= FBINFO_FOREIGN_ENDIAN; + +	/* Allocate color map */ +	ret = fb_alloc_cmap(&fbdev->info.cmap, PALETTE_SIZE, 0); +	if (ret) { +		dev_err(&pdev->dev, "Color map allocation failed\n"); +		goto err_dma_free; +	} + +	/* Register framebuffer */ +	ret = register_framebuffer(&fbdev->info); +	if (ret) { +		dev_err(&pdev->dev, "Framebuffer registration failed\n"); +		goto err_dealloc_cmap; +	} + +	return 0; + +err_dealloc_cmap: +	fb_dealloc_cmap(&fbdev->info.cmap); + +err_dma_free: +	dma_free_coherent(&pdev->dev, PAGE_ALIGN(fbsize), fbdev->fb_virt, +			  fbdev->fb_phys); + +	return ret; +} + +static int ocfb_remove(struct platform_device *pdev) +{ +	struct ocfb_dev *fbdev = platform_get_drvdata(pdev); + +	unregister_framebuffer(&fbdev->info); +	fb_dealloc_cmap(&fbdev->info.cmap); +	dma_free_coherent(&pdev->dev, PAGE_ALIGN(fbdev->info.fix.smem_len), +			  fbdev->fb_virt, fbdev->fb_phys); + +	/* Disable display */ +	ocfb_writereg(fbdev, OCFB_CTRL, 0); + +	platform_set_drvdata(pdev, NULL); + +	return 0; +} + +static struct of_device_id ocfb_match[] = { +	{ .compatible = "opencores,ocfb", }, +	{}, +}; +MODULE_DEVICE_TABLE(of, ocfb_match); + +static struct platform_driver ocfb_driver = { +	.probe  = ocfb_probe, +	.remove	= ocfb_remove, +	.driver = { +		.name = "ocfb_fb", +		.of_match_table = ocfb_match, +	} +}; + +/* + * Init and exit routines + */ +static int __init ocfb_init(void) +{ +#ifndef MODULE +	char *option = NULL; + +	if (fb_get_options("ocfb", &option)) +		return -ENODEV; +	ocfb_setup(option); +#endif +	return platform_driver_register(&ocfb_driver); +} + +static void __exit ocfb_exit(void) +{ +	platform_driver_unregister(&ocfb_driver); +} + +module_init(ocfb_init); +module_exit(ocfb_exit); + +MODULE_AUTHOR("Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>"); +MODULE_DESCRIPTION("OpenCores VGA/LCD 2.0 frame buffer driver"); +MODULE_LICENSE("GPL v2"); +module_param(mode_option, charp, 0); +MODULE_PARM_DESC(mode_option, "Video mode ('<xres>x<yres>[-<bpp>][@refresh]')"); diff --git a/drivers/video/offb.c b/drivers/video/fbdev/offb.c index 0c4f34311ed..43a0a52fc52 100644 --- a/drivers/video/offb.c +++ b/drivers/video/fbdev/offb.c @@ -301,7 +301,7 @@ static struct fb_ops offb_ops = {  static void __iomem *offb_map_reg(struct device_node *np, int index,  				  unsigned long offset, unsigned long size)  { -	const u32 *addrp; +	const __be32 *addrp;  	u64 asize, taddr;  	unsigned int flags; @@ -369,7 +369,11 @@ static void offb_init_palette_hacks(struct fb_info *info, struct device_node *dp  		}  		of_node_put(pciparent);  	} else if (dp && of_device_is_compatible(dp, "qemu,std-vga")) { -		const u32 io_of_addr[3] = { 0x01000000, 0x0, 0x0 }; +#ifdef __BIG_ENDIAN +		const __be32 io_of_addr[3] = { 0x01000000, 0x0, 0x0 }; +#else +		const __be32 io_of_addr[3] = { 0x00000001, 0x0, 0x0 }; +#endif  		u64 io_addr = of_translate_address(dp, io_of_addr);  		if (io_addr != OF_BAD_ADDR) {  			par->cmap_adr = ioremap(io_addr + 0x3c8, 2); @@ -515,8 +519,7 @@ static void __init offb_init_fb(const char *name, const char *full_name,  	if (register_framebuffer(info) < 0)  		goto out_err; -	printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n", -	       info->node, full_name); +	fb_info(info, "Open Firmware frame buffer device on %s\n", full_name);  	return;  out_err: @@ -536,7 +539,7 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)  	unsigned int flags, rsize, addr_prop = 0;  	unsigned long max_size = 0;  	u64 rstart, address = OF_BAD_ADDR; -	const u32 *pp, *addrp, *up; +	const __be32 *pp, *addrp, *up;  	u64 asize;  	int foreign_endian = 0; @@ -552,25 +555,25 @@ static void __init offb_init_nodriver(struct device_node *dp, int no_real_node)  	if (pp == NULL)  		pp = of_get_property(dp, "depth", &len);  	if (pp && len == sizeof(u32)) -		depth = *pp; +		depth = be32_to_cpup(pp);  	pp = of_get_property(dp, "linux,bootx-width", &len);  	if (pp == NULL)  		pp = of_get_property(dp, "width", &len);  	if (pp && len == sizeof(u32)) -		width = *pp; +		width = be32_to_cpup(pp);  	pp = of_get_property(dp, "linux,bootx-height", &len);  	if (pp == NULL)  		pp = of_get_property(dp, "height", &len);  	if (pp && len == sizeof(u32)) -		height = *pp; +		height = be32_to_cpup(pp);  	pp = of_get_property(dp, "linux,bootx-linebytes", &len);  	if (pp == NULL)  		pp = of_get_property(dp, "linebytes", &len);  	if (pp && len == sizeof(u32) && (*pp != 0xffffffffu)) -		pitch = *pp; +		pitch = be32_to_cpup(pp);  	else  		pitch = width * ((depth + 7) / 8); diff --git a/drivers/video/omap/Kconfig b/drivers/video/fbdev/omap/Kconfig index 0bc3a936ce2..18c4cb0d569 100644 --- a/drivers/video/omap/Kconfig +++ b/drivers/video/fbdev/omap/Kconfig @@ -39,6 +39,15 @@ config FB_OMAP_LCD_MIPID  	  the Mobile Industry Processor Interface DBI-C/DCS  	  specification. (Supported LCDs: Philips LPH8923, Sharp LS041Y3) +config FB_OMAP_LCD_H3 +	bool "TPS65010 LCD controller on OMAP-H3" +	depends on MACH_OMAP_H3 +	depends on TPS65010 +	default y +	help +	  Say Y here if you want to have support for the LCD on the +	  H3 board. +  config FB_OMAP_DMA_TUNE          bool "Set DMA SDRAM access priority high"          depends on FB_OMAP diff --git a/drivers/video/fbdev/omap/Makefile b/drivers/video/fbdev/omap/Makefile new file mode 100644 index 00000000000..732e0718be5 --- /dev/null +++ b/drivers/video/fbdev/omap/Makefile @@ -0,0 +1,27 @@ +# +# Makefile for the OMAP1 framebuffer device driver +# + +obj-$(CONFIG_FB_OMAP) += omapfb.o + +objs-yy := omapfb_main.o lcdc.o + +objs-y$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o + +objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o + +lcds-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o +lcds-y$(CONFIG_FB_OMAP_LCD_H3) += lcd_h3.o +lcds-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o +lcds-y$(CONFIG_MACH_OMAP_PALMTT) += lcd_palmtt.o +lcds-y$(CONFIG_MACH_OMAP_PALMZ71) += lcd_palmz71.o +lcds-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o +lcds-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o +lcds-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o + +lcds-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o +lcds-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o + +omapfb-objs := $(objs-yy) + +obj-$(CONFIG_FB_OMAP) += $(lcds-yy) diff --git a/drivers/video/omap/hwa742.c b/drivers/video/fbdev/omap/hwa742.c index f349ee6f0ce..a4ee65b8f91 100644 --- a/drivers/video/omap/hwa742.c +++ b/drivers/video/fbdev/omap/hwa742.c @@ -947,7 +947,7 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,  	hwa742.extif = fbdev->ext_if;  	hwa742.int_ctrl = fbdev->int_ctrl; -	omapfb_conf = fbdev->dev->platform_data; +	omapfb_conf = dev_get_platdata(fbdev->dev);  	hwa742.sys_ck = clk_get(NULL, "hwa_sys_ck"); diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/fbdev/omap/lcd_ams_delta.c index 4a5f2cd3d3b..4a5f2cd3d3b 100644 --- a/drivers/video/omap/lcd_ams_delta.c +++ b/drivers/video/fbdev/omap/lcd_ams_delta.c diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/fbdev/omap/lcd_h3.c index 49bdeca81e5..49bdeca81e5 100644 --- a/drivers/video/omap/lcd_h3.c +++ b/drivers/video/fbdev/omap/lcd_h3.c diff --git a/drivers/video/omap/lcd_htcherald.c b/drivers/video/fbdev/omap/lcd_htcherald.c index 20f477851d5..20f477851d5 100644 --- a/drivers/video/omap/lcd_htcherald.c +++ b/drivers/video/fbdev/omap/lcd_htcherald.c diff --git a/drivers/video/omap/lcd_inn1510.c b/drivers/video/fbdev/omap/lcd_inn1510.c index 2ee423279e3..2ee423279e3 100644 --- a/drivers/video/omap/lcd_inn1510.c +++ b/drivers/video/fbdev/omap/lcd_inn1510.c diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/fbdev/omap/lcd_inn1610.c index e3d3d135aa4..e3d3d135aa4 100644 --- a/drivers/video/omap/lcd_inn1610.c +++ b/drivers/video/fbdev/omap/lcd_inn1610.c diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/fbdev/omap/lcd_mipid.c index 803fee618d5..803fee618d5 100644 --- a/drivers/video/omap/lcd_mipid.c +++ b/drivers/video/fbdev/omap/lcd_mipid.c diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/fbdev/omap/lcd_osk.c index 7fbe04bce0e..7fbe04bce0e 100644 --- a/drivers/video/omap/lcd_osk.c +++ b/drivers/video/fbdev/omap/lcd_osk.c diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/fbdev/omap/lcd_palmte.c index ff4fb624b90..ff4fb624b90 100644 --- a/drivers/video/omap/lcd_palmte.c +++ b/drivers/video/fbdev/omap/lcd_palmte.c diff --git a/drivers/video/omap/lcd_palmtt.c b/drivers/video/fbdev/omap/lcd_palmtt.c index aaf3c8ba124..aaf3c8ba124 100644 --- a/drivers/video/omap/lcd_palmtt.c +++ b/drivers/video/fbdev/omap/lcd_palmtt.c diff --git a/drivers/video/omap/lcd_palmz71.c b/drivers/video/fbdev/omap/lcd_palmz71.c index 3b7d8aa1cf3..3b7d8aa1cf3 100644 --- a/drivers/video/omap/lcd_palmz71.c +++ b/drivers/video/fbdev/omap/lcd_palmz71.c diff --git a/drivers/video/omap/lcdc.c b/drivers/video/fbdev/omap/lcdc.c index b52f62595f6..6efa2591eaa 100644 --- a/drivers/video/omap/lcdc.c +++ b/drivers/video/fbdev/omap/lcdc.c @@ -74,7 +74,6 @@ static struct omap_lcd_controller {  	void			(*dma_callback)(void *data);  	void			*dma_callback_data; -	int			fbmem_allocated;  	dma_addr_t		vram_phys;  	void			*vram_virt;  	unsigned long		vram_size; @@ -611,42 +610,6 @@ static void lcdc_dma_handler(u16 status, void *data)  		lcdc.dma_callback(lcdc.dma_callback_data);  } -static int mmap_kern(void) -{ -	struct vm_struct	*kvma; -	struct vm_area_struct	vma; -	pgprot_t		pgprot; -	unsigned long		vaddr; - -	kvma = get_vm_area(lcdc.vram_size, VM_IOREMAP); -	if (kvma == NULL) { -		dev_err(lcdc.fbdev->dev, "can't get kernel vm area\n"); -		return -ENOMEM; -	} -	vma.vm_mm = &init_mm; - -	vaddr = (unsigned long)kvma->addr; -	vma.vm_start = vaddr; -	vma.vm_end = vaddr + lcdc.vram_size; - -	pgprot = pgprot_writecombine(pgprot_kernel); -	if (io_remap_pfn_range(&vma, vaddr, -			   lcdc.vram_phys >> PAGE_SHIFT, -			   lcdc.vram_size, pgprot) < 0) { -		dev_err(lcdc.fbdev->dev, "kernel mmap for FB memory failed\n"); -		return -EAGAIN; -	} - -	lcdc.vram_virt = (void *)vaddr; - -	return 0; -} - -static void unmap_kern(void) -{ -	vunmap(lcdc.vram_virt); -} -  static int alloc_palette_ram(void)  {  	lcdc.palette_virt = dma_alloc_writecombine(lcdc.fbdev->dev, @@ -703,8 +666,6 @@ static void free_fbmem(void)  static int setup_fbmem(struct omapfb_mem_desc *req_md)  { -	int r; -  	if (!req_md->region_cnt) {  		dev_err(lcdc.fbdev->dev, "no memory regions defined\n");  		return -EINVAL; @@ -715,31 +676,7 @@ static int setup_fbmem(struct omapfb_mem_desc *req_md)  		req_md->region_cnt = 1;  	} -	if (req_md->region[0].paddr == 0) { -		lcdc.fbmem_allocated = 1; -		if ((r = alloc_fbmem(&req_md->region[0])) < 0) -			return r; -		return 0; -	} - -	lcdc.vram_phys = req_md->region[0].paddr; -	lcdc.vram_size = req_md->region[0].size; - -	if ((r = mmap_kern()) < 0) -		return r; - -	dev_dbg(lcdc.fbdev->dev, "vram at %08x size %08lx mapped to 0x%p\n", -		 lcdc.vram_phys, lcdc.vram_size, lcdc.vram_virt); - -	return 0; -} - -static void cleanup_fbmem(void) -{ -	if (lcdc.fbmem_allocated) -		free_fbmem(); -	else -		unmap_kern(); +	return alloc_fbmem(&req_md->region[0]);  }  static int omap_lcdc_init(struct omapfb_device *fbdev, int ext_mode, @@ -833,7 +770,7 @@ static void omap_lcdc_cleanup(void)  {  	if (!lcdc.ext_mode)  		free_palette_ram(); -	cleanup_fbmem(); +	free_fbmem();  	omap_free_lcd_dma();  	free_irq(OMAP_LCDC_IRQ, lcdc.fbdev);  	clk_disable(lcdc.lcd_ck); diff --git a/drivers/video/omap/lcdc.h b/drivers/video/fbdev/omap/lcdc.h index 845222270db..845222270db 100644 --- a/drivers/video/omap/lcdc.h +++ b/drivers/video/fbdev/omap/lcdc.h diff --git a/drivers/video/omap/omapfb.h b/drivers/video/fbdev/omap/omapfb.h index 2921d20e4fb..2921d20e4fb 100644 --- a/drivers/video/omap/omapfb.h +++ b/drivers/video/fbdev/omap/omapfb.h diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/fbdev/omap/omapfb_main.c index d40612c31a9..d8d028d9871 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/fbdev/omap/omapfb_main.c @@ -1602,7 +1602,7 @@ static int omapfb_find_ctrl(struct omapfb_device *fbdev)  	char name[17];  	int i; -	conf = fbdev->dev->platform_data; +	conf = dev_get_platdata(fbdev->dev);  	fbdev->ctrl = NULL; @@ -1674,7 +1674,7 @@ static int omapfb_do_probe(struct platform_device *pdev,  		goto cleanup;  	} -	if (pdev->dev.platform_data == NULL) { +	if (dev_get_platdata(&pdev->dev) == NULL) {  		dev_err(&pdev->dev, "missing platform data\n");  		r = -ENOENT;  		goto cleanup; @@ -1823,6 +1823,7 @@ void omapfb_register_panel(struct lcd_panel *panel)  	if (fbdev_pdev != NULL)  		omapfb_do_probe(fbdev_pdev, fbdev_panel);  } +EXPORT_SYMBOL_GPL(omapfb_register_panel);  /* Called when the device is being detached from the driver */  static int omapfb_remove(struct platform_device *pdev) diff --git a/drivers/video/omap/sossi.c b/drivers/video/fbdev/omap/sossi.c index d4e7684e704..d4e7684e704 100644 --- a/drivers/video/omap/sossi.c +++ b/drivers/video/fbdev/omap/sossi.c diff --git a/drivers/video/fbdev/omap2/Kconfig b/drivers/video/fbdev/omap2/Kconfig new file mode 100644 index 00000000000..c22955d2de9 --- /dev/null +++ b/drivers/video/fbdev/omap2/Kconfig @@ -0,0 +1,10 @@ +config OMAP2_VRFB +	bool + +if ARCH_OMAP2PLUS + +source "drivers/video/fbdev/omap2/dss/Kconfig" +source "drivers/video/fbdev/omap2/omapfb/Kconfig" +source "drivers/video/fbdev/omap2/displays-new/Kconfig" + +endif diff --git a/drivers/video/omap2/Makefile b/drivers/video/fbdev/omap2/Makefile index bf8127df8c7..f8745ec369c 100644 --- a/drivers/video/omap2/Makefile +++ b/drivers/video/fbdev/omap2/Makefile @@ -1,5 +1,5 @@  obj-$(CONFIG_OMAP2_VRFB) += vrfb.o -obj-$(CONFIG_OMAP2_DSS) += dss/ +obj-y += dss/  obj-y += displays-new/  obj-$(CONFIG_FB_OMAP2) += omapfb/ diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/fbdev/omap2/displays-new/Kconfig index 6c90885b094..e6cfc38160d 100644 --- a/drivers/video/omap2/displays-new/Kconfig +++ b/drivers/video/fbdev/omap2/displays-new/Kconfig @@ -35,6 +35,7 @@ config DISPLAY_PANEL_DPI  config DISPLAY_PANEL_DSI_CM  	tristate "Generic DSI Command Mode Panel" +	depends on BACKLIGHT_CLASS_DEVICE  	help  	  Driver for generic DSI command mode panels. @@ -56,6 +57,12 @@ config DISPLAY_PANEL_SHARP_LS037V7DW01          help            LCD Panel used in TI's SDP3430 and EVM boards +config DISPLAY_PANEL_TPO_TD028TTEC1 +        tristate "TPO TD028TTEC1 LCD Panel" +        depends on SPI +        help +          LCD panel used in Openmoko. +  config DISPLAY_PANEL_TPO_TD043MTEA1          tristate "TPO TD043MTEA1 LCD Panel"          depends on SPI diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/fbdev/omap2/displays-new/Makefile index 5aeb11b8fcd..0323a8a1c68 100644 --- a/drivers/video/omap2/displays-new/Makefile +++ b/drivers/video/fbdev/omap2/displays-new/Makefile @@ -8,5 +8,6 @@ obj-$(CONFIG_DISPLAY_PANEL_DSI_CM) += panel-dsi-cm.o  obj-$(CONFIG_DISPLAY_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o  obj-$(CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o  obj-$(CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o +obj-$(CONFIG_DISPLAY_PANEL_TPO_TD028TTEC1) += panel-tpo-td028ttec1.o  obj-$(CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o  obj-$(CONFIG_DISPLAY_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o diff --git a/drivers/video/omap2/displays-new/connector-analog-tv.c b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c index 1b60698f141..5ee3b5505f7 100644 --- a/drivers/video/omap2/displays-new/connector-analog-tv.c +++ b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c @@ -12,6 +12,7 @@  #include <linux/slab.h>  #include <linux/module.h>  #include <linux/platform_device.h> +#include <linux/of.h>  #include <video/omapdss.h>  #include <video/omap-panel-data.h> @@ -31,7 +32,7 @@ struct panel_drv_data {  static const struct omap_video_timings tvc_pal_timings = {  	.x_res		= 720,  	.y_res		= 574, -	.pixel_clock	= 13500, +	.pixelclock	= 13500000,  	.hsw		= 64,  	.hfp		= 12,  	.hbp		= 68, @@ -42,6 +43,12 @@ static const struct omap_video_timings tvc_pal_timings = {  	.interlace	= true,  }; +static const struct of_device_id tvc_of_match[]; + +struct tvc_of_data { +	enum omap_dss_venc_type connector_type; +}; +  #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)  static int tvc_connect(struct omap_dss_device *dssdev) @@ -91,8 +98,12 @@ static int tvc_enable(struct omap_dss_device *dssdev)  	in->ops.atv->set_timings(in, &ddata->timings); -	in->ops.atv->set_type(in, ddata->connector_type); -	in->ops.atv->invert_vid_out_polarity(in, ddata->invert_polarity); +	if (!ddata->dev->of_node) { +		in->ops.atv->set_type(in, ddata->connector_type); + +		in->ops.atv->invert_vid_out_polarity(in, +			ddata->invert_polarity); +	}  	r = in->ops.atv->enable(in);  	if (r) @@ -191,7 +202,7 @@ static int tvc_probe_pdata(struct platform_device *pdev)  	in = omap_dss_find_output(pdata->source);  	if (in == NULL) {  		dev_err(&pdev->dev, "Failed to find video source\n"); -		return -ENODEV; +		return -EPROBE_DEFER;  	}  	ddata->in = in; @@ -205,6 +216,23 @@ static int tvc_probe_pdata(struct platform_device *pdev)  	return 0;  } +static int tvc_probe_of(struct platform_device *pdev) +{ +	struct panel_drv_data *ddata = platform_get_drvdata(pdev); +	struct device_node *node = pdev->dev.of_node; +	struct omap_dss_device *in; + +	in = omapdss_of_find_source_for_first_ep(node); +	if (IS_ERR(in)) { +		dev_err(&pdev->dev, "failed to find video source\n"); +		return PTR_ERR(in); +	} + +	ddata->in = in; + +	return 0; +} +  static int tvc_probe(struct platform_device *pdev)  {  	struct panel_drv_data *ddata; @@ -222,6 +250,10 @@ static int tvc_probe(struct platform_device *pdev)  		r = tvc_probe_pdata(pdev);  		if (r)  			return r; +	} else if (pdev->dev.of_node) { +		r = tvc_probe_of(pdev); +		if (r) +			return r;  	} else {  		return -ENODEV;  	} @@ -263,12 +295,19 @@ static int __exit tvc_remove(struct platform_device *pdev)  	return 0;  } +static const struct of_device_id tvc_of_match[] = { +	{ .compatible = "omapdss,svideo-connector", }, +	{ .compatible = "omapdss,composite-video-connector", }, +	{}, +}; +  static struct platform_driver tvc_connector_driver = {  	.probe	= tvc_probe,  	.remove	= __exit_p(tvc_remove),  	.driver	= {  		.name	= "connector-analog-tv",  		.owner	= THIS_MODULE, +		.of_match_table = tvc_of_match,  	},  }; diff --git a/drivers/video/omap2/displays-new/connector-dvi.c b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c index bc5f8ceda37..74de2bc50c4 100644 --- a/drivers/video/omap2/displays-new/connector-dvi.c +++ b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c @@ -23,7 +23,7 @@ static const struct omap_video_timings dvic_default_timings = {  	.x_res		= 640,  	.y_res		= 480, -	.pixel_clock	= 23500, +	.pixelclock	= 23500000,  	.hfp		= 48,  	.hsw		= 32, @@ -262,8 +262,11 @@ static int dvic_probe_pdata(struct platform_device *pdev)  	in = omap_dss_find_output(pdata->source);  	if (in == NULL) { +		if (ddata->i2c_adapter) +			i2c_put_adapter(ddata->i2c_adapter); +  		dev_err(&pdev->dev, "Failed to find video source\n"); -		return -ENODEV; +		return -EPROBE_DEFER;  	}  	ddata->in = in; @@ -274,6 +277,37 @@ static int dvic_probe_pdata(struct platform_device *pdev)  	return 0;  } +static int dvic_probe_of(struct platform_device *pdev) +{ +	struct panel_drv_data *ddata = platform_get_drvdata(pdev); +	struct device_node *node = pdev->dev.of_node; +	struct omap_dss_device *in; +	struct device_node *adapter_node; +	struct i2c_adapter *adapter; + +	in = omapdss_of_find_source_for_first_ep(node); +	if (IS_ERR(in)) { +		dev_err(&pdev->dev, "failed to find video source\n"); +		return PTR_ERR(in); +	} + +	ddata->in = in; + +	adapter_node = of_parse_phandle(node, "ddc-i2c-bus", 0); +	if (adapter_node) { +		adapter = of_find_i2c_adapter_by_node(adapter_node); +		if (adapter == NULL) { +			dev_err(&pdev->dev, "failed to parse ddc-i2c-bus\n"); +			omap_dss_put_device(ddata->in); +			return -EPROBE_DEFER; +		} + +		ddata->i2c_adapter = adapter; +	} + +	return 0; +} +  static int dvic_probe(struct platform_device *pdev)  {  	struct panel_drv_data *ddata; @@ -290,6 +324,10 @@ static int dvic_probe(struct platform_device *pdev)  		r = dvic_probe_pdata(pdev);  		if (r)  			return r; +	} else if (pdev->dev.of_node) { +		r = dvic_probe_of(pdev); +		if (r) +			return r;  	} else {  		return -ENODEV;  	} @@ -313,6 +351,10 @@ static int dvic_probe(struct platform_device *pdev)  err_reg:  	omap_dss_put_device(ddata->in); + +	if (ddata->i2c_adapter) +		i2c_put_adapter(ddata->i2c_adapter); +  	return r;  } @@ -335,12 +377,20 @@ static int __exit dvic_remove(struct platform_device *pdev)  	return 0;  } +static const struct of_device_id dvic_of_match[] = { +	{ .compatible = "omapdss,dvi-connector", }, +	{}, +}; + +MODULE_DEVICE_TABLE(of, dvic_of_match); +  static struct platform_driver dvi_connector_driver = {  	.probe	= dvic_probe,  	.remove	= __exit_p(dvic_remove),  	.driver	= {  		.name	= "connector-dvi",  		.owner	= THIS_MODULE, +		.of_match_table = dvic_of_match,  	},  }; diff --git a/drivers/video/omap2/displays-new/connector-hdmi.c b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c index c5826716d6a..4420ccb69aa 100644 --- a/drivers/video/omap2/displays-new/connector-hdmi.c +++ b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c @@ -12,6 +12,8 @@  #include <linux/slab.h>  #include <linux/module.h>  #include <linux/platform_device.h> +#include <linux/of.h> +#include <linux/of_gpio.h>  #include <drm/drm_edid.h> @@ -21,7 +23,7 @@  static const struct omap_video_timings hdmic_default_timings = {  	.x_res		= 640,  	.y_res		= 480, -	.pixel_clock	= 25175, +	.pixelclock	= 25175000,  	.hsw		= 96,  	.hfp		= 16,  	.hbp		= 48, @@ -42,6 +44,8 @@ struct panel_drv_data {  	struct device *dev;  	struct omap_video_timings timings; + +	int hpd_gpio;  };  #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev) @@ -160,7 +164,10 @@ static bool hdmic_detect(struct omap_dss_device *dssdev)  	struct panel_drv_data *ddata = to_panel_data(dssdev);  	struct omap_dss_device *in = ddata->in; -	return in->ops.hdmi->detect(in); +	if (gpio_is_valid(ddata->hpd_gpio)) +		return gpio_get_value_cansleep(ddata->hpd_gpio); +	else +		return in->ops.hdmi->detect(in);  }  static int hdmic_audio_enable(struct omap_dss_device *dssdev) @@ -287,10 +294,12 @@ static int hdmic_probe_pdata(struct platform_device *pdev)  	pdata = dev_get_platdata(&pdev->dev); +	ddata->hpd_gpio = -ENODEV; +  	in = omap_dss_find_output(pdata->source);  	if (in == NULL) {  		dev_err(&pdev->dev, "Failed to find video source\n"); -		return -ENODEV; +		return -EPROBE_DEFER;  	}  	ddata->in = in; @@ -301,6 +310,31 @@ static int hdmic_probe_pdata(struct platform_device *pdev)  	return 0;  } +static int hdmic_probe_of(struct platform_device *pdev) +{ +	struct panel_drv_data *ddata = platform_get_drvdata(pdev); +	struct device_node *node = pdev->dev.of_node; +	struct omap_dss_device *in; +	int gpio; + +	/* HPD GPIO */ +	gpio = of_get_named_gpio(node, "hpd-gpios", 0); +	if (gpio_is_valid(gpio)) +		ddata->hpd_gpio = gpio; +	else +		ddata->hpd_gpio = -ENODEV; + +	in = omapdss_of_find_source_for_first_ep(node); +	if (IS_ERR(in)) { +		dev_err(&pdev->dev, "failed to find video source\n"); +		return PTR_ERR(in); +	} + +	ddata->in = in; + +	return 0; +} +  static int hdmic_probe(struct platform_device *pdev)  {  	struct panel_drv_data *ddata; @@ -318,10 +352,21 @@ static int hdmic_probe(struct platform_device *pdev)  		r = hdmic_probe_pdata(pdev);  		if (r)  			return r; +	} else if (pdev->dev.of_node) { +		r = hdmic_probe_of(pdev); +		if (r) +			return r;  	} else {  		return -ENODEV;  	} +	if (gpio_is_valid(ddata->hpd_gpio)) { +		r = devm_gpio_request_one(&pdev->dev, ddata->hpd_gpio, +				GPIOF_DIR_IN, "hdmi_hpd"); +		if (r) +			goto err_reg; +	} +  	ddata->timings = hdmic_default_timings;  	dssdev = &ddata->dssdev; @@ -359,12 +404,20 @@ static int __exit hdmic_remove(struct platform_device *pdev)  	return 0;  } +static const struct of_device_id hdmic_of_match[] = { +	{ .compatible = "omapdss,hdmi-connector", }, +	{}, +}; + +MODULE_DEVICE_TABLE(of, hdmic_of_match); +  static struct platform_driver hdmi_connector_driver = {  	.probe	= hdmic_probe,  	.remove	= __exit_p(hdmic_remove),  	.driver	= {  		.name	= "connector-hdmi",  		.owner	= THIS_MODULE, +		.of_match_table = hdmic_of_match,  	},  }; diff --git a/drivers/video/omap2/displays-new/encoder-tfp410.c b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c index 4a291e756be..b4e9a42a79e 100644 --- a/drivers/video/omap2/displays-new/encoder-tfp410.c +++ b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c @@ -13,6 +13,7 @@  #include <linux/module.h>  #include <linux/platform_device.h>  #include <linux/slab.h> +#include <linux/of_gpio.h>  #include <video/omapdss.h>  #include <video/omap-panel-data.h> @@ -82,7 +83,8 @@ static int tfp410_enable(struct omap_dss_device *dssdev)  		return 0;  	in->ops.dpi->set_timings(in, &ddata->timings); -	in->ops.dpi->set_data_lines(in, ddata->data_lines); +	if (ddata->data_lines) +		in->ops.dpi->set_data_lines(in, ddata->data_lines);  	r = in->ops.dpi->enable(in);  	if (r) @@ -179,6 +181,33 @@ static int tfp410_probe_pdata(struct platform_device *pdev)  	return 0;  } +static int tfp410_probe_of(struct platform_device *pdev) +{ +	struct panel_drv_data *ddata = platform_get_drvdata(pdev); +	struct device_node *node = pdev->dev.of_node; +	struct omap_dss_device *in; +	int gpio; + +	gpio = of_get_named_gpio(node, "powerdown-gpios", 0); + +	if (gpio_is_valid(gpio) || gpio == -ENOENT) { +		ddata->pd_gpio = gpio; +	} else { +		dev_err(&pdev->dev, "failed to parse PD gpio\n"); +		return gpio; +	} + +	in = omapdss_of_find_source_for_first_ep(node); +	if (IS_ERR(in)) { +		dev_err(&pdev->dev, "failed to find video source\n"); +		return PTR_ERR(in); +	} + +	ddata->in = in; + +	return 0; +} +  static int tfp410_probe(struct platform_device *pdev)  {  	struct panel_drv_data *ddata; @@ -195,6 +224,10 @@ static int tfp410_probe(struct platform_device *pdev)  		r = tfp410_probe_pdata(pdev);  		if (r)  			return r; +	} else if (pdev->dev.of_node) { +		r = tfp410_probe_of(pdev); +		if (r) +			return r;  	} else {  		return -ENODEV;  	} @@ -251,12 +284,20 @@ static int __exit tfp410_remove(struct platform_device *pdev)  	return 0;  } +static const struct of_device_id tfp410_of_match[] = { +	{ .compatible = "omapdss,ti,tfp410", }, +	{}, +}; + +MODULE_DEVICE_TABLE(of, tfp410_of_match); +  static struct platform_driver tfp410_driver = {  	.probe	= tfp410_probe,  	.remove	= __exit_p(tfp410_remove),  	.driver	= {  		.name	= "tfp410",  		.owner	= THIS_MODULE, +		.of_match_table = tfp410_of_match,  	},  }; diff --git a/drivers/video/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c index 798ef200b05..7e33686171e 100644 --- a/drivers/video/omap2/displays-new/encoder-tpd12s015.c +++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c @@ -15,6 +15,7 @@  #include <linux/slab.h>  #include <linux/gpio.h>  #include <linux/platform_device.h> +#include <linux/of_gpio.h>  #include <video/omapdss.h>  #include <video/omap-panel-data.h> @@ -69,7 +70,7 @@ static int tpd_connect(struct omap_dss_device *dssdev,  	dst->src = dssdev;  	dssdev->dst = dst; -	INIT_COMPLETION(ddata->hpd_completion); +	reinit_completion(&ddata->hpd_completion);  	gpio_set_value_cansleep(ddata->ct_cp_hpd_gpio, 1);  	/* DC-DC converter needs at max 300us to get to 90% of 5V */ @@ -289,6 +290,49 @@ static int tpd_probe_pdata(struct platform_device *pdev)  	return 0;  } +static int tpd_probe_of(struct platform_device *pdev) +{ +	struct panel_drv_data *ddata = platform_get_drvdata(pdev); +	struct device_node *node = pdev->dev.of_node; +	struct omap_dss_device *in; +	int gpio; + +	/* CT CP HPD GPIO */ +	gpio = of_get_gpio(node, 0); +	if (!gpio_is_valid(gpio)) { +		dev_err(&pdev->dev, "failed to parse CT CP HPD gpio\n"); +		return gpio; +	} +	ddata->ct_cp_hpd_gpio = gpio; + +	/* LS OE GPIO */ +	gpio = of_get_gpio(node, 1); +	if (gpio_is_valid(gpio) || gpio == -ENOENT) { +		ddata->ls_oe_gpio = gpio; +	} else { +		dev_err(&pdev->dev, "failed to parse LS OE gpio\n"); +		return gpio; +	} + +	/* HPD GPIO */ +	gpio = of_get_gpio(node, 2); +	if (!gpio_is_valid(gpio)) { +		dev_err(&pdev->dev, "failed to parse HPD gpio\n"); +		return gpio; +	} +	ddata->hpd_gpio = gpio; + +	in = omapdss_of_find_source_for_first_ep(node); +	if (IS_ERR(in)) { +		dev_err(&pdev->dev, "failed to find video source\n"); +		return PTR_ERR(in); +	} + +	ddata->in = in; + +	return 0; +} +  static int tpd_probe(struct platform_device *pdev)  {  	struct omap_dss_device *in, *dssdev; @@ -307,6 +351,10 @@ static int tpd_probe(struct platform_device *pdev)  		r = tpd_probe_pdata(pdev);  		if (r)  			return r; +	} else if (pdev->dev.of_node) { +		r = tpd_probe_of(pdev); +		if (r) +			return r;  	} else {  		return -ENODEV;  	} @@ -379,12 +427,20 @@ static int __exit tpd_remove(struct platform_device *pdev)  	return 0;  } +static const struct of_device_id tpd_of_match[] = { +	{ .compatible = "omapdss,ti,tpd12s015", }, +	{}, +}; + +MODULE_DEVICE_TABLE(of, tpd_of_match); +  static struct platform_driver tpd_driver = {  	.probe	= tpd_probe,  	.remove	= __exit_p(tpd_remove),  	.driver	= {  		.name	= "tpd12s015",  		.owner	= THIS_MODULE, +		.of_match_table = tpd_of_match,  	},  }; diff --git a/drivers/video/omap2/displays-new/panel-dpi.c b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c index 5f8f7e7c81e..3636b61dc9b 100644 --- a/drivers/video/omap2/displays-new/panel-dpi.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c @@ -13,9 +13,12 @@  #include <linux/module.h>  #include <linux/platform_device.h>  #include <linux/slab.h> +#include <linux/of.h> +#include <linux/of_gpio.h>  #include <video/omapdss.h>  #include <video/omap-panel-data.h> +#include <video/of_display_timing.h>  struct panel_drv_data {  	struct omap_dss_device dssdev; @@ -25,8 +28,10 @@ struct panel_drv_data {  	struct omap_video_timings videomode; +	/* used for non-DT boot, to be removed */  	int backlight_gpio; -	int enable_gpio; + +	struct gpio_desc *enable_gpio;  };  #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) @@ -70,15 +75,16 @@ static int panel_dpi_enable(struct omap_dss_device *dssdev)  	if (omapdss_device_is_enabled(dssdev))  		return 0; -	in->ops.dpi->set_data_lines(in, ddata->data_lines); +	if (ddata->data_lines) +		in->ops.dpi->set_data_lines(in, ddata->data_lines);  	in->ops.dpi->set_timings(in, &ddata->videomode);  	r = in->ops.dpi->enable(in);  	if (r)  		return r; -	if (gpio_is_valid(ddata->enable_gpio)) -		gpio_set_value_cansleep(ddata->enable_gpio, 1); +	if (ddata->enable_gpio) +		gpiod_set_value_cansleep(ddata->enable_gpio, 1);  	if (gpio_is_valid(ddata->backlight_gpio))  		gpio_set_value_cansleep(ddata->backlight_gpio, 1); @@ -96,8 +102,8 @@ static void panel_dpi_disable(struct omap_dss_device *dssdev)  	if (!omapdss_device_is_enabled(dssdev))  		return; -	if (gpio_is_valid(ddata->enable_gpio)) -		gpio_set_value_cansleep(ddata->enable_gpio, 0); +	if (ddata->enable_gpio) +		gpiod_set_value_cansleep(ddata->enable_gpio, 0);  	if (gpio_is_valid(ddata->backlight_gpio))  		gpio_set_value_cansleep(ddata->backlight_gpio, 0); @@ -156,6 +162,7 @@ static int panel_dpi_probe_pdata(struct platform_device *pdev)  	struct panel_drv_data *ddata = platform_get_drvdata(pdev);  	struct omap_dss_device *dssdev, *in;  	struct videomode vm; +	int r;  	pdata = dev_get_platdata(&pdev->dev); @@ -176,10 +183,65 @@ static int panel_dpi_probe_pdata(struct platform_device *pdev)  	dssdev = &ddata->dssdev;  	dssdev->name = pdata->name; -	ddata->enable_gpio = pdata->enable_gpio; +	r = devm_gpio_request_one(&pdev->dev, pdata->enable_gpio, +					GPIOF_OUT_INIT_LOW, "panel enable"); +	if (r) +		goto err_gpio; + +	ddata->enable_gpio = gpio_to_desc(pdata->enable_gpio); +  	ddata->backlight_gpio = pdata->backlight_gpio;  	return 0; + +err_gpio: +	omap_dss_put_device(ddata->in); +	return r; +} + +static int panel_dpi_probe_of(struct platform_device *pdev) +{ +	struct panel_drv_data *ddata = platform_get_drvdata(pdev); +	struct device_node *node = pdev->dev.of_node; +	struct omap_dss_device *in; +	int r; +	struct display_timing timing; +	struct videomode vm; +	struct gpio_desc *gpio; + +	gpio = devm_gpiod_get(&pdev->dev, "enable"); + +	if (IS_ERR(gpio)) { +		if (PTR_ERR(gpio) != -ENOENT) +			return PTR_ERR(gpio); +		else +			gpio = NULL; +	} else { +		gpiod_direction_output(gpio, 0); +	} + +	ddata->enable_gpio = gpio; + +	ddata->backlight_gpio = -ENOENT; + +	r = of_get_display_timing(node, "panel-timing", &timing); +	if (r) { +		dev_err(&pdev->dev, "failed to get video timing\n"); +		return r; +	} + +	videomode_from_timing(&timing, &vm); +	videomode_to_omap_video_timings(&vm, &ddata->videomode); + +	in = omapdss_of_find_source_for_first_ep(node); +	if (IS_ERR(in)) { +		dev_err(&pdev->dev, "failed to find video source\n"); +		return PTR_ERR(in); +	} + +	ddata->in = in; + +	return 0;  }  static int panel_dpi_probe(struct platform_device *pdev) @@ -198,17 +260,14 @@ static int panel_dpi_probe(struct platform_device *pdev)  		r = panel_dpi_probe_pdata(pdev);  		if (r)  			return r; +	} else if (pdev->dev.of_node) { +		r = panel_dpi_probe_of(pdev); +		if (r) +			return r;  	} else {  		return -ENODEV;  	} -	if (gpio_is_valid(ddata->enable_gpio)) { -		r = devm_gpio_request_one(&pdev->dev, ddata->enable_gpio, -				GPIOF_OUT_INIT_LOW, "panel enable"); -		if (r) -			goto err_gpio; -	} -  	if (gpio_is_valid(ddata->backlight_gpio)) {  		r = devm_gpio_request_one(&pdev->dev, ddata->backlight_gpio,  				GPIOF_OUT_INIT_LOW, "panel backlight"); @@ -254,12 +313,20 @@ static int __exit panel_dpi_remove(struct platform_device *pdev)  	return 0;  } +static const struct of_device_id panel_dpi_of_match[] = { +	{ .compatible = "omapdss,panel-dpi", }, +	{}, +}; + +MODULE_DEVICE_TABLE(of, panel_dpi_of_match); +  static struct platform_driver panel_dpi_driver = {  	.probe = panel_dpi_probe,  	.remove = __exit_p(panel_dpi_remove),  	.driver = {  		.name = "panel-dpi",  		.owner = THIS_MODULE, +		.of_match_table = panel_dpi_of_match,  	},  }; diff --git a/drivers/video/omap2/displays-new/panel-dsi-cm.c b/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c index aaaea6469cd..d6f14e8717e 100644 --- a/drivers/video/omap2/displays-new/panel-dsi-cm.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c @@ -22,6 +22,8 @@  #include <linux/sched.h>  #include <linux/slab.h>  #include <linux/workqueue.h> +#include <linux/of_device.h> +#include <linux/of_gpio.h>  #include <video/omapdss.h>  #include <video/omap-panel-data.h> @@ -595,11 +597,14 @@ static int dsicm_power_on(struct panel_drv_data *ddata)  		.lp_clk_max = 10000000,  	}; -	r = in->ops.dsi->configure_pins(in, &ddata->pin_config); -	if (r) { -		dev_err(&ddata->pdev->dev, "failed to configure DSI pins\n"); -		goto err0; -	}; +	if (ddata->pin_config.num_pins > 0) { +		r = in->ops.dsi->configure_pins(in, &ddata->pin_config); +		if (r) { +			dev_err(&ddata->pdev->dev, +				"failed to configure DSI pins\n"); +			goto err0; +		} +	}  	r = in->ops.dsi->set_config(in, &dsi_config);  	if (r) { @@ -1156,6 +1161,41 @@ static int dsicm_probe_pdata(struct platform_device *pdev)  	return 0;  } +static int dsicm_probe_of(struct platform_device *pdev) +{ +	struct device_node *node = pdev->dev.of_node; +	struct panel_drv_data *ddata = platform_get_drvdata(pdev); +	struct omap_dss_device *in; +	int gpio; + +	gpio = of_get_named_gpio(node, "reset-gpios", 0); +	if (!gpio_is_valid(gpio)) { +		dev_err(&pdev->dev, "failed to parse reset gpio\n"); +		return gpio; +	} +	ddata->reset_gpio = gpio; + +	gpio = of_get_named_gpio(node, "te-gpios", 0); +	if (gpio_is_valid(gpio) || gpio == -ENOENT) { +		ddata->ext_te_gpio = gpio; +	} else { +		dev_err(&pdev->dev, "failed to parse TE gpio\n"); +		return gpio; +	} + +	in = omapdss_of_find_source_for_first_ep(node); +	if (IS_ERR(in)) { +		dev_err(&pdev->dev, "failed to find video source\n"); +		return PTR_ERR(in); +	} + +	ddata->in = in; + +	/* TODO: ulps, backlight */ + +	return 0; +} +  static int dsicm_probe(struct platform_device *pdev)  {  	struct backlight_properties props; @@ -1178,13 +1218,17 @@ static int dsicm_probe(struct platform_device *pdev)  		r = dsicm_probe_pdata(pdev);  		if (r)  			return r; +	} else if (pdev->dev.of_node) { +		r = dsicm_probe_of(pdev); +		if (r) +			return r;  	} else {  		return -ENODEV;  	}  	ddata->timings.x_res = 864;  	ddata->timings.y_res = 480; -	ddata->timings.pixel_clock = DIV_ROUND_UP(864 * 480 * 60, 1000); +	ddata->timings.pixelclock = 864 * 480 * 60;  	dssdev = &ddata->dssdev;  	dssdev->dev = dev; @@ -1320,12 +1364,20 @@ static int __exit dsicm_remove(struct platform_device *pdev)  	return 0;  } +static const struct of_device_id dsicm_of_match[] = { +	{ .compatible = "omapdss,panel-dsi-cm", }, +	{}, +}; + +MODULE_DEVICE_TABLE(of, dsicm_of_match); +  static struct platform_driver dsicm_driver = {  	.probe = dsicm_probe,  	.remove = __exit_p(dsicm_remove),  	.driver = {  		.name = "panel-dsi-cm",  		.owner = THIS_MODULE, +		.of_match_table = dsicm_of_match,  	},  }; diff --git a/drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c index 6e8977b1895..cc5b5124e0b 100644 --- a/drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c @@ -23,7 +23,7 @@ static struct omap_video_timings lb035q02_timings = {  	.x_res = 320,  	.y_res = 240, -	.pixel_clock	= 6500, +	.pixelclock	= 6500000,  	.hsw		= 2,  	.hfp		= 20, @@ -50,9 +50,10 @@ struct panel_drv_data {  	struct omap_video_timings videomode; -	int reset_gpio; +	/* used for non-DT boot, to be removed */  	int backlight_gpio; -	int enable_gpio; + +	struct gpio_desc *enable_gpio;  };  #define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) @@ -158,15 +159,16 @@ static int lb035q02_enable(struct omap_dss_device *dssdev)  	if (omapdss_device_is_enabled(dssdev))  		return 0; -	in->ops.dpi->set_data_lines(in, ddata->data_lines); +	if (ddata->data_lines) +		in->ops.dpi->set_data_lines(in, ddata->data_lines);  	in->ops.dpi->set_timings(in, &ddata->videomode);  	r = in->ops.dpi->enable(in);  	if (r)  		return r; -	if (gpio_is_valid(ddata->enable_gpio)) -		gpio_set_value_cansleep(ddata->enable_gpio, 1); +	if (ddata->enable_gpio) +		gpiod_set_value_cansleep(ddata->enable_gpio, 1);  	if (gpio_is_valid(ddata->backlight_gpio))  		gpio_set_value_cansleep(ddata->backlight_gpio, 1); @@ -184,8 +186,8 @@ static void lb035q02_disable(struct omap_dss_device *dssdev)  	if (!omapdss_device_is_enabled(dssdev))  		return; -	if (gpio_is_valid(ddata->enable_gpio)) -		gpio_set_value_cansleep(ddata->enable_gpio, 0); +	if (ddata->enable_gpio) +		gpiod_set_value_cansleep(ddata->enable_gpio, 0);  	if (gpio_is_valid(ddata->backlight_gpio))  		gpio_set_value_cansleep(ddata->backlight_gpio, 0); @@ -243,6 +245,7 @@ static int lb035q02_probe_pdata(struct spi_device *spi)  	const struct panel_lb035q02_platform_data *pdata;  	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev);  	struct omap_dss_device *dssdev, *in; +	int r;  	pdata = dev_get_platdata(&spi->dev); @@ -260,10 +263,48 @@ static int lb035q02_probe_pdata(struct spi_device *spi)  	dssdev = &ddata->dssdev;  	dssdev->name = pdata->name; -	ddata->enable_gpio = pdata->enable_gpio; +	r = devm_gpio_request_one(&spi->dev, pdata->enable_gpio, +					GPIOF_OUT_INIT_LOW, "panel enable"); +	if (r) +		goto err_gpio; + +	ddata->enable_gpio = gpio_to_desc(pdata->enable_gpio); +  	ddata->backlight_gpio = pdata->backlight_gpio;  	return 0; +err_gpio: +	omap_dss_put_device(ddata->in); +	return r; +} + +static int lb035q02_probe_of(struct spi_device *spi) +{ +	struct device_node *node = spi->dev.of_node; +	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); +	struct omap_dss_device *in; +	struct gpio_desc *gpio; + +	gpio = devm_gpiod_get(&spi->dev, "enable"); +	if (IS_ERR(gpio)) { +		dev_err(&spi->dev, "failed to parse enable gpio\n"); +		return PTR_ERR(gpio); +	} else { +		gpiod_direction_output(gpio, 0); +		ddata->enable_gpio = gpio; +	} + +	ddata->backlight_gpio = -ENOENT; + +	in = omapdss_of_find_source_for_first_ep(node); +	if (IS_ERR(in)) { +		dev_err(&spi->dev, "failed to find video source\n"); +		return PTR_ERR(in); +	} + +	ddata->in = in; + +	return 0;  }  static int lb035q02_panel_spi_probe(struct spi_device *spi) @@ -284,17 +325,14 @@ static int lb035q02_panel_spi_probe(struct spi_device *spi)  		r = lb035q02_probe_pdata(spi);  		if (r)  			return r; +	} else if (spi->dev.of_node) { +		r = lb035q02_probe_of(spi); +		if (r) +			return r;  	} else {  		return -ENODEV;  	} -	if (gpio_is_valid(ddata->enable_gpio)) { -		r = devm_gpio_request_one(&spi->dev, ddata->enable_gpio, -				GPIOF_OUT_INIT_LOW, "panel enable"); -		if (r) -			goto err_gpio; -	} -  	if (gpio_is_valid(ddata->backlight_gpio)) {  		r = devm_gpio_request_one(&spi->dev, ddata->backlight_gpio,  				GPIOF_OUT_INIT_LOW, "panel backlight"); @@ -342,17 +380,26 @@ static int lb035q02_panel_spi_remove(struct spi_device *spi)  	return 0;  } +static const struct of_device_id lb035q02_of_match[] = { +	{ .compatible = "omapdss,lgphilips,lb035q02", }, +	{}, +}; + +MODULE_DEVICE_TABLE(of, lb035q02_of_match); +  static struct spi_driver lb035q02_spi_driver = {  	.probe		= lb035q02_panel_spi_probe,  	.remove		= lb035q02_panel_spi_remove,  	.driver		= {  		.name	= "panel_lgphilips_lb035q02",  		.owner	= THIS_MODULE, +		.of_match_table = lb035q02_of_match,  	},  };  module_spi_driver(lb035q02_spi_driver); +MODULE_ALIAS("spi:lgphilips,lb035q02");  MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");  MODULE_DESCRIPTION("LG.Philips LB035Q02 LCD Panel driver");  MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c b/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c index bb217da65c5..3595f111aa3 100644 --- a/drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c @@ -16,6 +16,7 @@  #include <linux/spi/spi.h>  #include <linux/fb.h>  #include <linux/gpio.h> +#include <linux/of_gpio.h>  #include <video/omapdss.h>  #include <video/omap-panel-data.h> @@ -40,7 +41,7 @@ struct panel_drv_data {   * NEC PIX Clock Ratings   * MIN:21.8MHz TYP:23.8MHz MAX:25.7MHz   */ -#define LCD_PIXEL_CLOCK		23800 +#define LCD_PIXEL_CLOCK		23800000  static const struct {  	unsigned char addr; @@ -69,7 +70,7 @@ static const struct {  static const struct omap_video_timings nec_8048_panel_timings = {  	.x_res		= LCD_XRES,  	.y_res		= LCD_YRES, -	.pixel_clock	= LCD_PIXEL_CLOCK, +	.pixelclock	= LCD_PIXEL_CLOCK,  	.hfp		= 6,  	.hsw		= 1,  	.hbp		= 4, @@ -156,7 +157,8 @@ static int nec_8048_enable(struct omap_dss_device *dssdev)  	if (omapdss_device_is_enabled(dssdev))  		return 0; -	in->ops.dpi->set_data_lines(in, ddata->data_lines); +	if (ddata->data_lines) +		in->ops.dpi->set_data_lines(in, ddata->data_lines);  	in->ops.dpi->set_timings(in, &ddata->videomode);  	r = in->ops.dpi->enable(in); @@ -258,6 +260,34 @@ static int nec_8048_probe_pdata(struct spi_device *spi)  	return 0;  } +static int nec_8048_probe_of(struct spi_device *spi) +{ +	struct device_node *node = spi->dev.of_node; +	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); +	struct omap_dss_device *in; +	int gpio; + +	gpio = of_get_named_gpio(node, "reset-gpios", 0); +	if (!gpio_is_valid(gpio)) { +		dev_err(&spi->dev, "failed to parse enable gpio\n"); +		return gpio; +	} +	ddata->res_gpio = gpio; + +	/* XXX the panel spec doesn't mention any QVGA pin?? */ +	ddata->qvga_gpio = -ENOENT; + +	in = omapdss_of_find_source_for_first_ep(node); +	if (IS_ERR(in)) { +		dev_err(&spi->dev, "failed to find video source\n"); +		return PTR_ERR(in); +	} + +	ddata->in = in; + +	return 0; +} +  static int nec_8048_probe(struct spi_device *spi)  {  	struct panel_drv_data *ddata; @@ -289,6 +319,10 @@ static int nec_8048_probe(struct spi_device *spi)  		r = nec_8048_probe_pdata(spi);  		if (r)  			return r; +	} else if (spi->dev.of_node) { +		r = nec_8048_probe_of(spi); +		if (r) +			return r;  	} else {  		return -ENODEV;  	} @@ -377,11 +411,19 @@ static SIMPLE_DEV_PM_OPS(nec_8048_pm_ops, nec_8048_suspend,  #define NEC_8048_PM_OPS NULL  #endif +static const struct of_device_id nec_8048_of_match[] = { +	{ .compatible = "omapdss,nec,nl8048hl11", }, +	{}, +}; + +MODULE_DEVICE_TABLE(of, nec_8048_of_match); +  static struct spi_driver nec_8048_driver = {  	.driver = {  		.name	= "panel-nec-nl8048hl11",  		.owner	= THIS_MODULE,  		.pm	= NEC_8048_PM_OPS, +		.of_match_table = nec_8048_of_match,  	},  	.probe	= nec_8048_probe,  	.remove	= nec_8048_remove, @@ -389,6 +431,7 @@ static struct spi_driver nec_8048_driver = {  module_spi_driver(nec_8048_driver); +MODULE_ALIAS("spi:nec,nl8048hl11");  MODULE_AUTHOR("Erik Gilling <konkers@android.com>");  MODULE_DESCRIPTION("NEC-NL8048HL11 Driver");  MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c index 72a4fb5aa6b..f1f72ce50a1 100644 --- a/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c @@ -12,32 +12,35 @@  #include <linux/delay.h>  #include <linux/gpio.h>  #include <linux/module.h> +#include <linux/of.h> +#include <linux/of_gpio.h>  #include <linux/platform_device.h>  #include <linux/slab.h> - +#include <linux/regulator/consumer.h>  #include <video/omapdss.h>  #include <video/omap-panel-data.h>  struct panel_drv_data {  	struct omap_dss_device dssdev;  	struct omap_dss_device *in; +	struct regulator *vcc;  	int data_lines;  	struct omap_video_timings videomode; -	int resb_gpio; -	int ini_gpio; -	int mo_gpio; -	int lr_gpio; -	int ud_gpio; +	struct gpio_desc *resb_gpio;	/* low = reset active min 20 us */ +	struct gpio_desc *ini_gpio;	/* high = power on */ +	struct gpio_desc *mo_gpio;	/* low = 480x640, high = 240x320 */ +	struct gpio_desc *lr_gpio;	/* high = conventional horizontal scanning */ +	struct gpio_desc *ud_gpio;	/* high = conventional vertical scanning */  };  static const struct omap_video_timings sharp_ls_timings = {  	.x_res = 480,  	.y_res = 640, -	.pixel_clock	= 19200, +	.pixelclock	= 19200000,  	.hsw		= 2,  	.hfp		= 1, @@ -95,21 +98,30 @@ static int sharp_ls_enable(struct omap_dss_device *dssdev)  	if (omapdss_device_is_enabled(dssdev))  		return 0; -	in->ops.dpi->set_data_lines(in, ddata->data_lines); +	if (ddata->data_lines) +		in->ops.dpi->set_data_lines(in, ddata->data_lines);  	in->ops.dpi->set_timings(in, &ddata->videomode); +	if (ddata->vcc) { +		r = regulator_enable(ddata->vcc); +		if (r != 0) +			return r; +	} +  	r = in->ops.dpi->enable(in); -	if (r) +	if (r) { +		regulator_disable(ddata->vcc);  		return r; +	}  	/* wait couple of vsyncs until enabling the LCD */  	msleep(50); -	if (gpio_is_valid(ddata->resb_gpio)) -		gpio_set_value_cansleep(ddata->resb_gpio, 1); +	if (ddata->resb_gpio) +		gpiod_set_value_cansleep(ddata->resb_gpio, 1); -	if (gpio_is_valid(ddata->ini_gpio)) -		gpio_set_value_cansleep(ddata->ini_gpio, 1); +	if (ddata->ini_gpio) +		gpiod_set_value_cansleep(ddata->ini_gpio, 1);  	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; @@ -124,11 +136,11 @@ static void sharp_ls_disable(struct omap_dss_device *dssdev)  	if (!omapdss_device_is_enabled(dssdev))  		return; -	if (gpio_is_valid(ddata->ini_gpio)) -		gpio_set_value_cansleep(ddata->ini_gpio, 0); +	if (ddata->ini_gpio) +		gpiod_set_value_cansleep(ddata->ini_gpio, 0); -	if (gpio_is_valid(ddata->resb_gpio)) -		gpio_set_value_cansleep(ddata->resb_gpio, 0); +	if (ddata->resb_gpio) +		gpiod_set_value_cansleep(ddata->resb_gpio, 0);  	/* wait at least 5 vsyncs after disabling the LCD */ @@ -136,6 +148,9 @@ static void sharp_ls_disable(struct omap_dss_device *dssdev)  	in->ops.dpi->disable(in); +	if (ddata->vcc) +		regulator_disable(ddata->vcc); +  	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;  } @@ -182,11 +197,32 @@ static struct omap_dss_driver sharp_ls_ops = {  	.get_resolution	= omapdss_default_get_resolution,  }; +static int sharp_ls_get_gpio(struct device *dev, int gpio, unsigned long flags, +		  char *desc, struct gpio_desc **gpiod) +{ +	struct gpio_desc *gd; +	int r; + +	*gpiod = NULL; + +	r = devm_gpio_request_one(dev, gpio, flags, desc); +	if (r) +		return r == -ENOENT ? 0 : r; + +	gd = gpio_to_desc(gpio); +	if (IS_ERR(gd)) +		return PTR_ERR(gd) == -ENOENT ? 0 : PTR_ERR(gd); + +	*gpiod = gd; +	return 0; +} +  static int sharp_ls_probe_pdata(struct platform_device *pdev)  {  	const struct panel_sharp_ls037v7dw01_platform_data *pdata;  	struct panel_drv_data *ddata = platform_get_drvdata(pdev);  	struct omap_dss_device *dssdev, *in; +	int r;  	pdata = dev_get_platdata(&pdev->dev); @@ -204,11 +240,95 @@ static int sharp_ls_probe_pdata(struct platform_device *pdev)  	dssdev = &ddata->dssdev;  	dssdev->name = pdata->name; -	ddata->resb_gpio = pdata->resb_gpio; -	ddata->ini_gpio = pdata->ini_gpio; -	ddata->mo_gpio = pdata->mo_gpio; -	ddata->lr_gpio = pdata->lr_gpio; -	ddata->ud_gpio = pdata->ud_gpio; +	r = sharp_ls_get_gpio(&pdev->dev, pdata->mo_gpio, GPIOF_OUT_INIT_LOW, +		"lcd MO", &ddata->mo_gpio); +	if (r) +		return r; +	r = sharp_ls_get_gpio(&pdev->dev, pdata->lr_gpio, GPIOF_OUT_INIT_HIGH, +		"lcd LR", &ddata->lr_gpio); +	if (r) +		return r; +	r = sharp_ls_get_gpio(&pdev->dev, pdata->ud_gpio, GPIOF_OUT_INIT_HIGH, +		"lcd UD", &ddata->ud_gpio); +	if (r) +		return r; +	r = sharp_ls_get_gpio(&pdev->dev, pdata->resb_gpio, GPIOF_OUT_INIT_LOW, +		"lcd RESB", &ddata->resb_gpio); +	if (r) +		return r; +	r = sharp_ls_get_gpio(&pdev->dev, pdata->ini_gpio, GPIOF_OUT_INIT_LOW, +		"lcd INI", &ddata->ini_gpio); +	if (r) +		return r; + +	return 0; +} + +static  int sharp_ls_get_gpio_of(struct device *dev, int index, int val, +	const char *desc, struct gpio_desc **gpiod) +{ +	struct gpio_desc *gd; +	int r; + +	*gpiod = NULL; + +	gd = devm_gpiod_get_index(dev, desc, index); +	if (IS_ERR(gd)) +		return PTR_ERR(gd) == -ENOENT ? 0 : PTR_ERR(gd); + +	r = gpiod_direction_output(gd, val); +	if (r) +		return r; + +	*gpiod = gd; +	return 0; +} + +static int sharp_ls_probe_of(struct platform_device *pdev) +{ +	struct panel_drv_data *ddata = platform_get_drvdata(pdev); +	struct device_node *node = pdev->dev.of_node; +	struct omap_dss_device *in; +	int r; + +	ddata->vcc = devm_regulator_get(&pdev->dev, "envdd"); +	if (IS_ERR(ddata->vcc)) { +		dev_err(&pdev->dev, "failed to get regulator\n"); +		return PTR_ERR(ddata->vcc); +	} + +	/* lcd INI */ +	r = sharp_ls_get_gpio_of(&pdev->dev, 0, 0, "enable", &ddata->ini_gpio); +	if (r) +		return r; + +	/* lcd RESB */ +	r = sharp_ls_get_gpio_of(&pdev->dev, 0, 0, "reset", &ddata->resb_gpio); +	if (r) +		return r; + +	/* lcd MO */ +	r = sharp_ls_get_gpio_of(&pdev->dev, 0, 0, "mode", &ddata->mo_gpio); +	if (r) +		return r; + +	/* lcd LR */ +	r = sharp_ls_get_gpio_of(&pdev->dev, 1, 1, "mode", &ddata->lr_gpio); +	if (r) +		return r; + +	/* lcd UD */ +	r = sharp_ls_get_gpio_of(&pdev->dev, 2, 1, "mode", &ddata->ud_gpio); +	if (r) +		return r; + +	in = omapdss_of_find_source_for_first_ep(node); +	if (IS_ERR(in)) { +		dev_err(&pdev->dev, "failed to find video source\n"); +		return PTR_ERR(in); +	} + +	ddata->in = in;  	return 0;  } @@ -229,45 +349,14 @@ static int sharp_ls_probe(struct platform_device *pdev)  		r = sharp_ls_probe_pdata(pdev);  		if (r)  			return r; +	} else if (pdev->dev.of_node) { +		r = sharp_ls_probe_of(pdev); +		if (r) +			return r;  	} else {  		return -ENODEV;  	} -	if (gpio_is_valid(ddata->mo_gpio)) { -		r = devm_gpio_request_one(&pdev->dev, ddata->mo_gpio, -				GPIOF_OUT_INIT_LOW, "lcd MO"); -		if (r) -			goto err_gpio; -	} - -	if (gpio_is_valid(ddata->lr_gpio)) { -		r = devm_gpio_request_one(&pdev->dev, ddata->lr_gpio, -				GPIOF_OUT_INIT_HIGH, "lcd LR"); -		if (r) -			goto err_gpio; -	} - -	if (gpio_is_valid(ddata->ud_gpio)) { -		r = devm_gpio_request_one(&pdev->dev, ddata->ud_gpio, -				GPIOF_OUT_INIT_HIGH, "lcd UD"); -		if (r) -			goto err_gpio; -	} - -	if (gpio_is_valid(ddata->resb_gpio)) { -		r = devm_gpio_request_one(&pdev->dev, ddata->resb_gpio, -				GPIOF_OUT_INIT_LOW, "lcd RESB"); -		if (r) -			goto err_gpio; -	} - -	if (gpio_is_valid(ddata->ini_gpio)) { -		r = devm_gpio_request_one(&pdev->dev, ddata->ini_gpio, -				GPIOF_OUT_INIT_LOW, "lcd INI"); -		if (r) -			goto err_gpio; -	} -  	ddata->videomode = sharp_ls_timings;  	dssdev = &ddata->dssdev; @@ -287,7 +376,6 @@ static int sharp_ls_probe(struct platform_device *pdev)  	return 0;  err_reg: -err_gpio:  	omap_dss_put_device(ddata->in);  	return r;  } @@ -308,12 +396,20 @@ static int __exit sharp_ls_remove(struct platform_device *pdev)  	return 0;  } +static const struct of_device_id sharp_ls_of_match[] = { +	{ .compatible = "omapdss,sharp,ls037v7dw01", }, +	{}, +}; + +MODULE_DEVICE_TABLE(of, sharp_ls_of_match); +  static struct platform_driver sharp_ls_driver = {  	.probe = sharp_ls_probe,  	.remove = __exit_p(sharp_ls_remove),  	.driver = {  		.name = "panel-sharp-ls037v7dw01",  		.owner = THIS_MODULE, +		.of_match_table = sharp_ls_of_match,  	},  }; diff --git a/drivers/video/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c index e6d56f714ae..c7ba4d8b928 100644 --- a/drivers/video/omap2/displays-new/panel-sony-acx565akm.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c @@ -30,6 +30,8 @@  #include <linux/backlight.h>  #include <linux/fb.h>  #include <linux/gpio.h> +#include <linux/of.h> +#include <linux/of_gpio.h>  #include <video/omapdss.h>  #include <video/omap-panel-data.h> @@ -93,7 +95,7 @@ struct panel_drv_data {  static const struct omap_video_timings acx565akm_panel_timings = {  	.x_res		= 800,  	.y_res		= 480, -	.pixel_clock	= 24000, +	.pixelclock	= 24000000,  	.hfp		= 28,  	.hsw		= 4,  	.hbp		= 24, @@ -346,28 +348,22 @@ static int acx565akm_get_actual_brightness(struct panel_drv_data *ddata)  static int acx565akm_bl_update_status(struct backlight_device *dev)  {  	struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev); -	int r;  	int level;  	dev_dbg(&ddata->spi->dev, "%s\n", __func__); -	mutex_lock(&ddata->mutex); -  	if (dev->props.fb_blank == FB_BLANK_UNBLANK &&  			dev->props.power == FB_BLANK_UNBLANK)  		level = dev->props.brightness;  	else  		level = 0; -	r = 0;  	if (ddata->has_bc)  		acx565akm_set_brightness(ddata, level);  	else -		r = -ENODEV; - -	mutex_unlock(&ddata->mutex); +		return -ENODEV; -	return r; +	return 0;  }  static int acx565akm_bl_get_intensity(struct backlight_device *dev) @@ -390,9 +386,33 @@ static int acx565akm_bl_get_intensity(struct backlight_device *dev)  	return 0;  } +static int acx565akm_bl_update_status_locked(struct backlight_device *dev) +{ +	struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev); +	int r; + +	mutex_lock(&ddata->mutex); +	r = acx565akm_bl_update_status(dev); +	mutex_unlock(&ddata->mutex); + +	return r; +} + +static int acx565akm_bl_get_intensity_locked(struct backlight_device *dev) +{ +	struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev); +	int r; + +	mutex_lock(&ddata->mutex); +	r = acx565akm_bl_get_intensity(dev); +	mutex_unlock(&ddata->mutex); + +	return r; +} +  static const struct backlight_ops acx565akm_bl_ops = { -	.get_brightness = acx565akm_bl_get_intensity, -	.update_status  = acx565akm_bl_update_status, +	.get_brightness = acx565akm_bl_get_intensity_locked, +	.update_status  = acx565akm_bl_update_status_locked,  };  /*--------------------Auto Brightness control via Sysfs---------------------*/ @@ -529,7 +549,9 @@ static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)  	dev_dbg(&ddata->spi->dev, "%s\n", __func__);  	in->ops.sdi->set_timings(in, &ddata->videomode); -	in->ops.sdi->set_datapairs(in, ddata->datapairs); + +	if (ddata->datapairs > 0) +		in->ops.sdi->set_datapairs(in, ddata->datapairs);  	r = in->ops.sdi->enable(in);  	if (r) { @@ -566,8 +588,6 @@ static int acx565akm_panel_power_on(struct omap_dss_device *dssdev)  	set_display_state(ddata, 1);  	set_cabc_mode(ddata, ddata->cabc_mode); -	mutex_unlock(&ddata->mutex); -  	return acx565akm_bl_update_status(ddata->bl_dev);  } @@ -617,7 +637,6 @@ static int acx565akm_enable(struct omap_dss_device *dssdev)  	mutex_lock(&ddata->mutex);  	r = acx565akm_panel_power_on(dssdev);  	mutex_unlock(&ddata->mutex); -  	if (r)  		return r; @@ -711,6 +730,22 @@ static int acx565akm_probe_pdata(struct spi_device *spi)  	return 0;  } +static int acx565akm_probe_of(struct spi_device *spi) +{ +	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); +	struct device_node *np = spi->dev.of_node; + +	ddata->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); + +	ddata->in = omapdss_of_find_source_for_first_ep(np); +	if (IS_ERR(ddata->in)) { +		dev_err(&spi->dev, "failed to find video source\n"); +		return PTR_ERR(ddata->in); +	} + +	return 0; +} +  static int acx565akm_probe(struct spi_device *spi)  {  	struct panel_drv_data *ddata; @@ -738,7 +773,12 @@ static int acx565akm_probe(struct spi_device *spi)  		r = acx565akm_probe_pdata(spi);  		if (r)  			return r; +	} else if (spi->dev.of_node) { +		r = acx565akm_probe_of(spi); +		if (r) +			return r;  	} else { +		dev_err(&spi->dev, "platform data missing!\n");  		return -ENODEV;  	} @@ -849,10 +889,16 @@ static int acx565akm_remove(struct spi_device *spi)  	return 0;  } +static const struct of_device_id acx565akm_of_match[] = { +	{ .compatible = "omapdss,sony,acx565akm", }, +	{}, +}; +  static struct spi_driver acx565akm_driver = {  	.driver = {  		.name	= "acx565akm",  		.owner	= THIS_MODULE, +		.of_match_table = acx565akm_of_match,  	},  	.probe	= acx565akm_probe,  	.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 new file mode 100644 index 00000000000..728808bccee --- /dev/null +++ b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c @@ -0,0 +1,511 @@ +/* + * Toppoly TD028TTEC1 panel support + * + * Copyright (C) 2008 Nokia Corporation + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> + * + * Neo 1973 code (jbt6k74.c): + * Copyright (C) 2006-2007 by OpenMoko, Inc. + * Author: Harald Welte <laforge@openmoko.org> + * + * Ported and adapted from Neo 1973 U-Boot by: + * H. Nikolaus Schaller <hns@goldelico.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/module.h> +#include <linux/delay.h> +#include <linux/spi/spi.h> +#include <linux/gpio.h> +#include <video/omapdss.h> +#include <video/omap-panel-data.h> + +struct panel_drv_data { +	struct omap_dss_device dssdev; +	struct omap_dss_device *in; + +	int data_lines; + +	struct omap_video_timings videomode; + +	struct spi_device *spi_dev; +}; + +static struct omap_video_timings td028ttec1_panel_timings = { +	.x_res		= 480, +	.y_res		= 640, +	.pixelclock	= 22153000, +	.hfp		= 24, +	.hsw		= 8, +	.hbp		= 8, +	.vfp		= 4, +	.vsw		= 2, +	.vbp		= 2, + +	.vsync_level	= OMAPDSS_SIG_ACTIVE_LOW, +	.hsync_level	= OMAPDSS_SIG_ACTIVE_LOW, + +	.data_pclk_edge	= OMAPDSS_DRIVE_SIG_FALLING_EDGE, +	.de_level	= OMAPDSS_SIG_ACTIVE_HIGH, +	.sync_pclk_edge	= OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, +}; + +#define JBT_COMMAND	0x000 +#define JBT_DATA	0x100 + +static int jbt_ret_write_0(struct panel_drv_data *ddata, u8 reg) +{ +	int rc; +	u16 tx_buf = JBT_COMMAND | reg; + +	rc = spi_write(ddata->spi_dev, (u8 *)&tx_buf, +			1*sizeof(u16)); +	if (rc != 0) +		dev_err(&ddata->spi_dev->dev, +			"jbt_ret_write_0 spi_write ret %d\n", rc); + +	return rc; +} + +static int jbt_reg_write_1(struct panel_drv_data *ddata, u8 reg, u8 data) +{ +	int rc; +	u16 tx_buf[2]; + +	tx_buf[0] = JBT_COMMAND | reg; +	tx_buf[1] = JBT_DATA | data; +	rc = spi_write(ddata->spi_dev, (u8 *)tx_buf, +			2*sizeof(u16)); +	if (rc != 0) +		dev_err(&ddata->spi_dev->dev, +			"jbt_reg_write_1 spi_write ret %d\n", rc); + +	return rc; +} + +static int jbt_reg_write_2(struct panel_drv_data *ddata, u8 reg, u16 data) +{ +	int rc; +	u16 tx_buf[3]; + +	tx_buf[0] = JBT_COMMAND | reg; +	tx_buf[1] = JBT_DATA | (data >> 8); +	tx_buf[2] = JBT_DATA | (data & 0xff); + +	rc = spi_write(ddata->spi_dev, (u8 *)tx_buf, +			3*sizeof(u16)); + +	if (rc != 0) +		dev_err(&ddata->spi_dev->dev, +			"jbt_reg_write_2 spi_write ret %d\n", rc); + +	return rc; +} + +enum jbt_register { +	JBT_REG_SLEEP_IN		= 0x10, +	JBT_REG_SLEEP_OUT		= 0x11, + +	JBT_REG_DISPLAY_OFF		= 0x28, +	JBT_REG_DISPLAY_ON		= 0x29, + +	JBT_REG_RGB_FORMAT		= 0x3a, +	JBT_REG_QUAD_RATE		= 0x3b, + +	JBT_REG_POWER_ON_OFF		= 0xb0, +	JBT_REG_BOOSTER_OP		= 0xb1, +	JBT_REG_BOOSTER_MODE		= 0xb2, +	JBT_REG_BOOSTER_FREQ		= 0xb3, +	JBT_REG_OPAMP_SYSCLK		= 0xb4, +	JBT_REG_VSC_VOLTAGE		= 0xb5, +	JBT_REG_VCOM_VOLTAGE		= 0xb6, +	JBT_REG_EXT_DISPL		= 0xb7, +	JBT_REG_OUTPUT_CONTROL		= 0xb8, +	JBT_REG_DCCLK_DCEV		= 0xb9, +	JBT_REG_DISPLAY_MODE1		= 0xba, +	JBT_REG_DISPLAY_MODE2		= 0xbb, +	JBT_REG_DISPLAY_MODE		= 0xbc, +	JBT_REG_ASW_SLEW		= 0xbd, +	JBT_REG_DUMMY_DISPLAY		= 0xbe, +	JBT_REG_DRIVE_SYSTEM		= 0xbf, + +	JBT_REG_SLEEP_OUT_FR_A		= 0xc0, +	JBT_REG_SLEEP_OUT_FR_B		= 0xc1, +	JBT_REG_SLEEP_OUT_FR_C		= 0xc2, +	JBT_REG_SLEEP_IN_LCCNT_D	= 0xc3, +	JBT_REG_SLEEP_IN_LCCNT_E	= 0xc4, +	JBT_REG_SLEEP_IN_LCCNT_F	= 0xc5, +	JBT_REG_SLEEP_IN_LCCNT_G	= 0xc6, + +	JBT_REG_GAMMA1_FINE_1		= 0xc7, +	JBT_REG_GAMMA1_FINE_2		= 0xc8, +	JBT_REG_GAMMA1_INCLINATION	= 0xc9, +	JBT_REG_GAMMA1_BLUE_OFFSET	= 0xca, + +	JBT_REG_BLANK_CONTROL		= 0xcf, +	JBT_REG_BLANK_TH_TV		= 0xd0, +	JBT_REG_CKV_ON_OFF		= 0xd1, +	JBT_REG_CKV_1_2			= 0xd2, +	JBT_REG_OEV_TIMING		= 0xd3, +	JBT_REG_ASW_TIMING_1		= 0xd4, +	JBT_REG_ASW_TIMING_2		= 0xd5, + +	JBT_REG_HCLOCK_VGA		= 0xec, +	JBT_REG_HCLOCK_QVGA		= 0xed, +}; + +#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev) + +static int td028ttec1_panel_connect(struct omap_dss_device *dssdev) +{ +	struct panel_drv_data *ddata = to_panel_data(dssdev); +	struct omap_dss_device *in = ddata->in; +	int r; + +	if (omapdss_device_is_connected(dssdev)) +		return 0; + +	r = in->ops.dpi->connect(in, dssdev); +	if (r) +		return r; + +	return 0; +} + +static void td028ttec1_panel_disconnect(struct omap_dss_device *dssdev) +{ +	struct panel_drv_data *ddata = to_panel_data(dssdev); +	struct omap_dss_device *in = ddata->in; + +	if (!omapdss_device_is_connected(dssdev)) +		return; + +	in->ops.dpi->disconnect(in, dssdev); +} + +static int td028ttec1_panel_enable(struct omap_dss_device *dssdev) +{ +	struct panel_drv_data *ddata = to_panel_data(dssdev); +	struct omap_dss_device *in = ddata->in; +	int r; + +	if (!omapdss_device_is_connected(dssdev)) +		return -ENODEV; + +	if (omapdss_device_is_enabled(dssdev)) +		return 0; + +	if (ddata->data_lines) +		in->ops.dpi->set_data_lines(in, ddata->data_lines); +	in->ops.dpi->set_timings(in, &ddata->videomode); + +	r = in->ops.dpi->enable(in); +	if (r) +		return r; + +	dev_dbg(dssdev->dev, "td028ttec1_panel_enable() - state %d\n", +		dssdev->state); + +	/* three times command zero */ +	r |= jbt_ret_write_0(ddata, 0x00); +	usleep_range(1000, 2000); +	r |= jbt_ret_write_0(ddata, 0x00); +	usleep_range(1000, 2000); +	r |= jbt_ret_write_0(ddata, 0x00); +	usleep_range(1000, 2000); + +	if (r) { +		dev_warn(dssdev->dev, "transfer error\n"); +		goto transfer_err; +	} + +	/* deep standby out */ +	r |= jbt_reg_write_1(ddata, JBT_REG_POWER_ON_OFF, 0x17); + +	/* RGB I/F on, RAM write off, QVGA through, SIGCON enable */ +	r |= jbt_reg_write_1(ddata, JBT_REG_DISPLAY_MODE, 0x80); + +	/* Quad mode off */ +	r |= jbt_reg_write_1(ddata, JBT_REG_QUAD_RATE, 0x00); + +	/* AVDD on, XVDD on */ +	r |= jbt_reg_write_1(ddata, JBT_REG_POWER_ON_OFF, 0x16); + +	/* Output control */ +	r |= jbt_reg_write_2(ddata, JBT_REG_OUTPUT_CONTROL, 0xfff9); + +	/* Sleep mode off */ +	r |= jbt_ret_write_0(ddata, JBT_REG_SLEEP_OUT); + +	/* at this point we have like 50% grey */ + +	/* initialize register set */ +	r |= jbt_reg_write_1(ddata, JBT_REG_DISPLAY_MODE1, 0x01); +	r |= jbt_reg_write_1(ddata, JBT_REG_DISPLAY_MODE2, 0x00); +	r |= jbt_reg_write_1(ddata, JBT_REG_RGB_FORMAT, 0x60); +	r |= jbt_reg_write_1(ddata, JBT_REG_DRIVE_SYSTEM, 0x10); +	r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_OP, 0x56); +	r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_MODE, 0x33); +	r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_FREQ, 0x11); +	r |= jbt_reg_write_1(ddata, JBT_REG_BOOSTER_FREQ, 0x11); +	r |= jbt_reg_write_1(ddata, JBT_REG_OPAMP_SYSCLK, 0x02); +	r |= jbt_reg_write_1(ddata, JBT_REG_VSC_VOLTAGE, 0x2b); +	r |= jbt_reg_write_1(ddata, JBT_REG_VCOM_VOLTAGE, 0x40); +	r |= jbt_reg_write_1(ddata, JBT_REG_EXT_DISPL, 0x03); +	r |= jbt_reg_write_1(ddata, JBT_REG_DCCLK_DCEV, 0x04); +	/* +	 * default of 0x02 in JBT_REG_ASW_SLEW responsible for 72Hz requirement +	 * to avoid red / blue flicker +	 */ +	r |= jbt_reg_write_1(ddata, JBT_REG_ASW_SLEW, 0x04); +	r |= jbt_reg_write_1(ddata, JBT_REG_DUMMY_DISPLAY, 0x00); + +	r |= jbt_reg_write_1(ddata, JBT_REG_SLEEP_OUT_FR_A, 0x11); +	r |= jbt_reg_write_1(ddata, JBT_REG_SLEEP_OUT_FR_B, 0x11); +	r |= jbt_reg_write_1(ddata, JBT_REG_SLEEP_OUT_FR_C, 0x11); +	r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_D, 0x2040); +	r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_E, 0x60c0); +	r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_F, 0x1020); +	r |= jbt_reg_write_2(ddata, JBT_REG_SLEEP_IN_LCCNT_G, 0x60c0); + +	r |= jbt_reg_write_2(ddata, JBT_REG_GAMMA1_FINE_1, 0x5533); +	r |= jbt_reg_write_1(ddata, JBT_REG_GAMMA1_FINE_2, 0x00); +	r |= jbt_reg_write_1(ddata, JBT_REG_GAMMA1_INCLINATION, 0x00); +	r |= jbt_reg_write_1(ddata, JBT_REG_GAMMA1_BLUE_OFFSET, 0x00); + +	r |= jbt_reg_write_2(ddata, JBT_REG_HCLOCK_VGA, 0x1f0); +	r |= jbt_reg_write_1(ddata, JBT_REG_BLANK_CONTROL, 0x02); +	r |= jbt_reg_write_2(ddata, JBT_REG_BLANK_TH_TV, 0x0804); + +	r |= jbt_reg_write_1(ddata, JBT_REG_CKV_ON_OFF, 0x01); +	r |= jbt_reg_write_2(ddata, JBT_REG_CKV_1_2, 0x0000); + +	r |= jbt_reg_write_2(ddata, JBT_REG_OEV_TIMING, 0x0d0e); +	r |= jbt_reg_write_2(ddata, JBT_REG_ASW_TIMING_1, 0x11a4); +	r |= jbt_reg_write_1(ddata, JBT_REG_ASW_TIMING_2, 0x0e); + +	r |= jbt_ret_write_0(ddata, JBT_REG_DISPLAY_ON); + +	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; + +transfer_err: + +	return r ? -EIO : 0; +} + +static void td028ttec1_panel_disable(struct omap_dss_device *dssdev) +{ +	struct panel_drv_data *ddata = to_panel_data(dssdev); +	struct omap_dss_device *in = ddata->in; + +	if (!omapdss_device_is_enabled(dssdev)) +		return; + +	dev_dbg(dssdev->dev, "td028ttec1_panel_disable()\n"); + +	jbt_ret_write_0(ddata, JBT_REG_DISPLAY_OFF); +	jbt_reg_write_2(ddata, JBT_REG_OUTPUT_CONTROL, 0x8002); +	jbt_ret_write_0(ddata, JBT_REG_SLEEP_IN); +	jbt_reg_write_1(ddata, JBT_REG_POWER_ON_OFF, 0x00); + +	in->ops.dpi->disable(in); + +	dssdev->state = OMAP_DSS_DISPLAY_DISABLED; +} + +static void td028ttec1_panel_set_timings(struct omap_dss_device *dssdev, +		struct omap_video_timings *timings) +{ +	struct panel_drv_data *ddata = to_panel_data(dssdev); +	struct omap_dss_device *in = ddata->in; + +	ddata->videomode = *timings; +	dssdev->panel.timings = *timings; + +	in->ops.dpi->set_timings(in, timings); +} + +static void td028ttec1_panel_get_timings(struct omap_dss_device *dssdev, +		struct omap_video_timings *timings) +{ +	struct panel_drv_data *ddata = to_panel_data(dssdev); + +	*timings = ddata->videomode; +} + +static int td028ttec1_panel_check_timings(struct omap_dss_device *dssdev, +		struct omap_video_timings *timings) +{ +	struct panel_drv_data *ddata = to_panel_data(dssdev); +	struct omap_dss_device *in = ddata->in; + +	return in->ops.dpi->check_timings(in, timings); +} + +static struct omap_dss_driver td028ttec1_ops = { +	.connect	= td028ttec1_panel_connect, +	.disconnect	= td028ttec1_panel_disconnect, + +	.enable		= td028ttec1_panel_enable, +	.disable	= td028ttec1_panel_disable, + +	.set_timings	= td028ttec1_panel_set_timings, +	.get_timings	= td028ttec1_panel_get_timings, +	.check_timings	= td028ttec1_panel_check_timings, +}; + +static int td028ttec1_panel_probe_pdata(struct spi_device *spi) +{ +	const struct panel_tpo_td028ttec1_platform_data *pdata; +	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); +	struct omap_dss_device *dssdev, *in; + +	pdata = dev_get_platdata(&spi->dev); + +	in = omap_dss_find_output(pdata->source); +	if (in == NULL) { +		dev_err(&spi->dev, "failed to find video source '%s'\n", +				pdata->source); +		return -EPROBE_DEFER; +	} + +	ddata->in = in; + +	ddata->data_lines = pdata->data_lines; + +	dssdev = &ddata->dssdev; +	dssdev->name = pdata->name; + +	return 0; +} + +static int td028ttec1_probe_of(struct spi_device *spi) +{ +	struct device_node *node = spi->dev.of_node; +	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); +	struct omap_dss_device *in; + +	in = omapdss_of_find_source_for_first_ep(node); +	if (IS_ERR(in)) { +		dev_err(&spi->dev, "failed to find video source\n"); +		return PTR_ERR(in); +	} + +	ddata->in = in; + +	return 0; +} + +static int td028ttec1_panel_probe(struct spi_device *spi) +{ +	struct panel_drv_data *ddata; +	struct omap_dss_device *dssdev; +	int r; + +	dev_dbg(&spi->dev, "%s\n", __func__); + +	spi->bits_per_word = 9; +	spi->mode = SPI_MODE_3; + +	r = spi_setup(spi); +	if (r < 0) { +		dev_err(&spi->dev, "spi_setup failed: %d\n", r); +		return r; +	} + +	ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL); +	if (ddata == NULL) +		return -ENOMEM; + +	dev_set_drvdata(&spi->dev, ddata); + +	ddata->spi_dev = spi; + +	if (dev_get_platdata(&spi->dev)) { +		r = td028ttec1_panel_probe_pdata(spi); +		if (r) +			return r; +	} else if (spi->dev.of_node) { +		r = td028ttec1_probe_of(spi); +		if (r) +			return r; +	} else { +		return -ENODEV; +	} + +	ddata->videomode = td028ttec1_panel_timings; + +	dssdev = &ddata->dssdev; +	dssdev->dev = &spi->dev; +	dssdev->driver = &td028ttec1_ops; +	dssdev->type = OMAP_DISPLAY_TYPE_DPI; +	dssdev->owner = THIS_MODULE; +	dssdev->panel.timings = ddata->videomode; +	dssdev->phy.dpi.data_lines = ddata->data_lines; + +	r = omapdss_register_display(dssdev); +	if (r) { +		dev_err(&spi->dev, "Failed to register panel\n"); +		goto err_reg; +	} + +	return 0; + +err_reg: +	omap_dss_put_device(ddata->in); +	return r; +} + +static int td028ttec1_panel_remove(struct spi_device *spi) +{ +	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); +	struct omap_dss_device *dssdev = &ddata->dssdev; +	struct omap_dss_device *in = ddata->in; + +	dev_dbg(&ddata->spi_dev->dev, "%s\n", __func__); + +	omapdss_unregister_display(dssdev); + +	td028ttec1_panel_disable(dssdev); +	td028ttec1_panel_disconnect(dssdev); + +	omap_dss_put_device(in); + +	return 0; +} + +static const struct of_device_id td028ttec1_of_match[] = { +	{ .compatible = "omapdss,toppoly,td028ttec1", }, +	{}, +}; + +MODULE_DEVICE_TABLE(of, td028ttec1_of_match); + +static struct spi_driver td028ttec1_spi_driver = { +	.probe		= td028ttec1_panel_probe, +	.remove		= td028ttec1_panel_remove, + +	.driver         = { +		.name   = "panel-tpo-td028ttec1", +		.owner  = THIS_MODULE, +		.of_match_table = td028ttec1_of_match, +	}, +}; + +module_spi_driver(td028ttec1_spi_driver); + +MODULE_ALIAS("spi:toppoly,td028ttec1"); +MODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>"); +MODULE_DESCRIPTION("Toppoly TD028TTEC1 panel driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c index eadc6529fa3..de78ab0caaa 100644 --- a/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c +++ b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c @@ -17,6 +17,7 @@  #include <linux/gpio.h>  #include <linux/err.h>  #include <linux/slab.h> +#include <linux/of_gpio.h>  #include <video/omapdss.h>  #include <video/omap-panel-data.h> @@ -76,7 +77,7 @@ static const struct omap_video_timings tpo_td043_timings = {  	.x_res		= 800,  	.y_res		= 480, -	.pixel_clock	= 36000, +	.pixelclock	= 36000000,  	.hsw		= 1,  	.hfp		= 68, @@ -376,7 +377,8 @@ static int tpo_td043_enable(struct omap_dss_device *dssdev)  	if (omapdss_device_is_enabled(dssdev))  		return 0; -	in->ops.dpi->set_data_lines(in, ddata->data_lines); +	if (ddata->data_lines) +		in->ops.dpi->set_data_lines(in, ddata->data_lines);  	in->ops.dpi->set_timings(in, &ddata->videomode);  	r = in->ops.dpi->enable(in); @@ -489,6 +491,31 @@ static int tpo_td043_probe_pdata(struct spi_device *spi)  	return 0;  } +static int tpo_td043_probe_of(struct spi_device *spi) +{ +	struct device_node *node = spi->dev.of_node; +	struct panel_drv_data *ddata = dev_get_drvdata(&spi->dev); +	struct omap_dss_device *in; +	int gpio; + +	gpio = of_get_named_gpio(node, "reset-gpios", 0); +	if (!gpio_is_valid(gpio)) { +		dev_err(&spi->dev, "failed to parse enable gpio\n"); +		return gpio; +	} +	ddata->nreset_gpio = gpio; + +	in = omapdss_of_find_source_for_first_ep(node); +	if (IS_ERR(in)) { +		dev_err(&spi->dev, "failed to find video source\n"); +		return PTR_ERR(in); +	} + +	ddata->in = in; + +	return 0; +} +  static int tpo_td043_probe(struct spi_device *spi)  {  	struct panel_drv_data *ddata; @@ -518,6 +545,10 @@ static int tpo_td043_probe(struct spi_device *spi)  		r = tpo_td043_probe_pdata(spi);  		if (r)  			return r; +	} else if (spi->dev.of_node) { +		r = tpo_td043_probe_of(spi); +		if (r) +			return r;  	} else {  		return -ENODEV;  	} @@ -629,11 +660,19 @@ static int tpo_td043_spi_resume(struct device *dev)  static SIMPLE_DEV_PM_OPS(tpo_td043_spi_pm,  	tpo_td043_spi_suspend, tpo_td043_spi_resume); +static const struct of_device_id tpo_td043_of_match[] = { +	{ .compatible = "omapdss,tpo,td043mtea1", }, +	{}, +}; + +MODULE_DEVICE_TABLE(of, tpo_td043_of_match); +  static struct spi_driver tpo_td043_spi_driver = {  	.driver = {  		.name	= "panel-tpo-td043mtea1",  		.owner	= THIS_MODULE,  		.pm	= &tpo_td043_spi_pm, +		.of_match_table = tpo_td043_of_match,  	},  	.probe	= tpo_td043_probe,  	.remove	= tpo_td043_remove, @@ -641,6 +680,7 @@ static struct spi_driver tpo_td043_spi_driver = {  module_spi_driver(tpo_td043_spi_driver); +MODULE_ALIAS("spi:tpo,td043mtea1");  MODULE_AUTHOR("Gražvydas Ignotas <notasas@gmail.com>");  MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver");  MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/fbdev/omap2/dss/Kconfig index dde4281663b..285bcd103dc 100644 --- a/drivers/video/omap2/dss/Kconfig +++ b/drivers/video/fbdev/omap2/dss/Kconfig @@ -1,6 +1,10 @@ +config OMAP2_DSS_INIT +	bool +  menuconfig OMAP2_DSS          tristate "OMAP2+ Display Subsystem support"  	select VIDEOMODE_HELPERS +	select OMAP2_DSS_INIT          help  	  OMAP2+ Display Subsystem support. @@ -59,16 +63,32 @@ config OMAP2_DSS_VENC  	help  	  OMAP Video Encoder support for S-Video and composite TV-out. +config OMAP2_DSS_HDMI_COMMON +	bool +  config OMAP4_DSS_HDMI -	bool "HDMI support" +	bool "HDMI support for OMAP4"          default y +	select OMAP2_DSS_HDMI_COMMON  	help -	  HDMI Interface. This adds the High Definition Multimedia Interface. -	  See http://www.hdmi.org/ for HDMI specification. +	  HDMI support for OMAP4 based SoCs.  config OMAP4_DSS_HDMI_AUDIO  	bool +config OMAP5_DSS_HDMI +	bool "HDMI support for OMAP5" +	default n +	select OMAP2_DSS_HDMI_COMMON +	help +	  HDMI Interface for OMAP5 and similar cores. This adds the High +	  Definition Multimedia Interface. See http://www.hdmi.org/ for HDMI +	  specification. + +config OMAP5_DSS_HDMI_AUDIO +	depends on OMAP5_DSS_HDMI +	bool +  config OMAP2_DSS_SDI  	bool "SDI support"          default n diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/fbdev/omap2/dss/Makefile index 94832eb06a3..245f933060e 100644 --- a/drivers/video/omap2/dss/Makefile +++ b/drivers/video/fbdev/omap2/dss/Makefile @@ -1,7 +1,8 @@ +obj-$(CONFIG_OMAP2_DSS_INIT) += omapdss-boot-init.o  obj-$(CONFIG_OMAP2_DSS) += omapdss.o  # Core DSS files  omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ -	output.o +	output.o dss-of.o  # DSS compat layer files  omapdss-y += manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o \  	dispc-compat.o display-sysfs.o @@ -10,5 +11,8 @@ omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o  omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o  omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o  omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o -omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi.o ti_hdmi_4xxx_ip.o +omapdss-$(CONFIG_OMAP2_DSS_HDMI_COMMON) += hdmi_common.o hdmi_wp.o hdmi_pll.o \ +	hdmi_phy.o +omapdss-$(CONFIG_OMAP4_DSS_HDMI) += hdmi4.o hdmi4_core.o +omapdss-$(CONFIG_OMAP5_DSS_HDMI) += hdmi5.o hdmi5_core.o  ccflags-$(CONFIG_OMAP2_DSS_DEBUG) += -DDEBUG diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/fbdev/omap2/dss/apply.c index 60758dbefd7..0a0b084ce65 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/fbdev/omap2/dss/apply.c @@ -149,6 +149,9 @@ static void apply_init_priv(void)  		op = &dss_data.ovl_priv_data_array[i]; +		op->info.color_mode = OMAP_DSS_COLOR_RGB16; +		op->info.rotation_type = OMAP_DSS_ROT_DMA; +  		op->info.global_alpha = 255;  		switch (i) { @@ -629,7 +632,7 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)  	struct mgr_priv_data *mp;  	int r; -	DSSDBG("writing ovl %d regs", ovl->id); +	DSSDBG("writing ovl %d regs\n", ovl->id);  	if (!op->enabled || !op->info_dirty)  		return; @@ -664,7 +667,7 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)  	struct ovl_priv_data *op = get_ovl_priv(ovl);  	struct mgr_priv_data *mp; -	DSSDBG("writing ovl %d regs extra", ovl->id); +	DSSDBG("writing ovl %d regs extra\n", ovl->id);  	if (!op->extra_info_dirty)  		return; @@ -687,7 +690,7 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)  	struct mgr_priv_data *mp = get_mgr_priv(mgr);  	struct omap_overlay *ovl; -	DSSDBG("writing mgr %d regs", mgr->id); +	DSSDBG("writing mgr %d regs\n", mgr->id);  	if (!mp->enabled)  		return; @@ -713,7 +716,7 @@ static void dss_mgr_write_regs_extra(struct omap_overlay_manager *mgr)  {  	struct mgr_priv_data *mp = get_mgr_priv(mgr); -	DSSDBG("writing mgr %d regs extra", mgr->id); +	DSSDBG("writing mgr %d regs extra\n", mgr->id);  	if (!mp->extra_info_dirty)  		return; diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/fbdev/omap2/dss/core.c index 60d3958d04f..6b74f73fb52 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/fbdev/omap2/dss/core.c @@ -266,7 +266,10 @@ static int (*dss_output_drv_reg_funcs[])(void) __initdata = {  	venc_init_platform_driver,  #endif  #ifdef CONFIG_OMAP4_DSS_HDMI -	hdmi_init_platform_driver, +	hdmi4_init_platform_driver, +#endif +#ifdef CONFIG_OMAP5_DSS_HDMI +	hdmi5_init_platform_driver,  #endif  }; @@ -287,7 +290,10 @@ static void (*dss_output_drv_unreg_funcs[])(void) __exitdata = {  	venc_uninit_platform_driver,  #endif  #ifdef CONFIG_OMAP4_DSS_HDMI -	hdmi_uninit_platform_driver, +	hdmi4_uninit_platform_driver, +#endif +#ifdef CONFIG_OMAP5_DSS_HDMI +	hdmi5_uninit_platform_driver,  #endif  }; diff --git a/drivers/video/omap2/dss/dispc-compat.c b/drivers/video/fbdev/omap2/dss/dispc-compat.c index 83779c2b292..83779c2b292 100644 --- a/drivers/video/omap2/dss/dispc-compat.c +++ b/drivers/video/fbdev/omap2/dss/dispc-compat.c diff --git a/drivers/video/omap2/dss/dispc-compat.h b/drivers/video/fbdev/omap2/dss/dispc-compat.h index 14a69b3d4fb..14a69b3d4fb 100644 --- a/drivers/video/omap2/dss/dispc-compat.h +++ b/drivers/video/fbdev/omap2/dss/dispc-compat.h diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c index 02a7340111d..7aa33b0f4a1 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/fbdev/omap2/dss/dispc.c @@ -90,6 +90,8 @@ struct dispc_features {  	/* revert to the OMAP4 mechanism of DISPC Smart Standby operation */  	bool mstandby_workaround:1; + +	bool set_max_preload:1;  };  #define DISPC_MAX_NR_FIFOS 5 @@ -98,9 +100,9 @@ static struct {  	struct platform_device *pdev;  	void __iomem    *base; -	int		ctx_loss_cnt; -  	int irq; +	irq_handler_t user_handler; +	void *user_data;  	unsigned long core_clk_rate;  	unsigned long tv_pclk_rate; @@ -113,6 +115,8 @@ static struct {  	u32		ctx[DISPC_SZ_REGS / sizeof(u32)];  	const struct dispc_features *feat; + +	bool is_enabled;  } dispc;  enum omap_color_component { @@ -141,12 +145,18 @@ enum mgr_reg_fields {  	DISPC_MGR_FLD_NUM,  }; +struct dispc_reg_field { +	u16 reg; +	u8 high; +	u8 low; +}; +  static const struct {  	const char *name;  	u32 vsync_irq;  	u32 framedone_irq;  	u32 sync_lost_irq; -	struct reg_field reg_desc[DISPC_MGR_FLD_NUM]; +	struct dispc_reg_field reg_desc[DISPC_MGR_FLD_NUM];  } mgr_desc[] = {  	[OMAP_DSS_CHANNEL_LCD] = {  		.name		= "LCD", @@ -238,13 +248,13 @@ static inline u32 dispc_read_reg(const u16 idx)  static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld)  { -	const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld]; +	const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];  	return REG_GET(rfld.reg, rfld.high, rfld.low);  }  static void mgr_fld_write(enum omap_channel channel,  					enum mgr_reg_fields regfld, int val) { -	const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld]; +	const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];  	REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);  } @@ -355,29 +365,20 @@ static void dispc_save_context(void)  	if (dss_has_feature(FEAT_CORE_CLK_DIV))  		SR(DIVISOR); -	dispc.ctx_loss_cnt = dss_get_ctx_loss_count();  	dispc.ctx_valid = true; -	DSSDBG("context saved, ctx_loss_count %d\n", dispc.ctx_loss_cnt); +	DSSDBG("context saved\n");  }  static void dispc_restore_context(void)  { -	int i, j, ctx; +	int i, j;  	DSSDBG("dispc_restore_context\n");  	if (!dispc.ctx_valid)  		return; -	ctx = dss_get_ctx_loss_count(); - -	if (ctx >= 0 && ctx == dispc.ctx_loss_cnt) -		return; - -	DSSDBG("ctx_loss_count: saved %d, current %d\n", -			dispc.ctx_loss_cnt, ctx); -  	/*RR(IRQENABLE);*/  	/*RR(CONTROL);*/  	RR(CONFIG); @@ -1200,7 +1201,17 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)  	dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane),  			FLD_VAL(high, hi_start, hi_end) |  			FLD_VAL(low, lo_start, lo_end)); + +	/* +	 * configure the preload to the pipeline's high threhold, if HT it's too +	 * large for the preload field, set the threshold to the maximum value +	 * that can be held by the preload register +	 */ +	if (dss_has_feature(FEAT_PRELOAD) && dispc.feat->set_max_preload && +			plane != OMAP_DSS_WB) +		dispc_write_reg(DISPC_OVL_PRELOAD(plane), min(high, 0xfffu));  } +EXPORT_SYMBOL(dispc_ovl_set_fifo_threshold);  void dispc_enable_fifomerge(bool enable)  { @@ -1259,6 +1270,7 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane,  		*fifo_high = total_fifo_size - buf_unit;  	}  } +EXPORT_SYMBOL(dispc_ovl_compute_fifo_thresholds);  static void dispc_ovl_set_fir(enum omap_plane plane,  				int hinc, int vinc, @@ -1988,7 +2000,8 @@ static void calc_tiler_rotation_offset(u16 screen_width, u16 width,   */  static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk,  		const struct omap_video_timings *t, u16 pos_x, -		u16 width, u16 height, u16 out_width, u16 out_height) +		u16 width, u16 height, u16 out_width, u16 out_height, +		bool five_taps)  {  	const int ds = DIV_ROUND_UP(height, out_height);  	unsigned long nonactive; @@ -2008,6 +2021,10 @@ static int check_horiz_timing_omap3(unsigned long pclk, unsigned long lclk,  	if (blank <= limits[i])  		return -EINVAL; +	/* FIXME add checks for 3-tap filter once the limitations are known */ +	if (!five_taps) +		return 0; +  	/*  	 * Pixel data should be prepared before visible display point starts.  	 * So, atleast DS-2 lines must have already been fetched by DISPC @@ -2142,8 +2159,8 @@ static int dispc_ovl_calc_scaling_24xx(unsigned long pclk, unsigned long lclk,  	*five_taps = false;  	do { -		in_height = DIV_ROUND_UP(height, *decim_y); -		in_width = DIV_ROUND_UP(width, *decim_x); +		in_height = height / *decim_y; +		in_width = width / *decim_x;  		*core_clk = dispc.feat->calc_core_clk(pclk, in_width,  				in_height, out_width, out_height, mem_to_mem);  		error = (in_width > maxsinglelinewidth || !*core_clk || @@ -2181,24 +2198,32 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,  			dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);  	do { -		in_height = DIV_ROUND_UP(height, *decim_y); -		in_width = DIV_ROUND_UP(width, *decim_x); -		*core_clk = calc_core_clk_five_taps(pclk, mgr_timings, -			in_width, in_height, out_width, out_height, color_mode); - -		error = check_horiz_timing_omap3(pclk, lclk, mgr_timings, -				pos_x, in_width, in_height, out_width, -				out_height); +		in_height = height / *decim_y; +		in_width = width / *decim_x; +		*five_taps = in_height > out_height;  		if (in_width > maxsinglelinewidth)  			if (in_height > out_height &&  						in_height < out_height * 2)  				*five_taps = false; -		if (!*five_taps) +again: +		if (*five_taps) +			*core_clk = calc_core_clk_five_taps(pclk, mgr_timings, +						in_width, in_height, out_width, +						out_height, color_mode); +		else  			*core_clk = dispc.feat->calc_core_clk(pclk, in_width,  					in_height, out_width, out_height,  					mem_to_mem); +		error = check_horiz_timing_omap3(pclk, lclk, mgr_timings, +				pos_x, in_width, in_height, out_width, +				out_height, *five_taps); +		if (error && *five_taps) { +			*five_taps = false; +			goto again; +		} +  		error = (error || in_width > maxsinglelinewidth * 2 ||  			(in_width > maxsinglelinewidth && *five_taps) ||  			!*core_clk || *core_clk > dispc_core_clk_rate()); @@ -2215,7 +2240,7 @@ static int dispc_ovl_calc_scaling_34xx(unsigned long pclk, unsigned long lclk,  	} while (*decim_x <= *x_predecim && *decim_y <= *y_predecim && error);  	if (check_horiz_timing_omap3(pclk, lclk, mgr_timings, pos_x, width, -				height, out_width, out_height)){ +				height, out_width, out_height, *five_taps)) {  			DSSERR("horizontal timing too tight\n");  			return -EINVAL;  	} @@ -2242,7 +2267,7 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk,  {  	u16 in_width, in_width_max;  	int decim_x_min = *decim_x; -	u16 in_height = DIV_ROUND_UP(height, *decim_y); +	u16 in_height = height / *decim_y;  	const int maxsinglelinewidth =  				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);  	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE); @@ -2261,7 +2286,7 @@ static int dispc_ovl_calc_scaling_44xx(unsigned long pclk, unsigned long lclk,  		return -EINVAL;  	do { -		in_width = DIV_ROUND_UP(width, *decim_x); +		in_width = width / *decim_x;  	} while (*decim_x <= *x_predecim &&  			in_width > maxsinglelinewidth && ++*decim_x); @@ -2352,7 +2377,7 @@ int dispc_ovl_check(enum omap_plane plane, enum omap_channel channel,  {  	enum omap_overlay_caps caps = dss_feat_get_overlay_caps(plane);  	bool five_taps = true; -	bool fieldmode = 0; +	bool fieldmode = false;  	u16 in_height = oi->height;  	u16 in_width = oi->width;  	bool ilace = timings->interlace; @@ -2365,7 +2390,7 @@ int dispc_ovl_check(enum omap_plane plane, enum omap_channel channel,  	out_height = oi->out_height == 0 ? oi->height : oi->out_height;  	if (ilace && oi->height == out_height) -		fieldmode = 1; +		fieldmode = true;  	if (ilace) {  		if (fieldmode) @@ -2396,7 +2421,7 @@ static int dispc_ovl_setup_common(enum omap_plane plane,  		bool mem_to_mem)  {  	bool five_taps = true; -	bool fieldmode = 0; +	bool fieldmode = false;  	int r, cconv = 0;  	unsigned offset0, offset1;  	s32 row_inc; @@ -2417,7 +2442,7 @@ static int dispc_ovl_setup_common(enum omap_plane plane,  	out_height = out_height == 0 ? height : out_height;  	if (ilace && height == out_height) -		fieldmode = 1; +		fieldmode = true;  	if (ilace) {  		if (fieldmode) @@ -2440,8 +2465,8 @@ static int dispc_ovl_setup_common(enum omap_plane plane,  	if (r)  		return r; -	in_width = DIV_ROUND_UP(in_width, x_predecim); -	in_height = DIV_ROUND_UP(in_height, y_predecim); +	in_width = in_width / x_predecim; +	in_height = in_height / y_predecim;  	if (color_mode == OMAP_DSS_COLOR_YUV2 ||  			color_mode == OMAP_DSS_COLOR_UYVY || @@ -2552,9 +2577,9 @@ int dispc_ovl_setup(enum omap_plane plane, const struct omap_overlay_info *oi,  	channel = dispc_ovl_get_channel_out(plane); -	DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> " -		"%dx%d, cmode %x, rot %d, mir %d, chan %d repl %d\n", -		plane, oi->paddr, oi->p_uv_addr, oi->screen_width, oi->pos_x, +	DSSDBG("dispc_ovl_setup %d, pa %pad, pa_uv %pad, sw %d, %d,%d, %dx%d ->" +		" %dx%d, cmode %x, rot %d, mir %d, chan %d repl %d\n", +		plane, &oi->paddr, &oi->p_uv_addr, oi->screen_width, oi->pos_x,  		oi->pos_y, oi->width, oi->height, oi->out_width, oi->out_height,  		oi->color_mode, oi->rotation, oi->mirror, channel, replication); @@ -2858,7 +2883,7 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,  	timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res); -	timings_ok &= _dispc_mgr_pclk_ok(channel, timings->pixel_clock * 1000); +	timings_ok &= _dispc_mgr_pclk_ok(channel, timings->pixelclock);  	if (dss_mgr_is_lcd(channel)) {  		timings_ok &= _dispc_lcd_timings_ok(timings->hsw, timings->hfp, @@ -2918,15 +2943,15 @@ static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,  		break;  	default:  		BUG(); -	}; +	} + +	l = FLD_VAL(onoff, 17, 17) | +		FLD_VAL(rf, 16, 16) | +		FLD_VAL(de_level, 15, 15) | +		FLD_VAL(ipc, 14, 14) | +		FLD_VAL(hsync_level, 13, 13) | +		FLD_VAL(vsync_level, 12, 12); -	l = dispc_read_reg(DISPC_POL_FREQ(channel)); -	l |= FLD_VAL(onoff, 17, 17); -	l |= FLD_VAL(rf, 16, 16); -	l |= FLD_VAL(de_level, 15, 15); -	l |= FLD_VAL(ipc, 14, 14); -	l |= FLD_VAL(hsync_level, 13, 13); -	l |= FLD_VAL(vsync_level, 12, 12);  	dispc_write_reg(DISPC_POL_FREQ(channel), l);  } @@ -2953,10 +2978,10 @@ void dispc_mgr_set_timings(enum omap_channel channel,  		xtot = t.x_res + t.hfp + t.hsw + t.hbp;  		ytot = t.y_res + t.vfp + t.vsw + t.vbp; -		ht = (timings->pixel_clock * 1000) / xtot; -		vt = (timings->pixel_clock * 1000) / xtot / ytot; +		ht = timings->pixelclock / xtot; +		vt = timings->pixelclock / xtot / ytot; -		DSSDBG("pck %u\n", timings->pixel_clock); +		DSSDBG("pck %u\n", timings->pixelclock);  		DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n",  			t.hsw, t.hfp, t.hbp, t.vsw, t.vfp, t.vbp);  		DSSDBG("vsync_level %d hsync_level %d data_pclk_edge %d de_level %d sync_pclk_edge %d\n", @@ -3211,6 +3236,8 @@ static void dispc_dump_regs(struct seq_file *s)  		DUMPREG(DISPC_CONTROL3);  		DUMPREG(DISPC_CONFIG3);  	} +	if (dss_has_feature(FEAT_MFLAG)) +		DUMPREG(DISPC_GLOBAL_MFLAG_ATTRIBUTE);  #undef DUMPREG @@ -3285,6 +3312,8 @@ static void dispc_dump_regs(struct seq_file *s)  			DUMPREG(i, DISPC_OVL_ATTRIBUTES2);  		if (dss_has_feature(FEAT_PRELOAD))  			DUMPREG(i, DISPC_OVL_PRELOAD); +		if (dss_has_feature(FEAT_MFLAG)) +			DUMPREG(i, DISPC_OVL_MFLAG_THRESHOLD);  	}  #undef DISPC_REG @@ -3520,6 +3549,7 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {  	.calc_core_clk		=	calc_core_clk_24xx,  	.num_fifos		=	3,  	.no_framedone_tv	=	true, +	.set_max_preload	=	false,  };  static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = { @@ -3539,6 +3569,7 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {  	.calc_core_clk		=	calc_core_clk_34xx,  	.num_fifos		=	3,  	.no_framedone_tv	=	true, +	.set_max_preload	=	false,  };  static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = { @@ -3558,6 +3589,7 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {  	.calc_core_clk		=	calc_core_clk_34xx,  	.num_fifos		=	3,  	.no_framedone_tv	=	true, +	.set_max_preload	=	false,  };  static const struct dispc_features omap44xx_dispc_feats __initconst = { @@ -3577,6 +3609,7 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {  	.calc_core_clk		=	calc_core_clk_44xx,  	.num_fifos		=	5,  	.gfx_fifo_workaround	=	true, +	.set_max_preload	=	true,  };  static const struct dispc_features omap54xx_dispc_feats __initconst = { @@ -3597,6 +3630,7 @@ static const struct dispc_features omap54xx_dispc_feats __initconst = {  	.num_fifos		=	5,  	.gfx_fifo_workaround	=	true,  	.mstandby_workaround	=	true, +	.set_max_preload	=	true,  };  static int __init dispc_init_features(struct platform_device *pdev) @@ -3622,6 +3656,7 @@ static int __init dispc_init_features(struct platform_device *pdev)  	case OMAPDSS_VER_OMAP34xx_ES3:  	case OMAPDSS_VER_OMAP3630:  	case OMAPDSS_VER_AM35xx: +	case OMAPDSS_VER_AM43xx:  		src = &omap34xx_rev3_0_dispc_feats;  		break; @@ -3645,16 +3680,44 @@ static int __init dispc_init_features(struct platform_device *pdev)  	return 0;  } +static irqreturn_t dispc_irq_handler(int irq, void *arg) +{ +	if (!dispc.is_enabled) +		return IRQ_NONE; + +	return dispc.user_handler(irq, dispc.user_data); +} +  int dispc_request_irq(irq_handler_t handler, void *dev_id)  { -	return devm_request_irq(&dispc.pdev->dev, dispc.irq, handler, -			     IRQF_SHARED, "OMAP DISPC", dev_id); +	int r; + +	if (dispc.user_handler != NULL) +		return -EBUSY; + +	dispc.user_handler = handler; +	dispc.user_data = dev_id; + +	/* ensure the dispc_irq_handler sees the values above */ +	smp_wmb(); + +	r = devm_request_irq(&dispc.pdev->dev, dispc.irq, dispc_irq_handler, +			     IRQF_SHARED, "OMAP DISPC", &dispc); +	if (r) { +		dispc.user_handler = NULL; +		dispc.user_data = NULL; +	} + +	return r;  }  EXPORT_SYMBOL(dispc_request_irq);  void dispc_free_irq(void *dev_id)  { -	devm_free_irq(&dispc.pdev->dev, dispc.irq, dev_id); +	devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc); + +	dispc.user_handler = NULL; +	dispc.user_data = NULL;  }  EXPORT_SYMBOL(dispc_free_irq); @@ -3726,6 +3789,12 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)  static int dispc_runtime_suspend(struct device *dev)  { +	dispc.is_enabled = false; +	/* ensure the dispc_irq_handler sees the is_enabled value */ +	smp_wmb(); +	/* wait for current handler to finish before turning the DISPC off */ +	synchronize_irq(dispc.irq); +  	dispc_save_context();  	return 0; @@ -3733,7 +3802,21 @@ static int dispc_runtime_suspend(struct device *dev)  static int dispc_runtime_resume(struct device *dev)  { -	dispc_restore_context(); +	/* +	 * The reset value for load mode is 0 (OMAP_DSS_LOAD_CLUT_AND_FRAME) +	 * but we always initialize it to 2 (OMAP_DSS_LOAD_FRAME_ONLY) in +	 * _omap_dispc_initial_config(). We can thus use it to detect if +	 * we have lost register context. +	 */ +	if (REG_GET(DISPC_CONFIG, 2, 1) != OMAP_DSS_LOAD_FRAME_ONLY) { +		_omap_dispc_initial_config(); + +		dispc_restore_context(); +	} + +	dispc.is_enabled = true; +	/* ensure the dispc_irq_handler sees the is_enabled value */ +	smp_wmb();  	return 0;  } @@ -3743,12 +3826,21 @@ static const struct dev_pm_ops dispc_pm_ops = {  	.runtime_resume = dispc_runtime_resume,  }; +static const struct of_device_id dispc_of_match[] = { +	{ .compatible = "ti,omap2-dispc", }, +	{ .compatible = "ti,omap3-dispc", }, +	{ .compatible = "ti,omap4-dispc", }, +	{ .compatible = "ti,omap5-dispc", }, +	{}, +}; +  static struct platform_driver omap_dispchw_driver = {  	.remove         = __exit_p(omap_dispchw_remove),  	.driver         = {  		.name   = "omapdss_dispc",  		.owner  = THIS_MODULE,  		.pm	= &dispc_pm_ops, +		.of_match_table = dispc_of_match,  	},  }; diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/fbdev/omap2/dss/dispc.h index de4863d21ab..78edb449c76 100644 --- a/drivers/video/omap2/dss/dispc.h +++ b/drivers/video/fbdev/omap2/dss/dispc.h @@ -40,6 +40,7 @@  #define DISPC_CONTROL3                  0x0848  #define DISPC_CONFIG3                   0x084C  #define DISPC_MSTANDBY_CTRL		0x0858 +#define DISPC_GLOBAL_MFLAG_ATTRIBUTE	0x085C  /* DISPC overlay registers */  #define DISPC_OVL_BA0(n)		(DISPC_OVL_BASE(n) + \ @@ -100,6 +101,8 @@  					DISPC_FIR_COEF_V2_OFFSET(n, i))  #define DISPC_OVL_PRELOAD(n)		(DISPC_OVL_BASE(n) + \  					DISPC_PRELOAD_OFFSET(n)) +#define DISPC_OVL_MFLAG_THRESHOLD(n)	(DISPC_OVL_BASE(n) + \ +					DISPC_MFLAG_THRESHOLD_OFFSET(n))  /* DISPC up/downsampling FIR filter coefficient structure */  struct dispc_coef { @@ -894,4 +897,21 @@ static inline u16 DISPC_PRELOAD_OFFSET(enum omap_plane plane)  		return 0;  	}  } + +static inline u16 DISPC_MFLAG_THRESHOLD_OFFSET(enum omap_plane plane) +{ +	switch (plane) { +	case OMAP_DSS_GFX: +		return 0x0860; +	case OMAP_DSS_VIDEO1: +		return 0x0864; +	case OMAP_DSS_VIDEO2: +		return 0x0868; +	case OMAP_DSS_VIDEO3: +		return 0x086c; +	default: +		BUG(); +		return 0; +	} +}  #endif diff --git a/drivers/video/omap2/dss/dispc_coefs.c b/drivers/video/fbdev/omap2/dss/dispc_coefs.c index 038c15b0421..038c15b0421 100644 --- a/drivers/video/omap2/dss/dispc_coefs.c +++ b/drivers/video/fbdev/omap2/dss/dispc_coefs.c diff --git a/drivers/video/omap2/dss/display-sysfs.c b/drivers/video/fbdev/omap2/dss/display-sysfs.c index 21d7f77df70..5a2095a98ed 100644 --- a/drivers/video/omap2/dss/display-sysfs.c +++ b/drivers/video/fbdev/omap2/dss/display-sysfs.c @@ -132,7 +132,7 @@ static ssize_t display_timings_show(struct device *dev,  	dssdev->driver->get_timings(dssdev, &t);  	return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n", -			t.pixel_clock, +			t.pixelclock,  			t.x_res, t.hfp, t.hbp, t.hsw,  			t.y_res, t.vfp, t.vbp, t.vsw);  } @@ -158,7 +158,7 @@ static ssize_t display_timings_store(struct device *dev,  	}  #endif  	if (!found && sscanf(buf, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu", -				&t.pixel_clock, +				&t.pixelclock,  				&t.x_res, &t.hfp, &t.hbp, &t.hsw,  				&t.y_res, &t.vfp, &t.vbp, &t.vsw) != 9)  		return -EINVAL; @@ -277,7 +277,7 @@ static ssize_t display_wss_store(struct device *dev,  	return size;  } -static DEVICE_ATTR(name, S_IRUGO, display_name_show, NULL); +static DEVICE_ATTR(display_name, S_IRUGO, display_name_show, NULL);  static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,  		display_enabled_show, display_enabled_store);  static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR, @@ -292,7 +292,7 @@ static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,  		display_wss_show, display_wss_store);  static const struct attribute *display_sysfs_attrs[] = { -	&dev_attr_name.attr, +	&dev_attr_display_name.attr,  	&dev_attr_enabled.attr,  	&dev_attr_tear_elim.attr,  	&dev_attr_timings.attr, diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/fbdev/omap2/dss/display.c index fafe7c941a6..2412a0dd0c1 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/fbdev/omap2/dss/display.c @@ -26,6 +26,7 @@  #include <linux/module.h>  #include <linux/jiffies.h>  #include <linux/platform_device.h> +#include <linux/of.h>  #include <video/omapdss.h>  #include "dss.h" @@ -133,9 +134,32 @@ static int disp_num_counter;  int omapdss_register_display(struct omap_dss_device *dssdev)  {  	struct omap_dss_driver *drv = dssdev->driver; +	int id; -	snprintf(dssdev->alias, sizeof(dssdev->alias), -			"display%d", disp_num_counter++); +	/* +	 * Note: this presumes all the displays are either using DT or non-DT, +	 * which normally should be the case. This also presumes that all +	 * displays either have an DT alias, or none has. +	 */ + +	if (dssdev->dev->of_node) { +		id = of_alias_get_id(dssdev->dev->of_node, "display"); + +		if (id < 0) +			id = disp_num_counter++; +	} else { +		id = disp_num_counter++; +	} + +	snprintf(dssdev->alias, sizeof(dssdev->alias), "display%d", id); + +	/* Use 'label' property for name, if it exists */ +	if (dssdev->dev->of_node) +		of_property_read_string(dssdev->dev->of_node, "label", +			&dssdev->name); + +	if (dssdev->name == NULL) +		dssdev->name = dssdev->alias;  	if (drv && drv->get_resolution == NULL)  		drv->get_resolution = omapdss_default_get_resolution; @@ -248,7 +272,7 @@ void videomode_to_omap_video_timings(const struct videomode *vm,  {  	memset(ovt, 0, sizeof(*ovt)); -	ovt->pixel_clock = vm->pixelclock / 1000; +	ovt->pixelclock = vm->pixelclock;  	ovt->x_res = vm->hactive;  	ovt->hbp = vm->hback_porch;  	ovt->hfp = vm->hfront_porch; @@ -266,7 +290,7 @@ void videomode_to_omap_video_timings(const struct videomode *vm,  		OMAPDSS_SIG_ACTIVE_LOW;  	ovt->de_level = vm->flags & DISPLAY_FLAGS_DE_HIGH ?  		OMAPDSS_SIG_ACTIVE_HIGH : -		OMAPDSS_SIG_ACTIVE_HIGH; +		OMAPDSS_SIG_ACTIVE_LOW;  	ovt->data_pclk_edge = vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE ?  		OMAPDSS_DRIVE_SIG_RISING_EDGE :  		OMAPDSS_DRIVE_SIG_FALLING_EDGE; @@ -280,7 +304,7 @@ void omap_video_timings_to_videomode(const struct omap_video_timings *ovt,  {  	memset(vm, 0, sizeof(*vm)); -	vm->pixelclock = ovt->pixel_clock * 1000; +	vm->pixelclock = ovt->pixelclock;  	vm->hactive = ovt->x_res;  	vm->hback_porch = ovt->hbp; diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c index bd48cde5356..9368972d696 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/fbdev/omap2/dss/dpi.c @@ -30,6 +30,7 @@  #include <linux/platform_device.h>  #include <linux/regulator/consumer.h>  #include <linux/string.h> +#include <linux/of.h>  #include <video/omapdss.h> @@ -49,6 +50,8 @@ static struct {  	int data_lines;  	struct omap_dss_device output; + +	bool port_initialized;  } dpi;  static struct platform_device *dpi_get_dsidev(enum omap_channel channel) @@ -64,6 +67,7 @@ static struct platform_device *dpi_get_dsidev(enum omap_channel channel)  	case OMAPDSS_VER_OMAP34xx_ES3:  	case OMAPDSS_VER_OMAP3630:  	case OMAPDSS_VER_AM35xx: +	case OMAPDSS_VER_AM43xx:  		return NULL;  	case OMAPDSS_VER_OMAP4430_ES1: @@ -100,6 +104,8 @@ static enum omap_dss_clk_source dpi_get_alt_clk_src(enum omap_channel channel)  		return OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC;  	case OMAP_DSS_CHANNEL_LCD2:  		return OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC; +	case OMAP_DSS_CHANNEL_LCD3: +		return OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;  	default:  		/* this shouldn't happen */  		WARN_ON(1); @@ -117,7 +123,7 @@ struct dpi_clk_calc_ctx {  	/* outputs */  	struct dsi_clock_info dsi_cinfo; -	struct dss_clock_info dss_cinfo; +	unsigned long fck;  	struct dispc_clock_info dispc_cinfo;  }; @@ -184,12 +190,11 @@ static bool dpi_calc_pll_cb(int regn, int regm, unsigned long fint,  			dpi_calc_hsdiv_cb, ctx);  } -static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data) +static bool dpi_calc_dss_cb(unsigned long fck, void *data)  {  	struct dpi_clk_calc_ctx *ctx = data; -	ctx->dss_cinfo.fck = fck; -	ctx->dss_cinfo.fck_div = fckd; +	ctx->fck = fck;  	return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max,  			dpi_calc_dispc_cb, ctx); @@ -237,7 +242,7 @@ static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)  			ctx->pck_min = 0;  		ctx->pck_max = pck + 1000 * i * i * i; -		ok = dss_div_calc(ctx->pck_min, dpi_calc_dss_cb, ctx); +		ok = dss_div_calc(pck, ctx->pck_min, dpi_calc_dss_cb, ctx);  		if (ok)  			return ok;  	} @@ -286,13 +291,13 @@ static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,  	if (!ok)  		return -EINVAL; -	r = dss_set_clock_div(&ctx.dss_cinfo); +	r = dss_set_fck_rate(ctx.fck);  	if (r)  		return r;  	dpi.mgr_config.clock_info = ctx.dispc_cinfo; -	*fck = ctx.dss_cinfo.fck; +	*fck = ctx.fck;  	*lck_div = ctx.dispc_cinfo.lck_div;  	*pck_div = ctx.dispc_cinfo.pck_div; @@ -308,22 +313,21 @@ static int dpi_set_mode(struct omap_overlay_manager *mgr)  	int r = 0;  	if (dpi.dsidev) -		r = dpi_set_dsi_clk(mgr->id, t->pixel_clock * 1000, &fck, +		r = dpi_set_dsi_clk(mgr->id, t->pixelclock, &fck,  				&lck_div, &pck_div);  	else -		r = dpi_set_dispc_clk(t->pixel_clock * 1000, &fck, +		r = dpi_set_dispc_clk(t->pixelclock, &fck,  				&lck_div, &pck_div);  	if (r)  		return r; -	pck = fck / lck_div / pck_div / 1000; +	pck = fck / lck_div / pck_div; -	if (pck != t->pixel_clock) { -		DSSWARN("Could not find exact pixel clock. " -				"Requested %d kHz, got %lu kHz\n", -				t->pixel_clock, pck); +	if (pck != t->pixelclock) { +		DSSWARN("Could not find exact pixel clock. Requested %d Hz, got %lu Hz\n", +			t->pixelclock, pck); -		t->pixel_clock = pck; +		t->pixelclock = pck;  	}  	dss_mgr_set_timings(mgr, t); @@ -481,29 +485,29 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,  	if (mgr && !dispc_mgr_timings_ok(mgr->id, timings))  		return -EINVAL; -	if (timings->pixel_clock == 0) +	if (timings->pixelclock == 0)  		return -EINVAL;  	if (dpi.dsidev) { -		ok = dpi_dsi_clk_calc(timings->pixel_clock * 1000, &ctx); +		ok = dpi_dsi_clk_calc(timings->pixelclock, &ctx);  		if (!ok)  			return -EINVAL;  		fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk;  	} else { -		ok = dpi_dss_clk_calc(timings->pixel_clock * 1000, &ctx); +		ok = dpi_dss_clk_calc(timings->pixelclock, &ctx);  		if (!ok)  			return -EINVAL; -		fck = ctx.dss_cinfo.fck; +		fck = ctx.fck;  	}  	lck_div = ctx.dispc_cinfo.lck_div;  	pck_div = ctx.dispc_cinfo.pck_div; -	pck = fck / lck_div / pck_div / 1000; +	pck = fck / lck_div / pck_div; -	timings->pixel_clock = pck; +	timings->pixelclock = pck;  	return 0;  } @@ -551,7 +555,8 @@ static int dpi_init_regulator(void)  	vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi");  	if (IS_ERR(vdds_dsi)) { -		DSSERR("can't get VDDS_DSI regulator\n"); +		if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER) +			DSSERR("can't get VDDS_DSI regulator\n");  		return PTR_ERR(vdds_dsi);  	} @@ -593,6 +598,7 @@ static enum omap_channel dpi_get_channel(void)  	case OMAPDSS_VER_OMAP34xx_ES3:  	case OMAPDSS_VER_OMAP3630:  	case OMAPDSS_VER_AM35xx: +	case OMAPDSS_VER_AM43xx:  		return OMAP_DSS_CHANNEL_LCD;  	case OMAPDSS_VER_OMAP4430_ES1: @@ -726,3 +732,47 @@ void __exit dpi_uninit_platform_driver(void)  {  	platform_driver_unregister(&omap_dpi_driver);  } + +int __init dpi_init_port(struct platform_device *pdev, struct device_node *port) +{ +	struct device_node *ep; +	u32 datalines; +	int r; + +	ep = omapdss_of_get_next_endpoint(port, NULL); +	if (!ep) +		return 0; + +	r = of_property_read_u32(ep, "data-lines", &datalines); +	if (r) { +		DSSERR("failed to parse datalines\n"); +		goto err_datalines; +	} + +	dpi.data_lines = datalines; + +	of_node_put(ep); + +	dpi.pdev = pdev; + +	mutex_init(&dpi.lock); + +	dpi_init_output(pdev); + +	dpi.port_initialized = true; + +	return 0; + +err_datalines: +	of_node_put(ep); + +	return r; +} + +void __exit dpi_uninit_port(void) +{ +	if (!dpi.port_initialized) +		return; + +	dpi_uninit_output(dpi.pdev); +} diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c index a598b581228..4755a34a542 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/fbdev/omap2/dss/dsi.c @@ -38,6 +38,8 @@  #include <linux/slab.h>  #include <linux/debugfs.h>  #include <linux/pm_runtime.h> +#include <linux/of.h> +#include <linux/of_platform.h>  #include <video/omapdss.h>  #include <video/mipi_display.h> @@ -47,63 +49,73 @@  #define DSI_CATCH_MISSING_TE -struct dsi_reg { u16 idx; }; +struct dsi_reg { u16 module; u16 idx; }; -#define DSI_REG(idx)		((const struct dsi_reg) { idx }) +#define DSI_REG(mod, idx)		((const struct dsi_reg) { mod, idx }) -#define DSI_SZ_REGS		SZ_1K  /* DSI Protocol Engine */ -#define DSI_REVISION			DSI_REG(0x0000) -#define DSI_SYSCONFIG			DSI_REG(0x0010) -#define DSI_SYSSTATUS			DSI_REG(0x0014) -#define DSI_IRQSTATUS			DSI_REG(0x0018) -#define DSI_IRQENABLE			DSI_REG(0x001C) -#define DSI_CTRL			DSI_REG(0x0040) -#define DSI_GNQ				DSI_REG(0x0044) -#define DSI_COMPLEXIO_CFG1		DSI_REG(0x0048) -#define DSI_COMPLEXIO_IRQ_STATUS	DSI_REG(0x004C) -#define DSI_COMPLEXIO_IRQ_ENABLE	DSI_REG(0x0050) -#define DSI_CLK_CTRL			DSI_REG(0x0054) -#define DSI_TIMING1			DSI_REG(0x0058) -#define DSI_TIMING2			DSI_REG(0x005C) -#define DSI_VM_TIMING1			DSI_REG(0x0060) -#define DSI_VM_TIMING2			DSI_REG(0x0064) -#define DSI_VM_TIMING3			DSI_REG(0x0068) -#define DSI_CLK_TIMING			DSI_REG(0x006C) -#define DSI_TX_FIFO_VC_SIZE		DSI_REG(0x0070) -#define DSI_RX_FIFO_VC_SIZE		DSI_REG(0x0074) -#define DSI_COMPLEXIO_CFG2		DSI_REG(0x0078) -#define DSI_RX_FIFO_VC_FULLNESS		DSI_REG(0x007C) -#define DSI_VM_TIMING4			DSI_REG(0x0080) -#define DSI_TX_FIFO_VC_EMPTINESS	DSI_REG(0x0084) -#define DSI_VM_TIMING5			DSI_REG(0x0088) -#define DSI_VM_TIMING6			DSI_REG(0x008C) -#define DSI_VM_TIMING7			DSI_REG(0x0090) -#define DSI_STOPCLK_TIMING		DSI_REG(0x0094) -#define DSI_VC_CTRL(n)			DSI_REG(0x0100 + (n * 0x20)) -#define DSI_VC_TE(n)			DSI_REG(0x0104 + (n * 0x20)) -#define DSI_VC_LONG_PACKET_HEADER(n)	DSI_REG(0x0108 + (n * 0x20)) -#define DSI_VC_LONG_PACKET_PAYLOAD(n)	DSI_REG(0x010C + (n * 0x20)) -#define DSI_VC_SHORT_PACKET_HEADER(n)	DSI_REG(0x0110 + (n * 0x20)) -#define DSI_VC_IRQSTATUS(n)		DSI_REG(0x0118 + (n * 0x20)) -#define DSI_VC_IRQENABLE(n)		DSI_REG(0x011C + (n * 0x20)) +#define DSI_PROTO			0 +#define DSI_PROTO_SZ			0x200 + +#define DSI_REVISION			DSI_REG(DSI_PROTO, 0x0000) +#define DSI_SYSCONFIG			DSI_REG(DSI_PROTO, 0x0010) +#define DSI_SYSSTATUS			DSI_REG(DSI_PROTO, 0x0014) +#define DSI_IRQSTATUS			DSI_REG(DSI_PROTO, 0x0018) +#define DSI_IRQENABLE			DSI_REG(DSI_PROTO, 0x001C) +#define DSI_CTRL			DSI_REG(DSI_PROTO, 0x0040) +#define DSI_GNQ				DSI_REG(DSI_PROTO, 0x0044) +#define DSI_COMPLEXIO_CFG1		DSI_REG(DSI_PROTO, 0x0048) +#define DSI_COMPLEXIO_IRQ_STATUS	DSI_REG(DSI_PROTO, 0x004C) +#define DSI_COMPLEXIO_IRQ_ENABLE	DSI_REG(DSI_PROTO, 0x0050) +#define DSI_CLK_CTRL			DSI_REG(DSI_PROTO, 0x0054) +#define DSI_TIMING1			DSI_REG(DSI_PROTO, 0x0058) +#define DSI_TIMING2			DSI_REG(DSI_PROTO, 0x005C) +#define DSI_VM_TIMING1			DSI_REG(DSI_PROTO, 0x0060) +#define DSI_VM_TIMING2			DSI_REG(DSI_PROTO, 0x0064) +#define DSI_VM_TIMING3			DSI_REG(DSI_PROTO, 0x0068) +#define DSI_CLK_TIMING			DSI_REG(DSI_PROTO, 0x006C) +#define DSI_TX_FIFO_VC_SIZE		DSI_REG(DSI_PROTO, 0x0070) +#define DSI_RX_FIFO_VC_SIZE		DSI_REG(DSI_PROTO, 0x0074) +#define DSI_COMPLEXIO_CFG2		DSI_REG(DSI_PROTO, 0x0078) +#define DSI_RX_FIFO_VC_FULLNESS		DSI_REG(DSI_PROTO, 0x007C) +#define DSI_VM_TIMING4			DSI_REG(DSI_PROTO, 0x0080) +#define DSI_TX_FIFO_VC_EMPTINESS	DSI_REG(DSI_PROTO, 0x0084) +#define DSI_VM_TIMING5			DSI_REG(DSI_PROTO, 0x0088) +#define DSI_VM_TIMING6			DSI_REG(DSI_PROTO, 0x008C) +#define DSI_VM_TIMING7			DSI_REG(DSI_PROTO, 0x0090) +#define DSI_STOPCLK_TIMING		DSI_REG(DSI_PROTO, 0x0094) +#define DSI_VC_CTRL(n)			DSI_REG(DSI_PROTO, 0x0100 + (n * 0x20)) +#define DSI_VC_TE(n)			DSI_REG(DSI_PROTO, 0x0104 + (n * 0x20)) +#define DSI_VC_LONG_PACKET_HEADER(n)	DSI_REG(DSI_PROTO, 0x0108 + (n * 0x20)) +#define DSI_VC_LONG_PACKET_PAYLOAD(n)	DSI_REG(DSI_PROTO, 0x010C + (n * 0x20)) +#define DSI_VC_SHORT_PACKET_HEADER(n)	DSI_REG(DSI_PROTO, 0x0110 + (n * 0x20)) +#define DSI_VC_IRQSTATUS(n)		DSI_REG(DSI_PROTO, 0x0118 + (n * 0x20)) +#define DSI_VC_IRQENABLE(n)		DSI_REG(DSI_PROTO, 0x011C + (n * 0x20))  /* DSIPHY_SCP */ -#define DSI_DSIPHY_CFG0			DSI_REG(0x200 + 0x0000) -#define DSI_DSIPHY_CFG1			DSI_REG(0x200 + 0x0004) -#define DSI_DSIPHY_CFG2			DSI_REG(0x200 + 0x0008) -#define DSI_DSIPHY_CFG5			DSI_REG(0x200 + 0x0014) -#define DSI_DSIPHY_CFG10		DSI_REG(0x200 + 0x0028) +#define DSI_PHY				1 +#define DSI_PHY_OFFSET			0x200 +#define DSI_PHY_SZ			0x40 + +#define DSI_DSIPHY_CFG0			DSI_REG(DSI_PHY, 0x0000) +#define DSI_DSIPHY_CFG1			DSI_REG(DSI_PHY, 0x0004) +#define DSI_DSIPHY_CFG2			DSI_REG(DSI_PHY, 0x0008) +#define DSI_DSIPHY_CFG5			DSI_REG(DSI_PHY, 0x0014) +#define DSI_DSIPHY_CFG10		DSI_REG(DSI_PHY, 0x0028)  /* DSI_PLL_CTRL_SCP */ -#define DSI_PLL_CONTROL			DSI_REG(0x300 + 0x0000) -#define DSI_PLL_STATUS			DSI_REG(0x300 + 0x0004) -#define DSI_PLL_GO			DSI_REG(0x300 + 0x0008) -#define DSI_PLL_CONFIGURATION1		DSI_REG(0x300 + 0x000C) -#define DSI_PLL_CONFIGURATION2		DSI_REG(0x300 + 0x0010) +#define DSI_PLL				2 +#define DSI_PLL_OFFSET			0x300 +#define DSI_PLL_SZ			0x20 + +#define DSI_PLL_CONTROL			DSI_REG(DSI_PLL, 0x0000) +#define DSI_PLL_STATUS			DSI_REG(DSI_PLL, 0x0004) +#define DSI_PLL_GO			DSI_REG(DSI_PLL, 0x0008) +#define DSI_PLL_CONFIGURATION1		DSI_REG(DSI_PLL, 0x000C) +#define DSI_PLL_CONFIGURATION2		DSI_REG(DSI_PLL, 0x0010)  #define REG_GET(dsidev, idx, start, end) \  	FLD_GET(dsi_read_reg(dsidev, idx), start, end) @@ -277,12 +289,16 @@ struct dsi_clk_calc_ctx {  struct dsi_data {  	struct platform_device *pdev; -	void __iomem	*base; +	void __iomem *proto_base; +	void __iomem *phy_base; +	void __iomem *pll_base;  	int module_id;  	int irq; +	bool is_enabled; +  	struct clk *dss_clk;  	struct clk *sys_clk; @@ -297,7 +313,8 @@ struct dsi_data {  	struct {  		enum dsi_vc_source source;  		struct omap_dss_device *dssdev; -		enum fifo_size fifo_size; +		enum fifo_size tx_fifo_size; +		enum fifo_size rx_fifo_size;  		int vc_id;  	} vc[4]; @@ -312,7 +329,7 @@ struct dsi_data {  	struct dsi_isr_tables isr_tables_copy;  	int update_channel; -#ifdef DEBUG +#ifdef DSI_PERF_MEASURE  	unsigned update_bytes;  #endif @@ -334,7 +351,7 @@ struct dsi_data {  	u32		errors;  	spinlock_t	errors_lock; -#ifdef DEBUG +#ifdef DSI_PERF_MEASURE  	ktime_t perf_setup_time;  	ktime_t perf_start_time;  #endif @@ -373,7 +390,14 @@ struct dsi_packet_sent_handler_data {  	struct completion *completion;  }; -#ifdef DEBUG +struct dsi_module_id_data { +	u32 address; +	int id; +}; + +static const struct of_device_id dsi_of_match[]; + +#ifdef DSI_PERF_MEASURE  static bool dsi_perf;  module_param(dsi_perf, bool, 0644);  #endif @@ -413,16 +437,32 @@ static inline void dsi_write_reg(struct platform_device *dsidev,  		const struct dsi_reg idx, u32 val)  {  	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); +	void __iomem *base; + +	switch(idx.module) { +		case DSI_PROTO: base = dsi->proto_base; break; +		case DSI_PHY: base = dsi->phy_base; break; +		case DSI_PLL: base = dsi->pll_base; break; +		default: return; +	} -	__raw_writel(val, dsi->base + idx.idx); +	__raw_writel(val, base + idx.idx);  }  static inline u32 dsi_read_reg(struct platform_device *dsidev,  		const struct dsi_reg idx)  {  	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); +	void __iomem *base; + +	switch(idx.module) { +		case DSI_PROTO: base = dsi->proto_base; break; +		case DSI_PHY: base = dsi->phy_base; break; +		case DSI_PLL: base = dsi->pll_base; break; +		default: return 0; +	} -	return __raw_readl(dsi->base + idx.idx); +	return __raw_readl(base + idx.idx);  }  static void dsi_bus_lock(struct omap_dss_device *dssdev) @@ -497,7 +537,7 @@ u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)  	}  } -#ifdef DEBUG +#ifdef DSI_PERF_MEASURE  static void dsi_perf_mark_setup(struct platform_device *dsidev)  {  	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); @@ -757,6 +797,9 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)  	dsidev = (struct platform_device *) arg;  	dsi = dsi_get_dsidrv_data(dsidev); +	if (!dsi->is_enabled) +		return IRQ_NONE; +  	spin_lock(&dsi->irq_lock);  	irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS); @@ -1118,21 +1161,28 @@ static int dsi_regulator_init(struct platform_device *dsidev)  {  	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);  	struct regulator *vdds_dsi; +	int r;  	if (dsi->vdds_dsi_reg != NULL)  		return 0; -	vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "vdds_dsi"); - -	/* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */ -	if (IS_ERR(vdds_dsi)) -		vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "VCXIO"); +	vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "vdd");  	if (IS_ERR(vdds_dsi)) { -		DSSERR("can't get VDDS_DSI regulator\n"); +		if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER) +			DSSERR("can't get DSI VDD regulator\n");  		return PTR_ERR(vdds_dsi);  	} +	if (regulator_can_change_voltage(vdds_dsi)) { +		r = regulator_set_voltage(vdds_dsi, 1800000, 1800000); +		if (r) { +			devm_regulator_put(vdds_dsi); +			DSSERR("can't set the DSI regulator voltage\n"); +			return r; +		} +	} +  	dsi->vdds_dsi_reg = vdds_dsi;  	return 0; @@ -2427,14 +2477,14 @@ static void dsi_config_tx_fifo(struct platform_device *dsidev,  	int add = 0;  	int i; -	dsi->vc[0].fifo_size = size1; -	dsi->vc[1].fifo_size = size2; -	dsi->vc[2].fifo_size = size3; -	dsi->vc[3].fifo_size = size4; +	dsi->vc[0].tx_fifo_size = size1; +	dsi->vc[1].tx_fifo_size = size2; +	dsi->vc[2].tx_fifo_size = size3; +	dsi->vc[3].tx_fifo_size = size4;  	for (i = 0; i < 4; i++) {  		u8 v; -		int size = dsi->vc[i].fifo_size; +		int size = dsi->vc[i].tx_fifo_size;  		if (add + size > 4) {  			DSSERR("Illegal FIFO configuration\n"); @@ -2460,14 +2510,14 @@ static void dsi_config_rx_fifo(struct platform_device *dsidev,  	int add = 0;  	int i; -	dsi->vc[0].fifo_size = size1; -	dsi->vc[1].fifo_size = size2; -	dsi->vc[2].fifo_size = size3; -	dsi->vc[3].fifo_size = size4; +	dsi->vc[0].rx_fifo_size = size1; +	dsi->vc[1].rx_fifo_size = size2; +	dsi->vc[2].rx_fifo_size = size3; +	dsi->vc[3].rx_fifo_size = size4;  	for (i = 0; i < 4; i++) {  		u8 v; -		int size = dsi->vc[i].fifo_size; +		int size = dsi->vc[i].rx_fifo_size;  		if (add + size > 4) {  			DSSERR("Illegal FIFO configuration\n"); @@ -2920,7 +2970,7 @@ static int dsi_vc_send_long(struct platform_device *dsidev, int channel,  		DSSDBG("dsi_vc_send_long, %d bytes\n", len);  	/* len + header */ -	if (dsi->vc[channel].fifo_size * 32 * 4 < len + 4) { +	if (dsi->vc[channel].tx_fifo_size * 32 * 4 < len + 4) {  		DSSERR("unable to send long packet: packet too long.\n");  		return -EINVAL;  	} @@ -4066,7 +4116,7 @@ static int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)  		default:  			r = -EINVAL;  			goto err_pix_fmt; -		}; +		}  		dsi_if_enable(dsidev, false);  		dsi_vc_enable(dsidev, channel, false); @@ -4277,7 +4327,7 @@ static int dsi_update(struct omap_dss_device *dssdev, int channel,  	dw = dsi->timings.x_res;  	dh = dsi->timings.y_res; -#ifdef DEBUG +#ifdef DSI_PERF_MEASURE  	dsi->update_bytes = dw * dh *  		dsi_get_pixel_size(dsi->pix_fmt) / 8;  #endif @@ -4586,7 +4636,7 @@ static void print_dsi_vm(const char *str,  static void print_dispc_vm(const char *str, const struct omap_video_timings *t)  { -	unsigned long pck = t->pixel_clock * 1000; +	unsigned long pck = t->pixelclock;  	int hact, bl, tot;  	hact = t->x_res; @@ -4626,7 +4676,7 @@ static void print_dsi_dispc_vm(const char *str,  	dsi_hact = DIV_ROUND_UP(DIV_ROUND_UP(t->hact * t->bitspp, 8) + 6, t->ndl);  	dsi_htot = t->hss + t->hsa + t->hse + t->hbp + dsi_hact + t->hfp; -	vm.pixel_clock = pck / 1000; +	vm.pixelclock = pck;  	vm.hsw = div64_u64((u64)(t->hsa + t->hse) * pck, byteclk);  	vm.hbp = div64_u64((u64)t->hbp * pck, byteclk);  	vm.hfp = div64_u64((u64)t->hfp * pck, byteclk); @@ -4648,7 +4698,7 @@ static bool dsi_cm_calc_dispc_cb(int lckd, int pckd, unsigned long lck,  	ctx->dispc_cinfo.pck = pck;  	*t = *ctx->config->timings; -	t->pixel_clock = pck / 1000; +	t->pixelclock = pck;  	t->x_res = ctx->config->timings->x_res;  	t->y_res = ctx->config->timings->y_res;  	t->hsw = t->hfp = t->hbp = t->vsw = 1; @@ -4702,7 +4752,7 @@ static bool dsi_cm_calc(struct dsi_data *dsi,  	 * especially as we go to LP between each pixel packet due to HW  	 * "feature". So let's just estimate very roughly and multiply by 1.5.  	 */ -	pck = cfg->timings->pixel_clock * 1000; +	pck = cfg->timings->pixelclock;  	pck = pck * 3 / 2;  	txbyteclk = pck * bitspp / 8 / ndl; @@ -4879,7 +4929,7 @@ static bool dsi_vm_calc_blanking(struct dsi_clk_calc_ctx *ctx)  	dispc_vm = &ctx->dispc_vm;  	*dispc_vm = *req_vm; -	dispc_vm->pixel_clock = dispc_pck / 1000; +	dispc_vm->pixelclock = dispc_pck;  	if (cfg->trans_mode == OMAP_DSS_DSI_PULSE_MODE) {  		hsa = div64_u64((u64)req_vm->hsw * dispc_pck, @@ -5001,9 +5051,9 @@ static bool dsi_vm_calc(struct dsi_data *dsi,  	ctx->dsi_cinfo.clkin = clkin;  	/* these limits should come from the panel driver */ -	ctx->req_pck_min = t->pixel_clock * 1000 - 1000; -	ctx->req_pck_nom = t->pixel_clock * 1000; -	ctx->req_pck_max = t->pixel_clock * 1000 + 1000; +	ctx->req_pck_min = t->pixelclock - 1000; +	ctx->req_pck_nom = t->pixelclock; +	ctx->req_pck_max = t->pixelclock + 1000;  	byteclk_min = div64_u64((u64)ctx->req_pck_min * bitspp, ndl * 8);  	pll_min = max(cfg->hs_clk_min * 4, byteclk_min * 4 * 4); @@ -5082,6 +5132,7 @@ static enum omap_channel dsi_get_channel(int module_id)  {  	switch (omapdss_get_version()) {  	case OMAPDSS_VER_OMAP24xx: +	case OMAPDSS_VER_AM43xx:  		DSSWARN("DSI not supported\n");  		return OMAP_DSS_CHANNEL_LCD; @@ -5340,19 +5391,76 @@ static void dsi_uninit_output(struct platform_device *dsidev)  	omapdss_unregister_output(out);  } +static int dsi_probe_of(struct platform_device *pdev) +{ +	struct device_node *node = pdev->dev.of_node; +	struct dsi_data *dsi = dsi_get_dsidrv_data(pdev); +	struct property *prop; +	u32 lane_arr[10]; +	int len, num_pins; +	int r, i; +	struct device_node *ep; +	struct omap_dsi_pin_config pin_cfg; + +	ep = omapdss_of_get_first_endpoint(node); +	if (!ep) +		return 0; + +	prop = of_find_property(ep, "lanes", &len); +	if (prop == NULL) { +		dev_err(&pdev->dev, "failed to find lane data\n"); +		r = -EINVAL; +		goto err; +	} + +	num_pins = len / sizeof(u32); + +	if (num_pins < 4 || num_pins % 2 != 0 || +		num_pins > dsi->num_lanes_supported * 2) { +		dev_err(&pdev->dev, "bad number of lanes\n"); +		r = -EINVAL; +		goto err; +	} + +	r = of_property_read_u32_array(ep, "lanes", lane_arr, num_pins); +	if (r) { +		dev_err(&pdev->dev, "failed to read lane data\n"); +		goto err; +	} + +	pin_cfg.num_pins = num_pins; +	for (i = 0; i < num_pins; ++i) +		pin_cfg.pins[i] = (int)lane_arr[i]; + +	r = dsi_configure_pins(&dsi->output, &pin_cfg); +	if (r) { +		dev_err(&pdev->dev, "failed to configure pins"); +		goto err; +	} + +	of_node_put(ep); + +	return 0; + +err: +	of_node_put(ep); +	return r; +} +  /* DSI1 HW IP initialisation */  static int omap_dsihw_probe(struct platform_device *dsidev)  {  	u32 rev;  	int r, i; -	struct resource *dsi_mem;  	struct dsi_data *dsi; +	struct resource *dsi_mem; +	struct resource *res; +	struct resource temp_res;  	dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL);  	if (!dsi)  		return -ENOMEM; -	dsi->module_id = dsidev->id;  	dsi->pdev = dsidev;  	dev_set_drvdata(&dsidev->dev, dsi); @@ -5376,16 +5484,66 @@ static int omap_dsihw_probe(struct platform_device *dsidev)  	dsi->te_timer.function = dsi_te_timeout;  	dsi->te_timer.data = 0;  #endif -	dsi_mem = platform_get_resource(dsi->pdev, IORESOURCE_MEM, 0); -	if (!dsi_mem) { -		DSSERR("can't get IORESOURCE_MEM DSI\n"); -		return -EINVAL; + +	res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "proto"); +	if (!res) { +		res = platform_get_resource(dsidev, IORESOURCE_MEM, 0); +		if (!res) { +			DSSERR("can't get IORESOURCE_MEM DSI\n"); +			return -EINVAL; +		} + +		temp_res.start = res->start; +		temp_res.end = temp_res.start + DSI_PROTO_SZ - 1; +		res = &temp_res;  	} -	dsi->base = devm_ioremap(&dsidev->dev, dsi_mem->start, -				 resource_size(dsi_mem)); -	if (!dsi->base) { -		DSSERR("can't ioremap DSI\n"); +	dsi_mem = res; + +	dsi->proto_base = devm_ioremap(&dsidev->dev, res->start, +		resource_size(res)); +	if (!dsi->proto_base) { +		DSSERR("can't ioremap DSI protocol engine\n"); +		return -ENOMEM; +	} + +	res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "phy"); +	if (!res) { +		res = platform_get_resource(dsidev, IORESOURCE_MEM, 0); +		if (!res) { +			DSSERR("can't get IORESOURCE_MEM DSI\n"); +			return -EINVAL; +		} + +		temp_res.start = res->start + DSI_PHY_OFFSET; +		temp_res.end = temp_res.start + DSI_PHY_SZ - 1; +		res = &temp_res; +	} + +	dsi->phy_base = devm_ioremap(&dsidev->dev, res->start, +		resource_size(res)); +	if (!dsi->proto_base) { +		DSSERR("can't ioremap DSI PHY\n"); +		return -ENOMEM; +	} + +	res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "pll"); +	if (!res) { +		res = platform_get_resource(dsidev, IORESOURCE_MEM, 0); +		if (!res) { +			DSSERR("can't get IORESOURCE_MEM DSI\n"); +			return -EINVAL; +		} + +		temp_res.start = res->start + DSI_PLL_OFFSET; +		temp_res.end = temp_res.start + DSI_PLL_SZ - 1; +		res = &temp_res; +	} + +	dsi->pll_base = devm_ioremap(&dsidev->dev, res->start, +		resource_size(res)); +	if (!dsi->proto_base) { +		DSSERR("can't ioremap DSI PLL\n");  		return -ENOMEM;  	} @@ -5402,6 +5560,31 @@ static int omap_dsihw_probe(struct platform_device *dsidev)  		return r;  	} +	if (dsidev->dev.of_node) { +		const struct of_device_id *match; +		const struct dsi_module_id_data *d; + +		match = of_match_node(dsi_of_match, dsidev->dev.of_node); +		if (!match) { +			DSSERR("unsupported DSI module\n"); +			return -ENODEV; +		} + +		d = match->data; + +		while (d->address != 0 && d->address != dsi_mem->start) +			d++; + +		if (d->address == 0) { +			DSSERR("unsupported DSI module\n"); +			return -ENODEV; +		} + +		dsi->module_id = d->id; +	} else { +		dsi->module_id = dsidev->id; +	} +  	/* DSI VCs initialization */  	for (i = 0; i < ARRAY_SIZE(dsi->vc); i++) {  		dsi->vc[i].source = DSI_VC_SOURCE_L4; @@ -5437,6 +5620,19 @@ static int omap_dsihw_probe(struct platform_device *dsidev)  	dsi_init_output(dsidev); +	if (dsidev->dev.of_node) { +		r = dsi_probe_of(dsidev); +		if (r) { +			DSSERR("Invalid DSI DT data\n"); +			goto err_probe_of; +		} + +		r = of_platform_populate(dsidev->dev.of_node, NULL, NULL, +			&dsidev->dev); +		if (r) +			DSSERR("Failed to populate DSI child devices: %d\n", r); +	} +  	dsi_runtime_put(dsidev);  	if (dsi->module_id == 0) @@ -5450,17 +5646,31 @@ static int omap_dsihw_probe(struct platform_device *dsidev)  	else if (dsi->module_id == 1)  		dss_debugfs_create_file("dsi2_irqs", dsi2_dump_irqs);  #endif +  	return 0; +err_probe_of: +	dsi_uninit_output(dsidev); +	dsi_runtime_put(dsidev); +  err_runtime_get:  	pm_runtime_disable(&dsidev->dev);  	return r;  } +static int dsi_unregister_child(struct device *dev, void *data) +{ +	struct platform_device *pdev = to_platform_device(dev); +	platform_device_unregister(pdev); +	return 0; +} +  static int __exit omap_dsihw_remove(struct platform_device *dsidev)  {  	struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); +	device_for_each_child(&dsidev->dev, NULL, dsi_unregister_child); +  	WARN_ON(dsi->scp_clk_refcount > 0);  	dsi_uninit_output(dsidev); @@ -5477,6 +5687,15 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)  static int dsi_runtime_suspend(struct device *dev)  { +	struct platform_device *pdev = to_platform_device(dev); +	struct dsi_data *dsi = dsi_get_dsidrv_data(pdev); + +	dsi->is_enabled = false; +	/* ensure the irq handler sees the is_enabled value */ +	smp_wmb(); +	/* wait for current handler to finish before turning the DSI off */ +	synchronize_irq(dsi->irq); +  	dispc_runtime_put();  	return 0; @@ -5484,12 +5703,18 @@ static int dsi_runtime_suspend(struct device *dev)  static int dsi_runtime_resume(struct device *dev)  { +	struct platform_device *pdev = to_platform_device(dev); +	struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);  	int r;  	r = dispc_runtime_get();  	if (r)  		return r; +	dsi->is_enabled = true; +	/* ensure the irq handler sees the is_enabled value */ +	smp_wmb(); +  	return 0;  } @@ -5498,6 +5723,30 @@ static const struct dev_pm_ops dsi_pm_ops = {  	.runtime_resume = dsi_runtime_resume,  }; +static const struct dsi_module_id_data dsi_of_data_omap3[] = { +	{ .address = 0x4804fc00, .id = 0, }, +	{ }, +}; + +static const struct dsi_module_id_data dsi_of_data_omap4[] = { +	{ .address = 0x58004000, .id = 0, }, +	{ .address = 0x58005000, .id = 1, }, +	{ }, +}; + +static const struct dsi_module_id_data dsi_of_data_omap5[] = { +	{ .address = 0x58004000, .id = 0, }, +	{ .address = 0x58009000, .id = 1, }, +	{ }, +}; + +static const struct of_device_id dsi_of_match[] = { +	{ .compatible = "ti,omap3-dsi", .data = dsi_of_data_omap3, }, +	{ .compatible = "ti,omap4-dsi", .data = dsi_of_data_omap4, }, +	{ .compatible = "ti,omap5-dsi", .data = dsi_of_data_omap5, }, +	{}, +}; +  static struct platform_driver omap_dsihw_driver = {  	.probe		= omap_dsihw_probe,  	.remove         = __exit_p(omap_dsihw_remove), @@ -5505,6 +5754,7 @@ static struct platform_driver omap_dsihw_driver = {  		.name   = "omapdss_dsi",  		.owner  = THIS_MODULE,  		.pm	= &dsi_pm_ops, +		.of_match_table = dsi_of_match,  	},  }; diff --git a/drivers/video/fbdev/omap2/dss/dss-of.c b/drivers/video/fbdev/omap2/dss/dss-of.c new file mode 100644 index 00000000000..a4b20aaf614 --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/dss-of.c @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2013 Texas Instruments + * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + */ + +#include <linux/device.h> +#include <linux/err.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/seq_file.h> + +#include <video/omapdss.h> + +struct device_node * +omapdss_of_get_next_port(const struct device_node *parent, +			 struct device_node *prev) +{ +	struct device_node *port = NULL; + +	if (!parent) +		return NULL; + +	if (!prev) { +		struct device_node *ports; +		/* +		 * It's the first call, we have to find a port subnode +		 * within this node or within an optional 'ports' node. +		 */ +		ports = of_get_child_by_name(parent, "ports"); +		if (ports) +			parent = ports; + +		port = of_get_child_by_name(parent, "port"); + +		/* release the 'ports' node */ +		of_node_put(ports); +	} else { +		struct device_node *ports; + +		ports = of_get_parent(prev); +		if (!ports) +			return NULL; + +		do { +			port = of_get_next_child(ports, prev); +			if (!port) { +				of_node_put(ports); +				return NULL; +			} +			prev = port; +		} while (of_node_cmp(port->name, "port") != 0); +	} + +	return port; +} +EXPORT_SYMBOL_GPL(omapdss_of_get_next_port); + +struct device_node * +omapdss_of_get_next_endpoint(const struct device_node *parent, +			     struct device_node *prev) +{ +	struct device_node *ep = NULL; + +	if (!parent) +		return NULL; + +	do { +		ep = of_get_next_child(parent, prev); +		if (!ep) +			return NULL; +		prev = ep; +	} while (of_node_cmp(ep->name, "endpoint") != 0); + +	return ep; +} +EXPORT_SYMBOL_GPL(omapdss_of_get_next_endpoint); + +static struct device_node * +omapdss_of_get_remote_device_node(const struct device_node *node) +{ +	struct device_node *np; +	int i; + +	np = of_parse_phandle(node, "remote-endpoint", 0); + +	if (!np) +		return NULL; + +	np = of_get_next_parent(np); + +	for (i = 0; i < 3 && np; ++i) { +		struct property *prop; + +		prop = of_find_property(np, "compatible", NULL); + +		if (prop) +			return np; + +		np = of_get_next_parent(np); +	} + +	return NULL; +} + +struct device_node * +omapdss_of_get_first_endpoint(const struct device_node *parent) +{ +	struct device_node *port, *ep; + +	port = omapdss_of_get_next_port(parent, NULL); + +	if (!port) +		return NULL; + +	ep = omapdss_of_get_next_endpoint(port, NULL); + +	of_node_put(port); + +	return ep; +} +EXPORT_SYMBOL_GPL(omapdss_of_get_first_endpoint); + +struct omap_dss_device * +omapdss_of_find_source_for_first_ep(struct device_node *node) +{ +	struct device_node *ep; +	struct device_node *src_node; +	struct omap_dss_device *src; + +	ep = omapdss_of_get_first_endpoint(node); +	if (!ep) +		return ERR_PTR(-EINVAL); + +	src_node = omapdss_of_get_remote_device_node(ep); + +	of_node_put(ep); + +	if (!src_node) +		return ERR_PTR(-EINVAL); + +	src = omap_dss_find_output_by_node(src_node); + +	of_node_put(src_node); + +	if (!src) +		return ERR_PTR(-EPROBE_DEFER); + +	return src; +} +EXPORT_SYMBOL_GPL(omapdss_of_find_source_for_first_ep); diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c index bd01608e67e..6daeb7ed44c 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/fbdev/omap2/dss/dss.c @@ -23,6 +23,7 @@  #define DSS_SUBSYS_NAME "DSS"  #include <linux/kernel.h> +#include <linux/module.h>  #include <linux/io.h>  #include <linux/export.h>  #include <linux/err.h> @@ -33,6 +34,7 @@  #include <linux/pm_runtime.h>  #include <linux/gfp.h>  #include <linux/sizes.h> +#include <linux/of.h>  #include <video/omapdss.h> @@ -67,7 +69,7 @@ static void dss_runtime_put(void);  struct dss_features {  	u8 fck_div_max;  	u8 dss_fck_multiplier; -	const char *clk_name; +	const char *parent_clk_name;  	int (*dpi_select_source)(enum omap_channel channel);  }; @@ -75,13 +77,12 @@ static struct {  	struct platform_device *pdev;  	void __iomem    *base; -	struct clk	*dpll4_m4_ck; +	struct clk	*parent_clk;  	struct clk	*dss_clk;  	unsigned long	dss_clk_rate;  	unsigned long	cache_req_pck;  	unsigned long	cache_prate; -	struct dss_clock_info cache_dss_cinfo;  	struct dispc_clock_info cache_dispc_cinfo;  	enum omap_dss_clk_source dsi_clk_source[MAX_NUM_DSI]; @@ -155,22 +156,6 @@ static void dss_restore_context(void)  #undef SR  #undef RR -int dss_get_ctx_loss_count(void) -{ -	struct platform_device *core_pdev = dss_get_core_pdev(); -	struct omap_dss_board_info *board_data = core_pdev->dev.platform_data; -	int cnt; - -	if (!board_data->get_context_loss_count) -		return -ENOENT; - -	cnt = board_data->get_context_loss_count(&dss.pdev->dev); - -	WARN_ONCE(cnt < 0, "get_context_loss_count failed: %d\n", cnt); - -	return cnt; -} -  void dss_sdi_init(int datapairs)  {  	u32 l; @@ -265,8 +250,6 @@ const char *dss_get_generic_clk_source_name(enum omap_dss_clk_source clk_src)  void dss_dump_clocks(struct seq_file *s)  { -	unsigned long dpll4_ck_rate; -	unsigned long dpll4_m4_ck_rate;  	const char *fclk_name, *fclk_real_name;  	unsigned long fclk_rate; @@ -279,21 +262,9 @@ void dss_dump_clocks(struct seq_file *s)  	fclk_real_name = dss_feat_get_clk_source_name(OMAP_DSS_CLK_SRC_FCK);  	fclk_rate = clk_get_rate(dss.dss_clk); -	if (dss.dpll4_m4_ck) { -		dpll4_ck_rate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); -		dpll4_m4_ck_rate = clk_get_rate(dss.dpll4_m4_ck); - -		seq_printf(s, "dpll4_ck %lu\n", dpll4_ck_rate); - -		seq_printf(s, "%s (%s) = %lu / %lu * %d  = %lu\n", -				fclk_name, fclk_real_name, dpll4_ck_rate, -				dpll4_ck_rate / dpll4_m4_ck_rate, -				dss.feat->dss_fck_multiplier, fclk_rate); -	} else { -		seq_printf(s, "%s (%s) = %lu\n", -				fclk_name, fclk_real_name, -				fclk_rate); -	} +	seq_printf(s, "%s (%s) = %lu\n", +			fclk_name, fclk_real_name, +			fclk_rate);  	dss_runtime_put();  } @@ -451,30 +422,8 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel)  	}  } -/* calculate clock rates using dividers in cinfo */ -int dss_calc_clock_rates(struct dss_clock_info *cinfo) -{ -	if (dss.dpll4_m4_ck) { -		unsigned long prate; - -		if (cinfo->fck_div > dss.feat->fck_div_max || -				cinfo->fck_div == 0) -			return -EINVAL; - -		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); - -		cinfo->fck = prate / cinfo->fck_div * -			dss.feat->dss_fck_multiplier; -	} else { -		if (cinfo->fck_div != 0) -			return -EINVAL; -		cinfo->fck = clk_get_rate(dss.dss_clk); -	} - -	return 0; -} - -bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data) +bool dss_div_calc(unsigned long pck, unsigned long fck_min, +		dss_div_calc_func func, void *data)  {  	int fckd, fckd_start, fckd_stop;  	unsigned long fck; @@ -483,22 +432,24 @@ bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data)  	unsigned long prate;  	unsigned m; -	if (dss.dpll4_m4_ck == NULL) { -		/* -		 * TODO: dss1_fclk can be changed on OMAP2, but the available -		 * dividers are not continuous. We just use the pre-set rate for -		 * now. -		 */ -		fck = clk_get_rate(dss.dss_clk); -		fckd = 1; -		return func(fckd, fck, data); +	fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); + +	if (dss.parent_clk == NULL) { +		unsigned pckd; + +		pckd = fck_hw_max / pck; + +		fck = pck * pckd; + +		fck = clk_round_rate(dss.dss_clk, fck); + +		return func(fck, data);  	} -	fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);  	fckd_hw_max = dss.feat->fck_div_max;  	m = dss.feat->dss_fck_multiplier; -	prate = dss_get_dpll4_rate(); +	prate = clk_get_rate(dss.parent_clk);  	fck_min = fck_min ? fck_min : 1; @@ -506,52 +457,34 @@ bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data)  	fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul);  	for (fckd = fckd_start; fckd >= fckd_stop; --fckd) { -		fck = prate / fckd * m; +		fck = DIV_ROUND_UP(prate, fckd) * m; -		if (func(fckd, fck, data)) +		if (func(fck, data))  			return true;  	}  	return false;  } -int dss_set_clock_div(struct dss_clock_info *cinfo) +int dss_set_fck_rate(unsigned long rate)  { -	if (dss.dpll4_m4_ck) { -		unsigned long prate; -		int r; +	int r; -		prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); -		DSSDBG("dpll4_m4 = %ld\n", prate); +	DSSDBG("set fck to %lu\n", rate); -		r = clk_set_rate(dss.dpll4_m4_ck, -				DIV_ROUND_UP(prate, cinfo->fck_div)); -		if (r) -			return r; -	} else { -		if (cinfo->fck_div != 0) -			return -EINVAL; -	} +	r = clk_set_rate(dss.dss_clk, rate); +	if (r) +		return r;  	dss.dss_clk_rate = clk_get_rate(dss.dss_clk); -	WARN_ONCE(dss.dss_clk_rate != cinfo->fck, +	WARN_ONCE(dss.dss_clk_rate != rate,  			"clk rate mismatch: %lu != %lu", dss.dss_clk_rate, -			cinfo->fck); - -	DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div); +			rate);  	return 0;  } -unsigned long dss_get_dpll4_rate(void) -{ -	if (dss.dpll4_m4_ck) -		return clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); -	else -		return 0; -} -  unsigned long dss_get_dispc_clk_rate(void)  {  	return dss.dss_clk_rate; @@ -560,27 +493,23 @@ unsigned long dss_get_dispc_clk_rate(void)  static int dss_setup_default_clock(void)  {  	unsigned long max_dss_fck, prate; +	unsigned long fck;  	unsigned fck_div; -	struct dss_clock_info dss_cinfo = { 0 };  	int r; -	if (dss.dpll4_m4_ck == NULL) -		return 0; -  	max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK); -	prate = dss_get_dpll4_rate(); - -	fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier, -			max_dss_fck); - -	dss_cinfo.fck_div = fck_div; +	if (dss.parent_clk == NULL) { +		fck = clk_round_rate(dss.dss_clk, max_dss_fck); +	} else { +		prate = clk_get_rate(dss.parent_clk); -	r = dss_calc_clock_rates(&dss_cinfo); -	if (r) -		return r; +		fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier, +				max_dss_fck); +		fck = DIV_ROUND_UP(prate, fck_div) * dss.feat->dss_fck_multiplier; +	} -	r = dss_set_clock_div(&dss_cinfo); +	r = dss_set_fck_rate(fck);  	if (r)  		return r; @@ -706,25 +635,25 @@ static int dss_get_clocks(void)  	dss.dss_clk = clk; -	if (dss.feat->clk_name) { -		clk = clk_get(NULL, dss.feat->clk_name); +	if (dss.feat->parent_clk_name) { +		clk = clk_get(NULL, dss.feat->parent_clk_name);  		if (IS_ERR(clk)) { -			DSSERR("Failed to get %s\n", dss.feat->clk_name); +			DSSERR("Failed to get %s\n", dss.feat->parent_clk_name);  			return PTR_ERR(clk);  		}  	} else {  		clk = NULL;  	} -	dss.dpll4_m4_ck = clk; +	dss.parent_clk = clk;  	return 0;  }  static void dss_put_clocks(void)  { -	if (dss.dpll4_m4_ck) -		clk_put(dss.dpll4_m4_ck); +	if (dss.parent_clk) +		clk_put(dss.parent_clk);  }  static int dss_runtime_get(void) @@ -761,40 +690,51 @@ void dss_debug_dump_clocks(struct seq_file *s)  #endif  static const struct dss_features omap24xx_dss_feats __initconst = { -	.fck_div_max		=	16, +	/* +	 * fck div max is really 16, but the divider range has gaps. The range +	 * from 1 to 6 has no gaps, so let's use that as a max. +	 */ +	.fck_div_max		=	6,  	.dss_fck_multiplier	=	2, -	.clk_name		=	NULL, +	.parent_clk_name	=	"core_ck",  	.dpi_select_source	=	&dss_dpi_select_source_omap2_omap3,  };  static const struct dss_features omap34xx_dss_feats __initconst = {  	.fck_div_max		=	16,  	.dss_fck_multiplier	=	2, -	.clk_name		=	"dpll4_m4_ck", +	.parent_clk_name	=	"dpll4_ck",  	.dpi_select_source	=	&dss_dpi_select_source_omap2_omap3,  };  static const struct dss_features omap3630_dss_feats __initconst = {  	.fck_div_max		=	32,  	.dss_fck_multiplier	=	1, -	.clk_name		=	"dpll4_m4_ck", +	.parent_clk_name	=	"dpll4_ck",  	.dpi_select_source	=	&dss_dpi_select_source_omap2_omap3,  };  static const struct dss_features omap44xx_dss_feats __initconst = {  	.fck_div_max		=	32,  	.dss_fck_multiplier	=	1, -	.clk_name		=	"dpll_per_m5x2_ck", +	.parent_clk_name	=	"dpll_per_x2_ck",  	.dpi_select_source	=	&dss_dpi_select_source_omap4,  };  static const struct dss_features omap54xx_dss_feats __initconst = {  	.fck_div_max		=	64,  	.dss_fck_multiplier	=	1, -	.clk_name		=	"dpll_per_h12x2_ck", +	.parent_clk_name	=	"dpll_per_x2_ck",  	.dpi_select_source	=	&dss_dpi_select_source_omap5,  }; +static const struct dss_features am43xx_dss_feats __initconst = { +	.fck_div_max		=	0, +	.dss_fck_multiplier	=	0, +	.parent_clk_name	=	NULL, +	.dpi_select_source	=	&dss_dpi_select_source_omap2_omap3, +}; +  static int __init dss_init_features(struct platform_device *pdev)  {  	const struct dss_features *src; @@ -831,6 +771,10 @@ static int __init dss_init_features(struct platform_device *pdev)  		src = &omap54xx_dss_feats;  		break; +	case OMAPDSS_VER_AM43xx: +		src = &am43xx_dss_feats; +		break; +  	default:  		return -ENODEV;  	} @@ -841,6 +785,52 @@ static int __init dss_init_features(struct platform_device *pdev)  	return 0;  } +static int __init dss_init_ports(struct platform_device *pdev) +{ +	struct device_node *parent = pdev->dev.of_node; +	struct device_node *port; +	int r; + +	if (parent == NULL) +		return 0; + +	port = omapdss_of_get_next_port(parent, NULL); +	if (!port) +		return 0; + +	do { +		u32 reg; + +		r = of_property_read_u32(port, "reg", ®); +		if (r) +			reg = 0; + +#ifdef CONFIG_OMAP2_DSS_DPI +		if (reg == 0) +			dpi_init_port(pdev, port); +#endif + +#ifdef CONFIG_OMAP2_DSS_SDI +		if (reg == 1) +			sdi_init_port(pdev, port); +#endif + +	} while ((port = omapdss_of_get_next_port(parent, port)) != NULL); + +	return 0; +} + +static void __exit dss_uninit_ports(void) +{ +#ifdef CONFIG_OMAP2_DSS_DPI +	dpi_uninit_port(); +#endif + +#ifdef CONFIG_OMAP2_DSS_SDI +	sdi_uninit_port(); +#endif +} +  /* DSS HW IP initialisation */  static int __init omap_dsshw_probe(struct platform_device *pdev)  { @@ -899,6 +889,8 @@ static int __init omap_dsshw_probe(struct platform_device *pdev)  	dss.lcd_clk_source[0] = OMAP_DSS_CLK_SRC_FCK;  	dss.lcd_clk_source[1] = OMAP_DSS_CLK_SRC_FCK; +	dss_init_ports(pdev); +  	rev = dss_read_reg(DSS_REVISION);  	printk(KERN_INFO "OMAP DSS rev %d.%d\n",  			FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0)); @@ -918,6 +910,8 @@ err_setup_clocks:  static int __exit omap_dsshw_remove(struct platform_device *pdev)  { +	dss_uninit_ports(); +  	pm_runtime_disable(&pdev->dev);  	dss_put_clocks(); @@ -955,12 +949,23 @@ static const struct dev_pm_ops dss_pm_ops = {  	.runtime_resume = dss_runtime_resume,  }; +static const struct of_device_id dss_of_match[] = { +	{ .compatible = "ti,omap2-dss", }, +	{ .compatible = "ti,omap3-dss", }, +	{ .compatible = "ti,omap4-dss", }, +	{ .compatible = "ti,omap5-dss", }, +	{}, +}; + +MODULE_DEVICE_TABLE(of, dss_of_match); +  static struct platform_driver omap_dsshw_driver = {  	.remove         = __exit_p(omap_dsshw_remove),  	.driver         = {  		.name   = "omapdss_dss",  		.owner  = THIS_MODULE,  		.pm	= &dss_pm_ops, +		.of_match_table = dss_of_match,  	},  }; diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h index e172531d196..8ff22c134c6 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/fbdev/omap2/dss/dss.h @@ -100,14 +100,6 @@ enum dss_writeback_channel {  	DSS_WB_LCD3_MGR =	7,  }; -struct dss_clock_info { -	/* rates that we get with dividers below */ -	unsigned long fck; - -	/* dividers */ -	u16 fck_div; -}; -  struct dispc_clock_info {  	/* rates that we get with dividers below */  	unsigned long lck; @@ -139,12 +131,6 @@ struct dsi_clock_info {  	u16 lp_clk_div;  }; -struct reg_field { -	u16 reg; -	u8 high; -	u8 low; -}; -  struct dss_lcd_mgr_config {  	enum dss_io_pad_mode io_pad_mode; @@ -233,8 +219,6 @@ void dss_dump_clocks(struct seq_file *s);  void dss_debug_dump_clocks(struct seq_file *s);  #endif -int dss_get_ctx_loss_count(void); -  void dss_sdi_init(int datapairs);  int dss_sdi_enable(void);  void dss_sdi_disable(void); @@ -250,17 +234,19 @@ enum omap_dss_clk_source dss_get_lcd_clk_source(enum omap_channel channel);  void dss_set_venc_output(enum omap_dss_venc_type type);  void dss_set_dac_pwrdn_bgz(bool enable); -unsigned long dss_get_dpll4_rate(void); -int dss_calc_clock_rates(struct dss_clock_info *cinfo); -int dss_set_clock_div(struct dss_clock_info *cinfo); +int dss_set_fck_rate(unsigned long rate); -typedef bool (*dss_div_calc_func)(int fckd, unsigned long fck, void *data); -bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data); +typedef bool (*dss_div_calc_func)(unsigned long fck, void *data); +bool dss_div_calc(unsigned long pck, unsigned long fck_min, +		dss_div_calc_func func, void *data);  /* SDI */  int sdi_init_platform_driver(void) __init;  void sdi_uninit_platform_driver(void) __exit; +int sdi_init_port(struct platform_device *pdev, struct device_node *port) __init; +void sdi_uninit_port(void) __exit; +  /* DSI */  typedef bool (*dsi_pll_calc_func)(int regn, int regm, unsigned long fint, @@ -372,6 +358,9 @@ static inline bool dsi_pll_calc(struct platform_device *dsidev,  int dpi_init_platform_driver(void) __init;  void dpi_uninit_platform_driver(void) __exit; +int dpi_init_port(struct platform_device *pdev, struct device_node *port) __init; +void dpi_uninit_port(void) __exit; +  /* DISPC */  int dispc_init_platform_driver(void) __init;  void dispc_uninit_platform_driver(void) __exit; @@ -427,8 +416,11 @@ int venc_init_platform_driver(void) __init;  void venc_uninit_platform_driver(void) __exit;  /* HDMI */ -int hdmi_init_platform_driver(void) __init; -void hdmi_uninit_platform_driver(void) __exit; +int hdmi4_init_platform_driver(void) __init; +void hdmi4_uninit_platform_driver(void) __exit; + +int hdmi5_init_platform_driver(void) __init; +void hdmi5_uninit_platform_driver(void) __exit;  /* RFBI */  int rfbi_init_platform_driver(void) __init; diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/fbdev/omap2/dss/dss_features.c index b9cfebb378a..15088df7bd1 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/fbdev/omap2/dss/dss_features.c @@ -93,6 +93,17 @@ static const struct dss_reg_field omap3_dss_reg_fields[] = {  	[FEAT_REG_DSIPLL_REGM_DSI]		= { 26, 23 },  }; +static const struct dss_reg_field am43xx_dss_reg_fields[] = { +	[FEAT_REG_FIRHINC]			= { 12, 0 }, +	[FEAT_REG_FIRVINC]			= { 28, 16 }, +	[FEAT_REG_FIFOLOWTHRESHOLD]	= { 11, 0 }, +	[FEAT_REG_FIFOHIGHTHRESHOLD]		= { 27, 16 }, +	[FEAT_REG_FIFOSIZE]		= { 10, 0 }, +	[FEAT_REG_HORIZONTALACCU]		= { 9, 0 }, +	[FEAT_REG_VERTICALACCU]			= { 25, 16 }, +	[FEAT_REG_DISPC_CLK_SWITCH]		= { 0, 0 }, +}; +  static const struct dss_reg_field omap4_dss_reg_fields[] = {  	[FEAT_REG_FIRHINC]			= { 12, 0 },  	[FEAT_REG_FIRVINC]			= { 28, 16 }, @@ -149,6 +160,11 @@ static const enum omap_display_type omap3630_dss_supported_displays[] = {  	OMAP_DISPLAY_TYPE_VENC,  }; +static const enum omap_display_type am43xx_dss_supported_displays[] = { +	/* OMAP_DSS_CHANNEL_LCD */ +	OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI, +}; +  static const enum omap_display_type omap4_dss_supported_displays[] = {  	/* OMAP_DSS_CHANNEL_LCD */  	OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI, @@ -200,6 +216,11 @@ static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {  	OMAP_DSS_OUTPUT_VENC,  }; +static const enum omap_dss_output_id am43xx_dss_supported_outputs[] = { +	/* OMAP_DSS_CHANNEL_LCD */ +	OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI, +}; +  static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {  	/* OMAP_DSS_CHANNEL_LCD */  	OMAP_DSS_OUTPUT_DBI | OMAP_DSS_OUTPUT_DSI1, @@ -444,6 +465,13 @@ static const struct dss_param_range omap3_dss_param_range[] = {  	[FEAT_PARAM_LINEWIDTH]			= { 1, 1024 },  }; +static const struct dss_param_range am43xx_dss_param_range[] = { +	[FEAT_PARAM_DSS_FCK]			= { 0, 200000000 }, +	[FEAT_PARAM_DSS_PCD]			= { 2, 255 }, +	[FEAT_PARAM_DOWNSCALE]			= { 1, 4 }, +	[FEAT_PARAM_LINEWIDTH]			= { 1, 1024 }, +}; +  static const struct dss_param_range omap4_dss_param_range[] = {  	[FEAT_PARAM_DSS_FCK]			= { 0, 186000000 },  	[FEAT_PARAM_DSS_PCD]			= { 1, 255 }, @@ -520,6 +548,21 @@ static const enum dss_feat_id am35xx_dss_feat_list[] = {  	FEAT_OMAP3_DSI_FIFO_BUG,  }; +static const enum dss_feat_id am43xx_dss_feat_list[] = { +	FEAT_LCDENABLEPOL, +	FEAT_LCDENABLESIGNAL, +	FEAT_PCKFREEENABLE, +	FEAT_FUNCGATED, +	FEAT_LINEBUFFERSPLIT, +	FEAT_ROWREPEATENABLE, +	FEAT_RESIZECONF, +	FEAT_CPR, +	FEAT_PRELOAD, +	FEAT_FIR_COEF_V, +	FEAT_ALPHA_FIXED_ZORDER, +	FEAT_FIFO_MERGE, +}; +  static const enum dss_feat_id omap3630_dss_feat_list[] = {  	FEAT_LCDENABLEPOL,  	FEAT_LCDENABLESIGNAL, @@ -595,6 +638,7 @@ static const enum dss_feat_id omap4_dss_feat_list[] = {  static const enum dss_feat_id omap5_dss_feat_list[] = {  	FEAT_MGR_LCD2, +	FEAT_MGR_LCD3,  	FEAT_CORE_CLK_DIV,  	FEAT_LCD_CLK_SRC,  	FEAT_DSI_DCS_CMD_CONFIG_VC, @@ -613,6 +657,7 @@ static const enum dss_feat_id omap5_dss_feat_list[] = {  	FEAT_DSI_PLL_SELFREQDCO,  	FEAT_DSI_PLL_REFSEL,  	FEAT_DSI_PHY_DCC, +	FEAT_MFLAG,  };  /* OMAP2 DSS Features */ @@ -681,6 +726,26 @@ static const struct omap_dss_features am35xx_dss_features = {  	.burst_size_unit = 8,  }; +static const struct omap_dss_features am43xx_dss_features = { +	.reg_fields = am43xx_dss_reg_fields, +	.num_reg_fields = ARRAY_SIZE(am43xx_dss_reg_fields), + +	.features = am43xx_dss_feat_list, +	.num_features = ARRAY_SIZE(am43xx_dss_feat_list), + +	.num_mgrs = 1, +	.num_ovls = 3, +	.supported_displays = am43xx_dss_supported_displays, +	.supported_outputs = am43xx_dss_supported_outputs, +	.supported_color_modes = omap3_dss_supported_color_modes, +	.overlay_caps = omap3430_dss_overlay_caps, +	.clksrc_names = omap2_dss_clk_source_names, +	.dss_params = am43xx_dss_param_range, +	.supported_rotation_types = OMAP_DSS_ROT_DMA, +	.buffer_size_unit = 1, +	.burst_size_unit = 8, +}; +  static const struct omap_dss_features omap3630_dss_features = {  	.reg_fields = omap3_dss_reg_fields,  	.num_reg_fields = ARRAY_SIZE(omap3_dss_reg_fields), @@ -776,7 +841,7 @@ static const struct omap_dss_features omap5_dss_features = {  	.features = omap5_dss_feat_list,  	.num_features = ARRAY_SIZE(omap5_dss_feat_list), -	.num_mgrs = 3, +	.num_mgrs = 4,  	.num_ovls = 4,  	.supported_displays = omap5_dss_supported_displays,  	.supported_outputs = omap5_dss_supported_outputs, @@ -789,50 +854,6 @@ static const struct omap_dss_features omap5_dss_features = {  	.burst_size_unit = 16,  }; -#if defined(CONFIG_OMAP4_DSS_HDMI) -/* HDMI OMAP4 Functions*/ -static const struct ti_hdmi_ip_ops omap4_hdmi_functions = { - -	.video_configure	=	ti_hdmi_4xxx_basic_configure, -	.phy_enable		=	ti_hdmi_4xxx_phy_enable, -	.phy_disable		=	ti_hdmi_4xxx_phy_disable, -	.read_edid		=	ti_hdmi_4xxx_read_edid, -	.pll_enable		=	ti_hdmi_4xxx_pll_enable, -	.pll_disable		=	ti_hdmi_4xxx_pll_disable, -	.video_enable		=	ti_hdmi_4xxx_wp_video_start, -	.video_disable		=	ti_hdmi_4xxx_wp_video_stop, -	.dump_wrapper		=	ti_hdmi_4xxx_wp_dump, -	.dump_core		=	ti_hdmi_4xxx_core_dump, -	.dump_pll		=	ti_hdmi_4xxx_pll_dump, -	.dump_phy		=	ti_hdmi_4xxx_phy_dump, -#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -	.audio_enable		=       ti_hdmi_4xxx_wp_audio_enable, -	.audio_disable		=       ti_hdmi_4xxx_wp_audio_disable, -	.audio_start		=       ti_hdmi_4xxx_audio_start, -	.audio_stop		=       ti_hdmi_4xxx_audio_stop, -	.audio_config		=	ti_hdmi_4xxx_audio_config, -	.audio_get_dma_port	=	ti_hdmi_4xxx_audio_get_dma_port, -#endif - -}; - -void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data, -		enum omapdss_version version) -{ -	switch (version) { -	case OMAPDSS_VER_OMAP4430_ES1: -	case OMAPDSS_VER_OMAP4430_ES2: -	case OMAPDSS_VER_OMAP4: -		ip_data->ops = &omap4_hdmi_functions; -		break; -	default: -		ip_data->ops = NULL; -	} - -	WARN_ON(ip_data->ops == NULL); -} -#endif -  /* Functions returning values related to a DSS feature */  int dss_feat_get_num_mgrs(void)  { @@ -971,6 +992,10 @@ void dss_features_init(enum omapdss_version version)  		omap_current_dss_features = &am35xx_dss_features;  		break; +	case OMAPDSS_VER_AM43xx: +		omap_current_dss_features = &am43xx_dss_features; +		break; +  	default:  		DSSWARN("Unsupported OMAP version");  		break; diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/fbdev/omap2/dss/dss_features.h index 489b9bec4a6..e3ef3b71489 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/fbdev/omap2/dss/dss_features.h @@ -20,10 +20,6 @@  #ifndef __OMAP2_DSS_FEATURES_H  #define __OMAP2_DSS_FEATURES_H -#if defined(CONFIG_OMAP4_DSS_HDMI) -#include "ti_hdmi.h" -#endif -  #define MAX_DSS_MANAGERS	4  #define MAX_DSS_OVERLAYS	4  #define MAX_DSS_LCD_MANAGERS	3 @@ -68,6 +64,7 @@ enum dss_feat_id {  	FEAT_DSI_PLL_SELFREQDCO,  	FEAT_DSI_PLL_REFSEL,  	FEAT_DSI_PHY_DCC, +	FEAT_MFLAG,  };  /* DSS register field id */ @@ -117,8 +114,4 @@ bool dss_feat_rotation_type_supported(enum omap_dss_rotation_type rot_type);  bool dss_has_feature(enum dss_feat_id id);  void dss_feat_get_reg_field(enum dss_feat_reg_field id, u8 *start, u8 *end);  void dss_features_init(enum omapdss_version version); -#if defined(CONFIG_OMAP4_DSS_HDMI) -void dss_init_hdmi_ip_ops(struct hdmi_ip_data *ip_data, -		enum omapdss_version version); -#endif  #endif diff --git a/drivers/video/fbdev/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h new file mode 100644 index 00000000000..fbee0781633 --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/hdmi.h @@ -0,0 +1,447 @@ +/* + * HDMI driver definition for TI OMAP4 Processor. + * + * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _HDMI_H +#define _HDMI_H + +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <video/omapdss.h> + +#include "dss.h" + +/* HDMI Wrapper */ + +#define HDMI_WP_REVISION			0x0 +#define HDMI_WP_SYSCONFIG			0x10 +#define HDMI_WP_IRQSTATUS_RAW			0x24 +#define HDMI_WP_IRQSTATUS			0x28 +#define HDMI_WP_IRQENABLE_SET			0x2C +#define HDMI_WP_IRQENABLE_CLR			0x30 +#define HDMI_WP_IRQWAKEEN			0x34 +#define HDMI_WP_PWR_CTRL			0x40 +#define HDMI_WP_DEBOUNCE			0x44 +#define HDMI_WP_VIDEO_CFG			0x50 +#define HDMI_WP_VIDEO_SIZE			0x60 +#define HDMI_WP_VIDEO_TIMING_H			0x68 +#define HDMI_WP_VIDEO_TIMING_V			0x6C +#define HDMI_WP_CLK				0x70 +#define HDMI_WP_AUDIO_CFG			0x80 +#define HDMI_WP_AUDIO_CFG2			0x84 +#define HDMI_WP_AUDIO_CTRL			0x88 +#define HDMI_WP_AUDIO_DATA			0x8C + +/* HDMI WP IRQ flags */ +#define HDMI_IRQ_CORE				(1 << 0) +#define HDMI_IRQ_OCP_TIMEOUT			(1 << 4) +#define HDMI_IRQ_AUDIO_FIFO_UNDERFLOW		(1 << 8) +#define HDMI_IRQ_AUDIO_FIFO_OVERFLOW		(1 << 9) +#define HDMI_IRQ_AUDIO_FIFO_SAMPLE_REQ		(1 << 10) +#define HDMI_IRQ_VIDEO_VSYNC			(1 << 16) +#define HDMI_IRQ_VIDEO_FRAME_DONE		(1 << 17) +#define HDMI_IRQ_PHY_LINE5V_ASSERT		(1 << 24) +#define HDMI_IRQ_LINK_CONNECT			(1 << 25) +#define HDMI_IRQ_LINK_DISCONNECT		(1 << 26) +#define HDMI_IRQ_PLL_LOCK			(1 << 29) +#define HDMI_IRQ_PLL_UNLOCK			(1 << 30) +#define HDMI_IRQ_PLL_RECAL			(1 << 31) + +/* HDMI PLL */ + +#define PLLCTRL_PLL_CONTROL			0x0 +#define PLLCTRL_PLL_STATUS			0x4 +#define PLLCTRL_PLL_GO				0x8 +#define PLLCTRL_CFG1				0xC +#define PLLCTRL_CFG2				0x10 +#define PLLCTRL_CFG3				0x14 +#define PLLCTRL_SSC_CFG1			0x18 +#define PLLCTRL_SSC_CFG2			0x1C +#define PLLCTRL_CFG4				0x20 + +/* HDMI PHY */ + +#define HDMI_TXPHY_TX_CTRL			0x0 +#define HDMI_TXPHY_DIGITAL_CTRL			0x4 +#define HDMI_TXPHY_POWER_CTRL			0x8 +#define HDMI_TXPHY_PAD_CFG_CTRL			0xC +#define HDMI_TXPHY_BIST_CONTROL			0x1C + +enum hdmi_pll_pwr { +	HDMI_PLLPWRCMD_ALLOFF = 0, +	HDMI_PLLPWRCMD_PLLONLY = 1, +	HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2, +	HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3 +}; + +enum hdmi_phy_pwr { +	HDMI_PHYPWRCMD_OFF = 0, +	HDMI_PHYPWRCMD_LDOON = 1, +	HDMI_PHYPWRCMD_TXON = 2 +}; + +enum hdmi_core_hdmi_dvi { +	HDMI_DVI = 0, +	HDMI_HDMI = 1 +}; + +enum hdmi_clk_refsel { +	HDMI_REFSEL_PCLK = 0, +	HDMI_REFSEL_REF1 = 1, +	HDMI_REFSEL_REF2 = 2, +	HDMI_REFSEL_SYSCLK = 3 +}; + +enum hdmi_packing_mode { +	HDMI_PACK_10b_RGB_YUV444 = 0, +	HDMI_PACK_24b_RGB_YUV444_YUV422 = 1, +	HDMI_PACK_20b_YUV422 = 2, +	HDMI_PACK_ALREADYPACKED = 7 +}; + +enum hdmi_stereo_channels { +	HDMI_AUDIO_STEREO_NOCHANNELS = 0, +	HDMI_AUDIO_STEREO_ONECHANNEL = 1, +	HDMI_AUDIO_STEREO_TWOCHANNELS = 2, +	HDMI_AUDIO_STEREO_THREECHANNELS = 3, +	HDMI_AUDIO_STEREO_FOURCHANNELS = 4 +}; + +enum hdmi_audio_type { +	HDMI_AUDIO_TYPE_LPCM = 0, +	HDMI_AUDIO_TYPE_IEC = 1 +}; + +enum hdmi_audio_justify { +	HDMI_AUDIO_JUSTIFY_LEFT = 0, +	HDMI_AUDIO_JUSTIFY_RIGHT = 1 +}; + +enum hdmi_audio_sample_order { +	HDMI_AUDIO_SAMPLE_RIGHT_FIRST = 0, +	HDMI_AUDIO_SAMPLE_LEFT_FIRST = 1 +}; + +enum hdmi_audio_samples_perword { +	HDMI_AUDIO_ONEWORD_ONESAMPLE = 0, +	HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1 +}; + +enum hdmi_audio_sample_size { +	HDMI_AUDIO_SAMPLE_16BITS = 0, +	HDMI_AUDIO_SAMPLE_24BITS = 1 +}; + +enum hdmi_audio_transf_mode { +	HDMI_AUDIO_TRANSF_DMA = 0, +	HDMI_AUDIO_TRANSF_IRQ = 1 +}; + +enum hdmi_audio_blk_strt_end_sig { +	HDMI_AUDIO_BLOCK_SIG_STARTEND_ON = 0, +	HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF = 1 +}; + +enum hdmi_core_audio_layout { +	HDMI_AUDIO_LAYOUT_2CH = 0, +	HDMI_AUDIO_LAYOUT_8CH = 1 +}; + +enum hdmi_core_cts_mode { +	HDMI_AUDIO_CTS_MODE_HW = 0, +	HDMI_AUDIO_CTS_MODE_SW = 1 +}; + +enum hdmi_audio_mclk_mode { +	HDMI_AUDIO_MCLK_128FS = 0, +	HDMI_AUDIO_MCLK_256FS = 1, +	HDMI_AUDIO_MCLK_384FS = 2, +	HDMI_AUDIO_MCLK_512FS = 3, +	HDMI_AUDIO_MCLK_768FS = 4, +	HDMI_AUDIO_MCLK_1024FS = 5, +	HDMI_AUDIO_MCLK_1152FS = 6, +	HDMI_AUDIO_MCLK_192FS = 7 +}; + +/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */ +enum hdmi_core_infoframe { +	HDMI_INFOFRAME_AVI_DB1Y_RGB = 0, +	HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1, +	HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2, +	HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0, +	HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON =  1, +	HDMI_INFOFRAME_AVI_DB1B_NO = 0, +	HDMI_INFOFRAME_AVI_DB1B_VERT = 1, +	HDMI_INFOFRAME_AVI_DB1B_HORI = 2, +	HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3, +	HDMI_INFOFRAME_AVI_DB1S_0 = 0, +	HDMI_INFOFRAME_AVI_DB1S_1 = 1, +	HDMI_INFOFRAME_AVI_DB1S_2 = 2, +	HDMI_INFOFRAME_AVI_DB2C_NO = 0, +	HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1, +	HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2, +	HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3, +	HDMI_INFOFRAME_AVI_DB2M_NO = 0, +	HDMI_INFOFRAME_AVI_DB2M_43 = 1, +	HDMI_INFOFRAME_AVI_DB2M_169 = 2, +	HDMI_INFOFRAME_AVI_DB2R_SAME = 8, +	HDMI_INFOFRAME_AVI_DB2R_43 = 9, +	HDMI_INFOFRAME_AVI_DB2R_169 = 10, +	HDMI_INFOFRAME_AVI_DB2R_149 = 11, +	HDMI_INFOFRAME_AVI_DB3ITC_NO = 0, +	HDMI_INFOFRAME_AVI_DB3ITC_YES = 1, +	HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0, +	HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1, +	HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0, +	HDMI_INFOFRAME_AVI_DB3Q_LR = 1, +	HDMI_INFOFRAME_AVI_DB3Q_FR = 2, +	HDMI_INFOFRAME_AVI_DB3SC_NO = 0, +	HDMI_INFOFRAME_AVI_DB3SC_HORI = 1, +	HDMI_INFOFRAME_AVI_DB3SC_VERT = 2, +	HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3, +	HDMI_INFOFRAME_AVI_DB5PR_NO = 0, +	HDMI_INFOFRAME_AVI_DB5PR_2 = 1, +	HDMI_INFOFRAME_AVI_DB5PR_3 = 2, +	HDMI_INFOFRAME_AVI_DB5PR_4 = 3, +	HDMI_INFOFRAME_AVI_DB5PR_5 = 4, +	HDMI_INFOFRAME_AVI_DB5PR_6 = 5, +	HDMI_INFOFRAME_AVI_DB5PR_7 = 6, +	HDMI_INFOFRAME_AVI_DB5PR_8 = 7, +	HDMI_INFOFRAME_AVI_DB5PR_9 = 8, +	HDMI_INFOFRAME_AVI_DB5PR_10 = 9, +}; + +struct hdmi_cm { +	int	code; +	int	mode; +}; + +struct hdmi_video_format { +	enum hdmi_packing_mode	packing_mode; +	u32			y_res;	/* Line per panel */ +	u32			x_res;	/* pixel per line */ +}; + +struct hdmi_config { +	struct omap_video_timings timings; +	struct hdmi_cm cm; +}; + +/* HDMI PLL structure */ +struct hdmi_pll_info { +	u16 regn; +	u16 regm; +	u32 regmf; +	u16 regm2; +	u16 regsd; +	u16 dcofreq; +	enum hdmi_clk_refsel refsel; +}; + +struct hdmi_audio_format { +	enum hdmi_stereo_channels		stereo_channels; +	u8					active_chnnls_msk; +	enum hdmi_audio_type			type; +	enum hdmi_audio_justify			justification; +	enum hdmi_audio_sample_order		sample_order; +	enum hdmi_audio_samples_perword		samples_per_word; +	enum hdmi_audio_sample_size		sample_size; +	enum hdmi_audio_blk_strt_end_sig	en_sig_blk_strt_end; +}; + +struct hdmi_audio_dma { +	u8				transfer_size; +	u8				block_size; +	enum hdmi_audio_transf_mode	mode; +	u16				fifo_threshold; +}; + +struct hdmi_core_audio_i2s_config { +	u8 in_length_bits; +	u8 justification; +	u8 sck_edge_mode; +	u8 vbit; +	u8 direction; +	u8 shift; +	u8 active_sds; +}; + +struct hdmi_core_audio_config { +	struct hdmi_core_audio_i2s_config	i2s_cfg; +	struct snd_aes_iec958			*iec60958_cfg; +	bool					fs_override; +	u32					n; +	u32					cts; +	u32					aud_par_busclk; +	enum hdmi_core_audio_layout		layout; +	enum hdmi_core_cts_mode			cts_mode; +	bool					use_mclk; +	enum hdmi_audio_mclk_mode		mclk_mode; +	bool					en_acr_pkt; +	bool					en_dsd_audio; +	bool					en_parallel_aud_input; +	bool					en_spdif; +}; + +/* + * Refer to section 8.2 in HDMI 1.3 specification for + * details about infoframe databytes + */ +struct hdmi_core_infoframe_avi { +	/* Y0, Y1 rgb,yCbCr */ +	u8	db1_format; +	/* A0  Active information Present */ +	u8	db1_active_info; +	/* B0, B1 Bar info data valid */ +	u8	db1_bar_info_dv; +	/* S0, S1 scan information */ +	u8	db1_scan_info; +	/* C0, C1 colorimetry */ +	u8	db2_colorimetry; +	/* M0, M1 Aspect ratio (4:3, 16:9) */ +	u8	db2_aspect_ratio; +	/* R0...R3 Active format aspect ratio */ +	u8	db2_active_fmt_ar; +	/* ITC IT content. */ +	u8	db3_itc; +	/* EC0, EC1, EC2 Extended colorimetry */ +	u8	db3_ec; +	/* Q1, Q0 Quantization range */ +	u8	db3_q_range; +	/* SC1, SC0 Non-uniform picture scaling */ +	u8	db3_nup_scaling; +	/* VIC0..6 Video format identification */ +	u8	db4_videocode; +	/* PR0..PR3 Pixel repetition factor */ +	u8	db5_pixel_repeat; +	/* Line number end of top bar */ +	u16	db6_7_line_eoftop; +	/* Line number start of bottom bar */ +	u16	db8_9_line_sofbottom; +	/* Pixel number end of left bar */ +	u16	db10_11_pixel_eofleft; +	/* Pixel number start of right bar */ +	u16	db12_13_pixel_sofright; +}; + +struct hdmi_wp_data { +	void __iomem *base; +}; + +struct hdmi_pll_data { +	void __iomem *base; + +	struct hdmi_pll_info info; +}; + +struct hdmi_phy_data { +	void __iomem *base; + +	u8 lane_function[4]; +	u8 lane_polarity[4]; +}; + +struct hdmi_core_data { +	void __iomem *base; + +	struct hdmi_core_infoframe_avi avi_cfg; +}; + +static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx, +		u32 val) +{ +	__raw_writel(val, base_addr + idx); +} + +static inline u32 hdmi_read_reg(void __iomem *base_addr, const u32 idx) +{ +	return __raw_readl(base_addr + idx); +} + +#define REG_FLD_MOD(base, idx, val, start, end) \ +	hdmi_write_reg(base, idx, FLD_MOD(hdmi_read_reg(base, idx),\ +							val, start, end)) +#define REG_GET(base, idx, start, end) \ +	FLD_GET(hdmi_read_reg(base, idx), start, end) + +static inline int hdmi_wait_for_bit_change(void __iomem *base_addr, +		const u32 idx, int b2, int b1, u32 val) +{ +	u32 t = 0, v; +	while (val != (v = REG_GET(base_addr, idx, b2, b1))) { +		if (t++ > 10000) +			return v; +		udelay(1); +	} +	return v; +} + +/* HDMI wrapper funcs */ +int hdmi_wp_video_start(struct hdmi_wp_data *wp); +void hdmi_wp_video_stop(struct hdmi_wp_data *wp); +void hdmi_wp_dump(struct hdmi_wp_data *wp, struct seq_file *s); +u32 hdmi_wp_get_irqstatus(struct hdmi_wp_data *wp); +void hdmi_wp_set_irqstatus(struct hdmi_wp_data *wp, u32 irqstatus); +void hdmi_wp_set_irqenable(struct hdmi_wp_data *wp, u32 mask); +void hdmi_wp_clear_irqenable(struct hdmi_wp_data *wp, u32 mask); +int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val); +int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val); +void hdmi_wp_video_config_format(struct hdmi_wp_data *wp, +		struct hdmi_video_format *video_fmt); +void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp, +		struct omap_video_timings *timings); +void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp, +		struct omap_video_timings *timings); +void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt, +		struct omap_video_timings *timings, struct hdmi_config *param); +int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp); + +/* HDMI PLL funcs */ +int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp); +void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp); +void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s); +void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy); +int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll); + +/* HDMI PHY funcs */ +int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg); +void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s); +int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy); +int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes); + +/* HDMI common funcs */ +const struct hdmi_config *hdmi_default_timing(void); +const struct hdmi_config *hdmi_get_timings(int mode, int code); +struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing); +int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep, +	struct hdmi_phy_data *phy); + +#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) || defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) +int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts); +int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable); +int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable); +void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp, +		struct hdmi_audio_format *aud_fmt); +void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp, +		struct hdmi_audio_dma *aud_dma); +static inline bool hdmi_mode_has_audio(int mode) +{ +	return mode == HDMI_HDMI ? true : false; +} +#endif +#endif diff --git a/drivers/video/fbdev/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c new file mode 100644 index 00000000000..626aad2bef4 --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/hdmi4.c @@ -0,0 +1,804 @@ +/* + * HDMI interface DSS driver for TI's OMAP4 family of SoCs. + * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ + * Authors: Yong Zhi + *	Mythri pk <mythripk@ti.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +#define DSS_SUBSYS_NAME "HDMI" + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/mutex.h> +#include <linux/delay.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/clk.h> +#include <linux/gpio.h> +#include <linux/regulator/consumer.h> +#include <video/omapdss.h> + +#include "hdmi4_core.h" +#include "dss.h" +#include "dss_features.h" + +static struct { +	struct mutex lock; +	struct platform_device *pdev; + +	struct hdmi_wp_data	wp; +	struct hdmi_pll_data	pll; +	struct hdmi_phy_data	phy; +	struct hdmi_core_data	core; + +	struct hdmi_config cfg; + +	struct clk *sys_clk; +	struct regulator *vdda_hdmi_dac_reg; + +	bool core_enabled; + +	struct omap_dss_device output; +} hdmi; + +static int hdmi_runtime_get(void) +{ +	int r; + +	DSSDBG("hdmi_runtime_get\n"); + +	r = pm_runtime_get_sync(&hdmi.pdev->dev); +	WARN_ON(r < 0); +	if (r < 0) +		return r; + +	return 0; +} + +static void hdmi_runtime_put(void) +{ +	int r; + +	DSSDBG("hdmi_runtime_put\n"); + +	r = pm_runtime_put_sync(&hdmi.pdev->dev); +	WARN_ON(r < 0 && r != -ENOSYS); +} + +static irqreturn_t hdmi_irq_handler(int irq, void *data) +{ +	struct hdmi_wp_data *wp = data; +	u32 irqstatus; + +	irqstatus = hdmi_wp_get_irqstatus(wp); +	hdmi_wp_set_irqstatus(wp, irqstatus); + +	if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && +			irqstatus & HDMI_IRQ_LINK_DISCONNECT) { +		/* +		 * If we get both connect and disconnect interrupts at the same +		 * time, turn off the PHY, clear interrupts, and restart, which +		 * raises connect interrupt if a cable is connected, or nothing +		 * if cable is not connected. +		 */ +		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); + +		hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT | +				HDMI_IRQ_LINK_DISCONNECT); + +		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); +	} else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { +		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON); +	} else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { +		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); +	} + +	return IRQ_HANDLED; +} + +static int hdmi_init_regulator(void) +{ +	int r; +	struct regulator *reg; + +	if (hdmi.vdda_hdmi_dac_reg != NULL) +		return 0; + +	reg = devm_regulator_get(&hdmi.pdev->dev, "vdda"); + +	if (IS_ERR(reg)) { +		if (PTR_ERR(reg) != -EPROBE_DEFER) +			DSSERR("can't get VDDA regulator\n"); +		return PTR_ERR(reg); +	} + +	if (regulator_can_change_voltage(reg)) { +		r = regulator_set_voltage(reg, 1800000, 1800000); +		if (r) { +			devm_regulator_put(reg); +			DSSWARN("can't set the regulator voltage\n"); +			return r; +		} +	} + +	hdmi.vdda_hdmi_dac_reg = reg; + +	return 0; +} + +static int hdmi_power_on_core(struct omap_dss_device *dssdev) +{ +	int r; + +	r = regulator_enable(hdmi.vdda_hdmi_dac_reg); +	if (r) +		return r; + +	r = hdmi_runtime_get(); +	if (r) +		goto err_runtime_get; + +	/* Make selection of HDMI in DSS */ +	dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); + +	hdmi.core_enabled = true; + +	return 0; + +err_runtime_get: +	regulator_disable(hdmi.vdda_hdmi_dac_reg); + +	return r; +} + +static void hdmi_power_off_core(struct omap_dss_device *dssdev) +{ +	hdmi.core_enabled = false; + +	hdmi_runtime_put(); +	regulator_disable(hdmi.vdda_hdmi_dac_reg); +} + +static int hdmi_power_on_full(struct omap_dss_device *dssdev) +{ +	int r; +	struct omap_video_timings *p; +	struct omap_overlay_manager *mgr = hdmi.output.manager; +	unsigned long phy; +	struct hdmi_wp_data *wp = &hdmi.wp; + +	r = hdmi_power_on_core(dssdev); +	if (r) +		return r; + +	/* disable and clear irqs */ +	hdmi_wp_clear_irqenable(wp, 0xffffffff); +	hdmi_wp_set_irqstatus(wp, 0xffffffff); + +	p = &hdmi.cfg.timings; + +	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); + +	/* the functions below use kHz pixel clock. TODO: change to Hz */ +	phy = p->pixelclock / 1000; + +	hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy); + +	/* config the PLL and PHY hdmi_set_pll_pwrfirst */ +	r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp); +	if (r) { +		DSSDBG("Failed to lock PLL\n"); +		goto err_pll_enable; +	} + +	r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg); +	if (r) { +		DSSDBG("Failed to configure PHY\n"); +		goto err_phy_cfg; +	} + +	r = hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); +	if (r) +		goto err_phy_pwr; + +	hdmi4_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); + +	/* bypass TV gamma table */ +	dispc_enable_gamma_table(0); + +	/* tv size */ +	dss_mgr_set_timings(mgr, p); + +	r = hdmi_wp_video_start(&hdmi.wp); +	if (r) +		goto err_vid_enable; + +	r = dss_mgr_enable(mgr); +	if (r) +		goto err_mgr_enable; + +	hdmi_wp_set_irqenable(wp, +		HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); + +	return 0; + +err_mgr_enable: +	hdmi_wp_video_stop(&hdmi.wp); +err_vid_enable: +err_phy_cfg: +	hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); +err_phy_pwr: +	hdmi_pll_disable(&hdmi.pll, &hdmi.wp); +err_pll_enable: +	hdmi_power_off_core(dssdev); +	return -EIO; +} + +static void hdmi_power_off_full(struct omap_dss_device *dssdev) +{ +	struct omap_overlay_manager *mgr = hdmi.output.manager; + +	hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); + +	dss_mgr_disable(mgr); + +	hdmi_wp_video_stop(&hdmi.wp); + +	hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); + +	hdmi_pll_disable(&hdmi.pll, &hdmi.wp); + +	hdmi_power_off_core(dssdev); +} + +static int hdmi_display_check_timing(struct omap_dss_device *dssdev, +					struct omap_video_timings *timings) +{ +	struct omap_dss_device *out = &hdmi.output; + +	if (!dispc_mgr_timings_ok(out->dispc_channel, timings)) +		return -EINVAL; + +	return 0; +} + +static void hdmi_display_set_timing(struct omap_dss_device *dssdev, +		struct omap_video_timings *timings) +{ +	struct hdmi_cm cm; +	const struct hdmi_config *t; + +	mutex_lock(&hdmi.lock); + +	cm = hdmi_get_code(timings); +	hdmi.cfg.cm = cm; + +	t = hdmi_get_timings(cm.mode, cm.code); +	if (t != NULL) { +		hdmi.cfg = *t; + +		dispc_set_tv_pclk(t->timings.pixelclock); +	} else { +		hdmi.cfg.timings = *timings; +		hdmi.cfg.cm.code = 0; +		hdmi.cfg.cm.mode = HDMI_DVI; + +		dispc_set_tv_pclk(timings->pixelclock); +	} + +	DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ? +			"DVI" : "HDMI", hdmi.cfg.cm.code); + +	mutex_unlock(&hdmi.lock); +} + +static void hdmi_display_get_timings(struct omap_dss_device *dssdev, +		struct omap_video_timings *timings) +{ +	const struct hdmi_config *cfg; +	struct hdmi_cm cm = hdmi.cfg.cm; + +	cfg = hdmi_get_timings(cm.mode, cm.code); +	if (cfg == NULL) +		cfg = hdmi_default_timing(); + +	memcpy(timings, &cfg->timings, sizeof(cfg->timings)); +} + +static void hdmi_dump_regs(struct seq_file *s) +{ +	mutex_lock(&hdmi.lock); + +	if (hdmi_runtime_get()) { +		mutex_unlock(&hdmi.lock); +		return; +	} + +	hdmi_wp_dump(&hdmi.wp, s); +	hdmi_pll_dump(&hdmi.pll, s); +	hdmi_phy_dump(&hdmi.phy, s); +	hdmi4_core_dump(&hdmi.core, s); + +	hdmi_runtime_put(); +	mutex_unlock(&hdmi.lock); +} + +static int read_edid(u8 *buf, int len) +{ +	int r; + +	mutex_lock(&hdmi.lock); + +	r = hdmi_runtime_get(); +	BUG_ON(r); + +	r = hdmi4_read_edid(&hdmi.core,  buf, len); + +	hdmi_runtime_put(); +	mutex_unlock(&hdmi.lock); + +	return r; +} + +static int hdmi_display_enable(struct omap_dss_device *dssdev) +{ +	struct omap_dss_device *out = &hdmi.output; +	int r = 0; + +	DSSDBG("ENTER hdmi_display_enable\n"); + +	mutex_lock(&hdmi.lock); + +	if (out == NULL || out->manager == NULL) { +		DSSERR("failed to enable display: no output/manager\n"); +		r = -ENODEV; +		goto err0; +	} + +	r = hdmi_power_on_full(dssdev); +	if (r) { +		DSSERR("failed to power on device\n"); +		goto err0; +	} + +	mutex_unlock(&hdmi.lock); +	return 0; + +err0: +	mutex_unlock(&hdmi.lock); +	return r; +} + +static void hdmi_display_disable(struct omap_dss_device *dssdev) +{ +	DSSDBG("Enter hdmi_display_disable\n"); + +	mutex_lock(&hdmi.lock); + +	hdmi_power_off_full(dssdev); + +	mutex_unlock(&hdmi.lock); +} + +static int hdmi_core_enable(struct omap_dss_device *dssdev) +{ +	int r = 0; + +	DSSDBG("ENTER omapdss_hdmi_core_enable\n"); + +	mutex_lock(&hdmi.lock); + +	r = hdmi_power_on_core(dssdev); +	if (r) { +		DSSERR("failed to power on device\n"); +		goto err0; +	} + +	mutex_unlock(&hdmi.lock); +	return 0; + +err0: +	mutex_unlock(&hdmi.lock); +	return r; +} + +static void hdmi_core_disable(struct omap_dss_device *dssdev) +{ +	DSSDBG("Enter omapdss_hdmi_core_disable\n"); + +	mutex_lock(&hdmi.lock); + +	hdmi_power_off_core(dssdev); + +	mutex_unlock(&hdmi.lock); +} + +static int hdmi_get_clocks(struct platform_device *pdev) +{ +	struct clk *clk; + +	clk = devm_clk_get(&pdev->dev, "sys_clk"); +	if (IS_ERR(clk)) { +		DSSERR("can't get sys_clk\n"); +		return PTR_ERR(clk); +	} + +	hdmi.sys_clk = clk; + +	return 0; +} + +static int hdmi_connect(struct omap_dss_device *dssdev, +		struct omap_dss_device *dst) +{ +	struct omap_overlay_manager *mgr; +	int r; + +	r = hdmi_init_regulator(); +	if (r) +		return r; + +	mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel); +	if (!mgr) +		return -ENODEV; + +	r = dss_mgr_connect(mgr, dssdev); +	if (r) +		return r; + +	r = omapdss_output_set_device(dssdev, dst); +	if (r) { +		DSSERR("failed to connect output to new device: %s\n", +				dst->name); +		dss_mgr_disconnect(mgr, dssdev); +		return r; +	} + +	return 0; +} + +static void hdmi_disconnect(struct omap_dss_device *dssdev, +		struct omap_dss_device *dst) +{ +	WARN_ON(dst != dssdev->dst); + +	if (dst != dssdev->dst) +		return; + +	omapdss_output_unset_device(dssdev); + +	if (dssdev->manager) +		dss_mgr_disconnect(dssdev->manager, dssdev); +} + +static int hdmi_read_edid(struct omap_dss_device *dssdev, +		u8 *edid, int len) +{ +	bool need_enable; +	int r; + +	need_enable = hdmi.core_enabled == false; + +	if (need_enable) { +		r = hdmi_core_enable(dssdev); +		if (r) +			return r; +	} + +	r = read_edid(edid, len); + +	if (need_enable) +		hdmi_core_disable(dssdev); + +	return r; +} + +#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) +static int hdmi_audio_enable(struct omap_dss_device *dssdev) +{ +	int r; + +	mutex_lock(&hdmi.lock); + +	if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { +		r = -EPERM; +		goto err; +	} + +	r = hdmi_wp_audio_enable(&hdmi.wp, true); +	if (r) +		goto err; + +	mutex_unlock(&hdmi.lock); +	return 0; + +err: +	mutex_unlock(&hdmi.lock); +	return r; +} + +static void hdmi_audio_disable(struct omap_dss_device *dssdev) +{ +	hdmi_wp_audio_enable(&hdmi.wp, false); +} + +static int hdmi_audio_start(struct omap_dss_device *dssdev) +{ +	return hdmi4_audio_start(&hdmi.core, &hdmi.wp); +} + +static void hdmi_audio_stop(struct omap_dss_device *dssdev) +{ +	hdmi4_audio_stop(&hdmi.core, &hdmi.wp); +} + +static bool hdmi_audio_supported(struct omap_dss_device *dssdev) +{ +	bool r; + +	mutex_lock(&hdmi.lock); + +	r = hdmi_mode_has_audio(hdmi.cfg.cm.mode); + +	mutex_unlock(&hdmi.lock); +	return r; +} + +static int hdmi_audio_config(struct omap_dss_device *dssdev, +		struct omap_dss_audio *audio) +{ +	int r; +	u32 pclk = hdmi.cfg.timings.pixelclock; + +	mutex_lock(&hdmi.lock); + +	if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { +		r = -EPERM; +		goto err; +	} + +	r = hdmi4_audio_config(&hdmi.core, &hdmi.wp, audio, pclk); +	if (r) +		goto err; + +	mutex_unlock(&hdmi.lock); +	return 0; + +err: +	mutex_unlock(&hdmi.lock); +	return r; +} +#else +static int hdmi_audio_enable(struct omap_dss_device *dssdev) +{ +	return -EPERM; +} + +static void hdmi_audio_disable(struct omap_dss_device *dssdev) +{ +} + +static int hdmi_audio_start(struct omap_dss_device *dssdev) +{ +	return -EPERM; +} + +static void hdmi_audio_stop(struct omap_dss_device *dssdev) +{ +} + +static bool hdmi_audio_supported(struct omap_dss_device *dssdev) +{ +	return false; +} + +static int hdmi_audio_config(struct omap_dss_device *dssdev, +		struct omap_dss_audio *audio) +{ +	return -EPERM; +} +#endif + +static const struct omapdss_hdmi_ops hdmi_ops = { +	.connect		= hdmi_connect, +	.disconnect		= hdmi_disconnect, + +	.enable			= hdmi_display_enable, +	.disable		= hdmi_display_disable, + +	.check_timings		= hdmi_display_check_timing, +	.set_timings		= hdmi_display_set_timing, +	.get_timings		= hdmi_display_get_timings, + +	.read_edid		= hdmi_read_edid, + +	.audio_enable		= hdmi_audio_enable, +	.audio_disable		= hdmi_audio_disable, +	.audio_start		= hdmi_audio_start, +	.audio_stop		= hdmi_audio_stop, +	.audio_supported	= hdmi_audio_supported, +	.audio_config		= hdmi_audio_config, +}; + +static void hdmi_init_output(struct platform_device *pdev) +{ +	struct omap_dss_device *out = &hdmi.output; + +	out->dev = &pdev->dev; +	out->id = OMAP_DSS_OUTPUT_HDMI; +	out->output_type = OMAP_DISPLAY_TYPE_HDMI; +	out->name = "hdmi.0"; +	out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; +	out->ops.hdmi = &hdmi_ops; +	out->owner = THIS_MODULE; + +	omapdss_register_output(out); +} + +static void __exit hdmi_uninit_output(struct platform_device *pdev) +{ +	struct omap_dss_device *out = &hdmi.output; + +	omapdss_unregister_output(out); +} + +static int hdmi_probe_of(struct platform_device *pdev) +{ +	struct device_node *node = pdev->dev.of_node; +	struct device_node *ep; +	int r; + +	ep = omapdss_of_get_first_endpoint(node); +	if (!ep) +		return 0; + +	r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy); +	if (r) +		goto err; + +	of_node_put(ep); +	return 0; + +err: +	of_node_put(ep); +	return r; +} + +/* HDMI HW IP initialisation */ +static int omapdss_hdmihw_probe(struct platform_device *pdev) +{ +	int r; +	int irq; + +	hdmi.pdev = pdev; + +	mutex_init(&hdmi.lock); + +	if (pdev->dev.of_node) { +		r = hdmi_probe_of(pdev); +		if (r) +			return r; +	} + +	r = hdmi_wp_init(pdev, &hdmi.wp); +	if (r) +		return r; + +	r = hdmi_pll_init(pdev, &hdmi.pll); +	if (r) +		return r; + +	r = hdmi_phy_init(pdev, &hdmi.phy); +	if (r) +		return r; + +	r = hdmi4_core_init(pdev, &hdmi.core); +	if (r) +		return r; + +	r = hdmi_get_clocks(pdev); +	if (r) { +		DSSERR("can't get clocks\n"); +		return r; +	} + +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) { +		DSSERR("platform_get_irq failed\n"); +		return -ENODEV; +	} + +	r = devm_request_threaded_irq(&pdev->dev, irq, +			NULL, hdmi_irq_handler, +			IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); +	if (r) { +		DSSERR("HDMI IRQ request failed\n"); +		return r; +	} + +	pm_runtime_enable(&pdev->dev); + +	hdmi_init_output(pdev); + +	dss_debugfs_create_file("hdmi", hdmi_dump_regs); + +	return 0; +} + +static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) +{ +	hdmi_uninit_output(pdev); + +	pm_runtime_disable(&pdev->dev); + +	return 0; +} + +static int hdmi_runtime_suspend(struct device *dev) +{ +	clk_disable_unprepare(hdmi.sys_clk); + +	dispc_runtime_put(); + +	return 0; +} + +static int hdmi_runtime_resume(struct device *dev) +{ +	int r; + +	r = dispc_runtime_get(); +	if (r < 0) +		return r; + +	clk_prepare_enable(hdmi.sys_clk); + +	return 0; +} + +static const struct dev_pm_ops hdmi_pm_ops = { +	.runtime_suspend = hdmi_runtime_suspend, +	.runtime_resume = hdmi_runtime_resume, +}; + +static const struct of_device_id hdmi_of_match[] = { +	{ .compatible = "ti,omap4-hdmi", }, +	{}, +}; + +static struct platform_driver omapdss_hdmihw_driver = { +	.probe		= omapdss_hdmihw_probe, +	.remove         = __exit_p(omapdss_hdmihw_remove), +	.driver         = { +		.name   = "omapdss_hdmi", +		.owner  = THIS_MODULE, +		.pm	= &hdmi_pm_ops, +		.of_match_table = hdmi_of_match, +	}, +}; + +int __init hdmi4_init_platform_driver(void) +{ +	return platform_driver_register(&omapdss_hdmihw_driver); +} + +void __exit hdmi4_uninit_platform_driver(void) +{ +	platform_driver_unregister(&omapdss_hdmihw_driver); +} diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/fbdev/omap2/dss/hdmi4_core.c index 3dfe00956a4..8bde7b7e95f 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.c @@ -19,6 +19,8 @@   * this program.  If not, see <http://www.gnu.org/licenses/>.   */ +#define DSS_SUBSYS_NAME "HDMICORE" +  #include <linux/kernel.h>  #include <linux/module.h>  #include <linux/err.h> @@ -26,6 +28,7 @@  #include <linux/interrupt.h>  #include <linux/mutex.h>  #include <linux/delay.h> +#include <linux/platform_device.h>  #include <linux/string.h>  #include <linux/seq_file.h>  #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) @@ -33,304 +36,19 @@  #include <sound/asoundef.h>  #endif -#include "ti_hdmi_4xxx_ip.h" -#include "dss.h" +#include "hdmi4_core.h"  #include "dss_features.h" -#define HDMI_IRQ_LINK_CONNECT		(1 << 25) -#define HDMI_IRQ_LINK_DISCONNECT	(1 << 26) - -static inline void hdmi_write_reg(void __iomem *base_addr, -				const u16 idx, u32 val) -{ -	__raw_writel(val, base_addr + idx); -} - -static inline u32 hdmi_read_reg(void __iomem *base_addr, -				const u16 idx) -{ -	return __raw_readl(base_addr + idx); -} - -static inline void __iomem *hdmi_wp_base(struct hdmi_ip_data *ip_data) -{ -	return ip_data->base_wp; -} - -static inline void __iomem *hdmi_phy_base(struct hdmi_ip_data *ip_data) -{ -	return ip_data->base_wp + ip_data->phy_offset; -} - -static inline void __iomem *hdmi_pll_base(struct hdmi_ip_data *ip_data) -{ -	return ip_data->base_wp + ip_data->pll_offset; -} +#define HDMI_CORE_AV		0x500 -static inline void __iomem *hdmi_av_base(struct hdmi_ip_data *ip_data) +static inline void __iomem *hdmi_av_base(struct hdmi_core_data *core)  { -	return ip_data->base_wp + ip_data->core_av_offset; +	return core->base + HDMI_CORE_AV;  } -static inline void __iomem *hdmi_core_sys_base(struct hdmi_ip_data *ip_data) +static int hdmi_core_ddc_init(struct hdmi_core_data *core)  { -	return ip_data->base_wp + ip_data->core_sys_offset; -} - -static inline int hdmi_wait_for_bit_change(void __iomem *base_addr, -				const u16 idx, -				int b2, int b1, u32 val) -{ -	u32 t = 0; -	while (val != REG_GET(base_addr, idx, b2, b1)) { -		udelay(1); -		if (t++ > 10000) -			return !val; -	} -	return val; -} - -static int hdmi_pll_init(struct hdmi_ip_data *ip_data) -{ -	u32 r; -	void __iomem *pll_base = hdmi_pll_base(ip_data); -	struct hdmi_pll_info *fmt = &ip_data->pll_data; - -	/* PLL start always use manual mode */ -	REG_FLD_MOD(pll_base, PLLCTRL_PLL_CONTROL, 0x0, 0, 0); - -	r = hdmi_read_reg(pll_base, PLLCTRL_CFG1); -	r = FLD_MOD(r, fmt->regm, 20, 9); /* CFG1_PLL_REGM */ -	r = FLD_MOD(r, fmt->regn - 1, 8, 1);  /* CFG1_PLL_REGN */ - -	hdmi_write_reg(pll_base, PLLCTRL_CFG1, r); - -	r = hdmi_read_reg(pll_base, PLLCTRL_CFG2); - -	r = FLD_MOD(r, 0x0, 12, 12); /* PLL_HIGHFREQ divide by 2 */ -	r = FLD_MOD(r, 0x1, 13, 13); /* PLL_REFEN */ -	r = FLD_MOD(r, 0x0, 14, 14); /* PHY_CLKINEN de-assert during locking */ -	r = FLD_MOD(r, fmt->refsel, 22, 21); /* REFSEL */ - -	if (fmt->dcofreq) { -		/* divider programming for frequency beyond 1000Mhz */ -		REG_FLD_MOD(pll_base, PLLCTRL_CFG3, fmt->regsd, 17, 10); -		r = FLD_MOD(r, 0x4, 3, 1); /* 1000MHz and 2000MHz */ -	} else { -		r = FLD_MOD(r, 0x2, 3, 1); /* 500MHz and 1000MHz */ -	} - -	hdmi_write_reg(pll_base, PLLCTRL_CFG2, r); - -	r = hdmi_read_reg(pll_base, PLLCTRL_CFG4); -	r = FLD_MOD(r, fmt->regm2, 24, 18); -	r = FLD_MOD(r, fmt->regmf, 17, 0); - -	hdmi_write_reg(pll_base, PLLCTRL_CFG4, r); - -	/* go now */ -	REG_FLD_MOD(pll_base, PLLCTRL_PLL_GO, 0x1, 0, 0); - -	/* wait for bit change */ -	if (hdmi_wait_for_bit_change(pll_base, PLLCTRL_PLL_GO, -							0, 0, 1) != 1) { -		pr_err("PLL GO bit not set\n"); -		return -ETIMEDOUT; -	} - -	/* Wait till the lock bit is set in PLL status */ -	if (hdmi_wait_for_bit_change(pll_base, -				PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) { -		pr_err("cannot lock PLL\n"); -		pr_err("CFG1 0x%x\n", -			hdmi_read_reg(pll_base, PLLCTRL_CFG1)); -		pr_err("CFG2 0x%x\n", -			hdmi_read_reg(pll_base, PLLCTRL_CFG2)); -		pr_err("CFG4 0x%x\n", -			hdmi_read_reg(pll_base, PLLCTRL_CFG4)); -		return -ETIMEDOUT; -	} - -	pr_debug("PLL locked!\n"); - -	return 0; -} - -/* PHY_PWR_CMD */ -static int hdmi_set_phy_pwr(struct hdmi_ip_data *ip_data, enum hdmi_phy_pwr val) -{ -	/* Return if already the state */ -	if (REG_GET(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, 5, 4) == val) -		return 0; - -	/* Command for power control of HDMI PHY */ -	REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 7, 6); - -	/* Status of the power control of HDMI PHY */ -	if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data), -				HDMI_WP_PWR_CTRL, 5, 4, val) != val) { -		pr_err("Failed to set PHY power mode to %d\n", val); -		return -ETIMEDOUT; -	} - -	return 0; -} - -/* PLL_PWR_CMD */ -static int hdmi_set_pll_pwr(struct hdmi_ip_data *ip_data, enum hdmi_pll_pwr val) -{ -	/* Command for power control of HDMI PLL */ -	REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, val, 3, 2); - -	/* wait till PHY_PWR_STATUS is set */ -	if (hdmi_wait_for_bit_change(hdmi_wp_base(ip_data), HDMI_WP_PWR_CTRL, -						1, 0, val) != val) { -		pr_err("Failed to set PLL_PWR_STATUS\n"); -		return -ETIMEDOUT; -	} - -	return 0; -} - -static int hdmi_pll_reset(struct hdmi_ip_data *ip_data) -{ -	/* SYSRESET  controlled by power FSM */ -	REG_FLD_MOD(hdmi_pll_base(ip_data), PLLCTRL_PLL_CONTROL, 0x0, 3, 3); - -	/* READ 0x0 reset is in progress */ -	if (hdmi_wait_for_bit_change(hdmi_pll_base(ip_data), -				PLLCTRL_PLL_STATUS, 0, 0, 1) != 1) { -		pr_err("Failed to sysreset PLL\n"); -		return -ETIMEDOUT; -	} - -	return 0; -} - -int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data) -{ -	u16 r = 0; - -	r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF); -	if (r) -		return r; - -	r = hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); -	if (r) -		return r; - -	r = hdmi_pll_reset(ip_data); -	if (r) -		return r; - -	r = hdmi_pll_init(ip_data); -	if (r) -		return r; - -	return 0; -} - -void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data) -{ -	hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF); -} - -static irqreturn_t hdmi_irq_handler(int irq, void *data) -{ -	struct hdmi_ip_data *ip_data = data; -	void __iomem *wp_base = hdmi_wp_base(ip_data); -	u32 irqstatus; - -	irqstatus = hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS); -	hdmi_write_reg(wp_base, HDMI_WP_IRQSTATUS, irqstatus); -	/* flush posted write */ -	hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS); - -	if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && -			irqstatus & HDMI_IRQ_LINK_DISCONNECT) { -		/* -		 * If we get both connect and disconnect interrupts at the same -		 * time, turn off the PHY, clear interrupts, and restart, which -		 * raises connect interrupt if a cable is connected, or nothing -		 * if cable is not connected. -		 */ -		hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); - -		hdmi_write_reg(wp_base, HDMI_WP_IRQSTATUS, -			HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); -		/* flush posted write */ -		hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS); - -		hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON); -	} else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { -		hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON); -	} else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { -		hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON); -	} - -	return IRQ_HANDLED; -} - -int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data) -{ -	u16 r = 0; -	void __iomem *phy_base = hdmi_phy_base(ip_data); - -	hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQENABLE_CLR, -			0xffffffff); - -	hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQSTATUS, -			HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); - -	r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON); -	if (r) -		return r; - -	/* -	 * Read address 0 in order to get the SCP reset done completed -	 * Dummy access performed to make sure reset is done -	 */ -	hdmi_read_reg(phy_base, HDMI_TXPHY_TX_CTRL); - -	/* -	 * Write to phy address 0 to configure the clock -	 * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field -	 */ -	REG_FLD_MOD(phy_base, HDMI_TXPHY_TX_CTRL, 0x1, 31, 30); - -	/* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */ -	hdmi_write_reg(phy_base, HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000); - -	/* Setup max LDO voltage */ -	REG_FLD_MOD(phy_base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0); - -	/* Write to phy address 3 to change the polarity control */ -	REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27); - -	r = request_threaded_irq(ip_data->irq, NULL, hdmi_irq_handler, -				 IRQF_ONESHOT, "OMAP HDMI", ip_data); -	if (r) { -		DSSERR("HDMI IRQ request failed\n"); -		hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); -		return r; -	} - -	hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQENABLE_SET, -			HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); - -	return 0; -} - -void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data) -{ -	free_irq(ip_data->irq, ip_data); - -	hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF); -} - -static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data) -{ -	void __iomem *base = hdmi_core_sys_base(ip_data); +	void __iomem *base = core->base;  	/* Turn on CLK for DDC */  	REG_FLD_MOD(base, HDMI_CORE_AV_DPD, 0x7, 2, 0); @@ -370,10 +88,10 @@ static int hdmi_core_ddc_init(struct hdmi_ip_data *ip_data)  	return 0;  } -static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data, +static int hdmi_core_ddc_edid(struct hdmi_core_data *core,  		u8 *pedid, int ext)  { -	void __iomem *base = hdmi_core_sys_base(ip_data); +	void __iomem *base = core->base;  	u32 i;  	char checksum;  	u32 offset = 0; @@ -409,12 +127,12 @@ static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,  	/* HDMI_CORE_DDC_STATUS_BUS_LOW */  	if (REG_GET(base, HDMI_CORE_DDC_STATUS, 6, 6) == 1) { -		pr_err("I2C Bus Low?\n"); +		DSSERR("I2C Bus Low?\n");  		return -EIO;  	}  	/* HDMI_CORE_DDC_STATUS_NO_ACK */  	if (REG_GET(base, HDMI_CORE_DDC_STATUS, 5, 5) == 1) { -		pr_err("I2C No Ack\n"); +		DSSERR("I2C No Ack\n");  		return -EIO;  	} @@ -445,33 +163,32 @@ static int hdmi_core_ddc_edid(struct hdmi_ip_data *ip_data,  		checksum += pedid[i];  	if (checksum != 0) { -		pr_err("E-EDID checksum failed!!\n"); +		DSSERR("E-EDID checksum failed!!\n");  		return -EIO;  	}  	return 0;  } -int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, -				u8 *edid, int len) +int hdmi4_read_edid(struct hdmi_core_data *core, u8 *edid, int len)  {  	int r, l;  	if (len < 128)  		return -EINVAL; -	r = hdmi_core_ddc_init(ip_data); +	r = hdmi_core_ddc_init(core);  	if (r)  		return r; -	r = hdmi_core_ddc_edid(ip_data, edid, 0); +	r = hdmi_core_ddc_edid(core, edid, 0);  	if (r)  		return r;  	l = 128;  	if (len >= 128 * 2 && edid[0x7e] > 0) { -		r = hdmi_core_ddc_edid(ip_data, edid + 0x80, 1); +		r = hdmi_core_ddc_edid(core, edid + 0x80, 1);  		if (r)  			return r;  		l += 128; @@ -484,7 +201,7 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,  			struct hdmi_core_infoframe_avi *avi_cfg,  			struct hdmi_core_packet_enable_repeat *repeat_cfg)  { -	pr_debug("Enter hdmi_core_init\n"); +	DSSDBG("Enter hdmi_core_init\n");  	/* video core */  	video_cfg->ip_bus_width = HDMI_INPUT_8BIT; @@ -508,7 +225,7 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,  	avi_cfg->db3_nup_scaling = 0;  	avi_cfg->db4_videocode = 0;  	avi_cfg->db5_pixel_repeat = 0; -	avi_cfg->db6_7_line_eoftop = 0 ; +	avi_cfg->db6_7_line_eoftop = 0;  	avi_cfg->db8_9_line_sofbottom = 0;  	avi_cfg->db10_11_pixel_eofleft = 0;  	avi_cfg->db12_13_pixel_sofright = 0; @@ -524,38 +241,39 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,  	repeat_cfg->generic_pkt_repeat = 0;  } -static void hdmi_core_powerdown_disable(struct hdmi_ip_data *ip_data) +static void hdmi_core_powerdown_disable(struct hdmi_core_data *core)  { -	pr_debug("Enter hdmi_core_powerdown_disable\n"); -	REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_CTRL1, 0x0, 0, 0); +	DSSDBG("Enter hdmi_core_powerdown_disable\n"); +	REG_FLD_MOD(core->base, HDMI_CORE_SYS_SYS_CTRL1, 0x0, 0, 0);  } -static void hdmi_core_swreset_release(struct hdmi_ip_data *ip_data) +static void hdmi_core_swreset_release(struct hdmi_core_data *core)  { -	pr_debug("Enter hdmi_core_swreset_release\n"); -	REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_SRST, 0x0, 0, 0); +	DSSDBG("Enter hdmi_core_swreset_release\n"); +	REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x0, 0, 0);  } -static void hdmi_core_swreset_assert(struct hdmi_ip_data *ip_data) +static void hdmi_core_swreset_assert(struct hdmi_core_data *core)  { -	pr_debug("Enter hdmi_core_swreset_assert\n"); -	REG_FLD_MOD(hdmi_core_sys_base(ip_data), HDMI_CORE_SYS_SRST, 0x1, 0, 0); +	DSSDBG("Enter hdmi_core_swreset_assert\n"); +	REG_FLD_MOD(core->base, HDMI_CORE_SYS_SRST, 0x1, 0, 0);  }  /* HDMI_CORE_VIDEO_CONFIG */ -static void hdmi_core_video_config(struct hdmi_ip_data *ip_data, +static void hdmi_core_video_config(struct hdmi_core_data *core,  				struct hdmi_core_video_config *cfg)  {  	u32 r = 0; -	void __iomem *core_sys_base = hdmi_core_sys_base(ip_data); +	void __iomem *core_sys_base = core->base; +	void __iomem *core_av_base = hdmi_av_base(core);  	/* sys_ctrl1 default configuration not tunable */ -	r = hdmi_read_reg(core_sys_base, HDMI_CORE_CTRL1); -	r = FLD_MOD(r, HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC, 5, 5); -	r = FLD_MOD(r, HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC, 4, 4); -	r = FLD_MOD(r, HDMI_CORE_CTRL1_BSEL_24BITBUS, 2, 2); -	r = FLD_MOD(r, HDMI_CORE_CTRL1_EDGE_RISINGEDGE, 1, 1); -	hdmi_write_reg(core_sys_base, HDMI_CORE_CTRL1, r); +	r = hdmi_read_reg(core_sys_base, HDMI_CORE_SYS_SYS_CTRL1); +	r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_VEN_FOLLOWVSYNC, 5, 5); +	r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_HEN_FOLLOWHSYNC, 4, 4); +	r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_BSEL_24BITBUS, 2, 2); +	r = FLD_MOD(r, HDMI_CORE_SYS_SYS_CTRL1_EDGE_RISINGEDGE, 1, 1); +	hdmi_write_reg(core_sys_base, HDMI_CORE_SYS_SYS_CTRL1, r);  	REG_FLD_MOD(core_sys_base,  			HDMI_CORE_SYS_VID_ACEN, cfg->ip_bus_width, 7, 6); @@ -574,23 +292,23 @@ static void hdmi_core_video_config(struct hdmi_ip_data *ip_data,  	hdmi_write_reg(core_sys_base, HDMI_CORE_SYS_VID_MODE, r);  	/* HDMI_Ctrl */ -	r = hdmi_read_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_HDMI_CTRL); +	r = hdmi_read_reg(core_av_base, HDMI_CORE_AV_HDMI_CTRL);  	r = FLD_MOD(r, cfg->deep_color_pkt, 6, 6);  	r = FLD_MOD(r, cfg->pkt_mode, 5, 3);  	r = FLD_MOD(r, cfg->hdmi_dvi, 0, 0); -	hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_HDMI_CTRL, r); +	hdmi_write_reg(core_av_base, HDMI_CORE_AV_HDMI_CTRL, r);  	/* TMDS_CTRL */  	REG_FLD_MOD(core_sys_base,  			HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5);  } -static void hdmi_core_aux_infoframe_avi_config(struct hdmi_ip_data *ip_data) +static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core)  {  	u32 val;  	char sum = 0, checksum = 0; -	void __iomem *av_base = hdmi_av_base(ip_data); -	struct hdmi_core_infoframe_avi info_avi = ip_data->avi_cfg; +	void __iomem *av_base = hdmi_av_base(core); +	struct hdmi_core_infoframe_avi info_avi = core->avi_cfg;  	sum += 0x82 + 0x002 + 0x00D;  	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082); @@ -661,160 +379,64 @@ static void hdmi_core_aux_infoframe_avi_config(struct hdmi_ip_data *ip_data)  	hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_CHSUM, checksum);  } -static void hdmi_core_av_packet_config(struct hdmi_ip_data *ip_data, +static void hdmi_core_av_packet_config(struct hdmi_core_data *core,  		struct hdmi_core_packet_enable_repeat repeat_cfg)  {  	/* enable/repeat the infoframe */ -	hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_PB_CTRL1, +	hdmi_write_reg(hdmi_av_base(core), HDMI_CORE_AV_PB_CTRL1,  		(repeat_cfg.audio_pkt << 5) |  		(repeat_cfg.audio_pkt_repeat << 4) |  		(repeat_cfg.avi_infoframe << 1) |  		(repeat_cfg.avi_infoframe_repeat));  	/* enable/repeat the packet */ -	hdmi_write_reg(hdmi_av_base(ip_data), HDMI_CORE_AV_PB_CTRL2, +	hdmi_write_reg(hdmi_av_base(core), HDMI_CORE_AV_PB_CTRL2,  		(repeat_cfg.gen_cntrl_pkt << 3) |  		(repeat_cfg.gen_cntrl_pkt_repeat << 2) |  		(repeat_cfg.generic_pkt << 1) |  		(repeat_cfg.generic_pkt_repeat));  } -static void hdmi_wp_init(struct omap_video_timings *timings, -			struct hdmi_video_format *video_fmt) -{ -	pr_debug("Enter hdmi_wp_init\n"); - -	timings->hbp = 0; -	timings->hfp = 0; -	timings->hsw = 0; -	timings->vbp = 0; -	timings->vfp = 0; -	timings->vsw = 0; - -	video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444; -	video_fmt->y_res = 0; -	video_fmt->x_res = 0; - -} - -int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data) -{ -	REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, true, 31, 31); -	return 0; -} - -void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data) -{ -	REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, false, 31, 31); -} - -static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt, -	struct omap_video_timings *timings, struct hdmi_config *param) -{ -	pr_debug("Enter hdmi_wp_video_init_format\n"); - -	video_fmt->y_res = param->timings.y_res; -	video_fmt->x_res = param->timings.x_res; - -	timings->hbp = param->timings.hbp; -	timings->hfp = param->timings.hfp; -	timings->hsw = param->timings.hsw; -	timings->vbp = param->timings.vbp; -	timings->vfp = param->timings.vfp; -	timings->vsw = param->timings.vsw; -} - -static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data, -		struct hdmi_video_format *video_fmt) -{ -	u32 l = 0; - -	REG_FLD_MOD(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, -			video_fmt->packing_mode, 10, 8); - -	l |= FLD_VAL(video_fmt->y_res, 31, 16); -	l |= FLD_VAL(video_fmt->x_res, 15, 0); -	hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l); -} - -static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data) -{ -	u32 r; -	bool vsync_pol, hsync_pol; -	pr_debug("Enter hdmi_wp_video_config_interface\n"); - -	vsync_pol = ip_data->cfg.timings.vsync_level == OMAPDSS_SIG_ACTIVE_HIGH; -	hsync_pol = ip_data->cfg.timings.hsync_level == OMAPDSS_SIG_ACTIVE_HIGH; - -	r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG); -	r = FLD_MOD(r, vsync_pol, 7, 7); -	r = FLD_MOD(r, hsync_pol, 6, 6); -	r = FLD_MOD(r, ip_data->cfg.timings.interlace, 3, 3); -	r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ -	hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r); -} - -static void hdmi_wp_video_config_timing(struct hdmi_ip_data *ip_data, -		struct omap_video_timings *timings) -{ -	u32 timing_h = 0; -	u32 timing_v = 0; - -	pr_debug("Enter hdmi_wp_video_config_timing\n"); - -	timing_h |= FLD_VAL(timings->hbp, 31, 20); -	timing_h |= FLD_VAL(timings->hfp, 19, 8); -	timing_h |= FLD_VAL(timings->hsw, 7, 0); -	hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_H, timing_h); - -	timing_v |= FLD_VAL(timings->vbp, 31, 20); -	timing_v |= FLD_VAL(timings->vfp, 19, 8); -	timing_v |= FLD_VAL(timings->vsw, 7, 0); -	hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_TIMING_V, timing_v); -} - -void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) +void hdmi4_configure(struct hdmi_core_data *core, +	struct hdmi_wp_data *wp, struct hdmi_config *cfg)  {  	/* HDMI */  	struct omap_video_timings video_timing;  	struct hdmi_video_format video_format;  	/* HDMI core */ -	struct hdmi_core_infoframe_avi *avi_cfg = &ip_data->avi_cfg; +	struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg;  	struct hdmi_core_video_config v_core_cfg;  	struct hdmi_core_packet_enable_repeat repeat_cfg; -	struct hdmi_config *cfg = &ip_data->cfg; - -	hdmi_wp_init(&video_timing, &video_format);  	hdmi_core_init(&v_core_cfg, avi_cfg, &repeat_cfg); -	hdmi_wp_video_init_format(&video_format, &video_timing, cfg); +	hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg); -	hdmi_wp_video_config_timing(ip_data, &video_timing); +	hdmi_wp_video_config_timing(wp, &video_timing);  	/* video config */  	video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422; -	hdmi_wp_video_config_format(ip_data, &video_format); +	hdmi_wp_video_config_format(wp, &video_format); -	hdmi_wp_video_config_interface(ip_data); +	hdmi_wp_video_config_interface(wp, &video_timing);  	/*  	 * configure core video part  	 * set software reset in the core  	 */ -	hdmi_core_swreset_assert(ip_data); +	hdmi_core_swreset_assert(core);  	/* power down off */ -	hdmi_core_powerdown_disable(ip_data); +	hdmi_core_powerdown_disable(core);  	v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;  	v_core_cfg.hdmi_dvi = cfg->cm.mode; -	hdmi_core_video_config(ip_data, &v_core_cfg); +	hdmi_core_video_config(core, &v_core_cfg);  	/* release software reset in the core */ -	hdmi_core_swreset_release(ip_data); +	hdmi_core_swreset_release(core);  	/*  	 * configure packet @@ -839,7 +461,7 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)  	avi_cfg->db10_11_pixel_eofleft = 0;  	avi_cfg->db12_13_pixel_sofright = 0; -	hdmi_core_aux_infoframe_avi_config(ip_data); +	hdmi_core_aux_infoframe_avi_config(core);  	/* enable/repeat the infoframe */  	repeat_cfg.avi_infoframe = HDMI_PACKETENABLE; @@ -847,65 +469,30 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data)  	/* wakeup */  	repeat_cfg.audio_pkt = HDMI_PACKETENABLE;  	repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON; -	hdmi_core_av_packet_config(ip_data, repeat_cfg); -} - -void ti_hdmi_4xxx_wp_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) -{ -#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r,\ -		hdmi_read_reg(hdmi_wp_base(ip_data), r)) - -	DUMPREG(HDMI_WP_REVISION); -	DUMPREG(HDMI_WP_SYSCONFIG); -	DUMPREG(HDMI_WP_IRQSTATUS_RAW); -	DUMPREG(HDMI_WP_IRQSTATUS); -	DUMPREG(HDMI_WP_PWR_CTRL); -	DUMPREG(HDMI_WP_IRQENABLE_SET); -	DUMPREG(HDMI_WP_VIDEO_CFG); -	DUMPREG(HDMI_WP_VIDEO_SIZE); -	DUMPREG(HDMI_WP_VIDEO_TIMING_H); -	DUMPREG(HDMI_WP_VIDEO_TIMING_V); -	DUMPREG(HDMI_WP_WP_CLK); -	DUMPREG(HDMI_WP_AUDIO_CFG); -	DUMPREG(HDMI_WP_AUDIO_CFG2); -	DUMPREG(HDMI_WP_AUDIO_CTRL); -	DUMPREG(HDMI_WP_AUDIO_DATA); +	hdmi_core_av_packet_config(core, repeat_cfg);  } -void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) -{ -#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\ -		hdmi_read_reg(hdmi_pll_base(ip_data), r)) - -	DUMPPLL(PLLCTRL_PLL_CONTROL); -	DUMPPLL(PLLCTRL_PLL_STATUS); -	DUMPPLL(PLLCTRL_PLL_GO); -	DUMPPLL(PLLCTRL_CFG1); -	DUMPPLL(PLLCTRL_CFG2); -	DUMPPLL(PLLCTRL_CFG3); -	DUMPPLL(PLLCTRL_CFG4); -} - -void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) +void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s)  {  	int i;  #define CORE_REG(i, name) name(i)  #define DUMPCORE(r) seq_printf(s, "%-35s %08x\n", #r,\ -		hdmi_read_reg(hdmi_core_sys_base(ip_data), r)) +		hdmi_read_reg(core->base, r))  #define DUMPCOREAV(r) seq_printf(s, "%-35s %08x\n", #r,\ -		hdmi_read_reg(hdmi_av_base(ip_data), r)) +		hdmi_read_reg(hdmi_av_base(core), r))  #define DUMPCOREAV2(i, r) seq_printf(s, "%s[%d]%*s %08x\n", #r, i, \  		(i < 10) ? 32 - (int)strlen(#r) : 31 - (int)strlen(#r), " ", \ -		hdmi_read_reg(hdmi_av_base(ip_data), CORE_REG(i, r))) +		hdmi_read_reg(hdmi_av_base(core), CORE_REG(i, r)))  	DUMPCORE(HDMI_CORE_SYS_VND_IDL);  	DUMPCORE(HDMI_CORE_SYS_DEV_IDL);  	DUMPCORE(HDMI_CORE_SYS_DEV_IDH);  	DUMPCORE(HDMI_CORE_SYS_DEV_REV);  	DUMPCORE(HDMI_CORE_SYS_SRST); -	DUMPCORE(HDMI_CORE_CTRL1); +	DUMPCORE(HDMI_CORE_SYS_SYS_CTRL1);  	DUMPCORE(HDMI_CORE_SYS_SYS_STAT); +	DUMPCORE(HDMI_CORE_SYS_SYS_CTRL3);  	DUMPCORE(HDMI_CORE_SYS_DE_DLY);  	DUMPCORE(HDMI_CORE_SYS_DE_CTRL);  	DUMPCORE(HDMI_CORE_SYS_DE_TOP); @@ -913,14 +500,58 @@ void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s)  	DUMPCORE(HDMI_CORE_SYS_DE_CNTH);  	DUMPCORE(HDMI_CORE_SYS_DE_LINL);  	DUMPCORE(HDMI_CORE_SYS_DE_LINH_1); +	DUMPCORE(HDMI_CORE_SYS_HRES_L); +	DUMPCORE(HDMI_CORE_SYS_HRES_H); +	DUMPCORE(HDMI_CORE_SYS_VRES_L); +	DUMPCORE(HDMI_CORE_SYS_VRES_H); +	DUMPCORE(HDMI_CORE_SYS_IADJUST); +	DUMPCORE(HDMI_CORE_SYS_POLDETECT); +	DUMPCORE(HDMI_CORE_SYS_HWIDTH1); +	DUMPCORE(HDMI_CORE_SYS_HWIDTH2); +	DUMPCORE(HDMI_CORE_SYS_VWIDTH); +	DUMPCORE(HDMI_CORE_SYS_VID_CTRL);  	DUMPCORE(HDMI_CORE_SYS_VID_ACEN);  	DUMPCORE(HDMI_CORE_SYS_VID_MODE); +	DUMPCORE(HDMI_CORE_SYS_VID_BLANK1); +	DUMPCORE(HDMI_CORE_SYS_VID_BLANK3); +	DUMPCORE(HDMI_CORE_SYS_VID_BLANK1); +	DUMPCORE(HDMI_CORE_SYS_DC_HEADER); +	DUMPCORE(HDMI_CORE_SYS_VID_DITHER); +	DUMPCORE(HDMI_CORE_SYS_RGB2XVYCC_CT); +	DUMPCORE(HDMI_CORE_SYS_R2Y_COEFF_LOW); +	DUMPCORE(HDMI_CORE_SYS_R2Y_COEFF_UP); +	DUMPCORE(HDMI_CORE_SYS_G2Y_COEFF_LOW); +	DUMPCORE(HDMI_CORE_SYS_G2Y_COEFF_UP); +	DUMPCORE(HDMI_CORE_SYS_B2Y_COEFF_LOW); +	DUMPCORE(HDMI_CORE_SYS_B2Y_COEFF_UP); +	DUMPCORE(HDMI_CORE_SYS_R2CB_COEFF_LOW); +	DUMPCORE(HDMI_CORE_SYS_R2CB_COEFF_UP); +	DUMPCORE(HDMI_CORE_SYS_G2CB_COEFF_LOW); +	DUMPCORE(HDMI_CORE_SYS_G2CB_COEFF_UP); +	DUMPCORE(HDMI_CORE_SYS_B2CB_COEFF_LOW); +	DUMPCORE(HDMI_CORE_SYS_B2CB_COEFF_UP); +	DUMPCORE(HDMI_CORE_SYS_R2CR_COEFF_LOW); +	DUMPCORE(HDMI_CORE_SYS_R2CR_COEFF_UP); +	DUMPCORE(HDMI_CORE_SYS_G2CR_COEFF_LOW); +	DUMPCORE(HDMI_CORE_SYS_G2CR_COEFF_UP); +	DUMPCORE(HDMI_CORE_SYS_B2CR_COEFF_LOW); +	DUMPCORE(HDMI_CORE_SYS_B2CR_COEFF_UP); +	DUMPCORE(HDMI_CORE_SYS_RGB_OFFSET_LOW); +	DUMPCORE(HDMI_CORE_SYS_RGB_OFFSET_UP); +	DUMPCORE(HDMI_CORE_SYS_Y_OFFSET_LOW); +	DUMPCORE(HDMI_CORE_SYS_Y_OFFSET_UP); +	DUMPCORE(HDMI_CORE_SYS_CBCR_OFFSET_LOW); +	DUMPCORE(HDMI_CORE_SYS_CBCR_OFFSET_UP);  	DUMPCORE(HDMI_CORE_SYS_INTR_STATE);  	DUMPCORE(HDMI_CORE_SYS_INTR1);  	DUMPCORE(HDMI_CORE_SYS_INTR2);  	DUMPCORE(HDMI_CORE_SYS_INTR3);  	DUMPCORE(HDMI_CORE_SYS_INTR4); -	DUMPCORE(HDMI_CORE_SYS_UMASK1); +	DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK1); +	DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK2); +	DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK3); +	DUMPCORE(HDMI_CORE_SYS_INTR_UNMASK4); +	DUMPCORE(HDMI_CORE_SYS_INTR_CTRL);  	DUMPCORE(HDMI_CORE_SYS_TMDS_CTRL);  	DUMPCORE(HDMI_CORE_DDC_ADDR); @@ -1009,60 +640,12 @@ void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s)  	DUMPCOREAV(HDMI_CORE_AV_CEC_ADDR_ID);  } -void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s) -{ -#define DUMPPHY(r) seq_printf(s, "%-35s %08x\n", #r,\ -		hdmi_read_reg(hdmi_phy_base(ip_data), r)) - -	DUMPPHY(HDMI_TXPHY_TX_CTRL); -	DUMPPHY(HDMI_TXPHY_DIGITAL_CTRL); -	DUMPPHY(HDMI_TXPHY_POWER_CTRL); -	DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL); -} -  #if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -static void ti_hdmi_4xxx_wp_audio_config_format(struct hdmi_ip_data *ip_data, -					struct hdmi_audio_format *aud_fmt) -{ -	u32 r; - -	DSSDBG("Enter hdmi_wp_audio_config_format\n"); - -	r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG); -	r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24); -	r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16); -	r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5); -	r = FLD_MOD(r, aud_fmt->type, 4, 4); -	r = FLD_MOD(r, aud_fmt->justification, 3, 3); -	r = FLD_MOD(r, aud_fmt->sample_order, 2, 2); -	r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1); -	r = FLD_MOD(r, aud_fmt->sample_size, 0, 0); -	hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG, r); -} - -static void ti_hdmi_4xxx_wp_audio_config_dma(struct hdmi_ip_data *ip_data, -					struct hdmi_audio_dma *aud_dma) -{ -	u32 r; - -	DSSDBG("Enter hdmi_wp_audio_config_dma\n"); - -	r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG2); -	r = FLD_MOD(r, aud_dma->transfer_size, 15, 8); -	r = FLD_MOD(r, aud_dma->block_size, 7, 0); -	hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CFG2, r); - -	r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL); -	r = FLD_MOD(r, aud_dma->mode, 9, 9); -	r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0); -	hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_AUDIO_CTRL, r); -} - -static void ti_hdmi_4xxx_core_audio_config(struct hdmi_ip_data *ip_data, +static void hdmi_core_audio_config(struct hdmi_core_data *core,  					struct hdmi_core_audio_config *cfg)  {  	u32 r; -	void __iomem *av_base = hdmi_av_base(ip_data); +	void __iomem *av_base = hdmi_av_base(core);  	/*  	 * Parameters for generation of Audio Clock Recovery packets @@ -1157,11 +740,11 @@ static void ti_hdmi_4xxx_core_audio_config(struct hdmi_ip_data *ip_data,  	REG_FLD_MOD(av_base, HDMI_CORE_AV_SWAP_I2S, 1, 5, 5);  } -static void ti_hdmi_4xxx_core_audio_infoframe_cfg(struct hdmi_ip_data *ip_data, +static void hdmi_core_audio_infoframe_cfg(struct hdmi_core_data *core,  		struct snd_cea_861_aud_if *info_aud)  {  	u8 sum = 0, checksum = 0; -	void __iomem *av_base = hdmi_av_base(ip_data); +	void __iomem *av_base = hdmi_av_base(core);  	/*  	 * Set audio info frame type, version and length as @@ -1207,20 +790,20 @@ static void ti_hdmi_4xxx_core_audio_infoframe_cfg(struct hdmi_ip_data *ip_data,  	 */  } -int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data, -		struct omap_dss_audio *audio) +int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, +		struct omap_dss_audio *audio, u32 pclk)  {  	struct hdmi_audio_format audio_format;  	struct hdmi_audio_dma audio_dma; -	struct hdmi_core_audio_config core; +	struct hdmi_core_audio_config acore;  	int err, n, cts, channel_count;  	unsigned int fs_nr;  	bool word_length_16b = false; -	if (!audio || !audio->iec || !audio->cea || !ip_data) +	if (!audio || !audio->iec || !audio->cea || !core)  		return -EINVAL; -	core.iec60958_cfg = audio->iec; +	acore.iec60958_cfg = audio->iec;  	/*  	 * In the IEC-60958 status word, check if the audio sample word length  	 * is 16-bit as several optimizations can be performed in such case. @@ -1231,22 +814,22 @@ int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data,  	/* I2S configuration. See Phillips' specification */  	if (word_length_16b) -		core.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT; +		acore.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_LEFT;  	else -		core.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT; +		acore.i2s_cfg.justification = HDMI_AUDIO_JUSTIFY_RIGHT;  	/*  	 * The I2S input word length is twice the lenght given in the IEC-60958  	 * status word. If the word size is greater than  	 * 20 bits, increment by one.  	 */ -	core.i2s_cfg.in_length_bits = audio->iec->status[4] +	acore.i2s_cfg.in_length_bits = audio->iec->status[4]  		& IEC958_AES4_CON_WORDLEN;  	if (audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24) -		core.i2s_cfg.in_length_bits++; -	core.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING; -	core.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM; -	core.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST; -	core.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT; +		acore.i2s_cfg.in_length_bits++; +	acore.i2s_cfg.sck_edge_mode = HDMI_AUDIO_I2S_SCK_EDGE_RISING; +	acore.i2s_cfg.vbit = HDMI_AUDIO_I2S_VBIT_FOR_PCM; +	acore.i2s_cfg.direction = HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST; +	acore.i2s_cfg.shift = HDMI_AUDIO_I2S_FIRST_BIT_SHIFT;  	/* convert sample frequency to a number */  	switch (audio->iec->status[3] & IEC958_AES3_CON_FS) { @@ -1275,23 +858,23 @@ int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data,  		return -EINVAL;  	} -	err = hdmi_compute_acr(fs_nr, &n, &cts); +	err = hdmi_compute_acr(pclk, fs_nr, &n, &cts);  	/* Audio clock regeneration settings */ -	core.n = n; -	core.cts = cts; +	acore.n = n; +	acore.cts = cts;  	if (dss_has_feature(FEAT_HDMI_CTS_SWMODE)) { -		core.aud_par_busclk = 0; -		core.cts_mode = HDMI_AUDIO_CTS_MODE_SW; -		core.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK); +		acore.aud_par_busclk = 0; +		acore.cts_mode = HDMI_AUDIO_CTS_MODE_SW; +		acore.use_mclk = dss_has_feature(FEAT_HDMI_AUDIO_USE_MCLK);  	} else { -		core.aud_par_busclk = (((128 * 31) - 1) << 8); -		core.cts_mode = HDMI_AUDIO_CTS_MODE_HW; -		core.use_mclk = true; +		acore.aud_par_busclk = (((128 * 31) - 1) << 8); +		acore.cts_mode = HDMI_AUDIO_CTS_MODE_HW; +		acore.use_mclk = true;  	} -	if (core.use_mclk) -		core.mclk_mode = HDMI_AUDIO_MCLK_128FS; +	if (acore.use_mclk) +		acore.mclk_mode = HDMI_AUDIO_MCLK_128FS;  	/* Audio channels settings */  	channel_count = (audio->cea->db1_ct_cc & @@ -1329,25 +912,25 @@ int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data,  	 */  	if (channel_count == 2) {  		audio_format.stereo_channels = HDMI_AUDIO_STEREO_ONECHANNEL; -		core.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN; -		core.layout = HDMI_AUDIO_LAYOUT_2CH; +		acore.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN; +		acore.layout = HDMI_AUDIO_LAYOUT_2CH;  	} else {  		audio_format.stereo_channels = HDMI_AUDIO_STEREO_FOURCHANNELS; -		core.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN | +		acore.i2s_cfg.active_sds = HDMI_AUDIO_I2S_SD0_EN |  				HDMI_AUDIO_I2S_SD1_EN | HDMI_AUDIO_I2S_SD2_EN |  				HDMI_AUDIO_I2S_SD3_EN; -		core.layout = HDMI_AUDIO_LAYOUT_8CH; +		acore.layout = HDMI_AUDIO_LAYOUT_8CH;  	} -	core.en_spdif = false; +	acore.en_spdif = false;  	/* use sample frequency from channel status word */ -	core.fs_override = true; +	acore.fs_override = true;  	/* enable ACR packets */ -	core.en_acr_pkt = true; +	acore.en_acr_pkt = true;  	/* disable direct streaming digital audio */ -	core.en_dsd_audio = false; +	acore.en_dsd_audio = false;  	/* use parallel audio interface */ -	core.en_parallel_aud_input = true; +	acore.en_parallel_aud_input = true;  	/* DMA settings */  	if (word_length_16b) @@ -1374,49 +957,37 @@ int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data,  	audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON;  	/* configure DMA and audio FIFO format*/ -	ti_hdmi_4xxx_wp_audio_config_dma(ip_data, &audio_dma); -	ti_hdmi_4xxx_wp_audio_config_format(ip_data, &audio_format); +	hdmi_wp_audio_config_dma(wp, &audio_dma); +	hdmi_wp_audio_config_format(wp, &audio_format);  	/* configure the core*/ -	ti_hdmi_4xxx_core_audio_config(ip_data, &core); +	hdmi_core_audio_config(core, &acore);  	/* configure CEA 861 audio infoframe*/ -	ti_hdmi_4xxx_core_audio_infoframe_cfg(ip_data, audio->cea); +	hdmi_core_audio_infoframe_cfg(core, audio->cea);  	return 0;  } -int ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data) +int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp)  { -	REG_FLD_MOD(hdmi_wp_base(ip_data), -		    HDMI_WP_AUDIO_CTRL, true, 31, 31); -	return 0; -} +	REG_FLD_MOD(hdmi_av_base(core), +		    HDMI_CORE_AV_AUD_MODE, true, 0, 0); -void ti_hdmi_4xxx_wp_audio_disable(struct hdmi_ip_data *ip_data) -{ -	REG_FLD_MOD(hdmi_wp_base(ip_data), -		    HDMI_WP_AUDIO_CTRL, false, 31, 31); -} +	hdmi_wp_audio_core_req_enable(wp, true); -int ti_hdmi_4xxx_audio_start(struct hdmi_ip_data *ip_data) -{ -	REG_FLD_MOD(hdmi_av_base(ip_data), -		    HDMI_CORE_AV_AUD_MODE, true, 0, 0); -	REG_FLD_MOD(hdmi_wp_base(ip_data), -		    HDMI_WP_AUDIO_CTRL, true, 30, 30);  	return 0;  } -void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data) +void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp)  { -	REG_FLD_MOD(hdmi_av_base(ip_data), +	REG_FLD_MOD(hdmi_av_base(core),  		    HDMI_CORE_AV_AUD_MODE, false, 0, 0); -	REG_FLD_MOD(hdmi_wp_base(ip_data), -		    HDMI_WP_AUDIO_CTRL, false, 30, 30); + +	hdmi_wp_audio_core_req_enable(wp, false);  } -int ti_hdmi_4xxx_audio_get_dma_port(u32 *offset, u32 *size) +int hdmi4_audio_get_dma_port(u32 *offset, u32 *size)  {  	if (!offset || !size)  		return -EINVAL; @@ -1424,4 +995,24 @@ int ti_hdmi_4xxx_audio_get_dma_port(u32 *offset, u32 *size)  	*size = 4;  	return 0;  } +  #endif + +int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core) +{ +	struct resource *res; + +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core"); +	if (!res) { +		DSSERR("can't get CORE mem resource\n"); +		return -EINVAL; +	} + +	core->base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(core->base)) { +		DSSERR("can't ioremap CORE\n"); +		return PTR_ERR(core->base); +	} + +	return 0; +} diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h b/drivers/video/fbdev/omap2/dss/hdmi4_core.h index 6ef2f929a76..bb646896fa8 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h +++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.h @@ -1,7 +1,5 @@  /* - * ti_hdmi_4xxx_ip.h - * - * HDMI header definition for DM81xx, DM38xx, TI OMAP4 etc processors. + * HDMI header definition for OMAP4 HDMI core IP   *   * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/   * @@ -18,41 +16,22 @@   * this program.  If not, see <http://www.gnu.org/licenses/>.   */ -#ifndef _HDMI_TI_4xxx_H_ -#define _HDMI_TI_4xxx_H_ - -#include <linux/string.h> -#include <video/omapdss.h> -#include "ti_hdmi.h" - -/* HDMI Wrapper */ +#ifndef _HDMI4_CORE_H_ +#define _HDMI4_CORE_H_ -#define HDMI_WP_REVISION			0x0 -#define HDMI_WP_SYSCONFIG			0x10 -#define HDMI_WP_IRQSTATUS_RAW			0x24 -#define HDMI_WP_IRQSTATUS			0x28 -#define HDMI_WP_PWR_CTRL			0x40 -#define HDMI_WP_IRQENABLE_SET			0x2C -#define HDMI_WP_IRQENABLE_CLR			0x30 -#define HDMI_WP_VIDEO_CFG			0x50 -#define HDMI_WP_VIDEO_SIZE			0x60 -#define HDMI_WP_VIDEO_TIMING_H			0x68 -#define HDMI_WP_VIDEO_TIMING_V			0x6C -#define HDMI_WP_WP_CLK				0x70 -#define HDMI_WP_AUDIO_CFG			0x80 -#define HDMI_WP_AUDIO_CFG2			0x84 -#define HDMI_WP_AUDIO_CTRL			0x88 -#define HDMI_WP_AUDIO_DATA			0x8C +#include "hdmi.h" -/* HDMI IP Core System */ +/* OMAP4 HDMI IP Core System */  #define HDMI_CORE_SYS_VND_IDL			0x0  #define HDMI_CORE_SYS_DEV_IDL			0x8  #define HDMI_CORE_SYS_DEV_IDH			0xC  #define HDMI_CORE_SYS_DEV_REV			0x10  #define HDMI_CORE_SYS_SRST			0x14 -#define HDMI_CORE_CTRL1				0x20 +#define HDMI_CORE_SYS_SYS_CTRL1			0x20  #define HDMI_CORE_SYS_SYS_STAT			0x24 +#define HDMI_CORE_SYS_SYS_CTRL3			0x28 +#define HDMI_CORE_SYS_DCTL			0x34  #define HDMI_CORE_SYS_DE_DLY			0xC8  #define HDMI_CORE_SYS_DE_CTRL			0xCC  #define HDMI_CORE_SYS_DE_TOP			0xD0 @@ -60,20 +39,65 @@  #define HDMI_CORE_SYS_DE_CNTH			0xDC  #define HDMI_CORE_SYS_DE_LINL			0xE0  #define HDMI_CORE_SYS_DE_LINH_1			0xE4 +#define HDMI_CORE_SYS_HRES_L			0xE8 +#define HDMI_CORE_SYS_HRES_H			0xEC +#define HDMI_CORE_SYS_VRES_L			0xF0 +#define HDMI_CORE_SYS_VRES_H			0xF4 +#define HDMI_CORE_SYS_IADJUST			0xF8 +#define HDMI_CORE_SYS_POLDETECT			0xFC +#define HDMI_CORE_SYS_HWIDTH1			0x110 +#define HDMI_CORE_SYS_HWIDTH2			0x114 +#define HDMI_CORE_SYS_VWIDTH			0x11C +#define HDMI_CORE_SYS_VID_CTRL			0x120  #define HDMI_CORE_SYS_VID_ACEN			0x124  #define HDMI_CORE_SYS_VID_MODE			0x128 +#define HDMI_CORE_SYS_VID_BLANK1		0x12C +#define HDMI_CORE_SYS_VID_BLANK2		0x130 +#define HDMI_CORE_SYS_VID_BLANK3		0x134 +#define HDMI_CORE_SYS_DC_HEADER			0x138 +#define HDMI_CORE_SYS_VID_DITHER		0x13C +#define HDMI_CORE_SYS_RGB2XVYCC_CT		0x140 +#define HDMI_CORE_SYS_R2Y_COEFF_LOW		0x144 +#define HDMI_CORE_SYS_R2Y_COEFF_UP		0x148 +#define HDMI_CORE_SYS_G2Y_COEFF_LOW		0x14C +#define HDMI_CORE_SYS_G2Y_COEFF_UP		0x150 +#define HDMI_CORE_SYS_B2Y_COEFF_LOW		0x154 +#define HDMI_CORE_SYS_B2Y_COEFF_UP		0x158 +#define HDMI_CORE_SYS_R2CB_COEFF_LOW		0x15C +#define HDMI_CORE_SYS_R2CB_COEFF_UP		0x160 +#define HDMI_CORE_SYS_G2CB_COEFF_LOW		0x164 +#define HDMI_CORE_SYS_G2CB_COEFF_UP		0x168 +#define HDMI_CORE_SYS_B2CB_COEFF_LOW		0x16C +#define HDMI_CORE_SYS_B2CB_COEFF_UP		0x170 +#define HDMI_CORE_SYS_R2CR_COEFF_LOW		0x174 +#define HDMI_CORE_SYS_R2CR_COEFF_UP		0x178 +#define HDMI_CORE_SYS_G2CR_COEFF_LOW		0x17C +#define HDMI_CORE_SYS_G2CR_COEFF_UP		0x180 +#define HDMI_CORE_SYS_B2CR_COEFF_LOW		0x184 +#define HDMI_CORE_SYS_B2CR_COEFF_UP		0x188 +#define HDMI_CORE_SYS_RGB_OFFSET_LOW		0x18C +#define HDMI_CORE_SYS_RGB_OFFSET_UP		0x190 +#define HDMI_CORE_SYS_Y_OFFSET_LOW		0x194 +#define HDMI_CORE_SYS_Y_OFFSET_UP		0x198 +#define HDMI_CORE_SYS_CBCR_OFFSET_LOW		0x19C +#define HDMI_CORE_SYS_CBCR_OFFSET_UP		0x1A0  #define HDMI_CORE_SYS_INTR_STATE		0x1C0  #define HDMI_CORE_SYS_INTR1			0x1C4  #define HDMI_CORE_SYS_INTR2			0x1C8  #define HDMI_CORE_SYS_INTR3			0x1CC  #define HDMI_CORE_SYS_INTR4			0x1D0 -#define HDMI_CORE_SYS_UMASK1			0x1D4 +#define HDMI_CORE_SYS_INTR_UNMASK1		0x1D4 +#define HDMI_CORE_SYS_INTR_UNMASK2		0x1D8 +#define HDMI_CORE_SYS_INTR_UNMASK3		0x1DC +#define HDMI_CORE_SYS_INTR_UNMASK4		0x1E0 +#define HDMI_CORE_SYS_INTR_CTRL			0x1E4  #define HDMI_CORE_SYS_TMDS_CTRL			0x208 -#define HDMI_CORE_CTRL1_VEN_FOLLOWVSYNC	0x1 -#define HDMI_CORE_CTRL1_HEN_FOLLOWHSYNC	0x1 -#define HDMI_CORE_CTRL1_BSEL_24BITBUS	0x1 -#define HDMI_CORE_CTRL1_EDGE_RISINGEDGE	0x1 +/* value definitions for HDMI_CORE_SYS_SYS_CTRL1 fields */ +#define HDMI_CORE_SYS_SYS_CTRL1_VEN_FOLLOWVSYNC	0x1 +#define HDMI_CORE_SYS_SYS_CTRL1_HEN_FOLLOWHSYNC	0x1 +#define HDMI_CORE_SYS_SYS_CTRL1_BSEL_24BITBUS	0x1 +#define HDMI_CORE_SYS_SYS_CTRL1_EDGE_RISINGEDGE	0x1  /* HDMI DDC E-DID */  #define HDMI_CORE_DDC_ADDR			0x3B4 @@ -158,35 +182,6 @@  #define HDMI_CORE_AV_GEN_DBYTE_NELEMS		31  #define HDMI_CORE_AV_GEN2_DBYTE_NELEMS		31 -/* PLL */ - -#define PLLCTRL_PLL_CONTROL			0x0 -#define PLLCTRL_PLL_STATUS			0x4 -#define PLLCTRL_PLL_GO				0x8 -#define PLLCTRL_CFG1				0xC -#define PLLCTRL_CFG2				0x10 -#define PLLCTRL_CFG3				0x14 -#define PLLCTRL_CFG4				0x20 - -/* HDMI PHY */ - -#define HDMI_TXPHY_TX_CTRL			0x0 -#define HDMI_TXPHY_DIGITAL_CTRL			0x4 -#define HDMI_TXPHY_POWER_CTRL			0x8 -#define HDMI_TXPHY_PAD_CFG_CTRL			0xC - -#define REG_FLD_MOD(base, idx, val, start, end) \ -	hdmi_write_reg(base, idx, FLD_MOD(hdmi_read_reg(base, idx),\ -							val, start, end)) -#define REG_GET(base, idx, start, end) \ -	FLD_GET(hdmi_read_reg(base, idx), start, end) - -enum hdmi_phy_pwr { -	HDMI_PHYPWRCMD_OFF = 0, -	HDMI_PHYPWRCMD_LDOON = 1, -	HDMI_PHYPWRCMD_TXON = 2 -}; -  enum hdmi_core_inputbus_width {  	HDMI_INPUT_8BIT = 0,  	HDMI_INPUT_10BIT = 1, @@ -229,114 +224,6 @@ enum hdmi_core_packet_ctrl {  	HDMI_PACKETREPEATOFF = 0  }; -/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */ -enum hdmi_core_infoframe { -	HDMI_INFOFRAME_AVI_DB1Y_RGB = 0, -	HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1, -	HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2, -	HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0, -	HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON =  1, -	HDMI_INFOFRAME_AVI_DB1B_NO = 0, -	HDMI_INFOFRAME_AVI_DB1B_VERT = 1, -	HDMI_INFOFRAME_AVI_DB1B_HORI = 2, -	HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3, -	HDMI_INFOFRAME_AVI_DB1S_0 = 0, -	HDMI_INFOFRAME_AVI_DB1S_1 = 1, -	HDMI_INFOFRAME_AVI_DB1S_2 = 2, -	HDMI_INFOFRAME_AVI_DB2C_NO = 0, -	HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1, -	HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2, -	HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3, -	HDMI_INFOFRAME_AVI_DB2M_NO = 0, -	HDMI_INFOFRAME_AVI_DB2M_43 = 1, -	HDMI_INFOFRAME_AVI_DB2M_169 = 2, -	HDMI_INFOFRAME_AVI_DB2R_SAME = 8, -	HDMI_INFOFRAME_AVI_DB2R_43 = 9, -	HDMI_INFOFRAME_AVI_DB2R_169 = 10, -	HDMI_INFOFRAME_AVI_DB2R_149 = 11, -	HDMI_INFOFRAME_AVI_DB3ITC_NO = 0, -	HDMI_INFOFRAME_AVI_DB3ITC_YES = 1, -	HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0, -	HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1, -	HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0, -	HDMI_INFOFRAME_AVI_DB3Q_LR = 1, -	HDMI_INFOFRAME_AVI_DB3Q_FR = 2, -	HDMI_INFOFRAME_AVI_DB3SC_NO = 0, -	HDMI_INFOFRAME_AVI_DB3SC_HORI = 1, -	HDMI_INFOFRAME_AVI_DB3SC_VERT = 2, -	HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3, -	HDMI_INFOFRAME_AVI_DB5PR_NO = 0, -	HDMI_INFOFRAME_AVI_DB5PR_2 = 1, -	HDMI_INFOFRAME_AVI_DB5PR_3 = 2, -	HDMI_INFOFRAME_AVI_DB5PR_4 = 3, -	HDMI_INFOFRAME_AVI_DB5PR_5 = 4, -	HDMI_INFOFRAME_AVI_DB5PR_6 = 5, -	HDMI_INFOFRAME_AVI_DB5PR_7 = 6, -	HDMI_INFOFRAME_AVI_DB5PR_8 = 7, -	HDMI_INFOFRAME_AVI_DB5PR_9 = 8, -	HDMI_INFOFRAME_AVI_DB5PR_10 = 9, -}; - -enum hdmi_packing_mode { -	HDMI_PACK_10b_RGB_YUV444 = 0, -	HDMI_PACK_24b_RGB_YUV444_YUV422 = 1, -	HDMI_PACK_20b_YUV422 = 2, -	HDMI_PACK_ALREADYPACKED = 7 -}; - -enum hdmi_core_audio_layout { -	HDMI_AUDIO_LAYOUT_2CH = 0, -	HDMI_AUDIO_LAYOUT_8CH = 1 -}; - -enum hdmi_core_cts_mode { -	HDMI_AUDIO_CTS_MODE_HW = 0, -	HDMI_AUDIO_CTS_MODE_SW = 1 -}; - -enum hdmi_stereo_channels { -	HDMI_AUDIO_STEREO_NOCHANNELS = 0, -	HDMI_AUDIO_STEREO_ONECHANNEL = 1, -	HDMI_AUDIO_STEREO_TWOCHANNELS = 2, -	HDMI_AUDIO_STEREO_THREECHANNELS = 3, -	HDMI_AUDIO_STEREO_FOURCHANNELS = 4 -}; - -enum hdmi_audio_type { -	HDMI_AUDIO_TYPE_LPCM = 0, -	HDMI_AUDIO_TYPE_IEC = 1 -}; - -enum hdmi_audio_justify { -	HDMI_AUDIO_JUSTIFY_LEFT = 0, -	HDMI_AUDIO_JUSTIFY_RIGHT = 1 -}; - -enum hdmi_audio_sample_order { -	HDMI_AUDIO_SAMPLE_RIGHT_FIRST = 0, -	HDMI_AUDIO_SAMPLE_LEFT_FIRST = 1 -}; - -enum hdmi_audio_samples_perword { -	HDMI_AUDIO_ONEWORD_ONESAMPLE = 0, -	HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1 -}; - -enum hdmi_audio_sample_size { -	HDMI_AUDIO_SAMPLE_16BITS = 0, -	HDMI_AUDIO_SAMPLE_24BITS = 1 -}; - -enum hdmi_audio_transf_mode { -	HDMI_AUDIO_TRANSF_DMA = 0, -	HDMI_AUDIO_TRANSF_IRQ = 1 -}; - -enum hdmi_audio_blk_strt_end_sig { -	HDMI_AUDIO_BLOCK_SIG_STARTEND_ON = 0, -	HDMI_AUDIO_BLOCK_SIG_STARTEND_OFF = 1 -}; -  enum hdmi_audio_i2s_config {  	HDMI_AUDIO_I2S_MSB_SHIFTED_FIRST = 0,  	HDMI_AUDIO_I2S_LSB_SHIFTED_FIRST = 1, @@ -352,17 +239,6 @@ enum hdmi_audio_i2s_config {  	HDMI_AUDIO_I2S_SD3_EN = 1 << 3,  }; -enum hdmi_audio_mclk_mode { -	HDMI_AUDIO_MCLK_128FS = 0, -	HDMI_AUDIO_MCLK_256FS = 1, -	HDMI_AUDIO_MCLK_384FS = 2, -	HDMI_AUDIO_MCLK_512FS = 3, -	HDMI_AUDIO_MCLK_768FS = 4, -	HDMI_AUDIO_MCLK_1024FS = 5, -	HDMI_AUDIO_MCLK_1152FS = 6, -	HDMI_AUDIO_MCLK_192FS = 7 -}; -  struct hdmi_core_video_config {  	enum hdmi_core_inputbus_width	ip_bus_width;  	enum hdmi_core_dither_trunc	op_dither_truc; @@ -383,55 +259,18 @@ struct hdmi_core_packet_enable_repeat {  	u32	generic_pkt_repeat;  }; -struct hdmi_video_format { -	enum hdmi_packing_mode	packing_mode; -	u32			y_res;	/* Line per panel */ -	u32			x_res;	/* pixel per line */ -}; - -struct hdmi_audio_format { -	enum hdmi_stereo_channels		stereo_channels; -	u8					active_chnnls_msk; -	enum hdmi_audio_type			type; -	enum hdmi_audio_justify			justification; -	enum hdmi_audio_sample_order		sample_order; -	enum hdmi_audio_samples_perword		samples_per_word; -	enum hdmi_audio_sample_size		sample_size; -	enum hdmi_audio_blk_strt_end_sig	en_sig_blk_strt_end; -}; - -struct hdmi_audio_dma { -	u8				transfer_size; -	u8				block_size; -	enum hdmi_audio_transf_mode	mode; -	u16				fifo_threshold; -}; - -struct hdmi_core_audio_i2s_config { -	u8 in_length_bits; -	u8 justification; -	u8 sck_edge_mode; -	u8 vbit; -	u8 direction; -	u8 shift; -	u8 active_sds; -}; - -struct hdmi_core_audio_config { -	struct hdmi_core_audio_i2s_config	i2s_cfg; -	struct snd_aes_iec958			*iec60958_cfg; -	bool					fs_override; -	u32					n; -	u32					cts; -	u32					aud_par_busclk; -	enum hdmi_core_audio_layout		layout; -	enum hdmi_core_cts_mode			cts_mode; -	bool					use_mclk; -	enum hdmi_audio_mclk_mode		mclk_mode; -	bool					en_acr_pkt; -	bool					en_dsd_audio; -	bool					en_parallel_aud_input; -	bool					en_spdif; -}; +int hdmi4_read_edid(struct hdmi_core_data *core, u8 *edid, int len); +void hdmi4_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, +		struct hdmi_config *cfg); +void hdmi4_core_dump(struct hdmi_core_data *core, struct seq_file *s); +int hdmi4_core_init(struct platform_device *pdev, struct hdmi_core_data *core); + +#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) +int hdmi4_audio_start(struct hdmi_core_data *core, struct hdmi_wp_data *wp); +void hdmi4_audio_stop(struct hdmi_core_data *core, struct hdmi_wp_data *wp); +int hdmi4_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, +		struct omap_dss_audio *audio, u32 pclk); +int hdmi4_audio_get_dma_port(u32 *offset, u32 *size); +#endif  #endif diff --git a/drivers/video/fbdev/omap2/dss/hdmi5.c b/drivers/video/fbdev/omap2/dss/hdmi5.c new file mode 100644 index 00000000000..c468b9e1f29 --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/hdmi5.c @@ -0,0 +1,829 @@ +/* + * HDMI driver for OMAP5 + * + * Copyright (C) 2014 Texas Instruments Incorporated + * + * Authors: + *	Yong Zhi + *	Mythri pk + *	Archit Taneja <archit@ti.com> + *	Tomi Valkeinen <tomi.valkeinen@ti.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +#define DSS_SUBSYS_NAME "HDMI" + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/interrupt.h> +#include <linux/mutex.h> +#include <linux/delay.h> +#include <linux/string.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/clk.h> +#include <linux/gpio.h> +#include <linux/regulator/consumer.h> +#include <video/omapdss.h> + +#include "hdmi5_core.h" +#include "dss.h" +#include "dss_features.h" + +static struct { +	struct mutex lock; +	struct platform_device *pdev; + +	struct hdmi_wp_data	wp; +	struct hdmi_pll_data	pll; +	struct hdmi_phy_data	phy; +	struct hdmi_core_data	core; + +	struct hdmi_config cfg; + +	struct clk *sys_clk; +	struct regulator *vdda_reg; + +	bool core_enabled; + +	struct omap_dss_device output; +} hdmi; + +static int hdmi_runtime_get(void) +{ +	int r; + +	DSSDBG("hdmi_runtime_get\n"); + +	r = pm_runtime_get_sync(&hdmi.pdev->dev); +	WARN_ON(r < 0); +	if (r < 0) +		return r; + +	return 0; +} + +static void hdmi_runtime_put(void) +{ +	int r; + +	DSSDBG("hdmi_runtime_put\n"); + +	r = pm_runtime_put_sync(&hdmi.pdev->dev); +	WARN_ON(r < 0 && r != -ENOSYS); +} + +static irqreturn_t hdmi_irq_handler(int irq, void *data) +{ +	struct hdmi_wp_data *wp = data; +	u32 irqstatus; + +	irqstatus = hdmi_wp_get_irqstatus(wp); +	hdmi_wp_set_irqstatus(wp, irqstatus); + +	if ((irqstatus & HDMI_IRQ_LINK_CONNECT) && +			irqstatus & HDMI_IRQ_LINK_DISCONNECT) { +		u32 v; +		/* +		 * If we get both connect and disconnect interrupts at the same +		 * time, turn off the PHY, clear interrupts, and restart, which +		 * raises connect interrupt if a cable is connected, or nothing +		 * if cable is not connected. +		 */ + +		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_OFF); + +		/* +		 * We always get bogus CONNECT & DISCONNECT interrupts when +		 * setting the PHY to LDOON. To ignore those, we force the RXDET +		 * line to 0 until the PHY power state has been changed. +		 */ +		v = hdmi_read_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL); +		v = FLD_MOD(v, 1, 15, 15); /* FORCE_RXDET_HIGH */ +		v = FLD_MOD(v, 0, 14, 7); /* RXDET_LINE */ +		hdmi_write_reg(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, v); + +		hdmi_wp_set_irqstatus(wp, HDMI_IRQ_LINK_CONNECT | +				HDMI_IRQ_LINK_DISCONNECT); + +		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); + +		REG_FLD_MOD(hdmi.phy.base, HDMI_TXPHY_PAD_CFG_CTRL, 0, 15, 15); + +	} else if (irqstatus & HDMI_IRQ_LINK_CONNECT) { +		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_TXON); +	} else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) { +		hdmi_wp_set_phy_pwr(wp, HDMI_PHYPWRCMD_LDOON); +	} + +	return IRQ_HANDLED; +} + +static int hdmi_init_regulator(void) +{ +	int r; +	struct regulator *reg; + +	if (hdmi.vdda_reg != NULL) +		return 0; + +	reg = devm_regulator_get(&hdmi.pdev->dev, "vdda"); +	if (IS_ERR(reg)) { +		DSSERR("can't get VDDA regulator\n"); +		return PTR_ERR(reg); +	} + +	if (regulator_can_change_voltage(reg)) { +		r = regulator_set_voltage(reg, 1800000, 1800000); +		if (r) { +			devm_regulator_put(reg); +			DSSWARN("can't set the regulator voltage\n"); +			return r; +		} +	} + +	hdmi.vdda_reg = reg; + +	return 0; +} + +static int hdmi_power_on_core(struct omap_dss_device *dssdev) +{ +	int r; + +	r = regulator_enable(hdmi.vdda_reg); +	if (r) +		return r; + +	r = hdmi_runtime_get(); +	if (r) +		goto err_runtime_get; + +	/* Make selection of HDMI in DSS */ +	dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); + +	hdmi.core_enabled = true; + +	return 0; + +err_runtime_get: +	regulator_disable(hdmi.vdda_reg); + +	return r; +} + +static void hdmi_power_off_core(struct omap_dss_device *dssdev) +{ +	hdmi.core_enabled = false; + +	hdmi_runtime_put(); +	regulator_disable(hdmi.vdda_reg); +} + +static int hdmi_power_on_full(struct omap_dss_device *dssdev) +{ +	int r; +	struct omap_video_timings *p; +	struct omap_overlay_manager *mgr = hdmi.output.manager; +	unsigned long phy; + +	r = hdmi_power_on_core(dssdev); +	if (r) +		return r; + +	p = &hdmi.cfg.timings; + +	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); + +	/* the functions below use kHz pixel clock. TODO: change to Hz */ +	phy = p->pixelclock / 1000; + +	hdmi_pll_compute(&hdmi.pll, clk_get_rate(hdmi.sys_clk), phy); + +	/* disable and clear irqs */ +	hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); +	hdmi_wp_set_irqstatus(&hdmi.wp, +			hdmi_wp_get_irqstatus(&hdmi.wp)); + +	/* config the PLL and PHY hdmi_set_pll_pwrfirst */ +	r = hdmi_pll_enable(&hdmi.pll, &hdmi.wp); +	if (r) { +		DSSDBG("Failed to lock PLL\n"); +		goto err_pll_enable; +	} + +	r = hdmi_phy_configure(&hdmi.phy, &hdmi.cfg); +	if (r) { +		DSSDBG("Failed to start PHY\n"); +		goto err_phy_cfg; +	} + +	r = hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_LDOON); +	if (r) +		goto err_phy_pwr; + +	hdmi5_configure(&hdmi.core, &hdmi.wp, &hdmi.cfg); + +	/* bypass TV gamma table */ +	dispc_enable_gamma_table(0); + +	/* tv size */ +	dss_mgr_set_timings(mgr, p); + +	r = hdmi_wp_video_start(&hdmi.wp); +	if (r) +		goto err_vid_enable; + +	r = dss_mgr_enable(mgr); +	if (r) +		goto err_mgr_enable; + +	hdmi_wp_set_irqenable(&hdmi.wp, +			HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT); + +	return 0; + +err_mgr_enable: +	hdmi_wp_video_stop(&hdmi.wp); +err_vid_enable: +	hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); +err_phy_pwr: +err_phy_cfg: +	hdmi_pll_disable(&hdmi.pll, &hdmi.wp); +err_pll_enable: +	hdmi_power_off_core(dssdev); +	return -EIO; +} + +static void hdmi_power_off_full(struct omap_dss_device *dssdev) +{ +	struct omap_overlay_manager *mgr = hdmi.output.manager; + +	hdmi_wp_clear_irqenable(&hdmi.wp, 0xffffffff); + +	dss_mgr_disable(mgr); + +	hdmi_wp_video_stop(&hdmi.wp); + +	hdmi_wp_set_phy_pwr(&hdmi.wp, HDMI_PHYPWRCMD_OFF); + +	hdmi_pll_disable(&hdmi.pll, &hdmi.wp); + +	hdmi_power_off_core(dssdev); +} + +static int hdmi_display_check_timing(struct omap_dss_device *dssdev, +					struct omap_video_timings *timings) +{ +	struct omap_dss_device *out = &hdmi.output; + +	if (!dispc_mgr_timings_ok(out->dispc_channel, timings)) +		return -EINVAL; + +	return 0; +} + +static void hdmi_display_set_timing(struct omap_dss_device *dssdev, +		struct omap_video_timings *timings) +{ +	struct hdmi_cm cm; +	const struct hdmi_config *t; + +	mutex_lock(&hdmi.lock); + +	cm = hdmi_get_code(timings); +	hdmi.cfg.cm = cm; + +	t = hdmi_get_timings(cm.mode, cm.code); +	if (t != NULL) { +		hdmi.cfg = *t; + +		dispc_set_tv_pclk(t->timings.pixelclock); +	} else { +		hdmi.cfg.timings = *timings; +		hdmi.cfg.cm.code = 0; +		hdmi.cfg.cm.mode = HDMI_DVI; + +		dispc_set_tv_pclk(timings->pixelclock); +	} + +	DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ? +			"DVI" : "HDMI", hdmi.cfg.cm.code); + +	mutex_unlock(&hdmi.lock); +} + +static void hdmi_display_get_timings(struct omap_dss_device *dssdev, +		struct omap_video_timings *timings) +{ +	const struct hdmi_config *cfg; +	struct hdmi_cm cm = hdmi.cfg.cm; + +	cfg = hdmi_get_timings(cm.mode, cm.code); +	if (cfg == NULL) +		cfg = hdmi_default_timing(); + +	memcpy(timings, &cfg->timings, sizeof(cfg->timings)); +} + +static void hdmi_dump_regs(struct seq_file *s) +{ +	mutex_lock(&hdmi.lock); + +	if (hdmi_runtime_get()) { +		mutex_unlock(&hdmi.lock); +		return; +	} + +	hdmi_wp_dump(&hdmi.wp, s); +	hdmi_pll_dump(&hdmi.pll, s); +	hdmi_phy_dump(&hdmi.phy, s); +	hdmi5_core_dump(&hdmi.core, s); + +	hdmi_runtime_put(); +	mutex_unlock(&hdmi.lock); +} + +static int read_edid(u8 *buf, int len) +{ +	int r; +	int idlemode; + +	mutex_lock(&hdmi.lock); + +	r = hdmi_runtime_get(); +	BUG_ON(r); + +	idlemode = REG_GET(hdmi.wp.base, HDMI_WP_SYSCONFIG, 3, 2); +	/* No-idle mode */ +	REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, 1, 3, 2); + +	r = hdmi5_read_edid(&hdmi.core,  buf, len); + +	REG_FLD_MOD(hdmi.wp.base, HDMI_WP_SYSCONFIG, idlemode, 3, 2); + +	hdmi_runtime_put(); +	mutex_unlock(&hdmi.lock); + +	return r; +} + +static int hdmi_display_enable(struct omap_dss_device *dssdev) +{ +	struct omap_dss_device *out = &hdmi.output; +	int r = 0; + +	DSSDBG("ENTER hdmi_display_enable\n"); + +	mutex_lock(&hdmi.lock); + +	if (out == NULL || out->manager == NULL) { +		DSSERR("failed to enable display: no output/manager\n"); +		r = -ENODEV; +		goto err0; +	} + +	r = hdmi_power_on_full(dssdev); +	if (r) { +		DSSERR("failed to power on device\n"); +		goto err0; +	} + +	mutex_unlock(&hdmi.lock); +	return 0; + +err0: +	mutex_unlock(&hdmi.lock); +	return r; +} + +static void hdmi_display_disable(struct omap_dss_device *dssdev) +{ +	DSSDBG("Enter hdmi_display_disable\n"); + +	mutex_lock(&hdmi.lock); + +	hdmi_power_off_full(dssdev); + +	mutex_unlock(&hdmi.lock); +} + +static int hdmi_core_enable(struct omap_dss_device *dssdev) +{ +	int r = 0; + +	DSSDBG("ENTER omapdss_hdmi_core_enable\n"); + +	mutex_lock(&hdmi.lock); + +	r = hdmi_power_on_core(dssdev); +	if (r) { +		DSSERR("failed to power on device\n"); +		goto err0; +	} + +	mutex_unlock(&hdmi.lock); +	return 0; + +err0: +	mutex_unlock(&hdmi.lock); +	return r; +} + +static void hdmi_core_disable(struct omap_dss_device *dssdev) +{ +	DSSDBG("Enter omapdss_hdmi_core_disable\n"); + +	mutex_lock(&hdmi.lock); + +	hdmi_power_off_core(dssdev); + +	mutex_unlock(&hdmi.lock); +} + +static int hdmi_get_clocks(struct platform_device *pdev) +{ +	struct clk *clk; + +	clk = devm_clk_get(&pdev->dev, "sys_clk"); +	if (IS_ERR(clk)) { +		DSSERR("can't get sys_clk\n"); +		return PTR_ERR(clk); +	} + +	hdmi.sys_clk = clk; + +	return 0; +} + +static int hdmi_connect(struct omap_dss_device *dssdev, +		struct omap_dss_device *dst) +{ +	struct omap_overlay_manager *mgr; +	int r; + +	r = hdmi_init_regulator(); +	if (r) +		return r; + +	mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel); +	if (!mgr) +		return -ENODEV; + +	r = dss_mgr_connect(mgr, dssdev); +	if (r) +		return r; + +	r = omapdss_output_set_device(dssdev, dst); +	if (r) { +		DSSERR("failed to connect output to new device: %s\n", +				dst->name); +		dss_mgr_disconnect(mgr, dssdev); +		return r; +	} + +	return 0; +} + +static void hdmi_disconnect(struct omap_dss_device *dssdev, +		struct omap_dss_device *dst) +{ +	WARN_ON(dst != dssdev->dst); + +	if (dst != dssdev->dst) +		return; + +	omapdss_output_unset_device(dssdev); + +	if (dssdev->manager) +		dss_mgr_disconnect(dssdev->manager, dssdev); +} + +static int hdmi_read_edid(struct omap_dss_device *dssdev, +		u8 *edid, int len) +{ +	bool need_enable; +	int r; + +	need_enable = hdmi.core_enabled == false; + +	if (need_enable) { +		r = hdmi_core_enable(dssdev); +		if (r) +			return r; +	} + +	r = read_edid(edid, len); + +	if (need_enable) +		hdmi_core_disable(dssdev); + +	return r; +} + +#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) +static int hdmi_audio_enable(struct omap_dss_device *dssdev) +{ +	int r; + +	mutex_lock(&hdmi.lock); + +	if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { +		r = -EPERM; +		goto err; +	} + +	r = hdmi_wp_audio_enable(&hdmi.wp, true); +	if (r) +		goto err; + +	mutex_unlock(&hdmi.lock); +	return 0; + +err: +	mutex_unlock(&hdmi.lock); +	return r; +} + +static void hdmi_audio_disable(struct omap_dss_device *dssdev) +{ +	hdmi_wp_audio_enable(&hdmi.wp, false); +} + +static int hdmi_audio_start(struct omap_dss_device *dssdev) +{ +	return hdmi_wp_audio_core_req_enable(&hdmi.wp, true); +} + +static void hdmi_audio_stop(struct omap_dss_device *dssdev) +{ +	hdmi_wp_audio_core_req_enable(&hdmi.wp, false); +} + +static bool hdmi_audio_supported(struct omap_dss_device *dssdev) +{ +	bool r; + +	mutex_lock(&hdmi.lock); + +	r = hdmi_mode_has_audio(hdmi.cfg.cm.mode); + +	mutex_unlock(&hdmi.lock); +	return r; +} + +static int hdmi_audio_config(struct omap_dss_device *dssdev, +		struct omap_dss_audio *audio) +{ +	int r; +	u32 pclk = hdmi.cfg.timings.pixelclock; + +	mutex_lock(&hdmi.lock); + +	if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) { +		r = -EPERM; +		goto err; +	} + +	r = hdmi5_audio_config(&hdmi.core, &hdmi.wp, audio, pclk); +	if (r) +		goto err; + +	mutex_unlock(&hdmi.lock); +	return 0; + +err: +	mutex_unlock(&hdmi.lock); +	return r; +} +#else +static int hdmi_audio_enable(struct omap_dss_device *dssdev) +{ +	return -EPERM; +} + +static void hdmi_audio_disable(struct omap_dss_device *dssdev) +{ +} + +static int hdmi_audio_start(struct omap_dss_device *dssdev) +{ +	return -EPERM; +} + +static void hdmi_audio_stop(struct omap_dss_device *dssdev) +{ +} + +static bool hdmi_audio_supported(struct omap_dss_device *dssdev) +{ +	return false; +} + +static int hdmi_audio_config(struct omap_dss_device *dssdev, +		struct omap_dss_audio *audio) +{ +	return -EPERM; +} +#endif + +static const struct omapdss_hdmi_ops hdmi_ops = { +	.connect		= hdmi_connect, +	.disconnect		= hdmi_disconnect, + +	.enable			= hdmi_display_enable, +	.disable		= hdmi_display_disable, + +	.check_timings		= hdmi_display_check_timing, +	.set_timings		= hdmi_display_set_timing, +	.get_timings		= hdmi_display_get_timings, + +	.read_edid		= hdmi_read_edid, + +	.audio_enable		= hdmi_audio_enable, +	.audio_disable		= hdmi_audio_disable, +	.audio_start		= hdmi_audio_start, +	.audio_stop		= hdmi_audio_stop, +	.audio_supported	= hdmi_audio_supported, +	.audio_config		= hdmi_audio_config, +}; + +static void hdmi_init_output(struct platform_device *pdev) +{ +	struct omap_dss_device *out = &hdmi.output; + +	out->dev = &pdev->dev; +	out->id = OMAP_DSS_OUTPUT_HDMI; +	out->output_type = OMAP_DISPLAY_TYPE_HDMI; +	out->name = "hdmi.0"; +	out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; +	out->ops.hdmi = &hdmi_ops; +	out->owner = THIS_MODULE; + +	omapdss_register_output(out); +} + +static void __exit hdmi_uninit_output(struct platform_device *pdev) +{ +	struct omap_dss_device *out = &hdmi.output; + +	omapdss_unregister_output(out); +} + +static int hdmi_probe_of(struct platform_device *pdev) +{ +	struct device_node *node = pdev->dev.of_node; +	struct device_node *ep; +	int r; + +	ep = omapdss_of_get_first_endpoint(node); +	if (!ep) +		return 0; + +	r = hdmi_parse_lanes_of(pdev, ep, &hdmi.phy); +	if (r) +		goto err; + +	of_node_put(ep); +	return 0; + +err: +	of_node_put(ep); +	return r; +} + +/* HDMI HW IP initialisation */ +static int omapdss_hdmihw_probe(struct platform_device *pdev) +{ +	int r; +	int irq; + +	hdmi.pdev = pdev; + +	mutex_init(&hdmi.lock); + +	if (pdev->dev.of_node) { +		r = hdmi_probe_of(pdev); +		if (r) +			return r; +	} + +	r = hdmi_wp_init(pdev, &hdmi.wp); +	if (r) +		return r; + +	r = hdmi_pll_init(pdev, &hdmi.pll); +	if (r) +		return r; + +	r = hdmi_phy_init(pdev, &hdmi.phy); +	if (r) +		return r; + +	r = hdmi5_core_init(pdev, &hdmi.core); +	if (r) +		return r; + +	r = hdmi_get_clocks(pdev); +	if (r) { +		DSSERR("can't get clocks\n"); +		return r; +	} + +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) { +		DSSERR("platform_get_irq failed\n"); +		return -ENODEV; +	} + +	r = devm_request_threaded_irq(&pdev->dev, irq, +			NULL, hdmi_irq_handler, +			IRQF_ONESHOT, "OMAP HDMI", &hdmi.wp); +	if (r) { +		DSSERR("HDMI IRQ request failed\n"); +		return r; +	} + +	pm_runtime_enable(&pdev->dev); + +	hdmi_init_output(pdev); + +	dss_debugfs_create_file("hdmi", hdmi_dump_regs); + +	return 0; +} + +static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) +{ +	hdmi_uninit_output(pdev); + +	pm_runtime_disable(&pdev->dev); + +	return 0; +} + +static int hdmi_runtime_suspend(struct device *dev) +{ +	clk_disable_unprepare(hdmi.sys_clk); + +	dispc_runtime_put(); + +	return 0; +} + +static int hdmi_runtime_resume(struct device *dev) +{ +	int r; + +	r = dispc_runtime_get(); +	if (r < 0) +		return r; + +	clk_prepare_enable(hdmi.sys_clk); + +	return 0; +} + +static const struct dev_pm_ops hdmi_pm_ops = { +	.runtime_suspend = hdmi_runtime_suspend, +	.runtime_resume = hdmi_runtime_resume, +}; + +static const struct of_device_id hdmi_of_match[] = { +	{ .compatible = "ti,omap5-hdmi", }, +	{}, +}; + +static struct platform_driver omapdss_hdmihw_driver = { +	.probe		= omapdss_hdmihw_probe, +	.remove         = __exit_p(omapdss_hdmihw_remove), +	.driver         = { +		.name   = "omapdss_hdmi5", +		.owner  = THIS_MODULE, +		.pm	= &hdmi_pm_ops, +		.of_match_table = hdmi_of_match, +	}, +}; + +int __init hdmi5_init_platform_driver(void) +{ +	return platform_driver_register(&omapdss_hdmihw_driver); +} + +void __exit hdmi5_uninit_platform_driver(void) +{ +	platform_driver_unregister(&omapdss_hdmihw_driver); +} diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.c b/drivers/video/fbdev/omap2/dss/hdmi5_core.c new file mode 100644 index 00000000000..7528c7a42aa --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.c @@ -0,0 +1,922 @@ +/* + * OMAP5 HDMI CORE IP driver library + * + * Copyright (C) 2014 Texas Instruments Incorporated + * + * Authors: + *	Yong Zhi + *	Mythri pk + *	Archit Taneja <archit@ti.com> + *	Tomi Valkeinen <tomi.valkeinen@ti.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/delay.h> +#include <linux/string.h> +#include <linux/seq_file.h> +#include <drm/drm_edid.h> +#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) +#include <sound/asound.h> +#include <sound/asoundef.h> +#endif + +#include "hdmi5_core.h" + +/* only 24 bit color depth used for now */ +static const struct csc_table csc_table_deepcolor[] = { +	/* HDMI_DEEP_COLOR_24BIT */ +	[0] = { 7036, 0, 0, 32, 0, 7036, 0, 32, 0, 0, 7036, 32, }, +	/* HDMI_DEEP_COLOR_30BIT */ +	[1] = { 7015, 0, 0, 128, 0, 7015, 0, 128, 0, 0, 7015, 128, }, +	/* HDMI_DEEP_COLOR_36BIT */ +	[2] = { 7010, 0, 0, 512, 0, 7010, 0, 512, 0, 0, 7010, 512, }, +	/* FULL RANGE */ +	[3] = { 8192, 0, 0, 0, 0, 8192, 0, 0, 0, 0, 8192, 0, }, +}; + +static void hdmi_core_ddc_init(struct hdmi_core_data *core) +{ +	void __iomem *base = core->base; +	const unsigned long long iclk = 266000000;	/* DSS L3 ICLK */ +	const unsigned ss_scl_high = 4000;		/* ns */ +	const unsigned ss_scl_low = 4700;		/* ns */ +	const unsigned fs_scl_high = 600;		/* ns */ +	const unsigned fs_scl_low = 1300;		/* ns */ +	const unsigned sda_hold = 300;			/* ns */ +	const unsigned sfr_div = 10; +	unsigned long long sfr; +	unsigned v; + +	sfr = iclk / sfr_div;	/* SFR_DIV */ +	sfr /= 1000;		/* SFR clock in kHz */ + +	/* Reset */ +	REG_FLD_MOD(base, HDMI_CORE_I2CM_SOFTRSTZ, 0, 0, 0); +	if (hdmi_wait_for_bit_change(base, HDMI_CORE_I2CM_SOFTRSTZ, +				0, 0, 1) != 1) +		DSSERR("HDMI I2CM reset failed\n"); + +	/* Standard (0) or Fast (1) Mode */ +	REG_FLD_MOD(base, HDMI_CORE_I2CM_DIV, 0, 3, 3); + +	/* Standard Mode SCL High counter */ +	v = DIV_ROUND_UP_ULL(ss_scl_high * sfr, 1000000); +	REG_FLD_MOD(base, HDMI_CORE_I2CM_SS_SCL_HCNT_1_ADDR, +			(v >> 8) & 0xff, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_I2CM_SS_SCL_HCNT_0_ADDR, +			v & 0xff, 7, 0); + +	/* Standard Mode SCL Low counter */ +	v = DIV_ROUND_UP_ULL(ss_scl_low * sfr, 1000000); +	REG_FLD_MOD(base, HDMI_CORE_I2CM_SS_SCL_LCNT_1_ADDR, +			(v >> 8) & 0xff, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_I2CM_SS_SCL_LCNT_0_ADDR, +			v & 0xff, 7, 0); + +	/* Fast Mode SCL High Counter */ +	v = DIV_ROUND_UP_ULL(fs_scl_high * sfr, 1000000); +	REG_FLD_MOD(base, HDMI_CORE_I2CM_FS_SCL_HCNT_1_ADDR, +			(v >> 8) & 0xff, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_I2CM_FS_SCL_HCNT_0_ADDR, +			v & 0xff, 7, 0); + +	/* Fast Mode SCL Low Counter */ +	v = DIV_ROUND_UP_ULL(fs_scl_low * sfr, 1000000); +	REG_FLD_MOD(base, HDMI_CORE_I2CM_FS_SCL_LCNT_1_ADDR, +			(v >> 8) & 0xff, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_I2CM_FS_SCL_LCNT_0_ADDR, +			v & 0xff, 7, 0); + +	/* SDA Hold Time */ +	v = DIV_ROUND_UP_ULL(sda_hold * sfr, 1000000); +	REG_FLD_MOD(base, HDMI_CORE_I2CM_SDA_HOLD_ADDR, v & 0xff, 7, 0); + +	REG_FLD_MOD(base, HDMI_CORE_I2CM_SLAVE, 0x50, 6, 0); +	REG_FLD_MOD(base, HDMI_CORE_I2CM_SEGADDR, 0x30, 6, 0); + +	/* NACK_POL to high */ +	REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 7, 7); + +	/* NACK_MASK to unmasked */ +	REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x0, 6, 6); + +	/* ARBITRATION_POL to high */ +	REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 3, 3); + +	/* ARBITRATION_MASK to unmasked */ +	REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x0, 2, 2); + +	/* DONE_POL to high */ +	REG_FLD_MOD(base, HDMI_CORE_I2CM_INT, 0x1, 3, 3); + +	/* DONE_MASK to unmasked */ +	REG_FLD_MOD(base, HDMI_CORE_I2CM_INT, 0x0, 2, 2); +} + +static void hdmi_core_ddc_uninit(struct hdmi_core_data *core) +{ +	void __iomem *base = core->base; + +	/* Mask I2C interrupts */ +	REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 6, 6); +	REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 2, 2); +	REG_FLD_MOD(base, HDMI_CORE_I2CM_INT, 0x1, 2, 2); +} + +static int hdmi_core_ddc_edid(struct hdmi_core_data *core, u8 *pedid, u8 ext) +{ +	void __iomem *base = core->base; +	u8 cur_addr; +	char checksum = 0; +	const int retries = 1000; +	u8 seg_ptr = ext / 2; +	u8 edidbase = ((ext % 2) * 0x80); + +	REG_FLD_MOD(base, HDMI_CORE_I2CM_SEGPTR, seg_ptr, 7, 0); + +	/* +	 * TODO: We use polling here, although we probably should use proper +	 * interrupts. +	 */ +	for (cur_addr = 0; cur_addr < 128; ++cur_addr) { +		int i; + +		/* clear ERROR and DONE */ +		REG_FLD_MOD(base, HDMI_CORE_IH_I2CM_STAT0, 0x3, 1, 0); + +		REG_FLD_MOD(base, HDMI_CORE_I2CM_ADDRESS, +				edidbase + cur_addr, 7, 0); + +		if (seg_ptr) +			REG_FLD_MOD(base, HDMI_CORE_I2CM_OPERATION, 1, 1, 1); +		else +			REG_FLD_MOD(base, HDMI_CORE_I2CM_OPERATION, 1, 0, 0); + +		for (i = 0; i < retries; ++i) { +			u32 stat; + +			stat = REG_GET(base, HDMI_CORE_IH_I2CM_STAT0, 1, 0); + +			/* I2CM_ERROR */ +			if (stat & 1) { +				DSSERR("HDMI I2C Master Error\n"); +				return -EIO; +			} + +			/* I2CM_DONE */ +			if (stat & (1 << 1)) +				break; + +			usleep_range(250, 1000); +		} + +		if (i == retries) { +			DSSERR("HDMI I2C timeout reading EDID\n"); +			return -EIO; +		} + +		pedid[cur_addr] = REG_GET(base, HDMI_CORE_I2CM_DATAI, 7, 0); +		checksum += pedid[cur_addr]; +	} + +	return 0; + +} + +int hdmi5_read_edid(struct hdmi_core_data *core, u8 *edid, int len) +{ +	int r, n, i; +	int max_ext_blocks = (len / 128) - 1; + +	if (len < 128) +		return -EINVAL; + +	hdmi_core_ddc_init(core); + +	r = hdmi_core_ddc_edid(core, edid, 0); +	if (r) +		goto out; + +	n = edid[0x7e]; + +	if (n > max_ext_blocks) +		n = max_ext_blocks; + +	for (i = 1; i <= n; i++) { +		r = hdmi_core_ddc_edid(core, edid + i * EDID_LENGTH, i); +		if (r) +			goto out; +	} + +out: +	hdmi_core_ddc_uninit(core); + +	return r ? r : len; +} + +void hdmi5_core_dump(struct hdmi_core_data *core, struct seq_file *s) +{ + +#define DUMPCORE(r) seq_printf(s, "%-35s %08x\n", #r,\ +		hdmi_read_reg(core->base, r)) + +	DUMPCORE(HDMI_CORE_FC_INVIDCONF); +	DUMPCORE(HDMI_CORE_FC_INHACTIV0); +	DUMPCORE(HDMI_CORE_FC_INHACTIV1); +	DUMPCORE(HDMI_CORE_FC_INHBLANK0); +	DUMPCORE(HDMI_CORE_FC_INHBLANK1); +	DUMPCORE(HDMI_CORE_FC_INVACTIV0); +	DUMPCORE(HDMI_CORE_FC_INVACTIV1); +	DUMPCORE(HDMI_CORE_FC_INVBLANK); +	DUMPCORE(HDMI_CORE_FC_HSYNCINDELAY0); +	DUMPCORE(HDMI_CORE_FC_HSYNCINDELAY1); +	DUMPCORE(HDMI_CORE_FC_HSYNCINWIDTH0); +	DUMPCORE(HDMI_CORE_FC_HSYNCINWIDTH1); +	DUMPCORE(HDMI_CORE_FC_VSYNCINDELAY); +	DUMPCORE(HDMI_CORE_FC_VSYNCINWIDTH); +	DUMPCORE(HDMI_CORE_FC_CTRLDUR); +	DUMPCORE(HDMI_CORE_FC_EXCTRLDUR); +	DUMPCORE(HDMI_CORE_FC_EXCTRLSPAC); +	DUMPCORE(HDMI_CORE_FC_CH0PREAM); +	DUMPCORE(HDMI_CORE_FC_CH1PREAM); +	DUMPCORE(HDMI_CORE_FC_CH2PREAM); +	DUMPCORE(HDMI_CORE_FC_AVICONF0); +	DUMPCORE(HDMI_CORE_FC_AVICONF1); +	DUMPCORE(HDMI_CORE_FC_AVICONF2); +	DUMPCORE(HDMI_CORE_FC_AVIVID); +	DUMPCORE(HDMI_CORE_FC_PRCONF); + +	DUMPCORE(HDMI_CORE_MC_CLKDIS); +	DUMPCORE(HDMI_CORE_MC_SWRSTZREQ); +	DUMPCORE(HDMI_CORE_MC_FLOWCTRL); +	DUMPCORE(HDMI_CORE_MC_PHYRSTZ); +	DUMPCORE(HDMI_CORE_MC_LOCKONCLOCK); + +	DUMPCORE(HDMI_CORE_I2CM_SLAVE); +	DUMPCORE(HDMI_CORE_I2CM_ADDRESS); +	DUMPCORE(HDMI_CORE_I2CM_DATAO); +	DUMPCORE(HDMI_CORE_I2CM_DATAI); +	DUMPCORE(HDMI_CORE_I2CM_OPERATION); +	DUMPCORE(HDMI_CORE_I2CM_INT); +	DUMPCORE(HDMI_CORE_I2CM_CTLINT); +	DUMPCORE(HDMI_CORE_I2CM_DIV); +	DUMPCORE(HDMI_CORE_I2CM_SEGADDR); +	DUMPCORE(HDMI_CORE_I2CM_SOFTRSTZ); +	DUMPCORE(HDMI_CORE_I2CM_SEGPTR); +	DUMPCORE(HDMI_CORE_I2CM_SS_SCL_HCNT_1_ADDR); +	DUMPCORE(HDMI_CORE_I2CM_SS_SCL_HCNT_0_ADDR); +	DUMPCORE(HDMI_CORE_I2CM_SS_SCL_LCNT_1_ADDR); +	DUMPCORE(HDMI_CORE_I2CM_SS_SCL_LCNT_0_ADDR); +	DUMPCORE(HDMI_CORE_I2CM_FS_SCL_HCNT_1_ADDR); +	DUMPCORE(HDMI_CORE_I2CM_FS_SCL_HCNT_0_ADDR); +	DUMPCORE(HDMI_CORE_I2CM_FS_SCL_LCNT_1_ADDR); +	DUMPCORE(HDMI_CORE_I2CM_FS_SCL_LCNT_0_ADDR); +	DUMPCORE(HDMI_CORE_I2CM_SDA_HOLD_ADDR); +} + +static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg, +			struct hdmi_core_infoframe_avi *avi_cfg, +			struct hdmi_config *cfg) +{ +	DSSDBG("hdmi_core_init\n"); + +	/* video core */ +	video_cfg->data_enable_pol = 1; /* It is always 1*/ +	video_cfg->v_fc_config.timings.hsync_level = cfg->timings.hsync_level; +	video_cfg->v_fc_config.timings.x_res = cfg->timings.x_res; +	video_cfg->v_fc_config.timings.hsw = cfg->timings.hsw - 1; +	video_cfg->v_fc_config.timings.hbp = cfg->timings.hbp; +	video_cfg->v_fc_config.timings.hfp = cfg->timings.hfp; +	video_cfg->hblank = cfg->timings.hfp + +				cfg->timings.hbp + cfg->timings.hsw - 1; +	video_cfg->v_fc_config.timings.vsync_level = cfg->timings.vsync_level; +	video_cfg->v_fc_config.timings.y_res = cfg->timings.y_res; +	video_cfg->v_fc_config.timings.vsw = cfg->timings.vsw; +	video_cfg->v_fc_config.timings.vfp = cfg->timings.vfp; +	video_cfg->v_fc_config.timings.vbp = cfg->timings.vbp; +	video_cfg->vblank_osc = 0; /* Always 0 - need to confirm */ +	video_cfg->vblank = cfg->timings.vsw + +				cfg->timings.vfp + cfg->timings.vbp; +	video_cfg->v_fc_config.cm.mode = cfg->cm.mode; +	video_cfg->v_fc_config.timings.interlace = cfg->timings.interlace; + +	/* info frame */ +	avi_cfg->db1_format = 0; +	avi_cfg->db1_active_info = 0; +	avi_cfg->db1_bar_info_dv = 0; +	avi_cfg->db1_scan_info = 0; +	avi_cfg->db2_colorimetry = 0; +	avi_cfg->db2_aspect_ratio = 0; +	avi_cfg->db2_active_fmt_ar = 0; +	avi_cfg->db3_itc = 0; +	avi_cfg->db3_ec = 0; +	avi_cfg->db3_q_range = 0; +	avi_cfg->db3_nup_scaling = 0; +	avi_cfg->db4_videocode = 0; +	avi_cfg->db5_pixel_repeat = 0; +	avi_cfg->db6_7_line_eoftop = 0; +	avi_cfg->db8_9_line_sofbottom = 0; +	avi_cfg->db10_11_pixel_eofleft = 0; +	avi_cfg->db12_13_pixel_sofright = 0; +} + +/* DSS_HDMI_CORE_VIDEO_CONFIG */ +static void hdmi_core_video_config(struct hdmi_core_data *core, +			struct hdmi_core_vid_config *cfg) +{ +	void __iomem *base = core->base; +	unsigned char r = 0; +	bool vsync_pol, hsync_pol; + +	vsync_pol = +		cfg->v_fc_config.timings.vsync_level == OMAPDSS_SIG_ACTIVE_HIGH; +	hsync_pol = +		cfg->v_fc_config.timings.hsync_level == OMAPDSS_SIG_ACTIVE_HIGH; + +	/* Set hsync, vsync and data-enable polarity  */ +	r = hdmi_read_reg(base, HDMI_CORE_FC_INVIDCONF); +	r = FLD_MOD(r, vsync_pol, 6, 6); +	r = FLD_MOD(r, hsync_pol, 5, 5); +	r = FLD_MOD(r, cfg->data_enable_pol, 4, 4); +	r = FLD_MOD(r, cfg->vblank_osc, 1, 1); +	r = FLD_MOD(r, cfg->v_fc_config.timings.interlace, 0, 0); +	hdmi_write_reg(base, HDMI_CORE_FC_INVIDCONF, r); + +	/* set x resolution */ +	REG_FLD_MOD(base, HDMI_CORE_FC_INHACTIV1, +			cfg->v_fc_config.timings.x_res >> 8, 4, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_INHACTIV0, +			cfg->v_fc_config.timings.x_res & 0xFF, 7, 0); + +	/* set y resolution */ +	REG_FLD_MOD(base, HDMI_CORE_FC_INVACTIV1, +			cfg->v_fc_config.timings.y_res >> 8, 4, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_INVACTIV0, +			cfg->v_fc_config.timings.y_res & 0xFF, 7, 0); + +	/* set horizontal blanking pixels */ +	REG_FLD_MOD(base, HDMI_CORE_FC_INHBLANK1, cfg->hblank >> 8, 4, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_INHBLANK0, cfg->hblank & 0xFF, 7, 0); + +	/* set vertial blanking pixels */ +	REG_FLD_MOD(base, HDMI_CORE_FC_INVBLANK, cfg->vblank, 7, 0); + +	/* set horizontal sync offset */ +	REG_FLD_MOD(base, HDMI_CORE_FC_HSYNCINDELAY1, +			cfg->v_fc_config.timings.hfp >> 8, 4, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_HSYNCINDELAY0, +			cfg->v_fc_config.timings.hfp & 0xFF, 7, 0); + +	/* set vertical sync offset */ +	REG_FLD_MOD(base, HDMI_CORE_FC_VSYNCINDELAY, +			cfg->v_fc_config.timings.vfp, 7, 0); + +	/* set horizontal sync pulse width */ +	REG_FLD_MOD(base, HDMI_CORE_FC_HSYNCINWIDTH1, +			(cfg->v_fc_config.timings.hsw >> 8), 1, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_HSYNCINWIDTH0, +			cfg->v_fc_config.timings.hsw & 0xFF, 7, 0); + +	/*  set vertical sync pulse width */ +	REG_FLD_MOD(base, HDMI_CORE_FC_VSYNCINWIDTH, +			cfg->v_fc_config.timings.vsw, 5, 0); + +	/* select DVI mode */ +	REG_FLD_MOD(base, HDMI_CORE_FC_INVIDCONF, +			cfg->v_fc_config.cm.mode, 3, 3); +} + +static void hdmi_core_config_video_packetizer(struct hdmi_core_data *core) +{ +	void __iomem *base = core->base; +	int clr_depth = 0;	/* 24 bit color depth */ + +	/* COLOR_DEPTH */ +	REG_FLD_MOD(base, HDMI_CORE_VP_PR_CD, clr_depth, 7, 4); +	/* BYPASS_EN */ +	REG_FLD_MOD(base, HDMI_CORE_VP_CONF, clr_depth ? 0 : 1, 6, 6); +	/* PP_EN */ +	REG_FLD_MOD(base, HDMI_CORE_VP_CONF, clr_depth ? 1 : 0, 5, 5); +	/* YCC422_EN */ +	REG_FLD_MOD(base, HDMI_CORE_VP_CONF, 0, 3, 3); +	/* PP_STUFFING */ +	REG_FLD_MOD(base, HDMI_CORE_VP_STUFF, clr_depth ? 1 : 0, 1, 1); +	/* YCC422_STUFFING */ +	REG_FLD_MOD(base, HDMI_CORE_VP_STUFF, 1, 2, 2); +	/* OUTPUT_SELECTOR */ +	REG_FLD_MOD(base, HDMI_CORE_VP_CONF, clr_depth ? 0 : 2, 1, 0); +} + +static void hdmi_core_config_csc(struct hdmi_core_data *core) +{ +	int clr_depth = 0;	/* 24 bit color depth */ + +	/* CSC_COLORDEPTH */ +	REG_FLD_MOD(core->base, HDMI_CORE_CSC_SCALE, clr_depth, 7, 4); +} + +static void hdmi_core_config_video_sampler(struct hdmi_core_data *core) +{ +	int video_mapping = 1;	/* for 24 bit color depth */ + +	/* VIDEO_MAPPING */ +	REG_FLD_MOD(core->base, HDMI_CORE_TX_INVID0, video_mapping, 4, 0); +} + +static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core) +{ +	void __iomem *base = core->base; +	struct hdmi_core_infoframe_avi avi = core->avi_cfg; + +	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_format, 1, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_active_info, 6, 6); +	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_bar_info_dv, 3, 2); +	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_scan_info, 5, 4); +	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_colorimetry, 7, 6); +	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_aspect_ratio, 5, 4); +	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_active_fmt_ar, 3, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_itc, 7, 7); +	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_ec, 6, 4); +	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_q_range, 3, 2); +	REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_nup_scaling, 1, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_AVIVID, avi.db4_videocode, 6, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_PRCONF, avi.db5_pixel_repeat, 3, 0); +} + +static void hdmi_core_csc_config(struct hdmi_core_data *core, +		struct csc_table csc_coeff) +{ +	void __iomem *base = core->base; + +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A1_MSB, csc_coeff.a1 >> 8 , 6, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A1_LSB, csc_coeff.a1, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A2_MSB, csc_coeff.a2 >> 8, 6, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A2_LSB, csc_coeff.a2, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A3_MSB, csc_coeff.a3 >> 8, 6, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A3_LSB, csc_coeff.a3, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A4_MSB, csc_coeff.a4 >> 8, 6, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_A4_LSB, csc_coeff.a4, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B1_MSB, csc_coeff.b1 >> 8, 6, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B1_LSB, csc_coeff.b1, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B2_MSB, csc_coeff.b2 >> 8, 6, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B2_LSB, csc_coeff.b2, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B3_MSB, csc_coeff.b3 >> 8, 6, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B3_LSB, csc_coeff.b3, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B4_MSB, csc_coeff.b4 >> 8, 6, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_B4_LSB, csc_coeff.b4, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C1_MSB, csc_coeff.c1 >> 8, 6, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C1_LSB, csc_coeff.c1, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C2_MSB, csc_coeff.c2 >> 8, 6, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C2_LSB, csc_coeff.c2, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C3_MSB, csc_coeff.c3 >> 8, 6, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C3_LSB, csc_coeff.c3, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C4_MSB, csc_coeff.c4 >> 8, 6, 0); +	REG_FLD_MOD(base, HDMI_CORE_CSC_COEF_C4_LSB, csc_coeff.c4, 7, 0); + +	REG_FLD_MOD(base, HDMI_CORE_MC_FLOWCTRL, 0x1, 0, 0); +} + +static void hdmi_core_configure_range(struct hdmi_core_data *core) +{ +	struct csc_table csc_coeff = { 0 }; + +	/* support limited range with 24 bit color depth for now */ +	csc_coeff = csc_table_deepcolor[0]; +	core->avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_LR; + +	hdmi_core_csc_config(core, csc_coeff); +	hdmi_core_aux_infoframe_avi_config(core); +} + +static void hdmi_core_enable_video_path(struct hdmi_core_data *core) +{ +	void __iomem *base = core->base; + +	DSSDBG("hdmi_core_enable_video_path\n"); + +	REG_FLD_MOD(base, HDMI_CORE_FC_CTRLDUR, 0x0C, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_EXCTRLDUR, 0x20, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_EXCTRLSPAC, 0x01, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_CH0PREAM, 0x0B, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_CH1PREAM, 0x16, 5, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_CH2PREAM, 0x21, 5, 0); +	REG_FLD_MOD(base, HDMI_CORE_MC_CLKDIS, 0x00, 0, 0); +	REG_FLD_MOD(base, HDMI_CORE_MC_CLKDIS, 0x00, 1, 1); +} + +static void hdmi_core_mask_interrupts(struct hdmi_core_data *core) +{ +	void __iomem *base = core->base; + +	/* Master IRQ mask */ +	REG_FLD_MOD(base, HDMI_CORE_IH_MUTE, 0x3, 1, 0); + +	/* Mask all the interrupts in HDMI core */ + +	REG_FLD_MOD(base, HDMI_CORE_VP_MASK, 0xff, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_MASK0, 0xe7, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_MASK1, 0xfb, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_MASK2, 0x3, 1, 0); + +	REG_FLD_MOD(base, HDMI_CORE_AUD_INT, 0x3, 3, 2); +	REG_FLD_MOD(base, HDMI_CORE_AUD_GP_MASK, 0x3, 1, 0); + +	REG_FLD_MOD(base, HDMI_CORE_CEC_MASK, 0x7f, 6, 0); + +	REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 6, 6); +	REG_FLD_MOD(base, HDMI_CORE_I2CM_CTLINT, 0x1, 2, 2); +	REG_FLD_MOD(base, HDMI_CORE_I2CM_INT, 0x1, 2, 2); + +	REG_FLD_MOD(base, HDMI_CORE_PHY_MASK0, 0xf3, 7, 0); + +	REG_FLD_MOD(base, HDMI_CORE_IH_PHY_STAT0, 0xff, 7, 0); + +	/* Clear all the current interrupt bits */ + +	REG_FLD_MOD(base, HDMI_CORE_IH_VP_STAT0, 0xff, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT0, 0xe7, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT1, 0xfb, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT2, 0x3, 1, 0); + +	REG_FLD_MOD(base, HDMI_CORE_IH_AS_STAT0, 0x7, 2, 0); + +	REG_FLD_MOD(base, HDMI_CORE_IH_CEC_STAT0, 0x7f, 6, 0); + +	REG_FLD_MOD(base, HDMI_CORE_IH_I2CM_STAT0, 0x3, 1, 0); + +	REG_FLD_MOD(base, HDMI_CORE_IH_PHY_STAT0, 0xff, 7, 0); +} + +static void hdmi_core_enable_interrupts(struct hdmi_core_data *core) +{ +	/* Unmute interrupts */ +	REG_FLD_MOD(core->base, HDMI_CORE_IH_MUTE, 0x0, 1, 0); +} + +int hdmi5_core_handle_irqs(struct hdmi_core_data *core) +{ +	void __iomem *base = core->base; + +	REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT0, 0xff, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT1, 0xff, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_IH_FC_STAT2, 0xff, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_IH_AS_STAT0, 0xff, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_IH_PHY_STAT0, 0xff, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_IH_I2CM_STAT0, 0xff, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_IH_CEC_STAT0, 0xff, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_IH_VP_STAT0, 0xff, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_IH_I2CMPHY_STAT0, 0xff, 7, 0); + +	return 0; +} + +void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, +		struct hdmi_config *cfg) +{ +	struct omap_video_timings video_timing; +	struct hdmi_video_format video_format; +	struct hdmi_core_vid_config v_core_cfg; +	struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg; + +	hdmi_core_mask_interrupts(core); + +	hdmi_core_init(&v_core_cfg, avi_cfg, cfg); + +	hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg); + +	hdmi_wp_video_config_timing(wp, &video_timing); + +	/* video config */ +	video_format.packing_mode = HDMI_PACK_24b_RGB_YUV444_YUV422; + +	hdmi_wp_video_config_format(wp, &video_format); + +	hdmi_wp_video_config_interface(wp, &video_timing); + +	hdmi_core_configure_range(core); + +	/* +	 * configure core video part, set software reset in the core +	 */ +	v_core_cfg.packet_mode = HDMI_PACKETMODE24BITPERPIXEL; + +	hdmi_core_video_config(core, &v_core_cfg); + +	hdmi_core_config_video_packetizer(core); +	hdmi_core_config_csc(core); +	hdmi_core_config_video_sampler(core); + +	/* +	 * configure packet info frame video see doc CEA861-D page 65 +	 */ +	avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB; +	avi_cfg->db1_active_info = +			HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF; +	avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO; +	avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0; +	avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO; +	avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO; +	avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME; +	avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO; +	avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601; +	avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT; +	avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO; +	avi_cfg->db4_videocode = cfg->cm.code; +	avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO; +	avi_cfg->db6_7_line_eoftop = 0; +	avi_cfg->db8_9_line_sofbottom = 0; +	avi_cfg->db10_11_pixel_eofleft = 0; +	avi_cfg->db12_13_pixel_sofright = 0; + +	hdmi_core_aux_infoframe_avi_config(core); + +	hdmi_core_enable_video_path(core); + +	hdmi_core_enable_interrupts(core); +} + + +#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) + +static void hdmi5_core_audio_config(struct hdmi_core_data *core, +			struct hdmi_core_audio_config *cfg) +{ +	void __iomem *base = core->base; +	u8 val; + +	/* Mute audio before configuring */ +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCONF, 0xf, 7, 4); + +	/* Set the N parameter */ +	REG_FLD_MOD(base, HDMI_CORE_AUD_N1, cfg->n, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_AUD_N2, cfg->n >> 8, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_AUD_N3, cfg->n >> 16, 3, 0); + +	/* +	 * CTS manual mode. Automatic mode is not supported when using audio +	 * parallel interface. +	 */ +	REG_FLD_MOD(base, HDMI_CORE_AUD_CTS3, 1, 4, 4); +	REG_FLD_MOD(base, HDMI_CORE_AUD_CTS1, cfg->cts, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_AUD_CTS2, cfg->cts >> 8, 7, 0); +	REG_FLD_MOD(base, HDMI_CORE_AUD_CTS3, cfg->cts >> 16, 3, 0); + +	/* Layout of Audio Sample Packets: 2-channel or multichannels */ +	if (cfg->layout == HDMI_AUDIO_LAYOUT_2CH) +		REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCONF, 0, 0, 0); +	else +		REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCONF, 1, 0, 0); + +	/* Configure IEC-609580 Validity bits */ +	/* Channel 0 is valid */ +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, 0, 0, 0); +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, 0, 4, 4); + +	if (cfg->layout == HDMI_AUDIO_LAYOUT_2CH) +		val = 1; +	else +		val = 0; + +	/* Channels 1, 2 setting */ +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 1, 1); +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 5, 5); +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 2, 2); +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 6, 6); +	/* Channel 3 setting */ +	if (cfg->layout == HDMI_AUDIO_LAYOUT_6CH) +		val = 1; +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 3, 3); +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSV, val, 7, 7); + +	/* Configure IEC-60958 User bits */ +	/* TODO: should be set by user. */ +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSU, 0, 7, 0); + +	/* Configure IEC-60958 Channel Status word */ +	/* CGMSA */ +	val = cfg->iec60958_cfg->status[5] & IEC958_AES5_CON_CGMSA; +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(0), val, 5, 4); + +	/* Copyright */ +	val = (cfg->iec60958_cfg->status[0] & +			IEC958_AES0_CON_NOT_COPYRIGHT) >> 2; +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(0), val, 0, 0); + +	/* Category */ +	hdmi_write_reg(base, HDMI_CORE_FC_AUDSCHNLS(1), +		cfg->iec60958_cfg->status[1]); + +	/* PCM audio mode */ +	val = (cfg->iec60958_cfg->status[0] & IEC958_AES0_CON_MODE) >> 6; +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(2), val, 6, 4); + +	/* Source number */ +	val = cfg->iec60958_cfg->status[2] & IEC958_AES2_CON_SOURCE; +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(2), val, 3, 4); + +	/* Channel number right 0  */ +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(3), 2, 3, 0); +	/* Channel number right 1*/ +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(3), 4, 7, 4); +	/* Channel number right 2  */ +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(4), 6, 3, 0); +	/* Channel number right 3*/ +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(4), 8, 7, 4); +	/* Channel number left 0  */ +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(5), 1, 3, 0); +	/* Channel number left 1*/ +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(5), 3, 7, 4); +	/* Channel number left 2  */ +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(6), 5, 3, 0); +	/* Channel number left 3*/ +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCHNLS(6), 7, 7, 4); + +	/* Clock accuracy and sample rate */ +	hdmi_write_reg(base, HDMI_CORE_FC_AUDSCHNLS(7), +		cfg->iec60958_cfg->status[3]); + +	/* Original sample rate and word length */ +	hdmi_write_reg(base, HDMI_CORE_FC_AUDSCHNLS(8), +		cfg->iec60958_cfg->status[4]); + +	/* Enable FIFO empty and full interrupts */ +	REG_FLD_MOD(base, HDMI_CORE_AUD_INT, 3, 3, 2); + +	/* Configure GPA */ +	/* select HBR/SPDIF interfaces */ +	if (cfg->layout == HDMI_AUDIO_LAYOUT_2CH) { +		/* select HBR/SPDIF interfaces */ +		REG_FLD_MOD(base, HDMI_CORE_AUD_CONF0, 0, 5, 5); +		/* enable two channels in GPA */ +		REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF1, 3, 7, 0); +	} else if (cfg->layout == HDMI_AUDIO_LAYOUT_6CH) { +		/* select HBR/SPDIF interfaces */ +		REG_FLD_MOD(base, HDMI_CORE_AUD_CONF0, 0, 5, 5); +		/* enable six channels in GPA */ +		REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF1, 0x3F, 7, 0); +	} else { +		/* select HBR/SPDIF interfaces */ +		REG_FLD_MOD(base, HDMI_CORE_AUD_CONF0, 0, 5, 5); +		/* enable eight channels in GPA */ +		REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF1, 0xFF, 7, 0); +	} + +	/* disable HBR */ +	REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF2, 0, 0, 0); +	/* enable PCUV */ +	REG_FLD_MOD(base, HDMI_CORE_AUD_GP_CONF2, 1, 1, 1); +	/* enable GPA FIFO full and empty mask */ +	REG_FLD_MOD(base, HDMI_CORE_AUD_GP_MASK, 3, 1, 0); +	/* set polarity of GPA FIFO empty interrupts */ +	REG_FLD_MOD(base, HDMI_CORE_AUD_GP_POL, 1, 0, 0); + +	/* unmute audio */ +	REG_FLD_MOD(base, HDMI_CORE_FC_AUDSCONF, 0, 7, 4); +} + +static void hdmi5_core_audio_infoframe_cfg(struct hdmi_core_data *core, +	 struct snd_cea_861_aud_if *info_aud) +{ +	void __iomem *base = core->base; + +	/* channel count and coding type fields in AUDICONF0 are swapped */ +	hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF0, +		(info_aud->db1_ct_cc & CEA861_AUDIO_INFOFRAME_DB1CC) << 4 | +		(info_aud->db1_ct_cc & CEA861_AUDIO_INFOFRAME_DB1CT) >> 4); + +	hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF1, info_aud->db2_sf_ss); +	hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF2, info_aud->db4_ca); +	hdmi_write_reg(base, HDMI_CORE_FC_AUDICONF3, info_aud->db5_dminh_lsv); +} + +int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, +			struct omap_dss_audio *audio, u32 pclk) +{ +	struct hdmi_audio_format audio_format; +	struct hdmi_audio_dma audio_dma; +	struct hdmi_core_audio_config core_cfg; +	int err, n, cts, channel_count; +	unsigned int fs_nr; +	bool word_length_16b = false; + +	if (!audio || !audio->iec || !audio->cea || !core) +		return -EINVAL; + +	core_cfg.iec60958_cfg = audio->iec; + +	if (!(audio->iec->status[4] & IEC958_AES4_CON_MAX_WORDLEN_24) && +		(audio->iec->status[4] & IEC958_AES4_CON_WORDLEN_20_16)) +			word_length_16b = true; + +	/* only 16-bit word length supported atm */ +	if (!word_length_16b) +		return -EINVAL; + +	switch (audio->iec->status[3] & IEC958_AES3_CON_FS) { +	case IEC958_AES3_CON_FS_32000: +		fs_nr = 32000; +		break; +	case IEC958_AES3_CON_FS_44100: +		fs_nr = 44100; +		break; +	case IEC958_AES3_CON_FS_48000: +		fs_nr = 48000; +		break; +	case IEC958_AES3_CON_FS_88200: +		fs_nr = 88200; +		break; +	case IEC958_AES3_CON_FS_96000: +		fs_nr = 96000; +		break; +	case IEC958_AES3_CON_FS_176400: +		fs_nr = 176400; +		break; +	case IEC958_AES3_CON_FS_192000: +		fs_nr = 192000; +		break; +	default: +		return -EINVAL; +	} + +	err = hdmi_compute_acr(pclk, fs_nr, &n, &cts); +	core_cfg.n = n; +	core_cfg.cts = cts; + +	/* Audio channels settings */ +	channel_count = (audio->cea->db1_ct_cc & CEA861_AUDIO_INFOFRAME_DB1CC) +				+ 1; + +	if (channel_count == 2) +		core_cfg.layout = HDMI_AUDIO_LAYOUT_2CH; +	else if (channel_count == 6) +		core_cfg.layout = HDMI_AUDIO_LAYOUT_6CH; +	else +		core_cfg.layout = HDMI_AUDIO_LAYOUT_8CH; + +	/* DMA settings */ +	if (word_length_16b) +		audio_dma.transfer_size = 0x10; +	else +		audio_dma.transfer_size = 0x20; +	audio_dma.block_size = 0xC0; +	audio_dma.mode = HDMI_AUDIO_TRANSF_DMA; +	audio_dma.fifo_threshold = 0x20; /* in number of samples */ + +	/* audio FIFO format settings for 16-bit samples*/ +	audio_format.samples_per_word = HDMI_AUDIO_ONEWORD_TWOSAMPLES; +	audio_format.sample_size = HDMI_AUDIO_SAMPLE_16BITS; +	audio_format.justification = HDMI_AUDIO_JUSTIFY_LEFT; + +	/* only LPCM atm */ +	audio_format.type = HDMI_AUDIO_TYPE_LPCM; + +	/* disable start/stop signals of IEC 60958 blocks */ +	audio_format.en_sig_blk_strt_end = HDMI_AUDIO_BLOCK_SIG_STARTEND_ON; + +	/* configure DMA and audio FIFO format*/ +	hdmi_wp_audio_config_dma(wp, &audio_dma); +	hdmi_wp_audio_config_format(wp, &audio_format); + +	/* configure the core */ +	hdmi5_core_audio_config(core, &core_cfg); + +	/* configure CEA 861 audio infoframe */ +	hdmi5_core_audio_infoframe_cfg(core, audio->cea); + +	return 0; +} +#endif + +int hdmi5_core_init(struct platform_device *pdev, struct hdmi_core_data *core) +{ +	struct resource *res; + +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "core"); +	if (!res) { +		DSSERR("can't get CORE IORESOURCE_MEM HDMI\n"); +		return -EINVAL; +	} + +	core->base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(core->base)) { +		DSSERR("can't ioremap HDMI core\n"); +		return PTR_ERR(core->base); +	} + +	return 0; +} diff --git a/drivers/video/fbdev/omap2/dss/hdmi5_core.h b/drivers/video/fbdev/omap2/dss/hdmi5_core.h new file mode 100644 index 00000000000..ce7e9f376f0 --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/hdmi5_core.h @@ -0,0 +1,306 @@ +/* + * HDMI driver definition for TI OMAP5 processors. + * + * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef _HDMI5_CORE_H_ +#define _HDMI5_CORE_H_ + +#include "hdmi.h" + +/* HDMI IP Core System */ + +/* HDMI Identification */ +#define HDMI_CORE_DESIGN_ID			0x00000 +#define HDMI_CORE_REVISION_ID			0x00004 +#define HDMI_CORE_PRODUCT_ID0			0x00008 +#define HDMI_CORE_PRODUCT_ID1			0x0000C +#define HDMI_CORE_CONFIG0_ID			0x00010 +#define HDMI_CORE_CONFIG1_ID			0x00014 +#define HDMI_CORE_CONFIG2_ID			0x00018 +#define HDMI_CORE_CONFIG3_ID			0x0001C + +/* HDMI Interrupt */ +#define HDMI_CORE_IH_FC_STAT0			0x00400 +#define HDMI_CORE_IH_FC_STAT1			0x00404 +#define HDMI_CORE_IH_FC_STAT2			0x00408 +#define HDMI_CORE_IH_AS_STAT0			0x0040C +#define HDMI_CORE_IH_PHY_STAT0			0x00410 +#define HDMI_CORE_IH_I2CM_STAT0			0x00414 +#define HDMI_CORE_IH_CEC_STAT0			0x00418 +#define HDMI_CORE_IH_VP_STAT0			0x0041C +#define HDMI_CORE_IH_I2CMPHY_STAT0		0x00420 +#define HDMI_CORE_IH_MUTE			0x007FC + +/* HDMI Video Sampler */ +#define HDMI_CORE_TX_INVID0			0x00800 +#define HDMI_CORE_TX_INSTUFFING			0x00804 +#define HDMI_CORE_TX_RGYDATA0			0x00808 +#define HDMI_CORE_TX_RGYDATA1			0x0080C +#define HDMI_CORE_TX_RCRDATA0			0x00810 +#define HDMI_CORE_TX_RCRDATA1			0x00814 +#define HDMI_CORE_TX_BCBDATA0			0x00818 +#define HDMI_CORE_TX_BCBDATA1			0x0081C + +/* HDMI Video Packetizer */ +#define HDMI_CORE_VP_STATUS			0x02000 +#define HDMI_CORE_VP_PR_CD			0x02004 +#define HDMI_CORE_VP_STUFF			0x02008 +#define HDMI_CORE_VP_REMAP			0x0200C +#define HDMI_CORE_VP_CONF			0x02010 +#define HDMI_CORE_VP_STAT			0x02014 +#define HDMI_CORE_VP_INT			0x02018 +#define HDMI_CORE_VP_MASK			0x0201C +#define HDMI_CORE_VP_POL			0x02020 + +/* Frame Composer */ +#define HDMI_CORE_FC_INVIDCONF			0x04000 +#define HDMI_CORE_FC_INHACTIV0			0x04004 +#define HDMI_CORE_FC_INHACTIV1			0x04008 +#define HDMI_CORE_FC_INHBLANK0			0x0400C +#define HDMI_CORE_FC_INHBLANK1			0x04010 +#define HDMI_CORE_FC_INVACTIV0			0x04014 +#define HDMI_CORE_FC_INVACTIV1			0x04018 +#define HDMI_CORE_FC_INVBLANK			0x0401C +#define HDMI_CORE_FC_HSYNCINDELAY0		0x04020 +#define HDMI_CORE_FC_HSYNCINDELAY1		0x04024 +#define HDMI_CORE_FC_HSYNCINWIDTH0		0x04028 +#define HDMI_CORE_FC_HSYNCINWIDTH1		0x0402C +#define HDMI_CORE_FC_VSYNCINDELAY		0x04030 +#define HDMI_CORE_FC_VSYNCINWIDTH		0x04034 +#define HDMI_CORE_FC_INFREQ0			0x04038 +#define HDMI_CORE_FC_INFREQ1			0x0403C +#define HDMI_CORE_FC_INFREQ2			0x04040 +#define HDMI_CORE_FC_CTRLDUR			0x04044 +#define HDMI_CORE_FC_EXCTRLDUR			0x04048 +#define HDMI_CORE_FC_EXCTRLSPAC			0x0404C +#define HDMI_CORE_FC_CH0PREAM			0x04050 +#define HDMI_CORE_FC_CH1PREAM			0x04054 +#define HDMI_CORE_FC_CH2PREAM			0x04058 +#define HDMI_CORE_FC_AVICONF3			0x0405C +#define HDMI_CORE_FC_GCP			0x04060 +#define HDMI_CORE_FC_AVICONF0			0x04064 +#define HDMI_CORE_FC_AVICONF1			0x04068 +#define HDMI_CORE_FC_AVICONF2			0x0406C +#define HDMI_CORE_FC_AVIVID			0x04070 +#define HDMI_CORE_FC_AVIETB0			0x04074 +#define HDMI_CORE_FC_AVIETB1			0x04078 +#define HDMI_CORE_FC_AVISBB0			0x0407C +#define HDMI_CORE_FC_AVISBB1			0x04080 +#define HDMI_CORE_FC_AVIELB0			0x04084 +#define HDMI_CORE_FC_AVIELB1			0x04088 +#define HDMI_CORE_FC_AVISRB0			0x0408C +#define HDMI_CORE_FC_AVISRB1			0x04090 +#define HDMI_CORE_FC_AUDICONF0			0x04094 +#define HDMI_CORE_FC_AUDICONF1			0x04098 +#define HDMI_CORE_FC_AUDICONF2			0x0409C +#define HDMI_CORE_FC_AUDICONF3			0x040A0 +#define HDMI_CORE_FC_VSDIEEEID0			0x040A4 +#define HDMI_CORE_FC_VSDSIZE			0x040A8 +#define HDMI_CORE_FC_VSDIEEEID1			0x040C0 +#define HDMI_CORE_FC_VSDIEEEID2			0x040C4 +#define HDMI_CORE_FC_VSDPAYLOAD(n)		(n * 4 + 0x040C8) +#define HDMI_CORE_FC_SPDVENDORNAME(n)		(n * 4 + 0x04128) +#define HDMI_CORE_FC_SPDPRODUCTNAME(n)		(n * 4 + 0x04148) +#define HDMI_CORE_FC_SPDDEVICEINF		0x04188 +#define HDMI_CORE_FC_AUDSCONF			0x0418C +#define HDMI_CORE_FC_AUDSSTAT			0x04190 +#define HDMI_CORE_FC_AUDSV			0x04194 +#define HDMI_CORE_FC_AUDSU			0x04198 +#define HDMI_CORE_FC_AUDSCHNLS(n)		(n * 4 + 0x0419C) +#define HDMI_CORE_FC_CTRLQHIGH			0x041CC +#define HDMI_CORE_FC_CTRLQLOW			0x041D0 +#define HDMI_CORE_FC_ACP0			0x041D4 +#define HDMI_CORE_FC_ACP(n)			((16-n) * 4 + 0x04208) +#define HDMI_CORE_FC_ISCR1_0			0x04248 +#define HDMI_CORE_FC_ISCR1(n)			((16-n) * 4 + 0x0424C) +#define HDMI_CORE_FC_ISCR2(n)			((15-n) * 4 + 0x0428C) +#define HDMI_CORE_FC_DATAUTO0			0x042CC +#define HDMI_CORE_FC_DATAUTO1			0x042D0 +#define HDMI_CORE_FC_DATAUTO2			0x042D4 +#define HDMI_CORE_FC_DATMAN			0x042D8 +#define HDMI_CORE_FC_DATAUTO3			0x042DC +#define HDMI_CORE_FC_RDRB(n)			(n * 4 + 0x042E0) +#define HDMI_CORE_FC_STAT0			0x04340 +#define HDMI_CORE_FC_INT0			0x04344 +#define HDMI_CORE_FC_MASK0			0x04348 +#define HDMI_CORE_FC_POL0			0x0434C +#define HDMI_CORE_FC_STAT1			0x04350 +#define HDMI_CORE_FC_INT1			0x04354 +#define HDMI_CORE_FC_MASK1			0x04358 +#define HDMI_CORE_FC_POL1			0x0435C +#define HDMI_CORE_FC_STAT2			0x04360 +#define HDMI_CORE_FC_INT2			0x04364 +#define HDMI_CORE_FC_MASK2			0x04368 +#define HDMI_CORE_FC_POL2			0x0436C +#define HDMI_CORE_FC_PRCONF			0x04380 +#define HDMI_CORE_FC_GMD_STAT			0x04400 +#define HDMI_CORE_FC_GMD_EN			0x04404 +#define HDMI_CORE_FC_GMD_UP			0x04408 +#define HDMI_CORE_FC_GMD_CONF			0x0440C +#define HDMI_CORE_FC_GMD_HB			0x04410 +#define HDMI_CORE_FC_GMD_PB(n)			(n * 4 + 0x04414) +#define HDMI_CORE_FC_DBGFORCE			0x04800 +#define HDMI_CORE_FC_DBGAUD0CH0			0x04804 +#define HDMI_CORE_FC_DBGAUD1CH0			0x04808 +#define HDMI_CORE_FC_DBGAUD2CH0			0x0480C +#define HDMI_CORE_FC_DBGAUD0CH1			0x04810 +#define HDMI_CORE_FC_DBGAUD1CH1			0x04814 +#define HDMI_CORE_FC_DBGAUD2CH1			0x04818 +#define HDMI_CORE_FC_DBGAUD0CH2			0x0481C +#define HDMI_CORE_FC_DBGAUD1CH2			0x04820 +#define HDMI_CORE_FC_DBGAUD2CH2			0x04824 +#define HDMI_CORE_FC_DBGAUD0CH3			0x04828 +#define HDMI_CORE_FC_DBGAUD1CH3			0x0482C +#define HDMI_CORE_FC_DBGAUD2CH3			0x04830 +#define HDMI_CORE_FC_DBGAUD0CH4			0x04834 +#define HDMI_CORE_FC_DBGAUD1CH4			0x04838 +#define HDMI_CORE_FC_DBGAUD2CH4			0x0483C +#define HDMI_CORE_FC_DBGAUD0CH5			0x04840 +#define HDMI_CORE_FC_DBGAUD1CH5			0x04844 +#define HDMI_CORE_FC_DBGAUD2CH5			0x04848 +#define HDMI_CORE_FC_DBGAUD0CH6			0x0484C +#define HDMI_CORE_FC_DBGAUD1CH6			0x04850 +#define HDMI_CORE_FC_DBGAUD2CH6			0x04854 +#define HDMI_CORE_FC_DBGAUD0CH7			0x04858 +#define HDMI_CORE_FC_DBGAUD1CH7			0x0485C +#define HDMI_CORE_FC_DBGAUD2CH7			0x04860 +#define HDMI_CORE_FC_DBGTMDS0			0x04864 +#define HDMI_CORE_FC_DBGTMDS1			0x04868 +#define HDMI_CORE_FC_DBGTMDS2			0x0486C +#define HDMI_CORE_PHY_MASK0			0x0C018 +#define HDMI_CORE_PHY_I2CM_INT_ADDR		0x0C09C +#define HDMI_CORE_PHY_I2CM_CTLINT_ADDR		0x0C0A0 + +/* HDMI Audio */ +#define HDMI_CORE_AUD_CONF0			0x0C400 +#define HDMI_CORE_AUD_CONF1			0x0C404 +#define HDMI_CORE_AUD_INT			0x0C408 +#define HDMI_CORE_AUD_N1			0x0C800 +#define HDMI_CORE_AUD_N2			0x0C804 +#define HDMI_CORE_AUD_N3			0x0C808 +#define HDMI_CORE_AUD_CTS1			0x0C80C +#define HDMI_CORE_AUD_CTS2			0x0C810 +#define HDMI_CORE_AUD_CTS3			0x0C814 +#define HDMI_CORE_AUD_INCLKFS			0x0C818 +#define HDMI_CORE_AUD_CC08			0x0CC08 +#define HDMI_CORE_AUD_GP_CONF0			0x0D400 +#define HDMI_CORE_AUD_GP_CONF1			0x0D404 +#define HDMI_CORE_AUD_GP_CONF2			0x0D408 +#define HDMI_CORE_AUD_D010			0x0D010 +#define HDMI_CORE_AUD_GP_STAT			0x0D40C +#define HDMI_CORE_AUD_GP_INT			0x0D410 +#define HDMI_CORE_AUD_GP_POL			0x0D414 +#define HDMI_CORE_AUD_GP_MASK			0x0D418 + +/* HDMI Main Controller */ +#define HDMI_CORE_MC_CLKDIS			0x10004 +#define HDMI_CORE_MC_SWRSTZREQ			0x10008 +#define HDMI_CORE_MC_FLOWCTRL			0x10010 +#define HDMI_CORE_MC_PHYRSTZ			0x10014 +#define HDMI_CORE_MC_LOCKONCLOCK		0x10018 + +/* HDMI COLOR SPACE CONVERTER */ +#define HDMI_CORE_CSC_CFG			0x10400 +#define HDMI_CORE_CSC_SCALE			0x10404 +#define HDMI_CORE_CSC_COEF_A1_MSB		0x10408 +#define HDMI_CORE_CSC_COEF_A1_LSB		0x1040C +#define HDMI_CORE_CSC_COEF_A2_MSB		0x10410 +#define HDMI_CORE_CSC_COEF_A2_LSB		0x10414 +#define HDMI_CORE_CSC_COEF_A3_MSB		0x10418 +#define HDMI_CORE_CSC_COEF_A3_LSB		0x1041C +#define HDMI_CORE_CSC_COEF_A4_MSB		0x10420 +#define HDMI_CORE_CSC_COEF_A4_LSB		0x10424 +#define HDMI_CORE_CSC_COEF_B1_MSB		0x10428 +#define HDMI_CORE_CSC_COEF_B1_LSB		0x1042C +#define HDMI_CORE_CSC_COEF_B2_MSB		0x10430 +#define HDMI_CORE_CSC_COEF_B2_LSB		0x10434 +#define HDMI_CORE_CSC_COEF_B3_MSB		0x10438 +#define HDMI_CORE_CSC_COEF_B3_LSB		0x1043C +#define HDMI_CORE_CSC_COEF_B4_MSB		0x10440 +#define HDMI_CORE_CSC_COEF_B4_LSB		0x10444 +#define HDMI_CORE_CSC_COEF_C1_MSB		0x10448 +#define HDMI_CORE_CSC_COEF_C1_LSB		0x1044C +#define HDMI_CORE_CSC_COEF_C2_MSB		0x10450 +#define HDMI_CORE_CSC_COEF_C2_LSB		0x10454 +#define HDMI_CORE_CSC_COEF_C3_MSB		0x10458 +#define HDMI_CORE_CSC_COEF_C3_LSB		0x1045C +#define HDMI_CORE_CSC_COEF_C4_MSB		0x10460 +#define HDMI_CORE_CSC_COEF_C4_LSB		0x10464 + +/* HDMI HDCP */ +#define HDMI_CORE_HDCP_MASK			0x14020 + +/* HDMI CEC */ +#define HDMI_CORE_CEC_MASK			0x17408 + +/* HDMI I2C Master */ +#define HDMI_CORE_I2CM_SLAVE			0x157C8 +#define HDMI_CORE_I2CM_ADDRESS			0x157CC +#define HDMI_CORE_I2CM_DATAO			0x157D0 +#define HDMI_CORE_I2CM_DATAI			0X157D4 +#define HDMI_CORE_I2CM_OPERATION		0x157D8 +#define HDMI_CORE_I2CM_INT			0x157DC +#define HDMI_CORE_I2CM_CTLINT			0x157E0 +#define HDMI_CORE_I2CM_DIV			0x157E4 +#define HDMI_CORE_I2CM_SEGADDR			0x157E8 +#define HDMI_CORE_I2CM_SOFTRSTZ			0x157EC +#define HDMI_CORE_I2CM_SEGPTR			0x157F0 +#define HDMI_CORE_I2CM_SS_SCL_HCNT_1_ADDR	0x157F4 +#define HDMI_CORE_I2CM_SS_SCL_HCNT_0_ADDR	0x157F8 +#define HDMI_CORE_I2CM_SS_SCL_LCNT_1_ADDR	0x157FC +#define HDMI_CORE_I2CM_SS_SCL_LCNT_0_ADDR	0x15800 +#define HDMI_CORE_I2CM_FS_SCL_HCNT_1_ADDR	0x15804 +#define HDMI_CORE_I2CM_FS_SCL_HCNT_0_ADDR	0x15808 +#define HDMI_CORE_I2CM_FS_SCL_LCNT_1_ADDR	0x1580C +#define HDMI_CORE_I2CM_FS_SCL_LCNT_0_ADDR	0x15810 +#define HDMI_CORE_I2CM_SDA_HOLD_ADDR		0x15814 + +enum hdmi_core_packet_mode { +	HDMI_PACKETMODERESERVEDVALUE = 0, +	HDMI_PACKETMODE24BITPERPIXEL = 4, +	HDMI_PACKETMODE30BITPERPIXEL = 5, +	HDMI_PACKETMODE36BITPERPIXEL = 6, +	HDMI_PACKETMODE48BITPERPIXEL = 7, +}; + +struct hdmi_core_vid_config { +	struct hdmi_config v_fc_config; +	enum hdmi_core_packet_mode packet_mode; +	int data_enable_pol; +	int vblank_osc; +	int hblank; +	int vblank; +}; + +struct csc_table { +	u16 a1, a2, a3, a4; +	u16 b1, b2, b3, b4; +	u16 c1, c2, c3, c4; +}; + +int hdmi5_read_edid(struct hdmi_core_data *core, u8 *edid, int len); +void hdmi5_core_dump(struct hdmi_core_data *core, struct seq_file *s); +int hdmi5_core_handle_irqs(struct hdmi_core_data *core); +void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp, +			struct hdmi_config *cfg); +int hdmi5_core_init(struct platform_device *pdev, struct hdmi_core_data *core); + +#if defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) +int hdmi5_audio_config(struct hdmi_core_data *core, struct hdmi_wp_data *wp, +			struct omap_dss_audio *audio, u32 pclk); +#endif +#endif diff --git a/drivers/video/fbdev/omap2/dss/hdmi_common.c b/drivers/video/fbdev/omap2/dss/hdmi_common.c new file mode 100644 index 00000000000..9a2c39cf297 --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/hdmi_common.c @@ -0,0 +1,466 @@ + +/* + * Logic for the below structure : + * user enters the CEA or VESA timings by specifying the HDMI/DVI code. + * There is a correspondence between CEA/VESA timing and code, please + * refer to section 6.3 in HDMI 1.3 specification for timing code. + * + * In the below structure, cea_vesa_timings corresponds to all OMAP4 + * supported CEA and VESA timing values.code_cea corresponds to the CEA + * code, It is used to get the timing from cea_vesa_timing array.Similarly + * with code_vesa. Code_index is used for back mapping, that is once EDID + * is read from the TV, EDID is parsed to find the timing values and then + * map it to corresponding CEA or VESA index. + */ + +#define DSS_SUBSYS_NAME "HDMI" + +#include <linux/kernel.h> +#include <linux/err.h> +#include <linux/of.h> +#include <video/omapdss.h> + +#include "hdmi.h" + +static const struct hdmi_config cea_timings[] = { +	{ +		{ 640, 480, 25200000, 96, 16, 48, 2, 10, 33, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, +			false, }, +		{ 1, HDMI_HDMI }, +	}, +	{ +		{ 720, 480, 27027000, 62, 16, 60, 6, 9, 30, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, +			false, }, +		{ 2, HDMI_HDMI }, +	}, +	{ +		{ 1280, 720, 74250000, 40, 110, 220, 5, 5, 20, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 4, HDMI_HDMI }, +	}, +	{ +		{ 1920, 540, 74250000, 44, 88, 148, 5, 2, 15, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			true, }, +		{ 5, HDMI_HDMI }, +	}, +	{ +		{ 1440, 240, 27027000, 124, 38, 114, 3, 4, 15, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, +			true, }, +		{ 6, HDMI_HDMI }, +	}, +	{ +		{ 1920, 1080, 148500000, 44, 88, 148, 5, 4, 36, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 16, HDMI_HDMI }, +	}, +	{ +		{ 720, 576, 27000000, 64, 12, 68, 5, 5, 39, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, +			false, }, +		{ 17, HDMI_HDMI }, +	}, +	{ +		{ 1280, 720, 74250000, 40, 440, 220, 5, 5, 20, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 19, HDMI_HDMI }, +	}, +	{ +		{ 1920, 540, 74250000, 44, 528, 148, 5, 2, 15, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			true, }, +		{ 20, HDMI_HDMI }, +	}, +	{ +		{ 1440, 288, 27000000, 126, 24, 138, 3, 2, 19, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, +			true, }, +		{ 21, HDMI_HDMI }, +	}, +	{ +		{ 1440, 576, 54000000, 128, 24, 136, 5, 5, 39, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, +			false, }, +		{ 29, HDMI_HDMI }, +	}, +	{ +		{ 1920, 1080, 148500000, 44, 528, 148, 5, 4, 36, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 31, HDMI_HDMI }, +	}, +	{ +		{ 1920, 1080, 74250000, 44, 638, 148, 5, 4, 36, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 32, HDMI_HDMI }, +	}, +	{ +		{ 2880, 480, 108108000, 248, 64, 240, 6, 9, 30, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, +			false, }, +		{ 35, HDMI_HDMI }, +	}, +	{ +		{ 2880, 576, 108000000, 256, 48, 272, 5, 5, 39, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, +			false, }, +		{ 37, HDMI_HDMI }, +	}, +}; + +static const struct hdmi_config vesa_timings[] = { +/* VESA From Here */ +	{ +		{ 640, 480, 25175000, 96, 16, 48, 2, 11, 31, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, +			false, }, +		{ 4, HDMI_DVI }, +	}, +	{ +		{ 800, 600, 40000000, 128, 40, 88, 4, 1, 23, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 9, HDMI_DVI }, +	}, +	{ +		{ 848, 480, 33750000, 112, 16, 112, 8, 6, 23, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 0xE, HDMI_DVI }, +	}, +	{ +		{ 1280, 768, 79500000, 128, 64, 192, 7, 3, 20, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, +			false, }, +		{ 0x17, HDMI_DVI }, +	}, +	{ +		{ 1280, 800, 83500000, 128, 72, 200, 6, 3, 22, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, +			false, }, +		{ 0x1C, HDMI_DVI }, +	}, +	{ +		{ 1360, 768, 85500000, 112, 64, 256, 6, 3, 18, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 0x27, HDMI_DVI }, +	}, +	{ +		{ 1280, 960, 108000000, 112, 96, 312, 3, 1, 36, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 0x20, HDMI_DVI }, +	}, +	{ +		{ 1280, 1024, 108000000, 112, 48, 248, 3, 1, 38, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 0x23, HDMI_DVI }, +	}, +	{ +		{ 1024, 768, 65000000, 136, 24, 160, 6, 3, 29, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, +			false, }, +		{ 0x10, HDMI_DVI }, +	}, +	{ +		{ 1400, 1050, 121750000, 144, 88, 232, 4, 3, 32, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, +			false, }, +		{ 0x2A, HDMI_DVI }, +	}, +	{ +		{ 1440, 900, 106500000, 152, 80, 232, 6, 3, 25, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, +			false, }, +		{ 0x2F, HDMI_DVI }, +	}, +	{ +		{ 1680, 1050, 146250000, 176 , 104, 280, 6, 3, 30, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, +			false, }, +		{ 0x3A, HDMI_DVI }, +	}, +	{ +		{ 1366, 768, 85500000, 143, 70, 213, 3, 3, 24, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 0x51, HDMI_DVI }, +	}, +	{ +		{ 1920, 1080, 148500000, 44, 148, 80, 5, 4, 36, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 0x52, HDMI_DVI }, +	}, +	{ +		{ 1280, 768, 68250000, 32, 48, 80, 7, 3, 12, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 0x16, HDMI_DVI }, +	}, +	{ +		{ 1400, 1050, 101000000, 32, 48, 80, 4, 3, 23, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 0x29, HDMI_DVI }, +	}, +	{ +		{ 1680, 1050, 119000000, 32, 48, 80, 6, 3, 21, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 0x39, HDMI_DVI }, +	}, +	{ +		{ 1280, 800, 79500000, 32, 48, 80, 6, 3, 14, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 0x1B, HDMI_DVI }, +	}, +	{ +		{ 1280, 720, 74250000, 40, 110, 220, 5, 5, 20, +			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 0x55, HDMI_DVI }, +	}, +	{ +		{ 1920, 1200, 154000000, 32, 48, 80, 6, 3, 26, +			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, +			false, }, +		{ 0x44, HDMI_DVI }, +	}, +}; + +const struct hdmi_config *hdmi_default_timing(void) +{ +	return &vesa_timings[0]; +} + +static const struct hdmi_config *hdmi_find_timing(int code, +			const struct hdmi_config *timings_arr, int len) +{ +	int i; + +	for (i = 0; i < len; i++) { +		if (timings_arr[i].cm.code == code) +			return &timings_arr[i]; +	} + +	return NULL; +} + +const struct hdmi_config *hdmi_get_timings(int mode, int code) +{ +	const struct hdmi_config *arr; +	int len; + +	if (mode == HDMI_DVI) { +		arr = vesa_timings; +		len = ARRAY_SIZE(vesa_timings); +	} else { +		arr = cea_timings; +		len = ARRAY_SIZE(cea_timings); +	} + +	return hdmi_find_timing(code, arr, len); +} + +static bool hdmi_timings_compare(struct omap_video_timings *timing1, +			const struct omap_video_timings *timing2) +{ +	int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; + +	if ((DIV_ROUND_CLOSEST(timing2->pixelclock, 1000000) == +			DIV_ROUND_CLOSEST(timing1->pixelclock, 1000000)) && +		(timing2->x_res == timing1->x_res) && +		(timing2->y_res == timing1->y_res)) { + +		timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp; +		timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp; +		timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp; +		timing1_vsync = timing1->vfp + timing1->vsw + timing1->vbp; + +		DSSDBG("timing1_hsync = %d timing1_vsync = %d"\ +			"timing2_hsync = %d timing2_vsync = %d\n", +			timing1_hsync, timing1_vsync, +			timing2_hsync, timing2_vsync); + +		if ((timing1_hsync == timing2_hsync) && +			(timing1_vsync == timing2_vsync)) { +			return true; +		} +	} +	return false; +} + +struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) +{ +	int i; +	struct hdmi_cm cm = {-1}; +	DSSDBG("hdmi_get_code\n"); + +	for (i = 0; i < ARRAY_SIZE(cea_timings); i++) { +		if (hdmi_timings_compare(timing, &cea_timings[i].timings)) { +			cm = cea_timings[i].cm; +			goto end; +		} +	} +	for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) { +		if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) { +			cm = vesa_timings[i].cm; +			goto end; +		} +	} + +end: +	return cm; +} + +int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep, +	struct hdmi_phy_data *phy) +{ +	struct property *prop; +	int r, len; + +	prop = of_find_property(ep, "lanes", &len); +	if (prop) { +		u32 lanes[8]; + +		if (len / sizeof(u32) != ARRAY_SIZE(lanes)) { +			dev_err(&pdev->dev, "bad number of lanes\n"); +			return -EINVAL; +		} + +		r = of_property_read_u32_array(ep, "lanes", lanes, +			ARRAY_SIZE(lanes)); +		if (r) { +			dev_err(&pdev->dev, "failed to read lane data\n"); +			return r; +		} + +		r = hdmi_phy_parse_lanes(phy, lanes); +		if (r) { +			dev_err(&pdev->dev, "failed to parse lane data\n"); +			return r; +		} +	} else { +		static const u32 default_lanes[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + +		r = hdmi_phy_parse_lanes(phy, default_lanes); +		if (WARN_ON(r)) { +			dev_err(&pdev->dev, "failed to parse lane data\n"); +			return r; +		} +	} + +	return 0; +} + +#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) +int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts) +{ +	u32 deep_color; +	bool deep_color_correct = false; + +	if (n == NULL || cts == NULL) +		return -EINVAL; + +	/* TODO: When implemented, query deep color mode here. */ +	deep_color = 100; + +	/* +	 * When using deep color, the default N value (as in the HDMI +	 * specification) yields to an non-integer CTS. Hence, we +	 * modify it while keeping the restrictions described in +	 * section 7.2.1 of the HDMI 1.4a specification. +	 */ +	switch (sample_freq) { +	case 32000: +	case 48000: +	case 96000: +	case 192000: +		if (deep_color == 125) +			if (pclk == 27027000 || pclk == 74250000) +				deep_color_correct = true; +		if (deep_color == 150) +			if (pclk == 27027000) +				deep_color_correct = true; +		break; +	case 44100: +	case 88200: +	case 176400: +		if (deep_color == 125) +			if (pclk == 27027000) +				deep_color_correct = true; +		break; +	default: +		return -EINVAL; +	} + +	if (deep_color_correct) { +		switch (sample_freq) { +		case 32000: +			*n = 8192; +			break; +		case 44100: +			*n = 12544; +			break; +		case 48000: +			*n = 8192; +			break; +		case 88200: +			*n = 25088; +			break; +		case 96000: +			*n = 16384; +			break; +		case 176400: +			*n = 50176; +			break; +		case 192000: +			*n = 32768; +			break; +		default: +			return -EINVAL; +		} +	} else { +		switch (sample_freq) { +		case 32000: +			*n = 4096; +			break; +		case 44100: +			*n = 6272; +			break; +		case 48000: +			*n = 6144; +			break; +		case 88200: +			*n = 12544; +			break; +		case 96000: +			*n = 12288; +			break; +		case 176400: +			*n = 25088; +			break; +		case 192000: +			*n = 24576; +			break; +		default: +			return -EINVAL; +		} +	} +	/* Calculate CTS. See HDMI 1.3a or 1.4a specifications */ +	*cts = (pclk/1000) * (*n / 128) * deep_color / (sample_freq / 10); + +	return 0; +} +#endif diff --git a/drivers/video/fbdev/omap2/dss/hdmi_phy.c b/drivers/video/fbdev/omap2/dss/hdmi_phy.c new file mode 100644 index 00000000000..e007ac892d7 --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/hdmi_phy.c @@ -0,0 +1,255 @@ +/* + * HDMI PHY + * + * Copyright (C) 2013 Texas Instruments Incorporated + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include <linux/kernel.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <video/omapdss.h> + +#include "dss.h" +#include "hdmi.h" + +struct hdmi_phy_features { +	bool bist_ctrl; +	bool calc_freqout; +	bool ldo_voltage; +	unsigned long dcofreq_min; +	unsigned long max_phy; +}; + +static const struct hdmi_phy_features *phy_feat; + +void hdmi_phy_dump(struct hdmi_phy_data *phy, struct seq_file *s) +{ +#define DUMPPHY(r) seq_printf(s, "%-35s %08x\n", #r,\ +		hdmi_read_reg(phy->base, r)) + +	DUMPPHY(HDMI_TXPHY_TX_CTRL); +	DUMPPHY(HDMI_TXPHY_DIGITAL_CTRL); +	DUMPPHY(HDMI_TXPHY_POWER_CTRL); +	DUMPPHY(HDMI_TXPHY_PAD_CFG_CTRL); +	if (phy_feat->bist_ctrl) +		DUMPPHY(HDMI_TXPHY_BIST_CONTROL); +} + +int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes) +{ +	int i; + +	for (i = 0; i < 8; i += 2) { +		u8 lane, pol; +		int dx, dy; + +		dx = lanes[i]; +		dy = lanes[i + 1]; + +		if (dx < 0 || dx >= 8) +			return -EINVAL; + +		if (dy < 0 || dy >= 8) +			return -EINVAL; + +		if (dx & 1) { +			if (dy != dx - 1) +				return -EINVAL; +			pol = 1; +		} else { +			if (dy != dx + 1) +				return -EINVAL; +			pol = 0; +		} + +		lane = dx / 2; + +		phy->lane_function[lane] = i / 2; +		phy->lane_polarity[lane] = pol; +	} + +	return 0; +} + +static void hdmi_phy_configure_lanes(struct hdmi_phy_data *phy) +{ +	static const u16 pad_cfg_list[] = { +		0x0123, +		0x0132, +		0x0312, +		0x0321, +		0x0231, +		0x0213, +		0x1023, +		0x1032, +		0x3012, +		0x3021, +		0x2031, +		0x2013, +		0x1203, +		0x1302, +		0x3102, +		0x3201, +		0x2301, +		0x2103, +		0x1230, +		0x1320, +		0x3120, +		0x3210, +		0x2310, +		0x2130, +	}; + +	u16 lane_cfg = 0; +	int i; +	unsigned lane_cfg_val; +	u16 pol_val = 0; + +	for (i = 0; i < 4; ++i) +		lane_cfg |= phy->lane_function[i] << ((3 - i) * 4); + +	pol_val |= phy->lane_polarity[0] << 0; +	pol_val |= phy->lane_polarity[1] << 3; +	pol_val |= phy->lane_polarity[2] << 2; +	pol_val |= phy->lane_polarity[3] << 1; + +	for (i = 0; i < ARRAY_SIZE(pad_cfg_list); ++i) +		if (pad_cfg_list[i] == lane_cfg) +			break; + +	if (WARN_ON(i == ARRAY_SIZE(pad_cfg_list))) +		i = 0; + +	lane_cfg_val = i; + +	REG_FLD_MOD(phy->base, HDMI_TXPHY_PAD_CFG_CTRL, lane_cfg_val, 26, 22); +	REG_FLD_MOD(phy->base, HDMI_TXPHY_PAD_CFG_CTRL, pol_val, 30, 27); +} + +int hdmi_phy_configure(struct hdmi_phy_data *phy, struct hdmi_config *cfg) +{ +	u8 freqout; + +	/* +	 * Read address 0 in order to get the SCP reset done completed +	 * Dummy access performed to make sure reset is done +	 */ +	hdmi_read_reg(phy->base, HDMI_TXPHY_TX_CTRL); + +	/* +	 * In OMAP5+, the HFBITCLK must be divided by 2 before issuing the +	 * HDMI_PHYPWRCMD_LDOON command. +	*/ +	if (phy_feat->bist_ctrl) +		REG_FLD_MOD(phy->base, HDMI_TXPHY_BIST_CONTROL, 1, 11, 11); + +	if (phy_feat->calc_freqout) { +		/* DCOCLK/10 is pixel clock, compare pclk with DCOCLK_MIN/10 */ +		u32 dco_min = phy_feat->dcofreq_min / 10; +		u32 pclk = cfg->timings.pixelclock; + +		if (pclk < dco_min) +			freqout = 0; +		else if ((pclk >= dco_min) && (pclk < phy_feat->max_phy)) +			freqout = 1; +		else +			freqout = 2; +	} else { +		freqout = 1; +	} + +	/* +	 * Write to phy address 0 to configure the clock +	 * use HFBITCLK write HDMI_TXPHY_TX_CONTROL_FREQOUT field +	 */ +	REG_FLD_MOD(phy->base, HDMI_TXPHY_TX_CTRL, freqout, 31, 30); + +	/* Write to phy address 1 to start HDMI line (TXVALID and TMDSCLKEN) */ +	hdmi_write_reg(phy->base, HDMI_TXPHY_DIGITAL_CTRL, 0xF0000000); + +	/* Setup max LDO voltage */ +	if (phy_feat->ldo_voltage) +		REG_FLD_MOD(phy->base, HDMI_TXPHY_POWER_CTRL, 0xB, 3, 0); + +	hdmi_phy_configure_lanes(phy); + +	return 0; +} + +static const struct hdmi_phy_features omap44xx_phy_feats = { +	.bist_ctrl	=	false, +	.calc_freqout	=	false, +	.ldo_voltage	=	true, +	.dcofreq_min	=	500000000, +	.max_phy	=	185675000, +}; + +static const struct hdmi_phy_features omap54xx_phy_feats = { +	.bist_ctrl	=	true, +	.calc_freqout	=	true, +	.ldo_voltage	=	false, +	.dcofreq_min	=	750000000, +	.max_phy	=	186000000, +}; + +static int hdmi_phy_init_features(struct platform_device *pdev) +{ +	struct hdmi_phy_features *dst; +	const struct hdmi_phy_features *src; + +	dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL); +	if (!dst) { +		dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n"); +		return -ENOMEM; +	} + +	switch (omapdss_get_version()) { +	case OMAPDSS_VER_OMAP4430_ES1: +	case OMAPDSS_VER_OMAP4430_ES2: +	case OMAPDSS_VER_OMAP4: +		src = &omap44xx_phy_feats; +		break; + +	case OMAPDSS_VER_OMAP5: +		src = &omap54xx_phy_feats; +		break; + +	default: +		return -ENODEV; +	} + +	memcpy(dst, src, sizeof(*dst)); +	phy_feat = dst; + +	return 0; +} + +int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy) +{ +	int r; +	struct resource *res; + +	r = hdmi_phy_init_features(pdev); +	if (r) +		return r; + +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy"); +	if (!res) { +		DSSERR("can't get PHY mem resource\n"); +		return -EINVAL; +	} + +	phy->base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(phy->base)) { +		DSSERR("can't ioremap TX PHY\n"); +		return PTR_ERR(phy->base); +	} + +	return 0; +} diff --git a/drivers/video/fbdev/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c new file mode 100644 index 00000000000..54df12a8d74 --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c @@ -0,0 +1,291 @@ +/* + * HDMI PLL + * + * Copyright (C) 2013 Texas Instruments Incorporated + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#define DSS_SUBSYS_NAME "HDMIPLL" + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <video/omapdss.h> + +#include "dss.h" +#include "hdmi.h" + +#define HDMI_DEFAULT_REGN 16 +#define HDMI_DEFAULT_REGM2 1 + +struct hdmi_pll_features { +	bool sys_reset; +	/* this is a hack, need to replace it with a better computation of M2 */ +	bool bound_dcofreq; +	unsigned long fint_min, fint_max; +	u16 regm_max; +	unsigned long dcofreq_low_min, dcofreq_low_max; +	unsigned long dcofreq_high_min, dcofreq_high_max; +}; + +static const struct hdmi_pll_features *pll_feat; + +void hdmi_pll_dump(struct hdmi_pll_data *pll, struct seq_file *s) +{ +#define DUMPPLL(r) seq_printf(s, "%-35s %08x\n", #r,\ +		hdmi_read_reg(pll->base, r)) + +	DUMPPLL(PLLCTRL_PLL_CONTROL); +	DUMPPLL(PLLCTRL_PLL_STATUS); +	DUMPPLL(PLLCTRL_PLL_GO); +	DUMPPLL(PLLCTRL_CFG1); +	DUMPPLL(PLLCTRL_CFG2); +	DUMPPLL(PLLCTRL_CFG3); +	DUMPPLL(PLLCTRL_SSC_CFG1); +	DUMPPLL(PLLCTRL_SSC_CFG2); +	DUMPPLL(PLLCTRL_CFG4); +} + +void hdmi_pll_compute(struct hdmi_pll_data *pll, unsigned long clkin, int phy) +{ +	struct hdmi_pll_info *pi = &pll->info; +	unsigned long refclk; +	u32 mf; + +	/* use our funky units */ +	clkin /= 10000; + +	/* +	 * Input clock is predivided by N + 1 +	 * out put of which is reference clk +	 */ + +	pi->regn = HDMI_DEFAULT_REGN; + +	refclk = clkin / pi->regn; + +	/* temorary hack to make sure DCO freq isn't calculated too low */ +	if (pll_feat->bound_dcofreq && phy <= 65000) +		pi->regm2 = 3; +	else +		pi->regm2 = HDMI_DEFAULT_REGM2; + +	/* +	 * multiplier is pixel_clk/ref_clk +	 * Multiplying by 100 to avoid fractional part removal +	 */ +	pi->regm = phy * pi->regm2 / refclk; + +	/* +	 * fractional multiplier is remainder of the difference between +	 * multiplier and actual phy(required pixel clock thus should be +	 * multiplied by 2^18(262144) divided by the reference clock +	 */ +	mf = (phy - pi->regm / pi->regm2 * refclk) * 262144; +	pi->regmf = pi->regm2 * mf / refclk; + +	/* +	 * Dcofreq should be set to 1 if required pixel clock +	 * is greater than 1000MHz +	 */ +	pi->dcofreq = phy > 1000 * 100; +	pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10; + +	/* Set the reference clock to sysclk reference */ +	pi->refsel = HDMI_REFSEL_SYSCLK; + +	DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf); +	DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); +} + + +static int hdmi_pll_config(struct hdmi_pll_data *pll) +{ +	u32 r; +	struct hdmi_pll_info *fmt = &pll->info; + +	/* PLL start always use manual mode */ +	REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, 0x0, 0, 0); + +	r = hdmi_read_reg(pll->base, PLLCTRL_CFG1); +	r = FLD_MOD(r, fmt->regm, 20, 9);	/* CFG1_PLL_REGM */ +	r = FLD_MOD(r, fmt->regn - 1, 8, 1);	/* CFG1_PLL_REGN */ +	hdmi_write_reg(pll->base, PLLCTRL_CFG1, r); + +	r = hdmi_read_reg(pll->base, PLLCTRL_CFG2); + +	r = FLD_MOD(r, 0x0, 12, 12);	/* PLL_HIGHFREQ divide by 2 */ +	r = FLD_MOD(r, 0x1, 13, 13);	/* PLL_REFEN */ +	r = FLD_MOD(r, 0x0, 14, 14);	/* PHY_CLKINEN de-assert during locking */ +	r = FLD_MOD(r, fmt->refsel, 22, 21);	/* REFSEL */ + +	if (fmt->dcofreq) { +		/* divider programming for frequency beyond 1000Mhz */ +		REG_FLD_MOD(pll->base, PLLCTRL_CFG3, fmt->regsd, 17, 10); +		r = FLD_MOD(r, 0x4, 3, 1);	/* 1000MHz and 2000MHz */ +	} else { +		r = FLD_MOD(r, 0x2, 3, 1);	/* 500MHz and 1000MHz */ +	} + +	hdmi_write_reg(pll->base, PLLCTRL_CFG2, r); + +	r = hdmi_read_reg(pll->base, PLLCTRL_CFG4); +	r = FLD_MOD(r, fmt->regm2, 24, 18); +	r = FLD_MOD(r, fmt->regmf, 17, 0); +	hdmi_write_reg(pll->base, PLLCTRL_CFG4, r); + +	/* go now */ +	REG_FLD_MOD(pll->base, PLLCTRL_PLL_GO, 0x1, 0, 0); + +	/* wait for bit change */ +	if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_GO, +			0, 0, 1) != 1) { +		DSSERR("PLL GO bit not set\n"); +		return -ETIMEDOUT; +	} + +	/* Wait till the lock bit is set in PLL status */ +	if (hdmi_wait_for_bit_change(pll->base, +			PLLCTRL_PLL_STATUS, 1, 1, 1) != 1) { +		DSSERR("cannot lock PLL\n"); +		DSSERR("CFG1 0x%x\n", +			hdmi_read_reg(pll->base, PLLCTRL_CFG1)); +		DSSERR("CFG2 0x%x\n", +			hdmi_read_reg(pll->base, PLLCTRL_CFG2)); +		DSSERR("CFG4 0x%x\n", +			hdmi_read_reg(pll->base, PLLCTRL_CFG4)); +		return -ETIMEDOUT; +	} + +	DSSDBG("PLL locked!\n"); + +	return 0; +} + +static int hdmi_pll_reset(struct hdmi_pll_data *pll) +{ +	/* SYSRESET  controlled by power FSM */ +	REG_FLD_MOD(pll->base, PLLCTRL_PLL_CONTROL, pll_feat->sys_reset, 3, 3); + +	/* READ 0x0 reset is in progress */ +	if (hdmi_wait_for_bit_change(pll->base, PLLCTRL_PLL_STATUS, 0, 0, 1) +			!= 1) { +		DSSERR("Failed to sysreset PLL\n"); +		return -ETIMEDOUT; +	} + +	return 0; +} + +int hdmi_pll_enable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp) +{ +	u16 r = 0; + +	r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); +	if (r) +		return r; + +	r = hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_BOTHON_ALLCLKS); +	if (r) +		return r; + +	r = hdmi_pll_reset(pll); +	if (r) +		return r; + +	r = hdmi_pll_config(pll); +	if (r) +		return r; + +	return 0; +} + +void hdmi_pll_disable(struct hdmi_pll_data *pll, struct hdmi_wp_data *wp) +{ +	hdmi_wp_set_pll_pwr(wp, HDMI_PLLPWRCMD_ALLOFF); +} + +static const struct hdmi_pll_features omap44xx_pll_feats = { +	.sys_reset		=	false, +	.bound_dcofreq		=	false, +	.fint_min		=	500000, +	.fint_max		=	2500000, +	.regm_max		=	4095, +	.dcofreq_low_min	=	500000000, +	.dcofreq_low_max	=	1000000000, +	.dcofreq_high_min	=	1000000000, +	.dcofreq_high_max	=	2000000000, +}; + +static const struct hdmi_pll_features omap54xx_pll_feats = { +	.sys_reset		=	true, +	.bound_dcofreq		=	true, +	.fint_min		=	620000, +	.fint_max		=	2500000, +	.regm_max		=	2046, +	.dcofreq_low_min	=	750000000, +	.dcofreq_low_max	=	1500000000, +	.dcofreq_high_min	=	1250000000, +	.dcofreq_high_max	=	2500000000UL, +}; + +static int hdmi_pll_init_features(struct platform_device *pdev) +{ +	struct hdmi_pll_features *dst; +	const struct hdmi_pll_features *src; + +	dst = devm_kzalloc(&pdev->dev, sizeof(*dst), GFP_KERNEL); +	if (!dst) { +		dev_err(&pdev->dev, "Failed to allocate HDMI PHY Features\n"); +		return -ENOMEM; +	} + +	switch (omapdss_get_version()) { +	case OMAPDSS_VER_OMAP4430_ES1: +	case OMAPDSS_VER_OMAP4430_ES2: +	case OMAPDSS_VER_OMAP4: +		src = &omap44xx_pll_feats; +		break; + +	case OMAPDSS_VER_OMAP5: +		src = &omap54xx_pll_feats; +		break; + +	default: +		return -ENODEV; +	} + +	memcpy(dst, src, sizeof(*dst)); +	pll_feat = dst; + +	return 0; +} + +int hdmi_pll_init(struct platform_device *pdev, struct hdmi_pll_data *pll) +{ +	int r; +	struct resource *res; + +	r = hdmi_pll_init_features(pdev); +	if (r) +		return r; + +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll"); +	if (!res) { +		DSSERR("can't get PLL mem resource\n"); +		return -EINVAL; +	} + +	pll->base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(pll->base)) { +		DSSERR("can't ioremap PLLCTRL\n"); +		return PTR_ERR(pll->base); +	} + +	return 0; +} diff --git a/drivers/video/fbdev/omap2/dss/hdmi_wp.c b/drivers/video/fbdev/omap2/dss/hdmi_wp.c new file mode 100644 index 00000000000..496327e2b21 --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/hdmi_wp.c @@ -0,0 +1,258 @@ +/* + * HDMI wrapper + * + * Copyright (C) 2013 Texas Instruments Incorporated + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#define DSS_SUBSYS_NAME "HDMIWP" + +#include <linux/kernel.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/platform_device.h> +#include <video/omapdss.h> + +#include "dss.h" +#include "hdmi.h" + +void hdmi_wp_dump(struct hdmi_wp_data *wp, struct seq_file *s) +{ +#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, hdmi_read_reg(wp->base, r)) + +	DUMPREG(HDMI_WP_REVISION); +	DUMPREG(HDMI_WP_SYSCONFIG); +	DUMPREG(HDMI_WP_IRQSTATUS_RAW); +	DUMPREG(HDMI_WP_IRQSTATUS); +	DUMPREG(HDMI_WP_IRQENABLE_SET); +	DUMPREG(HDMI_WP_IRQENABLE_CLR); +	DUMPREG(HDMI_WP_IRQWAKEEN); +	DUMPREG(HDMI_WP_PWR_CTRL); +	DUMPREG(HDMI_WP_DEBOUNCE); +	DUMPREG(HDMI_WP_VIDEO_CFG); +	DUMPREG(HDMI_WP_VIDEO_SIZE); +	DUMPREG(HDMI_WP_VIDEO_TIMING_H); +	DUMPREG(HDMI_WP_VIDEO_TIMING_V); +	DUMPREG(HDMI_WP_CLK); +	DUMPREG(HDMI_WP_AUDIO_CFG); +	DUMPREG(HDMI_WP_AUDIO_CFG2); +	DUMPREG(HDMI_WP_AUDIO_CTRL); +	DUMPREG(HDMI_WP_AUDIO_DATA); +} + +u32 hdmi_wp_get_irqstatus(struct hdmi_wp_data *wp) +{ +	return hdmi_read_reg(wp->base, HDMI_WP_IRQSTATUS); +} + +void hdmi_wp_set_irqstatus(struct hdmi_wp_data *wp, u32 irqstatus) +{ +	hdmi_write_reg(wp->base, HDMI_WP_IRQSTATUS, irqstatus); +	/* flush posted write */ +	hdmi_read_reg(wp->base, HDMI_WP_IRQSTATUS); +} + +void hdmi_wp_set_irqenable(struct hdmi_wp_data *wp, u32 mask) +{ +	hdmi_write_reg(wp->base, HDMI_WP_IRQENABLE_SET, mask); +} + +void hdmi_wp_clear_irqenable(struct hdmi_wp_data *wp, u32 mask) +{ +	hdmi_write_reg(wp->base, HDMI_WP_IRQENABLE_CLR, mask); +} + +/* PHY_PWR_CMD */ +int hdmi_wp_set_phy_pwr(struct hdmi_wp_data *wp, enum hdmi_phy_pwr val) +{ +	/* Return if already the state */ +	if (REG_GET(wp->base, HDMI_WP_PWR_CTRL, 5, 4) == val) +		return 0; + +	/* Command for power control of HDMI PHY */ +	REG_FLD_MOD(wp->base, HDMI_WP_PWR_CTRL, val, 7, 6); + +	/* Status of the power control of HDMI PHY */ +	if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 5, 4, val) +			!= val) { +		DSSERR("Failed to set PHY power mode to %d\n", val); +		return -ETIMEDOUT; +	} + +	return 0; +} + +/* PLL_PWR_CMD */ +int hdmi_wp_set_pll_pwr(struct hdmi_wp_data *wp, enum hdmi_pll_pwr val) +{ +	/* Command for power control of HDMI PLL */ +	REG_FLD_MOD(wp->base, HDMI_WP_PWR_CTRL, val, 3, 2); + +	/* wait till PHY_PWR_STATUS is set */ +	if (hdmi_wait_for_bit_change(wp->base, HDMI_WP_PWR_CTRL, 1, 0, val) +			!= val) { +		DSSERR("Failed to set PLL_PWR_STATUS\n"); +		return -ETIMEDOUT; +	} + +	return 0; +} + +int hdmi_wp_video_start(struct hdmi_wp_data *wp) +{ +	REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, true, 31, 31); + +	return 0; +} + +void hdmi_wp_video_stop(struct hdmi_wp_data *wp) +{ +	REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, false, 31, 31); +} + +void hdmi_wp_video_config_format(struct hdmi_wp_data *wp, +		struct hdmi_video_format *video_fmt) +{ +	u32 l = 0; + +	REG_FLD_MOD(wp->base, HDMI_WP_VIDEO_CFG, video_fmt->packing_mode, +		10, 8); + +	l |= FLD_VAL(video_fmt->y_res, 31, 16); +	l |= FLD_VAL(video_fmt->x_res, 15, 0); +	hdmi_write_reg(wp->base, HDMI_WP_VIDEO_SIZE, l); +} + +void hdmi_wp_video_config_interface(struct hdmi_wp_data *wp, +		struct omap_video_timings *timings) +{ +	u32 r; +	bool vsync_pol, hsync_pol; +	DSSDBG("Enter hdmi_wp_video_config_interface\n"); + +	vsync_pol = timings->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH; +	hsync_pol = timings->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH; + +	r = hdmi_read_reg(wp->base, HDMI_WP_VIDEO_CFG); +	r = FLD_MOD(r, vsync_pol, 7, 7); +	r = FLD_MOD(r, hsync_pol, 6, 6); +	r = FLD_MOD(r, timings->interlace, 3, 3); +	r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ +	hdmi_write_reg(wp->base, HDMI_WP_VIDEO_CFG, r); +} + +void hdmi_wp_video_config_timing(struct hdmi_wp_data *wp, +		struct omap_video_timings *timings) +{ +	u32 timing_h = 0; +	u32 timing_v = 0; + +	DSSDBG("Enter hdmi_wp_video_config_timing\n"); + +	timing_h |= FLD_VAL(timings->hbp, 31, 20); +	timing_h |= FLD_VAL(timings->hfp, 19, 8); +	timing_h |= FLD_VAL(timings->hsw, 7, 0); +	hdmi_write_reg(wp->base, HDMI_WP_VIDEO_TIMING_H, timing_h); + +	timing_v |= FLD_VAL(timings->vbp, 31, 20); +	timing_v |= FLD_VAL(timings->vfp, 19, 8); +	timing_v |= FLD_VAL(timings->vsw, 7, 0); +	hdmi_write_reg(wp->base, HDMI_WP_VIDEO_TIMING_V, timing_v); +} + +void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt, +		struct omap_video_timings *timings, struct hdmi_config *param) +{ +	DSSDBG("Enter hdmi_wp_video_init_format\n"); + +	video_fmt->packing_mode = HDMI_PACK_10b_RGB_YUV444; +	video_fmt->y_res = param->timings.y_res; +	video_fmt->x_res = param->timings.x_res; +	if (param->timings.interlace) +		video_fmt->y_res /= 2; + +	timings->hbp = param->timings.hbp; +	timings->hfp = param->timings.hfp; +	timings->hsw = param->timings.hsw; +	timings->vbp = param->timings.vbp; +	timings->vfp = param->timings.vfp; +	timings->vsw = param->timings.vsw; +	timings->vsync_level = param->timings.vsync_level; +	timings->hsync_level = param->timings.hsync_level; +	timings->interlace = param->timings.interlace; +} + +#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) || defined(CONFIG_OMAP5_DSS_HDMI_AUDIO) +void hdmi_wp_audio_config_format(struct hdmi_wp_data *wp, +		struct hdmi_audio_format *aud_fmt) +{ +	u32 r; + +	DSSDBG("Enter hdmi_wp_audio_config_format\n"); + +	r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG); +	r = FLD_MOD(r, aud_fmt->stereo_channels, 26, 24); +	r = FLD_MOD(r, aud_fmt->active_chnnls_msk, 23, 16); +	r = FLD_MOD(r, aud_fmt->en_sig_blk_strt_end, 5, 5); +	r = FLD_MOD(r, aud_fmt->type, 4, 4); +	r = FLD_MOD(r, aud_fmt->justification, 3, 3); +	r = FLD_MOD(r, aud_fmt->sample_order, 2, 2); +	r = FLD_MOD(r, aud_fmt->samples_per_word, 1, 1); +	r = FLD_MOD(r, aud_fmt->sample_size, 0, 0); +	hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CFG, r); +} + +void hdmi_wp_audio_config_dma(struct hdmi_wp_data *wp, +		struct hdmi_audio_dma *aud_dma) +{ +	u32 r; + +	DSSDBG("Enter hdmi_wp_audio_config_dma\n"); + +	r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CFG2); +	r = FLD_MOD(r, aud_dma->transfer_size, 15, 8); +	r = FLD_MOD(r, aud_dma->block_size, 7, 0); +	hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CFG2, r); + +	r = hdmi_read_reg(wp->base, HDMI_WP_AUDIO_CTRL); +	r = FLD_MOD(r, aud_dma->mode, 9, 9); +	r = FLD_MOD(r, aud_dma->fifo_threshold, 8, 0); +	hdmi_write_reg(wp->base, HDMI_WP_AUDIO_CTRL, r); +} + +int hdmi_wp_audio_enable(struct hdmi_wp_data *wp, bool enable) +{ +	REG_FLD_MOD(wp->base, HDMI_WP_AUDIO_CTRL, enable, 31, 31); + +	return 0; +} + +int hdmi_wp_audio_core_req_enable(struct hdmi_wp_data *wp, bool enable) +{ +	REG_FLD_MOD(wp->base, HDMI_WP_AUDIO_CTRL, enable, 30, 30); + +	return 0; +} +#endif + +int hdmi_wp_init(struct platform_device *pdev, struct hdmi_wp_data *wp) +{ +	struct resource *res; + +	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "wp"); +	if (!res) { +		DSSERR("can't get WP mem resource\n"); +		return -EINVAL; +	} + +	wp->base = devm_ioremap_resource(&pdev->dev, res); +	if (IS_ERR(wp->base)) { +		DSSERR("can't ioremap HDMI WP\n"); +		return PTR_ERR(wp->base); +	} + +	return 0; +} diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/fbdev/omap2/dss/manager-sysfs.c index 37b59fe28dc..37b59fe28dc 100644 --- a/drivers/video/omap2/dss/manager-sysfs.c +++ b/drivers/video/fbdev/omap2/dss/manager-sysfs.c diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/fbdev/omap2/dss/manager.c index 1aac9b4191a..1aac9b4191a 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/fbdev/omap2/dss/manager.c diff --git a/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c b/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c new file mode 100644 index 00000000000..2f0822ee3ff --- /dev/null +++ b/drivers/video/fbdev/omap2/dss/omapdss-boot-init.c @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2014 Texas Instruments + * Author: Tomi Valkeinen <tomi.valkeinen@ti.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program.  If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * As omapdss panel drivers are omapdss specific, but we want to define the + * DT-data in generic manner, we convert the compatible strings of the panel and + * encoder nodes from "panel-foo" to "omapdss,panel-foo". This way we can have + * both correct DT data and omapdss specific drivers. + * + * When we get generic panel drivers to the kernel, this file will be removed. + */ + +#include <linux/kernel.h> +#include <linux/of.h> +#include <linux/of_graph.h> +#include <linux/slab.h> +#include <linux/list.h> + +static struct list_head dss_conv_list __initdata; + +static const char prefix[] __initconst = "omapdss,"; + +struct dss_conv_node { +	struct list_head list; +	struct device_node *node; +	bool root; +}; + +static int __init omapdss_count_strings(const struct property *prop) +{ +	const char *p = prop->value; +	int l = 0, total = 0; +	int i; + +	for (i = 0; total < prop->length; total += l, p += l, i++) +		l = strlen(p) + 1; + +	return i; +} + +static void __init omapdss_update_prop(struct device_node *node, char *compat, +	int len) +{ +	struct property *prop; + +	prop = kzalloc(sizeof(*prop), GFP_KERNEL); +	if (!prop) +		return; + +	prop->name = "compatible"; +	prop->value = compat; +	prop->length = len; + +	of_update_property(node, prop); +} + +static void __init omapdss_prefix_strcpy(char *dst, int dst_len, +	const char *src, int src_len) +{ +	size_t total = 0; + +	while (total < src_len) { +		size_t l = strlen(src) + 1; + +		strcpy(dst, prefix); +		dst += strlen(prefix); + +		strcpy(dst, src); +		dst += l; + +		src += l; +		total += l; +	} +} + +/* prepend compatible property strings with "omapdss," */ +static void __init omapdss_omapify_node(struct device_node *node) +{ +	struct property *prop; +	char *new_compat; +	int num_strs; +	int new_len; + +	prop = of_find_property(node, "compatible", NULL); + +	if (!prop || !prop->value) +		return; + +	if (strnlen(prop->value, prop->length) >= prop->length) +		return; + +	/* is it already prefixed? */ +	if (strncmp(prefix, prop->value, strlen(prefix)) == 0) +		return; + +	num_strs = omapdss_count_strings(prop); + +	new_len = prop->length + strlen(prefix) * num_strs; +	new_compat = kmalloc(new_len, GFP_KERNEL); + +	omapdss_prefix_strcpy(new_compat, new_len, prop->value, prop->length); + +	omapdss_update_prop(node, new_compat, new_len); +} + +static void __init omapdss_add_to_list(struct device_node *node, bool root) +{ +	struct dss_conv_node *n = kmalloc(sizeof(struct dss_conv_node), +		GFP_KERNEL); +	if (n) { +		n->node = node; +		n->root = root; +		list_add(&n->list, &dss_conv_list); +	} +} + +static bool __init omapdss_list_contains(const struct device_node *node) +{ +	struct dss_conv_node *n; + +	list_for_each_entry(n, &dss_conv_list, list) { +		if (n->node == node) +			return true; +	} + +	return false; +} + +static void __init omapdss_walk_device(struct device_node *node, bool root) +{ +	struct device_node *n; + +	omapdss_add_to_list(node, root); + +	/* +	 * of_graph_get_remote_port_parent() prints an error if there is no +	 * port/ports node. To avoid that, check first that there's the node. +	 */ +	n = of_get_child_by_name(node, "ports"); +	if (!n) +		n = of_get_child_by_name(node, "port"); +	if (!n) +		return; + +	of_node_put(n); + +	n = NULL; +	while ((n = of_graph_get_next_endpoint(node, n)) != NULL) { +		struct device_node *pn; + +		pn = of_graph_get_remote_port_parent(n); + +		if (!pn) { +			of_node_put(n); +			continue; +		} + +		if (!of_device_is_available(pn) || omapdss_list_contains(pn)) { +			of_node_put(pn); +			of_node_put(n); +			continue; +		} + +		omapdss_walk_device(pn, false); + +		of_node_put(n); +	} +} + +static const struct of_device_id omapdss_of_match[] __initconst = { +	{ .compatible = "ti,omap2-dss", }, +	{ .compatible = "ti,omap3-dss", }, +	{ .compatible = "ti,omap4-dss", }, +	{ .compatible = "ti,omap5-dss", }, +	{}, +}; + +static int __init omapdss_boot_init(void) +{ +	struct device_node *dss, *child; + +	INIT_LIST_HEAD(&dss_conv_list); + +	dss = of_find_matching_node(NULL, omapdss_of_match); + +	if (dss == NULL || !of_device_is_available(dss)) +		return 0; + +	omapdss_walk_device(dss, true); + +	for_each_available_child_of_node(dss, child) { +		if (!of_find_property(child, "compatible", NULL)) { +			of_node_put(child); +			continue; +		} + +		omapdss_walk_device(child, true); +	} + +	while (!list_empty(&dss_conv_list)) { +		struct dss_conv_node *n; + +		n = list_first_entry(&dss_conv_list, struct dss_conv_node, +			list); + +		if (!n->root) +			omapdss_omapify_node(n->node); + +		list_del(&n->list); +		of_node_put(n->node); +		kfree(n); +	} + +	return 0; +} + +subsys_initcall(omapdss_boot_init); diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/fbdev/omap2/dss/output.c index 2ab3afa615e..2ab3afa615e 100644 --- a/drivers/video/omap2/dss/output.c +++ b/drivers/video/fbdev/omap2/dss/output.c diff --git a/drivers/video/omap2/dss/overlay-sysfs.c b/drivers/video/fbdev/omap2/dss/overlay-sysfs.c index 4cc5ddebfb3..4cc5ddebfb3 100644 --- a/drivers/video/omap2/dss/overlay-sysfs.c +++ b/drivers/video/fbdev/omap2/dss/overlay-sysfs.c diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/fbdev/omap2/dss/overlay.c index eccde322c28..2f7cee985cd 100644 --- a/drivers/video/omap2/dss/overlay.c +++ b/drivers/video/fbdev/omap2/dss/overlay.c @@ -113,11 +113,6 @@ void dss_uninit_overlays(struct platform_device *pdev)  int dss_ovl_simple_check(struct omap_overlay *ovl,  		const struct omap_overlay_info *info)  { -	if (info->paddr == 0) { -		DSSERR("check_overlay: paddr cannot be 0\n"); -		return -EINVAL; -	} -  	if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {  		if (info->out_width != 0 && info->width != info->out_width) {  			DSSERR("check_overlay: overlay %d doesn't support " diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/fbdev/omap2/dss/rfbi.c index c8a81a2b879..c8a81a2b879 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/fbdev/omap2/dss/rfbi.c diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c index ccc569ae7cc..911dcc9173a 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/fbdev/omap2/dss/sdi.c @@ -26,6 +26,7 @@  #include <linux/export.h>  #include <linux/platform_device.h>  #include <linux/string.h> +#include <linux/of.h>  #include <video/omapdss.h>  #include "dss.h" @@ -41,12 +42,14 @@ static struct {  	int datapairs;  	struct omap_dss_device output; + +	bool port_initialized;  } sdi;  struct sdi_clk_calc_ctx {  	unsigned long pck_min, pck_max; -	struct dss_clock_info dss_cinfo; +	unsigned long fck;  	struct dispc_clock_info dispc_cinfo;  }; @@ -63,19 +66,18 @@ static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,  	return true;  } -static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data) +static bool dpi_calc_dss_cb(unsigned long fck, void *data)  {  	struct sdi_clk_calc_ctx *ctx = data; -	ctx->dss_cinfo.fck = fck; -	ctx->dss_cinfo.fck_div = fckd; +	ctx->fck = fck;  	return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max,  			dpi_calc_dispc_cb, ctx);  }  static int sdi_calc_clock_div(unsigned long pclk, -		struct dss_clock_info *dss_cinfo, +		unsigned long *fck,  		struct dispc_clock_info *dispc_cinfo)  {  	int i; @@ -98,9 +100,9 @@ static int sdi_calc_clock_div(unsigned long pclk,  			ctx.pck_min = 0;  		ctx.pck_max = pclk + 1000 * i * i * i; -		ok = dss_div_calc(ctx.pck_min, dpi_calc_dss_cb, &ctx); +		ok = dss_div_calc(pclk, ctx.pck_min, dpi_calc_dss_cb, &ctx);  		if (ok) { -			*dss_cinfo = ctx.dss_cinfo; +			*fck = ctx.fck;  			*dispc_cinfo = ctx.dispc_cinfo;  			return 0;  		} @@ -128,7 +130,7 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)  {  	struct omap_dss_device *out = &sdi.output;  	struct omap_video_timings *t = &sdi.timings; -	struct dss_clock_info dss_cinfo; +	unsigned long fck;  	struct dispc_clock_info dispc_cinfo;  	unsigned long pck;  	int r; @@ -150,26 +152,25 @@ static int sdi_display_enable(struct omap_dss_device *dssdev)  	t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;  	t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; -	r = sdi_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo); +	r = sdi_calc_clock_div(t->pixelclock, &fck, &dispc_cinfo);  	if (r)  		goto err_calc_clock_div;  	sdi.mgr_config.clock_info = dispc_cinfo; -	pck = dss_cinfo.fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div / 1000; +	pck = fck / dispc_cinfo.lck_div / dispc_cinfo.pck_div; -	if (pck != t->pixel_clock) { -		DSSWARN("Could not find exact pixel clock. Requested %d kHz, " -				"got %lu kHz\n", -				t->pixel_clock, pck); +	if (pck != t->pixelclock) { +		DSSWARN("Could not find exact pixel clock. Requested %d Hz, got %lu Hz\n", +			t->pixelclock, pck); -		t->pixel_clock = pck; +		t->pixelclock = pck;  	}  	dss_mgr_set_timings(out->manager, t); -	r = dss_set_clock_div(&dss_cinfo); +	r = dss_set_fck_rate(fck);  	if (r)  		goto err_set_dss_clock_div; @@ -245,7 +246,7 @@ static int sdi_check_timings(struct omap_dss_device *dssdev,  	if (mgr && !dispc_mgr_timings_ok(mgr->id, timings))  		return -EINVAL; -	if (timings->pixel_clock == 0) +	if (timings->pixelclock == 0)  		return -EINVAL;  	return 0; @@ -265,7 +266,8 @@ static int sdi_init_regulator(void)  	vdds_sdi = devm_regulator_get(&sdi.pdev->dev, "vdds_sdi");  	if (IS_ERR(vdds_sdi)) { -		DSSERR("can't get VDDS_SDI regulator\n"); +		if (PTR_ERR(vdds_sdi) != -EPROBE_DEFER) +			DSSERR("can't get VDDS_SDI regulator\n");  		return PTR_ERR(vdds_sdi);  	} @@ -387,3 +389,45 @@ void __exit sdi_uninit_platform_driver(void)  {  	platform_driver_unregister(&omap_sdi_driver);  } + +int __init sdi_init_port(struct platform_device *pdev, struct device_node *port) +{ +	struct device_node *ep; +	u32 datapairs; +	int r; + +	ep = omapdss_of_get_next_endpoint(port, NULL); +	if (!ep) +		return 0; + +	r = of_property_read_u32(ep, "datapairs", &datapairs); +	if (r) { +		DSSERR("failed to parse datapairs\n"); +		goto err_datapairs; +	} + +	sdi.datapairs = datapairs; + +	of_node_put(ep); + +	sdi.pdev = pdev; + +	sdi_init_output(pdev); + +	sdi.port_initialized = true; + +	return 0; + +err_datapairs: +	of_node_put(ep); + +	return r; +} + +void __exit sdi_uninit_port(void) +{ +	if (!sdi.port_initialized) +		return; + +	sdi_uninit_output(sdi.pdev); +} diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/fbdev/omap2/dss/venc.c index 5f88ac47b7f..21d81113962 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/fbdev/omap2/dss/venc.c @@ -34,6 +34,7 @@  #include <linux/platform_device.h>  #include <linux/regulator/consumer.h>  #include <linux/pm_runtime.h> +#include <linux/of.h>  #include <video/omapdss.h> @@ -264,7 +265,7 @@ static const struct venc_config venc_config_pal_bdghi = {  const struct omap_video_timings omap_dss_pal_timings = {  	.x_res		= 720,  	.y_res		= 574, -	.pixel_clock	= 13500, +	.pixelclock	= 13500000,  	.hsw		= 64,  	.hfp		= 12,  	.hbp		= 68, @@ -279,7 +280,7 @@ EXPORT_SYMBOL(omap_dss_pal_timings);  const struct omap_video_timings omap_dss_ntsc_timings = {  	.x_res		= 720,  	.y_res		= 482, -	.pixel_clock	= 13500, +	.pixelclock	= 13500000,  	.hsw		= 64,  	.hfp		= 16,  	.hbp		= 58, @@ -636,10 +637,14 @@ static int venc_init_regulator(void)  	if (venc.vdda_dac_reg != NULL)  		return 0; -	vdda_dac = devm_regulator_get(&venc.pdev->dev, "vdda_dac"); +	if (venc.pdev->dev.of_node) +		vdda_dac = devm_regulator_get(&venc.pdev->dev, "vdda"); +	else +		vdda_dac = devm_regulator_get(&venc.pdev->dev, "vdda_dac");  	if (IS_ERR(vdda_dac)) { -		DSSERR("can't get VDDA_DAC regulator\n"); +		if (PTR_ERR(vdda_dac) != -EPROBE_DEFER) +			DSSERR("can't get VDDA_DAC regulator\n");  		return PTR_ERR(vdda_dac);  	} @@ -804,6 +809,48 @@ static void __exit venc_uninit_output(struct platform_device *pdev)  	omapdss_unregister_output(out);  } +static int venc_probe_of(struct platform_device *pdev) +{ +	struct device_node *node = pdev->dev.of_node; +	struct device_node *ep; +	u32 channels; +	int r; + +	ep = omapdss_of_get_first_endpoint(node); +	if (!ep) +		return 0; + +	venc.invert_polarity = of_property_read_bool(ep, "ti,invert-polarity"); + +	r = of_property_read_u32(ep, "ti,channels", &channels); +	if (r) { +		dev_err(&pdev->dev, +			"failed to read property 'ti,channels': %d\n", r); +		goto err; +	} + +	switch (channels) { +	case 1: +		venc.type = OMAP_DSS_VENC_TYPE_COMPOSITE; +		break; +	case 2: +		venc.type = OMAP_DSS_VENC_TYPE_SVIDEO; +		break; +	default: +		dev_err(&pdev->dev, "bad channel propert '%d'\n", channels); +		r = -EINVAL; +		goto err; +	} + +	of_node_put(ep); + +	return 0; +err: +	of_node_put(ep); + +	return 0; +} +  /* VENC HW IP initialisation */  static int omap_venchw_probe(struct platform_device *pdev)  { @@ -845,12 +892,21 @@ static int omap_venchw_probe(struct platform_device *pdev)  	venc_runtime_put(); +	if (pdev->dev.of_node) { +		r = venc_probe_of(pdev); +		if (r) { +			DSSERR("Invalid DT data\n"); +			goto err_probe_of; +		} +	} +  	dss_debugfs_create_file("venc", venc_dump_regs);  	venc_init_output(pdev);  	return 0; +err_probe_of:  err_runtime_get:  	pm_runtime_disable(&pdev->dev);  	return r; @@ -894,6 +950,14 @@ static const struct dev_pm_ops venc_pm_ops = {  	.runtime_resume = venc_runtime_resume,  }; + +static const struct of_device_id venc_of_match[] = { +	{ .compatible = "ti,omap2-venc", }, +	{ .compatible = "ti,omap3-venc", }, +	{ .compatible = "ti,omap4-venc", }, +	{}, +}; +  static struct platform_driver omap_venchw_driver = {  	.probe		= omap_venchw_probe,  	.remove         = __exit_p(omap_venchw_remove), @@ -901,6 +965,7 @@ static struct platform_driver omap_venchw_driver = {  		.name   = "omapdss_venc",  		.owner  = THIS_MODULE,  		.pm	= &venc_pm_ops, +		.of_match_table = venc_of_match,  	},  }; diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/fbdev/omap2/omapfb/Kconfig index 4cb12ce6885..4cb12ce6885 100644 --- a/drivers/video/omap2/omapfb/Kconfig +++ b/drivers/video/fbdev/omap2/omapfb/Kconfig diff --git a/drivers/video/omap2/omapfb/Makefile b/drivers/video/fbdev/omap2/omapfb/Makefile index 51c2e00d9bf..51c2e00d9bf 100644 --- a/drivers/video/omap2/omapfb/Makefile +++ b/drivers/video/fbdev/omap2/omapfb/Makefile diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c index 146b6f5428d..146b6f5428d 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c index 27d6905683f..ec2d132c782 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c @@ -723,8 +723,8 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)  		display->driver->get_timings(display, &timings);  		/* pixclock in ps, the rest in pixclock */ -		var->pixclock = timings.pixel_clock != 0 ? -			KHZ2PICOS(timings.pixel_clock) : +		var->pixclock = timings.pixelclock != 0 ? +			KHZ2PICOS(timings.pixelclock / 1000) :  			0;  		var->left_margin = timings.hbp;  		var->right_margin = timings.hfp; @@ -1833,6 +1833,16 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev)  	if (fbdev == NULL)  		return; +	for (i = 0; i < fbdev->num_fbs; i++) { +		struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); +		int j; + +		for (j = 0; j < ofbi->num_overlays; j++) { +			struct omap_overlay *ovl = ofbi->overlays[j]; +			ovl->disable(ovl); +		} +	} +  	for (i = 0; i < fbdev->num_fbs; i++)  		unregister_framebuffer(fbdev->fbs[i]); @@ -2067,7 +2077,7 @@ static int omapfb_mode_to_timings(const char *mode_str,  		timings->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;  	} -	timings->pixel_clock = PICOS2KHZ(var->pixclock); +	timings->pixelclock = PICOS2KHZ(var->pixclock) * 1000;  	timings->hbp = var->left_margin;  	timings->hfp = var->right_margin;  	timings->vbp = var->upper_margin; @@ -2219,7 +2229,7 @@ static void fb_videomode_to_omap_timings(struct fb_videomode *m,  	t->x_res = m->xres;  	t->y_res = m->yres; -	t->pixel_clock = PICOS2KHZ(m->pixclock); +	t->pixelclock = PICOS2KHZ(m->pixclock) * 1000;  	t->hsw = m->hsync_len;  	t->hfp = m->right_margin;  	t->hbp = m->left_margin; @@ -2407,6 +2417,55 @@ static int omapfb_init_connections(struct omapfb2_device *fbdev,  	return 0;  } +static struct omap_dss_device * +omapfb_find_default_display(struct omapfb2_device *fbdev) +{ +	const char *def_name; +	int i; + +	/* +	 * Search with the display name from the user or the board file, +	 * comparing to display names and aliases +	 */ + +	def_name = omapdss_get_default_display_name(); + +	if (def_name) { +		for (i = 0; i < fbdev->num_displays; ++i) { +			struct omap_dss_device *dssdev; + +			dssdev = fbdev->displays[i].dssdev; + +			if (dssdev->name && strcmp(def_name, dssdev->name) == 0) +				return dssdev; + +			if (strcmp(def_name, dssdev->alias) == 0) +				return dssdev; +		} + +		/* def_name given but not found */ +		return NULL; +	} + +	/* then look for DT alias display0 */ +	for (i = 0; i < fbdev->num_displays; ++i) { +		struct omap_dss_device *dssdev; +		int id; + +		dssdev = fbdev->displays[i].dssdev; + +		if (dssdev->dev->of_node == NULL) +			continue; + +		id = of_alias_get_id(dssdev->dev->of_node, "display"); +		if (id == 0) +			return dssdev; +	} + +	/* return the first display we have in the list */ +	return fbdev->displays[0].dssdev; +} +  static int omapfb_probe(struct platform_device *pdev)  {  	struct omapfb2_device *fbdev = NULL; @@ -2484,23 +2543,7 @@ static int omapfb_probe(struct platform_device *pdev)  	for (i = 0; i < fbdev->num_managers; i++)  		fbdev->managers[i] = omap_dss_get_overlay_manager(i); -	def_display = NULL; - -	for (i = 0; i < fbdev->num_displays; ++i) { -		struct omap_dss_device *dssdev; -		const char *def_name; - -		def_name = omapdss_get_default_display_name(); - -		dssdev = fbdev->displays[i].dssdev; - -		if (def_name == NULL || -			(dssdev->name && strcmp(def_name, dssdev->name) == 0)) { -			def_display = dssdev; -			break; -		} -	} - +	def_display = omapfb_find_default_display(fbdev);  	if (def_display == NULL) {  		dev_err(fbdev->dev, "failed to find default display\n");  		r = -EPROBE_DEFER; @@ -2557,6 +2600,15 @@ static int omapfb_probe(struct platform_device *pdev)  		goto cleanup;  	} +	if (def_display) { +		u16 w, h; + +		def_display->driver->get_resolution(def_display, &w, &h); + +		dev_info(fbdev->dev, "using display '%s' mode %dx%d\n", +			def_display->name, w, h); +	} +  	return 0;  cleanup: diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c index 18fa9e1d003..18fa9e1d003 100644 --- a/drivers/video/omap2/omapfb/omapfb-sysfs.c +++ b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/fbdev/omap2/omapfb/omapfb.h index 623cd872a36..623cd872a36 100644 --- a/drivers/video/omap2/omapfb/omapfb.h +++ b/drivers/video/fbdev/omap2/omapfb/omapfb.h diff --git a/drivers/video/omap2/vrfb.c b/drivers/video/fbdev/omap2/vrfb.c index f346b02eee1..f346b02eee1 100644 --- a/drivers/video/omap2/vrfb.c +++ b/drivers/video/fbdev/omap2/vrfb.c diff --git a/drivers/video/p9100.c b/drivers/video/fbdev/p9100.c index 4b23af6e5c2..367cea8f43f 100644 --- a/drivers/video/p9100.c +++ b/drivers/video/fbdev/p9100.c @@ -339,8 +339,6 @@ static int p9100_remove(struct platform_device *op)  	framebuffer_release(info); -	dev_set_drvdata(&op->dev, NULL); -  	return 0;  } diff --git a/drivers/video/platinumfb.c b/drivers/video/fbdev/platinumfb.c index 3d86bac62d3..4c929957682 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/fbdev/platinumfb.c @@ -403,7 +403,7 @@ try_again:  	if (rc < 0)  		return rc; -	printk(KERN_INFO "fb%d: Apple Platinum frame buffer device\n", info->node); +	fb_info(info, "Apple Platinum frame buffer device\n");  	return 0;  } @@ -639,7 +639,6 @@ static int platinumfb_probe(struct platform_device* odev)  		iounmap(pinfo->frame_buffer);  		iounmap(pinfo->platinum_regs);  		iounmap(pinfo->cmap_regs); -		dev_set_drvdata(&odev->dev, NULL);  		framebuffer_release(info);  	} diff --git a/drivers/video/platinumfb.h b/drivers/video/fbdev/platinumfb.h index f6bd77cafd1..f6bd77cafd1 100644 --- a/drivers/video/platinumfb.h +++ b/drivers/video/fbdev/platinumfb.h diff --git a/drivers/video/pm2fb.c b/drivers/video/fbdev/pm2fb.c index 81354eeab02..3b85b647bc1 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/fbdev/pm2fb.c @@ -1694,8 +1694,8 @@ static int pm2fb_probe(struct pci_dev *pdev, const struct pci_device_id *id)  	if (retval < 0)  		goto err_exit_all; -	printk(KERN_INFO "fb%d: %s frame buffer device, memory = %dK.\n", -	       info->node, info->fix.id, pm2fb_fix.smem_len / 1024); +	fb_info(info, "%s frame buffer device, memory = %dK\n", +		info->fix.id, pm2fb_fix.smem_len / 1024);  	/*  	 * Our driver data @@ -1744,7 +1744,6 @@ static void pm2fb_remove(struct pci_dev *pdev)  	iounmap(par->v_regs);  	release_mem_region(fix->mmio_start, fix->mmio_len); -	pci_set_drvdata(pdev, NULL);  	fb_dealloc_cmap(&info->cmap);  	kfree(info->pixmap.addr);  	framebuffer_release(info); diff --git a/drivers/video/pm3fb.c b/drivers/video/fbdev/pm3fb.c index 7718faa4a73..4bf3273d043 100644 --- a/drivers/video/pm3fb.c +++ b/drivers/video/fbdev/pm3fb.c @@ -1445,8 +1445,7 @@ static int pm3fb_probe(struct pci_dev *dev, const struct pci_device_id *ent)  		retval = -EINVAL;  		goto err_exit_all;  	} -	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, -	   info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	pci_set_drvdata(dev, info);  	return 0; @@ -1489,7 +1488,6 @@ static void pm3fb_remove(struct pci_dev *dev)  		iounmap(par->v_regs);  		release_mem_region(fix->mmio_start, fix->mmio_len); -		pci_set_drvdata(dev, NULL);  		kfree(info->pixmap.addr);  		framebuffer_release(info);  	} diff --git a/drivers/video/pmag-aa-fb.c b/drivers/video/fbdev/pmag-aa-fb.c index 838424817de..838424817de 100644 --- a/drivers/video/pmag-aa-fb.c +++ b/drivers/video/fbdev/pmag-aa-fb.c diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/fbdev/pmag-ba-fb.c index d1e46cedb1f..914a52ba847 100644 --- a/drivers/video/pmag-ba-fb.c +++ b/drivers/video/fbdev/pmag-ba-fb.c @@ -212,8 +212,8 @@ static int pmagbafb_probe(struct device *dev)  	get_device(dev); -	pr_info("fb%d: %s frame buffer device at %s\n", -		info->node, info->fix.id, dev_name(dev)); +	fb_info(info, "%s frame buffer device at %s\n", +		info->fix.id, dev_name(dev));  	return 0; diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/fbdev/pmagb-b-fb.c index 0e131740032..0822b6f8ddd 100644 --- a/drivers/video/pmagb-b-fb.c +++ b/drivers/video/fbdev/pmagb-b-fb.c @@ -328,11 +328,10 @@ static int pmagbbfb_probe(struct device *dev)  	snprintf(freq1, sizeof(freq1), "%u.%03uMHz",  		 par->osc1 / 1000, par->osc1 % 1000); -	pr_info("fb%d: %s frame buffer device at %s\n", -		info->node, info->fix.id, dev_name(dev)); -	pr_info("fb%d: Osc0: %s, Osc1: %s, Osc%u selected\n", -		info->node, freq0, par->osc1 ? freq1 : "disabled", -		par->osc1 != 0); +	fb_info(info, "%s frame buffer device at %s\n", +		info->fix.id, dev_name(dev)); +	fb_info(info, "Osc0: %s, Osc1: %s, Osc%u selected\n", +		freq0, par->osc1 ? freq1 : "disabled", par->osc1 != 0);  	return 0; diff --git a/drivers/video/ps3fb.c b/drivers/video/fbdev/ps3fb.c index b269abd932a..b269abd932a 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/fbdev/ps3fb.c diff --git a/drivers/video/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c index df07860563e..167cffff3d4 100644 --- a/drivers/video/pvr2fb.c +++ b/drivers/video/fbdev/pvr2fb.c @@ -817,24 +817,25 @@ static int pvr2fb_common_init(void)  	rev = fb_readl(par->mmio_base + 0x04); -	printk("fb%d: %s (rev %ld.%ld) frame buffer device, using %ldk/%ldk of video memory\n", -	       fb_info->node, fb_info->fix.id, (rev >> 4) & 0x0f, rev & 0x0f, -	       modememused >> 10, (unsigned long)(fb_info->fix.smem_len >> 10)); -	printk("fb%d: Mode %dx%d-%d pitch = %ld cable: %s video output: %s\n", -	       fb_info->node, fb_info->var.xres, fb_info->var.yres, -	       fb_info->var.bits_per_pixel, -	       get_line_length(fb_info->var.xres, fb_info->var.bits_per_pixel), -	       (char *)pvr2_get_param(cables, NULL, cable_type, 3), -	       (char *)pvr2_get_param(outputs, NULL, video_output, 3)); +	fb_info(fb_info, "%s (rev %ld.%ld) frame buffer device, using %ldk/%ldk of video memory\n", +		fb_info->fix.id, (rev >> 4) & 0x0f, rev & 0x0f, +		modememused >> 10, +		(unsigned long)(fb_info->fix.smem_len >> 10)); +	fb_info(fb_info, "Mode %dx%d-%d pitch = %ld cable: %s video output: %s\n", +		fb_info->var.xres, fb_info->var.yres, +		fb_info->var.bits_per_pixel, +		get_line_length(fb_info->var.xres, fb_info->var.bits_per_pixel), +		(char *)pvr2_get_param(cables, NULL, cable_type, 3), +		(char *)pvr2_get_param(outputs, NULL, video_output, 3));  #ifdef CONFIG_SH_STORE_QUEUES -	printk(KERN_NOTICE "fb%d: registering with SQ API\n", fb_info->node); +	fb_notice(fb_info, "registering with SQ API\n");  	pvr2fb_map = sq_remap(fb_info->fix.smem_start, fb_info->fix.smem_len,  			      fb_info->fix.id, PAGE_SHARED); -	printk(KERN_NOTICE "fb%d: Mapped video memory to SQ addr 0x%lx\n", -	       fb_info->node, pvr2fb_map); +	fb_notice(fb_info, "Mapped video memory to SQ addr 0x%lx\n", +		  pvr2fb_map);  #endif  	return 0; diff --git a/drivers/video/pxa168fb.c b/drivers/video/fbdev/pxa168fb.c index aa9bd1f76d6..c95b9e46d48 100644 --- a/drivers/video/pxa168fb.c +++ b/drivers/video/fbdev/pxa168fb.c @@ -364,7 +364,7 @@ static void set_graphics_start(struct fb_info *info, int xoffset, int yoffset)  static void set_dumb_panel_control(struct fb_info *info)  {  	struct pxa168fb_info *fbi = info->par; -	struct pxa168fb_mach_info *mi = fbi->dev->platform_data; +	struct pxa168fb_mach_info *mi = dev_get_platdata(fbi->dev);  	u32 x;  	/* @@ -407,7 +407,7 @@ static int pxa168fb_set_par(struct fb_info *info)  	u32 x;  	struct pxa168fb_mach_info *mi; -	mi = fbi->dev->platform_data; +	mi = dev_get_platdata(fbi->dev);  	/*  	 * Set additional mode info. @@ -609,7 +609,7 @@ static int pxa168fb_probe(struct platform_device *pdev)  	struct clk *clk;  	int irq, ret; -	mi = pdev->dev.platform_data; +	mi = dev_get_platdata(&pdev->dev);  	if (mi == NULL) {  		dev_err(&pdev->dev, "no platform data defined\n");  		return -EINVAL; diff --git a/drivers/video/pxa168fb.h b/drivers/video/fbdev/pxa168fb.h index eee09279c52..eee09279c52 100644 --- a/drivers/video/pxa168fb.h +++ b/drivers/video/fbdev/pxa168fb.h diff --git a/drivers/video/pxa3xx-gcu.c b/drivers/video/fbdev/pxa3xx-gcu.c index ad382b3396c..4df3657fe22 100644 --- a/drivers/video/pxa3xx-gcu.c +++ b/drivers/video/fbdev/pxa3xx-gcu.c @@ -107,7 +107,6 @@ struct pxa3xx_gcu_priv {  	struct timeval 		  base_time;  	struct pxa3xx_gcu_batch *free; -  	struct pxa3xx_gcu_batch *ready;  	struct pxa3xx_gcu_batch *ready_last;  	struct pxa3xx_gcu_batch *running; @@ -368,27 +367,35 @@ pxa3xx_gcu_wait_free(struct pxa3xx_gcu_priv *priv)  /* Misc device layer */ -static inline struct pxa3xx_gcu_priv *file_dev(struct file *file) +static inline struct pxa3xx_gcu_priv *to_pxa3xx_gcu_priv(struct file *file)  {  	struct miscdevice *dev = file->private_data;  	return container_of(dev, struct pxa3xx_gcu_priv, misc_dev);  } +/* + * provide an empty .open callback, so the core sets file->private_data + * for us. + */ +static int pxa3xx_gcu_open(struct inode *inode, struct file *file) +{ +	return 0; +} +  static ssize_t -pxa3xx_gcu_misc_write(struct file *file, const char *buff, -		      size_t count, loff_t *offp) +pxa3xx_gcu_write(struct file *file, const char *buff, +		 size_t count, loff_t *offp)  {  	int ret;  	unsigned long flags;  	struct pxa3xx_gcu_batch	*buffer; -	struct pxa3xx_gcu_priv *priv = file_dev(file); +	struct pxa3xx_gcu_priv *priv = to_pxa3xx_gcu_priv(file);  	int words = count / 4;  	/* Does not need to be atomic. There's a lock in user space,  	 * but anyhow, this is just for statistics. */  	priv->shared->num_writes++; -  	priv->shared->num_words += words;  	/* Last word reserved for batch buffer end command */ @@ -406,10 +413,8 @@ pxa3xx_gcu_misc_write(struct file *file, const char *buff,  	 * Get buffer from free list  	 */  	spin_lock_irqsave(&priv->spinlock, flags); -  	buffer = priv->free;  	priv->free = buffer->next; -  	spin_unlock_irqrestore(&priv->spinlock, flags); @@ -454,10 +459,10 @@ pxa3xx_gcu_misc_write(struct file *file, const char *buff,  static long -pxa3xx_gcu_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +pxa3xx_gcu_ioctl(struct file *file, unsigned int cmd, unsigned long arg)  {  	unsigned long flags; -	struct pxa3xx_gcu_priv *priv = file_dev(file); +	struct pxa3xx_gcu_priv *priv = to_pxa3xx_gcu_priv(file);  	switch (cmd) {  	case PXA3XX_GCU_IOCTL_RESET: @@ -474,10 +479,10 @@ pxa3xx_gcu_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)  }  static int -pxa3xx_gcu_misc_mmap(struct file *file, struct vm_area_struct *vma) +pxa3xx_gcu_mmap(struct file *file, struct vm_area_struct *vma)  {  	unsigned int size = vma->vm_end - vma->vm_start; -	struct pxa3xx_gcu_priv *priv = file_dev(file); +	struct pxa3xx_gcu_priv *priv = to_pxa3xx_gcu_priv(file);  	switch (vma->vm_pgoff) {  	case 0: @@ -532,8 +537,8 @@ static inline void pxa3xx_gcu_init_debug_timer(void) {}  #endif  static int -add_buffer(struct platform_device *dev, -	   struct pxa3xx_gcu_priv *priv) +pxa3xx_gcu_add_buffer(struct device *dev, +		      struct pxa3xx_gcu_priv *priv)  {  	struct pxa3xx_gcu_batch *buffer; @@ -541,7 +546,7 @@ add_buffer(struct platform_device *dev,  	if (!buffer)  		return -ENOMEM; -	buffer->ptr = dma_alloc_coherent(&dev->dev, PXA3XX_GCU_BATCH_WORDS * 4, +	buffer->ptr = dma_alloc_coherent(dev, PXA3XX_GCU_BATCH_WORDS * 4,  					 &buffer->phys, GFP_KERNEL);  	if (!buffer->ptr) {  		kfree(buffer); @@ -549,57 +554,49 @@ add_buffer(struct platform_device *dev,  	}  	buffer->next = priv->free; -  	priv->free = buffer;  	return 0;  }  static void -free_buffers(struct platform_device *dev, -	     struct pxa3xx_gcu_priv *priv) +pxa3xx_gcu_free_buffers(struct device *dev, +			struct pxa3xx_gcu_priv *priv)  {  	struct pxa3xx_gcu_batch *next, *buffer = priv->free;  	while (buffer) {  		next = buffer->next; -		dma_free_coherent(&dev->dev, PXA3XX_GCU_BATCH_WORDS * 4, +		dma_free_coherent(dev, PXA3XX_GCU_BATCH_WORDS * 4,  				  buffer->ptr, buffer->phys);  		kfree(buffer); -  		buffer = next;  	}  	priv->free = NULL;  } -static const struct file_operations misc_fops = { -	.owner	= THIS_MODULE, -	.write	= pxa3xx_gcu_misc_write, -	.unlocked_ioctl = pxa3xx_gcu_misc_ioctl, -	.mmap	= pxa3xx_gcu_misc_mmap +static const struct file_operations pxa3xx_gcu_miscdev_fops = { +	.owner =		THIS_MODULE, +	.open =			pxa3xx_gcu_open, +	.write =		pxa3xx_gcu_write, +	.unlocked_ioctl =	pxa3xx_gcu_ioctl, +	.mmap =			pxa3xx_gcu_mmap,  }; -static int pxa3xx_gcu_probe(struct platform_device *dev) +static int pxa3xx_gcu_probe(struct platform_device *pdev)  {  	int i, ret, irq;  	struct resource *r;  	struct pxa3xx_gcu_priv *priv; +	struct device *dev = &pdev->dev; -	priv = kzalloc(sizeof(struct pxa3xx_gcu_priv), GFP_KERNEL); +	priv = devm_kzalloc(dev, sizeof(struct pxa3xx_gcu_priv), GFP_KERNEL);  	if (!priv)  		return -ENOMEM; -	for (i = 0; i < 8; i++) { -		ret = add_buffer(dev, priv); -		if (ret) { -			dev_err(&dev->dev, "failed to allocate DMA memory\n"); -			goto err_free_priv; -		} -	} -  	init_waitqueue_head(&priv->wait_idle);  	init_waitqueue_head(&priv->wait_free);  	spin_lock_init(&priv->spinlock); @@ -611,125 +608,97 @@ static int pxa3xx_gcu_probe(struct platform_device *dev)  	priv->misc_dev.minor	= MISCDEV_MINOR,  	priv->misc_dev.name	= DRV_NAME, -	priv->misc_dev.fops	= &misc_fops, - -	/* register misc device */ -	ret = misc_register(&priv->misc_dev); -	if (ret < 0) { -		dev_err(&dev->dev, "misc_register() for minor %d failed\n", -			MISCDEV_MINOR); -		goto err_free_priv; -	} +	priv->misc_dev.fops	= &pxa3xx_gcu_miscdev_fops;  	/* handle IO resources */ -	r = platform_get_resource(dev, IORESOURCE_MEM, 0); -	if (r == NULL) { -		dev_err(&dev->dev, "no I/O memory resource defined\n"); -		ret = -ENODEV; -		goto err_misc_deregister; +	r = platform_get_resource(pdev, IORESOURCE_MEM, 0); +	priv->mmio_base = devm_ioremap_resource(dev, r); +	if (IS_ERR(priv->mmio_base)) +		return PTR_ERR(priv->mmio_base); + +	/* enable the clock */ +	priv->clk = devm_clk_get(dev, NULL); +	if (IS_ERR(priv->clk)) { +		dev_err(dev, "failed to get clock\n"); +		return PTR_ERR(priv->clk);  	} -	if (!request_mem_region(r->start, resource_size(r), dev->name)) { -		dev_err(&dev->dev, "failed to request I/O memory\n"); -		ret = -EBUSY; -		goto err_misc_deregister; +	/* request the IRQ */ +	irq = platform_get_irq(pdev, 0); +	if (irq < 0) { +		dev_err(dev, "no IRQ defined\n"); +		return -ENODEV;  	} -	priv->mmio_base = ioremap_nocache(r->start, resource_size(r)); -	if (!priv->mmio_base) { -		dev_err(&dev->dev, "failed to map I/O memory\n"); -		ret = -EBUSY; -		goto err_free_mem_region; +	ret = devm_request_irq(dev, irq, pxa3xx_gcu_handle_irq, +			       0, DRV_NAME, priv); +	if (ret < 0) { +		dev_err(dev, "request_irq failed\n"); +		return ret;  	}  	/* allocate dma memory */ -	priv->shared = dma_alloc_coherent(&dev->dev, SHARED_SIZE, +	priv->shared = dma_alloc_coherent(dev, SHARED_SIZE,  					  &priv->shared_phys, GFP_KERNEL); -  	if (!priv->shared) { -		dev_err(&dev->dev, "failed to allocate DMA memory\n"); -		ret = -ENOMEM; -		goto err_free_io; +		dev_err(dev, "failed to allocate DMA memory\n"); +		return -ENOMEM;  	} -	/* enable the clock */ -	priv->clk = clk_get(&dev->dev, NULL); -	if (IS_ERR(priv->clk)) { -		dev_err(&dev->dev, "failed to get clock\n"); -		ret = -ENODEV; +	/* register misc device */ +	ret = misc_register(&priv->misc_dev); +	if (ret < 0) { +		dev_err(dev, "misc_register() for minor %d failed\n", +			MISCDEV_MINOR);  		goto err_free_dma;  	}  	ret = clk_enable(priv->clk);  	if (ret < 0) { -		dev_err(&dev->dev, "failed to enable clock\n"); -		goto err_put_clk; -	} - -	/* request the IRQ */ -	irq = platform_get_irq(dev, 0); -	if (irq < 0) { -		dev_err(&dev->dev, "no IRQ defined\n"); -		ret = -ENODEV; -		goto err_put_clk; +		dev_err(dev, "failed to enable clock\n"); +		goto err_misc_deregister;  	} -	ret = request_irq(irq, pxa3xx_gcu_handle_irq, -			  0, DRV_NAME, priv); -	if (ret) { -		dev_err(&dev->dev, "request_irq failed\n"); -		ret = -EBUSY; -		goto err_put_clk; +	for (i = 0; i < 8; i++) { +		ret = pxa3xx_gcu_add_buffer(dev, priv); +		if (ret) { +			dev_err(dev, "failed to allocate DMA memory\n"); +			goto err_disable_clk; +		}  	} -	platform_set_drvdata(dev, priv); +	platform_set_drvdata(pdev, priv);  	priv->resource_mem = r;  	pxa3xx_gcu_reset(priv);  	pxa3xx_gcu_init_debug_timer(); -	dev_info(&dev->dev, "registered @0x%p, DMA 0x%p (%d bytes), IRQ %d\n", +	dev_info(dev, "registered @0x%p, DMA 0x%p (%d bytes), IRQ %d\n",  			(void *) r->start, (void *) priv->shared_phys,  			SHARED_SIZE, irq);  	return 0; -err_put_clk: -	clk_disable(priv->clk); -	clk_put(priv->clk); -  err_free_dma: -	dma_free_coherent(&dev->dev, SHARED_SIZE, +	dma_free_coherent(dev, SHARED_SIZE,  			priv->shared, priv->shared_phys); -err_free_io: -	iounmap(priv->mmio_base); - -err_free_mem_region: -	release_mem_region(r->start, resource_size(r)); -  err_misc_deregister:  	misc_deregister(&priv->misc_dev); -err_free_priv: -	free_buffers(dev, priv); -	kfree(priv); +err_disable_clk: +	clk_disable(priv->clk); +  	return ret;  } -static int pxa3xx_gcu_remove(struct platform_device *dev) +static int pxa3xx_gcu_remove(struct platform_device *pdev)  { -	struct pxa3xx_gcu_priv *priv = platform_get_drvdata(dev); -	struct resource *r = priv->resource_mem; +	struct pxa3xx_gcu_priv *priv = platform_get_drvdata(pdev); +	struct device *dev = &pdev->dev;  	pxa3xx_gcu_wait_idle(priv); -  	misc_deregister(&priv->misc_dev); -	dma_free_coherent(&dev->dev, SHARED_SIZE, -			priv->shared, priv->shared_phys); -	iounmap(priv->mmio_base); -	release_mem_region(r->start, resource_size(r)); -	clk_disable(priv->clk); -	free_buffers(dev, priv); -	kfree(priv); +	dma_free_coherent(dev, SHARED_SIZE, priv->shared, priv->shared_phys); +	pxa3xx_gcu_free_buffers(dev, priv);  	return 0;  } diff --git a/drivers/video/pxa3xx-gcu.h b/drivers/video/fbdev/pxa3xx-gcu.h index 0428ed03dc4..0428ed03dc4 100644 --- a/drivers/video/pxa3xx-gcu.h +++ b/drivers/video/fbdev/pxa3xx-gcu.h diff --git a/drivers/video/pxafb.c b/drivers/video/fbdev/pxafb.c index eca2de45f7a..1ecd9cec292 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/fbdev/pxafb.c @@ -457,7 +457,7 @@ static int pxafb_adjust_timing(struct pxafb_info *fbi,  static int pxafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)  {  	struct pxafb_info *fbi = (struct pxafb_info *)info; -	struct pxafb_mach_info *inf = fbi->dev->platform_data; +	struct pxafb_mach_info *inf = dev_get_platdata(fbi->dev);  	int err;  	if (inf->fixed_modes) { @@ -1230,7 +1230,7 @@ static unsigned int __smart_timing(unsigned time_ns, unsigned long lcd_clk)  static void setup_smart_timing(struct pxafb_info *fbi,  				struct fb_var_screeninfo *var)  { -	struct pxafb_mach_info *inf = fbi->dev->platform_data; +	struct pxafb_mach_info *inf = dev_get_platdata(fbi->dev);  	struct pxafb_mode_info *mode = &inf->modes[0];  	unsigned long lclk = clk_get_rate(fbi->clk);  	unsigned t1, t2, t3, t4; @@ -1258,14 +1258,14 @@ static void setup_smart_timing(struct pxafb_info *fbi,  static int pxafb_smart_thread(void *arg)  {  	struct pxafb_info *fbi = arg; -	struct pxafb_mach_info *inf = fbi->dev->platform_data; +	struct pxafb_mach_info *inf = dev_get_platdata(fbi->dev);  	if (!inf->smart_update) {  		pr_err("%s: not properly initialized, thread terminated\n",  				__func__);  		return -EINVAL;  	} -	inf = fbi->dev->platform_data; +	inf = dev_get_platdata(fbi->dev);  	pr_debug("%s(): task starting\n", __func__); @@ -1793,7 +1793,7 @@ static struct pxafb_info *pxafb_init_fbinfo(struct device *dev)  {  	struct pxafb_info *fbi;  	void *addr; -	struct pxafb_mach_info *inf = dev->platform_data; +	struct pxafb_mach_info *inf = dev_get_platdata(dev);  	/* Alloc the pxafb_info and pseudo_palette in one step */  	fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL); @@ -1855,7 +1855,7 @@ static struct pxafb_info *pxafb_init_fbinfo(struct device *dev)  #ifdef CONFIG_FB_PXA_PARAMETERS  static int parse_opt_mode(struct device *dev, const char *this_opt)  { -	struct pxafb_mach_info *inf = dev->platform_data; +	struct pxafb_mach_info *inf = dev_get_platdata(dev);  	const char *name = this_opt+5;  	unsigned int namelen = strlen(name); @@ -1914,7 +1914,7 @@ done:  static int parse_opt(struct device *dev, char *this_opt)  { -	struct pxafb_mach_info *inf = dev->platform_data; +	struct pxafb_mach_info *inf = dev_get_platdata(dev);  	struct pxafb_mode_info *mode = &inf->modes[0];  	char s[64]; @@ -2102,7 +2102,7 @@ static int pxafb_probe(struct platform_device *dev)  	dev_dbg(&dev->dev, "pxafb_probe\n"); -	inf = dev->dev.platform_data; +	inf = dev_get_platdata(&dev->dev);  	ret = -ENOMEM;  	fbi = NULL;  	if (!inf) diff --git a/drivers/video/pxafb.h b/drivers/video/fbdev/pxafb.h index 26ba9fa3f73..26ba9fa3f73 100644 --- a/drivers/video/pxafb.h +++ b/drivers/video/fbdev/pxafb.h diff --git a/drivers/video/q40fb.c b/drivers/video/fbdev/q40fb.c index d44c7351de0..7487f76f627 100644 --- a/drivers/video/q40fb.c +++ b/drivers/video/fbdev/q40fb.c @@ -119,8 +119,7 @@ static int q40fb_probe(struct platform_device *dev)  		return -EINVAL;  	} -        printk(KERN_INFO "fb%d: Q40 frame buffer alive and kicking !\n", -	       info->node); +	fb_info(info, "Q40 frame buffer alive and kicking !\n");  	return 0;  } diff --git a/drivers/video/riva/Makefile b/drivers/video/fbdev/riva/Makefile index 8898c9915b0..8898c9915b0 100644 --- a/drivers/video/riva/Makefile +++ b/drivers/video/fbdev/riva/Makefile diff --git a/drivers/video/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c index 9536715b5a1..8a8d7f06078 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/fbdev/riva/fbdev.c @@ -1185,11 +1185,6 @@ static int rivafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)  	if (rivafb_do_maximize(info, var, nom, den) < 0)  		return -EINVAL; -	if (var->xoffset < 0) -		var->xoffset = 0; -	if (var->yoffset < 0) -		var->yoffset = 0; -  	/* truncate xoffset and yoffset to maximum if too high */  	if (var->xoffset > var->xres_virtual - var->xres)  		var->xoffset = var->xres_virtual - var->xres - 1; @@ -2133,7 +2128,6 @@ static void rivafb_remove(struct pci_dev *pd)  	pci_release_regions(pd);  	kfree(info->pixmap.addr);  	framebuffer_release(info); -	pci_set_drvdata(pd, NULL);  	NVTRACE_LEAVE();  } diff --git a/drivers/video/riva/nv_driver.c b/drivers/video/fbdev/riva/nv_driver.c index f3694cf17e5..f3694cf17e5 100644 --- a/drivers/video/riva/nv_driver.c +++ b/drivers/video/fbdev/riva/nv_driver.c diff --git a/drivers/video/riva/nv_type.h b/drivers/video/fbdev/riva/nv_type.h index a69480c9a67..a69480c9a67 100644 --- a/drivers/video/riva/nv_type.h +++ b/drivers/video/fbdev/riva/nv_type.h diff --git a/drivers/video/riva/nvreg.h b/drivers/video/fbdev/riva/nvreg.h index abfc167ae8d..abfc167ae8d 100644 --- a/drivers/video/riva/nvreg.h +++ b/drivers/video/fbdev/riva/nvreg.h diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/fbdev/riva/riva_hw.c index 78fdbf5178d..78fdbf5178d 100644 --- a/drivers/video/riva/riva_hw.c +++ b/drivers/video/fbdev/riva/riva_hw.c diff --git a/drivers/video/riva/riva_hw.h b/drivers/video/fbdev/riva/riva_hw.h index c2769f73e0b..c2769f73e0b 100644 --- a/drivers/video/riva/riva_hw.h +++ b/drivers/video/fbdev/riva/riva_hw.h diff --git a/drivers/video/riva/riva_tbl.h b/drivers/video/fbdev/riva/riva_tbl.h index 7ee7d72932d..7ee7d72932d 100644 --- a/drivers/video/riva/riva_tbl.h +++ b/drivers/video/fbdev/riva/riva_tbl.h diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/fbdev/riva/rivafb-i2c.c index 6a183375ced..6a183375ced 100644 --- a/drivers/video/riva/rivafb-i2c.c +++ b/drivers/video/fbdev/riva/rivafb-i2c.c diff --git a/drivers/video/riva/rivafb.h b/drivers/video/fbdev/riva/rivafb.h index d9f107b704c..d9f107b704c 100644 --- a/drivers/video/riva/rivafb.h +++ b/drivers/video/fbdev/riva/rivafb.h diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/fbdev/s1d13xxxfb.c index 05c2dc3d4bc..83433cb0dfb 100644 --- a/drivers/video/s1d13xxxfb.c +++ b/drivers/video/fbdev/s1d13xxxfb.c @@ -777,8 +777,8 @@ static int s1d13xxxfb_probe(struct platform_device *pdev)  	printk(KERN_INFO "Epson S1D13XXX FB Driver\n");  	/* enable platform-dependent hardware glue, if any */ -	if (pdev->dev.platform_data) -		pdata = pdev->dev.platform_data; +	if (dev_get_platdata(&pdev->dev)) +		pdata = dev_get_platdata(&pdev->dev);  	if (pdata && pdata->platform_init_video)  		pdata->platform_init_video(); @@ -901,8 +901,7 @@ static int s1d13xxxfb_probe(struct platform_device *pdev)  		goto bail;  	} -	printk(KERN_INFO "fb%d: %s frame buffer device\n", -	       info->node, info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	return 0; @@ -923,8 +922,8 @@ static int s1d13xxxfb_suspend(struct platform_device *dev, pm_message_t state)  	lcd_enable(s1dfb, 0);  	crt_enable(s1dfb, 0); -	if (dev->dev.platform_data) -		pdata = dev->dev.platform_data; +	if (dev_get_platdata(&dev->dev)) +		pdata = dev_get_platdata(&dev->dev);  #if 0  	if (!s1dfb->disp_save) @@ -973,8 +972,8 @@ static int s1d13xxxfb_resume(struct platform_device *dev)  	while ((s1d13xxxfb_readreg(s1dfb, S1DREG_PS_STATUS) & 0x01))  		udelay(10); -	if (dev->dev.platform_data) -		pdata = dev->dev.platform_data; +	if (dev_get_platdata(&dev->dev)) +		pdata = dev_get_platdata(&dev->dev);  	if (s1dfb->regs_save) {  		/* will write RO regs, *should* get away with it :) */ diff --git a/drivers/video/s3c-fb.c b/drivers/video/fbdev/s3c-fb.c index 2e7991c7ca0..62acae2694a 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/fbdev/s3c-fb.c @@ -1378,7 +1378,7 @@ static int s3c_fb_probe(struct platform_device *pdev)  		return -EINVAL;  	} -	pd = pdev->dev.platform_data; +	pd = dev_get_platdata(&pdev->dev);  	if (!pd) {  		dev_err(dev, "no platform data specified\n");  		return -EINVAL; diff --git a/drivers/video/s3c2410fb.c b/drivers/video/fbdev/s3c2410fb.c index 21a32adbb8e..81af5a63e9e 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/fbdev/s3c2410fb.c @@ -123,7 +123,7 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,  			       struct fb_info *info)  {  	struct s3c2410fb_info *fbi = info->par; -	struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data; +	struct s3c2410fb_mach_info *mach_info = dev_get_platdata(fbi->dev);  	struct s3c2410fb_display *display = NULL;  	struct s3c2410fb_display *default_display = mach_info->displays +  						    mach_info->default_display; @@ -686,7 +686,7 @@ static inline void modify_gpio(void __iomem *reg,  static int s3c2410fb_init_registers(struct fb_info *info)  {  	struct s3c2410fb_info *fbi = info->par; -	struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data; +	struct s3c2410fb_mach_info *mach_info = dev_get_platdata(fbi->dev);  	unsigned long flags;  	void __iomem *regs = fbi->io;  	void __iomem *tpal; @@ -833,7 +833,7 @@ static int s3c24xxfb_probe(struct platform_device *pdev,  	int size;  	u32 lcdcon1; -	mach_info = pdev->dev.platform_data; +	mach_info = dev_get_platdata(&pdev->dev);  	if (mach_info == NULL) {  		dev_err(&pdev->dev,  			"no platform data for lcd, cannot attach\n"); diff --git a/drivers/video/s3c2410fb.h b/drivers/video/fbdev/s3c2410fb.h index 47a17bd2301..47a17bd2301 100644 --- a/drivers/video/s3c2410fb.h +++ b/drivers/video/fbdev/s3c2410fb.h diff --git a/drivers/video/s3fb.c b/drivers/video/fbdev/s3fb.c index 47ca86c5c6c..c43b969e1e2 100644 --- a/drivers/video/s3fb.c +++ b/drivers/video/fbdev/s3fb.c @@ -306,8 +306,8 @@ static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)  	if ((map->width != 8) || (map->height != 16) ||  	    (map->depth != 1) || (map->length != 256)) { -	    	printk(KERN_ERR "fb%d: unsupported font parameters: width %d, height %d, depth %d, length %d\n", -			info->node, map->width, map->height, map->depth, map->length); +		fb_err(info, "unsupported font parameters: width %d, height %d, depth %d, length %d\n", +		       map->width, map->height, map->depth, map->length);  		return;  	} @@ -476,7 +476,7 @@ static void s3_set_pixclock(struct fb_info *info, u32 pixclock)  	rv = svga_compute_pll((par->chip == CHIP_365_TRIO3D) ? &s3_trio3d_pll : &s3_pll,  			      1000000000 / pixclock, &m, &n, &r, info->node);  	if (rv < 0) { -		printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node); +		fb_err(info, "cannot set requested pixclock, keeping old value\n");  		return;  	} @@ -569,7 +569,7 @@ static int s3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)  		rv = -EINVAL;  	if (rv < 0) { -		printk(KERN_ERR "fb%d: unsupported mode requested\n", info->node); +		fb_err(info, "unsupported mode requested\n");  		return rv;  	} @@ -587,22 +587,21 @@ static int s3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)  	/* Check whether have enough memory */  	mem = ((var->bits_per_pixel * var->xres_virtual) >> 3) * var->yres_virtual;  	if (mem > info->screen_size) { -		printk(KERN_ERR "fb%d: not enough framebuffer memory (%d kB requested , %d kB available)\n", -			info->node, mem >> 10, (unsigned int) (info->screen_size >> 10)); +		fb_err(info, "not enough framebuffer memory (%d kB requested , %u kB available)\n", +		       mem >> 10, (unsigned int) (info->screen_size >> 10));  		return -EINVAL;  	}  	rv = svga_check_timings (&s3_timing_regs, var, info->node);  	if (rv < 0) { -		printk(KERN_ERR "fb%d: invalid timings requested\n", info->node); +		fb_err(info, "invalid timings requested\n");  		return rv;  	}  	rv = svga_compute_pll(&s3_pll, PICOS2KHZ(var->pixclock), &m, &n, &r,  				info->node);  	if (rv < 0) { -		printk(KERN_ERR "fb%d: invalid pixclock value requested\n", -			info->node); +		fb_err(info, "invalid pixclock value requested\n");  		return rv;  	} @@ -686,7 +685,7 @@ static int s3fb_set_par(struct fb_info *info)  	/* Set the offset register */ -	pr_debug("fb%d: offset register       : %d\n", info->node, offset_value); +	fb_dbg(info, "offset register       : %d\n", offset_value);  	svga_wcrt_multi(par->state.vgabase, s3_offset_regs, offset_value);  	if (par->chip != CHIP_357_VIRGE_GX2 && @@ -769,7 +768,7 @@ static int s3fb_set_par(struct fb_info *info)  	/* Set mode-specific register values */  	switch (mode) {  	case 0: -		pr_debug("fb%d: text mode\n", info->node); +		fb_dbg(info, "text mode\n");  		svga_set_textmode_vga_regs(par->state.vgabase);  		/* Set additional registers like in 8-bit mode */ @@ -780,12 +779,12 @@ static int s3fb_set_par(struct fb_info *info)  		svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);  		if (fasttext) { -			pr_debug("fb%d: high speed text mode set\n", info->node); +			fb_dbg(info, "high speed text mode set\n");  			svga_wcrt_mask(par->state.vgabase, 0x31, 0x40, 0x40);  		}  		break;  	case 1: -		pr_debug("fb%d: 4 bit pseudocolor\n", info->node); +		fb_dbg(info, "4 bit pseudocolor\n");  		vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);  		/* Set additional registers like in 8-bit mode */ @@ -796,7 +795,7 @@ static int s3fb_set_par(struct fb_info *info)  		svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);  		break;  	case 2: -		pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); +		fb_dbg(info, "4 bit pseudocolor, planar\n");  		/* Set additional registers like in 8-bit mode */  		svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30); @@ -806,7 +805,7 @@ static int s3fb_set_par(struct fb_info *info)  		svga_wcrt_mask(par->state.vgabase, 0x3A, 0x00, 0x30);  		break;  	case 3: -		pr_debug("fb%d: 8 bit pseudocolor\n", info->node); +		fb_dbg(info, "8 bit pseudocolor\n");  		svga_wcrt_mask(par->state.vgabase, 0x50, 0x00, 0x30);  		if (info->var.pixclock > 20000 ||  		    par->chip == CHIP_357_VIRGE_GX2 || @@ -822,7 +821,7 @@ static int s3fb_set_par(struct fb_info *info)  		}  		break;  	case 4: -		pr_debug("fb%d: 5/5/5 truecolor\n", info->node); +		fb_dbg(info, "5/5/5 truecolor\n");  		if (par->chip == CHIP_988_VIRGE_VX) {  			if (info->var.pixclock > 20000)  				svga_wcrt_mask(par->state.vgabase, 0x67, 0x20, 0xF0); @@ -850,7 +849,7 @@ static int s3fb_set_par(struct fb_info *info)  		}  		break;  	case 5: -		pr_debug("fb%d: 5/6/5 truecolor\n", info->node); +		fb_dbg(info, "5/6/5 truecolor\n");  		if (par->chip == CHIP_988_VIRGE_VX) {  			if (info->var.pixclock > 20000)  				svga_wcrt_mask(par->state.vgabase, 0x67, 0x40, 0xF0); @@ -879,16 +878,16 @@ static int s3fb_set_par(struct fb_info *info)  		break;  	case 6:  		/* VIRGE VX case */ -		pr_debug("fb%d: 8/8/8 truecolor\n", info->node); +		fb_dbg(info, "8/8/8 truecolor\n");  		svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0);  		break;  	case 7: -		pr_debug("fb%d: 8/8/8/8 truecolor\n", info->node); +		fb_dbg(info, "8/8/8/8 truecolor\n");  		svga_wcrt_mask(par->state.vgabase, 0x50, 0x30, 0x30);  		svga_wcrt_mask(par->state.vgabase, 0x67, 0xD0, 0xF0);  		break;  	default: -		printk(KERN_ERR "fb%d: unsupported mode - bug\n", info->node); +		fb_err(info, "unsupported mode - bug\n");  		return -EINVAL;  	} @@ -991,27 +990,27 @@ static int s3fb_blank(int blank_mode, struct fb_info *info)  	switch (blank_mode) {  	case FB_BLANK_UNBLANK: -		pr_debug("fb%d: unblank\n", info->node); +		fb_dbg(info, "unblank\n");  		svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);  		svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);  		break;  	case FB_BLANK_NORMAL: -		pr_debug("fb%d: blank\n", info->node); +		fb_dbg(info, "blank\n");  		svga_wcrt_mask(par->state.vgabase, 0x56, 0x00, 0x06);  		svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);  		break;  	case FB_BLANK_HSYNC_SUSPEND: -		pr_debug("fb%d: hsync\n", info->node); +		fb_dbg(info, "hsync\n");  		svga_wcrt_mask(par->state.vgabase, 0x56, 0x02, 0x06);  		svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);  		break;  	case FB_BLANK_VSYNC_SUSPEND: -		pr_debug("fb%d: vsync\n", info->node); +		fb_dbg(info, "vsync\n");  		svga_wcrt_mask(par->state.vgabase, 0x56, 0x04, 0x06);  		svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);  		break;  	case FB_BLANK_POWERDOWN: -		pr_debug("fb%d: sync down\n", info->node); +		fb_dbg(info, "sync down\n");  		svga_wcrt_mask(par->state.vgabase, 0x56, 0x06, 0x06);  		svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);  		break; @@ -1181,7 +1180,7 @@ static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  	vga_res.flags = IORESOURCE_IO; -	pcibios_bus_to_resource(dev, &vga_res, &bus_reg); +	pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg);  	par->state.vgabase = (void __iomem *) vga_res.start; @@ -1336,14 +1335,7 @@ static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  			(info->var.bits_per_pixel * info->var.xres_virtual);  	if (info->var.yres_virtual < info->var.yres) {  		dev_err(info->device, "virtual vertical size smaller than real\n"); -		goto err_find_mode; -	} - -	/* maximize virtual vertical size for fast scrolling */ -	info->var.yres_virtual = info->fix.smem_len * 8 / -			(info->var.bits_per_pixel * info->var.xres_virtual); -	if (info->var.yres_virtual < info->var.yres) { -		dev_err(info->device, "virtual vertical size smaller than real\n"); +		rc = -EINVAL;  		goto err_find_mode;  	} @@ -1359,13 +1351,16 @@ static int s3_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  		goto err_reg_fb;  	} -	printk(KERN_INFO "fb%d: %s on %s, %d MB RAM, %d MHz MCLK\n", info->node, info->fix.id, -		 pci_name(dev), info->fix.smem_len >> 20, (par->mclk_freq + 500) / 1000); +	fb_info(info, "%s on %s, %d MB RAM, %d MHz MCLK\n", +		info->fix.id, pci_name(dev), +		info->fix.smem_len >> 20, (par->mclk_freq + 500) / 1000);  	if (par->chip == CHIP_UNKNOWN) -		printk(KERN_INFO "fb%d: unknown chip, CR2D=%x, CR2E=%x, CRT2F=%x, CRT30=%x\n", -			info->node, vga_rcrt(par->state.vgabase, 0x2d), vga_rcrt(par->state.vgabase, 0x2e), -			vga_rcrt(par->state.vgabase, 0x2f), vga_rcrt(par->state.vgabase, 0x30)); +		fb_info(info, "unknown chip, CR2D=%x, CR2E=%x, CRT2F=%x, CRT30=%x\n", +			vga_rcrt(par->state.vgabase, 0x2d), +			vga_rcrt(par->state.vgabase, 0x2e), +			vga_rcrt(par->state.vgabase, 0x2f), +			vga_rcrt(par->state.vgabase, 0x30));  	/* Record a reference to the driver data */  	pci_set_drvdata(dev, info); @@ -1406,9 +1401,10 @@ err_enable_device:  static void s3_pci_remove(struct pci_dev *dev)  {  	struct fb_info *info = pci_get_drvdata(dev); -	struct s3fb_info __maybe_unused *par = info->par; +	struct s3fb_info __maybe_unused *par;  	if (info) { +		par = info->par;  #ifdef CONFIG_MTRR  		if (par->mtrr_reg >= 0) { @@ -1431,7 +1427,6 @@ static void s3_pci_remove(struct pci_dev *dev)  		pci_release_regions(dev);  /*		pci_disable_device(dev); */ -		pci_set_drvdata(dev, NULL);  		framebuffer_release(info);  	}  } diff --git a/drivers/video/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c index de76da0c642..580c444ec30 100644 --- a/drivers/video/sa1100fb.c +++ b/drivers/video/fbdev/sa1100fb.c @@ -1116,7 +1116,7 @@ static struct fb_monspecs monspecs = {  static struct sa1100fb_info *sa1100fb_init_fbinfo(struct device *dev)  { -	struct sa1100fb_mach_info *inf = dev->platform_data; +	struct sa1100fb_mach_info *inf = dev_get_platdata(dev);  	struct sa1100fb_info *fbi;  	unsigned i; @@ -1201,7 +1201,7 @@ static int sa1100fb_probe(struct platform_device *pdev)  	struct resource *res;  	int ret, irq; -	if (!pdev->dev.platform_data) { +	if (!dev_get_platdata(&pdev->dev)) {  		dev_err(&pdev->dev, "no platform LCD data\n");  		return -EINVAL;  	} diff --git a/drivers/video/sa1100fb.h b/drivers/video/fbdev/sa1100fb.h index fc5d4292fad..fc5d4292fad 100644 --- a/drivers/video/sa1100fb.h +++ b/drivers/video/fbdev/sa1100fb.h diff --git a/drivers/video/savage/Makefile b/drivers/video/fbdev/savage/Makefile index e09770fff8e..e09770fff8e 100644 --- a/drivers/video/savage/Makefile +++ b/drivers/video/fbdev/savage/Makefile diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/fbdev/savage/savagefb-i2c.c index 80fa87e2ae2..80fa87e2ae2 100644 --- a/drivers/video/savage/savagefb-i2c.c +++ b/drivers/video/fbdev/savage/savagefb-i2c.c diff --git a/drivers/video/savage/savagefb.h b/drivers/video/fbdev/savage/savagefb.h index dcaab9012ca..dcaab9012ca 100644 --- a/drivers/video/savage/savagefb.h +++ b/drivers/video/fbdev/savage/savagefb.h diff --git a/drivers/video/savage/savagefb_accel.c b/drivers/video/fbdev/savage/savagefb_accel.c index bfefa6234cf..bfefa6234cf 100644 --- a/drivers/video/savage/savagefb_accel.c +++ b/drivers/video/fbdev/savage/savagefb_accel.c diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c index 741b2395d01..4dbf45f3b21 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/fbdev/savage/savagefb_driver.c @@ -2362,12 +2362,6 @@ static void savagefb_remove(struct pci_dev *dev)  		kfree(info->pixmap.addr);  		pci_release_regions(dev);  		framebuffer_release(info); - -		/* -		 * Ensure that the driver data is no longer -		 * valid. -		 */ -		pci_set_drvdata(dev, NULL);  	}  } diff --git a/drivers/video/sbuslib.c b/drivers/video/fbdev/sbuslib.c index 296afae442f..a350209ffbd 100644 --- a/drivers/video/sbuslib.c +++ b/drivers/video/fbdev/sbuslib.c @@ -186,7 +186,7 @@ int sbusfb_ioctl_helper(unsigned long cmd, unsigned long arg,  	}  	default:  		return -EINVAL; -	}; +	}  }  EXPORT_SYMBOL(sbusfb_ioctl_helper); diff --git a/drivers/video/sbuslib.h b/drivers/video/fbdev/sbuslib.h index 7ba3250236b..7ba3250236b 100644 --- a/drivers/video/sbuslib.h +++ b/drivers/video/fbdev/sbuslib.h diff --git a/drivers/video/sh7760fb.c b/drivers/video/fbdev/sh7760fb.c index 1265b25f9f9..1265b25f9f9 100644 --- a/drivers/video/sh7760fb.c +++ b/drivers/video/fbdev/sh7760fb.c diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/fbdev/sh_mipi_dsi.c index 8f6e8ff620d..8f6e8ff620d 100644 --- a/drivers/video/sh_mipi_dsi.c +++ b/drivers/video/fbdev/sh_mipi_dsi.c diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/fbdev/sh_mobile_hdmi.c index bfe4728480f..9a33ee0413f 100644 --- a/drivers/video/sh_mobile_hdmi.c +++ b/drivers/video/fbdev/sh_mobile_hdmi.c @@ -498,7 +498,7 @@ static void sh_hdmi_video_config(struct sh_hdmi *hdmi)  static void sh_hdmi_audio_config(struct sh_hdmi *hdmi)  {  	u8 data; -	struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; +	struct sh_mobile_hdmi_info *pdata = dev_get_platdata(hdmi->dev);  	/*  	 * [7:4] L/R data swap control @@ -815,7 +815,7 @@ static unsigned long sh_hdmi_rate_error(struct sh_hdmi *hdmi,  		unsigned long *hdmi_rate, unsigned long *parent_rate)  {  	unsigned long target = PICOS2KHZ(mode->pixclock) * 1000, rate_error; -	struct sh_mobile_hdmi_info *pdata = hdmi->dev->platform_data; +	struct sh_mobile_hdmi_info *pdata = dev_get_platdata(hdmi->dev);  	*hdmi_rate = clk_round_rate(hdmi->hdmi_clk, target);  	if ((long)*hdmi_rate < 0) @@ -1271,7 +1271,7 @@ static void sh_hdmi_htop1_init(struct sh_hdmi *hdmi)  static int __init sh_hdmi_probe(struct platform_device *pdev)  { -	struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data; +	struct sh_mobile_hdmi_info *pdata = dev_get_platdata(&pdev->dev);  	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	struct resource *htop1_res;  	int irq = platform_get_irq(pdev, 0), ret; @@ -1290,7 +1290,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)  		}  	} -	hdmi = kzalloc(sizeof(*hdmi), GFP_KERNEL); +	hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL);  	if (!hdmi) {  		dev_err(&pdev->dev, "Cannot allocate device data\n");  		return -ENOMEM; @@ -1304,7 +1304,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)  	if (IS_ERR(hdmi->hdmi_clk)) {  		ret = PTR_ERR(hdmi->hdmi_clk);  		dev_err(&pdev->dev, "Unable to get clock: %d\n", ret); -		goto egetclk; +		return ret;  	}  	/* select register access functions */ @@ -1326,7 +1326,7 @@ static int __init sh_hdmi_probe(struct platform_device *pdev)  		goto erate;  	} -	ret = clk_enable(hdmi->hdmi_clk); +	ret = clk_prepare_enable(hdmi->hdmi_clk);  	if (ret < 0) {  		dev_err(hdmi->dev, "Cannot enable clock: %d\n", ret);  		goto erate; @@ -1404,11 +1404,9 @@ emap_htop1:  emap:  	release_mem_region(res->start, resource_size(res));  ereqreg: -	clk_disable(hdmi->hdmi_clk); +	clk_disable_unprepare(hdmi->hdmi_clk);  erate:  	clk_put(hdmi->hdmi_clk); -egetclk: -	kfree(hdmi);  	return ret;  } @@ -1427,13 +1425,12 @@ static int __exit sh_hdmi_remove(struct platform_device *pdev)  	cancel_delayed_work_sync(&hdmi->edid_work);  	pm_runtime_put(&pdev->dev);  	pm_runtime_disable(&pdev->dev); -	clk_disable(hdmi->hdmi_clk); +	clk_disable_unprepare(hdmi->hdmi_clk);  	clk_put(hdmi->hdmi_clk);  	if (hdmi->htop1)  		iounmap(hdmi->htop1);  	iounmap(hdmi->base);  	release_mem_region(res->start, resource_size(res)); -	kfree(hdmi);  	return 0;  } diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c index 0264704a52b..2bcc84ac18c 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c @@ -344,7 +344,7 @@ static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)  {  	if (atomic_inc_and_test(&priv->hw_usecnt)) {  		if (priv->dot_clk) -			clk_enable(priv->dot_clk); +			clk_prepare_enable(priv->dot_clk);  		pm_runtime_get_sync(priv->dev);  		if (priv->meram_dev && priv->meram_dev->pdev)  			pm_runtime_get_sync(&priv->meram_dev->pdev->dev); @@ -358,7 +358,7 @@ static void sh_mobile_lcdc_clk_off(struct sh_mobile_lcdc_priv *priv)  			pm_runtime_put_sync(&priv->meram_dev->pdev->dev);  		pm_runtime_put(priv->dev);  		if (priv->dot_clk) -			clk_disable(priv->dot_clk); +			clk_disable_unprepare(priv->dot_clk);  	}  } @@ -574,8 +574,9 @@ static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch,  	switch (event) {  	case SH_MOBILE_LCDC_EVENT_DISPLAY_CONNECT:  		/* HDMI plug in */ +		console_lock();  		if (lock_fb_info(info)) { -			console_lock(); +  			ch->display.width = monspec->max_x * 10;  			ch->display.height = monspec->max_y * 10; @@ -594,19 +595,20 @@ static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch,  				fb_set_suspend(info, 0);  			} -			console_unlock(); +  			unlock_fb_info(info);  		} +		console_unlock();  		break;  	case SH_MOBILE_LCDC_EVENT_DISPLAY_DISCONNECT:  		/* HDMI disconnect */ +		console_lock();  		if (lock_fb_info(info)) { -			console_lock();  			fb_set_suspend(info, 1); -			console_unlock();  			unlock_fb_info(info);  		} +		console_unlock();  		break;  	case SH_MOBILE_LCDC_EVENT_DISPLAY_MODE: @@ -1225,7 +1227,7 @@ static void sh_mobile_lcdc_stop(struct sh_mobile_lcdc_priv *priv)  		/* Free the MERAM cache. */  		if (ch->cache) {  			sh_mobile_meram_cache_free(priv->meram_dev, ch->cache); -			ch->cache = 0; +			ch->cache = NULL;  		}  	} diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/fbdev/sh_mobile_lcdcfb.h index f839adef1d9..f839adef1d9 100644 --- a/drivers/video/sh_mobile_lcdcfb.h +++ b/drivers/video/fbdev/sh_mobile_lcdcfb.h diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/fbdev/sh_mobile_meram.c index e0f098562a7..a297de5cc85 100644 --- a/drivers/video/sh_mobile_meram.c +++ b/drivers/video/fbdev/sh_mobile_meram.c @@ -569,6 +569,7 @@ EXPORT_SYMBOL_GPL(sh_mobile_meram_cache_update);   * Power management   */ +#if defined(CONFIG_PM_SLEEP) || defined(CONFIG_PM_RUNTIME)  static int sh_mobile_meram_suspend(struct device *dev)  {  	struct platform_device *pdev = to_platform_device(dev); @@ -611,6 +612,7 @@ static int sh_mobile_meram_resume(struct device *dev)  		meram_write_reg(priv->base, common_regs[i], priv->regs[i]);  	return 0;  } +#endif /* CONFIG_PM_SLEEP || CONFIG_PM_RUNTIME */  static UNIVERSAL_DEV_PM_OPS(sh_mobile_meram_dev_pm_ops,  			    sh_mobile_meram_suspend, diff --git a/drivers/video/simplefb.c b/drivers/video/fbdev/simplefb.c index 8d781061305..210f3a02121 100644 --- a/drivers/video/simplefb.c +++ b/drivers/video/fbdev/simplefb.c @@ -66,8 +66,15 @@ static int simplefb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,  	return 0;  } +static void simplefb_destroy(struct fb_info *info) +{ +	if (info->screen_base) +		iounmap(info->screen_base); +} +  static struct fb_ops simplefb_ops = {  	.owner		= THIS_MODULE, +	.fb_destroy	= simplefb_destroy,  	.fb_setcolreg	= simplefb_setcolreg,  	.fb_fillrect	= cfb_fillrect,  	.fb_copyarea	= cfb_copyarea, @@ -132,7 +139,7 @@ static int simplefb_parse_dt(struct platform_device *pdev,  static int simplefb_parse_pd(struct platform_device *pdev,  			     struct simplefb_params *params)  { -	struct simplefb_platform_data *pd = pdev->dev.platform_data; +	struct simplefb_platform_data *pd = dev_get_platdata(&pdev->dev);  	int i;  	params->width = pd->width; @@ -167,7 +174,7 @@ static int simplefb_probe(struct platform_device *pdev)  		return -ENODEV;  	ret = -ENODEV; -	if (pdev->dev.platform_data) +	if (dev_get_platdata(&pdev->dev))  		ret = simplefb_parse_pd(pdev, ¶ms);  	else if (pdev->dev.of_node)  		ret = simplefb_parse_dt(pdev, ¶ms); @@ -212,17 +219,26 @@ static int simplefb_probe(struct platform_device *pdev)  	info->fbops = &simplefb_ops;  	info->flags = FBINFO_DEFAULT | FBINFO_MISC_FIRMWARE; -	info->screen_base = devm_ioremap(&pdev->dev, info->fix.smem_start, -					 info->fix.smem_len); +	info->screen_base = ioremap_wc(info->fix.smem_start, +				       info->fix.smem_len);  	if (!info->screen_base) {  		framebuffer_release(info);  		return -ENODEV;  	}  	info->pseudo_palette = (void *)(info + 1); +	dev_info(&pdev->dev, "framebuffer at 0x%lx, 0x%x bytes, mapped to 0x%p\n", +			     info->fix.smem_start, info->fix.smem_len, +			     info->screen_base); +	dev_info(&pdev->dev, "format=%s, mode=%dx%dx%d, linelength=%d\n", +			     params.format->name, +			     info->var.xres, info->var.yres, +			     info->var.bits_per_pixel, info->fix.line_length); +  	ret = register_framebuffer(info);  	if (ret < 0) {  		dev_err(&pdev->dev, "Unable to register simplefb: %d\n", ret); +		iounmap(info->screen_base);  		framebuffer_release(info);  		return ret;  	} diff --git a/drivers/video/sis/300vtbl.h b/drivers/video/fbdev/sis/300vtbl.h index e4b4a2626da..e4b4a2626da 100644 --- a/drivers/video/sis/300vtbl.h +++ b/drivers/video/fbdev/sis/300vtbl.h diff --git a/drivers/video/sis/310vtbl.h b/drivers/video/fbdev/sis/310vtbl.h index 54fcbbf4ef6..54fcbbf4ef6 100644 --- a/drivers/video/sis/310vtbl.h +++ b/drivers/video/fbdev/sis/310vtbl.h diff --git a/drivers/video/sis/Makefile b/drivers/video/fbdev/sis/Makefile index f7c0046e5b1..f7c0046e5b1 100644 --- a/drivers/video/sis/Makefile +++ b/drivers/video/fbdev/sis/Makefile diff --git a/drivers/video/sis/init.c b/drivers/video/fbdev/sis/init.c index f082ae55c0c..bd40f5ecd90 100644 --- a/drivers/video/sis/init.c +++ b/drivers/video/fbdev/sis/init.c @@ -651,6 +651,7 @@ SiS_GetModeID_LCD(int VGAEngine, unsigned int VBFlags, int HDisplay, int VDispla  	     switch(VDisplay) {  	     case 720:  		ModeIndex = ModeIndex_1280x720[Depth]; +		break;  	     case 768:  		if(VGAEngine == SIS_300_VGA) {  		   ModeIndex = ModeIndex_300_1280x768[Depth]; @@ -3320,9 +3321,8 @@ SiSSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo)  }  #ifndef GETBITSTR -#define BITMASK(h,l)    	(((unsigned)(1U << ((h)-(l)+1))-1)<<(l)) -#define GENMASK(mask)   	BITMASK(1?mask,0?mask) -#define GETBITS(var,mask)   	(((var) & GENMASK(mask)) >> (0?mask)) +#define GENBITSMASK(mask)   	GENMASK(1?mask,0?mask) +#define GETBITS(var,mask)   	(((var) & GENBITSMASK(mask)) >> (0?mask))  #define GETBITSTR(val,from,to)  ((GETBITS(val,from)) << (0?to))  #endif diff --git a/drivers/video/sis/init.h b/drivers/video/fbdev/sis/init.h index 85d6738b6c6..85d6738b6c6 100644 --- a/drivers/video/sis/init.h +++ b/drivers/video/fbdev/sis/init.h diff --git a/drivers/video/sis/init301.c b/drivers/video/fbdev/sis/init301.c index a89e3cafd5a..a89e3cafd5a 100644 --- a/drivers/video/sis/init301.c +++ b/drivers/video/fbdev/sis/init301.c diff --git a/drivers/video/sis/init301.h b/drivers/video/fbdev/sis/init301.h index 2112d6d7fed..2112d6d7fed 100644 --- a/drivers/video/sis/init301.h +++ b/drivers/video/fbdev/sis/init301.h diff --git a/drivers/video/sis/initdef.h b/drivers/video/fbdev/sis/initdef.h index 264b55a5947..264b55a5947 100644 --- a/drivers/video/sis/initdef.h +++ b/drivers/video/fbdev/sis/initdef.h diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/fbdev/sis/initextlfb.c index 3ab18f5a375..3ab18f5a375 100644 --- a/drivers/video/sis/initextlfb.c +++ b/drivers/video/fbdev/sis/initextlfb.c diff --git a/drivers/video/sis/oem300.h b/drivers/video/fbdev/sis/oem300.h index b73f2684014..b73f2684014 100644 --- a/drivers/video/sis/oem300.h +++ b/drivers/video/fbdev/sis/oem300.h diff --git a/drivers/video/sis/oem310.h b/drivers/video/fbdev/sis/oem310.h index 8fce56e4482..8fce56e4482 100644 --- a/drivers/video/sis/oem310.h +++ b/drivers/video/fbdev/sis/oem310.h diff --git a/drivers/video/sis/sis.h b/drivers/video/fbdev/sis/sis.h index 1987f1b7212..1987f1b7212 100644 --- a/drivers/video/sis/sis.h +++ b/drivers/video/fbdev/sis/sis.h diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/fbdev/sis/sis_accel.c index ceb434c95c0..ceb434c95c0 100644 --- a/drivers/video/sis/sis_accel.c +++ b/drivers/video/fbdev/sis/sis_accel.c diff --git a/drivers/video/sis/sis_accel.h b/drivers/video/fbdev/sis/sis_accel.h index 30e03cdf6b8..30e03cdf6b8 100644 --- a/drivers/video/sis/sis_accel.h +++ b/drivers/video/fbdev/sis/sis_accel.h diff --git a/drivers/video/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c index 977e27927a2..22ad028bf12 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/fbdev/sis/sis_main.c @@ -5994,7 +5994,6 @@ static int sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)  	if(!ivideo->sisvga_enabled) {  		if(pci_enable_device(pdev)) {  			if(ivideo->nbridge) pci_dev_put(ivideo->nbridge); -			pci_set_drvdata(pdev, NULL);  			framebuffer_release(sis_fb_info);  			return -EIO;  		} @@ -6211,7 +6210,6 @@ error_3:	vfree(ivideo->bios_abase);  			pci_dev_put(ivideo->lpcdev);  		if(ivideo->nbridge)  			pci_dev_put(ivideo->nbridge); -		pci_set_drvdata(pdev, NULL);  		if(!ivideo->sisvga_enabled)  			pci_disable_device(pdev);  		framebuffer_release(sis_fb_info); @@ -6480,8 +6478,8 @@ error_3:	vfree(ivideo->bios_abase);  									"disabled"); -		printk(KERN_INFO "fb%d: %s frame buffer device version %d.%d.%d\n", -			sis_fb_info->node, ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL); +		fb_info(sis_fb_info, "%s frame buffer device version %d.%d.%d\n", +			ivideo->myid, VER_MAJOR, VER_MINOR, VER_LEVEL);  		printk(KERN_INFO "sisfb: Copyright (C) 2001-2005 Thomas Winischhofer\n"); @@ -6523,8 +6521,6 @@ static void sisfb_remove(struct pci_dev *pdev)  		mtrr_del(ivideo->mtrr, ivideo->video_base, ivideo->video_size);  #endif -	pci_set_drvdata(pdev, NULL); -  	/* If device was disabled when starting, disable  	 * it when quitting.  	 */ diff --git a/drivers/video/sis/sis_main.h b/drivers/video/fbdev/sis/sis_main.h index 32e23c20943..32e23c20943 100644 --- a/drivers/video/sis/sis_main.h +++ b/drivers/video/fbdev/sis/sis_main.h diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/fbdev/sis/vgatypes.h index e3f9976cfef..e3f9976cfef 100644 --- a/drivers/video/sis/vgatypes.h +++ b/drivers/video/fbdev/sis/vgatypes.h diff --git a/drivers/video/sis/vstruct.h b/drivers/video/fbdev/sis/vstruct.h index ea94d214dcf..ea94d214dcf 100644 --- a/drivers/video/sis/vstruct.h +++ b/drivers/video/fbdev/sis/vstruct.h diff --git a/drivers/video/skeletonfb.c b/drivers/video/fbdev/skeletonfb.c index 2d4694c6b9e..fefde7c6add 100644 --- a/drivers/video/skeletonfb.c +++ b/drivers/video/fbdev/skeletonfb.c @@ -824,8 +824,7 @@ static int xxxfb_probe(struct pci_dev *dev, const struct pci_device_id *ent)  	fb_dealloc_cmap(&info->cmap);  	return -EINVAL;      } -    printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, -	   info->fix.id); +    fb_info(info, "%s frame buffer device\n", info->fix.id);      pci_set_drvdata(dev, info); /* or platform_set_drvdata(pdev, info) */      return 0;  } diff --git a/drivers/video/sm501fb.c b/drivers/video/fbdev/sm501fb.c index 1501979099d..c2c8eb66878 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/fbdev/sm501fb.c @@ -1215,7 +1215,7 @@ static ssize_t sm501fb_crtsrc_store(struct device *dev,  }  /* Prepare the device_attr for registration with sysfs later */ -static DEVICE_ATTR(crt_src, 0666, sm501fb_crtsrc_show, sm501fb_crtsrc_store); +static DEVICE_ATTR(crt_src, 0664, sm501fb_crtsrc_show, sm501fb_crtsrc_store);  /* sm501fb_show_regs   * diff --git a/drivers/video/smscufx.c b/drivers/video/fbdev/smscufx.c index e188ada2ffd..d513ed6a49f 100644 --- a/drivers/video/smscufx.c +++ b/drivers/video/fbdev/smscufx.c @@ -1147,7 +1147,7 @@ static void ufx_free_framebuffer_work(struct work_struct *work)  	fb_destroy_modelist(&info->modelist); -	dev->info = 0; +	dev->info = NULL;  	/* Assume info structure is freed after this point */  	framebuffer_release(info); diff --git a/drivers/video/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c index 44967c8fef2..f4daa59f0a8 100644 --- a/drivers/video/ssd1307fb.c +++ b/drivers/video/fbdev/ssd1307fb.c @@ -569,7 +569,7 @@ static struct i2c_driver ssd1307fb_driver = {  	.id_table = ssd1307fb_i2c_id,  	.driver = {  		.name = "ssd1307fb", -		.of_match_table = of_match_ptr(ssd1307fb_of_match), +		.of_match_table = ssd1307fb_of_match,  		.owner = THIS_MODULE,  	},  }; diff --git a/drivers/video/sstfb.c b/drivers/video/fbdev/sstfb.c index 9c00026e3ae..f0cb279ef33 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/fbdev/sstfb.c @@ -706,10 +706,10 @@ static void sstfb_setvgapass( struct fb_info *info, int enable )  	fbiinit0 = sst_read (FBIINIT0);  	if (par->vgapass) {  		sst_write(FBIINIT0, fbiinit0 & ~DIS_VGA_PASSTHROUGH); -		printk(KERN_INFO "fb%d: Enabling VGA pass-through\n", info->node ); +		fb_info(info, "Enabling VGA pass-through\n");  	} else {  		sst_write(FBIINIT0, fbiinit0 | DIS_VGA_PASSTHROUGH); -		printk(KERN_INFO "fb%d: Disabling VGA pass-through\n", info->node ); +		fb_info(info, "Disabling VGA pass-through\n");  	}  	pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, tmp);  } @@ -1437,8 +1437,8 @@ static int sstfb_probe(struct pci_dev *pdev, const struct pci_device_id *id)  		printk(KERN_WARNING "sstfb: can't create sysfs entry.\n"); -	printk(KERN_INFO "fb%d: %s frame buffer device at 0x%p\n", -	       info->node, fix->id, info->screen_base); +	fb_info(info, "%s frame buffer device at 0x%p\n", +		fix->id, info->screen_base);  	return 0; diff --git a/drivers/video/sticore.h b/drivers/video/fbdev/sticore.h index addf7b615ef..af1619536ac 100644 --- a/drivers/video/sticore.h +++ b/drivers/video/fbdev/sticore.h @@ -18,6 +18,9 @@  #define STI_FONT_HPROMAN8 1  #define STI_FONT_KANA8 2 +#define ALT_CODE_TYPE_UNKNOWN 0x00	/* alt code type values */ +#define ALT_CODE_TYPE_PA_RISC_64 0x01 +  /* The latency of the STI functions cannot really be reduced by setting   * this to 0;  STI doesn't seem to be designed to allow calling a different   * function (or the same function with different arguments) after a @@ -40,14 +43,6 @@  #define STI_PTR(p)	( virt_to_phys(p) )  #define PTR_STI(p)	( phys_to_virt((unsigned long)p) ) -#define STI_CALL(func, flags, inptr, outptr, glob_cfg)	\ -       ({						\ -               pdc_sti_call( func, STI_PTR(flags),	\ -				   STI_PTR(inptr),	\ -				   STI_PTR(outptr),	\ -				   STI_PTR(glob_cfg));	\ -       }) -  #define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x)  #define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y) @@ -56,6 +51,12 @@  #define sti_font_x(sti) (PTR_STI(sti->font)->width)  #define sti_font_y(sti) (PTR_STI(sti->font)->height) +#ifdef CONFIG_64BIT +#define STI_LOWMEM	(GFP_KERNEL | GFP_DMA) +#else +#define STI_LOWMEM	(GFP_KERNEL) +#endif +  /* STI function configuration structs */ @@ -306,6 +307,34 @@ struct sti_blkmv_outptr {  }; +/* sti_all_data is an internal struct which needs to be allocated in + * low memory (< 4GB) if STI is used with 32bit STI on a 64bit kernel */ + +struct sti_all_data { +	struct sti_glob_cfg glob_cfg; +	struct sti_glob_cfg_ext glob_cfg_ext; + +	struct sti_conf_inptr		inq_inptr; +	struct sti_conf_outptr		inq_outptr; /* configuration */ +	struct sti_conf_outptr_ext	inq_outptr_ext; + +	struct sti_init_inptr_ext	init_inptr_ext; +	struct sti_init_inptr		init_inptr; +	struct sti_init_outptr		init_outptr; + +	struct sti_blkmv_inptr		blkmv_inptr; +	struct sti_blkmv_outptr		blkmv_outptr; + +	struct sti_font_inptr		font_inptr; +	struct sti_font_outptr		font_outptr; + +	/* leave as last entries */ +	unsigned long save_addr[1024 / sizeof(unsigned long)]; +	   /* min 256 bytes which is STI default, max sti->sti_mem_request */ +	unsigned long sti_mem_addr[256 / sizeof(unsigned long)]; +	/* do not add something below here ! */ +}; +  /* internal generic STI struct */  struct sti_struct { @@ -330,11 +359,9 @@ struct sti_struct {  	region_t regions[STI_REGION_MAX];  	unsigned long regions_phys[STI_REGION_MAX]; -	struct sti_glob_cfg *glob_cfg; -	struct sti_cooked_font *font;	/* ptr to selected font (cooked) */ +	struct sti_glob_cfg *glob_cfg;	/* points into sti_all_data */ -	struct sti_conf_outptr outptr; /* configuration */ -	struct sti_conf_outptr_ext outptr_ext; +	struct sti_cooked_font *font;	/* ptr to selected font (cooked) */  	struct pci_dev *pd; @@ -343,6 +370,9 @@ struct sti_struct {  	/* pointer to the fb_info where this STI device is used */  	struct fb_info *info; + +	/* pointer to all internal data */ +	struct sti_all_data *sti_data;  }; @@ -350,6 +380,14 @@ struct sti_struct {  struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */ + +/* sticore main function to call STI firmware */ + +int sti_call(const struct sti_struct *sti, unsigned long func, +		const void *flags, void *inptr, void *outptr, +		struct sti_glob_cfg *glob_cfg); + +  /* functions to call the STI ROM directly */  void sti_putc(struct sti_struct *sti, int c, int y, int x); diff --git a/drivers/video/stifb.c b/drivers/video/fbdev/stifb.c index 876648e15e9..cfe8a2f905c 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/fbdev/stifb.c @@ -1101,6 +1101,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)  	var = &info->var;  	fb->sti = sti; +	dev_name = sti->sti_data->inq_outptr.dev_name;  	/* store upper 32bits of the graphics id */  	fb->id = fb->sti->graphics_id[0]; @@ -1114,11 +1115,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)  		  Since this driver only supports standard mode, we check  		  if the device name contains the string "DX" and tell the  		  user how to reconfigure the card. */ -		if (strstr(sti->outptr.dev_name, "DX")) { +		if (strstr(dev_name, "DX")) {  		   printk(KERN_WARNING  "WARNING: stifb framebuffer driver does not support '%s' in double-buffer mode.\n"  "WARNING: Please disable the double-buffer mode in IPL menu (the PARISC-BIOS).\n", -			sti->outptr.dev_name); +			dev_name);  		   goto out_err0;  		}  		/* fall though */ @@ -1130,7 +1131,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)  		break;  	default:  		printk(KERN_WARNING "stifb: '%s' (id: 0x%08x) not supported.\n", -			sti->outptr.dev_name, fb->id); +			dev_name, fb->id);  		goto out_err0;  	} @@ -1154,7 +1155,6 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)  		fb->id = S9000_ID_A1659A;  		break;  	case S9000_ID_TIMBER:	/* HP9000/710 Any (may be a grayscale device) */ -		dev_name = fb->sti->outptr.dev_name;  		if (strstr(dev_name, "GRAYSCALE") ||   		    strstr(dev_name, "Grayscale") ||  		    strstr(dev_name, "grayscale")) @@ -1283,14 +1283,12 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)  	sti->info = info; /* save for unregister_framebuffer() */ -	printk(KERN_INFO  -	    "fb%d: %s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n", -		fb->info.node,  +	fb_info(&fb->info, "%s %dx%d-%d frame buffer device, %s, id: %04x, mmio: 0x%04lx\n",  		fix->id,  		var->xres,   		var->yres,  		var->bits_per_pixel, -		sti->outptr.dev_name, +		dev_name,  		fb->id,   		fix->mmio_start); diff --git a/drivers/video/sunxvr1000.c b/drivers/video/fbdev/sunxvr1000.c index cc6f48bba36..58241b47a96 100644 --- a/drivers/video/sunxvr1000.c +++ b/drivers/video/fbdev/sunxvr1000.c @@ -186,8 +186,6 @@ static int gfb_remove(struct platform_device *op)          framebuffer_release(info); -	dev_set_drvdata(&op->dev, NULL); -  	return 0;  } diff --git a/drivers/video/sunxvr2500.c b/drivers/video/fbdev/sunxvr2500.c index 843b6bab048..843b6bab048 100644 --- a/drivers/video/sunxvr2500.c +++ b/drivers/video/fbdev/sunxvr2500.c diff --git a/drivers/video/sunxvr500.c b/drivers/video/fbdev/sunxvr500.c index 387350d004d..387350d004d 100644 --- a/drivers/video/sunxvr500.c +++ b/drivers/video/fbdev/sunxvr500.c diff --git a/drivers/video/tcx.c b/drivers/video/fbdev/tcx.c index c000852500a..7fb2d696fac 100644 --- a/drivers/video/tcx.c +++ b/drivers/video/fbdev/tcx.c @@ -232,7 +232,7 @@ tcx_blank(int blank, struct fb_info *info)  	case FB_BLANK_POWERDOWN: /* Poweroff */  		break; -	}; +	}  	sbus_writel(val, &thc->thc_misc); @@ -434,7 +434,7 @@ static int tcx_probe(struct platform_device *op)  		default:  			j = i;  			break; -		}; +		}  		par->mmap_map[i].poff = op->resource[j].start;  	} @@ -498,8 +498,6 @@ static int tcx_remove(struct platform_device *op)  	framebuffer_release(info); -	dev_set_drvdata(&op->dev, NULL); -  	return 0;  } diff --git a/drivers/video/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c index 64bc28ba403..f761fe375f5 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/fbdev/tdfxfb.c @@ -1646,7 +1646,6 @@ static void tdfxfb_remove(struct pci_dev *pdev)  			   pci_resource_len(pdev, 1));  	release_mem_region(pci_resource_start(pdev, 0),  			   pci_resource_len(pdev, 0)); -	pci_set_drvdata(pdev, NULL);  	fb_dealloc_cmap(&info->cmap);  	framebuffer_release(info);  } diff --git a/drivers/video/tgafb.c b/drivers/video/fbdev/tgafb.c index c9c8e5a1fde..65ba9921506 100644 --- a/drivers/video/tgafb.c +++ b/drivers/video/fbdev/tgafb.c @@ -32,12 +32,6 @@  #include <video/tgafb.h> -#ifdef CONFIG_PCI -#define TGA_BUS_PCI(dev) (dev->bus == &pci_bus_type) -#else -#define TGA_BUS_PCI(dev) 0 -#endif -  #ifdef CONFIG_TC  #define TGA_BUS_TC(dev) (dev->bus == &tc_bus_type)  #else @@ -188,6 +182,8 @@ tgafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)  	if (var->xres_virtual != var->xres || var->yres_virtual != var->yres)  		return -EINVAL; +	if (var->xres * var->yres * (var->bits_per_pixel >> 3) > info->fix.smem_len) +		return -EINVAL;  	if (var->nonstd)  		return -EINVAL;  	if (1000000000 / var->pixclock > TGA_PLL_MAX_FREQ) @@ -196,8 +192,8 @@ tgafb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)  		return -EINVAL;  	/* Some of the acceleration routines assume the line width is -	   a multiple of 64 bytes.  */ -	if (var->xres * (par->tga_type == TGA_TYPE_8PLANE ? 1 : 4) % 64) +	   a multiple of 8 bytes.  */ +	if (var->xres * (par->tga_type == TGA_TYPE_8PLANE ? 1 : 4) % 8)  		return -EINVAL;  	return 0; @@ -236,7 +232,7 @@ tgafb_set_par(struct fb_info *info)  	};  	struct tga_par *par = (struct tga_par *) info->par; -	int tga_bus_pci = TGA_BUS_PCI(par->dev); +	int tga_bus_pci = dev_is_pci(par->dev);  	int tga_bus_tc = TGA_BUS_TC(par->dev);  	u32 htimings, vtimings, pll_freq;  	u8 tga_type; @@ -268,6 +264,7 @@ tgafb_set_par(struct fb_info *info)  	par->yres = info->var.yres;  	par->pll_freq = pll_freq = 1000000000 / info->var.pixclock;  	par->bits_per_pixel = info->var.bits_per_pixel; +	info->fix.line_length = par->xres * (par->bits_per_pixel >> 3);  	tga_type = par->tga_type; @@ -519,7 +516,7 @@ tgafb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue,  		unsigned transp, struct fb_info *info)  {  	struct tga_par *par = (struct tga_par *) info->par; -	int tga_bus_pci = TGA_BUS_PCI(par->dev); +	int tga_bus_pci = dev_is_pci(par->dev);  	int tga_bus_tc = TGA_BUS_TC(par->dev);  	if (regno > 255) @@ -1142,222 +1139,57 @@ copyarea_line_32bpp(struct fb_info *info, u32 dy, u32 sy,  	__raw_writel(TGA_MODE_SBM_24BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG);  } -/* The general case of forward copy in 8bpp mode.  */ +/* The (almost) general case of backward copy in 8bpp mode.  */  static inline void -copyarea_foreward_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy, -		       u32 height, u32 width, u32 line_length) +copyarea_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy, +	      u32 height, u32 width, u32 line_length, +	      const struct fb_copyarea *area)  {  	struct tga_par *par = (struct tga_par *) info->par; -	unsigned long i, copied, left; -	unsigned long dpos, spos, dalign, salign, yincr; -	u32 smask_first, dmask_first, dmask_last; -	int pixel_shift, need_prime, need_second; -	unsigned long n64, n32, xincr_first; +	unsigned i, yincr; +	int depos, sepos, backward, last_step, step; +	u32 mask_last; +	unsigned n32;  	void __iomem *tga_regs;  	void __iomem *tga_fb; -	yincr = line_length; -	if (dy > sy) { -		dy += height - 1; -		sy += height - 1; -		yincr = -yincr; -	} - -	/* Compute the offsets and alignments in the frame buffer. -	   More than anything else, these control how we do copies.  */ -	dpos = dy * line_length + dx; -	spos = sy * line_length + sx; -	dalign = dpos & 7; -	salign = spos & 7; -	dpos &= -8; -	spos &= -8; - -	/* Compute the value for the PIXELSHIFT register.  This controls -	   both non-co-aligned source and destination and copy direction.  */ -	if (dalign >= salign) -		pixel_shift = dalign - salign; -	else -		pixel_shift = 8 - (salign - dalign); - -	/* Figure out if we need an additional priming step for the -	   residue register.  */ -	need_prime = (salign > dalign); -	if (need_prime) -		dpos -= 8; - -	/* Begin by copying the leading unaligned destination.  Copy enough -	   to make the next destination address 32-byte aligned.  */ -	copied = 32 - (dalign + (dpos & 31)); -	if (copied == 32) -		copied = 0; -	xincr_first = (copied + 7) & -8; -	smask_first = dmask_first = (1ul << copied) - 1; -	smask_first <<= salign; -	dmask_first <<= dalign + need_prime*8; -	if (need_prime && copied > 24) -		copied -= 8; -	left = width - copied; - -	/* Care for small copies.  */ -	if (copied > width) { -		u32 t; -		t = (1ul << width) - 1; -		t <<= dalign + need_prime*8; -		dmask_first &= t; -		left = 0; -	} - -	/* Attempt to use 64-byte copies.  This is only possible if the -	   source and destination are co-aligned at 64 bytes.  */ -	n64 = need_second = 0; -	if ((dpos & 63) == (spos & 63) -	    && (height == 1 || line_length % 64 == 0)) { -		/* We may need a 32-byte copy to ensure 64 byte alignment.  */ -		need_second = (dpos + xincr_first) & 63; -		if ((need_second & 32) != need_second) -			printk(KERN_ERR "tgafb: need_second wrong\n"); -		if (left >= need_second + 64) { -			left -= need_second; -			n64 = left / 64; -			left %= 64; -		} else -			need_second = 0; -	} - -	/* Copy trailing full 32-byte sections.  This will be the main -	   loop if the 64 byte loop can't be used.  */ -	n32 = left / 32; -	left %= 32; - -	/* Copy the trailing unaligned destination.  */ -	dmask_last = (1ul << left) - 1; - -	tga_regs = par->tga_regs_base; -	tga_fb = par->tga_fb_base; - -	/* Set up the MODE and PIXELSHIFT registers.  */ -	__raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_COPY, tga_regs+TGA_MODE_REG); -	__raw_writel(pixel_shift, tga_regs+TGA_PIXELSHIFT_REG); -	wmb(); - -	for (i = 0; i < height; ++i) { -		unsigned long j; -		void __iomem *sfb; -		void __iomem *dfb; - -		sfb = tga_fb + spos; -		dfb = tga_fb + dpos; -		if (dmask_first) { -			__raw_writel(smask_first, sfb); -			wmb(); -			__raw_writel(dmask_first, dfb); -			wmb(); -			sfb += xincr_first; -			dfb += xincr_first; -		} - -		if (need_second) { -			__raw_writel(0xffffffff, sfb); -			wmb(); -			__raw_writel(0xffffffff, dfb); -			wmb(); -			sfb += 32; -			dfb += 32; -		} - -		if (n64 && (((unsigned long)sfb | (unsigned long)dfb) & 63)) -			printk(KERN_ERR -			       "tgafb: misaligned copy64 (s:%p, d:%p)\n", -			       sfb, dfb); - -		for (j = 0; j < n64; ++j) { -			__raw_writel(sfb - tga_fb, tga_regs+TGA_COPY64_SRC); -			wmb(); -			__raw_writel(dfb - tga_fb, tga_regs+TGA_COPY64_DST); -			wmb(); -			sfb += 64; -			dfb += 64; -		} - -		for (j = 0; j < n32; ++j) { -			__raw_writel(0xffffffff, sfb); -			wmb(); -			__raw_writel(0xffffffff, dfb); -			wmb(); -			sfb += 32; -			dfb += 32; -		} - -		if (dmask_last) { -			__raw_writel(0xffffffff, sfb); -			wmb(); -			__raw_writel(dmask_last, dfb); -			wmb(); -		} - -		spos += yincr; -		dpos += yincr; +	/* Do acceleration only if we are aligned on 8 pixels */ +	if ((dx | sx | width) & 7) { +		cfb_copyarea(info, area); +		return;  	} -	/* Reset the MODE register to normal.  */ -	__raw_writel(TGA_MODE_SBM_8BPP|TGA_MODE_SIMPLE, tga_regs+TGA_MODE_REG); -} - -/* The (almost) general case of backward copy in 8bpp mode.  */ -static inline void -copyarea_backward_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy, -		       u32 height, u32 width, u32 line_length, -		       const struct fb_copyarea *area) -{ -	struct tga_par *par = (struct tga_par *) info->par; -	unsigned long i, left, yincr; -	unsigned long depos, sepos, dealign, sealign; -	u32 mask_first, mask_last; -	unsigned long n32; -	void __iomem *tga_regs; -	void __iomem *tga_fb; -  	yincr = line_length;  	if (dy > sy) {  		dy += height - 1;  		sy += height - 1;  		yincr = -yincr;  	} +	backward = dy == sy && dx > sx && dx < sx + width;  	/* Compute the offsets and alignments in the frame buffer.  	   More than anything else, these control how we do copies.  */ -	depos = dy * line_length + dx + width; -	sepos = sy * line_length + sx + width; -	dealign = depos & 7; -	sealign = sepos & 7; - -	/* ??? The documentation appears to be incorrect (or very -	   misleading) wrt how pixel shifting works in backward copy -	   mode, i.e. when PIXELSHIFT is negative.  I give up for now. -	   Do handle the common case of co-aligned backward copies, -	   but frob everything else back on generic code.  */ -	if (dealign != sealign) { -		cfb_copyarea(info, area); -		return; -	} - -	/* We begin the copy with the trailing pixels of the -	   unaligned destination.  */ -	mask_first = (1ul << dealign) - 1; -	left = width - dealign; - -	/* Care for small copies.  */ -	if (dealign > width) { -		mask_first ^= (1ul << (dealign - width)) - 1; -		left = 0; -	} +	depos = dy * line_length + dx; +	sepos = sy * line_length + sx; +	if (backward) +		depos += width, sepos += width;  	/* Next copy full words at a time.  */ -	n32 = left / 32; -	left %= 32; +	n32 = width / 32; +	last_step = width % 32;  	/* Finally copy the unaligned head of the span.  */ -	mask_last = -1 << (32 - left); +	mask_last = (1ul << last_step) - 1; + +	if (!backward) { +		step = 32; +		last_step = 32; +	} else { +		step = -32; +		last_step = -last_step; +		sepos -= 32; +		depos -= 32; +	}  	tga_regs = par->tga_regs_base;  	tga_fb = par->tga_fb_base; @@ -1374,25 +1206,33 @@ copyarea_backward_8bpp(struct fb_info *info, u32 dx, u32 dy, u32 sx, u32 sy,  		sfb = tga_fb + sepos;  		dfb = tga_fb + depos; -		if (mask_first) { -			__raw_writel(mask_first, sfb); -			wmb(); -			__raw_writel(mask_first, dfb); -			wmb(); -		} -		for (j = 0; j < n32; ++j) { -			sfb -= 32; -			dfb -= 32; +		for (j = 0; j < n32; j++) { +			if (j < 2 && j + 1 < n32 && !backward && +			    !(((unsigned long)sfb | (unsigned long)dfb) & 63)) { +				do { +					__raw_writel(sfb - tga_fb, tga_regs+TGA_COPY64_SRC); +					wmb(); +					__raw_writel(dfb - tga_fb, tga_regs+TGA_COPY64_DST); +					wmb(); +					sfb += 64; +					dfb += 64; +					j += 2; +				} while (j + 1 < n32); +				j--; +				continue; +			}  			__raw_writel(0xffffffff, sfb);  			wmb();  			__raw_writel(0xffffffff, dfb);  			wmb(); +			sfb += step; +			dfb += step;  		}  		if (mask_last) { -			sfb -= 32; -			dfb -= 32; +			sfb += last_step - step; +			dfb += last_step - step;  			__raw_writel(mask_last, sfb);  			wmb();  			__raw_writel(mask_last, dfb); @@ -1440,7 +1280,7 @@ tgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)  	bpp = info->var.bits_per_pixel;  	/* Detect copies of the entire line.  */ -	if (width * (bpp >> 3) == line_length) { +	if (!(line_length & 63) && width * (bpp >> 3) == line_length) {  		if (bpp == 8)  			copyarea_line_8bpp(info, dy, sy, height, width);  		else @@ -1453,14 +1293,9 @@ tgafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)  	else if (bpp == 32)  		cfb_copyarea(info, area); -	/* Detect overlapping source and destination that requires -	   a backward copy.  */ -	else if (dy == sy && dx > sx && dx < sx + width) -		copyarea_backward_8bpp(info, dx, dy, sx, sy, height, -				       width, line_length, area);  	else -		copyarea_foreward_8bpp(info, dx, dy, sx, sy, height, -				       width, line_length); +		copyarea_8bpp(info, dx, dy, sx, sy, height, +			      width, line_length, area);  } @@ -1472,10 +1307,11 @@ static void  tgafb_init_fix(struct fb_info *info)  {  	struct tga_par *par = (struct tga_par *)info->par; -	int tga_bus_pci = TGA_BUS_PCI(par->dev); +	int tga_bus_pci = dev_is_pci(par->dev);  	int tga_bus_tc = TGA_BUS_TC(par->dev);  	u8 tga_type = par->tga_type;  	const char *tga_type_name = NULL; +	unsigned memory_size;  	switch (tga_type) {  	case TGA_TYPE_8PLANE: @@ -1483,22 +1319,26 @@ tgafb_init_fix(struct fb_info *info)  			tga_type_name = "Digital ZLXp-E1";  		if (tga_bus_tc)  			tga_type_name = "Digital ZLX-E1"; +		memory_size = 2097152;  		break;  	case TGA_TYPE_24PLANE:  		if (tga_bus_pci)  			tga_type_name = "Digital ZLXp-E2";  		if (tga_bus_tc)  			tga_type_name = "Digital ZLX-E2"; +		memory_size = 8388608;  		break;  	case TGA_TYPE_24PLUSZ:  		if (tga_bus_pci)  			tga_type_name = "Digital ZLXp-E3";  		if (tga_bus_tc)  			tga_type_name = "Digital ZLX-E3"; +		memory_size = 16777216;  		break; -	default: +	} +	if (!tga_type_name) {  		tga_type_name = "Unknown"; -		break; +		memory_size = 16777216;  	}  	strlcpy(info->fix.id, tga_type_name, sizeof(info->fix.id)); @@ -1509,9 +1349,8 @@ tgafb_init_fix(struct fb_info *info)  			    ? FB_VISUAL_PSEUDOCOLOR  			    : FB_VISUAL_DIRECTCOLOR); -	info->fix.line_length = par->xres * (par->bits_per_pixel >> 3);  	info->fix.smem_start = (size_t) par->tga_fb_base; -	info->fix.smem_len = info->fix.line_length * par->yres; +	info->fix.smem_len = memory_size;  	info->fix.mmio_start = (size_t) par->tga_regs_base;  	info->fix.mmio_len = 512; @@ -1560,7 +1399,7 @@ static int tgafb_register(struct device *dev)  	const struct fb_videomode *modedb_tga = NULL;  	resource_size_t bar0_start = 0, bar0_len = 0;  	const char *mode_option_tga = NULL; -	int tga_bus_pci = TGA_BUS_PCI(dev); +	int tga_bus_pci = dev_is_pci(dev);  	int tga_bus_tc = TGA_BUS_TC(dev);  	unsigned int modedbsize_tga = 0;  	void __iomem *mem_base; @@ -1635,6 +1474,9 @@ static int tgafb_register(struct device *dev)  		modedb_tga = &modedb_tc;  		modedbsize_tga = 1;  	} + +	tgafb_init_fix(info); +  	ret = fb_find_mode(&info->var, info,  			   mode_option ? mode_option : mode_option_tga,  			   modedb_tga, modedbsize_tga, NULL, @@ -1652,7 +1494,6 @@ static int tgafb_register(struct device *dev)  	}  	tgafb_set_par(info); -	tgafb_init_fix(info);  	if (register_framebuffer(info) < 0) {  		printk(KERN_ERR "tgafb: Could not register framebuffer\n"); @@ -1671,8 +1512,8 @@ static int tgafb_register(struct device *dev)  	if (tga_bus_tc)  		pr_info("tgafb: SFB+ detected, rev=0x%02x\n",  			par->tga_chip_rev); -	pr_info("fb%d: %s frame buffer device at 0x%lx\n", -		info->node, info->fix.id, (long)bar0_start); +	fb_info(info, "%s frame buffer device at 0x%lx\n", +		info->fix.id, (long)bar0_start);  	return 0; @@ -1690,7 +1531,7 @@ static int tgafb_register(struct device *dev)  static void tgafb_unregister(struct device *dev)  {  	resource_size_t bar0_start = 0, bar0_len = 0; -	int tga_bus_pci = TGA_BUS_PCI(dev); +	int tga_bus_pci = dev_is_pci(dev);  	int tga_bus_tc = TGA_BUS_TC(dev);  	struct fb_info *info = NULL;  	struct tga_par *par; diff --git a/drivers/video/tmiofb.c b/drivers/video/fbdev/tmiofb.c index deb8733f3c7..7fb4e321a43 100644 --- a/drivers/video/tmiofb.c +++ b/drivers/video/fbdev/tmiofb.c @@ -250,7 +250,7 @@ static irqreturn_t tmiofb_irq(int irq, void *__info)   */  static int tmiofb_hw_stop(struct platform_device *dev)  { -	struct tmio_fb_data *data = dev->dev.platform_data; +	struct tmio_fb_data *data = dev_get_platdata(&dev->dev);  	struct fb_info *info = platform_get_drvdata(dev);  	struct tmiofb_par *par = info->par; @@ -311,7 +311,7 @@ static int tmiofb_hw_init(struct platform_device *dev)   */  static void tmiofb_hw_mode(struct platform_device *dev)  { -	struct tmio_fb_data *data = dev->dev.platform_data; +	struct tmio_fb_data *data = dev_get_platdata(&dev->dev);  	struct fb_info *info = platform_get_drvdata(dev);  	struct fb_videomode *mode = info->mode;  	struct tmiofb_par *par = info->par; @@ -557,7 +557,7 @@ static int tmiofb_ioctl(struct fb_info *fbi,  static struct fb_videomode *  tmiofb_find_mode(struct fb_info *info, struct fb_var_screeninfo *var)  { -	struct tmio_fb_data *data = info->device->platform_data; +	struct tmio_fb_data *data = dev_get_platdata(info->device);  	struct fb_videomode *best = NULL;  	int i; @@ -577,7 +577,7 @@ static int tmiofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)  {  	struct fb_videomode *mode; -	struct tmio_fb_data *data = info->device->platform_data; +	struct tmio_fb_data *data = dev_get_platdata(info->device);  	mode = tmiofb_find_mode(info, var);  	if (!mode || var->bits_per_pixel > 16) @@ -678,7 +678,7 @@ static struct fb_ops tmiofb_ops = {  static int tmiofb_probe(struct platform_device *dev)  {  	const struct mfd_cell *cell = mfd_get_cell(dev); -	struct tmio_fb_data *data = dev->dev.platform_data; +	struct tmio_fb_data *data = dev_get_platdata(&dev->dev);  	struct resource *ccr = platform_get_resource(dev, IORESOURCE_MEM, 1);  	struct resource *lcr = platform_get_resource(dev, IORESOURCE_MEM, 0);  	struct resource *vram = platform_get_resource(dev, IORESOURCE_MEM, 2); @@ -781,8 +781,7 @@ static int tmiofb_probe(struct platform_device *dev)  	if (retval < 0)  		goto err_register_framebuffer; -	printk(KERN_INFO "fb%d: %s frame buffer device\n", -				info->node, info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	return 0; diff --git a/drivers/video/tridentfb.c b/drivers/video/fbdev/tridentfb.c index ab57d387d6b..7ed9a227f5e 100644 --- a/drivers/video/tridentfb.c +++ b/drivers/video/fbdev/tridentfb.c @@ -1553,7 +1553,6 @@ static void trident_pci_remove(struct pci_dev *dev)  	iounmap(info->screen_base);  	release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);  	release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len); -	pci_set_drvdata(dev, NULL);  	kfree(info->pixmap.addr);  	fb_dealloc_cmap(&info->cmap);  	framebuffer_release(info); diff --git a/drivers/video/udlfb.c b/drivers/video/fbdev/udlfb.c index d2e5bc3cf96..77b890e4d29 100644 --- a/drivers/video/udlfb.c +++ b/drivers/video/fbdev/udlfb.c @@ -1166,7 +1166,7 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info)  	int new_len;  	unsigned char *old_fb = info->screen_base;  	unsigned char *new_fb; -	unsigned char *new_back = 0; +	unsigned char *new_back = NULL;  	pr_warn("Reallocating framebuffer. Addresses will change!\n"); @@ -1624,7 +1624,7 @@ static int dlfb_usb_probe(struct usb_interface *interface,  	}  	if (pixel_limit) { -		pr_warn("DL chip limit of %d overriden" +		pr_warn("DL chip limit of %d overridden"  			" by module param to %d\n",  			dev->sku_pixel_limit, pixel_limit);  		dev->sku_pixel_limit = pixel_limit; diff --git a/drivers/video/uvesafb.c b/drivers/video/fbdev/uvesafb.c index 7aec6f39fdd..509d452e8f9 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/fbdev/uvesafb.c @@ -190,7 +190,7 @@ static int uvesafb_exec(struct uvesafb_ktask *task)  	uvfb_tasks[seq] = task;  	mutex_unlock(&uvfb_lock); -	err = cn_netlink_send(m, 0, GFP_KERNEL); +	err = cn_netlink_send(m, 0, 0, GFP_KERNEL);  	if (err == -ESRCH) {  		/*  		 * Try to start the userspace helper if sending @@ -204,7 +204,7 @@ static int uvesafb_exec(struct uvesafb_ktask *task)  					"helper is installed and executable\n");  		} else {  			v86d_started = 1; -			err = cn_netlink_send(m, 0, gfp_any()); +			err = cn_netlink_send(m, 0, 0, gfp_any());  			if (err == -ENOBUFS)  				err = 0;  		} @@ -233,8 +233,7 @@ out:  static void uvesafb_free(struct uvesafb_ktask *task)  {  	if (task) { -		if (task->done) -			kfree(task->done); +		kfree(task->done);  		kfree(task);  	}  } @@ -1332,8 +1331,8 @@ setmode:  				FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;  	info->fix.line_length = mode->bytes_per_scan_line; -out:	if (crtc != NULL) -		kfree(crtc); +out: +	kfree(crtc);  	uvesafb_free(task);  	return err; @@ -1475,12 +1474,7 @@ static void uvesafb_init_info(struct fb_info *info, struct vbe_mode_ib *mode)  	 *                 used video mode, i.e. the minimum amount of  	 *                 memory we need.  	 */ -	if (mode != NULL) { -		size_vmode = info->var.yres * mode->bytes_per_scan_line; -	} else { -		size_vmode = info->var.yres * info->var.xres * -			     ((info->var.bits_per_pixel + 7) >> 3); -	} +	size_vmode = info->var.yres * mode->bytes_per_scan_line;  	/*  	 *   size_total -- all video memory we have. Used for mtrr @@ -1771,13 +1765,11 @@ static int uvesafb_probe(struct platform_device *dev)  			"using %dk, total %dk\n", info->fix.smem_start,  			info->screen_base, info->fix.smem_len/1024,  			par->vbe_ib.total_memory * 64); -	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, -			info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	err = sysfs_create_group(&dev->dev.kobj, &uvesafb_dev_attgrp);  	if (err != 0) -		printk(KERN_WARNING "fb%d: failed to register attributes\n", -			info->node); +		fb_warn(info, "failed to register attributes\n");  	return 0; @@ -1793,8 +1785,7 @@ out_mode:  	fb_destroy_modedb(info->monspecs.modedb);  	fb_dealloc_cmap(&info->cmap);  out: -	if (par->vbe_modes) -		kfree(par->vbe_modes); +	kfree(par->vbe_modes);  	framebuffer_release(info);  	return err; @@ -1816,14 +1807,9 @@ static int uvesafb_remove(struct platform_device *dev)  		fb_destroy_modedb(info->monspecs.modedb);  		fb_dealloc_cmap(&info->cmap); -		if (par) { -			if (par->vbe_modes) -				kfree(par->vbe_modes); -			if (par->vbe_state_orig) -				kfree(par->vbe_state_orig); -			if (par->vbe_state_saved) -				kfree(par->vbe_state_saved); -		} +		kfree(par->vbe_modes); +		kfree(par->vbe_state_orig); +		kfree(par->vbe_state_saved);  		framebuffer_release(info);  	} diff --git a/drivers/video/valkyriefb.c b/drivers/video/fbdev/valkyriefb.c index 3f5a041601d..97cb9bd1d1d 100644 --- a/drivers/video/valkyriefb.c +++ b/drivers/video/fbdev/valkyriefb.c @@ -56,7 +56,6 @@  #include <linux/cuda.h>  #include <asm/io.h>  #ifdef CONFIG_MAC -#include <asm/bootinfo.h>  #include <asm/macintosh.h>  #else  #include <asm/prom.h> @@ -392,7 +391,7 @@ int __init valkyriefb_init(void)  	if ((err = register_framebuffer(&p->info)) != 0)  		goto out_cmap_free; -	printk(KERN_INFO "fb%d: valkyrie frame buffer device\n", p->info.node); +	fb_info(&p->info, "valkyrie frame buffer device\n");  	return 0;   out_cmap_free: diff --git a/drivers/video/valkyriefb.h b/drivers/video/fbdev/valkyriefb.h index d787441e5a4..d787441e5a4 100644 --- a/drivers/video/valkyriefb.h +++ b/drivers/video/fbdev/valkyriefb.h diff --git a/drivers/video/vermilion/Makefile b/drivers/video/fbdev/vermilion/Makefile index cc21a656153..cc21a656153 100644 --- a/drivers/video/vermilion/Makefile +++ b/drivers/video/fbdev/vermilion/Makefile diff --git a/drivers/video/vermilion/cr_pll.c b/drivers/video/fbdev/vermilion/cr_pll.c index ebc6e6e0dd0..ebc6e6e0dd0 100644 --- a/drivers/video/vermilion/cr_pll.c +++ b/drivers/video/fbdev/vermilion/cr_pll.c diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/fbdev/vermilion/vermilion.c index 09a136633f3..048a66640b0 100644 --- a/drivers/video/vermilion/vermilion.c +++ b/drivers/video/fbdev/vermilion/vermilion.c @@ -383,7 +383,6 @@ static void vmlfb_disable_mmio(struct vml_par *par)  static void vmlfb_release_devices(struct vml_par *par)  {  	if (atomic_dec_and_test(&par->refcount)) { -		pci_set_drvdata(par->vdc, NULL);  		pci_disable_device(par->gpu);  		pci_disable_device(par->vdc);  	} diff --git a/drivers/video/vermilion/vermilion.h b/drivers/video/fbdev/vermilion/vermilion.h index 43d11ec197f..43d11ec197f 100644 --- a/drivers/video/vermilion/vermilion.h +++ b/drivers/video/fbdev/vermilion/vermilion.h diff --git a/drivers/video/vesafb.c b/drivers/video/fbdev/vesafb.c index bd83233ec22..6170e7f5864 100644 --- a/drivers/video/vesafb.c +++ b/drivers/video/fbdev/vesafb.c @@ -179,7 +179,6 @@ static void vesafb_destroy(struct fb_info *info)  	if (info->screen_base)  		iounmap(info->screen_base);  	release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size); -	framebuffer_release(info);  }  static struct fb_ops vesafb_ops = { @@ -297,6 +296,7 @@ static int vesafb_probe(struct platform_device *dev)  		release_mem_region(vesafb_fix.smem_start, size_total);  		return -ENOMEM;  	} +	platform_set_drvdata(dev, info);  	info->pseudo_palette = info->par;  	info->par = NULL; @@ -489,8 +489,7 @@ static int vesafb_probe(struct platform_device *dev)  		fb_dealloc_cmap(&info->cmap);  		goto err;  	} -	printk(KERN_INFO "fb%d: %s frame buffer device\n", -	       info->node, info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	return 0;  err:  	if (info->screen_base) @@ -500,12 +499,23 @@ err:  	return err;  } +static int vesafb_remove(struct platform_device *pdev) +{ +	struct fb_info *info = platform_get_drvdata(pdev); + +	unregister_framebuffer(info); +	framebuffer_release(info); + +	return 0; +} +  static struct platform_driver vesafb_driver = {  	.driver = {  		.name = "vesa-framebuffer",  		.owner = THIS_MODULE,  	},  	.probe = vesafb_probe, +	.remove = vesafb_remove,  };  module_platform_driver(vesafb_driver); diff --git a/drivers/video/vfb.c b/drivers/video/fbdev/vfb.c index ee5985efa15..70a897b1e45 100644 --- a/drivers/video/vfb.c +++ b/drivers/video/fbdev/vfb.c @@ -390,9 +390,8 @@ static int vfb_pan_display(struct fb_var_screeninfo *var,  			   struct fb_info *info)  {  	if (var->vmode & FB_VMODE_YWRAP) { -		if (var->yoffset < 0 -		    || var->yoffset >= info->var.yres_virtual -		    || var->xoffset) +		if (var->yoffset >= info->var.yres_virtual || +		    var->xoffset)  			return -EINVAL;  	} else {  		if (var->xoffset + info->var.xres > info->var.xres_virtual || @@ -527,9 +526,8 @@ static int vfb_probe(struct platform_device *dev)  		goto err2;  	platform_set_drvdata(dev, info); -	printk(KERN_INFO -	       "fb%d: Virtual frame buffer device, using %ldK of video memory\n", -	       info->node, videomemorysize >> 10); +	fb_info(info, "Virtual frame buffer device, using %ldK of video memory\n", +		videomemorysize >> 10);  	return 0;  err2:  	fb_dealloc_cmap(&info->cmap); diff --git a/drivers/video/vga16fb.c b/drivers/video/fbdev/vga16fb.c index 2827333703d..283d335a759 100644 --- a/drivers/video/vga16fb.c +++ b/drivers/video/fbdev/vga16fb.c @@ -1377,8 +1377,7 @@ static int vga16fb_probe(struct platform_device *dev)  		goto err_check_var;  	} -	printk(KERN_INFO "fb%d: %s frame buffer device\n", -	       info->node, info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	platform_set_drvdata(dev, info);  	return 0; diff --git a/drivers/video/via/Makefile b/drivers/video/fbdev/via/Makefile index 159f26e6adb..159f26e6adb 100644 --- a/drivers/video/via/Makefile +++ b/drivers/video/fbdev/via/Makefile diff --git a/drivers/video/via/accel.c b/drivers/video/fbdev/via/accel.c index 4b67b8e6030..4b67b8e6030 100644 --- a/drivers/video/via/accel.c +++ b/drivers/video/fbdev/via/accel.c diff --git a/drivers/video/via/accel.h b/drivers/video/fbdev/via/accel.h index 79d5e10cc83..79d5e10cc83 100644 --- a/drivers/video/via/accel.h +++ b/drivers/video/fbdev/via/accel.h diff --git a/drivers/video/via/chip.h b/drivers/video/fbdev/via/chip.h index d32a5076c20..d32a5076c20 100644 --- a/drivers/video/via/chip.h +++ b/drivers/video/fbdev/via/chip.h diff --git a/drivers/video/via/debug.h b/drivers/video/fbdev/via/debug.h index 86eacc2017f..86eacc2017f 100644 --- a/drivers/video/via/debug.h +++ b/drivers/video/fbdev/via/debug.h diff --git a/drivers/video/via/dvi.c b/drivers/video/fbdev/via/dvi.c index 7789553952d..7789553952d 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/fbdev/via/dvi.c diff --git a/drivers/video/via/dvi.h b/drivers/video/fbdev/via/dvi.h index 4c6bfba57d1..4c6bfba57d1 100644 --- a/drivers/video/via/dvi.h +++ b/drivers/video/fbdev/via/dvi.h diff --git a/drivers/video/via/global.c b/drivers/video/fbdev/via/global.c index 3102171c167..3102171c167 100644 --- a/drivers/video/via/global.c +++ b/drivers/video/fbdev/via/global.c diff --git a/drivers/video/via/global.h b/drivers/video/fbdev/via/global.h index 275dbbbd6b8..275dbbbd6b8 100644 --- a/drivers/video/via/global.h +++ b/drivers/video/fbdev/via/global.h diff --git a/drivers/video/via/hw.c b/drivers/video/fbdev/via/hw.c index 22450908306..22450908306 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/fbdev/via/hw.c diff --git a/drivers/video/via/hw.h b/drivers/video/fbdev/via/hw.h index 3be073c58b0..3be073c58b0 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/fbdev/via/hw.h diff --git a/drivers/video/via/ioctl.c b/drivers/video/fbdev/via/ioctl.c index ea1c5142882..ea1c5142882 100644 --- a/drivers/video/via/ioctl.c +++ b/drivers/video/fbdev/via/ioctl.c diff --git a/drivers/video/via/ioctl.h b/drivers/video/fbdev/via/ioctl.h index 6010d10b59e..6010d10b59e 100644 --- a/drivers/video/via/ioctl.h +++ b/drivers/video/fbdev/via/ioctl.h diff --git a/drivers/video/via/lcd.c b/drivers/video/fbdev/via/lcd.c index 5d21ff436ec..5d21ff436ec 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/fbdev/via/lcd.c diff --git a/drivers/video/via/lcd.h b/drivers/video/fbdev/via/lcd.h index 5c988a063ad..5c988a063ad 100644 --- a/drivers/video/via/lcd.h +++ b/drivers/video/fbdev/via/lcd.h diff --git a/drivers/video/via/share.h b/drivers/video/fbdev/via/share.h index 65c65c611e0..65c65c611e0 100644 --- a/drivers/video/via/share.h +++ b/drivers/video/fbdev/via/share.h diff --git a/drivers/video/via/tblDPASetting.c b/drivers/video/fbdev/via/tblDPASetting.c index 73bb554e7c1..73bb554e7c1 100644 --- a/drivers/video/via/tblDPASetting.c +++ b/drivers/video/fbdev/via/tblDPASetting.c diff --git a/drivers/video/via/tblDPASetting.h b/drivers/video/fbdev/via/tblDPASetting.h index 6db61519cb5..6db61519cb5 100644 --- a/drivers/video/via/tblDPASetting.h +++ b/drivers/video/fbdev/via/tblDPASetting.h diff --git a/drivers/video/via/via-core.c b/drivers/video/fbdev/via/via-core.c index 6e274825fb3..6e274825fb3 100644 --- a/drivers/video/via/via-core.c +++ b/drivers/video/fbdev/via/via-core.c diff --git a/drivers/video/via/via-gpio.c b/drivers/video/fbdev/via/via-gpio.c index e408679081a..e408679081a 100644 --- a/drivers/video/via/via-gpio.c +++ b/drivers/video/fbdev/via/via-gpio.c diff --git a/drivers/video/via/via_aux.c b/drivers/video/fbdev/via/via_aux.c index 4a0a55cdac3..4a0a55cdac3 100644 --- a/drivers/video/via/via_aux.c +++ b/drivers/video/fbdev/via/via_aux.c diff --git a/drivers/video/via/via_aux.h b/drivers/video/fbdev/via/via_aux.h index a8de3f038ce..a8de3f038ce 100644 --- a/drivers/video/via/via_aux.h +++ b/drivers/video/fbdev/via/via_aux.h diff --git a/drivers/video/via/via_aux_ch7301.c b/drivers/video/fbdev/via/via_aux_ch7301.c index 1cbe5037a6b..1cbe5037a6b 100644 --- a/drivers/video/via/via_aux_ch7301.c +++ b/drivers/video/fbdev/via/via_aux_ch7301.c diff --git a/drivers/video/via/via_aux_edid.c b/drivers/video/fbdev/via/via_aux_edid.c index 754d4509033..754d4509033 100644 --- a/drivers/video/via/via_aux_edid.c +++ b/drivers/video/fbdev/via/via_aux_edid.c diff --git a/drivers/video/via/via_aux_sii164.c b/drivers/video/fbdev/via/via_aux_sii164.c index ca1b35f033b..ca1b35f033b 100644 --- a/drivers/video/via/via_aux_sii164.c +++ b/drivers/video/fbdev/via/via_aux_sii164.c diff --git a/drivers/video/via/via_aux_vt1621.c b/drivers/video/fbdev/via/via_aux_vt1621.c index 38eca847989..38eca847989 100644 --- a/drivers/video/via/via_aux_vt1621.c +++ b/drivers/video/fbdev/via/via_aux_vt1621.c diff --git a/drivers/video/via/via_aux_vt1622.c b/drivers/video/fbdev/via/via_aux_vt1622.c index 8c79c68ba68..8c79c68ba68 100644 --- a/drivers/video/via/via_aux_vt1622.c +++ b/drivers/video/fbdev/via/via_aux_vt1622.c diff --git a/drivers/video/via/via_aux_vt1625.c b/drivers/video/fbdev/via/via_aux_vt1625.c index 03eb30165d3..03eb30165d3 100644 --- a/drivers/video/via/via_aux_vt1625.c +++ b/drivers/video/fbdev/via/via_aux_vt1625.c diff --git a/drivers/video/via/via_aux_vt1631.c b/drivers/video/fbdev/via/via_aux_vt1631.c index 06e742f1f72..06e742f1f72 100644 --- a/drivers/video/via/via_aux_vt1631.c +++ b/drivers/video/fbdev/via/via_aux_vt1631.c diff --git a/drivers/video/via/via_aux_vt1632.c b/drivers/video/fbdev/via/via_aux_vt1632.c index d24f4cd9740..d24f4cd9740 100644 --- a/drivers/video/via/via_aux_vt1632.c +++ b/drivers/video/fbdev/via/via_aux_vt1632.c diff --git a/drivers/video/via/via_aux_vt1636.c b/drivers/video/fbdev/via/via_aux_vt1636.c index 9e015c101d4..9e015c101d4 100644 --- a/drivers/video/via/via_aux_vt1636.c +++ b/drivers/video/fbdev/via/via_aux_vt1636.c diff --git a/drivers/video/via/via_clock.c b/drivers/video/fbdev/via/via_clock.c index db1e39277e3..db1e39277e3 100644 --- a/drivers/video/via/via_clock.c +++ b/drivers/video/fbdev/via/via_clock.c diff --git a/drivers/video/via/via_clock.h b/drivers/video/fbdev/via/via_clock.h index 88714ae0d15..88714ae0d15 100644 --- a/drivers/video/via/via_clock.h +++ b/drivers/video/fbdev/via/via_clock.h diff --git a/drivers/video/via/via_i2c.c b/drivers/video/fbdev/via/via_i2c.c index dd53058bbbb..dd53058bbbb 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/fbdev/via/via_i2c.c diff --git a/drivers/video/via/via_modesetting.c b/drivers/video/fbdev/via/via_modesetting.c index 0b414b09b9b..0b414b09b9b 100644 --- a/drivers/video/via/via_modesetting.c +++ b/drivers/video/fbdev/via/via_modesetting.c diff --git a/drivers/video/via/via_modesetting.h b/drivers/video/fbdev/via/via_modesetting.h index f6a6503da3b..f6a6503da3b 100644 --- a/drivers/video/via/via_modesetting.h +++ b/drivers/video/fbdev/via/via_modesetting.h diff --git a/drivers/video/via/via_utility.c b/drivers/video/fbdev/via/via_utility.c index 35458a5eadc..35458a5eadc 100644 --- a/drivers/video/via/via_utility.c +++ b/drivers/video/fbdev/via/via_utility.c diff --git a/drivers/video/via/via_utility.h b/drivers/video/fbdev/via/via_utility.h index f23be1708c1..f23be1708c1 100644 --- a/drivers/video/via/via_utility.h +++ b/drivers/video/fbdev/via/via_utility.h diff --git a/drivers/video/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c index 325c43c6ff9..325c43c6ff9 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/fbdev/via/viafbdev.c diff --git a/drivers/video/via/viafbdev.h b/drivers/video/fbdev/via/viafbdev.h index f6b2ddf56e9..f6b2ddf56e9 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/fbdev/via/viafbdev.h diff --git a/drivers/video/via/viamode.c b/drivers/video/fbdev/via/viamode.c index 0666ab01cf4..0666ab01cf4 100644 --- a/drivers/video/via/viamode.c +++ b/drivers/video/fbdev/via/viamode.c diff --git a/drivers/video/via/viamode.h b/drivers/video/fbdev/via/viamode.h index dd19106698e..dd19106698e 100644 --- a/drivers/video/via/viamode.h +++ b/drivers/video/fbdev/via/viamode.h diff --git a/drivers/video/via/vt1636.c b/drivers/video/fbdev/via/vt1636.c index ee2903b472c..ee2903b472c 100644 --- a/drivers/video/via/vt1636.c +++ b/drivers/video/fbdev/via/vt1636.c diff --git a/drivers/video/via/vt1636.h b/drivers/video/fbdev/via/vt1636.h index 4c1314e5746..4c1314e5746 100644 --- a/drivers/video/via/vt1636.h +++ b/drivers/video/fbdev/via/vt1636.h diff --git a/drivers/video/vt8500lcdfb.c b/drivers/video/fbdev/vt8500lcdfb.c index 897484903c3..a1134c3f6c1 100644 --- a/drivers/video/vt8500lcdfb.c +++ b/drivers/video/fbdev/vt8500lcdfb.c @@ -293,8 +293,7 @@ static int vt8500lcd_probe(struct platform_device *pdev)  			+ sizeof(u32) * 16, GFP_KERNEL);  	if (!fbi) {  		dev_err(&pdev->dev, "Failed to initialize framebuffer device\n"); -		ret = -ENOMEM; -		goto failed; +		return -ENOMEM;  	}  	strcpy(fbi->fb.fix.id, "VT8500 LCD"); @@ -327,15 +326,13 @@ static int vt8500lcd_probe(struct platform_device *pdev)  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	if (res == NULL) {  		dev_err(&pdev->dev, "no I/O memory resource defined\n"); -		ret = -ENODEV; -		goto failed_fbi; +		return -ENODEV;  	}  	res = request_mem_region(res->start, resource_size(res), "vt8500lcd");  	if (res == NULL) {  		dev_err(&pdev->dev, "failed to request I/O memory\n"); -		ret = -EBUSY; -		goto failed_fbi; +		return -EBUSY;  	}  	fbi->regbase = ioremap(res->start, resource_size(res)); @@ -346,17 +343,19 @@ static int vt8500lcd_probe(struct platform_device *pdev)  	}  	disp_timing = of_get_display_timings(pdev->dev.of_node); -	if (!disp_timing) -		return -EINVAL; +	if (!disp_timing) { +		ret = -EINVAL; +		goto failed_free_io; +	}  	ret = of_get_fb_videomode(pdev->dev.of_node, &of_mode,  							OF_USE_NATIVE_MODE);  	if (ret) -		return ret; +		goto failed_free_io;  	ret = of_property_read_u32(pdev->dev.of_node, "bits-per-pixel", &bpp);  	if (ret) -		return ret; +		goto failed_free_io;  	/* try allocating the framebuffer */  	fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8); @@ -364,8 +363,9 @@ static int vt8500lcd_probe(struct platform_device *pdev)  				GFP_KERNEL);  	if (!fb_mem_virt) {  		pr_err("%s: Failed to allocate framebuffer\n", __func__); -		return -ENOMEM; -	}; +		ret = -ENOMEM; +		goto failed_free_io; +	}  	fbi->fb.fix.smem_start	= fb_mem_phys;  	fbi->fb.fix.smem_len	= fb_mem_len; @@ -447,9 +447,6 @@ failed_free_io:  	iounmap(fbi->regbase);  failed_free_res:  	release_mem_region(res->start, resource_size(res)); -failed_fbi: -	kfree(fbi); -failed:  	return ret;  } @@ -477,8 +474,6 @@ static int vt8500lcd_remove(struct platform_device *pdev)  	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  	release_mem_region(res->start, resource_size(res)); -	kfree(fbi); -  	return 0;  } diff --git a/drivers/video/vt8500lcdfb.h b/drivers/video/fbdev/vt8500lcdfb.h index 36ca3ca09d8..36ca3ca09d8 100644 --- a/drivers/video/vt8500lcdfb.h +++ b/drivers/video/fbdev/vt8500lcdfb.h diff --git a/drivers/video/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c index e9557fa014e..5c7cbc6c623 100644 --- a/drivers/video/vt8623fb.c +++ b/drivers/video/fbdev/vt8623fb.c @@ -266,7 +266,7 @@ static void vt8623_set_pixclock(struct fb_info *info, u32 pixclock)  	rv = svga_compute_pll(&vt8623_pll, 1000000000 / pixclock, &m, &n, &r, info->node);  	if (rv < 0) { -		printk(KERN_ERR "fb%d: cannot set requested pixclock, keeping old value\n", info->node); +		fb_err(info, "cannot set requested pixclock, keeping old value\n");  		return;  	} @@ -335,7 +335,7 @@ static int vt8623fb_check_var(struct fb_var_screeninfo *var, struct fb_info *inf  	rv = svga_match_format (vt8623fb_formats, var, NULL);  	if (rv < 0)  	{ -		printk(KERN_ERR "fb%d: unsupported mode requested\n", info->node); +		fb_err(info, "unsupported mode requested\n");  		return rv;  	} @@ -354,21 +354,23 @@ static int vt8623fb_check_var(struct fb_var_screeninfo *var, struct fb_info *inf  	mem = ((var->bits_per_pixel * var->xres_virtual) >> 3) * var->yres_virtual;  	if (mem > info->screen_size)  	{ -		printk(KERN_ERR "fb%d: not enough framebuffer memory (%d kB requested , %d kB available)\n", info->node, mem >> 10, (unsigned int) (info->screen_size >> 10)); +		fb_err(info, "not enough framebuffer memory (%d kB requested, %d kB available)\n", +		       mem >> 10, (unsigned int) (info->screen_size >> 10));  		return -EINVAL;  	}  	/* Text mode is limited to 256 kB of memory */  	if ((var->bits_per_pixel == 0) && (mem > (256*1024)))  	{ -		printk(KERN_ERR "fb%d: text framebuffer size too large (%d kB requested, 256 kB possible)\n", info->node, mem >> 10); +		fb_err(info, "text framebuffer size too large (%d kB requested, 256 kB possible)\n", +		       mem >> 10);  		return -EINVAL;  	}  	rv = svga_check_timings (&vt8623_timing_regs, var, info->node);  	if (rv < 0)  	{ -		printk(KERN_ERR "fb%d: invalid timings requested\n", info->node); +		fb_err(info, "invalid timings requested\n");  		return rv;  	} @@ -474,32 +476,32 @@ static int vt8623fb_set_par(struct fb_info *info)  	mode = svga_match_format(vt8623fb_formats, &(info->var), &(info->fix));  	switch (mode) {  	case 0: -		pr_debug("fb%d: text mode\n", info->node); +		fb_dbg(info, "text mode\n");  		svga_set_textmode_vga_regs(par->state.vgabase);  		svga_wseq_mask(par->state.vgabase, 0x15, 0x00, 0xFE);  		svga_wcrt_mask(par->state.vgabase, 0x11, 0x60, 0x70);  		break;  	case 1: -		pr_debug("fb%d: 4 bit pseudocolor\n", info->node); +		fb_dbg(info, "4 bit pseudocolor\n");  		vga_wgfx(par->state.vgabase, VGA_GFX_MODE, 0x40);  		svga_wseq_mask(par->state.vgabase, 0x15, 0x20, 0xFE);  		svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x70);  		break;  	case 2: -		pr_debug("fb%d: 4 bit pseudocolor, planar\n", info->node); +		fb_dbg(info, "4 bit pseudocolor, planar\n");  		svga_wseq_mask(par->state.vgabase, 0x15, 0x00, 0xFE);  		svga_wcrt_mask(par->state.vgabase, 0x11, 0x00, 0x70);  		break;  	case 3: -		pr_debug("fb%d: 8 bit pseudocolor\n", info->node); +		fb_dbg(info, "8 bit pseudocolor\n");  		svga_wseq_mask(par->state.vgabase, 0x15, 0x22, 0xFE);  		break;  	case 4: -		pr_debug("fb%d: 5/6/5 truecolor\n", info->node); +		fb_dbg(info, "5/6/5 truecolor\n");  		svga_wseq_mask(par->state.vgabase, 0x15, 0xB6, 0xFE);  		break;  	case 5: -		pr_debug("fb%d: 8/8/8 truecolor\n", info->node); +		fb_dbg(info, "8/8/8 truecolor\n");  		svga_wseq_mask(par->state.vgabase, 0x15, 0xAE, 0xFE);  		break;  	default: @@ -584,27 +586,27 @@ static int vt8623fb_blank(int blank_mode, struct fb_info *info)  	switch (blank_mode) {  	case FB_BLANK_UNBLANK: -		pr_debug("fb%d: unblank\n", info->node); +		fb_dbg(info, "unblank\n");  		svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);  		svga_wseq_mask(par->state.vgabase, 0x01, 0x00, 0x20);  		break;  	case FB_BLANK_NORMAL: -		pr_debug("fb%d: blank\n", info->node); +		fb_dbg(info, "blank\n");  		svga_wcrt_mask(par->state.vgabase, 0x36, 0x00, 0x30);  		svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);  		break;  	case FB_BLANK_HSYNC_SUSPEND: -		pr_debug("fb%d: DPMS standby (hsync off)\n", info->node); +		fb_dbg(info, "DPMS standby (hsync off)\n");  		svga_wcrt_mask(par->state.vgabase, 0x36, 0x10, 0x30);  		svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);  		break;  	case FB_BLANK_VSYNC_SUSPEND: -		pr_debug("fb%d: DPMS suspend (vsync off)\n", info->node); +		fb_dbg(info, "DPMS suspend (vsync off)\n");  		svga_wcrt_mask(par->state.vgabase, 0x36, 0x20, 0x30);  		svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);  		break;  	case FB_BLANK_POWERDOWN: -		pr_debug("fb%d: DPMS off (no sync)\n", info->node); +		fb_dbg(info, "DPMS off (no sync)\n");  		svga_wcrt_mask(par->state.vgabase, 0x36, 0x30, 0x30);  		svga_wseq_mask(par->state.vgabase, 0x01, 0x20, 0x20);  		break; @@ -727,7 +729,7 @@ static int vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  	vga_res.flags = IORESOURCE_IO; -	pcibios_bus_to_resource(dev, &vga_res, &bus_reg); +	pcibios_bus_to_resource(dev->bus, &vga_res, &bus_reg);  	par->state.vgabase = (void __iomem *) vga_res.start; @@ -769,12 +771,12 @@ static int vt8623_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)  	rc = register_framebuffer(info);  	if (rc < 0) { -		dev_err(info->device, "cannot register framebugger\n"); +		dev_err(info->device, "cannot register framebuffer\n");  		goto err_reg_fb;  	} -	printk(KERN_INFO "fb%d: %s on %s, %d MB RAM\n", info->node, info->fix.id, -		 pci_name(dev), info->fix.smem_len >> 20); +	fb_info(info, "%s on %s, %d MB RAM\n", +		info->fix.id, pci_name(dev), info->fix.smem_len >> 20);  	/* Record a reference to the driver data */  	pci_set_drvdata(dev, info); @@ -829,7 +831,6 @@ static void vt8623_pci_remove(struct pci_dev *dev)  		pci_release_regions(dev);  /*		pci_disable_device(dev); */ -		pci_set_drvdata(dev, NULL);  		framebuffer_release(info);  	}  } diff --git a/drivers/video/w100fb.c b/drivers/video/fbdev/w100fb.c index 7a299e951f7..10951c82f6e 100644 --- a/drivers/video/w100fb.c +++ b/drivers/video/fbdev/w100fb.c @@ -680,7 +680,7 @@ int w100fb_probe(struct platform_device *pdev)  	par = info->par;  	platform_set_drvdata(pdev, info); -	inf = pdev->dev.platform_data; +	inf = dev_get_platdata(&pdev->dev);  	par->chip_id = chip_id;  	par->mach = inf;  	par->fastpll_mode = 0; @@ -761,10 +761,9 @@ int w100fb_probe(struct platform_device *pdev)  	err |= device_create_file(&pdev->dev, &dev_attr_flip);  	if (err != 0) -		printk(KERN_WARNING "fb%d: failed to register attributes (%d)\n", -				info->node, err); +		fb_warn(info, "failed to register attributes (%d)\n", err); -	printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); +	fb_info(info, "%s frame buffer device\n", info->fix.id);  	return 0;  out:  	if (info) { diff --git a/drivers/video/w100fb.h b/drivers/video/fbdev/w100fb.h index fffae7b4f6e..fffae7b4f6e 100644 --- a/drivers/video/w100fb.h +++ b/drivers/video/fbdev/w100fb.h diff --git a/drivers/video/wm8505fb.c b/drivers/video/fbdev/wm8505fb.c index 3072f30cad1..d2fafbbcd7f 100644 --- a/drivers/video/wm8505fb.c +++ b/drivers/video/fbdev/wm8505fb.c @@ -162,7 +162,7 @@ static ssize_t contrast_show(struct device *dev,  	struct fb_info *info = dev_get_drvdata(dev);  	struct wm8505fb_info *fbi = to_wm8505fb_info(info); -	return sprintf(buf, "%d\n", fbi->contrast); +	return sprintf(buf, "%u\n", fbi->contrast);  }  static ssize_t contrast_store(struct device *dev, @@ -372,14 +372,12 @@ static int wm8505fb_probe(struct platform_device *pdev)  	}  	ret = device_create_file(&pdev->dev, &dev_attr_contrast); -	if (ret < 0) { -		printk(KERN_WARNING "fb%d: failed to register attributes (%d)\n", -			fbi->fb.node, ret); -	} +	if (ret < 0) +		fb_warn(&fbi->fb, "failed to register attributes (%d)\n", ret); -	printk(KERN_INFO "fb%d: %s frame buffer at 0x%lx-0x%lx\n", -	       fbi->fb.node, fbi->fb.fix.id, fbi->fb.fix.smem_start, -	       fbi->fb.fix.smem_start + fbi->fb.fix.smem_len - 1); +	fb_info(&fbi->fb, "%s frame buffer at 0x%lx-0x%lx\n", +		fbi->fb.fix.id, fbi->fb.fix.smem_start, +		fbi->fb.fix.smem_start + fbi->fb.fix.smem_len - 1);  	return 0;  } @@ -411,7 +409,7 @@ static struct platform_driver wm8505fb_driver = {  	.driver		= {  		.owner	= THIS_MODULE,  		.name	= DRIVER_NAME, -		.of_match_table = of_match_ptr(wmt_dt_ids), +		.of_match_table = wmt_dt_ids,  	},  }; diff --git a/drivers/video/wm8505fb_regs.h b/drivers/video/fbdev/wm8505fb_regs.h index 4dd41668c6d..4dd41668c6d 100644 --- a/drivers/video/wm8505fb_regs.h +++ b/drivers/video/fbdev/wm8505fb_regs.h diff --git a/drivers/video/wmt_ge_rops.c b/drivers/video/fbdev/wmt_ge_rops.c index 4aaeb18223b..9df6fe78a44 100644 --- a/drivers/video/wmt_ge_rops.c +++ b/drivers/video/fbdev/wmt_ge_rops.c @@ -18,7 +18,7 @@  #include <linux/module.h>  #include <linux/fb.h>  #include <linux/platform_device.h> -#include "fb_draw.h" +#include "core/fb_draw.h"  #define GE_COMMAND_OFF		0x00  #define GE_DEPTH_OFF		0x04 @@ -169,13 +169,13 @@ static struct platform_driver wmt_ge_rops_driver = {  	.driver		= {  		.owner	= THIS_MODULE,  		.name	= "wmt_ge_rops", -		.of_match_table = of_match_ptr(wmt_dt_ids), +		.of_match_table = wmt_dt_ids,  	},  };  module_platform_driver(wmt_ge_rops_driver); -MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com"); +MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>");  MODULE_DESCRIPTION("Accelerators for raster operations using "  		   "WonderMedia Graphics Engine");  MODULE_LICENSE("GPL v2"); diff --git a/drivers/video/wmt_ge_rops.h b/drivers/video/fbdev/wmt_ge_rops.h index f73ec6377a4..f73ec6377a4 100644 --- a/drivers/video/wmt_ge_rops.h +++ b/drivers/video/fbdev/wmt_ge_rops.h diff --git a/drivers/video/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c index cd005c227a2..901014bbc82 100644 --- a/drivers/video/xen-fbfront.c +++ b/drivers/video/fbdev/xen-fbfront.c @@ -35,6 +35,7 @@  #include <xen/interface/io/fbif.h>  #include <xen/interface/io/protocols.h>  #include <xen/xenbus.h> +#include <xen/platform_pci.h>  struct xenfb_info {  	unsigned char		*fb; @@ -692,13 +693,16 @@ static DEFINE_XENBUS_DRIVER(xenfb, ,  static int __init xenfb_init(void)  { -	if (!xen_pv_domain()) +	if (!xen_domain())  		return -ENODEV;  	/* Nothing to do if running in dom0. */  	if (xen_initial_domain())  		return -ENODEV; +	if (!xen_has_pv_devices()) +		return -ENODEV; +  	return xenbus_register_frontend(&xenfb_driver);  } diff --git a/drivers/video/xilinxfb.c b/drivers/video/fbdev/xilinxfb.c index 84c664ea8eb..553cff2f3f4 100644 --- a/drivers/video/xilinxfb.c +++ b/drivers/video/fbdev/xilinxfb.c @@ -33,7 +33,6 @@  #include <linux/of_platform.h>  #include <linux/of_address.h>  #include <linux/io.h> -#include <linux/xilinxfb.h>  #include <linux/slab.h>  #ifdef CONFIG_PPC_DCR @@ -84,6 +83,20 @@  #define PALETTE_ENTRIES_NO	16	/* passed to fb_alloc_cmap() */ +/* ML300/403 reference design framebuffer driver platform data struct */ +struct xilinxfb_platform_data { +	u32 rotate_screen;      /* Flag to rotate display 180 degrees */ +	u32 screen_height_mm;   /* Physical dimensions of screen in mm */ +	u32 screen_width_mm; +	u32 xres, yres;         /* resolution of screen in pixels */ +	u32 xvirt, yvirt;       /* resolution of memory buffer */ + +	/* Physical address of framebuffer memory; If non-zero, driver +	* will use provided memory address instead of allocating one from +	* the consistent pool. */ +	u32 fb_phys; +}; +  /*   * Default xilinxfb configuration   */ @@ -260,10 +273,9 @@ static int xilinxfb_assign(struct platform_device *pdev,  		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);  		drvdata->regs = devm_ioremap_resource(&pdev->dev, res); -		if (IS_ERR(drvdata->regs)) { -			rc = PTR_ERR(drvdata->regs); -			goto err_region; -		} +		if (IS_ERR(drvdata->regs)) +			return PTR_ERR(drvdata->regs); +  		drvdata->regs_phys = res->start;  	} @@ -279,11 +291,7 @@ static int xilinxfb_assign(struct platform_device *pdev,  	if (!drvdata->fb_virt) {  		dev_err(dev, "Could not allocate frame buffer memory\n"); -		rc = -ENOMEM; -		if (drvdata->flags & BUS_ACCESS_FLAG) -			goto err_fbmem; -		else -			goto err_region; +		return -ENOMEM;  	}  	/* Clear (turn to black) the framebuffer */ @@ -363,14 +371,6 @@ err_cmap:  	/* Turn off the display */  	xilinx_fb_out32(drvdata, REG_CTRL, 0); -err_fbmem: -	if (drvdata->flags & BUS_ACCESS_FLAG) -		devm_iounmap(dev, drvdata->regs); - -err_region: -	kfree(drvdata); -	dev_set_drvdata(dev, NULL); -  	return rc;  } @@ -395,17 +395,12 @@ static int xilinxfb_release(struct device *dev)  	/* Turn off the display */  	xilinx_fb_out32(drvdata, REG_CTRL, 0); -	/* Release the resources, as allocated based on interface */ -	if (drvdata->flags & BUS_ACCESS_FLAG) -		devm_iounmap(dev, drvdata->regs);  #ifdef CONFIG_PPC_DCR -	else +	/* Release the resources, as allocated based on interface */ +	if (!(drvdata->flags & BUS_ACCESS_FLAG))  		dcr_unmap(drvdata->dcr_host, drvdata->dcr_len);  #endif -	kfree(drvdata); -	dev_set_drvdata(dev, NULL); -  	return 0;  } @@ -413,7 +408,7 @@ static int xilinxfb_release(struct device *dev)   * OF bus binding   */ -static int xilinxfb_of_probe(struct platform_device *op) +static int xilinxfb_of_probe(struct platform_device *pdev)  {  	const u32 *prop;  	u32 tft_access = 0; @@ -425,17 +420,15 @@ static int xilinxfb_of_probe(struct platform_device *op)  	pdata = xilinx_fb_default_pdata;  	/* Allocate the driver data region */ -	drvdata = kzalloc(sizeof(*drvdata), GFP_KERNEL); -	if (!drvdata) { -		dev_err(&op->dev, "Couldn't allocate device private record\n"); +	drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL); +	if (!drvdata)  		return -ENOMEM; -	}  	/*  	 * To check whether the core is connected directly to DCR or BUS  	 * interface and initialize the tft_access accordingly.  	 */ -	of_property_read_u32(op->dev.of_node, "xlnx,dcr-splb-slave-if", +	of_property_read_u32(pdev->dev.of_node, "xlnx,dcr-splb-slave-if",  			     &tft_access);  	/* @@ -448,40 +441,39 @@ static int xilinxfb_of_probe(struct platform_device *op)  #ifdef CONFIG_PPC_DCR  	else {  		int start; -		start = dcr_resource_start(op->dev.of_node, 0); -		drvdata->dcr_len = dcr_resource_len(op->dev.of_node, 0); -		drvdata->dcr_host = dcr_map(op->dev.of_node, start, drvdata->dcr_len); +		start = dcr_resource_start(pdev->dev.of_node, 0); +		drvdata->dcr_len = dcr_resource_len(pdev->dev.of_node, 0); +		drvdata->dcr_host = dcr_map(pdev->dev.of_node, start, drvdata->dcr_len);  		if (!DCR_MAP_OK(drvdata->dcr_host)) { -			dev_err(&op->dev, "invalid DCR address\n"); -			kfree(drvdata); +			dev_err(&pdev->dev, "invalid DCR address\n");  			return -ENODEV;  		}  	}  #endif -	prop = of_get_property(op->dev.of_node, "phys-size", &size); +	prop = of_get_property(pdev->dev.of_node, "phys-size", &size);  	if ((prop) && (size >= sizeof(u32)*2)) {  		pdata.screen_width_mm = prop[0];  		pdata.screen_height_mm = prop[1];  	} -	prop = of_get_property(op->dev.of_node, "resolution", &size); +	prop = of_get_property(pdev->dev.of_node, "resolution", &size);  	if ((prop) && (size >= sizeof(u32)*2)) {  		pdata.xres = prop[0];  		pdata.yres = prop[1];  	} -	prop = of_get_property(op->dev.of_node, "virtual-resolution", &size); +	prop = of_get_property(pdev->dev.of_node, "virtual-resolution", &size);  	if ((prop) && (size >= sizeof(u32)*2)) {  		pdata.xvirt = prop[0];  		pdata.yvirt = prop[1];  	} -	if (of_find_property(op->dev.of_node, "rotate-display", NULL)) +	if (of_find_property(pdev->dev.of_node, "rotate-display", NULL))  		pdata.rotate_screen = 1; -	dev_set_drvdata(&op->dev, drvdata); -	return xilinxfb_assign(op, drvdata, &pdata); +	dev_set_drvdata(&pdev->dev, drvdata); +	return xilinxfb_assign(pdev, drvdata, &pdata);  }  static int xilinxfb_of_remove(struct platform_device *op) diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig index 39ac49e0682..0037104d66a 100644 --- a/drivers/video/logo/Kconfig +++ b/drivers/video/logo/Kconfig @@ -54,7 +54,7 @@ config LOGO_PARISC_CLUT224  config LOGO_SGI_CLUT224  	bool "224-color SGI Linux logo" -	depends on SGI_IP22 || SGI_IP27 || SGI_IP32 || X86_VISWS +	depends on SGI_IP22 || SGI_IP27 || SGI_IP32  	default y  config LOGO_SUN_CLUT224 diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c index 080c35b34bb..940cd196eef 100644 --- a/drivers/video/logo/logo.c +++ b/drivers/video/logo/logo.c @@ -17,10 +17,6 @@  #include <asm/setup.h>  #endif -#ifdef CONFIG_MIPS -#include <asm/bootinfo.h> -#endif -  static bool nologo;  module_param(nologo, bool, 0);  MODULE_PARM_DESC(nologo, "Disables startup logo"); @@ -85,7 +81,7 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)  		logo = &logo_parisc_clut224;  #endif  #ifdef CONFIG_LOGO_SGI_CLUT224 -		/* SGI Linux logo on MIPS/MIPS64 and VISWS */ +		/* SGI Linux logo on MIPS/MIPS64 */  		logo = &logo_sgi_clut224;  #endif  #ifdef CONFIG_LOGO_SUN_CLUT224 diff --git a/drivers/video/mbx/Makefile b/drivers/video/mbx/Makefile deleted file mode 100644 index 16c1165cf9c..00000000000 --- a/drivers/video/mbx/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# Makefile for the 2700G controller driver. - -obj-$(CONFIG_FB_MBX)	   += mbxfb.o -obj-$(CONFIG_FB_MBX_DEBUG) += mbxfbdebugfs.o diff --git a/drivers/video/mmp/Kconfig b/drivers/video/mmp/Kconfig deleted file mode 100644 index e9ea39e1372..00000000000 --- a/drivers/video/mmp/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -menuconfig MMP_DISP -        tristate "Marvell MMP Display Subsystem support" -        depends on CPU_PXA910 || CPU_MMP2 || CPU_MMP3 || CPU_PXA988 -        help -	  Marvell Display Subsystem support. - -if MMP_DISP -source "drivers/video/mmp/hw/Kconfig" -source "drivers/video/mmp/panel/Kconfig" -source "drivers/video/mmp/fb/Kconfig" -endif diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c index 171821ddd78..987edf11003 100644 --- a/drivers/video/of_display_timing.c +++ b/drivers/video/of_display_timing.c @@ -115,12 +115,10 @@ int of_get_display_timing(struct device_node *np, const char *name,  {  	struct device_node *timing_np; -	if (!np) { -		pr_err("%s: no devicenode given\n", of_node_full_name(np)); +	if (!np)  		return -EINVAL; -	} -	timing_np = of_find_node_by_name(np, name); +	timing_np = of_get_child_by_name(np, name);  	if (!timing_np) {  		pr_err("%s: could not find node '%s'\n",  			of_node_full_name(np), name); @@ -142,12 +140,10 @@ struct display_timings *of_get_display_timings(struct device_node *np)  	struct device_node *native_mode;  	struct display_timings *disp; -	if (!np) { -		pr_err("%s: no devicenode given\n", of_node_full_name(np)); +	if (!np)  		return NULL; -	} -	timings_np = of_find_node_by_name(np, "display-timings"); +	timings_np = of_get_child_by_name(np, "display-timings");  	if (!timings_np) {  		pr_err("%s: could not find display-timings node\n",  			of_node_full_name(np)); @@ -164,7 +160,7 @@ struct display_timings *of_get_display_timings(struct device_node *np)  	entry = of_parse_phandle(timings_np, "native-mode", 0);  	/* assume first child as native mode if none provided */  	if (!entry) -		entry = of_get_next_child(np, NULL); +		entry = of_get_next_child(timings_np, NULL);  	/* if there is no child, it is useless to go on */  	if (!entry) {  		pr_err("%s: no timing specifications given\n", diff --git a/drivers/video/omap/Makefile b/drivers/video/omap/Makefile deleted file mode 100644 index 1927faffb5b..00000000000 --- a/drivers/video/omap/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# -# Makefile for the OMAP1 framebuffer device driver -# - -obj-$(CONFIG_FB_OMAP) += omapfb.o - -objs-yy := omapfb_main.o lcdc.o - -objs-y$(CONFIG_FB_OMAP_LCDC_EXTERNAL) += sossi.o - -objs-y$(CONFIG_FB_OMAP_LCDC_HWA742) += hwa742.o - -objs-y$(CONFIG_MACH_AMS_DELTA) += lcd_ams_delta.o -objs-y$(CONFIG_MACH_OMAP_H3) += lcd_h3.o -objs-y$(CONFIG_MACH_OMAP_PALMTE) += lcd_palmte.o -objs-y$(CONFIG_MACH_OMAP_PALMTT) += lcd_palmtt.o -objs-y$(CONFIG_MACH_OMAP_PALMZ71) += lcd_palmz71.o -objs-$(CONFIG_ARCH_OMAP16XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1610.o -objs-$(CONFIG_ARCH_OMAP15XX)$(CONFIG_MACH_OMAP_INNOVATOR) += lcd_inn1510.o -objs-y$(CONFIG_MACH_OMAP_OSK) += lcd_osk.o - -objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o -objs-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o - -omapfb-objs := $(objs-yy) - diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig deleted file mode 100644 index 63b23f87081..00000000000 --- a/drivers/video/omap2/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -config OMAP2_VRFB -	bool - -if ARCH_OMAP2PLUS - -source "drivers/video/omap2/dss/Kconfig" -source "drivers/video/omap2/omapfb/Kconfig" -source "drivers/video/omap2/displays-new/Kconfig" - -endif diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c deleted file mode 100644 index 82a96407499..00000000000 --- a/drivers/video/omap2/dss/hdmi.c +++ /dev/null @@ -1,1184 +0,0 @@ -/* - * hdmi.c - * - * HDMI interface DSS driver setting for TI's OMAP4 family of processor. - * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ - * Authors: Yong Zhi - *	Mythri pk <mythripk@ti.com> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#define DSS_SUBSYS_NAME "HDMI" - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/interrupt.h> -#include <linux/mutex.h> -#include <linux/delay.h> -#include <linux/string.h> -#include <linux/platform_device.h> -#include <linux/pm_runtime.h> -#include <linux/clk.h> -#include <linux/gpio.h> -#include <linux/regulator/consumer.h> -#include <video/omapdss.h> - -#include "ti_hdmi.h" -#include "dss.h" -#include "dss_features.h" - -#define HDMI_WP			0x0 -#define HDMI_CORE_SYS		0x400 -#define HDMI_CORE_AV		0x900 -#define HDMI_PLLCTRL		0x200 -#define HDMI_PHY		0x300 - -/* HDMI EDID Length move this */ -#define HDMI_EDID_MAX_LENGTH			256 -#define EDID_TIMING_DESCRIPTOR_SIZE		0x12 -#define EDID_DESCRIPTOR_BLOCK0_ADDRESS		0x36 -#define EDID_DESCRIPTOR_BLOCK1_ADDRESS		0x80 -#define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR	4 -#define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR	4 - -#define HDMI_DEFAULT_REGN 16 -#define HDMI_DEFAULT_REGM2 1 - -static struct { -	struct mutex lock; -	struct platform_device *pdev; - -	struct hdmi_ip_data ip_data; - -	struct clk *sys_clk; -	struct regulator *vdda_hdmi_dac_reg; - -	bool core_enabled; - -	struct omap_dss_device output; -} hdmi; - -/* - * Logic for the below structure : - * user enters the CEA or VESA timings by specifying the HDMI/DVI code. - * There is a correspondence between CEA/VESA timing and code, please - * refer to section 6.3 in HDMI 1.3 specification for timing code. - * - * In the below structure, cea_vesa_timings corresponds to all OMAP4 - * supported CEA and VESA timing values.code_cea corresponds to the CEA - * code, It is used to get the timing from cea_vesa_timing array.Similarly - * with code_vesa. Code_index is used for back mapping, that is once EDID - * is read from the TV, EDID is parsed to find the timing values and then - * map it to corresponding CEA or VESA index. - */ - -static const struct hdmi_config cea_timings[] = { -	{ -		{ 640, 480, 25200, 96, 16, 48, 2, 10, 33, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -			false, }, -		{ 1, HDMI_HDMI }, -	}, -	{ -		{ 720, 480, 27027, 62, 16, 60, 6, 9, 30, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -			false, }, -		{ 2, HDMI_HDMI }, -	}, -	{ -		{ 1280, 720, 74250, 40, 110, 220, 5, 5, 20, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 4, HDMI_HDMI }, -	}, -	{ -		{ 1920, 540, 74250, 44, 88, 148, 5, 2, 15, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			true, }, -		{ 5, HDMI_HDMI }, -	}, -	{ -		{ 1440, 240, 27027, 124, 38, 114, 3, 4, 15, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -			true, }, -		{ 6, HDMI_HDMI }, -	}, -	{ -		{ 1920, 1080, 148500, 44, 88, 148, 5, 4, 36, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 16, HDMI_HDMI }, -	}, -	{ -		{ 720, 576, 27000, 64, 12, 68, 5, 5, 39, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -			false, }, -		{ 17, HDMI_HDMI }, -	}, -	{ -		{ 1280, 720, 74250, 40, 440, 220, 5, 5, 20, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 19, HDMI_HDMI }, -	}, -	{ -		{ 1920, 540, 74250, 44, 528, 148, 5, 2, 15, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			true, }, -		{ 20, HDMI_HDMI }, -	}, -	{ -		{ 1440, 288, 27000, 126, 24, 138, 3, 2, 19, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -			true, }, -		{ 21, HDMI_HDMI }, -	}, -	{ -		{ 1440, 576, 54000, 128, 24, 136, 5, 5, 39, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -			false, }, -		{ 29, HDMI_HDMI }, -	}, -	{ -		{ 1920, 1080, 148500, 44, 528, 148, 5, 4, 36, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 31, HDMI_HDMI }, -	}, -	{ -		{ 1920, 1080, 74250, 44, 638, 148, 5, 4, 36, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 32, HDMI_HDMI }, -	}, -	{ -		{ 2880, 480, 108108, 248, 64, 240, 6, 9, 30, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -			false, }, -		{ 35, HDMI_HDMI }, -	}, -	{ -		{ 2880, 576, 108000, 256, 48, 272, 5, 5, 39, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -			false, }, -		{ 37, HDMI_HDMI }, -	}, -}; - -static const struct hdmi_config vesa_timings[] = { -/* VESA From Here */ -	{ -		{ 640, 480, 25175, 96, 16, 48, 2, 11, 31, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -			false, }, -		{ 4, HDMI_DVI }, -	}, -	{ -		{ 800, 600, 40000, 128, 40, 88, 4, 1, 23, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 9, HDMI_DVI }, -	}, -	{ -		{ 848, 480, 33750, 112, 16, 112, 8, 6, 23, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 0xE, HDMI_DVI }, -	}, -	{ -		{ 1280, 768, 79500, 128, 64, 192, 7, 3, 20, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -			false, }, -		{ 0x17, HDMI_DVI }, -	}, -	{ -		{ 1280, 800, 83500, 128, 72, 200, 6, 3, 22, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -			false, }, -		{ 0x1C, HDMI_DVI }, -	}, -	{ -		{ 1360, 768, 85500, 112, 64, 256, 6, 3, 18, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 0x27, HDMI_DVI }, -	}, -	{ -		{ 1280, 960, 108000, 112, 96, 312, 3, 1, 36, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 0x20, HDMI_DVI }, -	}, -	{ -		{ 1280, 1024, 108000, 112, 48, 248, 3, 1, 38, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 0x23, HDMI_DVI }, -	}, -	{ -		{ 1024, 768, 65000, 136, 24, 160, 6, 3, 29, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW, -			false, }, -		{ 0x10, HDMI_DVI }, -	}, -	{ -		{ 1400, 1050, 121750, 144, 88, 232, 4, 3, 32, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -			false, }, -		{ 0x2A, HDMI_DVI }, -	}, -	{ -		{ 1440, 900, 106500, 152, 80, 232, 6, 3, 25, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -			false, }, -		{ 0x2F, HDMI_DVI }, -	}, -	{ -		{ 1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW, -			false, }, -		{ 0x3A, HDMI_DVI }, -	}, -	{ -		{ 1366, 768, 85500, 143, 70, 213, 3, 3, 24, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 0x51, HDMI_DVI }, -	}, -	{ -		{ 1920, 1080, 148500, 44, 148, 80, 5, 4, 36, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 0x52, HDMI_DVI }, -	}, -	{ -		{ 1280, 768, 68250, 32, 48, 80, 7, 3, 12, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 0x16, HDMI_DVI }, -	}, -	{ -		{ 1400, 1050, 101000, 32, 48, 80, 4, 3, 23, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 0x29, HDMI_DVI }, -	}, -	{ -		{ 1680, 1050, 119000, 32, 48, 80, 6, 3, 21, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 0x39, HDMI_DVI }, -	}, -	{ -		{ 1280, 800, 79500, 32, 48, 80, 6, 3, 14, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 0x1B, HDMI_DVI }, -	}, -	{ -		{ 1280, 720, 74250, 40, 110, 220, 5, 5, 20, -			OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 0x55, HDMI_DVI }, -	}, -	{ -		{ 1920, 1200, 154000, 32, 48, 80, 6, 3, 26, -			OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH, -			false, }, -		{ 0x44, HDMI_DVI }, -	}, -}; - -static int hdmi_runtime_get(void) -{ -	int r; - -	DSSDBG("hdmi_runtime_get\n"); - -	r = pm_runtime_get_sync(&hdmi.pdev->dev); -	WARN_ON(r < 0); -	if (r < 0) -		return r; - -	return 0; -} - -static void hdmi_runtime_put(void) -{ -	int r; - -	DSSDBG("hdmi_runtime_put\n"); - -	r = pm_runtime_put_sync(&hdmi.pdev->dev); -	WARN_ON(r < 0 && r != -ENOSYS); -} - -static int hdmi_init_regulator(void) -{ -	struct regulator *reg; - -	if (hdmi.vdda_hdmi_dac_reg != NULL) -		return 0; - -	reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac"); - -	/* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */ -	if (IS_ERR(reg)) -		reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC"); - -	if (IS_ERR(reg)) { -		DSSERR("can't get VDDA_HDMI_DAC regulator\n"); -		return PTR_ERR(reg); -	} - -	hdmi.vdda_hdmi_dac_reg = reg; - -	return 0; -} - -static const struct hdmi_config *hdmi_find_timing( -					const struct hdmi_config *timings_arr, -					int len) -{ -	int i; - -	for (i = 0; i < len; i++) { -		if (timings_arr[i].cm.code == hdmi.ip_data.cfg.cm.code) -			return &timings_arr[i]; -	} -	return NULL; -} - -static const struct hdmi_config *hdmi_get_timings(void) -{ -       const struct hdmi_config *arr; -       int len; - -       if (hdmi.ip_data.cfg.cm.mode == HDMI_DVI) { -               arr = vesa_timings; -               len = ARRAY_SIZE(vesa_timings); -       } else { -               arr = cea_timings; -               len = ARRAY_SIZE(cea_timings); -       } - -       return hdmi_find_timing(arr, len); -} - -static bool hdmi_timings_compare(struct omap_video_timings *timing1, -				const struct omap_video_timings *timing2) -{ -	int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; - -	if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) == -			DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) && -		(timing2->x_res == timing1->x_res) && -		(timing2->y_res == timing1->y_res)) { - -		timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp; -		timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp; -		timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp; -		timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp; - -		DSSDBG("timing1_hsync = %d timing1_vsync = %d"\ -			"timing2_hsync = %d timing2_vsync = %d\n", -			timing1_hsync, timing1_vsync, -			timing2_hsync, timing2_vsync); - -		if ((timing1_hsync == timing2_hsync) && -			(timing1_vsync == timing2_vsync)) { -			return true; -		} -	} -	return false; -} - -static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) -{ -	int i; -	struct hdmi_cm cm = {-1}; -	DSSDBG("hdmi_get_code\n"); - -	for (i = 0; i < ARRAY_SIZE(cea_timings); i++) { -		if (hdmi_timings_compare(timing, &cea_timings[i].timings)) { -			cm = cea_timings[i].cm; -			goto end; -		} -	} -	for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) { -		if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) { -			cm = vesa_timings[i].cm; -			goto end; -		} -	} - -end:	return cm; - -} - -static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, -		struct hdmi_pll_info *pi) -{ -	unsigned long clkin, refclk; -	u32 mf; - -	clkin = clk_get_rate(hdmi.sys_clk) / 10000; -	/* -	 * Input clock is predivided by N + 1 -	 * out put of which is reference clk -	 */ - -	pi->regn = HDMI_DEFAULT_REGN; - -	refclk = clkin / pi->regn; - -	pi->regm2 = HDMI_DEFAULT_REGM2; - -	/* -	 * multiplier is pixel_clk/ref_clk -	 * Multiplying by 100 to avoid fractional part removal -	 */ -	pi->regm = phy * pi->regm2 / refclk; - -	/* -	 * fractional multiplier is remainder of the difference between -	 * multiplier and actual phy(required pixel clock thus should be -	 * multiplied by 2^18(262144) divided by the reference clock -	 */ -	mf = (phy - pi->regm / pi->regm2 * refclk) * 262144; -	pi->regmf = pi->regm2 * mf / refclk; - -	/* -	 * Dcofreq should be set to 1 if required pixel clock -	 * is greater than 1000MHz -	 */ -	pi->dcofreq = phy > 1000 * 100; -	pi->regsd = ((pi->regm * clkin / 10) / (pi->regn * 250) + 5) / 10; - -	/* Set the reference clock to sysclk reference */ -	pi->refsel = HDMI_REFSEL_SYSCLK; - -	DSSDBG("M = %d Mf = %d\n", pi->regm, pi->regmf); -	DSSDBG("range = %d sd = %d\n", pi->dcofreq, pi->regsd); -} - -static int hdmi_power_on_core(struct omap_dss_device *dssdev) -{ -	int r; - -	r = regulator_enable(hdmi.vdda_hdmi_dac_reg); -	if (r) -		return r; - -	r = hdmi_runtime_get(); -	if (r) -		goto err_runtime_get; - -	/* Make selection of HDMI in DSS */ -	dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK); - -	hdmi.core_enabled = true; - -	return 0; - -err_runtime_get: -	regulator_disable(hdmi.vdda_hdmi_dac_reg); - -	return r; -} - -static void hdmi_power_off_core(struct omap_dss_device *dssdev) -{ -	hdmi.core_enabled = false; - -	hdmi_runtime_put(); -	regulator_disable(hdmi.vdda_hdmi_dac_reg); -} - -static int hdmi_power_on_full(struct omap_dss_device *dssdev) -{ -	int r; -	struct omap_video_timings *p; -	struct omap_overlay_manager *mgr = hdmi.output.manager; -	unsigned long phy; - -	r = hdmi_power_on_core(dssdev); -	if (r) -		return r; - -	dss_mgr_disable(mgr); - -	p = &hdmi.ip_data.cfg.timings; - -	DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res); - -	phy = p->pixel_clock; - -	hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); - -	hdmi.ip_data.ops->video_disable(&hdmi.ip_data); - -	/* config the PLL and PHY hdmi_set_pll_pwrfirst */ -	r = hdmi.ip_data.ops->pll_enable(&hdmi.ip_data); -	if (r) { -		DSSDBG("Failed to lock PLL\n"); -		goto err_pll_enable; -	} - -	r = hdmi.ip_data.ops->phy_enable(&hdmi.ip_data); -	if (r) { -		DSSDBG("Failed to start PHY\n"); -		goto err_phy_enable; -	} - -	hdmi.ip_data.ops->video_configure(&hdmi.ip_data); - -	/* bypass TV gamma table */ -	dispc_enable_gamma_table(0); - -	/* tv size */ -	dss_mgr_set_timings(mgr, p); - -	r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data); -	if (r) -		goto err_vid_enable; - -	r = dss_mgr_enable(mgr); -	if (r) -		goto err_mgr_enable; - -	return 0; - -err_mgr_enable: -	hdmi.ip_data.ops->video_disable(&hdmi.ip_data); -err_vid_enable: -	hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); -err_phy_enable: -	hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); -err_pll_enable: -	hdmi_power_off_core(dssdev); -	return -EIO; -} - -static void hdmi_power_off_full(struct omap_dss_device *dssdev) -{ -	struct omap_overlay_manager *mgr = hdmi.output.manager; - -	dss_mgr_disable(mgr); - -	hdmi.ip_data.ops->video_disable(&hdmi.ip_data); -	hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); -	hdmi.ip_data.ops->pll_disable(&hdmi.ip_data); - -	hdmi_power_off_core(dssdev); -} - -static int hdmi_display_check_timing(struct omap_dss_device *dssdev, -					struct omap_video_timings *timings) -{ -	struct hdmi_cm cm; - -	cm = hdmi_get_code(timings); -	if (cm.code == -1) { -		return -EINVAL; -	} - -	return 0; - -} - -static void hdmi_display_set_timing(struct omap_dss_device *dssdev, -		struct omap_video_timings *timings) -{ -	struct hdmi_cm cm; -	const struct hdmi_config *t; - -	mutex_lock(&hdmi.lock); - -	cm = hdmi_get_code(timings); -	hdmi.ip_data.cfg.cm = cm; - -	t = hdmi_get_timings(); -	if (t != NULL) { -		hdmi.ip_data.cfg = *t; - -		dispc_set_tv_pclk(t->timings.pixel_clock * 1000); -	} - -	mutex_unlock(&hdmi.lock); -} - -static void hdmi_display_get_timings(struct omap_dss_device *dssdev, -		struct omap_video_timings *timings) -{ -	const struct hdmi_config *cfg; - -	cfg = hdmi_get_timings(); -	if (cfg == NULL) -		cfg = &vesa_timings[0]; - -	memcpy(timings, &cfg->timings, sizeof(cfg->timings)); -} - -static void hdmi_dump_regs(struct seq_file *s) -{ -	mutex_lock(&hdmi.lock); - -	if (hdmi_runtime_get()) { -		mutex_unlock(&hdmi.lock); -		return; -	} - -	hdmi.ip_data.ops->dump_wrapper(&hdmi.ip_data, s); -	hdmi.ip_data.ops->dump_pll(&hdmi.ip_data, s); -	hdmi.ip_data.ops->dump_phy(&hdmi.ip_data, s); -	hdmi.ip_data.ops->dump_core(&hdmi.ip_data, s); - -	hdmi_runtime_put(); -	mutex_unlock(&hdmi.lock); -} - -static int read_edid(u8 *buf, int len) -{ -	int r; - -	mutex_lock(&hdmi.lock); - -	r = hdmi_runtime_get(); -	BUG_ON(r); - -	r = hdmi.ip_data.ops->read_edid(&hdmi.ip_data, buf, len); - -	hdmi_runtime_put(); -	mutex_unlock(&hdmi.lock); - -	return r; -} - -static int hdmi_display_enable(struct omap_dss_device *dssdev) -{ -	struct omap_dss_device *out = &hdmi.output; -	int r = 0; - -	DSSDBG("ENTER hdmi_display_enable\n"); - -	mutex_lock(&hdmi.lock); - -	if (out == NULL || out->manager == NULL) { -		DSSERR("failed to enable display: no output/manager\n"); -		r = -ENODEV; -		goto err0; -	} - -	r = hdmi_power_on_full(dssdev); -	if (r) { -		DSSERR("failed to power on device\n"); -		goto err0; -	} - -	mutex_unlock(&hdmi.lock); -	return 0; - -err0: -	mutex_unlock(&hdmi.lock); -	return r; -} - -static void hdmi_display_disable(struct omap_dss_device *dssdev) -{ -	DSSDBG("Enter hdmi_display_disable\n"); - -	mutex_lock(&hdmi.lock); - -	hdmi_power_off_full(dssdev); - -	mutex_unlock(&hdmi.lock); -} - -static int hdmi_core_enable(struct omap_dss_device *dssdev) -{ -	int r = 0; - -	DSSDBG("ENTER omapdss_hdmi_core_enable\n"); - -	mutex_lock(&hdmi.lock); - -	r = hdmi_power_on_core(dssdev); -	if (r) { -		DSSERR("failed to power on device\n"); -		goto err0; -	} - -	mutex_unlock(&hdmi.lock); -	return 0; - -err0: -	mutex_unlock(&hdmi.lock); -	return r; -} - -static void hdmi_core_disable(struct omap_dss_device *dssdev) -{ -	DSSDBG("Enter omapdss_hdmi_core_disable\n"); - -	mutex_lock(&hdmi.lock); - -	hdmi_power_off_core(dssdev); - -	mutex_unlock(&hdmi.lock); -} - -static int hdmi_get_clocks(struct platform_device *pdev) -{ -	struct clk *clk; - -	clk = devm_clk_get(&pdev->dev, "sys_clk"); -	if (IS_ERR(clk)) { -		DSSERR("can't get sys_clk\n"); -		return PTR_ERR(clk); -	} - -	hdmi.sys_clk = clk; - -	return 0; -} - -#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts) -{ -	u32 deep_color; -	bool deep_color_correct = false; -	u32 pclk = hdmi.ip_data.cfg.timings.pixel_clock; - -	if (n == NULL || cts == NULL) -		return -EINVAL; - -	/* TODO: When implemented, query deep color mode here. */ -	deep_color = 100; - -	/* -	 * When using deep color, the default N value (as in the HDMI -	 * specification) yields to an non-integer CTS. Hence, we -	 * modify it while keeping the restrictions described in -	 * section 7.2.1 of the HDMI 1.4a specification. -	 */ -	switch (sample_freq) { -	case 32000: -	case 48000: -	case 96000: -	case 192000: -		if (deep_color == 125) -			if (pclk == 27027 || pclk == 74250) -				deep_color_correct = true; -		if (deep_color == 150) -			if (pclk == 27027) -				deep_color_correct = true; -		break; -	case 44100: -	case 88200: -	case 176400: -		if (deep_color == 125) -			if (pclk == 27027) -				deep_color_correct = true; -		break; -	default: -		return -EINVAL; -	} - -	if (deep_color_correct) { -		switch (sample_freq) { -		case 32000: -			*n = 8192; -			break; -		case 44100: -			*n = 12544; -			break; -		case 48000: -			*n = 8192; -			break; -		case 88200: -			*n = 25088; -			break; -		case 96000: -			*n = 16384; -			break; -		case 176400: -			*n = 50176; -			break; -		case 192000: -			*n = 32768; -			break; -		default: -			return -EINVAL; -		} -	} else { -		switch (sample_freq) { -		case 32000: -			*n = 4096; -			break; -		case 44100: -			*n = 6272; -			break; -		case 48000: -			*n = 6144; -			break; -		case 88200: -			*n = 12544; -			break; -		case 96000: -			*n = 12288; -			break; -		case 176400: -			*n = 25088; -			break; -		case 192000: -			*n = 24576; -			break; -		default: -			return -EINVAL; -		} -	} -	/* Calculate CTS. See HDMI 1.3a or 1.4a specifications */ -	*cts = pclk * (*n / 128) * deep_color / (sample_freq / 10); - -	return 0; -} - -static bool hdmi_mode_has_audio(void) -{ -	if (hdmi.ip_data.cfg.cm.mode == HDMI_HDMI) -		return true; -	else -		return false; -} - -#endif - -static int hdmi_connect(struct omap_dss_device *dssdev, -		struct omap_dss_device *dst) -{ -	struct omap_overlay_manager *mgr; -	int r; - -	dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version()); - -	r = hdmi_init_regulator(); -	if (r) -		return r; - -	mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel); -	if (!mgr) -		return -ENODEV; - -	r = dss_mgr_connect(mgr, dssdev); -	if (r) -		return r; - -	r = omapdss_output_set_device(dssdev, dst); -	if (r) { -		DSSERR("failed to connect output to new device: %s\n", -				dst->name); -		dss_mgr_disconnect(mgr, dssdev); -		return r; -	} - -	return 0; -} - -static void hdmi_disconnect(struct omap_dss_device *dssdev, -		struct omap_dss_device *dst) -{ -	WARN_ON(dst != dssdev->dst); - -	if (dst != dssdev->dst) -		return; - -	omapdss_output_unset_device(dssdev); - -	if (dssdev->manager) -		dss_mgr_disconnect(dssdev->manager, dssdev); -} - -static int hdmi_read_edid(struct omap_dss_device *dssdev, -		u8 *edid, int len) -{ -	bool need_enable; -	int r; - -	need_enable = hdmi.core_enabled == false; - -	if (need_enable) { -		r = hdmi_core_enable(dssdev); -		if (r) -			return r; -	} - -	r = read_edid(edid, len); - -	if (need_enable) -		hdmi_core_disable(dssdev); - -	return r; -} - -#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -static int hdmi_audio_enable(struct omap_dss_device *dssdev) -{ -	int r; - -	mutex_lock(&hdmi.lock); - -	if (!hdmi_mode_has_audio()) { -		r = -EPERM; -		goto err; -	} - - -	r = hdmi.ip_data.ops->audio_enable(&hdmi.ip_data); -	if (r) -		goto err; - -	mutex_unlock(&hdmi.lock); -	return 0; - -err: -	mutex_unlock(&hdmi.lock); -	return r; -} - -static void hdmi_audio_disable(struct omap_dss_device *dssdev) -{ -	hdmi.ip_data.ops->audio_disable(&hdmi.ip_data); -} - -static int hdmi_audio_start(struct omap_dss_device *dssdev) -{ -	return hdmi.ip_data.ops->audio_start(&hdmi.ip_data); -} - -static void hdmi_audio_stop(struct omap_dss_device *dssdev) -{ -	hdmi.ip_data.ops->audio_stop(&hdmi.ip_data); -} - -static bool hdmi_audio_supported(struct omap_dss_device *dssdev) -{ -	bool r; - -	mutex_lock(&hdmi.lock); - -	r = hdmi_mode_has_audio(); - -	mutex_unlock(&hdmi.lock); -	return r; -} - -static int hdmi_audio_config(struct omap_dss_device *dssdev, -		struct omap_dss_audio *audio) -{ -	int r; - -	mutex_lock(&hdmi.lock); - -	if (!hdmi_mode_has_audio()) { -		r = -EPERM; -		goto err; -	} - -	r = hdmi.ip_data.ops->audio_config(&hdmi.ip_data, audio); -	if (r) -		goto err; - -	mutex_unlock(&hdmi.lock); -	return 0; - -err: -	mutex_unlock(&hdmi.lock); -	return r; -} -#else -static int hdmi_audio_enable(struct omap_dss_device *dssdev) -{ -	return -EPERM; -} - -static void hdmi_audio_disable(struct omap_dss_device *dssdev) -{ -} - -static int hdmi_audio_start(struct omap_dss_device *dssdev) -{ -	return -EPERM; -} - -static void hdmi_audio_stop(struct omap_dss_device *dssdev) -{ -} - -static bool hdmi_audio_supported(struct omap_dss_device *dssdev) -{ -	return false; -} - -static int hdmi_audio_config(struct omap_dss_device *dssdev, -		struct omap_dss_audio *audio) -{ -	return -EPERM; -} -#endif - -static const struct omapdss_hdmi_ops hdmi_ops = { -	.connect		= hdmi_connect, -	.disconnect		= hdmi_disconnect, - -	.enable			= hdmi_display_enable, -	.disable		= hdmi_display_disable, - -	.check_timings		= hdmi_display_check_timing, -	.set_timings		= hdmi_display_set_timing, -	.get_timings		= hdmi_display_get_timings, - -	.read_edid		= hdmi_read_edid, - -	.audio_enable		= hdmi_audio_enable, -	.audio_disable		= hdmi_audio_disable, -	.audio_start		= hdmi_audio_start, -	.audio_stop		= hdmi_audio_stop, -	.audio_supported	= hdmi_audio_supported, -	.audio_config		= hdmi_audio_config, -}; - -static void hdmi_init_output(struct platform_device *pdev) -{ -	struct omap_dss_device *out = &hdmi.output; - -	out->dev = &pdev->dev; -	out->id = OMAP_DSS_OUTPUT_HDMI; -	out->output_type = OMAP_DISPLAY_TYPE_HDMI; -	out->name = "hdmi.0"; -	out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT; -	out->ops.hdmi = &hdmi_ops; -	out->owner = THIS_MODULE; - -	omapdss_register_output(out); -} - -static void __exit hdmi_uninit_output(struct platform_device *pdev) -{ -	struct omap_dss_device *out = &hdmi.output; - -	omapdss_unregister_output(out); -} - -/* HDMI HW IP initialisation */ -static int omapdss_hdmihw_probe(struct platform_device *pdev) -{ -	struct resource *res; -	int r; - -	hdmi.pdev = pdev; - -	mutex_init(&hdmi.lock); -	mutex_init(&hdmi.ip_data.lock); - -	res = platform_get_resource(hdmi.pdev, IORESOURCE_MEM, 0); - -	/* Base address taken from platform */ -	hdmi.ip_data.base_wp = devm_ioremap_resource(&pdev->dev, res); -	if (IS_ERR(hdmi.ip_data.base_wp)) -		return PTR_ERR(hdmi.ip_data.base_wp); - -	hdmi.ip_data.irq = platform_get_irq(pdev, 0); -	if (hdmi.ip_data.irq < 0) { -		DSSERR("platform_get_irq failed\n"); -		return -ENODEV; -	} - -	r = hdmi_get_clocks(pdev); -	if (r) { -		DSSERR("can't get clocks\n"); -		return r; -	} - -	pm_runtime_enable(&pdev->dev); - -	hdmi.ip_data.core_sys_offset = HDMI_CORE_SYS; -	hdmi.ip_data.core_av_offset = HDMI_CORE_AV; -	hdmi.ip_data.pll_offset = HDMI_PLLCTRL; -	hdmi.ip_data.phy_offset = HDMI_PHY; - -	hdmi_init_output(pdev); - -	dss_debugfs_create_file("hdmi", hdmi_dump_regs); - -	return 0; -} - -static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) -{ -	hdmi_uninit_output(pdev); - -	pm_runtime_disable(&pdev->dev); - -	return 0; -} - -static int hdmi_runtime_suspend(struct device *dev) -{ -	clk_disable_unprepare(hdmi.sys_clk); - -	dispc_runtime_put(); - -	return 0; -} - -static int hdmi_runtime_resume(struct device *dev) -{ -	int r; - -	r = dispc_runtime_get(); -	if (r < 0) -		return r; - -	clk_prepare_enable(hdmi.sys_clk); - -	return 0; -} - -static const struct dev_pm_ops hdmi_pm_ops = { -	.runtime_suspend = hdmi_runtime_suspend, -	.runtime_resume = hdmi_runtime_resume, -}; - -static struct platform_driver omapdss_hdmihw_driver = { -	.probe		= omapdss_hdmihw_probe, -	.remove         = __exit_p(omapdss_hdmihw_remove), -	.driver         = { -		.name   = "omapdss_hdmi", -		.owner  = THIS_MODULE, -		.pm	= &hdmi_pm_ops, -	}, -}; - -int __init hdmi_init_platform_driver(void) -{ -	return platform_driver_register(&omapdss_hdmihw_driver); -} - -void __exit hdmi_uninit_platform_driver(void) -{ -	platform_driver_unregister(&omapdss_hdmihw_driver); -} diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h deleted file mode 100644 index 45215f44617..00000000000 --- a/drivers/video/omap2/dss/ti_hdmi.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * ti_hdmi.h - * - * HDMI driver definition for TI OMAP4, DM81xx, DM38xx  Processor. - * - * Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com/ - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef _TI_HDMI_H -#define _TI_HDMI_H - -struct hdmi_ip_data; - -enum hdmi_pll_pwr { -	HDMI_PLLPWRCMD_ALLOFF = 0, -	HDMI_PLLPWRCMD_PLLONLY = 1, -	HDMI_PLLPWRCMD_BOTHON_ALLCLKS = 2, -	HDMI_PLLPWRCMD_BOTHON_NOPHYCLK = 3 -}; - -enum hdmi_core_hdmi_dvi { -	HDMI_DVI = 0, -	HDMI_HDMI = 1 -}; - -enum hdmi_clk_refsel { -	HDMI_REFSEL_PCLK = 0, -	HDMI_REFSEL_REF1 = 1, -	HDMI_REFSEL_REF2 = 2, -	HDMI_REFSEL_SYSCLK = 3 -}; - -struct hdmi_cm { -	int	code; -	int	mode; -}; - -struct hdmi_config { -	struct omap_video_timings timings; -	struct hdmi_cm cm; -}; - -/* HDMI PLL structure */ -struct hdmi_pll_info { -	u16 regn; -	u16 regm; -	u32 regmf; -	u16 regm2; -	u16 regsd; -	u16 dcofreq; -	enum hdmi_clk_refsel refsel; -}; - -struct ti_hdmi_ip_ops { - -	void (*video_configure)(struct hdmi_ip_data *ip_data); - -	int (*phy_enable)(struct hdmi_ip_data *ip_data); - -	void (*phy_disable)(struct hdmi_ip_data *ip_data); - -	int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len); - -	int (*pll_enable)(struct hdmi_ip_data *ip_data); - -	void (*pll_disable)(struct hdmi_ip_data *ip_data); - -	int (*video_enable)(struct hdmi_ip_data *ip_data); - -	void (*video_disable)(struct hdmi_ip_data *ip_data); - -	void (*dump_wrapper)(struct hdmi_ip_data *ip_data, struct seq_file *s); - -	void (*dump_core)(struct hdmi_ip_data *ip_data, struct seq_file *s); - -	void (*dump_pll)(struct hdmi_ip_data *ip_data, struct seq_file *s); - -	void (*dump_phy)(struct hdmi_ip_data *ip_data, struct seq_file *s); - -#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -	int (*audio_enable)(struct hdmi_ip_data *ip_data); - -	void (*audio_disable)(struct hdmi_ip_data *ip_data); - -	int (*audio_start)(struct hdmi_ip_data *ip_data); - -	void (*audio_stop)(struct hdmi_ip_data *ip_data); - -	int (*audio_config)(struct hdmi_ip_data *ip_data, -		struct omap_dss_audio *audio); - -	int (*audio_get_dma_port)(u32 *offset, u32 *size); -#endif - -}; - -/* - * Refer to section 8.2 in HDMI 1.3 specification for - * details about infoframe databytes - */ -struct hdmi_core_infoframe_avi { -	/* Y0, Y1 rgb,yCbCr */ -	u8	db1_format; -	/* A0  Active information Present */ -	u8	db1_active_info; -	/* B0, B1 Bar info data valid */ -	u8	db1_bar_info_dv; -	/* S0, S1 scan information */ -	u8	db1_scan_info; -	/* C0, C1 colorimetry */ -	u8	db2_colorimetry; -	/* M0, M1 Aspect ratio (4:3, 16:9) */ -	u8	db2_aspect_ratio; -	/* R0...R3 Active format aspect ratio */ -	u8	db2_active_fmt_ar; -	/* ITC IT content. */ -	u8	db3_itc; -	/* EC0, EC1, EC2 Extended colorimetry */ -	u8	db3_ec; -	/* Q1, Q0 Quantization range */ -	u8	db3_q_range; -	/* SC1, SC0 Non-uniform picture scaling */ -	u8	db3_nup_scaling; -	/* VIC0..6 Video format identification */ -	u8	db4_videocode; -	/* PR0..PR3 Pixel repetition factor */ -	u8	db5_pixel_repeat; -	/* Line number end of top bar */ -	u16	db6_7_line_eoftop; -	/* Line number start of bottom bar */ -	u16	db8_9_line_sofbottom; -	/* Pixel number end of left bar */ -	u16	db10_11_pixel_eofleft; -	/* Pixel number start of right bar */ -	u16	db12_13_pixel_sofright; -}; - -struct hdmi_ip_data { -	void __iomem	*base_wp;	/* HDMI wrapper */ -	unsigned long	core_sys_offset; -	unsigned long	core_av_offset; -	unsigned long	pll_offset; -	unsigned long	phy_offset; -	int		irq; -	const struct ti_hdmi_ip_ops *ops; -	struct hdmi_config cfg; -	struct hdmi_pll_info pll_data; -	struct hdmi_core_infoframe_avi avi_cfg; - -	/* ti_hdmi_4xxx_ip private data. These should be in a separate struct */ -	struct mutex lock; -}; -int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data); -void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data); -int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len); -int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data); -void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data); -int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data); -void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data); -void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data); -void ti_hdmi_4xxx_wp_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); -void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); -void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); -void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s); -#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) -int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts); -int ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data); -void ti_hdmi_4xxx_wp_audio_disable(struct hdmi_ip_data *ip_data); -int ti_hdmi_4xxx_audio_start(struct hdmi_ip_data *ip_data); -void ti_hdmi_4xxx_audio_stop(struct hdmi_ip_data *ip_data); -int ti_hdmi_4xxx_audio_config(struct hdmi_ip_data *ip_data, -		struct omap_dss_audio *audio); -int ti_hdmi_4xxx_audio_get_dma_port(u32 *offset, u32 *size); -#endif -#endif diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c deleted file mode 100644 index f7d92c57bd7..00000000000 --- a/drivers/video/omap2/dss/venc_panel.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (C) 2009 Nokia Corporation - * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> - * - * VENC panel driver - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program.  If not, see <http://www.gnu.org/licenses/>. - */ - -#include <linux/kernel.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/mutex.h> -#include <linux/module.h> - -#include <video/omapdss.h> - -#include "dss.h" - -static struct { -	struct mutex lock; -} venc_panel; - -static ssize_t display_output_type_show(struct device *dev, -		struct device_attribute *attr, char *buf) -{ -	struct omap_dss_device *dssdev = to_dss_device(dev); -	const char *ret; - -	switch (dssdev->phy.venc.type) { -	case OMAP_DSS_VENC_TYPE_COMPOSITE: -		ret = "composite"; -		break; -	case OMAP_DSS_VENC_TYPE_SVIDEO: -		ret = "svideo"; -		break; -	default: -		return -EINVAL; -	} - -	return snprintf(buf, PAGE_SIZE, "%s\n", ret); -} - -static ssize_t display_output_type_store(struct device *dev, -		struct device_attribute *attr, const char *buf, size_t size) -{ -	struct omap_dss_device *dssdev = to_dss_device(dev); -	enum omap_dss_venc_type new_type; - -	if (sysfs_streq("composite", buf)) -		new_type = OMAP_DSS_VENC_TYPE_COMPOSITE; -	else if (sysfs_streq("svideo", buf)) -		new_type = OMAP_DSS_VENC_TYPE_SVIDEO; -	else -		return -EINVAL; - -	mutex_lock(&venc_panel.lock); - -	if (dssdev->phy.venc.type != new_type) { -		dssdev->phy.venc.type = new_type; -		omapdss_venc_set_type(dssdev, new_type); -		if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { -			omapdss_venc_display_disable(dssdev); -			omapdss_venc_display_enable(dssdev); -		} -	} - -	mutex_unlock(&venc_panel.lock); - -	return size; -} - -static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR, -		display_output_type_show, display_output_type_store); - -static int venc_panel_probe(struct omap_dss_device *dssdev) -{ -	/* set default timings to PAL */ -	const struct omap_video_timings default_timings = { -		.x_res		= 720, -		.y_res		= 574, -		.pixel_clock	= 13500, -		.hsw		= 64, -		.hfp		= 12, -		.hbp		= 68, -		.vsw		= 5, -		.vfp		= 5, -		.vbp		= 41, - -		.vsync_level	= OMAPDSS_SIG_ACTIVE_HIGH, -		.hsync_level	= OMAPDSS_SIG_ACTIVE_HIGH, - -		.interlace	= true, -	}; - -	mutex_init(&venc_panel.lock); - -	dssdev->panel.timings = default_timings; - -	return device_create_file(dssdev->dev, &dev_attr_output_type); -} - -static void venc_panel_remove(struct omap_dss_device *dssdev) -{ -	device_remove_file(dssdev->dev, &dev_attr_output_type); -} - -static int venc_panel_enable(struct omap_dss_device *dssdev) -{ -	int r; - -	dev_dbg(dssdev->dev, "venc_panel_enable\n"); - -	mutex_lock(&venc_panel.lock); - -	if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) { -		r = -EINVAL; -		goto err; -	} - -	omapdss_venc_set_timings(dssdev, &dssdev->panel.timings); -	omapdss_venc_set_type(dssdev, dssdev->phy.venc.type); -	omapdss_venc_invert_vid_out_polarity(dssdev, -		dssdev->phy.venc.invert_polarity); - -	r = omapdss_venc_display_enable(dssdev); -	if (r) -		goto err; - -	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; - -	mutex_unlock(&venc_panel.lock); - -	return 0; -err: -	mutex_unlock(&venc_panel.lock); - -	return r; -} - -static void venc_panel_disable(struct omap_dss_device *dssdev) -{ -	dev_dbg(dssdev->dev, "venc_panel_disable\n"); - -	mutex_lock(&venc_panel.lock); - -	if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED) -		goto end; - -	omapdss_venc_display_disable(dssdev); - -	dssdev->state = OMAP_DSS_DISPLAY_DISABLED; -end: -	mutex_unlock(&venc_panel.lock); -} - -static void venc_panel_set_timings(struct omap_dss_device *dssdev, -		struct omap_video_timings *timings) -{ -	dev_dbg(dssdev->dev, "venc_panel_set_timings\n"); - -	mutex_lock(&venc_panel.lock); - -	omapdss_venc_set_timings(dssdev, timings); -	dssdev->panel.timings = *timings; - -	mutex_unlock(&venc_panel.lock); -} - -static int venc_panel_check_timings(struct omap_dss_device *dssdev, -		struct omap_video_timings *timings) -{ -	dev_dbg(dssdev->dev, "venc_panel_check_timings\n"); - -	return omapdss_venc_check_timings(dssdev, timings); -} - -static u32 venc_panel_get_wss(struct omap_dss_device *dssdev) -{ -	dev_dbg(dssdev->dev, "venc_panel_get_wss\n"); - -	return omapdss_venc_get_wss(dssdev); -} - -static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss) -{ -	dev_dbg(dssdev->dev, "venc_panel_set_wss\n"); - -	return omapdss_venc_set_wss(dssdev, wss); -} - -static struct omap_dss_driver venc_driver = { -	.probe		= venc_panel_probe, -	.remove		= venc_panel_remove, - -	.enable		= venc_panel_enable, -	.disable	= venc_panel_disable, - -	.get_resolution	= omapdss_default_get_resolution, -	.get_recommended_bpp = omapdss_default_get_recommended_bpp, - -	.set_timings	= venc_panel_set_timings, -	.check_timings	= venc_panel_check_timings, - -	.get_wss	= venc_panel_get_wss, -	.set_wss	= venc_panel_set_wss, - -	.driver         = { -		.name   = "venc", -		.owner  = THIS_MODULE, -	}, -}; - -int venc_panel_init(void) -{ -	return omap_dss_register_driver(&venc_driver); -} - -void venc_panel_exit(void) -{ -	omap_dss_unregister_driver(&venc_driver); -} diff --git a/drivers/video/output.c b/drivers/video/output.c deleted file mode 100644 index 1446c49fe6a..00000000000 --- a/drivers/video/output.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - *  output.c - Display Output Switch driver - * - *  Copyright (C) 2006 Luming Yu <luming.yu@intel.com> - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - *  This program is free software; you can redistribute it and/or modify - *  it under the terms of the GNU General Public License as published by - *  the Free Software Foundation; either version 2 of the License, or (at - *  your option) any later version. - * - *  This program is distributed in the hope that it will be useful, but - *  WITHOUT ANY WARRANTY; without even the implied warranty of - *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU - *  General Public License for more details. - * - *  You should have received a copy of the GNU General Public License along - *  with this program; if not, write to the Free Software Foundation, Inc., - *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ -#include <linux/module.h> -#include <linux/video_output.h> -#include <linux/slab.h> -#include <linux/err.h> -#include <linux/ctype.h> - - -MODULE_DESCRIPTION("Display Output Switcher Lowlevel Control Abstraction"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Luming Yu <luming.yu@intel.com>"); - -static ssize_t state_show(struct device *dev, struct device_attribute *attr, -			  char *buf) -{ -	ssize_t ret_size = 0; -	struct output_device *od = to_output_device(dev); -	if (od->props) -		ret_size = sprintf(buf,"%.8x\n",od->props->get_status(od)); -	return ret_size; -} - -static ssize_t state_store(struct device *dev, struct device_attribute *attr, -			   const char *buf,size_t count) -{ -	char *endp; -	struct output_device *od = to_output_device(dev); -	int request_state = simple_strtoul(buf,&endp,0); -	size_t size = endp - buf; - -	if (isspace(*endp)) -		size++; -	if (size != count) -		return -EINVAL; - -	if (od->props) { -		od->request_state = request_state; -		od->props->set_state(od); -	} -	return count; -} -static DEVICE_ATTR_RW(state); - -static void video_output_release(struct device *dev) -{ -	struct output_device *od = to_output_device(dev); -	kfree(od); -} - -static struct attribute *video_output_attrs[] = { -	&dev_attr_state.attr, -	NULL, -}; -ATTRIBUTE_GROUPS(video_output); - -static struct class video_output_class = { -	.name = "video_output", -	.dev_release = video_output_release, -	.dev_groups = video_output_groups, -}; - -struct output_device *video_output_register(const char *name, -	struct device *dev, -	void *devdata, -	struct output_properties *op) -{ -	struct output_device *new_dev; -	int ret_code = 0; - -	new_dev = kzalloc(sizeof(struct output_device),GFP_KERNEL); -	if (!new_dev) { -		ret_code = -ENOMEM; -		goto error_return; -	} -	new_dev->props = op; -	new_dev->dev.class = &video_output_class; -	new_dev->dev.parent = dev; -	dev_set_name(&new_dev->dev, "%s", name); -	dev_set_drvdata(&new_dev->dev, devdata); -	ret_code = device_register(&new_dev->dev); -	if (ret_code) { -		kfree(new_dev); -		goto error_return; -	} -	return new_dev; - -error_return: -	return ERR_PTR(ret_code); -} -EXPORT_SYMBOL(video_output_register); - -void video_output_unregister(struct output_device *dev) -{ -	if (!dev) -		return; -	device_unregister(&dev->dev); -} -EXPORT_SYMBOL(video_output_unregister); - -static void __exit video_output_class_exit(void) -{ -	class_unregister(&video_output_class); -} - -static int __init video_output_class_init(void) -{ -	return class_register(&video_output_class); -} - -postcore_initcall(video_output_class_init); -module_exit(video_output_class_exit); diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c deleted file mode 100644 index a9ac3ce2d0e..00000000000 --- a/drivers/video/sgivwfb.c +++ /dev/null @@ -1,889 +0,0 @@ -/* - *  linux/drivers/video/sgivwfb.c -- SGI DBE frame buffer device - * - *	Copyright (C) 1999 Silicon Graphics, Inc. - *      Jeffrey Newquist, newquist@engr.sgi.som - * - *  This file is subject to the terms and conditions of the GNU General Public - *  License. See the file COPYING in the main directory of this archive for - *  more details. - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/mm.h> -#include <linux/errno.h> -#include <linux/delay.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/ioport.h> -#include <linux/platform_device.h> - -#include <asm/io.h> -#include <asm/mtrr.h> -#include <asm/visws/sgivw.h> - -#define INCLUDE_TIMING_TABLE_DATA -#define DBE_REG_BASE par->regs -#include <video/sgivw.h> - -struct sgivw_par { -	struct asregs *regs; -	u32 cmap_fifo; -	u_long timing_num; -}; - -#define FLATPANEL_SGI_1600SW	5 - -/* - *  RAM we reserve for the frame buffer. This defines the maximum screen - *  size - * - *  The default can be overridden if the driver is compiled as a module - */ - -static int ypan = 0; -static int ywrap = 0; - -static int flatpanel_id = -1; - -static struct fb_fix_screeninfo sgivwfb_fix = { -	.id		= "SGI Vis WS FB", -	.type		= FB_TYPE_PACKED_PIXELS, -        .visual		= FB_VISUAL_PSEUDOCOLOR, -	.mmio_start	= DBE_REG_PHYS, -	.mmio_len	= DBE_REG_SIZE, -        .accel		= FB_ACCEL_NONE, -	.line_length	= 640, -}; - -static struct fb_var_screeninfo sgivwfb_var = { -	/* 640x480, 8 bpp */ -	.xres		= 640, -	.yres		= 480, -	.xres_virtual	= 640, -	.yres_virtual	= 480, -	.bits_per_pixel	= 8, -	.red		= { 0, 8, 0 }, -	.green		= { 0, 8, 0 }, -	.blue		= { 0, 8, 0 }, -	.height		= -1, -	.width		= -1, -	.pixclock	= 20000, -	.left_margin	= 64, -	.right_margin	= 64, -	.upper_margin	= 32, -	.lower_margin	= 32, -	.hsync_len	= 64, -	.vsync_len	= 2, -	.vmode		= FB_VMODE_NONINTERLACED -}; - -static struct fb_var_screeninfo sgivwfb_var1600sw = { -	/* 1600x1024, 8 bpp */ -	.xres		= 1600, -	.yres		= 1024, -	.xres_virtual	= 1600, -	.yres_virtual	= 1024, -	.bits_per_pixel	= 8, -	.red		= { 0, 8, 0 }, -	.green		= { 0, 8, 0 }, -	.blue		= { 0, 8, 0 }, -	.height		= -1, -	.width		= -1, -	.pixclock	= 9353, -	.left_margin	= 20, -	.right_margin	= 30, -	.upper_margin	= 37, -	.lower_margin	= 3, -	.hsync_len	= 20, -	.vsync_len	= 3, -	.vmode		= FB_VMODE_NONINTERLACED -}; - -/* - *  Interface used by the world - */ -int sgivwfb_init(void); - -static int sgivwfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info); -static int sgivwfb_set_par(struct fb_info *info); -static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green, -			     u_int blue, u_int transp, -			     struct fb_info *info); -static int sgivwfb_mmap(struct fb_info *info, -			struct vm_area_struct *vma); - -static struct fb_ops sgivwfb_ops = { -	.owner		= THIS_MODULE, -	.fb_check_var	= sgivwfb_check_var, -	.fb_set_par	= sgivwfb_set_par, -	.fb_setcolreg	= sgivwfb_setcolreg, -	.fb_fillrect	= cfb_fillrect, -	.fb_copyarea	= cfb_copyarea, -	.fb_imageblit	= cfb_imageblit, -	.fb_mmap	= sgivwfb_mmap, -}; - -/* - *  Internal routines - */ -static unsigned long bytes_per_pixel(int bpp) -{ -	switch (bpp) { -		case 8: -			return 1; -		case 16: -			return 2; -		case 32: -			return 4; -		default: -			printk(KERN_INFO "sgivwfb: unsupported bpp %d\n", bpp); -			return 0; -	} -} - -static unsigned long get_line_length(int xres_virtual, int bpp) -{ -	return (xres_virtual * bytes_per_pixel(bpp)); -} - -/* - * Function:	dbe_TurnOffDma - * Parameters:	(None) - * Description:	This should turn off the monitor and dbe.  This is used - *              when switching between the serial console and the graphics - *              console. - */ - -static void dbe_TurnOffDma(struct sgivw_par *par) -{ -	unsigned int readVal; -	int i; - -	// Check to see if things are already turned off: -	// 1) Check to see if dbe is not using the internal dotclock. -	// 2) Check to see if the xy counter in dbe is already off. - -	DBE_GETREG(ctrlstat, readVal); -	if (GET_DBE_FIELD(CTRLSTAT, PCLKSEL, readVal) < 2) -		return; - -	DBE_GETREG(vt_xy, readVal); -	if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1) -		return; - -	// Otherwise, turn off dbe - -	DBE_GETREG(ovr_control, readVal); -	SET_DBE_FIELD(OVR_CONTROL, OVR_DMA_ENABLE, readVal, 0); -	DBE_SETREG(ovr_control, readVal); -	udelay(1000); -	DBE_GETREG(frm_control, readVal); -	SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, readVal, 0); -	DBE_SETREG(frm_control, readVal); -	udelay(1000); -	DBE_GETREG(did_control, readVal); -	SET_DBE_FIELD(DID_CONTROL, DID_DMA_ENABLE, readVal, 0); -	DBE_SETREG(did_control, readVal); -	udelay(1000); - -	// XXX HACK: -	// -	//    This was necessary for GBE--we had to wait through two -	//    vertical retrace periods before the pixel DMA was -	//    turned off for sure.  I've left this in for now, in -	//    case dbe needs it. - -	for (i = 0; i < 10000; i++) { -		DBE_GETREG(frm_inhwctrl, readVal); -		if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) == -		    0) -			udelay(10); -		else { -			DBE_GETREG(ovr_inhwctrl, readVal); -			if (GET_DBE_FIELD -			    (OVR_INHWCTRL, OVR_DMA_ENABLE, readVal) == 0) -				udelay(10); -			else { -				DBE_GETREG(did_inhwctrl, readVal); -				if (GET_DBE_FIELD -				    (DID_INHWCTRL, DID_DMA_ENABLE, -				     readVal) == 0) -					udelay(10); -				else -					break; -			} -		} -	} -} - -/* - *  Set the User Defined Part of the Display. Again if par use it to get - *  real video mode. - */ -static int sgivwfb_check_var(struct fb_var_screeninfo *var,  -			     struct fb_info *info) -{ -	struct sgivw_par *par = (struct sgivw_par *)info->par; -	struct dbe_timing_info *timing; -	u_long line_length; -	u_long min_mode; -	int req_dot; -	int test_mode; - -	/* -	 *  FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal! -	 *  as FB_VMODE_SMOOTH_XPAN is only used internally -	 */ - -	if (var->vmode & FB_VMODE_CONUPDATE) { -		var->vmode |= FB_VMODE_YWRAP; -		var->xoffset = info->var.xoffset; -		var->yoffset = info->var.yoffset; -	} - -	/* XXX FIXME - forcing var's */ -	var->xoffset = 0; -	var->yoffset = 0; - -	/* Limit bpp to 8, 16, and 32 */ -	if (var->bits_per_pixel <= 8) -		var->bits_per_pixel = 8; -	else if (var->bits_per_pixel <= 16) -		var->bits_per_pixel = 16; -	else if (var->bits_per_pixel <= 32) -		var->bits_per_pixel = 32; -	else -		return -EINVAL; - -	var->grayscale = 0;	/* No grayscale for now */ - -	/* determine valid resolution and timing */ -	for (min_mode = 0; min_mode < ARRAY_SIZE(dbeVTimings); min_mode++) { -		if (dbeVTimings[min_mode].width >= var->xres && -		    dbeVTimings[min_mode].height >= var->yres) -			break; -	} - -	if (min_mode == ARRAY_SIZE(dbeVTimings)) -		return -EINVAL;	/* Resolution to high */ - -	/* XXX FIXME - should try to pick best refresh rate */ -	/* for now, pick closest dot-clock within 3MHz */ -	req_dot = PICOS2KHZ(var->pixclock); -	printk(KERN_INFO "sgivwfb: requested pixclock=%d ps (%d KHz)\n", -	       var->pixclock, req_dot); -	test_mode = min_mode; -	while (dbeVTimings[min_mode].width == dbeVTimings[test_mode].width) { -		if (dbeVTimings[test_mode].cfreq + 3000 > req_dot) -			break; -		test_mode++; -	} -	if (dbeVTimings[min_mode].width != dbeVTimings[test_mode].width) -		test_mode--; -	min_mode = test_mode; -	timing = &dbeVTimings[min_mode]; -	printk(KERN_INFO "sgivwfb: granted dot-clock=%d KHz\n", timing->cfreq); - -	/* Adjust virtual resolution, if necessary */ -	if (var->xres > var->xres_virtual || (!ywrap && !ypan)) -		var->xres_virtual = var->xres; -	if (var->yres > var->yres_virtual || (!ywrap && !ypan)) -		var->yres_virtual = var->yres; - -	/* -	 *  Memory limit -	 */ -	line_length = get_line_length(var->xres_virtual, var->bits_per_pixel); -	if (line_length * var->yres_virtual > sgivwfb_mem_size) -		return -ENOMEM;	/* Virtual resolution to high */ - -	info->fix.line_length = line_length; - -	switch (var->bits_per_pixel) { -	case 8: -		var->red.offset = 0; -		var->red.length = 8; -		var->green.offset = 0; -		var->green.length = 8; -		var->blue.offset = 0; -		var->blue.length = 8; -		var->transp.offset = 0; -		var->transp.length = 0; -		break; -	case 16:		/* RGBA 5551 */ -		var->red.offset = 11; -		var->red.length = 5; -		var->green.offset = 6; -		var->green.length = 5; -		var->blue.offset = 1; -		var->blue.length = 5; -		var->transp.offset = 0; -		var->transp.length = 0; -		break; -	case 32:		/* RGB 8888 */ -		var->red.offset = 0; -		var->red.length = 8; -		var->green.offset = 8; -		var->green.length = 8; -		var->blue.offset = 16; -		var->blue.length = 8; -		var->transp.offset = 24; -		var->transp.length = 8; -		break; -	} -	var->red.msb_right = 0; -	var->green.msb_right = 0; -	var->blue.msb_right = 0; -	var->transp.msb_right = 0; - -	/* set video timing information */ -	var->pixclock = KHZ2PICOS(timing->cfreq); -	var->left_margin = timing->htotal - timing->hsync_end; -	var->right_margin = timing->hsync_start - timing->width; -	var->upper_margin = timing->vtotal - timing->vsync_end; -	var->lower_margin = timing->vsync_start - timing->height; -	var->hsync_len = timing->hsync_end - timing->hsync_start; -	var->vsync_len = timing->vsync_end - timing->vsync_start; - -	/* Ouch. This breaks the rules but timing_num is only important if you -	* change a video mode */ -	par->timing_num = min_mode; - -	printk(KERN_INFO "sgivwfb: new video mode xres=%d yres=%d bpp=%d\n", -		var->xres, var->yres, var->bits_per_pixel); -	printk(KERN_INFO "         vxres=%d vyres=%d\n", var->xres_virtual, -		var->yres_virtual); -	return 0; -} - -/* - *  Setup flatpanel related registers. - */ -static void sgivwfb_setup_flatpanel(struct sgivw_par *par, struct dbe_timing_info *currentTiming) -{ -	int fp_wid, fp_hgt, fp_vbs, fp_vbe; -	u32 outputVal = 0; - -	SET_DBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal,  -		(currentTiming->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1); -	SET_DBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal,  -		(currentTiming->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1); -	DBE_SETREG(vt_flags, outputVal); - -	/* Turn on the flat panel */ -	switch (flatpanel_id) { -		case FLATPANEL_SGI_1600SW: -			fp_wid = 1600; -			fp_hgt = 1024; -			fp_vbs = 0; -			fp_vbe = 1600; -			currentTiming->pll_m = 4; -			currentTiming->pll_n = 1; -			currentTiming->pll_p = 0; -			break; -		default: -      			fp_wid = fp_hgt = fp_vbs = fp_vbe = 0xfff; -  	} - -	outputVal = 0; -	SET_DBE_FIELD(FP_DE, FP_DE_ON, outputVal, fp_vbs); -	SET_DBE_FIELD(FP_DE, FP_DE_OFF, outputVal, fp_vbe); -	DBE_SETREG(fp_de, outputVal); -	outputVal = 0; -	SET_DBE_FIELD(FP_HDRV, FP_HDRV_OFF, outputVal, fp_wid); -	DBE_SETREG(fp_hdrv, outputVal); -	outputVal = 0; -	SET_DBE_FIELD(FP_VDRV, FP_VDRV_ON, outputVal, 1); -	SET_DBE_FIELD(FP_VDRV, FP_VDRV_OFF, outputVal, fp_hgt + 1); -	DBE_SETREG(fp_vdrv, outputVal); -} - -/* - *  Set the hardware according to 'par'. - */ -static int sgivwfb_set_par(struct fb_info *info) -{ -	struct sgivw_par *par = info->par; -	int i, j, htmp, temp; -	u32 readVal, outputVal; -	int wholeTilesX, maxPixelsPerTileX; -	int frmWrite1, frmWrite2, frmWrite3b; -	struct dbe_timing_info *currentTiming; /* Current Video Timing */ -	int xpmax, ypmax;	// Monitor resolution -	int bytesPerPixel;	// Bytes per pixel - -	currentTiming = &dbeVTimings[par->timing_num]; -	bytesPerPixel = bytes_per_pixel(info->var.bits_per_pixel); -	xpmax = currentTiming->width; -	ypmax = currentTiming->height; - -	/* dbe_InitGraphicsBase(); */ -	/* Turn on dotclock PLL */ -	DBE_SETREG(ctrlstat, 0x20000000); - -	dbe_TurnOffDma(par); - -	/* dbe_CalculateScreenParams(); */ -	maxPixelsPerTileX = 512 / bytesPerPixel; -	wholeTilesX = xpmax / maxPixelsPerTileX; -	if (wholeTilesX * maxPixelsPerTileX < xpmax) -		wholeTilesX++; - -	printk(KERN_DEBUG "sgivwfb: pixPerTile=%d wholeTilesX=%d\n", -	       maxPixelsPerTileX, wholeTilesX); - -	/* dbe_InitGammaMap(); */ -	udelay(10); - -	for (i = 0; i < 256; i++) { -		DBE_ISETREG(gmap, i, (i << 24) | (i << 16) | (i << 8)); -	} - -	/* dbe_TurnOn(); */ -	DBE_GETREG(vt_xy, readVal); -	if (GET_DBE_FIELD(VT_XY, VT_FREEZE, readVal) == 1) { -		DBE_SETREG(vt_xy, 0x00000000); -		udelay(1); -	} else -		dbe_TurnOffDma(par); - -	/* dbe_Initdbe(); */ -	for (i = 0; i < 256; i++) { -		for (j = 0; j < 100; j++) { -			DBE_GETREG(cm_fifo, readVal); -			if (readVal != 0x00000000) -				break; -			else -				udelay(10); -		} - -		// DBE_ISETREG(cmap, i, 0x00000000); -		DBE_ISETREG(cmap, i, (i << 8) | (i << 16) | (i << 24)); -	} - -	/* dbe_InitFramebuffer(); */ -	frmWrite1 = 0; -	SET_DBE_FIELD(FRM_SIZE_TILE, FRM_WIDTH_TILE, frmWrite1, -		      wholeTilesX); -	SET_DBE_FIELD(FRM_SIZE_TILE, FRM_RHS, frmWrite1, 0); - -	switch (bytesPerPixel) { -	case 1: -		SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1, -			      DBE_FRM_DEPTH_8); -		break; -	case 2: -		SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1, -			      DBE_FRM_DEPTH_16); -		break; -	case 4: -		SET_DBE_FIELD(FRM_SIZE_TILE, FRM_DEPTH, frmWrite1, -			      DBE_FRM_DEPTH_32); -		break; -	} - -	frmWrite2 = 0; -	SET_DBE_FIELD(FRM_SIZE_PIXEL, FB_HEIGHT_PIX, frmWrite2, ypmax); - -	// Tell dbe about the framebuffer location and type -	// XXX What format is the FRM_TILE_PTR??  64K aligned address? -	frmWrite3b = 0; -	SET_DBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, frmWrite3b, -		      sgivwfb_mem_phys >> 9); -	SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, frmWrite3b, 1); -	SET_DBE_FIELD(FRM_CONTROL, FRM_LINEAR, frmWrite3b, 1); - -	/* Initialize DIDs */ - -	outputVal = 0; -	switch (bytesPerPixel) { -	case 1: -		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_I8); -		break; -	case 2: -		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGBA5); -		break; -	case 4: -		SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGB8); -		break; -	} -	SET_DBE_FIELD(WID, BUF, outputVal, DBE_BMODE_BOTH); - -	for (i = 0; i < 32; i++) { -		DBE_ISETREG(mode_regs, i, outputVal); -	} - -	/* dbe_InitTiming(); */ -	DBE_SETREG(vt_intr01, 0xffffffff); -	DBE_SETREG(vt_intr23, 0xffffffff); - -	DBE_GETREG(dotclock, readVal); -	DBE_SETREG(dotclock, readVal & 0xffff); - -	DBE_SETREG(vt_xymax, 0x00000000); -	outputVal = 0; -	SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_ON, outputVal, -		      currentTiming->vsync_start); -	SET_DBE_FIELD(VT_VSYNC, VT_VSYNC_OFF, outputVal, -		      currentTiming->vsync_end); -	DBE_SETREG(vt_vsync, outputVal); -	outputVal = 0; -	SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_ON, outputVal, -		      currentTiming->hsync_start); -	SET_DBE_FIELD(VT_HSYNC, VT_HSYNC_OFF, outputVal, -		      currentTiming->hsync_end); -	DBE_SETREG(vt_hsync, outputVal); -	outputVal = 0; -	SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_ON, outputVal, -		      currentTiming->vblank_start); -	SET_DBE_FIELD(VT_VBLANK, VT_VBLANK_OFF, outputVal, -		      currentTiming->vblank_end); -	DBE_SETREG(vt_vblank, outputVal); -	outputVal = 0; -	SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_ON, outputVal, -		      currentTiming->hblank_start); -	SET_DBE_FIELD(VT_HBLANK, VT_HBLANK_OFF, outputVal, -		      currentTiming->hblank_end - 3); -	DBE_SETREG(vt_hblank, outputVal); -	outputVal = 0; -	SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_ON, outputVal, -		      currentTiming->vblank_start); -	SET_DBE_FIELD(VT_VCMAP, VT_VCMAP_OFF, outputVal, -		      currentTiming->vblank_end); -	DBE_SETREG(vt_vcmap, outputVal); -	outputVal = 0; -	SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_ON, outputVal, -		      currentTiming->hblank_start); -	SET_DBE_FIELD(VT_HCMAP, VT_HCMAP_OFF, outputVal, -		      currentTiming->hblank_end - 3); -	DBE_SETREG(vt_hcmap, outputVal); - -	if (flatpanel_id != -1) -		sgivwfb_setup_flatpanel(par, currentTiming); - -	outputVal = 0; -	temp = currentTiming->vblank_start - currentTiming->vblank_end - 1; -	if (temp > 0) -		temp = -temp; - -	SET_DBE_FIELD(DID_START_XY, DID_STARTY, outputVal, (u32) temp); -	if (currentTiming->hblank_end >= 20) -		SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal, -			      currentTiming->hblank_end - 20); -	else -		SET_DBE_FIELD(DID_START_XY, DID_STARTX, outputVal, -			      currentTiming->htotal - (20 - -						       currentTiming-> -						       hblank_end)); -	DBE_SETREG(did_start_xy, outputVal); - -	outputVal = 0; -	SET_DBE_FIELD(CRS_START_XY, CRS_STARTY, outputVal, -		      (u32) (temp + 1)); -	if (currentTiming->hblank_end >= DBE_CRS_MAGIC) -		SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal, -			      currentTiming->hblank_end - DBE_CRS_MAGIC); -	else -		SET_DBE_FIELD(CRS_START_XY, CRS_STARTX, outputVal, -			      currentTiming->htotal - (DBE_CRS_MAGIC - -						       currentTiming-> -						       hblank_end)); -	DBE_SETREG(crs_start_xy, outputVal); - -	outputVal = 0; -	SET_DBE_FIELD(VC_START_XY, VC_STARTY, outputVal, (u32) temp); -	SET_DBE_FIELD(VC_START_XY, VC_STARTX, outputVal, -		      currentTiming->hblank_end - 4); -	DBE_SETREG(vc_start_xy, outputVal); - -	DBE_SETREG(frm_size_tile, frmWrite1); -	DBE_SETREG(frm_size_pixel, frmWrite2); - -	outputVal = 0; -	SET_DBE_FIELD(DOTCLK, M, outputVal, currentTiming->pll_m - 1); -	SET_DBE_FIELD(DOTCLK, N, outputVal, currentTiming->pll_n - 1); -	SET_DBE_FIELD(DOTCLK, P, outputVal, currentTiming->pll_p); -	SET_DBE_FIELD(DOTCLK, RUN, outputVal, 1); -	DBE_SETREG(dotclock, outputVal); - -	udelay(11 * 1000); - -	DBE_SETREG(vt_vpixen, 0xffffff); -	DBE_SETREG(vt_hpixen, 0xffffff); - -	outputVal = 0; -	SET_DBE_FIELD(VT_XYMAX, VT_MAXX, outputVal, currentTiming->htotal); -	SET_DBE_FIELD(VT_XYMAX, VT_MAXY, outputVal, currentTiming->vtotal); -	DBE_SETREG(vt_xymax, outputVal); - -	outputVal = frmWrite1; -	SET_DBE_FIELD(FRM_SIZE_TILE, FRM_FIFO_RESET, outputVal, 1); -	DBE_SETREG(frm_size_tile, outputVal); -	DBE_SETREG(frm_size_tile, frmWrite1); - -	outputVal = 0; -	SET_DBE_FIELD(OVR_WIDTH_TILE, OVR_FIFO_RESET, outputVal, 1); -	DBE_SETREG(ovr_width_tile, outputVal); -	DBE_SETREG(ovr_width_tile, 0); - -	DBE_SETREG(frm_control, frmWrite3b); -	DBE_SETREG(did_control, 0); - -	// Wait for dbe to take frame settings -	for (i = 0; i < 100000; i++) { -		DBE_GETREG(frm_inhwctrl, readVal); -		if (GET_DBE_FIELD(FRM_INHWCTRL, FRM_DMA_ENABLE, readVal) != -		    0) -			break; -		else -			udelay(1); -	} - -	if (i == 100000) -		printk(KERN_INFO -		       "sgivwfb: timeout waiting for frame DMA enable.\n"); - -	outputVal = 0; -	htmp = currentTiming->hblank_end - 19; -	if (htmp < 0) -		htmp += currentTiming->htotal;	/* allow blank to wrap around */ -	SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_ON, outputVal, htmp); -	SET_DBE_FIELD(VT_HPIXEN, VT_HPIXEN_OFF, outputVal, -		      ((htmp + currentTiming->width - -			2) % currentTiming->htotal)); -	DBE_SETREG(vt_hpixen, outputVal); - -	outputVal = 0; -	SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_OFF, outputVal, -		      currentTiming->vblank_start); -	SET_DBE_FIELD(VT_VPIXEN, VT_VPIXEN_ON, outputVal, -		      currentTiming->vblank_end); -	DBE_SETREG(vt_vpixen, outputVal); - -	// Turn off mouse cursor -	par->regs->crs_ctl = 0; - -	// XXX What's this section for?? -	DBE_GETREG(ctrlstat, readVal); -	readVal &= 0x02000000; - -	if (readVal != 0) { -		DBE_SETREG(ctrlstat, 0x30000000); -	} -	return 0; -} - -/* - *  Set a single color register. The values supplied are already - *  rounded down to the hardware's capabilities (according to the - *  entries in the var structure). Return != 0 for invalid regno. - */ - -static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green, -			     u_int blue, u_int transp, -			     struct fb_info *info) -{ -	struct sgivw_par *par = (struct sgivw_par *) info->par; - -	if (regno > 255) -		return 1; -	red >>= 8; -	green >>= 8; -	blue >>= 8; - -	/* wait for the color map FIFO to have a free entry */ -	while (par->cmap_fifo == 0) -		par->cmap_fifo = par->regs->cm_fifo; - -	par->regs->cmap[regno] = (red << 24) | (green << 16) | (blue << 8); -	par->cmap_fifo--;	/* assume FIFO is filling up */ -	return 0; -} - -static int sgivwfb_mmap(struct fb_info *info, -			struct vm_area_struct *vma) -{ -	int r; - -	pgprot_val(vma->vm_page_prot) = -		pgprot_val(vma->vm_page_prot) | _PAGE_PCD; - -	r = vm_iomap_memory(vma, sgivwfb_mem_phys, sgivwfb_mem_size); - -	printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n", -		sgivwfb_mem_phys + (vma->vm_pgoff << PAGE_SHIFT), vma->vm_start); - -	return r; -} - -int __init sgivwfb_setup(char *options) -{ -	char *this_opt; - -	if (!options || !*options) -		return 0; - -	while ((this_opt = strsep(&options, ",")) != NULL) { -		if (!strncmp(this_opt, "monitor:", 8)) { -			if (!strncmp(this_opt + 8, "crt", 3)) -				flatpanel_id = -1; -			else if (!strncmp(this_opt + 8, "1600sw", 6)) -				flatpanel_id = FLATPANEL_SGI_1600SW; -		} -	} -	return 0; -} - -/* - *  Initialisation - */ -static int sgivwfb_probe(struct platform_device *dev) -{ -	struct sgivw_par *par; -	struct fb_info *info; -	char *monitor; - -	info = framebuffer_alloc(sizeof(struct sgivw_par) + sizeof(u32) * 16, &dev->dev); -	if (!info) -		return -ENOMEM; -	par = info->par; - -	if (!request_mem_region(DBE_REG_PHYS, DBE_REG_SIZE, "sgivwfb")) { -		printk(KERN_ERR "sgivwfb: couldn't reserve mmio region\n"); -		framebuffer_release(info); -		return -EBUSY; -	} - -	par->regs = (struct asregs *) ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE); -	if (!par->regs) { -		printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n"); -		goto fail_ioremap_regs; -	} - -	mtrr_add(sgivwfb_mem_phys, sgivwfb_mem_size, MTRR_TYPE_WRCOMB, 1); - -	sgivwfb_fix.smem_start = sgivwfb_mem_phys; -	sgivwfb_fix.smem_len = sgivwfb_mem_size; -	sgivwfb_fix.ywrapstep = ywrap; -	sgivwfb_fix.ypanstep = ypan; - -	info->fix = sgivwfb_fix; - -	switch (flatpanel_id) { -		case FLATPANEL_SGI_1600SW: -			info->var = sgivwfb_var1600sw; -			monitor = "SGI 1600SW flatpanel"; -			break; -		default: -			info->var = sgivwfb_var; -			monitor = "CRT"; -	} - -	printk(KERN_INFO "sgivwfb: %s monitor selected\n", monitor); - -	info->fbops = &sgivwfb_ops; -	info->pseudo_palette = (void *) (par + 1); -	info->flags = FBINFO_DEFAULT; - -	info->screen_base = ioremap_nocache((unsigned long) sgivwfb_mem_phys, sgivwfb_mem_size); -	if (!info->screen_base) { -		printk(KERN_ERR "sgivwfb: couldn't ioremap screen_base\n"); -		goto fail_ioremap_fbmem; -	} - -	if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) -		goto fail_color_map; - -	if (register_framebuffer(info) < 0) { -		printk(KERN_ERR "sgivwfb: couldn't register framebuffer\n"); -		goto fail_register_framebuffer; -	} - -	platform_set_drvdata(dev, info); - -	printk(KERN_INFO "fb%d: SGI DBE frame buffer device, using %ldK of video memory at %#lx\n",       -		info->node, sgivwfb_mem_size >> 10, sgivwfb_mem_phys); -	return 0; - -fail_register_framebuffer: -	fb_dealloc_cmap(&info->cmap); -fail_color_map: -	iounmap((char *) info->screen_base); -fail_ioremap_fbmem: -	iounmap(par->regs); -fail_ioremap_regs: -	release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE); -	framebuffer_release(info); -	return -ENXIO; -} - -static int sgivwfb_remove(struct platform_device *dev) -{ -	struct fb_info *info = platform_get_drvdata(dev); - -	if (info) { -		struct sgivw_par *par = info->par; - -		unregister_framebuffer(info); -		dbe_TurnOffDma(par); -		iounmap(par->regs); -		iounmap(info->screen_base); -		release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE); -		fb_dealloc_cmap(&info->cmap); -		framebuffer_release(info); -	} -	return 0; -} - -static struct platform_driver sgivwfb_driver = { -	.probe	= sgivwfb_probe, -	.remove	= sgivwfb_remove, -	.driver	= { -		.name	= "sgivwfb", -	}, -}; - -static struct platform_device *sgivwfb_device; - -int __init sgivwfb_init(void) -{ -	int ret; - -#ifndef MODULE -	char *option = NULL; - -	if (fb_get_options("sgivwfb", &option)) -		return -ENODEV; -	sgivwfb_setup(option); -#endif -	ret = platform_driver_register(&sgivwfb_driver); -	if (!ret) { -		sgivwfb_device = platform_device_alloc("sgivwfb", 0); -		if (sgivwfb_device) { -			ret = platform_device_add(sgivwfb_device); -		} else -			ret = -ENOMEM; -		if (ret) { -			platform_driver_unregister(&sgivwfb_driver); -			platform_device_put(sgivwfb_device); -		} -	} -	return ret; -} - -module_init(sgivwfb_init); - -#ifdef MODULE -MODULE_LICENSE("GPL"); - -static void __exit sgivwfb_exit(void) -{ -	platform_device_unregister(sgivwfb_device); -	platform_driver_unregister(&sgivwfb_driver); -} - -module_exit(sgivwfb_exit); - -#endif				/* MODULE */  | 
