Merge branch '2023-11-03-assorted-tegra-improvements'

- Assorted improvements for Tegra platforms
This commit is contained in:
Tom Rini 2023-11-04 09:55:39 -04:00
commit a4c83bda17
67 changed files with 2650 additions and 215 deletions

View File

@ -704,6 +704,8 @@
clock-names = "sdhci";
resets = <&tegra_car 14>;
reset-names = "sdhci";
nvidia,default-tap = <0x2>;
nvidia,default-trim = <0x4>;
status = "disabled";
};
@ -715,6 +717,8 @@
clock-names = "sdhci";
resets = <&tegra_car 9>;
reset-names = "sdhci";
nvidia,default-tap = <0x8>;
nvidia,default-trim = <0x0>;
status = "disabled";
};
@ -726,6 +730,8 @@
clock-names = "sdhci";
resets = <&tegra_car 69>;
reset-names = "sdhci";
nvidia,default-tap = <0x3>;
nvidia,default-trim = <0x3>;
status = "disabled";
};
@ -737,6 +743,8 @@
clock-names = "sdhci";
resets = <&tegra_car 15>;
reset-names = "sdhci";
nvidia,default-tap = <0x8>;
nvidia,default-trim = <0x0>;
status = "disabled";
};

View File

@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <dt-bindings/input/input.h>
#include "tegra30.dtsi"
/ {
@ -62,6 +61,9 @@
status = "okay";
bus-width = <8>;
non-removable;
vmmc-supply = <&vcore_emmc>;
vqmmc-supply = <&vdd_1v8_vio>;
};
usb1: usb@7d000000 {
@ -150,7 +152,6 @@
regulator-name = "vdd_5v0_bl";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
regulator-boot-on;
gpio = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>;
enable-active-high;
};

View File

