aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mfd/glamo/glamo-core.c269
-rw-r--r--drivers/mfd/glamo/glamo-core.h2
-rw-r--r--drivers/mfd/glamo/glamo-regs.h6
3 files changed, 137 insertions, 140 deletions
diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
index d4b526d41fa..ee339010f07 100644
--- a/drivers/mfd/glamo/glamo-core.c
+++ b/drivers/mfd/glamo/glamo-core.c
@@ -54,6 +54,8 @@
#define RESSIZE(ressource) (((ressource)->end - (ressource)->start)+1)
+#define GLAMO_MEM_REFRESH_COUNT 0x100
+
static struct glamo_core *glamo_handle;
static inline void __reg_write(struct glamo_core *glamo,
@@ -381,9 +383,8 @@ out_unlock:
* 'engine' support
***********************************************************************/
-int glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine)
+int __glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine)
{
- spin_lock(&glamo->lock);
switch (engine) {
case GLAMO_ENGINE_LCD:
__reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_LCD,
@@ -432,27 +433,59 @@ int glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine)
default:
break;
}
- spin_unlock(&glamo->lock);
+
+ glamo->engine_enabled_bitfield |= 1 << engine;
return 0;
}
-EXPORT_SYMBOL_GPL(glamo_engine_enable);
-int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
+int glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine)
{
+ int ret;
+
spin_lock(&glamo->lock);
+
+ ret = __glamo_engine_enable(glamo, engine);
+
+ spin_unlock(&glamo->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(glamo_engine_enable);
+
+int __glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
+{
switch (engine) {
+ case GLAMO_ENGINE_LCD:
+ /* remove pixel clock to LCM */
+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_LCD,
+ GLAMO_CLOCK_LCD_EN_DCLK, 0);
+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_LCD,
+ GLAMO_CLOCK_LCD_EN_DHCLK |
+ GLAMO_CLOCK_LCD_EN_DMCLK, 0);
+ /* kill memory clock */
+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_LCD,
+ GLAMO_CLOCK_LCD_EN_M5CLK, 0);
+ /* stop dividing the clocks */
+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1,
+ GLAMO_CLOCK_GEN51_EN_DIV_DHCLK |
+ GLAMO_CLOCK_GEN51_EN_DIV_DMCLK |
+ GLAMO_CLOCK_GEN51_EN_DIV_DCLK, 0);
+ __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
+ GLAMO_HOSTBUS2_MMIO_EN_LCD, 0);
+ break;
+
case GLAMO_ENGINE_MMC:
__reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MMC, 0,
GLAMO_CLOCK_MMC_EN_M9CLK |
GLAMO_CLOCK_MMC_EN_TCLK |
GLAMO_CLOCK_MMC_DG_M9CLK |
GLAMO_CLOCK_MMC_DG_TCLK);
- __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2), 0,
- GLAMO_HOSTBUS2_MMIO_EN_MMC);
/* disable the TCLK divider clk input */
__reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1, 0,
GLAMO_CLOCK_GEN51_EN_DIV_TCLK);
+ __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2), 0,
+ GLAMO_HOSTBUS2_MMIO_EN_MMC);
/* good idea to hold the thing in reset when we power it off? */
/* writew(readw(glamo->base + GLAMO_REG_CLOCK_MMC) |
GLAMO_CLOCK_MMC_RESET, glamo->base + GLAMO_REG_CLOCK_MMC);
@@ -461,10 +494,23 @@ int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
default:
break;
}
- spin_unlock(&glamo->lock);
+
+ glamo->engine_enabled_bitfield &= ~(1 << engine);
return 0;
}
+int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
+{
+ int ret;
+
+ spin_lock(&glamo->lock);
+
+ ret = __glamo_engine_disable(glamo, engine);
+
+ spin_unlock(&glamo->lock);
+
+ return ret;
+}
EXPORT_SYMBOL_GPL(glamo_engine_disable);
struct glamo_script reset_regs[] = {
@@ -618,7 +664,7 @@ int glamo_run_script(struct glamo_core *glamo, struct glamo_script *script,
if (may_sleep)
msleep(line->val);
else
- mdelay(line->val);
+ mdelay(line->val * 4);
break;
case 0xfffd:
/* spin until PLLs lock */
@@ -717,111 +763,17 @@ static struct glamo_script glamo_init_script[] = {
{ GLAMO_REG_CLOCK_MEMORY, 0x000b },
};
-static struct glamo_script glamo_resume_script[] = {
- { GLAMO_REG_IRQ_ENABLE, 0x01ff },
- { GLAMO_REG_CLOCK_GEN6, 0x2000 },
- { GLAMO_REG_CLOCK_GEN7, 0x0001 }, /* 0101 */
- { GLAMO_REG_CLOCK_GEN8, 0x0100 },
- { GLAMO_REG_CLOCK_HOST, 0x000d },
- { 0x200, 0x0ef0 },
- { 0x202, 0x07ff },
- { 0x212, 0x0000 },
- { 0x214, 0x4000 },
- { 0x216, 0xf00e },
- { GLAMO_REG_MEM_TYPE, 0x0874 }, /* 8MB, 16 word pg wr+rd */
- { GLAMO_REG_MEM_GEN, 0xafaf }, /* 63 grants min + max */
-
- { GLAMO_REG_MEM_TIMING1, 0x0108 },
- { GLAMO_REG_MEM_TIMING2, 0x0010 }, /* Taa = 3 MCLK */
- { GLAMO_REG_MEM_TIMING3, 0x0000 },
- { GLAMO_REG_MEM_TIMING4, 0x0000 }, /* CE1# delay fall/rise */
- { GLAMO_REG_MEM_TIMING5, 0x0000 }, /* UB# LB# */
- { GLAMO_REG_MEM_TIMING6, 0x0000 }, /* OE# */
- { GLAMO_REG_MEM_TIMING7, 0x0000 }, /* WE# */
- { GLAMO_REG_MEM_TIMING8, 0x1002 }, /* MCLK delay, was 0x1000 */
- { GLAMO_REG_MEM_TIMING9, 0x6006 },
- { GLAMO_REG_MEM_TIMING10, 0x00ff },
- { GLAMO_REG_MEM_TIMING11, 0x0001 },
- { GLAMO_REG_MEM_POWER1, 0x0020 },
- { GLAMO_REG_MEM_POWER2, 0x0000 },
- { GLAMO_REG_MEM_DRAM1, 0x0000 },
- { 0xfffe, 1 },
- { GLAMO_REG_MEM_DRAM1, 0xc100 },
- { 0xfffe, 1 },
- { GLAMO_REG_MEM_DRAM1, 0xe100 },
- { GLAMO_REG_MEM_DRAM2, 0x01d6 },
- { GLAMO_REG_CLOCK_MEMORY, 0x000b },
-};
-
-#if 0 /* MM370 */
-static const struct glamo_script regs_vram_2mb = {
- { GLAMO_REG_CLOCK_MEMORY, 0x3aaa },
- { 0xfffe, 50 },
- { GLAMO_REG_CLOCK_MEMORY, 0x0aaa },
- { 0xfffe, 3 },
- { GLAMO_REG_MEM_POWER1, 0x0020 },
- { 0x033a, 0x0000 },
- { 0x033c, 0x0000 },
- { 0x033e, 0x0000 },
- { 0x0340, 0x0000 },
- { 0x0342, 0x0000 },
- { 0x0344, 0x0000 },
- { 0x0346, 0x0240 },
- { GLAMO_REG_MEM_TIMING8, 0x1016 },
- { GLAMO_REG_MEM_TIMING9, 0x6067 },
- { GLAMO_REG_MEM_TIMING10, 0x00ff },
- { GLAMO_REG_MEM_TIMING11, 0x0030 },
- { GLAMO_REG_MEM_GEN, 0x3fff },
- { GLAMO_REG_MEM_GEN, 0xafaf },
- { GLAMO_REG_MEM_TIMING1, 0x0108 },
- { GLAMO_REG_MEM_TIMING2, 0x0010 },
- { GLAMO_REG_MEM_DRAM1, 0x0a00 },
- { 0xfffe, 3 },
- { GLAMO_REG_MEM_DRAM1, 0xe200 },
- { 0xfffe, 1 },
-};
-
-static const struct glamo_script regs_vram_8mb = {
- { GLAMO_REG_CLOCK_MEMORY, 0x3aaa },
- { 0xfffe, 50 },
- { GLAMO_REG_CLOCK_MEMORY, 0x0aaa },
- { 0xfffe, 3 },
- { GLAMO_REG_MEM_POWER1, 0x0020 },
- { 0x033a, 0x45cf },
- { 0x033c, 0x4240 },
- { 0x033e, 0x53e0 },
- { 0x0340, 0x1401 },
- { 0x0342, 0x0c44 },
- { 0x0344, 0x1d0b },
- { 0x0346, 0x25ac },
- { 0x0348, 0x1953 },
- { 0xfffe, 1 },
- { GLAMO_REG_MEM_TYPE, 0x087a },
- { GLAMO_REG_MEM_DRAM2, 0x01d6 },
- { GLAMO_REG_MEM_TIMING8, 0x1060 },
- { GLAMO_REG_MEM_TIMING9, 0x6067 },
- { GLAMO_REG_MEM_TIMING10, 0x00ff },
- { GLAMO_REG_MEM_TIMING11, 0x0030 },
- { GLAMO_REG_MEM_GEN, 0x3fff },
- { GLAMO_REG_MEM_GEN, 0xafaf },
- { GLAMO_REG_MEM_TIMING1, 0x3108 },
- { GLAMO_REG_MEM_TIMING2, 0x0010 },
- { GLAMO_REG_MEM_DRAM1, 0x0a00 },
- { 0xfffe, 3 },
- { GLAMO_REG_MEM_DRAM1, 0xe200 },
- { 0xfffe, 1 },
-};
-#endif
enum glamo_power {
GLAMO_POWER_ON,
- GLAMO_POWER_STANDBY,
GLAMO_POWER_SUSPEND,
};
static void glamo_power(struct glamo_core *glamo,
enum glamo_power new_state)
{
+ int n;
+
spin_lock(&glamo->lock);
dev_dbg(&glamo->pdev->dev, "***** glamo_power -> %d\n", new_state);
@@ -836,37 +788,76 @@ static void glamo_power(struct glamo_core *glamo,
while ((__reg_read(glamo, GLAMO_REG_PLL_GEN5) & 3) != 3)
;
- /* enable memory clock and get it out of deep pwrdown */
- __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MEMORY,
- GLAMO_CLOCK_MEM_EN_MOCACLK, 0xffff);
- __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM2,
- GLAMO_MEM_DRAM2_DEEP_PWRDOWN, 0x0000);
- __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM1,
- GLAMO_MEM_DRAM1_SELF_REFRESH, 0x0000);
-
- glamo_run_script(glamo, glamo_resume_script,
- ARRAY_SIZE(glamo_resume_script), 0);
-
- break;
-
- case GLAMO_POWER_STANDBY:
- /* enable memory self-refresh */
- __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM1,
- GLAMO_MEM_DRAM1_SELF_REFRESH, 0xffff);
- /* stop memory clock */
- __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MEMORY,
- GLAMO_CLOCK_MEM_EN_MOCACLK, 0x0000);
- /* power down PLL2 and then PLL1 */
- __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 0x2000, 0xffff);
- __reg_set_bit_mask(glamo, GLAMO_REG_DFT_GEN5, 0x0001, 0xffff);
+ /* Get memory out of deep powerdown */
+
+ __reg_write(glamo, GLAMO_REG_MEM_DRAM2,
+ (7 << 6) | /* tRC */
+ (1 << 4) | /* tRP */
+ (1 << 2) | /* tRCD */
+ 2); /* CAS latency */
+
+ /* Stop self-refresh */
+
+ __reg_write(glamo, GLAMO_REG_MEM_DRAM1,
+ GLAMO_MEM_DRAM1_EN_DRAM_REFRESH |
+ GLAMO_MEM_DRAM1_EN_GATE_CKE |
+ GLAMO_MEM_REFRESH_COUNT);
+ __reg_write(glamo, GLAMO_REG_MEM_DRAM1,
+ GLAMO_MEM_DRAM1_EN_MODEREG_SET |
+ GLAMO_MEM_DRAM1_EN_DRAM_REFRESH |
+ GLAMO_MEM_DRAM1_EN_GATE_CKE |
+ GLAMO_MEM_REFRESH_COUNT);
+
+ /* re-enable clocks to memory */
+
+ __reg_write(glamo, GLAMO_REG_CLOCK_MEMORY,
+ GLAMO_CLOCK_MEM_EN_MOCACLK |
+ GLAMO_CLOCK_MEM_EN_M1CLK |
+ GLAMO_CLOCK_MEM_DG_M1CLK);
+
+ /* restore each engine that was up before suspend */
+ for (n = 0; n < __NUM_GLAMO_ENGINES; n++)
+ if (glamo->engine_enabled_bitfield_suspend & (1 << n))
+ __glamo_engine_enable(glamo, n);
break;
case GLAMO_POWER_SUSPEND:
- __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM2,
- GLAMO_MEM_DRAM2_DEEP_PWRDOWN, 0xffff);
- /* stop memory clock */
- __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MEMORY,
- GLAMO_CLOCK_MEM_EN_MOCACLK, 0x0000);
+ /* stash a copy of which engines were running */
+ glamo->engine_enabled_bitfield_suspend =
+ glamo->engine_enabled_bitfield;
+
+ /* take down each engine before we kill mem and pll */
+ for (n = 0; n < __NUM_GLAMO_ENGINES; n++)
+ if (glamo->engine_enabled_bitfield & (1 << n))
+ __glamo_engine_disable(glamo, n);
+
+ /* enable self-refresh */
+
+ __reg_write(glamo, GLAMO_REG_MEM_DRAM1,
+ GLAMO_MEM_DRAM1_EN_DRAM_REFRESH |
+ GLAMO_MEM_DRAM1_EN_GATE_CKE |
+ GLAMO_MEM_DRAM1_SELF_REFRESH |
+ GLAMO_MEM_REFRESH_COUNT);
+ __reg_write(glamo, GLAMO_REG_MEM_DRAM1,
+ GLAMO_MEM_DRAM1_EN_MODEREG_SET |
+ GLAMO_MEM_DRAM1_EN_DRAM_REFRESH |
+ GLAMO_MEM_DRAM1_EN_GATE_CKE |
+ GLAMO_MEM_DRAM1_SELF_REFRESH |
+ GLAMO_MEM_REFRESH_COUNT);
+
+ /* force RAM into deep powerdown */
+
+ __reg_write(glamo, GLAMO_REG_MEM_DRAM2,
+ GLAMO_MEM_DRAM2_DEEP_PWRDOWN |
+ (7 << 6) | /* tRC */
+ (1 << 4) | /* tRP */
+ (1 << 2) | /* tRCD */
+ 2); /* CAS latency */
+
+ /* kill clocks to memory */
+
+ __reg_write(glamo, GLAMO_REG_CLOCK_MEMORY, 0);
+
/* power down PLL2 and then PLL1 */
__reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 0x2000, 0xffff);
__reg_set_bit_mask(glamo, GLAMO_REG_DFT_GEN5, 0x0001, 0xffff);
@@ -1016,15 +1007,15 @@ static ssize_t regs_read(struct device *dev, struct device_attribute *attr,
char * name;
};
struct reg_range reg_range[] = {
-/* { 0x0000, 0x200, "General" },
- { 0x0200, 0x100, "Host Bus" },
- { 0x0300, 0x100, "Memory" },
- { 0x0400, 0x100, "Sensor" },
+ { 0x0000, 0x76, "General" },
+/* { 0x0200, 0x100, "Host Bus" },
+*/ { 0x0300, 0x38, "Memory" },
+/* { 0x0400, 0x100, "Sensor" },
{ 0x0500, 0x300, "ISP" },
{ 0x0800, 0x400, "JPEG" },
{ 0x0c00, 0x500, "MPEG" },
*/
- { 0x1100, 0x400, "LCD" },
+ { 0x1100, 0x88, "LCD" },
/*
{ 0x1500, 0x080, "MPU 0" },
{ 0x1580, 0x080, "MPU 1" },
@@ -1039,7 +1030,7 @@ static ssize_t regs_read(struct device *dev, struct device_attribute *attr,
for (r = 0; r < ARRAY_SIZE(reg_range); r++) {
n1 = 0;
- end += sprintf(end, "\n%s\n\n", reg_range[r].name);
+ end += sprintf(end, "\n%s\n", reg_range[r].name);
for (n = reg_range[r].start;
n < reg_range[r].start + reg_range[r].count; n += 2) {
if (((n1++) & 7) == 0)
diff --git a/drivers/mfd/glamo/glamo-core.h b/drivers/mfd/glamo/glamo-core.h
index b1531b387e5..c89f8104fb1 100644
--- a/drivers/mfd/glamo/glamo-core.h
+++ b/drivers/mfd/glamo/glamo-core.h
@@ -30,6 +30,8 @@ struct glamo_core {
u_int16_t revision;
spinlock_t lock;
struct resume_dependency resume_dependency;
+ u32 engine_enabled_bitfield;
+ u32 engine_enabled_bitfield_suspend;
};
struct glamo_script {
diff --git a/drivers/mfd/glamo/glamo-regs.h b/drivers/mfd/glamo/glamo-regs.h
index 32411e37f86..2328b8ac989 100644
--- a/drivers/mfd/glamo/glamo-regs.h
+++ b/drivers/mfd/glamo/glamo-regs.h
@@ -142,8 +142,12 @@ enum glamo_register_mem {
#define GLAMO_MEM_TYPE_MASK 0x03
enum glamo_reg_mem_dram1 {
- GLAMO_MEM_DRAM1_EN_SDRAM_CLK = (1 << 11),
+ /* b0 - b10 == refresh period, 1 -> 2048 clocks */
+ GLAMO_MEM_DRAM1_EN_GATE_CLK = (1 << 11),
GLAMO_MEM_DRAM1_SELF_REFRESH = (1 << 12),
+ GLAMO_MEM_DRAM1_EN_GATE_CKE = (1 << 13),
+ GLAMO_MEM_DRAM1_EN_DRAM_REFRESH = (1 << 14),
+ GLAMO_MEM_DRAM1_EN_MODEREG_SET = (1 << 15),
};
enum glamo_reg_mem_dram2 {