Merge git://git.denx.de/u-boot-uniphier

master
Tom Rini 7 years ago
commit 74a4818415
  1. 10
      arch/arm/dts/uniphier-ld11-ref.dts
  2. 50
      arch/arm/dts/uniphier-ld11.dtsi
  3. 10
      arch/arm/dts/uniphier-ld20-ref.dts
  4. 87
      arch/arm/dts/uniphier-ld20.dtsi
  5. 10
      arch/arm/dts/uniphier-ld4-ref.dts
  6. 23
      arch/arm/dts/uniphier-ld4.dtsi
  7. 10
      arch/arm/dts/uniphier-ld6b-ref.dts
  8. 52
      arch/arm/dts/uniphier-pinctrl.dtsi
  9. 10
      arch/arm/dts/uniphier-pro4-ref.dts
  10. 22
      arch/arm/dts/uniphier-pro4.dtsi
  11. 16
      arch/arm/dts/uniphier-pro5.dtsi
  12. 66
      arch/arm/dts/uniphier-pxs2.dtsi
  13. 10
      arch/arm/dts/uniphier-pxs3-ref.dts
  14. 42
      arch/arm/dts/uniphier-pxs3.dtsi
  15. 10
      arch/arm/dts/uniphier-sld8-ref.dts
  16. 23
      arch/arm/dts/uniphier-sld8.dtsi
  17. 3
      arch/arm/dts/uniphier-support-card.dtsi
  18. 8
      arch/arm/dts/uniphier-v7-u-boot.dtsi
  19. 3
      arch/arm/include/asm/arch-sunxi/dram_sunxi_dw.h
  20. 4
      arch/arm/mach-kirkwood/include/mach/gpio.h
  21. 51
      arch/arm/mach-uniphier/board_init.c
  22. 2
      arch/arm/mach-uniphier/sbc/sbc-ld11.c
  23. 2
      arch/arm/mach-uniphier/sbc/sbc-pxs2.c
  24. 2
      configs/openrd_base_defconfig
  25. 2
      configs/openrd_client_defconfig
  26. 2
      configs/openrd_ultimate_defconfig
  27. 1
      configs/uniphier_ld4_sld8_defconfig
  28. 1
      configs/uniphier_v7_defconfig
  29. 1
      configs/uniphier_v8_defconfig
  30. 3
      drivers/gpio/gpio-uniphier.c
  31. 2
      drivers/gpio/kw_gpio.c
  32. 360
      drivers/mtd/mtdcore.c
  33. 11
      drivers/mtd/nand/Kconfig
  34. 10
      drivers/mtd/nand/davinci_nand.c
  35. 2027
      drivers/mtd/nand/denali.c
  36. 473
      drivers/mtd/nand/denali.h
  37. 17
      drivers/mtd/nand/denali_dt.c
  38. 14
      drivers/mtd/nand/denali_spl.c
  39. 530
      drivers/mtd/nand/nand_base.c
  40. 494
      drivers/mtd/nand/nand_timings.c
  41. 5
      include/configs/uniphier.h
  42. 18
      include/dt-bindings/gpio/uniphier-gpio.h
  43. 7
      include/linux/bitops.h
  44. 57
      include/linux/mtd/mtd.h
  45. 314
      include/linux/mtd/nand.h
  46. 4
      include/usb/lin_gadget_compat.h

@ -40,13 +40,21 @@
};
&ethsc {
interrupts = <0 48 4>;
interrupts = <0 8>;
};
&serial0 {
status = "okay";
};
&gpio {
xirq0 {
gpio-hog;
gpios = <UNIPHIER_GPIO_IRQ(0) 0>;
input;
};
};
&i2c0 {
status = "okay";
};

@ -7,6 +7,9 @@
* SPDX-License-Identifier: (GPL-2.0+ OR MIT)
*/
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/gpio/uniphier-gpio.h>
/memreserve/ 0x80000000 0x02000000;
/ {
@ -49,7 +52,7 @@
};
};
cluster0_opp: opp_table {
cluster0_opp: opp-table {
compatible = "operating-points-v2";
opp-shared;
@ -96,6 +99,11 @@
};
};
emmc_pwrseq: emmc-pwrseq {
compatible = "mmc-pwrseq-emmc";
reset-gpios = <&gpio UNIPHIER_GPIO_PORT(3, 2) GPIO_ACTIVE_LOW>;
};
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 4>,
@ -119,6 +127,7 @@
pinctrl-0 = <&pinctrl_uart0>;
clocks = <&peri_clk 0>;
clock-frequency = <58820000>;
resets = <&peri_rst 0>;
};
serial1: serial@54006900 {
@ -130,6 +139,7 @@
pinctrl-0 = <&pinctrl_uart1>;
clocks = <&peri_clk 1>;
clock-frequency = <58820000>;
resets = <&peri_rst 1>;
};
serial2: serial@54006a00 {
@ -141,6 +151,7 @@
pinctrl-0 = <&pinctrl_uart2>;
clocks = <&peri_clk 2>;
clock-frequency = <58820000>;
resets = <&peri_rst 2>;
};
serial3: serial@54006b00 {
@ -152,6 +163,7 @@
pinctrl-0 = <&pinctrl_uart3>;
clocks = <&peri_clk 3>;
clock-frequency = <58820000>;
resets = <&peri_rst 3>;
};
gpio: gpio@55000000 {
@ -200,6 +212,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0>;
clocks = <&peri_clk 4>;
resets = <&peri_rst 4>;
clock-frequency = <100000>;
};
@ -213,6 +226,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
clocks = <&peri_clk 5>;
resets = <&peri_rst 5>;
clock-frequency = <100000>;
};
@ -223,6 +237,7 @@
#size-cells = <0>;
interrupts = <0 43 4>;
clocks = <&peri_clk 6>;
resets = <&peri_rst 6>;
clock-frequency = <400000>;
};
@ -236,6 +251,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3>;
clocks = <&peri_clk 7>;
resets = <&peri_rst 7>;
clock-frequency = <100000>;
};
@ -249,6 +265,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c4>;
clocks = <&peri_clk 8>;
resets = <&peri_rst 8>;
clock-frequency = <100000>;
};
@ -259,6 +276,7 @@
#size-cells = <0>;
interrupts = <0 25 4>;
clocks = <&peri_clk 9>;
resets = <&peri_rst 9>;
clock-frequency = <400000>;
};
@ -311,9 +329,11 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_emmc_1v8>;
clocks = <&sys_clk 4>;
resets = <&sys_rst 4>;
bus-width = <8>;
mmc-ddr-1_8v;
mmc-hs200-1_8v;
mmc-pwrseq = <&emmc_pwrseq>;
cdns,phy-input-delay-legacy = <4>;
cdns,phy-input-delay-mmc-highspeed = <2>;
cdns,phy-input-delay-mmc-ddr = <3>;
@ -328,7 +348,8 @@
interrupts = <0 243 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb0>;
clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>;
clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 8>,
<&mio_clk 12>;
resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>,
<&mio_rst 12>;
};
@ -340,7 +361,8 @@
interrupts = <0 244 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb1>;
clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>;
clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 9>,
<&mio_clk 13>;
resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>,
<&mio_rst 13>;
};
@ -352,7 +374,8 @@
interrupts = <0 245 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb2>;
clocks = <&mio_clk 7>, <&mio_clk 10>, <&mio_clk 14>;
clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 10>,
<&mio_clk 14>;
resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 10>,
<&mio_rst 14>;
};
@ -384,6 +407,24 @@
};
};
soc-glue@5f900000 {
compatible = "socionext,uniphier-ld11-soc-glue-debug",
"simple-mfd";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x5f900000 0x2000>;
efuse@100 {
compatible = "socionext,uniphier-efuse";
reg = <0x100 0x28>;
};
efuse@200 {
compatible = "socionext,uniphier-efuse";
reg = <0x200 0x68>;
};
};
aidet: aidet@5fc20000 {
compatible = "socionext,uniphier-ld11-aidet";
reg = <0x5fc20000 0x200>;
@ -429,6 +470,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_nand>;
clocks = <&sys_clk 2>;
resets = <&sys_rst 2>;
};
};
};

@ -40,13 +40,21 @@
};
&ethsc {
interrupts = <0 48 4>;
interrupts = <0 8>;
};
&serial0 {
status = "okay";
};
&gpio {
xirq0 {
gpio-hog;
gpios = <UNIPHIER_GPIO_IRQ(0) 0>;
input;
};
};
&i2c0 {
status = "okay";
};

@ -7,6 +7,10 @@
* SPDX-License-Identifier: (GPL-2.0+ OR MIT)
*/
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/gpio/uniphier-gpio.h>
#include <dt-bindings/thermal/thermal.h>
/memreserve/ 0x80000000 0x02000000;
/ {
@ -46,6 +50,7 @@
clocks = <&sys_clk 32>;
enable-method = "psci";
operating-points-v2 = <&cluster0_opp>;
#cooling-cells = <2>;
};
cpu1: cpu@1 {
@ -64,6 +69,7 @@
clocks = <&sys_clk 33>;
enable-method = "psci";
operating-points-v2 = <&cluster1_opp>;
#cooling-cells = <2>;
};
cpu3: cpu@101 {
@ -76,7 +82,7 @@
};
};
cluster0_opp: opp_table0 {
cluster0_opp: opp-table0 {
compatible = "operating-points-v2";
opp-shared;
@ -114,7 +120,7 @@
};
};
cluster1_opp: opp_table1 {
cluster1_opp: opp-table1 {
compatible = "operating-points-v2";
opp-shared;
@ -165,6 +171,11 @@
};
};
emmc_pwrseq: emmc-pwrseq {
compatible = "mmc-pwrseq-emmc";
reset-gpios = <&gpio UNIPHIER_GPIO_PORT(3, 2) GPIO_ACTIVE_LOW>;
};
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 4>,
@ -173,6 +184,40 @@
<1 10 4>;
};
thermal-zones {
cpu-thermal {
polling-delay-passive = <250>; /* 250ms */
polling-delay = <1000>; /* 1000ms */
thermal-sensors = <&pvtctl>;
trips {
cpu_crit: cpu-crit {
temperature = <110000>; /* 110C */
hysteresis = <2000>;
type = "critical";
};
cpu_alert: cpu-alert {
temperature = <100000>; /* 100C */
hysteresis = <2000>;
type = "passive";
};
};
cooling-maps {
map0 {
trip = <&cpu_alert>;
cooling-device = <&cpu0
THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
map1 {
trip = <&cpu_alert>;
cooling-device = <&cpu2
THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
};
soc@0 {
compatible = "simple-bus";
#address-cells = <1>;
@ -188,6 +233,7 @@
pinctrl-0 = <&pinctrl_uart0>;
clocks = <&peri_clk 0>;
clock-frequency = <58820000>;
resets = <&peri_rst 0>;
};
serial1: serial@54006900 {
@ -199,6 +245,7 @@
pinctrl-0 = <&pinctrl_uart1>;
clocks = <&peri_clk 1>;
clock-frequency = <58820000>;
resets = <&peri_rst 1>;
};
serial2: serial@54006a00 {
@ -210,6 +257,7 @@
pinctrl-0 = <&pinctrl_uart2>;
clocks = <&peri_clk 2>;
clock-frequency = <58820000>;
resets = <&peri_rst 2>;
};
serial3: serial@54006b00 {
@ -221,6 +269,7 @@
pinctrl-0 = <&pinctrl_uart3>;
clocks = <&peri_clk 3>;
clock-frequency = <58820000>;
resets = <&peri_rst 3>;
};
gpio: gpio@55000000 {
@ -263,6 +312,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0>;
clocks = <&peri_clk 4>;
resets = <&peri_rst 4>;
clock-frequency = <100000>;
};
@ -276,6 +326,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
clocks = <&peri_clk 5>;
resets = <&peri_rst 5>;
clock-frequency = <100000>;
};
@ -286,6 +337,7 @@
#size-cells = <0>;
interrupts = <0 43 4>;
clocks = <&peri_clk 6>;
resets = <&peri_rst 6>;
clock-frequency = <400000>;
};
@ -299,6 +351,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3>;
clocks = <&peri_clk 7>;
resets = <&peri_rst 7>;
clock-frequency = <100000>;
};
@ -312,6 +365,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c4>;
clocks = <&peri_clk 8>;
resets = <&peri_rst 8>;
clock-frequency = <100000>;
};
@ -322,6 +376,7 @@
#size-cells = <0>;
interrupts = <0 25 4>;
clocks = <&peri_clk 9>;
resets = <&peri_rst 9>;
clock-frequency = <400000>;
};
@ -379,9 +434,11 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_emmc_1v8>;
clocks = <&sys_clk 4>;
resets = <&sys_rst 4>;
bus-width = <8>;
mmc-ddr-1_8v;
mmc-hs200-1_8v;
mmc-pwrseq = <&emmc_pwrseq>;
cdns,phy-input-delay-legacy = <4>;
cdns,phy-input-delay-mmc-highspeed = <2>;
cdns,phy-input-delay-mmc-ddr = <3>;
@ -413,6 +470,24 @@
};
};
soc-glue@5f900000 {
compatible = "socionext,uniphier-ld20-soc-glue-debug",
"simple-mfd";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x5f900000 0x2000>;
efuse@100 {
compatible = "socionext,uniphier-efuse";
reg = <0x100 0x28>;
};
efuse@200 {
compatible = "socionext,uniphier-efuse";
reg = <0x200 0x68>;
};
};
aidet: aidet@5fc20000 {
compatible = "socionext,uniphier-ld20-aidet";
reg = <0x5fc20000 0x200>;
@ -447,6 +522,13 @@
watchdog {
compatible = "socionext,uniphier-wdt";
};
pvtctl: pvtctl {
compatible = "socionext,uniphier-ld20-thermal";
interrupts = <0 3 4>;
#thermal-sensor-cells = <0>;
socionext,tmod-calibration = <0x0f22 0x68ee>;
};
};
usb: usb@65b00000 {
@ -476,6 +558,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_nand>;
clocks = <&sys_clk 2>;
resets = <&sys_rst 2>;
};
};
};

@ -38,7 +38,7 @@
};
&ethsc {
interrupts = <0 49 4>;
interrupts = <1 8>;
};
&serial0 {
@ -53,6 +53,14 @@
status = "okay";
};
&gpio {
xirq1 {
gpio-hog;
gpios = <UNIPHIER_GPIO_IRQ(1) 0>;
input;
};
};
&i2c0 {
status = "okay";
};

@ -7,6 +7,8 @@
* SPDX-License-Identifier: (GPL-2.0+ OR MIT)
*/
#include <dt-bindings/gpio/uniphier-gpio.h>
/ {
compatible = "socionext,uniphier-ld4";
#address-cells = <1>;
@ -37,7 +39,7 @@
clock-frequency = <24576000>;
};
arm_timer_clk: arm_timer_clk {
arm_timer_clk: arm-timer {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <50000000>;
@ -72,6 +74,7 @@
pinctrl-0 = <&pinctrl_uart0>;
clocks = <&peri_clk 0>;
clock-frequency = <36864000>;
resets = <&peri_rst 0>;
};
serial1: serial@54006900 {
@ -83,6 +86,7 @@
pinctrl-0 = <&pinctrl_uart1>;
clocks = <&peri_clk 1>;
clock-frequency = <36864000>;
resets = <&peri_rst 1>;
};
serial2: serial@54006a00 {
@ -94,6 +98,7 @@
pinctrl-0 = <&pinctrl_uart2>;
clocks = <&peri_clk 2>;
clock-frequency = <36864000>;
resets = <&peri_rst 2>;
};
serial3: serial@54006b00 {
@ -105,6 +110,7 @@
pinctrl-0 = <&pinctrl_uart3>;
clocks = <&peri_clk 3>;
clock-frequency = <36864000>;
resets = <&peri_rst 3>;
};
gpio: gpio@55000000 {
@ -118,6 +124,7 @@
gpio-ranges = <&pinctrl 0 0 0>;
gpio-ranges-group-names = "gpio_range";
ngpios = <136>;
socionext,interrupt-ranges = <0 48 13>, <14 62 2>;
};
i2c0: i2c@58400000 {
@ -130,6 +137,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0>;
clocks = <&peri_clk 4>;
resets = <&peri_rst 4>;
clock-frequency = <100000>;
};
@ -143,6 +151,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
clocks = <&peri_clk 5>;
resets = <&peri_rst 5>;
clock-frequency = <100000>;
};
@ -156,6 +165,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
clocks = <&peri_clk 6>;
resets = <&peri_rst 6>;
clock-frequency = <400000>;
};
@ -169,6 +179,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3>;
clocks = <&peri_clk 7>;
resets = <&peri_rst 7>;
clock-frequency = <100000>;
};
@ -261,7 +272,8 @@
interrupts = <0 80 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb0>;
clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>;
clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 8>,
<&mio_clk 12>;
resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>,
<&mio_rst 12>;
};
@ -273,7 +285,8 @@
interrupts = <0 81 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb1>;
clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>;
clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 9>,
<&mio_clk 13>;
resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>,
<&mio_rst 13>;
};
@ -285,7 +298,8 @@
interrupts = <0 82 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb2>;
clocks = <&mio_clk 7>, <&mio_clk 10>, <&mio_clk 14>;
clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 10>,
<&mio_clk 14>;
resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 10>,
<&mio_rst 14>;
};
@ -354,6 +368,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_nand2cs>;
clocks = <&sys_clk 2>;
resets = <&sys_rst 2>;
};
};
};

@ -40,7 +40,7 @@
};
&ethsc {
interrupts = <0 52 4>;
interrupts = <4 8>;
};
&serial0 {
@ -55,6 +55,14 @@
status = "okay";
};
&gpio {
xirq4 {
gpio-hog;
gpios = <UNIPHIER_GPIO_IRQ(4) 0>;
input;
};
};
&i2c0 {
status = "okay";
};

