From 6016a363f6b56b46b24655bcfc0499b715851cf3 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Thu, 28 Jan 2010 14:06:53 -0700 Subject: of: unify phandle name in struct device_node In struct device_node, the phandle is named 'linux_phandle' for PowerPC and MicroBlaze, and 'node' for SPARC. There is no good reason for the difference, it is just an artifact of the code diverging over a couple of years. This patch renames both to simply .phandle. Note: the .node also existed in PowerPC/MicroBlaze, but the only user seems to be arch/powerpc/platforms/powermac/pfunc_core.c. It doesn't look like the assignment between .linux_phandle and .node is significantly different enough to warrant the separate code paths unless ibm,phandle properties actually appear in Apple device trees. I think it is safe to eliminate the old .node property and use phandle everywhere. Signed-off-by: Grant Likely Acked-by: David S. Miller Tested-by: Wolfram Sang Acked-by: Benjamin Herrenschmidt --- drivers/video/aty/atyfb_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 913b4a4..bb20987 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -3104,7 +3104,7 @@ static int __devinit atyfb_setup_sparc(struct pci_dev *pdev, } dp = pci_device_to_OF_node(pdev); - if (node == dp->node) { + if (node == dp->phandle) { struct fb_var_screeninfo *var = &default_var; unsigned int N, P, Q, M, T, R; u32 v_total, h_total; -- cgit v1.1 From 1c64606968538396ffe87eb6da4121a5bffe5e34 Mon Sep 17 00:00:00 2001 From: Vaibhav Hiremath Date: Mon, 4 Jan 2010 15:34:15 +0100 Subject: OMAP: DSS2: Add Sharp LQ043T1DG01 panel driver Signed-off-by: Vaibhav Hiremath Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/Kconfig | 6 ++ drivers/video/omap2/displays/Makefile | 1 + .../video/omap2/displays/panel-sharp-lq043t1dg01.c | 120 +++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c (limited to 'drivers/video') diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index b12a59c..4ce47dd 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig @@ -13,6 +13,12 @@ config PANEL_SHARP_LS037V7DW01 help LCD Panel used in TI's SDP3430 and EVM boards +config PANEL_SHARP_LQ043T1DG01 + tristate "Sharp LQ043T1DG01 LCD Panel" + depends on OMAP2_DSS + help + LCD Panel used in TI's OMAP3517 EVM boards + config PANEL_TAAL tristate "Taal DSI Panel" depends on OMAP2_DSS_DSI diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile index 9556464..8f3d0ad 100644 --- a/drivers/video/omap2/displays/Makefile +++ b/drivers/video/omap2/displays/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o +obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.o obj-$(CONFIG_PANEL_TAAL) += panel-taal.o diff --git a/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c b/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c new file mode 100644 index 0000000..e75798e --- /dev/null +++ b/drivers/video/omap2/displays/panel-sharp-lq043t1dg01.c @@ -0,0 +1,120 @@ +/* + * LCD panel driver for Sharp LQ043T1DG01 + * + * Copyright (C) 2009 Texas Instruments Inc + * Author: Vaibhav Hiremath + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include + +#include + +static struct omap_video_timings sharp_lq_timings = { + .x_res = 480, + .y_res = 272, + + .pixel_clock = 9000, + + .hsw = 42, + .hfp = 3, + .hbp = 2, + + .vsw = 11, + .vfp = 3, + .vbp = 2, +}; + +static int sharp_lq_panel_probe(struct omap_dss_device *dssdev) +{ + + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | + OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IEO; + dssdev->panel.acb = 0x0; + dssdev->panel.timings = sharp_lq_timings; + + return 0; +} + +static void sharp_lq_panel_remove(struct omap_dss_device *dssdev) +{ +} + +static int sharp_lq_panel_enable(struct omap_dss_device *dssdev) +{ + int r = 0; + + + /* wait couple of vsyncs until enabling the LCD */ + msleep(50); + + if (dssdev->platform_enable) + r = dssdev->platform_enable(dssdev); + + return r; +} + +static void sharp_lq_panel_disable(struct omap_dss_device *dssdev) +{ + + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); + + /* wait at least 5 vsyncs after disabling the LCD */ + + msleep(100); +} + +static int sharp_lq_panel_suspend(struct omap_dss_device *dssdev) +{ + sharp_lq_panel_disable(dssdev); + return 0; +} + +static int sharp_lq_panel_resume(struct omap_dss_device *dssdev) +{ + return sharp_lq_panel_enable(dssdev); +} + +static struct omap_dss_driver sharp_lq_driver = { + .probe = sharp_lq_panel_probe, + .remove = sharp_lq_panel_remove, + + .enable = sharp_lq_panel_enable, + .disable = sharp_lq_panel_disable, + .suspend = sharp_lq_panel_suspend, + .resume = sharp_lq_panel_resume, + + .driver = { + .name = "sharp_lq_panel", + .owner = THIS_MODULE, + }, +}; + +static int __init sharp_lq_panel_drv_init(void) +{ + return omap_dss_register_driver(&sharp_lq_driver); +} + +static void __exit sharp_lq_panel_drv_exit(void) +{ + omap_dss_unregister_driver(&sharp_lq_driver); +} + +module_init(sharp_lq_panel_drv_init); +module_exit(sharp_lq_panel_drv_exit); +MODULE_LICENSE("GPL"); -- cgit v1.1 From 71a157e8edca55198e808f8561dd49017a54ee34 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 1 Feb 2010 21:34:14 -0700 Subject: of: add 'of_' prefix to machine_is_compatible() machine is compatible is an OF-specific call. It should have the of_ prefix to protect the global namespace. Signed-off-by: Grant Likely Acked-by: Michal Simek --- drivers/video/aty/aty128fb.c | 14 +++++++------- drivers/video/aty/atyfb_base.c | 8 ++++---- drivers/video/aty/radeon_backlight.c | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index e4e4d43..9ee67d6 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -1931,22 +1931,22 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i * PowerMac2,2 summer 2000 iMacs * PowerMac4,1 january 2001 iMacs "flower power" */ - if (machine_is_compatible("PowerMac2,1") || - machine_is_compatible("PowerMac2,2") || - machine_is_compatible("PowerMac4,1")) + if (of_machine_is_compatible("PowerMac2,1") || + of_machine_is_compatible("PowerMac2,2") || + of_machine_is_compatible("PowerMac4,1")) default_vmode = VMODE_1024_768_75; /* iBook SE */ - if (machine_is_compatible("PowerBook2,2")) + if (of_machine_is_compatible("PowerBook2,2")) default_vmode = VMODE_800_600_60; /* PowerBook Firewire (Pismo), iBook Dual USB */ - if (machine_is_compatible("PowerBook3,1") || - machine_is_compatible("PowerBook4,1")) + if (of_machine_is_compatible("PowerBook3,1") || + of_machine_is_compatible("PowerBook4,1")) default_vmode = VMODE_1024_768_60; /* PowerBook Titanium */ - if (machine_is_compatible("PowerBook3,2")) + if (of_machine_is_compatible("PowerBook3,2")) default_vmode = VMODE_1152_768_60; if (default_cmode > 16) diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 5f1b580..e45ab8d 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -2439,7 +2439,7 @@ static int __devinit aty_init(struct fb_info *info) * The Apple iBook1 uses non-standard memory frequencies. * We detect it and set the frequency manually. */ - if (machine_is_compatible("PowerBook2,1")) { + if (of_machine_is_compatible("PowerBook2,1")) { par->pll_limits.mclk = 70; par->pll_limits.xclk = 53; } @@ -2659,7 +2659,7 @@ static int __devinit aty_init(struct fb_info *info) FBINFO_HWACCEL_YPAN; #ifdef CONFIG_PMAC_BACKLIGHT - if (M64_HAS(G3_PB_1_1) && machine_is_compatible("PowerBook1,1")) { + if (M64_HAS(G3_PB_1_1) && of_machine_is_compatible("PowerBook1,1")) { /* * these bits let the 101 powerbook * wake up from sleep -- paulus @@ -2690,9 +2690,9 @@ static int __devinit aty_init(struct fb_info *info) if (M64_HAS(G3_PB_1024x768)) /* G3 PowerBook with 1024x768 LCD */ default_vmode = VMODE_1024_768_60; - else if (machine_is_compatible("iMac")) + else if (of_machine_is_compatible("iMac")) default_vmode = VMODE_1024_768_75; - else if (machine_is_compatible("PowerBook2,1")) + else if (of_machine_is_compatible("PowerBook2,1")) /* iBook with 800x600 LCD */ default_vmode = VMODE_800_600_60; else diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index 1a056ad..fa1198c 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c @@ -175,9 +175,9 @@ void radeonfb_bl_init(struct radeonfb_info *rinfo) #ifdef CONFIG_PMAC_BACKLIGHT pdata->negative = pdata->negative || - machine_is_compatible("PowerBook4,3") || - machine_is_compatible("PowerBook6,3") || - machine_is_compatible("PowerBook6,5"); + of_machine_is_compatible("PowerBook4,3") || + of_machine_is_compatible("PowerBook6,3") || + of_machine_is_compatible("PowerBook6,5"); #endif rinfo->info->bl_dev = bd; -- cgit v1.1 From 751ef159c5600e7ee53e64c3d04f3e2d78908ce5 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Mon, 14 Dec 2009 09:01:07 +0100 Subject: OMAP: DSS2: add Toppoly TDO35S panel Signed-off-by: Mike Rapoport Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/Kconfig | 6 ++ drivers/video/omap2/displays/Makefile | 1 + .../video/omap2/displays/panel-toppoly-tdo35s.c | 112 +++++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 drivers/video/omap2/displays/panel-toppoly-tdo35s.c (limited to 'drivers/video') diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index 4ce47dd..4d95ed5 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig @@ -25,4 +25,10 @@ config PANEL_TAAL help Taal DSI command mode panel from TPO. +config PANEL_TOPPOLY_TDO35S + tristate "Toppoly TDO35S LCD Panel support" + depends on OMAP2_DSS + help + LCD Panel used in CM-T35 + endmenu diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile index 8f3d0ad..e75cc70 100644 --- a/drivers/video/omap2/displays/Makefile +++ b/drivers/video/omap2/displays/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.o obj-$(CONFIG_PANEL_TAAL) += panel-taal.o +obj-$(CONFIG_PANEL_TOPPOLY_TDO35S) += panel-toppoly-tdo35s.o \ No newline at end of file diff --git a/drivers/video/omap2/displays/panel-toppoly-tdo35s.c b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c new file mode 100644 index 0000000..e744b8c --- /dev/null +++ b/drivers/video/omap2/displays/panel-toppoly-tdo35s.c @@ -0,0 +1,112 @@ +/* + * LCD panel driver for Toppoly TDO35S + * + * Copyright (C) 2009 CompuLab, Ltd. + * Author: Mike Rapoport + * + * Based on generic panel support + * Copyright (C) 2008 Nokia Corporation + * Author: Tomi Valkeinen + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include + +#include + +static struct omap_video_timings toppoly_tdo_panel_timings = { + /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */ + .x_res = 480, + .y_res = 640, + + .pixel_clock = 26000, + + .hfp = 104, + .hsw = 8, + .hbp = 8, + + .vfp = 4, + .vsw = 2, + .vbp = 2, +}; + +static int toppoly_tdo_panel_probe(struct omap_dss_device *dssdev) +{ + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | + OMAP_DSS_LCD_IHS; + dssdev->panel.timings = toppoly_tdo_panel_timings; + + return 0; +} + +static void toppoly_tdo_panel_remove(struct omap_dss_device *dssdev) +{ +} + +static int toppoly_tdo_panel_enable(struct omap_dss_device *dssdev) +{ + int r = 0; + + if (dssdev->platform_enable) + r = dssdev->platform_enable(dssdev); + + return r; +} + +static void toppoly_tdo_panel_disable(struct omap_dss_device *dssdev) +{ + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); +} + +static int toppoly_tdo_panel_suspend(struct omap_dss_device *dssdev) +{ + toppoly_tdo_panel_disable(dssdev); + return 0; +} + +static int toppoly_tdo_panel_resume(struct omap_dss_device *dssdev) +{ + return toppoly_tdo_panel_enable(dssdev); +} + +static struct omap_dss_driver generic_driver = { + .probe = toppoly_tdo_panel_probe, + .remove = toppoly_tdo_panel_remove, + + .enable = toppoly_tdo_panel_enable, + .disable = toppoly_tdo_panel_disable, + .suspend = toppoly_tdo_panel_suspend, + .resume = toppoly_tdo_panel_resume, + + .driver = { + .name = "toppoly_tdo35s_panel", + .owner = THIS_MODULE, + }, +}; + +static int __init toppoly_tdo_panel_drv_init(void) +{ + return omap_dss_register_driver(&generic_driver); +} + +static void __exit toppoly_tdo_panel_drv_exit(void) +{ + omap_dss_unregister_driver(&generic_driver); +} + +module_init(toppoly_tdo_panel_drv_init); +module_exit(toppoly_tdo_panel_drv_exit); +MODULE_LICENSE("GPL"); -- cgit v1.1 From 9ce4ad0a7b2e21363ce1d1d4c8eb4c2ae213cb59 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Fri, 11 Dec 2009 21:30:14 +0200 Subject: OMAP: DSS: add TPO TD043MTEA1 panel Add support of TPO TD043MTEA1 TFT LCD panel to DSS2 driver. This panel is used by OMAP3 Pandora device. Signed-off-by: Grazvydas Ignotas Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/Kconfig | 6 + drivers/video/omap2/displays/Makefile | 3 +- .../video/omap2/displays/panel-tpo-td043mtea1.c | 489 +++++++++++++++++++++ 3 files changed, 497 insertions(+), 1 deletion(-) create mode 100644 drivers/video/omap2/displays/panel-tpo-td043mtea1.c (limited to 'drivers/video') diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig index 4d95ed5..dfb57ee 100644 --- a/drivers/video/omap2/displays/Kconfig +++ b/drivers/video/omap2/displays/Kconfig @@ -31,4 +31,10 @@ config PANEL_TOPPOLY_TDO35S help LCD Panel used in CM-T35 +config PANEL_TPO_TD043MTEA1 + tristate "TPO TD043MTEA1 LCD Panel" + depends on OMAP2_DSS && I2C + help + LCD Panel used in OMAP3 Pandora + endmenu diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile index e75cc70..e2bb321 100644 --- a/drivers/video/omap2/displays/Makefile +++ b/drivers/video/omap2/displays/Makefile @@ -3,4 +3,5 @@ obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o obj-$(CONFIG_PANEL_SHARP_LQ043T1DG01) += panel-sharp-lq043t1dg01.o obj-$(CONFIG_PANEL_TAAL) += panel-taal.o -obj-$(CONFIG_PANEL_TOPPOLY_TDO35S) += panel-toppoly-tdo35s.o \ No newline at end of file +obj-$(CONFIG_PANEL_TOPPOLY_TDO35S) += panel-toppoly-tdo35s.o +obj-$(CONFIG_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c new file mode 100644 index 0000000..f297a46 --- /dev/null +++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c @@ -0,0 +1,489 @@ +/* + * LCD panel driver for TPO TD043MTEA1 + * + * Author: Gražvydas Ignotas + * + * 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 +#include +#include +#include +#include +#include + +#include + +#define TPO_R02_MODE(x) ((x) & 7) +#define TPO_R02_MODE_800x480 7 +#define TPO_R02_NCLK_RISING BIT(3) +#define TPO_R02_HSYNC_HIGH BIT(4) +#define TPO_R02_VSYNC_HIGH BIT(5) + +#define TPO_R03_NSTANDBY BIT(0) +#define TPO_R03_EN_CP_CLK BIT(1) +#define TPO_R03_EN_VGL_PUMP BIT(2) +#define TPO_R03_EN_PWM BIT(3) +#define TPO_R03_DRIVING_CAP_100 BIT(4) +#define TPO_R03_EN_PRE_CHARGE BIT(6) +#define TPO_R03_SOFTWARE_CTL BIT(7) + +#define TPO_R04_NFLIP_H BIT(0) +#define TPO_R04_NFLIP_V BIT(1) +#define TPO_R04_CP_CLK_FREQ_1H BIT(2) +#define TPO_R04_VGL_FREQ_1H BIT(4) + +#define TPO_R03_VAL_NORMAL (TPO_R03_NSTANDBY | TPO_R03_EN_CP_CLK | \ + TPO_R03_EN_VGL_PUMP | TPO_R03_EN_PWM | \ + TPO_R03_DRIVING_CAP_100 | TPO_R03_EN_PRE_CHARGE | \ + TPO_R03_SOFTWARE_CTL) + +#define TPO_R03_VAL_STANDBY (TPO_R03_DRIVING_CAP_100 | \ + TPO_R03_EN_PRE_CHARGE | TPO_R03_SOFTWARE_CTL) + +static const u16 tpo_td043_def_gamma[12] = { + 106, 200, 289, 375, 460, 543, 625, 705, 785, 864, 942, 1020 +}; + +struct tpo_td043_device { + struct spi_device *spi; + struct regulator *vcc_reg; + u16 gamma[12]; + u32 mode; + u32 hmirror:1; + u32 vmirror:1; +}; + +static int tpo_td043_write(struct spi_device *spi, u8 addr, u8 data) +{ + struct spi_message m; + struct spi_transfer xfer; + u16 w; + int r; + + spi_message_init(&m); + + memset(&xfer, 0, sizeof(xfer)); + + w = ((u16)addr << 10) | (1 << 8) | data; + xfer.tx_buf = &w; + xfer.bits_per_word = 16; + xfer.len = 2; + spi_message_add_tail(&xfer, &m); + + r = spi_sync(spi, &m); + if (r < 0) + dev_warn(&spi->dev, "failed to write to LCD reg (%d)\n", r); + return r; +} + +static void tpo_td043_write_gamma(struct spi_device *spi, u16 gamma[12]) +{ + u8 i, val; + + /* gamma bits [9:8] */ + for (val = i = 0; i < 4; i++) + val |= (gamma[i] & 0x300) >> ((i + 1) * 2); + tpo_td043_write(spi, 0x11, val); + + for (val = i = 0; i < 4; i++) + val |= (gamma[i+4] & 0x300) >> ((i + 1) * 2); + tpo_td043_write(spi, 0x12, val); + + for (val = i = 0; i < 4; i++) + val |= (gamma[i+8] & 0x300) >> ((i + 1) * 2); + tpo_td043_write(spi, 0x13, val); + + /* gamma bits [7:0] */ + for (val = i = 0; i < 12; i++) + tpo_td043_write(spi, 0x14 + i, gamma[i] & 0xff); +} + +static int tpo_td043_write_mirror(struct spi_device *spi, bool h, bool v) +{ + u8 reg4 = TPO_R04_NFLIP_H | TPO_R04_NFLIP_V | \ + TPO_R04_CP_CLK_FREQ_1H | TPO_R04_VGL_FREQ_1H; + if (h) + reg4 &= ~TPO_R04_NFLIP_H; + if (v) + reg4 &= ~TPO_R04_NFLIP_V; + + return tpo_td043_write(spi, 4, reg4); +} + +static int tpo_td043_set_hmirror(struct omap_dss_device *dssdev, bool enable) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); + + tpo_td043->hmirror = enable; + return tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, + tpo_td043->vmirror); +} + +static bool tpo_td043_get_hmirror(struct omap_dss_device *dssdev) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); + + return tpo_td043->hmirror; +} + +static ssize_t tpo_td043_vmirror_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->vmirror); +} + +static ssize_t tpo_td043_vmirror_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); + long val; + int ret; + + ret = strict_strtol(buf, 0, &val); + if (ret < 0) + return ret; + + ret = tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, val); + if (ret < 0) + return ret; + + tpo_td043->vmirror = val; + + return count; +} + +static ssize_t tpo_td043_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); + + return snprintf(buf, PAGE_SIZE, "%d\n", tpo_td043->mode); +} + +static ssize_t tpo_td043_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); + long val; + int ret; + + ret = strict_strtol(buf, 0, &val); + if (ret != 0 || val & ~7) + return -EINVAL; + + tpo_td043->mode = val; + + val |= TPO_R02_NCLK_RISING; + tpo_td043_write(tpo_td043->spi, 2, val); + + return count; +} + +static ssize_t tpo_td043_gamma_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); + ssize_t len = 0; + int ret; + int i; + + for (i = 0; i < ARRAY_SIZE(tpo_td043->gamma); i++) { + ret = snprintf(buf + len, PAGE_SIZE - len, "%u ", + tpo_td043->gamma[i]); + if (ret < 0) + return ret; + len += ret; + } + buf[len - 1] = '\n'; + + return len; +} + +static ssize_t tpo_td043_gamma_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(dev); + unsigned int g[12]; + int ret; + int i; + + ret = sscanf(buf, "%u %u %u %u %u %u %u %u %u %u %u %u", + &g[0], &g[1], &g[2], &g[3], &g[4], &g[5], + &g[6], &g[7], &g[8], &g[9], &g[10], &g[11]); + + if (ret != 12) + return -EINVAL; + + for (i = 0; i < 12; i++) + tpo_td043->gamma[i] = g[i]; + + tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); + + return count; +} + +static DEVICE_ATTR(vmirror, S_IRUGO | S_IWUSR, + tpo_td043_vmirror_show, tpo_td043_vmirror_store); +static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, + tpo_td043_mode_show, tpo_td043_mode_store); +static DEVICE_ATTR(gamma, S_IRUGO | S_IWUSR, + tpo_td043_gamma_show, tpo_td043_gamma_store); + +static struct attribute *tpo_td043_attrs[] = { + &dev_attr_vmirror.attr, + &dev_attr_mode.attr, + &dev_attr_gamma.attr, + NULL, +}; + +static struct attribute_group tpo_td043_attr_group = { + .attrs = tpo_td043_attrs, +}; + +static const struct omap_video_timings tpo_td043_timings = { + .x_res = 800, + .y_res = 480, + + .pixel_clock = 36000, + + .hsw = 1, + .hfp = 68, + .hbp = 214, + + .vsw = 1, + .vfp = 39, + .vbp = 34, +}; + +static int tpo_td043_enable(struct omap_dss_device *dssdev) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); + int nreset_gpio = dssdev->reset_gpio; + int ret; + + dev_dbg(&dssdev->dev, "enable\n"); + + if (dssdev->platform_enable) { + ret = dssdev->platform_enable(dssdev); + if (ret) + return ret; + } + + regulator_enable(tpo_td043->vcc_reg); + + /* wait for power up */ + msleep(160); + + if (gpio_is_valid(nreset_gpio)) + gpio_set_value(nreset_gpio, 1); + + tpo_td043_write(tpo_td043->spi, 2, + TPO_R02_MODE(tpo_td043->mode) | TPO_R02_NCLK_RISING); + tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_NORMAL); + tpo_td043_write(tpo_td043->spi, 0x20, 0xf0); + tpo_td043_write(tpo_td043->spi, 0x21, 0xf0); + tpo_td043_write_mirror(tpo_td043->spi, tpo_td043->hmirror, + tpo_td043->vmirror); + tpo_td043_write_gamma(tpo_td043->spi, tpo_td043->gamma); + + return 0; +} + +static void tpo_td043_disable(struct omap_dss_device *dssdev) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); + int nreset_gpio = dssdev->reset_gpio; + + dev_dbg(&dssdev->dev, "disable\n"); + + tpo_td043_write(tpo_td043->spi, 3, + TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM); + + if (gpio_is_valid(nreset_gpio)) + gpio_set_value(nreset_gpio, 0); + + /* wait for at least 2 vsyncs before cutting off power */ + msleep(50); + + tpo_td043_write(tpo_td043->spi, 3, TPO_R03_VAL_STANDBY); + + regulator_disable(tpo_td043->vcc_reg); + + if (dssdev->platform_disable) + dssdev->platform_disable(dssdev); +} + +static int tpo_td043_suspend(struct omap_dss_device *dssdev) +{ + tpo_td043_disable(dssdev); + return 0; +} + +static int tpo_td043_resume(struct omap_dss_device *dssdev) +{ + return tpo_td043_enable(dssdev); +} + +static int tpo_td043_probe(struct omap_dss_device *dssdev) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); + int nreset_gpio = dssdev->reset_gpio; + int ret = 0; + + dev_dbg(&dssdev->dev, "probe\n"); + + if (tpo_td043 == NULL) { + dev_err(&dssdev->dev, "missing tpo_td043_device\n"); + return -ENODEV; + } + + dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IHS | + OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IPC; + dssdev->panel.timings = tpo_td043_timings; + dssdev->ctrl.pixel_size = 24; + + tpo_td043->mode = TPO_R02_MODE_800x480; + memcpy(tpo_td043->gamma, tpo_td043_def_gamma, sizeof(tpo_td043->gamma)); + + tpo_td043->vcc_reg = regulator_get(&dssdev->dev, "vcc"); + if (IS_ERR(tpo_td043->vcc_reg)) { + dev_err(&dssdev->dev, "failed to get LCD VCC regulator\n"); + ret = PTR_ERR(tpo_td043->vcc_reg); + goto fail_regulator; + } + + if (gpio_is_valid(nreset_gpio)) { + ret = gpio_request(nreset_gpio, "lcd reset"); + if (ret < 0) { + dev_err(&dssdev->dev, "couldn't request reset GPIO\n"); + goto fail_gpio_req; + } + + ret = gpio_direction_output(nreset_gpio, 0); + if (ret < 0) { + dev_err(&dssdev->dev, "couldn't set GPIO direction\n"); + goto fail_gpio_direction; + } + } + + ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group); + if (ret) + dev_warn(&dssdev->dev, "failed to create sysfs files\n"); + + return 0; + +fail_gpio_direction: + gpio_free(nreset_gpio); +fail_gpio_req: + regulator_put(tpo_td043->vcc_reg); +fail_regulator: + kfree(tpo_td043); + return ret; +} + +static void tpo_td043_remove(struct omap_dss_device *dssdev) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); + int nreset_gpio = dssdev->reset_gpio; + + dev_dbg(&dssdev->dev, "remove\n"); + + sysfs_remove_group(&dssdev->dev.kobj, &tpo_td043_attr_group); + regulator_put(tpo_td043->vcc_reg); + if (gpio_is_valid(nreset_gpio)) + gpio_free(nreset_gpio); +} + +static struct omap_dss_driver tpo_td043_driver = { + .probe = tpo_td043_probe, + .remove = tpo_td043_remove, + + .enable = tpo_td043_enable, + .disable = tpo_td043_disable, + .suspend = tpo_td043_suspend, + .resume = tpo_td043_resume, + .set_mirror = tpo_td043_set_hmirror, + .get_mirror = tpo_td043_get_hmirror, + + .driver = { + .name = "tpo_td043mtea1_panel", + .owner = THIS_MODULE, + }, +}; + +static int tpo_td043_spi_probe(struct spi_device *spi) +{ + struct omap_dss_device *dssdev = spi->dev.platform_data; + struct tpo_td043_device *tpo_td043; + int ret; + + if (dssdev == NULL) { + dev_err(&spi->dev, "missing dssdev\n"); + return -ENODEV; + } + + spi->bits_per_word = 16; + spi->mode = SPI_MODE_0; + + ret = spi_setup(spi); + if (ret < 0) { + dev_err(&spi->dev, "spi_setup failed: %d\n", ret); + return ret; + } + + tpo_td043 = kzalloc(sizeof(*tpo_td043), GFP_KERNEL); + if (tpo_td043 == NULL) + return -ENOMEM; + + tpo_td043->spi = spi; + dev_set_drvdata(&spi->dev, tpo_td043); + dev_set_drvdata(&dssdev->dev, tpo_td043); + + omap_dss_register_driver(&tpo_td043_driver); + + return 0; +} + +static int __devexit tpo_td043_spi_remove(struct spi_device *spi) +{ + struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&spi->dev); + + omap_dss_unregister_driver(&tpo_td043_driver); + kfree(tpo_td043); + + return 0; +} + +static struct spi_driver tpo_td043_spi_driver = { + .driver = { + .name = "tpo_td043mtea1_panel_spi", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = tpo_td043_spi_probe, + .remove = __devexit_p(tpo_td043_spi_remove), +}; + +static int __init tpo_td043_init(void) +{ + return spi_register_driver(&tpo_td043_spi_driver); +} + +static void __exit tpo_td043_exit(void) +{ + spi_unregister_driver(&tpo_td043_spi_driver); +} + +module_init(tpo_td043_init); +module_exit(tpo_td043_exit); + +MODULE_AUTHOR("Gražvydas Ignotas "); +MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver"); +MODULE_LICENSE("GPL"); -- cgit v1.1 From 60596045ac3d73ab6aac85d1eca617ba4c97b020 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 14 Jan 2010 15:12:47 +0200 Subject: OMAP: DSS2: Improve Kconfig help texts Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/Kconfig | 26 ++++++++++++++++++++++---- drivers/video/omap2/omapfb/Kconfig | 2 +- 2 files changed, 23 insertions(+), 5 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig index c63ce76..87afb81 100644 --- a/drivers/video/omap2/dss/Kconfig +++ b/drivers/video/omap2/dss/Kconfig @@ -30,19 +30,29 @@ config OMAP2_DSS_COLLECT_IRQ_STATS depends on OMAP2_DSS_DEBUG_SUPPORT default n help - Collect DSS IRQ statistics, printable via debugfs + Collect DSS IRQ statistics, printable via debugfs. + + The statistics can be found from + /omapdss/dispc_irq for DISPC interrupts, and + /omapdss/dsi_irq for DSI interrupts. config OMAP2_DSS_RFBI bool "RFBI support" default n help - MIPI DBI, or RFBI (Remote Framebuffer Interface), support. + MIPI DBI support (RFBI, Remote Framebuffer Interface, in Texas + Instrument's terminology). + + DBI is a bus between the host processor and a peripheral, + such as a display or a framebuffer chip. + + See http://www.mipi.org/ for DBI spesifications. config OMAP2_DSS_VENC bool "VENC support" default y help - OMAP Video Encoder support. + OMAP Video Encoder support for S-Video and composite TV-out. config OMAP2_DSS_SDI bool "SDI support" @@ -51,12 +61,20 @@ config OMAP2_DSS_SDI help SDI (Serial Display Interface) support. + SDI is a high speed one-way display serial bus between the host + processor and a display. + config OMAP2_DSS_DSI bool "DSI support" depends on ARCH_OMAP3 default n help - MIPI DSI support. + MIPI DSI (Display Serial Interface) support. + + DSI is a high speed half-duplex serial interface between the host + processor and a peripheral, such as a display or a framebuffer chip. + + See http://www.mipi.org/ for DSI spesifications. config OMAP2_DSS_USE_DSI_PLL bool "Use DSI PLL for PCLK (EXPERIMENTAL)" diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig index bb694cc..5effa1d 100644 --- a/drivers/video/omap2/omapfb/Kconfig +++ b/drivers/video/omap2/omapfb/Kconfig @@ -16,7 +16,7 @@ config FB_OMAP2_DEBUG_SUPPORT depends on FB_OMAP2 help Support for debug output. You have to enable the actual printing - with debug module parameter. + with 'debug' module parameter. config FB_OMAP2_FORCE_AUTO_UPDATE bool "Force main display to automatic update mode" -- cgit v1.1 From 3e9ff04408483b7972240cf433c7fb4b6b88cf0a Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Thu, 14 Jan 2010 21:25:43 +0100 Subject: omapfb: Fix 12-bit display (RGB444 color mode) handling Support for RGB444 (12-bit) pixel format has been introduced into omapfb/lcdc by Mark Underwood on 2006-05-26 (commit f74edb6668aad9fc8e81585861b18f996c78a574) in preparation for Amstrad Delta (E3) videophone LCD display support. Before the Amstrad Delta LCD patch by Jonathan McDowell was applied (on 2006-08-04, commit 8d22fb2ea004cdb6379b54c1a8fd1546cfe40ed7), omapfb and lcdc code was changed substantially (commit e563dc81aa01bd8bbb01bc53975a15c398715f62 dated 2006-06-26) in a way that broke Mark's 12-bit display support. Than, a patch by Jonathan, that supposed to correct the problem, was introduced immediatelly (on 2006-08-04, commit e10a75b49e7a57ae17c28b705153c70eba15a8ef). As a result, the Amstrad Delta display was working correctly at boot time, with fbset reporting: geometry 480 320 480 320 16 ... rgba 4/8,4/4,4/0,0/0 However, after first framebuffer reinitialization, colors were no longer being displayed correctly and fbset was reporting: rgba 5/11,6/5,5/0,0/0 The patch tries to correct the issue by setting plane->color_mode depending on panel->bpp, not var->bits_per_pixel. Created and tested on Amstrad Delta against linux-2.6.33-rc3. Signed-off-by: Janusz Krzysztofik Signed-off-by: Tomi Valkeinen --- drivers/video/omap/omapfb_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c index 2c4f470..8ce60e1 100644 --- a/drivers/video/omap/omapfb_main.c +++ b/drivers/video/omap/omapfb_main.c @@ -486,10 +486,11 @@ static int set_color_mode(struct omapfb_plane_struct *plane, return 0; case 12: var->bits_per_pixel = 16; - plane->color_mode = OMAPFB_COLOR_RGB444; - return 0; case 16: - plane->color_mode = OMAPFB_COLOR_RGB565; + if (plane->fbdev->panel->bpp == 12) + plane->color_mode = OMAPFB_COLOR_RGB444; + else + plane->color_mode = OMAPFB_COLOR_RGB565; return 0; default: return -EINVAL; -- cgit v1.1 From e721032785b72afbc3da14c5525ca570bc2ed108 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Fri, 11 Dec 2009 13:21:46 +0000 Subject: omapfb: lcd_ams_delta: add support for contrast control The patch extends the Amstrad Delta LCD panel driver with optional support for changing contrast using standard LCD class device API instead of setting it silently to a default value at panel enable. It also allows for lowering power consumption by turning off OMAP_PWL_CLK_ENABLE via lcd_ops.set_power callback. Created and tested against linux-omap for-next, commit 155a75d9725e66e5ec8a383822957dee52427057. Signed-off-by: Janusz Krzysztofik Signed-off-by: Tomi Valkeinen --- drivers/video/omap/lcd_ams_delta.c | 93 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 4 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c index 567db6a..6978ae4 100644 --- a/drivers/video/omap/lcd_ams_delta.c +++ b/drivers/video/omap/lcd_ams_delta.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,71 @@ #define AMS_DELTA_DEFAULT_CONTRAST 112 +#define AMS_DELTA_MAX_CONTRAST 0x00FF +#define AMS_DELTA_LCD_POWER 0x0100 + + +/* LCD class device section */ + +static int ams_delta_lcd; + +static int ams_delta_lcd_set_power(struct lcd_device *dev, int power) +{ + if (power == FB_BLANK_UNBLANK) { + if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER)) { + omap_writeb(ams_delta_lcd & AMS_DELTA_MAX_CONTRAST, + OMAP_PWL_ENABLE); + omap_writeb(1, OMAP_PWL_CLK_ENABLE); + ams_delta_lcd |= AMS_DELTA_LCD_POWER; + } + } else { + if (ams_delta_lcd & AMS_DELTA_LCD_POWER) { + omap_writeb(0, OMAP_PWL_ENABLE); + omap_writeb(0, OMAP_PWL_CLK_ENABLE); + ams_delta_lcd &= ~AMS_DELTA_LCD_POWER; + } + } + return 0; +} + +static int ams_delta_lcd_set_contrast(struct lcd_device *dev, int value) +{ + if ((value >= 0) && (value <= AMS_DELTA_MAX_CONTRAST)) { + omap_writeb(value, OMAP_PWL_ENABLE); + ams_delta_lcd &= ~AMS_DELTA_MAX_CONTRAST; + ams_delta_lcd |= value; + } + return 0; +} + +#ifdef CONFIG_LCD_CLASS_DEVICE +static int ams_delta_lcd_get_power(struct lcd_device *dev) +{ + if (ams_delta_lcd & AMS_DELTA_LCD_POWER) + return FB_BLANK_UNBLANK; + else + return FB_BLANK_POWERDOWN; +} + +static int ams_delta_lcd_get_contrast(struct lcd_device *dev) +{ + if (!(ams_delta_lcd & AMS_DELTA_LCD_POWER)) + return 0; + + return ams_delta_lcd & AMS_DELTA_MAX_CONTRAST; +} + +static struct lcd_ops ams_delta_lcd_ops = { + .get_power = ams_delta_lcd_get_power, + .set_power = ams_delta_lcd_set_power, + .get_contrast = ams_delta_lcd_get_contrast, + .set_contrast = ams_delta_lcd_set_contrast, +}; +#endif + + +/* omapfb panel section */ + static int ams_delta_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) { @@ -48,10 +114,6 @@ static int ams_delta_panel_enable(struct lcd_panel *panel) AMS_DELTA_LATCH2_LCD_NDISP); ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, AMS_DELTA_LATCH2_LCD_VBLEN); - - omap_writeb(1, OMAP_PWL_CLK_ENABLE); - omap_writeb(AMS_DELTA_DEFAULT_CONTRAST, OMAP_PWL_ENABLE); - return 0; } @@ -91,8 +153,31 @@ static struct lcd_panel ams_delta_panel = { .get_caps = ams_delta_panel_get_caps, }; + +/* platform driver section */ + static int ams_delta_panel_probe(struct platform_device *pdev) { + struct lcd_device *lcd_device = NULL; +#ifdef CONFIG_LCD_CLASS_DEVICE + int ret; + + lcd_device = lcd_device_register("omapfb", &pdev->dev, NULL, + &ams_delta_lcd_ops); + + if (IS_ERR(lcd_device)) { + ret = PTR_ERR(lcd_device); + dev_err(&pdev->dev, "failed to register device\n"); + return ret; + } + + platform_set_drvdata(pdev, lcd_device); + lcd_device->props.max_contrast = AMS_DELTA_MAX_CONTRAST; +#endif + + ams_delta_lcd_set_contrast(lcd_device, AMS_DELTA_DEFAULT_CONTRAST); + ams_delta_lcd_set_power(lcd_device, FB_BLANK_UNBLANK); + omapfb_register_panel(&ams_delta_panel); return 0; } -- cgit v1.1 From 8a2cfea8ccb6292dc43c37968fe08475ae7c2576 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 4 Feb 2010 17:03:41 +0200 Subject: OMAP: DSS2: enable VDDS_DSI when using DPI It looks like on OMAP3 some DSS pins need VDDS_DSI to function properly. This has not been confirmed from TI, but looking at figure 15-1 "Display subsystem highlight" from the TRM, some data pins come near the DSI and SDI blocks. This is not very hard evidence, but the fact remains that with the power on, pixels are ok, and with the power off, pixels are not ok. It may also be that VDDS_SDI is needed to power some pins, but as normally both VDDS_SDI and VDDS_DSI come from the same power source, this hasn't been shown. It seems that a single driver can only get a regulator once. This patch solves it by getting all the required regulators in one place, and from which the submodules then get the regulators they need. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 66 +++++++++++++++++++++++++++++++++++++++++- drivers/video/omap2/dss/dpi.c | 55 +++++++++++++++++++++++++++++------ drivers/video/omap2/dss/dsi.c | 4 +-- drivers/video/omap2/dss/dss.h | 5 +++- drivers/video/omap2/dss/venc.c | 4 +-- 5 files changed, 117 insertions(+), 17 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 82918ee..791e1cb 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -47,6 +48,10 @@ static struct { struct clk *dss_54m_fck; struct clk *dss_96m_fck; unsigned num_clks_enabled; + + struct regulator *vdds_dsi_reg; + struct regulator *vdds_sdi_reg; + struct regulator *vdda_dac_reg; } core; static void dss_clk_enable_all_no_ctx(void); @@ -352,6 +357,50 @@ static void dss_clk_disable_all(void) dss_clk_disable(clks); } +/* REGULATORS */ + +struct regulator *dss_get_vdds_dsi(void) +{ + struct regulator *reg; + + if (core.vdds_dsi_reg != NULL) + return core.vdds_dsi_reg; + + reg = regulator_get(&core.pdev->dev, "vdds_dsi"); + if (!IS_ERR(reg)) + core.vdds_dsi_reg = reg; + + return reg; +} + +struct regulator *dss_get_vdds_sdi(void) +{ + struct regulator *reg; + + if (core.vdds_sdi_reg != NULL) + return core.vdds_sdi_reg; + + reg = regulator_get(&core.pdev->dev, "vdds_sdi"); + if (!IS_ERR(reg)) + core.vdds_sdi_reg = reg; + + return reg; +} + +struct regulator *dss_get_vdda_dac(void) +{ + struct regulator *reg; + + if (core.vdda_dac_reg != NULL) + return core.vdda_dac_reg; + + reg = regulator_get(&core.pdev->dev, "vdda_dac"); + if (!IS_ERR(reg)) + core.vdda_dac_reg = reg; + + return reg; +} + /* DEBUGFS */ #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT) static void dss_debug_dump_clocks(struct seq_file *s) @@ -473,7 +522,7 @@ static int omap_dss_probe(struct platform_device *pdev) } #endif - r = dpi_init(); + r = dpi_init(pdev); if (r) { DSSERR("Failed to initialize dpi\n"); goto fail0; @@ -901,6 +950,21 @@ static int __init omap_dss_init(void) static void __exit omap_dss_exit(void) { + if (core.vdds_dsi_reg != NULL) { + regulator_put(core.vdds_dsi_reg); + core.vdds_dsi_reg = NULL; + } + + if (core.vdds_sdi_reg != NULL) { + regulator_put(core.vdds_sdi_reg); + core.vdds_sdi_reg = NULL; + } + + if (core.vdda_dac_reg != NULL) { + regulator_put(core.vdda_dac_reg); + core.vdda_dac_reg = NULL; + } + platform_driver_unregister(&omap_dss_driver); omap_dss_bus_unregister(); diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 2d71031..69ce31a 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -25,7 +25,10 @@ #include #include #include +#include #include +#include +#include #include #include @@ -34,6 +37,7 @@ static struct { int update_enabled; + struct regulator *vdds_dsi_reg; } dpi; #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL @@ -166,21 +170,27 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) goto err1; } + if (cpu_is_omap34xx()) { + r = regulator_enable(dpi.vdds_dsi_reg); + if (r) + goto err2; + } + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); r = dpi_basic_init(dssdev); if (r) - goto err2; + goto err3; #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL dss_clk_enable(DSS_CLK_FCK2); r = dsi_pll_init(dssdev, 0, 1); if (r) - goto err3; + goto err4; #endif r = dpi_set_mode(dssdev); if (r) - goto err4; + goto err5; mdelay(2); @@ -188,22 +198,25 @@ static int dpi_display_enable(struct omap_dss_device *dssdev) r = dssdev->driver->enable(dssdev); if (r) - goto err5; + goto err6; dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; return 0; -err5: +err6: dispc_enable_lcd_out(0); -err4: +err5: #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL dsi_pll_uninit(); -err3: +err4: dss_clk_disable(DSS_CLK_FCK2); #endif -err2: +err3: dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); +err2: + if (cpu_is_omap34xx()) + regulator_disable(dpi.vdds_dsi_reg); err1: omap_dss_stop_device(dssdev); err0: @@ -232,6 +245,9 @@ static void dpi_display_disable(struct omap_dss_device *dssdev) dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + if (cpu_is_omap34xx()) + regulator_disable(dpi.vdds_dsi_reg); + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; omap_dss_stop_device(dssdev); @@ -251,6 +267,9 @@ static int dpi_display_suspend(struct omap_dss_device *dssdev) dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); + if (cpu_is_omap34xx()) + regulator_disable(dpi.vdds_dsi_reg); + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; return 0; @@ -258,11 +277,19 @@ static int dpi_display_suspend(struct omap_dss_device *dssdev) static int dpi_display_resume(struct omap_dss_device *dssdev) { + int r; + if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) return -EINVAL; DSSDBG("dpi_display_resume\n"); + if (cpu_is_omap34xx()) { + r = regulator_enable(dpi.vdds_dsi_reg); + if (r) + goto err0; + } + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); dispc_enable_lcd_out(1); @@ -273,6 +300,8 @@ static int dpi_display_resume(struct omap_dss_device *dssdev) dssdev->state = OMAP_DSS_DISPLAY_ACTIVE; return 0; +err0: + return r; } static void dpi_set_timings(struct omap_dss_device *dssdev, @@ -388,8 +417,16 @@ int dpi_init_display(struct omap_dss_device *dssdev) return 0; } -int dpi_init(void) +int dpi_init(struct platform_device *pdev) { + if (cpu_is_omap34xx()) { + dpi.vdds_dsi_reg = dss_get_vdds_dsi(); + if (IS_ERR(dpi.vdds_dsi_reg)) { + DSSERR("can't get VDDS_DSI regulator\n"); + return PTR_ERR(dpi.vdds_dsi_reg); + } + } + return 0; } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 6122178..036f422 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3799,7 +3799,7 @@ int dsi_init(struct platform_device *pdev) goto err1; } - dsi.vdds_dsi_reg = regulator_get(&pdev->dev, "vdds_dsi"); + dsi.vdds_dsi_reg = dss_get_vdds_dsi(); if (IS_ERR(dsi.vdds_dsi_reg)) { iounmap(dsi.base); DSSERR("can't get VDDS_DSI regulator\n"); @@ -3830,8 +3830,6 @@ void dsi_exit(void) { kthread_stop(dsi.thread); - regulator_put(dsi.vdds_dsi_reg); - iounmap(dsi.base); DSSDBG("omap_dsi_exit\n"); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 2bcb124..41145af 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -169,6 +169,9 @@ unsigned long dss_clk_get_rate(enum dss_clock clk); int dss_need_ctx_restore(void); void dss_dump_clocks(struct seq_file *s); struct bus_type *dss_get_bus(void); +struct regulator *dss_get_vdds_dsi(void); +struct regulator *dss_get_vdds_sdi(void); +struct regulator *dss_get_vdda_dac(void); /* display */ int dss_suspend_all_devices(void); @@ -261,7 +264,7 @@ void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, u32 *fifo_low, u32 *fifo_high); /* DPI */ -int dpi_init(void); +int dpi_init(struct platform_device *pdev); void dpi_exit(void); int dpi_init_display(struct omap_dss_device *dssdev); diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 749a5a0..44b4998 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -482,7 +482,7 @@ int venc_init(struct platform_device *pdev) return -ENOMEM; } - venc.vdda_dac_reg = regulator_get(&pdev->dev, "vdda_dac"); + venc.vdda_dac_reg = dss_get_vdda_dac(); if (IS_ERR(venc.vdda_dac_reg)) { iounmap(venc.base); DSSERR("can't get VDDA_DAC regulator\n"); @@ -503,8 +503,6 @@ void venc_exit(void) { omap_dss_unregister_driver(&venc_driver); - regulator_put(venc.vdda_dac_reg); - iounmap(venc.base); } -- cgit v1.1 From 80b1cc23ac96373bd5ff17f8959f2587d6fc37dd Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 4 Feb 2010 17:13:16 +0200 Subject: OMAP: 3430SDP: remove vdvi regulator The regulator is now enabled by DSS driver, and thus the panel driver doesn't need to touch it. Signed-off-by: Tomi Valkeinen --- .../video/omap2/displays/panel-sharp-ls037v7dw01.c | 35 ---------------------- 1 file changed, 35 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c index bbe880bb..e207d66 100644 --- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c +++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c @@ -25,14 +25,6 @@ #include -struct sharp_data { - /* XXX This regulator should actually be in SDP board file, not here, - * as it doesn't actually power the LCD, but something else that - * affects the output to LCD (I think. Somebody clarify). It doesn't do - * harm here, as SDP is the only board using this currently */ - struct regulator *vdvi_reg; -}; - static struct omap_video_timings sharp_ls_timings = { .x_res = 480, .y_res = 640, @@ -50,48 +42,25 @@ static struct omap_video_timings sharp_ls_timings = { static int sharp_ls_panel_probe(struct omap_dss_device *dssdev) { - struct sharp_data *sd; - dssdev->panel.config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS; dssdev->panel.acb = 0x28; dssdev->panel.timings = sharp_ls_timings; - sd = kzalloc(sizeof(*sd), GFP_KERNEL); - if (!sd) - return -ENOMEM; - - dev_set_drvdata(&dssdev->dev, sd); - - sd->vdvi_reg = regulator_get(&dssdev->dev, "vdvi"); - if (IS_ERR(sd->vdvi_reg)) { - kfree(sd); - pr_err("failed to get VDVI regulator\n"); - return PTR_ERR(sd->vdvi_reg); - } - return 0; } static void sharp_ls_panel_remove(struct omap_dss_device *dssdev) { - struct sharp_data *sd = dev_get_drvdata(&dssdev->dev); - - regulator_put(sd->vdvi_reg); - - kfree(sd); } static int sharp_ls_panel_enable(struct omap_dss_device *dssdev) { - struct sharp_data *sd = dev_get_drvdata(&dssdev->dev); int r = 0; /* wait couple of vsyncs until enabling the LCD */ msleep(50); - regulator_enable(sd->vdvi_reg); - if (dssdev->platform_enable) r = dssdev->platform_enable(dssdev); @@ -100,13 +69,9 @@ static int sharp_ls_panel_enable(struct omap_dss_device *dssdev) static void sharp_ls_panel_disable(struct omap_dss_device *dssdev) { - struct sharp_data *sd = dev_get_drvdata(&dssdev->dev); - if (dssdev->platform_disable) dssdev->platform_disable(dssdev); - regulator_disable(sd->vdvi_reg); - /* wait at least 5 vsyncs after disabling the LCD */ msleep(100); -- cgit v1.1 From 92fe0ff16a9299233104187bd6ceb2101501badc Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Wed, 9 Dec 2009 17:26:25 +0100 Subject: OMAP: DSS: Taal: fix error returns in taal_probe() The workqueue creation error branch attempted to destroy a NULL wq, and, in turn, a failed registration does not destroy the newly created workqueue. The problem was reported by a static analysis tool. Signed-off-by: Aaro Koskinen Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/displays/panel-taal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 1f01dfc..0aaaa8a 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -510,7 +510,7 @@ static int taal_probe(struct omap_dss_device *dssdev) if (td->esd_wq == NULL) { dev_err(&dssdev->dev, "can't create ESD workqueue\n"); r = -ENOMEM; - goto err2; + goto err1; } INIT_DELAYED_WORK_DEFERRABLE(&td->esd_work, taal_esd_work); @@ -528,7 +528,7 @@ static int taal_probe(struct omap_dss_device *dssdev) &taal_bl_ops); if (IS_ERR(bldev)) { r = PTR_ERR(bldev); - goto err1; + goto err2; } td->bldev = bldev; -- cgit v1.1 From 6dd2e42bd892b2e16080ceba451fd9c3ed633145 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 14 Jan 2010 17:32:13 +0200 Subject: OMAP: DSS2: OMAPFB: implement OMAPFB_GET_DISPLAY_INFO Previously the only place to get the size of the display was from the DSS's sysfs interface, making, for example, configuring overlays and doing updates on manual displays more difficult. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/omapfb/omapfb-ioctl.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers/video') diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index 4c4bafd..33fc145 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -483,6 +483,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) struct omapfb_memory_read memory_read; struct omapfb_vram_info vram_info; struct omapfb_tearsync_info tearsync_info; + struct omapfb_display_info display_info; } p; int r = 0; @@ -741,6 +742,29 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) break; } + case OMAPFB_GET_DISPLAY_INFO: { + u16 xres, yres; + + DBG("ioctl GET_DISPLAY_INFO\n"); + + if (display == NULL) { + r = -ENODEV; + break; + } + + display->get_resolution(display, &xres, &yres); + + p.display_info.xres = xres; + p.display_info.yres = yres; + p.display_info.width = 0; + p.display_info.height = 0; + + if (copy_to_user((void __user *)arg, &p.display_info, + sizeof(p.display_info))) + r = -EFAULT; + break; + } + default: dev_err(fbdev->dev, "Unknown ioctl 0x%x\n", cmd); r = -EINVAL; -- cgit v1.1 From 853525d7785761d2d9c121b41326ab19d3af4a22 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 8 Feb 2010 12:19:46 +0200 Subject: OMAP: DSS2: fix irq-stats compilation Fix compilation of the CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS feature. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 4 +++- drivers/video/omap2/dss/dispc.c | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 791e1cb..5939da9 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -446,10 +446,12 @@ static int dss_initialize_debugfs(void) debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir, &dss_debug_dump_clocks, &dss_debug_fops); +#ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS debugfs_create_file("dispc_irq", S_IRUGO, dss_debugfs_dir, &dispc_dump_irqs, &dss_debug_fops); +#endif -#ifdef CONFIG_OMAP2_DSS_DSI +#if defined(CONFIG_OMAP2_DSS_DSI) && defined(CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS) debugfs_create_file("dsi_irq", S_IRUGO, dss_debugfs_dir, &dsi_dump_irqs, &dss_debug_fops); #endif diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index de8bfba..7781c65 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -2301,8 +2301,6 @@ void dispc_dump_irqs(struct seq_file *s) PIS(WAKEUP); #undef PIS } -#else -void dispc_dump_irqs(struct seq_file *s) { } #endif void dispc_dump_regs(struct seq_file *s) -- cgit v1.1 From b63c97f5184684c841be84ec80928e3c5fe57fbe Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 5 Feb 2010 14:46:19 +0200 Subject: OMAP: DSS2: OMAPFB: Add omapfb_update_window prototype Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/omapfb/omapfb.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/video') diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h index f7c9c73..4ae0b64 100644 --- a/drivers/video/omap2/omapfb/omapfb.h +++ b/drivers/video/omap2/omapfb/omapfb.h @@ -105,6 +105,9 @@ void omapfb_remove_sysfs(struct omapfb2_device *fbdev); int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg); +int omapfb_update_window(struct fb_info *fbi, + u32 x, u32 y, u32 w, u32 h); + int dss_mode_to_fb_mode(enum omap_color_mode dssmode, struct fb_var_screeninfo *var); -- cgit v1.1 From 2f18c4d89861fc1abdfa2531ba76017acb78edc5 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 8 Jan 2010 18:00:36 +0200 Subject: OMAP: DSS2: improve DSS clk src selection dss_select_clk_source() was rather confusing. Selecting the source with enums is much clearer. The clk source selection is also stored into memory, so that we know what is the selected source, even when clocks are off. This is important during setup, as we need to what clocks to turn on before the clocks are turned on. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dpi.c | 4 ++-- drivers/video/omap2/dss/dsi.c | 9 ++++++--- drivers/video/omap2/dss/dss.c | 42 ++++++++++++++++++++++++++++++++---------- drivers/video/omap2/dss/dss.h | 14 +++++++++++--- 4 files changed, 51 insertions(+), 18 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 69ce31a..c5091ed 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -57,7 +57,7 @@ static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req, if (r) return r; - dss_select_clk_source(0, 1); + dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); r = dispc_set_clock_div(&dispc_cinfo); if (r) @@ -238,7 +238,7 @@ static void dpi_display_disable(struct omap_dss_device *dssdev) dispc_enable_lcd_out(0); #ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL - dss_select_clk_source(0, 0); + dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); dsi_pll_uninit(); dss_clk_disable(DSS_CLK_FCK2); #endif diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 036f422..4fdb628 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -3203,7 +3203,8 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) if (r) goto err1; - dss_select_clk_source(true, true); + dss_select_dispc_clk_source(DSS_SRC_DSI1_PLL_FCLK); + dss_select_dsi_clk_source(DSS_SRC_DSI2_PLL_FCLK); DSSDBG("PLL OK\n"); @@ -3247,7 +3248,8 @@ err4: err3: dsi_complexio_uninit(); err2: - dss_select_clk_source(false, false); + dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); + dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); err1: dsi_pll_uninit(); err0: @@ -3259,7 +3261,8 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev) if (dssdev->driver->disable) dssdev->driver->disable(dssdev); - dss_select_clk_source(false, false); + dss_select_dispc_clk_source(DSS_SRC_DSS1_ALWON_FCLK); + dss_select_dsi_clk_source(DSS_SRC_DSS1_ALWON_FCLK); dsi_complexio_uninit(); dsi_pll_uninit(); } diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 0a26b7d..8254a42 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -68,6 +68,9 @@ static struct { struct dss_clock_info cache_dss_cinfo; struct dispc_clock_info cache_dispc_cinfo; + enum dss_clk_source dsi_clk_source; + enum dss_clk_source dispc_clk_source; + u32 ctx[DSS_SZ_REGS / sizeof(u32)]; } dss; @@ -247,23 +250,42 @@ void dss_dump_regs(struct seq_file *s) #undef DUMPREG } -void dss_select_clk_source(bool dsi, bool dispc) +void dss_select_dispc_clk_source(enum dss_clk_source clk_src) +{ + int b; + + BUG_ON(clk_src != DSS_SRC_DSI1_PLL_FCLK && + clk_src != DSS_SRC_DSS1_ALWON_FCLK); + + b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; + + REG_FLD_MOD(DSS_CONTROL, b, 0, 0); /* DISPC_CLK_SWITCH */ + + dss.dispc_clk_source = clk_src; +} + +void dss_select_dsi_clk_source(enum dss_clk_source clk_src) { - u32 r; - r = dss_read_reg(DSS_CONTROL); - r = FLD_MOD(r, dsi, 1, 1); /* DSI_CLK_SWITCH */ - r = FLD_MOD(r, dispc, 0, 0); /* DISPC_CLK_SWITCH */ - dss_write_reg(DSS_CONTROL, r); + int b; + + BUG_ON(clk_src != DSS_SRC_DSI2_PLL_FCLK && + clk_src != DSS_SRC_DSS1_ALWON_FCLK); + + b = clk_src == DSS_SRC_DSS1_ALWON_FCLK ? 0 : 1; + + REG_FLD_MOD(DSS_CONTROL, b, 1, 1); /* DSI_CLK_SWITCH */ + + dss.dsi_clk_source = clk_src; } -int dss_get_dsi_clk_source(void) +enum dss_clk_source dss_get_dispc_clk_source(void) { - return FLD_GET(dss_read_reg(DSS_CONTROL), 1, 1); + return dss.dispc_clk_source; } -int dss_get_dispc_clk_source(void) +enum dss_clk_source dss_get_dsi_clk_source(void) { - return FLD_GET(dss_read_reg(DSS_CONTROL), 0, 0); + return dss.dsi_clk_source; } /* calculate clock rates using dividers in cinfo */ diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 41145af..3713dc6 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -119,6 +119,12 @@ enum dss_clock { DSS_CLK_96M = 1 << 4, }; +enum dss_clk_source { + DSS_SRC_DSI1_PLL_FCLK, + DSS_SRC_DSI2_PLL_FCLK, + DSS_SRC_DSS1_ALWON_FCLK, +}; + struct dss_clock_info { /* rates that we get with dividers below */ unsigned long fck; @@ -219,9 +225,11 @@ void dss_sdi_init(u8 datapairs); int dss_sdi_enable(void); void dss_sdi_disable(void); -void dss_select_clk_source(bool dsi, bool dispc); -int dss_get_dsi_clk_source(void); -int dss_get_dispc_clk_source(void); +void dss_select_dispc_clk_source(enum dss_clk_source clk_src); +void dss_select_dsi_clk_source(enum dss_clk_source clk_src); +enum dss_clk_source dss_get_dispc_clk_source(void); +enum dss_clk_source dss_get_dsi_clk_source(void); + void dss_set_venc_output(enum omap_dss_venc_type type); void dss_set_dac_pwrdn_bgz(bool enable); -- cgit v1.1 From 4f76502374ff91bc80a48a32cabb1009087a3b9d Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 18 Jan 2010 16:27:52 +0200 Subject: OMAP: DSS2: DSI: add dsi_bus_is_locked() Helper function to clean up the checking of the bus lock. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 4fdb628..b389745 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -309,6 +309,11 @@ void dsi_bus_unlock(void) } EXPORT_SYMBOL(dsi_bus_unlock); +static bool dsi_bus_is_locked(void) +{ + return mutex_is_locked(&dsi.bus_lock); +} + static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum, int value) { @@ -1959,7 +1964,7 @@ static int dsi_vc_send_bta(int channel) (dsi.debug_write || dsi.debug_read)) DSSDBG("dsi_vc_send_bta %d\n", channel); - WARN_ON(!mutex_is_locked(&dsi.bus_lock)); + WARN_ON(!dsi_bus_is_locked()); if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */ DSSERR("rx fifo not empty when sending BTA, dumping data:\n"); @@ -2010,7 +2015,7 @@ static inline void dsi_vc_write_long_header(int channel, u8 data_type, u32 val; u8 data_id; - WARN_ON(!mutex_is_locked(&dsi.bus_lock)); + WARN_ON(!dsi_bus_is_locked()); /*data_id = data_type | channel << 6; */ data_id = data_type | dsi.vc[channel].dest_per << 6; @@ -2105,7 +2110,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc) u32 r; u8 data_id; - WARN_ON(!mutex_is_locked(&dsi.bus_lock)); + WARN_ON(!dsi_bus_is_locked()); if (dsi.debug_write) DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n", @@ -2895,7 +2900,7 @@ static int dsi_set_update_mode(struct omap_dss_device *dssdev, int r = 0; int i; - WARN_ON(!mutex_is_locked(&dsi.bus_lock)); + WARN_ON(!dsi_bus_is_locked()); if (dsi.update_mode != mode) { dsi.update_mode = mode; -- cgit v1.1 From 828c48f8c51ebfc2a00e1a834b0bc9e7fd35060f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Dec 2009 14:53:15 +0200 Subject: OMAP: DSS2: DSI: add helpers for DCS read/write Add helper functions for most common DCS read and write operations. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index b389745..e49f063 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -2176,6 +2176,21 @@ int dsi_vc_dcs_write(int channel, u8 *data, int len) } EXPORT_SYMBOL(dsi_vc_dcs_write); +int dsi_vc_dcs_write_0(int channel, u8 dcs_cmd) +{ + return dsi_vc_dcs_write(channel, &dcs_cmd, 1); +} +EXPORT_SYMBOL(dsi_vc_dcs_write_0); + +int dsi_vc_dcs_write_1(int channel, u8 dcs_cmd, u8 param) +{ + u8 buf[2]; + buf[0] = dcs_cmd; + buf[1] = param; + return dsi_vc_dcs_write(channel, buf, 2); +} +EXPORT_SYMBOL(dsi_vc_dcs_write_1); + int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) { u32 val; @@ -2268,6 +2283,21 @@ int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen) } EXPORT_SYMBOL(dsi_vc_dcs_read); +int dsi_vc_dcs_read_1(int channel, u8 dcs_cmd, u8 *data) +{ + int r; + + r = dsi_vc_dcs_read(channel, dcs_cmd, data, 1); + + if (r < 0) + return r; + + if (r != 1) + return -EIO; + + return 0; +} +EXPORT_SYMBOL(dsi_vc_dcs_read_1); int dsi_vc_set_max_rx_packet_size(int channel, u16 len) { -- cgit v1.1 From 61140c9a88ce1f1dee4e98a0c442f9a84b4c5e6b Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 12 Jan 2010 16:00:30 +0200 Subject: OMAP: DSS2: DSI: export dsi_vc_enable_hs() Rename and export dsi_vc_enable_hs() so that the display drivers can control the mode of the DSI link. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index e49f063..e003fe9 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1864,10 +1864,12 @@ static void dsi_vc_config_vp(int channel) } -static void dsi_vc_enable_hs(int channel, bool enable) +void omapdss_dsi_vc_enable_hs(int channel, bool enable) { DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable); + WARN_ON(!dsi_bus_is_locked()); + dsi_vc_enable(channel, 0); dsi_if_enable(0); @@ -1878,6 +1880,7 @@ static void dsi_vc_enable_hs(int channel, bool enable) dsi_force_tx_stop_mode_io(); } +EXPORT_SYMBOL(omapdss_dsi_vc_enable_hs); static void dsi_vc_flush_long_data(int channel) { @@ -3275,7 +3278,7 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) } /* enable high-speed after initial config */ - dsi_vc_enable_hs(0, 1); + omapdss_dsi_vc_enable_hs(0, 1); return 0; err4: @@ -3688,7 +3691,7 @@ static int dsi_display_run_test(struct omap_dss_device *dssdev, int test_num) dsi_bus_lock(); /* run test first in low speed mode */ - dsi_vc_enable_hs(0, 0); + omapdss_dsi_vc_enable_hs(0, 0); if (dssdev->driver->run_test) { r = dssdev->driver->run_test(dssdev, test_num); @@ -3697,7 +3700,7 @@ static int dsi_display_run_test(struct omap_dss_device *dssdev, int test_num) } /* then in high speed */ - dsi_vc_enable_hs(0, 1); + omapdss_dsi_vc_enable_hs(0, 1); if (dssdev->driver->run_test) { r = dssdev->driver->run_test(dssdev, test_num); @@ -3706,7 +3709,7 @@ static int dsi_display_run_test(struct omap_dss_device *dssdev, int test_num) } end: - dsi_vc_enable_hs(0, 1); + omapdss_dsi_vc_enable_hs(0, 1); dsi_bus_unlock(); -- cgit v1.1 From dd8079d6a9c2aa292dacaf1b42f526558e20379f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Dec 2009 16:49:03 +0200 Subject: OMAP: DSS2: DSI: configure all DSI VCs Instead of configuring only VC0 to be usable, configure all four VCs similarly. This is needed to utilize the other VCs. Setting the FIFO sizes evenly for all VCs, regardless of how many VCs are actually used, is not optimal. However, this affects only cases when larger amounts of data are written or read via L4, meaning that normal use cases are not affected. At some point this could be optimized better to suit different use cases. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index e003fe9..131bd53 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -224,7 +224,6 @@ static struct enum dsi_vc_mode mode; struct omap_dss_device *dssdev; enum fifo_size fifo_size; - int dest_per; /* destination peripheral 0-3 */ } vc[4]; struct mutex lock; @@ -2020,8 +2019,7 @@ static inline void dsi_vc_write_long_header(int channel, u8 data_type, WARN_ON(!dsi_bus_is_locked()); - /*data_id = data_type | channel << 6; */ - data_id = data_type | dsi.vc[channel].dest_per << 6; + data_id = data_type | channel << 6; val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) | FLD_VAL(ecc, 31, 24); @@ -2127,7 +2125,7 @@ static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc) return -EINVAL; } - data_id = data_type | dsi.vc[channel].dest_per << 6; + data_id = data_type | channel << 6; r = (data_id << 0) | (data << 8) | (ecc << 24); @@ -2529,15 +2527,15 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) u32 r; int buswidth = 0; - dsi_config_tx_fifo(DSI_FIFO_SIZE_128, - DSI_FIFO_SIZE_0, - DSI_FIFO_SIZE_0, - DSI_FIFO_SIZE_0); + dsi_config_tx_fifo(DSI_FIFO_SIZE_32, + DSI_FIFO_SIZE_32, + DSI_FIFO_SIZE_32, + DSI_FIFO_SIZE_32); - dsi_config_rx_fifo(DSI_FIFO_SIZE_128, - DSI_FIFO_SIZE_0, - DSI_FIFO_SIZE_0, - DSI_FIFO_SIZE_0); + dsi_config_rx_fifo(DSI_FIFO_SIZE_32, + DSI_FIFO_SIZE_32, + DSI_FIFO_SIZE_32, + DSI_FIFO_SIZE_32); /* XXX what values for the timeouts? */ dsi_set_stop_state_counter(1000); @@ -2575,12 +2573,9 @@ static int dsi_proto_config(struct omap_dss_device *dssdev) dsi_write_reg(DSI_CTRL, r); dsi_vc_initial_config(0); - - /* set all vc targets to peripheral 0 */ - dsi.vc[0].dest_per = 0; - dsi.vc[1].dest_per = 0; - dsi.vc[2].dest_per = 0; - dsi.vc[3].dest_per = 0; + dsi_vc_initial_config(1); + dsi_vc_initial_config(2); + dsi_vc_initial_config(3); return 0; } @@ -2846,9 +2841,6 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev, if (bytespf % packet_payload) total_len += (bytespf % packet_payload) + 1; - if (0) - dsi_vc_print_status(1); - l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */ dsi_write_reg(DSI_VC_TE(channel), l); @@ -3014,7 +3006,7 @@ static void dsi_handle_framedone(void) /* RX_FIFO_NOT_EMPTY */ if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { DSSERR("Received error during frame transfer:\n"); - dsi_vc_flush_receive_data(0); + dsi_vc_flush_receive_data(channel); } #ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC @@ -3268,6 +3260,9 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev) /* enable interface */ dsi_vc_enable(0, 1); + dsi_vc_enable(1, 1); + dsi_vc_enable(2, 1); + dsi_vc_enable(3, 1); dsi_if_enable(1); dsi_force_tx_stop_mode_io(); -- cgit v1.1 From 6eed73debf5840a42ebe9ea90958d2ce4a38c6b0 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 5 Feb 2010 14:44:05 +0200 Subject: OMAP: DSS2: DSI: remove dsi_vc_print_status() It was not used. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dsi.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index 131bd53..4b85ed2 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1760,24 +1760,6 @@ static int dsi_force_tx_stop_mode_io(void) return 0; } -static void dsi_vc_print_status(int channel) -{ - u32 r; - - r = dsi_read_reg(DSI_VC_CTRL(channel)); - DSSDBG("vc %d: TX_FIFO_NOT_EMPTY %d, BTA_EN %d, VC_BUSY %d, " - "TX_FIFO_FULL %d, RX_FIFO_NOT_EMPTY %d, ", - channel, - FLD_GET(r, 5, 5), - FLD_GET(r, 6, 6), - FLD_GET(r, 15, 15), - FLD_GET(r, 16, 16), - FLD_GET(r, 20, 20)); - - r = dsi_read_reg(DSI_TX_FIFO_VC_EMPTINESS); - DSSDBG("EMPTINESS %d\n", (r >> (8 * channel)) & 0xff); -} - static int dsi_vc_enable(int channel, bool enable) { if (dsi.update_mode != OMAP_DSS_UPDATE_AUTO) @@ -2062,13 +2044,10 @@ static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len, dsi_vc_write_long_header(channel, data_type, len, ecc); - /*dsi_vc_print_status(0); */ - p = data; for (i = 0; i < len >> 2; i++) { if (dsi.debug_write) DSSDBG("\tsending full packet %d\n", i); - /*dsi_vc_print_status(0); */ b1 = *p++; b2 = *p++; -- cgit v1.1 From e296264977f68ddf395b8f93f8e174930f88499a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 1 Dec 2009 13:23:25 +0200 Subject: OMAP: DSS2: Check ctx loss count only when starting the first clock When OMAP PM layer is no-op/debug, the PM layer will increment context loss count with every call. This resulted DSS2 to restore context whenever a clock was enabled. This commit checks the context loss count only when the context actually could have been lost, ie. when enabling a clock when no clocks had been previously enabled. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 5939da9..72547df 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -289,9 +289,11 @@ static void dss_clk_enable_no_ctx(enum dss_clock clks) void dss_clk_enable(enum dss_clock clks) { + bool check_ctx = core.num_clks_enabled == 0; + dss_clk_enable_no_ctx(clks); - if (cpu_is_omap34xx() && dss_need_ctx_restore()) + if (check_ctx && cpu_is_omap34xx() && dss_need_ctx_restore()) restore_all_ctx(); } -- cgit v1.1 From 40331b21f5fdb746e80fc609ef60ef71b5cd47d9 Mon Sep 17 00:00:00 2001 From: Phil Edworthy Date: Mon, 15 Feb 2010 13:57:49 +0000 Subject: video: sh_mobile_lcdcfb: Add wait for vsync. Added FBIO_WAITFORVSYNC ioctl for SH-Mobile devices. Tested on MS7724 and MigoR boards against 2.6.33-rc7. Signed-off-by: Phil Edworthy Signed-off-by: Paul Mundt --- drivers/video/sh_mobile_lcdcfb.c | 48 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) (limited to 'drivers/video') diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index a69830d..37aeced 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c @@ -19,6 +19,7 @@ #include #include #include +#include #include