beagleboard: added 2.6.29 kernel from OE

tested on B7

Signed-off-by: Marcin Juszkiewicz <marcin@buglabs.net>
This commit is contained in:
Marcin Juszkiewicz 2009-04-27 16:41:24 +02:00
parent d65be3dd2a
commit 0adc74b062
146 changed files with 156117 additions and 1 deletions

View File

@ -23,7 +23,7 @@ EXTRA_IMAGECMD_jffs2 = "-lnp "
SERIAL_CONSOLE = "115200 ttyS2"
# No kernel recipe yet
PREFERRED_PROVIDER_virtual/kernel = "linux-omap2"
PREFERRED_PROVIDER_virtual/kernel = "linux-omap"
KERNEL_IMAGETYPE = "uImage"

View File

@ -0,0 +1,206 @@
From c1dad0b6b434300ae64c902d11611c54c513ea10 Mon Sep 17 00:00:00 2001
From: Anuj Aggarwal <anuj.aggarwal@ti.com>
Date: Fri, 21 Nov 2008 17:41:03 +0530
Subject: [PATCH] ASoC: Add support for OMAP3 EVM
This patch adds ALSA SoC support for OMAP3 EVM using TWL4030 audio codec.
Signed-off-by: Anuj Aggarwal <anuj.aggarwal@ti.com>
---
sound/soc/omap/Kconfig | 8 +++
sound/soc/omap/Makefile | 3 +-
sound/soc/omap/omap3evm.c | 147 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 157 insertions(+), 1 deletions(-)
create mode 100644 sound/soc/omap/omap3evm.c
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 0daeee4..deb6ba9 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -22,6 +22,14 @@ config SND_OMAP_SOC_OMAP3_BEAGLE
help
Say Y if you want to add support for SoC audio on the Beagleboard.
+config SND_OMAP_SOC_OMAP3EVM
+ tristate "SoC Audio support for OMAP3EVM board"
+ depends on SND_OMAP_SOC && MACH_OMAP3EVM
+ select SND_OMAP_SOC_MCBSP
+ select SND_SOC_TWL4030
+ help
+ Say Y if you want to add support for SoC audio on the omap3evm board.
+
config SND_OMAP_SOC_OSK5912
tristate "SoC Audio support for omap osk5912"
depends on SND_OMAP_SOC && MACH_OMAP_OSK
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 4bae404..ef31c25 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -10,9 +10,10 @@ snd-soc-n810-objs := n810.o
snd-soc-omap3beagle-objs := omap3beagle.o
snd-soc-osk5912-objs := osk5912.o
snd-soc-overo-objs := overo.o
+snd-soc-omap3evm-objs := omap3evm.o
obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
-
+obj-$(CONFIG_MACH_OMAP3EVM) += snd-soc-omap3evm.o
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
new file mode 100644
index 0000000..570af55
--- /dev/null
+++ b/sound/soc/omap/omap3evm.c
@@ -0,0 +1,147 @@
+/*
+ * omap3evm.c -- ALSA SoC support for OMAP3 EVM
+ *
+ * Author: Anuj Aggarwal <anuj.aggarwal@ti.com>
+ *
+ * Based on sound/soc/omap/beagle.c by Steve Sakoman
+ *
+ * Copyright (C) 2008 Texas Instruments, Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
+ * whether express or implied; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/mcbsp.h>
+
+#include "omap-mcbsp.h"
+#include "omap-pcm.h"
+#include "../codecs/twl4030.h"
+
+static int omap3evm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
+ int ret;
+
+ /* Set codec DAI configuration */
+ ret = snd_soc_dai_set_fmt(codec_dai,
+ SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM);
+ if (ret < 0) {
+ printk(KERN_ERR "can't set codec DAI configuration\n");
+ return ret;
+ }
+
+ /* Set cpu DAI configuration */
+ ret = snd_soc_dai_set_fmt(cpu_dai,
+ SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBM_CFM);
+ if (ret < 0) {
+ printk(KERN_ERR "can't set cpu DAI configuration\n");
+ return ret;
+ }
+
+ /* Set the codec system clock for DAC and ADC */
+ ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
+ SND_SOC_CLOCK_IN);
+ if (ret < 0) {
+ printk(KERN_ERR "can't set codec system clock\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static struct snd_soc_ops omap3evm_ops = {
+ .hw_params = omap3evm_hw_params,
+};
+
+/* Digital audio interface glue - connects codec <--> CPU */
+static struct snd_soc_dai_link omap3evm_dai = {
+ .name = "TWL4030",
+ .stream_name = "TWL4030",
+ .cpu_dai = &omap_mcbsp_dai[0],
+ .codec_dai = &twl4030_dai,
+ .ops = &omap3evm_ops,
+};
+
+/* Audio machine driver */
+static struct snd_soc_machine snd_soc_machine_omap3evm = {
+ .name = "omap3evm",
+ .dai_link = &omap3evm_dai,
+ .num_links = 1,
+};
+
+/* Audio subsystem */
+static struct snd_soc_device omap3evm_snd_devdata = {
+ .machine = &snd_soc_machine_omap3evm,
+ .platform = &omap_soc_platform,
+ .codec_dev = &soc_codec_dev_twl4030,
+};
+
+static struct platform_device *omap3evm_snd_device;
+
+static int __init omap3evm_soc_init(void)
+{
+ int ret;
+
+ if (!machine_is_omap3evm()) {
+ pr_debug("Not OMAP3 EVM!\n");
+ return -ENODEV;
+ }
+ pr_info("OMAP3 EVM SoC init\n");
+
+ omap3evm_snd_device = platform_device_alloc("soc-audio", -1);
+ if (!omap3evm_snd_device) {
+ printk(KERN_ERR "Platform device allocation failed\n");
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(omap3evm_snd_device, &omap3evm_snd_devdata);
+ omap3evm_snd_devdata.dev = &omap3evm_snd_device->dev;
+ *(unsigned int *)omap3evm_dai.cpu_dai->private_data = 1; /* McBSP2 */
+
+ ret = platform_device_add(omap3evm_snd_device);
+ if (ret)
+ goto err1;
+
+ return 0;
+
+err1:
+ printk(KERN_ERR "Unable to add platform device\n");
+ platform_device_put(omap3evm_snd_device);
+
+ return ret;
+}
+
+static void __exit omap3evm_soc_exit(void)
+{
+ platform_device_unregister(omap3evm_snd_device);
+}
+
+module_init(omap3evm_soc_init);
+module_exit(omap3evm_soc_exit);
+
+MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>");
+MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM");
+MODULE_LICENSE("GPL");
--
1.5.6.5

View File

@ -0,0 +1,146 @@
From f8f10f496bce396416d7156da876222c6ce8c341 Mon Sep 17 00:00:00 2001
From: Steven Kipisz <skipisz@beagleboard.org>
Date: Wed, 9 Jan 2009 12:01:11 -0600
Subject: [PATCH-USB] Omap3 beagleboard: add support for EHCI in revision C1 boards
Signed-off-by: Jason Kridner <jkridner@beagleboard.org>
---
arch/arm/mach-omap2/board-omap3beagle.c | 10 +---------
arch/arm/mach-omap2/usb-ehci.c | 4 +---
drivers/usb/host/ehci-omap.c | 26 ++++++++++++++++++++++++++
3 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index fe97bab..de81153 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -140,15 +140,7 @@ static int beagle_twl_gpio_setup(struct device *dev,
* power switch and overcurrent detect
*/
- gpio_request(gpio + 1, "EHCI_nOC");
- gpio_direction_input(gpio + 1);
-
- /* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
- gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
- gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
-
- /* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
- gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+ /* TODO: This needs to be modified to not rely on u-boot */
return 0;
}
diff --git a/arch/arm/mach-omap2/usb-ehci.c b/arch/arm/mach-omap2/usb-ehci.c
index 489439d..2c6305b 100644
--- a/arch/arm/mach-omap2/usb-ehci.c
+++ b/arch/arm/mach-omap2/usb-ehci.c
@@ -152,9 +152,7 @@ static void setup_ehci_io_mux(void)
void __init usb_ehci_init(void)
{
#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
- /* Setup Pin IO MUX for EHCI */
- if (cpu_is_omap34xx())
- setup_ehci_io_mux();
+ /* TODO: Setup Pin IO MUX for EHCI - moved this temporarily to U-boot */
if (platform_device_register(&ehci_device) < 0) {
printk(KERN_ERR "Unable to register HS-USB (EHCI) device\n");
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index 1b3266c..8472996 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -48,16 +48,26 @@
* to get the PHY state machine in working state
*/
#define EXTERNAL_PHY_RESET
+#ifdef CONFIG_MACH_OMAP3_BEAGLE
+#define EXT_PHY_RESET_GPIO_PORT2 (147)
+#else
#define EXT_PHY_RESET_GPIO_PORT1 (57)
#define EXT_PHY_RESET_GPIO_PORT2 (61)
+#endif
#define EXT_PHY_RESET_DELAY (10)
+#define PHY_STP_PULLUP_ENABLE (0x10)
+#define PHY_STP_PULLUP_DISABLE (0x90)
+
+
/* ISSUE2:
* USBHOST supports External charge pump PHYs only
* Use the VBUS from Port1 to power VBUS of Port2 externally
* So use Port2 as the working ULPI port
*/
+#ifndef CONFIG_MACH_OMAP3_BEAGLE
#define VBUS_INTERNAL_CHARGEPUMP_HACK
+#endif
#endif /* CONFIG_OMAP_EHCI_PHY_MODE */
@@ -225,14 +235,43 @@ static int omap_start_ehc(struct platform_device *dev, struct usb_hcd *hcd)
#ifdef EXTERNAL_PHY_RESET
/* Refer: ISSUE1 */
+#ifndef CONFIG_MACH_OMAP3_BEAGLE
gpio_request(EXT_PHY_RESET_GPIO_PORT1, "USB1 PHY reset");
gpio_direction_output(EXT_PHY_RESET_GPIO_PORT1, 0);
+#endif
gpio_request(EXT_PHY_RESET_GPIO_PORT2, "USB2 PHY reset");
gpio_direction_output(EXT_PHY_RESET_GPIO_PORT2, 0);
+ gpio_set_value(EXT_PHY_RESET_GPIO_PORT2, 0);
/* Hold the PHY in RESET for enough time till DIR is high */
udelay(EXT_PHY_RESET_DELAY);
#endif
+ /*
+ * The PHY register 0x7 - Interface Control register is
+ * configured to disable the integrated STP pull-up resistor
+ * used for interface protection.
+ *
+ * May not need to be here.
+ */
+ omap_writel((0x7 << EHCI_INSNREG05_ULPI_REGADD_SHIFT) |/* interface reg */
+ (2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT) |/* Write */
+ (1 << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT) |/* Port1 */
+ (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT) |/* Start */
+ (PHY_STP_PULLUP_DISABLE),
+ EHCI_INSNREG05_ULPI);
+
+ while (!(omap_readl(EHCI_INSNREG05_ULPI) & (1<<EHCI_INSNREG05_ULPI_CONTROL_SHIFT)));
+
+ /* Force PHY to HS */
+ omap_writel((0x4 << EHCI_INSNREG05_ULPI_REGADD_SHIFT) |/* function ctrl */
+ (2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT) |/* Write */
+ (1 << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT) |/* Port1 */
+ (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT) |/* Start */
+ (0x40),
+ EHCI_INSNREG05_ULPI);
+
+ while (!(omap_readl(EHCI_INSNREG05_ULPI) & (1<<EHCI_INSNREG05_ULPI_CONTROL_SHIFT)));
+
/* Configure TLL for 60Mhz clk for ULPI */
ehci_clocks->usbtll_fck_clk = clk_get(&dev->dev, USBHOST_TLL_FCLK);
if (IS_ERR(ehci_clocks->usbtll_fck_clk))
@@ -307,7 +346,9 @@ static int omap_start_ehc(struct platform_device *dev, struct usb_hcd *hcd)
* Hold the PHY in RESET for enough time till PHY is settled and ready
*/
udelay(EXT_PHY_RESET_DELAY);
+#ifndef CONFIG_MACH_OMAP3_BEAGLE
gpio_set_value(EXT_PHY_RESET_GPIO_PORT1, 1);
+#endif
gpio_set_value(EXT_PHY_RESET_GPIO_PORT2, 1);
#endif
@@ -393,7 +434,9 @@ static void omap_stop_ehc(struct platform_device *dev, struct usb_hcd *hcd)
#ifdef EXTERNAL_PHY_RESET
+#ifndef CONFIG_MACH_OMAP3_BEAGLE
gpio_free(EXT_PHY_RESET_GPIO_PORT1);
+#endif
gpio_free(EXT_PHY_RESET_GPIO_PORT2);
#endif
--
1.6.0.4.790.gaa14a

View File

@ -0,0 +1,90 @@
From 7efa7cc5b807cb840c62b5bf54bf47181c9b95a6 Mon Sep 17 00:00:00 2001
From: Koen Kooi <koen@openembedded.org>
Date: Mon, 30 Mar 2009 15:21:37 +0200
Subject: [PATCH v2] ARM: OMAP: board-ldp: add regulator info to get the microSD slot working again
The ldp board was left behind when other boards got updated. The ldp info was copied from the beagleboard board file and s/beagle/ldp/g
Changes since v1:
* dropped vsim portion since only 4 pins are hooked up
Signed-off-by: Koen Kooi <koen@beagleboard.org>
---
arch/arm/mach-omap2/board-ldp.c | 32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/board-ldp.c b/arch/arm/mach-omap2/board-ldp.c
index 30926b0..19a5c15 100644
--- a/arch/arm/mach-omap2/board-ldp.c
+++ b/arch/arm/mach-omap2/board-ldp.c
@@ -22,6 +22,7 @@
#include <linux/clk.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
+#include <linux/regulator/machine.h>
#include <linux/i2c/twl4030.h>
#include <mach/hardware.h>
@@ -450,7 +451,16 @@ static struct twl4030_script *twl4030_scripts[] __initdata = {
&wrst_script,
};
+static const struct twl4030_resconfig ldp_resconfig[] = {
+ /* disable regulators that u-boot left enabled; the
+ * devices' drivers should be managing these.
+ */
+ { .resource = RES_VMMC1, },
+ { 0, },
+};
+
static struct twl4030_power_data sdp3430_t2scripts_data __initdata = {
+ .resource_config = ldp_resconfig,
.scripts = twl4030_scripts,
.size = ARRAY_SIZE(twl4030_scripts),
};
@@ -474,6 +484,25 @@ static struct twl4030_madc_platform_data ldp_madc_data = {
.irq_line = 1,
};
+static struct regulator_consumer_supply ldp_vmmc1_supply = {
+ .supply = "vmmc",
+};
+
+/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
+static struct regulator_init_data ldp_vmmc1 = {
+ .constraints = {
+ .min_uV = 1850000,
+ .max_uV = 3150000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &ldp_vmmc1_supply,
+};
+
static struct twl4030_platform_data ldp_twldata = {
.irq_base = TWL4030_IRQ_BASE,
.irq_end = TWL4030_IRQ_END,
@@ -483,6 +512,7 @@ static struct twl4030_platform_data ldp_twldata = {
.madc = &ldp_madc_data,
.usb = &ldp_usb_data,
.power = &sdp3430_t2scripts_data,
+ .vmmc1 = &ldp_vmmc1,
.gpio = &ldp_gpio_data,
.keypad = &ldp_kp_twl4030_data,
};
@@ -530,6 +560,8 @@ static void __init omap_ldp_init(void)
omap_serial_init();
usb_musb_init();
twl4030_mmc_init(mmc);
+ /* link regulators to MMC adapters */
+ ldp_vmmc1_supply.dev = mmc[0].dev;
}
static void __init omap_ldp_map_io(void)
--
1.6.2

View File

@ -0,0 +1,79 @@
From c810e850d830330cf04225a4cff8e981e153f269 Mon Sep 17 00:00:00 2001
From: David Brownell <david-b@pacbell.net>
Date: Mon, 23 Feb 2009 14:08:14 -0800
Subject: [PATCH 124/133] leds-gpio broken with current git?
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
On Monday 23 February 2009, David Brownell wrote:
>
> > Perhaps something broke with Tony's RC1 merge?
> > The LEDs are broken for me as well.
>
> Still works for me.  Did you maybe not enable the twl4030
> GPIO support in Kconfig?
Oh, and if you did *not*, please give this patch a try.
I've been meaning to test it.
- Dave
==============
Sometimes it's awkward to make sure that the array in the
platform_data handed to the leds-gpio driver has only valid
data ... some leds may not be always available, and coping
with that currently requires patching or rebuilding the array.
This patch fixes that by making it be OK to pass an invalid
GPIO (such as "-EINVAL") ... such table entries are skipped.
---
drivers/leds/leds-gpio.c | 12 +++++++++++-
1 files changed, 11 insertions(+), 1 deletions(-)
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index b13bd29..83737e6 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -90,13 +90,19 @@ static int gpio_led_probe(struct platform_device *pdev)
cur_led = &pdata->leds[i];
led_dat = &leds_data[i];
+ /* skip leds that aren't available */
+ led_dat->gpio = cur_led->gpio;
+ if (!gpio_is_valid(led_dat->gpio)) {
+ dev_dbg(&pdev->dev, "skipping %s\n", cur_led->name);
+ continue;
+ }
+
ret = gpio_request(cur_led->gpio, cur_led->name);
if (ret < 0)
goto err;
led_dat->cdev.name = cur_led->name;
led_dat->cdev.default_trigger = cur_led->default_trigger;
- led_dat->gpio = cur_led->gpio;
led_dat->can_sleep = gpio_cansleep(cur_led->gpio);
led_dat->active_low = cur_led->active_low;
if (pdata->gpio_blink_set) {
@@ -124,6 +130,8 @@ static int gpio_led_probe(struct platform_device *pdev)
err:
if (i > 0) {
for (i = i - 1; i >= 0; i--) {
+ if (!gpio_is_valid(leds_data[i].gpio))
+ continue;
led_classdev_unregister(&leds_data[i].cdev);
cancel_work_sync(&leds_data[i].work);
gpio_free(leds_data[i].gpio);
@@ -144,6 +152,8 @@ static int __devexit gpio_led_remove(struct platform_device *pdev)
leds_data = platform_get_drvdata(pdev);
for (i = 0; i < pdata->num_leds; i++) {
+ if (!gpio_is_valid(leds_data[i].gpio))
+ continue;
led_classdev_unregister(&leds_data[i].cdev);
cancel_work_sync(&leds_data[i].work);
gpio_free(leds_data[i].gpio);
--
1.6.0.4.790.gaa14a

View File

@ -0,0 +1,41 @@
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 2ae5ab8..a68b0a6 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -1154,9 +1154,16 @@ static int __devinit ads7846_probe(struct spi_device *spi)
/* take a first sample, leaving nPENIRQ active and vREF off; avoid
* the touchscreen, in case it's not connected.
*/
- (void) ads7846_read12_ser(&spi->dev,
+ err = ads7846_read12_ser(&spi->dev,
READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
+ /* if sample is all 0's or all 1's then there is no device on spi */
+ if ( (err == 0x000) || (err == 0xfff)) {
+ dev_info(&spi->dev, "no device detected, test read result was 0x%08X\n", err);
+ err = -ENODEV;
+ goto err_free_irq;
+ }
+
err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group);
if (err)
goto err_remove_hwmon;
@@ -1174,7 +1181,7 @@ static int __devinit ads7846_probe(struct spi_device *spi)
err_free_irq:
free_irq(spi->irq, ts);
err_free_gpio:
- if (ts->gpio_pendown != -1)
+ if (!ts->get_pendown_state && ts->gpio_pendown != -1)
gpio_free(ts->gpio_pendown);
err_cleanup_filter:
if (ts->filter_cleanup)
@@ -1201,7 +1208,7 @@ static int __devexit ads7846_remove(struct spi_device *spi)
/* suspend left the IRQ disabled */
enable_irq(ts->spi->irq);
- if (ts->gpio_pendown != -1)
+ if (!ts->get_pendown_state && ts->gpio_pendown != -1)
gpio_free(ts->gpio_pendown);
if (ts->filter_cleanup)

View File

@ -0,0 +1,35 @@
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 4f7f040..ccd8973 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -55,3 +55,13 @@ config SND_OMAP_SOC_OMAP3_PANDORA
select SND_SOC_TWL4030
help
Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
+
+config SND_OMAP_SOC_OMAP3_BEAGLE
+ tristate "SoC Audio support for OMAP3 Beagle"
+ depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_BEAGLE
+ select SND_OMAP_SOC_MCBSP
+ select SND_SOC_TWL4030
+ help
+ Say Y if you want to add support for SoC audio on the Beagleboard.
+
+
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 76fedd9..0c9e4ac 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -12,6 +12,7 @@ snd-soc-overo-objs := overo.o
snd-soc-omap2evm-objs := omap2evm.o
snd-soc-sdp3430-objs := sdp3430.o
snd-soc-omap3pandora-objs := omap3pandora.o
+snd-soc-omap3beagle-objs := omap3beagle.o
obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
@@ -19,3 +20,4 @@ obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o
obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
+obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,131 @@
Index: git/arch/arm/mach-omap2/board-omap3beagle.c
===================================================================
--- git.orig/arch/arm/mach-omap2/board-omap3beagle.c
+++ git/arch/arm/mach-omap2/board-omap3beagle.c
@@ -154,6 +154,7 @@ static int beagle_twl_gpio_setup(struct
* power switch and overcurrent detect
*/
+#if 0 /* TODO: This needs to be modified to not rely on u-boot */
gpio_request(gpio + 1, "EHCI_nOC");
gpio_direction_input(gpio + 1);
@@ -163,7 +164,7 @@ static int beagle_twl_gpio_setup(struct
/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
-
+#endif
return 0;
}
Index: git/arch/arm/mach-omap2/usb-ehci.c
===================================================================
--- git.orig/arch/arm/mach-omap2/usb-ehci.c
+++ git/arch/arm/mach-omap2/usb-ehci.c
@@ -147,9 +147,11 @@ static void setup_ehci_io_mux(void)
void __init usb_ehci_init(void)
{
+#if 0 /* TODO: Setup Pin IO MUX for EHCI - moved this temporarily to U-boot */
/* Setup Pin IO MUX for EHCI */
if (cpu_is_omap34xx())
setup_ehci_io_mux();
+#endif
if (platform_device_register(&ehci_device) < 0) {
printk(KERN_ERR "Unable to register HS-USB (EHCI) device\n");
Index: git/drivers/usb/host/ehci-omap.c
===================================================================
--- git.orig/drivers/usb/host/ehci-omap.c
+++ git/drivers/usb/host/ehci-omap.c
@@ -48,16 +48,25 @@
* to get the PHY state machine in working state
*/
#define EXTERNAL_PHY_RESET
+#ifdef CONFIG_MACH_OMAP3_BEAGLE
+#define EXT_PHY_RESET_GPIO_PORT2 (147)
+#else
#define EXT_PHY_RESET_GPIO_PORT1 (57)
#define EXT_PHY_RESET_GPIO_PORT2 (61)
+#endif
#define EXT_PHY_RESET_DELAY (10)
+#define PHY_STP_PULLUP_ENABLE (0x10)
+#define PHY_STP_PULLUP_DISABLE (0x90)
+
/* ISSUE2:
* USBHOST supports External charge pump PHYs only
* Use the VBUS from Port1 to power VBUS of Port2 externally
* So use Port2 as the working ULPI port
*/
+#ifndef CONFIG_MACH_OMAP3_BEAGLE
#define VBUS_INTERNAL_CHARGEPUMP_HACK
+#endif
#endif /* CONFIG_OMAP_EHCI_PHY_MODE */
@@ -225,14 +234,43 @@ static int omap_start_ehc(struct platfor
#ifdef EXTERNAL_PHY_RESET
/* Refer: ISSUE1 */
+#ifndef CONFIG_MACH_OMAP3_BEAGLE
gpio_request(EXT_PHY_RESET_GPIO_PORT1, "USB1 PHY reset");
gpio_direction_output(EXT_PHY_RESET_GPIO_PORT1, 0);
+#endif
gpio_request(EXT_PHY_RESET_GPIO_PORT2, "USB2 PHY reset");
gpio_direction_output(EXT_PHY_RESET_GPIO_PORT2, 0);
+ gpio_set_value(EXT_PHY_RESET_GPIO_PORT2, 0);
/* Hold the PHY in RESET for enough time till DIR is high */
udelay(EXT_PHY_RESET_DELAY);
#endif
+ /*
+ * The PHY register 0x7 - Interface Control register is
+ * configured to disable the integrated STP pull-up resistor
+ * used for interface protection.
+ *
+ * May not need to be here.
+ */
+ omap_writel((0x7 << EHCI_INSNREG05_ULPI_REGADD_SHIFT) |/* interface reg */
+ (2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT) |/* Write */
+ (1 << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT) |/* Port1 */
+ (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT) |/* Start */
+ (PHY_STP_PULLUP_DISABLE),
+ EHCI_INSNREG05_ULPI);
+
+ while (!(omap_readl(EHCI_INSNREG05_ULPI) & (1<<EHCI_INSNREG05_ULPI_CONTROL_SHIFT)));
+
+ /* Force PHY to HS */
+ omap_writel((0x4 << EHCI_INSNREG05_ULPI_REGADD_SHIFT) |/* function ctrl */
+ (2 << EHCI_INSNREG05_ULPI_OPSEL_SHIFT) |/* Write */
+ (1 << EHCI_INSNREG05_ULPI_PORTSEL_SHIFT) |/* Port1 */
+ (1 << EHCI_INSNREG05_ULPI_CONTROL_SHIFT) |/* Start */
+ (0x40),
+ EHCI_INSNREG05_ULPI);
+
+ while (!(omap_readl(EHCI_INSNREG05_ULPI) & (1<<EHCI_INSNREG05_ULPI_CONTROL_SHIFT)));
+
/* Configure TLL for 60Mhz clk for ULPI */
ehci_clocks->usbtll_fck_clk = clk_get(&dev->dev, USBHOST_TLL_FCLK);
if (IS_ERR(ehci_clocks->usbtll_fck_clk))
@@ -307,7 +345,9 @@ static int omap_start_ehc(struct platfor
* Hold the PHY in RESET for enough time till PHY is settled and ready
*/
udelay(EXT_PHY_RESET_DELAY);
+#ifndef CONFIG_MACH_OMAP3_BEAGLE
gpio_set_value(EXT_PHY_RESET_GPIO_PORT1, 1);
+#endif
gpio_set_value(EXT_PHY_RESET_GPIO_PORT2, 1);
#endif
@@ -393,7 +433,9 @@ static void omap_stop_ehc(struct platfor
#ifdef EXTERNAL_PHY_RESET
+#ifndef CONFIG_MACH_OMAP3_BEAGLE
gpio_free(EXT_PHY_RESET_GPIO_PORT1);
+#endif
gpio_free(EXT_PHY_RESET_GPIO_PORT2);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,238 @@
On Tue, 2008-07-01 at 06:23 +0100, Dirk Behme wrote:
> Catalin Marinas wrote:
> > But, anyway, if you want a patch, Harry is updating it to a recent
> > kernel.
>
> Any news on this? I think there are some people wanting a patch ;)
See below for a preliminary patch updated to 2.6.26-rc8. Note that I
don't plan to submit it in its current form but clean it up a bit first.
Show the cache type of ARMv7 CPUs
From: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm/kernel/setup.c | 137 +++++++++++++++++++++++++++++++++++++++++++++-
include/asm-arm/system.h | 18 ++++++
2 files changed, 153 insertions(+), 2 deletions(-)
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 5ae0eb2..0cd238d 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -256,6 +256,24 @@ static const char *proc_arch[] = {
"?(17)",
};
+static const char *v7_cache_policy[4] = {
+ "reserved",
+ "AVIVT",
+ "VIPT",
+ "PIPT",
+};
+
+static const char *v7_cache_type[8] = {
+ "none",
+ "instruction only",
+ "data only",
+ "separate instruction and data",
+ "unified",
+ "unknown type",
+ "unknown type",
+ "unknown type",
+};
+
#define CACHE_TYPE(x) (((x) >> 25) & 15)
#define CACHE_S(x) ((x) & (1 << 24))
#define CACHE_DSIZE(x) (((x) >> 12) & 4095) /* only if S=1 */
@@ -266,6 +284,22 @@ static const char *proc_arch[] = {
#define CACHE_M(y) ((y) & (1 << 2))
#define CACHE_LINE(y) ((y) & 3)
+#define CACHE_TYPE_V7(x) (((x) >> 14) & 3)
+#define CACHE_UNIFIED(x) ((((x) >> 27) & 7)+1)
+#define CACHE_COHERENT(x) ((((x) >> 24) & 7)+1)
+
+#define CACHE_ID_LEVEL_MASK 7
+#define CACHE_ID_LEVEL_BITS 3
+
+#define CACHE_LINE_V7(v) ((1 << (((v) & 7)+4)))
+#define CACHE_ASSOC_V7(v) ((((v) >> 3) & ((1<<10)-1))+1)
+#define CACHE_SETS_V7(v) ((((v) >> 13) & ((1<<15)-1))+1)
+#define CACHE_SIZE_V7(v) (CACHE_LINE_V7(v)*CACHE_ASSOC_V7(v)*CACHE_SETS_V7(v))
+#define CACHE_WA_V7(v) (((v) & (1<<28)) != 0)
+#define CACHE_RA_V7(v) (((v) & (1<<29)) != 0)
+#define CACHE_WB_V7(v) (((v) & (1<<30)) != 0)
+#define CACHE_WT_V7(v) (((v) & (1<<31)) != 0)
+
static inline void dump_cache(const char *prefix, int cpu, unsigned int cache)
{
unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0);
@@ -279,11 +313,57 @@ static inline void dump_cache(const char *prefix, int cpu, unsigned int cache)
CACHE_LINE(cache)));
}
+static void dump_v7_cache(const char *type, int cpu, unsigned int level)
+{
+ unsigned int cachesize;
+
+ write_extended_cpuid(2,0,0,0,level); /* Set the cache size selection register */
+ write_extended_cpuid(0,7,5,4,0); /* Prefetch flush to wait for above */
+ cachesize = read_extended_cpuid(1,0,0,0);
+
+ printk("CPU%u: %s cache: %d bytes, associativity %d, %d byte lines, %d sets,\n supports%s%s%s%s\n",
+ cpu, type,
+ CACHE_SIZE_V7(cachesize),CACHE_ASSOC_V7(cachesize),
+ CACHE_LINE_V7(cachesize),CACHE_SETS_V7(cachesize),
+ CACHE_WA_V7(cachesize) ? " WA" : "",
+ CACHE_RA_V7(cachesize) ? " RA" : "",
+ CACHE_WB_V7(cachesize) ? " WB" : "",
+ CACHE_WT_V7(cachesize) ? " WT" : "");
+}
+
static void __init dump_cpu_info(int cpu)
{
unsigned int info = read_cpuid(CPUID_CACHETYPE);
- if (info != processor_id) {
+ if (info != processor_id && (info & (1 << 31))) {
+ /* ARMv7 style of cache info register */
+ unsigned int id = read_extended_cpuid(1,0,0,1);
+ unsigned int level = 0;
+ printk("CPU%u: L1 I %s cache. Caches unified at level %u, coherent at level %u\n",
+ cpu,
+ v7_cache_policy[CACHE_TYPE_V7(info)],
+ CACHE_UNIFIED(id),
+ CACHE_COHERENT(id));
+
+ while (id & CACHE_ID_LEVEL_MASK) {
+ printk("CPU%u: Level %u cache is %s\n",
+ cpu, (level >> 1)+1, v7_cache_type[id & CACHE_ID_LEVEL_MASK]);
+
+ if (id & 1) {
+ /* Dump I at this level */
+ dump_v7_cache("I", cpu, level | 1);
+ }
+
+ if (id & (4 | 2)) {
+ /* Dump D or unified at this level */
+ dump_v7_cache((id & 4) ? "unified" : "D", cpu, level);
+ }
+
+ /* Next level out */
+ level += 2;
+ id >>= CACHE_ID_LEVEL_BITS;
+ }
+ } else if (info != processor_id) {
printk("CPU%u: D %s %s cache\n", cpu, cache_is_vivt() ? "VIVT" : "VIPT",
cache_types[CACHE_TYPE(info)]);
if (CACHE_S(info)) {
@@ -916,6 +996,30 @@ c_show_cache(struct seq_file *m, const char *type, unsigned int cache)
CACHE_LINE(cache)));
}
+static void c_show_v7_cache(struct seq_file *m, const char *type, unsigned int levelselect)
+{
+ unsigned int cachesize;
+ unsigned int level = (levelselect >> 1) + 1;
+
+ write_extended_cpuid(2,0,0,0,levelselect); /* Set the cache size selection register */
+ write_extended_cpuid(0,7,5,4,0); /* Prefetch flush to wait for above */
+ cachesize = read_extended_cpuid(1,0,0,0);
+
+ seq_printf(m, "L%u %s size\t\t: %d bytes\n"
+ "L%u %s assoc\t\t: %d\n"
+ "L%u %s line length\t: %d\n"
+ "L%u %s sets\t\t: %d\n"
+ "L%u %s supports\t\t:%s%s%s%s\n",
+ level, type, CACHE_SIZE_V7(cachesize),
+ level, type, CACHE_ASSOC_V7(cachesize),
+ level, type, CACHE_LINE_V7(cachesize),
+ level, type, CACHE_SETS_V7(cachesize),
+ level, type, CACHE_WA_V7(cachesize) ? " WA" : "",
+ CACHE_RA_V7(cachesize) ? " RA" : "",
+ CACHE_WB_V7(cachesize) ? " WB" : "",
+ CACHE_WT_V7(cachesize) ? " WT" : "");
+}
+
static int c_show(struct seq_file *m, void *v)
{
int i;
@@ -971,7 +1075,36 @@ static int c_show(struct seq_file *m, void *v)
{
unsigned int cache_info = read_cpuid(CPUID_CACHETYPE);
- if (cache_info != processor_id) {
+ if (cache_info != processor_id && (cache_info & (1<<31))) {
+ /* V7 style of cache info register */
+ unsigned int id = read_extended_cpuid(1,0,0,1);
+ unsigned int levelselect = 0;
+ seq_printf(m, "L1 I cache\t:%s\n"
+ "Cache unification level\t: %u\n"
+ "Cache coherency level\t: %u\n",
+ v7_cache_policy[CACHE_TYPE_V7(cache_info)],
+ CACHE_UNIFIED(id),
+ CACHE_COHERENT(id));
+
+ while (id & CACHE_ID_LEVEL_MASK) {
+ seq_printf(m, "Level %u cache\t\t: %s\n",
+ (levelselect >> 1)+1, v7_cache_type[id & CACHE_ID_LEVEL_MASK]);
+
+ if (id & 1) {
+ /* Dump I at this level */
+ c_show_v7_cache(m, "I", levelselect | 1);
+ }
+
+ if (id & (4 | 2)) {
+ /* Dump D or unified at this level */
+ c_show_v7_cache(m, (id & 4) ? "cache" : "D", levelselect);
+ }
+
+ /* Next level out */
+ levelselect += 2;
+ id >>= CACHE_ID_LEVEL_BITS;
+ }
+ } else if (cache_info != processor_id) {
seq_printf(m, "Cache type\t: %s\n"
"Cache clean\t: %s\n"
"Cache lockdown\t: %s\n"
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 514af79..704738e 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -74,6 +74,24 @@
: "cc"); \
__val; \
})
+#define read_extended_cpuid(op1,op2,op3,op4) \
+ ({ \
+ unsigned int __val; \
+ asm("mrc p15," __stringify(op1) ",%0,c" __stringify(op2)",c" __stringify(op3)"," __stringify(op4) \
+ : "=r" (__val) \
+ : \
+ : "cc"); \
+ __val; \
+ })
+
+#define write_extended_cpuid(op1,op2,op3,op4,v) \
+ ({ \
+ unsigned int __val = v; \
+ asm("mcr p15," __stringify(op1) ",%0,c" __stringify(op2)",c" __stringify(op3)"," __stringify(op4) \
+ : \
+ : "r" (__val) \
+ : "cc"); \
+ })
#else
extern unsigned int processor_id;
#define read_cpuid(reg) (processor_id)
--
Catalin

View File

@ -0,0 +1,39 @@
From 26abf45ac80be4c54a63fecf1c3c1e1efb416e0a Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Wed, 1 Apr 2009 18:27:09 +0300
Subject: [PATCH] Revert "gro: Fix legacy path napi_complete crash"
This reverts commit 303c6a0251852ecbdc5c15e466dcaff5971f7517.
Fixes USB network problems
---
net/core/dev.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index e3fe5c7..c1e9dc0 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2588,9 +2588,9 @@ static int process_backlog(struct napi_struct *napi, int quota)
local_irq_disable();
skb = __skb_dequeue(&queue->input_pkt_queue);
if (!skb) {
+ __napi_complete(napi);
local_irq_enable();
- napi_complete(napi);
- goto out;
+ break;
}
local_irq_enable();
@@ -2599,7 +2599,6 @@ static int process_backlog(struct napi_struct *napi, int quota)
napi_gro_flush(napi);
-out:
return work;
}
--
1.5.6.5

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,396 @@
From 4cc0368574f587f448231ccd121266bed4bf9729 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Thu, 2 Apr 2009 10:29:56 +0300
Subject: [PATCH] DSS2: Add panel drivers
- Generic panel
- Samsung LTE430WQ-F0C LCD Panel
- Sharp LS037V7DW01 LCD Panel
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
---
drivers/video/omap2/displays/Kconfig | 21 ++++
drivers/video/omap2/displays/Makefile | 3 +
drivers/video/omap2/displays/panel-generic.c | 96 +++++++++++++++++
.../omap2/displays/panel-samsung-lte430wq-f0c.c | 108 +++++++++++++++++++
.../video/omap2/displays/panel-sharp-ls037v7dw01.c | 112 ++++++++++++++++++++
5 files changed, 340 insertions(+), 0 deletions(-)
create mode 100644 drivers/video/omap2/displays/Kconfig
create mode 100644 drivers/video/omap2/displays/Makefile
create mode 100644 drivers/video/omap2/displays/panel-generic.c
create mode 100644 drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c
create mode 100644 drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
new file mode 100644
index 0000000..0419ec8
--- /dev/null
+++ b/drivers/video/omap2/displays/Kconfig
@@ -0,0 +1,21 @@
+menu "OMAP2/3 Display Device Drivers"
+ depends on OMAP2_DSS
+
+config PANEL_GENERIC
+ tristate "Generic Panel"
+ help
+ Generic panel driver.
+ Used for DVI output for Beagle and OMAP3 SDP.
+
+config PANEL_SAMSUNG_LTE430WQ_F0C
+ tristate "Samsung LTE430WQ-F0C LCD Panel"
+ depends on OMAP2_DSS
+ help
+ LCD Panel used on Overo Palo43
+
+config PANEL_SHARP_LS037V7DW01
+ tristate "Sharp LS037V7DW01 LCD Panel"
+ depends on OMAP2_DSS
+ help
+ LCD Panel used in TI's SDP3430 and EVM boards
+endmenu
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
new file mode 100644
index 0000000..a26bbd2
--- /dev/null
+++ b/drivers/video/omap2/displays/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o
+obj-$(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C) += panel-samsung-lte430wq-f0c.o
+obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
diff --git a/drivers/video/omap2/displays/panel-generic.c b/drivers/video/omap2/displays/panel-generic.c
new file mode 100644
index 0000000..8382acb
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-generic.c
@@ -0,0 +1,96 @@
+/*
+ * Generic panel support
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+
+#include <mach/display.h>
+
+static int generic_panel_init(struct omap_display *display)
+{
+ return 0;
+}
+
+static int generic_panel_enable(struct omap_display *display)
+{
+ int r = 0;
+
+ if (display->hw_config.panel_enable)
+ r = display->hw_config.panel_enable(display);
+
+ return r;
+}
+
+static void generic_panel_disable(struct omap_display *display)
+{
+ if (display->hw_config.panel_disable)
+ display->hw_config.panel_disable(display);
+}
+
+static int generic_panel_suspend(struct omap_display *display)
+{
+ generic_panel_disable(display);
+ return 0;
+}
+
+static int generic_panel_resume(struct omap_display *display)
+{
+ return generic_panel_enable(display);
+}
+
+static struct omap_panel generic_panel = {
+ .owner = THIS_MODULE,
+ .name = "panel-generic",
+ .init = generic_panel_init,
+ .enable = generic_panel_enable,
+ .disable = generic_panel_disable,
+ .suspend = generic_panel_suspend,
+ .resume = generic_panel_resume,
+
+ .timings = {
+ /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
+ .x_res = 640,
+ .y_res = 480,
+ .pixel_clock = 23500,
+ .hfp = 48,
+ .hsw = 32,
+ .hbp = 80,
+ .vfp = 3,
+ .vsw = 4,
+ .vbp = 7,
+ },
+
+ .config = OMAP_DSS_LCD_TFT,
+};
+
+
+static int __init generic_panel_drv_init(void)
+{
+ omap_dss_register_panel(&generic_panel);
+ return 0;
+}
+
+static void __exit generic_panel_drv_exit(void)
+{
+ omap_dss_unregister_panel(&generic_panel);
+}
+
+module_init(generic_panel_drv_init);
+module_exit(generic_panel_drv_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c b/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c
new file mode 100644
index 0000000..e4bb781
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c
@@ -0,0 +1,108 @@
+/*
+ * LCD panel driver for Samsung LTE430WQ-F0C
+ *
+ * Author: Steve Sakoman <steve@sakoman.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+
+#include <mach/display.h>
+
+static int samsung_lte_panel_init(struct omap_display *display)
+{
+ return 0;
+}
+
+static void samsung_lte_panel_cleanup(struct omap_display *display)
+{
+}
+
+static int samsung_lte_panel_enable(struct omap_display *display)
+{
+ int r = 0;
+
+ /* wait couple of vsyncs until enabling the LCD */
+ msleep(50);
+
+ if (display->hw_config.panel_enable)
+ r = display->hw_config.panel_enable(display);
+
+ return r;
+}
+
+static void samsung_lte_panel_disable(struct omap_display *display)
+{
+ if (display->hw_config.panel_disable)
+ display->hw_config.panel_disable(display);
+
+ /* wait at least 5 vsyncs after disabling the LCD */
+ msleep(100);
+}
+
+static int samsung_lte_panel_suspend(struct omap_display *display)
+{
+ samsung_lte_panel_disable(display);
+ return 0;
+}
+
+static int samsung_lte_panel_resume(struct omap_display *display)
+{
+ return samsung_lte_panel_enable(display);
+}
+
+static struct omap_panel samsung_lte_panel = {
+ .owner = THIS_MODULE,
+ .name = "samsung-lte430wq-f0c",
+ .init = samsung_lte_panel_init,
+ .cleanup = samsung_lte_panel_cleanup,
+ .enable = samsung_lte_panel_enable,
+ .disable = samsung_lte_panel_disable,
+ .suspend = samsung_lte_panel_suspend,
+ .resume = samsung_lte_panel_resume,
+
+ .timings = {
+ .x_res = 480,
+ .y_res = 272,
+
+ .pixel_clock = 9200,
+
+ .hsw = 41,
+ .hfp = 8,
+ .hbp = 45-41,
+
+ .vsw = 10,
+ .vfp = 4,
+ .vbp = 12-10,
+ },
+ .recommended_bpp = 16,
+ .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IVS,
+};
+
+
+static int __init samsung_lte_panel_drv_init(void)
+{
+ omap_dss_register_panel(&samsung_lte_panel);
+ return 0;
+}
+
+static void __exit samsung_lte_panel_drv_exit(void)
+{
+ omap_dss_unregister_panel(&samsung_lte_panel);
+}
+
+module_init(samsung_lte_panel_drv_init);
+module_exit(samsung_lte_panel_drv_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
new file mode 100644
index 0000000..1f99150
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -0,0 +1,112 @@
+/*
+ * LCD panel driver for Sharp LS037V7DW01
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+
+#include <mach/display.h>
+
+static int sharp_ls_panel_init(struct omap_display *display)
+{
+ return 0;
+}
+
+static void sharp_ls_panel_cleanup(struct omap_display *display)
+{
+}
+
+static int sharp_ls_panel_enable(struct omap_display *display)
+{
+ int r = 0;
+
+ /* wait couple of vsyncs until enabling the LCD */
+ msleep(50);
+
+ if (display->hw_config.panel_enable)
+ r = display->hw_config.panel_enable(display);
+
+ return r;
+}
+
+static void sharp_ls_panel_disable(struct omap_display *display)
+{
+ if (display->hw_config.panel_disable)
+ display->hw_config.panel_disable(display);
+
+ /* wait at least 5 vsyncs after disabling the LCD */
+
+ msleep(100);
+}
+
+static int sharp_ls_panel_suspend(struct omap_display *display)
+{
+ sharp_ls_panel_disable(display);
+ return 0;
+}
+
+static int sharp_ls_panel_resume(struct omap_display *display)
+{
+ return sharp_ls_panel_enable(display);
+}
+
+static struct omap_panel sharp_ls_panel = {
+ .owner = THIS_MODULE,
+ .name = "sharp-ls037v7dw01",
+ .init = sharp_ls_panel_init,
+ .cleanup = sharp_ls_panel_cleanup,
+ .enable = sharp_ls_panel_enable,
+ .disable = sharp_ls_panel_disable,
+ .suspend = sharp_ls_panel_suspend,
+ .resume = sharp_ls_panel_resume,
+
+ .timings = {
+ .x_res = 480,
+ .y_res = 640,
+
+ .pixel_clock = 19200,
+
+ .hsw = 2,
+ .hfp = 1,
+ .hbp = 28,
+
+ .vsw = 1,
+ .vfp = 1,
+ .vbp = 1,
+ },
+
+ .acb = 0x28,
+
+ .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS,
+};
+
+
+static int __init sharp_ls_panel_drv_init(void)
+{
+ omap_dss_register_panel(&sharp_ls_panel);
+ return 0;
+}
+
+static void __exit sharp_ls_panel_drv_exit(void)
+{
+ omap_dss_unregister_panel(&sharp_ls_panel);
+}
+
+module_init(sharp_ls_panel_drv_init);
+module_exit(sharp_ls_panel_drv_exit);
+MODULE_LICENSE("GPL");
--
1.5.6.5

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,39 @@
From 4741076cae4f4284e1fff9a03f35475b8455af54 Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@nokia.com>
Date: Wed, 1 Apr 2009 14:36:39 +0200
Subject: [PATCH] DSS2: Add function to display object to get the backlight level
This is needed by an upcoming patch that changes the backlight
initialization to use the backlight level set by the bootloader.
Also add a field for the maximum backlight level.
Signed-off-by: Imre Deak <imre.deak@nokia.com>
---
arch/arm/plat-omap/include/mach/display.h | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-omap/include/mach/display.h b/arch/arm/plat-omap/include/mach/display.h
index 6288353..6b702c7 100644
--- a/arch/arm/plat-omap/include/mach/display.h
+++ b/arch/arm/plat-omap/include/mach/display.h
@@ -211,6 +211,8 @@ struct omap_dss_display_config {
int panel_reset_gpio;
int ctrl_reset_gpio;
+ int max_backlight_level;
+
const char *name; /* for debug */
const char *ctrl_name;
const char *panel_name;
@@ -225,6 +227,7 @@ struct omap_dss_display_config {
void (*ctrl_disable)(struct omap_display *display);
int (*set_backlight)(struct omap_display *display,
int level);
+ int (*get_backlight)(struct omap_display *display);
};
struct device;
--
1.5.6.5

View File

@ -0,0 +1,778 @@
From 66e16f86d3f4c5b34b37e965c65102b7192371de Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@nokia.com>
Date: Thu, 2 Apr 2009 11:47:13 +0300
Subject: [PATCH] DSS2: Add acx565akm panel
Signed-off-by: Imre Deak <imre.deak@nokia.com>
---
drivers/video/omap2/displays/Kconfig | 8 +
drivers/video/omap2/displays/Makefile | 2 +
drivers/video/omap2/displays/panel-acx565akm.c | 712 ++++++++++++++++++++++++
drivers/video/omap2/displays/panel-acx565akm.h | 9 +
4 files changed, 731 insertions(+), 0 deletions(-)
create mode 100644 drivers/video/omap2/displays/panel-acx565akm.c
create mode 100644 drivers/video/omap2/displays/panel-acx565akm.h
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 356ceb1..3feecee 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -28,4 +28,12 @@ config CTRL_BLIZZARD
tristate "Blizzard Controller"
help
Blizzard Controller (hack)
+
+config PANEL_ACX565AKM
+ tristate "ACX565AKM LCD Panel"
+ depends on OMAP2_DSS_SDI
+ select BACKLIGHT_CLASS_DEVICE
+ help
+ LCD Panel used in RX51
+
endmenu
diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
index 1b74b7e..9bafcb6 100644
--- a/drivers/video/omap2/displays/Makefile
+++ b/drivers/video/omap2/displays/Makefile
@@ -4,3 +4,5 @@ obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
obj-$(CONFIG_CTRL_BLIZZARD) += ctrl-blizzard.o
obj-$(CONFIG_PANEL_N800) += panel-n800.o
+
+obj-$(CONFIG_PANEL_ACX565AKM) += panel-acx565akm.o
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
new file mode 100644
index 0000000..2679d6c
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -0,0 +1,712 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+#include <linux/jiffies.h>
+#include <linux/sched.h>
+#include <linux/backlight.h>
+#include <linux/fb.h>
+
+#include <mach/display.h>
+#include <mach/dma.h>
+
+#include "panel-acx565akm.h"
+
+#define MIPID_CMD_READ_DISP_ID 0x04
+#define MIPID_CMD_READ_RED 0x06
+#define MIPID_CMD_READ_GREEN 0x07
+#define MIPID_CMD_READ_BLUE 0x08
+#define MIPID_CMD_READ_DISP_STATUS 0x09
+#define MIPID_CMD_RDDSDR 0x0F
+#define MIPID_CMD_SLEEP_IN 0x10
+#define MIPID_CMD_SLEEP_OUT 0x11
+#define MIPID_CMD_DISP_OFF 0x28
+#define MIPID_CMD_DISP_ON 0x29
+#define MIPID_CMD_WRITE_DISP_BRIGHTNESS 0x51
+#define MIPID_CMD_READ_DISP_BRIGHTNESS 0x52
+#define MIPID_CMD_WRITE_CTRL_DISP 0x53
+
+#define CTRL_DISP_BRIGHTNESS_CTRL_ON (1 << 5)
+#define CTRL_DISP_AMBIENT_LIGHT_CTRL_ON (1 << 4)
+#define CTRL_DISP_BACKLIGHT_ON (1 << 2)
+#define CTRL_DISP_AUTO_BRIGHTNESS_ON (1 << 1)
+
+#define MIPID_CMD_READ_CTRL_DISP 0x54
+#define MIPID_CMD_WRITE_CABC 0x55
+#define MIPID_CMD_READ_CABC 0x56
+
+#define MIPID_VER_LPH8923 3
+#define MIPID_VER_LS041Y3 4
+#define MIPID_VER_L4F00311 8
+#define MIPID_VER_ACX565AKM 9
+
+struct acx565akm_device {
+ struct backlight_device *bl_dev;
+ int enabled;
+ int model;
+ int revision;
+ u8 display_id[3];
+ int has_bc:1;
+ int has_cabc:1;
+ unsigned int saved_bklight_level;
+ unsigned long hw_guard_end; /* next value of jiffies
+ when we can issue the
+ next sleep in/out command */
+ unsigned long hw_guard_wait; /* max guard time in jiffies */
+
+ struct spi_device *spi;
+ struct mutex mutex;
+ struct omap_panel panel;
+ struct omap_display *display;
+};
+
+static int acx565akm_bl_update_status(struct backlight_device *dev);
+
+static void acx565akm_transfer(struct acx565akm_device *md, int cmd,
+ const u8 *wbuf, int wlen, u8 *rbuf, int rlen)
+{
+ struct spi_message m;
+ struct spi_transfer *x, xfer[5];
+ int r;
+
+ BUG_ON(md->spi == NULL);
+
+ spi_message_init(&m);
+
+ memset(xfer, 0, sizeof(xfer));
+ x = &xfer[0];
+
+ cmd &= 0xff;
+ x->tx_buf = &cmd;
+ x->bits_per_word = 9;
+ x->len = 2;
+
+ if (rlen > 1 && wlen == 0) {
+ /*
+ * Between the command and the response data there is a
+ * dummy clock cycle. Add an extra bit after the command
+ * word to account for this.
+ */
+ x->bits_per_word = 10;
+ cmd <<= 1;
+ }
+ spi_message_add_tail(x, &m);
+
+ if (wlen) {
+ x++;
+ x->tx_buf = wbuf;
+ x->len = wlen;
+ x->bits_per_word = 9;
+ spi_message_add_tail(x, &m);
+ }
+
+ if (rlen) {
+ x++;
+ x->rx_buf = rbuf;
+ x->len = rlen;
+ spi_message_add_tail(x, &m);
+ }
+
+ r = spi_sync(md->spi, &m);
+ if (r < 0)
+ dev_dbg(&md->spi->dev, "spi_sync %d\n", r);
+}
+
+static inline void acx565akm_cmd(struct acx565akm_device *md, int cmd)
+{
+ acx565akm_transfer(md, cmd, NULL, 0, NULL, 0);
+}
+
+static inline void acx565akm_write(struct acx565akm_device *md,
+ int reg, const u8 *buf, int len)
+{
+ acx565akm_transfer(md, reg, buf, len, NULL, 0);
+}
+
+static inline void acx565akm_read(struct acx565akm_device *md,
+ int reg, u8 *buf, int len)
+{
+ acx565akm_transfer(md, reg, NULL, 0, buf, len);
+}
+
+static void hw_guard_start(struct acx565akm_device *md, int guard_msec)
+{
+ md->hw_guard_wait = msecs_to_jiffies(guard_msec);
+ md->hw_guard_end = jiffies + md->hw_guard_wait;
+}
+
+static void hw_guard_wait(struct acx565akm_device *md)
+{
+ unsigned long wait = md->hw_guard_end - jiffies;
+
+ if ((long)wait > 0 && wait <= md->hw_guard_wait) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(wait);
+ }
+}
+
+static void set_sleep_mode(struct acx565akm_device *md, int on)
+{
+ int cmd, sleep_time = 50;
+
+ if (on)
+ cmd = MIPID_CMD_SLEEP_IN;
+ else
+ cmd = MIPID_CMD_SLEEP_OUT;
+ hw_guard_wait(md);
+ acx565akm_cmd(md, cmd);
+ hw_guard_start(md, 120);
+ /*
+ * When we enable the panel, it seems we _have_ to sleep
+ * 120 ms before sending the init string. When disabling the
+ * panel we'll sleep for the duration of 2 frames, so that the
+ * controller can still provide the PCLK,HS,VS signals. */
+ if (!on)
+ sleep_time = 120;
+ msleep(sleep_time);
+}
+
+static void set_display_state(struct acx565akm_device *md, int enabled)
+{
+ int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF;
+
+ acx565akm_cmd(md, cmd);
+}
+
+static int panel_enabled(struct acx565akm_device *md)
+{
+ u32 disp_status;
+ int enabled;
+
+ acx565akm_read(md, MIPID_CMD_READ_DISP_STATUS, (u8 *)&disp_status, 4);
+ disp_status = __be32_to_cpu(disp_status);
+ enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10));
+ dev_dbg(&md->spi->dev,
+ "LCD panel %senabled by bootloader (status 0x%04x)\n",
+ enabled ? "" : "not ", disp_status);
+ return enabled;
+}
+
+static void enable_backlight_ctrl(struct acx565akm_device *md, int enable)
+{
+ u16 ctrl;
+
+ acx565akm_read(md, MIPID_CMD_READ_CTRL_DISP, (u8 *)&ctrl, 1);
+ if (enable) {
+ ctrl |= CTRL_DISP_BRIGHTNESS_CTRL_ON |
+ CTRL_DISP_BACKLIGHT_ON;
+ } else {
+ ctrl &= ~(CTRL_DISP_BRIGHTNESS_CTRL_ON |
+ CTRL_DISP_BACKLIGHT_ON);
+ }
+
+ ctrl |= 1 << 8;
+ acx565akm_write(md, MIPID_CMD_WRITE_CTRL_DISP, (u8 *)&ctrl, 2);
+}
+
+static void set_cabc_mode(struct acx565akm_device *md, int mode)
+{
+ u16 cabc_ctrl;
+
+ cabc_ctrl = 0;
+ acx565akm_read(md, MIPID_CMD_READ_CABC, (u8 *)&cabc_ctrl, 1);
+ cabc_ctrl &= ~3;
+ cabc_ctrl |= (1 << 8) | (mode & 3);
+ acx565akm_write(md, MIPID_CMD_WRITE_CABC, (u8 *)&cabc_ctrl, 2);
+}
+
+static int get_cabc_mode(struct acx565akm_device *md)
+{
+ u8 cabc_ctrl;
+
+ acx565akm_read(md, MIPID_CMD_READ_CABC, &cabc_ctrl, 1);
+ return cabc_ctrl & 3;
+}
+
+static int panel_detect(struct acx565akm_device *md)
+{
+ acx565akm_read(md, MIPID_CMD_READ_DISP_ID, md->display_id, 3);
+ dev_dbg(&md->spi->dev, "MIPI display ID: %02x%02x%02x\n",
+ md->display_id[0], md->display_id[1], md->display_id[2]);
+
+ switch (md->display_id[0]) {
+ case 0x10:
+ md->model = MIPID_VER_ACX565AKM;
+ md->panel.name = "acx565akm";
+ md->has_bc = 1;
+ md->has_cabc = 1;
+ break;
+ case 0x29:
+ md->model = MIPID_VER_L4F00311;
+ md->panel.name = "l4f00311";
+ break;
+ case 0x45:
+ md->model = MIPID_VER_LPH8923;
+ md->panel.name = "lph8923";
+ break;
+ case 0x83:
+ md->model = MIPID_VER_LS041Y3;
+ md->panel.name = "ls041y3";
+ break;
+ default:
+ md->panel.name = "unknown";
+ dev_err(&md->spi->dev, "invalid display ID\n");
+ return -ENODEV;
+ }
+
+ md->revision = md->display_id[1];
+
+ pr_info("omapfb: %s rev %02x LCD detected\n",
+ md->panel.name, md->revision);
+
+ return 0;
+}
+
+static int acx565akm_panel_enable(struct omap_display *display)
+{
+ struct acx565akm_device *md =
+ (struct acx565akm_device *)display->panel->priv;
+
+ dev_dbg(&md->spi->dev, "%s\n", __func__);
+
+ mutex_lock(&md->mutex);
+
+ if (display->hw_config.panel_enable)
+ display->hw_config.panel_enable(display);
+
+ md->enabled = panel_enabled(md);
+
+ if (md->enabled) {
+ dev_dbg(&md->spi->dev, "panel already enabled\n");
+ mutex_unlock(&md->mutex);
+ return 0;
+ }
+
+ set_sleep_mode(md, 0);
+ md->enabled = 1;
+ set_display_state(md, 1);
+
+ mutex_unlock(&md->mutex);
+
+ return acx565akm_bl_update_status(md->bl_dev);
+}
+
+static void acx565akm_panel_disable(struct omap_display *display)
+{
+ struct acx565akm_device *md =
+ (struct acx565akm_device *)display->panel->priv;
+
+ dev_dbg(&md->spi->dev, "%s\n", __func__);
+
+ mutex_lock(&md->mutex);
+
+ if (!md->enabled) {
+ mutex_unlock(&md->mutex);
+ return;
+ }
+ set_display_state(md, 0);
+ set_sleep_mode(md, 1);
+ md->enabled = 0;
+
+ if (display->hw_config.panel_disable)
+ display->hw_config.panel_disable(display);
+
+ mutex_unlock(&md->mutex);
+}
+
+#if 0
+static void acx565akm_set_mode(struct omap_display *display,
+ int x_res, int y_res, int bpp)
+{
+ struct acx565akm_device *md =
+ (struct acx565akm_device *)display->panel->priv;
+ u16 par;
+
+ switch (bpp) {
+ case 16:
+ par = 0x150;
+ break;
+ case 18:
+ par = 0x160;
+ break;
+ case 24:
+ par = 0x170;
+ break;
+ }
+
+ acx565akm_write(md, 0x3a, (u8 *)&par, 2);
+}
+#endif
+
+static int acx565akm_panel_suspend(struct omap_display *display)
+{
+ acx565akm_panel_disable(display);
+ return 0;
+}
+
+static int acx565akm_panel_resume(struct omap_display *display)
+{
+ return acx565akm_panel_enable(display);
+}
+
+static void acx565akm_set_brightness(struct acx565akm_device *md, int level)
+{
+ int bv;
+
+ bv = level | (1 << 8);
+ acx565akm_write(md, MIPID_CMD_WRITE_DISP_BRIGHTNESS, (u8 *)&bv, 2);
+
+ if (level)
+ enable_backlight_ctrl(md, 1);
+ else
+ enable_backlight_ctrl(md, 0);
+}
+
+static int acx565akm_get_actual_brightness(struct acx565akm_device *md)
+{
+ u8 bv;
+
+ acx565akm_read(md, MIPID_CMD_READ_DISP_BRIGHTNESS, &bv, 1);
+
+ return bv;
+}
+
+static int acx565akm_bl_update_status(struct backlight_device *dev)
+{
+ struct acx565akm_device *md = dev_get_drvdata(&dev->dev);
+ struct omap_display *display = md->display;
+ int r;
+ int level;
+
+ dev_dbg(&md->spi->dev, "%s\n", __func__);
+
+ if (display->hw_config.set_backlight == NULL)
+ return -ENODEV;
+
+ mutex_lock(&md->mutex);
+
+ if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
+ dev->props.power == FB_BLANK_UNBLANK)
+ level = dev->props.brightness;
+ else
+ level = 0;
+
+ r = 0;
+ if (md->has_bc)
+ acx565akm_set_brightness(md, level);
+ else
+ if (display->hw_config.set_backlight != NULL)
+ r = display->hw_config.set_backlight(display, level);
+ else
+ r = -ENODEV;
+
+ mutex_unlock(&md->mutex);
+
+ return r;
+}
+
+static int acx565akm_bl_get_intensity(struct backlight_device *dev)
+{
+ struct acx565akm_device *md = dev_get_drvdata(&dev->dev);
+ struct omap_display *display = md->display;
+
+ dev_dbg(&dev->dev, "%s\n", __func__);
+
+ if (md->has_bc && display->hw_config.set_backlight == NULL)
+ return -ENODEV;
+
+ if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
+ dev->props.power == FB_BLANK_UNBLANK) {
+ if (md->has_bc)
+ return acx565akm_get_actual_brightness(md);
+ else
+ return dev->props.brightness;
+ }
+
+ return 0;
+}
+
+static struct backlight_ops acx565akm_bl_ops = {
+ .get_brightness = acx565akm_bl_get_intensity,
+ .update_status = acx565akm_bl_update_status,
+};
+
+static const char *cabc_modes[] = {
+ "off", /* used also always when CABC is not supported */
+ "ui",
+ "still-image",
+ "moving-image",
+};
+
+static ssize_t show_cabc_mode(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct acx565akm_device *md = dev_get_drvdata(dev);
+ const char *mode_str;
+ int mode;
+ int len;
+
+ if (!md->has_cabc)
+ mode = 0;
+ else
+ mode = get_cabc_mode(md);
+ mode_str = "unknown";
+ if (mode >= 0 && mode < ARRAY_SIZE(cabc_modes))
+ mode_str = cabc_modes[mode];
+ len = snprintf(buf, PAGE_SIZE, "%s\n", mode_str);
+
+ return len < PAGE_SIZE - 1 ? len : PAGE_SIZE - 1;
+}
+
+static ssize_t store_cabc_mode(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct acx565akm_device *md = dev_get_drvdata(dev);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(cabc_modes); i++) {
+ const char *mode_str = cabc_modes[i];
+ int cmp_len = strlen(mode_str);
+
+ if (count > 0 && buf[count - 1] == '\n')
+ count--;
+ if (count != cmp_len)
+ continue;
+
+ if (strncmp(buf, mode_str, cmp_len) == 0)
+ break;
+ }
+
+ if (i == ARRAY_SIZE(cabc_modes))
+ return -EINVAL;
+
+ if (!md->has_cabc && i != 0)
+ return -EINVAL;
+
+ mutex_lock(&md->mutex);
+ set_cabc_mode(md, i);
+ mutex_unlock(&md->mutex);
+
+ return count;
+}
+
+static ssize_t show_cabc_available_modes(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct acx565akm_device *md = dev_get_drvdata(dev);
+ int len;
+ int i;
+
+ if (!md->has_cabc)
+ return snprintf(buf, PAGE_SIZE, "%s\n", cabc_modes[0]);
+
+ for (i = 0, len = 0;
+ len < PAGE_SIZE && i < ARRAY_SIZE(cabc_modes); i++)
+ len += snprintf(&buf[len], PAGE_SIZE - len, "%s%s%s",
+ i ? " " : "", cabc_modes[i],
+ i == ARRAY_SIZE(cabc_modes) - 1 ? "\n" : "");
+
+ return len < PAGE_SIZE ? len : PAGE_SIZE - 1;
+}
+
+static DEVICE_ATTR(cabc_mode, S_IRUGO | S_IWUSR,
+ show_cabc_mode, store_cabc_mode);
+static DEVICE_ATTR(cabc_available_modes, S_IRUGO,
+ show_cabc_available_modes, NULL);
+
+static struct attribute *bldev_attrs[] = {
+ &dev_attr_cabc_mode.attr,
+ &dev_attr_cabc_available_modes.attr,
+ NULL,
+};
+
+static struct attribute_group bldev_attr_group = {
+ .attrs = bldev_attrs,
+};
+
+static int acx565akm_panel_init(struct omap_display *display)
+{
+ struct omap_panel *panel = display->panel;
+ struct acx565akm_panel_data *panel_data = display->hw_config.panel_data;
+ struct acx565akm_device *md = (struct acx565akm_device *)panel->priv;
+
+ struct backlight_device *bldev;
+ int brightness;
+ int max_brightness;
+ int r;
+
+ dev_dbg(&md->spi->dev, "%s\n", __func__);
+
+ if (!panel_data) {
+ dev_err(&md->spi->dev, "no panel data\n");
+ return -ENODEV;
+ }
+
+ mutex_init(&md->mutex);
+ md->display = display;
+
+ if (display->hw_config.panel_enable)
+ display->hw_config.panel_enable(display);
+
+ md->enabled = panel_enabled(md);
+
+ r = panel_detect(md);
+ if (r) {
+ if (!md->enabled && display->hw_config.panel_disable)
+ display->hw_config.panel_disable(display);
+ mutex_unlock(&md->mutex);
+ return r;
+ }
+
+ if (!panel_data->bc_connected) {
+ md->has_bc = 0;
+ md->has_cabc = 0;
+ }
+
+#if 0
+ acx565akm_set_mode(display, panel->timings.x_res, panel->timings.y_res,
+ panel->bpp);
+#endif
+
+ if (!md->enabled)
+ display->hw_config.panel_disable(display);
+
+ bldev = backlight_device_register("acx565akm", &md->spi->dev,
+ md, &acx565akm_bl_ops);
+ md->bl_dev = bldev;
+
+ if (md->has_cabc) {
+ r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group);
+ if (r) {
+ dev_err(&bldev->dev, "failed to create sysfs files\n");
+ backlight_device_unregister(bldev);
+ return r;
+ }
+ }
+
+ bldev->props.fb_blank = FB_BLANK_UNBLANK;
+ bldev->props.power = FB_BLANK_UNBLANK;
+
+ if (md->has_bc)
+ max_brightness = 255;
+ else
+ max_brightness = display->hw_config.max_backlight_level;
+
+ if (md->has_bc)
+ brightness = acx565akm_get_actual_brightness(md);
+ else {
+ if (display->hw_config.get_backlight != NULL)
+ brightness = display->hw_config.get_backlight(display);
+ else
+ brightness = 0;
+ }
+
+ bldev->props.max_brightness = max_brightness;
+ bldev->props.brightness = brightness;
+ acx565akm_bl_update_status(bldev);
+
+ return 0;
+}
+
+static struct omap_panel acx565akm_panel = {
+ .name = "panel-acx565akm",
+ .init = acx565akm_panel_init,
+ .suspend = acx565akm_panel_suspend,
+ .resume = acx565akm_panel_resume,
+ .enable = acx565akm_panel_enable,
+ .disable = acx565akm_panel_disable,
+
+ .timings = {
+ .x_res = 800,
+ .y_res = 480,
+
+ .pixel_clock = 24000,
+
+ .hsw = 4,
+ .hfp = 16,
+ .hbp = 12,
+
+ .vsw = 3,
+ .vfp = 3,
+ .vbp = 3,
+ },
+
+ .config = OMAP_DSS_LCD_TFT,
+
+ .recommended_bpp = 16,
+
+ /*
+ * supported modes: 12bpp(444), 16bpp(565), 18bpp(666), 24bpp(888)
+ * resolutions.
+ */
+};
+
+static int acx565akm_spi_probe(struct spi_device *spi)
+{
+ struct acx565akm_device *md;
+
+ dev_dbg(&md->spi->dev, "%s\n", __func__);
+
+ md = kzalloc(sizeof(*md), GFP_KERNEL);
+ if (md == NULL) {
+ dev_err(&spi->dev, "out of memory\n");
+ return -ENOMEM;
+ }
+
+ spi->mode = SPI_MODE_3;
+ md->spi = spi;
+ dev_set_drvdata(&spi->dev, md);
+ md->panel = acx565akm_panel;
+ acx565akm_panel.priv = md;
+
+ omap_dss_register_panel(&acx565akm_panel);
+
+ return 0;
+}
+
+static int acx565akm_spi_remove(struct spi_device *spi)
+{
+ struct acx565akm_device *md = dev_get_drvdata(&spi->dev);
+
+ dev_dbg(&md->spi->dev, "%s\n", __func__);
+
+ sysfs_remove_group(&md->bl_dev->dev.kobj, &bldev_attr_group);
+ backlight_device_unregister(md->bl_dev);
+ omap_dss_unregister_panel(&acx565akm_panel);
+
+ kfree(md);
+
+ return 0;
+}
+
+static struct spi_driver acx565akm_spi_driver = {
+ .driver = {
+ .name = "acx565akm",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = acx565akm_spi_probe,
+ .remove = __devexit_p(acx565akm_spi_remove),
+};
+
+static int __init acx565akm_init(void)
+{
+ return spi_register_driver(&acx565akm_spi_driver);
+}
+
+static void __exit acx565akm_exit(void)
+{
+ spi_unregister_driver(&acx565akm_spi_driver);
+}
+
+module_init(acx565akm_init);
+module_exit(acx565akm_exit);
+
+MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
+MODULE_DESCRIPTION("acx565akm LCD Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap2/displays/panel-acx565akm.h b/drivers/video/omap2/displays/panel-acx565akm.h
new file mode 100644
index 0000000..6d3727b
--- /dev/null
+++ b/drivers/video/omap2/displays/panel-acx565akm.h
@@ -0,0 +1,9 @@
+#ifndef __DRIVERS_VIDEO_OMAP2_DISPLAYS_PANEL_ACX565AKM_H
+#define __DRIVERS_VIDEO_OMAP2_DISPLAYS_PANEL_ACX565AKM_H
+
+struct acx565akm_panel_data {
+ unsigned bc_connected:1;
+};
+
+#endif
+
--
1.5.6.5

View File

@ -0,0 +1,28 @@
From 370510e24ddbf539392ebb6a1e43280965fcb19b Mon Sep 17 00:00:00 2001
From: Vaibhav Hiremath <hvaibhav@ti.com>
Date: Tue, 31 Mar 2009 18:47:32 +0530
Subject: [PATCH] DSS2: Small VRFB context allocation bug fixed
This is minor bug while requesting and mapping memory for
VRFB space.
Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
---
drivers/video/omap2/omapfb/omapfb-main.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 852abe5..44febef 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1193,6 +1193,7 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
if(!va) {
printk(KERN_ERR "vrfb: ioremap failed\n");
+ omap_vrfb_release_ctx(&rg->vrfb);
return -ENOMEM;
}
--
1.5.6.5

View File

@ -0,0 +1,37 @@
From 370d1f93a32e8fcaeac5c16574417e354af21d08 Mon Sep 17 00:00:00 2001
From: Vaibhav Hiremath <hvaibhav@ti.com>
Date: Tue, 31 Mar 2009 18:38:31 +0530
Subject: [PATCH] DSS2: Allocated memory for Color Look-up-table
We were not allocating memory for CMAP buffer and due to that
G_CMAP was failing, since it does check for size of CMAP buffer.
Called "fb_alloc_cmap" for llocating memory for CMAP.
We are currently not supporting 1,2,4,8 bpp, so meaning less
for us as of now. But for completeness this is required.
Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
---
drivers/video/omap2/omapfb/omapfb-main.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 44febef..afe40a9 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1525,6 +1525,11 @@ int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
goto err;
set_fb_fix(fbi);
+
+ r = fb_alloc_cmap(&fbi->cmap, 256, 0);
+ if (r)
+ dev_err(fbdev->dev, "unable to allocate color map memory\n");
+
err:
return r;
}
--
1.5.6.5

View File

@ -0,0 +1,65 @@
From 9c93bcab724b5935d745604773ed43825efefd87 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Thu, 2 Apr 2009 13:47:11 +0300
Subject: [PATCH] DSS2: Fix DMA rotation
u16 was not a good type for offsets. First, they need to be signed,
and second, 16 bits is not enough.
---
drivers/video/omap2/dss/dispc.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ffb5648..6cea545 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -778,7 +778,7 @@ static void _dispc_set_vid_size(enum omap_plane plane, int width, int height)
dispc_write_reg(vsi_reg[plane-1], val);
}
-static void _dispc_set_pix_inc(enum omap_plane plane, u16 inc)
+static void _dispc_set_pix_inc(enum omap_plane plane, s32 inc)
{
const struct dispc_reg ri_reg[] = { DISPC_GFX_PIXEL_INC,
DISPC_VID_PIXEL_INC(0),
@@ -787,7 +787,7 @@ static void _dispc_set_pix_inc(enum omap_plane plane, u16 inc)
dispc_write_reg(ri_reg[plane], inc);
}
-static void _dispc_set_row_inc(enum omap_plane plane, u16 inc)
+static void _dispc_set_row_inc(enum omap_plane plane, s32 inc)
{
const struct dispc_reg ri_reg[] = { DISPC_GFX_ROW_INC,
DISPC_VID_ROW_INC(0),
@@ -1123,7 +1123,7 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
}
}
-static int pixinc(int pixels, u8 ps)
+static s32 pixinc(int pixels, u8 ps)
{
if (pixels == 1)
return 1;
@@ -1140,7 +1140,7 @@ static void calc_rotation_offset(u8 rotation, bool mirror,
u16 width, u16 height,
enum omap_color_mode color_mode, bool fieldmode,
unsigned *offset0, unsigned *offset1,
- u16 *row_inc, u16 *pix_inc)
+ s32 *row_inc, s32 *pix_inc)
{
u8 ps;
u16 fbw, fbh;
@@ -1298,8 +1298,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
bool fieldmode = 0;
int cconv = 0;
unsigned offset0, offset1;
- u16 row_inc;
- u16 pix_inc;
+ s32 row_inc;
+ s32 pix_inc;
if (plane == OMAP_DSS_GFX) {
if (width != out_width || height != out_height)
--
1.5.6.5

View File

@ -0,0 +1,41 @@
From 360a55ddd309e3a45b227a4a905ae7120dd16169 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Thu, 2 Apr 2009 14:21:12 +0300
Subject: [PATCH] DSS2: Verify that overlay paddr != 0
---
drivers/video/omap2/dss/dispc.c | 3 +++
drivers/video/omap2/dss/overlay.c | 3 +++
2 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 6cea545..2480a03 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1301,6 +1301,9 @@ static int _dispc_setup_plane(enum omap_plane plane,
s32 row_inc;
s32 pix_inc;
+ if (paddr == 0)
+ return -EINVAL;
+
if (plane == OMAP_DSS_GFX) {
if (width != out_width || height != out_height)
return -EINVAL;
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 968edbe..9209acf 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -331,6 +331,9 @@ static int dss_ovl_set_overlay_info(struct omap_overlay *ovl,
int r;
struct omap_overlay_info old_info;
+ if (info->paddr == 0)
+ return -EINVAL;
+
old_info = ovl->info;
ovl->info = *info;
--
1.5.6.5

View File

@ -0,0 +1,51 @@
From 832b763db235da8e62f7b6ab02bcb8ad6bcb7a01 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Thu, 2 Apr 2009 16:48:41 +0300
Subject: [PATCH] DSS2: Add function to get DSS logic clock rate
---
drivers/video/omap2/dss/dispc.c | 15 +++++++++++++++
drivers/video/omap2/dss/dss.h | 1 +
2 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 2480a03..1bc23f7 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1850,6 +1850,21 @@ unsigned long dispc_fclk_rate(void)
return r;
}
+unsigned long dispc_lclk_rate(void)
+{
+ int lcd;
+ unsigned long r;
+ u32 l;
+
+ l = dispc_read_reg(DISPC_DIVISOR);
+
+ lcd = FLD_GET(l, 23, 16);
+
+ r = dispc_fclk_rate();
+
+ return r / lcd;
+}
+
unsigned long dispc_pclk_rate(void)
{
int lcd, pcd;
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index bac5ece..0be42b6 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -294,6 +294,7 @@ bool dispc_trans_key_enabled(enum omap_channel ch);
void dispc_set_lcd_timings(struct omap_video_timings *timings);
unsigned long dispc_fclk_rate(void);
+unsigned long dispc_lclk_rate(void);
unsigned long dispc_pclk_rate(void);
void dispc_set_pol_freq(struct omap_panel *panel);
void find_lck_pck_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
--
1.5.6.5

View File

@ -0,0 +1,68 @@
From a5c235a6f0094494ae1fc1a1ba4728e0d33dfd3b Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Thu, 2 Apr 2009 16:49:27 +0300
Subject: [PATCH] DSS2: DSI: calculate VP_CLK_RATIO properly
---
drivers/video/omap2/dss/dsi.c | 17 +++++++++++------
1 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 4442931..aecb89d 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -1104,7 +1104,10 @@ int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv)
enable_clocks(1);
dsi_enable_pll_clock(1);
- /* configure dispc fck and pixel clock to something sane */
+ /* XXX this should be calculated depending on the screen size,
+ * required framerate and DSI speed.
+ * For now 48MHz is enough for 864x480@60 with 360Mbps/lane
+ * with two lanes */
r = dispc_calc_clock_div(1, 48 * 1000 * 1000, &cinfo);
if (r)
goto err0;
@@ -1119,7 +1122,7 @@ int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv)
if (r)
goto err0;
- /* PLL does not come out of reset without this... */
+ /* XXX PLL does not come out of reset without this... */
dispc_pck_free_enable(1);
if (wait_for_bit_change(DSI_PLL_STATUS, 0, 1) != 1) {
@@ -1128,8 +1131,8 @@ int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv)
goto err1;
}
- /* ... but if left on, we get problems when planes do not
- * fill the whole display. No idea about this XXX */
+ /* XXX ... but if left on, we get problems when planes do not
+ * fill the whole display. No idea about this */
dispc_pck_free_enable(0);
if (enable_hsclk && enable_hsdiv)
@@ -2214,6 +2217,7 @@ static int dsi_proto_config(struct omap_display *display)
{
u32 r;
int buswidth = 0;
+ int div;
dsi_config_tx_fifo(DSI_FIFO_SIZE_128,
DSI_FIFO_SIZE_0,
@@ -2254,8 +2258,9 @@ static int dsi_proto_config(struct omap_display *display)
r = FLD_MOD(r, 1, 1, 1); /* CS_RX_EN */
r = FLD_MOD(r, 1, 2, 2); /* ECC_RX_EN */
r = FLD_MOD(r, 1, 3, 3); /* TX_FIFO_ARBITRATION */
- /* XXX what should the ratio be */
- r = FLD_MOD(r, 0, 4, 4); /* VP_CLK_RATIO, VP_PCLK = VP_CLK/2 */
+
+ div = dispc_lclk_rate() / dispc_pclk_rate();
+ r = FLD_MOD(r, div == 2 ? 0 : 1, 4, 4); /* VP_CLK_RATIO */
r = FLD_MOD(r, buswidth, 7, 6); /* VP_DATA_BUS_WIDTH */
r = FLD_MOD(r, 0, 8, 8); /* VP_CLK_POL */
r = FLD_MOD(r, 2, 13, 12); /* LINE_BUFFER, 2 lines */
--
1.5.6.5

View File

@ -0,0 +1,58 @@
From 6b2c9d84c7accdfe1067fcdc8a00e50674aab4bb Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Thu, 2 Apr 2009 17:42:26 +0300
Subject: [PATCH] DSS2: DSI: improve packet len calculation
---
drivers/video/omap2/dss/dsi.c | 21 ++++++++++++++++-----
1 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index aecb89d..66ac6ea 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -2624,17 +2624,28 @@ static void dsi_update_screen_dispc(struct omap_display *display,
u16 x, u16 y, u16 w, u16 h)
{
int bytespp = 3;
+ int len;
int total_len;
- int line_packet_len;
+ int packet_payload;
+ int packet_len;
u32 l;
if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL)
DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
x, y, w, h);
- /* TODO: one packet could be longer, I think? Max is the line buffer */
- line_packet_len = w * bytespp + 1; /* 1 byte for DCS cmd */
- total_len = line_packet_len * h;
+ len = w * h * bytespp;
+
+ /* XXX: one packet could be longer, I think? Line buffer is
+ * 1024 x 24bits, but we have to put DCS cmd there also.
+ * 1023 * 3 should work, but causes strange color effects. */
+ packet_payload = min(w, (u16)1020) * bytespp;
+
+ packet_len = packet_payload + 1; /* 1 byte for DCS cmd */
+ total_len = (len / packet_payload) * packet_len;
+
+ if (len % packet_payload)
+ total_len += (len % packet_payload) + 1;
display->ctrl->setup_update(display, x, y, w, h);
@@ -2646,7 +2657,7 @@ static void dsi_update_screen_dispc(struct omap_display *display,
l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
dsi_write_reg(DSI_VC_TE(1), l);
- dsi_vc_write_long_header(1, DSI_DT_DCS_LONG_WRITE, line_packet_len, 0);
+ dsi_vc_write_long_header(1, DSI_DT_DCS_LONG_WRITE, packet_len, 0);
if (dsi.use_te)
l = FLD_MOD(l, 1, 30, 30); /* TE_EN */
--
1.5.6.5

View File

@ -0,0 +1,103 @@
From 85848d329ca3a2d6ee6841cdc11cc5951d187931 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@nokia.com>
Date: Fri, 3 Apr 2009 19:09:20 +0200
Subject: [PATCH] DSS2: Disable video planes on sync lost error
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
When encountering the sync lost error disable the display and all video
planes on the affected manager. Afterwards re-enable the display.
Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com>
---
drivers/video/omap2/dss/dispc.c | 50 +++++++++++++++++++++++++++++++++++++++
1 files changed, 50 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 1bc23f7..41734f3 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2518,29 +2518,79 @@ static void dispc_error_worker(struct work_struct *work)
}
if (errors & DISPC_IRQ_SYNC_LOST) {
+ struct omap_overlay_manager *manager = NULL;
+ bool enable = false;
+
DSSERR("SYNC_LOST, disabling LCD\n");
+
for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
struct omap_overlay_manager *mgr;
mgr = omap_dss_get_overlay_manager(i);
if (mgr->id == OMAP_DSS_CHANNEL_LCD) {
+ manager = mgr;
+ enable = mgr->display->state ==
+ OMAP_DSS_DISPLAY_ACTIVE;
mgr->display->disable(mgr->display);
break;
}
}
+
+ if (manager) {
+ for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+ struct omap_overlay *ovl;
+ ovl = omap_dss_get_overlay(i);
+
+ if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
+ continue;
+
+ if (ovl->id != 0 && ovl->manager == manager)
+ dispc_enable_plane(ovl->id, 0);
+ }
+
+ dispc_go(manager->id);
+ mdelay(50);
+ if (enable)
+ manager->display->enable(manager->display);
+ }
}
if (errors & DISPC_IRQ_SYNC_LOST_DIGIT) {
+ struct omap_overlay_manager *manager = NULL;
+ bool enable = false;
+
DSSERR("SYNC_LOST_DIGIT, disabling TV\n");
+
for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
struct omap_overlay_manager *mgr;
mgr = omap_dss_get_overlay_manager(i);
if (mgr->id == OMAP_DSS_CHANNEL_DIGIT) {
+ manager = mgr;
+ enable = mgr->display->state ==
+ OMAP_DSS_DISPLAY_ACTIVE;
mgr->display->disable(mgr->display);
break;
}
}
+
+ if (manager) {
+ for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
+ struct omap_overlay *ovl;
+ ovl = omap_dss_get_overlay(i);
+
+ if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
+ continue;
+
+ if (ovl->id != 0 && ovl->manager == manager)
+ dispc_enable_plane(ovl->id, 0);
+ }
+
+ dispc_go(manager->id);
+ mdelay(50);
+ if (enable)
+ manager->display->enable(manager->display);
+ }
}
if (errors & DISPC_IRQ_OCP_ERR) {
--
1.5.6.5

View File

@ -0,0 +1,40 @@
From 63e15ba8d5f95b13d3abf359da718537d769f112 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Tue, 7 Apr 2009 10:01:58 +0300
Subject: [PATCH] DSS2: check for ovl paddr only when enabling
It seems Xvideo uses SETUP_PLANE ioctl even when
the fb memory has not been allocated. Sigh.
---
drivers/video/omap2/dss/overlay.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 9209acf..c047206 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -281,6 +281,11 @@ int dss_check_overlay(struct omap_overlay *ovl, struct omap_display *display)
info = &ovl->info;
+ if (info->paddr == 0) {
+ DSSDBG("check_overlay failed: paddr 0\n");
+ return -EINVAL;
+ }
+
display->get_resolution(display, &dw, &dh);
DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n",
@@ -331,9 +336,6 @@ static int dss_ovl_set_overlay_info(struct omap_overlay *ovl,
int r;
struct omap_overlay_info old_info;
- if (info->paddr == 0)
- return -EINVAL;
-
old_info = ovl->info;
ovl->info = *info;
--
1.5.6.5

View File

@ -0,0 +1,183 @@
From 67f3fc050ab4e2006d5b7ec6ec341896627181ab Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@nokia.com>
Date: Mon, 6 Apr 2009 17:32:04 +0200
Subject: [PATCH] DSS2: Check fclk limits when configuring video planes
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Check that the currect functional clock is fast enough to support
the requested scaling ratios. Also check if 5-tap filtering can be
used even though the downscaling ratio is less than 1:2 since the
functional clock rate required for 5-tap filtering can be less than
the requirement for 3-tap filtering, and 5-tap filtering should look
better.
Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com>
---
drivers/video/omap2/dss/dispc.c | 104 ++++++++++++++++++++++++++++++++++++---
1 files changed, 97 insertions(+), 7 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 41734f3..61861d8 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1026,11 +1026,11 @@ static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
static void _dispc_set_scaling(enum omap_plane plane,
u16 orig_width, u16 orig_height,
u16 out_width, u16 out_height,
- bool ilace)
+ bool ilace, bool five_taps)
{
int fir_hinc;
int fir_vinc;
- int hscaleup, vscaleup, five_taps;
+ int hscaleup, vscaleup;
int fieldmode = 0;
int accu0 = 0;
int accu1 = 0;
@@ -1040,7 +1040,6 @@ static void _dispc_set_scaling(enum omap_plane plane,
hscaleup = orig_width <= out_width;
vscaleup = orig_height <= out_height;
- five_taps = orig_height > out_height * 2;
_dispc_set_scale_coef(plane, hscaleup, vscaleup, five_taps);
@@ -1283,6 +1282,73 @@ static void calc_rotation_offset(u8 rotation, bool mirror,
}
}
+static unsigned long calc_fclk_five_taps(u16 width, u16 height,
+ u16 out_width, u16 out_height, enum omap_color_mode color_mode)
+{
+ u32 fclk = 0;
+ /* FIXME venc pclk? */
+ u64 tmp, pclk = dispc_pclk_rate();
+
+ if (height > out_height) {
+ /* FIXME get real display PPL */
+ unsigned int ppl = 800;
+
+ tmp = pclk * height * out_width;
+ do_div(tmp, 2 * out_height * ppl);
+ fclk = tmp;
+
+ if (height > 2 * out_height) {
+ tmp = pclk * (height - 2 * out_height) * out_width;
+ do_div(tmp, 2 * out_height * (ppl - out_width));
+ fclk = max(fclk, (u32) tmp);
+ }
+ }
+
+ if (width > out_width) {
+ tmp = pclk * width;
+ do_div(tmp, out_width);
+ fclk = max(fclk, (u32) tmp);
+
+ if (color_mode == OMAP_DSS_COLOR_RGB24U)
+ fclk <<= 1;
+ }
+
+ return fclk;
+}
+
+static unsigned long calc_fclk(u16 width, u16 height,
+ u16 out_width, u16 out_height,
+ enum omap_color_mode color_mode, bool five_taps)
+{
+ unsigned int hf, vf;
+
+ if (five_taps)
+ return calc_fclk_five_taps(width, height,
+ out_width, out_height, color_mode);
+
+ /*
+ * FIXME how to determine the 'A' factor
+ * for the no downscaling case ?
+ */
+
+ if (width > 3 * out_width)
+ hf = 4;
+ else if (width > 2 * out_width)
+ hf = 3;
+ else if (width > out_width)
+ hf = 2;
+ else
+ hf = 1;
+
+ if (height > out_height)
+ vf = 2;
+ else
+ vf = 1;
+
+ /* FIXME venc pclk? */
+ return dispc_pclk_rate() * vf * hf;
+}
+
static int _dispc_setup_plane(enum omap_plane plane,
enum omap_channel channel_out,
u32 paddr, u16 screen_width,
@@ -1294,7 +1360,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
u8 rotation, int mirror)
{
const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
- bool five_taps = height > out_height * 2;
+ bool five_taps = 0;
bool fieldmode = 0;
int cconv = 0;
unsigned offset0, offset1;
@@ -1323,8 +1389,8 @@ static int _dispc_setup_plane(enum omap_plane plane,
}
} else {
/* video plane */
- if (width > (2048 >> five_taps))
- return -EINVAL;
+
+ unsigned long fclk;
if (out_width < width / maxdownscale ||
out_width > width * 8)
@@ -1356,6 +1422,30 @@ static int _dispc_setup_plane(enum omap_plane plane,
default:
return -EINVAL;
}
+
+ /* Must use 5-tap filter? */
+ five_taps = height > out_height * 2;
+
+ /* Try to use 5-tap filter whenever possible. */
+ if (cpu_is_omap34xx() && !five_taps &&
+ height > out_height && width <= 1024) {
+ fclk = calc_fclk_five_taps(width, height,
+ out_width, out_height, color_mode);
+ if (fclk <= dispc_fclk_rate())
+ five_taps = true;
+ }
+
+ if (width > (2048 >> five_taps))
+ return -EINVAL;
+
+ fclk = calc_fclk(width, height, out_width, out_height,
+ color_mode, five_taps);
+
+ DSSDBG("required fclk rate = %lu Hz\n", fclk);
+ DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
+
+ if (fclk > dispc_fclk_rate())
+ return -EINVAL;
}
if (ilace && height >= out_height)
@@ -1399,7 +1489,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
if (plane != OMAP_DSS_GFX) {
_dispc_set_scaling(plane, width, height,
out_width, out_height,
- ilace);
+ ilace, five_taps);
_dispc_set_vid_size(plane, out_width, out_height);
_dispc_set_vid_color_conv(plane, cconv);
}
--
1.5.6.5

View File

@ -0,0 +1,79 @@
From 9f8f1613253656f155b3844c8255a560f86e0acd Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@nokia.com>
Date: Mon, 6 Apr 2009 17:32:05 +0200
Subject: [PATCH] DSS2: Check scaling limits against proper values
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Move the ilace and fieldmode related height adjustments to be performed
before checking the scaling limits.
Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com>
---
drivers/video/omap2/dss/dispc.c | 31 ++++++++++++++++---------------
1 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 61861d8..ae7be3d 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1366,10 +1366,25 @@ static int _dispc_setup_plane(enum omap_plane plane,
unsigned offset0, offset1;
s32 row_inc;
s32 pix_inc;
+ u16 frame_height = height;
if (paddr == 0)
return -EINVAL;
+ if (ilace && height >= out_height)
+ fieldmode = 1;
+
+ if (ilace) {
+ if (fieldmode)
+ height /= 2;
+ pos_y /= 2;
+ out_height /= 2;
+
+ DSSDBG("adjusting for ilace: height %d, pos_y %d, "
+ "out_height %d\n",
+ height, pos_y, out_height);
+ }
+
if (plane == OMAP_DSS_GFX) {
if (width != out_width || height != out_height)
return -EINVAL;
@@ -1448,28 +1463,14 @@ static int _dispc_setup_plane(enum omap_plane plane,
return -EINVAL;
}
- if (ilace && height >= out_height)
- fieldmode = 1;
-
calc_rotation_offset(rotation, mirror,
- screen_width, width, height, color_mode,
+ screen_width, width, frame_height, color_mode,
fieldmode,
&offset0, &offset1, &row_inc, &pix_inc);
DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
offset0, offset1, row_inc, pix_inc);
- if (ilace) {
- if (fieldmode)
- height /= 2;
- pos_y /= 2;
- out_height /= 2;
-
- DSSDBG("adjusting for ilace: height %d, pos_y %d, "
- "out_height %d\n",
- height, pos_y, out_height);
- }
-
_dispc_set_channel_out(plane, channel_out);
_dispc_set_color_mode(plane, color_mode);
--
1.5.6.5

View File

@ -0,0 +1,96 @@
From c5e71be877e71c7df329205307e830f158c403bf Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@nokia.com>
Date: Mon, 6 Apr 2009 17:32:06 +0200
Subject: [PATCH] DSS2: Add venc register dump
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
Add a new file to debugfs to dump the VENC registers. The function
prototype was already there but the implementation was missing.
Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com>
---
drivers/video/omap2/dss/venc.c | 55 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index aceed9f..b655df4 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -30,6 +30,7 @@
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/string.h>
+#include <linux/seq_file.h>
#include <mach/display.h>
#include <mach/cpu.h>
@@ -81,6 +82,7 @@
#define VENC_TVDETGP_INT_START_STOP_Y 0xB4
#define VENC_GEN_CTRL 0xB8
#define VENC_OUTPUT_CONTROL 0xC4
+#define VENC_OUTPUT_TEST 0xC8
#define VENC_DAC_B__DAC_C 0xC8
struct venc_config {
@@ -598,3 +600,56 @@ void venc_init_display(struct omap_display *display)
display->set_timings = venc_set_timings;
display->check_timings = venc_check_timings;
}
+
+void venc_dump_regs(struct seq_file *s)
+{
+#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r))
+
+ venc_enable_clocks(1);
+
+ DUMPREG(VENC_F_CONTROL);
+ DUMPREG(VENC_VIDOUT_CTRL);
+ DUMPREG(VENC_SYNC_CTRL);
+ DUMPREG(VENC_LLEN);
+ DUMPREG(VENC_FLENS);
+ DUMPREG(VENC_HFLTR_CTRL);
+ DUMPREG(VENC_CC_CARR_WSS_CARR);
+ DUMPREG(VENC_C_PHASE);
+ DUMPREG(VENC_GAIN_U);
+ DUMPREG(VENC_GAIN_V);
+ DUMPREG(VENC_GAIN_Y);
+ DUMPREG(VENC_BLACK_LEVEL);
+ DUMPREG(VENC_BLANK_LEVEL);
+ DUMPREG(VENC_X_COLOR);
+ DUMPREG(VENC_M_CONTROL);
+ DUMPREG(VENC_BSTAMP_WSS_DATA);
+ DUMPREG(VENC_S_CARR);
+ DUMPREG(VENC_LINE21);
+ DUMPREG(VENC_LN_SEL);
+ DUMPREG(VENC_L21__WC_CTL);
+ DUMPREG(VENC_HTRIGGER_VTRIGGER);
+ DUMPREG(VENC_SAVID__EAVID);
+ DUMPREG(VENC_FLEN__FAL);
+ DUMPREG(VENC_LAL__PHASE_RESET);
+ DUMPREG(VENC_HS_INT_START_STOP_X);
+ DUMPREG(VENC_HS_EXT_START_STOP_X);
+ DUMPREG(VENC_VS_INT_START_X);
+ DUMPREG(VENC_VS_INT_STOP_X__VS_INT_START_Y);
+ DUMPREG(VENC_VS_INT_STOP_Y__VS_EXT_START_X);
+ DUMPREG(VENC_VS_EXT_STOP_X__VS_EXT_START_Y);
+ DUMPREG(VENC_VS_EXT_STOP_Y);
+ DUMPREG(VENC_AVID_START_STOP_X);
+ DUMPREG(VENC_AVID_START_STOP_Y);
+ DUMPREG(VENC_FID_INT_START_X__FID_INT_START_Y);
+ DUMPREG(VENC_FID_INT_OFFSET_Y__FID_EXT_START_X);
+ DUMPREG(VENC_FID_EXT_START_Y__FID_EXT_OFFSET_Y);
+ DUMPREG(VENC_TVDETGP_INT_START_STOP_X);
+ DUMPREG(VENC_TVDETGP_INT_START_STOP_Y);
+ DUMPREG(VENC_GEN_CTRL);
+ DUMPREG(VENC_OUTPUT_CONTROL);
+ DUMPREG(VENC_OUTPUT_TEST);
+
+ venc_enable_clocks(0);
+
+#undef DUMPREG
+}
--
1.5.6.5

View File

@ -0,0 +1,27 @@
From facfd479bb6efad76eec1e74048cb7a31da7287d Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@nokia.com>
Date: Mon, 6 Apr 2009 22:26:04 +0200
Subject: [PATCH] DSS2: FB: remove unused var warning
Signed-off-by: Imre Deak <imre.deak@nokia.com>
---
drivers/video/omap2/omapfb/omapfb-main.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index afe40a9..12ce0c3 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1246,7 +1246,9 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
display->get_resolution(display, &w, &h);
if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
+#ifdef DEBUG
int oldw = w, oldh = h;
+#endif
omap_vrfb_adjust_size(&w, &h, bytespp);
--
1.5.6.5

View File

@ -0,0 +1,214 @@
From c02b843c2732bc7b15a3e35b5dd715d68225bbd1 Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@nokia.com>
Date: Wed, 8 Apr 2009 12:51:46 +0200
Subject: [PATCH] DSS2: pass the default FB color format through board info
Add a field to the FB memory region platform data, so that board
init code can pass a default color format to the driver. Set this
format as an initial setting for the given FB.
This is needed for an upcoming patch that adds detection of the
color format set by the bootloader.
Signed-off-by: Imre Deak <imre.deak@nokia.com>
---
drivers/video/omap2/omapfb/omapfb-main.c | 121 +++++++++++++++++++++++++++---
drivers/video/omap2/omapfb/omapfb.h | 2 +
include/linux/omapfb.h | 5 +
3 files changed, 117 insertions(+), 11 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 12ce0c3..67c67c2 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -370,6 +370,21 @@ static enum omap_color_mode fb_mode_to_dss_mode(struct fb_var_screeninfo *var)
return -EINVAL;
}
+static int dss_mode_to_fb_mode(enum omap_color_mode dssmode,
+ struct fb_var_screeninfo *var)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) {
+ struct omapfb_colormode *mode = &omapfb_colormodes[i];
+ if (dssmode == mode->dssmode) {
+ assign_colormode_to_var(var, mode);
+ return 0;
+ }
+ }
+ return -ENOENT;
+}
+
void set_fb_fix(struct fb_info *fbi)
{
struct fb_fix_screeninfo *fix = &fbi->fix;
@@ -1267,6 +1282,60 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
return omapfb_alloc_fbmem(fbi, size, paddr);
}
+static enum omap_color_mode fb_format_to_dss_mode(enum omapfb_color_format format)
+{
+ enum omap_color_mode mode;
+
+ switch (format) {
+ case OMAPFB_COLOR_RGB565:
+ mode = OMAP_DSS_COLOR_RGB16;
+ break;
+ case OMAPFB_COLOR_YUV422:
+ mode = OMAP_DSS_COLOR_YUV2;
+ break;
+ case OMAPFB_COLOR_CLUT_8BPP:
+ mode = OMAP_DSS_COLOR_CLUT8;
+ break;
+ case OMAPFB_COLOR_CLUT_4BPP:
+ mode = OMAP_DSS_COLOR_CLUT4;
+ break;
+ case OMAPFB_COLOR_CLUT_2BPP:
+ mode = OMAP_DSS_COLOR_CLUT2;
+ break;
+ case OMAPFB_COLOR_CLUT_1BPP:
+ mode = OMAP_DSS_COLOR_CLUT1;
+ break;
+ case OMAPFB_COLOR_RGB444:
+ mode = OMAP_DSS_COLOR_RGB12U;
+ break;
+ case OMAPFB_COLOR_YUY422:
+ mode = OMAP_DSS_COLOR_UYVY;
+ break;
+ case OMAPFB_COLOR_ARGB16:
+ mode = OMAP_DSS_COLOR_ARGB16;
+ break;
+ case OMAPFB_COLOR_RGB24U:
+ mode = OMAP_DSS_COLOR_RGB24U;
+ break;
+ case OMAPFB_COLOR_RGB24P:
+ mode = OMAP_DSS_COLOR_RGB24P;
+ break;
+ case OMAPFB_COLOR_ARGB32:
+ mode = OMAP_DSS_COLOR_ARGB32;
+ break;
+ case OMAPFB_COLOR_RGBA32:
+ mode = OMAP_DSS_COLOR_RGBA32;
+ break;
+ case OMAPFB_COLOR_RGBX32:
+ mode = OMAP_DSS_COLOR_RGBX32;
+ break;
+ default:
+ mode = -EINVAL;
+ }
+
+ return mode;
+}
+
static int omapfb_parse_vram_param(const char *param, int max_entries,
unsigned long *sizes, unsigned long *paddrs)
{
@@ -1483,9 +1552,36 @@ int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
}
var->nonstd = 0;
+ var->bits_per_pixel = 0;
var->rotate = ofbi->rotation;
+ /*
+ * Check if there is a default color format set in the board file,
+ * and use this format instead the default deducted from the
+ * display bpp.
+ */
+ if (fbdev->dev->platform_data) {
+ struct omapfb_platform_data *opd;
+ int id = ofbi->id;
+
+ opd = fbdev->dev->platform_data;
+ if (opd->mem_desc.region[id].format_used) {
+ enum omap_color_mode mode;
+ enum omapfb_color_format format;
+
+ format = opd->mem_desc.region[id].format;
+ mode = fb_format_to_dss_mode(format);
+ if (mode < 0) {
+ r = mode;
+ goto err;
+ }
+ r = dss_mode_to_fb_mode(mode, var);
+ if (r < 0)
+ goto err;
+ }
+ }
+
if (display) {
u16 w, h;
display->get_resolution(display, &w, &h);
@@ -1502,16 +1598,18 @@ int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
var->xres_virtual = var->xres;
var->yres_virtual = var->yres;
- switch (display->get_recommended_bpp(display)) {
- case 16:
- var->bits_per_pixel = 16;
- break;
- case 24:
- var->bits_per_pixel = 32;
- break;
- default:
- dev_err(fbdev->dev, "illegal display bpp\n");
- return -EINVAL;
+ if (!var->bits_per_pixel) {
+ switch (display->get_recommended_bpp(display)) {
+ case 16:
+ var->bits_per_pixel = 16;
+ break;
+ case 24:
+ var->bits_per_pixel = 32;
+ break;
+ default:
+ dev_err(fbdev->dev, "illegal display bpp\n");
+ return -EINVAL;
+ }
}
} else {
/* if there's no display, let's just guess some basic values */
@@ -1519,7 +1617,8 @@ int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
var->yres = 240;
var->xres_virtual = var->xres;
var->yres_virtual = var->yres;
- var->bits_per_pixel = 16;
+ if (!var->bits_per_pixel)
+ var->bits_per_pixel = 16;
}
r = check_fb_var(fbi, var);
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 65e9e6e..2607def 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -27,6 +27,8 @@
#define DEBUG
#endif
+#include <mach/display.h>
+
#ifdef DEBUG
extern unsigned int omapfb_debug;
#define DBG(format, ...) \
diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h
index 96190b2..7a34f22 100644
--- a/include/linux/omapfb.h
+++ b/include/linux/omapfb.h
@@ -298,6 +298,11 @@ struct omapfb_mem_region {
void __iomem *vaddr;
unsigned long size;
u8 type; /* OMAPFB_PLANE_MEM_* */
+ enum omapfb_color_format format;/* OMAPFB_COLOR_* */
+ unsigned format_used:1; /* Must be set when format is set.
+ * Needed b/c of the badly chosen 0
+ * base for OMAPFB_COLOR_* values
+ */
unsigned alloc:1; /* allocated by the driver */
unsigned map:1; /* kernel mapped by the driver */
};
--
1.5.6.5

View File

@ -0,0 +1,48 @@
From 2710416c43572652cb5355a5eaf68038c95659e8 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Thu, 9 Apr 2009 12:10:46 +0300
Subject: [PATCH] DSS2: Beagle: Use gpio_set_value
---
arch/arm/mach-omap2/board-omap3beagle.c | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
index b67e7a5..8c1961d 100644
--- a/arch/arm/mach-omap2/board-omap3beagle.c
+++ b/arch/arm/mach-omap2/board-omap3beagle.c
@@ -372,7 +372,7 @@ static struct platform_device keys_gpio = {
static int beagle_enable_dvi(struct omap_display *display)
{
if (display->hw_config.panel_reset_gpio != -1)
- gpio_direction_output(display->hw_config.panel_reset_gpio, 1);
+ gpio_set_value(display->hw_config.panel_reset_gpio, 1);
return 0;
}
@@ -380,7 +380,7 @@ static int beagle_enable_dvi(struct omap_display *display)
static void beagle_disable_dvi(struct omap_display *display)
{
if (display->hw_config.panel_reset_gpio != -1)
- gpio_direction_output(display->hw_config.panel_reset_gpio, 0);
+ gpio_set_value(display->hw_config.panel_reset_gpio, 0);
}
static struct omap_dss_display_config beagle_display_data_dvi = {
@@ -445,8 +445,12 @@ static void __init beagle_display_init(void)
int r;
r = gpio_request(beagle_display_data_dvi.panel_reset_gpio, "DVI reset");
- if (r < 0)
+ if (r < 0) {
printk(KERN_ERR "Unable to get DVI reset GPIO\n");
+ return;
+ }
+
+ gpio_direction_output(beagle_display_data_dvi.panel_reset_gpio, 0);
}
static struct omap_board_config_kernel omap3_beagle_config[] __initdata = {
--
1.5.6.5

View File

@ -0,0 +1,28 @@
From 990f3160d33361c135ee72e91f202e05a8c378fc Mon Sep 17 00:00:00 2001
From: Hardik Shah <hardik.shah@ti.com>
Date: Mon, 13 Apr 2009 18:50:24 +0530
Subject: [PATCH] DSS2: VRFB: Macro for calculating base address of the VRFB context was faulty
Signed-off-by: Hardik Shah <hardik.shah@ti.com>
---
arch/arm/plat-omap/vrfb.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/plat-omap/vrfb.c b/arch/arm/plat-omap/vrfb.c
index 7e0f8fc..d68065f 100644
--- a/arch/arm/plat-omap/vrfb.c
+++ b/arch/arm/plat-omap/vrfb.c
@@ -16,8 +16,8 @@
#define SMS_ROT_VIRT_BASE(context, rot) \
(((context >= 4) ? 0xD0000000 : 0x70000000) \
- | 0x4000000 * (context) \
- | 0x1000000 * (rot))
+ + (0x4000000 * (context)) \
+ + (0x1000000 * (rot)))
#define OMAP_VRFB_SIZE (2048 * 2048 * 4)
--
1.5.6.5

View File

@ -0,0 +1,78 @@
From a1e8018c0806a1a0579eda4b93b7d6764a2ff643 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Wed, 15 Apr 2009 14:06:54 +0300
Subject: [PATCH] DSS2: DSI: sidlemode to noidle while sending frame
DISPC interrupts are not wake-up capable. Smart-idle in DISPC_SIDLEMODE
causes DSS interface to go to idle at the end of the frame, and the
FRAMEDONE interrupt is then delayed until something wakes up the DSS
interface.
So we set SIDLEMODE to no-idle when we start sending the frame, and
set it back to smart-idle after receiving FRAMEDONE.
---
drivers/video/omap2/dss/dispc.c | 10 ++++++++++
drivers/video/omap2/dss/dsi.c | 4 ++++
drivers/video/omap2/dss/dss.h | 3 +++
3 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index ae7be3d..16c68b8 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2791,6 +2791,16 @@ static void _omap_dispc_initialize_irq(void)
omap_dispc_set_irqs();
}
+void dispc_enable_sidle(void)
+{
+ REG_FLD_MOD(DISPC_SYSCONFIG, 2, 4, 3); /* SIDLEMODE: smart idle */
+}
+
+void dispc_disable_sidle(void)
+{
+ REG_FLD_MOD(DISPC_SYSCONFIG, 1, 4, 3); /* SIDLEMODE: no idle */
+}
+
static void _omap_dispc_initial_config(void)
{
u32 l;
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 66ac6ea..50af925 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -2665,6 +2665,8 @@ static void dsi_update_screen_dispc(struct omap_display *display,
l = FLD_MOD(l, 1, 31, 31); /* TE_START */
dsi_write_reg(DSI_VC_TE(1), l);
+ dispc_disable_sidle();
+
dispc_enable_lcd_out(1);
if (dsi.use_te)
@@ -2678,6 +2680,8 @@ static void framedone_callback(void *data, u32 mask)
return;
}
+ dispc_enable_sidle();
+
dsi.framedone_scheduled = 1;
/* We get FRAMEDONE when DISPC has finished sending pixels and turns
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 0be42b6..d0917a8 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -244,6 +244,9 @@ void dispc_fake_vsync_irq(void);
void dispc_save_context(void);
void dispc_restore_context(void);
+void dispc_enable_sidle(void);
+void dispc_disable_sidle(void);
+
void dispc_lcd_enable_signal_polarity(bool act_high);
void dispc_lcd_enable_signal(bool enable);
void dispc_pck_free_enable(bool enable);
--
1.5.6.5

View File

@ -0,0 +1,324 @@
From 77e848eeba461e9b55b09d39fd0d640caea13e19 Mon Sep 17 00:00:00 2001
From: Hardik Shah <hardik.shah@ti.com>
Date: Thu, 9 Apr 2009 12:09:44 +0530
Subject: [PATCH] DSS2: VRFB rotation and mirroring implemented.
DSS2 modified to accept the rotation_type input
to get the dma or VRFB rotation.
DSS2: VRFB: Changed to pass DSS mode to vrfb_setup instead of Bpp.
VRFB size registers requires the width to be halved when the
mode is YUV or UYVY. So modifed to pass the mode to omap_vrfb_setup
function.
Code added by Tim Yamin for few bug fixes
Signed-off-by: Tim Yamin <plasm@roo.me.uk>
Signed-off-by: Hardik Shah <hardik.shah@ti.com>
---
arch/arm/plat-omap/include/mach/display.h | 6 ++
arch/arm/plat-omap/include/mach/vrfb.h | 3 +-
arch/arm/plat-omap/vrfb.c | 36 +++++++++-
drivers/video/omap2/dss/dispc.c | 109 +++++++++++++++++++++++++++--
drivers/video/omap2/dss/dss.h | 1 +
drivers/video/omap2/dss/manager.c | 1 +
6 files changed, 144 insertions(+), 12 deletions(-)
diff --git a/arch/arm/plat-omap/include/mach/display.h b/arch/arm/plat-omap/include/mach/display.h
index 6b702c7..b0a6272 100644
--- a/arch/arm/plat-omap/include/mach/display.h
+++ b/arch/arm/plat-omap/include/mach/display.h
@@ -341,6 +341,11 @@ enum omap_dss_overlay_managers {
struct omap_overlay_manager;
+enum omap_dss_rotation_type {
+ OMAP_DSS_ROT_DMA = 0,
+ OMAP_DSS_ROT_VRFB = 1,
+};
+
struct omap_overlay_info {
bool enabled;
@@ -351,6 +356,7 @@ struct omap_overlay_info {
u16 height;
enum omap_color_mode color_mode;
u8 rotation;
+ enum omap_dss_rotation_type rotation_type;
bool mirror;
u16 pos_x;
diff --git a/arch/arm/plat-omap/include/mach/vrfb.h b/arch/arm/plat-omap/include/mach/vrfb.h
index 2047862..12c7fab 100644
--- a/arch/arm/plat-omap/include/mach/vrfb.h
+++ b/arch/arm/plat-omap/include/mach/vrfb.h
@@ -24,6 +24,7 @@
#ifndef __VRFB_H
#define __VRFB_H
+#include <mach/display.h>
#define OMAP_VRFB_LINE_LEN 2048
struct vrfb
@@ -42,6 +43,6 @@ extern void omap_vrfb_adjust_size(u16 *width, u16 *height,
u8 bytespp);
extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
u16 width, u16 height,
- u8 bytespp);
+ enum omap_color_mode color_mode);
#endif /* __VRFB_H */
diff --git a/arch/arm/plat-omap/vrfb.c b/arch/arm/plat-omap/vrfb.c
index d68065f..2f08f6d 100644
--- a/arch/arm/plat-omap/vrfb.c
+++ b/arch/arm/plat-omap/vrfb.c
@@ -5,7 +5,6 @@
#include <mach/io.h>
#include <mach/vrfb.h>
-
/*#define DEBUG*/
#ifdef DEBUG
@@ -50,19 +49,48 @@ EXPORT_SYMBOL(omap_vrfb_adjust_size);
void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
u16 width, u16 height,
- u8 bytespp)
+ enum omap_color_mode color_mode)
{
unsigned pixel_size_exp;
u16 vrfb_width;
u16 vrfb_height;
u8 ctx = vrfb->context;
+ u8 bytespp;
DBG("omapfb_set_vrfb(%d, %lx, %dx%d, %d)\n", ctx, paddr,
width, height, bytespp);
- if (bytespp == 4)
+ switch (color_mode) {
+ case OMAP_DSS_COLOR_RGB16:
+ case OMAP_DSS_COLOR_ARGB16:
+ bytespp = 2;
+ break;
+
+ case OMAP_DSS_COLOR_RGB24P:
+ bytespp = 3;
+ break;
+
+ case OMAP_DSS_COLOR_RGB24U:
+ case OMAP_DSS_COLOR_ARGB32:
+ case OMAP_DSS_COLOR_RGBA32:
+ case OMAP_DSS_COLOR_RGBX32:
+ case OMAP_DSS_COLOR_YUV2:
+ case OMAP_DSS_COLOR_UYVY:
+ bytespp = 4;
+ break;
+
+ default:
+ BUG();
+ return;
+ }
+
+ if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+ color_mode == OMAP_DSS_COLOR_UYVY)
+ width >>= 1;
+
+ if (bytespp == 4) {
pixel_size_exp = 2;
- else if (bytespp == 2)
+ } else if (bytespp == 2)
pixel_size_exp = 1;
else
BUG();
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 16c68b8..23a8155 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1106,7 +1106,7 @@ static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
case 0: vidrot = 0; break;
case 1: vidrot = 1; break;
case 2: vidrot = 2; break;
- case 3: vidrot = 1; break;
+ case 3: vidrot = 3; break;
}
}
@@ -1134,7 +1134,92 @@ static s32 pixinc(int pixels, u8 ps)
BUG();
}
-static void calc_rotation_offset(u8 rotation, bool mirror,
+static void calc_vrfb_rotation_offset(u8 rotation, bool mirror,
+ u16 screen_width,
+ u16 width, u16 height,
+ enum omap_color_mode color_mode, bool fieldmode,
+ unsigned *offset0, unsigned *offset1,
+ s32 *row_inc, s32 *pix_inc)
+{
+ u8 ps;
+
+ switch (color_mode) {
+ case OMAP_DSS_COLOR_RGB16:
+ case OMAP_DSS_COLOR_ARGB16:
+ ps = 2;
+ break;
+
+ case OMAP_DSS_COLOR_RGB24P:
+ ps = 3;
+ break;
+
+ case OMAP_DSS_COLOR_RGB24U:
+ case OMAP_DSS_COLOR_ARGB32:
+ case OMAP_DSS_COLOR_RGBA32:
+ case OMAP_DSS_COLOR_RGBX32:
+ case OMAP_DSS_COLOR_YUV2:
+ case OMAP_DSS_COLOR_UYVY:
+ ps = 4;
+ break;
+
+ default:
+ BUG();
+ return;
+ }
+
+ DSSDBG("calc_rot(%d): scrw %d, %dx%d\n", rotation, screen_width,
+ width, height);
+ switch (rotation + mirror * 4) {
+ case 0:
+ case 2:
+ /*
+ * If the pixel format is YUV or UYVY divide the width
+ * of the image by 2 for 0 and 180 degree rotation.
+ */
+ if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+ color_mode == OMAP_DSS_COLOR_UYVY)
+ width = width >> 1;
+ case 1:
+ case 3:
+ *offset0 = 0;
+ if (fieldmode)
+ *offset1 = screen_width * ps;
+ else
+ *offset1 = 0;
+
+ *row_inc = pixinc(1 + (screen_width - width) +
+ (fieldmode ? screen_width : 0),
+ ps);
+ *pix_inc = pixinc(1, ps);
+ break;
+
+ case 4:
+ case 6:
+ /* If the pixel format is YUV or UYVY divide the width
+ * of the image by 2 for 0 degree and 180 degree
+ */
+ if (color_mode == OMAP_DSS_COLOR_YUV2 ||
+ color_mode == OMAP_DSS_COLOR_UYVY)
+ width = width >> 1;
+ case 5:
+ case 7:
+ *offset0 = 0;
+ if (fieldmode)
+ *offset1 = screen_width * ps;
+ else
+ *offset1 = 0;
+ *row_inc = pixinc(1 - (screen_width + width) -
+ (fieldmode ? screen_width : 0),
+ ps);
+ *pix_inc = pixinc(1, ps);
+ break;
+
+ default:
+ BUG();
+ }
+}
+
+static void calc_dma_rotation_offset(u8 rotation, bool mirror,
u16 screen_width,
u16 width, u16 height,
enum omap_color_mode color_mode, bool fieldmode,
@@ -1357,6 +1442,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
u16 out_width, u16 out_height,
enum omap_color_mode color_mode,
bool ilace,
+ enum omap_dss_rotation_type rotation_type,
u8 rotation, int mirror)
{
const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
@@ -1463,10 +1549,16 @@ static int _dispc_setup_plane(enum omap_plane plane,
return -EINVAL;
}
- calc_rotation_offset(rotation, mirror,
- screen_width, width, frame_height, color_mode,
- fieldmode,
- &offset0, &offset1, &row_inc, &pix_inc);
+ if (rotation_type == OMAP_DSS_ROT_DMA)
+ calc_dma_rotation_offset(rotation, mirror,
+ screen_width, width, frame_height, color_mode,
+ fieldmode,
+ &offset0, &offset1, &row_inc, &pix_inc);
+ else
+ calc_vrfb_rotation_offset(rotation, mirror,
+ screen_width, width, frame_height, color_mode,
+ fieldmode,
+ &offset0, &offset1, &row_inc, &pix_inc);
DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
offset0, offset1, row_inc, pix_inc);
@@ -2889,6 +2981,7 @@ int dispc_setup_plane(enum omap_plane plane, enum omap_channel channel_out,
u16 out_width, u16 out_height,
enum omap_color_mode color_mode,
bool ilace,
+ enum omap_dss_rotation_type rotation_type,
u8 rotation, bool mirror)
{
int r = 0;
@@ -2909,6 +3002,7 @@ int dispc_setup_plane(enum omap_plane plane, enum omap_channel channel_out,
width, height,
out_width, out_height,
color_mode, ilace,
+ rotation_type,
rotation, mirror);
enable_clocks(0);
@@ -3122,7 +3216,8 @@ void dispc_setup_partial_planes(struct omap_display *display,
pw, ph,
pow, poh,
pi->color_mode, 0,
- pi->rotation, // XXX rotation probably wrong
+ pi->rotation_type,
+ pi->rotation,
pi->mirror);
dispc_enable_plane(ovl->id, 1);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index d0917a8..584dce6 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -272,6 +272,7 @@ int dispc_setup_plane(enum omap_plane plane, enum omap_channel channel_out,
u16 out_width, u16 out_height,
enum omap_color_mode color_mode,
bool ilace,
+ enum omap_dss_rotation_type rotation_type,
u8 rotation, bool mirror);
void dispc_go(enum omap_channel channel);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index b0fee80..8ca0bbb 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -395,6 +395,7 @@ static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
outh,
ovl->info.color_mode,
ilace,
+ ovl->info.rotation_type,
ovl->info.rotation,
ovl->info.mirror);
--
1.5.6.5

View File

@ -0,0 +1,236 @@
From c09f1a0642fd58a1b081594ea36dfd1bf71aec52 Mon Sep 17 00:00:00 2001
From: Hardik Shah <hardik.shah@ti.com>
Date: Thu, 9 Apr 2009 12:13:07 +0530
Subject: [PATCH] DSS2: OMAPFB: Added support for the YUV VRFB rotation and mirroring.
DSS2 now requires roatation_type to be specified by driver.
Added support for that.
DSS2 OMAPFB: Modified to pass the dss mode to omap_vrfb_setup function.
VRFB size register requires the width to be halved when the
mode is YUV or UYVY. So VRFB is modifed to pass the mode to omap_vrfb_setup
function.
Few changes done by Tim Yamin
Signed-off-by: Tim Yamin <plasm@roo.me.uk>
Signed-off-by: Hardik Shah <hardik.shah@ti.com>
---
arch/arm/plat-omap/vrfb.c | 4 +-
drivers/video/omap2/omapfb/omapfb-main.c | 59 ++++++++++++++----------------
drivers/video/omap2/omapfb/omapfb.h | 7 +---
3 files changed, 30 insertions(+), 40 deletions(-)
diff --git a/arch/arm/plat-omap/vrfb.c b/arch/arm/plat-omap/vrfb.c
index 2f08f6d..2ae0d68 100644
--- a/arch/arm/plat-omap/vrfb.c
+++ b/arch/arm/plat-omap/vrfb.c
@@ -88,9 +88,9 @@ void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
color_mode == OMAP_DSS_COLOR_UYVY)
width >>= 1;
- if (bytespp == 4) {
+ if (bytespp == 4)
pixel_size_exp = 2;
- } else if (bytespp == 2)
+ else if (bytespp == 2)
pixel_size_exp = 1;
else
BUG();
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 67c67c2..57f5900 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -176,15 +176,9 @@ static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot)
static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi)
{
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
- unsigned offset;
- int rot;
-
- rot = ofbi->rotation;
-
- offset = omapfb_get_vrfb_offset(ofbi, rot);
-
- return ofbi->region.vrfb.paddr[rot] + offset;
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+ return ofbi->region.vrfb.paddr[ofbi->rotation]
+ + omapfb_get_vrfb_offset(ofbi, ofbi->rotation);
} else {
return ofbi->region.paddr;
}
@@ -192,7 +186,7 @@ static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi)
u32 omapfb_get_region_paddr(struct omapfb_info *ofbi)
{
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
return ofbi->region.vrfb.paddr[0];
else
return ofbi->region.paddr;
@@ -200,7 +194,7 @@ u32 omapfb_get_region_paddr(struct omapfb_info *ofbi)
void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi)
{
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
return ofbi->region.vrfb.vaddr[0];
else
return ofbi->region.vaddr;
@@ -398,7 +392,7 @@ void set_fb_fix(struct fb_info *fbi)
fbi->screen_base = (char __iomem *)omapfb_get_region_vaddr(ofbi);
/* used by mmap in fbmem.c */
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
fix->line_length =
(OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 3;
else
@@ -434,11 +428,14 @@ void set_fb_fix(struct fb_info *fbi)
fix->xpanstep = 1;
fix->ypanstep = 1;
- if (rg->size) {
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
- omap_vrfb_setup(&rg->vrfb, rg->paddr,
- var->xres_virtual, var->yres_virtual,
- var->bits_per_pixel >> 3);
+ if (rg->size && ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+ enum omap_color_mode mode = 0;
+ mode = fb_mode_to_dss_mode(var);
+
+ omap_vrfb_setup(&rg->vrfb, rg->paddr,
+ var->xres_virtual,
+ var->yres_virtual,
+ mode);
}
}
@@ -527,7 +524,7 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
if (var->yres > var->yres_virtual)
var->yres = var->yres_virtual;
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
line_size = OMAP_VRFB_LINE_LEN * bytespp;
else
line_size = var->xres_virtual * bytespp;
@@ -549,7 +546,7 @@ int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
if (line_size * var->yres_virtual > max_frame_size) {
DBG("can't fit FB into memory, reducing x\n");
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
return -EINVAL;
var->xres_virtual = max_frame_size / var->yres_virtual /
@@ -672,7 +669,7 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
struct omap_overlay_info info;
int xres, yres;
int screen_width;
- int rot, mirror;
+ int mirror;
DBG("setup_overlay %d, posx %d, posy %d, outw %d, outh %d\n", ofbi->id,
posx, posy, outw, outh);
@@ -688,7 +685,7 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
offset = ((var->yoffset * var->xres_virtual +
var->xoffset) * var->bits_per_pixel) >> 3;
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
data_start_p = omapfb_get_region_rot_paddr(ofbi);
data_start_v = NULL;
} else {
@@ -711,13 +708,10 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
ovl->get_overlay_info(ovl, &info);
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
- rot = 0;
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
mirror = 0;
- } else {
- rot = ofbi->rotation;
+ else
mirror = ofbi->mirror;
- }
info.paddr = data_start_p;
info.vaddr = data_start_v;
@@ -725,7 +719,8 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
info.width = xres;
info.height = yres;
info.color_mode = mode;
- info.rotation = rot;
+ info.rotation_type = ofbi->rotation_type;
+ info.rotation = ofbi->rotation;
info.mirror = mirror;
info.pos_x = posx;
@@ -1121,7 +1116,7 @@ static void omapfb_free_fbmem(struct fb_info *fbi)
if (rg->vaddr)
iounmap(rg->vaddr);
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
/* unmap the 0 angle rotation */
if (rg->vrfb.vaddr[0]) {
iounmap(rg->vrfb.vaddr[0]);
@@ -1181,7 +1176,7 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
return -ENOMEM;
}
- if (ofbi->rotation_type != OMAPFB_ROT_VRFB) {
+ if (ofbi->rotation_type != OMAP_DSS_ROT_VRFB) {
vaddr = ioremap_wc(paddr, size);
if (!vaddr) {
@@ -1260,7 +1255,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
display->get_resolution(display, &w, &h);
- if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
#ifdef DEBUG
int oldw = w, oldh = h;
#endif
@@ -1701,8 +1696,8 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
ofbi->id = i;
/* assign these early, so that fb alloc can use them */
- ofbi->rotation_type = def_vrfb ? OMAPFB_ROT_VRFB :
- OMAPFB_ROT_DMA;
+ ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB :
+ OMAP_DSS_ROT_DMA;
ofbi->rotation = def_rotate;
ofbi->mirror = def_mirror;
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index 2607def..43f6922 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -53,11 +53,6 @@ struct omapfb2_mem_region {
bool map; /* kernel mapped by the driver */
};
-enum omapfb_rotation_type {
- OMAPFB_ROT_DMA = 0,
- OMAPFB_ROT_VRFB = 1,
-};
-
/* appended to fb_info */
struct omapfb_info {
int id;
@@ -66,7 +61,7 @@ struct omapfb_info {
int num_overlays;
struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB];
struct omapfb2_device *fbdev;
- enum omapfb_rotation_type rotation_type;
+ enum omap_dss_rotation_type rotation_type;
u8 rotation;
bool mirror;
};
--
1.5.6.5

View File

@ -0,0 +1,61 @@
From a8a37babe4856170f4cba86c425a8f21975d9e9e Mon Sep 17 00:00:00 2001
From: Tim Yamin <plasm@roo.me.uk>
Date: Mon, 13 Apr 2009 13:57:42 -0700
Subject: [PATCH] DSS2: OMAPFB: Set line_length correctly for YUV with VRFB.
Signed-off-by: Tim Yamin <plasm@roo.me.uk>
---
drivers/video/omap2/omapfb/omapfb-main.c | 30 +++++++++++++++++++++++++-----
1 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 57f5900..cd63740 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -392,10 +392,19 @@ void set_fb_fix(struct fb_info *fbi)
fbi->screen_base = (char __iomem *)omapfb_get_region_vaddr(ofbi);
/* used by mmap in fbmem.c */
- if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
- fix->line_length =
- (OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 3;
- else
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+ switch (var->nonstd) {
+ case OMAPFB_COLOR_YUV422:
+ case OMAPFB_COLOR_YUY422:
+ fix->line_length =
+ (OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 2;
+ break;
+ default:
+ fix->line_length =
+ (OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 3;
+ break;
+ }
+ } else
fix->line_length =
(var->xres_virtual * var->bits_per_pixel) >> 3;
fix->smem_start = omapfb_get_region_paddr(ofbi);
@@ -704,7 +713,18 @@ static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
goto err;
}
- screen_width = fix->line_length / (var->bits_per_pixel >> 3);
+ switch (var->nonstd) {
+ case OMAPFB_COLOR_YUV422:
+ case OMAPFB_COLOR_YUY422:
+ if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+ screen_width = fix->line_length
+ / (var->bits_per_pixel >> 2);
+ break;
+ }
+ default:
+ screen_width = fix->line_length / (var->bits_per_pixel >> 3);
+ break;
+ }
ovl->get_overlay_info(ovl, &info);
--
1.5.6.5

View File

@ -0,0 +1,29 @@
From bda19b9359d9dc60f8b0beb5685e173e236ee30f Mon Sep 17 00:00:00 2001
From: Hardik Shah <hardik.shah@ti.com>
Date: Wed, 15 Apr 2009 17:05:18 +0530
Subject: [PATCH] DSS2: dispc_get_trans_key was returning wrong key type
Signed-off-by: Hardik Shah <hardik.shah@ti.com>
---
drivers/video/omap2/dss/dispc.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 23a8155..076d3d4 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1826,9 +1826,9 @@ void dispc_get_trans_key(enum omap_channel ch,
enable_clocks(1);
if (type) {
if (ch == OMAP_DSS_CHANNEL_LCD)
- *type = REG_GET(DISPC_CONFIG, 11, 11) >> 11;
+ *type = REG_GET(DISPC_CONFIG, 11, 11);
else if (ch == OMAP_DSS_CHANNEL_DIGIT)
- *type = REG_GET(DISPC_CONFIG, 13, 13) >> 13;
+ *type = REG_GET(DISPC_CONFIG, 13, 13);
else
BUG();
}
--
1.5.6.5

View File

@ -0,0 +1,33 @@
From 30c40f5e6b1794430f678bf23d3319354321cab7 Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@nokia.com>
Date: Tue, 14 Apr 2009 14:50:11 +0200
Subject: [PATCH] DSS2: do bootmem reserve for exclusive access
BOOTMEM_DEFAULT would allow multiple reservations for the same location,
we need to reserve the region for our exclusive use. Also check if the
reserve succeeded.
Signed-off-by: Imre Deak <imre.deak@nokia.com>
---
arch/arm/plat-omap/vram.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/arch/arm/plat-omap/vram.c b/arch/arm/plat-omap/vram.c
index f24a110..520f260 100644
--- a/arch/arm/plat-omap/vram.c
+++ b/arch/arm/plat-omap/vram.c
@@ -524,7 +524,10 @@ void __init omapfb_reserve_sdram(void)
return;
}
- reserve_bootmem(paddr, size, BOOTMEM_DEFAULT);
+ if (reserve_bootmem(paddr, size, BOOTMEM_EXCLUSIVE) < 0) {
+ pr_err("FB: failed to reserve VRAM\n");
+ return;
+ }
} else {
if (size > sdram_size) {
printk(KERN_ERR "Illegal SDRAM size for VRAM\n");
--
1.5.6.5

View File

@ -0,0 +1,35 @@
From ed7a9223f6785be03951c55f3b0695b0d5635c80 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@nokia.com>
Date: Thu, 9 Apr 2009 15:04:44 +0200
Subject: [PATCH] DSS2: Fix DISPC_VID_FIR value for omap34xx
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
The msbs of the DISPC_VID_FIR fields were incorrectly masked out on
omap34xx and thus 4:1 downscale did not work correctly.
Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com>
---
drivers/video/omap2/dss/dispc.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 076d3d4..b8a3329 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -994,7 +994,10 @@ static void _dispc_set_fir(enum omap_plane plane, int hinc, int vinc)
BUG_ON(plane == OMAP_DSS_GFX);
- val = FLD_VAL(vinc, 27, 16) | FLD_VAL(hinc, 11, 0);
+ if (cpu_is_omap24xx())
+ val = FLD_VAL(vinc, 27, 16) | FLD_VAL(hinc, 11, 0);
+ else
+ val = FLD_VAL(vinc, 28, 16) | FLD_VAL(hinc, 12, 0);
dispc_write_reg(fir_reg[plane-1], val);
}
--
1.5.6.5

View File

@ -0,0 +1,82 @@
From 5390230ed12585a79683733209db34e9130b8e3b Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@nokia.com>
Date: Thu, 9 Apr 2009 15:04:43 +0200
Subject: [PATCH] DSS2: Prefer 3-tap filter
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
The 5-tap filter seems rather unstable. With some scaling settings it
works and with some it doesn't even though the functional clock remains
within the TRM limits. So prefer the 3-tap filter unless the functional
clock required for it is too high.
Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com>
---
drivers/video/omap2/dss/dispc.c | 27 ++++++++++++---------------
1 files changed, 12 insertions(+), 15 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index b8a3329..b631dd8 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1405,15 +1405,10 @@ static unsigned long calc_fclk_five_taps(u16 width, u16 height,
}
static unsigned long calc_fclk(u16 width, u16 height,
- u16 out_width, u16 out_height,
- enum omap_color_mode color_mode, bool five_taps)
+ u16 out_width, u16 out_height)
{
unsigned int hf, vf;
- if (five_taps)
- return calc_fclk_five_taps(width, height,
- out_width, out_height, color_mode);
-
/*
* FIXME how to determine the 'A' factor
* for the no downscaling case ?
@@ -1494,7 +1489,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
} else {
/* video plane */
- unsigned long fclk;
+ unsigned long fclk = 0;
if (out_width < width / maxdownscale ||
out_width > width * 8)
@@ -1530,20 +1525,22 @@ static int _dispc_setup_plane(enum omap_plane plane,
/* Must use 5-tap filter? */
five_taps = height > out_height * 2;
- /* Try to use 5-tap filter whenever possible. */
- if (cpu_is_omap34xx() && !five_taps &&
- height > out_height && width <= 1024) {
- fclk = calc_fclk_five_taps(width, height,
- out_width, out_height, color_mode);
- if (fclk <= dispc_fclk_rate())
+ if (!five_taps) {
+ fclk = calc_fclk(width, height,
+ out_width, out_height);
+
+ /* Try 5-tap filter if 3-tap fclk is too high */
+ if (cpu_is_omap34xx() && height > out_height &&
+ fclk > dispc_fclk_rate())
five_taps = true;
}
if (width > (2048 >> five_taps))
return -EINVAL;
- fclk = calc_fclk(width, height, out_width, out_height,
- color_mode, five_taps);
+ if (five_taps)
+ fclk = calc_fclk_five_taps(width, height,
+ out_width, out_height, color_mode);
DSSDBG("required fclk rate = %lu Hz\n", fclk);
DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
--
1.5.6.5

View File

@ -0,0 +1,135 @@
From 946eb774e95cdc2f2fa5cdc24aa69229f82814b8 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Thu, 16 Apr 2009 17:56:00 +0300
Subject: [PATCH] DSS2: VRAM: improve omap_vram_add_region()
Combine postponed and non-posponed versions of omap_vram_add_region.
Make the func non-static, so it can be called from board files.
---
arch/arm/plat-omap/include/mach/vram.h | 1 +
arch/arm/plat-omap/vram.c | 54 +++++++++++++------------------
2 files changed, 24 insertions(+), 31 deletions(-)
diff --git a/arch/arm/plat-omap/include/mach/vram.h b/arch/arm/plat-omap/include/mach/vram.h
index f176562..8639e08 100644
--- a/arch/arm/plat-omap/include/mach/vram.h
+++ b/arch/arm/plat-omap/include/mach/vram.h
@@ -24,6 +24,7 @@
#include <asm/types.h>
+extern int omap_vram_add_region(unsigned long paddr, size_t size);
extern int omap_vram_free(unsigned long paddr, size_t size);
extern int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr);
extern int omap_vram_reserve(unsigned long paddr, size_t size);
diff --git a/arch/arm/plat-omap/vram.c b/arch/arm/plat-omap/vram.c
index 520f260..8e9fe77 100644
--- a/arch/arm/plat-omap/vram.c
+++ b/arch/arm/plat-omap/vram.c
@@ -60,6 +60,7 @@
* time when we cannot yet allocate the region list */
#define MAX_POSTPONED_REGIONS 10
+static bool vram_initialized;
static int postponed_cnt __initdata;
static struct {
unsigned long paddr;
@@ -145,39 +146,32 @@ static void omap_vram_free_allocation(struct vram_alloc *va)
kfree(va);
}
-static __init int omap_vram_add_region_postponed(unsigned long paddr,
- size_t size)
-{
- if (postponed_cnt == MAX_POSTPONED_REGIONS)
- return -ENOMEM;
-
- postponed_regions[postponed_cnt].paddr = paddr;
- postponed_regions[postponed_cnt].size = size;
-
- ++postponed_cnt;
-
- return 0;
-}
-
-/* add/remove_region can be exported if there's need to add/remove regions
- * runtime */
-static int omap_vram_add_region(unsigned long paddr, size_t size)
+int omap_vram_add_region(unsigned long paddr, size_t size)
{
struct vram_region *rm;
unsigned pages;
- DBG("adding region paddr %08lx size %d\n",
- paddr, size);
+ if (vram_initialized) {
+ DBG("adding region paddr %08lx size %d\n",
+ paddr, size);
- size &= PAGE_MASK;
- pages = size >> PAGE_SHIFT;
+ size &= PAGE_MASK;
+ pages = size >> PAGE_SHIFT;
- rm = omap_vram_create_region(paddr, pages);
- if (rm == NULL)
- return -ENOMEM;
+ rm = omap_vram_create_region(paddr, pages);
+ if (rm == NULL)
+ return -ENOMEM;
+
+ list_add(&rm->list, &region_list);
+ } else {
+ if (postponed_cnt == MAX_POSTPONED_REGIONS)
+ return -ENOMEM;
- list_add(&rm->list, &region_list);
+ postponed_regions[postponed_cnt].paddr = paddr;
+ postponed_regions[postponed_cnt].size = size;
+ ++postponed_cnt;
+ }
return 0;
}
@@ -438,6 +432,8 @@ static __init int omap_vram_init(void)
{
int i, r;
+ vram_initialized = 1;
+
for (i = 0; i < postponed_cnt; i++)
omap_vram_add_region(postponed_regions[i].paddr,
postponed_regions[i].size);
@@ -472,10 +468,6 @@ static void __init omapfb_early_vram(char **p)
omapfb_def_sdram_vram_size = memparse(*p, p);
if (**p == ',')
omapfb_def_sdram_vram_start = simple_strtoul((*p) + 1, p, 16);
-
- printk("omapfb_early_vram, %d, 0x%x\n",
- omapfb_def_sdram_vram_size,
- omapfb_def_sdram_vram_start);
}
__early_param("vram=", omapfb_early_vram);
@@ -538,7 +530,7 @@ void __init omapfb_reserve_sdram(void)
BUG_ON(paddr & ~PAGE_MASK);
}
- omap_vram_add_region_postponed(paddr, size);
+ omap_vram_add_region(paddr, size);
pr_info("Reserving %u bytes SDRAM for VRAM\n", size);
}
@@ -594,7 +586,7 @@ unsigned long __init omapfb_reserve_sram(unsigned long sram_pstart,
reserved = pend_avail - paddr;
size_avail = pend_avail - reserved - pstart_avail;
- omap_vram_add_region_postponed(paddr, size);
+ omap_vram_add_region(paddr, size);
if (reserved)
pr_info("Reserving %lu bytes SRAM for VRAM\n", reserved);
--
1.5.6.5

View File

@ -0,0 +1,66 @@
From f825cafd5ee5c600218740507f85594c825b0c00 Mon Sep 17 00:00:00 2001
From: Hardik Shah <hardik.shah@ti.com>
Date: Thu, 16 Apr 2009 18:47:49 +0530
Subject: [PATCH] DSS2: Added the function pointer for getting default color.
V4L2 Framework has a CID for getting/setting default color.
So added the function pointer for doing same.
SYSFS based getting the default color will remain same
Signed-off-by: Hardik Shah <hardik.shah@ti.com>
---
arch/arm/plat-omap/include/mach/display.h | 1 +
drivers/video/omap2/dss/manager.c | 11 +++++++----
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/arch/arm/plat-omap/include/mach/display.h b/arch/arm/plat-omap/include/mach/display.h
index b0a6272..073cdda 100644
--- a/arch/arm/plat-omap/include/mach/display.h
+++ b/arch/arm/plat-omap/include/mach/display.h
@@ -414,6 +414,7 @@ struct omap_overlay_manager {
int (*apply)(struct omap_overlay_manager *mgr);
void (*set_default_color)(struct omap_overlay_manager *mgr, u32 color);
+ u32 (*get_default_color)(struct omap_overlay_manager *mgr);
void (*set_trans_key)(struct omap_overlay_manager *mgr,
enum omap_dss_color_key_type type,
u32 trans_key);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 8ca0bbb..12cf7b0 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -98,10 +98,8 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr, const cha
static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
char *buf)
{
- u32 default_color;
-
- default_color = dispc_get_default_color(mgr->id);
- return snprintf(buf, PAGE_SIZE, "%d", default_color);
+ return snprintf(buf, PAGE_SIZE, "%d",
+ mgr->get_default_color(mgr));
}
static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
@@ -470,6 +468,10 @@ static void omap_dss_mgr_enable_trans_key(struct omap_overlay_manager *mgr,
{
dispc_enable_trans_key(mgr->id, enable);
}
+static u32 omap_dss_mgr_get_default_color(struct omap_overlay_manager *mgr)
+{
+ return dispc_get_default_color(mgr->id);
+}
static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager)
{
@@ -512,6 +514,7 @@ int dss_init_overlay_managers(struct platform_device *pdev)
mgr->set_default_color = &omap_dss_mgr_set_def_color,
mgr->set_trans_key = &omap_dss_mgr_set_trans_key,
mgr->enable_trans_key = &omap_dss_mgr_enable_trans_key,
+ mgr->get_default_color = &omap_dss_mgr_get_default_color;
mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC,
dss_overlay_setup_dispc_manager(mgr);
--
1.5.6.5

View File

@ -0,0 +1,118 @@
From 6c56dc10226c84f41917ac2117b0e654fa080d40 Mon Sep 17 00:00:00 2001
From: Hardik Shah <hardik.shah@ti.com>
Date: Thu, 16 Apr 2009 19:00:11 +0530
Subject: [PATCH] DSS2: Added support for setting and querying alpha blending.
Signed-off-by: Hardik Shah <hardik.shah@ti.com>
---
arch/arm/plat-omap/include/mach/display.h | 3 +++
drivers/video/omap2/dss/dispc.c | 26 ++++++++++++++++++++++++++
drivers/video/omap2/dss/dss.h | 2 ++
drivers/video/omap2/dss/manager.c | 14 ++++++++++++++
4 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-omap/include/mach/display.h b/arch/arm/plat-omap/include/mach/display.h
index 073cdda..e1f615a 100644
--- a/arch/arm/plat-omap/include/mach/display.h
+++ b/arch/arm/plat-omap/include/mach/display.h
@@ -415,11 +415,14 @@ struct omap_overlay_manager {
void (*set_default_color)(struct omap_overlay_manager *mgr, u32 color);
u32 (*get_default_color)(struct omap_overlay_manager *mgr);
+ bool (*get_alpha_blending_status)(struct omap_overlay_manager *mgr);
void (*set_trans_key)(struct omap_overlay_manager *mgr,
enum omap_dss_color_key_type type,
u32 trans_key);
void (*enable_trans_key)(struct omap_overlay_manager *mgr,
bool enable);
+ void (*enable_alpha_blending)(struct omap_overlay_manager *mgr,
+ bool enable);
};
enum omap_display_caps {
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index b631dd8..7e551c2 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1847,6 +1847,32 @@ void dispc_enable_trans_key(enum omap_channel ch, bool enable)
REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12);
enable_clocks(0);
}
+void dispc_enable_alpha_blending(enum omap_channel ch, bool enable)
+{
+ enable_clocks(1);
+ if (ch == OMAP_DSS_CHANNEL_LCD)
+ REG_FLD_MOD(DISPC_CONFIG, enable, 18, 18);
+ else /* OMAP_DSS_CHANNEL_DIGIT */
+ REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
+ enable_clocks(0);
+}
+bool dispc_alpha_blending_enabled(enum omap_channel ch)
+{
+ bool enabled;
+
+ enable_clocks(1);
+ if (ch == OMAP_DSS_CHANNEL_LCD)
+ enabled = REG_GET(DISPC_CONFIG, 18, 18);
+ else if (ch == OMAP_DSS_CHANNEL_DIGIT)
+ enabled = REG_GET(DISPC_CONFIG, 18, 18);
+ else
+ BUG();
+ enable_clocks(0);
+
+ return enabled;
+
+}
+
bool dispc_trans_key_enabled(enum omap_channel ch)
{
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 584dce6..1d01ff6 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -294,7 +294,9 @@ void dispc_get_trans_key(enum omap_channel ch,
enum omap_dss_color_key_type *type,
u32 *trans_key);
void dispc_enable_trans_key(enum omap_channel ch, bool enable);
+void dispc_enable_alpha_blending(enum omap_channel ch, bool enable);
bool dispc_trans_key_enabled(enum omap_channel ch);
+bool dispc_alpha_blending_enabled(enum omap_channel ch);
void dispc_set_lcd_timings(struct omap_video_timings *timings);
unsigned long dispc_fclk_rate(void);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 12cf7b0..90acd28 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -468,6 +468,16 @@ static void omap_dss_mgr_enable_trans_key(struct omap_overlay_manager *mgr,
{
dispc_enable_trans_key(mgr->id, enable);
}
+static void omap_dss_mgr_enable_alpha_blending(struct omap_overlay_manager *mgr,
+ bool enable)
+{
+ dispc_enable_alpha_blending(mgr->id, enable);
+}
+static bool omap_dss_mgr_get_alpha_blending_status(
+ struct omap_overlay_manager *mgr)
+{
+ return dispc_alpha_blending_enabled(mgr->id);
+}
static u32 omap_dss_mgr_get_default_color(struct omap_overlay_manager *mgr)
{
return dispc_get_default_color(mgr->id);
@@ -514,6 +524,10 @@ int dss_init_overlay_managers(struct platform_device *pdev)
mgr->set_default_color = &omap_dss_mgr_set_def_color,
mgr->set_trans_key = &omap_dss_mgr_set_trans_key,
mgr->enable_trans_key = &omap_dss_mgr_enable_trans_key,
+ mgr->enable_alpha_blending =
+ &omap_dss_mgr_enable_alpha_blending;
+ mgr->get_alpha_blending_status =
+ omap_dss_mgr_get_alpha_blending_status;
mgr->get_default_color = &omap_dss_mgr_get_default_color;
mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC,
--
1.5.6.5

View File

@ -0,0 +1,150 @@
From 2c9edd6af31a812a9487dd8bc12322e105a29f44 Mon Sep 17 00:00:00 2001
From: Hardik Shah <hardik.shah@ti.com>
Date: Fri, 17 Apr 2009 09:42:36 +0530
Subject: [PATCH] DSS2: Added support for querying color keying.
V4L2 Framework has a ioctl for getting/setting color keying.
So added the function manager pointers for doing same.
Modifed the color keying sysfs entries to use manager
function pointer. Earlier they were calling direcly
dispc function to set/enable color keying.
Some of color-keying function pointers in the overlay_manager
structure re-named to be more specific.
Signed-off-by: Hardik Shah <hardik.shah@ti.com>
---
arch/arm/plat-omap/include/mach/display.h | 6 ++++-
drivers/video/omap2/dss/manager.c | 36 +++++++++++++++++++++--------
2 files changed, 31 insertions(+), 11 deletions(-)
diff --git a/arch/arm/plat-omap/include/mach/display.h b/arch/arm/plat-omap/include/mach/display.h
index e1f615a..d0b4c83 100644
--- a/arch/arm/plat-omap/include/mach/display.h
+++ b/arch/arm/plat-omap/include/mach/display.h
@@ -416,7 +416,11 @@ struct omap_overlay_manager {
void (*set_default_color)(struct omap_overlay_manager *mgr, u32 color);
u32 (*get_default_color)(struct omap_overlay_manager *mgr);
bool (*get_alpha_blending_status)(struct omap_overlay_manager *mgr);
- void (*set_trans_key)(struct omap_overlay_manager *mgr,
+ bool (*get_trans_key_status)(struct omap_overlay_manager *mgr);
+ void (*get_trans_key_type_and_value)(struct omap_overlay_manager *mgr,
+ enum omap_dss_color_key_type *type,
+ u32 *trans_key);
+ void (*set_trans_key_type_and_value)(struct omap_overlay_manager *mgr,
enum omap_dss_color_key_type type,
u32 trans_key);
void (*enable_trans_key)(struct omap_overlay_manager *mgr,
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 90acd28..e0501c4 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -124,7 +124,7 @@ static ssize_t manager_color_key_type_show(struct omap_overlay_manager *mgr,
{
enum omap_dss_color_key_type key_type;
- dispc_get_trans_key(mgr->id, &key_type, NULL);
+ mgr->get_trans_key_type_and_value(mgr, &key_type, NULL);
BUG_ON(key_type >= ARRAY_SIZE(color_key_type_str));
return snprintf(buf, PAGE_SIZE, "%s\n", color_key_type_str[key_type]);
@@ -143,8 +143,8 @@ static ssize_t manager_color_key_type_store(struct omap_overlay_manager *mgr,
}
if (key_type == ARRAY_SIZE(color_key_type_str))
return -EINVAL;
- dispc_get_trans_key(mgr->id, NULL, &key_value);
- dispc_set_trans_key(mgr->id, key_type, key_value);
+ mgr->get_trans_key_type_and_value(mgr, NULL, &key_value);
+ mgr->set_trans_key_type_and_value(mgr, key_type, key_value);
return size;
}
@@ -154,7 +154,7 @@ static ssize_t manager_color_key_value_show(struct omap_overlay_manager *mgr,
{
u32 key_value;
- dispc_get_trans_key(mgr->id, NULL, &key_value);
+ mgr->get_trans_key_type_and_value(mgr, NULL, &key_value);
return snprintf(buf, PAGE_SIZE, "%d\n", key_value);
}
@@ -167,8 +167,8 @@ static ssize_t manager_color_key_value_store(struct omap_overlay_manager *mgr,
if (sscanf(buf, "%d", &key_value) != 1)
return -EINVAL;
- dispc_get_trans_key(mgr->id, &key_type, NULL);
- dispc_set_trans_key(mgr->id, key_type, key_value);
+ mgr->get_trans_key_type_and_value(mgr, &key_type, NULL);
+ mgr->set_trans_key_type_and_value(mgr, key_type, key_value);
return size;
}
@@ -177,7 +177,7 @@ static ssize_t manager_color_key_enabled_show(struct omap_overlay_manager *mgr,
char *buf)
{
return snprintf(buf, PAGE_SIZE, "%d\n",
- dispc_trans_key_enabled(mgr->id));
+ mgr->get_trans_key_status(mgr));
}
static ssize_t manager_color_key_enabled_store(struct omap_overlay_manager *mgr,
@@ -188,7 +188,7 @@ static ssize_t manager_color_key_enabled_store(struct omap_overlay_manager *mgr,
if (sscanf(buf, "%d", &enable) != 1)
return -EINVAL;
- dispc_enable_trans_key(mgr->id, enable);
+ mgr->enable_trans_key(mgr, enable);
return size;
}
@@ -456,12 +456,20 @@ static void omap_dss_mgr_set_def_color(struct omap_overlay_manager *mgr,
dispc_set_default_color(mgr->id, color);
}
-static void omap_dss_mgr_set_trans_key(struct omap_overlay_manager *mgr,
+static void omap_dss_mgr_set_trans_key_type_and_value(
+ struct omap_overlay_manager *mgr,
enum omap_dss_color_key_type type,
u32 trans_key)
{
dispc_set_trans_key(mgr->id, type, trans_key);
}
+static void omap_dss_mgr_get_trans_key_type_and_value(
+ struct omap_overlay_manager *mgr,
+ enum omap_dss_color_key_type *type,
+ u32 *trans_key)
+{
+ dispc_get_trans_key(mgr->id, type, trans_key);
+}
static void omap_dss_mgr_enable_trans_key(struct omap_overlay_manager *mgr,
bool enable)
@@ -482,6 +490,10 @@ static u32 omap_dss_mgr_get_default_color(struct omap_overlay_manager *mgr)
{
return dispc_get_default_color(mgr->id);
}
+static bool omap_dss_mgr_get_trans_key_status(struct omap_overlay_manager *mgr)
+{
+ return dispc_trans_key_enabled(mgr->id);
+}
static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager)
{
@@ -522,8 +534,12 @@ int dss_init_overlay_managers(struct platform_device *pdev)
mgr->unset_display = &omap_dss_unset_display,
mgr->apply = &omap_dss_mgr_apply,
mgr->set_default_color = &omap_dss_mgr_set_def_color,
- mgr->set_trans_key = &omap_dss_mgr_set_trans_key,
+ mgr->set_trans_key_type_and_value =
+ &omap_dss_mgr_set_trans_key_type_and_value,
+ mgr->get_trans_key_type_and_value =
+ &omap_dss_mgr_get_trans_key_type_and_value,
mgr->enable_trans_key = &omap_dss_mgr_enable_trans_key,
+ mgr->get_trans_key_status = &omap_dss_mgr_get_trans_key_status,
mgr->enable_alpha_blending =
&omap_dss_mgr_enable_alpha_blending;
mgr->get_alpha_blending_status =
--
1.5.6.5

View File

@ -0,0 +1,56 @@
From 9e8877f0e5b17d3ddd101d6a63aa86fdb14d35d5 Mon Sep 17 00:00:00 2001
From: Hardik Shah <hardik.shah@ti.com>
Date: Fri, 17 Apr 2009 09:51:25 +0530
Subject: [PATCH] DSS2:OMAPFB: Some color keying pointerd renamed in DSS2. Replicated in FB
Signed-off-by: Hardik Shah <hardik.shah@ti.com>
---
drivers/video/omap2/omapfb/omapfb-ioctl.c | 11 +++++++----
1 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 7f18d2a..79d8916 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -288,7 +288,8 @@ static int _omapfb_set_color_key(struct omap_overlay_manager *mgr,
{
enum omap_dss_color_key_type kt;
- if(!mgr->set_default_color || !mgr->set_trans_key ||
+ if (!mgr->set_default_color ||
+ !mgr->set_trans_key_type_and_value ||
!mgr->enable_trans_key)
return 0;
@@ -310,7 +311,7 @@ static int _omapfb_set_color_key(struct omap_overlay_manager *mgr,
}
mgr->set_default_color(mgr, ck->background);
- mgr->set_trans_key(mgr, kt, ck->trans_key);
+ mgr->set_trans_key_type_and_value(mgr, kt, ck->trans_key);
mgr->enable_trans_key(mgr, 1);
omapfb_color_keys[mgr->id] = *ck;
@@ -341,7 +342,8 @@ static int omapfb_set_color_key(struct fb_info *fbi,
goto err;
}
- if(!mgr->set_default_color || !mgr->set_trans_key ||
+ if (!mgr->set_default_color ||
+ !mgr->set_trans_key_type_and_value ||
!mgr->enable_trans_key) {
r = -ENODEV;
goto err;
@@ -377,7 +379,8 @@ static int omapfb_get_color_key(struct fb_info *fbi,
goto err;
}
- if(!mgr->set_default_color || !mgr->set_trans_key ||
+ if (!mgr->set_default_color ||
+ !mgr->set_trans_key_type_and_value ||
!mgr->enable_trans_key) {
r = -ENODEV;
goto err;
--
1.5.6.5

View File

@ -0,0 +1,59 @@
From 6f1f0c7b19ecb468824b79f9d181ef0da41b7d7d Mon Sep 17 00:00:00 2001
From: Hardik Shah <hardik.shah@ti.com>
Date: Fri, 17 Apr 2009 13:58:21 +0530
Subject: [PATCH] DSS2: Add sysfs entry to for the alpha blending support.
Signed-off-by: Hardik Shah <hardik.shah@ti.com>
---
drivers/video/omap2/dss/manager.c | 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index e0501c4..7965a84 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -192,6 +192,22 @@ static ssize_t manager_color_key_enabled_store(struct omap_overlay_manager *mgr,
return size;
}
+static ssize_t manager_alpha_blending_enabled_show(
+ struct omap_overlay_manager *mgr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n",
+ mgr->get_alpha_blending_status(mgr));
+}
+static ssize_t manager_alpha_blending_enabled_store(
+ struct omap_overlay_manager *mgr,
+ const char *buf, size_t size)
+{
+ int enable;
+ if (sscanf(buf, "%d", &enable) != 1)
+ return -EINVAL;
+ mgr->enable_alpha_blending(mgr, enable);
+ return size;
+}
struct manager_attribute {
@@ -215,6 +231,10 @@ static MANAGER_ATTR(color_key_value, S_IRUGO|S_IWUSR,
manager_color_key_value_show, manager_color_key_value_store);
static MANAGER_ATTR(color_key_enabled, S_IRUGO|S_IWUSR,
manager_color_key_enabled_show, manager_color_key_enabled_store);
+static MANAGER_ATTR(alpha_blending_enabled, S_IRUGO|S_IWUSR,
+ manager_alpha_blending_enabled_show,
+ manager_alpha_blending_enabled_store);
+
static struct attribute *manager_sysfs_attrs[] = {
&manager_attr_name.attr,
@@ -223,6 +243,7 @@ static struct attribute *manager_sysfs_attrs[] = {
&manager_attr_color_key_type.attr,
&manager_attr_color_key_value.attr,
&manager_attr_color_key_enabled.attr,
+ &manager_attr_alpha_blending_enabled.attr,
NULL
};
--
1.5.6.5

View File

@ -0,0 +1,97 @@
From a5129f272a48aa22629137c9c31e60eddb8c3f5d Mon Sep 17 00:00:00 2001
From: Hardik Shah <hardik.shah@ti.com>
Date: Fri, 17 Apr 2009 14:24:46 +0530
Subject: [PATCH] DSS2: Provided proper exclusion for destination color keying and alpha blending.
OMAP does not support destination color key and alpha blending
simultaneously. So this patch does not allow the user
so set both at a time.
Signed-off-by: Hardik Shah <hardik.shah@ti.com>
---
drivers/video/omap2/dss/manager.c | 50 ++++++++++++++++++++++++++++++++++++-
1 files changed, 49 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 7965a84..108489c 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -137,12 +137,26 @@ static ssize_t manager_color_key_type_store(struct omap_overlay_manager *mgr,
u32 key_value;
for (key_type = OMAP_DSS_COLOR_KEY_GFX_DST;
- key_type < ARRAY_SIZE(color_key_type_str); key_type++) {
+ key_type < ARRAY_SIZE(color_key_type_str); key_type++) {
if (sysfs_streq(buf, color_key_type_str[key_type]))
break;
}
if (key_type == ARRAY_SIZE(color_key_type_str))
return -EINVAL;
+ /* OMAP does not support destination color key and alpha blending
+ * simultaneously. So if alpha blending and color keying both are
+ * enabled then refrain from setting the color key type to
+ * gfx-destination
+ */
+ if (!key_type) {
+ bool color_key_enabled;
+ bool alpha_blending_enabled;
+ color_key_enabled = mgr->get_trans_key_status(mgr);
+ alpha_blending_enabled = mgr->get_alpha_blending_status(mgr);
+ if (color_key_enabled && alpha_blending_enabled)
+ return -EINVAL;
+ }
+
mgr->get_trans_key_type_and_value(mgr, NULL, &key_value);
mgr->set_trans_key_type_and_value(mgr, key_type, key_value);
@@ -188,6 +202,23 @@ static ssize_t manager_color_key_enabled_store(struct omap_overlay_manager *mgr,
if (sscanf(buf, "%d", &enable) != 1)
return -EINVAL;
+ /* OMAP does not support destination color keying and
+ * alpha blending simultaneously. so if alpha blending
+ * is enabled refrain from enabling destination color
+ * keying.
+ */
+ if (enable) {
+ bool enabled;
+ enabled = mgr->get_alpha_blending_status(mgr);
+ if (enabled) {
+ enum omap_dss_color_key_type key_type;
+ mgr->get_trans_key_type_and_value(mgr,
+ &key_type, NULL);
+ if (!key_type)
+ return -EINVAL;
+ }
+
+ }
mgr->enable_trans_key(mgr, enable);
return size;
@@ -205,6 +236,23 @@ static ssize_t manager_alpha_blending_enabled_store(
int enable;
if (sscanf(buf, "%d", &enable) != 1)
return -EINVAL;
+ /* OMAP does not support destination color keying and
+ * alpha blending simultaneously. so if destination
+ * color keying is enabled refrain from enabling
+ * alpha blending
+ */
+ if (enable) {
+ bool enabled;
+ enabled = mgr->get_trans_key_status(mgr);
+ if (enabled) {
+ enum omap_dss_color_key_type key_type;
+ mgr->get_trans_key_type_and_value(mgr, &key_type, NULL);
+ if (!key_type)
+ return -EINVAL;
+
+ }
+
+ }
mgr->enable_alpha_blending(mgr, enable);
return size;
}
--
1.5.6.5

View File

@ -0,0 +1,71 @@
From 9bcac9b9e678f476c83b5679b1215b6bc946130a Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@nokia.com>
Date: Mon, 20 Apr 2009 16:26:18 +0200
Subject: [PATCH] DSS2: Disable vertical offset with fieldmode
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
When using fieldmode each field is basically a separate picture so the
vertical filter should start at phase 0 for both fields.
Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com>
---
drivers/video/omap2/dss/dispc.c | 23 +++++++++--------------
1 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 7e551c2..f15614b 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1029,12 +1029,12 @@ static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
static void _dispc_set_scaling(enum omap_plane plane,
u16 orig_width, u16 orig_height,
u16 out_width, u16 out_height,
- bool ilace, bool five_taps)
+ bool ilace, bool five_taps,
+ bool fieldmode)
{
int fir_hinc;
int fir_vinc;
int hscaleup, vscaleup;
- int fieldmode = 0;
int accu0 = 0;
int accu1 = 0;
u32 l;
@@ -1072,17 +1072,12 @@ static void _dispc_set_scaling(enum omap_plane plane,
dispc_write_reg(dispc_reg_att[plane], l);
- if (ilace) {
- if (fieldmode) {
- accu0 = fir_vinc / 2;
- accu1 = 0;
- } else {
- accu0 = 0;
- accu1 = fir_vinc / 2;
- if (accu1 >= 1024/2) {
- accu0 = 1024/2;
- accu1 -= accu0;
- }
+ if (ilace && !fieldmode) {
+ accu0 = 0;
+ accu1 = fir_vinc / 2;
+ if (accu1 >= 1024/2) {
+ accu0 = 1024/2;
+ accu1 -= accu0;
}
}
@@ -1582,7 +1577,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
if (plane != OMAP_DSS_GFX) {
_dispc_set_scaling(plane, width, height,
out_width, out_height,
- ilace, five_taps);
+ ilace, five_taps, fieldmode);
_dispc_set_vid_size(plane, out_width, out_height);
_dispc_set_vid_color_conv(plane, cconv);
}
--
1.5.6.5

View File

@ -0,0 +1,34 @@
From 9c6de0fed6e8a598d026d348533fdf731b737d55 Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@nokia.com>
Date: Mon, 20 Apr 2009 16:26:19 +0200
Subject: [PATCH] DSS2: Don't enable fieldmode automatically
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
The only case where enabling fieldmode automatically seems reasonable
is when source and destination heights are equal. Some kind of user
controllable knob should be added so the user could enable field mode
when the source is interlaced.
Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com>
---
drivers/video/omap2/dss/dispc.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index f15614b..1c036c1 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1450,7 +1450,7 @@ static int _dispc_setup_plane(enum omap_plane plane,
if (paddr == 0)
return -EINVAL;
- if (ilace && height >= out_height)
+ if (ilace && height == out_height)
fieldmode = 1;
if (ilace) {
--
1.5.6.5

View File

@ -0,0 +1,170 @@
From 35e88797e93b107ba602dee1e2ac8ea761dccd4b Mon Sep 17 00:00:00 2001
From: =?utf-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@nokia.com>
Date: Mon, 20 Apr 2009 16:26:20 +0200
Subject: [PATCH] DSS2: Swap field 0 and field 1 registers
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 8bit
The values for the registers which have alternate values for each field
were reveresed to what the hardware expects. For the hardware field 0
is the even field or the bottom field, field 1 is the odd field or the
top field. So simply swap the register values.
Signed-off-by: Ville Syrjälä <ville.syrjala@nokia.com>
---
drivers/video/omap2/dss/dispc.c | 66 ++++++++++++++++++++++-----------------
1 files changed, 37 insertions(+), 29 deletions(-)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 1c036c1..9bab6cf 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1072,12 +1072,16 @@ static void _dispc_set_scaling(enum omap_plane plane,
dispc_write_reg(dispc_reg_att[plane], l);
+ /*
+ * field 0 = even field = bottom field
+ * field 1 = odd field = top field
+ */
if (ilace && !fieldmode) {
- accu0 = 0;
- accu1 = fir_vinc / 2;
- if (accu1 >= 1024/2) {
- accu0 = 1024/2;
- accu1 -= accu0;
+ accu1 = 0;
+ accu0 = fir_vinc / 2;
+ if (accu0 >= 1024/2) {
+ accu1 = 1024/2;
+ accu0 -= accu1;
}
}
@@ -1266,34 +1270,38 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
fbh = width;
}
+ /*
+ * field 0 = even field = bottom field
+ * field 1 = odd field = top field
+ */
switch (rotation + mirror * 4) {
case 0:
- *offset0 = 0;
+ *offset1 = 0;
if (fieldmode)
- *offset1 = screen_width * ps;
+ *offset0 = screen_width * ps;
else
- *offset1 = 0;
+ *offset0 = 0;
*row_inc = pixinc(1 + (screen_width - fbw) +
(fieldmode ? screen_width : 0),
ps);
*pix_inc = pixinc(1, ps);
break;
case 1:
- *offset0 = screen_width * (fbh - 1) * ps;
+ *offset1 = screen_width * (fbh - 1) * ps;
if (fieldmode)
- *offset1 = *offset0 + ps;
+ *offset0 = *offset1 + ps;
else
- *offset1 = *offset0;
+ *offset0 = *offset1;
*row_inc = pixinc(screen_width * (fbh - 1) + 1 +
(fieldmode ? 1 : 0), ps);
*pix_inc = pixinc(-screen_width, ps);
break;
case 2:
- *offset0 = (screen_width * (fbh - 1) + fbw - 1) * ps;
+ *offset1 = (screen_width * (fbh - 1) + fbw - 1) * ps;
if (fieldmode)
- *offset1 = *offset0 - screen_width * ps;
+ *offset0 = *offset1 - screen_width * ps;
else
- *offset1 = *offset0;
+ *offset0 = *offset1;
*row_inc = pixinc(-1 -
(screen_width - fbw) -
(fieldmode ? screen_width : 0),
@@ -1301,11 +1309,11 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
*pix_inc = pixinc(-1, ps);
break;
case 3:
- *offset0 = (fbw - 1) * ps;
+ *offset1 = (fbw - 1) * ps;
if (fieldmode)
- *offset1 = *offset0 - ps;
+ *offset0 = *offset1 - ps;
else
- *offset1 = *offset0;
+ *offset0 = *offset1;
*row_inc = pixinc(-screen_width * (fbh - 1) - 1 -
(fieldmode ? 1 : 0), ps);
*pix_inc = pixinc(screen_width, ps);
@@ -1313,11 +1321,11 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
/* mirroring */
case 0 + 4:
- *offset0 = (fbw - 1) * ps;
+ *offset1 = (fbw - 1) * ps;
if (fieldmode)
- *offset1 = *offset0 + screen_width * ps;
+ *offset0 = *offset1 + screen_width * ps;
else
- *offset1 = *offset0;
+ *offset0 = *offset1;
*row_inc = pixinc(screen_width * 2 - 1 +
(fieldmode ? screen_width : 0),
ps);
@@ -1325,11 +1333,11 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
break;
case 1 + 4:
- *offset0 = 0;
+ *offset1 = 0;
if (fieldmode)
- *offset1 = *offset0 + screen_width * ps;
+ *offset0 = *offset1 + screen_width * ps;
else
- *offset1 = *offset0;
+ *offset0 = *offset1;
*row_inc = pixinc(-screen_width * (fbh - 1) + 1 +
(fieldmode ? 1 : 0),
ps);
@@ -1337,11 +1345,11 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
break;
case 2 + 4:
- *offset0 = screen_width * (fbh - 1) * ps;
+ *offset1 = screen_width * (fbh - 1) * ps;
if (fieldmode)
- *offset1 = *offset0 + screen_width * ps;
+ *offset0 = *offset1 + screen_width * ps;
else
- *offset1 = *offset0;
+ *offset0 = *offset1;
*row_inc = pixinc(1 - screen_width * 2 -
(fieldmode ? screen_width : 0),
ps);
@@ -1349,11 +1357,11 @@ static void calc_dma_rotation_offset(u8 rotation, bool mirror,
break;
case 3 + 4:
- *offset0 = (screen_width * (fbh - 1) + fbw - 1) * ps;
+ *offset1 = (screen_width * (fbh - 1) + fbw - 1) * ps;
if (fieldmode)
- *offset1 = *offset0 + screen_width * ps;
+ *offset0 = *offset1 + screen_width * ps;
else
- *offset1 = *offset0;
+ *offset0 = *offset1;
*row_inc = pixinc(screen_width * (fbh - 1) - 1 -
(fieldmode ? 1 : 0),
ps);
--
1.5.6.5

View File

@ -0,0 +1,76 @@
From a9b3500bd14609750a2337e866e1df62627c1bac Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@nokia.com>
Date: Mon, 20 Apr 2009 14:55:33 +0200
Subject: [PATCH] DSS2: add sysfs entry for seting the rotate type
This can help in utilizing VRAM memory better. Since with VRFB rotation
we waste a lot of physical memory due to the VRFB HW design, provide the
possibility to turn it off and free the extra memory for the use by other
planes for example.
---
drivers/video/omap2/omapfb/omapfb-sysfs.c | 42 ++++++++++++++++++++++++++++-
1 files changed, 41 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 2c88718..4e3da42 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -43,6 +43,46 @@ static ssize_t show_rotate_type(struct device *dev,
return snprintf(buf, PAGE_SIZE, "%d\n", ofbi->rotation_type);
}
+static ssize_t store_rotate_type(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct fb_info *fbi = dev_get_drvdata(dev);
+ struct omapfb_info *ofbi = FB2OFB(fbi);
+ struct omapfb2_device *fbdev = ofbi->fbdev;
+ enum omap_dss_rotation_type rot_type;
+ int r;
+
+ rot_type = simple_strtoul(buf, NULL, 0);
+
+ if (rot_type != OMAP_DSS_ROT_DMA && rot_type != OMAP_DSS_ROT_VRFB)
+ return -EINVAL;
+
+ omapfb_lock(fbdev);
+
+ r = 0;
+ if (rot_type == ofbi->rotation_type)
+ goto out;
+
+ r = -EBUSY;
+ if (ofbi->region.size)
+ goto out;
+
+ ofbi->rotation_type = rot_type;
+
+ /*
+ * Since the VRAM for this FB is not allocated at the moment we don't need to
+ * do any further parameter checking at this point.
+ */
+
+ r = count;
+out:
+ omapfb_unlock(fbdev);
+
+ return r;
+}
+
+
static ssize_t show_mirror(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -327,7 +367,7 @@ static ssize_t show_virt(struct device *dev,
}
static struct device_attribute omapfb_attrs[] = {
- __ATTR(rotate_type, S_IRUGO, show_rotate_type, NULL),
+ __ATTR(rotate_type, S_IRUGO | S_IWUSR, show_rotate_type, store_rotate_type),
__ATTR(mirror, S_IRUGO | S_IWUSR, show_mirror, store_mirror),
__ATTR(size, S_IRUGO | S_IWUSR, show_size, store_size),
__ATTR(overlays, S_IRUGO | S_IWUSR, show_overlays, store_overlays),
--
1.5.6.5

View File

@ -0,0 +1,48 @@
From b0e081456a9b094109c04467d041ff693843ca47 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Tue, 21 Apr 2009 09:25:16 +0300
Subject: [PATCH] DSS2: Fixed line endings from , to ;
---
drivers/video/omap2/dss/manager.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 108489c..bf059e0 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -599,22 +599,22 @@ int dss_init_overlay_managers(struct platform_device *pdev)
break;
}
- mgr->set_display = &omap_dss_set_display,
- mgr->unset_display = &omap_dss_unset_display,
- mgr->apply = &omap_dss_mgr_apply,
- mgr->set_default_color = &omap_dss_mgr_set_def_color,
+ mgr->set_display = &omap_dss_set_display;
+ mgr->unset_display = &omap_dss_unset_display;
+ mgr->apply = &omap_dss_mgr_apply;
+ mgr->set_default_color = &omap_dss_mgr_set_def_color;
mgr->set_trans_key_type_and_value =
- &omap_dss_mgr_set_trans_key_type_and_value,
+ &omap_dss_mgr_set_trans_key_type_and_value;
mgr->get_trans_key_type_and_value =
- &omap_dss_mgr_get_trans_key_type_and_value,
- mgr->enable_trans_key = &omap_dss_mgr_enable_trans_key,
- mgr->get_trans_key_status = &omap_dss_mgr_get_trans_key_status,
+ &omap_dss_mgr_get_trans_key_type_and_value;
+ mgr->enable_trans_key = &omap_dss_mgr_enable_trans_key;
+ mgr->get_trans_key_status = &omap_dss_mgr_get_trans_key_status;
mgr->enable_alpha_blending =
&omap_dss_mgr_enable_alpha_blending;
mgr->get_alpha_blending_status =
omap_dss_mgr_get_alpha_blending_status;
mgr->get_default_color = &omap_dss_mgr_get_default_color;
- mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC,
+ mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC;
dss_overlay_setup_dispc_manager(mgr);
--
1.5.6.5

View File

@ -0,0 +1,26 @@
From 0f88992b2681aed4f31dc7dd3926b357bbc95154 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Tue, 21 Apr 2009 10:11:55 +0300
Subject: [PATCH] DSS2: DSI: decrease sync timeout from 60s to 2s
The framedone-problem should be ok now, so we shouldn't get long waits.
---
drivers/video/omap2/dss/dsi.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 50af925..d59ad38 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -3216,7 +3216,7 @@ static void dsi_push_set_mirror(struct omap_display *display, int mirror)
static int dsi_wait_sync(struct omap_display *display)
{
- long wait = msecs_to_jiffies(60000);
+ long wait = msecs_to_jiffies(2000);
struct completion compl;
DSSDBGF("");
--
1.5.6.5

View File

@ -0,0 +1,44 @@
From 7ddd5eaa7bc345c3719d613a46a95b7e8052ad2c Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@nokia.com>
Date: Tue, 21 Apr 2009 15:18:36 +0200
Subject: [PATCH] DSS2: fix return value for rotate_type sysfs function
Signed-off-by: Imre Deak <imre.deak@nokia.com>
---
drivers/video/omap2/omapfb/omapfb-sysfs.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 4e3da42..13028ae 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -64,9 +64,10 @@ static ssize_t store_rotate_type(struct device *dev,
if (rot_type == ofbi->rotation_type)
goto out;
- r = -EBUSY;
- if (ofbi->region.size)
+ if (ofbi->region.size) {
+ r = -EBUSY;
goto out;
+ }
ofbi->rotation_type = rot_type;
@@ -74,12 +75,10 @@ static ssize_t store_rotate_type(struct device *dev,
* Since the VRAM for this FB is not allocated at the moment we don't need to
* do any further parameter checking at this point.
*/
-
- r = count;
out:
omapfb_unlock(fbdev);
- return r;
+ return r ? r : count;
}
--
1.5.6.5

View File

@ -0,0 +1,123 @@
From e34564db95627ad20e918b240c45e2bd5555f7e8 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Wed, 22 Apr 2009 10:06:08 +0300
Subject: [PATCH] OMAP2/3: DMA: implement trans copy and const fill
Implement transparent copy and constant fill features for OMAP2/3.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
---
arch/arm/plat-omap/dma.c | 81 +++++++++++++++++++++------------
arch/arm/plat-omap/include/mach/dma.h | 1 +
2 files changed, 52 insertions(+), 30 deletions(-)
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 3fd0e77..060ac71 100755
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -310,41 +310,62 @@ EXPORT_SYMBOL(omap_set_dma_transfer_params);
void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
{
- u16 w;
-
BUG_ON(omap_dma_in_1510_mode());
- if (cpu_class_is_omap2()) {
- REVISIT_24XX();
- return;
- }
+ if (cpu_class_is_omap1()) {
+ u16 w;
- w = dma_read(CCR2(lch));
- w &= ~0x03;
+ w = dma_read(CCR2(lch));
+ w &= ~0x03;
- switch (mode) {
- case OMAP_DMA_CONSTANT_FILL:
- w |= 0x01;
- break;
- case OMAP_DMA_TRANSPARENT_COPY:
- w |= 0x02;
- break;
- case OMAP_DMA_COLOR_DIS:
- break;
- default:
- BUG();
+ switch (mode) {
+ case OMAP_DMA_CONSTANT_FILL:
+ w |= 0x01;
+ break;
+ case OMAP_DMA_TRANSPARENT_COPY:
+ w |= 0x02;
+ break;
+ case OMAP_DMA_COLOR_DIS:
+ break;
+ default:
+ BUG();
+ }
+ dma_write(w, CCR2(lch));
+
+ w = dma_read(LCH_CTRL(lch));
+ w &= ~0x0f;
+ /* Default is channel type 2D */
+ if (mode) {
+ dma_write((u16)color, COLOR_L(lch));
+ dma_write((u16)(color >> 16), COLOR_U(lch));
+ w |= 1; /* Channel type G */
+ }
+ dma_write(w, LCH_CTRL(lch));
}
- dma_write(w, CCR2(lch));
- w = dma_read(LCH_CTRL(lch));
- w &= ~0x0f;
- /* Default is channel type 2D */
- if (mode) {
- dma_write((u16)color, COLOR_L(lch));
- dma_write((u16)(color >> 16), COLOR_U(lch));
- w |= 1; /* Channel type G */
+ if (cpu_class_is_omap2()) {
+ u32 val;
+
+ val = dma_read(CCR(lch));
+ val &= ~((1 << 17) | (1 << 16));
+
+ switch (mode) {
+ case OMAP_DMA_CONSTANT_FILL:
+ val |= 1 << 16;
+ break;
+ case OMAP_DMA_TRANSPARENT_COPY:
+ val |= 1 << 17;
+ break;
+ case OMAP_DMA_COLOR_DIS:
+ break;
+ default:
+ BUG();
+ }
+ dma_write(val, CCR(lch));
+
+ color &= 0xffffff;
+ dma_write(color, COLOR(lch));
}
- dma_write(w, LCH_CTRL(lch));
}
EXPORT_SYMBOL(omap_set_dma_color_mode);
diff --git a/arch/arm/plat-omap/include/mach/dma.h b/arch/arm/plat-omap/include/mach/dma.h
index 224b077..4e34f47 100644
--- a/arch/arm/plat-omap/include/mach/dma.h
+++ b/arch/arm/plat-omap/include/mach/dma.h
@@ -144,6 +144,7 @@
#define OMAP_DMA4_CSSA_U(n) 0
#define OMAP_DMA4_CDSA_L(n) 0
#define OMAP_DMA4_CDSA_U(n) 0
+#define OMAP1_DMA_COLOR(n) 0
/*----------------------------------------------------------------------------*/
--
1.5.6.5

View File

@ -0,0 +1,101 @@
From 02034cc79f69512a6037f03ad1243c28f59fdd8a Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Wed, 22 Apr 2009 10:25:20 +0300
Subject: [PATCH] DSS2: VRAM: clear allocated area with DMA
Use DMA constant fill feature to clear VRAM area when
someone allocates it.
---
arch/arm/plat-omap/vram.c | 57 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 57 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-omap/vram.c b/arch/arm/plat-omap/vram.c
index 8e9fe77..90276ac 100644
--- a/arch/arm/plat-omap/vram.c
+++ b/arch/arm/plat-omap/vram.c
@@ -31,11 +31,13 @@
#include <linux/seq_file.h>
#include <linux/bootmem.h>
#include <linux/omapfb.h>
+#include <linux/completion.h>
#include <asm/setup.h>
#include <mach/sram.h>
#include <mach/vram.h>
+#include <mach/dma.h>
#ifdef DEBUG
#define DBG(format, ...) printk(KERN_DEBUG "VRAM: " format, ## __VA_ARGS__)
@@ -276,6 +278,59 @@ int omap_vram_reserve(unsigned long paddr, size_t size)
}
EXPORT_SYMBOL(omap_vram_reserve);
+static void _omap_vram_dma_cb(int lch, u16 ch_status, void *data)
+{
+ struct completion *compl = data;
+ complete(compl);
+}
+
+static int _omap_vram_clear(u32 paddr, unsigned pages)
+{
+ struct completion compl;
+ unsigned elem_count;
+ unsigned frame_count;
+ int r;
+ int lch;
+
+ init_completion(&compl);
+
+ r = omap_request_dma(OMAP_DMA_NO_DEVICE, "VRAM DMA",
+ _omap_vram_dma_cb,
+ &compl, &lch);
+ if (r) {
+ pr_err("VRAM: request_dma failed for memory clear\n");
+ return -EBUSY;
+ }
+
+ elem_count = pages * PAGE_SIZE / 4;
+ frame_count = 1;
+
+ omap_set_dma_transfer_params(lch, OMAP_DMA_DATA_TYPE_S32,
+ elem_count, frame_count,
+ OMAP_DMA_SYNC_ELEMENT,
+ 0, 0);
+
+ omap_set_dma_dest_params(lch, 0, OMAP_DMA_AMODE_POST_INC,
+ paddr, 0, 0);
+
+ omap_set_dma_color_mode(lch, OMAP_DMA_CONSTANT_FILL, 0x000000);
+
+ omap_start_dma(lch);
+
+ if (wait_for_completion_timeout(&compl, msecs_to_jiffies(1000)) == 0) {
+ omap_stop_dma(lch);
+ pr_err("VRAM: dma timeout while clearing memory\n");
+ r = -EIO;
+ goto err;
+ }
+
+ r = 0;
+err:
+ omap_free_dma(lch);
+
+ return r;
+}
+
static int _omap_vram_alloc(int mtype, unsigned pages, unsigned long *paddr)
{
struct vram_region *rm;
@@ -313,6 +368,8 @@ found:
*paddr = start;
+ _omap_vram_clear(start, pages);
+
return 0;
}
--
1.5.6.5

View File

@ -0,0 +1,53 @@
From 07482193cccdfe9ede1f47d72790dfbe54343505 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Wed, 22 Apr 2009 10:26:06 +0300
Subject: [PATCH] DSS2: OMAPFB: remove fb clearing code
VRAM manager does the clearing now when the area is allocated.
---
drivers/video/omap2/omapfb/omapfb-main.c | 8 --------
1 files changed, 0 insertions(+), 8 deletions(-)
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index cd63740..76e7c6c 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -1174,7 +1174,6 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
struct omapfb2_mem_region *rg;
void __iomem *vaddr;
int r;
- int clear = 0;
rg = &ofbi->region;
memset(rg, 0, sizeof(*rg));
@@ -1184,7 +1183,6 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
if (!paddr) {
DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
r = omap_vram_alloc(OMAPFB_MEMTYPE_SDRAM, size, &paddr);
- clear = 1;
} else {
DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr,
ofbi->id);
@@ -1206,9 +1204,6 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
}
DBG("allocated VRAM paddr %lx, vaddr %p\n", paddr, vaddr);
-
- if (clear)
- memset_io(vaddr, 0, size);
} else {
void __iomem *va;
@@ -1232,9 +1227,6 @@ static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
rg->vrfb.vaddr[0] = va;
vaddr = NULL;
-
- if (clear)
- memset_io(va, 0, size);
}
rg->paddr = paddr;
--
1.5.6.5

View File

@ -0,0 +1,170 @@
From b47aef28536f3c276d232c41cd3084c69389dca4 Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Wed, 22 Apr 2009 14:11:52 +0300
Subject: [PATCH] DSS2: VRAM: use debugfs, not procfs
---
arch/arm/plat-omap/vram.c | 103 +++++++++++++++------------------------------
1 files changed, 34 insertions(+), 69 deletions(-)
diff --git a/arch/arm/plat-omap/vram.c b/arch/arm/plat-omap/vram.c
index 90276ac..e847579 100644
--- a/arch/arm/plat-omap/vram.c
+++ b/arch/arm/plat-omap/vram.c
@@ -27,11 +27,11 @@
#include <linux/mm.h>
#include <linux/list.h>
#include <linux/dma-mapping.h>
-#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/bootmem.h>
#include <linux/omapfb.h>
#include <linux/completion.h>
+#include <linux/debugfs.h>
#include <asm/setup.h>
@@ -398,88 +398,54 @@ int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr)
}
EXPORT_SYMBOL(omap_vram_alloc);
-#ifdef CONFIG_PROC_FS
-static void *r_next(struct seq_file *m, void *v, loff_t *pos)
-{
- struct list_head *l = v;
-
- (*pos)++;
-
- if (list_is_last(l, &region_list))
- return NULL;
-
- return l->next;
-}
-
-static void *r_start(struct seq_file *m, loff_t *pos)
-{
- loff_t p = *pos;
- struct list_head *l = &region_list;
-
- mutex_lock(&region_mutex);
-
- do {
- l = l->next;
- if (l == &region_list)
- return NULL;
- } while (p--);
-
- return l;
-}
-
-static void r_stop(struct seq_file *m, void *v)
-{
- mutex_unlock(&region_mutex);
-}
-
-static int r_show(struct seq_file *m, void *v)
+#if defined(CONFIG_DEBUG_FS)
+static int vram_debug_show(struct seq_file *s, void *unused)
{
struct vram_region *vr;
struct vram_alloc *va;
unsigned size;
- vr = list_entry(v, struct vram_region, list);
-
- size = vr->pages << PAGE_SHIFT;
-
- seq_printf(m, "%08lx-%08lx (%d bytes)\n",
- vr->paddr, vr->paddr + size - 1,
- size);
+ mutex_lock(&region_mutex);
- list_for_each_entry(va, &vr->alloc_list, list) {
- size = va->pages << PAGE_SHIFT;
- seq_printf(m, " %08lx-%08lx (%d bytes)\n",
- va->paddr, va->paddr + size - 1,
+ list_for_each_entry(vr, &region_list, list) {
+ size = vr->pages << PAGE_SHIFT;
+ seq_printf(s, "%08lx-%08lx (%d bytes)\n",
+ vr->paddr, vr->paddr + size - 1,
size);
- }
+ list_for_each_entry(va, &vr->alloc_list, list) {
+ size = va->pages << PAGE_SHIFT;
+ seq_printf(s, " %08lx-%08lx (%d bytes)\n",
+ va->paddr, va->paddr + size - 1,
+ size);
+ }
+ }
+ mutex_unlock(&region_mutex);
return 0;
}
-static const struct seq_operations resource_op = {
- .start = r_start,
- .next = r_next,
- .stop = r_stop,
- .show = r_show,
-};
-
-static int vram_open(struct inode *inode, struct file *file)
+static int vram_debug_open(struct inode *inode, struct file *file)
{
- return seq_open(file, &resource_op);
+ return single_open(file, vram_debug_show, inode->i_private);
}
-static const struct file_operations proc_vram_operations = {
- .open = vram_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release,
+static const struct file_operations vram_debug_fops = {
+ .open = vram_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
};
-static int __init omap_vram_create_proc(void)
+static int __init omap_vram_create_debugfs(void)
{
- proc_create("omap-vram", 0, NULL, &proc_vram_operations);
+ struct dentry *d;
+
+ d = debugfs_create_file("vram", S_IRUGO, NULL,
+ NULL, &vram_debug_fops);
+ if (IS_ERR(d))
+ return PTR_ERR(d);
return 0;
}
@@ -487,7 +453,7 @@ static int __init omap_vram_create_proc(void)
static __init int omap_vram_init(void)
{
- int i, r;
+ int i;
vram_initialized = 1;
@@ -495,10 +461,9 @@ static __init int omap_vram_init(void)
omap_vram_add_region(postponed_regions[i].paddr,
postponed_regions[i].size);
-#ifdef CONFIG_PROC_FS
- r = omap_vram_create_proc();
- if (r)
- return -ENOMEM;
+#ifdef CONFIG_DEBUG_FS
+ if (omap_vram_create_debugfs())
+ pr_err("VRAM: Failed to create debugfs file\n");
#endif
return 0;
--
1.5.6.5

View File

@ -0,0 +1,34 @@
From 635fa66abe6e502c9b78b1dc66757bf67fd163e1 Mon Sep 17 00:00:00 2001
From: Imre Deak <imre.deak@nokia.com>
Date: Wed, 22 Apr 2009 14:40:48 +0200
Subject: [PATCH] DSS2: VRAM: fix section mismatch warning
postponed_regions are accessed from the non __init
omap_vram_add_region().
Signed-off-by: Imre Deak <imre.deak@nokia.com>
---
arch/arm/plat-omap/vram.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/plat-omap/vram.c b/arch/arm/plat-omap/vram.c
index e847579..b126a64 100644
--- a/arch/arm/plat-omap/vram.c
+++ b/arch/arm/plat-omap/vram.c
@@ -63,11 +63,11 @@
#define MAX_POSTPONED_REGIONS 10
static bool vram_initialized;
-static int postponed_cnt __initdata;
+static int postponed_cnt;
static struct {
unsigned long paddr;
size_t size;
-} postponed_regions[MAX_POSTPONED_REGIONS] __initdata;
+} postponed_regions[MAX_POSTPONED_REGIONS];
struct vram_alloc {
struct list_head list;
--
1.5.6.5

View File

@ -0,0 +1,41 @@
From c7ce3c5e9f7e28900b8ea9c3e1afe41dcdc0863d Mon Sep 17 00:00:00 2001
From: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Date: Thu, 23 Apr 2009 10:46:53 +0300
Subject: [PATCH] DSS2: disable LCD & DIGIT before resetting DSS
This seems to fix the synclost problem that we get, if the bootloader
starts the DSS and the kernel resets it.
---
drivers/video/omap2/dss/dss.c | 8 +++++---
1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index adc1f34..aab9758 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -285,6 +285,11 @@ int dss_init(bool skip_init)
}
if (!skip_init) {
+ /* disable LCD and DIGIT output. This seems to fix the synclost
+ * problem that we get, if the bootloader starts the DSS and
+ * the kernel resets it */
+ omap_writel(omap_readl(0x48050440) & ~0x3, 0x48050440);
+
/* We need to wait here a bit, otherwise we sometimes start to
* get synclost errors, and after that only power cycle will
* restore DSS functionality. I have no idea why this happens.
@@ -294,10 +299,7 @@ int dss_init(bool skip_init)
msleep(50);
_omap_dss_reset();
-
}
- else
- printk("DSS SKIP RESET\n");
/* autoidle */
REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0);
--
1.5.6.5

View File

View File

@ -0,0 +1,132 @@
From linux-omap-owner@vger.kernel.org Sun Nov 02 21:08:25 2008
Received: from localhost
([127.0.0.1] helo=dominion ident=koen)
by dominion.dominion.void with esmtp (Exim 4.69)
(envelope-from <linux-omap-owner@vger.kernel.org>)
id 1KwjFJ-0008Hg-0T
for koen@localhost; Sun, 02 Nov 2008 21:08:25 +0100
Received: from xs.service.utwente.nl [130.89.5.250]
by dominion with POP3 (fetchmail-6.3.9-rc2)
for <koen@localhost> (single-drop); Sun, 02 Nov 2008 21:08:25 +0100 (CET)
Received: from mail.service.utwente.nl ([130.89.5.253]) by exchange.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
Sun, 2 Nov 2008 20:57:16 +0100
Received: from mx.utwente.nl ([130.89.2.13]) by mail.service.utwente.nl with Microsoft SMTPSVC(6.0.3790.3959);
Sun, 2 Nov 2008 20:57:16 +0100
Received: from vger.kernel.org (vger.kernel.org [209.132.176.167])
by mx.utwente.nl (8.12.10/SuSE Linux 0.7) with ESMTP id mA2JudEK010968
for <k.kooi@student.utwente.nl>; Sun, 2 Nov 2008 20:56:40 +0100
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
id S1752819AbYKBT4i (ORCPT <rfc822;k.kooi@student.utwente.nl>);
Sun, 2 Nov 2008 14:56:38 -0500
Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1752829AbYKBT4i
(ORCPT <rfc822;linux-omap-outgoing>); Sun, 2 Nov 2008 14:56:38 -0500
Received: from fg-out-1718.google.com ([72.14.220.153]:32481 "EHLO
fg-out-1718.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
with ESMTP id S1752819AbYKBT4h (ORCPT
<rfc822;linux-omap@vger.kernel.org>); Sun, 2 Nov 2008 14:56:37 -0500
Received: by fg-out-1718.google.com with SMTP id 19so1869080fgg.17
for <linux-omap@vger.kernel.org>; Sun, 02 Nov 2008 11:56:33 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
d=gmail.com; s=gamma;
h=domainkey-signature:received:received:from:to:cc:subject:date
:message-id:x-mailer:in-reply-to:references;
bh=Ftvoq8kE3ciPRy7pNy5VLkNnZD8o0HYWIrO1LMS/lAY=;
b=HpEcngDUbAObGNJuQmBIG3SoNHesUL57GluZGlYO7kxFxfH6N8zeHjKuRSk86+mT5s
gMhyCC07wjVp75HnqCtKbOJzNw/8F4ZGbL2lY1LC99+zxHW1JBQv5c3ZaoCVqTw6TuH0
bQ8Ew2BwHknT3wGA+QcGoMJJs5aw62AhPiyHY=
DomainKey-Signature: a=rsa-sha1; c=nofws;
d=gmail.com; s=gamma;
h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references;
b=aio1APZhCIcYIrMY844QkdaQzKw0/yiuaVjqfv52fnft1kafGT2qAS3KfXAc61a9If
sXHbi2fr/r1a7YZJJVGqkJX0WmWTY0OqdhS1lmugP/dXEMHeqaArKATbvxrq9/svb1bV
Vzpkm6sOzLrr54uo+BcZNoxHWqb8W2UrRxuTk=
Received: by 10.103.131.18 with SMTP id i18mr6668205mun.126.1225655793072;
Sun, 02 Nov 2008 11:56:33 -0800 (PST)
Received: from localhost.localdomain ([78.59.134.74])
by mx.google.com with ESMTPS id g1sm23199635muf.8.2008.11.02.11.56.31
(version=TLSv1/SSLv3 cipher=RC4-MD5);
Sun, 02 Nov 2008 11:56:31 -0800 (PST)
From: Grazvydas Ignotas <notasas@gmail.com>
To: linux-omap@vger.kernel.org
Cc: Grazvydas Ignotas <notasas@gmail.com>
Subject: Re: omap3evm LCD red-tint workaround
Date: Sun, 2 Nov 2008 21:56:19 +0200
Message-Id: <1225655779-18934-1-git-send-email-notasas@gmail.com>
X-Mailer: git-send-email 1.5.4.3
In-Reply-To: <57322719-1A5A-45DC-9846-5C0A3B6EF346@student.utwente.nl>
References: <57322719-1A5A-45DC-9846-5C0A3B6EF346@student.utwente.nl>
Sender: linux-omap-owner@vger.kernel.org
Precedence: bulk
List-ID: <linux-omap.vger.kernel.org>
X-Mailing-List: linux-omap@vger.kernel.org
X-UTwente-MailScanner-Information: Scanned by MailScanner. Contact servicedesk@icts.utwente.nl for more information.
X-UTwente-MailScanner: Found to be clean
X-UTwente-MailScanner-From: linux-omap-owner@vger.kernel.org
X-Spam-Status: No
X-OriginalArrivalTime: 02 Nov 2008 19:57:16.0876 (UTC) FILETIME=[34FBA0C0:01C93D25]
> PS: TS is still unusable with the 16x16 pixel resolution
This is also the case for Pandora. The patch below fixes the problem,
but as I have no other boards to test this on, I haven't sent it.
See if it helps you.
From 91f3af26bbf751b846e6265d86387e81be7c1364 Mon Sep 17 00:00:00 2001
From: Grazvydas Ignotas <notasas@gmail.com>
Date: Tue, 28 Oct 2008 22:01:42 +0200
Subject: [PATCH] OMAP3: fix McSPI transfers
Currently on OMAP3 if both write and read is set up for a transfer,
the first byte returned on read is corrupted. Work around this by
disabling channel between reads and writes, instead of transfers.
---
drivers/spi/omap2_mcspi.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 454a271..4890b6c 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -710,7 +710,6 @@ static void omap2_mcspi_work(struct work_struct *work)
spi = m->spi;
cs = spi->controller_state;
- omap2_mcspi_set_enable(spi, 1);
list_for_each_entry(t, &m->transfers, transfer_list) {
if (t->tx_buf == NULL && t->rx_buf == NULL && t->len) {
status = -EINVAL;
@@ -741,6 +740,8 @@ static void omap2_mcspi_work(struct work_struct *work)
if (t->len) {
unsigned count;
+ omap2_mcspi_set_enable(spi, 1);
+
/* RX_ONLY mode needs dummy data in TX reg */
if (t->tx_buf == NULL)
__raw_writel(0, cs->base
@@ -752,6 +753,8 @@ static void omap2_mcspi_work(struct work_struct *work)
count = omap2_mcspi_txrx_pio(spi, t);
m->actual_length += count;
+ omap2_mcspi_set_enable(spi, 0);
+
if (count != t->len) {
status = -EIO;
break;
@@ -777,8 +780,6 @@ static void omap2_mcspi_work(struct work_struct *work)
if (cs_active)
omap2_mcspi_force_cs(spi, 0);
- omap2_mcspi_set_enable(spi, 0);
-
m->status = status;
m->complete(m->context);
--
1.5.4.3
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

View File

@ -0,0 +1,16 @@
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index ee2f0d3..8b4aafb 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -45,8 +45,8 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
0xc3, /* REG_OPTION (0x2) */
0x00, /* REG_UNKNOWN (0x3) */
0x00, /* REG_MICBIAS_CTL (0x4) */
- 0x20, /* REG_ANAMICL (0x5) */
- 0x00, /* REG_ANAMICR (0x6) */
+ 0x34, /* REG_ANAMICL (0x5) */
+ 0x14, /* REG_ANAMICR (0x6) */
0x00, /* REG_AVADC_CTL (0x7) */
0x00, /* REG_ADCMICSEL (0x8) */
0x00, /* REG_DIGMIXING (0x9) */

View File

@ -0,0 +1,23 @@
From: Steve Sakoman <steve@sakoman.com>
Date: Mon, 18 Aug 2008 16:07:31 +0000 (-0700)
Subject: scripts/Makefile.fwinst: add missing space when setting mode in cmd_install
X-Git-Url: http://www.sakoman.net/cgi-bin/gitweb.cgi?p=linux-omap-2.6.git;a=commitdiff_plain;h=f039944bdd491cde7327133e9976881d3133ae70
scripts/Makefile.fwinst: add missing space when setting mode in cmd_install
This was causing build failures on some machines
---
diff --git a/scripts/Makefile.fwinst b/scripts/Makefile.fwinst
index 6bf8e87..fb20532 100644
--- a/scripts/Makefile.fwinst
+++ b/scripts/Makefile.fwinst
@@ -37,7 +37,7 @@ install-all-dirs: $(installed-fw-dirs)
@true
quiet_cmd_install = INSTALL $(subst $(srctree)/,,$@)
- cmd_install = $(INSTALL) -m0644 $< $@
+ cmd_install = $(INSTALL) -m 0644 $< $@
$(installed-fw-dirs):
$(call cmd,mkdir)

View File

@ -0,0 +1,41 @@
From: Mans Rullgard <mans@mansr.com>
Date: Sat, 28 Mar 2009 12:54:25 +0000 (+0000)
Subject: NSM: Fix unaligned accesses in nsm_init_private()
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=8f2bd6fdde1ebfef57f65b6cf29b29008c23d297
NSM: Fix unaligned accesses in nsm_init_private()
This fixes unaligned accesses in nsm_init_private() when
creating nlm_reboot keys.
Signed-off-by: Mans Rullgard <mans@mansr.com>
---
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 5e2c4d5..6d5d4a4 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -16,6 +16,8 @@
#include <linux/sunrpc/svc.h>
#include <linux/lockd/lockd.h>
+#include <asm/unaligned.h>
+
#define NLMDBG_FACILITY NLMDBG_MONITOR
#define NSM_PROGRAM 100024
#define NSM_VERSION 1
@@ -274,10 +276,12 @@ static void nsm_init_private(struct nsm_handle *nsm)
{
u64 *p = (u64 *)&nsm->sm_priv.data;
struct timespec ts;
+ s64 ns;
ktime_get_ts(&ts);
- *p++ = timespec_to_ns(&ts);
- *p = (unsigned long)nsm;
+ ns = timespec_to_ns(&ts);
+ put_unaligned(ns, p);
+ put_unaligned((unsigned long)nsm, p + 1);
}
static struct nsm_handle *nsm_create_handle(const struct sockaddr *sap,

View File

@ -0,0 +1,153 @@
From 742cc1e62f0d04333c51630f3020da000aeb6de1 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
Date: Mon, 2 Mar 2009 19:36:26 +0200
Subject: [PATCH] omap3: Add base address definitions and resources for OMAP 3 ISP
This replaces earlier patch from Sergio Aguirre titled "[REVIEW PATCH 03/14]
OMAP34XX: CAM: Resources fixes".
Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
arch/arm/mach-omap2/devices.c | 66 ++++++++++++++++++++++++---
arch/arm/plat-omap/include/mach/omap34xx.h | 28 +++++++++++-
2 files changed, 85 insertions(+), 9 deletions(-)
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index dad4528..2568b0c 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -56,10 +56,60 @@ static inline void omap_init_camera(void)
#elif defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
-static struct resource cam_resources[] = {
+static struct resource omap3isp_resources[] = {
+ {
+ .start = OMAP3430_ISP_BASE,
+ .end = OMAP3430_ISP_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CBUFF_BASE,
+ .end = OMAP3430_ISP_CBUFF_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CCP2_BASE,
+ .end = OMAP3430_ISP_CCP2_END,
+ .flags = IORESOURCE_MEM,
+ },
{
- .start = OMAP34XX_CAMERA_BASE,
- .end = OMAP34XX_CAMERA_BASE + 0x1B70,
+ .start = OMAP3430_ISP_CCDC_BASE,
+ .end = OMAP3430_ISP_CCDC_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_HIST_BASE,
+ .end = OMAP3430_ISP_HIST_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_H3A_BASE,
+ .end = OMAP3430_ISP_H3A_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_PREV_BASE,
+ .end = OMAP3430_ISP_PREV_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_RESZ_BASE,
+ .end = OMAP3430_ISP_RESZ_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_SBL_BASE,
+ .end = OMAP3430_ISP_SBL_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CSI2A_BASE,
+ .end = OMAP3430_ISP_CSI2A_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CSI2PHY_BASE,
+ .end = OMAP3430_ISP_CSI2PHY_END,
.flags = IORESOURCE_MEM,
},
{
@@ -68,16 +118,16 @@ static struct resource cam_resources[] = {
}
};
-static struct platform_device omap_cam_device = {
- .name = "omap34xxcam",
+static struct platform_device omap3isp_device = {
+ .name = "omap3isp",
.id = -1,
- .num_resources = ARRAY_SIZE(cam_resources),
- .resource = cam_resources,
+ .num_resources = ARRAY_SIZE(omap3isp_resources),
+ .resource = omap3isp_resources,
};
static inline void omap_init_camera(void)
{
- platform_device_register(&omap_cam_device);
+ platform_device_register(&omap3isp_device);
}
#else
static inline void omap_init_camera(void)
diff --git a/arch/arm/plat-omap/include/mach/omap34xx.h b/arch/arm/plat-omap/include/mach/omap34xx.h
index 27a1e45..3bfbdf7 100644
--- a/arch/arm/plat-omap/include/mach/omap34xx.h
+++ b/arch/arm/plat-omap/include/mach/omap34xx.h
@@ -49,6 +49,33 @@
#define OMAP343X_CTRL_BASE OMAP343X_SCM_BASE
#define OMAP34XX_IC_BASE 0x48200000
+
+#define OMAP3430_ISP_BASE (L4_34XX_BASE + 0xBC000)
+#define OMAP3430_ISP_CBUFF_BASE (OMAP3430_ISP_BASE + 0x0100)
+#define OMAP3430_ISP_CCP2_BASE (OMAP3430_ISP_BASE + 0x0400)
+#define OMAP3430_ISP_CCDC_BASE (OMAP3430_ISP_BASE + 0x0600)
+#define OMAP3430_ISP_HIST_BASE (OMAP3430_ISP_BASE + 0x0A00)
+#define OMAP3430_ISP_H3A_BASE (OMAP3430_ISP_BASE + 0x0C00)
+#define OMAP3430_ISP_PREV_BASE (OMAP3430_ISP_BASE + 0x0E00)
+#define OMAP3430_ISP_RESZ_BASE (OMAP3430_ISP_BASE + 0x1000)
+#define OMAP3430_ISP_SBL_BASE (OMAP3430_ISP_BASE + 0x1200)
+#define OMAP3430_ISP_MMU_BASE (OMAP3430_ISP_BASE + 0x1400)
+#define OMAP3430_ISP_CSI2A_BASE (OMAP3430_ISP_BASE + 0x1800)
+#define OMAP3430_ISP_CSI2PHY_BASE (OMAP3430_ISP_BASE + 0x1970)
+
+#define OMAP3430_ISP_END (OMAP3430_ISP_BASE + 0x06F)
+#define OMAP3430_ISP_CBUFF_END (OMAP3430_ISP_CBUFF_BASE + 0x077)
+#define OMAP3430_ISP_CCP2_END (OMAP3430_ISP_CCP2_BASE + 0x1EF)
+#define OMAP3430_ISP_CCDC_END (OMAP3430_ISP_CCDC_BASE + 0x0A7)
+#define OMAP3430_ISP_HIST_END (OMAP3430_ISP_HIST_BASE + 0x047)
+#define OMAP3430_ISP_H3A_END (OMAP3430_ISP_H3A_BASE + 0x05F)
+#define OMAP3430_ISP_PREV_END (OMAP3430_ISP_PREV_BASE + 0x09F)
+#define OMAP3430_ISP_RESZ_END (OMAP3430_ISP_RESZ_BASE + 0x0AB)
+#define OMAP3430_ISP_SBL_END (OMAP3430_ISP_SBL_BASE + 0x0FB)
+#define OMAP3430_ISP_MMU_END (OMAP3430_ISP_MMU_BASE + 0x06F)
+#define OMAP3430_ISP_CSI2A_END (OMAP3430_ISP_CSI2A_BASE + 0x16F)
+#define OMAP3430_ISP_CSI2PHY_END (OMAP3430_ISP_CSI2PHY_BASE + 0x007)
+
#define OMAP34XX_IVA_INTC_BASE 0x40000000
#define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000)
#define OMAP34XX_HSUSB_HOST_BASE (L4_34XX_BASE + 0x64000)
@@ -56,7 +83,6 @@
#define OMAP34XX_SR1_BASE 0x480C9000
#define OMAP34XX_SR2_BASE 0x480CB000
-#define OMAP34XX_CAMERA_BASE (L4_34XX_BASE + 0xBC000)
#define OMAP34XX_MAILBOX_BASE (L4_34XX_BASE + 0x94000)
--
1.5.6.5

View File

@ -0,0 +1,453 @@
From c79d7959c45f40e47520aa6acd54c19094754787 Mon Sep 17 00:00:00 2001
From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Date: Mon, 26 Jan 2009 15:13:45 +0200
Subject: [PATCH] omap iommu: omap2 architecture specific functions
The structure 'arch_mmu' accommodates the difference between omap1 and
omap2/3.
This patch provides omap2/3 specific functions
Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
---
arch/arm/mach-omap2/iommu2.c | 326 ++++++++++++++++++++++++++++++
arch/arm/plat-omap/include/mach/iommu2.h | 94 +++++++++
2 files changed, 420 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-omap2/iommu2.c
create mode 100644 arch/arm/plat-omap/include/mach/iommu2.h
diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
new file mode 100644
index 0000000..88a44f1
--- /dev/null
+++ b/arch/arm/mach-omap2/iommu2.c
@@ -0,0 +1,326 @@
+/*
+ * omap iommu: omap2/3 architecture specific functions
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>,
+ * Paul Mundt and Toshihiro Kobayashi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/module.h>
+#include <linux/stringify.h>
+
+#include <asm/io.h>
+
+#include <mach/iommu.h>
+#include <mach/iommu2.h>
+
+/*
+ * omap2 architecture specific register bit definitions
+ */
+#define IOMMU_ARCH_VERSION 0x00000011
+
+/* SYSCONF */
+#define MMU_SYS_IDLE_SHIFT 3
+#define MMU_SYS_IDLE_FORCE (0 << MMU_SYS_IDLE_SHIFT)
+#define MMU_SYS_IDLE_NONE (1 << MMU_SYS_IDLE_SHIFT)
+#define MMU_SYS_IDLE_SMART (2 << MMU_SYS_IDLE_SHIFT)
+#define MMU_SYS_IDLE_MASK (3 << MMU_SYS_IDLE_SHIFT)
+
+#define MMU_SYS_SOFTRESET (1 << 1)
+#define MMU_SYS_AUTOIDLE 1
+
+/* SYSSTATUS */
+#define MMU_SYS_RESETDONE 1
+
+/* IRQSTATUS & IRQENABLE */
+#define MMU_IRQ_MULTIHITFAULT (1 << 4)
+#define MMU_IRQ_TABLEWALKFAULT (1 << 3)
+#define MMU_IRQ_EMUMISS (1 << 2)
+#define MMU_IRQ_TRANSLATIONFAULT (1 << 1)
+#define MMU_IRQ_TLBMISS (1 << 0)
+#define MMU_IRQ_MASK \
+ (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_EMUMISS | \
+ MMU_IRQ_TRANSLATIONFAULT)
+
+/* MMU_CNTL */
+#define MMU_CNTL_SHIFT 1
+#define MMU_CNTL_MASK (7 << MMU_CNTL_SHIFT)
+#define MMU_CNTL_EML_TLB (1 << 3)
+#define MMU_CNTL_TWL_EN (1 << 2)
+#define MMU_CNTL_MMU_EN (1 << 1)
+
+#define get_cam_va_mask(pgsz) \
+ (((pgsz) == MMU_CAM_PGSZ_16M) ? 0xff000000 : \
+ ((pgsz) == MMU_CAM_PGSZ_1M) ? 0xfff00000 : \
+ ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \
+ ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0)
+
+static int omap2_iommu_enable(struct iommu *obj)
+{
+ u32 l, pa;
+ unsigned long timeout;
+
+ if (!obj->iopgd || !IS_ALIGNED((u32)obj->iopgd, SZ_16K))
+ return -EINVAL;
+
+ pa = virt_to_phys(obj->iopgd);
+ if (!IS_ALIGNED(pa, SZ_16K))
+ return -EINVAL;
+
+ iommu_write_reg(obj, MMU_SYS_SOFTRESET, MMU_SYSCONFIG);
+
+ timeout = jiffies + msecs_to_jiffies(20);
+ do {
+ l = iommu_read_reg(obj, MMU_SYSSTATUS);
+ if (l & MMU_SYS_RESETDONE)
+ break;
+ } while (time_after(jiffies, timeout));
+
+ if (!(l & MMU_SYS_RESETDONE)) {
+ dev_err(obj->dev, "can't take mmu out of reset\n");
+ return -ENODEV;
+ }
+
+ l = iommu_read_reg(obj, MMU_REVISION);
+ dev_info(obj->dev, "%s: version %d.%d\n", obj->name,
+ (l >> 4) & 0xf, l & 0xf);
+
+ l = iommu_read_reg(obj, MMU_SYSCONFIG);
+ l &= ~MMU_SYS_IDLE_MASK;
+ l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE);
+ iommu_write_reg(obj, l, MMU_SYSCONFIG);
+
+ iommu_write_reg(obj, MMU_IRQ_MASK, MMU_IRQENABLE);
+ iommu_write_reg(obj, pa, MMU_TTB);
+
+ l = iommu_read_reg(obj, MMU_CNTL);
+ l &= ~MMU_CNTL_MASK;
+ l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN);
+ iommu_write_reg(obj, l, MMU_CNTL);
+
+ return 0;
+}
+
+static void omap2_iommu_disable(struct iommu *obj)
+{
+ u32 l = iommu_read_reg(obj, MMU_CNTL);
+
+ l &= ~MMU_CNTL_MASK;
+ iommu_write_reg(obj, l, MMU_CNTL);
+ iommu_write_reg(obj, MMU_SYS_IDLE_FORCE, MMU_SYSCONFIG);
+
+ dev_dbg(obj->dev, "%s is shutting down\n", obj->name);
+}
+
+static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
+{
+ int i;
+ u32 stat, da;
+ const char *err_msg[] = {
+ "tlb miss",
+ "translation fault",
+ "emulation miss",
+ "table walk fault",
+ "multi hit fault",
+ };
+
+ stat = iommu_read_reg(obj, MMU_IRQSTATUS);
+ stat &= MMU_IRQ_MASK;
+ if (!stat)
+ return 0;
+
+ da = iommu_read_reg(obj, MMU_FAULT_AD);
+ *ra = da;
+
+ dev_err(obj->dev, "%s:\tda:%08x ", __func__, da);
+
+ for (i = 0; i < ARRAY_SIZE(err_msg); i++) {
+ if (stat & (1 << i))
+ printk("%s ", err_msg[i]);
+ }
+ printk("\n");
+
+ iommu_write_reg(obj, stat, MMU_IRQSTATUS);
+ return stat;
+}
+
+static void omap2_tlb_read_cr(struct iommu *obj, struct cr_regs *cr)
+{
+ cr->cam = iommu_read_reg(obj, MMU_READ_CAM);
+ cr->ram = iommu_read_reg(obj, MMU_READ_RAM);
+}
+
+static void omap2_tlb_load_cr(struct iommu *obj, struct cr_regs *cr)
+{
+ iommu_write_reg(obj, cr->cam | MMU_CAM_V, MMU_CAM);
+ iommu_write_reg(obj, cr->ram, MMU_RAM);
+}
+
+static u32 omap2_cr_to_virt(struct cr_regs *cr)
+{
+ u32 page_size = cr->cam & MMU_CAM_PGSZ_MASK;
+ u32 mask = get_cam_va_mask(cr->cam & page_size);
+
+ return cr->cam & mask;
+}
+
+static struct cr_regs *omap2_alloc_cr(struct iommu *obj, struct iotlb_entry *e)
+{
+ struct cr_regs *cr;
+
+ if (e->da & ~(get_cam_va_mask(e->pgsz))) {
+ dev_err(obj->dev, "%s:\twrong alignment: %08x\n", __func__,
+ e->da);
+ return ERR_PTR(-EINVAL);
+ }
+
+ cr = kmalloc(sizeof(*cr), GFP_KERNEL);
+ if (!cr)
+ return ERR_PTR(-ENOMEM);
+
+ cr->cam = (e->da & MMU_CAM_VATAG_MASK) | e->prsvd | e->pgsz;
+ cr->ram = e->pa | e->endian | e->elsz | e->mixed;
+
+ return cr;
+}
+
+static inline int omap2_cr_valid(struct cr_regs *cr)
+{
+ return cr->cam & MMU_CAM_V;
+}
+
+static u32 omap2_get_pte_attr(struct iotlb_entry *e)
+{
+ u32 attr;
+
+ attr = e->mixed << 5;
+ attr |= e->endian;
+ attr |= e->elsz >> 3;
+ attr <<= ((e->pgsz & MMU_CAM_PGSZ_4K) ? 0 : 6);
+
+ return attr;
+}
+
+static ssize_t omap2_dump_cr(struct iommu *obj, struct cr_regs *cr, char *buf)
+{
+ char *p = buf;
+
+ /* FIXME: Need more detail analysis of cam/ram */
+ p += sprintf(p, "%08x %08x\n", cr->cam, cr->ram);
+
+ return p - buf;
+}
+
+#define pr_reg(name) \
+ p += sprintf(p, "%20s: %08x\n", \
+ __stringify(name), iommu_read_reg(obj, MMU_##name));
+
+static ssize_t omap2_iommu_dump_ctx(struct iommu *obj, char *buf)
+{
+ char *p = buf;
+
+ pr_reg(REVISION);
+ pr_reg(SYSCONFIG);
+ pr_reg(SYSSTATUS);
+ pr_reg(IRQSTATUS);
+ pr_reg(IRQENABLE);
+ pr_reg(WALKING_ST);
+ pr_reg(CNTL);
+ pr_reg(FAULT_AD);
+ pr_reg(TTB);
+ pr_reg(LOCK);
+ pr_reg(LD_TLB);
+ pr_reg(CAM);
+ pr_reg(RAM);
+ pr_reg(GFLUSH);
+ pr_reg(FLUSH_ENTRY);
+ pr_reg(READ_CAM);
+ pr_reg(READ_RAM);
+ pr_reg(EMU_FAULT_AD);
+
+ return p - buf;
+}
+
+static void omap2_iommu_save_ctx(struct iommu *obj)
+{
+ int i;
+ u32 *p = obj->ctx;
+
+ for (i = 0; i < (MMU_REG_SIZE / sizeof(u32)); i++) {
+ p[i] = iommu_read_reg(obj, i * sizeof(u32));
+ dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]);
+ }
+
+ BUG_ON(p[0] != IOMMU_ARCH_VERSION);
+}
+
+static void omap2_iommu_restore_ctx(struct iommu *obj)
+{
+ int i;
+ u32 *p = obj->ctx;
+
+ for (i = 0; i < (MMU_REG_SIZE / sizeof(u32)); i++) {
+ iommu_write_reg(obj, p[i], i * sizeof(u32));
+ dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]);
+ }
+
+ BUG_ON(p[0] != IOMMU_ARCH_VERSION);
+}
+
+static void omap2_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e)
+{
+ e->da = cr->cam & MMU_CAM_VATAG_MASK;
+ e->pa = cr->ram & MMU_RAM_PADDR_MASK;
+ e->valid = cr->cam & MMU_CAM_V;
+ e->pgsz = cr->cam & MMU_CAM_PGSZ_MASK;
+ e->endian = cr->ram & MMU_RAM_ENDIAN_MASK;
+ e->elsz = cr->ram & MMU_RAM_ELSZ_MASK;
+ e->mixed = cr->ram & MMU_RAM_MIXED;
+}
+
+static const struct iommu_functions omap2_iommu_ops = {
+ .version = IOMMU_ARCH_VERSION,
+
+ .enable = omap2_iommu_enable,
+ .disable = omap2_iommu_disable,
+ .fault_isr = omap2_iommu_fault_isr,
+
+ .tlb_read_cr = omap2_tlb_read_cr,
+ .tlb_load_cr = omap2_tlb_load_cr,
+
+ .cr_to_e = omap2_cr_to_e,
+ .cr_to_virt = omap2_cr_to_virt,
+ .alloc_cr = omap2_alloc_cr,
+ .cr_valid = omap2_cr_valid,
+ .dump_cr = omap2_dump_cr,
+
+ .get_pte_attr = omap2_get_pte_attr,
+
+ .save_ctx = omap2_iommu_save_ctx,
+ .restore_ctx = omap2_iommu_restore_ctx,
+ .dump_ctx = omap2_iommu_dump_ctx,
+};
+
+static int __init omap2_iommu_init(void)
+{
+ return install_iommu_arch(&omap2_iommu_ops);
+}
+module_init(omap2_iommu_init);
+
+static void __exit omap2_iommu_exit(void)
+{
+ uninstall_iommu_arch(&omap2_iommu_ops);
+}
+module_exit(omap2_iommu_exit);
+
+MODULE_AUTHOR("Hiroshi DOYU, Paul Mundt and Toshihiro Kobayashi");
+MODULE_DESCRIPTION("omap iommu: omap2/3 architecture specific functions");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/plat-omap/include/mach/iommu2.h b/arch/arm/plat-omap/include/mach/iommu2.h
new file mode 100644
index 0000000..d746047
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/iommu2.h
@@ -0,0 +1,94 @@
+/*
+ * omap iommu: omap2 architecture specific definitions
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.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 __MACH_IOMMU2_H
+#define __MACH_IOMMU2_H
+
+/*
+ * MMU Register offsets
+ */
+#define MMU_REVISION 0x00
+#define MMU_SYSCONFIG 0x10
+#define MMU_SYSSTATUS 0x14
+#define MMU_IRQSTATUS 0x18
+#define MMU_IRQENABLE 0x1c
+#define MMU_WALKING_ST 0x40
+#define MMU_CNTL 0x44
+#define MMU_FAULT_AD 0x48
+#define MMU_TTB 0x4c
+#define MMU_LOCK 0x50
+#define MMU_LD_TLB 0x54
+#define MMU_CAM 0x58
+#define MMU_RAM 0x5c
+#define MMU_GFLUSH 0x60
+#define MMU_FLUSH_ENTRY 0x64
+#define MMU_READ_CAM 0x68
+#define MMU_READ_RAM 0x6c
+#define MMU_EMU_FAULT_AD 0x70
+
+#define MMU_REG_SIZE 256
+
+/*
+ * MMU Register bit definitions
+ */
+#define MMU_LOCK_BASE_SHIFT 10
+#define MMU_LOCK_BASE_MASK (0x1f << MMU_LOCK_BASE_SHIFT)
+#define MMU_LOCK_BASE(x) \
+ ((x & MMU_LOCK_BASE_MASK) >> MMU_LOCK_BASE_SHIFT)
+
+#define MMU_LOCK_VICT_SHIFT 4
+#define MMU_LOCK_VICT_MASK (0x1f << MMU_LOCK_VICT_SHIFT)
+#define MMU_LOCK_VICT(x) \
+ ((x & MMU_LOCK_VICT_MASK) >> MMU_LOCK_VICT_SHIFT)
+
+#define MMU_CAM_VATAG_SHIFT 12
+#define MMU_CAM_VATAG_MASK \
+ ((~0UL >> MMU_CAM_VATAG_SHIFT) << MMU_CAM_VATAG_SHIFT)
+#define MMU_CAM_P (1 << 3)
+#define MMU_CAM_V (1 << 2)
+#define MMU_CAM_PGSZ_MASK 3
+#define MMU_CAM_PGSZ_1M (0 << 0)
+#define MMU_CAM_PGSZ_64K (1 << 0)
+#define MMU_CAM_PGSZ_4K (2 << 0)
+#define MMU_CAM_PGSZ_16M (3 << 0)
+
+#define MMU_RAM_PADDR_SHIFT 12
+#define MMU_RAM_PADDR_MASK \
+ ((~0UL >> MMU_RAM_PADDR_SHIFT) << MMU_RAM_PADDR_SHIFT)
+#define MMU_RAM_ENDIAN_SHIFT 9
+#define MMU_RAM_ENDIAN_MASK (1 << MMU_RAM_ENDIAN_SHIFT)
+#define MMU_RAM_ENDIAN_BIG (1 << MMU_RAM_ENDIAN_SHIFT)
+#define MMU_RAM_ENDIAN_LITTLE (0 << MMU_RAM_ENDIAN_SHIFT)
+#define MMU_RAM_ELSZ_SHIFT 7
+#define MMU_RAM_ELSZ_MASK (3 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_8 (0 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_16 (1 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_32 (2 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_ELSZ_NONE (3 << MMU_RAM_ELSZ_SHIFT)
+#define MMU_RAM_MIXED_SHIFT 6
+#define MMU_RAM_MIXED_MASK (1 << MMU_RAM_MIXED_SHIFT)
+#define MMU_RAM_MIXED MMU_RAM_MIXED_MASK
+
+/*
+ * register accessors
+ */
+static inline u32 iommu_read_reg(struct iommu *obj, size_t offs)
+{
+ return __raw_readl(obj->regbase + offs);
+}
+
+static inline void iommu_write_reg(struct iommu *obj, u32 val, size_t offs)
+{
+ __raw_writel(val, obj->regbase + offs);
+}
+
+#endif /* __MACH_IOMMU2_H */
--
1.5.6.5

View File

@ -0,0 +1,124 @@
From 6a84082597dd322713c5d5951530e3eecb878ad4 Mon Sep 17 00:00:00 2001
From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Date: Wed, 28 Jan 2009 21:32:04 +0200
Subject: [PATCH] omap iommu: omap3 iommu device registration
Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
---
arch/arm/mach-omap2/omap3-iommu.c | 104 +++++++++++++++++++++++++++++++++++++
1 files changed, 104 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-omap2/omap3-iommu.c
diff --git a/arch/arm/mach-omap2/omap3-iommu.c b/arch/arm/mach-omap2/omap3-iommu.c
new file mode 100644
index 0000000..97481cc
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3-iommu.c
@@ -0,0 +1,104 @@
+/*
+ * omap iommu: omap3 device registration
+ *
+ * Copyright (C) 2008-2009 Nokia Corporation
+ *
+ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/iommu.h>
+
+#define OMAP3_MMU1_BASE 0x480bd400
+#define OMAP3_MMU2_BASE 0x5d000000
+#define OMAP3_MMU1_IRQ 24
+#define OMAP3_MMU2_IRQ 28
+
+static struct resource omap3_iommu_res[] = {
+ { /* Camera ISP MMU */
+ .start = OMAP3_MMU1_BASE,
+ .end = OMAP3_MMU1_BASE + MMU_REG_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3_MMU1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ { /* IVA2.2 MMU */
+ .start = OMAP3_MMU2_BASE,
+ .end = OMAP3_MMU2_BASE + MMU_REG_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3_MMU2_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+#define NR_IOMMU_RES (ARRAY_SIZE(omap3_iommu_res) / 2)
+
+static const struct iommu_platform_data omap3_iommu_pdata[] __initconst = {
+ {
+ .name = "isp",
+ .nr_tlb_entries = 8,
+ .clk_name = "cam_ick",
+ },
+ {
+ .name = "iva2",
+ .nr_tlb_entries = 32,
+ .clk_name = "iva2_ck",
+ },
+};
+#define NR_IOMMU_DEVICES ARRAY_SIZE(omap3_iommu_pdata)
+
+static struct platform_device *omap3_iommu_pdev[NR_IOMMU_DEVICES];
+
+static int __init omap3_iommu_init(void)
+{
+ int i, err;
+
+ for (i = 0; i < NR_IOMMU_DEVICES; i++) {
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc("omap-iommu", i + 1);
+ if (!pdev)
+ goto err_out;
+ err = platform_device_add_resources(pdev,
+ &omap3_iommu_res[2 * i], NR_IOMMU_RES);
+ if (err)
+ goto err_out;
+ err = platform_device_add_data(pdev, &omap3_iommu_pdata[i],
+ sizeof(omap3_iommu_pdata[0]));
+ if (err)
+ goto err_out;
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_out;
+ omap3_iommu_pdev[i] = pdev;
+ }
+ return 0;
+
+err_out:
+ while (i--)
+ platform_device_put(omap3_iommu_pdev[i]);
+ return err;
+}
+module_init(omap3_iommu_init);
+
+static void __exit omap3_iommu_exit(void)
+{
+ int i;
+
+ for (i = 0; i < NR_IOMMU_DEVICES; i++)
+ platform_device_unregister(omap3_iommu_pdev[i]);
+}
+module_exit(omap3_iommu_exit);
+
+MODULE_AUTHOR("Hiroshi DOYU");
+MODULE_DESCRIPTION("omap iommu: omap3 device registration");
+MODULE_LICENSE("GPL v2");
--
1.5.6.5

View File

@ -0,0 +1,45 @@
From 7de046a6a8446358001c38ad1d0b2b829ca0c98c Mon Sep 17 00:00:00 2001
From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Date: Wed, 28 Jan 2009 21:32:08 +0200
Subject: [PATCH] omap iommu: entries for Kconfig and Makefile
Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
---
arch/arm/plat-omap/Kconfig | 8 ++++++++
arch/arm/plat-omap/Makefile | 1 +
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index b16ae76..2090bb5 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -176,6 +176,14 @@ config OMAP_MBOX_FWK
Say Y here if you want to use OMAP Mailbox framework support for
DSP, IVA1.0 and IVA2 in OMAP1/2/3.
+config OMAP_IOMMU
+ tristate "IOMMU support"
+ depends on ARCH_OMAP
+ default n
+ help
+ Say Y here if you want to use OMAP IOMMU support for IVA2 and
+ Camera in OMAP3.
+
choice
prompt "System timer"
default OMAP_MPU_TIMER
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 3ebc09e..aa8f6df 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -13,6 +13,7 @@ obj- :=
obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
+obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
--
1.5.6.5

View File

@ -0,0 +1,26 @@
From b03f695e25bbdaa95a2cc87e15ee8592e7ca128d Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
Date: Tue, 10 Feb 2009 18:01:29 +0200
Subject: [PATCH] omap iommu: Don't try BUG_ON(in_interrupt())
Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
arch/arm/plat-omap/iovmm.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c
index 6726d10..bdfbb09 100644
--- a/arch/arm/plat-omap/iovmm.c
+++ b/arch/arm/plat-omap/iovmm.c
@@ -523,8 +523,6 @@ static struct sg_table *unmap_vm_area(struct iommu *obj, const u32 da,
struct sg_table *sgt = NULL;
struct iovm_struct *area;
- BUG_ON(in_interrupt());
-
if (!IS_ALIGNED(da, PAGE_SIZE)) {
dev_err(obj->dev, "%s: alignment err(%08x)\n", __func__, da);
return NULL;
--
1.5.6.5

View File

@ -0,0 +1,24 @@
From 24f984f784cae1a4515fe1be8db1ac24cdf51e84 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
Date: Tue, 10 Feb 2009 18:37:41 +0200
Subject: [PATCH] omap iommu: We support chained scatterlists, probably. :)
Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
arch/arm/include/asm/scatterlist.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/scatterlist.h b/arch/arm/include/asm/scatterlist.h
index ca0a37d..393f8b8 100644
--- a/arch/arm/include/asm/scatterlist.h
+++ b/arch/arm/include/asm/scatterlist.h
@@ -24,4 +24,6 @@ struct scatterlist {
#define sg_dma_address(sg) ((sg)->dma_address)
#define sg_dma_len(sg) ((sg)->length)
+#define ARCH_HAS_SG_CHAIN
+
#endif /* _ASMARM_SCATTERLIST_H */
--
1.5.6.5

View File

@ -0,0 +1,29 @@
From 3c65ff4a684d3e0f4d9c59e731975408452c3743 Mon Sep 17 00:00:00 2001
From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Date: Wed, 28 Jan 2009 21:32:09 +0200
Subject: [PATCH] omap2 iommu: entries for Kconfig and Makefile
Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
---
arch/arm/mach-omap2/Makefile | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index b44bb78..33b5aa8 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -38,6 +38,11 @@ obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
mailbox_mach-objs := mailbox.o
+iommu-y += iommu2.o
+iommu-$(CONFIG_ARCH_OMAP3) += omap3-iommu.o
+
+obj-$(CONFIG_OMAP_IOMMU) += $(iommu-y)
+
# Specific board support
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o board-h4-mmc.o
--
1.5.6.5

View File

@ -0,0 +1,209 @@
From 731527a7dc26533a878c7c5f36fc148fdcaa21b8 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
Date: Tue, 10 Mar 2009 10:49:02 +0200
Subject: [PATCH] omap3isp: Add ISP MMU wrapper
TODO:
- The ISP driver should start using the IOMMU directly without this wrapper.
Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
drivers/media/video/isp/ispmmu.c | 141 ++++++++++++++++++++++++++++++++++++++
drivers/media/video/isp/ispmmu.h | 36 ++++++++++
2 files changed, 177 insertions(+), 0 deletions(-)
create mode 100644 drivers/media/video/isp/ispmmu.c
create mode 100644 drivers/media/video/isp/ispmmu.h
diff --git a/drivers/media/video/isp/ispmmu.c b/drivers/media/video/isp/ispmmu.c
new file mode 100644
index 0000000..f872c71
--- /dev/null
+++ b/drivers/media/video/isp/ispmmu.c
@@ -0,0 +1,141 @@
+/*
+ * omap iommu wrapper for TI's OMAP3430 Camera ISP
+ *
+ * Copyright (C) 2008--2009 Nokia.
+ *
+ * Contributors:
+ * Hiroshi Doyu <hiroshi.doyu@nokia.com>
+ * Sakari Ailus <sakari.ailus@nokia.com>
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/module.h>
+
+#include "ispmmu.h"
+#include "isp.h"
+
+#include <mach/iommu.h>
+#include <mach/iovmm.h>
+
+#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
+
+static struct iommu *isp_iommu;
+
+dma_addr_t ispmmu_vmalloc(size_t bytes)
+{
+ return (dma_addr_t)iommu_vmalloc(isp_iommu, 0, bytes, IOMMU_FLAG);
+}
+
+void ispmmu_vfree(const dma_addr_t da)
+{
+ iommu_vfree(isp_iommu, (u32)da);
+}
+
+dma_addr_t ispmmu_kmap(u32 pa, int size)
+{
+ void *da;
+
+ da = (void *)iommu_kmap(isp_iommu, 0, pa, size, IOMMU_FLAG);
+ if (IS_ERR(da))
+ return PTR_ERR(da);
+
+ return (dma_addr_t)da;
+}
+
+void ispmmu_kunmap(dma_addr_t da)
+{
+ iommu_kunmap(isp_iommu, (u32)da);
+}
+
+dma_addr_t ispmmu_vmap(const struct scatterlist *sglist,
+ int sglen)
+{
+ int err;
+ void *da;
+ struct sg_table *sgt;
+ unsigned int i;
+ struct scatterlist *sg, *src = (struct scatterlist *)sglist;
+
+ /*
+ * convert isp sglist to iommu sgt
+ * FIXME: should be fixed in the upper layer?
+ */
+ sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
+ if (!sgt)
+ return -ENOMEM;
+ err = sg_alloc_table(sgt, sglen, GFP_KERNEL);
+ if (err)
+ goto err_sg_alloc;
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, i)
+ sg_set_buf(sg, phys_to_virt(sg_dma_address(src + i)),
+ sg_dma_len(src + i));
+
+ da = (void *)iommu_vmap(isp_iommu, 0, sgt, IOMMU_FLAG);
+ if (IS_ERR(da))
+ goto err_vmap;
+
+ return (dma_addr_t)da;
+
+err_vmap:
+ sg_free_table(sgt);
+err_sg_alloc:
+ kfree(sgt);
+ return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(ispmmu_vmap);
+
+void ispmmu_vunmap(dma_addr_t da)
+{
+ struct sg_table *sgt;
+
+ sgt = iommu_vunmap(isp_iommu, (u32)da);
+ if (!sgt)
+ return;
+ sg_free_table(sgt);
+ kfree(sgt);
+}
+EXPORT_SYMBOL_GPL(ispmmu_vunmap);
+
+void ispmmu_save_context(void)
+{
+ if (isp_iommu)
+ iommu_save_ctx(isp_iommu);
+}
+
+void ispmmu_restore_context(void)
+{
+ if (isp_iommu)
+ iommu_restore_ctx(isp_iommu);
+}
+
+int __init ispmmu_init(void)
+{
+ int err = 0;
+
+ isp_get();
+ isp_iommu = iommu_get("isp");
+ if (IS_ERR(isp_iommu)) {
+ err = PTR_ERR(isp_iommu);
+ isp_iommu = NULL;
+ }
+ isp_put();
+
+ return err;
+}
+
+void ispmmu_cleanup(void)
+{
+ isp_get();
+ if (isp_iommu)
+ iommu_put(isp_iommu);
+ isp_put();
+ isp_iommu = NULL;
+}
diff --git a/drivers/media/video/isp/ispmmu.h b/drivers/media/video/isp/ispmmu.h
new file mode 100644
index 0000000..0bc5bcb
--- /dev/null
+++ b/drivers/media/video/isp/ispmmu.h
@@ -0,0 +1,36 @@
+/*
+ * omap iommu wrapper for TI's OMAP3430 Camera ISP
+ *
+ * Copyright (C) 2008--2009 Nokia.
+ *
+ * Contributors:
+ * Hiroshi Doyu <hiroshi.doyu@nokia.com>
+ * Sakari Ailus <sakari.ailus@nokia.com>
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef OMAP_ISP_MMU_H
+#define OMAP_ISP_MMU_H
+
+#include <linux/err.h>
+#include <linux/scatterlist.h>
+
+dma_addr_t ispmmu_vmalloc(size_t bytes);
+void ispmmu_vfree(const dma_addr_t da);
+dma_addr_t ispmmu_kmap(u32 pa, int size);
+void ispmmu_kunmap(dma_addr_t da);
+dma_addr_t ispmmu_vmap(const struct scatterlist *sglist, int sglen);
+void ispmmu_vunmap(dma_addr_t da);
+void ispmmu_save_context(void);
+void ispmmu_restore_context(void);
+int ispmmu_init(void);
+void ispmmu_cleanup(void);
+
+#endif /* OMAP_ISP_MMU_H */
--
1.5.6.5

View File

@ -0,0 +1,696 @@
From 98ca1ef8c6e2561989aeef981131cf5077eab1d1 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
Date: Tue, 10 Mar 2009 10:49:02 +0200
Subject: [PATCH] omap3isp: Add userspace header
Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
arch/arm/plat-omap/include/mach/isp_user.h | 676 ++++++++++++++++++++++++++++
1 files changed, 676 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/plat-omap/include/mach/isp_user.h
diff --git a/arch/arm/plat-omap/include/mach/isp_user.h b/arch/arm/plat-omap/include/mach/isp_user.h
new file mode 100644
index 0000000..b819e26
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/isp_user.h
@@ -0,0 +1,676 @@
+/*
+ * isp_user.h
+ *
+ * Include file for OMAP ISP module in TI's OMAP3.
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ *
+ * Contributors:
+ * Mohit Jalori <mjalori@ti.com>
+ * Sergio Aguirre <saaguirre@ti.com>
+ *
+ * This package 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 PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef OMAP_ISP_USER_H
+#define OMAP_ISP_USER_H
+
+/* ISP Private IOCTLs */
+#define VIDIOC_PRIVATE_ISP_CCDC_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct ispccdc_update_config)
+#define VIDIOC_PRIVATE_ISP_PRV_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 2, struct ispprv_update_config)
+#define VIDIOC_PRIVATE_ISP_AEWB_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct isph3a_aewb_config)
+#define VIDIOC_PRIVATE_ISP_AEWB_REQ \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct isph3a_aewb_data)
+#define VIDIOC_PRIVATE_ISP_HIST_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 6, struct isp_hist_config)
+#define VIDIOC_PRIVATE_ISP_HIST_REQ \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 7, struct isp_hist_data)
+#define VIDIOC_PRIVATE_ISP_AF_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 8, struct af_configuration)
+#define VIDIOC_PRIVATE_ISP_AF_REQ \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 9, struct isp_af_data)
+
+/* AE/AWB related structures and flags*/
+
+/* Flags for update field */
+#define REQUEST_STATISTICS (1 << 0)
+#define SET_COLOR_GAINS (1 << 1)
+#define SET_DIGITAL_GAIN (1 << 2)
+#define SET_EXPOSURE (1 << 3)
+#define SET_ANALOG_GAIN (1 << 4)
+
+#define MAX_FRAME_COUNT 0x0FFF
+#define MAX_FUTURE_FRAMES 10
+
+#define MAX_SATURATION_LIM 1023
+#define MIN_WIN_H 2
+#define MAX_WIN_H 256
+#define MIN_WIN_W 6
+#define MAX_WIN_W 256
+#define MAX_WINVC 128
+#define MAX_WINHC 36
+#define MAX_WINSTART 4095
+#define MIN_SUB_INC 2
+#define MAX_SUB_INC 32
+
+/* Range Constants */
+#define AF_IIRSH_MIN 0
+#define AF_IIRSH_MAX 4094
+#define AF_PAXEL_HORIZONTAL_COUNT_MIN 0
+#define AF_PAXEL_HORIZONTAL_COUNT_MAX 35
+#define AF_PAXEL_VERTICAL_COUNT_MIN 0
+#define AF_PAXEL_VERTICAL_COUNT_MAX 127
+#define AF_PAXEL_INCREMENT_MIN 0
+#define AF_PAXEL_INCREMENT_MAX 14
+#define AF_PAXEL_HEIGHT_MIN 0
+#define AF_PAXEL_HEIGHT_MAX 127
+#define AF_PAXEL_WIDTH_MIN 0
+#define AF_PAXEL_WIDTH_MAX 127
+#define AF_PAXEL_HZSTART_MIN 2
+#define AF_PAXEL_HZSTART_MAX 4094
+
+#define AF_PAXEL_VTSTART_MIN 0
+#define AF_PAXEL_VTSTART_MAX 4095
+#define AF_THRESHOLD_MAX 255
+#define AF_COEF_MAX 4095
+#define AF_PAXEL_SIZE 48
+
+/**
+ * struct isph3a_aewb_config - AE AWB configuration reset values.
+ * saturation_limit: Saturation limit.
+ * @win_height: Window Height. Range 2 - 256, even values only.
+ * @win_width: Window Width. Range 6 - 256, even values only.
+ * @ver_win_count: Vertical Window Count. Range 1 - 128.
+ * @hor_win_count: Horizontal Window Count. Range 1 - 36.
+ * @ver_win_start: Vertical Window Start. Range 0 - 4095.
+ * @hor_win_start: Horizontal Window Start. Range 0 - 4095.
+ * @blk_ver_win_start: Black Vertical Windows Start. Range 0 - 4095.
+ * @blk_win_height: Black Window Height. Range 2 - 256, even values only.
+ * @subsample_ver_inc: Subsample Vertical points increment Range 2 - 32, even
+ * values only.
+ * @subsample_hor_inc: Subsample Horizontal points increment Range 2 - 32, even
+ * values only.
+ * @alaw_enable: AEW ALAW EN flag.
+ * @aewb_enable: AE AWB stats generation EN flag.
+ */
+struct isph3a_aewb_config {
+ __u16 saturation_limit;
+ __u16 win_height;
+ __u16 win_width;
+ __u16 ver_win_count;
+ __u16 hor_win_count;
+ __u16 ver_win_start;
+ __u16 hor_win_start;
+ __u16 blk_ver_win_start;
+ __u16 blk_win_height;
+ __u16 subsample_ver_inc;
+ __u16 subsample_hor_inc;
+ __u8 alaw_enable;
+ __u8 aewb_enable;
+};
+
+/**
+ * struct isph3a_aewb_data - Structure of data sent to or received from user
+ * @h3a_aewb_statistics_buf: Pointer to pass to user.
+ * @shutter: Shutter speed.
+ * @gain: Sensor analog Gain.
+ * @shutter_cap: Shutter speed for capture.
+ * @gain_cap: Sensor Gain for capture.
+ * @dgain: White balance digital gain.
+ * @wb_gain_b: White balance color gain blue.
+ * @wb_gain_r: White balance color gain red.
+ * @wb_gain_gb: White balance color gain green blue.
+ * @wb_gain_gr: White balance color gain green red.
+ * @frame_number: Frame number of requested stats.
+ * @curr_frame: Current frame number being processed.
+ * @update: Bitwise flags to update parameters.
+ * @ts: Timestamp of returned framestats.
+ * @field_count: Sequence number of returned framestats.
+ */
+struct isph3a_aewb_data {
+ void *h3a_aewb_statistics_buf;
+ __u32 shutter;
+ __u16 gain;
+ __u32 shutter_cap;
+ __u16 gain_cap;
+ __u16 dgain;
+ __u16 wb_gain_b;
+ __u16 wb_gain_r;
+ __u16 wb_gain_gb;
+ __u16 wb_gain_gr;
+ __u16 frame_number;
+ __u16 curr_frame;
+ __u8 update;
+ struct timeval ts;
+ __u32 config_counter;
+ unsigned long field_count;
+};
+
+
+/* Histogram related structs */
+/* Flags for number of bins */
+#define BINS_32 0x0
+#define BINS_64 0x1
+#define BINS_128 0x2
+#define BINS_256 0x3
+
+struct isp_hist_config {
+ __u8 hist_source; /* CCDC or Memory */
+ __u8 input_bit_width; /* Needed o know the size per pixel */
+ __u8 hist_frames; /* Num of frames to be processed and
+ * accumulated
+ */
+ __u8 hist_h_v_info; /* frame-input width and height if source is
+ * memory
+ */
+ __u16 hist_radd; /* frame-input address in memory */
+ __u16 hist_radd_off; /* line-offset for frame-input */
+ __u16 hist_bins; /* number of bins: 32, 64, 128, or 256 */
+ __u16 wb_gain_R; /* White Balance Field-to-Pattern Assignments */
+ __u16 wb_gain_RG; /* White Balance Field-to-Pattern Assignments */
+ __u16 wb_gain_B; /* White Balance Field-to-Pattern Assignments */
+ __u16 wb_gain_BG; /* White Balance Field-to-Pattern Assignments */
+ __u8 num_regions; /* number of regions to be configured */
+ __u16 reg0_hor; /* Region 0 size and position */
+ __u16 reg0_ver; /* Region 0 size and position */
+ __u16 reg1_hor; /* Region 1 size and position */
+ __u16 reg1_ver; /* Region 1 size and position */
+ __u16 reg2_hor; /* Region 2 size and position */
+ __u16 reg2_ver; /* Region 2 size and position */
+ __u16 reg3_hor; /* Region 3 size and position */
+ __u16 reg3_ver; /* Region 3 size and position */
+};
+
+struct isp_hist_data {
+ __u32 *hist_statistics_buf; /* Pointer to pass to user */
+};
+
+/* Auto Focus related structs */
+
+#define AF_NUMBER_OF_COEF 11
+
+/* Flags for update field */
+#define REQUEST_STATISTICS (1 << 0)
+#define LENS_DESIRED_POSITION (1 << 1)
+#define LENS_CURRENT_POSITION (1 << 2)
+
+/**
+ * struct isp_af_xtrastats - Extra statistics related to AF generated stats.
+ * @ts: Timestamp when the frame gets delivered to the user.
+ * @field_count: Field count of the frame delivered to the user.
+ * @lens_position: Lens position when the stats are being generated.
+ */
+struct isp_af_xtrastats {
+ struct timeval ts;
+ unsigned long field_count;
+ __u16 lens_position; /* deprecated */
+};
+
+/**
+ * struct isp_af_data - AF statistics data to transfer between driver and user.
+ * @af_statistics_buf: Pointer to pass to user.
+ * @lens_current_position: Read value of lens absolute position.
+ * @desired_lens_direction: Lens desired location.
+ * @update: Bitwise flags to update parameters.
+ * @frame_number: Data for which frame is desired/given.
+ * @curr_frame: Current frame number being processed by AF module.
+ * @xtrastats: Extra statistics structure.
+ */
+struct isp_af_data {
+ void *af_statistics_buf;
+ __u16 lens_current_position; /* deprecated */
+ __u16 desired_lens_direction; /* deprecated */
+ __u16 update;
+ __u16 frame_number;
+ __u16 curr_frame;
+ __u32 config_counter;
+ struct isp_af_xtrastats xtrastats;
+};
+
+/* enum used for status of specific feature */
+enum af_alaw_enable {
+ H3A_AF_ALAW_DISABLE = 0,
+ H3A_AF_ALAW_ENABLE = 1
+};
+
+enum af_hmf_enable {
+ H3A_AF_HMF_DISABLE = 0,
+ H3A_AF_HMF_ENABLE = 1
+};
+
+enum af_config_flag {
+ H3A_AF_CFG_DISABLE = 0,
+ H3A_AF_CFG_ENABLE = 1
+};
+
+enum af_mode {
+ ACCUMULATOR_SUMMED = 0,
+ ACCUMULATOR_PEAK = 1
+};
+
+/* Red, Green, and blue pixel location in the AF windows */
+enum rgbpos {
+ GR_GB_BAYER = 0, /* GR and GB as Bayer pattern */
+ RG_GB_BAYER = 1, /* RG and GB as Bayer pattern */
+ GR_BG_BAYER = 2, /* GR and BG as Bayer pattern */
+ RG_BG_BAYER = 3, /* RG and BG as Bayer pattern */
+ GG_RB_CUSTOM = 4, /* GG and RB as custom pattern */
+ RB_GG_CUSTOM = 5 /* RB and GG as custom pattern */
+};
+
+/* Contains the information regarding the Horizontal Median Filter */
+struct af_hmf {
+ enum af_hmf_enable enable; /* Status of Horizontal Median Filter */
+ unsigned int threshold; /* Threshhold Value for Horizontal Median
+ * Filter
+ */
+};
+
+/* Contains the information regarding the IIR Filters */
+struct af_iir {
+ unsigned int hz_start_pos; /* IIR Start Register Value */
+ int coeff_set0[AF_NUMBER_OF_COEF]; /*
+ * IIR Filter Coefficient for
+ * Set 0
+ */
+ int coeff_set1[AF_NUMBER_OF_COEF]; /*
+ * IIR Filter Coefficient for
+ * Set 1
+ */
+};
+
+/* Contains the information regarding the Paxels Structure in AF Engine */
+struct af_paxel {
+ unsigned int width; /* Width of the Paxel */
+ unsigned int height; /* Height of the Paxel */
+ unsigned int hz_start; /* Horizontal Start Position */
+ unsigned int vt_start; /* Vertical Start Position */
+ unsigned int hz_cnt; /* Horizontal Count */
+ unsigned int vt_cnt; /* vertical Count */
+ unsigned int line_incr; /* Line Increment */
+};
+/* Contains the parameters required for hardware set up of AF Engine */
+struct af_configuration {
+ enum af_alaw_enable alaw_enable; /*ALWAW status */
+ struct af_hmf hmf_config; /*HMF configurations */
+ enum rgbpos rgb_pos; /*RGB Positions */
+ struct af_iir iir_config; /*IIR filter configurations */
+ struct af_paxel paxel_config; /*Paxel parameters */
+ enum af_mode mode; /*Accumulator mode */
+ enum af_config_flag af_config; /*Flag indicates Engine is configured */
+};
+
+/* ISP CCDC structs */
+
+/* Abstraction layer CCDC configurations */
+#define ISP_ABS_CCDC_ALAW (1 << 0)
+#define ISP_ABS_CCDC_LPF (1 << 1)
+#define ISP_ABS_CCDC_BLCLAMP (1 << 2)
+#define ISP_ABS_CCDC_BCOMP (1 << 3)
+#define ISP_ABS_CCDC_FPC (1 << 4)
+#define ISP_ABS_CCDC_CULL (1 << 5)
+#define ISP_ABS_CCDC_COLPTN (1 << 6)
+#define ISP_ABS_CCDC_CONFIG_LSC (1 << 7)
+#define ISP_ABS_TBL_LSC (1 << 8)
+
+#define RGB_MAX 3
+
+/* Enumeration constants for Alaw input width */
+enum alaw_ipwidth {
+ ALAW_BIT12_3 = 0x3,
+ ALAW_BIT11_2 = 0x4,
+ ALAW_BIT10_1 = 0x5,
+ ALAW_BIT9_0 = 0x6
+};
+
+/* Enumeration constants for Video Port */
+enum vpin {
+ BIT12_3 = 3,
+ BIT11_2 = 4,
+ BIT10_1 = 5,
+ BIT9_0 = 6
+};
+
+enum vpif_freq {
+ PIXCLKBY2,
+ PIXCLKBY3_5,
+ PIXCLKBY4_5,
+ PIXCLKBY5_5,
+ PIXCLKBY6_5
+};
+
+/**
+ * struct ispccdc_lsc_config - Structure for LSC configuration.
+ * @offset: Table Offset of the gain table.
+ * @gain_mode_n: Vertical dimension of a paxel in LSC configuration.
+ * @gain_mode_m: Horizontal dimension of a paxel in LSC configuration.
+ * @gain_format: Gain table format.
+ * @fmtsph: Start pixel horizontal from start of the HS sync pulse.
+ * @fmtlnh: Number of pixels in horizontal direction to use for the data
+ * reformatter.
+ * @fmtslv: Start line from start of VS sync pulse for the data reformatter.
+ * @fmtlnv: Number of lines in vertical direction for the data reformatter.
+ * @initial_x: X position, in pixels, of the first active pixel in reference
+ * to the first active paxel. Must be an even number.
+ * @initial_y: Y position, in pixels, of the first active pixel in reference
+ * to the first active paxel. Must be an even number.
+ * @size: Size of LSC gain table. Filled when loaded from userspace.
+ */
+struct ispccdc_lsc_config {
+ __u16 offset;
+ __u8 gain_mode_n;
+ __u8 gain_mode_m;
+ __u8 gain_format;
+ __u16 fmtsph;
+ __u16 fmtlnh;
+ __u16 fmtslv;
+ __u16 fmtlnv;
+ __u8 initial_x;
+ __u8 initial_y;
+ __u32 size;
+};
+
+/**
+ * struct ispccdc_bclamp - Structure for Optical & Digital black clamp subtract
+ * @obgain: Optical black average gain.
+ * @obstpixel: Start Pixel w.r.t. HS pulse in Optical black sample.
+ * @oblines: Optical Black Sample lines.
+ * @oblen: Optical Black Sample Length.
+ * @dcsubval: Digital Black Clamp subtract value.
+ */
+struct ispccdc_bclamp {
+ __u8 obgain;
+ __u8 obstpixel;
+ __u8 oblines;
+ __u8 oblen;
+ __u16 dcsubval;
+};
+
+/**
+ * ispccdc_fpc - Structure for FPC
+ * @fpnum: Number of faulty pixels to be corrected in the frame.
+ * @fpcaddr: Memory address of the FPC Table
+ */
+struct ispccdc_fpc {
+ __u16 fpnum;
+ __u32 fpcaddr;
+};
+
+/**
+ * ispccdc_blcomp - Structure for Black Level Compensation parameters.
+ * @b_mg: B/Mg pixels. 2's complement. -128 to +127.
+ * @gb_g: Gb/G pixels. 2's complement. -128 to +127.
+ * @gr_cy: Gr/Cy pixels. 2's complement. -128 to +127.
+ * @r_ye: R/Ye pixels. 2's complement. -128 to +127.
+ */
+struct ispccdc_blcomp {
+ __u8 b_mg;
+ __u8 gb_g;
+ __u8 gr_cy;
+ __u8 r_ye;
+};
+
+/**
+ * struct ispccdc_vp - Structure for Video Port parameters
+ * @bitshift_sel: Video port input select. 3 - bits 12-3, 4 - bits 11-2,
+ * 5 - bits 10-1, 6 - bits 9-0.
+ * @freq_sel: Video port data ready frequency. 1 - 1/3.5, 2 - 1/4.5,
+ * 3 - 1/5.5, 4 - 1/6.5.
+ */
+struct ispccdc_vp {
+ enum vpin bitshift_sel;
+ enum vpif_freq freq_sel;
+};
+
+/**
+ * ispccdc_culling - Structure for Culling parameters.
+ * @v_pattern: Vertical culling pattern.
+ * @h_odd: Horizontal Culling pattern for odd lines.
+ * @h_even: Horizontal Culling pattern for even lines.
+ */
+struct ispccdc_culling {
+ __u8 v_pattern;
+ __u16 h_odd;
+ __u16 h_even;
+};
+
+/**
+ * ispccdc_update_config - Structure for CCDC configuration.
+ * @update: Specifies which CCDC registers should be updated.
+ * @flag: Specifies which CCDC functions should be enabled.
+ * @alawip: Enable/Disable A-Law compression.
+ * @bclamp: Black clamp control register.
+ * @blcomp: Black level compensation value for RGrGbB Pixels. 2's complement.
+ * @fpc: Number of faulty pixels corrected in the frame, address of FPC table.
+ * @cull: Cull control register.
+ * @colptn: Color pattern of the sensor.
+ * @lsc: Pointer to LSC gain table.
+ */
+struct ispccdc_update_config {
+ __u16 update;
+ __u16 flag;
+ enum alaw_ipwidth alawip;
+ struct ispccdc_bclamp *bclamp;
+ struct ispccdc_blcomp *blcomp;
+ struct ispccdc_fpc *fpc;
+ struct ispccdc_lsc_config *lsc_cfg;
+ struct ispccdc_culling *cull;
+ __u32 colptn;
+ __u8 *lsc;
+};
+
+/* Preview configuration */
+
+/*Abstraction layer preview configurations*/
+#define ISP_ABS_PREV_LUMAENH (1 << 0)
+#define ISP_ABS_PREV_INVALAW (1 << 1)
+#define ISP_ABS_PREV_HRZ_MED (1 << 2)
+#define ISP_ABS_PREV_CFA (1 << 3)
+#define ISP_ABS_PREV_CHROMA_SUPP (1 << 4)
+#define ISP_ABS_PREV_WB (1 << 5)
+#define ISP_ABS_PREV_BLKADJ (1 << 6)
+#define ISP_ABS_PREV_RGB2RGB (1 << 7)
+#define ISP_ABS_PREV_COLOR_CONV (1 << 8)
+#define ISP_ABS_PREV_YC_LIMIT (1 << 9)
+#define ISP_ABS_PREV_DEFECT_COR (1 << 10)
+#define ISP_ABS_PREV_GAMMABYPASS (1 << 11)
+#define ISP_ABS_TBL_NF (1 << 12)
+#define ISP_ABS_TBL_REDGAMMA (1 << 13)
+#define ISP_ABS_TBL_GREENGAMMA (1 << 14)
+#define ISP_ABS_TBL_BLUEGAMMA (1 << 15)
+
+#define ISPPRV_NF_TBL_SIZE 64
+#define ISPPRV_CFA_TBL_SIZE 576
+#define ISPPRV_GAMMA_TBL_SIZE 1024
+#define ISPPRV_YENH_TBL_SIZE 128
+
+/**
+ * struct ispprev_hmed - Structure for Horizontal Median Filter.
+ * @odddist: Distance between consecutive pixels of same color in the odd line.
+ * @evendist: Distance between consecutive pixels of same color in the even
+ * line.
+ * @thres: Horizontal median filter threshold.
+ */
+struct ispprev_hmed {
+ __u8 odddist;
+ __u8 evendist;
+ __u8 thres;
+};
+
+/*
+ * Enumeration for CFA Formats supported by preview
+ */
+enum cfa_fmt {
+ CFAFMT_BAYER, CFAFMT_SONYVGA, CFAFMT_RGBFOVEON,
+ CFAFMT_DNSPL, CFAFMT_HONEYCOMB, CFAFMT_RRGGBBFOVEON
+};
+
+/**
+ * struct ispprev_cfa - Structure for CFA Inpterpolation.
+ * @cfafmt: CFA Format Enum value supported by preview.
+ * @cfa_gradthrs_vert: CFA Gradient Threshold - Vertical.
+ * @cfa_gradthrs_horz: CFA Gradient Threshold - Horizontal.
+ * @cfa_table: Pointer to the CFA table.
+ */
+struct ispprev_cfa {
+ enum cfa_fmt cfafmt;
+ __u8 cfa_gradthrs_vert;
+ __u8 cfa_gradthrs_horz;
+ __u32 *cfa_table;
+};
+
+/**
+ * struct ispprev_csup - Structure for Chrominance Suppression.
+ * @gain: Gain.
+ * @thres: Threshold.
+ * @hypf_en: Flag to enable/disable the High Pass Filter.
+ */
+struct ispprev_csup {
+ __u8 gain;
+ __u8 thres;
+ __u8 hypf_en;
+};
+
+/**
+ * struct ispprev_wbal - Structure for White Balance.
+ * @dgain: Digital gain (U10Q8).
+ * @coef3: White balance gain - COEF 3 (U8Q5).
+ * @coef2: White balance gain - COEF 2 (U8Q5).
+ * @coef1: White balance gain - COEF 1 (U8Q5).
+ * @coef0: White balance gain - COEF 0 (U8Q5).
+ */
+struct ispprev_wbal {
+ __u16 dgain;
+ __u8 coef3;
+ __u8 coef2;
+ __u8 coef1;
+ __u8 coef0;
+};
+
+/**
+ * struct ispprev_blkadj - Structure for Black Adjustment.
+ * @red: Black level offset adjustment for Red in 2's complement format
+ * @green: Black level offset adjustment for Green in 2's complement format
+ * @blue: Black level offset adjustment for Blue in 2's complement format
+ */
+struct ispprev_blkadj {
+ /*Black level offset adjustment for Red in 2's complement format */
+ __u8 red;
+ /*Black level offset adjustment for Green in 2's complement format */
+ __u8 green;
+ /* Black level offset adjustment for Blue in 2's complement format */
+ __u8 blue;
+};
+
+/**
+ * struct ispprev_rgbtorgb - Structure for RGB to RGB Blending.
+ * @matrix: Blending values(S12Q8 format)
+ * [RR] [GR] [BR]
+ * [RG] [GG] [BG]
+ * [RB] [GB] [BB]
+ * @offset: Blending offset value for R,G,B in 2's complement integer format.
+ */
+struct ispprev_rgbtorgb {
+ __u16 matrix[3][3];
+ __u16 offset[3];
+};
+
+/**
+ * struct ispprev_csc - Structure for Color Space Conversion from RGB-YCbYCr
+ * @matrix: Color space conversion coefficients(S10Q8)
+ * [CSCRY] [CSCGY] [CSCBY]
+ * [CSCRCB] [CSCGCB] [CSCBCB]
+ * [CSCRCR] [CSCGCR] [CSCBCR]
+ * @offset: CSC offset values for Y offset, CB offset and CR offset respectively
+ */
+struct ispprev_csc {
+ __u16 matrix[RGB_MAX][RGB_MAX];
+ __s16 offset[RGB_MAX];
+};
+
+/**
+ * struct ispprev_yclimit - Structure for Y, C Value Limit.
+ * @minC: Minimum C value
+ * @maxC: Maximum C value
+ * @minY: Minimum Y value
+ * @maxY: Maximum Y value
+ */
+struct ispprev_yclimit {
+ __u8 minC;
+ __u8 maxC;
+ __u8 minY;
+ __u8 maxY;
+};
+
+/**
+ * struct ispprev_dcor - Structure for Defect correction.
+ * @couplet_mode_en: Flag to enable or disable the couplet dc Correction in NF
+ * @detect_correct: Thresholds for correction bit 0:10 detect 16:25 correct
+ */
+struct ispprev_dcor {
+ __u8 couplet_mode_en;
+ __u32 detect_correct[4];
+};
+
+/**
+ * struct ispprev_nf - Structure for Noise Filter
+ * @spread: Spread value to be used in Noise Filter
+ * @table: Pointer to the Noise Filter table
+ */
+struct ispprev_nf {
+ __u8 spread;
+ __u32 table[ISPPRV_NF_TBL_SIZE];
+};
+
+/**
+ * struct ispprv_update_config - Structure for Preview Configuration (user).
+ * @update: Specifies which ISP Preview registers should be updated.
+ * @flag: Specifies which ISP Preview functions should be enabled.
+ * @yen: Pointer to luma enhancement table.
+ * @shading_shift: 3bit value of shift used in shading compensation.
+ * @prev_hmed: Pointer to structure containing the odd and even distance.
+ * between the pixels in the image along with the filter threshold.
+ * @prev_cfa: Pointer to structure containing the CFA interpolation table, CFA.
+ * format in the image, vertical and horizontal gradient threshold.
+ * @csup: Pointer to Structure for Chrominance Suppression coefficients.
+ * @prev_wbal: Pointer to structure for White Balance.
+ * @prev_blkadj: Pointer to structure for Black Adjustment.
+ * @rgb2rgb: Pointer to structure for RGB to RGB Blending.
+ * @prev_csc: Pointer to structure for Color Space Conversion from RGB-YCbYCr.
+ * @yclimit: Pointer to structure for Y, C Value Limit.
+ * @prev_dcor: Pointer to structure for defect correction.
+ * @prev_nf: Pointer to structure for Noise Filter
+ * @red_gamma: Pointer to red gamma correction table.
+ * @green_gamma: Pointer to green gamma correction table.
+ * @blue_gamma: Pointer to blue gamma correction table.
+ */
+struct ispprv_update_config {
+ __u16 update;
+ __u16 flag;
+ void *yen;
+ __u32 shading_shift;
+ struct ispprev_hmed *prev_hmed;
+ struct ispprev_cfa *prev_cfa;
+ struct ispprev_csup *csup;
+ struct ispprev_wbal *prev_wbal;
+ struct ispprev_blkadj *prev_blkadj;
+ struct ispprev_rgbtorgb *rgb2rgb;
+ struct ispprev_csc *prev_csc;
+ struct ispprev_yclimit *yclimit;
+ struct ispprev_dcor *prev_dcor;
+ struct ispprev_nf *prev_nf;
+ __u32 *red_gamma;
+ __u32 *green_gamma;
+ __u32 *blue_gamma;
+};
+
+#endif /* OMAP_ISP_USER_H */
--
1.5.6.5

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,730 @@
From 20d79137ecaa6c7dad007d9ea1d7be5550db4839 Mon Sep 17 00:00:00 2001
From: Vaibhav Hiremath <hvaibhav@ti.com>
Date: Fri, 13 Feb 2009 15:40:25 +0530
Subject: [PATCH 2/2] Resizer bug fixes on top of 1.0.2 release
This commit contains resizer bug fixes on top of
PSP1.0.2 release -
- 4096 aligned address constraint
- workaround for extra page allocation for page aligned
size buffers
Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
---
drivers/media/video/isp/omap_resizer.c | 417 ++++++++++++++++++++++++--------
include/linux/omap_resizer.h | 3 +-
2 files changed, 321 insertions(+), 99 deletions(-)
diff --git a/drivers/media/video/isp/omap_resizer.c b/drivers/media/video/isp/omap_resizer.c
index 54bc425..8059c70 100644
--- a/drivers/media/video/isp/omap_resizer.c
+++ b/drivers/media/video/isp/omap_resizer.c
@@ -28,6 +28,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/uaccess.h>
+#include <linux/pci.h>
#include <media/v4l2-dev.h>
#include <asm/cacheflush.h>
@@ -76,6 +77,10 @@
#define MAX_COEF_COUNTER 16
#define COEFF_ADDRESS_OFFSET 0x04
+#define RSZ_DEF_REQ_EXP 0xE /* Default read operation expand
+ * for the Resizer driver; value
+ * taken from Davinci.
+ */
/* Global structure which contains information about number of channels
and protection variables */
struct device_params {
@@ -85,6 +90,7 @@ struct device_params {
struct mutex reszwrap_mutex; /* Semaphore for array */
struct videobuf_queue_ops vbq_ops; /* videobuf queue operations */
+ unsigned long extra_page_addr;
};
/* Register mapped structure which contains the every register
@@ -126,6 +132,9 @@ struct resizer_config {
u32 rsz_yehn; /* yehn(luma)register mapping
* variable.
*/
+ u32 sdr_req_exp; /* Configuration for Non
+ * real time read expand
+ */
};
struct rsz_mult {
@@ -179,6 +188,7 @@ struct channel_config {
* channel is busy or not
*/
struct mutex chanprotection_mutex;
+ int buf_address[VIDEO_MAX_FRAME];
enum config_done config_state;
u8 input_buf_index;
u8 output_buf_index;
@@ -200,8 +210,6 @@ struct rsz_fh {
struct videobuf_queue vbq;
struct device_params *device;
- dma_addr_t isp_addr_read; /* Input/Output address */
- dma_addr_t isp_addr_write; /* Input/Output address */
u32 rsz_bufsize; /* channel specific buffersize
*/
};
@@ -227,6 +235,10 @@ static int rsz_set_ratio(struct rsz_mult *multipass,
static void rsz_config_ratio(struct rsz_mult *multipass,
struct channel_config *rsz_conf_chan);
+static void inline rsz_set_exp(unsigned int exp)
+{
+ omap_writel(((exp & 0x3FF) << 10), OMAP3ISP_SBL_REG(0xF8));
+}
/**
* rsz_hardware_setup - Sets hardware configuration registers
* @rsz_conf_chan: Structure containing channel configuration
@@ -271,12 +283,15 @@ static void rsz_hardware_setup(struct channel_config *rsz_conf_chan)
+ coeffoffset));
coeffoffset = coeffoffset + COEFF_ADDRESS_OFFSET;
}
+ /* Configure the read expand register */
+ rsz_set_exp(rsz_conf_chan->register_config.sdr_req_exp);
}
/**
* rsz_start - Enables Resizer Wrapper
* @arg: Currently not used.
- * @device: Structure containing ISP resizer wrapper global information
+ * @fh: File structure containing ISP resizer information specific to
+ * channel opened.
*
* Submits a resizing task specified by the rsz_resize structure. The call can
* either be blocked until the task is completed or returned immediately based
@@ -292,12 +307,18 @@ int rsz_start(int *arg, struct rsz_fh *fh)
struct channel_config *rsz_conf_chan = fh->config;
struct rsz_mult *multipass = fh->multipass;
struct videobuf_queue *q = &fh->vbq;
+ struct videobuf_buffer *buf;
int ret;
if (rsz_conf_chan->config_state) {
dev_err(rsz_device, "State not configured \n");
goto err_einval;
}
+ if (!rsz_conf_chan->register_config.rsz_sdr_inadd ||
+ !rsz_conf_chan->register_config.rsz_sdr_outadd) {
+ dev_err(rsz_device, "address is null\n");
+ goto err_einval;
+ }
rsz_conf_chan->status = CHANNEL_BUSY;
@@ -325,33 +346,22 @@ mult:
goto mult;
}
- if (fh->isp_addr_read) {
- ispmmu_vunmap(fh->isp_addr_read);
- fh->isp_addr_read = 0;
- }
- if (fh->isp_addr_write) {
- ispmmu_vunmap(fh->isp_addr_write);
- fh->isp_addr_write = 0;
- }
-
rsz_conf_chan->status = CHANNEL_FREE;
- q->bufs[rsz_conf_chan->input_buf_index]->state = VIDEOBUF_NEEDS_INIT;
- q->bufs[rsz_conf_chan->output_buf_index]->state = VIDEOBUF_NEEDS_INIT;
rsz_conf_chan->register_config.rsz_sdr_outadd = 0;
rsz_conf_chan->register_config.rsz_sdr_inadd = 0;
- /* Unmap and free the DMA memory allocated for buffers */
- videobuf_dma_unmap(q, videobuf_to_dma(
- q->bufs[rsz_conf_chan->input_buf_index]));
- videobuf_dma_unmap(q, videobuf_to_dma(
- q->bufs[rsz_conf_chan->output_buf_index]));
- videobuf_dma_free(videobuf_to_dma(
- q->bufs[rsz_conf_chan->input_buf_index]));
- videobuf_dma_free(videobuf_to_dma(
- q->bufs[rsz_conf_chan->output_buf_index]));
-
isp_unset_callback(CBK_RESZ_DONE);
+ /* Empty the Videobuf queue which was filled during the qbuf */
+ buf = q->bufs[rsz_conf_chan->input_buf_index];
+ buf->state = VIDEOBUF_IDLE;
+ list_del(&buf->stream);
+ if (rsz_conf_chan->input_buf_index != rsz_conf_chan->output_buf_index) {
+ buf = q->bufs[rsz_conf_chan->output_buf_index];
+ buf->state = VIDEOBUF_IDLE;
+ list_del(&buf->stream);
+ }
+
return 0;
err_einval:
return -EINVAL;
@@ -359,6 +369,8 @@ err_einval:
/**
* rsz_set_multipass - Set resizer multipass
+ * @multipass: Structure containing channel configuration
+ for multipass support
* @rsz_conf_chan: Structure containing channel configuration
*
* Returns always 0
@@ -384,6 +396,8 @@ static int rsz_set_multipass(struct rsz_mult *multipass,
/**
* rsz_copy_data - Copy data
+ * @multipass: Structure containing channel configuration
+ for multipass support
* @params: Structure containing the Resizer Wrapper parameters
*
* Copy data
@@ -413,6 +427,8 @@ static void rsz_copy_data(struct rsz_mult *multipass, struct rsz_params *params)
/**
* rsz_set_params - Set parameters for resizer wrapper
+ * @multipass: Structure containing channel configuration
+ for multipass support
* @params: Structure containing the Resizer Wrapper parameters
* @rsz_conf_chan: Structure containing channel configuration
*
@@ -524,6 +540,8 @@ static int rsz_set_params(struct rsz_mult *multipass, struct rsz_params *params,
}
rsz_config_ratio(multipass, rsz_conf_chan);
+ /* Default value for read expand:Taken from Davinci */
+ rsz_conf_chan->register_config.sdr_req_exp = RSZ_DEF_REQ_EXP;
rsz_conf_chan->config_state = STATE_CONFIGURED;
@@ -534,6 +552,8 @@ err_einval:
/**
* rsz_set_ratio - Set ratio
+ * @multipass: Structure containing channel configuration
+ for multipass support
* @rsz_conf_chan: Structure containing channel configuration
*
* Returns 0 if successful, -EINVAL if invalid output size, upscaling ratio is
@@ -548,7 +568,8 @@ static int rsz_set_ratio(struct rsz_mult *multipass,
if ((multipass->out_hsize > MAX_IMAGE_WIDTH) ||
(multipass->out_vsize > MAX_IMAGE_WIDTH)) {
- dev_err(rsz_device, "Invalid output size!");
+ dev_err(rsz_device, "Invalid output size! - %d", \
+ multipass->out_hsize);
goto err_einval;
}
if (multipass->cbilin) {
@@ -758,6 +779,8 @@ err_einval:
/**
* rsz_config_ratio - Configure ratio
+ * @multipass: Structure containing channel configuration
+ for multipass support
* @rsz_conf_chan: Structure containing channel configuration
*
* Configure ratio
@@ -789,6 +812,20 @@ static void rsz_config_ratio(struct rsz_mult *multipass,
((vsize << ISPRSZ_IN_SIZE_VERT_SHIFT)
& ISPRSZ_IN_SIZE_VERT_MASK);
+ /* This is another workaround for the ISP-MMU translation fault.
+ For the parameters whose image size comes exactly to PAGE_SIZE
+ generates ISP-MMU translation fault. The root-cause is the equation
+ input width = (32*sph + (ow - 1)*hrsz + 16) >> 8 + 7
+ = (64*sph + (ow - 1)*hrsz + 32) >> 8 + 7
+ input height = (32*spv + (oh - 1)*vrsz + 16) >> 8 + 4
+ = (64*spv + (oh - 1)*vrsz + 32) >> 8 + 7
+
+ we are adjusting the input width to suit for Resizer module,
+ application should use this configuration henceforth.
+ */
+ multipass->in_hsize = hsize;
+ multipass->in_vsize = vsize;
+
for (coeffcounter = 0; coeffcounter < MAX_COEF_COUNTER;
coeffcounter++) {
if (multipass->num_htap) {
@@ -990,24 +1027,15 @@ static void rsz_calculate_crop(struct channel_config *rsz_conf_chan,
static void rsz_vbq_release(struct videobuf_queue *q,
struct videobuf_buffer *vb)
{
- int i;
struct rsz_fh *fh = q->priv_data;
+ struct videobuf_dmabuf *dma = NULL;
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- struct videobuf_dmabuf *dma = NULL;
- if (!q->bufs[i])
- continue;
- if (q->bufs[i]->memory != V4L2_MEMORY_MMAP)
- continue;
- dma = videobuf_to_dma(q->bufs[i]);
- videobuf_dma_unmap(q, dma);
- videobuf_dma_free(dma);
- }
+ dma = videobuf_to_dma(q->bufs[vb->i]);
+ videobuf_dma_unmap(q, dma);
+ videobuf_dma_free(dma);
+ ispmmu_vunmap(fh->config->buf_address[vb->i]);
+ fh->config->buf_address[vb->i] = 0;
- ispmmu_vunmap(fh->isp_addr_read);
- ispmmu_vunmap(fh->isp_addr_write);
- fh->isp_addr_read = 0;
- fh->isp_addr_write = 0;
spin_lock(&fh->vbq_lock);
vb->state = VIDEOBUF_NEEDS_INIT;
spin_unlock(&fh->vbq_lock);
@@ -1062,7 +1090,105 @@ err_einval:
spin_unlock(&fh->vbq_lock);
return -EINVAL;
}
+/*
+ * This function is work around for the videobuf_iolock API,
+ * for User memory allocated with ioremap (VM_IO flag) the API
+ * get_user_pages fails.
+ *
+ * To fulfill this requirement, we have completely ignored VM layer of
+ * Linux, and configuring the ISP MMU with physical address.
+ */
+static int omap_videobuf_dma_init_user(struct videobuf_buffer *vb,
+ unsigned long physp, unsigned long asize)
+{
+ struct videobuf_dmabuf *dma;
+ struct scatterlist *sglist;
+ unsigned long data, first, last;
+ int len, i = 0;
+
+ dma = videobuf_to_dma(vb);
+ data = vb->baddr;
+
+ first = (data & PAGE_MASK) >> PAGE_SHIFT;
+ last = ((data+asize-1) & PAGE_MASK) >> PAGE_SHIFT;
+ dma->offset = data & ~PAGE_MASK;
+ dma->nr_pages = last-first+1;
+
+ dma->direction = PCI_DMA_FROMDEVICE;
+ /*
+ * Allocate array of sglen + 1, to add entry of extra page
+ * for input buffer. Driver always uses 0th buffer as input buffer.
+ */
+ len = dma->nr_pages + (vb->i ? 0 : 1);
+ sglist = kcalloc(len, sizeof(*sglist), GFP_KERNEL);
+ if (NULL == sglist)
+ return -ENOMEM;
+
+ sglist[0].offset = 0;
+ sglist[0].length = PAGE_SIZE - dma->offset;
+ sglist[0].dma_address = (dma_addr_t)physp;
+ physp += sglist[0].length;
+ /*
+ * Iterate in a loop for the number of pages
+ */
+ for (i = 1; i < (len - (vb->i ? 0 : 1)); i++) {
+ sglist[i].offset = 0;
+ sglist[i].length = PAGE_SIZE;
+ sglist[i].dma_address = (dma_addr_t)physp;
+ physp += PAGE_SIZE;
+ }
+ if (0 == vb->i) {
+ sglist[i].offset = 0;
+ sglist[i].length = PAGE_SIZE;
+ sglist[i].dma_address =
+ (dma_addr_t)device_config->extra_page_addr;
+ }
+ dma->sglist = sglist;
+ dma->sglen = len;
+ return 0;
+
+ }
+/*
+ * This function is workaround for the issue, where ISP-MMU generated
+ * translation fault for specific params whose size is aligned to PAGE_SIZE.
+
+ * As a workaround we are padding one extra page for input buffer. This page
+ * we are allocating during init time and will not be released through-out
+ * life time of resizer driver. Please note that Resizer module only reads
+ * from this extra page.
+ */
+int omap_create_sg(struct videobuf_queue *q, struct videobuf_dmabuf *dma)
+{
+ struct scatterlist *sglist;
+ int sglen;
+ sglen = dma->sglen;
+ sglist = kcalloc(sglen + 1, sizeof(*sglist), GFP_KERNEL);
+ if (NULL == sglist)
+ return -ENOMEM;
+ /*
+ * Copy the sglist locally
+ */
+ memcpy(sglist, dma->sglist, sglen * sizeof(*sglist));
+ /*
+ * Release the old sglist, since we already copied it locally
+ */
+ videobuf_dma_unmap(q, dma);
+ /*
+ * Add extra entry to sglist to work with specific params, whose
+ * buffer address alined to PAGE_SIZE.
+ */
+ sglist[sglen].offset = 0;
+ sglist[sglen].length = PAGE_SIZE;
+ sglist[sglen].dma_address = (dma_addr_t)device_config->extra_page_addr;
+ sglen++;
+ /*
+ * Save the sglist for mapping to ISP-MMU space
+ */
+ dma->sglist = sglist;
+ dma->sglen = sglen;
+ return 0;
+}
/**
* rsz_vbq_prepare - Videobuffer is prepared and mmapped.
* @q: Structure containing the videobuffer queue file handle, and device
@@ -1079,19 +1205,24 @@ static int rsz_vbq_prepare(struct videobuf_queue *q,
{
struct rsz_fh *fh = q->priv_data;
struct channel_config *rsz_conf_chan = fh->config;
- struct rsz_mult *multipass = fh->multipass;
int err = 0;
unsigned int isp_addr, insize, outsize;
- struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
-
+ struct rsz_mult *multipass = fh->multipass;
spin_lock(&fh->vbq_lock);
if (vb->baddr) {
+ /* Check for 32 byte alignement */
+ if (vb->baddr != (vb->baddr & ~0x1F)) {
+ spin_unlock(&fh->vbq_lock);
+ dev_err(rsz_device, "Buffer address should be aligned \
+ to 32 byte\n");
+ return -EINVAL;
+ }
vb->size = fh->rsz_bufsize;
vb->bsize = fh->rsz_bufsize;
} else {
spin_unlock(&fh->vbq_lock);
dev_err(rsz_device, "No user buffer allocated\n");
- goto out;
+ return -EINVAL;
}
if (vb->i) {
vb->width = fh->params->out_hsize;
@@ -1103,55 +1234,128 @@ static int rsz_vbq_prepare(struct videobuf_queue *q,
vb->field = field;
spin_unlock(&fh->vbq_lock);
+ /*
+ * Calculate input and output sizes, will be used while mapping
+ * user pages
+ */
+ outsize = multipass->out_pitch * multipass->out_vsize;
+ insize = multipass->in_pitch * multipass->in_vsize;
if (vb->state == VIDEOBUF_NEEDS_INIT) {
- err = videobuf_iolock(q, vb, NULL);
- if (!err) {
- isp_addr = ispmmu_vmap(dma->sglist, dma->sglen);
- if (!isp_addr)
- err = -EIO;
- else {
- if (vb->i) {
- rsz_conf_chan->register_config.
- rsz_sdr_outadd
- = isp_addr;
- fh->isp_addr_write = isp_addr;
- rsz_conf_chan->output_buf_index = vb->i;
- } else {
+ struct videobuf_dmabuf *dma;
+ struct vm_area_struct *vma;
+ spin_lock(&fh->vbq_lock);
+ dma = videobuf_to_dma(vb);
+ vma = find_vma(current->mm, vb->baddr);
+ if ((vma) && (vma->vm_flags & VM_IO) && (vma->vm_pgoff)) {
+ /* This will catch ioremaped buffers to the kernel.
+ * It gives two possible scenarios -
+ * - Driver allocates buffer using either
+ * dma_alloc_coherent or get_free_pages,
+ * and maps to user space using
+ * io_remap_pfn_range/remap_pfn_range
+ * - Drivers maps memory outside from Linux using
+ * io_remap
+ */
+ unsigned long physp = 0, asize;
+ asize = vb->i ? outsize : insize;
+ if ((vb->baddr + asize) > vma->vm_end) {
+ spin_unlock(&fh->vbq_lock);
+ dev_err(rsz_device, "User Buffer Allocation:" \
+ "err=%lu[%lu]\n",\
+ (vma->vm_end - vb->baddr), asize);
+ return -ENOMEM;
+ }
+ physp = (vma->vm_pgoff << PAGE_SHIFT) +
+ (vb->baddr - vma->vm_start);
+ err = omap_videobuf_dma_init_user(vb, physp, asize);
+ spin_unlock(&fh->vbq_lock);
+ if (0 != err)
+ return err;
+ } else {
+ err = videobuf_iolock(q, vb, NULL);
+ /*
+ * In case of user pointer mode, the get_user_pages
+ * will fail if user has allocated less memory than
+ * vb->size. But it is not error from resizer driver
+ * point of view. so handled seperately
+ */
+ if ((err < 0) && (dma->nr_pages > 0))
+ err = videobuf_dma_map(q, dma);
+ if (err)
+ goto buf_release;
+ /*
+ * Add one extra page for input buffer
+ */
+ if (0 == vb->i)
+ err = omap_create_sg(q, dma);
+ if (err)
+ goto buf_release;
+ spin_unlock(&fh->vbq_lock);
+ }
+ isp_addr = ispmmu_vmap(dma->sglist, dma->sglen);
+ if (!isp_addr)
+ err = -EIO;
+ else {
+ if (vb->i) {
+ rsz_conf_chan->buf_address[vb->i] = isp_addr;
+ rsz_conf_chan->register_config.
+ rsz_sdr_outadd
+ = isp_addr;
+ rsz_conf_chan->output_buf_index = vb->i;
+ } else {
+ rsz_conf_chan->buf_address[vb->i] = isp_addr;
+ rsz_conf_chan->register_config.
+ rsz_sdr_inadd
+ = isp_addr;
+ rsz_conf_chan->input_buf_index = vb->i;
+ if (outsize < insize && rsz_conf_chan->
+ register_config.
+ rsz_sdr_outadd == 0) {
rsz_conf_chan->register_config.
- rsz_sdr_inadd
- = isp_addr;
- rsz_conf_chan->input_buf_index = vb->i;
- outsize = multipass->out_pitch *
- multipass->out_vsize;
- insize = multipass->in_pitch *
- multipass->in_vsize;
- if (outsize < insize) {
- rsz_conf_chan->register_config.
- rsz_sdr_outadd
- = isp_addr;
- rsz_conf_chan->
- output_buf_index =
- vb->i;
- }
-
- fh->isp_addr_read = isp_addr;
+ rsz_sdr_outadd
+ = isp_addr;
+ rsz_conf_chan->
+ output_buf_index =
+ vb->i;
}
}
}
- }
+ } else {
+ if(vb->i) {
+ rsz_conf_chan->register_config.
+ rsz_sdr_outadd =
+ rsz_conf_chan->buf_address[vb->i];
+ rsz_conf_chan->output_buf_index = vb->i;
+ } else {
+ rsz_conf_chan->register_config.
+ rsz_sdr_inadd =
+ rsz_conf_chan->buf_address[vb->i];
+ rsz_conf_chan->input_buf_index = vb->i;
+ if(outsize < insize && rsz_conf_chan->
+ register_config.
+ rsz_sdr_outadd == 0) {
+ rsz_conf_chan->register_config.
+ rsz_sdr_outadd
+ = rsz_conf_chan->buf_address[vb->i];
+ rsz_conf_chan->output_buf_index = vb->i;
+ }
+
+ }
+ }
if (!err) {
spin_lock(&fh->vbq_lock);
vb->state = VIDEOBUF_PREPARED;
spin_unlock(&fh->vbq_lock);
- flush_cache_user_range(NULL, vb->baddr, (vb->baddr
- + vb->bsize));
} else
rsz_vbq_release(q, vb);
-out:
+ return err;
+buf_release:
+ spin_unlock(&fh->vbq_lock);
+ rsz_vbq_release(q, vb);
return err;
}
@@ -1255,7 +1459,8 @@ err_enomem0:
**/
static int rsz_release(struct inode *inode, struct file *filp)
{
- u32 timeout = 0;
+ int i;
+ unsigned int timeout = 0;
struct rsz_fh *fh = filp->private_data;
struct channel_config *rsz_conf_chan = fh->config;
struct rsz_params *params = fh->params;
@@ -1266,17 +1471,17 @@ static int rsz_release(struct inode *inode, struct file *filp)
timeout++;
schedule();
}
- if (mutex_lock_interruptible(&device_config->reszwrap_mutex))
- return -EINTR;
- device_config->opened--;
- mutex_unlock(&device_config->reszwrap_mutex);
- /* This will Free memory allocated to the buffers,
- * and flushes the queue
- */
- videobuf_queue_cancel(q);
- fh->params = NULL;
- fh->config = NULL;
+ /* Free memory allocated to the buffers */
+ for (i = 0 ; i < VIDEO_MAX_FRAME ; i++) {
+ struct videobuf_dmabuf *dma = NULL;
+ if (!q->bufs[i])
+ continue;
+ dma = videobuf_to_dma(q->bufs[i]);
+ videobuf_dma_unmap(q, dma);
+ videobuf_dma_free(dma);
+ }
+ videobuf_mmap_free(q);
fh->rsz_bufsize = 0;
filp->private_data = NULL;
@@ -1286,7 +1491,8 @@ static int rsz_release(struct inode *inode, struct file *filp)
kfree(fh);
isp_put();
-
+ fh->params = NULL;
+ fh->config = NULL;
return 0;
}
@@ -1353,6 +1559,12 @@ static long rsz_unlocked_ioctl(struct file *file, unsigned int cmd,
chanprotection_mutex))
return -EINTR;
ret = videobuf_reqbufs(&fh->vbq, (void *)&req_buf);
+ if (ret >= 0) {
+ if (copy_to_user((struct v4l2_requestbuffers *)arg,
+ &req_buf, sizeof(struct
+ v4l2_requestbuffers)))
+ return -EFAULT;
+ }
mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
break;
}
@@ -1394,11 +1606,7 @@ static long rsz_unlocked_ioctl(struct file *file, unsigned int cmd,
sizeof(struct rsz_params))) {
return -EFAULT;
}
- if (mutex_lock_interruptible(&rsz_conf_chan->
- chanprotection_mutex))
- return -EINTR;
- ret = rsz_set_params(fh->multipass, params, rsz_conf_chan);
- mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
+ ret = rsz_set_params(fh->multipass, fh->params, rsz_conf_chan);
break;
}
case RSZ_G_PARAM:
@@ -1433,6 +1641,12 @@ static long rsz_unlocked_ioctl(struct file *file, unsigned int cmd,
rsz_calculate_crop(rsz_conf_chan, (struct rsz_cropsize *)arg);
break;
+ case RSZ_S_EXP:
+ if (mutex_lock_interruptible(&rsz_conf_chan->chanprotection_mutex))
+ return -EINTR;
+ rsz_conf_chan->register_config.sdr_req_exp = *((unsigned int *)arg);
+ mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
+ break;
default:
dev_err(rsz_device, "resizer_ioctl: Invalid Command Value");
return -EINVAL;
@@ -1535,14 +1749,18 @@ static int __init omap_rsz_init(void)
"memory\n");
return -ENOMEM;
}
-
+ device->extra_page_addr = __get_free_pages(GFP_KERNEL | GFP_DMA, 0);
+ if (!device->extra_page_addr) {
+ dev_err(rsz_device, OMAP_REZR_NAME ":Allocation failed. ");
+ kfree(device);
+ return -ENOMEM;
+ }
ret = alloc_chrdev_region(&dev, 0, 1, OMAP_REZR_NAME);
if (ret < 0) {
dev_err(rsz_device, OMAP_REZR_NAME ": intialization failed. "
"Could not allocate region "
"for character device\n");
- kfree(device);
- return -ENODEV;
+ goto fail1;
}
/* Register the driver in the kernel */
@@ -1608,6 +1826,8 @@ fail3:
cdev_del(&c_dev);
fail2:
unregister_chrdev_region(dev, 1);
+fail1:
+ free_pages((unsigned long)device->extra_page_addr, 0);
kfree(device);
return ret;
}
@@ -1623,6 +1843,7 @@ void __exit omap_rsz_exit(void)
platform_driver_unregister(&omap_resizer_driver);
cdev_del(&c_dev);
unregister_chrdev_region(dev, 1);
+ free_pages((unsigned long)device_config->extra_page_addr, 0);
kfree(device_config);
}
diff --git a/include/linux/omap_resizer.h b/include/linux/omap_resizer.h
index 5ac0c88..47b8dd8 100644
--- a/include/linux/omap_resizer.h
+++ b/include/linux/omap_resizer.h
@@ -21,7 +21,7 @@
/* ioctls definition */
#define RSZ_IOC_BASE 'R'
-#define RSZ_IOC_MAXNR 8
+#define RSZ_IOC_MAXNR 9
/*Ioctl options which are to be passed while calling the ioctl*/
#define RSZ_REQBUF _IOWR(RSZ_IOC_BASE, 1,\
@@ -33,6 +33,7 @@
#define RSZ_G_STATUS _IOWR(RSZ_IOC_BASE, 6, struct rsz_status)
#define RSZ_QUEUEBUF _IOWR(RSZ_IOC_BASE, 7, struct v4l2_buffer)
#define RSZ_GET_CROPSIZE _IOWR(RSZ_IOC_BASE, 8, struct rsz_cropsize)
+#define RSZ_S_EXP _IOWR(RSZ_IOC_BASE, 9, __s32)
#define RSZ_INTYPE_YCBCR422_16BIT 0
#define RSZ_INTYPE_PLANAR_8BIT 1
--
1.6.0.3

View File

@ -0,0 +1,44 @@
From ad422f476ce04636f911557bbfd066c516e9b472 Mon Sep 17 00:00:00 2001
From: Aguirre Rodriguez, Sergio Alberto <saaguirre@ti.com>
Date: Tue, 20 Jan 2009 16:29:26 -0600
Subject: [PATCH] V4L2: Add COLORFX user control
From 07396d67b39bf7bcc81440d3e72d253ad6c54f11 Mon Sep 17 00:00:00 2001
From: Sergio Aguirre <saaguirre@ti.com>
Date: Tue, 20 Jan 2009 15:34:43 -0600
Subject: [PATCH v2] V4L2: Add COLORFX user control
This is a common feature on many cameras. the options are:
Default colors,
B & W,
Sepia
Signed-off-by: Sergio Aguirre <saaguirre@ti.com>
---
include/linux/videodev2.h | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 5571dbe..8e4e25e 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -879,8 +879,15 @@ enum v4l2_power_line_frequency {
#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28)
#define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29)
#define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30)
+#define V4L2_CID_COLORFX (V4L2_CID_BASE+31)
+enum v4l2_colorfx {
+ V4L2_COLORFX_NONE = 0,
+ V4L2_COLORFX_BW = 1,
+ V4L2_COLORFX_SEPIA = 2,
+};
+
/* last CID + 1 */
-#define V4L2_CID_LASTP1 (V4L2_CID_BASE+31)
+#define V4L2_CID_LASTP1 (V4L2_CID_BASE+32)
/* MPEG-class control IDs defined by V4L2 */
#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
--
1.5.6.5

View File

@ -0,0 +1,50 @@
From 5b007183d51543624bc9f582966f245a64157b57 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@nokia.com>
Date: Fri, 31 Oct 2008 11:51:30 +0200
Subject: [PATCH] V4L: Int if: v4l2_int_device_try_attach_all requires mutex
Signed-off-by: Sakari Ailus <sakari.ailus@nokia.com>
---
drivers/media/video/v4l2-int-device.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/media/video/v4l2-int-device.c b/drivers/media/video/v4l2-int-device.c
index a935bae..eb8dc84 100644
--- a/drivers/media/video/v4l2-int-device.c
+++ b/drivers/media/video/v4l2-int-device.c
@@ -32,7 +32,7 @@
static DEFINE_MUTEX(mutex);
static LIST_HEAD(int_list);
-void v4l2_int_device_try_attach_all(void)
+static void __v4l2_int_device_try_attach_all(void)
{
struct v4l2_int_device *m, *s;
@@ -66,6 +66,14 @@ void v4l2_int_device_try_attach_all(void)
}
}
}
+
+void v4l2_int_device_try_attach_all(void)
+{
+ mutex_lock(&mutex);
+ __v4l2_int_device_try_attach_all();
+ mutex_unlock(&mutex);
+}
+
EXPORT_SYMBOL_GPL(v4l2_int_device_try_attach_all);
static int ioctl_sort_cmp(const void *a, const void *b)
@@ -89,7 +97,7 @@ int v4l2_int_device_register(struct v4l2_int_device *d)
&ioctl_sort_cmp, NULL);
mutex_lock(&mutex);
list_add(&d->head, &int_list);
- v4l2_int_device_try_attach_all();
+ __v4l2_int_device_try_attach_all();
mutex_unlock(&mutex);
return 0;
--
1.5.6.5

View File

@ -0,0 +1,61 @@
From cc1d76e0f50321e80f7f50e9e214de2c9a45628a Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@nokia.com>
Date: Wed, 22 Oct 2008 18:41:20 +0300
Subject: [PATCH] V4L: Int if: Dummy slave
This patch implements a dummy slave that has no functionality. Helps
managing slaves in the OMAP 3 camera driver; no need to check for NULL
pointers.
Signed-off-by: Sakari Ailus <sakari.ailus@nokia.com>
---
drivers/media/video/v4l2-int-device.c | 19 +++++++++++++++++++
include/media/v4l2-int-device.h | 2 ++
2 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/drivers/media/video/v4l2-int-device.c b/drivers/media/video/v4l2-int-device.c
index eb8dc84..483ee2e 100644
--- a/drivers/media/video/v4l2-int-device.c
+++ b/drivers/media/video/v4l2-int-device.c
@@ -67,6 +67,25 @@ static void __v4l2_int_device_try_attach_all(void)
}
}
+static struct v4l2_int_slave dummy_slave = {
+ /* Dummy pointer to avoid underflow in find_ioctl. */
+ .ioctls = (void *)sizeof(struct v4l2_int_ioctl_desc),
+ .num_ioctls = 0,
+};
+
+static struct v4l2_int_device dummy = {
+ .type = v4l2_int_type_slave,
+ .u = {
+ .slave = &dummy_slave,
+ },
+};
+
+struct v4l2_int_device *v4l2_int_device_dummy()
+{
+ return &dummy;
+}
+EXPORT_SYMBOL_GPL(v4l2_int_device_dummy);
+
void v4l2_int_device_try_attach_all(void)
{
mutex_lock(&mutex);
diff --git a/include/media/v4l2-int-device.h b/include/media/v4l2-int-device.h
index fbf5855..5d254c4 100644
--- a/include/media/v4l2-int-device.h
+++ b/include/media/v4l2-int-device.h
@@ -84,6 +84,8 @@ struct v4l2_int_device {
void *priv;
};
+struct v4l2_int_device *v4l2_int_device_dummy(void);
+
void v4l2_int_device_try_attach_all(void);
int v4l2_int_device_register(struct v4l2_int_device *d);
--
1.5.6.5

View File

@ -0,0 +1,33 @@
From e041e57cafca24cf92430cdf3cc091060a271e19 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@nokia.com>
Date: Fri, 31 Oct 2008 10:20:31 +0200
Subject: [PATCH] V4L: int device: add support for VIDIOC_QUERYMENU
Signed-off-by: Tuukka Toivonen <tuukka.o.toivonen@nokia.com>
---
include/media/v4l2-int-device.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/media/v4l2-int-device.h b/include/media/v4l2-int-device.h
index 5d254c4..81f4863 100644
--- a/include/media/v4l2-int-device.h
+++ b/include/media/v4l2-int-device.h
@@ -178,6 +178,7 @@ enum v4l2_int_ioctl_num {
vidioc_int_s_fmt_cap_num,
vidioc_int_try_fmt_cap_num,
vidioc_int_queryctrl_num,
+ vidioc_int_querymenu_num,
vidioc_int_g_ctrl_num,
vidioc_int_s_ctrl_num,
vidioc_int_cropcap_num,
@@ -282,6 +283,7 @@ V4L2_INT_WRAPPER_1(g_fmt_cap, struct v4l2_format, *);
V4L2_INT_WRAPPER_1(s_fmt_cap, struct v4l2_format, *);
V4L2_INT_WRAPPER_1(try_fmt_cap, struct v4l2_format, *);
V4L2_INT_WRAPPER_1(queryctrl, struct v4l2_queryctrl, *);
+V4L2_INT_WRAPPER_1(querymenu, struct v4l2_querymenu, *);
V4L2_INT_WRAPPER_1(g_ctrl, struct v4l2_control, *);
V4L2_INT_WRAPPER_1(s_ctrl, struct v4l2_control, *);
V4L2_INT_WRAPPER_1(cropcap, struct v4l2_cropcap, *);
--
1.5.6.5

View File

@ -0,0 +1,35 @@
From dc05ee10583dca44e0f8d4109bd1397ee3c5ffae Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@nokia.com>
Date: Thu, 2 Oct 2008 11:55:07 +0300
Subject: [PATCH] V4L: Int if: Add vidioc_int_querycap
Signed-off-by: Sakari Ailus <sakari.ailus@nokia.com>
---
include/media/v4l2-int-device.h | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/include/media/v4l2-int-device.h b/include/media/v4l2-int-device.h
index 81f4863..2830ae1 100644
--- a/include/media/v4l2-int-device.h
+++ b/include/media/v4l2-int-device.h
@@ -173,7 +173,8 @@ enum v4l2_int_ioctl_num {
* "Proper" V4L ioctls, as in struct video_device.
*
*/
- vidioc_int_enum_fmt_cap_num = 1,
+ vidioc_int_querycap_num = 1,
+ vidioc_int_enum_fmt_cap_num,
vidioc_int_g_fmt_cap_num,
vidioc_int_s_fmt_cap_num,
vidioc_int_try_fmt_cap_num,
@@ -278,6 +279,7 @@ enum v4l2_int_ioctl_num {
return desc; \
}
+V4L2_INT_WRAPPER_1(querycap, struct v4l2_capability, *);
V4L2_INT_WRAPPER_1(enum_fmt_cap, struct v4l2_fmtdesc, *);
V4L2_INT_WRAPPER_1(g_fmt_cap, struct v4l2_format, *);
V4L2_INT_WRAPPER_1(s_fmt_cap, struct v4l2_format, *);
--
1.5.6.5

View File

@ -0,0 +1,26 @@
From: Mans Rullgard <mans@mansr.com>
Date: Mon, 13 Oct 2008 19:32:16 +0000 (+0100)
Subject: ARM: Add prompt for CONFIG_ALIGNMENT_TRAP
X-Git-Url: http://git.mansr.com/?p=linux-omap;a=commitdiff_plain;h=60d60f0ca47fcf4fbb649e45aa64f5a0a4c2f2c8
ARM: Add prompt for CONFIG_ALIGNMENT_TRAP
This adds a prompt text for CONFIG_ALIGNMENT_TRAP, thus making it
visible in make *config.
Signed-off-by: Mans Rullgard <mans@mansr.com>
---
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 61314f6..18d3119 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -971,7 +971,7 @@ config LEDS_CPU
will overrule the CPU usage LED.
config ALIGNMENT_TRAP
- bool
+ bool "Enable alignment trap"
depends on CPU_CP15_MMU
default y if !ARCH_EBSA110
help

View File

@ -0,0 +1,16 @@
Index: git/drivers/mmc/core/core.c
===================================================================
--- git.orig/drivers/mmc/core/core.c
+++ git/drivers/mmc/core/core.c
@@ -284,9 +284,9 @@ void mmc_set_data_timeout(struct mmc_dat
* The limit is really 250 ms, but that is
* insufficient for some crappy cards.
*/
- limit_us = 300000;
+ limit_us = 500000;
else
- limit_us = 100000;
+ limit_us = 200000;
/*
* SDHC cards always use these fixed values.

View File

@ -0,0 +1,13 @@
--- orig/drivers/video/modedb.c.orig 2009-04-07 11:40:10.000000000 +0200
+++ git/drivers/video/modedb.c 2009-04-07 10:35:29.000000000 +0200
@@ -44,6 +44,10 @@
NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
0, FB_VMODE_NONINTERLACED
}, {
+ /* 1280x720 @ 60 Hz, 45 kHz hsync, CEA 681-E Format 4 */
+ "hd720", 60, 1280, 720, 13468, 220, 110, 20, 5, 40, 5,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
/* 800x600 @ 56 Hz, 35.15 kHz hsync */
NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
0, FB_VMODE_NONINTERLACED

View File

@ -0,0 +1,43 @@
From a9199e8ab6d6fb105aa251d6bf2192e7eafac8ee Mon Sep 17 00:00:00 2001
From: Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org>
Date: Tue, 24 Mar 2009 17:22:53 -0700
Subject: [PATCH] USB: musb: only turn off vbus in OTG hosts
Except on DaVinci, VBUS is now switched off as part of idling the
USB link (after a_wait_bcon) whenever a device is disconnected
from host. This is correct for OTG hosts, where either SRP or
an ID interrupt could turn VBUS on again.
However, for non-OTG hosts there's no way to turn VBUS on again,
so the host becomes unusable. And the procfs entry which once
allowed a manual workaround for this is now gone.
This patch adds an is_otg_enabled() check before scheduling the
switch-off timer in disconnect path, supporting a "classic host"
mode where SRP is unavailable.
[ dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org: tweak patch description ]
Signed-off-by: Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org>
Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
Signed-off-by: Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org>
---
drivers/usb/musb/musb_core.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index af77e46..338cd16 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -769,7 +769,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb,
case OTG_STATE_A_SUSPEND:
usb_hcd_resume_root_hub(musb_to_hcd(musb));
musb_root_disconnect(musb);
- if (musb->a_wait_bcon != 0)
+ if (musb->a_wait_bcon != 0 && is_otg_enabled(musb))
musb_platform_try_idle(musb, jiffies
+ msecs_to_jiffies(musb->a_wait_bcon));
break;
--
1.6.0.4

View File

@ -0,0 +1,76 @@
From 83eb44b1c84f99d9a5c67612bd94b4ed7c43f64c Mon Sep 17 00:00:00 2001
From: Felipe Balbi <felipe.balbi-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Date: Tue, 24 Mar 2009 17:22:49 -0700
Subject: [PATCH] USB: composite: avoid inconsistent lock state
Avoid the following INFO from lock debugging:
[ 369.126112] =================================
[ 369.132063] [ INFO: inconsistent lock state ]
[ 369.136457] 2.6.28-maemo1 #1
[ 369.139387] ---------------------------------
[ 369.143782] inconsistent {hardirq-on-W} -> {in-hardirq-W} usage.
[ 369.149855] swapper/0 [HC1[1]:SC0[0]:HE0:SE1] takes:
[ 369.154890] (&cdev->lock){+-..}, at: [<bf1979f0>] composite_disconnect+0x1c/0]
[ 369.163404] {hardirq-on-W} state was registered at:
[ 369.168348] [<c00788a8>] __lock_acquire+0x5d0/0x7d8
[ 369.173506] [<c0078b14>] lock_acquire+0x64/0x78
[ 369.178266] [<c0263a34>] _spin_lock+0x4c/0x80
[ 369.182905] [<bf19597c>] usb_function_deactivate+0x20/0x70 [g_nokia]
[ 369.189527] [<bf1a0a88>] 0xbf1a0a88
[ 369.193281] [<bf19f450>] 0xbf19f450
[ 369.197004] [<bf19fa3c>] 0xbf19fa3c
[ 369.200758] [<bf1a03a0>] 0xbf1a03a0
[ 369.204481] [<bf19f254>] 0xbf19f254
[ 369.208204] [<bf1a0158>] 0xbf1a0158
[ 369.211927] [<bf1a130c>] 0xbf1a130c
[ 369.215650] [<c01c21f0>] usb_gadget_register_driver+0x12c/0x28c
[ 369.221846] [<bf1a06bc>] 0xbf1a06bc
[ 369.225569] [<bf1a06e8>] 0xbf1a06e8
[ 369.229322] [<c002c2dc>] __exception_text_end+0x64/0x19c
[ 369.234877] [<c0081628>] sys_init_module+0x9c/0x194
[ 369.240004] [<c002c8e0>] ret_fast_syscall+0x0/0x2c
[ 369.245039] [<ffffffff>] 0xffffffff
[ 369.248793] irq event stamp: 218356
[ 369.252302] hardirqs last enabled at (218355): [<c003a77c>] omap3_enter_idle+8
[ 369.260420] hardirqs last disabled at (218356): [<c0264774>] __irq_svc+0x34/0x0
[ 369.267927] softirqs last enabled at (218348): [<c00585a4>] __do_softirq+0x134
[ 369.275892] softirqs last disabled at (218335): [<c005899c>] irq_exit+0x60/0xb0
[ 369.283308]
[ 369.283308] other info that might help us debug this:
[ 369.289930] no locks held by swapper/0.
Cc: David Brownell <david-b-yBeKhBN/0LDR7s880joybQ@public.gmane.org>
Signed-off-by: Felipe Balbi <felipe.balbi-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Signed-off-by: Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org>
---
drivers/usb/gadget/composite.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 5d11c29..40f1da7 100644
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -149,16 +149,17 @@ done:
int usb_function_deactivate(struct usb_function *function)
{
struct usb_composite_dev *cdev = function->config->cdev;
+ unsigned long flags;
int status = 0;
- spin_lock(&cdev->lock);
+ spin_lock_irqsave(&cdev->lock, flags);
if (cdev->deactivations == 0)
status = usb_gadget_disconnect(cdev->gadget);
if (status == 0)
cdev->deactivations++;
- spin_unlock(&cdev->lock);
+ spin_unlock_irqrestore(&cdev->lock, flags);
return status;
}
--
1.6.0.4

View File

@ -0,0 +1,218 @@
From ba7b26e69f4bb41f10be444c5fded853330f82b5 Mon Sep 17 00:00:00 2001
From: Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org>
Date: Tue, 24 Mar 2009 17:22:51 -0700
Subject: [PATCH] USB: musb: NAK timeout scheme on bulk RX endpoint
Fixes endpoint starvation issue when more than one bulk QH is
multiplexed on the reserved bulk RX endpoint, which is normal
for cases like serial and ethernet adapters.
This patch sets the NAK timeout interval for such QHs, and when
a timeout triggers the next QH will be scheduled. (This resembles
the bulk scheduling done in hardware by EHCI, OHCI, and UHCI.)
This scheme doesn't work for devices which are connected to a
high to full speed tree (transaction translator) as there is
no NAK timeout interrupt from the musb controller from such
devices.
Tested with PIO, Inventra DMA, CPPI DMA.
[ dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org: fold in start_urb() update;
clarify only for bulk RX; don't accidentally clear WZC bits ]
Signed-off-by: Ajay Kumar Gupta <ajay.gupta-l0cyMroinI0@public.gmane.org>
Cc: Felipe Balbi <felipe.balbi-xNZwKgViW5gAvxtiuMwx3w@public.gmane.org>
Signed-off-by: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
Signed-off-by: Greg Kroah-Hartman <gregkh-l3A5Bk7waGM@public.gmane.org>
---
drivers/usb/musb/musb_host.c | 112 ++++++++++++++++++++++++++++++++----------
1 files changed, 85 insertions(+), 27 deletions(-)
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 6dbbd07..bd1d5ae 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -64,11 +64,8 @@
*
* - DMA (Mentor/OMAP) ...has at least toggle update problems
*
- * - Still no traffic scheduling code to make NAKing for bulk or control
- * transfers unable to starve other requests; or to make efficient use
- * of hardware with periodic transfers. (Note that network drivers
- * commonly post bulk reads that stay pending for a long time; these
- * would make very visible trouble.)
+ * - [23-feb-2009] minimal traffic scheduling to avoid bulk RX packet
+ * starvation ... nothing yet for TX, interrupt, or bulk.
*
* - Not tested with HNP, but some SRP paths seem to behave.
*
@@ -88,11 +85,8 @@
*
* CONTROL transfers all go through ep0. BULK ones go through dedicated IN
* and OUT endpoints ... hardware is dedicated for those "async" queue(s).
- *
* (Yes, bulk _could_ use more of the endpoints than that, and would even
- * benefit from it ... one remote device may easily be NAKing while others
- * need to perform transfers in that same direction. The same thing could
- * be done in software though, assuming dma cooperates.)
+ * benefit from it.)
*
* INTERUPPT and ISOCHRONOUS transfers are scheduled to the other endpoints.
* So far that scheduling is both dumb and optimistic: the endpoint will be
@@ -201,8 +195,9 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh)
len = urb->iso_frame_desc[0].length;
break;
default: /* bulk, interrupt */
- buf = urb->transfer_buffer;
- len = urb->transfer_buffer_length;
+ /* actual_length may be nonzero on retry paths */
+ buf = urb->transfer_buffer + urb->actual_length;
+ len = urb->transfer_buffer_length - urb->actual_length;
}
DBG(4, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n",
@@ -1045,7 +1040,8 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb)
/* NOTE: this code path would be a good place to PAUSE a
* control transfer, if another one is queued, so that
- * ep0 is more likely to stay busy.
+ * ep0 is more likely to stay busy. That's already done
+ * for bulk RX transfers.
*
* if (qh->ring.next != &musb->control), then
* we have a candidate... NAKing is *NOT* an error
@@ -1197,6 +1193,7 @@ void musb_host_tx(struct musb *musb, u8 epnum)
/* NOTE: this code path would be a good place to PAUSE a
* transfer, if there's some other (nonperiodic) tx urb
* that could use this fifo. (dma complicates it...)
+ * That's already done for bulk RX transfers.
*
* if (bulk && qh->ring.next != &musb->out_bulk), then
* we have a candidate... NAKing is *NOT* an error
@@ -1358,6 +1355,50 @@ finish:
#endif
+/* Schedule next QH from musb->in_bulk and move the current qh to
+ * the end; avoids starvation for other endpoints.
+ */
+static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep)
+{
+ struct dma_channel *dma;
+ struct urb *urb;
+ void __iomem *mbase = musb->mregs;
+ void __iomem *epio = ep->regs;
+ struct musb_qh *cur_qh, *next_qh;
+ u16 rx_csr;
+
+ musb_ep_select(mbase, ep->epnum);
+ dma = is_dma_capable() ? ep->rx_channel : NULL;
+
+ /* clear nak timeout bit */
+ rx_csr = musb_readw(epio, MUSB_RXCSR);
+ rx_csr |= MUSB_RXCSR_H_WZC_BITS;
+ rx_csr &= ~MUSB_RXCSR_DATAERROR;
+ musb_writew(epio, MUSB_RXCSR, rx_csr);
+
+ cur_qh = first_qh(&musb->in_bulk);
+ if (cur_qh) {
+ urb = next_urb(cur_qh);
+ if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) {
+ dma->status = MUSB_DMA_STATUS_CORE_ABORT;
+ musb->dma_controller->channel_abort(dma);
+ urb->actual_length += dma->actual_len;
+ dma->actual_len = 0L;
+ }
+ musb_save_toggle(ep, 1, urb);
+
+ /* move cur_qh to end of queue */
+ list_move_tail(&cur_qh->ring, &musb->in_bulk);
+
+ /* get the next qh from musb->in_bulk */
+ next_qh = first_qh(&musb->in_bulk);
+
+ /* set rx_reinit and schedule the next qh */
+ ep->rx_reinit = 1;
+ musb_start_urb(musb, 1, next_qh);
+ }
+}
+
/*
* Service an RX interrupt for the given IN endpoint; docs cover bulk, iso,
* and high-bandwidth IN transfer cases.
@@ -1421,18 +1462,26 @@ void musb_host_rx(struct musb *musb, u8 epnum)
} else if (rx_csr & MUSB_RXCSR_DATAERROR) {
if (USB_ENDPOINT_XFER_ISOC != qh->type) {
- /* NOTE this code path would be a good place to PAUSE a
- * transfer, if there's some other (nonperiodic) rx urb
- * that could use this fifo. (dma complicates it...)
+ DBG(6, "RX end %d NAK timeout\n", epnum);
+
+ /* NOTE: NAKing is *NOT* an error, so we want to
+ * continue. Except ... if there's a request for
+ * another QH, use that instead of starving it.
*
- * if (bulk && qh->ring.next != &musb->in_bulk), then
- * we have a candidate... NAKing is *NOT* an error
+ * Devices like Ethernet and serial adapters keep
+ * reads posted at all times, which will starve
+ * other devices without this logic.
*/
- DBG(6, "RX end %d NAK timeout\n", epnum);
+ if (usb_pipebulk(urb->pipe)
+ && qh->mux == 1
+ && !list_is_singular(&musb->in_bulk)) {
+ musb_bulk_rx_nak_timeout(musb, hw_ep);
+ return;
+ }
musb_ep_select(mbase, epnum);
- musb_writew(epio, MUSB_RXCSR,
- MUSB_RXCSR_H_WZC_BITS
- | MUSB_RXCSR_H_REQPKT);
+ rx_csr |= MUSB_RXCSR_H_WZC_BITS;
+ rx_csr &= ~MUSB_RXCSR_DATAERROR;
+ musb_writew(epio, MUSB_RXCSR, rx_csr);
goto finish;
} else {
@@ -1756,6 +1805,17 @@ static int musb_schedule(
head = &musb->in_bulk;
else
head = &musb->out_bulk;
+
+ /* Enable bulk RX NAK timeout scheme when bulk requests are
+ * multiplexed. This scheme doen't work in high speed to full
+ * speed scenario as NAK interrupts are not coming from a
+ * full speed device connected to a high speed device.
+ * NAK timeout interval is 8 (128 uframe or 16ms) for HS and
+ * 4 (8 frame or 8ms) for FS device.
+ */
+ if (is_in && qh->dev)
+ qh->intv_reg =
+ (USB_SPEED_HIGH == qh->dev->speed) ? 8 : 4;
goto success;
} else if (best_end < 0) {
return -ENOSPC;
@@ -1888,13 +1948,11 @@ static int musb_urb_enqueue(
*
* The downside of disabling this is that transfer scheduling
* gets VERY unfair for nonperiodic transfers; a misbehaving
- * peripheral could make that hurt. Or for reads, one that's
- * perfectly normal: network and other drivers keep reads
- * posted at all times, having one pending for a week should
- * be perfectly safe.
+ * peripheral could make that hurt. That's perfectly normal
+ * for reads from network or serial adapters ... so we have
+ * partial NAKlimit support for bulk RX.
*
- * The upside of disabling it is avoidng transfer scheduling
- * code to put this aside for while.
+ * The upside of disabling it is simpler transfer scheduling.
*/
interval = 0;
}
--
1.6.0.4

Some files were not shown because too many files have changed in this diff Show More