Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'

This commit is contained in:
Albert ARIBAUD 2014-06-30 23:00:34 +02:00
commit d6694aff56
50 changed files with 2474 additions and 504 deletions

View File

@ -15,7 +15,7 @@
#include <asm/arch/tegra.h>
#include <asm/arch-tegra/apb_misc.h>
#include <asm/arch-tegra/board.h>
#include <asm/arch/spl.h>
#include <asm/spl.h>
#include "cpu.h"
void spl_board_init(void)

View File

@ -8,4 +8,5 @@
#
obj-y := soc.o clock.o
obj-$(CONFIG_SPL_BUILD) += ddr.o
obj-$(CONFIG_SECURE_BOOT) += hab.o

View File

@ -0,0 +1,490 @@
/*
* Copyright (C) 2014 Gateworks Corporation
* Author: Tim Harvey <tharvey@gateworks.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <linux/types.h>
#include <asm/arch/mx6-ddr.h>
#include <asm/arch/sys_proto.h>
#include <asm/io.h>
#include <asm/types.h>
#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
/* Configure MX6DQ mmdc iomux */
void mx6dq_dram_iocfg(unsigned width,
const struct mx6dq_iomux_ddr_regs *ddr,
const struct mx6dq_iomux_grp_regs *grp)
{
volatile struct mx6dq_iomux_ddr_regs *mx6_ddr_iomux;
volatile struct mx6dq_iomux_grp_regs *mx6_grp_iomux;
mx6_ddr_iomux = (struct mx6dq_iomux_ddr_regs *)MX6DQ_IOM_DDR_BASE;
mx6_grp_iomux = (struct mx6dq_iomux_grp_regs *)MX6DQ_IOM_GRP_BASE;
/* DDR IO Type */
mx6_grp_iomux->grp_ddr_type = grp->grp_ddr_type;
mx6_grp_iomux->grp_ddrpke = grp->grp_ddrpke;
/* Clock */
mx6_ddr_iomux->dram_sdclk_0 = ddr->dram_sdclk_0;
mx6_ddr_iomux->dram_sdclk_1 = ddr->dram_sdclk_1;
/* Address */
mx6_ddr_iomux->dram_cas = ddr->dram_cas;
mx6_ddr_iomux->dram_ras = ddr->dram_ras;
mx6_grp_iomux->grp_addds = grp->grp_addds;
/* Control */
mx6_ddr_iomux->dram_reset = ddr->dram_reset;
mx6_ddr_iomux->dram_sdcke0 = ddr->dram_sdcke0;
mx6_ddr_iomux->dram_sdcke1 = ddr->dram_sdcke1;
mx6_ddr_iomux->dram_sdba2 = ddr->dram_sdba2;
mx6_ddr_iomux->dram_sdodt0 = ddr->dram_sdodt0;
mx6_ddr_iomux->dram_sdodt1 = ddr->dram_sdodt1;
mx6_grp_iomux->grp_ctlds = grp->grp_ctlds;
/* Data Strobes */
mx6_grp_iomux->grp_ddrmode_ctl = grp->grp_ddrmode_ctl;
mx6_ddr_iomux->dram_sdqs0 = ddr->dram_sdqs0;
mx6_ddr_iomux->dram_sdqs1 = ddr->dram_sdqs1;
if (width >= 32) {
mx6_ddr_iomux->dram_sdqs2 = ddr->dram_sdqs2;
mx6_ddr_iomux->dram_sdqs3 = ddr->dram_sdqs3;
}
if (width >= 64) {
mx6_ddr_iomux->dram_sdqs4 = ddr->dram_sdqs4;
mx6_ddr_iomux->dram_sdqs5 = ddr->dram_sdqs5;
mx6_ddr_iomux->dram_sdqs6 = ddr->dram_sdqs6;
mx6_ddr_iomux->dram_sdqs7 = ddr->dram_sdqs7;
}
/* Data */
mx6_grp_iomux->grp_ddrmode = grp->grp_ddrmode;
mx6_grp_iomux->grp_b0ds = grp->grp_b0ds;
mx6_grp_iomux->grp_b1ds = grp->grp_b1ds;
if (width >= 32) {
mx6_grp_iomux->grp_b2ds = grp->grp_b2ds;
mx6_grp_iomux->grp_b3ds = grp->grp_b3ds;
}
if (width >= 64) {
mx6_grp_iomux->grp_b4ds = grp->grp_b4ds;
mx6_grp_iomux->grp_b5ds = grp->grp_b5ds;
mx6_grp_iomux->grp_b6ds = grp->grp_b6ds;
mx6_grp_iomux->grp_b7ds = grp->grp_b7ds;
}
mx6_ddr_iomux->dram_dqm0 = ddr->dram_dqm0;
mx6_ddr_iomux->dram_dqm1 = ddr->dram_dqm1;
if (width >= 32) {
mx6_ddr_iomux->dram_dqm2 = ddr->dram_dqm2;
mx6_ddr_iomux->dram_dqm3 = ddr->dram_dqm3;
}
if (width >= 64) {
mx6_ddr_iomux->dram_dqm4 = ddr->dram_dqm4;
mx6_ddr_iomux->dram_dqm5 = ddr->dram_dqm5;
mx6_ddr_iomux->dram_dqm6 = ddr->dram_dqm6;
mx6_ddr_iomux->dram_dqm7 = ddr->dram_dqm7;
}
}
#endif
#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6DL) || defined(CONFIG_MX6S)
/* Configure MX6SDL mmdc iomux */
void mx6sdl_dram_iocfg(unsigned width,
const struct mx6sdl_iomux_ddr_regs *ddr,
const struct mx6sdl_iomux_grp_regs *grp)
{
volatile struct mx6sdl_iomux_ddr_regs *mx6_ddr_iomux;
volatile struct mx6sdl_iomux_grp_regs *mx6_grp_iomux;
mx6_ddr_iomux = (struct mx6sdl_iomux_ddr_regs *)MX6SDL_IOM_DDR_BASE;
mx6_grp_iomux = (struct mx6sdl_iomux_grp_regs *)MX6SDL_IOM_GRP_BASE;
/* DDR IO Type */
mx6_grp_iomux->grp_ddr_type = grp->grp_ddr_type;
mx6_grp_iomux->grp_ddrpke = grp->grp_ddrpke;
/* Clock */
mx6_ddr_iomux->dram_sdclk_0 = ddr->dram_sdclk_0;
mx6_ddr_iomux->dram_sdclk_1 = ddr->dram_sdclk_1;
/* Address */
mx6_ddr_iomux->dram_cas = ddr->dram_cas;
mx6_ddr_iomux->dram_ras = ddr->dram_ras;
mx6_grp_iomux->grp_addds = grp->grp_addds;
/* Control */
mx6_ddr_iomux->dram_reset = ddr->dram_reset;
mx6_ddr_iomux->dram_sdcke0 = ddr->dram_sdcke0;
mx6_ddr_iomux->dram_sdcke1 = ddr->dram_sdcke1;
mx6_ddr_iomux->dram_sdba2 = ddr->dram_sdba2;
mx6_ddr_iomux->dram_sdodt0 = ddr->dram_sdodt0;
mx6_ddr_iomux->dram_sdodt1 = ddr->dram_sdodt1;
mx6_grp_iomux->grp_ctlds = grp->grp_ctlds;
/* Data Strobes */
mx6_grp_iomux->grp_ddrmode_ctl = grp->grp_ddrmode_ctl;
mx6_ddr_iomux->dram_sdqs0 = ddr->dram_sdqs0;
mx6_ddr_iomux->dram_sdqs1 = ddr->dram_sdqs1;
if (width >= 32) {
mx6_ddr_iomux->dram_sdqs2 = ddr->dram_sdqs2;
mx6_ddr_iomux->dram_sdqs3 = ddr->dram_sdqs3;
}
if (width >= 64) {
mx6_ddr_iomux->dram_sdqs4 = ddr->dram_sdqs4;
mx6_ddr_iomux->dram_sdqs5 = ddr->dram_sdqs5;
mx6_ddr_iomux->dram_sdqs6 = ddr->dram_sdqs6;
mx6_ddr_iomux->dram_sdqs7 = ddr->dram_sdqs7;
}
/* Data */
mx6_grp_iomux->grp_ddrmode = grp->grp_ddrmode;
mx6_grp_iomux->grp_b0ds = grp->grp_b0ds;
mx6_grp_iomux->grp_b1ds = grp->grp_b1ds;
if (width >= 32) {
mx6_grp_iomux->grp_b2ds = grp->grp_b2ds;
mx6_grp_iomux->grp_b3ds = grp->grp_b3ds;
}
if (width >= 64) {
mx6_grp_iomux->grp_b4ds = grp->grp_b4ds;
mx6_grp_iomux->grp_b5ds = grp->grp_b5ds;
mx6_grp_iomux->grp_b6ds = grp->grp_b6ds;
mx6_grp_iomux->grp_b7ds = grp->grp_b7ds;
}
mx6_ddr_iomux->dram_dqm0 = ddr->dram_dqm0;
mx6_ddr_iomux->dram_dqm1 = ddr->dram_dqm1;
if (width >= 32) {
mx6_ddr_iomux->dram_dqm2 = ddr->dram_dqm2;
mx6_ddr_iomux->dram_dqm3 = ddr->dram_dqm3;
}
if (width >= 64) {
mx6_ddr_iomux->dram_dqm4 = ddr->dram_dqm4;
mx6_ddr_iomux->dram_dqm5 = ddr->dram_dqm5;
mx6_ddr_iomux->dram_dqm6 = ddr->dram_dqm6;
mx6_ddr_iomux->dram_dqm7 = ddr->dram_dqm7;
}
}
#endif
/*
* Configure mx6 mmdc registers based on:
* - board-specific memory configuration
* - board-specific calibration data
* - ddr3 chip details
*
* The various calculations here are derived from the Freescale
* i.Mx6DQSDL DDR3 Script Aid spreadsheet (DOC-94917) designed to generate MMDC
* configuration registers based on memory system and memory chip parameters.
*
* The defaults here are those which were specified in the spreadsheet.
* For details on each register, refer to the IMX6DQRM and/or IMX6SDLRM
* section titled MMDC initialization
*/
#define MR(val, ba, cmd, cs1) \
((val << 16) | (1 << 15) | (cmd << 4) | (cs1 << 3) | ba)
void mx6_dram_cfg(const struct mx6_ddr_sysinfo *i,
const struct mx6_mmdc_calibration *c,
const struct mx6_ddr3_cfg *m)
{
volatile struct mmdc_p_regs *mmdc0;
volatile struct mmdc_p_regs *mmdc1;
u32 reg;
u8 tcke, tcksrx, tcksre, txpdll, taofpd, taonpd, trrd;
u8 todtlon, taxpd, tanpd, tcwl, txp, tfaw, tcl;
u8 todt_idle_off = 0x4; /* from DDR3 Script Aid spreadsheet */
u16 trcd, trc, tras, twr, tmrd, trtp, trp, twtr, trfc, txs, txpr;
u16 CS0_END;
u16 tdllk = 0x1ff; /* DLL locking time: 512 cycles (JEDEC DDR3) */
int clkper; /* clock period in picoseconds */
int clock; /* clock freq in mHz */
int cs;
mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR;
mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR;
/* MX6D/MX6Q: 1066 MHz memory clock, clkper = 1.894ns = 1894ps */
if (is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) {
clock = 528;
tcwl = 4;
}
/* MX6S/MX6DL: 800 MHz memory clock, clkper = 2.5ns = 2500ps */
else {
clock = 400;
tcwl = 3;
}
clkper = (1000*1000)/clock; /* ps */
todtlon = tcwl;
taxpd = tcwl;
tanpd = tcwl;
tcwl = tcwl;
switch (m->density) {
case 1: /* 1Gb per chip */
trfc = DIV_ROUND_UP(110000, clkper) - 1;
txs = DIV_ROUND_UP(120000, clkper) - 1;
break;
case 2: /* 2Gb per chip */
trfc = DIV_ROUND_UP(160000, clkper) - 1;
txs = DIV_ROUND_UP(170000, clkper) - 1;
break;
case 4: /* 4Gb per chip */
trfc = DIV_ROUND_UP(260000, clkper) - 1;
txs = DIV_ROUND_UP(270000, clkper) - 1;
break;
case 8: /* 8Gb per chip */
trfc = DIV_ROUND_UP(350000, clkper) - 1;
txs = DIV_ROUND_UP(360000, clkper) - 1;
break;
default:
/* invalid density */
printf("invalid chip density\n");
hang();
break;
}
txpr = txs;
switch (m->mem_speed) {
case 800:
txp = DIV_ROUND_UP(MAX(3*clkper, 7500), clkper) - 1;
tcke = DIV_ROUND_UP(MAX(3*clkper, 7500), clkper) - 1;
if (m->pagesz == 1) {
tfaw = DIV_ROUND_UP(40000, clkper) - 1;
trrd = DIV_ROUND_UP(MAX(4*clkper, 10000), clkper) - 1;
} else {
tfaw = DIV_ROUND_UP(50000, clkper) - 1;
trrd = DIV_ROUND_UP(MAX(4*clkper, 10000), clkper) - 1;
}
break;
case 1066:
txp = DIV_ROUND_UP(MAX(3*clkper, 7500), clkper) - 1;
tcke = DIV_ROUND_UP(MAX(3*clkper, 5625), clkper) - 1;
if (m->pagesz == 1) {
tfaw = DIV_ROUND_UP(37500, clkper) - 1;
trrd = DIV_ROUND_UP(MAX(4*clkper, 7500), clkper) - 1;
} else {
tfaw = DIV_ROUND_UP(50000, clkper) - 1;
trrd = DIV_ROUND_UP(MAX(4*clkper, 10000), clkper) - 1;
}
break;
case 1333:
txp = DIV_ROUND_UP(MAX(3*clkper, 6000), clkper) - 1;
tcke = DIV_ROUND_UP(MAX(3*clkper, 5625), clkper) - 1;
if (m->pagesz == 1) {
tfaw = DIV_ROUND_UP(30000, clkper) - 1;
trrd = DIV_ROUND_UP(MAX(4*clkper, 6000), clkper) - 1;
} else {
tfaw = DIV_ROUND_UP(45000, clkper) - 1;
trrd = DIV_ROUND_UP(MAX(4*clkper, 7500), clkper) - 1;
}
break;
case 1600:
txp = DIV_ROUND_UP(MAX(3*clkper, 6000), clkper) - 1;
tcke = DIV_ROUND_UP(MAX(3*clkper, 5000), clkper) - 1;
if (m->pagesz == 1) {
tfaw = DIV_ROUND_UP(30000, clkper) - 1;
trrd = DIV_ROUND_UP(MAX(4*clkper, 6000), clkper) - 1;
} else {
tfaw = DIV_ROUND_UP(40000, clkper) - 1;
trrd = DIV_ROUND_UP(MAX(4*clkper, 7500), clkper) - 1;
}
break;
default:
printf("invalid memory speed\n");
hang();
break;
}
txpdll = DIV_ROUND_UP(MAX(10*clkper, 24000), clkper) - 1;
tcl = DIV_ROUND_UP(m->trcd, clkper/10) - 3;
tcksre = DIV_ROUND_UP(MAX(5*clkper, 10000), clkper);
tcksrx = tcksre;
taonpd = DIV_ROUND_UP(2000, clkper) - 1;
taofpd = taonpd;
trp = DIV_ROUND_UP(m->trcd, clkper/10) - 1;
trcd = trp;
trc = DIV_ROUND_UP(m->trcmin, clkper/10) - 1;
tras = DIV_ROUND_UP(m->trasmin, clkper/10) - 1;
twr = DIV_ROUND_UP(15000, clkper) - 1;
tmrd = DIV_ROUND_UP(MAX(12*clkper, 15000), clkper) - 1;
twtr = ROUND(MAX(4*clkper, 7500)/clkper, 1) - 1;
trtp = twtr;
CS0_END = ((4*i->cs_density) <= 120) ? (4*i->cs_density)+7 : 127;
debug("density:%d Gb (%d Gb per chip)\n", i->cs_density, m->density);
debug("clock: %dMHz (%d ps)\n", clock, clkper);
debug("memspd:%d\n", m->mem_speed);
debug("tcke=%d\n", tcke);
debug("tcksrx=%d\n", tcksrx);
debug("tcksre=%d\n", tcksre);
debug("taofpd=%d\n", taofpd);
debug("taonpd=%d\n", taonpd);
debug("todtlon=%d\n", todtlon);
debug("tanpd=%d\n", tanpd);
debug("taxpd=%d\n", taxpd);
debug("trfc=%d\n", trfc);
debug("txs=%d\n", txs);
debug("txp=%d\n", txp);
debug("txpdll=%d\n", txpdll);
debug("tfaw=%d\n", tfaw);
debug("tcl=%d\n", tcl);
debug("trcd=%d\n", trcd);
debug("trp=%d\n", trp);
debug("trc=%d\n", trc);
debug("tras=%d\n", tras);
debug("twr=%d\n", twr);
debug("tmrd=%d\n", tmrd);
debug("tcwl=%d\n", tcwl);
debug("tdllk=%d\n", tdllk);
debug("trtp=%d\n", trtp);
debug("twtr=%d\n", twtr);
debug("trrd=%d\n", trrd);
debug("txpr=%d\n", txpr);
debug("CS0_END=%d\n", CS0_END);
debug("ncs=%d\n", i->ncs);
debug("Rtt_wr=%d\n", i->rtt_wr);
debug("Rtt_nom=%d\n", i->rtt_nom);
debug("SRT=%d\n", m->SRT);
debug("tcl=%d\n", tcl);
debug("twr=%d\n", twr);
/*
* board-specific configuration:
* These values are determined empirically and vary per board layout
* see:
* appnote, ddr3 spreadsheet
*/
mmdc0->mpwldectrl0 = c->p0_mpwldectrl0;
mmdc0->mpwldectrl1 = c->p0_mpwldectrl1;
mmdc0->mpdgctrl0 = c->p0_mpdgctrl0;
mmdc0->mpdgctrl1 = c->p0_mpdgctrl1;
mmdc0->mprddlctl = c->p0_mprddlctl;
mmdc0->mpwrdlctl = c->p0_mpwrdlctl;
if (i->dsize > 1) {
mmdc1->mpwldectrl0 = c->p1_mpwldectrl0;
mmdc1->mpwldectrl1 = c->p1_mpwldectrl1;
mmdc1->mpdgctrl0 = c->p1_mpdgctrl0;
mmdc1->mpdgctrl1 = c->p1_mpdgctrl1;
mmdc1->mprddlctl = c->p1_mprddlctl;
mmdc1->mpwrdlctl = c->p1_mpwrdlctl;
}
/* Read data DQ Byte0-3 delay */
mmdc0->mprddqby0dl = (u32)0x33333333;
mmdc0->mprddqby1dl = (u32)0x33333333;
if (i->dsize > 0) {
mmdc0->mprddqby2dl = (u32)0x33333333;
mmdc0->mprddqby3dl = (u32)0x33333333;
}
if (i->dsize > 1) {
mmdc1->mprddqby0dl = (u32)0x33333333;
mmdc1->mprddqby1dl = (u32)0x33333333;
mmdc1->mprddqby2dl = (u32)0x33333333;
mmdc1->mprddqby3dl = (u32)0x33333333;
}
/* MMDC Termination: rtt_nom:2 RZQ/2(120ohm), rtt_nom:1 RZQ/4(60ohm) */
reg = (i->rtt_nom == 2) ? 0x00011117 : 0x00022227;
mmdc0->mpodtctrl = reg;
if (i->dsize > 1)
mmdc1->mpodtctrl = reg;
/* complete calibration */
reg = (1 << 11); /* Force measurement on delay-lines */
mmdc0->mpmur0 = reg;
if (i->dsize > 1)
mmdc1->mpmur0 = reg;
/* Step 1: configuration request */
mmdc0->mdscr = (u32)(1 << 15); /* config request */
/* Step 2: Timing configuration */
reg = (trfc << 24) | (txs << 16) | (txp << 13) | (txpdll << 9) |
(tfaw << 4) | tcl;
mmdc0->mdcfg0 = reg;
reg = (trcd << 29) | (trp << 26) | (trc << 21) | (tras << 16) |
(1 << 15) | /* trpa */
(twr << 9) | (tmrd << 5) | tcwl;
mmdc0->mdcfg1 = reg;
reg = (tdllk << 16) | (trtp << 6) | (twtr << 3) | trrd;
mmdc0->mdcfg2 = reg;
reg = (taofpd << 27) | (taonpd << 24) | (tanpd << 20) | (taxpd << 16) |
(todtlon << 12) | (todt_idle_off << 4);
mmdc0->mdotc = reg;
mmdc0->mdasp = CS0_END; /* CS addressing */
/* Step 3: Configure DDR type */
reg = (i->cs1_mirror << 19) | (i->walat << 16) | (i->bi_on << 12) |
(i->mif3_mode << 9) | (i->ralat << 6);
mmdc0->mdmisc = reg;
/* Step 4: Configure delay while leaving reset */
reg = (txpr << 16) | (i->sde_to_rst << 8) | (i->rst_to_cke << 0);
mmdc0->mdor = reg;
/* Step 5: Configure DDR physical parameters (density and burst len) */
reg = (m->rowaddr - 11) << 24 | /* ROW */
(m->coladdr - 9) << 20 | /* COL */
(1 << 19) | /* Burst Length = 8 for DDR3 */
(i->dsize << 16); /* DDR data bus size */
mmdc0->mdctl = reg;
/* Step 6: Perform ZQ calibration */
reg = (u32)0xa1390001; /* one-time HW ZQ calib */
mmdc0->mpzqhwctrl = reg;
if (i->dsize > 1)
mmdc1->mpzqhwctrl = reg;
/* Step 7: Enable MMDC with desired chip select */
reg = mmdc0->mdctl |
(1 << 31) | /* SDE_0 for CS0 */
((i->ncs == 2) ? 1 : 0) << 30; /* SDE_1 for CS1 */
mmdc0->mdctl = reg;
/* Step 8: Write Mode Registers to Init DDR3 devices */
for (cs = 0; cs < i->ncs; cs++) {
/* MR2 */
reg = (i->rtt_wr & 3) << 9 | (m->SRT & 1) << 7 |
((tcwl - 3) & 3) << 3;
mmdc0->mdscr = (u32)MR(reg, 2, 3, cs);
/* MR3 */
mmdc0->mdscr = (u32)MR(0, 3, 3, cs);
/* MR1 */
reg = ((i->rtt_nom & 1) ? 1 : 0) << 2 |
((i->rtt_nom & 2) ? 1 : 0) << 6;
mmdc0->mdscr = (u32)MR(reg, 1, 3, cs);
reg = ((tcl - 1) << 4) | /* CAS */
(1 << 8) | /* DLL Reset */
((twr - 3) << 9); /* Write Recovery */
/* MR0 */
mmdc0->mdscr = (u32)MR(reg, 0, 3, cs);
/* ZQ calibration */
reg = (1 << 10);
mmdc0->mdscr = (u32)MR(reg, 0, 4, cs);
}
/* Step 10: Power down control and self-refresh */
reg = (tcke & 0x7) << 16 |
5 << 12 | /* PWDT_1: 256 cycles */
5 << 8 | /* PWDT_0: 256 cycles */
1 << 6 | /* BOTH_CS_PD */
(tcksrx & 0x7) << 3 |
(tcksre & 0x7);
mmdc0->mdpdc = reg;
mmdc0->mapsr = (u32)0x00011006; /* ADOPT power down enabled */
/* Step 11: Configure ZQ calibration: one-time and periodic 1ms */
mmdc0->mpzqhwctrl = (u32)0xa1390003;
if (i->dsize > 1)
mmdc1->mpzqhwctrl = (u32)0xa1390003;
/* Step 12: Configure and activate periodic refresh */
reg = (1 << 14) | /* REF_SEL: Periodic refresh cycles of 32kHz */
(7 << 11); /* REFR: Refresh Rate - 8 refreshes */
mmdc0->mdref = reg;
/* Step 13: Deassert config request - init complete */
mmdc0->mdscr = (u32)0x00000000;
/* wait for auto-ZQ calibration to complete */
mdelay(1);
}

