This commit is contained in:
Tom Rini 2025-05-08 09:22:25 -06:00
commit ffd5d9cc27
77 changed files with 2468 additions and 196 deletions

View File

@ -86,6 +86,7 @@ dtb-$(CONFIG_ARCH_TEGRA) += \
tegra20-asus-tf101.dtb \
tegra20-asus-tf101g.dtb \
tegra20-harmony.dtb \
tegra20-lg-star.dtb \
tegra20-medcom-wide.dtb \
tegra20-motorola-daytona.dtb \
tegra20-motorola-olympus.dtb \

View File

@ -0,0 +1,538 @@
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
#include <dt-bindings/input/input.h>
#include "tegra20.dtsi"
/ {
model = "LG Optimus 2X (P990)";
compatible = "lg,star", "nvidia,tegra20";
chosen {
stdout-path = &uartb;
};
aliases {
i2c0 = &pwr_i2c;
i2c5 = &dcdc_i2c;
mmc0 = &sdmmc4; /* eMMC */
mmc1 = &sdmmc3; /* uSD slot */
rtc0 = &pmic;
rtc1 = "/rtc@7000e000";
usb0 = &micro_usb;
};
memory {
device_type = "memory";
reg = <0x00000000 0x20000000>; /* 512 MB */
};
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 {
crt {
nvidia,pins = "crtp";
nvidia,function = "crt";
};
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";
};
displaya {
nvidia,pins = "lcsn", "ld0", "ld1", "ld10",
"ld11", "ld12", "ld13", "ld14",
"ld15", "ld16", "ld17", "ld2",
"ld3", "ld4", "ld5", "ld6",
"ld7", "ld8", "ld9", "ldc",
"ldi", "lhp0", "lhp1", "lhp2",
"lhs", "lm0", "lm1", "lpp",
"lpw0", "lpw1", "lpw2", "lsc0",
"lsc1", "lsck", "lsda", "lsdi",
"lspi", "lvp0", "lvp1", "lvs";
nvidia,function = "displaya";
};
gmi {
nvidia,pins = "ata", "atc", "atd", "ate",
"gmb", "irrx", "irtx";
nvidia,function = "gmi";
};
hdmi {
nvidia,pins = "hdint";
nvidia,function = "hdmi";
};
i2c {
nvidia,pins = "i2cp", "rm";
nvidia,function = "i2c";
};
i2c2 {
nvidia,pins = "pta";
nvidia,function = "i2c2";
};
i2c3 {
nvidia,pins = "dtf";
nvidia,function = "i2c3";
};
kbc {
nvidia,pins = "kbca", "kbcb", "kbcc", "kbce",
"kbcf";
nvidia,function = "kbc";
};
owr {
nvidia,pins = "owc";
nvidia,function = "owr";
};
plla-out {
nvidia,pins = "cdev1";
nvidia,function = "plla_out";
};
pllp-out4 {
nvidia,pins = "cdev2";
nvidia,function = "pllp_out4";
};
pwm {
nvidia,pins = "gpu";
nvidia,function = "pwm";
};
pwr-on {
nvidia,pins = "pmc";
nvidia,function = "pwr_on";
};
rtck {
nvidia,pins = "gpu7";
nvidia,function = "rtck";
};
sdio1 {
nvidia,pins = "sdio1";
nvidia,function = "sdio1";
};
sdio2 {
nvidia,pins = "kbcd";
nvidia,function = "sdio2";
};
sdio3 {
nvidia,pins = "sdb", "sdc", "sdd", "slxa",
"slxd", "slxk", "slxc";
nvidia,function = "sdio3";
};
sdio4 {
nvidia,pins = "atb", "gma", "gme";
nvidia,function = "sdio4";
};
spi1 {
nvidia,pins = "uda";
nvidia,function = "spi1";
};
spi2 {
nvidia,pins = "spia", "spib", "spic";
nvidia,function = "spi2";
};
spi2-alt {
nvidia,pins = "spid", "spie", "spig", "spih";
nvidia,function = "spi2_alt";
};
uarta {
nvidia,pins = "uaa", "uab";
nvidia,function = "uarta";
};
uartc {
nvidia,pins = "uca", "ucb";
nvidia,function = "uartc";
};
uartd {
nvidia,pins = "gmc";
nvidia,function = "uartd";
};
vi {
nvidia,pins = "dtc", "dtd";
nvidia,function = "vi";
};
vi-sensor-clk {
nvidia,pins = "csus";
nvidia,function = "vi_sensor_clk";
};
conf-lsda {
nvidia,pins = "lsda", "owc";
nvidia,pull = <TEGRA_PIN_PULL_UP>;
nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf-ata {
nvidia,pins = "ata", "dtf", "gmb", "gmc",
"i2cp", "irrx", "kbca", "kbcc",
"kbcd", "kbce", "kbcf", "lcsn",
"ldc", "pta", "rm", "sdc",
"sdd", "spie", "spif", "spig",
"spih", "uaa", "uad", "uca",
"ucb", "pmce";
nvidia,pull = <TEGRA_PIN_PULL_UP>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf-crtp {
nvidia,pins = "crtp", "gpv", "hdint", "lhs",
"lm0", "lpw0", "lpw1", "lpw2",
"lsc1", "lsck", "lspi", "lvs",
"slxa", "slxd", "spdi";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf-atb {
nvidia,pins = "atb", "atc", "atd", "ate",
"cdev1", "cdev2", "csus", "dap1",
"dap2", "dap3", "dap4", "ddc",
"dta", "dtb", "dte", "gma",
"gmd", "gme", "gpu", "gpu7",
"irtx", "kbcb", "lm1", "lsc0",
"lsdi", "lvp0", "pmc", "sdb",
"sdio1", "slxc", "spdo", "spia",
"spib", "spic", "uab", "uac",
"uda", "ck32", "ddrc", "pmca",
"pmcb", "pmcc", "pmcd", "xm2c",
"xm2d";
nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
conf-dtc {
nvidia,pins = "dtc", "dtd";
nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
nvidia,tristate = <TEGRA_PIN_ENABLE>;
};
conf-ld0 {
nvidia,pins = "ld0", "ld1", "ld2", "ld3",
"ld4", "ld5", "ld6", "ld7",
"ld8", "ld9", "ld10", "ld11",
"ld12", "ld13", "ld14", "ld15",
"ld16", "ld17", "ldi", "lhp0",
"lhp1", "lhp2", "lpp", "lvp1",
"slxk", "spid";
nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
nvidia,tristate = <TEGRA_PIN_DISABLE>;
};
drive-sdio1 {
nvidia,pins = "drive_sdio1", "drive_vi1";
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-i2c {
nvidia,pins = "drive_dbg", "drive_ddc", "drive_at1",
"drive_vi2", "drive_ao1";
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>;
};
drive-dap {
nvidia,pins = "drive_dap2", "drive_dap3";
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 = <46>;
nvidia,pull-up-strength = <46>;
nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOWEST>;
};
};
};
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 {
vdd_1v8_vio: sd3 {
regulator-name = "vcc_1v8_io";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
iovcc_1v8_lcd: ldo3 {
regulator-name = "vcc_1v8_lcd";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-boot-on;
};
avdd_3v3_usb: ldo4 {
regulator-name = "avdd_3v3_usb";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
vcore_emmc: ldo5 {
regulator-name = "vcc_2v8_emmc";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-boot-on;
};
vdd_usd: ldo12 {
regulator-name = "vcc_2v8_sdio";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-boot-on;
};
vcc_2v8_lcd: ldo14 {
regulator-name = "vcc_2v8_lcd";
regulator-min-microvolt = <2800000>;
regulator-max-microvolt = <2800000>;
regulator-boot-on;
};
};
};
};
dcdc_i2c: i2c-5 {
compatible = "i2c-gpio";
sda-gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_HIGH>;
scl-gpios = <&gpio TEGRA_GPIO(Q, 1) GPIO_ACTIVE_HIGH>;
i2c-gpio,delay-us = <5>;
i2c-gpio,timeout-ms = <100>;
#address-cells = <1>;
#size-cells = <0>;
aat2870: led-controller@60 {
compatible = "skyworks,aat2870";
reg = <0x60>;
enable-gpios = <&gpio TEGRA_GPIO(R, 3) GPIO_ACTIVE_HIGH>;
backlight {
current-max-microamp = <27900000>;
};
};
};
micro_usb: usb@c5000000 {
status = "okay";
dr_mode = "otg";
};
usb-phy@c5000000 {
status = "okay";
vbus-supply = <&avdd_3v3_usb>;
};
sdmmc3: sdhci@c8000400 {
status = "okay";
bus-width = <4>;
cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
vmmc-supply = <&vdd_usd>;
vqmmc-supply = <&vdd_1v8_vio>;
};
sdmmc4: sdhci@c8000600 {
status = "okay";
bus-width = <8>;
non-removable;
vmmc-supply = <&vcore_emmc>;
vqmmc-supply = <&vdd_1v8_vio>;
};
/* 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";
};
bridge: cpu-bridge {
compatible = "nvidia,tegra-8bit-cpu";
dc-gpios = <&gpio TEGRA_GPIO(N, 6) GPIO_ACTIVE_HIGH>;
rw-gpios = <&gpio TEGRA_GPIO(B, 3) GPIO_ACTIVE_HIGH>;
cs-gpios = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
data-gpios = <&gpio TEGRA_GPIO(E, 0) GPIO_ACTIVE_HIGH>,
<&gpio TEGRA_GPIO(E, 1) GPIO_ACTIVE_HIGH>,
<&gpio TEGRA_GPIO(E, 2) GPIO_ACTIVE_HIGH>,
<&gpio TEGRA_GPIO(E, 3) GPIO_ACTIVE_HIGH>,
<&gpio TEGRA_GPIO(E, 4) GPIO_ACTIVE_HIGH>,
<&gpio TEGRA_GPIO(E, 5) GPIO_ACTIVE_HIGH>,
<&gpio TEGRA_GPIO(E, 6) GPIO_ACTIVE_HIGH>,
<&gpio TEGRA_GPIO(E, 7) GPIO_ACTIVE_HIGH>;
nvidia,init-sequence = <0x0000002c 0x0 0x0 0x00005000>;
panel {
/*
* There are 2 rev of P990. One has Hitachi TX10D07VM0BAA
* panel and other has LG LH400WV3-SD04 panel. We are using
* Hitachi here but it is dynamically adjusted for the
* correct compatible.
*/
compatible = "hit,tx10d07vm0baa";
reset-gpios = <&gpio TEGRA_GPIO(V, 7) GPIO_ACTIVE_LOW>;
avci-supply = <&vcc_2v8_lcd>;
iovcc-supply = <&iovcc_1v8_lcd>;
backlight = <&aat2870>;
port {
panel_input: endpoint {
remote-endpoint = <&bridge_output>;
};
};
};
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>;
};
};
};
};
gpio-keys {
compatible = "gpio-keys";
key-power {
label = "Power";
gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
linux,code = <KEY_ENTER>;
};
key-volume-up {
label = "Volume Up";
gpios = <&gpio TEGRA_GPIO(G, 1) GPIO_ACTIVE_LOW>;
linux,code = <KEY_UP>;
};
key-volume-down {
label = "Volume Down";
gpios = <&gpio TEGRA_GPIO(G, 0) GPIO_ACTIVE_LOW>;
linux,code = <KEY_DOWN>;
};
};
vdd_3v3_vbat: regulator-vbat {
compatible = "regulator-fixed";
regulator-name = "vdd_vbat";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
};

