Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / u-boot / board / st-ericsson / u8500 / gpio.c
diff --git a/qemu/roms/u-boot/board/st-ericsson/u8500/gpio.c b/qemu/roms/u-boot/board/st-ericsson/u8500/gpio.c
new file mode 100644 (file)
index 0000000..2ddc7af
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/gpio.h>
+
+static struct gpio_register *addr_gpio_register[] = {
+       (void *)U8500_GPIO_0_BASE,
+       (void *)U8500_GPIO_1_BASE,
+       (void *)U8500_GPIO_2_BASE,
+       (void *)U8500_GPIO_3_BASE,
+       (void *)U8500_GPIO_4_BASE,
+       (void *)U8500_GPIO_5_BASE,
+       (void *)U8500_GPIO_6_BASE,
+       (void *)U8500_GPIO_7_BASE,
+       (void *)U8500_GPIO_8_BASE,
+};
+
+struct gpio_altfun_data altfun_table[] = {
+       {
+               .altfun = GPIO_ALT_I2C_0,
+               .start = 147,
+               .end = 148,
+               .cont = 0,
+               .type = GPIO_ALTF_A,
+       },
+       {
+               .altfun = GPIO_ALT_I2C_1,
+               .start = 16,
+               .end = 17,
+               .cont = 0,
+               .type = GPIO_ALTF_B,
+       },
+       {
+               .altfun = GPIO_ALT_I2C_2,
+               .start = 10,
+               .end = 11,
+               .cont = 0,
+               .type = GPIO_ALTF_B,
+       },
+       {
+               .altfun = GPIO_ALT_I2C_3,
+               .start = 229,
+               .end = 230,
+               .cont = 0,
+               .type = GPIO_ALTF_C,
+       },
+       {
+               .altfun = GPIO_ALT_UART_0_MODEM,
+               .start = 0,
+               .end = 3,
+               .cont = 1,
+               .type = GPIO_ALTF_A,
+       },
+       {
+               .altfun = GPIO_ALT_UART_0_MODEM,
+               .start = 33,
+               .end = 36,
+               .cont = 0,
+               .type = GPIO_ALTF_C,
+       },
+       {
+               .altfun = GPIO_ALT_UART_1,
+               .start = 4,
+               .end = 7,
+               .cont = 0,
+               .type =
+                       GPIO_ALTF_A,
+       },
+       {
+               .altfun = GPIO_ALT_UART_2,
+               .start = 18,
+               .end = 19,
+               .cont = 1,
+               .type = GPIO_ALTF_B,
+       },
+       {
+               .altfun = GPIO_ALT_UART_2,
+               .start = 29,
+               .end = 32,
+               .cont = 0,
+               .type = GPIO_ALTF_C,
+       },
+       {
+               .altfun = GPIO_ALT_MSP_0,
+               .start = 12,
+               .end = 17,
+               .cont = 1,
+               .type = GPIO_ALTF_A,
+       },
+       {
+               .altfun = GPIO_ALT_MSP_0,
+               .start = 21,
+               .end = 21,
+               .cont = 0,
+               .type = GPIO_ALTF_B,
+       },
+       {
+               .altfun = GPIO_ALT_MSP_1,
+               .start = 33,
+               .end = 36,
+               .cont = 0,
+               .type = GPIO_ALTF_A,
+       },
+       {
+               .altfun = GPIO_ALT_MSP_2,
+               .start = 192,
+               .end = 196,
+               .cont = 0,
+               .type = GPIO_ALTF_A,
+       },
+       {
+               .altfun = GPIO_ALT_LCD_PANEL,
+               .start = 64,
+               .end = 93,
+               .cont = 1,
+               .type = GPIO_ALTF_A,
+       },
+       {
+               .altfun = GPIO_ALT_LCD_PANEL,
+               .start = 150,
+               .end = 171,
+               .cont = 0,
+               .type = GPIO_ALTF_B,
+       },
+       {
+               .altfun = GPIO_ALT_SD_CARD0,
+               .start = 18,
+               .end = 28,
+               .cont = 0,
+               .type = GPIO_ALTF_A,
+       },
+       {
+               .altfun = GPIO_ALT_MM_CARD0,
+               .start = 18,
+               .end = 32,
+               .cont = 0,
+               .type = GPIO_ALTF_A,
+       },
+       {
+               .altfun = GPIO_ALT_USB_OTG,
+               .start = 256,
+               .end = 267,
+               .cont = 0,
+               .type = GPIO_ALTF_A,
+       },
+       {
+               .altfun = GPIO_ALT_EMMC,
+               .start = 197,
+               .end = 207,
+               .cont = 0,
+               .type = GPIO_ALTF_A,
+       },
+       {
+               .altfun = GPIO_ALT_POP_EMMC,
+               .start = 128,
+               .end = 138,
+               .cont = 0,
+               .type = GPIO_ALTF_A,
+       },
+};
+
+/*
+ * Static Function declarations
+ */
+enum gpio_error gpio_setpinconfig(int pin_id, struct gpio_config *config)
+{
+       struct gpio_register *p_gpio_register =
+           addr_gpio_register[GPIO_BLOCK(pin_id)];
+       u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+       enum gpio_error error = GPIO_OK;
+       u32 temp_reg;
+
+       switch (config->mode) {
+       case GPIO_ALTF_A:
+               temp_reg = readl(&p_gpio_register->gpio_afsa);
+               temp_reg |= mask;
+               writel(temp_reg, &p_gpio_register->gpio_afsa);
+               temp_reg = readl(&p_gpio_register->gpio_afsb);
+               temp_reg &= ~mask;
+               writel(temp_reg, &p_gpio_register->gpio_afsb);
+               break;
+       case GPIO_ALTF_B:
+               temp_reg = readl(&p_gpio_register->gpio_afsa);
+               temp_reg &= ~mask;
+               writel(temp_reg, &p_gpio_register->gpio_afsa);
+               temp_reg = readl(&p_gpio_register->gpio_afsb);
+               temp_reg |= mask;
+               writel(temp_reg, &p_gpio_register->gpio_afsb);
+               break;
+       case GPIO_ALTF_C:
+               temp_reg = readl(&p_gpio_register->gpio_afsa);
+               temp_reg |= mask;
+               writel(temp_reg, &p_gpio_register->gpio_afsa);
+               temp_reg = readl(&p_gpio_register->gpio_afsb);
+               temp_reg |= mask;
+               writel(temp_reg, &p_gpio_register->gpio_afsb);
+               break;
+       case GPIO_MODE_SOFTWARE:
+               temp_reg = readl(&p_gpio_register->gpio_afsa);
+               temp_reg &= ~mask;
+               writel(temp_reg, &p_gpio_register->gpio_afsa);
+               temp_reg = readl(&p_gpio_register->gpio_afsb);
+               temp_reg &= ~mask;
+               writel(temp_reg, &p_gpio_register->gpio_afsb);
+
+               switch (config->direction) {
+               case GPIO_DIR_INPUT:
+                       writel(mask, &p_gpio_register->gpio_dirc);
+                       break;
+               case GPIO_DIR_OUTPUT:
+                       writel(mask, &p_gpio_register->gpio_dirs);
+                       break;
+               case GPIO_DIR_LEAVE_UNCHANGED:
+                       break;
+               default:
+                       return GPIO_INVALID_PARAMETER;
+               }
+
+               break;
+       case GPIO_MODE_LEAVE_UNCHANGED:
+               break;
+       default:
+               return GPIO_INVALID_PARAMETER;
+       }
+       return error;
+}
+
+enum gpio_error gpio_resetgpiopin(int pin_id, char *dev_name)
+{
+       struct gpio_register *p_gpio_register =
+           addr_gpio_register[GPIO_BLOCK(pin_id)];
+       u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+       enum gpio_error error = GPIO_OK;
+       u32 temp_reg;
+
+       temp_reg = readl(&p_gpio_register->gpio_afsa);
+       temp_reg &= ~mask;
+       writel(temp_reg, &p_gpio_register->gpio_afsa);
+       temp_reg = readl(&p_gpio_register->gpio_afsb);
+       temp_reg &= ~mask;
+       writel(temp_reg, &p_gpio_register->gpio_afsb);
+       writel(mask, &p_gpio_register->gpio_dirc);
+
+       return error;
+}
+
+struct gpio_config altfun_pinconfig;
+enum gpio_error gpio_altfunction(enum gpio_alt_function alt_func,
+                           int which_altfunc, char *dev_name)
+{
+       int i, j, start, end;
+       enum gpio_error error = -1;
+
+       for (i = 0; i < ARRAY_SIZE(altfun_table); i++) {
+               if (altfun_table[i].altfun != alt_func)
+                       continue;
+
+               start = altfun_table[i].start;
+               end = altfun_table[i].end;
+               for (j = start; j <= end; j++) {
+                       if (which_altfunc == GPIO_ALTF_FIND)
+                               altfun_pinconfig.mode = altfun_table[i].type;
+                       else
+                               altfun_pinconfig.mode = which_altfunc;
+                       altfun_pinconfig.direction = GPIO_DIR_OUTPUT;
+                       altfun_pinconfig.dev_name = dev_name;
+
+                       if (which_altfunc != GPIO_ALTF_DISABLE)
+                               error = gpio_setpinconfig(j, &altfun_pinconfig);
+                       else
+                               error = gpio_resetgpiopin(j, dev_name);
+                       if (!error)
+                               continue;
+                       printf("GPIO %d configuration failure (nmdk_error:%d)",
+                               j, error);
+                       error = GPIO_INVALID_PARAMETER;
+                       return error;
+               }
+
+               if (!altfun_table[i].cont)
+                       break;
+       }
+       return error;
+}
+
+int gpio_writepin(int pin_id, enum gpio_data value, char *dev_name)
+{
+       struct gpio_register *p_gpio_register =
+           addr_gpio_register[GPIO_BLOCK(pin_id)];
+       u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
+       switch (value) {
+       case GPIO_DATA_HIGH:
+               writel(mask, &p_gpio_register->gpio_dats);
+               break;
+       case GPIO_DATA_LOW:
+               writel(mask, &p_gpio_register->gpio_datc);
+               break;
+       default:
+               printf("Invalid value passed in %s", __FUNCTION__);
+               return GPIO_INVALID_PARAMETER;
+       }
+       return GPIO_OK;
+}
+
+int gpio_readpin(int pin_id, enum gpio_data *rv)
+{
+       struct gpio_register *p_gpio_register =
+           addr_gpio_register[GPIO_BLOCK(pin_id)];
+       u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
+       if ((readl(&p_gpio_register->gpio_dat) & mask) != 0)
+               *rv = GPIO_DATA_HIGH;
+       else
+               *rv = GPIO_DATA_LOW;
+       return GPIO_OK;
+}
+
+int gpio_altfuncenable(enum gpio_alt_function altfunc, char *dev_name)
+{
+       return (int)gpio_altfunction(altfunc, GPIO_ALTF_FIND, dev_name);
+}
+
+int gpio_altfuncdisable(enum gpio_alt_function altfunc, char *dev_name)
+{
+       return (int)gpio_altfunction(altfunc, GPIO_ALTF_DISABLE, dev_name);
+}