U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
March 2008
- 209 participants
- 580 discussions
I have u-boot 1.1.6 running on my board based on IXP425
processor (266MhZ).
I trying to use netconsole.
I readed doc/README.NetConsole and make connection with u-boot.
On u-boot I do:
setenv nc 'setenv stdout nc;setenv stdin nc'
setenv ncip 192.168.1.5:1234
saveenv
run nc
On host PC (192.168.1.5) I run following script:
nc -u -l 1234 < /dev/null &
nc -u 192.168.1.88 1234
Note that in first host command I omitted "-p" flag before port definition.
The problem is the communication in vary slow: one character per second!
Any suggestion ?
3
3

[U-Boot-Users] [PATCH 2/2] DM644x: This adds support for the Prodrive PMDRA board, based on a DM6441
by Pieter Voorthuijsen 20 Mar '08
by Pieter Voorthuijsen 20 Mar '08
20 Mar '08
Hello,
This patch adds support for the new Prodrive PMDR-A board. It is based
on the DaVinci DM6441 processor, has 256M DDR2, 8M NOR and 256M of NAND.
(This requires the previous patch that removes board specific code from
/cpu/arm926ejs/davinci)
Best regards,
Pieter
Signed-off-by: Pieter Voorthuijsen <pieter.voorthuijsen(a)prodrive.nl>
---
Makefile | 3 +
board/prodrive/pmdra/Makefile | 52 ++++++++++
board/prodrive/pmdra/board_init.S | 34 +++++++
board/prodrive/pmdra/config.mk | 39 ++++++++
board/prodrive/pmdra/pmdra.c | 192
+++++++++++++++++++++++++++++++++++++
board/prodrive/pmdra/u-boot.lds | 52 ++++++++++
include/configs/pmdra.h | 184
+++++++++++++++++++++++++++++++++++
7 files changed, 556 insertions(+), 0 deletions(-)
create mode 100644 board/prodrive/pmdra/Makefile
create mode 100644 board/prodrive/pmdra/board_init.S
create mode 100644 board/prodrive/pmdra/config.mk
create mode 100644 board/prodrive/pmdra/pmdra.c
create mode 100644 board/prodrive/pmdra/u-boot.lds
create mode 100644 include/configs/pmdra.h
diff --git a/Makefile b/Makefile
index 4fde699..77f3d24 100644
--- a/Makefile
+++ b/Makefile
@@ -2375,6 +2375,9 @@ davinci_schmoogie_config : unconfig
davinci_sonata_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm926ejs sonata davinci davinci
+pmdra_config : unconfig
+ @$(MKCONFIG) $(@:_config=) arm arm926ejs pmdra prodrive davinci
+
omap1610inn_config \
omap1610inn_cs0boot_config \
omap1610inn_cs3boot_config \
diff --git a/board/prodrive/pmdra/Makefile
b/board/prodrive/pmdra/Makefile
new file mode 100644
index 0000000..918c7b0
--- /dev/null
+++ b/board/prodrive/pmdra/Makefile
@@ -0,0 +1,52 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd(a)denx.de.
+#
+# Copyright (C) 2007 Sergey Kubushyn <ksi(a)koi8.net>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).a
+
+COBJS := pmdra.o
+SOBJS := board_init.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak *~ .depend
+
+#######################################################################
##
+# This is for $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#######################################################################
##
diff --git a/board/prodrive/pmdra/board_init.S
b/board/prodrive/pmdra/board_init.S
new file mode 100644
index 0000000..6cc2e86
--- /dev/null
+++ b/board/prodrive/pmdra/board_init.S
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 Prodrive B.V.
+ *
+ * Board-specific low level initialization code. Called at the very end
+ * of cpu/arm926ejs/davinci/lowlevel_init.S. Just returns if there is
no
+ * initialization required.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* This code sets up the timing params for EMIF CE2 and CE3 which
+ * connect to NOR and NAND flash
+ */
+
+#include <config.h>
+
+.globl dv_board_init
+dv_board_init:
+
+ mov pc, lr
+
diff --git a/board/prodrive/pmdra/config.mk
b/board/prodrive/pmdra/config.mk
new file mode 100644
index 0000000..aa89d0e
--- /dev/null
+++ b/board/prodrive/pmdra/config.mk
@@ -0,0 +1,39 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj(a)denx.de>
+# David Mueller, ELSOFT AG, <d.mueller(a)elsoft.ch>
+#
+# (C) Copyright 2003
+# Texas Instruments, <www.ti.com>
+# Swaminathan <swami.iyer(a)ti.com>
+#
+# Davinci EVM board (ARM925EJS) cpu
+# see http://www.ti.com/ for more information on Texas Instruments
+#
+# Davinci EVM has 1 bank of 256 MB DDR RAM
+# Physical Address:
+# 8000'0000 to 9000'0000
+#
+# Copyright (C) 2007 Sergey Kubushyn <ksi(a)koi8.net>
+#
+# Visioneering Corp. Sonata board (ARM926EJS) cpu
+#
+# Sonata board has 1 bank of 128 MB DDR RAM
+# Physical Address:
+# 8000'0000 to 8800'0000
+#
+# Razorstream, LLC. SCHMOOGIE board (ARM926EJS) cpu
+#
+# Schmoogie board has 1 bank of 128 MB DDR RAM
+# Physical Address:
+# 8000'0000 to 8800'0000
+#
+# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000
+# (mem base + reserved)
+#
+# we load ourself to 8108 '0000
+#
+#
+
+#Provide at least 16MB spacing between us and the Linux Kernel image
+TEXT_BASE = 0x81080000
diff --git a/board/prodrive/pmdra/pmdra.c b/board/prodrive/pmdra/pmdra.c
new file mode 100644
index 0000000..348ba47
--- /dev/null
+++ b/board/prodrive/pmdra/pmdra.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi(a)koi8.net>
+ *
+ * Parts are shamelessly stolen from various TI sources, original
copyright
+ * follows:
+ * -----------------------------------------------------------------
+ *
+ * Copyright (C) 2004 Texas Instruments.
+ *
+ *
------------------------------------------------------------------------
----
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
------------------------------------------------------------------------
----
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/emac_defs.h>
+
+#define MACH_TYPE_DAVINCI_EVM 901
+
+DECLARE_GLOBAL_DATA_PTR;
+
+extern void i2c_init(int speed, int slaveaddr);
+extern void timer_init(void);
+extern int eth_hw_init(void);
+extern phy_t phy;
+
+
+/* Works on Always On power domain only (no PD argument) */
+void lpsc_on(unsigned int id)
+{
+ dv_reg_p mdstat, mdctl;
+
+ if (id >= DAVINCI_LPSC_GEM)
+ return; /* Don't work on DSP Power
Domain */
+
+ mdstat = REG_P(PSC_MDSTAT_BASE + (id * 4));
+ mdctl = REG_P(PSC_MDCTL_BASE + (id * 4));
+
+ while (REG(PSC_PTSTAT) & 0x01) {;}
+
+ if ((*mdstat & 0x1f) == 0x03)
+ return; /* Already on and enabled */
+
+ *mdctl |= 0x03;
+
+ /* Special treatment for some modules as for sprue14 p.7.4.2 */
+ if ( (id == DAVINCI_LPSC_VPSSSLV) ||
+ (id == DAVINCI_LPSC_EMAC) ||
+ (id == DAVINCI_LPSC_EMAC_WRAPPER) ||
+ (id == DAVINCI_LPSC_MDIO) ||
+ (id == DAVINCI_LPSC_USB) ||
+ (id == DAVINCI_LPSC_ATA) ||
+ (id == DAVINCI_LPSC_VLYNQ) ||
+ (id == DAVINCI_LPSC_UHPI) ||
+ (id == DAVINCI_LPSC_DDR_EMIF) ||
+ (id == DAVINCI_LPSC_AEMIF) ||
+ (id == DAVINCI_LPSC_MMC_SD) ||
+ (id == DAVINCI_LPSC_MEMSTICK) ||
+ (id == DAVINCI_LPSC_McBSP) ||
+ (id == DAVINCI_LPSC_GPIO)
+ )
+ *mdctl |= 0x200;
+
+ REG(PSC_PTCMD) = 0x01;
+
+ while (REG(PSC_PTSTAT) & 0x03) {;}
+ while ((*mdstat & 0x1f) != 0x03) {;} /* Probably an
overkill... */
+}
+
+void dsp_on(void)
+{
+ int i;
+
+ if (REG(PSC_PDSTAT1) & 0x1f)
+ return; /* Already on */
+
+ REG(PSC_GBLCTL) |= 0x01;
+ REG(PSC_PDCTL1) |= 0x01;
+ REG(PSC_PDCTL1) &= ~0x100;
+ REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) |= 0x03;
+ REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_GEM * 4)) &= 0xfffffeff;
+ REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) |= 0x03;
+ REG(PSC_MDCTL_BASE + (DAVINCI_LPSC_IMCOP * 4)) &= 0xfffffeff;
+ REG(PSC_PTCMD) = 0x02;
+
+ for (i = 0; i < 100; i++) {
+ if (REG(PSC_EPCPR) & 0x02)
+ break;
+ }
+
+ REG(PSC_CHP_SHRTSW) = 0x01;
+ REG(PSC_PDCTL1) |= 0x100;
+ REG(PSC_EPCCR) = 0x02;
+
+ for (i = 0; i < 100; i++) {
+ if (!(REG(PSC_PTSTAT) & 0x02))
+ break;
+ }
+
+ REG(PSC_GBLCTL) &= ~0x1f;
+}
+
+
+int board_init(void)
+{
+ /* arch number of the board */
+ gd->bd->bi_arch_number = MACH_TYPE_DAVINCI_EVM;
+
+ /* address of boot parameters */
+ gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR;
+
+ /* Workaround for TMS320DM6446 errata 1.3.22 */
+ REG(PSC_SILVER_BULLET) = 0;
+
+ /* Power on required peripherals */
+ lpsc_on(DAVINCI_LPSC_EMAC);
+ lpsc_on(DAVINCI_LPSC_EMAC_WRAPPER);
+ lpsc_on(DAVINCI_LPSC_MDIO);
+ lpsc_on(DAVINCI_LPSC_I2C);
+ lpsc_on(DAVINCI_LPSC_UART0);
+ lpsc_on(DAVINCI_LPSC_UART2);
+ lpsc_on(DAVINCI_LPSC_TIMER1);
+ lpsc_on(DAVINCI_LPSC_GPIO);
+
+ /* Powerup the DSP */
+ dsp_on();
+
+ /* Bringup UART0 and 2 out of reset */
+// REG(UART0_PWREMU_MGMT) = 0x0000e003; /* Why does TI use reserved
bits or bit that MUST be set to 0? */
+ REG(UART0_PWREMU_MGMT) = 0x00006001;
+ REG(UART2_PWREMU_MGMT) = 0x00006001;
+
+ /* Enable GIO3.3V cells used for EMAC */
+ REG(VDD3P3V_PWDN) = 0;
+
+ /* Enable UART0 and 2 MUX lines */
+ REG(PINMUX1) |= 1; //(0)
+ REG(PINMUX1) |= 4; //(2)
+
+ /* Enable EMAC and AEMIF pins */
+ REG(PINMUX0) = 0x80000c1f;
+
+ /* Enable I2C pin Mux */
+ REG(PINMUX1) |= (1 << 7);
+
+ /* Set the Bus Priority Register to appropriate value */
+ REG(VBPR) = 0x20;
+
+ timer_init();
+
+ return(0);
+}
+
+int misc_init_r (void)
+{
+ int clk = 0;
+
+ clk = ((REG(PLL2_PLLM) + 1) * 27) / ((REG(PLL2_DIV2) & 0x1f) +
1);
+
+ printf ("ARM Clock : %dMHz\n", ((REG(PLL1_PLLM) + 1) * 27 ) /
2);
+ printf ("DDR Clock : %dMHz\n", (clk / 2));
+
+ if (!eth_hw_init()) {
+ printf("ethernet init failed!\n");
+ } else {
+ printf("ETH PHY : %s\n", phy.name);
+ }
+
+ return(0);
+}
+
+int dram_init(void)
+{
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+ return(0);
+}
diff --git a/board/prodrive/pmdra/u-boot.lds
b/board/prodrive/pmdra/u-boot.lds
new file mode 100644
index 0000000..710b2a2
--- /dev/null
+++ b/board/prodrive/pmdra/u-boot.lds
@@ -0,0 +1,52 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj(a)denx.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0x00000000;
+ . = ALIGN(4);
+ .text :
+ {
+ cpu/arm926ejs/start.o (.text)
+ *(.text)
+ }
+ . = ALIGN(4);
+ .rodata : { *(.rodata) }
+ . = ALIGN(4);
+ .data : { *(.data) }
+ . = ALIGN(4);
+ .got : { *(.got) }
+
+ . = .;
+ __u_boot_cmd_start = .;
+ .u_boot_cmd : { *(.u_boot_cmd) }
+ __u_boot_cmd_end = .;
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss) }
+ _end = .;
+}
diff --git a/include/configs/pmdra.h b/include/configs/pmdra.h
new file mode 100644
index 0000000..d6b3456
--- /dev/null
+++ b/include/configs/pmdra.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2007 Sergey Kubushyn <ksi(a)koi8.net>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+#include <asm/sizes.h>
+
+/*=======*/
+/* Board */
+/*=======*/
+#define CFG_PMDRA
+#define CFG_NAND_LARGEPAGE
+/*===================*/
+/* SoC Configuration */
+/*===================*/
+#define CONFIG_ARM926EJS /* arm926ejs CPU core */
+#define CONFIG_SYS_CLK_FREQ (CFG_HZ_CLOCK * (CFG_DAVINCI_PLL1_PLLM +
1)) / 2
+#define CFG_TIMERBASE 0x01c21400 /* use timer 0 */
+#define CFG_HZ_CLOCK 27000000 /* Timer Input clock
freq */
+#define CFG_HZ 1000
+#define CFG_DAVINCI_PINMUX_0 0x00000c1f
+#define CFG_DAVINCI_WAITCFG 0x10000000
+#define CFG_DAVINCI_ACFG2 0x00460385 /* NOR CE Config */
+#define CFG_DAVINCI_ACFG3 0x0822218c /* NAND CE Config */
+#define CFG_DAVINCI_ACFG4 0x3ffffffd
+#define CFG_DAVINCI_ACFG5 0x3ffffffd
+#define CFG_DAVINCI_NANDCE 3 /* Use CE3 for NAND */
+#define CFG_DAVINCI_DDRCTL 0x50006405 /* DDR timing config */
+#define CFG_DAVINCI_SDREF 0x000005c3
+#define CFG_DAVINCI_SDCFG 0x00178832 /* 8 banks , CAS = 4*/
+#define CFG_DAVINCI_SDTIM0 0x28923211
+#define CFG_DAVINCI_SDTIM1 0x0016c722
+#define CFG_DAVINCI_MMARG_BRF0 0x00444400
+#define CFG_DAVINCI_PLL1_PLLM 0x12 /* DM6446 = 0x15, DM6441
= 0x12, DM6441_LV = 0x0e */
+#define CFG_DAVINCI_PLL2_PLLM 0x17 /* 162 MHz */
+#define CFG_DAVINCI_PLL2_DIV1 0x0b /* 54 MHz */
+#define CFG_DAVINCI_PLL2_DIV2 0x01
+/*====================================================*/
+/* EEPROM definitions for Atmel 24C256BN SEEPROM chip */
+/* on Sonata/DV_EVM board. No EEPROM on schmoogie. */
+/*====================================================*/
+#define CFG_I2C_EEPROM_ADDR_LEN 2
+#define CFG_I2C_EEPROM_ADDR 0x50
+#define CFG_EEPROM_PAGE_WRITE_BITS 6
+#define CFG_EEPROM_PAGE_WRITE_DELAY_MS 20
+/*=============*/
+/* Memory Info */
+/*=============*/
+#define CFG_MALLOC_LEN (0x10000 + 128*1024) /* malloc() len
*/
+#define CFG_GBL_DATA_SIZE 128 /* reserved for initial
data */
+#define CFG_MEMTEST_START 0x80000000 /* memtest start address
*/
+#define CFG_MEMTEST_END 0x81000000 /* 16MB RAM test
*/
+#define CONFIG_NR_DRAM_BANKS 1 /* we have 1 bank of
DRAM */
+#define CONFIG_STACKSIZE (256*1024) /* regular stack */
+#define PHYS_SDRAM_1 0x80000000 /* DDR Start */
+#define PHYS_SDRAM_1_SIZE 0x10000000 /* DDR size 256MB */
+#define DDR_8BANKS /* 8-bank DDR2 (256MB)
*/
+/*====================*/
+/* Serial Driver info */
+/*====================*/
+#define CFG_NS16550
+#define CFG_NS16550_SERIAL
+#define CFG_NS16550_REG_SIZE 4 /* NS16550 register size
*/
+#define CFG_NS16550_COM1 0x01c20000 /* Base address of UART0
*/
+#define CFG_NS16550_COM2 0x01c20800 /* Base address of UART2
*/
+#define CFG_NS16550_CLK 27000000 /* Input clock
to NS16550 */
+#define CONFIG_CONS_INDEX 1 /* use UART0 for console
*/
+#define CONFIG_BAUDRATE 115200 /* Default baud
rate */
+#define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+/*===================*/
+/* I2C Configuration */
+/*===================*/
+#define CONFIG_HARD_I2C
+#define CONFIG_DRIVER_DAVINCI_I2C
+#define CFG_I2C_SPEED 50000 /* 100Kbps won't work, silicon
bug */
+#define CFG_I2C_SLAVE 10 /* Bogus, master-only in U-Boot
*/
+/*==================================*/
+/* Network & Ethernet Configuration */
+/*==================================*/
+#define CONFIG_DRIVER_TI_EMAC
+#define CONFIG_MII
+#define CONFIG_BOOTP_DEFAULT
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS2
+#define CONFIG_BOOTP_SEND_HOSTNAME
+#define CONFIG_NET_RETRY_COUNT 10
+/*=====================*/
+/* Flash & Environment */
+/*=====================*/
+#define CFG_USE_NAND
+#define CFG_NAND_BASE 0x04000000
+#define CFG_NAND_HW_ECC
+#define CFG_MAX_NAND_DEVICE 1 /* Max number of NAND devices */
+#define NAND_MAX_CHIPS 1
+#undef CONFIG_SKIP_LOWLEVEL_INIT
+#undef CONFIG_SKIP_RELOCATE_UBOOT
+#define DEF_BOOTM ""
+#define CFG_ENV_IS_IN_FLASH 1
+#undef CFG_NO_FLASH
+#define CFG_FLASH_CFI_DRIVER
+#define CFG_FLASH_CFI
+#define CFG_MAX_FLASH_BANKS 1 /* max number of flash
banks */
+#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x40000)
+#define CFG_ENV_OFFSET (CFG_ENV_ADDR)
+#define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes
(20x faster) */
+#define PHYS_FLASH_1 0x02000000 /* CS2 Base address
*/
+#define CFG_FLASH_BASE PHYS_FLASH_1 /* Flash Base for U-Boot
*/
+#define PHYS_FLASH_SIZE 0x2000000 /* Flash size
32MB */
+#define CFG_MAX_FLASH_SECT (PHYS_FLASH_SIZE/CFG_FLASH_SECT_SZ)
+#define CFG_ENV_SECT_SIZE CFG_FLASH_SECT_SZ /* Env sector
Size */
+#define CFG_FLASH_SECT_SZ 0x20000 /* 128KB sect size INTEL
Flash */
+#define CFG_FLASH_PROTECTION 1
+/*==============================*/
+/* U-Boot general configuration */
+/*==============================*/
+#undef CONFIG_USE_IRQ /* No IRQ/FIQ in U-Boot
*/
+#define CONFIG_MISC_INIT_R
+#define CONFIG_BOOTFILE "uImage" /* Boot file
name */
+#define CFG_PROMPT "U-Boot > " /* Monitor Command
Prompt */
+#define CFG_CBSIZE 1024 /* Console I/O Buffer
Size */
+#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16)
/* Print buffer sz */
+#define CFG_MAXARGS 16 /* max number of command
args */
+#define CFG_BARGSIZE CFG_CBSIZE /* Boot Argument Buffer
Size */
+#define CFG_LOAD_ADDR 0x80700000 /* default Linux kernel
load address */
+#define CONFIG_VERSION_VARIABLE
+#define CONFIG_AUTO_COMPLETE /* Won't work with hush so far,
may be later */
+#define CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2 "> "
+#define CONFIG_CMDLINE_EDITING
+#define CFG_LONGHELP
+#define CONFIG_CRC32_VERIFY
+#define CONFIG_MX_CYCLIC
+/*===================*/
+/* Linux Information */
+/*===================*/
+#define LINUX_BOOT_PARAM_ADDR 0x80000100
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTDELAY 2
+#define CONFIG_BOOTARGS "mem=120M console=ttyS0,115200n8
root=/dev/hda1 rw noinitrd ip=dhcp"
+#define CONFIG_BOOTCOMMAND "run nand"
+#define CONFIG_EXTRA_ENV_SETTINGS "ethaddr=00:11:22:33:44:55\n"
+/*=================*/
+/* U-Boot commands */
+/*=================*/
+#include <config_cmd_default.h>
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_DIAG
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SAVES
+#define CONFIG_CMD_EEPROM
+#undef CONFIG_CMD_BDI
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_SETGETDCR
+#define CONFIG_CMD_FLASH
+#undef CONFIG_CMD_IMLS
+#define CONFIG_CMD_NAND
+/*=======================*/
+/* KGDB support (if any) */
+/*=======================*/
+#ifdef CONFIG_CMD_KGDB
+#define CONFIG_KGDB_BAUDRATE 115200 /* speed to run kgdb serial port
*/
+#define CONFIG_KGDB_SER_INDEX 1 /* which serial port to use */
+#endif
+#endif /* __CONFIG_H */
--
1.5.3.7
Pieter Voorthuijsen
Prodrive B.V.
Science Park Eindhoven
P.O. box 28030
5602 JA Eindhoven
The Netherlands
Email pieter.voorthuijsen(a)prodrive.nl
Tel: +31-40-2676258
Fax: +31-40-2676201
3
2
Hi, friends,
I am new to this forum.
Currently we are working on u-boot for our customized board (use MPC8272).
Our reference board is mpc8272ads board from freescale. U-boot configiures
mpc8272ads board as one of the mpc8260ads family. And u-boot uses BR0/OR0,
BR1/OR1 for flash and BR2/OR2, BR3/OR3 for SDRAM. However, our customized
board is configured using CS1 (BR1/OR1) for the SDRAM.
How can I modify the u-boot source code for the mpc8260ads family to let
u-boot recognize BR1/OR1 as SDRAM? I don't know how many files will be
related to this change and how 'deep' I will go.
or let the hardware engineer change SDRAM to CS2 (BR2/OR2) may be easier?
Thank you for your advice,
solaz
--
View this message in context: http://www.nabble.com/Is-it-easy-to-config-BR1-OR1-as-SDRAM-in-u-boot--tp16…
Sent from the Uboot - Users mailing list archive at Nabble.com.
2
2