View File

@ -448,10 +448,19 @@ enum win_color_depth_id {
#define LVS_OUTPUT_POLARITY_LOW BIT(28)
#define LSC0_OUTPUT_POLARITY_LOW BIT(24)
/* DC_COM_PIN_OUTPUT_SELECT6 0x31a */
#define LDC_OUTPUT_SELECT_V_PULSE1 BIT(14) /* 100b */
/* DC_DISP_DISP_SIGNAL_OPTIONS0 0x400 */
#define H_PULSE0_ENABLE BIT(8)
#define H_PULSE1_ENABLE BIT(10)
#define H_PULSE2_ENABLE BIT(12)
#define V_PULSE0_ENABLE BIT(16)
#define V_PULSE1_ENABLE BIT(18)
#define V_PULSE2_ENABLE BIT(19)
#define V_PULSE3_ENABLE BIT(20)
#define M0_ENABLE BIT(24)
#define M1_ENABLE BIT(26)
/* DC_DISP_DISP_WIN_OPTIONS 0x402 */
#define CURSOR_ENABLE BIT(16)
@ -525,6 +534,28 @@ enum {
BASE_COLOR_SIZE_888,
};
/* DC_DISP_SHIFT_CLOCK_OPTIONS 0x431 */
#define SC0_H_QUALIFIER_SHIFT 0
#define SC1_H_QUALIFIER_SHIFT 16
enum {
SC_H_QUALIFIER_DISABLE,
SC_H_QUALIFIER_NONE,
SC_H_QUALIFIER_HACTIVE,
SC_H_QUALIFIER_EXT_HACTIVE,
SC_H_QUALIFIER_HPULSE,
SC_H_QUALIFIER_EXT_HPULSE,
};
#define SC0_V_QUALIFIER_SHIFT 3
#define SC1_V_QUALIFIER_SHIFT 19
enum {
SC_V_QUALIFIER_NONE,
SC_V_QUALIFIER_RSVD,
SC_V_QUALIFIER_VACTIVE,
SC_V_QUALIFIER_EXT_VACTIVE,
SC_V_QUALIFIER_VPULSE,
SC_V_QUALIFIER_EXT_VPULSE,
};
/* DC_DISP_DATA_ENABLE_OPTIONS 0x432 */
#define DE_SELECT_SHIFT 0
#define DE_SELECT_MASK (0x3 << DE_SELECT_SHIFT)
@ -541,6 +572,23 @@ enum {
DE_CONTROL_ACTIVE_BLANK,
};
/* DC_DISP_INIT_SEQ_CONTROL 0x442 */
#define SEND_INIT_SEQUENCE BIT(0)
#define INIT_SEQUENCE_MODE_SPI BIT(1)
#define INIT_SEQUENCE_MODE_PLCD 0x0
#define INIT_SEQ_DC_SIGNAL_SHIFT 4
#define INIT_SEQ_DC_SIGNAL_MASK (0x7 << INIT_SEQ_DC_SIGNAL_SHIFT)
enum {
NO_DC_SIGNAL,
DC_SIGNAL_VSYNC,
DC_SIGNAL_VPULSE0,
DC_SIGNAL_VPULSE1,
DC_SIGNAL_VPULSE2,
DC_SIGNAL_VPULSE3,
};
#define INIT_SEQ_DC_CONTROL_SHIFT 7
#define FRAME_INIT_SEQ_CYCLES_SHIFT 8
/* DC_WIN_WIN_OPTIONS 0x700 */
#define H_DIRECTION BIT(0)
enum {

View File

@ -198,6 +198,23 @@ source "arch/arm/mach-tegra/tegra124/Kconfig"
source "arch/arm/mach-tegra/tegra210/Kconfig"
source "arch/arm/mach-tegra/tegra186/Kconfig"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_PRAM
select TEGRA_SUPPORT_NON_SECURE if TEGRA114 || TEGRA124
bool "Support reservation of the protected RAM"
help
This option indicates the presence of a region of protected RAM.
config TEGRA_PRAM_SIZE
hex "Size of pRAM region"
depends on TEGRA_PRAM
default 0x1000
help
Size in kB of carevout which will be reserved as protected RAM starting
from the top of the RAM.
config TEGRA_SPI
def_bool y
depends on TEGRA20_SFLASH || TEGRA20_SLINK || TEGRA114_SPI

View File

@ -227,31 +227,6 @@ int board_early_init_f(void)
arch_timer_init();
#endif
#if defined(CONFIG_DISABLE_SDMMC1_EARLY)
/*
* Turn off (reset/disable) SDMMC1 on Nano here, before GPIO INIT.
* We do this because earlier bootloaders have enabled power to
* SDMMC1 on Nano, and toggling power-gpio (PZ3) in pinmux_init()
* results in power being back-driven into the SD-card and SDMMC1
* HW, which is 'bad' as per the HW team.
*
* From the HW team: "LDO2 from the PMIC has already been set to 3.3v in
* nvtboot/CBoot on Nano (for SD-card boot). So when U-Boot's GPIO_INIT
* table sets PZ3 to OUT0 as per the pinmux spreadsheet, it turns off
* the loadswitch. When PZ3 is 0 and not driving, essentially the SDCard
* voltage turns off. Since the SDCard voltage is no longer there, the
* SDMMC CLK/DAT lines are backdriving into what essentially is a
* powered-off SDCard, that's why the voltage drops from 3.3V to ~1.6V"
*
* Note that this can probably be removed when we change over to storing
* all BL components on QSPI on Nano, and U-Boot then becomes the first
* one to turn on SDMMC1 power. Another fix would be to have CBoot
* disable power/gate SDMMC1 off before handing off to U-Boot/kernel.
*/
reset_set_enable(PERIPH_ID_SDMMC1, 1);
clock_set_enable(PERIPH_ID_SDMMC1, 0);
#endif /* CONFIG_DISABLE_SDMMC1_EARLY */
pinmux_init();
board_init_uart_f();

View File

@ -54,6 +54,10 @@ config TARGET_SEABOARD
select TEGRA_LP0
select TEGRA_PMU
config TARGET_STAR
bool "LG Tegra20 Star board"
select BOARD_LATE_INIT
config TARGET_TEC
bool "Avionic Design Tamonten Evaluation Carrier"
select BOARD_LATE_INIT
@ -88,6 +92,7 @@ source "board/compal/paz00/Kconfig"
source "board/acer/picasso/Kconfig"
source "board/avionic-design/plutux/Kconfig"
source "board/nvidia/seaboard/Kconfig"
source "board/lg/star/Kconfig"
source "board/avionic-design/tec/Kconfig"
source "board/asus/transformer-t20/Kconfig"
source "board/compulab/trimslice/Kconfig"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "acer"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "Acer Iconia Tab A500"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "asus"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "ASUS Google Nexus 7 (2012)"

View File

@ -6,11 +6,12 @@ config SYS_BOARD
config SYS_VENDOR
default "asus"
config SYS_CONFIG_NAME
default "transformer-t114"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "ASUS Transformer T114"
config TEGRA_PRAM_SIZE
depends on TEGRA_PRAM
default 0x20000
endif

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "asus"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "ASUS Transformer T20"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "asus"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "ASUS Transformer T30"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "avionic-design"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "Avionic Design Medcom-Wide"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "avionic-design"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "Avionic Design Plutux"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "avionic-design"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "Avionic Design Tamonten™ NG Evaluation Carrier"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "avionic-design"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "Avionic Design Tamonten Evaluation Carrier"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "cei"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "CEI tk1-som"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "compal"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "Compal Paz00"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "compulab"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "Compulab Trimslice"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "htc"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "HTC One X"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "lenovo"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "Lenovo Ideapad Yoga 11"

13
board/lg/star/Kconfig Normal file
View File

@ -0,0 +1,13 @@
if TARGET_STAR
config SYS_BOARD
default "star"
config SYS_VENDOR
default "lg"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "LG Star"
endif

View File

@ -0,0 +1,7 @@
STAR BOARD
M: Svyatoslav Ryhel <clamor95@gmail.com>
S: Maintained
F: arch/arm/dts/tegra20-lg-star.dts
F: board/lg/star/
F: configs/star_defconfig
F: doc/board/lg/star.rst

9
board/lg/star/Makefile Normal file
View File

@ -0,0 +1,9 @@
# SPDX-License-Identifier: GPL-2.0+
#
# (C) Copyright 2010-2012
# NVIDIA Corporation <www.nvidia.com>
#
# (C) Copyright 2024
# Svyatoslav Ryhel <clamor95@gmail.com>
obj-y += star.o

50
board/lg/star/star.c Normal file
View File

@ -0,0 +1,50 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2023
* Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <dm/root.h>
#include <fdt_support.h>
#include <log.h>
#include <spl_gpio.h>
static int star_fix_panel(void *fdt)
{
int panel_offset, ret;
/* Patch panel compatible */
spl_gpio_input(NULL, TEGRA_GPIO(J, 5));
if (spl_gpio_get_value(NULL, TEGRA_GPIO(J, 5))) {
panel_offset = fdt_node_offset_by_compatible(fdt, -1,
"hit,tx10d07vm0baa");
if (panel_offset < 0) {
log_debug("%s: panel node not found\n", __func__);
return panel_offset;
}
ret = fdt_setprop_string(fdt, panel_offset, "compatible",
"lg,lh400wv3-sd04");
if (ret) {
log_debug("%s: panel comapible patch failed\n", __func__);
return ret;
}
}
return 0;
}
void pinmux_init(void)
{
void *fdt = (void *)gd->fdt_blob;
star_fix_panel(fdt);
}
#if IS_ENABLED(CONFIG_OF_LIBFDT) && IS_ENABLED(CONFIG_OF_BOARD_SETUP)
int ft_board_setup(void *fdt, struct bd_info *bd)
{
return star_fix_panel(fdt);
}
#endif

15
board/lg/star/star.env Normal file
View File

@ -0,0 +1,15 @@
#include <env/nvidia/prod_upd.env>
button_cmd_0_name=Volume Down
button_cmd_0=bootmenu
partitions=name=emmc,start=0,size=-,uuid=${uuid_gpt_rootfs}
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=update bootloader=run flash_uboot
bootmenu_4=reboot RCM=enterrcm
bootmenu_5=reboot=reset
bootmenu_6=power off=poweroff
bootmenu_delay=-1

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "lg"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "LG X3 Board"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "microsoft"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "Microsoft Surface RT"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "NVIDIA Beaver"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "NVIDIA Cardhu"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "NVIDIA Dalmore"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "NVIDIA Harmony"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "NVIDIA Jetson TK1"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "Google/NVIDIA Nyan-big"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "NVIDIA P2371-0000"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "NVIDIA P2371-2180"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "NVIDIA P2571"

View File

@ -10,9 +10,6 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "NVIDIA P2771-0000"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "NVIDIA P3450-0000"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "NVIDIA Seaboard"

View File

@ -6,11 +6,12 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegratab"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "NVIDIA TegraTab"
config TEGRA_PRAM_SIZE
depends on TEGRA_PRAM
default 0x21c00
endif

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "NVIDIA Venice2"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "nvidia"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "NVIDIA Ventana"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "ouya"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "Ouya Game Console"

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "toradex"
config SYS_CONFIG_NAME
default "tegra"
config TDX_CFG_BLOCK
default y

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "toradex"
config SYS_CONFIG_NAME
default "tegra"
config TDX_CFG_BLOCK
default y

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "toradex"
config SYS_CONFIG_NAME
default "tegra"
config TDX_CFG_BLOCK
default y

View File

@ -6,9 +6,6 @@ config SYS_BOARD
config SYS_VENDOR
default "wexler"
config SYS_CONFIG_NAME
default "tegra"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "Wexler QC750"

View File

@ -6,11 +6,12 @@ config SYS_BOARD
config SYS_VENDOR
default "xiaomi"
config SYS_CONFIG_NAME
default "mocha"
config TEGRA_BOARD_STRING
string "Default Tegra board name"
default "Xiaomi Mocha"
config TEGRA_PRAM_SIZE
depends on TEGRA_PRAM
default 0x38400
endif

93
configs/star_defconfig Normal file
View File

@ -0,0 +1,93 @@
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="star"
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra20-lg-star"
CONFIG_SPL_STACK=0xffffc
CONFIG_SPL_TEXT_BASE=0x00108000
CONFIG_SYS_LOAD_ADDR=0x2000000
CONFIG_TEGRA20=y
CONFIG_TARGET_STAR=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_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=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 (Star) # "
# 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_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_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_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="LG"
CONFIG_USB_GADGET_VENDOR_NUM=0x1004
CONFIG_USB_GADGET_PRODUCT_NUM=0x7100
CONFIG_CI_UDC=y
CONFIG_VIDEO=y
# CONFIG_VIDEO_LOGO is not set
# CONFIG_VIDEO_BPP8 is not set
CONFIG_VIDEO_LCD_LG_LH400WV3=y
CONFIG_VIDEO_LCD_HITACHI_TX10D07VM0BAA=y
CONFIG_BACKLIGHT_AAT2870=y
CONFIG_VIDEO_BRIDGE=y
CONFIG_TEGRA_8BIT_CPU_BRIDGE=y

View File

@ -36,7 +36,7 @@ To build U-Boot without SPL adjust tf701t_defconfig:
CONFIG_TEXT_BASE=0x80A00000
CONFIG_SKIP_LOWLEVEL_INIT=y
# CONFIG_OF_BOARD_SETUP is not set
CONFIG_TEGRA_SUPPORT_NON_SECURE=y
CONFIG_TEGRA_PRAM=y
After the build succeeds, you will obtain the final ``u-boot-dtb.bin`` file,
ready for booting with fastboot boot or which can be further processed into

View File

@ -6,4 +6,5 @@ LG
.. toctree::
:maxdepth: 2
star
x3_t30

125
doc/board/lg/star.rst Normal file
View File

@ -0,0 +1,125 @@
.. SPDX-License-Identifier: GPL-2.0+
U-Boot for the LG Optimus 2X P990
=================================
``DISCLAMER!`` Moving your device to use U-Boot assumes replacement of the
vendor bootloader. Vendor Android firmwares will no longer be able to run on
the device. This replacement IS reversible.
Quick Start
-----------
- Build U-Boot
- Process U-Boot
- Flashing U-Boot into the eMMC
- Boot
- Self Upgrading
Build U-Boot
------------
.. code-block:: bash
$ export CROSS_COMPILE=arm-none-eabi-
$ make star_defconfig
$ make
After the build succeeds, you will obtain the final ``u-boot-dtb-tegra.bin``
image, ready for further processing.
Process U-Boot
--------------
``DISCLAMER!`` All questions related to the re-crypt work should be asked
in re-crypt repo issues. NOT HERE!
re-crypt is a tool that processes the ``u-boot-dtb-tegra.bin`` binary into form
usable by device. This process is required only on the first installation or
to recover the device in case of a failed update.
Permanent installation can be performed either by using the nv3p protocol or by
pre-loading just built U-Boot into RAM.
Processing for the NV3P protocol
********************************
.. code-block:: bash
$ git clone https://gitlab.com/grate-driver/re-crypt.git
$ cd re-crypt # place your u-boot-dtb-tegra.bin here
$ ./re-crypt.py --dev star
The script will produce a ``repart-block.bin`` ready to flash.
Processing for pre-loaded U-Boot
********************************
The procedure is the same, but the ``--split`` argument is used with the
``re-crypt.py``. The script will produce ``bct.img`` and ``ebt.img`` ready
to flash.
Flashing U-Boot into the eMMC
-----------------------------
``DISCLAMER!`` All questions related to NvFlash should be asked in the proper
place. NOT HERE! Flashing U-Boot will erase all eMMC, so make a backup before!
Permanent installation can be performed either by using the nv3p protocol or by
pre-loading just built U-Boot into RAM.
Flashing with the NV3P protocol
*******************************
Nv3p is a custom Nvidia protocol used to recover bricked devices. Devices can
enter it by pre-loading vendor bootloader with nvflash.
With nv3p, ``repart-block.bin`` is used. It contains BCT and a bootloader in
encrypted state in form, which can just be written RAW at the start of eMMC.
.. code-block:: bash
$ ./nvflash_v1.13.87205 --bct star.bct --setbct --odmdata 0xC8000
--configfile flash.cfg --bl android_bootloader.bin --sync
$ ./utiils/nvflash_v1.13.87205 --resume --rawdevicewrite 0 2048 repart-block.bin
When flashing is done, reboot the device.
Flashing with a pre-loaded U-Boot
*********************************
U-Boot pre-loaded into RAM acts the same as when it was booted "cold". Currently
U-Boot supports bootmenu entry fastboot, which allows to write a processed copy
of U-Boot permanently into eMMC.
While pre-loading U-Boot, hold the ``volume down`` button which will trigger
the bootmenu. There, select ``fastboot`` using the volume and power buttons.
After, on host PC, do:
.. code-block:: bash
$ fastboot flash 0.1 bct.img
$ fastboot flash 0.2 ebt.img
$ fastboot reboot
Device will reboot.
Boot
----
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 booting, the
device will enter bootmenu. Bootmenu contains entries to mount MicroSD and eMMC
as mass storage, fastboot, reboot, reboot RCM, poweroff, enter U-Boot console
and update bootloader (check the next chapter).
Flashing ``repart-block.bin`` eliminates vendor restrictions on eMMC and allows
the user to use/partition it in any way the user desires.
Self Upgrading
--------------
Place your ``u-boot-dtb-tegra.bin`` on the first partition of the MicroSD card
and insert it into the device. Enter bootmenu, choose update the bootloader
option with the Power button and U-Boot should update itself. Once the process
is completed, U-Boot will ask to press any button to reboot.

View File

@ -36,7 +36,7 @@ To build U-Boot without SPL adjust tegratab_defconfig:
CONFIG_TEXT_BASE=0x80A00000
CONFIG_SKIP_LOWLEVEL_INIT=y
# CONFIG_OF_BOARD_SETUP is not set
CONFIG_TEGRA_SUPPORT_NON_SECURE=y
CONFIG_TEGRA_PRAM=y
After the build succeeds, you will obtain the final ``u-boot-dtb.bin`` file,
ready for booting with fastboot boot or which can be further processed into

View File

@ -105,7 +105,7 @@ To build U-Boot without SPL suitable for chainloading adjust mocha_defconfig:
CONFIG_TEXT_BASE=0x80A00000
CONFIG_SKIP_LOWLEVEL_INIT=y
# CONFIG_OF_BOARD_SETUP is not set
CONFIG_TEGRA_SUPPORT_NON_SECURE=y
CONFIG_TEGRA_PRAM=y
After the build succeeds, you will obtain the final ``u-boot-dtb.bin``
file, ready for booting using vendor bootloader's fastboot or which can be

View File

@ -248,6 +248,16 @@ static int tegra_gpio_xlate(struct udevice *dev, struct gpio_desc *desc,
return 0;
}
static int tegra_gpio_rfree(struct udevice *dev, unsigned int offset)
{
struct tegra_port_info *state = dev_get_priv(dev);
/* Set the pin as a SFIO */
set_config(state->base_gpio + offset, CFG_SFIO);
return 0;
}
static const struct dm_gpio_ops gpio_tegra_ops = {
.direction_input = tegra_gpio_direction_input,
.direction_output = tegra_gpio_direction_output,
@ -255,6 +265,7 @@ static const struct dm_gpio_ops gpio_tegra_ops = {
.set_value = tegra_gpio_set_value,
.get_function = tegra_gpio_get_function,
.xlate = tegra_gpio_xlate,
.rfree = tegra_gpio_rfree,
};
/*

View File

@ -184,6 +184,15 @@ config SPL_DM_PMIC_PFUZE100
This config enables implementation of driver-model pmic uclass features
for PMIC PFUZE100 in SPL. The driver implements read/write operations.
config DM_PMIC_MAX8907
bool "Enable Driver Model for PMIC MAX8907"
---help---
This config enables implementation of driver-model pmic uclass features
for PMIC MAX8907. The driver implements read/write operations.
This is a Power Management IC with a decent set of peripherals from which
3 DC-to-DC Step-Down (SD) Regulators, 20 Low-Dropout Linear (LDO) Regulators,
Real-Time Clock (RTC) and more with I2C Compatible Interface.
config DM_PMIC_MAX77663
bool "Enable Driver Model for PMIC MAX77663"
---help---

View File

@ -7,6 +7,7 @@ obj-$(CONFIG_$(PHASE_)DM_PMIC) += pmic-uclass.o
obj-$(CONFIG_$(PHASE_)DM_PMIC_FAN53555) += fan53555.o
obj-$(CONFIG_$(PHASE_)DM_PMIC_DA9063) += da9063.o
obj-$(CONFIG_$(PHASE_)DM_PMIC_MAX77663) += max77663.o
obj-$(CONFIG_$(PHASE_)DM_PMIC_MAX8907) += max8907.o
obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
obj-$(CONFIG_DM_PMIC_MAX8998) += max8998.o
obj-$(CONFIG_DM_PMIC_MC34708) += mc34708.o

View File

@ -0,0 +1,94 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright(C) 2024 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <dm/lists.h>
#include <power/pmic.h>
#include <power/max8907.h>
static const struct pmic_child_info pmic_children_info[] = {
{ .prefix = "ldo", .driver = MAX8907_LDO_DRIVER },
{ .prefix = "sd", .driver = MAX8907_SD_DRIVER },
{ },
};
static int max8907_write(struct udevice *dev, uint reg, const uint8_t *buff, int len)
{
int ret;
ret = dm_i2c_write(dev, reg, buff, len);
if (ret) {
log_debug("%s: write error to device: %p register: %#x!\n",
__func__, dev, reg);
return ret;
}
return 0;
}
static int max8907_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
{
int ret;
ret = dm_i2c_read(dev, reg, buff, len);
if (ret) {
log_debug("%s: read error from device: %p register: %#x!\n",
__func__, dev, reg);
return ret;
}
return 0;
}
static int max8907_bind(struct udevice *dev)
{
ofnode regulators_node;
int children, ret;
if (IS_ENABLED(CONFIG_SYSRESET_MAX8907) &&
dev_read_bool(dev, "maxim,system-power-controller")) {
ret = device_bind_driver_to_node(dev, MAX8907_RST_DRIVER,
"sysreset", dev_ofnode(dev),
NULL);
if (ret) {
log_debug("%s: cannot bind SYSRESET (ret = %d)\n",
__func__, ret);
return ret;
}
}
regulators_node = dev_read_subnode(dev, "regulators");
if (!ofnode_valid(regulators_node)) {
log_err("%s regulators subnode not found!\n", dev->name);
return -ENXIO;
}
log_debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
children = pmic_bind_children(dev, regulators_node, pmic_children_info);
if (!children)
log_err("%s - no child found\n", dev->name);
/* Always return success for this device */
return 0;
}
static struct dm_pmic_ops max8907_ops = {
.read = max8907_read,
.write = max8907_write,
};
static const struct udevice_id max8907_ids[] = {
{ .compatible = "maxim,max8907" },
{ }
};
U_BOOT_DRIVER(pmic_max8907) = {
.name = "max8907_pmic",
.id = UCLASS_PMIC,
.of_match = max8907_ids,
.bind = max8907_bind,
.ops = &max8907_ops,
};

View File

@ -148,6 +148,15 @@ config SPL_REGULATOR_PWM
This config enables implementation of driver-model regulator uclass
features for PWM regulators in SPL.
config DM_REGULATOR_MAX8907
bool "Enable Driver Model for REGULATOR MAX8907"
depends on DM_REGULATOR && DM_PMIC_MAX8907
---help---
This config enables implementation of driver-model regulator uclass
features for REGULATOR MAX8907. The driver supports both DC-to-DC
Step-Down (SD) Regulators and Low-Dropout Linear (LDO) Regulators
found in MAX8907 PMIC and implements get/set api for value and enable.
config DM_REGULATOR_MAX77663
bool "Enable Driver Model for REGULATOR MAX77663"
depends on DM_REGULATOR && DM_PMIC_MAX77663

View File

@ -12,6 +12,7 @@ obj-$(CONFIG_$(PHASE_)REGULATOR_AXP_DRIVEVBUS) += axp_drivevbus.o
obj-$(CONFIG_$(PHASE_)REGULATOR_AXP_USB_POWER) += axp_usb_power.o
obj-$(CONFIG_$(PHASE_)DM_REGULATOR_DA9063) += da9063.o
obj-$(CONFIG_$(PHASE_)DM_REGULATOR_MAX77663) += max77663_regulator.o
obj-$(CONFIG_$(PHASE_)DM_REGULATOR_MAX8907) += max8907_regulator.o
obj-$(CONFIG_DM_REGULATOR_MAX77686) += max77686.o
obj-$(CONFIG_DM_REGULATOR_NPCM8XX) += npcm8xx_regulator.o
obj-$(CONFIG_$(PHASE_)DM_PMIC_PFUZE100) += pfuze100.o

View File

@ -0,0 +1,249 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright(C) 2024 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <power/pmic.h>
#include <power/regulator.h>
#include <power/max8907.h>
static const char max8907_regmap[] = {
0x00, MAX8907_REG_SDCTL1, MAX8907_REG_SDCTL2, MAX8907_REG_SDCTL3,
MAX8907_REG_LDOCTL1, MAX8907_REG_LDOCTL2, MAX8907_REG_LDOCTL3,
MAX8907_REG_LDOCTL4, MAX8907_REG_LDOCTL5, MAX8907_REG_LDOCTL6,
MAX8907_REG_LDOCTL7, MAX8907_REG_LDOCTL8, MAX8907_REG_LDOCTL9,
MAX8907_REG_LDOCTL10, MAX8907_REG_LDOCTL11, MAX8907_REG_LDOCTL12,
MAX8907_REG_LDOCTL13, MAX8907_REG_LDOCTL14, MAX8907_REG_LDOCTL15,
MAX8907_REG_LDOCTL16, MAX8907_REG_LDOCTL17, MAX8907_REG_LDOCTL18,
MAX8907_REG_LDOCTL19, MAX8907_REG_LDOCTL20
};
static int max8907_enable(struct udevice *dev, int op, bool *enable)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
int val, ret = 0;
if (op == PMIC_OP_GET) {
val = pmic_reg_read(dev->parent, uc_pdata->ctrl_reg);
if (val < 0)
return val;
if (val & MAX8907_MASK_LDO_EN)
*enable = true;
else
*enable = false;
} else if (op == PMIC_OP_SET) {
if (*enable) {
ret = pmic_clrsetbits(dev->parent,
uc_pdata->ctrl_reg,
MAX8907_MASK_LDO_EN |
MAX8907_MASK_LDO_SEQ,
MAX8907_MASK_LDO_EN |
MAX8907_MASK_LDO_SEQ);
} else {
ret = pmic_clrsetbits(dev->parent,
uc_pdata->ctrl_reg,
MAX8907_MASK_LDO_EN |
MAX8907_MASK_LDO_SEQ,
MAX8907_MASK_LDO_SEQ);
}
}
return ret;
}
static int max8907_get_enable(struct udevice *dev)
{
bool enable = false;
int ret;
ret = max8907_enable(dev, PMIC_OP_GET, &enable);
if (ret)
return ret;
return enable;
}
static int max8907_set_enable(struct udevice *dev, bool enable)
{
return max8907_enable(dev, PMIC_OP_SET, &enable);
}
/**
* max8907_volt2hex() - convert voltage in uV into
* applicable to register hex value
*
* @idx: regulator index
* @uV: voltage in uV
*
* Return: voltage in hex on success, -ve on failure
*/
static int max8907_volt2hex(int idx, int uV)
{
switch (idx) {
case 1: /* SD1 */
if (uV > SD1_VOLT_MAX || uV < SD1_VOLT_MIN)
break;
return (uV - SD1_VOLT_MIN) / SD1_VOLT_STEP;
case 2: /* SD2 */
if (uV > SD2_VOLT_MAX || uV < SD2_VOLT_MIN)
break;
return (uV - SD2_VOLT_MIN) / SD2_VOLT_STEP;
case 3: /* SD3 */
if (uV > SD2_VOLT_MAX || uV < SD2_VOLT_MIN)
break;
return (uV - SD2_VOLT_MIN) / SD2_VOLT_STEP;
case 5: /* LDO2 */
case 6: /* LDO3 */
case 20: /* LDO17 */
case 21: /* LDO18 */
if (uV > LDO_650_VOLT_MAX || uV < LDO_650_VOLT_MIN)
break;
return (uV - LDO_650_VOLT_MIN) / LDO_650_VOLT_STEP;
default: /* LDO1, 4..16, 19..20 */
if (uV > LDO_750_VOLT_MAX || uV < LDO_750_VOLT_MIN)
break;
return (uV - LDO_750_VOLT_MIN) / LDO_750_VOLT_STEP;
};
return -EINVAL;
}
/**
* max8907_hex2volt() - convert register hex value into
* actual voltage in uV
*
* @idx: regulator index
* @hex: hex value of register
*
* Return: voltage in uV on success, -ve on failure
*/
static int max8907_hex2volt(int idx, int hex)
{
switch (idx) {
case 1:
return hex * SD1_VOLT_STEP + SD1_VOLT_MIN;
case 2:
return hex * SD2_VOLT_STEP + SD2_VOLT_MIN;
case 3:
return hex * SD3_VOLT_STEP + SD3_VOLT_MIN;
case 5: /* LDO2 */
case 6: /* LDO3 */
case 20: /* LDO17 */
case 21: /* LDO18 */
return hex * LDO_650_VOLT_STEP + LDO_650_VOLT_MIN;
default: /* LDO1, 4..16, 19..20 */
return hex * LDO_750_VOLT_STEP + LDO_750_VOLT_MIN;
};
return -EINVAL;
}
static int max8907_val(struct udevice *dev, int op, int *uV)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
int idx = dev->driver_data;
int hex, ret;
if (op == PMIC_OP_GET) {
hex = pmic_reg_read(dev->parent, uc_pdata->volt_reg);
if (hex < 0)
return hex;
*uV = 0;
ret = max8907_hex2volt(idx, hex);
if (ret < 0)
return ret;
*uV = ret;
return 0;
}
hex = max8907_volt2hex(idx, *uV);
if (hex < 0)
return hex;
return pmic_reg_write(dev->parent, uc_pdata->volt_reg, hex);
}
static int max8907_get_value(struct udevice *dev)
{
int uV;
int ret;
ret = max8907_val(dev, PMIC_OP_GET, &uV);
if (ret)
return ret;
return uV;
}
static int max8907_set_value(struct udevice *dev, int uV)
{
return max8907_val(dev, PMIC_OP_SET, &uV);
}
static const struct dm_regulator_ops max8907_regulator_ops = {
.get_value = max8907_get_value,
.set_value = max8907_set_value,
.get_enable = max8907_get_enable,
.set_enable = max8907_set_enable,
};
static int max8907_sd_probe(struct udevice *dev)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
int idx = dev->driver_data;
uc_pdata->type = REGULATOR_TYPE_BUCK;
uc_pdata->ctrl_reg = max8907_regmap[idx];
uc_pdata->volt_reg = uc_pdata->ctrl_reg + MAX8907_VOUT;
return 0;
}
U_BOOT_DRIVER(max8907_sd) = {
.name = MAX8907_SD_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &max8907_regulator_ops,
.probe = max8907_sd_probe,
};
static int max8907_ldo_probe(struct udevice *dev)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
/* LDO regulator id is shifted by number for SD regulators */
int idx = dev->driver_data + 3;
uc_pdata->type = REGULATOR_TYPE_LDO;
uc_pdata->ctrl_reg = max8907_regmap[idx];
uc_pdata->volt_reg = uc_pdata->ctrl_reg + MAX8907_VOUT;
return 0;
}
U_BOOT_DRIVER(max8907_ldo) = {
.name = MAX8907_LDO_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &max8907_regulator_ops,
.probe = max8907_ldo_probe,
};

