s5pc110: aquila: Register based sleep & PMIC LDO command support
authorKyungmin Park <kyungmin.park@samsung.com>
Thu, 8 Oct 2009 02:20:31 +0000 (11:20 +0900)
committerKyungmin Park <kyungmin.park@samsung.com>
Thu, 8 Oct 2009 02:20:31 +0000 (11:20 +0900)
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
board/samsung/universal/universal.c
cpu/arm_cortexa8/s5pc1xx/sleep.c
include/asm-arm/arch-s5pc1xx/power.h

index cbd72c4..254b4af 100644 (file)
@@ -982,15 +982,21 @@ void board_sleep_init(void)
        i2c_read(addr, 0x11, 1, val, 1);
        val[0] &= ~((1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0));
        i2c_write(addr, 0x11, 1, val, 1);
+       i2c_read(addr, 0x11, 1, val, 1);
+       printf("ONOFF1 0x%02x\n", val[0]);
        /* Set ONOFF2 */
        i2c_read(addr, 0x12, 1, val, 1);
-       val[0] &= ~((1 << 6) | (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
+       val[0] &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
        i2c_write(addr, 0x12, 1, val, 1);
+       i2c_read(addr, 0x12, 1, val, 1);
+       printf("ONOFF2 0x%02x\n", val[0]);
        /* Set ONOFF3 */
        i2c_read(addr, 0x13, 1, val, 1);
        val[0] &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4));
        val[0] = 0x0;
        i2c_write(addr, 0x13, 1, val, 1);
+       i2c_read(addr, 0x13, 1, val, 1);
+       printf("ONOFF3 0x%02x\n", val[0]);
 
        printf("%s[%d]\n", __func__, __LINE__);
 }
@@ -1077,3 +1083,127 @@ int board_mmc_init(bd_t *bis)
        return s5pc1xx_mmc_init(0);
 }
 #endif
+
+static int pmic_status(void)
+{
+       unsigned char addr, val[2];
+       int reg, i;
+
+       i2c_gpio_set_bus(I2C_PMIC);
+       addr = 0xCC >> 1;
+       if (i2c_probe(addr)) {
+               printf("Can't found max8998\n");
+               return -1;
+       }
+
+       reg = 0x11;
+       i2c_read(addr, reg, 1, val, 1);
+       for (i = 7; i >= 4; i--)
+               printf("BUCK%d %s\n", 7 - i + 1, val[0] & (1 << i) ? "on" : "off");
+       for (; i >= 0; i--)
+               printf("LDO%d %s\n", 5 - i, val[0] & (1 << i) ? "on" : "off");
+       reg = 0x12;
+       i2c_read(addr, reg, 1, val, 1);
+       for (i = 7; i >= 0; i--)
+               printf("LDO%d %s\n", 7 - i + 6, val[0] & (1 << i) ? "on" : "off");
+       reg = 0x13;
+       i2c_read(addr, reg, 1, val, 1);
+       for (i = 7; i >= 4; i--)
+               printf("LDO%d %s\n", 7 - i + 14, val[0] & (1 << i) ? "on" : "off");
+       return 0;
+}
+
+static int pmic_ldo_control(int buck, int ldo, int on)
+{
+       unsigned char addr, val[2];
+       unsigned int reg, shift;
+
+       if (ldo) {
+               if (ldo < 2)
+                       return -1;
+               if (ldo <= 5) {
+                       reg = 0x11;
+                       shift = 5 - ldo;
+               } else if (ldo <= 13) {
+                       reg = 0x12;
+                       shift = 13 - ldo;
+               } else if (ldo <= 17) {
+                       reg = 0x13;
+                       shift = 17 - ldo + 4;
+               } else
+                       return -1;
+       } else if (buck) {
+               if (buck > 4)
+                       return -1;
+               reg = 0x11;
+               shift = 4 - buck + 4;
+       } else
+               return -1;
+
+       i2c_gpio_set_bus(I2C_PMIC);
+       addr = 0xCC >> 1;
+       if (i2c_probe(addr)) {
+               printf("Can't found max8998\n");
+               return -1;
+       }
+
+       i2c_read(addr, reg, 1, val, 1);
+       if (on)
+               val[0] |= (1 << shift);
+       else
+               val[0] &= ~(1 << shift);
+       i2c_write(addr, reg, 1, val, 1);
+       i2c_read(addr, reg, 1, val, 1);
+       printf("%s %d value 0x%x, %s\n", __func__, __LINE__,
+               buck ? "buck" : "ldo", buck ? : ldo,
+               val[0], val[0] & (1 << shift) ? "on" : "off");
+
+       return 0;
+}
+
+static int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       int buck = 0, ldo = 0, on = -1;
+
+       switch (argc) {
+       case 2:
+               if (strncmp(argv[1], "status", 6) == 0)
+                       return pmic_status();
+               break;
+       case 4:
+               if (strncmp(argv[1], "ldo", 3) == 0) {
+                       ldo = simple_strtoul(argv[2], NULL, 10);
+                       if (strncmp(argv[3], "on", 2) == 0)
+                               on = 1;
+                       else if (strncmp(argv[3], "off", 3) == 0)
+                               on = 0;
+                       else
+                               break;
+                       return pmic_ldo_control(buck, ldo, on);
+               }
+               if (strncmp(argv[1], "buck", 4) == 0) {
+                       buck = simple_strtoul(argv[2], NULL, 10);
+                       if (strncmp(argv[3], "on", 2) == 0)
+                               on = 1;
+                       else if (strncmp(argv[3], "off", 3) == 0)
+                               on = 0;
+                       else
+                               break;
+                       return pmic_ldo_control(buck, ldo, on);
+               }
+
+       default:
+               break;
+       }
+
+       cmd_usage(cmdtp);
+       return 1;
+}
+
+U_BOOT_CMD(
+       pmic,           CONFIG_SYS_MAXARGS,     1, do_pmic,
+       "PMIC LDO & BUCK control",
+       "status - Display PMIC LDO & BUCK status\n"
+       "pmic ldo num on/off - Turn on/off the LDO\n"
+       "pmic buck num on/off - Turn on/off the BUCK\n"
+);
index 96ce7b7..7d76d02 100644 (file)
 #include <asm/arch/cpu.h>
 #include <asm/arch/power.h>
 
