]> git.karo-electronics.de Git - karo-tx-uboot.git/blobdiff - board/karo/tx6/tx6qdl.c
karo: tx6: changed module suffix from -.xx. to -.x1. for distinction of future eMMC...
[karo-tx-uboot.git] / board / karo / tx6 / tx6qdl.c
index 15324068d4c412c82287b5f2242b89da8071bf0a..80b3626a75e99452c6e696e4c76dd757cb109a8e 100644 (file)
@@ -225,23 +225,54 @@ static void tx6qdl_print_cpuinfo(void)
        check_cpu_temperature(1);
 }
 
+#define LTC3676_BUCK1          0x01
+#define LTC3676_BUCK2          0x02
+#define LTC3676_BUCK3          0x03
+#define LTC3676_BUCK4          0x04
 #define LTC3676_DVB2A          0x0C
 #define LTC3676_DVB2B          0x0D
 #define LTC3676_DVB4A          0x10
 #define LTC3676_DVB4B          0x11
+#define LTC3676_CLIRQ          0x1f
 
 #define VDD_SOC_mV             (1375 + 50)
 #define VDD_CORE_mV            (1375 + 50)
 
+#define LTC3676_BUCK_DVDT_FAST (1 << 0)
+#define LTC3676_BUCK_KEEP_ALIVE        (1 << 1)
+#define LTC3676_BUCK_CLK_RATE_LOW      (1 << 2)
+#define LTC3676_BUCK_PHASE_SEL (1 << 3)
+#define LTC3676_BUCK_ENABLE_300        (1 << 4)
+#define LTC3676_BUCK_PULSE_SKIP        (0 << 5)
+#define LTC3676_BUCK_BURST_MODE        (1 << 5)
+#define LTC3676_BUCK_CONTINUOUS        (2 << 5)
+#define LTC3676_BUCK_ENABLE    (1 << 7)
+
+#define LTC3676_PGOOD_MASK     (1 << 5)
+
 #define mV_to_regval(mV)       (((mV) * 360 / 330 - 825 + 1) / 25)
 #define regval_to_mV(v)                (((v) * 25 + 825) * 330 / 360)
 
