From a87b564018ac3a2beb460439ba002e4c0cb59998 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 11 Apr 2025 08:49:12 +0300 Subject: [PATCH 01/13] gpio: tegra_gpio: implement rfree operation Releasing a GPIO on Tegra necessitates changing its configuration to SFIO to activate its special function. Without this reconfiguration, the special function will be unavailable. Signed-off-by: Svyatoslav Ryhel --- drivers/gpio/tegra_gpio.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c index b83df351e74..3d1e18854f2 100644 --- a/drivers/gpio/tegra_gpio.c +++ b/drivers/gpio/tegra_gpio.c @@ -248,6 +248,16 @@ static int tegra_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, return 0; } +static int tegra_gpio_rfree(struct udevice *dev, unsigned int offset) +{ + struct tegra_port_info *state = dev_get_priv(dev); + + /* Set the pin as a SFIO */ + set_config(state->base_gpio + offset, CFG_SFIO); + + return 0; +} + static const struct dm_gpio_ops gpio_tegra_ops = { .direction_input = tegra_gpio_direction_input, .direction_output = tegra_gpio_direction_output, @@ -255,6 +265,7 @@ static const struct dm_gpio_ops gpio_tegra_ops = { .set_value = tegra_gpio_set_value, .get_function = tegra_gpio_get_function, .xlate = tegra_gpio_xlate, + .rfree = tegra_gpio_rfree, }; /* From 68d1b0f84aa8128eeed4a1d13ddf8e5a57630011 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Sun, 6 Oct 2024 14:50:02 +0300 Subject: [PATCH 02/13] power: pmic: add the base MAX8907 PMIC support Add basic i2c based read/write functions to access PMIC registers. Tested-by: Ion Agorria Signed-off-by: Svyatoslav Ryhel --- drivers/power/pmic/Kconfig | 9 ++++++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/max8907.c | 53 ++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 drivers/power/pmic/max8907.c diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index 5a61cd45b8c..ec7ccc3a63f 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -184,6 +184,15 @@ config SPL_DM_PMIC_PFUZE100 This config enables implementation of driver-model pmic uclass features for PMIC PFUZE100 in SPL. The driver implements read/write operations. +config DM_PMIC_MAX8907 + bool "Enable Driver Model for PMIC MAX8907" + ---help--- + This config enables implementation of driver-model pmic uclass features + for PMIC MAX8907. The driver implements read/write operations. + This is a Power Management IC with a decent set of peripherals from which + 3 DC-to-DC Step-Down (SD) Regulators, 20 Low-Dropout Linear (LDO) Regulators, + Real-Time Clock (RTC) and more with I2C Compatible Interface. + config DM_PMIC_MAX77663 bool "Enable Driver Model for PMIC MAX77663" ---help--- diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 2210b1a64ae..6bebffb05a6 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_$(PHASE_)DM_PMIC) += pmic-uclass.o obj-$(CONFIG_$(PHASE_)DM_PMIC_FAN53555) += fan53555.o obj-$(CONFIG_$(PHASE_)DM_PMIC_DA9063) += da9063.o obj-$(CONFIG_$(PHASE_)DM_PMIC_MAX77663) += max77663.o +obj-$(CONFIG_$(PHASE_)DM_PMIC_MAX8907) += max8907.o obj-$(CONFIG_DM_PMIC_MAX77686) += max77686.o obj-$(CONFIG_DM_PMIC_MAX8998) += max8998.o obj-$(CONFIG_DM_PMIC_MC34708) += mc34708.o diff --git a/drivers/power/pmic/max8907.c b/drivers/power/pmic/max8907.c new file mode 100644 index 00000000000..aeb6fe734e6 --- /dev/null +++ b/drivers/power/pmic/max8907.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2024 Svyatoslav Ryhel + */ + +#include +#include +#include + +static int max8907_write(struct udevice *dev, uint reg, const uint8_t *buff, int len) +{ + int ret; + + ret = dm_i2c_write(dev, reg, buff, len); + if (ret) { + log_debug("%s: write error to device: %p register: %#x!\n", + __func__, dev, reg); + return ret; + } + + return 0; +} + +static int max8907_read(struct udevice *dev, uint reg, uint8_t *buff, int len) +{ + int ret; + + ret = dm_i2c_read(dev, reg, buff, len); + if (ret) { + log_debug("%s: read error from device: %p register: %#x!\n", + __func__, dev, reg); + return ret; + } + + return 0; +} + +static struct dm_pmic_ops max8907_ops = { + .read = max8907_read, + .write = max8907_write, +}; + +static const struct udevice_id max8907_ids[] = { + { .compatible = "maxim,max8907" }, + { } +}; + +U_BOOT_DRIVER(pmic_max8907) = { + .name = "max8907_pmic", + .id = UCLASS_PMIC, + .of_match = max8907_ids, + .ops = &max8907_ops, +}; From 5204a362b8c80049e5242d92994637b3bac94d14 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Sun, 6 Oct 2024 14:59:54 +0300 Subject: [PATCH 03/13] power: regulator: max9807: add regulator support Added a new regulator driver for the MAXIM MAX8907 PMIC, providing essential regulator functionalities and incorporated the necessary binding framework within the core PMIC driver. Tested-by: Ion Agorria Signed-off-by: Svyatoslav Ryhel --- drivers/power/pmic/max8907.c | 29 +++ drivers/power/regulator/Kconfig | 9 + drivers/power/regulator/Makefile | 1 + drivers/power/regulator/max8907_regulator.c | 249 ++++++++++++++++++++ include/power/max8907.h | 73 ++++++ 5 files changed, 361 insertions(+) create mode 100644 drivers/power/regulator/max8907_regulator.c create mode 100644 include/power/max8907.h diff --git a/drivers/power/pmic/max8907.c b/drivers/power/pmic/max8907.c index aeb6fe734e6..5d35957bf40 100644 --- a/drivers/power/pmic/max8907.c +++ b/drivers/power/pmic/max8907.c @@ -6,6 +6,13 @@ #include #include #include +#include + +static const struct pmic_child_info pmic_children_info[] = { + { .prefix = "ldo", .driver = MAX8907_LDO_DRIVER }, + { .prefix = "sd", .driver = MAX8907_SD_DRIVER }, + { }, +}; static int max8907_write(struct udevice *dev, uint reg, const uint8_t *buff, int len) { @@ -35,6 +42,27 @@ static int max8907_read(struct udevice *dev, uint reg, uint8_t *buff, int len) return 0; } +static int max8907_bind(struct udevice *dev) +{ + ofnode regulators_node; + int children; + + regulators_node = dev_read_subnode(dev, "regulators"); + if (!ofnode_valid(regulators_node)) { + log_err("%s regulators subnode not found!\n", dev->name); + return -ENXIO; + } + + log_debug("%s: '%s' - found regulators subnode\n", __func__, dev->name); + + children = pmic_bind_children(dev, regulators_node, pmic_children_info); + if (!children) + log_err("%s - no child found\n", dev->name); + + /* Always return success for this device */ + return 0; +} + static struct dm_pmic_ops max8907_ops = { .read = max8907_read, .write = max8907_write, @@ -49,5 +77,6 @@ U_BOOT_DRIVER(pmic_max8907) = { .name = "max8907_pmic", .id = UCLASS_PMIC, .of_match = max8907_ids, + .bind = max8907_bind, .ops = &max8907_ops, }; diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index 95912ef5633..7ed435f0202 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -148,6 +148,15 @@ config SPL_REGULATOR_PWM This config enables implementation of driver-model regulator uclass features for PWM regulators in SPL. +config DM_REGULATOR_MAX8907 + bool "Enable Driver Model for REGULATOR MAX8907" + depends on DM_REGULATOR && DM_PMIC_MAX8907 + ---help--- + This config enables implementation of driver-model regulator uclass + features for REGULATOR MAX8907. The driver supports both DC-to-DC + Step-Down (SD) Regulators and Low-Dropout Linear (LDO) Regulators + found in MAX8907 PMIC and implements get/set api for value and enable. + config DM_REGULATOR_MAX77663 bool "Enable Driver Model for REGULATOR MAX77663" depends on DM_REGULATOR && DM_PMIC_MAX77663 diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index 0ee5d908a2a..ee8f56ea3b9 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_$(PHASE_)REGULATOR_AXP_DRIVEVBUS) += axp_drivevbus.o obj-$(CONFIG_$(PHASE_)REGULATOR_AXP_USB_POWER) += axp_usb_power.o obj-$(CONFIG_$(PHASE_)DM_REGULATOR_DA9063) += da9063.o obj-$(CONFIG_$(PHASE_)DM_REGULATOR_MAX77663) += max77663_regulator.o +obj-$(CONFIG_$(PHASE_)DM_REGULATOR_MAX8907) += max8907_regulator.o obj-$(CONFIG_DM_REGULATOR_MAX77686) += max77686.o obj-$(CONFIG_DM_REGULATOR_NPCM8XX) += npcm8xx_regulator.o obj-$(CONFIG_$(PHASE_)DM_PMIC_PFUZE100) += pfuze100.o diff --git a/drivers/power/regulator/max8907_regulator.c b/drivers/power/regulator/max8907_regulator.c new file mode 100644 index 00000000000..00ecd4b808b --- /dev/null +++ b/drivers/power/regulator/max8907_regulator.c @@ -0,0 +1,249 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2024 Svyatoslav Ryhel + */ + +#include +#include +#include +#include + +static const char max8907_regmap[] = { + 0x00, MAX8907_REG_SDCTL1, MAX8907_REG_SDCTL2, MAX8907_REG_SDCTL3, + MAX8907_REG_LDOCTL1, MAX8907_REG_LDOCTL2, MAX8907_REG_LDOCTL3, + MAX8907_REG_LDOCTL4, MAX8907_REG_LDOCTL5, MAX8907_REG_LDOCTL6, + MAX8907_REG_LDOCTL7, MAX8907_REG_LDOCTL8, MAX8907_REG_LDOCTL9, + MAX8907_REG_LDOCTL10, MAX8907_REG_LDOCTL11, MAX8907_REG_LDOCTL12, + MAX8907_REG_LDOCTL13, MAX8907_REG_LDOCTL14, MAX8907_REG_LDOCTL15, + MAX8907_REG_LDOCTL16, MAX8907_REG_LDOCTL17, MAX8907_REG_LDOCTL18, + MAX8907_REG_LDOCTL19, MAX8907_REG_LDOCTL20 +}; + +static int max8907_enable(struct udevice *dev, int op, bool *enable) +{ + struct dm_regulator_uclass_plat *uc_pdata = + dev_get_uclass_plat(dev); + int val, ret = 0; + + if (op == PMIC_OP_GET) { + val = pmic_reg_read(dev->parent, uc_pdata->ctrl_reg); + if (val < 0) + return val; + + if (val & MAX8907_MASK_LDO_EN) + *enable = true; + else + *enable = false; + } else if (op == PMIC_OP_SET) { + if (*enable) { + ret = pmic_clrsetbits(dev->parent, + uc_pdata->ctrl_reg, + MAX8907_MASK_LDO_EN | + MAX8907_MASK_LDO_SEQ, + MAX8907_MASK_LDO_EN | + MAX8907_MASK_LDO_SEQ); + } else { + ret = pmic_clrsetbits(dev->parent, + uc_pdata->ctrl_reg, + MAX8907_MASK_LDO_EN | + MAX8907_MASK_LDO_SEQ, + MAX8907_MASK_LDO_SEQ); + } + } + + return ret; +} + +static int max8907_get_enable(struct udevice *dev) +{ + bool enable = false; + int ret; + + ret = max8907_enable(dev, PMIC_OP_GET, &enable); + if (ret) + return ret; + + return enable; +} + +static int max8907_set_enable(struct udevice *dev, bool enable) +{ + return max8907_enable(dev, PMIC_OP_SET, &enable); +} + +/** + * max8907_volt2hex() - convert voltage in uV into + * applicable to register hex value + * + * @idx: regulator index + * @uV: voltage in uV + * + * Return: voltage in hex on success, -ve on failure + */ +static int max8907_volt2hex(int idx, int uV) +{ + switch (idx) { + case 1: /* SD1 */ + if (uV > SD1_VOLT_MAX || uV < SD1_VOLT_MIN) + break; + + return (uV - SD1_VOLT_MIN) / SD1_VOLT_STEP; + + case 2: /* SD2 */ + if (uV > SD2_VOLT_MAX || uV < SD2_VOLT_MIN) + break; + + return (uV - SD2_VOLT_MIN) / SD2_VOLT_STEP; + + case 3: /* SD3 */ + if (uV > SD2_VOLT_MAX || uV < SD2_VOLT_MIN) + break; + + return (uV - SD2_VOLT_MIN) / SD2_VOLT_STEP; + + case 5: /* LDO2 */ + case 6: /* LDO3 */ + case 20: /* LDO17 */ + case 21: /* LDO18 */ + if (uV > LDO_650_VOLT_MAX || uV < LDO_650_VOLT_MIN) + break; + + return (uV - LDO_650_VOLT_MIN) / LDO_650_VOLT_STEP; + + default: /* LDO1, 4..16, 19..20 */ + if (uV > LDO_750_VOLT_MAX || uV < LDO_750_VOLT_MIN) + break; + + return (uV - LDO_750_VOLT_MIN) / LDO_750_VOLT_STEP; + }; + + return -EINVAL; +} + +/** + * max8907_hex2volt() - convert register hex value into + * actual voltage in uV + * + * @idx: regulator index + * @hex: hex value of register + * + * Return: voltage in uV on success, -ve on failure + */ +static int max8907_hex2volt(int idx, int hex) +{ + switch (idx) { + case 1: + return hex * SD1_VOLT_STEP + SD1_VOLT_MIN; + + case 2: + return hex * SD2_VOLT_STEP + SD2_VOLT_MIN; + + case 3: + return hex * SD3_VOLT_STEP + SD3_VOLT_MIN; + + case 5: /* LDO2 */ + case 6: /* LDO3 */ + case 20: /* LDO17 */ + case 21: /* LDO18 */ + return hex * LDO_650_VOLT_STEP + LDO_650_VOLT_MIN; + + default: /* LDO1, 4..16, 19..20 */ + return hex * LDO_750_VOLT_STEP + LDO_750_VOLT_MIN; + }; + + return -EINVAL; +} + +static int max8907_val(struct udevice *dev, int op, int *uV) +{ + struct dm_regulator_uclass_plat *uc_pdata = + dev_get_uclass_plat(dev); + int idx = dev->driver_data; + int hex, ret; + + if (op == PMIC_OP_GET) { + hex = pmic_reg_read(dev->parent, uc_pdata->volt_reg); + if (hex < 0) + return hex; + + *uV = 0; + + ret = max8907_hex2volt(idx, hex); + if (ret < 0) + return ret; + *uV = ret; + + return 0; + } + + hex = max8907_volt2hex(idx, *uV); + if (hex < 0) + return hex; + + return pmic_reg_write(dev->parent, uc_pdata->volt_reg, hex); +} + +static int max8907_get_value(struct udevice *dev) +{ + int uV; + int ret; + + ret = max8907_val(dev, PMIC_OP_GET, &uV); + if (ret) + return ret; + + return uV; +} + +static int max8907_set_value(struct udevice *dev, int uV) +{ + return max8907_val(dev, PMIC_OP_SET, &uV); +} + +static const struct dm_regulator_ops max8907_regulator_ops = { + .get_value = max8907_get_value, + .set_value = max8907_set_value, + .get_enable = max8907_get_enable, + .set_enable = max8907_set_enable, +}; + +static int max8907_sd_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_plat *uc_pdata = + dev_get_uclass_plat(dev); + int idx = dev->driver_data; + + uc_pdata->type = REGULATOR_TYPE_BUCK; + uc_pdata->ctrl_reg = max8907_regmap[idx]; + uc_pdata->volt_reg = uc_pdata->ctrl_reg + MAX8907_VOUT; + + return 0; +} + +U_BOOT_DRIVER(max8907_sd) = { + .name = MAX8907_SD_DRIVER, + .id = UCLASS_REGULATOR, + .ops = &max8907_regulator_ops, + .probe = max8907_sd_probe, +}; + +static int max8907_ldo_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_plat *uc_pdata = + dev_get_uclass_plat(dev); + /* LDO regulator id is shifted by number for SD regulators */ + int idx = dev->driver_data + 3; + + uc_pdata->type = REGULATOR_TYPE_LDO; + uc_pdata->ctrl_reg = max8907_regmap[idx]; + uc_pdata->volt_reg = uc_pdata->ctrl_reg + MAX8907_VOUT; + + return 0; +} + +U_BOOT_DRIVER(max8907_ldo) = { + .name = MAX8907_LDO_DRIVER, + .id = UCLASS_REGULATOR, + .ops = &max8907_regulator_ops, + .probe = max8907_ldo_probe, +}; diff --git a/include/power/max8907.h b/include/power/max8907.h new file mode 100644 index 00000000000..a19b25f44c0 --- /dev/null +++ b/include/power/max8907.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright(C) 2024 Svyatoslav Ryhel + */ + +#ifndef _MAX8907_H_ +#define _MAX8907_H_ + +#define MAX8907_LDO_NUM 20 +#define MAX8907_SD_NUM 3 + +/* Drivers name */ +#define MAX8907_LDO_DRIVER "max8907_ldo" +#define MAX8907_SD_DRIVER "max8907_sd" + +/* MAX8907 register map */ +#define MAX8907_REG_SDCTL1 0x04 +#define MAX8907_REG_SDCTL2 0x07 +#define MAX8907_REG_SDCTL3 0x0A + +#define MAX8907_REG_LDOCTL16 0x10 +#define MAX8907_REG_LDOCTL17 0x14 +#define MAX8907_REG_LDOCTL1 0x18 +#define MAX8907_REG_LDOCTL2 0x1C +#define MAX8907_REG_LDOCTL3 0x20 +#define MAX8907_REG_LDOCTL4 0x24 +#define MAX8907_REG_LDOCTL5 0x28 +#define MAX8907_REG_LDOCTL6 0x2C +#define MAX8907_REG_LDOCTL7 0x30 +#define MAX8907_REG_LDOCTL8 0x34 +#define MAX8907_REG_LDOCTL9 0x38 +#define MAX8907_REG_LDOCTL10 0x3C +#define MAX8907_REG_LDOCTL11 0x40 +#define MAX8907_REG_LDOCTL12 0x44 +#define MAX8907_REG_LDOCTL13 0x48 +#define MAX8907_REG_LDOCTL14 0x4C +#define MAX8907_REG_LDOCTL15 0x50 +#define MAX8907_REG_LDOCTL19 0x5C +#define MAX8907_REG_LDOCTL18 0x72 +#define MAX8907_REG_LDOCTL20 0x9C + +/* MAX8907 configuration values */ +#define MAX8907_CTL 0 +#define MAX8907_SEQCNT 1 +#define MAX8907_VOUT 2 + +/* mask bit fields */ +#define MAX8907_MASK_LDO_SEQ 0x1C +#define MAX8907_MASK_LDO_EN 0x01 + +/* Step-Down (SD) Regulator calculations */ +#define SD1_VOLT_MAX 2225000 +#define SD1_VOLT_MIN 650000 +#define SD1_VOLT_STEP 25000 + +#define SD2_VOLT_MAX 1425000 +#define SD2_VOLT_MIN 637500 +#define SD2_VOLT_STEP 12500 + +#define SD3_VOLT_MAX 3900000 +#define SD3_VOLT_MIN 750000 +#define SD3_VOLT_STEP 50000 + +/* Low-Dropout Linear (LDO) Regulator calculations */ +#define LDO_750_VOLT_MAX 3900000 +#define LDO_750_VOLT_MIN 750000 +#define LDO_750_VOLT_STEP 50000 + +#define LDO_650_VOLT_MAX 2225000 +#define LDO_650_VOLT_MIN 650000 +#define LDO_650_VOLT_STEP 25000 + +#endif /* _MAX8907_H_ */ From 5f3588a94d219818c1b3a2dac4d063f77f48a5ef Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Sun, 6 Oct 2024 16:51:21 +0300 Subject: [PATCH 04/13] sysreset: implement MAX9807 sysreset functions MAX8907 PMIC has embedded poweroff function used by some device to initiane device power off. Implement it as optional sysreset driver guarded by kconfig option and system-power-controller device tree property. Tested-by: Ion Agorria Signed-off-by: Svyatoslav Ryhel --- drivers/power/pmic/max8907.c | 14 ++++++++++- drivers/sysreset/Kconfig | 7 ++++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_max8907.c | 37 +++++++++++++++++++++++++++++ include/power/max8907.h | 4 ++++ 5 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 drivers/sysreset/sysreset_max8907.c diff --git a/drivers/power/pmic/max8907.c b/drivers/power/pmic/max8907.c index 5d35957bf40..a7ef70177de 100644 --- a/drivers/power/pmic/max8907.c +++ b/drivers/power/pmic/max8907.c @@ -45,7 +45,19 @@ static int max8907_read(struct udevice *dev, uint reg, uint8_t *buff, int len) static int max8907_bind(struct udevice *dev) { ofnode regulators_node; - int children; + int children, ret; + + if (IS_ENABLED(CONFIG_SYSRESET_MAX8907) && + dev_read_bool(dev, "maxim,system-power-controller")) { + ret = device_bind_driver_to_node(dev, MAX8907_RST_DRIVER, + "sysreset", dev_ofnode(dev), + NULL); + if (ret) { + log_debug("%s: cannot bind SYSRESET (ret = %d)\n", + __func__, ret); + return ret; + } + } regulators_node = dev_read_subnode(dev, "regulators"); if (!ofnode_valid(regulators_node)) { diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index 4972905482a..aa83073c96a 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -131,6 +131,13 @@ config SYSRESET_MAX77663 help Enable system power management functions found in MAX77663 PMIC. +config SYSRESET_MAX8907 + bool "Enable support for MAX8907 PMIC System Reset" + depends on DM_PMIC_MAX8907 + select SYSRESET_CMD_POWEROFF if CMD_POWEROFF + help + Enable system power management functions found in MAX8907 PMIC. + config SYSRESET_MICROBLAZE bool "Enable support for Microblaze soft reset" depends on MICROBLAZE diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index ded91a4d325..f5c78b25896 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_SYSRESET_CV1800B) += sysreset_cv1800b.o obj-$(CONFIG_$(PHASE_)POWEROFF_GPIO) += poweroff_gpio.o obj-$(CONFIG_$(PHASE_)SYSRESET_GPIO) += sysreset_gpio.o obj-$(CONFIG_$(PHASE_)SYSRESET_MAX77663) += sysreset_max77663.o +obj-$(CONFIG_$(PHASE_)SYSRESET_MAX8907) += sysreset_max8907.o obj-$(CONFIG_SYSRESET_MPC83XX) += sysreset_mpc83xx.o obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o obj-$(CONFIG_SYSRESET_OCTEON) += sysreset_octeon.o diff --git a/drivers/sysreset/sysreset_max8907.c b/drivers/sysreset/sysreset_max8907.c new file mode 100644 index 00000000000..6f62af9bffe --- /dev/null +++ b/drivers/sysreset/sysreset_max8907.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright(C) 2024 Svyatoslav Ryhel + */ + +#include +#include +#include +#include +#include +#include + +static int max8907_sysreset_request(struct udevice *dev, enum sysreset_t type) +{ + switch (type) { + case SYSRESET_POWER: + case SYSRESET_POWER_OFF: + /* MAX8907: PWR_OFF > RESET_CNFG */ + pmic_clrsetbits(dev->parent, MAX8907_REG_RESET_CNFG, + MASK_POWER_OFF, MASK_POWER_OFF); + break; + default: + return -EPROTONOSUPPORT; + } + + return -EINPROGRESS; +} + +static struct sysreset_ops max8907_sysreset = { + .request = max8907_sysreset_request, +}; + +U_BOOT_DRIVER(sysreset_max8907) = { + .id = UCLASS_SYSRESET, + .name = MAX8907_RST_DRIVER, + .ops = &max8907_sysreset, +}; diff --git a/include/power/max8907.h b/include/power/max8907.h index a19b25f44c0..a6e558e582c 100644 --- a/include/power/max8907.h +++ b/include/power/max8907.h @@ -12,6 +12,7 @@ /* Drivers name */ #define MAX8907_LDO_DRIVER "max8907_ldo" #define MAX8907_SD_DRIVER "max8907_sd" +#define MAX8907_RST_DRIVER "max8907_rst" /* MAX8907 register map */ #define MAX8907_REG_SDCTL1 0x04 @@ -39,6 +40,9 @@ #define MAX8907_REG_LDOCTL18 0x72 #define MAX8907_REG_LDOCTL20 0x9C +#define MAX8907_REG_RESET_CNFG 0x0F +#define MASK_POWER_OFF BIT(6) + /* MAX8907 configuration values */ #define MAX8907_CTL 0 #define MAX8907_SEQCNT 1 From 505dd92275531e8b5f475105362265f7ac96ad7c Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 4 Oct 2024 11:54:46 +0300 Subject: [PATCH 05/13] video: tegra: add 8-bit CPU driven protocol Add support for 8-bit CPU driven (primary and secondary) display signal interface found in Tegra 2 and Tegra 3 SoC. Tested-by: Ion Agorria Signed-off-by: Svyatoslav Ryhel --- arch/arm/include/asm/arch-tegra/dc.h | 48 ++++ drivers/video/tegra/Kconfig | 10 + drivers/video/tegra/Makefile | 1 + drivers/video/tegra/cpu-bridge.c | 325 +++++++++++++++++++++++++++ 4 files changed, 384 insertions(+) create mode 100644 drivers/video/tegra/cpu-bridge.c diff --git a/arch/arm/include/asm/arch-tegra/dc.h b/arch/arm/include/asm/arch-tegra/dc.h index 2fd07403bdf..ab12cc9c7d0 100644 --- a/arch/arm/include/asm/arch-tegra/dc.h +++ b/arch/arm/include/asm/arch-tegra/dc.h @@ -448,10 +448,19 @@ enum win_color_depth_id { #define LVS_OUTPUT_POLARITY_LOW BIT(28) #define LSC0_OUTPUT_POLARITY_LOW BIT(24) +/* DC_COM_PIN_OUTPUT_SELECT6 0x31a */ +#define LDC_OUTPUT_SELECT_V_PULSE1 BIT(14) /* 100b */ + /* DC_DISP_DISP_SIGNAL_OPTIONS0 0x400 */ #define H_PULSE0_ENABLE BIT(8) #define H_PULSE1_ENABLE BIT(10) #define H_PULSE2_ENABLE BIT(12) +#define V_PULSE0_ENABLE BIT(16) +#define V_PULSE1_ENABLE BIT(18) +#define V_PULSE2_ENABLE BIT(19) +#define V_PULSE3_ENABLE BIT(20) +#define M0_ENABLE BIT(24) +#define M1_ENABLE BIT(26) /* DC_DISP_DISP_WIN_OPTIONS 0x402 */ #define CURSOR_ENABLE BIT(16) @@ -525,6 +534,28 @@ enum { BASE_COLOR_SIZE_888, }; +/* DC_DISP_SHIFT_CLOCK_OPTIONS 0x431 */ +#define SC0_H_QUALIFIER_SHIFT 0 +#define SC1_H_QUALIFIER_SHIFT 16 +enum { + SC_H_QUALIFIER_DISABLE, + SC_H_QUALIFIER_NONE, + SC_H_QUALIFIER_HACTIVE, + SC_H_QUALIFIER_EXT_HACTIVE, + SC_H_QUALIFIER_HPULSE, + SC_H_QUALIFIER_EXT_HPULSE, +}; +#define SC0_V_QUALIFIER_SHIFT 3 +#define SC1_V_QUALIFIER_SHIFT 19 +enum { + SC_V_QUALIFIER_NONE, + SC_V_QUALIFIER_RSVD, + SC_V_QUALIFIER_VACTIVE, + SC_V_QUALIFIER_EXT_VACTIVE, + SC_V_QUALIFIER_VPULSE, + SC_V_QUALIFIER_EXT_VPULSE, +}; + /* DC_DISP_DATA_ENABLE_OPTIONS 0x432 */ #define DE_SELECT_SHIFT 0 #define DE_SELECT_MASK (0x3 << DE_SELECT_SHIFT) @@ -541,6 +572,23 @@ enum { DE_CONTROL_ACTIVE_BLANK, }; +/* DC_DISP_INIT_SEQ_CONTROL 0x442 */ +#define SEND_INIT_SEQUENCE BIT(0) +#define INIT_SEQUENCE_MODE_SPI BIT(1) +#define INIT_SEQUENCE_MODE_PLCD 0x0 +#define INIT_SEQ_DC_SIGNAL_SHIFT 4 +#define INIT_SEQ_DC_SIGNAL_MASK (0x7 << INIT_SEQ_DC_SIGNAL_SHIFT) +enum { + NO_DC_SIGNAL, + DC_SIGNAL_VSYNC, + DC_SIGNAL_VPULSE0, + DC_SIGNAL_VPULSE1, + DC_SIGNAL_VPULSE2, + DC_SIGNAL_VPULSE3, +}; +#define INIT_SEQ_DC_CONTROL_SHIFT 7 +#define FRAME_INIT_SEQ_CYCLES_SHIFT 8 + /* DC_WIN_WIN_OPTIONS 0x700 */ #define H_DIRECTION BIT(0) enum { diff --git a/drivers/video/tegra/Kconfig b/drivers/video/tegra/Kconfig index 1a328407b13..f32972d937e 100644 --- a/drivers/video/tegra/Kconfig +++ b/drivers/video/tegra/Kconfig @@ -42,6 +42,16 @@ config TEGRA_BACKLIGHT_PWM Enable support for the Display Controller dependent PWM backlight found in the Tegra SoC and usually used with DSI panels. +config TEGRA_8BIT_CPU_BRIDGE + bool "Enable 8 bit panel communication protocol for Tegra 20/30" + depends on VIDEO_BRIDGE && DM_GPIO + select VIDEO_TEGRA + select VIDEO_MIPI_DSI + help + Tegra 20 and Tegra 30 feature 8 bit CPU driver panel control + protocol. This option allows use it as a MIPI DSI bridge to + set up and control compatible panel. + config VIDEO_TEGRA124 bool "Enable video support on Tegra124" imply VIDEO_DAMAGE diff --git a/drivers/video/tegra/Makefile b/drivers/video/tegra/Makefile index 3c50a0ba3c3..4995c93a8af 100644 --- a/drivers/video/tegra/Makefile +++ b/drivers/video/tegra/Makefile @@ -5,5 +5,6 @@ obj-$(CONFIG_VIDEO_TEGRA) += dc.o obj-$(CONFIG_VIDEO_DSI_TEGRA) += dsi.o mipi.o mipi-phy.o obj-$(CONFIG_VIDEO_HDMI_TEGRA) += hdmi.o obj-$(CONFIG_TEGRA_BACKLIGHT_PWM) += dc-pwm-backlight.o +obj-$(CONFIG_TEGRA_8BIT_CPU_BRIDGE) += cpu-bridge.o obj-${CONFIG_VIDEO_TEGRA124} += tegra124/ diff --git a/drivers/video/tegra/cpu-bridge.c b/drivers/video/tegra/cpu-bridge.c new file mode 100644 index 00000000000..e5fefe028f0 --- /dev/null +++ b/drivers/video/tegra/cpu-bridge.c @@ -0,0 +1,325 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2024 Svyatoslav Ryhel + * + * This driver uses 8-bit CPU interface found in Tegra 2 + * and Tegra 3 to drive MIPI DSI panel. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dc.h" + +struct tegra_cpu_bridge_priv { + struct dc_ctlr *dc; + + struct mipi_dsi_host host; + struct mipi_dsi_device device; + + struct udevice *panel; + struct display_timing timing; + + struct gpio_desc dc_gpio; + struct gpio_desc rw_gpio; + struct gpio_desc cs_gpio; + + struct gpio_desc data_gpios[8]; + + u32 pixel_format; + u32 spi_init_seq[4]; +}; + +#define TEGRA_CPU_BRIDGE_COMM 0 +#define TEGRA_CPU_BRIDGE_DATA 1 + +static void tegra_cpu_bridge_write(struct tegra_cpu_bridge_priv *priv, + u8 type, u8 value) +{ + int i; + + dm_gpio_set_value(&priv->dc_gpio, type); + + dm_gpio_set_value(&priv->cs_gpio, 0); + dm_gpio_set_value(&priv->rw_gpio, 0); + + for (i = 0; i < 8; i++) + dm_gpio_set_value(&priv->data_gpios[i], + (value >> i) & 0x1); + + dm_gpio_set_value(&priv->cs_gpio, 1); + dm_gpio_set_value(&priv->rw_gpio, 1); + + udelay(10); + + log_debug("%s: type 0x%x, val 0x%x\n", + __func__, type, value); +} + +static ssize_t tegra_cpu_bridge_transfer(struct mipi_dsi_host *host, + const struct mipi_dsi_msg *msg) +{ + struct udevice *dev = (struct udevice *)host->dev; + struct tegra_cpu_bridge_priv *priv = dev_get_priv(dev); + u8 command = *(u8 *)msg->tx_buf; + const u8 *data = msg->tx_buf; + int i; + + tegra_cpu_bridge_write(priv, TEGRA_CPU_BRIDGE_COMM, command); + + for (i = 1; i < msg->tx_len; i++) + tegra_cpu_bridge_write(priv, TEGRA_CPU_BRIDGE_DATA, data[i]); + + return 0; +} + +static const struct mipi_dsi_host_ops tegra_cpu_bridge_host_ops = { + .transfer = tegra_cpu_bridge_transfer, +}; + +static int tegra_cpu_bridge_get_format(enum mipi_dsi_pixel_format format, u32 *fmt) +{ + switch (format) { + case MIPI_DSI_FMT_RGB888: + case MIPI_DSI_FMT_RGB666_PACKED: + *fmt = BASE_COLOR_SIZE_888; + break; + + case MIPI_DSI_FMT_RGB666: + *fmt = BASE_COLOR_SIZE_666; + break; + + case MIPI_DSI_FMT_RGB565: + *fmt = BASE_COLOR_SIZE_565; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int tegra_cpu_bridge_attach(struct udevice *dev) +{ + struct tegra_cpu_bridge_priv *priv = dev_get_priv(dev); + struct dc_disp_reg *disp = &priv->dc->disp; + struct dc_cmd_reg *cmd = &priv->dc->cmd; + struct dc_com_reg *com = &priv->dc->com; + u32 value; + int ret; + + writel(CTRL_MODE_STOP << CTRL_MODE_SHIFT, &cmd->disp_cmd); + writel(0, &disp->disp_win_opt); + writel(GENERAL_UPDATE, &cmd->state_ctrl); + writel(GENERAL_ACT_REQ, &cmd->state_ctrl); + + /* TODO: parametrize if needed */ + writel(V_PULSE1_ENABLE, &disp->disp_signal_opt0); + writel(PULSE_POLARITY_LOW, &disp->v_pulse1.v_pulse_ctrl); + + writel(PULSE_END(1), &disp->v_pulse1.v_pulse_pos[V_PULSE0_POSITION_A]); + writel(0, &disp->v_pulse1.v_pulse_pos[V_PULSE0_POSITION_B]); + writel(0, &disp->v_pulse1.v_pulse_pos[V_PULSE0_POSITION_C]); + + ret = dev_read_u32_array(dev, "nvidia,init-sequence", priv->spi_init_seq, 4); + if (!ret) { + value = 1 << FRAME_INIT_SEQ_CYCLES_SHIFT | + DC_SIGNAL_VPULSE1 << INIT_SEQ_DC_SIGNAL_SHIFT | + INIT_SEQUENCE_MODE_PLCD | SEND_INIT_SEQUENCE; + writel(value, &disp->seq_ctrl); + + writel(priv->spi_init_seq[0], &disp->spi_init_seq_data_a); + writel(priv->spi_init_seq[1], &disp->spi_init_seq_data_b); + writel(priv->spi_init_seq[2], &disp->spi_init_seq_data_c); + writel(priv->spi_init_seq[3], &disp->spi_init_seq_data_d); + } + + value = readl(&cmd->disp_cmd); + value &= ~CTRL_MODE_MASK; + value |= CTRL_MODE_C_DISPLAY << CTRL_MODE_SHIFT; + writel(value, &cmd->disp_cmd); + + /* set LDC pin to V Pulse 1 */ + value = readl(&com->pin_output_sel[6]) | LDC_OUTPUT_SELECT_V_PULSE1; + writel(value, &com->pin_output_sel[6]); + + value = readl(&disp->disp_interface_ctrl); + value |= DATA_ALIGNMENT_LSB << DATA_ALIGNMENT_SHIFT; + writel(value, &disp->disp_interface_ctrl); + + value = SC_H_QUALIFIER_NONE << SC1_H_QUALIFIER_SHIFT | + SC_V_QUALIFIER_VACTIVE << SC0_V_QUALIFIER_SHIFT | + SC_H_QUALIFIER_HACTIVE << SC0_H_QUALIFIER_SHIFT; + writel(value, &disp->shift_clk_opt); + + value = readl(&disp->disp_color_ctrl); + value |= priv->pixel_format; + writel(value, &disp->disp_color_ctrl); + + /* Perform panel setup */ + panel_enable_backlight(priv->panel); + + dm_gpio_set_value(&priv->cs_gpio, 0); + + dm_gpio_free(dev, &priv->dc_gpio); + dm_gpio_free(dev, &priv->rw_gpio); + dm_gpio_free(dev, &priv->cs_gpio); + + gpio_free_list(dev, priv->data_gpios, 8); + + return 0; +} + +static int tegra_cpu_bridge_set_panel(struct udevice *dev, int percent) +{ + struct tegra_cpu_bridge_priv *priv = dev_get_priv(dev); + + return panel_set_backlight(priv->panel, percent); +} + +static int tegra_cpu_bridge_panel_timings(struct udevice *dev, + struct display_timing *timing) +{ + struct tegra_cpu_bridge_priv *priv = dev_get_priv(dev); + + memcpy(timing, &priv->timing, sizeof(*timing)); + + return 0; +} + +static int tegra_cpu_bridge_hw_init(struct udevice *dev) +{ + struct tegra_cpu_bridge_priv *priv = dev_get_priv(dev); + + dm_gpio_set_value(&priv->cs_gpio, 1); + + dm_gpio_set_value(&priv->rw_gpio, 1); + dm_gpio_set_value(&priv->dc_gpio, 0); + + return 0; +} + +static int tegra_cpu_bridge_get_links(struct udevice *dev) +{ + struct tegra_cpu_bridge_priv *priv = dev_get_priv(dev); + int i, ret; + + u32 num = ofnode_graph_get_port_count(dev_ofnode(dev)); + + for (i = 0; i < num; i++) { + ofnode remote = ofnode_graph_get_remote_node(dev_ofnode(dev), i, -1); + + /* Look for DC source */ + if (ofnode_name_eq(remote, "rgb")) { + ofnode dc = ofnode_get_parent(remote); + + priv->dc = (struct dc_ctlr *)ofnode_get_addr(dc); + if (!priv->dc) { + log_err("%s: failed to get DC controller\n", __func__); + return -EINVAL; + } + } + + /* Look for driven panel */ + ret = uclass_get_device_by_ofnode(UCLASS_PANEL, remote, &priv->panel); + if (!ret) + return 0; + } + + /* If this point is reached, no panels were found */ + return -ENODEV; +} + +static int tegra_cpu_bridge_probe(struct udevice *dev) +{ + struct tegra_cpu_bridge_priv *priv = dev_get_priv(dev); + struct mipi_dsi_device *device = &priv->device; + struct mipi_dsi_panel_plat *mipi_plat; + int ret; + + ret = tegra_cpu_bridge_get_links(dev); + if (ret) { + log_debug("%s: links not found, ret %d\n", __func__, ret); + return ret; + } + + panel_get_display_timing(priv->panel, &priv->timing); + + mipi_plat = dev_get_plat(priv->panel); + mipi_plat->device = device; + + priv->host.dev = (struct device *)dev; + priv->host.ops = &tegra_cpu_bridge_host_ops; + + device->host = &priv->host; + device->lanes = mipi_plat->lanes; + device->format = mipi_plat->format; + device->mode_flags = mipi_plat->mode_flags; + + tegra_cpu_bridge_get_format(device->format, &priv->pixel_format); + + /* get control gpios */ + ret = gpio_request_by_name(dev, "dc-gpios", 0, + &priv->dc_gpio, GPIOD_IS_OUT); + if (ret) { + log_debug("%s: could not decode dc-gpios (%d)\n", __func__, ret); + return ret; + } + + ret = gpio_request_by_name(dev, "rw-gpios", 0, + &priv->rw_gpio, GPIOD_IS_OUT); + if (ret) { + log_debug("%s: could not decode rw-gpios (%d)\n", __func__, ret); + return ret; + } + + ret = gpio_request_by_name(dev, "cs-gpios", 0, + &priv->cs_gpio, GPIOD_IS_OUT); + if (ret) { + log_debug("%s: could not decode cs-gpios (%d)\n", __func__, ret); + return ret; + } + + /* get data gpios */ + ret = gpio_request_list_by_name(dev, "data-gpios", + priv->data_gpios, 8, + GPIOD_IS_OUT); + if (ret < 0) { + log_debug("%s: could not decode data-gpios (%d)\n", __func__, ret); + return ret; + } + + return tegra_cpu_bridge_hw_init(dev); +} + +static const struct video_bridge_ops tegra_cpu_bridge_ops = { + .attach = tegra_cpu_bridge_attach, + .set_backlight = tegra_cpu_bridge_set_panel, + .get_display_timing = tegra_cpu_bridge_panel_timings, +}; + +static const struct udevice_id tegra_cpu_bridge_ids[] = { + { .compatible = "nvidia,tegra-8bit-cpu" }, + { } +}; + +U_BOOT_DRIVER(tegra_8bit_cpu) = { + .name = "tegra_8bit_cpu", + .id = UCLASS_VIDEO_BRIDGE, + .of_match = tegra_cpu_bridge_ids, + .ops = &tegra_cpu_bridge_ops, + .bind = dm_scan_fdt_dev, + .probe = tegra_cpu_bridge_probe, + .priv_auto = sizeof(struct tegra_cpu_bridge_priv), +}; From 7eb99ba543c5c84d021287b5721f75174f1ed01b Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 4 Oct 2024 12:03:09 +0300 Subject: [PATCH 06/13] video: panel: add Hitachi TX10D07VM0BAA MIPI DSI panel driver Hitachi TX10D07VM0BAA is a color active matrix TFT (Thin Film Transistor) liquid crystal display (LCD). The resolution of a 4" contains 480 x 800 pixels. Tested-by: Ion Agorria Signed-off-by: Svyatoslav Ryhel --- drivers/video/Kconfig | 8 + drivers/video/Makefile | 1 + drivers/video/hitachi-tx10d07vm0baa.c | 304 ++++++++++++++++++++++++++ 3 files changed, 313 insertions(+) create mode 100644 drivers/video/hitachi-tx10d07vm0baa.c diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index fe70e98f964..36deb40bb78 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -668,6 +668,14 @@ config VIDEO_LCD_TDO_TL070WSH30 Say Y here if you want to enable support for TDO TL070WSH30 1024x600 DSI video mode panel. +config VIDEO_LCD_HITACHI_TX10D07VM0BAA + tristate "Hitachi TX10D07VM0BAA 480x800 MIPI DSI video mode panel" + depends on PANEL && BACKLIGHT + select VIDEO_MIPI_DSI + help + Say Y here if you want to enable support for Hitachi TX10D07VM0BAA + TFT-LCD module. The panel has a 480x800 resolution. + config VIDEO_LCD_HITACHI_TX18D42VM bool "Hitachi tx18d42vm LVDS LCD panel support" ---help--- diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 31f68585fe4..5c976090f42 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_VIDEO_IVYBRIDGE_IGD) += ivybridge_igd.o obj-$(CONFIG_VIDEO_LCD_ANX9804) += anx9804.o obj-$(CONFIG_VIDEO_LCD_ENDEAVORU) += endeavoru-panel.o obj-$(CONFIG_VIDEO_LCD_HIMAX_HX8394) += himax-hx8394.o +obj-$(CONFIG_VIDEO_LCD_HITACHI_TX10D07VM0BAA) += hitachi-tx10d07vm0baa.o obj-$(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM) += hitachi_tx18d42vm_lcd.o obj-$(CONFIG_VIDEO_LCD_LG_LD070WX3) += lg-ld070wx3.o obj-$(CONFIG_VIDEO_LCD_MOT) += mot-panel.o diff --git a/drivers/video/hitachi-tx10d07vm0baa.c b/drivers/video/hitachi-tx10d07vm0baa.c new file mode 100644 index 00000000000..95b2f7bfc41 --- /dev/null +++ b/drivers/video/hitachi-tx10d07vm0baa.c @@ -0,0 +1,304 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Hitachi TX10D07VM0BAA DSI panel driver + * + * Copyright (c) 2024 Svyatoslav Ryhel + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct hitachi_tx10d07vm0baa_priv { + struct udevice *avci; + struct udevice *iovcc; + + struct udevice *backlight; + + struct gpio_desc reset_gpio; +}; + +static struct display_timing default_timing = { + .pixelclock.typ = 29816000, + .hactive.typ = 480, + .hfront_porch.typ = 10, + .hback_porch.typ = 10, + .hsync_len.typ = 10, + .vactive.typ = 800, + .vfront_porch.typ = 4, + .vback_porch.typ = 4, + .vsync_len.typ = 4, +}; + +#define dsi_generic_write_seq(dsi, cmd, seq...) do { \ + static const u8 b[] = { cmd, seq }; \ + int ret; \ + ret = mipi_dsi_dcs_write_buffer(dsi, b, ARRAY_SIZE(b)); \ + if (ret < 0) \ + return ret; \ + } while (0) + +static int hitachi_tx10d07vm0baa_enable_backlight(struct udevice *dev) +{ + struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); + struct mipi_dsi_device *dsi = plat->device; + int ret; + + dsi_generic_write_seq(dsi, MIPI_DCS_SET_PARTIAL_AREA, 0x00, + 0x00, 0x03, 0x1f); + dsi_generic_write_seq(dsi, MIPI_DCS_SET_SCROLL_AREA, 0x00, + 0x00, 0x03, 0x20, 0x00, 0x00); + + dsi_generic_write_seq(dsi, MIPI_DCS_SET_ADDRESS_MODE, 0x0a); + dsi_generic_write_seq(dsi, MIPI_DCS_SET_SCROLL_START, 0x00, + 0x00); + + ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT); + if (ret) { + log_debug("%s: failed to set pixel format: %d\n", __func__, ret); + return ret; + } + + ret = mipi_dsi_dcs_set_tear_scanline(dsi, 0x00); + if (ret) { + log_debug("%s: failed to set tear scanline: %d\n", __func__, ret); + return ret; + } + + dsi_generic_write_seq(dsi, 0x71, 0x00); /* Ex_Vsync_en */ + + dsi_generic_write_seq(dsi, 0xb2, 0x00); /* VCSEL */ + dsi_generic_write_seq(dsi, 0xb4, 0xaa); /* setvgmpm */ + dsi_generic_write_seq(dsi, 0xb5, 0x33); /* rbias1 */ + dsi_generic_write_seq(dsi, 0xb6, 0x03); /* rbias2 */ + + dsi_generic_write_seq(dsi, 0xb7, 0x1a, 0x33, 0x03, 0x03, + 0x03, 0x00, 0x00, 0x01, 0x02, 0x00, + 0x00, 0x04, 0x00, 0x01, 0x01, 0x01); /* set_ddvdhp */ + dsi_generic_write_seq(dsi, 0xb8, 0x1c, 0x53, 0x03, 0x03, + 0x00, 0x01, 0x02, 0x00, 0x00, 0x04, + 0x00, 0x01, 0x01); /* set_ddvdhm */ + + dsi_generic_write_seq(dsi, 0xb9, 0x0a, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x02, 0x01); /* set_vgh */ + dsi_generic_write_seq(dsi, 0xba, 0x0f, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x02, 0x01); /* set_vgl */ + dsi_generic_write_seq(dsi, 0xbb, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x01); /* set_vcl */ + + dsi_generic_write_seq(dsi, 0xc1, 0x01); /* number of lines */ + dsi_generic_write_seq(dsi, 0xc2, 0x08); /* number of fp lines */ + dsi_generic_write_seq(dsi, 0xc3, 0x04); /* gateset(1) */ + dsi_generic_write_seq(dsi, 0xc4, 0x4c); /* 1h period */ + dsi_generic_write_seq(dsi, 0xc5, 0x03); /* source precharge */ + dsi_generic_write_seq(dsi, 0xc6, 0xc4, 0x04); /* source precharge timing */ + dsi_generic_write_seq(dsi, 0xc7, 0x00); /* source level */ + dsi_generic_write_seq(dsi, 0xc8, 0x02); /* number of bp lines */ + dsi_generic_write_seq(dsi, 0xc9, 0x10); /* gateset(2) */ + dsi_generic_write_seq(dsi, 0xca, 0x04, 0x04); /* gateset(3) */ + dsi_generic_write_seq(dsi, 0xcb, 0x03); /* gateset(4) */ + dsi_generic_write_seq(dsi, 0xcc, 0x12); /* gateset(5) */ + dsi_generic_write_seq(dsi, 0xcd, 0x12); /* gateset(6) */ + dsi_generic_write_seq(dsi, 0xce, 0x30); /* gateset(7) */ + dsi_generic_write_seq(dsi, 0xcf, 0x30); /* gateset(8) */ + dsi_generic_write_seq(dsi, 0xd0, 0x40); /* gateset(9) */ + dsi_generic_write_seq(dsi, 0xd1, 0x22); /* flhw */ + dsi_generic_write_seq(dsi, 0xd2, 0x22); /* vckhw */ + dsi_generic_write_seq(dsi, 0xd3, 0x04); /* flt */ + dsi_generic_write_seq(dsi, 0xd4, 0x14); /* tctrl */ + dsi_generic_write_seq(dsi, 0xd6, 0x02); /* dotinv */ + dsi_generic_write_seq(dsi, 0xd7, 0x00); /* on/off sequence period */ + + dsi_generic_write_seq(dsi, 0xd8, 0x01, 0x05, 0x06, 0x0d, + 0x18, 0x09, 0x22, 0x23, 0x00); /* ponseqa */ + dsi_generic_write_seq(dsi, 0xd9, 0x24, 0x01); /* ponseqb */ + dsi_generic_write_seq(dsi, 0xde, 0x09, 0x0f, 0x21, 0x12, + 0x04); /* ponseqc */ + + dsi_generic_write_seq(dsi, 0xdf, 0x02, 0x06, 0x06, 0x06, + 0x06, 0x00); /* pofseqa */ + dsi_generic_write_seq(dsi, 0xe0, 0x01); /* pofseqb */ + + ret = mipi_dsi_dcs_set_display_brightness(dsi, 0xff); + if (ret) { + log_debug("%s: failed to set display brightness: %d\n", __func__, ret); + return ret; + } + + dsi_generic_write_seq(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY, 0x40); + + dsi_generic_write_seq(dsi, 0xe2, 0x00, 0x00); /* cabc pwm */ + dsi_generic_write_seq(dsi, 0xe3, 0x03); /* cabc */ + dsi_generic_write_seq(dsi, 0xe4, 0x66, 0x7b, 0x90, 0xa5, + 0xbb, 0xc7, 0xe1, 0xe5); /* cabc brightness */ + dsi_generic_write_seq(dsi, 0xe5, 0xc5, 0xc5, 0xc9, 0xc9, + 0xd1, 0xe1, 0xf1, 0xfe); /* cabc brightness */ + dsi_generic_write_seq(dsi, 0xe7, 0x2a); /* cabc */ + dsi_generic_write_seq(dsi, 0xe8, 0x00); /* brt_rev */ + dsi_generic_write_seq(dsi, 0xe9, 0x00); /* tefreq */ + + dsi_generic_write_seq(dsi, 0xea, 0x01); /* high speed ram */ + + dsi_generic_write_seq(dsi, 0xeb, 0x00, 0x33, 0x0e, 0x15, + 0xb7, 0x78, 0x88, 0x0f); /* gamma setting r pos */ + dsi_generic_write_seq(dsi, 0xec, 0x00, 0x33, 0x0e, 0x15, + 0xb7, 0x78, 0x88, 0x0f); /* gamma setting r neg */ + dsi_generic_write_seq(dsi, 0xed, 0x00, 0x33, 0x0e, 0x15, + 0xb7, 0x78, 0x88, 0x0f); /* gamma setting g pos */ + dsi_generic_write_seq(dsi, 0xee, 0x00, 0x33, 0x0e, 0x15, + 0xb7, 0x78, 0x88, 0x0f); /* gamma setting g neg */ + dsi_generic_write_seq(dsi, 0xef, 0x00, 0x33, 0x0e, 0x15, + 0xb7, 0x78, 0x88, 0x0f); /* gamma setting b pos */ + dsi_generic_write_seq(dsi, 0xf0, 0x00, 0x33, 0x0e, 0x15, + 0xb7, 0x78, 0x88, 0x0f); /* gamma setting b neg */ + + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); + if (ret) { + log_debug("%s: failed to exit sleep mode: %d\n", __func__, ret); + return ret; + } + + mdelay(110); + + ret = mipi_dsi_dcs_set_display_on(dsi); + if (ret) { + log_debug("%s: failed to set display on: %d\n", __func__, ret); + return ret; + } + + return 0; +} + +static int hitachi_tx10d07vm0baa_set_backlight(struct udevice *dev, int percent) +{ + struct hitachi_tx10d07vm0baa_priv *priv = dev_get_priv(dev); + int ret; + + ret = backlight_enable(priv->backlight); + if (ret) + return ret; + + return backlight_set_brightness(priv->backlight, percent); +} + +static int hitachi_tx10d07vm0baa_timings(struct udevice *dev, + struct display_timing *timing) +{ + memcpy(timing, &default_timing, sizeof(*timing)); + return 0; +} + +static int hitachi_tx10d07vm0baa_of_to_plat(struct udevice *dev) +{ + struct hitachi_tx10d07vm0baa_priv *priv = dev_get_priv(dev); + int ret; + + ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev, + "backlight", &priv->backlight); + if (ret) { + log_debug("%s: cannot get backlight: ret = %d\n", + __func__, ret); + return ret; + } + + ret = device_get_supply_regulator(dev, "avci-supply", &priv->avci); + if (ret) { + log_debug("%s: cannot get avci-supply: ret = %d\n", + __func__, ret); + return ret; + } + + ret = device_get_supply_regulator(dev, "iovcc-supply", &priv->iovcc); + if (ret) { + log_debug("%s: cannot get iovcc-supply: ret = %d\n", + __func__, ret); + return ret; + } + + ret = gpio_request_by_name(dev, "reset-gpios", 0, + &priv->reset_gpio, GPIOD_IS_OUT); + if (ret) { + log_debug("%s: cannot decode reset-gpios (%d)\n", + __func__, ret); + return ret; + } + + return 0; +} + +static int hitachi_tx10d07vm0baa_hw_init(struct udevice *dev) +{ + struct hitachi_tx10d07vm0baa_priv *priv = dev_get_priv(dev); + int ret; + + ret = dm_gpio_set_value(&priv->reset_gpio, 1); + if (ret) { + log_debug("%s: error entering reset (%d)\n", __func__, ret); + return ret; + } + + ret = regulator_set_enable_if_allowed(priv->iovcc, 1); + if (ret) { + log_debug("%s: enabling iovcc-supply failed (%d)\n", + __func__, ret); + return ret; + } + + ret = regulator_set_enable_if_allowed(priv->avci, 1); + if (ret) { + log_debug("%s: enabling avci-supply failed (%d)\n", + __func__, ret); + return ret; + } + + mdelay(25); + + ret = dm_gpio_set_value(&priv->reset_gpio, 0); + if (ret) { + log_debug("%s: error exiting reset (%d)\n", __func__, ret); + return ret; + } + + mdelay(5); + + return 0; +} + +static int hitachi_tx10d07vm0baa_probe(struct udevice *dev) +{ + struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); + + /* fill characteristics of DSI data link */ + plat->lanes = 2; + plat->format = MIPI_DSI_FMT_RGB888; + plat->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM; + + return hitachi_tx10d07vm0baa_hw_init(dev); +} + +static const struct panel_ops hitachi_tx10d07vm0baa_ops = { + .enable_backlight = hitachi_tx10d07vm0baa_enable_backlight, + .set_backlight = hitachi_tx10d07vm0baa_set_backlight, + .get_display_timing = hitachi_tx10d07vm0baa_timings, +}; + +static const struct udevice_id hitachi_tx10d07vm0baa_ids[] = { + { .compatible = "hit,tx10d07vm0baa" }, + { } +}; + +U_BOOT_DRIVER(hitachi_tx10d07vm0baa) = { + .name = "hitachi_tx10d07vm0baa", + .id = UCLASS_PANEL, + .of_match = hitachi_tx10d07vm0baa_ids, + .ops = &hitachi_tx10d07vm0baa_ops, + .of_to_plat = hitachi_tx10d07vm0baa_of_to_plat, + .probe = hitachi_tx10d07vm0baa_probe, + .plat_auto = sizeof(struct mipi_dsi_panel_plat), + .priv_auto = sizeof(struct hitachi_tx10d07vm0baa_priv), +}; From cb9c3024d1d9589b51cf256d03b4887a6e88b412 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Mon, 3 Mar 2025 15:00:37 +0200 Subject: [PATCH 07/13] video: panel: add LG LH400WV3-SD04 MIPI DSI panel driver LG LH400WV3-SD04 is a color active matrix TFT (Thin Film Transistor) liquid crystal display (LCD). The resolution of a 4" contains 480 x 800 pixels. Signed-off-by: Svyatoslav Ryhel --- drivers/video/Kconfig | 8 ++ drivers/video/Makefile | 1 + drivers/video/lg-lh400wv3-sd04.c | 230 +++++++++++++++++++++++++++++++ 3 files changed, 239 insertions(+) create mode 100644 drivers/video/lg-lh400wv3-sd04.c diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 36deb40bb78..2014090c178 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -581,6 +581,14 @@ config VIDEO_LCD_LG_LD070WX3 Say Y here if you want to enable support for LG LD070WX3 800x1280 DSI video mode panel. +config VIDEO_LCD_LG_LH400WV3 + bool "LH400WV3-SD04 DSI LCD panel support" + depends on PANEL && BACKLIGHT + select VIDEO_MIPI_DSI + help + Say Y here if you want to enable support for LG LH400WV3 + 480x800 DSI video mode panel. + config VIDEO_LCD_RAYDIUM_RM68200 bool "RM68200 DSI LCD panel support" select VIDEO_MIPI_DSI diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 5c976090f42..277ed093a03 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -61,6 +61,7 @@ obj-$(CONFIG_VIDEO_LCD_HIMAX_HX8394) += himax-hx8394.o obj-$(CONFIG_VIDEO_LCD_HITACHI_TX10D07VM0BAA) += hitachi-tx10d07vm0baa.o obj-$(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM) += hitachi_tx18d42vm_lcd.o obj-$(CONFIG_VIDEO_LCD_LG_LD070WX3) += lg-ld070wx3.o +obj-$(CONFIG_VIDEO_LCD_LG_LH400WV3) += lg-lh400wv3-sd04.o obj-$(CONFIG_VIDEO_LCD_MOT) += mot-panel.o obj-$(CONFIG_VIDEO_LCD_NOVATEK_NT35510) += novatek-nt35510.o obj-$(CONFIG_VIDEO_LCD_ORISETECH_OTM8009A) += orisetech_otm8009a.o diff --git a/drivers/video/lg-lh400wv3-sd04.c b/drivers/video/lg-lh400wv3-sd04.c new file mode 100644 index 00000000000..0385b39867f --- /dev/null +++ b/drivers/video/lg-lh400wv3-sd04.c @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * LG LH400WV3-SD04 DSI panel driver + * + * Copyright (c) 2025 Svyatoslav Ryhel + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct lg_lh400wv3_priv { + struct udevice *avci; + struct udevice *iovcc; + + struct udevice *backlight; + + struct gpio_desc reset_gpio; +}; + +static struct display_timing default_timing = { + .pixelclock.typ = 29816000, + .hactive.typ = 480, + .hfront_porch.typ = 10, + .hback_porch.typ = 10, + .hsync_len.typ = 10, + .vactive.typ = 800, + .vfront_porch.typ = 4, + .vback_porch.typ = 4, + .vsync_len.typ = 4, +}; + +#define dsi_generic_write_seq(dsi, cmd, seq...) do { \ + static const u8 b[] = { cmd, seq }; \ + int ret; \ + ret = mipi_dsi_dcs_write_buffer(dsi, b, ARRAY_SIZE(b)); \ + if (ret < 0) \ + return ret; \ + } while (0) + +static int lg_lh400wv3_enable_backlight(struct udevice *dev) +{ + struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); + struct mipi_dsi_device *dsi = plat->device; + int ret; + + dsi_generic_write_seq(dsi, MIPI_DCS_EXIT_INVERT_MODE); + dsi_generic_write_seq(dsi, MIPI_DCS_SET_TEAR_ON); + + ret = mipi_dsi_dcs_set_pixel_format(dsi, MIPI_DCS_PIXEL_FMT_24BIT | + MIPI_DCS_PIXEL_FMT_24BIT << 4); + if (ret < 0) { + log_debug("%s: failed to set pixel format: %d\n", __func__, ret); + return ret; + } + + dsi_generic_write_seq(dsi, 0xb2, 0x00, 0xc8); + dsi_generic_write_seq(dsi, 0xb3, 0x00); + dsi_generic_write_seq(dsi, 0xb4, 0x04); + dsi_generic_write_seq(dsi, 0xb5, 0x42, 0x10, 0x10, 0x00, 0x20); + dsi_generic_write_seq(dsi, 0xb6, 0x0b, 0x0f, 0x3c, 0x13, 0x13, 0xe8); + dsi_generic_write_seq(dsi, 0xb7, 0x4c, 0x06, 0x0c, 0x00, 0x00); + + dsi_generic_write_seq(dsi, 0xc0, 0x01, 0x11); + dsi_generic_write_seq(dsi, 0xc3, 0x07, 0x03, 0x04, 0x04, 0x04); + dsi_generic_write_seq(dsi, 0xc4, 0x12, 0x24, 0x18, 0x18, 0x02, 0x49); + dsi_generic_write_seq(dsi, 0xc5, 0x65); + dsi_generic_write_seq(dsi, 0xc6, 0x41, 0x63); + + dsi_generic_write_seq(dsi, 0xd0, 0x00, 0x46, 0x74, 0x32, 0x1d, 0x03, 0x51, 0x15, 0x04); + dsi_generic_write_seq(dsi, 0xd1, 0x00, 0x46, 0x74, 0x32, 0x1d, 0x03, 0x51, 0x15, 0x04); + dsi_generic_write_seq(dsi, 0xd2, 0x00, 0x46, 0x74, 0x32, 0x1f, 0x03, 0x51, 0x15, 0x04); + dsi_generic_write_seq(dsi, 0xd3, 0x00, 0x46, 0x74, 0x32, 0x1f, 0x03, 0x51, 0x15, 0x04); + dsi_generic_write_seq(dsi, 0xd4, 0x01, 0x46, 0x74, 0x25, 0x00, 0x03, 0x51, 0x15, 0x04); + dsi_generic_write_seq(dsi, 0xd5, 0x01, 0x46, 0x74, 0x25, 0x00, 0x03, 0x51, 0x15, 0x04); + + dsi_generic_write_seq(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, 0x00, 0x00, 0x01, 0xdf); + dsi_generic_write_seq(dsi, MIPI_DCS_SET_PAGE_ADDRESS, 0x00, 0x00, 0x03, 0x1f); + + ret = mipi_dsi_dcs_exit_sleep_mode(dsi); + if (ret < 0) { + log_debug("%s: failed to exit sleep mode: %d\n", __func__, ret); + return ret; + } + + mdelay(120); + + dsi_generic_write_seq(dsi, MIPI_DCS_WRITE_MEMORY_START); + + ret = mipi_dsi_dcs_set_display_on(dsi); + if (ret < 0) { + log_debug("%s: failed to set display on: %d\n", __func__, ret); + return ret; + } + + return 0; +} + +static int lg_lh400wv3_set_backlight(struct udevice *dev, int percent) +{ + struct lg_lh400wv3_priv *priv = dev_get_priv(dev); + int ret; + + ret = backlight_enable(priv->backlight); + if (ret) + return ret; + + return backlight_set_brightness(priv->backlight, percent); +} + +static int lg_lh400wv3_timings(struct udevice *dev, struct display_timing *timing) +{ + memcpy(timing, &default_timing, sizeof(*timing)); + return 0; +} + +static int lg_lh400wv3_of_to_plat(struct udevice *dev) +{ + struct lg_lh400wv3_priv *priv = dev_get_priv(dev); + int ret; + + ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev, + "backlight", &priv->backlight); + if (ret) { + log_debug("%s: cannot get backlight: ret = %d\n", + __func__, ret); + return ret; + } + + ret = device_get_supply_regulator(dev, "avci-supply", &priv->avci); + if (ret) { + log_debug("%s: cannot get avci-supply: ret = %d\n", + __func__, ret); + return ret; + } + + ret = device_get_supply_regulator(dev, "iovcc-supply", &priv->iovcc); + if (ret) { + log_debug("%s: cannot get iovcc-supply: ret = %d\n", + __func__, ret); + return ret; + } + + ret = gpio_request_by_name(dev, "reset-gpios", 0, + &priv->reset_gpio, GPIOD_IS_OUT); + if (ret) { + log_debug("%s: cannot decode reset-gpios (%d)\n", + __func__, ret); + return ret; + } + + return 0; +} + +static int lg_lh400wv3_hw_init(struct udevice *dev) +{ + struct lg_lh400wv3_priv *priv = dev_get_priv(dev); + int ret; + + ret = dm_gpio_set_value(&priv->reset_gpio, 1); + if (ret) { + log_debug("%s: error entering reset (%d)\n", __func__, ret); + return ret; + } + + ret = regulator_set_enable_if_allowed(priv->iovcc, 1); + if (ret) { + log_debug("%s: enabling iovcc-supply failed (%d)\n", + __func__, ret); + return ret; + } + + ret = regulator_set_enable_if_allowed(priv->avci, 1); + if (ret) { + log_debug("%s: enabling avci-supply failed (%d)\n", + __func__, ret); + return ret; + } + + mdelay(1); + + ret = dm_gpio_set_value(&priv->reset_gpio, 0); + if (ret) { + log_debug("%s: error exiting reset (%d)\n", __func__, ret); + return ret; + } + + mdelay(10); + + return 0; +} + +static int lg_lh400wv3_probe(struct udevice *dev) +{ + struct mipi_dsi_panel_plat *plat = dev_get_plat(dev); + + /* fill characteristics of DSI data link */ + plat->lanes = 2; + plat->format = MIPI_DSI_FMT_RGB888; + plat->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM; + + return lg_lh400wv3_hw_init(dev); +} + +static const struct panel_ops lg_lh400wv3_ops = { + .enable_backlight = lg_lh400wv3_enable_backlight, + .set_backlight = lg_lh400wv3_set_backlight, + .get_display_timing = lg_lh400wv3_timings, +}; + +static const struct udevice_id lg_lh400wv3_ids[] = { + { .compatible = "lg,lh400wv3-sd04" }, + { } +}; + +U_BOOT_DRIVER(lg_lh400wv3) = { + .name = "lg_lh400wv3", + .id = UCLASS_PANEL, + .of_match = lg_lh400wv3_ids, + .ops = &lg_lh400wv3_ops, + .of_to_plat = lg_lh400wv3_of_to_plat, + .probe = lg_lh400wv3_probe, + .plat_auto = sizeof(struct mipi_dsi_panel_plat), + .priv_auto = sizeof(struct lg_lh400wv3_priv), +}; From bf2d1902f4c670fa5a4cfa88982aaf6ab6ee2688 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Wed, 2 Oct 2024 12:07:10 +0300 Subject: [PATCH 08/13] video: backlight: add Skyworks/Analogictech AAT2870 led controller driver Add support for Skyworks AAT2870 LED Backlight Driver and Multiple LDO Lighting Management Unit. Only backlight is supported as for now. Supported backlight level range is from 2 to 255 with step of 1. Tested-by: Ion Agorria Signed-off-by: Svyatoslav Ryhel --- drivers/video/Kconfig | 10 +++ drivers/video/Makefile | 1 + drivers/video/aat2870_backlight.c | 132 ++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 drivers/video/aat2870_backlight.c diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 2014090c178..dfe4b3b8a02 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -783,6 +783,16 @@ config ATMEL_HLCD help HLCDC supports video output to an attached LCD panel. +config BACKLIGHT_AAT2870 + bool "Backlight Driver for AAT2870" + depends on BACKLIGHT + select DM_I2C + help + Say Y to enable the backlight driver for Skyworks AAT2870 LED + Backlight Driver and Multiple LDO Lighting Management Unit. + Only backlight is supported as for now. Supported backlight + level range is from 2 to 255 with step of 1. + config BACKLIGHT_LM3532 bool "Backlight Driver for LM3532" depends on BACKLIGHT diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 277ed093a03..ebe4a3961fc 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -29,6 +29,7 @@ obj-$(CONFIG_$(PHASE_)BMP) += bmp.o endif +obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_backlight.o obj-$(CONFIG_BACKLIGHT_LM3532) += lm3532_backlight.o obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_backlight.o obj-$(CONFIG_BACKLIGHT_LP855x) += lp855x_backlight.o diff --git a/drivers/video/aat2870_backlight.c b/drivers/video/aat2870_backlight.c new file mode 100644 index 00000000000..209d15b3639 --- /dev/null +++ b/drivers/video/aat2870_backlight.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2024 Svyatoslav Ryhel + */ + +#define LOG_CATEGORY UCLASS_PANEL_BACKLIGHT + +#include +#include +#include +#include +#include +#include +#include + +#define AAT2870_BL_MIN_BRIGHTNESS 0x01 +#define AAT2870_BL_DEF_BRIGHTNESS 0x64 +#define AAT2870_BL_MAX_BRIGHTNESS 0xff + +#define AAT2870_BL_CH_EN 0x00 +#define AAT2870_BLM 0x01 + +#define AAT2870_BL_CH_ALL 0xff + +#define AAT2870_CURRENT_MAX 27900000 +#define AAT2870_CURRENT_STEP 900000 + +struct aat2870_backlight_priv { + struct gpio_desc enable_gpio; + + int channels; + int max_current; +}; + +static int aat2870_backlight_enable(struct udevice *dev) +{ + struct aat2870_backlight_priv *priv = dev_get_priv(dev); + int ret; + + dm_gpio_set_value(&priv->enable_gpio, 1); + + /* Enable backlight for defined set of channels */ + ret = dm_i2c_reg_write(dev, AAT2870_BL_CH_EN, priv->channels); + if (ret) + return ret; + + return 0; +} + +static int aat2870_backlight_set_brightness(struct udevice *dev, int percent) +{ + struct aat2870_backlight_priv *priv = dev_get_priv(dev); + int brightness, ret; + + if (percent == BACKLIGHT_DEFAULT) + percent = AAT2870_BL_DEF_BRIGHTNESS; + + if (percent < AAT2870_BL_MIN_BRIGHTNESS) + percent = AAT2870_BL_MIN_BRIGHTNESS; + + if (percent > AAT2870_BL_MAX_BRIGHTNESS) + percent = AAT2870_BL_MAX_BRIGHTNESS; + + brightness = percent * priv->max_current; + brightness /= AAT2870_BL_MAX_BRIGHTNESS; + + /* Set brightness level */ + ret = dm_i2c_reg_write(dev, AAT2870_BLM, brightness); + if (ret) + return ret; + + return 0; +} + +static int aat2870_backlight_of_to_plat(struct udevice *dev) +{ + struct aat2870_backlight_priv *priv = dev_get_priv(dev); + int ret; + + ret = gpio_request_by_name(dev, "enable-gpios", 0, + &priv->enable_gpio, GPIOD_IS_OUT); + if (ret) { + log_err("%s: cannot get enable-gpios (%d)\n", + __func__, ret); + return ret; + } + + /* Backlight is one of children but has no dedicated driver */ + ofnode backlight = ofnode_find_subnode(dev_ofnode(dev), "backlight"); + if (ofnode_valid(backlight) && ofnode_is_enabled(backlight)) { + /* Number of channel is equal to bit number */ + priv->channels = dev_read_u32_default(dev, "channels", AAT2870_BL_CH_ALL); + if (priv->channels != AAT2870_BL_CH_ALL) + priv->channels = BIT(priv->channels); + + /* 450mA - 27900mA range with a 900mA step */ + priv->max_current = dev_read_u32_default(dev, "current-max-microamp", + AAT2870_CURRENT_MAX); + priv->max_current /= AAT2870_CURRENT_STEP; + } + + return 0; +} + +static int aat2870_backlight_probe(struct udevice *dev) +{ + if (device_get_uclass_id(dev->parent) != UCLASS_I2C) + return -EPROTONOSUPPORT; + + return 0; +} + +static const struct backlight_ops aat2870_backlight_ops = { + .enable = aat2870_backlight_enable, + .set_brightness = aat2870_backlight_set_brightness, +}; + +static const struct udevice_id aat2870_backlight_ids[] = { + { .compatible = "analogictech,aat2870" }, + { .compatible = "skyworks,aat2870" }, + { } +}; + +U_BOOT_DRIVER(aat2870_backlight) = { + .name = "aat2870_backlight", + .id = UCLASS_PANEL_BACKLIGHT, + .of_match = aat2870_backlight_ids, + .of_to_plat = aat2870_backlight_of_to_plat, + .probe = aat2870_backlight_probe, + .ops = &aat2870_backlight_ops, + .priv_auto = sizeof(struct aat2870_backlight_priv), +}; From 24e578cbac78d7d09ec2bb9b3049a0eec456e626 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 3 Nov 2023 21:00:22 +0200 Subject: [PATCH 09/13] board: lg: star: add Optimus 2X P990 support The LG Optimus 2X is a touchscreen-based, slate-sized smartphone designed and manufactured by LG that runs the Android operating system. The Optimus 2X features a 4" WVGA display, an Nvidia Tegra 2 dual-core chip, 512 MB of RAM and extendable 8 GB of internal storage. UART-B is default debug port. Tested-by: Ion Agorria Signed-off-by: Svyatoslav Ryhel --- arch/arm/dts/Makefile | 1 + arch/arm/dts/tegra20-lg-star.dts | 538 ++++++++++++++++++++++++++++ arch/arm/mach-tegra/tegra20/Kconfig | 5 + board/lg/star/Kconfig | 16 + board/lg/star/MAINTAINERS | 7 + board/lg/star/Makefile | 9 + board/lg/star/star.c | 50 +++ board/lg/star/star.env | 15 + configs/star_defconfig | 93 +++++ doc/board/lg/index.rst | 1 + doc/board/lg/star.rst | 125 +++++++ 11 files changed, 860 insertions(+) create mode 100644 arch/arm/dts/tegra20-lg-star.dts create mode 100644 board/lg/star/Kconfig create mode 100644 board/lg/star/MAINTAINERS create mode 100644 board/lg/star/Makefile create mode 100644 board/lg/star/star.c create mode 100644 board/lg/star/star.env create mode 100644 configs/star_defconfig create mode 100644 doc/board/lg/star.rst diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index c197e3b7a8e..32b698a7f41 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -86,6 +86,7 @@ dtb-$(CONFIG_ARCH_TEGRA) += \ tegra20-asus-tf101.dtb \ tegra20-asus-tf101g.dtb \ tegra20-harmony.dtb \ + tegra20-lg-star.dtb \ tegra20-medcom-wide.dtb \ tegra20-motorola-daytona.dtb \ tegra20-motorola-olympus.dtb \ diff --git a/arch/arm/dts/tegra20-lg-star.dts b/arch/arm/dts/tegra20-lg-star.dts new file mode 100644 index 00000000000..3045bc3135f --- /dev/null +++ b/arch/arm/dts/tegra20-lg-star.dts @@ -0,0 +1,538 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include + +#include "tegra20.dtsi" + +/ { + model = "LG Optimus 2X (P990)"; + compatible = "lg,star", "nvidia,tegra20"; + + chosen { + stdout-path = &uartb; + }; + + aliases { + i2c0 = &pwr_i2c; + i2c5 = &dcdc_i2c; + + mmc0 = &sdmmc4; /* eMMC */ + mmc1 = &sdmmc3; /* uSD slot */ + + rtc0 = &pmic; + rtc1 = "/rtc@7000e000"; + + usb0 = µ_usb; + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x20000000>; /* 512 MB */ + }; + + host1x@50000000 { + dc@54200000 { + rgb { + status = "okay"; + + port { + dpi_output: endpoint { + remote-endpoint = <&bridge_input>; + bus-width = <24>; + }; + }; + }; + }; + }; + + pinmux@70000014 { + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pinmux { + crt { + nvidia,pins = "crtp"; + nvidia,function = "crt"; + }; + + dap1 { + nvidia,pins = "dap1"; + nvidia,function = "dap1"; + }; + + dap2 { + nvidia,pins = "dap2"; + nvidia,function = "dap2"; + }; + + dap3 { + nvidia,pins = "dap3"; + nvidia,function = "dap3"; + }; + + dap4 { + nvidia,pins = "dap4"; + nvidia,function = "dap4"; + }; + + displaya { + nvidia,pins = "lcsn", "ld0", "ld1", "ld10", + "ld11", "ld12", "ld13", "ld14", + "ld15", "ld16", "ld17", "ld2", + "ld3", "ld4", "ld5", "ld6", + "ld7", "ld8", "ld9", "ldc", + "ldi", "lhp0", "lhp1", "lhp2", + "lhs", "lm0", "lm1", "lpp", + "lpw0", "lpw1", "lpw2", "lsc0", + "lsc1", "lsck", "lsda", "lsdi", + "lspi", "lvp0", "lvp1", "lvs"; + nvidia,function = "displaya"; + }; + + gmi { + nvidia,pins = "ata", "atc", "atd", "ate", + "gmb", "irrx", "irtx"; + nvidia,function = "gmi"; + }; + + hdmi { + nvidia,pins = "hdint"; + nvidia,function = "hdmi"; + }; + + i2c { + nvidia,pins = "i2cp", "rm"; + nvidia,function = "i2c"; + }; + + i2c2 { + nvidia,pins = "pta"; + nvidia,function = "i2c2"; + }; + + i2c3 { + nvidia,pins = "dtf"; + nvidia,function = "i2c3"; + }; + + kbc { + nvidia,pins = "kbca", "kbcb", "kbcc", "kbce", + "kbcf"; + nvidia,function = "kbc"; + }; + + owr { + nvidia,pins = "owc"; + nvidia,function = "owr"; + }; + + plla-out { + nvidia,pins = "cdev1"; + nvidia,function = "plla_out"; + }; + + pllp-out4 { + nvidia,pins = "cdev2"; + nvidia,function = "pllp_out4"; + }; + + pwm { + nvidia,pins = "gpu"; + nvidia,function = "pwm"; + }; + + pwr-on { + nvidia,pins = "pmc"; + nvidia,function = "pwr_on"; + }; + + rtck { + nvidia,pins = "gpu7"; + nvidia,function = "rtck"; + }; + + sdio1 { + nvidia,pins = "sdio1"; + nvidia,function = "sdio1"; + }; + + sdio2 { + nvidia,pins = "kbcd"; + nvidia,function = "sdio2"; + }; + + sdio3 { + nvidia,pins = "sdb", "sdc", "sdd", "slxa", + "slxd", "slxk", "slxc"; + nvidia,function = "sdio3"; + }; + + sdio4 { + nvidia,pins = "atb", "gma", "gme"; + nvidia,function = "sdio4"; + }; + + spi1 { + nvidia,pins = "uda"; + nvidia,function = "spi1"; + }; + + spi2 { + nvidia,pins = "spia", "spib", "spic"; + nvidia,function = "spi2"; + }; + + spi2-alt { + nvidia,pins = "spid", "spie", "spig", "spih"; + nvidia,function = "spi2_alt"; + }; + + uarta { + nvidia,pins = "uaa", "uab"; + nvidia,function = "uarta"; + }; + + uartc { + nvidia,pins = "uca", "ucb"; + nvidia,function = "uartc"; + }; + + uartd { + nvidia,pins = "gmc"; + nvidia,function = "uartd"; + }; + + vi { + nvidia,pins = "dtc", "dtd"; + nvidia,function = "vi"; + }; + + vi-sensor-clk { + nvidia,pins = "csus"; + nvidia,function = "vi_sensor_clk"; + }; + + conf-lsda { + nvidia,pins = "lsda", "owc"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + conf-ata { + nvidia,pins = "ata", "dtf", "gmb", "gmc", + "i2cp", "irrx", "kbca", "kbcc", + "kbcd", "kbce", "kbcf", "lcsn", + "ldc", "pta", "rm", "sdc", + "sdd", "spie", "spif", "spig", + "spih", "uaa", "uad", "uca", + "ucb", "pmce"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + conf-crtp { + nvidia,pins = "crtp", "gpv", "hdint", "lhs", + "lm0", "lpw0", "lpw1", "lpw2", + "lsc1", "lsck", "lspi", "lvs", + "slxa", "slxd", "spdi"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + conf-atb { + nvidia,pins = "atb", "atc", "atd", "ate", + "cdev1", "cdev2", "csus", "dap1", + "dap2", "dap3", "dap4", "ddc", + "dta", "dtb", "dte", "gma", + "gmd", "gme", "gpu", "gpu7", + "irtx", "kbcb", "lm1", "lsc0", + "lsdi", "lvp0", "pmc", "sdb", + "sdio1", "slxc", "spdo", "spia", + "spib", "spic", "uab", "uac", + "uda", "ck32", "ddrc", "pmca", + "pmcb", "pmcc", "pmcd", "xm2c", + "xm2d"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + conf-dtc { + nvidia,pins = "dtc", "dtd"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + conf-ld0 { + nvidia,pins = "ld0", "ld1", "ld2", "ld3", + "ld4", "ld5", "ld6", "ld7", + "ld8", "ld9", "ld10", "ld11", + "ld12", "ld13", "ld14", "ld15", + "ld16", "ld17", "ldi", "lhp0", + "lhp1", "lhp2", "lpp", "lvp1", + "slxk", "spid"; + nvidia,pull = ; + nvidia,tristate = ; + }; + + drive-sdio1 { + nvidia,pins = "drive_sdio1", "drive_vi1"; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,low-power-mode = ; + nvidia,pull-down-strength = <31>; + nvidia,pull-up-strength = <31>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; + }; + + drive-i2c { + nvidia,pins = "drive_dbg", "drive_ddc", "drive_at1", + "drive_vi2", "drive_ao1"; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,low-power-mode = ; + nvidia,pull-down-strength = <31>; + nvidia,pull-up-strength = <31>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; + }; + + drive-dap { + nvidia,pins = "drive_dap2", "drive_dap3"; + nvidia,high-speed-mode = ; + nvidia,schmitt = ; + nvidia,low-power-mode = ; + nvidia,pull-down-strength = <46>; + nvidia,pull-up-strength = <46>; + nvidia,slew-rate-rising = ; + nvidia,slew-rate-falling = ; + }; + }; + }; + + uartb: serial@70006040 { + clocks = <&tegra_car 7>; + status = "okay"; + }; + + pwr_i2c: i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + pmic: max8907@3c { + compatible = "maxim,max8907"; + reg = <0x3c>; + + interrupts = ; + #interrupt-cells = <2>; + interrupt-controller; + + #gpio-cells = <2>; + gpio-controller; + + maxim,system-power-controller; + + regulators { + vdd_1v8_vio: sd3 { + regulator-name = "vcc_1v8_io"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + iovcc_1v8_lcd: ldo3 { + regulator-name = "vcc_1v8_lcd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + }; + + avdd_3v3_usb: ldo4 { + regulator-name = "avdd_3v3_usb"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + vcore_emmc: ldo5 { + regulator-name = "vcc_2v8_emmc"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-boot-on; + }; + + vdd_usd: ldo12 { + regulator-name = "vcc_2v8_sdio"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-boot-on; + }; + + vcc_2v8_lcd: ldo14 { + regulator-name = "vcc_2v8_lcd"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-boot-on; + }; + }; + }; + }; + + dcdc_i2c: i2c-5 { + compatible = "i2c-gpio"; + + sda-gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_HIGH>; + scl-gpios = <&gpio TEGRA_GPIO(Q, 1) GPIO_ACTIVE_HIGH>; + + i2c-gpio,delay-us = <5>; + i2c-gpio,timeout-ms = <100>; + + #address-cells = <1>; + #size-cells = <0>; + + aat2870: led-controller@60 { + compatible = "skyworks,aat2870"; + reg = <0x60>; + + enable-gpios = <&gpio TEGRA_GPIO(R, 3) GPIO_ACTIVE_HIGH>; + + backlight { + current-max-microamp = <27900000>; + }; + }; + }; + + micro_usb: usb@c5000000 { + status = "okay"; + dr_mode = "otg"; + }; + + usb-phy@c5000000 { + status = "okay"; + vbus-supply = <&avdd_3v3_usb>; + }; + + sdmmc3: sdhci@c8000400 { + status = "okay"; + bus-width = <4>; + + cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; + + vmmc-supply = <&vdd_usd>; + vqmmc-supply = <&vdd_1v8_vio>; + }; + + sdmmc4: sdhci@c8000600 { + status = "okay"; + bus-width = <8>; + non-removable; + + vmmc-supply = <&vcore_emmc>; + vqmmc-supply = <&vdd_1v8_vio>; + }; + + /* 32KHz oscillator which is used by PMC */ + clk32k_in: clock-32k-in { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "ref-oscillator"; + }; + + bridge: cpu-bridge { + compatible = "nvidia,tegra-8bit-cpu"; + + dc-gpios = <&gpio TEGRA_GPIO(N, 6) GPIO_ACTIVE_HIGH>; + rw-gpios = <&gpio TEGRA_GPIO(B, 3) GPIO_ACTIVE_HIGH>; + cs-gpios = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>; + + data-gpios = <&gpio TEGRA_GPIO(E, 0) GPIO_ACTIVE_HIGH>, + <&gpio TEGRA_GPIO(E, 1) GPIO_ACTIVE_HIGH>, + <&gpio TEGRA_GPIO(E, 2) GPIO_ACTIVE_HIGH>, + <&gpio TEGRA_GPIO(E, 3) GPIO_ACTIVE_HIGH>, + <&gpio TEGRA_GPIO(E, 4) GPIO_ACTIVE_HIGH>, + <&gpio TEGRA_GPIO(E, 5) GPIO_ACTIVE_HIGH>, + <&gpio TEGRA_GPIO(E, 6) GPIO_ACTIVE_HIGH>, + <&gpio TEGRA_GPIO(E, 7) GPIO_ACTIVE_HIGH>; + + nvidia,init-sequence = <0x0000002c 0x0 0x0 0x00005000>; + + panel { + /* + * There are 2 rev of P990. One has Hitachi TX10D07VM0BAA + * panel and other has LG LH400WV3-SD04 panel. We are using + * Hitachi here but it is dynamically adjusted for the + * correct compatible. + */ + compatible = "hit,tx10d07vm0baa"; + + reset-gpios = <&gpio TEGRA_GPIO(V, 7) GPIO_ACTIVE_LOW>; + + avci-supply = <&vcc_2v8_lcd>; + iovcc-supply = <&iovcc_1v8_lcd>; + + backlight = <&aat2870>; + + port { + panel_input: endpoint { + remote-endpoint = <&bridge_output>; + }; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + bridge_input: endpoint { + remote-endpoint = <&dpi_output>; + }; + }; + + port@1 { + reg = <1>; + + bridge_output: endpoint { + remote-endpoint = <&panel_input>; + }; + }; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + key-power { + label = "Power"; + gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + key-volume-up { + label = "Volume Up"; + gpios = <&gpio TEGRA_GPIO(G, 1) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + key-volume-down { + label = "Volume Down"; + gpios = <&gpio TEGRA_GPIO(G, 0) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + vdd_3v3_vbat: regulator-vbat { + compatible = "regulator-fixed"; + regulator-name = "vdd_vbat"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; +}; diff --git a/arch/arm/mach-tegra/tegra20/Kconfig b/arch/arm/mach-tegra/tegra20/Kconfig index a79fdc25650..bedbedade7b 100644 --- a/arch/arm/mach-tegra/tegra20/Kconfig +++ b/arch/arm/mach-tegra/tegra20/Kconfig @@ -54,6 +54,10 @@ config TARGET_SEABOARD select TEGRA_LP0 select TEGRA_PMU +config TARGET_STAR + bool "LG Tegra20 Star board" + select BOARD_LATE_INIT + config TARGET_TEC bool "Avionic Design Tamonten Evaluation Carrier" select BOARD_LATE_INIT @@ -88,6 +92,7 @@ source "board/compal/paz00/Kconfig" source "board/acer/picasso/Kconfig" source "board/avionic-design/plutux/Kconfig" source "board/nvidia/seaboard/Kconfig" +source "board/lg/star/Kconfig" source "board/avionic-design/tec/Kconfig" source "board/asus/transformer-t20/Kconfig" source "board/compulab/trimslice/Kconfig" diff --git a/board/lg/star/Kconfig b/board/lg/star/Kconfig new file mode 100644 index 00000000000..58523121750 --- /dev/null +++ b/board/lg/star/Kconfig @@ -0,0 +1,16 @@ +if TARGET_STAR + +config SYS_BOARD + default "star" + +config SYS_VENDOR + default "lg" + +config SYS_CONFIG_NAME + default "tegra" + +config TEGRA_BOARD_STRING + string "Default Tegra board name" + default "LG Star" + +endif diff --git a/board/lg/star/MAINTAINERS b/board/lg/star/MAINTAINERS new file mode 100644 index 00000000000..e2d6e904f02 --- /dev/null +++ b/board/lg/star/MAINTAINERS @@ -0,0 +1,7 @@ +STAR BOARD +M: Svyatoslav Ryhel +S: Maintained +F: arch/arm/dts/tegra20-lg-star.dts +F: board/lg/star/ +F: configs/star_defconfig +F: doc/board/lg/star.rst diff --git a/board/lg/star/Makefile b/board/lg/star/Makefile new file mode 100644 index 00000000000..3e6e9f4e41c --- /dev/null +++ b/board/lg/star/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2010-2012 +# NVIDIA Corporation +# +# (C) Copyright 2024 +# Svyatoslav Ryhel + +obj-y += star.o diff --git a/board/lg/star/star.c b/board/lg/star/star.c new file mode 100644 index 00000000000..dc593754101 --- /dev/null +++ b/board/lg/star/star.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2023 + * Svyatoslav Ryhel + */ + +#include +#include +#include +#include +#include + +static int star_fix_panel(void *fdt) +{ + int panel_offset, ret; + + /* Patch panel compatible */ + spl_gpio_input(NULL, TEGRA_GPIO(J, 5)); + if (spl_gpio_get_value(NULL, TEGRA_GPIO(J, 5))) { + panel_offset = fdt_node_offset_by_compatible(fdt, -1, + "hit,tx10d07vm0baa"); + if (panel_offset < 0) { + log_debug("%s: panel node not found\n", __func__); + return panel_offset; + } + + ret = fdt_setprop_string(fdt, panel_offset, "compatible", + "lg,lh400wv3-sd04"); + if (ret) { + log_debug("%s: panel comapible patch failed\n", __func__); + return ret; + } + } + + return 0; +} + +void pinmux_init(void) +{ + void *fdt = (void *)gd->fdt_blob; + + star_fix_panel(fdt); +} + +#if IS_ENABLED(CONFIG_OF_LIBFDT) && IS_ENABLED(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *fdt, struct bd_info *bd) +{ + return star_fix_panel(fdt); +} +#endif diff --git a/board/lg/star/star.env b/board/lg/star/star.env new file mode 100644 index 00000000000..f2bf298a997 --- /dev/null +++ b/board/lg/star/star.env @@ -0,0 +1,15 @@ +#include + +button_cmd_0_name=Volume Down +button_cmd_0=bootmenu +partitions=name=emmc,start=0,size=-,uuid=${uuid_gpt_rootfs} +boot_dev=1 + +bootmenu_0=mount internal storage=usb start && ums 0 mmc 0; bootmenu +bootmenu_1=mount external storage=usb start && ums 0 mmc 1; bootmenu +bootmenu_2=fastboot=echo Starting Fastboot protocol ...; fastboot usb 0; bootmenu +bootmenu_3=update bootloader=run flash_uboot +bootmenu_4=reboot RCM=enterrcm +bootmenu_5=reboot=reset +bootmenu_6=power off=poweroff +bootmenu_delay=-1 diff --git a/configs/star_defconfig b/configs/star_defconfig new file mode 100644 index 00000000000..f0574b077ac --- /dev/null +++ b/configs/star_defconfig @@ -0,0 +1,93 @@ +CONFIG_ARM=y +CONFIG_ARCH_TEGRA=y +CONFIG_SUPPORT_PASSING_ATAGS=y +CONFIG_CMDLINE_TAG=y +CONFIG_INITRD_TAG=y +CONFIG_TEXT_BASE=0x00110000 +CONFIG_NR_DRAM_BANKS=2 +CONFIG_ENV_SOURCE_FILE="star" +CONFIG_ENV_SIZE=0x3000 +CONFIG_ENV_OFFSET=0xFFFFD000 +CONFIG_DEFAULT_DEVICE_TREE="tegra20-lg-star" +CONFIG_SPL_STACK=0xffffc +CONFIG_SPL_TEXT_BASE=0x00108000 +CONFIG_SYS_LOAD_ADDR=0x2000000 +CONFIG_TEGRA20=y +CONFIG_TARGET_STAR=y +CONFIG_TEGRA_ENABLE_UARTB=y +CONFIG_CMD_EBTUPDATE=y +CONFIG_BUTTON_CMD=y +CONFIG_BOOTDELAY=0 +CONFIG_AUTOBOOT_KEYED=y +CONFIG_AUTOBOOT_KEYED_CTRLC=y +CONFIG_OF_BOARD_SETUP=y +CONFIG_OF_SYSTEM_SETUP=y +CONFIG_BOOTCOMMAND="bootflow scan; echo 'Boot configuration not found... Power off in 3 sec'; sleep 3; poweroff" +CONFIG_SYS_PBSIZE=2085 +CONFIG_SPL_FOOTPRINT_LIMIT=y +CONFIG_SPL_MAX_FOOTPRINT=0x8000 +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_HAVE_INIT_STACK=y +CONFIG_SPL_SYS_MALLOC=y +CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y +CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x90000 +CONFIG_SPL_SYS_MALLOC_SIZE=0x10000 +CONFIG_SYS_PROMPT="Tegra20 (Star) # " +# CONFIG_CMD_BOOTEFI_BOOTMGR is not set +CONFIG_CMD_BOOTMENU=y +# CONFIG_CMD_IMI is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_GPT_RENAME=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_POWEROFF=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +CONFIG_CMD_UMS_ABORT_KEYED=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_PAUSE=y +CONFIG_CMD_REGULATOR=y +CONFIG_CMD_EXT4_WRITE=y +# CONFIG_SPL_DOS_PARTITION is not set +# CONFIG_SPL_EFI_PARTITION is not set +CONFIG_ENV_OVERWRITE=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_SYS_MMC_ENV_PART=2 +CONFIG_BUTTON=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x11000000 +CONFIG_FASTBOOT_BUF_SIZE=0x5000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_FASTBOOT_CMD_OEM_FORMAT=y +CONFIG_DM_I2C_GPIO=y +CONFIG_SYS_I2C_TEGRA=y +CONFIG_BUTTON_KEYBOARD=y +CONFIG_DM_PMIC=y +CONFIG_DM_PMIC_MAX8907=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_MAX8907=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_SYS_NS16550=y +CONFIG_SYSRESET_MAX8907=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_TEGRA=y +CONFIG_USB_ULPI_VIEWPORT=y +CONFIG_USB_ULPI=y +CONFIG_USB_KEYBOARD=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="LG" +CONFIG_USB_GADGET_VENDOR_NUM=0x1004 +CONFIG_USB_GADGET_PRODUCT_NUM=0x7100 +CONFIG_CI_UDC=y +CONFIG_VIDEO=y +# CONFIG_VIDEO_LOGO is not set +# CONFIG_VIDEO_BPP8 is not set +CONFIG_VIDEO_LCD_LG_LH400WV3=y +CONFIG_VIDEO_LCD_HITACHI_TX10D07VM0BAA=y +CONFIG_BACKLIGHT_AAT2870=y +CONFIG_VIDEO_BRIDGE=y +CONFIG_TEGRA_8BIT_CPU_BRIDGE=y diff --git a/doc/board/lg/index.rst b/doc/board/lg/index.rst index 3af3681e0bb..2db0f2374ad 100644 --- a/doc/board/lg/index.rst +++ b/doc/board/lg/index.rst @@ -6,4 +6,5 @@ LG .. toctree:: :maxdepth: 2 + star x3_t30 diff --git a/doc/board/lg/star.rst b/doc/board/lg/star.rst new file mode 100644 index 00000000000..9e480929182 --- /dev/null +++ b/doc/board/lg/star.rst @@ -0,0 +1,125 @@ +.. SPDX-License-Identifier: GPL-2.0+ + +U-Boot for the LG Optimus 2X P990 +================================= + +``DISCLAMER!`` Moving your device to use U-Boot assumes replacement of the +vendor bootloader. Vendor Android firmwares will no longer be able to run on +the device. This replacement IS reversible. + +Quick Start +----------- + +- Build U-Boot +- Process U-Boot +- Flashing U-Boot into the eMMC +- Boot +- Self Upgrading + +Build U-Boot +------------ + +.. code-block:: bash + + $ export CROSS_COMPILE=arm-none-eabi- + $ make star_defconfig + $ make + +After the build succeeds, you will obtain the final ``u-boot-dtb-tegra.bin`` +image, ready for further processing. + +Process U-Boot +-------------- + +``DISCLAMER!`` All questions related to the re-crypt work should be asked +in re-crypt repo issues. NOT HERE! + +re-crypt is a tool that processes the ``u-boot-dtb-tegra.bin`` binary into form +usable by device. This process is required only on the first installation or +to recover the device in case of a failed update. + +Permanent installation can be performed either by using the nv3p protocol or by +pre-loading just built U-Boot into RAM. + +Processing for the NV3P protocol +******************************** + +.. code-block:: bash + + $ git clone https://gitlab.com/grate-driver/re-crypt.git + $ cd re-crypt # place your u-boot-dtb-tegra.bin here + $ ./re-crypt.py --dev star + +The script will produce a ``repart-block.bin`` ready to flash. + +Processing for pre-loaded U-Boot +******************************** + +The procedure is the same, but the ``--split`` argument is used with the +``re-crypt.py``. The script will produce ``bct.img`` and ``ebt.img`` ready +to flash. + +Flashing U-Boot into the eMMC +----------------------------- + +``DISCLAMER!`` All questions related to NvFlash should be asked in the proper +place. NOT HERE! Flashing U-Boot will erase all eMMC, so make a backup before! + +Permanent installation can be performed either by using the nv3p protocol or by +pre-loading just built U-Boot into RAM. + +Flashing with the NV3P protocol +******************************* + +Nv3p is a custom Nvidia protocol used to recover bricked devices. Devices can +enter it by pre-loading vendor bootloader with nvflash. + +With nv3p, ``repart-block.bin`` is used. It contains BCT and a bootloader in +encrypted state in form, which can just be written RAW at the start of eMMC. + +.. code-block:: bash + + $ ./nvflash_v1.13.87205 --bct star.bct --setbct --odmdata 0xC8000 + --configfile flash.cfg --bl android_bootloader.bin --sync + $ ./utiils/nvflash_v1.13.87205 --resume --rawdevicewrite 0 2048 repart-block.bin + +When flashing is done, reboot the device. + +Flashing with a pre-loaded U-Boot +********************************* + +U-Boot pre-loaded into RAM acts the same as when it was booted "cold". Currently +U-Boot supports bootmenu entry fastboot, which allows to write a processed copy +of U-Boot permanently into eMMC. + +While pre-loading U-Boot, hold the ``volume down`` button which will trigger +the bootmenu. There, select ``fastboot`` using the volume and power buttons. +After, on host PC, do: + +.. code-block:: bash + + $ fastboot flash 0.1 bct.img + $ fastboot flash 0.2 ebt.img + $ fastboot reboot + +Device will reboot. + +Boot +---- + +To boot Linux, U-Boot will look for an ``extlinux.conf`` on MicroSD and then on +eMMC. Additionally, if the Volume Down button is pressed while booting, the +device will enter bootmenu. Bootmenu contains entries to mount MicroSD and eMMC +as mass storage, fastboot, reboot, reboot RCM, poweroff, enter U-Boot console +and update bootloader (check the next chapter). + +Flashing ``repart-block.bin`` eliminates vendor restrictions on eMMC and allows +the user to use/partition it in any way the user desires. + +Self Upgrading +-------------- + +Place your ``u-boot-dtb-tegra.bin`` on the first partition of the MicroSD card +and insert it into the device. Enter bootmenu, choose update the bootloader +option with the Power button and U-Boot should update itself. Once the process +is completed, U-Boot will ask to press any button to reboot. From 94b395cc2db0160a079b208d9cc49485f2b943b1 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Tue, 15 Apr 2025 11:54:55 +0300 Subject: [PATCH 10/13] ARM: tegra: add PRAM Kconfig option Wrap CFG_PRAM with Kconfig option. Signed-off-by: Svyatoslav Ryhel --- arch/arm/mach-tegra/Kconfig | 14 ++++++++++++++ include/configs/tegra.h | 4 ++++ 2 files changed, 18 insertions(+) diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 4690dcb3ea6..67bd2398bfd 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -198,6 +198,20 @@ source "arch/arm/mach-tegra/tegra124/Kconfig" source "arch/arm/mach-tegra/tegra210/Kconfig" source "arch/arm/mach-tegra/tegra186/Kconfig" +config TEGRA_PRAM + select TEGRA_SUPPORT_NON_SECURE if TEGRA114 || TEGRA124 + bool "Support reservation of the protected RAM" + help + This option indicates the presence of a region of protected RAM. + +config TEGRA_PRAM_SIZE + hex "Size of pRAM region" + depends on TEGRA_PRAM + default 0x1000 + help + Size in kB of carevout which will be reserved as protected RAM starting + from the top of the RAM. + config TEGRA_SPI def_bool y depends on TEGRA20_SFLASH || TEGRA20_SLINK || TEGRA114_SPI diff --git a/include/configs/tegra.h b/include/configs/tegra.h index 77bc38930d2..5db3129fade 100644 --- a/include/configs/tegra.h +++ b/include/configs/tegra.h @@ -29,6 +29,10 @@ #include "tegra210-common.h" #endif +#ifdef CONFIG_TEGRA_PRAM + #define CFG_PRAM CONFIG_TEGRA_PRAM_SIZE +#endif + #include "tegra-common-post.h" #endif /* __CONFIG_H */ From 718740855325c3366ea95e420bf8b32f47b0aa9f Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Tue, 15 Apr 2025 11:55:28 +0300 Subject: [PATCH 11/13] ARM: tegra: convert boards to use TEGRA_PRAM Switch boards that use CFG_PRAM to TEGRA_PRAM. Signed-off-by: Svyatoslav Ryhel --- board/asus/transformer-t114/Kconfig | 6 +++++- board/nvidia/tegratab/Kconfig | 6 +++++- board/xiaomi/mocha/Kconfig | 6 +++++- doc/board/asus/transformer_t114.rst | 2 +- doc/board/nvidia/tegratab.rst | 2 +- doc/board/xiaomi/mocha.rst | 2 +- include/configs/mocha.h | 19 ------------------- include/configs/tegratab.h | 19 ------------------- include/configs/transformer-t114.h | 19 ------------------- 9 files changed, 18 insertions(+), 63 deletions(-) delete mode 100644 include/configs/mocha.h delete mode 100644 include/configs/tegratab.h delete mode 100644 include/configs/transformer-t114.h diff --git a/board/asus/transformer-t114/Kconfig b/board/asus/transformer-t114/Kconfig index 2560c35846e..2d7630422de 100644 --- a/board/asus/transformer-t114/Kconfig +++ b/board/asus/transformer-t114/Kconfig @@ -7,10 +7,14 @@ config SYS_VENDOR default "asus" config SYS_CONFIG_NAME - default "transformer-t114" + default "tegra" config TEGRA_BOARD_STRING string "Default Tegra board name" default "ASUS Transformer T114" +config TEGRA_PRAM_SIZE + depends on TEGRA_PRAM + default 0x20000 + endif diff --git a/board/nvidia/tegratab/Kconfig b/board/nvidia/tegratab/Kconfig index 8bd7cfd87b8..25468bb57f5 100644 --- a/board/nvidia/tegratab/Kconfig +++ b/board/nvidia/tegratab/Kconfig @@ -7,10 +7,14 @@ config SYS_VENDOR default "nvidia" config SYS_CONFIG_NAME - default "tegratab" + default "tegra" config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA TegraTab" +config TEGRA_PRAM_SIZE + depends on TEGRA_PRAM + default 0x21c00 + endif diff --git a/board/xiaomi/mocha/Kconfig b/board/xiaomi/mocha/Kconfig index bb53cc56161..3e1e076986c 100644 --- a/board/xiaomi/mocha/Kconfig +++ b/board/xiaomi/mocha/Kconfig @@ -7,10 +7,14 @@ config SYS_VENDOR default "xiaomi" config SYS_CONFIG_NAME - default "mocha" + default "tegra" config TEGRA_BOARD_STRING string "Default Tegra board name" default "Xiaomi Mocha" +config TEGRA_PRAM_SIZE + depends on TEGRA_PRAM + default 0x38400 + endif diff --git a/doc/board/asus/transformer_t114.rst b/doc/board/asus/transformer_t114.rst index 3e42b5dd9a3..29094eeeaf4 100644 --- a/doc/board/asus/transformer_t114.rst +++ b/doc/board/asus/transformer_t114.rst @@ -36,7 +36,7 @@ To build U-Boot without SPL adjust tf701t_defconfig: CONFIG_TEXT_BASE=0x80A00000 CONFIG_SKIP_LOWLEVEL_INIT=y # CONFIG_OF_BOARD_SETUP is not set - CONFIG_TEGRA_SUPPORT_NON_SECURE=y + CONFIG_TEGRA_PRAM=y After the build succeeds, you will obtain the final ``u-boot-dtb.bin`` file, ready for booting with fastboot boot or which can be further processed into diff --git a/doc/board/nvidia/tegratab.rst b/doc/board/nvidia/tegratab.rst index c6d97ce3828..65150fc7fbf 100644 --- a/doc/board/nvidia/tegratab.rst +++ b/doc/board/nvidia/tegratab.rst @@ -36,7 +36,7 @@ To build U-Boot without SPL adjust tegratab_defconfig: CONFIG_TEXT_BASE=0x80A00000 CONFIG_SKIP_LOWLEVEL_INIT=y # CONFIG_OF_BOARD_SETUP is not set - CONFIG_TEGRA_SUPPORT_NON_SECURE=y + CONFIG_TEGRA_PRAM=y After the build succeeds, you will obtain the final ``u-boot-dtb.bin`` file, ready for booting with fastboot boot or which can be further processed into diff --git a/doc/board/xiaomi/mocha.rst b/doc/board/xiaomi/mocha.rst index be3e333127b..230081e3287 100644 --- a/doc/board/xiaomi/mocha.rst +++ b/doc/board/xiaomi/mocha.rst @@ -105,7 +105,7 @@ To build U-Boot without SPL suitable for chainloading adjust mocha_defconfig: CONFIG_TEXT_BASE=0x80A00000 CONFIG_SKIP_LOWLEVEL_INIT=y # CONFIG_OF_BOARD_SETUP is not set - CONFIG_TEGRA_SUPPORT_NON_SECURE=y + CONFIG_TEGRA_PRAM=y After the build succeeds, you will obtain the final ``u-boot-dtb.bin`` file, ready for booting using vendor bootloader's fastboot or which can be diff --git a/include/configs/mocha.h b/include/configs/mocha.h deleted file mode 100644 index 7255f31baec..00000000000 --- a/include/configs/mocha.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. - * - * Copyright (c) 2024, Svyatoslav Ryhel - */ - -#ifndef __CONFIG_H -#define __CONFIG_H - -#include "tegra124-common.h" - -#ifdef CONFIG_TEGRA_SUPPORT_NON_SECURE - #define CFG_PRAM 0x38400 /* 225 MB */ -#endif - -#include "tegra-common-post.h" - -#endif /* __CONFIG_H */ diff --git a/include/configs/tegratab.h b/include/configs/tegratab.h deleted file mode 100644 index afab01ec09c..00000000000 --- a/include/configs/tegratab.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. - * - * Copyright (c) 2023, Svyatoslav Ryhel - */ - -#ifndef __CONFIG_H -#define __CONFIG_H - -#include "tegra114-common.h" - -#ifdef CONFIG_TEGRA_SUPPORT_NON_SECURE - #define CFG_PRAM 0x21c00 /* 135 MB */ -#endif - -#include "tegra-common-post.h" - -#endif /* __CONFIG_H */ diff --git a/include/configs/transformer-t114.h b/include/configs/transformer-t114.h deleted file mode 100644 index 2fbf3417691..00000000000 --- a/include/configs/transformer-t114.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. - * - * Copyright (c) 2023, Svyatoslav Ryhel - */ - -#ifndef __CONFIG_H -#define __CONFIG_H - -#include "tegra114-common.h" - -#ifdef CONFIG_TEGRA_SUPPORT_NON_SECURE - #define CFG_PRAM 0x20000 /* 128 MB */ -#endif - -#include "tegra-common-post.h" - -#endif /* __CONFIG_H */ From 66c4ac31ca5c74e4bcdb1889c9d64e9554412de7 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Tue, 15 Apr 2025 18:07:01 +0300 Subject: [PATCH 12/13] ARM: tegra: set default SYS_CONFIG_NAME from SoC Kconfig Since most boards now use the same generic device config header, move its setup to SoC Kconfig instead of setting SYS_CONFIG_NAME in each board's Kconfig. Signed-off-by: Svyatoslav Ryhel --- arch/arm/mach-tegra/Kconfig | 3 +++ board/acer/picasso/Kconfig | 3 --- board/asus/grouper/Kconfig | 3 --- board/asus/transformer-t114/Kconfig | 3 --- board/asus/transformer-t20/Kconfig | 3 --- board/asus/transformer-t30/Kconfig | 3 --- board/avionic-design/medcom-wide/Kconfig | 3 --- board/avionic-design/plutux/Kconfig | 3 --- board/avionic-design/tec-ng/Kconfig | 3 --- board/avionic-design/tec/Kconfig | 3 --- board/cei/cei-tk1-som/Kconfig | 3 --- board/compal/paz00/Kconfig | 3 --- board/compulab/trimslice/Kconfig | 3 --- board/htc/endeavoru/Kconfig | 3 --- board/lenovo/ideapad-yoga-11/Kconfig | 3 --- board/lg/star/Kconfig | 3 --- board/lg/x3-t30/Kconfig | 3 --- board/microsoft/surface-rt/Kconfig | 3 --- board/nvidia/beaver/Kconfig | 3 --- board/nvidia/cardhu/Kconfig | 3 --- board/nvidia/dalmore/Kconfig | 3 --- board/nvidia/harmony/Kconfig | 3 --- board/nvidia/jetson-tk1/Kconfig | 3 --- board/nvidia/nyan-big/Kconfig | 3 --- board/nvidia/p2371-0000/Kconfig | 3 --- board/nvidia/p2371-2180/Kconfig | 3 --- board/nvidia/p2571/Kconfig | 3 --- board/nvidia/p2771-0000/Kconfig | 3 --- board/nvidia/p3450-0000/Kconfig | 3 --- board/nvidia/seaboard/Kconfig | 3 --- board/nvidia/tegratab/Kconfig | 3 --- board/nvidia/venice2/Kconfig | 3 --- board/nvidia/ventana/Kconfig | 3 --- board/ouya/ouya/Kconfig | 3 --- board/toradex/apalis_t30/Kconfig | 3 --- board/toradex/colibri_t20/Kconfig | 3 --- board/toradex/colibri_t30/Kconfig | 3 --- board/wexler/qc750/Kconfig | 3 --- board/xiaomi/mocha/Kconfig | 3 --- 39 files changed, 3 insertions(+), 114 deletions(-) diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 67bd2398bfd..c3c352eceb1 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -198,6 +198,9 @@ source "arch/arm/mach-tegra/tegra124/Kconfig" source "arch/arm/mach-tegra/tegra210/Kconfig" source "arch/arm/mach-tegra/tegra186/Kconfig" +config SYS_CONFIG_NAME + default "tegra" + config TEGRA_PRAM select TEGRA_SUPPORT_NON_SECURE if TEGRA114 || TEGRA124 bool "Support reservation of the protected RAM" diff --git a/board/acer/picasso/Kconfig b/board/acer/picasso/Kconfig index 879b778aa53..947cd2b1f18 100644 --- a/board/acer/picasso/Kconfig +++ b/board/acer/picasso/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "acer" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "Acer Iconia Tab A500" diff --git a/board/asus/grouper/Kconfig b/board/asus/grouper/Kconfig index 3bd712b274c..82529908607 100644 --- a/board/asus/grouper/Kconfig +++ b/board/asus/grouper/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "asus" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "ASUS Google Nexus 7 (2012)" diff --git a/board/asus/transformer-t114/Kconfig b/board/asus/transformer-t114/Kconfig index 2d7630422de..5c25ea82dde 100644 --- a/board/asus/transformer-t114/Kconfig +++ b/board/asus/transformer-t114/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "asus" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "ASUS Transformer T114" diff --git a/board/asus/transformer-t20/Kconfig b/board/asus/transformer-t20/Kconfig index 3e80d38d590..3a06c79e4bf 100644 --- a/board/asus/transformer-t20/Kconfig +++ b/board/asus/transformer-t20/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "asus" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "ASUS Transformer T20" diff --git a/board/asus/transformer-t30/Kconfig b/board/asus/transformer-t30/Kconfig index 34fd6f200f8..dbbc3210528 100644 --- a/board/asus/transformer-t30/Kconfig +++ b/board/asus/transformer-t30/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "asus" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "ASUS Transformer T30" diff --git a/board/avionic-design/medcom-wide/Kconfig b/board/avionic-design/medcom-wide/Kconfig index 54474b5061a..b2fbae639ca 100644 --- a/board/avionic-design/medcom-wide/Kconfig +++ b/board/avionic-design/medcom-wide/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "avionic-design" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "Avionic Design Medcom-Wide" diff --git a/board/avionic-design/plutux/Kconfig b/board/avionic-design/plutux/Kconfig index 35b19dd2ea0..cf9894cf0c6 100644 --- a/board/avionic-design/plutux/Kconfig +++ b/board/avionic-design/plutux/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "avionic-design" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "Avionic Design Plutux" diff --git a/board/avionic-design/tec-ng/Kconfig b/board/avionic-design/tec-ng/Kconfig index 8782e7a2a67..a410fdb9317 100644 --- a/board/avionic-design/tec-ng/Kconfig +++ b/board/avionic-design/tec-ng/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "avionic-design" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "Avionic Design Tamonten™ NG Evaluation Carrier" diff --git a/board/avionic-design/tec/Kconfig b/board/avionic-design/tec/Kconfig index 12cc4e1f4d0..ae4d1e24ffe 100644 --- a/board/avionic-design/tec/Kconfig +++ b/board/avionic-design/tec/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "avionic-design" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "Avionic Design Tamonten Evaluation Carrier" diff --git a/board/cei/cei-tk1-som/Kconfig b/board/cei/cei-tk1-som/Kconfig index 9b944730e63..ddaf8a7771f 100644 --- a/board/cei/cei-tk1-som/Kconfig +++ b/board/cei/cei-tk1-som/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "cei" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "CEI tk1-som" diff --git a/board/compal/paz00/Kconfig b/board/compal/paz00/Kconfig index 7fa47fc8c77..ce2e381b7b0 100644 --- a/board/compal/paz00/Kconfig +++ b/board/compal/paz00/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "compal" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "Compal Paz00" diff --git a/board/compulab/trimslice/Kconfig b/board/compulab/trimslice/Kconfig index 226ebc228a8..b5a38359a54 100644 --- a/board/compulab/trimslice/Kconfig +++ b/board/compulab/trimslice/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "compulab" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "Compulab Trimslice" diff --git a/board/htc/endeavoru/Kconfig b/board/htc/endeavoru/Kconfig index ef50da9be45..d9734f00c2b 100644 --- a/board/htc/endeavoru/Kconfig +++ b/board/htc/endeavoru/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "htc" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "HTC One X" diff --git a/board/lenovo/ideapad-yoga-11/Kconfig b/board/lenovo/ideapad-yoga-11/Kconfig index cd4aa32d86d..328ebe22280 100644 --- a/board/lenovo/ideapad-yoga-11/Kconfig +++ b/board/lenovo/ideapad-yoga-11/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "lenovo" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "Lenovo Ideapad Yoga 11" diff --git a/board/lg/star/Kconfig b/board/lg/star/Kconfig index 58523121750..7e50a4677f5 100644 --- a/board/lg/star/Kconfig +++ b/board/lg/star/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "lg" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "LG Star" diff --git a/board/lg/x3-t30/Kconfig b/board/lg/x3-t30/Kconfig index d2cdf860db4..534c5aa97c1 100644 --- a/board/lg/x3-t30/Kconfig +++ b/board/lg/x3-t30/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "lg" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "LG X3 Board" diff --git a/board/microsoft/surface-rt/Kconfig b/board/microsoft/surface-rt/Kconfig index 6afddb9b363..245284202cf 100644 --- a/board/microsoft/surface-rt/Kconfig +++ b/board/microsoft/surface-rt/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "microsoft" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "Microsoft Surface RT" diff --git a/board/nvidia/beaver/Kconfig b/board/nvidia/beaver/Kconfig index fe36d475b30..32f2918adc9 100644 --- a/board/nvidia/beaver/Kconfig +++ b/board/nvidia/beaver/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA Beaver" diff --git a/board/nvidia/cardhu/Kconfig b/board/nvidia/cardhu/Kconfig index 92de3f2e669..8081c9ac25a 100644 --- a/board/nvidia/cardhu/Kconfig +++ b/board/nvidia/cardhu/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA Cardhu" diff --git a/board/nvidia/dalmore/Kconfig b/board/nvidia/dalmore/Kconfig index 8da3499b9f5..a8d7f1c8ca6 100644 --- a/board/nvidia/dalmore/Kconfig +++ b/board/nvidia/dalmore/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA Dalmore" diff --git a/board/nvidia/harmony/Kconfig b/board/nvidia/harmony/Kconfig index eedee71cac9..dfbb71cdfd4 100644 --- a/board/nvidia/harmony/Kconfig +++ b/board/nvidia/harmony/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA Harmony" diff --git a/board/nvidia/jetson-tk1/Kconfig b/board/nvidia/jetson-tk1/Kconfig index 9eeb55f639d..c89eedf4562 100644 --- a/board/nvidia/jetson-tk1/Kconfig +++ b/board/nvidia/jetson-tk1/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA Jetson TK1" diff --git a/board/nvidia/nyan-big/Kconfig b/board/nvidia/nyan-big/Kconfig index 65fef3c063f..9c27c9a8351 100644 --- a/board/nvidia/nyan-big/Kconfig +++ b/board/nvidia/nyan-big/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "Google/NVIDIA Nyan-big" diff --git a/board/nvidia/p2371-0000/Kconfig b/board/nvidia/p2371-0000/Kconfig index e2770781a25..659b81775f0 100644 --- a/board/nvidia/p2371-0000/Kconfig +++ b/board/nvidia/p2371-0000/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA P2371-0000" diff --git a/board/nvidia/p2371-2180/Kconfig b/board/nvidia/p2371-2180/Kconfig index 8d97dc354b6..07cd2406f84 100644 --- a/board/nvidia/p2371-2180/Kconfig +++ b/board/nvidia/p2371-2180/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA P2371-2180" diff --git a/board/nvidia/p2571/Kconfig b/board/nvidia/p2571/Kconfig index 1d41e9d68f4..eb6e8016d91 100644 --- a/board/nvidia/p2571/Kconfig +++ b/board/nvidia/p2571/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA P2571" diff --git a/board/nvidia/p2771-0000/Kconfig b/board/nvidia/p2771-0000/Kconfig index 199e04da07e..960e7015488 100644 --- a/board/nvidia/p2771-0000/Kconfig +++ b/board/nvidia/p2771-0000/Kconfig @@ -10,9 +10,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA P2771-0000" diff --git a/board/nvidia/p3450-0000/Kconfig b/board/nvidia/p3450-0000/Kconfig index 9235c2a0c35..eddf71f4073 100644 --- a/board/nvidia/p3450-0000/Kconfig +++ b/board/nvidia/p3450-0000/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA P3450-0000" diff --git a/board/nvidia/seaboard/Kconfig b/board/nvidia/seaboard/Kconfig index a6baeeb7f87..f60a65676de 100644 --- a/board/nvidia/seaboard/Kconfig +++ b/board/nvidia/seaboard/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA Seaboard" diff --git a/board/nvidia/tegratab/Kconfig b/board/nvidia/tegratab/Kconfig index 25468bb57f5..a55c1c3810e 100644 --- a/board/nvidia/tegratab/Kconfig +++ b/board/nvidia/tegratab/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA TegraTab" diff --git a/board/nvidia/venice2/Kconfig b/board/nvidia/venice2/Kconfig index 9ebaa2fa413..23d9d2ae39c 100644 --- a/board/nvidia/venice2/Kconfig +++ b/board/nvidia/venice2/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA Venice2" diff --git a/board/nvidia/ventana/Kconfig b/board/nvidia/ventana/Kconfig index b8654c24e0b..ae50f36a210 100644 --- a/board/nvidia/ventana/Kconfig +++ b/board/nvidia/ventana/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "nvidia" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "NVIDIA Ventana" diff --git a/board/ouya/ouya/Kconfig b/board/ouya/ouya/Kconfig index c698f730412..24903c92bc0 100644 --- a/board/ouya/ouya/Kconfig +++ b/board/ouya/ouya/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "ouya" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "Ouya Game Console" diff --git a/board/toradex/apalis_t30/Kconfig b/board/toradex/apalis_t30/Kconfig index 6260f8eb7f4..f07fed94415 100644 --- a/board/toradex/apalis_t30/Kconfig +++ b/board/toradex/apalis_t30/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "toradex" -config SYS_CONFIG_NAME - default "tegra" - config TDX_CFG_BLOCK default y diff --git a/board/toradex/colibri_t20/Kconfig b/board/toradex/colibri_t20/Kconfig index 8a7295a41e2..c8e3a14204b 100644 --- a/board/toradex/colibri_t20/Kconfig +++ b/board/toradex/colibri_t20/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "toradex" -config SYS_CONFIG_NAME - default "tegra" - config TDX_CFG_BLOCK default y diff --git a/board/toradex/colibri_t30/Kconfig b/board/toradex/colibri_t30/Kconfig index 643309fe856..f3b7b8f6d90 100644 --- a/board/toradex/colibri_t30/Kconfig +++ b/board/toradex/colibri_t30/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "toradex" -config SYS_CONFIG_NAME - default "tegra" - config TDX_CFG_BLOCK default y diff --git a/board/wexler/qc750/Kconfig b/board/wexler/qc750/Kconfig index b449720a8b3..b53beef9eb9 100644 --- a/board/wexler/qc750/Kconfig +++ b/board/wexler/qc750/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "wexler" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "Wexler QC750" diff --git a/board/xiaomi/mocha/Kconfig b/board/xiaomi/mocha/Kconfig index 3e1e076986c..11fd84fcd40 100644 --- a/board/xiaomi/mocha/Kconfig +++ b/board/xiaomi/mocha/Kconfig @@ -6,9 +6,6 @@ config SYS_BOARD config SYS_VENDOR default "xiaomi" -config SYS_CONFIG_NAME - default "tegra" - config TEGRA_BOARD_STRING string "Default Tegra board name" default "Xiaomi Mocha" From d5b9b7aa039b03e6de4b32cc961f7ec1205ded75 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 18 Apr 2025 17:29:52 +0300 Subject: [PATCH 13/13] ARM: tegra: drop CONFIG_DISABLE_SDMMC1_EARLY This was a temporary workaround for the Tegra210 Jetson Nano board. It is not used by any device anymore, so let's remove it. Signed-off-by: Svyatoslav Ryhel --- arch/arm/mach-tegra/board2.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c index 68534dcbb22..396851c5bd8 100644 --- a/arch/arm/mach-tegra/board2.c +++ b/arch/arm/mach-tegra/board2.c @@ -227,31 +227,6 @@ int board_early_init_f(void) arch_timer_init(); #endif -#if defined(CONFIG_DISABLE_SDMMC1_EARLY) - /* - * Turn off (reset/disable) SDMMC1 on Nano here, before GPIO INIT. - * We do this because earlier bootloaders have enabled power to - * SDMMC1 on Nano, and toggling power-gpio (PZ3) in pinmux_init() - * results in power being back-driven into the SD-card and SDMMC1 - * HW, which is 'bad' as per the HW team. - * - * From the HW team: "LDO2 from the PMIC has already been set to 3.3v in - * nvtboot/CBoot on Nano (for SD-card boot). So when U-Boot's GPIO_INIT - * table sets PZ3 to OUT0 as per the pinmux spreadsheet, it turns off - * the loadswitch. When PZ3 is 0 and not driving, essentially the SDCard - * voltage turns off. Since the SDCard voltage is no longer there, the - * SDMMC CLK/DAT lines are backdriving into what essentially is a - * powered-off SDCard, that's why the voltage drops from 3.3V to ~1.6V" - * - * Note that this can probably be removed when we change over to storing - * all BL components on QSPI on Nano, and U-Boot then becomes the first - * one to turn on SDMMC1 power. Another fix would be to have CBoot - * disable power/gate SDMMC1 off before handing off to U-Boot/kernel. - */ - reset_set_enable(PERIPH_ID_SDMMC1, 1); - clock_set_enable(PERIPH_ID_SDMMC1, 0); -#endif /* CONFIG_DISABLE_SDMMC1_EARLY */ - pinmux_init(); board_init_uart_f();