2 * Copyright (C) 2012-2013 Lothar Waßmann <LW@KARO-electronics.de>
5 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
24 #include <fdt_support.h>
27 #include <linux/mtd/nand.h>
30 #include <asm/cache.h>
31 #include <asm/omap_common.h>
33 #include <asm/arch/cpu.h>
34 #include <asm/arch/hardware.h>
35 #include <asm/arch/mmc_host_def.h>
36 #include <asm/arch/sys_proto.h>
37 #include <asm/arch/nand.h>
38 #include <asm/arch/clock.h>
40 #include <asm/arch/da8xx-fb.h>
42 #include "../common/karo.h"
44 DECLARE_GLOBAL_DATA_PTR;
46 #define TX48_LED_GPIO AM33XX_GPIO_NR(1, 26)
47 #define TX48_ETH_PHY_RST_GPIO AM33XX_GPIO_NR(3, 8)
48 #define TX48_LCD_RST_GPIO AM33XX_GPIO_NR(1, 19)
49 #define TX48_LCD_PWR_GPIO AM33XX_GPIO_NR(1, 22)
50 #define TX48_LCD_BACKLIGHT_GPIO AM33XX_GPIO_NR(3, 14)
52 #define GMII_SEL (CTRL_BASE + 0x650)
55 #define UART_SYSCFG_OFFSET 0x54
56 #define UART_SYSSTS_OFFSET 0x58
58 #define UART_RESET (0x1 << 1)
59 #define UART_CLK_RUNNING_MASK 0x1
60 #define UART_SMART_IDLE_EN (0x1 << 0x3)
63 #define TSICR_REG 0x54
64 #define TIOCP_CFG_REG 0x10
67 /* RGMII mode define */
68 #define RGMII_MODE_ENABLE 0xA
69 #define RMII_MODE_ENABLE 0x5
70 #define MII_MODE_ENABLE 0x0
72 #define NO_OF_MAC_ADDR 1
75 #define MUX_CFG(value, offset) { \
76 __raw_writel(value, (CTRL_BASE + (offset))); \
79 /* PAD Control Fields */
80 #define SLEWCTRL (0x1 << 6)
81 #define RXACTIVE (0x1 << 5)
82 #define PULLUP_EN (0x1 << 4) /* Pull UP Selection */
83 #define PULLUDEN (0x0 << 3) /* Pull up enabled */
84 #define PULLUDDIS (0x1 << 3) /* Pull up disabled */
85 #define MODE(val) (val)
89 * Field names corresponds to the pad signal name
181 int ecap0_in_pwm0_out;
200 int xdma_event_intr0;
201 int xdma_event_intr1;
305 #define PAD_CTRL_BASE 0x800
306 #define OFFSET(x) (unsigned int) (&((struct pad_signals *) \
310 * Configure the pin mux for the module
312 static inline void tx48_set_pin_mux(const struct pin_mux *pin_mux,
317 for (i = 0; i < num_pins; i++)
318 MUX_CFG(pin_mux[i].val, pin_mux[i].reg_offset);
321 #define PRM_RSTST_GLOBAL_COLD_RST (1 << 0)
322 #define PRM_RSTST_GLOBAL_WARM_SW_RST (1 << 1)
323 #define PRM_RSTST_WDT1_RST (1 << 4)
324 #define PRM_RSTST_EXTERNAL_WARM_RST (1 << 5)
325 #define PRM_RSTST_ICEPICK_RST (1 << 9)
327 static u32 prm_rstst __attribute__((section(".data")));
330 * Basic board specific setup
332 static const struct pin_mux stk5_pads[] = {
334 { OFFSET(gpmc_a10), MODE(7) | PULLUDEN, },
336 { OFFSET(gpmc_a3), MODE(7) | PULLUDEN, },
337 /* LCD POWER_ENABLE */
338 { OFFSET(gpmc_a6), MODE(7) | PULLUDEN, },
339 /* LCD Backlight (PWM) */
340 { OFFSET(mcasp0_aclkx), MODE(7) | PULLUDEN, },
343 static const struct pin_mux stk5_lcd_pads[] = {
345 { OFFSET(lcd_data0), MODE(0) | PULLUDEN, },
346 { OFFSET(lcd_data1), MODE(0) | PULLUDEN, },
347 { OFFSET(lcd_data2), MODE(0) | PULLUDEN, },
348 { OFFSET(lcd_data3), MODE(0) | PULLUDEN, },
349 { OFFSET(lcd_data4), MODE(0) | PULLUDEN, },
350 { OFFSET(lcd_data5), MODE(0) | PULLUDEN, },
351 { OFFSET(lcd_data6), MODE(0) | PULLUDEN, },
352 { OFFSET(lcd_data7), MODE(0) | PULLUDEN, },
353 { OFFSET(lcd_data8), MODE(0) | PULLUDEN, },
354 { OFFSET(lcd_data9), MODE(0) | PULLUDEN, },
355 { OFFSET(lcd_data10), MODE(0) | PULLUDEN, },
356 { OFFSET(lcd_data11), MODE(0) | PULLUDEN, },
357 { OFFSET(lcd_data12), MODE(0) | PULLUDEN, },
358 { OFFSET(lcd_data13), MODE(0) | PULLUDEN, },
359 { OFFSET(lcd_data14), MODE(0) | PULLUDEN, },
360 { OFFSET(lcd_data15), MODE(0) | PULLUDEN, },
361 /* LCD control signals */
362 { OFFSET(lcd_hsync), MODE(0) | PULLUDEN, },
363 { OFFSET(lcd_vsync), MODE(0) | PULLUDEN, },
364 { OFFSET(lcd_pclk), MODE(0) | PULLUDEN, },
365 { OFFSET(lcd_ac_bias_en), MODE(0) | PULLUDEN, },
368 static const struct gpio stk5_gpios[] = {
369 { AM33XX_GPIO_NR(1, 26), GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
372 static const struct gpio stk5_lcd_gpios[] = {
373 { AM33XX_GPIO_NR(1, 19), GPIOF_OUTPUT_INIT_LOW, "LCD RESET", },
374 { AM33XX_GPIO_NR(1, 22), GPIOF_OUTPUT_INIT_LOW, "LCD POWER", },
375 { AM33XX_GPIO_NR(3, 14), GPIOF_OUTPUT_INIT_HIGH, "LCD BACKLIGHT", },
378 static const struct pin_mux stk5v5_pads[] = {
379 /* CAN transceiver control */
380 { OFFSET(gpmc_ad8), MODE(7) | PULLUDEN, },
383 static const struct gpio stk5v5_gpios[] = {
384 { AM33XX_GPIO_NR(0, 22), GPIOF_OUTPUT_INIT_HIGH, "CAN XCVR", },
388 static u16 tx48_cmap[256];
389 vidinfo_t panel_info = {
390 /* set to max. size supported by SoC */
394 .vl_bpix = LCD_COLOR24, /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
398 #define FB_SYNC_OE_LOW_ACT (1 << 31)
399 #define FB_SYNC_CLK_LAT_FALL (1 << 30)
401 static struct fb_videomode tx48_fb_modes[] = {
403 /* Standard VGA timing */
408 .pixclock = KHZ2PICOS(25175),
415 .sync = FB_SYNC_CLK_LAT_FALL,
418 /* Emerging ETV570 640 x 480 display. Syncs low active,
419 * DE high active, 115.2 mm x 86.4 mm display area
420 * VGA compatible timing
426 .pixclock = KHZ2PICOS(25175),
433 .sync = FB_SYNC_CLK_LAT_FALL,
436 /* Emerging ET0350G0DH6 320 x 240 display.
437 * 70.08 mm x 52.56 mm display area.
443 .pixclock = KHZ2PICOS(6500),
444 .left_margin = 68 - 34,
447 .upper_margin = 18 - 3,
450 .sync = FB_SYNC_CLK_LAT_FALL,
453 /* Emerging ET0430G0DH6 480 x 272 display.
454 * 95.04 mm x 53.856 mm display area.
460 .pixclock = KHZ2PICOS(9000),
469 /* Emerging ET0500G0DH6 800 x 480 display.
470 * 109.6 mm x 66.4 mm display area.
476 .pixclock = KHZ2PICOS(33260),
477 .left_margin = 216 - 128,
479 .right_margin = 1056 - 800 - 216,
480 .upper_margin = 35 - 2,
482 .lower_margin = 525 - 480 - 35,
483 .sync = FB_SYNC_CLK_LAT_FALL,
486 /* Emerging ETQ570G0DH6 320 x 240 display.
487 * 115.2 mm x 86.4 mm display area.
493 .pixclock = KHZ2PICOS(6400),
497 .upper_margin = 16, /* 15 according to datasheet */
498 .vsync_len = 3, /* TVP -> 1>x>5 */
499 .lower_margin = 4, /* 4.5 according to datasheet */
500 .sync = FB_SYNC_CLK_LAT_FALL,
503 /* Emerging ET0700G0DH6 800 x 480 display.
504 * 152.4 mm x 91.44 mm display area.
510 .pixclock = KHZ2PICOS(33260),
511 .left_margin = 216 - 128,
513 .right_margin = 1056 - 800 - 216,
514 .upper_margin = 35 - 2,
516 .lower_margin = 525 - 480 - 35,
517 .sync = FB_SYNC_CLK_LAT_FALL,
520 /* unnamed entry for assigning parameters parsed from 'video_mode' string */
528 .sync = FB_SYNC_CLK_LAT_FALL,
532 void *lcd_base; /* Start of framebuffer memory */
533 void *lcd_console_address; /* Start of console buffer */
541 static int lcd_enabled = 1;
543 void lcd_initcolregs(void)
547 void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue)
551 void lcd_enable(void)
554 * global variable from common/lcd.c
555 * Set to 0 here to prevent messages from going to LCD
556 * rather than serial console
561 karo_load_splashimage(1);
563 debug("Switching LCD on\n");
564 gpio_set_value(TX48_LCD_PWR_GPIO, 1);
566 gpio_set_value(TX48_LCD_RST_GPIO, 1);
568 gpio_set_value(TX48_LCD_BACKLIGHT_GPIO, 0);
572 void lcd_disable(void)
575 printf("Disabling LCD\n");
581 static void tx48_lcd_panel_setup(struct da8xx_panel *p,
582 struct fb_videomode *fb)
584 p->pxl_clk = PICOS2KHZ(fb->pixclock) * 1000;
587 p->hbp = fb->left_margin;
588 p->hsw = fb->hsync_len;
589 p->hfp = fb->right_margin;
591 p->height = fb->yres;
592 p->vbp = fb->upper_margin;
593 p->vsw = fb->vsync_len;
594 p->vfp = fb->lower_margin;
596 p->invert_pxl_clk = !!(fb->sync & FB_SYNC_CLK_LAT_FALL);
599 void lcd_panel_disable(void)
602 debug("Switching LCD off\n");
603 gpio_set_value(TX48_LCD_BACKLIGHT_GPIO, 1);
604 gpio_set_value(TX48_LCD_PWR_GPIO, 0);
605 gpio_set_value(TX48_LCD_RST_GPIO, 0);
609 void lcd_ctrl_init(void *lcdbase)
611 int color_depth = 24;
612 const char *video_mode = getenv("video_mode");
616 struct fb_videomode *p = &tx48_fb_modes[0];
617 struct fb_videomode fb_mode;
618 int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
621 debug("LCD disabled\n");
625 if (tstc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
626 debug("Disabling LCD\n");
628 setenv("splashimage", NULL);
634 vm = karo_fdt_set_display(video_mode, "/panel", NULL);
636 debug("Disabling LCD\n");
641 if (karo_fdt_get_fb_mode(working_fdt, vm, &fb_mode) == 0) {
643 debug("Using video mode from FDT\n");
645 if (fb_mode.xres > panel_info.vl_col ||
646 fb_mode.yres > panel_info.vl_row) {
647 printf("video resolution from DT: %dx%d exceeds hardware limits: %dx%d\n",
648 fb_mode.xres, fb_mode.yres,
649 panel_info.vl_col, panel_info.vl_row);
655 debug("Trying compiled-in video modes\n");
656 while (p->name != NULL) {
657 if (strcmp(p->name, vm) == 0) {
658 debug("Using video mode: '%s'\n", p->name);
665 debug("Trying to decode video_mode: '%s'\n", vm);
666 while (*vm != '\0') {
667 if (*vm >= '0' && *vm <= '9') {
670 val = simple_strtoul(vm, &end, 0);
673 if (val > panel_info.vl_col)
674 val = panel_info.vl_col;
676 panel_info.vl_col = val;
678 } else if (!yres_set) {
679 if (val > panel_info.vl_row)
680 val = panel_info.vl_row;
682 panel_info.vl_row = val;
684 } else if (!bpp_set) {
693 printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
694 end - vm, vm, color_depth);
697 } else if (!refresh_set) {
724 if (p->xres == 0 || p->yres == 0) {
725 printf("Invalid video mode: %s\n", getenv("video_mode"));
727 printf("Supported video modes are:");
728 for (p = &tx48_fb_modes[0]; p->name != NULL; p++) {
729 printf(" %s", p->name);
734 if (p->xres > panel_info.vl_col || p->yres > panel_info.vl_row) {
735 printf("video resolution: %dx%d exceeds hardware limits: %dx%d\n",
736 p->xres, p->yres, panel_info.vl_col, panel_info.vl_row);
740 panel_info.vl_col = p->xres;
741 panel_info.vl_row = p->yres;
743 switch (color_depth) {
745 panel_info.vl_bpix = LCD_COLOR8;
748 panel_info.vl_bpix = LCD_COLOR16;
751 panel_info.vl_bpix = LCD_COLOR24;
754 p->pixclock = KHZ2PICOS(refresh *
755 (p->xres + p->left_margin + p->right_margin + p->hsync_len) *
756 (p->yres + p->upper_margin + p->lower_margin + p->vsync_len)
758 debug("Pixel clock set to %lu.%03lu MHz\n",
759 PICOS2KHZ(p->pixclock) / 1000,
760 PICOS2KHZ(p->pixclock) % 1000);
765 debug("Creating new display-timing node from '%s'\n",
767 ret = karo_fdt_create_fb_mode(working_fdt, video_mode, p);
769 printf("Failed to create new display-timing node from '%s': %d\n",
773 gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
774 tx48_set_pin_mux(stk5_lcd_pads, ARRAY_SIZE(stk5_lcd_pads));
776 if (karo_load_splashimage(0) == 0) {
777 struct da8xx_panel da8xx_panel = { };
779 debug("Initializing FB driver\n");
780 tx48_lcd_panel_setup(&da8xx_panel, p);
781 da8xx_video_init(&da8xx_panel, color_depth);
783 debug("Initializing LCD controller\n");
786 debug("Skipping initialization of LCD controller\n");
790 #define lcd_enabled 0
791 #endif /* CONFIG_LCD */
793 static void stk5_board_init(void)
795 tx48_set_pin_mux(stk5_pads, ARRAY_SIZE(stk5_pads));
798 static void stk5v3_board_init(void)
803 static void stk5v5_board_init(void)
806 tx48_set_pin_mux(stk5v5_pads, ARRAY_SIZE(stk5v5_pads));
807 gpio_request_array(stk5v5_gpios, ARRAY_SIZE(stk5v5_gpios));
810 /* called with default environment! */
813 /* mach type passed to kernel */
814 #ifdef CONFIG_OF_LIBFDT
815 gd->bd->bi_arch_number = -1;
817 /* address of boot parameters */
818 gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
823 static void show_reset_cause(u32 prm_rstst)
825 const char *dlm = "";
827 printf("RESET cause: ");
828 if (prm_rstst & PRM_RSTST_GLOBAL_COLD_RST) {
829 printf("%sPOR", dlm);
832 if (prm_rstst & PRM_RSTST_GLOBAL_WARM_SW_RST) {
836 if (prm_rstst & PRM_RSTST_WDT1_RST) {
837 printf("%sWATCHDOG", dlm);
840 if (prm_rstst & PRM_RSTST_EXTERNAL_WARM_RST) {
841 printf("%sWARM", dlm);
844 if (prm_rstst & PRM_RSTST_ICEPICK_RST) {
845 printf("%sJTAG", dlm);
854 /* called with default environment! */
857 prm_rstst = readl(PRM_RSTST);
858 show_reset_cause(prm_rstst);
860 #ifdef CONFIG_OF_LIBFDT
861 printf("Board: Ka-Ro TX48-7020 with FDT support\n");
863 printf("Board: Ka-Ro TX48-7020\n");
869 static void tx48_set_cpu_clock(void)
871 unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0);
873 if (tstc() || (prm_rstst & PRM_RSTST_WDT1_RST))
876 if (cpu_clk == 0 || cpu_clk == mpu_clk_rate() / 1000000)
879 mpu_pll_config_val(cpu_clk);
881 printf("CPU clock set to %lu.%03lu MHz\n",
882 mpu_clk_rate() / 1000000,
883 mpu_clk_rate() / 1000 % 1000);
886 static void tx48_init_mac(void)
888 uint8_t mac_addr[ETH_ALEN];
889 uint32_t mac_hi, mac_lo;
891 /* try reading mac address from efuse */
892 mac_lo = __raw_readl(MAC_ID0_LO);
893 mac_hi = __raw_readl(MAC_ID0_HI);
895 mac_addr[0] = mac_hi & 0xFF;
896 mac_addr[1] = (mac_hi & 0xFF00) >> 8;
897 mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
898 mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
899 mac_addr[4] = mac_lo & 0xFF;
900 mac_addr[5] = (mac_lo & 0xFF00) >> 8;
902 if (!is_valid_ether_addr(mac_addr)) {
903 printf("No valid MAC address programmed\n");
906 printf("MAC addr from fuse: %pM\n", mac_addr);
907 eth_setenv_enetaddr("ethaddr", mac_addr);
910 /* called with environment from NAND or MMC */
911 int board_late_init(void)
914 const char *baseboard;
916 tx48_set_cpu_clock();
919 baseboard = getenv("baseboard");
923 if (strncmp(baseboard, "stk5", 4) == 0) {
924 printf("Baseboard: %s\n", baseboard);
925 if ((strlen(baseboard) == 4) ||
926 strcmp(baseboard, "stk5-v3") == 0) {
928 } else if (strcmp(baseboard, "stk5-v5") == 0) {
931 printf("WARNING: Unsupported STK5 board rev.: %s\n",
935 printf("WARNING: Unsupported baseboard: '%s'\n",
944 #ifdef CONFIG_DRIVER_TI_CPSW
945 static void tx48_phy_init(char *name, int addr)
947 debug("%s: Resetting ethernet PHY\n", __func__);
949 gpio_direction_output(TX48_ETH_PHY_RST_GPIO, 0);
954 gpio_set_value(TX48_ETH_PHY_RST_GPIO, 1);
956 /* Wait for PHY internal POR signal to deassert */
960 static void cpsw_control(int enabled)
962 /* nothing for now */
963 /* TODO : VTP was here before */
966 static struct cpsw_slave_data cpsw_slaves[] = {
968 .slave_reg_ofs = 0x208,
969 .sliver_reg_ofs = 0xd80,
971 .phy_if = PHY_INTERFACE_MODE_RMII,
977 /* Nothing to be done here */
980 static struct cpsw_platform_data cpsw_data = {
981 .mdio_base = CPSW_MDIO_BASE,
982 .cpsw_base = CPSW_BASE,
985 .cpdma_reg_ofs = 0x800,
986 .slaves = ARRAY_SIZE(cpsw_slaves),
987 .slave_data = cpsw_slaves,
988 .ale_reg_ofs = 0xd00,
990 .host_port_reg_ofs = 0x108,
991 .hw_stats_reg_ofs = 0x900,
992 .mac_control = (1 << 5) /* MIIEN */,
993 .control = cpsw_control,
994 .phy_init = tx48_phy_init,
997 .version = CPSW_CTRL_VERSION_2,
1000 int board_eth_init(bd_t *bis)
1002 __raw_writel(RMII_MODE_ENABLE, MAC_MII_SEL);
1003 __raw_writel(0x5D, GMII_SEL);
1004 return cpsw_register(&cpsw_data);
1006 #endif /* CONFIG_DRIVER_TI_CPSW */
1008 void tx48_disable_watchdog(void)
1010 struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
1012 while (readl(&wdtimer->wdtwwps) & (1 << 4))
1014 writel(0xaaaa, &wdtimer->wdtwspr);
1015 while (readl(&wdtimer->wdtwwps) & (1 << 4))
1017 writel(0x5555, &wdtimer->wdtwspr);
1021 LED_STATE_INIT = -1,
1026 void show_activity(int arg)
1028 static int led_state = LED_STATE_INIT;
1031 if (led_state == LED_STATE_INIT) {
1032 last = get_timer(0);
1033 gpio_set_value(TX48_LED_GPIO, 1);
1034 led_state = LED_STATE_ON;
1036 if (get_timer(last) > CONFIG_SYS_HZ) {
1037 last = get_timer(0);
1038 if (led_state == LED_STATE_ON) {
1039 gpio_set_value(TX48_LED_GPIO, 0);
1041 gpio_set_value(TX48_LED_GPIO, 1);
1043 led_state = 1 - led_state;
1048 #ifdef CONFIG_OF_BOARD_SETUP
1049 #ifdef CONFIG_FDT_FIXUP_PARTITIONS
1050 #include <jffs2/jffs2.h>
1051 #include <mtd_node.h>
1052 struct node_info nodes[] = {
1053 { "ti,omap2-nand", MTD_DEV_TYPE_NAND, },
1057 #define fdt_fixup_mtdparts(b,n,c) do { } while (0)
1058 #endif /* CONFIG_FDT_FIXUP_PARTITIONS */
1060 void ft_board_setup(void *blob, bd_t *bd)
1062 const char *baseboard = getenv("baseboard");
1063 int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
1064 const char *video_mode = getenv("video_mode");
1066 fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
1067 fdt_fixup_ethernet(blob);
1069 karo_fdt_fixup_touchpanel(blob);
1070 karo_fdt_fixup_flexcan(blob, stk5_v5);
1072 video_mode = karo_fdt_set_display(video_mode, "/panel", NULL);
1073 karo_fdt_update_fb_mode(blob, video_mode);
1075 tx48_disable_watchdog();
1077 #endif /* CONFIG_OF_BOARD_SETUP */