@ -8,132 +8,132 @@
*/
&pinctrl {
pinctrl_aout: aout_grp {
pinctrl_aout: aout {
groups = "aout";
function = "aout";
};
pinctrl_emmc: emmc_grp {
pinctrl_emmc: emmc {
groups = "emmc", "emmc_dat8";
function = "emmc";
};
pinctrl_emmc_1v8: emmc_grp_1v8 {
pinctrl_emmc_1v8: emmc-1v8 {
groups = "emmc", "emmc_dat8";
function = "emmc";
};
pinctrl_ether_mii: ether_mii_grp {
pinctrl_ether_mii: ether-mii {
groups = "ether_mii";
function = "ether_mii";
};
pinctrl_ether_rgmii: ether_rgmii_grp {
pinctrl_ether_rgmii: ether-rgmii {
groups = "ether_rgmii";
function = "ether_rgmii";
};
pinctrl_ether_rmii: ether_rmii_grp {
pinctrl_ether_rmii: ether-rmii {
groups = "ether_rmii";
function = "ether_rmii";
};
pinctrl_i2c0: i2c0_grp {
pinctrl_i2c0: i2c0 {
groups = "i2c0";
function = "i2c0";
};
pinctrl_i2c1: i2c1_grp {
pinctrl_i2c1: i2c1 {
groups = "i2c1";
function = "i2c1";
};
pinctrl_i2c2: i2c2_grp {
pinctrl_i2c2: i2c2 {
groups = "i2c2";
function = "i2c2";
};
pinctrl_i2c3: i2c3_grp {
pinctrl_i2c3: i2c3 {
groups = "i2c3";
function = "i2c3";
};
pinctrl_i2c4: i2c4_grp {
pinctrl_i2c4: i2c4 {
groups = "i2c4";
function = "i2c4";
};
pinctrl_nand: nand_grp {
pinctrl_nand: nand {
groups = "nand";
function = "nand";
};
pinctrl_nand2cs: nand2cs_grp {
pinctrl_nand2cs: nand2cs {
groups = "nand", "nand_cs1";
function = "nand";
};
pinctrl_sd: sd_grp {
pinctrl_sd: sd {
groups = "sd";
function = "sd";
};
pinctrl_sd_1v8: sd_grp_1v8 {
pinctrl_sd_1v8: sd-1v8 {
groups = "sd";
function = "sd";
};
pinctrl_sd1: sd1_grp {
pinctrl_sd1: sd1 {
groups = "sd1";
function = "sd1";
};
pinctrl_sd1_1v8: sd1_grp_1v8 {
pinctrl_sd1_1v8: sd1-1v8 {
groups = "sd1";
function = "sd1";
};
pinctrl_system_bus: system_bus_grp {
pinctrl_system_bus: system-bus {
groups = "system_bus", "system_bus_cs1";
function = "system_bus";
};
pinctrl_uart0: uart0_grp {
pinctrl_uart0: uart0 {
groups = "uart0";
function = "uart0";
};
pinctrl_uart1: uart1_grp {
pinctrl_uart1: uart1 {
groups = "uart1";
function = "uart1";
};
pinctrl_uart2: uart2_grp {
pinctrl_uart2: uart2 {
groups = "uart2";
function = "uart2";
};
pinctrl_uart3: uart3_grp {
pinctrl_uart3: uart3 {
groups = "uart3";
function = "uart3";
};
pinctrl_usb0: usb0_grp {
pinctrl_usb0: usb0 {
groups = "usb0";
function = "usb0";
};
pinctrl_usb1: usb1_grp {
pinctrl_usb1: usb1 {
groups = "usb1";
function = "usb1";
};
pinctrl_usb2: usb2_grp {
pinctrl_usb2: usb2 {
groups = "usb2";
function = "usb2";
};
pinctrl_usb3: usb3_grp {
pinctrl_usb3: usb3 {
groups = "usb3";
function = "usb3";
};

@ -41,7 +41,7 @@
};
&ethsc {
interrupts = <0 50 4>;
interrupts = <2 8>;
};
&serial0 {
@ -56,6 +56,14 @@
status = "okay";
};
&gpio {
xirq2 {
gpio-hog;
gpios = <UNIPHIER_GPIO_IRQ(2) 0>;
input;
};
};
&i2c0 {
status = "okay";
};

@ -7,6 +7,8 @@
* SPDX-License-Identifier: (GPL-2.0+ OR MIT)
*/
#include <dt-bindings/gpio/uniphier-gpio.h>
/ {
compatible = "socionext,uniphier-pro4";
#address-cells = <1>;
@ -45,7 +47,7 @@
clock-frequency = <25000000>;
};
arm_timer_clk: arm_timer_clk {
arm_timer_clk: arm-timer {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <50000000>;
@ -80,6 +82,7 @@
pinctrl-0 = <&pinctrl_uart0>;
clocks = <&peri_clk 0>;
clock-frequency = <73728000>;
resets = <&peri_rst 0>;
};
serial1: serial@54006900 {
@ -91,6 +94,7 @@
pinctrl-0 = <&pinctrl_uart1>;
clocks = <&peri_clk 1>;
clock-frequency = <73728000>;
resets = <&peri_rst 1>;
};
serial2: serial@54006a00 {
@ -102,6 +106,7 @@
pinctrl-0 = <&pinctrl_uart2>;
clocks = <&peri_clk 2>;
clock-frequency = <73728000>;
resets = <&peri_rst 2>;
};
serial3: serial@54006b00 {
@ -113,6 +118,7 @@
pinctrl-0 = <&pinctrl_uart3>;
clocks = <&peri_clk 3>;
clock-frequency = <73728000>;
resets = <&peri_rst 3>;
};
gpio: gpio@55000000 {
@ -126,6 +132,7 @@
gpio-ranges = <&pinctrl 0 0 0>;
gpio-ranges-group-names = "gpio_range";
ngpios = <248>;
socionext,interrupt-ranges = <0 48 16>, <16 154 5>;
};
i2c0: i2c@58780000 {
@ -138,6 +145,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0>;
clocks = <&peri_clk 4>;
resets = <&peri_rst 4>;
clock-frequency = <100000>;
};
@ -151,6 +159,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
clocks = <&peri_clk 5>;
resets = <&peri_rst 5>;
clock-frequency = <100000>;
};
@ -164,6 +173,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
clocks = <&peri_clk 6>;
resets = <&peri_rst 6>;
clock-frequency = <100000>;
};
@ -177,6 +187,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3>;
clocks = <&peri_clk 7>;
resets = <&peri_rst 7>;
clock-frequency = <100000>;
};
@ -190,6 +201,7 @@
#size-cells = <0>;
interrupts = <0 25 4>;
clocks = <&peri_clk 9>;
resets = <&peri_rst 9>;
clock-frequency = <400000>;
};
@ -201,6 +213,7 @@
#size-cells = <0>;
interrupts = <0 26 4>;
clocks = <&peri_clk 10>;
resets = <&peri_rst 10>;
clock-frequency = <400000>;
};
@ -310,7 +323,8 @@
interrupts = <0 80 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb2>;
clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>;
clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 8>,
<&mio_clk 12>;
resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>,
<&mio_rst 12>;
};
@ -322,7 +336,8 @@
interrupts = <0 81 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb3>;
clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>;
clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 9>,
<&mio_clk 13>;
resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>,
<&mio_rst 13>;
};
@ -427,6 +442,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_nand>;
clocks = <&sys_clk 2>;
resets = <&sys_rst 2>;
};
};
};

@ -37,7 +37,7 @@
};
};
cpu_opp: opp_table {
cpu_opp: opp-table {
compatible = "operating-points-v2";
opp-shared;
@ -119,7 +119,7 @@
clock-frequency = <20000000>;
};
arm_timer_clk: arm_timer_clk {
arm_timer_clk: arm-timer {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <50000000>;
@ -167,6 +167,7 @@
pinctrl-0 = <&pinctrl_uart0>;
clocks = <&peri_clk 0>;
clock-frequency = <73728000>;
resets = <&peri_rst 0>;
};
serial1: serial@54006900 {
@ -178,6 +179,7 @@
pinctrl-0 = <&pinctrl_uart1>;
clocks = <&peri_clk 1>;
clock-frequency = <73728000>;
resets = <&peri_rst 1>;
};
serial2: serial@54006a00 {
@ -189,6 +191,7 @@
pinctrl-0 = <&pinctrl_uart2>;
clocks = <&peri_clk 2>;
clock-frequency = <73728000>;
resets = <&peri_rst 2>;
};
serial3: serial@54006b00 {
@ -200,6 +203,7 @@
pinctrl-0 = <&pinctrl_uart3>;
clocks = <&peri_clk 3>;
clock-frequency = <73728000>;
resets = <&peri_rst 3>;
};
gpio: gpio@55000000 {
@ -213,6 +217,7 @@
gpio-ranges = <&pinctrl 0 0 0>;
gpio-ranges-group-names = "gpio_range";
ngpios = <248>;
socionext,interrupt-ranges = <0 48 16>, <16 154 5>;
};
i2c0: i2c@58780000 {
@ -225,6 +230,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0>;
clocks = <&peri_clk 4>;
resets = <&peri_rst 4>;
clock-frequency = <100000>;
};
@ -238,6 +244,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
clocks = <&peri_clk 5>;
resets = <&peri_rst 5>;
clock-frequency = <100000>;
};
@ -251,6 +258,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
clocks = <&peri_clk 6>;
resets = <&peri_rst 6>;
clock-frequency = <100000>;
};
@ -264,6 +272,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3>;
clocks = <&peri_clk 7>;
resets = <&peri_rst 7>;
clock-frequency = <100000>;
};
@ -277,6 +286,7 @@
#size-cells = <0>;
interrupts = <0 25 4>;
clocks = <&peri_clk 9>;
resets = <&peri_rst 9>;
clock-frequency = <400000>;
};
@ -288,6 +298,7 @@
#size-cells = <0>;
interrupts = <0 26 4>;
clocks = <&peri_clk 10>;
resets = <&peri_rst 10>;
clock-frequency = <400000>;
};
@ -438,6 +449,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_nand2cs>;
clocks = <&sys_clk 2>;
resets = <&sys_rst 2>;
};
emmc: sdhc@68400000 {

@ -7,6 +7,9 @@
* SPDX-License-Identifier: (GPL-2.0+ OR MIT)
*/
#include <dt-bindings/gpio/uniphier-gpio.h>
#include <dt-bindings/thermal/thermal.h>
/ {
compatible = "socionext,uniphier-pxs2";
#address-cells = <1>;
@ -16,7 +19,7 @@
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <0>;
@ -24,9 +27,10 @@
enable-method = "psci";
next-level-cache = <&l2>;
operating-points-v2 = <&cpu_opp>;
#cooling-cells = <2>;
};
cpu@1 {
cpu1: cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <1>;
@ -36,7 +40,7 @@
operating-points-v2 = <&cpu_opp>;
};
cpu@2 {
cpu2: cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <2>;
@ -46,7 +50,7 @@
operating-points-v2 = <&cpu_opp>;
};
cpu@3 {
cpu3: cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a9";
reg = <3>;
@ -57,7 +61,7 @@
};
};
cpu_opp: opp_table {
cpu_opp: opp-table {
compatible = "operating-points-v2";
opp-shared;
@ -107,13 +111,42 @@
clock-frequency = <25000000>;
};
arm_timer_clk: arm_timer_clk {
arm_timer_clk: arm-timer {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <50000000>;
};
};
thermal-zones {
cpu-thermal {
polling-delay-passive = <250>; /* 250ms */
polling-delay = <1000>; /* 1000ms */
thermal-sensors = <&pvtctl>;
trips {
cpu_crit: cpu-crit {
temperature = <95000>; /* 95C */
hysteresis = <2000>;
type = "critical";
};
cpu_alert: cpu-alert {
temperature = <85000>; /* 85C */
hysteresis = <2000>;
type = "passive";
};
};
cooling-maps {
map {
trip = <&cpu_alert>;
cooling-device = <&cpu0
THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
};
soc {
compatible = "simple-bus";
#address-cells = <1>;
@ -142,6 +175,7 @@
pinctrl-0 = <&pinctrl_uart0>;
clocks = <&peri_clk 0>;
clock-frequency = <88900000>;
resets = <&peri_rst 0>;
};
serial1: serial@54006900 {
@ -153,6 +187,7 @@
pinctrl-0 = <&pinctrl_uart1>;
clocks = <&peri_clk 1>;
clock-frequency = <88900000>;
resets = <&peri_rst 1>;
};
serial2: serial@54006a00 {
@ -164,6 +199,7 @@
pinctrl-0 = <&pinctrl_uart2>;
clocks = <&peri_clk 2>;
clock-frequency = <88900000>;
resets = <&peri_rst 2>;
};
serial3: serial@54006b00 {
@ -175,6 +211,7 @@
pinctrl-0 = <&pinctrl_uart3>;
clocks = <&peri_clk 3>;
clock-frequency = <88900000>;
resets = <&peri_rst 3>;
};
gpio: gpio@55000000 {
@ -190,6 +227,8 @@
gpio-ranges-group-names = "gpio_range0",
"gpio_range1";
ngpios = <232>;
socionext,interrupt-ranges = <0 48 16>, <16 154 5>,
<21 217 3>;
};
i2c0: i2c@58780000 {
@ -202,6 +241,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0>;
clocks = <&peri_clk 4>;
resets = <&peri_rst 4>;
clock-frequency = <100000>;
};
@ -215,6 +255,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
clocks = <&peri_clk 5>;
resets = <&peri_rst 5>;
clock-frequency = <100000>;
};
@ -228,6 +269,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
clocks = <&peri_clk 6>;
resets = <&peri_rst 6>;
clock-frequency = <100000>;
};
@ -241,6 +283,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3>;
clocks = <&peri_clk 7>;
resets = <&peri_rst 7>;
clock-frequency = <100000>;
};
@ -252,6 +295,7 @@
#size-cells = <0>;
interrupts = <0 45 4>;
clocks = <&peri_clk 8>;
resets = <&peri_rst 8>;
clock-frequency = <400000>;
};
@ -263,6 +307,7 @@
#size-cells = <0>;
interrupts = <0 25 4>;
clocks = <&peri_clk 9>;
resets = <&peri_rst 9>;
clock-frequency = <400000>;
};
@ -274,6 +319,7 @@
#size-cells = <0>;
interrupts = <0 26 4>;
clocks = <&peri_clk 10>;
resets = <&peri_rst 10>;
clock-frequency = <400000>;
};
@ -412,6 +458,13 @@
compatible = "socionext,uniphier-pxs2-reset";
#reset-cells = <1>;
};
pvtctl: pvtctl {
compatible = "socionext,uniphier-pxs2-thermal";
interrupts = <0 3 4>;
#thermal-sensor-cells = <0>;
socionext,tmod-calibration = <0x0f86 0x6844>;
};
};
usb0: usb@65b00000 {
@ -459,6 +512,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_nand2cs>;
clocks = <&sys_clk 2>;
resets = <&sys_rst 2>;
};
};
};

@ -38,13 +38,21 @@
};
&ethsc {
interrupts = <0 52 4>;
interrupts = <4 8>;
};
&serial0 {
status = "okay";
};
&gpio {
xirq4 {
gpio-hog;
gpios = <UNIPHIER_GPIO_IRQ(4) 0>;
input;
};
};
&i2c0 {
status = "okay";
};

@ -7,6 +7,9 @@
* SPDX-License-Identifier: (GPL-2.0+ OR MIT)
*/
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/gpio/uniphier-gpio.h>
/memreserve/ 0x80000000 0x02000000;
/ {
@ -73,7 +76,7 @@
};
};
cluster0_opp: opp_table {
cluster0_opp: opp-table {
compatible = "operating-points-v2";
opp-shared;
@ -124,6 +127,11 @@
};
};
emmc_pwrseq: emmc-pwrseq {
compatible = "mmc-pwrseq-emmc";
reset-gpios = <&gpio UNIPHIER_GPIO_PORT(5, 7) GPIO_ACTIVE_LOW>;
};
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 4>,
@ -147,6 +155,7 @@
pinctrl-0 = <&pinctrl_uart0>;
clocks = <&peri_clk 0>;
clock-frequency = <58820000>;
resets = <&peri_rst 0>;
};
serial1: serial@54006900 {
@ -158,6 +167,7 @@
pinctrl-0 = <&pinctrl_uart1>;
clocks = <&peri_clk 1>;
clock-frequency = <58820000>;
resets = <&peri_rst 1>;
};
serial2: serial@54006a00 {
@ -169,6 +179,7 @@
pinctrl-0 = <&pinctrl_uart2>;
clocks = <&peri_clk 2>;
clock-frequency = <58820000>;
resets = <&peri_rst 2>;
};
serial3: serial@54006b00 {
@ -180,6 +191,7 @@
pinctrl-0 = <&pinctrl_uart3>;
clocks = <&peri_clk 3>;
clock-frequency = <58820000>;
resets = <&peri_rst 3>;
};
gpio: gpio@55000000 {
@ -197,6 +209,8 @@
"gpio_range1",
"gpio_range2";
ngpios = <286>;
socionext,interrupt-ranges = <0 48 16>, <16 154 5>,
<21 217 3>;
};
i2c0: i2c@58780000 {
@ -209,6 +223,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0>;
clocks = <&peri_clk 4>;
resets = <&peri_rst 4>;
clock-frequency = <100000>;
};
@ -222,6 +237,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
clocks = <&peri_clk 5>;
resets = <&peri_rst 5>;
clock-frequency = <100000>;
};
@ -235,6 +251,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
clocks = <&peri_clk 6>;
resets = <&peri_rst 6>;
clock-frequency = <100000>;
};
@ -248,6 +265,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3>;
clocks = <&peri_clk 7>;
resets = <&peri_rst 7>;
clock-frequency = <100000>;
};
@ -259,6 +277,7 @@
#size-cells = <0>;
interrupts = <0 26 4>;
clocks = <&peri_clk 10>;
resets = <&peri_rst 10>;
clock-frequency = <400000>;
};
@ -316,9 +335,11 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_emmc_1v8>;
clocks = <&sys_clk 4>;
resets = <&sys_rst 4>;
bus-width = <8>;
mmc-ddr-1_8v;
mmc-hs200-1_8v;
mmc-pwrseq = <&emmc_pwrseq>;
cdns,phy-input-delay-legacy = <4>;
cdns,phy-input-delay-mmc-highspeed = <2>;
cdns,phy-input-delay-mmc-ddr = <3>;
@ -350,6 +371,24 @@
};
};
soc-glue@5f900000 {
compatible = "socionext,uniphier-pxs3-soc-glue-debug",
"simple-mfd";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x5f900000 0x2000>;
efuse@100 {
compatible = "socionext,uniphier-efuse";
reg = <0x100 0x28>;
};
efuse@200 {
compatible = "socionext,uniphier-efuse";
reg = <0x200 0x68>;
};
};
aidet: aidet@5fc20000 {
compatible = "socionext,uniphier-pxs3-aidet";
reg = <0x5fc20000 0x200>;
@ -431,6 +470,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_nand>;
clocks = <&sys_clk 2>;
resets = <&sys_rst 2>;
};
};
};

@ -38,7 +38,7 @@
};
&ethsc {
interrupts = <0 48 4>;
interrupts = <0 8>;
};
&serial0 {
@ -53,6 +53,14 @@
status = "okay";
};
&gpio {
xirq0 {
gpio-hog;
gpios = <UNIPHIER_GPIO_IRQ(0) 0>;
input;
};
};
&i2c0 {
status = "okay";
};

