writel(CLKCTRL_PLL2CTRL0_CLKGATE,
&clkctrl_regs->hw_clkctrl_pll2ctrl0_clr);
+ udelay(6000);
return 0;
}
#endif
writel(reg, &iomuxc_regs->gpr1);
}
-#if 1
void cpu_cache_initialization(void)
{
printf("Enabling L2 cache\n");
: : : "r0", "memory"
);
}
-#endif
#ifdef CONFIG_MX53
void boot_mode_apply(unsigned cfg_val)
#if defined(CONFIG_MX51)
#define IRAM_BASE_ADDR 0x1FFE0000 /* internal ram */
#define IPU_SOC_BASE_ADDR 0x40000000
-#define IPU_SOC_OFFSET 0x1E000000
#define SPBA0_BASE_ADDR 0x70000000
#define AIPS1_BASE_ADDR 0x73F00000
#define AIPS2_BASE_ADDR 0x83F00000
#define NFC_BASE_ADDR_AXI 0xCFFF0000
#define CS1_BASE_ADDR 0xB8000000
#elif defined(CONFIG_MX53)
-#define IPU_SOC_BASE_ADDR 0x18000000
-#define IPU_SOC_OFFSET 0x06000000
+#define IPU_SOC_BASE_ADDR 0x00000000
#define SPBA0_BASE_ADDR 0x50000000
#define AIPS1_BASE_ADDR 0x53F00000
#define AIPS2_BASE_ADDR 0x63F00000
MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
- MX6_PAD_SD3_DAT5__GPIO_7_0 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+ MX6_PAD_SD3_DAT5__GPIO_7_0, /* CD */
};
iomux_v3_cfg_t const usdhc4_pads[] = {
MX6_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
- MX6_PAD_NANDF_D6__GPIO_2_6 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+ MX6_PAD_NANDF_D6__GPIO_2_6, /* CD */
};
iomux_v3_cfg_t const enet_pads1[] = {
MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
/* pin 35 - 1 (PHY_AD2) on reset */
- MX6_PAD_RGMII_RXC__GPIO_6_30 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_RGMII_RXC__GPIO_6_30,
/* pin 32 - 1 - (MODE0) all */
- MX6_PAD_RGMII_RD0__GPIO_6_25 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_RGMII_RD0__GPIO_6_25,
/* pin 31 - 1 - (MODE1) all */
- MX6_PAD_RGMII_RD1__GPIO_6_27 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_RGMII_RD1__GPIO_6_27,
/* pin 28 - 1 - (MODE2) all */
- MX6_PAD_RGMII_RD2__GPIO_6_28 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_RGMII_RD2__GPIO_6_28,
/* pin 27 - 1 - (MODE3) all */
- MX6_PAD_RGMII_RD3__GPIO_6_29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_RGMII_RD3__GPIO_6_29,
/* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
- MX6_PAD_RGMII_RX_CTL__GPIO_6_24 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_RGMII_RX_CTL__GPIO_6_24,
/* pin 42 PHY nRST */
- MX6_PAD_EIM_D23__GPIO_3_23 | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_ENET_RXD0__GPIO_1_27 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_EIM_D23__GPIO_3_23,
+ MX6_PAD_ENET_RXD0__GPIO_1_27,
};
iomux_v3_cfg_t const enet_pads2[] = {
}
iomux_v3_cfg_t const usb_pads[] = {
- MX6_PAD_GPIO_17__GPIO_7_12 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_GPIO_17__GPIO_7_12,
};
static void setup_iomux_uart(void)
static iomux_v3_cfg_t const backlight_pads[] = {
/* Backlight on RGB connector: J15 */
- MX6_PAD_SD1_DAT3__GPIO_1_21 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_SD1_DAT3__GPIO_1_21,
#define RGB_BACKLIGHT_GP IMX_GPIO_NR(1, 21)
/* Backlight on LVDS connector: J6 */
- MX6_PAD_SD1_CMD__GPIO_1_18 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_SD1_CMD__GPIO_1_18,
#define LVDS_BACKLIGHT_GP IMX_GPIO_NR(1, 18)
};
MX6_PAD_SD4_DAT5__USDHC4_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD4_DAT6__USDHC4_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD4_DAT7__USDHC4_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
- MX6_PAD_NANDF_D6__GPIO_2_6 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+ MX6_PAD_NANDF_D6__GPIO_2_6, /* CD */
};
static void setup_iomux_uart(void)
MX6_PAD_RGMII_RD3__ENET_RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
/* AR8031 PHY Reset */
- MX6_PAD_ENET_CRS_DV__GPIO_1_25 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_ENET_CRS_DV__GPIO_1_25,
};
static void setup_iomux_enet(void)
MX6_PAD_NANDF_D5__USDHC2_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_NANDF_D6__USDHC2_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_NANDF_D7__USDHC2_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
- MX6_PAD_NANDF_D2__GPIO_2_2 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+ MX6_PAD_NANDF_D2__GPIO_2_2, /* CD */
};
iomux_v3_cfg_t const usdhc3_pads[] = {
MX6_PAD_SD3_DAT5__USDHC3_DAT5 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD3_DAT6__USDHC3_DAT6 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD3_DAT7__USDHC3_DAT7 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
- MX6_PAD_NANDF_D0__GPIO_2_0 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+ MX6_PAD_NANDF_D0__GPIO_2_0, /* CD */
};
iomux_v3_cfg_t const usdhc4_pads[] = {
MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
- MX6_PAD_SD3_DAT5__GPIO_7_0 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
+ MX6_PAD_SD3_DAT5__GPIO_7_0, /* CD */
};
iomux_v3_cfg_t const enet_pads1[] = {
MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
/* pin 35 - 1 (PHY_AD2) on reset */
- MX6_PAD_RGMII_RXC__GPIO_6_30 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_RGMII_RXC__GPIO_6_30,
/* pin 32 - 1 - (MODE0) all */
- MX6_PAD_RGMII_RD0__GPIO_6_25 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_RGMII_RD0__GPIO_6_25,
/* pin 31 - 1 - (MODE1) all */
- MX6_PAD_RGMII_RD1__GPIO_6_27 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_RGMII_RD1__GPIO_6_27,
/* pin 28 - 1 - (MODE2) all */
- MX6_PAD_RGMII_RD2__GPIO_6_28 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_RGMII_RD2__GPIO_6_28,
/* pin 27 - 1 - (MODE3) all */
- MX6_PAD_RGMII_RD3__GPIO_6_29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_RGMII_RD3__GPIO_6_29,
/* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
- MX6_PAD_RGMII_RX_CTL__GPIO_6_24 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_RGMII_RX_CTL__GPIO_6_24,
/* pin 42 PHY nRST */
- MX6_PAD_EIM_D23__GPIO_3_23 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_EIM_D23__GPIO_3_23,
};
iomux_v3_cfg_t const enet_pads2[] = {
};
iomux_v3_cfg_t nfc_pads[] = {
- MX6_PAD_NANDF_CLE__RAWNAND_CLE | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_ALE__RAWNAND_ALE | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_WP_B__RAWNAND_RESETN | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_RB0__RAWNAND_READY0 | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_CS0__RAWNAND_CE0N | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_CS1__RAWNAND_CE1N | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_CS2__RAWNAND_CE2N | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_CS3__RAWNAND_CE3N | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_SD4_CMD__RAWNAND_RDN | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_SD4_CLK__RAWNAND_WRN | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_D0__RAWNAND_D0 | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_D1__RAWNAND_D1 | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_D2__RAWNAND_D2 | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_D3__RAWNAND_D3 | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_D4__RAWNAND_D4 | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_D5__RAWNAND_D5 | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_D6__RAWNAND_D6 | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_NANDF_D7__RAWNAND_D7 | MUX_PAD_CTRL(NO_PAD_CTRL),
- MX6_PAD_SD4_DAT0__RAWNAND_DQS | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_NANDF_CLE__RAWNAND_CLE,
+ MX6_PAD_NANDF_ALE__RAWNAND_ALE,
+ MX6_PAD_NANDF_WP_B__RAWNAND_RESETN,
+ MX6_PAD_NANDF_RB0__RAWNAND_READY0,
+ MX6_PAD_NANDF_CS0__RAWNAND_CE0N,
+ MX6_PAD_NANDF_CS1__RAWNAND_CE1N,
+ MX6_PAD_NANDF_CS2__RAWNAND_CE2N,
+ MX6_PAD_NANDF_CS3__RAWNAND_CE3N,
+ MX6_PAD_SD4_CMD__RAWNAND_RDN,
+ MX6_PAD_SD4_CLK__RAWNAND_WRN,
+ MX6_PAD_NANDF_D0__RAWNAND_D0,
+ MX6_PAD_NANDF_D1__RAWNAND_D1,
+ MX6_PAD_NANDF_D2__RAWNAND_D2,
+ MX6_PAD_NANDF_D3__RAWNAND_D3,
+ MX6_PAD_NANDF_D4__RAWNAND_D4,
+ MX6_PAD_NANDF_D5__RAWNAND_D5,
+ MX6_PAD_NANDF_D6__RAWNAND_D6,
+ MX6_PAD_NANDF_D7__RAWNAND_D7,
+ MX6_PAD_SD4_DAT0__RAWNAND_DQS,
};
static void setup_gpmi_nand(void)
karo_set_fdtsize(blob);
}
+static int karo_fdt_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 (status && strcmp(status, "okay") == 0) {
+ debug("%s is enabled\n", can_ifs[i]);
+ return 1;
+ }
+ }
+ debug("can driver is disabled\n");
+ return 0;
+}
+
+static void karo_fdt_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);
+}
+
+void karo_fdt_fixup_flexcan(void *blob, int xcvr_present)
+{
+ const char *xcvr_status = "disabled";
+
+ if (xcvr_present) {
+ if (karo_fdt_flexcan_enabled(blob)) {
+ karo_fdt_set_lcd_pins(blob, "lcdif_23bit_pins_a");
+ xcvr_status = "okay";
+ } else {
+ karo_fdt_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);
+
+ karo_fdt_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 karo_fdt_del_prop(void *blob, const char *compat, phys_addr_t offs,
const char *prop)
{
prop = fdt_getprop(blob, off, "vsync-active", NULL);
if (prop)
fb_mode->sync |= *prop ? FB_SYNC_VERT_HIGH_ACT : 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 ? 0 : FB_SYNC_OE_LOW_ACT;
prop = fdt_getprop(blob, off, "pixelclk-active", NULL);
if (prop)
fb_mode->sync |= *prop ? 0 : FB_SYNC_CLK_LAT_FALL;
-#endif
+
return 0;
}
int ret;
uint32_t ph;
- ret = fdt_increase_size(blob, 32);
+ ret = fdt_increase_size(blob, 64);
if (ret) {
printf("Warning: Failed to increase FDT size: %d\n", ret);
}
fb_mode->sync & FB_SYNC_VERT_HIGH_ACT ? 1 : 0);
if (ret)
goto out;
-
-#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;
-#endif
out:
karo_set_fdtsize(blob);
return ret;
return off;
if (name == NULL) {
- int parent = fdt_parent_offset(blob, off);
int ret;
- if (parent < 0) {
- printf("Failed to find parent of node '%s'\n",
- fdt_get_name(blob, off, NULL));
- return parent;
- }
- debug("parent offset=%06x\n", parent);
- ret = fdt_set_node_status(blob, parent, FDT_STATUS_DISABLED, 0);
+ debug("Disabling node '%s' at %03x\n",
+ fdt_get_name(blob, off, NULL), off);
+ ret = fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
return ret;
}
return ret;
debug("Trying to find NAND partition '%s'\n", part);
- ret = find_dev_and_part(part, &dev, &part_num,
- &part_info);
+ ret = find_dev_and_part(part, &dev, &part_num, &part_info);
if (ret) {
printf("Failed to find flash partition '%s': %d\n",
part, ret);
void karo_fdt_move_fdt(void);
void karo_fdt_fixup_touchpanel(void *blob);
void karo_fdt_fixup_usb_otg(void *blob, const char *node, const char *phy);
+void karo_fdt_fixup_flexcan(void *blob, int xcvr_present);
void karo_fdt_del_prop(void *blob, const char *compat, phys_addr_t offs,
const char *prop);
void karo_fdt_enable_node(void *blob, const char *node, int enable);
const char *phy)
{
}
+static inline void karo_fdt_fixup_flexcan(void *blob, int xcvr_present)
+{
+}
static inline void karo_fdt_del_prop(void *blob, const char *compat,
phys_addr_t offs, const char *prop)
{
if (!is_valid_ether_addr(mac))
return 0;
- if (index == 0)
+ if (index == 0) {
+ printf("MAC addr from fuse: %pM\n", mac);
snprintf(env_name, sizeof(env_name), "ethaddr");
- else
+ } else {
snprintf(env_name, sizeof(env_name), "eth%daddr", index);
-
+ }
eth_setenv_enetaddr(env_name, mac);
return 0;
}
return ret;
}
- ret = fec_get_mac_addr(0);
- if (ret < 0) {
- printf("Failed to read FEC0 MAC address from OCOTP\n");
- return ret;
- }
#ifdef CONFIG_FEC_MXC_MULTI
if (getenv("ethaddr")) {
ret = fecmxc_initialize_multi(bis, 0, 0, MXS_ENET0_BASE);
}
}
- ret = fec_get_mac_addr(1);
- if (ret < 0) {
- printf("Failed to read FEC1 MAC address from OCOTP\n");
- return ret;
- }
if (getenv("eth1addr")) {
ret = fecmxc_initialize_multi(bis, 1, 1, MXS_ENET1_BASE);
if (ret) {
return ret;
}
}
- return 0;
#else
if (getenv("ethaddr")) {
ret = fecmxc_initialize(bis);
+ if (ret) {
+ printf("FEC MXS: Unable to init FEC\n");
+ return ret;
+ }
}
- return ret;
#endif
+ return 0;
}
#endif /* CONFIG_FEC_MXC */
printf("\n");
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) *
(p->yres + p->upper_margin + p->lower_margin + p->vsync_len) /
color_depth, refresh);
if (karo_load_splashimage(0) == 0) {
+ char vmode[32];
+
+ /* setup env variable for mxsfb display driver */
+ snprintf(vmode, sizeof(vmode), "%dx%dMR-%d@%d",
+ p->xres, p->yres, color_depth, refresh);
+ setenv("videomode", vmode);
+
debug("Initializing LCD controller\n");
video_hw_init(lcdbase);
+ setenv("videomode", NULL);
} else {
debug("Skipping initialization of LCD controller\n");
}
mxs_iomux_setup_pad(MX28_PAD_LCD_D00__GPIO_1_0);
}
+int tx28_fec1_enabled(void)
+{
+ const char *status;
+ int off;
+
+ if (!gd->fdt_blob)
+ return 0;
+
+ off = fdt_path_offset(gd->fdt_blob, "ethernet1");
+ if (off < 0)
+ return 0;
+
+ status = fdt_getprop(gd->fdt_blob, off, "status", NULL);
+ return status && (strcmp(status, "okay") == 0);
+}
+
int board_late_init(void)
{
+ int ret;
const char *baseboard;
karo_fdt_move_fdt();
return -EINVAL;
}
+ ret = fec_get_mac_addr(0);
+ if (ret < 0) {
+ printf("Failed to read FEC0 MAC address from OCOTP\n");
+ return ret;
+ }
+#ifdef CONFIG_FEC_MXC_MULTI
+ if (tx28_fec1_enabled()) {
+ ret = fec_get_mac_addr(1);
+ if (ret < 0) {
+ printf("Failed to read FEC1 MAC address from OCOTP\n");
+ return ret;
+ }
+ }
+#endif
return 0;
}
can_xcvr, strlen(can_xcvr) + 1, 1);
}
-static void tx28_fixup_fec(void *blob)
-{
- karo_fdt_enable_node(blob, "ethernet1", 0);
-}
-
void ft_board_setup(void *blob, bd_t *bd)
{
const char *baseboard = getenv("baseboard");
#endif
if (stk5_v5) {
karo_fdt_remove_node(blob, "stk5led");
- } else {
- tx28_fixup_fec(blob);
}
tx28_fixup_flexcan(blob, stk5_v5);
* 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
#include <nand.h>
#include <net.h>
#include <linux/mtd/nand.h>
+#include <linux/fb.h>
#include <asm/gpio.h>
#include <asm/cache.h>
#include <asm/omap_common.h>
.cmap = tx48_cmap,
};
-static struct da8xx_panel tx48_lcd_panel = {
- .name = "640x480MR@60",
- .width = 640,
- .height = 480,
- .hfp = 12,
- .hbp = 144,
- .hsw = 30,
- .vfp = 10,
- .vbp = 35,
- .vsw = 3,
- .pxl_clk = 25000000,
- .invert_pxl_clk = 1,
+#define FB_SYNC_OE_LOW_ACT (1 << 31)
+#define FB_SYNC_CLK_LAT_FALL (1 << 30)
+
+static struct fb_videomode tx48_fb_modes[] = {
+ {
+ /* Standard VGA timing */
+ .name = "VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = KHZ2PICOS(25175),
+ .left_margin = 48,
+ .hsync_len = 96,
+ .right_margin = 16,
+ .upper_margin = 31,
+ .vsync_len = 2,
+ .lower_margin = 12,
+ .sync = FB_SYNC_CLK_LAT_FALL,
+ },
+ {
+ /* Emerging ETV570 640 x 480 display. Syncs low active,
+ * DE high active, 115.2 mm x 86.4 mm display area
+ * VGA compatible timing
+ */
+ .name = "ETV570",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = KHZ2PICOS(25175),
+ .left_margin = 114,
+ .hsync_len = 30,
+ .right_margin = 16,
+ .upper_margin = 32,
+ .vsync_len = 3,
+ .lower_margin = 10,
+ .sync = FB_SYNC_CLK_LAT_FALL,
+ },
+ {
+ /* Emerging ET0350G0DH6 320 x 240 display.
+ * 70.08 mm x 52.56 mm display area.
+ */
+ .name = "ET0350",
+ .refresh = 60,
+ .xres = 320,
+ .yres = 240,
+ .pixclock = KHZ2PICOS(6500),
+ .left_margin = 68 - 34,
+ .hsync_len = 34,
+ .right_margin = 20,
+ .upper_margin = 18 - 3,
+ .vsync_len = 3,
+ .lower_margin = 4,
+ .sync = FB_SYNC_CLK_LAT_FALL,
+ },
+ {
+ /* Emerging ET0430G0DH6 480 x 272 display.
+ * 95.04 mm x 53.856 mm display area.
+ */
+ .name = "ET0430",
+ .refresh = 60,
+ .xres = 480,
+ .yres = 272,
+ .pixclock = KHZ2PICOS(9000),
+ .left_margin = 2,
+ .hsync_len = 41,
+ .right_margin = 2,
+ .upper_margin = 2,
+ .vsync_len = 10,
+ .lower_margin = 2,
+ },
+ {
+ /* Emerging ET0500G0DH6 800 x 480 display.
+ * 109.6 mm x 66.4 mm display area.
+ */
+ .name = "ET0500",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 480,
+ .pixclock = KHZ2PICOS(33260),
+ .left_margin = 216 - 128,
+ .hsync_len = 128,
+ .right_margin = 1056 - 800 - 216,
+ .upper_margin = 35 - 2,
+ .vsync_len = 2,
+ .lower_margin = 525 - 480 - 35,
+ .sync = FB_SYNC_CLK_LAT_FALL,
+ },
+ {
+ /* Emerging ETQ570G0DH6 320 x 240 display.
+ * 115.2 mm x 86.4 mm display area.
+ */
+ .name = "ETQ570",
+ .refresh = 60,
+ .xres = 320,
+ .yres = 240,
+ .pixclock = KHZ2PICOS(6400),
+ .left_margin = 38,
+ .hsync_len = 30,
+ .right_margin = 30,
+ .upper_margin = 16, /* 15 according to datasheet */
+ .vsync_len = 3, /* TVP -> 1>x>5 */
+ .lower_margin = 4, /* 4.5 according to datasheet */
+ .sync = FB_SYNC_CLK_LAT_FALL,
+ },
+ {
+ /* Emerging ET0700G0DH6 800 x 480 display.
+ * 152.4 mm x 91.44 mm display area.
+ */
+ .name = "ET0700",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 480,
+ .pixclock = KHZ2PICOS(33260),
+ .left_margin = 216 - 128,
+ .hsync_len = 128,
+ .right_margin = 1056 - 800 - 216,
+ .upper_margin = 35 - 2,
+ .vsync_len = 2,
+ .lower_margin = 525 - 480 - 35,
+ .sync = FB_SYNC_CLK_LAT_FALL,
+ },
+ {
+ /* unnamed entry for assigning parameters parsed from 'video_mode' string */
+ .refresh = 60,
+ .left_margin = 48,
+ .hsync_len = 96,
+ .right_margin = 16,
+ .upper_margin = 31,
+ .vsync_len = 2,
+ .lower_margin = 12,
+ .sync = FB_SYNC_CLK_LAT_FALL,
+ },
};
void *lcd_base; /* Start of framebuffer memory */
if (lcd_enabled) {
karo_load_splashimage(1);
+ debug("Switching LCD on\n");
gpio_set_value(TX48_LCD_PWR_GPIO, 1);
+ udelay(100);
gpio_set_value(TX48_LCD_RST_GPIO, 1);
udelay(300000);
gpio_set_value(TX48_LCD_BACKLIGHT_GPIO, 0);
void lcd_disable(void)
{
if (lcd_enabled) {
+ printf("Disabling LCD\n");
da8xx_fb_disable();
lcd_enabled = 0;
}
}
+static void tx48_lcd_panel_setup(struct da8xx_panel *p,
+ struct fb_videomode *fb)
+{
+ p->pxl_clk = PICOS2KHZ(fb->pixclock) * 1000;
+
+ p->width = fb->xres;
+ p->hbp = fb->left_margin;
+ p->hsw = fb->hsync_len;
+ p->hfp = fb->right_margin;
+
+ p->height = fb->yres;
+ p->vbp = fb->upper_margin;
+ p->vsw = fb->vsync_len;
+ p->vfp = fb->lower_margin;
+
+ p->invert_pxl_clk = !!(fb->sync & FB_SYNC_CLK_LAT_FALL);
+}
+
void lcd_panel_disable(void)
{
if (lcd_enabled) {
+ debug("Switching LCD off\n");
gpio_set_value(TX48_LCD_BACKLIGHT_GPIO, 1);
gpio_set_value(TX48_LCD_PWR_GPIO, 0);
gpio_set_value(TX48_LCD_RST_GPIO, 0);
int color_depth = 24;
char *vm, *v;
unsigned long val;
- struct da8xx_panel *p = &tx48_lcd_panel;
int refresh = 60;
+ struct fb_videomode *p = &tx48_fb_modes[0];
+ struct fb_videomode fb_mode;
+ int xres_set = 0, yres_set = 0, bpp_set = 0, refresh_set = 0;
if (!lcd_enabled) {
- printf("LCD disabled\n");
+ debug("LCD disabled\n");
return;
}
if (tstc() || (prm_rstst & PRM_RSTST_WDT1_RST)) {
+ debug("Disabling LCD\n");
lcd_enabled = 0;
+ setenv("splashimage", NULL);
return;
}
+ karo_fdt_move_fdt();
+
vm = getenv("video_mode");
if (vm == NULL) {
+ debug("Disabling LCD\n");
lcd_enabled = 0;
return;
}
if ((v = strstr(vm, ":")))
vm = v + 1;
- strncpy((char *)p->name, vm, sizeof(p->name));
-
- val = simple_strtoul(vm, &vm, 10);
- if (val != 0) {
- if (val > panel_info.vl_col)
- val = panel_info.vl_col;
- p->width = val;
- panel_info.vl_col = val;
+ 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 ||
+ 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 (*vm == 'x') {
- val = simple_strtoul(vm + 1, &vm, 10);
- if (val > panel_info.vl_row)
- val = panel_info.vl_row;
- p->height = val;
- panel_info.vl_row = val;
+ if (p->name != NULL)
+ debug("Trying compiled-in video modes\n");
+ while (p->name != NULL) {
+ if (strcmp(p->name, vm) == 0) {
+ debug("Using video mode: '%s'\n", p->name);
+ vm += strlen(vm);
+ break;
+ }
+ p++;
}
+ if (*vm != '\0')
+ debug("Trying to decode video_mode: '%s'\n", vm);
while (*vm != '\0') {
+ if (*vm >= '0' && *vm <= '9') {
+ char *end;
+
+ val = simple_strtoul(vm, &end, 0);
+ if (end > vm) {
+ if (!xres_set) {
+ if (val > panel_info.vl_col)
+ val = panel_info.vl_col;
+ p->xres = val;
+ panel_info.vl_col = val;
+ xres_set = 1;
+ } else if (!yres_set) {
+ if (val > panel_info.vl_row)
+ val = panel_info.vl_row;
+ p->yres = val;
+ panel_info.vl_row = val;
+ yres_set = 1;
+ } else if (!bpp_set) {
+ switch (val) {
+ case 24:
+ case 16:
+ case 8:
+ color_depth = val;
+ break;
+
+ default:
+ printf("Invalid color depth: '%.*s' in video_mode; using default: '%u'\n",
+ end - vm, vm, color_depth);
+ }
+ bpp_set = 1;
+ } else if (!refresh_set) {
+ refresh = val;
+ refresh_set = 1;
+ }
+ }
+ vm = end;
+ }
switch (*vm) {
+ case '@':
+ bpp_set = 1;
+ /* fallthru */
+ case '-':
+ yres_set = 1;
+ /* fallthru */
+ case 'x':
+ xres_set = 1;
+ /* fallthru */
case 'M':
case 'R':
vm++;
break;
- case '-':
- color_depth = simple_strtoul(vm + 1, &vm, 10);
- break;
-
- case '@':
- refresh = simple_strtoul(vm + 1, &vm, 10);
- break;
-
default:
- debug("Ignoring '%c'\n", *vm);
- vm++;
+ if (*vm != '\0')
+ vm++;
}
}
+ if (p->xres == 0 || p->yres == 0) {
+ printf("Invalid video mode: %s\n", getenv("video_mode"));
+ lcd_enabled = 0;
+ printf("Supported video modes are:");
+ for (p = &tx48_fb_modes[0]; p->name != NULL; p++) {
+ printf(" %s", p->name);
+ }
+ 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 = 3;
+ panel_info.vl_bpix = LCD_COLOR8;
break;
-
case 16:
- panel_info.vl_bpix = 4;
+ panel_info.vl_bpix = LCD_COLOR16;
break;
-
- case 24:
- panel_info.vl_bpix = 5;
- break;
-
default:
- printf("Invalid color_depth %u from video_mode '%s'; using default: %u\n",
- color_depth, getenv("video_mode"), 24);
+ panel_info.vl_bpix = LCD_COLOR24;
+ }
+
+ 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);
+ debug("Pixel clock set to %lu.%03lu MHz\n",
+ 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);
}
- lcd_line_length = NBITS(panel_info.vl_bpix) / 8 * panel_info.vl_col;
- p->pxl_clk = refresh *
- (p->width + p->hfp + p->hbp + p->hsw) *
- (p->height + p->vfp + p->vbp + p->vsw);
- debug("Pixel clock set to %u.%03uMHz\n",
- p->pxl_clk / 1000000, p->pxl_clk / 1000 % 1000);
gpio_request_array(stk5_lcd_gpios, ARRAY_SIZE(stk5_lcd_gpios));
tx48_set_pin_mux(stk5_lcd_pads, ARRAY_SIZE(stk5_lcd_pads));
- debug("Initializing FB driver\n");
- da8xx_video_init(&tx48_lcd_panel, color_depth);
if (karo_load_splashimage(0) == 0) {
+ struct da8xx_panel da8xx_panel = { };
+
+ debug("Initializing FB driver\n");
+ tx48_lcd_panel_setup(&da8xx_panel, p);
+ da8xx_video_init(&da8xx_panel, color_depth);
+
debug("Initializing LCD controller\n");
video_hw_init();
} else {
mpu_clk_rate() / 1000 % 1000);
}
+static void tx48_init_mac(void)
+{
+ uint8_t mac_addr[ETH_ALEN];
+ uint32_t mac_hi, mac_lo;
+
+ /* try reading mac address from efuse */
+ mac_lo = __raw_readl(MAC_ID0_LO);
+ mac_hi = __raw_readl(MAC_ID0_HI);
+
+ mac_addr[0] = mac_hi & 0xFF;
+ mac_addr[1] = (mac_hi & 0xFF00) >> 8;
+ mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
+ mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
+ mac_addr[4] = mac_lo & 0xFF;
+ mac_addr[5] = (mac_lo & 0xFF00) >> 8;
+
+ if (!is_valid_ether_addr(mac_addr)) {
+ printf("No valid MAC address programmed\n");
+ return;
+ }
+ printf("MAC addr from fuse: %pM\n", mac_addr);
+ eth_setenv_enetaddr("ethaddr", mac_addr);
+}
+
/* called with environment from NAND or MMC */
int board_late_init(void)
{
+ int ret = 0;
const char *baseboard;
tx48_set_cpu_clock();
-#ifdef CONFIG_OF_BOARD_SETUP
karo_fdt_move_fdt();
-#endif
+
baseboard = getenv("baseboard");
if (!baseboard)
- return 0;
+ goto exit;
if (strncmp(baseboard, "stk5", 4) == 0) {
printf("Baseboard: %s\n", baseboard);
} else {
printf("WARNING: Unsupported baseboard: '%s'\n",
baseboard);
- return -EINVAL;
+ ret = -EINVAL;
}
-
- return 0;
+exit:
+ tx48_init_mac();
+ return ret;
}
#ifdef CONFIG_DRIVER_TI_CPSW
int board_eth_init(bd_t *bis)
{
- uint8_t mac_addr[ETH_ALEN];
- uint32_t mac_hi, mac_lo;
-
- /* try reading mac address from efuse */
- mac_lo = __raw_readl(MAC_ID0_LO);
- mac_hi = __raw_readl(MAC_ID0_HI);
-
- mac_addr[0] = mac_hi & 0xFF;
- mac_addr[1] = (mac_hi & 0xFF00) >> 8;
- mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
- mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
- mac_addr[4] = mac_lo & 0xFF;
- mac_addr[5] = (mac_lo & 0xFF00) >> 8;
-
- if (is_valid_ether_addr(mac_addr)) {
- printf("MAC addr from fuse: %pM\n", mac_addr);
- eth_setenv_enetaddr("ethaddr", mac_addr);
- } else {
- printf("ERROR: Did not find a valid mac address in e-fuse\n");
- }
-
__raw_writel(RMII_MODE_ENABLE, MAC_MII_SEL);
__raw_writel(0x5D, GMII_SEL);
return cpsw_register(&cpsw_data);
#define fdt_fixup_mtdparts(b,n,c) do { } while (0)
#endif /* CONFIG_FDT_FIXUP_PARTITIONS */
-static void tx48_fixup_flexcan(void *blob)
+void ft_board_setup(void *blob, bd_t *bd)
{
const char *baseboard = getenv("baseboard");
+ int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
- if (baseboard && strcmp(baseboard, "stk5-v5") == 0)
- return;
-
- karo_fdt_del_prop(blob, "ti,dcan", 0x481cc000, "can-xcvr-enable");
- karo_fdt_del_prop(blob, "ti,dcan", 0x481d0000, "can-xcvr-enable");
-}
-
-void ft_board_setup(void *blob, bd_t *bd)
-{
fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
fdt_fixup_ethernet(blob);
karo_fdt_fixup_touchpanel(blob);
- tx48_fixup_flexcan(blob);
+ karo_fdt_fixup_flexcan(blob, stk5_v5);
tx48_disable_watchdog();
}
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)
{
int board_eth_init(bd_t *bis)
{
int ret;
- unsigned char mac[ETH_ALEN];
/* Power up the external phy and assert strap options */
gpio_request_array(tx51_fec_gpios, ARRAY_SIZE(tx51_fec_gpios));
ARRAY_SIZE(tx51_fec_pads));
ret = cpu_eth_init(bis);
- if (ret) {
+ if (ret)
printf("cpu_eth_init() failed: %d\n", ret);
- return ret;
- }
-
- imx_get_mac_from_fuse(0, mac);
- eth_setenv_enetaddr("ethaddr", mac);
- printf("MAC addr from fuse: %pM\n", mac);
-
return ret;
}
#endif /* CONFIG_FEC_MXC */
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;
+ }
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");
}
mxc_get_clock(MXC_ARM_CLK) / 1000 % 1000);
}
+static void tx51_init_mac(void)
+{
+ u8 mac[ETH_ALEN];
+
+ imx_get_mac_from_fuse(0, mac);
+ if (!is_valid_ether_addr(mac)) {
+ printf("No valid MAC address programmed\n");
+ return;
+ }
+
+ eth_setenv_enetaddr("ethaddr", mac);
+ printf("MAC addr from fuse: %pM\n", mac);
+}
+
int board_late_init(void)
{
int ret = 0;
}
exit:
+ tx51_init_mac();
gpio_set_value(TX51_RESET_OUT_GPIO, 1);
return ret;
}
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)
{
int board_eth_init(bd_t *bis)
{
int ret;
- unsigned char mac[ETH_ALEN];
/* delay at least 21ms for the PHY internal POR signal to deassert */
udelay(22000);
gpio_set_value(TX53_FEC_RST_GPIO, 1);
ret = cpu_eth_init(bis);
- if (ret) {
+ if (ret)
printf("cpu_eth_init() failed: %d\n", ret);
- return ret;
- }
-
- imx_get_mac_from_fuse(0, mac);
- eth_setenv_enetaddr("ethaddr", mac);
- printf("MAC addr from fuse: %pM\n", mac);
-
return ret;
}
#endif /* CONFIG_FEC_MXC */
};
#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;
}
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");
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) *
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");
}
mxc_get_clock(MXC_ARM_CLK) / 1000 % 1000);
}
+static void tx53_init_mac(void)
+{
+ u8 mac[ETH_ALEN];
+
+ imx_get_mac_from_fuse(0, mac);
+ if (!is_valid_ether_addr(mac)) {
+ printf("No valid MAC address programmed\n");
+ return;
+ }
+
+ eth_setenv_enetaddr("ethaddr", mac);
+ printf("MAC addr from fuse: %pM\n", mac);
+}
+
int board_late_init(void)
{
int ret = 0;
}
exit:
+ tx53_init_mac();
gpio_set_value(TX53_RESET_OUT_GPIO, 1);
return ret;
}
#define fdt_fixup_mtdparts(b,n,c) do { } while (0)
#endif
-static void tx53_fixup_flexcan(void *blob)
-{
- const char *baseboard = getenv("baseboard");
-
- if (baseboard && strcmp(baseboard, "stk5-v5") == 0)
- return;
-
- karo_fdt_del_prop(blob, "fsl,p1010-flexcan", 0x53fc8000, "transceiver-switch");
- karo_fdt_del_prop(blob, "fsl,p1010-flexcan", 0x53fcc000, "transceiver-switch");
-}
-
#ifdef CONFIG_SYS_TX53_HWREV_2
void tx53_fixup_rtc(void *blob)
{
static inline void tx53_fixup_rtc(void *blob)
{
}
-#endif
+#endif /* CONFIG_SYS_TX53_HWREV_2 */
void ft_board_setup(void *blob, bd_t *bd)
{
+ const char *baseboard = getenv("baseboard");
+ int stk5_v5 = baseboard != NULL && (strcmp(baseboard, "stk5-v5") == 0);
+
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);
+ karo_fdt_fixup_flexcan(blob, stk5_v5);
tx53_fixup_rtc(blob);
+ karo_fdt_update_fb_mode(blob, getenv("video_mode"));
}
-#endif
+#endif /* CONFIG_OF_BOARD_SETUP */
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");
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) *
#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");
karo_fdt_fixup_touchpanel(blob);
karo_fdt_fixup_usb_otg(blob, "usbotg", "fsl,usbphy");
- tx6qdl_fixup_flexcan(blob, stk5_v5);
+ karo_fdt_fixup_flexcan(blob, stk5_v5);
karo_fdt_update_fb_mode(blob, getenv("video_mode"));
}
-#endif
+#endif /* CONFIG_OF_BOARD_SETUP */
MX6_PAD_SD1_DAT2__USDHC1_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD1_DAT3__USDHC1_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
/* Carrier MicroSD Card Detect */
- MX6_PAD_GPIO_2__GPIO_1_2 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_GPIO_2__GPIO_1_2,
};
static iomux_v3_cfg_t const usdhc3_pads[] = {
MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
/* SOM MicroSD Card Detect */
- MX6_PAD_EIM_DA9__GPIO_3_9 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_EIM_DA9__GPIO_3_9,
};
static iomux_v3_cfg_t const enet_pads[] = {
MX6_PAD_RGMII_RD3__ENET_RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
/* AR8031 PHY Reset */
- MX6_PAD_EIM_D29__GPIO_3_29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+ MX6_PAD_EIM_D29__GPIO_3_29,
};
static void setup_iomux_uart(void)
$(MAKE) -C ../tools
# SEE README.arm-unaligned-accesses
-$(obj)hush.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
+$(obj)cmd_bmp.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
$(obj)fdt_support.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
+$(obj)hush.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
+ifneq ($(CONFIG_CMD_BMP)$(CONFIG_SPLASH_SCREEN),)
+$(obj)lcd.o: CFLAGS += $(PLATFORM_NO_UNALIGNED)
+endif
#########################################################################
ret = fdt_add_mem_rsv(blob, (uintptr_t)blob, actualsize);
if (ret < 0)
return ret;
-
+ if (getenv("fdtsize"))
+ setenv_hex("fdtsize", actualsize);
return actualsize;
}
return 0;
}
-void ipuv3_fb_shutdown(void)
-{
- int i;
- struct ipu_stat *stat = (struct ipu_stat *)IPU_STAT;
-
- for (i = 0; i < ARRAY_SIZE(mxcfb_info); i++) {
- struct fb_info *fbi = mxcfb_info[i];
-
- if (fbi) {
- struct mxcfb_info *mxc_fbi = fbi->par;
-
- ipu_disable_channel(mxc_fbi->ipu_ch);
- ipu_uninit_channel(mxc_fbi->ipu_ch);
- }
- }
-
- clk_enable(g_ipu_clk);
- for (i = 0; i < ARRAY_SIZE(stat->int_stat); i++) {
- __raw_writel(__raw_readl(&stat->int_stat[i]),
- &stat->int_stat[i]);
- }
- clk_disable(g_ipu_clk);
-}
-
/*
* Initializes the framebuffer information pointer. After allocating
* sufficient memory for the framebuffer structure, the fields are
NBITS(panel_info.vl_bpix)) / 8;
}
+void ipuv3_fb_shutdown(void)
+{
+ int i;
+ struct ipu_stat *stat = (struct ipu_stat *)IPU_STAT;
+
+ for (i = 0; i < ARRAY_SIZE(mxcfb_info); i++) {
+ struct fb_info *fbi = mxcfb_info[i];
+ if (fbi) {
+ struct mxcfb_info *mxc_fbi = fbi->par;
+ ipu_disable_channel(mxc_fbi->ipu_ch);
+ ipu_uninit_channel(mxc_fbi->ipu_ch);
+ }
+ }
+ clk_enable(g_ipu_clk);
+ for (i = 0; i < ARRAY_SIZE(stat->int_stat); i++) {
+ __raw_writel(__raw_readl(&stat->int_stat[i]),
+ &stat->int_stat[i]);
+ }
+ clk_disable(g_ipu_clk);
+}
+
int ipuv3_fb_init(struct fb_videomode *mode, int di, unsigned int interface_pix_fmt,
ipu_di_clk_parent_t di_clk_parent, unsigned long di_clk_val, int bpp)
{
#define CONFIG_FEC_MXC_PHYADDR 0x00
#endif
+#define CONFIG_PHY_SMSC
+#define CONFIG_PHYLIB
#define CONFIG_MII
#define CONFIG_FEC_XCV_TYPE RMII
#define CONFIG_GET_FEC_MAC_ADDR_FROM_IIM