View File

@ -131,6 +131,13 @@ config SYSRESET_MAX77663
help
Enable system power management functions found in MAX77663 PMIC.
config SYSRESET_MAX8907
bool "Enable support for MAX8907 PMIC System Reset"
depends on DM_PMIC_MAX8907
select SYSRESET_CMD_POWEROFF if CMD_POWEROFF
help
Enable system power management functions found in MAX8907 PMIC.
config SYSRESET_MICROBLAZE
bool "Enable support for Microblaze soft reset"
depends on MICROBLAZE

View File

@ -11,6 +11,7 @@ obj-$(CONFIG_SYSRESET_CV1800B) += sysreset_cv1800b.o
obj-$(CONFIG_$(PHASE_)POWEROFF_GPIO) += poweroff_gpio.o
obj-$(CONFIG_$(PHASE_)SYSRESET_GPIO) += sysreset_gpio.o
obj-$(CONFIG_$(PHASE_)SYSRESET_MAX77663) += sysreset_max77663.o
obj-$(CONFIG_$(PHASE_)SYSRESET_MAX8907) += sysreset_max8907.o
obj-$(CONFIG_SYSRESET_MPC83XX) += sysreset_mpc83xx.o
obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o
obj-$(CONFIG_SYSRESET_OCTEON) += sysreset_octeon.o

