#include <libfdt.h>
#include <fdt_support.h>
#include <nand.h>
+#include <mxcfb.h>
#include <linux/list.h>
#include <linux/fb.h>
#include <jffs2/load_kernel.h>
continue;
}
fdt_disable_tp_node(blob, karo_touchpanels[i]);
- karo_set_fdtsize(blob);
}
+ karo_set_fdtsize(blob);
}
void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy)
prop = fdt_getprop(blob, off, "vsync-active", NULL);
if (prop)
fb_mode->sync |= *prop ? FB_SYNC_VERT_HIGH_ACT : 0;
-#if 0
+#if defined(CONFIG_MX51) || defined(CONFIG_MX53) || defined(CONFIG_MX6)
prop = fdt_getprop(blob, off, "de-active", NULL);
if (prop)
- fb_mode->sync |= *prop ? FB_SYNC_DATA_ENABLE_HIGH_ACT : 0;
+ fb_mode->sync |= *prop ? 0 : FB_SYNC_OE_LOW_ACT;
prop = fdt_getprop(blob, off, "pixelclk-active", NULL);
if (prop)
- fb_mode->sync |= *prop ? FB_SYNC_DOTCLK_FALLING_ACT : 0;
+ fb_mode->sync |= *prop ? 0 : FB_SYNC_CLK_LAT_FALL;
#endif
return 0;
}
int ret;
uint32_t ph;
+ ret = fdt_increase_size(blob, 32);
+ if (ret) {
+ printf("Warning: Failed to increase FDT size: %d\n", ret);
+ }
debug("Creating phandle at offset %d\n", off);
ph = fdt_create_phandle(blob, off);
- if (!ph) {
- ret = fdt_increase_size(blob, 512);
- if (ret) {
- printf("Failed to increase FDT size: %d\n", ret);
- return ret;
- }
- ph = fdt_create_phandle(blob, off);
- }
if (!ph) {
printf("Failed to create phandle for video timing\n");
return -ENOMEM;
}
}
if (off > 0) {
- fdt_init_fb_mode(blob, off, fb_mode);
- return fdt_update_native_fb_mode(blob, off);
+ return fdt_init_fb_mode(blob, off, fb_mode);
}
return -EINVAL;
}
if (ret)
goto out;
- /* TOTO: make these configurable */
+#if defined(CONFIG_MX51) || defined(CONFIG_MX53) || defined(CONFIG_MX6)
+ ret = SET_FB_PROP("de-active",
+ !(fb_mode->sync & FB_SYNC_OE_LOW_ACT));
+ if (ret)
+ goto out;
+ ret = SET_FB_PROP("pixelclk-active",
+ !(fb_mode->sync & FB_SYNC_CLK_LAT_FALL));
+ if (ret)
+ goto out;
+#else
+ /* TODO: make these configurable */
ret = SET_FB_PROP("de-active", 1);
if (ret)
goto out;
ret = SET_FB_PROP("pixelclk-active", 1);
if (ret)
goto out;
-
- return fdt_update_native_fb_mode(blob, off);
-
+#endif
out:
karo_set_fdtsize(blob);
return ret;
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
dcd_len:
.long dcd_end - dcd_start
dcd_start:
- DCDGEN(4, CCM_BASE_ADDR + REG_CCGR0, 0xffcffffc);
- DCDGEN(4, CCM_BASE_ADDR + REG_CCGR1, 0x003fffff);
- DCDGEN(4, CCM_BASE_ADDR + REG_CCGR2, 0x030c003c);
- DCDGEN(4, CCM_BASE_ADDR + REG_CCGR3, 0x000000ff);
- DCDGEN(4, CCM_BASE_ADDR + REG_CCGR4, 0x00000000);
- DCDGEN(4, CCM_BASE_ADDR + REG_CCGR5, 0x003fc003);
- DCDGEN(4, CCM_BASE_ADDR + REG_CCGR6, 0x00000000);
- DCDGEN(4, CCM_BASE_ADDR + REG_CMEOR, 0x00000000);
-
DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDCTL0, 0x80000000)
DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDSCR, 0x04008008)
DCDGEN(4, ESDCTL_BASE_ADDR + REG_ESDSCR, 0x00008010)
/*
- * Copyright (C) 2011 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright (C) 2011-2013 Lothar Waßmann <LW@KARO-electronics.de>
* based on: board/freescale/mx28_evk.c (C) 2010 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
#define FEC_PAD_CTRL MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_DSE_HIGH | \
PAD_CTL_SRE_FAST)
#define FEC_PAD_CTRL2 MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_SRE_FAST)
-#define GPIO_PAD_CTRL MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_DSE_HIGH)
+#define GPIO_PAD_CTRL MUX_PAD_CTRL(PAD_CTL_DVS | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP)
static iomux_v3_cfg_t tx51_pads[] = {
/* NAND flash pads are set up in lowlevel_init.S */
int board_early_init_f(void)
{
- struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)MXC_CCM_BASE;
+ struct mxc_ccm_reg *ccm_regs = (void *)CCM_BASE_ADDR;
-#ifdef CONFIG_CMD_BOOTCE
- /* WinCE fails to enable these clocks */
- writel(readl(&ccm_regs->CCGR2) | 0x0c000000, &ccm_regs->CCGR2); /* usboh3_ipg_ahb */
- writel(readl(&ccm_regs->CCGR4) | 0x30000000, &ccm_regs->CCGR4); /* srtc */
- writel(readl(&ccm_regs->CCGR6) | 0x00000300, &ccm_regs->CCGR6); /* emi_garb */
-#endif
gpio_request_array(tx51_gpios, ARRAY_SIZE(tx51_gpios));
imx_iomux_v3_setup_multiple_pads(tx51_pads, ARRAY_SIZE(tx51_pads));
writel(0x00000000, AIPS2_BASE_ADDR + 0x4c);
writel(0x00000000, AIPS2_BASE_ADDR + 0x50);
+ writel(0xffcffffc, &ccm_regs->CCGR0);
+ writel(0x003fffff, &ccm_regs->CCGR1);
+ writel(0x030c003c, &ccm_regs->CCGR2);
+ writel(0x000000ff, &ccm_regs->CCGR3);
+ writel(0x00000000, &ccm_regs->CCGR4);
+ writel(0x003fc003, &ccm_regs->CCGR5);
+ writel(0x00000000, &ccm_regs->CCGR6);
+ writel(0x00000000, &ccm_regs->cmeor);
+#ifdef CONFIG_CMD_BOOTCE
+ /* WinCE fails to enable these clocks */
+ writel(readl(&ccm_regs->CCGR2) | 0x0c000000, &ccm_regs->CCGR2); /* usboh3_ipg_ahb */
+ writel(readl(&ccm_regs->CCGR4) | 0x30000000, &ccm_regs->CCGR4); /* srtc */
+ writel(readl(&ccm_regs->CCGR6) | 0x00000300, &ccm_regs->CCGR6); /* emi_garb */
+#endif
return 0;
}
MX51_PAD_SD1_DATA2__SD1_DATA2,
MX51_PAD_SD1_DATA3__SD1_DATA3,
/* SD1 CD */
- MX51_PAD_DISPB2_SER_RS__GPIO3_8 | MUX_PAD_CTRL(PAD_CTL_PUE | PAD_CTL_PKE),
+ MX51_PAD_DISPB2_SER_RS__GPIO3_8 | GPIO_PAD_CTRL,
};
static const iomux_v3_cfg_t mmc1_pads[] = {
MX51_PAD_SD2_DATA2__SD2_DATA2,
MX51_PAD_SD2_DATA3__SD2_DATA3,
/* SD2 CD */
- MX51_PAD_DISPB2_SER_DIO__GPIO3_6 | MUX_PAD_CTRL(PAD_CTL_PUE | PAD_CTL_PKE),
+ MX51_PAD_DISPB2_SER_DIO__GPIO3_6 | GPIO_PAD_CTRL,
};
static struct tx51_esdhc_cfg {
.num_pads = ARRAY_SIZE(mmc0_pads),
.cfg = {
.esdhc_base = (void __iomem *)MMC_SDHC1_BASE_ADDR,
+ .max_bus_width = 4,
},
.cd_gpio = IMX_GPIO_NR(3, 8),
},
.num_pads = ARRAY_SIZE(mmc1_pads),
.cfg = {
.esdhc_base = (void __iomem *)MMC_SDHC2_BASE_ADDR,
+ .max_bus_width = 4,
},
.cd_gpio = IMX_GPIO_NR(3, 6),
},
};
-static struct tx51_esdhc_cfg *to_tx51_esdhc_cfg(struct fsl_esdhc_cfg *cfg)
-{
- return container_of(cfg, struct tx51_esdhc_cfg, cfg);
-}
+#define to_tx51_esdhc_cfg(p) container_of(p, struct tx51_esdhc_cfg, cfg)
int board_mmc_getcd(struct mmc *mmc)
{
static const iomux_v3_cfg_t stk5_pads[] = {
/* SW controlled LED on STK5 baseboard */
- MX51_PAD_CSI2_D13__GPIO4_10,
+ MX51_PAD_CSI2_D13__GPIO4_10 | GPIO_PAD_CTRL,
/* USB PHY reset */
- MX51_PAD_GPIO1_4__GPIO1_4,
+ MX51_PAD_GPIO1_4__GPIO1_4 | GPIO_PAD_CTRL,
/* USBOTG OC */
- MX51_PAD_GPIO1_6__GPIO1_6,
+ MX51_PAD_GPIO1_6__GPIO1_6 | GPIO_PAD_CTRL,
/* USB PHY clock enable */
- MX51_PAD_GPIO1_7__GPIO1_7,
+ MX51_PAD_GPIO1_7__GPIO1_7 | GPIO_PAD_CTRL,
/* USBH1 VBUS enable */
- MX51_PAD_GPIO1_8__GPIO1_8,
+ MX51_PAD_GPIO1_8__GPIO1_8 | GPIO_PAD_CTRL,
/* USBH1 OC */
- MX51_PAD_GPIO1_9__GPIO1_9,
+ MX51_PAD_GPIO1_9__GPIO1_9 | GPIO_PAD_CTRL,
};
static const struct gpio stk5_gpios[] = {
};
#ifdef CONFIG_LCD
-static ushort tx51_cmap[256];
vidinfo_t panel_info = {
/* set to max. size supported by SoC */
.vl_col = 1600,
.vl_row = 1200,
.vl_bpix = LCD_COLOR24, /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
- .cmap = tx51_cmap,
};
static struct fb_videomode tx51_fb_modes[] = {
*/
lcd_is_enabled = 0;
- karo_load_splashimage(1);
if (lcd_enabled) {
+ karo_load_splashimage(1);
+
debug("Switching LCD on\n");
gpio_set_value(TX51_LCD_PWR_GPIO, 1);
udelay(100);
void lcd_disable(void)
{
- printf("Disabling LCD\n");
+ if (lcd_enabled) {
+ printf("Disabling LCD\n");
+ ipuv3_fb_shutdown();
+ }
}
void lcd_panel_disable(void)
if (tstc() || (wrsr & WRSR_TOUT)) {
debug("Disabling LCD\n");
lcd_enabled = 0;
+ setenv("splashimage", NULL);
return;
}
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");
case 8:
case 16:
case 24:
+ case 32:
color_depth = val;
break;
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;
+ }
+ printf("xres=%d left_margin=%d right_margin=%d hsync_len=%d yres=%d upper_margin=%d lower_margin=%d vsync_len=%d\n",
+ p->xres, p->left_margin, p->right_margin, p->hsync_len,
+ p->yres, p->upper_margin, p->lower_margin, p->vsync_len);
p->pixclock = KHZ2PICOS(refresh *
(p->xres + p->left_margin + p->right_margin + p->hsync_len) *
PICOS2KHZ(p->pixclock) / 1000,
PICOS2KHZ(p->pixclock) % 1000);
+ 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);
+ if (ret)
+ printf("Failed to create new display-timing node from '%s': %d\n",
+ modename, ret);
+ }
+
gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
imx_iomux_v3_setup_multiple_pads(stk5_lcd_pads,
ARRAY_SIZE(stk5_lcd_pads));
pix_fmt = IPU_PIX_FMT_RGB24;
if (karo_load_splashimage(0) == 0) {
+ int ret;
struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)MXC_CCM_BASE;
u32 ccgr4 = readl(&ccm_regs->CCGR4);
/* MIPI HSC clock is required for initialization */
writel(ccgr4 | (3 << 12), &ccm_regs->CCGR4);
- debug("Initializing LCD controller\n");
- ipuv3_fb_init(p, 0, pix_fmt, di_clk_parent, di_clk_rate, -1);
+ gd->arch.ipu_hw_rev = IPUV3_HW_REV_IPUV3DEX;
+ debug("Initializing LCD controller\n");
+ ret = ipuv3_fb_init(p, 0, pix_fmt, di_clk_parent, di_clk_rate, -1);
writel(ccgr4 & ~(3 << 12), &ccm_regs->CCGR4);
+ if (ret) {
+ printf("Failed to initialize FB driver: %d\n", ret);
+ lcd_enabled = 0;
+ }
} else {
debug("Skipping initialization of LCD controller\n");
}
karo_fdt_fixup_touchpanel(blob);
karo_fdt_fixup_usb_otg(blob, "fsl,imx-otg", "fsl,usbphy");
+ karo_fdt_update_fb_mode(blob, getenv("video_mode"));
}
#endif
/*
- * Copyright (C) 2011 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright (C) 2011-2013 Lothar Waßmann <LW@KARO-electronics.de>
* based on: board/freescale/mx28_evk.c (C) 2010 Freescale Semiconductor, Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
},
};
-#if 1
#define to_tx53_esdhc_cfg(p) container_of(p, struct tx53_esdhc_cfg, cfg)
-#else
-static struct tx53_esdhc_cfg *to_tx53_esdhc_cfg(struct fsl_esdhc_cfg *cfg)
-{
- void *p = cfg;
-
- return p - offsetof(struct tx53_esdhc_cfg, cfg);
-}
-#endif
int board_mmc_getcd(struct mmc *mmc)
{
};
#ifdef CONFIG_LCD
-static ushort tx53_cmap[256];
vidinfo_t panel_info = {
/* set to max. size supported by SoC */
.vl_col = 1600,
.vl_row = 1200,
.vl_bpix = LCD_COLOR24, /* Bits per pixel, 0: 1bpp, 1: 2bpp, 2: 4bpp, 3: 8bpp ... */
- .cmap = tx53_cmap,
};
static struct fb_videomode tx53_fb_modes[] = {
*/
lcd_is_enabled = 0;
- karo_load_splashimage(1);
if (lcd_enabled) {
+ karo_load_splashimage(1);
+
debug("Switching LCD on\n");
gpio_set_value(TX53_LCD_PWR_GPIO, 1);
udelay(100);
void lcd_disable(void)
{
- printf("Disabling LCD\n");
+ if (lcd_enabled) {
+ printf("Disabling LCD\n");
+ ipuv3_fb_shutdown();
+ }
}
void lcd_panel_disable(void)
if (tstc() || (wrsr & WRSR_TOUT)) {
debug("Disabling LCD\n");
lcd_enabled = 0;
+ setenv("splashimage", NULL);
return;
}
PICOS2KHZ(p->pixclock) / 1000,
PICOS2KHZ(p->pixclock) % 1000);
+ 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);
+ if (ret)
+ printf("Failed to create new display-timing node from '%s': %d\n",
+ modename, ret);
+ }
+
gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
imx_iomux_v3_setup_multiple_pads(stk5_lcd_pads,
ARRAY_SIZE(stk5_lcd_pads));
}
if (karo_load_splashimage(0) == 0) {
+ int ret;
+
+ gd->arch.ipu_hw_rev = IPUV3_HW_REV_IPUV3M;
+
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_clk_parent, 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");
}
static inline void tx53_fixup_rtc(void *blob)
{
}
-#endif
+#endif /* CONFIG_SYS_TX53_HWREV_2 */
void ft_board_setup(void *blob, bd_t *bd)
{
fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
fdt_fixup_ethernet(blob);
- karo_fdt_enable_node(blob, "ipu", getenv("video_mode") != NULL);
karo_fdt_fixup_touchpanel(blob);
karo_fdt_fixup_usb_otg(blob, "fsl,imx-otg", "fsl,usbphy");
tx53_fixup_flexcan(blob);
tx53_fixup_rtc(blob);
+ karo_fdt_update_fb_mode(blob, getenv("video_mode"));
}
-#endif
+#endif /* CONFIG_OF_BOARD_SETUP */
}
U_BOOT_CMD(romupdate, 11, 0, do_update,
- "Creates an FCB data structure and writes an U-Boot image to flash\n",
+ "Creates an FCB data structure and writes an U-Boot image to flash",
"[-f #] [-r [#]] [-e #] [<address>] [<length>]\n"
"\t-f #\twrite bootloader image at block #\n"
"\t-r\twrite redundant bootloader image at next free block after first image\n"
/*
- * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright (C) 2012,2013 Lothar Waßmann <LW@KARO-electronics.de>
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
*/
#include <common.h>
void lcd_disable(void)
{
- printf("Disabling LCD\n");
+ if (lcd_enabled) {
+ printf("Disabling LCD\n");
+ ipuv3_fb_shutdown();
+ }
}
void lcd_panel_disable(void)
PICOS2KHZ(p->pixclock) / 1000,
PICOS2KHZ(p->pixclock) % 1000);
+ 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);
+ if (ret)
+ printf("Failed to create new display-timing node from '%s': %d\n",
+ modename, ret);
+ }
+
gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
imx_iomux_v3_setup_multiple_pads(stk5_lcd_pads,
ARRAY_SIZE(stk5_lcd_pads));
strcmp(baseboard, "stk5-v3") == 0) {
stk5v3_board_init();
} else if (strcmp(baseboard, "stk5-v5") == 0) {
+ const char *otg_mode = getenv("otg_mode");
+
+ if (otg_mode && strcmp(otg_mode, "host") == 0) {
+ printf("otg_mode='%s' is incompatible with baseboard %s; setting to 'none'\n",
+ otg_mode, baseboard);
+ setenv("otg_mode", "none");
+ }
stk5v5_board_init();
} else {
printf("WARNING: Unsupported STK5 board rev.: %s\n",
#define fdt_fixup_mtdparts(b,n,c) do { } while (0)
#endif
-static void tx6qdl_fixup_flexcan(void *blob)
+static int flexcan_enabled(void *blob)
{
- const char *baseboard = getenv("baseboard");
+ 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;
- if (baseboard && strcmp(baseboard, "stk5-v5") == 0)
+ ph = fdt_create_phandle(blob, off);
+ if (!ph)
return;
- karo_fdt_del_prop(blob, "fsl,p1010-flexcan", 0x02090000, "transceiver-switch");
- karo_fdt_del_prop(blob, "fsl,p1010-flexcan", 0x02094000, "transceiver-switch");
+ 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);
+
+ karo_fdt_enable_node(blob, "stk5led", !stk5_v5);
+
fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
fdt_fixup_ethernet(blob);
karo_fdt_fixup_touchpanel(blob);
karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy");
- tx6qdl_fixup_flexcan(blob);
+ tx6qdl_fixup_flexcan(blob, stk5_v5);
karo_fdt_update_fb_mode(blob, getenv("video_mode"));
}
#endif
}
U_BOOT_CMD(
bootce, 2, 0, do_bootce,
- "Boot a Windows CE image from RAM\n",
+ "Boot a Windows CE image from RAM",
"[addr]\n"
- "\taddr\t\tboot image from address addr (default ${fileaddr})\n"
+ "\taddr\t\tboot image from address addr (default ${fileaddr})"
);
static int ce_nand_load(ce_bin *bin, loff_t *offset, void *buf, size_t max_len)
break;
}
} while (ret == CE_PR_MORE);
+ free(buffer);
if (ret != CE_PR_EOF)
return CMD_RET_FAILURE;
- free(buffer);
if (getenv_yesno("autostart") != 1) {
/*
* just use bootce to load the image to SDRAM;
}
U_BOOT_CMD(
nbootce, 2, 0, do_nbootce,
- "Boot a Windows CE image from NAND\n",
+ "Boot a Windows CE image from NAND",
"off|partitition\n"
"\toff\t\t- flash offset (hex)\n"
- "\tpartition\t- partition name\n"
+ "\tpartition\t- partition name"
);
static int ce_send_write_ack(ce_net *net)
} else {
int rc = ce_send_write_ack(net);
- printf("Dropping out of sequence packet with ID %d (expected %d)\n",
- blknum, nxt);
+ if (net->verbose)
+ printf("Dropping out of sequence packet with ID %d (expected %d)\n",
+ blknum, nxt);
if (rc != 0)
return rc;
net->state = BOOTME_DEBUG;
}
-debug("%s@%d\n", __func__, __LINE__);
switch (header.cmd) {
case EDBG_CMD_JUMPIMG:
-debug("%s@%d\n", __func__, __LINE__);
net->gotJumpingRequest = 1;
if (net->verbose) {
printf("Received JUMPING command\n");
}
/* Just pass through and copy CONFIG structure */
+ ret = BOOTME_DONE;
case EDBG_CMD_OS_CONFIG:
-debug("%s@%d\n", __func__, __LINE__);
/* Copy config structure */
- memcpy(&bin->edbgConfig, header.data,
+ memcpy(&bin->edbgConfig, &net->data[sizeof(header)],
sizeof(edbg_os_config_data));
if (net->verbose) {
printf("Received CONFIG command\n");
printf("--> Force clean boot\n");
}
}
- ret = BOOTME_DEBUG;
break;
default:
/* Respond with ack */
header.flags = EDBG_FL_FROM_DEV | EDBG_FL_ACK;
+ memcpy(net->data, &header, sizeof(header));
net->dataLen = EDBG_DATA_OFFSET;
-debug("%s@%d: sending packet %p len %u\n", __func__, __LINE__,
- net->data, net->dataLen);
- bootme_send_frame(net->data, net->dataLen);
- return ret;
+
+ int retries = 10;
+ int rc;
+ do {
+ rc = bootme_send_frame(net->data, net->dataLen);
+ if (rc != 0) {
+ printf("Failed to send ACK: %d\n", rc);
+ }
+ } while (rc && retries-- > 0);
+ return rc ?: ret;
}
static enum bootme_state ce_edbg_handler(const void *buf, size_t len)
i++;
if (argc > i) {
timeout = simple_strtoul(argv[i],
- NULL, 10);
+ NULL, 0);
if (timeout >= UINT_MAX / CONFIG_SYS_HZ) {
printf("Timeout value %lu out of range (max.: %lu)\n",
timeout, UINT_MAX / CONFIG_SYS_HZ - 1);
server_ip = string_to_ip(argv[i]);
printf("Using server %pI4\n", &server_ip);
} else {
- printf("Option requires an argument - t\n");
+ printf("Option requires an argument - h\n");
return CMD_RET_USAGE;
}
}
}
U_BOOT_CMD(
ceconnect, 6, 1, do_ceconnect,
- "Set up a connection to the CE host PC over TCP/IP and download the run-time image\n",
+ "Set up a connection to the CE host PC over TCP/IP and download the run-time image",
"[-v] [-t <timeout>] [-h host]\n"
" -v - verbose operation\n"
" -t <timeout> - max wait time (#sec) for the connection\n"
enum bootme_state {
BOOTME_INIT,
BOOTME_DOWNLOAD,
+ BOOTME_DEBUG_INIT,
BOOTME_DEBUG,
BOOTME_DONE,
BOOTME_ERROR,
DECLARE_GLOBAL_DATA_PTR;
-#define WINCE_VRAM_BASE 0x80000000
-#define CE_FIX_ADDRESS(a) ((void *)((a) - WINCE_VRAM_BASE + CONFIG_SYS_SDRAM_BASE))
-
-#ifndef INT_MAX
-#define INT_MAX ((int)(~0 >> 1))
-#endif
-
-/* Bin image parse states */
-#define CE_PS_RTI_ADDR 0
-#define CE_PS_RTI_LEN 1
-#define CE_PS_E_ADDR 2
-#define CE_PS_E_LEN 3
-#define CE_PS_E_CHKSUM 4
-#define CE_PS_E_DATA 5
-
-#define CE_MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define CE_MAX(a, b) (((a) > (b)) ? (a) : (b))
-
-#define _STRMAC(s) #s
-#define STRMAC(s) _STRMAC(s)
-
static enum bootme_state bootme_state;
static int bootme_src_port = 0xdeadface;
static int bootme_dst_port = 0xdeadbeef;
static uchar bootme_ether[ETH_ALEN];
static IPaddr_t bootme_ip;
static int bootme_timed_out;
-//static size_t input_len, input_size;
-//static void *input_packet;
static const char *output_packet; /* used by first send udp */
static int output_packet_len;
static unsigned long bootme_timeout;
static void bootme_timeout_handler(void)
{
+ printf("%s\n", __func__);
net_set_state(NETLOOP_SUCCESS);
bootme_timed_out++;
}
uchar *eth_pkt = pkt;
unsigned eth_len = len;
static char cursor = '|';
- enum bootme_state last_state = BOOTME_INIT;
-#if 1
+ enum bootme_state last_state = bootme_state;
+
debug("received packet of len %d from %pI4:%d to port %d\n",
len, &src_ip, src_port, dest_port);
ce_dump_block(pkt, len);
-#endif
+
if (!bootme_packet_handler) {
printf("No packet handler set for BOOTME protocol; dropping packet\n");
return;
printf("%c\x08", cursor);
cursor = next_cursor(cursor);
- if (is_broadcast(bootme_ip)) {
- bootme_ip = src_ip;
- } else if (src_ip != bootme_ip) {
+ if (!is_broadcast(bootme_ip) && src_ip != bootme_ip) {
debug("src_ip %pI4 does not match destination IP %pI4\n",
&src_ip, &bootme_ip);
return; /* not from our server */
}
-
- last_state = bootme_state;
- bootme_dst_port = src_port;
- debug("bootme_dst_port set to %d\n", bootme_dst_port);
+ if (bootme_state == BOOTME_INIT || bootme_state == BOOTME_DEBUG_INIT) {
+ struct ethernet_hdr *eth = (struct ethernet_hdr *)(pkt -
+ NetEthHdrSize() - IP_UDP_HDR_SIZE);
+ memcpy(bootme_ether, eth->et_src, sizeof(bootme_ether));
+ printf("Target MAC address set to %pM\n", bootme_ether);
+
+ if (is_broadcast(bootme_ip)) {
+ NetCopyIP(&bootme_ip, &src_ip);
+ }
+ }
if (bootme_state == BOOTME_INIT) {
bootme_src_port = EDBG_SVC_PORT;
debug("%s: bootme_src_port set to %d\n", __func__, bootme_src_port);
}
+
+ debug("bootme_dst_port %d -> %d\n", bootme_dst_port, src_port);
+ bootme_dst_port = src_port;
+
bootme_state = bootme_packet_handler(eth_pkt, eth_len);
debug("bootme_packet_handler() returned %d\n", bootme_state);
if (bootme_state != last_state)
- debug("bootme_state: %d -> %d\n", last_state, bootme_state);
+ debug("%s@%d: bootme_state: %d -> %d\n", __func__, __LINE__,
+ last_state, bootme_state);
switch (bootme_state) {
case BOOTME_INIT:
+ case BOOTME_DEBUG_INIT:
break;
case BOOTME_DOWNLOAD:
NetBootFileXferSize += len - 4;
/* fallthru */
case BOOTME_DEBUG:
- if (last_state == BOOTME_INIT) {
+ if (last_state == BOOTME_INIT ||
+ last_state == BOOTME_DEBUG_INIT)
bootme_timeout = 3 * 1000;
- }
NetSetTimeout(bootme_timeout, bootme_timeout_handler);
break;
assert(NetTxPacket != NULL);
pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
memcpy(pkt, output_packet, output_packet_len);
+ debug("%s@%d: Sending ARP request:\n", __func__, __LINE__);
+ ce_dump_block(pkt, output_packet_len);
NetSendUDPPacket(bootme_ether, bootme_ip, bootme_dst_port,
bootme_src_port, output_packet_len);
+ output_packet_len = 0;
}
}
{
int ret;
struct eth_device *eth;
- int inited = 0;
uchar *pkt;
eth = eth_get_dev();
if (eth == NULL)
return -EINVAL;
- if (bootme_state == BOOTME_INIT)
+ if (bootme_state == BOOTME_INIT || bootme_state == BOOTME_DEBUG_INIT)
check_net_config();
debug("%s: buf: %p len: %u from %pI4:%d to %pI4:%d\n",
- __func__, buf, len, &NetOurIP, bootme_src_port, &bootme_ip, bootme_dst_port);
+ __func__, buf, len, &NetOurIP, bootme_src_port, &bootme_ip,
+ bootme_dst_port);
if (memcmp(bootme_ether, NetEtherNullAddr, ETH_ALEN) == 0) {
- if (eth->state == ETH_STATE_ACTIVE)
- return 0; /* inside net loop */
-
output_packet = buf;
output_packet_len = len;
/* wait for arp reply and send packet */
return 0;
}
- if (eth->state != ETH_STATE_ACTIVE) {
- if (eth_is_on_demand_init()) {
- ret = eth_init(gd->bd);
- if (ret < 0)
- return ret;
- eth_set_last_protocol(BOOTME);
- } else {
- eth_init_state_only(gd->bd);
- }
- inited = 1;
- }
-
assert(NetTxPacket != NULL);
pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
memcpy(pkt, buf, len);
ret = NetSendUDPPacket(bootme_ether, bootme_ip, bootme_dst_port,
bootme_src_port, len);
- if (inited) {
- debug("Stopping network\n");
- if (eth_is_on_demand_init())
- eth_halt();
- else
- eth_halt_state_only();
- }
+ if (ret)
+ printf("Failed to send packet: %d\n", ret);
+
return ret;
}
static void bootme_init(IPaddr_t server_ip)
{
+ debug("%s@%d: bootme_state: %d -> %d\n", __func__, __LINE__,
+ bootme_state, BOOTME_INIT);
bootme_state = BOOTME_INIT;
bootme_ip = server_ip;
/* force reconfiguration in check_net_config() */
bootme_packet_handler = handler;
bootme_init(bootme_ip);
- bootme_state = BOOTME_DEBUG;
+ debug("%s@%d: bootme_state: %d -> %d\n", __func__, __LINE__,
+ bootme_state, BOOTME_DEBUG_INIT);
+ bootme_state = BOOTME_DEBUG_INIT;
+
bootme_timeout = 3 * 1000;
NetSetTimeout(bootme_timeout, bootme_timeout_handler);