View File

@ -7,15 +7,69 @@
#include <common.h>
#include <asm/io.h>
#include <asm/arch/hab.h>
#include <asm/arch/sys_proto.h>
/* -------- start of HAB API updates ------------*/
#define hab_rvt_report_event ((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT)
#define hab_rvt_report_status ((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS)
#define hab_rvt_authenticate_image \
((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE)
#define hab_rvt_entry ((hab_rvt_entry_t *)HAB_RVT_ENTRY)
#define hab_rvt_exit ((hab_rvt_exit_t *)HAB_RVT_EXIT)
#define hab_rvt_clock_init HAB_RVT_CLOCK_INIT
#define hab_rvt_report_event_p \
( \
((is_cpu_type(MXC_CPU_MX6Q) || \
is_cpu_type(MXC_CPU_MX6D)) && \
(soc_rev() >= CHIP_REV_1_5)) ? \
((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT_NEW) : \
(is_cpu_type(MXC_CPU_MX6DL) && \
(soc_rev() >= CHIP_REV_1_2)) ? \
((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT_NEW) : \
((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT) \
)
#define hab_rvt_report_status_p \
( \
((is_cpu_type(MXC_CPU_MX6Q) || \
is_cpu_type(MXC_CPU_MX6D)) && \
(soc_rev() >= CHIP_REV_1_5)) ? \
((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS_NEW) :\
(is_cpu_type(MXC_CPU_MX6DL) && \
(soc_rev() >= CHIP_REV_1_2)) ? \
((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS_NEW) :\
((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS) \
)
#define hab_rvt_authenticate_image_p \
( \
((is_cpu_type(MXC_CPU_MX6Q) || \
is_cpu_type(MXC_CPU_MX6D)) && \
(soc_rev() >= CHIP_REV_1_5)) ? \
((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE_NEW) : \
(is_cpu_type(MXC_CPU_MX6DL) && \
(soc_rev() >= CHIP_REV_1_2)) ? \
((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE_NEW) : \
((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE) \
)
#define hab_rvt_entry_p \
( \
((is_cpu_type(MXC_CPU_MX6Q) || \
is_cpu_type(MXC_CPU_MX6D)) && \
(soc_rev() >= CHIP_REV_1_5)) ? \
((hab_rvt_entry_t *)HAB_RVT_ENTRY_NEW) : \
(is_cpu_type(MXC_CPU_MX6DL) && \
(soc_rev() >= CHIP_REV_1_2)) ? \
((hab_rvt_entry_t *)HAB_RVT_ENTRY_NEW) : \
((hab_rvt_entry_t *)HAB_RVT_ENTRY) \
)
#define hab_rvt_exit_p \
( \
((is_cpu_type(MXC_CPU_MX6Q) || \
is_cpu_type(MXC_CPU_MX6D)) && \
(soc_rev() >= CHIP_REV_1_5)) ? \
((hab_rvt_exit_t *)HAB_RVT_EXIT_NEW) : \
(is_cpu_type(MXC_CPU_MX6DL) && \
(soc_rev() >= CHIP_REV_1_2)) ? \
((hab_rvt_exit_t *)HAB_RVT_EXIT_NEW) : \
((hab_rvt_exit_t *)HAB_RVT_EXIT) \
)
bool is_hab_enabled(void)
{
@ -52,6 +106,11 @@ int get_hab_status(void)
size_t bytes = sizeof(event_data); /* Event size in bytes */
enum hab_config config = 0;
enum hab_state state = 0;
hab_rvt_report_event_t *hab_rvt_report_event;
hab_rvt_report_status_t *hab_rvt_report_status;
hab_rvt_report_event = hab_rvt_report_event_p;
hab_rvt_report_status = hab_rvt_report_status_p;
if (is_hab_enabled())
puts("\nSecure boot enabled\n");

View File

@ -16,6 +16,7 @@ obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o
endif
ifeq ($(SOC),$(filter $(SOC),mx6 mxs))
obj-y += misc.o
obj-$(CONFIG_SPL_BUILD) += spl.o
endif
ifeq ($(SOC),$(filter $(SOC),mx6))
obj-$(CONFIG_CMD_SATA) += sata.o

View File

@ -58,6 +58,7 @@ char *get_reset_cause(void)
static const unsigned char col_lookup[] = {9, 10, 11, 8, 12, 9, 9, 9};
static const unsigned char bank_lookup[] = {3, 2};
/* these MMDC registers are common to the IMX53 and IMX6 */
struct esd_mmdc_regs {
uint32_t ctl;
uint32_t pdc;
@ -66,15 +67,6 @@ struct esd_mmdc_regs {
uint32_t cfg1;
uint32_t cfg2;
uint32_t misc;
uint32_t scr;
uint32_t ref;
uint32_t rsvd1;
uint32_t rsvd2;
uint32_t rwd;
uint32_t or;
uint32_t mrr;
uint32_t cfg3lp;
uint32_t mr4;
};
#define ESD_MMDC_CTL_GET_ROW(mdctl) ((ctl >> 24) & 7)
@ -83,6 +75,12 @@ struct esd_mmdc_regs {
#define ESD_MMDC_CTL_GET_CS1(mdctl) ((ctl >> 30) & 1)
#define ESD_MMDC_MISC_GET_BANK(mdmisc) ((misc >> 5) & 1)
/*
* imx_ddr_size - return size in bytes of DRAM according MMDC config
* The MMDC MDCTL register holds the number of bits for row, col, and data
* width and the MMDC MDMISC register holds the number of banks. Combine
* all these bits to determine the meme size the MMDC has been configured for
*/
unsigned imx_ddr_size(void)
{
struct esd_mmdc_regs *mem = (struct esd_mmdc_regs *)MEMCTL_BASE;

View File

@ -11,6 +11,9 @@
#include <common.h>
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
#if !defined(CONFIG_MX25) && !defined(CONFIG_VF610)
#include <asm/arch/sys_proto.h>
#endif
#include <asm/imx-common/iomux-v3.h>
static void *base = (void *)IOMUXC_BASE_ADDR;
@ -54,12 +57,23 @@ void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad)
#endif
}
/* configures a list of pads within declared with IOMUX_PADS macro */
void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
unsigned count)
{
iomux_v3_cfg_t const *p = pad_list;
int stride;
int i;
for (i = 0; i < count; i++)
imx_iomux_v3_setup_pad(*p++);
#if defined(CONFIG_MX6QDL)
stride = 2;
if (!is_cpu_type(MXC_CPU_MX6Q) && !is_cpu_type(MXC_CPU_MX6D))
p += 1;
#else
stride = 1;
#endif
for (i = 0; i < count; i++) {
imx_iomux_v3_setup_pad(*p);
p += stride;
}
}

View File

@ -8,13 +8,18 @@
#include <asm/arch/iomux.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/sys_proto.h>
int setup_sata(void)
{
struct iomuxc_base_regs *const iomuxc_regs
= (struct iomuxc_base_regs *)IOMUXC_BASE_ADDR;
int ret;
int ret = enable_sata_clock();
if (!is_cpu_type(MXC_CPU_MX6Q) && !is_cpu_type(MXC_CPU_MX6D))
return 1;
ret = enable_sata_clock();
if (ret)
return ret;

81
arch/arm/imx-common/spl.c Normal file
View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2014 Gateworks Corporation
* Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
*
* Author: Tim Harvey <tharvey@gateworks.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
#include <asm/spl.h>
#include <spl.h>
#if defined(CONFIG_MX6)
/* determine boot device from SRC_SBMR1 register (BOOT_CFG[4:1]) */
u32 spl_boot_device(void)
{
struct src *psrc = (struct src *)SRC_BASE_ADDR;
unsigned reg = readl(&psrc->sbmr1);
/* BOOT_CFG1[7:4] - see IMX6DQRM Table 8-8 */
switch ((reg & 0x000000FF) >> 4) {
/* EIM: See 8.5.1, Table 8-9 */
case 0x0:
/* BOOT_CFG1[3]: NOR/OneNAND Selection */
if ((reg & 0x00000008) >> 3)
return BOOT_DEVICE_ONENAND;
else
return BOOT_DEVICE_NOR;
break;
/* SATA: See 8.5.4, Table 8-20 */
case 0x2:
return BOOT_DEVICE_SATA;
/* Serial ROM: See 8.5.5.1, Table 8-22 */
case 0x3:
/* BOOT_CFG4[2:0] */
switch ((reg & 0x07000000) >> 24) {
case 0x0 ... 0x4:
return BOOT_DEVICE_SPI;
case 0x5 ... 0x7:
return BOOT_DEVICE_I2C;
}
break;
/* SD/eSD: 8.5.3, Table 8-15 */
case 0x4:
case 0x5:
return BOOT_DEVICE_MMC1;
/* MMC/eMMC: 8.5.3 */
case 0x6:
case 0x7:
return BOOT_DEVICE_MMC1;
/* NAND Flash: 8.5.2 */
case 0x8 ... 0xf:
return BOOT_DEVICE_NAND;
}
return BOOT_DEVICE_NONE;
}
#endif
#if defined(CONFIG_SPL_MMC_SUPPORT)
/* called from spl_mmc to see type of boot mode for storage (RAW or FAT) */
u32 spl_boot_mode(void)
{
switch (spl_boot_device()) {
/* for MMC return either RAW or FAT mode */
case BOOT_DEVICE_MMC1:
case BOOT_DEVICE_MMC2:
#ifdef CONFIG_SPL_FAT_SUPPORT
return MMCSD_MODE_FAT;
#else
return MMCSD_MODE_RAW;
#endif
break;
default:
puts("spl: ERROR: unsupported device\n");
hang();
}
}
#endif

View File

@ -1,24 +0,0 @@
/*
* Copyright (C) 2013 Atmel Corporation
* Bo Shen <voice.shen@atmel.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARCH_SPL_H_
#define _ASM_ARCH_SPL_H_
enum {
BOOT_DEVICE_NONE,
#ifdef CONFIG_SYS_USE_MMC
BOOT_DEVICE_MMC1,
BOOT_DEVICE_MMC2,
BOOT_DEVICE_MMC2_2,
#elif CONFIG_SYS_USE_NANDFLASH
BOOT_DEVICE_NAND,
#elif CONFIG_SYS_USE_SERIALFLASH
BOOT_DEVICE_SPI,
#endif
};
#endif

View File

@ -1,16 +0,0 @@
/*
* (C) Copyright 2012
* Texas Instruments, <www.ti.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARCH_SPL_H_
#define _ASM_ARCH_SPL_H_
#define BOOT_DEVICE_NAND 1
#define BOOT_DEVICE_SPI 2
#define BOOT_DEVICE_MMC1 3
#define BOOT_DEVICE_MMC2 4 /* dummy */
#define BOOT_DEVICE_MMC2_2 5 /* dummy */
#endif

View File

@ -1,22 +0,0 @@
/*
* (C) Copyright 2012
* Texas Instruments, <www.ti.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARCH_SPL_H_
#define _ASM_ARCH_SPL_H_
#define BOOT_DEVICE_NONE 0
#define BOOT_DEVICE_XIP 1
#define BOOT_DEVICE_XIPWAIT 2
#define BOOT_DEVICE_NAND 3
#define BOOT_DEVICE_ONENAND 4
#define BOOT_DEVICE_MMC1 5
#define BOOT_DEVICE_MMC2 6
#define BOOT_DEVICE_MMC2_2 7
#define BOOT_DEVICE_NOR 8
#define BOOT_DEVICE_I2C 9
#define BOOT_DEVICE_SPI 10
#endif

View File

@ -1,13 +0,0 @@
/*
* Copyright (C) 2013 Marek Vasut <marex@denx.de>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __ASM_ARCH_SPL_H__
#define __ASM_ARCH_SPL_H__
#define BOOT_DEVICE_NONE 0
#define BOOT_DEVICE_NAND 1
#endif /* __ASM_ARCH_SPL_H__ */

View File

@ -53,12 +53,17 @@ typedef void *hab_rvt_authenticate_image_t(uint8_t, ptrdiff_t,
void **, size_t *, hab_loader_callback_f_t);
typedef void hapi_clock_init_t(void);
#define HAB_RVT_REPORT_EVENT (*(uint32_t *)0x000000B4)
#define HAB_RVT_REPORT_STATUS (*(uint32_t *)0x000000B8)
#define HAB_RVT_AUTHENTICATE_IMAGE (*(uint32_t *)0x000000A4)
#define HAB_RVT_ENTRY (*(uint32_t *)0x00000098)
#define HAB_RVT_EXIT (*(uint32_t *)0x0000009C)
#define HAB_RVT_CLOCK_INIT ((hapi_clock_init_t *)0x0000024D)
#define HAB_RVT_REPORT_EVENT (*(uint32_t *)0x000000B4)
#define HAB_RVT_REPORT_STATUS (*(uint32_t *)0x000000B8)
#define HAB_RVT_AUTHENTICATE_IMAGE (*(uint32_t *)0x000000A4)
#define HAB_RVT_ENTRY (*(uint32_t *)0x00000098)
#define HAB_RVT_EXIT (*(uint32_t *)0x0000009C)
#define HAB_RVT_REPORT_EVENT_NEW (*(uint32_t *)0x000000B8)
#define HAB_RVT_REPORT_STATUS_NEW (*(uint32_t *)0x000000BC)
#define HAB_RVT_AUTHENTICATE_IMAGE_NEW (*(uint32_t *)0x000000A8)
#define HAB_RVT_ENTRY_NEW (*(uint32_t *)0x0000009C)
#define HAB_RVT_EXIT_NEW (*(uint32_t *)0x000000A0)
#define HAB_CID_ROM 0 /**< ROM Caller ID */
#define HAB_CID_UBOOT 1 /**< UBOOT Caller ID*/

View File

@ -217,6 +217,8 @@
#define IP2APB_USBPHY2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x7C000)
#define CHIP_REV_1_0 0x10
#define CHIP_REV_1_2 0x12
#define CHIP_REV_1_5 0x15
#define IRAM_SIZE 0x00040000
#define FEC_QUIRK_ENET_MAC

View File

@ -39,7 +39,7 @@
#define IOMUXC_GPR12_LOS_LEVEL_MASK (0x1f << 4)
#define IOMUXC_GPR12_APPS_LTSSM_ENABLE (1 << 10)
#define IOMUXC_GPR12_DEVICE_TYPE_EP (0x0 << 12)
#define IOMUXC_GPR12_DEVICE_TYPE_RC (0x2 << 12)
#define IOMUXC_GPR12_DEVICE_TYPE_RC (0x4 << 12)
#define IOMUXC_GPR12_DEVICE_TYPE_MASK (0xf << 12)
/*

View File

@ -6,6 +6,7 @@
#ifndef __ASM_ARCH_MX6_DDR_H__
#define __ASM_ARCH_MX6_DDR_H__
#ifndef CONFIG_SPL_BUILD
#ifdef CONFIG_MX6Q
#include "mx6q-ddr.h"
#else
@ -15,6 +16,236 @@
#error "Please select cpu"
#endif /* CONFIG_MX6DL or CONFIG_MX6S */
#endif /* CONFIG_MX6Q */
#else
/* MMDC P0/P1 Registers */
struct mmdc_p_regs {
u32 mdctl;
u32 mdpdc;
u32 mdotc;
u32 mdcfg0;
u32 mdcfg1;
u32 mdcfg2;
u32 mdmisc;
u32 mdscr;
u32 mdref;
u32 res1[2];
u32 mdrwd;
u32 mdor;
u32 res2[3];
u32 mdasp;
u32 res3[240];
u32 mapsr;
u32 res4[254];
u32 mpzqhwctrl;
u32 res5[2];
u32 mpwldectrl0;
u32 mpwldectrl1;
u32 res6;
u32 mpodtctrl;
u32 mprddqby0dl;
u32 mprddqby1dl;
u32 mprddqby2dl;
u32 mprddqby3dl;
u32 res7[4];
u32 mpdgctrl0;
u32 mpdgctrl1;
u32 res8;
u32 mprddlctl;
u32 res9;
u32 mpwrdlctl;
u32 res10[25];
u32 mpmur0;
};
/*
* MMDC iomux registers (pinctl/padctl) - (different for IMX6DQ vs IMX6SDL)
*/
#define MX6DQ_IOM_DDR_BASE 0x020e0500
struct mx6dq_iomux_ddr_regs {
u32 res1[3];
u32 dram_sdqs5;
u32 dram_dqm5;
u32 dram_dqm4;
u32 dram_sdqs4;
u32 dram_sdqs3;
u32 dram_dqm3;
u32 dram_sdqs2;
u32 dram_dqm2;
u32 res2[16];
u32 dram_cas;
u32 res3[2];
u32 dram_ras;
u32 dram_reset;
u32 res4[2];
u32 dram_sdclk_0;
u32 dram_sdba2;
u32 dram_sdcke0;
u32 dram_sdclk_1;
u32 dram_sdcke1;
u32 dram_sdodt0;
u32 dram_sdodt1;
u32 res5;
u32 dram_sdqs0;
u32 dram_dqm0;
u32 dram_sdqs1;
u32 dram_dqm1;
u32 dram_sdqs6;
u32 dram_dqm6;
u32 dram_sdqs7;
u32 dram_dqm7;
};
#define MX6DQ_IOM_GRP_BASE 0x020e0700
struct mx6dq_iomux_grp_regs {
u32 res1[18];
u32 grp_b7ds;
u32 grp_addds;
u32 grp_ddrmode_ctl;
u32 res2;
u32 grp_ddrpke;
u32 res3[6];
u32 grp_ddrmode;
u32 res4[3];
u32 grp_b0ds;
u32 grp_b1ds;
u32 grp_ctlds;
u32 res5;
u32 grp_b2ds;
u32 grp_ddr_type;
u32 grp_b3ds;
u32 grp_b4ds;
u32 grp_b5ds;
u32 grp_b6ds;
};
#define MX6SDL_IOM_DDR_BASE 0x020e0400
struct mx6sdl_iomux_ddr_regs {
u32 res1[25];
u32 dram_cas;
u32 res2[2];
u32 dram_dqm0;
u32 dram_dqm1;
u32 dram_dqm2;
u32 dram_dqm3;
u32 dram_dqm4;
u32 dram_dqm5;
u32 dram_dqm6;
u32 dram_dqm7;
u32 dram_ras;
u32 dram_reset;
u32 res3[2];
u32 dram_sdba2;
u32 dram_sdcke0;
u32 dram_sdcke1;
u32 dram_sdclk_0;
u32 dram_sdclk_1;
u32 dram_sdodt0;
u32 dram_sdodt1;
u32 dram_sdqs0;
u32 dram_sdqs1;
u32 dram_sdqs2;
u32 dram_sdqs3;
u32 dram_sdqs4;
u32 dram_sdqs5;
u32 dram_sdqs6;
u32 dram_sdqs7;
};
#define MX6SDL_IOM_GRP_BASE 0x020e0700
struct mx6sdl_iomux_grp_regs {
u32 res1[18];
u32 grp_b7ds;
u32 grp_addds;
u32 grp_ddrmode_ctl;
u32 grp_ddrpke;
u32 res2[2];
u32 grp_ddrmode;
u32 grp_b0ds;
u32 res3;
u32 grp_ctlds;
u32 grp_b1ds;
u32 grp_ddr_type;
u32 grp_b2ds;
u32 grp_b3ds;
u32 grp_b4ds;
u32 grp_b5ds;
u32 res4;
u32 grp_b6ds;
};
/* Device Information: Varies per DDR3 part number and speed grade */
struct mx6_ddr3_cfg {
u16 mem_speed; /* ie 1600 for DDR3-1600 (800,1066,1333,1600) */
u8 density; /* chip density (Gb) (1,2,4,8) */
u8 width; /* bus width (bits) (4,8,16) */
u8 banks; /* number of banks */
u8 rowaddr; /* row address bits (11-16)*/
u8 coladdr; /* col address bits (9-12) */
u8 pagesz; /* page size (K) (1-2) */
u16 trcd; /* tRCD=tRP=CL (ns*100) */
u16 trcmin; /* tRC min (ns*100) */
u16 trasmin; /* tRAS min (ns*100) */
u8 SRT; /* self-refresh temperature: 0=normal, 1=extended */
};
/* System Information: Varies per board design, layout, and term choices */
struct mx6_ddr_sysinfo {
u8 dsize; /* size of bus (in dwords: 0=16bit,1=32bit,2=64bit) */
u8 cs_density; /* density per chip select (Gb) */
u8 ncs; /* number chip selects used (1|2) */
char cs1_mirror;/* enable address mirror (0|1) */
char bi_on; /* Bank interleaving enable */
u8 rtt_nom; /* Rtt_Nom (DDR3_RTT_*) */
u8 rtt_wr; /* Rtt_Wr (DDR3_RTT_*) */
u8 ralat; /* Read Additional Latency (0-7) */
u8 walat; /* Write Additional Latency (0-3) */
u8 mif3_mode; /* Command prediction working mode */
u8 rst_to_cke; /* Time from SDE enable to CKE rise */
u8 sde_to_rst; /* Time from SDE enable until DDR reset# is high */
};
/*
* Board specific calibration:
* This includes write leveling calibration values as well as DQS gating
* and read/write delays. These values are board/layout/device specific.
* Freescale recommends using the i.MX6 DDR Stress Test Tool V1.0.2
* (DOC-96412) to determine these values over a range of boards and
* temperatures.
*/
struct mx6_mmdc_calibration {
/* write leveling calibration */
u32 p0_mpwldectrl0;
u32 p0_mpwldectrl1;
u32 p1_mpwldectrl0;
u32 p1_mpwldectrl1;
/* read DQS gating */
u32 p0_mpdgctrl0;
u32 p0_mpdgctrl1;
u32 p1_mpdgctrl0;
u32 p1_mpdgctrl1;
/* read delay */
u32 p0_mprddlctl;
u32 p1_mprddlctl;
/* write delay */
u32 p0_mpwrdlctl;
u32 p1_mpwrdlctl;
};
/* configure iomux (pinctl/padctl) */
void mx6dq_dram_iocfg(unsigned width,
const struct mx6dq_iomux_ddr_regs *,
const struct mx6dq_iomux_grp_regs *);
void mx6sdl_dram_iocfg(unsigned width,
const struct mx6sdl_iomux_ddr_regs *,
const struct mx6sdl_iomux_grp_regs *);
/* configure mx6 mmdc registers */
void mx6_dram_cfg(const struct mx6_ddr_sysinfo *,
const struct mx6_mmdc_calibration *,
const struct mx6_ddr3_cfg *);
#endif /* CONFIG_SPL_BUILD */
#define MX6_MMDC_P0_MDCTL 0x021b0000
#define MX6_MMDC_P0_MDPDC 0x021b0004

View File

@ -11,7 +11,9 @@
#include <asm/imx-common/regs-common.h>
#include "../arch-imx/cpu.h"
#define is_soc_rev(rev) ((get_cpu_rev() & 0xFF) - rev)
#define soc_rev() (get_cpu_rev() & 0xFF)
#define is_soc_rev(rev) (soc_rev() - rev)
u32 get_cpu_rev(void);
/* returns MXC_CPU_ value */

View File

@ -1,22 +0,0 @@
/*
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ASM_ARCH_SPL_H_
#define _ASM_ARCH_SPL_H_
#define BOOT_DEVICE_RAM 1
#endif

View File

@ -1,13 +0,0 @@
/*
* (C) Copyright 2010-2013
* NVIDIA Corporation <www.nvidia.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARCH_SPL_H_
#define _ASM_ARCH_SPL_H_
#define BOOT_DEVICE_RAM 1
#endif /* _ASM_ARCH_SPL_H_ */

View File

@ -1,12 +0,0 @@
/*
* (C) Copyright 2012
* NVIDIA Corporation <www.nvidia.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARCH_SPL_H_
#define _ASM_ARCH_SPL_H_
#define BOOT_DEVICE_RAM 1
#endif

View File

@ -1,12 +0,0 @@
/*
* (C) Copyright 2012
* NVIDIA Corporation <www.nvidia.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ASM_ARCH_SPL_H_
#define _ASM_ARCH_SPL_H_
#define BOOT_DEVICE_RAM 1
#endif

View File

@ -177,4 +177,29 @@ void imx_iomux_v3_setup_pad(iomux_v3_cfg_t pad);
void imx_iomux_v3_setup_multiple_pads(iomux_v3_cfg_t const *pad_list,
unsigned count);
/* macros for declaring and using pinmux array */
#if defined(CONFIG_MX6QDL)
#define IOMUX_PADS(x) (MX6Q_##x), (MX6DL_##x)
#define SETUP_IOMUX_PAD(def) \
if (is_cpu_type(MXC_CPU_MX6Q)) { \
imx_iomux_v3_setup_pad(MX6Q_##def); \
} else { \
imx_iomux_v3_setup_pad(MX6DL_##def); \
}
#define SETUP_IOMUX_PADS(x) \
imx_iomux_v3_setup_multiple_pads(x, ARRAY_SIZE(x)/2)
#elif defined(CONFIG_MX6Q) || defined(CONFIG_MX6D)
#define IOMUX_PADS(x) MX6Q_##x
#define SETUP_IOMUX_PAD(def) \
imx_iomux_v3_setup_pad(MX6Q_##def);
#define SETUP_IOMUX_PADS(x) \
imx_iomux_v3_setup_multiple_pads(x, ARRAY_SIZE(x))
#else
#define IOMUX_PADS(x) MX6DL_##x
#define SETUP_IOMUX_PAD(def) \
imx_iomux_v3_setup_pad(MX6DL_##def);
#define SETUP_IOMUX_PADS(x) \
imx_iomux_v3_setup_multiple_pads(x, ARRAY_SIZE(x))
#endif
#endif /* __MACH_IOMUX_V3_H__*/

View File

@ -7,9 +7,29 @@
#ifndef _ASM_SPL_H_
#define _ASM_SPL_H_
#if defined(CONFIG_OMAP) || defined(CONFIG_SOCFPGA) || defined(CONFIG_ZYNQ) \
|| defined(CONFIG_EXYNOS4) || defined(CONFIG_EXYNOS5) \
|| defined(CONFIG_EXYNOS4210)
/* Platform-specific defines */
#include <asm/arch/spl.h>
#else
enum {
BOOT_DEVICE_RAM,
BOOT_DEVICE_MMC1,
BOOT_DEVICE_MMC2,
BOOT_DEVICE_MMC2_2,
BOOT_DEVICE_NAND,
BOOT_DEVICE_ONENAND,
BOOT_DEVICE_NOR,
BOOT_DEVICE_UART,
BOOT_DEVICE_SPI,
BOOT_DEVICE_SATA,
BOOT_DEVICE_I2C,
BOOT_DEVICE_NONE
};
#endif
/* Linker symbols. */
extern char __bss_start[], __bss_end[];

View File

@ -14,7 +14,7 @@
#include <asm/arch/clock.h>
#include <asm/arch/iomux-mx53.h>
#include <asm/imx-common/mx5_video.h>
#include <asm/arch/spl.h>
#include <asm/spl.h>
#include <asm/errno.h>
#include <netdev.h>
#include <i2c.h>

View File

@ -23,11 +23,19 @@ To boot MX28EVK from an SD card, set the boot mode DIP switches as:
* VDD 5V: To the left (off)
* Hold Button: Down (off)
To boot MX28EVK from SPI NOR flash, set the boot mode DIP switches as:
* Boot Mode Select: 0 0 1 0 (Boot from SSP2)
* JTAG PSWITCH RESET: To the right (reset disabled)
* Battery Source: Down
* Wall 5V: Up
* VDD 5V: To the left (off)
* Hold Button: Down (off)
Environment Storage
-------------------
There are two targets for mx28evk:
There are three targets for mx28evk:
"make mx28evk_config" - store environment variables into MMC
@ -35,12 +43,20 @@ or
"make mx28evk_nand_config" - store environment variables into NAND flash
or
"make mx28evk_spi_config" - store enviroment variables into SPI NOR flash
Choose the target accordingly.
Note: The mx28evk board does not come with a NAND flash populated from the
factory. It comes with an empty slot (U23), which allows the insertion of a
48-pin TSOP flash device.
Follow the instructions from doc/README.mxs to generate a bootable SD card.
mx28evk does not come with SPI NOR flash populated from the factory either.
It is possible to solder a SOIC memory on U49 or use a DIP8 on J89.
To get SPI communication to work R320, R321,R322 and C178 need to be populated.
Look in the schematics for the proper component values.
Insert the SD card in slot 0, power up the board and U-boot will boot.
Follow the instructions from doc/README.mxs to generate a bootable SD card or
to generate a binary to be flashed into SPI NOR.

View File

@ -0,0 +1,130 @@
/*
* Copyright (C) 2013 Freescale Semiconductor, Inc.
* Jason Liu <r64343@freescale.com>
*
* SPDX-License-Identifier: GPL-2.0+
*
* Refer doc/README.imximage for more details about how-to configure
* and create imximage boot image
*
* The syntax is taken as close as possible with the kwbimage
*/
/* image version */
IMAGE_VERSION 2
/*
* Boot Device : one of
* spi, sd (the board has no nand neither onenand)
*/
BOOT_FROM sd
/*
* Device Configuration Data (DCD)
*
* Each entry must have the format:
* Addr-type Address Value
*
* where:
* Addr-type register length (1,2 or 4 bytes)
* Address absolute address of the register
* value value to be stored in the register
*/
DATA 4 0x020e0774 0x000C0000
DATA 4 0x020e0754 0x00000000
DATA 4 0x020e04ac 0x00000030
DATA 4 0x020e04b0 0x00000030
DATA 4 0x020e0464 0x00000030
DATA 4 0x020e0490 0x00000030
DATA 4 0x020e074c 0x00000030
DATA 4 0x020e0494 0x00000030
DATA 4 0x020e04a0 0x00000000
DATA 4 0x020e04b4 0x00000030
DATA 4 0x020e04b8 0x00000030
DATA 4 0x020e076c 0x00000030
DATA 4 0x020e0750 0x00020000
DATA 4 0x020e04bc 0x00000028
DATA 4 0x020e04c0 0x00000028
DATA 4 0x020e04c4 0x00000028
DATA 4 0x020e04c8 0x00000028
DATA 4 0x020e04cc 0x00000028
DATA 4 0x020e04d0 0x00000028
DATA 4 0x020e04d4 0x00000028
DATA 4 0x020e04d8 0x00000028
DATA 4 0x020e0760 0x00020000
DATA 4 0x020e0764 0x00000028
DATA 4 0x020e0770 0x00000028
DATA 4 0x020e0778 0x00000028
DATA 4 0x020e077c 0x00000028
DATA 4 0x020e0780 0x00000028
DATA 4 0x020e0784 0x00000028
DATA 4 0x020e078c 0x00000028
DATA 4 0x020e0748 0x00000028
DATA 4 0x020e0470 0x00000028
DATA 4 0x020e0474 0x00000028
DATA 4 0x020e0478 0x00000028
DATA 4 0x020e047c 0x00000028
DATA 4 0x020e0480 0x00000028
DATA 4 0x020e0484 0x00000028
DATA 4 0x020e0488 0x00000028
DATA 4 0x020e048c 0x00000028
DATA 4 0x021b0800 0xa1390003
DATA 4 0x021b080c 0x001F001F
DATA 4 0x021b0810 0x001F001F
DATA 4 0x021b480c 0x001F001F
DATA 4 0x021b4810 0x001F001F
DATA 4 0x021b083c 0x42190217
DATA 4 0x021b0840 0x017B017B
DATA 4 0x021b483c 0x4176017B
DATA 4 0x021b4840 0x015F016C
DATA 4 0x021b0848 0x4C4C4D4C
DATA 4 0x021b4848 0x4A4D4C48
DATA 4 0x021b0850 0x3F3F3F40
DATA 4 0x021b4850 0x3538382E
DATA 4 0x021b081c 0x33333333
DATA 4 0x021b0820 0x33333333
DATA 4 0x021b0824 0x33333333
DATA 4 0x021b0828 0x33333333
DATA 4 0x021b481c 0x33333333
DATA 4 0x021b4820 0x33333333
DATA 4 0x021b4824 0x33333333
DATA 4 0x021b4828 0x33333333
DATA 4 0x021b08b8 0x00000800
DATA 4 0x021b48b8 0x00000800
DATA 4 0x021b0004 0x00020025
DATA 4 0x021b0008 0x00333030
DATA 4 0x021b000c 0x676B5313
DATA 4 0x021b0010 0xB66E8B63
DATA 4 0x021b0014 0x01FF00DB
DATA 4 0x021b0018 0x00001740
DATA 4 0x021b001c 0x00008000
DATA 4 0x021b002c 0x000026d2
DATA 4 0x021b0030 0x006B1023
DATA 4 0x021b0040 0x00000047
DATA 4 0x021b0000 0x841A0000
DATA 4 0x021b001c 0x04008032
DATA 4 0x021b001c 0x00008033
DATA 4 0x021b001c 0x00048031
DATA 4 0x021b001c 0x05208030
DATA 4 0x021b001c 0x04008040
DATA 4 0x021b0020 0x00005800
DATA 4 0x021b0818 0x00011117
DATA 4 0x021b4818 0x00011117
DATA 4 0x021b0004 0x00025565
DATA 4 0x021b0404 0x00011006
DATA 4 0x021b001c 0x00000000
/* set the default clock gate to save power */
DATA 4 0x020c4068 0x00C03F3F
DATA 4 0x020c406c 0x0030FC03
DATA 4 0x020c4070 0x0FFFC000
DATA 4 0x020c4074 0x3FF00000
DATA 4 0x020c4078 0xFFFFF300
DATA 4 0x020c407c 0x0F0000C3
DATA 4 0x020c4080 0x00000FFF
/* enable AXI cache for VDOA/VPU/IPU */
DATA 4 0x020e0010 0xF00000CF
/* set IPU AXI-id0 Qos=0xf(bypass) AXI-id1 Qos=0x7 */
DATA 4 0x020e0018 0x007F007F
DATA 4 0x020e001c 0x007F007F

View File

@ -12,6 +12,7 @@
#include <asm/arch/mx6-pins.h>
#include <asm/errno.h>
#include <asm/gpio.h>
#include <asm/imx-common/mxc_i2c.h>
#include <asm/imx-common/iomux-v3.h>
#include <asm/imx-common/boot_mode.h>
#include <asm/imx-common/video.h>
@ -23,6 +24,9 @@
#include <asm/arch/crm_regs.h>
#include <asm/io.h>
#include <asm/arch/sys_proto.h>
#include <i2c.h>
#include <power/pmic.h>
#include <power/pfuze100_pmic.h>
DECLARE_GLOBAL_DATA_PTR;
#define UART_PAD_CTRL (PAD_CTL_PUS_100K_UP | \
@ -39,6 +43,14 @@ DECLARE_GLOBAL_DATA_PTR;
#define SPI_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_SPEED_MED | \
PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST)
#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)
#define I2C_PMIC 1
#define I2C_PAD MUX_PAD_CTRL(I2C_PAD_CTRL)
int dram_init(void)
{
gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
@ -129,6 +141,19 @@ iomux_v3_cfg_t const ecspi1_pads[] = {
MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
};
static struct i2c_pads_info i2c_pad_info1 = {
.scl = {
.i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | I2C_PAD,
.gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12 | I2C_PAD,
.gp = IMX_GPIO_NR(4, 12)
},
.sda = {
.i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | I2C_PAD,
.gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | I2C_PAD,
.gp = IMX_GPIO_NR(4, 13)
}
};
static void setup_spi(void)
{
imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
@ -426,6 +451,64 @@ int board_init(void)
#ifdef CONFIG_MXC_SPI
setup_spi();
#endif
setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
return 0;
}
static int pfuze_init(void)
{
struct pmic *p;
int ret;
unsigned int reg;
ret = power_pfuze100_init(I2C_PMIC);
if (ret)
return ret;
p = pmic_get("PFUZE100_PMIC");
ret = pmic_probe(p);
if (ret)
return ret;
pmic_reg_read(p, PFUZE100_DEVICEID, &reg);
printf("PMIC: PFUZE100 ID=0x%02x\n", reg);
/* Increase VGEN3 from 2.5 to 2.8V */
pmic_reg_read(p, PFUZE100_VGEN3VOL, &reg);
reg &= ~0xf;
reg |= 0xa;
pmic_reg_write(p, PFUZE100_VGEN3VOL, reg);
/* Increase VGEN5 from 2.8 to 3V */
pmic_reg_read(p, PFUZE100_VGEN5VOL, &reg);
reg &= ~0xf;
reg |= 0xc;
pmic_reg_write(p, PFUZE100_VGEN5VOL, reg);
/* Set SW1AB stanby volage to 0.975V */
pmic_reg_read(p, PFUZE100_SW1ABSTBY, &reg);
reg &= ~0x3f;
reg |= 0x1b;
pmic_reg_write(p, PFUZE100_SW1ABSTBY, reg);
/* Set SW1AB/VDDARM step ramp up time from 16us to 4us/25mV */
pmic_reg_read(p, PUZE_100_SW1ABCONF, &reg);
reg &= ~0xc0;
reg |= 0x40;
pmic_reg_write(p, PUZE_100_SW1ABCONF, reg);
/* Set SW1C standby voltage to 0.975V */
pmic_reg_read(p, PFUZE100_SW1CSTBY, &reg);
reg &= ~0x3f;
reg |= 0x1b;
pmic_reg_write(p, PFUZE100_SW1CSTBY, reg);
/* Set SW1C/VDDSOC step ramp up time from 16us to 4us/25mV */
pmic_reg_read(p, PFUZE100_SW1CCONF, &reg);
reg &= ~0xc0;
reg |= 0x40;
pmic_reg_write(p, PFUZE100_SW1CCONF, reg);
return 0;
}
@ -446,6 +529,7 @@ int board_late_init(void)
#ifdef CONFIG_CMD_BMODE
add_board_boot_modes(board_boot_modes);
#endif
pfuze_init();
return 0;
}

View File

@ -6,5 +6,6 @@
# SPDX-License-Identifier: GPL-2.0+
#
obj-y := gw_ventana.o gsc.o
obj-y := gw_ventana.o gsc.o eeprom.o
obj-$(CONFIG_SPL_BUILD) += gw_ventana_spl.o

View File

@ -3,53 +3,81 @@ U-Boot for the Gateworks Ventana Product Family boards
This file contains information for the port of U-Boot to the Gateworks
Ventana Product family boards.
1. Boot source, boot from NAND
1. Secondary Program Loader (SPL)
---------------------------------
The i.MX6 has a BOOT ROM PPL (Primary Program Loader) which supports loading
an executable image from various boot devices.
The Gateworks Ventana board config uses an SPL build configuration. This
will build the following artifacts from u-boot source:
- SPL - Secondary Program Loader that the i.MX6 BOOT ROM (Primary Program
Loader) boots. This detects CPU/DRAM configuration, configures
The DRAM controller, loads u-boot.img from the detected boot device,
and jumps to it. As this is booted from the PPL, it has an IVT/DCD
table.
- u-boot.img - The main u-boot core which is u-boot.bin with a image header.
2. Build
--------
To build U-Boot for the Gateworks Ventana product family:
make gwventana_config
make
3. Boot source, boot from NAND
------------------------------
The i.MX6 BOOT ROM expects some structures that provide details of NAND layout
and bad block information (referred to as 'bootstreams') which are replicated
multiple times in NAND. The number of replications is configurable through
board strapping options and eFUSE settings. The Freescale 'kobs-ng'
application from the Freescale LTIB BSP, which runs under Linux, must be used
to program the bootstream in order to setup the replicated headers correctly.
multiple times in NAND. The number of replications and their spacing (referred
to as search stride) is configurable through board strapping options and/or
eFUSE settings (BOOT_SEARCH_COUNT / Pages in block from BOOT_CFG2). In
addition, the i.MX6 BOOT ROM Flash Configuration Block (FCB) supports two
copies of a bootloader in flash in the case that a bad block has corrupted one.
The Freescale 'kobs-ng' application from the Freescale LTIB BSP, which runs
under Linux and operates on an MTD partition, must be used to program the
bootstream in order to setup this flash structure correctly.
The Gateworks Ventana boards with NAND flash have been factory programmed
such that their eFUSE settings expect 2 copies of the boostream (this is
specified by providing kobs-ng with the --search_exponent=1 argument). Once in
Linux with MTD support for the NAND on /dev/mtd0 you can program the boostream
Linux with MTD support for the NAND on /dev/mtd0 you can program the SPL
with:
kobs-ng init -v -x --search_exponent=1 u-boot.imx
kobs-ng init -v -x --search_exponent=1 SPL
The kobs-ng application uses an imximage (u-boot.imx) which contains the
Image Vector Table (IVT) and Device Configuration Data (DCD) structures that
the i.MX6 BOOT ROM requires to boot. The kobs-ng adds the Firmware
Configuration Block (FCB) and Discovered Bad Block Table (DBBT).
The kobs-ng application uses an imximage which contains the Image Vector Table
(IVT) and Device Configuration Data (DCD) structures that the i.MX6 BOOT ROM
requires to boot. The kobs-ng adds the Firmware Configuration Block (FCB) and
Discovered Bad Block Table (DBBT). The SPL build artifact from u-boot is
an imximage.
The u-boot.img, which is the non SPL u-boot binary appended to a u-boot image
header must be programmed in the NAND flash boot device at an offset hard
coded in the SPL. For the Ventana boards, this has been chosen to be 14MB.
The image can be programmed from either u-boot or Linux:
u-boot:
Ventana > setenv mtdparts mtdparts=nand:14m(spl),2m(uboot),1m(env),-(rootfs)
Ventana > tftp ${loadaddr} u-boot.img && nand erase.part uboot && \
nand write ${loadaddr} uboot ${filesize}
Linux:
nandwrite /dev/mtd1 u-boot.img
The above assumes the default Ventana partitioning scheme which is configured
via the mtdparts env var:
- spl: 14MB
- uboot: 2M
- env: 1M
- rootfs: the rest
This information is taken from:
http://trac.gateworks.com/wiki/ventana/bootloader#NANDFLASH
More details about the i.MX6 BOOT ROM can be found in the IMX6 reference manual.
2. Build
--------
There are several Gateworks Ventana boards that share a simliar design but
vary based on CPU, Memory configuration, and subloaded devices. Although
the subloaded devices are handled dynamically in the bootloader using
factory configured EEPROM data to modify the device-tree, the CPU choice
(IMX6Q vs IMX6DL) and memory configurations are currently compile-time
options.
The following Gateworks Ventana configurations exist:
gwventanaq1gspi: MX6Q,1GB,SPI FLASH
gwventanaq : MX6Q,512MB,NAND FLASH
gwventanaq1g : MX6Q,1GB,NAND FLASH
gwventanadl : MX6DL,512MB,NAND FLASH
gwventanadl1g : MX6DL,1GB,NAND FLASH
To build U-Boot for the MX6Q,1GB,NAND FLASH for example:
make gwventanaq1g_config
make

View File

@ -0,0 +1,89 @@
/*
* Copyright (C) 2014 Gateworks Corporation
* Author: Tim Harvey <tharvey@gateworks.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <i2c.h>
#include "gsc.h"
#include "ventana_eeprom.h"
/* read ventana EEPROM, check for validity, and return baseboard type */
int
read_eeprom(int bus, struct ventana_board_info *info)
{
int i;
int chksum;
char baseboard;
int type;
unsigned char *buf = (unsigned char *)info;
memset(info, 0, sizeof(*info));
/*
* On a board with a missing/depleted backup battery for GSC, the
* board may be ready to probe the GSC before its firmware is
* running. We will wait here indefinately for the GSC/EEPROM.
*/
while (1) {
if (0 == i2c_set_bus_num(bus) &&
0 == i2c_probe(GSC_EEPROM_ADDR))
break;
mdelay(1);
}
/* read eeprom config section */
if (gsc_i2c_read(GSC_EEPROM_ADDR, 0x00, 1, buf, sizeof(*info))) {
puts("EEPROM: Failed to read EEPROM\n");
info->model[0] = 0;
return GW_UNKNOWN;
}
/* sanity checks */
if (info->model[0] != 'G' || info->model[1] != 'W') {
puts("EEPROM: Invalid Model in EEPROM\n");
info->model[0] = 0;
return GW_UNKNOWN;
}
/* validate checksum */
for (chksum = 0, i = 0; i < sizeof(*info)-2; i++)
chksum += buf[i];
if ((info->chksum[0] != chksum>>8) ||
(info->chksum[1] != (chksum&0xff))) {
puts("EEPROM: Failed EEPROM checksum\n");
info->model[0] = 0;
return GW_UNKNOWN;
}
/* original GW5400-A prototype */
baseboard = info->model[3];
if (strncasecmp((const char *)info->model, "GW5400-A", 8) == 0)
baseboard = '0';
switch (baseboard) {
case '0': /* original GW5400-A prototype */
type = GW54proto;
break;
case '1':
type = GW51xx;
break;
case '2':
type = GW52xx;
break;
case '3':
type = GW53xx;
break;
case '4':
type = GW54xx;
break;
default:
printf("EEPROM: Unknown model in EEPROM: %s\n", info->model);
type = GW_UNKNOWN;
break;
}
return type;
}

View File

@ -84,122 +84,153 @@ DECLARE_GLOBAL_DATA_PTR;
*/
static struct ventana_board_info ventana_info;
enum {
GW54proto, /* original GW5400-A prototype */
GW51xx,
GW52xx,
GW53xx,
GW54xx,
GW_UNKNOWN,
};
int board_type;
/* UART1: Function varies per baseboard */
iomux_v3_cfg_t const uart1_pads[] = {
MX6_PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
MX6_PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
IOMUX_PADS(PAD_SD3_DAT6__UART1_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
IOMUX_PADS(PAD_SD3_DAT7__UART1_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
};
/* UART2: Serial Console */
iomux_v3_cfg_t const uart2_pads[] = {
MX6_PAD_SD4_DAT7__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
MX6_PAD_SD4_DAT4__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL),
IOMUX_PADS(PAD_SD4_DAT7__UART2_TX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
IOMUX_PADS(PAD_SD4_DAT4__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
};
#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
/* I2C1: GSC */
struct i2c_pads_info i2c_pad_info0 = {
struct i2c_pads_info mx6q_i2c_pad_info0 = {
.scl = {
.i2c_mode = MX6_PAD_EIM_D21__I2C1_SCL | PC,
.gpio_mode = MX6_PAD_EIM_D21__GPIO3_IO21 | PC,
.i2c_mode = MX6Q_PAD_EIM_D21__I2C1_SCL | PC,
.gpio_mode = MX6Q_PAD_EIM_D21__GPIO3_IO21 | PC,
.gp = IMX_GPIO_NR(3, 21)
},
.sda = {
.i2c_mode = MX6_PAD_EIM_D28__I2C1_SDA | PC,
.gpio_mode = MX6_PAD_EIM_D28__GPIO3_IO28 | PC,
.i2c_mode = MX6Q_PAD_EIM_D28__I2C1_SDA | PC,
.gpio_mode = MX6Q_PAD_EIM_D28__GPIO3_IO28 | PC,
.gp = IMX_GPIO_NR(3, 28)
}
};
struct i2c_pads_info mx6dl_i2c_pad_info0 = {
.scl = {
.i2c_mode = MX6DL_PAD_EIM_D21__I2C1_SCL | PC,
.gpio_mode = MX6DL_PAD_EIM_D21__GPIO3_IO21 | PC,
.gp = IMX_GPIO_NR(3, 21)
},
.sda = {
.i2c_mode = MX6DL_PAD_EIM_D28__I2C1_SDA | PC,
.gpio_mode = MX6DL_PAD_EIM_D28__GPIO3_IO28 | PC,
.gp = IMX_GPIO_NR(3, 28)
}
};
/* I2C2: PMIC/PCIe Switch/PCIe Clock/Mezz */
struct i2c_pads_info i2c_pad_info1 = {
struct i2c_pads_info mx6q_i2c_pad_info1 = {
.scl = {
.i2c_mode = MX6_PAD_KEY_COL3__I2C2_SCL | PC,
.gpio_mode = MX6_PAD_KEY_COL3__GPIO4_IO12 | PC,
.i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL | PC,
.gpio_mode = MX6Q_PAD_KEY_COL3__GPIO4_IO12 | PC,
.gp = IMX_GPIO_NR(4, 12)
},
.sda = {
.i2c_mode = MX6_PAD_KEY_ROW3__I2C2_SDA | PC,
.gpio_mode = MX6_PAD_KEY_ROW3__GPIO4_IO13 | PC,
.i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | PC,
.gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO4_IO13 | PC,
.gp = IMX_GPIO_NR(4, 13)
}
};
struct i2c_pads_info mx6dl_i2c_pad_info1 = {
.scl = {
.i2c_mode = MX6DL_PAD_KEY_COL3__I2C2_SCL | PC,
.gpio_mode = MX6DL_PAD_KEY_COL3__GPIO4_IO12 | PC,
.gp = IMX_GPIO_NR(4, 12)
},
.sda = {
.i2c_mode = MX6DL_PAD_KEY_ROW3__I2C2_SDA | PC,
.gpio_mode = MX6DL_PAD_KEY_ROW3__GPIO4_IO13 | PC,
.gp = IMX_GPIO_NR(4, 13)
}
};
/* I2C3: Misc/Expansion */
struct i2c_pads_info i2c_pad_info2 = {
struct i2c_pads_info mx6q_i2c_pad_info2 = {
.scl = {
.i2c_mode = MX6_PAD_GPIO_3__I2C3_SCL | PC,
.gpio_mode = MX6_PAD_GPIO_3__GPIO1_IO03 | PC,
.i2c_mode = MX6Q_PAD_GPIO_3__I2C3_SCL | PC,
.gpio_mode = MX6Q_PAD_GPIO_3__GPIO1_IO03 | PC,
.gp = IMX_GPIO_NR(1, 3)
},
.sda = {
.i2c_mode = MX6_PAD_GPIO_6__I2C3_SDA | PC,
.gpio_mode = MX6_PAD_GPIO_6__GPIO1_IO06 | PC,
.i2c_mode = MX6Q_PAD_GPIO_6__I2C3_SDA | PC,
.gpio_mode = MX6Q_PAD_GPIO_6__GPIO1_IO06 | PC,
.gp = IMX_GPIO_NR(1, 6)
}
};
struct i2c_pads_info mx6dl_i2c_pad_info2 = {
.scl = {
.i2c_mode = MX6DL_PAD_GPIO_3__I2C3_SCL | PC,
.gpio_mode = MX6DL_PAD_GPIO_3__GPIO1_IO03 | PC,
.gp = IMX_GPIO_NR(1, 3)
},
.sda = {
.i2c_mode = MX6DL_PAD_GPIO_6__I2C3_SDA | PC,
.gpio_mode = MX6DL_PAD_GPIO_6__GPIO1_IO06 | PC,
.gp = IMX_GPIO_NR(1, 6)
}
};
/* MMC */
iomux_v3_cfg_t const usdhc3_pads[] = {
MX6_PAD_SD3_CLK__SD3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD3_CMD__SD3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
MX6_PAD_SD3_DAT5__GPIO7_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
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)),
/* CD */
IOMUX_PADS(PAD_SD3_DAT5__GPIO7_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL)),
};
/* ENET */
iomux_v3_cfg_t const enet_pads[] = {
MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TXC__RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD0__RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD1__RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD2__RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TD3__RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RXC__RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD0__RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD1__RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD2__RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RD3__RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
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_TX_CTL__RGMII_TX_CTL |
MUX_PAD_CTRL(ENET_PAD_CTRL)),
IOMUX_PADS(PAD_ENET_REF_CLK__ENET_TX_CLK |
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_RGMII_RX_CTL__RGMII_RX_CTL |
MUX_PAD_CTRL(ENET_PAD_CTRL)),
/* PHY nRST */
MX6_PAD_ENET_TXD0__GPIO1_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_ENET_TXD0__GPIO1_IO30 | MUX_PAD_CTRL(NO_PAD_CTRL)),
};
/* NAND */
iomux_v3_cfg_t const nfc_pads[] = {
MX6_PAD_NANDF_CLE__NAND_CLE | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_NANDF_ALE__NAND_ALE | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_NANDF_WP_B__NAND_WP_B | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_NANDF_RB0__NAND_READY_B | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_NANDF_CS0__NAND_CE0_B | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_SD4_CMD__NAND_RE_B | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_SD4_CLK__NAND_WE_B | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_NANDF_D0__NAND_DATA00 | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_NANDF_D1__NAND_DATA01 | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_NANDF_D2__NAND_DATA02 | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_NANDF_D3__NAND_DATA03 | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_NANDF_D4__NAND_DATA04 | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_NANDF_D5__NAND_DATA05 | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_NANDF_D6__NAND_DATA06 | MUX_PAD_CTRL(NO_PAD_CTRL),
MX6_PAD_NANDF_D7__NAND_DATA07 | MUX_PAD_CTRL(NO_PAD_CTRL),
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_WP_B__NAND_WP_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_CS0__NAND_CE0_B | 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)),
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)),
};
#ifdef CONFIG_CMD_NAND
@ -208,7 +239,7 @@ static void setup_gpmi_nand(void)
struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
/* config gpmi nand iomux */
imx_iomux_v3_setup_multiple_pads(nfc_pads, ARRAY_SIZE(nfc_pads));
SETUP_IOMUX_PADS(nfc_pads);
/* config gpmi and bch clock to 100 MHz */
clrsetbits_le32(&mxc_ccm->cs2cdr,
@ -234,7 +265,7 @@ static void setup_gpmi_nand(void)
static void setup_iomux_enet(void)
{
imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
SETUP_IOMUX_PADS(enet_pads);
/* toggle PHY_RST# */
gpio_direction_output(GP_PHY_RST, 0);
@ -244,35 +275,36 @@ static void setup_iomux_enet(void)
static void setup_iomux_uart(void)
{
imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
SETUP_IOMUX_PADS(uart1_pads);
SETUP_IOMUX_PADS(uart2_pads);
}
#ifdef CONFIG_USB_EHCI_MX6
iomux_v3_cfg_t const usb_pads[] = {
MX6_PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(DIO_PAD_CTRL),
MX6_PAD_KEY_COL4__USB_OTG_OC | MUX_PAD_CTRL(DIO_PAD_CTRL),
MX6_PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(DIO_PAD_CTRL), /* OTG PWR */
IOMUX_PADS(PAD_GPIO_1__USB_OTG_ID | MUX_PAD_CTRL(DIO_PAD_CTRL)),
IOMUX_PADS(PAD_KEY_COL4__USB_OTG_OC | MUX_PAD_CTRL(DIO_PAD_CTRL)),
/* OTG PWR */
IOMUX_PADS(PAD_EIM_D22__GPIO3_IO22 | MUX_PAD_CTRL(DIO_PAD_CTRL)),
};
int board_ehci_hcd_init(int port)
{
struct ventana_board_info *info = &ventana_info;
imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads));
SETUP_IOMUX_PADS(usb_pads);
/* Reset USB HUB (present on GW54xx/GW53xx) */
switch (info->model[3]) {
case '3': /* GW53xx */
imx_iomux_v3_setup_pad(MX6_PAD_GPIO_9__GPIO1_IO09|
MUX_PAD_CTRL(NO_PAD_CTRL));
SETUP_IOMUX_PAD(PAD_GPIO_9__GPIO1_IO09 |
MUX_PAD_CTRL(NO_PAD_CTRL));
gpio_direction_output(IMX_GPIO_NR(1, 9), 0);
mdelay(2);
gpio_set_value(IMX_GPIO_NR(1, 9), 1);
break;
case '4': /* GW54xx */
imx_iomux_v3_setup_pad(MX6_PAD_SD1_DAT0__GPIO1_IO16 |
MUX_PAD_CTRL(NO_PAD_CTRL));
SETUP_IOMUX_PAD(PAD_SD1_DAT0__GPIO1_IO16 |
MUX_PAD_CTRL(NO_PAD_CTRL));
gpio_direction_output(IMX_GPIO_NR(1, 16), 0);
mdelay(2);
gpio_set_value(IMX_GPIO_NR(1, 16), 1);
@ -304,7 +336,7 @@ int board_mmc_getcd(struct mmc *mmc)
int board_mmc_init(bd_t *bis)
{
/* Only one USDHC controller on Ventana */
imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
SETUP_IOMUX_PADS(usdhc3_pads);
usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
usdhc_cfg.max_bus_width = 4;
@ -315,17 +347,16 @@ int board_mmc_init(bd_t *bis)
#ifdef CONFIG_MXC_SPI
iomux_v3_cfg_t const ecspi1_pads[] = {
/* SS1 */
MX6_PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(SPI_PAD_CTRL),
MX6_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
MX6_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
MX6_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
IOMUX_PADS(PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(SPI_PAD_CTRL)),
IOMUX_PADS(PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL)),
IOMUX_PADS(PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL)),
IOMUX_PADS(PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL)),
};
static void setup_spi(void)
{
gpio_direction_output(CONFIG_SF_DEFAULT_CS, 1);
imx_iomux_v3_setup_multiple_pads(ecspi1_pads,
ARRAY_SIZE(ecspi1_pads));
SETUP_IOMUX_PADS(ecspi1_pads);
}
#endif
@ -395,8 +426,7 @@ static void enable_lvds(struct display_info_t const *dev)
writel(reg, &iomux->gpr[2]);
/* Enable Backlight */
imx_iomux_v3_setup_pad(MX6_PAD_SD1_CMD__GPIO1_IO18 |
MUX_PAD_CTRL(NO_PAD_CTRL));
SETUP_IOMUX_PAD(PAD_SD1_CMD__GPIO1_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL));
gpio_direction_output(IMX_GPIO_NR(1, 18), 1);
}
@ -493,90 +523,11 @@ static void setup_display(void)
writel(reg, &iomux->gpr[3]);
/* Backlight CABEN on LVDS connector */
imx_iomux_v3_setup_pad(MX6_PAD_SD2_CLK__GPIO1_IO10 |
MUX_PAD_CTRL(NO_PAD_CTRL));
SETUP_IOMUX_PAD(PAD_SD2_CLK__GPIO1_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL));
gpio_direction_output(IMX_GPIO_NR(1, 10), 0);
}
#endif /* CONFIG_VIDEO_IPUV3 */
/* read ventana EEPROM, check for validity, and return baseboard type */
static int
read_eeprom(void)
{
int i;
int chksum;
char baseboard;
int type;
struct ventana_board_info *info = &ventana_info;
unsigned char *buf = (unsigned char *)&ventana_info;
memset(info, 0, sizeof(ventana_info));
/*
* On a board with a missing/depleted backup battery for GSC, the
* board may be ready to probe the GSC before its firmware is
* running. We will wait here indefinately for the GSC/EEPROM.
*/
while (1) {
if (0 == i2c_set_bus_num(I2C_GSC) &&
0 == i2c_probe(GSC_EEPROM_ADDR))
break;
mdelay(1);
}
/* read eeprom config section */
if (gsc_i2c_read(GSC_EEPROM_ADDR, 0x00, 1, buf, sizeof(ventana_info))) {
puts("EEPROM: Failed to read EEPROM\n");
info->model[0] = 0;
return GW_UNKNOWN;
}
/* sanity checks */
if (info->model[0] != 'G' || info->model[1] != 'W') {
puts("EEPROM: Invalid Model in EEPROM\n");
info->model[0] = 0;
return GW_UNKNOWN;
}
/* validate checksum */
for (chksum = 0, i = 0; i < sizeof(*info)-2; i++)
chksum += buf[i];
if ((info->chksum[0] != chksum>>8) ||
(info->chksum[1] != (chksum&0xff))) {
puts("EEPROM: Failed EEPROM checksum\n");
info->model[0] = 0;
return GW_UNKNOWN;
}
/* original GW5400-A prototype */
baseboard = info->model[3];
if (strncasecmp((const char *)info->model, "GW5400-A", 8) == 0)
baseboard = '0';
switch (baseboard) {
case '0': /* original GW5400-A prototype */
type = GW54proto;
break;
case '1':
type = GW51xx;
break;
case '2':
type = GW52xx;
break;
case '3':
type = GW53xx;
break;
case '4':
type = GW54xx;
break;
default:
printf("EEPROM: Unknown model in EEPROM: %s\n", info->model);
type = GW_UNKNOWN;
break;
}
return type;
}
/*
* Baseboard specific GPIO
*/
@ -584,118 +535,118 @@ read_eeprom(void)
/* common to add baseboards */
static iomux_v3_cfg_t const gw_gpio_pads[] = {
/* MSATA_EN */
MX6_PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_SD4_DAT0__GPIO2_IO08 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* RS232_EN# */
MX6_PAD_SD4_DAT3__GPIO2_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_SD4_DAT3__GPIO2_IO11 | MUX_PAD_CTRL(NO_PAD_CTRL)),
};
/* prototype */
static iomux_v3_cfg_t const gwproto_gpio_pads[] = {
/* PANLEDG# */
MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* PANLEDR# */
MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* LOCLED# */
MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* RS485_EN */
MX6_PAD_SD3_DAT4__GPIO7_IO01 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_SD3_DAT4__GPIO7_IO01 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* IOEXP_PWREN# */
MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* IOEXP_IRQ# */
MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* VID_EN */
MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* DIOI2C_DIS# */
MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* PCICK_SSON */
MX6_PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* PCI_RST# */
MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)),
};
static iomux_v3_cfg_t const gw51xx_gpio_pads[] = {
/* PANLEDG# */
MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* PANLEDR# */
MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* IOEXP_PWREN# */
MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* IOEXP_IRQ# */
MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* GPS_SHDN */
MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* VID_PWR */
MX6_PAD_CSI0_DATA_EN__GPIO5_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_CSI0_DATA_EN__GPIO5_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* PCI_RST# */
MX6_PAD_GPIO_0__GPIO1_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_GPIO_0__GPIO1_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL)),
};
static iomux_v3_cfg_t const gw52xx_gpio_pads[] = {
/* PANLEDG# */
MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* PANLEDR# */
MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* IOEXP_PWREN# */
MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* IOEXP_IRQ# */
MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* MX6_LOCLED# */
MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* GPS_SHDN */
MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* USBOTG_SEL */
MX6_PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_GPIO_2__GPIO1_IO02 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* VID_PWR */
MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* PCI_RST# */
MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)),
};
static iomux_v3_cfg_t const gw53xx_gpio_pads[] = {
/* PANLEDG# */
MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* PANLEDR# */
MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* IOEXP_PWREN# */
MX6_PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_EIM_A19__GPIO2_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* IOEXP_IRQ# */
MX6_PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_EIM_A20__GPIO2_IO18 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* MX6_LOCLED# */
MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* GPS_SHDN */
MX6_PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_ENET_RXD0__GPIO1_IO27 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* VID_EN */
MX6_PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_EIM_D31__GPIO3_IO31 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* PCI_RST# */
MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)),
};
static iomux_v3_cfg_t const gw54xx_gpio_pads[] = {
/* PANLEDG# */
MX6_PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_COL0__GPIO4_IO06 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* PANLEDR# */
MX6_PAD_KEY_COL2__GPIO4_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_COL2__GPIO4_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* MX6_LOCLED# */
MX6_PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_ROW4__GPIO4_IO15 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* MIPI_DIO */
MX6_PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_SD1_DAT3__GPIO1_IO21 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* RS485_EN */
MX6_PAD_EIM_D24__GPIO3_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_EIM_D24__GPIO3_IO24 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* IOEXP_PWREN# */
MX6_PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_ROW0__GPIO4_IO07 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* IOEXP_IRQ# */
MX6_PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_KEY_ROW1__GPIO4_IO09 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* DIOI2C_DIS# */
MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* DIOI2C_DIS# */
MX6_PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_GPIO_19__GPIO4_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* PCICK_SSON */
MX6_PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20 | MUX_PAD_CTRL(NO_PAD_CTRL)),
/* PCI_RST# */
MX6_PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL),
IOMUX_PADS(PAD_ENET_TXD1__GPIO1_IO29 | MUX_PAD_CTRL(NO_PAD_CTRL)),
};
/*
@ -703,9 +654,9 @@ static iomux_v3_cfg_t const gw54xx_gpio_pads[] = {
* be pinmuxed as a GPIO or in some cases a PWM
*/
struct dio_cfg {
iomux_v3_cfg_t gpio_padmux;
iomux_v3_cfg_t gpio_padmux[2];
unsigned gpio_param;
iomux_v3_cfg_t pwm_padmux;
iomux_v3_cfg_t pwm_padmux[2];
unsigned pwm_param;
};
@ -732,16 +683,32 @@ struct ventana gpio_cfg[] = {
/* GW5400proto */
{
.gpio_pads = gw54xx_gpio_pads,
.num_pads = ARRAY_SIZE(gw54xx_gpio_pads),
.num_pads = ARRAY_SIZE(gw54xx_gpio_pads)/2,
.dio_cfg = {
{ MX6_PAD_GPIO_9__GPIO1_IO09, IMX_GPIO_NR(1, 9),
MX6_PAD_GPIO_9__PWM1_OUT, 1 },
{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
{ MX6_PAD_SD4_DAT1__GPIO2_IO09, IMX_GPIO_NR(2, 9),
MX6_PAD_SD4_DAT1__PWM3_OUT, 3 },
{ MX6_PAD_SD4_DAT2__GPIO2_IO10, IMX_GPIO_NR(2, 10),
MX6_PAD_SD4_DAT2__PWM4_OUT, 4 },
{
{ IOMUX_PADS(PAD_GPIO_9__GPIO1_IO09) },
IMX_GPIO_NR(1, 9),
{ IOMUX_PADS(PAD_GPIO_9__PWM1_OUT) },
1
},
{
{ IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) },
IMX_GPIO_NR(1, 19),
{ IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) },
2
},
{
{ IOMUX_PADS(PAD_SD4_DAT1__GPIO2_IO09) },
IMX_GPIO_NR(2, 9),
{ IOMUX_PADS(PAD_SD4_DAT1__PWM3_OUT) },
3
},
{
{ IOMUX_PADS(PAD_SD4_DAT2__GPIO2_IO10) },
IMX_GPIO_NR(2, 10),
{ IOMUX_PADS(PAD_SD4_DAT2__PWM4_OUT) },
4
},
},
.leds = {
IMX_GPIO_NR(4, 6),
@ -759,16 +726,32 @@ struct ventana gpio_cfg[] = {
/* GW51xx */
{
.gpio_pads = gw51xx_gpio_pads,
.num_pads = ARRAY_SIZE(gw51xx_gpio_pads),
.num_pads = ARRAY_SIZE(gw51xx_gpio_pads)/2,
.dio_cfg = {
{ MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
0, 0 },
{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
{ MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
{ MX6_PAD_SD1_CMD__GPIO1_IO18, IMX_GPIO_NR(1, 18),
MX6_PAD_SD1_CMD__PWM4_OUT, 4 },
{
{ IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) },
IMX_GPIO_NR(1, 16),
{ 0, 0 },
0
},
{
{ IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) },
IMX_GPIO_NR(1, 19),
{ IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) },
2
},
{
{ IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) },
IMX_GPIO_NR(1, 17),
{ IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) },
3
},
{
{ IOMUX_PADS(PAD_SD1_CMD__GPIO1_IO18) },
IMX_GPIO_NR(1, 18),
{ IOMUX_PADS(PAD_SD1_CMD__PWM4_OUT) },
4
},
},
.leds = {
IMX_GPIO_NR(4, 6),
@ -784,16 +767,32 @@ struct ventana gpio_cfg[] = {
/* GW52xx */
{
.gpio_pads = gw52xx_gpio_pads,
.num_pads = ARRAY_SIZE(gw52xx_gpio_pads),
.num_pads = ARRAY_SIZE(gw52xx_gpio_pads)/2,
.dio_cfg = {
{ MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
0, 0 },
{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
{ MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
{ MX6_PAD_SD1_CLK__GPIO1_IO20, IMX_GPIO_NR(1, 20),
0, 0 },
{
{ IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) },
IMX_GPIO_NR(1, 16),
{ 0, 0 },
0
},
{
{ IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) },
IMX_GPIO_NR(1, 19),
{ IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) },
2
},
{
{ IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) },
IMX_GPIO_NR(1, 17),
{ IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) },
3
},
{
{ IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20) },
IMX_GPIO_NR(1, 20),
{ 0, 0 },
0
},
},
.leds = {
IMX_GPIO_NR(4, 6),
@ -811,16 +810,32 @@ struct ventana gpio_cfg[] = {
/* GW53xx */
{
.gpio_pads = gw53xx_gpio_pads,
.num_pads = ARRAY_SIZE(gw53xx_gpio_pads),
.num_pads = ARRAY_SIZE(gw53xx_gpio_pads)/2,
.dio_cfg = {
{ MX6_PAD_SD1_DAT0__GPIO1_IO16, IMX_GPIO_NR(1, 16),
0, 0 },
{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
{ MX6_PAD_SD1_DAT1__GPIO1_IO17, IMX_GPIO_NR(1, 17),
MX6_PAD_SD1_DAT1__PWM3_OUT, 3 },
{ MX6_PAD_SD1_CLK__GPIO1_IO20, IMX_GPIO_NR(1, 20),
0, 0 },
{
{ IOMUX_PADS(PAD_SD1_DAT0__GPIO1_IO16) },
IMX_GPIO_NR(1, 16),
{ 0, 0 },
0
},
{
{ IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) },
IMX_GPIO_NR(1, 19),
{ IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) },
2
},
{
{ IOMUX_PADS(PAD_SD1_DAT1__GPIO1_IO17) },
IMX_GPIO_NR(1, 17),
{ IOMUX_PADS(PAD_SD1_DAT1__PWM3_OUT) },
3
},
{
{IOMUX_PADS(PAD_SD1_CLK__GPIO1_IO20) },
IMX_GPIO_NR(1, 20),
{ 0, 0 },
0
},
},
.leds = {
IMX_GPIO_NR(4, 6),
@ -837,16 +852,32 @@ struct ventana gpio_cfg[] = {
/* GW54xx */
{
.gpio_pads = gw54xx_gpio_pads,
.num_pads = ARRAY_SIZE(gw54xx_gpio_pads),
.num_pads = ARRAY_SIZE(gw54xx_gpio_pads)/2,
.dio_cfg = {
{ MX6_PAD_GPIO_9__GPIO1_IO09, IMX_GPIO_NR(1, 9),
MX6_PAD_GPIO_9__PWM1_OUT, 1 },
{ MX6_PAD_SD1_DAT2__GPIO1_IO19, IMX_GPIO_NR(1, 19),
MX6_PAD_SD1_DAT2__PWM2_OUT, 2 },
{ MX6_PAD_SD4_DAT1__GPIO2_IO09, IMX_GPIO_NR(2, 9),
MX6_PAD_SD4_DAT1__PWM3_OUT, 3 },
{ MX6_PAD_SD4_DAT2__GPIO2_IO10, IMX_GPIO_NR(2, 10),
MX6_PAD_SD4_DAT2__PWM4_OUT, 4 },
{
{ IOMUX_PADS(PAD_GPIO_9__GPIO1_IO09) },
IMX_GPIO_NR(1, 9),
{ IOMUX_PADS(PAD_GPIO_9__PWM1_OUT) },
1
},
{
{ IOMUX_PADS(PAD_SD1_DAT2__GPIO1_IO19) },
IMX_GPIO_NR(1, 19),
{ IOMUX_PADS(PAD_SD1_DAT2__PWM2_OUT) },
2
},
{
{ IOMUX_PADS(PAD_SD4_DAT1__GPIO2_IO09) },
IMX_GPIO_NR(2, 9),
{ IOMUX_PADS(PAD_SD4_DAT1__PWM3_OUT) },
3
},
{
{ IOMUX_PADS(PAD_SD4_DAT2__GPIO2_IO10) },
IMX_GPIO_NR(2, 10),
{ IOMUX_PADS(PAD_SD4_DAT2__PWM4_OUT) },
4
},
},
.leds = {
IMX_GPIO_NR(4, 6),
@ -992,6 +1023,7 @@ static void setup_board_gpio(int board)
for (i = 0; i < 4; i++) {
struct dio_cfg *cfg = &gpio_cfg[board].dio_cfg[i];
unsigned ctrl = DIO_PAD_CTRL;
unsigned cputype = is_cpu_type(MXC_CPU_MX6Q) ? 0 : 1;
sprintf(arg, "dio%d", i);
if (!hwconfig(arg))
@ -1006,14 +1038,14 @@ static void setup_board_gpio(int board)
cfg->gpio_param%32,
cfg->gpio_param);
}
imx_iomux_v3_setup_pad(cfg->gpio_padmux |
imx_iomux_v3_setup_pad(cfg->gpio_padmux[cputype] |
MUX_PAD_CTRL(ctrl));
gpio_direction_input(cfg->gpio_param);
} else if (hwconfig_subarg_cmp("dio2", "mode", "pwm") &&
cfg->pwm_padmux) {
if (!quiet)
printf("DIO%d: pwm%d\n", i, cfg->pwm_param);
imx_iomux_v3_setup_pad(cfg->pwm_padmux |
imx_iomux_v3_setup_pad(cfg->pwm_padmux[cputype] |
MUX_PAD_CTRL(ctrl));
}
}
@ -1033,9 +1065,10 @@ static void setup_board_gpio(int board)
int imx6_pcie_toggle_reset(void)
{
if (board_type < GW_UNKNOWN) {
gpio_direction_output(gpio_cfg[board_type].pcie_rst, 0);
uint pin = gpio_cfg[board_type].pcie_rst;
gpio_direction_output(pin, 0);
mdelay(50);
gpio_direction_output(gpio_cfg[board_type].pcie_rst, 1);
gpio_direction_output(pin, 1);
}
return 0;
}
@ -1069,6 +1102,7 @@ void get_board_serial(struct tag_serialnr *serialnr)
* Board Support
*/
/* called from SPL board_init_f() */
int board_early_init_f(void)
{
setup_iomux_uart();
@ -1082,9 +1116,7 @@ int board_early_init_f(void)
int dram_init(void)
{
gd->ram_size = get_ram_size((void *)PHYS_SDRAM,
CONFIG_DDR_MB*1024*1024);
gd->ram_size = imx_ddr_size();
return 0;
}
@ -1106,22 +1138,29 @@ int board_init(void)
#ifdef CONFIG_MXC_SPI
setup_spi();
#endif
setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0);
setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
if (is_cpu_type(MXC_CPU_MX6Q)) {
setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info0);
setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info1);
setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info2);
} else {
setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info0);
setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info1);
setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info2);
}
#ifdef CONFIG_CMD_SATA
setup_sata();
#endif
/* read Gateworks EEPROM into global struct (used later) */
board_type = read_eeprom();
board_type = read_eeprom(I2C_GSC, &ventana_info);
/* board-specifc GPIO iomux */
SETUP_IOMUX_PADS(gw_gpio_pads);
if (board_type < GW_UNKNOWN) {
imx_iomux_v3_setup_multiple_pads(gw_gpio_pads,
ARRAY_SIZE(gw_gpio_pads));
imx_iomux_v3_setup_multiple_pads(gpio_cfg[board_type].gpio_pads,
gpio_cfg[board_type].num_pads);
iomux_v3_cfg_t const *p = gpio_cfg[board_type].gpio_pads;
int count = gpio_cfg[board_type].num_pads;
imx_iomux_v3_setup_multiple_pads(p, count);
}
return 0;
@ -1219,9 +1258,11 @@ int misc_init_r(void)
* env scripts will try loading each from most specific to
* least.
*/
if (is_cpu_type(MXC_CPU_MX6Q))
if (is_cpu_type(MXC_CPU_MX6Q) ||
is_cpu_type(MXC_CPU_MX6D))
cputype = "imx6q";
else if (is_cpu_type(MXC_CPU_MX6DL))
else if (is_cpu_type(MXC_CPU_MX6DL) ||
is_cpu_type(MXC_CPU_MX6SOLO))
cputype = "imx6dl";
memset(str, 0, sizeof(str));
for (i = 0; i < (sizeof(str)-1) && info->model[i]; i++)