View File

@ -0,0 +1,37 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright(C) 2024 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <i2c.h>
#include <errno.h>
#include <sysreset.h>
#include <power/pmic.h>
#include <power/max8907.h>
static int max8907_sysreset_request(struct udevice *dev, enum sysreset_t type)
{
switch (type) {
case SYSRESET_POWER:
case SYSRESET_POWER_OFF:
/* MAX8907: PWR_OFF > RESET_CNFG */
pmic_clrsetbits(dev->parent, MAX8907_REG_RESET_CNFG,
MASK_POWER_OFF, MASK_POWER_OFF);
break;
default:
return -EPROTONOSUPPORT;
}
return -EINPROGRESS;
}
static struct sysreset_ops max8907_sysreset = {
.request = max8907_sysreset_request,
};
U_BOOT_DRIVER(sysreset_max8907) = {
.id = UCLASS_SYSRESET,
.name = MAX8907_RST_DRIVER,
.ops = &max8907_sysreset,
};

View File

@ -581,6 +581,14 @@ config VIDEO_LCD_LG_LD070WX3
Say Y here if you want to enable support for LG LD070WX3
800x1280 DSI video mode panel.
config VIDEO_LCD_LG_LH400WV3
bool "LH400WV3-SD04 DSI LCD panel support"
depends on PANEL && BACKLIGHT
select VIDEO_MIPI_DSI
help
Say Y here if you want to enable support for LG LH400WV3
480x800 DSI video mode panel.
config VIDEO_LCD_RAYDIUM_RM68200
bool "RM68200 DSI LCD panel support"
select VIDEO_MIPI_DSI
@ -668,6 +676,14 @@ config VIDEO_LCD_TDO_TL070WSH30
Say Y here if you want to enable support for TDO TL070WSH30
1024x600 DSI video mode panel.
config VIDEO_LCD_HITACHI_TX10D07VM0BAA
tristate "Hitachi TX10D07VM0BAA 480x800 MIPI DSI video mode panel"
depends on PANEL && BACKLIGHT
select VIDEO_MIPI_DSI
help
Say Y here if you want to enable support for Hitachi TX10D07VM0BAA
TFT-LCD module. The panel has a 480x800 resolution.
config VIDEO_LCD_HITACHI_TX18D42VM
bool "Hitachi tx18d42vm LVDS LCD panel support"
---help---
@ -767,6 +783,16 @@ config ATMEL_HLCD
help
HLCDC supports video output to an attached LCD panel.
config BACKLIGHT_AAT2870
bool "Backlight Driver for AAT2870"
depends on BACKLIGHT
select DM_I2C
help
Say Y to enable the backlight driver for Skyworks AAT2870 LED
Backlight Driver and Multiple LDO Lighting Management Unit.
Only backlight is supported as for now. Supported backlight
level range is from 2 to 255 with step of 1.
config BACKLIGHT_LM3532
bool "Backlight Driver for LM3532"
depends on BACKLIGHT