@ -22,7 +22,7 @@
gpio-controller;
regulators {
vdd_1v8: sd2 {
vdd_1v8_vio: sd2 {
regulator-name = "vdd_1v8_gen";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
@ -34,8 +34,7 @@
vcore_emmc: ldo3 {
regulator-name = "vcore_emmc";
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <3100000>;
regulator-always-on;
regulator-max-microvolt = <2850000>;
};
};
};

View File

@ -23,12 +23,19 @@
gpio-controller;
regulators {
vdd_1v8_vio: vddio {
regulator-name = "vdd_1v8_gen";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
/* eMMC VDD */
vcore_emmc: ldo1 {
regulator-name = "vdd_emmc_core";
regulator-min-microvolt = <1000000>;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
};
};

View File

@ -22,7 +22,7 @@
gpio-controller;
regulators {
vdd_1v8: sd2 {
vdd_1v8_vio: sd2 {
regulator-name = "vdd_1v8_gen";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
@ -34,8 +34,7 @@
vcore_emmc: ldo3 {
regulator-name = "vcore_emmc";
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <3100000>;
regulator-always-on;
regulator-max-microvolt = <2850000>;
};
};
};

View File

@ -1,18 +1,209 @@
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
#include "tegra30-asus-transformer.dtsi"
#include <dt-bindings/input/input.h>
#include "tegra30.dtsi"
/ {
model = "ASUS Portable AiO P1801-T";
compatible = "asus,p1801-t", "nvidia,tegra30";
/delete-node/ host1x@50000000;
/delete-node/ pwm@7000a000;
chosen {
stdout-path = &uarta;
};
/delete-node/ backlight;
/delete-node/ panel;
aliases {
i2c0 = &pwr_i2c;
i2c1 = &hdmi_ddc;
/delete-node/ regulator-pnl;
/delete-node/ regulator-bl;
mmc0 = &sdmmc4; /* eMMC */
mmc1 = &sdmmc1; /* uSD slot */
rtc0 = &pmic;
rtc1 = "/rtc@7000e000";
usb0 = &usb1;
usb1 = &usb2; /* Mini USB */
usb2 = &usb3; /* Dock USB */
};
memory {
device_type = "memory";
reg = <0x80000000 0x80000000>;
};
host1x@50000000 {
dc@54200000 {
clocks = <&tegra_car TEGRA30_CLK_DISP1>,
<&tegra_car TEGRA30_CLK_PLL_D_OUT0>;
rgb {
status = "okay";
nvidia,panel = <&hdmi>;
};
};
hdmi: hdmi@54280000 {
clocks = <&tegra_car TEGRA30_CLK_HDMI>,
<&tegra_car TEGRA30_CLK_PLL_D_OUT0>;
status = "okay";
hdmi-supply = <&hdmi_5v0_sys>;
pll-supply = <&vdd_1v8_vio>;
vdd-supply = <&hdmi_3v3_vdd>;
/* low: tablet, high: dock */
nvidia,hpd-gpio = <&gpio TEGRA_GPIO(H, 4) GPIO_ACTIVE_LOW>;
nvidia,ddc-i2c-bus = <&hdmi_ddc>;
};
};
uarta: serial@70006000 {
status = "okay";
};
hdmi_ddc: i2c@7000c700 {
status = "okay";
clock-frequency = <33000>;
};
pwr_i2c: i2c@7000d000 {
status = "okay";
clock-frequency = <400000>;
/* Texas Instruments TPS659110 PMIC */
pmic: tps65911@2d {
compatible = "ti,tps65911";
reg = <0x2d>;
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <2>;
interrupt-controller;
ti,system-power-controller;
#gpio-cells = <2>;
gpio-controller;
regulators {
vdd_1v8_vio: vddio {
regulator-name = "vdd_1v8_gen";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
/* eMMC VDD */
vcore_emmc: ldo1 {
regulator-name = "vdd_emmc_core";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
/* uSD slot VDD */
vdd_usd: ldo2 {
regulator-name = "vdd_usd";
regulator-min-microvolt = <3100000>;
regulator-max-microvolt = <3100000>;
};
/* uSD slot VDDIO */
vddio_usd: ldo3 {
regulator-name = "vddio_usd";
regulator-min-microvolt = <3100000>;
regulator-max-microvolt = <3100000>;
regulator-always-on;
regulator-boot-on;
};
};
};
};
sdmmc1: sdhci@78000000 {
status = "okay";
bus-width = <4>;
cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
power-gpios = <&gpio TEGRA_GPIO(D, 7) GPIO_ACTIVE_HIGH>;
vmmc-supply = <&vdd_usd>;
vqmmc-supply = <&vddio_usd>;
};
sdmmc4: sdhci@78000600 {
status = "okay";
bus-width = <8>;
non-removable;
vmmc-supply = <&vcore_emmc>;
vqmmc-supply = <&vdd_1v8_vio>;
};
/* USB via ASUS connector */
usb1: usb@7d000000 {
status = "okay";
dr_mode = "otg";
};
/* Mini USB port */
usb2: usb@7d004000 {
status = "okay";
nvidia,vbus-gpio = <&gpio TEGRA_GPIO(H, 7) GPIO_ACTIVE_HIGH>;
};
/* Dock's USB port */
usb3: usb@7d008000 {
status = "okay";
};
/* PMIC has a built-in 32KHz oscillator which is used by PMC */
clk32k_in: clock-32k {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
clock-output-names = "pmic-oscillator";
};
gpio-keys {
compatible = "gpio-keys";
key-power {
label = "Power";
gpios = <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>;
linux,code = <KEY_ENTER>;
};
key-volume-up {
label = "Volume Up";
gpios = <&gpio TEGRA_GPIO(Q, 2) GPIO_ACTIVE_LOW>;
linux,code = <KEY_UP>;
};
key-volume-down {
label = "Volume Down";
gpios = <&gpio TEGRA_GPIO(Q, 3) GPIO_ACTIVE_LOW>;
linux,code = <KEY_DOWN>;
};
};
hdmi_3v3_vdd: regulator-vdd {
compatible = "regulator-fixed";
regulator-name = "hdmi_3v3_vdd";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>;
enable-active-high;
};
hdmi_5v0_sys: regulator-hdmi {
compatible = "regulator-fixed";
regulator-name = "hdmi_5v0_sys";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&gpio TEGRA_GPIO(P, 2) GPIO_ACTIVE_HIGH>;
enable-active-high;
};
};

View File

@ -6,4 +6,9 @@
/ {
model = "ASUS Transformer Prime TF201";
compatible = "asus,tf201", "nvidia,tegra30";
usb-phy@7d008000 {
/delete-property/ nvidia,xcvr-setup-use-fuses;
nvidia,xcvr-setup = <5>; /* Based on TF201 fuse value - 48 */
};
};

View File

@ -1,38 +1,116 @@
// SPDX-License-Identifier: GPL-2.0
/dts-v1/;
#include "tegra30-asus-transformer.dtsi"
#include <dt-bindings/input/input.h>
#include "tegra30.dtsi"
/ {
model = "ASUS VivoTab RT TF600T";
compatible = "asus,tf600t", "nvidia,tegra30";
aliases {
spi0 = &spi4;
chosen {
stdout-path = &uarta;
};
/delete-node/ host1x@50000000;
aliases {
i2c0 = &pwr_i2c;
mmc0 = &sdmmc4; /* eMMC */
mmc1 = &sdmmc1; /* uSD slot */
rtc0 = &pmic;
rtc1 = "/rtc@7000e000";
spi0 = &spi4;
usb0 = &usb1;
usb1 = &usb3; /* Dock USB */
};
memory {
device_type = "memory";
reg = <0x80000000 0x80000000>;
};
host1x@50000000 {
dc@54200000 {
clocks = <&tegra_car TEGRA30_CLK_DISP1>,
<&tegra_car TEGRA30_CLK_PLL_D_OUT0>;
rgb {
status = "okay";
nvidia,panel = <&dsia>;
};
};
dsia: dsi@54300000 {
status = "okay";
avdd-dsi-csi-supply = <&avdd_dsi_csi>;
panel = <&panel>;
};
};
uarta: serial@70006000 {
status = "okay";
};
pwm: pwm@7000a000 {
status = "okay";
};
pwr_i2c: i2c@7000d000 {
status = "okay";
clock-frequency = <400000>;
pmic_i2c: i2c@7000d000 {
/* Texas Instruments TPS659110 PMIC */
pmic: tps65911@2d {
compatible = "ti,tps65911";
reg = <0x2d>;
interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
#interrupt-cells = <2>;
interrupt-controller;
ti,system-power-controller;
#gpio-cells = <2>;
gpio-controller;
regulators {
vdd_1v2_bl: vdd1 {
regulator-name = "vdd_1v2_backlight";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
regulator-boot-on;
ti,regulator-ext-sleep-control = <8>;
};
/delete-node/ ldo2;
/delete-node/ ldo3;
vcore_lcd: vdd2 {
regulator-name = "vcore_lcd";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
};
vdd_1v8_vio: vddio {
regulator-name = "vdd_1v8_gen";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
/* eMMC VDD */
vcore_emmc: ldo1 {
regulator-name = "vdd_emmc_core";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
/* uSD slot VDDIO */
vddio_usd: ldo5 {
regulator-name = "vddio_sdmmc";
regulator-min-microvolt = <1800000>;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
@ -57,11 +135,65 @@
};
};
backlight {
sdmmc1: sdhci@78000000 {
status = "okay";
bus-width = <4>;
cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
power-gpios = <&gpio TEGRA_GPIO(D, 7) GPIO_ACTIVE_HIGH>;
vmmc-supply = <&vdd_usd>;
vqmmc-supply = <&vddio_usd>;
};
sdmmc4: sdhci@78000600 {
status = "okay";
bus-width = <8>;
non-removable;
vmmc-supply = <&vcore_emmc>;
vqmmc-supply = <&vdd_1v8_vio>;
};
/* USB via ASUS connector */
usb1: usb@7d000000 {
status = "okay";
dr_mode = "otg";
};
/* Dock's USB port */
usb3: usb@7d008000 {
status = "okay";
};
backlight: backlight {
compatible = "pwm-backlight";
enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
power-supply = <&vdd_1v2_bl>;
pwms = <&pwm 0 71428>;
brightness-levels = <1 35 70 105 140 175 210 255>;
default-brightness-level = <5>;
};
/* PMIC has a built-in 32KHz oscillator which is used by PMC */
clk32k_in: clock-32k {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
clock-output-names = "pmic-oscillator";
};
gpio-keys {
compatible = "gpio-keys";
key-power {
label = "Power";
gpios = <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>;
linux,code = <KEY_ENTER>;
};
key-volume-up {
label = "Volume Up";
gpios = <&gpio TEGRA_GPIO(Q, 3) GPIO_ACTIVE_LOW>;
@ -75,7 +207,14 @@
};
};
/delete-node/ panel;
panel: panel {
compatible = "hydis,hv101hd1";
vdd-supply = <&vcore_lcd>;
enable-gpios = <&gpio TEGRA_GPIO(L, 4) GPIO_ACTIVE_HIGH>;
backlight = <&backlight>;
};
vdd_usd: regulator-usd {
compatible = "regulator-fixed";
@ -83,7 +222,4 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
/delete-node/ regulator-pnl;
/delete-node/ regulator-bl;
};

View File

@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <dt-bindings/input/input.h>
#include "tegra30.dtsi"
/ {
@ -70,12 +69,19 @@
gpio-controller;
regulators {
vdd_1v8_vio: vddio {
regulator-name = "vdd_1v8_gen";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
/* eMMC VDD */
vcore_emmc: ldo1 {
regulator-name = "vdd_emmc_core";
regulator-min-microvolt = <1000000>;
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
/* uSD slot VDD */
@ -88,8 +94,10 @@
/* uSD slot VDDIO */
vddio_usd: ldo3 {
regulator-name = "vddio_usd";
regulator-min-microvolt = <1800000>;
regulator-min-microvolt = <3100000>;
regulator-max-microvolt = <3100000>;
regulator-always-on;
regulator-boot-on;
};
};
};
@ -110,6 +118,9 @@
status = "okay";
bus-width = <8>;
non-removable;
vmmc-supply = <&vcore_emmc>;
vqmmc-supply = <&vdd_1v8_vio>;
};
/* USB via ASUS connector */
@ -123,6 +134,10 @@
status = "okay";
};
usb-phy@7d008000 {
status = "okay";
};
backlight: backlight {
compatible = "pwm-backlight";
@ -204,7 +219,6 @@
regulator-name = "vdd_5v0_bl";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
regulator-boot-on;
gpio = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>;
enable-active-high;
};

View File

@ -5,7 +5,6 @@
/* CPU Speedo ID 4, Soc Speedo ID 1, CPU Process: 1, Core Process: 0 */
#include <dt-bindings/input/input.h>
#include "tegra30.dtsi"
/ {
@ -66,13 +65,22 @@
compatible = "ti,tps80032";
reg = <0x48>;
ti,system-power-controller;
regulators {
vdd_1v8_vio: smps5 {
regulator-name = "vdd_1v8_gen";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
/* DSI VDD */
avdd_dsi_csi: ldo1 {
regulator-name = "avdd_dsi_csi";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
};
};
};
@ -82,6 +90,9 @@
status = "okay";
bus-width = <8>;
non-removable;
vmmc-supply = <&vcore_emmc>;
vqmmc-supply = <&vdd_1v8_vio>;
};
micro_usb: usb@7d000000 {

View File

@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#include <dt-bindings/input/input.h>
#include "tegra30.dtsi"
/ {
@ -91,6 +90,14 @@
regulator-boot-on;
};
avdd_3v3_periph: ldo2 {
regulator-name = "avdd_usb";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
vdd_usd: ldo3 {
regulator-name = "vdd_sdmmc3";
regulator-min-microvolt = <3000000>;
@ -103,8 +110,6 @@
regulator-name = "vdd_ddr_rx";
regulator-min-microvolt = <2850000>;
regulator-max-microvolt = <2850000>;
regulator-always-on;
regulator-boot-on;
};
};
};

View File

@ -128,21 +128,22 @@ struct tegra_mmc {
/* SDMMC1/3 settings from SDMMCx Initialization Sequence of TRM */
#define MEMCOMP_PADCTRL_VREF 7
#define AUTO_CAL_ENABLE (1 << 29)
#define AUTO_CAL_ACTIVE (1 << 31)
#define AUTO_CAL_START (1 << 31)
#define AUTO_CAL_ENABLE BIT(29)
#define AUTO_CAL_ACTIVE BIT(31)
#define AUTO_CAL_START BIT(31)
#if defined(CONFIG_TEGRA210)
#define AUTO_CAL_PD_OFFSET (0x7D << 8)
#define AUTO_CAL_PU_OFFSET (0 << 0)
#define IO_TRIM_BYPASS_MASK (1 << 2)
#define TRIM_VAL_SHIFT 24
#define TRIM_VAL_MASK (0x1F << TRIM_VAL_SHIFT)
#define TAP_VAL_SHIFT 16
#define TAP_VAL_MASK (0xFF << TAP_VAL_SHIFT)
#else
#define AUTO_CAL_PD_OFFSET (0x70 << 8)
#define AUTO_CAL_PU_OFFSET (0x62 << 0)
#endif
#define TRIM_VAL_SHIFT 24
#define TRIM_VAL_MASK (0x1F << TRIM_VAL_SHIFT)
#define TAP_VAL_SHIFT 16
#define TAP_VAL_MASK (0xFF << TAP_VAL_SHIFT)
#endif /* __ASSEMBLY__ */
#endif /* __TEGRA_MMC_H_ */

View File

@ -60,6 +60,9 @@ config TEGRA_COMMON
select MISC
select OF_CONTROL
select SPI
select SYSRESET
select SPL_SYSRESET if SPL
select SYSRESET_TEGRA
imply CMD_DM
imply CRC32_VERIFY

View File

@ -26,6 +26,10 @@
#include <asm/arch-tegra/gpu.h>
#include <asm/arch-tegra/usb.h>
#include <asm/arch-tegra/xusb-padctl.h>
#ifndef CONFIG_TEGRA186
#include <asm/arch-tegra/fuse.h>
#include <asm/arch/gp_padctrl.h>
#endif
#if IS_ENABLED(CONFIG_TEGRA_CLKRST)
#include <asm/arch/clock.h>
#endif
@ -256,6 +260,37 @@ int board_early_init_f(void)
}
#endif /* EARLY_INIT */
#ifndef CONFIG_TEGRA186
static void nvidia_board_late_init_generic(void)
{
char serialno_str[17];
/* Set chip id as serialno */
sprintf(serialno_str, "%016llx", tegra_chip_uid());
env_set("serial#", serialno_str);
switch (tegra_get_chip()) {
case CHIPID_TEGRA20:
env_set("platform", "tegra20");
break;
case CHIPID_TEGRA30:
env_set("platform", "tegra30");
break;
case CHIPID_TEGRA114:
env_set("platform", "tegra114");
break;
case CHIPID_TEGRA124:
env_set("platform", "tegra124");
break;
case CHIPID_TEGRA210:
env_set("platform", "tegra210");
break;
default:
return;
}
}
#endif
int board_late_init(void)
{
#if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE)
@ -268,6 +303,14 @@ int board_late_init(void)
#endif
start_cpu_fan();
cboot_late_init();
/*
* Perform generic env setup in case
* vendor does not provide it.
*/
#ifndef CONFIG_TEGRA186
nvidia_board_late_init_generic();
#endif
nvidia_board_late_init();
return 0;

View File

@ -84,12 +84,3 @@ void tegra_pmc_writel(u32 value, unsigned long offset)
writel(value, NV_PA_PMC_BASE + offset);
}
void reset_cpu(void)
{
u32 value;
value = tegra_pmc_readl(PMC_CNTRL);
value |= PMC_CNTRL_MAIN_RST;
tegra_pmc_writel(value, PMC_CNTRL);
}

View File

@ -13,9 +13,13 @@
#include <asm/arch/tegra.h>
#include <asm/arch-tegra/clk_rst.h>
#include <asm/arch-tegra/pmc.h>
#include <asm/arch-tegra/tegra_i2c.h>
#include <linux/delay.h>
#include "../cpu.h"
/* In case this function is not defined */
__weak void pmic_enable_cpu_vdd(void) {}
/* Tegra114-specific CPU init code */
static void enable_cpu_power_rail(void)
{
@ -254,6 +258,7 @@ void start_cpu(u32 reset_vector)
/* Enable VDD_CPU */
enable_cpu_power_rail();
pmic_enable_cpu_vdd();
/* Get the CPU(s) running */
enable_cpu_clocks();

View File

@ -11,6 +11,9 @@
#include "bct.h"
#include "uboot_aes.h"
/* Device with "sbk burned: false" will expose zero key */
const u8 nosbk[AES128_KEY_LENGTH] = { 0 };
/*
* @param bct boot config table start in RAM
* @param ect bootloader start in RAM
@ -23,22 +26,27 @@ static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size)
u8 ebt_hash[AES128_KEY_LENGTH] = { 0 };
u8 sbk[AES128_KEY_LENGTH] = { 0 };
u8 *bct_hash = bct;
bool encrypted;
int ret;
bct += BCT_HASH;
ebt_size = roundup(ebt_size, EBT_ALIGNMENT);
memcpy(sbk, (u8 *)(bct + BCT_LENGTH),
NVBOOT_CMAC_AES_HASH_LENGTH * 4);
ret = decrypt_data_block(bct, BCT_LENGTH, sbk);
if (ret)
return 1;
encrypted = memcmp(&sbk, &nosbk, AES128_KEY_LENGTH);
ebt_size = roundup(ebt_size, EBT_ALIGNMENT);
if (encrypted) {
ret = decrypt_data_block(bct, BCT_LENGTH, sbk);
if (ret)
return 1;
ret = encrypt_data_block(ebt, ebt_size, sbk);
if (ret)
return 1;
ret = encrypt_data_block(ebt, ebt_size, sbk);
if (ret)
return 1;
}
ret = sign_enc_data_block(ebt, ebt_size, ebt_hash, sbk);
if (ret)
@ -52,9 +60,11 @@ static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size)
bct_tbl->bootloader[0].load_addr = CONFIG_SPL_TEXT_BASE;
bct_tbl->bootloader[0].length = ebt_size;
ret = encrypt_data_block(bct, BCT_LENGTH, sbk);
if (ret)
return 1;
if (encrypted) {
ret = encrypt_data_block(bct, BCT_LENGTH, sbk);
if (ret)
return 1;
}
ret = sign_enc_data_block(bct, BCT_LENGTH, bct_hash, sbk);
if (ret)

View File

@ -11,6 +11,9 @@
#include "bct.h"
#include "uboot_aes.h"
/* Device with "sbk burned: false" will expose zero key */
const u8 nosbk[AES128_KEY_LENGTH] = { 0 };
/*
* @param bct boot config table start in RAM
* @param ect bootloader start in RAM
@ -23,22 +26,27 @@ static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size)
u8 ebt_hash[AES128_KEY_LENGTH] = { 0 };
u8 sbk[AES128_KEY_LENGTH] = { 0 };
u8 *bct_hash = bct;
bool encrypted;
int ret;
bct += BCT_HASH;
ebt_size = roundup(ebt_size, EBT_ALIGNMENT);
memcpy(sbk, (u8 *)(bct + BCT_LENGTH),
NVBOOT_CMAC_AES_HASH_LENGTH * 4);
ret = decrypt_data_block(bct, BCT_LENGTH, sbk);
if (ret)
return 1;
encrypted = memcmp(&sbk, &nosbk, AES128_KEY_LENGTH);
ebt_size = roundup(ebt_size, EBT_ALIGNMENT);
if (encrypted) {
ret = decrypt_data_block(bct, BCT_LENGTH, sbk);
if (ret)
return 1;
ret = encrypt_data_block(ebt, ebt_size, sbk);
if (ret)
return 1;
ret = encrypt_data_block(ebt, ebt_size, sbk);
if (ret)
return 1;
}
ret = sign_enc_data_block(ebt, ebt_size, ebt_hash, sbk);
if (ret)
@ -52,9 +60,11 @@ static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size)
bct_tbl->bootloader[0].load_addr = CONFIG_SPL_TEXT_BASE;
bct_tbl->bootloader[0].length = ebt_size;
ret = encrypt_data_block(bct, BCT_LENGTH, sbk);
if (ret)
return 1;
if (encrypted) {
ret = encrypt_data_block(bct, BCT_LENGTH, sbk);
if (ret)
return 1;
}
ret = sign_enc_data_block(bct, BCT_LENGTH, bct_hash, sbk);
if (ret)

View File

@ -2,9 +2,6 @@ GROUPER BOARD
M: Svyatoslav Ryhel <clamor95@gmail.com>
S: Maintained
F: board/asus/grouper/
F: configs/grouper_E1565.config
F: configs/grouper_PM269.config
F: configs/tilapia.config
F: configs/grouper_common_defconfig
F: doc/board/asus/grouper_common.rst
F: include/configs/grouper.h

View File

@ -9,14 +9,12 @@
#include <common.h>
#include <dm.h>
#include <env.h>
#include <fdt_support.h>
#include <i2c.h>
#include <log.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/gp_padctrl.h>
#include <asm/arch/gpio.h>
#include <asm/arch-tegra/fuse.h>
#include <asm/gpio.h>
#include <linux/delay.h>
#include "pinmux-config-grouper.h"
@ -190,13 +188,3 @@ int ft_board_setup(void *blob, struct bd_info *bd)
return 0;
}
#endif
void nvidia_board_late_init(void)
{
char serialno_str[17];
/* Set chip id as serialno */
sprintf(serialno_str, "%016llx", tegra_chip_uid());
env_set("serial#", serialno_str);
env_set("platform", "Tegra 3 T30");
}

View File

@ -2,13 +2,6 @@ TRANSFORMER BOARD
M: Svyatoslav Ryhel <clamor95@gmail.com>
S: Maintained
F: board/asus/transformer-t30/
F: configs/p1801-t.config
F: configs/tf201.config
F: configs/tf300t.config
F: configs/tf300tg.config
F: configs/tf300tl.config
F: configs/tf600t.config
F: configs/tf700t.config
F: configs/transformer_t30_defconfig
F: doc/board/asus/transformer_t30.rst
F: include/configs/transformer-common.h

View File

@ -1,4 +1,4 @@
CONFIG_DEFAULT_DEVICE_TREE="tegra30-asus-tf600t"
CONFIG_TRANSFORMER_SPI_BOOT=y
CONFIG_BOOTCOMMAND="setenv gpio_button 222; if run check_button; then poweroff; fi; setenv gpio_button 132; if run check_button; then echo Starting SPI flash update ...; run update_spi; fi; run bootcmd_mmc1; run bootcmd_mmc0; poweroff;"
CONFIG_BOOTCOMMAND="setenv gpio_button 222; if run check_button; then poweroff; fi; setenv gpio_button 132; if run check_button; then echo Starting SPI flash update ...; run update_spi; fi; run bootcmd_usb0; run bootcmd_mmc1; run bootcmd_mmc0; poweroff;"
CONFIG_USB_GADGET_PRODUCT_NUM=0x4d00

View File

@ -11,14 +11,12 @@
#include <common.h>
#include <dm.h>
#include <env.h>
#include <fdt_support.h>
#include <i2c.h>
#include <log.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/gp_padctrl.h>
#include <asm/arch/gpio.h>
#include <asm/arch-tegra/fuse.h>
#include <asm/gpio.h>
#include <linux/delay.h>
#include "pinmux-config-transformer.h"
@ -33,11 +31,6 @@
#define TPS65911_LDO5 0x32
#define TPS65911_LDO6 0x35
#define TPS65911_GPIO0 0x60
#define TPS65911_GPIO6 0x66
#define TPS65911_GPIO7 0x67
#define TPS65911_GPIO8 0x68
#define TPS65911_DEVCTRL 0x3F
#define DEVCTRL_PWR_OFF_MASK BIT(7)
#define DEVCTRL_DEV_ON_MASK BIT(2)
@ -146,26 +139,6 @@ static void tps65911_voltage_init(void)
if (ret)
log_debug("vddio_usd set failed: %d\n", ret);
}
/* TPS659110: GPIO0_REG output high to VDD_5V0_SBY */
ret = dm_i2c_reg_write(dev, TPS65911_GPIO0, 0x07);
if (ret)
log_debug("vdd_5v0_sby set failed: %d\n", ret);
/* TPS659110: GPIO6_REG output high to VDD_3V3_SYS */
ret = dm_i2c_reg_write(dev, TPS65911_GPIO6, 0x07);
if (ret)
log_debug("vdd_3v3_sys set failed: %d\n", ret);
/* TPS659110: GPIO7_REG output high to VDD_1V5_DDR */
ret = dm_i2c_reg_write(dev, TPS65911_GPIO7, 0x07);
if (ret)
log_debug("vdd_1v5_ddr set failed: %d\n", ret);
/* TPS659110: GPIO8_REG pull_down output high to VDD_5V0_SYS */
ret = dm_i2c_reg_write(dev, TPS65911_GPIO8, 0x0f);
if (ret)
log_debug("vdd_5v0_sys set failed: %d\n", ret);
}
/*
@ -189,13 +162,3 @@ int ft_board_setup(void *blob, struct bd_info *bd)
return 0;
}
#endif
void nvidia_board_late_init(void)
{
char serialno_str[17];
/* Set chip id as serialno */
sprintf(serialno_str, "%016llx", tegra_chip_uid());
env_set("serial#", serialno_str);
env_set("platform", "Tegra 3 T30");
}

View File

@ -9,14 +9,12 @@
#include <common.h>
#include <dm.h>
#include <env.h>
#include <fdt_support.h>
#include <i2c.h>
#include <log.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/gp_padctrl.h>
#include <asm/arch/gpio.h>
#include <asm/arch-tegra/fuse.h>
#include <asm/gpio.h>
#include <linux/delay.h>
#include "pinmux-config-endeavoru.h"
@ -104,13 +102,3 @@ int ft_board_setup(void *blob, struct bd_info *bd)
return 0;
}
#endif
void nvidia_board_late_init(void)
{
char serialno_str[17];
/* Set chip id as serialno */
sprintf(serialno_str, "%016llx", tegra_chip_uid());
env_set("serial#", serialno_str);
env_set("platform", "Tegra 3 T30");
}

View File

@ -2,8 +2,6 @@ X3 BOARD
M: Svyatoslav Ryhel <clamor95@gmail.com>
S: Maintained
F: board/lg/x3-t30/
F: configs/p880.config
F: configs/p895.config
F: configs/x3_t30_defconfig
F: doc/board/lg/x3_t30.rst
F: include/configs/x3-t30.h

View File

@ -9,7 +9,6 @@
#include <common.h>
#include <dm.h>
#include <env.h>
#include <fdt_support.h>
#include <i2c.h>
#include <log.h>
@ -164,13 +163,3 @@ int ft_board_setup(void *blob, struct bd_info *bd)
return 0;
}
#endif
void nvidia_board_late_init(void)
{
char serialno_str[17];
/* Set chip id as serialno */
sprintf(serialno_str, "%016llx", tegra_chip_uid());
env_set("serial#", serialno_str);
env_set("platform", "Tegra 3 T30");
}

View File

@ -59,8 +59,6 @@ CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_FASTBOOT_CMD_OEM_FORMAT=y
CONFIG_GPIO_HOG=y
CONFIG_SYS_I2C_TEGRA=y
CONFIG_I2C_MUX=y
CONFIG_I2C_MUX_GPIO=y
CONFIG_BUTTON_KEYBOARD=y
CONFIG_DM_PMIC=y
CONFIG_DM_REGULATOR=y

View File

@ -20,7 +20,7 @@ CONFIG_AUTOBOOT_KEYED=y
CONFIG_AUTOBOOT_KEYED_CTRLC=y
CONFIG_OF_BOARD_SETUP=y
CONFIG_OF_SYSTEM_SETUP=y
CONFIG_BOOTCOMMAND="setenv gpio_button 150; if run check_button; then poweroff; fi; setenv gpio_button 131; if run check_button; then bootmenu; fi; run bootcmd_mmc1; run bootcmd_mmc0; poweroff;"
CONFIG_BOOTCOMMAND="setenv skip_boot 0; setenv gpio_button 150; if run check_button; then poweroff; fi; setenv gpio_button 131; if run check_button; then bootmenu; fi; if test ${skip_boot} -eq 1; then; else run bootcmd_usb0; run bootcmd_mmc1; run bootcmd_mmc0; poweroff; fi"
CONFIG_SPL_FOOTPRINT_LIMIT=y
CONFIG_SPL_MAX_FOOTPRINT=0x8000
# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set

View File

@ -0,0 +1,84 @@
MAXIM, MAX77663 PMIC
This device uses two drivers:
- drivers/power/pmic/max77663.c (for parent device)
- drivers/power/regulator/max77663_regulator.c (for child regulators)
This chapter describes the binding info for the PMIC driver and regulators.
Required properties for PMIC:
- compatible: "maxim,max77663"
- reg: usually 0x1c or 0x3c
With those two properties, the pmic device can be used for read/write only.
To bind each regulator, the optional regulators subnode should exists.
Optional subnode:
- name: regulators (subnode list of each device's regulator)
Regulators subnode contains set on supported regulators.
Required properties:
- regulator-name: used for regulator uclass platform data '.name',
List of supported regulator nodes names for max77663:
- sd0, sd1, sd2, sd3, ldo0, ldo1, ldo2, ldo3, ldo4, ldo5, ldo6, ldo7, ldo8
Optional:
- regulator-min-microvolt: minimum allowed Voltage to set
- regulator-max-microvolt: minimum allowed Voltage to set
- regulator-always-on: regulator should be never disabled
- regulator-boot-on: regulator should be enabled by the bootloader
Linux driver binding for this driver is compatible.
Example:
max77663@1c {
compatible = "maxim,max77663";
reg = <0x1c>;
regulators {
sd0 {
regulator-name = "vdd_cpu";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1250000>;
regulator-always-on;
regulator-boot-on;
};
...
ldo0 {
regulator-name = "avdd_pll";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
};
...
ldo2 {
regulator-name = "avdd_usb";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
ldo3 {
regulator-name = "vdd_sdmmc3";
regulator-min-microvolt = <3000000>;
regulator-max-microvolt = <3000000>;
regulator-always-on;
regulator-boot-on;
};
...
ldo8 {
regulator-name = "avdd_dsi_csi";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
};
};
};

View File

@ -0,0 +1,78 @@
Texas Instruments, TPS65911 PMIC
This device uses two drivers:
- drivers/power/pmic/tps65910.c (for parent device)
- drivers/power/regulator/tps65911_regulator.c (for child regulators)
This chapter describes the binding info for the PMIC driver and regulators.
Required properties for PMIC:
- compatible: "ti,tps65911"
- reg: 0x2d
With those two properties, the pmic device can be used for read/write only.
To bind each regulator, the optional regulators subnode should exists.
Optional subnode:
- name: regulators (subnode list of each device's regulator)
Regulators subnode contains set on supported regulators.
Required properties:
- regulator-name: used for regulator uclass platform data '.name',
List of supported regulator nodes names for tps65911:
- vdd1, vdd2, vddctrl, vddio
- ldo1, ldo2, ldo3, ldo4, ldo5, ldo6, ldo7, ldo8
vddio in datasheet is referred as vio, but for reduction of code and
unification of smps regulators it is named vddio.
Optional:
- regulator-min-microvolt: minimum allowed Voltage to set
- regulator-max-microvolt: minimum allowed Voltage to set
- regulator-always-on: regulator should be never disabled
- regulator-boot-on: regulator should be enabled by the bootloader
Example:
tps65911@2d {
compatible = "ti,tps65911";
reg = <0x2d>;
regulators {
vdd1 {
regulator-name = "vdd_1v2_backlight";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
regulator-boot-on;
};
...
vddio {
regulator-name = "vdd_1v8_gen";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
ldo1 {
regulator-name = "vdd_emmc_core";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
regulator-boot-on;
};
...
ldo8 {
regulator-name = "vdd_ddr_hs";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
};
};
};

View File

@ -0,0 +1,76 @@
Texas Instruments, TPS80031/TPS80032 PMIC
This device uses two drivers:
- drivers/power/pmic/tps80031.c (for parent device)
- drivers/power/regulator/tps80031_regulator.c (for child regulators)
This chapter describes the binding info for the PMIC driver and regulators.
Required properties for PMIC:
- compatible: "ti,tps80031" or "ti,tps80032"
- reg: 0x48
With those two properties, the pmic device can be used for read/write only.
To bind each regulator, the optional regulators subnode should exists.
Optional subnode:
- name: regulators (subnode list of each device's regulator)
Regulators subnode contains set on supported regulators.
Required properties:
- regulator-name: used for regulator uclass platform data '.name',
List of supported regulator nodes names for tps80031/tps80032:
- smps1, smps2, smps3, smps4, smps5
- ldo1, ldo2, ldo3, ldo4, ldo5, ldo6, ldo7, ldoln, ldousb
SMPS5 in Linux 3.1.10 is referred as vio, but datasheet clearly names it SMPS5.
Optional:
- regulator-min-microvolt: minimum allowed Voltage to set
- regulator-max-microvolt: minimum allowed Voltage to set
- regulator-always-on: regulator should be never disabled
- regulator-boot-on: regulator should be enabled by the bootloader
Example:
tps80032@48 {
compatible = "ti,tps80032";
reg = <0x48>;
regulators {
smps1 {
regulator-name = "vdd_cpu";
regulator-min-microvolt = <800000>;
regulator-max-microvolt = <1250000>;
regulator-always-on;
regulator-boot-on;
};
...
smps5 {
regulator-name = "vdd_1v8_gen";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
};
ldo1 {
regulator-name = "avdd_dsi_csi";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-boot-on;
};
...
ldousb {
regulator-name = "avdd_usb";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
};
};

View File

@ -37,6 +37,9 @@ struct tegra_mmc_priv {
unsigned int version; /* SDHCI spec. version */
unsigned int clock; /* Current clock (MHz) */
int mmc_id; /* peripheral id */
int tap_value;
int trim_value;
};
static void tegra_mmc_set_power(struct tegra_mmc_priv *priv,
@ -526,31 +529,6 @@ static void tegra_mmc_pad_init(struct tegra_mmc_priv *priv)
printf("%s: Warning: Autocal timed out!\n", __func__);
/* TBD: Set CFG2TMC_SDMMC1_PAD_CAL_DRV* regs here */
}
#if defined(CONFIG_TEGRA210)
u32 tap_value, trim_value;
/* Set tap/trim values for SDMMC1/3 @ <48MHz here */
val = readl(&priv->reg->venspictl); /* aka VENDOR_SYS_SW_CNTL */
val &= IO_TRIM_BYPASS_MASK;
if (id == PERIPH_ID_SDMMC1) {
tap_value = 4; /* default */
if (val)
tap_value = 3;
trim_value = 2;
} else { /* SDMMC3 */
tap_value = 3;
trim_value = 3;
}
val = readl(&priv->reg->venclkctl);
val &= ~TRIM_VAL_MASK;
val |= (trim_value << TRIM_VAL_SHIFT);
val &= ~TAP_VAL_MASK;
val |= (tap_value << TAP_VAL_SHIFT);
writel(val, &priv->reg->venclkctl);
debug("%s: VENDOR_CLOCK_CNTRL = 0x%08X\n", __func__, val);
#endif /* T210 */
#endif /* T30/T210 */
}
@ -588,6 +566,22 @@ static void tegra_mmc_reset(struct tegra_mmc_priv *priv, struct mmc *mmc)
/* Make sure SDIO pads are set up */
tegra_mmc_pad_init(priv);
if (!IS_ERR_VALUE(priv->tap_value) ||
!IS_ERR_VALUE(priv->trim_value)) {
u32 val;
val = readl(&priv->reg->venclkctl);
val &= ~TRIM_VAL_MASK;
val |= (priv->trim_value << TRIM_VAL_SHIFT);
val &= ~TAP_VAL_MASK;
val |= (priv->tap_value << TAP_VAL_SHIFT);
writel(val, &priv->reg->venclkctl);
debug("%s: VENDOR_CLOCK_CNTRL = 0x%08X\n", __func__, val);
}
}
static int tegra_mmc_init(struct udevice *dev)
@ -742,6 +736,14 @@ static int tegra_mmc_probe(struct udevice *dev)
if (dm_gpio_is_valid(&priv->pwr_gpio))
dm_gpio_set_value(&priv->pwr_gpio, 1);
ret = dev_read_u32(dev, "nvidia,default-tap", &priv->tap_value);
if (ret)
priv->tap_value = ret;
ret = dev_read_u32(dev, "nvidia,default-trim", &priv->trim_value);
if (ret)
priv->trim_value = ret;
upriv->mmc = &plat->mmc;
return tegra_mmc_init(dev);

View File

@ -184,6 +184,15 @@ config SPL_DM_PMIC_PFUZE100
This config enables implementation of driver-model pmic uclass features
for PMIC PFUZE100 in SPL. The driver implements read/write operations.
config DM_PMIC_MAX77663
bool "Enable Driver Model for PMIC MAX77663"
---help---
This config enables implementation of driver-model pmic uclass features
for PMIC MAX77663. The driver implements read/write operations.
This is a Power Management IC with a decent set of peripherals from which
4 DC-to-DC Step-Down (SD) Regulators, 9 Low-Dropout Linear (LDO) Regulators,
8 GPIOs, Real-Time Clock (RTC) and more with I2C Compatible Interface.
config DM_PMIC_MAX77686
bool "Enable Driver Model for PMIC MAX77686"
---help---
@ -342,6 +351,17 @@ config DM_PMIC_TPS65910
DC-DC converter, 8 LDOs and a RTC. This driver binds the SMPS and LDO
pmic children.
config DM_PMIC_TPS80031
bool "Enable driver for Texas Instruments TPS80031/TPS80032 PMIC"
---help---
This config enables implementation of driver-model pmic uclass features
for TPS80031/TPS80032 PMICs. The driver implements read/write operations.
This is a Power Management IC with a decent set of peripherals from which
5 Buck Converters refered as Switched-mode power supply (SMPS), 11 General-
Purpose Low-Dropout Voltage Regulators (LDO), USB OTG Module, Real-Time
Clock (RTC) with Timer and Alarm Wake-Up, Two Digital PWM Outputs and more
with I2C Compatible Interface. PMIC occupies 4 I2C addresses.
config PMIC_STPMIC1
bool "Enable support for STMicroelectronics STPMIC1 PMIC"
depends on DM_I2C

View File

@ -6,6 +6,7 @@
obj-$(CONFIG_$(SPL_TPL_)DM_PMIC) += pmic-uclass.o
obj-$(CONFIG_$(SPL_)DM_PMIC_FAN53555) += fan53555.o
obj-$(CONFIG_$(SPL_)DM_PMIC_DA9063) += da9063.o
obj-$(CONFIG_$(SPL_)DM_PMIC_MAX77663) += max77663.o
obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o
obj-$(CONFIG_DM_PMIC_MAX8998) += max8998.o
obj-$(CONFIG_DM_PMIC_MC34708) += mc34708.o
@ -26,6 +27,7 @@ obj-$(CONFIG_$(SPL_)PMIC_RN5T567) += rn5t567.o
obj-$(CONFIG_PMIC_TPS65090) += tps65090.o
obj-$(CONFIG_PMIC_S5M8767) += s5m8767.o
obj-$(CONFIG_DM_PMIC_TPS65910) += pmic_tps65910_dm.o
obj-$(CONFIG_$(SPL_)DM_PMIC_TPS80031) += tps80031.o
obj-$(CONFIG_$(SPL_)PMIC_PALMAS) += palmas.o
obj-$(CONFIG_$(SPL_)PMIC_LP873X) += lp873x.o
obj-$(CONFIG_$(SPL_)PMIC_LP87565) += lp87565.o

View File

@ -0,0 +1,90 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <dm/lists.h>
#include <power/pmic.h>
#include <power/max77663.h>
static const struct pmic_child_info pmic_children_info[] = {
{ .prefix = "ldo", .driver = MAX77663_LDO_DRIVER },
{ .prefix = "sd", .driver = MAX77663_SD_DRIVER },
{ },
};
static int max77663_write(struct udevice *dev, uint reg, const uint8_t *buff,
int len)
{
int ret;
ret = dm_i2c_write(dev, reg, buff, len);
if (ret) {
log_debug("write error to device: %p register: %#x!\n", dev, reg);
return ret;
}
return 0;
}
static int max77663_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
{
int ret;
ret = dm_i2c_read(dev, reg, buff, len);
if (ret) {
log_debug("read error from device: %p register: %#x!\n", dev, reg);
return ret;
}
return 0;
}
static int max77663_bind(struct udevice *dev)
{
ofnode regulators_node;
int children, ret;
if (IS_ENABLED(CONFIG_SYSRESET_MAX77663)) {
ret = device_bind_driver(dev, MAX77663_RST_DRIVER,
"sysreset", NULL);
if (ret) {
log_err("cannot bind SYSRESET (ret = %d)\n", ret);
return ret;
}
}
regulators_node = dev_read_subnode(dev, "regulators");
if (!ofnode_valid(regulators_node)) {
log_err("%s regulators subnode not found!\n", dev->name);
return -ENXIO;
}
debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
children = pmic_bind_children(dev, regulators_node, pmic_children_info);
if (!children)
log_err("%s - no child found\n", dev->name);
/* Always return success for this device */
return 0;
}
static struct dm_pmic_ops max77663_ops = {
.read = max77663_read,
.write = max77663_write,
};
static const struct udevice_id max77663_ids[] = {
{ .compatible = "maxim,max77663" },
{ }
};
U_BOOT_DRIVER(pmic_max77663) = {
.name = "max77663_pmic",
.id = UCLASS_PMIC,
.of_match = max77663_ids,
.bind = max77663_bind,
.ops = &max77663_ops,
};

View File

@ -8,13 +8,13 @@
#include <fdtdec.h>
#include <errno.h>
#include <dm.h>
#include <dm/lists.h>
#include <i2c.h>
#include <log.h>
#include <linux/printk.h>
#include <power/pmic.h>
#include <power/regulator.h>
#include <power/palmas.h>
#include <dm/device.h>
static const struct pmic_child_info pmic_children_info[] = {
{ .prefix = "ldo", .driver = PALMAS_LDO_DRIVER },
@ -47,7 +47,16 @@ static int palmas_bind(struct udevice *dev)
{
ofnode pmic_node = ofnode_null(), regulators_node;
ofnode subnode;
int children;
int children, ret;
if (IS_ENABLED(CONFIG_SYSRESET_PALMAS)) {
ret = device_bind_driver(dev, PALMAS_RST_DRIVER,
"sysreset", NULL);
if (ret) {
log_err("cannot bind SYSRESET (ret = %d)\n", ret);
return ret;
}
}
dev_for_each_subnode(subnode, dev) {
const char *name;
@ -81,6 +90,24 @@ static int palmas_bind(struct udevice *dev)
return 0;
}
static int palmas_probe(struct udevice *dev)
{
struct dm_i2c_chip *chip = dev_get_parent_plat(dev);
struct palmas_priv *priv = dev_get_priv(dev);
struct udevice *bus = dev_get_parent(dev);
u32 chip2_addr = chip->chip_addr + 1;
int ret;
/* Palmas PMIC is multi chip and chips are located in a row */
ret = i2c_get_chip(bus, chip2_addr, 1, &priv->chip2);
if (ret) {
log_err("cannot get second PMIC I2C chip (err %d)\n", ret);
return ret;
}
return 0;
}
static struct dm_pmic_ops palmas_ops = {
.read = palmas_read,
.write = palmas_write,
@ -88,6 +115,7 @@ static struct dm_pmic_ops palmas_ops = {
static const struct udevice_id palmas_ids[] = {
{ .compatible = "ti,tps659038", .data = TPS659038 },
{ .compatible = "ti,tps65913" , .data = TPS659038 },
{ .compatible = "ti,tps65917" , .data = TPS65917 },
{ }
};
@ -97,5 +125,7 @@ U_BOOT_DRIVER(pmic_palmas) = {
.id = UCLASS_PMIC,
.of_match = palmas_ids,
.bind = palmas_bind,
.probe = palmas_probe,
.ops = &palmas_ops,
.priv_auto = sizeof(struct palmas_priv),
};

View File

@ -5,6 +5,7 @@
#include <common.h>
#include <dm.h>
#include <dm/lists.h>
#include <i2c.h>
#include <log.h>
#include <linux/printk.h>
@ -12,13 +13,19 @@
#include <power/regulator.h>
#include <power/tps65910_pmic.h>
static const struct pmic_child_info pmic_children_info[] = {
static const struct pmic_child_info tps65910_children_info[] = {
{ .prefix = "ldo_", .driver = TPS65910_LDO_DRIVER },
{ .prefix = "buck_", .driver = TPS65910_BUCK_DRIVER },
{ .prefix = "boost_", .driver = TPS65910_BOOST_DRIVER },
{ },
};
static const struct pmic_child_info tps65911_children_info[] = {
{ .prefix = "ldo", .driver = TPS65911_LDO_DRIVER },
{ .prefix = "vdd", .driver = TPS65911_VDD_DRIVER },
{ },
};
static int pmic_tps65910_reg_count(struct udevice *dev)
{
return TPS65910_NUM_REGS;
@ -50,8 +57,19 @@ static int pmic_tps65910_read(struct udevice *dev, uint reg, u8 *buffer,
static int pmic_tps65910_bind(struct udevice *dev)
{
const struct pmic_child_info *tps6591x_children_info =
(struct pmic_child_info *)dev_get_driver_data(dev);
ofnode regulators_node;
int children;
int children, ret;
if (IS_ENABLED(CONFIG_SYSRESET_TPS65910)) {
ret = device_bind_driver(dev, TPS65910_RST_DRIVER,
"sysreset", NULL);
if (ret) {
log_err("cannot bind SYSRESET (ret = %d)\n", ret);
return ret;
}
}
regulators_node = dev_read_subnode(dev, "regulators");
if (!ofnode_valid(regulators_node)) {
@ -59,7 +77,7 @@ static int pmic_tps65910_bind(struct udevice *dev)
return -EINVAL;
}
children = pmic_bind_children(dev, regulators_node, pmic_children_info);
children = pmic_bind_children(dev, regulators_node, tps6591x_children_info);
if (!children)
debug("%s has no children (regulators)\n", dev->name);
@ -83,7 +101,8 @@ static struct dm_pmic_ops pmic_tps65910_ops = {
};
static const struct udevice_id pmic_tps65910_match[] = {
{ .compatible = "ti,tps65910" },
{ .compatible = "ti,tps65910", .data = (ulong)&tps65910_children_info },
{ .compatible = "ti,tps65911", .data = (ulong)&tps65911_children_info },
{ /* sentinel */ }
};

View File

@ -0,0 +1,91 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <dm/lists.h>
#include <power/pmic.h>
#include <power/tps80031.h>
static const struct pmic_child_info pmic_children_info[] = {
{ .prefix = "ldo", .driver = TPS80031_LDO_DRIVER },
{ .prefix = "smps", .driver = TPS80031_SMPS_DRIVER },
{ },
};
static int tps80031_write(struct udevice *dev, uint reg, const uint8_t *buff,
int len)
{
int ret;
ret = dm_i2c_write(dev, reg, buff, len);
if (ret) {
log_debug("write error to device: %p register: %#x!\n", dev, reg);
return ret;
}
return 0;
}
static int tps80031_read(struct udevice *dev, uint reg, uint8_t *buff, int len)
{
int ret;
ret = dm_i2c_read(dev, reg, buff, len);
if (ret) {
log_debug("read error from device: %p register: %#x!\n", dev, reg);
return ret;
}
return 0;
}
static int tps80031_bind(struct udevice *dev)
{
ofnode regulators_node;
int children, ret;
if (IS_ENABLED(CONFIG_SYSRESET_TPS80031)) {
ret = device_bind_driver(dev, TPS80031_RST_DRIVER,
"sysreset", NULL);
if (ret) {
log_err("cannot bind SYSRESET (ret = %d)\n", ret);
return ret;
}
}
regulators_node = dev_read_subnode(dev, "regulators");
if (!ofnode_valid(regulators_node)) {
log_err("%s regulators subnode not found!\n", dev->name);
return -ENXIO;
}
debug("%s: '%s' - found regulators subnode\n", __func__, dev->name);
children = pmic_bind_children(dev, regulators_node, pmic_children_info);
if (!children)
log_err("%s - no child found\n", dev->name);
/* Always return success for this device */
return 0;
}
static struct dm_pmic_ops tps80031_ops = {
.read = tps80031_read,
.write = tps80031_write,
};
static const struct udevice_id tps80031_ids[] = {
{ .compatible = "ti,tps80031" },
{ .compatible = "ti,tps80032" },
{ }
};
U_BOOT_DRIVER(pmic_tps80031) = {
.name = "tps80031_pmic",
.id = UCLASS_PMIC,
.of_match = tps80031_ids,
.bind = tps80031_bind,
.ops = &tps80031_ops,
};

View File

@ -141,6 +141,15 @@ config SPL_REGULATOR_PWM
This config enables implementation of driver-model regulator uclass
features for PWM regulators in SPL.
config DM_REGULATOR_MAX77663
bool "Enable Driver Model for REGULATOR MAX77663"
depends on DM_REGULATOR && DM_PMIC_MAX77663
---help---
This config enables implementation of driver-model regulator uclass
features for REGULATOR MAX77663. The driver supports both DC-to-DC
Step-Down (SD) Regulators and Low-Dropout Linear (LDO) Regulators
found in MAX77663 PMIC and implements get/set api for value and enable.
config DM_REGULATOR_MAX77686
bool "Enable Driver Model for REGULATOR MAX77686"
depends on DM_REGULATOR && DM_PMIC_MAX77686
@ -337,6 +346,17 @@ config DM_REGULATOR_TPS65910
regulator types of the TPS65910 (BUCK, BOOST and LDO). It implements
the get/set api for value and enable.
config DM_REGULATOR_TPS65911
bool "Enable driver for TPS65911 PMIC regulators"
depends on DM_PMIC_TPS65910
---help---
This config enables implementation of driver-model regulator
uclass features for the TPS65911 PMIC. The driver supports Step-Down
DC-DC Converters for Processor Cores (VDD1 and VDD2), Step-Down DC-DC
Converter for I/O Power (VIO), Controller for External FETs (VDDCtrl)
and LDO Voltage Regulators found in TPS65911 PMIC and implements
get/set api for value and enable.
config DM_REGULATOR_TPS62360
bool "Enable driver for TPS6236x Power Regulator"
depends on DM_REGULATOR
@ -347,6 +367,14 @@ config DM_REGULATOR_TPS62360
implements the get/set api for value only, as the power line is
always on.
config DM_REGULATOR_TPS80031
bool "Enable driver for TPS80031/TPS80032 PMIC regulators"
depends on DM_PMIC_TPS80031
---help---
This enables implementation of driver-model regulator uclass
features for TPS80031/TPS80032 PMICs. The driver implements
get/set api for: value and enable.
config DM_REGULATOR_STPMIC1
bool "Enable driver for STPMIC1 regulators"
depends on DM_REGULATOR && PMIC_STPMIC1

View File

@ -10,6 +10,7 @@ obj-$(CONFIG_REGULATOR_AS3722) += as3722_regulator.o
obj-$(CONFIG_$(SPL_)REGULATOR_AXP) += axp_regulator.o
obj-$(CONFIG_$(SPL_)REGULATOR_AXP_USB_POWER) += axp_usb_power.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_DA9063) += da9063.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_MAX77663) += max77663_regulator.o
obj-$(CONFIG_DM_REGULATOR_MAX77686) += max77686.o
obj-$(CONFIG_DM_REGULATOR_NPCM8XX) += npcm8xx_regulator.o
obj-$(CONFIG_$(SPL_)DM_PMIC_PFUZE100) += pfuze100.o
@ -31,7 +32,9 @@ obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP873X) += lp873x_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_LP87565) += lp87565_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_STM32_VREFBUF) += stm32-vrefbuf.o
obj-$(CONFIG_DM_REGULATOR_TPS65910) += tps65910_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_TPS65911) += tps65911_regulator.o
obj-$(CONFIG_DM_REGULATOR_TPS62360) += tps62360_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_TPS80031) += tps80031_regulator.o
obj-$(CONFIG_$(SPL_)DM_REGULATOR_STPMIC1) += stpmic1.o
obj-$(CONFIG_DM_REGULATOR_TPS65941) += tps65941_regulator.o
obj-$(CONFIG_DM_REGULATOR_SCMI) += scmi_regulator.o

View File

@ -0,0 +1,375 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <power/pmic.h>
#include <power/regulator.h>
#include <power/max77663.h>
/* fist row is control registers, second is voltage registers */
static const char max77663_sd_reg[][MAX77663_SD_NUM] = {
{ 0x1d, 0x1e, 0x1f, 0x20, 0x21 },
{ 0x16, 0x17, 0x18, 0x19, 0x2a },
};
static const char max77663_ldo_reg[MAX77663_LDO_NUM] = {
0x23, 0x25, 0x27, 0x29, 0x2b, 0x2d, 0x2f, 0x31, 0x33
};
static int max77663_sd_enable(struct udevice *dev, int op, bool *enable)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
u32 adr = uc_pdata->ctrl_reg;
int val, ret;
val = pmic_reg_read(dev->parent, adr);
if (val < 0)
return val;
if (op == PMIC_OP_GET) {
if (val & SD_STATUS_MASK)
*enable = true;
else
*enable = false;
return 0;
} else if (op == PMIC_OP_SET) {
val &= ~SD_STATUS_MASK;
if (*enable)
val |= SD_STATUS_MASK;
ret = pmic_reg_write(dev->parent, adr, val);
if (ret)
return ret;
}
return 0;
}
/**
* max77663_*_volt2hex() - convert voltage in uV into
* applicable to register hex value
*
* @idx: regulator index
* @uV: voltage in uV
*
* Return: voltage in hex on success, -ve on failure
*/
static int max77663_sd_volt2hex(int idx, int uV)
{
switch (idx) {
case 0:
/* SD0 has max voltage 1.4V */
if (uV > SD0_VOLT_MAX)
return -EINVAL;
break;
case 1:
/* SD1 has max voltage 1.55V */
if (uV > SD1_VOLT_MAX)
return -EINVAL;
break;
default:
/* SD2 and SD3 have max voltage 3.79V */
if (uV > SD_VOLT_MAX)
return -EINVAL;
break;
};
if (uV < SD_VOLT_MIN)
uV = SD_VOLT_MIN;
return (uV - SD_VOLT_BASE) / 12500;
}
/**
* max77663_*_hex2volt() - convert register hex value into
* actual voltage in uV
*
* @idx: regulator index
* @hex: hex value of register
*
* Return: voltage in uV on success, -ve on failure
*/
static int max77663_sd_hex2volt(int idx, int hex)
{
switch (idx) {
case 0:
/* SD0 has max voltage 1.4V */
if (hex > SD0_VOLT_MAX_HEX)
return -EINVAL;
break;
case 1:
/* SD1 has max voltage 1.55V */
if (hex > SD1_VOLT_MAX_HEX)
return -EINVAL;
break;
default:
/* SD2 and SD3 have max voltage 3.79V */
if (hex > SD_VOLT_MAX_HEX)
return -EINVAL;
break;
};
if (hex < SD_VOLT_MIN_HEX)
hex = SD_VOLT_MIN_HEX;
return SD_VOLT_BASE + hex * 12500;
}
static int max77663_sd_val(struct udevice *dev, int op, int *uV)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
u32 adr = uc_pdata->volt_reg;
int idx = dev->driver_data;
int hex, ret;
if (op == PMIC_OP_GET) {
hex = pmic_reg_read(dev->parent, adr);
if (hex < 0)
return hex;
*uV = 0;
ret = max77663_sd_hex2volt(idx, hex);
if (ret < 0)
return ret;
*uV = ret;
return 0;
}
/* SD regulators use entire register for voltage */
hex = max77663_sd_volt2hex(idx, *uV);
if (hex < 0)
return hex;
return pmic_reg_write(dev->parent, adr, hex);
}
static int max77663_sd_probe(struct udevice *dev)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
int idx = dev->driver_data;
uc_pdata->type = REGULATOR_TYPE_BUCK;
uc_pdata->ctrl_reg = max77663_sd_reg[0][idx];
uc_pdata->volt_reg = max77663_sd_reg[1][idx];
return 0;
}
static int sd_get_value(struct udevice *dev)
{
int uV;
int ret;
ret = max77663_sd_val(dev, PMIC_OP_GET, &uV);
if (ret)
return ret;
return uV;
}
static int sd_set_value(struct udevice *dev, int uV)
{
return max77663_sd_val(dev, PMIC_OP_SET, &uV);
}
static int sd_get_enable(struct udevice *dev)
{
bool enable = false;
int ret;
ret = max77663_sd_enable(dev, PMIC_OP_GET, &enable);
if (ret)
return ret;
return enable;
}
static int sd_set_enable(struct udevice *dev, bool enable)
{
return max77663_sd_enable(dev, PMIC_OP_SET, &enable);
}
static const struct dm_regulator_ops max77663_sd_ops = {
.get_value = sd_get_value,
.set_value = sd_set_value,
.get_enable = sd_get_enable,
.set_enable = sd_set_enable,
};
U_BOOT_DRIVER(max77663_sd) = {
.name = MAX77663_SD_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &max77663_sd_ops,
.probe = max77663_sd_probe,
};
static int max77663_ldo_enable(struct udevice *dev, int op, bool *enable)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
u32 adr = uc_pdata->ctrl_reg;
int val, ret;
val = pmic_reg_read(dev->parent, adr);
if (val < 0)
return val;
if (op == PMIC_OP_GET) {
if (val & LDO_STATUS_MASK)
*enable = true;
else
*enable = false;
return 0;
} else if (op == PMIC_OP_SET) {
val &= ~LDO_STATUS_MASK;
if (*enable)
val |= LDO_STATUS_MASK;
ret = pmic_reg_write(dev->parent, adr, val);
if (ret)
return ret;
}
return 0;
}
static int max77663_ldo_volt2hex(int idx, int uV)
{
switch (idx) {
case 0:
case 1:
if (uV > LDO01_VOLT_MAX)
return -EINVAL;
return (uV - LDO_VOLT_BASE) / 25000;
case 4:
if (uV > LDO4_VOLT_MAX)
return -EINVAL;
return (uV - LDO_VOLT_BASE) / 12500;
default:
if (uV > LDO_VOLT_MAX)
return -EINVAL;
return (uV - LDO_VOLT_BASE) / 50000;
};
}
static int max77663_ldo_hex2volt(int idx, int hex)
{
if (hex > LDO_VOLT_MAX_HEX)
return -EINVAL;
switch (idx) {
case 0:
case 1:
return (hex * 25000) + LDO_VOLT_BASE;
case 4:
return (hex * 12500) + LDO_VOLT_BASE;
default:
return (hex * 50000) + LDO_VOLT_BASE;
};
}
static int max77663_ldo_val(struct udevice *dev, int op, int *uV)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
u32 adr = uc_pdata->ctrl_reg;
int idx = dev->driver_data;
int hex, val, ret;
val = pmic_reg_read(dev->parent, adr);
if (val < 0)
return val;
if (op == PMIC_OP_GET) {
*uV = 0;
ret = max77663_ldo_hex2volt(idx, val & LDO_VOLT_MASK);
if (ret < 0)
return ret;
*uV = ret;
return 0;
}
hex = max77663_ldo_volt2hex(idx, *uV);
if (hex < 0)
return hex;
val &= ~LDO_VOLT_MASK;
return pmic_reg_write(dev->parent, adr, val | hex);
}
static int max77663_ldo_probe(struct udevice *dev)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
int idx = dev->driver_data;
uc_pdata->type = REGULATOR_TYPE_LDO;
uc_pdata->ctrl_reg = max77663_ldo_reg[idx];
return 0;
}
static int ldo_get_value(struct udevice *dev)
{
int uV;
int ret;
ret = max77663_ldo_val(dev, PMIC_OP_GET, &uV);
if (ret)
return ret;
return uV;
}
static int ldo_set_value(struct udevice *dev, int uV)
{
return max77663_ldo_val(dev, PMIC_OP_SET, &uV);
}
static int ldo_get_enable(struct udevice *dev)
{
bool enable = false;
int ret;
ret = max77663_ldo_enable(dev, PMIC_OP_GET, &enable);
if (ret)
return ret;
return enable;
}
static int ldo_set_enable(struct udevice *dev, bool enable)
{
return max77663_ldo_enable(dev, PMIC_OP_SET, &enable);
}
static const struct dm_regulator_ops max77663_ldo_ops = {
.get_value = ldo_get_value,
.set_value = ldo_set_value,
.get_enable = ldo_get_enable,
.set_enable = ldo_set_enable,
};
U_BOOT_DRIVER(max77663_ldo) = {
.name = MAX77663_LDO_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &max77663_ldo_ops,
.probe = max77663_ldo_probe,
};

View File

@ -301,19 +301,23 @@ static int palmas_ldo_probe(struct udevice *dev)
uc_pdata->type = REGULATOR_TYPE_LDO;
if (dev->driver_data) {
/* check for ldoln and ldousb cases */
if (!strcmp("ldoln", dev->name)) {
uc_pdata->ctrl_reg = palmas_ldo_ctrl[type][9];
uc_pdata->volt_reg = palmas_ldo_volt[type][9];
return 0;
}
if (!strcmp("ldousb", dev->name)) {
uc_pdata->ctrl_reg = palmas_ldo_ctrl[type][10];
uc_pdata->volt_reg = palmas_ldo_volt[type][10];
return 0;
}
if (dev->driver_data > 0) {
u8 idx = dev->driver_data - 1;
uc_pdata->ctrl_reg = palmas_ldo_ctrl[type][idx];
uc_pdata->volt_reg = palmas_ldo_volt[type][idx];
} else {
/* check for ldoln and ldousb cases */
if (!strcmp("ldoln", dev->name)) {
uc_pdata->ctrl_reg = palmas_ldo_ctrl[type][9];
uc_pdata->volt_reg = palmas_ldo_volt[type][9];
} else if (!strcmp("ldousb", dev->name)) {
uc_pdata->ctrl_reg = palmas_ldo_ctrl[type][10];
uc_pdata->volt_reg = palmas_ldo_volt[type][10];
}
}
return 0;

View File

@ -0,0 +1,395 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <power/pmic.h>
#include <power/regulator.h>
#include <power/tps65910_pmic.h>
/* fist row is control registers, second is voltage registers */
static const char tps65911_vdd_reg[][TPS65911_VDD_NUM] = {
{ TPS65911_REG_VDD1, TPS65911_REG_VDD2,
TPS65911_REG_VDDCTRL, TPS65911_REG_VIO },
{ TPS65911_REG_VDD1_OP, TPS65911_REG_VDD2_OP,
TPS65911_REG_VDDCTRL_OP, 0x00 },
};
static const char tps65911_ldo_reg[TPS65911_LDO_NUM] = {
TPS65911_REG_LDO1, TPS65911_REG_LDO2, TPS65911_REG_LDO3,
TPS65911_REG_LDO4, TPS65911_REG_LDO5, TPS65911_REG_LDO6,
TPS65911_REG_LDO7, TPS65911_REG_LDO8
};
static int tps65911_regulator_enable(struct udevice *dev, int op, bool *enable)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
u32 adr = uc_pdata->ctrl_reg;
int val, ret;
val = pmic_reg_read(dev->parent, adr);
if (val < 0)
return val;
if (op == PMIC_OP_GET) {
if (val & TPS65910_SUPPLY_STATE_ON)
*enable = true;
else
*enable = false;
return 0;
} else if (op == PMIC_OP_SET) {
val &= ~TPS65910_SUPPLY_STATE_MASK;
if (*enable)
val |= TPS65910_SUPPLY_STATE_ON;
ret = pmic_reg_write(dev->parent, adr, val);
if (ret)
return ret;
}
return 0;
}
static int tps65911_get_enable(struct udevice *dev)
{
bool enable = false;
int ret;
ret = tps65911_regulator_enable(dev, PMIC_OP_GET, &enable);
if (ret)
return ret;
return enable;
}
static int tps65911_set_enable(struct udevice *dev, bool enable)
{
return tps65911_regulator_enable(dev, PMIC_OP_SET, &enable);
}
/**
* tps65911_vdd_volt2hex() - convert voltage in uV into
* applicable to register hex value
*
* @uV: voltage in uV
*
* Return: voltage in hex on success, -ve on failure
*/
static int tps65911_vdd_volt2hex(int uV)
{
if (uV > TPS65911_VDD_VOLT_MAX)
return -EINVAL;
if (uV < TPS65911_VDD_VOLT_MIN)
uV = TPS65911_VDD_VOLT_MIN;
return (uV - TPS65911_VDD_VOLT_BASE) / 12500;
}
/**
* tps65911_vdd_hex2volt() - convert register hex value into
* actual voltage in uV
*
* @hex: hex value of register
*
* Return: voltage in uV on success, -ve on failure
*/
static int tps65911_vdd_hex2volt(int hex)
{
if (hex > TPS65910_VDD_SEL_MAX)
return -EINVAL;
if (hex < TPS65910_VDD_SEL_MIN)
hex = TPS65910_VDD_SEL_MIN;
return TPS65911_VDD_VOLT_BASE + hex * 12500;
}
static int tps65911_vio_range[4] = {
1500000, 1800000, 2500000, 3300000
};
static int tps65911_vio_val(struct udevice *dev, int op, int *uV)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
u32 adr = uc_pdata->volt_reg;
int i, val;
val = pmic_reg_read(dev->parent, adr);
if (val < 0)
return val;
if (op == PMIC_OP_GET) {
*uV = 0;
val &= TPS65910_SEL_MASK;
*uV = tps65911_vio_range[val >> 2];
return 0;
}
val &= ~TPS65910_SEL_MASK;
for (i = 0; i < ARRAY_SIZE(tps65911_vio_range); i++)
if (*uV <= tps65911_vio_range[i])
break;
return pmic_reg_write(dev->parent, adr, val | i << 2);
}
static int tps65911_vdd_val(struct udevice *dev, int op, int *uV)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
u32 adr = uc_pdata->volt_reg;
int val, ret;
/* in case vdd is vio */
if (!adr)
return tps65911_vio_val(dev, op, uV);
val = pmic_reg_read(dev->parent, adr);
if (val < 0)
return val;
if (op == PMIC_OP_GET) {
*uV = 0;
ret = tps65911_vdd_hex2volt(val);
if (ret < 0)
return ret;
*uV = ret;
return 0;
}
val = tps65911_vdd_volt2hex(*uV);
if (val < 0)
return val;
return pmic_reg_write(dev->parent, adr, val);
}
static int tps65911_vdd_probe(struct udevice *dev)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
uc_pdata->type = REGULATOR_TYPE_BUCK;
/* check for vddctrl and vddio cases */
if (!strcmp("vddctrl", dev->name)) {
uc_pdata->ctrl_reg = tps65911_vdd_reg[0][2];
uc_pdata->volt_reg = tps65911_vdd_reg[1][2];
return 0;
}
if (!strcmp("vddio", dev->name)) {
uc_pdata->ctrl_reg = tps65911_vdd_reg[0][3];
uc_pdata->volt_reg = tps65911_vdd_reg[1][3];
return 0;
}
if (dev->driver_data > 0) {
u8 idx = dev->driver_data - 1;
uc_pdata->ctrl_reg = tps65911_vdd_reg[0][idx];
uc_pdata->volt_reg = tps65911_vdd_reg[1][idx];
}
return 0;
}
static int vdd_get_value(struct udevice *dev)
{
int uV;
int ret;
ret = tps65911_vdd_val(dev, PMIC_OP_GET, &uV);
if (ret)
return ret;
return uV;
}
static int vdd_set_value(struct udevice *dev, int uV)
{
return tps65911_vdd_val(dev, PMIC_OP_SET, &uV);
}
static const struct dm_regulator_ops tps65911_vdd_ops = {
.get_value = vdd_get_value,
.set_value = vdd_set_value,
.get_enable = tps65911_get_enable,
.set_enable = tps65911_set_enable,
};
U_BOOT_DRIVER(tps65911_vdd) = {
.name = TPS65911_VDD_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &tps65911_vdd_ops,
.probe = tps65911_vdd_probe,
};
/**
* tps65911_ldo_volt2hex() - convert voltage in uV into
* applicable to register hex value
*
* @idx: regulator index
* @uV: voltage in uV
*
* Return: voltage in hex on success, -ve on failure
*/
static int tps65911_ldo_volt2hex(int idx, int uV)
{
int step;
if (uV > TPS65911_LDO_VOLT_MAX)
return -EINVAL;
if (uV < TPS65911_LDO_VOLT_BASE)
uV = TPS65911_LDO_VOLT_BASE;
switch (idx) {
case 1:
case 2:
case 4:
step = TPS65911_LDO124_VOLT_STEP;
break;
case 3:
case 5:
case 6:
case 7:
case 8:
step = TPS65911_LDO358_VOLT_STEP;
break;
default:
return -EINVAL;
};
return ((uV - TPS65911_LDO_VOLT_BASE) / step) << 2;
}
/**
* tps65911_ldo_hex2volt() - convert register hex value into
* actual voltage in uV
*
* @idx: regulator index
* @hex: hex value of register
*
* Return: voltage in uV on success, -ve on failure
*/
static int tps65911_ldo_hex2volt(int idx, int hex)
{
int step;
switch (idx) {
case 1:
case 2:
case 4:
if (hex > TPS65911_LDO124_VOLT_MAX_HEX)
return -EINVAL;
step = TPS65911_LDO124_VOLT_STEP;
break;
case 3:
case 5:
case 6:
case 7:
case 8:
if (hex > TPS65911_LDO358_VOLT_MAX_HEX)
return -EINVAL;
if (hex < TPS65911_LDO358_VOLT_MIN_HEX)
hex = TPS65911_LDO358_VOLT_MIN_HEX;
step = TPS65911_LDO358_VOLT_STEP;
break;
default:
return -EINVAL;
};
return TPS65911_LDO_VOLT_BASE + hex * step;
}
static int tps65911_ldo_val(struct udevice *dev, int op, int *uV)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
u32 adr = uc_pdata->ctrl_reg;
int idx = dev->driver_data;
int val, hex, ret;
val = pmic_reg_read(dev->parent, adr);
if (val < 0)
return val;
if (op == PMIC_OP_GET) {
*uV = 0;
val &= TPS65911_LDO_SEL_MASK;
ret = tps65911_ldo_hex2volt(idx, val >> 2);
if (ret < 0)
return ret;
*uV = ret;
return 0;
}
hex = tps65911_ldo_volt2hex(idx, *uV);
if (hex < 0)
return hex;
val &= ~TPS65911_LDO_SEL_MASK;
return pmic_reg_write(dev->parent, adr, val | hex);
}
static int tps65911_ldo_probe(struct udevice *dev)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
u8 idx = dev->driver_data - 1;
uc_pdata->type = REGULATOR_TYPE_LDO;
uc_pdata->ctrl_reg = tps65911_ldo_reg[idx];
return 0;
}
static int ldo_get_value(struct udevice *dev)
{
int uV;
int ret;
ret = tps65911_ldo_val(dev, PMIC_OP_GET, &uV);
if (ret)
return ret;
return uV;
}
static int ldo_set_value(struct udevice *dev, int uV)
{
return tps65911_ldo_val(dev, PMIC_OP_SET, &uV);
}
static const struct dm_regulator_ops tps65911_ldo_ops = {
.get_value = ldo_get_value,
.set_value = ldo_set_value,
.get_enable = tps65911_get_enable,
.set_enable = tps65911_set_enable,
};
U_BOOT_DRIVER(tps65911_ldo) = {
.name = TPS65911_LDO_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &tps65911_ldo_ops,
.probe = tps65911_ldo_probe,
};

View File

@ -0,0 +1,347 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <power/pmic.h>
#include <power/regulator.h>
#include <power/tps80031.h>
static const char tps80031_smps_reg[][TPS80031_SMPS_NUM] = {
{ 0x54, 0x5a, 0x66, 0x42, 0x48 },
{ 0x56, 0x5c, 0x68, 0x44, 0x4a },
{ BIT(3), BIT(4), BIT(6), BIT(0), BIT(1) },
};
static const char tps80031_ldo_reg[][TPS80031_LDO_NUM] = {
{ 0x9e, 0x86, 0x8e, 0x8a, 0x9a, 0x92, 0xa6, 0x96, 0xa2 },
{ 0x9f, 0x87, 0x8f, 0x8b, 0x9b, 0x93, 0xa7, 0x97, 0xa3 },
};
static int tps80031_regulator_enable(struct udevice *dev, int op, bool *enable)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
u32 adr = uc_pdata->ctrl_reg;
int val, ret;
val = pmic_reg_read(dev->parent, adr);
if (val < 0)
return val;
if (op == PMIC_OP_GET) {
if (val & REGULATOR_MODE_ON)
*enable = true;
else
*enable = false;
return 0;
} else if (op == PMIC_OP_SET) {
val &= ~REGULATOR_STATUS_MASK;
if (*enable)
val |= REGULATOR_MODE_ON;
ret = pmic_reg_write(dev->parent, adr, val);
if (ret)
return ret;
}
return 0;
}
static int tps80031_get_enable(struct udevice *dev)
{
bool enable = false;
int ret;
ret = tps80031_regulator_enable(dev, PMIC_OP_GET, &enable);
if (ret)
return ret;
return enable;
}
static int tps80031_set_enable(struct udevice *dev, bool enable)
{
return tps80031_regulator_enable(dev, PMIC_OP_SET, &enable);
}
/**
* tps80031_ldo_volt2hex() - convert voltage in uV into
* applicable to register hex value
*
* @uV: voltage in uV
*
* Return: voltage in hex on success, -ve on failure
*/
static int tps80031_ldo_volt2hex(int uV)
{
if (uV > LDO_VOLT_MAX)
return -EINVAL;
if (uV < LDO_VOLT_MIN)
uV = LDO_VOLT_MIN;
return DIV_ROUND_UP(uV - LDO_VOLT_BASE, 102000);
}
/**
* tps80031_ldo_hex2volt() - convert register hex value into
* actual voltage in uV
*
* @hex: hex value of register
*
* Return: voltage in uV on success, -ve on failure
*/
static int tps80031_ldo_hex2volt(int hex)
{
if (hex > LDO_VOLT_MAX_HEX)
return -EINVAL;
if (hex < LDO_VOLT_MIN_HEX)
hex = LDO_VOLT_MIN_HEX;
return LDO_VOLT_BASE + hex * 102000;
}
static int tps80031_ldo_val(struct udevice *dev, int op, int *uV)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
u32 adr = uc_pdata->volt_reg;
int val, hex, ret;
val = pmic_reg_read(dev->parent, adr);
if (val < 0)
return val;
if (op == PMIC_OP_GET) {
*uV = 0;
ret = tps80031_ldo_hex2volt(val & LDO_VOLT_MASK);
if (ret < 0)
return ret;
*uV = ret;
return 0;
}
hex = tps80031_ldo_volt2hex(*uV);
if (hex < 0)
return hex;
val &= ~LDO_VOLT_MASK;
return pmic_reg_write(dev->parent, adr, val | hex);
}
static int tps80031_ldo_probe(struct udevice *dev)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
uc_pdata->type = REGULATOR_TYPE_LDO;
/* check for ldoln and ldousb cases */
if (!strcmp("ldoln", dev->name)) {
uc_pdata->ctrl_reg = tps80031_ldo_reg[CTRL][7];
uc_pdata->volt_reg = tps80031_ldo_reg[VOLT][7];
return 0;
}
if (!strcmp("ldousb", dev->name)) {
uc_pdata->ctrl_reg = tps80031_ldo_reg[CTRL][8];
uc_pdata->volt_reg = tps80031_ldo_reg[VOLT][8];
return 0;
}
if (dev->driver_data > 0) {
u8 idx = dev->driver_data - 1;
uc_pdata->ctrl_reg = tps80031_ldo_reg[CTRL][idx];
uc_pdata->volt_reg = tps80031_ldo_reg[VOLT][idx];
}
return 0;
}
static int ldo_get_value(struct udevice *dev)
{
int uV;
int ret;
ret = tps80031_ldo_val(dev, PMIC_OP_GET, &uV);
if (ret)
return ret;
return uV;
}
static int ldo_set_value(struct udevice *dev, int uV)
{
return tps80031_ldo_val(dev, PMIC_OP_SET, &uV);
}
static const struct dm_regulator_ops tps80031_ldo_ops = {
.get_value = ldo_get_value,
.set_value = ldo_set_value,
.get_enable = tps80031_get_enable,
.set_enable = tps80031_set_enable,
};
U_BOOT_DRIVER(tps80031_ldo) = {
.name = TPS80031_LDO_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &tps80031_ldo_ops,
.probe = tps80031_ldo_probe,
};
struct tps80031_smps_priv {
int flags;
};
/* DCDC voltages for the selector of 0x39 to 0x3F */
static int tps80031_dcdc_voltages[5] = {
1350000, 1500000, 1800000, 1900000, 2100000
};
/**
* tps80031_smps_volt2hex() - convert voltage in uV into
* applicable to register hex value
*
* @base: base voltage in uV
* @uV: voltage in uV
*
* Return: voltage in hex on success, -ve on failure
*/
static int tps80031_smps_volt2hex(u32 base, int uV)
{
int i;
if (uV < base)
return 1;
if (uV > SMPS_VOLT_LINEAR) {
for (i = 0; i < ARRAY_SIZE(tps80031_dcdc_voltages); i++)
if (uV <= tps80031_dcdc_voltages[i])
break;
return SMPS_VOLT_NLINEAR_HEX + i;
}
return DIV_ROUND_UP(uV - base, 12500);
}
/**
* tps80031_smps_hex2volt() - convert register hex value into
* actual voltage in uV
*
* @base: base voltage in uV
* @hex: hex value of register
*
* Return: voltage in uV on success, -ve on failure
*/
static int tps80031_smps_hex2volt(u32 base, int hex)
{
if (!hex)
return 0;
/* if reg value exceeds linear scale use table */
if (hex > SMPS_VOLT_LINEAR_HEX)
return tps80031_dcdc_voltages[hex - SMPS_VOLT_LINEAR_HEX];
else
return base + hex * 12500;
}
static int tps80031_smps_val(struct udevice *dev, int op, int *uV)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
struct tps80031_smps_priv *priv = dev_get_priv(dev);
u32 adr = uc_pdata->volt_reg;
int base, val, hex, ret;
/* If offset flag was set then base voltage is higher */
if (priv->flags & TPS80031_OFFSET_FLAG)
base = SMPS_VOLT_BASE_OFFSET;
else
base = SMPS_VOLT_BASE;
val = pmic_reg_read(dev->parent, adr);
if (val < 0)
return val;
if (op == PMIC_OP_GET) {
*uV = 0;
ret = tps80031_smps_hex2volt(base, val & SMPS_VOLT_MASK);
if (ret < 0)
return ret;
*uV = ret;
return 0;
}
hex = tps80031_smps_volt2hex(base, *uV);
if (hex < 0)
return hex;
val &= ~SMPS_VOLT_MASK;
return pmic_reg_write(dev->parent, adr, val | hex);
}
static int tps80031_smps_probe(struct udevice *dev)
{
struct dm_regulator_uclass_plat *uc_pdata =
dev_get_uclass_plat(dev);
struct tps80031_smps_priv *priv = dev_get_priv(dev);
int idx = dev->driver_data - 1;
int val;
uc_pdata->type = REGULATOR_TYPE_BUCK;
uc_pdata->ctrl_reg = tps80031_smps_reg[CTRL][idx];
uc_pdata->volt_reg = tps80031_smps_reg[VOLT][idx];
/* Determine if smps regulator uses higher voltage */
val = pmic_reg_read(dev->parent, TPS80031_SMPS_OFFSET);
if (val & tps80031_smps_reg[OFFSET][idx])
priv->flags |= TPS80031_OFFSET_FLAG;
return 0;
}
static int smps_get_value(struct udevice *dev)
{
int uV;
int ret;
ret = tps80031_smps_val(dev, PMIC_OP_GET, &uV);
if (ret)
return ret;
return uV;
}
static int smps_set_value(struct udevice *dev, int uV)
{
return tps80031_smps_val(dev, PMIC_OP_SET, &uV);
}
static const struct dm_regulator_ops tps80031_smps_ops = {
.get_value = smps_get_value,
.set_value = smps_set_value,
.get_enable = tps80031_get_enable,
.set_enable = tps80031_set_enable,
};
U_BOOT_DRIVER(tps80031_smps) = {
.name = TPS80031_SMPS_DRIVER,
.id = UCLASS_REGULATOR,
.ops = &tps80031_smps_ops,
.probe = tps80031_smps_probe,
.priv_auto = sizeof(struct tps80031_smps_priv),
};

