X-Git-Url: https://git.karo-electronics.de/?a=blobdiff_plain;f=board%2Fkaro%2Ftx6%2Ftx6qdl.c;h=08dd9dd2a549cc81ddd431120283551591a19d06;hb=2f4f0e7e9a042f8a6302c5a941986d0d6d3337c0;hp=e748111bb754f1a7f0e252f9e4c3151c03f8eb64;hpb=fe7efb2d95028bc6cab111a2af9290099ffaee0c;p=karo-tx-uboot.git diff --git a/board/karo/tx6/tx6qdl.c b/board/karo/tx6/tx6qdl.c index e748111bb7..08dd9dd2a5 100644 --- a/board/karo/tx6/tx6qdl.c +++ b/board/karo/tx6/tx6qdl.c @@ -336,7 +336,7 @@ static int tx6_rev_2(void) struct fuse_bank5_regs *fuse = (void *)ocotp->bank[5].fuse_regs; u32 pad_settings = readl(&fuse->pad_settings); - debug("Fuse pad_settings @ %p = %08x\n", + debug("Fuse pad_settings @ %p = %02x\n", &fuse->pad_settings, pad_settings); return pad_settings & 1; } @@ -425,15 +425,13 @@ int board_init(void) /* Address of boot parameters */ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x1000; -#ifdef CONFIG_OF_LIBFDT gd->bd->bi_arch_number = -1; -#else - gd->bd->bi_arch_number = 4429; -#endif + if (ctrlc()) { printf("CTRL-C detected; Skipping PMIC setup\n"); return 1; } + ret = setup_pmic_voltages(); if (ret) { printf("Failed to setup PMIC voltages\n"); @@ -516,9 +514,7 @@ static struct tx6_esdhc_cfg { static inline struct tx6_esdhc_cfg *to_tx6_esdhc_cfg(struct fsl_esdhc_cfg *cfg) { - void *p = cfg; - - return p - offsetof(struct tx6_esdhc_cfg, cfg); + return container_of(cfg, struct tx6_esdhc_cfg, cfg); } int board_mmc_getcd(struct mmc *mmc) @@ -543,9 +539,6 @@ int board_mmc_init(bd_t *bis) struct tx6_esdhc_cfg *cfg = &tx6qdl_esdhc_cfg[i]; int ret; - if (i >= CONFIG_SYS_FSL_ESDHC_NUM) - break; - cfg->cfg.sdhc_clk = mxc_get_clock(cfg->clkid); imx_iomux_v3_setup_multiple_pads(cfg->pads, cfg->num_pads); @@ -705,15 +698,18 @@ static const struct gpio stk5_gpios[] = { }; #ifdef CONFIG_LCD +static u16 tx6_cmap[256]; vidinfo_t panel_info = { /* set to max. size supported by SoC */ .vl_col = 1920, .vl_row = 1080, .vl_bpix = LCD_COLOR24, /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */ + .cmap = tx6_cmap, }; static struct fb_videomode tx6_fb_modes[] = { +#ifndef CONFIG_SYS_LVDS_IF { /* Standard VGA timing */ .name = "VGA", @@ -832,6 +828,25 @@ static struct fb_videomode tx6_fb_modes[] = { .lower_margin = 525 - 480 - 35, .sync = FB_SYNC_CLK_LAT_FALL, }, +#else + { + /* HannStar HSD100PXN1 + * 202.7m mm x 152.06 mm display area. + */ + .name = "HSD100PXN1", + .refresh = 60, + .xres = 1024, + .yres = 768, + .pixclock = KHZ2PICOS(65000), + .left_margin = 0, + .hsync_len = 0, + .right_margin = 320, + .upper_margin = 0, + .vsync_len = 0, + .lower_margin = 38, + .sync = FB_SYNC_CLK_LAT_FALL, + }, +#endif { /* unnamed entry for assigning parameters parsed from 'video_mode' string */ .refresh = 60, @@ -846,6 +861,12 @@ static struct fb_videomode tx6_fb_modes[] = { }; static int lcd_enabled = 1; +static int lcd_bl_polarity; + +static int lcd_backlight_polarity(void) +{ + return lcd_bl_polarity; +} void lcd_enable(void) { @@ -864,7 +885,8 @@ void lcd_enable(void) udelay(100); gpio_set_value(TX6_LCD_RST_GPIO, 1); udelay(300000); - gpio_set_value(TX6_LCD_BACKLIGHT_GPIO, 0); + gpio_set_value(TX6_LCD_BACKLIGHT_GPIO, + lcd_backlight_polarity()); } } @@ -880,7 +902,8 @@ void lcd_panel_disable(void) { if (lcd_enabled) { debug("Switching LCD off\n"); - gpio_set_value(TX6_LCD_BACKLIGHT_GPIO, 1); + gpio_set_value(TX6_LCD_BACKLIGHT_GPIO, + !lcd_backlight_polarity()); gpio_set_value(TX6_LCD_RST_GPIO, 0); gpio_set_value(TX6_LCD_PWR_GPIO, 0); } @@ -934,15 +957,15 @@ static const struct gpio stk5_lcd_gpios[] = { void lcd_ctrl_init(void *lcdbase) { int color_depth = 24; - const char *video_mode = getenv("video_mode"); + const char *video_mode = karo_get_vmode(getenv("video_mode")); const char *vm; unsigned long val; int refresh = 60; struct fb_videomode *p = &tx6_fb_modes[0]; struct fb_videomode fb_mode; int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0; - int pix_fmt = 0; - ipu_di_clk_parent_t di_clk_parent = DI_PCLK_PLL3; + int pix_fmt; + int lcd_bus_width; unsigned long di_clk_rate = 65000000; if (!lcd_enabled) { @@ -958,15 +981,15 @@ void lcd_ctrl_init(void *lcdbase) } karo_fdt_move_fdt(); + lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt); - vm = karo_fdt_set_display(video_mode, "", "/soc/aips-bus/ldb"); - if (vm == NULL) { + if (video_mode == NULL) { debug("Disabling LCD\n"); lcd_enabled = 0; return; } - video_mode = vm; - if (karo_fdt_get_fb_mode(working_fdt, vm, &fb_mode) == 0) { + vm = video_mode; + if (karo_fdt_get_fb_mode(working_fdt, video_mode, &fb_mode) == 0) { p = &fb_mode; debug("Using video mode from FDT\n"); vm += strlen(vm); @@ -1013,7 +1036,7 @@ void lcd_ctrl_init(void *lcdbase) switch (val) { case 32: case 24: - if (pix_fmt == IPU_PIX_FMT_LVDS666) + if (is_lvds()) pix_fmt = IPU_PIX_FMT_LVDS888; /* fallthru */ case 16: @@ -1022,7 +1045,7 @@ void lcd_ctrl_init(void *lcdbase) break; case 18: - if (pix_fmt == IPU_PIX_FMT_LVDS666) { + if (is_lvds()) { color_depth = val; break; } @@ -1055,19 +1078,6 @@ void lcd_ctrl_init(void *lcdbase) break; default: - if (!pix_fmt) { - char *tmp; - - if (strncmp(vm, "LVDS", 4) == 0) { - pix_fmt = IPU_PIX_FMT_LVDS666; - di_clk_parent = DI_PCLK_LDB; - } else { - pix_fmt = IPU_PIX_FMT_RGB24; - } - tmp = strchr(vm, ':'); - if (tmp) - vm = tmp; - } if (*vm != '\0') vm++; } @@ -1104,11 +1114,10 @@ void lcd_ctrl_init(void *lcdbase) 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); + (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); + PICOS2KHZ(p->pixclock) / 1000, PICOS2KHZ(p->pixclock) % 1000); if (p != &fb_mode) { int ret; @@ -1125,25 +1134,56 @@ void lcd_ctrl_init(void *lcdbase) imx_iomux_v3_setup_multiple_pads(stk5_lcd_pads, ARRAY_SIZE(stk5_lcd_pads)); - debug("Initializing FB driver\n"); - if (!pix_fmt) - pix_fmt = IPU_PIX_FMT_RGB24; - else if (pix_fmt == IPU_PIX_FMT_LVDS666) { - writel(0x01, IOMUXC_BASE_ADDR + 8); - } else if (pix_fmt == IPU_PIX_FMT_LVDS888) { - writel(0x21, IOMUXC_BASE_ADDR + 8); - } - if (pix_fmt != IPU_PIX_FMT_RGB24) { - struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - /* enable LDB & DI0 clock */ - writel(readl(&ccm_regs->CCGR3) | MXC_CCM_CCGR3_LDB_DI0_MASK | - MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK, - &ccm_regs->CCGR3); + lcd_bus_width = karo_fdt_get_lcd_bus_width(working_fdt, 24); + switch (lcd_bus_width) { + case 24: + pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS888 : IPU_PIX_FMT_RGB24; + break; + + case 18: + pix_fmt = is_lvds() ? IPU_PIX_FMT_LVDS666 : IPU_PIX_FMT_RGB666; + break; + + case 16: + if (!is_lvds()) { + pix_fmt = IPU_PIX_FMT_RGB565; + break; + } + /* fallthru */ + default: + lcd_enabled = 0; + printf("Invalid %s bus width: %d\n", is_lvds() ? "LVDS" : "LCD", + lcd_bus_width); + return; } + if (is_lvds()) { + int lvds_mapping = karo_fdt_get_lvds_mapping(working_fdt, 0); + int lvds_chan_mask = karo_fdt_get_lvds_channels(working_fdt); + uint32_t gpr2; + + if (lvds_chan_mask == 0) { + printf("No LVDS channel active\n"); + lcd_enabled = 0; + return; + } + gpr2 = (lvds_mapping << 6) | (lvds_mapping << 8); + if (lcd_bus_width == 24) + gpr2 |= (1 << 5) | (1 << 7); + gpr2 |= (lvds_chan_mask & 1) ? 1 << 0 : 0; + gpr2 |= (lvds_chan_mask & 2) ? 3 << 2 : 0; + debug("writing %08x to GPR2[%08x]\n", gpr2, IOMUXC_BASE_ADDR + 8); + writel(gpr2, IOMUXC_BASE_ADDR + 8); + } if (karo_load_splashimage(0) == 0) { + int ret; + debug("Initializing LCD controller\n"); - ipuv3_fb_init(p, 0, pix_fmt, di_clk_parent, di_clk_rate, -1); + ret = ipuv3_fb_init(p, 0, pix_fmt, DI_PCLK_PLL3, di_clk_rate, -1); + if (ret) { + printf("Failed to initialize FB driver: %d\n", ret); + lcd_enabled = 0; + } } else { debug("Skipping initialization of LCD controller\n"); } @@ -1187,7 +1227,7 @@ static void tx6qdl_set_cpu_clock(void) printf("CPU clock set to %lu.%03lu MHz\n", cpu_clk / 1000000, cpu_clk / 1000 % 1000); } else { - printf("Failed to set CPU clock to %lu MHz\n", cpu_clk); + printf("Error: Failed to set CPU clock to %lu MHz\n", cpu_clk); } } @@ -1201,8 +1241,8 @@ static void tx6_init_mac(void) return; } - eth_setenv_enetaddr("ethaddr", mac); printf("MAC addr from fuse: %pM\n", mac); + eth_setenv_enetaddr("ethaddr", mac); } int board_late_init(void) @@ -1257,10 +1297,10 @@ int checkboard(void) tx6qdl_print_cpuinfo(); - printf("Board: Ka-Ro TX6%c-%dx1%d\n", + printf("Board: Ka-Ro TX6%c-%d%d1%d\n", cpu_variant == MXC_CPU_MX6Q ? 'Q' : 'U', cpu_variant == MXC_CPU_MX6Q ? 1 : 8, - 1 - PHYS_SDRAM_1_WIDTH / 64); + is_lvds(), 1 - PHYS_SDRAM_1_WIDTH / 64); return 0; } @@ -1280,30 +1320,36 @@ void get_board_serial(struct tag_serialnr *serialnr) #ifdef CONFIG_FDT_FIXUP_PARTITIONS #include #include -struct node_info nodes[] = { +static struct node_info nodes[] = { { "fsl,imx6q-gpmi-nand", MTD_DEV_TYPE_NAND, }, }; - #else #define fdt_fixup_mtdparts(b,n,c) do { } while (0) #endif +static const char *tx6_touchpanels[] = { + "ti,tsc2007", + "edt,edt-ft5x06", + "eeti,egalax_ts", +}; + 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"); + const char *video_mode = karo_get_vmode(getenv("video_mode")); - karo_fdt_enable_node(blob, "stk5led", !stk5_v5); + if (stk5_v5) + karo_fdt_enable_node(blob, "stk5led", 0); fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes)); fdt_fixup_ethernet(blob); - karo_fdt_fixup_touchpanel(blob); + karo_fdt_fixup_touchpanel(blob, tx6_touchpanels, + ARRAY_SIZE(tx6_touchpanels)); karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy"); 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 /* CONFIG_OF_BOARD_SETUP */