View File

@ -24,21 +24,6 @@ BOOT_FROM nand
#define __ASSEMBLY__
#include <config.h>
#include "asm/arch/mx6-ddr.h"
#include "asm/arch/iomux.h"
#include "asm/arch/crm_regs.h"
/* Memory configuration (size is overridden via eeprom config) */
#include "../../boundary/nitrogen6x/ddr-setup.cfg"
#if defined(CONFIG_MX6Q) && CONFIG_DDR_MB == 1024
#include "../../boundary/nitrogen6x/1066mhz_4x128mx16.cfg"
#elif defined(CONFIG_MX6DL) && CONFIG_DDR_MB == 1024
#include "../../boundary/nitrogen6x/800mhz_4x128mx16.cfg"
#elif defined(CONFIG_MX6DL) && CONFIG_DDR_MB == 512
#include "../../boundary/nitrogen6x/800mhz_2x128mx16.cfg"
#elif defined(CONFIG_MX6Q) && CONFIG_DDR_MB == 512
#include "../../boundary/nitrogen6x/800mhz_2x128mx16.cfg"
#else
#error "Unsupported CPU/Memory configuration"
#endif
#include "clocks.cfg"

View File

@ -0,0 +1,419 @@
/*
* Copyright (C) 2014 Gateworks Corporation
* Author: Tim Harvey <tharvey@gateworks.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <i2c.h>
#include <asm/io.h>
#include <asm/arch/iomux.h>
#include <asm/arch/mx6-ddr.h>
#include <asm/arch/mx6-pins.h>
#include <asm/arch/sys_proto.h>
#include <asm/imx-common/boot_mode.h>
#include <asm/imx-common/iomux-v3.h>
#include <asm/imx-common/mxc_i2c.h>
#include <spl.h>
#include "ventana_eeprom.h"
DECLARE_GLOBAL_DATA_PTR;
#define RTT_NOM_120OHM /* use 120ohm Rtt_nom vs 60ohm (lower power) */
#define I2C_GSC 0
#define GSC_EEPROM_ADDR 0x51
#define GSC_EEPROM_DDR_SIZE 0x2B /* enum (512,1024,2048) MB */
#define GSC_EEPROM_DDR_WIDTH 0x2D /* enum (32,64) bit */
#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)
#define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
#define CONFIG_SYS_I2C_SPEED 100000
/* I2C1: GSC */
static struct i2c_pads_info mx6q_i2c_pad_info0 = {
.scl = {
.i2c_mode = MX6Q_PAD_EIM_D21__I2C1_SCL | PC,
.gpio_mode = MX6Q_PAD_EIM_D21__GPIO3_IO21 | PC,
.gp = IMX_GPIO_NR(3, 21)
},
.sda = {
.i2c_mode = MX6Q_PAD_EIM_D28__I2C1_SDA | PC,
.gpio_mode = MX6Q_PAD_EIM_D28__GPIO3_IO28 | PC,
.gp = IMX_GPIO_NR(3, 28)
}
};
static struct i2c_pads_info mx6dl_i2c_pad_info0 = {
.scl = {
.i2c_mode = MX6DL_PAD_EIM_D21__I2C1_SCL | PC,
.gpio_mode = MX6DL_PAD_EIM_D21__GPIO3_IO21 | PC,
.gp = IMX_GPIO_NR(3, 21)
},
.sda = {
.i2c_mode = MX6DL_PAD_EIM_D28__I2C1_SDA | PC,
.gpio_mode = MX6DL_PAD_EIM_D28__GPIO3_IO28 | PC,
.gp = IMX_GPIO_NR(3, 28)
}
};
static void i2c_setup_iomux(void)
{
if (is_cpu_type(MXC_CPU_MX6Q))
setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6q_i2c_pad_info0);
else
setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &mx6dl_i2c_pad_info0);
}
/* configure MX6Q/DUAL mmdc DDR io registers */
struct mx6dq_iomux_ddr_regs mx6dq_ddr_ioregs = {
/* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */
.dram_sdclk_0 = 0x00020030,
.dram_sdclk_1 = 0x00020030,
.dram_cas = 0x00020030,
.dram_ras = 0x00020030,
.dram_reset = 0x00020030,
/* SDCKE[0:1]: 100k pull-up */
.dram_sdcke0 = 0x00003000,
.dram_sdcke1 = 0x00003000,
/* SDBA2: pull-up disabled */
.dram_sdba2 = 0x00000000,
/* SDODT[0:1]: 100k pull-up, 40 ohm */
.dram_sdodt0 = 0x00003030,
.dram_sdodt1 = 0x00003030,
/* SDQS[0:7]: Differential input, 40 ohm */
.dram_sdqs0 = 0x00000030,
.dram_sdqs1 = 0x00000030,
.dram_sdqs2 = 0x00000030,
.dram_sdqs3 = 0x00000030,
.dram_sdqs4 = 0x00000030,
.dram_sdqs5 = 0x00000030,
.dram_sdqs6 = 0x00000030,
.dram_sdqs7 = 0x00000030,
/* DQM[0:7]: Differential input, 40 ohm */
.dram_dqm0 = 0x00020030,
.dram_dqm1 = 0x00020030,
.dram_dqm2 = 0x00020030,
.dram_dqm3 = 0x00020030,
.dram_dqm4 = 0x00020030,
.dram_dqm5 = 0x00020030,
.dram_dqm6 = 0x00020030,
.dram_dqm7 = 0x00020030,
};
/* configure MX6Q/DUAL mmdc GRP io registers */
struct mx6dq_iomux_grp_regs mx6dq_grp_ioregs = {
/* DDR3 */
.grp_ddr_type = 0x000c0000,
.grp_ddrmode_ctl = 0x00020000,
/* disable DDR pullups */
.grp_ddrpke = 0x00000000,
/* ADDR[00:16], SDBA[0:1]: 40 ohm */
.grp_addds = 0x00000030,
/* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */
.grp_ctlds = 0x00000030,
/* DATA[00:63]: Differential input, 40 ohm */
.grp_ddrmode = 0x00020000,
.grp_b0ds = 0x00000030,
.grp_b1ds = 0x00000030,
.grp_b2ds = 0x00000030,
.grp_b3ds = 0x00000030,
.grp_b4ds = 0x00000030,
.grp_b5ds = 0x00000030,
.grp_b6ds = 0x00000030,
.grp_b7ds = 0x00000030,
};
/* configure MX6SOLO/DUALLITE mmdc DDR io registers */
struct mx6sdl_iomux_ddr_regs mx6sdl_ddr_ioregs = {
/* SDCLK[0:1], CAS, RAS, Reset: Differential input, 40ohm */
.dram_sdclk_0 = 0x00020030,
.dram_sdclk_1 = 0x00020030,
.dram_cas = 0x00020030,
.dram_ras = 0x00020030,
.dram_reset = 0x00020030,
/* SDCKE[0:1]: 100k pull-up */
.dram_sdcke0 = 0x00003000,
.dram_sdcke1 = 0x00003000,
/* SDBA2: pull-up disabled */
.dram_sdba2 = 0x00000000,
/* SDODT[0:1]: 100k pull-up, 40 ohm */
.dram_sdodt0 = 0x00003030,
.dram_sdodt1 = 0x00003030,
/* SDQS[0:7]: Differential input, 40 ohm */
.dram_sdqs0 = 0x00000030,
.dram_sdqs1 = 0x00000030,
.dram_sdqs2 = 0x00000030,
.dram_sdqs3 = 0x00000030,
.dram_sdqs4 = 0x00000030,
.dram_sdqs5 = 0x00000030,
.dram_sdqs6 = 0x00000030,
.dram_sdqs7 = 0x00000030,
/* DQM[0:7]: Differential input, 40 ohm */
.dram_dqm0 = 0x00020030,
.dram_dqm1 = 0x00020030,
.dram_dqm2 = 0x00020030,
.dram_dqm3 = 0x00020030,
.dram_dqm4 = 0x00020030,
.dram_dqm5 = 0x00020030,
.dram_dqm6 = 0x00020030,
.dram_dqm7 = 0x00020030,
};
/* configure MX6SOLO/DUALLITE mmdc GRP io registers */
struct mx6sdl_iomux_grp_regs mx6sdl_grp_ioregs = {
/* DDR3 */
.grp_ddr_type = 0x000c0000,
/* SDQS[0:7]: Differential input, 40 ohm */
.grp_ddrmode_ctl = 0x00020000,
/* disable DDR pullups */
.grp_ddrpke = 0x00000000,
/* ADDR[00:16], SDBA[0:1]: 40 ohm */
.grp_addds = 0x00000030,
/* CS0/CS1/SDBA2/CKE0/CKE1/SDWE: 40 ohm */
.grp_ctlds = 0x00000030,
/* DATA[00:63]: Differential input, 40 ohm */
.grp_ddrmode = 0x00020000,
.grp_b0ds = 0x00000030,
.grp_b1ds = 0x00000030,
.grp_b2ds = 0x00000030,
.grp_b3ds = 0x00000030,
.grp_b4ds = 0x00000030,
.grp_b5ds = 0x00000030,
.grp_b6ds = 0x00000030,
.grp_b7ds = 0x00000030,
};
/* MT41K128M16JT-125 */
static struct mx6_ddr3_cfg mt41k128m16jt_125 = {
.mem_speed = 1600,
.density = 2,
.width = 16,
.banks = 8,
.rowaddr = 14,
.coladdr = 10,
.pagesz = 2,
.trcd = 1375,
.trcmin = 4875,
.trasmin = 3500,
};
/* GW54xx specific calibration */
static struct mx6_mmdc_calibration gw54xxq_mmdc_calib = {
/* write leveling calibration determine */
.p0_mpwldectrl0 = 0x00190018,
.p0_mpwldectrl1 = 0x0021001D,
.p1_mpwldectrl0 = 0x00160027,
.p1_mpwldectrl1 = 0x0012001E,
/* Read DQS Gating calibration */
.p0_mpdgctrl0 = 0x43370346,
.p0_mpdgctrl1 = 0x032A0321,
.p1_mpdgctrl0 = 0x433A034D,
.p1_mpdgctrl1 = 0x032F0235,
/* Read Calibration: DQS delay relative to DQ read access */
.p0_mprddlctl = 0x3C313539,
.p1_mprddlctl = 0x37333140,
/* Write Calibration: DQ/DM delay relative to DQS write access */
.p0_mpwrdlctl = 0x37393C38,
.p1_mpwrdlctl = 0x42334538,
};
/* GW53xx specific calibration */
static struct mx6_mmdc_calibration gw53xxq_mmdc_calib = {
/* write leveling calibration determine */
.p0_mpwldectrl0 = 0x00160013,
.p0_mpwldectrl1 = 0x00090024,
.p1_mpwldectrl0 = 0x001F0018,
.p1_mpwldectrl1 = 0x000C001C,
/* Read DQS Gating calibration */
.p0_mpdgctrl0 = 0x433A034C,
.p0_mpdgctrl1 = 0x0336032F,
.p1_mpdgctrl0 = 0x4343034A,
.p1_mpdgctrl1 = 0x03370222,
/* Read Calibration: DQS delay relative to DQ read access */
.p0_mprddlctl = 0x3F343638,
.p1_mprddlctl = 0x38373442,
/* Write Calibration: DQ/DM delay relative to DQS write access */
.p0_mpwrdlctl = 0x343A3E39,
.p1_mpwrdlctl = 0x44344239,
};
static struct mx6_mmdc_calibration gw53xxdl_mmdc_calib = {
/* write leveling calibration determine */
.p0_mpwldectrl0 = 0x003C003C,
.p0_mpwldectrl1 = 0x00330038,
.p1_mpwldectrl0 = 0x001F002A,
.p1_mpwldectrl1 = 0x0022003F,
/* Read DQS Gating calibration */
.p0_mpdgctrl0 = 0x42410244,
.p0_mpdgctrl1 = 0x022D022D,
.p1_mpdgctrl0 = 0x4234023A,
.p1_mpdgctrl1 = 0x021C0228,
/* Read Calibration: DQS delay relative to DQ read access */
.p0_mprddlctl = 0x484A4C4B,
.p1_mprddlctl = 0x4B4D4E4B,
/* Write Calibration: DQ/DM delay relative to DQS write access */
.p0_mpwrdlctl = 0x33342B32,
.p1_mpwrdlctl = 0x3933332B,
};
/* GW52xx specific calibration */
static struct mx6_mmdc_calibration gw52xxdl_mmdc_calib = {
/* write leveling calibration determine */
.p0_mpwldectrl0 = 0x0040003F,
.p0_mpwldectrl1 = 0x00370037,
/* Read DQS Gating calibration */
.p0_mpdgctrl0 = 0x42420244,
.p0_mpdgctrl1 = 0x022F022F,
/* Read Calibration: DQS delay relative to DQ read access */
.p0_mprddlctl = 0x49464B4A,
/* Write Calibration: DQ/DM delay relative to DQS write access */
.p0_mpwrdlctl = 0x32362C32,
};
/* GW51xx specific calibration */
static struct mx6_mmdc_calibration gw51xxq_mmdc_calib = {
/* write leveling calibration determine */
.p0_mpwldectrl0 = 0x00150016,
.p0_mpwldectrl1 = 0x001F0017,
/* Read DQS Gating calibration */
.p0_mpdgctrl0 = 0x433D034D,
.p0_mpdgctrl1 = 0x033D032F,
/* Read Calibration: DQS delay relative to DQ read access */
.p0_mprddlctl = 0x3F313639,
/* Write Calibration: DQ/DM delay relative to DQS write access */
.p0_mpwrdlctl = 0x33393F36,
};
static struct mx6_mmdc_calibration gw51xxdl_mmdc_calib = {
/* write leveling calibration determine */
.p0_mpwldectrl0 = 0x003D003F,
.p0_mpwldectrl1 = 0x002F0038,
/* Read DQS Gating calibration */
.p0_mpdgctrl0 = 0x423A023A,
.p0_mpdgctrl1 = 0x022A0228,
/* Read Calibration: DQS delay relative to DQ read access */
.p0_mprddlctl = 0x48494C4C,
/* Write Calibration: DQ/DM delay relative to DQS write access */
.p0_mpwrdlctl = 0x34352D31,
};
static void spl_dram_init(int width, int size, int board_model)
{
struct mx6_ddr3_cfg *mem = &mt41k128m16jt_125;
struct mx6_mmdc_calibration *calib;
struct mx6_ddr_sysinfo sysinfo = {
/* width of data bus:0=16,1=32,2=64 */
.dsize = width/32,
/* config for full 4GB range so that get_mem_size() works */
.cs_density = 32, /* 32Gb per CS */
/* single chip select */
.ncs = 1,
.cs1_mirror = 0,
.rtt_wr = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Wr = RZQ/4 */
#ifdef RTT_NOM_120OHM
.rtt_nom = 2 /*DDR3_RTT_120_OHM*/, /* RTT_Nom = RZQ/2 */
#else
.rtt_nom = 1 /*DDR3_RTT_60_OHM*/, /* RTT_Nom = RZQ/4 */
#endif
.walat = 1, /* Write additional latency */
.ralat = 5, /* Read additional latency */
.mif3_mode = 3, /* Command prediction working mode */
.bi_on = 1, /* Bank interleaving enabled */
.sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */
.rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */
};
/*
* MMDC Calibration requires the following data:
* mx6_mmdc_calibration - board-specific calibration (routing delays)
* mx6_ddr_sysinfo - board-specific memory architecture (width/cs/etc)
* mx6_ddr_cfg - chip specific timing/layout details
*/
switch (board_model) {
default:
case GW51xx:
if (is_cpu_type(MXC_CPU_MX6Q))
calib = &gw51xxq_mmdc_calib;
else
calib = &gw51xxdl_mmdc_calib;
break;
case GW52xx:
calib = &gw52xxdl_mmdc_calib;
break;
case GW53xx:
if (is_cpu_type(MXC_CPU_MX6Q))
calib = &gw53xxq_mmdc_calib;
else
calib = &gw53xxdl_mmdc_calib;
break;
case GW54xx:
calib = &gw54xxq_mmdc_calib;
break;
}
if (is_cpu_type(MXC_CPU_MX6Q))
mx6dq_dram_iocfg(width, &mx6dq_ddr_ioregs,
&mx6dq_grp_ioregs);
else
mx6sdl_dram_iocfg(width, &mx6sdl_ddr_ioregs,
&mx6sdl_grp_ioregs);
mx6_dram_cfg(&sysinfo, calib, mem);
}
/*
* called from C runtime startup code (arch/arm/lib/crt0.S:_main)
* - we have a stack and a place to store GD, both in SRAM
* - no variable global data is available
*/
void board_init_f(ulong dummy)
{
struct ventana_board_info ventana_info;
int board_model;
/*
* Zero out global data:
* - this shoudl be done by crt0.S
* - failure to zero it will cause i2c_setup to fail
*/
memset((void *)gd, 0, sizeof(struct global_data));
/* setup AIPS and disable watchdog */
arch_cpu_init();
/* iomux and setup of i2c */
board_early_init_f();
i2c_setup_iomux();
/* setup GP timer */
timer_init();
/* UART clocks enabled and gd valid - init serial console */
preloader_console_init();
/* read/validate EEPROM info to determine board model and SDRAM cfg */
board_model = read_eeprom(I2C_GSC, &ventana_info);
/* provide some some default: 32bit 128MB */
if (GW_UNKNOWN == board_model) {
ventana_info.sdram_width = 2;
ventana_info.sdram_size = 3;
}
/* configure MMDC for SDRAM width/size and per-model calibration */
spl_dram_init(8 << ventana_info.sdram_width,
16 << ventana_info.sdram_size,
board_model);
/* Clear the BSS. */
memset(__bss_start, 0, __bss_end - __bss_start);
/* load/boot image from boot device */
board_init_r(NULL, 0);
}
void reset_cpu(ulong addr)
{
}