+enum {
+       SLEEP_WFI,
+       SLEEP_REGISTER,
+};
+
 static void __board_sleep_init(void) { }
 
 void board_sleep_init(void)
        __attribute__((weak, alias("__board_sleep_init")));
 
-static int s5pc110_sleep(void)
+static int s5pc110_sleep(int mode)
 {
        unsigned int value;
 
@@ -33,22 +38,30 @@ static int s5pc110_sleep(void)
 
        value = readl(S5PC110_PWR_CFG);
        value &= ~S5PC110_CFG_STANDBYWFI_MASK;
-       value |= S5PC110_CFG_STANDBYWFI_SLEEP;
+       if (mode == SLEEP_WFI)
+               value |= S5PC110_CFG_STANDBYWFI_SLEEP;
+       else
+               value |= S5PC110_CFG_STANDBYWFI_IGNORE;
        writel(value, S5PC110_PWR_CFG);
 
        value = readl(S5PC110_OTHERS);
        value |= S5PC110_OTHERS_SYSCON_INT_DISABLE;
        writel(value, S5PC110_OTHERS);
 
-       printf("%s[%d] sleep enter\n\n", __func__, __LINE__);
-
-       value = 0;
-       asm("b  1f\n\t"
-               ".align 5\n\t"
-               "1:\n\t"
-               "mcr p15, 0, %0, c7, c10, 5\n\t"
-               "mcr p15, 0, %0, c7, c10, 4\n\t"
-               ".word 0xe320f003" :: "r" (value));
+       printf("%s[%d] sleep enter mode %d\n\n", __func__, __LINE__, mode);
+
+       if (mode == SLEEP_WFI) {
+               value = 0;
+               asm("b  1f\n\t"
+                       ".align 5\n\t"
+                       "1:\n\t"
+                       "mcr p15, 0, %0, c7, c10, 5\n\t"
+                       "mcr p15, 0, %0, c7, c10, 4\n\t"
+                       ".word 0xe320f003" :: "r" (value));
+       } else {
+               value = S5PC110_PWR_MODE_SLEEP;
+               writel(value, S5PC110_PWR_MODE);
+       }
 
        printf("%s[%d] sleep success\n", __func__, __LINE__);
        return 0;
@@ -56,8 +69,13 @@ static int s5pc110_sleep(void)
 
 int do_sleep(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
+       int mode = SLEEP_WFI;
+
+       if (argc >= 2)
+               mode = SLEEP_REGISTER;
+
        if (cpu_is_s5pc110())
-               return s5pc110_sleep();
+               return s5pc110_sleep(mode);
 
        cmd_usage(cmdtp);
        return 1;
index 921f775..27e2649 100644 (file)
 #define S5PC110_SLEEP_WAKEUP           (1 << 16)
 #define S5PC110_PWR_CFG                        0xE010C000
 #define S5PC110_CFG_STANDBYWFI_MASK    (0x3 << 8)
+#define S5PC110_CFG_STANDBYWFI_IGNORE  (0x0 << 8)
 #define S5PC110_CFG_STANDBYWFI_IDLE    (0x1 << 8)
 #define S5PC110_CFG_STANDBYWFI_STOP    (0x2 << 8)
 #define S5PC110_CFG_STANDBYWFI_SLEEP   (0x3 << 8)
 #define S5PC110_EINT_WAKEUP_MASK       0xE010C004
 #define S5PC110_WAKEUP_MASK            0xE010C008
+#define S5PC110_PWR_MODE               0xE010C00C
+#define S5PC110_PWR_MODE_SLEEP         (1 << 2)
 #define S5PC110_SLEEP_CFG              0xE010C040
 #define S5PC110_WAKEUP_STAT            0xE010C200
 #define S5PC110_OTHERS                 0xE010E000