]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - board/karo/tx6/tx6ul.c
karo: tx6: add support for TXUL-5014
[karo-tx-uboot.git] / board / karo / tx6 / tx6ul.c
index 5606cbf432dbdd64fcf714f6b2c16be6ce3e7d89..702a1f838abdfa7de62517cfbaeaa530e418b3df 100644 (file)
@@ -81,10 +81,6 @@ char __csf_data[0] __attribute__((section(".__csf_data")));
                                        PAD_CTL_SPEED_LOW |             \
                                        PAD_CTL_DSE_34ohm |             \
                                        PAD_CTL_SRE_FAST)
-#define TX6UL_I2C_GPIO_PAD_CTRL        MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |       \
-                                       PAD_CTL_HYS |                   \
-                                       PAD_CTL_DSE_34ohm |             \
-                                       PAD_CTL_SPEED_MED)
 #define TX6UL_ENET_PAD_CTRL    MUX_PAD_CTRL(PAD_CTL_SPEED_HIGH |       \
                                        PAD_CTL_DSE_120ohm |            \
                                        PAD_CTL_PUS_100K_UP |           \
@@ -163,14 +159,6 @@ static const iomux_v3_cfg_t const tx6ul_i2c_pads[] = {
                        TX6UL_I2C_PAD_CTRL, /* I2C SDA */
 };
 