View File

@ -103,4 +103,15 @@ enum {
EECONFIG_RES15,
};
enum {
GW54proto, /* original GW5400-A prototype */
GW51xx,
GW52xx,
GW53xx,
GW54xx,
GW_UNKNOWN,
};
int read_eeprom(int bus, struct ventana_board_info *);
#endif

View File

@ -209,6 +209,7 @@ Active arm arm926ejs mxs freescale mx23evk
Active arm arm926ejs mxs freescale mx28evk mx28evk mx28evk:ENV_IS_IN_MMC Fabio Estevam <fabio.estevam@freescale.com>
Active arm arm926ejs mxs freescale mx28evk mx28evk_auart_console mx28evk:MXS_AUART,MXS_AUART_BASE=MXS_UARTAPP3_BASE,ENV_IS_IN_MMC Fabio Estevam <fabio.estevam@freescale.com>
Active arm arm926ejs mxs freescale mx28evk mx28evk_nand mx28evk:ENV_IS_IN_NAND Fabio Estevam <fabio.estevam@freescale.com>
Active arm arm926ejs mxs freescale mx28evk mx28evk_spi mx28evk:ENV_IS_IN_SPI_FLASH Fabio Estevam <fabio.estevam@freescale.com>
Active arm arm926ejs mxs olimex mx23_olinuxino mx23_olinuxino - Marek Vasut <marek.vasut@gmail.com>
Active arm arm926ejs mxs ppcag bg0900 bg0900 - Marek Vasut <marex@denx.de>
Active arm arm926ejs mxs sandisk sansa_fuze_plus sansa_fuze_plus - Marek Vasut <marek.vasut@gmail.com>
@ -320,14 +321,11 @@ Active arm armv7 mx6 embest mx6boards
Active arm armv7 mx6 embest mx6boards riotboard embestmx6boards:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6s1g.cfg,MX6S,DDR_MB=1024,ENV_IS_IN_MMC Eric Bénard <eric@eukrea.com>
Active arm armv7 mx6 freescale mx6qarm2 mx6qarm2 mx6qarm2:IMX_CONFIG=board/freescale/mx6qarm2/imximage.cfg Jason Liu <r64343@freescale.com>
Active arm armv7 mx6 freescale mx6qsabreauto mx6qsabreauto mx6qsabreauto:IMX_CONFIG=board/freescale/mx6qsabreauto/imximage.cfg,MX6Q Fabio Estevam <fabio.estevam@freescale.com>
Active arm armv7 mx6 freescale mx6qsabreauto mx6dlsabreauto mx6qsabreauto:IMX_CONFIG=board/freescale/mx6qsabreauto/mx6dl.cfg,MX6DL Fabio Estevam <fabio.estevam@freescale.com>
Active arm armv7 mx6 freescale mx6sabresd mx6dlsabresd mx6sabresd:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL Fabio Estevam <fabio.estevam@freescale.com>
Active arm armv7 mx6 freescale mx6sabresd mx6qsabresd mx6sabresd:IMX_CONFIG=board/freescale/imx/ddr/mx6q_4x_mt41j128.cfg,MX6Q Fabio Estevam <fabio.estevam@freescale.com>
Active arm armv7 mx6 freescale mx6slevk mx6slevk mx6slevk:IMX_CONFIG=board/freescale/mx6slevk/imximage.cfg,MX6SL Fabio Estevam <fabio.estevam@freescale.com>
Active arm armv7 mx6 gateworks gw_ventana gwventanadl gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6DL,DDR_MB=512 Tim Harvey <tharvey@gateworks.com>
Active arm armv7 mx6 gateworks gw_ventana gwventanadl1g gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6DL,DDR_MB=1024 Tim Harvey <tharvey@gateworks.com>
Active arm armv7 mx6 gateworks gw_ventana gwventanaq gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=512 Tim Harvey <tharvey@gateworks.com>
Active arm armv7 mx6 gateworks gw_ventana gwventanaq1g gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=1024 Tim Harvey <tharvey@gateworks.com>
Active arm armv7 mx6 gateworks gw_ventana gwventanaq1gspi gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6Q,DDR_MB=1024,SPI_FLASH Tim Harvey <tharvey@gateworks.com>
Active arm armv7 mx6 gateworks gw_ventana gwventana gw_ventana:IMX_CONFIG=board/gateworks/gw_ventana/gw_ventana.cfg,MX6QDL,SPL Tim Harvey <tharvey@gateworks.com>
Active arm armv7 mx6 solidrun hummingboard hummingboard_solo hummingboard:IMX_CONFIG=board/solidrun/hummingboard/solo.cfg,MX6S,DDR_MB=512 Jon Nettleton <jon.nettleton@gmail.com>
Active arm armv7 omap3 - overo omap3_overo - Steve Sakoman <sakoman@gmail.com>
Active arm armv7 omap3 - pandora omap3_pandora - Grazvydas Ignotas <notasas@gmail.com>