View File

@ -74,6 +74,13 @@ config SYSRESET_GPIO
example on Microblaze where reset logic can be controlled via GPIO
pin which triggers cpu reset.
config SYSRESET_MAX77663
bool "Enable support for MAX77663 PMIC System Reset"
depends on DM_PMIC_MAX77663
select SYSRESET_CMD_POWEROFF if CMD_POWEROFF
help
Enable system power management functions found in MAX77663 PMIC.
config SYSRESET_MICROBLAZE
bool "Enable support for Microblaze soft reset"
depends on MICROBLAZE
@ -102,6 +109,13 @@ config SYSRESET_SPL_AT91
This enables the system reset driver support for Microchip/Atmel
SoCs in SPL.
config SYSRESET_PALMAS
bool "Enable support for PALMAS System Reset"
depends on PMIC_PALMAS
select SYSRESET_CMD_POWEROFF if CMD_POWEROFF
help
Enable system power management functions found in PLAMAS PMIC family.
config SYSRESET_PSCI
bool "Enable support for PSCI System Reset"
depends on ARM_PSCI_FW
@ -137,6 +151,12 @@ config SYSRESET_SOCFPGA_SOC64
This enables the system reset driver support for Intel SOCFPGA
SoC64 SoCs.
config SYSRESET_TEGRA
bool "Tegra PMC system reset driver"
depends on ARCH_TEGRA
help
This enables the system reset ability of PMC used in Tegra SoCs.
config SYSRESET_TI_SCI
bool "TI System Control Interface (TI SCI) system reset driver"
depends on TI_SCI_PROTOCOL
@ -144,6 +164,22 @@ config SYSRESET_TI_SCI
This enables the system reset driver support over TI System Control
Interface available on some new TI's SoCs.
config SYSRESET_TPS65910
bool "Enable support for TPS65910/TPS65911 PMIC System Reset"
depends on DM_PMIC_TPS65910
select SYSRESET_CMD_POWEROFF if CMD_POWEROFF
help
Enable system power management functions found in TPS65910/TPS65911
PMICs.
config SYSRESET_TPS80031
bool "Enable support for TPS80031/TPS80032 PMIC System Reset"
depends on DM_PMIC_TPS80031
select SYSRESET_CMD_POWEROFF if CMD_POWEROFF
help
Enable system power management functions found in TPS80031/TPS80032
PMICs.
config SYSRESET_SYSCON
bool "Enable support for mfd syscon reboot driver"
select REGMAP