@ -7,6 +7,8 @@
* SPDX-License-Identifier: (GPL-2.0+ OR MIT)
*/
#include <dt-bindings/gpio/uniphier-gpio.h>
/ {
compatible = "socionext,uniphier-sld8";
#address-cells = <1>;
@ -37,7 +39,7 @@
clock-frequency = <25000000>;
};
arm_timer_clk: arm_timer_clk {
arm_timer_clk: arm-timer {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <50000000>;
@ -72,6 +74,7 @@
pinctrl-0 = <&pinctrl_uart0>;
clocks = <&peri_clk 0>;
clock-frequency = <80000000>;
resets = <&peri_rst 0>;
};
serial1: serial@54006900 {
@ -83,6 +86,7 @@
pinctrl-0 = <&pinctrl_uart1>;
clocks = <&peri_clk 1>;
clock-frequency = <80000000>;
resets = <&peri_rst 1>;
};
serial2: serial@54006a00 {
@ -94,6 +98,7 @@
pinctrl-0 = <&pinctrl_uart2>;
clocks = <&peri_clk 2>;
clock-frequency = <80000000>;
resets = <&peri_rst 2>;
};
serial3: serial@54006b00 {
@ -105,6 +110,7 @@
pinctrl-0 = <&pinctrl_uart3>;
clocks = <&peri_clk 3>;
clock-frequency = <80000000>;
resets = <&peri_rst 3>;
};
gpio: gpio@55000000 {
@ -122,6 +128,7 @@
"gpio_range1",
"gpio_range2";
ngpios = <136>;
socionext,interrupt-ranges = <0 48 13>, <14 62 2>;
};
i2c0: i2c@58400000 {
@ -134,6 +141,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0>;
clocks = <&peri_clk 4>;
resets = <&peri_rst 4>;
clock-frequency = <100000>;
};
@ -147,6 +155,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
clocks = <&peri_clk 5>;
resets = <&peri_rst 5>;
clock-frequency = <100000>;
};
@ -160,6 +169,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
clocks = <&peri_clk 6>;
resets = <&peri_rst 6>;
clock-frequency = <400000>;
};
@ -173,6 +183,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c3>;
clocks = <&peri_clk 7>;
resets = <&peri_rst 7>;
clock-frequency = <100000>;
};
@ -265,7 +276,8 @@
interrupts = <0 80 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb0>;
clocks = <&mio_clk 7>, <&mio_clk 8>, <&mio_clk 12>;
clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 8>,
<&mio_clk 12>;
resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 8>,
<&mio_rst 12>;
};
@ -277,7 +289,8 @@
interrupts = <0 81 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb1>;
clocks = <&mio_clk 7>, <&mio_clk 9>, <&mio_clk 13>;
clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 9>,
<&mio_clk 13>;
resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 9>,
<&mio_rst 13>;
};
@ -289,7 +302,8 @@
interrupts = <0 82 4>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb2>;
clocks = <&mio_clk 7>, <&mio_clk 10>, <&mio_clk 14>;
clocks = <&sys_clk 8>, <&mio_clk 7>, <&mio_clk 10>,
<&mio_clk 14>;
resets = <&sys_rst 8>, <&mio_rst 7>, <&mio_rst 10>,
<&mio_rst 14>;
};
@ -358,6 +372,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_nand2cs>;
clocks = <&sys_clk 2>;
resets = <&sys_rst 2>;
};
};
};