[U-Boot-Users] [PATCH] DM644x: This patch removes all board specific code from the arch. part for DM644x (DaVinci) boards
by Pieter Voorthuijsen 20 Mar '08
by Pieter Voorthuijsen 20 Mar '08
20 Mar '08
Hello,
In the current implementation of the DM644x (DaVinci) achitecture there
is a lot of code in the /cpu/arm926ejs/davinci folder that is meant to
be board specific. I'm talking about EMIF timing/width configuration for
NAND and NOR but also DRAM timing settings which are of course different
for boards. This patch makes the board config files configure the
architecture files (lowlevel_init.S and nand.c) with defines.
Also there is a small addition to add support for the DVEVM, the only
difference is an Intel NOR instead of an AMD, so blocksizes are
different.
This is tested with the Davinci EVM (Old and new one), the other boards
(Sonata and Schmoogie) are building with these patches.
Best regards,
Pieter Voorthuijsen
Signed-off-by: Pieter Voorthuijsen <pieter.voorthuijsen(a)prodrive.nl>
---
cpu/arm926ejs/davinci/lowlevel_init.S | 79
++++++++++++++++++++-----------
cpu/arm926ejs/davinci/nand.c | 41 ++--------------
include/asm-arm/arch-davinci/hardware.h | 2 +
include/configs/davinci_dvevm.h | 33 ++++++++++++-
include/configs/davinci_schmoogie.h | 19 +++++++-
include/configs/davinci_sonata.h | 18 +++++++
6 files changed, 124 insertions(+), 68 deletions(-)
diff --git a/cpu/arm926ejs/davinci/lowlevel_init.S
b/cpu/arm926ejs/davinci/lowlevel_init.S
index a87c112..0e94981 100644
--- a/cpu/arm926ejs/davinci/lowlevel_init.S
+++ b/cpu/arm926ejs/davinci/lowlevel_init.S
@@ -3,6 +3,11 @@
*
* Copyright (C) 2007 Sergey Kubushyn <ksi(a)koi8.net>
*
+ * Copyright (C) 2008 Prodrive BV <pv(a)prodrive.nl>
+ * Changed:
+ * Made board specific defines such as DDR timing and PLL
+ * dividers. These should be set in the board config file.
+ *
* Partially based on TI sources, original copyrights follow:
*/
@@ -156,17 +161,17 @@ WaitPPL2Loop:
/* Program the PLL Multiplier */
ldr r6, PLL2_PLLM
- mov r2, $0x17 /* 162 MHz */
+ mov r2, $CFG_DAVINCI_PLL2_PLLM
str r2, [r6]
/* Program the PLL2 Divisor Value */
ldr r6, PLL2_DIV2
- mov r3, $0x01
+ mov r3, $CFG_DAVINCI_PLL2_DIV2
str r3, [r6]
/* Program the PLL2 Divisor Value */
ldr r6, PLL2_DIV1
- mov r4, $0x0b /* 54 MHz */
+ mov r4, $CFG_DAVINCI_PLL2_DIV1
str r4, [r6]
/* PLL2 DIV2 MMR */
@@ -273,7 +278,7 @@ checkDDRStatClkStop:
bne checkDDRStatClkStop
/*------------------------------------------------------*
- * Program DDR2 MMRs for 162MHz Setting *
+ * Program DDR2 MMRs *
*------------------------------------------------------*/
/* Program PHY Control Register */
@@ -288,12 +293,12 @@ checkDDRStatClkStop:
/* Program SDRAM TIM-0 Config Register */
ldr r6, SDTIM0
- ldr r7, SDTIM0_VAL_162MHz
+ ldr r7, SDTIM0_VAL
str r7, [r6]
/* Program SDRAM TIM-1 Config Register */
ldr r6, SDTIM1
- ldr r7, SDTIM1_VAL_162MHz
+ ldr r7, SDTIM1_VAL
str r7, [r6]
/* Program the SDRAM Bank Config Control Register */
@@ -435,7 +440,7 @@ WaitLoop:
/* Program the PLL Multiplier */
ldr r6, PLL1_PLLM
- mov r3, $0x15 /* For 594MHz */
+ mov r3, $CFG_DAVINCI_PLL1_PLLM
str r3, [r6]
/* Wait for PLL to Reset Properly */
@@ -467,7 +472,7 @@ PLL1Lock:
nop
/*------------------------------------------------------*
- * AEMIF configuration for NOR Flash (double check) *
+ * AEMIF configuration for NAND/NOR Flash *
*------------------------------------------------------*/
ldr r0, _PINMUX0
ldr r1, _DEV_SETTING
@@ -479,6 +484,12 @@ PLL1Lock:
orr r2, r2, r1
str r2, [r0]
+ ldr r0, ACFG2
+ ldr r1, ACFG2_VAL
+ ldr r2, [r0]
+ and r1, r2, r1
+ str r1, [r0]
+
ldr r0, ACFG3
ldr r1, ACFG3_VAL
ldr r2, [r0]
@@ -497,6 +508,12 @@ PLL1Lock:
and r1, r2, r1
str r1, [r0]
+ ldr r0, NANDFCR
+ ldr r1, NANDFCR_VAL
+ ldr r2, [r0]
+ and r1, r2, r1
+ str r1, [r0]
+
/*--------------------------------------*
* VTP manual Calibration *
*--------------------------------------*/
@@ -560,24 +577,36 @@ _PINMUX1:
.word 0x01c40004 /* Device Configuration
Registers */
_DEV_SETTING:
- .word 0x00000c1f
+ .word CFG_DAVINCI_PINMUX_0
WAITCFG:
.word 0x01e00004
WAITCFG_VAL:
- .word 0
+ .word CFG_DAVINCI_WAITCFG
+ACFG2:
+ .word 0x01e00010
+ACFG2_VAL:
+ .word CFG_DAVINCI_ACFG2
ACFG3:
.word 0x01e00014
ACFG3_VAL:
- .word 0x3ffffffd
+ .word CFG_DAVINCI_ACFG3
ACFG4:
.word 0x01e00018
ACFG4_VAL:
- .word 0x3ffffffd
+ .word CFG_DAVINCI_ACFG4
ACFG5:
.word 0x01e0001c
ACFG5_VAL:
- .word 0x3ffffffd
+ .word CFG_DAVINCI_ACFG5
+NANDFCR:
+ .word 0x01e00060
+NANDFCR_VAL:
+#ifdef CFG_DAVINCI_NANDCE
+ .word (1 << (CFG_DAVINCI_NANDCE - 2))
+#else
+ .word 0x00000000
+#endif
MDCTL_DDR2:
.word 0x01c41a34
@@ -599,33 +628,27 @@ PSC_FLAG_CLEAR:
PSC_GEM_FLAG_CLEAR:
.word 0xfffffeff
-/* DDR2 MMR & CONFIGURATION VALUES, 162 MHZ clock */
+/* DDR2 MMR & CONFIGURATION VALUES */
DDRCTL:
.word 0x200000e4
DDRCTL_VAL:
- .word 0x50006405
+ .word CFG_DAVINCI_DDRCTL
SDREF:
.word 0x2000000c
SDREF_VAL:
- .word 0x000005c3
+ .word CFG_DAVINCI_SDREF
SDCFG:
.word 0x20000008
SDCFG_VAL:
-#ifdef DDR_4BANKS
- .word 0x00178622
-#elif defined DDR_8BANKS
- .word 0x00178632
-#else
-#error "Unknown DDR configuration!!!"
-#endif
+ .word CFG_DAVINCI_SDCFG
SDTIM0:
.word 0x20000010
-SDTIM0_VAL_162MHz:
- .word 0x28923211
+SDTIM0_VAL:
+ .word CFG_DAVINCI_SDTIM0
SDTIM1:
.word 0x20000014
-SDTIM1_VAL_162MHz:
- .word 0x0016c722
+SDTIM1_VAL:
+ .word CFG_DAVINCI_SDTIM1
VTPIOCR:
.word 0x200000f0 /* VTP IO Control register */
DDRVTPR:
@@ -699,7 +722,7 @@ PLL2_DIV_MASK:
MMARG_BRF0:
.word 0x01c42010 /* BRF margin mode 0 (R/W)*/
MMARG_BRF0_VAL:
- .word 0x00444400
+ .word CFG_DAVINCI_MMARG_BRF0
DDR2_START_ADDR:
.word 0x80000000
diff --git a/cpu/arm926ejs/davinci/nand.c b/cpu/arm926ejs/davinci/nand.c
index 127be9f..3257f83 100644
--- a/cpu/arm926ejs/davinci/nand.c
+++ b/cpu/arm926ejs/davinci/nand.c
@@ -117,7 +117,7 @@ static void nand_davinci_enable_hwecc(struct
mtd_info *mtd, int mode)
dummy = emif_addr->NANDF3ECC;
dummy = emif_addr->NANDF4ECC;
- emif_addr->NANDFCR |= (1 << 8);
+ emif_addr->NANDFCR |= (1 << (CFG_DAVINCI_NANDCE + 6));
}
static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t
region)
@@ -147,7 +147,7 @@ static int nand_davinci_calculate_ecc(struct
mtd_info *mtd, const u_char *dat, u
n = (this->eccmode == NAND_ECC_HW12_2048) ? 4 : 1;
- region = 1;
+ region = (CFG_DAVINCI_NANDCE - 1);
while (n--) {
tmp = nand_davinci_readecc(mtd, region);
*ecc_code++ = tmp;
@@ -311,40 +311,9 @@ static int nand_davinci_waitfunc(struct mtd_info
*mtd, struct nand_chip *this, i
static void nand_flash_init(void)
{
- u_int32_t acfg1 = 0x3ffffffc;
- u_int32_t acfg2 = 0x3ffffffc;
- u_int32_t acfg3 = 0x3ffffffc;
- u_int32_t acfg4 = 0x3ffffffc;
- emifregs emif_regs;
-
-
/*------------------------------------------------------------------*
- * NAND FLASH CHIP TIMEOUT @ 459 MHz
*
- *
*
- * AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz
*
- * AEMIF.CLK period = 1/76.5 MHz = 13.1 ns
*
- *
*
-
*------------------------------------------------------------------*/
- acfg1 = 0
- | (0 << 31 ) /* selectStrobe */
- | (0 << 30 ) /* extWait */
- | (1 << 26 ) /* writeSetup 10 ns */
- | (3 << 20 ) /* writeStrobe 40 ns */
- | (1 << 17 ) /* writeHold 10 ns */
- | (1 << 13 ) /* readSetup 10 ns */
- | (5 << 7 ) /* readStrobe 60 ns */
- | (1 << 4 ) /* readHold 10 ns */
- | (3 << 2 ) /* turnAround ?? ns */
- | (0 << 0 ) /* asyncSize 8-bit bus */
- ;
-
- emif_regs = (emifregs)DAVINCI_ASYNC_EMIF_CNTRL_BASE;
-
- emif_regs->AWCCR |= 0x10000000;
- emif_regs->AB1CR = acfg1; /* 0x08244128 */;
- emif_regs->AB2CR = acfg2;
- emif_regs->AB3CR = acfg3;
- emif_regs->AB4CR = acfg4;
- emif_regs->NANDFCR = 0x00000101;
+ /* All EMIF initialization is done in lowlevel_init.S
+ * and config values are in the board config files
+ */
}
int board_nand_init(struct nand_chip *nand)
diff --git a/include/asm-arm/arch-davinci/hardware.h
b/include/asm-arm/arch-davinci/hardware.h
index ebcdcfe..71c38b0 100644
--- a/include/asm-arm/arch-davinci/hardware.h
+++ b/include/asm-arm/arch-davinci/hardware.h
@@ -150,6 +150,8 @@ typedef volatile unsigned int * dv_reg_p;
#define VDD3P3V_PWDN (0x01c40048)
#define UART0_PWREMU_MGMT (0x01c20030)
+#define UART1_PWREMU_MGMT (0x01c20430)
+#define UART2_PWREMU_MGMT (0x01c20830)
#define PSC_SILVER_BULLET (0x01c41a20)
diff --git a/include/configs/davinci_dvevm.h
b/include/configs/davinci_dvevm.h
index 8ecd059..11db760 100644
--- a/include/configs/davinci_dvevm.h
+++ b/include/configs/davinci_dvevm.h
@@ -52,6 +52,8 @@
#define DV_EVM
#define CFG_NAND_SMALLPAGE
#define CFG_USE_NOR
+#define CFG_USE_INTEL_NOR /* Define this when your DVEVM has Intel
+ * flash instead of AMD flash */
/*===================*/
/* SoC Configuration */
/*===================*/
@@ -60,6 +62,24 @@
#define CFG_TIMERBASE 0x01c21400 /* use timer 0 */
#define CFG_HZ_CLOCK 27000000 /* Timer Input clock
freq */
#define CFG_HZ 1000
+#define CFG_DAVINCI_PINMUX_0 0x00000c1f
+#define CFG_DAVINCI_WAITCFG 0x00000000
+#define CFG_DAVINCI_ACFG2 0x3ffffffd /* CE configs */
+#define CFG_DAVINCI_ACFG3 0x3ffffffd
+#define CFG_DAVINCI_ACFG4 0x3ffffffd
+#define CFG_DAVINCI_ACFG5 0x3ffffffd
+#undef CFG_DAVINCI_NANDCE /* When using NAND,
define 2,3 or 4 */
+#define CFG_DAVINCI_DDRCTL 0x50006405 /* DDR timing config */
+#define CFG_DAVINCI_SDREF 0x000005c3
+#define CFG_DAVINCI_SDCFG 0x00178632 /* 8 banks */
+/*#define CFG_DAVINCI_SDCFG 0x00178622*/ /* 4 banks */
+#define CFG_DAVINCI_SDTIM0 0x28923211
+#define CFG_DAVINCI_SDTIM1 0x0016c722
+#define CFG_DAVINCI_MMARG_BRF0 0x00444400
+#define CFG_DAVINCI_PLL1_PLLM 0x15 /* DM6446 = 0x15, DM6441
= 0x12, DM6441_LV = 0x0e */
+#define CFG_DAVINCI_PLL2_PLLM 0x17 /* 162 MHz */
+#define CFG_DAVINCI_PLL2_DIV1 0x0b /* 54 MHz */
+#define CFG_DAVINCI_PLL2_DIV2 0x01
/*====================================================*/
/* EEPROM definitions for Atmel 24C256BN SEEPROM chip */
/* on Sonata/DV_EVM board. No EEPROM on schmoogie. */
@@ -143,20 +163,27 @@
#define CFG_FLASH_CFI_DRIVER
#define CFG_FLASH_CFI
#define CFG_MAX_FLASH_BANKS 1 /* max number of flash
banks */
-#define CFG_FLASH_SECT_SZ 0x10000 /* 64KB sect size AMD
Flash */
-#define CFG_ENV_OFFSET (CFG_FLASH_SECT_SZ*3)
+#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x40000)
+#define CFG_ENV_OFFSET (CFG_ENV_ADDR)
+#define CFG_FLASH_USE_BUFFER_WRITE 1 /* use buffered writes
(20x faster) */
#define PHYS_FLASH_1 0x02000000 /* CS2 Base address
*/
#define CFG_FLASH_BASE PHYS_FLASH_1 /* Flash Base for U-Boot
*/
#define PHYS_FLASH_SIZE 0x2000000 /* Flash size
32MB */
#define CFG_MAX_FLASH_SECT (PHYS_FLASH_SIZE/CFG_FLASH_SECT_SZ)
#define CFG_ENV_SECT_SIZE CFG_FLASH_SECT_SZ /* Env sector
Size */
+#ifdef CFG_USE_INTEL_NOR
+#define CFG_FLASH_SECT_SZ 0x20000 /* 128KB sect size
INTEL Flash */
+#define CFG_FLASH_PROTECTION 1
+#else
+#define CFG_FLASH_SECT_SZ 0x10000 /* 64KB sect size AMD
Flash */
+#endif
#endif
/*==============================*/
/* U-Boot general configuration */
/*==============================*/
#undef CONFIG_USE_IRQ /* No IRQ/FIQ in U-Boot
*/
#define CONFIG_MISC_INIT_R
-#undef CONFIG_BOOTDELAY
+#undef CONFIG_BOOTDELAY
#define CONFIG_BOOTFILE "uImage" /* Boot file
name */
#define CFG_PROMPT "U-Boot > " /* Monitor Command
Prompt */
#define CFG_CBSIZE 1024 /* Console I/O Buffer
Size */
diff --git a/include/configs/davinci_schmoogie.h
b/include/configs/davinci_schmoogie.h
index 96c9a30..970fd19 100644
--- a/include/configs/davinci_schmoogie.h
+++ b/include/configs/davinci_schmoogie.h
@@ -35,6 +35,24 @@
#define CFG_TIMERBASE 0x01c21400 /* use timer 0 */
#define CFG_HZ_CLOCK 27000000 /* Timer Input clock
freq */
#define CFG_HZ 1000
+#define CFG_DAVINCI_PINMUX_0 0x00000c1f
+#define CFG_DAVINCI_WAITCFG 0x00000000
+#define CFG_DAVINCI_ACFG2 0x3ffffffd /* CE configs */
+#define CFG_DAVINCI_ACFG3 0x3ffffffd
+#define CFG_DAVINCI_ACFG4 0x3ffffffd
+#define CFG_DAVINCI_ACFG5 0x3ffffffd
+#undef CFG_DAVINCI_NANDCE /* When using NAND,
define 2,3 or 4 */
+#define CFG_DAVINCI_DDRCTL 0x50006405 /* DDR timing config */
+#define CFG_DAVINCI_SDREF 0x000005c3
+/*#define CFG_DAVINCI_SDCFG 0x00178632*/ /* 8 banks */
+#define CFG_DAVINCI_SDCFG 0x00178622 /* 4 banks */
+#define CFG_DAVINCI_SDTIM0 0x28923211
+#define CFG_DAVINCI_SDTIM1 0x0016c722
+#define CFG_DAVINCI_MMARG_BRF0 0x00444400
+#define CFG_DAVINCI_PLL1_PLLM 0x15 /* DM6446 = 0x15, DM6441
= 0x12, DM6441_LV = 0x0e */
+#define CFG_DAVINCI_PLL2_PLLM 0x17 /* 162 MHz */
+#define CFG_DAVINCI_PLL2_DIV1 0x0b /* 54 MHz */
+#define CFG_DAVINCI_PLL2_DIV2 0x01
/*=============*/
/* Memory Info */
/*=============*/
@@ -46,7 +64,6 @@
#define CONFIG_STACKSIZE (256*1024) /* regular stack */
#define PHYS_SDRAM_1 0x80000000 /* DDR Start */
#define PHYS_SDRAM_1_SIZE 0x08000000 /* DDR size 128MB */
-#define DDR_4BANKS /* 4-bank DDR2 (128MB)
*/
/*====================*/
/* Serial Driver info */
/*====================*/
diff --git a/include/configs/davinci_sonata.h
b/include/configs/davinci_sonata.h
index de8c4fa..5201a48 100644
--- a/include/configs/davinci_sonata.h
+++ b/include/configs/davinci_sonata.h
@@ -60,6 +60,24 @@
#define CFG_TIMERBASE 0x01c21400 /* use timer 0 */
#define CFG_HZ_CLOCK 27000000 /* Timer Input clock
freq */
#define CFG_HZ 1000
+#define CFG_DAVINCI_PINMUX_0 0x00000c1f
+#define CFG_DAVINCI_WAITCFG 0x00000000
+#define CFG_DAVINCI_ACFG2 0x3ffffffd /* CE configs */
+#define CFG_DAVINCI_ACFG3 0x3ffffffd
+#define CFG_DAVINCI_ACFG4 0x3ffffffd
+#define CFG_DAVINCI_ACFG5 0x3ffffffd
+#undef CFG_DAVINCI_NANDCE /* When using NAND,
define 2,3 or 4 */
+#define CFG_DAVINCI_DDRCTL 0x50006405 /* DDR timing config */
+#define CFG_DAVINCI_SDREF 0x000005c3
+#define CFG_DAVINCI_SDCFG 0x00178632 /* 8 banks */
+/*#define CFG_DAVINCI_SDCFG 0x00178622*/ /* 4 banks */
+#define CFG_DAVINCI_SDTIM0 0x28923211
+#define CFG_DAVINCI_SDTIM1 0x0016c722
+#define CFG_DAVINCI_MMARG_BRF0 0x00444400
+#define CFG_DAVINCI_PLL1_PLLM 0x15 /* DM6446 = 0x15, DM6441
= 0x12, DM6441_LV = 0x0e */
+#define CFG_DAVINCI_PLL2_PLLM 0x17 /* 162 MHz */
+#define CFG_DAVINCI_PLL2_DIV1 0x0b /* 54 MHz */
+#define CFG_DAVINCI_PLL2_DIV2 0x01
/*====================================================*/
/* EEPROM definitions for Atmel 24C256BN SEEPROM chip */
/* on Sonata/DV_EVM board. No EEPROM on schmoogie. */
--
1.5.3.7
Pieter Voorthuijsen
Prodrive B.V.
Science Park Eindhoven
P.O. box 28030
5602 JA Eindhoven
The Netherlands
Email pieter.voorthuijsen(a)prodrive.nl
Tel: +31-40-2676258
Fax: +31-40-2676201
1
0

[U-Boot-Users] [PATCH v2 9/9] mpc83xx: enable the SATA interface on mpc837xemds board
by Dave Liu 20 Mar '08
by Dave Liu 20 Mar '08
20 Mar '08
Enable the first two SATA interfaces on MPC837xEMDS board,
The two SATA ports are on LYNX1. (SATA0/1 on J4/5)
Signed-off-by: Dave Liu <daveliu(a)freescale.com>
---
include/configs/MPC837XEMDS.h | 23 +++++++++++++++++++++++
1 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/include/configs/MPC837XEMDS.h b/include/configs/MPC837XEMDS.h
index 2ac3d37..f17a2d8 100644
--- a/include/configs/MPC837XEMDS.h
+++ b/include/configs/MPC837XEMDS.h
@@ -338,6 +338,29 @@
#define CONFIG_FSL_SERDES1_VDD_1V 1
/*
+ * SATA
+ */
+#define CONFIG_LIBATA
+#define CONFIG_FSL_SATA
+
+#define CFG_SATA_MAX_DEVICE 2
+#define CONFIG_SATA1
+#define CFG_SATA1_OFFSET 0x18000
+#define CFG_SATA1 (CFG_IMMR + CFG_SATA1_OFFSET)
+#define CFG_SATA1_FLAGS FLAGS_DMA
+#define CONFIG_SATA2
+#define CFG_SATA2_OFFSET 0x19000
+#define CFG_SATA2 (CFG_IMMR + CFG_SATA2_OFFSET)
+#define CFG_SATA2_FLAGS FLAGS_DMA
+
+#ifdef CONFIG_FSL_SATA
+#define CONFIG_LBA48
+#define CONFIG_CMD_SATA
+#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_EXT2
+#endif
+
+/*
* General PCI
* Addresses are mapped 1-1.
*/
--
1.5.4.rc4
1
0

[U-Boot-Users] [PATCH v2 8/9] drivers: Add the support for Freescale SATA controller
by Dave Liu 20 Mar '08
by Dave Liu 20 Mar '08
20 Mar '08
Add the Freescale on-chip SATA controller driver to u-boot,
The SATA controller is used on the 837x and 8315 targets,
The driver can be used to load kernel, fs and dtb.
The features list:
- 1.5/3 Gbps link speed
- LBA48, LBA28 support
- DMA and FPDMA support
- Two ports support
Signed-off-by: Dave Liu <daveliu(a)freescale.com>
---
drivers/block/Makefile | 1 +
drivers/block/fsl_sata.c | 921 ++++++++++++++++++++++++++++++++++++++++++++++
drivers/block/fsl_sata.h | 374 +++++++++++++++++++
3 files changed, 1296 insertions(+), 0 deletions(-)
create mode 100644 drivers/block/fsl_sata.c
create mode 100644 drivers/block/fsl_sata.h
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index d63ca2d..dca3547 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -27,6 +27,7 @@ LIB := $(obj)libblock.a
COBJS-y += ahci.o
COBJS-y += ata_piix.o
+COBJS-$(CONFIG_FSL_SATA) += fsl_sata.o
COBJS-$(CONFIG_LIBATA) += libata.o
COBJS-y += sil680.o
COBJS-y += sym53c8xx.o
diff --git a/drivers/block/fsl_sata.c b/drivers/block/fsl_sata.c
new file mode 100644
index 0000000..df00446
--- /dev/null
+++ b/drivers/block/fsl_sata.c
@@ -0,0 +1,921 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc.
+ * Dave Liu <daveliu(a)freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <libata.h>
+#include <fis.h>
+#include "fsl_sata.h"
+
+extern block_dev_desc_t sata_dev_desc[CFG_SATA_MAX_DEVICE];
+
+#ifndef CFG_SATA1_FLAGS
+ #define CFG_SATA1_FLAGS FLAGS_DMA
+#endif
+#ifndef CFG_SATA2_FLAGS
+ #define CFG_SATA2_FLAGS FLAGS_DMA
+#endif
+
+static struct fsl_sata_info fsl_sata_info[] = {
+#ifdef CONFIG_SATA1
+ {CFG_SATA1, CFG_SATA1_FLAGS},
+#else
+ {0, 0},
+#endif
+#ifdef CONFIG_SATA2
+ {CFG_SATA2, CFG_SATA2_FLAGS},
+#else
+ {0, 0},
+#endif
+};
+
+static inline void mdelay(unsigned long msec)
+{
+ unsigned long i;
+ for (i = 0; i < msec; i++)
+ udelay(1000);
+}
+
+static inline void sdelay(unsigned long sec)
+{
+ unsigned long i;
+ for (i = 0; i < sec; i++)
+ mdelay(1000);
+}
+
+void dprint_buffer(unsigned char *buf, int len)
+{
+ int i, j;
+
+ i = 0;
+ j = 0;
+ printf("\n\r");
+
+ for (i = 0; i < len; i++) {
+ printf("%02x ", *buf++);
+ j++;
+ if (j == 16) {
+ printf("\n\r");
+ j = 0;
+ }
+ }
+ printf("\n\r");
+}
+
+static void fsl_sata_dump_sfis(struct sfis *s)
+{
+ printf("Status FIS dump:\n\r");
+ printf("fis_type: %02x\n\r", s->fis_type);
+ printf("pm_port_i: %02x\n\r", s->pm_port_i);
+ printf("status: %02x\n\r", s->status);
+ printf("error: %02x\n\r", s->error);
+ printf("lba_low: %02x\n\r", s->lba_low);
+ printf("lba_mid: %02x\n\r", s->lba_mid);
+ printf("lba_high: %02x\n\r", s->lba_high);
+ printf("device: %02x\n\r", s->device);
+ printf("lba_low_exp: %02x\n\r", s->lba_low_exp);
+ printf("lba_mid_exp: %02x\n\r", s->lba_mid_exp);
+ printf("lba_high_exp: %02x\n\r", s->lba_high_exp);
+ printf("res1: %02x\n\r", s->res1);
+ printf("sector_count: %02x\n\r", s->sector_count);
+ printf("sector_count_exp: %02x\n\r", s->sector_count_exp);
+}
+
+static int ata_wait_register(volatile unsigned *addr, u32 mask,
+ u32 val, u32 timeout_msec)
+{
+ int i;
+ u32 temp;
+
+ for (i = 0; (((temp = in_le32(addr)) & mask) != val)
+ && i < timeout_msec; i++)
+ mdelay(1);
+ return (i < timeout_msec) ? 0 : -1;
+}
+
+static int fsl_sata_init(int dev)
+{
+ u32 length, align;
+ cmd_hdr_tbl_t *cmd_hdr;
+ u32 cda;
+ u32 val32;
+ fsl_sata_reg_t *reg;
+ u32 sig;
+ int i;
+ fsl_sata_t *sata;
+
+ if (dev < 0 || dev > (CFG_SATA_MAX_DEVICE - 1)) {
+ printf("the sata index %d is out of ranges\n\r", dev);
+ return -1;
+ }
+
+ /* Allocate SATA device driver struct */
+ sata = (fsl_sata_t *)malloc(sizeof(fsl_sata_t));
+ if (!sata) {
+ printf("alloc the sata device struct failed\n\r");
+ return -1;
+ }
+ /* Zero all of the device driver struct */
+ memset((void *)sata, 0, sizeof(fsl_sata_t));
+
+ /* Save the private struct to block device struct */
+ sata_dev_desc[dev].priv = (void *)sata;
+
+ sprintf(sata->name, "SATA%d", dev);
+
+ /* Set the controller register base address to device struct */
+ reg = (fsl_sata_reg_t *)(fsl_sata_info[dev].sata_reg_base);
+ sata->reg_base = reg;
+
+ /* Allocate the command header table, 4 bytes aligned */
+ length = sizeof(struct cmd_hdr_tbl);
+ align = SATA_HC_CMD_HDR_TBL_ALIGN;
+ sata->cmd_hdr_tbl_offset = (void *)malloc(length + align);
+ if (!sata) {
+ printf("alloc the command header failed\n\r");
+ return -1;
+ }
+
+ cmd_hdr = (cmd_hdr_tbl_t *)(((u32)sata->cmd_hdr_tbl_offset + align)
+ & ~(align - 1));
+ sata->cmd_hdr = cmd_hdr;
+
+ /* Zero all of the command header table */
+ memset((void *)sata->cmd_hdr_tbl_offset, 0, length + align);
+
+ /* Allocate command descriptor for all command */
+ length = sizeof(struct cmd_desc) * SATA_HC_MAX_CMD;
+ align = SATA_HC_CMD_DESC_ALIGN;
+ sata->cmd_desc_offset = (void *)malloc(length + align);
+ if (!sata->cmd_desc_offset) {
+ printf("alloc the command descriptor failed\n\r");
+ return -1;
+ }
+ sata->cmd_desc = (cmd_desc_t *)(((u32)sata->cmd_desc_offset + align)
+ & ~(align - 1));
+ /* Zero all of command descriptor */
+ memset((void *)sata->cmd_desc_offset, 0, length + align);
+
+ /* Link the command descriptor to command header */
+ for (i = 0; i < SATA_HC_MAX_CMD; i++) {
+ cda = ((u32)sata->cmd_desc + SATA_HC_CMD_DESC_SIZE * i)
+ & ~(CMD_HDR_CDA_ALIGN - 1);
+ cmd_hdr->cmd_slot[i].cda = cpu_to_le32(cda);
+ }
+
+ /* To have safe state, force the controller offline */
+ val32 = in_le32(®->hcontrol);
+ val32 &= ~HCONTROL_ONOFF;
+ val32 |= HCONTROL_FORCE_OFFLINE;
+ out_le32(®->hcontrol, val32);
+
+ /* Wait the controller offline */
+ ata_wait_register(®->hstatus, HSTATUS_ONOFF, 0, 1000);
+
+ /* Set the command header base address to CHBA register to tell DMA */
+ out_le32(®->chba, (u32)cmd_hdr & ~0x3);
+
+ /* Snoop for the command header */
+ val32 = in_le32(®->hcontrol);
+ val32 |= HCONTROL_HDR_SNOOP;
+ out_le32(®->hcontrol, val32);
+
+ /* Disable all of interrupts */
+ val32 = in_le32(®->hcontrol);
+ val32 &= ~HCONTROL_INT_EN_ALL;
+ out_le32(®->hcontrol, val32);
+
+ /* Clear all of interrupts */
+ val32 = in_le32(®->hstatus);
+ out_le32(®->hstatus, val32);
+
+ /* Set the ICC, no interrupt coalescing */
+ out_le32(®->icc, 0x01000000);
+
+ /* No PM attatched, the SATA device direct connect */
+ out_le32(®->cqpmp, 0);
+
+ /* Clear SError register */
+ val32 = in_le32(®->serror);
+ out_le32(®->serror, val32);
+
+ /* Clear CER register */
+ val32 = in_le32(®->cer);
+ out_le32(®->cer, val32);
+
+ /* Clear DER register */
+ val32 = in_le32(®->der);
+ out_le32(®->der, val32);
+
+ /* No device detection or initialization action requested */
+ out_le32(®->scontrol, 0x00000300);
+
+ /* Configure the transport layer, default value */
+ out_le32(®->transcfg, 0x08000016);
+
+ /* Configure the link layer, default value */
+ out_le32(®->linkcfg, 0x0000ff34);
+
+ /* Bring the controller online */
+ val32 = in_le32(®->hcontrol);
+ val32 |= HCONTROL_ONOFF;
+ out_le32(®->hcontrol, val32);
+
+ mdelay(100);
+
+ /* print sata device name */
+ if (!dev)
+ printf("%s ", sata->name);
+ else
+ printf(" %s ", sata->name);
+
+ /* Check PHYRDY */
+ val32 = in_le32(®->hstatus);
+ if (val32 & HSTATUS_PHY_RDY) {
+ sata->link = 1;
+ } else {
+ sata->link = 0;
+ printf("(No RDY)\n\r");
+ return -1;
+ }
+
+ if (val32 & HSTATUS_SIGNATURE) {
+ sig = in_le32(®->sig);
+ debug("Signature updated, the sig =%08x\n\r", sig);
+ sata->ata_device_type = ata_dev_classify(sig);
+ }
+
+ /* Check the speed */
+ val32 = in_le32(®->sstatus);
+ if ((val32 & SSTATUS_SPD_MASK) == SSTATUS_SPD_GEN1)
+ printf("(1.5 Gbps)\n\r");
+ else if ((val32 & SSTATUS_SPD_MASK) == SSTATUS_SPD_GEN2)
+ printf("(3 Gbps)\n\r");
+
+ return 0;
+}
+
+/* Hardware reset, like Power-on and COMRESET */
+void fsl_sata_hardware_reset(u32 reg_base)
+{
+ fsl_sata_reg_t *reg = (fsl_sata_reg_t *)reg_base;
+ u32 scontrol;
+
+ /* Disable the SATA interface and put PHY offline */
+ scontrol = in_le32(®->scontrol);
+ scontrol = (scontrol & 0x0f0) | 0x304;
+ out_le32(®->scontrol, scontrol);
+
+ /* No speed strict */
+ scontrol = in_le32(®->scontrol);
+ scontrol = scontrol & ~0x0f0;
+ out_le32(®->scontrol, scontrol);
+
+ /* Issue PHY wake/reset, Hardware_reset_asserted */
+ scontrol = in_le32(®->scontrol);
+ scontrol = (scontrol & 0x0f0) | 0x301;
+ out_le32(®->scontrol, scontrol);
+
+ mdelay(100);
+
+ /* Resume PHY, COMRESET negated, the device initialize hardware
+ * and execute diagnostics, send good status-signature to host,
+ * which is D2H register FIS, and then the device enter idle state.
+ */
+ scontrol = in_le32(®->scontrol);
+ scontrol = (scontrol & 0x0f0) | 0x300;
+ out_le32(®->scontrol, scontrol);
+
+ mdelay(100);
+ return;
+}
+
+static void fsl_sata_dump_regs(fsl_sata_reg_t *reg)
+{
+ printf("\n\rSATA: %08x\n\r", (u32)reg);
+ printf("CQR: %08x\n\r", in_le32(®->cqr));
+ printf("CAR: %08x\n\r", in_le32(®->car));
+ printf("CCR: %08x\n\r", in_le32(®->ccr));
+ printf("CER: %08x\n\r", in_le32(®->cer));
+ printf("CQR: %08x\n\r", in_le32(®->cqr));
+ printf("DER: %08x\n\r", in_le32(®->der));
+ printf("CHBA: %08x\n\r", in_le32(®->chba));
+ printf("HStatus: %08x\n\r", in_le32(®->hstatus));
+ printf("HControl: %08x\n\r", in_le32(®->hcontrol));
+ printf("CQPMP: %08x\n\r", in_le32(®->cqpmp));
+ printf("SIG: %08x\n\r", in_le32(®->sig));
+ printf("ICC: %08x\n\r", in_le32(®->icc));
+ printf("SStatus: %08x\n\r", in_le32(®->sstatus));
+ printf("SError: %08x\n\r", in_le32(®->serror));
+ printf("SControl: %08x\n\r", in_le32(®->scontrol));
+ printf("SNotification: %08x\n\r", in_le32(®->snotification));
+ printf("TransCfg: %08x\n\r", in_le32(®->transcfg));
+ printf("TransStatus: %08x\n\r", in_le32(®->transstatus));
+ printf("LinkCfg: %08x\n\r", in_le32(®->linkcfg));
+ printf("LinkCfg1: %08x\n\r", in_le32(®->linkcfg1));
+ printf("LinkCfg2: %08x\n\r", in_le32(®->linkcfg2));
+ printf("LinkStatus: %08x\n\r", in_le32(®->linkstatus));
+ printf("LinkStatus1: %08x\n\r", in_le32(®->linkstatus1));
+ printf("PhyCtrlCfg: %08x\n\r", in_le32(®->phyctrlcfg));
+ printf("SYSPR: %08x\n\r", in_be32(®->syspr));
+}
+
+static int fsl_ata_exec_ata_cmd(struct fsl_sata *sata, struct cfis *cfis,
+ int is_ncq, int tag, u8 *buffer, u32 len)
+{
+ cmd_hdr_entry_t *cmd_hdr;
+ cmd_desc_t *cmd_desc;
+ sata_fis_h2d_t *h2d;
+ prd_entry_t *prde;
+ u32 ext_c_ddc;
+ u32 prde_count;
+ u32 val32;
+ u32 ttl;
+ fsl_sata_reg_t *reg = sata->reg_base;
+ int i;
+
+ /* Check xfer length */
+ if (len > SATA_HC_MAX_XFER_LEN) {
+ printf("max transfer length is 64MB\n\r");
+ return 0;
+ }
+
+ /* Setup the command descriptor */
+ cmd_desc = sata->cmd_desc + tag;
+
+ /* Get the pointer cfis of command descriptor */
+ h2d = (sata_fis_h2d_t *)cmd_desc->cfis;
+
+ /* Zero the cfis of command descriptor */
+ memset((void *)h2d, 0, SATA_HC_CMD_DESC_CFIS_SIZE);
+
+ /* Copy the cfis from user to command descriptor */
+ h2d->fis_type = cfis->fis_type;
+ h2d->pm_port_c = cfis->pm_port_c;
+ h2d->command = cfis->command;
+
+ h2d->features = cfis->features;
+ h2d->features_exp = cfis->features_exp;
+
+ h2d->lba_low = cfis->lba_low;
+ h2d->lba_mid = cfis->lba_mid;
+ h2d->lba_high = cfis->lba_high;
+ h2d->lba_low_exp = cfis->lba_low_exp;
+ h2d->lba_mid_exp = cfis->lba_mid_exp;
+ h2d->lba_high_exp = cfis->lba_high_exp;
+
+ if (!is_ncq) {
+ h2d->sector_count = cfis->sector_count;
+ h2d->sector_count_exp = cfis->sector_count_exp;
+ } else { /* NCQ */
+ h2d->sector_count = (u8)(tag << 3);
+ }
+
+ h2d->device = cfis->device;
+ h2d->control = cfis->control;
+
+ /* Setup the PRD table */
+ prde = (prd_entry_t *)cmd_desc->prdt;
+ memset((void *)prde, 0, sizeof(struct prdt));
+
+ prde_count = 0;
+ ttl = len;
+ for (i = 0; i < SATA_HC_MAX_PRD_DIRECT; i++) {
+ if (!len)
+ break;
+ prde->dba = cpu_to_le32((u32)buffer & ~0x3);
+ debug("dba = %08x\n\r", (u32)buffer);
+
+ if (len < PRD_ENTRY_MAX_XFER_SZ) {
+ ext_c_ddc = PRD_ENTRY_DATA_SNOOP | len;
+ debug("ext_c_ddc1 = %08x, len = %08x\n\r", ext_c_ddc, len);
+ prde->ext_c_ddc = cpu_to_le32(ext_c_ddc);
+ prde_count++;
+ prde++;
+ break;
+ } else {
+ ext_c_ddc = PRD_ENTRY_DATA_SNOOP; /* 4M bytes */
+ debug("ext_c_ddc2 = %08x, len = %08x\n\r", ext_c_ddc, len);
+ prde->ext_c_ddc = cpu_to_le32(ext_c_ddc);
+ buffer += PRD_ENTRY_MAX_XFER_SZ;
+ len -= PRD_ENTRY_MAX_XFER_SZ;
+ prde_count++;
+ prde++;
+ }
+ }
+
+ /* Setup the command slot of cmd hdr */
+ cmd_hdr = (cmd_hdr_entry_t *)&sata->cmd_hdr->cmd_slot[tag];
+
+ cmd_hdr->cda = cpu_to_le32((u32)cmd_desc & ~0x3);
+
+ val32 = prde_count << CMD_HDR_PRD_ENTRY_SHIFT;
+ val32 |= sizeof(sata_fis_h2d_t);
+ cmd_hdr->prde_fis_len = cpu_to_le32(val32);
+
+ cmd_hdr->ttl = cpu_to_le32(ttl);
+
+ if (!is_ncq) {
+ val32 = CMD_HDR_ATTR_RES | CMD_HDR_ATTR_SNOOP;
+ } else {
+ val32 = CMD_HDR_ATTR_RES | CMD_HDR_ATTR_SNOOP | CMD_HDR_ATTR_FPDMA;
+ }
+
+ tag &= CMD_HDR_ATTR_TAG;
+ val32 |= tag;
+
+ debug("attribute = %08x\n\r", val32);
+ cmd_hdr->attribute = cpu_to_le32(val32);
+
+ /* Make sure cmd desc and cmd slot valid before commmand issue */
+ sync();
+
+ /* PMP*/
+ val32 = (u32)(h2d->pm_port_c & 0x0f);
+ out_le32(®->cqpmp, val32);
+
+ /* Wait no active */
+ if (ata_wait_register(®->car, (1 << tag), 0, 10000))
+ printf("Wait no active time out\n\r");
+
+ /* Issue command */
+ if (!(in_le32(®->cqr) & (1 << tag))) {
+ val32 = 1 << tag;
+ out_le32(®->cqr, val32);
+ }
+
+ /* Wait command completed for 10s */
+ if (ata_wait_register(®->ccr, (1 << tag), (1 << tag), 10000)) {
+ if (!is_ncq)
+ printf("Non-NCQ command time out\n\r");
+ else
+ printf("NCQ command time out\n\r");
+ }
+
+ val32 = in_le32(®->cer);
+
+ if (val32) {
+ u32 der;
+ fsl_sata_dump_sfis((struct sfis *)cmd_desc->sfis);
+ printf("CE at device\n\r");
+ fsl_sata_dump_regs(reg);
+ der = in_le32(®->der);
+ out_le32(®->cer, val32);
+ out_le32(®->der, der);
+ }
+
+ /* Clear complete flags */
+ val32 = in_le32(®->ccr);
+ out_le32(®->ccr, val32);
+
+ return len;
+}
+
+static int fsl_ata_exec_reset_cmd(struct fsl_sata *sata, struct cfis *cfis,
+ int tag, u8 *buffer, u32 len)
+{
+ return 0;
+}
+
+static int fsl_sata_exec_cmd(struct fsl_sata *sata, struct cfis *cfis,
+ enum cmd_type command_type, int tag, u8 *buffer, u32 len)
+{
+ int rc;
+
+ if (tag > SATA_HC_MAX_CMD || tag < 0) {
+ printf("tag is out of range, tag=\n\r", tag);
+ return -1;
+ }
+
+ switch (command_type) {
+ case CMD_ATA:
+ rc = fsl_ata_exec_ata_cmd(sata, cfis, 0, tag, buffer, len);
+ return rc;
+ case CMD_RESET:
+ rc = fsl_ata_exec_reset_cmd(sata, cfis, tag, buffer, len);
+ return rc;
+ case CMD_NCQ:
+ rc = fsl_ata_exec_ata_cmd(sata, cfis, 1, tag, buffer, len);
+ return rc;
+ case CMD_ATAPI:
+ case CMD_VENDOR_BIST:
+ case CMD_BIST:
+ printf("not support now\n\r");
+ return -1;
+ default:
+ break;
+ }
+
+ return -1;
+}
+
+static void fsl_sata_identify(int dev, u16 *id)
+{
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+ struct sata_fis_h2d h2d;
+ struct cfis *cfis;
+
+ cfis = (struct cfis *)&h2d;
+ memset((void *)cfis, 0, sizeof(struct cfis));
+
+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+ cfis->pm_port_c = 0x80; /* is command */
+ cfis->command = ATA_CMD_ID_ATA;
+
+ fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, (u8 *)id, ATA_ID_WORDS * 2);
+ ata_swap_buf_le16(id, ATA_ID_WORDS);
+}
+
+static void fsl_sata_xfer_mode(int dev, u16 *id)
+{
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+
+ sata->pio = id[ATA_ID_PIO_MODES];
+ sata->mwdma = id[ATA_ID_MWDMA_MODES];
+ sata->udma = id[ATA_ID_UDMA_MODES];
+ debug("pio %04x, mwdma %04x, udma %04x\n\r", sata->pio, sata->mwdma, sata->udma);
+}
+
+static void fsl_sata_set_features(int dev)
+{
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+ struct sata_fis_h2d h2d;
+ struct cfis *cfis;
+ u8 udma_cap;
+
+ cfis = (struct cfis *)&h2d;
+ memset((void *)cfis, 0, sizeof(struct cfis));
+
+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+ cfis->pm_port_c = 0x80; /* is command */
+ cfis->command = ATA_CMD_SET_FEATURES;
+ cfis->features = SETFEATURES_XFER;
+
+ /* First check the device capablity */
+ udma_cap = (u8)(sata->udma & 0xff);
+ debug("udma_cap %02x\n\r", udma_cap);
+
+ if (udma_cap == ATA_UDMA6)
+ cfis->sector_count = XFER_UDMA_6;
+ if (udma_cap == ATA_UDMA5)
+ cfis->sector_count = XFER_UDMA_5;
+ if (udma_cap == ATA_UDMA4)
+ cfis->sector_count = XFER_UDMA_4;
+ if (udma_cap == ATA_UDMA3)
+ cfis->sector_count = XFER_UDMA_3;
+
+ fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0);
+}
+
+static u32 fsl_sata_rw_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write)
+{
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+ struct sata_fis_h2d h2d;
+ struct cfis *cfis;
+ u32 block;
+
+ block = start;
+ cfis = (struct cfis *)&h2d;
+
+ memset((void *)cfis, 0, sizeof(struct cfis));
+
+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+ cfis->pm_port_c = 0x80; /* is command */
+ cfis->command = (is_write) ? ATA_CMD_WRITE_DMA : ATA_CMD_READ_DMA;
+ cfis->device = ATA_LBA;
+
+ cfis->device |= (block >> 24) & 0xf;
+ cfis->lba_high = (block >> 16) & 0xff;
+ cfis->lba_mid = (block >> 8) & 0xff;
+ cfis->lba_low = block & 0xff;
+ cfis->sector_count = (u8)(blkcnt & 0xff);
+
+ fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, buffer, ATA_SECT_SIZE * blkcnt);
+ return blkcnt;
+}
+
+void fsl_sata_flush_cache(int dev)
+{
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+ struct sata_fis_h2d h2d;
+ struct cfis *cfis;
+
+ cfis = (struct cfis *)&h2d;
+
+ memset((void *)cfis, 0, sizeof(struct cfis));
+
+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+ cfis->pm_port_c = 0x80; /* is command */
+ cfis->command = ATA_CMD_FLUSH_CACHE;
+
+ fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0);
+}
+
+static u32 fsl_sata_rw_cmd_ext(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write)
+{
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+ struct sata_fis_h2d h2d;
+ struct cfis *cfis;
+ u64 block;
+
+ block = (u64)start;
+ cfis = (struct cfis *)&h2d;
+
+ memset((void *)cfis, 0, sizeof(struct cfis));
+
+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+ cfis->pm_port_c = 0x80; /* is command */
+
+ cfis->command = (is_write) ? ATA_CMD_WRITE_DMA_EXT
+ : ATA_CMD_READ_DMA_EXT;
+
+ cfis->lba_high_exp = (block >> 40) & 0xff;
+ cfis->lba_mid_exp = (block >> 32) & 0xff;
+ cfis->lba_low_exp = (block >> 24) & 0xff;
+ cfis->lba_high = (block >> 16) & 0xff;
+ cfis->lba_mid = (block >> 8) & 0xff;
+ cfis->lba_low = block & 0xff;
+ cfis->device = ATA_LBA;
+ cfis->sector_count_exp = (blkcnt >> 8) & 0xff;
+ cfis->sector_count = blkcnt & 0xff;
+
+ fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, buffer, ATA_SECT_SIZE * blkcnt);
+ return blkcnt;
+}
+
+u32 fsl_sata_rw_ncq_cmd(int dev, u32 start, u32 blkcnt, u8 *buffer, int is_write)
+{
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+ struct sata_fis_h2d h2d;
+ struct cfis *cfis;
+ int ncq_channel;
+ u64 block;
+
+ if (sata_dev_desc[dev].lba48 != 1) {
+ printf("execute FPDMA command on non-LBA48 hard disk\n\r");
+ return -1;
+ }
+
+ block = (u64)start;
+ cfis = (struct cfis *)&h2d;
+
+ memset((void *)cfis, 0, sizeof(struct cfis));
+
+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+ cfis->pm_port_c = 0x80; /* is command */
+
+ cfis->command = (is_write) ? ATA_CMD_WRITE_FPDMA_QUEUED
+ : ATA_CMD_READ_FPDMA_QUEUED;
+
+ cfis->lba_high_exp = (block >> 40) & 0xff;
+ cfis->lba_mid_exp = (block >> 32) & 0xff;
+ cfis->lba_low_exp = (block >> 24) & 0xff;
+ cfis->lba_high = (block >> 16) & 0xff;
+ cfis->lba_mid = (block >> 8) & 0xff;
+ cfis->lba_low = block & 0xff;
+
+ cfis->device = ATA_LBA;
+ cfis->features_exp = (blkcnt >> 8) & 0xff;
+ cfis->features = blkcnt & 0xff;
+
+ if (sata->queue_depth >= SATA_HC_MAX_CMD)
+ ncq_channel = SATA_HC_MAX_CMD - 1;
+ else
+ ncq_channel = sata->queue_depth - 1;
+
+ /* Use the latest queue */
+ fsl_sata_exec_cmd(sata, cfis, CMD_NCQ, ncq_channel, buffer, ATA_SECT_SIZE * blkcnt);
+ return blkcnt;
+}
+
+void fsl_sata_flush_cache_ext(int dev)
+{
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+ struct sata_fis_h2d h2d;
+ struct cfis *cfis;
+
+ cfis = (struct cfis *)&h2d;
+
+ memset((void *)cfis, 0, sizeof(struct cfis));
+
+ cfis->fis_type = SATA_FIS_TYPE_REGISTER_H2D;
+ cfis->pm_port_c = 0x80; /* is command */
+ cfis->command = ATA_CMD_FLUSH_CACHE_EXT;
+
+ fsl_sata_exec_cmd(sata, cfis, CMD_ATA, 0, NULL, 0);
+}
+
+/* Software reset, set SRST of the Device Control register */
+void fsl_sata_software_reset(int dev)
+{
+ return;
+}
+
+static void fsl_sata_init_wcache(int dev, u16 *id)
+{
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+
+ if (ata_id_has_wcache(id) && ata_id_wcache_enabled(id))
+ sata->wcache = 1;
+ if (ata_id_has_flush(id))
+ sata->flush = 1;
+ if (ata_id_has_flush_ext(id))
+ sata->flush_ext = 1;
+}
+
+static int fsl_sata_get_wcache(int dev)
+{
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+ return sata->wcache;
+}
+
+static int fsl_sata_get_flush(int dev)
+{
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+ return sata->flush;
+}
+
+static int fsl_sata_get_flush_ext(int dev)
+{
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+ return sata->flush_ext;
+}
+
+u32 ata_low_level_rw_lba48(int dev, u32 blknr, u32 blkcnt, void *buffer, int is_write)
+{
+ u32 start, blks;
+ u8 *addr;
+ int max_blks;
+
+ start = blknr;
+ blks = blkcnt;
+ addr = (u8 *)buffer;
+
+ max_blks = ATA_MAX_SECTORS_LBA48;
+ do {
+ if (blks > max_blks) {
+ if (fsl_sata_info[dev].flags != FLAGS_FPDMA)
+ fsl_sata_rw_cmd_ext(dev, start, max_blks, addr, is_write);
+ else
+ fsl_sata_rw_ncq_cmd(dev, start, max_blks, addr, is_write);
+ start += max_blks;
+ blks -= max_blks;
+ addr += ATA_SECT_SIZE * max_blks;
+ } else {
+ if (fsl_sata_info[dev].flags != FLAGS_FPDMA)
+ fsl_sata_rw_cmd_ext(dev, start, blks, addr, is_write);
+ else
+ fsl_sata_rw_ncq_cmd(dev, start, blks, addr, is_write);
+ start += blks;
+ blks = 0;
+ addr += ATA_SECT_SIZE * blks;
+ }
+ } while (blks != 0);
+
+ return blkcnt;
+}
+
+u32 ata_low_level_rw_lba28(int dev, u32 blknr, u32 blkcnt, void *buffer, int is_write)
+{
+ u32 start, blks;
+ u8 *addr;
+ int max_blks;
+
+ start = blknr;
+ blks = blkcnt;
+ addr = (u8 *)buffer;
+
+ max_blks = ATA_MAX_SECTORS;
+ do {
+ if (blks > max_blks) {
+ fsl_sata_rw_cmd(dev, start, max_blks, addr, is_write);
+ start += max_blks;
+ blks -= max_blks;
+ addr += ATA_SECT_SIZE * max_blks;
+ } else {
+ fsl_sata_rw_cmd(dev, start, blks, addr, is_write);
+ start += blks;
+ blks = 0;
+ addr += ATA_SECT_SIZE * blks;
+ }
+ } while (blks != 0);
+
+ return blkcnt;
+}
+
+/********************************************************************
+ * SATA interface between low level driver and command layer
+ *******************************************************************/
+u32 sata_low_level_read(int dev, u32 blknr, u32 blkcnt, void *buffer)
+{
+ u32 rc;
+
+ if (sata_dev_desc[dev].lba48)
+ rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, buffer, READ_CMD);
+ else
+ rc = ata_low_level_rw_lba28(dev, blknr, blkcnt, buffer, READ_CMD);
+ return rc;
+}
+
+u32 sata_low_level_write(int dev, u32 blknr, u32 blkcnt, void *buffer)
+{
+ u32 rc;
+
+ if (sata_dev_desc[dev].lba48) {
+ rc = ata_low_level_rw_lba48(dev, blknr, blkcnt, buffer, WRITE_CMD);
+ if (fsl_sata_get_wcache(dev) && fsl_sata_get_flush_ext(dev))
+ fsl_sata_flush_cache_ext(dev);
+ } else {
+ rc = ata_low_level_rw_lba28(dev, blknr, blkcnt, buffer, WRITE_CMD);
+ if (fsl_sata_get_wcache(dev) && fsl_sata_get_flush(dev))
+ fsl_sata_flush_cache(dev);
+ }
+ return rc;
+}
+
+int sata_low_level_init(int dev)
+{
+ return fsl_sata_init(dev);
+}
+
+int sata_low_level_scan(int dev)
+{
+ fsl_sata_t *sata = (fsl_sata_t *)sata_dev_desc[dev].priv;
+ unsigned char serial[ATA_ID_SERNO_LEN + 1];
+ unsigned char firmware[ATA_ID_FW_REV_LEN + 1];
+ unsigned char product[ATA_ID_PROD_LEN + 1];
+ u16 *id;
+ u64 n_sectors;
+
+ /* if no detected link */
+ if (!sata->link)
+ return -1;
+
+ id = (u16 *)malloc(ATA_ID_WORDS * 2);
+ if (!id) {
+ printf("id malloc failed\n\r");
+ return -1;
+ }
+
+ /* Identify device to get information */
+ fsl_sata_identify(dev, id);
+
+ /* Serial number */
+ ata_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
+ memcpy(sata_dev_desc[dev].product, serial, sizeof(serial));
+
+ /* Firmware version */
+ ata_id_c_string(id, firmware, ATA_ID_FW_REV, sizeof(firmware));
+ memcpy(sata_dev_desc[dev].revision, firmware, sizeof(firmware));
+
+ /* Product model */
+ ata_id_c_string(id, product, ATA_ID_PROD, sizeof(product));
+ memcpy(sata_dev_desc[dev].vendor, product, sizeof(product));
+
+ /* Totoal sectors */
+ n_sectors = ata_id_n_sectors(id);
+ sata_dev_desc[dev].lba = (u32)n_sectors;
+
+ /* Check if support LBA48 */
+ if (ata_id_has_lba48(id)) {
+ sata_dev_desc[dev].lba48 = 1;
+ debug("Device support LBA48\n\r");
+ }
+
+ /* Get the NCQ queue depth from device */
+ sata->queue_depth = ata_id_queue_depth(id);
+
+ /* Get the xfer mode from device */
+ fsl_sata_xfer_mode(dev, id);
+
+ /* Get the write cache status from device */
+ fsl_sata_init_wcache(dev, id);
+
+ /* Set the xfer mode to highest speed */
+ fsl_sata_set_features(dev);
+#ifdef DEBUG
+ fsl_sata_identify(dev, id);
+ ata_dump_id(id);
+#endif
+ free((void *)id);
+ return 0;
+}
diff --git a/drivers/block/fsl_sata.h b/drivers/block/fsl_sata.h
new file mode 100644
index 0000000..874c0dc
--- /dev/null
+++ b/drivers/block/fsl_sata.h
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2007-2008 Freescale Semiconductor, Inc.
+ * Dave Liu <daveliu(a)freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __FSL_SATA_H__
+#define __FSL_SATA_H__
+
+#define SATA_HC_MAX_NUM 4 /* Max host controller numbers */
+#define SATA_HC_MAX_CMD 16 /* Max command queue depth per host controller */
+#define SATA_HC_MAX_PORT 16 /* Max port number per host controller */
+
+/*
+* SATA Host Controller Registers
+*/
+typedef struct fsl_sata_reg {
+ /* SATA command registers */
+ u32 cqr; /* Command queue register */
+ u8 res1[0x4];
+ u32 car; /* Command active register */
+ u8 res2[0x4];
+ u32 ccr; /* Command completed register */
+ u8 res3[0x4];
+ u32 cer; /* Command error register */
+ u8 res4[0x4];
+ u32 der; /* Device error register */
+ u32 chba; /* Command header base address */
+ u32 hstatus; /* Host status register */
+ u32 hcontrol; /* Host control register */
+ u32 cqpmp; /* Port number queue register */
+ u32 sig; /* Signature register */
+ u32 icc; /* Interrupt coalescing control register */
+ u8 res5[0xc4];
+
+ /* SATA supperset registers */
+ u32 sstatus; /* SATA interface status register */
+ u32 serror; /* SATA interface error register */
+ u32 scontrol; /* SATA interface control register */
+ u32 snotification; /* SATA interface notification register */
+ u8 res6[0x30];
+
+ /* SATA control status registers */
+ u32 transcfg; /* Transport layer configuration */
+ u32 transstatus; /* Transport layer status */
+ u32 linkcfg; /* Link layer configuration */
+ u32 linkcfg1; /* Link layer configuration1 */
+ u32 linkcfg2; /* Link layer configuration2 */
+ u32 linkstatus; /* Link layer status */
+ u32 linkstatus1; /* Link layer status1 */
+ u32 phyctrlcfg; /* PHY control configuration */
+ u8 res7[0x2b0];
+
+ /* SATA system control registers */
+ u32 syspr; /* System priority register - big endian */
+ u8 res8[0xbec];
+} __attribute__ ((packed)) fsl_sata_reg_t;
+
+/* HStatus register
+*/
+#define HSTATUS_ONOFF 0x80000000 /* Online/offline status */
+#define HSTATUS_FORCE_OFFLINE 0x40000000 /* In process going offline */
+#define HSTATUS_BIST_ERR 0x20000000
+
+/* Fatal error */
+#define HSTATUS_MASTER_ERR 0x00004000
+#define HSTATUS_DATA_UNDERRUN 0x00002000
+#define HSTATUS_DATA_OVERRUN 0x00001000
+#define HSTATUS_CRC_ERR_TX 0x00000800
+#define HSTATUS_CRC_ERR_RX 0x00000400
+#define HSTATUS_FIFO_OVERFLOW_TX 0x00000200
+#define HSTATUS_FIFO_OVERFLOW_RX 0x00000100
+#define HSTATUS_FATAL_ERR_ALL (HSTATUS_MASTER_ERR | \
+ HSTATUS_DATA_UNDERRUN | \
+ HSTATUS_DATA_OVERRUN | \
+ HSTATUS_CRC_ERR_TX | \
+ HSTATUS_CRC_ERR_RX | \
+ HSTATUS_FIFO_OVERFLOW_TX | \
+ HSTATUS_FIFO_OVERFLOW_RX)
+/* Interrupt status */
+#define HSTATUS_FATAL_ERR 0x00000020
+#define HSTATUS_PHY_RDY 0x00000010
+#define HSTATUS_SIGNATURE 0x00000008
+#define HSTATUS_SNOTIFY 0x00000004
+#define HSTATUS_DEVICE_ERR 0x00000002
+#define HSTATUS_CMD_COMPLETE 0x00000001
+
+/* HControl register
+*/
+#define HCONTROL_ONOFF 0x80000000 /* Online or offline request */
+#define HCONTROL_FORCE_OFFLINE 0x40000000 /* Force offline request */
+#define HCONTROL_HDR_SNOOP 0x00000400 /* Command header snoop */
+#define HCONTROL_PMP_ATTACHED 0x00000200 /* Port multiplier attached */
+
+/* Interrupt enable */
+#define HCONTROL_FATAL_ERR 0x00000020
+#define HCONTROL_PHY_RDY 0x00000010
+#define HCONTROL_SIGNATURE 0x00000008
+#define HCONTROL_SNOTIFY 0x00000004
+#define HCONTROL_DEVICE_ERR 0x00000002
+#define HCONTROL_CMD_COMPLETE 0x00000001
+
+#define HCONTROL_INT_EN_ALL (HCONTROL_FATAL_ERR | \
+ HCONTROL_PHY_RDY | \
+ HCONTROL_SIGNATURE | \
+ HCONTROL_SNOTIFY | \
+ HCONTROL_DEVICE_ERR | \
+ HCONTROL_CMD_COMPLETE)
+
+/* SStatus register
+*/
+#define SSTATUS_IPM_MASK 0x00000780
+#define SSTATUS_IPM_NOPRESENT 0x00000000
+#define SSTATUS_IPM_ACTIVE 0x00000080
+#define SSTATUS_IPM_PATIAL 0x00000100
+#define SSTATUS_IPM_SLUMBER 0x00000300
+
+#define SSTATUS_SPD_MASK 0x000000f0
+#define SSTATUS_SPD_GEN1 0x00000010
+#define SSTATUS_SPD_GEN2 0x00000020
+
+#define SSTATUS_DET_MASK 0x0000000f
+#define SSTATUS_DET_NODEVICE 0x00000000
+#define SSTATUS_DET_DISCONNECT 0x00000001
+#define SSTATUS_DET_CONNECT 0x00000003
+#define SSTATUS_DET_PHY_OFFLINE 0x00000004
+
+/* SControl register
+*/
+#define SCONTROL_SPM_MASK 0x0000f000
+#define SCONTROL_SPM_GO_PARTIAL 0x00001000
+#define SCONTROL_SPM_GO_SLUMBER 0x00002000
+#define SCONTROL_SPM_GO_ACTIVE 0x00004000
+
+#define SCONTROL_IPM_MASK 0x00000f00
+#define SCONTROL_IPM_NO_RESTRICT 0x00000000
+#define SCONTROL_IPM_PARTIAL 0x00000100
+#define SCONTROL_IPM_SLUMBER 0x00000200
+#define SCONTROL_IPM_PART_SLUM 0x00000300
+
+#define SCONTROL_SPD_MASK 0x000000f0
+#define SCONTROL_SPD_NO_RESTRICT 0x00000000
+#define SCONTROL_SPD_GEN1 0x00000010
+#define SCONTROL_SPD_GEN2 0x00000020
+
+#define SCONTROL_DET_MASK 0x0000000f
+#define SCONTROL_DET_HRESET 0x00000001
+#define SCONTROL_DET_DISABLE 0x00000004
+
+/* TransCfg register
+*/
+#define TRANSCFG_DFIS_SIZE_SHIFT 16
+#define TRANSCFG_RX_WATER_MARK_MASK 0x0000001f
+
+/* PhyCtrlCfg register
+*/
+#define PHYCTRLCFG_FPRFTI_MASK 0x00000018
+#define PHYCTRLCFG_LOOPBACK_MASK 0x0000000e
+
+/*
+* Command Header Entry
+*/
+typedef struct cmd_hdr_entry {
+ u32 cda; /* Command Descriptor Address, 4 bytes aligned */
+ u32 prde_fis_len; /* Number of PRD entries and FIS length */
+ u32 ttl; /* Total transfer length */
+ u32 attribute; /* the attribute of command */
+} __attribute__ ((packed)) cmd_hdr_entry_t;
+
+#define SATA_HC_CMD_HDR_ENTRY_SIZE sizeof(struct cmd_hdr_entry)
+
+/* cda
+*/
+#define CMD_HDR_CDA_ALIGN 4
+
+/* prde_fis_len
+*/
+#define CMD_HDR_PRD_ENTRY_SHIFT 16
+#define CMD_HDR_PRD_ENTRY_MASK 0x003f0000
+#define CMD_HDR_FIS_LEN_SHIFT 2
+
+/* attribute
+*/
+#define CMD_HDR_ATTR_RES 0x00000800 /* Reserved bit, should be 1 */
+#define CMD_HDR_ATTR_VBIST 0x00000400 /* Vendor BIST */
+#define CMD_HDR_ATTR_SNOOP 0x00000200 /* Snoop enable for all descriptor */
+#define CMD_HDR_ATTR_FPDMA 0x00000100 /* FPDMA queued command */
+#define CMD_HDR_ATTR_RESET 0x00000080 /* Reset - a SRST or device reset */
+#define CMD_HDR_ATTR_BIST 0x00000040 /* BIST - require the host to enter BIST mode */
+#define CMD_HDR_ATTR_ATAPI 0x00000020 /* ATAPI command */
+#define CMD_HDR_ATTR_TAG 0x0000001f /* TAG mask */
+
+/* command type
+*/
+enum cmd_type {
+ CMD_VENDOR_BIST,
+ CMD_BIST,
+ CMD_RESET, /* SRST or device reset */
+ CMD_ATAPI,
+ CMD_NCQ,
+ CMD_ATA, /* None of all above */
+};
+
+/*
+* Command Header Table
+*/
+typedef struct cmd_hdr_tbl {
+ cmd_hdr_entry_t cmd_slot[SATA_HC_MAX_CMD];
+} __attribute__ ((packed)) cmd_hdr_tbl_t;
+
+#define SATA_HC_CMD_HDR_TBL_SIZE sizeof(struct cmd_hdr_tbl)
+#define SATA_HC_CMD_HDR_TBL_ALIGN 4
+
+/*
+* PRD entry - Physical Region Descriptor entry
+*/
+typedef struct prd_entry {
+ u32 dba; /* Data base address, 4 bytes aligned */
+ u32 res1;
+ u32 res2;
+ u32 ext_c_ddc; /* Indirect PRD flags, snoop and data word count */
+} __attribute__ ((packed)) prd_entry_t;
+
+#define SATA_HC_CMD_DESC_PRD_SIZE sizeof(struct prd_entry)
+
+/* dba
+*/
+#define PRD_ENTRY_DBA_ALIGN 4
+
+/* ext_c_ddc
+*/
+#define PRD_ENTRY_EXT 0x80000000 /* extension flag or called indirect descriptor flag */
+#define PRD_ENTRY_DATA_SNOOP 0x00400000 /* Snoop enable for all data associated with the PRD entry */
+#define PRD_ENTRY_LEN_MASK 0x003fffff /* Data word count */
+
+#define PRD_ENTRY_MAX_XFER_SZ (PRD_ENTRY_LEN_MASK + 1)
+
+/*
+ * This SATA host controller supports a max of 16 direct PRD entries, but if use
+ * chained indirect PRD entries, then the contollers supports upto a max of 63
+ * entries including direct and indirect PRD entries.
+ * The PRDT is an array of 63 PRD entries contigiously, but the PRD entries#15
+ * will be setup as an indirect descriptor, pointing to it's next (contigious)
+ * PRD entries#16.
+ */
+#define SATA_HC_MAX_PRD 63 /* Max PRD entry numbers per command */
+#define SATA_HC_MAX_PRD_DIRECT 16 /* Direct PRDT entries */
+#define SATA_HC_MAX_PRD_USABLE (SATA_HC_MAX_PRD - 1)
+#define SATA_HC_MAX_XFER_LEN 0x4000000
+
+/*
+* PRDT - Physical Region Descriptor Table
+*/
+typedef struct prdt {
+ prd_entry_t prdt[SATA_HC_MAX_PRD];
+} __attribute__ ((packed)) prdt_t;
+
+/*
+* Command Descriptor
+*/
+#define SATA_HC_CMD_DESC_CFIS_SIZE 32 /* bytes */
+#define SATA_HC_CMD_DESC_SFIS_SIZE 32 /* bytes */
+#define SATA_HC_CMD_DESC_ACMD_SIZE 16 /* bytes */
+#define SATA_HC_CMD_DESC_RES 16 /* bytes */
+
+typedef struct cmd_desc {
+ u8 cfis[SATA_HC_CMD_DESC_CFIS_SIZE];
+ u8 sfis[SATA_HC_CMD_DESC_SFIS_SIZE];
+ u8 acmd[SATA_HC_CMD_DESC_ACMD_SIZE];
+ u8 res[SATA_HC_CMD_DESC_RES];
+ prd_entry_t prdt[SATA_HC_MAX_PRD];
+} __attribute__ ((packed)) cmd_desc_t;
+
+#define SATA_HC_CMD_DESC_SIZE sizeof(struct cmd_desc)
+#define SATA_HC_CMD_DESC_ALIGN 4
+
+/*
+* CFIS - Command FIS, which is H2D register FIS, the struct defination
+* of Non-Queued command is different than NCQ command. see them is sata2.h
+*/
+typedef struct cfis {
+ u8 fis_type;
+ u8 pm_port_c;
+ u8 command;
+ u8 features;
+ u8 lba_low;
+ u8 lba_mid;
+ u8 lba_high;
+ u8 device;
+ u8 lba_low_exp;
+ u8 lba_mid_exp;
+ u8 lba_high_exp;
+ u8 features_exp;
+ u8 sector_count;
+ u8 sector_count_exp;
+ u8 res1;
+ u8 control;
+ u8 res2[4];
+} __attribute__ ((packed)) cfis_t;
+
+/*
+* SFIS - Status FIS, which is D2H register FIS.
+*/
+typedef struct sfis {
+ u8 fis_type;
+ u8 pm_port_i;
+ u8 status;
+ u8 error;
+ u8 lba_low;
+ u8 lba_mid;
+ u8 lba_high;
+ u8 device;
+ u8 lba_low_exp;
+ u8 lba_mid_exp;
+ u8 lba_high_exp;
+ u8 res1;
+ u8 sector_count;
+ u8 sector_count_exp;
+ u8 res2[2];
+ u8 res3[4];
+} __attribute__ ((packed)) sfis_t;
+
+/*
+ * SATA device driver info
+ */
+typedef struct fsl_sata_info {
+ u32 sata_reg_base;
+ u32 flags;
+} fsl_sata_info_t;
+
+#define FLAGS_DMA 0x00000000
+#define FLAGS_FPDMA 0x00000001
+
+/*
+ * SATA device driver struct
+ */
+typedef struct fsl_sata {
+ char name[12];
+ fsl_sata_reg_t *reg_base; /* the base address of controller register */
+ void *cmd_hdr_tbl_offset; /* alloc address of command header table */
+ cmd_hdr_tbl_t *cmd_hdr; /* aligned address of command header table */
+ void *cmd_desc_offset; /* alloc address of command descriptor */
+ cmd_desc_t *cmd_desc; /* aligned address of command descriptor */
+ int link; /* PHY link status */
+ /* device attribute */
+ int ata_device_type; /* device type */
+ int lba48;
+ int queue_depth; /* Max NCQ queue depth */
+ u16 pio;
+ u16 mwdma;
+ u16 udma;
+ int wcache;
+ int flush;
+ int flush_ext;
+} fsl_sata_t;
+
+#define READ_CMD 0
+#define WRITE_CMD 1
+
+#endif /* __FSL_SATA_H__ */
--
1.5.4.rc4
1
0