View File

@ -23,6 +23,7 @@ Contents
2) Compiling U-Boot for a MXS based board
3) Installation of U-Boot for a MXS based board to SD card
4) Installation of U-Boot into NAND flash on a MX28 based board
5) Installation of U-boot into SPI NOR flash on a MX28 based board
1) Prerequisites
----------------
@ -262,3 +263,28 @@ There are two possibilities when preparing an image writable to NAND flash.
In case the user needs to boot a firmware image bigger than 1Mb, the
user has to adjust the "update_nand_firmware_maxsz" variable for the
update scripts to work properly.
5) Installation of U-Boot into SPI NOR flash on a MX28 based board
------------------------------------------------------------------
The u-boot.sb file can be directly written to SPI NOR from U-boot prompt.
Load u-boot.sb into RAM, this can be done in several ways and one way is to use
tftp:
=> tftp u-boot.sb 0x42000000
Probe the SPI NOR flash:
=> sf probe
(SPI NOR should be succesfully detected in this step)
Erase the blocks where U-boot binary will be written to:
=> sf erase 0x0 0x80000
Write u-boot.sb to SPI NOR:
=> sf write 0x42000000 0 0x80000
Power off the board and set the boot mode DIP switches to boot from the SPI NOR
according to MX28 manual section 12.2.1 (Table 12-2)
Last step is to power up the board and U-boot should start from SPI NOR.