@ -11,11 +11,12 @@
status = "okay";
ranges = <1 0x00000000 0x42000000 0x02000000>;
support_card: support_card@1,1f00000 {
support_card: support-card@1,1f00000 {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
ranges = <0x00000000 1 0x01f00000 0x00100000>;
interrupt-parent = <&gpio>;
ethsc: ethernet@0 {
compatible = "smsc,lan9118", "smsc,lan9115";

@ -36,19 +36,19 @@
pinctrl {
u-boot,dm-pre-reloc;
emmc_grp {
emmc {
u-boot,dm-pre-reloc;
};
uart0_grp {
uart0 {
u-boot,dm-pre-reloc;
};
uart1_grp {
uart1 {
u-boot,dm-pre-reloc;
};
uart2_grp {
uart2 {
u-boot,dm-pre-reloc;
};
};

@ -13,6 +13,8 @@
#ifndef _SUNXI_DRAM_SUN8I_H3_H
#define _SUNXI_DRAM_SUN8I_H3_H
#include <linux/bitops.h>
struct sunxi_mctl_com_reg {
u32 cr; /* 0x00 control register */
u32 cr_r1; /* 0x04 rank 1 control register (R40 only) */
@ -211,7 +213,6 @@ struct sunxi_mctl_ctl_reg {
* the 32-bit wide access consists of. Also three control signals can be
* adjusted individually.
*/
#define BITS_PER_BYTE 8
#define NR_OF_BYTE_LANES (32 / BITS_PER_BYTE)
/* The eight data lines (DQn) plus DM, DQS and DQSN */
#define LINES_PER_BYTE_LANE (BITS_PER_BYTE + 3)

@ -15,10 +15,6 @@
#ifndef __KIRKWOOD_GPIO_H
#define __KIRKWOOD_GPIO_H
/* got from kernel include/linux/bitops.h */
#define BITS_PER_BYTE 8
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
#define GPIO_MAX 50
#define GPIO_OFF(pin) (((pin) >> 5) ? 0x0040 : 0x0000)
#define GPIO_OUT(pin) (MVEBU_GPIO0_BASE + GPIO_OFF(pin) + 0x00)

@ -17,55 +17,9 @@
DECLARE_GLOBAL_DATA_PTR;
static void uniphier_setup_xirq(void)
{
const void *fdt = gd->fdt_blob;
int soc_node, aidet_node;
const fdt32_t *val;
unsigned long aidet_base;
u32 tmp;
soc_node = fdt_path_offset(fdt, "/soc");
if (soc_node < 0)
return;
aidet_node = fdt_subnode_offset_namelen(fdt, soc_node, "aidet", 5);
if (aidet_node < 0)
return;
val = fdt_getprop(fdt, aidet_node, "reg", NULL);
if (!val)
return;
aidet_base = fdt32_to_cpu(*val);
tmp = readl(aidet_base + 8); /* AIDET DETCONFR2 */
tmp |= 0x00ff0000; /* Set XIRQ0-7 low active */
writel(tmp, aidet_base + 8);
tmp = readl(0x55000090); /* IRQCTL */
tmp |= 0x000000ff;
writel(tmp, 0x55000090);
}
#ifdef CONFIG_ARCH_UNIPHIER_LD11
static void uniphier_ld11_misc_init(void)
{
sg_set_pinsel(149, 14, 8, 4); /* XIRQ0 -> XIRQ0 */
sg_set_iectrl(149);
sg_set_pinsel(153, 14, 8, 4); /* XIRQ4 -> XIRQ4 */
sg_set_iectrl(153);
}
#endif
#ifdef CONFIG_ARCH_UNIPHIER_LD20
static void uniphier_ld20_misc_init(void)
{
sg_set_pinsel(149, 14, 8, 4); /* XIRQ0 -> XIRQ0 */
sg_set_iectrl(149);
sg_set_pinsel(153, 14, 8, 4); /* XIRQ4 -> XIRQ4 */
sg_set_iectrl(153);
/* ES1 errata: increase VDD09 supply to suppress VBO noise */
if (uniphier_get_soc_revision() == 1) {
writel(0x00000003, 0x6184e004);
@ -136,7 +90,6 @@ static const struct uniphier_initdata uniphier_initdata[] = {
.sbc_init = uniphier_ld11_sbc_init,
.pll_init = uniphier_ld11_pll_init,
.clk_init = uniphier_ld11_clk_init,
.misc_init = uniphier_ld11_misc_init,
},
#endif
#if defined(CONFIG_ARCH_UNIPHIER_LD20)
@ -192,10 +145,6 @@ int board_init(void)
led_puts("U3");
uniphier_setup_xirq();
led_puts("U4");
support_card_late_init();
led_puts("Uboo");

@ -21,5 +21,5 @@ void uniphier_ld11_sbc_init(void)
/* pins for NAND and System Bus are multiplexed */
if (spl_boot_device() != BOOT_DEVICE_NAND)
uniphier_pin_init("system_bus_grp");
uniphier_pin_init("system-bus");
}

@ -17,5 +17,5 @@ void uniphier_pxs2_sbc_init(void)
/* system bus output enable */
writel(0x17, PC0CTRL);
uniphier_pin_init("system_bus_grp"); /* PXs3 */
uniphier_pin_init("system-bus"); /* PXs3 */
}

@ -5,7 +5,7 @@ CONFIG_TARGET_OPENRD=y
CONFIG_IDENT_STRING="\nOpenRD-Base"
CONFIG_SYS_EXTRA_OPTIONS="BOARD_IS_OPENRD_BASE"
CONFIG_BOOTDELAY=3
CONFIG_LOGLEVEL=3
CONFIG_LOGLEVEL=2
# CONFIG_DISPLAY_BOARDINFO is not set
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_IDE=y

@ -5,7 +5,7 @@ CONFIG_TARGET_OPENRD=y
CONFIG_IDENT_STRING="\nOpenRD-Client"
CONFIG_SYS_EXTRA_OPTIONS="BOARD_IS_OPENRD_CLIENT"
CONFIG_BOOTDELAY=3
CONFIG_LOGLEVEL=3
CONFIG_LOGLEVEL=2
# CONFIG_DISPLAY_BOARDINFO is not set
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_IDE=y

@ -5,7 +5,7 @@ CONFIG_TARGET_OPENRD=y
CONFIG_IDENT_STRING="\nOpenRD-Ultimate"
CONFIG_SYS_EXTRA_OPTIONS="BOARD_IS_OPENRD_ULTIMATE"
CONFIG_BOOTDELAY=3
CONFIG_LOGLEVEL=3
CONFIG_LOGLEVEL=2
# CONFIG_DISPLAY_BOARDINFO is not set
# CONFIG_CMD_FLASH is not set
CONFIG_CMD_IDE=y

@ -9,6 +9,7 @@ CONFIG_ARCH_UNIPHIER_LD4_SLD8=y
CONFIG_MICRO_SUPPORT_CARD=y
CONFIG_DEFAULT_DEVICE_TREE="uniphier-ld4-ref"
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
CONFIG_LOGLEVEL=6
CONFIG_SPL=y
CONFIG_SPL_NOR_SUPPORT=y
CONFIG_HUSH_PARSER=y

@ -8,6 +8,7 @@ CONFIG_SPL_NAND_SUPPORT=y
CONFIG_MICRO_SUPPORT_CARD=y
CONFIG_DEFAULT_DEVICE_TREE="uniphier-pxs2-vodka"
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
CONFIG_LOGLEVEL=6
CONFIG_SPL=y
CONFIG_SPL_NOR_SUPPORT=y
CONFIG_HUSH_PARSER=y

@ -7,6 +7,7 @@ CONFIG_ARCH_UNIPHIER_V8_MULTI=y
CONFIG_MICRO_SUPPORT_CARD=y
CONFIG_DEFAULT_DEVICE_TREE="uniphier-ld20-ref"
# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
CONFIG_LOGLEVEL=6
CONFIG_HUSH_PARSER=y
CONFIG_CMD_CONFIG=y
CONFIG_CMD_IMLS=y

@ -13,8 +13,7 @@
#include <linux/errno.h>
#include <asm/global_data.h>
#include <asm/gpio.h>
#define UNIPHIER_GPIO_LINES_PER_BANK 8
#include <dt-bindings/gpio/uniphier-gpio.h>
#define UNIPHIER_GPIO_PORT_DATA 0x0 /* data */
#define UNIPHIER_GPIO_PORT_DIR 0x4 /* direction (1:in, 0:out) */

@ -14,7 +14,7 @@
*/
#include <common.h>
#include <asm/bitops.h>
#include <linux/bitops.h>
#include <asm/io.h>
#include <asm/arch/soc.h>
#include <asm/arch/gpio.h>

@ -1005,6 +1005,366 @@ int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops)
}
EXPORT_SYMBOL_GPL(mtd_read_oob);
/**
* mtd_ooblayout_ecc - Get the OOB region definition of a specific ECC section
* @mtd: MTD device structure
* @section: ECC section. Depending on the layout you may have all the ECC
* bytes stored in a single contiguous section, or one section
* per ECC chunk (and sometime several sections for a single ECC
* ECC chunk)
* @oobecc: OOB region struct filled with the appropriate ECC position
* information
*
* This function returns ECC section information in the OOB area. If you want
* to get all the ECC bytes information, then you should call
* mtd_ooblayout_ecc(mtd, section++, oobecc) until it returns -ERANGE.
*
* Returns zero on success, a negative error code otherwise.
*/
int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobecc)
{
memset(oobecc, 0, sizeof(*oobecc));
if (!mtd || section < 0)
return -EINVAL;
if (!mtd->ooblayout || !mtd->ooblayout->ecc)
return -ENOTSUPP;
return mtd->ooblayout->ecc(mtd, section, oobecc);
}
EXPORT_SYMBOL_GPL(mtd_ooblayout_ecc);
/**
* mtd_ooblayout_free - Get the OOB region definition of a specific free
* section
* @mtd: MTD device structure
* @section: Free section you are interested in. Depending on the layout
* you may have all the free bytes stored in a single contiguous
* section, or one section per ECC chunk plus an extra section
* for the remaining bytes (or other funky layout).
* @oobfree: OOB region struct filled with the appropriate free position
* information
*
* This function returns free bytes position in the OOB area. If you want
* to get all the free bytes information, then you should call
* mtd_ooblayout_free(mtd, section++, oobfree) until it returns -ERANGE.
*
* Returns zero on success, a negative error code otherwise.
*/
int mtd_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobfree)
{
memset(oobfree, 0, sizeof(*oobfree));
if (!mtd || section < 0)
return -EINVAL;
if (!mtd->ooblayout || !mtd->ooblayout->free)
return -ENOTSUPP;
return mtd->ooblayout->free(mtd, section, oobfree);
}
EXPORT_SYMBOL_GPL(mtd_ooblayout_free);
/**
* mtd_ooblayout_find_region - Find the region attached to a specific byte
* @mtd: mtd info structure
* @byte: the byte we are searching for
* @sectionp: pointer where the section id will be stored
* @oobregion: used to retrieve the ECC position
* @iter: iterator function. Should be either mtd_ooblayout_free or
* mtd_ooblayout_ecc depending on the region type you're searching for
*
* This function returns the section id and oobregion information of a
* specific byte. For example, say you want to know where the 4th ECC byte is
* stored, you'll use:
*
* mtd_ooblayout_find_region(mtd, 3, &section, &oobregion, mtd_ooblayout_ecc);
*
* Returns zero on success, a negative error code otherwise.
*/
static int mtd_ooblayout_find_region(struct mtd_info *mtd, int byte,
int *sectionp, struct mtd_oob_region *oobregion,
int (*iter)(struct mtd_info *,
int section,
struct mtd_oob_region *oobregion))
{
int pos = 0, ret, section = 0;
memset(oobregion, 0, sizeof(*oobregion));
while (1) {
ret = iter(mtd, section, oobregion);
if (ret)
return ret;
if (pos + oobregion->length > byte)
break;
pos += oobregion->length;
section++;
}
/*
* Adjust region info to make it start at the beginning at the
* 'start' ECC byte.
*/
oobregion->offset += byte - pos;
oobregion->length -= byte - pos;
*sectionp = section;
return 0;
}
/**
* mtd_ooblayout_find_eccregion - Find the ECC region attached to a specific
* ECC byte
* @mtd: mtd info structure
* @eccbyte: the byte we are searching for
* @sectionp: pointer where the section id will be stored
* @oobregion: OOB region information
*
* Works like mtd_ooblayout_find_region() except it searches for a specific ECC
* byte.
*
* Returns zero on success, a negative error code otherwise.
*/
int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte,
int *section,
struct mtd_oob_region *oobregion)
{
return mtd_ooblayout_find_region(mtd, eccbyte, section, oobregion,
mtd_ooblayout_ecc);
}
EXPORT_SYMBOL_GPL(mtd_ooblayout_find_eccregion);
/**
* mtd_ooblayout_get_bytes - Extract OOB bytes from the oob buffer
* @mtd: mtd info structure
* @buf: destination buffer to store OOB bytes
* @oobbuf: OOB buffer
* @start: first byte to retrieve
* @nbytes: number of bytes to retrieve
* @iter: section iterator
*
* Extract bytes attached to a specific category (ECC or free)
* from the OOB buffer and copy them into buf.
*
* Returns zero on success, a negative error code otherwise.
*/
static int mtd_ooblayout_get_bytes(struct mtd_info *mtd, u8 *buf,
const u8 *oobbuf, int start, int nbytes,
int (*iter)(struct mtd_info *,
int section,
struct mtd_oob_region *oobregion))
{
struct mtd_oob_region oobregion;
int section, ret;
ret = mtd_ooblayout_find_region(mtd, start, &section,
&oobregion, iter);
while (!ret) {
int cnt;
cnt = min_t(int, nbytes, oobregion.length);
memcpy(buf, oobbuf + oobregion.offset, cnt);
buf += cnt;
nbytes -= cnt;
if (!nbytes)
break;
ret = iter(mtd, ++section, &oobregion);
}
return ret;
}
/**
* mtd_ooblayout_set_bytes - put OOB bytes into the oob buffer
* @mtd: mtd info structure
* @buf: source buffer to get OOB bytes from
* @oobbuf: OOB buffer
* @start: first OOB byte to set
* @nbytes: number of OOB bytes to set
* @iter: section iterator
*
* Fill the OOB buffer with data provided in buf. The category (ECC or free)
* is selected by passing the appropriate iterator.
*
* Returns zero on success, a negative error code otherwise.
*/
static int mtd_ooblayout_set_bytes(struct mtd_info *mtd, const u8 *buf,
u8 *oobbuf, int start, int nbytes,
int (*iter)(struct mtd_info *,
int section,
struct mtd_oob_region *oobregion))
{
struct mtd_oob_region oobregion;
int section, ret;
ret = mtd_ooblayout_find_region(mtd, start, &section,
&oobregion, iter);
while (!ret) {
int cnt;
cnt = min_t(int, nbytes, oobregion.length);
memcpy(oobbuf + oobregion.offset, buf, cnt);
buf += cnt;
nbytes -= cnt;
if (!nbytes)
break;
ret = iter(mtd, ++section, &oobregion);
}
return ret;
}
/**
* mtd_ooblayout_count_bytes - count the number of bytes in a OOB category
* @mtd: mtd info structure
* @iter: category iterator
*
* Count the number of bytes in a given category.
*
* Returns a positive value on success, a negative error code otherwise.
*/
static int mtd_ooblayout_count_bytes(struct mtd_info *mtd,
int (*iter)(struct mtd_info *,
int section,
struct mtd_oob_region *oobregion))
{
struct mtd_oob_region oobregion;
int section = 0, ret, nbytes = 0;
while (1) {
ret = iter(mtd, section++, &oobregion);
if (ret) {
if (ret == -ERANGE)
ret = nbytes;
break;
}
nbytes += oobregion.length;
}
return ret;
}
/**
* mtd_ooblayout_get_eccbytes - extract ECC bytes from the oob buffer
* @mtd: mtd info structure
* @eccbuf: destination buffer to store ECC bytes
* @oobbuf: OOB buffer
* @start: first ECC byte to retrieve
* @nbytes: number of ECC bytes to retrieve
*
* Works like mtd_ooblayout_get_bytes(), except it acts on ECC bytes.
*
* Returns zero on success, a negative error code otherwise.
*/
int mtd_ooblayout_get_eccbytes(struct mtd_info *mtd, u8 *eccbuf,
const u8 *oobbuf, int start, int nbytes)
{
return mtd_ooblayout_get_bytes(mtd, eccbuf, oobbuf, start, nbytes,
mtd_ooblayout_ecc);
}
EXPORT_SYMBOL_GPL(mtd_ooblayout_get_eccbytes);
/**
* mtd_ooblayout_set_eccbytes - set ECC bytes into the oob buffer
* @mtd: mtd info structure
* @eccbuf: source buffer to get ECC bytes from
* @oobbuf: OOB buffer
* @start: first ECC byte to set
* @nbytes: number of ECC bytes to set
*
* Works like mtd_ooblayout_set_bytes(), except it acts on ECC bytes.
*
* Returns zero on success, a negative error code otherwise.
*/
int mtd_ooblayout_set_eccbytes(struct mtd_info *mtd, const u8 *eccbuf,
u8 *oobbuf, int start, int nbytes)
{
return mtd_ooblayout_set_bytes(mtd, eccbuf, oobbuf, start, nbytes,
mtd_ooblayout_ecc);
}
EXPORT_SYMBOL_GPL(mtd_ooblayout_set_eccbytes);
/**
* mtd_ooblayout_get_databytes - extract data bytes from the oob buffer
* @mtd: mtd info structure
* @databuf: destination buffer to store ECC bytes
* @oobbuf: OOB buffer
* @start: first ECC byte to retrieve
* @nbytes: number of ECC bytes to retrieve
*
* Works like mtd_ooblayout_get_bytes(), except it acts on free bytes.
*
* Returns zero on success, a negative error code otherwise.
*/
int mtd_ooblayout_get_databytes(struct mtd_info *mtd, u8 *databuf,
const u8 *oobbuf, int start, int nbytes)
{
return mtd_ooblayout_get_bytes(mtd, databuf, oobbuf, start, nbytes,
mtd_ooblayout_free);
}
EXPORT_SYMBOL_GPL(mtd_ooblayout_get_databytes);
/**
* mtd_ooblayout_get_eccbytes - set data bytes into the oob buffer
* @mtd: mtd info structure
* @eccbuf: source buffer to get data bytes from
* @oobbuf: OOB buffer
* @start: first ECC byte to set
* @nbytes: number of ECC bytes to set
*
* Works like mtd_ooblayout_get_bytes(), except it acts on free bytes.
*
* Returns zero on success, a negative error code otherwise.
*/
int mtd_ooblayout_set_databytes(struct mtd_info *mtd, const u8 *databuf,
u8 *oobbuf, int start, int nbytes)
{
return mtd_ooblayout_set_bytes(mtd, databuf, oobbuf, start, nbytes,
mtd_ooblayout_free);
}
EXPORT_SYMBOL_GPL(mtd_ooblayout_set_databytes);
/**
* mtd_ooblayout_count_freebytes - count the number of free bytes in OOB
* @mtd: mtd info structure
*
* Works like mtd_ooblayout_count_bytes(), except it count free bytes.
*
* Returns zero on success, a negative error code otherwise.
*/
int mtd_ooblayout_count_freebytes(struct mtd_info *mtd)
{
return mtd_ooblayout_count_bytes(mtd, mtd_ooblayout_free);
}
EXPORT_SYMBOL_GPL(mtd_ooblayout_count_freebytes);
/**
* mtd_ooblayout_count_freebytes - count the number of ECC bytes in OOB
* @mtd: mtd info structure
*
* Works like mtd_ooblayout_count_bytes(), except it count ECC bytes.
*
* Returns zero on success, a negative error code otherwise.
*/
int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd)
{
return mtd_ooblayout_count_bytes(mtd, mtd_ooblayout_ecc);
}
EXPORT_SYMBOL_GPL(mtd_ooblayout_count_eccbytes);
/*
* Method to access the protection register area, present in some flash
* devices. The user data is one time programmable but the factory data is read

@ -23,17 +23,6 @@ config NAND_DENALI_DT
Enable the driver for NAND flash on platforms using a Denali NAND
controller as a DT device.
config SYS_NAND_DENALI_64BIT
bool "Use 64-bit variant of Denali NAND controller"
depends on NAND_DENALI
help
The Denali NAND controller IP has some variations in terms of
the bus interface. The DMA setup sequence is completely differenct
between 32bit / 64bit AXI bus variants.
If your Denali NAND controller is the 64-bit variant, say Y.
Otherwise (32 bit), say N.
config NAND_DENALI_SPARE_AREA_SKIP_BYTES
int "Number of bytes skipped in OOB area"
depends on NAND_DENALI

@ -358,13 +358,12 @@ static struct nand_ecclayout nand_keystone_rbl_4bit_layout_oobfirst = {
* @buf: the data to write
* @oob_required: must write chip->oob_poi to OOB
* @page: page number to write
* @cached: cached programming
* @raw: use _raw version of write_page
*/
static int nand_davinci_write_page(struct mtd_info *mtd, struct nand_chip *chip,
uint32_t offset, int data_len,
const uint8_t *buf, int oob_required,
int page, int cached, int raw)
int page, int raw)
{
int status;
int ret = 0;
@ -395,13 +394,6 @@ static int nand_davinci_write_page(struct mtd_info *mtd, struct nand_chip *chip,
chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
status = chip->waitfunc(mtd, chip);
/*
* See if operation failed and additional status checks are
* available.
*/
if ((status & NAND_STATUS_FAIL) && (chip->errstat))
status = chip->errstat(mtd, chip, FL_WRITING, status, page);
if (status & NAND_STATUS_FAIL) {
ret = -EIO;
goto err;

File diff suppressed because it is too large Load Diff

@ -8,466 +8,319 @@
#ifndef __DENALI_H__
#define __DENALI_H__
#include <linux/bitops.h>
#include <linux/mtd/nand.h>
#include <linux/types.h>
#define DEVICE_RESET 0x0
#define DEVICE_RESET__BANK0 0x0001
#define DEVICE_RESET__BANK1 0x0002
#define DEVICE_RESET__BANK2 0x0004
#define DEVICE_RESET__BANK3 0x0008
#define DEVICE_RESET__BANK(bank) BIT(bank)
#define TRANSFER_SPARE_REG 0x10
#define TRANSFER_SPARE_REG__FLAG 0x0001
#define TRANSFER_SPARE_REG__FLAG BIT(0)
#define LOAD_WAIT_CNT 0x20
#define LOAD_WAIT_CNT__VALUE 0xffff
#define LOAD_WAIT_CNT__VALUE GENMASK(15, 0)
#define PROGRAM_WAIT_CNT 0x30
#define PROGRAM_WAIT_CNT__VALUE 0xffff
#define PROGRAM_WAIT_CNT__VALUE GENMASK(15, 0)
#define ERASE_WAIT_CNT 0x40
#define ERASE_WAIT_CNT__VALUE 0xffff
#define ERASE_WAIT_CNT__VALUE GENMASK(15, 0)
#define INT_MON_CYCCNT 0x50
#define INT_MON_CYCCNT__VALUE 0xffff
#define INT_MON_CYCCNT__VALUE GENMASK(15, 0)
#define RB_PIN_ENABLED 0x60
#define RB_PIN_ENABLED__BANK0 0x0001
#define RB_PIN_ENABLED__BANK1 0x0002
#define RB_PIN_ENABLED__BANK2 0x0004
#define RB_PIN_ENABLED__BANK3 0x0008
#define RB_PIN_ENABLED__BANK(bank) BIT(bank)
#define MULTIPLANE_OPERATION 0x70
#define MULTIPLANE_OPERATION__FLAG 0x0001
#define MULTIPLANE_OPERATION__FLAG BIT(0)
#define MULTIPLANE_READ_ENABLE 0x80
#define MULTIPLANE_READ_ENABLE__FLAG 0x0001
#define MULTIPLANE_READ_ENABLE__FLAG BIT(0)
#define COPYBACK_DISABLE 0x90
#define COPYBACK_DISABLE__FLAG 0x0001
#define COPYBACK_DISABLE__FLAG BIT(0)
#define CACHE_WRITE_ENABLE 0xa0
#define CACHE_WRITE_ENABLE__FLAG 0x0001
#define CACHE_WRITE_ENABLE__FLAG BIT(0)
#define CACHE_READ_ENABLE 0xb0
#define CACHE_READ_ENABLE__FLAG 0x0001
#define CACHE_READ_ENABLE__FLAG BIT(0)
#define PREFETCH_MODE 0xc0
#define PREFETCH_MODE__PREFETCH_EN 0x0001
#define PREFETCH_MODE__PREFETCH_BURST_LENGTH 0xfff0
#define PREFETCH_MODE__PREFETCH_EN BIT(0)
#define PREFETCH_MODE__PREFETCH_BURST_LENGTH GENMASK(15, 4)
#define CHIP_ENABLE_DONT_CARE 0xd0
#define CHIP_EN_DONT_CARE__FLAG 0x01
#define CHIP_EN_DONT_CARE__FLAG BIT(0)
#define ECC_ENABLE 0xe0
#define ECC_ENABLE__FLAG 0x0001
#define ECC_ENABLE__FLAG BIT(0)
#define GLOBAL_INT_ENABLE 0xf0
#define GLOBAL_INT_EN_FLAG 0x01
#define GLOBAL_INT_EN_FLAG BIT(0)
#define WE_2_RE 0x100
#define WE_2_RE__VALUE 0x003f
#define TWHR2_AND_WE_2_RE 0x100
#define TWHR2_AND_WE_2_RE__WE_2_RE GENMASK(5, 0)
#define TWHR2_AND_WE_2_RE__TWHR2 GENMASK(13, 8)
#define ADDR_2_DATA 0x110
#define ADDR_2_DATA__VALUE 0x003f
#define TCWAW_AND_ADDR_2_DATA 0x110
/* The width of ADDR_2_DATA is 6 bit for old IP, 7 bit for new IP */
#define TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA GENMASK(6, 0)
#define TCWAW_AND_ADDR_2_DATA__TCWAW GENMASK(13, 8)
#define RE_2_WE 0x120
#define RE_2_WE__VALUE 0x003f
#define RE_2_WE__VALUE GENMASK(5, 0)
#define ACC_CLKS 0x130
#define ACC_CLKS__VALUE 0x000f
#define ACC_CLKS__VALUE GENMASK(3, 0)
#define NUMBER_OF_PLANES 0x140
#define NUMBER_OF_PLANES__VALUE 0x0007
#define NUMBER_OF_PLANES__VALUE GENMASK(2, 0)
#define PAGES_PER_BLOCK 0x150
#define PAGES_PER_BLOCK__VALUE 0xffff
#define PAGES_PER_BLOCK__VALUE GENMASK(15, 0)
#define DEVICE_WIDTH 0x160
#define DEVICE_WIDTH__VALUE 0x0003
#define DEVICE_WIDTH__VALUE GENMASK(1, 0)
#define DEVICE_MAIN_AREA_SIZE 0x170
#define DEVICE_MAIN_AREA_SIZE__VALUE 0xffff
#define DEVICE_MAIN_AREA_SIZE__VALUE GENMASK(15, 0)
#define DEVICE_SPARE_AREA_SIZE 0x180
#define DEVICE_SPARE_AREA_SIZE__VALUE 0xffff
#define DEVICE_SPARE_AREA_SIZE__VALUE GENMASK(15, 0)
#define TWO_ROW_ADDR_CYCLES 0x190
#define TWO_ROW_ADDR_CYCLES__FLAG 0x0001
#define TWO_ROW_ADDR_CYCLES__FLAG BIT(0)
#define MULTIPLANE_ADDR_RESTRICT 0x1a0
#define MULTIPLANE_ADDR_RESTRICT__FLAG 0x0001
#define MULTIPLANE_ADDR_RESTRICT__FLAG BIT(0)
#define ECC_CORRECTION 0x1b0
#define ECC_CORRECTION__VALUE 0x001f
#define ECC_CORRECTION__VALUE GENMASK(4, 0)
#define ECC_CORRECTION__ERASE_THRESHOLD GENMASK(31, 16)
#define READ_MODE 0x1c0
#define READ_MODE__VALUE 0x000f
#define READ_MODE__VALUE GENMASK(3, 0)
#define WRITE_MODE 0x1d0
#define WRITE_MODE__VALUE 0x000f
#define WRITE_MODE__VALUE GENMASK(3, 0)
#define COPYBACK_MODE 0x1e0
#define COPYBACK_MODE__VALUE 0x000f
#define COPYBACK_MODE__VALUE GENMASK(3, 0)
#define RDWR_EN_LO_CNT 0x1f0
#define RDWR_EN_LO_CNT__VALUE 0x001f
#define RDWR_EN_LO_CNT__VALUE GENMASK(4, 0)
#define RDWR_EN_HI_CNT 0x200
#define RDWR_EN_HI_CNT__VALUE 0x001f
#define RDWR_EN_HI_CNT__VALUE GENMASK(4, 0)
#define MAX_RD_DELAY 0x210
#define MAX_RD_DELAY__VALUE 0x000f
#define MAX_RD_DELAY__VALUE GENMASK(3, 0)
#define CS_SETUP_CNT 0x220
#define CS_SETUP_CNT__VALUE 0x001f
#define CS_SETUP_CNT__VALUE GENMASK(4, 0)
#define CS_SETUP_CNT__TWB GENMASK(17, 12)
#define SPARE_AREA_SKIP_BYTES 0x230
#define SPARE_AREA_SKIP_BYTES__VALUE 0x003f
#define SPARE_AREA_SKIP_BYTES__VALUE GENMASK(5, 0)
#define SPARE_AREA_MARKER 0x240
#define SPARE_AREA_MARKER__VALUE 0xffff
#define SPARE_AREA_MARKER__VALUE GENMASK(15, 0)
#define DEVICES_CONNECTED 0x250
#define DEVICES_CONNECTED__VALUE 0x0007
#define DEVICES_CONNECTED__VALUE GENMASK(2, 0)
#define DIE_MASK 0x260
#define DIE_MASK__VALUE 0x00ff
#define DIE_MASK__VALUE GENMASK(7, 0)
#define FIRST_BLOCK_OF_NEXT_PLANE 0x270
#define FIRST_BLOCK_OF_NEXT_PLANE__VALUE 0xffff
#define FIRST_BLOCK_OF_NEXT_PLANE__VALUE GENMASK(15, 0)
#define WRITE_PROTECT 0x280
#define WRITE_PROTECT__FLAG 0x0001
#define WRITE_PROTECT__FLAG BIT(0)
#define RE_2_RE 0x290
#define RE_2_RE__VALUE 0x003f
#define RE_2_RE__VALUE GENMASK(5, 0)
#define MANUFACTURER_ID 0x300
#define MANUFACTURER_ID__VALUE 0x00ff
#define MANUFACTURER_ID__VALUE GENMASK(7, 0)
#define DEVICE_ID 0x310
#define DEVICE_ID__VALUE 0x00ff
#define DEVICE_ID__VALUE GENMASK(7, 0)
#define DEVICE_PARAM_0 0x320
#define DEVICE_PARAM_0__VALUE 0x00ff
#define DEVICE_PARAM_0__VALUE GENMASK(7, 0)
#define DEVICE_PARAM_1 0x330
#define DEVICE_PARAM_1__VALUE 0x00ff
#define DEVICE_PARAM_1__VALUE GENMASK(7, 0)
#define DEVICE_PARAM_2 0x340
#define DEVICE_PARAM_2__VALUE 0x00ff
#define DEVICE_PARAM_2__VALUE GENMASK(7, 0)
#define LOGICAL_PAGE_DATA_SIZE 0x350
#define LOGICAL_PAGE_DATA_SIZE__VALUE 0xffff
#define LOGICAL_PAGE_DATA_SIZE__VALUE GENMASK(15, 0)
#define LOGICAL_PAGE_SPARE_SIZE 0x360
#define LOGICAL_PAGE_SPARE_SIZE__VALUE 0xffff
#define LOGICAL_PAGE_SPARE_SIZE__VALUE GENMASK(15, 0)
#define REVISION 0x370
#define REVISION__VALUE 0xffff
#define REVISION__VALUE GENMASK(15, 0)
#define ONFI_DEVICE_FEATURES 0x380
#define ONFI_DEVICE_FEATURES__VALUE 0x003f
#define ONFI_DEVICE_FEATURES__VALUE GENMASK(5, 0)
#define ONFI_OPTIONAL_COMMANDS 0x390
#define ONFI_OPTIONAL_COMMANDS__VALUE 0x003f
#define ONFI_OPTIONAL_COMMANDS__VALUE GENMASK(5, 0)
#define ONFI_TIMING_MODE 0x3a0
#define ONFI_TIMING_MODE__VALUE 0x003f
#define ONFI_TIMING_MODE__VALUE GENMASK(5, 0)
#define ONFI_PGM_CACHE_TIMING_MODE 0x3b0
#define ONFI_PGM_CACHE_TIMING_MODE__VALUE 0x003f
#define ONFI_PGM_CACHE_TIMING_MODE__VALUE GENMASK(5, 0)
#define ONFI_DEVICE_NO_OF_LUNS 0x3c0
#define ONFI_DEVICE_NO_OF_LUNS__NO_OF_LUNS 0x00ff
#define ONFI_DEVICE_NO_OF_LUNS__ONFI_DEVICE 0x0100
#define ONFI_DEVICE_NO_OF_LUNS__NO_OF_LUNS GENMASK(7, 0)
#define ONFI_DEVICE_NO_OF_LUNS__ONFI_DEVICE BIT(8)
#define ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_L 0x3d0
#define ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_L__VALUE 0xffff
#define ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_L__VALUE GENMASK(15, 0)
#define ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_U 0x3e0
#define ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_U__VALUE 0xffff
#define FEATURES 0x3f0
#define FEATURES__N_BANKS 0x0003
#define FEATURES__ECC_MAX_ERR 0x003c
#define FEATURES__DMA 0x0040
#define FEATURES__CMD_DMA 0x0080
#define FEATURES__PARTITION 0x0100
#define FEATURES__XDMA_SIDEBAND 0x0200
#define FEATURES__GPREG 0x0400
#define FEATURES__INDEX_ADDR 0x0800
#define ONFI_DEVICE_NO_OF_BLOCKS_PER_LUN_U__VALUE GENMASK(15, 0)
#define FEATURES 0x3f0
#define FEATURES__N_BANKS GENMASK(1, 0)
#define FEATURES__ECC_MAX_ERR GENMASK(5, 2)
#define FEATURES__DMA BIT(6)
#define FEATURES__CMD_DMA BIT(7)
#define FEATURES__PARTITION BIT(8)
#define FEATURES__XDMA_SIDEBAND BIT(9)
#define FEATURES__GPREG BIT(10)
#define FEATURES__INDEX_ADDR BIT(11)
#define TRANSFER_MODE 0x400
#define TRANSFER_MODE__VALUE 0x0003
#define INTR_STATUS(__bank) (0x410 + ((__bank) * 0x50))
#define INTR_EN(__bank) (0x420 + ((__bank) * 0x50))
/*
* Some versions of the IP have the ECC fixup handled in hardware. In this
* configuration we only get interrupted when the error is uncorrectable.
* Unfortunately this bit replaces INTR_STATUS__ECC_TRANSACTION_DONE from the
* old IP.
*/
#define INTR_STATUS__ECC_UNCOR_ERR 0x0001
#define INTR_STATUS__ECC_TRANSACTION_DONE 0x0001
#define INTR_STATUS__ECC_ERR 0x0002
#define INTR_STATUS__DMA_CMD_COMP 0x0004
#define INTR_STATUS__TIME_OUT 0x0008
#define INTR_STATUS__PROGRAM_FAIL 0x0010
#define INTR_STATUS__ERASE_FAIL 0x0020
#define INTR_STATUS__LOAD_COMP 0x0040
#define INTR_STATUS__PROGRAM_COMP 0x0080
#define INTR_STATUS__ERASE_COMP 0x0100
#define INTR_STATUS__PIPE_CPYBCK_CMD_COMP 0x0200
#define INTR_STATUS__LOCKED_BLK 0x0400
#define INTR_STATUS__UNSUP_CMD 0x0800
#define INTR_STATUS__INT_ACT 0x1000
#define INTR_STATUS__RST_COMP 0x2000
#define INTR_STATUS__PIPE_CMD_ERR 0x4000
#define INTR_STATUS__PAGE_XFER_INC 0x8000
#define INTR_EN__ECC_TRANSACTION_DONE 0x0001
#define INTR_EN__ECC_ERR 0x0002
#define INTR_EN__DMA_CMD_COMP 0x0004
#define INTR_EN__TIME_OUT 0x0008
#define INTR_EN__PROGRAM_FAIL 0x0010
#define INTR_EN__ERASE_FAIL 0x0020
#define INTR_EN__LOAD_COMP 0x0040
#define INTR_EN__PROGRAM_COMP 0x0080
#define INTR_EN__ERASE_COMP 0x0100
#define INTR_EN__PIPE_CPYBCK_CMD_COMP 0x0200
#define INTR_EN__LOCKED_BLK 0x0400
#define INTR_EN__UNSUP_CMD 0x0800
#define INTR_EN__INT_ACT 0x1000
#define INTR_EN__RST_COMP 0x2000
#define INTR_EN__PIPE_CMD_ERR 0x4000
#define INTR_EN__PAGE_XFER_INC 0x8000
#define PAGE_CNT(__bank) (0x430 + ((__bank) * 0x50))
#define ERR_PAGE_ADDR(__bank) (0x440 + ((__bank) * 0x50))
#define ERR_BLOCK_ADDR(__bank) (0x450 + ((__bank) * 0x50))
#define DATA_INTR 0x550
#define DATA_INTR__WRITE_SPACE_AV 0x0001
#define DATA_INTR__READ_DATA_AV 0x0002
#define DATA_INTR_EN 0x560
#define DATA_INTR_EN__WRITE_SPACE_AV 0x0001
#define DATA_INTR_EN__READ_DATA_AV 0x0002
#define GPREG_0 0x570
#define GPREG_0__VALUE 0xffff
#define GPREG_1 0x580
#define GPREG_1__VALUE 0xffff
#define GPREG_2 0x590
#define GPREG_2__VALUE 0xffff
#define GPREG_3 0x5a0
#define GPREG_3__VALUE 0xffff
#define TRANSFER_MODE__VALUE GENMASK(1, 0)
#define INTR_STATUS(bank) (0x410 + (bank) * 0x50)
#define INTR_EN(bank) (0x420 + (bank) * 0x50)
/* bit[1:0] is used differently depending on IP version */
#define INTR__ECC_UNCOR_ERR BIT(0) /* new IP */
#define INTR__ECC_TRANSACTION_DONE BIT(0) /* old IP */
#define INTR__ECC_ERR BIT(1) /* old IP */
#define INTR__DMA_CMD_COMP BIT(2)
#define INTR__TIME_OUT BIT(3)
#define INTR__PROGRAM_FAIL BIT(4)
#define INTR__ERASE_FAIL BIT(5)
#define INTR__LOAD_COMP BIT(6)
#define INTR__PROGRAM_COMP BIT(7)
#define INTR__ERASE_COMP BIT(8)
#define INTR__PIPE_CPYBCK_CMD_COMP BIT(9)
#define INTR__LOCKED_BLK BIT(10)
#define INTR__UNSUP_CMD BIT(11)
#define INTR__INT_ACT BIT(12)
#define INTR__RST_COMP BIT(13)
#define INTR__PIPE_CMD_ERR BIT(14)
#define INTR__PAGE_XFER_INC BIT(15)
#define INTR__ERASED_PAGE BIT(16)
#define PAGE_CNT(bank) (0x430 + (bank) * 0x50)
#define ERR_PAGE_ADDR(bank) (0x440 + (bank) * 0x50)
#define ERR_BLOCK_ADDR(bank) (0x450 + (bank) * 0x50)
#define ECC_THRESHOLD 0x600
#define ECC_THRESHOLD__VALUE 0x03ff
#define ECC_THRESHOLD__VALUE GENMASK(9, 0)
#define ECC_ERROR_BLOCK_ADDRESS 0x610
#define ECC_ERROR_BLOCK_ADDRESS__VALUE 0xffff
#define ECC_ERROR_BLOCK_ADDRESS__VALUE GENMASK(15, 0)
#define ECC_ERROR_PAGE_ADDRESS 0x620
#define ECC_ERROR_PAGE_ADDRESS__VALUE 0x0fff
#define ECC_ERROR_PAGE_ADDRESS__BANK 0xf000
#define ECC_ERROR_PAGE_ADDRESS__VALUE GENMASK(11, 0)
#define ECC_ERROR_PAGE_ADDRESS__BANK GENMASK(15, 12)
#define ECC_ERROR_ADDRESS 0x630
#define ECC_ERROR_ADDRESS__OFFSET 0x0fff
#define ECC_ERROR_ADDRESS__SECTOR_NR 0xf000
#define ECC_ERROR_ADDRESS__OFFSET GENMASK(11, 0)
#define ECC_ERROR_ADDRESS__SECTOR GENMASK(15, 12)
#define ERR_CORRECTION_INFO 0x640
#define ERR_CORRECTION_INFO__BYTEMASK 0x00ff
#define ERR_CORRECTION_INFO__DEVICE_NR 0x0f00
#define ERR_CORRECTION_INFO__ERROR_TYPE 0x4000
#define ERR_CORRECTION_INFO__LAST_ERR_INFO 0x8000
#define ERR_CORRECTION_INFO__BYTE GENMASK(7, 0)
#define ERR_CORRECTION_INFO__DEVICE GENMASK(11, 8)
#define ERR_CORRECTION_INFO__UNCOR BIT(14)
#define ERR_CORRECTION_INFO__LAST_ERR BIT(15)
#define ECC_COR_INFO(bank) (0x650 + (bank) / 2 * 0x10)
#define ECC_COR_INFO__SHIFT(bank) ((bank) % 2 * 8)
#define ECC_COR_INFO__MAX_ERRORS GENMASK(6, 0)
#define ECC_COR_INFO__UNCOR_ERR BIT(7)
#define CFG_DATA_BLOCK_SIZE 0x6b0
#define CFG_LAST_DATA_BLOCK_SIZE 0x6c0
#define CFG_NUM_DATA_BLOCKS 0x6d0
#define CFG_META_DATA_SIZE 0x6e0
#define DMA_ENABLE 0x700
#define DMA_ENABLE__FLAG 0x0001
#define DMA_ENABLE__FLAG BIT(0)
#define IGNORE_ECC_DONE 0x710
#define IGNORE_ECC_DONE__FLAG 0x0001
#define IGNORE_ECC_DONE__FLAG BIT(0)
#define DMA_INTR 0x720
#define DMA_INTR__TARGET_ERROR 0x0001
#define DMA_INTR__DESC_COMP_CHANNEL0 0x0002
#define DMA_INTR__DESC_COMP_CHANNEL1 0x0004
#define DMA_INTR__DESC_COMP_CHANNEL2 0x0008
#define DMA_INTR__DESC_COMP_CHANNEL3 0x0010
#define DMA_INTR__MEMCOPY_DESC_COMP 0x0020
#define DMA_INTR_EN 0x730
#define DMA_INTR_EN__TARGET_ERROR 0x0001
#define DMA_INTR_EN__DESC_COMP_CHANNEL0 0x0002
#define DMA_INTR_EN__DESC_COMP_CHANNEL1 0x0004
#define DMA_INTR_EN__DESC_COMP_CHANNEL2 0x0008
#define DMA_INTR_EN__DESC_COMP_CHANNEL3 0x0010
#define DMA_INTR_EN__MEMCOPY_DESC_COMP 0x0020
#define DMA_INTR__TARGET_ERROR BIT(0)
#define DMA_INTR__DESC_COMP_CHANNEL0 BIT(1)
#define DMA_INTR__DESC_COMP_CHANNEL1 BIT(2)
#define DMA_INTR__DESC_COMP_CHANNEL2 BIT(3)
#define DMA_INTR__DESC_COMP_CHANNEL3 BIT(4)
#define DMA_INTR__MEMCOPY_DESC_COMP BIT(5)
#define TARGET_ERR_ADDR_LO 0x740
#define TARGET_ERR_ADDR_LO__VALUE 0xffff
#define TARGET_ERR_ADDR_LO__VALUE GENMASK(15, 0)
#define TARGET_ERR_ADDR_HI 0x750
#define TARGET_ERR_ADDR_HI__VALUE 0xffff
#define TARGET_ERR_ADDR_HI__VALUE GENMASK(15, 0)
#define CHNL_ACTIVE 0x760
#define CHNL_ACTIVE__CHANNEL0 0x0001
#define CHNL_ACTIVE__CHANNEL1 0x0002
#define CHNL_ACTIVE__CHANNEL2 0x0004
#define CHNL_ACTIVE__CHANNEL3 0x0008
#define ACTIVE_SRC_ID 0x800
#define ACTIVE_SRC_ID__VALUE 0x00ff
#define PTN_INTR 0x810
#define PTN_INTR__CONFIG_ERROR 0x0001
#define PTN_INTR__ACCESS_ERROR_BANK0 0x0002
#define PTN_INTR__ACCESS_ERROR_BANK1 0x0004
#define PTN_INTR__ACCESS_ERROR_BANK2 0x0008
#define PTN_INTR__ACCESS_ERROR_BANK3 0x0010
#define PTN_INTR__REG_ACCESS_ERROR 0x0020
#define PTN_INTR_EN 0x820
#define PTN_INTR_EN__CONFIG_ERROR 0x0001
#define PTN_INTR_EN__ACCESS_ERROR_BANK0 0x0002
#define PTN_INTR_EN__ACCESS_ERROR_BANK1 0x0004
#define PTN_INTR_EN__ACCESS_ERROR_BANK2 0x0008
#define PTN_INTR_EN__ACCESS_ERROR_BANK3 0x0010
#define PTN_INTR_EN__REG_ACCESS_ERROR 0x0020
#define PERM_SRC_ID(__bank) (0x830 + ((__bank) * 0x40))
#define PERM_SRC_ID__SRCID 0x00ff
#define PERM_SRC_ID__DIRECT_ACCESS_ACTIVE 0x0800
#define PERM_SRC_ID__WRITE_ACTIVE 0x2000
#define PERM_SRC_ID__READ_ACTIVE 0x4000
#define PERM_SRC_ID__PARTITION_VALID 0x8000
#define MIN_BLK_ADDR(__bank) (0x840 + ((__bank) * 0x40))
#define MIN_BLK_ADDR__VALUE 0xffff
#define MAX_BLK_ADDR(__bank) (0x850 + ((__bank) * 0x40))
#define MAX_BLK_ADDR__VALUE 0xffff
#define MIN_MAX_BANK(__bank) (0x860 + ((__bank) * 0x40))
#define MIN_MAX_BANK__MIN_VALUE 0x0003
#define MIN_MAX_BANK__MAX_VALUE 0x000c
/* lld.h */
#define GOOD_BLOCK 0
#define DEFECTIVE_BLOCK 1
#define READ_ERROR 2
#define CLK_X 5
#define CLK_MULTI 4
/* spectraswconfig.h */
#define CMD_DMA 0
#define SPECTRA_PARTITION_ID 0
/**** Block Table and Reserved Block Parameters *****/
#define SPECTRA_START_BLOCK 3
#define NUM_FREE_BLOCKS_GATE 30
/* KBV - Updated to LNW scratch register address */
#define SCRATCH_REG_ADDR CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR
#define SCRATCH_REG_SIZE 64
#define GLOB_HWCTL_DEFAULT_BLKS 2048
#define CUSTOM_CONF_PARAMS 0
#define INDEX_CTRL_REG 0x0
#define INDEX_DATA_REG 0x10
#define MODE_00 0x00000000
#define MODE_01 0x04000000
#define MODE_10 0x08000000
#define MODE_11 0x0C000000
#define DATA_TRANSFER_MODE 0
#define PROTECTION_PER_BLOCK 1
#define LOAD_WAIT_COUNT 2
#define PROGRAM_WAIT_COUNT 3
#define ERASE_WAIT_COUNT 4
#define INT_MONITOR_CYCLE_COUNT 5
#define READ_BUSY_PIN_ENABLED 6
#define MULTIPLANE_OPERATION_SUPPORT 7
#define PRE_FETCH_MODE 8
#define CE_DONT_CARE_SUPPORT 9
#define COPYBACK_SUPPORT 10
#define CACHE_WRITE_SUPPORT 11
#define CACHE_READ_SUPPORT 12
#define NUM_PAGES_IN_BLOCK 13
#define ECC_ENABLE_SELECT 14
#define WRITE_ENABLE_2_READ_ENABLE 15
#define ADDRESS_2_DATA 16
#define READ_ENABLE_2_WRITE_ENABLE 17
#define TWO_ROW_ADDRESS_CYCLES 18
#define MULTIPLANE_ADDRESS_RESTRICT 19
#define ACC_CLOCKS 20
#define READ_WRITE_ENABLE_LOW_COUNT 21
#define READ_WRITE_ENABLE_HIGH_COUNT 22
#define ECC_SECTOR_SIZE 512
#define DENALI_BUF_SIZE (NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE)
struct nand_buf {
int head;
int tail;
/* seprating dma_buf as buf can be used for status read purpose */
uint8_t dma_buf[DENALI_BUF_SIZE] __aligned(64);
uint8_t buf[DENALI_BUF_SIZE];
};
#define CHNL_ACTIVE__CHANNEL0 BIT(0)
#define CHNL_ACTIVE__CHANNEL1 BIT(1)
#define CHNL_ACTIVE__CHANNEL2 BIT(2)
#define CHNL_ACTIVE__CHANNEL3 BIT(3)
#define INTEL_CE4100 1
#define INTEL_MRST 2
#define DT 3
struct udevice;
struct denali_nand_info {
struct nand_chip nand;
unsigned long clk_x_rate; /* bus interface clock rate */
int flash_bank; /* currently selected chip */
int status;
int platform;
struct nand_buf buf;
struct device *dev;
int total_used_banks;
uint32_t block; /* stored for future use */
int active_bank; /* currently selected bank */
struct udevice *dev;
uint32_t page;
void __iomem *flash_reg; /* Mapped io reg base address */
void __iomem *flash_mem; /* Mapped io reg base address */
/* elements used by ISR */
/*struct completion complete;*/
uint32_t irq_status;
int irq_debug_array[32];
int idx;
void __iomem *reg; /* Register Interface */
void __iomem *host; /* Host Data/Command Interface */
u32 irq_mask; /* interrupts we are waiting for */
u32 irq_status; /* interrupts that have happened */
int irq;
uint32_t devnum; /* represent how many nands connected */
uint32_t fwblks; /* represent how many blocks FW used */
uint32_t totalblks;
uint32_t blksperchip;
uint32_t bbtskipbytes;
uint32_t max_banks;
unsigned int revision;
unsigned int caps;
void *buf; /* for syndrome layout conversion */
dma_addr_t dma_addr;
int dma_avail; /* can support DMA? */
int devs_per_cs; /* devices connected in parallel */
int oob_skip_bytes; /* number of bytes reserved for BBM */
int max_banks;
unsigned int revision; /* IP revision */
unsigned int caps; /* IP capability (or quirk) */
const struct nand_ecc_caps *ecc_caps;
u32 (*host_read)(struct denali_nand_info *denali, u32 addr);
void (*host_write)(struct denali_nand_info *denali, u32 addr, u32 data);
void (*setup_dma)(struct denali_nand_info *denali, dma_addr_t dma_addr,
int page, int write);
};
#define DENALI_CAP_HW_ECC_FIXUP BIT(0)
#define DENALI_CAP_DMA_64BIT BIT(1)
int denali_calc_ecc_bytes(int step_size, int strength);
int denali_init(struct denali_nand_info *denali);
#endif /* __DENALI_H__ */

@ -16,21 +16,31 @@
struct denali_dt_data {
unsigned int revision;
unsigned int caps;
const struct nand_ecc_caps *ecc_caps;
};
NAND_ECC_CAPS_SINGLE(denali_socfpga_ecc_caps, denali_calc_ecc_bytes,
512, 8, 15);
static const struct denali_dt_data denali_socfpga_data = {
.caps = DENALI_CAP_HW_ECC_FIXUP,
.ecc_caps = &denali_socfpga_ecc_caps,
};
NAND_ECC_CAPS_SINGLE(denali_uniphier_v5a_ecc_caps, denali_calc_ecc_bytes,
1024, 8, 16, 24);
static const struct denali_dt_data denali_uniphier_v5a_data = {
.caps = DENALI_CAP_HW_ECC_FIXUP |
DENALI_CAP_DMA_64BIT,
.ecc_caps = &denali_uniphier_v5a_ecc_caps,
};
NAND_ECC_CAPS_SINGLE(denali_uniphier_v5b_ecc_caps, denali_calc_ecc_bytes,
1024, 8, 16);
static const struct denali_dt_data denali_uniphier_v5b_data = {
.revision = 0x0501,
.caps = DENALI_CAP_HW_ECC_FIXUP |
DENALI_CAP_DMA_64BIT,
.ecc_caps = &denali_uniphier_v5b_ecc_caps,
};
static const struct udevice_id denali_nand_dt_ids[] = {
@ -61,19 +71,22 @@ static int denali_dt_probe(struct udevice *dev)
if (data) {
denali->revision = data->revision;
denali->caps = data->caps;
denali->ecc_caps = data->ecc_caps;
}
denali->dev = dev;
ret = dev_read_resource_byname(dev, "denali_reg", &res);
if (ret)
return ret;
denali->flash_reg = devm_ioremap(dev, res.start, resource_size(&res));
denali->reg = devm_ioremap(dev, res.start, resource_size(&res));
ret = dev_read_resource_byname(dev, "nand_data", &res);
if (ret)
return ret;
denali->flash_mem = devm_ioremap(dev, res.start, resource_size(&res));
denali->host = devm_ioremap(dev, res.start, resource_size(&res));
ret = clk_get_by_index(dev, 0, &clk);
if (ret)

@ -11,6 +11,12 @@
#include <linux/mtd/nand.h>
#include "denali.h"
#define DENALI_MAP01 (1 << 26) /* read/write pages in PIO */
#define DENALI_MAP10 (2 << 26) /* high-level control plane */
#define INDEX_CTRL_REG 0x0
#define INDEX_DATA_REG 0x10
#define SPARE_ACCESS 0x41
#define MAIN_ACCESS 0x42
#define PIPELINE_ACCESS 0x2000
@ -39,7 +45,7 @@ static int wait_for_irq(uint32_t irq_mask)
do {
intr_status = readl(denali_flash_reg + INTR_STATUS(flash_bank));
if (intr_status & INTR_STATUS__ECC_UNCOR_ERR) {
if (intr_status & INTR__ECC_UNCOR_ERR) {
debug("Uncorrected ECC detected\n");
return -EBADMSG;
}
@ -106,16 +112,16 @@ int denali_send_pipeline_cmd(int page, int ecc_en, int access_type)
addr = BANK(flash_bank) | page;
/* setup the acccess type */
cmd = MODE_10 | addr;
cmd = DENALI_MAP10 | addr;
index_addr(cmd, access_type);
/* setup the pipeline command */
index_addr(cmd, PIPELINE_ACCESS | page_count);
cmd = MODE_01 | addr;
cmd = DENALI_MAP01 | addr;
writel(cmd, denali_flash_mem + INDEX_CTRL_REG);
return wait_for_irq(INTR_STATUS__LOAD_COMP);
return wait_for_irq(INTR__LOAD_COMP);
}
static int nand_read_oob(void *buf, int page)

@ -634,8 +634,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command,
chip->cmd_ctrl(mtd, page_addr, ctrl);
ctrl &= ~NAND_CTRL_CHANGE;
chip->cmd_ctrl(mtd, page_addr >> 8, ctrl);
/* One more address cycle for devices > 32MiB */
if (chip->chipsize > (32 << 20))
if (chip->options & NAND_ROW_ADDR_3)
chip->cmd_ctrl(mtd, page_addr >> 16, ctrl);
}
chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
@ -729,8 +728,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command,
chip->cmd_ctrl(mtd, page_addr, ctrl);
chip->cmd_ctrl(mtd, page_addr >> 8,
NAND_NCE | NAND_ALE);
/* One more address cycle for devices > 128MiB */
if (chip->chipsize > (128 << 20))
if (chip->options & NAND_ROW_ADDR_3)
chip->cmd_ctrl(mtd, page_addr >> 16,
NAND_NCE | NAND_ALE);
}
@ -901,7 +899,184 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
return status;
}
#define BITS_PER_BYTE 8
/**
* nand_reset_data_interface - Reset data interface and timings
* @chip: The NAND chip
* @chipnr: Internal die id
*
* Reset the Data interface and timings to ONFI mode 0.
*
* Returns 0 for success or negative error code otherwise.
*/
static int nand_reset_data_interface(struct nand_chip *chip, int chipnr)
{
struct mtd_info *mtd = nand_to_mtd(chip);
const struct nand_data_interface *conf;
int ret;
if (!chip->setup_data_interface)
return 0;
/*
* The ONFI specification says:
* "
* To transition from NV-DDR or NV-DDR2 to the SDR data
* interface, the host shall use the Reset (FFh) command
* using SDR timing mode 0. A device in any timing mode is
* required to recognize Reset (FFh) command issued in SDR
* timing mode 0.
* "
*
* Configure the data interface in SDR mode and set the
* timings to timing mode 0.
*/
conf = nand_get_default_data_interface();
ret = chip->setup_data_interface(mtd, chipnr, conf);
if (ret)
pr_err("Failed to configure data interface to SDR timing mode 0\n");
return ret;
}
/**
* nand_setup_data_interface - Setup the best data interface and timings
* @chip: The NAND chip
* @chipnr: Internal die id
*
* Find and configure the best data interface and NAND timings supported by
* the chip and the driver.
* First tries to retrieve supported timing modes from ONFI information,
* and if the NAND chip does not support ONFI, relies on the
* ->onfi_timing_mode_default specified in the nand_ids table.
*
* Returns 0 for success or negative error code otherwise.
*/
static int nand_setup_data_interface(struct nand_chip *chip, int chipnr)
{
struct mtd_info *mtd = nand_to_mtd(chip);
int ret;
if (!chip->setup_data_interface || !chip->data_interface)
return 0;
/*
* Ensure the timing mode has been changed on the chip side
* before changing timings on the controller side.
*/
if (chip->onfi_version) {
u8 tmode_param[ONFI_SUBFEATURE_PARAM_LEN] = {
chip->onfi_timing_mode_default,
};
ret = chip->onfi_set_features(mtd, chip,
ONFI_FEATURE_ADDR_TIMING_MODE,
tmode_param);
if (ret)
goto err;
}
ret = chip->setup_data_interface(mtd, chipnr, chip->data_interface);
err:
return ret;
}
/**
* nand_init_data_interface - find the best data interface and timings
* @chip: The NAND chip
*
* Find the best data interface and NAND timings supported by the chip
* and the driver.
* First tries to retrieve supported timing modes from ONFI information,
* and if the NAND chip does not support ONFI, relies on the
* ->onfi_timing_mode_default specified in the nand_ids table. After this
* function nand_chip->data_interface is initialized with the best timing mode
* available.
*
* Returns 0 for success or negative error code otherwise.
*/
static int nand_init_data_interface(struct nand_chip *chip)
{
struct mtd_info *mtd = nand_to_mtd(chip);
int modes, mode, ret;
if (!chip->setup_data_interface)
return 0;
/*
* First try to identify the best timings from ONFI parameters and
* if the NAND does not support ONFI, fallback to the default ONFI
* timing mode.
*/
modes = onfi_get_async_timing_mode(chip);
if (modes == ONFI_TIMING_MODE_UNKNOWN) {
if (!chip->onfi_timing_mode_default)
return 0;
modes = GENMASK(chip->onfi_timing_mode_default, 0);
}
chip->data_interface = kzalloc(sizeof(*chip->data_interface),
GFP_KERNEL);
if (!chip->data_interface)
return -ENOMEM;
for (mode = fls(modes) - 1; mode >= 0; mode--) {
ret = onfi_init_data_interface(chip, chip->data_interface,
NAND_SDR_IFACE, mode);
if (ret)
continue;
/* Pass -1 to only */
ret = chip->setup_data_interface(mtd,
NAND_DATA_IFACE_CHECK_ONLY,
chip->data_interface);
if (!ret) {
chip->onfi_timing_mode_default = mode;
break;
}
}
return 0;
}
static void __maybe_unused nand_release_data_interface(struct nand_chip *chip)
{
kfree(chip->data_interface);
}
/**
* nand_reset - Reset and initialize a NAND device
* @chip: The NAND chip
* @chipnr: Internal die id
*
* Returns 0 for success or negative error code otherwise
*/
int nand_reset(struct nand_chip *chip, int chipnr)
{
struct mtd_info *mtd = nand_to_mtd(chip);
int ret;
ret = nand_reset_data_interface(chip, chipnr);
if (ret)
return ret;
/*
* The CS line has to be released before we can apply the new NAND
* interface settings, hence this weird ->select_chip() dance.
*/
chip->select_chip(mtd, chipnr);
chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
chip->select_chip(mtd, -1);
chip->select_chip(mtd, chipnr);
ret = nand_setup_data_interface(chip, chipnr);
chip->select_chip(mtd, -1);
if (ret)
return ret;
return 0;
}
/**
* nand_check_erased_buf - check if a buffer contains (almost) only 0xff data
@ -1547,6 +1722,9 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
if (!aligned)
use_bufpoi = 1;
else if (chip->options & NAND_USE_BOUNCE_BUFFER)
use_bufpoi = !IS_ALIGNED((unsigned long)buf,
chip->buf_align);
else
use_bufpoi = 0;
@ -1559,7 +1737,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
__func__, buf);
read_retry:
chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
if (nand_standard_page_accessors(&chip->ecc))
chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page);
/*
* Now read the page into the buffer. Absent an error,
@ -2235,12 +2414,11 @@ static int nand_write_page_syndrome(struct mtd_info *mtd,
* @buf: the data to write
* @oob_required: must write chip->oob_poi to OOB
* @page: page number to write
* @cached: cached programming
* @raw: use _raw version of write_page
*/
static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
uint32_t offset, int data_len, const uint8_t *buf,
int oob_required, int page, int cached, int raw)
int oob_required, int page, int raw)
{
int status, subpage;
@ -2250,7 +2428,8 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
else
subpage = 0;
chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
if (nand_standard_page_accessors(&chip->ecc))
chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);
if (unlikely(raw))
status = chip->ecc.write_page_raw(mtd, chip, buf,
@ -2265,29 +2444,12 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
if (status < 0)
return status;
/*
* Cached progamming disabled for now. Not sure if it's worth the
* trouble. The speed gain is not very impressive. (2.3->2.6Mib/s).
*/
cached = 0;
if (!cached || !NAND_HAS_CACHEPROG(chip)) {
if (nand_standard_page_accessors(&chip->ecc)) {
chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
status = chip->waitfunc(mtd, chip);
/*
* See if operation failed and additional status checks are
* available.
*/
if ((status & NAND_STATUS_FAIL) && (chip->errstat))
status = chip->errstat(mtd, chip, FL_WRITING, status,
page);
status = chip->waitfunc(mtd, chip);
if (status & NAND_STATUS_FAIL)
return -EIO;
} else {
chip->cmdfunc(mtd, NAND_CMD_CACHEDPROG, -1, -1);
status = chip->waitfunc(mtd, chip);
}
return 0;
@ -2362,7 +2524,7 @@ static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len,
static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops)
{
int chipnr, realpage, page, blockmask, column;
int chipnr, realpage, page, column;
struct nand_chip *chip = mtd_to_nand(mtd);
uint32_t writelen = ops->len;
@ -2398,7 +2560,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
realpage = (int)(to >> chip->page_shift);
page = realpage & chip->pagemask;
blockmask = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
/* Invalidate the page cache, when we write to the cached page */
if (to <= ((loff_t)chip->pagebuf << chip->page_shift) &&
@ -2413,13 +2574,15 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
while (1) {
int bytes = mtd->writesize;
int cached = writelen > bytes && page != blockmask;
uint8_t *wbuf = buf;
int use_bufpoi;
int part_pagewr = (column || writelen < mtd->writesize);
if (part_pagewr)
use_bufpoi = 1;
else if (chip->options & NAND_USE_BOUNCE_BUFFER)
use_bufpoi = !IS_ALIGNED((unsigned long)buf,
chip->buf_align);
else
use_bufpoi = 0;
@ -2428,7 +2591,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
if (use_bufpoi) {
pr_debug("%s: using write bounce buffer for buf@%p\n",
__func__, buf);
cached = 0;
if (part_pagewr)
bytes = min_t(int, bytes - column, writelen);
chip->pagebuf = -1;
@ -2446,7 +2608,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
memset(chip->oob_poi, 0xff, mtd->oobsize);
}
ret = chip->write_page(mtd, chip, column, bytes, wbuf,
oob_required, page, cached,
oob_required, page,
(ops->mode == MTD_OPS_RAW));
if (ret)
break;
@ -2582,10 +2744,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
}
chipnr = (int)(to >> chip->chip_shift);
chip->select_chip(mtd, chipnr);
/* Shift to get page */
page = (int)(to >> chip->page_shift);
/*
* Reset the chip. Some chips (like the Toshiba TC5832DC found in one
@ -2593,7 +2751,12 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
* if we don't do this. I have no clue why, but I seem to have 'fixed'
* it in the doc2000 driver in August 1999. dwmw2.
*/
chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
nand_reset(chip, chipnr);
chip->select_chip(mtd, chipnr);
/* Shift to get page */
page = (int)(to >> chip->page_shift);
/* Check, if it is write protected */
if (nand_check_wp(mtd)) {
@ -2763,14 +2926,6 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
status = chip->erase(mtd, page & chip->pagemask);
/*
* See if operation failed and additional status checks are
* available
*/
if ((status & NAND_STATUS_FAIL) && (chip->errstat))
status = chip->errstat(mtd, chip, FL_ERASING,
status, page);
/* See if block erase succeeded */
if (status & NAND_STATUS_FAIL) {
pr_debug("%s: failed erase, page 0x%08x\n",
@ -2972,6 +3127,8 @@ static void nand_set_defaults(struct nand_chip *chip, int busw)
init_waitqueue_head(&chip->controller->wq);
}
if (!chip->buf_align)
chip->buf_align = 1;
}
/* Sanitize ONFI strings so we can safely print them */
@ -3607,14 +3764,14 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,
int i, maf_idx;
u8 id_data[8];
/* Select the device */
chip->select_chip(mtd, 0);
/*
* Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
* after power-up.
*/
chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
nand_reset(chip, 0);
/* Select the device */
chip->select_chip(mtd, 0);
/* Send the command for reading device ID */
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
@ -3730,6 +3887,9 @@ ident_done:
chip->chip_shift += 32 - 1;
}
if (chip->chip_shift - chip->page_shift > 16)
chip->options |= NAND_ROW_ADDR_3;
chip->badblockbits = 8;
chip->erase = single_erase;
@ -3819,6 +3979,9 @@ static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip, int node)
if (ecc_step > 0)
chip->ecc.size = ecc_step;
if (fdt_getprop(blob, node, "nand-ecc-maximize", NULL))
chip->ecc.options |= NAND_ECC_MAXIMIZE;
return 0;
}
#else
@ -3866,13 +4029,31 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
return PTR_ERR(type);
}
/* Initialize the ->data_interface field. */
ret = nand_init_data_interface(chip);
if (ret)
return ret;
/*
* Setup the data interface correctly on the chip and controller side.
* This explicit call to nand_setup_data_interface() is only required
* for the first die, because nand_reset() has been called before
* ->data_interface and ->default_onfi_timing_mode were set.
* For the other dies, nand_reset() will automatically switch to the
* best mode for us.
*/
ret = nand_setup_data_interface(chip, 0);
if (ret)
return ret;
chip->select_chip(mtd, -1);
/* Check for a chip array */
for (i = 1; i < maxchips; i++) {
chip->select_chip(mtd, i);
/* See comment in nand_get_flash_type for reset */
chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
nand_reset(chip, i);
chip->select_chip(mtd, i);
/* Send the command for reading device ID */
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
/* Read manufacturer and device IDs */
@ -3897,6 +4078,226 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips,
}
EXPORT_SYMBOL(nand_scan_ident);
/**
* nand_check_ecc_caps - check the sanity of preset ECC settings
* @chip: nand chip info structure
* @caps: ECC caps info structure
* @oobavail: OOB size that the ECC engine can use
*
* When ECC step size and strength are already set, check if they are supported
* by the controller and the calculated ECC bytes fit within the chip's OOB.
* On success, the calculated ECC bytes is set.
*/
int nand_check_ecc_caps(struct nand_chip *chip,
const struct nand_ecc_caps *caps, int oobavail)
{
struct mtd_info *mtd = nand_to_mtd(chip);
const struct nand_ecc_step_info *stepinfo;
int preset_step = chip->ecc.size;
int preset_strength = chip->ecc.strength;
int nsteps, ecc_bytes;
int i, j;
if (WARN_ON(oobavail < 0))
return -EINVAL;
if (!preset_step || !preset_strength)
return -ENODATA;
nsteps = mtd->writesize / preset_step;
for (i = 0; i < caps->nstepinfos; i++) {
stepinfo = &caps->stepinfos[i];
if (stepinfo->stepsize != preset_step)
continue;
for (j = 0; j < stepinfo->nstrengths; j++) {
if (stepinfo->strengths[j] != preset_strength)
continue;
ecc_bytes = caps->calc_ecc_bytes(preset_step,
preset_strength);
if (WARN_ON_ONCE(ecc_bytes < 0))
return ecc_bytes;
if (ecc_bytes * nsteps > oobavail) {
pr_err("ECC (step, strength) = (%d, %d) does not fit in OOB",
preset_step, preset_strength);
return -ENOSPC;
}
chip->ecc.bytes = ecc_bytes;
return 0;
}
}
pr_err("ECC (step, strength) = (%d, %d) not supported on this controller",
preset_step, preset_strength);
return -ENOTSUPP;
}
EXPORT_SYMBOL_GPL(nand_check_ecc_caps);
/**
* nand_match_ecc_req - meet the chip's requirement with least ECC bytes
* @chip: nand chip info structure
* @caps: ECC engine caps info structure
* @oobavail: OOB size that the ECC engine can use
*
* If a chip's ECC requirement is provided, try to meet it with the least
* number of ECC bytes (i.e. with the largest number of OOB-free bytes).
* On success, the chosen ECC settings are set.
*/
int nand_match_ecc_req(struct nand_chip *chip,
const struct nand_ecc_caps *caps, int oobavail)
{
struct mtd_info *mtd = nand_to_mtd(chip);
const struct nand_ecc_step_info *stepinfo;
int req_step = chip->ecc_step_ds;
int req_strength = chip->ecc_strength_ds;
int req_corr, step_size, strength, nsteps, ecc_bytes, ecc_bytes_total;
int best_step, best_strength, best_ecc_bytes;
int best_ecc_bytes_total = INT_MAX;
int i, j;
if (WARN_ON(oobavail < 0))
return -EINVAL;
/* No information provided by the NAND chip */
if (!req_step || !req_strength)
return -ENOTSUPP;
/* number of correctable bits the chip requires in a page */
req_corr = mtd->writesize / req_step * req_strength;
for (i = 0; i < caps->nstepinfos; i++) {
stepinfo = &caps->stepinfos[i];
step_size = stepinfo->stepsize;
for (j = 0; j < stepinfo->nstrengths; j++) {
strength = stepinfo->strengths[j];
/*
* If both step size and strength are smaller than the
* chip's requirement, it is not easy to compare the
* resulted reliability.
*/
if (step_size < req_step && strength < req_strength)
continue;
if (mtd->writesize % step_size)
continue;
nsteps = mtd->writesize / step_size;
ecc_bytes = caps->calc_ecc_bytes(step_size, strength);
if (WARN_ON_ONCE(ecc_bytes < 0))
continue;
ecc_bytes_total = ecc_bytes * nsteps;
if (ecc_bytes_total > oobavail ||
strength * nsteps < req_corr)
continue;
/*
* We assume the best is to meet the chip's requrement
* with the least number of ECC bytes.
*/
if (ecc_bytes_total < best_ecc_bytes_total) {
best_ecc_bytes_total = ecc_bytes_total;
best_step = step_size;
best_strength = strength;
best_ecc_bytes = ecc_bytes;
}
}
}
if (best_ecc_bytes_total == INT_MAX)
return -ENOTSUPP;
chip->ecc.size = best_step;
chip->ecc.strength = best_strength;
chip->ecc.bytes = best_ecc_bytes;
return 0;
}
EXPORT_SYMBOL_GPL(nand_match_ecc_req);
/**
* nand_maximize_ecc - choose the max ECC strength available
* @chip: nand chip info structure
* @caps: ECC engine caps info structure
* @oobavail: OOB size that the ECC engine can use
*
* Choose the max ECC strength that is supported on the controller, and can fit
* within the chip's OOB. On success, the chosen ECC settings are set.
*/
int nand_maximize_ecc(struct nand_chip *chip,
const struct nand_ecc_caps *caps, int oobavail)
{
struct mtd_info *mtd = nand_to_mtd(chip);
const struct nand_ecc_step_info *stepinfo;
int step_size, strength, nsteps, ecc_bytes, corr;
int best_corr = 0;
int best_step = 0;
int best_strength, best_ecc_bytes;
int i, j;
if (WARN_ON(oobavail < 0))
return -EINVAL;
for (i = 0; i < caps->nstepinfos; i++) {
stepinfo = &caps->stepinfos[i];
step_size = stepinfo->stepsize;
/* If chip->ecc.size is already set, respect it */
if (chip->ecc.size && step_size != chip->ecc.size)
continue;
for (j = 0; j < stepinfo->nstrengths; j++) {
strength = stepinfo->strengths[j];
if (mtd->writesize % step_size)
continue;
nsteps = mtd->writesize / step_size;
ecc_bytes = caps->calc_ecc_bytes(step_size, strength);
if (WARN_ON_ONCE(ecc_bytes < 0))
continue;
if (ecc_bytes * nsteps > oobavail)
continue;
corr = strength * nsteps;
/*
* If the number of correctable bits is the same,
* bigger step_size has more reliability.
*/
if (corr > best_corr ||
(corr == best_corr && step_size > best_step)) {
best_corr = corr;
best_step = step_size;
best_strength = strength;
best_ecc_bytes = ecc_bytes;
}
}
}
if (!best_corr)
return -ENOTSUPP;
chip->ecc.size = best_step;
chip->ecc.strength = best_strength;
chip->ecc.bytes = best_ecc_bytes;
return 0;
}
EXPORT_SYMBOL_GPL(nand_maximize_ecc);
/*
* Check if the chip configuration meet the datasheet requirements.
@ -3931,6 +4332,26 @@ static bool nand_ecc_strength_good(struct mtd_info *mtd)
return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds;
}
static bool invalid_ecc_page_accessors(struct nand_chip *chip)
{
struct nand_ecc_ctrl *ecc = &chip->ecc;
if (nand_standard_page_accessors(ecc))
return false;
/*
* NAND_ECC_CUSTOM_PAGE_ACCESS flag is set, make sure the NAND
* controller driver implements all the page accessors because
* default helpers are not suitable when the core does not
* send the READ0/PAGEPROG commands.
*/
return (!ecc->read_page || !ecc->write_page ||
!ecc->read_page_raw || !ecc->write_page_raw ||
(NAND_HAS_SUBPAGE_READ(chip) && !ecc->read_subpage) ||
(NAND_HAS_SUBPAGE_WRITE(chip) && !ecc->write_subpage &&
ecc->hwctl && ecc->calculate));
}
/**
* nand_scan_tail - [NAND Interface] Scan for the NAND device
* @mtd: MTD device structure
@ -3950,6 +4371,11 @@ int nand_scan_tail(struct mtd_info *mtd)
BUG_ON((chip->bbt_options & NAND_BBT_NO_OOB_BBM) &&
!(chip->bbt_options & NAND_BBT_USE_FLASH));
if (invalid_ecc_page_accessors(chip)) {
pr_err("Invalid ECC page accessors setup\n");
return -EINVAL;
}
if (!(chip->options & NAND_OWN_BUFFERS)) {
nbuf = kzalloc(sizeof(struct nand_buffers), GFP_KERNEL);
chip->buffers = nbuf;

@ -12,228 +12,258 @@
#include <linux/kernel.h>
#include <linux/mtd/nand.h>
static const struct nand_sdr_timings onfi_sdr_timings[] = {
static const struct nand_data_interface onfi_sdr_timings[] = {
/* Mode 0 */
{
.tADL_min = 200000,
.tALH_min = 20000,
.tALS_min = 50000,
.tAR_min = 25000,
.tCEA_max = 100000,
.tCEH_min = 20000,
.tCH_min = 20000,
.tCHZ_max = 100000,
.tCLH_min = 20000,
.tCLR_min = 20000,
.tCLS_min = 50000,
.tCOH_min = 0,
.tCS_min = 70000,
.tDH_min = 20000,
.tDS_min = 40000,
.tFEAT_max = 1000000,
.tIR_min = 10000,
.tITC_max = 1000000,
.tRC_min = 100000,
.tREA_max = 40000,
.tREH_min = 30000,
.tRHOH_min = 0,
.tRHW_min = 200000,
.tRHZ_max = 200000,
.tRLOH_min = 0,
.tRP_min = 50000,
.tRST_max = 250000000000ULL,
.tWB_max = 200000,
.tRR_min = 40000,
.tWC_min = 100000,
.tWH_min = 30000,
.tWHR_min = 120000,
.tWP_min = 50000,
.tWW_min = 100000,
.type = NAND_SDR_IFACE,
.timings.sdr = {
.tCCS_min = 500000,
.tR_max = 200000000,
.tADL_min = 400000,
.tALH_min = 20000,
.tALS_min = 50000,
.tAR_min = 25000,
.tCEA_max = 100000,
.tCEH_min = 20000,
.tCH_min = 20000,
.tCHZ_max = 100000,
.tCLH_min = 20000,
.tCLR_min = 20000,
.tCLS_min = 50000,
.tCOH_min = 0,
.tCS_min = 70000,
.tDH_min = 20000,
.tDS_min = 40000,
.tFEAT_max = 1000000,
.tIR_min = 10000,
.tITC_max = 1000000,
.tRC_min = 100000,
.tREA_max = 40000,
.tREH_min = 30000,
.tRHOH_min = 0,
.tRHW_min = 200000,
.tRHZ_max = 200000,
.tRLOH_min = 0,
.tRP_min = 50000,
.tRR_min = 40000,
.tRST_max = 250000000000ULL,
.tWB_max = 200000,
.tWC_min = 100000,
.tWH_min = 30000,
.tWHR_min = 120000,
.tWP_min = 50000,
.tWW_min = 100000,
},
},
/* Mode 1 */
{
.tADL_min = 100000,
.tALH_min = 10000,
.tALS_min = 25000,
.tAR_min = 10000,
.tCEA_max = 45000,
.tCEH_min = 20000,
.tCH_min = 10000,
.tCHZ_max = 50000,
.tCLH_min = 10000,
.tCLR_min = 10000,
.tCLS_min = 25000,
.tCOH_min = 15000,
.tCS_min = 35000,
.tDH_min = 10000,
.tDS_min = 20000,
.tFEAT_max = 1000000,
.tIR_min = 0,
.tITC_max = 1000000,
.tRC_min = 50000,
.tREA_max = 30000,
.tREH_min = 15000,
.tRHOH_min = 15000,
.tRHW_min = 100000,
.tRHZ_max = 100000,
.tRLOH_min = 0,
.tRP_min = 25000,
.tRR_min = 20000,
.tRST_max = 500000000,
.tWB_max = 100000,
.tWC_min = 45000,
.tWH_min = 15000,
.tWHR_min = 80000,
.tWP_min = 25000,
.tWW_min = 100000,
.type = NAND_SDR_IFACE,
.timings.sdr = {
.tCCS_min = 500000,
.tR_max = 200000000,
.tADL_min = 400000,
.tALH_min = 10000,
.tALS_min = 25000,
.tAR_min = 10000,
.tCEA_max = 45000,
.tCEH_min = 20000,
.tCH_min = 10000,
.tCHZ_max = 50000,
.tCLH_min = 10000,
.tCLR_min = 10000,
.tCLS_min = 25000,
.tCOH_min = 15000,
.tCS_min = 35000,
.tDH_min = 10000,
.tDS_min = 20000,
.tFEAT_max = 1000000,
.tIR_min = 0,
.tITC_max = 1000000,
.tRC_min = 50000,
.tREA_max = 30000,
.tREH_min = 15000,
.tRHOH_min = 15000,
.tRHW_min = 100000,
.tRHZ_max = 100000,
.tRLOH_min = 0,
.tRP_min = 25000,
.tRR_min = 20000,
.tRST_max = 500000000,
.tWB_max = 100000,
.tWC_min = 45000,
.tWH_min = 15000,
.tWHR_min = 80000,
.tWP_min = 25000,
.tWW_min = 100000,
},
},
/* Mode 2 */
{
.tADL_min = 100000,
.tALH_min = 10000,
.tALS_min = 15000,
.tAR_min = 10000,
.tCEA_max = 30000,
.tCEH_min = 20000,
.tCH_min = 10000,
.tCHZ_max = 50000,
.tCLH_min = 10000,
.tCLR_min = 10000,
.tCLS_min = 15000,
.tCOH_min = 15000,
.tCS_min = 25000,
.tDH_min = 5000,
.tDS_min = 15000,
.tFEAT_max = 1000000,
.tIR_min = 0,
.tITC_max = 1000000,
.tRC_min = 35000,
.tREA_max = 25000,
.tREH_min = 15000,
.tRHOH_min = 15000,
.tRHW_min = 100000,
.tRHZ_max = 100000,
.tRLOH_min = 0,
.tRR_min = 20000,
.tRST_max = 500000000,
.tWB_max = 100000,
.tRP_min = 17000,
.tWC_min = 35000,
.tWH_min = 15000,
.tWHR_min = 80000,
.tWP_min = 17000,
.tWW_min = 100000,
.type = NAND_SDR_IFACE,
.timings.sdr = {
.tCCS_min = 500000,
.tR_max = 200000000,
.tADL_min = 400000,
.tALH_min = 10000,
.tALS_min = 15000,
.tAR_min = 10000,
.tCEA_max = 30000,
.tCEH_min = 20000,
.tCH_min = 10000,
.tCHZ_max = 50000,
.tCLH_min = 10000,
.tCLR_min = 10000,
.tCLS_min = 15000,
.tCOH_min = 15000,
.tCS_min = 25000,
.tDH_min = 5000,
.tDS_min = 15000,
.tFEAT_max = 1000000,
.tIR_min = 0,
.tITC_max = 1000000,
.tRC_min = 35000,
.tREA_max = 25000,
.tREH_min = 15000,
.tRHOH_min = 15000,
.tRHW_min = 100000,
.tRHZ_max = 100000,
.tRLOH_min = 0,
.tRR_min = 20000,
.tRST_max = 500000000,
.tWB_max = 100000,
.tRP_min = 17000,
.tWC_min = 35000,
.tWH_min = 15000,
.tWHR_min = 80000,
.tWP_min = 17000,
.tWW_min = 100000,
},
},
/* Mode 3 */
{
.tADL_min = 100000,
.tALH_min = 5000,
.tALS_min = 10000,
.tAR_min = 10000,
.tCEA_max = 25000,
.tCEH_min = 20000,
.tCH_min = 5000,
.tCHZ_max = 50000,
.tCLH_min = 5000,
.tCLR_min = 10000,
.tCLS_min = 10000,
.tCOH_min = 15000,
.tCS_min = 25000,
.tDH_min = 5000,
.tDS_min = 10000,
.tFEAT_max = 1000000,
.tIR_min = 0,
.tITC_max = 1000000,
.tRC_min = 30000,
.tREA_max = 20000,
.tREH_min = 10000,
.tRHOH_min = 15000,
.tRHW_min = 100000,
.tRHZ_max = 100000,
.tRLOH_min = 0,
.tRP_min = 15000,
.tRR_min = 20000,
.tRST_max = 500000000,
.tWB_max = 100000,
.tWC_min = 30000,
.tWH_min = 10000,
.tWHR_min = 80000,
.tWP_min = 15000,
.tWW_min = 100000,
.type = NAND_SDR_IFACE,
.timings.sdr = {
.tCCS_min = 500000,
.tR_max = 200000000,
.tADL_min = 400000,
.tALH_min = 5000,
.tALS_min = 10000,
.tAR_min = 10000,
.tCEA_max = 25000,
.tCEH_min = 20000,
.tCH_min = 5000,
.tCHZ_max = 50000,
.tCLH_min = 5000,
.tCLR_min = 10000,
.tCLS_min = 10000,
.tCOH_min = 15000,
.tCS_min = 25000,
.tDH_min = 5000,
.tDS_min = 10000,
.tFEAT_max = 1000000,
.tIR_min = 0,
.tITC_max = 1000000,
.tRC_min = 30000,
.tREA_max = 20000,
.tREH_min = 10000,
.tRHOH_min = 15000,
.tRHW_min = 100000,
.tRHZ_max = 100000,
.tRLOH_min = 0,
.tRP_min = 15000,
.tRR_min = 20000,
.tRST_max = 500000000,
.tWB_max = 100000,
.tWC_min = 30000,
.tWH_min = 10000,
.tWHR_min = 80000,
.tWP_min = 15000,
.tWW_min = 100000,
},
},
/* Mode 4 */
{
.tADL_min = 70000,
.tALH_min = 5000,
.tALS_min = 10000,
.tAR_min = 10000,
.tCEA_max = 25000,
.tCEH_min = 20000,
.tCH_min = 5000,
.tCHZ_max = 30000,
.tCLH_min = 5000,
.tCLR_min = 10000,
.tCLS_min = 10000,
.tCOH_min = 15000,
.tCS_min = 20000,
.tDH_min = 5000,
.tDS_min = 10000,
.tFEAT_max = 1000000,
.tIR_min = 0,
.tITC_max = 1000000,
.tRC_min = 25000,
.tREA_max = 20000,
.tREH_min = 10000,
.tRHOH_min = 15000,
.tRHW_min = 100000,
.tRHZ_max = 100000,
.tRLOH_min = 5000,
.tRP_min = 12000,
.tRR_min = 20000,
.tRST_max = 500000000,
.tWB_max = 100000,
.tWC_min = 25000,
.tWH_min = 10000,
.tWHR_min = 80000,
.tWP_min = 12000,
.tWW_min = 100000,
.type = NAND_SDR_IFACE,
.timings.sdr = {
.tCCS_min = 500000,
.tR_max = 200000000,
.tADL_min = 400000,
.tALH_min = 5000,
.tALS_min = 10000,
.tAR_min = 10000,
.tCEA_max = 25000,
.tCEH_min = 20000,
.tCH_min = 5000,
.tCHZ_max = 30000,
.tCLH_min = 5000,
.tCLR_min = 10000,
.tCLS_min = 10000,
.tCOH_min = 15000,
.tCS_min = 20000,
.tDH_min = 5000,
.tDS_min = 10000,
.tFEAT_max = 1000000,
.tIR_min = 0,
.tITC_max = 1000000,
.tRC_min = 25000,
.tREA_max = 20000,
.tREH_min = 10000,
.tRHOH_min = 15000,
.tRHW_min = 100000,
.tRHZ_max = 100000,
.tRLOH_min = 5000,
.tRP_min = 12000,
.tRR_min = 20000,
.tRST_max = 500000000,
.tWB_max = 100000,
.tWC_min = 25000,
.tWH_min = 10000,
.tWHR_min = 80000,
.tWP_min = 12000,
.tWW_min = 100000,
},
},
/* Mode 5 */
{
.tADL_min = 70000,
.tALH_min = 5000,
.tALS_min = 10000,
.tAR_min = 10000,
.tCEA_max = 25000,
.tCEH_min = 20000,
.tCH_min = 5000,
.tCHZ_max = 30000,
.tCLH_min = 5000,
.tCLR_min = 10000,
.tCLS_min = 10000,
.tCOH_min = 15000,
.tCS_min = 15000,
.tDH_min = 5000,
.tDS_min = 7000,
.tFEAT_max = 1000000,
.tIR_min = 0,
.tITC_max = 1000000,
.tRC_min = 20000,
.tREA_max = 16000,
.tREH_min = 7000,
.tRHOH_min = 15000,
.tRHW_min = 100000,
.tRHZ_max = 100000,
.tRLOH_min = 5000,
.tRP_min = 10000,
.tRR_min = 20000,
.tRST_max = 500000000,
.tWB_max = 100000,
.tWC_min = 20000,
.tWH_min = 7000,
.tWHR_min = 80000,
.tWP_min = 10000,
.tWW_min = 100000,
.type = NAND_SDR_IFACE,
.timings.sdr = {
.tCCS_min = 500000,
.tR_max = 200000000,
.tADL_min = 400000,
.tALH_min = 5000,
.tALS_min = 10000,
.tAR_min = 10000,
.tCEA_max = 25000,
.tCEH_min = 20000,
.tCH_min = 5000,
.tCHZ_max = 30000,
.tCLH_min = 5000,
.tCLR_min = 10000,
.tCLS_min = 10000,
.tCOH_min = 15000,
.tCS_min = 15000,
.tDH_min = 5000,
.tDS_min = 7000,
.tFEAT_max = 1000000,
.tIR_min = 0,
.tITC_max = 1000000,
.tRC_min = 20000,
.tREA_max = 16000,
.tREH_min = 7000,
.tRHOH_min = 15000,
.tRHW_min = 100000,
.tRHZ_max = 100000,
.tRLOH_min = 5000,
.tRP_min = 10000,
.tRR_min = 20000,
.tRST_max = 500000000,
.tWB_max = 100000,
.tWC_min = 20000,
.tWH_min = 7000,
.tWHR_min = 80000,
.tWP_min = 10000,
.tWW_min = 100000,
},
},
};
@ -247,6 +277,58 @@ const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode)
if (mode < 0 || mode >= ARRAY_SIZE(onfi_sdr_timings))
return ERR_PTR(-EINVAL);
return &onfi_sdr_timings[mode];
return &onfi_sdr_timings[mode].timings.sdr;
}
EXPORT_SYMBOL(onfi_async_timing_mode_to_sdr_timings);
/**
* onfi_init_data_interface - [NAND Interface] Initialize a data interface from
* given ONFI mode
* @iface: The data interface to be initialized
* @mode: The ONFI timing mode
*/
int onfi_init_data_interface(struct nand_chip *chip,
struct nand_data_interface *iface,
enum nand_data_interface_type type,
int timing_mode)
{
if (type != NAND_SDR_IFACE)
return -EINVAL;
if (timing_mode < 0 || timing_mode >= ARRAY_SIZE(onfi_sdr_timings))
return -EINVAL;
*iface = onfi_sdr_timings[timing_mode];
/*
* Initialize timings that cannot be deduced from timing mode:
* tR, tPROG, tCCS, ...
* These information are part of the ONFI parameter page.
*/
if (chip->onfi_version) {
struct nand_onfi_params *params = &chip->onfi_params;
struct nand_sdr_timings *timings = &iface->timings.sdr;
/* microseconds -> picoseconds */
timings->tPROG_max = 1000000ULL * le16_to_cpu(params->t_prog);
timings->tBERS_max = 1000000ULL * le16_to_cpu(params->t_bers);
timings->tR_max = 1000000ULL * le16_to_cpu(params->t_r);
/* nanoseconds -> picoseconds */
timings->tCCS_min = 1000UL * le16_to_cpu(params->t_ccs);
}
return 0;
}
EXPORT_SYMBOL(onfi_init_data_interface);
/**
* nand_get_default_data_interface - [NAND Interface] Retrieve NAND
* data interface for mode 0. This is used as default timing after
* reset.
*/
const struct nand_data_interface *nand_get_default_data_interface(void)
{
return &onfi_sdr_timings[0];
}
EXPORT_SYMBOL(nand_get_default_data_interface);