20 Mar '08
enable serdes1(LYNX1) for 837x SATA interface
Signed-off-by: Dave Liu <daveliu(a)freescale.com>
---
board/freescale/mpc837xemds/mpc837xemds.c | 3 +++
include/configs/MPC837XEMDS.h | 9 +++++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/board/freescale/mpc837xemds/mpc837xemds.c b/board/freescale/mpc837xemds/mpc837xemds.c
index e57a53f..3d32c9c 100644
--- a/board/freescale/mpc837xemds/mpc837xemds.c
+++ b/board/freescale/mpc837xemds/mpc837xemds.c
@@ -13,6 +13,7 @@
#include <common.h>
#include <i2c.h>
#include <spd_sdram.h>
+#include <asm/fsl_serdes.h>
#if defined(CONFIG_OF_LIBFDT)
#include <libfdt.h>
#endif
@@ -29,6 +30,8 @@ int board_early_init_f(void)
/* Clear all of the interrupt of BCSR */
bcsr[0xe] = 0xff;
+ fsl_setup_serdes();
+
return 0;
}
diff --git a/include/configs/MPC837XEMDS.h b/include/configs/MPC837XEMDS.h
index 5586533..2ac3d37 100644
--- a/include/configs/MPC837XEMDS.h
+++ b/include/configs/MPC837XEMDS.h
@@ -329,6 +329,15 @@
#define CFG_I2C_RTC_ADDR 0x68 /* at address 0x68 */
/*
+ * SERDES
+ */
+#define CONFIG_FSL_SERDES
+#define CONFIG_FSL_SERDES1 (CFG_IMMR + 0xE3000)
+#define CONFIG_FSL_SERDES1_PROTO FSL_SERDES_PROTO_SATA
+#define CONFIG_FSL_SERDES1_CLK FSL_SERDES_CLK_100
+#define CONFIG_FSL_SERDES1_VDD_1V 1
+
+/*
* General PCI
* Addresses are mapped 1-1.
*/
--
1.5.4.rc4
1
0

