aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-s3c2440/mach-gta02.c28
-rw-r--r--drivers/mfd/glamo/glamo-core.c158
-rw-r--r--drivers/mfd/glamo/glamo-fb.c15
-rw-r--r--drivers/mfd/glamo/glamo-mci.c43
-rw-r--r--drivers/video/console/fbcon.c3
-rw-r--r--drivers/video/display/jbt6k74.c8
6 files changed, 192 insertions, 63 deletions
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
index a55fd43ef6b..5fa837751e3 100644
--- a/arch/arm/mach-s3c2440/mach-gta02.c
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -1582,28 +1582,29 @@ __setup("hardware_ecc=", hardware_ecc_setup);
/* these are the guys that don't need to be children of PMU */
static struct platform_device *gta02_devices[] __initdata = {
- &gta02_pmu_dev,
+ &gta02_version_device,
&s3c_device_usb,
&s3c_device_wdt,
- &s3c_device_i2c,
- &s3c_device_iis,
+ &gta02_memconfig_device,
// &s3c_device_sdi, /* FIXME: temporary disable to avoid s3cmci bind */
&s3c_device_usbgadget,
&s3c_device_nand,
&s3c_device_ts,
&gta02_nor_flash,
+
&sc32440_fiq_device,
- &gta02_version_device,
- &gta02_memconfig_device,
&s3c24xx_pwm_device,
&gta02_pm_wlan_dev,
+
+ &s3c_device_iis,
+ &gta02_pmu_dev,
+ &s3c_device_i2c,
};
/* these guys DO need to be children of PMU */
static struct platform_device *gta02_devices_pmu_children[] = {
- &gta02_glamo_dev, /* glamo-mci power handling depends on PMU */
&gta01_pm_gps_dev,
&gta01_pm_bt_dev,
&gta02_pm_gsm_dev,
@@ -1612,6 +1613,7 @@ static struct platform_device *gta02_devices_pmu_children[] = {
&s3c_device_spi_acc,
&gta02_button_dev,
&gta02_resume_reason_device,
+ &gta02_glamo_dev, /* glamo-mci power handling depends on PMU */
};
/* this is called when pc50633 is probed, unfortunately quite late in the
@@ -1733,10 +1735,20 @@ static void __init gta02_machine_init(void)
enable_irq_wake(GTA02_IRQ_WLAN_GPIO1);
}
-void DEBUG_LED(void)
+void DEBUG_LED(int n)
{
// int *p = NULL;
- neo1973_gpb_setpin(GTA02_GPIO_AUX_LED, 1);
+ switch (n) {
+ case 0:
+ neo1973_gpb_setpin(GTA02_GPIO_PWR_LED1, 1);
+ break;
+ case 1:
+ neo1973_gpb_setpin(GTA02_GPIO_PWR_LED2, 1);
+ break;
+ default:
+ neo1973_gpb_setpin(GTA02_GPIO_AUX_LED, 1);
+ break;
+ }
// printk(KERN_ERR"die %d\n", *p);
}
EXPORT_SYMBOL_GPL(DEBUG_LED);
diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
index 2ddc0357588..c3ecb0af81a 100644
--- a/drivers/mfd/glamo/glamo-core.c
+++ b/drivers/mfd/glamo/glamo-core.c
@@ -393,26 +393,24 @@ static void glamo_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
int __glamo_engine_enable(struct glamo_core *glamo, enum glamo_engine engine)
{
- printk(KERN_ERR" __glamo_engine_enable %d\n", engine);
switch (engine) {
case GLAMO_ENGINE_LCD:
- __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_LCD,
+ __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
+ GLAMO_HOSTBUS2_MMIO_EN_LCD,
+ GLAMO_HOSTBUS2_MMIO_EN_LCD);
+ __reg_write(glamo, GLAMO_REG_CLOCK_LCD,
GLAMO_CLOCK_LCD_EN_M5CLK |
GLAMO_CLOCK_LCD_EN_DHCLK |
GLAMO_CLOCK_LCD_EN_DMCLK |
GLAMO_CLOCK_LCD_EN_DCLK |
GLAMO_CLOCK_LCD_DG_M5CLK |
- GLAMO_CLOCK_LCD_DG_DMCLK, 0xffff);
+ GLAMO_CLOCK_LCD_DG_DMCLK);
__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, 0xffff);
- __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
- GLAMO_HOSTBUS2_MMIO_EN_LCD,
- 0xffff);
break;
case GLAMO_ENGINE_MMC:
- /* enable access to MMC unit */
__reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
GLAMO_HOSTBUS2_MMIO_EN_MMC,
GLAMO_HOSTBUS2_MMIO_EN_MMC);
@@ -469,7 +467,6 @@ EXPORT_SYMBOL_GPL(glamo_engine_enable);
int __glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
{
- printk(KERN_ERR" __glamo_engine_disable %d\n", engine);
switch (engine) {
case GLAMO_ENGINE_LCD:
/* remove pixel clock to LCM */
@@ -486,23 +483,18 @@ int __glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
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,
- GLAMO_CLOCK_MMC_EN_M9CLK |
- GLAMO_CLOCK_MMC_EN_TCLK |
- GLAMO_CLOCK_MMC_DG_M9CLK |
- GLAMO_CLOCK_MMC_DG_TCLK, 0);
+// __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MMC,
+// GLAMO_CLOCK_MMC_EN_M9CLK |
+// GLAMO_CLOCK_MMC_EN_TCLK |
+// GLAMO_CLOCK_MMC_DG_M9CLK |
+// GLAMO_CLOCK_MMC_DG_TCLK, 0);
/* disable the TCLK divider clk input */
- __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1,
- GLAMO_CLOCK_GEN51_EN_DIV_TCLK, 0);
- /* kill access to MMC unit */
-// __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2),
-// GLAMO_HOSTBUS2_MMIO_EN_MMC, 0);
- break;
+// __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1,
+// GLAMO_CLOCK_GEN51_EN_DIV_TCLK, 0);
+
default:
break;
}
@@ -803,6 +795,28 @@ static struct glamo_script glamo_init_script[] = {
{ GLAMO_REG_CLOCK_MEMORY, 0x000b },
};
+static struct glamo_script glamo_resume_script[] = {
+
+ { GLAMO_REG_PLL_GEN1, 0x05db }, /* 48MHz */
+ { GLAMO_REG_PLL_GEN3, 0x0aba }, /* 90MHz */
+ { 0xfffd, 0 },
+ /*
+ * b9 of this register MUST be zero to get any interrupts on INT#
+ * the other set bits enable all the engine interrupt sources
+ */
+ { GLAMO_REG_IRQ_ENABLE, 0x01ff },
+ { GLAMO_REG_CLOCK_HOST, 0x0018 },
+ { GLAMO_REG_CLOCK_GEN5_1, 0x1801 },
+
+ { 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 },
+};
+
enum glamo_power {
GLAMO_POWER_ON,
@@ -813,8 +827,9 @@ static void glamo_power(struct glamo_core *glamo,
enum glamo_power new_state)
{
int n;
+ unsigned long flags;
- spin_lock(&glamo->lock);
+ spin_lock_irqsave(&glamo->lock, flags);
dev_dbg(&glamo->pdev->dev, "***** glamo_power -> %d\n", new_state);
@@ -849,24 +864,57 @@ static const REG_VALUE_MASK_TYPE reg_powerSuspend[] =
switch (new_state) {
case GLAMO_POWER_ON:
- /* power up PLL1 and PLL2 */
- __reg_set_bit_mask(glamo, GLAMO_REG_DFT_GEN6, 1, 1);
- __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 1 << 13, 0);
+ glamo_run_script(glamo, glamo_resume_script,
+ ARRAY_SIZE(glamo_resume_script), 0);
+#if 0
+ __reg_write(glamo, GLAMO_REG_MEM_TYPE, 0x0c74);
+ __reg_write(glamo, GLAMO_REG_MEM_GEN, 0xafaf);
- /* spin until PLL1 and PLL2 lock */
- while ((__reg_read(glamo, GLAMO_REG_PLL_GEN5) & 3) != 3)
- ;
+ /* 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 | GLAMO_CLOCK_MEM_RESET);
/* re-enable clocks to memory */
- __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MEMORY,
- GLAMO_CLOCK_MEM_EN_MOCACLK, GLAMO_CLOCK_MEM_EN_MOCACLK);
+ __reg_write(glamo, GLAMO_REG_CLOCK_MEMORY,
+ GLAMO_CLOCK_MEM_EN_MOCACLK | GLAMO_CLOCK_MEM_EN_M1CLK |
+ GLAMO_CLOCK_MEM_DG_M1CLK);
+
/* Get memory out of deep powerdown */
- __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM2,
- GLAMO_MEM_DRAM2_DEEP_PWRDOWN, 0);
- /* clear selfrefresh */
+ __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);
- __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM1, 1 << 12, 0);
+ /* power up PLL2 and PLL1 */
+ __reg_write(glamo, GLAMO_REG_PLL_GEN3, (1 << 12) | 0xaba);
+ __reg_write(glamo, GLAMO_REG_DFT_GEN6, 1);
+
+ mdelay(50);
+
+ /* spin until PLL1 and PLL2 lock */
+ while ((__reg_read(glamo, GLAMO_REG_PLL_GEN5) & 3) != 3)
+ ;
+
+ /* PLL2 out of bypass */
+ __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 1 << 12, 0);
+#endif
+ /* all dividers from PLLs */
+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1, 0x400, 0);
/* restore each engine that was up before suspend */
for (n = 0; n < __NUM_GLAMO_ENGINES; n++)
@@ -891,20 +939,47 @@ static const REG_VALUE_MASK_TYPE reg_powerSuspend[] =
for (n = 0; n < __NUM_GLAMO_ENGINES; n++)
if (glamo->engine_enabled_bitfield & (1 << n))
__glamo_engine_disable(glamo, n);
-
- __reg_set_bit_mask(glamo, GLAMO_REG_MEM_DRAM2,
- GLAMO_MEM_DRAM2_DEEP_PWRDOWN, GLAMO_MEM_DRAM2_DEEP_PWRDOWN);
+ /* 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 */
+
/* disable clocks to memory */
- __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MEMORY,
- GLAMO_CLOCK_MEM_EN_MOCACLK, 0);
- __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 1 << 13, 1 << 13);
+ __reg_write(glamo, GLAMO_REG_CLOCK_MEMORY, 0);
+
+ /* all dividers from OSCI */
+ __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1, 0x400, 0x400);
+
+ /* PLL2 into bypass */
+ __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 1 << 12, 1 << 12);
+
+ /* kill PLLS 1 then 2 */
__reg_write(glamo, GLAMO_REG_DFT_GEN5, 0x0001);
+ __reg_set_bit_mask(glamo, GLAMO_REG_PLL_GEN3, 1 << 13, 1 << 13);
break;
}
- spin_unlock(&glamo->lock);
+ spin_unlock_irqrestore(&glamo->lock, flags);
}
#if 0
@@ -1306,6 +1381,7 @@ static int glamo_resume(struct platform_device *pdev)
return 0;
}
+
#else
#define glamo_suspend NULL
#define glamo_resume NULL
diff --git a/drivers/mfd/glamo/glamo-fb.c b/drivers/mfd/glamo/glamo-fb.c
index 26a6d29ddba..7bfd539972f 100644
--- a/drivers/mfd/glamo/glamo-fb.c
+++ b/drivers/mfd/glamo/glamo-fb.c
@@ -945,8 +945,14 @@ static int glamofb_suspend(struct platform_device *pdev, pm_message_t state)
{
struct glamofb_handle *gfb = platform_get_drvdata(pdev);
- if (state.event & PM_EVENT_SLEEP)
- fb_set_suspend(gfb->fb, 1);
+ /* we need to stop anything touching our framebuffer */
+// fb_blank(gfb->fb, FB_BLANK_NORMAL);
+ fb_set_suspend(gfb->fb, 1);
+
+ /* seriously -- nobody is allowed to touch glamo memory when we
+ * are suspended or we lock on nWAIT
+ */
+// iounmap(gfb->fb->screen_base);
return 0;
}
@@ -955,7 +961,12 @@ static int glamofb_resume(struct platform_device *pdev)
{
struct glamofb_handle *gfb = platform_get_drvdata(pdev);
+ /* OK let's allow framebuffer ops again */
+// gfb->fb->screen_base = ioremap(gfb->fb_res->start,
+// RESSIZE(gfb->fb_res));
+
fb_set_suspend(gfb->fb, 0);
+// fb_blank(gfb->fb, FB_BLANK_UNBLANK);
return 0;
}
diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c
index 13175c4a240..b5d6ad10dd9 100644
--- a/drivers/mfd/glamo/glamo-mci.c
+++ b/drivers/mfd/glamo/glamo-mci.c
@@ -341,6 +341,12 @@ static void glamo_mci_irq(unsigned int irq, struct irq_desc *desc)
if (!host)
return;
+
+ if (host->suspending) { /* bad news, dangerous time */
+ dev_err(&host->pdev->dev, "****glamo_mci_irq before resumed\n");
+ return;
+ }
+
if (!host->mrq)
return;
cmd = host->mrq->cmd;
@@ -499,7 +505,7 @@ static int glamo_mci_send_command(struct glamo_mci_host *host,
/* multiblock with stop */
fire |= GLAMO_FIRE_MMC_CC_MBWS;
else
- /* multiblock NO stop-- 'RESERVED'? */
+// /* multiblock NO stop-- 'RESERVED'? */
fire |= GLAMO_FIRE_MMC_CC_MBWNS;
break;
case MMC_STOP_TRANSMISSION:
@@ -573,7 +579,14 @@ static void glamo_mci_send_request(struct mmc_host *mmc)
u16 * reg_resp = (u16 *)(host->base + GLAMO_REG_MMC_CMD_RSP1);
u16 status;
int n;
- int timeout = 100000000;
+ int timeout = 10000000;
+ int insanity_timeout = 10000000;
+
+ if (host->suspending) {
+ dev_err(&host->pdev->dev, "IGNORING glamo_mci_send_request while "
+ "suspended\n");
+ return;
+ }
host->ccnt++;
/*
@@ -620,7 +633,12 @@ static void glamo_mci_send_request(struct mmc_host *mmc)
GLAMO_STAT1_MMC_RTOUT |
GLAMO_STAT1_MMC_DTOUT |
GLAMO_STAT1_MMC_BWERR |
- GLAMO_STAT1_MMC_BRERR))));
+ GLAMO_STAT1_MMC_BRERR))) && (insanity_timeout--));
+
+ if (insanity_timeout < 0) {
+ cmd->error = -ETIMEDOUT;
+ dev_err(&host->pdev->dev, "****** insanity timeout\n");
+ }
if (status & (GLAMO_STAT1_MMC_RTOUT |
GLAMO_STAT1_MMC_DTOUT))
@@ -716,13 +734,18 @@ static void glamo_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
#if 0
static void glamo_mci_reset(struct glamo_mci_host *host)
{
+ if (host->suspending) {
+ dev_err(&host->pdev->dev, "IGNORING glamo_mci_reset while "
+ "suspended\n");
+ return;
+ }
dev_err(&host->pdev->dev, "******* glamo_mci_reset\n");
/* reset MMC controller */
writew(GLAMO_CLOCK_MMC_RESET | GLAMO_CLOCK_MMC_DG_TCLK |
GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK |
GLAMO_CLOCK_MMC_EN_M9CLK,
glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_MMC);
- msleep(1);
+ udelay(10);
/* and disable reset */
writew(GLAMO_CLOCK_MMC_DG_TCLK |
GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK |
@@ -738,6 +761,12 @@ static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
int div;
int powering = 0;
+ if (host->suspending) {
+ dev_err(&host->pdev->dev, "IGNORING glamo_mci_set_ios while "
+ "suspended\n");
+ return;
+ }
+
/* Set power */
switch(ios->power_mode) {
case MMC_POWER_ON:
@@ -1002,6 +1031,7 @@ static int glamo_mci_suspend(struct platform_device *dev, pm_message_t state)
ret = mmc_suspend_host(mmc, state);
+ host->suspending++;
/* so that when we resume, we use any modified max rate */
mmc->f_max = sd_max_clk;
@@ -1014,6 +1044,11 @@ int glamo_mci_resume(struct platform_device *dev)
struct glamo_mci_host *host = mmc_priv(mmc);
int ret;
+ sd_idleclk = 1;
+
+ glamo_engine_enable(host->pdata->pglamo, GLAMO_ENGINE_MMC);
+ glamo_mci_reset(host);
+
host->suspending--;
ret = mmc_resume_host(mmc);
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 6b666a50e3a..285acaeafe8 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -401,6 +401,9 @@ static void fb_flashcursor(struct work_struct *work)
int c;
int mode;
+ if (info->state != FBINFO_STATE_RUNNING)
+ return;
+
acquire_console_sem();
if (ops && ops->currcon != -1)
vc = vc_cons[ops->currcon].d;
diff --git a/drivers/video/display/jbt6k74.c b/drivers/video/display/jbt6k74.c
index 807d6b538f7..77f9528ff5a 100644
--- a/drivers/video/display/jbt6k74.c
+++ b/drivers/video/display/jbt6k74.c
@@ -692,14 +692,6 @@ int jbt6k74_resume(struct spi_device *spi)
struct jbt_info *jbt = dev_get_drvdata(&spi->dev);
struct jbt6k74_platform_data *jbt6k74_pdata = spi->dev.platform_data;
- /* we can get called twice with all dependencies resumed if our core
- * resume callback is last of all. Protect against doing anything twice
- */
- if (jbt->have_resumed)
- return 0;
-
- jbt->have_resumed |= 1;
-
switch (jbt->last_state) {
case JBT_STATE_QVGA_NORMAL:
jbt6k74_enter_state(jbt, JBT_STATE_QVGA_NORMAL);