@ -71,13 +71,8 @@
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_ONFI_DETECTION
#define CONFIG_NAND_DENALI_ECC_SIZE 1024
#define CONFIG_SYS_NAND_REGS_BASE 0x68100000
#define CONFIG_SYS_NAND_DATA_BASE 0x68000000
#define CONFIG_SYS_NAND_USE_FLASH_BBT
#define CONFIG_SYS_NAND_BAD_BLOCK_POS 0
/* SD/MMC */

@ -0,0 +1,18 @@
/*
* Copyright (C) 2017 Socionext Inc.
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
*/
#ifndef _DT_BINDINGS_GPIO_UNIPHIER_H
#define _DT_BINDINGS_GPIO_UNIPHIER_H
#define UNIPHIER_GPIO_LINES_PER_BANK 8
#define UNIPHIER_GPIO_IRQ_OFFSET ((UNIPHIER_GPIO_LINES_PER_BANK) * 15)
#define UNIPHIER_GPIO_PORT(bank, line) \
((UNIPHIER_GPIO_LINES_PER_BANK) * (bank) + (line))
#define UNIPHIER_GPIO_IRQ(n) ((UNIPHIER_GPIO_IRQ_OFFSET) + (n))
#endif /* _DT_BINDINGS_GPIO_UNIPHIER_H */