20 Mar '08
Signed-off-by: Dave Liu <daveliu(a)freescale.com>
---
doc/README.sata | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 69 insertions(+), 0 deletions(-)
create mode 100644 doc/README.sata
diff --git a/doc/README.sata b/doc/README.sata
new file mode 100644
index 0000000..5cc69db
--- /dev/null
+++ b/doc/README.sata
@@ -0,0 +1,69 @@
+1. SATA usage in U-boot
+
+ Two ways to operate the hard disk
+
+ * Raw read/write block from/to SATA hard disk;
+ * ext2load read file from ext2 filesytem in hard disk
+
+1.0 How to know the information of SATA hard disk?
+
+ => sata info
+
+SATA device 0: Model: ST3320620AS Firm: 3.AAD Ser#: 4QF01ZTN
+ Type: Hard Disk
+ Supports 48-bit addressing
+ Capacity: 305245.3 MB = 298.0 GB (625142448 x 512)
+
+1.1 How to save the kernel, filesystem, dtb to SATA hard disk with raw?
+
+ Notes: 0x1000 sectors = 2 MBytes
+
+ wirte kernel
+ => tftp 40000 /tftpboot/uImage.837x
+ => sata write 40000 0 2000
+
+ write ramdisk
+ => tftp 40000 /tftpboot/ramdisk.837x
+ => sata write 40000 2000 8000
+
+ write dtb
+ => tftp 40000 /tftpboot/mpc837xemds.dtb
+ => sata write 40000 a000 1000
+
+1.2 How to read the kernel, filesystem, dtb from SATA hard disk with raw?
+
+ load kernel
+ => sata read 200000 0 2000
+
+ load ramdisk
+ => sata read 1000000 2000 8000
+
+ load dtb
+ => sata read 2000000 a000 1000
+
+ boot
+ => bootm 200000 1000000 2000000
+
+1.3 How to load image from ext2 filesystem in U-boot?
+
+ U-boot doesn't support ext2 write to hard disk, so
+ you have to write the image to hard disk under Linux env,
+ before you load image from ext2 filesystem.
+
+ => ext2ls sata 0:1 /
+ <DIR> 4096 .
+ <DIR> 4096 ..
+ <DIR> 16384 lost+found
+ 1352023 uImage.837x
+ 3646377 ramdisk.837x
+ 12288 mpc837xemds.dtb
+ 12 hello.txt
+
+ => ext2load sata 0:1 200000 /uImage.837x
+
+ => ext2load sata 0:1 1000000 /ramdisk.837x
+
+ => ext2load sata 0:1 2000000 /mpc837xemds.dtb
+
+ => bootm 200000 1000000 2000000
+
--
1.5.4.rc4
1
0
Signed-off-by: Dave Liu <daveliu(a)freescale.com>
---
lib_ppc/board.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/lib_ppc/board.c b/lib_ppc/board.c
index ee0213e..5e466fa 100644
--- a/lib_ppc/board.c
+++ b/lib_ppc/board.c
@@ -38,6 +38,9 @@
#if defined(CONFIG_CMD_IDE)
#include <ide.h>
#endif
+#if defined(CONFIG_CMD_SATA)
+#include <libata.h>
+#endif
#if defined(CONFIG_CMD_SCSI)
#include <scsi.h>
#endif
@@ -1093,6 +1096,11 @@ void board_init_r (gd_t *id, ulong dest_addr)
#endif
#endif
+#if defined(CONFIG_CMD_SATA)
+ puts ("SATA: ");
+ sata_init ();
+#endif
+
#ifdef CONFIG_LAST_STAGE_INIT
WATCHDOG_RESET ();
/*
--
1.5.4.rc4
1
0
Signed-off-by: Dave Liu <daveliu(a)freescale.com>
---
include/fis.h | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 156 insertions(+), 0 deletions(-)
create mode 100644 include/fis.h
diff --git a/include/fis.h b/include/fis.h
new file mode 100644
index 0000000..2040b50
--- /dev/null
+++ b/include/fis.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2008 Freescale Semiconductor, Inc.
+ * Dave Liu <daveliu(a)freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#ifndef __FIS_H__
+#define __FIS_H__
+/*
+* Register - Host to Device FIS
+*/
+typedef struct sata_fis_h2d {
+ u8 fis_type;
+ u8 pm_port_c;
+ u8 command;
+ u8 features;
+ u8 lba_low;
+ u8 lba_mid;
+ u8 lba_high;
+ u8 device;
+ u8 lba_low_exp;
+ u8 lba_mid_exp;
+ u8 lba_high_exp;
+ u8 features_exp;
+ u8 sector_count;
+ u8 sector_count_exp;
+ u8 res1;
+ u8 control;
+ u8 res2[4];
+} __attribute__ ((packed)) sata_fis_h2d_t;
+
+/*
+* Register - Host to Device FIS for read/write FPDMA queued
+*/
+typedef struct sata_fis_h2d_ncq {
+ u8 fis_type;
+ u8 pm_port_c;
+ u8 command;
+ u8 sector_count_low;
+ u8 lba_low;
+ u8 lba_mid;
+ u8 lba_high;
+ u8 device;
+ u8 lba_low_exp;
+ u8 lba_mid_exp;
+ u8 lba_high_exp;
+ u8 sector_count_high;
+ u8 tag;
+ u8 res1;
+ u8 res2;
+ u8 control;
+ u8 res3[4];
+} __attribute__ ((packed)) sata_fis_h2d_ncq_t;
+
+/*
+* Register - Device to Host FIS
+*/
+typedef struct sata_fis_d2h {
+ u8 fis_type;
+ u8 pm_port_i;
+ u8 status;
+ u8 error;
+ u8 lba_low;
+ u8 lba_mid;
+ u8 lba_high;
+ u8 device;
+ u8 lba_low_exp;
+ u8 lba_mid_exp;
+ u8 lba_high_exp;
+ u8 res1;
+ u8 sector_count;
+ u8 sector_count_exp;
+ u8 res2[2];
+ u8 res3[4];
+} __attribute__ ((packed)) sata_fis_d2h_t;
+
+/*
+* DMA Setup - Device to Host or Host to Device FIS
+*/
+typedef struct sata_fis_dma_setup {
+ u8 fis_type;
+ u8 pm_port_dir_int_act;
+ u8 res1;
+ u8 res2;
+ u32 dma_buffer_id_low;
+ u32 dma_buffer_id_high;
+ u32 res3;
+ u32 dma_buffer_offset;
+ u32 dma_transfer_count;
+ u32 res4;
+} __attribute__ ((packed)) sata_fis_dma_setup_t;
+
+/*
+* PIO Setup - Device to Host FIS
+*/
+typedef struct sata_fis_pio_setup {
+ u8 fis_type;
+ u8 pm_port_dir_int;
+ u8 status;
+ u8 error;
+ u8 lba_low;
+ u8 lba_mid;
+ u8 lba_high;
+ u8 res1;
+ u8 lba_low_exp;
+ u8 lba_mid_exp;
+ u8 lba_high_exp;
+ u8 res2;
+ u8 sector_count;
+ u8 sector_count_exp;
+ u8 res3;
+ u8 e_status;
+ u16 transfer_count;
+ u16 res4;
+} __attribute__ ((packed)) sata_fis_pio_setup_t;
+
+/*
+* Data - Host to Device or Device to Host FIS
+*/
+typedef struct sata_fis_data {
+ u8 fis_type;
+ u8 pm_port;
+ u8 res1;
+ u8 res2;
+ u32 data[2048];
+} __attribute__ ((packed)) sata_fis_data_t;
+
+/* fis_type - SATA FIS type
+ */
+enum sata_fis_type {
+ SATA_FIS_TYPE_REGISTER_H2D = 0x27,
+ SATA_FIS_TYPE_REGISTER_D2H = 0x34,
+ SATA_FIS_TYPE_DMA_ACT_D2H = 0x39,
+ SATA_FIS_TYPE_DMA_SETUP_BI = 0x41,
+ SATA_FIS_TYPE_DATA_BI = 0x46,
+ SATA_FIS_TYPE_BIST_ACT_BI = 0x58,
+ SATA_FIS_TYPE_PIO_SETUP_D2H = 0x5F,
+ SATA_FIS_TYPE_SET_DEVICE_BITS_D2H = 0xA1,
+};
+
+#endif /* __FIS_H__ */
--
1.5.4.rc4
1
0