avionic design with actual uboot and tooling

submodule of avionic design uboot bootloader and with included tools to
get you started , read readme.md and readme-tk1-loader.md
This commit is contained in:
2026-03-03 21:46:32 +02:00
parent fe3ba02c96
commit 68d74d3181
11967 changed files with 2221897 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
if TARGET_CM_FX6
config SYS_BOARD
default "cm_fx6"
config SYS_VENDOR
default "compulab"
config SYS_CONFIG_NAME
default "cm_fx6"
endif

View File

@@ -0,0 +1,6 @@
CM_FX6 BOARD
M: Nikita Kiryanov <nikita@compulab.co.il>
S: Maintained
F: board/compulab/cm_fx6/
F: include/configs/cm_fx6.h
F: configs/cm_fx6_defconfig

View File

@@ -0,0 +1,12 @@
#
# (C) Copyright 2014 CompuLab, Ltd. <www.compulab.co.il>
#
# Authors: Nikita Kiryanov <nikita@compulab.co.il>
#
# SPDX-License-Identifier: GPL-2.0+
#
ifdef CONFIG_SPL_BUILD
obj-y = common.o spl.o
else
obj-y = common.o cm_fx6.o
endif

View File

@@ -0,0 +1,741 @@
/*
* Board functions for Compulab CM-FX6 board
*
* Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
*
* Author: Nikita Kiryanov <nikita@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <dm.h>
#include <fsl_esdhc.h>
#include <miiphy.h>
#include <netdev.h>
#include <errno.h>
#include <usb.h>
#include <fdt_support.h>
#include <sata.h>
#include <splash.h>
#include <asm/arch/crm_regs.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/iomux.h>
#include <asm/arch/mxc_hdmi.h>
#include <asm/imx-common/mxc_i2c.h>
#include <asm/imx-common/sata.h>
#include <asm/imx-common/video.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <dm/platform_data/serial_mxc.h>
#include "common.h"
#include "../common/eeprom.h"
#include "../common/common.h"
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_SPLASH_SCREEN
static struct splash_location cm_fx6_splash_locations[] = {
{
.name = "sf",
.storage = SPLASH_STORAGE_SF,
.flags = SPLASH_STORAGE_RAW,
.offset = 0x100000,
},
{
.name = "mmc_fs",
.storage = SPLASH_STORAGE_MMC,
.flags = SPLASH_STORAGE_FS,
.devpart = "2:1",
},
{
.name = "usb_fs",
.storage = SPLASH_STORAGE_USB,
.flags = SPLASH_STORAGE_FS,
.devpart = "0:1",
},
{
.name = "sata_fs",
.storage = SPLASH_STORAGE_SATA,
.flags = SPLASH_STORAGE_FS,
.devpart = "0:1",
},
};
int splash_screen_prepare(void)
{
return splash_source_load(cm_fx6_splash_locations,
ARRAY_SIZE(cm_fx6_splash_locations));
}
#endif
#ifdef CONFIG_IMX_HDMI
static void cm_fx6_enable_hdmi(struct display_info_t const *dev)
{
struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
imx_setup_hdmi();
setbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK);
imx_enable_hdmi_phy();
}
static struct display_info_t preset_hdmi_1024X768 = {
.bus = -1,
.addr = 0,
.pixfmt = IPU_PIX_FMT_RGB24,
.enable = cm_fx6_enable_hdmi,
.mode = {
.name = "HDMI",
.refresh = 60,
.xres = 1024,
.yres = 768,
.pixclock = 40385,
.left_margin = 220,
.right_margin = 40,
.upper_margin = 21,
.lower_margin = 7,
.hsync_len = 60,
.vsync_len = 10,
.sync = FB_SYNC_EXT,
.vmode = FB_VMODE_NONINTERLACED,
}
};
static void cm_fx6_setup_display(void)
{
struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
enable_ipu_clock();
clrbits_le32(&iomuxc_regs->gpr[3], MXC_CCM_CCGR3_IPU1_IPU_DI0_MASK);
}
int board_video_skip(void)
{
int ret;
struct display_info_t *preset;
char const *panel = getenv("displaytype");
if (!panel) /* Also accept panel for backward compatibility */
panel = getenv("panel");
if (!panel)
return -ENOENT;
if (!strcmp(panel, "HDMI"))
preset = &preset_hdmi_1024X768;
else
return -EINVAL;
ret = ipuv3_fb_init(&preset->mode, 0, preset->pixfmt);
if (ret) {
printf("Can't init display %s: %d\n", preset->mode.name, ret);
return ret;
}
preset->enable(preset);
printf("Display: %s (%ux%u)\n", preset->mode.name, preset->mode.xres,
preset->mode.yres);
return 0;
}
#else
static inline void cm_fx6_setup_display(void) {}
#endif /* CONFIG_VIDEO_IPUV3 */
#ifdef CONFIG_DWC_AHSATA
static int cm_fx6_issd_gpios[] = {
/* The order of the GPIOs in the array is important! */
CM_FX6_SATA_LDO_EN,
CM_FX6_SATA_PHY_SLP,
CM_FX6_SATA_NRSTDLY,
CM_FX6_SATA_PWREN,
CM_FX6_SATA_NSTANDBY1,
CM_FX6_SATA_NSTANDBY2,
};
static void cm_fx6_sata_power(int on)
{
int i;
if (!on) { /* tell the iSSD that the power will be removed */
gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 1);
mdelay(10);
}
for (i = 0; i < ARRAY_SIZE(cm_fx6_issd_gpios); i++) {
gpio_direction_output(cm_fx6_issd_gpios[i], on);
udelay(100);
}
if (!on) /* for compatibility lower the power loss interrupt */
gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0);
}
static iomux_v3_cfg_t const sata_pads[] = {
/* SATA PWR */
IOMUX_PADS(PAD_ENET_TX_EN__GPIO1_IO28 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_EIM_A22__GPIO2_IO16 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_EIM_D20__GPIO3_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_EIM_A25__GPIO5_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* SATA CTRL */
IOMUX_PADS(PAD_ENET_TXD0__GPIO1_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_EIM_D23__GPIO3_IO23 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_EIM_D29__GPIO3_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_EIM_A23__GPIO6_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_EIM_BCLK__GPIO6_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL)),
};
static int cm_fx6_setup_issd(void)
{
int ret, i;
SETUP_IOMUX_PADS(sata_pads);
for (i = 0; i < ARRAY_SIZE(cm_fx6_issd_gpios); i++) {
ret = gpio_request(cm_fx6_issd_gpios[i], "sata");
if (ret)
return ret;
}
ret = gpio_request(CM_FX6_SATA_PWLOSS_INT, "sata_pwloss_int");
if (ret)
return ret;
return 0;
}
#define CM_FX6_SATA_INIT_RETRIES 10
int sata_initialize(void)
{
int err, i;
/* Make sure this gpio has logical 0 value */
gpio_direction_output(CM_FX6_SATA_PWLOSS_INT, 0);
udelay(100);
cm_fx6_sata_power(1);
for (i = 0; i < CM_FX6_SATA_INIT_RETRIES; i++) {
err = setup_sata();
if (err) {
printf("SATA setup failed: %d\n", err);
return err;
}
udelay(100);
err = __sata_initialize();
if (!err)
break;
/* There is no device on the SATA port */
if (sata_port_status(0, 0) == 0)
break;
/* There's a device, but link not established. Retry */
}
return err;
}
int sata_stop(void)
{
__sata_stop();
cm_fx6_sata_power(0);
mdelay(250);
return 0;
}
#else
static int cm_fx6_setup_issd(void) { return 0; }
#endif
#ifdef CONFIG_SYS_I2C_MXC
#define I2C_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
PAD_CTL_ODE | PAD_CTL_SRE_FAST)
I2C_PADS(i2c0_pads,
PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
PAD_EIM_D21__GPIO3_IO21 | MUX_PAD_CTRL(I2C_PAD_CTRL),
IMX_GPIO_NR(3, 21),
PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
PAD_EIM_D28__GPIO3_IO28 | MUX_PAD_CTRL(I2C_PAD_CTRL),
IMX_GPIO_NR(3, 28));
I2C_PADS(i2c1_pads,
PAD_KEY_COL3__I2C2_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
PAD_KEY_COL3__GPIO4_IO12 | MUX_PAD_CTRL(I2C_PAD_CTRL),
IMX_GPIO_NR(4, 12),
PAD_KEY_ROW3__I2C2_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
PAD_KEY_ROW3__GPIO4_IO13 | MUX_PAD_CTRL(I2C_PAD_CTRL),
IMX_GPIO_NR(4, 13));
I2C_PADS(i2c2_pads,
PAD_GPIO_3__I2C3_SCL | MUX_PAD_CTRL(I2C_PAD_CTRL),
PAD_GPIO_3__GPIO1_IO03 | MUX_PAD_CTRL(I2C_PAD_CTRL),
IMX_GPIO_NR(1, 3),
PAD_GPIO_6__I2C3_SDA | MUX_PAD_CTRL(I2C_PAD_CTRL),
PAD_GPIO_6__GPIO1_IO06 | MUX_PAD_CTRL(I2C_PAD_CTRL),
IMX_GPIO_NR(1, 6));
static int cm_fx6_setup_one_i2c(int busnum, struct i2c_pads_info *pads)
{
int ret;
ret = setup_i2c(busnum, CONFIG_SYS_I2C_SPEED, 0x7f, pads);
if (ret)
printf("Warning: I2C%d setup failed: %d\n", busnum, ret);
return ret;
}
static int cm_fx6_setup_i2c(void)
{
int ret = 0, err;
/* i2c<x>_pads are wierd macro variables; we can't use an array */
err = cm_fx6_setup_one_i2c(0, I2C_PADS_INFO(i2c0_pads));
if (err)
ret = err;
err = cm_fx6_setup_one_i2c(1, I2C_PADS_INFO(i2c1_pads));
if (err)
ret = err;
err = cm_fx6_setup_one_i2c(2, I2C_PADS_INFO(i2c2_pads));
if (err)
ret = err;
return ret;
}
#else
static int cm_fx6_setup_i2c(void) { return 0; }
#endif
#ifdef CONFIG_USB_EHCI_MX6
#define WEAK_PULLDOWN (PAD_CTL_PUS_100K_DOWN | \
PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
PAD_CTL_HYS | PAD_CTL_SRE_SLOW)
#define MX6_USBNC_BASEADDR 0x2184800
#define USBNC_USB_H1_PWR_POL (1 << 9)
static int cm_fx6_setup_usb_host(void)
{
int err;
err = gpio_request(CM_FX6_USB_HUB_RST, "usb hub rst");
if (err)
return err;
SETUP_IOMUX_PAD(PAD_GPIO_0__USB_H1_PWR | MUX_PAD_CTRL(NO_PAD_CTRL));
SETUP_IOMUX_PAD(PAD_SD3_RST__GPIO7_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL));
return 0;
}
static int cm_fx6_setup_usb_otg(void)
{
int err;
struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
err = gpio_request(SB_FX6_USB_OTG_PWR, "usb-pwr");
if (err) {
printf("USB OTG pwr gpio request failed: %d\n", err);
return err;
}
SETUP_IOMUX_PAD(PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(NO_PAD_CTRL));
SETUP_IOMUX_PAD(PAD_ENET_RX_ER__USB_OTG_ID |
MUX_PAD_CTRL(WEAK_PULLDOWN));
clrbits_le32(&iomux->gpr[1], IOMUXC_GPR1_OTG_ID_MASK);
/* disable ext. charger detect, or it'll affect signal quality at dp. */
return gpio_direction_output(SB_FX6_USB_OTG_PWR, 0);
}
int board_usb_phy_mode(int port)
{
return USB_INIT_HOST;
}
int board_ehci_hcd_init(int port)
{
int ret;
u32 *usbnc_usb_uh1_ctrl = (u32 *)(MX6_USBNC_BASEADDR + 4);
/* Only 1 host controller in use. port 0 is OTG & needs no attention */
if (port != 1)
return 0;
/* Set PWR polarity to match power switch's enable polarity */
setbits_le32(usbnc_usb_uh1_ctrl, USBNC_USB_H1_PWR_POL);
ret = gpio_direction_output(CM_FX6_USB_HUB_RST, 0);
if (ret)
return ret;
udelay(10);
ret = gpio_direction_output(CM_FX6_USB_HUB_RST, 1);
if (ret)
return ret;
mdelay(1);
return 0;
}
int board_ehci_power(int port, int on)
{
if (port == 0)
return gpio_direction_output(SB_FX6_USB_OTG_PWR, on);
return 0;
}
#else
static int cm_fx6_setup_usb_otg(void) { return 0; }
static int cm_fx6_setup_usb_host(void) { return 0; }
#endif
#ifdef CONFIG_FEC_MXC
#define ENET_PAD_CTRL (PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
static int mx6_rgmii_rework(struct phy_device *phydev)
{
unsigned short val;
/* Ar8031 phy SmartEEE feature cause link status generates glitch,
* which cause ethernet link down/up issue, so disable SmartEEE
*/
phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x3);
phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x805d);
phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4003);
val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
val &= ~(0x1 << 8);
phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
/* To enable AR8031 ouput a 125MHz clk from CLK_25M */
phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
val &= 0xffe3;
val |= 0x18;
phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
/* introduce tx clock delay */
phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
val |= 0x0100;
phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
return 0;
}
int board_phy_config(struct phy_device *phydev)
{
mx6_rgmii_rework(phydev);
if (phydev->drv->config)
return phydev->drv->config(phydev);
return 0;
}
static iomux_v3_cfg_t const enet_pads[] = {
IOMUX_PADS(PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_GPIO_0__CCM_CLKO1 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_GPIO_3__CCM_CLKO2 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(0x84)),
IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK |
MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_RGMII_TX_CTL__RGMII_TX_CTL |
MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_RGMII_RX_CTL__RGMII_RX_CTL |
MUX_PAD_CTRL(ENET_PAD_CTRL)),
};
static int handle_mac_address(char *env_var, uint eeprom_bus)
{
unsigned char enetaddr[6];
int rc;
rc = eth_getenv_enetaddr(env_var, enetaddr);
if (rc)
return 0;
rc = cl_eeprom_read_mac_addr(enetaddr, eeprom_bus);
if (rc)
return rc;
if (!is_valid_ethaddr(enetaddr))
return -1;
return eth_setenv_enetaddr(env_var, enetaddr);
}
#define SB_FX6_I2C_EEPROM_BUS 0
#define NO_MAC_ADDR "No MAC address found for %s\n"
int board_eth_init(bd_t *bis)
{
int err;
if (handle_mac_address("ethaddr", CONFIG_SYS_I2C_EEPROM_BUS))
printf(NO_MAC_ADDR, "primary NIC");
if (handle_mac_address("eth1addr", SB_FX6_I2C_EEPROM_BUS))
printf(NO_MAC_ADDR, "secondary NIC");
SETUP_IOMUX_PADS(enet_pads);
/* phy reset */
err = gpio_request(CM_FX6_ENET_NRST, "enet_nrst");
if (err)
printf("Etnernet NRST gpio request failed: %d\n", err);
gpio_direction_output(CM_FX6_ENET_NRST, 0);
udelay(500);
gpio_set_value(CM_FX6_ENET_NRST, 1);
enable_enet_clk(1);
return cpu_eth_init(bis);
}
#endif
#ifdef CONFIG_NAND_MXS
static iomux_v3_cfg_t const nand_pads[] = {
IOMUX_PADS(PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
IOMUX_PADS(PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NO_PAD_CTRL)),
};
static void cm_fx6_setup_gpmi_nand(void)
{
SETUP_IOMUX_PADS(nand_pads);
/* Enable clock roots */
enable_usdhc_clk(1, 3);
enable_usdhc_clk(1, 4);
setup_gpmi_io_clk(MXC_CCM_CS2CDR_ENFC_CLK_PODF(0xf) |
MXC_CCM_CS2CDR_ENFC_CLK_PRED(1) |
MXC_CCM_CS2CDR_ENFC_CLK_SEL(0));
}
#else
static void cm_fx6_setup_gpmi_nand(void) {}
#endif
#ifdef CONFIG_FSL_ESDHC
static struct fsl_esdhc_cfg usdhc_cfg[3] = {
{USDHC1_BASE_ADDR},
{USDHC2_BASE_ADDR},
{USDHC3_BASE_ADDR},
};
static enum mxc_clock usdhc_clk[3] = {
MXC_ESDHC_CLK,
MXC_ESDHC2_CLK,
MXC_ESDHC3_CLK,
};
int board_mmc_init(bd_t *bis)
{
int i;
cm_fx6_set_usdhc_iomux();
for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
usdhc_cfg[i].sdhc_clk = mxc_get_clock(usdhc_clk[i]);
usdhc_cfg[i].max_bus_width = 4;
fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
enable_usdhc_clk(1, i);
}
return 0;
}
#endif
#ifdef CONFIG_MXC_SPI
int cm_fx6_setup_ecspi(void)
{
cm_fx6_set_ecspi_iomux();
return gpio_request(CM_FX6_ECSPI_BUS0_CS0, "ecspi_bus0_cs0");
}
#else
int cm_fx6_setup_ecspi(void) { return 0; }
#endif
#ifdef CONFIG_OF_BOARD_SETUP
#define USDHC3_PATH "/soc/aips-bus@02100000/usdhc@02198000/"
int ft_board_setup(void *blob, bd_t *bd)
{
u32 baseboard_rev;
int nodeoffset;
uint8_t enetaddr[6];
char baseboard_name[16];
int err;
/* MAC addr */
if (eth_getenv_enetaddr("ethaddr", enetaddr)) {
fdt_find_and_setprop(blob,
"/soc/aips-bus@02100000/ethernet@02188000",
"local-mac-address", enetaddr, 6, 1);
}
if (eth_getenv_enetaddr("eth1addr", enetaddr)) {
fdt_find_and_setprop(blob, "/eth@pcie", "local-mac-address",
enetaddr, 6, 1);
}
baseboard_rev = cl_eeprom_get_board_rev(0);
err = cl_eeprom_get_product_name((uchar *)baseboard_name, 0);
if (err || baseboard_rev == 0)
return 0; /* Assume not an early revision SB-FX6m baseboard */
if (!strncmp("SB-FX6m", baseboard_name, 7) && baseboard_rev <= 120) {
fdt_shrink_to_minimum(blob); /* Make room for new properties */
nodeoffset = fdt_path_offset(blob, USDHC3_PATH);
fdt_delprop(blob, nodeoffset, "cd-gpios");
fdt_find_and_setprop(blob, USDHC3_PATH, "non-removable",
NULL, 0, 1);
fdt_find_and_setprop(blob, USDHC3_PATH, "keep-power-in-suspend",
NULL, 0, 1);
}
return 0;
}
#endif
int board_init(void)
{
int ret;
gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
cm_fx6_setup_gpmi_nand();
ret = cm_fx6_setup_ecspi();
if (ret)
printf("Warning: ECSPI setup failed: %d\n", ret);
ret = cm_fx6_setup_usb_otg();
if (ret)
printf("Warning: USB OTG setup failed: %d\n", ret);
ret = cm_fx6_setup_usb_host();
if (ret)
printf("Warning: USB host setup failed: %d\n", ret);
/*
* cm-fx6 may have iSSD not assembled and in this case it has
* bypasses for a (m)SATA socket on the baseboard. The socketed
* device is not controlled by those GPIOs. So just print a warning
* if the setup fails.
*/
ret = cm_fx6_setup_issd();
if (ret)
printf("Warning: iSSD setup failed: %d\n", ret);
/* Warn on failure but do not abort boot */
ret = cm_fx6_setup_i2c();
if (ret)
printf("Warning: I2C setup failed: %d\n", ret);
cm_fx6_setup_display();
return 0;
}
int checkboard(void)
{
puts("Board: CM-FX6\n");
return 0;
}
int misc_init_r(void)
{
cl_print_pcb_info();
return 0;
}
void dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
switch (gd->ram_size) {
case 0x10000000: /* DDR_16BIT_256MB */
gd->bd->bi_dram[0].size = 0x10000000;
gd->bd->bi_dram[1].size = 0;
break;
case 0x20000000: /* DDR_32BIT_512MB */
gd->bd->bi_dram[0].size = 0x20000000;
gd->bd->bi_dram[1].size = 0;
break;
case 0x40000000:
if (is_cpu_type(MXC_CPU_MX6SOLO)) { /* DDR_32BIT_1GB */
gd->bd->bi_dram[0].size = 0x20000000;
gd->bd->bi_dram[1].size = 0x20000000;
} else { /* DDR_64BIT_1GB */
gd->bd->bi_dram[0].size = 0x40000000;
gd->bd->bi_dram[1].size = 0;
}
break;
case 0x80000000: /* DDR_64BIT_2GB */
gd->bd->bi_dram[0].size = 0x40000000;
gd->bd->bi_dram[1].size = 0x40000000;
break;
case 0xEFF00000: /* DDR_64BIT_4GB */
gd->bd->bi_dram[0].size = 0x70000000;
gd->bd->bi_dram[1].size = 0x7FF00000;
break;
}
}
int dram_init(void)
{
gd->ram_size = imx_ddr_size();
switch (gd->ram_size) {
case 0x10000000:
case 0x20000000:
case 0x40000000:
case 0x80000000:
break;
case 0xF0000000:
gd->ram_size -= 0x100000;
break;
default:
printf("ERROR: Unsupported DRAM size 0x%lx\n", gd->ram_size);
return -1;
}
return 0;
}
u32 get_board_rev(void)
{
return cl_eeprom_get_board_rev(CONFIG_SYS_I2C_EEPROM_BUS);
}
static struct mxc_serial_platdata cm_fx6_mxc_serial_plat = {
.reg = (struct mxc_uart *)UART4_BASE,
};
U_BOOT_DEVICE(cm_fx6_serial) = {
.name = "serial_mxc",
.platdata = &cm_fx6_mxc_serial_plat,
};

View File