View File

@ -29,6 +29,7 @@ obj-$(CONFIG_$(PHASE_)BMP) += bmp.o
endif
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
@ -58,8 +59,10 @@ obj-$(CONFIG_VIDEO_IVYBRIDGE_IGD) += ivybridge_igd.o
obj-$(CONFIG_VIDEO_LCD_ANX9804) += anx9804.o
obj-$(CONFIG_VIDEO_LCD_ENDEAVORU) += endeavoru-panel.o
obj-$(CONFIG_VIDEO_LCD_HIMAX_HX8394) += himax-hx8394.o
obj-$(CONFIG_VIDEO_LCD_HITACHI_TX10D07VM0BAA) += hitachi-tx10d07vm0baa.o
obj-$(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM) += hitachi_tx18d42vm_lcd.o
obj-$(CONFIG_VIDEO_LCD_LG_LD070WX3) += lg-ld070wx3.o
obj-$(CONFIG_VIDEO_LCD_LG_LH400WV3) += lg-lh400wv3-sd04.o
obj-$(CONFIG_VIDEO_LCD_MOT) += mot-panel.o
obj-$(CONFIG_VIDEO_LCD_NOVATEK_NT35510) += novatek-nt35510.o
obj-$(CONFIG_VIDEO_LCD_ORISETECH_OTM8009A) += orisetech_otm8009a.o

View File

@ -0,0 +1,132 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2024 Svyatoslav Ryhel <clamor95@gmail.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 AAT2870_BL_MIN_BRIGHTNESS 0x01
#define AAT2870_BL_DEF_BRIGHTNESS 0x64
#define AAT2870_BL_MAX_BRIGHTNESS 0xff
#define AAT2870_BL_CH_EN 0x00
#define AAT2870_BLM 0x01
#define AAT2870_BL_CH_ALL 0xff
#define AAT2870_CURRENT_MAX 27900000
#define AAT2870_CURRENT_STEP 900000
struct aat2870_backlight_priv {
struct gpio_desc enable_gpio;
int channels;
int max_current;
};
static int aat2870_backlight_enable(struct udevice *dev)
{
struct aat2870_backlight_priv *priv = dev_get_priv(dev);
int ret;
dm_gpio_set_value(&priv->enable_gpio, 1);
/* Enable backlight for defined set of channels */
ret = dm_i2c_reg_write(dev, AAT2870_BL_CH_EN, priv->channels);
if (ret)
return ret;
return 0;
}
static int aat2870_backlight_set_brightness(struct udevice *dev, int percent)
{
struct aat2870_backlight_priv *priv = dev_get_priv(dev);
int brightness, ret;
if (percent == BACKLIGHT_DEFAULT)
percent = AAT2870_BL_DEF_BRIGHTNESS;
if (percent < AAT2870_BL_MIN_BRIGHTNESS)
percent = AAT2870_BL_MIN_BRIGHTNESS;
if (percent > AAT2870_BL_MAX_BRIGHTNESS)
percent = AAT2870_BL_MAX_BRIGHTNESS;
brightness = percent * priv->max_current;
brightness /= AAT2870_BL_MAX_BRIGHTNESS;
/* Set brightness level */
ret = dm_i2c_reg_write(dev, AAT2870_BLM, brightness);
if (ret)
return ret;
return 0;
}
static int aat2870_backlight_of_to_plat(struct udevice *dev)
{
struct aat2870_backlight_priv *priv = dev_get_priv(dev);
int ret;
ret = gpio_request_by_name(dev, "enable-gpios", 0,
&priv->enable_gpio, GPIOD_IS_OUT);
if (ret) {
log_err("%s: cannot get enable-gpios (%d)\n",
__func__, ret);
return ret;
}
/* Backlight is one of children but has no dedicated driver */
ofnode backlight = ofnode_find_subnode(dev_ofnode(dev), "backlight");
if (ofnode_valid(backlight) && ofnode_is_enabled(backlight)) {
/* Number of channel is equal to bit number */
priv->channels = dev_read_u32_default(dev, "channels", AAT2870_BL_CH_ALL);
if (priv->channels != AAT2870_BL_CH_ALL)
priv->channels = BIT(priv->channels);
/* 450mA - 27900mA range with a 900mA step */
priv->max_current = dev_read_u32_default(dev, "current-max-microamp",
AAT2870_CURRENT_MAX);
priv->max_current /= AAT2870_CURRENT_STEP;
}
return 0;
}
static int aat2870_backlight_probe(struct udevice *dev)
{
if (device_get_uclass_id(dev->parent) != UCLASS_I2C)
return -EPROTONOSUPPORT;
return 0;
}
static const struct backlight_ops aat2870_backlight_ops = {
.enable = aat2870_backlight_enable,
.set_brightness = aat2870_backlight_set_brightness,
};
static const struct udevice_id aat2870_backlight_ids[] = {
{ .compatible = "analogictech,aat2870" },
{ .compatible = "skyworks,aat2870" },
{ }
};
U_BOOT_DRIVER(aat2870_backlight) = {
.name = "aat2870_backlight",
.id = UCLASS_PANEL_BACKLIGHT,
.of_match = aat2870_backlight_ids,
.of_to_plat = aat2870_backlight_of_to_plat,
.probe = aat2870_backlight_probe,
.ops = &aat2870_backlight_ops,
.priv_auto = sizeof(struct aat2870_backlight_priv),
};

View File

