summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kconfig2
-rw-r--r--Makefile1
-rw-r--r--arch/arm/dts/Makefile3
-rw-r--r--arch/arm/dts/tegra20-acer-a500-picasso.dts4
-rw-r--r--arch/arm/dts/tegra20-asus-transformer.dtsi4
-rw-r--r--arch/arm/dts/tegra20-lg-star.dts4
-rw-r--r--arch/arm/dts/tegra20-motorola-mot.dtsi4
-rw-r--r--arch/arm/dts/tegra20-samsung-bose.dts119
-rw-r--r--arch/arm/dts/tegra20-samsung-n1-common.dtsi428
-rw-r--r--arch/arm/dts/tegra20-samsung-n1.dts184
-rw-r--r--arch/arm/dts/tegra20.dtsi29
-rw-r--r--arch/arm/dts/tegra30-asus-grouper-common.dtsi4
-rw-r--r--arch/arm/dts/tegra30-asus-p1801-t.dts4
-rw-r--r--arch/arm/dts/tegra30-asus-tf600t.dts4
-rw-r--r--arch/arm/dts/tegra30-asus-transformer.dtsi4
-rw-r--r--arch/arm/dts/tegra30-htc-endeavoru.dts4
-rw-r--r--arch/arm/dts/tegra30-lenovo-ideapad-yoga-11.dts4
-rw-r--r--arch/arm/dts/tegra30-lg-x3.dtsi4
-rw-r--r--arch/arm/dts/tegra30-ouya.dts4
-rw-r--r--arch/arm/dts/tegra30-pegatron-chagall.dts1291
-rw-r--r--arch/arm/dts/tegra30-wexler-qc750.dts4
-rw-r--r--arch/arm/dts/tegra30.dtsi29
-rw-r--r--arch/arm/include/asm/arch-tegra/ap.h7
-rw-r--r--arch/arm/include/asm/arch-tegra/crypto.h43
-rw-r--r--arch/arm/include/asm/arch-tegra/dc.h3
-rw-r--r--arch/arm/include/asm/arch-tegra/fuse.h21
-rw-r--r--arch/arm/include/asm/arch-tegra/warmboot.h7
-rw-r--r--arch/arm/mach-tegra/Kconfig2
-rw-r--r--arch/arm/mach-tegra/ap.c8
-rw-r--r--arch/arm/mach-tegra/cpu.h1
-rw-r--r--arch/arm/mach-tegra/crypto.c184
-rw-r--r--arch/arm/mach-tegra/fuse.c63
-rw-r--r--arch/arm/mach-tegra/tegra124/bct.c20
-rw-r--r--arch/arm/mach-tegra/tegra20/Kconfig5
-rw-r--r--arch/arm/mach-tegra/tegra20/bct.c20
-rw-r--r--arch/arm/mach-tegra/tegra20/warmboot.c117
-rw-r--r--arch/arm/mach-tegra/tegra30/Kconfig5
-rw-r--r--arch/arm/mach-tegra/tegra30/bct.c20
-rw-r--r--board/pegatron/chagall/Kconfig13
-rw-r--r--board/pegatron/chagall/MAINTAINERS7
-rw-r--r--board/pegatron/chagall/Makefile11
-rw-r--r--board/pegatron/chagall/chagall-spl.c41
-rw-r--r--board/pegatron/chagall/chagall.c23
-rw-r--r--board/pegatron/chagall/chagall.env9
-rw-r--r--board/samsung/n1/Kconfig13
-rw-r--r--board/samsung/n1/MAINTAINERS9
-rw-r--r--board/samsung/n1/bose.config6
-rw-r--r--board/samsung/n1/n1.env16
-rw-r--r--cmd/bdinfo.c7
-rw-r--r--configs/chagall_defconfig80
-rw-r--r--configs/n1_defconfig92
-rw-r--r--doc/board/index.rst1
-rw-r--r--doc/board/pegatron/chagall.rst41
-rw-r--r--doc/board/pegatron/index.rst9
-rw-r--r--doc/board/samsung/index.rst1
-rw-r--r--doc/board/samsung/n1.rst51
-rw-r--r--drivers/crypto/Kconfig2
-rw-r--r--drivers/crypto/Makefile1
-rw-r--r--drivers/crypto/tegra/Kconfig7
-rw-r--r--drivers/crypto/tegra/Makefile3
-rw-r--r--drivers/crypto/tegra/tegra_aes.c591
-rw-r--r--drivers/video/Kconfig24
-rw-r--r--drivers/video/Makefile3
-rw-r--r--drivers/video/bridge/Kconfig8
-rw-r--r--drivers/video/bridge/Makefile1
-rw-r--r--drivers/video/bridge/cmc623.c234
-rw-r--r--drivers/video/cmc623_backlight.c124
-rw-r--r--drivers/video/samsung-s6e63m0.c393
-rw-r--r--drivers/video/sony-l4f00430t01.c210
-rw-r--r--drivers/video/tegra/dc.c16
-rw-r--r--scripts/Makefile.xpl1
-rw-r--r--test/py/tests/test_fit_mkimage_validate.py2
72 files changed, 4406 insertions, 308 deletions
diff --git a/Kconfig b/Kconfig
index c883f115459..70125c4e5a6 100644
--- a/Kconfig
+++ b/Kconfig
@@ -552,7 +552,7 @@ config BOARD_SIZE_LIMIT
Maximum size of the U-Boot image. When defined, the build system
checks that the actual size does not exceed it. This does not
include SPL nor TPL, on platforms that use that functionality, they
- have a separate option to restict size.
+ have separate options to restrict size.
config SYS_CUSTOM_LDSCRIPT
bool "Use a custom location for the U-Boot linker script"
diff --git a/Makefile b/Makefile
index b03f87a93fb..6ec2ce05928 100644
--- a/Makefile
+++ b/Makefile
@@ -1574,7 +1574,6 @@ u-boot-nodtb.bin: u-boot FORCE
$(BOARD_SIZE_CHECK)
u-boot.ldr: u-boot
- $(CREATE_LDR_ENV)
$(LDR) -T $(CONFIG_LDR_CPU) -c $@ $< $(LDR_FLAGS)
$(BOARD_SIZE_CHECK)
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 0dc7e190eb9..e212ed40b78 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -92,6 +92,8 @@ dtb-$(CONFIG_ARCH_TEGRA) += \
tegra20-motorola-olympus.dtb \
tegra20-paz00.dtb \
tegra20-plutux.dtb \
+ tegra20-samsung-bose.dtb \
+ tegra20-samsung-n1.dtb \
tegra20-seaboard.dtb \
tegra20-tec.dtb \
tegra20-trimslice.dtb \
@@ -117,6 +119,7 @@ dtb-$(CONFIG_ARCH_TEGRA) += \
tegra30-lg-p895.dtb \
tegra30-microsoft-surface-rt.dtb \
tegra30-ouya.dtb \
+ tegra30-pegatron-chagall.dtb \
tegra30-tec-ng.dtb \
tegra30-wexler-qc750.dtb \
tegra114-asus-tf701t.dtb \
diff --git a/arch/arm/dts/tegra20-acer-a500-picasso.dts b/arch/arm/dts/tegra20-acer-a500-picasso.dts
index 0c301483180..4afde766330 100644
--- a/arch/arm/dts/tegra20-acer-a500-picasso.dts
+++ b/arch/arm/dts/tegra20-acer-a500-picasso.dts
@@ -40,6 +40,10 @@
};
};
+ bsev@6001b000 {
+ status = "okay";
+ };
+
pinmux@70000014 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/dts/tegra20-asus-transformer.dtsi b/arch/arm/dts/tegra20-asus-transformer.dtsi
index 49efabbfd92..61b1cea6e90 100644
--- a/arch/arm/dts/tegra20-asus-transformer.dtsi
+++ b/arch/arm/dts/tegra20-asus-transformer.dtsi
@@ -36,6 +36,10 @@
};
};
+ bsev@6001b000 {
+ status = "okay";
+ };
+
pinmux@70000014 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/dts/tegra20-lg-star.dts b/arch/arm/dts/tegra20-lg-star.dts
index 3045bc3135f..083598b1b92 100644
--- a/arch/arm/dts/tegra20-lg-star.dts
+++ b/arch/arm/dts/tegra20-lg-star.dts
@@ -46,6 +46,10 @@
};
};
+ bsev@6001b000 {
+ status = "okay";
+ };
+
pinmux@70000014 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/dts/tegra20-motorola-mot.dtsi b/arch/arm/dts/tegra20-motorola-mot.dtsi
index f00707c2859..db2cce1cc0d 100644
--- a/arch/arm/dts/tegra20-motorola-mot.dtsi
+++ b/arch/arm/dts/tegra20-motorola-mot.dtsi
@@ -62,6 +62,10 @@
};
};
+ bsev@6001b000 {
+ status = "okay";
+ };
+
pinmux@70000014 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/dts/tegra20-samsung-bose.dts b/arch/arm/dts/tegra20-samsung-bose.dts
new file mode 100644
index 00000000000..5bb9a33adf2
--- /dev/null
+++ b/arch/arm/dts/tegra20-samsung-bose.dts
@@ -0,0 +1,119 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "tegra20-samsung-n1-common.dtsi"
+
+/ {
+ model = "Samsung Captivate Glide (SGH-i927)";
+ compatible = "samsung,bose", "nvidia,tegra20";
+
+ aliases {
+ spi0 = &panel_spi;
+ };
+
+ host1x@50000000 {
+ dc@54200000 {
+ rgb {
+ status = "okay";
+
+ port {
+ dpi_output: endpoint {
+ remote-endpoint = <&panel_input>;
+ bus-width = <24>;
+ };
+ };
+ };
+ };
+ };
+
+ pinmux@70000014 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ conf-dtf {
+ nvidia,pins = "dtf", "spdi", "spib", "spih";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ conf-gpv {
+ nvidia,pins = "gpv";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ conf-kbcd {
+ nvidia,pins = "kbcd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ drive-dap {
+ nvidia,pins = "drive_dap2", "drive_dap3";
+ nvidia,high-speed-mode = <TEGRA_PIN_ENABLE>;
+ nvidia,schmitt = <TEGRA_PIN_ENABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
+ nvidia,pull-down-strength = <31>;
+ nvidia,pull-up-strength = <31>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ };
+ };
+ };
+
+ panel_spi: spi@7000d800 {
+ status = "okay";
+ spi-max-frequency = <1000000>;
+
+ panel: panel@2 {
+ /* 480x800 AMOLED panel */
+ compatible = "samsung,bose-panel", "samsung,s6e63m0";
+ reg = <2>;
+
+ spi-max-frequency = <1000000>;
+
+ spi-cpol;
+ spi-cpha;
+
+ reset-gpios = <&gpio TEGRA_GPIO(C, 1) GPIO_ACTIVE_LOW>;
+
+ vdd3-supply = <&vlcd_1v8_reg>;
+ vci-supply = <&vlcd_3v0_reg>;
+
+ panel-width-mm = <52>;
+ panel-height-mm = <87>;
+
+ port {
+ panel_input: endpoint {
+ remote-endpoint = <&dpi_output>;
+ };
+ };
+ };
+ };
+
+ sdhci@c8000400 {
+ broken-cd;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ switch-hall {
+ label = "Keyboard Slide";
+ gpios = <&gpio TEGRA_GPIO(W, 3) GPIO_ACTIVE_HIGH>;
+ linux,input-type = <EV_SW>;
+ linux,code = <SW_KEYPAD_SLIDE>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ led-kbd {
+ label = "Keyboard backlight";
+ gpios = <&gpio TEGRA_GPIO(L, 5) GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+};
diff --git a/arch/arm/dts/tegra20-samsung-n1-common.dtsi b/arch/arm/dts/tegra20-samsung-n1-common.dtsi
new file mode 100644
index 00000000000..8223c5ece54
--- /dev/null
+++ b/arch/arm/dts/tegra20-samsung-n1-common.dtsi
@@ -0,0 +1,428 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <dt-bindings/input/input.h>
+#include "tegra20.dtsi"
+
+/ {
+ chosen {
+ stdout-path = &uartb;
+ };
+
+ aliases {
+ i2c0 = &pwr_i2c;
+
+ mmc0 = &sdmmc4; /* eMMC */
+ mmc1 = &sdmmc3; /* uSD slot */
+
+ rtc0 = &pmic;
+ rtc1 = "/rtc@7000e000";
+
+ usb0 = &micro_usb;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x00000000 0x40000000>; /* 1 GB */
+ };
+
+ pinmux@70000014 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ ata {
+ nvidia,pins = "ata", "atc", "atd", "ate",
+ "gmb", "gmd", "irrx", "irtx",
+ "spid", "spie";
+ nvidia,function = "gmi";
+ };
+
+ atb {
+ nvidia,pins = "atb", "gma", "gme";
+ nvidia,function = "sdio4";
+ };
+
+ cdev1 {
+ nvidia,pins = "cdev1";
+ nvidia,function = "plla_out";
+ };
+
+ cdev2 {
+ nvidia,pins = "cdev2";
+ nvidia,function = "pllp_out4";
+ };
+
+ crtp {
+ nvidia,pins = "crtp";
+ nvidia,function = "crt";
+ };
+
+ csus {
+ nvidia,pins = "csus";
+ nvidia,function = "vi_sensor_clk";
+ };
+
+ dap1 {
+ nvidia,pins = "dap1";
+ nvidia,function = "dap1";
+ };
+
+ dap2 {
+ nvidia,pins = "dap2";
+ nvidia,function = "dap2";
+ };
+
+ dap3 {
+ nvidia,pins = "dap3";
+ nvidia,function = "dap3";
+ };
+
+ dap4 {
+ nvidia,pins = "dap4";
+ nvidia,function = "dap4";
+ };
+
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "rsvd4";
+ };
+
+ pta {
+ nvidia,pins = "pta";
+ nvidia,function = "i2c2";
+ };
+
+ spif {
+ nvidia,pins = "spif", "uac";
+ nvidia,function = "rsvd4";
+ };
+
+ dta {
+ nvidia,pins = "dta", "dtb", "dtc", "dtd", "dte";
+ nvidia,function = "vi";
+ };
+
+ dtf {
+ nvidia,pins = "dtf";
+ nvidia,function = "i2c3";
+ };
+
+ gmc {
+ nvidia,pins = "gmc";
+ nvidia,function = "uartd";
+ };
+
+ gpu {
+ nvidia,pins = "gpu", "uaa", "uab";
+ nvidia,function = "uarta";
+ };
+
+ gpu7 {
+ nvidia,pins = "gpu7";
+ nvidia,function = "rtck";
+ };
+
+ gpv {
+ nvidia,pins = "gpv", "slxa", "slxk";
+ nvidia,function = "pcie";
+ };
+
+ hdint {
+ nvidia,pins = "hdint", "spdi", "spdo";
+ nvidia,function = "rsvd2";
+ };
+
+ i2cp {
+ nvidia,pins = "i2cp";
+ nvidia,function = "i2cp";
+ };
+
+ kbca {
+ nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd",
+ "kbce", "kbcf";
+ nvidia,function = "kbc";
+ };
+
+ lcsn {
+ nvidia,pins = "lcsn", "lsck", "lsda", "lsdi";
+ nvidia,function = "spi3";
+ };
+
+ ld0 {
+ nvidia,pins = "ld0", "ld1", "ld2", "ld3", "ld4",
+ "ld5", "ld6", "ld7", "ld8", "ld9",
+ "ld10", "ld11", "ld12", "ld13", "ld14",
+ "ld15", "ld16", "ld17", "ldc", "ldi",
+ "lhp0", "lhp1", "lhp2", "lhs", "lm0",
+ "lm1", "lpp", "lpw0", "lpw1", "lpw2",
+ "lsc0", "lsc1", "lspi", "lvp0", "lvp1",
+ "lvs";
+ nvidia,function = "displaya";
+ };
+
+ owc {
+ nvidia,pins = "owc";
+ nvidia,function = "owr";
+ };
+
+ pmc {
+ nvidia,pins = "pmc";
+ nvidia,function = "pwr_on";
+ };
+
+ rm {
+ nvidia,pins = "rm";
+ nvidia,function = "i2c1";
+ };
+
+ sdb {
+ nvidia,pins = "sdb", "sdc", "sdd";
+ nvidia,function = "sdio3";
+ };
+
+ sdio1 {
+ nvidia,pins = "sdio1";
+ nvidia,function = "sdio1";
+ };
+
+ slxc {
+ nvidia,pins = "slxc", "slxd";
+ nvidia,function = "spi4";
+ };
+
+ spig {
+ nvidia,pins = "spig", "spih";
+ nvidia,function = "spi2_alt";
+ };
+
+ uad {
+ nvidia,pins = "uad";
+ nvidia,function = "irda";
+ };
+
+ uca {
+ nvidia,pins = "uca", "ucb";
+ nvidia,function = "uartc";
+ };
+
+ uda {
+ nvidia,pins = "uda";
+ nvidia,function = "spi1";
+ };
+
+ spia {
+ nvidia,pins = "spia", "spib", "spic";
+ nvidia,function = "spi2";
+ };
+
+ conf-cdev1 {
+ nvidia,pins = "cdev1", "cdev2", "dap1", "dap2",
+ "dap3", "dap4", "ddc", "dte", "gma",
+ "gmc", "gmd", "gme", "gpu7", "hdint",
+ "i2cp", "lcsn", "lhs", "lm0", "lm1",
+ "lpw1", "lsc0", "lsck", "lsda", "lsdi",
+ "lspi", "lvs", "pmc", "pta", "rm",
+ "sdb", "sdio1", "uac", "uda", "ck32",
+ "ddrc", "pmca", "pmcb", "pmcc", "pmcd",
+ "xm2c", "xm2d";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ conf-crtp {
+ nvidia,pins = "crtp", "lvp0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+
+ conf-csus {
+ nvidia,pins = "csus", "spid";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+
+ conf-ata {
+ nvidia,pins = "ata", "atb", "atc", "ate",
+ "gmb", "gpu", "irrx", "irtx",
+ "kbca", "kbcc", "kbce", "kbcf",
+ "ldc", "lpw0", "lpw2", "lsc1", "sdc",
+ "sdd", "spig", "uaa", "uab",
+ "uad", "uca", "ucb", "pmce";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ conf-owc {
+ nvidia,pins = "owc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ };
+
+ conf-atd {
+ nvidia,pins = "atd", "dta", "dtb", "dtc", "dtd",
+ "kbcb", "ld0", "ld1", "ld10", "ld11",
+ "ld12", "ld13", "ld14", "ld15", "ld16",
+ "ld17", "ld2", "ld3", "ld4", "ld5",
+ "ld6", "ld7", "ld8", "ld9", "ldi",
+ "lhp0", "lhp1", "lhp2", "lpp", "lvp1",
+ "slxa", "slxc", "slxd", "slxk", "spdo",
+ "spia", "spic", "spie", "spif";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ drive-ao1 {
+ nvidia,pins = "drive_ao1", "drive_at1", "drive_dbg",
+ "drive_vi1", "drive_vi2";
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_ENABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
+ nvidia,pull-down-strength = <31>;
+ nvidia,pull-up-strength = <31>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ };
+
+ drive-sdio1 {
+ nvidia,pins = "drive_sdio1";
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_ENABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
+ nvidia,pull-down-strength = <31>;
+ nvidia,pull-up-strength = <31>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ };
+
+ drive-ddc {
+ nvidia,pins = "drive_ddc";
+ nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>;
+ nvidia,schmitt = <TEGRA_PIN_ENABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
+ nvidia,pull-down-strength = <31>;
+ nvidia,pull-up-strength = <31>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+ };
+ };
+
+ uartb: serial@70006040 {
+ clocks = <&tegra_car 7>;
+ status = "okay";
+ };
+
+ pwr_i2c: i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ pmic: max8907@3c {
+ compatible = "maxim,max8907";
+ reg = <0x3c>;
+
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ maxim,system-power-controller;
+
+ regulators {
+ vlcd_1v8_reg: ldo3 {
+ regulator-name = "vlcd_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ usb_phy_reg: ldo4 {
+ regulator-name = "vap_usb_3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vlcd_3v0_reg: ldo12 {
+ regulator-name = "vlcd_3v0";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ vmmc_usd_reg: ldo16 {
+ regulator-name = "vmmc_usd";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+ };
+ };
+ };
+
+ micro_usb: usb@c5000000 {
+ status = "okay";
+ dr_mode = "otg";
+ };
+
+ usb-phy@c5000000 {
+ status = "okay";
+ vbus-supply = <&usb_phy_reg>;
+ };
+
+ sdmmc3: sdhci@c8000400 {
+ status = "okay";
+ bus-width = <4>;
+
+ vmmc-supply = <&vmmc_usd_reg>;
+ vqmmc-supply = <&vdd_3v3_sys>;
+ };
+
+ sdmmc4: sdhci@c8000600 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+
+ vmmc-supply = <&vdd_3v3_sys>;
+ vqmmc-supply = <&vdd_3v3_sys>;
+ };
+
+ /* 32KHz oscillator which is used by PMC */
+ clk32k_in: clock-32k-in {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "ref-oscillator";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ key-power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(U, 5) GPIO_ACTIVE_HIGH>;
+ linux,code = <KEY_ENTER>;
+ };
+
+ key-volume-up {
+ label = "Volume Up";
+ gpios = <&gpio TEGRA_GPIO(Q, 1) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_UP>;
+ };
+
+ key-volume-down {
+ label = "Volume Down";
+ gpios = <&gpio TEGRA_GPIO(Q, 2) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_DOWN>;
+ };
+ };
+
+ vdd_3v3_sys: regulator-3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_3v3_vs";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+};
diff --git a/arch/arm/dts/tegra20-samsung-n1.dts b/arch/arm/dts/tegra20-samsung-n1.dts
new file mode 100644
index 00000000000..930a3195aa0
--- /dev/null
+++ b/arch/arm/dts/tegra20-samsung-n1.dts
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include "tegra20-samsung-n1-common.dtsi"
+
+/ {
+ model = "Samsung Galaxy R (GT-I9103)";
+ compatible = "samsung,n1", "nvidia,tegra20";
+
+ aliases {
+ i2c10 = &cmc_i2c;
+ spi0 = &panel_spi;
+ };
+
+ host1x@50000000 {
+ dc@54200000 {
+ rgb {
+ status = "okay";
+
+ port {
+ dpi_output: endpoint {
+ remote-endpoint = <&bridge_input>;
+ bus-width = <24>;
+ };
+ };
+ };
+ };
+ };
+
+ pinmux@70000014 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ conf-dtf {
+ nvidia,pins = "dtf", "spdi", "spih";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ conf-gpv {
+ nvidia,pins = "gpv", "spib";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+
+ conf-kbcd {
+ nvidia,pins = "kbcd";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ };
+ };
+ };
+
+ i2c@7000d000 {
+ max8907@3c {
+ regulators {
+ vcmc623_io_1v8: ldo15 {
+ regulator-name = "vcmc623_io_1v8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+ };
+ };
+
+ cmc_i2c: i2c-10 {
+ compatible = "i2c-gpio";
+
+ sda-gpios = <&gpio TEGRA_GPIO(Z, 3) GPIO_ACTIVE_HIGH>;
+ scl-gpios = <&gpio TEGRA_GPIO(C, 6) GPIO_ACTIVE_HIGH>;
+
+ i2c-gpio,scl-output-only;
+ i2c-gpio,delay-us = <1>;
+
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cmc623: bridge@38 {
+ compatible = "samsung,cmc623";
+ reg = <0x38>;
+
+ enable-gpios = <&gpio TEGRA_GPIO(Q, 4) GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&gpio TEGRA_GPIO(J, 6) GPIO_ACTIVE_HIGH>;
+
+ bypass-gpios = <&gpio TEGRA_GPIO(BB, 5) GPIO_ACTIVE_LOW>;
+ sleep-gpios = <&gpio TEGRA_GPIO(W, 0) GPIO_ACTIVE_HIGH>;
+
+ vdd3v0-supply = <&vcmc623_3v0>;
+ vdd1v2-supply = <&vcmc623_1v2>;
+ vddio1v8-supply = <&vcmc623_io_1v8>;
+
+ cmc623_backlight: backlight {
+ compatible = "samsung,cmc623-backlight";
+
+ enable-gpios = <&gpio TEGRA_GPIO(R, 3) GPIO_ACTIVE_HIGH>;
+ };
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ bridge_input: endpoint {
+ remote-endpoint = <&dpi_output>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ bridge_output: endpoint {
+ remote-endpoint = <&panel_input>;
+ };
+ };
+ };
+ };
+ };
+
+ panel_spi: spi@7000d800 {
+ status = "okay";
+ spi-max-frequency = <1000000>;
+
+ panel: panel@2 {
+ /* 480x800 TFT LCD panel */
+ compatible = "sony,l4f00430t01";
+ reg = <2>;
+
+ spi-max-frequency = <1000000>;
+
+ spi-cpol;
+ spi-cpha;
+
+ reset-gpios = <&gpio TEGRA_GPIO(C, 1) GPIO_ACTIVE_LOW>;
+
+ vdd1v8-supply = <&vlcd_1v8_reg>;
+ vdd3v0-supply = <&vlcd_3v0_reg>;
+
+ panel-width-mm = <55>;
+ panel-height-mm = <91>;
+
+ backlight = <&cmc623_backlight>;
+
+ port {
+ panel_input: endpoint {
+ remote-endpoint = <&bridge_output>;
+ };
+ };
+ };
+ };
+
+ sdhci@c8000400 {
+ /* battery blocks the sdcard slot and the device lacks CD pin */
+ non-removable;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ key-home {
+ label = "Home";
+ gpios = <&gpio TEGRA_GPIO(O, 5) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_ENTER>;
+ };
+ };
+
+ vcmc623_3v0: regulator-cmc623-3v0 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcmc623_3v0";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ vcmc623_1v2: regulator-cmc623-1v2 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcmc623_1v2";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ gpio = <&gpio TEGRA_GPIO(L, 5) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+};
diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
index 275b3432bd8..4a40edfdfbe 100644
--- a/arch/arm/dts/tegra20.dtsi
+++ b/arch/arm/dts/tegra20.dtsi
@@ -249,6 +249,35 @@
*/
};
+ /* Audio Bitstream Engine */
+ bsea@60011000 {
+ compatible = "nvidia,tegra20-bsea";
+ reg = <0x60011000 0x1000>, <0x4000c000 0x4000>;
+ reg-names = "bsea", "iram-buffer";
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "bsea";
+ clocks = <&tegra_car TEGRA20_CLK_BSEA>;
+ resets = <&tegra_car 62>;
+ reset-names = "bsea";
+ status = "disabled";
+ };
+
+ /* Video Bitstream Engine */
+ bsev@6001b000 {
+ compatible = "nvidia,tegra20-bsev";
+ reg = <0x6001b000 0x1000>, <0x40008000 0x4000>;
+ reg-names = "bsev", "iram-buffer";
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "bsev";
+ clocks = <&tegra_car TEGRA20_CLK_BSEV>,
+ <&tegra_car TEGRA20_CLK_VDE>;
+ clock-names = "bsev", "vde";
+ resets = <&tegra_car 63>,
+ <&tegra_car 61>;
+ reset-names = "bsev", "vde";
+ status = "disabled";
+ };
+
apbmisc@70000800 {
compatible = "nvidia,tegra20-apbmisc";
reg = <0x70000800 0x64 /* Chip revision */
diff --git a/arch/arm/dts/tegra30-asus-grouper-common.dtsi b/arch/arm/dts/tegra30-asus-grouper-common.dtsi
index d437ddc4dce..ddacdbb85c8 100644
--- a/arch/arm/dts/tegra30-asus-grouper-common.dtsi
+++ b/arch/arm/dts/tegra30-asus-grouper-common.dtsi
@@ -44,6 +44,10 @@
};
};
+ bsev@6001b000 {
+ status = "okay";
+ };
+
pinmux@70000868 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/dts/tegra30-asus-p1801-t.dts b/arch/arm/dts/tegra30-asus-p1801-t.dts
index 58f1499cb92..31cbef1b93c 100644
--- a/arch/arm/dts/tegra30-asus-p1801-t.dts
+++ b/arch/arm/dts/tegra30-asus-p1801-t.dts
@@ -50,6 +50,10 @@
};
};
+ bsev@6001b000 {
+ status = "okay";
+ };
+
pinmux@70000868 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/dts/tegra30-asus-tf600t.dts b/arch/arm/dts/tegra30-asus-tf600t.dts
index 1b5729c65f4..5135b8c666c 100644
--- a/arch/arm/dts/tegra30-asus-tf600t.dts
+++ b/arch/arm/dts/tegra30-asus-tf600t.dts
@@ -53,6 +53,10 @@
};
};
+ bsev@6001b000 {
+ status = "okay";
+ };
+
pinmux@70000868 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/dts/tegra30-asus-transformer.dtsi b/arch/arm/dts/tegra30-asus-transformer.dtsi
index 032fb3d00ac..47a44fbc9dd 100644
--- a/arch/arm/dts/tegra30-asus-transformer.dtsi
+++ b/arch/arm/dts/tegra30-asus-transformer.dtsi
@@ -37,6 +37,10 @@
};
};
+ bsev@6001b000 {
+ status = "okay";
+ };
+
pinmux@70000868 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/dts/tegra30-htc-endeavoru.dts b/arch/arm/dts/tegra30-htc-endeavoru.dts
index db8ac457880..79f423bd22a 100644
--- a/arch/arm/dts/tegra30-htc-endeavoru.dts
+++ b/arch/arm/dts/tegra30-htc-endeavoru.dts
@@ -60,6 +60,10 @@
};
};
+ bsev@6001b000 {
+ status = "okay";
+ };
+
pinmux@70000868 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/dts/tegra30-lenovo-ideapad-yoga-11.dts b/arch/arm/dts/tegra30-lenovo-ideapad-yoga-11.dts
index 876fac7b661..53f42089d30 100644
--- a/arch/arm/dts/tegra30-lenovo-ideapad-yoga-11.dts
+++ b/arch/arm/dts/tegra30-lenovo-ideapad-yoga-11.dts
@@ -43,6 +43,10 @@
};
};
+ bsev@6001b000 {
+ status = "okay";
+ };
+
pinmux@70000868 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/dts/tegra30-lg-x3.dtsi b/arch/arm/dts/tegra30-lg-x3.dtsi
index 40b0ee07787..09c5d04a225 100644
--- a/arch/arm/dts/tegra30-lg-x3.dtsi
+++ b/arch/arm/dts/tegra30-lg-x3.dtsi
@@ -42,6 +42,10 @@
};
};
+ bsev@6001b000 {
+ status = "okay";
+ };
+
pinmux@70000868 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/dts/tegra30-ouya.dts b/arch/arm/dts/tegra30-ouya.dts
index 04453eb2432..e6b2824d783 100644
--- a/arch/arm/dts/tegra30-ouya.dts
+++ b/arch/arm/dts/tegra30-ouya.dts
@@ -56,6 +56,10 @@
};
};
+ bsev@6001b000 {
+ status = "okay";
+ };
+
pinmux@70000868 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/dts/tegra30-pegatron-chagall.dts b/arch/arm/dts/tegra30-pegatron-chagall.dts
new file mode 100644
index 00000000000..98eb369f7a8
--- /dev/null
+++ b/arch/arm/dts/tegra30-pegatron-chagall.dts
@@ -0,0 +1,1291 @@
+// SPDX-License-Identifier: GPL-2.0
+/dts-v1/;
+
+#include <dt-bindings/input/input.h>
+#include "tegra30.dtsi"
+
+/ {
+ model = "Pegatron Chagall";
+ compatible = "pegatron,chagall", "nvidia,tegra30";
+
+ chosen {
+ stdout-path = &uarta;
+ };
+
+ aliases {
+ i2c0 = &pwr_i2c;
+
+ mmc0 = &sdmmc4; /* eMMC */
+ mmc1 = &sdmmc1; /* uSD slot */
+
+ rtc0 = &pmic;
+ rtc1 = "/rtc@7000e000";
+
+ usb0 = &usb1;
+ usb1 = &usb3; /* Dock USB */
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0x80000000 0x40000000>;
+ };
+
+ host1x@50000000 {
+ dc@54200000 {
+ rgb {
+ status = "okay";
+
+ port {
+ dpi_output: endpoint {
+ remote-endpoint = <&bridge_input>;
+ bus-width = <24>;
+ };
+ };
+ };
+ };
+ };
+
+ pinmux@70000868 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ /* SDMMC1 pinmux */
+ sdmmc1_clk_pz0 {
+ nvidia,pins = "sdmmc1_clk_pz0";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ sdmmc1_dat3_py4 {
+ nvidia,pins = "sdmmc1_dat3_py4",
+ "sdmmc1_dat2_py5",
+ "sdmmc1_dat1_py6",
+ "sdmmc1_dat0_py7",
+ "sdmmc1_cmd_pz1";
+ nvidia,function = "sdmmc1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* SDMMC2 pinmux */
+ vi_d1_pd5 {
+ nvidia,pins = "vi_d1_pd5",
+ "vi_d2_pl0",
+ "vi_d3_pl1",
+ "vi_d5_pl3",
+ "vi_d7_pl5";
+ nvidia,function = "sdmmc2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ vi_d8_pl6 {
+ nvidia,pins = "vi_d8_pl6",
+ "vi_d9_pl7";
+ nvidia,function = "sdmmc2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <0>;
+ nvidia,io-reset = <0>;
+ };
+
+ /* SDMMC3 pinmux */
+ sdmmc3_clk_pa6 {
+ nvidia,pins = "sdmmc3_clk_pa6";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ sdmmc3_cmd_pa7 {
+ nvidia,pins = "sdmmc3_cmd_pa7",
+ "sdmmc3_dat3_pb4",
+ "sdmmc3_dat2_pb5",
+ "sdmmc3_dat1_pb6",
+ "sdmmc3_dat0_pb7",
+ "sdmmc3_dat5_pd0",
+ "sdmmc3_dat4_pd1",
+ "sdmmc3_dat6_pd3",
+ "sdmmc3_dat7_pd4";
+ nvidia,function = "sdmmc3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* SDMMC4 pinmux */
+ sdmmc4_clk_pcc4 {
+ nvidia,pins = "sdmmc4_clk_pcc4";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ sdmmc4_cmd_pt7 {
+ nvidia,pins = "sdmmc4_cmd_pt7",
+ "sdmmc4_dat0_paa0",
+ "sdmmc4_dat1_paa1",
+ "sdmmc4_dat2_paa2",
+ "sdmmc4_dat3_paa3",
+ "sdmmc4_dat4_paa4",
+ "sdmmc4_dat5_paa5",
+ "sdmmc4_dat6_paa6",
+ "sdmmc4_dat7_paa7";
+ nvidia,function = "sdmmc4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* I2C pinmux */
+ gen1_i2c_scl_pc4 {
+ nvidia,pins = "gen1_i2c_scl_pc4",
+ "gen1_i2c_sda_pc5";
+ nvidia,function = "i2c1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <0>;
+ };
+
+ gen2_i2c_scl_pt5 {
+ nvidia,pins = "gen2_i2c_scl_pt5",
+ "gen2_i2c_sda_pt6";
+ nvidia,function = "i2c2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <0>;
+ };
+
+ cam_i2c_scl_pbb1 {
+ nvidia,pins = "cam_i2c_scl_pbb1",
+ "cam_i2c_sda_pbb2";
+ nvidia,function = "i2c3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <0>;
+ };
+
+ ddc_scl_pv4 {
+ nvidia,pins = "ddc_scl_pv4",
+ "ddc_sda_pv5";
+ nvidia,function = "i2c4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <0>;
+ };
+
+ pwr_i2c_scl_pz6 {
+ nvidia,pins = "pwr_i2c_scl_pz6",
+ "pwr_i2c_sda_pz7";
+ nvidia,function = "i2cpwr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <0>;
+ };
+
+ /* HDMI-CEC pinmux */
+ hdmi_cec_pee3 {
+ nvidia,pins = "hdmi_cec_pee3";
+ nvidia,function = "cec";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,open-drain = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <0>;
+ };
+
+ /* UART-A */
+ ulpi_data0_po1 {
+ nvidia,pins = "ulpi_data0_po1";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ ulpi_data1_po2 {
+ nvidia,pins = "ulpi_data1_po2",
+ "ulpi_data2_po3",
+ "ulpi_data3_po4",
+ "ulpi_data4_po5",
+ "ulpi_data5_po6",
+ "ulpi_data6_po7";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ ulpi_data7_po0 {
+ nvidia,pins = "ulpi_data7_po0";
+ nvidia,function = "uarta";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* UART-B */
+ uart2_txd_pc2 {
+ nvidia,pins = "uart2_txd_pc2",
+ "uart2_rts_n_pj6";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ uart2_rxd_pc3 {
+ nvidia,pins = "uart2_rxd_pc3",
+ "uart2_cts_n_pj5";
+ nvidia,function = "uartb";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* UART-C */
+ uart3_cts_n_pa1 {
+ nvidia,pins = "uart3_cts_n_pa1",
+ "uart3_rxd_pw7";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ uart3_rts_n_pc0 {
+ nvidia,pins = "uart3_rts_n_pc0",
+ "uart3_txd_pw6";
+ nvidia,function = "uartc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* UART-D */
+ ulpi_clk_py0 {
+ nvidia,pins = "ulpi_clk_py0",
+ "ulpi_stp_py3";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ ulpi_dir_py1 {
+ nvidia,pins = "ulpi_dir_py1",
+ "ulpi_nxt_py2";
+ nvidia,function = "uartd";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* I2S pinmux */
+ dap1_fs_pn0 {
+ nvidia,pins = "dap1_fs_pn0",
+ "dap1_din_pn1",
+ "dap1_dout_pn2",
+ "dap1_sclk_pn3";
+ nvidia,function = "i2s0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ dap2_fs_pa2 {
+ nvidia,pins = "dap2_fs_pa2",
+ "dap2_sclk_pa3",
+ "dap2_din_pa4",
+ "dap2_dout_pa5";
+ nvidia,function = "i2s1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ dap3_fs_pp0 {
+ nvidia,pins = "dap3_fs_pp0",
+ "dap3_din_pp1",
+ "dap3_dout_pp2",
+ "dap3_sclk_pp3";
+ nvidia,function = "i2s2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ dap4_fs_pp4 {
+ nvidia,pins = "dap4_fs_pp4",
+ "dap4_din_pp5",
+ "dap4_dout_pp6",
+ "dap4_sclk_pp7";
+ nvidia,function = "i2s3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ pcc2 {
+ nvidia,pins = "pcc2";
+ nvidia,function = "i2s4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* PCI-e pinmux */
+ pex_l2_rst_n_pcc6 {
+ nvidia,pins = "pex_l2_rst_n_pcc6",
+ "pex_l0_rst_n_pdd1",
+ "pex_l1_rst_n_pdd5";
+ nvidia,function = "pcie";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ pex_l2_clkreq_n_pcc7 {
+ nvidia,pins = "pex_l2_clkreq_n_pcc7",
+ "pex_l0_prsnt_n_pdd0",
+ "pex_l0_clkreq_n_pdd2",
+ "pex_l2_prsnt_n_pdd7";
+ nvidia,function = "pcie";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ pex_wake_n_pdd3 {
+ nvidia,pins = "pex_wake_n_pdd3";
+ nvidia,function = "pcie";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* SPI pinmux */
+ spi1_mosi_px4 {
+ nvidia,pins = "spi1_mosi_px4",
+ "spi1_sck_px5",
+ "spi1_cs0_n_px6",
+ "spi1_miso_px7";
+ nvidia,function = "spi1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ spi2_cs1_n_pw2 {
+ nvidia,pins = "spi2_cs1_n_pw2",
+ "spi2_cs2_n_pw3";
+ nvidia,function = "spi2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ spi2_sck_px2 {
+ nvidia,pins = "spi2_sck_px2";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ gmi_a16_pj7 {
+ nvidia,pins = "gmi_a16_pj7",
+ "gmi_a19_pk7";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ gmi_a17_pb0 {
+ nvidia,pins = "gmi_a17_pb0",
+ "gmi_a18_pb1";
+ nvidia,function = "spi4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ spi2_mosi_px0 {
+ nvidia,pins = "spi2_mosi_px0";
+ nvidia,function = "spi6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ spdif_out_pk5 {
+ nvidia,pins = "spdif_out_pk5";
+ nvidia,function = "spdif";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ spdif_in_pk6 {
+ nvidia,pins = "spdif_in_pk6";
+ nvidia,function = "spdif";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* Display A pinmux */
+ lcd_pwr0_pb2 {
+ nvidia,pins = "lcd_pwr0_pb2",
+ "lcd_pclk_pb3",
+ "lcd_pwr1_pc1",
+ "lcd_pwr2_pc6",
+ "lcd_d0_pe0",
+ "lcd_d1_pe1",
+ "lcd_d2_pe2",
+ "lcd_d3_pe3",
+ "lcd_d4_pe4",
+ "lcd_d5_pe5",
+ "lcd_d6_pe6",
+ "lcd_d7_pe7",
+ "lcd_d8_pf0",
+ "lcd_d9_pf1",
+ "lcd_d10_pf2",
+ "lcd_d11_pf3",
+ "lcd_d12_pf4",
+ "lcd_d13_pf5",
+ "lcd_d14_pf6",
+ "lcd_d15_pf7",
+ "lcd_de_pj1",
+ "lcd_hsync_pj3",
+ "lcd_vsync_pj4",
+ "lcd_d16_pm0",
+ "lcd_d17_pm1",
+ "lcd_d18_pm2",
+ "lcd_d19_pm3",
+ "lcd_d20_pm4",
+ "lcd_d21_pm5",
+ "lcd_d22_pm6",
+ "lcd_d23_pm7",
+ "lcd_cs0_n_pn4",
+ "lcd_sdout_pn5",
+ "lcd_dc0_pn6",
+ "lcd_sdin_pz2",
+ "lcd_wr_n_pz3",
+ "lcd_sck_pz4",
+ "lcd_cs1_n_pw0",
+ "lcd_m1_pw1";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ lcd_dc1_pd2 {
+ nvidia,pins = "lcd_dc1_pd2";
+ nvidia,function = "displaya";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ clk_32k_out_pa0 {
+ nvidia,pins = "clk_32k_out_pa0";
+ nvidia,function = "blink";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ /* KBC keys */
+ kb_row0_pr0 {
+ nvidia,pins = "kb_row0_pr0",
+ "kb_row1_pr1",
+ "kb_row2_pr2",
+ "kb_row3_pr3",
+ "kb_row8_ps0",
+ "kb_col0_pq0",
+ "kb_col1_pq1",
+ "kb_col2_pq2",
+ "kb_col3_pq3",
+ "kb_col4_pq4",
+ "kb_col5_pq5",
+ "kb_col7_pq7";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ kb_row4_pr4 {
+ nvidia,pins = "kb_row4_pr4",
+ "kb_row7_pr7",
+ "kb_row10_ps2",
+ "kb_row13_ps5";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ kb_row11_ps3 {
+ nvidia,pins = "kb_row11_ps3",
+ "kb_row12_ps4",
+ "kb_row15_ps7";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ kb_row14_ps6 {
+ nvidia,pins = "kb_row14_ps6";
+ nvidia,function = "kbc";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ gmi_iordy_pi5 {
+ nvidia,pins = "gmi_iordy_pi5";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ vi_pclk_pt0 {
+ nvidia,pins = "vi_pclk_pt0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <0>;
+ nvidia,io-reset = <0>;
+ };
+
+ pu1 {
+ nvidia,pins = "pu1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ pu2 {
+ nvidia,pins = "pu2";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ pv0 {
+ nvidia,pins = "pv0";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ pv1 {
+ nvidia,pins = "pv1";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ pcc1 {
+ nvidia,pins = "pcc1";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ sdmmc4_rst_n_pcc3 {
+ nvidia,pins = "sdmmc4_rst_n_pcc3";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ pv3 {
+ nvidia,pins = "pv3";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ vi_vsync_pd6 {
+ nvidia,pins = "vi_vsync_pd6",
+ "vi_hsync_pd7";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ nvidia,lock = <0>;
+ nvidia,io-reset = <0>;
+ };
+
+ vi_d10_pt2 {
+ nvidia,pins = "vi_d10_pt2",
+ "vi_d0_pt4", "pbb0";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ vi_d11_pt3 {
+ nvidia,pins = "vi_d11_pt3";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ pu0 {
+ nvidia,pins = "pu0";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ pu3 {
+ nvidia,pins = "pu3";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ pu6 {
+ nvidia,pins = "pu6";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ pex_l1_prsnt_n_pdd4 {
+ nvidia,pins = "pex_l1_prsnt_n_pdd4",
+ "pex_l1_clkreq_n_pdd6";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ gmi_wait_pi7 {
+ nvidia,pins = "gmi_wait_pi7",
+ "gmi_cs0_n_pj0",
+ "gmi_cs1_n_pj2",
+ "gmi_cs4_n_pk2";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ gmi_ad0_pg0 {
+ nvidia,pins = "gmi_ad0_pg0",
+ "gmi_ad1_pg1",
+ "gmi_ad2_pg2",
+ "gmi_ad3_pg3",
+ "gmi_ad4_pg4",
+ "gmi_ad5_pg5",
+ "gmi_ad6_pg6",
+ "gmi_ad7_pg7",
+ "gmi_wr_n_pi0",
+ "gmi_oe_n_pi1",
+ "gmi_dqs_pi2",
+ "gmi_adv_n_pk0",
+ "gmi_clk_pk1";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ gmi_cs2_n_pk3 {
+ nvidia,pins = "gmi_cs2_n_pk3";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ gmi_cs3_n_pk4 {
+ nvidia,pins = "gmi_cs3_n_pk4";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ gmi_ad10_ph2 {
+ nvidia,pins = "gmi_ad10_ph2",
+ "gmi_ad11_ph3",
+ "gmi_ad14_ph6";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ gmi_ad13_ph5 {
+ nvidia,pins = "gmi_ad13_ph5",
+ "gmi_ad12_ph4",
+ "gmi_cs7_n_pi6";
+ nvidia,function = "nand";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ gmi_rst_n_pi4 {
+ nvidia,pins = "gmi_rst_n_pi4";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ gmi_ad8_ph0 {
+ nvidia,pins = "gmi_ad8_ph0";
+ nvidia,function = "pwm0";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ gmi_ad9_ph1 {
+ nvidia,pins = "gmi_ad9_ph1";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ gmi_wp_n_pc7 {
+ nvidia,pins = "gmi_wp_n_pc7";
+ nvidia,function = "gmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ gmi_cs6_n_pi3 {
+ nvidia,pins = "gmi_cs6_n_pi3";
+ nvidia,function = "sata";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ vi_d4_pl2 {
+ nvidia,pins = "vi_d4_pl2";
+ nvidia,function = "vi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ vi_d6_pl4 {
+ nvidia,pins = "vi_d6_pl4";
+ nvidia,function = "vi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ nvidia,lock = <0>;
+ nvidia,io-reset = <0>;
+ };
+
+ vi_mclk_pt1 {
+ nvidia,pins = "vi_mclk_pt1";
+ nvidia,function = "vi";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* HDMI hot-plug-detect */
+ hdmi_int_pn7 {
+ nvidia,pins = "hdmi_int_pn7";
+ nvidia,function = "hdmi";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_ENABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ pu4 {
+ nvidia,pins = "pu4";
+ nvidia,function = "pwm1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ pu5 {
+ nvidia,pins = "pu5";
+ nvidia,function = "pwm2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ jtag_rtck_pu7 {
+ nvidia,pins = "jtag_rtck_pu7";
+ nvidia,function = "rtck";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ crt_hsync_pv6 {
+ nvidia,pins = "crt_hsync_pv6",
+ "crt_vsync_pv7";
+ nvidia,function = "crt";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ clk1_out_pw4 {
+ nvidia,pins = "clk1_out_pw4";
+ nvidia,function = "extperiph1";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ clk2_out_pw5 {
+ nvidia,pins = "clk2_out_pw5";
+ nvidia,function = "extperiph2";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ clk3_out_pee0 {
+ nvidia,pins = "clk3_out_pee0";
+ nvidia,function = "extperiph3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ sys_clk_req_pz5 {
+ nvidia,pins = "sys_clk_req_pz5";
+ nvidia,function = "sysclk";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ pbb4 {
+ nvidia,pins = "pbb4";
+ nvidia,function = "vgp4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ pbb5 {
+ nvidia,pins = "pbb5";
+ nvidia,function = "vgp5";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ pbb6 {
+ nvidia,pins = "pbb6";
+ nvidia,function = "vgp6";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ clk1_req_pee2 {
+ nvidia,pins = "clk1_req_pee2";
+ nvidia,function = "dap";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ clk2_req_pcc5 {
+ nvidia,pins = "clk2_req_pcc5";
+ nvidia,function = "dap";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ clk3_req_pee1 {
+ nvidia,pins = "clk3_req_pee1";
+ nvidia,function = "dev3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ owr {
+ nvidia,pins = "owr";
+ nvidia,function = "owr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ pv2 {
+ nvidia,pins = "pv2",
+ "kb_row5_pr5";
+ nvidia,function = "owr";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_DISABLE>;
+ };
+
+ pbb3 {
+ nvidia,pins = "pbb3";
+ nvidia,function = "vgp3";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ pbb7 {
+ nvidia,pins = "pbb7";
+ nvidia,function = "i2s4";
+ nvidia,pull = <TEGRA_PIN_PULL_NONE>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ cam_mclk_pcc0 {
+ nvidia,pins = "cam_mclk_pcc0";
+ nvidia,function = "vi_alt3";
+ nvidia,pull = <TEGRA_PIN_PULL_UP>;
+ nvidia,tristate = <TEGRA_PIN_DISABLE>;
+ nvidia,enable-input = <TEGRA_PIN_ENABLE>;
+ };
+
+ /* GPIO power/drive control */
+ drive_dap1 {
+ nvidia,pins = "drive_dap1",
+ "drive_dap2",
+ "drive_dbg",
+ "drive_at5",
+ "drive_gme",
+ "drive_ddc",
+ "drive_ao1",
+ "drive_uart3";
+ nvidia,high-speed-mode = <0>;
+ nvidia,schmitt = <TEGRA_PIN_ENABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>;
+ nvidia,pull-down-strength = <31>;
+ nvidia,pull-up-strength = <31>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+
+ drive_sdio1 {
+ nvidia,pins = "drive_sdio1";
+ nvidia,high-speed-mode = <0>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,pull-down-strength = <5>;
+ nvidia,pull-up-strength = <5>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FAST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FAST>;
+ };
+
+ drive_sdio3 {
+ nvidia,pins = "drive_sdio3";
+ nvidia,high-speed-mode = <0>;
+ nvidia,schmitt = <TEGRA_PIN_DISABLE>;
+ nvidia,pull-down-strength = <46>;
+ nvidia,pull-up-strength = <42>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FAST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FAST>;
+ };
+
+ drive_gma {
+ nvidia,pins = "drive_gma",
+ "drive_gmb",
+ "drive_gmc",
+ "drive_gmd";
+ nvidia,pull-down-strength = <9>;
+ nvidia,pull-up-strength = <9>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
+ };
+
+ drive_lcd2 {
+ nvidia,pins = "drive_lcd2";
+ nvidia,high-speed-mode = <0>;
+ nvidia,schmitt = <TEGRA_PIN_ENABLE>;
+ nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_4>;
+ nvidia,pull-down-strength = <20>;
+ nvidia,pull-up-strength = <20>;
+ nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_FASTEST>;
+ };
+ };
+ };
+
+ uarta: serial@70006000 {
+ status = "okay";
+ };
+
+ pwm: pwm@7000a000 {
+ status = "okay";
+ };
+
+ pwr_i2c: i2c@7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ /* Texas Instruments TPS659110 PMIC */
+ pmic: tps65911@2d {
+ compatible = "ti,tps65911";
+ reg = <0x2d>;
+
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+
+ ti,system-power-controller;
+
+ #gpio-cells = <2>;
+ gpio-controller;
+
+ regulators {
+ vdd_1v8_vio: vddio {
+ regulator-name = "vdd_1v8_gen";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ /* eMMC VDD */
+ vcore_emmc: ldo1 {
+ regulator-name = "vdd_emmc_core";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-boot-on;
+ };
+
+ /* uSD slot VDD */
+ vdd_usd: ldo2 {
+ regulator-name = "vdd_usd";
+ regulator-min-microvolt = <3100000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-boot-on;
+ };
+
+ /* uSD slot VDDIO */
+ vddio_usd: ldo3 {
+ regulator-name = "vddio_usd";
+ regulator-min-microvolt = <3100000>;
+ regulator-max-microvolt = <3100000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+ };
+ };
+ };
+
+ sdmmc1: sdhci@78000000 {
+ status = "okay";
+ bus-width = <4>;
+
+ cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
+
+ vmmc-supply = <&vdd_usd>;
+ vqmmc-supply = <&vddio_usd>;
+ };
+
+ sdmmc4: sdhci@78000600 {
+ status = "okay";
+ bus-width = <8>;
+ non-removable;
+
+ vmmc-supply = <&vcore_emmc>;
+ vqmmc-supply = <&vdd_1v8_vio>;
+ };
+
+ usb1: usb@7d000000 {
+ status = "okay";
+ dr_mode = "otg";
+ nvidia,vbus-gpio = <&gpio TEGRA_GPIO(DD, 3) GPIO_ACTIVE_HIGH>;
+ };
+
+ usb-phy@7d000000 {
+ status = "okay";
+ nvidia,hssync-start-delay = <0>;
+ nvidia,xcvr-lsfslew = <2>;
+ nvidia,xcvr-lsrslew = <2>;
+ };
+
+ usb3: usb@7d008000 {
+ status = "okay";
+ nvidia,vbus-gpio = <&gpio TEGRA_GPIO(CC, 6) GPIO_ACTIVE_HIGH>;
+ };
+
+ usb-phy@7d008000 {
+ status = "okay";
+ };
+
+ backlight: backlight {
+ compatible = "pwm-backlight";
+
+ enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
+ power-supply = <&vdd_5v0_bl>;
+ pwms = <&pwm 0 5000000>;
+
+ brightness-levels = <1 35 70 105 140 175 210 255>;
+ default-brightness-level = <5>;
+ };
+
+ /* PMIC has a built-in 32KHz oscillator which is used by PMC */
+ clk32k_in: clock-32k {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ clock-output-names = "pmic-oscillator";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ key-power {
+ label = "Power";
+ gpios = <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_ENTER>;
+ };
+
+ key-volume-up {
+ label = "Volume Up";
+ gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_UP>;
+ };
+
+ key-volume-down {
+ label = "Volume Down";
+ gpios = <&gpio TEGRA_GPIO(Q, 1) GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_DOWN>;
+ };
+ };
+
+ display-panel {
+ compatible = "hannstar,hsd101pww2", "simple-panel";
+
+ power-supply = <&vdd_pnl_reg>;
+ backlight = <&backlight>;
+
+ display-timings {
+ timing@0 {
+ /* 1280x800@60Hz */
+ clock-frequency = <68000000>;
+
+ hactive = <1280>;
+ hfront-porch = <48>;
+ hback-porch = <18>;
+ hsync-len = <30>;
+
+ vactive = <800>;
+ vfront-porch = <3>;
+ vback-porch = <12>;
+ vsync-len = <5>;
+ };
+ };
+
+ port {
+ panel_input: endpoint {
+ remote-endpoint = <&bridge_output>;
+ };
+ };
+ };
+
+ /* Texas Instruments SN75LVDS83B LVDS Transmitter */
+ lvds-encoder {
+ compatible = "ti,sn75lvds83", "lvds-encoder";
+
+ powerdown-gpios = <&gpio TEGRA_GPIO(N, 6) GPIO_ACTIVE_LOW>;
+ power-supply = <&vdd_3v3_sys>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ bridge_input: endpoint {
+ remote-endpoint = <&dpi_output>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ bridge_output: endpoint {
+ remote-endpoint = <&panel_input>;
+ };
+ };
+ };
+ };
+
+ vdd_3v3_sys: regulator-3v {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_3v3_sys";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
+
+ vdd_pnl_reg: regulator-pnl {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_panel";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio TEGRA_GPIO(W, 1) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ vdd_5v0_bl: regulator-bl {
+ compatible = "regulator-fixed";
+ regulator-name = "vdd_5v0_bl";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+};
diff --git a/arch/arm/dts/tegra30-wexler-qc750.dts b/arch/arm/dts/tegra30-wexler-qc750.dts
index b376b91a7fa..ededbf579fd 100644
--- a/arch/arm/dts/tegra30-wexler-qc750.dts
+++ b/arch/arm/dts/tegra30-wexler-qc750.dts
@@ -44,6 +44,10 @@
};
};
+ bsev@6001b000 {
+ status = "okay";
+ };
+
pinmux@70000868 {
pinctrl-names = "default";
pinctrl-0 = <&state_default>;
diff --git a/arch/arm/dts/tegra30.dtsi b/arch/arm/dts/tegra30.dtsi
index d5de1ecaf05..82e843d05be 100644
--- a/arch/arm/dts/tegra30.dtsi
+++ b/arch/arm/dts/tegra30.dtsi
@@ -373,6 +373,35 @@
*/
};
+ /* Audio Bitstream Engine */
+ bsea@60011000 {
+ compatible = "nvidia,tegra30-bsea";
+ reg = <0x60011000 0x1000>, <0x4000c000 0x4000>;
+ reg-names = "bsea", "iram-buffer";
+ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "bsea";
+ clocks = <&tegra_car TEGRA30_CLK_BSEA>;
+ resets = <&tegra_car 62>;
+ reset-names = "bsea";
+ status = "disabled";
+ };
+
+ /* Video Bitstream Engine */
+ bsev@6001b000 {
+ compatible = "nvidia,tegra30-bsev";
+ reg = <0x6001b000 0x1000>, <0x40008000 0x4000>;
+ reg-names = "bsev", "iram-buffer";
+ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "bsev";
+ clocks = <&tegra_car TEGRA30_CLK_BSEV>,
+ <&tegra_car TEGRA30_CLK_VDE>;
+ clock-names = "bsev", "vde";
+ resets = <&tegra_car 63>,
+ <&tegra_car 61>;
+ reset-names = "bsev", "vde";
+ status = "disabled";
+ };
+
apbmisc@70000800 {
compatible = "nvidia,tegra30-apbmisc", "nvidia,tegra20-apbmisc";
reg = <0x70000800 0x64 /* Chip revision */
diff --git a/arch/arm/include/asm/arch-tegra/ap.h b/arch/arm/include/asm/arch-tegra/ap.h
index b922b2d30ea..295c3287737 100644
--- a/arch/arm/include/asm/arch-tegra/ap.h
+++ b/arch/arm/include/asm/arch-tegra/ap.h
@@ -55,6 +55,13 @@ int tegra_get_chip_sku(void);
int tegra_get_chip(void);
/**
+ * Returns the pure SOC major version from the HIDREV register
+ *
+ * Return: SOC major version
+ */
+u32 tegra_get_major_version(void);
+
+/**
* Returns the SKU ID from the sku_info register
*
* Return: SKU ID - see SKU_ID_Txx...
diff --git a/arch/arm/include/asm/arch-tegra/crypto.h b/arch/arm/include/asm/arch-tegra/crypto.h
index 7646163b97b..930bc842039 100644
--- a/arch/arm/include/asm/arch-tegra/crypto.h
+++ b/arch/arm/include/asm/arch-tegra/crypto.h
@@ -7,41 +7,36 @@
#ifndef _CRYPTO_H_
#define _CRYPTO_H_
-/**
- * Sign a block of data
- *
- * \param source Source data
- * \param length Size of source data
- * \param signature Destination address for signature, AES_KEY_LENGTH bytes
- */
-int sign_data_block(u8 *source, unsigned int length, u8 *signature);
+#define TEGRA_AES_SLOT_SBK 0
/**
- * Sign an encrypted block of data
+ * sign_data_block - Sign a block of data
*
- * \param source Source data
- * \param length Size of source data
- * \param signature Destination address for signature, AES_KEY_LENGTH bytes
- * \param key AES128 encryption key
+ * @source Source data
+ * @length Size of source data in bytes
+ * @signature Destination address for signature, AES_KEY_LENGTH bytes
+ * Return: 0 on success, negative value on failure
*/
-int sign_enc_data_block(u8 *source, unsigned int length, u8 *signature, u8 *key);
+int sign_data_block(u8 *source, unsigned int length, u8 *signature);
/**
- * Encrypt a block of data
+ * encrypt_data_block - Encrypt a block of data
*
- * \param source Source data
- * \param length Size of source data
- * \param key AES128 encryption key
+ * @source Source data
+ * @dest Destination data
+ * @length Size of source data in bytes
+ * Return: 0 on success, negative value on failure
*/
-int encrypt_data_block(u8 *source, unsigned int length, u8 *key);
+int encrypt_data_block(u8 *source, u8 *dest, unsigned int length);
/**
- * Decrypt a block of data
+ * decrypt_data_block - Decrypt a block of data
*
- * \param source Source data
- * \param length Size of source data
- * \param key AES128 encryption key
+ * @source Source data
+ * @dest Destination data
+ * @length Size of source data in bytes
+ * Return: 0 on success, negative value on failure
*/
-int decrypt_data_block(u8 *source, unsigned int length, u8 *key);
+int decrypt_data_block(u8 *source, u8 *dest, unsigned int length);
#endif /* #ifndef _CRYPTO_H_ */
diff --git a/arch/arm/include/asm/arch-tegra/dc.h b/arch/arm/include/asm/arch-tegra/dc.h
index ab12cc9c7d0..22f8f977cc6 100644
--- a/arch/arm/include/asm/arch-tegra/dc.h
+++ b/arch/arm/include/asm/arch-tegra/dc.h
@@ -448,6 +448,9 @@ enum win_color_depth_id {
#define LVS_OUTPUT_POLARITY_LOW BIT(28)
#define LSC0_OUTPUT_POLARITY_LOW BIT(24)
+/* DC_COM_PIN_OUTPUT_POLARITY3 0x309 */
+#define LSPI_OUTPUT_POLARITY_LOW BIT(8)
+
/* DC_COM_PIN_OUTPUT_SELECT6 0x31a */
#define LDC_OUTPUT_SELECT_V_PULSE1 BIT(14) /* 100b */
diff --git a/arch/arm/include/asm/arch-tegra/fuse.h b/arch/arm/include/asm/arch-tegra/fuse.h
index f3f2ad8e3f2..631ebbb283c 100644
--- a/arch/arm/include/asm/arch-tegra/fuse.h
+++ b/arch/arm/include/asm/arch-tegra/fuse.h
@@ -17,8 +17,22 @@ struct fuse_regs {
u32 fa; /* 0x148: FUSE_FA */
u32 reserved3[21]; /* 0x14C - 0x19C: */
u32 security_mode; /* 0x1A0: FUSE_SECURITY_MODE */
+ u32 sbk[4]; /* 0x1A4 - 0x1B4 */
};
+/* Defines the supported operating modes */
+enum fuse_operating_mode {
+ MODE_UNDEFINED = 0,
+ MODE_PRODUCTION = 3,
+ MODE_ODM_PRODUCTION_SECURE = 4,
+ MODE_ODM_PRODUCTION_OPEN = 5,
+};
+
+/**
+ * Initializes fuse hardware
+ */
+void tegra_fuse_init(void);
+
/**
* Calculate SoC UID
*
@@ -26,4 +40,11 @@ struct fuse_regs {
*/
unsigned long long tegra_chip_uid(void);
+/**
+ * Gives the current operating mode from fuses
+ *
+ * @return current operating mode
+ */
+enum fuse_operating_mode tegra_fuse_get_operation_mode(void);
+
#endif /* ifndef _FUSE_H_ */
diff --git a/arch/arm/include/asm/arch-tegra/warmboot.h b/arch/arm/include/asm/arch-tegra/warmboot.h
index 9a53456370f..4352f1dc5e8 100644
--- a/arch/arm/include/asm/arch-tegra/warmboot.h
+++ b/arch/arm/include/asm/arch-tegra/warmboot.h
@@ -10,12 +10,6 @@
#define STRAP_OPT_A_RAM_CODE_SHIFT 4
#define STRAP_OPT_A_RAM_CODE_MASK (0xf << STRAP_OPT_A_RAM_CODE_SHIFT)
-/* Defines the supported operating modes */
-enum fuse_operating_mode {
- MODE_PRODUCTION = 3,
- MODE_UNDEFINED,
-};
-
/* Defines the CMAC-AES-128 hash length in 32 bit words. (128 bits = 4 words) */
enum {
HASH_LENGTH = 4
@@ -125,7 +119,6 @@ union scratch3_reg {
int warmboot_save_sdram_params(void);
int warmboot_prepare_code(u32 seg_address, u32 seg_length);
-int sign_data_block(u8 *source, u32 length, u8 *signature);
void wb_start(void); /* Start of WB assembly code */
void wb_end(void); /* End of WB assembly code */
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index c3c352eceb1..32cdfebfc01 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -17,7 +17,9 @@ config TEGRA_CLKRST
config TEGRA_CRYPTO
bool "Tegra AES128 crypto module"
+ select DM_AES
select AES
+ select TEGRA_AES
config TEGRA_GP_PADCTRL
bool
diff --git a/arch/arm/mach-tegra/ap.c b/arch/arm/mach-tegra/ap.c
index f35bdba4d48..a7938ed7910 100644
--- a/arch/arm/mach-tegra/ap.c
+++ b/arch/arm/mach-tegra/ap.c
@@ -37,6 +37,14 @@ int tegra_get_chip(void)
return rev;
}
+u32 tegra_get_major_version(void)
+{
+ struct apb_misc_gp_ctlr *gp =
+ (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE;
+
+ return (readl(&gp->hidrev) & HIDREV_MAJORPREV_MASK) >> HIDREV_MAJORPREV_SHIFT;
+}
+
int tegra_get_sku_info(void)
{
int sku_id;
diff --git a/arch/arm/mach-tegra/cpu.h b/arch/arm/mach-tegra/cpu.h
index 006aae3d070..5477423f4d0 100644
--- a/arch/arm/mach-tegra/cpu.h
+++ b/arch/arm/mach-tegra/cpu.h
@@ -71,6 +71,7 @@ void powerup_cpu(void);
void reset_A9_cpu(int reset);
void start_cpu(u32 reset_vector);
int tegra_get_chip(void);
+u32 tegra_get_major_version(void);
int tegra_get_sku_info(void);
int tegra_get_chip_sku(void);
void adjust_pllp_out_freqs(void);
diff --git a/arch/arm/mach-tegra/crypto.c b/arch/arm/mach-tegra/crypto.c
index 49e6a45243a..1005c815b36 100644
--- a/arch/arm/mach-tegra/crypto.c
+++ b/arch/arm/mach-tegra/crypto.c
@@ -4,164 +4,68 @@
* (C) Copyright 2010 - 2011 NVIDIA Corporation <www.nvidia.com>
*/
+#include <dm.h>
#include <log.h>
#include <linux/errno.h>
#include <asm/arch-tegra/crypto.h>
#include "uboot_aes.h"
-static u8 zero_key[16];
-
-#define AES_CMAC_CONST_RB 0x87 /* from RFC 4493, Figure 2.2 */
-
-enum security_op {
- SECURITY_SIGN = 1 << 0, /* Sign the data */
- SECURITY_ENCRYPT = 1 << 1, /* Encrypt the data */
- SECURITY_DECRYPT = 1 << 2, /* Dectypt the data */
-};
-
-/**
- * Shift a vector left by one bit
- *
- * \param in Input vector
- * \param out Output vector
- * \param size Length of vector in bytes
- */
-static void left_shift_vector(u8 *in, u8 *out, int size)
+int sign_data_block(u8 *source, unsigned int length, u8 *signature)
{
- int carry = 0;
- int i;
-
- for (i = size - 1; i >= 0; i--) {
- out[i] = (in[i] << 1) | carry;
- carry = in[i] >> 7; /* get most significant bit */
+ struct udevice *dev;
+ int ret;
+
+ /* Only one AES engine should be present */
+ ret = uclass_get_device(UCLASS_AES, 0, &dev);
+ if (ret) {
+ log_err("%s: failed to get tegra_aes: %d\n", __func__, ret);
+ return ret;
}
-}
-
-/**
- * Sign a block of data, putting the result into dst.
- *
- * \param key Input AES key, length AES128_KEY_LENGTH
- * \param key_schedule Expanded key to use
- * \param src Source data of length 'num_aes_blocks' blocks
- * \param dst Destination buffer, length AES128_KEY_LENGTH
- * \param num_aes_blocks Number of AES blocks to encrypt
- */
-static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst,
- u32 num_aes_blocks)
-{
- u8 tmp_data[AES128_KEY_LENGTH];
- u8 iv[AES128_KEY_LENGTH] = {0};
- u8 left[AES128_KEY_LENGTH];
- u8 k1[AES128_KEY_LENGTH];
- u8 *cbc_chain_data;
- unsigned int i;
- cbc_chain_data = zero_key; /* Convenient array of 0's for IV */
+ ret = dm_aes_select_key_slot(dev, 128, TEGRA_AES_SLOT_SBK);
+ if (ret)
+ return ret;
- /* compute K1 constant needed by AES-CMAC calculation */
- for (i = 0; i < AES128_KEY_LENGTH; i++)
- tmp_data[i] = 0;
-
- aes_cbc_encrypt_blocks(AES128_KEY_LENGTH, key_schedule, iv,
- tmp_data, left, 1);
-
- left_shift_vector(left, k1, sizeof(left));
-
- if ((left[0] >> 7) != 0) /* get MSB of L */
- k1[AES128_KEY_LENGTH - 1] ^= AES_CMAC_CONST_RB;
-
- /* compute the AES-CMAC value */
- for (i = 0; i < num_aes_blocks; i++) {
- /* Apply the chain data */
- aes_apply_cbc_chain_data(cbc_chain_data, src, tmp_data);
-
- /* for the final block, XOR K1 into the IV */
- if (i == num_aes_blocks - 1)
- aes_apply_cbc_chain_data(tmp_data, k1, tmp_data);
-
- /* encrypt the AES block */
- aes_encrypt(AES128_KEY_LENGTH, tmp_data,
- key_schedule, dst);
-
- debug("sign_obj: block %d of %d\n", i, num_aes_blocks);
-
- /* Update pointers for next loop. */
- cbc_chain_data = dst;
- src += AES128_KEY_LENGTH;
- }
+ return dm_aes_cmac(dev, source, signature,
+ DIV_ROUND_UP(length, AES_BLOCK_LENGTH));
}
-/**
- * Decrypt, encrypt or sign a block of data (depending on security mode).
- *
- * \param key Input AES key, length AES128_KEY_LENGTH
- * \param oper Security operations mask to perform (enum security_op)
- * \param src Source data
- * \param length Size of source data
- * \param sig_dst Destination address for signature, AES128_KEY_LENGTH bytes
- */
-static int tegra_crypto_core(u8 *key, enum security_op oper, u8 *src,
- u32 length, u8 *sig_dst)
+int encrypt_data_block(u8 *source, u8 *dest, unsigned int length)
{
- u32 num_aes_blocks;
- u8 key_schedule[AES128_EXPAND_KEY_LENGTH];
- u8 iv[AES128_KEY_LENGTH] = {0};
-
- debug("%s: length = %d\n", __func__, length);
-
- aes_expand_key(key, AES128_KEY_LENGTH, key_schedule);
-
- num_aes_blocks = (length + AES128_KEY_LENGTH - 1) / AES128_KEY_LENGTH;
-
- if (oper & SECURITY_DECRYPT) {
- /* Perform this in place, resulting in src being decrypted. */
- debug("%s: begin decryption\n", __func__);
- aes_cbc_decrypt_blocks(AES128_KEY_LENGTH, key_schedule, iv, src,
- src, num_aes_blocks);
- debug("%s: end decryption\n", __func__);
- }
-
- if (oper & SECURITY_ENCRYPT) {
- /* Perform this in place, resulting in src being encrypted. */
- debug("%s: begin encryption\n", __func__);
- aes_cbc_encrypt_blocks(AES128_KEY_LENGTH, key_schedule, iv, src,
- src, num_aes_blocks);
- debug("%s: end encryption\n", __func__);
- }
-
- if (oper & SECURITY_SIGN) {
- /* encrypt the data, overwriting the result in signature. */
- debug("%s: begin signing\n", __func__);
- sign_object(key, key_schedule, src, sig_dst, num_aes_blocks);
- debug("%s: end signing\n", __func__);
+ struct udevice *dev;
+ int ret;
+
+ /* Only one AES engine should be present */
+ ret = uclass_get_device(UCLASS_AES, 0, &dev);
+ if (ret) {
+ log_err("%s: failed to get tegra_aes: %d\n", __func__, ret);
+ return ret;
}
- return 0;
-}
+ ret = dm_aes_select_key_slot(dev, 128, TEGRA_AES_SLOT_SBK);
+ if (ret)
+ return ret;
-/**
- * Tegra crypto group
- */
-int sign_data_block(u8 *source, unsigned int length, u8 *signature)
-{
- return tegra_crypto_core(zero_key, SECURITY_SIGN, source,
- length, signature);
+ return dm_aes_cbc_encrypt(dev, (u8 *)AES_ZERO_BLOCK, source, dest,
+ DIV_ROUND_UP(length, AES_BLOCK_LENGTH));
}
-int sign_enc_data_block(u8 *source, unsigned int length, u8 *signature, u8 *key)
+int decrypt_data_block(u8 *source, u8 *dest, unsigned int length)
{
- return tegra_crypto_core(key, SECURITY_SIGN, source,
- length, signature);
-}
+ struct udevice *dev;
+ int ret;
+
+ /* Only one AES engine should be present */
+ ret = uclass_get_device(UCLASS_AES, 0, &dev);
+ if (ret) {
+ log_err("%s: failed to get tegra_aes: %d\n", __func__, ret);
+ return ret;
+ }
-int encrypt_data_block(u8 *source, unsigned int length, u8 *key)
-{
- return tegra_crypto_core(key, SECURITY_ENCRYPT, source,
- length, NULL);
-}
+ ret = dm_aes_select_key_slot(dev, 128, TEGRA_AES_SLOT_SBK);
+ if (ret)
+ return ret;
-int decrypt_data_block(u8 *source, unsigned int length, u8 *key)
-{
- return tegra_crypto_core(key, SECURITY_DECRYPT, source,
- length, NULL);
+ return dm_aes_cbc_decrypt(dev, (u8 *)AES_ZERO_BLOCK, source, dest,
+ DIV_ROUND_UP(length, AES_BLOCK_LENGTH));
}
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
index e9b5259ac70..abdf6504161 100644
--- a/arch/arm/mach-tegra/fuse.c
+++ b/arch/arm/mach-tegra/fuse.c
@@ -39,7 +39,7 @@ static u32 tegra_fuse_readl(unsigned long offset)
return readl(NV_PA_FUSE_BASE + offset);
}
-static void tegra_fuse_init(void)
+void tegra_fuse_init(void)
{
u32 reg;
@@ -49,8 +49,11 @@ static void tegra_fuse_init(void)
* this bit fuse region will not work.
*/
reg = readl_relaxed(NV_PA_CLK_RST_BASE + 0x48);
- reg |= BIT(28);
- writel(reg, NV_PA_CLK_RST_BASE + 0x48);
+
+ if (reg & BIT(28))
+ return;
+
+ writel(reg | BIT(28), NV_PA_CLK_RST_BASE + 0x48);
clock_enable(PERIPH_ID_FUSE);
udelay(2);
@@ -148,3 +151,57 @@ unsigned long long tegra_chip_uid(void)
return uid;
}
+
+static int tegra_is_production_mode_fuse_set(struct fuse_regs *fuse)
+{
+ return readl(&fuse->production_mode);
+}
+
+static int tegra_is_odm_production_mode_fuse_set(struct fuse_regs *fuse)
+{
+ return readl(&fuse->security_mode);
+}
+
+static int tegra_is_failure_analysis_mode(struct fuse_regs *fuse)
+{
+ return readl(&fuse->fa);
+}
+
+static int tegra_is_sbk_zeroes(struct fuse_regs *fuse)
+{
+ int i;
+
+ for (i = 0; i < 4; i++)
+ if (readl(&fuse->sbk[i]))
+ return 0;
+
+ return 1;
+}
+
+static int tegra_is_production_mode(struct fuse_regs *fuse)
+{
+ if (!tegra_get_major_version())
+ return 1;
+
+ return !tegra_is_failure_analysis_mode(fuse) &&
+ tegra_is_production_mode_fuse_set(fuse);
+}
+
+enum fuse_operating_mode tegra_fuse_get_operation_mode(void)
+{
+ struct fuse_regs *fuse = (struct fuse_regs *)NV_PA_FUSE_BASE;
+
+ tegra_fuse_init();
+
+ if (tegra_is_production_mode(fuse)) {
+ if (!tegra_is_odm_production_mode_fuse_set(fuse))
+ return MODE_PRODUCTION;
+ else
+ if (tegra_is_sbk_zeroes(fuse))
+ return MODE_ODM_PRODUCTION_OPEN;
+ else
+ return MODE_ODM_PRODUCTION_SECURE;
+ }
+
+ return MODE_UNDEFINED;
+}
diff --git a/arch/arm/mach-tegra/tegra124/bct.c b/arch/arm/mach-tegra/tegra124/bct.c
index 4dc4b7138ab..676b68dc5de 100644
--- a/arch/arm/mach-tegra/tegra124/bct.c
+++ b/arch/arm/mach-tegra/tegra124/bct.c
@@ -9,12 +9,10 @@
#include <vsprintf.h>
#include <linux/string.h>
#include <asm/arch-tegra/crypto.h>
+#include <asm/arch-tegra/fuse.h>
#include "bct.h"
#include "uboot_aes.h"
-/* Device with "sbk burned: false" will expose zero key */
-const u8 nosbk[AES128_KEY_LENGTH] = { 0 };
-
/*
* @param bct boot config table start in RAM
* @param ect bootloader start in RAM
@@ -26,29 +24,25 @@ static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size)
struct nvboot_config_table *bct_tbl = NULL;
u8 ebt_hash[AES128_KEY_LENGTH] = { 0 };
u8 bct_hash[AES128_KEY_LENGTH] = { 0 };
- u8 sbk[AES128_KEY_LENGTH] = { 0 };
u8 *sbct = bct + UBCT_LENGTH;
bool encrypted;
int ret;
ebt_size = roundup(ebt_size, EBT_ALIGNMENT);
- memcpy(sbk, (u8 *)(bct + UBCT_LENGTH + SBCT_LENGTH),
- NVBOOT_CMAC_AES_HASH_LENGTH * 4);
-
- encrypted = memcmp(&sbk, &nosbk, AES128_KEY_LENGTH);
+ encrypted = tegra_fuse_get_operation_mode() == MODE_ODM_PRODUCTION_SECURE;
if (encrypted) {
- ret = decrypt_data_block(sbct, SBCT_LENGTH, sbk);
+ ret = decrypt_data_block(sbct, sbct, SBCT_LENGTH);
if (ret)
return 1;
- ret = encrypt_data_block(ebt, ebt_size, sbk);
+ ret = encrypt_data_block(ebt, ebt, ebt_size);
if (ret)
return 1;
}
- ret = sign_enc_data_block(ebt, ebt_size, ebt_hash, sbk);
+ ret = sign_data_block(ebt, ebt_size, ebt_hash);
if (ret)
return 1;
@@ -61,12 +55,12 @@ static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size)
bct_tbl->bootloader[0].length = ebt_size;
if (encrypted) {
- ret = encrypt_data_block(sbct, SBCT_LENGTH, sbk);
+ ret = encrypt_data_block(sbct, sbct, SBCT_LENGTH);
if (ret)
return 1;
}
- ret = sign_enc_data_block(sbct, SBCT_LENGTH, bct_hash, sbk);
+ ret = sign_data_block(sbct, SBCT_LENGTH, bct_hash);
if (ret)
return 1;
diff --git a/arch/arm/mach-tegra/tegra20/Kconfig b/arch/arm/mach-tegra/tegra20/Kconfig
index bedbedade7b..b07b5a15585 100644
--- a/arch/arm/mach-tegra/tegra20/Kconfig
+++ b/arch/arm/mach-tegra/tegra20/Kconfig
@@ -54,6 +54,10 @@ config TARGET_SEABOARD
select TEGRA_LP0
select TEGRA_PMU
+config TARGET_SAMSUNG_N1
+ bool "Samsung Tegra20 N1 board"
+ select BOARD_LATE_INIT
+
config TARGET_STAR
bool "LG Tegra20 Star board"
select BOARD_LATE_INIT
@@ -92,6 +96,7 @@ source "board/compal/paz00/Kconfig"
source "board/acer/picasso/Kconfig"
source "board/avionic-design/plutux/Kconfig"
source "board/nvidia/seaboard/Kconfig"
+source "board/samsung/n1/Kconfig"
source "board/lg/star/Kconfig"
source "board/avionic-design/tec/Kconfig"
source "board/asus/transformer-t20/Kconfig"
diff --git a/arch/arm/mach-tegra/tegra20/bct.c b/arch/arm/mach-tegra/tegra20/bct.c
index 253cb243676..0270cf592c1 100644
--- a/arch/arm/mach-tegra/tegra20/bct.c
+++ b/arch/arm/mach-tegra/tegra20/bct.c
@@ -9,12 +9,10 @@
#include <vsprintf.h>
#include <linux/string.h>
#include <asm/arch-tegra/crypto.h>
+#include <asm/arch-tegra/fuse.h>
#include "bct.h"
#include "uboot_aes.h"
-/* Device with "sbk burned: false" will expose zero key */
-const u8 nosbk[AES128_KEY_LENGTH] = { 0 };
-
/*
* @param bct boot config table start in RAM
* @param ect bootloader start in RAM
@@ -25,7 +23,6 @@ static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size)
{
struct nvboot_config_table *bct_tbl = NULL;
u8 ebt_hash[AES128_KEY_LENGTH] = { 0 };
- u8 sbk[AES128_KEY_LENGTH] = { 0 };
u8 *bct_hash = bct;
bool encrypted;
int ret;
@@ -34,22 +31,19 @@ static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size)
ebt_size = roundup(ebt_size, EBT_ALIGNMENT);
- memcpy(sbk, (u8 *)(bct + BCT_LENGTH),
- NVBOOT_CMAC_AES_HASH_LENGTH * 4);
-
- encrypted = memcmp(&sbk, &nosbk, AES128_KEY_LENGTH);
+ encrypted = tegra_fuse_get_operation_mode() == MODE_ODM_PRODUCTION_SECURE;
if (encrypted) {
- ret = decrypt_data_block(bct, BCT_LENGTH, sbk);
+ ret = decrypt_data_block(bct, bct, BCT_LENGTH);
if (ret)
return 1;
- ret = encrypt_data_block(ebt, ebt_size, sbk);
+ ret = encrypt_data_block(ebt, ebt, ebt_size);
if (ret)
return 1;
}
- ret = sign_enc_data_block(ebt, ebt_size, ebt_hash, sbk);
+ ret = sign_data_block(ebt, ebt_size, ebt_hash);
if (ret)
return 1;
@@ -62,12 +56,12 @@ static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size)
bct_tbl->bootloader[0].length = ebt_size;
if (encrypted) {
- ret = encrypt_data_block(bct, BCT_LENGTH, sbk);
+ ret = encrypt_data_block(bct, bct, BCT_LENGTH);
if (ret)
return 1;
}
- ret = sign_enc_data_block(bct, BCT_LENGTH, bct_hash, sbk);
+ ret = sign_data_block(bct, BCT_LENGTH, bct_hash);
if (ret)
return 1;
diff --git a/arch/arm/mach-tegra/tegra20/warmboot.c b/arch/arm/mach-tegra/tegra20/warmboot.c
index 18034c83a1c..3fd39fe3c1a 100644
--- a/arch/arm/mach-tegra/tegra20/warmboot.c
+++ b/arch/arm/mach-tegra/tegra20/warmboot.c
@@ -19,6 +19,7 @@
#include <asm/arch-tegra/pmc.h>
#include <asm/arch-tegra/fuse.h>
#include <asm/arch-tegra/warmboot.h>
+#include <asm/arch-tegra/crypto.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -182,98 +183,36 @@ int warmboot_save_sdram_params(void)
return 0;
}
-static u32 get_major_version(void)
+static void determine_crypto_options(int *is_encrypted, int *is_signed)
{
- u32 major_id;
- struct apb_misc_gp_ctlr *gp =
- (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE;
-
- major_id = (readl(&gp->hidrev) & HIDREV_MAJORPREV_MASK) >>
- HIDREV_MAJORPREV_SHIFT;
- return major_id;
-}
-
-static int is_production_mode_fuse_set(struct fuse_regs *fuse)
-{
- return readl(&fuse->production_mode);
-}
-
-static int is_odm_production_mode_fuse_set(struct fuse_regs *fuse)
-{
- return readl(&fuse->security_mode);
-}
-
-static int is_failure_analysis_mode(struct fuse_regs *fuse)
-{
- return readl(&fuse->fa);
-}
-
-static int ap20_is_odm_production_mode(void)
-{
- struct fuse_regs *fuse = (struct fuse_regs *)NV_PA_FUSE_BASE;
-
- if (!is_failure_analysis_mode(fuse) &&
- is_odm_production_mode_fuse_set(fuse))
- return 1;
- else
- return 0;
-}
-
-static int ap20_is_production_mode(void)
-{
- struct fuse_regs *fuse = (struct fuse_regs *)NV_PA_FUSE_BASE;
-
- if (get_major_version() == 0)
- return 1;
-
- if (!is_failure_analysis_mode(fuse) &&
- is_production_mode_fuse_set(fuse) &&
- !is_odm_production_mode_fuse_set(fuse))
- return 1;
- else
- return 0;
-}
-
-static enum fuse_operating_mode fuse_get_operation_mode(void)
-{
- u32 chip_id;
- struct apb_misc_gp_ctlr *gp =
- (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE;
-
- chip_id = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >>
- HIDREV_CHIPID_SHIFT;
- if (chip_id == CHIPID_TEGRA20) {
- if (ap20_is_odm_production_mode()) {
- printf("!! odm_production_mode is not supported !!\n");
- return MODE_UNDEFINED;
- } else
- if (ap20_is_production_mode())
- return MODE_PRODUCTION;
- else
- return MODE_UNDEFINED;
- }
- return MODE_UNDEFINED;
-}
-
-static void determine_crypto_options(int *is_encrypted, int *is_signed,
- int *use_zero_key)
-{
- switch (fuse_get_operation_mode()) {
+ switch (tegra_fuse_get_operation_mode()) {
+ case MODE_ODM_PRODUCTION_SECURE:
+ *is_encrypted = 1;
+ *is_signed = 1;
+ break;
+ case MODE_ODM_PRODUCTION_OPEN:
case MODE_PRODUCTION:
*is_encrypted = 0;
*is_signed = 1;
- *use_zero_key = 1;
break;
case MODE_UNDEFINED:
default:
*is_encrypted = 0;
*is_signed = 0;
- *use_zero_key = 0;
break;
}
}
-static int sign_wb_code(u32 start, u32 length, int use_zero_key)
+static int encrypt_wb_code(u8 *source, u8 *destination, u32 length)
+{
+ source += offsetof(struct wb_header, random_aes_block);
+ destination += offsetof(struct wb_header, random_aes_block);
+ length -= offsetof(struct wb_header, random_aes_block);
+
+ return encrypt_data_block(source, destination, length);
+}
+
+static int sign_wb_code(u32 start, u32 length)
{
int err;
u8 *source; /* Pointer to source */
@@ -295,10 +234,9 @@ int warmboot_prepare_code(u32 seg_address, u32 seg_length)
struct wb_header *dst_header; /* Pointer to dest WB header */
int is_encrypted; /* Segment is encrypted */
int is_signed; /* Segment is signed */
- int use_zero_key; /* Use key of all zeros */
/* Determine crypto options. */
- determine_crypto_options(&is_encrypted, &is_signed, &use_zero_key);
+ determine_crypto_options(&is_encrypted, &is_signed);
/* Get the actual code limits. */
length = roundup(((u32)wb_end - (u32)wb_start), 16);
@@ -346,18 +284,15 @@ int warmboot_prepare_code(u32 seg_address, u32 seg_length)
dst_header->entry_point = NV_WB_RUN_ADDRESS;
dst_header->code_length = length;
- if (is_encrypted) {
- printf("!!!! Encryption is not supported !!!!\n");
- dst_header->length_insecure = 0;
- err = -EACCES;
- goto fail;
- } else
- /* copy the wb code directly following dst_header. */
- memcpy((char *)(dst_header+1), (char *)wb_start, length);
+ if (is_encrypted)
+ encrypt_wb_code((u8 *)wb_start, (u8 *)dst_header,
+ length + sizeof(struct wb_header));
+ else
+ /* copy the wb code directly following dst_header */
+ memcpy((char *)(dst_header + 1), (char *)wb_start, length);
if (is_signed)
- err = sign_wb_code(seg_address, dst_header->length_insecure,
- use_zero_key);
+ err = sign_wb_code(seg_address, dst_header->length_insecure);
fail:
if (err)
diff --git a/arch/arm/mach-tegra/tegra30/Kconfig b/arch/arm/mach-tegra/tegra30/Kconfig
index b5099ce67fc..4da67b19990 100644
--- a/arch/arm/mach-tegra/tegra30/Kconfig
+++ b/arch/arm/mach-tegra/tegra30/Kconfig
@@ -16,6 +16,10 @@ config TARGET_CARDHU
bool "NVIDIA Tegra30 Cardhu evaluation board"
select BOARD_LATE_INIT
+config TARGET_CHAGALL
+ bool "Pegatron Tegra30 Chagall board"
+ select BOARD_LATE_INIT
+
config TARGET_COLIBRI_T30
bool "Toradex Colibri T30 board"
select BOARD_LATE_INIT
@@ -64,6 +68,7 @@ config SYS_SOC
source "board/toradex/apalis_t30/Kconfig"
source "board/nvidia/beaver/Kconfig"
source "board/nvidia/cardhu/Kconfig"
+source "board/pegatron/chagall/Kconfig"
source "board/toradex/colibri_t30/Kconfig"
source "board/htc/endeavoru/Kconfig"
source "board/asus/grouper/Kconfig"
diff --git a/arch/arm/mach-tegra/tegra30/bct.c b/arch/arm/mach-tegra/tegra30/bct.c
index 398ba1de386..de668214517 100644
--- a/arch/arm/mach-tegra/tegra30/bct.c
+++ b/arch/arm/mach-tegra/tegra30/bct.c
@@ -9,12 +9,10 @@
#include <vsprintf.h>
#include <linux/string.h>
#include <asm/arch-tegra/crypto.h>
+#include <asm/arch-tegra/fuse.h>
#include "bct.h"
#include "uboot_aes.h"
-/* Device with "sbk burned: false" will expose zero key */
-const u8 nosbk[AES128_KEY_LENGTH] = { 0 };
-
/*
* @param bct boot config table start in RAM
* @param ect bootloader start in RAM
@@ -25,7 +23,6 @@ static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size)
{
struct nvboot_config_table *bct_tbl = NULL;
u8 ebt_hash[AES128_KEY_LENGTH] = { 0 };
- u8 sbk[AES128_KEY_LENGTH] = { 0 };
u8 *bct_hash = bct;
bool encrypted;
int ret;
@@ -34,22 +31,19 @@ static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size)
ebt_size = roundup(ebt_size, EBT_ALIGNMENT);
- memcpy(sbk, (u8 *)(bct + BCT_LENGTH),
- NVBOOT_CMAC_AES_HASH_LENGTH * 4);
-
- encrypted = memcmp(&sbk, &nosbk, AES128_KEY_LENGTH);
+ encrypted = tegra_fuse_get_operation_mode() == MODE_ODM_PRODUCTION_SECURE;
if (encrypted) {
- ret = decrypt_data_block(bct, BCT_LENGTH, sbk);
+ ret = decrypt_data_block(bct, bct, BCT_LENGTH);
if (ret)
return 1;
- ret = encrypt_data_block(ebt, ebt_size, sbk);
+ ret = encrypt_data_block(ebt, ebt, ebt_size);
if (ret)
return 1;
}
- ret = sign_enc_data_block(ebt, ebt_size, ebt_hash, sbk);
+ ret = sign_data_block(ebt, ebt_size, ebt_hash);
if (ret)
return 1;
@@ -62,12 +56,12 @@ static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size)
bct_tbl->bootloader[0].length = ebt_size;
if (encrypted) {
- ret = encrypt_data_block(bct, BCT_LENGTH, sbk);
+ ret = encrypt_data_block(bct, bct, BCT_LENGTH);
if (ret)
return 1;
}
- ret = sign_enc_data_block(bct, BCT_LENGTH, bct_hash, sbk);
+ ret = sign_data_block(bct, BCT_LENGTH, bct_hash);
if (ret)
return 1;
diff --git a/board/pegatron/chagall/Kconfig b/board/pegatron/chagall/Kconfig
new file mode 100644
index 00000000000..8c229d0e333
--- /dev/null
+++ b/board/pegatron/chagall/Kconfig
@@ -0,0 +1,13 @@
+if TARGET_CHAGALL
+
+config SYS_BOARD
+ default "chagall"
+
+config SYS_VENDOR
+ default "pegatron"
+
+config TEGRA_BOARD_STRING
+ string "Default Tegra board name"
+ default "Pegatron Chagall"
+
+endif
diff --git a/board/pegatron/chagall/MAINTAINERS b/board/pegatron/chagall/MAINTAINERS
new file mode 100644
index 00000000000..5ebd5940f42
--- /dev/null
+++ b/board/pegatron/chagall/MAINTAINERS
@@ -0,0 +1,7 @@
+CHAGALL BOARD
+M: Svyatoslav Ryhel <clamor95@gmail.com>
+S: Maintained
+F: arch/arm/dts/tegra30-pegatron-chagall.dts
+F: board/pegatron/chagall/
+F: configs/chagall_defconfig
+F: doc/board/pegatron/chagall.rst
diff --git a/board/pegatron/chagall/Makefile b/board/pegatron/chagall/Makefile
new file mode 100644
index 00000000000..17cfef50987
--- /dev/null
+++ b/board/pegatron/chagall/Makefile
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# (C) Copyright 2010-2012
+# NVIDIA Corporation <www.nvidia.com>
+#
+# (C) Copyright 2021
+# Svyatoslav Ryhel <clamor95@gmail.com>
+
+obj-$(CONFIG_XPL_BUILD) += chagall-spl.o
+
+obj-y += chagall.o
diff --git a/board/pegatron/chagall/chagall-spl.c b/board/pegatron/chagall/chagall-spl.c
new file mode 100644
index 00000000000..6c271973ada
--- /dev/null
+++ b/board/pegatron/chagall/chagall-spl.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Chagall SPL stage configuration
+ *
+ * (C) Copyright 2010-2013
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * (C) Copyright 2021
+ * Svyatoslav Ryhel <clamor95@gmail.com>
+ */
+
+#include <asm/arch/tegra.h>
+#include <asm/arch-tegra/tegra_i2c.h>
+#include <linux/delay.h>
+
+#define TPS65911_I2C_ADDR (0x2D << 1)
+#define TPS65911_VDDCTRL_OP_REG 0x28
+#define TPS65911_VDDCTRL_SR_REG 0x27
+#define TPS65911_VDDCTRL_OP_DATA (0x2400 | TPS65911_VDDCTRL_OP_REG)
+#define TPS65911_VDDCTRL_SR_DATA (0x0100 | TPS65911_VDDCTRL_SR_REG)
+
+#define TPS62361B_I2C_ADDR (0x60 << 1)
+#define TPS62361B_SET3_REG 0x03
+#define TPS62361B_SET3_DATA (0x4600 | TPS62361B_SET3_REG)
+
+void pmic_enable_cpu_vdd(void)
+{
+ /* Set VDD_CORE to 1.200V. */
+ tegra_i2c_ll_write(TPS62361B_I2C_ADDR, TPS62361B_SET3_DATA);
+
+ udelay(1000);
+
+ /*
+ * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus.
+ * First set VDD to 1.0125V, then enable the VDD regulator.
+ */
+ tegra_i2c_ll_write(TPS65911_I2C_ADDR, TPS65911_VDDCTRL_OP_DATA);
+ udelay(1000);
+ tegra_i2c_ll_write(TPS65911_I2C_ADDR, TPS65911_VDDCTRL_SR_DATA);
+ udelay(10 * 1000);
+}
diff --git a/board/pegatron/chagall/chagall.c b/board/pegatron/chagall/chagall.c
new file mode 100644
index 00000000000..1412c4f9b60
--- /dev/null
+++ b/board/pegatron/chagall/chagall.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * (C) Copyright 2010-2013
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * (C) Copyright 2021
+ * Svyatoslav Ryhel <clamor95@gmail.com>
+ */
+
+/* Chagall derives from Cardhu board */
+
+#include <fdt_support.h>
+
+#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
+int ft_board_setup(void *blob, struct bd_info *bd)
+{
+ /* Remove TrustZone nodes */
+ fdt_del_node_and_alias(blob, "/firmware");
+ fdt_del_node_and_alias(blob, "/reserved-memory/trustzone@bfe00000");
+
+ return 0;
+}
+#endif
diff --git a/board/pegatron/chagall/chagall.env b/board/pegatron/chagall/chagall.env
new file mode 100644
index 00000000000..68bf51bdc3c
--- /dev/null
+++ b/board/pegatron/chagall/chagall.env
@@ -0,0 +1,9 @@
+button_cmd_0_name=Volume Down
+button_cmd_0=bootmenu
+
+bootmenu_0=mount external storage=usb start && ums 0 mmc 1; bootmenu
+bootmenu_1=fastboot=echo Starting Fastboot protocol ...; fastboot usb 0; bootmenu
+bootmenu_2=reboot RCM=enterrcm
+bootmenu_3=reboot=reset
+bootmenu_4=power off=poweroff
+bootmenu_delay=-1
diff --git a/board/samsung/n1/Kconfig b/board/samsung/n1/Kconfig
new file mode 100644
index 00000000000..a5e5edda9e2
--- /dev/null
+++ b/board/samsung/n1/Kconfig
@@ -0,0 +1,13 @@
+if TARGET_SAMSUNG_N1
+
+config SYS_BOARD
+ default "n1"
+
+config SYS_VENDOR
+ default "samsung"
+
+config TEGRA_BOARD_STRING
+ string "Default Tegra board name"
+ default "Samsung N1"
+
+endif
diff --git a/board/samsung/n1/MAINTAINERS b/board/samsung/n1/MAINTAINERS
new file mode 100644
index 00000000000..798cb56cd37
--- /dev/null
+++ b/board/samsung/n1/MAINTAINERS
@@ -0,0 +1,9 @@
+N1 BOARD
+M: Ion Agorria <ion@agorria.com>
+M: Svyatoslav Ryhel <clamor95@gmail.com>
+S: Maintained
+F: arch/arm/dts/tegra20-samsung-bose.dts
+F: arch/arm/dts/tegra20-samsung-n1.dts
+F: board/samsung/n1/
+F: configs/n1_defconfig
+F: doc/board/samsung/n1.rst
diff --git a/board/samsung/n1/bose.config b/board/samsung/n1/bose.config
new file mode 100644
index 00000000000..6d6d9d3f2ce
--- /dev/null
+++ b/board/samsung/n1/bose.config
@@ -0,0 +1,6 @@
+CONFIG_DEFAULT_DEVICE_TREE="tegra20-samsung-bose"
+CONFIG_SYS_PROMPT="Tegra20 (Bose) # "
+# CONFIG_VIDEO_BRIDGE_SAMSUNG_CMC623 is not set
+# CONFIG_BACKLIGHT_SAMSUNG_CMC623 is not set
+# CONFIG_VIDEO_LCD_SONY_L4F00430T01 is not set
+CONFIG_VIDEO_LCD_SAMSUNG_S6E63M0=y
diff --git a/board/samsung/n1/n1.env b/board/samsung/n1/n1.env
new file mode 100644
index 00000000000..e2b883dbc10
--- /dev/null
+++ b/board/samsung/n1/n1.env
@@ -0,0 +1,16 @@
+#include <env/nvidia/prod_upd.env>
+
+button_cmd_0_name=Volume Down
+button_cmd_0=bootmenu
+
+boot_block_size_r=0x80000
+boot_block_size=0x400
+boot_dev=1
+
+bootmenu_0=mount internal storage=usb start && ums 0 mmc 0; bootmenu
+bootmenu_1=mount external storage=usb start && ums 0 mmc 1; bootmenu
+bootmenu_2=fastboot=echo Starting Fastboot protocol ...; fastboot usb 0; bootmenu
+bootmenu_3=reboot RCM=enterrcm
+bootmenu_4=reboot=reset
+bootmenu_5=power off=poweroff
+bootmenu_delay=-1
diff --git a/cmd/bdinfo.c b/cmd/bdinfo.c
index ae9e1923eac..20c8c97f0cd 100644
--- a/cmd/bdinfo.c
+++ b/cmd/bdinfo.c
@@ -46,6 +46,7 @@ void bdinfo_print_num_ll(const char *name, unsigned long long value)
static void print_eth(void)
{
const int idx = eth_get_dev_index();
+ char ipstr[] = "ipaddr\0\0";
uchar enetaddr[6];
char name[10];
int ret;
@@ -62,7 +63,11 @@ static void print_eth(void)
printf("%-12s= (not set)\n", name);
else
printf("%-12s= %pM\n", name, enetaddr);
- printf("IP addr = %s\n", env_get("ipaddr"));
+
+ if (idx > 0)
+ sprintf(ipstr, "ipaddr%d", idx);
+
+ printf("IP addr = %s\n", env_get(ipstr));
}
void bdinfo_print_mhz(const char *name, unsigned long hz)
diff --git a/configs/chagall_defconfig b/configs/chagall_defconfig
new file mode 100644
index 00000000000..9ad5fb98a8a
--- /dev/null
+++ b/configs/chagall_defconfig
@@ -0,0 +1,80 @@
+CONFIG_ARM=y
+CONFIG_ARCH_TEGRA=y
+CONFIG_SUPPORT_PASSING_ATAGS=y
+CONFIG_CMDLINE_TAG=y
+CONFIG_INITRD_TAG=y
+CONFIG_TEXT_BASE=0x80110000
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_ENV_SOURCE_FILE="chagall"
+CONFIG_ENV_SIZE=0x3000
+CONFIG_ENV_OFFSET=0xFFFFD000
+CONFIG_DEFAULT_DEVICE_TREE="tegra30-pegatron-chagall"
+CONFIG_SPL_STACK=0x800ffffc
+CONFIG_SPL_TEXT_BASE=0x80108000
+CONFIG_SYS_LOAD_ADDR=0x82000000
+CONFIG_TEGRA30=y
+CONFIG_TARGET_CHAGALL=y
+CONFIG_BUTTON_CMD=y
+CONFIG_BOOTDELAY=0
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_KEYED_CTRLC=y
+CONFIG_OF_BOARD_SETUP=y
+CONFIG_OF_SYSTEM_SETUP=y
+CONFIG_BOOTCOMMAND="bootflow scan; echo 'Boot configuration not found... Power off in 3 sec'; sleep 3; poweroff"
+CONFIG_SYS_PBSIZE=2084
+CONFIG_SPL_FOOTPRINT_LIMIT=y
+CONFIG_SPL_MAX_FOOTPRINT=0x8000
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_HAVE_INIT_STACK=y
+CONFIG_SPL_SYS_MALLOC=y
+CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y
+CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x80090000
+CONFIG_SPL_SYS_MALLOC_SIZE=0x10000
+CONFIG_SYS_PROMPT="Tegra30 (Chagall) # "
+# CONFIG_CMD_BOOTEFI_BOOTMGR is not set
+CONFIG_CMD_BOOTMENU=y
+# CONFIG_CMD_IMI is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_POWEROFF=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+CONFIG_CMD_UMS_ABORT_KEYED=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_PAUSE=y
+CONFIG_CMD_REGULATOR=y
+CONFIG_CMD_EXT4_WRITE=y
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_ENV_OVERWRITE=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_SYS_MMC_ENV_PART=2
+CONFIG_BUTTON=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x91000000
+CONFIG_FASTBOOT_BUF_SIZE=0x10000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
+CONFIG_SYS_I2C_TEGRA=y
+CONFIG_BUTTON_KEYBOARD=y
+CONFIG_DM_PMIC=y
+CONFIG_DM_PMIC_TPS65910=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_TPS65911=y
+CONFIG_PWM_TEGRA=y
+CONFIG_SYS_NS16550=y
+CONFIG_SYSRESET_TPS65910=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_TEGRA=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_USB_GADGET=y
+CONFIG_CI_UDC=y
+CONFIG_VIDEO=y
+# CONFIG_VIDEO_LOGO is not set
+CONFIG_VIDEO_BRIDGE=y
+CONFIG_VIDEO_BRIDGE_LVDS_CODEC=y
+CONFIG_VIDEO_TEGRA=y
diff --git a/configs/n1_defconfig b/configs/n1_defconfig
new file mode 100644
index 00000000000..da76c59412d
--- /dev/null
+++ b/configs/n1_defconfig
@@ -0,0 +1,92 @@
+CONFIG_ARM=y
+CONFIG_ARCH_TEGRA=y
+CONFIG_SUPPORT_PASSING_ATAGS=y
+CONFIG_CMDLINE_TAG=y
+CONFIG_INITRD_TAG=y
+CONFIG_TEXT_BASE=0x00110000
+CONFIG_NR_DRAM_BANKS=2
+CONFIG_ENV_SOURCE_FILE="n1"
+CONFIG_ENV_SIZE=0x3000
+CONFIG_ENV_OFFSET=0xFFFFD000
+CONFIG_DEFAULT_DEVICE_TREE="tegra20-samsung-n1"
+CONFIG_SPL_STACK=0xffffc
+CONFIG_SPL_TEXT_BASE=0x00108000
+CONFIG_SYS_LOAD_ADDR=0x2000000
+CONFIG_TEGRA20=y
+CONFIG_TARGET_SAMSUNG_N1=y
+CONFIG_TEGRA_ENABLE_UARTB=y
+CONFIG_CMD_EBTUPDATE=y
+CONFIG_BUTTON_CMD=y
+CONFIG_BOOTDELAY=0
+CONFIG_AUTOBOOT_KEYED=y
+CONFIG_AUTOBOOT_KEYED_CTRLC=y
+CONFIG_OF_SYSTEM_SETUP=y
+CONFIG_BOOTCOMMAND="bootflow scan; echo 'Boot configuration not found... Power off in 3 sec'; sleep 3; poweroff"
+CONFIG_SYS_PBSIZE=2085
+CONFIG_SPL_FOOTPRINT_LIMIT=y
+CONFIG_SPL_MAX_FOOTPRINT=0x8000
+# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
+CONFIG_SPL_HAVE_INIT_STACK=y
+CONFIG_SPL_SYS_MALLOC=y
+CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y
+CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x90000
+CONFIG_SPL_SYS_MALLOC_SIZE=0x10000
+CONFIG_SYS_PROMPT="Tegra20 (N1) # "
+# CONFIG_CMD_BOOTEFI_BOOTMGR is not set
+CONFIG_CMD_BOOTMENU=y
+# CONFIG_CMD_IMI is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_GPT_RENAME=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_POWEROFF=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_USB_MASS_STORAGE=y
+CONFIG_CMD_UMS_ABORT_KEYED=y
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_PAUSE=y
+CONFIG_CMD_EXT4_WRITE=y
+# CONFIG_SPL_DOS_PARTITION is not set
+# CONFIG_SPL_EFI_PARTITION is not set
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_SYS_MMC_ENV_PART=2
+CONFIG_BUTTON=y
+CONFIG_USB_FUNCTION_FASTBOOT=y
+CONFIG_FASTBOOT_BUF_ADDR=0x11000000
+CONFIG_FASTBOOT_BUF_SIZE=0x5000000
+CONFIG_FASTBOOT_FLASH=y
+CONFIG_FASTBOOT_FLASH_MMC_DEV=0
+CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
+CONFIG_DM_I2C_GPIO=y
+CONFIG_SYS_I2C_TEGRA=y
+CONFIG_BUTTON_KEYBOARD=y
+CONFIG_DM_PMIC=y
+CONFIG_DM_PMIC_MAX8907=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_MAX8907=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_SYS_NS16550=y
+CONFIG_TEGRA20_SLINK=y
+CONFIG_SYSRESET_MAX8907=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_TEGRA=y
+CONFIG_USB_ULPI_VIEWPORT=y
+CONFIG_USB_ULPI=y
+CONFIG_USB_KEYBOARD=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="Samsung"
+CONFIG_USB_GADGET_VENDOR_NUM=0x04e8
+CONFIG_USB_GADGET_PRODUCT_NUM=0x685F
+CONFIG_CI_UDC=y
+CONFIG_VIDEO=y
+# CONFIG_VIDEO_LOGO is not set
+# CONFIG_VIDEO_BPP8 is not set
+CONFIG_VIDEO_BRIDGE=y
+CONFIG_VIDEO_TEGRA=y
+CONFIG_VIDEO_BRIDGE_SAMSUNG_CMC623=y
+CONFIG_BACKLIGHT_SAMSUNG_CMC623=y
+CONFIG_VIDEO_LCD_SONY_L4F00430T01=y
diff --git a/doc/board/index.rst b/doc/board/index.rst
index e084c7fb1df..7870f1bc246 100644
--- a/doc/board/index.rst
+++ b/doc/board/index.rst
@@ -47,6 +47,7 @@ Board-specific doc
nxp/index
openpiton/index
ouya/index
+ pegatron/index
phytec/index
purism/index
qualcomm/index
diff --git a/doc/board/pegatron/chagall.rst b/doc/board/pegatron/chagall.rst
new file mode 100644
index 00000000000..18ed425ec73
--- /dev/null
+++ b/doc/board/pegatron/chagall.rst
@@ -0,0 +1,41 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+U-Boot for the Pegatron Chagall tablet
+======================================
+
+Quick Start
+-----------
+
+- Build U-Boot
+- Boot
+
+Build U-Boot
+------------
+
+.. code-block:: bash
+
+ $ export CROSS_COMPILE=arm-none-eabi-
+ $ make chagall_defconfig
+ $ make
+
+After the build succeeds, you will obtain the final ``u-boot-dtb-tegra.bin``
+image, ready for loading.
+
+Boot
+----
+
+Currently, U-Boot can be preloaded into RAM via the Fusée Gelée. To enter
+RCM protocol use ``power`` and ``volume up`` key combination from powered
+off device. The host PC should recognize an APX device.
+
+Built U-Boot ``u-boot-dtb-tegra.bin`` can be loaded from fusee-tools
+directory with
+
+.. code-block:: bash
+
+ $ ./run_bootloader.sh -s T30 -t ./bct/chagall.bct
+
+To boot Linux, U-Boot will look for an ``extlinux.conf`` on MicroSD and then on
+eMMC. Additionally, if the Volume Down button is pressed while loading, the
+device will enter bootmenu. Bootmenu contains entries to mount MicroSD and eMMC
+as mass storage, fastboot, reboot, reboot RCM and poweroff.
diff --git a/doc/board/pegatron/index.rst b/doc/board/pegatron/index.rst
new file mode 100644
index 00000000000..8fd8d5fa547
--- /dev/null
+++ b/doc/board/pegatron/index.rst
@@ -0,0 +1,9 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+Pegatron
+========
+
+.. toctree::
+ :maxdepth: 2
+
+ chagall
diff --git a/doc/board/samsung/index.rst b/doc/board/samsung/index.rst
index a1c9636b050..1b92c9518a5 100644
--- a/doc/board/samsung/index.rst
+++ b/doc/board/samsung/index.rst
@@ -8,3 +8,4 @@ Samsung
axy17lte
e850-96
+ n1
diff --git a/doc/board/samsung/n1.rst b/doc/board/samsung/n1.rst
new file mode 100644
index 00000000000..4dbb3141774
--- /dev/null
+++ b/doc/board/samsung/n1.rst
@@ -0,0 +1,51 @@
+.. SPDX-License-Identifier: GPL-2.0+
+
+U-Boot for the Samsung N1 device family
+=======================================
+
+``DISCLAMER!`` Moving your Samsung Galaxy R (GT-I9103) or Samsung Captivate Glide
+(SGH-i927) to use U-Boot assumes replacement of the sboot. Vendor android firmwares
+will no longer be able to run on the device. This replacement IS reversible.
+
+Quick Start
+-----------
+
+- Build U-Boot
+- Boot
+
+Build U-Boot
+------------
+
+Device support is implemented by applying config fragment to a generic board
+defconfig. Generic board defconfig is suitable for Samsung Galaxy R (GT-I9103)
+while Samsung Captivate Glide (SGH-i927) support is provided by applying
+``bose.config`` fragment.
+
+.. code-block:: bash
+
+ $ export CROSS_COMPILE=arm-none-eabi-
+ $ make n1_defconfig bose.config # For Captivate Glide
+ $ make
+
+After the build succeeds, you will obtain the final ``u-boot-dtb-tegra.bin``
+image, ready for further processing.
+
+Boot
+----
+
+Currently, U-Boot can be preloaded into RAM via the NvFlash. To enter
+RCM protocol use ``home`` and ``volume up`` for Galaxy R and ``volume down``
+and ``volume up`` Captivate Glide key combination plus plugging usb in.
+The host PC should recognize an APX device.
+
+Built U-Boot ``u-boot-dtb-tegra.bin`` can be loaded from fusee-tools
+directory with
+
+.. code-block:: bash
+
+ $ ./utils/nvflash_t20 --setbct --bct ./bct/i927.bct --configfile ./utils/flash.cfg --bl u-boot-dtb-tegra.bin --sbk (in form of 0xABCDABCD 4 times) --sync # For Captivate Glide
+
+To boot Linux, U-Boot will look for an ``extlinux.conf`` on MicroSD and then on
+eMMC. Additionally, if the Volume Down button is pressed while loading, the
+device will enter bootmenu. Bootmenu contains entries to mount MicroSD and eMMC
+as mass storage, fastboot, reboot, reboot RCM and poweroff.
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index d26f87364f9..0d58e3910fe 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -10,4 +10,6 @@ source "drivers/crypto/aspeed/Kconfig"
source "drivers/crypto/nuvoton/Kconfig"
+source "drivers/crypto/tegra/Kconfig"
+
endmenu
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 2bd99fc2763..e4a4482b7f3 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -10,3 +10,4 @@ obj-y += fsl/
obj-y += hash/
obj-y += aspeed/
obj-y += nuvoton/
+obj-y += tegra/
diff --git a/drivers/crypto/tegra/Kconfig b/drivers/crypto/tegra/Kconfig
new file mode 100644
index 00000000000..b027609307b
--- /dev/null
+++ b/drivers/crypto/tegra/Kconfig
@@ -0,0 +1,7 @@
+config TEGRA_AES
+ bool "Support the Tegra AES"
+ depends on DM_AES
+ help
+ This provides a means to encrypt and decrypt data using the Tegra
+ Bit Stream Engine for Video/Audio. Also may provide a mean to
+ encrypt/decrypt/sign using already loaded device SBK.
diff --git a/drivers/crypto/tegra/Makefile b/drivers/crypto/tegra/Makefile
new file mode 100644
index 00000000000..a118350fd11
--- /dev/null
+++ b/drivers/crypto/tegra/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-$(CONFIG_$(PHASE_)TEGRA_AES) += tegra_aes.o
diff --git a/drivers/crypto/tegra/tegra_aes.c b/drivers/crypto/tegra/tegra_aes.c
new file mode 100644
index 00000000000..7b374c757ba
--- /dev/null
+++ b/drivers/crypto/tegra/tegra_aes.c
@@ -0,0 +1,591 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for NVIDIA Tegra AES hardware engine residing inside the Bit Stream Engine
+ * for Video (BSEV) hardware block and Bit Stream Engine for Audio (BSEA).
+ *
+ * The programming sequence for this engine is with the help of commands which travel
+ * via a command queue residing between the CPU and the BSEV/BSEA block.
+ *
+ * The hardware key table length is 64 bytes and each key slot divided as follows:
+ * 1. Key - 32 bytes
+ * 2. Original IV - 16 bytes
+ * 3. Updated IV - 16 bytes
+ *
+ * The engine has 4 slots in T20/T30 in which 0th contains SBK loaded by bootrom,
+ * vendor bootloaders tend to clear this slot so that anything booted after can't
+ * use the SBK. This is relevant for U-Boot's chainloaded from these vendor bootloaders.
+ *
+ * Copyright (c) 2010-2011, NVIDIA Corporation
+ * Copyright (c) 2025, Ion Agorria.
+ */
+
+#include <dm.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <time.h>
+#include <linux/delay.h>
+#include <clk.h>
+#include <reset.h>
+#include <uboot_aes.h>
+
+#include <asm/arch-tegra/crypto.h>
+#include <asm/arch-tegra/fuse.h>
+
+/* Make sure pointers will fit register size for AES engine */
+static_assert(sizeof(void *) == sizeof(u32));
+
+#define IRAM_BASE 0x40000000
+
+#define TEGRA_AES_DMA_BUFFER_SIZE (0x4000 / AES_BLOCK_LENGTH)
+#define TEGRA_AES_HW_MAX_KEY_LENGTH AES256_KEY_LENGTH
+#define TEGRA_AES_HW_TABLE_LENGTH (TEGRA_AES_HW_MAX_KEY_LENGTH + AES_BLOCK_LENGTH * 2)
+#define TEGRA_AES_IRAM_MAX_ADDR (IRAM_BASE | TEGRA_AES_KEYTABLEADDR_FIELD)
+
+#define TEGRA_AES_BUSY_TIMEOUT_MS 1000
+
+/* Registers */
+#define TEGRA_AES_ICMDQUE_WR 0x000
+#define TEGRA_AES_CMDQUE_CONTROL 0x008
+#define TEGRA_AES_INTR_STATUS 0x018
+#define TEGRA_AES_INT_ENB 0x040
+#define TEGRA_AES_BSE_CFG 0x044
+#define TEGRA_AES_IRAM_ACCESS_CFG 0x0a0
+#define TEGRA_AES_SECURE_DEST_ADDR 0x100
+#define TEGRA_AES_SECURE_INPUT_SELECT 0x104
+#define TEGRA_AES_SECURE_CONFIG 0x108
+#define TEGRA_AES_SECURE_CONFIG_EXT 0x10c
+
+/* Register field macros */
+#define TEGRA_AES_ENGINE_BUSY_FIELD BIT(0)
+#define TEGRA_AES_ICQ_EMPTY_FIELD BIT(3)
+#define TEGRA_AES_DMA_BUSY_FIELD BIT(23)
+#define TEGRA_AES_SECURE_KEY_SCH_DIS_FIELD BIT(15)
+#define TEGRA_AES_KEYTABLEADDR_FIELD (BIT(17) - 1)
+#define TEGRA_AES_SECURE_KEY_INDEX_SHIFT 20
+#define TEGRA_AES_SECURE_KEY_INDEX_FIELD (0x1f << TEGRA_AES_SECURE_KEY_INDEX_SHIFT)
+#define TEGRA_AES_SECURE_CTR_CNT_SHIFT 16
+#define TEGRA_AES_SECURE_CTR_CNT_FIELD (0xffff << TEGRA_AES_SECURE_CTR_CNT_SHIFT)
+#define TEGRA_AES_BSE_MODE_FIELD 0x1f
+#define TEGRA_AES_BSE_LITTLE_ENDIAN_FIELD BIT(10)
+#define TEGRA_AES_CMDQ_OPCODE_SHIFT 26
+#define TEGRA_AES_CMDQ_CTRL_ICMDQEN_FIELD BIT(1)
+#define TEGRA_AES_CMDQ_CTRL_SRC_STM_SEL_FIELD BIT(4)
+#define TEGRA_AES_CMDQ_CTRL_DST_STM_SEL_FIELD BIT(5)
+#define TEGRA_AES_SECURE_INPUT_ALG_SEL_SHIFT 28
+#define TEGRA_AES_SECURE_INPUT_KEY_LEN_SHIFT 16
+#define TEGRA_AES_SECURE_INPUT_IV_FIELD BIT(10)
+#define TEGRA_AES_SECURE_INPUT_HASH_ENB_FIELD BIT(2)
+#define TEGRA_AES_SECURE_CORE_SEL_SHIFT 9
+#define TEGRA_AES_SECURE_VCTRAM_SEL_SHIFT 7
+#define TEGRA_AES_SECURE_XOR_POS_SHIFT 3
+#define TEGRA_AES_INT_ERROR_MASK 0x6ff000
+
+/* Commands for BSEV/BSEA */
+#define TEGRA_AES_CMD_BLKSTARTENGINE 0x0e
+#define TEGRA_AES_CMD_DMASETUP 0x10
+#define TEGRA_AES_CMD_DMACOMPLETE 0x11
+#define TEGRA_AES_CMD_SETTABLE 0x15
+
+/* Flags for mode */
+#define TEGRA_AES_MODE_ENCRYPT BIT(0)
+#define TEGRA_AES_MODE_CBC BIT(1)
+#define TEGRA_AES_MODE_UPDATE_IV BIT(2)
+#define TEGRA_AES_MODE_HASH BIT(3)
+
+struct tegra_aes_priv {
+ void *regs;
+ void *iram_addr;
+
+ struct reset_ctl reset_ctl;
+ struct reset_ctl reset_ctl_vde;
+
+ struct clk *clk;
+ struct clk *clk_parent;
+
+ u8 current_key_size;
+ bool sbk_available;
+};
+
+static bool tegra_aes_is_busy(struct tegra_aes_priv *priv, bool dma_wait)
+{
+ u32 value = readl(priv->regs + TEGRA_AES_INTR_STATUS);
+ bool engine_busy = value & TEGRA_AES_ENGINE_BUSY_FIELD;
+ bool non_empty_queue = !(value & TEGRA_AES_ICQ_EMPTY_FIELD);
+ bool dma_busy = dma_wait && (value & TEGRA_AES_DMA_BUSY_FIELD);
+
+ log_debug("%s - e:%d q:%d dma:%d\n", __func__, engine_busy, non_empty_queue, dma_busy);
+
+ return engine_busy || non_empty_queue || dma_busy;
+}
+
+static u32 tegra_aes_check_error(struct tegra_aes_priv *priv)
+{
+ u32 value = readl(priv->regs + TEGRA_AES_INTR_STATUS) & TEGRA_AES_INT_ERROR_MASK;
+
+ if (value) {
+ writel(TEGRA_AES_INT_ERROR_MASK, priv->regs + TEGRA_AES_INTR_STATUS);
+ log_debug("%s 0x%x\n", __func__, value);
+ }
+
+ return value;
+}
+
+static int tegra_aes_wait_for_idle_dma(struct tegra_aes_priv *priv, bool dma_wait)
+{
+ ulong start = get_timer(0);
+
+ while (tegra_aes_is_busy(priv, dma_wait)) {
+ if (get_timer(start) > TEGRA_AES_BUSY_TIMEOUT_MS) {
+ log_err("%s: TIMEOUT!!!\n", __func__);
+ break;
+ }
+ mdelay(5);
+ }
+
+ if (tegra_aes_check_error(priv))
+ return -1;
+
+ return 0;
+}
+
+static int tegra_aes_wait_for_idle(struct tegra_aes_priv *priv)
+{
+ return tegra_aes_wait_for_idle_dma(priv, 1);
+}
+
+static int tegra_aes_configure(struct tegra_aes_priv *priv)
+{
+ u32 value;
+
+ if (tegra_aes_wait_for_idle(priv))
+ return -1;
+
+ /* IRAM config */
+ writel(0, priv->regs + TEGRA_AES_IRAM_ACCESS_CFG);
+
+ /* Reset interrupts bits, or engine will hang on next operation */
+ writel(0xFFFFFFFF, priv->regs + TEGRA_AES_INTR_STATUS);
+
+ /* Set interrupts */
+ writel(0, priv->regs + TEGRA_AES_INT_ENB);
+
+ /* Configure CMDQUE */
+ value = readl(priv->regs + TEGRA_AES_CMDQUE_CONTROL);
+ value |= TEGRA_AES_CMDQ_CTRL_SRC_STM_SEL_FIELD |
+ TEGRA_AES_CMDQ_CTRL_DST_STM_SEL_FIELD |
+ TEGRA_AES_CMDQ_CTRL_ICMDQEN_FIELD;
+ writel(value, priv->regs + TEGRA_AES_CMDQUE_CONTROL);
+
+ value = readl(priv->regs + TEGRA_AES_SECURE_CONFIG_EXT);
+ value &= ~TEGRA_AES_SECURE_CTR_CNT_FIELD;
+ writel(value, priv->regs + TEGRA_AES_SECURE_CONFIG_EXT);
+
+ /* Configure BSE */
+ value = readl(priv->regs + TEGRA_AES_BSE_CFG);
+ value &= ~TEGRA_AES_BSE_MODE_FIELD;
+ value |= TEGRA_AES_BSE_LITTLE_ENDIAN_FIELD;
+ writel(value, priv->regs + TEGRA_AES_BSE_CFG);
+
+ return 0;
+}
+
+static int tegra_aes_select_key_slot(struct tegra_aes_priv *priv, u32 key_size, u8 slot)
+{
+ if (tegra_aes_wait_for_idle(priv))
+ return -1;
+
+ if (key_size < (AES128_KEY_LENGTH * 8) ||
+ key_size > (TEGRA_AES_HW_MAX_KEY_LENGTH * 8))
+ return -EINVAL;
+
+ priv->current_key_size = key_size;
+
+ /* Select the key slot */
+ u32 value = readl(priv->regs + TEGRA_AES_SECURE_CONFIG);
+
+ value &= ~TEGRA_AES_SECURE_KEY_INDEX_FIELD;
+ value |= (slot << TEGRA_AES_SECURE_KEY_INDEX_SHIFT);
+ writel(value, priv->regs + TEGRA_AES_SECURE_CONFIG);
+
+ return 0;
+}
+
+static int tegra_aes_call_engine(struct tegra_aes_priv *priv, u8 *src, u8 *dst,
+ u32 nblocks, u32 mode)
+{
+ u32 value;
+ const u32 ICMDQ_LENGTH = 4;
+ u32 cmdq[ICMDQ_LENGTH];
+
+ log_debug("%s: 0x%p -> 0x%p blocks %d mode 0x%x\n", __func__,
+ src, dst, nblocks, mode);
+
+ if (!nblocks) {
+ log_warning("%s: called with 0 blocks!\n", __func__);
+ return -1;
+ }
+
+ if (tegra_aes_configure(priv))
+ return -1;
+
+ /* Configure Secure Input */
+ value = 1 << TEGRA_AES_SECURE_INPUT_ALG_SEL_SHIFT |
+ priv->current_key_size << TEGRA_AES_SECURE_INPUT_KEY_LEN_SHIFT;
+
+ if (mode & TEGRA_AES_MODE_UPDATE_IV)
+ value |= TEGRA_AES_SECURE_INPUT_IV_FIELD;
+ if (mode & TEGRA_AES_MODE_HASH)
+ value |= TEGRA_AES_SECURE_INPUT_HASH_ENB_FIELD;
+ if (mode & TEGRA_AES_MODE_CBC) {
+ value |= ((mode & TEGRA_AES_MODE_ENCRYPT) ? 2 : 3) <<
+ TEGRA_AES_SECURE_XOR_POS_SHIFT;
+ value |= ((mode & TEGRA_AES_MODE_ENCRYPT) ? 2 : 3) <<
+ TEGRA_AES_SECURE_VCTRAM_SEL_SHIFT;
+ value |= ((mode & TEGRA_AES_MODE_ENCRYPT) ? 1 : 0) <<
+ TEGRA_AES_SECURE_CORE_SEL_SHIFT;
+ } else {
+ /* ECB */
+ value |= ((mode & TEGRA_AES_MODE_ENCRYPT) ? 1 : 0) <<
+ TEGRA_AES_SECURE_CORE_SEL_SHIFT;
+ }
+
+ writel(value, priv->regs + TEGRA_AES_SECURE_INPUT_SELECT);
+
+ /* Set destination address (doing in-place at IRAM) */
+ writel((u32)priv->iram_addr, priv->regs + TEGRA_AES_SECURE_DEST_ADDR);
+
+ /* Copy src data to IRAM */
+ if (src != priv->iram_addr)
+ memcpy(priv->iram_addr, src, nblocks * AES_BLOCK_LENGTH);
+
+ /* Run ICMD commands */
+ cmdq[0] = TEGRA_AES_CMD_DMASETUP << TEGRA_AES_CMDQ_OPCODE_SHIFT;
+ cmdq[1] = (u32)priv->iram_addr;
+ cmdq[2] = TEGRA_AES_CMD_BLKSTARTENGINE << TEGRA_AES_CMDQ_OPCODE_SHIFT | (nblocks - 1);
+ cmdq[3] = TEGRA_AES_CMD_DMACOMPLETE << TEGRA_AES_CMDQ_OPCODE_SHIFT;
+
+ for (int i = 0; i < ICMDQ_LENGTH; i++) {
+ tegra_aes_wait_for_idle_dma(priv, (ICMDQ_LENGTH - 1) == i);
+ writel(cmdq[i], priv->regs + TEGRA_AES_ICMDQUE_WR);
+ }
+
+ if (tegra_aes_wait_for_idle(priv))
+ return -1;
+
+ /* Put the result from IRAM to destination if not hashing */
+ if (dst != priv->iram_addr && !(mode & TEGRA_AES_MODE_HASH))
+ memcpy(dst, priv->iram_addr, nblocks * AES_BLOCK_LENGTH);
+
+ return 0;
+}
+
+static int tegra_aes_process_blocks(struct udevice *dev, u8 *iv, u8 *src,
+ u8 *dst, u32 num_aes_blocks, u32 mode)
+{
+ struct tegra_aes_priv *priv = dev_get_priv(dev);
+
+ log_debug("%s: 0x%p -> 0x%p blocks %d mode 0x%x\n",
+ __func__, src, dst, num_aes_blocks, mode);
+
+ if (!num_aes_blocks) {
+ log_warning("%s: called with 0 blocks!\n", __func__);
+ return -1;
+ }
+
+ /* Load initial IV if CBC mode */
+ if (mode & TEGRA_AES_MODE_CBC) {
+ if (tegra_aes_call_engine(priv, iv, priv->iram_addr, 1, TEGRA_AES_MODE_CBC))
+ return -1;
+
+ /* Add update IV flag */
+ mode |= TEGRA_AES_MODE_UPDATE_IV;
+ }
+
+ /* Process blocks by calling engine several times per dma buffer size */
+ while (num_aes_blocks > 0) {
+ u32 blocks = min(num_aes_blocks, (u32)TEGRA_AES_DMA_BUFFER_SIZE);
+
+ if (tegra_aes_call_engine(priv, src, dst, blocks, mode))
+ return -1;
+
+ num_aes_blocks -= blocks;
+ src += blocks * AES_BLOCK_LENGTH;
+ dst += blocks * AES_BLOCK_LENGTH;
+ }
+
+ return 0;
+}
+
+static int tegra_aes_ops_available_key_slots(struct udevice *dev)
+{
+ return 4; /* 4 slots in Tegra20 and Tegra30 */
+}
+
+static int tegra_aes_ops_select_key_slot(struct udevice *dev, u32 key_size, u8 slot)
+{
+ struct tegra_aes_priv *priv = dev_get_priv(dev);
+
+ if (slot == TEGRA_AES_SLOT_SBK && !priv->sbk_available) {
+ log_warning("%s: SBK not available!\n", __func__);
+ return -1;
+ }
+
+ return tegra_aes_select_key_slot(priv, key_size, slot);
+}
+
+static int tegra_aes_ops_set_key_for_key_slot(struct udevice *dev, u32 key_size,
+ u8 *key, u8 slot)
+{
+ struct tegra_aes_priv *priv = dev_get_priv(dev);
+ const u8 SUBCMD_CRYPTO_TABLE_SEL = 0x3;
+ const u8 SUBCMD_KEY_TABLE_SEL = 0x8;
+ const u8 CMDQ_KEYTABLEADDR_SHIFT = 0;
+ const u8 CMDQ_KEYTABLEID_SHIFT = 17;
+ const u8 CMDQ_TABLESEL_SHIFT = 24;
+ u32 value, addr;
+
+ log_debug("%s: slot %d\n", __func__, slot);
+
+ if (tegra_aes_configure(priv))
+ return -1;
+
+ if (key_size < (AES128_KEY_LENGTH * 8) ||
+ key_size > (TEGRA_AES_HW_MAX_KEY_LENGTH * 8))
+ return -EINVAL;
+
+ if (slot == TEGRA_AES_SLOT_SBK)
+ log_debug("%s: SBK slot being set!\n", __func__);
+
+ /* Clear and copy data to IRAM */
+ memset(priv->iram_addr, 0, TEGRA_AES_HW_TABLE_LENGTH);
+ memcpy(priv->iram_addr, key, key_size / 8);
+
+ /* Mask the addr */
+ addr = ((u32)priv->iram_addr) & TEGRA_AES_KEYTABLEADDR_FIELD;
+
+ /* Command for engine to load AES key from IRAM */
+ value = TEGRA_AES_CMD_SETTABLE << TEGRA_AES_CMDQ_OPCODE_SHIFT |
+ SUBCMD_CRYPTO_TABLE_SEL << CMDQ_TABLESEL_SHIFT |
+ (SUBCMD_KEY_TABLE_SEL | slot) << CMDQ_KEYTABLEID_SHIFT |
+ addr << CMDQ_KEYTABLEADDR_SHIFT;
+ writel(value, priv->regs + TEGRA_AES_ICMDQUE_WR);
+
+ return tegra_aes_wait_for_idle(priv);
+}
+
+static int tegra_aes_ops_aes_ecb_encrypt(struct udevice *dev, u8 *src, u8 *dst,
+ u32 num_aes_blocks)
+{
+ return tegra_aes_process_blocks(dev, NULL, src, dst, num_aes_blocks,
+ TEGRA_AES_MODE_ENCRYPT);
+}
+
+static int tegra_aes_ops_aes_ecb_decrypt(struct udevice *dev, u8 *src, u8 *dst,
+ u32 num_aes_blocks)
+{
+ return tegra_aes_process_blocks(dev, NULL, src, dst, num_aes_blocks, 0);
+}
+
+static int tegra_aes_ops_aes_cbc_encrypt(struct udevice *dev, u8 *iv, u8 *src,
+ u8 *dst, u32 num_aes_blocks)
+{
+ return tegra_aes_process_blocks(dev, iv, src, dst, num_aes_blocks,
+ TEGRA_AES_MODE_CBC | TEGRA_AES_MODE_ENCRYPT);
+}
+
+static int tegra_aes_ops_aes_cbc_decrypt(struct udevice *dev, u8 *iv, u8 *src,
+ u8 *dst, u32 num_aes_blocks)
+{
+ return tegra_aes_process_blocks(dev, iv, src, dst, num_aes_blocks,
+ TEGRA_AES_MODE_CBC);
+}
+
+static void tegra_aes_test_loaded_sbk(struct udevice *dev)
+{
+ struct tegra_aes_priv *priv = dev_get_priv(dev);
+ enum fuse_operating_mode opmode = tegra_fuse_get_operation_mode();
+ const u8 ZERO_KEY_CIPHERTEXT[AES_BLOCK_LENGTH] = {
+ 0x66, 0xe9, 0x4b, 0xd4, 0xef, 0x8a, 0x2c, 0x3b,
+ 0x88, 0x4c, 0xfa, 0x59, 0xca, 0x34, 0x2b, 0x2e
+ };
+
+ /* Encrypt a zero block, we use ECB so that we only care about SBK and not the IV */
+ memset(priv->iram_addr, 0, AES_BLOCK_LENGTH);
+ tegra_aes_select_key_slot(priv, 128, TEGRA_AES_SLOT_SBK);
+ tegra_aes_call_engine(priv, priv->iram_addr, priv->iram_addr, 1, TEGRA_AES_MODE_ENCRYPT);
+
+ /* Evaluate the result of engine operation */
+ if (!memcmp(priv->iram_addr, AES_ZERO_BLOCK, AES_BLOCK_LENGTH)) {
+ log_err("%s: engine is not operational! (opmode 0x%x)\n", __func__, opmode);
+ } else if (!memcmp(priv->iram_addr, ZERO_KEY_CIPHERTEXT, AES_BLOCK_LENGTH)) {
+ if (opmode == MODE_ODM_PRODUCTION_SECURE) {
+ log_warning("%s: SBK is zero or is cleared from engine! (opmode 0x%x)\n",
+ __func__, opmode);
+ } else {
+ log_debug("%s - SBK is zero and available! (opmode 0x%x)\n",
+ __func__, opmode);
+ priv->sbk_available = true;
+ }
+ } else {
+ if (opmode == MODE_ODM_PRODUCTION_SECURE) {
+ log_debug("%s: SBK is available! (opmode 0x%x)\n", __func__, opmode);
+ priv->sbk_available = true;
+ } else {
+ log_warning("%s: SBK is not zero and should be! (opmode 0x%x)\n",
+ __func__, opmode);
+ }
+ }
+}
+
+static int tegra_aes_hw_init(struct udevice *dev)
+{
+ struct tegra_aes_priv *priv = dev_get_priv(dev);
+ u32 value;
+ int ret;
+
+ if (priv->clk_parent) {
+ ret = reset_assert(&priv->reset_ctl_vde);
+ if (ret) {
+ log_debug("%s: VDE reset assert failed: %d\n", __func__, ret);
+ return ret;
+ }
+ }
+
+ ret = reset_assert(&priv->reset_ctl);
+ if (ret) {
+ log_debug("%s: BSE reset assert failed: %d\n", __func__, ret);
+ return ret;
+ }
+
+ if (priv->clk_parent) {
+ ret = clk_enable(priv->clk_parent);
+ if (ret) {
+ log_err("%s: VDE clock enable failed: %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = clk_set_rate(priv->clk_parent, 50 * 1000000);
+ if (IS_ERR_VALUE(ret)) {
+ log_err("%s: VDE clock set rate failed: %d\n", __func__, ret);
+ return ret;
+ }
+ }
+
+ ret = clk_enable(priv->clk);
+ if (ret) {
+ log_err("%s: BSE clock enable failed: %d\n", __func__, ret);
+ return ret;
+ }
+
+ if (priv->clk_parent) {
+ ret = reset_deassert(&priv->reset_ctl_vde);
+ if (ret) {
+ log_err("%s: VDE reset deassert failed: %d\n", __func__, ret);
+ return ret;
+ }
+ }
+
+ ret = reset_deassert(&priv->reset_ctl);
+ if (ret) {
+ log_err("%s: BSE reset deassert failed: %d\n", __func__, ret);
+ return ret;
+ }
+
+ /* Enable key schedule generation in hardware */
+ value = readl(priv->regs + TEGRA_AES_SECURE_CONFIG_EXT);
+ value &= ~TEGRA_AES_SECURE_KEY_SCH_DIS_FIELD;
+ writel(value, priv->regs + TEGRA_AES_SECURE_CONFIG_EXT);
+
+ /* Check if SBK is loaded in SBK slot or was erased */
+ priv->sbk_available = false;
+ tegra_aes_test_loaded_sbk(dev);
+
+ return 0;
+}
+
+static int tegra_aes_probe(struct udevice *dev)
+{
+ struct tegra_aes_priv *priv = dev_get_priv(dev);
+ fdt_size_t iram_size = 0;
+ u32 value;
+ int ret;
+
+ priv->current_key_size = AES128_KEY_LENGTH;
+
+ priv->regs = dev_read_addr_ptr(dev);
+ if (!priv->regs) {
+ log_err("%s: Cannot find aes reg address, binding failed\n", __func__);
+ return -EINVAL;
+ }
+
+ priv->iram_addr = devfdt_get_addr_size_name_ptr(dev, "iram-buffer", &iram_size);
+ if (!priv->iram_addr) {
+ log_debug("%s: Cannot find iram buffer address, binding failed\n", __func__);
+ return -EINVAL;
+ }
+
+ if (iram_size < TEGRA_AES_DMA_BUFFER_SIZE * AES_BLOCK_LENGTH) {
+ log_debug("%s: Unsupported iram buffer size: 0x%x required: 0x%x\n",
+ __func__, iram_size, TEGRA_AES_DMA_BUFFER_SIZE);
+ return -EINVAL;
+ }
+
+ /* Make sure the IRAM address is kept block aligned and accessible for slot loading */
+ value = (uint32_t)priv->iram_addr;
+ if ((value & 0xFFF0000F) != IRAM_BASE || value > TEGRA_AES_IRAM_MAX_ADDR) {
+ log_debug("%s: iram buffer must be located inside iram,", __func__);
+ log_debug("AES block aligned and not above 0x%08x, current addr %p\n",
+ (u32)TEGRA_AES_IRAM_MAX_ADDR, priv->iram_addr);
+ return -EINVAL;
+ }
+
+ ret = reset_get_by_name(dev, NULL, &priv->reset_ctl);
+ if (ret) {
+ log_debug("%s: failed to get BSE reset: %d\n", __func__, ret);
+ return ret;
+ }
+
+ priv->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ log_err("%s: failed to get BSE clock: %d\n", __func__, ret);
+ return ret;
+ }
+
+ /* VDE clock and reset required by BSEV */
+ ret = reset_get_by_name(dev, "vde", &priv->reset_ctl_vde);
+ if (ret)
+ log_debug("%s: failed to get VDE reset: %d\n", __func__, ret);
+
+ priv->clk_parent = devm_clk_get(dev, "vde");
+ if (IS_ERR(priv->clk_parent))
+ log_debug("%s: failed to get BSE clock: %d\n", __func__, ret);
+
+ return tegra_aes_hw_init(dev);
+}
+
+static const struct aes_ops tegra_aes_ops = {
+ .available_key_slots = tegra_aes_ops_available_key_slots,
+ .select_key_slot = tegra_aes_ops_select_key_slot,
+ .set_key_for_key_slot = tegra_aes_ops_set_key_for_key_slot,
+ .aes_ecb_encrypt = tegra_aes_ops_aes_ecb_encrypt,
+ .aes_ecb_decrypt = tegra_aes_ops_aes_ecb_decrypt,
+ .aes_cbc_encrypt = tegra_aes_ops_aes_cbc_encrypt,
+ .aes_cbc_decrypt = tegra_aes_ops_aes_cbc_decrypt,
+};
+
+static const struct udevice_id tegra_aes_ids[] = {
+ { .compatible = "nvidia,tegra20-bsea" },
+ { .compatible = "nvidia,tegra20-bsev" },
+ { .compatible = "nvidia,tegra30-bsea" },
+ { .compatible = "nvidia,tegra30-bsev" },
+ { }
+};
+
+U_BOOT_DRIVER(tegra_aes) = {
+ .name = "tegra_aes",
+ .id = UCLASS_AES,
+ .of_match = tegra_aes_ids,
+ .probe = tegra_aes_probe,
+ .ops = &tegra_aes_ops,
+ .priv_auto = sizeof(struct tegra_aes_priv),
+};
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index dfe4b3b8a02..b5777da5218 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -691,6 +691,23 @@ config VIDEO_LCD_HITACHI_TX18D42VM
lcd controller which needs to be initialized over SPI, once that is
done they work like a regular LVDS panel.
+config VIDEO_LCD_SONY_L4F00430T01
+ tristate "Sony L4F00430T01 480x800 LCD panel support"
+ depends on PANEL
+ help
+ Say Y here if you want to enable support for Sony L4F00430T01
+ LCD module found in Samsung Galaxy R. The panel has a
+ WVGA resolution (480x800) and is setup over SPI, video
+ data comes from RGB.
+
+config VIDEO_LCD_SAMSUNG_S6E63M0
+ tristate "Samsung S6E63M0 controller based panel support"
+ depends on PANEL && BACKLIGHT
+ help
+ Say Y here if you want to enable support for Samsung S6E63M0
+ controller found in some panels like on Samsung Captivate Glide.
+ Currently only DBI C panel is implemented.
+
config VIDEO_LCD_SPI_CS
string "SPI CS pin for LCD related config job"
depends on VIDEO_LCD_SSD2828 || VIDEO_LCD_HITACHI_TX18D42VM
@@ -821,6 +838,13 @@ config BACKLIGHT_LP855x
supported for now, PWM mode can be added if there will be any need in
it. Supported backlight level range is from 0 to 255 with step of 1.
+config BACKLIGHT_SAMSUNG_CMC623
+ bool "Backlight Driver for Samsung CMC623"
+ depends on VIDEO_BRIDGE_SAMSUNG_CMC623
+ help
+ Say Y to enable the backlight driver for Samsung CMC623 image converter
+ chip's PWM output to control backlight brightness.
+
source "drivers/video/ti/Kconfig"
source "drivers/video/exynos/Kconfig"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index ebe4a3961fc..96c7ce7bb09 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_backlight.o
obj-$(CONFIG_BACKLIGHT_LM3532) += lm3532_backlight.o
obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_backlight.o
obj-$(CONFIG_BACKLIGHT_LP855x) += lp855x_backlight.o
+obj-$(CONFIG_BACKLIGHT_SAMSUNG_CMC623) += cmc623_backlight.o
obj-${CONFIG_EXYNOS_FB} += exynos/
obj-${CONFIG_VIDEO_ROCKCHIP} += rockchip/
obj-${CONFIG_VIDEO_STM32} += stm32/
@@ -74,6 +75,8 @@ obj-$(CONFIG_VIDEO_LCD_SHARP_LQ079L1SX01) += sharp-lq079l1sx01.o
obj-$(CONFIG_VIDEO_LCD_SHARP_LQ101R1SX01) += sharp-lq101r1sx01.o
obj-$(CONFIG_VIDEO_LCD_SSD2828) += ssd2828.o
obj-$(CONFIG_VIDEO_LCD_TDO_TL070WSH30) += tdo-tl070wsh30.o
+obj-$(CONFIG_VIDEO_LCD_SONY_L4F00430T01) += sony-l4f00430t01.o
+obj-$(CONFIG_VIDEO_LCD_SAMSUNG_S6E63M0) += samsung-s6e63m0.o
obj-$(CONFIG_VIDEO_MCDE_SIMPLE) += mcde_simple.o
obj-${CONFIG_VIDEO_MESON} += meson/
obj-${CONFIG_VIDEO_MIPI_DSI} += mipi_dsi.o
diff --git a/drivers/video/bridge/Kconfig b/drivers/video/bridge/Kconfig
index be53034bd3d..a48cec7a138 100644
--- a/drivers/video/bridge/Kconfig
+++ b/drivers/video/bridge/Kconfig
@@ -66,3 +66,11 @@ config VIDEO_BRIDGE_LVDS_CODEC
help
Support for transparent LVDS encoders and decoders that don't
require any configuration.
+
+config VIDEO_BRIDGE_SAMSUNG_CMC623
+ bool "Samsung CMC623 Image Converter driver"
+ depends on VIDEO_BRIDGE && DM_GPIO
+ select DM_I2C
+ help
+ Samsung CMC623 image converter chip driver.
+ Found in several Samsung devices such as N1
diff --git a/drivers/video/bridge/Makefile b/drivers/video/bridge/Makefile
index 63dc6e62c49..520f36a7a6f 100644
--- a/drivers/video/bridge/Makefile
+++ b/drivers/video/bridge/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_VIDEO_BRIDGE_ANALOGIX_ANX6345) += anx6345.o
obj-$(CONFIG_VIDEO_BRIDGE_SOLOMON_SSD2825) += ssd2825.o
obj-$(CONFIG_VIDEO_BRIDGE_TOSHIBA_TC358768) += tc358768.o
obj-$(CONFIG_VIDEO_BRIDGE_LVDS_CODEC) += lvds-codec.o
+obj-$(CONFIG_VIDEO_BRIDGE_SAMSUNG_CMC623) += cmc623.o
diff --git a/drivers/video/bridge/cmc623.c b/drivers/video/bridge/cmc623.c
new file mode 100644
index 00000000000..78dafef8145
--- /dev/null
+++ b/drivers/video/bridge/cmc623.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2025 Ion Agorria <ion@agorria.com>
+ */
+
+#include <clk.h>
+#include <dm.h>
+#include <dm/ofnode_graph.h>
+#include <i2c.h>
+#include <log.h>
+#include <backlight.h>
+#include <panel.h>
+#include <video_bridge.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/math64.h>
+#include <power/regulator.h>
+#include <asm/gpio.h>
+
+static const char * const cmc623_supplies[] = {
+ "vdd3v0-supply", "vdd1v2-supply", "vddio1v8-supply"
+};
+
+struct cmc623_priv {
+ struct udevice *panel;
+ struct display_timing timing;
+
+ struct udevice *supplies[ARRAY_SIZE(cmc623_supplies)];
+
+ struct gpio_desc enable_gpio; /* also known as FAILSAFE */
+ struct gpio_desc bypass_gpio;
+};
+
+static int cmc623_attach(struct udevice *dev)
+{
+ struct cmc623_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ /* Perform panel setup */
+ ret = panel_enable_backlight(priv->panel);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int cmc623_set_backlight(struct udevice *dev, int percent)
+{
+ struct cmc623_priv *priv = dev_get_priv(dev);
+
+ return panel_set_backlight(priv->panel, percent);
+}
+
+static int cmc623_panel_timings(struct udevice *dev, struct display_timing *timing)
+{
+ struct cmc623_priv *priv = dev_get_priv(dev);
+
+ memcpy(timing, &priv->timing, sizeof(*timing));
+
+ return 0;
+}
+
+static int cmc623_hw_init(struct udevice *dev)
+{
+ struct cmc623_priv *priv = dev_get_priv(dev);
+ struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev);
+ int i, ret;
+
+ /* enable supplies */
+ for (i = 0; i < ARRAY_SIZE(cmc623_supplies); i++) {
+ ret = regulator_set_enable_if_allowed(priv->supplies[i], 1);
+ if (ret) {
+ log_debug("%s: cannot enable %s %d\n", __func__,
+ cmc623_supplies[i], ret);
+ return ret;
+ }
+ }
+
+ mdelay(10);
+
+ ret = dm_gpio_set_value(&uc_priv->reset, 1);
+ if (ret) {
+ log_debug("%s: error at reset = 1 (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ ret = dm_gpio_set_value(&priv->enable_gpio, 0);
+ if (ret) {
+ log_debug("%s: error at enable = 0 (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ ret = dm_gpio_set_value(&priv->bypass_gpio, 0);
+ if (ret) {
+ log_debug("%s: error at bypass = 0 (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ ret = dm_gpio_set_value(&uc_priv->sleep, 0);
+ if (ret) {
+ log_debug("%s: error at sleep = 0 (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ udelay(2000);
+
+ ret = dm_gpio_set_value(&priv->enable_gpio, 1);
+ if (ret) {
+ log_debug("%s: error at enable = 1 (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ udelay(2000);
+
+ ret = dm_gpio_set_value(&priv->bypass_gpio, 1);
+ if (ret) {
+ log_debug("%s: error at bypass = 1 (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ udelay(2000);
+
+ ret = dm_gpio_set_value(&uc_priv->sleep, 1);
+ if (ret) {
+ log_debug("%s: error at sleep = 1 (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ udelay(2000);
+
+ ret = dm_gpio_set_value(&uc_priv->reset, 0);
+ if (ret) {
+ log_debug("%s: error at sleep = 0 (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ mdelay(10);
+
+ ret = dm_gpio_set_value(&uc_priv->reset, 1);
+ if (ret) {
+ log_debug("%s: error at sleep = 1 (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ mdelay(10);
+
+ return 0;
+}
+
+static int cmc623_get_panel(struct udevice *dev)
+{
+ struct cmc623_priv *priv = dev_get_priv(dev);
+ int i, ret;
+
+ u32 num = ofnode_graph_get_port_count(dev_ofnode(dev));
+
+ for (i = 0; i < num; i++) {
+ ofnode remote = ofnode_graph_get_remote_node(dev_ofnode(dev), i, -1);
+
+ ret = uclass_get_device_by_ofnode(UCLASS_PANEL, remote, &priv->panel);
+ if (!ret)
+ return 0;
+ }
+
+ /* If this point is reached, no panels were found */
+ return -ENODEV;
+}
+
+static int cmc623_probe(struct udevice *dev)
+{
+ struct cmc623_priv *priv = dev_get_priv(dev);
+ int i, ret;
+
+ /* get supplies */
+ for (i = 0; i < ARRAY_SIZE(cmc623_supplies); i++) {
+ ret = device_get_supply_regulator(dev, cmc623_supplies[i], &priv->supplies[i]);
+ if (ret) {
+ log_debug("%s: cannot get %s %d\n", __func__, cmc623_supplies[i], ret);
+ if (ret != -ENOENT)
+ return log_ret(ret);
+ }
+ }
+
+ /* get control gpios */
+ ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable_gpio, GPIOD_IS_OUT);
+ if (ret) {
+ log_debug("%s: could not get enable-gpios (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ ret = gpio_request_by_name(dev, "bypass-gpios", 0, &priv->bypass_gpio, GPIOD_IS_OUT);
+ if (ret) {
+ log_debug("%s: could not get bypass-gpios (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ ret = cmc623_hw_init(dev);
+ if (ret) {
+ log_debug("%s: error doing hw init, ret %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = cmc623_get_panel(dev);
+ if (ret) {
+ log_debug("%s: panel not found, ret %d\n", __func__, ret);
+ return ret;
+ }
+
+ panel_get_display_timing(priv->panel, &priv->timing);
+
+ return 0;
+}
+
+static const struct video_bridge_ops cmc623_ops = {
+ .attach = cmc623_attach,
+ .set_backlight = cmc623_set_backlight,
+ .get_display_timing = cmc623_panel_timings,
+};
+
+static const struct udevice_id cmc623_ids[] = {
+ { .compatible = "samsung,cmc623" },
+ { }
+};
+
+U_BOOT_DRIVER(samsung_cmc623) = {
+ .name = "samsung_cmc623",
+ .id = UCLASS_VIDEO_BRIDGE,
+ .of_match = cmc623_ids,
+ .ops = &cmc623_ops,
+ .bind = dm_scan_fdt_dev,
+ .probe = cmc623_probe,
+ .priv_auto = sizeof(struct cmc623_priv),
+};
diff --git a/drivers/video/cmc623_backlight.c b/drivers/video/cmc623_backlight.c
new file mode 100644
index 00000000000..84b01724a07
--- /dev/null
+++ b/drivers/video/cmc623_backlight.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2025 Ion Agorria <ion@agorria.com>
+ */
+
+#define LOG_CATEGORY UCLASS_PANEL_BACKLIGHT
+
+#include <backlight.h>
+#include <dm.h>
+#include <i2c.h>
+#include <log.h>
+#include <linux/err.h>
+#include <asm/gpio.h>
+#include <power/regulator.h>
+
+#define CMC623_I2C_REG_SELBANK 0x00
+#define CMC623_I2C_REG_PWMCTRL 0xb4
+#define CMC623_I2C_REG_REGMASK 0x28
+
+#define CMC623_BL_MIN_BRIGHTNESS 0
+#define CMC623_BL_DEF_BRIGHTNESS 50
+#define CMC623_BL_MAX_BRIGHTNESS 100
+
+struct cmc623_backlight_priv {
+ struct gpio_desc enable_gpio;
+};
+
+static int cmc623_backlight_enable(struct udevice *dev)
+{
+ struct cmc623_backlight_priv *priv = dev_get_priv(dev);
+
+ if (dm_gpio_is_valid(&priv->enable_gpio))
+ dm_gpio_set_value(&priv->enable_gpio, 1);
+
+ return 0;
+}
+
+static int cmc623_i2c_write(struct udevice *dev, u8 reg, u16 value)
+{
+ u8 data[2];
+
+ data[0] = (value >> 8) & 0xff;
+ data[1] = value & 0xff;
+
+ return dm_i2c_write(dev->parent, reg, data, 2);
+}
+
+static int cmc623_backlight_set_brightness(struct udevice *dev, int percent)
+{
+ int ret;
+ u16 brightness;
+
+ if (percent == BACKLIGHT_DEFAULT)
+ percent = CMC623_BL_DEF_BRIGHTNESS;
+
+ if (percent < CMC623_BL_MIN_BRIGHTNESS)
+ percent = CMC623_BL_MIN_BRIGHTNESS;
+
+ if (percent > CMC623_BL_MAX_BRIGHTNESS)
+ percent = CMC623_BL_MAX_BRIGHTNESS;
+
+ brightness = 0x4000 | (percent << 4);
+
+ ret = cmc623_i2c_write(dev, CMC623_I2C_REG_SELBANK, 0x0000);
+ if (ret) {
+ log_debug("%s: error at CMC623_I2C_REG_SELBANK (%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = cmc623_i2c_write(dev, CMC623_I2C_REG_PWMCTRL, brightness);
+ if (ret) {
+ log_debug("%s: error at CMC623_I2C_REG_PWMCTRL (%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = cmc623_i2c_write(dev, CMC623_I2C_REG_REGMASK, 0x0000);
+ if (ret) {
+ log_debug("%s: error at CMC623_I2C_REG_REGMASK (%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int cmc623_backlight_of_to_plat(struct udevice *dev)
+{
+ struct cmc623_backlight_priv *priv = dev_get_priv(dev);
+
+ gpio_request_by_name(dev, "enable-gpios", 0,
+ &priv->enable_gpio, GPIOD_IS_OUT);
+
+ return 0;
+}
+
+static int cmc623_backlight_probe(struct udevice *dev)
+{
+ if (device_get_uclass_id(dev->parent) != UCLASS_VIDEO_BRIDGE)
+ return -EPROTONOSUPPORT;
+
+ return 0;
+}
+
+static const struct backlight_ops cmc623_backlight_ops = {
+ .enable = cmc623_backlight_enable,
+ .set_brightness = cmc623_backlight_set_brightness,
+};
+
+static const struct udevice_id cmc623_backlight_ids[] = {
+ { .compatible = "samsung,cmc623-backlight" },
+ { }
+};
+
+U_BOOT_DRIVER(cmc623_backlight) = {
+ .name = "cmc623_backlight",
+ .id = UCLASS_PANEL_BACKLIGHT,
+ .of_match = cmc623_backlight_ids,
+ .of_to_plat = cmc623_backlight_of_to_plat,
+ .probe = cmc623_backlight_probe,
+ .ops = &cmc623_backlight_ops,
+ .priv_auto = sizeof(struct cmc623_backlight_priv),
+};
diff --git a/drivers/video/samsung-s6e63m0.c b/drivers/video/samsung-s6e63m0.c
new file mode 100644
index 00000000000..7497fc0f53a
--- /dev/null
+++ b/drivers/video/samsung-s6e63m0.c
@@ -0,0 +1,393 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2025 Ion Agorria <ion@agorria.com>
+ */
+
+#include <backlight.h>
+#include <dm.h>
+#include <panel.h>
+#include <log.h>
+#include <malloc.h>
+#include <spi.h>
+#include <mipi_display.h>
+#include <linux/delay.h>
+#include <power/regulator.h>
+#include <asm/gpio.h>
+
+#define S6E63M0_DCS_CMD 0
+#define S6E63M0_DCS_DATA 1
+
+#define S6E63M0_INFO_FLAG_PGAMMACTL BIT(0)
+#define S6E63M0_INFO_FLAG_GAMMA_DELTA BIT(1)
+
+#define S6E63M0_GTCON_FLAG_FLIP_H BIT(0)
+#define S6E63M0_GTCON_FLAG_FLIP_V BIT(1)
+
+/* Manufacturer Command Set */
+#define MCS_PENTILE_1 0xb3
+#define MCS_GAMMA_DELTA_Y_RED 0xb5
+#define MCS_GAMMA_DELTA_X_RED 0xb6
+#define MCS_GAMMA_DELTA_Y_GREEN 0xb7
+#define MCS_GAMMA_DELTA_X_GREEN 0xb8
+#define MCS_GAMMA_DELTA_Y_BLUE 0xb9
+#define MCS_GAMMA_DELTA_X_BLUE 0xba
+#define MCS_DISCTL 0xf2
+#define MCS_SRCCTL 0xf6
+#define MCS_IFCTL 0xf7
+#define MCS_PANELCTL 0xf8
+#define MCS_PGAMMACTL 0xfa
+
+#define MCS_PANELCTL_LEN 14
+#define MCS_IFCTL_LEN 3
+#define MCS_PGAMMACTL_LEN 22
+#define MCS_GAMMA_DELTA_Y_LEN 32
+#define MCS_GAMMA_DELTA_X_LEN 16
+
+struct s6e63m0_priv {
+ struct udevice *vdd3;
+ struct udevice *vci;
+
+ struct s6e63m0_info *info;
+
+ struct gpio_desc reset_gpio;
+
+ u8 gtcon;
+};
+
+struct s6e63m0_info {
+ const u32 flags;
+ struct display_timing timing;
+ const u8 cmd_mcs_panelctl[MCS_PANELCTL_LEN];
+ const u8 cmd_mcs_pgammactl_1[MCS_PGAMMACTL_LEN];
+ const u8 cmd_mcs_pgammactl_2;
+ const u8 cmd_mcs_gamma_delta_y[MCS_GAMMA_DELTA_Y_LEN];
+ const u8 cmd_mcs_gamma_delta_x[MCS_GAMMA_DELTA_X_LEN];
+};
+
+static const struct s6e63m0_info s6e63m0_generic_info = {
+ .flags = S6E63M0_INFO_FLAG_GAMMA_DELTA,
+ .timing = {
+ .pixelclock.typ = 25628,
+ .hactive.typ = 480,
+ .hfront_porch.typ = 16,
+ .hback_porch.typ = 16,
+ .hsync_len.typ = 2,
+ .vactive.typ = 800,
+ .vfront_porch.typ = 28,
+ .vback_porch.typ = 1,
+ .vsync_len.typ = 2,
+ .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW,
+ },
+ .cmd_mcs_panelctl = {
+ 0x01, /* DOCT */ 0x27, /* CLWEA */
+ 0x27, /* CLWEB*/ 0x07, /* CLTE */
+ 0x07, /* SHE */ 0x54, /* FLTE */
+ 0x9F, /* FLWE */ 0x63, /* SCTE */
+ 0x8F, /* SCWE */ 0x1A, /* INTE */
+ 0x33, /* INWE */ 0x0D, /* EMPS */
+ 0x00, /* E_INTE */ 0x00 /* E_INWE */
+ },
+ .cmd_mcs_pgammactl_1 = {
+ 0x00, 0x18, 0x08, 0x24, 0x64, 0x56, 0x33, 0xb6,
+ 0xba, 0xa8, 0xac, 0xb1, 0x9d, 0xc1, 0xc1, 0xb7,
+ 0x00, 0x9c, 0x00, 0x9f, 0x00, 0xd6
+ },
+ .cmd_mcs_pgammactl_2 = 0x01,
+ .cmd_mcs_gamma_delta_y = {
+ 0x2c, 0x12, 0x0c, 0x0a, 0x10, 0x0e, 0x17, 0x13,
+ 0x1f, 0x1a, 0x2a, 0x24, 0x1f, 0x1b, 0x1a, 0x17,
+ 0x2b, 0x26, 0x22, 0x20, 0x3a, 0x34, 0x30, 0x2c,
+ 0x29, 0x26, 0x25, 0x23, 0x21, 0x20, 0x1e, 0x1e
+ },
+ .cmd_mcs_gamma_delta_x = {
+ 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x44, 0x44,
+ 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
+ },
+};
+
+static const struct s6e63m0_info samsung_bose_panel_info = {
+ .flags = S6E63M0_INFO_FLAG_PGAMMACTL | S6E63M0_INFO_FLAG_GAMMA_DELTA,
+ .timing = {
+ .pixelclock.typ = 24000000,
+ .hactive.typ = 480,
+ .hfront_porch.typ = 16,
+ .hback_porch.typ = 14,
+ .hsync_len.typ = 2,
+ .vactive.typ = 800,
+ .vfront_porch.typ = 28,
+ .vback_porch.typ = 1,
+ .vsync_len.typ = 2,
+ .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
+ DISPLAY_FLAGS_DE_LOW | DISPLAY_FLAGS_PIXDATA_NEGEDGE,
+ },
+ .cmd_mcs_panelctl = {
+ 0x01, /* DOCT */ 0x27, /* CLWEA */
+ 0x27, /* CLWEB*/ 0x07, /* CLTE */
+ 0x07, /* SHE */ 0x54, /* FLTE */
+ 0x9F, /* FLWE */ 0x63, /* SCTE */
+ 0x86, /* SCWE */ 0x1A, /* INTE */
+ 0x33, /* INWE */ 0x0D, /* EMPS */
+ 0x00, /* E_INTE */ 0x00 /* E_INWE */
+ },
+ .cmd_mcs_pgammactl_1 = {
+ 0x02, 0x18, 0x08, 0x24, 0x70, 0x6e, 0x4e, 0xbc,
+ 0xc0, 0xaf, 0xb3, 0xb8, 0xa5, 0xc5, 0xc7, 0xbb,
+ 0x00, 0xb9, 0x00, 0xb8, 0x00, 0xfc
+ },
+ .cmd_mcs_pgammactl_2 = 0x03,
+ .cmd_mcs_gamma_delta_y = {
+ 0x2c, 0x12, 0x0c, 0x0a, 0x10, 0x0e, 0x17, 0x13,
+ 0x1f, 0x1a, 0x2a, 0x24, 0x1f, 0x1b, 0x1a, 0x17,
+ 0x2b, 0x26, 0x22, 0x20, 0x3a, 0x34, 0x30, 0x2c,
+ 0x29, 0x26, 0x25, 0x23, 0x21, 0x20, 0x1e, 0x1e
+ },
+ .cmd_mcs_gamma_delta_x = {
+ 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x44, 0x44,
+ 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66
+ },
+};
+
+static int s6e63m0_dcs_write(struct udevice *dev, u8 cmd, const u8 *seq, size_t len)
+{
+ int ret;
+ u8 data[2];
+ int i;
+
+ data[0] = S6E63M0_DCS_CMD;
+ data[1] = cmd;
+
+ ret = dm_spi_xfer(dev, 9, &data, NULL, SPI_XFER_ONCE);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < len; i++) {
+ data[0] = S6E63M0_DCS_DATA;
+ data[1] = seq[i];
+
+ ret = dm_spi_xfer(dev, 9, &data, NULL, SPI_XFER_ONCE);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+#define s6e63m0_dcs_write_seq_static(dev, cmd, seq ...) ({ \
+ static const u8 d[] = { seq }; \
+ ret = s6e63m0_dcs_write(dev, cmd, d, ARRAY_SIZE(d)); \
+ if (ret) \
+ return ret; \
+})
+
+static int s6e63m0_enable_backlight(struct udevice *dev)
+{
+ struct s6e63m0_priv *priv = dev_get_priv(dev);
+ struct s6e63m0_info *info = priv->info;
+ u8 cmd_mcs_ifctl[MCS_IFCTL_LEN];
+ int ret;
+
+ ret = s6e63m0_dcs_write(dev, MCS_PANELCTL, info->cmd_mcs_panelctl, MCS_PANELCTL_LEN);
+ if (ret)
+ return ret;
+
+ s6e63m0_dcs_write_seq_static(dev, MCS_DISCTL,
+ 0x02, /* Number of Line */
+ 0x03, /* VBP */
+ 0x1c, /* VFP */
+ 0x10, /* HBP */
+ 0x10); /* HFP */
+
+ cmd_mcs_ifctl[0] = priv->gtcon; /* GTCON */
+ cmd_mcs_ifctl[1] = 0x00; /* Display Mode */
+ cmd_mcs_ifctl[2] = 0x00; /* Vsync/Hsync, DOCCLK, RGB mode */
+ ret = s6e63m0_dcs_write(dev, MCS_IFCTL, cmd_mcs_ifctl, MCS_IFCTL_LEN);
+ if (ret)
+ return ret;
+
+ if (info->flags & S6E63M0_INFO_FLAG_PGAMMACTL) {
+ ret = s6e63m0_dcs_write(dev, MCS_PGAMMACTL, info->cmd_mcs_pgammactl_1,
+ MCS_PGAMMACTL_LEN);
+ if (ret)
+ return ret;
+
+ s6e63m0_dcs_write(dev, MCS_PGAMMACTL, &info->cmd_mcs_pgammactl_2, 1);
+ }
+
+ s6e63m0_dcs_write_seq_static(dev, MCS_SRCCTL, 0x00, 0x8e, 0x07);
+ s6e63m0_dcs_write_seq_static(dev, MCS_PENTILE_1, 0x6c);
+
+ if (info->flags & S6E63M0_INFO_FLAG_GAMMA_DELTA) {
+ ret = s6e63m0_dcs_write(dev, MCS_GAMMA_DELTA_Y_RED, info->cmd_mcs_gamma_delta_y,
+ MCS_GAMMA_DELTA_Y_LEN);
+ if (ret)
+ return ret;
+
+ ret = s6e63m0_dcs_write(dev, MCS_GAMMA_DELTA_X_RED, info->cmd_mcs_gamma_delta_x,
+ MCS_GAMMA_DELTA_X_LEN);
+ if (ret)
+ return ret;
+
+ ret = s6e63m0_dcs_write(dev, MCS_GAMMA_DELTA_Y_GREEN, info->cmd_mcs_gamma_delta_y,
+ MCS_GAMMA_DELTA_Y_LEN);
+ if (ret)
+ return ret;
+
+ ret = s6e63m0_dcs_write(dev, MCS_GAMMA_DELTA_X_GREEN, info->cmd_mcs_gamma_delta_x,
+ MCS_GAMMA_DELTA_X_LEN);
+ if (ret)
+ return ret;
+
+ ret = s6e63m0_dcs_write(dev, MCS_GAMMA_DELTA_Y_BLUE, info->cmd_mcs_gamma_delta_y,
+ MCS_GAMMA_DELTA_Y_LEN);
+ if (ret)
+ return ret;
+
+ ret = s6e63m0_dcs_write(dev, MCS_GAMMA_DELTA_X_BLUE, info->cmd_mcs_gamma_delta_x,
+ MCS_GAMMA_DELTA_X_LEN);
+ if (ret)
+ return ret;
+ }
+
+ s6e63m0_dcs_write_seq_static(dev, MIPI_DCS_EXIT_SLEEP_MODE);
+ s6e63m0_dcs_write_seq_static(dev, MIPI_DCS_SET_DISPLAY_ON);
+
+ return 0;
+}
+
+static int s6e63m0_set_backlight(struct udevice *dev, int percent)
+{
+ return 0;
+}
+
+static int s6e63m0_get_display_timing(struct udevice *dev, struct display_timing *timing)
+{
+ struct s6e63m0_priv *priv = dev_get_priv(dev);
+
+ memcpy(timing, &priv->info->timing, sizeof(*timing));
+
+ return 0;
+}
+
+static int s6e63m0_of_to_plat(struct udevice *dev)
+{
+ struct s6e63m0_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = device_get_supply_regulator(dev, "vdd3-supply", &priv->vdd3);
+ if (ret) {
+ log_debug("%s: cannot get vdd3-supply: ret = %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = device_get_supply_regulator(dev, "vci-supply", &priv->vci);
+ if (ret) {
+ log_debug("%s: cannot get vci-supply: ret = %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = gpio_request_by_name(dev, "reset-gpios", 0,
+ &priv->reset_gpio, GPIOD_IS_OUT);
+ if (ret) {
+ log_debug("%s: cannot decode reset-gpios (%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ if (dev_read_bool(dev, "flip-horizontal"))
+ priv->gtcon |= S6E63M0_GTCON_FLAG_FLIP_H;
+
+ if (dev_read_bool(dev, "flip-vertical"))
+ priv->gtcon |= S6E63M0_GTCON_FLAG_FLIP_V;
+
+ return 0;
+}
+
+static int s6e63m0_hw_init(struct udevice *dev)
+{
+ struct s6e63m0_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = dm_gpio_set_value(&priv->reset_gpio, 1);
+ if (ret) {
+ log_debug("%s: error entering reset (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ ret = regulator_set_enable_if_allowed(priv->vdd3, 1);
+ if (ret) {
+ log_debug("%s: enabling vdd3-supply failed (%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ mdelay(1);
+
+ ret = regulator_set_enable_if_allowed(priv->vci, 1);
+ if (ret) {
+ log_debug("%s: enabling vci-supply failed (%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ mdelay(26);
+
+ ret = dm_gpio_set_value(&priv->reset_gpio, 0);
+ if (ret) {
+ log_debug("%s: error exiting reset (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ mdelay(10);
+
+ return 0;
+}
+
+static int s6e63m0_probe(struct udevice *dev)
+{
+ struct s6e63m0_priv *priv = dev_get_priv(dev);
+ struct spi_slave *slave = dev_get_parent_priv(dev);
+ int ret;
+
+ if (device_get_uclass_id(dev->parent) != UCLASS_SPI)
+ return -EPROTONOSUPPORT;
+
+ ret = spi_claim_bus(slave);
+ if (ret) {
+ log_err("SPI bus allocation failed (%d)\n", ret);
+ return ret;
+ }
+
+ priv->info = (struct s6e63m0_info *)dev_get_driver_data(dev);
+
+ return s6e63m0_hw_init(dev);
+}
+
+static const struct panel_ops s6e63m0_ops = {
+ .enable_backlight = s6e63m0_enable_backlight,
+ .set_backlight = s6e63m0_set_backlight,
+ .get_display_timing = s6e63m0_get_display_timing,
+};
+
+static const struct udevice_id s6e63m0_ids[] = {
+ {
+ .compatible = "samsung,s6e63m0",
+ .data = (ulong)&s6e63m0_generic_info
+ },
+ {
+ .compatible = "samsung,bose-panel",
+ .data = (ulong)&samsung_bose_panel_info
+ },
+ { }
+};
+
+U_BOOT_DRIVER(samsung_s6e63m0) = {
+ .name = "samsung_s6e63m0",
+ .id = UCLASS_PANEL,
+ .of_match = s6e63m0_ids,
+ .ops = &s6e63m0_ops,
+ .of_to_plat = s6e63m0_of_to_plat,
+ .probe = s6e63m0_probe,
+ .priv_auto = sizeof(struct s6e63m0_priv),
+};
diff --git a/drivers/video/sony-l4f00430t01.c b/drivers/video/sony-l4f00430t01.c
new file mode 100644
index 00000000000..2303eb86143
--- /dev/null
+++ b/drivers/video/sony-l4f00430t01.c
@@ -0,0 +1,210 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2025 Ion Agorria <ion@agorria.com>
+ */
+
+#include <backlight.h>
+#include <dm.h>
+#include <panel.h>
+#include <log.h>
+#include <spi.h>
+#include <mipi_display.h>
+#include <linux/delay.h>
+#include <power/regulator.h>
+#include <asm/gpio.h>
+
+#define SONY_L4F00430T01_DCS_CMD 0
+#define SONY_L4F00430T01_DCS_DATA 1
+
+struct sony_l4f00430t01_priv {
+ struct udevice *vdd1v8;
+ struct udevice *vdd3v0;
+
+ struct udevice *backlight;
+
+ struct gpio_desc reset_gpio;
+};
+
+static struct display_timing default_timing = {
+ .pixelclock.typ = 24000000,
+ .hactive.typ = 480,
+ .hfront_porch.typ = 10,
+ .hback_porch.typ = 20,
+ .hsync_len.typ = 10,
+ .vactive.typ = 800,
+ .vfront_porch.typ = 3,
+ .vback_porch.typ = 4,
+ .vsync_len.typ = 2,
+ .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
+ DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_NEGEDGE,
+};
+
+static int sony_l4f00430t01_write(struct udevice *dev, u8 cmd, const u8 *seq, int len)
+{
+ u8 data[2];
+ int i, ret;
+
+ data[0] = SONY_L4F00430T01_DCS_CMD;
+ data[1] = cmd;
+
+ ret = dm_spi_xfer(dev, 9, &data, NULL, SPI_XFER_ONCE);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < len; i++) {
+ data[0] = SONY_L4F00430T01_DCS_DATA;
+ data[1] = seq[i];
+
+ ret = dm_spi_xfer(dev, 9, &data, NULL, SPI_XFER_ONCE);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+#define sony_l4f00430t01_write_seq(dev, cmd, seq...) do { \
+ static const u8 b[] = { seq }; \
+ sony_l4f00430t01_write(dev, cmd, b, ARRAY_SIZE(b)); \
+ } while (0)
+
+static int sony_l4f00430t01_enable_backlight(struct udevice *dev)
+{
+ sony_l4f00430t01_write_seq(dev, MIPI_DCS_SET_ADDRESS_MODE, 0xd4);
+ mdelay(25);
+
+ sony_l4f00430t01_write_seq(dev, MIPI_DCS_EXIT_SLEEP_MODE);
+ mdelay(150);
+
+ sony_l4f00430t01_write_seq(dev, MIPI_DCS_SET_DISPLAY_ON);
+
+ return 0;
+}
+
+static int sony_l4f00430t01_set_backlight(struct udevice *dev, int percent)
+{
+ struct sony_l4f00430t01_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
+ "backlight", &priv->backlight);
+ if (ret) {
+ log_debug("%s: cannot get backlight: ret = %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = backlight_enable(priv->backlight);
+ if (ret)
+ return ret;
+
+ return backlight_set_brightness(priv->backlight, percent);
+}
+
+static int sony_l4f00430t01_get_display_timing(struct udevice *dev,
+ struct display_timing *timing)
+{
+ memcpy(timing, &default_timing, sizeof(*timing));
+ return 0;
+}
+
+static int sony_l4f00430t01_of_to_plat(struct udevice *dev)
+{
+ struct sony_l4f00430t01_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = device_get_supply_regulator(dev, "vdd1v8-supply", &priv->vdd1v8);
+ if (ret) {
+ log_debug("%s: cannot get vdd1v8-supply: ret = %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = device_get_supply_regulator(dev, "vdd3v0-supply", &priv->vdd3v0);
+ if (ret) {
+ log_debug("%s: cannot get vdd3v0-supply: ret = %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = gpio_request_by_name(dev, "reset-gpios", 0,
+ &priv->reset_gpio, GPIOD_IS_OUT);
+ if (ret) {
+ log_debug("%s: cannot decode reset-gpios (%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int sony_l4f00430t01_hw_init(struct udevice *dev)
+{
+ struct sony_l4f00430t01_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ ret = dm_gpio_set_value(&priv->reset_gpio, 1);
+ if (ret) {
+ log_debug("%s: error entering reset (%d)\n", __func__, ret);
+ return ret;
+ }
+
+ ret = regulator_set_enable_if_allowed(priv->vdd1v8, 1);
+ if (ret) {
+ log_debug("%s: enabling vdd1v8-supply failed (%d)\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = regulator_set_enable_if_allowed(priv->vdd3v0, 1);
+ if (ret) {
+ log_debug("%s: enabling vdd3v0-supply failed (%d)\n",
+ __func__, ret);
+ return ret;
+ }
+ mdelay(15);
+
+ ret = dm_gpio_set_value(&priv->reset_gpio, 0);
+ if (ret) {
+ log_debug("%s: error exiting reset (%d)\n", __func__, ret);
+ return ret;
+ }
+ mdelay(100);
+
+ return 0;
+}
+
+static int sony_l4f00430t01_probe(struct udevice *dev)
+{
+ struct spi_slave *slave = dev_get_parent_priv(dev);
+ int ret;
+
+ ret = spi_claim_bus(slave);
+ if (ret) {
+ log_err("SPI bus allocation failed (%d)\n", ret);
+ return ret;
+ }
+
+ return sony_l4f00430t01_hw_init(dev);
+}
+
+static const struct panel_ops sony_l4f00430t01_ops = {
+ .enable_backlight = sony_l4f00430t01_enable_backlight,
+ .set_backlight = sony_l4f00430t01_set_backlight,
+ .get_display_timing = sony_l4f00430t01_get_display_timing,
+};
+
+static const struct udevice_id sony_l4f00430t01_ids[] = {
+ { .compatible = "sony,l4f00430t01" },
+ { }
+};
+
+U_BOOT_DRIVER(sony_l4f00430t01) = {
+ .name = "sony_l4f00430t01",
+ .id = UCLASS_PANEL,
+ .of_match = sony_l4f00430t01_ids,
+ .ops = &sony_l4f00430t01_ops,
+ .of_to_plat = sony_l4f00430t01_of_to_plat,
+ .probe = sony_l4f00430t01_probe,
+ .priv_auto = sizeof(struct sony_l4f00430t01_priv),
+};
diff --git a/drivers/video/tegra/dc.c b/drivers/video/tegra/dc.c
index f0e3d2c993f..ced49718834 100644
--- a/drivers/video/tegra/dc.c
+++ b/drivers/video/tegra/dc.c
@@ -238,8 +238,24 @@ static void rgb_enable(struct tegra_lcd_priv *priv)
else
value &= ~LVS_OUTPUT_POLARITY_LOW;
+ /* configure pixel data signal polarity */
+ if (dt->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
+ value &= ~LSC0_OUTPUT_POLARITY_LOW;
+ else
+ value |= LSC0_OUTPUT_POLARITY_LOW;
+
writel(value, &com->pin_output_polarity[1]);
+ /* configure data enable signal polarity */
+ value = readl(&com->pin_output_polarity[3]);
+
+ if (dt->flags & DISPLAY_FLAGS_DE_LOW)
+ value |= LSPI_OUTPUT_POLARITY_LOW;
+ else
+ value &= ~LSPI_OUTPUT_POLARITY_LOW;
+
+ writel(value, &com->pin_output_polarity[3]);
+
for (i = 0; i < PIN_OUTPUT_SEL_COUNT; i++)
writel(rgb_sel_tab[i], &com->pin_output_sel[i]);
}
diff --git a/scripts/Makefile.xpl b/scripts/Makefile.xpl
index 03a2f151d91..3e940bf562d 100644
--- a/scripts/Makefile.xpl
+++ b/scripts/Makefile.xpl
@@ -390,7 +390,6 @@ $(obj)/$(BOARD)-spl.bin: $(obj)/u-boot-spl.bin
endif
$(obj)/u-boot-spl.ldr: $(obj)/u-boot-spl
- $(CREATE_LDR_ENV)
$(LDR) -T $(CONFIG_LDR_CPU) -c $@ $< $(LDR_FLAGS)
$(BOARD_SIZE_CHECK)
diff --git a/test/py/tests/test_fit_mkimage_validate.py b/test/py/tests/test_fit_mkimage_validate.py
index ef974c8c762..170b2a8cbbb 100644
--- a/test/py/tests/test_fit_mkimage_validate.py
+++ b/test/py/tests/test_fit_mkimage_validate.py
@@ -57,6 +57,8 @@ def test_fit_invalid_image_reference(ubman):
assert result.returncode != 0, "mkimage should fail due to missing image reference"
assert "references undefined image 'notexist'" in result.stderr
+@pytest.mark.boardspec('sandbox')
+@pytest.mark.requiredtool('dtc')
def test_fit_invalid_default_config(ubman):
"""Test that mkimage fails when default config is missing"""