View File

@ -9,14 +9,19 @@ obj-$(CONFIG_ARCH_STI) += sysreset_sti.o
obj-$(CONFIG_SANDBOX) += sysreset_sandbox.o
obj-$(CONFIG_POWEROFF_GPIO) += poweroff_gpio.o
obj-$(CONFIG_SYSRESET_GPIO) += sysreset_gpio.o
obj-$(CONFIG_$(SPL_TPL_)SYSRESET_MAX77663) += sysreset_max77663.o
obj-$(CONFIG_SYSRESET_MPC83XX) += sysreset_mpc83xx.o
obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o
obj-$(CONFIG_SYSRESET_OCTEON) += sysreset_octeon.o
obj-$(CONFIG_$(SPL_TPL_)SYSRESET_PALMAS) += sysreset_palmas.o
obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o
obj-$(CONFIG_SYSRESET_SBI) += sysreset_sbi.o
obj-$(CONFIG_SYSRESET_SOCFPGA) += sysreset_socfpga.o
obj-$(CONFIG_SYSRESET_SOCFPGA_SOC64) += sysreset_socfpga_soc64.o
obj-$(CONFIG_SYSRESET_TEGRA) += sysreset_tegra.o
obj-$(CONFIG_SYSRESET_TI_SCI) += sysreset-ti-sci.o
obj-$(CONFIG_$(SPL_TPL_)SYSRESET_TPS65910) += sysreset_tps65910.o
obj-$(CONFIG_$(SPL_TPL_)SYSRESET_TPS80031) += sysreset_tps80031.o
obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o
obj-$(CONFIG_SYSRESET_RESETCTL) += sysreset_resetctl.o