@ -0,0 +1,304 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Hitachi TX10D07VM0BAA DSI panel driver
*
* Copyright (c) 2024 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <backlight.h>
#include <dm.h>
#include <panel.h>
#include <log.h>
#include <mipi_dsi.h>
#include <linux/delay.h>
#include <power/regulator.h>
#include <asm/gpio.h>
struct hitachi_tx10d07vm0baa_priv {
struct udevice *avci;
struct udevice *iovcc;
struct udevice *backlight;
struct gpio_desc reset_gpio;
};
static struct display_timing default_timing = {
.pixelclock.typ = 29816000,
.hactive.typ = 480,
.hfront_porch.typ = 10,
.hback_porch.typ = 10,
.hsync_len.typ = 10,
.vactive.typ = 800,
.vfront_porch.typ = 4,
.vback_porch.typ = 4,
.vsync_len.typ = 4,
};
#define dsi_generic_write_seq(dsi, cmd, seq...) do { \
static const u8 b[] = { cmd, seq }; \
int ret; \
ret = mipi_dsi_dcs_write_buffer(dsi, b, ARRAY_SIZE(b)); \
if (ret < 0) \
return ret; \
} while (0)
static int hitachi_tx10d07vm0baa_enable_backlight(struct udevice *dev)
{
struct mipi_dsi_panel_plat *plat = dev_get_plat(dev);
struct mipi_dsi_device *dsi = plat->device;
int ret;
dsi_generic_write_seq(dsi, MIPI_DCS_SET_PARTIAL_AREA, 0x00,
0x00, 0x03, 0x1f);
dsi_generic_write_seq(dsi, MIPI_DCS_SET_SCROLL_AREA, 0x00,
0x00, 0x03, 0x20, 0x00, 0x00);
dsi_generic_write_seq(dsi, MIPI_DCS_SET_ADDRESS_MODE, 0x0a);
dsi_generic_write_seq(dsi, MIPI_DCS_SET_SCROLL_START, 0x00,
0x00);
ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT);
if (ret) {
log_debug("%s: failed to set pixel format: %d\n", __func__, ret);
return ret;
}
ret = mipi_dsi_dcs_set_tear_scanline(dsi, 0x00);
if (ret) {
log_debug("%s: failed to set tear scanline: %d\n", __func__, ret);
return ret;
}
dsi_generic_write_seq(dsi, 0x71, 0x00); /* Ex_Vsync_en */
dsi_generic_write_seq(dsi, 0xb2, 0x00); /* VCSEL */
dsi_generic_write_seq(dsi, 0xb4, 0xaa); /* setvgmpm */
dsi_generic_write_seq(dsi, 0xb5, 0x33); /* rbias1 */
dsi_generic_write_seq(dsi, 0xb6, 0x03); /* rbias2 */
dsi_generic_write_seq(dsi, 0xb7, 0x1a, 0x33, 0x03, 0x03,
0x03, 0x00, 0x00, 0x01, 0x02, 0x00,
0x00, 0x04, 0x00, 0x01, 0x01, 0x01); /* set_ddvdhp */
dsi_generic_write_seq(dsi, 0xb8, 0x1c, 0x53, 0x03, 0x03,
0x00, 0x01, 0x02, 0x00, 0x00, 0x04,
0x00, 0x01, 0x01); /* set_ddvdhm */
dsi_generic_write_seq(dsi, 0xb9, 0x0a, 0x01, 0x01, 0x00,
0x00, 0x00, 0x02, 0x00, 0x02, 0x01); /* set_vgh */
dsi_generic_write_seq(dsi, 0xba, 0x0f, 0x01, 0x01, 0x00,
0x00, 0x00, 0x02, 0x00, 0x02, 0x01); /* set_vgl */
dsi_generic_write_seq(dsi, 0xbb, 0x00, 0x00, 0x00, 0x00,
0x01, 0x02, 0x01); /* set_vcl */
dsi_generic_write_seq(dsi, 0xc1, 0x01); /* number of lines */
dsi_generic_write_seq(dsi, 0xc2, 0x08); /* number of fp lines */
dsi_generic_write_seq(dsi, 0xc3, 0x04); /* gateset(1) */
dsi_generic_write_seq(dsi, 0xc4, 0x4c); /* 1h period */
dsi_generic_write_seq(dsi, 0xc5, 0x03); /* source precharge */
dsi_generic_write_seq(dsi, 0xc6, 0xc4, 0x04); /* source precharge timing */
dsi_generic_write_seq(dsi, 0xc7, 0x00); /* source level */
dsi_generic_write_seq(dsi, 0xc8, 0x02); /* number of bp lines */
dsi_generic_write_seq(dsi, 0xc9, 0x10); /* gateset(2) */
dsi_generic_write_seq(dsi, 0xca, 0x04, 0x04); /* gateset(3) */
dsi_generic_write_seq(dsi, 0xcb, 0x03); /* gateset(4) */
dsi_generic_write_seq(dsi, 0xcc, 0x12); /* gateset(5) */
dsi_generic_write_seq(dsi, 0xcd, 0x12); /* gateset(6) */
dsi_generic_write_seq(dsi, 0xce, 0x30); /* gateset(7) */
dsi_generic_write_seq(dsi, 0xcf, 0x30); /* gateset(8) */
dsi_generic_write_seq(dsi, 0xd0, 0x40); /* gateset(9) */
dsi_generic_write_seq(dsi, 0xd1, 0x22); /* flhw */
dsi_generic_write_seq(dsi, 0xd2, 0x22); /* vckhw */
dsi_generic_write_seq(dsi, 0xd3, 0x04); /* flt */
dsi_generic_write_seq(dsi, 0xd4, 0x14); /* tctrl */
dsi_generic_write_seq(dsi, 0xd6, 0x02); /* dotinv */
dsi_generic_write_seq(dsi, 0xd7, 0x00); /* on/off sequence period */
dsi_generic_write_seq(dsi, 0xd8, 0x01, 0x05, 0x06, 0x0d,
0x18, 0x09, 0x22, 0x23, 0x00); /* ponseqa */
dsi_generic_write_seq(dsi, 0xd9, 0x24, 0x01); /* ponseqb */
dsi_generic_write_seq(dsi, 0xde, 0x09, 0x0f, 0x21, 0x12,
0x04); /* ponseqc */
dsi_generic_write_seq(dsi, 0xdf, 0x02, 0x06, 0x06, 0x06,
0x06, 0x00); /* pofseqa */
dsi_generic_write_seq(dsi, 0xe0, 0x01); /* pofseqb */
ret = mipi_dsi_dcs_set_display_brightness(dsi, 0xff);
if (ret) {
log_debug("%s: failed to set display brightness: %d\n", __func__, ret);
return ret;
}
dsi_generic_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x40);
dsi_generic_write_seq(dsi, 0xe2, 0x00, 0x00); /* cabc pwm */
dsi_generic_write_seq(dsi, 0xe3, 0x03); /* cabc */
dsi_generic_write_seq(dsi, 0xe4, 0x66, 0x7b, 0x90, 0xa5,
0xbb, 0xc7, 0xe1, 0xe5); /* cabc brightness */
dsi_generic_write_seq(dsi, 0xe5, 0xc5, 0xc5, 0xc9, 0xc9,
0xd1, 0xe1, 0xf1, 0xfe); /* cabc brightness */
dsi_generic_write_seq(dsi, 0xe7, 0x2a); /* cabc */
dsi_generic_write_seq(dsi, 0xe8, 0x00); /* brt_rev */
dsi_generic_write_seq(dsi, 0xe9, 0x00); /* tefreq */
dsi_generic_write_seq(dsi, 0xea, 0x01); /* high speed ram */
dsi_generic_write_seq(dsi, 0xeb, 0x00, 0x33, 0x0e, 0x15,
0xb7, 0x78, 0x88, 0x0f); /* gamma setting r pos */
dsi_generic_write_seq(dsi, 0xec, 0x00, 0x33, 0x0e, 0x15,
0xb7, 0x78, 0x88, 0x0f); /* gamma setting r neg */
dsi_generic_write_seq(dsi, 0xed, 0x00, 0x33, 0x0e, 0x15,
0xb7, 0x78, 0x88, 0x0f); /* gamma setting g pos */
dsi_generic_write_seq(dsi, 0xee, 0x00, 0x33, 0x0e, 0x15,
0xb7, 0x78, 0x88, 0x0f); /* gamma setting g neg */
dsi_generic_write_seq(dsi, 0xef, 0x00, 0x33, 0x0e, 0x15,
0xb7, 0x78, 0x88, 0x0f); /* gamma setting b pos */
dsi_generic_write_seq(dsi, 0xf0, 0x00, 0x33, 0x0e, 0x15,
0xb7, 0x78, 0x88, 0x0f); /* gamma setting b neg */
ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
if (ret) {
log_debug("%s: failed to exit sleep mode: %d\n", __func__, ret);
return ret;
}
mdelay(110);
ret = mipi_dsi_dcs_set_display_on(dsi);
if (ret) {
log_debug("%s: failed to set display on: %d\n", __func__, ret);
return ret;
}
return 0;
}
static int hitachi_tx10d07vm0baa_set_backlight(struct udevice *dev, int percent)
{
struct hitachi_tx10d07vm0baa_priv *priv = dev_get_priv(dev);
int ret;
ret = backlight_enable(priv->backlight);
if (ret)
return ret;
return backlight_set_brightness(priv->backlight, percent);
}
static int hitachi_tx10d07vm0baa_timings(struct udevice *dev,
struct display_timing *timing)
{
memcpy(timing, &default_timing, sizeof(*timing));
return 0;
}
static int hitachi_tx10d07vm0baa_of_to_plat(struct udevice *dev)
{
struct hitachi_tx10d07vm0baa_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 = device_get_supply_regulator(dev, "avci-supply", &priv->avci);
if (ret) {
log_debug("%s: cannot get avci-supply: ret = %d\n",
__func__, ret);
return ret;
}
ret = device_get_supply_regulator(dev, "iovcc-supply", &priv->iovcc);
if (ret) {
log_debug("%s: cannot get iovcc-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 hitachi_tx10d07vm0baa_hw_init(struct udevice *dev)
{
struct hitachi_tx10d07vm0baa_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->iovcc, 1);
if (ret) {
log_debug("%s: enabling iovcc-supply failed (%d)\n",
__func__, ret);
return ret;
}
ret = regulator_set_enable_if_allowed(priv->avci, 1);
if (ret) {
log_debug("%s: enabling avci-supply failed (%d)\n",
__func__, ret);
return ret;
}
mdelay(25);
ret = dm_gpio_set_value(&priv->reset_gpio, 0);
if (ret) {
log_debug("%s: error exiting reset (%d)\n", __func__, ret);
return ret;
}
mdelay(5);
return 0;
}
static int hitachi_tx10d07vm0baa_probe(struct udevice *dev)
{
struct mipi_dsi_panel_plat *plat = dev_get_plat(dev);
/* fill characteristics of DSI data link */
plat->lanes = 2;
plat->format = MIPI_DSI_FMT_RGB888;
plat->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM;
return hitachi_tx10d07vm0baa_hw_init(dev);
}
static const struct panel_ops hitachi_tx10d07vm0baa_ops = {
.enable_backlight = hitachi_tx10d07vm0baa_enable_backlight,
.set_backlight = hitachi_tx10d07vm0baa_set_backlight,
.get_display_timing = hitachi_tx10d07vm0baa_timings,
};
static const struct udevice_id hitachi_tx10d07vm0baa_ids[] = {
{ .compatible = "hit,tx10d07vm0baa" },
{ }
};
U_BOOT_DRIVER(hitachi_tx10d07vm0baa) = {
.name = "hitachi_tx10d07vm0baa",
.id = UCLASS_PANEL,
.of_match = hitachi_tx10d07vm0baa_ids,
.ops = &hitachi_tx10d07vm0baa_ops,
.of_to_plat = hitachi_tx10d07vm0baa_of_to_plat,
.probe = hitachi_tx10d07vm0baa_probe,
.plat_auto = sizeof(struct mipi_dsi_panel_plat),
.priv_auto = sizeof(struct hitachi_tx10d07vm0baa_priv),
};

View File

@ -0,0 +1,230 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* LG LH400WV3-SD04 DSI panel driver
*
* Copyright (c) 2025 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <backlight.h>
#include <dm.h>
#include <panel.h>
#include <log.h>
#include <mipi_dsi.h>
#include <linux/delay.h>
#include <power/regulator.h>
#include <asm/gpio.h>
struct lg_lh400wv3_priv {
struct udevice *avci;
struct udevice *iovcc;
struct udevice *backlight;
struct gpio_desc reset_gpio;
};
static struct display_timing default_timing = {
.pixelclock.typ = 29816000,
.hactive.typ = 480,
.hfront_porch.typ = 10,
.hback_porch.typ = 10,
.hsync_len.typ = 10,
.vactive.typ = 800,
.vfront_porch.typ = 4,
.vback_porch.typ = 4,
.vsync_len.typ = 4,
};
#define dsi_generic_write_seq(dsi, cmd, seq...) do { \
static const u8 b[] = { cmd, seq }; \
int ret; \
ret = mipi_dsi_dcs_write_buffer(dsi, b, ARRAY_SIZE(b)); \
if (ret < 0) \
return ret; \
} while (0)
static int lg_lh400wv3_enable_backlight(struct udevice *dev)
{
struct mipi_dsi_panel_plat *plat = dev_get_plat(dev);
struct mipi_dsi_device *dsi = plat->device;
int ret;
dsi_generic_write_seq(dsi, MIPI_DCS_EXIT_INVERT_MODE);
dsi_generic_write_seq(dsi, MIPI_DCS_SET_TEAR_ON);
ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT |
MIPI_DCS_PIXEL_FMT_24BIT << 4);
if (ret < 0) {
log_debug("%s: failed to set pixel format: %d\n", __func__, ret);
return ret;
}
dsi_generic_write_seq(dsi, 0xb2, 0x00, 0xc8);
dsi_generic_write_seq(dsi, 0xb3, 0x00);
dsi_generic_write_seq(dsi, 0xb4, 0x04);
dsi_generic_write_seq(dsi, 0xb5, 0x42, 0x10, 0x10, 0x00, 0x20);
dsi_generic_write_seq(dsi, 0xb6, 0x0b, 0x0f, 0x3c, 0x13, 0x13, 0xe8);
dsi_generic_write_seq(dsi, 0xb7, 0x4c, 0x06, 0x0c, 0x00, 0x00);
dsi_generic_write_seq(dsi, 0xc0, 0x01, 0x11);
dsi_generic_write_seq(dsi, 0xc3, 0x07, 0x03, 0x04, 0x04, 0x04);
dsi_generic_write_seq(dsi, 0xc4, 0x12, 0x24, 0x18, 0x18, 0x02, 0x49);
dsi_generic_write_seq(dsi, 0xc5, 0x65);
dsi_generic_write_seq(dsi, 0xc6, 0x41, 0x63);
dsi_generic_write_seq(dsi, 0xd0, 0x00, 0x46, 0x74, 0x32, 0x1d, 0x03, 0x51, 0x15, 0x04);
dsi_generic_write_seq(dsi, 0xd1, 0x00, 0x46, 0x74, 0x32, 0x1d, 0x03, 0x51, 0x15, 0x04);
dsi_generic_write_seq(dsi, 0xd2, 0x00, 0x46, 0x74, 0x32, 0x1f, 0x03, 0x51, 0x15, 0x04);
dsi_generic_write_seq(dsi, 0xd3, 0x00, 0x46, 0x74, 0x32, 0x1f, 0x03, 0x51, 0x15, 0x04);
dsi_generic_write_seq(dsi, 0xd4, 0x01, 0x46, 0x74, 0x25, 0x00, 0x03, 0x51, 0x15, 0x04);
dsi_generic_write_seq(dsi, 0xd5, 0x01, 0x46, 0x74, 0x25, 0x00, 0x03, 0x51, 0x15, 0x04);
dsi_generic_write_seq(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, 0x00, 0x00, 0x01, 0xdf);
dsi_generic_write_seq(dsi, MIPI_DCS_SET_PAGE_ADDRESS, 0x00, 0x00, 0x03, 0x1f);
ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
if (ret < 0) {
log_debug("%s: failed to exit sleep mode: %d\n", __func__, ret);
return ret;
}
mdelay(120);
dsi_generic_write_seq(dsi, MIPI_DCS_WRITE_MEMORY_START);
ret = mipi_dsi_dcs_set_display_on(dsi);
if (ret < 0) {
log_debug("%s: failed to set display on: %d\n", __func__, ret);
return ret;
}
return 0;
}
static int lg_lh400wv3_set_backlight(struct udevice *dev, int percent)
{
struct lg_lh400wv3_priv *priv = dev_get_priv(dev);
int ret;
ret = backlight_enable(priv->backlight);
if (ret)
return ret;
return backlight_set_brightness(priv->backlight, percent);
}
static int lg_lh400wv3_timings(struct udevice *dev, struct display_timing *timing)
{
memcpy(timing, &default_timing, sizeof(*timing));
return 0;
}
static int lg_lh400wv3_of_to_plat(struct udevice *dev)
{
struct lg_lh400wv3_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 = device_get_supply_regulator(dev, "avci-supply", &priv->avci);
if (ret) {
log_debug("%s: cannot get avci-supply: ret = %d\n",
__func__, ret);
return ret;
}
ret = device_get_supply_regulator(dev, "iovcc-supply", &priv->iovcc);
if (ret) {
log_debug("%s: cannot get iovcc-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 lg_lh400wv3_hw_init(struct udevice *dev)
{
struct lg_lh400wv3_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->iovcc, 1);
if (ret) {
log_debug("%s: enabling iovcc-supply failed (%d)\n",
__func__, ret);
return ret;
}
ret = regulator_set_enable_if_allowed(priv->avci, 1);
if (ret) {
log_debug("%s: enabling avci-supply failed (%d)\n",
__func__, ret);
return ret;
}
mdelay(1);
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 lg_lh400wv3_probe(struct udevice *dev)
{
struct mipi_dsi_panel_plat *plat = dev_get_plat(dev);
/* fill characteristics of DSI data link */
plat->lanes = 2;
plat->format = MIPI_DSI_FMT_RGB888;
plat->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM;
return lg_lh400wv3_hw_init(dev);
}
static const struct panel_ops lg_lh400wv3_ops = {
.enable_backlight = lg_lh400wv3_enable_backlight,
.set_backlight = lg_lh400wv3_set_backlight,
.get_display_timing = lg_lh400wv3_timings,
};
static const struct udevice_id lg_lh400wv3_ids[] = {
{ .compatible = "lg,lh400wv3-sd04" },
{ }
};
U_BOOT_DRIVER(lg_lh400wv3) = {
.name = "lg_lh400wv3",
.id = UCLASS_PANEL,
.of_match = lg_lh400wv3_ids,
.ops = &lg_lh400wv3_ops,
.of_to_plat = lg_lh400wv3_of_to_plat,
.probe = lg_lh400wv3_probe,
.plat_auto = sizeof(struct mipi_dsi_panel_plat),
.priv_auto = sizeof(struct lg_lh400wv3_priv),
};

View File

@ -42,6 +42,16 @@ config TEGRA_BACKLIGHT_PWM
Enable support for the Display Controller dependent PWM backlight
found in the Tegra SoC and usually used with DSI panels.
config TEGRA_8BIT_CPU_BRIDGE
bool "Enable 8 bit panel communication protocol for Tegra 20/30"
depends on VIDEO_BRIDGE && DM_GPIO
select VIDEO_TEGRA
select VIDEO_MIPI_DSI
help
Tegra 20 and Tegra 30 feature 8 bit CPU driver panel control
protocol. This option allows use it as a MIPI DSI bridge to
set up and control compatible panel.
config VIDEO_TEGRA124
bool "Enable video support on Tegra124"
imply VIDEO_DAMAGE

View File

@ -5,5 +5,6 @@ obj-$(CONFIG_VIDEO_TEGRA) += dc.o
obj-$(CONFIG_VIDEO_DSI_TEGRA) += dsi.o mipi.o mipi-phy.o
obj-$(CONFIG_VIDEO_HDMI_TEGRA) += hdmi.o
obj-$(CONFIG_TEGRA_BACKLIGHT_PWM) += dc-pwm-backlight.o
obj-$(CONFIG_TEGRA_8BIT_CPU_BRIDGE) += cpu-bridge.o
obj-${CONFIG_VIDEO_TEGRA124} += tegra124/

View File

@ -0,0 +1,325 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2024 Svyatoslav Ryhel <clamor95@gmail.com>
*
* This driver uses 8-bit CPU interface found in Tegra 2
* and Tegra 3 to drive MIPI DSI panel.
*/
#include <dm.h>
#include <dm/ofnode_graph.h>
#include <log.h>
#include <mipi_display.h>
#include <mipi_dsi.h>
#include <backlight.h>
#include <panel.h>
#include <video_bridge.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include "dc.h"
struct tegra_cpu_bridge_priv {
struct dc_ctlr *dc;
struct mipi_dsi_host host;
struct mipi_dsi_device device;
struct udevice *panel;
struct display_timing timing;
struct gpio_desc dc_gpio;
struct gpio_desc rw_gpio;
struct gpio_desc cs_gpio;
struct gpio_desc data_gpios[8];
u32 pixel_format;
u32 spi_init_seq[4];
};
#define TEGRA_CPU_BRIDGE_COMM 0
#define TEGRA_CPU_BRIDGE_DATA 1
static void tegra_cpu_bridge_write(struct tegra_cpu_bridge_priv *priv,
u8 type, u8 value)
{
int i;
dm_gpio_set_value(&priv->dc_gpio, type);
dm_gpio_set_value(&priv->cs_gpio, 0);
dm_gpio_set_value(&priv->rw_gpio, 0);
for (i = 0; i < 8; i++)
dm_gpio_set_value(&priv->data_gpios[i],
(value >> i) & 0x1);
dm_gpio_set_value(&priv->cs_gpio, 1);
dm_gpio_set_value(&priv->rw_gpio, 1);
udelay(10);
log_debug("%s: type 0x%x, val 0x%x\n",
__func__, type, value);
}
static ssize_t tegra_cpu_bridge_transfer(struct mipi_dsi_host *host,
const struct mipi_dsi_msg *msg)
{
struct udevice *dev = (struct udevice *)host->dev;
struct tegra_cpu_bridge_priv *priv = dev_get_priv(dev);
u8 command = *(u8 *)msg->tx_buf;
const u8 *data = msg->tx_buf;
int i;
tegra_cpu_bridge_write(priv, TEGRA_CPU_BRIDGE_COMM, command);
for (i = 1; i < msg->tx_len; i++)
tegra_cpu_bridge_write(priv, TEGRA_CPU_BRIDGE_DATA, data[i]);
return 0;
}
static const struct mipi_dsi_host_ops tegra_cpu_bridge_host_ops = {
.transfer = tegra_cpu_bridge_transfer,
};
static int tegra_cpu_bridge_get_format(enum mipi_dsi_pixel_format format, u32 *fmt)
{
switch (format) {
case MIPI_DSI_FMT_RGB888:
case MIPI_DSI_FMT_RGB666_PACKED:
*fmt = BASE_COLOR_SIZE_888;
break;
case MIPI_DSI_FMT_RGB666:
*fmt = BASE_COLOR_SIZE_666;
break;
case MIPI_DSI_FMT_RGB565:
*fmt = BASE_COLOR_SIZE_565;
break;
default:
return -EINVAL;
}
return 0;
}
static int tegra_cpu_bridge_attach(struct udevice *dev)
{
struct tegra_cpu_bridge_priv *priv = dev_get_priv(dev);
struct dc_disp_reg *disp = &priv->dc->disp;
struct dc_cmd_reg *cmd = &priv->dc->cmd;
struct dc_com_reg *com = &priv->dc->com;
u32 value;
int ret;
writel(CTRL_MODE_STOP << CTRL_MODE_SHIFT, &cmd->disp_cmd);
writel(0, &disp->disp_win_opt);
writel(GENERAL_UPDATE, &cmd->state_ctrl);
writel(GENERAL_ACT_REQ, &cmd->state_ctrl);
/* TODO: parametrize if needed */
writel(V_PULSE1_ENABLE, &disp->disp_signal_opt0);
writel(PULSE_POLARITY_LOW, &disp->v_pulse1.v_pulse_ctrl);
writel(PULSE_END(1), &disp->v_pulse1.v_pulse_pos[V_PULSE0_POSITION_A]);
writel(0, &disp->v_pulse1.v_pulse_pos[V_PULSE0_POSITION_B]);
writel(0, &disp->v_pulse1.v_pulse_pos[V_PULSE0_POSITION_C]);
ret = dev_read_u32_array(dev, "nvidia,init-sequence", priv->spi_init_seq, 4);
if (!ret) {
value = 1 << FRAME_INIT_SEQ_CYCLES_SHIFT |
DC_SIGNAL_VPULSE1 << INIT_SEQ_DC_SIGNAL_SHIFT |
INIT_SEQUENCE_MODE_PLCD | SEND_INIT_SEQUENCE;
writel(value, &disp->seq_ctrl);
writel(priv->spi_init_seq[0], &disp->spi_init_seq_data_a);
writel(priv->spi_init_seq[1], &disp->spi_init_seq_data_b);
writel(priv->spi_init_seq[2], &disp->spi_init_seq_data_c);
writel(priv->spi_init_seq[3], &disp->spi_init_seq_data_d);
}
value = readl(&cmd->disp_cmd);
value &= ~CTRL_MODE_MASK;
value |= CTRL_MODE_C_DISPLAY << CTRL_MODE_SHIFT;
writel(value, &cmd->disp_cmd);
/* set LDC pin to V Pulse 1 */
value = readl(&com->pin_output_sel[6]) | LDC_OUTPUT_SELECT_V_PULSE1;
writel(value, &com->pin_output_sel[6]);
value = readl(&disp->disp_interface_ctrl);
value |= DATA_ALIGNMENT_LSB << DATA_ALIGNMENT_SHIFT;
writel(value, &disp->disp_interface_ctrl);
value = SC_H_QUALIFIER_NONE << SC1_H_QUALIFIER_SHIFT |
SC_V_QUALIFIER_VACTIVE << SC0_V_QUALIFIER_SHIFT |
SC_H_QUALIFIER_HACTIVE << SC0_H_QUALIFIER_SHIFT;
writel(value, &disp->shift_clk_opt);
value = readl(&disp->disp_color_ctrl);
value |= priv->pixel_format;
writel(value, &disp->disp_color_ctrl);
/* Perform panel setup */
panel_enable_backlight(priv->panel);
dm_gpio_set_value(&priv->cs_gpio, 0);
dm_gpio_free(dev, &priv->dc_gpio);
dm_gpio_free(dev, &priv->rw_gpio);
dm_gpio_free(dev, &priv->cs_gpio);
gpio_free_list(dev, priv->data_gpios, 8);
return 0;
}
static int tegra_cpu_bridge_set_panel(struct udevice *dev, int percent)
{
struct tegra_cpu_bridge_priv *priv = dev_get_priv(dev);
return panel_set_backlight(priv->panel, percent);
}
static int tegra_cpu_bridge_panel_timings(struct udevice *dev,
struct display_timing *timing)
{
struct tegra_cpu_bridge_priv *priv = dev_get_priv(dev);
memcpy(timing, &priv->timing, sizeof(*timing));
return 0;
}
static int tegra_cpu_bridge_hw_init(struct udevice *dev)
{
struct tegra_cpu_bridge_priv *priv = dev_get_priv(dev);
dm_gpio_set_value(&priv->cs_gpio, 1);
dm_gpio_set_value(&priv->rw_gpio, 1);
dm_gpio_set_value(&priv->dc_gpio, 0);
return 0;
}
static int tegra_cpu_bridge_get_links(struct udevice *dev)
{
struct tegra_cpu_bridge_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);
/* Look for DC source */
if (ofnode_name_eq(remote, "rgb")) {
ofnode dc = ofnode_get_parent(remote);
priv->dc = (struct dc_ctlr *)ofnode_get_addr(dc);
if (!priv->dc) {
log_err("%s: failed to get DC controller\n", __func__);
return -EINVAL;
}
}
/* Look for driven panel */
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 tegra_cpu_bridge_probe(struct udevice *dev)
{
struct tegra_cpu_bridge_priv *priv = dev_get_priv(dev);
struct mipi_dsi_device *device = &priv->device;
struct mipi_dsi_panel_plat *mipi_plat;
int ret;
ret = tegra_cpu_bridge_get_links(dev);
if (ret) {
log_debug("%s: links not found, ret %d\n", __func__, ret);
return ret;
}
panel_get_display_timing(priv->panel, &priv->timing);
mipi_plat = dev_get_plat(priv->panel);
mipi_plat->device = device;
priv->host.dev = (struct device *)dev;
priv->host.ops = &tegra_cpu_bridge_host_ops;
device->host = &priv->host;
device->lanes = mipi_plat->lanes;
device->format = mipi_plat->format;
device->mode_flags = mipi_plat->mode_flags;
tegra_cpu_bridge_get_format(device->format, &priv->pixel_format);
/* get control gpios */
ret = gpio_request_by_name(dev, "dc-gpios", 0,
&priv->dc_gpio, GPIOD_IS_OUT);
if (ret) {
log_debug("%s: could not decode dc-gpios (%d)\n", __func__, ret);
return ret;
}
ret = gpio_request_by_name(dev, "rw-gpios", 0,
&priv->rw_gpio, GPIOD_IS_OUT);
if (ret) {
log_debug("%s: could not decode rw-gpios (%d)\n", __func__, ret);
return ret;
}
ret = gpio_request_by_name(dev, "cs-gpios", 0,
&priv->cs_gpio, GPIOD_IS_OUT);
if (ret) {
log_debug("%s: could not decode cs-gpios (%d)\n", __func__, ret);
return ret;
}
/* get data gpios */
ret = gpio_request_list_by_name(dev, "data-gpios",
priv->data_gpios, 8,
GPIOD_IS_OUT);
if (ret < 0) {
log_debug("%s: could not decode data-gpios (%d)\n", __func__, ret);
return ret;
}
return tegra_cpu_bridge_hw_init(dev);
}
static const struct video_bridge_ops tegra_cpu_bridge_ops = {
.attach = tegra_cpu_bridge_attach,
.set_backlight = tegra_cpu_bridge_set_panel,
.get_display_timing = tegra_cpu_bridge_panel_timings,
};
static const struct udevice_id tegra_cpu_bridge_ids[] = {
{ .compatible = "nvidia,tegra-8bit-cpu" },
{ }
};
U_BOOT_DRIVER(tegra_8bit_cpu) = {
.name = "tegra_8bit_cpu",
.id = UCLASS_VIDEO_BRIDGE,
.of_match = tegra_cpu_bridge_ids,
.ops = &tegra_cpu_bridge_ops,
.bind = dm_scan_fdt_dev,
.probe = tegra_cpu_bridge_probe,
.priv_auto = sizeof(struct tegra_cpu_bridge_priv),
};

View File

@ -1,19 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
*
* Copyright (c) 2024, Svyatoslav Ryhel <clamor95@gmail.com>
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#include "tegra124-common.h"
#ifdef CONFIG_TEGRA_SUPPORT_NON_SECURE
#define CFG_PRAM 0x38400 /* 225 MB */
#endif
#include "tegra-common-post.h"
#endif /* __CONFIG_H */

View File

@ -29,6 +29,10 @@
#include "tegra210-common.h"
#endif
#ifdef CONFIG_TEGRA_PRAM
#define CFG_PRAM CONFIG_TEGRA_PRAM_SIZE
#endif
#include "tegra-common-post.h"
#endif /* __CONFIG_H */

View File

@ -1,19 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
*
* Copyright (c) 2023, Svyatoslav Ryhel <clamor95@gmail.com>
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#include "tegra114-common.h"
#ifdef CONFIG_TEGRA_SUPPORT_NON_SECURE
#define CFG_PRAM 0x21c00 /* 135 MB */
#endif
#include "tegra-common-post.h"
#endif /* __CONFIG_H */

View File

@ -1,19 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved.
*
* Copyright (c) 2023, Svyatoslav Ryhel <clamor95@gmail.com>
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#include "tegra114-common.h"
#ifdef CONFIG_TEGRA_SUPPORT_NON_SECURE
#define CFG_PRAM 0x20000 /* 128 MB */
#endif
#include "tegra-common-post.h"
#endif /* __CONFIG_H */

77
include/power/max8907.h Normal file
View File

@ -0,0 +1,77 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright(C) 2024 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#ifndef _MAX8907_H_
#define _MAX8907_H_
#define MAX8907_LDO_NUM 20
#define MAX8907_SD_NUM 3
/* Drivers name */
#define MAX8907_LDO_DRIVER "max8907_ldo"
#define MAX8907_SD_DRIVER "max8907_sd"
#define MAX8907_RST_DRIVER "max8907_rst"
/* MAX8907 register map */
#define MAX8907_REG_SDCTL1 0x04
#define MAX8907_REG_SDCTL2 0x07
#define MAX8907_REG_SDCTL3 0x0A
#define MAX8907_REG_LDOCTL16 0x10
#define MAX8907_REG_LDOCTL17 0x14
#define MAX8907_REG_LDOCTL1 0x18
#define MAX8907_REG_LDOCTL2 0x1C
#define MAX8907_REG_LDOCTL3 0x20
#define MAX8907_REG_LDOCTL4 0x24
#define MAX8907_REG_LDOCTL5 0x28
#define MAX8907_REG_LDOCTL6 0x2C
#define MAX8907_REG_LDOCTL7 0x30
#define MAX8907_REG_LDOCTL8 0x34
#define MAX8907_REG_LDOCTL9 0x38
#define MAX8907_REG_LDOCTL10 0x3C
#define MAX8907_REG_LDOCTL11 0x40
#define MAX8907_REG_LDOCTL12 0x44
#define MAX8907_REG_LDOCTL13 0x48
#define MAX8907_REG_LDOCTL14 0x4C
#define MAX8907_REG_LDOCTL15 0x50
#define MAX8907_REG_LDOCTL19 0x5C
#define MAX8907_REG_LDOCTL18 0x72
#define MAX8907_REG_LDOCTL20 0x9C
#define MAX8907_REG_RESET_CNFG 0x0F
#define MASK_POWER_OFF BIT(6)
/* MAX8907 configuration values */
#define MAX8907_CTL 0
#define MAX8907_SEQCNT 1
#define MAX8907_VOUT 2
/* mask bit fields */
#define MAX8907_MASK_LDO_SEQ 0x1C
#define MAX8907_MASK_LDO_EN 0x01
/* Step-Down (SD) Regulator calculations */
#define SD1_VOLT_MAX 2225000
#define SD1_VOLT_MIN 650000
#define SD1_VOLT_STEP 25000
#define SD2_VOLT_MAX 1425000
#define SD2_VOLT_MIN 637500
#define SD2_VOLT_STEP 12500
#define SD3_VOLT_MAX 3900000
#define SD3_VOLT_MIN 750000
#define SD3_VOLT_STEP 50000
/* Low-Dropout Linear (LDO) Regulator calculations */
#define LDO_750_VOLT_MAX 3900000
#define LDO_750_VOLT_MIN 750000
#define LDO_750_VOLT_STEP 50000
#define LDO_650_VOLT_MAX 2225000
#define LDO_650_VOLT_MIN 650000
#define LDO_650_VOLT_STEP 25000
#endif /* _MAX8907_H_ */