-static const iomux_v3_cfg_t const tx6ul_i2c_gpio_pads[] = {
-       /* internal I2C set up for I2C bus recovery */
-       MX6_PAD_SNVS_TAMPER1__GPIO5_IO01 | MUX_CFG_SION |
-                       TX6UL_I2C_PAD_CTRL, /* I2C SCL */
-       MX6_PAD_SNVS_TAMPER0__GPIO5_IO00 | MUX_CFG_SION |
-                       TX6UL_I2C_PAD_CTRL, /* I2C SDA */
-};
-
 static const struct gpio const tx6ul_gpios[] = {
 #ifdef CONFIG_SYS_I2C_SOFT
        /* These two entries are used to forcefully reinitialize the I2C bus */
@@ -236,9 +224,6 @@ static void tx6ul_i2c_recover(void)
                setbits_le32(&scl_regs->gpio_dr, SCL_BIT);
                setbits_le32(&scl_regs->gpio_dir, SCL_BIT);
 
-               imx_iomux_v3_setup_multiple_pads(tx6ul_i2c_gpio_pads,
-                                                ARRAY_SIZE(tx6ul_i2c_gpio_pads));
-
                udelay(5);
 
                for (i = 0; i < 18; i++) {
@@ -433,10 +418,15 @@ static bool tx6ul_temp_check_enabled = true;
 #define tx6ul_temp_check_enabled       0
 #endif
 
+#ifndef CONFIG_SYS_NAND_BLOCKS
+#define CONFIG_SYS_NAND_BLOCKS 0
+#endif
+
 static inline u8 tx6ul_mem_suffix(void)
 {
        return '0' + CONFIG_SYS_SDRAM_CHIP_SIZE / 1024 * 2 +
-               IS_ENABLED(CONFIG_TX6_EMMC);
+               IS_ENABLED(CONFIG_TX6_EMMC) +
+               CONFIG_SYS_NAND_BLOCKS / 2048 * 4;
 }
 
 #ifdef CONFIG_RN5T567
@@ -444,43 +434,70 @@ static inline u8 tx6ul_mem_suffix(void)
 #define VDD_RTC_VAL            rn5t_mV_to_regval_rtc(3000)
 #define VDD_CORE_VAL           rn5t_mV_to_regval(1300)         /* DCDC1 */
 #define VDD_CORE_VAL_LP                rn5t_mV_to_regval(900)
-#define VDD_DDR_VAL            rn5t_mV_to_regval(1350)         /* DCDC3 */
+#define VDD_DDR_VAL            rn5t_mV_to_regval(1350)         /* DCDC3 SDRAM 1.35V */
 #define VDD_DDR_VAL_LP         rn5t_mV_to_regval(1350)
-#define VDD_IO_EXT_VAL         rn5t_mV_to_regval(3300)         /* DCDC4 */
+#define VDD_IO_EXT_VAL         rn5t_mV_to_regval(3300)         /* DCDC4 eMMC/NAND,VDDIO_EXT 3.0V */
 #define VDD_IO_EXT_VAL_LP      rn5t_mV_to_regval(3300)
-#define VDD_IO_INT_VAL         rn5t_mV_to_regval2(3300)        /* LDO1 */
+#define VDD_IO_INT_VAL         rn5t_mV_to_regval2(3300)        /* LDO1 ENET,GPIO,LCD,SD1,UART,3.3V */
 #define VDD_IO_INT_VAL_LP      rn5t_mV_to_regval2(3300)
-#define VDD_ADC_VAL            rn5t_mV_to_regval2(3300)        /* LDO2 */
+#define VDD_ADC_VAL            rn5t_mV_to_regval2(3300)        /* LDO2 ADC */
 #define VDD_ADC_VAL_LP         rn5t_mV_to_regval2(3300)
-#define VDD_PMIC_VAL           rn5t_mV_to_regval2(2500)        /* LDO3 */
+#define VDD_PMIC_VAL           rn5t_mV_to_regval2(2500)        /* LDO3 PMIC */
 #define VDD_PMIC_VAL_LP                rn5t_mV_to_regval2(2500)
-#define VDD_CSI_VAL            rn5t_mV_to_regval2(1800)        /* LDO4 */
-#define VDD_CSI_VAL_LP         rn5t_mV_to_regval2(1800)
+#define VDD_CSI_VAL            rn5t_mV_to_regval2(3300)        /* LDO4 CSI */
+#define VDD_CSI_VAL_LP         rn5t_mV_to_regval2(3300)
+#define VDD_LDO5_VAL           rn5t_mV_to_regval2(1200)        /* LDO5 1.2V */
+#define LDOEN1_LDO1EN          (1 << 0)
+#define LDOEN1_LDO2EN          (1 << 1)
+#define LDOEN1_LDO3EN          (1 << 2)
+#define LDOEN1_LDO4EN          (1 << 3)
+#define LDOEN1_LDO5EN          (1 << 4)
+#define LDOEN1_VAL             (LDOEN1_LDO1EN | LDOEN1_LDO2EN | LDOEN1_LDO3EN | LDOEN1_LDO4EN)
+#define LDOEN1_MASK            0x1f
+#define LDOEN2_LDORTC1EN       (1 << 4)
+#define LDOEN2_LDORTC2EN       (1 << 5)
+#define LDOEN2_VAL             LDOEN2_LDORTC1EN
+#define LDOEN2_MASK            0x30
 
 static struct pmic_regs rn5t567_regs[] = {
        { RN5T567_NOETIMSET, NOETIMSET_DIS_OFF_NOE_TIM | 0x5, },
+       { RN5T567_SLPCNT, 0, },
+       { RN5T567_REPCNT, (3 << 4) | (0 << 1), },
        { RN5T567_DC1DAC, VDD_CORE_VAL, },
        { RN5T567_DC3DAC, VDD_DDR_VAL, },
        { RN5T567_DC4DAC, VDD_IO_EXT_VAL, },
        { RN5T567_DC1DAC_SLP, VDD_CORE_VAL_LP, },
        { RN5T567_DC3DAC_SLP, VDD_DDR_VAL_LP, },
        { RN5T567_DC4DAC_SLP, VDD_IO_EXT_VAL_LP, },
-       { RN5T567_DC1CTL, DCnCTL_DCnEN | DCnMODE_SLP(DCnMODE_PSM), },
-       { RN5T567_DC2CTL, DCnCTL_DCnDIS, },
-       { RN5T567_DC3CTL, DCnCTL_DCnEN | DCnMODE_SLP(DCnMODE_PSM), },
-       { RN5T567_DC4CTL, DCnCTL_DCnEN | DCnMODE_SLP(DCnMODE_PSM), },
+       { RN5T567_DC1CTL, DCnCTL_EN | DCnCTL_DIS | DCnMODE_SLP(MODE_PSM), },
+       { RN5T567_DC2CTL, DCnCTL_DIS, },
+       { RN5T567_DC3CTL, DCnCTL_EN | DCnCTL_DIS | DCnMODE_SLP(MODE_PSM), },
+       { RN5T567_DC4CTL, DCnCTL_EN | DCnCTL_DIS | DCnMODE_SLP(MODE_PSM), },
+       { RN5T567_DC1CTL2, DCnCTL2_LIMSDEN | DCnCTL2_LIM_HIGH | DCnCTL2_SR_HIGH | DCnCTL2_OSC_LOW, },
+       { RN5T567_DC2CTL2, DCnCTL2_LIMSDEN | DCnCTL2_LIM_HIGH | DCnCTL2_SR_HIGH | DCnCTL2_OSC_LOW, },
+       { RN5T567_DC3CTL2, DCnCTL2_LIMSDEN | DCnCTL2_LIM_HIGH | DCnCTL2_SR_HIGH | DCnCTL2_OSC_LOW, },
+       { RN5T567_DC4CTL2, DCnCTL2_LIMSDEN | DCnCTL2_LIM_HIGH | DCnCTL2_SR_HIGH | DCnCTL2_OSC_LOW, },
        { RN5T567_LDORTC1DAC, VDD_RTC_VAL, },
        { RN5T567_LDORTC1_SLOT, 0x0f, ~0x3f, },
        { RN5T567_LDO1DAC, VDD_IO_INT_VAL, },
        { RN5T567_LDO2DAC, VDD_ADC_VAL, },
        { RN5T567_LDO3DAC, VDD_PMIC_VAL, },
        { RN5T567_LDO4DAC, VDD_CSI_VAL, },
-       { RN5T567_LDOEN1, 0x0f, ~0x1f, },
-       { RN5T567_LDOEN2, 0x10, ~0x30, },
-       { RN5T567_LDODIS, 0x10, ~0x1f, },
+       { RN5T567_LDO1DAC_SLP, VDD_IO_INT_VAL_LP, },
+       { RN5T567_LDO2DAC_SLP, VDD_ADC_VAL_LP, },
+       { RN5T567_LDO3DAC_SLP, VDD_PMIC_VAL_LP, },
+       { RN5T567_LDO4DAC_SLP, VDD_CSI_VAL_LP, },
+       { RN5T567_LDO5DAC, VDD_LDO5_VAL, },
+       { RN5T567_LDO1DAC_SLP, VDD_IO_INT_VAL_LP, },
+       { RN5T567_LDO2DAC_SLP, VDD_ADC_VAL_LP, },
+       { RN5T567_LDO3DAC_SLP, VDD_PMIC_VAL_LP, },
+       { RN5T567_LDO4DAC_SLP, VDD_CSI_VAL_LP, },
+       { RN5T567_LDOEN1, LDOEN1_VAL, ~LDOEN1_MASK, },
+       { RN5T567_LDOEN2, LDOEN2_VAL, ~LDOEN2_MASK, },
+       { RN5T567_LDODIS, 0x1f, ~0x1f, },
        { RN5T567_INTPOL, 0, },
        { RN5T567_INTEN, 0x3, },
-       { RN5T567_IREN, 0xf, },
+       { RN5T567_DCIREN, 0xf, },
        { RN5T567_EN_GPIR, 0, },
 };
 
@@ -494,7 +511,7 @@ int board_init(void)
        char f = '?';
 
        if (is_cpu_type(MXC_CPU_MX6UL))
-               f = ((cpurev & 0xf0) > 0x10) ? '5' : '0';
+               f = ((cpurev & 0xff) > 0x10) ? '5' : '0';
        else if (is_cpu_type(MXC_CPU_MX6ULL))
                f = '8';
 
@@ -777,6 +794,71 @@ static const struct gpio stk5_gpios[] = {
        { IMX_GPIO_NR(1, 26), GPIOFLAG_OUTPUT_INIT_LOW, "USBOTG VBUS enable", },
 };
 
+static const iomux_v3_cfg_t tx_tester_pads[] = {
+       /* SW controlled LEDs on TX-TESTER-V5 baseboard */
+       MX6_PAD_SNVS_TAMPER4__GPIO5_IO04, /* red LED */
+       MX6_PAD_SNVS_TAMPER9__GPIO5_IO09, /* yellow LED */
+       MX6_PAD_SNVS_TAMPER8__GPIO5_IO08, /* green LED */
+
+       MX6_PAD_LCD_DATA04__GPIO3_IO09, /* IO_RESET */
+
+       /* I2C bus on DIMM pins 40/41 */
+       MX6_PAD_GPIO1_IO01__I2C2_SDA | MUX_MODE_SION | TX6UL_I2C_PAD_CTRL,
+       MX6_PAD_GPIO1_IO00__I2C2_SCL | MUX_MODE_SION | TX6UL_I2C_PAD_CTRL,
+
+       /* USBH1 */
+       MX6_PAD_GPIO1_IO02__USB_OTG2_PWR | TX6UL_GPIO_OUT_PAD_CTRL, /* VBUSEN */
+       MX6_PAD_GPIO1_IO03__USB_OTG2_OC | TX6UL_GPIO_IN_PAD_CTRL, /* OC */
+
+       /* USBOTG */
+       MX6_PAD_UART3_CTS_B__GPIO1_IO26 | TX6UL_GPIO_OUT_PAD_CTRL, /* VBUSEN */
+       MX6_PAD_UART3_RTS_B__GPIO1_IO27 | TX6UL_GPIO_IN_PAD_CTRL, /* OC */
+
+       MX6_PAD_LCD_DATA08__GPIO3_IO13 | TX6UL_GPIO_OUT_PAD_CTRL,
+       MX6_PAD_LCD_DATA09__GPIO3_IO14 | TX6UL_GPIO_OUT_PAD_CTRL,
+       MX6_PAD_LCD_DATA10__GPIO3_IO15 | TX6UL_GPIO_OUT_PAD_CTRL,
+
+       /* USBH_VBUSEN */
+       MX6_PAD_LCD_DATA11__GPIO3_IO16 | TX6UL_GPIO_OUT_PAD_CTRL,
+
+       /*
+        * no drive capability for DUT_ETN_LINKLED, DUT_ETN_ACTLED
+        * to not interfere whith the DUT ETN PHY strap pins
+        */
+       MX6_PAD_SNVS_TAMPER2__GPIO5_IO02, MUX_PAD_CTRL(PAD_CTL_HYS |
+                                                      PAD_CTL_DSE_DISABLE |
+                                                      PAD_CTL_SPEED_LOW),
+       MX6_PAD_SNVS_TAMPER3__GPIO5_IO03, MUX_PAD_CTRL(PAD_CTL_HYS |
+                                                      PAD_CTL_DSE_DISABLE |
+                                                      PAD_CTL_SPEED_LOW),
+};
+
+static const struct gpio tx_tester_gpios[] = {
+       { TX6UL_LED_GPIO, GPIOFLAG_OUTPUT_INIT_LOW, "LEDGE#", },
+       { IMX_GPIO_NR(5, 4), GPIOFLAG_OUTPUT_INIT_LOW, "LEDRT#", },
+       { IMX_GPIO_NR(5, 8), GPIOFLAG_OUTPUT_INIT_LOW, "LEDGN#", },
+
+       { IMX_GPIO_NR(1, 26), GPIOFLAG_OUTPUT_INIT_HIGH, "PMIC PWR_ON", },
+
+       { IMX_GPIO_NR(3, 5), GPIOFLAG_INPUT, "TSTART#", },
+       { IMX_GPIO_NR(3, 6), GPIOFLAG_INPUT, "STARTED", },
+       { IMX_GPIO_NR(3, 7), GPIOFLAG_INPUT, "TSTOP#", },
+       { IMX_GPIO_NR(3, 8), GPIOFLAG_OUTPUT_INIT_LOW, "STOP#", },
+
+       { IMX_GPIO_NR(3, 10), GPIOFLAG_INPUT, "DUT_PGOOD", },
+
+       { IMX_GPIO_NR(3, 11), GPIOFLAG_OUTPUT_INIT_HIGH, "VBACKUP_OFF", },
+       { IMX_GPIO_NR(3, 12), GPIOFLAG_OUTPUT_INIT_LOW, "VBACKUP_LOAD", },
+
+       { IMX_GPIO_NR(1, 10), GPIOFLAG_OUTPUT_INIT_LOW, "VOUTLOAD1", },
+       { IMX_GPIO_NR(3, 30), GPIOFLAG_OUTPUT_INIT_LOW, "VOUTLOAD2", },
+       { IMX_GPIO_NR(3, 31), GPIOFLAG_OUTPUT_INIT_LOW, "VOUTLOAD3", },
+
+       { IMX_GPIO_NR(3, 13), GPIOFLAG_OUTPUT_INIT_LOW, "VIOLOAD1", },
+       { IMX_GPIO_NR(3, 14), GPIOFLAG_OUTPUT_INIT_LOW, "VIOLOAD2", },
+       { IMX_GPIO_NR(3, 15), GPIOFLAG_OUTPUT_INIT_LOW, "VIOLOAD3", },
+};
+
 #ifdef CONFIG_LCD
 vidinfo_t panel_info = {
        /* set to max. size supported by SoC */
@@ -1186,10 +1268,13 @@ void lcd_ctrl_init(void *lcdbase)
                panel_info.vl_bpix = LCD_COLOR32;
        }
 
-       p->pixclock = KHZ2PICOS(refresh *
-               (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
-               (p->yres + p->upper_margin + p->lower_margin + p->vsync_len) /
-                               1000);
+       if (refresh_set || p->pixclock == 0)
+               p->pixclock = KHZ2PICOS(refresh *
+                                       (p->xres + p->left_margin +
+                                        p->right_margin + p->hsync_len) *
+                                       (p->yres + p->upper_margin +
+                                        p->lower_margin + p->vsync_len) /
+                                       1000);
        debug("Pixel clock set to %lu.%03lu MHz\n",
              PICOS2KHZ(p->pixclock) / 1000, PICOS2KHZ(p->pixclock) % 1000);
 
@@ -1293,6 +1378,34 @@ static void stk5v5_board_init(void)
                               TX6UL_GPIO_OUT_PAD_CTRL);
 }
 
+static void tx_tester_board_init(void)
+{
+       int ret;
+
+       setenv("video_mode", NULL);
+       setenv("touchpanel", NULL);
+       if (getenv("eth1addr") && !getenv("ethprime"))
+               setenv("ethprime", "FEC1");
+
+       ret = gpio_request_array(tx_tester_gpios, ARRAY_SIZE(tx_tester_gpios));
+       if (ret) {
+               printf("Failed to request TX-Tester GPIOs: %d\n", ret);
+               return;
+       }
+       imx_iomux_v3_setup_multiple_pads(stk5_pads, ARRAY_SIZE(stk5_pads));
+
+       if (wrsr & WRSR_TOUT)
+               gpio_set_value(IMX_GPIO_NR(5, 4), 1);
+
+       if (getenv_yesno("jtag_enable") != 0) {
+               /* true if unset or set to one of: 'yYtT1' */
+               imx_iomux_v3_setup_multiple_pads(stk5_jtag_pads,
+                                                ARRAY_SIZE(stk5_jtag_pads));
+       }
+
+       gpio_set_value(IMX_GPIO_NR(3, 8), 1);
+}
+
 static void tx6ul_set_cpu_clock(void)
 {
        unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0);
@@ -1366,9 +1479,16 @@ int board_late_init(void)
                                setenv("otg_mode", "none");
                        }
                        stk5_board_init();