+static struct pmic_regs {
+       u8 addr;
+       u8 val;
+} ltc3676_regs[] = {
+       { LTC3676_DVB2B, mV_to_regval(900) | LTC3676_PGOOD_MASK, },
+       { LTC3676_DVB4B, mV_to_regval(900) | LTC3676_PGOOD_MASK, },
+       { LTC3676_DVB2A, mV_to_regval(VDD_SOC_mV), },
+       { LTC3676_DVB4A, mV_to_regval(VDD_CORE_mV), },
+       { LTC3676_BUCK1, LTC3676_BUCK_BURST_MODE | LTC3676_BUCK_CLK_RATE_LOW, },
+       { LTC3676_BUCK2, LTC3676_BUCK_BURST_MODE | LTC3676_BUCK_CLK_RATE_LOW, },
+       { LTC3676_BUCK3, LTC3676_BUCK_BURST_MODE | LTC3676_BUCK_CLK_RATE_LOW, },
+       { LTC3676_BUCK4, LTC3676_BUCK_BURST_MODE | LTC3676_BUCK_CLK_RATE_LOW, },
+       { LTC3676_CLIRQ, 0, }, /* clear interrupt status */
+};
+
 static int setup_pmic_voltages(void)
 {
        int ret;
        unsigned char value;
-
-       i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+       int i;
 
        ret = i2c_probe(CONFIG_SYS_I2C_SLAVE);
        if (ret != 0) {
@@ -255,41 +286,17 @@ static int setup_pmic_voltages(void)
                return ret;
        }
 
-       /* VDDCORE/VDDSOC default 1.375V is not enough, considering
-          pfuze tolerance and IR drop and ripple, need increase
-          to 1.425V for SabreSD */
-
-       value = 0x39; /* VB default value & PGOOD not forced when slewing */
-       ret = i2c_write(CONFIG_SYS_I2C_SLAVE, LTC3676_DVB2B, 1, &value, 1);
-       if (ret) {
-               printf("%s: failed to write PMIC DVB2B register: %d\n",
-                       __func__, ret);
-               return ret;
-       }
-       ret = i2c_write(CONFIG_SYS_I2C_SLAVE, LTC3676_DVB4B, 1, &value, 1);
-       if (ret) {
-               printf("%s: failed to write PMIC DVB4B register: %d\n",
-                       __func__, ret);
-               return ret;
-       }
-
-       value = mV_to_regval(VDD_SOC_mV);
-       ret = i2c_write(CONFIG_SYS_I2C_SLAVE, LTC3676_DVB2A, 1, &value, 1);
-       if (ret) {
-               printf("%s: failed to write PMIC DVB2A register: %d\n",
-                       __func__, ret);
-               return ret;
-       }
-       printf("VDDSOC  set to %dmV\n", regval_to_mV(value));
-
-       value = mV_to_regval(VDD_CORE_mV);
-       ret = i2c_write(CONFIG_SYS_I2C_SLAVE, LTC3676_DVB4A, 1, &value, 1);
-       if (ret) {
-               printf("%s: failed to write PMIC DVB4A register: %d\n",
-                       __func__, ret);
-               return ret;
+       for (i = 0; i < ARRAY_SIZE(ltc3676_regs); i++) {
+               ret = i2c_write(CONFIG_SYS_I2C_SLAVE, ltc3676_regs[i].addr, 1,
+                               &ltc3676_regs[i].val, 1);
+               if (ret) {
+                       printf("%s: failed to write PMIC register %02x: %d\n",
+                               __func__, ltc3676_regs[i].addr, ret);
+                       return ret;
+               }
        }
-       printf("VDDCORE set to %dmV\n", regval_to_mV(value));
+       printf("VDDCORE set to %dmV\n", VDD_CORE_mV);
+       printf("VDDSOC  set to %dmV\n", VDD_SOC_mV);
        return 0;
 }
 
@@ -812,7 +819,8 @@ static const struct gpio stk5_lcd_gpios[] = {
 void lcd_ctrl_init(void *lcdbase)
 {
        int color_depth = 24;
-       char *vm;
+       const char *video_mode = getenv("video_mode");
+       const char *vm;
        unsigned long val;
        int refresh = 60;
        struct fb_videomode *p = &tx6_fb_modes[0];
@@ -830,25 +838,31 @@ void lcd_ctrl_init(void *lcdbase)
        if (tstc() || (wrsr & WRSR_TOUT)) {
                debug("Disabling LCD\n");
                lcd_enabled = 0;
+               setenv("splashimage", NULL);
                return;
        }
 
        karo_fdt_move_fdt();
 
-       vm = getenv("video_mode");
+       vm = karo_fdt_set_display(video_mode, "", "/soc/aips-bus/ldb");
        if (vm == NULL) {
                debug("Disabling LCD\n");
                lcd_enabled = 0;
                return;
        }
+       video_mode = vm;
        if (karo_fdt_get_fb_mode(working_fdt, vm, &fb_mode) == 0) {
                p = &fb_mode;
                debug("Using video mode from FDT\n");
                vm += strlen(vm);
-               if (fb_mode.xres < panel_info.vl_col)
-                       panel_info.vl_col = fb_mode.xres;
-               if (fb_mode.yres < panel_info.vl_row)
-                       panel_info.vl_row = fb_mode.yres;
+               if (fb_mode.xres > panel_info.vl_col ||
+                       fb_mode.yres > panel_info.vl_row) {
+                       printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
+                               fb_mode.xres, fb_mode.yres,
+                               panel_info.vl_col, panel_info.vl_row);
+                       lcd_enabled = 0;
+                       return;
+               }
        }
        if (p->name != NULL)
                debug("Trying compiled-in video modes\n");
@@ -953,6 +967,25 @@ void lcd_ctrl_init(void *lcdbase)
                printf("\n");
                return;
        }
+       if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
+               printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
+                       p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
+               lcd_enabled = 0;
+               return;
+       }
+       panel_info.vl_col = p->xres;
+       panel_info.vl_row = p->yres;
+
+       switch (color_depth) {
+       case 8:
+               panel_info.vl_bpix = LCD_COLOR8;
+               break;
+       case 16:
+               panel_info.vl_bpix = LCD_COLOR16;
+               break;
+       default:
+               panel_info.vl_bpix = LCD_COLOR24;
+       }
 
        p->pixclock = KHZ2PICOS(refresh *
                (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
@@ -964,14 +997,13 @@ void lcd_ctrl_init(void *lcdbase)
 
        if (p != &fb_mode) {
                int ret;
-               char *modename = getenv("video_mode");
 
-               printf("Creating new display-timing node from '%s'\n",
-                       modename);
-               ret = karo_fdt_create_fb_mode(working_fdt, modename, p);
+               debug("Creating new display-timing node from '%s'\n",
+                       video_mode);
+               ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
                if (ret)
                        printf("Failed to create new display-timing node from '%s': %d\n",
-                               modename, ret);
+                               video_mode, ret);
        }
 
        gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
@@ -1109,7 +1141,7 @@ int checkboard(void)
 
        tx6qdl_print_cpuinfo();
 
-       printf("Board: Ka-Ro TX6%c-%dxx%d\n",
+       printf("Board: Ka-Ro TX6%c-%dx1%d\n",
                cpu_variant == MXC_CPU_MX6Q ? 'Q' : 'U',
                cpu_variant == MXC_CPU_MX6Q ? 1 : 8,
                1 - PHYS_SDRAM_1_WIDTH / 64);
@@ -1140,85 +1172,11 @@ struct node_info nodes[] = {
 #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
 #endif
 
-static int flexcan_enabled(void *blob)
-{
-       const char *can_ifs[] = {
-               "can0",
-               "can1",
-       };
-       size_t i;
-
-       for (i = 0; i < ARRAY_SIZE(can_ifs); i++) {
-               const char *status;
-               int off = fdt_path_offset(blob, can_ifs[i]);
-
-               if (off < 0) {
-                       debug("node '%s' not found\n", can_ifs[i]);
-                       continue;
-               }
-               status = fdt_getprop(blob, off, "status", NULL);
-               if (strcmp(status, "okay") == 0) {
-                       debug("%s is enabled\n", can_ifs[i]);
-                       return 1;
-               }
-       }
-       debug("can driver is disabled\n");
-       return 0;
-}
-
-static void tx6qdl_set_lcd_pins(void *blob, const char *name)
-{
-       int off = fdt_path_offset(blob, name);
-       u32 ph;
-       const struct fdt_property *pc;
-       int len;
-
-       if (off < 0)
-               return;
-
-       ph = fdt_create_phandle(blob, off);
-       if (!ph)
-               return;
-
-       off = fdt_path_offset(blob, "display");
-       if (off < 0)
-               return;
-
-       pc = fdt_get_property(blob, off, "pinctrl-0", &len);
-       if (!pc || len < sizeof(ph))
-               return;
-
-       memcpy((void *)pc->data, &ph, sizeof(ph));
-       fdt_setprop_cell(blob, off, "pinctrl-0", ph);
-}
-
-static void tx6qdl_fixup_flexcan(void *blob, int stk5_v5)
-{
-       const char *xcvr_status = "disabled";
-
-       if (stk5_v5) {
-               if (flexcan_enabled(blob)) {
-                       tx6qdl_set_lcd_pins(blob, "lcdif_23bit_pins_a");
-                       xcvr_status = "okay";
-               } else {
-                       tx6qdl_set_lcd_pins(blob, "lcdif_24bit_pins_a");
-               }
-       } else {
-               const char *otg_mode = getenv("otg_mode");
-
-               if (otg_mode && (strcmp(otg_mode, "host") == 0))
-                       karo_fdt_enable_node(blob, "can1", 0);
-
-               tx6qdl_set_lcd_pins(blob, "lcdif_24bit_pins_a");
-       }
-       fdt_find_and_setprop(blob, "/regulators/can-xcvr", "status",
-                       xcvr_status, strlen(xcvr_status) + 1, 1);
-}
-
 void ft_board_setup(void *blob, bd_t *bd)
 {
        const char *baseboard = getenv("baseboard");
        int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+       const char *video_mode = getenv("video_mode");
 
        karo_fdt_enable_node(blob, "stk5led", !stk5_v5);
 
@@ -1227,7 +1185,9 @@ void ft_board_setup(void *blob, bd_t *bd)
 
        karo_fdt_fixup_touchpanel(blob);
        karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy");
-       tx6qdl_fixup_flexcan(blob, stk5_v5);
-       karo_fdt_update_fb_mode(blob, getenv("video_mode"));
+       karo_fdt_fixup_flexcan(blob, stk5_v5);
+
+       video_mode = karo_fdt_set_display(video_mode, "", "/soc/aips-bus/ldb");
+       karo_fdt_update_fb_mode(blob, video_mode);
 }
-#endif
+#endif /* CONFIG_OF_BOARD_SETUP */