View File

@ -0,0 +1,52 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <i2c.h>
#include <errno.h>
#include <sysreset.h>
#include <power/pmic.h>
#include <power/max77663.h>
static int max77663_sysreset_request(struct udevice *dev,
enum sysreset_t type)
{
int val;
val = pmic_reg_read(dev->parent, MAX77663_REG_ONOFF_CFG1);
if (val < 0)
return val;
/* clear both bits */
val &= ~ONOFF_SFT_RST;
val &= ~ONOFF_PWR_OFF;
switch (type) {
case SYSRESET_POWER:
/* MAX77663: SFT_RST > ONOFF_CFG1 */
pmic_reg_write(dev->parent, MAX77663_REG_ONOFF_CFG1,
val | ONOFF_SFT_RST);
break;
case SYSRESET_POWER_OFF:
/* MAX77663: PWR_OFF > ONOFF_CFG1 */
pmic_reg_write(dev->parent, MAX77663_REG_ONOFF_CFG1,
val | ONOFF_PWR_OFF);
break;
default:
return -EPROTONOSUPPORT;
}
return -EINPROGRESS;
}
static struct sysreset_ops max77663_sysreset = {
.request = max77663_sysreset_request,
};
U_BOOT_DRIVER(sysreset_max77663) = {
.id = UCLASS_SYSRESET,
.name = MAX77663_RST_DRIVER,
.ops = &max77663_sysreset,
};

