- More Tegra video improvements
This commit is contained in:
Tom Rini 2025-03-26 14:07:37 -06:00
commit 4adbf64ff8
56 changed files with 4721 additions and 491 deletions

View file

@ -113,6 +113,7 @@ dtb-$(CONFIG_ARCH_TEGRA) += \
tegra30-lg-p880.dtb \ tegra30-lg-p880.dtb \
tegra30-lg-p895.dtb \ tegra30-lg-p895.dtb \
tegra30-microsoft-surface-rt.dtb \ tegra30-microsoft-surface-rt.dtb \
tegra30-ouya.dtb \
tegra30-tec-ng.dtb \ tegra30-tec-ng.dtb \
tegra30-wexler-qc750.dtb \ tegra30-wexler-qc750.dtb \
tegra114-dalmore.dtb \ tegra114-dalmore.dtb \

View file

@ -215,8 +215,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,open-drain = <1>; nvidia,open-drain = <TEGRA_PIN_DISABLE>;
}; };
gen2-i2c { gen2-i2c {
nvidia,pins = "gen2_i2c_scl_pt5", nvidia,pins = "gen2_i2c_scl_pt5",
@ -225,8 +225,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,open-drain = <1>; nvidia,open-drain = <TEGRA_PIN_DISABLE>;
}; };
cam-i2c { cam-i2c {
nvidia,pins = "cam_i2c_scl_pbb1", nvidia,pins = "cam_i2c_scl_pbb1",
@ -235,8 +235,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,open-drain = <1>; nvidia,open-drain = <TEGRA_PIN_DISABLE>;
}; };
ddc-i2c { ddc-i2c {
nvidia,pins = "ddc_scl_pv4", nvidia,pins = "ddc_scl_pv4",
@ -253,7 +253,7 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <1>; nvidia,open-drain = <TEGRA_PIN_DISABLE>;
}; };
dsi-b { dsi-b {

View file

@ -34,20 +34,10 @@
host1x@50000000 { host1x@50000000 {
dc@54200000 { dc@54200000 {
clocks = <&tegra_car TEGRA30_CLK_DISP1>, status = "disabled";
<&tegra_car TEGRA30_CLK_PLL_D_OUT0>;
rgb {
status = "okay";
nvidia,panel = <&hdmi>;
};
}; };
hdmi: hdmi@54280000 { hdmi: hdmi@54280000 {
clocks = <&tegra_car TEGRA30_CLK_HDMI>,
<&tegra_car TEGRA30_CLK_PLL_D_OUT0>;
status = "okay"; status = "okay";
hdmi-supply = <&hdmi_5v0_sys>; hdmi-supply = <&hdmi_5v0_sys>;
@ -118,8 +108,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
/* SDMMC3 pinmux */ /* SDMMC3 pinmux */
@ -203,7 +193,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
gen2_i2c { gen2_i2c {
nvidia,pins = "gen2_i2c_scl_pt5", nvidia,pins = "gen2_i2c_scl_pt5",
@ -213,7 +203,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
cam_i2c { cam_i2c {
nvidia,pins = "cam_i2c_scl_pbb1", nvidia,pins = "cam_i2c_scl_pbb1",
@ -223,7 +213,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
ddc_i2c { ddc_i2c {
nvidia,pins = "ddc_scl_pv4", nvidia,pins = "ddc_scl_pv4",
@ -232,7 +222,7 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
pwr_i2c { pwr_i2c {
nvidia,pins = "pwr_i2c_scl_pz6", nvidia,pins = "pwr_i2c_scl_pz6",
@ -242,7 +232,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
hotplug_i2c { hotplug_i2c {
nvidia,pins = "pu4"; nvidia,pins = "pu4";
@ -260,7 +250,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
hdmi_hpd { hdmi_hpd {
nvidia,pins = "hdmi_int_pn7"; nvidia,pins = "hdmi_int_pn7";
@ -632,8 +622,8 @@
nvidia,pull = <TEGRA_PIN_PULL_UP>; nvidia,pull = <TEGRA_PIN_PULL_UP>;
nvidia,tristate = <TEGRA_PIN_ENABLE>; nvidia,tristate = <TEGRA_PIN_ENABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
/* GPIO keys pinmux */ /* GPIO keys pinmux */
@ -718,8 +708,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
vi_d10_pt2 { vi_d10_pt2 {
nvidia,pins = "vi_d10_pt2", nvidia,pins = "vi_d10_pt2",
@ -838,8 +828,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_DISABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
vi_mclk_pt1 { vi_mclk_pt1 {
nvidia,pins = "vi_mclk_pt1"; nvidia,pins = "vi_mclk_pt1";

View file

@ -90,8 +90,8 @@
nvidia,pull = <TEGRA_PIN_PULL_UP>; nvidia,pull = <TEGRA_PIN_PULL_UP>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
/* SDMMC2 pinmux */ /* SDMMC2 pinmux */
@ -107,8 +107,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
/* SDMMC3 pinmux */ /* SDMMC3 pinmux */
@ -142,8 +142,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
sdmmc4_cmd { sdmmc4_cmd {
nvidia,pins = "sdmmc4_cmd_pt7", nvidia,pins = "sdmmc4_cmd_pt7",
@ -159,8 +159,8 @@
nvidia,pull = <TEGRA_PIN_PULL_UP>; nvidia,pull = <TEGRA_PIN_PULL_UP>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
sdmmc4_rst_n { sdmmc4_rst_n {
nvidia,pins = "sdmmc4_rst_n_pcc3"; nvidia,pins = "sdmmc4_rst_n_pcc3";
@ -186,7 +186,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
gen2_i2c { gen2_i2c {
nvidia,pins = "gen2_i2c_scl_pt5", nvidia,pins = "gen2_i2c_scl_pt5",
@ -196,7 +196,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
cam_i2c { cam_i2c {
nvidia,pins = "cam_i2c_scl_pbb1", nvidia,pins = "cam_i2c_scl_pbb1",
@ -206,7 +206,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
ddc_i2c { ddc_i2c {
nvidia,pins = "ddc_scl_pv4", nvidia,pins = "ddc_scl_pv4",
@ -215,7 +215,7 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
pwr_i2c { pwr_i2c {
nvidia,pins = "pwr_i2c_scl_pz6", nvidia,pins = "pwr_i2c_scl_pz6",
@ -225,7 +225,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
hotplug_i2c { hotplug_i2c {
nvidia,pins = "pu4"; nvidia,pins = "pu4";
@ -243,7 +243,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
hdmi_hpd { hdmi_hpd {
nvidia,pins = "hdmi_int_pn7"; nvidia,pins = "hdmi_int_pn7";
@ -613,8 +613,8 @@
nvidia,pull = <TEGRA_PIN_PULL_UP>; nvidia,pull = <TEGRA_PIN_PULL_UP>;
nvidia,tristate = <TEGRA_PIN_ENABLE>; nvidia,tristate = <TEGRA_PIN_ENABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
/* GPIO keys pinmux */ /* GPIO keys pinmux */
@ -701,8 +701,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
pbb0 { pbb0 {
nvidia,pins = "pbb0"; nvidia,pins = "pbb0";
@ -827,8 +827,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_DISABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
vi_mclk_pt1 { vi_mclk_pt1 {
nvidia,pins = "vi_mclk_pt1"; nvidia,pins = "vi_mclk_pt1";
@ -836,8 +836,8 @@
nvidia,pull = <TEGRA_PIN_PULL_UP>; nvidia,pull = <TEGRA_PIN_PULL_UP>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
jtag { jtag {

View file

@ -15,7 +15,14 @@
rgb { rgb {
status = "okay"; status = "okay";
nvidia,panel = <&tc358768>; /delete-property/ nvidia,panel;
port {
dpi_output: endpoint {
remote-endpoint = <&bridge_input>;
bus-width = <24>;
};
};
}; };
}; };
}; };
@ -118,19 +125,17 @@
vddio-supply = <&vdd_1v8_vio>; vddio-supply = <&vdd_1v8_vio>;
vddmipi-supply = <&vdd_1v2_mipi>; vddmipi-supply = <&vdd_1v2_mipi>;
panel = <&panel>; /*
}; * Panasonic VVX10F004B00 or HYDIS HV101WU1-1E1
}; * LCD SuperIPS+ Full HD panel.
}; */
panel@1 {
panel: panel {
compatible = "panasonic,vvx10f004b00"; compatible = "panasonic,vvx10f004b00";
reg = <1>;
power-supply = <&vdd_pnl_reg>; power-supply = <&vdd_pnl_reg>;
backlight = <&backlight>; backlight = <&backlight>;
/delete-property/ enable-gpios;
display-timings { display-timings {
timing@0 { timing@0 {
/* 1920x1200@60Hz */ /* 1920x1200@60Hz */
@ -149,7 +154,40 @@
vsync-active = <1>; vsync-active = <1>;
}; };
}; };
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>;
bus-width = <24>;
};
};
port@1 {
reg = <1>;
bridge_output: endpoint {
remote-endpoint = <&panel_input>;
};
};
};
};
};
};
/delete-node/ panel;
vdd_1v2_mipi: regulator-mipi { vdd_1v2_mipi: regulator-mipi {
compatible = "regulator-fixed"; compatible = "regulator-fixed";

View file

@ -99,8 +99,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
/* SDMMC3 pinmux */ /* SDMMC3 pinmux */
@ -189,7 +189,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
gen2_i2c { gen2_i2c {
@ -200,7 +200,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
cam_i2c { cam_i2c {
@ -211,7 +211,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
ddc_i2c { ddc_i2c {
@ -221,7 +221,7 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
pwr_i2c { pwr_i2c {
@ -232,7 +232,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
hotplug_i2c { hotplug_i2c {
@ -647,8 +647,8 @@
nvidia,pull = <TEGRA_PIN_PULL_UP>; nvidia,pull = <TEGRA_PIN_PULL_UP>;
nvidia,tristate = <TEGRA_PIN_ENABLE>; nvidia,tristate = <TEGRA_PIN_ENABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
/* GPIO keys pinmux */ /* GPIO keys pinmux */
@ -741,8 +741,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
vi_d10_pt2 { vi_d10_pt2 {
@ -879,8 +879,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_DISABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
vi_mclk_pt1 { vi_mclk_pt1 {

View file

@ -33,13 +33,11 @@
host1x@50000000 { host1x@50000000 {
dc@54200000 { dc@54200000 {
clocks = <&tegra_car TEGRA30_CLK_DISP1>, backlight: backlight {
<&tegra_car TEGRA30_CLK_PLL_D_OUT0>; compatible = "nvidia,tegra-pwm-backlight";
rgb { nvidia,pwm-source = <1>;
status = "okay"; nvidia,default-brightness = <0x8E>;
nvidia,panel = <&dsia>;
}; };
}; };
@ -1265,13 +1263,6 @@
nvidia,xcvr-lsrslew = <2>; nvidia,xcvr-lsrslew = <2>;
}; };
backlight: backlight {
compatible = "nvidia,tegra-pwm-backlight";
nvidia,pwm-source = <1>;
nvidia,default-brightness = <0x8E>;
};
/* PMIC has a built-in 32KHz oscillator which is used by PMC */ /* PMIC has a built-in 32KHz oscillator which is used by PMC */
clk32k_in: clock-32k { clk32k_in: clock-32k {
compatible = "fixed-clock"; compatible = "fixed-clock";

View file

@ -109,8 +109,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
sdmmc4-cmd { sdmmc4-cmd {
nvidia,pins = "sdmmc4_cmd_pt7", nvidia,pins = "sdmmc4_cmd_pt7",
@ -127,8 +127,8 @@
nvidia,pull = <TEGRA_PIN_PULL_UP>; nvidia,pull = <TEGRA_PIN_PULL_UP>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
cam-mclk { cam-mclk {
nvidia,pins = "cam_mclk_pcc0"; nvidia,pins = "cam_mclk_pcc0";
@ -147,7 +147,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
gen2-i2c { gen2-i2c {
nvidia,pins = "gen2_i2c_scl_pt5", nvidia,pins = "gen2_i2c_scl_pt5",
@ -157,7 +157,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
cam-i2c { cam-i2c {
nvidia,pins = "cam_i2c_scl_pbb1", nvidia,pins = "cam_i2c_scl_pbb1",
@ -167,7 +167,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
ddc-i2c { ddc-i2c {
nvidia,pins = "ddc_scl_pv4", nvidia,pins = "ddc_scl_pv4",
@ -176,7 +176,7 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
pwr-i2c { pwr-i2c {
nvidia,pins = "pwr_i2c_scl_pz6", nvidia,pins = "pwr_i2c_scl_pz6",
@ -186,7 +186,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
/* HDMI pinmux */ /* HDMI pinmux */
@ -724,8 +724,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_ENABLE>; nvidia,tristate = <TEGRA_PIN_ENABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
vi-vsync-pd6 { vi-vsync-pd6 {
nvidia,pins = "vi_vsync_pd6", nvidia,pins = "vi_vsync_pd6",
@ -736,8 +736,8 @@
nvidia,pull = <TEGRA_PIN_PULL_DOWN>; nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
nvidia,tristate = <TEGRA_PIN_ENABLE>; nvidia,tristate = <TEGRA_PIN_ENABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <2>; nvidia,io-reset = <TEGRA_PIN_ENABLE>;
}; };
vi-hsync-pd7 { vi-hsync-pd7 {
nvidia,pins = "vi_hsync_pd7", nvidia,pins = "vi_hsync_pd7",
@ -749,8 +749,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_DISABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
vi-d2-pl0 { vi-d2-pl0 {
nvidia,pins = "vi_d2_pl0", nvidia,pins = "vi_d2_pl0",
@ -760,8 +760,8 @@
nvidia,pull = <TEGRA_PIN_PULL_UP>; nvidia,pull = <TEGRA_PIN_PULL_UP>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
vi-mclk-pt1 { vi-mclk-pt1 {
nvidia,pins = "vi_mclk_pt1"; nvidia,pins = "vi_mclk_pt1";
@ -769,8 +769,8 @@
nvidia,pull = <TEGRA_PIN_PULL_DOWN>; nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
nvidia,tristate = <TEGRA_PIN_ENABLE>; nvidia,tristate = <TEGRA_PIN_ENABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <2>; nvidia,io-reset = <TEGRA_PIN_ENABLE>;
}; };
vi-d11-pt3 { vi-d11-pt3 {
nvidia,pins = "vi_d11_pt3"; nvidia,pins = "vi_d11_pt3";
@ -778,8 +778,8 @@
nvidia,pull = <TEGRA_PIN_PULL_UP>; nvidia,pull = <TEGRA_PIN_PULL_UP>;
nvidia,tristate = <TEGRA_PIN_ENABLE>; nvidia,tristate = <TEGRA_PIN_ENABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
vi-d5-pl3 { vi-d5-pl3 {
nvidia,pins = "vi_d5_pl3"; nvidia,pins = "vi_d5_pl3";
@ -787,8 +787,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
/* PORT U */ /* PORT U */

View file

@ -101,6 +101,31 @@
}; };
}; };
spi@7000dc00 {
bridge-spi@2 {
/*
* JDI 4.57" 720x1280 DX12D100VM0EAA MIPI DSI panel
*/
panel@0 {
compatible = "jdi,dx12d100vm0eaa";
reg = <0>;
reset-gpios = <&gpio TEGRA_GPIO(W, 0) GPIO_ACTIVE_LOW>;
vdd-supply = <&vcc_3v0_lcd>;
vddio-supply = <&iovcc_1v8_lcd>;
backlight = <&backlight>;
port {
panel_input: endpoint {
remote-endpoint = <&bridge_output>;
};
};
};
};
};
sdmmc3: sdhci@78000400 { sdmmc3: sdhci@78000400 {
status = "okay"; status = "okay";
bus-width = <4>; bus-width = <4>;
@ -118,13 +143,4 @@
linux,code = <KEY_UP>; linux,code = <KEY_UP>;
}; };
}; };
panel: panel {
compatible = "jdi,dx12d100vm0eaa";
enable-gpios = <&gpio TEGRA_GPIO(Y, 0) GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio TEGRA_GPIO(W, 0) GPIO_ACTIVE_HIGH>;
backlight = <&backlight>;
};
}; };

View file

@ -108,10 +108,16 @@
}; };
}; };
panel: panel { spi@7000dc00 {
compatible = "hitachi,tx13d100vm0eaa"; bridge-spi@2 {
/*
* HITACHI/KOE 5" 768x1024 TX13D100VM0EAA MIPI DSI panel
*/
panel@0 {
compatible = "koe,tx13d100vm0eaa";
reg = <0>;
reset-gpios = <&gpio TEGRA_GPIO(W, 0) GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio TEGRA_GPIO(W, 0) GPIO_ACTIVE_LOW>;
renesas,gamma = <3>; renesas,gamma = <3>;
renesas,inversion; renesas,inversion;
@ -121,23 +127,18 @@
iovcc-supply = <&iovcc_1v8_lcd>; iovcc-supply = <&iovcc_1v8_lcd>;
backlight = <&backlight>; backlight = <&backlight>;
port {
panel_input: endpoint {
remote-endpoint = <&bridge_output>;
};
};
};
};
}; };
vcc_3v0_lcd: regulator-lcd { regulator-lcd3v {
compatible = "regulator-fixed";
regulator-name = "vcc_3v0_lcd";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
gpio = <&gpio TEGRA_GPIO(BB, 0) GPIO_ACTIVE_HIGH>; gpio = <&gpio TEGRA_GPIO(BB, 0) GPIO_ACTIVE_HIGH>;
enable-active-high; enable-active-high;
}; };
iovcc_1v8_lcd: regulator-lcdvio {
compatible = "regulator-fixed";
regulator-name = "iovcc_1v8_lcd";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
gpio = <&gpio TEGRA_GPIO(Y, 0) GPIO_ACTIVE_HIGH>;
enable-active-high;
};
}; };

View file

@ -32,7 +32,12 @@
rgb { rgb {
status = "okay"; status = "okay";
nvidia,panel = <&bridge>; port {
dpi_output: endpoint {
remote-endpoint = <&bridge_input>;
bus-width = <24>;
};
};
}; };
}; };
}; };
@ -890,12 +895,22 @@
status = "okay"; status = "okay";
clock-frequency = <400000>; clock-frequency = <400000>;
backlight: lm3533@36 { backlight: led-controller@36 {
compatible = "ti,lm3533"; compatible = "ti,lm3533";
reg = <0x36>; reg = <0x36>;
enable-gpios = <&gpio TEGRA_GPIO(N, 6) GPIO_ACTIVE_HIGH>; enable-gpios = <&gpio TEGRA_GPIO(N, 6) GPIO_ACTIVE_HIGH>;
default-brightness-level = <128>;
ti,boost-ovp-microvolt = <24000000>;
ti,boost-freq-hz = <500000>;
backlight-0 {
compatible = "ti,lm3533-backlight";
ti,max-current-microamp = <23400>;
ti,linear-mapping-mode;
ti,hardware-controlled;
};
}; };
muic@44 { muic@44 {
@ -969,18 +984,46 @@
compatible = "solomon,ssd2825"; compatible = "solomon,ssd2825";
reg = <2>; reg = <2>;
#address-cells = <1>;
#size-cells = <0>;
spi-cpol; spi-cpol;
spi-cpha; spi-cpha;
spi-max-frequency = <1000000>; spi-max-frequency = <1000000>;
power-gpios = <&gpio TEGRA_GPIO(B, 1) GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio TEGRA_GPIO(O, 2) GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio TEGRA_GPIO(O, 2) GPIO_ACTIVE_HIGH>;
dvdd-supply = <&vdd_1v2_rgb>;
avdd-supply = <&vdd_1v2_rgb>;
vddio-supply = <&vdd_1v8_vio>;
solomon,hs-zero-delay-ns = <300>;
solomon,hs-prep-delay-ns = <65>;
clocks = <&ssd2825_refclk>; clocks = <&ssd2825_refclk>;
clock-names = "tx_clk";
panel = <&panel>; ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
bridge_input: endpoint {
remote-endpoint = <&dpi_output>;
bus-width = <24>;
};
};
port@1 {
reg = <1>;
bridge_output: endpoint {
remote-endpoint = <&panel_input>;
};
};
};
}; };
}; };
@ -1036,4 +1079,29 @@
linux,code = <KEY_DOWN>; linux,code = <KEY_DOWN>;
}; };
}; };
vdd_1v2_rgb: regulator-rgb1v2 {
compatible = "regulator-fixed";
regulator-name = "vdd_1v2_rgb";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
gpio = <&gpio TEGRA_GPIO(B, 1) GPIO_ACTIVE_HIGH>;
enable-active-high;
};
vcc_3v0_lcd: regulator-lcd3v {
compatible = "regulator-fixed";
regulator-name = "vcc_3v0_lcd";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
};
iovcc_1v8_lcd: regulator-lcd1v8 {
compatible = "regulator-fixed";
regulator-name = "iovcc_1v8_lcd";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
gpio = <&gpio TEGRA_GPIO(Y, 0) GPIO_ACTIVE_HIGH>;
enable-active-high;
};
}; };

View file

@ -103,8 +103,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
sdmmc4-cmd { sdmmc4-cmd {
nvidia,pins = "sdmmc4_cmd_pt7", nvidia,pins = "sdmmc4_cmd_pt7",
@ -121,8 +121,8 @@
nvidia,pull = <TEGRA_PIN_PULL_UP>; nvidia,pull = <TEGRA_PIN_PULL_UP>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
cam-mclk { cam-mclk {
nvidia,pins = "cam_mclk_pcc0"; nvidia,pins = "cam_mclk_pcc0";
@ -141,7 +141,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
gen2-i2c { gen2-i2c {
nvidia,pins = "gen2_i2c_scl_pt5", nvidia,pins = "gen2_i2c_scl_pt5",
@ -151,7 +151,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
cam-i2c { cam-i2c {
nvidia,pins = "cam_i2c_scl_pbb1", nvidia,pins = "cam_i2c_scl_pbb1",
@ -161,7 +161,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
ddc-i2c { ddc-i2c {
nvidia,pins = "ddc_scl_pv4", nvidia,pins = "ddc_scl_pv4",
@ -170,7 +170,7 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
pwr-i2c { pwr-i2c {
nvidia,pins = "pwr_i2c_scl_pz6", nvidia,pins = "pwr_i2c_scl_pz6",
@ -180,7 +180,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
/* HDMI pinmux */ /* HDMI pinmux */
@ -703,8 +703,8 @@
nvidia,pull = <TEGRA_PIN_PULL_DOWN>; nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
nvidia,tristate = <TEGRA_PIN_ENABLE>; nvidia,tristate = <TEGRA_PIN_ENABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
vi-d3-pl1 { vi-d3-pl1 {
nvidia,pins = "vi_d3_pl1"; nvidia,pins = "vi_d3_pl1";
@ -712,8 +712,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_ENABLE>; nvidia,tristate = <TEGRA_PIN_ENABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
vi-hsync-pd7 { vi-hsync-pd7 {
nvidia,pins = "vi_hsync_pd7", nvidia,pins = "vi_hsync_pd7",
@ -724,8 +724,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_DISABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
vi-mclk-pt1 { vi-mclk-pt1 {
nvidia,pins = "vi_mclk_pt1"; nvidia,pins = "vi_mclk_pt1";
@ -733,8 +733,8 @@
nvidia,pull = <TEGRA_PIN_PULL_DOWN>; nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
nvidia,tristate = <TEGRA_PIN_ENABLE>; nvidia,tristate = <TEGRA_PIN_ENABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
vi-d11-pt3 { vi-d11-pt3 {
nvidia,pins = "vi_d11_pt3"; nvidia,pins = "vi_d11_pt3";
@ -742,8 +742,8 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_DISABLE>; nvidia,enable-input = <TEGRA_PIN_DISABLE>;
nvidia,lock = <1>; nvidia,lock = <TEGRA_PIN_DISABLE>;
nvidia,io-reset = <1>; nvidia,io-reset = <TEGRA_PIN_DISABLE>;
}; };
/* PORT U */ /* PORT U */

File diff suppressed because it is too large Load diff

View file

@ -157,7 +157,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
gen2-i2c { gen2-i2c {
nvidia,pins = "gen2_i2c_scl_pt5", nvidia,pins = "gen2_i2c_scl_pt5",
@ -167,7 +167,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
cam-i2c { cam-i2c {
nvidia,pins = "cam_i2c_scl_pbb1", nvidia,pins = "cam_i2c_scl_pbb1",
@ -177,7 +177,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
ddc-i2c { ddc-i2c {
nvidia,pins = "ddc_scl_pv4", nvidia,pins = "ddc_scl_pv4",
@ -186,7 +186,7 @@
nvidia,pull = <TEGRA_PIN_PULL_NONE>; nvidia,pull = <TEGRA_PIN_PULL_NONE>;
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
pwr-i2c { pwr-i2c {
nvidia,pins = "pwr_i2c_scl_pz6", nvidia,pins = "pwr_i2c_scl_pz6",
@ -196,7 +196,7 @@
nvidia,tristate = <TEGRA_PIN_DISABLE>; nvidia,tristate = <TEGRA_PIN_DISABLE>;
nvidia,enable-input = <TEGRA_PIN_ENABLE>; nvidia,enable-input = <TEGRA_PIN_ENABLE>;
nvidia,open-drain = <TEGRA_PIN_ENABLE>; nvidia,open-drain = <TEGRA_PIN_ENABLE>;
nvidia,lock = <0>; nvidia,lock = <TEGRA_PIN_DISABLE>;
}; };
/* HDMI pinmux */ /* HDMI pinmux */

View file

@ -448,6 +448,11 @@ enum win_color_depth_id {
#define LVS_OUTPUT_POLARITY_LOW BIT(28) #define LVS_OUTPUT_POLARITY_LOW BIT(28)
#define LSC0_OUTPUT_POLARITY_LOW BIT(24) #define LSC0_OUTPUT_POLARITY_LOW BIT(24)
/* DC_DISP_DISP_SIGNAL_OPTIONS0 0x400 */
#define H_PULSE0_ENABLE BIT(8)
#define H_PULSE1_ENABLE BIT(10)
#define H_PULSE2_ENABLE BIT(12)
/* DC_DISP_DISP_WIN_OPTIONS 0x402 */ /* DC_DISP_DISP_WIN_OPTIONS 0x402 */
#define CURSOR_ENABLE BIT(16) #define CURSOR_ENABLE BIT(16)
#define SOR_ENABLE BIT(25) #define SOR_ENABLE BIT(25)
@ -504,6 +509,22 @@ enum {
DATA_ORDER_BLUE_RED, DATA_ORDER_BLUE_RED,
}; };
/* DC_DISP_DISP_COLOR_CONTROL 0x430 */
#define DITHER_CONTROL_DISABLE (0 << 8)
#define DITHER_CONTROL_ORDERED (2 << 8)
#define DITHER_CONTROL_ERRDIFF (3 << 8)
enum {
BASE_COLOR_SIZE_666,
BASE_COLOR_SIZE_111,
BASE_COLOR_SIZE_222,
BASE_COLOR_SIZE_333,
BASE_COLOR_SIZE_444,
BASE_COLOR_SIZE_555,
BASE_COLOR_SIZE_565,
BASE_COLOR_SIZE_332,
BASE_COLOR_SIZE_888,
};
/* DC_DISP_DATA_ENABLE_OPTIONS 0x432 */ /* DC_DISP_DATA_ENABLE_OPTIONS 0x432 */
#define DE_SELECT_SHIFT 0 #define DE_SELECT_SHIFT 0
#define DE_SELECT_MASK (0x3 << DE_SELECT_SHIFT) #define DE_SELECT_MASK (0x3 << DE_SELECT_SHIFT)
@ -574,4 +595,23 @@ enum {
#define DC_N_WINDOWS 5 #define DC_N_WINDOWS 5
#define DC_REG_SAVE_SPACE (DC_N_WINDOWS + 5) #define DC_REG_SAVE_SPACE (DC_N_WINDOWS + 5)
#define PULSE_MODE_NORMAL (0 << 3)
#define PULSE_MODE_ONE_CLOCK (1 << 3)
#define PULSE_POLARITY_HIGH (0 << 4)
#define PULSE_POLARITY_LOW (1 << 4)
#define PULSE_QUAL_ALWAYS (0 << 6)
#define PULSE_QUAL_VACTIVE (2 << 6)
#define PULSE_QUAL_VACTIVE1 (3 << 6)
#define PULSE_LAST_START_A (0 << 8)
#define PULSE_LAST_END_A (1 << 8)
#define PULSE_LAST_START_B (2 << 8)
#define PULSE_LAST_END_B (3 << 8)
#define PULSE_LAST_START_C (4 << 8)
#define PULSE_LAST_END_C (5 << 8)
#define PULSE_LAST_START_D (6 << 8)
#define PULSE_LAST_END_D (7 << 8)
#define PULSE_START(x) (((x) & 0xfff) << 0)
#define PULSE_END(x) (((x) & 0xfff) << 16)
#endif /* __ASM_ARCH_TEGRA_DC_H */ #endif /* __ASM_ARCH_TEGRA_DC_H */

View file

@ -34,41 +34,41 @@ enum pmux_pin_io {
#ifdef TEGRA_PMX_PINS_HAVE_LOCK #ifdef TEGRA_PMX_PINS_HAVE_LOCK
enum pmux_pin_lock { enum pmux_pin_lock {
PMUX_PIN_LOCK_DEFAULT = 0, PMUX_PIN_LOCK_DISABLE = 0,
PMUX_PIN_LOCK_DISABLE,
PMUX_PIN_LOCK_ENABLE, PMUX_PIN_LOCK_ENABLE,
PMUX_PIN_LOCK_DEFAULT,
}; };
#endif #endif
#ifdef TEGRA_PMX_PINS_HAVE_OD #ifdef TEGRA_PMX_PINS_HAVE_OD
enum pmux_pin_od { enum pmux_pin_od {
PMUX_PIN_OD_DEFAULT = 0, PMUX_PIN_OD_DISABLE = 0,
PMUX_PIN_OD_DISABLE,
PMUX_PIN_OD_ENABLE, PMUX_PIN_OD_ENABLE,
PMUX_PIN_OD_DEFAULT,
}; };
#endif #endif
#ifdef TEGRA_PMX_PINS_HAVE_IO_RESET #ifdef TEGRA_PMX_PINS_HAVE_IO_RESET
enum pmux_pin_ioreset { enum pmux_pin_ioreset {
PMUX_PIN_IO_RESET_DEFAULT = 0, PMUX_PIN_IO_RESET_DISABLE = 0,
PMUX_PIN_IO_RESET_DISABLE,
PMUX_PIN_IO_RESET_ENABLE, PMUX_PIN_IO_RESET_ENABLE,
PMUX_PIN_IO_RESET_DEFAULT,
}; };
#endif #endif
#ifdef TEGRA_PMX_PINS_HAVE_RCV_SEL #ifdef TEGRA_PMX_PINS_HAVE_RCV_SEL
enum pmux_pin_rcv_sel { enum pmux_pin_rcv_sel {
PMUX_PIN_RCV_SEL_DEFAULT = 0, PMUX_PIN_RCV_SEL_NORMAL = 0,
PMUX_PIN_RCV_SEL_NORMAL,
PMUX_PIN_RCV_SEL_HIGH, PMUX_PIN_RCV_SEL_HIGH,
PMUX_PIN_RCV_SEL_DEFAULT,
}; };
#endif #endif
#ifdef TEGRA_PMX_PINS_HAVE_E_IO_HV #ifdef TEGRA_PMX_PINS_HAVE_E_IO_HV
enum pmux_pin_e_io_hv { enum pmux_pin_e_io_hv {
PMUX_PIN_E_IO_HV_DEFAULT = 0, PMUX_PIN_E_IO_HV_NORMAL = 0,
PMUX_PIN_E_IO_HV_NORMAL,
PMUX_PIN_E_IO_HV_HIGH, PMUX_PIN_E_IO_HV_HIGH,
PMUX_PIN_E_IO_HV_DEFAULT,
}; };
#endif #endif

View file

@ -467,14 +467,14 @@ static const char * const tegra_pinctrl_to_func[] = {
[PMUX_FUNC_DAP3] = "dap3", [PMUX_FUNC_DAP3] = "dap3",
[PMUX_FUNC_DAP4] = "dap4", [PMUX_FUNC_DAP4] = "dap4",
[PMUX_FUNC_DAP5] = "dap5", [PMUX_FUNC_DAP5] = "dap5",
[PMUX_FUNC_DISPA] = "dispa", [PMUX_FUNC_DISPA] = "displaya",
[PMUX_FUNC_DISPB] = "dispb", [PMUX_FUNC_DISPB] = "displayb",
[PMUX_FUNC_EMC_TEST0_DLL] = "emc_test0_dll", [PMUX_FUNC_EMC_TEST0_DLL] = "emc_test0_dll",
[PMUX_FUNC_EMC_TEST1_DLL] = "emc_test1_dll", [PMUX_FUNC_EMC_TEST1_DLL] = "emc_test1_dll",
[PMUX_FUNC_GMI] = "gmi", [PMUX_FUNC_GMI] = "gmi",
[PMUX_FUNC_GMI_INT] = "gmi_int", [PMUX_FUNC_GMI_INT] = "gmi_int",
[PMUX_FUNC_HDMI] = "hdmi", [PMUX_FUNC_HDMI] = "hdmi",
[PMUX_FUNC_I2C] = "i2c", [PMUX_FUNC_I2C] = "i2c1",
[PMUX_FUNC_I2C2] = "i2c2", [PMUX_FUNC_I2C2] = "i2c2",
[PMUX_FUNC_I2C3] = "i2c3", [PMUX_FUNC_I2C3] = "i2c3",
[PMUX_FUNC_IDE] = "ide", [PMUX_FUNC_IDE] = "ide",

View file

@ -32,6 +32,10 @@ config TARGET_IDEAPAD_YOGA_11
bool "Lenovo Ideapad Yoga 11 board" bool "Lenovo Ideapad Yoga 11 board"
select BOARD_LATE_INIT select BOARD_LATE_INIT
config TARGET_OUYA
bool "Ouya Game Console board"
select BOARD_LATE_INIT
config TARGET_QC750 config TARGET_QC750
bool "Wexler QC750 board" bool "Wexler QC750 board"
select BOARD_LATE_INIT select BOARD_LATE_INIT
@ -64,6 +68,7 @@ source "board/toradex/colibri_t30/Kconfig"
source "board/htc/endeavoru/Kconfig" source "board/htc/endeavoru/Kconfig"
source "board/asus/grouper/Kconfig" source "board/asus/grouper/Kconfig"
source "board/lenovo/ideapad-yoga-11/Kconfig" source "board/lenovo/ideapad-yoga-11/Kconfig"
source "board/ouya/ouya/Kconfig"
source "board/wexler/qc750/Kconfig" source "board/wexler/qc750/Kconfig"
source "board/microsoft/surface-rt/Kconfig" source "board/microsoft/surface-rt/Kconfig"
source "board/avionic-design/tec-ng/Kconfig" source "board/avionic-design/tec-ng/Kconfig"

12
board/ouya/ouya/Kconfig Normal file
View file

@ -0,0 +1,12 @@
if TARGET_OUYA
config SYS_BOARD
default "ouya"
config SYS_VENDOR
default "ouya"
config SYS_CONFIG_NAME
default "ouya"
endif

View file

@ -0,0 +1,8 @@
OUYA BOARD
M: Svyatoslav Ryhel <clamor95@gmail.com>
M: Peter Geis <pgwipeout@gmail.com>
S: Maintained
F: board/ouya/ouya/
F: configs/ouya_defconfig
F: doc/board/ouya/ouya.rst
F: include/configs/ouya.h

11
board/ouya/ouya/Makefile Normal file
View file

@ -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) += ouya-spl.o
obj-y += ouya.o

View file

@ -0,0 +1,41 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* T30 Ouya SPL stage configuration
*
* (C) Copyright 2010-2013
* NVIDIA Corporation <www.nvidia.com>
*
* (C) Copyright 2025
* 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);
}

21
board/ouya/ouya/ouya.c Normal file
View file

@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2010-2013
* NVIDIA Corporation <www.nvidia.com>
*
* (C) Copyright 2025
* Svyatoslav Ryhel <clamor95@gmail.com>
*/
#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

12
board/ouya/ouya/ouya.env Normal file
View file

@ -0,0 +1,12 @@
#include <env/nvidia/prod_upd.env>
partitions=name=emmc,start=0,size=-,uuid=${uuid_gpt_rootfs}
boot_interface=usb
bootmenu_0=mount internal storage=usb start && ums 0 mmc 0; bootmenu
bootmenu_1=fastboot=echo Starting Fastboot protocol ...; fastboot usb 0; bootmenu
bootmenu_2=update bootloader=run flash_uboot
bootmenu_3=reboot RCM=enterrcm
bootmenu_4=reboot=reset
bootmenu_5=power off=poweroff
bootmenu_delay=-1

View file

@ -16,6 +16,7 @@
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/string.h> #include <linux/string.h>
#if CONFIG_IS_ENABLED(I2C_EDID_STANDARD)
#define TIMING(c, ha, hfp, hbp, hsl, va, vfp, vbp, vsl, f) \ #define TIMING(c, ha, hfp, hbp, hsl, va, vfp, vbp, vsl, f) \
.pixelclock = { (c), (c), (c) }, \ .pixelclock = { (c), (c), (c) }, \
.hactive = { (ha), (ha), (ha) }, \ .hactive = { (ha), (ha), (ha) }, \
@ -206,6 +207,7 @@ static const struct display_timing dmt_timings[] = {
{ TIMING(556188000, 4096, 8, 32, 40, 2160, 48, 8, 6, { TIMING(556188000, 4096, 8, 32, 40, 2160, 48, 8, 6,
DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) }, DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW) },
}; };
#endif
int edid_check_info(struct edid1_info *edid_info) int edid_check_info(struct edid1_info *edid_info)
{ {
@ -417,6 +419,7 @@ static bool edid_get_standard_timing(struct edid1_info *edid, int i, unsigned in
return false; return false;
} }
#if CONFIG_IS_ENABLED(I2C_EDID_STANDARD)
static bool edid_find_valid_standard_timing(struct edid1_info *buf, static bool edid_find_valid_standard_timing(struct edid1_info *buf,
struct display_timing *timing, struct display_timing *timing,
bool (*mode_valid)(void *priv, bool (*mode_valid)(void *priv,
@ -446,6 +449,7 @@ static bool edid_find_valid_standard_timing(struct edid1_info *buf,
return found; return found;
} }
#endif
int edid_get_timing_validate(u8 *buf, int buf_size, int edid_get_timing_validate(u8 *buf, int buf_size,
struct display_timing *timing, struct display_timing *timing,
@ -493,10 +497,12 @@ int edid_get_timing_validate(u8 *buf, int buf_size,
} }
} }
#if CONFIG_IS_ENABLED(I2C_EDID_STANDARD)
/* Look for timing in Standard Timings */ /* Look for timing in Standard Timings */
if (!found) if (!found)
found = edid_find_valid_standard_timing(edid, timing, mode_valid, found = edid_find_valid_standard_timing(edid, timing, mode_valid,
mode_valid_priv); mode_valid_priv);
#endif
if (!found) if (!found)
return -EINVAL; return -EINVAL;

View file

@ -80,6 +80,7 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0bb4
CONFIG_USB_GADGET_PRODUCT_NUM=0x0c02 CONFIG_USB_GADGET_PRODUCT_NUM=0x0c02
CONFIG_CI_UDC=y CONFIG_CI_UDC=y
CONFIG_VIDEO=y CONFIG_VIDEO=y
CONFIG_VIDEO_BRIDGE=y
# CONFIG_VIDEO_LOGO is not set # CONFIG_VIDEO_LOGO is not set
CONFIG_VIDEO_LCD_ENDEAVORU=y CONFIG_VIDEO_LCD_ENDEAVORU=y
CONFIG_VIDEO_DSI_TEGRA30=y CONFIG_VIDEO_DSI_TEGRA30=y

86
configs/ouya_defconfig Normal file
View file

@ -0,0 +1,86 @@
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="ouya"
CONFIG_ENV_SIZE=0x3000
CONFIG_ENV_OFFSET=0xFFFFD000
CONFIG_DEFAULT_DEVICE_TREE="tegra30-ouya"
CONFIG_SPL_STACK=0x800ffffc
CONFIG_SPL_TEXT_BASE=0x80108000
CONFIG_SYS_LOAD_ADDR=0x82000000
CONFIG_TEGRA30=y
CONFIG_TARGET_OUYA=y
CONFIG_TEGRA_ENABLE_UARTD=y
CONFIG_CMD_EBTUPDATE=y
CONFIG_BUTTON_CMD=y
CONFIG_BOOTDELAY=3
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_USE_PREBOOT=y
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_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 (Ouya) # "
# 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_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_GPIO_HOG=y
CONFIG_SYS_I2C_TEGRA=y
CONFIG_BUTTON_KEYBOARD=y
CONFIG_LED=y
CONFIG_LED_BLINK=y
CONFIG_LED_GPIO=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_I2C_EDID_STANDARD=y
CONFIG_VIDEO_BRIDGE=y
CONFIG_VIDEO_HDMI_TEGRA=y

View file

@ -90,6 +90,8 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0b05
CONFIG_USB_GADGET_PRODUCT_NUM=0x4daf CONFIG_USB_GADGET_PRODUCT_NUM=0x4daf
CONFIG_CI_UDC=y CONFIG_CI_UDC=y
CONFIG_VIDEO=y CONFIG_VIDEO=y
CONFIG_VIDEO_BRIDGE=y
# CONFIG_VIDEO_LOGO is not set # CONFIG_VIDEO_LOGO is not set
CONFIG_VIDEO_BRIDGE_TOSHIBA_TC358768=y CONFIG_VIDEO_BRIDGE_TOSHIBA_TC358768=y
CONFIG_VIDEO_TEGRA20=y CONFIG_VIDEO_TEGRA20=y
CONFIG_VIDEO_HDMI_TEGRA=y

View file

@ -83,6 +83,7 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x1004
CONFIG_USB_GADGET_PRODUCT_NUM=0x7100 CONFIG_USB_GADGET_PRODUCT_NUM=0x7100
CONFIG_CI_UDC=y CONFIG_CI_UDC=y
CONFIG_VIDEO=y CONFIG_VIDEO=y
CONFIG_VIDEO_BRIDGE=y
# CONFIG_VIDEO_LOGO is not set # CONFIG_VIDEO_LOGO is not set
CONFIG_BACKLIGHT_LM3533=y CONFIG_BACKLIGHT_LM3533=y
CONFIG_VIDEO_BRIDGE_SOLOMON_SSD2825=y CONFIG_VIDEO_BRIDGE_SOLOMON_SSD2825=y

View file

@ -43,6 +43,7 @@ Board-specific doc
microsoft/index microsoft/index
nxp/index nxp/index
openpiton/index openpiton/index
ouya/index
phytec/index phytec/index
purism/index purism/index
qualcomm/index qualcomm/index

9
doc/board/ouya/index.rst Normal file
View file

@ -0,0 +1,9 @@
.. SPDX-License-Identifier: GPL-2.0+
OUYA
====
.. toctree::
:maxdepth: 2
ouya

124
doc/board/ouya/ouya.rst Normal file
View file

@ -0,0 +1,124 @@
.. SPDX-License-Identifier: GPL-2.0+
U-Boot for the Ouya Game Console (ouya)
=======================================
``DISCLAMER!`` Moving your Ouya 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 ouya_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 ouya
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
-----------------------------
Permanent installation can be performed either by using the nv3p protocol or by
pre-loading just built U-Boot into RAM. Regardless of the method bct and bootloader
will end up in boot0 and boot1 partitions of eMMC.
Flashing with the NV3P protocol
*******************************
``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!
Nv3p is a custom Nvidia protocol used to recover bricked devices. Devices can
enter it by pre-loading vendor bootloader with the Fusée Gelée.
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
$ ./run_bootloader.sh -s T30 -t ./bct/ouya.bct -b android_bootloader.bin
$ ./utiils/nvflash_v1.13.87205 --resume --rawdevicewrite 0 1024 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, interrupt bootflow by pressing ``CTRL + C`` (USB keyboard
must be plugged in before U-Boot is preloaded, else it will not work), input
``bootmenu`` from the keyboard and hit enter. The bootmenu will appear. There, select
``fastboot`` using the up and down arrows and enter key. 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 eMMC. Additionally,
bootmenu provides entries to mount 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 USB. Enter
bootmenu, choose update bootloader option with Enter and U-Boot should update
itself. Once the process is completed, U-Boot will ask to press any button to reboot.

View file

@ -23,18 +23,18 @@ static void tegra_pinctrl_set_drive(struct udevice *config, int drvcnt)
return; return;
} }
drive_group[0].slwf = dev_read_u32_default(config, "nvidia,slew-rate-falling", 0); drive_group[0].slwf = dev_read_u32_default(config, "nvidia,slew-rate-falling", PMUX_SLWF_NONE);
drive_group[0].slwr = dev_read_u32_default(config, "nvidia,slew-rate-rising", 0); drive_group[0].slwr = dev_read_u32_default(config, "nvidia,slew-rate-rising", PMUX_SLWR_NONE);
drive_group[0].drvup = dev_read_u32_default(config, "nvidia,pull-up-strength", 0); drive_group[0].drvup = dev_read_u32_default(config, "nvidia,pull-up-strength", PMUX_DRVUP_NONE);
drive_group[0].drvdn = dev_read_u32_default(config, "nvidia,pull-down-strength", 0); drive_group[0].drvdn = dev_read_u32_default(config, "nvidia,pull-down-strength", PMUX_DRVDN_NONE);
#ifdef TEGRA_PMX_GRPS_HAVE_LPMD #ifdef TEGRA_PMX_GRPS_HAVE_LPMD
drive_group[0].lpmd = dev_read_u32_default(config, "nvidia,low-power-mode", 0); drive_group[0].lpmd = dev_read_u32_default(config, "nvidia,low-power-mode", PMUX_LPMD_NONE);
#endif #endif
#ifdef TEGRA_PMX_GRPS_HAVE_SCHMT #ifdef TEGRA_PMX_GRPS_HAVE_SCHMT
drive_group[0].schmt = dev_read_u32_default(config, "nvidia,schmitt", 0); drive_group[0].schmt = dev_read_u32_default(config, "nvidia,schmitt", PMUX_SCHMT_NONE);
#endif #endif
#ifdef TEGRA_PMX_GRPS_HAVE_HSM #ifdef TEGRA_PMX_GRPS_HAVE_HSM
drive_group[0].hsm = dev_read_u32_default(config, "nvidia,high-speed-mode", 0); drive_group[0].hsm = dev_read_u32_default(config, "nvidia,high-speed-mode", PMUX_HSM_NONE);
#endif #endif
for (i = 1; i < drvcnt; i++) for (i = 1; i < drvcnt; i++)
@ -142,31 +142,31 @@ static void tegra_pinctrl_set_pin(struct udevice *config, int pincnt)
pinmux_group[0].func = i; pinmux_group[0].func = i;
pinmux_group[0].pull = dev_read_u32_default(config, "nvidia,pull", 0); pinmux_group[0].pull = dev_read_u32_default(config, "nvidia,pull", PMUX_PULL_NORMAL);
pinmux_group[0].tristate = dev_read_u32_default(config, "nvidia,tristate", 0); pinmux_group[0].tristate = dev_read_u32_default(config, "nvidia,tristate", PMUX_TRI_TRISTATE);
#ifdef TEGRA_PMX_PINS_HAVE_E_INPUT #ifdef TEGRA_PMX_PINS_HAVE_E_INPUT
pinmux_group[0].io = dev_read_u32_default(config, "nvidia,enable-input", 0); pinmux_group[0].io = dev_read_u32_default(config, "nvidia,enable-input", PMUX_PIN_NONE);
#endif #endif
#ifdef TEGRA_PMX_PINS_HAVE_LOCK #ifdef TEGRA_PMX_PINS_HAVE_LOCK
pinmux_group[0].lock = dev_read_u32_default(config, "nvidia,lock", 0); pinmux_group[0].lock = dev_read_u32_default(config, "nvidia,lock", PMUX_PIN_LOCK_DEFAULT);
#endif #endif
#ifdef TEGRA_PMX_PINS_HAVE_OD #ifdef TEGRA_PMX_PINS_HAVE_OD
pinmux_group[0].od = dev_read_u32_default(config, "nvidia,open-drain", 0); pinmux_group[0].od = dev_read_u32_default(config, "nvidia,open-drain", PMUX_PIN_OD_DEFAULT);
#endif #endif
#ifdef TEGRA_PMX_PINS_HAVE_IO_RESET #ifdef TEGRA_PMX_PINS_HAVE_IO_RESET
pinmux_group[0].ioreset = dev_read_u32_default(config, "nvidia,io-reset", 0); pinmux_group[0].ioreset = dev_read_u32_default(config, "nvidia,io-reset", PMUX_PIN_IO_RESET_DEFAULT);
#endif #endif
#ifdef TEGRA_PMX_PINS_HAVE_RCV_SEL #ifdef TEGRA_PMX_PINS_HAVE_RCV_SEL
pinmux_group[0].rcv_sel = dev_read_u32_default(config, "nvidia,rcv-sel", 0); pinmux_group[0].rcv_sel = dev_read_u32_default(config, "nvidia,rcv-sel", PMUX_PIN_RCV_SEL_DEFAULT);
#endif #endif
#ifdef TEGRA_PMX_PINS_HAVE_E_IO_HV #ifdef TEGRA_PMX_PINS_HAVE_E_IO_HV
pinmux_group[0].e_io_hv = dev_read_u32_default(config, "nvidia,io-hv", 0); pinmux_group[0].e_io_hv = dev_read_u32_default(config, "nvidia,io-hv", PMUX_PIN_E_IO_HV_DEFAULT);
#endif #endif
#ifdef TEGRA_PMX_PINS_HAVE_SCHMT #ifdef TEGRA_PMX_PINS_HAVE_SCHMT
pinmux_group[0].schmt = dev_read_u32_default(config, "nvidia,schmitt", 0); pinmux_group[0].schmt = dev_read_u32_default(config, "nvidia,schmitt", PMUX_SCHMT_NONE);
#endif #endif
#ifdef TEGRA_PMX_PINS_HAVE_HSM #ifdef TEGRA_PMX_PINS_HAVE_HSM
pinmux_group[0].hsm = dev_read_u32_default(config, "nvidia,high-speed-mode", 0); pinmux_group[0].hsm = dev_read_u32_default(config, "nvidia,high-speed-mode", PMUX_HSM_NONE);
#endif #endif
for (i = 1; i < pincnt; i++) for (i = 1; i < pincnt; i++)

View file

@ -700,6 +700,12 @@ config I2C_EDID
help help
This enables library for accessing EDID data from an LCD panel. This enables library for accessing EDID data from an LCD panel.
config I2C_EDID_STANDARD
bool "Enable standard timings EDID library expansion"
depends on I2C_EDID
help
This enables standard timings expansion for EDID data from an LCD panel.
config DISPLAY config DISPLAY
bool "Enable Display support" bool "Enable Display support"
depends on DM depends on DM

View file

@ -9,7 +9,7 @@ config VIDEO_BRIDGE
config VIDEO_BRIDGE_PARADE_DP501 config VIDEO_BRIDGE_PARADE_DP501
bool "Support Parade DP501 DP & DVI/HDMI dual mode transmitter" bool "Support Parade DP501 DP & DVI/HDMI dual mode transmitter"
depends on PANEL && DM_GPIO depends on VIDEO_BRIDGE && PANEL && DM_GPIO
select DM_I2C select DM_I2C
help help
The Parade DP501 is a DP & DVI/HDMI dual-mode transmitter. It The Parade DP501 is a DP & DVI/HDMI dual-mode transmitter. It
@ -46,14 +46,14 @@ config VIDEO_BRIDGE_ANALOGIX_ANX6345
config VIDEO_BRIDGE_SOLOMON_SSD2825 config VIDEO_BRIDGE_SOLOMON_SSD2825
bool "Solomon SSD2825 bridge driver" bool "Solomon SSD2825 bridge driver"
depends on PANEL && DM_GPIO depends on VIDEO_BRIDGE && PANEL && DM_GPIO
select VIDEO_MIPI_DSI select VIDEO_MIPI_DSI
help help
Solomon SSD2824 SPI RGB-DSI bridge driver wrapped into panel uClass. Solomon SSD2824 SPI RGB-DSI bridge driver.
config VIDEO_BRIDGE_TOSHIBA_TC358768 config VIDEO_BRIDGE_TOSHIBA_TC358768
bool "Support Toshiba TC358768 MIPI DSI bridge" bool "Support Toshiba TC358768 MIPI DSI bridge"
depends on PANEL && DM_GPIO depends on VIDEO_BRIDGE && PANEL && DM_GPIO
select VIDEO_MIPI_DSI select VIDEO_MIPI_DSI
select DM_I2C select DM_I2C
help help

View file

@ -9,6 +9,7 @@
#include <log.h> #include <log.h>
#include <backlight.h> #include <backlight.h>
#include <panel.h> #include <panel.h>
#include <video_bridge.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
#include <power/regulator.h> #include <power/regulator.h>
@ -206,7 +207,6 @@ struct dp501_priv {
struct udevice *chip2; struct udevice *chip2;
struct udevice *vdd; struct udevice *vdd;
struct gpio_desc reset_gpio;
struct gpio_desc enable_gpio; struct gpio_desc enable_gpio;
}; };
@ -484,16 +484,19 @@ static int dp501_panel_timings(struct udevice *dev,
return 0; return 0;
} }
static void dp501_hw_init(struct dp501_priv *priv) static void dp501_hw_init(struct udevice *dev)
{ {
dm_gpio_set_value(&priv->reset_gpio, 1); struct dp501_priv *priv = dev_get_priv(dev);
struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev);
dm_gpio_set_value(&uc_priv->reset, 1);
regulator_set_enable_if_allowed(priv->vdd, 1); regulator_set_enable_if_allowed(priv->vdd, 1);
dm_gpio_set_value(&priv->enable_gpio, 1); dm_gpio_set_value(&priv->enable_gpio, 1);
udelay(100); udelay(100);
dm_gpio_set_value(&priv->reset_gpio, 0); dm_gpio_set_value(&uc_priv->reset, 0);
mdelay(80); mdelay(80);
} }
@ -521,14 +524,6 @@ static int dp501_setup(struct udevice *dev)
} }
/* get gpios */ /* get gpios */
ret = gpio_request_by_name(dev, "reset-gpios", 0,
&priv->reset_gpio, GPIOD_IS_OUT);
if (ret) {
log_debug("%s: Could not decode reset-gpios (%d)\n",
__func__, ret);
return ret;
}
ret = gpio_request_by_name(dev, "enable-gpios", 0, ret = gpio_request_by_name(dev, "enable-gpios", 0,
&priv->enable_gpio, GPIOD_IS_OUT); &priv->enable_gpio, GPIOD_IS_OUT);
if (ret) { if (ret) {
@ -544,7 +539,7 @@ static int dp501_setup(struct udevice *dev)
return ret; return ret;
} }
dp501_hw_init(priv); dp501_hw_init(dev);
/* get EDID */ /* get EDID */
return panel_get_display_timing(priv->panel, &priv->timing); return panel_get_display_timing(priv->panel, &priv->timing);
@ -558,8 +553,8 @@ static int dp501_probe(struct udevice *dev)
return dp501_setup(dev); return dp501_setup(dev);
} }
struct panel_ops dp501_ops = { static const struct video_bridge_ops dp501_ops = {
.enable_backlight = dp501_attach, .attach = dp501_attach,
.set_backlight = dp501_set_backlight, .set_backlight = dp501_set_backlight,
.get_display_timing = dp501_panel_timings, .get_display_timing = dp501_panel_timings,
}; };
@ -571,7 +566,7 @@ static const struct udevice_id dp501_ids[] = {
U_BOOT_DRIVER(dp501) = { U_BOOT_DRIVER(dp501) = {
.name = "dp501", .name = "dp501",
.id = UCLASS_PANEL, .id = UCLASS_VIDEO_BRIDGE,
.of_match = dp501_ids, .of_match = dp501_ids,
.ops = &dp501_ops, .ops = &dp501_ops,
.probe = dp501_probe, .probe = dp501_probe,

View file

@ -5,12 +5,15 @@
#include <clk.h> #include <clk.h>
#include <dm.h> #include <dm.h>
#include <dm/ofnode_graph.h>
#include <log.h> #include <log.h>
#include <misc.h> #include <misc.h>
#include <mipi_display.h> #include <mipi_display.h>
#include <mipi_dsi.h> #include <mipi_dsi.h>
#include <backlight.h> #include <backlight.h>
#include <video_bridge.h>
#include <panel.h> #include <panel.h>
#include <power/regulator.h>
#include <spi.h> #include <spi.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
@ -106,6 +109,10 @@
#define SSD2825_LP_MIN_CLK 5000 /* KHz */ #define SSD2825_LP_MIN_CLK 5000 /* KHz */
#define SSD2825_REF_MIN_CLK 2000 /* KHz */ #define SSD2825_REF_MIN_CLK 2000 /* KHz */
static const char * const ssd2825_supplies[] = {
"dvdd-supply", "avdd-supply", "vddio-supply"
};
struct ssd2825_bridge_priv { struct ssd2825_bridge_priv {
struct mipi_dsi_host host; struct mipi_dsi_host host;
struct mipi_dsi_device device; struct mipi_dsi_device device;
@ -113,12 +120,16 @@ struct ssd2825_bridge_priv {
struct udevice *panel; struct udevice *panel;
struct display_timing timing; struct display_timing timing;
struct udevice *supplies[ARRAY_SIZE(ssd2825_supplies)];
struct gpio_desc power_gpio; struct gpio_desc power_gpio;
struct gpio_desc reset_gpio;
struct clk *tx_clk; struct clk *tx_clk;
u32 pll_freq_kbps; /* PLL in kbps */ u32 pll_freq_kbps; /* PLL in kbps */
u32 hzd; /* HS Zero Delay in ns */
u32 hpd; /* HS Prepare Delay is ns */
}; };
static int ssd2825_spi_write(struct udevice *dev, int reg, static int ssd2825_spi_write(struct udevice *dev, int reg,
@ -231,7 +242,6 @@ static ssize_t ssd2825_bridge_transfer(struct mipi_dsi_host *host,
const struct mipi_dsi_msg *msg) const struct mipi_dsi_msg *msg)
{ {
struct udevice *dev = (struct udevice *)host->dev; struct udevice *dev = (struct udevice *)host->dev;
u8 buf = *(u8 *)msg->tx_buf;
u16 config; u16 config;
int ret; int ret;
@ -260,15 +270,6 @@ static ssize_t ssd2825_bridge_transfer(struct mipi_dsi_host *host,
ssd2825_write_register(dev, SSD2825_VC_CTRL_REG, 0x0000); ssd2825_write_register(dev, SSD2825_VC_CTRL_REG, 0x0000);
ssd2825_write_dsi(dev, msg->tx_buf, msg->tx_len); ssd2825_write_dsi(dev, msg->tx_buf, msg->tx_len);
if (buf == MIPI_DCS_SET_DISPLAY_ON) {
ssd2825_write_register(dev, SSD2825_CONFIGURATION_REG,
SSD2825_CONF_REG_HS | SSD2825_CONF_REG_VEN |
SSD2825_CONF_REG_DCS | SSD2825_CONF_REG_ECD |
SSD2825_CONF_REG_EOT);
ssd2825_write_register(dev, SSD2825_PLL_CTRL_REG, 0x0001);
ssd2825_write_register(dev, SSD2825_VC_CTRL_REG, 0x0000);
}
return 0; return 0;
} }
@ -312,9 +313,14 @@ static void ssd2825_setup_pll(struct udevice *dev)
struct mipi_dsi_device *device = &priv->device; struct mipi_dsi_device *device = &priv->device;
struct display_timing *dt = &priv->timing; struct display_timing *dt = &priv->timing;
u16 pll_config, lp_div; u16 pll_config, lp_div;
u32 nibble_delay, nibble_freq_khz;
u32 pclk_mult, tx_freq_khz, pd_lines; u32 pclk_mult, tx_freq_khz, pd_lines;
u8 hzd, hpd;
tx_freq_khz = clk_get_rate(priv->tx_clk) / 1000; tx_freq_khz = clk_get_rate(priv->tx_clk) / 1000;
if (!tx_freq_khz || tx_freq_khz < 0)
tx_freq_khz = SSD2825_REF_MIN_CLK;
pd_lines = mipi_dsi_pixel_format_to_bpp(device->format); pd_lines = mipi_dsi_pixel_format_to_bpp(device->format);
pclk_mult = pd_lines / device->lanes + 1; pclk_mult = pd_lines / device->lanes + 1;
@ -324,12 +330,19 @@ static void ssd2825_setup_pll(struct udevice *dev)
lp_div = priv->pll_freq_kbps / (SSD2825_LP_MIN_CLK * 8); lp_div = priv->pll_freq_kbps / (SSD2825_LP_MIN_CLK * 8);
/* nibble_delay in nanoseconds */
nibble_freq_khz = priv->pll_freq_kbps / 4;
nibble_delay = 1000 * 1000 / nibble_freq_khz;
hzd = priv->hzd / nibble_delay;
hpd = (priv->hpd - 4 * nibble_delay) / nibble_delay;
/* Disable PLL */ /* Disable PLL */
ssd2825_write_register(dev, SSD2825_PLL_CTRL_REG, 0x0000); ssd2825_write_register(dev, SSD2825_PLL_CTRL_REG, 0x0000);
ssd2825_write_register(dev, SSD2825_LINE_CTRL_REG, 0x0001); ssd2825_write_register(dev, SSD2825_LINE_CTRL_REG, 0x0001);
/* Set delays */ /* Set delays */
ssd2825_write_register(dev, SSD2825_DELAY_ADJ_REG_1, 0x2103); ssd2825_write_register(dev, SSD2825_DELAY_ADJ_REG_1, (hzd << 8) | hpd);
/* Set PLL coeficients */ /* Set PLL coeficients */
ssd2825_write_register(dev, SSD2825_PLL_CONFIGURATION_REG, pll_config); ssd2825_write_register(dev, SSD2825_PLL_CONFIGURATION_REG, pll_config);
@ -343,11 +356,30 @@ static void ssd2825_setup_pll(struct udevice *dev)
ssd2825_write_register(dev, SSD2825_VC_CTRL_REG, 0x0000); ssd2825_write_register(dev, SSD2825_VC_CTRL_REG, 0x0000);
} }
static int ssd2825_bridge_enable_panel(struct udevice *dev) static int ssd2825_bridge_attach(struct udevice *dev)
{ {
struct ssd2825_bridge_priv *priv = dev_get_priv(dev); struct ssd2825_bridge_priv *priv = dev_get_priv(dev);
struct mipi_dsi_device *device = &priv->device; struct mipi_dsi_device *device = &priv->device;
struct display_timing *dt = &priv->timing; struct display_timing *dt = &priv->timing;
u8 pixel_format;
int ret;
/* Set pixel format */
switch (device->format) {
case MIPI_DSI_FMT_RGB565:
pixel_format = 0x00;
break;
case MIPI_DSI_FMT_RGB666_PACKED:
pixel_format = 0x01;
break;
case MIPI_DSI_FMT_RGB666:
pixel_format = 0x02;
break;
case MIPI_DSI_FMT_RGB888:
default:
pixel_format = 0x03;
break;
}
/* Perform SW reset */ /* Perform SW reset */
ssd2825_write_register(dev, SSD2825_OPERATION_CTRL_REG, 0x0100); ssd2825_write_register(dev, SSD2825_OPERATION_CTRL_REG, 0x0100);
@ -367,7 +399,7 @@ static int ssd2825_bridge_enable_panel(struct udevice *dev)
ssd2825_write_register(dev, SSD2825_RGB_INTERFACE_CTRL_REG_6, ssd2825_write_register(dev, SSD2825_RGB_INTERFACE_CTRL_REG_6,
SSD2825_HSYNC_HIGH | SSD2825_VSYNC_HIGH | SSD2825_HSYNC_HIGH | SSD2825_VSYNC_HIGH |
SSD2825_PCKL_HIGH | SSD2825_NON_BURST | SSD2825_PCKL_HIGH | SSD2825_NON_BURST |
(3 - device->format)); pixel_format);
ssd2825_write_register(dev, SSD2825_LANE_CONFIGURATION_REG, ssd2825_write_register(dev, SSD2825_LANE_CONFIGURATION_REG,
device->lanes - 1); device->lanes - 1);
ssd2825_write_register(dev, SSD2825_TEST_REG, 0x0004); ssd2825_write_register(dev, SSD2825_TEST_REG, 0x0004);
@ -384,7 +416,18 @@ static int ssd2825_bridge_enable_panel(struct udevice *dev)
ssd2825_write_register(dev, SSD2825_VC_CTRL_REG, 0x0000); ssd2825_write_register(dev, SSD2825_VC_CTRL_REG, 0x0000);
/* Perform panel setup */ /* Perform panel setup */
return panel_enable_backlight(priv->panel); ret = panel_enable_backlight(priv->panel);
if (ret)
return ret;
ssd2825_write_register(dev, SSD2825_CONFIGURATION_REG,
SSD2825_CONF_REG_HS | SSD2825_CONF_REG_VEN |
SSD2825_CONF_REG_DCS | SSD2825_CONF_REG_ECD |
SSD2825_CONF_REG_EOT);
ssd2825_write_register(dev, SSD2825_PLL_CTRL_REG, 0x0001);
ssd2825_write_register(dev, SSD2825_VC_CTRL_REG, 0x0000);
return 0;
} }
static int ssd2825_bridge_set_panel(struct udevice *dev, int percent) static int ssd2825_bridge_set_panel(struct udevice *dev, int percent)
@ -407,7 +450,8 @@ static int ssd2825_bridge_panel_timings(struct udevice *dev,
static int ssd2825_bridge_hw_init(struct udevice *dev) static int ssd2825_bridge_hw_init(struct udevice *dev)
{ {
struct ssd2825_bridge_priv *priv = dev_get_priv(dev); struct ssd2825_bridge_priv *priv = dev_get_priv(dev);
int ret; struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev);
int i, ret;
ret = clk_prepare_enable(priv->tx_clk); ret = clk_prepare_enable(priv->tx_clk);
if (ret) { if (ret) {
@ -416,25 +460,28 @@ static int ssd2825_bridge_hw_init(struct udevice *dev)
return ret; return ret;
} }
ret = dm_gpio_set_value(&priv->power_gpio, 1); /* enable supplies */
for (i = 0; i < ARRAY_SIZE(ssd2825_supplies); i++) {
ret = regulator_set_enable_if_allowed(priv->supplies[i], 1);
if (ret) { if (ret) {
log_debug("%s: error changing power-gpios (%d)\n", log_debug("%s: cannot enable %s %d\n", __func__,
ssd2825_supplies[i], ret);
return ret;
}
}
mdelay(10);
ret = dm_gpio_set_value(&uc_priv->reset, 1);
if (ret) {
log_debug("%s: error entering reset (%d)\n",
__func__, ret); __func__, ret);
return ret; return ret;
} }
mdelay(10); mdelay(10);
ret = dm_gpio_set_value(&priv->reset_gpio, 0); ret = dm_gpio_set_value(&uc_priv->reset, 0);
if (ret) { if (ret) {
log_debug("%s: error changing reset-gpios (%d)\n", log_debug("%s: error exiting reset (%d)\n",
__func__, ret);
return ret;
}
mdelay(10);
ret = dm_gpio_set_value(&priv->reset_gpio, 1);
if (ret) {
log_debug("%s: error changing reset-gpios (%d)\n",
__func__, ret); __func__, ret);
return ret; return ret;
} }
@ -443,13 +490,33 @@ static int ssd2825_bridge_hw_init(struct udevice *dev)
return 0; return 0;
} }
static int ssd2825_bridge_get_panel(struct udevice *dev)
{
struct ssd2825_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);
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 ssd2825_bridge_probe(struct udevice *dev) static int ssd2825_bridge_probe(struct udevice *dev)
{ {
struct ssd2825_bridge_priv *priv = dev_get_priv(dev); struct ssd2825_bridge_priv *priv = dev_get_priv(dev);
struct spi_slave *slave = dev_get_parent_priv(dev); struct spi_slave *slave = dev_get_parent_priv(dev);
struct mipi_dsi_device *device = &priv->device; struct mipi_dsi_device *device = &priv->device;
struct mipi_dsi_panel_plat *mipi_plat; struct mipi_dsi_panel_plat *mipi_plat;
int ret; int i, ret;
ret = spi_claim_bus(slave); ret = spi_claim_bus(slave);
if (ret) { if (ret) {
@ -457,10 +524,9 @@ static int ssd2825_bridge_probe(struct udevice *dev)
return ret; return ret;
} }
ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev, ret = ssd2825_bridge_get_panel(dev);
"panel", &priv->panel);
if (ret) { if (ret) {
log_err("cannot get panel: ret=%d\n", ret); log_debug("%s: panel not found, ret %d\n", __func__, ret);
return ret; return ret;
} }
@ -477,33 +543,33 @@ static int ssd2825_bridge_probe(struct udevice *dev)
device->format = mipi_plat->format; device->format = mipi_plat->format;
device->mode_flags = mipi_plat->mode_flags; device->mode_flags = mipi_plat->mode_flags;
/* get panel gpios */ /* get supplies */
ret = gpio_request_by_name(dev, "power-gpios", 0, for (i = 0; i < ARRAY_SIZE(ssd2825_supplies); i++) {
&priv->power_gpio, GPIOD_IS_OUT); ret = device_get_supply_regulator(dev, ssd2825_supplies[i],
&priv->supplies[i]);
if (ret) { if (ret) {
log_err("could not decode power-gpios (%d)\n", ret); log_debug("%s: cannot get %s %d\n", __func__,
return ret; ssd2825_supplies[i], ret);
if (ret != -ENOENT)
return log_ret(ret);
} }
ret = gpio_request_by_name(dev, "reset-gpios", 0,
&priv->reset_gpio, GPIOD_IS_OUT);
if (ret) {
log_err("could not decode reset-gpios (%d)\n", ret);
return ret;
} }
/* get clk */ /* get clk */
priv->tx_clk = devm_clk_get(dev, "tx_clk"); priv->tx_clk = devm_clk_get_optional(dev, NULL);
if (IS_ERR(priv->tx_clk)) { if (IS_ERR(priv->tx_clk)) {
log_err("cannot get tx_clk: %ld\n", PTR_ERR(priv->tx_clk)); log_err("cannot get tx_clk: %ld\n", PTR_ERR(priv->tx_clk));
return PTR_ERR(priv->tx_clk); return PTR_ERR(priv->tx_clk);
} }
priv->hzd = dev_read_u32_default(dev, "solomon,hs-zero-delay-ns", 133);
priv->hpd = dev_read_u32_default(dev, "solomon,hs-prep-delay-ns", 40);
return ssd2825_bridge_hw_init(dev); return ssd2825_bridge_hw_init(dev);
} }
static const struct panel_ops ssd2825_bridge_ops = { static const struct video_bridge_ops ssd2825_bridge_ops = {
.enable_backlight = ssd2825_bridge_enable_panel, .attach = ssd2825_bridge_attach,
.set_backlight = ssd2825_bridge_set_panel, .set_backlight = ssd2825_bridge_set_panel,
.get_display_timing = ssd2825_bridge_panel_timings, .get_display_timing = ssd2825_bridge_panel_timings,
}; };
@ -515,9 +581,10 @@ static const struct udevice_id ssd2825_bridge_ids[] = {
U_BOOT_DRIVER(ssd2825) = { U_BOOT_DRIVER(ssd2825) = {
.name = "ssd2825", .name = "ssd2825",
.id = UCLASS_PANEL, .id = UCLASS_VIDEO_BRIDGE,
.of_match = ssd2825_bridge_ids, .of_match = ssd2825_bridge_ids,
.ops = &ssd2825_bridge_ops, .ops = &ssd2825_bridge_ops,
.bind = dm_scan_fdt_dev,
.probe = ssd2825_bridge_probe, .probe = ssd2825_bridge_probe,
.priv_auto = sizeof(struct ssd2825_bridge_priv), .priv_auto = sizeof(struct ssd2825_bridge_priv),
}; };

View file

@ -6,12 +6,14 @@
#include <clk.h> #include <clk.h>
#include <dm.h> #include <dm.h>
#include <dm/ofnode_graph.h>
#include <i2c.h> #include <i2c.h>
#include <log.h> #include <log.h>
#include <mipi_display.h> #include <mipi_display.h>
#include <mipi_dsi.h> #include <mipi_dsi.h>
#include <backlight.h> #include <backlight.h>
#include <panel.h> #include <panel.h>
#include <video_bridge.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/kernel.h> #include <linux/kernel.h>
@ -122,6 +124,10 @@
#define NANO 1000000000UL #define NANO 1000000000UL
#define PICO 1000000000000ULL #define PICO 1000000000000ULL
static const char * const tc358768_supplies[] = {
"vddc-supply", "vddmipi-supply", "vddio-supply"
};
struct tc358768_priv { struct tc358768_priv {
struct mipi_dsi_host host; struct mipi_dsi_host host;
struct mipi_dsi_device device; struct mipi_dsi_device device;
@ -129,9 +135,7 @@ struct tc358768_priv {
struct udevice *panel; struct udevice *panel;
struct display_timing timing; struct display_timing timing;
struct udevice *vddc; struct udevice *supplies[ARRAY_SIZE(tc358768_supplies)];
struct udevice *vddmipi;
struct udevice *vddio;
struct clk *refclk; struct clk *refclk;
@ -265,25 +269,27 @@ static void tc358768_sw_reset(struct udevice *dev)
tc358768_write(dev, TC358768_SYSCTL, 0); tc358768_write(dev, TC358768_SYSCTL, 0);
} }
static void tc358768_hw_enable(struct tc358768_priv *priv) static void tc358768_hw_enable(struct udevice *dev)
{ {
struct tc358768_priv *priv = dev_get_priv(dev);
struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev);
int ret; int ret;
ret = clk_prepare_enable(priv->refclk); ret = clk_prepare_enable(priv->refclk);
if (ret) if (ret)
log_debug("%s: error enabling refclk (%d)\n", __func__, ret); log_debug("%s: error enabling refclk (%d)\n", __func__, ret);
ret = regulator_set_enable_if_allowed(priv->vddc, true); ret = regulator_set_enable_if_allowed(priv->supplies[0], true);
if (ret) if (ret)
log_debug("%s: error enabling vddc (%d)\n", __func__, ret); log_debug("%s: error enabling vddc (%d)\n", __func__, ret);
ret = regulator_set_enable_if_allowed(priv->vddmipi, true); ret = regulator_set_enable_if_allowed(priv->supplies[1], true);
if (ret) if (ret)
log_debug("%s: error enabling vddmipi (%d)\n", __func__, ret); log_debug("%s: error enabling vddmipi (%d)\n", __func__, ret);
mdelay(10); mdelay(10);
ret = regulator_set_enable_if_allowed(priv->vddio, true); ret = regulator_set_enable_if_allowed(priv->supplies[2], true);
if (ret) if (ret)
log_debug("%s: error enabling vddio (%d)\n", __func__, ret); log_debug("%s: error enabling vddio (%d)\n", __func__, ret);
@ -293,7 +299,7 @@ static void tc358768_hw_enable(struct tc358768_priv *priv)
* The RESX is active low (GPIO_ACTIVE_LOW). * The RESX is active low (GPIO_ACTIVE_LOW).
* DEASSERT (value = 0) the reset_gpio to enable the chip * DEASSERT (value = 0) the reset_gpio to enable the chip
*/ */
ret = dm_gpio_set_value(&priv->reset_gpio, 0); ret = dm_gpio_set_value(&uc_priv->reset, 0);
if (ret) if (ret)
log_debug("%s: error changing reset-gpio (%d)\n", __func__, ret); log_debug("%s: error changing reset-gpio (%d)\n", __func__, ret);
@ -477,7 +483,7 @@ static int tc358768_attach(struct udevice *dev)
device->mode_flags &= ~MIPI_DSI_CLOCK_NON_CONTINUOUS; device->mode_flags &= ~MIPI_DSI_CLOCK_NON_CONTINUOUS;
} }
tc358768_hw_enable(priv); tc358768_hw_enable(dev);
tc358768_sw_reset(dev); tc358768_sw_reset(dev);
tc358768_setup_pll(dev); tc358768_setup_pll(dev);
@ -874,12 +880,33 @@ static int tc358768_panel_timings(struct udevice *dev,
return 0; return 0;
} }
static int tc358768_get_panel(struct udevice *dev)
{
struct tc358768_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 tc358768_setup(struct udevice *dev) static int tc358768_setup(struct udevice *dev)
{ {
struct tc358768_priv *priv = dev_get_priv(dev); struct tc358768_priv *priv = dev_get_priv(dev);
struct video_bridge_priv *uc_priv = dev_get_uclass_priv(dev);
struct mipi_dsi_device *device = &priv->device; struct mipi_dsi_device *device = &priv->device;
struct mipi_dsi_panel_plat *mipi_plat; struct mipi_dsi_panel_plat *mipi_plat;
int ret; int i, ret;
/* The bridge uses 16 bit registers */ /* The bridge uses 16 bit registers */
ret = i2c_set_chip_offset_len(dev, 2); ret = i2c_set_chip_offset_len(dev, 2);
@ -889,11 +916,10 @@ static int tc358768_setup(struct udevice *dev)
return ret; return ret;
} }
ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev, ret = tc358768_get_panel(dev);
"panel", &priv->panel);
if (ret) { if (ret) {
log_debug("%s: Cannot get panel: ret=%d\n", __func__, ret); log_debug("%s: panel not found, ret %d\n", __func__, ret);
return log_ret(ret); return ret;
} }
panel_get_display_timing(priv->panel, &priv->timing); panel_get_display_timing(priv->panel, &priv->timing);
@ -913,44 +939,26 @@ static int tc358768_setup(struct udevice *dev)
priv->dsi_lanes = device->lanes; priv->dsi_lanes = device->lanes;
/* get regulators */ /* get regulators */
ret = device_get_supply_regulator(dev, "vddc-supply", &priv->vddc); for (i = 0; i < ARRAY_SIZE(tc358768_supplies); i++) {
ret = device_get_supply_regulator(dev, tc358768_supplies[i],
&priv->supplies[i]);
if (ret) { if (ret) {
log_debug("%s: vddc regulator error: %d\n", __func__, ret); log_debug("%s: cannot get %s %d\n", __func__,
tc358768_supplies[i], ret);
if (ret != -ENOENT) if (ret != -ENOENT)
return log_ret(ret); return log_ret(ret);
} }
ret = device_get_supply_regulator(dev, "vddmipi-supply", &priv->vddmipi);
if (ret) {
log_debug("%s: vddmipi regulator error: %d\n", __func__, ret);
if (ret != -ENOENT)
return log_ret(ret);
}
ret = device_get_supply_regulator(dev, "vddio-supply", &priv->vddio);
if (ret) {
log_debug("%s: vddio regulator error: %d\n", __func__, ret);
if (ret != -ENOENT)
return log_ret(ret);
} }
/* get clk */ /* get clk */
priv->refclk = devm_clk_get(dev, "refclk"); priv->refclk = devm_clk_get(dev, NULL);
if (IS_ERR(priv->refclk)) { if (IS_ERR(priv->refclk)) {
log_debug("%s: Could not get refclk: %ld\n", log_debug("%s: Could not get refclk: %ld\n",
__func__, PTR_ERR(priv->refclk)); __func__, PTR_ERR(priv->refclk));
return PTR_ERR(priv->refclk); return PTR_ERR(priv->refclk);
} }
/* get gpios */ dm_gpio_set_value(&uc_priv->reset, 1);
ret = gpio_request_by_name(dev, "reset-gpios", 0,
&priv->reset_gpio, GPIOD_IS_OUT);
if (ret) {
log_debug("%s: Could not decode reset-gpios (%d)\n", __func__, ret);
return ret;
}
dm_gpio_set_value(&priv->reset_gpio, 1);
return 0; return 0;
} }
@ -963,8 +971,8 @@ static int tc358768_probe(struct udevice *dev)
return tc358768_setup(dev); return tc358768_setup(dev);
} }
struct panel_ops tc358768_ops = { static const struct video_bridge_ops tc358768_ops = {
.enable_backlight = tc358768_attach, .attach = tc358768_attach,
.set_backlight = tc358768_set_backlight, .set_backlight = tc358768_set_backlight,
.get_display_timing = tc358768_panel_timings, .get_display_timing = tc358768_panel_timings,
}; };
@ -977,9 +985,10 @@ static const struct udevice_id tc358768_ids[] = {
U_BOOT_DRIVER(tc358768) = { U_BOOT_DRIVER(tc358768) = {
.name = "tc358768", .name = "tc358768",
.id = UCLASS_PANEL, .id = UCLASS_VIDEO_BRIDGE,
.of_match = tc358768_ids, .of_match = tc358768_ids,
.ops = &tc358768_ops, .ops = &tc358768_ops,
.bind = dm_scan_fdt_dev,
.probe = tc358768_probe, .probe = tc358768_probe,
.priv_auto = sizeof(struct tc358768_priv), .priv_auto = sizeof(struct tc358768_priv),
}; };

View file

@ -117,6 +117,18 @@ static int endeavoru_panel_set_backlight(struct udevice *dev, int percent)
struct endeavoru_panel_priv *priv = dev_get_priv(dev); struct endeavoru_panel_priv *priv = dev_get_priv(dev);
int ret; int ret;
/*
* Due to the use of the Tegra DC backlight feature, backlight
* requests MUST NOT be made during probe or earlier. This is
* because it creates a loop, as the backlight is a DC child.
*/
ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
"backlight", &priv->backlight);
if (ret) {
log_err("cannot get backlight: ret = %d\n", ret);
return ret;
}
ret = backlight_enable(priv->backlight); ret = backlight_enable(priv->backlight);
if (ret) if (ret)
return ret; return ret;
@ -136,13 +148,6 @@ static int endeavoru_panel_of_to_plat(struct udevice *dev)
struct endeavoru_panel_priv *priv = dev_get_priv(dev); struct endeavoru_panel_priv *priv = dev_get_priv(dev);
int ret; int ret;
ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev,
"backlight", &priv->backlight);
if (ret) {
log_err("cannot get backlight: ret = %d\n", ret);
return ret;
}
ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
"vdd-supply", &priv->vdd); "vdd-supply", &priv->vdd);
if (ret) { if (ret) {
@ -231,7 +236,7 @@ static int endeavoru_panel_probe(struct udevice *dev)
/* fill characteristics of DSI data link */ /* fill characteristics of DSI data link */
plat->lanes = 2; plat->lanes = 2;
plat->format = MIPI_DSI_FMT_RGB888; plat->format = MIPI_DSI_FMT_RGB888;
plat->mode_flags = MIPI_DSI_MODE_VIDEO; plat->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM;
return endeavoru_panel_hw_init(dev); return endeavoru_panel_hw_init(dev);
} }

View file

@ -158,7 +158,7 @@ static int lg_ld070wx3_probe(struct udevice *dev)
/* fill characteristics of DSI data link */ /* fill characteristics of DSI data link */
plat->lanes = 4; plat->lanes = 4;
plat->format = MIPI_DSI_FMT_RGB888; plat->format = MIPI_DSI_FMT_RGB888;
plat->mode_flags = MIPI_DSI_MODE_VIDEO; plat->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM;
return lg_ld070wx3_hw_init(dev); return lg_ld070wx3_hw_init(dev);
} }

View file

@ -7,6 +7,7 @@
#include <backlight.h> #include <backlight.h>
#include <dm.h> #include <dm.h>
#include <dm/ofnode.h>
#include <i2c.h> #include <i2c.h>
#include <log.h> #include <log.h>
#include <linux/delay.h> #include <linux/delay.h>
@ -17,56 +18,79 @@
#define LM3533_BL_MAX_BRIGHTNESS 0xFF #define LM3533_BL_MAX_BRIGHTNESS 0xFF
#define LM3533_SINK_OUTPUT_CONFIG_1 0x10 #define LM3533_SINK_OUTPUT_CONFIG_1 0x10
#define LM3533_CONTROL_BANK_A_PWM 0x14 #define LM3533_CONTROL_PWM_BASE 0x14
#define PWM_MAX GENMASK(5, 0)
#define LM3533_CONTROL_BANK_AB_BRIGHTNESS 0x1A #define LM3533_CONTROL_BANK_AB_BRIGHTNESS 0x1A
#define LM3533_CONTROL_BANK_A_FULLSCALE_CURRENT 0x1F #define LM3533_CONTROL_FULLSCALE_CURRENT_BASE 0x1F
#define MAX_CURRENT_MIN 5000
#define MAX_CURRENT_MAX 29800
#define MAX_CURRENT_STEP 800
#define LM3533_CONTROL_BANK_ENABLE 0x27 #define LM3533_CONTROL_BANK_ENABLE 0x27
#define LM3533_OVP_FREQUENCY_PWM_POLARITY 0x2C #define LM3533_OVP_FREQUENCY_PWM_POLARITY 0x2C
#define BOOST_OVP_MASK GENMASK(2, 1)
#define BOOST_OVP_SHIFT 1
#define BOOST_FREQ_MASK BIT(0)
#define BOOST_FREQ_SHIFT 0
#define LM3533_BRIGHTNESS_REGISTER_A 0x40 #define LM3533_BRIGHTNESS_REGISTER_A 0x40
#define LM3533_BOOST_OVP_16V 16000000UL
#define LM3533_BOOST_FREQ_500KHZ 500000UL
struct lm3533_backlight_priv { struct lm3533_backlight_priv {
struct gpio_desc enable_gpio; struct gpio_desc enable_gpio;
u32 def_bl_lvl; u32 def_bl_lvl;
/* Core */
u32 boost_ovp;
u32 boost_freq;
/* Backlight */
u32 reg;
u16 max_current; /* 5000 - 29800 uA (800 uA step) */
u8 pwm; /* 0 - 0x3f */
bool linear;
bool hvled;
}; };
static int lm3533_backlight_enable(struct udevice *dev) static int lm3533_backlight_enable(struct udevice *dev)
{ {
struct lm3533_backlight_priv *priv = dev_get_priv(dev); struct lm3533_backlight_priv *priv = dev_get_priv(dev);
u8 val, id = priv->reg;
int ret; int ret;
dm_gpio_set_value(&priv->enable_gpio, 1); if (priv->linear) {
mdelay(5); ret = dm_i2c_reg_clrset(dev, LM3533_CONTROL_BANK_AB_BRIGHTNESS,
BIT(2 * id + 1), BIT(2 * id + 1));
if (ret)
return ret;
}
/* HVLED 1 & 2 are controlled by Bank A */ if (priv->hvled) {
ret = dm_i2c_reg_write(dev, LM3533_SINK_OUTPUT_CONFIG_1, 0x00); ret = dm_i2c_reg_clrset(dev, LM3533_SINK_OUTPUT_CONFIG_1,
BIT(0) | BIT(1), id | id << 1);
if (ret)
return ret;
}
/* Set current */
if (priv->max_current < MAX_CURRENT_MIN || priv->max_current > MAX_CURRENT_MAX)
return -EINVAL;
val = (priv->max_current - MAX_CURRENT_MIN) / MAX_CURRENT_STEP;
ret = dm_i2c_reg_write(dev, LM3533_CONTROL_FULLSCALE_CURRENT_BASE + id, val);
if (ret) if (ret)
return ret; return ret;
/* PWM input is disabled for CABC */ /* Set PWM mask */
ret = dm_i2c_reg_write(dev, LM3533_CONTROL_BANK_A_PWM, 0x00); if (priv->pwm > PWM_MAX)
return -EINVAL;
ret = dm_i2c_reg_write(dev, LM3533_CONTROL_PWM_BASE + id, priv->pwm);
if (ret) if (ret)
return ret; return ret;
/* Linear & Control Bank A is configured for register Current control */ /* Enable Control Bank */
ret = dm_i2c_reg_write(dev, LM3533_CONTROL_BANK_AB_BRIGHTNESS, 0x02); return dm_i2c_reg_clrset(dev, LM3533_CONTROL_BANK_ENABLE, BIT(id), BIT(id));
if (ret)
return ret;
/* Full-Scale Current (20.2mA) */
ret = dm_i2c_reg_write(dev, LM3533_CONTROL_BANK_A_FULLSCALE_CURRENT, 0x13);
if (ret)
return ret;
/* Control Bank A is enable */
ret = dm_i2c_reg_write(dev, LM3533_CONTROL_BANK_ENABLE, 0x01);
if (ret)
return ret;
ret = dm_i2c_reg_write(dev, LM3533_OVP_FREQUENCY_PWM_POLARITY, 0x0A);
if (ret)
return ret;
return 0;
} }
static int lm3533_backlight_set_brightness(struct udevice *dev, int percent) static int lm3533_backlight_set_brightness(struct udevice *dev, int percent)
@ -92,14 +116,12 @@ static int lm3533_backlight_set_brightness(struct udevice *dev, int percent)
return 0; return 0;
} }
static int lm3533_backlight_probe(struct udevice *dev) static int lm3533_backlight_of_to_plat(struct udevice *dev)
{ {
struct lm3533_backlight_priv *priv = dev_get_priv(dev); struct lm3533_backlight_priv *priv = dev_get_priv(dev);
ofnode child;
int ret; int ret;
if (device_get_uclass_id(dev->parent) != UCLASS_I2C)
return -EPROTONOSUPPORT;
ret = gpio_request_by_name(dev, "enable-gpios", 0, ret = gpio_request_by_name(dev, "enable-gpios", 0,
&priv->enable_gpio, GPIOD_IS_OUT); &priv->enable_gpio, GPIOD_IS_OUT);
if (ret) { if (ret) {
@ -107,9 +129,68 @@ static int lm3533_backlight_probe(struct udevice *dev)
return ret; return ret;
} }
priv->def_bl_lvl = dev_read_u32_default(dev, "default-brightness-level", priv->boost_ovp = dev_read_u32_default(dev, "ti,boost-ovp-microvolt",
LM3533_BOOST_OVP_16V);
/* boost_ovp is defined in microvolts, convert to enum value */
priv->boost_ovp = priv->boost_ovp / (8 * 1000 * 1000) - 2;
priv->boost_freq = dev_read_u32_default(dev, "ti,boost-freq-hz",
LM3533_BOOST_FREQ_500KHZ);
/* boost_freq is defined in Hz, convert to enum value */
priv->boost_freq = priv->boost_freq / (500 * 1000) - 1;
/* Backlight is one of children but has no dedicated driver */
ofnode_for_each_subnode(child, dev_ofnode(dev)) {
if (ofnode_device_is_compatible(child, "ti,lm3533-backlight")) {
const char *node_name = ofnode_get_name(child);
if (!strcmp(&node_name[10], "1"))
priv->reg = 1;
else
priv->reg = 0;
priv->max_current = ofnode_read_u32_default(child, "ti,max-current-microamp",
5000);
priv->pwm = ofnode_read_u32_default(child, "ti,pwm-config-mask", 0);
priv->def_bl_lvl = ofnode_read_u32_default(child, "default-brightness",
LM3533_BL_MAX_BRIGHTNESS); LM3533_BL_MAX_BRIGHTNESS);
priv->linear = ofnode_read_bool(child, "ti,linear-mapping-mode");
priv->hvled = ofnode_read_bool(child, "ti,hardware-controlled");
}
}
return 0;
}
static int lm3533_backlight_probe(struct udevice *dev)
{
struct lm3533_backlight_priv *priv = dev_get_priv(dev);
int ret;
if (device_get_uclass_id(dev->parent) != UCLASS_I2C)
return -EPROTONOSUPPORT;
dm_gpio_set_value(&priv->enable_gpio, 1);
mdelay(5);
ret = dm_i2c_reg_clrset(dev, LM3533_OVP_FREQUENCY_PWM_POLARITY,
BOOST_FREQ_MASK, priv->boost_freq << BOOST_FREQ_SHIFT);
if (ret) {
log_debug("%s: freq config failed %d\n", __func__, ret);
return ret;
}
ret = dm_i2c_reg_clrset(dev, LM3533_OVP_FREQUENCY_PWM_POLARITY,
BOOST_OVP_MASK, priv->boost_ovp << BOOST_OVP_SHIFT);
if (ret) {
log_debug("%s: ovp config failed %d\n", __func__, ret);
return ret;
}
return 0; return 0;
} }
@ -127,6 +208,7 @@ U_BOOT_DRIVER(lm3533_backlight) = {
.name = "lm3533_backlight", .name = "lm3533_backlight",
.id = UCLASS_PANEL_BACKLIGHT, .id = UCLASS_PANEL_BACKLIGHT,
.of_match = lm3533_backlight_ids, .of_match = lm3533_backlight_ids,
.of_to_plat = lm3533_backlight_of_to_plat,
.probe = lm3533_backlight_probe, .probe = lm3533_backlight_probe,
.ops = &lm3533_backlight_ops, .ops = &lm3533_backlight_ops,
.priv_auto = sizeof(struct lm3533_backlight_priv), .priv_auto = sizeof(struct lm3533_backlight_priv),

View file

@ -254,17 +254,17 @@ static int renesas_r61307_hw_init(struct udevice *dev)
return ret; return ret;
} }
ret = dm_gpio_set_value(&priv->reset_gpio, 0); ret = dm_gpio_set_value(&priv->reset_gpio, 1);
if (ret) { if (ret) {
log_debug("%s: changing reset-gpio failed (%d)\n", log_debug("%s: entering reset failed (%d)\n",
__func__, ret); __func__, ret);
return ret; return ret;
} }
mdelay(5); mdelay(5);
ret = dm_gpio_set_value(&priv->reset_gpio, 1); ret = dm_gpio_set_value(&priv->reset_gpio, 0);
if (ret) { if (ret) {
log_debug("%s: changing reset-gpio failed (%d)\n", log_debug("%s: exiting reset failed (%d)\n",
__func__, ret); __func__, ret);
return ret; return ret;
} }
@ -281,7 +281,8 @@ static int renesas_r61307_probe(struct udevice *dev)
/* fill characteristics of DSI data link */ /* fill characteristics of DSI data link */
plat->lanes = 4; plat->lanes = 4;
plat->format = MIPI_DSI_FMT_RGB888; plat->format = MIPI_DSI_FMT_RGB888;
plat->mode_flags = MIPI_DSI_MODE_VIDEO; plat->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM;
return renesas_r61307_hw_init(dev); return renesas_r61307_hw_init(dev);
} }
@ -294,7 +295,7 @@ static const struct panel_ops renesas_r61307_ops = {
static const struct udevice_id renesas_r61307_ids[] = { static const struct udevice_id renesas_r61307_ids[] = {
{ .compatible = "koe,tx13d100vm0eaa" }, { .compatible = "koe,tx13d100vm0eaa" },
{ .compatible = "hitachi,tx13d100vm0eaa" }, { .compatible = "hit,tx13d100vm0eaa" },
{ } { }
}; };

View file

@ -32,9 +32,11 @@
#define R69328_POWER_SET 0xD1 #define R69328_POWER_SET 0xD1
struct renesas_r69328_priv { struct renesas_r69328_priv {
struct udevice *vdd;
struct udevice *vddio;
struct udevice *backlight; struct udevice *backlight;
struct gpio_desc enable_gpio;
struct gpio_desc reset_gpio; struct gpio_desc reset_gpio;
}; };
@ -159,10 +161,15 @@ static int renesas_r69328_of_to_plat(struct udevice *dev)
return ret; return ret;
} }
ret = gpio_request_by_name(dev, "enable-gpios", 0, ret = device_get_supply_regulator(dev, "vdd-supply", &priv->vdd);
&priv->enable_gpio, GPIOD_IS_OUT);
if (ret) { if (ret) {
log_err("could not decode enable-gpios (%d)\n", ret); log_err("Cannot get vdd-supply: ret = %d\n", ret);
return ret;
}
ret = device_get_supply_regulator(dev, "vddio-supply", &priv->vddio);
if (ret) {
log_err("Cannot get vddio-supply: ret = %d\n", ret);
return ret; return ret;
} }
@ -181,9 +188,24 @@ static int renesas_r69328_hw_init(struct udevice *dev)
struct renesas_r69328_priv *priv = dev_get_priv(dev); struct renesas_r69328_priv *priv = dev_get_priv(dev);
int ret; int ret;
ret = dm_gpio_set_value(&priv->enable_gpio, 1); ret = regulator_set_enable_if_allowed(priv->vddio, 1);
if (ret) { if (ret) {
log_debug("%s: error changing enable-gpios (%d)\n", log_debug("%s: enabling vddio-supply failed (%d)\n",
__func__, ret);
return ret;
}
mdelay(5);
ret = regulator_set_enable_if_allowed(priv->vdd, 1);
if (ret) {
log_debug("%s: enabling vdd-supply failed (%d)\n",
__func__, ret);
return ret;
}
ret = dm_gpio_set_value(&priv->reset_gpio, 1);
if (ret) {
log_debug("%s: error entering reset (%d)\n",
__func__, ret); __func__, ret);
return ret; return ret;
} }
@ -191,15 +213,7 @@ static int renesas_r69328_hw_init(struct udevice *dev)
ret = dm_gpio_set_value(&priv->reset_gpio, 0); ret = dm_gpio_set_value(&priv->reset_gpio, 0);
if (ret) { if (ret) {
log_debug("%s: error changing reset-gpios (%d)\n", log_debug("%s: error exiting reset (%d)\n",
__func__, ret);
return ret;
}
mdelay(5);
ret = dm_gpio_set_value(&priv->reset_gpio, 1);
if (ret) {
log_debug("%s: error changing reset-gpios (%d)\n",
__func__, ret); __func__, ret);
return ret; return ret;
} }
@ -216,7 +230,8 @@ static int renesas_r69328_probe(struct udevice *dev)
/* fill characteristics of DSI data link */ /* fill characteristics of DSI data link */
plat->lanes = 4; plat->lanes = 4;
plat->format = MIPI_DSI_FMT_RGB888; plat->format = MIPI_DSI_FMT_RGB888;
plat->mode_flags = MIPI_DSI_MODE_VIDEO; plat->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
MIPI_DSI_CLOCK_NON_CONTINUOUS | MIPI_DSI_MODE_LPM;
return renesas_r69328_hw_init(dev); return renesas_r69328_hw_init(dev);
} }

View file

@ -129,7 +129,7 @@ static int samsung_ltl106hl02_probe(struct udevice *dev)
/* fill characteristics of DSI data link */ /* fill characteristics of DSI data link */
plat->lanes = 4; plat->lanes = 4;
plat->format = MIPI_DSI_FMT_RGB888; plat->format = MIPI_DSI_FMT_RGB888;
plat->mode_flags = MIPI_DSI_MODE_VIDEO; plat->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM;
return samsung_ltl106hl02_hw_init(dev); return samsung_ltl106hl02_hw_init(dev);
} }

View file

@ -255,6 +255,7 @@ static int sharp_lq101r1sx01_probe(struct udevice *dev)
/* fill characteristics of DSI data link */ /* fill characteristics of DSI data link */
plat->lanes = 4; plat->lanes = 4;
plat->format = MIPI_DSI_FMT_RGB888; plat->format = MIPI_DSI_FMT_RGB888;
plat->mode_flags = MIPI_DSI_MODE_LPM;
return sharp_lq101r1sx01_hw_init(dev); return sharp_lq101r1sx01_hw_init(dev);
} }

View file

@ -1,6 +1,11 @@
config HOST1X_TEGRA
bool "NVIDIA Tegra host1x BUS support"
depends on SIMPLE_BUS
config VIDEO_TEGRA20 config VIDEO_TEGRA20
bool "Enable Display Controller support on Tegra20 and Tegra 30" bool "Enable Display Controller support on Tegra20 and Tegra 30"
depends on OF_CONTROL depends on OF_CONTROL
select HOST1X_TEGRA
help help
T20/T30 support video output to an attached LCD panel as well as T20/T30 support video output to an attached LCD panel as well as
other options such as HDMI. Only the LCD is supported in U-Boot. other options such as HDMI. Only the LCD is supported in U-Boot.
@ -9,13 +14,22 @@ config VIDEO_TEGRA20
config VIDEO_DSI_TEGRA30 config VIDEO_DSI_TEGRA30
bool "Enable Tegra 30 DSI support" bool "Enable Tegra 30 DSI support"
depends on PANEL && DM_GPIO depends on VIDEO_BRIDGE && PANEL && DM_GPIO
select VIDEO_TEGRA20 select VIDEO_TEGRA20
select VIDEO_MIPI_DSI select VIDEO_MIPI_DSI
help help
T30 has native support for DSI panels. This option enables support T30 has native support for DSI panels. This option enables support
for such panels which can be used on endeavoru and tf600t. for such panels which can be used on endeavoru and tf600t.
config VIDEO_HDMI_TEGRA
bool "Enable Tegra HDMI support"
depends on VIDEO_BRIDGE && DM_I2C
select I2C_EDID
select VIDEO_TEGRA20
help
Tegra has native support for HDMI. This option enables support
for such connection and can be used for any supported device.
config TEGRA_BACKLIGHT_PWM config TEGRA_BACKLIGHT_PWM
bool "Enable Tegra DC PWM backlight support" bool "Enable Tegra DC PWM backlight support"
depends on BACKLIGHT depends on BACKLIGHT

View file

@ -1,5 +1,7 @@
# SPDX-License-Identifier: GPL-2.0+ # SPDX-License-Identifier: GPL-2.0+
obj-$(CONFIG_HOST1X_TEGRA) += tegra-host1x.o
obj-$(CONFIG_VIDEO_TEGRA20) += tegra-dc.o obj-$(CONFIG_VIDEO_TEGRA20) += tegra-dc.o
obj-$(CONFIG_VIDEO_DSI_TEGRA30) += tegra-dsi.o tegra-mipi.o mipi-phy.o obj-$(CONFIG_VIDEO_DSI_TEGRA30) += tegra-dsi.o tegra-mipi.o mipi-phy.o
obj-$(CONFIG_VIDEO_HDMI_TEGRA) += tegra-hdmi.o
obj-$(CONFIG_TEGRA_BACKLIGHT_PWM) += tegra-pwm-backlight.o obj-$(CONFIG_TEGRA_BACKLIGHT_PWM) += tegra-pwm-backlight.o

View file

@ -1,16 +1,19 @@
// SPDX-License-Identifier: GPL-2.0+ // SPDX-License-Identifier: GPL-2.0+
/* /*
* Copyright (c) 2011 The Chromium OS Authors. * Copyright (c) 2011 The Chromium OS Authors.
* Copyright (c) 2024 Svyatoslav Ryhel <clamor95@gmail.com>
*/ */
#include <backlight.h> #include <backlight.h>
#include <cpu_func.h> #include <cpu_func.h>
#include <clk.h> #include <clk.h>
#include <dm.h> #include <dm.h>
#include <dm/ofnode_graph.h>
#include <fdtdec.h> #include <fdtdec.h>
#include <log.h> #include <log.h>
#include <panel.h> #include <panel.h>
#include <video.h> #include <video.h>
#include <video_bridge.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/arch/clock.h> #include <asm/arch/clock.h>
@ -31,7 +34,8 @@ struct tegra_lcd_priv {
int height; /* height in pixels */ int height; /* height in pixels */
enum video_log2_bpp log2_bpp; /* colour depth */ enum video_log2_bpp log2_bpp; /* colour depth */
struct display_timing timing; struct display_timing timing;
struct udevice *panel; struct udevice *panel; /* Panels attached to RGB */
struct udevice *bridge; /* Bridge linked with DC */
struct dc_ctlr *dc; /* Display controller regmap */ struct dc_ctlr *dc; /* Display controller regmap */
const struct tegra_dc_soc_info *soc; const struct tegra_dc_soc_info *soc;
fdt_addr_t frame_buffer; /* Address of frame buffer */ fdt_addr_t frame_buffer; /* Address of frame buffer */
@ -319,11 +323,6 @@ static int tegra_display_probe(struct tegra_lcd_priv *priv,
/ priv->pixel_clock) - 2; / priv->pixel_clock) - 2;
log_debug("Display clock %lu, divider %lu\n", rate, priv->scdiv); log_debug("Display clock %lu, divider %lu\n", rate, priv->scdiv);
/*
* HOST1X is init by default at 150MHz with PLLC as parent
*/
clock_start_periph_pll(PERIPH_ID_HOST1X, CLOCK_ID_CGENERAL,
150 * 1000000);
clock_start_periph_pll(priv->clk->id, priv->clk_parent->id, clock_start_periph_pll(priv->clk->id, priv->clk_parent->id,
rate); rate);
@ -378,12 +377,13 @@ static int tegra_lcd_probe(struct udevice *dev)
} }
/* Get shift clock divider from Tegra DSI if used */ /* Get shift clock divider from Tegra DSI if used */
if (!strcmp(priv->panel->name, TEGRA_DSI_A) || if (priv->bridge) {
!strcmp(priv->panel->name, TEGRA_DSI_B)) { if (!strcmp(priv->bridge->driver->name, "tegra_dsi")) {
struct tegra_dc_plat *dc_plat = dev_get_plat(priv->panel); struct tegra_dc_plat *dc_plat = dev_get_plat(priv->bridge);
priv->scdiv = dc_plat->scdiv; priv->scdiv = dc_plat->scdiv;
} }
}
/* Clean the framebuffer area */ /* Clean the framebuffer area */
memset((u8 *)plat->base, 0, plat->size); memset((u8 *)plat->base, 0, plat->size);
@ -395,11 +395,21 @@ static int tegra_lcd_probe(struct udevice *dev)
return ret; return ret;
} }
if (priv->panel) {
ret = panel_enable_backlight(priv->panel); ret = panel_enable_backlight(priv->panel);
if (ret) { if (ret) {
log_debug("%s: Cannot enable backlight, ret=%d\n", __func__, ret); log_debug("%s: Cannot enable backlight, ret=%d\n", __func__, ret);
return ret; return ret;
} }
}
if (priv->bridge) {
ret = video_bridge_attach(priv->bridge);
if (ret) {
log_debug("%s: Cannot attach bridge, ret=%d\n", __func__, ret);
return ret;
}
}
mmu_set_region_dcache_behaviour(priv->frame_buffer, plat->size, mmu_set_region_dcache_behaviour(priv->frame_buffer, plat->size,
DCACHE_WRITETHROUGH); DCACHE_WRITETHROUGH);
@ -413,17 +423,129 @@ static int tegra_lcd_probe(struct udevice *dev)
log_debug("LCD frame buffer at %08x, size %x\n", priv->frame_buffer, log_debug("LCD frame buffer at %08x, size %x\n", priv->frame_buffer,
plat->size); plat->size);
return panel_set_backlight(priv->panel, BACKLIGHT_DEFAULT); if (priv->panel) {
ret = panel_set_backlight(priv->panel, BACKLIGHT_DEFAULT);
if (ret)
return ret;
}
if (priv->bridge) {
ret = video_bridge_set_backlight(priv->bridge, BACKLIGHT_DEFAULT);
if (ret)
return ret;
}
return 0;
}
static int tegra_lcd_configure_rgb(struct udevice *dev, ofnode rgb)
{
struct tegra_lcd_priv *priv = dev_get_priv(dev);
ofnode remote;
int ret;
/* DC can have only 1 port */
remote = ofnode_graph_get_remote_node(rgb, -1, -1);
ret = uclass_get_device_by_ofnode(UCLASS_PANEL, remote, &priv->panel);
if (!ret)
return 0;
ret = uclass_get_device_by_ofnode(UCLASS_VIDEO_BRIDGE, remote, &priv->bridge);
if (!ret)
return 0;
/* Try legacy method if graph did not work */
remote = ofnode_parse_phandle(rgb, "nvidia,panel", 0);
if (!ofnode_valid(remote))
return -EINVAL;
ret = uclass_get_device_by_ofnode(UCLASS_PANEL, remote, &priv->panel);
if (ret) {
log_debug("%s: Cannot find panel for '%s' (ret=%d)\n",
__func__, dev->name, ret);
ret = uclass_get_device_by_ofnode(UCLASS_VIDEO_BRIDGE, remote,
&priv->bridge);
if (ret) {
log_err("%s: Cannot find panel or bridge for '%s' (ret=%d)\n",
__func__, dev->name, ret);
return ret;
}
}
return 0;
}
static int tegra_lcd_configure_internal(struct udevice *dev)
{
struct tegra_lcd_priv *priv = dev_get_priv(dev);
struct tegra_dc_plat *dc_plat;
ofnode host1x = ofnode_get_parent(dev_ofnode(dev));
ofnode node;
int ret;
switch (priv->pipe) {
case 0: /* DC0 is usually used for DSI */
/* Check for ganged DSI configuration */
ofnode_for_each_subnode(node, host1x)
if (ofnode_name_eq(node, "dsi") && ofnode_is_enabled(node) &&
ofnode_read_bool(node, "nvidia,ganged-mode"))
goto exit;
/* If no master DSI found loop for any active DSI */
ofnode_for_each_subnode(node, host1x)
if (ofnode_name_eq(node, "dsi") && ofnode_is_enabled(node))
goto exit;
log_err("%s: failed to find DSI device for '%s'\n",
__func__, dev->name);
return -ENODEV;
case 1: /* DC1 is usually used for HDMI */
ofnode_for_each_subnode(node, host1x)
if (ofnode_name_eq(node, "hdmi"))
goto exit;
log_err("%s: failed to find HDMI device for '%s'\n",
__func__, dev->name);
return -ENODEV;
default:
log_debug("Unsupported DC selection\n");
return -EINVAL;
}
exit:
ret = uclass_get_device_by_ofnode(UCLASS_VIDEO_BRIDGE, node, &priv->bridge);
if (ret) {
log_err("%s: failed to get DSI/HDMI device for '%s' (ret %d)\n",
__func__, dev->name, ret);
return ret;
}
priv->clk_parent = devm_clk_get(priv->bridge, "parent");
if (IS_ERR(priv->clk_parent)) {
log_debug("%s: Could not get DC clock parent from DSI/HDMI: %ld\n",
__func__, PTR_ERR(priv->clk_parent));
return PTR_ERR(priv->clk_parent);
}
dc_plat = dev_get_plat(priv->bridge);
/* Fill the platform data for internal devices */
dc_plat->dev = dev;
dc_plat->dc = priv->dc;
dc_plat->pipe = priv->pipe;
return 0;
} }
static int tegra_lcd_of_to_plat(struct udevice *dev) static int tegra_lcd_of_to_plat(struct udevice *dev)
{ {
struct tegra_lcd_priv *priv = dev_get_priv(dev); struct tegra_lcd_priv *priv = dev_get_priv(dev);
const void *blob = gd->fdt_blob;
struct display_timing *timing; struct display_timing *timing;
int node = dev_of_offset(dev); ofnode rgb;
int panel_node;
int rgb;
int ret; int ret;
priv->dc = (struct dc_ctlr *)dev_read_addr_ptr(dev); priv->dc = (struct dc_ctlr *)dev_read_addr_ptr(dev);
@ -451,44 +573,42 @@ static int tegra_lcd_of_to_plat(struct udevice *dev)
priv->rotation = dev_read_bool(dev, "nvidia,180-rotation"); priv->rotation = dev_read_bool(dev, "nvidia,180-rotation");
priv->pipe = dev_read_u32_default(dev, "nvidia,head", 0); priv->pipe = dev_read_u32_default(dev, "nvidia,head", 0);
rgb = fdt_subnode_offset(blob, node, "rgb");
if (rgb < 0) {
log_debug("%s: Cannot find rgb subnode for '%s' (ret=%d)\n",
__func__, dev->name, rgb);
return -EINVAL;
}
/* /*
* Sadly the panel phandle is in an rgb subnode so we cannot use * Usual logic of Tegra video routing should be next:
* uclass_get_device_by_phandle(). * 1. Check rgb subnode for RGB/LVDS panels or bridges
* 2. If none found, then iterate through bridges bound,
* looking for DSIA or DSIB for DC0 and HDMI for DC1.
* If none of above is valid, then configuration is not
* valid.
*/ */
panel_node = fdtdec_lookup_phandle(blob, rgb, "nvidia,panel");
if (panel_node < 0) {
log_debug("%s: Cannot find panel information\n", __func__);
return -EINVAL;
}
ret = uclass_get_device_by_of_offset(UCLASS_PANEL, panel_node, rgb = dev_read_subnode(dev, "rgb");
&priv->panel); if (ofnode_valid(rgb) && ofnode_is_enabled(rgb)) {
if (ret) { /* RGB is available, use it */
log_debug("%s: Cannot find panel for '%s' (ret=%d)\n", __func__, ret = tegra_lcd_configure_rgb(dev, rgb);
dev->name, ret); if (ret)
return ret;
} else {
/* RGB is not available, check for internal devices */
ret = tegra_lcd_configure_internal(dev);
if (ret)
return ret; return ret;
} }
/* Fill the platform data for internal devices */ if (priv->panel) {
if (!strcmp(priv->panel->name, TEGRA_DSI_A) ||
!strcmp(priv->panel->name, TEGRA_DSI_B)) {
struct tegra_dc_plat *dc_plat = dev_get_plat(priv->panel);
dc_plat->dev = dev;
dc_plat->dc = priv->dc;
dc_plat->pipe = priv->pipe;
}
ret = panel_get_display_timing(priv->panel, &priv->timing); ret = panel_get_display_timing(priv->panel, &priv->timing);
if (ret) { if (ret) {
ret = fdtdec_decode_display_timing(blob, rgb, 0, &priv->timing); ret = ofnode_decode_display_timing(rgb, 0, &priv->timing);
if (ret) {
log_debug("%s: Cannot read display timing for '%s' (ret=%d)\n",
__func__, dev->name, ret);
return -EINVAL;
}
}
}
if (priv->bridge) {
ret = video_bridge_get_display_timing(priv->bridge, &priv->timing);
if (ret) { if (ret) {
log_debug("%s: Cannot read display timing for '%s' (ret=%d)\n", log_debug("%s: Cannot read display timing for '%s' (ret=%d)\n",
__func__, dev->name, ret); __func__, dev->name, ret);
@ -508,23 +628,13 @@ static int tegra_lcd_of_to_plat(struct udevice *dev)
static int tegra_lcd_bind(struct udevice *dev) static int tegra_lcd_bind(struct udevice *dev)
{ {
struct video_uc_plat *plat = dev_get_uclass_plat(dev); struct video_uc_plat *plat = dev_get_uclass_plat(dev);
const void *blob = gd->fdt_blob;
int node = dev_of_offset(dev);
int rgb;
rgb = fdt_subnode_offset(blob, node, "rgb");
if ((rgb < 0) || !fdtdec_get_is_enabled(blob, rgb))
return -ENODEV;
plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT * plat->size = LCD_MAX_WIDTH * LCD_MAX_HEIGHT *
(1 << LCD_MAX_LOG2_BPP) / 8; (1 << LCD_MAX_LOG2_BPP) / 8;
return 0; return dm_scan_fdt_dev(dev);
} }
static const struct video_ops tegra_lcd_ops = {
};
static const struct tegra_dc_soc_info tegra20_dc_soc_info = { static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
.has_timer = true, .has_timer = true,
.has_rgb = true, .has_rgb = true,
@ -565,7 +675,6 @@ U_BOOT_DRIVER(tegra_lcd) = {
.name = "tegra_lcd", .name = "tegra_lcd",
.id = UCLASS_VIDEO, .id = UCLASS_VIDEO,
.of_match = tegra_lcd_ids, .of_match = tegra_lcd_ids,
.ops = &tegra_lcd_ops,
.bind = tegra_lcd_bind, .bind = tegra_lcd_bind,
.probe = tegra_lcd_probe, .probe = tegra_lcd_probe,
.of_to_plat = tegra_lcd_of_to_plat, .of_to_plat = tegra_lcd_of_to_plat,

View file

@ -14,9 +14,6 @@
/* arch-tegra/dc exists only because T124 uses it */ /* arch-tegra/dc exists only because T124 uses it */
#include <asm/arch-tegra/dc.h> #include <asm/arch-tegra/dc.h>
#define TEGRA_DSI_A "dsi@54300000"
#define TEGRA_DSI_B "dsi@54400000"
struct tegra_dc_plat { struct tegra_dc_plat {
struct udevice *dev; /* Display controller device */ struct udevice *dev; /* Display controller device */
struct dc_ctlr *dc; /* Display controller regmap */ struct dc_ctlr *dc; /* Display controller regmap */

View file

@ -11,6 +11,7 @@
#include <mipi_display.h> #include <mipi_display.h>
#include <mipi_dsi.h> #include <mipi_dsi.h>
#include <backlight.h> #include <backlight.h>
#include <video_bridge.h>
#include <panel.h> #include <panel.h>
#include <reset.h> #include <reset.h>
#include <linux/delay.h> #include <linux/delay.h>
@ -250,6 +251,9 @@ static ssize_t tegra_dsi_host_transfer(struct mipi_dsi_host *host,
value = DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST | value = DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST |
DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC; DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC;
if ((msg->flags & MIPI_DSI_MSG_USE_LPM) == 0)
value |= DSI_HOST_CONTROL_HS;
/* /*
* The host FIFO has a maximum of 64 words, so larger transmissions * The host FIFO has a maximum of 64 words, so larger transmissions
* need to use the video FIFO. * need to use the video FIFO.
@ -991,7 +995,7 @@ static int tegra_dsi_ganged_probe(struct udevice *dev)
struct tegra_dsi_priv *mpriv = dev_get_priv(dev); struct tegra_dsi_priv *mpriv = dev_get_priv(dev);
struct udevice *gangster; struct udevice *gangster;
uclass_get_device_by_phandle(UCLASS_PANEL, dev, uclass_get_device_by_phandle(UCLASS_VIDEO_BRIDGE, dev,
"nvidia,ganged-mode", &gangster); "nvidia,ganged-mode", &gangster);
if (gangster) { if (gangster) {
/* Ganged mode is set */ /* Ganged mode is set */
@ -1118,8 +1122,8 @@ static int tegra_dsi_bridge_probe(struct udevice *dev)
return 0; return 0;
} }
static const struct panel_ops tegra_dsi_bridge_ops = { static const struct video_bridge_ops tegra_dsi_bridge_ops = {
.enable_backlight = tegra_dsi_encoder_enable, .attach = tegra_dsi_encoder_enable,
.set_backlight = tegra_dsi_bridge_set_panel, .set_backlight = tegra_dsi_bridge_set_panel,
.get_display_timing = tegra_dsi_panel_timings, .get_display_timing = tegra_dsi_panel_timings,
}; };
@ -1133,7 +1137,7 @@ static const struct udevice_id tegra_dsi_bridge_ids[] = {
U_BOOT_DRIVER(tegra_dsi) = { U_BOOT_DRIVER(tegra_dsi) = {
.name = "tegra_dsi", .name = "tegra_dsi",
.id = UCLASS_PANEL, .id = UCLASS_VIDEO_BRIDGE,
.of_match = tegra_dsi_bridge_ids, .of_match = tegra_dsi_bridge_ids,
.ops = &tegra_dsi_bridge_ops, .ops = &tegra_dsi_bridge_ops,
.bind = dm_scan_fdt_dev, .bind = dm_scan_fdt_dev,

View file

@ -0,0 +1,623 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2013 NVIDIA Corporation
* Copyright (c) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <clk.h>
#include <dm.h>
#include <edid.h>
#include <i2c.h>
#include <log.h>
#include <misc.h>
#include <panel.h>
#include <reset.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/time.h>
#include <power/regulator.h>
#include <video_bridge.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include "tegra-dc.h"
#include "tegra-hdmi.h"
#define DDCCI_ENTRY_ADDR 0x37
#define DDCCI_SOURSE_ADDR 0x51
#define DDCCI_COMMAND_WRITE 0x03
#define DDCCI_CTRL_BRIGHTNESS 0x10
#define HDMI_EDID_I2C_ADDR 0x50
#define HDMI_REKEY_DEFAULT 56
static const char * const hdmi_supplies[] = {
"hdmi-supply", "pll-supply", "vdd-supply"
};
struct tmds_config {
unsigned int pclk;
u32 pll0;
u32 pll1;
u32 pe_current;
u32 drive_current;
u32 peak_current;
};
struct tegra_hdmi_config {
const struct tmds_config *tmds;
unsigned int num_tmds;
unsigned int max_pclk;
/* to be filled */
};
struct tegra_hdmi_priv {
struct hdmi_ctlr *hdmi_regmap;
struct udevice *supplies[ARRAY_SIZE(hdmi_supplies)];
struct udevice *hdmi_ddc;
struct gpio_desc hpd; /* hotplug detection gpio */
struct display_timing timing;
struct clk *clk;
struct clk *clk_parent;
int panel_bits_per_colourp;
const struct tegra_hdmi_config *config;
};
/* 1280x720p 60hz: EIA/CEA-861-B Format 4 */
static struct display_timing default_720p_timing = {
.pixelclock.typ = 74250000,
.hactive.typ = 1280,
.hfront_porch.typ = 110,
.hback_porch.typ = 220,
.hsync_len.typ = 40,
.vactive.typ = 720,
.vfront_porch.typ = 5,
.vback_porch.typ = 20,
.vsync_len.typ = 5,
.flags = DISPLAY_FLAGS_HSYNC_HIGH |
DISPLAY_FLAGS_VSYNC_HIGH,
};
static const struct tmds_config tegra20_tmds_config[] = {
{ /* slow pixel clock modes */
.pclk = 27000000,
.pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(0) |
SOR_PLL_TX_REG_LOAD(3),
.pll1 = SOR_PLL_TMDS_TERM_ENABLE,
.pe_current = PE_CURRENT0(PE_CURRENT_0_0_mA) |
PE_CURRENT1(PE_CURRENT_0_0_mA) |
PE_CURRENT2(PE_CURRENT_0_0_mA) |
PE_CURRENT3(PE_CURRENT_0_0_mA),
.drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_7_125_mA) |
DRIVE_CURRENT_LANE1(DRIVE_CURRENT_7_125_mA) |
DRIVE_CURRENT_LANE2(DRIVE_CURRENT_7_125_mA) |
DRIVE_CURRENT_LANE3(DRIVE_CURRENT_7_125_mA),
},
{ /* high pixel clock modes */
.pclk = UINT_MAX,
.pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(1) |
SOR_PLL_TX_REG_LOAD(3),
.pll1 = SOR_PLL_TMDS_TERM_ENABLE | SOR_PLL_PE_EN,
.pe_current = PE_CURRENT0(PE_CURRENT_6_0_mA) |
PE_CURRENT1(PE_CURRENT_6_0_mA) |
PE_CURRENT2(PE_CURRENT_6_0_mA) |
PE_CURRENT3(PE_CURRENT_6_0_mA),
.drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_7_125_mA) |
DRIVE_CURRENT_LANE1(DRIVE_CURRENT_7_125_mA) |
DRIVE_CURRENT_LANE2(DRIVE_CURRENT_7_125_mA) |
DRIVE_CURRENT_LANE3(DRIVE_CURRENT_7_125_mA),
},
};
static const struct tmds_config tegra30_tmds_config[] = {
{ /* 480p modes */
.pclk = 27000000,
.pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(0) |
SOR_PLL_TX_REG_LOAD(0),
.pll1 = SOR_PLL_TMDS_TERM_ENABLE,
.pe_current = PE_CURRENT0(PE_CURRENT_0_0_mA) |
PE_CURRENT1(PE_CURRENT_0_0_mA) |
PE_CURRENT2(PE_CURRENT_0_0_mA) |
PE_CURRENT3(PE_CURRENT_0_0_mA),
.drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_5_250_mA) |
DRIVE_CURRENT_LANE1(DRIVE_CURRENT_5_250_mA) |
DRIVE_CURRENT_LANE2(DRIVE_CURRENT_5_250_mA) |
DRIVE_CURRENT_LANE3(DRIVE_CURRENT_5_250_mA),
}, { /* 720p modes */
.pclk = 74250000,
.pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(1) |
SOR_PLL_TX_REG_LOAD(0),
.pll1 = SOR_PLL_TMDS_TERM_ENABLE | SOR_PLL_PE_EN,
.pe_current = PE_CURRENT0(PE_CURRENT_5_0_mA) |
PE_CURRENT1(PE_CURRENT_5_0_mA) |
PE_CURRENT2(PE_CURRENT_5_0_mA) |
PE_CURRENT3(PE_CURRENT_5_0_mA),
.drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_5_250_mA) |
DRIVE_CURRENT_LANE1(DRIVE_CURRENT_5_250_mA) |
DRIVE_CURRENT_LANE2(DRIVE_CURRENT_5_250_mA) |
DRIVE_CURRENT_LANE3(DRIVE_CURRENT_5_250_mA),
}, { /* 1080p modes */
.pclk = UINT_MAX,
.pll0 = SOR_PLL_BG_V17_S(3) | SOR_PLL_ICHPMP(1) |
SOR_PLL_RESISTORSEL | SOR_PLL_VCOCAP(3) |
SOR_PLL_TX_REG_LOAD(0),
.pll1 = SOR_PLL_TMDS_TERM_ENABLE | SOR_PLL_PE_EN,
.pe_current = PE_CURRENT0(PE_CURRENT_5_0_mA) |
PE_CURRENT1(PE_CURRENT_5_0_mA) |
PE_CURRENT2(PE_CURRENT_5_0_mA) |
PE_CURRENT3(PE_CURRENT_5_0_mA),
.drive_current = DRIVE_CURRENT_LANE0(DRIVE_CURRENT_5_250_mA) |
DRIVE_CURRENT_LANE1(DRIVE_CURRENT_5_250_mA) |
DRIVE_CURRENT_LANE2(DRIVE_CURRENT_5_250_mA) |
DRIVE_CURRENT_LANE3(DRIVE_CURRENT_5_250_mA),
},
};
static void tegra_dc_enable_controller(struct udevice *dev)
{
struct tegra_dc_plat *dc_plat = dev_get_plat(dev);
struct dc_ctlr *dc = dc_plat->dc;
u32 value;
value = readl(&dc->disp.disp_win_opt);
value |= HDMI_ENABLE;
writel(value, &dc->disp.disp_win_opt);
writel(GENERAL_UPDATE, &dc->cmd.state_ctrl);
writel(GENERAL_ACT_REQ, &dc->cmd.state_ctrl);
}
static void tegra_hdmi_setup_tmds(struct tegra_hdmi_priv *priv,
const struct tmds_config *tmds)
{
struct hdmi_ctlr *hdmi = priv->hdmi_regmap;
u32 value;
writel(tmds->pll0, &hdmi->nv_pdisp_sor_pll0);
writel(tmds->pll1, &hdmi->nv_pdisp_sor_pll1);
writel(tmds->pe_current, &hdmi->nv_pdisp_pe_current);
writel(tmds->drive_current, &hdmi->nv_pdisp_sor_lane_drive_current);
value = readl(&hdmi->nv_pdisp_sor_lane_drive_current);
value |= BIT(31);
writel(value, &hdmi->nv_pdisp_sor_lane_drive_current);
}
static int tegra_hdmi_encoder_enable(struct udevice *dev)
{
struct tegra_dc_plat *dc_plat = dev_get_plat(dev);
struct tegra_hdmi_priv *priv = dev_get_priv(dev);
struct dc_ctlr *dc = dc_plat->dc;
struct display_timing *dt = &priv->timing;
struct hdmi_ctlr *hdmi = priv->hdmi_regmap;
unsigned long rate, div82;
unsigned int pulse_start, rekey;
int retries = 1000;
u32 value;
int i;
/* power up sequence */
value = readl(&hdmi->nv_pdisp_sor_pll0);
value &= ~SOR_PLL_PDBG;
writel(value, &hdmi->nv_pdisp_sor_pll0);
udelay(20);
value = readl(&hdmi->nv_pdisp_sor_pll0);
value &= ~SOR_PLL_PWR;
writel(value, &hdmi->nv_pdisp_sor_pll0);
writel(VSYNC_H_POSITION(1), &dc->disp.disp_timing_opt);
writel(DITHER_CONTROL_DISABLE | BASE_COLOR_SIZE_888,
&dc->disp.disp_color_ctrl);
/* video_preamble uses h_pulse2 */
pulse_start = 1 + dt->hsync_len.typ + dt->hback_porch.typ - 10;
writel(H_PULSE2_ENABLE, &dc->disp.disp_signal_opt0);
value = PULSE_MODE_NORMAL | PULSE_POLARITY_HIGH |
PULSE_QUAL_VACTIVE | PULSE_LAST_END_A;
writel(value, &dc->disp.h_pulse[H_PULSE2].h_pulse_ctrl);
value = PULSE_START(pulse_start) | PULSE_END(pulse_start + 8);
writel(value, &dc->disp.h_pulse[H_PULSE2].h_pulse_pos[H_PULSE0_POSITION_A]);
value = VSYNC_WINDOW_END(0x210) | VSYNC_WINDOW_START(0x200) |
VSYNC_WINDOW_ENABLE;
writel(value, &hdmi->nv_pdisp_hdmi_vsync_window);
if (dc_plat->pipe)
value = HDMI_SRC_DISPLAYB;
else
value = HDMI_SRC_DISPLAYA;
if (dt->hactive.typ == 720 && (dt->vactive.typ == 480 ||
dt->vactive.typ == 576))
writel(value | ARM_VIDEO_RANGE_FULL,
&hdmi->nv_pdisp_input_control);
else
writel(value | ARM_VIDEO_RANGE_LIMITED,
&hdmi->nv_pdisp_input_control);
rate = clock_get_periph_rate(priv->clk->id, priv->clk_parent->id);
div82 = rate / USEC_PER_SEC * 4;
value = SOR_REFCLK_DIV_INT(div82 >> 2) | SOR_REFCLK_DIV_FRAC(div82);
writel(value, &hdmi->nv_pdisp_sor_refclk);
rekey = HDMI_REKEY_DEFAULT;
value = HDMI_CTRL_REKEY(rekey);
value |= HDMI_CTRL_MAX_AC_PACKET((dt->hsync_len.typ + dt->hback_porch.typ +
dt->hfront_porch.typ - rekey - 18) / 32);
writel(value, &hdmi->nv_pdisp_hdmi_ctrl);
/* TMDS CONFIG */
for (i = 0; i < priv->config->num_tmds; i++) {
if (dt->pixelclock.typ <= priv->config->tmds[i].pclk) {
tegra_hdmi_setup_tmds(priv, &priv->config->tmds[i]);
break;
}
}
writel(SOR_SEQ_PU_PC(0) | SOR_SEQ_PU_PC_ALT(0) | SOR_SEQ_PD_PC(8) |
SOR_SEQ_PD_PC_ALT(8), &hdmi->nv_pdisp_sor_seq_ctl);
value = SOR_SEQ_INST_WAIT_TIME(1) | SOR_SEQ_INST_WAIT_UNITS_VSYNC |
SOR_SEQ_INST_HALT | SOR_SEQ_INST_PIN_A_LOW |
SOR_SEQ_INST_PIN_B_LOW | SOR_SEQ_INST_DRIVE_PWM_OUT_LO;
writel(value, &hdmi->nv_pdisp_sor_seq_inst0);
writel(value, &hdmi->nv_pdisp_sor_seq_inst8);
value = readl(&hdmi->nv_pdisp_sor_cstm);
value &= ~SOR_CSTM_ROTCLK(~0);
value |= SOR_CSTM_ROTCLK(2);
value |= SOR_CSTM_PLLDIV;
value &= ~SOR_CSTM_LVDS_ENABLE;
value &= ~SOR_CSTM_MODE_MASK;
value |= SOR_CSTM_MODE_TMDS;
writel(value, &hdmi->nv_pdisp_sor_cstm);
/* start SOR */
writel(SOR_PWR_NORMAL_STATE_PU | SOR_PWR_NORMAL_START_NORMAL |
SOR_PWR_SAFE_STATE_PD | SOR_PWR_SETTING_NEW_TRIGGER,
&hdmi->nv_pdisp_sor_pwr);
writel(SOR_PWR_NORMAL_STATE_PU | SOR_PWR_NORMAL_START_NORMAL |
SOR_PWR_SAFE_STATE_PD | SOR_PWR_SETTING_NEW_DONE,
&hdmi->nv_pdisp_sor_pwr);
do {
if (--retries < 0)
return -ETIME;
value = readl(&hdmi->nv_pdisp_sor_pwr);
} while (value & SOR_PWR_SETTING_NEW_PENDING);
value = SOR_STATE_ASY_CRCMODE_COMPLETE |
SOR_STATE_ASY_OWNER_HEAD0 |
SOR_STATE_ASY_SUBOWNER_BOTH |
SOR_STATE_ASY_PROTOCOL_SINGLE_TMDS_A |
SOR_STATE_ASY_DEPOL_POS;
/* setup sync polarities */
if (dt->flags & DISPLAY_FLAGS_HSYNC_HIGH)
value |= SOR_STATE_ASY_HSYNCPOL_POS;
if (dt->flags & DISPLAY_FLAGS_HSYNC_LOW)
value |= SOR_STATE_ASY_HSYNCPOL_NEG;
if (dt->flags & DISPLAY_FLAGS_VSYNC_HIGH)
value |= SOR_STATE_ASY_VSYNCPOL_POS;
if (dt->flags & DISPLAY_FLAGS_VSYNC_LOW)
value |= SOR_STATE_ASY_VSYNCPOL_NEG;
writel(value, &hdmi->nv_pdisp_sor_state2);
value = SOR_STATE_ASY_HEAD_OPMODE_AWAKE | SOR_STATE_ASY_ORMODE_NORMAL;
writel(value, &hdmi->nv_pdisp_sor_state1);
writel(0, &hdmi->nv_pdisp_sor_state0);
writel(SOR_STATE_UPDATE, &hdmi->nv_pdisp_sor_state0);
writel(value | SOR_STATE_ATTACHED,
&hdmi->nv_pdisp_sor_state1);
writel(0, &hdmi->nv_pdisp_sor_state0);
tegra_dc_enable_controller(dev);
return 0;
}
/* DDC/CI backlight control */
static int tegra_hdmi_set_connector(struct udevice *dev, int percent)
{
struct tegra_hdmi_priv *priv = dev_get_priv(dev);
struct udevice *ddc_entry;
struct i2c_msg msg[1];
u8 checksum = DDCCI_ENTRY_ADDR << 1;
int i, ret;
ret = dm_i2c_probe(priv->hdmi_ddc, DDCCI_ENTRY_ADDR, 0, &ddc_entry);
if (ret) {
log_debug("%s: cannot probe DDC/CI entry: error %d\n",
__func__, ret);
return 0;
}
/*
* payload[1] is length: hithest bit OR last 4 bits indicate
* the number of following bytes (excluding checksum)
*/
u8 payload[7] = { DDCCI_SOURSE_ADDR, BIT(7) | (sizeof(payload) - 3),
DDCCI_COMMAND_WRITE, DDCCI_CTRL_BRIGHTNESS,
(u8)(percent & 0xff), (u8)(percent & 0xff), 0 };
/* DDC/CI checksum is a simple XOR of all preceding bytes */
for (i = 0; i < (sizeof(payload) - 1); i++)
checksum ^= payload[i];
payload[6] = checksum;
msg->addr = DDCCI_ENTRY_ADDR;
msg->flags = 0;
msg->len = sizeof(payload);
msg->buf = payload;
dm_i2c_xfer(ddc_entry, msg, 1);
return 0;
}
static int tegra_hdmi_timings(struct udevice *dev,
struct display_timing *timing)
{
struct tegra_hdmi_priv *priv = dev_get_priv(dev);
memcpy(timing, &priv->timing, sizeof(*timing));
return 0;
}
static void tegra_hdmi_init_clocks(struct udevice *dev)
{
struct tegra_hdmi_priv *priv = dev_get_priv(dev);
u32 n = priv->timing.pixelclock.typ * 2 / USEC_PER_SEC;
switch (clock_get_osc_freq()) {
case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
case CLOCK_OSC_FREQ_48_0: /* OSC is 48Mhz */
clock_set_rate(priv->clk_parent->id, n, 12, 0, 8);
break;
case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */
clock_set_rate(priv->clk_parent->id, n, 26, 0, 8);
break;
case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
case CLOCK_OSC_FREQ_16_8: /* OSC is 16.8Mhz */
clock_set_rate(priv->clk_parent->id, n, 13, 0, 8);
break;
case CLOCK_OSC_FREQ_19_2:
case CLOCK_OSC_FREQ_38_4:
default:
/*
* These are not supported.
*/
break;
}
clock_start_periph_pll(priv->clk->id, priv->clk_parent->id,
priv->timing.pixelclock.typ);
}
static bool tegra_hdmi_mode_valid(void *hdmi_priv, const struct display_timing *timing)
{
struct tegra_hdmi_priv *priv = hdmi_priv;
if (timing->pixelclock.typ > priv->config->max_pclk)
return false;
return true;
}
static int tegra_hdmi_decode_edid(struct udevice *dev)
{
struct tegra_hdmi_priv *priv = dev_get_priv(dev);
struct udevice *hdmi_edid;
uchar edid_buf[EDID_SIZE] = { 0 };
int i, ret;
/* Poll for 1 sec in case EDID is not ready right after hpd */
for (i = 0; i < 10; i++) {
ret = dm_i2c_probe(priv->hdmi_ddc, HDMI_EDID_I2C_ADDR, 0,
&hdmi_edid);
if (!ret)
break;
mdelay(100);
}
if (ret) {
log_debug("%s: cannot probe EDID: error %d\n",
__func__, ret);
return ret;
}
ret = dm_i2c_read(hdmi_edid, 0, edid_buf, sizeof(edid_buf));
if (ret) {
log_debug("%s: cannot dump EDID buffer: error %d\n",
__func__, ret);
return ret;
}
ret = edid_get_timing_validate(edid_buf, sizeof(edid_buf), &priv->timing,
&priv->panel_bits_per_colourp,
tegra_hdmi_mode_valid, priv);
if (ret) {
log_debug("%s: cannot decode EDID info: error %d\n",
__func__, ret);
return ret;
}
return 0;
}
static int tegra_hdmi_wait_hpd(struct tegra_hdmi_priv *priv)
{
int i;
/* Poll 1 second for HPD signal */
for (i = 0; i < 10; i++) {
if (dm_gpio_get_value(&priv->hpd))
return 0;
mdelay(100);
}
return -ETIMEDOUT;
}
static int tegra_hdmi_probe(struct udevice *dev)
{
struct tegra_hdmi_priv *priv = dev_get_priv(dev);
struct reset_ctl reset_ctl;
int i, ret;
priv->hdmi_regmap = (struct hdmi_ctlr *)dev_read_addr_ptr(dev);
if (!priv->hdmi_regmap) {
log_debug("%s: no display controller address\n", __func__);
return -EINVAL;
}
priv->config = (struct tegra_hdmi_config *)dev_get_driver_data(dev);
priv->clk = devm_clk_get(dev, NULL);
if (IS_ERR(priv->clk)) {
log_debug("%s: Could not get HDMI clock: %ld\n",
__func__, PTR_ERR(priv->clk));
return PTR_ERR(priv->clk);
}
priv->clk_parent = devm_clk_get(dev, "parent");
if (IS_ERR(priv->clk_parent)) {
log_debug("%s: Could not get HDMI clock parent: %ld\n",
__func__, PTR_ERR(priv->clk_parent));
return PTR_ERR(priv->clk_parent);
}
for (i = 0; i < ARRAY_SIZE(hdmi_supplies); i++) {
ret = device_get_supply_regulator(dev, hdmi_supplies[i],
&priv->supplies[i]);
if (ret) {
log_debug("%s: cannot get %s %d\n", __func__,
hdmi_supplies[i], ret);
if (ret != -ENOENT)
return log_ret(ret);
}
ret = regulator_set_enable_if_allowed(priv->supplies[i], true);
if (ret && ret != -ENOSYS) {
log_debug("%s: cannot enable %s: error %d\n",
__func__, hdmi_supplies[i], ret);
return ret;
}
}
ret = reset_get_by_name(dev, "hdmi", &reset_ctl);
if (ret) {
log_debug("%s: reset_get_by_name() failed: %d\n",
__func__, ret);
return ret;
}
ret = uclass_get_device_by_phandle(UCLASS_I2C, dev,
"nvidia,ddc-i2c-bus",
&priv->hdmi_ddc);
if (ret) {
log_debug("%s: cannot get hdmi ddc i2c bus: error %d\n",
__func__, ret);
return ret;
}
ret = gpio_request_by_name(dev, "nvidia,hpd-gpio", 0,
&priv->hpd, GPIOD_IS_IN);
if (ret) {
log_debug("%s: Could not decode hpd-gpios (%d)\n",
__func__, ret);
return ret;
}
/* wait for connector */
ret = tegra_hdmi_wait_hpd(priv);
if (ret) {
/* HPD failed, use default timings */
memcpy(&priv->timing, &default_720p_timing,
sizeof(default_720p_timing));
} else {
ret = tegra_hdmi_decode_edid(dev);
if (ret)
memcpy(&priv->timing, &default_720p_timing,
sizeof(default_720p_timing));
}
reset_assert(&reset_ctl);
tegra_hdmi_init_clocks(dev);
mdelay(2);
reset_deassert(&reset_ctl);
return 0;
}
static const struct tegra_hdmi_config tegra20_hdmi_config = {
.tmds = tegra20_tmds_config,
.num_tmds = ARRAY_SIZE(tegra20_tmds_config),
.max_pclk = 148500000, /* 1080p */
};
static const struct tegra_hdmi_config tegra30_hdmi_config = {
.tmds = tegra30_tmds_config,
.num_tmds = ARRAY_SIZE(tegra30_tmds_config),
.max_pclk = 148500000, /* 1080p */
};
static const struct video_bridge_ops tegra_hdmi_ops = {
.attach = tegra_hdmi_encoder_enable,
.set_backlight = tegra_hdmi_set_connector,
.get_display_timing = tegra_hdmi_timings,
};
static const struct udevice_id tegra_hdmi_ids[] = {
{
.compatible = "nvidia,tegra20-hdmi",
.data = (ulong)&tegra20_hdmi_config
}, {
.compatible = "nvidia,tegra30-hdmi",
.data = (ulong)&tegra30_hdmi_config
}, {
/* sentinel */
}
};
U_BOOT_DRIVER(tegra_hdmi) = {
.name = "tegra_hdmi",
.id = UCLASS_VIDEO_BRIDGE,
.of_match = tegra_hdmi_ids,
.ops = &tegra_hdmi_ops,
.probe = tegra_hdmi_probe,
.plat_auto = sizeof(struct tegra_dc_plat),
.priv_auto = sizeof(struct tegra_hdmi_priv),
};

View file

@ -0,0 +1,648 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2010
* NVIDIA Corporation <www.nvidia.com>
*/
#ifndef _TEGRA_HDMI_H
#define _TEGRA_HDMI_H
#ifndef __ASSEMBLY__
#include <linux/bitops.h>
#endif
/* Register definitions for the Tegra high-definition multimedia interface */
/* High-Definition Multimedia Interface (HDMI_) regs */
struct hdmi_ctlr {
/* Address 0x000 ~ 0x0d2 */
uint ctxsw; /* _CTXSW */ /* 0x00 */
uint nv_pdisp_sor_state0; /* _NV_PDISP_SOR_STATE0 */
uint nv_pdisp_sor_state1; /* _NV_PDISP_SOR_STATE1 */
uint nv_pdisp_sor_state2; /* _NV_PDISP_SOR_STATE2 */
uint nv_pdisp_rg_hdcp_an_msb; /* _NV_PDISP_RG_HDCP_AN_MSB */
uint nv_pdisp_rg_hdcp_an_lsb; /* _NV_PDISP_RG_HDCP_AN_LSB */
uint nv_pdisp_rg_hdcp_cn_msb; /* _NV_PDISP_RG_HDCP_CN_MSB */
uint nv_pdisp_rg_hdcp_cn_lsb; /* _NV_PDISP_RG_HDCP_CN_LSB */
uint nv_pdisp_rg_hdcp_aksv_msb; /* _NV_PDISP_RG_HDCP_AKSV_MSB */
uint nv_pdisp_rg_hdcp_aksv_lsb; /* _NV_PDISP_RG_HDCP_AKSV_LSB */
uint nv_pdisp_rg_hdcp_bksv_msb; /* _NV_PDISP_RG_HDCP_BKSV_MSB */
uint nv_pdisp_rg_hdcp_bksv_lsb; /* _NV_PDISP_RG_HDCP_BKSV_LSB */
uint nv_pdisp_rg_hdcp_cksv_msb; /* _NV_PDISP_RG_HDCP_CKSV_MSB */
uint nv_pdisp_rg_hdcp_cksv_lsb; /* _NV_PDISP_RG_HDCP_CKSV_LSB */
uint nv_pdisp_rg_hdcp_dksv_msb; /* _NV_PDISP_RG_HDCP_DKSV_MSB */
uint nv_pdisp_rg_hdcp_dksv_lsb; /* _NV_PDISP_RG_HDCP_DKSV_LSB */
uint nv_pdisp_rg_hdcp_ctrl; /* _NV_PDISP_RG_HDCP_CTRL */ /* 0x10 */
uint nv_pdisp_rg_hdcp_cmode; /* _NV_PDISP_RG_HDCP_CMODE */
uint nv_pdisp_rg_hdcp_mprime_msb; /* _NV_PDISP_RG_HDCP_MPRIME_MSB */
uint nv_pdisp_rg_hdcp_mprime_lsb; /* _NV_PDISP_RG_HDCP_MPRIME_LSB */
uint nv_pdisp_rg_hdcp_sprime_msb; /* _NV_PDISP_RG_HDCP_SPRIME_MSB */
uint nv_pdisp_rg_hdcp_sprime_lsb2; /* _NV_PDISP_RG_HDCP_SPRIME_LSB2 */
uint nv_pdisp_rg_hdcp_sprime_lsb1; /* _NV_PDISP_RG_HDCP_SPRIME_LSB1 */
uint nv_pdisp_rg_hdcp_ri; /* _NV_PDISP_RG_HDCP_RI */
uint nv_pdisp_rg_hdcp_cs_msb; /* _NV_PDISP_RG_HDCP_CS_MSB */
uint nv_pdisp_rg_hdcp_cs_lsb; /* _NV_PDISP_RG_HDCP_CS_LSB */
uint nv_pdisp_hdmi_audio_emu0; /* _NV_PDISP_HDMI_AUDIO_EMU0 */
uint nv_pdisp_hdmi_audio_emu_rdata0; /* _NV_PDISP_HDMI_AUDIO_EMU_RDATA0 */
uint nv_pdisp_hdmi_audio_emu1; /* _NV_PDISP_HDMI_AUDIO_EMU1 */
uint nv_pdisp_hdmi_audio_emu2; /* _NV_PDISP_HDMI_AUDIO_EMU2 */
uint nv_pdisp_hdmi_audio_infoframe_ctrl; /* _NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL */
uint nv_pdisp_hdmi_audio_infoframe_status; /* _NV_PDISP_HDMI_AUDIO_INFOFRAME_STATUS */
uint nv_pdisp_hdmi_audio_infoframe_header; /* _NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER */ /* 0x20 */
uint nv_pdisp_hdmi_audio_infoframe_subpack0_low; /* _NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_LOW */
uint nv_pdisp_hdmi_audio_infoframe_subpack0_high; /* _NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_HIGH */
uint nv_pdisp_hdmi_avi_infoframe_ctrl; /* _NV_PDISP_HDMI_AVI_INFOFRAME_CTRL */
uint nv_pdisp_hdmi_avi_infoframe_status; /* _NV_PDISP_HDMI_AVI_INFOFRAME_STATUS */
uint nv_pdisp_hdmi_avi_infoframe_header; /* _NV_PDISP_HDMI_AVI_INFOFRAME_HEADER */
uint nv_pdisp_hdmi_avi_infoframe_subpack0_low; /* _NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_LOW */
uint nv_pdisp_hdmi_avi_infoframe_subpack0_high; /* _NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH */
uint nv_pdisp_hdmi_avi_infoframe_subpack1_low; /* _NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_LOW */
uint nv_pdisp_hdmi_avi_infoframe_subpack1_high; /* _NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH */
uint nv_pdisp_hdmi_generic_ctrl; /* _NV_PDISP_HDMI_GENERIC_CTRL */
uint nv_pdisp_hdmi_generic_status; /* _NV_PDISP_HDMI_GENERIC_STATUS */
uint nv_pdisp_hdmi_generic_header; /* _NV_PDISP_HDMI_GENERIC_HEADER */
uint nv_pdisp_hdmi_generic_subpack0_low; /* _NV_PDISP_HDMI_GENERIC_SUBPACK0_LOW */
uint nv_pdisp_hdmi_generic_subpack0_high; /* _NV_PDISP_HDMI_GENERIC_SUBPACK0_HIGH */
uint nv_pdisp_hdmi_generic_subpack1_low; /* _NV_PDISP_HDMI_GENERIC_SUBPACK1_LOW */
uint nv_pdisp_hdmi_generic_subpack1_high; /* _NV_PDISP_HDMI_GENERIC_SUBPACK1_HIGH */
uint nv_pdisp_hdmi_generic_subpack2_low; /* _NV_PDISP_HDMI_GENERIC_SUBPACK2_LOW */
uint nv_pdisp_hdmi_generic_subpack2_high; /* _NV_PDISP_HDMI_GENERIC_SUBPACK2_HIGH */
uint nv_pdisp_hdmi_generic_subpack3_low; /* _NV_PDISP_HDMI_GENERIC_SUBPACK3_LOW */
uint nv_pdisp_hdmi_generic_subpack3_high; /* _NV_PDISP_HDMI_GENERIC_SUBPACK3_HIGH */
uint nv_pdisp_hdmi_acr_ctrl; /* _NV_PDISP_HDMI_ACR_CTRL */
uint nv_pdisp_hdmi_acr_0320_subpack_low; /* _NV_PDISP_HDMI_ACR_0320_SUBPACK_LOW */
uint nv_pdisp_hdmi_acr_0320_subpack_high; /* _NV_PDISP_HDMI_ACR_0320_SUBPACK_HIGH */
uint nv_pdisp_hdmi_acr_0441_subpack_low; /* _NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW */
uint nv_pdisp_hdmi_acr_0441_subpack_high; /* _NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH */
uint nv_pdisp_hdmi_acr_0882_subpack_low; /* _NV_PDISP_HDMI_ACR_0882_SUBPACK_LOW */
uint nv_pdisp_hdmi_acr_0882_subpack_high; /* _NV_PDISP_HDMI_ACR_0882_SUBPACK_HIGH */
uint nv_pdisp_hdmi_acr_1764_subpack_low; /* _NV_PDISP_HDMI_ACR_1764_SUBPACK_LOW */
uint nv_pdisp_hdmi_acr_1764_subpack_high; /* _NV_PDISP_HDMI_ACR_1764_SUBPACK_HIGH */
uint nv_pdisp_hdmi_acr_0480_subpack_low; /* _NV_PDISP_HDMI_ACR_0480_SUBPACK_LOW */
uint nv_pdisp_hdmi_acr_0480_subpack_high; /* _NV_PDISP_HDMI_ACR_0480_SUBPACK_HIGH */
uint nv_pdisp_hdmi_acr_0960_subpack_low; /* _NV_PDISP_HDMI_ACR_0960_SUBPACK_LOW */
uint nv_pdisp_hdmi_acr_0960_subpack_high; /* _NV_PDISP_HDMI_ACR_0960_SUBPACK_HIGH */
uint nv_pdisp_hdmi_acr_1920_subpack_low; /* _NV_PDISP_HDMI_ACR_1920_SUBPACK_LOW */
uint nv_pdisp_hdmi_acr_1920_subpack_high; /* _NV_PDISP_HDMI_ACR_1920_SUBPACK_HIGH */
uint nv_pdisp_hdmi_ctrl; /* _NV_PDISP_HDMI_CTRL */
uint nv_pdisp_hdmi_vsync_keepout; /* _NV_PDISP_HDMI_VSYNC_KEEPOUT */
uint nv_pdisp_hdmi_vsync_window; /* _NV_PDISP_HDMI_VSYNC_WINDOW */
uint nv_pdisp_hdmi_gcp_ctrl; /* _NV_PDISP_HDMI_GCP_CTRL */
uint nv_pdisp_hdmi_gcp_status; /* _NV_PDISP_HDMI_GCP_STATUS */
uint nv_pdisp_hdmi_gcp_subpack; /* _NV_PDISP_HDMI_GCP_SUBPACK */
uint nv_pdisp_hdmi_channel_status1; /* _NV_PDISP_HDMI_CHANNEL_STATUS1 */
uint nv_pdisp_hdmi_channel_status2; /* _NV_PDISP_HDMI_CHANNEL_STATUS2 */
uint nv_pdisp_hdmi_emu0; /* _NV_PDISP_HDMI_EMU0 */
uint nv_pdisp_hdmi_emu1; /* _NV_PDISP_HDMI_EMU1 */
uint nv_pdisp_hdmi_emu1_rdata; /* _NV_PDISP_HDMI_EMU1_RDATA */
uint nv_pdisp_hdmi_spare; /* _NV_PDISP_HDMI_SPARE */
uint nv_pdisp_hdmi_spdif_chn_status1; /* _NV_PDISP_HDMI_SPDIF_CHN_STATUS1 */
uint nv_pdisp_hdmi_spdif_chn_status2; /* _NV_PDISP_HDMI_SPDIF_CHN_STATUS2 */
uint nv_pdisp_hdcprif_rom_ctrl; /* _NV_PDISP_HDCPRIF_ROM_CTRL */
uint unused;
uint nv_pdisp_sor_cap; /* _NV_PDISP_SOR_CAP */
uint nv_pdisp_sor_pwr; /* _NV_PDISP_SOR_PWR */
uint nv_pdisp_sor_test; /* _NV_PDISP_SOR_TEST */
uint nv_pdisp_sor_pll0; /* _NV_PDISP_SOR_PLL0 */
uint nv_pdisp_sor_pll1; /* _NV_PDISP_SOR_PLL1 */
uint nv_pdisp_sor_pll2; /* _NV_PDISP_SOR_PLL2 */
uint nv_pdisp_sor_cstm; /* _NV_PDISP_SOR_CSTM */
uint nv_pdisp_sor_lvds; /* _NV_PDISP_SOR_LVDS */
uint nv_pdisp_sor_crca; /* _NV_PDISP_SOR_CRCA */
uint nv_pdisp_sor_crcb; /* _NV_PDISP_SOR_CRCB */
uint nv_pdisp_sor_blank; /* _NV_PDISP_SOR_BLANK */
uint nv_pdisp_sor_seq_ctl; /* _NV_PDISP_SOR_SEQ_CTL */
uint nv_pdisp_sor_seq_inst0; /* _NV_PDISP_SOR_SEQ_INST0 */
uint nv_pdisp_sor_seq_inst1; /* _NV_PDISP_SOR_SEQ_INST1 */
uint nv_pdisp_sor_seq_inst2; /* _NV_PDISP_SOR_SEQ_INST2 */
uint nv_pdisp_sor_seq_inst3; /* _NV_PDISP_SOR_SEQ_INST3 */
uint nv_pdisp_sor_seq_inst4; /* _NV_PDISP_SOR_SEQ_INST4 */
uint nv_pdisp_sor_seq_inst5; /* _NV_PDISP_SOR_SEQ_INST5 */
uint nv_pdisp_sor_seq_inst6; /* _NV_PDISP_SOR_SEQ_INST6 */
uint nv_pdisp_sor_seq_inst7; /* _NV_PDISP_SOR_SEQ_INST7 */
uint nv_pdisp_sor_seq_inst8; /* _NV_PDISP_SOR_SEQ_INST8 */
uint nv_pdisp_sor_seq_inst9; /* _NV_PDISP_SOR_SEQ_INST9 */
uint nv_pdisp_sor_seq_insta; /* _NV_PDISP_SOR_SEQ_INSTA */
uint nv_pdisp_sor_seq_instb; /* _NV_PDISP_SOR_SEQ_INSTB */
uint nv_pdisp_sor_seq_instc; /* _NV_PDISP_SOR_SEQ_INSTC */
uint nv_pdisp_sor_seq_instd; /* _NV_PDISP_SOR_SEQ_INSTD */
uint nv_pdisp_sor_seq_inste; /* _NV_PDISP_SOR_SEQ_INSTE */
uint nv_pdisp_sor_seq_instf; /* _NV_PDISP_SOR_SEQ_INSTF */
uint unused1[2];
uint nv_pdisp_sor_vcrca0; /* _NV_PDISP_SOR_VCRCA0 */
uint nv_pdisp_sor_vcrca1; /* _NV_PDISP_SOR_VCRCA1 */
uint nv_pdisp_sor_ccrca0; /* _NV_PDISP_SOR_CCRCA0 */
uint nv_pdisp_sor_ccrca1; /* _NV_PDISP_SOR_CCRCA1 */
uint nv_pdisp_sor_edataa0; /* _NV_PDISP_SOR_EDATAA0 */
uint nv_pdisp_sor_edataa1; /* _NV_PDISP_SOR_EDATAA1 */
uint nv_pdisp_sor_counta0; /* _NV_PDISP_SOR_COUNTA0 */
uint nv_pdisp_sor_counta1; /* _NV_PDISP_SOR_COUNTA1 */
uint nv_pdisp_sor_debuga0; /* _NV_PDISP_SOR_DEBUGA0 */
uint nv_pdisp_sor_debuga1; /* _NV_PDISP_SOR_DEBUGA1 */
uint nv_pdisp_sor_trig; /* _NV_PDISP_SOR_TRIG */
uint nv_pdisp_sor_mscheck; /* _NV_PDISP_SOR_MSCHECK */
uint nv_pdisp_sor_lane_drive_current; /* _NV_PDISP_SOR_LANE_DRIVE_CURRENT */
uint nv_pdisp_audio_debug0; /* _NV_PDISP_AUDIO_DEBUG0 0x7f */
uint nv_pdisp_audio_debug1; /* _NV_PDISP_AUDIO_DEBUG1 0x80 */
uint nv_pdisp_audio_debug2; /* _NV_PDISP_AUDIO_DEBUG2 0x81 */
uint nv_pdisp_audio_fs1; /* _NV_PDISP_AUDIO_FS1 0x82 */
uint nv_pdisp_audio_fs2; /* _NV_PDISP_AUDIO_FS2 */
uint nv_pdisp_audio_fs3; /* _NV_PDISP_AUDIO_FS3 */
uint nv_pdisp_audio_fs4; /* _NV_PDISP_AUDIO_FS4 */
uint nv_pdisp_audio_fs5; /* _NV_PDISP_AUDIO_FS5 */
uint nv_pdisp_audio_fs6; /* _NV_PDISP_AUDIO_FS6 */
uint nv_pdisp_audio_fs7; /* _NV_PDISP_AUDIO_FS7 0x88 */
uint nv_pdisp_audio_pulse_width; /* _NV_PDISP_AUDIO_PULSE_WIDTH */
uint nv_pdisp_audio_threshold; /* _NV_PDISP_AUDIO_THRESHOLD */
uint nv_pdisp_audio_cntrl0; /* _NV_PDISP_AUDIO_CNTRL0 */
uint nv_pdisp_audio_n; /* _NV_PDISP_AUDIO_N */
uint nv_pdisp_audio_nval[7]; /* _NV_PDISP_AUDIO_NVAL */
uint nv_pdisp_hdcprif_rom_timing; /* _NV_PDISP_HDCPRIF_ROM_TIMING */
uint nv_pdisp_sor_refclk; /* _NV_PDISP_SOR_REFCLK */
uint nv_pdisp_crc_control; /* _NV_PDISP_CRC_CONTROL */
uint nv_pdisp_input_control; /* _NV_PDISP_INPUT_CONTROL */
uint nv_pdisp_scratch; /* _NV_PDISP_SCRATCH */
uint nv_pdisp_pe_current; /* _NV_PDISP_PE_CURRENT */
uint nv_pdisp_key_ctrl; /* _NV_PDISP_KEY_CTRL */
uint nv_pdisp_key_debug0; /* _NV_PDISP_KEY_DEBUG0 */
uint nv_pdisp_key_debug1; /* _NV_PDISP_KEY_DEBUG1 */
uint nv_pdisp_key_debug2; /* _NV_PDISP_KEY_DEBUG2 */
uint nv_pdisp_key_hdcp_key_0; /* _NV_PDISP_KEY_HDCP_KEY_0 */
uint nv_pdisp_key_hdcp_key_1; /* _NV_PDISP_KEY_HDCP_KEY_1 */
uint nv_pdisp_key_hdcp_key_2; /* _NV_PDISP_KEY_HDCP_KEY_2 */
uint nv_pdisp_key_hdcp_key_3; /* _NV_PDISP_KEY_HDCP_KEY_3 */
uint nv_pdisp_key_hdcp_key_trig; /* _NV_PDISP_KEY_HDCP_KEY_3 */
uint nv_pdisp_key_skey_index; /* _NV_PDISP_KEY_HDCP_KEY_3 */ /* 0xa3 */
uint unused2[8];
uint nv_pdisp_sor_audio_cntrl0; /* _NV_PDISP_SOR_AUDIO_CNTRL0 */ /* 0xac */
uint nv_pdisp_sor_audio_debug; /* _NV_PDISP_SOR_AUDIO_DEBUG */
uint nv_pdisp_sor_audio_spare0; /* _NV_PDISP_SOR_AUDIO_SPARE0 */
uint nv_pdisp_sor_audio_nval[7]; /* _NV_PDISP_SOR_AUDIO_NVAL 0xaf ~ 0xb5 */
uint nv_pdisp_sor_audio_hda_scratch[4]; /* _NV_PDISP_SOR_AUDIO_HDA_SCRATCH 0xb6 ~ 0xb9 */
uint nv_pdisp_sor_audio_hda_codec_scratch[2]; /* _NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH 0xba ~ 0xbb */
uint nv_pdisp_sor_audio_hda_eld_bufwr; /* _NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR */
uint nv_pdisp_sor_audio_hda_presense; /* _NV_PDISP_SOR_AUDIO_HDA_PRESENSE */
uint nv_pdisp_sor_audio_hda_cp; /* _NV_PDISP_SOR_AUDIO_HDA_CP */
uint nv_pdisp_sor_audio_aval[8]; /* _NV_PDISP_SOR_AUDIO_AVAL */
uint nv_pdisp_sor_audio_gen_ctrl; /* _NV_PDISP_SOR_AUDIO_GEN_CTRL */
uint unused3[4];
uint nv_pdisp_int_status; /* _NV_PDISP_INT_STATUS */
uint nv_pdisp_int_mask; /* _NV_PDISP_INT_MASK */
uint nv_pdisp_int_enable; /* _NV_PDISP_INT_ENABLE */
uint unused4[2];
uint nv_pdisp_sor_io_peak_current; /* _NV_PDISP_SOR_IO_PEAK_CURRENT */
uint nv_pdisp_sor_pad_ctls0; /* _NV_PDISP_SOR_PAD_CTLS0 */
};
/* HDMI_NV_PDISP_SOR_STATE0 0x01 */
#define SOR_STATE_UPDATE BIT(0)
/* HDMI_NV_PDISP_SOR_STATE1 0x02 */
#define SOR_STATE_ASY_HEAD_OPMODE_AWAKE BIT(1)
#define SOR_STATE_ASY_ORMODE_NORMAL BIT(2)
#define SOR_STATE_ATTACHED BIT(3)
/* HDMI_NV_PDISP_SOR_STATE2 0x03 */
#define SOR_STATE_ASY_OWNER_NONE (0 << 0)
#define SOR_STATE_ASY_OWNER_HEAD0 (1 << 0)
#define SOR_STATE_ASY_SUBOWNER_NONE (0 << 4)
#define SOR_STATE_ASY_SUBOWNER_SUBHEAD0 (1 << 4)
#define SOR_STATE_ASY_SUBOWNER_SUBHEAD1 (2 << 4)
#define SOR_STATE_ASY_SUBOWNER_BOTH (3 << 4)
#define SOR_STATE_ASY_CRCMODE_ACTIVE (0 << 6)
#define SOR_STATE_ASY_CRCMODE_COMPLETE (1 << 6)
#define SOR_STATE_ASY_CRCMODE_NON_ACTIVE (2 << 6)
#define SOR_STATE_ASY_PROTOCOL_SINGLE_TMDS_A (1 << 8)
#define SOR_STATE_ASY_PROTOCOL_CUSTOM (15 << 8)
#define SOR_STATE_ASY_HSYNCPOL_POS (0 << 12)
#define SOR_STATE_ASY_HSYNCPOL_NEG (1 << 12)
#define SOR_STATE_ASY_VSYNCPOL_POS (0 << 13)
#define SOR_STATE_ASY_VSYNCPOL_NEG (1 << 13)
#define SOR_STATE_ASY_DEPOL_POS (0 << 14)
#define SOR_STATE_ASY_DEPOL_NEG (1 << 14)
#define INFOFRAME_CTRL_ENABLE BIT(0)
#define INFOFRAME_HEADER_TYPE(x) (((x) & 0xff) << 0)
#define INFOFRAME_HEADER_VERSION(x) (((x) & 0xff) << 8)
#define INFOFRAME_HEADER_LEN(x) (((x) & 0x0f) << 16)
/* HDMI_NV_PDISP_HDMI_GENERIC_CTRL 0x2a */
#define GENERIC_CTRL_ENABLE BIT(0)
#define GENERIC_CTRL_OTHER BIT(4)
#define GENERIC_CTRL_SINGLE BIT(8)
#define GENERIC_CTRL_HBLANK BIT(12)
#define GENERIC_CTRL_AUDIO BIT(16)
/* HDMI_NV_PDISP_HDMI_ACR_* */
#define ACR_SUBPACK_CTS(x) (((x) & 0xffffff) << 8)
#define ACR_SUBPACK_N(x) (((x) & 0xffffff) << 0)
#define ACR_ENABLE BIT(31)
/* HDMI_NV_PDISP_HDMI_CTRL 0x44 */
#define HDMI_CTRL_REKEY(x) (((x) & 0x7f) << 0)
#define HDMI_CTRL_MAX_AC_PACKET(x) (((x) & 0x1f) << 16)
#define HDMI_CTRL_ENABLE BIT(30)
/* HDMI_NV_PDISP_HDMI_VSYNC_* */
#define VSYNC_WINDOW_END(x) (((x) & 0x3ff) << 0)
#define VSYNC_WINDOW_START(x) (((x) & 0x3ff) << 16)
#define VSYNC_WINDOW_ENABLE BIT(31)
/* HDMI_NV_PDISP_HDMI_SPARE 0x4f */
#define SPARE_HW_CTS BIT(0)
#define SPARE_FORCE_SW_CTS BIT(1)
#define SPARE_CTS_RESET_VAL(x) (((x) & 0x7) << 16)
/* HDMI_NV_PDISP_SOR_PWR 0x55 */
#define SOR_PWR_NORMAL_STATE_PD (0 << 0)
#define SOR_PWR_NORMAL_STATE_PU (1 << 0)
#define SOR_PWR_NORMAL_START_NORMAL (0 << 1)
#define SOR_PWR_NORMAL_START_ALT (1 << 1)
#define SOR_PWR_SAFE_STATE_PD (0 << 16)
#define SOR_PWR_SAFE_STATE_PU (1 << 16)
#define SOR_PWR_SETTING_NEW_DONE (0 << 31)
#define SOR_PWR_SETTING_NEW_PENDING (1 << 31)
#define SOR_PWR_SETTING_NEW_TRIGGER (1 << 31)
/* HDMI_NV_PDISP_SOR_PLL0 0x57 */
#define SOR_PLL_PWR BIT(0)
#define SOR_PLL_PDBG BIT(1)
#define SOR_PLL_VCAPD BIT(2)
#define SOR_PLL_PDPORT BIT(3)
#define SOR_PLL_RESISTORSEL BIT(4)
#define SOR_PLL_PULLDOWN BIT(5)
#define SOR_PLL_VCOCAP(x) (((x) & 0xf) << 8)
#define SOR_PLL_BG_V17_S(x) (((x) & 0xf) << 12)
#define SOR_PLL_FILTER(x) (((x) & 0xf) << 16)
#define SOR_PLL_ICHPMP(x) (((x) & 0xf) << 24)
#define SOR_PLL_TX_REG_LOAD(x) (((x) & 0xf) << 28)
/* HDMI_NV_PDISP_SOR_PLL1 0x58 */
#define SOR_PLL_TMDS_TERM_ENABLE BIT(8)
#define SOR_PLL_TMDS_TERMADJ(x) (((x) & 0xf) << 9)
#define SOR_PLL_LOADADJ(x) (((x) & 0xf) << 20)
#define SOR_PLL_PE_EN BIT(28)
#define SOR_PLL_HALF_FULL_PE BIT(29)
#define SOR_PLL_S_D_PIN_PE BIT(30)
/* HDMI_NV_PDISP_SOR_CSTM 0x5a */
#define SOR_CSTM_ROTCLK(x) (((x) & 0xf) << 24)
#define SOR_CSTM_PLLDIV BIT(21)
#define SOR_CSTM_LVDS_ENABLE BIT(16)
#define SOR_CSTM_MODE_LVDS (0 << 12)
#define SOR_CSTM_MODE_TMDS (1 << 12)
#define SOR_CSTM_MODE_MASK (3 << 12)
/* HDMI_NV_PDISP_SOR_SEQ_CTL 0x5f */
#define SOR_SEQ_PU_PC(x) (((x) & 0xf) << 0)
#define SOR_SEQ_PU_PC_ALT(x) (((x) & 0xf) << 4)
#define SOR_SEQ_PD_PC(x) (((x) & 0xf) << 8)
#define SOR_SEQ_PD_PC_ALT(x) (((x) & 0xf) << 12)
#define SOR_SEQ_PC(x) (((x) & 0xf) << 16)
#define SOR_SEQ_STATUS BIT(28)
#define SOR_SEQ_SWITCH BIT(30)
/* HDMI_NV_PDISP_SOR_SEQ_INST(x) (0x60 + (x)) */
#define SOR_SEQ_INST_WAIT_TIME(x) (((x) & 0x3ff) << 0)
#define SOR_SEQ_INST_WAIT_UNITS_VSYNC (2 << 12)
#define SOR_SEQ_INST_HALT (1 << 15)
#define SOR_SEQ_INST_PIN_A_LOW (0 << 21)
#define SOR_SEQ_INST_PIN_A_HIGH (1 << 21)
#define SOR_SEQ_INST_PIN_B_LOW (0 << 22)
#define SOR_SEQ_INST_PIN_B_HIGH (1 << 22)
#define SOR_SEQ_INST_DRIVE_PWM_OUT_LO (1 << 23)
/* HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT 0x7e */
#define DRIVE_CURRENT_LANE0(x) (((x) & 0x3f) << 0)
#define DRIVE_CURRENT_LANE1(x) (((x) & 0x3f) << 8)
#define DRIVE_CURRENT_LANE2(x) (((x) & 0x3f) << 16)
#define DRIVE_CURRENT_LANE3(x) (((x) & 0x3f) << 24)
#define DRIVE_CURRENT_LANE0_T114(x) (((x) & 0x7f) << 0)
#define DRIVE_CURRENT_LANE1_T114(x) (((x) & 0x7f) << 8)
#define DRIVE_CURRENT_LANE2_T114(x) (((x) & 0x7f) << 16)
#define DRIVE_CURRENT_LANE3_T114(x) (((x) & 0x7f) << 24)
/* Drive current list */
enum {
DRIVE_CURRENT_1_500_mA,
DRIVE_CURRENT_1_875_mA,
DRIVE_CURRENT_2_250_mA,
DRIVE_CURRENT_2_625_mA,
DRIVE_CURRENT_3_000_mA,
DRIVE_CURRENT_3_375_mA,
DRIVE_CURRENT_3_750_mA,
DRIVE_CURRENT_4_125_mA,
DRIVE_CURRENT_4_500_mA,
DRIVE_CURRENT_4_875_mA,
DRIVE_CURRENT_5_250_mA,
DRIVE_CURRENT_5_625_mA,
DRIVE_CURRENT_6_000_mA,
DRIVE_CURRENT_6_375_mA,
DRIVE_CURRENT_6_750_mA,
DRIVE_CURRENT_7_125_mA,
DRIVE_CURRENT_7_500_mA,
DRIVE_CURRENT_7_875_mA,
DRIVE_CURRENT_8_250_mA,
DRIVE_CURRENT_8_625_mA,
DRIVE_CURRENT_9_000_mA,
DRIVE_CURRENT_9_375_mA,
DRIVE_CURRENT_9_750_mA,
DRIVE_CURRENT_10_125_mA,
DRIVE_CURRENT_10_500_mA,
DRIVE_CURRENT_10_875_mA,
DRIVE_CURRENT_11_250_mA,
DRIVE_CURRENT_11_625_mA,
DRIVE_CURRENT_12_000_mA,
DRIVE_CURRENT_12_375_mA,
DRIVE_CURRENT_12_750_mA,
DRIVE_CURRENT_13_125_mA,
DRIVE_CURRENT_13_500_mA,
DRIVE_CURRENT_13_875_mA,
DRIVE_CURRENT_14_250_mA,
DRIVE_CURRENT_14_625_mA,
DRIVE_CURRENT_15_000_mA,
DRIVE_CURRENT_15_375_mA,
DRIVE_CURRENT_15_750_mA,
DRIVE_CURRENT_16_125_mA,
DRIVE_CURRENT_16_500_mA,
DRIVE_CURRENT_16_875_mA,
DRIVE_CURRENT_17_250_mA,
DRIVE_CURRENT_17_625_mA,
DRIVE_CURRENT_18_000_mA,
DRIVE_CURRENT_18_375_mA,
DRIVE_CURRENT_18_750_mA,
DRIVE_CURRENT_19_125_mA,
DRIVE_CURRENT_19_500_mA,
DRIVE_CURRENT_19_875_mA,
DRIVE_CURRENT_20_250_mA,
DRIVE_CURRENT_20_625_mA,
DRIVE_CURRENT_21_000_mA,
DRIVE_CURRENT_21_375_mA,
DRIVE_CURRENT_21_750_mA,
DRIVE_CURRENT_22_125_mA,
DRIVE_CURRENT_22_500_mA,
DRIVE_CURRENT_22_875_mA,
DRIVE_CURRENT_23_250_mA,
DRIVE_CURRENT_23_625_mA,
DRIVE_CURRENT_24_000_mA,
DRIVE_CURRENT_24_375_mA,
DRIVE_CURRENT_24_750_mA,
};
/* Drive current list for T114 */
enum {
DRIVE_CURRENT_0_000_mA_T114,
DRIVE_CURRENT_0_400_mA_T114,
DRIVE_CURRENT_0_800_mA_T114,
DRIVE_CURRENT_1_200_mA_T114,
DRIVE_CURRENT_1_600_mA_T114,
DRIVE_CURRENT_2_000_mA_T114,
DRIVE_CURRENT_2_400_mA_T114,
DRIVE_CURRENT_2_800_mA_T114,
DRIVE_CURRENT_3_200_mA_T114,
DRIVE_CURRENT_3_600_mA_T114,
DRIVE_CURRENT_4_000_mA_T114,
DRIVE_CURRENT_4_400_mA_T114,
DRIVE_CURRENT_4_800_mA_T114,
DRIVE_CURRENT_5_200_mA_T114,
DRIVE_CURRENT_5_600_mA_T114,
DRIVE_CURRENT_6_000_mA_T114,
DRIVE_CURRENT_6_400_mA_T114,
DRIVE_CURRENT_6_800_mA_T114,
DRIVE_CURRENT_7_200_mA_T114,
DRIVE_CURRENT_7_600_mA_T114,
DRIVE_CURRENT_8_000_mA_T114,
DRIVE_CURRENT_8_400_mA_T114,
DRIVE_CURRENT_8_800_mA_T114,
DRIVE_CURRENT_9_200_mA_T114,
DRIVE_CURRENT_9_600_mA_T114,
DRIVE_CURRENT_10_000_mA_T114,
DRIVE_CURRENT_10_400_mA_T114,
DRIVE_CURRENT_10_800_mA_T114,
DRIVE_CURRENT_11_200_mA_T114,
DRIVE_CURRENT_11_600_mA_T114,
DRIVE_CURRENT_12_000_mA_T114,
DRIVE_CURRENT_12_400_mA_T114,
DRIVE_CURRENT_12_800_mA_T114,
DRIVE_CURRENT_13_200_mA_T114,
DRIVE_CURRENT_13_600_mA_T114,
DRIVE_CURRENT_14_000_mA_T114,
DRIVE_CURRENT_14_400_mA_T114,
DRIVE_CURRENT_14_800_mA_T114,
DRIVE_CURRENT_15_200_mA_T114,
DRIVE_CURRENT_15_600_mA_T114,
DRIVE_CURRENT_16_000_mA_T114,
DRIVE_CURRENT_16_400_mA_T114,
DRIVE_CURRENT_16_800_mA_T114,
DRIVE_CURRENT_17_200_mA_T114,
DRIVE_CURRENT_17_600_mA_T114,
DRIVE_CURRENT_18_000_mA_T114,
DRIVE_CURRENT_18_400_mA_T114,
DRIVE_CURRENT_18_800_mA_T114,
DRIVE_CURRENT_19_200_mA_T114,
DRIVE_CURRENT_19_600_mA_T114,
DRIVE_CURRENT_20_000_mA_T114,
DRIVE_CURRENT_20_400_mA_T114,
DRIVE_CURRENT_20_800_mA_T114,
DRIVE_CURRENT_21_200_mA_T114,
DRIVE_CURRENT_21_600_mA_T114,
DRIVE_CURRENT_22_000_mA_T114,
DRIVE_CURRENT_22_400_mA_T114,
DRIVE_CURRENT_22_800_mA_T114,
DRIVE_CURRENT_23_200_mA_T114,
DRIVE_CURRENT_23_600_mA_T114,
DRIVE_CURRENT_24_000_mA_T114,
DRIVE_CURRENT_24_400_mA_T114,
DRIVE_CURRENT_24_800_mA_T114,
DRIVE_CURRENT_25_200_mA_T114,
DRIVE_CURRENT_25_400_mA_T114,
DRIVE_CURRENT_25_800_mA_T114,
DRIVE_CURRENT_26_200_mA_T114,
DRIVE_CURRENT_26_600_mA_T114,
DRIVE_CURRENT_27_000_mA_T114,
DRIVE_CURRENT_27_400_mA_T114,
DRIVE_CURRENT_27_800_mA_T114,
DRIVE_CURRENT_28_200_mA_T114,
};
/* HDMI_NV_PDISP_AUDIO_FS */
#define AUDIO_FS_LOW(x) (((x) & 0xfff) << 0)
#define AUDIO_FS_HIGH(x) (((x) & 0xfff) << 16)
/* HDMI_NV_PDISP_AUDIO_CNTRL0 0x8b */
#define AUDIO_CNTRL0_ERROR_TOLERANCE(x) (((x) & 0xff) << 0)
#define AUDIO_CNTRL0_SOURCE_SELECT_AUTO (0 << 20)
#define AUDIO_CNTRL0_SOURCE_SELECT_SPDIF (1 << 20)
#define AUDIO_CNTRL0_SOURCE_SELECT_HDAL (2 << 20)
#define AUDIO_CNTRL0_FRAMES_PER_BLOCK(x) (((x) & 0xff) << 24)
/* HDMI_NV_PDISP_AUDIO_N 0x8c */
#define AUDIO_N_VALUE(x) (((x) & 0xfffff) << 0)
#define AUDIO_N_RESETF (1 << 20)
#define AUDIO_N_GENERATE_NORMAL (0 << 24)
#define AUDIO_N_GENERATE_ALTERNATE (1 << 24)
/* HDMI_NV_PDISP_SOR_REFCLK 0x95 */
#define SOR_REFCLK_DIV_INT(x) (((x) & 0xff) << 8)
#define SOR_REFCLK_DIV_FRAC(x) (((x) & 0x03) << 6)
/* HDMI_NV_PDISP_INPUT_CONTROL 0x97 */
#define HDMI_SRC_DISPLAYA (0 << 0)
#define HDMI_SRC_DISPLAYB (1 << 0)
#define ARM_VIDEO_RANGE_FULL (0 << 1)
#define ARM_VIDEO_RANGE_LIMITED (1 << 1)
/* HDMI_NV_PDISP_PE_CURRENT 0x99 */
#define PE_CURRENT0(x) (((x) & 0xf) << 0)
#define PE_CURRENT1(x) (((x) & 0xf) << 8)
#define PE_CURRENT2(x) (((x) & 0xf) << 16)
#define PE_CURRENT3(x) (((x) & 0xf) << 24)
enum {
PE_CURRENT_0_0_mA,
PE_CURRENT_0_5_mA,
PE_CURRENT_1_0_mA,
PE_CURRENT_1_5_mA,
PE_CURRENT_2_0_mA,
PE_CURRENT_2_5_mA,
PE_CURRENT_3_0_mA,
PE_CURRENT_3_5_mA,
PE_CURRENT_4_0_mA,
PE_CURRENT_4_5_mA,
PE_CURRENT_5_0_mA,
PE_CURRENT_5_5_mA,
PE_CURRENT_6_0_mA,
PE_CURRENT_6_5_mA,
PE_CURRENT_7_0_mA,
PE_CURRENT_7_5_mA,
};
enum {
PE_CURRENT_0_mA_T114,
PE_CURRENT_1_mA_T114,
PE_CURRENT_2_mA_T114,
PE_CURRENT_3_mA_T114,
PE_CURRENT_4_mA_T114,
PE_CURRENT_5_mA_T114,
PE_CURRENT_6_mA_T114,
PE_CURRENT_7_mA_T114,
PE_CURRENT_8_mA_T114,
PE_CURRENT_9_mA_T114,
PE_CURRENT_10_mA_T114,
PE_CURRENT_11_mA_T114,
PE_CURRENT_12_mA_T114,
PE_CURRENT_13_mA_T114,
PE_CURRENT_14_mA_T114,
PE_CURRENT_15_mA_T114,
};
/* HDMI_NV_PDISP_SOR_AUDIO_CNTRL0 0xac */
#define SOR_AUDIO_CNTRL0_SOURCE_SELECT_AUTO (0 << 20)
#define SOR_AUDIO_CNTRL0_SOURCE_SELECT_SPDIF (1 << 20)
#define SOR_AUDIO_CNTRL0_SOURCE_SELECT_HDAL (2 << 20)
#define SOR_AUDIO_CNTRL0_INJECT_NULLSMPL (1 << 29)
/* HDMI_NV_PDISP_SOR_AUDIO_SPARE0 0xae */
#define SOR_AUDIO_SPARE0_HBR_ENABLE BIT(27)
/* HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH0 0xba */
#define SOR_AUDIO_HDA_CODEC_SCRATCH0_VALID BIT(30)
#define SOR_AUDIO_HDA_CODEC_SCRATCH0_FMT_MASK 0xffff
/* HDMI_NV_PDISP_SOR_AUDIO_HDA_PRESENSE 0xbd */
#define SOR_AUDIO_HDA_PRESENSE_VALID BIT(1)
#define SOR_AUDIO_HDA_PRESENSE_PRESENT BIT(0)
/* HDMI_NV_PDISP_INT_STATUS 0xcc */
#define INT_SCRATCH BIT(3)
#define INT_CP_REQUEST BIT(2)
#define INT_CODEC_SCRATCH1 BIT(1)
#define INT_CODEC_SCRATCH0 BIT(0)
/* HDMI_NV_PDISP_SOR_IO_PEAK_CURRENT 0xd1 */
#define PEAK_CURRENT_LANE0(x) (((x) & 0x7f) << 0)
#define PEAK_CURRENT_LANE1(x) (((x) & 0x7f) << 8)
#define PEAK_CURRENT_LANE2(x) (((x) & 0x7f) << 16)
#define PEAK_CURRENT_LANE3(x) (((x) & 0x7f) << 24)
enum {
PEAK_CURRENT_0_000_mA,
PEAK_CURRENT_0_200_mA,
PEAK_CURRENT_0_400_mA,
PEAK_CURRENT_0_600_mA,
PEAK_CURRENT_0_800_mA,
PEAK_CURRENT_1_000_mA,
PEAK_CURRENT_1_200_mA,
PEAK_CURRENT_1_400_mA,
PEAK_CURRENT_1_600_mA,
PEAK_CURRENT_1_800_mA,
PEAK_CURRENT_2_000_mA,
PEAK_CURRENT_2_200_mA,
PEAK_CURRENT_2_400_mA,
PEAK_CURRENT_2_600_mA,
PEAK_CURRENT_2_800_mA,
PEAK_CURRENT_3_000_mA,
PEAK_CURRENT_3_200_mA,
PEAK_CURRENT_3_400_mA,
PEAK_CURRENT_3_600_mA,
PEAK_CURRENT_3_800_mA,
PEAK_CURRENT_4_000_mA,
PEAK_CURRENT_4_200_mA,
PEAK_CURRENT_4_400_mA,
PEAK_CURRENT_4_600_mA,
PEAK_CURRENT_4_800_mA,
PEAK_CURRENT_5_000_mA,
PEAK_CURRENT_5_200_mA,
PEAK_CURRENT_5_400_mA,
PEAK_CURRENT_5_600_mA,
PEAK_CURRENT_5_800_mA,
PEAK_CURRENT_6_000_mA,
PEAK_CURRENT_6_200_mA,
PEAK_CURRENT_6_400_mA,
PEAK_CURRENT_6_600_mA,
PEAK_CURRENT_6_800_mA,
PEAK_CURRENT_7_000_mA,
PEAK_CURRENT_7_200_mA,
PEAK_CURRENT_7_400_mA,
PEAK_CURRENT_7_600_mA,
PEAK_CURRENT_7_800_mA,
PEAK_CURRENT_8_000_mA,
PEAK_CURRENT_8_200_mA,
PEAK_CURRENT_8_400_mA,
PEAK_CURRENT_8_600_mA,
PEAK_CURRENT_8_800_mA,
PEAK_CURRENT_9_000_mA,
PEAK_CURRENT_9_200_mA,
PEAK_CURRENT_9_400_mA,
};
#endif /* _TEGRA_HDMI_H */

View file

@ -0,0 +1,86 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (c) 2025 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <clk.h>
#include <log.h>
#include <reset.h>
#include <linux/delay.h>
#include <asm/arch/clock.h>
#include <asm/arch-tegra/clk_rst.h>
struct tegra_host1x_info {
u32 clk_parent;
u32 rate;
};
static int tegra_host1x_probe(struct udevice *dev)
{
struct clk *clk;
struct reset_ctl reset_ctl;
const struct tegra_host1x_info *info;
int ret;
clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk)) {
log_debug("%s: cannot get HOST1X clock: %ld\n",
__func__, PTR_ERR(clk));
return PTR_ERR(clk);
}
ret = reset_get_by_name(dev, "host1x", &reset_ctl);
if (ret) {
log_debug("%s: cannot get HOST1X reset: %d\n",
__func__, ret);
return ret;
}
info = (struct tegra_host1x_info *)dev_get_driver_data(dev);
reset_assert(&reset_ctl);
clock_start_periph_pll(clk->id, info->clk_parent, info->rate);
mdelay(2);
reset_deassert(&reset_ctl);
return 0;
}
static const struct tegra_host1x_info tegra20_host1x_info = {
.clk_parent = CLOCK_ID_CGENERAL,
.rate = 150000000, /* 150 MHz */
};
static const struct tegra_host1x_info tegra114_host1x_info = {
.clk_parent = CLOCK_ID_PERIPH,
.rate = 136000000, /* 136 MHz */
};
static const struct udevice_id tegra_host1x_ids[] = {
{
.compatible = "nvidia,tegra20-host1x",
.data = (ulong)&tegra20_host1x_info
}, {
.compatible = "nvidia,tegra30-host1x",
.data = (ulong)&tegra20_host1x_info
}, {
.compatible = "nvidia,tegra114-host1x",
.data = (ulong)&tegra114_host1x_info
}, {
.compatible = "nvidia,tegra124-host1x",
.data = (ulong)&tegra114_host1x_info
}, {
/* sentinel */
}
};
U_BOOT_DRIVER(tegra_host1x) = {
.name = "tegra_host1x",
.id = UCLASS_SIMPLE_BUS,
.of_match = tegra_host1x_ids,
.probe = tegra_host1x_probe,
.flags = DM_FLAG_PRE_RELOC,
};

View file

@ -17,9 +17,6 @@
#include "tegra-dc.h" #include "tegra-dc.h"
#define TEGRA_DISPLAY_A_BASE 0x54200000
#define TEGRA_DISPLAY_B_BASE 0x54240000
#define TEGRA_PWM_BL_MIN_BRIGHTNESS 0x10 #define TEGRA_PWM_BL_MIN_BRIGHTNESS 0x10
#define TEGRA_PWM_BL_MAX_BRIGHTNESS 0xFF #define TEGRA_PWM_BL_MAX_BRIGHTNESS 0xFF
@ -106,14 +103,11 @@ static int tegra_pwm_backlight_enable(struct udevice *dev)
static int tegra_pwm_backlight_probe(struct udevice *dev) static int tegra_pwm_backlight_probe(struct udevice *dev)
{ {
struct tegra_pwm_backlight_priv *priv = dev_get_priv(dev); struct tegra_pwm_backlight_priv *priv = dev_get_priv(dev);
ofnode dc = ofnode_get_parent(dev_ofnode(dev));
if (dev_read_bool(dev, "nvidia,display-b-base")) priv->dc = (struct dc_ctlr *)ofnode_get_addr(dc);
priv->dc = (struct dc_ctlr *)TEGRA_DISPLAY_B_BASE;
else
priv->dc = (struct dc_ctlr *)TEGRA_DISPLAY_A_BASE;
if (!priv->dc) { if (!priv->dc) {
log_err("no display controller address\n"); log_err("%s: failed to get DC controller\n", __func__);
return -EINVAL; return -EINVAL;
} }

23
include/configs/ouya.h Normal file
View file

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* (C) Copyright 2010,2012
* NVIDIA Corporation <www.nvidia.com>
*
* (C) Copyright 2025
* Svyatoslav Ryhel <clamor95@gmail.com>
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#include "tegra30-common.h"
/* High-level configuration options */
#define CFG_TEGRA_BOARD_STRING "Ouya Game Console"
/* Board-specific serial config */
#define CFG_SYS_NS16550_COM1 NV_PA_APB_UARTD_BASE
#include "tegra-common-post.h"
#endif /* __CONFIG_H */

View file

@ -3,6 +3,7 @@ boot_block_size=0x1000
bootloader_file=u-boot-dtb-tegra.bin bootloader_file=u-boot-dtb-tegra.bin
spi_size=0x400000 spi_size=0x400000
boot_dev=0 boot_dev=0
boot_interface=mmc
flash_uboot=echo Preparing RAM; flash_uboot=echo Preparing RAM;
mw ${kernel_addr_r} 0 ${boot_block_size_r}; mw ${kernel_addr_r} 0 ${boot_block_size_r};
@ -11,9 +12,9 @@ flash_uboot=echo Preparing RAM;
mmc dev 0 1; mmc dev 0 1;
mmc read ${kernel_addr_r} 0 ${boot_block_size}; mmc read ${kernel_addr_r} 0 ${boot_block_size};
echo Reading bootloader; echo Reading bootloader;
if load mmc ${boot_dev}:1 ${ramdisk_addr_r} ${bootloader_file}; if load ${boot_interface} ${boot_dev}:1 ${ramdisk_addr_r} ${bootloader_file};
then echo Calculating bootloader size; then echo Calculating bootloader size;
size mmc ${boot_dev}:1 ${bootloader_file}; size ${boot_interface} ${boot_dev}:1 ${bootloader_file};
ebtupdate ${kernel_addr_r} ${ramdisk_addr_r} ${filesize}; ebtupdate ${kernel_addr_r} ${ramdisk_addr_r} ${filesize};
echo Writing bootloader to eMMC; echo Writing bootloader to eMMC;
mmc dev 0 1; mmc dev 0 1;