/*
- * tx48.c
- * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright (C) 2012-2013 Lothar Waßmann <LW@KARO-electronics.de>
*
* based on evm.c
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
#include <asm/arch/hardware.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/sys_proto.h>
-#include <asm/arch/nand.h>
#include <asm/arch/clock.h>
#include <video_fb.h>
#include <asm/arch/da8xx-fb.h>
#define TX48_LCD_RST_GPIO AM33XX_GPIO_NR(1, 19)
#define TX48_LCD_PWR_GPIO AM33XX_GPIO_NR(1, 22)
#define TX48_LCD_BACKLIGHT_GPIO AM33XX_GPIO_NR(3, 14)
+#define TX48_MMC_CD_GPIO AM33XX_GPIO_NR(3, 15)
#define GMII_SEL (CTRL_BASE + 0x650)
#define NO_OF_MAC_ADDR 1
#define ETH_ALEN 6
-#define MUX_CFG(value, offset) { \
- __raw_writel(value, (CTRL_BASE + (offset))); \
- }
-
/* PAD Control Fields */
#define SLEWCTRL (0x1 << 6)
#define RXACTIVE (0x1 << 5)
int i;
for (i = 0; i < num_pins; i++)
- MUX_CFG(pin_mux[i].val, pin_mux[i].reg_offset);
+ writel(pin_mux[i].val, CTRL_BASE + pin_mux[i].reg_offset);
}
#define PRM_RSTST_GLOBAL_COLD_RST (1 << 0)
{ OFFSET(gpmc_a6), MODE(7) | PULLUDEN, },
/* LCD Backlight (PWM) */
{ OFFSET(mcasp0_aclkx), MODE(7) | PULLUDEN, },
+ /* MMC CD */
+ { OFFSET(mcasp0_fsx), MODE(7) | PULLUDEN | PULLUP_EN, },
+};
+
+static const struct gpio stk5_gpios[] = {
+ { TX48_LED_GPIO, GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
+ { TX48_MMC_CD_GPIO, GPIOF_INPUT, "MMC0 CD", },
};
static const struct pin_mux stk5_lcd_pads[] = {
{ OFFSET(lcd_ac_bias_en), MODE(0) | PULLUDEN, },
};
-static const struct gpio stk5_gpios[] = {
- { AM33XX_GPIO_NR(1, 26), GPIOF_OUTPUT_INIT_LOW, "HEARTBEAT LED", },
-};
-
static const struct gpio stk5_lcd_gpios[] = {
{ AM33XX_GPIO_NR(1, 19), GPIOF_OUTPUT_INIT_LOW, "LCD RESET", },
{ AM33XX_GPIO_NR(1, 22), GPIOF_OUTPUT_INIT_LOW, "LCD POWER", },
short console_row;
static int lcd_enabled = 1;
+static int lcd_bl_polarity;
+
+static int lcd_backlight_polarity(void)
+{
+ return lcd_bl_polarity;
+}
void lcd_initcolregs(void)
{
udelay(100);
gpio_set_value(TX48_LCD_RST_GPIO, 1);
udelay(300000);
- gpio_set_value(TX48_LCD_BACKLIGHT_GPIO, 0);
+ gpio_set_value(TX48_LCD_BACKLIGHT_GPIO,
+ lcd_backlight_polarity());
}
}
{
if (lcd_enabled) {
debug("Switching LCD off\n");
- gpio_set_value(TX48_LCD_BACKLIGHT_GPIO, 1);
+ gpio_set_value(TX48_LCD_BACKLIGHT_GPIO,
+ !lcd_backlight_polarity());
gpio_set_value(TX48_LCD_PWR_GPIO, 0);
gpio_set_value(TX48_LCD_RST_GPIO, 0);
}
void lcd_ctrl_init(void *lcdbase)
{
int color_depth = 24;
- char *vm, *v;
+ const char *video_mode = karo_get_vmode(getenv("video_mode"));
+ const char *vm;
unsigned long val;
int refresh = 60;
struct fb_videomode *p = &tx48_fb_modes[0];
return;
}
- if (tstc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
+ if (had_ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
debug("Disabling LCD\n");
lcd_enabled = 0;
setenv("splashimage", NULL);
}
karo_fdt_move_fdt();
+ lcd_bl_polarity = karo_fdt_get_backlight_polarity(working_fdt);
- vm = getenv("video_mode");
- if (vm == NULL) {
+ if (video_mode == NULL) {
debug("Disabling LCD\n");
lcd_enabled = 0;
return;
}
-
- if ((v = strstr(vm, ":")))
- vm = v + 1;
-
- 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);
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));
static void stk5_board_init(void)
{
+ gpio_request_array(stk5_gpios, ARRAY_SIZE(stk5_gpios));
tx48_set_pin_mux(stk5_pads, ARRAY_SIZE(stk5_pads));
}
static void stk5v5_board_init(void)
{
stk5_board_init();
- tx48_set_pin_mux(stk5v5_pads, ARRAY_SIZE(stk5v5_pads));
+
gpio_request_array(stk5v5_gpios, ARRAY_SIZE(stk5v5_gpios));
+ tx48_set_pin_mux(stk5v5_pads, ARRAY_SIZE(stk5v5_pads));
}
/* called with default environment! */
/* address of boot parameters */
gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
+ if (ctrlc())
+ printf("CTRL-C detected\n");
+
return 0;
}
prm_rstst = readl(PRM_RSTST);
show_reset_cause(prm_rstst);
-#ifdef CONFIG_OF_LIBFDT
- printf("Board: Ka-Ro TX48-7020 with FDT support\n");
-#else
printf("Board: Ka-Ro TX48-7020\n");
-#endif
+
timer_init();
return 0;
}
static void tx48_set_cpu_clock(void)
{
unsigned long cpu_clk = getenv_ulong("cpu_clk", 10, 0);
+ unsigned long act_cpu_clk;
- if (tstc() || (prm_rstst & PRM_RSTST_WDT1_RST))
+ if (cpu_clk == 0 || cpu_clk == mpu_clk_rate() / 1000000)
return;
- if (cpu_clk == 0 || cpu_clk == mpu_clk_rate() / 1000000)
+ if (had_ctrlc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
+ if (prm_rstst & PRM_RSTST_WDT1_RST) {
+ printf("Watchdog reset detected; skipping cpu clock change\n");
+ } else {
+ printf("<CTRL-C> detected; skipping cpu clock change\n");
+ }
return;
+ }
mpu_pll_config_val(cpu_clk);
- printf("CPU clock set to %lu.%03lu MHz\n",
- mpu_clk_rate() / 1000000,
- mpu_clk_rate() / 1000 % 1000);
+ act_cpu_clk = mpu_clk_rate();
+ if (cpu_clk * 1000000 != act_cpu_clk) {
+ printf("Failed to set CPU clock to %lu MHz; using %lu.%03lu MHz instead\n",
+ cpu_clk, act_cpu_clk / 1000000,
+ act_cpu_clk / 1000 % 1000);
+ } else {
+ printf("CPU clock set to %lu.%03lu MHz\n",
+ act_cpu_clk / 1000000, act_cpu_clk / 1000 % 1000);
+ }
}
static void tx48_init_mac(void)
baseboard);
ret = -EINVAL;
}
+
exit:
tx48_init_mac();
+ clear_ctrlc();
return ret;
}
}
#endif /* CONFIG_DRIVER_TI_CPSW */
+#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
+int cpu_mmc_init(bd_t *bis)
+{
+ return omap_mmc_init(1, 0, 0, TX48_MMC_CD_GPIO, -1);
+}
+#endif
+
void tx48_disable_watchdog(void)
{
struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
#ifdef CONFIG_FDT_FIXUP_PARTITIONS
#include <jffs2/jffs2.h>
#include <mtd_node.h>
-struct node_info nodes[] = {
+static struct node_info nodes[] = {
{ "ti,omap2-nand", MTD_DEV_TYPE_NAND, },
+ { "ti,am3352-gpmc", MTD_DEV_TYPE_NAND, },
};
#else
#define fdt_fixup_mtdparts(b,n,c) do { } while (0)
#endif /* CONFIG_FDT_FIXUP_PARTITIONS */
+static const char *tx48_touchpanels[] = {
+ "ti,tsc2007",
+ "edt,edt-ft5x06",
+ "ti,am3359-tscadc",
+};
+
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 = karo_get_vmode(getenv("video_mode"));
+ int ret;
+
+ ret = fdt_increase_size(blob, 4096);
+ if (ret)
+ printf("Failed to increase FDT size: %s\n", fdt_strerror(ret));
fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
fdt_fixup_ethernet(blob);
- karo_fdt_fixup_touchpanel(blob);
+ karo_fdt_fixup_touchpanel(blob, tx48_touchpanels,
+ ARRAY_SIZE(tx48_touchpanels));
+ karo_fdt_fixup_usb_otg(blob, "usb0", "phys", "vcc-supply");
karo_fdt_fixup_flexcan(blob, stk5_v5);
+ karo_fdt_update_fb_mode(blob, video_mode);
+
tx48_disable_watchdog();
}
#endif /* CONFIG_OF_BOARD_SETUP */