View File

@ -0,0 +1,52 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <i2c.h>
#include <errno.h>
#include <sysreset.h>
#include <power/pmic.h>
#include <power/palmas.h>
static int palmas_sysreset_request(struct udevice *dev,
enum sysreset_t type)
{
struct palmas_priv *priv = dev_get_priv(dev->parent);
int ret;
/*
* Mask INT3 on second page which detects vbus
* or device will immediately turn on.
*/
ret = dm_i2c_reg_clrset(priv->chip2, PALMAS_INT3_MASK,
MASK_VBUS, MASK_VBUS);
if (ret < 0)
return ret;
switch (type) {
case SYSRESET_POWER:
/* PALMAS: SW_RST > DEV_CTRL */
pmic_reg_write(dev->parent, PALMAS_DEV_CTRL, SW_RST);
break;
case SYSRESET_POWER_OFF:
/* PALMAS: DEV_OFF > DEV_CTRL */
pmic_reg_write(dev->parent, PALMAS_DEV_CTRL, DEV_OFF);
break;
default:
return -EPROTONOSUPPORT;
}
return -EINPROGRESS;
}
static struct sysreset_ops palmas_sysreset = {
.request = palmas_sysreset_request,
};
U_BOOT_DRIVER(sysreset_palmas) = {
.id = UCLASS_SYSRESET,
.name = PALMAS_RST_DRIVER,
.ops = &palmas_sysreset,
};

