This commit is contained in:
Tom Rini 2015-08-31 12:12:27 -04:00
commit b7e84c93c4
29 changed files with 988 additions and 179 deletions

View File

@ -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

View File

@ -23,6 +23,7 @@
#include <asm/arch/gpio.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/timer.h>
#include <asm/arch/tzpc.h>
#include <asm/arch/mmc.h>
#include <linux/compiler.h>
@ -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();

View File

@ -0,0 +1,18 @@
/*
* (C) Copyright 2015 Chen-Yu Tsai <wens@csie.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/tzpc.h>
/* 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);
}

View File

@ -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 \
@ -121,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 \
@ -134,6 +136,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) += \

View File

@ -0,0 +1,236 @@
/*
* Copyright 2015 Hans de Goede <hdegoede@redhat.com>
*
* 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 <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
model = "INet-98V Rev 02";
compatible = "primux,inet98v-rev2", "allwinner,sun5i-a13";
aliases {
serial0 = &uart1;
};
chosen {
stdout-path = "serial0:115200n8";
};
};
&cpu0 {
cpu-supply = <&reg_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 = <&reg_ldo2>;
status = "okay";
button@200 {
label = "Volume Up";
linux,code = <KEY_VOLUMEUP>;
channel = <0>;
voltage = <200000>;
};
button@400 {
label = "Volume Down";
linux,code = <KEY_VOLUMEDOWN>;
channel = <0>;
voltage = <400000>;
};
};
&mmc0 {
pinctrl-names = "default";
pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_inet98fv2>;
vmmc-supply = <&reg_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 = <&reg_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 = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
allwinner,pins = "PG1";
allwinner,function = "gpio_in";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_PULL_DOWN>;
};
usb0_id_detect_pin: usb0_id_detect_pin@0 {
allwinner,pins = "PG2";
allwinner,function = "gpio_in";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
};
&reg_dcdc2 {
regulator-always-on;
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1400000>;
regulator-name = "vdd-cpu";
};
&reg_dcdc3 {
regulator-always-on;
regulator-min-microvolt = <1250000>;
regulator-max-microvolt = <1250000>;
regulator-name = "vdd-int-pll";
};
&reg_ldo1 {
regulator-name = "vdd-rtc";
};
&reg_ldo2 {
regulator-always-on;
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-name = "avcc";
};
&reg_ldo3 {
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-name = "vcc-wifi";
};
&reg_usb0_vbus {
gpio = <&pio 6 12 GPIO_ACTIVE_HIGH>; /* PG12 */
status = "okay";
};
&reg_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 = <&reg_usb0_vbus>;
usb1_vbus-supply = <&reg_usb1_vbus>;
status = "okay";
};

View File

@ -0,0 +1,244 @@
/*
* Copyright 2015 - Marcus Cooper <codekipper@gmail.com>
*
* 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 <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
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 = <&reg_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 = <&reg_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 = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
led_pins_olimex_som_evb: led_pins@0 {
allwinner,pins = "PH2";
allwinner,function = "gpio_out";
allwinner,drive = <SUN4I_PINCTRL_20_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
usb0_id_detect_pin: usb0_id_detect_pin@0 {
allwinner,pins = "PH04";
allwinner,function = "gpio_in";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
usb0_vbus_detect_pin: usb0_vbus_detect_pin@0 {
allwinner,pins = "PH05";
allwinner,function = "gpio_in";
allwinner,drive = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_NO_PULL>;
};
};
&reg_ahci_5v {
pinctrl-0 = <&ahci_pwr_pin_olimex_som_evb>;
gpio = <&pio 2 3 GPIO_ACTIVE_HIGH>;
status = "okay";
};
#include "axp209.dtsi"
&reg_dcdc2 {
regulator-always-on;
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1425000>;
regulator-name = "vdd-cpu";
};
&reg_dcdc3 {
regulator-always-on;
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1400000>;
regulator-name = "vdd-int-dll";
};
&reg_ldo1 {
regulator-name = "vdd-rtc";
};
&reg_ldo2 {
regulator-always-on;
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-name = "avcc";
};
&reg_usb0_vbus {
status = "okay";
};
&reg_usb1_vbus {
status = "okay";
};
&reg_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 = <&reg_usb0_vbus>;
usb1_vbus-supply = <&reg_usb1_vbus>;
usb2_vbus-supply = <&reg_usb2_vbus>;
status = "okay";
};

View File

@ -0,0 +1,145 @@
/*
* Copyright 2015 Hans de Goede <hdegoede@redhat.com>
*
* 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 <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
#include <dt-bindings/pinctrl/sun4i-a10.h>
/ {
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 = <&reg_vcc3v0>;
status = "okay";
button@200 {
label = "Volume Up";
linux,code = <KEY_VOLUMEUP>;
channel = <0>;
voltage = <200000>;
};
button@400 {
label = "Volume Down";
linux,code = <KEY_VOLUMEDOWN>;
channel = <0>;
voltage = <400000>;
};
button@600 {
label = "Back";
linux,code = <KEY_BACK>;
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 = <&reg_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 = <SUN4I_PINCTRL_10_MA>;
allwinner,pull = <SUN4I_PINCTRL_PULL_UP>;
};
};
&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";
};

View File

@ -0,0 +1,23 @@
/*
* (C) Copyright 2015 Chen-Yu Tsai <wens@csie.org>
*
* 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 */

