Merge git://www.denx.de/git/u-boot-marvell
This commit is contained in:
		
						commit
						b591730c35
					
				| 
						 | 
				
			
			@ -66,36 +66,14 @@
 | 
			
		|||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&i2c0 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
	clock-frequency = <100000>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&spi0 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
 | 
			
		||||
	spi-flash@0 {
 | 
			
		||||
		#address-cells = <1>;
 | 
			
		||||
		#size-cells = <1>;
 | 
			
		||||
		compatible = "jedec,spi-nor";
 | 
			
		||||
		reg = <0>;
 | 
			
		||||
		spi-max-frequency = <10000000>;
 | 
			
		||||
 | 
			
		||||
		partitions {
 | 
			
		||||
			compatible = "fixed-partitions";
 | 
			
		||||
			#address-cells = <1>;
 | 
			
		||||
			#size-cells = <1>;
 | 
			
		||||
 | 
			
		||||
			partition@0 {
 | 
			
		||||
				label = "U-Boot";
 | 
			
		||||
				reg = <0 0x200000>;
 | 
			
		||||
			};
 | 
			
		||||
			partition@400000 {
 | 
			
		||||
				label = "Filesystem";
 | 
			
		||||
				reg = <0x200000 0xce0000>;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
&ap_pinctl {
 | 
			
		||||
	   /* MPP Bus:
 | 
			
		||||
	    * SDIO  [0-5]
 | 
			
		||||
	    * UART0 [11,19]
 | 
			
		||||
	    */
 | 
			
		||||
		  /* 0 1 2 3 4 5 6 7 8 9 */
 | 
			
		||||
	pin-func = < 1 1 1 1 1 1 0 0 0 0
 | 
			
		||||
		     0 3 0 0 0 0 0 0 0 3 >;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&uart0 {
 | 
			
		||||
| 
						 | 
				
			
			@ -108,11 +86,37 @@
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
&cpm_i2c0 {
 | 
			
		||||
	pinctrl-names = "default";
 | 
			
		||||
	pinctrl-0 = <&cpm_i2c0_pins>;
 | 
			
		||||
	status = "okay";
 | 
			
		||||
	clock-frequency = <100000>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&cpm_pinctl {
 | 
			
		||||
		/* MPP Bus:
 | 
			
		||||
		 * TDM	 [0-11]
 | 
			
		||||
		 * SPI   [13-16]
 | 
			
		||||
		 * SATA1 [28]
 | 
			
		||||
		 * UART0 [29-30]
 | 
			
		||||
		 * SMI	 [32,34]
 | 
			
		||||
		 * XSMI  [35-36]
 | 
			
		||||
		 * I2C	 [37-38]
 | 
			
		||||
		 * RGMII1[44-55]
 | 
			
		||||
		 * SD	 [56-62]
 | 
			
		||||
		 */
 | 
			
		||||
		/*   0   1   2   3   4   5   6   7   8   9 */
 | 
			
		||||
	pin-func = < 4   4   4   4   4   4   4   4   4   4
 | 
			
		||||
		     4   4   0   3   3   3   3   0   0   0
 | 
			
		||||
		     0   0   0   0   0   0   0   0   9   0xA
 | 
			
		||||
		     0xA 0   7   0   7   7   7   2   2   0
 | 
			
		||||
		     0   0   0   0   1   1   1   1   1   1
 | 
			
		||||
		     1   1   1   1   1   1   0xE 0xE 0xE 0xE
 | 
			
		||||
		     0xE 0xE 0xE >;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&cpm_spi1 {
 | 
			
		||||
	pinctrl-names = "default";
 | 
			
		||||
	pinctrl-0 = <&cpm_spi0_pins>;
 | 
			
		||||
	status = "okay";
 | 
			
		||||
 | 
			
		||||
	spi-flash@0 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,7 +57,7 @@
 | 
			
		|||
 | 
			
		||||
	aliases {
 | 
			
		||||
		i2c0 = &cpm_i2c0;
 | 
			
		||||
		spi0 = &spi0;
 | 
			
		||||
		spi0 = &cps_spi1;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	memory@00000000 {
 | 
			
		||||
| 
						 | 
				
			
			@ -66,12 +66,99 @@
 | 
			
		|||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&i2c0 {
 | 
			
		||||
/* Accessible over the mini-USB CON9 connector on the main board */
 | 
			
		||||
&uart0 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&ap_pinctl {
 | 
			
		||||
	/* MPP Bus:
 | 
			
		||||
	 * SDIO  [0-10]
 | 
			
		||||
	 * UART0 [11,19]
 | 
			
		||||
	 */
 | 
			
		||||
		  /* 0 1 2 3 4 5 6 7 8 9 */
 | 
			
		||||
	pin-func = < 1 1 1 1 1 1 1 1 1 1
 | 
			
		||||
		     1 3 0 0 0 0 0 0 0 3 >;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&cpm_pinctl {
 | 
			
		||||
	/* MPP Bus:
 | 
			
		||||
	 * [0-31] = 0xff: Keep default CP0_shared_pins:
 | 
			
		||||
	 * [11] CLKOUT_MPP_11 (out)
 | 
			
		||||
	 * [23] LINK_RD_IN_CP2CP (in)
 | 
			
		||||
	 * [25] CLKOUT_MPP_25 (out)
 | 
			
		||||
	 * [29] AVS_FB_IN_CP2CP (in)
 | 
			
		||||
	 * [32,34] SMI
 | 
			
		||||
	 * [31]    GPIO: push button/Wake
 | 
			
		||||
	 * [35-36] GPIO
 | 
			
		||||
	 * [37-38] I2C
 | 
			
		||||
	 * [40-41] SATA[0/1]_PRESENT_ACTIVEn
 | 
			
		||||
	 * [42-43] XSMI
 | 
			
		||||
	 * [44-55] RGMII1
 | 
			
		||||
	 * [56-62] SD
 | 
			
		||||
	 */
 | 
			
		||||
		/*   0    1    2    3    4    5    6    7    8    9 */
 | 
			
		||||
	pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 | 
			
		||||
		     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 | 
			
		||||
		     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 | 
			
		||||
		     0xff 0    7    0    7    0    0    2    2    0
 | 
			
		||||
		     0    0    8    8    1    1    1    1    1    1
 | 
			
		||||
		     1    1    1    1    1    1    0xe  0xe  0xe  0xe
 | 
			
		||||
		     0xe  0xe  0xe >;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* CON5 on CP0 expansion */
 | 
			
		||||
&cpm_pcie2 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&cpm_i2c0 {
 | 
			
		||||
	pinctrl-names = "default";
 | 
			
		||||
	pinctrl-0 = <&cpm_i2c0_pins>;
 | 
			
		||||
	status = "okay";
 | 
			
		||||
	clock-frequency = <100000>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&spi0 {
 | 
			
		||||
/* CON4 on CP0 expansion */
 | 
			
		||||
&cpm_sata0 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* CON9 on CP0 expansion */
 | 
			
		||||
&cpm_usb3_0 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* CON10 on CP0 expansion */
 | 
			
		||||
&cpm_usb3_1 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&cps_pinctl {
 | 
			
		||||
	/* MPP Bus:
 | 
			
		||||
	 * [0-11]  RGMII0
 | 
			
		||||
	 * [13-16] SPI1
 | 
			
		||||
	 * [27,31] GE_MDIO/MDC
 | 
			
		||||
	 * [32-62] = 0xff: Keep default CP1_shared_pins:
 | 
			
		||||
	 */
 | 
			
		||||
		/*   0    1    2    3    4    5    6    7    8    9 */
 | 
			
		||||
	pin-func = < 0x3  0x3  0x3  0x3  0x3  0x3  0x3  0x3  0x3  0x3
 | 
			
		||||
		     0x3  0x3  0xff 0x3  0x3  0x3  0x3  0xff 0xff 0xff
 | 
			
		||||
		     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x8  0xff 0xff
 | 
			
		||||
		     0xff 0x8  0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 | 
			
		||||
		     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 | 
			
		||||
		     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 | 
			
		||||
		     0xff 0xff 0xff >;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* CON5 on CP1 expansion */
 | 
			
		||||
&cps_pcie2 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&cps_spi1 {
 | 
			
		||||
	pinctrl-names = "default";
 | 
			
		||||
	pinctrl-0 = <&cps_spi1_pins>;
 | 
			
		||||
	status = "okay";
 | 
			
		||||
 | 
			
		||||
	spi-flash@0 {
 | 
			
		||||
| 
						 | 
				
			
			@ -98,47 +185,6 @@
 | 
			
		|||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Accessible over the mini-USB CON9 connector on the main board */
 | 
			
		||||
&uart0 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* CON5 on CP0 expansion */
 | 
			
		||||
&cpm_pcie2 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&cpm_i2c0 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
	clock-frequency = <100000>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* CON4 on CP0 expansion */
 | 
			
		||||
&cpm_sata0 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* CON9 on CP0 expansion */
 | 
			
		||||
&cpm_usb3_0 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* CON10 on CP0 expansion */
 | 
			
		||||
&cpm_usb3_1 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* CON5 on CP1 expansion */
 | 
			
		||||
&cps_pcie2 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
&cps_i2c0 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
	clock-frequency = <100000>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* CON4 on CP1 expansion */
 | 
			
		||||
&cps_sata0 {
 | 
			
		||||
	status = "okay";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -140,6 +140,24 @@
 | 
			
		|||
				marvell,spi-base = <128>, <136>, <144>, <152>;
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			ap_pinctl: ap-pinctl@6F4000 {
 | 
			
		||||
				compatible = "marvell,armada-ap806-pinctrl";
 | 
			
		||||
				bank-name ="apn-806";
 | 
			
		||||
				reg = <0x6F4000 0x10>;
 | 
			
		||||
				pin-count = <20>;
 | 
			
		||||
				max-func = <3>;
 | 
			
		||||
 | 
			
		||||
				ap_i2c0_pins: i2c-pins-0 {
 | 
			
		||||
					marvell,pins = < 4 5 >;
 | 
			
		||||
					marvell,function = <3>;
 | 
			
		||||
				};
 | 
			
		||||
				ap_emmc_pins: emmc-pins-0 {
 | 
			
		||||
					marvell,pins = < 0 1 2 3 4 5 6 7
 | 
			
		||||
							 8 9 10 >;
 | 
			
		||||
					marvell,function = <1>;
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			xor@400000 {
 | 
			
		||||
				compatible = "marvell,mv-xor-v2";
 | 
			
		||||
				reg = <0x400000 0x1000>,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,6 +81,38 @@
 | 
			
		|||
					"cpm-usb3dev", "cpm-eip150", "cpm-eip197";
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			cpm_pinctl: cpm-pinctl@440000 {
 | 
			
		||||
				compatible = "marvell,mvebu-pinctrl",
 | 
			
		||||
					     "marvell,a70x0-pinctrl",
 | 
			
		||||
					     "marvell,a80x0-cp0-pinctrl";
 | 
			
		||||
				bank-name ="cp0-110";
 | 
			
		||||
				reg = <0x440000 0x20>;
 | 
			
		||||
				pin-count = <63>;
 | 
			
		||||
				max-func = <0xf>;
 | 
			
		||||
 | 
			
		||||
				cpm_i2c0_pins: cpm-i2c-pins-0 {
 | 
			
		||||
					marvell,pins = < 37 38 >;
 | 
			
		||||
					marvell,function = <2>;
 | 
			
		||||
				};
 | 
			
		||||
				cpm_ge2_rgmii_pins: cpm-ge-rgmii-pins-0 {
 | 
			
		||||
					marvell,pins = < 44 45 46 47 48 49 50 51
 | 
			
		||||
							 52 53 54 55 >;
 | 
			
		||||
					marvell,function = <1>;
 | 
			
		||||
				};
 | 
			
		||||
				pca0_pins: cpm-pca0_pins {
 | 
			
		||||
					marvell,pins = <62>;
 | 
			
		||||
					marvell,function = <0>;
 | 
			
		||||
				};
 | 
			
		||||
				cpm_sdhci_pins: cpm-sdhi-pins-0 {
 | 
			
		||||
					marvell,pins = < 56 57 58 59 60 61 >;
 | 
			
		||||
					marvell,function = <14>;
 | 
			
		||||
				};
 | 
			
		||||
				cpm_spi0_pins: cpm-spi-pins-0 {
 | 
			
		||||
					marvell,pins = < 13 14 15 16 >;
 | 
			
		||||
					marvell,function = <3>;
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			cpm_sata0: sata@540000 {
 | 
			
		||||
				compatible = "marvell,armada-8k-ahci";
 | 
			
		||||
				reg = <0x540000 0x30000>;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,6 +81,25 @@
 | 
			
		|||
					"cps-usb3dev", "cps-eip150", "cps-eip197";
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			cps_pinctl: cps-pinctl@440000 {
 | 
			
		||||
				compatible = "marvell,mvebu-pinctrl",
 | 
			
		||||
					     "marvell,a80x0-cp1-pinctrl";
 | 
			
		||||
				bank-name ="cp1-110";
 | 
			
		||||
				reg = <0x440000 0x20>;
 | 
			
		||||
				pin-count = <63>;
 | 
			
		||||
				max-func = <0xf>;
 | 
			
		||||
 | 
			
		||||
				cps_ge1_rgmii_pins: cps-ge-rgmii-pins-0 {
 | 
			
		||||
					marvell,pins = < 0  1  2  3  4  5  6  7
 | 
			
		||||
							 8  9  10 11 >;
 | 
			
		||||
					marvell,function = <3>;
 | 
			
		||||
				};
 | 
			
		||||
				cps_spi1_pins: cps-spi-pins-1 {
 | 
			
		||||
					marvell,pins = < 13 14 15 16 >;
 | 
			
		||||
					marvell,function = <3>;
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			cps_sata0: sata@540000 {
 | 
			
		||||
				compatible = "marvell,armada-8k-ahci";
 | 
			
		||||
				reg = <0x540000 0x30000>;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,21 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2016 Marvell International Ltd.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier:	GPL-2.0
 | 
			
		||||
 * https://spdx.org/licenses
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _CACHE_LLC_H_
 | 
			
		||||
#define _CACHE_LLC_H_
 | 
			
		||||
 | 
			
		||||
/* Armada-7K/8K last level cache */
 | 
			
		||||
 | 
			
		||||
#define MVEBU_A8K_REGS_BASE_MSB		0xf000
 | 
			
		||||
#define LLC_BASE_ADDR			0x8000
 | 
			
		||||
#define LLC_CACHE_SYNC			0x700
 | 
			
		||||
#define LLC_CACHE_SYNC_COMPLETE		0x730
 | 
			
		||||
#define LLC_FLUSH_BY_WAY		0x7fc
 | 
			
		||||
#define LLC_WAY_MASK			0xffffffff
 | 
			
		||||
#define LLC_CACHE_SYNC_MASK		0x1
 | 
			
		||||
 | 
			
		||||
#endif	/* _CACHE_LLC_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2016 Marvell International Ltd.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier:	GPL-2.0
 | 
			
		||||
 * https://spdx.org/licenses
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _SOC_INFO_H_
 | 
			
		||||
#define _SOC_INFO_H_
 | 
			
		||||
 | 
			
		||||
/* Pin Ctrl driver definitions */
 | 
			
		||||
#define BITS_PER_PIN		4
 | 
			
		||||
#define PIN_FUNC_MASK		((1 << BITS_PER_PIN) - 1)
 | 
			
		||||
#define PIN_REG_SHIFT		3
 | 
			
		||||
#define PIN_FIELD_MASK		((1 << PIN_REG_SHIFT) - 1)
 | 
			
		||||
 | 
			
		||||
#endif	/* _SOC_INFO_H_ */
 | 
			
		||||
| 
						 | 
				
			
			@ -5,3 +5,4 @@
 | 
			
		|||
#
 | 
			
		||||
 | 
			
		||||
obj-y = cpu.o
 | 
			
		||||
obj-y += cache_llc.o
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2016 Marvell International Ltd.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier:	GPL-2.0
 | 
			
		||||
 * https://spdx.org/licenses
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <asm/arch-armada8k/cache_llc.h>
 | 
			
		||||
#include <linux/linkage.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * int __asm_flush_l3_dcache
 | 
			
		||||
 *
 | 
			
		||||
 * flush Armada-8K last level cache.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
ENTRY(__asm_flush_l3_dcache)
 | 
			
		||||
	/* flush cache */
 | 
			
		||||
	mov     x0, #LLC_BASE_ADDR
 | 
			
		||||
	add	x0, x0, #LLC_FLUSH_BY_WAY
 | 
			
		||||
	movk    x0, #MVEBU_A8K_REGS_BASE_MSB, lsl #16
 | 
			
		||||
	mov     w1, #LLC_WAY_MASK
 | 
			
		||||
	str     w1, [x0]
 | 
			
		||||
	/* sync cache */
 | 
			
		||||
	mov     x0, #LLC_BASE_ADDR
 | 
			
		||||
	add	x0, x0, #LLC_CACHE_SYNC
 | 
			
		||||
	movk    x0, #MVEBU_A8K_REGS_BASE_MSB, lsl #16
 | 
			
		||||
	str     wzr, [x0]
 | 
			
		||||
	/* check that cache sync completed */
 | 
			
		||||
	mov     x0, #LLC_BASE_ADDR
 | 
			
		||||
	add	x0, x0, #LLC_CACHE_SYNC_COMPLETE
 | 
			
		||||
	movk    x0, #MVEBU_A8K_REGS_BASE_MSB, lsl #16
 | 
			
		||||
1:	ldr	w1, [x0]
 | 
			
		||||
	and	w1, w1, #LLC_CACHE_SYNC_MASK
 | 
			
		||||
	cbnz	w1, 1b
 | 
			
		||||
	/* return success */
 | 
			
		||||
	mov	x0, #0
 | 
			
		||||
	ret
 | 
			
		||||
ENDPROC(__asm_flush_l3_dcache)
 | 
			
		||||
| 
						 | 
				
			
			@ -653,6 +653,9 @@ config CMD_QFW
 | 
			
		|||
	  This provides access to the QEMU firmware interface.  The main
 | 
			
		||||
	  feature is to allow easy loading of files passed to qemu-system
 | 
			
		||||
	  via -kernel / -initrd
 | 
			
		||||
 | 
			
		||||
source "cmd/mvebu/Kconfig"
 | 
			
		||||
 | 
			
		||||
endmenu
 | 
			
		||||
 | 
			
		||||
config CMD_BOOTSTAGE
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -163,3 +163,5 @@ obj-$(CONFIG_CMD_BLOB) += blob.o
 | 
			
		|||
 | 
			
		||||
# core command
 | 
			
		||||
obj-y += nvedit.o
 | 
			
		||||
 | 
			
		||||
obj-$(CONFIG_ARCH_MVEBU) += mvebu/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,52 @@
 | 
			
		|||
menu "MVEBU commands"
 | 
			
		||||
depends on ARCH_MVEBU
 | 
			
		||||
 | 
			
		||||
config CMD_MVEBU_BUBT
 | 
			
		||||
	bool "bubt"
 | 
			
		||||
	default n
 | 
			
		||||
	help
 | 
			
		||||
	  bubt - Burn a u-boot image to flash
 | 
			
		||||
	  For details about bubt command please see the documentation
 | 
			
		||||
	  in doc/mvebu/cmd/bubt.txt
 | 
			
		||||
 | 
			
		||||
choice
 | 
			
		||||
	prompt "Flash for image"
 | 
			
		||||
	default MVEBU_SPI_BOOT
 | 
			
		||||
 | 
			
		||||
config MVEBU_NAND_BOOT
 | 
			
		||||
	bool "NAND flash boot"
 | 
			
		||||
	depends on NAND_PXA3XX
 | 
			
		||||
	help
 | 
			
		||||
	  Enable boot from NAND flash.
 | 
			
		||||
	  Allow usage of NAND flash as a target for "bubt" command
 | 
			
		||||
	  For details about bubt command please see the documentation
 | 
			
		||||
	  in doc/mvebu/cmd/bubt.txt
 | 
			
		||||
 | 
			
		||||
config MVEBU_SPI_BOOT
 | 
			
		||||
	bool "SPI flash boot"
 | 
			
		||||
	depends on SPI_FLASH
 | 
			
		||||
	help
 | 
			
		||||
	  Enable boot from SPI flash.
 | 
			
		||||
	  Allow usage of SPI flash as a target for "bubt" command
 | 
			
		||||
	  For details about bubt command please see the documentation
 | 
			
		||||
	  in doc/mvebu/cmd/bubt.txt
 | 
			
		||||
 | 
			
		||||
config MVEBU_MMC_BOOT
 | 
			
		||||
	bool "eMMC flash boot"
 | 
			
		||||
	depends on MVEBU_MMC
 | 
			
		||||
	help
 | 
			
		||||
	  Enable boot from eMMC boot partition
 | 
			
		||||
	  Allow usage of eMMC/SD device as a target for "bubt" command
 | 
			
		||||
	  For details about bubt command please see the documentation
 | 
			
		||||
	  in doc/mvebu/cmd/bubt.txt
 | 
			
		||||
 | 
			
		||||
endchoice
 | 
			
		||||
 | 
			
		||||
config MVEBU_UBOOT_DFLT_NAME
 | 
			
		||||
	string "Default image name for bubt command"
 | 
			
		||||
	default "flash-image.bin"
 | 
			
		||||
	help
 | 
			
		||||
	  This option should contain a default file name to be used with
 | 
			
		||||
	  MVEBU "bubt" command if the source file name is omitted
 | 
			
		||||
 | 
			
		||||
endmenu
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,8 @@
 | 
			
		|||
#
 | 
			
		||||
# Copyright (C) 2016 Marvell International Ltd.
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier:	GPL-2.0
 | 
			
		||||
# https://spdx.org/licenses
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
obj-$(CONFIG_CMD_MVEBU_BUBT) += bubt.o
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,767 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2016 Marvell International Ltd.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier:	GPL-2.0
 | 
			
		||||
 * https://spdx.org/licenses
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <common.h>
 | 
			
		||||
#include <command.h>
 | 
			
		||||
#include <vsprintf.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <dm.h>
 | 
			
		||||
 | 
			
		||||
#include <spi_flash.h>
 | 
			
		||||
#include <spi.h>
 | 
			
		||||
#include <nand.h>
 | 
			
		||||
#include <usb.h>
 | 
			
		||||
#include <fs.h>
 | 
			
		||||
#include <mmc.h>
 | 
			
		||||
#include <u-boot/sha1.h>
 | 
			
		||||
#include <u-boot/sha256.h>
 | 
			
		||||
 | 
			
		||||
#ifndef CONFIG_SYS_MMC_ENV_DEV
 | 
			
		||||
#define CONFIG_SYS_MMC_ENV_DEV	0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_ARMADA_8K)
 | 
			
		||||
#define MAIN_HDR_MAGIC		0xB105B002
 | 
			
		||||
 | 
			
		||||
struct mvebu_image_header {
 | 
			
		||||
	u32	magic;			/*  0-3  */
 | 
			
		||||
	u32	prolog_size;		/*  4-7  */
 | 
			
		||||
	u32	prolog_checksum;	/*  8-11 */
 | 
			
		||||
	u32	boot_image_size;	/* 12-15 */
 | 
			
		||||
	u32	boot_image_checksum;	/* 16-19 */
 | 
			
		||||
	u32	rsrvd0;			/* 20-23 */
 | 
			
		||||
	u32	load_addr;		/* 24-27 */
 | 
			
		||||
	u32	exec_addr;		/* 28-31 */
 | 
			
		||||
	u8	uart_cfg;		/*  32   */
 | 
			
		||||
	u8	baudrate;		/*  33   */
 | 
			
		||||
	u8	ext_count;		/*  34   */
 | 
			
		||||
	u8	aux_flags;		/*  35   */
 | 
			
		||||
	u32	io_arg_0;		/* 36-39 */
 | 
			
		||||
	u32	io_arg_1;		/* 40-43 */
 | 
			
		||||
	u32	io_arg_2;		/* 43-47 */
 | 
			
		||||
	u32	io_arg_3;		/* 48-51 */
 | 
			
		||||
	u32	rsrvd1;			/* 52-55 */
 | 
			
		||||
	u32	rsrvd2;			/* 56-59 */
 | 
			
		||||
	u32	rsrvd3;			/* 60-63 */
 | 
			
		||||
};
 | 
			
		||||
#elif defined(CONFIG_ARMADA_3700)	/* A3700 */
 | 
			
		||||
#define HASH_SUM_LEN		16
 | 
			
		||||
#define IMAGE_VERSION_3_6_0	0x030600
 | 
			
		||||
#define IMAGE_VERSION_3_5_0	0x030500
 | 
			
		||||
 | 
			
		||||
struct common_tim_data {
 | 
			
		||||
	u32	version;
 | 
			
		||||
	u32	identifier;
 | 
			
		||||
	u32	trusted;
 | 
			
		||||
	u32	issue_date;
 | 
			
		||||
	u32	oem_unique_id;
 | 
			
		||||
	u32	reserved[5];		/* Reserve 20 bytes */
 | 
			
		||||
	u32	boot_flash_sign;
 | 
			
		||||
	u32	num_images;
 | 
			
		||||
	u32	num_keys;
 | 
			
		||||
	u32	size_of_reserved;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct mvebu_image_info {
 | 
			
		||||
	u32	image_id;
 | 
			
		||||
	u32	next_image_id;
 | 
			
		||||
	u32	flash_entry_addr;
 | 
			
		||||
	u32	load_addr;
 | 
			
		||||
	u32	image_size;
 | 
			
		||||
	u32	image_size_to_hash;
 | 
			
		||||
	u32	hash_algorithm_id;
 | 
			
		||||
	u32	hash[HASH_SUM_LEN];	/* Reserve 512 bits for the hash */
 | 
			
		||||
	u32	partition_number;
 | 
			
		||||
	u32	enc_algorithm_id;
 | 
			
		||||
	u32	encrypt_start_offset;
 | 
			
		||||
	u32	encrypt_size;
 | 
			
		||||
};
 | 
			
		||||
#endif /* CONFIG_ARMADA_XXX */
 | 
			
		||||
 | 
			
		||||
struct bubt_dev {
 | 
			
		||||
	char name[8];
 | 
			
		||||
	size_t (*read)(const char *file_name);
 | 
			
		||||
	int (*write)(size_t image_size);
 | 
			
		||||
	int (*active)(void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static ulong get_load_addr(void)
 | 
			
		||||
{
 | 
			
		||||
	const char *addr_str;
 | 
			
		||||
	unsigned long addr;
 | 
			
		||||
 | 
			
		||||
	addr_str = getenv("loadaddr");
 | 
			
		||||
	if (addr_str)
 | 
			
		||||
		addr = simple_strtoul(addr_str, NULL, 16);
 | 
			
		||||
	else
 | 
			
		||||
		addr = CONFIG_SYS_LOAD_ADDR;
 | 
			
		||||
 | 
			
		||||
	return addr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/********************************************************************
 | 
			
		||||
 *     eMMC services
 | 
			
		||||
 ********************************************************************/
 | 
			
		||||
#ifdef CONFIG_DM_MMC
 | 
			
		||||
static int mmc_burn_image(size_t image_size)
 | 
			
		||||
{
 | 
			
		||||
	struct mmc	*mmc;
 | 
			
		||||
	lbaint_t	start_lba;
 | 
			
		||||
	lbaint_t	blk_count;
 | 
			
		||||
	ulong		blk_written;
 | 
			
		||||
	int		err;
 | 
			
		||||
	const u8	mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
 | 
			
		||||
 | 
			
		||||
	mmc = find_mmc_device(mmc_dev_num);
 | 
			
		||||
	if (!mmc) {
 | 
			
		||||
		printf("No SD/MMC/eMMC card found\n");
 | 
			
		||||
		return -ENOMEDIUM;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = mmc_init(mmc);
 | 
			
		||||
	if (err) {
 | 
			
		||||
		printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
 | 
			
		||||
		       mmc_dev_num);
 | 
			
		||||
		return err;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_SYS_MMC_ENV_PART
 | 
			
		||||
	if (mmc->part_num != CONFIG_SYS_MMC_ENV_PART) {
 | 
			
		||||
		err = mmc_switch_part(mmc_dev_num, CONFIG_SYS_MMC_ENV_PART);
 | 
			
		||||
		if (err) {
 | 
			
		||||
			printf("MMC partition switch failed\n");
 | 
			
		||||
			return err;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	/* SD reserves LBA-0 for MBR and boots from LBA-1,
 | 
			
		||||
	 * MMC/eMMC boots from LBA-0
 | 
			
		||||
	 */
 | 
			
		||||
	start_lba = IS_SD(mmc) ? 1 : 0;
 | 
			
		||||
	blk_count = image_size / mmc->block_dev.blksz;
 | 
			
		||||
	if (image_size % mmc->block_dev.blksz)
 | 
			
		||||
		blk_count += 1;
 | 
			
		||||
 | 
			
		||||
	blk_written = mmc->block_dev.block_write(mmc_dev_num,
 | 
			
		||||
						start_lba, blk_count,
 | 
			
		||||
						(void *)get_load_addr());
 | 
			
		||||
	if (blk_written != blk_count) {
 | 
			
		||||
		printf("Error - written %#lx blocks\n", blk_written);
 | 
			
		||||
		return -ENOSPC;
 | 
			
		||||
	}
 | 
			
		||||
	printf("Done!\n");
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_SYS_MMC_ENV_PART
 | 
			
		||||
	if (mmc->part_num != CONFIG_SYS_MMC_ENV_PART)
 | 
			
		||||
		mmc_switch_part(mmc_dev_num, mmc->part_num);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static size_t mmc_read_file(const char *file_name)
 | 
			
		||||
{
 | 
			
		||||
	loff_t		act_read = 0;
 | 
			
		||||
	int		rc;
 | 
			
		||||
	struct mmc	*mmc;
 | 
			
		||||
	const u8	mmc_dev_num = CONFIG_SYS_MMC_ENV_DEV;
 | 
			
		||||
 | 
			
		||||
	mmc = find_mmc_device(mmc_dev_num);
 | 
			
		||||
	if (!mmc) {
 | 
			
		||||
		printf("No SD/MMC/eMMC card found\n");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (mmc_init(mmc)) {
 | 
			
		||||
		printf("%s(%d) init failed\n", IS_SD(mmc) ? "SD" : "MMC",
 | 
			
		||||
		       mmc_dev_num);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Load from data partition (0) */
 | 
			
		||||
	if (fs_set_blk_dev("mmc", "0", FS_TYPE_ANY)) {
 | 
			
		||||
		printf("Error: MMC 0 not found\n");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Perfrom file read */
 | 
			
		||||
	rc = fs_read(file_name, get_load_addr(), 0, 0, &act_read);
 | 
			
		||||
	if (rc)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return act_read;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int is_mmc_active(void)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
#else /* CONFIG_DM_MMC */
 | 
			
		||||
static int mmc_burn_image(size_t image_size)
 | 
			
		||||
{
 | 
			
		||||
	return -ENODEV;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static size_t mmc_read_file(const char *file_name)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int is_mmc_active(void)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif /* CONFIG_DM_MMC */
 | 
			
		||||
 | 
			
		||||
/********************************************************************
 | 
			
		||||
 *     SPI services
 | 
			
		||||
 ********************************************************************/
 | 
			
		||||
#ifdef CONFIG_SPI_FLASH
 | 
			
		||||
static int spi_burn_image(size_t image_size)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	struct spi_flash *flash;
 | 
			
		||||
	u32 erase_bytes;
 | 
			
		||||
 | 
			
		||||
	/* Probe the SPI bus to get the flash device */
 | 
			
		||||
	flash = spi_flash_probe(CONFIG_ENV_SPI_BUS,
 | 
			
		||||
				CONFIG_ENV_SPI_CS,
 | 
			
		||||
				CONFIG_SF_DEFAULT_SPEED,
 | 
			
		||||
				CONFIG_SF_DEFAULT_MODE);
 | 
			
		||||
	if (!flash) {
 | 
			
		||||
		printf("Failed to probe SPI Flash\n");
 | 
			
		||||
		return -ENOMEDIUM;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_SPI_FLASH_PROTECTION
 | 
			
		||||
	spi_flash_protect(flash, 0);
 | 
			
		||||
#endif
 | 
			
		||||
	erase_bytes = image_size +
 | 
			
		||||
		(flash->erase_size - image_size % flash->erase_size);
 | 
			
		||||
	printf("Erasing %d bytes (%d blocks) at offset 0 ...",
 | 
			
		||||
	       erase_bytes, erase_bytes / flash->erase_size);
 | 
			
		||||
	ret = spi_flash_erase(flash, 0, erase_bytes);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		printf("Error!\n");
 | 
			
		||||
	else
 | 
			
		||||
		printf("Done!\n");
 | 
			
		||||
 | 
			
		||||
	printf("Writing %d bytes from 0x%lx to offset 0 ...",
 | 
			
		||||
	       (int)image_size, get_load_addr());
 | 
			
		||||
	ret = spi_flash_write(flash, 0, image_size, (void *)get_load_addr());
 | 
			
		||||
	if (ret)
 | 
			
		||||
		printf("Error!\n");
 | 
			
		||||
	else
 | 
			
		||||
		printf("Done!\n");
 | 
			
		||||
 | 
			
		||||
#ifdef CONFIG_SPI_FLASH_PROTECTION
 | 
			
		||||
	spi_flash_protect(flash, 1);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int is_spi_active(void)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else /* CONFIG_SPI_FLASH */
 | 
			
		||||
static int spi_burn_image(size_t image_size)
 | 
			
		||||
{
 | 
			
		||||
	return -ENODEV;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int is_spi_active(void)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif /* CONFIG_SPI_FLASH */
 | 
			
		||||
 | 
			
		||||
/********************************************************************
 | 
			
		||||
 *     NAND services
 | 
			
		||||
 ********************************************************************/
 | 
			
		||||
#ifdef CONFIG_CMD_NAND
 | 
			
		||||
static int nand_burn_image(size_t image_size)
 | 
			
		||||
{
 | 
			
		||||
	int ret, block_size;
 | 
			
		||||
	nand_info_t *nand;
 | 
			
		||||
	int dev = nand_curr_device;
 | 
			
		||||
 | 
			
		||||
	if ((dev < 0) || (dev >= CONFIG_SYS_MAX_NAND_DEVICE) ||
 | 
			
		||||
	    (!nand_info[dev].name)) {
 | 
			
		||||
		puts("\nno devices available\n");
 | 
			
		||||
		return -ENOMEDIUM;
 | 
			
		||||
	}
 | 
			
		||||
	nand = &nand_info[dev];
 | 
			
		||||
	block_size = nand->erasesize;
 | 
			
		||||
 | 
			
		||||
	/* Align U-Boot size to currently used blocksize */
 | 
			
		||||
	image_size = ((image_size + (block_size - 1)) & (~(block_size - 1)));
 | 
			
		||||
 | 
			
		||||
	/* Erase the U-BOOT image space */
 | 
			
		||||
	printf("Erasing 0x%x - 0x%x:...", 0, (int)image_size);
 | 
			
		||||
	ret = nand_erase(nand, 0, image_size);
 | 
			
		||||
	if (ret) {
 | 
			
		||||
		printf("Error!\n");
 | 
			
		||||
		goto error;
 | 
			
		||||
	}
 | 
			
		||||
	printf("Done!\n");
 | 
			
		||||
 | 
			
		||||
	/* Write the image to flash */
 | 
			
		||||
	printf("Writing image:...");
 | 
			
		||||
	printf("&image_size = 0x%p\n", (void *)&image_size);
 | 
			
		||||
	ret = nand_write(nand, 0, &image_size, (void *)get_load_addr());
 | 
			
		||||
	if (ret)
 | 
			
		||||
		printf("Error!\n");
 | 
			
		||||
	else
 | 
			
		||||
		printf("Done!\n");
 | 
			
		||||
 | 
			
		||||
error:
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int is_nand_active(void)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else /* CONFIG_CMD_NAND */
 | 
			
		||||
static int nand_burn_image(size_t image_size)
 | 
			
		||||
{
 | 
			
		||||
	return -ENODEV;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int is_nand_active(void)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif /* CONFIG_CMD_NAND */
 | 
			
		||||
 | 
			
		||||
/********************************************************************
 | 
			
		||||
 *     USB services
 | 
			
		||||
 ********************************************************************/
 | 
			
		||||
#if defined(CONFIG_USB_STORAGE) && defined(CONFIG_BLK)
 | 
			
		||||
static size_t usb_read_file(const char *file_name)
 | 
			
		||||
{
 | 
			
		||||
	loff_t act_read = 0;
 | 
			
		||||
	struct udevice *dev;
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	usb_stop();
 | 
			
		||||
 | 
			
		||||
	if (usb_init() < 0) {
 | 
			
		||||
		printf("Error: usb_init failed\n");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Try to recognize storage devices immediately */
 | 
			
		||||
	blk_first_device(IF_TYPE_USB, &dev);
 | 
			
		||||
	if (!dev) {
 | 
			
		||||
		printf("Error: USB storage device not found\n");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Always load from usb 0 */
 | 
			
		||||
	if (fs_set_blk_dev("usb", "0", FS_TYPE_ANY)) {
 | 
			
		||||
		printf("Error: USB 0 not found\n");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Perfrom file read */
 | 
			
		||||
	rc = fs_read(file_name, get_load_addr(), 0, 0, &act_read);
 | 
			
		||||
	if (rc)
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return act_read;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int is_usb_active(void)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else /* defined(CONFIG_USB_STORAGE) && defined (CONFIG_BLK) */
 | 
			
		||||
static size_t usb_read_file(const char *file_name)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int is_usb_active(void)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif /* defined(CONFIG_USB_STORAGE) && defined (CONFIG_BLK) */
 | 
			
		||||
 | 
			
		||||
/********************************************************************
 | 
			
		||||
 *     Network services
 | 
			
		||||
 ********************************************************************/
 | 
			
		||||
#ifdef CONFIG_CMD_NET
 | 
			
		||||
static size_t tftp_read_file(const char *file_name)
 | 
			
		||||
{
 | 
			
		||||
	/* update global variable load_addr before tftp file from network */
 | 
			
		||||
	load_addr = get_load_addr();
 | 
			
		||||
	return net_loop(TFTPGET);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int is_tftp_active(void)
 | 
			
		||||
{
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
static size_t tftp_read_file(const char *file_name)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int is_tftp_active(void)
 | 
			
		||||
{
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif /* CONFIG_CMD_NET */
 | 
			
		||||
 | 
			
		||||
enum bubt_devices {
 | 
			
		||||
	BUBT_DEV_NET = 0,
 | 
			
		||||
	BUBT_DEV_USB,
 | 
			
		||||
	BUBT_DEV_MMC,
 | 
			
		||||
	BUBT_DEV_SPI,
 | 
			
		||||
	BUBT_DEV_NAND,
 | 
			
		||||
 | 
			
		||||
	BUBT_MAX_DEV
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct bubt_dev bubt_devs[BUBT_MAX_DEV] = {
 | 
			
		||||
	{"tftp", tftp_read_file, NULL, is_tftp_active},
 | 
			
		||||
	{"usb",  usb_read_file,  NULL, is_usb_active},
 | 
			
		||||
	{"mmc",  mmc_read_file,  mmc_burn_image, is_mmc_active},
 | 
			
		||||
	{"spi",  NULL, spi_burn_image,  is_spi_active},
 | 
			
		||||
	{"nand", NULL, nand_burn_image, is_nand_active},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int bubt_write_file(struct bubt_dev *dst, size_t image_size)
 | 
			
		||||
{
 | 
			
		||||
	if (!dst->write) {
 | 
			
		||||
		printf("Error: Write not supported on device %s\n", dst->name);
 | 
			
		||||
		return -ENOTSUPP;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return dst->write(image_size);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined(CONFIG_ARMADA_8K)
 | 
			
		||||
u32 do_checksum32(u32 *start, int32_t len)
 | 
			
		||||
{
 | 
			
		||||
	u32 sum = 0;
 | 
			
		||||
	u32 *startp = start;
 | 
			
		||||
 | 
			
		||||
	do {
 | 
			
		||||
		sum += *startp;
 | 
			
		||||
		startp++;
 | 
			
		||||
		len -= 4;
 | 
			
		||||
	} while (len > 0);
 | 
			
		||||
 | 
			
		||||
	return sum;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int check_image_header(void)
 | 
			
		||||
{
 | 
			
		||||
	struct mvebu_image_header *hdr =
 | 
			
		||||
			(struct mvebu_image_header *)get_load_addr();
 | 
			
		||||
	u32 header_len = hdr->prolog_size;
 | 
			
		||||
	u32 checksum;
 | 
			
		||||
	u32 checksum_ref = hdr->prolog_checksum;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * For now compare checksum, and magic. Later we can
 | 
			
		||||
	 * verify more stuff on the header like interface type, etc
 | 
			
		||||
	 */
 | 
			
		||||
	if (hdr->magic != MAIN_HDR_MAGIC) {
 | 
			
		||||
		printf("ERROR: Bad MAGIC 0x%08x != 0x%08x\n",
 | 
			
		||||
		       hdr->magic, MAIN_HDR_MAGIC);
 | 
			
		||||
		return -ENOEXEC;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* The checksum value is discarded from checksum calculation */
 | 
			
		||||
	hdr->prolog_checksum = 0;
 | 
			
		||||
 | 
			
		||||
	checksum = do_checksum32((u32 *)hdr, header_len);
 | 
			
		||||
	if (checksum != checksum_ref) {
 | 
			
		||||
		printf("Error: Bad Image checksum. 0x%x != 0x%x\n",
 | 
			
		||||
		       checksum, checksum_ref);
 | 
			
		||||
		return -ENOEXEC;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Restore the checksum before writing */
 | 
			
		||||
	hdr->prolog_checksum = checksum_ref;
 | 
			
		||||
	printf("Image checksum...OK!\n");
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
#elif defined(CONFIG_ARMADA_3700) /* Armada 3700 */
 | 
			
		||||
static int check_image_header(void)
 | 
			
		||||
{
 | 
			
		||||
	struct common_tim_data *hdr = (struct common_tim_data *)get_load_addr();
 | 
			
		||||
	int image_num;
 | 
			
		||||
	u8 hash_160_output[SHA1_SUM_LEN];
 | 
			
		||||
	u8 hash_256_output[SHA256_SUM_LEN];
 | 
			
		||||
	sha1_context hash1_text;
 | 
			
		||||
	sha256_context hash256_text;
 | 
			
		||||
	u8 *hash_output;
 | 
			
		||||
	u32 hash_algorithm_id;
 | 
			
		||||
	u32 image_size_to_hash;
 | 
			
		||||
	u32 flash_entry_addr;
 | 
			
		||||
	u32 *hash_value;
 | 
			
		||||
	u32 internal_hash[HASH_SUM_LEN];
 | 
			
		||||
	const u8 *buff;
 | 
			
		||||
	u32 num_of_image = hdr->num_images;
 | 
			
		||||
	u32 version = hdr->version;
 | 
			
		||||
	u32 trusted = hdr->trusted;
 | 
			
		||||
 | 
			
		||||
	/* bubt checksum validation only supports nontrusted images */
 | 
			
		||||
	if (trusted == 1) {
 | 
			
		||||
		printf("bypass image validation, ");
 | 
			
		||||
		printf("only untrusted image is supported now\n");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	/* only supports image version 3.5 and 3.6 */
 | 
			
		||||
	if (version != IMAGE_VERSION_3_5_0 && version != IMAGE_VERSION_3_6_0) {
 | 
			
		||||
		printf("Error: Unsupported Image version = 0x%08x\n", version);
 | 
			
		||||
		return -ENOEXEC;
 | 
			
		||||
	}
 | 
			
		||||
	/* validate images hash value */
 | 
			
		||||
	for (image_num = 0; image_num < num_of_image; image_num++) {
 | 
			
		||||
		struct mvebu_image_info *info =
 | 
			
		||||
				(struct mvebu_image_info *)(get_load_addr() +
 | 
			
		||||
				sizeof(struct common_tim_data) +
 | 
			
		||||
				image_num * sizeof(struct mvebu_image_info));
 | 
			
		||||
		hash_algorithm_id = info->hash_algorithm_id;
 | 
			
		||||
		image_size_to_hash = info->image_size_to_hash;
 | 
			
		||||
		flash_entry_addr = info->flash_entry_addr;
 | 
			
		||||
		hash_value = info->hash;
 | 
			
		||||
		buff = (const u8 *)(get_load_addr() + flash_entry_addr);
 | 
			
		||||
 | 
			
		||||
		if (image_num == 0) {
 | 
			
		||||
			/*
 | 
			
		||||
			 * The first image includes hash values in its content.
 | 
			
		||||
			 * For hash calculation, we need to save the original
 | 
			
		||||
			 * hash values to a local variable that will be
 | 
			
		||||
			 * copied back for comparsion and set all zeros to
 | 
			
		||||
			 * the orignal hash values for calculating new value.
 | 
			
		||||
			 * First image original format :
 | 
			
		||||
			 * x...x (datum1) x...x(orig. hash values) x...x(datum2)
 | 
			
		||||
			 * Replaced first image format :
 | 
			
		||||
			 * x...x (datum1) 0...0(hash values) x...x(datum2)
 | 
			
		||||
			 */
 | 
			
		||||
			memcpy(internal_hash, hash_value,
 | 
			
		||||
			       sizeof(internal_hash));
 | 
			
		||||
			memset(hash_value, 0, sizeof(internal_hash));
 | 
			
		||||
		}
 | 
			
		||||
		if (image_size_to_hash == 0) {
 | 
			
		||||
			printf("Warning: Image_%d hash checksum is disabled, ",
 | 
			
		||||
			       image_num);
 | 
			
		||||
			printf("skip the image validation.\n");
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		switch (hash_algorithm_id) {
 | 
			
		||||
		case SHA1_SUM_LEN:
 | 
			
		||||
			sha1_starts(&hash1_text);
 | 
			
		||||
			sha1_update(&hash1_text, buff, image_size_to_hash);
 | 
			
		||||
			sha1_finish(&hash1_text, hash_160_output);
 | 
			
		||||
			hash_output = hash_160_output;
 | 
			
		||||
			break;
 | 
			
		||||
		case SHA256_SUM_LEN:
 | 
			
		||||
			sha256_starts(&hash256_text);
 | 
			
		||||
			sha256_update(&hash256_text, buff, image_size_to_hash);
 | 
			
		||||
			sha256_finish(&hash256_text, hash_256_output);
 | 
			
		||||
			hash_output = hash_256_output;
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			printf("Error: Unsupported hash_algorithm_id = %d\n",
 | 
			
		||||
			       hash_algorithm_id);
 | 
			
		||||
			return -ENOEXEC;
 | 
			
		||||
		}
 | 
			
		||||
		if (image_num == 0)
 | 
			
		||||
			memcpy(hash_value, internal_hash,
 | 
			
		||||
			       sizeof(internal_hash));
 | 
			
		||||
		if (memcmp(hash_value, hash_output, hash_algorithm_id) != 0) {
 | 
			
		||||
			printf("Error: Image_%d checksum is not correct\n",
 | 
			
		||||
			       image_num);
 | 
			
		||||
			return -ENOEXEC;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	printf("Image checksum...OK!\n");
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else /* Not ARMADA? */
 | 
			
		||||
static int check_image_header(void)
 | 
			
		||||
{
 | 
			
		||||
	printf("bubt cmd does not support this SoC device or family!\n");
 | 
			
		||||
	return -ENOEXEC;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static int bubt_verify(size_t image_size)
 | 
			
		||||
{
 | 
			
		||||
	int err;
 | 
			
		||||
 | 
			
		||||
	/* Check a correct image header exists */
 | 
			
		||||
	err = check_image_header();
 | 
			
		||||
	if (err) {
 | 
			
		||||
		printf("Error: Image header verification failed\n");
 | 
			
		||||
		return err;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int bubt_read_file(struct bubt_dev *src)
 | 
			
		||||
{
 | 
			
		||||
	size_t image_size;
 | 
			
		||||
 | 
			
		||||
	if (!src->read) {
 | 
			
		||||
		printf("Error: Read not supported on device \"%s\"\n",
 | 
			
		||||
		       src->name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	image_size = src->read(net_boot_file_name);
 | 
			
		||||
	if (image_size <= 0) {
 | 
			
		||||
		printf("Error: Failed to read file %s from %s\n",
 | 
			
		||||
		       net_boot_file_name, src->name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return image_size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int bubt_is_dev_active(struct bubt_dev *dev)
 | 
			
		||||
{
 | 
			
		||||
	if (!dev->active) {
 | 
			
		||||
		printf("Device \"%s\" not supported by U-BOOT image\n",
 | 
			
		||||
		       dev->name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!dev->active()) {
 | 
			
		||||
		printf("Device \"%s\" is inactive\n", dev->name);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct bubt_dev *find_bubt_dev(char *dev_name)
 | 
			
		||||
{
 | 
			
		||||
	int dev;
 | 
			
		||||
 | 
			
		||||
	for (dev = 0; dev < BUBT_MAX_DEV; dev++) {
 | 
			
		||||
		if (strcmp(bubt_devs[dev].name, dev_name) == 0)
 | 
			
		||||
			return &bubt_devs[dev];
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_BUBT_SRC "tftp"
 | 
			
		||||
 | 
			
		||||
#ifndef DEFAULT_BUBT_DST
 | 
			
		||||
#ifdef CONFIG_MVEBU_SPI_BOOT
 | 
			
		||||
#define DEFAULT_BUBT_DST "spi"
 | 
			
		||||
#elif defined(CONFIG_MVEBU_NAND_BOOT)
 | 
			
		||||
#define DEFAULT_BUBT_DST "nand"
 | 
			
		||||
#elif defined(CONFIG_MVEBU_MMC_BOOT)
 | 
			
		||||
#define DEFAULT_BUBT_DST "mmc"
 | 
			
		||||
else
 | 
			
		||||
#define DEFAULT_BUBT_DST "error"
 | 
			
		||||
#endif
 | 
			
		||||
#endif /* DEFAULT_BUBT_DST */
 | 
			
		||||
 | 
			
		||||
int do_bubt_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 | 
			
		||||
{
 | 
			
		||||
	struct bubt_dev *src, *dst;
 | 
			
		||||
	size_t image_size;
 | 
			
		||||
	char src_dev_name[8];
 | 
			
		||||
	char dst_dev_name[8];
 | 
			
		||||
	char *name;
 | 
			
		||||
	int  err;
 | 
			
		||||
 | 
			
		||||
	if (argc < 2)
 | 
			
		||||
		copy_filename(net_boot_file_name,
 | 
			
		||||
			      CONFIG_MVEBU_UBOOT_DFLT_NAME,
 | 
			
		||||
			      sizeof(net_boot_file_name));
 | 
			
		||||
	else
 | 
			
		||||
		copy_filename(net_boot_file_name, argv[1],
 | 
			
		||||
			      sizeof(net_boot_file_name));
 | 
			
		||||
 | 
			
		||||
	if (argc >= 3) {
 | 
			
		||||
		strncpy(dst_dev_name, argv[2], 8);
 | 
			
		||||
	} else {
 | 
			
		||||
		name = DEFAULT_BUBT_DST;
 | 
			
		||||
		strncpy(dst_dev_name, name, 8);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (argc >= 4)
 | 
			
		||||
		strncpy(src_dev_name, argv[3], 8);
 | 
			
		||||
	else
 | 
			
		||||
		strncpy(src_dev_name, DEFAULT_BUBT_SRC, 8);
 | 
			
		||||
 | 
			
		||||
	/* Figure out the destination device */
 | 
			
		||||
	dst = find_bubt_dev(dst_dev_name);
 | 
			
		||||
	if (!dst) {
 | 
			
		||||
		printf("Error: Unknown destination \"%s\"\n", dst_dev_name);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!bubt_is_dev_active(dst))
 | 
			
		||||
		return -ENODEV;
 | 
			
		||||
 | 
			
		||||
	/* Figure out the source device */
 | 
			
		||||
	src = find_bubt_dev(src_dev_name);
 | 
			
		||||
	if (!src) {
 | 
			
		||||
		printf("Error: Unknown source \"%s\"\n", src_dev_name);
 | 
			
		||||
		return 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!bubt_is_dev_active(src))
 | 
			
		||||
		return -ENODEV;
 | 
			
		||||
 | 
			
		||||
	printf("Burning U-BOOT image \"%s\" from \"%s\" to \"%s\"\n",
 | 
			
		||||
	       net_boot_file_name, src->name, dst->name);
 | 
			
		||||
 | 
			
		||||
	image_size = bubt_read_file(src);
 | 
			
		||||
	if (!image_size)
 | 
			
		||||
		return -EIO;
 | 
			
		||||
 | 
			
		||||
	err = bubt_verify(image_size);
 | 
			
		||||
	if (err)
 | 
			
		||||
		return err;
 | 
			
		||||
 | 
			
		||||
	err = bubt_write_file(dst, image_size);
 | 
			
		||||
	if (err)
 | 
			
		||||
		return err;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
U_BOOT_CMD(
 | 
			
		||||
	bubt, 4, 0, do_bubt_cmd,
 | 
			
		||||
	"Burn a u-boot image to flash",
 | 
			
		||||
	"[file-name] [destination [source]]\n"
 | 
			
		||||
	"\t-file-name     The image file name to burn. Default = flash-image.bin\n"
 | 
			
		||||
	"\t-destination   Flash to burn to [spi, nand, mmc]. Default = active boot device\n"
 | 
			
		||||
	"\t-source        The source to load image from [tftp, usb, mmc]. Default = tftp\n"
 | 
			
		||||
	"Examples:\n"
 | 
			
		||||
	"\tbubt - Burn flash-image.bin from tftp to active boot device\n"
 | 
			
		||||
	"\tbubt flash-image-new.bin nand - Burn flash-image-new.bin from tftp to NAND flash\n"
 | 
			
		||||
	"\tbubt backup-flash-image.bin mmc usb - Burn backup-flash-image.bin from usb to MMC\n"
 | 
			
		||||
 | 
			
		||||
);
 | 
			
		||||
| 
						 | 
				
			
			@ -27,6 +27,7 @@ CONFIG_CMD_EXT4=y
 | 
			
		|||
CONFIG_CMD_EXT4_WRITE=y
 | 
			
		||||
CONFIG_CMD_FAT=y
 | 
			
		||||
CONFIG_CMD_FS_GENERIC=y
 | 
			
		||||
CONFIG_CMD_MVEBU_BUBT=y
 | 
			
		||||
CONFIG_BLOCK_CACHE=y
 | 
			
		||||
CONFIG_DM_I2C=y
 | 
			
		||||
CONFIG_SYS_I2C_MVTWSI=y
 | 
			
		||||
| 
						 | 
				
			
			@ -36,6 +37,9 @@ CONFIG_SPI_FLASH_MACRONIX=y
 | 
			
		|||
CONFIG_SPI_FLASH_SPANSION=y
 | 
			
		||||
CONFIG_SPI_FLASH_STMICRO=y
 | 
			
		||||
CONFIG_PHYLIB=y
 | 
			
		||||
CONFIG_PCI=y
 | 
			
		||||
CONFIG_DM_PCI=y
 | 
			
		||||
CONFIG_PCIE_DW_MVEBU=y
 | 
			
		||||
CONFIG_MVEBU_COMPHY_SUPPORT=y
 | 
			
		||||
# CONFIG_SPL_SERIAL_PRESENT is not set
 | 
			
		||||
CONFIG_DEBUG_UART=y
 | 
			
		||||
| 
						 | 
				
			
			@ -50,3 +54,5 @@ CONFIG_USB_XHCI_HCD=y
 | 
			
		|||
CONFIG_USB_EHCI_HCD=y
 | 
			
		||||
CONFIG_USB_STORAGE=y
 | 
			
		||||
CONFIG_SMBIOS_MANUFACTURER=""
 | 
			
		||||
CONFIG_PINCTRL=y
 | 
			
		||||
CONFIG_HUSH_PARSER=y
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,7 @@ CONFIG_CMD_EXT4=y
 | 
			
		|||
CONFIG_CMD_EXT4_WRITE=y
 | 
			
		||||
CONFIG_CMD_FAT=y
 | 
			
		||||
CONFIG_CMD_FS_GENERIC=y
 | 
			
		||||
CONFIG_CMD_MVEBU_BUBT=y
 | 
			
		||||
CONFIG_BLOCK_CACHE=y
 | 
			
		||||
CONFIG_DM_I2C=y
 | 
			
		||||
CONFIG_SYS_I2C_MVTWSI=y
 | 
			
		||||
| 
						 | 
				
			
			@ -53,3 +54,5 @@ CONFIG_USB_XHCI_HCD=y
 | 
			
		|||
CONFIG_USB_EHCI_HCD=y
 | 
			
		||||
CONFIG_USB_STORAGE=y
 | 
			
		||||
CONFIG_SMBIOS_MANUFACTURER=""
 | 
			
		||||
CONFIG_PINCTRL=y
 | 
			
		||||
CONFIG_HUSH_PARSER=y
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,25 @@
 | 
			
		|||
	Functions of Armada APN806 pin controller
 | 
			
		||||
	Function 0x0 for any MPP ID activates GPIO pin mode
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
MPP#	0x1			0x2		0x3		0x4
 | 
			
		||||
----------------------------------------------------------------------
 | 
			
		||||
0	SDIO_CLK		-		SPI0_CLK 	-
 | 
			
		||||
1	SDIO_CMD		-		SPI0_MISO	-
 | 
			
		||||
2	SDIO_D[0]		-		SPI0_MOSI 	-
 | 
			
		||||
3	SDIO_D[1]		-		SPI0_CS0n 	-
 | 
			
		||||
4	SDIO_D[2]		-		I2C0_SDA	SPI0_CS1n
 | 
			
		||||
5	SDIO_D[3]		-		I2C0_SCK	-
 | 
			
		||||
6	SDIO_DS			-		-		-
 | 
			
		||||
7	SDIO_D[4]		-		UART1_RXD	-
 | 
			
		||||
8	SDIO_D[5]		-		UART1_TXD 	-
 | 
			
		||||
9	SDIO_D[6]		-		SPI0_CS1n 	-
 | 
			
		||||
10	SDIO_D[7]		-		-		-
 | 
			
		||||
11	-			-		UART0_TXD 	-
 | 
			
		||||
12	SDIO_CARD_PW_OFF 	SDIO_HW_RST 	-		-
 | 
			
		||||
13	-			-		-		-
 | 
			
		||||
14	-			-		-		-
 | 
			
		||||
15	-			-		-		-
 | 
			
		||||
16	-			-		-		-
 | 
			
		||||
17	-			-		-		-
 | 
			
		||||
18	-			-		-		-
 | 
			
		||||
19	-			-		UART0_RXD	-
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,270 @@
 | 
			
		|||
	Functions of Armada CP110 pin controller
 | 
			
		||||
	Function 0x0 for any MPP ID activates GPIO pin mode
 | 
			
		||||
	Function 0xc for any MPP ID activates DEBUG_BUS pin mode
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
MPP#	0x1			0x2		0x3		0x4
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
0	DEV_ALE[1]		AU_I2SMCLK	GE0_RXD[3]	TDM_PCLK
 | 
			
		||||
1	DEV_ALE[0]		AU_I2SDO_SPDIFO	GE0_RXD[2]	TDM_DRX
 | 
			
		||||
2	DEV_AD[15]		AU_I2SEXTCLK	GE0_RXD[1]	TDM_DTX
 | 
			
		||||
3	DEV_AD[14]		AU_I2SLRCLK	GE0_RXD[0]	TDM_FSYNC
 | 
			
		||||
4	DEV_AD[13]		AU_I2SBCLK	GE0_RXCTL	TDM_RSTn
 | 
			
		||||
5	DEV_AD[12]		AU_I2SDI	GE0_RXCLK	TDM_INTn
 | 
			
		||||
6	DEV_AD[11]		-		GE0_TXD[3]	SPI0_CSn[2]
 | 
			
		||||
7	DEV_AD[10]		-		GE0_TXD[2]	SPI0_CSn[1]
 | 
			
		||||
8	DEV_AD[9]		-		GE0_TXD[1]	SPI0_CSn[0]
 | 
			
		||||
9	DEV_AD[8]		-		GE0_TXD[0]	SPI0_MOSI
 | 
			
		||||
10	DEV_READYn		-		GE0_TXCTL	SPI0_MISO
 | 
			
		||||
11	DEV_WEn[1]		-		GE0_TXCLKOUT	SPI0_CLK
 | 
			
		||||
12	DEV_CLK_OUT		NF_RBn[1]	SPI1_CSn[1]	GE0_RXCLK
 | 
			
		||||
13	DEV_BURSTn		NF_RBn[0]	SPI1_MISO	GE0_RXCTL
 | 
			
		||||
14	DEV_BOOTCSn		DEV_CSn[0]	SPI1_CSn[0]	SPI0_CSn[3]
 | 
			
		||||
15	DEV_AD[7]		-		SPI1_MOSI	-
 | 
			
		||||
16	DEV_AD[6]		-		SPI1_CLK	-
 | 
			
		||||
17	DEV_AD[5]		-		-		GE0_TXD[3]
 | 
			
		||||
18	DEV_AD[4]		-		-		GE0_TXD[2]
 | 
			
		||||
19	DEV_AD[3]		-		-		GE0_TXD[1]
 | 
			
		||||
20	DEV_AD[2]		-		-		GE0_TXD[0]
 | 
			
		||||
21	DEV_AD[1]		-		-		GE0_TXCTL
 | 
			
		||||
22	DEV_AD[0]		-		-		GE0_TXCLKOUT
 | 
			
		||||
23	DEV_A[1]		-		-		-
 | 
			
		||||
24	DEV_A[0]		-		-		-
 | 
			
		||||
25	DEV_OEn	-		-		-		-
 | 
			
		||||
26	DEV_WEn[0]		-		-		-
 | 
			
		||||
27	DEV_CSn[0]		SPI1_MISO	MSS_GPIO[4]	GE0_RXD[3]
 | 
			
		||||
28	DEV_CSn[1]		SPI1_CSn[0]	MSS_GPIO[5]	GE0_RXD[2]
 | 
			
		||||
29	DEV_CSn[2]		SPI1_MOSI	MSS_GPIO[6]	GE0_RXD[1]
 | 
			
		||||
30	DEV_CSn[3]		SPI1_CLK	MSS_GPIO[7]	GE0_RXD[0]
 | 
			
		||||
31	DEV_A[2]		-		MSS_GPIO[4]	-
 | 
			
		||||
32	MII_COL			MII_TXERR	MSS_SPI_MISO	TDM_DRX
 | 
			
		||||
33	MII_TXCLK		SDIO_PWR1[0]	MSS_SPI_CSn	TDM_FSYNC
 | 
			
		||||
34	MII_RXERR		SDIO_PWR1[1]	MSS_SPI_MOSI	TDM_DTX
 | 
			
		||||
35	SATA1_PRESENT_ACTIVEn	TWSI1_SDA	MSS_SPI_CLK	TDM_PCLK
 | 
			
		||||
36	SYNCE2_CLK		TWSI1_SCK	PTP_CLK		SYNCE1_CLK
 | 
			
		||||
37	UART2_RXD		TWSI0_SCK	PTP_PCLK_OUT	TDM_INTn
 | 
			
		||||
38	UART2_TXD		TWSI0_SDA	PTP_PULSE	TDM_RSTn
 | 
			
		||||
39	SDIO_WR_PROTECT		-	-	AU_I2SBCLK	PTP_CLK
 | 
			
		||||
40	SDIO_PWR1[1]		SYNCE1_CLK	MSS_TWSI_SDA	AU_I2SDO_SPDIFO
 | 
			
		||||
41	SDIO_PWR1[0]		SDIO_BUS_PWR	MSS_TWSI_SCK	AU_I2SLRCLK
 | 
			
		||||
42	SDIO_V18_EN		SDIO_WR_PROTECT	SYNCE2_CLK	AU_I2SMCLK
 | 
			
		||||
43	SDIO_CARD_DETECT	-		SYNCE1_CLK	AU_I2SEXTCLK
 | 
			
		||||
44	GE1_TXD[2]		-		-		-
 | 
			
		||||
45	GE1_TXD[3]		-		-		-
 | 
			
		||||
46	GE1_TXD[1]		-		-		-
 | 
			
		||||
47	GE1_TXD[0]		-		-		-
 | 
			
		||||
48	GE1_TXCTL_MII_TXEN	-		-		-
 | 
			
		||||
49	GE1_TXCLKOUT		MII_CRS		-		-
 | 
			
		||||
50	GE1_RXCLK		MSS_TWSI_SDA	-		-
 | 
			
		||||
51	GE1_RXD[0]		MSS_TWSI_SCK	-		-
 | 
			
		||||
52	GE1_RXD[1]		SYNCE1_CLK	-		SYNCE2_CLK
 | 
			
		||||
53	GE1_RXD[2]		-		PTP_CLK		-
 | 
			
		||||
54	GE1_RXD[3]		SYNCE2_CLK	PTP_PCLK_OUT	SYNCE1_CLK
 | 
			
		||||
55	GE1_RXCTL_MII_RXDV	-		PTP_PULSE	-
 | 
			
		||||
56	-			-		-		TDM_DRX
 | 
			
		||||
57	-			MSS_TWSI_SDA	PTP_PCLK_OUT	TDM_INTn
 | 
			
		||||
58	-			MSS_TWSI_SCK	PTP_CLK		TDM_RSTn
 | 
			
		||||
59	MSS_GPIO[7]		SYNCE2_CLK	-		TDM_FSYNC
 | 
			
		||||
60	MSS_GPIO[6]		-		PTP_PULSE	TDM_DTX
 | 
			
		||||
61	MSS_GPIO[5]		-		PTP_CLK		TDM_PCLK
 | 
			
		||||
62	MSS_GPIO[4]		SYNCE1_CLK	PTP_PCLK_OUT	-
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
MPP#	0x5			0x6			0x7
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
0	-			PTP_PULSE		MSS_TWSI_SDA
 | 
			
		||||
1	-			PTP_CLK			MSS_TWSI_SCK
 | 
			
		||||
2	MSS_UART_RXD		PTP_PCLK_OUT		TWSI1_SCK
 | 
			
		||||
3	MSS_UART_TXD		PCIe_RSTOUTn		TWSI1_SDA
 | 
			
		||||
4	MSS_UART_RXD		UART1_CTS		PCIe0_CLKREQ
 | 
			
		||||
5	MSS_UART_TXD		UART1_RTS		PCIe1_CLKREQ
 | 
			
		||||
6	AU_I2SEXTCLK		SATA1_PRESENT_ACTIVEn	PCIe2_CLKREQ
 | 
			
		||||
7	SPI1_CSn[1]		SATA0_PRESENT_ACTIVEn	LED_DATA
 | 
			
		||||
8	SPI1_CSn[0]		UART0_CTS		LED_STB
 | 
			
		||||
9	SPI1_MOSI		-			PCIe_RSTOUTn
 | 
			
		||||
10	SPI1_MISO		UART0_CTS		SATA1_PRESENT_ACTIVEn
 | 
			
		||||
11	SPI1_CLK		UART0_RTS		LED_CLK
 | 
			
		||||
12	-			-			-
 | 
			
		||||
13	-			-			-
 | 
			
		||||
14	AU_I2SEXTCLK		SPI0_MISO		SATA0_PRESENT_ACTIVEn
 | 
			
		||||
15	-			SPI0_MOSI		-
 | 
			
		||||
16	-			-			-
 | 
			
		||||
17	-			-			-
 | 
			
		||||
18	-			-			-
 | 
			
		||||
19	-			-			-
 | 
			
		||||
20	-			-			-
 | 
			
		||||
21	-			-			-
 | 
			
		||||
22	-			-			-
 | 
			
		||||
23	AU_I2SMCLK		-			-
 | 
			
		||||
24	AU_I2SLRCLK		-			-
 | 
			
		||||
25	AU_I2SDO_SPDIFO		-			-
 | 
			
		||||
26	AU_I2SBCLK		-			-
 | 
			
		||||
27	SPI0_CSn[4]		-			-
 | 
			
		||||
28	SPI0_CSn[5]		PCIe2_CLKREQ		PTP_PULSE
 | 
			
		||||
29	SPI0_CSn[6]		PCIe1_CLKREQ		PTP_CLK
 | 
			
		||||
30	SPI0_CSn[7]		PCIe0_CLKREQ		PTP_PCLK_OUT
 | 
			
		||||
31	-			PCIe_RSTOUTn		-
 | 
			
		||||
32	AU_I2SEXTCLK		AU_I2SDI		GE_MDIO
 | 
			
		||||
33	AU_I2SMCLK		SDIO_BUS_PWR		-
 | 
			
		||||
34	AU_I2SLRCLK		SDIO_WR_PROTECT		GE_MDC
 | 
			
		||||
35	AU_I2SDO_SPDIFO		SDIO_CARD_DETECT	XG_MDIO
 | 
			
		||||
36	AU_I2SBCLK		SATA0_PRESENT_ACTIVEn	XG_MDC
 | 
			
		||||
37	MSS_TWSI_SCK		SATA1_PRESENT_ACTIVEn	GE_MDC
 | 
			
		||||
38	MSS_TWSI_SDA		SATA0_PRESENT_ACTIVEn	GE_MDIO
 | 
			
		||||
39	SPI0_CSn[1]		-			-
 | 
			
		||||
40	PTP_PCLK_OUT		SPI0_CLK		UART1_TXD
 | 
			
		||||
41	PTP_PULSE		SPI0_MOSI		UART1_RXD
 | 
			
		||||
42	MSS_UART_TXD		SPI0_MISO		UART1_CTS
 | 
			
		||||
43	MSS_UART_RXD		SPI0_CSn[0]		UART1_RTS
 | 
			
		||||
44	-			-			UART0_RTS
 | 
			
		||||
45	-			-			UART0_TXD
 | 
			
		||||
46	-			-			UART1_RTS
 | 
			
		||||
47	SPI1_CLK		-			UART1_TXD
 | 
			
		||||
48	SPI1_MOSI		-			-
 | 
			
		||||
49	SPI1_MISO		-			UART1_RXD
 | 
			
		||||
50	SPI1_CSn[0]		UART2_TXD		UART0_RXD
 | 
			
		||||
51	SPI1_CSn[1]		UART2_RXD		UART0_CTS
 | 
			
		||||
52	SPI1_CSn[2]		-			UART1_CTS
 | 
			
		||||
53	SPI1_CSn[3]		-			UART1_RXD
 | 
			
		||||
54	-			-			-
 | 
			
		||||
55	-			-			-
 | 
			
		||||
56	AU_I2SDO_SPDIFO		SPI0_CLK		UART1_RXD
 | 
			
		||||
57	AU_I2SBCLK		SPI0_MOSI		UART1_TXD
 | 
			
		||||
58	AU_I2SDI		SPI0_MISO		UART1_CTS
 | 
			
		||||
59	AU_I2SLRCLK		SPI0_CSn[0]		UART0_CTS
 | 
			
		||||
60	AU_I2SMCLK		SPI0_CSn[1]		UART0_RTS
 | 
			
		||||
61	AU_I2SEXTCLK		SPI0_CSn[2]		UART0_TXD
 | 
			
		||||
62	SATA1_PRESENT_ACTIVEn	SPI0_CSn[3]		UART0_RXD
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
MPP#	0x8			0x9			0xA
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
0	UART0_RXD		SATA0_PRESENT_ACTIVEn	GE_MDIO
 | 
			
		||||
1	UART0_TXD		SATA1_PRESENT_ACTIVEn	GE_MDC
 | 
			
		||||
2	UART1_RXD		SATA0_PRESENT_ACTIVEn	XG_MDC
 | 
			
		||||
3	UART1_TXD		SATA1_PRESENT_ACTIVEn	XG_MDIO
 | 
			
		||||
4	UART3_RXD		-			GE_MDC
 | 
			
		||||
5	UART3_TXD		-			GE_MDIO
 | 
			
		||||
6	UART0_RXD		PTP_PULSE		-
 | 
			
		||||
7	UART0_TXD		PTP_CLK			-
 | 
			
		||||
8	UART2_RXD		PTP_PCLK_OUT		SYNCE1_CLK
 | 
			
		||||
9	-			-			SYNCE2_CLK
 | 
			
		||||
10	-			-			-
 | 
			
		||||
11	UART2_TXD		SATA0_PRESENT_ACTIVEn	-
 | 
			
		||||
12	-			-			-
 | 
			
		||||
13	MSS_SPI_MISO		-			-
 | 
			
		||||
14	MSS_SPI_CSn		-			-
 | 
			
		||||
15	MSS_SPI_MOSI		-			-
 | 
			
		||||
16	MSS_SPI_CLK		-			-
 | 
			
		||||
17	-			-			-
 | 
			
		||||
18	-			-			-
 | 
			
		||||
19	-			-			-
 | 
			
		||||
20	-			-			-
 | 
			
		||||
21	-			-			-
 | 
			
		||||
22	-			-			-
 | 
			
		||||
23	-			-			-
 | 
			
		||||
24	-			-			-
 | 
			
		||||
25	-			-			-
 | 
			
		||||
26	-			-			-
 | 
			
		||||
27	GE_MDIO			SATA0_PRESENT_ACTIVEn	UART0_RTS
 | 
			
		||||
28	GE_MDC			SATA1_PRESENT_ACTIVEn	UART0_CTS
 | 
			
		||||
29	MSS_TWSI_SDA		SATA0_PRESENT_ACTIVEn	UART0_RXD
 | 
			
		||||
30	MSS_TWSI_SCK		SATA1_PRESENT_ACTIVEn	UART0_TXD
 | 
			
		||||
31	GE_MDC			-			-
 | 
			
		||||
32	SDIO_V18_EN		PCIe1_CLKREQ		MSS_GPIO[0]
 | 
			
		||||
33	XG_MDIO			PCIe2_CLKREQ		MSS_GPIO[1]
 | 
			
		||||
34	-			PCIe0_CLKREQ		MSS_GPIO[2]
 | 
			
		||||
35	GE_MDIO			PCIe_RSTOUTn		MSS_GPIO[3]
 | 
			
		||||
36	GE_MDC			PCIe2_CLKREQ		MSS_GPIO[5]
 | 
			
		||||
37	XG_MDC			PCIe1_CLKREQ		MSS_GPIO[6]
 | 
			
		||||
38	XG_MDIO			AU_I2SEXTCLK		MSS_GPIO[7]
 | 
			
		||||
39	SATA1_PRESENT_ACTIVEn				MSS_GPIO[0]
 | 
			
		||||
40	GE_MDIO			SATA0_PRESENT_ACTIVEn	MSS_GPIO[1]
 | 
			
		||||
41	GE_MDC			SATA1_PRESENT_ACTIVEn	MSS_GPIO[2]
 | 
			
		||||
42	XG_MDC			SATA0_PRESENT_ACTIVEn	MSS_GPIO[4]
 | 
			
		||||
43	XG_MDIO			SATA1_PRESENT_ACTIVEn	MSS_GPIO[5]
 | 
			
		||||
44	-			-			-
 | 
			
		||||
45	-			PCIe_RSTOUTn		-
 | 
			
		||||
46	-			-			-
 | 
			
		||||
47	GE_MDC			CLKOUT			-
 | 
			
		||||
48	XG_MDC			-			-
 | 
			
		||||
49	GE_MDIO			PCIe0_CLKREQ		SDIO_V18_EN
 | 
			
		||||
50	XG_MDIO			-			SDIO_PWR1[1]
 | 
			
		||||
51	-			-			SDIO_PWR1[0]
 | 
			
		||||
52	LED_CLK			PCIe_RSTOUTn		PCIe0_CLKREQ
 | 
			
		||||
53	LED_STB			-			-
 | 
			
		||||
54	LED_DATA		-			SDIO_HW_RST
 | 
			
		||||
55	-			-			SDIO_LED
 | 
			
		||||
56	-			SATA1_PRESENT_ACTIVEn	-
 | 
			
		||||
57	-			SATA0_PRESENT_ACTIVEn	-
 | 
			
		||||
58	LED_CLK			-			-
 | 
			
		||||
59	LED_STB			UART1_TXD		-
 | 
			
		||||
60	LED_DATA		UART1_RXD		-
 | 
			
		||||
61	UART2_TXD		SATA1_PRESENT_ACTIVEn	GE_MDIO
 | 
			
		||||
62	UART2_RXD		SATA0_PRESENT_ACTIVEn	GE_MDC
 | 
			
		||||
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
MPP#	0xB			0xD			0xE
 | 
			
		||||
-------------------------------------------------------------------------------
 | 
			
		||||
0	-			-			-
 | 
			
		||||
1	-			-			-
 | 
			
		||||
2	-			-			-
 | 
			
		||||
3	-			-			-
 | 
			
		||||
4	-			-			-
 | 
			
		||||
5	-			-			-
 | 
			
		||||
6	-			-			-
 | 
			
		||||
7	-			-			-
 | 
			
		||||
8	-			-			-
 | 
			
		||||
9	-			-			-
 | 
			
		||||
10	-			-			-
 | 
			
		||||
11	-			CLKOUT_MPP_11		-
 | 
			
		||||
12	-			-			-
 | 
			
		||||
13	-			-			-
 | 
			
		||||
14	-			-			-
 | 
			
		||||
15	PTP_PULSE_CP2CP		SAR_IN[5]		-
 | 
			
		||||
16	-			SAR_IN[3]		-
 | 
			
		||||
17	-			SAR_IN[6]		-
 | 
			
		||||
18	PTP_CLK_CP2CP		SAR_IN[11]		-
 | 
			
		||||
19	WAKEUP_OUT_CP2CP	SAR_IN[7]		-
 | 
			
		||||
20	-			SAR_IN[9]		-
 | 
			
		||||
21	SEI_IN_CP2CP		SAR_IN[8]		-
 | 
			
		||||
22	WAKEUP_IN_CP2CP		SAR_IN[10]		-
 | 
			
		||||
23	LINK_RD_IN_CP2CP	SAR_IN[4]		-
 | 
			
		||||
24	-			-			-
 | 
			
		||||
25	-			CLKOUT_MPP_25		-
 | 
			
		||||
26	-			SAR_IN[0]		-
 | 
			
		||||
27	REI_IN_CP2CP		SAR_IN[1]		-
 | 
			
		||||
28	LED_DATA		SAR_IN[2]		-
 | 
			
		||||
29	LED_STB			AVS_FB_IN_CP2CP		-
 | 
			
		||||
30	LED_CLK			SAR_IN[13]		-
 | 
			
		||||
31	-			-			-
 | 
			
		||||
32	-			SAR_CP2CP_OUT[0]	-
 | 
			
		||||
33	-			SAR_CP2CP_OUT[1]	-
 | 
			
		||||
34	-			SAR_CP2CP_OUT[2]	-
 | 
			
		||||
35	-			SAR_CP2CP_OUT[3]	-
 | 
			
		||||
36	-			CLKIN			-
 | 
			
		||||
37	LINK_RD_OUT_CP2CP	SAR_CP2CP_OUT[4]	-
 | 
			
		||||
38	PTP_PULSE_CP2CP		SAR_CP2CP_OUT[5]	-
 | 
			
		||||
39	-			AVS_FB_OUT_CP2CP	-
 | 
			
		||||
40	-			-			-
 | 
			
		||||
41	REI_OUT_CP2CP		-			-
 | 
			
		||||
42	-			SAR_CP2CP_OUT[9]	-
 | 
			
		||||
43	WAKEUP_OUT_CP2CP	SAR_CP2CP_OUT[10]	-
 | 
			
		||||
44	PTP_CLK_CP2CP		SAR_CP2CP_OUT[11]	-
 | 
			
		||||
45	-			SAR_CP2CP_OUT[6]	-
 | 
			
		||||
46	-			SAR_CP2CP_OUT[13]	-
 | 
			
		||||
47	-			-			-
 | 
			
		||||
48	WAKEUP_IN_CP2CP		SAR_CP2CP_OUT[7]	-
 | 
			
		||||
49	SEI_OUT_CP2CP		SAR_CP2CP_OUT[8]	-
 | 
			
		||||
50	-			-			-
 | 
			
		||||
51	-			-			-
 | 
			
		||||
52	-			-			-
 | 
			
		||||
53	SDIO_LED		-			-
 | 
			
		||||
54	SDIO_WR_PROTECT		-			-
 | 
			
		||||
55	SDIO_CARD_DETECT	-			-
 | 
			
		||||
56	-			-			SDIO0_CLK
 | 
			
		||||
57	-			-			SDIO0_CMD
 | 
			
		||||
58	-			-			SDIO0_D[0]
 | 
			
		||||
59	-			-			SDIO0_D[1]
 | 
			
		||||
60	-			-			SDIO0_D[2]
 | 
			
		||||
61	-			-			SDIO0_D[3]
 | 
			
		||||
62	-			-			-
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,113 @@
 | 
			
		|||
The pinctrl driver enables Marvell Armada 8K SoCs to configure the multi-purpose
 | 
			
		||||
pins (mpp) to a specific function.
 | 
			
		||||
A Marvell SoC pin configuration node is a node of a group of pins which can
 | 
			
		||||
be used for a specific device or function. Each node requires one or more
 | 
			
		||||
mpp pins or group of pins and a mpp function common to all pins.
 | 
			
		||||
 | 
			
		||||
Required properties for the pinctrl driver:
 | 
			
		||||
- compatible:	"marvell,mvebu-pinctrl",
 | 
			
		||||
		"marvell,armada-ap806-pinctrl",
 | 
			
		||||
		"marvell,a70x0-pinctrl",
 | 
			
		||||
		"marvell,a80x0-cp0-pinctrl",
 | 
			
		||||
		"marvell,a80x0-cp1-pinctrl"
 | 
			
		||||
- bank-name:	A string defining the pinc controller bank name
 | 
			
		||||
- reg: 		A pair of values defining the pin controller base address
 | 
			
		||||
		and the address space
 | 
			
		||||
- pin-count:	Numeric value defining the amount of multi purpose pins
 | 
			
		||||
		included in this bank
 | 
			
		||||
- max-func:	Numeric value defining the maximum function value for
 | 
			
		||||
		pins in this bank
 | 
			
		||||
- pin-func:	Array of pin function values for every pin in the bank.
 | 
			
		||||
		When the function value for a specific pin equal 0xFF,
 | 
			
		||||
		the pin configuration is skipped and a default function
 | 
			
		||||
		value is used for this pin.
 | 
			
		||||
 | 
			
		||||
The A8K is a hybrid SoC that contains several silicon dies interconnected in
 | 
			
		||||
a single package. Each such die may have a separate pin controller.
 | 
			
		||||
 | 
			
		||||
Example:
 | 
			
		||||
/ {
 | 
			
		||||
	ap806 {
 | 
			
		||||
		config-space {
 | 
			
		||||
			pinctl: pinctl@6F4000 {
 | 
			
		||||
				compatible = "marvell,mvebu-pinctrl",
 | 
			
		||||
					     "marvell,armada-ap806-pinctrl";
 | 
			
		||||
				bank-name ="apn-806";
 | 
			
		||||
				reg = <0x6F4000 0x10>;
 | 
			
		||||
				pin-count = <20>;
 | 
			
		||||
				max-func = <3>;
 | 
			
		||||
				/* MPP Bus:
 | 
			
		||||
				 * SPI0 [0-3]
 | 
			
		||||
				 * I2C0 [4-5]
 | 
			
		||||
				 * UART0 [11,19]
 | 
			
		||||
				 */
 | 
			
		||||
					  /* 0 1 2 3 4 5 6 7 8 9 */
 | 
			
		||||
				pin-func = < 3 3 3 3 3 3 0 0 0 0
 | 
			
		||||
					     0 3 0 0 0 0 0 0 0 3>;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	cp110-master {
 | 
			
		||||
		config-space {
 | 
			
		||||
			cpm_pinctl: pinctl@44000 {
 | 
			
		||||
				compatible = "marvell,mvebu-pinctrl",
 | 
			
		||||
					     "marvell,a70x0-pinctrl",
 | 
			
		||||
					     "marvell,a80x0-cp0-pinctrl";
 | 
			
		||||
				bank-name ="cp0-110";
 | 
			
		||||
				reg = <0x440000 0x20>;
 | 
			
		||||
				pin-count = <63>;
 | 
			
		||||
				max-func = <0xf>;
 | 
			
		||||
				/* MPP Bus:
 | 
			
		||||
				 * [0-31] = 0xff: Keep default CP0_shared_pins:
 | 
			
		||||
				 * [11] CLKOUT_MPP_11 (out)
 | 
			
		||||
				 * [23] LINK_RD_IN_CP2CP (in)
 | 
			
		||||
				 * [25] CLKOUT_MPP_25 (out)
 | 
			
		||||
				 * [29] AVS_FB_IN_CP2CP (in)
 | 
			
		||||
				 * [32,34] SMI
 | 
			
		||||
				 * [31]    GPIO: push button/Wake
 | 
			
		||||
				 * [35-36] GPIO
 | 
			
		||||
				 * [37-38] I2C
 | 
			
		||||
				 * [40-41] SATA[0/1]_PRESENT_ACTIVEn
 | 
			
		||||
				 * [42-43] XSMI
 | 
			
		||||
				 * [44-55] RGMII1
 | 
			
		||||
				 * [56-62] SD
 | 
			
		||||
				 */
 | 
			
		||||
					/*   0    1    2    3    4    5    6    7    8    9 */
 | 
			
		||||
				pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 | 
			
		||||
					     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 | 
			
		||||
					     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 | 
			
		||||
					     0xff 0    7    0    7    0    0    2    2    0
 | 
			
		||||
					     0    0    8    8    1    1    1    1    1    1
 | 
			
		||||
					     1    1    1    1    1    1    0xE  0xE  0xE  0xE
 | 
			
		||||
					     0xE  0xE  0xE>;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	cp110-slave {
 | 
			
		||||
		config-space {
 | 
			
		||||
			cps_pinctl: pinctl@44000 {
 | 
			
		||||
				compatible = "marvell,mvebu-pinctrl",
 | 
			
		||||
					     "marvell,a80x0-cp1-pinctrl";
 | 
			
		||||
				bank-name ="cp1-110";
 | 
			
		||||
				reg = <0x440000 0x20>;
 | 
			
		||||
				pin-count = <63>;
 | 
			
		||||
				max-func = <0xf>;
 | 
			
		||||
				/* MPP Bus:
 | 
			
		||||
				 * [0-11]  RGMII0
 | 
			
		||||
				 * [27,31] GE_MDIO/MDC
 | 
			
		||||
				 * [32-62] = 0xff: Keep default CP1_shared_pins:
 | 
			
		||||
				 */
 | 
			
		||||
					/*   0    1    2    3    4    5    6    7    8    9 */
 | 
			
		||||
				pin-func = < 0x3  0x3  0x3  0x3  0x3  0x3  0x3  0x3  0x3  0x3
 | 
			
		||||
					     0x3  0x3  0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 | 
			
		||||
					     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x8  0xff 0xff
 | 
			
		||||
					     0xff 0x8  0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 | 
			
		||||
					     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 | 
			
		||||
					     0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 | 
			
		||||
					     0xff 0xff 0xff>;
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
	};
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,64 @@
 | 
			
		|||
BUBT (Burn ATF) command
 | 
			
		||||
--------------------------
 | 
			
		||||
Bubt command is used to burn a new ATF image to flash device.
 | 
			
		||||
 | 
			
		||||
The bubt command gets the following parameters: ATF file name, destination device and source device.
 | 
			
		||||
bubt [file-name] [destination [source]]
 | 
			
		||||
	- file-name		Image file name to burn. default = flash-image.bin
 | 
			
		||||
	- destination		Flash to burn to [spi, nand, mmc]. default = active flash
 | 
			
		||||
	- source		Source to load image from [tftp, usb]. default = tftp
 | 
			
		||||
 | 
			
		||||
Examples:
 | 
			
		||||
	bubt				- Burn flash-image.bin from tftp to active flash
 | 
			
		||||
	bubt latest-spi.bin nand	- Burn latest-spi.bin from tftp to NAND flash
 | 
			
		||||
 | 
			
		||||
Notes:
 | 
			
		||||
- For the TFTP interface set serverip and ipaddr.
 | 
			
		||||
- To burn image to SD/eMMC device, the target is defined
 | 
			
		||||
  by parameters CONFIG_SYS_MMC_ENV_DEV and CONFIG_SYS_MMC_ENV_PART.
 | 
			
		||||
 | 
			
		||||
Bubt command details (burn image step by-step)
 | 
			
		||||
----------------------------------------------
 | 
			
		||||
This section describes bubt command flow:
 | 
			
		||||
 | 
			
		||||
1. Fetch the requested ATF image from an available interface (USB/SD/SATA/XDB, etc.)
 | 
			
		||||
   into the DRAM, and place it at <load_address>
 | 
			
		||||
   Example: when using the FAT file system on USB flash device:
 | 
			
		||||
   # usb reset
 | 
			
		||||
   # fatls usb 0 (see files in device)
 | 
			
		||||
   # fatload usb 0 <load_address> <file_name>
 | 
			
		||||
 | 
			
		||||
2. Erase the target device:
 | 
			
		||||
	- NAND:		# nand erase 0 100000
 | 
			
		||||
	- SPI:		# sf probe 0
 | 
			
		||||
			# sf erase 0 100000
 | 
			
		||||
	- SD/eMMC:	# mmc dev <dev_id> <boot_partition>
 | 
			
		||||
 | 
			
		||||
Notes:
 | 
			
		||||
- The eMMC has 2 boot partitions (BOOT0 and BOOT1) and a user data partition (DATA).
 | 
			
		||||
  The boot partitions are numbered as partition 1 and 2 in MMC driver.
 | 
			
		||||
  Number 0 is used for user data partition and should not be utilized for storing
 | 
			
		||||
  boot images and U-Boot environment in RAW mode since it will break file system
 | 
			
		||||
  structures usually located here.
 | 
			
		||||
  The default boot partition is BOOT0. It is selected by the following parameter:
 | 
			
		||||
  CONFIG_SYS_MMC_ENV_PART=1
 | 
			
		||||
  Valid values for this parameter are 1 for BOOT0 and 2 for BOOT1.
 | 
			
		||||
  Please never use partition number 0 here!
 | 
			
		||||
  The eMMC has 2 boot partitions (BOOT0 and BOOT1) and a user data partition (DATA).
 | 
			
		||||
  The boot partitions are numbered as partition 1 and 2 in MMC driver.
 | 
			
		||||
  Number 0 is used for user data partition and should not be utilized for storing
 | 
			
		||||
  boot images and U-Boot environment in RAW mode since it will break file system
 | 
			
		||||
  structures usually located here.
 | 
			
		||||
  The default boot partition is BOOT0. It is selected by the following parameter:
 | 
			
		||||
  CONFIG_SYS_MMC_ENV_PART=1
 | 
			
		||||
  Valid values for this parameter are 1 for BOOT0 and 2 for BOOT1.
 | 
			
		||||
  Please never use partition number 0 here!
 | 
			
		||||
- The partition number is ignored if the target device is SD card.
 | 
			
		||||
- The boot image offset starts at block 0 for eMMC and block 1 for SD devices.
 | 
			
		||||
  The block 0 on SD devices is left for MBR storage.
 | 
			
		||||
 | 
			
		||||
3. Write the ATF image:
 | 
			
		||||
	- NAND:		# nand write <load_address> 0 <ATF Size>
 | 
			
		||||
	- SPI:		# sf write <load_address> 0 <ATF Size>
 | 
			
		||||
	- SD/eMMC:	# mmc write <load_address> [0|1] <ATF Size>/<block_size>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -181,5 +181,6 @@ source "drivers/pinctrl/meson/Kconfig"
 | 
			
		|||
source "drivers/pinctrl/nxp/Kconfig"
 | 
			
		||||
source "drivers/pinctrl/uniphier/Kconfig"
 | 
			
		||||
source "drivers/pinctrl/exynos/Kconfig"
 | 
			
		||||
source "drivers/pinctrl/mvebu/Kconfig"
 | 
			
		||||
 | 
			
		||||
endmenu
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,3 +15,4 @@ obj-$(CONFIG_PINCTRL_UNIPHIER)	+= uniphier/
 | 
			
		|||
obj-$(CONFIG_PIC32_PINCTRL)	+= pinctrl_pic32.o
 | 
			
		||||
obj-$(CONFIG_PINCTRL_EXYNOS)	+= exynos/
 | 
			
		||||
obj-$(CONFIG_PINCTRL_MESON)	+= meson/
 | 
			
		||||
obj-$(CONFIG_PINCTRL_MVEBU)	+= mvebu/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
config PINCTRL_MVEBU
 | 
			
		||||
	depends on ARCH_MVEBU
 | 
			
		||||
	bool
 | 
			
		||||
	default y
 | 
			
		||||
	help
 | 
			
		||||
	   Support pin multiplexing and pin configuration control on
 | 
			
		||||
	   Marvell's Armada-8K SoC.
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,7 @@
 | 
			
		|||
#
 | 
			
		||||
# Copyright (C) 2016 Marvell International Ltd.
 | 
			
		||||
#
 | 
			
		||||
# SPDX-License-Identifier:	GPL-2.0
 | 
			
		||||
# https://spdx.org/licenses
 | 
			
		||||
 | 
			
		||||
obj-$(CONFIG_PINCTRL_MVEBU)	+= pinctrl-mvebu.o
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,179 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2016 Marvell International Ltd.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier:	GPL-2.0
 | 
			
		||||
 * https://spdx.org/licenses
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <common.h>
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <fdtdec.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <dm.h>
 | 
			
		||||
#include <dm/pinctrl.h>
 | 
			
		||||
#include <dm/root.h>
 | 
			
		||||
#include <asm/system.h>
 | 
			
		||||
#include <asm/io.h>
 | 
			
		||||
#include <asm/arch-armada8k/soc-info.h>
 | 
			
		||||
#include "pinctrl-mvebu.h"
 | 
			
		||||
 | 
			
		||||
DECLARE_GLOBAL_DATA_PTR;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * mvebu_pinctrl_set_state: configure pin functions.
 | 
			
		||||
 * @dev: the pinctrl device to be configured.
 | 
			
		||||
 * @config: the state to be configured.
 | 
			
		||||
 * @return: 0 in success
 | 
			
		||||
 */
 | 
			
		||||
int mvebu_pinctrl_set_state(struct udevice *dev, struct udevice *config)
 | 
			
		||||
{
 | 
			
		||||
	const void *blob = gd->fdt_blob;
 | 
			
		||||
	int node = config->of_offset;
 | 
			
		||||
	struct mvebu_pinctrl_priv *priv;
 | 
			
		||||
	u32 pin_arr[MVEBU_MAX_PINS_PER_BANK];
 | 
			
		||||
	u32 function;
 | 
			
		||||
	int i, pin_count;
 | 
			
		||||
 | 
			
		||||
	priv = dev_get_priv(dev);
 | 
			
		||||
 | 
			
		||||
	pin_count = fdtdec_get_int_array_count(blob, node,
 | 
			
		||||
					       "marvell,pins",
 | 
			
		||||
					       pin_arr,
 | 
			
		||||
					       MVEBU_MAX_PINS_PER_BANK);
 | 
			
		||||
	if (pin_count <= 0) {
 | 
			
		||||
		debug("Failed reading pins array for pinconfig %s (%d)\n",
 | 
			
		||||
		      config->name, pin_count);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	function = fdtdec_get_int(blob, node, "marvell,function", 0xff);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < pin_count; i++) {
 | 
			
		||||
	int reg_offset;
 | 
			
		||||
	int field_offset;
 | 
			
		||||
		int pin = pin_arr[i];
 | 
			
		||||
 | 
			
		||||
		if (function > priv->max_func) {
 | 
			
		||||
			debug("Illegal function %d for pinconfig %s\n",
 | 
			
		||||
			      function, config->name);
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Calculate register address and bit in register */
 | 
			
		||||
		reg_offset   = priv->reg_direction * 4 *
 | 
			
		||||
					(pin >> (PIN_REG_SHIFT));
 | 
			
		||||
		field_offset = (BITS_PER_PIN) * (pin & PIN_FIELD_MASK);
 | 
			
		||||
 | 
			
		||||
		clrsetbits_le32(priv->base_reg + reg_offset,
 | 
			
		||||
				PIN_FUNC_MASK << field_offset,
 | 
			
		||||
				(function & PIN_FUNC_MASK) << field_offset);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * mvebu_pinctrl_set_state_all: configure the entire bank pin functions.
 | 
			
		||||
 * @dev: the pinctrl device to be configured.
 | 
			
		||||
 * @config: the state to be configured.
 | 
			
		||||
 * @return: 0 in success
 | 
			
		||||
 */
 | 
			
		||||
static int mvebu_pinctrl_set_state_all(struct udevice *dev,
 | 
			
		||||
				       struct udevice *config)
 | 
			
		||||
{
 | 
			
		||||
	const void *blob = gd->fdt_blob;
 | 
			
		||||
	int node = config->of_offset;
 | 
			
		||||
	struct mvebu_pinctrl_priv *priv;
 | 
			
		||||
	u32 func_arr[MVEBU_MAX_PINS_PER_BANK];
 | 
			
		||||
	int pin, err;
 | 
			
		||||
 | 
			
		||||
	priv = dev_get_priv(dev);
 | 
			
		||||
 | 
			
		||||
	err = fdtdec_get_int_array(blob, node, "pin-func",
 | 
			
		||||
				   func_arr, priv->pin_cnt);
 | 
			
		||||
	if (err) {
 | 
			
		||||
		debug("Failed reading pin functions for bank %s\n",
 | 
			
		||||
		      priv->bank_name);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (pin = 0; pin < priv->pin_cnt; pin++) {
 | 
			
		||||
		int reg_offset;
 | 
			
		||||
		int field_offset;
 | 
			
		||||
		u32 func = func_arr[pin];
 | 
			
		||||
 | 
			
		||||
		/* Bypass pins with function 0xFF */
 | 
			
		||||
		if (func == 0xff) {
 | 
			
		||||
			debug("Warning: pin %d value is not modified ", pin);
 | 
			
		||||
			debug("(kept as default)\n");
 | 
			
		||||
			continue;
 | 
			
		||||
		} else if (func > priv->max_func) {
 | 
			
		||||
			debug("Illegal function %d for pin %d\n", func, pin);
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Calculate register address and bit in register */
 | 
			
		||||
		reg_offset   = priv->reg_direction * 4 *
 | 
			
		||||
					(pin >> (PIN_REG_SHIFT));
 | 
			
		||||
		field_offset = (BITS_PER_PIN) * (pin & PIN_FIELD_MASK);
 | 
			
		||||
 | 
			
		||||
		clrsetbits_le32(priv->base_reg + reg_offset,
 | 
			
		||||
				PIN_FUNC_MASK << field_offset,
 | 
			
		||||
				(func & PIN_FUNC_MASK) << field_offset);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int mvebu_pinctl_probe(struct udevice *dev)
 | 
			
		||||
{
 | 
			
		||||
	const void *blob = gd->fdt_blob;
 | 
			
		||||
	int node = dev->of_offset;
 | 
			
		||||
	struct mvebu_pinctrl_priv *priv;
 | 
			
		||||
 | 
			
		||||
	priv = dev_get_priv(dev);
 | 
			
		||||
	if (!priv) {
 | 
			
		||||
		debug("%s: Failed to get private\n", __func__);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	priv->base_reg = dev_get_addr_ptr(dev);
 | 
			
		||||
	if (priv->base_reg == (void *)FDT_ADDR_T_NONE) {
 | 
			
		||||
		debug("%s: Failed to get base address\n", __func__);
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	priv->pin_cnt   = fdtdec_get_int(blob, node, "pin-count",
 | 
			
		||||
					MVEBU_MAX_PINS_PER_BANK);
 | 
			
		||||
	priv->max_func  = fdtdec_get_int(blob, node, "max-func",
 | 
			
		||||
					 MVEBU_MAX_FUNC);
 | 
			
		||||
	priv->bank_name = fdt_getprop(blob, node, "bank-name", NULL);
 | 
			
		||||
 | 
			
		||||
	priv->reg_direction = 1;
 | 
			
		||||
	if (fdtdec_get_bool(blob, node, "reverse-reg"))
 | 
			
		||||
		priv->reg_direction = -1;
 | 
			
		||||
 | 
			
		||||
	return mvebu_pinctrl_set_state_all(dev, dev);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct pinctrl_ops mvebu_pinctrl_ops = {
 | 
			
		||||
	.set_state	= mvebu_pinctrl_set_state
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct udevice_id mvebu_pinctrl_ids[] = {
 | 
			
		||||
	{ .compatible = "marvell,mvebu-pinctrl" },
 | 
			
		||||
	{ .compatible = "marvell,armada-ap806-pinctrl" },
 | 
			
		||||
	{ .compatible = "marvell,a70x0-pinctrl" },
 | 
			
		||||
	{ .compatible = "marvell,a80x0-cp0-pinctrl" },
 | 
			
		||||
	{ .compatible = "marvell,a80x0-cp1-pinctrl" },
 | 
			
		||||
	{ }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
U_BOOT_DRIVER(pinctrl_mvebu) = {
 | 
			
		||||
	.name		= "mvebu_pinctrl",
 | 
			
		||||
	.id		= UCLASS_PINCTRL,
 | 
			
		||||
	.of_match	= mvebu_pinctrl_ids,
 | 
			
		||||
	.priv_auto_alloc_size = sizeof(struct mvebu_pinctrl_priv),
 | 
			
		||||
	.ops		= &mvebu_pinctrl_ops,
 | 
			
		||||
	.probe		= mvebu_pinctl_probe
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,31 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright (C) 2016 Marvell International Ltd.
 | 
			
		||||
 *
 | 
			
		||||
 * SPDX-License-Identifier:	GPL-2.0
 | 
			
		||||
 * https://spdx.org/licenses
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 #ifndef __PINCTRL_MVEBU_H_
 | 
			
		||||
 #define __PINCTRL_MVEBU_H_
 | 
			
		||||
 | 
			
		||||
 #define MVEBU_MAX_PINCTL_BANKS		4
 | 
			
		||||
 #define MVEBU_MAX_PINS_PER_BANK	100
 | 
			
		||||
 #define MVEBU_MAX_FUNC			0xF
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * struct mvebu_pin_bank_data: mvebu-pinctrl bank data
 | 
			
		||||
 * @base_reg: controller base address for this bank
 | 
			
		||||
 * @pin_cnt:  number of pins included in this bank
 | 
			
		||||
 * @max_func: maximum configurable function value for pins in this bank
 | 
			
		||||
 * @reg_direction:
 | 
			
		||||
 * @bank_name: the pin's bank name
 | 
			
		||||
 */
 | 
			
		||||
struct mvebu_pinctrl_priv {
 | 
			
		||||
	void		*base_reg;
 | 
			
		||||
	uint		pin_cnt;
 | 
			
		||||
	uint		max_func;
 | 
			
		||||
	int		reg_direction;
 | 
			
		||||
	const char	*bank_name;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif /* __PINCTRL_MVEBU_H_ */
 | 
			
		||||
		Loading…
	
		Reference in New Issue