]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - board/karo/tx6/tx6qdl.c
karo: tx6: cleanup i2c_recover implementation
[karo-tx-uboot.git] / board / karo / tx6 / tx6qdl.c
index d183db6f52756ac20f2417e51191bf40f6419273..7b2cd5371fe3288c98195808d042e127f8bc01f9 100644 (file)
@@ -158,90 +158,88 @@ static const struct gpio const tx6qdl_gpios[] = {
 
 static int pmic_addr __data;
 
-#if defined(CONFIG_SOC_MX6Q)
-#define IOMUXC_SW_MUX_CTL_PAD_EIM_DATA21       0x020e00a4
-#define IOMUXC_SW_MUX_CTL_PAD_EIM_DATA28       0x020e00c4
-#define IOMUXC_SW_PAD_CTL_PAD_EIM_DATA21       0x020e03b8
-#define IOMUXC_SW_PAD_CTL_PAD_EIM_DATA28       0x020e03d8
-#define IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA21     0x020e0898
-#define IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA28     0x020e089c
-#define I2C1_SEL_INPUT_VAL                     0
-#endif
-#if defined(CONFIG_SOC_MX6DL) || defined(CONFIG_SOC_MX6S)
-#define IOMUXC_SW_MUX_CTL_PAD_EIM_DATA21       0x020e0158
-#define IOMUXC_SW_MUX_CTL_PAD_EIM_DATA28       0x020e0174
-#define IOMUXC_SW_PAD_CTL_PAD_EIM_DATA21       0x020e0528
-#define IOMUXC_SW_PAD_CTL_PAD_EIM_DATA28       0x020e0544
-#define IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA21     0x020e0868
-#define IOMUXC_SW_SEL_INPUT_PAD_EIM_DATA28     0x020e086c
-#define I2C1_SEL_INPUT_VAL                     1
-#endif
+#if defined(TX6_I2C1_SCL_GPIO) && defined(TX6_I2C1_SDA_GPIO)
+#define SCL_BANK       (TX6_I2C1_SCL_GPIO / 32)
+#define SDA_BANK       (TX6_I2C1_SDA_GPIO / 32)
+#define SCL_BIT                (1 << (TX6_I2C1_SCL_GPIO % 32))
+#define SDA_BIT                (1 << (TX6_I2C1_SDA_GPIO % 32))
 
-#define GPIO_DR 0
-#define GPIO_DIR 4
-#define GPIO_PSR 8
+static void * const gpio_ports[] = {
+       (void *)GPIO1_BASE_ADDR,
+       (void *)GPIO2_BASE_ADDR,
+       (void *)GPIO3_BASE_ADDR,
+       (void *)GPIO4_BASE_ADDR,
+       (void *)GPIO5_BASE_ADDR,
+       (void *)GPIO6_BASE_ADDR,
+       (void *)GPIO7_BASE_ADDR,
+};
 
 static void tx6_i2c_recover(void)
 {
        int i;
        int bad = 0;
-#define SCL_BIT                (1 << (TX6_I2C1_SCL_GPIO % 32))
-#define SDA_BIT                (1 << (TX6_I2C1_SDA_GPIO % 32))
+       struct gpio_regs *scl_regs = gpio_ports[SCL_BANK];
+       struct gpio_regs *sda_regs = gpio_ports[SDA_BANK];
 
-       if ((readl(GPIO3_BASE_ADDR + GPIO_PSR) &
-                       (SCL_BIT | SDA_BIT)) == (SCL_BIT | SDA_BIT))
+       if ((readl(&scl_regs->gpio_psr) & SCL_BIT) &&
+           (readl(&sda_regs->gpio_psr) & SDA_BIT))
                return;
 
        debug("Clearing I2C bus\n");
-       if (!(readl(GPIO3_BASE_ADDR + GPIO_PSR) & SCL_BIT)) {
+       if (!(readl(&scl_regs->gpio_psr) & SCL_BIT)) {
                printf("I2C SCL stuck LOW\n");
                bad++;
 
-               writel(readl(GPIO3_BASE_ADDR + GPIO_DR) | SCL_BIT,
-                       GPIO3_BASE_ADDR + GPIO_DR);
-               writel(readl(GPIO3_BASE_ADDR + GPIO_DIR) | SCL_BIT,
-                       GPIO3_BASE_ADDR + GPIO_DIR);
+               setbits_le32(&scl_regs->gpio_dr, SCL_BIT);
+               setbits_le32(&scl_regs->gpio_dir, SCL_BIT);
+
+               imx_iomux_v3_setup_multiple_pads(tx6_i2c_gpio_pads,
+                                                ARRAY_SIZE(tx6_i2c_gpio_pads));
        }
-       if (!(readl(GPIO3_BASE_ADDR + GPIO_PSR) & SDA_BIT)) {
+       if (!(readl(&sda_regs->gpio_psr) & SDA_BIT)) {
                printf("I2C SDA stuck LOW\n");
-               bad++;
 
-               writel(readl(GPIO3_BASE_ADDR + GPIO_DIR) & ~SDA_BIT,
-                       GPIO3_BASE_ADDR + GPIO_DIR);
-               writel(readl(GPIO3_BASE_ADDR + GPIO_DR) | SCL_BIT,
-                       GPIO3_BASE_ADDR + GPIO_DR);
-               writel(readl(GPIO3_BASE_ADDR + GPIO_DIR) | SCL_BIT,
-                       GPIO3_BASE_ADDR + GPIO_DIR);
+               clrbits_le32(&sda_regs->gpio_dir, SDA_BIT);
+               setbits_le32(&scl_regs->gpio_dr, SCL_BIT);
+               setbits_le32(&scl_regs->gpio_dir, SCL_BIT);
+
+               if (!bad++)
+                       imx_iomux_v3_setup_multiple_pads(tx6_i2c_gpio_pads,
+                                                        ARRAY_SIZE(tx6_i2c_gpio_pads));
 
-               imx_iomux_v3_setup_multiple_pads(tx6_i2c_gpio_pads,
-                                               ARRAY_SIZE(tx6_i2c_gpio_pads));
                udelay(10);
 
                for (i = 0; i < 18; i++) {
-                       u32 reg = readl(GPIO3_BASE_ADDR + GPIO_DR) ^ SCL_BIT;
-
-                       debug("%sing SCL\n", (reg & SCL_BIT) ? "Sett" : "Clear");
-                       writel(reg, GPIO3_BASE_ADDR + GPIO_DR);
-                       udelay(10);
-                       if (reg & SCL_BIT &&
-                               readl(GPIO3_BASE_ADDR + GPIO_PSR) & SDA_BIT)
+                       u32 reg = readl(&scl_regs->gpio_dr) ^ SCL_BIT;
+
+                       debug("%sing SCL\n",
+                             (reg & SCL_BIT) ? "Sett" : "Clear");
+                       writel(reg, &scl_regs->gpio_dr);
+                       udelay(5);
+                       if (reg & SCL_BIT) {
+                               if (readl(&sda_regs->gpio_psr) & SDA_BIT)
+                                       break;
+                               if (!(readl(&scl_regs->gpio_psr) & SCL_BIT))
+                                       break;
                                break;
+                       }
                }
        }
        if (bad) {
-               u32 reg = readl(GPIO3_BASE_ADDR + GPIO_PSR);
+               bool scl = !!(readl(&scl_regs->gpio_psr) & SCL_BIT);
+               bool sda = !!(readl(&sda_regs->gpio_psr) & SDA_BIT);
 
-               if ((reg & (SCL_BIT | SDA_BIT)) == (SCL_BIT | SDA_BIT)) {
+               if (scl && sda) {
                        printf("I2C bus recovery succeeded\n");
                } else {
-                       printf("I2C bus recovery FAILED: %08x:%08x\n", reg,
-                               SCL_BIT | SDA_BIT);
+                       printf("I2C bus recovery FAILED: SCL: %d SDA: %d\n",
+                              scl, sda);
                }
+               imx_iomux_v3_setup_multiple_pads(tx6_i2c_pads,
+                                                ARRAY_SIZE(tx6_i2c_pads));
        }
-       debug("Setting up I2C Pads\n");
-       imx_iomux_v3_setup_multiple_pads(tx6_i2c_pads,
-                                       ARRAY_SIZE(tx6_i2c_pads));
 }
+#endif
 
 /* placed in section '.data' to prevent overwriting relocation info
  * overlayed with bss
@@ -430,20 +428,65 @@ static char tx6_mem_table[] = {
        '3', /* TX6U-8033 1GiB SDRAM 64bit; 4GiB eMMC */
        '?', /* N/A 256MiB SDRAM 16bit; 8GiB eMMC */
        '?', /* N/A 512MiB SDRAM 32bit; 8GiB eMMC */
-#if defined(CONFIG_TX6_REV) && CONFIG_TX6_REV == 2
-       '0', /* TX6Q-1020 (legacy) 1GiB SDRAM 64bit; 8GiB eMMC */
-#else
        '6', /* TX6Q-1036 1GiB SDRAM 64bit; 8GiB eMMC */
-#endif
 };
 
+#ifdef CONFIG_RN5T567
+/* PMIC settings */
+#define VDD_RTC_VAL            rn5t_mV_to_regval_rtc(3000)
+#define VDD_CORE_VAL           rn5t_mV_to_regval(1400)         /* DCDC1 */
+#define VDD_CORE_VAL_LP                rn5t_mV_to_regval(900)
+#define VDD_SOC_VAL            rn5t_mV_to_regval(1400)         /* DCDC2 */
+#define VDD_SOC_VAL_LP         rn5t_mV_to_regval(1400)
+#define VDD_DDR_VAL            rn5t_mV_to_regval(1350)         /* DCDC3 */
+#define VDD_DDR_VAL_LP         rn5t_mV_to_regval(1350)
+#define VDD_HIGH_VAL           rn5t_mV_to_regval(3000)         /* DCDC4 */
+#define VDD_HIGH_VAL_LP                rn5t_mV_to_regval(3000)
+#define VDD_IO_INT_VAL         rn5t_mV_to_regval2(3300)        /* LDO1 */
+#define VDD_IO_INT_VAL_LP      rn5t_mV_to_regval2(3300)
+#define VDD_IO_EXT_VAL         rn5t_mV_to_regval2(3300)        /* LDO2 */
+#define VDD_IO_EXT_VAL_LP      rn5t_mV_to_regval2(3300)
+
+static struct pmic_regs rn5t567_regs[] = {
+       { RN5T567_NOETIMSET, 0x5, },
+       { RN5T567_DC1DAC, VDD_CORE_VAL, },
+       { RN5T567_DC2DAC, VDD_SOC_VAL, },
+       { RN5T567_DC3DAC, VDD_DDR_VAL, },
+       { RN5T567_DC4DAC, VDD_HIGH_VAL, },
+       { RN5T567_DC1DAC_SLP, VDD_CORE_VAL_LP, },
+       { RN5T567_DC2DAC_SLP, VDD_SOC_VAL_LP, },
+       { RN5T567_DC3DAC_SLP, VDD_DDR_VAL_LP, },
+       { RN5T567_DC4DAC_SLP, VDD_HIGH_VAL_LP, },
+       { RN5T567_DC1CTL, DCnCTL_DCnEN | DCnMODE_SLP(DCnMODE_PSM), },
+       { RN5T567_DC2CTL, DCnCTL_DCnEN | DCnMODE_SLP(DCnMODE_PSM), },
+       { RN5T567_DC3CTL, DCnCTL_DCnEN | DCnMODE_SLP(DCnMODE_PSM), },
+       { RN5T567_DC4CTL, DCnCTL_DCnEN | DCnMODE_SLP(DCnMODE_PSM), },
+       { RN5T567_LDORTC1DAC, VDD_RTC_VAL, },
+       { RN5T567_LDORTC1_SLOT, 0x0f, ~0x3f, },
+       { RN5T567_LDO1DAC, VDD_IO_INT_VAL, },
+       { RN5T567_LDO2DAC, VDD_IO_EXT_VAL, },
+       { RN5T567_LDOEN1, 0x03, ~0x1f, },
+       { RN5T567_LDOEN2, 0x10, ~0x30, },
+       { RN5T567_LDODIS, 0x1c, ~0x1f, },
+       { RN5T567_INTPOL, 0, },
+       { RN5T567_INTEN, 0x3, },
+       { RN5T567_IREN, 0xf, },
+       { RN5T567_EN_GPIR, 0, },
+};
+#endif
+
 static struct {
        uchar addr;
        uchar rev;
+       struct pmic_regs *regs;
+       size_t num_regs;
 } tx6_mod_revs[] = {
-       { 0x3c, 1, },
-       { 0x32, 2, },
-       { 0x33, 3, },
+#ifdef CONFIG_LTC3676
+       { 0x3c, 1, NULL, 0, },
+#endif
+#ifdef CONFIG_RN5T567
+       { 0x33, 3, rn5t567_regs, ARRAY_SIZE(rn5t567_regs), },
+#endif
 };
 
 static inline char tx6_mem_suffix(void)
@@ -489,6 +532,16 @@ static int tx6_pmic_probe(void)
        return -EINVAL;
 }
 
+static int tx6_mipi(void)
+{
+       struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+       struct fuse_bank4_regs *fuse = (void *)ocotp->bank[4].fuse_regs;
+       u32 gp1 = readl(&fuse->gp1);
+
+       debug("Fuse gp1 @ %p = %08x\n", &fuse->gp1, gp1);
+       return gp1 & 1;
+}
+
 int board_init(void)
 {
        int ret;
@@ -503,7 +556,7 @@ int board_init(void)
        printf("Board: Ka-Ro TX6%s-%d%d%d%c\n",
                tx6_mod_suffix,
                is_cpu_type(MXC_CPU_MX6Q) ? 1 : 8,
-               is_lvds(), tx6_get_mod_rev(pmic_id),
+               tx6_mipi() ? 2 : is_lvds(), tx6_get_mod_rev(pmic_id),
                tx6_mem_suffix());
 
        get_hab_status();
@@ -529,7 +582,8 @@ int board_init(void)
                return 0;
        }
 
-       ret = tx6_pmic_init(pmic_addr, NULL, 0);
+       ret = tx6_pmic_init(pmic_addr, tx6_mod_revs[pmic_id].regs,
+                       tx6_mod_revs[pmic_id].num_regs);
        if (ret) {
                printf("Failed to setup PMIC voltages: %d\n", ret);
                hang();
@@ -831,7 +885,6 @@ vidinfo_t panel_info = {
 };
 
 static struct fb_videomode tx6_fb_modes[] = {
-#ifndef CONFIG_SYS_LVDS_IF
        {
                /* Standard VGA timing */
                .name           = "VGA",
@@ -865,6 +918,24 @@ static struct fb_videomode tx6_fb_modes[] = {
                .lower_margin   = 10,
                .sync           = FB_SYNC_CLK_LAT_FALL,
        },
+       {
+               /* Emerging ETM0700G0DH6 800 x 480 display.
+                * 152.4 mm x 91.44 mm display area.
+                */
+               .name           = "ET0700",
+               .refresh        = 60,
+               .xres           = 800,
+               .yres           = 480,
+               .pixclock       = KHZ2PICOS(33260),
+               .left_margin    = 88,
+               .hsync_len      = 128,
+               .right_margin   = 40,
+               .upper_margin   = 33,
+               .vsync_len      = 2,
+               .lower_margin   = 10,
+               .sync           = FB_SYNC_CLK_LAT_FALL,
+       },
+#ifndef CONFIG_SYS_LVDS_IF
        {
                /* Emerging ET0350G0DH6 320 x 240 display.
                 * 70.08 mm x 52.56 mm display area.
@@ -874,10 +945,10 @@ static struct fb_videomode tx6_fb_modes[] = {
                .xres           = 320,
                .yres           = 240,
                .pixclock       = KHZ2PICOS(6500),
-               .left_margin    = 68 - 34,
+               .left_margin    = 34,
                .hsync_len      = 34,
                .right_margin   = 20,
-               .upper_margin   = 18 - 3,
+               .upper_margin   = 15,
                .vsync_len      = 3,
                .lower_margin   = 4,
                .sync           = FB_SYNC_CLK_LAT_FALL,
@@ -907,12 +978,12 @@ static struct fb_videomode tx6_fb_modes[] = {
                .xres           = 800,
                .yres           = 480,
                .pixclock       = KHZ2PICOS(33260),
-               .left_margin    = 216 - 128,
+               .left_margin    = 88,
                .hsync_len      = 128,
-               .right_margin   = 1056 - 800 - 216,
-               .upper_margin   = 35 - 2,
+               .right_margin   = 40,
+               .upper_margin   = 33,
                .vsync_len      = 2,
-               .lower_margin   = 525 - 480 - 35,
+               .lower_margin   = 10,
                .sync           = FB_SYNC_CLK_LAT_FALL,
        },
        {
@@ -932,40 +1003,6 @@ static struct fb_videomode tx6_fb_modes[] = {
                .lower_margin   = 4, /* 4.5 according to datasheet */
                .sync           = FB_SYNC_CLK_LAT_FALL,
        },
-       {
-               /* Emerging ET0700G0DH6 800 x 480 display.
-                * 152.4 mm x 91.44 mm display area.
-                */
-               .name           = "ET0700",
-               .refresh        = 60,
-               .xres           = 800,
-               .yres           = 480,
-               .pixclock       = KHZ2PICOS(33260),
-               .left_margin    = 216 - 128,
-               .hsync_len      = 128,
-               .right_margin   = 1056 - 800 - 216,
-               .upper_margin   = 35 - 2,
-               .vsync_len      = 2,
-               .lower_margin   = 525 - 480 - 35,
-               .sync           = FB_SYNC_CLK_LAT_FALL,
-       },
-       {
-               /* Emerging ET070001DM6 800 x 480 display.
-                * 152.4 mm x 91.44 mm display area.
-                */
-               .name           = "ET070001DM6",
-               .refresh        = 60,
-               .xres           = 800,
-               .yres           = 480,
-               .pixclock       = KHZ2PICOS(33260),
-               .left_margin    = 216 - 128,
-               .hsync_len      = 128,
-               .right_margin   = 1056 - 800 - 216,
-               .upper_margin   = 35 - 2,
-               .vsync_len      = 2,
-               .lower_margin   = 525 - 480 - 35,
-               .sync           = 0,
-       },
 #else
        {
                /* HannStar HSD100PXN1
@@ -1509,8 +1546,12 @@ int ft_board_setup(void *blob, bd_t *bd)
        karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy", "vbus-supply");
        karo_fdt_fixup_flexcan(blob, stk5_v5);
 
-       karo_fdt_update_fb_mode(blob, video_mode);
-
+#ifdef CONFIG_SYS_LVDS_IF
+       karo_fdt_update_fb_mode(blob, video_mode, "/lvds0-panel");
+       karo_fdt_update_fb_mode(blob, video_mode, "/lvds1-panel");
+#else
+       karo_fdt_update_fb_mode(blob, video_mode, "/lcd-panel");
+#endif
        return 0;
 }
 #endif /* CONFIG_OF_BOARD_SETUP */