View File

@ -0,0 +1,45 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <errno.h>
#include <sysreset.h>
#include <linux/err.h>
#include <asm/arch-tegra/pmc.h>
static int tegra_sysreset_request(struct udevice *dev,
enum sysreset_t type)
{
u32 value;
switch (type) {
case SYSRESET_WARM:
case SYSRESET_COLD:
/* resets everything but scratch 0 and reset status */
value = tegra_pmc_readl(PMC_CNTRL);
value |= PMC_CNTRL_MAIN_RST;
tegra_pmc_writel(value, PMC_CNTRL);
break;
default:
return -EPROTONOSUPPORT;
}
return -EINPROGRESS;
}
static struct sysreset_ops tegra_sysreset = {
.request = tegra_sysreset_request,
};
U_BOOT_DRIVER(sysreset_tegra) = {
.id = UCLASS_SYSRESET,
.name = "sysreset_tegra",
.ops = &tegra_sysreset,
};
/* Link to Tegra PMC once there is a driver */
U_BOOT_DRVINFO(sysreset_tegra) = {
.name = "sysreset_tegra"
};

View File

@ -0,0 +1,54 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <i2c.h>
#include <errno.h>
#include <sysreset.h>
#include <power/pmic.h>
#include <power/tps65910_pmic.h>
static int tps65910_sysreset_request(struct udevice *dev,
enum sysreset_t type)
{
int val;
val = pmic_reg_read(dev->parent, TPS65910_REG_DEVICE_CTRL);
if (val < 0)
return val;
/* define power-off to be sequential */
val |= PWR_OFF_SEQ;
pmic_reg_write(dev->parent, TPS65910_REG_DEVICE_CTRL, val);
val &= ~DEV_ON;
switch (type) {
case SYSRESET_POWER:
/* TPS65910: DEV_OFF_RST > DEVICE_CTRL */
pmic_reg_write(dev->parent, TPS65910_REG_DEVICE_CTRL,
val | DEV_OFF_RST);
break;
case SYSRESET_POWER_OFF:
/* TPS65910: DEV_OFF > DEVICE_CTRL */
pmic_reg_write(dev->parent, TPS65910_REG_DEVICE_CTRL,
val | DEV_OFF);
break;
default:
return -EPROTONOSUPPORT;
}
return -EINPROGRESS;
}
static struct sysreset_ops tps65910_sysreset = {
.request = tps65910_sysreset_request,
};
U_BOOT_DRIVER(sysreset_tps65910) = {
.id = UCLASS_SYSRESET,
.name = TPS65910_RST_DRIVER,
.ops = &tps65910_sysreset,
};

