Hello again Vagrant! First the bad news, then the good...
Unfortunately your new version does not seem to include AHCI support. On Sat, Jun 14, 2014 at 03:02:02PM -0700, Vagrant Cascadian wrote: [...] > I took all patches from v2014.07-rc2 to the HEAD of that branch, and other > than > boards.cfg, seemed to apply and build fine. Possibly because of a mismerge of boards.cfg? ah@heavy:/tmp/vagrant/u-boot-2014.04$ grep Cubietruck boards.cfg Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII - Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII - There's no mention of AHCI or SATAPWR=... in the above lines. > A smaller patchset would be > preferable, but at least most of the changes are sunxi-specific. They were > applied on top of the Cubietruck patches already applied from upstream. [...] I'm attaching two patches which is against http://anonscm.debian.org/gitweb/?p=collab-maint/u-boot.git;a=summary commit 3764e45bbcbc858ecc83ec "Updated lintian overrides:" which is the patches from the mailing list with minor massage to apply without all the other sunxi boards which apparently got sent for review between what's already merged upstream and the AHCI thread. > > Please confirm if it works for you, or have suggestions or an alternate > patchset to apply. Unfortunately your u-boot does not include the "scsi" command at all. My version finds my SSD when I do "scsi scan". Please tell me if you'd rather see me push straight to collab-maint then to mail you patches.... Regards, Andreas Henriksson
>From 9221c88f68905f8f8411d31447019cbe6e73ed13 Mon Sep 17 00:00:00 2001 From: Andreas Henriksson <andr...@fatal.se> Date: Sun, 15 Jun 2014 08:08:17 +0200 Subject: [PATCH 1/2] Add patches for sunxi AHCI driver (Cubietruck) This is patch 1,2,4,5,6 (skipping 3 - Cubietruck2) from: http://lists.denx.de/pipermail/u-boot/2014-June/181047.html With minor modifications to get it to apply cleanly. --- debian/patches/series | 5 + .../0013-AHCI-Increase-link-timeout-to-200ms.patch | 31 +++ .../0014-board_r-run-scsi-init-on-ARM-too.patch | 52 ++++ .../0015-sunxi-add-gpio-driver.patch | 175 ++++++++++++++ ...-use-setbits_le32-to-enable-the-DMA-clock.patch | 24 ++ ...e-sunxi-SATA-driver-using-AHCI-platform-f.patch | 269 +++++++++++++++++++++ 6 files changed, 556 insertions(+) create mode 100644 debian/patches/sunxi-cubietruck/0013-AHCI-Increase-link-timeout-to-200ms.patch create mode 100644 debian/patches/sunxi-cubietruck/0014-board_r-run-scsi-init-on-ARM-too.patch create mode 100644 debian/patches/sunxi-cubietruck/0015-sunxi-add-gpio-driver.patch create mode 100644 debian/patches/sunxi-cubietruck/0016-sunxi-use-setbits_le32-to-enable-the-DMA-clock.patch create mode 100644 debian/patches/sunxi-cubietruck/0017-ahci-provide-sunxi-SATA-driver-using-AHCI-platform-f.patch diff --git a/debian/patches/series b/debian/patches/series index e8e24dc..2f6beeb 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -26,5 +26,10 @@ sunxi-cubietruck/0009-net-designware-ensure-device-private-data-is-DMA-ali.patch sunxi-cubietruck/0010-net-designware-ensure-cache-invalidations-are-aligne.patch sunxi-cubietruck/0011-net-designware-reorder-struct-dw_eth_dev-to-pack-mor.patch sunxi-cubietruck/0012-net-designware-Make-DMA-burst-length-configurable-an.patch +sunxi-cubietruck/0013-AHCI-Increase-link-timeout-to-200ms.patch +sunxi-cubietruck/0014-board_r-run-scsi-init-on-ARM-too.patch +sunxi-cubietruck/0015-sunxi-add-gpio-driver.patch +sunxi-cubietruck/0016-sunxi-use-setbits_le32-to-enable-the-DMA-clock.patch +sunxi-cubietruck/0017-ahci-provide-sunxi-SATA-driver-using-AHCI-platform-f.patch am335x-bootscript.diff am335x-try-boot-from-first-partition.diff diff --git a/debian/patches/sunxi-cubietruck/0013-AHCI-Increase-link-timeout-to-200ms.patch b/debian/patches/sunxi-cubietruck/0013-AHCI-Increase-link-timeout-to-200ms.patch new file mode 100644 index 0000000..b22d52c --- /dev/null +++ b/debian/patches/sunxi-cubietruck/0013-AHCI-Increase-link-timeout-to-200ms.patch @@ -0,0 +1,31 @@ +From: Ian Campbell <i...@hellion.org.uk> +Date: Thu, 5 Jun 2014 19:00:12 +0100 +Subject: AHCI: Increase link timeout to 200ms + +In 73545f75b66d "ahci: wait longer for link" I increased the +timeout to 40ms based on the observed behaviour of a WD disk on a +Cubietruck. Since then Karsten Merker and myself have both +observed timeouts with HGST disks (Karsten on Cubietruck, me on +Cubieboard2). Increasing the timeout to ~175ms fixes this, so go +to 200ms for a bit of headroom. + +Signed-off-by: Ian Campbell <i...@hellion.org.uk> +Acked-by: Hans de Goede <hdego...@redhat.com> +Cc: Karsten Merker <mer...@debian.org> +--- + drivers/block/ahci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c +index c8f6573..4df8046 100644 +--- a/drivers/block/ahci.c ++++ b/drivers/block/ahci.c +@@ -41,7 +41,7 @@ u16 *ataid[AHCI_MAX_PORTS]; + #define WAIT_MS_SPINUP 20000 + #define WAIT_MS_DATAIO 5000 + #define WAIT_MS_FLUSH 5000 +-#define WAIT_MS_LINKUP 40 ++#define WAIT_MS_LINKUP 200 + + static inline u32 ahci_port_base(u32 base, u32 port) + { diff --git a/debian/patches/sunxi-cubietruck/0014-board_r-run-scsi-init-on-ARM-too.patch b/debian/patches/sunxi-cubietruck/0014-board_r-run-scsi-init-on-ARM-too.patch new file mode 100644 index 0000000..dc73786 --- /dev/null +++ b/debian/patches/sunxi-cubietruck/0014-board_r-run-scsi-init-on-ARM-too.patch @@ -0,0 +1,52 @@ +From: Ian Campbell <i...@hellion.org.uk> +Date: Thu, 5 Jun 2014 19:00:13 +0100 +Subject: board_r: run scsi init() on ARM too + +This has been disabled for ARM in initr_scsi since that function was +introduced. However it works fine for me on Cubieboard and Cubietruck (with the +upcoming AHCI glue patch). + +I also tested on two random ARM platforms which seem to define CONFIG_CMD_SCSI: + - highbank worked fine (on midway hardware) + - omap5_uevm built OK and I confirmed using objdump that things were as + expected (i.e. the default weak scsi_init nop was used). + +While there remove the mismatched comment from the #endif (omitting the comment +seems to be the prevailing style in this file) and add a missing return to +initr_doc which I happened to spot while editing. + +Signed-off-by: Ian Campbell <i...@hellion.org.uk> +Acked-by: Simon Glass <s...@chromium.org> +Acked-by: Hans de Goede <hdego...@redhat.com> +--- + common/board_r.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +diff --git a/common/board_r.c b/common/board_r.c +index 8629a65..89b5596 100644 +--- a/common/board_r.c ++++ b/common/board_r.c +@@ -587,21 +587,19 @@ static int initr_status_led(void) + #if defined(CONFIG_CMD_SCSI) + static int initr_scsi(void) + { +- /* Not supported properly on ARM yet */ +-#ifndef CONFIG_ARM + puts("SCSI: "); + scsi_init(); +-#endif + + return 0; + } +-#endif /* CONFIG_CMD_NET */ ++#endif + + #if defined(CONFIG_CMD_DOC) + static int initr_doc(void) + { + puts("DOC: "); + doc_init(); ++ return 0 + } + #endif + diff --git a/debian/patches/sunxi-cubietruck/0015-sunxi-add-gpio-driver.patch b/debian/patches/sunxi-cubietruck/0015-sunxi-add-gpio-driver.patch new file mode 100644 index 0000000..7e69c8a --- /dev/null +++ b/debian/patches/sunxi-cubietruck/0015-sunxi-add-gpio-driver.patch @@ -0,0 +1,175 @@ +From: Ian Campbell <i...@hellion.org.uk> +Date: Thu, 5 Jun 2014 19:00:15 +0100 +Subject: sunxi: add gpio driver +MIME-Version: 1.0 +Content-Type: text/plain; charset="utf-8" +Content-Transfer-Encoding: 8bit + +This patch enables CONFIG_CMD_GPIO for the Allwinner (sunxi) platform as well +as providing the common gpio API (gpio_request/free, direction in/out, get/set +etc). + +Conflicts: + include/configs/sunxi-common.h +(Fixed to apply by Andreas Henriksson <andr...@fatal.se>) + +Signed-off-by: Chen-Yu Tsai <w...@csie.org> +Signed-off-by: Hans de Goede <hdego...@redhat.com> +Signed-off-by: Ma Haijun <mahaij...@gmail.com> +Signed-off-by: Oliver Schinagl <oli...@schinagl.nl> +Signed-off-by: Ian Campbell <i...@hellion.org.uk> +Cc: Henrik Nordström <hen...@henriknordstrom.net> +Cc: Tom Cubie <mr.hip...@gmail.com> +Acked-by: Hans de Goede <hdego...@redhat.com> +--- + arch/arm/include/asm/arch-sunxi/gpio.h | 2 + + drivers/gpio/Makefile | 1 + + drivers/gpio/sunxi_gpio.c | 102 +++++++++++++++++++++++++++++++++ + include/configs/sunxi-common.h | 4 ++ + 4 files changed, 109 insertions(+) + create mode 100644 drivers/gpio/sunxi_gpio.c + +diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h +index 892479c..f7f3d8c 100644 +--- a/arch/arm/include/asm/arch-sunxi/gpio.h ++++ b/arch/arm/include/asm/arch-sunxi/gpio.h +@@ -143,5 +143,7 @@ int sunxi_gpio_set_cfgpin(u32 pin, u32 val); + int sunxi_gpio_get_cfgpin(u32 pin); + int sunxi_gpio_set_drv(u32 pin, u32 val); + int sunxi_gpio_set_pull(u32 pin, u32 val); ++int sunxi_name_to_gpio(const char *name); ++#define name_to_gpio(name) sunxi_name_to_gpio(name) + + #endif /* _SUNXI_GPIO_H */ +diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile +index 4e001e1..86813b9 100644 +--- a/drivers/gpio/Makefile ++++ b/drivers/gpio/Makefile +@@ -34,3 +34,4 @@ obj-$(CONFIG_XILINX_GPIO) += xilinx_gpio.o + obj-$(CONFIG_ADI_GPIO2) += adi_gpio2.o + obj-$(CONFIG_TCA642X) += tca642x.o + oby-$(CONFIG_SX151X) += sx151x.o ++obj-$(CONFIG_SUNXI_GPIO) += sunxi_gpio.o +diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c +new file mode 100644 +index 0000000..0c50a8f +--- /dev/null ++++ b/drivers/gpio/sunxi_gpio.c +@@ -0,0 +1,102 @@ ++/* ++ * (C) Copyright 2012 Henrik Nordstrom <hen...@henriknordstrom.net> ++ * ++ * Based on earlier arch/arm/cpu/armv7/sunxi/gpio.c: ++ * ++ * (C) Copyright 2007-2011 ++ * Allwinner Technology Co., Ltd. <www.allwinnertech.com> ++ * Tom Cubie <tangli...@allwinnertech.com> ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include <common.h> ++#include <asm/io.h> ++#include <asm/gpio.h> ++ ++static int sunxi_gpio_output(u32 pin, u32 val) ++{ ++ u32 dat; ++ u32 bank = GPIO_BANK(pin); ++ u32 num = GPIO_NUM(pin); ++ struct sunxi_gpio *pio = BANK_TO_GPIO(bank); ++ ++ dat = readl(&pio->dat); ++ if (val) ++ dat |= 0x1 << num; ++ else ++ dat &= ~(0x1 << num); ++ ++ writel(dat, &pio->dat); ++ ++ return 0; ++} ++ ++static int sunxi_gpio_input(u32 pin) ++{ ++ u32 dat; ++ u32 bank = GPIO_BANK(pin); ++ u32 num = GPIO_NUM(pin); ++ struct sunxi_gpio *pio = BANK_TO_GPIO(bank); ++ ++ dat = readl(&pio->dat); ++ dat >>= num; ++ ++ return dat & 0x1; ++} ++ ++int gpio_request(unsigned gpio, const char *label) ++{ ++ return 0; ++} ++ ++int gpio_free(unsigned gpio) ++{ ++ return 0; ++} ++ ++int gpio_direction_input(unsigned gpio) ++{ ++ sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_INPUT); ++ ++ return sunxi_gpio_input(gpio); ++} ++ ++int gpio_direction_output(unsigned gpio, int value) ++{ ++ sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_OUTPUT); ++ ++ return sunxi_gpio_output(gpio, value); ++} ++ ++int gpio_get_value(unsigned gpio) ++{ ++ return sunxi_gpio_input(gpio); ++} ++ ++int gpio_set_value(unsigned gpio, int value) ++{ ++ return sunxi_gpio_output(gpio, value); ++} ++ ++int sunxi_name_to_gpio(const char *name) ++{ ++ int group = 0; ++ int groupsize = 9 * 32; ++ long pin; ++ char *eptr; ++ if (*name == 'P' || *name == 'p') ++ name++; ++ if (*name >= 'A') { ++ group = *name - (*name > 'a' ? 'a' : 'A'); ++ groupsize = 32; ++ name++; ++ } ++ ++ pin = simple_strtol(name, &eptr, 10); ++ if (!*name || *eptr) ++ return -1; ++ if (pin < 0 || pin > groupsize || group >= 9) ++ return -1; ++ return group * 32 + pin; ++} +diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h +index 5d72d62..bdcf18f 100644 +--- a/include/configs/sunxi-common.h ++++ b/include/configs/sunxi-common.h +@@ -164,6 +164,10 @@ + + #define CONFIG_CONS_INDEX 1 /* UART0 */ + ++/* GPIO */ ++#define CONFIG_SUNXI_GPIO ++#define CONFIG_CMD_GPIO ++ + #ifdef CONFIG_SUNXI_GMAC + #define CONFIG_DESIGNWARE_ETH /* GMAC can use designware driver */ + #define CONFIG_DW_AUTONEG diff --git a/debian/patches/sunxi-cubietruck/0016-sunxi-use-setbits_le32-to-enable-the-DMA-clock.patch b/debian/patches/sunxi-cubietruck/0016-sunxi-use-setbits_le32-to-enable-the-DMA-clock.patch new file mode 100644 index 0000000..5e317fb --- /dev/null +++ b/debian/patches/sunxi-cubietruck/0016-sunxi-use-setbits_le32-to-enable-the-DMA-clock.patch @@ -0,0 +1,24 @@ +From: Ian Campbell <i...@hellion.org.uk> +Date: Thu, 5 Jun 2014 19:00:16 +0100 +Subject: sunxi: use setbits_le32 to enable the DMA clock + +Signed-off-by: Ian Campbell <i...@hellion.org.uk> +Acked-by: Hans de Goede <hdego...@redhat.com> +--- + arch/arm/cpu/armv7/sunxi/clock_sun4i.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c +index 5a7da3c..b8b16cf 100644 +--- a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c ++++ b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c +@@ -36,8 +36,7 @@ void clock_init_safe(void) + CPU_CLK_SRC_PLL1 << CPU_CLK_SRC_SHIFT, + &ccm->cpu_ahb_apb0_cfg); + #ifdef CONFIG_SUN7I +- writel(0x1 << AHB_GATE_OFFSET_DMA | readl(&ccm->ahb_gate0), +- &ccm->ahb_gate0); ++ setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_DMA); + #endif + writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); + } diff --git a/debian/patches/sunxi-cubietruck/0017-ahci-provide-sunxi-SATA-driver-using-AHCI-platform-f.patch b/debian/patches/sunxi-cubietruck/0017-ahci-provide-sunxi-SATA-driver-using-AHCI-platform-f.patch new file mode 100644 index 0000000..e57abb4 --- /dev/null +++ b/debian/patches/sunxi-cubietruck/0017-ahci-provide-sunxi-SATA-driver-using-AHCI-platform-f.patch @@ -0,0 +1,269 @@ +From: Ian Campbell <i...@hellion.org.uk> +Date: Thu, 5 Jun 2014 19:00:17 +0100 +Subject: ahci: provide sunxi SATA driver using AHCI platform framework + +This enables the necessary clocks, in AHB0 and in PLL6_CFG. This is done +for sun7i only since I don't have access to any other sunxi platforms +with sata included. + +The PHY setup is derived from the Alwinner releases and Linux, but is mostly +undocumented. + +The Allwinner AHCI controller also requires some magic (and, again, +undocumented) DMA initialisation when starting a port. This is added under a +suitable ifdef. + +This option is enabled for Cubieboard, Cubieboard2 and Cubietruck based on +contents of Linux DTS files, including SATA power pin config taken from the +DTS. All build tested, but runtime tested on Cubieboard2 and Cubietruck only. + +Conflicts: + board/sunxi/Makefile + boards.cfg +(Fixed to apply by Andreas Henriksson <andr...@fatal.se>) + +Signed-off-by: Ian Campbell <i...@hellion.org.uk> +Acked-by: Hans de Goede <hdego...@redhat.com> +--- + arch/arm/cpu/armv7/sunxi/clock_sun4i.c | 4 ++ + arch/arm/include/asm/arch-sunxi/clock_sun4i.h | 11 ++-- + board/sunxi/Makefile | 1 + + board/sunxi/ahci.c | 84 +++++++++++++++++++++++++++ + boards.cfg | 4 +- + drivers/block/ahci.c | 16 +++++ + include/ahci.h | 4 ++ + include/configs/sunxi-common.h | 12 ++++ + 8 files changed, 130 insertions(+), 6 deletions(-) + create mode 100644 board/sunxi/ahci.c + +diff --git a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c +index b8b16cf..ecbdb01 100644 +--- a/arch/arm/cpu/armv7/sunxi/clock_sun4i.c ++++ b/arch/arm/cpu/armv7/sunxi/clock_sun4i.c +@@ -39,6 +39,10 @@ void clock_init_safe(void) + setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_DMA); + #endif + writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg); ++#ifdef CONFIG_SUNXI_AHCI ++ setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_SATA); ++ setbits_le32(&ccm->pll6_cfg, 0x1 << CCM_PLL6_CTRL_SATA_EN_SHIFT); ++#endif + } + #endif + +diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h +index 928f3f2..2531cbd 100644 +--- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h ++++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h +@@ -218,10 +218,13 @@ struct sunxi_ccm_reg { + #define CCM_PLL5_CTRL_BYPASS (0x1 << 30) + #define CCM_PLL5_CTRL_EN (0x1 << 31) + +-#define CCM_PLL6_CTRL_N_SHIFT 8 +-#define CCM_PLL6_CTRL_N_MASK (0x1f << CCM_PLL6_CTRL_N_SHIFT) +-#define CCM_PLL6_CTRL_K_SHIFT 4 +-#define CCM_PLL6_CTRL_K_MASK (0x3 << CCM_PLL6_CTRL_K_SHIFT) ++#define CCM_PLL6_CTRL_EN 31 ++#define CCM_PLL6_CTRL_BYPASS_EN 30 ++#define CCM_PLL6_CTRL_SATA_EN_SHIFT 14 ++#define CCM_PLL6_CTRL_N_SHIFT 8 ++#define CCM_PLL6_CTRL_N_MASK (0x1f << CCM_PLL6_CTRL_N_SHIFT) ++#define CCM_PLL6_CTRL_K_SHIFT 4 ++#define CCM_PLL6_CTRL_K_MASK (0x3 << CCM_PLL6_CTRL_K_SHIFT) + + #define CCM_GPS_CTRL_RESET (0x1 << 0) + #define CCM_GPS_CTRL_GATE (0x1 << 1) +diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile +index cbf8f08..d69b521 100644 +--- a/board/sunxi/Makefile ++++ b/board/sunxi/Makefile +@@ -10,4 +10,5 @@ + # + obj-y += board.o + obj-$(CONFIG_SUNXI_GMAC) += gmac.o ++obj-$(CONFIG_SUNXI_AHCI) += ahci.o + obj-$(CONFIG_CUBIETRUCK) += dram_cubietruck.o +diff --git a/board/sunxi/ahci.c b/board/sunxi/ahci.c +new file mode 100644 +index 0000000..0c262ea +--- /dev/null ++++ b/board/sunxi/ahci.c +@@ -0,0 +1,84 @@ ++#include <common.h> ++#include <ahci.h> ++#include <scsi.h> ++#include <errno.h> ++#include <asm/io.h> ++#include <asm/gpio.h> ++ ++#define AHCI_PHYCS0R 0x00c0 ++#define AHCI_PHYCS1R 0x00c4 ++#define AHCI_PHYCS2R 0x00c8 ++#define AHCI_RWCR 0x00fc ++ ++/* This magic PHY initialisation was taken from the Allwinner releases ++ * and Linux driver, but is completely undocumented. ++ */ ++static int sunxi_ahci_phy_init(u32 base) ++{ ++ u8 *reg_base = (u8 *)base; ++ u32 reg_val; ++ int timeout; ++ ++ writel(0, reg_base + AHCI_RWCR); ++ mdelay(5); ++ ++ setbits_le32(reg_base + AHCI_PHYCS1R, 0x1 << 19); ++ clrsetbits_le32(reg_base + AHCI_PHYCS0R, ++ (0x7 << 24), ++ (0x5 << 24) | (0x1 << 23) | (0x1 << 18)); ++ clrsetbits_le32(reg_base + AHCI_PHYCS1R, ++ (0x3 << 16) | (0x1f << 8) | (0x3 << 6), ++ (0x2 << 16) | (0x6 << 8) | (0x2 << 6)); ++ setbits_le32(reg_base + AHCI_PHYCS1R, (0x1 << 28) | (0x1 << 15)); ++ clrbits_le32(reg_base + AHCI_PHYCS1R, (0x1 << 19)); ++ clrsetbits_le32(reg_base + AHCI_PHYCS0R, (0x7 << 20), (0x3 << 20)); ++ clrsetbits_le32(reg_base + AHCI_PHYCS2R, (0x1f << 5), (0x19 << 5)); ++ mdelay(5); ++ ++ setbits_le32(reg_base + AHCI_PHYCS0R, (0x1 << 19)); ++ ++ timeout = 250; /* Power up takes approx 50 us */ ++ for (;;) { ++ reg_val = readl(reg_base + AHCI_PHYCS0R) & (0x7 << 28); ++ if (reg_val == (0x2 << 28)) ++ break; ++ if (--timeout == 0) { ++ printf("AHCI PHY power up failed.\n"); ++ return -EIO; ++ } ++ udelay(1); ++ }; ++ ++ setbits_le32(reg_base + AHCI_PHYCS2R, (0x1 << 24)); ++ ++ timeout = 100; /* Calibration takes approx 10 us */ ++ for (;;) { ++ reg_val = readl(reg_base + AHCI_PHYCS2R) & (0x1 << 24); ++ if (reg_val == 0x0) ++ break; ++ if (--timeout == 0) { ++ printf("AHCI PHY calibration failed.\n"); ++ return -EIO; ++ } ++ udelay(1); ++ } ++ ++ mdelay(15); ++ ++ writel(0x7, reg_base + AHCI_RWCR); ++ ++ return 0; ++} ++ ++void scsi_init(void) ++{ ++ printf("SUNXI SCSI INIT\n"); ++#ifdef CONFIG_SATAPWR ++ gpio_direction_output(CONFIG_SATAPWR, 1); ++#endif ++ ++ if (sunxi_ahci_phy_init(SUNXI_SATA_BASE) < 0) ++ return; ++ ++ ahci_init(SUNXI_SATA_BASE); ++} +diff --git a/boards.cfg b/boards.cfg +index f62eb4c..9a7b9b2 100644 +--- a/boards.cfg ++++ b/boards.cfg +@@ -371,8 +371,8 @@ Active arm armv7 rmobile renesas lager + Active arm armv7 s5pc1xx samsung goni s5p_goni - Mateusz Zalega <m.zal...@samsung.com> + Active arm armv7 s5pc1xx samsung smdkc100 smdkc100 - Minkyu Kang <mk7.k...@samsung.com> + Active arm armv7 socfpga altera socfpga socfpga_cyclone5 - - +-Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII - +-Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII - ++Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPH(12) Ian Campbell <i...@hellion.org.uk>:Hans de Goede <hdego...@redhat.com> ++Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII,,AHCI,SATAPWR=SUNXI_GPH(12) Ian Campbell <i...@hellion.org.uk>:Hans de Goede <hdego...@redhat.com> + Active arm armv7 u8500 st-ericsson snowball snowball - Mathieu Poirier <mathieu.poir...@linaro.org> + Active arm armv7 u8500 st-ericsson u8500 u8500_href - - + Active arm armv7 vf610 freescale vf610twr vf610twr vf610twr:IMX_CONFIG=board/freescale/vf610twr/imximage.cfg Alison Wang <b18...@freescale.com> +diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c +index 4df8046..dce99ad 100644 +--- a/drivers/block/ahci.c ++++ b/drivers/block/ahci.c +@@ -129,6 +129,14 @@ int __weak ahci_link_up(struct ahci_probe_ent *probe_ent, u8 port) + return 1; + } + ++#ifdef CONFIG_SUNXI_AHCI ++/* The sunxi AHCI controller requires this undocumented setup */ ++static void sunxi_dma_init(volatile u8 *port_mmio) ++{ ++ clrsetbits_le32(port_mmio + PORT_P0DMACR, 0x0000ff00, 0x00004400); ++} ++#endif ++ + static int ahci_host_init(struct ahci_probe_ent *probe_ent) + { + #ifndef CONFIG_SCSI_AHCI_PLAT +@@ -213,6 +221,10 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) + msleep(500); + } + ++#ifdef CONFIG_SUNXI_AHCI ++ sunxi_dma_init(port_mmio); ++#endif ++ + /* Add the spinup command to whatever mode bits may + * already be on in the command register. + */ +@@ -545,6 +557,10 @@ static int ahci_port_start(u8 port) + + writel_with_flush(pp->rx_fis, port_mmio + PORT_FIS_ADDR); + ++#ifdef CONFIG_SUNXI_AHCI ++ sunxi_dma_init(port_mmio); ++#endif ++ + writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX | + PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP | + PORT_CMD_START, port_mmio + PORT_CMD); +diff --git a/include/ahci.h b/include/ahci.h +index 90e8509..35b8a8c 100644 +--- a/include/ahci.h ++++ b/include/ahci.h +@@ -58,6 +58,10 @@ + #define PORT_SCR_ERR 0x30 /* SATA phy register: SError */ + #define PORT_SCR_ACT 0x34 /* SATA phy register: SActive */ + ++#ifdef CONFIG_SUNXI_AHCI ++#define PORT_P0DMACR 0x70 /* SUNXI specific "DMA register" */ ++#endif ++ + /* PORT_IRQ_{STAT,MASK} bits */ + #define PORT_IRQ_COLD_PRES (1 << 31) /* cold presence detect */ + #define PORT_IRQ_TF_ERR (1 << 30) /* task file error */ +diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h +index bdcf18f..8e15dc9 100644 +--- a/include/configs/sunxi-common.h ++++ b/include/configs/sunxi-common.h +@@ -57,6 +57,18 @@ + #define PHYS_SDRAM_0 CONFIG_SYS_SDRAM_BASE + #define PHYS_SDRAM_0_SIZE 0x80000000 /* 2 GiB */ + ++#ifdef CONFIG_AHCI ++#define CONFIG_LIBATA ++#define CONFIG_SCSI_AHCI ++#define CONFIG_SCSI_AHCI_PLAT ++#define CONFIG_SUNXI_AHCI ++#define CONFIG_SYS_SCSI_MAX_SCSI_ID 1 ++#define CONFIG_SYS_SCSI_MAX_LUN 1 ++#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \ ++ CONFIG_SYS_SCSI_MAX_LUN) ++#define CONFIG_CMD_SCSI ++#endif ++ + #define CONFIG_CMD_MEMORY + #define CONFIG_CMD_SETEXPR + -- 2.0.0
>From 64d2401bd5a258c2c71be7844796dd5d90299026 Mon Sep 17 00:00:00 2001 From: Andreas Henriksson <andr...@fatal.se> Date: Sun, 15 Jun 2014 08:20:08 +0200 Subject: [PATCH 2/2] Add sunxi drop MMC DMA patch From: http://lists.denx.de/pipermail/u-boot/2014-June/180936.html --- debian/patches/series | 1 + .../0018-sunxi-Remove-mmc-DMA-support.patch | 227 +++++++++++++++++++++ 2 files changed, 228 insertions(+) create mode 100644 debian/patches/sunxi-cubietruck/0018-sunxi-Remove-mmc-DMA-support.patch diff --git a/debian/patches/series b/debian/patches/series index 2f6beeb..4708f35 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -31,5 +31,6 @@ sunxi-cubietruck/0014-board_r-run-scsi-init-on-ARM-too.patch sunxi-cubietruck/0015-sunxi-add-gpio-driver.patch sunxi-cubietruck/0016-sunxi-use-setbits_le32-to-enable-the-DMA-clock.patch sunxi-cubietruck/0017-ahci-provide-sunxi-SATA-driver-using-AHCI-platform-f.patch +sunxi-cubietruck/0018-sunxi-Remove-mmc-DMA-support.patch am335x-bootscript.diff am335x-try-boot-from-first-partition.diff diff --git a/debian/patches/sunxi-cubietruck/0018-sunxi-Remove-mmc-DMA-support.patch b/debian/patches/sunxi-cubietruck/0018-sunxi-Remove-mmc-DMA-support.patch new file mode 100644 index 0000000..9a620a8 --- /dev/null +++ b/debian/patches/sunxi-cubietruck/0018-sunxi-Remove-mmc-DMA-support.patch @@ -0,0 +1,227 @@ +From: Hans de Goede <hdego...@redhat.com> +Date: Mon, 9 Jun 2014 11:36:55 +0200 +Subject: sunxi: Remove mmc DMA support + +The DMA code in sunxi_mmc.c is broken. mmc_trans_data_by_dma() allocates the +dma descriptors on the stack, and then exits while the dma transfer is in +progress, so the dma engine is reading stack memory which at that point may +be re-used. So far we've gotten away with this by luck, but recent u-boot +changes have shifted the stack start address by 16 bytes, which combined +with dma alignment now exposes this problem. + +Since we end up just busy waiting for the dma engine anyway, this commit +fixes things by simply removing the dma code, resulting in smaller bug-free +code. + +Signed-off-by: Hans de Goede <hdego...@redhat.com> +Acked-by: Ian Campbell <i...@hellion.org.uk> +--- + drivers/mmc/sunxi_mmc.c | 140 ++--------------------------------------- + include/configs/sunxi-common.h | 1 - + 2 files changed, 6 insertions(+), 135 deletions(-) + +diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c +index eb7b115..ae0cf1a 100644 +--- a/drivers/mmc/sunxi_mmc.c ++++ b/drivers/mmc/sunxi_mmc.c +@@ -16,28 +16,6 @@ + #include <asm/arch/cpu.h> + #include <asm/arch/mmc.h> + +-struct sunxi_mmc_des { +- u32 reserved1_1:1; +- u32 dic:1; /* disable interrupt on completion */ +- u32 last_des:1; /* 1-this data buffer is the last buffer */ +- u32 first_des:1; /* 1-data buffer is the first buffer, +- 0-data buffer contained in the next +- descriptor is 1st buffer */ +- u32 des_chain:1; /* 1-the 2nd address in the descriptor is the +- next descriptor address */ +- u32 end_of_ring:1; /* 1-last descriptor flag when using dual +- data buffer in descriptor */ +- u32 reserved1_2:24; +- u32 card_err_sum:1; /* transfer error flag */ +- u32 own:1; /* des owner:1-idma owns it, 0-host owns it */ +-#define SDXC_DES_NUM_SHIFT 16 +-#define SDXC_DES_BUFFER_MAX_LEN (1 << SDXC_DES_NUM_SHIFT) +- u32 data_buf1_sz:16; +- u32 data_buf2_sz:16; +- u32 buf_addr_ptr1; +- u32 buf_addr_ptr2; +-}; +- + struct sunxi_mmc_host { + unsigned mmc_no; + uint32_t *mclkreg; +@@ -189,6 +167,9 @@ static int mmc_core_init(struct mmc *mmc) + + /* Reset controller */ + writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); ++ udelay(1000); ++ /* Always read / write data through the CPU */ ++ writel(SUNXI_MMC_GCTRL_ACCESS_BY_AHB, &mmchost->reg->gctrl); + + return 0; + } +@@ -220,85 +201,6 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) + return 0; + } + +-static int mmc_trans_data_by_dma(struct mmc *mmc, struct mmc_data *data) +-{ +- struct sunxi_mmc_host *mmchost = mmc->priv; +- unsigned byte_cnt = data->blocksize * data->blocks; +- unsigned char *buff; +- unsigned des_idx = 0; +- unsigned buff_frag_num = +- (byte_cnt + SDXC_DES_BUFFER_MAX_LEN - 1) >> SDXC_DES_NUM_SHIFT; +- unsigned remain; +- unsigned i, rval; +- ALLOC_CACHE_ALIGN_BUFFER(struct sunxi_mmc_des, pdes, buff_frag_num); +- +- buff = data->flags & MMC_DATA_READ ? +- (unsigned char *)data->dest : (unsigned char *)data->src; +- remain = byte_cnt & (SDXC_DES_BUFFER_MAX_LEN - 1); +- +- flush_cache((unsigned long)buff, (unsigned long)byte_cnt); +- for (i = 0; i < buff_frag_num; i++, des_idx++) { +- memset((void *)&pdes[des_idx], 0, sizeof(struct sunxi_mmc_des)); +- pdes[des_idx].des_chain = 1; +- pdes[des_idx].own = 1; +- pdes[des_idx].dic = 1; +- if (buff_frag_num > 1 && i != buff_frag_num - 1) +- pdes[des_idx].data_buf1_sz = 0; /* 0 == max_len */ +- else +- pdes[des_idx].data_buf1_sz = remain; +- +- pdes[des_idx].buf_addr_ptr1 = +- (u32) buff + i * SDXC_DES_BUFFER_MAX_LEN; +- if (i == 0) +- pdes[des_idx].first_des = 1; +- +- if (i == buff_frag_num - 1) { +- pdes[des_idx].dic = 0; +- pdes[des_idx].last_des = 1; +- pdes[des_idx].end_of_ring = 1; +- pdes[des_idx].buf_addr_ptr2 = 0; +- } else { +- pdes[des_idx].buf_addr_ptr2 = (u32)&pdes[des_idx + 1]; +- } +- } +- flush_cache((unsigned long)pdes, +- sizeof(struct sunxi_mmc_des) * (des_idx + 1)); +- +- rval = readl(&mmchost->reg->gctrl); +- /* Enable DMA */ +- writel(rval | SUNXI_MMC_GCTRL_DMA_RESET | SUNXI_MMC_GCTRL_DMA_ENABLE, +- &mmchost->reg->gctrl); +- /* Reset iDMA */ +- writel(SUNXI_MMC_IDMAC_RESET, &mmchost->reg->dmac); +- /* Enable iDMA */ +- writel(SUNXI_MMC_IDMAC_FIXBURST | SUNXI_MMC_IDMAC_ENABLE, +- &mmchost->reg->dmac); +- rval = readl(&mmchost->reg->idie) & +- ~(SUNXI_MMC_IDIE_TXIRQ|SUNXI_MMC_IDIE_RXIRQ); +- if (data->flags & MMC_DATA_WRITE) +- rval |= SUNXI_MMC_IDIE_TXIRQ; +- else +- rval |= SUNXI_MMC_IDIE_RXIRQ; +- writel(rval, &mmchost->reg->idie); +- writel((u32) pdes, &mmchost->reg->dlba); +- writel((0x2 << 28) | (0x7 << 16) | (0x01 << 3), +- &mmchost->reg->ftrglevel); +- +- return 0; +-} +- +-static void mmc_enable_dma_accesses(struct mmc *mmc, int dma) +-{ +- struct sunxi_mmc_host *mmchost = mmc->priv; +- +- unsigned int gctrl = readl(&mmchost->reg->gctrl); +- if (dma) +- gctrl &= ~SUNXI_MMC_GCTRL_ACCESS_BY_AHB; +- else +- gctrl |= SUNXI_MMC_GCTRL_ACCESS_BY_AHB; +- writel(gctrl, &mmchost->reg->gctrl); +-} +- + static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, + unsigned int done_bit, const char *what) + { +@@ -327,7 +229,6 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + unsigned int timeout_msecs; + int error = 0; + unsigned int status = 0; +- unsigned int usedma = 0; + unsigned int bytecnt = 0; + + if (mmchost->fatal_err) +@@ -378,20 +279,8 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + + bytecnt = data->blocksize * data->blocks; + debug("trans data %d bytes\n", bytecnt); +-#if defined(CONFIG_MMC_SUNXI_USE_DMA) && !defined(CONFIG_SPL_BUILD) +- if (bytecnt > 64) { +-#else +- if (0) { +-#endif +- usedma = 1; +- mmc_enable_dma_accesses(mmc, 1); +- ret = mmc_trans_data_by_dma(mmc, data); +- writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); +- } else { +- mmc_enable_dma_accesses(mmc, 0); +- writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); +- ret = mmc_trans_data_by_cpu(mmc, data); +- } ++ writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); ++ ret = mmc_trans_data_by_cpu(mmc, data); + if (ret) { + error = readl(&mmchost->reg->rint) & \ + SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT; +@@ -405,7 +294,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + goto out; + + if (data) { +- timeout_msecs = usedma ? 120 * bytecnt : 120; ++ timeout_msecs = 120; + debug("cacl timeout %x msec\n", timeout_msecs); + error = mmc_rint_wait(mmc, timeout_msecs, + data->blocks > 1 ? +@@ -442,23 +331,6 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, + debug("mmc resp 0x%08x\n", cmd->response[0]); + } + out: +- if (data && usedma) { +- /* IDMASTAREG +- * IDST[0] : idma tx int +- * IDST[1] : idma rx int +- * IDST[2] : idma fatal bus error +- * IDST[4] : idma descriptor invalid +- * IDST[5] : idma error summary +- * IDST[8] : idma normal interrupt sumary +- * IDST[9] : idma abnormal interrupt sumary +- */ +- status = readl(&mmchost->reg->idst); +- writel(status, &mmchost->reg->idst); +- writel(0, &mmchost->reg->idie); +- writel(0, &mmchost->reg->dmac); +- writel(readl(&mmchost->reg->gctrl) & ~SUNXI_MMC_GCTRL_DMA_ENABLE, +- &mmchost->reg->gctrl); +- } + if (error < 0) { + writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); + mmc_update_clk(mmc); +diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h +index 8e15dc9..33ac646 100644 +--- a/include/configs/sunxi-common.h ++++ b/include/configs/sunxi-common.h +@@ -82,7 +82,6 @@ + #define CONFIG_CMD_MMC + #define CONFIG_MMC_SUNXI + #define CONFIG_MMC_SUNXI_SLOT 0 +-#define CONFIG_MMC_SUNXI_USE_DMA + #define CONFIG_ENV_IS_IN_MMC + #define CONFIG_SYS_MMC_ENV_DEV 0 /* first detected MMC controller */ + -- 2.0.0