View File

@ -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"

View File

@ -8,9 +8,9 @@ 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
F: configs/Mele_M3_defconfig
F: configs/Mini-X_defconfig
F: configs/mk802_defconfig
@ -21,11 +21,13 @@ 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
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
@ -40,11 +42,17 @@ 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
F: configs/Merrii_A80_Optimus_defconfig
A20-OLIMEX-SOM-EVB BOARD
M: Marcus Cooper <codekipper@gmail.com>
S: Maintained
F: configs/A20-Olimex-SOM-EVB_defconfig
A20-OLINUXINO-LIME BOARD
M: FUKAUMI Naoki <naobsd@gmail.com>
S: Maintained

View File

@ -31,6 +31,7 @@
#include <asm/arch/usb_phy.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <nand.h>
#include <net.h>
#if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD)
@ -107,26 +108,44 @@ 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;
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)
{
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);
}
void board_nand_init(void)
{
nand_pinmux_setup();
nand_clock_setup();
}
#endif
#ifdef CONFIG_GENERIC_MMC
@ -437,7 +456,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 */
@ -453,11 +472,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);

View File

@ -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

View File

@ -3,11 +3,11 @@ 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
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"

View File

@ -3,12 +3,12 @@ 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
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"

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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
@ -84,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
@ -92,46 +109,6 @@ 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 A20 in SPL"
depends on MACH_SUN7I
---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"
default 0x400000
depends on SPL_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.
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

View File

@ -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

View File

@ -5,9 +5,10 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm/arch/clock.h>
#include <asm/io.h>
#include <common.h>
#include <config.h>
#include <asm/io.h>
#include <nand.h>
/* registers */
@ -41,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)
@ -64,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
@ -85,6 +89,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 +99,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,
@ -156,6 +157,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,
@ -165,86 +168,49 @@ void nand_init(void)
NFC_CTL_RESET, MAX_RETRIES)) {
printf("Couldn't initialize nand\n");
}
/* 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_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 void nand_read_page(unsigned int real_addr, 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 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 (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(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 */
/* 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);
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;
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);
@ -262,15 +228,11 @@ static void nand_read_page(unsigned int real_addr, int syndrome,
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,
if (!syndrome)
writel(page_size + (column / ecc_page_size) * ecc_off,
SUNXI_NFC_BASE + NFC_SPARE_AREA);
} else {
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);
}
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 */
@ -278,15 +240,15 @@ 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);
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
| 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,
@ -300,54 +262,134 @@ static void nand_read_page(unsigned int real_addr, int syndrome,
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 | (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),
if (!check_value(SUNXI_NFC_BASE + NFC_ST, NFC_ST_DMA_INT_FLAG,
MAX_RETRIES)) {
printf("Error while initializing dma interrupt\n");
return;
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)) {
printf("Error while waiting for dma transfer to finish\n");
return;
return -1;
}
invalidate_dcache_range(dst,
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)
{
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)
{
void *current_dest;
uint32_t count;
uint32_t current_count;
uint32_t ecc_errors = 0;
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 i, syndrome;
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 (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 (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);
offs += CONFIG_NAND_SUNXI_SPL_ECC_PAGE_SIZE;
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 ecc_errors ? -1 : 0;
return nand_read_buffer(offs, size, dest, syndrome);
}
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);
}

View File

@ -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

View File

@ -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

View File

@ -137,16 +137,10 @@
#define CONFIG_INITRD_TAG
#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_SYS_NAND_U_BOOT_OFFS 0x008000
#ifdef CONFIG_NAND_SUNXI
#define CONFIG_SPL_NAND_SUPPORT 1
#endif
/* mmc config */
#if !defined(CONFIG_UART0_PORT_F)
#define CONFIG_MMC
@ -185,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 */