View File

@ -0,0 +1,40 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#include <dm.h>
#include <i2c.h>
#include <errno.h>
#include <sysreset.h>
#include <power/pmic.h>
#include <power/tps80031.h>
static int tps80031_sysreset_request(struct udevice *dev,
enum sysreset_t type)
{
switch (type) {
case SYSRESET_POWER:
/* TPS80031: SW_RESET > PHOENIX_DEV_ON */
pmic_reg_write(dev->parent, TPS80031_PHOENIX_DEV_ON, SW_RESET);
break;
case SYSRESET_POWER_OFF:
/* TPS80031: DEVOFF > PHOENIX_DEV_ON */
pmic_reg_write(dev->parent, TPS80031_PHOENIX_DEV_ON, DEVOFF);
break;
default:
return -EPROTONOSUPPORT;
}
return -EINPROGRESS;
}
static struct sysreset_ops tps80031_sysreset = {
.request = tps80031_sysreset_request,
};
U_BOOT_DRIVER(sysreset_tps80031) = {
.id = UCLASS_SYSRESET,
.name = TPS80031_RST_DRIVER,
.ops = &tps80031_sysreset,
};

View File

@ -64,19 +64,14 @@
"else echo SPI flash backup FAILED! Aborting ...;" \
"poweroff; fi\0"
#define TRANSFORMER_REFRESH_USB \
"refresh_usb=usb start; usb reset; usb tree; usb info;" \
"pause 'Press ANY key to return to bootmenu...'; bootmenu\0"
#define TRANSFORMER_BOOTMENU \
TRANSFORMER_FLASH_UBOOT \
TRANSFORMER_FLASH_SPI \
TRANSFORMER_REFRESH_USB \
"bootmenu_0=mount internal storage=usb start && ums 0 mmc 0; bootmenu\0" \
"bootmenu_1=mount external storage=usb start && ums 0 mmc 1; bootmenu\0" \
"bootmenu_2=fastboot=echo Starting Fastboot protocol ...; fastboot usb 0; bootmenu\0" \
"bootmenu_3=update bootloader=run flash_uboot\0" \
"bootmenu_4=refresh USB=run refresh_usb\0" \
"bootmenu_4=enter console=usb start; setenv skip_boot 1; exit\0" \
"bootmenu_5=reboot RCM=enterrcm\0" \
"bootmenu_6=reboot=reset\0" \
"bootmenu_7=power off=poweroff\0" \

47
include/power/max77663.h Normal file
View File

@ -0,0 +1,47 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#ifndef _MAX77663_H_
#define _MAX77663_H_
#define MAX77663_LDO_NUM 9
#define MAX77663_SD_NUM 5
/* Drivers name */
#define MAX77663_LDO_DRIVER "max77663_ldo"
#define MAX77663_SD_DRIVER "max77663_sd"
#define MAX77663_RST_DRIVER "max77663_rst"
/* Step-Down (SD) Regulator calculations */
#define SD_STATUS_MASK 0x30
#define SD0_VOLT_MAX_HEX 0x40
#define SD1_VOLT_MAX_HEX 0x4c
#define SD_VOLT_MAX_HEX 0xff
#define SD_VOLT_MIN_HEX 0x02
#define SD0_VOLT_MAX 1400000
#define SD1_VOLT_MAX 1550000
#define SD_VOLT_MAX 3787500
#define SD_VOLT_MIN 625000
#define SD_VOLT_BASE 600000
/* Low-Dropout Linear (LDO) Regulator calculations */
#define LDO_STATUS_MASK 0xc0
#define LDO_VOLT_MASK 0x3f
#define LDO_VOLT_MAX_HEX 0x3f
#define LDO01_VOLT_MAX 2375000
#define LDO4_VOLT_MAX 1587500
#define LDO_VOLT_MAX 3950000
#define LDO_VOLT_BASE 800000
#define MAX77663_REG_ONOFF_CFG1 0x41
#define ONOFF_SFT_RST BIT(7)
#define ONOFF_PWR_OFF BIT(1)
#endif /* _MAX77663_H_ */

View File

@ -2,6 +2,10 @@
#define TPS659038 0x1
#define TPS65917 0x2
struct palmas_priv {
struct udevice *chip2;
};
/* I2C device address for pmic palmas */
#define PALMAS_I2C_ADDR (0x12 >> 1)
#define PALMAS_LDO_NUM 11
@ -10,6 +14,7 @@
/* Drivers name */
#define PALMAS_LDO_DRIVER "palmas_ldo"
#define PALMAS_SMPS_DRIVER "palmas_smps"
#define PALMAS_RST_DRIVER "palmas_rst"
#define PALMAS_SMPS_VOLT_MASK 0x7F
#define PALMAS_SMPS_RANGE_MASK 0x80
@ -24,3 +29,9 @@
#define PALMAS_LDO_MODE_MASK 0x1
#define PALMAS_LDO_STATUS_MASK 0x10
#define PALMAS_LDO_BYPASS_EN 0x40
#define PALMAS_DEV_CTRL 0xA0
#define SW_RST BIT(1)
#define DEV_OFF 0x00
#define PALMAS_INT3_MASK 0x1B
#define MASK_VBUS BIT(7)

View File

@ -17,6 +17,12 @@
#define TPS65910_SUPPLY_STATE_OFF 0x0
#define TPS65910_SUPPLY_STATE_ON 0x1
/* TPS65910 DEVICE_CTRL bits */
#define PWR_OFF_SEQ BIT(7)
#define DEV_OFF_RST BIT(3)
#define DEV_ON BIT(2)
#define DEV_OFF BIT(0)
/* i2c registers */
enum {
TPS65910_REG_RTC_SEC = 0x00,
@ -125,5 +131,50 @@ struct tps65910_regulator_pdata {
#define TPS65910_BUCK_DRIVER "tps65910_buck"
#define TPS65910_BOOST_DRIVER "tps65910_boost"
#define TPS65910_LDO_DRIVER "tps65910_ldo"
#define TPS65910_RST_DRIVER "tps65910_rst"
/* tps65911 i2c registers */
enum {
TPS65911_REG_VIO = 0x20,
TPS65911_REG_VDD1,
TPS65911_REG_VDD1_OP,
TPS65911_REG_VDD1_SR,
TPS65911_REG_VDD2,
TPS65911_REG_VDD2_OP,
TPS65911_REG_VDD2_SR,
TPS65911_REG_VDDCTRL,
TPS65911_REG_VDDCTRL_OP,
TPS65911_REG_VDDCTRL_SR,
TPS65911_REG_LDO1 = 0x30,
TPS65911_REG_LDO2,
TPS65911_REG_LDO5,
TPS65911_REG_LDO8,
TPS65911_REG_LDO7,
TPS65911_REG_LDO6,
TPS65911_REG_LDO4,
TPS65911_REG_LDO3,
};
#define TPS65911_VDD_NUM 4
#define TPS65911_LDO_NUM 8
#define TPS65911_VDD_VOLT_MAX 1500000
#define TPS65911_VDD_VOLT_MIN 600000
#define TPS65911_VDD_VOLT_BASE 562500
#define TPS65911_LDO_VOLT_MAX 3300000
#define TPS65911_LDO_VOLT_BASE 800000
#define TPS65911_LDO_SEL_MASK (0x3f << 2)
#define TPS65911_LDO124_VOLT_MAX_HEX 0x32
#define TPS65911_LDO358_VOLT_MAX_HEX 0x19
#define TPS65911_LDO358_VOLT_MIN_HEX 0x02
#define TPS65911_LDO124_VOLT_STEP 50000
#define TPS65911_LDO358_VOLT_STEP 100000
#define TPS65911_VDD_DRIVER "tps65911_vdd"
#define TPS65911_LDO_DRIVER "tps65911_ldo"
#endif /* __TPS65910_PMIC_H_ */

50
include/power/tps80031.h Normal file
View File

@ -0,0 +1,50 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright(C) 2023 Svyatoslav Ryhel <clamor95@gmail.com>
*/
#ifndef _TPS80031_H_
#define _TPS80031_H_
#define TPS80031_LDO_NUM 9
#define TPS80031_SMPS_NUM 5
/* Drivers name */
#define TPS80031_LDO_DRIVER "tps80031_ldo"
#define TPS80031_SMPS_DRIVER "tps80031_smps"
#define TPS80031_RST_DRIVER "tps80031_rst"
#define TPS80031_SMPS_OFFSET 0xe0
#define TPS80031_OFFSET_FLAG BIT(0)
#define REGULATOR_STATUS_MASK 0x3
#define REGULATOR_MODE_ON 0x1
/* Switched-Mode Power Supply Regulator calculations */
#define SMPS_VOLT_MASK 0x3f
#define SMPS_VOLT_LINEAR_HEX 0x39
#define SMPS_VOLT_NLINEAR_HEX 0x3a
#define SMPS_VOLT_LINEAR 1300000
#define SMPS_VOLT_BASE 600000
#define SMPS_VOLT_BASE_OFFSET 700000
/* Low-Dropout Linear (LDO) Regulator calculations */
#define LDO_VOLT_MASK 0x3f
#define LDO_VOLT_MAX_HEX 0x18
#define LDO_VOLT_MIN_HEX 0x01
#define LDO_VOLT_MAX 3360000
#define LDO_VOLT_MIN 1018000
#define LDO_VOLT_BASE 916000
#define TPS80031_PHOENIX_DEV_ON 0x25
#define SW_RESET BIT(6)
#define DEVOFF BIT(0)
/* register groups */
enum {
CTRL,
VOLT,
OFFSET,
};
#endif /* _TPS80031_H_ */