@@ -0,0 +1,85 @@
/*
* Code used by both U-Boot and SPL for Compulab CM-FX6
*
* Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
*
* Author: Nikita Kiryanov <nikita@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/arch/sys_proto.h>
#include <asm/gpio.h>
#include <asm/imx-common/spi.h>
#include <fsl_esdhc.h>
#include "common.h"
DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_FSL_ESDHC
#define USDHC_PAD_CTRL (PAD_CTL_PUS_47K_UP | \
PAD_CTL_SPEED_LOW | PAD_CTL_DSE_80ohm | \
PAD_CTL_SRE_FAST | PAD_CTL_HYS)
static iomux_v3_cfg_t const usdhc_pads[] = {
IOMUX_PADS(PAD_SD1_CLK__SD1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD1_CMD__SD1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD1_DAT0__SD1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD1_DAT1__SD1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD1_DAT2__SD1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD1_DAT3__SD1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD2_CLK__SD2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD2_CMD__SD2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD2_DAT0__SD2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD2_DAT1__SD2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD2_DAT2__SD2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD2_DAT3__SD2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD3_DAT4__SD3_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD3_DAT5__SD3_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD3_DAT6__SD3_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
IOMUX_PADS(PAD_SD3_DAT7__SD3_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
};
void cm_fx6_set_usdhc_iomux(void)
{
SETUP_IOMUX_PADS(usdhc_pads);
}
/* CINS bit doesn't work, so always try to access the MMC card */
int board_mmc_getcd(struct mmc *mmc)
{
return 1;
}
#endif
#ifdef CONFIG_MXC_SPI
#define ECSPI_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_SPEED_MED | \
PAD_CTL_PUS_100K_DOWN | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
static iomux_v3_cfg_t const ecspi_pads[] = {
IOMUX_PADS(PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(ECSPI_PAD_CTRL)),
IOMUX_PADS(PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(ECSPI_PAD_CTRL)),
IOMUX_PADS(PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(ECSPI_PAD_CTRL)),
IOMUX_PADS(PAD_EIM_EB2__GPIO2_IO30 | MUX_PAD_CTRL(ECSPI_PAD_CTRL)),
IOMUX_PADS(PAD_EIM_D19__ECSPI1_SS1 | MUX_PAD_CTRL(ECSPI_PAD_CTRL)),
};
void cm_fx6_set_ecspi_iomux(void)
{
SETUP_IOMUX_PADS(ecspi_pads);
}
int board_spi_cs_gpio(unsigned bus, unsigned cs)
{
return (bus == 0 && cs == 0) ? (CM_FX6_ECSPI_BUS0_CS0) : -1;
}
#endif

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
*
* Author: Nikita Kiryanov <nikita@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm/arch/mx6-pins.h>
#include <asm/arch/clock.h>
#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | \
PAD_CTL_SRE_FAST | PAD_CTL_HYS)
#define CM_FX6_ECSPI_BUS0_CS0 IMX_GPIO_NR(2, 30)
#define CM_FX6_GREEN_LED IMX_GPIO_NR(2, 31)
#define CM_FX6_ENET_NRST IMX_GPIO_NR(2, 8)
#define CM_FX6_ENET_NRST IMX_GPIO_NR(2, 8)
#define CM_FX6_USB_HUB_RST IMX_GPIO_NR(7, 8)
#define SB_FX6_USB_OTG_PWR IMX_GPIO_NR(3, 22)
#define CM_FX6_ENET_NRST IMX_GPIO_NR(2, 8)
#define CM_FX6_USB_HUB_RST IMX_GPIO_NR(7, 8)
#define SB_FX6_USB_OTG_PWR IMX_GPIO_NR(3, 22)
#define CM_FX6_SATA_PWREN IMX_GPIO_NR(1, 28)
#define CM_FX6_SATA_VDDC_CTRL IMX_GPIO_NR(1, 30)
#define CM_FX6_SATA_LDO_EN IMX_GPIO_NR(2, 16)
#define CM_FX6_SATA_NSTANDBY1 IMX_GPIO_NR(3, 20)
#define CM_FX6_SATA_PHY_SLP IMX_GPIO_NR(3, 23)
#define CM_FX6_SATA_STBY_REQ IMX_GPIO_NR(3, 29)
#define CM_FX6_SATA_NSTANDBY2 IMX_GPIO_NR(5, 2)
#define CM_FX6_SATA_NRSTDLY IMX_GPIO_NR(6, 6)
#define CM_FX6_SATA_PWLOSS_INT IMX_GPIO_NR(6, 31)
void cm_fx6_set_usdhc_iomux(void);
void cm_fx6_set_ecspi_iomux(void);

View File

