aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig19
-rw-r--r--drivers/video/Makefile3
-rw-r--r--drivers/video/atmel_lcdfb.c8
-rw-r--r--drivers/video/aty/atyfb_base.c7
-rw-r--r--drivers/video/aty/mach64_accel.c3
-rw-r--r--drivers/video/aty/mach64_cursor.c22
-rw-r--r--drivers/video/backlight/aat2870_bl.c2
-rw-r--r--drivers/video/backlight/adp8860_bl.c4
-rw-r--r--drivers/video/backlight/adp8870_bl.c4
-rw-r--r--drivers/video/backlight/backlight.c30
-rw-r--r--drivers/video/backlight/corgi_lcd.c4
-rw-r--r--drivers/video/backlight/gpio_backlight.c58
-rw-r--r--drivers/video/backlight/hx8357.c4
-rw-r--r--drivers/video/backlight/ili922x.c4
-rw-r--r--drivers/video/backlight/ili9320.c4
-rw-r--r--drivers/video/backlight/l4f00242t03.c5
-rw-r--r--drivers/video/backlight/lm3533_bl.c5
-rw-r--r--drivers/video/backlight/lm3639_bl.c17
-rw-r--r--drivers/video/backlight/lms283gf05.c4
-rw-r--r--drivers/video/backlight/platform_lcd.c4
-rw-r--r--drivers/video/backlight/tps65217_bl.c5
-rw-r--r--drivers/video/cfbcopyarea.c153
-rw-r--r--drivers/video/console/fbcon.c27
-rw-r--r--drivers/video/da8xx-fb.c22
-rw-r--r--drivers/video/efifb.c13
-rw-r--r--drivers/video/exynos/Kconfig7
-rw-r--r--drivers/video/exynos/Makefile1
-rw-r--r--drivers/video/exynos/exynos_dp_core.c1156
-rw-r--r--drivers/video/exynos/exynos_dp_core.h320
-rw-r--r--drivers/video/exynos/exynos_dp_reg.c1243
-rw-r--r--drivers/video/exynos/exynos_dp_reg.h366
-rw-r--r--drivers/video/exynos/s6e8ax0.c13
-rw-r--r--drivers/video/fbmem.c3
-rw-r--r--drivers/video/gbefb.c4
-rw-r--r--drivers/video/hyperv_fb.c88
-rw-r--r--drivers/video/imxfb.c380
-rw-r--r--drivers/video/logo/Kconfig2
-rw-r--r--drivers/video/logo/logo.c2
-rw-r--r--drivers/video/matrox/matroxfb_accel.c38
-rw-r--r--drivers/video/matrox/matroxfb_base.c3
-rw-r--r--drivers/video/matrox/matroxfb_base.h2
-rw-r--r--drivers/video/omap2/displays-new/connector-analog-tv.c45
-rw-r--r--drivers/video/omap2/displays-new/connector-dvi.c45
-rw-r--r--drivers/video/omap2/displays-new/connector-hdmi.c32
-rw-r--r--drivers/video/omap2/displays-new/encoder-tfp410.c43
-rw-r--r--drivers/video/omap2/displays-new/encoder-tpd12s015.c56
-rw-r--r--drivers/video/omap2/displays-new/panel-dsi-cm.c62
-rw-r--r--drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c2
-rw-r--r--drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c4
-rw-r--r--drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c2
-rw-r--r--drivers/video/omap2/displays-new/panel-sony-acx565akm.c35
-rw-r--r--drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c2
-rw-r--r--drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c2
-rw-r--r--drivers/video/omap2/dss/Makefile2
-rw-r--r--drivers/video/omap2/dss/dispc.c40
-rw-r--r--drivers/video/omap2/dss/display-sysfs.c4
-rw-r--r--drivers/video/omap2/dss/display.c32
-rw-r--r--drivers/video/omap2/dss/dpi.c72
-rw-r--r--drivers/video/omap2/dss/dsi.c163
-rw-r--r--drivers/video/omap2/dss/dss-of.c159
-rw-r--r--drivers/video/omap2/dss/dss.c82
-rw-r--r--drivers/video/omap2/dss/dss.h8
-rw-r--r--drivers/video/omap2/dss/hdmi4.c23
-rw-r--r--drivers/video/omap2/dss/hdmi_common.c74
-rw-r--r--drivers/video/omap2/dss/hdmi_wp.c2
-rw-r--r--drivers/video/omap2/dss/sdi.c60
-rw-r--r--drivers/video/omap2/dss/venc.c70
-rw-r--r--drivers/video/omap2/dss/venc_panel.c2
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c75
-rw-r--r--drivers/video/output.c133
-rw-r--r--drivers/video/pxa3xx-gcu.c191
-rw-r--r--drivers/video/sgivwfb.c889
-rw-r--r--drivers/video/sis/init.c1
-rw-r--r--drivers/video/tgafb.c288
-rw-r--r--drivers/video/uvesafb.c19
-rw-r--r--drivers/video/vesafb.c13
-rw-r--r--drivers/video/xilinxfb.c15
77 files changed, 1715 insertions, 5091 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index dade5b7699bc..6c793bc683d9 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -27,12 +27,6 @@ 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
@@ -802,18 +796,9 @@ config FB_HGA
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)
+ depends on (FB = y) && SGI_IP32
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
@@ -982,7 +967,7 @@ config FB_PVR2
config FB_OPENCORES
tristate "OpenCores VGA/LCD core 2.0 framebuffer support"
- depends on FB
+ depends on FB && HAS_DMA
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index ae17ddf49a00..1be26fe10592 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -75,7 +75,6 @@ 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
@@ -172,8 +171,6 @@ obj-$(CONFIG_FB_SIMPLE) += simplefb.o
# the test framebuffer is last
obj-$(CONFIG_FB_VIRTUAL) += vfb.o
-#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/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index cd961622f9c1..e683b6ef9594 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -1190,12 +1190,12 @@ static int __init atmel_lcdfb_probe(struct platform_device *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;
info->fix = atmel_lcdfb_fix;
+ strcpy(info->fix.id, sinfo->pdev->name);
/* Enable LCDC Clocks */
sinfo->bus_clk = clk_get(dev, "hclk");
@@ -1298,6 +1298,12 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev)
goto unregister_irqs;
}
+ 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);
/*
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 28fafbf864a5..c3d0074a32db 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/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;
@@ -2653,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/aty/mach64_accel.c
index e45833ce975b..182bd680141f 100644
--- a/drivers/video/aty/mach64_accel.c
+++ b/drivers/video/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_cursor.c b/drivers/video/aty/mach64_cursor.c
index 95ec042ddbf8..0fe02e22d9a4 100644
--- a/drivers/video/aty/mach64_cursor.c
+++ b/drivers/video/aty/mach64_cursor.c
@@ -5,6 +5,7 @@
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/string.h>
+#include "../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/backlight/aat2870_bl.c b/drivers/video/backlight/aat2870_bl.c
index ee0c0a982e4e..ec5350f2c28a 100644
--- a/drivers/video/backlight/aat2870_bl.c
+++ b/drivers/video/backlight/aat2870_bl.c
@@ -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;
}
diff --git a/drivers/video/backlight/adp8860_bl.c b/drivers/video/backlight/adp8860_bl.c
index 9d656717d0f7..be8d83deca7d 100644
--- a/drivers/video/backlight/adp8860_bl.c
+++ b/drivers/video/backlight/adp8860_bl.c
@@ -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,
diff --git a/drivers/video/backlight/adp8870_bl.c b/drivers/video/backlight/adp8870_bl.c
index 63707205326b..251af4d38d86 100644
--- a/drivers/video/backlight/adp8870_bl.c
+++ b/drivers/video/backlight/adp8870_bl.c
@@ -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)
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 5d05555fe841..bd2172c2d650 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -34,13 +34,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)
@@ -51,12 +53,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;
@@ -333,7 +347,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);
}
diff --git a/drivers/video/backlight/corgi_lcd.c b/drivers/video/backlight/corgi_lcd.c
index db8db5fa6583..51d18d637e2b 100644
--- a/drivers/video/backlight/corgi_lcd.c
+++ b/drivers/video/backlight/corgi_lcd.c
@@ -543,10 +543,8 @@ 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;
diff --git a/drivers/video/backlight/gpio_backlight.c b/drivers/video/backlight/gpio_backlight.c
index 81fb12770c2a..a2eba12e1cb7 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)
@@ -60,6 +63,29 @@ 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 =
@@ -67,10 +93,12 @@ static int gpio_backlight_probe(struct platform_device *pdev)
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;
}
@@ -79,14 +107,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;
@@ -103,17 +139,25 @@ static int gpio_backlight_probe(struct platform_device *pdev)
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;
}
+#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,
};
diff --git a/drivers/video/backlight/hx8357.c b/drivers/video/backlight/hx8357.c
index 985e854e244b..23f50b92a930 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) {
diff --git a/drivers/video/backlight/ili922x.c b/drivers/video/backlight/ili922x.c
index 73464e4b4c74..ea67fe199e34 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);
diff --git a/drivers/video/backlight/ili9320.c b/drivers/video/backlight/ili9320.c
index e2b8b40a9bd9..2cf39e6d519d 100644
--- a/drivers/video/backlight/ili9320.c
+++ b/drivers/video/backlight/ili9320.c
@@ -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);
diff --git a/drivers/video/backlight/l4f00242t03.c b/drivers/video/backlight/l4f00242t03.c
index 63e763828e0e..5fa2649c9631 100644
--- a/drivers/video/backlight/l4f00242t03.c
+++ b/drivers/video/backlight/l4f00242t03.c
@@ -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;
diff --git a/drivers/video/backlight/lm3533_bl.c b/drivers/video/backlight/lm3533_bl.c
index 187d1c283c1d..cff1fbe89a1b 100644
--- a/drivers/video/backlight/lm3533_bl.c
+++ b/drivers/video/backlight/lm3533_bl.c
@@ -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;
diff --git a/drivers/video/backlight/lm3639_bl.c b/drivers/video/backlight/lm3639_bl.c
index 6fd60adf922e..5f36808d214f 100644
--- a/drivers/video/backlight/lm3639_bl.c
+++ b/drivers/video/backlight/lm3639_bl.c
@@ -349,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);
@@ -360,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 */
@@ -391,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;
}
@@ -407,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;
}
@@ -432,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 de8832504f68..14590c54aedf 100644
--- a/drivers/video/backlight/lms283gf05.c
+++ b/drivers/video/backlight/lms283gf05.c
@@ -168,10 +168,8 @@ 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 = devm_lcd_device_register(&spi->dev, "lms283gf05", &spi->dev, st,
&lms_ops);
diff --git a/drivers/video/backlight/platform_lcd.c b/drivers/video/backlight/platform_lcd.c
index d01884d4f1bf..c3d2e209fc8f 100644
--- a/drivers/video/backlight/platform_lcd.c
+++ b/drivers/video/backlight/platform_lcd.c
@@ -94,10 +94,8 @@ 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;
diff --git a/drivers/video/backlight/tps65217_bl.c b/drivers/video/backlight/tps65217_bl.c
index cbba37e6836e..595dcf561020 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;
}
@@ -296,10 +295,8 @@ static int tps65217_bl_probe(struct platform_device *pdev)
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;
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index bb5a96b1645d..bcb57235fcc7 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/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/console/fbcon.c b/drivers/video/console/fbcon.c
index 4e39291ac8b4..f447734b09b4 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -759,7 +759,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 +3028,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;
}
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c
index a1d74dd11988..0c0ba920ea48 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/da8xx-fb.c
@@ -1546,7 +1546,7 @@ err_pm_runtime_disable:
return ret;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static struct lcdc_context {
u32 clk_enable;
u32 ctrl;
@@ -1610,9 +1610,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();
@@ -1622,18 +1622,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();
@@ -1647,19 +1647,17 @@ 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,
},
};
module_platform_driver(da8xx_fb_driver);
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index cd7c0df9f24b..ae9618ff6735 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/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 = {
@@ -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;
@@ -337,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/exynos/Kconfig b/drivers/video/exynos/Kconfig
index 75c8a8e7efc0..fcf2d48ac6d1 100644
--- a/drivers/video/exynos/Kconfig
+++ b/drivers/video/exynos/Kconfig
@@ -29,11 +29,4 @@ config EXYNOS_LCD_S6E8AX0
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 OF && ARCH_EXYNOS
- default n
- help
- This enables support for DP device.
-
endif # EXYNOS_VIDEO
diff --git a/drivers/video/exynos/Makefile b/drivers/video/exynos/Makefile
index ec7772e452a9..b5b1bd228abb 100644
--- a/drivers/video/exynos/Makefile
+++ b/drivers/video/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_dp_core.c b/drivers/video/exynos/exynos_dp_core.c
deleted file mode 100644
index 5e1a71580051..000000000000
--- a/drivers/video/exynos/exynos_dp_core.c
+++ /dev/null
@@ -1,1156 +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 <linux/phy/phy.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, &reg);
- 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, &reg);
- 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");
-}
-
-static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
-{
- struct device_node *dp_node = dev->of_node;
- struct video_info *dp_video_config;
-
- 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);
- }
-
- 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 dp_video_config;
-}
-
-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) {
- dp->phy = devm_phy_get(dp->dev, "dp");
- if (IS_ERR(dp->phy))
- return PTR_ERR(dp->phy);
- else
- return 0;
- }
-
- 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)
-{
- if (dp->phy) {
- phy_power_on(dp->phy);
- } else if (dp->phy_addr) {
- 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)
-{
- if (dp->phy) {
- phy_power_off(dp->phy);
- } else if (dp->phy_addr) {
- u32 reg;
-
- reg = __raw_readl(dp->phy_addr);
- reg &= ~(dp->enable_mask);
- __raw_writel(reg, dp->phy_addr);
- }
-}
-
-static int exynos_dp_probe(struct platform_device *pdev)
-{
- struct resource *res;
- struct exynos_dp_device *dp;
-
- 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;
-
- dp->video_info = exynos_dp_dt_parse_pdata(&pdev->dev);
- if (IS_ERR(dp->video_info))
- return PTR_ERR(dp->video_info);
-
- ret = exynos_dp_dt_parse_phydata(dp);
- if (ret)
- return ret;
-
- 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);
-
- exynos_dp_phy_init(dp);
-
- 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_device *dp = platform_get_drvdata(pdev);
-
- flush_work(&dp->hotplug_work);
-
- exynos_dp_phy_exit(dp);
-
- clk_disable_unprepare(dp->clock);
-
-
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int exynos_dp_suspend(struct device *dev)
-{
- struct exynos_dp_device *dp = dev_get_drvdata(dev);
-
- disable_irq(dp->irq);
-
- flush_work(&dp->hotplug_work);
-
- exynos_dp_phy_exit(dp);
-
- clk_disable_unprepare(dp->clock);
-
- return 0;
-}
-
-static int exynos_dp_resume(struct device *dev)
-{
- struct exynos_dp_device *dp = dev_get_drvdata(dev);
-
- exynos_dp_phy_init(dp);
-
- 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 = 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 607e36d0c147..000000000000
--- a/drivers/video/exynos/exynos_dp_core.h
+++ /dev/null
@@ -1,320 +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
-
-#define DP_TIMEOUT_LOOP_COUNT 100
-#define MAX_CR_LOOP 5
-#define MAX_EQ_LOOP 5
-
-enum link_rate_type {
- LINK_RATE_1_62GBPS = 0x06,
- LINK_RATE_2_70GBPS = 0x0a
-};
-
-enum link_lane_count_type {
- LANE_COUNT1 = 1,
- LANE_COUNT2 = 2,
- LANE_COUNT4 = 4
-};
-
-enum link_training_state {
- START,
- CLOCK_RECOVERY,
- EQUALIZER_TRAINING,
- FINISHED,
- FAILED
-};
-
-enum voltage_swing_level {
- VOLTAGE_LEVEL_0,
- VOLTAGE_LEVEL_1,
- VOLTAGE_LEVEL_2,
- VOLTAGE_LEVEL_3,
-};
-
-enum pre_emphasis_level {
- PRE_EMPHASIS_LEVEL_0,
- PRE_EMPHASIS_LEVEL_1,
- PRE_EMPHASIS_LEVEL_2,
- PRE_EMPHASIS_LEVEL_3,
-};
-
-enum pattern_set {
- PRBS7,
- D10_2,
- TRAINING_PTN1,
- TRAINING_PTN2,
- DP_NONE
-};
-
-enum color_space {
- COLOR_RGB,
- COLOR_YCBCR422,
- COLOR_YCBCR444
-};
-
-enum color_depth {
- COLOR_6,
- COLOR_8,
- COLOR_10,
- COLOR_12
-};
-
-enum color_coefficient {
- COLOR_YCBCR601,
- COLOR_YCBCR709
-};
-
-enum dynamic_range {
- VESA,
- CEA
-};
-
-enum pll_status {
- PLL_UNLOCKED,
- PLL_LOCKED
-};
-
-enum clock_recovery_m_value_type {
- CALCULATED_M,
- REGISTER_M
-};
-
-enum video_timing_recognition_type {
- VIDEO_TIMING_FROM_CAPTURE,
- VIDEO_TIMING_FROM_REGISTER
-};
-
-enum analog_power_block {
- AUX_BLOCK,
- CH0_BLOCK,
- CH1_BLOCK,
- CH2_BLOCK,
- CH3_BLOCK,
- ANALOG_TOTAL,
- POWER_ALL
-};
-
-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 video_info {
- char *name;
-
- bool h_sync_polarity;
- bool v_sync_polarity;
- bool interlaced;
-
- enum color_space color_space;
- enum dynamic_range dynamic_range;
- enum color_coefficient ycbcr_coeff;
- enum color_depth color_depth;
-
- enum link_rate_type link_rate;
- enum link_lane_count_type lane_count;
-};
-
-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;
- struct phy *phy;
-};
-
-/* 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 b70da5052ff0..000000000000
--- a/drivers/video/exynos/exynos_dp_reg.c
+++ /dev/null
@@ -1,1243 +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 "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 2e9bd0e0b9f2..000000000000
--- 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/exynos/s6e8ax0.c b/drivers/video/exynos/s6e8ax0.c
index ca2602413aa4..29e70ed3f154 100644
--- a/drivers/video/exynos/s6e8ax0.c
+++ b/drivers/video/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/fbmem.c b/drivers/video/fbmem.c
index 7309ac704e26..b6d5008f361f 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1596,8 +1596,7 @@ static int 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);
ret = do_unregister_framebuffer(registered_fb[i]);
if (ret)
diff --git a/drivers/video/gbefb.c b/drivers/video/gbefb.c
index 4c7cb368a9dc..3ec65a878ac8 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/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
diff --git a/drivers/video/hyperv_fb.c b/drivers/video/hyperv_fb.c
index 130708f96430..e23392ec5af3 100644
--- a/drivers/video/hyperv_fb.c
+++ b/drivers/video/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;
@@ -627,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;
@@ -654,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);
}
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index 44ee678481d5..f6e621684953 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/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,37 +622,6 @@ 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 = dev_get_platdata(&pdev->dev);
@@ -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;
@@ -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,9 +1016,6 @@ 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 = dev_get_platdata(&pdev->dev);
@@ -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/logo/Kconfig b/drivers/video/logo/Kconfig
index 39ac49e0682c..0037104d66ac 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 b670cbda38e3..940cd196eef5 100644
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -81,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/matrox/matroxfb_accel.c b/drivers/video/matrox/matroxfb_accel.c
index 8335a6fe303e..0d5cb85d071a 100644
--- a/drivers/video/matrox/matroxfb_accel.c
+++ b/drivers/video/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_base.c b/drivers/video/matrox/matroxfb_base.c
index 87c64ff4546c..7116c5309c7d 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/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);
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h
index 11ed57bb704e..556d96ce40bf 100644
--- a/drivers/video/matrox/matroxfb_base.h
+++ b/drivers/video/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;
diff --git a/drivers/video/omap2/displays-new/connector-analog-tv.c b/drivers/video/omap2/displays-new/connector-analog-tv.c
index ccd9073f706f..5ee3b5505f7f 100644
--- a/drivers/video/omap2/displays-new/connector-analog-tv.c
+++ b/drivers/video/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)
@@ -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/omap2/displays-new/connector-dvi.c
index b6c50904038e..74de2bc50c4f 100644
--- a/drivers/video/omap2/displays-new/connector-dvi.c
+++ b/drivers/video/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,
@@ -277,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;
@@ -293,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;
}
@@ -342,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/omap2/displays-new/connector-hdmi.c
index 9abe2c039ae9..29ed21b9dce5 100644
--- a/drivers/video/omap2/displays-new/connector-hdmi.c
+++ b/drivers/video/omap2/displays-new/connector-hdmi.c
@@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/of.h>
#include <drm/drm_edid.h>
@@ -21,7 +22,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,
@@ -301,6 +302,23 @@ 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;
+
+ 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,6 +336,10 @@ 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;
}
@@ -359,12 +381,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/omap2/displays-new/encoder-tfp410.c
index 4a291e756be9..b4e9a42a79e6 100644
--- a/drivers/video/omap2/displays-new/encoder-tfp410.c
+++ b/drivers/video/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/omap2/displays-new/encoder-tpd12s015.c
index d5c936cb217f..7e33686171e3 100644
--- a/drivers/video/omap2/displays-new/encoder-tpd12s015.c
+++ b/drivers/video/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>
@@ -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-dsi-cm.c b/drivers/video/omap2/displays-new/panel-dsi-cm.c
index b7baafe83aa3..d6f14e8717e8 100644
--- a/drivers/video/omap2/displays-new/panel-dsi-cm.c
+++ b/drivers/video/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,10 +597,13 @@ 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);
@@ -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/omap2/displays-new/panel-lgphilips-lb035q02.c
index 6e8977b18950..2e6b513222d9 100644
--- a/drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c
+++ b/drivers/video/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,
diff --git a/drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c b/drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c
index bb217da65c5f..996fa004b48c 100644
--- a/drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c
+++ b/drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c
@@ -40,7 +40,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 +69,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,
diff --git a/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c
index 72a4fb5aa6b1..b2f710be565d 100644
--- a/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c
@@ -37,7 +37,7 @@ static const struct omap_video_timings sharp_ls_timings = {
.x_res = 480,
.y_res = 640,
- .pixel_clock = 19200,
+ .pixelclock = 19200000,
.hsw = 2,
.hfp = 1,
diff --git a/drivers/video/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/omap2/displays-new/panel-sony-acx565akm.c
index 8e97d06921ff..c7ba4d8b928a 100644
--- a/drivers/video/omap2/displays-new/panel-sony-acx565akm.c
+++ b/drivers/video/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,
@@ -547,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) {
@@ -726,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;
@@ -753,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;
}
@@ -864,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/omap2/displays-new/panel-tpo-td028ttec1.c b/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
index 9a08908fe998..fae6adc005a7 100644
--- a/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
+++ b/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
@@ -45,7 +45,7 @@ struct panel_drv_data {
static struct omap_video_timings td028ttec1_panel_timings = {
.x_res = 480,
.y_res = 640,
- .pixel_clock = 22153,
+ .pixelclock = 22153000,
.hfp = 24,
.hsw = 8,
.hbp = 8,
diff --git a/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c
index eadc6529fa3d..875b40263b33 100644
--- a/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c
@@ -76,7 +76,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,
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index d3aa91bdd6a8..8aec8bda27cc 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,7 +1,7 @@
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
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 77d6221618f4..2bbdb7ff7daf 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -100,8 +100,6 @@ static struct {
struct platform_device *pdev;
void __iomem *base;
- int ctx_loss_cnt;
-
int irq;
unsigned long core_clk_rate;
@@ -357,29 +355,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);
@@ -2884,7 +2873,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,
@@ -2979,10 +2968,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",
@@ -3768,6 +3757,15 @@ static int dispc_runtime_suspend(struct device *dev)
static int dispc_runtime_resume(struct device *dev)
{
+ /*
+ * 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)
+ return 0;
+
_omap_dispc_initial_config();
dispc_restore_context();
@@ -3780,12 +3778,20 @@ 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", },
+ {},
+};
+
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/display-sysfs.c b/drivers/video/omap2/dss/display-sysfs.c
index f7b5f9561041..5a2095a98ed8 100644
--- a/drivers/video/omap2/dss/display-sysfs.c
+++ b/drivers/video/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;
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 669a81fdf58e..2412a0dd0c13 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/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;
@@ -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/omap2/dss/dpi.c
index 23ef21ffc2c4..157921db447a 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/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)
@@ -307,22 +310,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);
@@ -480,17 +482,17 @@ 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;
@@ -500,9 +502,9 @@ static int dpi_check_timings(struct omap_dss_device *dssdev,
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;
}
@@ -726,3 +728,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/omap2/dss/dsi.c
index a820c37e323e..121d1049d0bc 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/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>
@@ -386,6 +388,13 @@ struct dsi_packet_sent_handler_data {
struct completion *completion;
};
+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);
@@ -1151,15 +1160,11 @@ static int dsi_regulator_init(struct platform_device *dsidev)
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)) {
if (PTR_ERR(vdds_dsi) != -EPROBE_DEFER)
- DSSERR("can't get VDDS_DSI regulator\n");
+ DSSERR("can't get DSI VDD regulator\n");
return PTR_ERR(vdds_dsi);
}
@@ -4616,7 +4621,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;
@@ -4656,7 +4661,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);
@@ -4678,7 +4683,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;
@@ -4732,7 +4737,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;
@@ -4909,7 +4914,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,
@@ -5031,9 +5036,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);
@@ -5370,12 +5375,69 @@ 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 dsi_data *dsi;
+ struct resource *dsi_mem;
struct resource *res;
struct resource temp_res;
@@ -5383,7 +5445,6 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
if (!dsi)
return -ENOMEM;
- dsi->module_id = dsidev->id;
dsi->pdev = dsidev;
dev_set_drvdata(&dsidev->dev, dsi);
@@ -5421,6 +5482,8 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
res = &temp_res;
}
+ dsi_mem = res;
+
dsi->proto_base = devm_ioremap(&dsidev->dev, res->start,
resource_size(res));
if (!dsi->proto_base) {
@@ -5481,6 +5544,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;
@@ -5516,6 +5604,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)
@@ -5529,17 +5630,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);
@@ -5577,6 +5692,23 @@ 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 of_device_id dsi_of_match[] = {
+ { .compatible = "ti,omap3-dsi", .data = dsi_of_data_omap3, },
+ { .compatible = "ti,omap4-dsi", .data = dsi_of_data_omap4, },
+ {},
+};
+
static struct platform_driver omap_dsihw_driver = {
.probe = omap_dsihw_probe,
.remove = __exit_p(omap_dsihw_remove),
@@ -5584,6 +5716,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/omap2/dss/dss-of.c b/drivers/video/omap2/dss/dss-of.c
new file mode 100644
index 000000000000..a4b20aaf6142
--- /dev/null
+++ b/drivers/video/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/omap2/dss/dss.c
index 9a145da35ad3..825c019ddee7 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/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>
@@ -154,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;
@@ -788,6 +774,56 @@ 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) {
+#ifdef CONFIG_OMAP2_DSS_DPI
+ dpi_init_port(pdev, parent);
+#endif
+ return 0;
+ }
+
+ do {
+ u32 reg;
+
+ r = of_property_read_u32(port, "reg", &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 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)
{
@@ -846,6 +882,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));
@@ -865,6 +903,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();
@@ -902,12 +942,22 @@ 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", },
+ {},
+};
+
+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/omap2/dss/dss.h
index 057f24c8a332..918fec182424 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -225,8 +225,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);
@@ -252,6 +250,9 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
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,
@@ -363,6 +364,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;
diff --git a/drivers/video/omap2/dss/hdmi4.c b/drivers/video/omap2/dss/hdmi4.c
index 4a74538f9ea5..f5f7944a1fd1 100644
--- a/drivers/video/omap2/dss/hdmi4.c
+++ b/drivers/video/omap2/dss/hdmi4.c
@@ -88,15 +88,11 @@ static int hdmi_init_regulator(void)
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");
+ reg = devm_regulator_get(&hdmi.pdev->dev, "vdda");
if (IS_ERR(reg)) {
if (PTR_ERR(reg) != -EPROBE_DEFER)
- DSSERR("can't get VDDA_HDMI_DAC regulator\n");
+ DSSERR("can't get VDDA regulator\n");
return PTR_ERR(reg);
}
@@ -153,7 +149,8 @@ static int hdmi_power_on_full(struct omap_dss_device *dssdev)
DSSDBG("hdmi_power_on x_res= %d y_res = %d\n", p->x_res, p->y_res);
- phy = p->pixel_clock;
+ /* 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);
@@ -238,13 +235,13 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
if (t != NULL) {
hdmi.cfg = *t;
- dispc_set_tv_pclk(t->timings.pixel_clock * 1000);
+ 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->pixel_clock * 1000);
+ dispc_set_tv_pclk(timings->pixelclock);
}
DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ?
@@ -509,7 +506,7 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
struct omap_dss_audio *audio)
{
int r;
- u32 pclk = hdmi.cfg.timings.pixel_clock;
+ u32 pclk = hdmi.cfg.timings.pixelclock;
mutex_lock(&hdmi.lock);
@@ -679,6 +676,11 @@ static const struct dev_pm_ops hdmi_pm_ops = {
.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),
@@ -686,6 +688,7 @@ static struct platform_driver omapdss_hdmihw_driver = {
.name = "omapdss_hdmi",
.owner = THIS_MODULE,
.pm = &hdmi_pm_ops,
+ .of_match_table = hdmi_of_match,
},
};
diff --git a/drivers/video/omap2/dss/hdmi_common.c b/drivers/video/omap2/dss/hdmi_common.c
index 0614922902dd..b11afac8e068 100644
--- a/drivers/video/omap2/dss/hdmi_common.c
+++ b/drivers/video/omap2/dss/hdmi_common.c
@@ -23,91 +23,91 @@
static const struct hdmi_config cea_timings[] = {
{
- { 640, 480, 25200, 96, 16, 48, 2, 10, 33,
+ { 640, 480, 25200000, 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,
+ { 720, 480, 27027000, 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,
+ { 1280, 720, 74250000, 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,
+ { 1920, 540, 74250000, 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,
+ { 1440, 240, 27027000, 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,
+ { 1920, 1080, 148500000, 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,
+ { 720, 576, 27000000, 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,
+ { 1280, 720, 74250000, 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,
+ { 1920, 540, 74250000, 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,
+ { 1440, 288, 27000000, 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,
+ { 1440, 576, 54000000, 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,
+ { 1920, 1080, 148500000, 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,
+ { 1920, 1080, 74250000, 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,
+ { 2880, 480, 108108000, 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,
+ { 2880, 576, 108000000, 256, 48, 272, 5, 5, 39,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
false, },
{ 37, HDMI_HDMI },
@@ -117,121 +117,121 @@ static const struct hdmi_config cea_timings[] = {
static const struct hdmi_config vesa_timings[] = {
/* VESA From Here */
{
- { 640, 480, 25175, 96, 16, 48, 2, 11, 31,
+ { 640, 480, 25175000, 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,
+ { 800, 600, 40000000, 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,
+ { 848, 480, 33750000, 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,
+ { 1280, 768, 79500000, 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,
+ { 1280, 800, 83500000, 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,
+ { 1360, 768, 85500000, 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,
+ { 1280, 960, 108000000, 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,
+ { 1280, 1024, 108000000, 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,
+ { 1024, 768, 65000000, 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,
+ { 1400, 1050, 121750000, 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,
+ { 1440, 900, 106500000, 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,
+ { 1680, 1050, 146250000, 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,
+ { 1366, 768, 85500000, 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,
+ { 1920, 1080, 148500000, 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,
+ { 1280, 768, 68250000, 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,
+ { 1400, 1050, 101000000, 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,
+ { 1680, 1050, 119000000, 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,
+ { 1280, 800, 79500000, 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,
+ { 1280, 720, 74250000, 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,
+ { 1920, 1200, 154000000, 32, 48, 80, 6, 3, 26,
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
false, },
{ 0x44, HDMI_DVI },
@@ -277,8 +277,8 @@ static bool hdmi_timings_compare(struct omap_video_timings *timing1,
{
int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
- if ((DIV_ROUND_CLOSEST(timing2->pixel_clock, 1000) ==
- DIV_ROUND_CLOSEST(timing1->pixel_clock, 1000)) &&
+ 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)) {
diff --git a/drivers/video/omap2/dss/hdmi_wp.c b/drivers/video/omap2/dss/hdmi_wp.c
index cd620c6e43a0..f5f4ccf50d90 100644
--- a/drivers/video/omap2/dss/hdmi_wp.c
+++ b/drivers/video/omap2/dss/hdmi_wp.c
@@ -171,6 +171,8 @@ void hdmi_wp_init_vid_fmt_timings(struct hdmi_video_format *video_fmt,
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;
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index ba806c9e7f54..911dcc9173a6 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/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,6 +42,8 @@ static struct {
int datapairs;
struct omap_dss_device output;
+
+ bool port_initialized;
} sdi;
struct sdi_clk_calc_ctx {
@@ -149,20 +152,19 @@ 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, &fck, &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 = 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;
}
@@ -244,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;
@@ -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/omap2/dss/venc.c
index 2cd7f7e42105..21d81113962b 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/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,7 +637,10 @@ 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)) {
if (PTR_ERR(vdda_dac) != -EPROBE_DEFER)
@@ -805,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)
{
@@ -846,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;
@@ -895,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),
@@ -902,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/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
index f7d92c57bd73..af68cd444d7e 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -89,7 +89,7 @@ static int venc_panel_probe(struct omap_dss_device *dssdev)
const struct omap_video_timings default_timings = {
.x_res = 720,
.y_res = 574,
- .pixel_clock = 13500,
+ .pixelclock = 13500000,
.hsw = 64,
.hfp = 12,
.hbp = 68,
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index fcb9e932d00c..ec2d132c782d 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/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;
@@ -2077,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;
@@ -2229,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;
@@ -2417,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;
@@ -2494,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;
diff --git a/drivers/video/output.c b/drivers/video/output.c
deleted file mode 100644
index 1446c49fe6af..000000000000
--- 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/pxa3xx-gcu.c b/drivers/video/pxa3xx-gcu.c
index ad382b3396cd..417f9a27eb7d 100644
--- a/drivers/video/pxa3xx-gcu.c
+++ b/drivers/video/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,99 @@ 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,
+ priv->misc_dev.fops = &pxa3xx_gcu_miscdev_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;
+ /* handle IO resources */
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ priv->mmio_base = devm_request_and_ioremap(dev, r);
+ if (IS_ERR(priv->mmio_base)) {
+ dev_err(dev, "failed to map I/O memory\n");
+ return PTR_ERR(priv->mmio_base);
}
- /* 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;
+ /* 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/sgivwfb.c b/drivers/video/sgivwfb.c
deleted file mode 100644
index bc74d0408998..000000000000
--- 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);
-
- fb_info(info, "SGI DBE frame buffer device, using %ldK of video memory at %#lx\n",
- 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 */
diff --git a/drivers/video/sis/init.c b/drivers/video/sis/init.c
index 4f26bc28e60b..bd40f5ecd901 100644
--- a/drivers/video/sis/init.c
+++ b/drivers/video/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];
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 07c7df9ee77b..65ba9921506e 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -182,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)
@@ -190,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;
@@ -262,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;
@@ -1136,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;
@@ -1368,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);
@@ -1434,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
@@ -1447,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);
}
@@ -1470,6 +1311,7 @@ tgafb_init_fix(struct fb_info *info)
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:
@@ -1477,22 +1319,27 @@ 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;
}
- if (!tga_type_name)
+ if (!tga_type_name) {
tga_type_name = "Unknown";
+ memory_size = 16777216;
+ }
strlcpy(info->fix.id, tga_type_name, sizeof(info->fix.id));
@@ -1502,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;
@@ -1628,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,
@@ -1645,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");
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 256fba7f4641..509d452e8f91 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/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;
}
@@ -1474,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
@@ -1812,11 +1807,9 @@ static int uvesafb_remove(struct platform_device *dev)
fb_destroy_modedb(info->monspecs.modedb);
fb_dealloc_cmap(&info->cmap);
- if (par) {
- kfree(par->vbe_modes);
- kfree(par->vbe_state_orig);
- 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/vesafb.c b/drivers/video/vesafb.c
index 1c7da3b098d6..6170e7f58640 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/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;
@@ -499,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/xilinxfb.c b/drivers/video/xilinxfb.c
index 6ff1a91e9dfd..553cff2f3f4c 100644
--- a/drivers/video/xilinxfb.c
+++ b/drivers/video/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
*/