@ -5,9 +5,16 @@
#include <asm-generic/bitsperlong.h>
#include <linux/compiler.h>
#ifdef __KERNEL__
#define BIT(nr) (1UL << (nr))
#define BIT_ULL(nr) (1ULL << (nr))
#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
#define BIT_ULL_MASK(nr) (1ULL << ((nr) % BITS_PER_LONG_LONG))
#define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG)
#define BITS_PER_BYTE 8
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
#endif
/*
* Create a contiguous bitmask starting at bit position @l and ending at

@ -103,6 +103,36 @@ struct mtd_oob_ops {
#else
#define MTD_MAX_ECCPOS_ENTRIES_LARGE 680
#endif
/**
* struct mtd_oob_region - oob region definition
* @offset: region offset
* @length: region length
*
* This structure describes a region of the OOB area, and is used
* to retrieve ECC or free bytes sections.
* Each section is defined by an offset within the OOB area and a
* length.
*/
struct mtd_oob_region {
u32 offset;
u32 length;
};
/*
* struct mtd_ooblayout_ops - NAND OOB layout operations
* @ecc: function returning an ECC region in the OOB area.
* Should return -ERANGE if %section exceeds the total number of
* ECC sections.
* @free: function returning a free region in the OOB area.
* Should return -ERANGE if %section exceeds the total number of
* free sections.
*/
struct mtd_ooblayout_ops {
int (*ecc)(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobecc);
int (*free)(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobfree);
};
/*
* Internal ECC layout control structure. For historical reasons, there is a
@ -179,6 +209,9 @@ struct mtd_info {
#endif
int index;
/* OOB layout description */
const struct mtd_ooblayout_ops *ooblayout;
/* ECC layout structure pointer - read only! */
struct nand_ecclayout *ecclayout;
@ -278,6 +311,30 @@ struct mtd_info {
int usecount;
};
int mtd_ooblayout_ecc(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobecc);
int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte,
int *section,
struct mtd_oob_region *oobregion);
int mtd_ooblayout_get_eccbytes(struct mtd_info *mtd, u8 *eccbuf,
const u8 *oobbuf, int start, int nbytes);
int mtd_ooblayout_set_eccbytes(struct mtd_info *mtd, const u8 *eccbuf,
u8 *oobbuf, int start, int nbytes);
int mtd_ooblayout_free(struct mtd_info *mtd, int section,
struct mtd_oob_region *oobfree);
int mtd_ooblayout_get_databytes(struct mtd_info *mtd, u8 *databuf,
const u8 *oobbuf, int start, int nbytes);
int mtd_ooblayout_set_databytes(struct mtd_info *mtd, const u8 *databuf,
u8 *oobbuf, int start, int nbytes);
int mtd_ooblayout_count_freebytes(struct mtd_info *mtd);
int mtd_ooblayout_count_eccbytes(struct mtd_info *mtd);
static inline void mtd_set_ooblayout(struct mtd_info *mtd,
const struct mtd_ooblayout_ops *ooblayout)
{
mtd->ooblayout = ooblayout;
}
static inline int mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops)
{
return ops->mode == MTD_OPS_AUTO_OOB ? mtd->oobavail : mtd->oobsize;

@ -28,20 +28,20 @@ struct nand_flash_dev;
struct device_node;
/* Scan and identify a NAND device */
extern int nand_scan(struct mtd_info *mtd, int max_chips);
int nand_scan(struct mtd_info *mtd, int max_chips);
/*
* Separate phases of nand_scan(), allowing board driver to intervene
* and override command or ECC setup according to flash type.
*/
extern int nand_scan_ident(struct mtd_info *mtd, int max_chips,
int nand_scan_ident(struct mtd_info *mtd, int max_chips,
struct nand_flash_dev *table);
extern int nand_scan_tail(struct mtd_info *mtd);
int nand_scan_tail(struct mtd_info *mtd);
/* Free resources held by the NAND device */
extern void nand_release(struct mtd_info *mtd);
void nand_release(struct mtd_info *mtd);
/* Internal helper for board drivers which need to override command function */
extern void nand_wait_ready(struct mtd_info *mtd);
void nand_wait_ready(struct mtd_info *mtd);
/*
* This constant declares the max. oobsize / page, which
@ -124,6 +124,8 @@ extern void nand_wait_ready(struct mtd_info *mtd);
#define NAND_STATUS_READY 0x40
#define NAND_STATUS_WP 0x80
#define NAND_DATA_IFACE_CHECK_ONLY -1
/*
* Constants for ECC_MODES
*/
@ -153,6 +155,13 @@ typedef enum {
* pages and you want to rely on the default implementation.
*/
#define NAND_ECC_GENERIC_ERASED_CHECK BIT(0)
#define NAND_ECC_MAXIMIZE BIT(1)
/*
* If your controller already sends the required NAND commands when
* reading or writing a page, then the framework is not supposed to
* send READ0 and SEQIN/PAGEPROG respectively.
*/
#define NAND_ECC_CUSTOM_PAGE_ACCESS BIT(2)
/* Bit mask for flags passed to do_nand_read_ecc */
#define NAND_GET_DEVICE 0x80
@ -195,12 +204,16 @@ typedef enum {
*/
#define NAND_NEED_SCRAMBLING 0x00002000
/* Device needs 3rd row address cycle */
#define NAND_ROW_ADDR_3 0x00004000
/* Options valid for Samsung large page devices */
#define NAND_SAMSUNG_LP_OPTIONS NAND_CACHEPRG
/* Macros to identify the above */
#define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
#define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ))
#define NAND_HAS_SUBPAGE_WRITE(chip) !((chip)->options & NAND_NO_SUBPAGE_WRITE)
/* Non chip related options */
/* This option skips the bbt scan during initialization. */
@ -478,6 +491,44 @@ struct nand_hw_control {
};
/**
* struct nand_ecc_step_info - ECC step information of ECC engine
* @stepsize: data bytes per ECC step
* @strengths: array of supported strengths
* @nstrengths: number of supported strengths
*/
struct nand_ecc_step_info {
int stepsize;
const int *strengths;
int nstrengths;
};
/**
* struct nand_ecc_caps - capability of ECC engine
* @stepinfos: array of ECC step information
* @nstepinfos: number of ECC step information
* @calc_ecc_bytes: driver's hook to calculate ECC bytes per step
*/
struct nand_ecc_caps {
const struct nand_ecc_step_info *stepinfos;
int nstepinfos;
int (*calc_ecc_bytes)(int step_size, int strength);
};
/* a shorthand to generate struct nand_ecc_caps with only one ECC stepsize */
#define NAND_ECC_CAPS_SINGLE(__name, __calc, __step, ...) \
static const int __name##_strengths[] = { __VA_ARGS__ }; \
static const struct nand_ecc_step_info __name##_stepinfo = { \
.stepsize = __step, \
.strengths = __name##_strengths, \
.nstrengths = ARRAY_SIZE(__name##_strengths), \
}; \
static const struct nand_ecc_caps __name = { \
.stepinfos = &__name##_stepinfo, \
.nstepinfos = 1, \
.calc_ecc_bytes = __calc, \
}
/**
* struct nand_ecc_ctrl - Control structure for ECC
* @mode: ECC mode
* @steps: number of ECC steps per page
@ -567,6 +618,11 @@ struct nand_ecc_ctrl {
int page);
};
static inline int nand_standard_page_accessors(struct nand_ecc_ctrl *ecc)
{
return !(ecc->options & NAND_ECC_CUSTOM_PAGE_ACCESS);
}
/**
* struct nand_buffers - buffer structure for read/write
* @ecccalc: buffer pointer for calculated ECC, size is oobsize.
@ -584,6 +640,131 @@ struct nand_buffers {
};
/**
* struct nand_sdr_timings - SDR NAND chip timings
*
* This struct defines the timing requirements of a SDR NAND chip.
* These information can be found in every NAND datasheets and the timings
* meaning are described in the ONFI specifications:
* www.onfi.org/~/media/ONFI/specs/onfi_3_1_spec.pdf (chapter 4.15 Timing
* Parameters)
*
* All these timings are expressed in picoseconds.
*
* @tBERS_max: Block erase time
* @tCCS_min: Change column setup time
* @tPROG_max: Page program time
* @tR_max: Page read time
* @tALH_min: ALE hold time
* @tADL_min: ALE to data loading time
* @tALS_min: ALE setup time
* @tAR_min: ALE to RE# delay
* @tCEA_max: CE# access time
* @tCEH_min: CE# high hold time
* @tCH_min: CE# hold time
* @tCHZ_max: CE# high to output hi-Z
* @tCLH_min: CLE hold time
* @tCLR_min: CLE to RE# delay
* @tCLS_min: CLE setup time
* @tCOH_min: CE# high to output hold
* @tCS_min: CE# setup time
* @tDH_min: Data hold time
* @tDS_min: Data setup time
* @tFEAT_max: Busy time for Set Features and Get Features
* @tIR_min: Output hi-Z to RE# low
* @tITC_max: Interface and Timing Mode Change time
* @tRC_min: RE# cycle time
* @tREA_max: RE# access time
* @tREH_min: RE# high hold time
* @tRHOH_min: RE# high to output hold
* @tRHW_min: RE# high to WE# low
* @tRHZ_max: RE# high to output hi-Z
* @tRLOH_min: RE# low to output hold
* @tRP_min: RE# pulse width
* @tRR_min: Ready to RE# low (data only)
* @tRST_max: Device reset time, measured from the falling edge of R/B# to the
* rising edge of R/B#.
* @tWB_max: WE# high to SR[6] low
* @tWC_min: WE# cycle time
* @tWH_min: WE# high hold time
* @tWHR_min: WE# high to RE# low
* @tWP_min: WE# pulse width
* @tWW_min: WP# transition to WE# low
*/
struct nand_sdr_timings {
u64 tBERS_max;
u32 tCCS_min;
u64 tPROG_max;
u64 tR_max;
u32 tALH_min;
u32 tADL_min;
u32 tALS_min;
u32 tAR_min;
u32 tCEA_max;
u32 tCEH_min;
u32 tCH_min;
u32 tCHZ_max;
u32 tCLH_min;
u32 tCLR_min;
u32 tCLS_min;
u32 tCOH_min;
u32 tCS_min;
u32 tDH_min;
u32 tDS_min;
u32 tFEAT_max;
u32 tIR_min;
u32 tITC_max;
u32 tRC_min;
u32 tREA_max;
u32 tREH_min;
u32 tRHOH_min;
u32 tRHW_min;
u32 tRHZ_max;
u32 tRLOH_min;
u32 tRP_min;
u32 tRR_min;
u64 tRST_max;
u32 tWB_max;
u32 tWC_min;
u32 tWH_min;
u32 tWHR_min;
u32 tWP_min;
u32 tWW_min;
};
/**
* enum nand_data_interface_type - NAND interface timing type
* @NAND_SDR_IFACE: Single Data Rate interface
*/
enum nand_data_interface_type {
NAND_SDR_IFACE,
};
/**
* struct nand_data_interface - NAND interface timing
* @type: type of the timing
* @timings: The timing, type according to @type
*/
struct nand_data_interface {
enum nand_data_interface_type type;
union {
struct nand_sdr_timings sdr;
} timings;
};
/**
* nand_get_sdr_timings - get SDR timing from data interface
* @conf: The data interface
*/
static inline const struct nand_sdr_timings *
nand_get_sdr_timings(const struct nand_data_interface *conf)
{
if (conf->type != NAND_SDR_IFACE)
return ERR_PTR(-EINVAL);
return &conf->timings.sdr;
}
/**
* struct nand_chip - NAND Private Flash Chip Data
* @mtd: MTD device registered to the MTD framework
* @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the
@ -614,6 +795,7 @@ struct nand_buffers {
* setting the read-retry mode. Mostly needed for MLC NAND.
* @ecc: [BOARDSPECIFIC] ECC control structure
* @buffers: buffer structure for read/write
* @buf_align: minimum buffer alignment required by a platform
* @hwcontrol: platform-specific hardware control structure
* @erase: [REPLACEABLE] erase function
* @scan_bbt: [REPLACEABLE] function to scan bad block table
@ -646,10 +828,9 @@ struct nand_buffers {
* also from the datasheet. It is the recommended ECC step
* size, if known; if unknown, set to zero.
* @onfi_timing_mode_default: [INTERN] default ONFI timing mode. This field is
* either deduced from the datasheet if the NAND
* chip is not ONFI compliant or set to 0 if it is
* (an ONFI chip is always configured in mode 0
* after a NAND reset)
* set to the actually used ONFI mode if the chip is
* ONFI compliant or deduced from the datasheet if
* the NAND chip is not ONFI compliant.
* @numchips: [INTERN] number of physical chips
* @chipsize: [INTERN] the size of one chip for multichip arrays
* @pagemask: [INTERN] page number mask = number of (pages / chip) - 1
@ -669,6 +850,10 @@ struct nand_buffers {
* @read_retries: [INTERN] the number of read retry modes supported
* @onfi_set_features: [REPLACEABLE] set the features for ONFI nand
* @onfi_get_features: [REPLACEABLE] get the features for ONFI nand
* @setup_data_interface: [OPTIONAL] setup the data interface and timing. If
* chipnr is set to %NAND_DATA_IFACE_CHECK_ONLY this
* means the configuration should not be applied but
* only checked.
* @bbt: [INTERN] bad block table pointer
* @bbt_td: [REPLACEABLE] bad block table descriptor for flash
* lookup.
@ -679,9 +864,6 @@ struct nand_buffers {
* structure which is shared among multiple independent
* devices.
* @priv: [OPTIONAL] pointer to private chip data
* @errstat: [OPTIONAL] hardware specific function to perform
* additional error status checks (determine if errors are
* correctable).
* @write_page: [REPLACEABLE] High-level page write function
*/
@ -707,16 +889,17 @@ struct nand_chip {
int(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);
int (*erase)(struct mtd_info *mtd, int page);
int (*scan_bbt)(struct mtd_info *mtd);
int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state,
int status, int page);
int (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
uint32_t offset, int data_len, const uint8_t *buf,
int oob_required, int page, int cached, int raw);
int oob_required, int page, int raw);
int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip,
int feature_addr, uint8_t *subfeature_para);
int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip,
int feature_addr, uint8_t *subfeature_para);
int (*setup_read_retry)(struct mtd_info *mtd, int retry_mode);
int (*setup_data_interface)(struct mtd_info *mtd, int chipnr,
const struct nand_data_interface *conf);
int chip_delay;
unsigned int options;
@ -741,11 +924,11 @@ struct nand_chip {
int onfi_version;
int jedec_version;
#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
struct nand_onfi_params onfi_params;
#endif
struct nand_jedec_params jedec_params;
struct nand_data_interface *data_interface;
int read_retries;
flstate_t state;
@ -756,6 +939,7 @@ struct nand_chip {
struct nand_ecc_ctrl ecc;
struct nand_buffers *buffers;
unsigned long buf_align;
struct nand_hw_control hwcontrol;
uint8_t *bbt;
@ -900,13 +1084,13 @@ struct nand_manufacturers {
extern struct nand_flash_dev nand_flash_ids[];
extern struct nand_manufacturers nand_manuf_ids[];
extern int nand_default_bbt(struct mtd_info *mtd);
extern int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs);
extern int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs);
extern int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt);
extern int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
int nand_default_bbt(struct mtd_info *mtd);
int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs);
int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs);
int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt);
int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr,
int allowbbt);
extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, uint8_t *buf);
/*
@ -1001,8 +1185,28 @@ static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
return ONFI_TIMING_MODE_UNKNOWN;
return le16_to_cpu(chip->onfi_params.src_sync_timing_mode);
}
#else
static inline int onfi_feature(struct nand_chip *chip)
{
return 0;
}
static inline int onfi_get_async_timing_mode(struct nand_chip *chip)
{
return ONFI_TIMING_MODE_UNKNOWN;
}
static inline int onfi_get_sync_timing_mode(struct nand_chip *chip)
{
return ONFI_TIMING_MODE_UNKNOWN;
}
#endif
int onfi_init_data_interface(struct nand_chip *chip,
struct nand_data_interface *iface,
enum nand_data_interface_type type,
int timing_mode);
/*
* Check if it is a SLC nand.
* The !nand_is_slc() can be used to check the MLC/TLC nand chips.
@ -1045,60 +1249,26 @@ void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len);
void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len);
uint8_t nand_read_byte(struct mtd_info *mtd);
/*
* struct nand_sdr_timings - SDR NAND chip timings
*
* This struct defines the timing requirements of a SDR NAND chip.
* These informations can be found in every NAND datasheets and the timings
* meaning are described in the ONFI specifications:
* www.onfi.org/~/media/ONFI/specs/onfi_3_1_spec.pdf (chapter 4.15 Timing
* Parameters)
*
* All these timings are expressed in picoseconds.
*/
struct nand_sdr_timings {
u32 tALH_min;
u32 tADL_min;
u32 tALS_min;
u32 tAR_min;
u32 tCEA_max;
u32 tCEH_min;
u32 tCH_min;
u32 tCHZ_max;
u32 tCLH_min;
u32 tCLR_min;
u32 tCLS_min;
u32 tCOH_min;
u32 tCS_min;
u32 tDH_min;
u32 tDS_min;
u32 tFEAT_max;
u32 tIR_min;
u32 tITC_max;
u32 tRC_min;
u32 tREA_max;
u32 tREH_min;
u32 tRHOH_min;
u32 tRHW_min;
u32 tRHZ_max;
u32 tRLOH_min;
u32 tRP_min;
u32 tRR_min;
u64 tRST_max;
u32 tWB_max;
u32 tWC_min;
u32 tWH_min;
u32 tWHR_min;
u32 tWP_min;
u32 tWW_min;
};
/* get timing characteristics from ONFI timing mode. */
const struct nand_sdr_timings *onfi_async_timing_mode_to_sdr_timings(int mode);
/* get data interface from ONFI timing mode 0, used after reset. */
const struct nand_data_interface *nand_get_default_data_interface(void);
int nand_check_erased_ecc_chunk(void *data, int datalen,
void *ecc, int ecclen,
void *extraoob, int extraooblen,
int threshold);
int nand_check_ecc_caps(struct nand_chip *chip,
const struct nand_ecc_caps *caps, int oobavail);
int nand_match_ecc_req(struct nand_chip *chip,
const struct nand_ecc_caps *caps, int oobavail);
int nand_maximize_ecc(struct nand_chip *chip,
const struct nand_ecc_caps *caps, int oobavail);
/* Reset and initialize a NAND device */
int nand_reset(struct nand_chip *chip, int chipnr);
#endif /* __LINUX_MTD_NAND_H */

@ -10,12 +10,10 @@
#ifndef __LIN_COMPAT_H__
#define __LIN_COMPAT_H__
#include <linux/bitops.h>
#include <linux/compat.h>
/* common */
#define BITS_PER_BYTE 8
#define BITS_TO_LONGS(nr) \
DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
#define DECLARE_BITMAP(name, bits) \
unsigned long name[BITS_TO_LONGS(bits)]

Loading…
Cancel
Save