@@ -0,0 +1,367 @@
/*
* SPL specific code for Compulab CM-FX6 board
*
* Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
*
* Author: Nikita Kiryanov <nikita@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <spl.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/arch/mx6-ddr.h>
#include <asm/arch/clock.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/crm_regs.h>
#include <asm/imx-common/iomux-v3.h>
#include <fsl_esdhc.h>
#include "common.h"
DECLARE_GLOBAL_DATA_PTR;
enum ddr_config {
DDR_16BIT_256MB,
DDR_32BIT_512MB,
DDR_32BIT_1GB,
DDR_64BIT_1GB,
DDR_64BIT_2GB,
DDR_64BIT_4GB,
DDR_UNKNOWN,
};
/*
* Below DRAM_RESET[DDR_SEL] = 0 which is incorrect according to
* Freescale QRM, but this is exactly the value used by the automatic
* calibration script and it works also in all our tests, so we leave
* it as is at this point.
*/
#define CM_FX6_DDR_IOMUX_CFG \
.dram_sdqs0 = 0x00000038, \
.dram_sdqs1 = 0x00000038, \
.dram_sdqs2 = 0x00000038, \
.dram_sdqs3 = 0x00000038, \
.dram_sdqs4 = 0x00000038, \
.dram_sdqs5 = 0x00000038, \
.dram_sdqs6 = 0x00000038, \
.dram_sdqs7 = 0x00000038, \
.dram_dqm0 = 0x00000038, \
.dram_dqm1 = 0x00000038, \
.dram_dqm2 = 0x00000038, \
.dram_dqm3 = 0x00000038, \
.dram_dqm4 = 0x00000038, \
.dram_dqm5 = 0x00000038, \
.dram_dqm6 = 0x00000038, \
.dram_dqm7 = 0x00000038, \
.dram_cas = 0x00000038, \
.dram_ras = 0x00000038, \
.dram_sdclk_0 = 0x00000038, \
.dram_sdclk_1 = 0x00000038, \
.dram_sdcke0 = 0x00003000, \
.dram_sdcke1 = 0x00003000, \
.dram_reset = 0x00000038, \
.dram_sdba2 = 0x00000000, \
.dram_sdodt0 = 0x00000038, \
.dram_sdodt1 = 0x00000038,
#define CM_FX6_GPR_IOMUX_CFG \
.grp_b0ds = 0x00000038, \
.grp_b1ds = 0x00000038, \
.grp_b2ds = 0x00000038, \
.grp_b3ds = 0x00000038, \
.grp_b4ds = 0x00000038, \
.grp_b5ds = 0x00000038, \
.grp_b6ds = 0x00000038, \
.grp_b7ds = 0x00000038, \
.grp_addds = 0x00000038, \
.grp_ddrmode_ctl = 0x00020000, \
.grp_ddrpke = 0x00000000, \
.grp_ddrmode = 0x00020000, \
.grp_ctlds = 0x00000038, \
.grp_ddr_type = 0x000C0000,
static struct mx6sdl_iomux_ddr_regs ddr_iomux_s = { CM_FX6_DDR_IOMUX_CFG };
static struct mx6sdl_iomux_grp_regs grp_iomux_s = { CM_FX6_GPR_IOMUX_CFG };
static struct mx6dq_iomux_ddr_regs ddr_iomux_q = { CM_FX6_DDR_IOMUX_CFG };
static struct mx6dq_iomux_grp_regs grp_iomux_q = { CM_FX6_GPR_IOMUX_CFG };
static struct mx6_mmdc_calibration cm_fx6_calib_s = {
.p0_mpwldectrl0 = 0x005B0061,
.p0_mpwldectrl1 = 0x004F0055,
.p0_mpdgctrl0 = 0x0314030C,
.p0_mpdgctrl1 = 0x025C0268,
.p0_mprddlctl = 0x42464646,
.p0_mpwrdlctl = 0x36322C34,
};
static struct mx6_ddr_sysinfo cm_fx6_sysinfo_s = {
.cs1_mirror = 1,
.cs_density = 16,
.bi_on = 1,
.rtt_nom = 1,
.rtt_wr = 0,
.ralat = 5,
.walat = 1,
.mif3_mode = 3,
.rst_to_cke = 0x23,
.sde_to_rst = 0x10,
};
static struct mx6_ddr3_cfg cm_fx6_ddr3_cfg_s = {
.mem_speed = 800,
.density = 4,
.rowaddr = 14,
.coladdr = 10,
.pagesz = 2,
.trcd = 1800,
.trcmin = 5200,
.trasmin = 3600,
.SRT = 0,
};
static void spl_mx6s_dram_init(enum ddr_config dram_config, bool reset)
{
if (reset)
((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2;
switch (dram_config) {
case DDR_16BIT_256MB:
cm_fx6_sysinfo_s.dsize = 0;
cm_fx6_sysinfo_s.ncs = 1;
break;
case DDR_32BIT_512MB:
cm_fx6_sysinfo_s.dsize = 1;
cm_fx6_sysinfo_s.ncs = 1;
break;
case DDR_32BIT_1GB:
cm_fx6_sysinfo_s.dsize = 1;
cm_fx6_sysinfo_s.ncs = 2;
break;
default:
puts("Tried to setup invalid DDR configuration\n");
hang();
}
mx6_dram_cfg(&cm_fx6_sysinfo_s, &cm_fx6_calib_s, &cm_fx6_ddr3_cfg_s);
udelay(100);
}
static struct mx6_mmdc_calibration cm_fx6_calib_q = {
.p0_mpwldectrl0 = 0x00630068,
.p0_mpwldectrl1 = 0x0068005D,
.p0_mpdgctrl0 = 0x04140428,
.p0_mpdgctrl1 = 0x037C037C,
.p0_mprddlctl = 0x3C30303A,
.p0_mpwrdlctl = 0x3A344038,
.p1_mpwldectrl0 = 0x0035004C,
.p1_mpwldectrl1 = 0x00170026,
.p1_mpdgctrl0 = 0x0374037C,
.p1_mpdgctrl1 = 0x0350032C,
.p1_mprddlctl = 0x30322A3C,
.p1_mpwrdlctl = 0x48304A3E,
};
static struct mx6_ddr_sysinfo cm_fx6_sysinfo_q = {
.cs_density = 16,
.cs1_mirror = 1,
.bi_on = 1,
.rtt_nom = 1,
.rtt_wr = 0,
.ralat = 5,
.walat = 1,
.mif3_mode = 3,
.rst_to_cke = 0x23,
.sde_to_rst = 0x10,
};
static struct mx6_ddr3_cfg cm_fx6_ddr3_cfg_q = {
.mem_speed = 1066,
.density = 4,
.rowaddr = 14,
.coladdr = 10,
.pagesz = 2,
.trcd = 1324,
.trcmin = 59500,
.trasmin = 9750,
.SRT = 0,
};
static void spl_mx6q_dram_init(enum ddr_config dram_config, bool reset)
{
if (reset)
((struct mmdc_p_regs *)MX6_MMDC_P0_MDCTL)->mdmisc = 2;
cm_fx6_ddr3_cfg_q.rowaddr = 14;
switch (dram_config) {
case DDR_16BIT_256MB:
cm_fx6_sysinfo_q.dsize = 0;
cm_fx6_sysinfo_q.ncs = 1;
break;
case DDR_32BIT_512MB:
cm_fx6_sysinfo_q.dsize = 1;
cm_fx6_sysinfo_q.ncs = 1;
break;
case DDR_64BIT_1GB:
cm_fx6_sysinfo_q.dsize = 2;
cm_fx6_sysinfo_q.ncs = 1;
break;
case DDR_64BIT_2GB:
cm_fx6_sysinfo_q.dsize = 2;
cm_fx6_sysinfo_q.ncs = 2;
break;
case DDR_64BIT_4GB:
cm_fx6_sysinfo_q.dsize = 2;
cm_fx6_sysinfo_q.ncs = 2;
cm_fx6_ddr3_cfg_q.rowaddr = 15;
break;
default:
puts("Tried to setup invalid DDR configuration\n");
hang();
}
mx6_dram_cfg(&cm_fx6_sysinfo_q, &cm_fx6_calib_q, &cm_fx6_ddr3_cfg_q);
udelay(100);
}
static int cm_fx6_spl_dram_init(void)
{
unsigned long bank1_size, bank2_size;
switch (get_cpu_type()) {
case MXC_CPU_MX6SOLO:
mx6sdl_dram_iocfg(64, &ddr_iomux_s, &grp_iomux_s);
spl_mx6s_dram_init(DDR_32BIT_1GB, false);
bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
bank2_size = get_ram_size((long int *)PHYS_SDRAM_2, 0x80000000);
if (bank1_size == 0x20000000) {
if (bank2_size == 0x20000000)
return 0;
spl_mx6s_dram_init(DDR_32BIT_512MB, true);
return 0;
}
spl_mx6s_dram_init(DDR_16BIT_256MB, true);
bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
if (bank1_size == 0x10000000)
return 0;
break;
case MXC_CPU_MX6D:
case MXC_CPU_MX6Q:
mx6dq_dram_iocfg(64, &ddr_iomux_q, &grp_iomux_q);
spl_mx6q_dram_init(DDR_64BIT_4GB, false);
bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
if (bank1_size == 0x80000000)
return 0;
if (bank1_size == 0x40000000) {
bank2_size = get_ram_size((long int *)PHYS_SDRAM_2,
0x80000000);
if (bank2_size == 0x40000000) {
/* Don't do a full reset here */
spl_mx6q_dram_init(DDR_64BIT_2GB, false);
} else {
spl_mx6q_dram_init(DDR_64BIT_1GB, true);
}
return 0;
}
spl_mx6q_dram_init(DDR_32BIT_512MB, true);
bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
if (bank1_size == 0x20000000)
return 0;
spl_mx6q_dram_init(DDR_16BIT_256MB, true);
bank1_size = get_ram_size((long int *)PHYS_SDRAM_1, 0x80000000);
if (bank1_size == 0x10000000)
return 0;
break;
}
return -1;
}
static iomux_v3_cfg_t const uart4_pads[] = {
IOMUX_PADS(PAD_KEY_COL0__UART4_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
IOMUX_PADS(PAD_KEY_ROW0__UART4_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
};
static void cm_fx6_setup_uart(void)
{
SETUP_IOMUX_PADS(uart4_pads);
enable_uart_clk(1);
}
#ifdef CONFIG_SPL_SPI_SUPPORT
static void cm_fx6_setup_ecspi(void)
{
cm_fx6_set_ecspi_iomux();
enable_spi_clk(1, 0);
}
#else
static void cm_fx6_setup_ecspi(void) { }
#endif
void board_init_f(ulong dummy)
{
struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
/*
* We don't use DMA in SPL, but we do need it in U-Boot. U-Boot
* initializes DMA very early (before all board code), so the only
* opportunity we have to initialize APBHDMA clocks is in SPL.
*/
setbits_le32(&mxc_ccm->CCGR0, MXC_CCM_CCGR0_APBHDMA_MASK);
enable_usdhc_clk(1, 2);
arch_cpu_init();
timer_init();
cm_fx6_setup_ecspi();
cm_fx6_setup_uart();
get_clocks();
preloader_console_init();
gpio_direction_output(CM_FX6_GREEN_LED, 1);
if (cm_fx6_spl_dram_init()) {
puts("!!!ERROR!!! DRAM detection failed!!!\n");
hang();
}
memset(__bss_start, 0, __bss_end - __bss_start);
board_init_r(NULL, 0);
}
void board_boot_order(u32 *spl_boot_list)
{
spl_boot_list[0] = spl_boot_device();
switch (spl_boot_list[0]) {
case BOOT_DEVICE_SPI:
spl_boot_list[1] = BOOT_DEVICE_MMC1;
break;
case BOOT_DEVICE_MMC1:
spl_boot_list[1] = BOOT_DEVICE_SPI;
break;
}
}
#ifdef CONFIG_SPL_MMC_SUPPORT
static struct fsl_esdhc_cfg usdhc_cfg = {
.esdhc_base = USDHC3_BASE_ADDR,
.max_bus_width = 4,
};
int board_mmc_init(bd_t *bis)
{
cm_fx6_set_usdhc_iomux();
usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
return fsl_esdhc_initialize(bis, &usdhc_cfg);
}
#endif

View File

@@ -0,0 +1,15 @@
if TARGET_CM_T335
config SYS_BOARD
default "cm_t335"
config SYS_VENDOR
default "compulab"
config SYS_SOC
default "am33xx"
config SYS_CONFIG_NAME
default "cm_t335"
endif

View File

@@ -0,0 +1,6 @@
CM_T335 BOARD
M: Igor Grinberg <grinberg@compulab.co.il>
S: Maintained
F: board/compulab/cm_t335/
F: include/configs/cm_t335.h
F: configs/cm_t335_defconfig

View File

@@ -0,0 +1,10 @@
#
# Copyright (C) 2013 Compulab Ltd - http://compulab.co.il/
#
# Author: Ilya Ledvich <ilya@compulab.co.il>
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += cm_t335.o
obj-$(CONFIG_SPL_BUILD) += mux.o spl.o

View File

@@ -0,0 +1,162 @@
/*
* Board functions for Compulab CM-T335 board
*
* Copyright (C) 2013, Compulab Ltd - http://compulab.co.il/
*
* Author: Ilya Ledvich <ilya@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <errno.h>
#include <miiphy.h>
#include <cpsw.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/hardware_am33xx.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include "../common/eeprom.h"
DECLARE_GLOBAL_DATA_PTR;
/*
* Basic board specific setup. Pinmux has been handled already.
*/
int board_init(void)
{
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
gpmc_init();
#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT)
status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
#endif
return 0;
}
#if defined (CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)
static void cpsw_control(int enabled)
{
/* VTP can be added here */
return;
}
static struct cpsw_slave_data cpsw_slave = {
.slave_reg_ofs = 0x208,
.sliver_reg_ofs = 0xd80,
.phy_addr = 0,
.phy_if = PHY_INTERFACE_MODE_RGMII,
};
static struct cpsw_platform_data cpsw_data = {
.mdio_base = CPSW_MDIO_BASE,
.cpsw_base = CPSW_BASE,
.mdio_div = 0xff,
.channels = 8,
.cpdma_reg_ofs = 0x800,
.slaves = 1,
.slave_data = &cpsw_slave,
.ale_reg_ofs = 0xd00,
.ale_entries = 1024,
.host_port_reg_ofs = 0x108,
.hw_stats_reg_ofs = 0x900,
.bd_ram_ofs = 0x2000,
.mac_control = (1 << 5),
.control = cpsw_control,
.host_port_num = 0,
.version = CPSW_CTRL_VERSION_2,
};
/* PHY reset GPIO */
#define GPIO_PHY_RST GPIO_PIN(3, 7)
static void board_phy_init(void)
{
gpio_request(GPIO_PHY_RST, "phy_rst");
gpio_direction_output(GPIO_PHY_RST, 0);
mdelay(2);
gpio_set_value(GPIO_PHY_RST, 1);
mdelay(2);
}
static void get_efuse_mac_addr(uchar *enetaddr)
{
uint32_t mac_hi, mac_lo;
struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
mac_lo = readl(&cdev->macid0l);
mac_hi = readl(&cdev->macid0h);
enetaddr[0] = mac_hi & 0xFF;
enetaddr[1] = (mac_hi & 0xFF00) >> 8;
enetaddr[2] = (mac_hi & 0xFF0000) >> 16;
enetaddr[3] = (mac_hi & 0xFF000000) >> 24;
enetaddr[4] = mac_lo & 0xFF;
enetaddr[5] = (mac_lo & 0xFF00) >> 8;
}
/*
* Routine: handle_mac_address
* Description: prepare MAC address for on-board Ethernet.
*/
static int handle_mac_address(void)
{
uchar enetaddr[6];
int rv;
rv = eth_getenv_enetaddr("ethaddr", enetaddr);
if (rv)
return 0;
rv = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS);
if (rv)
get_efuse_mac_addr(enetaddr);
if (!is_valid_ethaddr(enetaddr))
return -1;
return eth_setenv_enetaddr("ethaddr", enetaddr);
}
#define AR8051_PHY_DEBUG_ADDR_REG 0x1d
#define AR8051_PHY_DEBUG_DATA_REG 0x1e
#define AR8051_DEBUG_RGMII_CLK_DLY_REG 0x5
#define AR8051_RGMII_TX_CLK_DLY 0x100
int board_eth_init(bd_t *bis)
{
int rv, n = 0;
const char *devname;
struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
rv = handle_mac_address();
if (rv)
printf("No MAC address found!\n");
writel(RGMII_MODE_ENABLE | RGMII_INT_DELAY, &cdev->miisel);
board_phy_init();
rv = cpsw_register(&cpsw_data);
if (rv < 0)
printf("Error %d registering CPSW switch\n", rv);
else
n += rv;
/*
* CPSW RGMII Internal Delay Mode is not supported in all PVT
* operating points. So we must set the TX clock delay feature
* in the AR8051 PHY. Since we only support a single ethernet
* device, we only do this for the first instance.
*/
devname = miiphy_get_current_dev();
miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_ADDR_REG,
AR8051_DEBUG_RGMII_CLK_DLY_REG);
miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_DATA_REG,
AR8051_RGMII_TX_CLK_DLY);
return n;
}
#endif /* CONFIG_DRIVER_TI_CPSW && !CONFIG_SPL_BUILD */

View File

@@ -0,0 +1,117 @@
/*
* Pinmux configuration for Compulab CM-T335 board
*
* Copyright (C) 2013, Compulab Ltd - http://compulab.co.il/
*
* Author: Ilya Ledvich <ilya@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/hardware.h>
#include <asm/arch/mux.h>
#include <asm/io.h>
static struct module_pin_mux uart0_pin_mux[] = {
{OFFSET(uart0_rxd), (MODE(0) | PULLUP_EN | RXACTIVE)},
{OFFSET(uart0_txd), (MODE(0) | PULLUDEN)},
{-1},
};
static struct module_pin_mux uart1_pin_mux[] = {
{OFFSET(uart1_rxd), (MODE(0) | PULLUP_EN | RXACTIVE)},
{OFFSET(uart1_txd), (MODE(0) | PULLUDEN)},
{OFFSET(uart1_ctsn), (MODE(0) | PULLUP_EN | RXACTIVE)},
{OFFSET(uart1_rtsn), (MODE(0) | PULLUDEN)},
{-1},
};
static struct module_pin_mux mmc0_pin_mux[] = {
{OFFSET(mmc0_dat3), (MODE(0) | RXACTIVE | PULLUP_EN)},
{OFFSET(mmc0_dat2), (MODE(0) | RXACTIVE | PULLUP_EN)},
{OFFSET(mmc0_dat1), (MODE(0) | RXACTIVE | PULLUP_EN)},
{OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)},
{OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)},
{OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)},
{-1},
};
static struct module_pin_mux i2c0_pin_mux[] = {
{OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | PULLUDDIS | SLEWCTRL)},
{OFFSET(i2c0_scl), (MODE(0) | RXACTIVE | PULLUDDIS | SLEWCTRL)},
{-1},
};
static struct module_pin_mux i2c1_pin_mux[] = {
/* I2C_DATA */
{OFFSET(uart0_ctsn), (MODE(3) | RXACTIVE | PULLUDDIS | SLEWCTRL)},
/* I2C_SCLK */
{OFFSET(uart0_rtsn), (MODE(3) | RXACTIVE | PULLUDDIS | SLEWCTRL)},
{-1},
};
static struct module_pin_mux rgmii1_pin_mux[] = {
{OFFSET(mii1_txen), MODE(2)}, /* RGMII1_TCTL */
{OFFSET(mii1_rxdv), MODE(2) | RXACTIVE}, /* RGMII1_RCTL */
{OFFSET(mii1_txd3), MODE(2)}, /* RGMII1_TD3 */
{OFFSET(mii1_txd2), MODE(2)}, /* RGMII1_TD2 */
{OFFSET(mii1_txd1), MODE(2)}, /* RGMII1_TD1 */
{OFFSET(mii1_txd0), MODE(2)}, /* RGMII1_TD0 */
{OFFSET(mii1_txclk), MODE(2)}, /* RGMII1_TCLK */
{OFFSET(mii1_rxclk), MODE(2) | RXACTIVE}, /* RGMII1_RCLK */
{OFFSET(mii1_rxd3), MODE(2) | RXACTIVE}, /* RGMII1_RD3 */
{OFFSET(mii1_rxd2), MODE(2) | RXACTIVE}, /* RGMII1_RD2 */
{OFFSET(mii1_rxd1), MODE(2) | RXACTIVE}, /* RGMII1_RD1 */
{OFFSET(mii1_rxd0), MODE(2) | RXACTIVE}, /* RGMII1_RD0 */
{OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN},/* MDIO_DATA */
{OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */
{-1},
};
static struct module_pin_mux nand_pin_mux[] = {
{OFFSET(gpmc_ad0), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD0 */
{OFFSET(gpmc_ad1), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD1 */
{OFFSET(gpmc_ad2), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD2 */
{OFFSET(gpmc_ad3), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD3 */
{OFFSET(gpmc_ad4), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD4 */
{OFFSET(gpmc_ad5), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD5 */
{OFFSET(gpmc_ad6), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD6 */
{OFFSET(gpmc_ad7), (MODE(0) | PULLUP_EN | RXACTIVE)}, /* NAND AD7 */
{OFFSET(gpmc_wait0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* NAND WAIT */
{OFFSET(gpmc_wpn), (MODE(7) | PULLUP_EN | RXACTIVE)}, /* NAND_WPN */
{OFFSET(gpmc_csn0), (MODE(0) | PULLUDEN)}, /* NAND_CS0 */
{OFFSET(gpmc_advn_ale), (MODE(0) | PULLUDEN)}, /* NAND_ADV_ALE */
{OFFSET(gpmc_oen_ren), (MODE(0) | PULLUDEN)}, /* NAND_OE */
{OFFSET(gpmc_wen), (MODE(0) | PULLUDEN)}, /* NAND_WEN */
{OFFSET(gpmc_be0n_cle), (MODE(0) | PULLUDEN)}, /* NAND_BE_CLE */
{-1},
};
static struct module_pin_mux eth_phy_rst_pin_mux[] = {
{OFFSET(emu0), (MODE(7) | PULLUDDIS)}, /* GPIO3_7 */
{-1},
};
static struct module_pin_mux status_led_pin_mux[] = {
{OFFSET(gpmc_csn3), (MODE(7) | PULLUDEN)}, /* GPIO2_0 */
{-1},
};
void set_uart_mux_conf(void)
{
configure_module_pin_mux(uart0_pin_mux);
configure_module_pin_mux(uart1_pin_mux);
}
void set_mux_conf_regs(void)
{
configure_module_pin_mux(i2c0_pin_mux);
configure_module_pin_mux(i2c1_pin_mux);
configure_module_pin_mux(rgmii1_pin_mux);
configure_module_pin_mux(eth_phy_rst_pin_mux);
configure_module_pin_mux(mmc0_pin_mux);
configure_module_pin_mux(nand_pin_mux);
configure_module_pin_mux(status_led_pin_mux);
}

View File

@@ -0,0 +1,114 @@
/*
* SPL specific code for Compulab CM-T335 board
*
* Board functions for Compulab CM-T335 board
*
* Copyright (C) 2013, Compulab Ltd - http://compulab.co.il/
*
* Author: Ilya Ledvich <ilya@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <errno.h>
#include <asm/arch/ddr_defs.h>
#include <asm/arch/clock.h>
#include <asm/arch/clocks_am33xx.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/hardware_am33xx.h>
#include <linux/sizes.h>
const struct ctrl_ioregs ioregs = {
.cm0ioctl = MT41J128MJT125_IOCTRL_VALUE,
.cm1ioctl = MT41J128MJT125_IOCTRL_VALUE,
.cm2ioctl = MT41J128MJT125_IOCTRL_VALUE,
.dt0ioctl = MT41J128MJT125_IOCTRL_VALUE,
.dt1ioctl = MT41J128MJT125_IOCTRL_VALUE,
};
static const struct ddr_data ddr3_data = {
.datardsratio0 = MT41J128MJT125_RD_DQS,
.datawdsratio0 = MT41J128MJT125_WR_DQS,
.datafwsratio0 = MT41J128MJT125_PHY_FIFO_WE,
.datawrsratio0 = MT41J128MJT125_PHY_WR_DATA,
};
static const struct cmd_control ddr3_cmd_ctrl_data = {
.cmd0csratio = MT41J128MJT125_RATIO,
.cmd0iclkout = MT41J128MJT125_INVERT_CLKOUT,
.cmd1csratio = MT41J128MJT125_RATIO,
.cmd1iclkout = MT41J128MJT125_INVERT_CLKOUT,
.cmd2csratio = MT41J128MJT125_RATIO,
.cmd2iclkout = MT41J128MJT125_INVERT_CLKOUT,
};
static struct emif_regs ddr3_emif_reg_data = {
.sdram_config = MT41J128MJT125_EMIF_SDCFG,
.ref_ctrl = MT41J128MJT125_EMIF_SDREF,
.sdram_tim1 = MT41J128MJT125_EMIF_TIM1,
.sdram_tim2 = MT41J128MJT125_EMIF_TIM2,
.sdram_tim3 = MT41J128MJT125_EMIF_TIM3,
.zq_config = MT41J128MJT125_ZQ_CFG,
.emif_ddr_phy_ctlr_1 = MT41J128MJT125_EMIF_READ_LATENCY |
PHY_EN_DYN_PWRDN,
};
const struct dpll_params dpll_ddr = {
/* M N M2 M3 M4 M5 M6 */
303, (V_OSCK/1000000) - 1, 1, -1, -1, -1, -1};
void am33xx_spl_board_init(void)
{
struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
/* Get the frequency */
dpll_mpu_opp100.m = am335x_get_efuse_mpu_max_freq(cdev);
/* Set CORE Frequencies to OPP100 */
do_setup_dpll(&dpll_core_regs, &dpll_core_opp100);
/* Set MPU Frequency to what we detected now that voltages are set */
do_setup_dpll(&dpll_mpu_regs, &dpll_mpu_opp100);
}
const struct dpll_params *get_dpll_ddr_params(void)
{
return &dpll_ddr;
}
static void probe_sdram_size(long size)
{
switch (size) {
case SZ_512M:
ddr3_emif_reg_data.sdram_config = MT41J256MJT125_EMIF_SDCFG;
break;
case SZ_256M:
ddr3_emif_reg_data.sdram_config = MT41J128MJT125_EMIF_SDCFG;
break;
case SZ_128M:
ddr3_emif_reg_data.sdram_config = MT41J64MJT125_EMIF_SDCFG;
break;
default:
puts("Failed configuring DRAM, resetting...\n\n");
reset_cpu(0);
}
debug("%s: setting DRAM size to %ldM\n", __func__, size >> 20);
config_ddr(303, &ioregs, &ddr3_data,
&ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
}
void sdram_init(void)
{
long size = SZ_1G;
do {
size = size / 2;
probe_sdram_size(size);
} while (get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, size) < size);
return;
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright (c) 2004-2008 Texas Instruments
*
* (C) Copyright 2002
* Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
. = ALIGN(4);
.text :
{
*(.__image_copy_start)
*(.vectors)
CPUDIR/start.o (.text*)
board/compulab/cm_t335/built-in.o (.text*)
*(.text*)
}
. = ALIGN(4);
.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
. = ALIGN(4);
.data : {
*(.data*)
}
. = ALIGN(4);
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
}
. = ALIGN(4);
.image_copy_end :
{
*(.__image_copy_end)
}
.rel_dyn_start :
{
*(.__rel_dyn_start)
}
.rel.dyn : {
*(.rel*)
}
.rel_dyn_end :
{
*(.__rel_dyn_end)
}
.hash : { *(.hash*) }
.end :
{
*(.__end)
}
_image_binary_end = .;
/*
* Deprecated: this MMU section is used by pxa at present but
* should not be used by new boards/CPUs.
*/
. = ALIGN(4096);
.mmutable : {
*(.mmutable)
}
/*
* Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c
* __bss_base and __bss_limit are for linker only (overlay ordering)
*/
.bss_start __rel_dyn_start (OVERLAY) : {
KEEP(*(.__bss_start));
__bss_base = .;
}
.bss __bss_base (OVERLAY) : {
*(.bss*)
. = ALIGN(4);
__bss_limit = .;
}
.bss_end __bss_limit (OVERLAY) : {
KEEP(*(.__bss_end));
}
.dynsym _image_binary_end : { *(.dynsym) }
.dynbss : { *(.dynbss) }
.dynstr : { *(.dynstr*) }
.dynamic : { *(.dynamic*) }
.plt : { *(.plt*) }
.interp : { *(.interp*) }
.gnu : { *(.gnu*) }
.ARM.exidx : { *(.ARM.exidx*) }
}

View File

@@ -0,0 +1,12 @@
if TARGET_CM_T35
config SYS_BOARD
default "cm_t35"
config SYS_VENDOR
default "compulab"
config SYS_CONFIG_NAME
default "cm_t35"
endif

View File

@@ -0,0 +1,6 @@
CM_T35 BOARD
M: Igor Grinberg <grinberg@compulab.co.il>
S: Maintained
F: board/compulab/cm_t35/
F: include/configs/cm_t35.h
F: configs/cm_t35_defconfig

View File

@@ -0,0 +1,10 @@
#
# (C) Copyright 2011 - 2013 CompuLab, Ltd. <www.compulab.co.il>
#
# Authors: Nikita Kiryanov <nikita@compulab.co.il>
# Igor Grinberg <grinberg@compulab.co.il>
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += cm_t35.o

View File

@@ -0,0 +1,510 @@
/*
* (C) Copyright 2011 - 2013 CompuLab, Ltd. <www.compulab.co.il>
*
* Authors: Mike Rapoport <mike@compulab.co.il>
* Igor Grinberg <grinberg@compulab.co.il>
*
* Derived from omap3evm and Beagle Board by
* Manikandan Pillai <mani.pillai@ti.com>
* Richard Woodruff <r-woodruff2@ti.com>
* Syed Mohammed Khasim <x0khasim@ti.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <status_led.h>
#include <netdev.h>
#include <net.h>
#include <i2c.h>
#include <usb.h>
#include <mmc.h>
#include <splash.h>
#include <twl4030.h>
#include <linux/compiler.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <asm/arch/mem.h>
#include <asm/arch/mux.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/sys_proto.h>
#include <asm/mach-types.h>
#include <asm/ehci-omap.h>
#include <asm/gpio.h>
#include "../common/common.h"
#include "../common/eeprom.h"
DECLARE_GLOBAL_DATA_PTR;
const omap3_sysinfo sysinfo = {
DDR_DISCRETE,
"CM-T3x board",
"NAND",
};
#ifdef CONFIG_SPL_BUILD
/*
* Routine: get_board_mem_timings
* Description: If we use SPL then there is no x-loader nor config header
* so we have to setup the DDR timings ourself on both banks.
*/
void get_board_mem_timings(struct board_sdrc_timings *timings)
{
timings->mr = MICRON_V_MR_165;
timings->mcfg = MICRON_V_MCFG_200(256 << 20); /* raswidth 14 needed */
timings->ctrla = MICRON_V_ACTIMA_165;
timings->ctrlb = MICRON_V_ACTIMB_165;
timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
}
#endif
struct splash_location splash_locations[] = {
{
.name = "nand",
.storage = SPLASH_STORAGE_NAND,
.flags = SPLASH_STORAGE_RAW,
.offset = 0x100000,
},
};
int splash_screen_prepare(void)
{
return splash_source_load(splash_locations,
ARRAY_SIZE(splash_locations));
}
/*
* Routine: board_init
* Description: hardware init.
*/
int board_init(void)
{
gpmc_init(); /* in SRAM or SDRAM, finish GPMC */
/* board id for Linux */
if (get_cpu_family() == CPU_OMAP34XX)
gd->bd->bi_arch_number = MACH_TYPE_CM_T35;
else
gd->bd->bi_arch_number = MACH_TYPE_CM_T3730;
/* boot param addr */
gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100);
#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT)
status_led_set(STATUS_LED_BOOT, STATUS_LED_ON);
#endif
return 0;
}
/*
* Routine: get_board_rev
* Description: read system revision
*/
u32 get_board_rev(void)
{
return cl_eeprom_get_board_rev(CONFIG_SYS_I2C_EEPROM_BUS);
};
int misc_init_r(void)
{
cl_print_pcb_info();
omap_die_id_display();
return 0;
}
/*
* Routine: set_muxconf_regs
* Description: Setting up the configuration Mux registers specific to the
* hardware. Many pins need to be moved from protect to primary
* mode.
*/
static void cm_t3x_set_common_muxconf(void)
{
/* SDRC */
MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0)); /*SDRC_D0*/
MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0)); /*SDRC_D1*/
MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0)); /*SDRC_D2*/
MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0)); /*SDRC_D3*/
MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0)); /*SDRC_D4*/
MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0)); /*SDRC_D5*/
MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0)); /*SDRC_D6*/
MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0)); /*SDRC_D7*/
MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0)); /*SDRC_D8*/
MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0)); /*SDRC_D9*/
MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0)); /*SDRC_D10*/
MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0)); /*SDRC_D11*/
MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0)); /*SDRC_D12*/
MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0)); /*SDRC_D13*/
MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0)); /*SDRC_D14*/
MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0)); /*SDRC_D15*/
MUX_VAL(CP(SDRC_D16), (IEN | PTD | DIS | M0)); /*SDRC_D16*/
MUX_VAL(CP(SDRC_D17), (IEN | PTD | DIS | M0)); /*SDRC_D17*/
MUX_VAL(CP(SDRC_D18), (IEN | PTD | DIS | M0)); /*SDRC_D18*/
MUX_VAL(CP(SDRC_D19), (IEN | PTD | DIS | M0)); /*SDRC_D19*/
MUX_VAL(CP(SDRC_D20), (IEN | PTD | DIS | M0)); /*SDRC_D20*/
MUX_VAL(CP(SDRC_D21), (IEN | PTD | DIS | M0)); /*SDRC_D21*/
MUX_VAL(CP(SDRC_D22), (IEN | PTD | DIS | M0)); /*SDRC_D22*/
MUX_VAL(CP(SDRC_D23), (IEN | PTD | DIS | M0)); /*SDRC_D23*/
MUX_VAL(CP(SDRC_D24), (IEN | PTD | DIS | M0)); /*SDRC_D24*/
MUX_VAL(CP(SDRC_D25), (IEN | PTD | DIS | M0)); /*SDRC_D25*/
MUX_VAL(CP(SDRC_D26), (IEN | PTD | DIS | M0)); /*SDRC_D26*/
MUX_VAL(CP(SDRC_D27), (IEN | PTD | DIS | M0)); /*SDRC_D27*/
MUX_VAL(CP(SDRC_D28), (IEN | PTD | DIS | M0)); /*SDRC_D28*/
MUX_VAL(CP(SDRC_D29), (IEN | PTD | DIS | M0)); /*SDRC_D29*/
MUX_VAL(CP(SDRC_D30), (IEN | PTD | DIS | M0)); /*SDRC_D30*/
MUX_VAL(CP(SDRC_D31), (IEN | PTD | DIS | M0)); /*SDRC_D31*/
MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0)); /*SDRC_CLK*/
MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0)); /*SDRC_DQS0*/
MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0)); /*SDRC_DQS1*/
MUX_VAL(CP(SDRC_DQS2), (IEN | PTD | DIS | M0)); /*SDRC_DQS2*/
MUX_VAL(CP(SDRC_DQS3), (IEN | PTD | DIS | M0)); /*SDRC_DQS3*/
MUX_VAL(CP(SDRC_CKE0), (IDIS | PTU | EN | M0)); /*SDRC_CKE0*/
MUX_VAL(CP(SDRC_CKE1), (IDIS | PTD | DIS | M7)); /*SDRC_CKE1*/
/* GPMC */
MUX_VAL(CP(GPMC_A1), (IDIS | PTU | EN | M0)); /*GPMC_A1*/
MUX_VAL(CP(GPMC_A2), (IDIS | PTU | EN | M0)); /*GPMC_A2*/
MUX_VAL(CP(GPMC_A3), (IDIS | PTU | EN | M0)); /*GPMC_A3*/
MUX_VAL(CP(GPMC_A4), (IDIS | PTU | EN | M0)); /*GPMC_A4*/
MUX_VAL(CP(GPMC_A5), (IDIS | PTU | EN | M0)); /*GPMC_A5*/
MUX_VAL(CP(GPMC_A6), (IDIS | PTU | EN | M0)); /*GPMC_A6*/
MUX_VAL(CP(GPMC_A7), (IDIS | PTU | EN | M0)); /*GPMC_A7*/
MUX_VAL(CP(GPMC_A8), (IDIS | PTU | EN | M0)); /*GPMC_A8*/
MUX_VAL(CP(GPMC_A9), (IDIS | PTU | EN | M0)); /*GPMC_A9*/
MUX_VAL(CP(GPMC_A10), (IDIS | PTU | EN | M0)); /*GPMC_A10*/
MUX_VAL(CP(GPMC_D0), (IEN | PTU | EN | M0)); /*GPMC_D0*/
MUX_VAL(CP(GPMC_D1), (IEN | PTU | EN | M0)); /*GPMC_D1*/
MUX_VAL(CP(GPMC_D2), (IEN | PTU | EN | M0)); /*GPMC_D2*/
MUX_VAL(CP(GPMC_D3), (IEN | PTU | EN | M0)); /*GPMC_D3*/
MUX_VAL(CP(GPMC_D4), (IEN | PTU | EN | M0)); /*GPMC_D4*/
MUX_VAL(CP(GPMC_D5), (IEN | PTU | EN | M0)); /*GPMC_D5*/
MUX_VAL(CP(GPMC_D6), (IEN | PTU | EN | M0)); /*GPMC_D6*/
MUX_VAL(CP(GPMC_D7), (IEN | PTU | EN | M0)); /*GPMC_D7*/
MUX_VAL(CP(GPMC_D8), (IEN | PTU | EN | M0)); /*GPMC_D8*/
MUX_VAL(CP(GPMC_D9), (IEN | PTU | EN | M0)); /*GPMC_D9*/
MUX_VAL(CP(GPMC_D10), (IEN | PTU | EN | M0)); /*GPMC_D10*/
MUX_VAL(CP(GPMC_D11), (IEN | PTU | EN | M0)); /*GPMC_D11*/
MUX_VAL(CP(GPMC_D12), (IEN | PTU | EN | M0)); /*GPMC_D12*/
MUX_VAL(CP(GPMC_D13), (IEN | PTU | EN | M0)); /*GPMC_D13*/
MUX_VAL(CP(GPMC_D14), (IEN | PTU | EN | M0)); /*GPMC_D14*/
MUX_VAL(CP(GPMC_D15), (IEN | PTU | EN | M0)); /*GPMC_D15*/
MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN | M0)); /*GPMC_nCS0*/
/* SB-T35 Ethernet */
MUX_VAL(CP(GPMC_NCS4), (IEN | PTU | EN | M0)); /*GPMC_nCS4*/
/* DVI enable */
MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | DIS | M4));/*GPMC_nCS3*/
/* DataImage backlight */
MUX_VAL(CP(GPMC_NCS7), (IDIS | PTU | DIS | M4));/*GPIO_58*/
/* CM-T3x Ethernet */
MUX_VAL(CP(GPMC_NCS5), (IDIS | PTU | DIS | M0)); /*GPMC_nCS5*/
MUX_VAL(CP(GPMC_CLK), (IEN | PTD | DIS | M4)); /*GPIO_59*/
MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0)); /*nADV_ALE*/
MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0)); /*nOE*/
MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0)); /*nWE*/
MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTU | EN | M0)); /*nBE0_CLE*/
MUX_VAL(CP(GPMC_NBE1), (IDIS | PTD | DIS | M4)); /*GPIO_61*/
MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0)); /*nWP*/
MUX_VAL(CP(GPMC_WAIT0), (IEN | PTU | EN | M0)); /*WAIT0*/
/* DSS */
MUX_VAL(CP(DSS_PCLK), (IDIS | PTD | DIS | M0)); /*DSS_PCLK*/
MUX_VAL(CP(DSS_HSYNC), (IDIS | PTD | DIS | M0)); /*DSS_HSYNC*/
MUX_VAL(CP(DSS_VSYNC), (IDIS | PTD | DIS | M0)); /*DSS_VSYNC*/
MUX_VAL(CP(DSS_ACBIAS), (IDIS | PTD | DIS | M0)); /*DSS_ACBIAS*/
MUX_VAL(CP(DSS_DATA6), (IDIS | PTD | DIS | M0)); /*DSS_DATA6*/
MUX_VAL(CP(DSS_DATA7), (IDIS | PTD | DIS | M0)); /*DSS_DATA7*/
MUX_VAL(CP(DSS_DATA8), (IDIS | PTD | DIS | M0)); /*DSS_DATA8*/
MUX_VAL(CP(DSS_DATA9), (IDIS | PTD | DIS | M0)); /*DSS_DATA9*/
MUX_VAL(CP(DSS_DATA10), (IDIS | PTD | DIS | M0)); /*DSS_DATA10*/
MUX_VAL(CP(DSS_DATA11), (IDIS | PTD | DIS | M0)); /*DSS_DATA11*/
MUX_VAL(CP(DSS_DATA12), (IDIS | PTD | DIS | M0)); /*DSS_DATA12*/
MUX_VAL(CP(DSS_DATA13), (IDIS | PTD | DIS | M0)); /*DSS_DATA13*/
MUX_VAL(CP(DSS_DATA14), (IDIS | PTD | DIS | M0)); /*DSS_DATA14*/
MUX_VAL(CP(DSS_DATA15), (IDIS | PTD | DIS | M0)); /*DSS_DATA15*/
MUX_VAL(CP(DSS_DATA16), (IDIS | PTD | DIS | M0)); /*DSS_DATA16*/
MUX_VAL(CP(DSS_DATA17), (IDIS | PTD | DIS | M0)); /*DSS_DATA17*/
/* serial interface */
MUX_VAL(CP(UART3_RX_IRRX), (IEN | PTD | DIS | M0)); /*UART3_RX*/
MUX_VAL(CP(UART3_TX_IRTX), (IDIS | PTD | DIS | M0)); /*UART3_TX*/
/* mUSB */
MUX_VAL(CP(HSUSB0_CLK), (IEN | PTD | DIS | M0)); /*HSUSB0_CLK*/
MUX_VAL(CP(HSUSB0_STP), (IDIS | PTU | EN | M0)); /*HSUSB0_STP*/
MUX_VAL(CP(HSUSB0_DIR), (IEN | PTD | DIS | M0)); /*HSUSB0_DIR*/
MUX_VAL(CP(HSUSB0_NXT), (IEN | PTD | DIS | M0)); /*HSUSB0_NXT*/
MUX_VAL(CP(HSUSB0_DATA0), (IEN | PTD | DIS | M0)); /*HSUSB0_DATA0*/
MUX_VAL(CP(HSUSB0_DATA1), (IEN | PTD | DIS | M0)); /*HSUSB0_DATA1*/
MUX_VAL(CP(HSUSB0_DATA2), (IEN | PTD | DIS | M0)); /*HSUSB0_DATA2*/
MUX_VAL(CP(HSUSB0_DATA3), (IEN | PTD | DIS | M0)); /*HSUSB0_DATA3*/
MUX_VAL(CP(HSUSB0_DATA4), (IEN | PTD | DIS | M0)); /*HSUSB0_DATA4*/
MUX_VAL(CP(HSUSB0_DATA5), (IEN | PTD | DIS | M0)); /*HSUSB0_DATA5*/
MUX_VAL(CP(HSUSB0_DATA6), (IEN | PTD | DIS | M0)); /*HSUSB0_DATA6*/
MUX_VAL(CP(HSUSB0_DATA7), (IEN | PTD | DIS | M0)); /*HSUSB0_DATA7*/
/* USB EHCI */
MUX_VAL(CP(ETK_D0_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT0*/
MUX_VAL(CP(ETK_D1_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT1*/
MUX_VAL(CP(ETK_D2_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT2*/
MUX_VAL(CP(ETK_D7_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT3*/
MUX_VAL(CP(ETK_D4_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT4*/
MUX_VAL(CP(ETK_D5_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT5*/
MUX_VAL(CP(ETK_D6_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT6*/
MUX_VAL(CP(ETK_D3_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT7*/
MUX_VAL(CP(ETK_D8_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DIR*/
MUX_VAL(CP(ETK_D9_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_NXT*/
MUX_VAL(CP(ETK_CTL_ES2), (IDIS | PTD | DIS | M3)); /*HSUSB1_CLK*/
MUX_VAL(CP(ETK_CLK_ES2), (IDIS | PTU | DIS | M3)); /*HSUSB1_STP*/
MUX_VAL(CP(ETK_D14_ES2), (IEN | PTD | EN | M3)); /*HSUSB2_DT0*/
MUX_VAL(CP(ETK_D15_ES2), (IEN | PTD | EN | M3)); /*HSUSB2_DT1*/
MUX_VAL(CP(MCSPI1_CS3), (IEN | PTD | EN | M3)); /*HSUSB2_DT2*/
MUX_VAL(CP(MCSPI2_CS1), (IEN | PTD | EN | M3)); /*HSUSB2_DT3*/
MUX_VAL(CP(MCSPI2_SIMO), (IEN | PTD | EN | M3)); /*HSUSB2_DT4*/
MUX_VAL(CP(MCSPI2_SOMI), (IEN | PTD | EN | M3)); /*HSUSB2_DT5*/
MUX_VAL(CP(MCSPI2_CS0), (IEN | PTD | EN | M3)); /*HSUSB2_DT6*/
MUX_VAL(CP(MCSPI2_CLK), (IEN | PTD | EN | M3)); /*HSUSB2_DT7*/
MUX_VAL(CP(ETK_D12_ES2), (IEN | PTD | EN | M3)); /*HSUSB2_DIR*/
MUX_VAL(CP(ETK_D13_ES2), (IEN | PTD | EN | M3)); /*HSUSB2_NXT*/
MUX_VAL(CP(ETK_D10_ES2), (IDIS | PTD | DIS | M3)); /*HSUSB2_CLK*/
MUX_VAL(CP(ETK_D11_ES2), (IDIS | PTU | DIS | M3)); /*HSUSB2_STP*/
/* SB_T35_USB_HUB_RESET_GPIO */
MUX_VAL(CP(CAM_WEN), (IDIS | PTD | DIS | M4)); /*GPIO_167*/
/* I2C1 */
MUX_VAL(CP(I2C1_SCL), (IEN | PTU | EN | M0)); /*I2C1_SCL*/
MUX_VAL(CP(I2C1_SDA), (IEN | PTU | EN | M0)); /*I2C1_SDA*/
/* I2C2 */
MUX_VAL(CP(I2C2_SCL), (IEN | PTU | EN | M0)); /*I2C2_SCL*/
MUX_VAL(CP(I2C2_SDA), (IEN | PTU | EN | M0)); /*I2C2_SDA*/
/* I2C3 */
MUX_VAL(CP(I2C3_SCL), (IEN | PTU | EN | M0)); /*I2C3_SCL*/
MUX_VAL(CP(I2C3_SDA), (IEN | PTU | EN | M0)); /*I2C3_SDA*/
/* control and debug */
MUX_VAL(CP(SYS_32K), (IEN | PTD | DIS | M0)); /*SYS_32K*/
MUX_VAL(CP(SYS_CLKREQ), (IEN | PTD | DIS | M0)); /*SYS_CLKREQ*/
MUX_VAL(CP(SYS_NIRQ), (IEN | PTU | EN | M0)); /*SYS_nIRQ*/
MUX_VAL(CP(SYS_OFF_MODE), (IEN | PTD | DIS | M0)); /*OFF_MODE*/
MUX_VAL(CP(SYS_CLKOUT1), (IEN | PTD | DIS | M0)); /*CLKOUT1*/
MUX_VAL(CP(SYS_CLKOUT2), (IDIS | PTU | DIS | M4)); /*green LED*/
MUX_VAL(CP(JTAG_NTRST), (IEN | PTD | DIS | M0)); /*JTAG_NTRST*/
MUX_VAL(CP(JTAG_TCK), (IEN | PTD | DIS | M0)); /*JTAG_TCK*/
MUX_VAL(CP(JTAG_TMS), (IEN | PTD | DIS | M0)); /*JTAG_TMS*/
MUX_VAL(CP(JTAG_TDI), (IEN | PTD | DIS | M0)); /*JTAG_TDI*/
/* MMC1 */
MUX_VAL(CP(MMC1_CLK), (IDIS | PTU | EN | M0)); /*MMC1_CLK*/
MUX_VAL(CP(MMC1_CMD), (IEN | PTU | EN | M0)); /*MMC1_CMD*/
MUX_VAL(CP(MMC1_DAT0), (IEN | PTU | EN | M0)); /*MMC1_DAT0*/
MUX_VAL(CP(MMC1_DAT1), (IEN | PTU | EN | M0)); /*MMC1_DAT1*/
MUX_VAL(CP(MMC1_DAT2), (IEN | PTU | EN | M0)); /*MMC1_DAT2*/
MUX_VAL(CP(MMC1_DAT3), (IEN | PTU | EN | M0)); /*MMC1_DAT3*/
/* SPI */
MUX_VAL(CP(MCBSP1_CLKR), (IEN | PTD | DIS | M1)); /*MCSPI4_CLK*/
MUX_VAL(CP(MCBSP1_DX), (IEN | PTD | DIS | M1)); /*MCSPI4_SIMO*/
MUX_VAL(CP(MCBSP1_DR), (IEN | PTD | DIS | M1)); /*MCSPI4_SOMI*/
MUX_VAL(CP(MCBSP1_FSX), (IEN | PTU | EN | M1)); /*MCSPI4_CS0*/
/* display controls */
MUX_VAL(CP(MCBSP1_FSR), (IDIS | PTU | DIS | M4)); /*GPIO_157*/
}
static void cm_t35_set_muxconf(void)
{
/* DSS */
MUX_VAL(CP(DSS_DATA0), (IDIS | PTD | DIS | M0)); /*DSS_DATA0*/
MUX_VAL(CP(DSS_DATA1), (IDIS | PTD | DIS | M0)); /*DSS_DATA1*/
MUX_VAL(CP(DSS_DATA2), (IDIS | PTD | DIS | M0)); /*DSS_DATA2*/
MUX_VAL(CP(DSS_DATA3), (IDIS | PTD | DIS | M0)); /*DSS_DATA3*/
MUX_VAL(CP(DSS_DATA4), (IDIS | PTD | DIS | M0)); /*DSS_DATA4*/
MUX_VAL(CP(DSS_DATA5), (IDIS | PTD | DIS | M0)); /*DSS_DATA5*/
MUX_VAL(CP(DSS_DATA18), (IDIS | PTD | DIS | M0)); /*DSS_DATA18*/
MUX_VAL(CP(DSS_DATA19), (IDIS | PTD | DIS | M0)); /*DSS_DATA19*/
MUX_VAL(CP(DSS_DATA20), (IDIS | PTD | DIS | M0)); /*DSS_DATA20*/
MUX_VAL(CP(DSS_DATA21), (IDIS | PTD | DIS | M0)); /*DSS_DATA21*/
MUX_VAL(CP(DSS_DATA22), (IDIS | PTD | DIS | M0)); /*DSS_DATA22*/
MUX_VAL(CP(DSS_DATA23), (IDIS | PTD | DIS | M0)); /*DSS_DATA23*/
/* MMC1 */
MUX_VAL(CP(MMC1_DAT4), (IEN | PTU | EN | M0)); /*MMC1_DAT4*/
MUX_VAL(CP(MMC1_DAT5), (IEN | PTU | EN | M0)); /*MMC1_DAT5*/
MUX_VAL(CP(MMC1_DAT6), (IEN | PTU | EN | M0)); /*MMC1_DAT6*/
MUX_VAL(CP(MMC1_DAT7), (IEN | PTU | EN | M0)); /*MMC1_DAT7*/
}
static void cm_t3730_set_muxconf(void)
{
/* DSS */
MUX_VAL(CP(DSS_DATA18), (IDIS | PTD | DIS | M3)); /*DSS_DATA0*/
MUX_VAL(CP(DSS_DATA19), (IDIS | PTD | DIS | M3)); /*DSS_DATA1*/
MUX_VAL(CP(DSS_DATA20), (IDIS | PTD | DIS | M3)); /*DSS_DATA2*/
MUX_VAL(CP(DSS_DATA21), (IDIS | PTD | DIS | M3)); /*DSS_DATA3*/
MUX_VAL(CP(DSS_DATA22), (IDIS | PTD | DIS | M3)); /*DSS_DATA4*/
MUX_VAL(CP(DSS_DATA23), (IDIS | PTD | DIS | M3)); /*DSS_DATA5*/
MUX_VAL(CP(SYS_BOOT0), (IDIS | PTD | DIS | M3)); /*DSS_DATA18*/
MUX_VAL(CP(SYS_BOOT1), (IDIS | PTD | DIS | M3)); /*DSS_DATA19*/
MUX_VAL(CP(SYS_BOOT3), (IDIS | PTD | DIS | M3)); /*DSS_DATA20*/
MUX_VAL(CP(SYS_BOOT4), (IDIS | PTD | DIS | M3)); /*DSS_DATA21*/
MUX_VAL(CP(SYS_BOOT5), (IDIS | PTD | DIS | M3)); /*DSS_DATA22*/
MUX_VAL(CP(SYS_BOOT6), (IDIS | PTD | DIS | M3)); /*DSS_DATA23*/
}
void set_muxconf_regs(void)
{
cm_t3x_set_common_muxconf();
if (get_cpu_family() == CPU_OMAP34XX)
cm_t35_set_muxconf();
else
cm_t3730_set_muxconf();
}
#if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
#define SB_T35_WP_GPIO 59
int board_mmc_getcd(struct mmc *mmc)
{
u8 val;
if (twl4030_i2c_read_u8(TWL4030_CHIP_GPIO, TWL4030_BASEADD_GPIO, &val))
return -1;
return !(val & 1);
}
int board_mmc_init(bd_t *bis)
{
return omap_mmc_init(0, 0, 0, -1, SB_T35_WP_GPIO);
}
#endif
#if defined(CONFIG_GENERIC_MMC)
void board_mmc_power_init(void)
{
twl4030_power_mmc_init(0);
}
#endif
#ifdef CONFIG_SYS_I2C_OMAP34XX
/*
* Routine: reset_net_chip
* Description: reset the Ethernet controller via TPS65930 GPIO
*/
static int cm_t3x_reset_net_chip(int gpio)
{
/* Set GPIO1 of TPS65930 as output */
twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, TWL4030_BASEADD_GPIO + 0x03,
0x02);
/* Send a pulse on the GPIO pin */
twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, TWL4030_BASEADD_GPIO + 0x0C,
0x02);
udelay(1);
twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, TWL4030_BASEADD_GPIO + 0x09,
0x02);
mdelay(40);
twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, TWL4030_BASEADD_GPIO + 0x0C,
0x02);
mdelay(1);
return 0;
}
#else
static inline int cm_t3x_reset_net_chip(int gpio) { return 0; }
#endif
#ifdef CONFIG_SMC911X
/*
* Routine: handle_mac_address
* Description: prepare MAC address for on-board Ethernet.
*/
static int handle_mac_address(void)
{
unsigned char enetaddr[6];
int rc;
rc = eth_getenv_enetaddr("ethaddr", enetaddr);
if (rc)
return 0;
rc = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS);
if (rc)
return rc;
if (!is_valid_ethaddr(enetaddr))
return -1;
return eth_setenv_enetaddr("ethaddr", enetaddr);
}
/*
* Routine: board_eth_init
* Description: initialize module and base-board Ethernet chips
*/
int board_eth_init(bd_t *bis)
{
int rc = 0, rc1 = 0;
rc1 = handle_mac_address();
if (rc1)
printf("No MAC address found! ");
rc1 = cl_omap3_smc911x_init(0, 5, CM_T3X_SMC911X_BASE,
cm_t3x_reset_net_chip, -EINVAL);
if (rc1 > 0)
rc++;
rc1 = cl_omap3_smc911x_init(1, 4, SB_T35_SMC911X_BASE, NULL, -EINVAL);
if (rc1 > 0)
rc++;
return rc;
}
#endif
#ifdef CONFIG_USB_EHCI_OMAP
struct omap_usbhs_board_data usbhs_bdata = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
.port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
};
#define SB_T35_USB_HUB_RESET_GPIO 167
int ehci_hcd_init(int index, enum usb_init_type init,
struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
u8 val;
int offset;
cl_usb_hub_init(SB_T35_USB_HUB_RESET_GPIO, "sb-t35 hub rst");
offset = TWL4030_BASEADD_GPIO + TWL4030_GPIO_GPIODATADIR1;
twl4030_i2c_read_u8(TWL4030_CHIP_GPIO, offset, &val);
/* Set GPIO6 and GPIO7 of TPS65930 as output */
val |= 0xC0;
twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, offset, val);
offset = TWL4030_BASEADD_GPIO + TWL4030_GPIO_SETGPIODATAOUT1;
/* Take both PHYs out of reset */
twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, offset, 0xC0);
udelay(1);
return omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor);
}
int ehci_hcd_stop(void)
{
cl_usb_hub_deinit(SB_T35_USB_HUB_RESET_GPIO);
return omap_ehci_hcd_stop();
}
#endif /* CONFIG_USB_EHCI_OMAP */

View File

@@ -0,0 +1,12 @@
if TARGET_CM_T3517
config SYS_BOARD
default "cm_t3517"
config SYS_VENDOR
default "compulab"
config SYS_CONFIG_NAME
default "cm_t3517"
endif

View File

@@ -0,0 +1,6 @@
CM_T3517 BOARD
M: Igor Grinberg <grinberg@compulab.co.il>
S: Maintained
F: board/compulab/cm_t3517/
F: include/configs/cm_t3517.h
F: configs/cm_t3517_defconfig

View File

@@ -0,0 +1,9 @@
#
# (C) Copyright 2014 CompuLab, Ltd. <www.compulab.co.il>
#
# Authors: Igor Grinberg <grinberg@compulab.co.il>
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += cm_t3517.o mux.o

View File

@@ -0,0 +1,240 @@
/*
* (C) Copyright 2014 CompuLab, Ltd. <www.compulab.co.il>
*
* Authors: Igor Grinberg <grinberg@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <status_led.h>
#include <net.h>
#include <netdev.h>
#include <usb.h>
#include <mmc.h>
#include <linux/compiler.h>
#include <linux/usb/musb.h>
#include <asm/io.h>
#include <asm/arch/mem.h>
#include <asm/arch/am35x_def.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/musb.h>
#include <asm/omap_musb.h>
#include <asm/ehci-omap.h>
#include "../common/common.h"
#include "../common/eeprom.h"
DECLARE_GLOBAL_DATA_PTR;
const omap3_sysinfo sysinfo = {
DDR_DISCRETE,
"CM-T3517 board",
"NAND 128/512M",
};
#ifdef CONFIG_USB_MUSB_AM35X
static struct musb_hdrc_config cm_t3517_musb_config = {
.multipoint = 1,
.dyn_fifo = 1,
.num_eps = 16,
.ram_bits = 12,
};
static struct omap_musb_board_data cm_t3517_musb_board_data = {
.set_phy_power = am35x_musb_phy_power,
.clear_irq = am35x_musb_clear_irq,
.reset = am35x_musb_reset,
};
static struct musb_hdrc_platform_data cm_t3517_musb_pdata = {
#if defined(CONFIG_USB_MUSB_HOST)
.mode = MUSB_HOST,
#elif defined(CONFIG_USB_MUSB_GADGET)
.mode = MUSB_PERIPHERAL,
#else
#error "Please define either CONFIG_USB_MUSB_HOST or CONFIG_USB_MUSB_GADGET"
#endif
.config = &cm_t3517_musb_config,
.power = 250,
.platform_ops = &am35x_ops,
.board_data = &cm_t3517_musb_board_data,
};
static void cm_t3517_musb_init(void)
{
/*
* Set up USB clock/mode in the DEVCONF2 register.
* USB2.0 PHY reference clock is 13 MHz
*/
clrsetbits_le32(&am35x_scm_general_regs->devconf2,
CONF2_REFFREQ | CONF2_OTGMODE | CONF2_PHY_GPIOMODE,
CONF2_REFFREQ_13MHZ | CONF2_SESENDEN |
CONF2_VBDTCTEN | CONF2_DATPOL);
if (musb_register(&cm_t3517_musb_pdata, &cm_t3517_musb_board_data,
(void *)AM35XX_IPSS_USBOTGSS_BASE))
printf("Failed initializing AM35x MUSB!\n");
}
#else
static inline void am3517_evm_musb_init(void) {}
#endif
int board_init(void)
{
gpmc_init(); /* in SRAM or SDRAM, finish GPMC */
/* boot param addr */
gd->bd->bi_boot_params = (OMAP34XX_SDRC_CS0 + 0x100);
#if defined(CONFIG_STATUS_LED) && defined(STATUS_LED_BOOT)
status_led_set(STATUS_LED_BOOT, STATUS_LED_ON);
#endif
cm_t3517_musb_init();
return 0;
}
/*
* Routine: get_board_rev
* Description: read system revision
*/
u32 get_board_rev(void)
{
return cl_eeprom_get_board_rev(CONFIG_SYS_I2C_EEPROM_BUS);
};
int misc_init_r(void)
{
cl_print_pcb_info();
omap_die_id_display();
return 0;
}
#if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
#define SB_T35_CD_GPIO 144
#define SB_T35_WP_GPIO 59
int board_mmc_init(bd_t *bis)
{
return omap_mmc_init(0, 0, 0, SB_T35_CD_GPIO, SB_T35_WP_GPIO);
}
#endif
#ifdef CONFIG_DRIVER_TI_EMAC
#define CONTROL_EFUSE_EMAC_LSB 0x48002380
#define CONTROL_EFUSE_EMAC_MSB 0x48002384
static int am3517_get_efuse_enetaddr(u8 *enetaddr)
{
u32 lsb = __raw_readl(CONTROL_EFUSE_EMAC_LSB);
u32 msb = __raw_readl(CONTROL_EFUSE_EMAC_MSB);
enetaddr[0] = (u8)((msb >> 16) & 0xff);
enetaddr[1] = (u8)((msb >> 8) & 0xff);
enetaddr[2] = (u8)(msb & 0xff);
enetaddr[3] = (u8)((lsb >> 16) & 0xff);
enetaddr[4] = (u8)((lsb >> 8) & 0xff);
enetaddr[5] = (u8)(lsb & 0xff);
return is_valid_ethaddr(enetaddr);
}
static inline int cm_t3517_init_emac(bd_t *bis)
{
int ret = cpu_eth_init(bis);
if (ret > 0)
return ret;
printf("Failed initializing EMAC! ");
return 0;
}
#else /* !CONFIG_DRIVER_TI_EMAC */
static inline int am3517_get_efuse_enetaddr(u8 *enetaddr) { return 1; }
static inline int cm_t3517_init_emac(bd_t *bis) { return 0; }
#endif /* CONFIG_DRIVER_TI_EMAC */
/*
* Routine: handle_mac_address
* Description: prepare MAC address for on-board Ethernet.
*/
static int cm_t3517_handle_mac_address(void)
{
unsigned char enetaddr[6];
int ret;
ret = eth_getenv_enetaddr("ethaddr", enetaddr);
if (ret)
return 0;
ret = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS);
if (ret) {
ret = am3517_get_efuse_enetaddr(enetaddr);
if (ret)
return ret;
}
if (!is_valid_ethaddr(enetaddr))
return -1;
return eth_setenv_enetaddr("ethaddr", enetaddr);
}
#define SB_T35_ETH_RST_GPIO 164
/*
* Routine: board_eth_init
* Description: initialize module and base-board Ethernet chips
*/
int board_eth_init(bd_t *bis)
{
int rc = 0, rc1 = 0;
rc1 = cm_t3517_handle_mac_address();
if (rc1)
printf("No MAC address found! ");
rc1 = cm_t3517_init_emac(bis);
if (rc1 > 0)
rc++;
rc1 = cl_omap3_smc911x_init(0, 4, CONFIG_SMC911X_BASE,
NULL, SB_T35_ETH_RST_GPIO);
if (rc1 > 0)
rc++;
return rc;
}
#ifdef CONFIG_USB_EHCI_OMAP
static struct omap_usbhs_board_data cm_t3517_usbhs_bdata = {
.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
.port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
};
#define CM_T3517_USB_HUB_RESET_GPIO 152
#define SB_T35_USB_HUB_RESET_GPIO 98
int ehci_hcd_init(int index, enum usb_init_type init,
struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
cl_usb_hub_init(CM_T3517_USB_HUB_RESET_GPIO, "cm-t3517 hub rst");
cl_usb_hub_init(SB_T35_USB_HUB_RESET_GPIO, "sb-t35 hub rst");
return omap_ehci_hcd_init(index, &cm_t3517_usbhs_bdata, hccr, hcor);
}
int ehci_hcd_stop(void)
{
cl_usb_hub_deinit(CM_T3517_USB_HUB_RESET_GPIO);
cl_usb_hub_deinit(SB_T35_USB_HUB_RESET_GPIO);
return omap_ehci_hcd_stop();
}
#endif /* CONFIG_USB_EHCI_OMAP */

View File

@@ -0,0 +1,236 @@
/*
* (C) Copyright 2014 CompuLab, Ltd. <www.compulab.co.il>
*
* Authors: Igor Grinberg <grinberg@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/mux.h>
#include <asm/io.h>
void set_muxconf_regs(void)
{
/* SDRC */
MUX_VAL(CP(SDRC_D0), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D1), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D2), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D3), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D4), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D5), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D6), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D7), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D8), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D9), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D10), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D11), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D12), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D13), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D14), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D15), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D16), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D17), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D18), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D19), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D20), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D21), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D22), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D23), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D24), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D25), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D26), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D27), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D28), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D29), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D30), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_D31), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_CLK), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_DQS0), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_DQS1), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_DQS2), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_DQS3), (IEN | PTD | DIS | M0));
MUX_VAL(CP(SDRC_CKE0), (IDIS | PTU | EN | M0));
MUX_VAL(CP(SDRC_CKE1), (IDIS | PTD | DIS | M7));
/* GPMC */
MUX_VAL(CP(GPMC_A1), (IDIS | PTU | EN | M0));
MUX_VAL(CP(GPMC_A2), (IDIS | PTU | EN | M0));
MUX_VAL(CP(GPMC_A3), (IDIS | PTU | EN | M0));
MUX_VAL(CP(GPMC_A4), (IDIS | PTU | EN | M0));
MUX_VAL(CP(GPMC_A5), (IDIS | PTU | EN | M0));
MUX_VAL(CP(GPMC_A6), (IDIS | PTU | EN | M0));
MUX_VAL(CP(GPMC_A7), (IDIS | PTU | EN | M0));
MUX_VAL(CP(GPMC_A8), (IDIS | PTU | EN | M0));
MUX_VAL(CP(GPMC_A9), (IDIS | PTU | EN | M0));
MUX_VAL(CP(GPMC_A10), (IDIS | PTU | EN | M0));
MUX_VAL(CP(GPMC_D0), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D1), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D2), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D3), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D4), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D5), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D6), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D7), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D8), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D9), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D10), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D11), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D12), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D13), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D14), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_D15), (IEN | PTU | EN | M0));
MUX_VAL(CP(GPMC_NCS0), (IDIS | PTU | EN | M0));
/* SB-T35 Ethernet */
MUX_VAL(CP(GPMC_NCS4), (IEN | PTU | EN | M0));
/* DVI enable */
MUX_VAL(CP(GPMC_NCS3), (IDIS | PTU | DIS | M4));/*GPIO_54*/
/* DataImage backlight */
MUX_VAL(CP(GPMC_NCS7), (IDIS | PTU | DIS | M4));/*GPIO_58*/
/* SB-T35 SD/MMC WP GPIO59 */
MUX_VAL(CP(GPMC_CLK), (IEN | PTU | EN | M4)); /*GPIO_59*/
MUX_VAL(CP(GPMC_NWE), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(GPMC_NOE), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(GPMC_NADV_ALE), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(GPMC_NBE0_CLE), (IDIS | PTU | EN | M0));
/* SB-T35 Audio Enable GPIO61 */
MUX_VAL(CP(GPMC_NBE1), (IDIS | PTU | EN | M4)); /*GPIO_61*/
MUX_VAL(CP(GPMC_NWP), (IEN | PTD | DIS | M0));
MUX_VAL(CP(GPMC_WAIT0), (IEN | PTU | EN | M0));
/* SB-T35 Ethernet IRQ GPIO65 */
MUX_VAL(CP(GPMC_WAIT3), (IEN | PTU | EN | M4)); /*GPIO_65*/
/* UART3 Console */
MUX_VAL(CP(UART3_RX_IRRX), (IEN | PTD | DIS | M0));
MUX_VAL(CP(UART3_TX_IRTX), (IDIS | PTD | DIS | M0));
/* RTC V3020 nCS GPIO163 */
MUX_VAL(CP(UART3_CTS_RCTX), (IEN | PTU | EN | M4)); /*GPIO_163*/
/* SB-T35 Ethernet nRESET GPIO164 */
MUX_VAL(CP(UART3_RTS_SD), (IDIS | PTU | EN | M4)); /*GPIO_164*/
/* SB-T35 SD/MMC CD GPIO144 */
MUX_VAL(CP(UART2_CTS), (IEN | PTU | EN | M4)); /*GPIO_144*/
/* WIFI nRESET GPIO145 */
MUX_VAL(CP(UART2_RTS), (IEN | PTD | EN | M4)); /*GPIO_145*/
/* USB1 PHY Reset GPIO 146 */
MUX_VAL(CP(UART2_TX), (IEN | PTD | EN | M4)); /*GPIO_146*/
/* USB2 PHY Reset GPIO 147 */
MUX_VAL(CP(UART2_RX), (IEN | PTD | EN | M4)); /*GPIO_147*/
/* MMC1 */
MUX_VAL(CP(MMC1_CLK), (IEN | PTU | EN | M0));
MUX_VAL(CP(MMC1_CMD), (IEN | PTU | DIS | M0));
MUX_VAL(CP(MMC1_DAT0), (IEN | PTU | DIS | M0));
MUX_VAL(CP(MMC1_DAT1), (IEN | PTU | DIS | M0));
MUX_VAL(CP(MMC1_DAT2), (IEN | PTU | DIS | M0));
MUX_VAL(CP(MMC1_DAT3), (IEN | PTU | DIS | M0));
/* DSS */
MUX_VAL(CP(DSS_PCLK), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_HSYNC), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_VSYNC), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_ACBIAS), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA0), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA1), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA2), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA3), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA4), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA5), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA6), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA7), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA8), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA9), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA10), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA11), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA12), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA13), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA14), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA15), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA16), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA17), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA18), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA19), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA20), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA21), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA22), (IDIS | PTD | DIS | M0));
MUX_VAL(CP(DSS_DATA23), (IDIS | PTD | DIS | M0));
/* I2C */
MUX_VAL(CP(I2C1_SCL), (IEN | PTU | EN | M0));
MUX_VAL(CP(I2C1_SDA), (IEN | PTU | EN | M0));
MUX_VAL(CP(I2C3_SCL), (IEN | PTU | EN | M0));
MUX_VAL(CP(I2C3_SDA), (IEN | PTU | EN | M0));
/* SB-T35 USB HUB Reset GPIO98 */
MUX_VAL(CP(CCDC_WEN), (IDIS | PTU | EN | M4)); /*GPIO_98*/
/* CM-T3517 USB HUB Reset GPIO152 */
MUX_VAL(CP(MCBSP4_CLKX), (IDIS | PTD | DIS | M4)); /*GPIO_152*/
/* RMII */
MUX_VAL(CP(RMII_MDIO_DATA), (IEN | PTU | EN | M0));
MUX_VAL(CP(RMII_MDIO_CLK), (M0));
MUX_VAL(CP(RMII_RXD0), (IEN | PTD | DIS | M0));
MUX_VAL(CP(RMII_RXD1), (IEN | PTD | DIS | M0));
MUX_VAL(CP(RMII_CRS_DV), (IEN | PTD | DIS | M0));
MUX_VAL(CP(RMII_RXER), (IEN | PTD | DIS | M0));
MUX_VAL(CP(RMII_TXD0), (IDIS | M0));
MUX_VAL(CP(RMII_TXD1), (IDIS | M0));
MUX_VAL(CP(RMII_TXEN), (IDIS | M0));
MUX_VAL(CP(RMII_50MHZ_CLK), (IEN | PTU | DIS | M0));
/* Green LED GPIO186 */
MUX_VAL(CP(SYS_CLKOUT2), (IDIS | PTU | DIS | M4)); /*GPIO_186*/
/* SPI */
MUX_VAL(CP(MCBSP1_CLKR), (IEN | PTD | DIS | M1)); /*MCSPI4_CLK*/
MUX_VAL(CP(MCBSP1_DX), (IEN | PTD | DIS | M1)); /*MCSPI4_SIMO*/
MUX_VAL(CP(MCBSP1_DR), (IEN | PTD | DIS | M1)); /*MCSPI4_SOMI*/
MUX_VAL(CP(MCBSP1_FSX), (IEN | PTU | EN | M1)); /*MCSPI4_CS0*/
/* LCD reset GPIO157 */
MUX_VAL(CP(MCBSP1_FSR), (IDIS | PTU | DIS | M4)); /*GPIO_157*/
/* RTC V3020 CS Enable GPIO160 */
MUX_VAL(CP(MCBSP_CLKS), (IEN | PTD | EN | M4)); /*GPIO_160*/
/* SB-T35 LVDS Transmitter SHDN GPIO162 */
MUX_VAL(CP(MCBSP1_CLKX), (IEN | PTU | DIS | M4)); /*GPIO_162*/
/* USB0 - mUSB */
MUX_VAL(CP(USB0_DRVBUS), (IEN | PTD | EN | M0));
/* USB1 EHCI */
MUX_VAL(CP(ETK_D0_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT0*/
MUX_VAL(CP(ETK_D1_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT1*/
MUX_VAL(CP(ETK_D2_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT2*/
MUX_VAL(CP(ETK_D7_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT3*/
MUX_VAL(CP(ETK_D4_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT4*/
MUX_VAL(CP(ETK_D5_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT5*/
MUX_VAL(CP(ETK_D6_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT6*/
MUX_VAL(CP(ETK_D3_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DT7*/
MUX_VAL(CP(ETK_D8_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_DIR*/
MUX_VAL(CP(ETK_D9_ES2), (IEN | PTD | EN | M3)); /*HSUSB1_NXT*/
MUX_VAL(CP(ETK_CTL_ES2), (IDIS | PTD | DIS | M3)); /*HSUSB1_CLK*/
MUX_VAL(CP(ETK_CLK_ES2), (IDIS | PTU | DIS | M3)); /*HSUSB1_STP*/
/* USB2 EHCI */
MUX_VAL(CP(ETK_D14_ES2), (IEN | PTD | EN | M3)); /*HSUSB2_DT0*/
MUX_VAL(CP(ETK_D15_ES2), (IEN | PTD | EN | M3)); /*HSUSB2_DT1*/
MUX_VAL(CP(MCSPI1_CS3), (IEN | PTD | EN | M3)); /*HSUSB2_DT2*/
MUX_VAL(CP(MCSPI2_CS1), (IEN | PTD | EN | M3)); /*HSUSB2_DT3*/
MUX_VAL(CP(MCSPI2_SIMO), (IEN | PTD | EN | M3)); /*HSUSB2_DT4*/
MUX_VAL(CP(MCSPI2_SOMI), (IEN | PTD | EN | M3)); /*HSUSB2_DT5*/
MUX_VAL(CP(MCSPI2_CS0), (IEN | PTD | EN | M3)); /*HSUSB2_DT6*/
MUX_VAL(CP(MCSPI2_CLK), (IEN | PTD | EN | M3)); /*HSUSB2_DT7*/
MUX_VAL(CP(ETK_D12_ES2), (IEN | PTD | EN | M3)); /*HSUSB2_DIR*/
MUX_VAL(CP(ETK_D13_ES2), (IEN | PTD | EN | M3)); /*HSUSB2_NXT*/
MUX_VAL(CP(ETK_D10_ES2), (IDIS | PTD | DIS | M3)); /*HSUSB2_CLK*/
MUX_VAL(CP(ETK_D11_ES2), (IDIS | PTU | DIS | M3)); /*HSUSB2_STP*/
/* SYS_BOOT */
MUX_VAL(CP(SYS_BOOT0), (IEN | PTU | DIS | M4)); /*GPIO_2*/
MUX_VAL(CP(SYS_BOOT1), (IEN | PTU | DIS | M4)); /*GPIO_3*/
MUX_VAL(CP(SYS_BOOT2), (IEN | PTU | DIS | M4)); /*GPIO_4*/
MUX_VAL(CP(SYS_BOOT3), (IEN | PTU | DIS | M4)); /*GPIO_5*/
MUX_VAL(CP(SYS_BOOT4), (IEN | PTU | DIS | M4)); /*GPIO_6*/
MUX_VAL(CP(SYS_BOOT5), (IEN | PTU | DIS | M4)); /*GPIO_7*/
}

View File

@@ -0,0 +1,15 @@
if TARGET_CM_T43
config SYS_BOARD
default "cm_t43"
config SYS_VENDOR
default "compulab"
config SYS_SOC
default "am33xx"
config SYS_CONFIG_NAME
default "cm_t43"
endif

View File

@@ -0,0 +1,6 @@
CM_T43 BOARD
M: Nikita Kiryanov <nikita@compulab.co.il>
S: Maintained
F: board/compulab/cm_t43/
F: include/configs/cm_t43.h
F: configs/cm_t43_defconfig

View File

@@ -0,0 +1,13 @@
#
# Makefile
#
# Copyright (C) 2015 Compulab, Ltd.
#
# SPDX-License-Identifier: GPL-2.0+
#
ifdef CONFIG_SPL_BUILD
obj-y += spl.o mux.o
else
obj-y += cm_t43.o mux.o
endif

View File

@@ -0,0 +1,12 @@
/*
* Copyright (C) 2015 Compulab, Ltd.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _BOARD_H_
#define _BOARD_H_
void set_i2c_pin_mux(void);
void set_mdio_pin_mux(void);
void set_rgmii_pin_mux(void);
#endif

View File

@@ -0,0 +1,151 @@
/*
* Copyright (C) 2015 Compulab, Ltd.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <i2c.h>
#include <miiphy.h>
#include <cpsw.h>
#include <asm/gpio.h>
#include <asm/arch/sys_proto.h>
#include <asm/emif.h>
#include <power/pmic.h>
#include <power/tps65218.h>
#include "board.h"
DECLARE_GLOBAL_DATA_PTR;
static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
/* setup board specific PMIC */
int power_init_board(void)
{
struct pmic *p;
uchar tps_status = 0;
power_tps65218_init(I2C_PMIC);
p = pmic_get("TPS65218_PMIC");
if (p && !pmic_probe(p)) {
puts("PMIC: TPS65218\n");
/* We don't care if fseal is locked, but we do need it set */
tps65218_lock_fseal();
tps65218_reg_read(TPS65218_STATUS, &tps_status);
if (!(tps_status & TPS65218_FSEAL))
printf("WARNING: RTC not backed by battery!\n");
}
return 0;
}
int board_init(void)
{
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
gpmc_init();
set_i2c_pin_mux();
i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
i2c_probe(TPS65218_CHIP_PM);
return 0;
}
#ifdef CONFIG_DRIVER_TI_CPSW
static void cpsw_control(int enabled)
{
return;
}
static struct cpsw_slave_data cpsw_slaves[] = {
{
.slave_reg_ofs = 0x208,
.sliver_reg_ofs = 0xd80,
.phy_addr = 0,
.phy_if = PHY_INTERFACE_MODE_RGMII,
},
{
.slave_reg_ofs = 0x308,
.sliver_reg_ofs = 0xdc0,
.phy_addr = 1,
.phy_if = PHY_INTERFACE_MODE_RGMII,
},
};
static struct cpsw_platform_data cpsw_data = {
.mdio_base = CPSW_MDIO_BASE,
.cpsw_base = CPSW_BASE,
.mdio_div = 0xff,
.channels = 8,
.cpdma_reg_ofs = 0x800,
.slaves = 2,
.slave_data = cpsw_slaves,
.ale_reg_ofs = 0xd00,
.ale_entries = 1024,
.host_port_reg_ofs = 0x108,
.hw_stats_reg_ofs = 0x900,
.bd_ram_ofs = 0x2000,
.mac_control = (1 << 5),
.control = cpsw_control,
.host_port_num = 0,
.version = CPSW_CTRL_VERSION_2,
};
#define GPIO_PHY1_RST 170
#define GPIO_PHY2_RST 168
int board_phy_config(struct phy_device *phydev)
{
unsigned short val;
/* introduce tx clock delay */
phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
val |= 0x0100;
phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
if (phydev->drv->config)
return phydev->drv->config(phydev);
return 0;
}
static void board_phy_init(void)
{
set_mdio_pin_mux();
writel(0x40003, 0x44e10a74); /* Mux pin as clkout2 */
writel(0x10006, 0x44df4108); /* Select EXTDEV as clock source */
writel(0x4, 0x44df2e60); /* Set EXTDEV as MNbypass */
/* For revision A */
writel(0x2000009, 0x44df2e6c);
writel(0x38a, 0x44df2e70);
mdelay(10);
gpio_request(GPIO_PHY1_RST, "phy1_rst");
gpio_request(GPIO_PHY2_RST, "phy2_rst");
gpio_direction_output(GPIO_PHY1_RST, 0);
gpio_direction_output(GPIO_PHY2_RST, 0);
mdelay(2);
gpio_set_value(GPIO_PHY1_RST, 1);
gpio_set_value(GPIO_PHY2_RST, 1);
mdelay(2);
}
int board_eth_init(bd_t *bis)
{
int rv;
set_rgmii_pin_mux();
writel(RGMII_MODE_ENABLE | RGMII_INT_DELAY, &cdev->miisel);
board_phy_init();
rv = cpsw_register(&cpsw_data);
if (rv < 0)
printf("Error %d registering CPSW switch\n", rv);
return rv;
}
#endif

View File

@@ -0,0 +1,143 @@
/*
* Copyright (C) 2015 Compulab, Ltd.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/mux.h>
#include "board.h"
static struct module_pin_mux rgmii1_pin_mux[] = {
{OFFSET(mii1_txen), MODE(2)},
{OFFSET(mii1_txd3), MODE(2)},
{OFFSET(mii1_txd2), MODE(2)},
{OFFSET(mii1_txd1), MODE(2)},
{OFFSET(mii1_txd0), MODE(2)},
{OFFSET(mii1_txclk), MODE(2)},
{OFFSET(mii1_rxdv), MODE(2) | RXACTIVE | PULLDOWN_EN},
{OFFSET(mii1_rxclk), MODE(2) | RXACTIVE | PULLDOWN_EN},
{OFFSET(mii1_rxd3), MODE(2) | RXACTIVE | PULLDOWN_EN},
{OFFSET(mii1_rxd2), MODE(2) | RXACTIVE | PULLDOWN_EN},
{OFFSET(mii1_rxd1), MODE(2) | RXACTIVE | PULLDOWN_EN},
{OFFSET(mii1_rxd0), MODE(2) | RXACTIVE | PULLDOWN_EN},
{-1},
};
static struct module_pin_mux rgmii2_pin_mux[] = {
{OFFSET(gpmc_a0), MODE(2)}, /* txen */
{OFFSET(gpmc_a2), MODE(2)}, /* txd3 */
{OFFSET(gpmc_a3), MODE(2)}, /* txd2 */
{OFFSET(gpmc_a4), MODE(2)}, /* txd1 */
{OFFSET(gpmc_a5), MODE(2)}, /* txd0 */
{OFFSET(gpmc_a6), MODE(2)}, /* txclk */
{OFFSET(gpmc_a1), MODE(2) | RXACTIVE | PULLDOWN_EN}, /* rxvd */
{OFFSET(gpmc_a7), MODE(2) | RXACTIVE | PULLDOWN_EN}, /* rxclk */
{OFFSET(gpmc_a8), MODE(2) | RXACTIVE | PULLDOWN_EN}, /* rxd3 */
{OFFSET(gpmc_a9), MODE(2) | RXACTIVE | PULLDOWN_EN}, /* rxd2 */
{OFFSET(gpmc_a10), MODE(2) | RXACTIVE | PULLDOWN_EN}, /* rxd1 */
{OFFSET(gpmc_a11), MODE(2) | RXACTIVE | PULLUP_EN}, /* rxd0 */
{-1},
};
static struct module_pin_mux mdio_pin_mux[] = {
{OFFSET(mdio_data), (MODE(0) | PULLUP_EN | RXACTIVE)},
{OFFSET(mdio_clk), (MODE(0) | PULLUP_EN)},
{-1},
};
static struct module_pin_mux uart0_pin_mux[] = {
{OFFSET(uart0_rxd), (MODE(0) | PULLUP_EN | RXACTIVE | SLEWCTRL)},
{OFFSET(uart0_txd), (MODE(0) | PULLUDDIS | PULLUP_EN | SLEWCTRL)},
{-1},
};
static struct module_pin_mux mmc0_pin_mux[] = {
{OFFSET(mmc0_clk), (MODE(0) | PULLUDDIS | RXACTIVE)},
{OFFSET(mmc0_cmd), (MODE(0) | PULLUP_EN | RXACTIVE)},
{OFFSET(mmc0_dat0), (MODE(0) | PULLUP_EN | RXACTIVE)},
{OFFSET(mmc0_dat1), (MODE(0) | PULLUP_EN | RXACTIVE)},
{OFFSET(mmc0_dat2), (MODE(0) | PULLUP_EN | RXACTIVE)},
{OFFSET(mmc0_dat3), (MODE(0) | PULLUP_EN | RXACTIVE)},
{-1},
};
static struct module_pin_mux i2c_pin_mux[] = {
{OFFSET(i2c0_sda), (MODE(0) | PULLUP_EN | RXACTIVE | SLEWCTRL)},
{OFFSET(i2c0_scl), (MODE(0) | PULLUP_EN | RXACTIVE | SLEWCTRL)},
{OFFSET(spi2_sclk), (MODE(1) | PULLUP_EN | RXACTIVE | SLEWCTRL)},
{OFFSET(spi2_cs0), (MODE(1) | PULLUP_EN | RXACTIVE | SLEWCTRL)},
{-1},
};
static struct module_pin_mux nand_pin_mux[] = {
{OFFSET(gpmc_ad0), (MODE(0) | PULLUDDIS | RXACTIVE)},
{OFFSET(gpmc_ad1), (MODE(0) | PULLUDDIS | RXACTIVE)},
{OFFSET(gpmc_ad2), (MODE(0) | PULLUDDIS | RXACTIVE)},
{OFFSET(gpmc_ad3), (MODE(0) | PULLUDDIS | RXACTIVE)},
{OFFSET(gpmc_ad4), (MODE(0) | PULLUDDIS | RXACTIVE)},
{OFFSET(gpmc_ad5), (MODE(0) | PULLUDDIS | RXACTIVE)},
{OFFSET(gpmc_ad6), (MODE(0) | PULLUDDIS | RXACTIVE)},
{OFFSET(gpmc_ad7), (MODE(0) | PULLUDDIS | RXACTIVE)},
{OFFSET(gpmc_wait0), (MODE(0) | PULLUP_EN | RXACTIVE)},
{OFFSET(gpmc_wpn), (MODE(0) | PULLUP_EN)},
{OFFSET(gpmc_csn0), (MODE(0) | PULLUP_EN)},
{OFFSET(gpmc_wen), (MODE(0) | PULLDOWN_EN)},
{OFFSET(gpmc_oen_ren), (MODE(0) | PULLDOWN_EN)},
{OFFSET(gpmc_advn_ale), (MODE(0) | PULLDOWN_EN)},
{OFFSET(gpmc_be0n_cle), (MODE(0) | PULLDOWN_EN)},
{-1},
};
static struct module_pin_mux emmc_pin_mux[] = {
{OFFSET(gpmc_csn1), (MODE(2) | PULLUDDIS | RXACTIVE)}, /* EMMC_CLK */
{OFFSET(gpmc_csn2), (MODE(2) | PULLUP_EN | RXACTIVE)}, /* EMMC_CMD */
{OFFSET(gpmc_ad8), (MODE(2) | PULLUP_EN | RXACTIVE)}, /* EMMC_DAT0 */
{OFFSET(gpmc_ad9), (MODE(2) | PULLUP_EN | RXACTIVE)}, /* EMMC_DAT1 */
{OFFSET(gpmc_ad10), (MODE(2) | PULLUP_EN | RXACTIVE)}, /* EMMC_DAT2 */
{OFFSET(gpmc_ad11), (MODE(2) | PULLUP_EN | RXACTIVE)}, /* EMMC_DAT3 */
{OFFSET(gpmc_ad12), (MODE(2) | PULLUP_EN | RXACTIVE)}, /* EMMC_DAT4 */
{OFFSET(gpmc_ad13), (MODE(2) | PULLUP_EN | RXACTIVE)}, /* EMMC_DAT5 */
{OFFSET(gpmc_ad14), (MODE(2) | PULLUP_EN | RXACTIVE)}, /* EMMC_DAT6 */
{OFFSET(gpmc_ad15), (MODE(2) | PULLUP_EN | RXACTIVE)}, /* EMMC_DAT7 */
{-1},
};
static struct module_pin_mux spi_flash_pin_mux[] = {
{OFFSET(spi0_d0), (MODE(0) | RXACTIVE | PULLUDEN)},
{OFFSET(spi0_d1), (MODE(0) | RXACTIVE | PULLUDEN)},
{OFFSET(spi0_cs0), (MODE(0) | RXACTIVE | PULLUDEN)},
{OFFSET(spi0_sclk), (MODE(0) | RXACTIVE | PULLUDEN)},
{-1},
};
void set_uart_mux_conf(void)
{
configure_module_pin_mux(uart0_pin_mux);
}
void set_mdio_pin_mux(void)
{
configure_module_pin_mux(mdio_pin_mux);
}
void set_rgmii_pin_mux(void)
{
configure_module_pin_mux(rgmii1_pin_mux);
configure_module_pin_mux(rgmii2_pin_mux);
}
void set_mux_conf_regs(void)
{
configure_module_pin_mux(mmc0_pin_mux);
configure_module_pin_mux(emmc_pin_mux);
configure_module_pin_mux(i2c_pin_mux);
configure_module_pin_mux(spi_flash_pin_mux);
configure_module_pin_mux(nand_pin_mux);
}
void set_i2c_pin_mux(void)
{
configure_module_pin_mux(i2c_pin_mux);
}

View File

@@ -0,0 +1,137 @@
/*
* Copyright (C) 2016 Compulab, Ltd.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <spl.h>
#include <i2c.h>
#include <asm/arch/clock.h>
#include <asm/arch/ddr_defs.h>
#include <asm/gpio.h>
#include <power/pmic.h>
#include <power/tps65218.h>
#include "board.h"
DECLARE_GLOBAL_DATA_PTR;
const struct dpll_params dpll_mpu = { 800, 24, 1, -1, -1, -1, -1 };
const struct dpll_params dpll_core = { 1000, 24, -1, -1, 10, 8, 4 };
const struct dpll_params dpll_per = { 960, 24, 5, -1, -1, -1, -1 };
const struct dpll_params dpll_ddr = { 400, 23, 1, -1, 1, -1, -1 };
const struct ctrl_ioregs ioregs_ddr3 = {
.cm0ioctl = DDR3_ADDRCTRL_IOCTRL_VALUE,
.cm1ioctl = DDR3_ADDRCTRL_WD0_IOCTRL_VALUE,
.cm2ioctl = DDR3_ADDRCTRL_WD1_IOCTRL_VALUE,
.dt0ioctl = DDR3_DATA0_IOCTRL_VALUE,
.dt1ioctl = DDR3_DATA0_IOCTRL_VALUE,
.dt2ioctrl = DDR3_DATA0_IOCTRL_VALUE,
.dt3ioctrl = DDR3_DATA0_IOCTRL_VALUE,
.emif_sdram_config_ext = 0x0143,
};
/* EMIF DDR3 Configurations are different for production AM43X GP EVMs */
struct emif_regs ddr3_emif_regs = {
.sdram_config = 0x638413B2,
.ref_ctrl = 0x00000C30,
.sdram_tim1 = 0xEAAAD4DB,
.sdram_tim2 = 0x266B7FDA,
.sdram_tim3 = 0x107F8678,
.read_idle_ctrl = 0x00050000,
.zq_config = 0x50074BE4,
.temp_alert_config = 0x0,
.emif_ddr_phy_ctlr_1 = 0x0E004008,
.emif_ddr_ext_phy_ctrl_1 = 0x08020080,
.emif_ddr_ext_phy_ctrl_2 = 0x00000066,
.emif_ddr_ext_phy_ctrl_3 = 0x00000091,
.emif_ddr_ext_phy_ctrl_4 = 0x000000B9,
.emif_ddr_ext_phy_ctrl_5 = 0x000000E6,
.emif_rd_wr_exec_thresh = 0x80000405,
.emif_prio_class_serv_map = 0x80000001,
.emif_connect_id_serv_1_map = 0x80000094,
.emif_connect_id_serv_2_map = 0x00000000,
.emif_cos_config = 0x000FFFFF
};
const u32 ext_phy_ctrl_const_base_ddr3[] = {
0x00000000,
0x00000044,
0x00000044,
0x00000046,
0x00000046,
0x00000000,
0x00000059,
0x00000077,
0x00000093,
0x000000A8,
0x00000000,
0x00000019,
0x00000037,
0x00000053,
0x00000068,
0x00000000,
0x0,
0x0,
0x40000000,
0x08102040
};
void emif_get_ext_phy_ctrl_const_regs(const u32 **regs, u32 *size)
{
*regs = ext_phy_ctrl_const_base_ddr3;
*size = ARRAY_SIZE(ext_phy_ctrl_const_base_ddr3);
}
const struct dpll_params *get_dpll_ddr_params(void)
{
return &dpll_ddr;
}
const struct dpll_params *get_dpll_mpu_params(void)
{
return &dpll_mpu;
}
const struct dpll_params *get_dpll_core_params(void)
{
return &dpll_core;
}
const struct dpll_params *get_dpll_per_params(void)
{
return &dpll_per;
}
void scale_vcores(void)
{
set_i2c_pin_mux();
i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
if (i2c_probe(TPS65218_CHIP_PM))
return;
tps65218_voltage_update(TPS65218_DCDC1, TPS65218_DCDC_VOLT_SEL_1100MV);
tps65218_voltage_update(TPS65218_DCDC2, TPS65218_DCDC_VOLT_SEL_1100MV);
}
void sdram_init(void)
{
unsigned long ram_size;
config_ddr(0, &ioregs_ddr3, NULL, NULL, &ddr3_emif_regs, 0);
ram_size = get_ram_size((long int *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
if (ram_size == 0x80000000 ||
ram_size == 0x40000000 ||
ram_size == 0x20000000)
return;
ddr3_emif_regs.sdram_config = 0x638453B2;
config_ddr(0, &ioregs_ddr3, NULL, NULL, &ddr3_emif_regs, 0);
ram_size = get_ram_size((long int *)CONFIG_SYS_SDRAM_BASE, 0x80000000);
if (ram_size == 0x08000000)
return;
hang();
}

View File

@@ -0,0 +1,12 @@
if TARGET_CM_T54
config SYS_BOARD
default "cm_t54"
config SYS_VENDOR
default "compulab"
config SYS_CONFIG_NAME
default "cm_t54"
endif

View File

@@ -0,0 +1,6 @@
CM_T54 BOARD
M: Dmitry Lifshitz <lifshitz@compulab.co.il>
S: Maintained
F: board/compulab/cm_t54/
F: include/configs/cm_t54.h
F: configs/cm_t54_defconfig

View File

@@ -0,0 +1,10 @@
#
# Copyright (C) 2014 Compulab Ltd - http://compulab.co.il/
#
# Author: Dmitry Lifshitz <lifshitz@compulab.co.il>
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += cm_t54.o
obj-$(CONFIG_SPL_BUILD) += mux.o spl.o

View File

@@ -0,0 +1,259 @@
/*
* Board functions for Compulab CM-T54 board
*
* Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
*
* Author: Dmitry Lifshitz <lifshitz@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <fdt_support.h>
#include <usb.h>
#include <mmc.h>
#include <palmas.h>
#include <spl.h>
#include <asm/gpio.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/mmc_host_def.h>
#include <asm/arch/clock.h>
#include <asm/arch/ehci.h>
#include <asm/ehci-omap.h>
#include "../common/eeprom.h"
#define DIE_ID_REG_BASE (OMAP54XX_L4_CORE_BASE + 0x2000)
#define DIE_ID_REG_OFFSET 0x200
DECLARE_GLOBAL_DATA_PTR;
#if !defined(CONFIG_SPL_BUILD)
inline void set_muxconf_regs(void){};
#endif
const struct omap_sysinfo sysinfo = {
"Board: CM-T54\n"
};
/*
* Routine: board_init
* Description: hardware init.
*/
int board_init(void)
{
gd->bd->bi_boot_params = (CONFIG_SYS_SDRAM_BASE + 0x100);
return 0;
}
/*
* Routine: cm_t54_palmas_regulator_set
* Description: select voltage and turn on/off Palmas PMIC regulator.
*/
static int cm_t54_palmas_regulator_set(u8 vreg, u8 vval, u8 creg, u8 cval)
{
int err;
/* Setup voltage */
err = palmas_i2c_write_u8(TWL603X_CHIP_P1, vreg, vval);
if (err) {
printf("cm_t54: could not set regulator 0x%02x voltage : %d\n",
vreg, err);
return err;
}
/* Turn on/off regulator */
err = palmas_i2c_write_u8(TWL603X_CHIP_P1, creg, cval);
if (err) {
printf("cm_t54: could not turn on/off regulator 0x%02x : %d\n",
creg, err);
return err;
}
return 0;
}
/*
* Routine: mmc_get_env_part
* Description: setup environment storage device partition.
*/
#ifdef CONFIG_SYS_MMC_ENV_PART
uint mmc_get_env_part(struct mmc *mmc)
{
u32 bootmode = gd->arch.omap_boot_mode;
uint bootpart = CONFIG_SYS_MMC_ENV_PART;
/*
* If booted from eMMC boot partition then force eMMC
* FIRST boot partition to be env storage
*/
if (bootmode == BOOT_DEVICE_MMC2)
bootpart = 1;
return bootpart;
}
#endif
#if defined(CONFIG_GENERIC_MMC) && !defined(CONFIG_SPL_BUILD)
#define SB_T54_CD_GPIO 228
#define SB_T54_WP_GPIO 229
int board_mmc_init(bd_t *bis)
{
int ret0, ret1;
ret0 = omap_mmc_init(0, 0, 0, SB_T54_CD_GPIO, SB_T54_WP_GPIO);
if (ret0)
printf("cm_t54: failed to initialize mmc0\n");
ret1 = omap_mmc_init(1, 0, 0, -1, -1);
if (ret1)
printf("cm_t54: failed to initialize mmc1\n");
if (ret0 && ret1)
return -1;
return 0;
}
#endif
#ifdef CONFIG_USB_HOST_ETHER
int ft_board_setup(void *blob, bd_t *bd)
{
uint8_t enetaddr[6];
/* MAC addr */
if (eth_getenv_enetaddr("usbethaddr", enetaddr)) {
fdt_find_and_setprop(blob, "/smsc95xx@0", "mac-address",
enetaddr, 6, 1);
}
return 0;
}
static void generate_mac_addr(uint8_t *enetaddr)
{
int reg;
reg = DIE_ID_REG_BASE + DIE_ID_REG_OFFSET;
/*
* create a fake MAC address from the processor ID code.
* first byte is 0x02 to signify locally administered.
*/
enetaddr[0] = 0x02;
enetaddr[1] = readl(reg + 0x10) & 0xff;
enetaddr[2] = readl(reg + 0xC) & 0xff;
enetaddr[3] = readl(reg + 0x8) & 0xff;
enetaddr[4] = readl(reg) & 0xff;
enetaddr[5] = (readl(reg) >> 8) & 0xff;
}
/*
* Routine: handle_mac_address
* Description: prepare MAC address for on-board Ethernet.
*/
static int handle_mac_address(void)
{
uint8_t enetaddr[6];
int ret;
ret = eth_getenv_enetaddr("usbethaddr", enetaddr);
if (ret)
return 0;
ret = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS);
if (ret || !is_valid_ethaddr(enetaddr))
generate_mac_addr(enetaddr);
if (!is_valid_ethaddr(enetaddr))
return -1;
return eth_setenv_enetaddr("usbethaddr", enetaddr);
}
int board_eth_init(bd_t *bis)
{
return handle_mac_address();
}
#endif
#ifdef CONFIG_USB_EHCI
static struct omap_usbhs_board_data usbhs_bdata = {
.port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
.port_mode[1] = OMAP_EHCI_PORT_MODE_HSIC,
.port_mode[2] = OMAP_EHCI_PORT_MODE_HSIC,
};
static void setup_host_clocks(bool enable)
{
int usbhost_clk = OPTFCLKEN_HSIC60M_P3_CLK |
OPTFCLKEN_HSIC480M_P3_CLK |
OPTFCLKEN_HSIC60M_P2_CLK |
OPTFCLKEN_HSIC480M_P2_CLK |
OPTFCLKEN_UTMI_P3_CLK |
OPTFCLKEN_UTMI_P2_CLK;
int usbtll_clk = OPTFCLKEN_USB_CH1_CLK_ENABLE |
OPTFCLKEN_USB_CH2_CLK_ENABLE;
int usbhub_clk = CKOBUFFER_CLK_ENABLE_MASK;
if (enable) {
/* Enable port 2 and 3 clocks*/
setbits_le32((*prcm)->cm_l3init_hsusbhost_clkctrl, usbhost_clk);
/* Enable port 2 and 3 usb host ports tll clocks*/
setbits_le32((*prcm)->cm_l3init_hsusbtll_clkctrl, usbtll_clk);
/* Request FREF_XTAL_CLK clock for HSIC USB Hub */
setbits_le32((*ctrl)->control_ckobuffer, usbhub_clk);
} else {
clrbits_le32((*ctrl)->control_ckobuffer, usbhub_clk);
clrbits_le32((*prcm)->cm_l3init_hsusbtll_clkctrl, usbtll_clk);
clrbits_le32((*prcm)->cm_l3init_hsusbhost_clkctrl, usbhost_clk);
}
}
int ehci_hcd_init(int index, enum usb_init_type init,
struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
int ret;
/* VCC_3V3_ETH */
cm_t54_palmas_regulator_set(SMPS9_VOLTAGE, SMPS_VOLT_3V3, SMPS9_CTRL,
SMPS_MODE_SLP_AUTO | SMPS_MODE_ACT_AUTO);
setup_host_clocks(true);
ret = omap_ehci_hcd_init(index, &usbhs_bdata, hccr, hcor);
if (ret < 0)
printf("cm_t54: Failed to initialize ehci : %d\n", ret);
return ret;
}
int ehci_hcd_stop(void)
{
int ret = omap_ehci_hcd_stop();
setup_host_clocks(false);
cm_t54_palmas_regulator_set(SMPS9_VOLTAGE, SMPS_VOLT_OFF,
SMPS9_CTRL, SMPS_MODE_SLP_AUTO);
return ret;
}
void usb_hub_reset_devices(int port)
{
/* The LAN9730 needs to be reset after the port power has been set. */
if (port == 3) {
gpio_direction_output(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO, 0);
udelay(10);
gpio_direction_output(CONFIG_OMAP_EHCI_PHY3_RESET_GPIO, 1);
}
}
#endif

View File

@@ -0,0 +1,94 @@
/*
* Pinmux configuration for Compulab CM-T54 board
*
* Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
*
* Author: Dmitry Lifshitz <lifshitz@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _CM_T54_MUX_DATA_H
#define _CM_T54_MUX_DATA_H
#include <asm/arch/mux_omap5.h>
#include <asm/arch/sys_proto.h>
const struct pad_conf_entry core_padconf_array_essential[] = {
/* MMC1 - SD CARD */
{SDCARD_CLK, (PTU | IEN | M0)}, /* SDCARD_CLK */
{SDCARD_CMD, (PTU | IEN | M0)}, /* SDCARD_CMD */
{SDCARD_DATA0, (PTU | IEN | M0)}, /* SDCARD_DATA0 */
{SDCARD_DATA1, (PTU | IEN | M0)}, /* SDCARD_DATA1 */
{SDCARD_DATA2, (PTU | IEN | M0)}, /* SDCARD_DATA2 */
{SDCARD_DATA3, (PTU | IEN | M0)}, /* SDCARD_DATA3 */
/* SD CARD CD and WP GPIOs*/
{TIMER5_PWM_EVT, (PTU | IEN | M6)}, /* GPIO8_228 */
{TIMER6_PWM_EVT, (PTU | IEN | M6)}, /* GPIO8_229 */
/* MMC2 - eMMC */
{EMMC_CLK, (PTU | IEN | M0)}, /* EMMC_CLK */
{EMMC_CMD, (PTU | IEN | M0)}, /* EMMC_CMD */
{EMMC_DATA0, (PTU | IEN | M0)}, /* EMMC_DATA0 */
{EMMC_DATA1, (PTU | IEN | M0)}, /* EMMC_DATA1 */
{EMMC_DATA2, (PTU | IEN | M0)}, /* EMMC_DATA2 */
{EMMC_DATA3, (PTU | IEN | M0)}, /* EMMC_DATA3 */
{EMMC_DATA4, (PTU | IEN | M0)}, /* EMMC_DATA4 */
{EMMC_DATA5, (PTU | IEN | M0)}, /* EMMC_DATA5 */
{EMMC_DATA6, (PTU | IEN | M0)}, /* EMMC_DATA6 */
{EMMC_DATA7, (PTU | IEN | M0)}, /* EMMC_DATA7 */
/* UART4 */
{I2C5_SCL, (PTU | IEN | M2)}, /* UART4_RX */
{I2C5_SDA, (M2)}, /* UART4_TX */
/* Led */
{HSI2_CAFLAG, (PTU | M6)}, /* GPIO3_80 */
/* I2C1 */
{I2C1_PMIC_SCL, (PTU | IEN | M0)}, /* I2C1_PMIC_SCL */
{I2C1_PMIC_SDA, (PTU | IEN | M0)}, /* I2C1_PMIC_SDA */
/* USBB2, USBB3 */
{USBB2_HSIC_STROBE, (PTU | IEN | M0)}, /* USBB2_HSIC_STROBE */
{USBB2_HSIC_DATA, (PTU | IEN | M0)}, /* USBB2_HSIC_DATA */
{USBB3_HSIC_STROBE, (PTU | IEN | M0)}, /* USBB3_HSIC_STROBE */
{USBB3_HSIC_DATA, (PTU | IEN | M0)}, /* USBB3_HSIC_DATA */
/* USB Hub and USB Eth reset GPIOs */
{HSI2_CAREADY, (PTD | M6)}, /* GPIO3_76 */
{HSI2_ACDATA, (PTD | M6)}, /* GPIO3_83 */
/* I2C4 */
{I2C4_SCL, (PTU | IEN | M0)}, /* I2C4_SCL */
{I2C4_SDA, (PTU | IEN | M0)}, /* I2C4_SDA */
};
const struct pad_conf_entry wkup_padconf_array_essential[] = {
{SR_PMIC_SCL, (PTU | IEN | M0)}, /* SR_PMIC_SCL */
{SR_PMIC_SDA, (PTU | IEN | M0)}, /* SR_PMIC_SDA */
{SYS_32K, (IEN | M0)}, /* SYS_32K */
/* USB Hub clock */
{FREF_CLK1_OUT, (PTD | IEN | M0)}, /* FREF_CLK1_OUT */
};
/*
* Routine: set_muxconf_regs
* Description: setup board pinmux configuration.
*/
void set_muxconf_regs(void)
{
do_set_mux((*ctrl)->control_padconf_core_base,
core_padconf_array_essential,
sizeof(core_padconf_array_essential) /
sizeof(struct pad_conf_entry));
do_set_mux((*ctrl)->control_padconf_wkup_base,
wkup_padconf_array_essential,
sizeof(wkup_padconf_array_essential) /
sizeof(struct pad_conf_entry));
}
#endif /* _CM_T54_MUX_DATA_H */

View File

@@ -0,0 +1,66 @@
/*
* SPL specific code for Compulab CM-T54 board
*
* Copyright (C) 2014, Compulab Ltd - http://compulab.co.il/
*
* Author: Dmitry Lifshitz <lifshitz@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm/emif.h>
const struct emif_regs emif_regs_ddr3_532_mhz_cm_t54 = {
#if defined(CONFIG_DRAM_1G) || defined(CONFIG_DRAM_512M)
.sdram_config_init = 0x618522B2,
.sdram_config = 0x618522B2,
#elif defined(CONFIG_DRAM_2G)
.sdram_config_init = 0x618522BA,
.sdram_config = 0x618522BA,
#endif
.sdram_config2 = 0x0,
.ref_ctrl = 0x00001040,
.sdram_tim1 = 0xEEEF36F3,
.sdram_tim2 = 0x348F7FDA,
.sdram_tim3 = 0x027F88A8,
.read_idle_ctrl = 0x00050000,
.zq_config = 0x1007190B,
.temp_alert_config = 0x00000000,
.emif_ddr_phy_ctlr_1_init = 0x0030400B,
.emif_ddr_phy_ctlr_1 = 0x0034400B,
.emif_ddr_ext_phy_ctrl_1 = 0x04040100,
.emif_ddr_ext_phy_ctrl_2 = 0x00000000,
.emif_ddr_ext_phy_ctrl_3 = 0x00000000,
.emif_ddr_ext_phy_ctrl_4 = 0x00000000,
.emif_ddr_ext_phy_ctrl_5 = 0x4350D435,
.emif_rd_wr_lvl_rmp_win = 0x00000000,
.emif_rd_wr_lvl_rmp_ctl = 0x80000000,
.emif_rd_wr_lvl_ctl = 0x00000000,
.emif_rd_wr_exec_thresh = 0x40000305,
};
const struct dmm_lisa_map_regs lisa_map_cm_t54 = {
.dmm_lisa_map_0 = 0x0,
.dmm_lisa_map_1 = 0x0,
#ifdef CONFIG_DRAM_2G
.dmm_lisa_map_2 = 0x80740300,
#elif defined(CONFIG_DRAM_1G)
.dmm_lisa_map_2 = 0x80640300,
#elif defined(CONFIG_DRAM_512M)
.dmm_lisa_map_2 = 0x80500100,
#endif
.dmm_lisa_map_3 = 0x00000000,
.is_ma_present = 0x1,
};
void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs)
{
*regs = &emif_regs_ddr3_532_mhz_cm_t54;
}
void emif_get_dmm_regs(const struct dmm_lisa_map_regs **dmm_lisa_regs)
{
*dmm_lisa_regs = &lisa_map_cm_t54;
}

View File

@@ -0,0 +1,12 @@
#
# (C) Copyright 2011 - 2013 CompuLab, Ltd. <www.compulab.co.il>
#
# Author: Igor Grinberg <grinberg@compulab.co.il>
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += common.o
obj-$(CONFIG_SYS_I2C) += eeprom.o
obj-$(CONFIG_LCD) += omap3_display.o
obj-$(CONFIG_SMC911X) += omap3_smc911x.o

View File

@@ -0,0 +1,59 @@
/*
* (C) Copyright 2014 CompuLab, Ltd. <www.compulab.co.il>
*
* Authors: Igor Grinberg <grinberg@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/bootm.h>
#include <asm/gpio.h>
#include "common.h"
#include "eeprom.h"
void cl_print_pcb_info(void)
{
u32 board_rev = get_board_rev();
u32 rev_major = board_rev / 100;
u32 rev_minor = board_rev - (rev_major * 100);
if ((rev_minor / 10) * 10 == rev_minor)
rev_minor = rev_minor / 10;
printf("PCB: %u.%u\n", rev_major, rev_minor);
}
#ifdef CONFIG_SERIAL_TAG
void __weak get_board_serial(struct tag_serialnr *serialnr)
{
/*
* This corresponds to what happens when we can communicate with the
* eeprom but don't get a valid board serial value.
*/
serialnr->low = 0;
serialnr->high = 0;
};
#endif
#ifdef CONFIG_CMD_USB
int cl_usb_hub_init(int gpio, const char *label)
{
if (gpio_request(gpio, label)) {
printf("Error: can't obtain GPIO%d for %s", gpio, label);
return -1;
}
gpio_direction_output(gpio, 0);
udelay(10);
gpio_set_value(gpio, 1);
udelay(1000);
return 0;
}
void cl_usb_hub_deinit(int gpio)
{
gpio_free(gpio);
}
#endif

View File

@@ -0,0 +1,38 @@
/*
* (C) Copyright 2014 CompuLab, Ltd. <www.compulab.co.il>
*
* Authors: Igor Grinberg <grinberg@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _CL_COMMON_
#define _CL_COMMON_
#include <asm/errno.h>
void cl_print_pcb_info(void);
#ifdef CONFIG_CMD_USB
int cl_usb_hub_init(int gpio, const char *label);
void cl_usb_hub_deinit(int gpio);
#else /* !CONFIG_CMD_USB */
static inline int cl_usb_hub_init(int gpio, const char *label)
{
return -ENOSYS;
}
static inline void cl_usb_hub_deinit(int gpio) {}
#endif /* CONFIG_CMD_USB */
#ifdef CONFIG_SMC911X
int cl_omap3_smc911x_init(int id, int cs, u32 base_addr,
int (*reset)(int), int rst_gpio);
#else /* !CONFIG_SMC911X */
static inline int cl_omap3_smc911x_init(int id, int cs, u32 base_addr,
int (*reset)(int), int rst_gpio)
{
return -ENOSYS;
}
#endif /* CONFIG_SMC911X */
#endif /* _CL_COMMON_ */

View File

@@ -0,0 +1,527 @@
/*
* (C) Copyright 2011 CompuLab, Ltd. <www.compulab.co.il>
*
* Authors: Nikita Kiryanov <nikita@compulab.co.il>
* Igor Grinberg <grinberg@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <i2c.h>
#include <eeprom_layout.h>
#include <eeprom_field.h>
#include <linux/kernel.h>
#include "eeprom.h"
#ifndef CONFIG_SYS_I2C_EEPROM_ADDR
# define CONFIG_SYS_I2C_EEPROM_ADDR 0x50
# define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1
#endif
#ifndef CONFIG_SYS_I2C_EEPROM_BUS
#define CONFIG_SYS_I2C_EEPROM_BUS 0
#endif
#define EEPROM_LAYOUT_VER_OFFSET 44
#define BOARD_SERIAL_OFFSET 20
#define BOARD_SERIAL_OFFSET_LEGACY 8
#define BOARD_REV_OFFSET 0
#define BOARD_REV_OFFSET_LEGACY 6
#define BOARD_REV_SIZE 2
#define PRODUCT_NAME_OFFSET 128
#define PRODUCT_NAME_SIZE 16
#define MAC_ADDR_OFFSET 4
#define MAC_ADDR_OFFSET_LEGACY 0
#define LAYOUT_INVALID 0
#define LAYOUT_LEGACY 0xff
static int cl_eeprom_bus;
static int cl_eeprom_layout; /* Implicitly LAYOUT_INVALID */
static int cl_eeprom_read(uint offset, uchar *buf, int len)
{
int res;
unsigned int current_i2c_bus = i2c_get_bus_num();
res = i2c_set_bus_num(cl_eeprom_bus);
if (res < 0)
return res;
res = i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, offset,
CONFIG_SYS_I2C_EEPROM_ADDR_LEN, buf, len);
i2c_set_bus_num(current_i2c_bus);
return res;
}
static int cl_eeprom_setup(uint eeprom_bus)
{
int res;
/*
* We know the setup was already done when the layout is set to a valid
* value and we're using the same bus as before.
*/
if (cl_eeprom_layout != LAYOUT_INVALID && eeprom_bus == cl_eeprom_bus)
return 0;
cl_eeprom_bus = eeprom_bus;
res = cl_eeprom_read(EEPROM_LAYOUT_VER_OFFSET,
(uchar *)&cl_eeprom_layout, 1);
if (res) {
cl_eeprom_layout = LAYOUT_INVALID;
return res;
}
if (cl_eeprom_layout == 0 || cl_eeprom_layout >= 0x20)
cl_eeprom_layout = LAYOUT_LEGACY;
return 0;
}
void get_board_serial(struct tag_serialnr *serialnr)
{
u32 serial[2];
uint offset;
memset(serialnr, 0, sizeof(*serialnr));
if (cl_eeprom_setup(CONFIG_SYS_I2C_EEPROM_BUS))
return;
offset = (cl_eeprom_layout != LAYOUT_LEGACY) ?
BOARD_SERIAL_OFFSET : BOARD_SERIAL_OFFSET_LEGACY;
if (cl_eeprom_read(offset, (uchar *)serial, 8))
return;
if (serial[0] != 0xffffffff && serial[1] != 0xffffffff) {
serialnr->low = serial[0];
serialnr->high = serial[1];
}
}
/*
* Routine: cl_eeprom_read_mac_addr
* Description: read mac address and store it in buf.
*/
int cl_eeprom_read_mac_addr(uchar *buf, uint eeprom_bus)
{
uint offset;
int err;
err = cl_eeprom_setup(eeprom_bus);
if (err)
return err;
offset = (cl_eeprom_layout != LAYOUT_LEGACY) ?
MAC_ADDR_OFFSET : MAC_ADDR_OFFSET_LEGACY;
return cl_eeprom_read(offset, buf, 6);
}
static u32 board_rev;
/*
* Routine: cl_eeprom_get_board_rev
* Description: read system revision from eeprom
*/
u32 cl_eeprom_get_board_rev(uint eeprom_bus)
{
char str[5]; /* Legacy representation can contain at most 4 digits */
uint offset = BOARD_REV_OFFSET_LEGACY;
if (board_rev)
return board_rev;
if (cl_eeprom_setup(eeprom_bus))
return 0;
if (cl_eeprom_layout != LAYOUT_LEGACY)
offset = BOARD_REV_OFFSET;
if (cl_eeprom_read(offset, (uchar *)&board_rev, BOARD_REV_SIZE))
return 0;
/*
* Convert legacy syntactic representation to semantic
* representation. i.e. for rev 1.00: 0x100 --> 0x64
*/
if (cl_eeprom_layout == LAYOUT_LEGACY) {
sprintf(str, "%x", board_rev);
board_rev = simple_strtoul(str, NULL, 10);
}
return board_rev;
};
/*
* Routine: cl_eeprom_get_board_rev
* Description: read system revision from eeprom
*
* @buf: buffer to store the product name
* @eeprom_bus: i2c bus num of the eeprom
*
* @return: 0 on success, < 0 on failure
*/
int cl_eeprom_get_product_name(uchar *buf, uint eeprom_bus)
{
int err;
if (buf == NULL)
return -EINVAL;
err = cl_eeprom_setup(eeprom_bus);
if (err)
return err;
err = cl_eeprom_read(PRODUCT_NAME_OFFSET, buf, PRODUCT_NAME_SIZE);
if (!err) /* Protect ourselves from invalid data (unterminated str) */
buf[PRODUCT_NAME_SIZE - 1] = '\0';
return err;
}
#ifdef CONFIG_CMD_EEPROM_LAYOUT
/**
* eeprom_field_print_bin_ver() - print a "version field" which contains binary
* data
*
* Treat the field data as simple binary data, and print it formatted as a
* version number (2 digits after decimal point).
* The field size must be exactly 2 bytes.
*
* Sample output:
* Field Name 123.45
*
* @field: an initialized field to print
*/
void eeprom_field_print_bin_ver(const struct eeprom_field *field)
{
if ((field->buf[0] == 0xff) && (field->buf[1] == 0xff)) {
field->buf[0] = 0;
field->buf[1] = 0;
}
printf(PRINT_FIELD_SEGMENT, field->name);
int major = (field->buf[1] << 8 | field->buf[0]) / 100;
int minor = (field->buf[1] << 8 | field->buf[0]) - major * 100;
printf("%d.%02d\n", major, minor);
}
/**
* eeprom_field_update_bin_ver() - update a "version field" which contains
* binary data
*
* This function takes a version string in the form of x.y (x and y are both
* decimal values, y is limited to two digits), translates it to the binary
* form, then writes it to the field. The field size must be exactly 2 bytes.
*
* This function strictly enforces the data syntax, and will not update the
* field if there's any deviation from it. It also protects from overflow.
*
* @field: an initialized field
* @value: a version string
*
* Returns 0 on success, -1 on failure.
*/
int eeprom_field_update_bin_ver(struct eeprom_field *field, char *value)
{
char *endptr;
char *tok = strtok(value, ".");
if (tok == NULL)
return -1;
int num = simple_strtol(tok, &endptr, 0);
if (*endptr != '\0')
return -1;
tok = strtok(NULL, "");
if (tok == NULL)
return -1;
int remainder = simple_strtol(tok, &endptr, 0);
if (*endptr != '\0')
return -1;
num = num * 100 + remainder;
if (num >> 16)
return -1;
field->buf[0] = (unsigned char)num;
field->buf[1] = num >> 8;
return 0;
}
char *months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
/**
* eeprom_field_print_date() - print a field which contains date data
*
* Treat the field data as simple binary data, and print it formatted as a date.
* Sample output:
* Field Name 07/Feb/2014
* Field Name 56/BAD/9999
*
* @field: an initialized field to print
*/
void eeprom_field_print_date(const struct eeprom_field *field)
{
printf(PRINT_FIELD_SEGMENT, field->name);
printf("%02d/", field->buf[0]);
if (field->buf[1] >= 1 && field->buf[1] <= 12)
printf("%s", months[field->buf[1] - 1]);
else
printf("BAD");
printf("/%d\n", field->buf[3] << 8 | field->buf[2]);
}
static int validate_date(unsigned char day, unsigned char month,
unsigned int year)
{
int days_in_february;
switch (month) {
case 0:
case 2:
case 4:
case 6:
case 7:
case 9:
case 11:
if (day > 31)
return -1;
break;
case 3:
case 5:
case 8:
case 10:
if (day > 30)
return -1;
break;
case 1:
days_in_february = 28;
if (year % 4 == 0) {
if (year % 100 != 0)
days_in_february = 29;
else if (year % 400 == 0)
days_in_february = 29;
}
if (day > days_in_february)
return -1;
break;
default:
return -1;
}
return 0;
}
/**
* eeprom_field_update_date() - update a date field which contains binary data
*
* This function takes a date string in the form of x/Mon/y (x and y are both
* decimal values), translates it to the binary representation, then writes it
* to the field.
*
* This function strictly enforces the data syntax, and will not update the
* field if there's any deviation from it. It also protects from overflow in the
* year value, and checks the validity of the date.
*
* @field: an initialized field
* @value: a date string
*
* Returns 0 on success, -1 on failure.
*/
int eeprom_field_update_date(struct eeprom_field *field, char *value)
{
char *endptr;
char *tok1 = strtok(value, "/");
char *tok2 = strtok(NULL, "/");
char *tok3 = strtok(NULL, "/");
if (tok1 == NULL || tok2 == NULL || tok3 == NULL) {
printf("%s: syntax error\n", field->name);
return -1;
}
unsigned char day = (unsigned char)simple_strtol(tok1, &endptr, 0);
if (*endptr != '\0' || day == 0) {
printf("%s: invalid day\n", field->name);
return -1;
}
unsigned char month;
for (month = 1; month <= 12; month++)
if (!strcmp(tok2, months[month - 1]))
break;
unsigned int year = simple_strtol(tok3, &endptr, 0);
if (*endptr != '\0') {
printf("%s: invalid year\n", field->name);
return -1;
}
if (validate_date(day, month - 1, year)) {
printf("%s: invalid date\n", field->name);
return -1;
}
if (year >> 16) {
printf("%s: year overflow\n", field->name);
return -1;
}
field->buf[0] = day;
field->buf[1] = month;
field->buf[2] = (unsigned char)year;
field->buf[3] = (unsigned char)(year >> 8);
return 0;
}
#define LAYOUT_VERSION_LEGACY 1
#define LAYOUT_VERSION_VER1 2
#define LAYOUT_VERSION_VER2 3
#define LAYOUT_VERSION_VER3 4
extern struct eeprom_field layout_unknown[1];
#define DEFINE_PRINT_UPDATE(x) eeprom_field_print_##x, eeprom_field_update_##x
#ifdef CONFIG_CM_T3X
struct eeprom_field layout_legacy[5] = {
{ "MAC address", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
{ "Board Revision", 2, NULL, DEFINE_PRINT_UPDATE(bin) },
{ "Serial Number", 8, NULL, DEFINE_PRINT_UPDATE(bin) },
{ "Board Configuration", 64, NULL, DEFINE_PRINT_UPDATE(ascii) },
{ RESERVED_FIELDS, 176, NULL, eeprom_field_print_reserved,
eeprom_field_update_ascii },
};
#else
#define layout_legacy layout_unknown
#endif
#if defined(CONFIG_CM_T3X) || defined(CONFIG_CM_T3517)
struct eeprom_field layout_v1[12] = {
{ "Major Revision", 2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
{ "Minor Revision", 2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
{ "1st MAC Address", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
{ "2nd MAC Address", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
{ "Production Date", 4, NULL, DEFINE_PRINT_UPDATE(date) },
{ "Serial Number", 12, NULL, DEFINE_PRINT_UPDATE(bin_rev) },
{ RESERVED_FIELDS, 96, NULL, DEFINE_PRINT_UPDATE(reserved) },
{ "Product Name", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
{ "Product Options #1", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
{ "Product Options #2", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
{ "Product Options #3", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
{ RESERVED_FIELDS, 64, NULL, eeprom_field_print_reserved,
eeprom_field_update_ascii },
};
#else
#define layout_v1 layout_unknown
#endif
struct eeprom_field layout_v2[15] = {
{ "Major Revision", 2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
{ "Minor Revision", 2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
{ "1st MAC Address", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
{ "2nd MAC Address", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
{ "Production Date", 4, NULL, DEFINE_PRINT_UPDATE(date) },
{ "Serial Number", 12, NULL, DEFINE_PRINT_UPDATE(bin_rev) },
{ "3rd MAC Address (WIFI)", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
{ "4th MAC Address (Bluetooth)", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
{ "Layout Version", 1, NULL, DEFINE_PRINT_UPDATE(bin) },
{ RESERVED_FIELDS, 83, NULL, DEFINE_PRINT_UPDATE(reserved) },
{ "Product Name", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
{ "Product Options #1", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
{ "Product Options #2", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
{ "Product Options #3", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
{ RESERVED_FIELDS, 64, NULL, eeprom_field_print_reserved,
eeprom_field_update_ascii },
};
struct eeprom_field layout_v3[16] = {
{ "Major Revision", 2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
{ "Minor Revision", 2, NULL, DEFINE_PRINT_UPDATE(bin_ver) },
{ "1st MAC Address", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
{ "2nd MAC Address", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
{ "Production Date", 4, NULL, DEFINE_PRINT_UPDATE(date) },
{ "Serial Number", 12, NULL, DEFINE_PRINT_UPDATE(bin_rev) },
{ "3rd MAC Address (WIFI)", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
{ "4th MAC Address (Bluetooth)", 6, NULL, DEFINE_PRINT_UPDATE(mac) },
{ "Layout Version", 1, NULL, DEFINE_PRINT_UPDATE(bin) },
{ "CompuLab EEPROM ID", 3, NULL, DEFINE_PRINT_UPDATE(bin) },
{ RESERVED_FIELDS, 80, NULL, DEFINE_PRINT_UPDATE(reserved) },
{ "Product Name", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
{ "Product Options #1", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
{ "Product Options #2", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
{ "Product Options #3", 16, NULL, DEFINE_PRINT_UPDATE(ascii) },
{ RESERVED_FIELDS, 64, NULL, eeprom_field_print_reserved,
eeprom_field_update_ascii },
};
void eeprom_layout_assign(struct eeprom_layout *layout, int layout_version)
{
switch (layout->layout_version) {
case LAYOUT_VERSION_LEGACY:
layout->fields = layout_legacy;
layout->num_of_fields = ARRAY_SIZE(layout_legacy);
break;
case LAYOUT_VERSION_VER1:
layout->fields = layout_v1;
layout->num_of_fields = ARRAY_SIZE(layout_v1);
break;
case LAYOUT_VERSION_VER2:
layout->fields = layout_v2;
layout->num_of_fields = ARRAY_SIZE(layout_v2);
break;
case LAYOUT_VERSION_VER3:
layout->fields = layout_v3;
layout->num_of_fields = ARRAY_SIZE(layout_v3);
break;
default:
__eeprom_layout_assign(layout, layout_version);
}
}
int eeprom_parse_layout_version(char *str)
{
if (!strcmp(str, "legacy"))
return LAYOUT_VERSION_LEGACY;
else if (!strcmp(str, "v1"))
return LAYOUT_VERSION_VER1;
else if (!strcmp(str, "v2"))
return LAYOUT_VERSION_VER2;
else if (!strcmp(str, "v3"))
return LAYOUT_VERSION_VER3;
else
return LAYOUT_VERSION_UNRECOGNIZED;
}
int eeprom_layout_detect(unsigned char *data)
{
switch (data[EEPROM_LAYOUT_VER_OFFSET]) {
case 0xff:
case 0:
return LAYOUT_VERSION_VER1;
case 2:
return LAYOUT_VERSION_VER2;
case 3:
return LAYOUT_VERSION_VER3;
}
if (data[EEPROM_LAYOUT_VER_OFFSET] >= 0x20)
return LAYOUT_VERSION_LEGACY;
return LAYOUT_VERSION_UNRECOGNIZED;
}
#endif

View File

@@ -0,0 +1,33 @@
/*
* (C) Copyright 2011 CompuLab, Ltd. <www.compulab.co.il>
*
* Authors: Nikita Kiryanov <nikita@compulab.co.il>
* Igor Grinberg <grinberg@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _EEPROM_
#define _EEPROM_
#include <errno.h>
#ifdef CONFIG_SYS_I2C
int cl_eeprom_read_mac_addr(uchar *buf, uint eeprom_bus);
u32 cl_eeprom_get_board_rev(uint eeprom_bus);
int cl_eeprom_get_product_name(uchar *buf, uint eeprom_bus);
#else
static inline int cl_eeprom_read_mac_addr(uchar *buf, uint eeprom_bus)
{
return 1;
}
static inline u32 cl_eeprom_get_board_rev(uint eeprom_bus)
{
return 0;
}
static inline int cl_eeprom_get_product_name(uchar *buf, uint eeprom_bus)
{
return -ENOSYS;
}
#endif
#endif

View File

@@ -0,0 +1,454 @@
/*
* (C) Copyright 2012 - 2013 CompuLab, Ltd. <www.compulab.co.il>
*
* Authors: Nikita Kiryanov <nikita@compulab.co.il>
*
* Parsing code based on linux/drivers/video/pxafb.c
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <stdio_dev.h>
#include <asm/arch/dss.h>
#include <lcd.h>
#include <scf0403_lcd.h>
#include <asm/arch-omap3/dss.h>
DECLARE_GLOBAL_DATA_PTR;
enum display_type {
NONE,
DVI,
DVI_CUSTOM,
DATA_IMAGE, /* #define CONFIG_SCF0403_LCD to use */
};
#define CMAP_ADDR 0x80100000
/*
* The frame buffer is allocated before we have the chance to parse user input.
* To make sure enough memory is allocated for all resolutions, we define
* vl_{col | row} to the maximal resolution supported by OMAP3.
*/
vidinfo_t panel_info = {
.vl_col = 1400,
.vl_row = 1050,
.vl_bpix = LCD_BPP,
.cmap = (ushort *)CMAP_ADDR,
};
static struct panel_config panel_cfg;
static enum display_type lcd_def;
/*
* A note on DVI presets;
* U-Boot can convert 8 bit BMP data to 16 bit BMP data, and OMAP DSS can
* convert 16 bit data into 24 bit data. Thus, GFXFORMAT_RGB16 allows us to
* support two BMP types with one setting.
*/
static const struct panel_config preset_dvi_640X480 = {
.lcd_size = PANEL_LCD_SIZE(640, 480),
.timing_h = DSS_HBP(48) | DSS_HFP(16) | DSS_HSW(96),
.timing_v = DSS_VBP(33) | DSS_VFP(10) | DSS_VSW(2),
.pol_freq = DSS_IHS | DSS_IVS | DSS_IPC,
.divisor = 12 | (1 << 16),
.data_lines = LCD_INTERFACE_24_BIT,
.panel_type = ACTIVE_DISPLAY,
.load_mode = 2,
.gfx_format = GFXFORMAT_RGB16,
};
static const struct panel_config preset_dvi_800X600 = {
.lcd_size = PANEL_LCD_SIZE(800, 600),
.timing_h = DSS_HBP(88) | DSS_HFP(40) | DSS_HSW(128),
.timing_v = DSS_VBP(23) | DSS_VFP(1) | DSS_VSW(4),
.pol_freq = DSS_IHS | DSS_IVS | DSS_IPC,
.divisor = 8 | (1 << 16),
.data_lines = LCD_INTERFACE_24_BIT,
.panel_type = ACTIVE_DISPLAY,
.load_mode = 2,
.gfx_format = GFXFORMAT_RGB16,
};
static const struct panel_config preset_dvi_1024X768 = {
.lcd_size = PANEL_LCD_SIZE(1024, 768),
.timing_h = DSS_HBP(160) | DSS_HFP(24) | DSS_HSW(136),
.timing_v = DSS_VBP(29) | DSS_VFP(3) | DSS_VSW(6),
.pol_freq = DSS_IHS | DSS_IVS | DSS_IPC,
.divisor = 5 | (1 << 16),
.data_lines = LCD_INTERFACE_24_BIT,
.panel_type = ACTIVE_DISPLAY,
.load_mode = 2,
.gfx_format = GFXFORMAT_RGB16,
};
static const struct panel_config preset_dvi_1152X864 = {
.lcd_size = PANEL_LCD_SIZE(1152, 864),
.timing_h = DSS_HBP(256) | DSS_HFP(64) | DSS_HSW(128),
.timing_v = DSS_VBP(32) | DSS_VFP(1) | DSS_VSW(3),
.pol_freq = DSS_IHS | DSS_IVS | DSS_IPC,
.divisor = 4 | (1 << 16),
.data_lines = LCD_INTERFACE_24_BIT,
.panel_type = ACTIVE_DISPLAY,
.load_mode = 2,
.gfx_format = GFXFORMAT_RGB16,
};
static const struct panel_config preset_dvi_1280X960 = {
.lcd_size = PANEL_LCD_SIZE(1280, 960),
.timing_h = DSS_HBP(312) | DSS_HFP(96) | DSS_HSW(112),
.timing_v = DSS_VBP(36) | DSS_VFP(1) | DSS_VSW(3),
.pol_freq = DSS_IHS | DSS_IVS | DSS_IPC,
.divisor = 3 | (1 << 16),
.data_lines = LCD_INTERFACE_24_BIT,
.panel_type = ACTIVE_DISPLAY,
.load_mode = 2,
.gfx_format = GFXFORMAT_RGB16,
};
static const struct panel_config preset_dvi_1280X1024 = {
.lcd_size = PANEL_LCD_SIZE(1280, 1024),
.timing_h = DSS_HBP(248) | DSS_HFP(48) | DSS_HSW(112),
.timing_v = DSS_VBP(38) | DSS_VFP(1) | DSS_VSW(3),
.pol_freq = DSS_IHS | DSS_IVS | DSS_IPC,
.divisor = 3 | (1 << 16),
.data_lines = LCD_INTERFACE_24_BIT,
.panel_type = ACTIVE_DISPLAY,
.load_mode = 2,
.gfx_format = GFXFORMAT_RGB16,
};
static const struct panel_config preset_dataimage_480X800 = {
.lcd_size = PANEL_LCD_SIZE(480, 800),
.timing_h = DSS_HBP(2) | DSS_HFP(2) | DSS_HSW(2),
.timing_v = DSS_VBP(17) | DSS_VFP(20) | DSS_VSW(3),
.pol_freq = DSS_IVS | DSS_IHS | DSS_IPC | DSS_ONOFF,
.divisor = 10 | (1 << 10),
.data_lines = LCD_INTERFACE_18_BIT,
.panel_type = ACTIVE_DISPLAY,
.load_mode = 2,
.gfx_format = GFXFORMAT_RGB16,
};
/*
* set_resolution_params()
*
* Due to usage of multiple display related APIs resolution data is located in
* more than one place. This function updates them all.
*/
static void set_resolution_params(int x, int y)
{
panel_cfg.lcd_size = PANEL_LCD_SIZE(x, y);
panel_info.vl_col = x;
panel_info.vl_row = y;
lcd_line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8;
}
static void set_preset(const struct panel_config preset, int x_res, int y_res)
{
panel_cfg = preset;
set_resolution_params(x_res, y_res);
}
static enum display_type set_dvi_preset(const struct panel_config preset,
int x_res, int y_res)
{
set_preset(preset, x_res, y_res);
return DVI;
}
static enum display_type set_dataimage_preset(const struct panel_config preset,
int x_res, int y_res)
{
set_preset(preset, x_res, y_res);
return DATA_IMAGE;
}
/*
* parse_mode() - parse the mode parameter of custom lcd settings
*
* @mode: <res_x>x<res_y>
*
* Returns -1 on error, 0 on success.
*/
static int parse_mode(const char *mode)
{
unsigned int modelen = strlen(mode);
int res_specified = 0;
unsigned int xres = 0, yres = 0;
int yres_specified = 0;
int i;
for (i = modelen - 1; i >= 0; i--) {
switch (mode[i]) {
case 'x':
if (!yres_specified) {
yres = simple_strtoul(&mode[i + 1], NULL, 0);
yres_specified = 1;
} else {
goto done_parsing;
}
break;
case '0' ... '9':
break;
default:
goto done_parsing;
}
}
if (i < 0 && yres_specified) {
xres = simple_strtoul(mode, NULL, 0);
res_specified = 1;
}
done_parsing:
if (res_specified) {
set_resolution_params(xres, yres);
} else {
printf("LCD: invalid mode: %s\n", mode);
return -1;
}
return 0;
}
#define PIXEL_CLK_NUMERATOR (26 * 432 / 39)
/*
* parse_pixclock() - Parse the pixclock parameter of custom lcd settings
*
* @pixclock: the desired pixel clock
*
* Returns -1 on error, 0 on success.
*
* Handling the pixel_clock:
*
* Pixel clock is defined in the OMAP35x TRM as follows:
* pixel_clock =
* (SYS_CLK * 2 * PRCM.CM_CLKSEL2_PLL[18:8]) /
* (DSS.DISPC_DIVISOR[23:16] * DSS.DISPC_DIVISOR[6:0] *
* PRCM.CM_CLKSEL_DSS[4:0] * (PRCM.CM_CLKSEL2_PLL[6:0] + 1))
*
* In practice, this means that in order to set the
* divisor for the desired pixel clock one needs to
* solve the following equation:
*
* 26 * 432 / (39 * <pixel_clock>) = DSS.DISPC_DIVISOR[6:0]
*
* NOTE: the explicit equation above is reduced. Do not
* try to infer anything from these numbers.
*/
static int parse_pixclock(char *pixclock)
{
int divisor, pixclock_val;
char *pixclk_start = pixclock;
pixclock_val = simple_strtoul(pixclock, &pixclock, 10);
divisor = DIV_ROUND_UP(PIXEL_CLK_NUMERATOR, pixclock_val);
/* 0 and 1 are illegal values for PCD */
if (divisor <= 1)
divisor = 2;
panel_cfg.divisor = divisor | (1 << 16);
if (pixclock[0] != '\0') {
printf("LCD: invalid value for pixclock:%s\n", pixclk_start);
return -1;
}
return 0;
}
/*
* parse_setting() - parse a single setting of custom lcd parameters
*
* @setting: The custom lcd setting <name>:<value>
*
* Returns -1 on failure, 0 on success.
*/
static int parse_setting(char *setting)
{
int num_val;
char *setting_start = setting;
if (!strncmp(setting, "mode:", 5)) {
return parse_mode(setting + 5);
} else if (!strncmp(setting, "pixclock:", 9)) {
return parse_pixclock(setting + 9);
} else if (!strncmp(setting, "left:", 5)) {
num_val = simple_strtoul(setting + 5, &setting, 0);
panel_cfg.timing_h |= DSS_HBP(num_val);
} else if (!strncmp(setting, "right:", 6)) {
num_val = simple_strtoul(setting + 6, &setting, 0);
panel_cfg.timing_h |= DSS_HFP(num_val);
} else if (!strncmp(setting, "upper:", 6)) {
num_val = simple_strtoul(setting + 6, &setting, 0);
panel_cfg.timing_v |= DSS_VBP(num_val);
} else if (!strncmp(setting, "lower:", 6)) {
num_val = simple_strtoul(setting + 6, &setting, 0);
panel_cfg.timing_v |= DSS_VFP(num_val);
} else if (!strncmp(setting, "hsynclen:", 9)) {
num_val = simple_strtoul(setting + 9, &setting, 0);
panel_cfg.timing_h |= DSS_HSW(num_val);
} else if (!strncmp(setting, "vsynclen:", 9)) {
num_val = simple_strtoul(setting + 9, &setting, 0);
panel_cfg.timing_v |= DSS_VSW(num_val);
} else if (!strncmp(setting, "hsync:", 6)) {
if (simple_strtoul(setting + 6, &setting, 0) == 0)
panel_cfg.pol_freq |= DSS_IHS;
else
panel_cfg.pol_freq &= ~DSS_IHS;
} else if (!strncmp(setting, "vsync:", 6)) {
if (simple_strtoul(setting + 6, &setting, 0) == 0)
panel_cfg.pol_freq |= DSS_IVS;
else
panel_cfg.pol_freq &= ~DSS_IVS;
} else if (!strncmp(setting, "outputen:", 9)) {
if (simple_strtoul(setting + 9, &setting, 0) == 0)
panel_cfg.pol_freq |= DSS_IEO;
else
panel_cfg.pol_freq &= ~DSS_IEO;
} else if (!strncmp(setting, "pixclockpol:", 12)) {
if (simple_strtoul(setting + 12, &setting, 0) == 0)
panel_cfg.pol_freq |= DSS_IPC;
else
panel_cfg.pol_freq &= ~DSS_IPC;
} else if (!strncmp(setting, "active", 6)) {
panel_cfg.panel_type = ACTIVE_DISPLAY;
return 0; /* Avoid sanity check below */
} else if (!strncmp(setting, "passive", 7)) {
panel_cfg.panel_type = PASSIVE_DISPLAY;
return 0; /* Avoid sanity check below */
} else if (!strncmp(setting, "display:", 8)) {
if (!strncmp(setting + 8, "dvi", 3)) {
lcd_def = DVI_CUSTOM;
return 0; /* Avoid sanity check below */
}
} else {
printf("LCD: unknown option %s\n", setting_start);
return -1;
}
if (setting[0] != '\0') {
printf("LCD: invalid value for %s\n", setting_start);
return -1;
}
return 0;
}
/*
* env_parse_customlcd() - parse custom lcd params from an environment variable.
*
* @custom_lcd_params: The environment variable containing the lcd params.
*
* Returns -1 on failure, 0 on success.
*/
static int parse_customlcd(char *custom_lcd_params)
{
char params_cpy[160];
char *setting;
strncpy(params_cpy, custom_lcd_params, 160);
setting = strtok(params_cpy, ",");
while (setting) {
if (parse_setting(setting) < 0)
return -1;
setting = strtok(NULL, ",");
}
/* Currently we don't support changing this via custom lcd params */
panel_cfg.data_lines = LCD_INTERFACE_24_BIT;
panel_cfg.gfx_format = GFXFORMAT_RGB16; /* See dvi predefines note */
return 0;
}
/*
* env_parse_displaytype() - parse display type.
*
* Parses the environment variable "displaytype", which contains the
* name of the display type or preset, in which case it applies its
* configurations.
*
* Returns the type of display that was specified.
*/
static enum display_type env_parse_displaytype(char *displaytype)
{
if (!strncmp(displaytype, "dvi640x480", 10))
return set_dvi_preset(preset_dvi_640X480, 640, 480);
else if (!strncmp(displaytype, "dvi800x600", 10))
return set_dvi_preset(preset_dvi_800X600, 800, 600);
else if (!strncmp(displaytype, "dvi1024x768", 11))
return set_dvi_preset(preset_dvi_1024X768, 1024, 768);
else if (!strncmp(displaytype, "dvi1152x864", 11))
return set_dvi_preset(preset_dvi_1152X864, 1152, 864);
else if (!strncmp(displaytype, "dvi1280x960", 11))
return set_dvi_preset(preset_dvi_1280X960, 1280, 960);
else if (!strncmp(displaytype, "dvi1280x1024", 12))
return set_dvi_preset(preset_dvi_1280X1024, 1280, 1024);
else if (!strncmp(displaytype, "dataimage480x800", 16))
return set_dataimage_preset(preset_dataimage_480X800, 480, 800);
return NONE;
}
void lcd_ctrl_init(void *lcdbase)
{
struct prcm *prcm = (struct prcm *)PRCM_BASE;
char *custom_lcd;
char *displaytype = getenv("displaytype");
if (displaytype == NULL)
return;
lcd_def = env_parse_displaytype(displaytype);
/* If we did not recognize the preset, check if it's an env variable */
if (lcd_def == NONE) {
custom_lcd = getenv(displaytype);
if (custom_lcd == NULL || parse_customlcd(custom_lcd) < 0)
return;
}
panel_cfg.frame_buffer = lcdbase;
omap3_dss_panel_config(&panel_cfg);
/*
* Pixel clock is defined with many divisions and only few
* multiplications of the system clock. Since DSS FCLK divisor is set
* to 16 by default, we need to set it to a smaller value, like 3
* (chosen via trial and error).
*/
clrsetbits_le32(&prcm->clksel_dss, 0xF, 3);
}
#ifdef CONFIG_SCF0403_LCD
static void scf0403_enable(void)
{
gpio_direction_output(58, 1);
scf0403_init(157);
}
#else
static inline void scf0403_enable(void) {}
#endif
void lcd_enable(void)
{
switch (lcd_def) {
case NONE:
return;
case DVI:
case DVI_CUSTOM:
gpio_direction_output(54, 0); /* Turn on DVI */
break;
case DATA_IMAGE:
scf0403_enable();
break;
}
omap3_dss_enable();
}
void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) {}

View File

@@ -0,0 +1,93 @@
/*
* (C) Copyright 2014 CompuLab, Ltd. <www.compulab.co.il>
*
* Authors: Igor Grinberg <grinberg@compulab.co.il>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <netdev.h>
#include <asm/io.h>
#include <asm/errno.h>
#include <asm/arch/cpu.h>
#include <asm/arch/mem.h>
#include <asm/arch/sys_proto.h>
#include <asm/gpio.h>
#include "common.h"
static u32 cl_omap3_smc911x_gpmc_net_config[GPMC_MAX_REG] = {
NET_GPMC_CONFIG1,
NET_GPMC_CONFIG2,
NET_GPMC_CONFIG3,
NET_GPMC_CONFIG4,
NET_GPMC_CONFIG5,
NET_GPMC_CONFIG6,
0
};
static void cl_omap3_smc911x_setup_net_chip_gmpc(int cs, u32 base_addr)
{
struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE;
enable_gpmc_cs_config(cl_omap3_smc911x_gpmc_net_config,
&gpmc_cfg->cs[cs], base_addr, GPMC_SIZE_16M);
/* Enable off mode for NWE in PADCONF_GPMC_NWE register */
writew(readw(&ctrl_base->gpmc_nwe) | 0x0E00, &ctrl_base->gpmc_nwe);
/* Enable off mode for NOE in PADCONF_GPMC_NADV_ALE register */
writew(readw(&ctrl_base->gpmc_noe) | 0x0E00, &ctrl_base->gpmc_noe);
/* Enable off mode for ALE in PADCONF_GPMC_NADV_ALE register */
writew(readw(&ctrl_base->gpmc_nadv_ale) | 0x0E00,
&ctrl_base->gpmc_nadv_ale);
}
#ifdef CONFIG_OMAP_GPIO
static int cl_omap3_smc911x_reset_net_chip(int gpio)
{
int err;
if (!gpio_is_valid(gpio))
return -EINVAL;
err = gpio_request(gpio, "eth rst");
if (err)
return err;
/* Set gpio as output and send a pulse */
gpio_direction_output(gpio, 1);
udelay(1);
gpio_set_value(gpio, 0);
mdelay(40);
gpio_set_value(gpio, 1);
mdelay(1);
return 0;
}
#else /* !CONFIG_OMAP_GPIO */
static inline int cl_omap3_smc911x_reset_net_chip(int gpio) { return 0; }
#endif /* CONFIG_OMAP_GPIO */
int cl_omap3_smc911x_init(int id, int cs, u32 base_addr,
int (*reset)(int), int rst_gpio)
{
int ret;
cl_omap3_smc911x_setup_net_chip_gmpc(cs, base_addr);
if (reset)
reset(rst_gpio);
else
cl_omap3_smc911x_reset_net_chip(rst_gpio);
ret = smc911x_initialize(id, base_addr);
if (ret > 0)
return ret;
printf("Failed initializing SMC911x! ");
return 0;
}

View File

@@ -0,0 +1,12 @@
if TARGET_TRIMSLICE
config SYS_BOARD
default "trimslice"
config SYS_VENDOR
default "compulab"
config SYS_CONFIG_NAME
default "trimslice"
endif

View File

@@ -0,0 +1,7 @@
TRIMSLICE BOARD
M: Tom Warren <twarren@nvidia.com>
M: Stephen Warren <swarren@nvidia.com>
S: Maintained
F: board/compulab/trimslice/
F: include/configs/trimslice.h
F: configs/trimslice_defconfig

View File

@@ -0,0 +1,8 @@
#
# (C) Copyright 2010-2012
# NVIDIA Corporation <www.nvidia.com>
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := trimslice.o

View File

@@ -0,0 +1,42 @@
/*
* (C) Copyright 2010-2012
* NVIDIA Corporation <www.nvidia.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch/tegra.h>
#include <asm/arch/clock.h>
#include <asm/arch/funcmux.h>
#include <asm/arch/pinmux.h>
#include <asm/gpio.h>
#include <i2c.h>
void pin_mux_usb(void)
{
/*
* USB1 internal/external mux GPIO, which masquerades as a VBUS GPIO
* in the current device tree.
*/
pinmux_tristate_disable(PMUX_PINGRP_UAC);
}
void pin_mux_spi(void)
{
funcmux_select(PERIPH_ID_SPI1, FUNCMUX_SPI1_GMC_GMD);
}
/*
* Routine: pin_mux_mmc
* Description: setup the pin muxes/tristate values for the SDMMC(s)
*/
void pin_mux_mmc(void)
{
funcmux_select(PERIPH_ID_SDMMC1, FUNCMUX_SDMMC1_SDIO1_4BIT);
funcmux_select(PERIPH_ID_SDMMC4, FUNCMUX_SDMMC4_ATB_GMA_4_BIT);
/* For CD GPIO PP1 */
pinmux_tristate_disable(PMUX_PINGRP_DAP3);
}