View File

@ -17,6 +17,7 @@
#include <asm/io.h>
#include <linux/bitops.h>
#include <asm/arch/clock.h>
#include <asm/arch/sys_proto.h>
#include "dwc_ahsata.h"
struct sata_port_regs {
@ -558,6 +559,10 @@ int init_sata(int dev)
u32 linkmap;
struct ahci_probe_ent *probe_ent = NULL;
#if defined(CONFIG_MX6)
if (!is_cpu_type(MXC_CPU_MX6Q) && !is_cpu_type(MXC_CPU_MX6D))
return 1;
#endif
if (dev < 0 || dev > (CONFIG_SYS_SATA_MAX_DEVICE - 1)) {
printf("The sata index %d is out of ranges\n\r", dev);
return -1;

View File

@ -68,5 +68,6 @@ else # minimal SPL drivers
obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o
obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o
obj-$(CONFIG_NAND_MXC) += mxc_nand_spl.o
obj-$(CONFIG_NAND_MXS) += mxs_nand_spl.o mxs_nand.o
endif # drivers

View File

@ -0,0 +1,231 @@
/*
* Copyright (C) 2014 Gateworks Corporation
* Author: Tim Harvey <tharvey@gateworks.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <nand.h>
#include <malloc.h>
static nand_info_t mtd;
static struct nand_chip nand_chip;
static void mxs_nand_command(struct mtd_info *mtd, unsigned int command,
int column, int page_addr)
{
register struct nand_chip *chip = mtd->priv;
u32 timeo, time_start;
/* write out the command to the device */
chip->cmd_ctrl(mtd, command, NAND_CLE);
/* Serially input address */
if (column != -1) {
chip->cmd_ctrl(mtd, column, NAND_ALE);
chip->cmd_ctrl(mtd, column >> 8, NAND_ALE);
}
if (page_addr != -1) {
chip->cmd_ctrl(mtd, page_addr, NAND_ALE);
chip->cmd_ctrl(mtd, page_addr >> 8, NAND_ALE);
/* One more address cycle for devices > 128MiB */
if (chip->chipsize > (128 << 20))
chip->cmd_ctrl(mtd, page_addr >> 16, NAND_ALE);
}
chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0);
if (command == NAND_CMD_READ0) {
chip->cmd_ctrl(mtd, NAND_CMD_READSTART, NAND_CLE);
chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0);
}
/* wait for nand ready */
ndelay(100);
timeo = (CONFIG_SYS_HZ * 20) / 1000;
time_start = get_timer(0);
while (get_timer(time_start) < timeo) {
if (chip->dev_ready(mtd))
break;
}
}
static int mxs_flash_ident(struct mtd_info *mtd)
{
register struct nand_chip *chip = mtd->priv;
int i;
u8 mfg_id, dev_id;
u8 id_data[8];
struct nand_onfi_params *p = &chip->onfi_params;
/* Reset the chip */
chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
/* Send the command for reading device ID */
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
/* Read manufacturer and device IDs */
mfg_id = chip->read_byte(mtd);
dev_id = chip->read_byte(mtd);
/* Try again to make sure */
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
for (i = 0; i < 8; i++)
id_data[i] = chip->read_byte(mtd);
if (id_data[0] != mfg_id || id_data[1] != dev_id) {
printf("second ID read did not match");
return -1;
}
debug("0x%02x:0x%02x ", mfg_id, dev_id);
/* read ONFI */
chip->onfi_version = 0;
chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' ||
chip->read_byte(mtd) != 'F' || chip->read_byte(mtd) != 'I') {
return -2;
}
/* we have ONFI, probe it */
chip->cmdfunc(mtd, NAND_CMD_PARAM, 0, -1);
chip->read_buf(mtd, (uint8_t *)p, sizeof(*p));
mtd->name = p->model;
mtd->writesize = le32_to_cpu(p->byte_per_page);
mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize;
mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
chip->chipsize = le32_to_cpu(p->blocks_per_lun);
chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
/* Calculate the address shift from the page size */
chip->page_shift = ffs(mtd->writesize) - 1;
chip->phys_erase_shift = ffs(mtd->erasesize) - 1;
/* Convert chipsize to number of pages per chip -1 */
chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
chip->badblockbits = 8;
debug("erasesize=%d (>>%d)\n", mtd->erasesize, chip->phys_erase_shift);
debug("writesize=%d (>>%d)\n", mtd->writesize, chip->page_shift);
debug("oobsize=%d\n", mtd->oobsize);
debug("chipsize=%lld\n", chip->chipsize);
return 0;
}
static int mxs_read_page_ecc(struct mtd_info *mtd, void *buf, unsigned int page)
{
register struct nand_chip *chip = mtd->priv;
int ret;
chip->cmdfunc(mtd, NAND_CMD_READ0, 0x0, page);
ret = nand_chip.ecc.read_page(mtd, chip, buf, 1, page);
if (ret < 0) {
printf("read_page failed %d\n", ret);
return -1;
}
return 0;
}
static int is_badblock(struct mtd_info *mtd, loff_t offs, int allowbbt)
{
register struct nand_chip *chip = mtd->priv;
unsigned int block = offs >> chip->phys_erase_shift;
unsigned int page = offs >> chip->page_shift;
debug("%s offs=0x%08x block:%d page:%d\n", __func__, (int)offs, block,
page);
chip->cmdfunc(mtd, NAND_CMD_READ0, mtd->writesize, page);
memset(chip->oob_poi, 0, mtd->oobsize);
chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
return chip->oob_poi[0] != 0xff;
}
/* setup mtd and nand structs and init mxs_nand driver */
static int mxs_nand_init(void)
{
/* return if already initalized */
if (nand_chip.numchips)
return 0;
/* init mxs nand driver */
board_nand_init(&nand_chip);
mtd.priv = &nand_chip;
/* set mtd functions */
nand_chip.cmdfunc = mxs_nand_command;
nand_chip.numchips = 1;
/* identify flash device */
puts("NAND : ");
if (mxs_flash_ident(&mtd)) {
printf("Failed to identify\n");
return -1;
}
/* allocate and initialize buffers */
nand_chip.buffers = memalign(ARCH_DMA_MINALIGN,
sizeof(*nand_chip.buffers));
nand_chip.oob_poi = nand_chip.buffers->databuf + mtd.writesize;
/* setup flash layout (does not scan as we override that) */
mtd.size = nand_chip.chipsize;
nand_chip.scan_bbt(&mtd);
printf("%llu MiB\n", (mtd.size / (1024 * 1024)));
return 0;
}
int nand_spl_load_image(uint32_t offs, unsigned int size, void *buf)
{
struct nand_chip *chip;
unsigned int page;
unsigned int nand_page_per_block;
unsigned int sz = 0;
if (mxs_nand_init())
return -ENODEV;
chip = mtd.priv;
page = offs >> chip->page_shift;
nand_page_per_block = mtd.erasesize / mtd.writesize;
debug("%s offset:0x%08x len:%d page:%d\n", __func__, offs, size, page);
size = roundup(size, mtd.writesize);
while (sz < size) {
if (mxs_read_page_ecc(&mtd, buf, page) < 0)
return -1;
sz += mtd.writesize;
offs += mtd.writesize;
page++;
buf += mtd.writesize;
/*
* Check if we have crossed a block boundary, and if so
* check for bad block.
*/
if (!(page % nand_page_per_block)) {
/*
* Yes, new block. See if this block is good. If not,
* loop until we find a good block.
*/
while (is_badblock(&mtd, offs, 1)) {
page = page + nand_page_per_block;
/* Check i we've reached the end of flash. */
if (page >= mtd.size >> chip->page_shift)
return -ENOMEM;
}
}
}
return 0;
}
int nand_default_bbt(struct mtd_info *mtd)
{
return 0;
}
void nand_init(void)
{
}
void nand_deselect(void)
{
}

