From 7a0bbe64d8ec87e07179fe6124dc8a177b5abd3e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 14 Aug 2015 16:19:34 +0200 Subject: [PATCH 01/31] sunxi: axp221: Allow specifying dcdc2 voltage via Kconfig Allow specifying the axp221 dcdc2 voltage via Kconfig, this is necessary because on some boards the 1.2V default does not work reliable. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/board.c | 2 +- drivers/power/Kconfig | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/board/sunxi/board.c b/board/sunxi/board.c index f85e825891..680523ac63 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -437,7 +437,7 @@ void sunxi_board_init(void) #ifdef CONFIG_AXP221_POWER power_failed = axp221_init(); power_failed |= axp221_set_dcdc1(CONFIG_AXP221_DCDC1_VOLT); - power_failed |= axp221_set_dcdc2(1200); /* A31:VDD-GPU, A23:VDD-SYS */ + power_failed |= axp221_set_dcdc2(CONFIG_AXP221_DCDC2_VOLT); power_failed |= axp221_set_dcdc3(1200); /* VDD-CPU */ #ifdef CONFIG_MACH_SUN6I power_failed |= axp221_set_dcdc4(1200); /* A31:VDD-SYS */ diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 23cdd714ae..df5e3734b0 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -22,6 +22,15 @@ config AXP221_DCDC1_VOLT things like GPIO-s, sdcard interfaces, etc. On most boards this is undervolted to 3.0V to safe battery. +config AXP221_DCDC2_VOLT + int "axp221 dcdc2 voltage" + depends on AXP221_POWER + default 1200 + ---help--- + Set the voltage (mV) to program the axp221 dcdc2 at, set to 0 to + disable dcdc2. On A31 boards this is typically used for VDD-GPU, + on A23/A33 for VDD-SYS, this should normally be set to 1.2V. + config AXP221_DLDO1_VOLT int "axp221 dldo1 voltage" depends on AXP221_POWER From f9a37289b83100cf9c75114283c1216c1149386c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 14 Aug 2015 16:13:03 +0200 Subject: [PATCH 02/31] sunxi: Add support for gt90h-v4 tablets The gt90h is a pcb found in generic 9" tablets with an A23 soc, 1G RAM and 8G nand, rtl8723as usb wifi, 1 micro usb port and 1 micro sd slot. The pmic setup on this board is somewhat special, dcdc2 MUST be set to 1.1V instead of the usual 1.2V otherwise the board is very unstable. aldo1 is used to power the micro sd slot, dldo1 is used for wifi. This commit adds a defconfig + dts (as submitted to the kernel) for the gt90h-v4 pcb. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/dts/Makefile | 1 + arch/arm/dts/sun8i-a23-gt90h-v4.dts | 145 ++++++++++++++++++++++++++++ board/sunxi/MAINTAINERS | 1 + configs/gt90h_v4_defconfig | 26 +++++ 4 files changed, 173 insertions(+) create mode 100644 arch/arm/dts/sun8i-a23-gt90h-v4.dts create mode 100644 configs/gt90h_v4_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index c4c4344759..d65876fad7 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -134,6 +134,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \ sun7i-a20-yones-toptech-bd1078.dtb dtb-$(CONFIG_MACH_SUN8I_A23) += \ sun8i-a23-evb.dtb \ + sun8i-a23-gt90h-v4.dtb \ sun8i-a23-ippo-q8h-v5.dtb \ sun8i-a23-ippo-q8h-v1.2.dtb dtb-$(CONFIG_MACH_SUN8I_A33) += \ diff --git a/arch/arm/dts/sun8i-a23-gt90h-v4.dts b/arch/arm/dts/sun8i-a23-gt90h-v4.dts new file mode 100644 index 0000000000..1aeb06c649 --- /dev/null +++ b/arch/arm/dts/sun8i-a23-gt90h-v4.dts @@ -0,0 +1,145 @@ +/* + * Copyright 2015 Hans de Goede + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun8i-a23.dtsi" +#include "sunxi-common-regulators.dtsi" + +#include +#include +#include + +/ { + model = "Allwinner GT90H Quad Core Tablet (v4)"; + compatible = "allwinner,gt90h-v4", "allwinner,sun8i-a33"; + + aliases { + serial0 = &r_uart; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; +}; + +&lradc { + vref-supply = <®_vcc3v0>; + status = "okay"; + + button@200 { + label = "Volume Up"; + linux,code = ; + channel = <0>; + voltage = <200000>; + }; + + button@400 { + label = "Volume Down"; + linux,code = ; + channel = <0>; + voltage = <400000>; + }; + + button@600 { + label = "Back"; + linux,code = ; + channel = <0>; + voltage = <600000>; + }; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_gt90h>; + /* FIXME this really is aldo1, correct once we've pmic support */ + vmmc-supply = <®_vcc3v0>; + bus-width = <4>; + cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */ + cd-inverted; + status = "okay"; +}; + +&pio { + mmc0_cd_pin_gt90h: mmc0_cd_pin@0 { + allwinner,pins = "PB4"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; +}; + +&r_uart { + pinctrl-names = "default"; + pinctrl-0 = <&r_uart_pins_a>; + status = "okay"; +}; + +/* + * FIXME for now we only support host mode and rely on u-boot to have + * turned on Vbus which is controlled by the axp223 pmic on the board. + * + * Once we have axp223 support we should switch to fully supporting otg. + */ +&usb_otg { + dr_mode = "host"; + status = "okay"; +}; + +&usbphy { + status = "okay"; +}; diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 1b44ce8e09..de99fe137c 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -40,6 +40,7 @@ F: configs/qt840a_defconfig F: configs/Wits_Pro_A20_DKT_defconfig F: include/configs/sun8i.h F: configs/ga10h_v1_1_defconfig +F: configs/gt90h_v4_defconfig F: configs/Ippo_q8h_v1_2_defconfig F: configs/Ippo_q8h_v1_2_a33_1024x600_defconfig F: include/configs/sun9i.h diff --git a/configs/gt90h_v4_defconfig b/configs/gt90h_v4_defconfig new file mode 100644 index 0000000000..3b72dc2e6d --- /dev/null +++ b/configs/gt90h_v4_defconfig @@ -0,0 +1,26 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN8I_A23=y +CONFIG_DRAM_CLK=480 +CONFIG_DRAM_ZQ=32767 +CONFIG_MMC0_CD_PIN="PB4" +CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE" +CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT" +CONFIG_USB0_ID_DET="PH8" +CONFIG_AXP_GPIO=y +CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:18,pclk_khz:55000,le:159,ri:160,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_DCLK_PHASE=0 +CONFIG_VIDEO_LCD_POWER="PH7" +CONFIG_VIDEO_LCD_BL_EN="PH6" +CONFIG_VIDEO_LCD_BL_PWM="PH0" +CONFIG_USB_MUSB_HOST=y +CONFIG_DEFAULT_DEVICE_TREE="sun8i-a23-gt90h-v4" +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5" +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set +CONFIG_AXP221_DCDC2_VOLT=1100 +CONFIG_AXP221_DLDO1_VOLT=3300 +CONFIG_AXP221_ALDO1_VOLT=3000 From 7806b75a0582cee9ddea46fd9b03e06e774455f7 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 16 Aug 2015 11:15:29 +0200 Subject: [PATCH 03/31] sunxi: musb: Drop no longer accurate comment in Kconfig help text Drop the no longer accurate part of the USB_MUSB_SUNXI Kconfig help text, since the musb-host code now supports the device-model, ehci and musb in host mode can both be enabled at the same time without issues. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/usb/musb-new/Kconfig | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/musb-new/Kconfig b/drivers/usb/musb-new/Kconfig index 0082ff87f0..6a6cb93b4c 100644 --- a/drivers/usb/musb-new/Kconfig +++ b/drivers/usb/musb-new/Kconfig @@ -21,8 +21,6 @@ config USB_MUSB_SUNXI default y ---help--- Say y here to enable support for the sunxi OTG / DRC USB controller - used on almost all sunxi boards. Note currently u-boot can only have - one usb host controller enabled at a time, so enabling this on boards - which also use the ehci host controller will result in build errors. + used on almost all sunxi boards. endif From 8addd3ed7e6c1bcc54a4c9062e0bec6c302b462d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 16 Aug 2015 11:23:42 +0200 Subject: [PATCH 04/31] sunxi: Drop LCD_MODE from A13-OLinuxIno defconfigs With the unified / cleaned up default display output selection changes, which were done as part of adding composite video out support, our example LCD_MODE line in the A13-OLinuxIno defconfigs causes the display code to setup a LCD console by default, rather then a VGA console. Given that the LCD console is only useful for people who have hooked up the exact lcd-panel from the config, while most people will not have any lcd panel connected to these boards, this is not a good default. Dropping the LCD_MODE line which was intended as an example fixes this, instead add a link to the LCD_MODE help text pointing to http://linux-sunxi.org/LCD which contains the removed and other example modes. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/Kconfig | 1 + configs/A13-OLinuXinoM_defconfig | 1 - configs/A13-OLinuXino_defconfig | 1 - 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index fd6668fea2..55906b5b76 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -425,6 +425,7 @@ config VIDEO_LCD_MODE LCD panel timing details string, leave empty if there is no LCD panel. This is in drivers/video/videomodes.c: video_get_params() format, e.g. x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:0,vmode:0 + Also see: http://linux-sunxi.org/LCD config VIDEO_LCD_DCLK_PHASE int "LCD panel display clock phase" diff --git a/configs/A13-OLinuXinoM_defconfig b/configs/A13-OLinuXinoM_defconfig index dcaaff9220..5852be6d43 100644 --- a/configs/A13-OLinuXinoM_defconfig +++ b/configs/A13-OLinuXinoM_defconfig @@ -7,7 +7,6 @@ CONFIG_USB1_VBUS_PIN="PG11" # CONFIG_VIDEO_HDMI is not set CONFIG_VIDEO_VGA_VIA_LCD=y CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y -CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_POWER="PB10" CONFIG_VIDEO_LCD_BL_PWM="PB2" CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino-micro" diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig index 4b4337223c..f1961f3190 100644 --- a/configs/A13-OLinuXino_defconfig +++ b/configs/A13-OLinuXino_defconfig @@ -8,7 +8,6 @@ CONFIG_AXP_GPIO=y # CONFIG_VIDEO_HDMI is not set CONFIG_VIDEO_VGA_VIA_LCD=y CONFIG_VIDEO_VGA_VIA_LCD_FORCE_SYNC_ACTIVE_HIGH=y -CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:16,ri:209,up:22,lo:22,hs:30,vs:1,sync:3,vmode:0" CONFIG_VIDEO_LCD_POWER="AXP0-0" CONFIG_VIDEO_LCD_BL_PWM="PB2" CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino" From 6c16d089fbfcd661b19030bc994f75577d9a7c4d Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 11:46:01 +0200 Subject: [PATCH 05/31] sunxi: Add CONFIG_MMC0_CD_PIN to various boards Add CONFIG_MMC0_CD_PIN to various boards, this stops the SPL from still trying to access the sdcard when there is none (e.g. when booting from nand). Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- configs/A10-OLinuXino-Lime_defconfig | 1 + configs/A13-OLinuXinoM_defconfig | 1 + configs/A13-OLinuXino_defconfig | 1 + configs/A20-OLinuXino-Lime_defconfig | 1 + configs/Cubieboard_defconfig | 1 + configs/Cubietruck_defconfig | 1 + 6 files changed, 6 insertions(+) diff --git a/configs/A10-OLinuXino-Lime_defconfig b/configs/A10-OLinuXino-Lime_defconfig index 0245bfc763..ee219f82fd 100644 --- a/configs/A10-OLinuXino-Lime_defconfig +++ b/configs/A10-OLinuXino-Lime_defconfig @@ -3,6 +3,7 @@ CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN4I=y CONFIG_DRAM_CLK=480 CONFIG_DRAM_EMR1=4 +CONFIG_MMC0_CD_PIN="PH1" CONFIG_SYS_CLK_FREQ=912000000 CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-olinuxino-lime" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set diff --git a/configs/A13-OLinuXinoM_defconfig b/configs/A13-OLinuXinoM_defconfig index 5852be6d43..ccf35c784c 100644 --- a/configs/A13-OLinuXinoM_defconfig +++ b/configs/A13-OLinuXinoM_defconfig @@ -3,6 +3,7 @@ CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN5I=y CONFIG_DRAM_CLK=408 CONFIG_DRAM_EMR1=0 +CONFIG_MMC0_CD_PIN="PG0" CONFIG_USB1_VBUS_PIN="PG11" # CONFIG_VIDEO_HDMI is not set CONFIG_VIDEO_VGA_VIA_LCD=y diff --git a/configs/A13-OLinuXino_defconfig b/configs/A13-OLinuXino_defconfig index f1961f3190..1f68d98cba 100644 --- a/configs/A13-OLinuXino_defconfig +++ b/configs/A13-OLinuXino_defconfig @@ -3,6 +3,7 @@ CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN5I=y CONFIG_DRAM_CLK=408 CONFIG_DRAM_EMR1=0 +CONFIG_MMC0_CD_PIN="PG0" CONFIG_USB1_VBUS_PIN="PG11" CONFIG_AXP_GPIO=y # CONFIG_VIDEO_HDMI is not set diff --git a/configs/A20-OLinuXino-Lime_defconfig b/configs/A20-OLinuXino-Lime_defconfig index fb1f24002c..4a257b3d35 100644 --- a/configs/A20-OLinuXino-Lime_defconfig +++ b/configs/A20-OLinuXino-Lime_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=480 +CONFIG_MMC0_CD_PIN="PH1" CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-olinuxino-lime" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SPL=y diff --git a/configs/Cubieboard_defconfig b/configs/Cubieboard_defconfig index fa60ddf415..bbda5bfa5c 100644 --- a/configs/Cubieboard_defconfig +++ b/configs/Cubieboard_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN4I=y CONFIG_DRAM_CLK=480 +CONFIG_MMC0_CD_PIN="PH1" CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-cubieboard" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_SPL=y diff --git a/configs/Cubietruck_defconfig b/configs/Cubietruck_defconfig index b8809c806b..e1b76ce78c 100644 --- a/configs/Cubietruck_defconfig +++ b/configs/Cubietruck_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_ARCH_SUNXI=y CONFIG_MACH_SUN7I=y CONFIG_DRAM_CLK=432 +CONFIG_MMC0_CD_PIN="PH1" CONFIG_VIDEO_VGA=y CONFIG_GMAC_TX_DELAY=1 CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-cubietruck" From 21d4d37aaf06acc6d274751b9f54492696606a50 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 09:38:22 +0200 Subject: [PATCH 06/31] sunxi_nand_spl: Fix CONFIG_SPL_NAND_SUNXI handling CONFIG_SPL_NAND_SUPPORT gets used via IS_ENABLED so it must be defined to 1, rather then just being defined. While at remove 2 other unused NAND related defines from sunxi-common.h. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- include/configs/sunxi-common.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 1abf73c311..3735afbafc 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -138,15 +138,10 @@ #define CONFIG_SERIAL_TAG #if defined(CONFIG_SPL_NAND_SUNXI) -#define CONFIG_SPL_NAND_DRIVERS -#define CONFIG_SPL_NAND_SUPPORT - -#define CONFIG_SYS_NAND_SPL_KERNEL_OFFS 0x280000 +#define CONFIG_SPL_NAND_SUPPORT 1 #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x008000 - #endif - /* mmc config */ #if !defined(CONFIG_UART0_PORT_F) #define CONFIG_MMC From 10d069b79734942226223178a9e18b26da60002f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 09:33:41 +0200 Subject: [PATCH 07/31] sunxi_nand_spl: Drop unnecessary temp buf nand_spl_load_image() always gets called with either CONFIG_SYS_TEXT_BASE or spl_image.load_addr as destination, both of which are properly aligened, and have plenty of space for "overshooting" up to CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE bytes, as we read in CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE bytes chunks. This saves CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE (typically 1k) in SPL size, which is a lot on the total 24k we have. Note this changes the dma destination from SRAM to DRAM, so this patch updates the DDMA_DST_TYPE bits in the dma controller cfg0 reg accordingly. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mtd/nand/sunxi_nand_spl.c | 35 +++++++------------------------ 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index ac5f56d066..46654e4ef6 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -85,6 +85,7 @@ #define SUNXI_DMA_DDMA_CFG_REG_LOADING (1 << 31) #define SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 (2 << 25) +#define SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM (1 << 16) #define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 (2 << 9) #define SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO (1 << 5) #define SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC (3 << 0) @@ -94,10 +95,6 @@ /* minimal "boot0" style NAND support for Allwinner A20 */ -/* temporary buffer in internal ram */ -unsigned char temp_buf[CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE] - __aligned(0x10) __section(".text#"); - /* random seed used by linux */ const uint16_t random_seed[128] = { 0x2b75, 0x0bd0, 0x5ca3, 0x62d1, 0x1c93, 0x07e9, 0x2162, 0x3a72, @@ -167,8 +164,8 @@ void nand_init(void) } } -static void nand_read_page(unsigned int real_addr, int syndrome, - uint32_t *ecc_errors) +static void nand_read_page(unsigned int real_addr, dma_addr_t dst, + int syndrome, uint32_t *ecc_errors) { uint32_t val; int ecc_off = 0; @@ -226,9 +223,6 @@ static void nand_read_page(unsigned int real_addr, int syndrome, return; } - /* clear temp_buf */ - memset(temp_buf, 0, CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE); - /* set CMD */ writel(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET, SUNXI_NFC_BASE + NFC_CMD); @@ -278,8 +272,7 @@ static void nand_read_page(unsigned int real_addr, int syndrome, writel(SUNXI_NFC_BASE + NFC_IO_DATA, SUNXI_DMA_BASE + SUNXI_DMA_SRC_START_ADDR_REG0); /* read to RAM */ - writel((uint32_t)temp_buf, - SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0); + writel(dst, SUNXI_DMA_BASE + SUNXI_DMA_DEST_START_ADDRR_REG0); writel(SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC | SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE, SUNXI_DMA_BASE + SUNXI_DMA_DDMA_PARA_REG0); @@ -287,6 +280,7 @@ static void nand_read_page(unsigned int real_addr, int syndrome, SUNXI_DMA_BASE + SUNXI_DMA_DDMA_BC_REG0); /* 1kB */ writel(SUNXI_DMA_DDMA_CFG_REG_LOADING | SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 + | SUNXI_DMA_DDMA_CFG_REG_DDMA_DST_DRQ_TYPE_DRAM | SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_DATA_WIDTH_32 | SUNXI_DMA_DDMA_CFG_REG_DMA_SRC_ADDR_MODE_IO | SUNXI_DMA_DDMA_CFG_REG_DDMA_SRC_DRQ_TYPE_NFC, @@ -324,27 +318,14 @@ static void nand_read_page(unsigned int real_addr, int syndrome, int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest) { void *current_dest; - uint32_t count; - uint32_t current_count; uint32_t ecc_errors = 0; - memset(dest, 0x0, size); /* clean destination memory */ for (current_dest = dest; current_dest < (dest + size); current_dest += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) { - nand_read_page(offs, offs - < CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END, - &ecc_errors); - count = current_dest - dest; - - if (size - count > CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) - current_count = CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE; - else - current_count = size - count; - - memcpy(current_dest, - temp_buf, - current_count); + nand_read_page(offs, (dma_addr_t)current_dest, + offs < CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END, + &ecc_errors); offs += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE; } return ecc_errors ? -1 : 0; From 630cf2e7628502b410622fcfa72bd553a94dfa93 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 11:38:33 +0200 Subject: [PATCH 08/31] sunxi_nand_spl: We only need to reset the nand chip once There is no need to reset the nand chip for every ecc-block read. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mtd/nand/sunxi_nand_spl.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index 46654e4ef6..56c0be02f5 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -162,6 +162,16 @@ void nand_init(void) NFC_CTL_RESET, MAX_RETRIES)) { printf("Couldn't initialize nand\n"); } + + /* reset NAND */ + writel(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET, + SUNXI_NFC_BASE + NFC_CMD); + + if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_CMD_INT_FLAG, + MAX_RETRIES)) { + printf("Error timeout waiting for nand reset\n"); + return; + } } static void nand_read_page(unsigned int real_addr, dma_addr_t dst, @@ -223,16 +233,6 @@ static void nand_read_page(unsigned int real_addr, dma_addr_t dst, return; } - /* set CMD */ - writel(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET, - SUNXI_NFC_BASE + NFC_CMD); - - if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_CMD_INT_FLAG, - MAX_RETRIES)) { - printf("Error while initilizing command interrupt\n"); - return; - } - page = real_addr / CONFIG_NAND_SUNXI_SPL_PAGE_SIZE; column = real_addr % CONFIG_NAND_SUNXI_SPL_PAGE_SIZE; From 9da5fca55cbf9465052256346f6e61968acedf2f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 12:43:26 +0200 Subject: [PATCH 09/31] sunxi_nand_spl: Do not bother writing the spare-area reg in syndrome mode In syndrome mode we set the NFC_SEQ bit in the command register, so the spare-area register is not used. Also the value currently being written is actual wrong, the ecc sits at "column + CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE" not just CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE. So the current code only serves to confuse the user -> remove it. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mtd/nand/sunxi_nand_spl.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index 56c0be02f5..f6f49289f8 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -256,10 +256,7 @@ static void nand_read_page(unsigned int real_addr, dma_addr_t dst, val = readl(SUNXI_NFC_BASE + NFC_CTL); writel(val | NFC_CTL_RAM_METHOD, SUNXI_NFC_BASE + NFC_CTL); - if (syndrome) { - writel(CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE, - SUNXI_NFC_BASE + NFC_SPARE_AREA); - } else { + if (!syndrome) { oob_offset = CONFIG_NAND_SUNXI_SPL_PAGE_SIZE + (column / CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) * ecc_off; From f62bfa56daf17e3e8fac85795196c0ffad42e444 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 11:55:26 +0200 Subject: [PATCH 10/31] sunxi_nand_spl: Use SYS_NAND_SELF_INIT and only do nand init when necessary Use SYS_NAND_SELF_INIT and only setup the pinmux and clocks when we are actually using the nand. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/board.c | 12 +++++++----- drivers/mtd/nand/Kconfig | 1 + drivers/mtd/nand/sunxi_nand_spl.c | 2 ++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 680523ac63..b76bb83251 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD) @@ -127,6 +128,12 @@ static void nand_clock_setup(void) setbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0)); setbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1); } + +void board_nand_init(void) +{ + nand_pinmux_setup(); + nand_clock_setup(); +} #endif #ifdef CONFIG_GENERIC_MMC @@ -453,11 +460,6 @@ void sunxi_board_init(void) power_failed |= axp221_set_eldo(3, CONFIG_AXP221_ELDO3_VOLT); #endif -#ifdef CONFIG_SPL_NAND_SUNXI - nand_pinmux_setup(); - nand_clock_setup(); -#endif - printf("DRAM:"); ramsize = sunxi_dram_init(); printf(" %lu MiB\n", ramsize >> 20); diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index b6dfb0e835..28597f0c8b 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -95,6 +95,7 @@ config SPL_NAND_DENALI config SPL_NAND_SUNXI bool "Support for NAND on Allwinner A20 in SPL" depends on MACH_SUN7I + select SYS_NAND_SELF_INIT ---help--- Enable support for NAND. This option allows SPL to read from sunxi NAND using DMA transfers. diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index f6f49289f8..9efe904cc7 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -153,6 +153,8 @@ void nand_init(void) { uint32_t val; + board_nand_init(); + val = readl(SUNXI_NFC_BASE + NFC_CTL); /* enable and reset CTL */ writel(val | NFC_CTL_EN | NFC_CTL_RESET, From 31c21471debbc9cec7466088da4fe2ee970d33b6 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 11:58:03 +0200 Subject: [PATCH 11/31] sunxi_nand_spl: Make sure the DMA controller is enabled We use DMA for nand data transfers in the SPL, so make sure the DMA controller is enabled. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/board.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/board/sunxi/board.c b/board/sunxi/board.c index b76bb83251..1ebd0a423d 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -125,7 +125,13 @@ static void nand_clock_setup(void) { struct sunxi_ccm_reg *const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + setbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0)); +#ifdef CONFIG_MACH_SUN9I + setbits_le32(&ccm->ahb_gate1, (1 << AHB_GATE_OFFSET_DMA)); +#else + setbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_DMA)); +#endif setbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1); } From 5d65c67bf10bc5a815023ac13a2689aee9956d92 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 11:59:25 +0200 Subject: [PATCH 12/31] sunxi_nand_spl: Turn off clocks when we're done with the nand Turn off the nand and dma clocks when we're done with the nand, this puts the nand and dma controllers back into a clean state for when the kernel boots. Without this the kernel will not boot properly when it is built with dma-controller support. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mtd/nand/sunxi_nand_spl.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index 9efe904cc7..147d47638f 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -5,9 +5,10 @@ * SPDX-License-Identifier: GPL-2.0+ */ +#include +#include #include #include -#include #include /* registers */ @@ -330,4 +331,16 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest) return ecc_errors ? -1 : 0; } -void nand_deselect(void) {} +void nand_deselect(void) +{ + struct sunxi_ccm_reg *const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + clrbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0)); +#ifdef CONFIG_MACH_SUN9I + clrbits_le32(&ccm->ahb_gate1, (1 << AHB_GATE_OFFSET_DMA)); +#else + clrbits_le32(&ccm->ahb_gate0, (1 << AHB_GATE_OFFSET_DMA)); +#endif + clrbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1); +} From 2a43973f64bce7dba1a5aabd18f2268f062aa0ef Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 12:32:24 +0200 Subject: [PATCH 13/31] sunxi_nand_spl: Add proper cache flusing We are using dma, so we should flush the cache before starting the dma, and invalidate it once the dma is done. Things are working without this by mostly luck, but lets not rely on that. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mtd/nand/sunxi_nand_spl.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index 147d47638f..663c03ec4f 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -266,6 +266,10 @@ static void nand_read_page(unsigned int real_addr, dma_addr_t dst, writel(oob_offset, SUNXI_NFC_BASE + NFC_SPARE_AREA); } + flush_dcache_range(dst, + ALIGN(dst + CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE, + ARCH_DMA_MINALIGN)); + /* SUNXI_DMA */ writel(0x0, SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0); /* clr dma cmd */ /* read from REG_IO_DATA */ @@ -311,6 +315,10 @@ static void nand_read_page(unsigned int real_addr, dma_addr_t dst, return; } + invalidate_dcache_range(dst, + ALIGN(dst + CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE, + ARCH_DMA_MINALIGN)); + if (readl(SUNXI_NFC_BASE + NFC_ECC_ST)) (*ecc_errors)++; } From 008ac1dfe0815476cca819c16e06616c12c303b7 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 12:41:09 +0200 Subject: [PATCH 14/31] sunxi_nand_spl: Use kernel driver algorithm for determining ecc_mode / _off Sync the code for figuring out the ecc_mode and ecc_offset with the linux kernel v4.1. Keeping this in sync seems like a good idea in general, and it fixes / adds support for ecc strengths of 56, 60 and 64 bits. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mtd/nand/sunxi_nand_spl.c | 58 +++++++------------------------ 1 file changed, 12 insertions(+), 46 deletions(-) diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index 663c03ec4f..61eb393446 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -181,60 +181,26 @@ static void nand_read_page(unsigned int real_addr, dma_addr_t dst, int syndrome, uint32_t *ecc_errors) { uint32_t val; - int ecc_off = 0; + int i, ecc_off = 0; uint16_t ecc_mode = 0; uint16_t rand_seed; uint32_t page; uint16_t column; uint32_t oob_offset; + static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 }; - switch (CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH) { - case 16: - ecc_mode = 0; - ecc_off = 0x20; - break; - case 24: - ecc_mode = 1; - ecc_off = 0x2e; - break; - case 28: - ecc_mode = 2; - ecc_off = 0x32; - break; - case 32: - ecc_mode = 3; - ecc_off = 0x3c; - break; - case 40: - ecc_mode = 4; - ecc_off = 0x4a; - break; - case 48: - ecc_mode = 4; - ecc_off = 0x52; - break; - case 56: - ecc_mode = 4; - ecc_off = 0x60; - break; - case 60: - ecc_mode = 4; - ecc_off = 0x0; - break; - case 64: - ecc_mode = 4; - ecc_off = 0x0; - break; - default: - ecc_mode = 0; - ecc_off = 0; + for (i = 0; i < ARRAY_SIZE(strengths); i++) { + if (CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH == strengths[i]) { + ecc_mode = i; + break; + } } - if (ecc_off == 0) { - printf("Unsupported ECC strength (%d)!\n", - CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH); - return; - } + /* HW ECC always request ECC bytes for 1024 bytes blocks */ + ecc_off = DIV_ROUND_UP(CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH * fls(8 * 1024), 8); + /* HW ECC always work with even numbers of ECC bytes */ + ecc_off += (ecc_off & 1); + ecc_off += 4; /* prepad */ page = real_addr / CONFIG_NAND_SUNXI_SPL_PAGE_SIZE; column = real_addr % CONFIG_NAND_SUNXI_SPL_PAGE_SIZE; From 022a99d8b2f84e6bda44e6dcfd1748219b665143 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 13:17:49 +0200 Subject: [PATCH 15/31] sunxi_nand_spl: Add support for sun4i and sun5i SoCs Other then having a few less chip-select lines the nand controller on sun4i, sun5i and sun7i is identical. Note this patch also muxes GPC7 to the NAND on sun7i where as before it was not muxed this way. GPC7 is a standard NAND pin, so it should always be muxed to the NAND when in use. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/board.c | 12 +++++++++--- drivers/mtd/nand/Kconfig | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/board/sunxi/board.c b/board/sunxi/board.c index 1ebd0a423d..d411e96c76 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -112,13 +112,19 @@ int dram_init(void) static void nand_pinmux_setup(void) { unsigned int pin; - for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(6); pin++) + + for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(19); pin++) sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND); - for (pin = SUNXI_GPC(8); pin <= SUNXI_GPC(22); pin++) +#if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN7I + for (pin = SUNXI_GPC(20); pin <= SUNXI_GPC(22); pin++) sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND); - +#endif + /* sun4i / sun7i do have a PC23, but it is not used for nand, + * only sun7i has a PC24 */ +#ifdef CONFIG_MACH_SUN7I sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_NAND); +#endif } static void nand_clock_setup(void) diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 28597f0c8b..8fac5e873b 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -93,8 +93,8 @@ config SPL_NAND_DENALI for use on SPL. config SPL_NAND_SUNXI - bool "Support for NAND on Allwinner A20 in SPL" - depends on MACH_SUN7I + bool "Support for NAND on Allwinner SoCs in SPL" + depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I select SYS_NAND_SELF_INIT ---help--- Enable support for NAND. This option allows SPL to read from From 0a247554c2dec96e693c1b02761cf0b5d5189fc0 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 20:05:13 +0200 Subject: [PATCH 16/31] sunxi_nand_spl: Properly config page-size in the nand ctl register Properly config page-size in the nand ctl register, it seems that things work fine without doing this, but still lets play it safe and properly set the page-size. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mtd/nand/sunxi_nand_spl.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index 61eb393446..872cedfd5e 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -42,6 +42,8 @@ #define NFC_CTL_EN (1 << 0) #define NFC_CTL_RESET (1 << 1) #define NFC_CTL_RAM_METHOD (1 << 14) +#define NFC_CTL_PAGE_SIZE_MASK (0xf << 8) +#define NFC_CTL_PAGE_SIZE(a) ((fls(a) - 11) << 8) #define NFC_ECC_EN (1 << 0) @@ -294,6 +296,9 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest) void *current_dest; uint32_t ecc_errors = 0; + clrsetbits_le32(SUNXI_NFC_BASE + NFC_CTL, NFC_CTL_PAGE_SIZE_MASK, + NFC_CTL_PAGE_SIZE(CONFIG_NAND_SUNXI_SPL_PAGE_SIZE)); + for (current_dest = dest; current_dest < (dest + size); current_dest += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) { From f5916d1856cb043f79304a99103a2f910298eecc Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 20:51:53 +0200 Subject: [PATCH 17/31] sunxi_nand_spl: Parametrize lowlevel read functions Parametrize the lowlevel nand_read_page function, instead of directly using the CONFIG_foo settings for page-size, etc. there and add a few wrappers / helper functions for calling it. This is a preparation patch for adding auto-detecting of the nand parameters like the BROM does. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mtd/nand/sunxi_nand_spl.c | 88 +++++++++++++++++-------------- 1 file changed, 49 insertions(+), 39 deletions(-) diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index 872cedfd5e..3206a50202 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -179,8 +179,8 @@ void nand_init(void) } } -static void nand_read_page(unsigned int real_addr, dma_addr_t dst, - int syndrome, uint32_t *ecc_errors) +static int nand_read_page(int page_size, int ecc_strength, int ecc_page_size, + int addr_cycles, uint32_t real_addr, dma_addr_t dst, int syndrome) { uint32_t val; int i, ecc_off = 0; @@ -188,28 +188,26 @@ static void nand_read_page(unsigned int real_addr, dma_addr_t dst, uint16_t rand_seed; uint32_t page; uint16_t column; - uint32_t oob_offset; static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 }; for (i = 0; i < ARRAY_SIZE(strengths); i++) { - if (CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH == strengths[i]) { + if (ecc_strength == strengths[i]) { ecc_mode = i; break; } } /* HW ECC always request ECC bytes for 1024 bytes blocks */ - ecc_off = DIV_ROUND_UP(CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH * fls(8 * 1024), 8); + ecc_off = DIV_ROUND_UP(ecc_strength * fls(8 * 1024), 8); /* HW ECC always work with even numbers of ECC bytes */ ecc_off += (ecc_off & 1); ecc_off += 4; /* prepad */ - page = real_addr / CONFIG_NAND_SUNXI_SPL_PAGE_SIZE; - column = real_addr % CONFIG_NAND_SUNXI_SPL_PAGE_SIZE; + page = real_addr / page_size; + column = real_addr % page_size; if (syndrome) - column += (column / CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) - * ecc_off; + column += (column / ecc_page_size) * ecc_off; /* clear ecc status */ writel(0, SUNXI_NFC_BASE + NFC_ECC_ST); @@ -227,16 +225,11 @@ static void nand_read_page(unsigned int real_addr, dma_addr_t dst, val = readl(SUNXI_NFC_BASE + NFC_CTL); writel(val | NFC_CTL_RAM_METHOD, SUNXI_NFC_BASE + NFC_CTL); - if (!syndrome) { - oob_offset = CONFIG_NAND_SUNXI_SPL_PAGE_SIZE - + (column / CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) - * ecc_off; - writel(oob_offset, SUNXI_NFC_BASE + NFC_SPARE_AREA); - } + if (!syndrome) + writel(page_size + (column / ecc_page_size) * ecc_off, + SUNXI_NFC_BASE + NFC_SPARE_AREA); - flush_dcache_range(dst, - ALIGN(dst + CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE, - ARCH_DMA_MINALIGN)); + flush_dcache_range(dst, ALIGN(dst + ecc_page_size, ARCH_DMA_MINALIGN)); /* SUNXI_DMA */ writel(0x0, SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0); /* clr dma cmd */ @@ -248,7 +241,7 @@ static void nand_read_page(unsigned int real_addr, dma_addr_t dst, writel(SUNXI_DMA_DDMA_PARA_REG_SRC_WAIT_CYC | SUNXI_DMA_DDMA_PARA_REG_SRC_BLK_SIZE, SUNXI_DMA_BASE + SUNXI_DMA_DDMA_PARA_REG0); - writel(CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE, + writel(ecc_page_size, SUNXI_DMA_BASE + SUNXI_DMA_DDMA_BC_REG0); /* 1kB */ writel(SUNXI_DMA_DDMA_CFG_REG_LOADING | SUNXI_DMA_DDMA_CFG_REG_DMA_DEST_DATA_WIDTH_32 @@ -267,47 +260,64 @@ static void nand_read_page(unsigned int real_addr, dma_addr_t dst, SUNXI_NFC_BASE + NFC_ADDR_LOW); writel((page >> 16) & 0xFF, SUNXI_NFC_BASE + NFC_ADDR_HIGH); writel(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_DATA_TRANS | - NFC_PAGE_CMD | NFC_WAIT_FLAG | (4 << NFC_ADDR_NUM_OFFSET) | + NFC_PAGE_CMD | NFC_WAIT_FLAG | + ((addr_cycles - 1) << NFC_ADDR_NUM_OFFSET) | NFC_SEND_ADR | NFC_DATA_SWAP_METHOD | (syndrome ? NFC_SEQ : 0), SUNXI_NFC_BASE + NFC_CMD); if (!check_value(SUNXI_NFC_BASE + NFC_ST, (1 << 2), MAX_RETRIES)) { printf("Error while initializing dma interrupt\n"); - return; + return -1; } if (!check_value_negated(SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0, SUNXI_DMA_DDMA_CFG_REG_LOADING, MAX_RETRIES)) { printf("Error while waiting for dma transfer to finish\n"); - return; + return -1; } invalidate_dcache_range(dst, - ALIGN(dst + CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE, - ARCH_DMA_MINALIGN)); + ALIGN(dst + ecc_page_size, ARCH_DMA_MINALIGN)); if (readl(SUNXI_NFC_BASE + NFC_ECC_ST)) - (*ecc_errors)++; + return -1; + + return 0; +} + +static int nand_read_ecc(int page_size, int ecc_strength, int ecc_page_size, + int addr_cycles, uint32_t offs, uint32_t size, void *dest, int syndrome) +{ + void *end = dest + size; + + clrsetbits_le32(SUNXI_NFC_BASE + NFC_CTL, NFC_CTL_PAGE_SIZE_MASK, + NFC_CTL_PAGE_SIZE(page_size)); + + for ( ;dest < end; dest += ecc_page_size, offs += ecc_page_size) { + if (nand_read_page(page_size, ecc_strength, ecc_page_size, + addr_cycles, offs, (dma_addr_t)dest, + syndrome)) + return -1; + } + + return 0; +} + +static int nand_read_buffer(uint32_t offs, unsigned int size, void *dest, + int syndrome) +{ + return nand_read_ecc(CONFIG_NAND_SUNXI_SPL_PAGE_SIZE, + CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH, + CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE, + 5, offs, size, dest, syndrome); } int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest) { - void *current_dest; - uint32_t ecc_errors = 0; + int syndrome = offs < CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END; - clrsetbits_le32(SUNXI_NFC_BASE + NFC_CTL, NFC_CTL_PAGE_SIZE_MASK, - NFC_CTL_PAGE_SIZE(CONFIG_NAND_SUNXI_SPL_PAGE_SIZE)); - - for (current_dest = dest; - current_dest < (dest + size); - current_dest += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE) { - nand_read_page(offs, (dma_addr_t)current_dest, - offs < CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END, - &ecc_errors); - offs += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE; - } - return ecc_errors ? -1 : 0; + return nand_read_buffer(offs, size, dest, syndrome); } void nand_deselect(void) From 2b8a01a99d6b1632d4356fa71383069b4a532687 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 21:23:08 +0200 Subject: [PATCH 18/31] sunxi_nand_spl: Auto detect nand configuration parameters Auto detect the nand configuration parameters, like the BROM does. This allows us to get rid of various Kconfig settings, and is necessary to support generic boards like the mk802 which have seen many production runs with different nands. The full blown u-boot/kernel nand driver uses the nand id to determine this info, for the SPL we do as the BROM does and simply try a few standard configs. Note the table only contains configs which are known to actually be used, rather then all the configs the BROM tries. This means that it may need to be updated in the future as we add support for nand on more boards. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mtd/nand/Kconfig | 25 ------------------ drivers/mtd/nand/sunxi_nand_spl.c | 43 ++++++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 8fac5e873b..09c9668e10 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -99,8 +99,6 @@ config SPL_NAND_SUNXI ---help--- Enable support for NAND. This option allows SPL to read from sunxi NAND using DMA transfers. - Depending on the NAND chip, values like ECC strength and page sizes - have to be configured. config NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END hex "Size of syndrome partitions in sunxi NAND" @@ -110,29 +108,6 @@ config NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END End address for boot partitions on NAND. Those partitions have a different random seed that has to match the sunxi BROM setting. -config NAND_SUNXI_SPL_ECC_STRENGTH - int "ECC Strength for sunxi NAND" - default 40 - depends on SPL_NAND_SUNXI - ---help--- - ECC strength used by the sunxi NAND SPL driver. This is specific to the - chosen NAND chip and has to match the value used by the sunxi BROM. - -config NAND_SUNXI_SPL_ECC_PAGE_SIZE - hex "ECC page size for sunxi NAND" - default 0x400 - depends on SPL_NAND_SUNXI - ---help--- - ECC page size used by the sunxi NAND SPL driver for syndrome partitions. - This setting has to match the value used by the sunxi BROM. - -config NAND_SUNXI_SPL_PAGE_SIZE - hex "Page size for sunxi NAND" - default 0x2000 - depends on SPL_NAND_SUNXI - ---help--- - Page size of the NAND flash used by the sunxi NAND SPL driver. This is - specific to the chosen NAND chip. endif endmenu diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index 3206a50202..eee6c7b7ab 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -307,10 +307,45 @@ static int nand_read_ecc(int page_size, int ecc_strength, int ecc_page_size, static int nand_read_buffer(uint32_t offs, unsigned int size, void *dest, int syndrome) { - return nand_read_ecc(CONFIG_NAND_SUNXI_SPL_PAGE_SIZE, - CONFIG_NAND_SUNXI_SPL_ECC_STRENGTH, - CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE, - 5, offs, size, dest, syndrome); + const struct { + int page_size; + int ecc_strength; + int ecc_page_size; + int addr_cycles; + } nand_configs[] = { + { 8192, 40, 1024, 5 }, + { 16384, 56, 1024, 5 }, + { 8192, 24, 1024, 5 }, + }; + static int nand_config = -1; + int i; + + if (nand_config == -1) { + for (i = 0; i < ARRAY_SIZE(nand_configs); i++) { + debug("nand: trying page %d ecc %d / %d addr %d: ", + nand_configs[i].page_size, + nand_configs[i].ecc_strength, + nand_configs[i].ecc_page_size, + nand_configs[i].addr_cycles); + if (nand_read_ecc(nand_configs[i].page_size, + nand_configs[i].ecc_strength, + nand_configs[i].ecc_page_size, + nand_configs[i].addr_cycles, + offs, size, dest, syndrome) == 0) { + debug("success\n"); + nand_config = i; + return 0; + } + debug("failed\n"); + } + return -1; + } + + return nand_read_ecc(nand_configs[nand_config].page_size, + nand_configs[nand_config].ecc_strength, + nand_configs[nand_config].ecc_page_size, + nand_configs[nand_config].addr_cycles, + offs, size, dest, syndrome); } int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest) From 24a06c964fd457238f16531d8ed1b660c4341676 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 15 Aug 2015 21:51:33 +0200 Subject: [PATCH 19/31] sunxi_nand_spl: Add support for backup boot partitions The BROM does not care / use bad page markings, instead it deals with any bad pages in the first erase-block by simply trying to load "boot0" from the next erase-block. This commit implements the same strategy for the sunxi spl nand code, allowing it to boot from the backup boot partition when the main boot partition is bad (tested by erasing the main boot partition). Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mtd/nand/sunxi_nand_spl.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index eee6c7b7ab..14320c4494 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -350,7 +350,23 @@ static int nand_read_buffer(uint32_t offs, unsigned int size, void *dest, int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest) { + const uint32_t boot_offsets[] = { + 0 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS, + 1 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS, + 2 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS, + 4 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS, + }; int syndrome = offs < CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END; + int i; + + if (offs == CONFIG_SYS_NAND_U_BOOT_OFFS) { + for (i = 0; i < ARRAY_SIZE(boot_offsets); i++) { + if (nand_read_buffer(boot_offsets[i], size, + dest, syndrome) == 0) + return 0; + } + return -1; + } return nand_read_buffer(offs, size, dest, syndrome); } From e5268616878690037474ff36cb6efb350b5e1061 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sun, 16 Aug 2015 14:48:22 +0200 Subject: [PATCH 20/31] sunxi_nand_spl: Rename SPL_NAND_SUNXI to NAND_SUNXI We eventually want to add full nand support, since it makes no sense to build SPL with nand support and u-boot without, or the other way around, a single option will suffice. Renaming the Kconfig option now makes things easier when we add full nand support in the future. The "obj-$(CONFIG_NAND_SUNXI) += sunxi_nand_spl.o" is moved to an "ifdef CONFIG_SPL_BUILD" block in the Makefile. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/board.c | 2 +- drivers/mtd/nand/Kconfig | 18 +++++++++--------- drivers/mtd/nand/Makefile | 2 +- include/configs/sunxi-common.h | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/board/sunxi/board.c b/board/sunxi/board.c index d411e96c76..9c855f604d 100644 --- a/board/sunxi/board.c +++ b/board/sunxi/board.c @@ -108,7 +108,7 @@ int dram_init(void) return 0; } -#if defined(CONFIG_SPL_NAND_SUNXI) && defined(CONFIG_SPL_BUILD) +#if defined(CONFIG_NAND_SUNXI) && defined(CONFIG_SPL_BUILD) static void nand_pinmux_setup(void) { unsigned int pin; diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 09c9668e10..1d08d28d0e 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -63,6 +63,14 @@ config NAND_PXA3XX This enables the driver for the NAND flash device found on PXA3xx processors (NFCv1) and also on Armada 370/XP (NFCv2). +config NAND_SUNXI + bool "Support for NAND on Allwinner SoCs in SPL" + depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I + select SYS_NAND_SELF_INIT + ---help--- + Enable support for NAND. This option allows SPL to read from + sunxi NAND using DMA transfers. + comment "Generic NAND options" # Enhance depends when converting drivers to Kconfig which use this config @@ -92,18 +100,10 @@ config SPL_NAND_DENALI This is a small implementation of the Denali NAND controller for use on SPL. -config SPL_NAND_SUNXI - bool "Support for NAND on Allwinner SoCs in SPL" - depends on MACH_SUN4I || MACH_SUN5I || MACH_SUN7I - select SYS_NAND_SELF_INIT - ---help--- - Enable support for NAND. This option allows SPL to read from - sunxi NAND using DMA transfers. - config NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END hex "Size of syndrome partitions in sunxi NAND" default 0x400000 - depends on SPL_NAND_SUNXI + depends on NAND_SUNXI ---help--- End address for boot partitions on NAND. Those partitions have a different random seed that has to match the sunxi BROM setting. diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 64d1675d0a..71c1a519e9 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -12,7 +12,6 @@ NORMAL_DRIVERS=y endif obj-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o -obj-$(CONFIG_SPL_NAND_SUNXI) += sunxi_nand_spl.o obj-$(CONFIG_SPL_NAND_DENALI) += denali_spl.o obj-$(CONFIG_SPL_NAND_DOCG4) += docg4_spl.o obj-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o @@ -77,5 +76,6 @@ obj-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o obj-$(CONFIG_NAND_FSL_IFC) += fsl_ifc_spl.o obj-$(CONFIG_NAND_MXC) += mxc_nand_spl.o obj-$(CONFIG_NAND_MXS) += mxs_nand_spl.o mxs_nand.o +obj-$(CONFIG_NAND_SUNXI) += sunxi_nand_spl.o endif # drivers diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 3735afbafc..519c99cdaa 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -137,7 +137,7 @@ #define CONFIG_INITRD_TAG #define CONFIG_SERIAL_TAG -#if defined(CONFIG_SPL_NAND_SUNXI) +#ifdef CONFIG_NAND_SUNXI #define CONFIG_SPL_NAND_SUPPORT 1 #define CONFIG_SYS_NAND_U_BOOT_OFFS 0x008000 #endif From 6a08d65acc0f5e62e3144e16fc4460e068e3c6ec Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 21 Aug 2015 15:23:57 +0200 Subject: [PATCH 21/31] sunxi_nand_spl: Remove NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END We only ever use syndrome mode for the partitions which contain the SPL, as that is required for the BROM to be able to read the SPL. Instead of using some arbritray limit for deciding whether or not to use syndrome, be smart and check if u-boot-dtb.bin is directly behind the SPL, if it is not then it is on its own partition and we should not use syndrome. Note the reason why we only use syndrome mode for the SPL is because it comeswith weaker randomization, introducing a risk for more bit errors, so we want to avoid it when possible. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/mtd/nand/Kconfig | 8 -------- drivers/mtd/nand/sunxi_nand_spl.c | 8 ++++++-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 1d08d28d0e..c34c234cc1 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -100,14 +100,6 @@ config SPL_NAND_DENALI This is a small implementation of the Denali NAND controller for use on SPL. -config NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END - hex "Size of syndrome partitions in sunxi NAND" - default 0x400000 - depends on NAND_SUNXI - ---help--- - End address for boot partitions on NAND. Those partitions have a - different random seed that has to match the sunxi BROM setting. - endif endmenu diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index 14320c4494..5c0a52744f 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -356,8 +356,12 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest) 2 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS, 4 * 1024 * 1024 + CONFIG_SYS_NAND_U_BOOT_OFFS, }; - int syndrome = offs < CONFIG_NAND_SUNXI_SPL_SYNDROME_PARTITIONS_END; - int i; + int i, syndrome; + + if (CONFIG_SYS_NAND_U_BOOT_OFFS == CONFIG_SPL_PAD_TO) + syndrome = 1; /* u-boot-dtb.bin appended to SPL */ + else + syndrome = 0; /* u-boot-dtb.bin on its own partition */ if (offs == CONFIG_SYS_NAND_U_BOOT_OFFS) { for (i = 0; i < ARRAY_SIZE(boot_offsets); i++) { From ddd37fe865bee8b17842a55ab917ae597fe8af0d Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Sat, 29 Aug 2015 12:29:38 +0200 Subject: [PATCH 22/31] sunxi_nand_spl: clear status flags in SPL implementation Some status flags remain set until you explicetly clear the bit in the status register. Fix the SPL implementation to avoid false positive. Signed-off-by: Boris Brezillon [hdegoede@redhat.com: Port from v2015.07 to v2015.10] Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/mtd/nand/sunxi_nand_spl.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/sunxi_nand_spl.c b/drivers/mtd/nand/sunxi_nand_spl.c index 5c0a52744f..bf9b1b1450 100644 --- a/drivers/mtd/nand/sunxi_nand_spl.c +++ b/drivers/mtd/nand/sunxi_nand_spl.c @@ -67,7 +67,8 @@ #define NFC_SEND_CMD3 (1 << 28) #define NFC_SEND_CMD4 (1 << 29) -#define NFC_CMD_INT_FLAG (1 << 1) +#define NFC_ST_CMD_INT_FLAG (1 << 1) +#define NFC_ST_DMA_INT_FLAG (1 << 2) #define NFC_READ_CMD_OFFSET 0 #define NFC_RANDOM_READ_CMD0_OFFSET 8 @@ -169,14 +170,16 @@ void nand_init(void) } /* reset NAND */ + writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST); writel(NFC_SEND_CMD1 | NFC_WAIT_FLAG | NAND_CMD_RESET, SUNXI_NFC_BASE + NFC_CMD); - if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_CMD_INT_FLAG, + if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_CMD_INT_FLAG, MAX_RETRIES)) { printf("Error timeout waiting for nand reset\n"); return; } + writel(NFC_ST_CMD_INT_FLAG, SUNXI_NFC_BASE + NFC_ST); } static int nand_read_page(int page_size, int ecc_strength, int ecc_page_size, @@ -259,17 +262,19 @@ static int nand_read_page(int page_size, int ecc_strength, int ecc_page_size, writel(((page & 0xFFFF) << 16) | column, SUNXI_NFC_BASE + NFC_ADDR_LOW); writel((page >> 16) & 0xFF, SUNXI_NFC_BASE + NFC_ADDR_HIGH); + writel(NFC_ST_DMA_INT_FLAG, SUNXI_NFC_BASE + NFC_ST); writel(NFC_SEND_CMD1 | NFC_SEND_CMD2 | NFC_DATA_TRANS | NFC_PAGE_CMD | NFC_WAIT_FLAG | ((addr_cycles - 1) << NFC_ADDR_NUM_OFFSET) | NFC_SEND_ADR | NFC_DATA_SWAP_METHOD | (syndrome ? NFC_SEQ : 0), SUNXI_NFC_BASE + NFC_CMD); - if (!check_value(SUNXI_NFC_BASE + NFC_ST, (1 << 2), + if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_DMA_INT_FLAG, MAX_RETRIES)) { printf("Error while initializing dma interrupt\n"); return -1; } + writel(NFC_ST_DMA_INT_FLAG, SUNXI_NFC_BASE + NFC_ST); if (!check_value_negated(SUNXI_DMA_BASE + SUNXI_DMA_CFG_REG0, SUNXI_DMA_DDMA_CFG_REG_LOADING, MAX_RETRIES)) { From d90ba790d8ae40c39d9e359dc71df16911b7bdb3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Fri, 21 Aug 2015 21:49:51 +0200 Subject: [PATCH 23/31] mtd: nand: Make CONFIG_SYS_NAND_U_BOOT_OFFS configurable through Kconfig Make CONFIG_SYS_NAND_U_BOOT_OFFS configurable through Kconfig, just like SYS_NAND_BUSWIDTH_16BIT this is only enabled on some SoCs using depends, to avoid double defining it for SoCs which have not yet moved to Kconfig for this. Having this in Kconfig is useful because this is something which may differ from one board to the other even when using the same SoC. Signed-off-by: Hans de Goede Acked-by: Ian Campbell Acked-by: Scott Wood --- drivers/mtd/nand/Kconfig | 9 +++++++++ include/configs/sunxi-common.h | 1 - 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index c34c234cc1..9a74064c98 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -92,6 +92,15 @@ config SYS_NAND_BUSWIDTH_16BIT not available while configuring controller. So a static CONFIG_NAND_xx is needed to know the device's bus-width in advance. +# Enhance depends when converting drivers to Kconfig which use this config +config SYS_NAND_U_BOOT_OFFS + hex "Location in NAND to read U-Boot from" + default 0x8000 if NAND_SUNXI + depends on NAND_SUNXI + help + Set the offset from the start of the nand where u-boot should be + loaded from. + if SPL config SPL_NAND_DENALI diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 519c99cdaa..5c65a89c4a 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -139,7 +139,6 @@ #ifdef CONFIG_NAND_SUNXI #define CONFIG_SPL_NAND_SUPPORT 1 -#define CONFIG_SYS_NAND_U_BOOT_OFFS 0x008000 #endif /* mmc config */ From 7a7334719c6b3089350f7d0ed8a273cc906370e7 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 25 Aug 2015 14:19:06 +0200 Subject: [PATCH 24/31] sunxi: Ampe_A76_defconfig: Add otg id pin configuration Add otg id pin configuration, this speeds up bootup when no host cable is plugged into the otg port. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- configs/Ampe_A76_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/Ampe_A76_defconfig b/configs/Ampe_A76_defconfig index e3f44f6262..57ff52da95 100644 --- a/configs/Ampe_A76_defconfig +++ b/configs/Ampe_A76_defconfig @@ -5,6 +5,7 @@ CONFIG_DRAM_CLK=432 CONFIG_MMC0_CD_PIN="PG0" CONFIG_USB0_VBUS_PIN="PG12" CONFIG_USB0_VBUS_DET="PG1" +CONFIG_USB0_ID_DET="PG2" CONFIG_AXP_GPIO=y # CONFIG_VIDEO_HDMI is not set CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:82,up:22,lo:22,hs:1,vs:1,sync:3,vmode:0" From 1f554906c3620db639c59000a8d76373c6152cfb Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 22 Aug 2015 20:06:02 +0200 Subject: [PATCH 25/31] sunxi: Add inet97fv2_defconfig The inet97fv2 is a board found in the first generation of cheap allwinner A10 based 7" tablets. Note that this patch does not add a dts file as we already have one from our dts syncs with the kernel. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/MAINTAINERS | 1 + configs/inet97fv2_defconfig | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 configs/inet97fv2_defconfig diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index de99fe137c..01fc7d6a50 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -8,6 +8,7 @@ F: configs/ba10_tv_box_defconfig F: configs/Chuwi_V7_CW0825_defconfig F: configs/Cubieboard_defconfig F: configs/Hyundai_A7HD_defconfig +F: configs/inet97fv2_defconfig F: configs/jesurun_q5_defconfig F: configs/Mele_A1000_defconfig F: configs/Mele_A1000G_quad_defconfig diff --git a/configs/inet97fv2_defconfig b/configs/inet97fv2_defconfig new file mode 100644 index 0000000000..d7ddee13ff --- /dev/null +++ b/configs/inet97fv2_defconfig @@ -0,0 +1,20 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN4I=y +CONFIG_DRAM_CLK=408 +CONFIG_DRAM_EMR1=4 +CONFIG_USB0_VBUS_PIN="PB9" +CONFIG_USB0_VBUS_DET="PH5" +CONFIG_USB0_ID_DET="PH4" +CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:24,pclk_khz:33000,le:45,ri:209,up:22,lo:22,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_POWER="PH8" +CONFIG_VIDEO_LCD_BL_EN="PH7" +CONFIG_VIDEO_LCD_BL_PWM="PB2" +CONFIG_USB_MUSB_HOST=y +CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-inet97fv2" +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER" +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set From 4ddcf1df175165cb59b2cb2a38f50a9537477f52 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 25 Aug 2015 14:20:49 +0200 Subject: [PATCH 26/31] sunxi: Add inet98v_rev2 defconfig and dts file The inet98v_rev2 is a pcb used in generic A13 based tablets. It features volume buttons, a power barrel, micro-usb otg, headphone connector and a power button. The dts file is identical to the one submitted to the upstream kernel. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/dts/Makefile | 1 + arch/arm/dts/sun5i-a13-inet-98v-rev2.dts | 236 +++++++++++++++++++++++ board/sunxi/MAINTAINERS | 1 + configs/inet98v_rev2_defconfig | 22 +++ 4 files changed, 260 insertions(+) create mode 100644 arch/arm/dts/sun5i-a13-inet-98v-rev2.dts create mode 100644 configs/inet98v_rev2_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index d65876fad7..46eafd5548 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -96,6 +96,7 @@ dtb-$(CONFIG_MACH_SUN5I) += \ sun5i-a13-forfun-q88db.dtb \ sun5i-a13-hsg-h702.dtb \ sun5i-a13-inet-86vs.dtb \ + sun5i-a13-inet-98v-rev2.dtb \ sun5i-a13-olinuxino.dtb \ sun5i-a13-olinuxino-micro.dtb \ sun5i-a13-tzx-q8-713b7.dtb \ diff --git a/arch/arm/dts/sun5i-a13-inet-98v-rev2.dts b/arch/arm/dts/sun5i-a13-inet-98v-rev2.dts new file mode 100644 index 0000000000..6d466a28ec --- /dev/null +++ b/arch/arm/dts/sun5i-a13-inet-98v-rev2.dts @@ -0,0 +1,236 @@ +/* + * Copyright 2015 Hans de Goede + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun5i-a13.dtsi" +#include "sunxi-common-regulators.dtsi" +#include +#include +#include +#include + +/ { + model = "INet-98V Rev 02"; + compatible = "primux,inet98v-rev2", "allwinner,sun5i-a13"; + + aliases { + serial0 = &uart1; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + +}; + +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + +&ehci0 { + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + + axp209: pmic@34 { + reg = <0x34>; + interrupts = <0>; + }; +}; + +#include "axp209.dtsi" + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; + + pcf8563: rtc@51 { + compatible = "nxp,pcf8563"; + reg = <0x51>; + }; +}; + +&lradc { + vref-supply = <®_ldo2>; + status = "okay"; + + button@200 { + label = "Volume Up"; + linux,code = ; + channel = <0>; + voltage = <200000>; + }; + + button@400 { + label = "Volume Down"; + linux,code = ; + channel = <0>; + voltage = <400000>; + }; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_inet98fv2>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 6 0 GPIO_ACTIVE_HIGH>; /* PG0 */ + cd-inverted; + status = "okay"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_pins_a>; + vmmc-supply = <®_vcc3v3>; + bus-width = <8>; + non-removable; + status = "okay"; + + mmccard: mmccard@0 { + reg = <0>; + compatible = "mmc-card"; + broken-hpi; + }; +}; + +&otg_sram { + status = "okay"; +}; + +&pio { + mmc0_cd_pin_inet98fv2: mmc0_cd_pin@0 { + allwinner,pins = "PG0"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; + + usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 { + allwinner,pins = "PG1"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; + + usb0_id_detect_pin: usb0_id_detect_pin@0 { + allwinner,pins = "PG2"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-cpu"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <1250000>; + regulator-name = "vdd-int-pll"; +}; + +®_ldo1 { + regulator-name = "vdd-rtc"; +}; + +®_ldo2 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "avcc"; +}; + +®_ldo3 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-wifi"; +}; + +®_usb0_vbus { + gpio = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */ + status = "okay"; +}; + +®_usb1_vbus { + gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>; /* PG11 */ + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins_b>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usb0_vbus_pin_a { + allwinner,pins = "PG12"; +}; + +&usb1_vbus_pin_a { + allwinner,pins = "PG11"; +}; + +&usbphy { + pinctrl-names = "default"; + pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; + usb0_id_det-gpio = <&pio 6 2 GPIO_ACTIVE_HIGH>; /* PG2 */ + usb0_vbus_det-gpio = <&pio 6 1 GPIO_ACTIVE_HIGH>; /* PG1 */ + usb0_vbus-supply = <®_usb0_vbus>; + usb1_vbus-supply = <®_usb1_vbus>; + status = "okay"; +}; diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 01fc7d6a50..fca051ffa7 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -22,6 +22,7 @@ F: configs/A13-OLinuXino_defconfig F: configs/A13-OLinuXinoM_defconfig F: configs/Auxtek-T003_defconfig F: configs/Auxtek-T004_defconfig +F: configs/inet98v_rev2_defconfig F: configs/mk802_a10s_defconfig F: configs/r7-tv-dongle_defconfig F: configs/UTOO_P66_defconfig diff --git a/configs/inet98v_rev2_defconfig b/configs/inet98v_rev2_defconfig new file mode 100644 index 0000000000..c23245adf9 --- /dev/null +++ b/configs/inet98v_rev2_defconfig @@ -0,0 +1,22 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN5I=y +CONFIG_DRAM_CLK=432 +CONFIG_MMC0_CD_PIN="PG0" +CONFIG_USB0_VBUS_PIN="PG12" +CONFIG_USB0_VBUS_DET="PG1" +CONFIG_USB0_ID_DET="PG2" +CONFIG_AXP_GPIO=y +# CONFIG_VIDEO_HDMI is not set +CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:45,ri:209,up:22,lo:22,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_POWER="AXP0-0" +CONFIG_VIDEO_LCD_BL_EN="AXP0-1" +CONFIG_VIDEO_LCD_BL_PWM="PB2" +CONFIG_USB_MUSB_HOST=y +CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-inet-98v-rev2" +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER" +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set From 50222f3bab2213fa440712d2f46ae7f9314f3b7a Mon Sep 17 00:00:00 2001 From: Marcus Cooper Date: Wed, 26 Aug 2015 20:38:33 +0200 Subject: [PATCH 27/31] sunxi: Add support for the Olimex A20 EVB Signed-off-by: Marcus Cooper Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/dts/Makefile | 1 + arch/arm/dts/sun7i-a20-olimex-som-evb.dts | 244 ++++++++++++++++++++++ board/sunxi/MAINTAINERS | 5 + configs/A20-Olimex-SOM-EVB_defconfig | 16 ++ 4 files changed, 266 insertions(+) create mode 100644 arch/arm/dts/sun7i-a20-olimex-som-evb.dts create mode 100644 configs/A20-Olimex-SOM-EVB_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 46eafd5548..c97f39dc6b 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -122,6 +122,7 @@ dtb-$(CONFIG_MACH_SUN7I) += \ sun7i-a20-m3.dtb \ sun7i-a20-m5.dtb \ sun7i-a20-mk808c.dtb \ + sun7i-a20-olimex-som-evb.dtb \ sun7i-a20-olinuxino-lime.dtb \ sun7i-a20-olinuxino-lime2.dtb \ sun7i-a20-olinuxino-micro.dtb \ diff --git a/arch/arm/dts/sun7i-a20-olimex-som-evb.dts b/arch/arm/dts/sun7i-a20-olimex-som-evb.dts new file mode 100644 index 0000000000..6904dbd732 --- /dev/null +++ b/arch/arm/dts/sun7i-a20-olimex-som-evb.dts @@ -0,0 +1,244 @@ +/* + * Copyright 2015 - Marcus Cooper + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun7i-a20.dtsi" +#include "sunxi-common-regulators.dtsi" + +#include +#include +#include + +/ { + model = "Olimex A20-Olimex-SOM-EVB"; + compatible = "olimex,a20-olimex-som-evb", "allwinner,sun7i-a20"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_pins_olimex_som_evb>; + + green { + label = "a20-olimex-som-evb:green:usr"; + gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + }; + + reg_axp_ipsout: axp_ipsout { + compatible = "regulator-fixed"; + regulator-name = "axp-ipsout"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; +}; + +&ahci { + target-supply = <®_ahci_5v>; + status = "okay"; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +&gmac { + pinctrl-names = "default"; + pinctrl-0 = <&gmac_pins_rgmii_a>; + phy = <&phy1>; + phy-mode = "rgmii"; + status = "okay"; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_pins_a>; + status = "okay"; + + axp209: pmic@34 { + reg = <0x34>; + interrupt-parent = <&nmi_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins_a>; + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_reference_design>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 7 1 GPIO_ACTIVE_HIGH>; /* PH1 */ + cd-inverted; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&otg_sram { + status = "okay"; +}; + +&pio { + ahci_pwr_pin_olimex_som_evb: ahci_pwr_pin@1 { + allwinner,pins = "PC3"; + allwinner,function = "gpio_out"; + allwinner,drive = ; + allwinner,pull = ; + }; + + led_pins_olimex_som_evb: led_pins@0 { + allwinner,pins = "PH2"; + allwinner,function = "gpio_out"; + allwinner,drive = ; + allwinner,pull = ; + }; + + usb0_id_detect_pin: usb0_id_detect_pin@0 { + allwinner,pins = "PH04"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; + + usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 { + allwinner,pins = "PH05"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; +}; + +®_ahci_5v { + pinctrl-0 = <&ahci_pwr_pin_olimex_som_evb>; + gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +#include "axp209.dtsi" + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1425000>; + regulator-name = "vdd-cpu"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1400000>; + regulator-name = "vdd-int-dll"; +}; + +®_ldo1 { + regulator-name = "vdd-rtc"; +}; + +®_ldo2 { + regulator-always-on; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-name = "avcc"; +}; + +®_usb0_vbus { + status = "okay"; +}; + +®_usb1_vbus { + status = "okay"; +}; + +®_usb2_vbus { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usbphy { + pinctrl-names = "default"; + pinctrl-0 = <&usb0_id_detect_pin>, <&usb0_vbus_detect_pin>; + usb0_id_det-gpios = <&pio 7 04 GPIO_ACTIVE_HIGH>; /* PH04 */ + usb0_vbus_det-gpios = <&pio 7 05 GPIO_ACTIVE_HIGH>; /* PH05 */ + usb0_vbus-supply = <®_usb0_vbus>; + usb1_vbus-supply = <®_usb1_vbus>; + usb2_vbus-supply = <®_usb2_vbus>; + status = "okay"; +}; diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index fca051ffa7..7ae72ac4f2 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -48,6 +48,11 @@ F: configs/Ippo_q8h_v1_2_a33_1024x600_defconfig F: include/configs/sun9i.h F: configs/Merrii_A80_Optimus_defconfig +A20-OLIMEX-SOM-EVB BOARD +M: Marcus Cooper +S: Maintained +F: configs/A20-Olimex-SOM-EVB_defconfig + A20-OLINUXINO-LIME BOARD M: FUKAUMI Naoki S: Maintained diff --git a/configs/A20-Olimex-SOM-EVB_defconfig b/configs/A20-Olimex-SOM-EVB_defconfig new file mode 100644 index 0000000000..e8c3d18db9 --- /dev/null +++ b/configs/A20-Olimex-SOM-EVB_defconfig @@ -0,0 +1,16 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN7I=y +CONFIG_DRAM_CLK=480 +CONFIG_MMC0_CD_PIN="PH1" +CONFIG_USB0_VBUS_PIN="PB9" +CONFIG_USB0_VBUS_DET="PH5" +CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-olimex-som-evb" +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL=y +CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPC(3)" +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set +CONFIG_ETH_DESIGNWARE=y +CONFIG_USB_EHCI_HCD=y From 3537a0e8caa33ad4af354d5efc6be117b0728856 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 27 Aug 2015 20:07:28 +0200 Subject: [PATCH 28/31] sunxi: Fix MAINTAINERS board sorting The boards are sorted by SoC, move the Mele_A1000G_quad entry to the list of sun6i boards where it belongs. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- board/sunxi/MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 7ae72ac4f2..3a4d1fbfb8 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -11,7 +11,6 @@ F: configs/Hyundai_A7HD_defconfig F: configs/inet97fv2_defconfig F: configs/jesurun_q5_defconfig F: configs/Mele_A1000_defconfig -F: configs/Mele_A1000G_quad_defconfig F: configs/Mele_M3_defconfig F: configs/Mini-X_defconfig F: configs/mk802_defconfig @@ -28,6 +27,7 @@ F: configs/r7-tv-dongle_defconfig F: configs/UTOO_P66_defconfig F: include/configs/sun6i.h F: configs/CSQ_CS908_defconfig +F: configs/Mele_A1000G_quad_defconfig F: configs/Mele_M9_defconfig F: include/configs/sun7i.h F: configs/A20-OLinuXino_MICRO_defconfig From 92369844ec7bf0e63de51e19b281fe3739e01397 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 25 Aug 2015 10:49:19 +0800 Subject: [PATCH 29/31] sunxi: Enable non-secure access to RTC on sun6i (A31s) On the A31s the RTC is by default secured. Thus when u-boot loads the kernel in non-secure world, the RTC is unavailable. The SoC has a TrustZone Protection Controller, which can be used to enable non-secure access to the RTC. On the A31 the TZPC doesn't seem to do anything, i.e. changes to its register contents do not affect access to the RTC. Signed-off-by: Chen-Yu Tsai Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/sunxi/Makefile | 1 + arch/arm/cpu/armv7/sunxi/board.c | 5 +++++ arch/arm/cpu/armv7/sunxi/tzpc.c | 18 ++++++++++++++++++ arch/arm/include/asm/arch-sunxi/tzpc.h | 23 +++++++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 arch/arm/cpu/armv7/sunxi/tzpc.c create mode 100644 arch/arm/include/asm/arch-sunxi/tzpc.h diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index 76c7e555f1..459d5d8b0c 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_MACH_SUN6I) += clock_sun6i.o obj-$(CONFIG_MACH_SUN7I) += clock_sun4i.o obj-$(CONFIG_MACH_SUN8I) += clock_sun6i.o obj-$(CONFIG_MACH_SUN9I) += clock_sun9i.o +obj-$(CONFIG_MACH_SUN6I) += tzpc.o obj-$(CONFIG_AXP152_POWER) += pmic_bus.o obj-$(CONFIG_AXP209_POWER) += pmic_bus.o diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index f01846ef9a..b40198b36e 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -115,6 +116,10 @@ void s_init(void) "orr r0, r0, #1 << 6\n" "mcr p15, 0, r0, c1, c0, 1\n"); #endif +#if defined CONFIG_MACH_SUN6I + /* Enable non-secure access to the RTC */ + tzpc_init(); +#endif clock_init(); timer_init(); diff --git a/arch/arm/cpu/armv7/sunxi/tzpc.c b/arch/arm/cpu/armv7/sunxi/tzpc.c new file mode 100644 index 0000000000..5c9c69b20b --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/tzpc.c @@ -0,0 +1,18 @@ +/* + * (C) Copyright 2015 Chen-Yu Tsai + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +/* Configure Trust Zone Protection Controller */ +void tzpc_init(void) +{ + struct sunxi_tzpc *tzpc = (struct sunxi_tzpc *)SUNXI_TZPC_BASE; + + /* Enable non-secure access to the RTC */ + writel(SUNXI_TZPC_DECPORT0_RTC, &tzpc->decport0_set); +} diff --git a/arch/arm/include/asm/arch-sunxi/tzpc.h b/arch/arm/include/asm/arch-sunxi/tzpc.h new file mode 100644 index 0000000000..ba4d43bc3a --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/tzpc.h @@ -0,0 +1,23 @@ +/* + * (C) Copyright 2015 Chen-Yu Tsai + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SUNXI_TZPC_H +#define _SUNXI_TZPC_H + +#ifndef __ASSEMBLY__ +struct sunxi_tzpc { + u32 r0size; /* 0x00 Size of secure RAM region */ + u32 decport0_status; /* 0x04 Status of decode protection port 0 */ + u32 decport0_set; /* 0x08 Set decode protection port 0 */ + u32 decport0_clear; /* 0x0c Clear decode protection port 0 */ +}; +#endif + +#define SUNXI_TZPC_DECPORT0_RTC (1 << 1) + +void tzpc_init(void); + +#endif /* _SUNXI_TZPC_H */ From 28f69b9a229108834af34da099949076d9fd4ff3 Mon Sep 17 00:00:00 2001 From: Yousong Zhou Date: Sat, 29 Aug 2015 21:26:11 +0800 Subject: [PATCH 30/31] sunxi: mmc: set transfer timeout according to byte_cnt. Originally a timeout value of 2 seconds was used regardless of the size of data to be transfered. This prevented slow devices from working correctly while there was no much gain for faster devices, e.g. it takes 3708ms for a transfer of uImage of size 1899008 bytes. Signed-off-by: Yousong Zhou Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- drivers/mmc/sunxi_mmc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index f9b9493c89..25f18adb67 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -257,9 +257,11 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) const uint32_t status_bit = reading ? SUNXI_MMC_STATUS_FIFO_EMPTY : SUNXI_MMC_STATUS_FIFO_FULL; unsigned i; - unsigned byte_cnt = data->blocksize * data->blocks; - unsigned timeout_msecs = 2000; unsigned *buff = (unsigned int *)(reading ? data->dest : data->src); + unsigned byte_cnt = data->blocksize * data->blocks; + unsigned timeout_msecs = byte_cnt >> 8; + if (timeout_msecs < 2000) + timeout_msecs = 2000; /* Always read / write data through the CPU */ setbits_le32(&mmchost->reg->gctrl, SUNXI_MMC_GCTRL_ACCESS_BY_AHB); From fa5e102019e28a5936e52d6aa9f5624cf1744a35 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 27 Jul 2015 16:21:26 +0200 Subject: [PATCH 31/31] sunxi: increase SYS_MONITOR_LEN Signed-off-by: Boris Brezillon Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- include/configs/sunxi-common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 5c65a89c4a..48cc4ed6f6 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -179,7 +179,7 @@ #define CONFIG_SYS_NO_FLASH -#define CONFIG_SYS_MONITOR_LEN (512 << 10) /* 512 KiB */ +#define CONFIG_SYS_MONITOR_LEN (768 << 10) /* 768 KiB */ #define CONFIG_IDENT_STRING " Allwinner Technology" #define CONFIG_ENV_OFFSET (544 << 10) /* (8 + 24 + 512) KiB */