diff options
-rw-r--r-- | arch/arm/mach-s3c2440/mach-gta02.c | 28 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-core.c | 158 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-fb.c | 15 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-mci.c | 43 | ||||
-rw-r--r-- | drivers/video/console/fbcon.c | 3 | ||||
-rw-r--r-- | drivers/video/display/jbt6k74.c | 8 |
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 = { - >a02_pmu_dev, + >a02_version_device, &s3c_device_usb, &s3c_device_wdt, - &s3c_device_i2c, - &s3c_device_iis, + >a02_memconfig_device, // &s3c_device_sdi, /* FIXME: temporary disable to avoid s3cmci bind */ &s3c_device_usbgadget, &s3c_device_nand, &s3c_device_ts, >a02_nor_flash, + &sc32440_fiq_device, - >a02_version_device, - >a02_memconfig_device, &s3c24xx_pwm_device, >a02_pm_wlan_dev, + + &s3c_device_iis, + >a02_pmu_dev, + &s3c_device_i2c, }; /* these guys DO need to be children of PMU */ static struct platform_device *gta02_devices_pmu_children[] = { - >a02_glamo_dev, /* glamo-mci power handling depends on PMU */ >a01_pm_gps_dev, >a01_pm_bt_dev, >a02_pm_gsm_dev, @@ -1612,6 +1613,7 @@ static struct platform_device *gta02_devices_pmu_children[] = { &s3c_device_spi_acc, >a02_button_dev, >a02_resume_reason_device, + >a02_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); |