+       } else if (strncmp(baseboard, "tx-tester-", 10) == 0) {
+                       const char *otg_mode = getenv("otg_mode");
+
+                       if (!otg_mode || strcmp(otg_mode, "none") != 0)
+                               setenv("otg_mode", "device");
+                       tx_tester_board_init();
        } else {
                printf("WARNING: Unsupported baseboard: '%s'\n",
                        baseboard);
+               printf("Reboot with <CTRL-C> pressed to fix this\n");
                if (!had_ctrlc())
                        return -EINVAL;
        }
@@ -1386,6 +1506,56 @@ exit:
 #define ETH_ALEN 6
 #endif
 
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+{
+       unsigned int mac0, mac1, mac2;
+       unsigned int __maybe_unused fuse3_override, fuse4_override;
+
+       memset(mac, 0, 6);
+
+       switch (dev_id) {
+       case 0:
+               if (fuse_read(4, 2, &mac0)) {
+                       printf("Failed to read MAC0 fuse\n");
+                       return;
+               }
+               if (fuse_read(4, 3, &mac1)) {
+                       printf("Failed to read MAC1 fuse\n");
+                       return;
+               }
+               mac[0] = mac1 >> 8;
+               mac[1] = mac1;
+               mac[2] = mac0 >> 24;
+               mac[3] = mac0 >> 16;
+               mac[4] = mac0 >> 8;
+               mac[5] = mac0;
+               break;
+
+       case 1:
+               if (fuse_read(4, 3, &mac1)) {
+                       printf("Failed to read MAC1 fuse\n");
+                       return;
+               }
+               debug("read %08x from fuse 3\n", mac1);
+               if (fuse_read(4, 4, &mac2)) {
+                       printf("Failed to read MAC2 fuse\n");
+                       return;
+               }
+               debug("read %08x from fuse 4\n", mac2);
+               mac[0] = mac2 >> 24;
+               mac[1] = mac2 >> 16;
+               mac[2] = mac2 >> 8;
+               mac[3] = mac2;
+               mac[4] = mac1 >> 24;
+               mac[5] = mac1 >> 16;
+               break;
+
+       default:
+               return;
+       }
+       debug("%s@%d: Done %d %pM\n", __func__, __LINE__, dev_id, mac);
+}
+
 static void tx6ul_init_mac(void)
 {
        u8 mac[ETH_ALEN];
@@ -1407,7 +1577,8 @@ static void tx6ul_init_mac(void)
        if (getenv("eth1addr"))
                return;
        imx_get_mac_from_fuse(1, mac);
-       eth_setenv_enetaddr("eth1addr", mac);
+       if (is_valid_ethaddr(mac))
+               eth_setenv_enetaddr("eth1addr", mac);
 }
 
 int board_eth_init(bd_t *bis)