View File

@ -77,7 +77,7 @@
#define UCR3_DSR (1<<10) /* Data set ready */
#define UCR3_DCD (1<<9) /* Data carrier detect */
#define UCR3_RI (1<<8) /* Ring indicator */
#define UCR3_TIMEOUTEN (1<<7) /* Timeout interrupt enable */
#define UCR3_ADNIMP (1<<7) /* Autobaud Detection Not Improved */
#define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */
#define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */
#define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */
@ -186,7 +186,7 @@ static int mxc_serial_init(void)
while (!(__REG(UART_PHYS + UCR2) & UCR2_SRST));
__REG(UART_PHYS + UCR3) = 0x0704;
__REG(UART_PHYS + UCR3) = 0x0704 | UCR3_ADNIMP;
__REG(UART_PHYS + UCR4) = 0x8000;
__REG(UART_PHYS + UESC) = 0x002b;
__REG(UART_PHYS + UTIM) = 0x0;

View File

@ -20,7 +20,7 @@
#include <linux/sizes.h>
#define CONFIG_MXC_UART_BASE UART2_BASE
#define CONFIG_CONSOLE_DEV "ttymxc0"
#define CONFIG_CONSOLE_DEV "ttymxc1"
#define CONFIG_MMCROOT "/dev/mmcblk1p2"
#define PHYS_SDRAM_SIZE (1u * 1024 * 1024 * 1024)
@ -293,7 +293,7 @@
#if defined(CONFIG_ENV_IS_IN_MMC)
/* RiOTboard */
#define CONFIG_DEFAULT_FDT_FILE "imx6s-riotboard.dtb"
#define CONFIG_DEFAULT_FDT_FILE "imx6dl-riotboard.dtb"
#define CONFIG_SYS_FSL_USDHC_NUM 3
#define CONFIG_SYS_MMC_ENV_DEV 2 /* SDHC4 */
#define CONFIG_ENV_OFFSET (6 * 64 * 1024)

