diff options
author | Koen Kooi <koen@openembedded.org> | 2009-07-30 11:19:10 +0200 |
---|---|---|
committer | Koen Kooi <koen@openembedded.org> | 2009-07-30 11:19:10 +0200 |
commit | f2e6ca6bfa79d166ee72224bbb95ca1a71125d43 (patch) | |
tree | b2facdc46191d38b9917a7d390c44f668f19183f /recipes/linux/linux-omap-pm/dss2/0110-DSS2-isolate-the-SDI-pads-when-SDI-is-disabled.patch | |
parent | 0501fbe7b6f99eddc8ee9b0d3dab9ebac4722166 (diff) |
linux-omap-pm git: add patch for fix musb oops and dss2 patches
Diffstat (limited to 'recipes/linux/linux-omap-pm/dss2/0110-DSS2-isolate-the-SDI-pads-when-SDI-is-disabled.patch')
-rw-r--r-- | recipes/linux/linux-omap-pm/dss2/0110-DSS2-isolate-the-SDI-pads-when-SDI-is-disabled.patch | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/recipes/linux/linux-omap-pm/dss2/0110-DSS2-isolate-the-SDI-pads-when-SDI-is-disabled.patch b/recipes/linux/linux-omap-pm/dss2/0110-DSS2-isolate-the-SDI-pads-when-SDI-is-disabled.patch new file mode 100644 index 0000000000..5a45e433a0 --- /dev/null +++ b/recipes/linux/linux-omap-pm/dss2/0110-DSS2-isolate-the-SDI-pads-when-SDI-is-disabled.patch @@ -0,0 +1,209 @@ +From 964c2a99d0b9db59bc716022c7f9f6da580f44d6 Mon Sep 17 00:00:00 2001 +From: Tomi Valkeinen <tomi.valkeinen@nokia.com> +Date: Fri, 12 Jun 2009 11:17:15 +0300 +Subject: [PATCH 110/146] DSS2: isolate the SDI pads when SDI is disabled + +When SDI is disabled there is still ~1.6mA drain through the VSDI_CSI +regulator. This seems to be internal to the SDI module, since even +disconnecting the LCD panel doesn't get rid of the drain. Also +disabling/resetting the SDI or the DSS module doesn't help. The only +solution is to configure the SDI pads to safe mode with pull up +resistors enabled on them when SDI gets disabled. + +Bootloader / platform code is still responsible for setting up the +muxing, so in the driver check if all required pads are in SDI mode +or all of them are in non-configured state. + +Signed-off-by: Imre Deak <imre.deak@nokia.com> + +Conflicts: + + arch/arm/plat-omap/include/mach/display.h +--- + arch/arm/plat-omap/include/mach/display.h | 2 + + drivers/video/omap2/dss/sdi.c | 110 ++++++++++++++++++++++++++++- + 2 files changed, 111 insertions(+), 1 deletions(-) + +diff --git a/arch/arm/plat-omap/include/mach/display.h b/arch/arm/plat-omap/include/mach/display.h +index 3d8ed69..0695497 100644 +--- a/arch/arm/plat-omap/include/mach/display.h ++++ b/arch/arm/plat-omap/include/mach/display.h +@@ -344,6 +344,8 @@ struct omap_dss_device { + + struct { + u8 datapairs; ++ unsigned pad_off_pe : 1; /* pull pads if disabled */ ++ unsigned pad_off_pu : 1; /* pull up */ + } sdi; + + struct { +diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c +index 86b9a56..c484e0c 100644 +--- a/drivers/video/omap2/dss/sdi.c ++++ b/drivers/video/omap2/dss/sdi.c +@@ -23,17 +23,120 @@ + #include <linux/clk.h> + #include <linux/delay.h> + #include <linux/err.h> ++#include <linux/io.h> + + #include <mach/board.h> + #include <mach/display.h> + #include "dss.h" + ++#define CONTROL_PADCONF_BASE 0x48002000 ++ ++#define OMAP_SDI_PAD_DIS(pe,pu) ((7 << 0) | /* MODE 7 = safe */ \ ++ (((pe) ? 1 : 0) << 3) | /* PULL_ENA */ \ ++ (((pu) ? 1 : 0) << 4) | /* PULL_UP */ \ ++ (1 << 8)) /* INPUT_EN */ ++ ++#define OMAP_SDI_PAD_EN (1 << 0) /* MODE 1 = SDI_xx */ ++ ++#define OMAP_SDI_PAD_MASK OMAP_SDI_PAD_DIS(1, 1) + + static struct { + bool skip_init; + bool update_enabled; + } sdi; + ++/* CONTROL_PADCONF_DSS_DATAXX */ ++const u16 sdi_pads[] = ++{ ++ 0x0f0, /* 10[ 7..0]:SDI_DAT1N */ ++ 0x0f2, /* 10[15..0]:SDI_DAT1P */ ++ 0x0f4, /* 12[ 7..0]:SDI_DAT2N */ ++ 0x0f6, /* 12[15..0]:SDI_DAT2P */ ++ 0x0f8, /* 14[ 7..0]:SDI_DAT3N */ ++ 0x0fa, /* 14[15..0]:SDI_DAT3P */ ++ 0x108, /* 22[ 7..0]:SDI_CLKN */ ++ 0x10a, /* 22[15..0]:SDI_CLKP */ ++}; ++ ++/* ++ * Check if bootloader / platform code has configured the SDI pads properly. ++ * This means it either configured all required pads for SDI mode, or that it ++ * left all the required pads unconfigured. ++ */ ++static int sdi_pad_init(struct omap_dss_device *dssdev) ++{ ++ unsigned req_map; ++ bool configured = false; ++ bool unconfigured = false; ++ int data_pairs; ++ int i; ++ ++ data_pairs = dssdev->phy.sdi.datapairs; ++ req_map = (1 << (data_pairs * 2)) - 1; /* data lanes */ ++ req_map |= 3 << 6; /* clk lane */ ++ for (i = 0; i < ARRAY_SIZE(sdi_pads); i++) { ++ u32 reg; ++ u32 val; ++ ++ if (!((1 << i) & req_map)) ++ /* Ignore unneded pads. */ ++ continue; ++ reg = CONTROL_PADCONF_BASE + sdi_pads[i]; ++ val = omap_readw(reg); ++ switch (val & 0x07) { /* pad mode */ ++ case 1: ++ if (unconfigured) ++ break; ++ /* Is the pull configuration ok for SDI mode? */ ++ if ((val & OMAP_SDI_PAD_MASK) != OMAP_SDI_PAD_EN) ++ break; ++ configured = true; ++ break; ++ case 0: ++ case 7: ++ if (configured) ++ break; ++ unconfigured = true; ++ break; ++ default: ++ break; ++ } ++ } ++ if (i != ARRAY_SIZE(sdi_pads)) { ++ DSSERR("SDI: invalid pad configuration\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static void sdi_pad_config(struct omap_dss_device *dssdev, bool enable) ++{ ++ int data_pairs; ++ bool pad_off_pe, pad_off_pu; ++ unsigned req_map; ++ int i; ++ ++ data_pairs = dssdev->phy.sdi.datapairs; ++ pad_off_pe = dssdev->phy.sdi.pad_off_pe; ++ pad_off_pu = dssdev->phy.sdi.pad_off_pu; ++ req_map = (1 << (data_pairs * 2)) - 1; /* data lanes */ ++ req_map |= 3 << 6; /* clk lane */ ++ for (i = 0; i < ARRAY_SIZE(sdi_pads); i++) { ++ u32 reg; ++ u16 val; ++ ++ if (!((1 << i) & req_map)) ++ continue; ++ if (enable) ++ val = OMAP_SDI_PAD_EN; ++ else ++ val = OMAP_SDI_PAD_DIS(pad_off_pe, pad_off_pu); ++ reg = CONTROL_PADCONF_BASE + sdi_pads[i]; ++ omap_writew(val, reg); ++ } ++} ++ + static void sdi_basic_init(void) + { + dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_BYPASS); +@@ -64,6 +167,8 @@ static int sdi_display_enable(struct omap_dss_device *dssdev) + goto err1; + } + ++ sdi_pad_config(dssdev, 1); ++ + /* In case of skip_init sdi_init has already enabled the clocks */ + if (!sdi.skip_init) + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); +@@ -153,6 +258,7 @@ static void sdi_display_disable(struct omap_dss_device *dssdev) + dss_sdi_disable(); + + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); ++ sdi_pad_config(dssdev, 0); + + dssdev->state = OMAP_DSS_DISPLAY_DISABLED; + +@@ -172,6 +278,7 @@ static int sdi_display_suspend(struct omap_dss_device *dssdev) + dss_sdi_disable(); + + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1); ++ sdi_pad_config(dssdev, 0); + + dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED; + +@@ -183,6 +290,7 @@ static int sdi_display_resume(struct omap_dss_device *dssdev) + if (dssdev->state != OMAP_DSS_DISPLAY_SUSPENDED) + return -EINVAL; + ++ sdi_pad_config(dssdev, 1); + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1); + + dss_sdi_enable(); +@@ -240,7 +348,7 @@ int sdi_init_display(struct omap_dss_device *dssdev) + dssdev->get_update_mode = sdi_display_get_update_mode; + dssdev->get_timings = sdi_get_timings; + +- return 0; ++ return sdi_pad_init(dssdev); + } + + int sdi_init(bool skip_init) +-- +1.6.2.4 + |