View File

@ -7,6 +7,17 @@
#ifndef __CONFIG_H
#define __CONFIG_H
/* SPL */
#define CONFIG_SPL_NAND_SUPPORT
#define CONFIG_SPL_MMC_SUPPORT
#define CONFIG_SPL_FAT_SUPPORT
/*
#define CONFIG_SPL_SATA_SUPPORT
*/
/* Location in NAND to read U-Boot from */
#define CONFIG_SYS_NAND_U_BOOT_OFFS (14 * 1024 * 1024)
#include "imx6_spl.h" /* common IMX6 SPL configuration */
#include "mx6_common.h"
#define CONFIG_MX6
#define CONFIG_DISPLAY_CPUINFO /* display cpu info */

View File

@ -0,0 +1,71 @@
/*
* Copyright (C) 2014 Gateworks Corporation
* Author: Tim Harvey <tharvey@gateworks.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef __IMX6_SPL_CONFIG_H
#define __IMX6_SPL_CONFIG_H
#ifdef CONFIG_SPL
#define CONFIG_SPL_FRAMEWORK
/*
* see Figure 8-3 in IMX6DQ/IMX6SDL Reference manuals:
* - IMX6SDL OCRAM (IRAM) is from 0x00907000 to 0x0091FFFF
* - IMX6DQ has 2x IRAM of IMX6SDL but we intend to support IMX6SDL as well
* - BOOT ROM stack is at 0x0091FFB8
* - if icache/dcache is enabled (eFuse/strapping controlled) then the
* IMX BOOT ROM will setup MMU table at 0x00918000, therefore we need to
* fit between 0x00907000 and 0x00918000.
* - Additionally the BOOT ROM loads what they consider the firmware image
* which consists of a 4K header in front of us that contains the IVT, DCD
* and some padding thus 'our' max size is really 0x00908000 - 0x00918000
* or 64KB
*/
#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/omap-common/u-boot-spl.lds"
#define CONFIG_SPL_TEXT_BASE 0x00908000
#define CONFIG_SPL_MAX_SIZE (64 * 1024)
#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/armv7"
#define CONFIG_SPL_STACK 0x0091FFB8
#define CONFIG_SPL_LIBCOMMON_SUPPORT
#define CONFIG_SPL_LIBGENERIC_SUPPORT
#define CONFIG_SPL_SERIAL_SUPPORT
#define CONFIG_SPL_I2C_SUPPORT
#define CONFIG_SPL_GPIO_SUPPORT
/* NAND support */
#if defined(CONFIG_SPL_NAND_SUPPORT)
#define CONFIG_SPL_NAND_MXS
#define CONFIG_SPL_DMA_SUPPORT
#endif
/* MMC support */
#if defined(CONFIG_SPL_MMC_SUPPORT)
#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 138 /* offset 69KB */
#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 800 /* 400 KB */
#define CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION 1
#define CONFIG_SYS_MONITOR_LEN (CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS/2*1024)
#endif
/* SATA support */
#if defined(CONFIG_SPL_SATA_SUPPORT)
#define CONFIG_SPL_SATA_BOOT_DEVICE 0
#define CONFIG_SYS_SATA_FAT_BOOT_PARTITION 1
#endif
/* Define the payload for FAT/EXT support */
#if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT)
#define CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME "u-boot.img"
#define CONFIG_SPL_LIBDISK_SUPPORT
#endif
#define CONFIG_SPL_BSS_START_ADDR 0x18200000
#define CONFIG_SPL_BSS_MAX_SIZE 0x100000 /* 1 MB */
#define CONFIG_SYS_SPL_MALLOC_START 0x18300000
#define CONFIG_SYS_SPL_MALLOC_SIZE 0x3200000 /* 50 MB */
#define CONFIG_SYS_TEXT_BASE 0x17800000
#endif
#endif

View File

@ -9,6 +9,7 @@
#define __M53EVK_CONFIG_H__
#define CONFIG_MX53
#define CONFIG_SYS_GENERIC_BOARD
#define CONFIG_MXC_GPIO
#include <asm/arch/imx-regs.h>

View File

@ -48,7 +48,11 @@
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
/* Environment */
#ifndef CONFIG_ENV_IS_IN_SPI_FLASH
#define CONFIG_ENV_SIZE (16 * 1024)
#else
#define CONFIG_ENV_SIZE (4 * 1024)
#endif
#define CONFIG_ENV_OVERWRITE
/* Environment is in MMC */
@ -70,7 +74,6 @@
/* Environemnt is in SPI flash */
#if defined(CONFIG_CMD_SF) && defined(CONFIG_ENV_IS_IN_SPI_FLASH)
#define CONFIG_SYS_REDUNDAND_ENVIRONMENT
#define CONFIG_ENV_SIZE 0x1000 /* 4KB */
#define CONFIG_ENV_OFFSET 0x40000 /* 256K */
#define CONFIG_ENV_OFFSET_REDUND (CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE)
#define CONFIG_ENV_SECT_SIZE 0x1000

View File

@ -17,7 +17,6 @@
#ifndef __MX6_COMMON_H
#define __MX6_COMMON_H
#define CONFIG_ARM_ERRATA_742230
#define CONFIG_ARM_ERRATA_743622
#define CONFIG_ARM_ERRATA_751472
#define CONFIG_ARM_ERRATA_794072

View File

@ -12,7 +12,11 @@
#define CONFIG_MACH_TYPE 3529
#define CONFIG_MXC_UART_BASE UART4_BASE
#define CONFIG_CONSOLE_DEV "ttymxc3"
#if defined CONFIG_MX6Q
#define CONFIG_DEFAULT_FDT_FILE "imx6q-sabreauto.dtb"
#elif defined CONFIG_MX6DL
#define CONFIG_DEFAULT_FDT_FILE "imx6dl-sabreauto.dtb"
#endif
#define CONFIG_MMCROOT "/dev/mmcblk0p2"
#define PHYS_SDRAM_SIZE (2u * 1024 * 1024 * 1024)

View File

@ -59,4 +59,16 @@
#define CONFIG_PCIE_IMX_POWER_GPIO IMX_GPIO_NR(3, 19)
#endif
/* I2C Configs */
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
#define CONFIG_SYS_I2C_SPEED 100000
/* PMIC */
#define CONFIG_POWER
#define CONFIG_POWER_I2C
#define CONFIG_POWER_PFUZE100
#define CONFIG_POWER_PFUZE100_I2C_ADDR 0x08
#endif /* __MX6QSABRESD_CONFIG_H */

View File

@ -15,7 +15,11 @@ enum {
PFUZE100_FABID = 0x04,
PFUZE100_SW1ABVOL = 0x20,
PFUZE100_SW1ABSTBY = 0x21,
PUZE_100_SW1ABCONF = 0x24,
PFUZE100_SW1CVOL = 0x2e,
PFUZE100_SW1CSTBY = 0x2f,
PFUZE100_SW1CCONF = 0x32,
PFUZE100_SW2VOL = 0x35,
PFUZE100_SW3AVOL = 0x3c,
PFUZE100_SW3BVOL = 0x43,