From 1436fe760e6858d0ce0d8086321c0b012f990622 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20Schw=C3=B6bel?= Date: Sun, 16 Jan 2022 09:39:02 +0200 Subject: [PATCH 01/45] input: gpio-kbd: add driver for handling GPIO keyboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This driver allows use a set of GPIO buttons as input device. It may be useful for bootmenu navigation if device has GPIO based volume and power buttons (like tablets). Signed-off-by: Jonas Schwöbel Signed-off-by: Svyatoslav Ryhel --- drivers/input/Kconfig | 5 ++ drivers/input/Makefile | 1 + drivers/input/gpio-kbd.c | 140 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 drivers/input/gpio-kbd.c diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 1c534be00580..6f682efde5ec 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -91,3 +91,8 @@ config TWL4030_INPUT bool "Enable TWL4030 Input controller" help Enable TWL4030 Input controller + +config GPIO_KEYBOARD + bool "Enable GPIO based keyboard support" + help + Simple driver for keyboard where each key is controlled via one GPIO. diff --git a/drivers/input/Makefile b/drivers/input/Makefile index ded76bddb229..c56415dffd08 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -14,4 +14,5 @@ obj-$(CONFIG_I8042_KEYB) += i8042.o obj-$(CONFIG_TEGRA_KEYBOARD) += input.o tegra-kbc.o obj-$(CONFIG_TWL4030_INPUT) += twl4030.o obj-$(CONFIG_TWL6030_INPUT) += twl6030.o +obj-$(CONFIG_GPIO_KEYBOARD) += gpio-kbd.o endif diff --git a/drivers/input/gpio-kbd.c b/drivers/input/gpio-kbd.c new file mode 100644 index 000000000000..d1bd2d71e2fd --- /dev/null +++ b/drivers/input/gpio-kbd.c @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2011 + * NVIDIA Corporation + * (C) Copyright 2022 + * Jonas Schwöbel + */ + +#include +#include +#include +#include +#include +#include +#include + +struct gpio_kbd_priv { + struct input_config *input; + struct input_key *keys; + + unsigned char num_gpios; + unsigned int num_keys; +}; + +struct input_key { + struct gpio_desc gpio; + unsigned int key_code; +}; + +/** + * Check the gpio keys, and send any keys that are pressed. + * + * This is called by input_tstc() and input_getc() when they need more + * characters + * + * @param input Input configuration + * @return 1, to indicate that we have something to look at + */ +static int gpio_read_keys(struct input_config *input) +{ + struct gpio_kbd_priv *priv = dev_get_priv(input->dev); + int i; + + for (i = 0; i < priv->num_keys; i++) { + if (dm_gpio_get_value(&priv->keys[i].gpio)) + input_send_keycodes(input, &priv->keys[i].key_code, 1); + } + + return 1; +} + +static int gpio_kbd_start(struct udevice *dev) +{ + return 0; +} + +/** + * Set up the gpio keys. This is called by the stdio device handler + * + * @return 0 if ok, -ve on error + */ + +#define KBC_REPEAT_DELAY_MS 250 +#define KBC_REPEAT_RATE_MS 250 + +static int gpio_kbd_probe(struct udevice *dev) +{ + struct gpio_kbd_priv *priv = dev_get_priv(dev); + struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); + struct stdio_dev *sdev = &uc_priv->sdev; + struct input_config *input = &uc_priv->input; + ofnode node = dev_ofnode(dev); + int count = ofnode_get_child_count(node); + int ret; + + if (count < 1) { + printf("No (gpio) subnodes found\n"); + return -EINVAL; + } + + priv->keys = devm_kzalloc(dev, sizeof(struct input_key) * count, 0); + priv->num_gpios = count; + + input_set_delays(input, KBC_REPEAT_DELAY_MS, KBC_REPEAT_RATE_MS); + input_allow_repeats(input, false); + input_add_tables(input, false); + + priv->num_keys = 0; + + dev_for_each_subnode(node, dev) { + const char *label = ofnode_read_string(node, "label"); + + if (!label) { + printf("%s: node %s has no label\n", __func__, + ofnode_get_name(node)); + return -EINVAL; + } + + ofnode_read_u32(node, "linux,code", &priv->keys[priv->num_keys].key_code); + + ret = gpio_request_by_name_nodev(node, "gpios", 0, + &priv->keys[priv->num_keys].gpio, GPIOD_IS_IN); + if (ret) + printf("GPIO request error: %d\n", ret); + + priv->num_keys++; + } + + /* Register the device */ + priv->input = input; + input->dev = dev; + input->read_keys = gpio_read_keys; + strcpy(sdev->name, "gpio-kbd"); + + ret = input_stdio_register(sdev); + if (ret) { + debug("%s: input_stdio_register() failed\n", __func__); + return ret; + } + + return 0; +} + +static const struct keyboard_ops gpio_kbd_ops = { + .start = gpio_kbd_start, +}; + +static const struct udevice_id gpio_kbd_ids[] = { + { .compatible = "gpio-kbd" }, + { } +}; + +U_BOOT_DRIVER(gpio_kbd_input) = { + .name = "gpio_kbd_input", + .id = UCLASS_KEYBOARD, + .of_match = gpio_kbd_ids, + .probe = gpio_kbd_probe, + .ops = &gpio_kbd_ops, + .priv_auto = sizeof(struct gpio_kbd_priv), +}; From b05641f39ae4f5a663baa4f7ae9be9a955b77390 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Sat, 30 Jul 2022 17:01:06 +0300 Subject: [PATCH 02/45] cmd: exit: add continue on key press command Signed-off-by: Svyatoslav Ryhel --- cmd/exit.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cmd/exit.c b/cmd/exit.c index 2c7132693ad8..2e0918dcb8fc 100644 --- a/cmd/exit.c +++ b/cmd/exit.c @@ -7,6 +7,17 @@ #include #include +static int do_continue(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + while (true) { + if (tstc()) + break; + } + + return 0; +} + static int do_exit(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { @@ -16,6 +27,12 @@ static int do_exit(struct cmd_tbl *cmdtp, int flag, int argc, return 0; } +U_BOOT_CMD( + continue, 1, 0, do_continue, + "contimue script on key pressed", + "" +); + U_BOOT_CMD( exit, 2, 1, do_exit, "exit script", From ac711404e59d535523215b45c8ef2e4b293d0b12 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 16 Sep 2022 09:18:22 +0300 Subject: [PATCH 03/45] cmd: ums: abort mounting by pressing any key Signed-off-by: Svyatoslav Ryhel --- cmd/usb_mass_storage.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmd/usb_mass_storage.c b/cmd/usb_mass_storage.c index b7daaa6e8e84..df637e87a2b8 100644 --- a/cmd/usb_mass_storage.c +++ b/cmd/usb_mass_storage.c @@ -231,6 +231,13 @@ static int do_usb_mass_storage(struct cmd_tbl *cmdtp, int flag, goto cleanup_register; } + /* Abort by pressing any key */ + if (tstc()) { + puts("\rOperation aborted.\n"); + rc = CMD_RET_SUCCESS; + goto cleanup_register; + } + schedule(); } From 28e435fc79121d0c3d14de47b43a2041f437ec2f Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 19 Aug 2022 20:34:35 +0300 Subject: [PATCH 04/45] spi: tegra20_slink: accept any word length Signed-off-by: Svyatoslav Ryhel --- drivers/spi/tegra20_slink.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/spi/tegra20_slink.c b/drivers/spi/tegra20_slink.c index 209ba8b0ccf2..833733303fd5 100644 --- a/drivers/spi/tegra20_slink.c +++ b/drivers/spi/tegra20_slink.c @@ -209,15 +209,12 @@ static int tegra30_spi_xfer(struct udevice *dev, unsigned int bitlen, const u8 *dout = data_out; u8 *din = data_in; int num_bytes; - int ret; + int ret = 0; debug("%s: slave %u:%u dout %p din %p bitlen %u\n", __func__, dev_seq(bus), spi_chip_select(dev), dout, din, bitlen); - if (bitlen % 8) - return -1; - num_bytes = bitlen / 8; - ret = 0; + num_bytes = DIV_ROUND_UP(bitlen, 8); reg = readl(®s->status); writel(reg, ®s->status); /* Clear all SPI events via R/W */ @@ -255,7 +252,7 @@ static int tegra30_spi_xfer(struct udevice *dev, unsigned int bitlen, num_bytes -= bytes; clrsetbits_le32(®s->command, SLINK_CMD_BIT_LENGTH_MASK, - bytes * 8 - 1); + bitlen - 1); writel(tmpdout, ®s->tx_fifo); setbits_le32(®s->command, SLINK_CMD_GO); From efcee3c6c2b9ae6eb3cd62d0576836c2d24daa80 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 19 Aug 2022 22:59:16 +0300 Subject: [PATCH 05/45] tegra30: clock: add EXTPERIPH --- arch/arm/include/asm/arch-tegra30/clock-tables.h | 6 +++--- arch/arm/mach-tegra/tegra30/clock.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/include/asm/arch-tegra30/clock-tables.h b/arch/arm/include/asm/arch-tegra30/clock-tables.h index 8588009c61de..6c899ff64c8c 100644 --- a/arch/arm/include/asm/arch-tegra30/clock-tables.h +++ b/arch/arm/include/asm/arch-tegra30/clock-tables.h @@ -190,9 +190,9 @@ enum periph_id { PERIPH_ID_ACTMON, /* 24 */ - PERIPH_ID_EX_RESERVED24, - PERIPH_ID_EX_RESERVED25, - PERIPH_ID_EX_RESERVED26, + PERIPH_ID_EXTPERIPH1, + PERIPH_ID_EXTPERIPH2, + PERIPH_ID_EXTPERIPH3, PERIPH_ID_EX_RESERVED27, PERIPH_ID_SATA, PERIPH_ID_HDA, diff --git a/arch/arm/mach-tegra/tegra30/clock.c b/arch/arm/mach-tegra/tegra30/clock.c index c835cd0d47b1..54855d6be72e 100644 --- a/arch/arm/mach-tegra/tegra30/clock.c +++ b/arch/arm/mach-tegra/tegra30/clock.c @@ -377,9 +377,9 @@ static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { PERIPHC_ACTMON, /* 24 */ - NONE(RESERVED24), - NONE(RESERVED25), - NONE(RESERVED26), + PERIPHC_EXTPERIPH1, + PERIPHC_EXTPERIPH2, + PERIPHC_EXTPERIPH3, NONE(RESERVED27), PERIPHC_SATA, PERIPHC_HDA, From cbe480ec7ad290081e66e133111b89cf610c496c Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Tue, 28 Sep 2021 23:27:07 +0300 Subject: [PATCH 06/45] tegra: lcd: video: integrate display driver for t30 On popular request make the display driver from T20 work on T30 as well. Turned out to be quite straight forward. However a few notes about some things encountered during porting: Of course the T30 device tree was completely missing host1x as well as PWM support but it turns out this can simply be copied from T20. The only trouble compiling the Tegra video driver for T30 had to do with some hard-coded PWM pin muxing for T20 which is quite ugly anyway. On T30 this gets handled by a board specific complete pin muxing table. The older Chromium U-Boot 2011.06 which to my knowledge was the only prior attempt at enabling a display driver for T30 for whatever reason got some clocking stuff mixed up. Turns out at least for a single display controller T20 and T30 can be clocked quite similar. Enjoy. Signed-off-by: Marcel Ziswiler Signed-off-by: Svyatoslav Ryhel --- arch/arm/dts/tegra30-u-boot.dtsi | 9 +++++++ arch/arm/include/asm/arch-tegra30/display.h | 28 +++++++++++++++++++++ arch/arm/include/asm/arch-tegra30/pwm.h | 13 ++++++++++ drivers/video/tegra.c | 9 +++++-- 4 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 arch/arm/include/asm/arch-tegra30/display.h create mode 100644 arch/arm/include/asm/arch-tegra30/pwm.h diff --git a/arch/arm/dts/tegra30-u-boot.dtsi b/arch/arm/dts/tegra30-u-boot.dtsi index 7c1197255284..cf17fa803b51 100644 --- a/arch/arm/dts/tegra30-u-boot.dtsi +++ b/arch/arm/dts/tegra30-u-boot.dtsi @@ -1,3 +1,12 @@ #include #include "tegra-u-boot.dtsi" + +/ { + host1x@50000000 { + u-boot,dm-pre-reloc; + dc@54200000 { + u-boot,dm-pre-reloc; + }; + }; +}; diff --git a/arch/arm/include/asm/arch-tegra30/display.h b/arch/arm/include/asm/arch-tegra30/display.h new file mode 100644 index 000000000000..e7b3cffd4664 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/display.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2010 + * NVIDIA Corporation + */ + +#ifndef __ASM_ARCH_TEGRA_DISPLAY_H +#define __ASM_ARCH_TEGRA_DISPLAY_H + +#include + +/* This holds information about a window which can be displayed */ +struct disp_ctl_win { + enum win_color_depth_id fmt; /* Color depth/format */ + unsigned bpp; /* Bits per pixel */ + phys_addr_t phys_addr; /* Physical address in memory */ + unsigned x; /* Horizontal address offset (bytes) */ + unsigned y; /* Veritical address offset (bytes) */ + unsigned w; /* Width of source window */ + unsigned h; /* Height of source window */ + unsigned stride; /* Number of bytes per line */ + unsigned out_x; /* Left edge of output window (col) */ + unsigned out_y; /* Top edge of output window (row) */ + unsigned out_w; /* Width of output window in pixels */ + unsigned out_h; /* Height of output window in pixels */ +}; + +#endif /*__ASM_ARCH_TEGRA_DISPLAY_H*/ diff --git a/arch/arm/include/asm/arch-tegra30/pwm.h b/arch/arm/include/asm/arch-tegra30/pwm.h new file mode 100644 index 000000000000..c314e2b5ad25 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra30/pwm.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Tegra pulse width frequency modulator definitions + * + * Copyright (c) 2011 The Chromium OS Authors. + */ + +#ifndef __ASM_ARCH_TEGRA30_PWM_H +#define __ASM_ARCH_TEGRA30_PWM_H + +#include + +#endif /* __ASM_ARCH_TEGRA30_PWM_H */ diff --git a/drivers/video/tegra.c b/drivers/video/tegra.c index 3f9fcd040361..5320278bc202 100644 --- a/drivers/video/tegra.c +++ b/drivers/video/tegra.c @@ -40,8 +40,8 @@ struct tegra_lcd_priv { enum { /* Maximum LCD size we support */ - LCD_MAX_WIDTH = 1366, - LCD_MAX_HEIGHT = 768, + LCD_MAX_WIDTH = 1920, + LCD_MAX_HEIGHT = 1200, LCD_MAX_LOG2_BPP = VIDEO_BPP16, }; @@ -307,14 +307,18 @@ static int tegra_lcd_probe(struct udevice *dev) int ret; /* Initialize the Tegra display controller */ +#ifdef CONFIG_TEGRA20 funcmux_select(PERIPH_ID_DISP1, FUNCMUX_DEFAULT); +#endif if (tegra_display_probe(blob, priv, (void *)plat->base)) { printf("%s: Failed to probe display driver\n", __func__); return -1; } +#ifdef CONFIG_TEGRA20 pinmux_set_func(PMUX_PINGRP_GPU, PMUX_FUNC_PWM); pinmux_tristate_disable(PMUX_PINGRP_GPU); +#endif ret = panel_enable_backlight(priv->panel); if (ret) { @@ -414,6 +418,7 @@ static const struct video_ops tegra_lcd_ops = { static const struct udevice_id tegra_lcd_ids[] = { { .compatible = "nvidia,tegra20-dc" }, + { .compatible = "nvidia,tegra30-dc" }, { } }; From 38532b1b7db4e86e32a1b93ba060a8b7ff7fa8ac Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 12 Aug 2022 11:09:39 +0300 Subject: [PATCH 07/45] video: x3: add lm3533 backlight driver Signed-off-by: Svyatoslav Ryhel --- drivers/video/Kconfig | 2 + drivers/video/Makefile | 2 +- drivers/video/lge-x3/Kconfig | 7 ++ drivers/video/lge-x3/Makefile | 2 + drivers/video/lge-x3/lm3533_backlight.c | 153 ++++++++++++++++++++++++ 5 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 drivers/video/lge-x3/Kconfig create mode 100644 drivers/video/lge-x3/Makefile create mode 100644 drivers/video/lge-x3/lm3533_backlight.c diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index c841b99bb30d..7558818fc3a2 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -650,6 +650,8 @@ config VIDEO_TEGRA124 source "drivers/video/bridge/Kconfig" +source "drivers/video/lge-x3/Kconfig" + source "drivers/video/imx/Kconfig" config VIDEO_MXS diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 40a871d638e9..ff92d34d469f 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -26,7 +26,6 @@ obj-${CONFIG_EXYNOS_FB} += exynos/ obj-${CONFIG_VIDEO_ROCKCHIP} += rockchip/ obj-${CONFIG_VIDEO_STM32} += stm32/ obj-${CONFIG_VIDEO_TEGRA124} += tegra124/ - obj-$(CONFIG_ATMEL_HLCD) += atmel_hlcdfb.o obj-$(CONFIG_ATMEL_LCD) += atmel_lcdfb.o obj-$(CONFIG_IHS_VIDEO_OUT) += ihs_video_out.o @@ -68,3 +67,4 @@ obj-$(CONFIG_VIDEO_ZYNQMP_DPSUB) += zynqmp_dpsub.o obj-y += bridge/ obj-y += sunxi/ +obj-y += lge-x3/ diff --git a/drivers/video/lge-x3/Kconfig b/drivers/video/lge-x3/Kconfig new file mode 100644 index 000000000000..a2f0b29eae60 --- /dev/null +++ b/drivers/video/lge-x3/Kconfig @@ -0,0 +1,7 @@ +config BACKLIGHT_LM3533 + bool "Backlight Driver for LM3533" + depends on BACKLIGHT + select DM_I2C + help + Say Y to enable the backlight driver for National Semiconductor / TI + LM3533 Lighting Power chips. diff --git a/drivers/video/lge-x3/Makefile b/drivers/video/lge-x3/Makefile new file mode 100644 index 000000000000..a5044658fcdf --- /dev/null +++ b/drivers/video/lge-x3/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0+ +obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_backlight.o diff --git a/drivers/video/lge-x3/lm3533_backlight.c b/drivers/video/lge-x3/lm3533_backlight.c new file mode 100644 index 000000000000..6cf332169242 --- /dev/null +++ b/drivers/video/lge-x3/lm3533_backlight.c @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2022 Svyatoslav Ryhel + */ + +#define LOG_CATEGORY UCLASS_PANEL_BACKLIGHT + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LM3533_BL_MIN_BRIGHTNESS 0x02 +#define LM3533_BL_MAX_BRIGHTNESS 0xFF + +#define LM3533_SINK_OUTPUT_CONFIG_1 0x10 +#define LM3533_CONTROL_BANK_A_PWM 0x14 +#define LM3533_CONTROL_BANK_AB_BRIGHTNESS 0x1A +#define LM3533_CONTROL_BANK_A_FULLSCALE_CURRENT 0x1F +#define LM3533_CONTROL_BANK_ENABLE 0x27 +#define LM3533_OVP_FREQUENCY_PWM_POLARITY 0x2C +#define LM3533_BRIGHTNESS_REGISTER_A 0x40 + +struct lm3533_backlight_priv { + struct gpio_desc enable_gpio; +}; + +static int lm3533_backlight_write_reg(struct udevice *dev, u8 addr, u8 data) +{ + struct dm_i2c_chip *chip = dev_get_parent_plat(dev); + u8 buf[2]; + struct i2c_msg msg[1]; + int err; + + buf[0] = addr; + buf[1] = data; + + msg->addr = chip->chip_addr; + msg->flags = 0; + msg->len = ARRAY_SIZE(buf); + msg->buf = buf; + + err = dm_i2c_xfer(dev, msg, ARRAY_SIZE(msg)); + if (err) { + printf("%s: write failed, err = %d, addr = %#x, data = %#x\n", + __func__, err, addr, data); + return err; + } + + return 0; +} + +static int lm3533_backlight_enable(struct udevice *dev) +{ + struct lm3533_backlight_priv *priv = dev_get_priv(dev); + int ret; + + dm_gpio_set_value(&priv->enable_gpio, 1); + mdelay(5); + + /* HVLED 1 & 2 are controlled by Bank A */ + ret = lm3533_backlight_write_reg(dev, LM3533_SINK_OUTPUT_CONFIG_1, 0x00); + if (ret) + return ret; + + /* PWM input is disabled for CABC */ + ret = lm3533_backlight_write_reg(dev, LM3533_CONTROL_BANK_A_PWM, 0x00); + if (ret) + return ret; + + /* Linear & Control Bank A is configured for register Current control */ + ret = lm3533_backlight_write_reg(dev, LM3533_CONTROL_BANK_AB_BRIGHTNESS, 0x02); + if (ret) + return ret; + + /* Full-Scale Current (20.2mA) */ + ret = lm3533_backlight_write_reg(dev, LM3533_CONTROL_BANK_A_FULLSCALE_CURRENT, 0x13); + if (ret) + return ret; + + /* Control Bank A is enable */ + ret = lm3533_backlight_write_reg(dev, LM3533_CONTROL_BANK_ENABLE, 0x01); + if (ret) + return ret; + + ret = lm3533_backlight_write_reg(dev, LM3533_OVP_FREQUENCY_PWM_POLARITY, 0x0A); + if (ret) + return ret; + + + return 0; +} + +static int lm3533_backlight_set_brightness(struct udevice *dev, int percent) +{ + int ret; + + if (percent < LM3533_BL_MIN_BRIGHTNESS) + percent = LM3533_BL_MIN_BRIGHTNESS; + + if (percent > LM3533_BL_MAX_BRIGHTNESS) + percent = LM3533_BL_MAX_BRIGHTNESS; + + /* Set brightness level */ + ret = lm3533_backlight_write_reg(dev, LM3533_BRIGHTNESS_REGISTER_A, + percent); + if (ret) + return ret; + + return 0; +} + +static int lm3533_backlight_probe(struct udevice *dev) +{ + struct lm3533_backlight_priv *priv = dev_get_priv(dev); + int ret; + + if (device_get_uclass_id(dev->parent) != UCLASS_I2C) + return -EPROTONOSUPPORT; + + ret = gpio_request_by_name(dev, "enable-gpios", 0, + &priv->enable_gpio, GPIOD_IS_OUT); + if (ret) { + printf("%s: Could not decode enable-gpios (%d)\n", + __func__, ret); + return ret; + } + + return 0; +} + +static const struct backlight_ops lm3533_backlight_ops = { + .enable = lm3533_backlight_enable, + .set_brightness = lm3533_backlight_set_brightness, +}; + +static const struct udevice_id lm3533_backlight_ids[] = { + { .compatible = "ti,lm3533" }, + { } +}; + +U_BOOT_DRIVER(lm3533_backlight) = { + .name = "lm3533_backlight", + .id = UCLASS_PANEL_BACKLIGHT, + .of_match = lm3533_backlight_ids, + .probe = lm3533_backlight_probe, + .ops = &lm3533_backlight_ops, + .priv_auto = sizeof(struct lm3533_backlight_priv), +}; From 1bd4fdcf45843c1446f5c916619816a99feaafdf Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 12 Aug 2022 21:23:17 +0300 Subject: [PATCH 08/45] video: x3: add ssd2825 bridge driver Signed-off-by: Svyatoslav Ryhel --- drivers/video/lge-x3/Kconfig | 6 ++ drivers/video/lge-x3/Makefile | 1 + drivers/video/lge-x3/ssd2825.c | 119 +++++++++++++++++++++++++++++++++ drivers/video/lge-x3/ssd2825.h | 89 ++++++++++++++++++++++++ 4 files changed, 215 insertions(+) create mode 100644 drivers/video/lge-x3/ssd2825.c create mode 100644 drivers/video/lge-x3/ssd2825.h diff --git a/drivers/video/lge-x3/Kconfig b/drivers/video/lge-x3/Kconfig index a2f0b29eae60..deb8ce1b47ab 100644 --- a/drivers/video/lge-x3/Kconfig +++ b/drivers/video/lge-x3/Kconfig @@ -5,3 +5,9 @@ config BACKLIGHT_LM3533 help Say Y to enable the backlight driver for National Semiconductor / TI LM3533 Lighting Power chips. + +config BRIDGE_SOLOMON_SSD2825 + bool "Solomon SSD2825 bridge driver" + depends on PANEL && BACKLIGHT && DM_GPIO + help + Solomon SSD2824 SPI RGB-DSI bridge driver wrapped into panel uClass. diff --git a/drivers/video/lge-x3/Makefile b/drivers/video/lge-x3/Makefile index a5044658fcdf..a7657a364e4e 100644 --- a/drivers/video/lge-x3/Makefile +++ b/drivers/video/lge-x3/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0+ obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_backlight.o +obj-$(CONFIG_BRIDGE_SOLOMON_SSD2825) += ssd2825.o diff --git a/drivers/video/lge-x3/ssd2825.c b/drivers/video/lge-x3/ssd2825.c new file mode 100644 index 000000000000..26c03d932131 --- /dev/null +++ b/drivers/video/lge-x3/ssd2825.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2022 Svyatoslav Ryhel + * + * This driver is a hw bridge setup before final + * configuration in panel driver. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "ssd2825.h" + +#define LM3533_BL_DEFAULT_BRIGHTNESS 0x71 + +struct ssd2825_bridge_priv { + struct udevice *panel; + + struct gpio_desc enable_gpio; + struct gpio_desc reset_gpio; +}; + +static int ssd2825_bridge_enable_panel(struct udevice *dev) +{ + struct ssd2825_bridge_priv *priv = dev_get_priv(dev); + int ret; + + ret = dm_gpio_set_value(&priv->enable_gpio, 1); + if (ret) { + printf("%s: error changing enable-gpios (%d)\n", __func__, ret); + return ret; + } + mdelay(10); + + ret = dm_gpio_set_value(&priv->reset_gpio, 0); + if (ret) { + printf("%s: error changing reset-gpios (%d)\n", __func__, ret); + return ret; + } + mdelay(10); + + ret = dm_gpio_set_value(&priv->reset_gpio, 1); + if (ret) { + printf("%s: error changing reset-gpios (%d)\n", __func__, ret); + return ret; + } + mdelay(10); + + ret = panel_enable_backlight(priv->panel); + if (ret) + return ret; + + /* Set backlight brightness here since set_backlight may not be called */ + ret = panel_set_backlight(priv->panel, + LM3533_BL_DEFAULT_BRIGHTNESS); + if (ret) + return ret; + + return 0; +} + +static int ssd2825_bridge_set_panel(struct udevice *dev, int percent) +{ + return 0; +} + +static int ssd2825_bridge_probe(struct udevice *dev) +{ + struct ssd2825_bridge_priv *priv = dev_get_priv(dev); + int ret; + + ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev, + "panel", &priv->panel); + if (ret) { + printf("%s: Cannot get panel: ret=%d\n", __func__, ret); + return log_ret(ret); + } + + /* get panel gpios */ + ret = gpio_request_by_name(dev, "enable-gpios", 0, + &priv->enable_gpio, GPIOD_IS_OUT); + if (ret) { + printf("%s: Could not decode enable-gpios (%d)\n", __func__, ret); + return ret; + } + + ret = gpio_request_by_name(dev, "reset-gpios", 0, + &priv->reset_gpio, GPIOD_IS_OUT); + if (ret) { + printf("%s: Could not decode reset-gpios (%d)\n", __func__, ret); + return ret; + } + + return 0; +} + +static const struct panel_ops ssd2825_bridge_ops = { + .enable_backlight = ssd2825_bridge_enable_panel, + .set_backlight = ssd2825_bridge_set_panel, +}; + +static const struct udevice_id ssd2825_bridge_ids[] = { + { .compatible = "solomon,ssd2825" }, + { } +}; + +U_BOOT_DRIVER(ssd2825) = { + .name = "ssd2825", + .id = UCLASS_PANEL, + .of_match = ssd2825_bridge_ids, + .ops = &ssd2825_bridge_ops, + .probe = ssd2825_bridge_probe, + .priv_auto = sizeof(struct ssd2825_bridge_priv), +}; diff --git a/drivers/video/lge-x3/ssd2825.h b/drivers/video/lge-x3/ssd2825.h new file mode 100644 index 000000000000..827c33aad431 --- /dev/null +++ b/drivers/video/lge-x3/ssd2825.h @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _SSD2825_H_ +#define _SSD2825_H_ + +#define SSD2825_DEVICE_ID_REG 0xB0 +#define SSD2825_RGB_INTERFACE_CTRL_REG_1 0xB1 +#define SSD2825_RGB_INTERFACE_CTRL_REG_2 0xB2 +#define SSD2825_RGB_INTERFACE_CTRL_REG_3 0xB3 +#define SSD2825_RGB_INTERFACE_CTRL_REG_4 0xB4 +#define SSD2825_RGB_INTERFACE_CTRL_REG_5 0xB5 +#define SSD2825_RGB_INTERFACE_CTRL_REG_6 0xB6 +#define SSD2825_CONFIGURATION_REG 0xB7 +#define SSD2825_VC_CTRL_REG 0xB8 +#define SSD2825_PLL_CTRL_REG 0xB9 +#define SSD2825_PLL_CONFIGURATION_REG 0xBA +#define SSD2825_CLOCK_CTRL_REG 0xBB +#define SSD2825_PACKET_SIZE_CTRL_REG_1 0xBC +#define SSD2825_PACKET_SIZE_CTRL_REG_2 0xBD +#define SSD2825_PACKET_SIZE_CTRL_REG_3 0xBE +#define SSD2825_PACKET_DROP_REG 0xBF +#define SSD2825_OPERATION_CTRL_REG 0xC0 +#define SSD2825_MAX_RETURN_SIZE_REG 0xC1 +#define SSD2825_RETURN_DATA_COUNT_REG 0xC2 +#define SSD2825_ACK_RESPONSE_REG 0xC3 +#define SSD2825_LINE_CTRL_REG 0xC4 +#define SSD2825_INTERRUPT_CTRL_REG 0xC5 +#define SSD2825_INTERRUPT_STATUS_REG 0xC6 +#define SSD2825_ERROR_STATUS_REG 0xC7 +#define SSD2825_DATA_FORMAT_REG 0xC8 +#define SSD2825_DELAY_ADJ_REG_1 0xC9 +#define SSD2825_DELAY_ADJ_REG_2 0xCA +#define SSD2825_DELAY_ADJ_REG_3 0xCB +#define SSD2825_DELAY_ADJ_REG_4 0xCC +#define SSD2825_DELAY_ADJ_REG_5 0xCD +#define SSD2825_DELAY_ADJ_REG_6 0xCE +#define SSD2825_HS_TX_TIMER_REG_1 0xCF +#define SSD2825_HS_TX_TIMER_REG_2 0xD0 +#define SSD2825_LP_RX_TIMER_REG_1 0xD1 +#define SSD2825_LP_RX_TIMER_REG_2 0xD2 +#define SSD2825_TE_STATUS_REG 0xD3 +#define SSD2825_SPI_READ_REG 0xD4 +#define SSD2825_PLL_LOCK_REG 0xD5 +#define SSD2825_TEST_REG 0xD6 +#define SSD2825_TE_COUNT_REG 0xD7 +#define SSD2825_ANALOG_CTRL_REG_1 0xD8 +#define SSD2825_ANALOG_CTRL_REG_2 0xD9 +#define SSD2825_ANALOG_CTRL_REG_3 0xDA +#define SSD2825_ANALOG_CTRL_REG_4 0xDB +#define SSD2825_INTERRUPT_OUT_CTRL_REG 0xDC +#define SSD2825_RGB_INTERFACE_CTRL_REG_7 0xDD +#define SSD2825_LANE_CONFIGURATION_REG 0xDE +#define SSD2825_DELAY_ADJ_REG_7 0xDF +#define SSD2825_INPUT_PIN_CTRL_REG_1 0xE0 +#define SSD2825_INPUT_PIN_CTRL_REG_2 0xE1 +#define SSD2825_BIDIR_PIN_CTRL_REG_1 0xE2 +#define SSD2825_BIDIR_PIN_CTRL_REG_2 0xE3 +#define SSD2825_BIDIR_PIN_CTRL_REG_3 0xE4 +#define SSD2825_BIDIR_PIN_CTRL_REG_4 0xE5 +#define SSD2825_BIDIR_PIN_CTRL_REG_5 0xE6 +#define SSD2825_BIDIR_PIN_CTRL_REG_6 0xE7 +#define SSD2825_BIDIR_PIN_CTRL_REG_7 0xE8 +#define SSD2825_CABC_BRIGHTNESS_CTRL_REG_1 0xE9 +#define SSD2825_CABC_BRIGHTNESS_CTRL_REG_2 0xEA +#define SSD2825_CABC_BRIGHTNESS_STATUS_REG 0xEB +#define SSD2825_READ_REG 0xFF + +#define SSD2825_CONF_REG_HS BIT(0) // 0 - LP mode; 1 - HS mode +#define SSD2825_CONF_REG_CKE BIT(1) // 0 - Clock lane can enter LP; 1 - Clock lane will enter HS +#define SSD2825_CONF_REG_SLP BIT(2) // Sleep mode switch +#define SSD2825_CONF_REG_VEN BIT(3) // Video mode switch +#define SSD2825_CONF_REG_HCLK BIT(4) // HS clock switch +#define SSD2825_CONF_REG_CSS BIT(5) // 0 - The clock source is tx_clk; 1 - The clock source is pclk +#define SSD2825_CONF_REG_DCS BIT(6) // 0 - Generic packet in use; 1 - DCS packet in use +#define SSD2825_CONF_REG_REN BIT(7) // 0 - Write operation; 1 - Read operation +#define SSD2825_CONF_REG_ECD BIT(8) // ECC CRC Check switch +#define SSD2825_CONF_REG_EOT BIT(9) // EOT Packet send switch +#define SSD2825_CONF_REG_LPE BIT(10) // Long Packet enable switch + +#define SSD2825_SPI_READ_REG_RESET 0xFA + +#define SSD2825_CMD_SEND BIT(0) +#define SSD2825_DAT_SEND BIT(1) +#define SSD2825_DSI_SEND BIT(2) + +#define SSD2825_CMD_MASK 0x00 +#define SSD2825_DAT_MASK 0x01 + +#endif /* _SSD2825_H_ */ From ed6b75cedfdb81251af164909ce281db20bde926 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Sun, 14 Aug 2022 15:29:26 +0300 Subject: [PATCH 09/45] video: x3: add bridge spi interface Signed-off-by: Svyatoslav Ryhel --- drivers/video/lge-x3/Kconfig | 7 ++ drivers/video/lge-x3/Makefile | 1 + drivers/video/lge-x3/bridge-spi.c | 134 ++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 drivers/video/lge-x3/bridge-spi.c diff --git a/drivers/video/lge-x3/Kconfig b/drivers/video/lge-x3/Kconfig index deb8ce1b47ab..a9669d863107 100644 --- a/drivers/video/lge-x3/Kconfig +++ b/drivers/video/lge-x3/Kconfig @@ -11,3 +11,10 @@ config BRIDGE_SOLOMON_SSD2825 depends on PANEL && BACKLIGHT && DM_GPIO help Solomon SSD2824 SPI RGB-DSI bridge driver wrapped into panel uClass. + +config BRIDGE_SPI + bool "Solomon SSD2825 bridge SPI bitbang" + depends on BRIDGE_SOLOMON_SSD2825 + select DM_MISC + help + SPI bitbang emulation for setting up bridge and panel. diff --git a/drivers/video/lge-x3/Makefile b/drivers/video/lge-x3/Makefile index a7657a364e4e..93fa2c6094ff 100644 --- a/drivers/video/lge-x3/Makefile +++ b/drivers/video/lge-x3/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0+ obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_backlight.o obj-$(CONFIG_BRIDGE_SOLOMON_SSD2825) += ssd2825.o +obj-$(CONFIG_BRIDGE_SPI) += bridge-spi.o diff --git a/drivers/video/lge-x3/bridge-spi.c b/drivers/video/lge-x3/bridge-spi.c new file mode 100644 index 000000000000..71ff072881bb --- /dev/null +++ b/drivers/video/lge-x3/bridge-spi.c @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2022 Svyatoslav Ryhel + * + * SPI interface for ssd2825 bridge on t30 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ssd2825.h" + +static int bridge_spi_write(struct udevice *dev, int reg, + const void *buf, int flags) +{ + struct spi_slave *slave = dev_get_parent_priv(dev); + u8 command[2]; + + if (flags & SSD2825_CMD_SEND) { + command[0] = SSD2825_CMD_MASK; + command[1] = reg; + spi_xfer(slave, 9, &command, + NULL, SPI_XFER_ONCE); + } + + if (flags & SSD2825_DAT_SEND) { + u16 data = *(u16 *)buf; + u8 cmd1, cmd2; + + /* send low byte first and then high byte */ + cmd1 = (data & 0x00FF); + cmd2 = (data & 0xFF00) >> 8; + + command[0] = SSD2825_DAT_MASK; + command[1] = cmd1; + spi_xfer(slave, 9, &command, + NULL, SPI_XFER_ONCE); + + command[0] = SSD2825_DAT_MASK; + command[1] = cmd2; + spi_xfer(slave, 9, &command, + NULL, SPI_XFER_ONCE); + } + + if (flags & SSD2825_DSI_SEND) { + u16 data = *(u16 *)buf; + data &= 0x00FF; + + debug("%s: dsi command (0x%x)\n", + __func__, data); + + command[0] = SSD2825_DAT_MASK; + command[1] = data; + spi_xfer(slave, 9, &command, + NULL, SPI_XFER_ONCE); + } + + return 0; +} + +static int bridge_spi_read(struct udevice *dev, int reg, + void *data, int flags) +{ + struct spi_slave *slave = dev_get_parent_priv(dev); + u8 command[2]; + + command[0] = SSD2825_CMD_MASK; + command[1] = SSD2825_SPI_READ_REG; + spi_xfer(slave, 9, &command, + NULL, SPI_XFER_ONCE); + + command[0] = SSD2825_DAT_MASK; + command[1] = SSD2825_SPI_READ_REG_RESET; + spi_xfer(slave, 9, &command, + NULL, SPI_XFER_ONCE); + + command[0] = SSD2825_DAT_MASK; + command[1] = 0; + spi_xfer(slave, 9, &command, + NULL, SPI_XFER_ONCE); + + command[0] = SSD2825_CMD_MASK; + command[1] = reg; + spi_xfer(slave, 9, &command, + NULL, SPI_XFER_ONCE); + + command[0] = SSD2825_CMD_MASK; + command[1] = SSD2825_SPI_READ_REG_RESET; + spi_xfer(slave, 9, &command, + NULL, SPI_XFER_ONCE); + + spi_xfer(slave, 16, NULL, + (u8 *)data, SPI_XFER_ONCE); + + return 0; +} + +static int bridge_spi_probe(struct udevice *dev) +{ + struct spi_slave *slave = dev_get_parent_priv(dev); + int ret; + + ret = spi_claim_bus(slave); + if (ret) { + printf("%s: SPI bus allocation failed (%d)\n", __func__, ret); + return ret; + } + + return 0; +} + +static const struct misc_ops bridge_spi_ops = { + .write = bridge_spi_write, + .read = bridge_spi_read, +}; + +static const struct udevice_id bridge_spi_ids[] = { + { .compatible = "lge,bridge-spi" }, + { } +}; + +U_BOOT_DRIVER(bridge_spi) = { + .name = "bridge_spi", + .id = UCLASS_MISC, + .of_match = bridge_spi_ids, + .ops = &bridge_spi_ops, + .probe = bridge_spi_probe, +}; From d27140172a5f68d39417a4056c59d078e40de27a Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Sun, 14 Aug 2022 15:30:18 +0300 Subject: [PATCH 10/45] video: x3: add KOE (Hitachi) TX13D100VM0EAA panel support Signed-off-by: Svyatoslav Ryhel --- drivers/video/lge-x3/Kconfig | 8 + drivers/video/lge-x3/Makefile | 1 + drivers/video/lge-x3/koe-tx13d100vm0eaa.c | 261 ++++++++++++++++++++++ 3 files changed, 270 insertions(+) create mode 100644 drivers/video/lge-x3/koe-tx13d100vm0eaa.c diff --git a/drivers/video/lge-x3/Kconfig b/drivers/video/lge-x3/Kconfig index a9669d863107..fc4ba79d5100 100644 --- a/drivers/video/lge-x3/Kconfig +++ b/drivers/video/lge-x3/Kconfig @@ -18,3 +18,11 @@ config BRIDGE_SPI select DM_MISC help SPI bitbang emulation for setting up bridge and panel. + +config PANEL_KOE_TX13D100VM0EAA + bool "Hitachi KOE TX13D100VM0EAA DSI panel driver" + depends on BRIDGE_SOLOMON_SSD2825 + select BRIDGE_SPI + help + Hitachi KOE TX13D100VM0EAA DSI panel setup with panel specific bridge + configuration. Use only with Solomon SSD2825 spi bridge. diff --git a/drivers/video/lge-x3/Makefile b/drivers/video/lge-x3/Makefile index 93fa2c6094ff..3418ac70ffea 100644 --- a/drivers/video/lge-x3/Makefile +++ b/drivers/video/lge-x3/Makefile @@ -2,3 +2,4 @@ obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_backlight.o obj-$(CONFIG_BRIDGE_SOLOMON_SSD2825) += ssd2825.o obj-$(CONFIG_BRIDGE_SPI) += bridge-spi.o +obj-$(CONFIG_PANEL_KOE_TX13D100VM0EAA) += koe-tx13d100vm0eaa.o diff --git a/drivers/video/lge-x3/koe-tx13d100vm0eaa.c b/drivers/video/lge-x3/koe-tx13d100vm0eaa.c new file mode 100644 index 000000000000..7d85821a269f --- /dev/null +++ b/drivers/video/lge-x3/koe-tx13d100vm0eaa.c @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2022 Svyatoslav Ryhel + * + * Panel specific configuration of bridge and panel itself. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ssd2825.h" + +struct koe_panel_priv { + struct udevice *vcc; + struct udevice *iovcc; + + struct udevice *backlight; + struct udevice *spi; + + struct gpio_desc reset_gpio; +}; + +#define MIPI_DCS_MCAP_ON 0x03B0 +#define MIPI_DCS_MCAP_OFF 0x04B0 + +static const u8 dig_contrast[] = { + 0xCC, 0xDC, 0xB4, 0xFF +}; + +static const u8 gamma_curve_3[] = { + 0xC8, 0x0B, 0x0D, 0x10, 0x14, + 0x13, 0x1D, 0x20, 0x18, 0x12, + 0x09, 0x07, 0x06, 0x0A, 0x0C, + 0x10, 0x14, 0x13, 0x1D, 0x20, + 0x18, 0x12, 0x09, 0x07, 0x06 +}; + +static const u8 column_inversion[] = { + 0xC1, 0x00, 0x50, 0x03, 0x22, + 0x16, 0x06, 0x60, 0x11 +}; + +static void write_hw_register(struct koe_panel_priv *priv, u8 reg, + u16 command) +{ + misc_write(priv->spi, reg, &command, SSD2825_CMD_SEND | SSD2825_DAT_SEND); +} + +static void write_hw_dsi(struct koe_panel_priv *priv, const u8 *command, + int len) +{ + int i; + + misc_write(priv->spi, SSD2825_PACKET_SIZE_CTRL_REG_1, &len, + SSD2825_CMD_SEND | SSD2825_DAT_SEND); + + misc_write(priv->spi, SSD2825_PACKET_DROP_REG, NULL, + SSD2825_CMD_SEND); + + for (i = 0; i < len; i++) { + misc_write(priv->spi, 0, &command[i], SSD2825_DSI_SEND); + } +} + +static int koe_panel_enable_backlight(struct udevice *dev) +{ + struct koe_panel_priv *priv = dev_get_priv(dev); + int ret; + + ret = regulator_set_enable_if_allowed(priv->vcc, 1); + if (ret) { + printf("%s: error enabling vcc-supply (%d)\n", __func__, ret); + return ret; + } + mdelay(5); + + ret = regulator_set_enable_if_allowed(priv->iovcc, 1); + if (ret) { + printf("%s: error enabling iovcc-supply (%d)\n", __func__, ret); + return ret; + } + + ret = dm_gpio_set_value(&priv->reset_gpio, 0); + if (ret) { + printf("%s: error changing reset-gpios (%d)\n", __func__, ret); + return ret; + } + mdelay(5); + + ret = dm_gpio_set_value(&priv->reset_gpio, 1); + if (ret) { + printf("%s: error changing reset-gpios (%d)\n", __func__, ret); + return ret; + } + + mdelay(5); + + /* Bridge configuration */ + write_hw_register(priv, SSD2825_RGB_INTERFACE_CTRL_REG_1, 0x0205); + write_hw_register(priv, SSD2825_RGB_INTERFACE_CTRL_REG_2, 0x0A56); + write_hw_register(priv, SSD2825_RGB_INTERFACE_CTRL_REG_3, 0x1874); + write_hw_register(priv, SSD2825_RGB_INTERFACE_CTRL_REG_4, 0x0300); + write_hw_register(priv, SSD2825_RGB_INTERFACE_CTRL_REG_5, 0x0400); + write_hw_register(priv, SSD2825_RGB_INTERFACE_CTRL_REG_6, 0xE007); + write_hw_register(priv, SSD2825_LANE_CONFIGURATION_REG, 0x0003); + write_hw_register(priv, SSD2825_TEST_REG, 0x0004); + + write_hw_register(priv, SSD2825_PLL_CTRL_REG, 0x0000); + write_hw_register(priv, SSD2825_LINE_CTRL_REG, 0x0001); + write_hw_register(priv, SSD2825_DELAY_ADJ_REG_1, 0x2103); + write_hw_register(priv, SSD2825_PLL_CONFIGURATION_REG, 0x8CD7); + write_hw_register(priv, SSD2825_CLOCK_CTRL_REG, 0x0009); + write_hw_register(priv, SSD2825_PLL_CTRL_REG, 0x0001); + write_hw_register(priv, SSD2825_VC_CTRL_REG, 0x0000); + + mdelay(10); + + /* Panel configuration */ + write_hw_register(priv, SSD2825_CONFIGURATION_REG, + SSD2825_CONF_REG_CKE | SSD2825_CONF_REG_DCS | + SSD2825_CONF_REG_ECD | SSD2825_CONF_REG_EOT); + write_hw_register(priv, SSD2825_VC_CTRL_REG, 0x0000); + + write_hw_register(priv, SSD2825_PACKET_SIZE_CTRL_REG_1, 0x0002); + write_hw_register(priv, SSD2825_PACKET_DROP_REG, + 0x00FF & MIPI_DCS_EXIT_SLEEP_MODE); + mdelay(80); + + write_hw_register(priv, SSD2825_PACKET_SIZE_CTRL_REG_1, 0x0002); + write_hw_register(priv, SSD2825_PACKET_DROP_REG, + 0x00FF & MIPI_DCS_SET_ADDRESS_MODE); + mdelay(20); + + write_hw_register(priv, SSD2825_PACKET_SIZE_CTRL_REG_1, 0x0002); + write_hw_register(priv, SSD2825_PACKET_DROP_REG, + (MIPI_DCS_PIXEL_FMT_24BIT << 12) & + MIPI_DCS_SET_PIXEL_FORMAT); + + write_hw_register(priv, SSD2825_CONFIGURATION_REG, + SSD2825_CONF_REG_CKE | SSD2825_CONF_REG_ECD | + SSD2825_CONF_REG_EOT); + write_hw_register(priv, SSD2825_VC_CTRL_REG, 0x0000); + + write_hw_register(priv, SSD2825_PACKET_SIZE_CTRL_REG_1, 0x0002); + write_hw_register(priv, SSD2825_PACKET_DROP_REG, MIPI_DCS_MCAP_OFF); + + write_hw_dsi(priv, dig_contrast, sizeof(dig_contrast)); + write_hw_dsi(priv, gamma_curve_3, sizeof(gamma_curve_3)); + write_hw_dsi(priv, column_inversion, sizeof(column_inversion)); + + write_hw_register(priv, SSD2825_PACKET_SIZE_CTRL_REG_1, 0x0002); + write_hw_register(priv, SSD2825_PACKET_DROP_REG, MIPI_DCS_MCAP_ON); + + write_hw_register(priv, SSD2825_CONFIGURATION_REG, + SSD2825_CONF_REG_CKE | SSD2825_CONF_REG_DCS | + SSD2825_CONF_REG_ECD | SSD2825_CONF_REG_EOT); + write_hw_register(priv, SSD2825_VC_CTRL_REG, 0x0000); + + write_hw_register(priv, SSD2825_PACKET_SIZE_CTRL_REG_1, 0x0002); + write_hw_register(priv, SSD2825_PACKET_DROP_REG, + 0x00FF & MIPI_DCS_SET_DISPLAY_ON); + mdelay(10); + + write_hw_register(priv, SSD2825_PLL_CTRL_REG, 0x0001); + write_hw_register(priv, SSD2825_VC_CTRL_REG, 0x0000); + + write_hw_register(priv, SSD2825_CONFIGURATION_REG, + SSD2825_CONF_REG_HS | SSD2825_CONF_REG_VEN | + SSD2825_CONF_REG_DCS | SSD2825_CONF_REG_ECD | + SSD2825_CONF_REG_EOT); + + ret = backlight_enable(priv->backlight); + if (ret) + return ret; + + return 0; +} + +static int koe_panel_set_backlight(struct udevice *dev, int percent) +{ + struct koe_panel_priv *priv = dev_get_priv(dev); + int ret; + + ret = backlight_set_brightness(priv->backlight, percent); + if (ret) + return ret; + + return 0; +} + +static int koe_panel_probe(struct udevice *dev) +{ + struct koe_panel_priv *priv = dev_get_priv(dev); + int ret; + + ret = uclass_get_device_by_phandle(UCLASS_MISC, dev, + "bridge-spi", &priv->spi); + if (ret) { + printf("%s: Cannot get bridge-spi: ret = %d\n", __func__, ret); + return ret; + } + + ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev, + "backlight", &priv->backlight); + if (ret) { + printf("%s: Cannot get backlight: ret = %d\n", __func__, ret); + return ret; + } + + ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, + "vcc-supply", &priv->vcc); + if (ret) { + printf("%s: Cannot get vcc-supply: ret = %d\n", __func__, ret); + return ret; + } + + ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev, + "iovcc-supply", &priv->iovcc); + if (ret) { + printf("%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) { + printf("%s: Could not decode reser-gpios (%d)\n", __func__, ret); + return ret; + } + + return 0; +} + +static const struct panel_ops koe_panel_ops = { + .enable_backlight = koe_panel_enable_backlight, + .set_backlight = koe_panel_set_backlight, +}; + +static const struct udevice_id koe_panel_ids[] = { + { .compatible = "koe,tx13d100vm0eaa" }, + { .compatible = "hitachi,tx13d100vm0eaa" }, + { } +}; + +U_BOOT_DRIVER(koe_tx13d100vm0eaa) = { + .name = "koe_tx13d100vm0eaa", + .id = UCLASS_PANEL, + .of_match = koe_panel_ids, + .ops = &koe_panel_ops, + .probe = koe_panel_probe, + .priv_auto = sizeof(struct koe_panel_priv), +}; From 021ebb5dab0f505e96cc9520fded6a7a721227fe Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Sun, 14 Aug 2022 21:00:32 +0300 Subject: [PATCH 11/45] video: x3: add Renesas R69328 panel support Signed-off-by: Svyatoslav Ryhel --- drivers/video/lge-x3/Kconfig | 8 + drivers/video/lge-x3/Makefile | 1 + drivers/video/lge-x3/renesas-r69328.c | 264 ++++++++++++++++++++++++++ 3 files changed, 273 insertions(+) create mode 100644 drivers/video/lge-x3/renesas-r69328.c diff --git a/drivers/video/lge-x3/Kconfig b/drivers/video/lge-x3/Kconfig index fc4ba79d5100..59377d98d75c 100644 --- a/drivers/video/lge-x3/Kconfig +++ b/drivers/video/lge-x3/Kconfig @@ -26,3 +26,11 @@ config PANEL_KOE_TX13D100VM0EAA help Hitachi KOE TX13D100VM0EAA DSI panel setup with panel specific bridge configuration. Use only with Solomon SSD2825 spi bridge. + +config PANEL_RENESAS_R69328 + bool "Renesas R69328 DSI panel driver" + depends on BRIDGE_SOLOMON_SSD2825 + select BRIDGE_SPI + help + Renesas R69328 DSI panel setup with panel specific bridge configuration. + Use only with Solomon SSD2825 spi bridge for LG Optimux 4X HD. diff --git a/drivers/video/lge-x3/Makefile b/drivers/video/lge-x3/Makefile index 3418ac70ffea..21ea17d13851 100644 --- a/drivers/video/lge-x3/Makefile +++ b/drivers/video/lge-x3/Makefile @@ -3,3 +3,4 @@ obj-$(CONFIG_BACKLIGHT_LM3533) += lm3533_backlight.o obj-$(CONFIG_BRIDGE_SOLOMON_SSD2825) += ssd2825.o obj-$(CONFIG_BRIDGE_SPI) += bridge-spi.o obj-$(CONFIG_PANEL_KOE_TX13D100VM0EAA) += koe-tx13d100vm0eaa.o +obj-$(CONFIG_PANEL_RENESAS_R69328) += renesas-r69328.o diff --git a/drivers/video/lge-x3/renesas-r69328.c b/drivers/video/lge-x3/renesas-r69328.c new file mode 100644 index 000000000000..167481f9d730 --- /dev/null +++ b/drivers/video/lge-x3/renesas-r69328.c @@ -0,0 +1,264 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2022 Svyatoslav Ryhel + * + * Panel specific configuration of bridge and panel itself. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ssd2825.h" + +struct renesas_r69328_priv { + struct udevice *backlight; + struct udevice *spi; + + struct gpio_desc enable_gpio; + struct gpio_desc reset_gpio; +}; + +#define MIPI_DCS_MCAP_ON 0x03B0 +#define MIPI_DCS_MCAP_OFF 0x04B0 + +static const u8 power_set[] = { + 0xD1, 0x14, 0x1D, 0x21, 0x67, + 0x11, 0x9A +}; + +static const u8 gamma_setting_a[] = { + 0xC8, 0x00, 0x1A, 0x20, 0x28, + 0x25, 0x24, 0x26, 0x15, 0x13, + 0x11, 0x18, 0x1E, 0x1C, 0x00, + 0x00, 0x1A, 0x20, 0x28, 0x25, + 0x24, 0x26, 0x15, 0x13, 0x11, + 0x18, 0x1E, 0x1C, 0x00 +}; + +static const u8 gamma_setting_b[] = { + 0xC9, 0x00, 0x1A, 0x20, 0x28, + 0x25, 0x24, 0x26, 0x15, 0x13, + 0x11, 0x18, 0x1E, 0x1C, 0x00, + 0x00, 0x1A, 0x20, 0x28, 0x25, + 0x24, 0x26, 0x15, 0x13, 0x11, + 0x18, 0x1E, 0x1C, 0x00 +}; + +static const u8 gamma_setting_c[] = { + 0xCA, 0x00, 0x1A, 0x20, 0x28, + 0x25, 0x24, 0x26, 0x15, 0x13, + 0x11, 0x18, 0x1E, 0x1C, 0x00, + 0x00, 0x1A, 0x20, 0x28, 0x25, + 0x24, 0x26, 0x15, 0x13, 0x11, + 0x18, 0x1E, 0x1C, 0x00 +}; + +static void write_hw_register(struct renesas_r69328_priv *priv, u8 reg, + u16 command) +{ + misc_write(priv->spi, reg, &command, SSD2825_CMD_SEND | SSD2825_DAT_SEND); +} + +static void write_hw_dsi(struct renesas_r69328_priv *priv, const u8 *command, + int len) +{ + int i; + + misc_write(priv->spi, SSD2825_PACKET_SIZE_CTRL_REG_1, &len, + SSD2825_CMD_SEND | SSD2825_DAT_SEND); + + misc_write(priv->spi, SSD2825_PACKET_DROP_REG, NULL, + SSD2825_CMD_SEND); + + for (i = 0; i < len; i++) { + misc_write(priv->spi, 0, &command[i], SSD2825_DSI_SEND); + } +} + +static int renesas_r69328_enable_backlight(struct udevice *dev) +{ + struct renesas_r69328_priv *priv = dev_get_priv(dev); + int ret; + + ret = dm_gpio_set_value(&priv->enable_gpio, 1); + if (ret) { + printf("%s: error changing enable-gpios (%d)\n", __func__, ret); + return ret; + } + mdelay(5); + + ret = dm_gpio_set_value(&priv->reset_gpio, 0); + if (ret) { + printf("%s: error changing reset-gpios (%d)\n", __func__, ret); + return ret; + } + mdelay(5); + + ret = dm_gpio_set_value(&priv->reset_gpio, 1); + if (ret) { + printf("%s: error changing reset-gpios (%d)\n", __func__, ret); + return ret; + } + + mdelay(5); + + /* Bridge configuration */ + write_hw_register(priv, SSD2825_RGB_INTERFACE_CTRL_REG_1, 0x0104); + write_hw_register(priv, SSD2825_RGB_INTERFACE_CTRL_REG_2, 0x0442); + write_hw_register(priv, SSD2825_RGB_INTERFACE_CTRL_REG_3, 0x065C); + write_hw_register(priv, SSD2825_RGB_INTERFACE_CTRL_REG_4, 0x02D0); + write_hw_register(priv, SSD2825_RGB_INTERFACE_CTRL_REG_5, 0x0500); + write_hw_register(priv, SSD2825_RGB_INTERFACE_CTRL_REG_6, 0xE007); + write_hw_register(priv, SSD2825_LANE_CONFIGURATION_REG, 0x0003); + write_hw_register(priv, SSD2825_TEST_REG, 0x0004); + + write_hw_register(priv, SSD2825_PLL_CTRL_REG, 0x0000); + write_hw_register(priv, SSD2825_LINE_CTRL_REG, 0x0001); + write_hw_register(priv, SSD2825_DELAY_ADJ_REG_1, 0x2103); + write_hw_register(priv, SSD2825_PLL_CONFIGURATION_REG, 0xC8AB); + write_hw_register(priv, SSD2825_CLOCK_CTRL_REG, 0x0009); + write_hw_register(priv, SSD2825_PLL_CTRL_REG, 0x0001); + write_hw_register(priv, SSD2825_VC_CTRL_REG, 0x0000); + + /* Panel configuration */ + write_hw_register(priv, SSD2825_CONFIGURATION_REG, + SSD2825_CONF_REG_CKE | SSD2825_CONF_REG_ECD | + SSD2825_CONF_REG_EOT); + write_hw_register(priv, SSD2825_VC_CTRL_REG, 0x0000); + + write_hw_register(priv, SSD2825_PACKET_SIZE_CTRL_REG_1, 0x0002); + write_hw_register(priv, SSD2825_PACKET_DROP_REG, + 0x00FF & MIPI_DCS_SET_ADDRESS_MODE); + + write_hw_register(priv, SSD2825_PACKET_SIZE_CTRL_REG_1, 0x0002); + write_hw_register(priv, SSD2825_PACKET_DROP_REG, + (MIPI_DCS_PIXEL_FMT_24BIT << 12) & + MIPI_DCS_SET_PIXEL_FORMAT); + + write_hw_register(priv, SSD2825_CONFIGURATION_REG, + SSD2825_CONF_REG_CKE | SSD2825_CONF_REG_DCS | + SSD2825_CONF_REG_ECD | SSD2825_CONF_REG_EOT); + write_hw_register(priv, SSD2825_VC_CTRL_REG, 0x0000); + + write_hw_register(priv, SSD2825_PACKET_SIZE_CTRL_REG_1, 0x0002); + write_hw_register(priv, SSD2825_PACKET_DROP_REG, + 0x00FF & MIPI_DCS_EXIT_SLEEP_MODE); + mdelay(80); + + write_hw_register(priv, SSD2825_CONFIGURATION_REG, + SSD2825_CONF_REG_CKE | SSD2825_CONF_REG_ECD | + SSD2825_CONF_REG_EOT); + write_hw_register(priv, SSD2825_VC_CTRL_REG, 0x0000); + + write_hw_register(priv, SSD2825_PACKET_SIZE_CTRL_REG_1, 0x0002); + write_hw_register(priv, SSD2825_PACKET_DROP_REG, MIPI_DCS_MCAP_OFF); + + write_hw_dsi(priv, power_set, sizeof(power_set)); + write_hw_dsi(priv, gamma_setting_a, sizeof(gamma_setting_a)); + write_hw_dsi(priv, gamma_setting_b, sizeof(gamma_setting_b)); + write_hw_dsi(priv, gamma_setting_c, sizeof(gamma_setting_c)); + + write_hw_register(priv, SSD2825_PACKET_SIZE_CTRL_REG_1, 0x0002); + write_hw_register(priv, SSD2825_PACKET_DROP_REG, MIPI_DCS_MCAP_ON); + + write_hw_register(priv, SSD2825_CONFIGURATION_REG, + SSD2825_CONF_REG_CKE | SSD2825_CONF_REG_DCS | + SSD2825_CONF_REG_ECD | SSD2825_CONF_REG_EOT); + write_hw_register(priv, SSD2825_VC_CTRL_REG, 0x0000); + + write_hw_register(priv, SSD2825_PACKET_SIZE_CTRL_REG_1, 0x0002); + write_hw_register(priv, SSD2825_PACKET_DROP_REG, + 0x00FF & MIPI_DCS_SET_DISPLAY_ON); + mdelay(50); + + write_hw_register(priv, SSD2825_PLL_CONFIGURATION_REG, 0xC8AB); + write_hw_register(priv, SSD2825_CLOCK_CTRL_REG, 0x0009); + write_hw_register(priv, SSD2825_PLL_CTRL_REG, 0x0001); + write_hw_register(priv, SSD2825_VC_CTRL_REG, 0x0000); + + write_hw_register(priv, SSD2825_CONFIGURATION_REG, + SSD2825_CONF_REG_HS | SSD2825_CONF_REG_VEN | + SSD2825_CONF_REG_ECD | SSD2825_CONF_REG_EOT); + + ret = backlight_enable(priv->backlight); + if (ret) + return ret; + + return 0; +} + +static int renesas_r69328_set_backlight(struct udevice *dev, int percent) +{ + struct renesas_r69328_priv *priv = dev_get_priv(dev); + int ret; + + ret = backlight_set_brightness(priv->backlight, percent); + if (ret) + return ret; + + return 0; +} + +static int renesas_r69328_probe(struct udevice *dev) +{ + struct renesas_r69328_priv *priv = dev_get_priv(dev); + int ret; + + ret = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev, + "backlight", &priv->backlight); + if (ret) { + printf("%s: Cannot get backlight: ret = %d\n", __func__, ret); + return ret; + } + + ret = uclass_get_device_by_phandle(UCLASS_MISC, dev, + "bridge-spi", &priv->spi); + if (ret) { + debug("%s: Cannot get bridge-spi: ret = %d\n", __func__, ret); + return ret; + } + + ret = gpio_request_by_name(dev, "enable-gpios", 0, + &priv->enable_gpio, GPIOD_IS_OUT); + if (ret) { + printf("%s: Could not decode enable-gpios (%d)\n", __func__, ret); + return ret; + } + + ret = gpio_request_by_name(dev, "reset-gpios", 0, + &priv->reset_gpio, GPIOD_IS_OUT); + if (ret) { + printf("%s: Could not decode reser-gpios (%d)\n", __func__, ret); + return ret; + } + + return 0; +} + +static const struct panel_ops renesas_r69328_ops = { + .enable_backlight = renesas_r69328_enable_backlight, + .set_backlight = renesas_r69328_set_backlight, +}; + +static const struct udevice_id renesas_r69328_ids[] = { + { .compatible = "jdi,dx12d100vm0eaa" }, + { } +}; + +U_BOOT_DRIVER(renesas_r69328) = { + .name = "renesas_r69328", + .id = UCLASS_PANEL, + .of_match = renesas_r69328_ids, + .ops = &renesas_r69328_ops, + .probe = renesas_r69328_probe, + .priv_auto = sizeof(struct renesas_r69328_priv), +}; From dcc05c784e3ec4c6fdd300d031eb1d9ef26ee2f3 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Tue, 23 Aug 2022 19:51:29 +0300 Subject: [PATCH 12/45] misc: extcon: add MAX14526 MUIC support Signed-off-by: Svyatoslav Ryhel --- drivers/misc/Kconfig | 2 + drivers/misc/Makefile | 1 + drivers/misc/extcon/Kconfig | 8 ++ drivers/misc/extcon/Makefile | 2 + drivers/misc/extcon/extcon-max14526.c | 157 ++++++++++++++++++++++++++ 5 files changed, 170 insertions(+) create mode 100644 drivers/misc/extcon/Kconfig create mode 100644 drivers/misc/extcon/Makefile create mode 100644 drivers/misc/extcon/extcon-max14526.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index a6da6e215dec..b5c6a492d9f7 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -645,4 +645,6 @@ config SL28CPLD the base driver which provides common access methods for the sub-drivers. +source "drivers/misc/extcon/Kconfig" + endmenu diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index d494639cd950..ebc132bd02df 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -89,3 +89,4 @@ obj-$(CONFIG_K3_AVS0) += k3_avs.o obj-$(CONFIG_ESM_K3) += k3_esm.o obj-$(CONFIG_ESM_PMIC) += esm_pmic.o obj-$(CONFIG_SL28CPLD) += sl28cpld.o +obj-y += extcon/ diff --git a/drivers/misc/extcon/Kconfig b/drivers/misc/extcon/Kconfig new file mode 100644 index 000000000000..99c38224f3bb --- /dev/null +++ b/drivers/misc/extcon/Kconfig @@ -0,0 +1,8 @@ +config EXTCON_MAX14526 + bool "Maxim MAX14526 EXTCON Support" + select DM_I2C + select DM_MISC + help + If you say yes here you get support for the MUIC device of + Maxim MAX14526. The MAX14526 MUIC is a USB port accessory + detector and switch. diff --git a/drivers/misc/extcon/Makefile b/drivers/misc/extcon/Makefile new file mode 100644 index 000000000000..f012b688cea6 --- /dev/null +++ b/drivers/misc/extcon/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0+ +obj-$(CONFIG_EXTCON_MAX14526) += extcon-max14526.o diff --git a/drivers/misc/extcon/extcon-max14526.c b/drivers/misc/extcon/extcon-max14526.c new file mode 100644 index 000000000000..e984cc9e7d17 --- /dev/null +++ b/drivers/misc/extcon/extcon-max14526.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2022 Svyatoslav Ryhel + * + * U-boot lacks extcon DM. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define CONTROL_1 0x01 +#define SW_CONTROL 0x03 + +#define ID_200 0x10 +#define ADC_EN 0x02 +#define CP_EN 0x01 + +#define DP_USB 0x00 +#define DP_UART 0x08 +#define DP_AUDIO 0x10 +#define DP_OPEN 0x38 + +#define DM_USB 0x00 +#define DM_UART 0x01 +#define DM_AUDIO 0x02 +#define DM_OPEN 0x07 + +#define AP_USB BIT(0) +#define CP_USB BIT(1) +#define CP_UART BIT(2) + +struct max14526_priv { + struct gpio_desc usif_gpio; + struct gpio_desc dp2t_gpio; + struct gpio_desc ifx_usb_vbus_gpio; +}; + +static void max14526_set_mode(struct udevice *dev, int mode) +{ + struct max14526_priv *priv = dev_get_priv(dev); + uchar val; + int ret; + + if ((mode & AP_USB) || (mode & CP_USB)) { + /* Connect CP UART signals to AP */ + ret = dm_gpio_set_value(&priv->usif_gpio, 0); + if (ret) + printf("%s: error changing usif-gpio (%d)\n", __func__, ret); + } + + if (mode & CP_UART) { + /* Connect CP UART signals to DP2T */ + ret = dm_gpio_set_value(&priv->usif_gpio, 1); + if (ret) + printf("%s: error changing usif-gpio (%d)\n", __func__, ret); + } + + if (mode & CP_USB) { + /* Connect CP USB to MUIC UART */ + ret = dm_gpio_set_value(&priv->ifx_usb_vbus_gpio, 1); + if (ret) + printf("%s: error changing usb-vbus-gpio (%d)\n", __func__, ret); + + ret = dm_gpio_set_value(&priv->dp2t_gpio, 1); + if (ret) + printf("%s: error changing dp2t-gpio (%d)\n", __func__, ret); + } + + if ((mode & AP_USB) || (mode & CP_UART)) { + /* Connect CP UART to MUIC UART */ + ret = dm_gpio_set_value(&priv->dp2t_gpio, 0); + if (ret) + printf("%s: error changing dp2t-gpio (%d)\n", __func__, ret); + } + + if (mode & AP_USB) { + /* Enables USB Path */ + val = DP_USB | DM_USB; + ret = dm_i2c_write(dev, SW_CONTROL, &val, 1); + if (ret) + printf("USB Path set failed: %d\n", ret); + } + + if ((mode & CP_USB) || (mode & CP_UART)) { + /* Enables UART Path */ + val = DP_UART | DM_UART; + ret = dm_i2c_write(dev, SW_CONTROL, &val, 1); + if (ret) + printf("USB Path set failed: %d\n", ret); + } + + /* Enables 200K, Charger Pump, and ADC */ + val = ID_200 | ADC_EN | CP_EN; + ret = dm_i2c_write(dev, CONTROL_1, &val, 1); + if (ret) + printf("200K, Charger Pump, and ADC set failed: %d\n", ret); +} + +static int max14526_probe(struct udevice *dev) +{ + struct max14526_priv *priv = dev_get_priv(dev); + int ret, mode = 0; + + ret = gpio_request_by_name(dev, "usif-gpios", 0, + &priv->usif_gpio, GPIOD_IS_OUT); + if (ret) { + printf("%s: Could not decode usif-gpios (%d)\n", __func__, ret); + return ret; + } + + ret = gpio_request_by_name(dev, "dp2t-gpios", 0, + &priv->dp2t_gpio, GPIOD_IS_OUT); + if (ret) { + printf("%s: Could not decode dp2t-gpios (%d)\n", __func__, ret); + return ret; + } + + if (dev_read_bool(dev, "maxim,ap-usb")) + mode |= AP_USB; + + if (dev_read_bool(dev, "maxim,cp-usb")) { + mode |= CP_USB; + + ret = gpio_request_by_name(dev, "usb-vbus-gpios", 0, + &priv->ifx_usb_vbus_gpio, GPIOD_IS_OUT); + if (ret) { + printf("%s: Could not decode dp2t-gpios (%d)\n", __func__, ret); + return ret; + } + } + + if (dev_read_bool(dev, "maxim,cp-uart")) + mode |= CP_UART; + + max14526_set_mode(dev, mode); + + return 0; +} + +static const struct udevice_id max14526_ids[] = { + { .compatible = "maxim,max14526-muic" }, + { } +}; + +U_BOOT_DRIVER(extcon_max14526) = { + .name = "extcon_max14526", + .id = UCLASS_MISC, + .of_match = max14526_ids, + .probe = max14526_probe, + .priv_auto = sizeof(struct max14526_priv), +}; From 9cb34aeba5f9377d40dc7bb2c7d395d9faf15bb0 Mon Sep 17 00:00:00 2001 From: Maxim Schwalm Date: Sun, 23 Jan 2022 22:55:33 +0100 Subject: [PATCH 13/45] tegra: provide default USB gadget setup All Nvidia boards use the same manufacturer, vendor ID and product ID for the gadgets. Make them the defaults to remove some boilerplate from the defconfigs. Inspired by commit e02687bda96c ("sunxi: provide default USB gadget setup") which did the same for Allwinner boards. Signed-off-by: Maxim Schwalm --- configs/beaver_defconfig | 3 --- configs/cei-tk1-som_defconfig | 3 --- configs/dalmore_defconfig | 3 --- configs/jetson-tk1_defconfig | 3 --- configs/nyan-big_defconfig | 3 --- configs/p2371-0000_defconfig | 3 --- configs/p2371-2180_defconfig | 3 --- configs/p2571_defconfig | 3 --- configs/p3450-0000_defconfig | 3 --- configs/venice2_defconfig | 3 --- drivers/usb/gadget/Kconfig | 3 +++ 11 files changed, 3 insertions(+), 30 deletions(-) diff --git a/configs/beaver_defconfig b/configs/beaver_defconfig index 0967367e6a7d..693ccb893ded 100644 --- a/configs/beaver_defconfig +++ b/configs/beaver_defconfig @@ -64,8 +64,5 @@ CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MANUFACTURER="NVIDIA" -CONFIG_USB_GADGET_VENDOR_NUM=0x0955 -CONFIG_USB_GADGET_PRODUCT_NUM=0x701a CONFIG_CI_UDC=y CONFIG_USB_GADGET_DOWNLOAD=y diff --git a/configs/cei-tk1-som_defconfig b/configs/cei-tk1-som_defconfig index 58d75a52a08d..14a712abca4a 100644 --- a/configs/cei-tk1-som_defconfig +++ b/configs/cei-tk1-som_defconfig @@ -69,8 +69,5 @@ CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MANUFACTURER="NVIDIA" -CONFIG_USB_GADGET_VENDOR_NUM=0x0955 -CONFIG_USB_GADGET_PRODUCT_NUM=0x701a CONFIG_CI_UDC=y CONFIG_USB_GADGET_DOWNLOAD=y diff --git a/configs/dalmore_defconfig b/configs/dalmore_defconfig index cc46f4eda419..956a8a47665b 100644 --- a/configs/dalmore_defconfig +++ b/configs/dalmore_defconfig @@ -59,8 +59,5 @@ CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MANUFACTURER="NVIDIA" -CONFIG_USB_GADGET_VENDOR_NUM=0x0955 -CONFIG_USB_GADGET_PRODUCT_NUM=0x701a CONFIG_CI_UDC=y CONFIG_USB_GADGET_DOWNLOAD=y diff --git a/configs/jetson-tk1_defconfig b/configs/jetson-tk1_defconfig index b391a86c0225..7689ceb330df 100644 --- a/configs/jetson-tk1_defconfig +++ b/configs/jetson-tk1_defconfig @@ -69,8 +69,5 @@ CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MANUFACTURER="NVIDIA" -CONFIG_USB_GADGET_VENDOR_NUM=0x0955 -CONFIG_USB_GADGET_PRODUCT_NUM=0x701a CONFIG_CI_UDC=y CONFIG_USB_GADGET_DOWNLOAD=y diff --git a/configs/nyan-big_defconfig b/configs/nyan-big_defconfig index e2e8bebf6d1a..fef9141d35f7 100644 --- a/configs/nyan-big_defconfig +++ b/configs/nyan-big_defconfig @@ -93,9 +93,6 @@ CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MANUFACTURER="NVIDIA" -CONFIG_USB_GADGET_VENDOR_NUM=0x0955 -CONFIG_USB_GADGET_PRODUCT_NUM=0x701a CONFIG_CI_UDC=y CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_VIDEO=y diff --git a/configs/p2371-0000_defconfig b/configs/p2371-0000_defconfig index e8074914c8a0..2962a7db75a2 100644 --- a/configs/p2371-0000_defconfig +++ b/configs/p2371-0000_defconfig @@ -48,8 +48,5 @@ CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MANUFACTURER="NVIDIA" -CONFIG_USB_GADGET_VENDOR_NUM=0x0955 -CONFIG_USB_GADGET_PRODUCT_NUM=0x701a CONFIG_CI_UDC=y CONFIG_USB_GADGET_DOWNLOAD=y diff --git a/configs/p2371-2180_defconfig b/configs/p2371-2180_defconfig index ea62e18f7384..6b44361b5b08 100644 --- a/configs/p2371-2180_defconfig +++ b/configs/p2371-2180_defconfig @@ -57,8 +57,5 @@ CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MANUFACTURER="NVIDIA" -CONFIG_USB_GADGET_VENDOR_NUM=0x0955 -CONFIG_USB_GADGET_PRODUCT_NUM=0x701a CONFIG_CI_UDC=y CONFIG_USB_GADGET_DOWNLOAD=y diff --git a/configs/p2571_defconfig b/configs/p2571_defconfig index bc3fb3e5ae37..00b0dc6109e6 100644 --- a/configs/p2571_defconfig +++ b/configs/p2571_defconfig @@ -49,8 +49,5 @@ CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MANUFACTURER="NVIDIA" -CONFIG_USB_GADGET_VENDOR_NUM=0x0955 -CONFIG_USB_GADGET_PRODUCT_NUM=0x701a CONFIG_CI_UDC=y CONFIG_USB_GADGET_DOWNLOAD=y diff --git a/configs/p3450-0000_defconfig b/configs/p3450-0000_defconfig index 8e16afde9135..d35bea422044 100644 --- a/configs/p3450-0000_defconfig +++ b/configs/p3450-0000_defconfig @@ -61,8 +61,5 @@ CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MANUFACTURER="NVIDIA" -CONFIG_USB_GADGET_VENDOR_NUM=0x0955 -CONFIG_USB_GADGET_PRODUCT_NUM=0x701a CONFIG_CI_UDC=y CONFIG_USB_GADGET_DOWNLOAD=y diff --git a/configs/venice2_defconfig b/configs/venice2_defconfig index a754c2004698..fe794b76fff4 100644 --- a/configs/venice2_defconfig +++ b/configs/venice2_defconfig @@ -59,8 +59,5 @@ CONFIG_USB_EHCI_TEGRA=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_GADGET=y -CONFIG_USB_GADGET_MANUFACTURER="NVIDIA" -CONFIG_USB_GADGET_VENDOR_NUM=0x0955 -CONFIG_USB_GADGET_PRODUCT_NUM=0x701a CONFIG_CI_UDC=y CONFIG_USB_GADGET_DOWNLOAD=y diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index e8da73c78869..37594d5132e4 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -40,6 +40,7 @@ if USB_GADGET config USB_GADGET_MANUFACTURER string "Vendor name of the USB device" + default "NVIDIA" if ARCH_TEGRA default "Allwinner Technology" if ARCH_SUNXI default "Rockchip" if ARCH_ROCKCHIP default "U-Boot" @@ -49,6 +50,7 @@ config USB_GADGET_MANUFACTURER config USB_GADGET_VENDOR_NUM hex "Vendor ID of the USB device" + default 0x0955 if ARCH_TEGRA default 0x1f3a if ARCH_SUNXI default 0x2207 if ARCH_ROCKCHIP default 0x0 @@ -59,6 +61,7 @@ config USB_GADGET_VENDOR_NUM config USB_GADGET_PRODUCT_NUM hex "Product ID of the USB device" + default 0x701a if ARCH_TEGRA default 0x1010 if ARCH_SUNXI default 0x310a if ROCKCHIP_RK3036 default 0x300a if ROCKCHIP_RK3066 From 27d0743136664ac25846d267ec7b50f4d600719d Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Tue, 18 Oct 2022 19:03:44 +0300 Subject: [PATCH 14/45] ARM: tegra: add late init support Signed-off-by: Svyatoslav Ryhel --- arch/arm/include/asm/arch-tegra/sys_proto.h | 6 ++++++ arch/arm/mach-tegra/board2.c | 2 ++ 2 files changed, 8 insertions(+) diff --git a/arch/arm/include/asm/arch-tegra/sys_proto.h b/arch/arm/include/asm/arch-tegra/sys_proto.h index c3a2673e6c3c..566666a9a052 100644 --- a/arch/arm/include/asm/arch-tegra/sys_proto.h +++ b/arch/arm/include/asm/arch-tegra/sys_proto.h @@ -31,4 +31,10 @@ int tegra_lcd_pmic_init(int board_id); */ int nvidia_board_init(void); +/** + * nvidia_board_late_init() - perform any board-specific + * init on late stages + */ +void nvidia_board_late_init(void); + #endif diff --git a/arch/arm/mach-tegra/board2.c b/arch/arm/mach-tegra/board2.c index 82d3d3350284..5e24761ecfb5 100644 --- a/arch/arm/mach-tegra/board2.c +++ b/arch/arm/mach-tegra/board2.c @@ -56,6 +56,7 @@ __weak void gpio_early_init_uart(void) {} __weak void pin_mux_display(void) {} __weak void start_cpu_fan(void) {} __weak void cboot_late_init(void) {} +__weak void nvidia_board_late_init(void) {} #if defined(CONFIG_TEGRA_NAND) __weak void pin_mux_nand(void) @@ -267,6 +268,7 @@ int board_late_init(void) #endif start_cpu_fan(); cboot_late_init(); + nvidia_board_late_init(); return 0; } From 8a4b9764d974893760584e381eb2091f98149e2b Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Mon, 7 Nov 2022 10:13:53 +0200 Subject: [PATCH 15/45] ARM: tegra: create common pre-dm i2c write Signed-off-by: Svyatoslav Ryhel --- arch/arm/include/asm/arch-tegra/tegra_spl.h | 34 +++++++++++++++++++++ arch/arm/mach-tegra/cpu.h | 1 - arch/arm/mach-tegra/tegra124/cpu.c | 4 +++ arch/arm/mach-tegra/tegra30/cpu.c | 23 +++----------- 4 files changed, 43 insertions(+), 19 deletions(-) create mode 100644 arch/arm/include/asm/arch-tegra/tegra_spl.h diff --git a/arch/arm/include/asm/arch-tegra/tegra_spl.h b/arch/arm/include/asm/arch-tegra/tegra_spl.h new file mode 100644 index 000000000000..07c966147be9 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra/tegra_spl.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2022 Svyatoslav Ryhel + * (C) Copyright 2010 - 2011 NVIDIA Corporation + */ + +#ifndef _TEGRA_SPL_H_ +#define _TEGRA_SPL_H_ + +#include +#include + +#define I2C_SEND_2_BYTES 0x0A02 + +/* Pre-dm way to work with i2c */ +static inline void tegra_i2c_ll_write_addr(uint addr, uint config) +{ + struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; + + writel(addr, ®->cmd_addr0); + writel(config, ®->cnfg); +} + +static inline void tegra_i2c_ll_write_data(uint data, uint config) +{ + struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; + + writel(data, ®->cmd_data1); + writel(config, ®->cnfg); +} + +void pmic_enable_cpu_vdd(void); + +#endif /* _TEGRA_SPL_H_ */ diff --git a/arch/arm/mach-tegra/cpu.h b/arch/arm/mach-tegra/cpu.h index d541825441a3..006aae3d0705 100644 --- a/arch/arm/mach-tegra/cpu.h +++ b/arch/arm/mach-tegra/cpu.h @@ -74,4 +74,3 @@ int tegra_get_chip(void); int tegra_get_sku_info(void); int tegra_get_chip_sku(void); void adjust_pllp_out_freqs(void); -void pmic_enable_cpu_vdd(void); diff --git a/arch/arm/mach-tegra/tegra124/cpu.c b/arch/arm/mach-tegra/tegra124/cpu.c index d5f2683b266c..b03f3f937f9e 100644 --- a/arch/arm/mach-tegra/tegra124/cpu.c +++ b/arch/arm/mach-tegra/tegra124/cpu.c @@ -14,10 +14,14 @@ #include #include #include +#include #include #include #include "../cpu.h" +/* In case this function is not defined */ +__weak void pmic_enable_cpu_vdd(void) {} + /* Tegra124-specific CPU init code */ static void enable_cpu_power_rail(void) diff --git a/arch/arm/mach-tegra/tegra30/cpu.c b/arch/arm/mach-tegra/tegra30/cpu.c index 651edd27ee87..6dda73e5e8f8 100644 --- a/arch/arm/mach-tegra/tegra30/cpu.c +++ b/arch/arm/mach-tegra/tegra30/cpu.c @@ -12,26 +12,10 @@ #include #include #include +#include #include #include "../cpu.h" -/* Tegra30-specific CPU init code */ -void tegra_i2c_ll_write_addr(uint addr, uint config) -{ - struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; - - writel(addr, ®->cmd_addr0); - writel(config, ®->cnfg); -} - -void tegra_i2c_ll_write_data(uint data, uint config) -{ - struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; - - writel(data, ®->cmd_data1); - writel(config, ®->cnfg); -} - #define TPS62366A_I2C_ADDR 0xC0 #define TPS62366A_SET1_REG 0x01 #define TPS62366A_SET1_DATA (0x4600 | TPS62366A_SET1_REG) @@ -45,7 +29,9 @@ void tegra_i2c_ll_write_data(uint data, uint config) #define TPS65911_VDDCTRL_SR_REG 0x27 #define TPS65911_VDDCTRL_OP_DATA (0x2400 | TPS65911_VDDCTRL_OP_REG) #define TPS65911_VDDCTRL_SR_DATA (0x0100 | TPS65911_VDDCTRL_SR_REG) -#define I2C_SEND_2_BYTES 0x0A02 + +/* In case this function is not defined */ +__weak void pmic_enable_cpu_vdd(void) {} static void enable_cpu_power_rail(void) { @@ -142,6 +128,7 @@ void start_cpu(u32 reset_vector) /* Enable VDD_CPU */ enable_cpu_power_rail(); + pmic_enable_cpu_vdd(); set_cpu_running(0); From 71b9076391e8bc995db3f4aed4edb6a257a56441 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Mon, 7 Nov 2022 10:15:58 +0200 Subject: [PATCH 16/45] board: tegra210: use pre-dm i2c write Signed-off-by: Svyatoslav Ryhel --- board/nvidia/venice2/as3722_init.c | 46 ++++++++++++++++++-------- board/nvidia/venice2/as3722_init.h | 43 ------------------------ board/toradex/apalis-tk1/as3722_init.c | 44 ++++++++++++++++-------- board/toradex/apalis-tk1/as3722_init.h | 40 ---------------------- 4 files changed, 62 insertions(+), 111 deletions(-) delete mode 100644 board/nvidia/venice2/as3722_init.h delete mode 100644 board/toradex/apalis-tk1/as3722_init.h diff --git a/board/nvidia/venice2/as3722_init.c b/board/nvidia/venice2/as3722_init.c index ba676547d3ec..c90470721397 100644 --- a/board/nvidia/venice2/as3722_init.c +++ b/board/nvidia/venice2/as3722_init.c @@ -8,26 +8,44 @@ #include #include #include +#include #include -#include "as3722_init.h" -/* AS3722-PMIC-specific early init code - get CPU rails up, etc */ +/* AS3722-PMIC-specific early init regs */ -void tegra_i2c_ll_write_addr(uint addr, uint config) -{ - struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; +#define AS3722_I2C_ADDR 0x80 - writel(addr, ®->cmd_addr0); - writel(config, ®->cnfg); -} +#define AS3722_SD0VOLTAGE_REG 0x00 /* CPU */ +#define AS3722_SD1VOLTAGE_REG 0x01 /* CORE, already set by OTP */ +#define AS3722_SD6VOLTAGE_REG 0x06 /* GPU */ +#define AS3722_SDCONTROL_REG 0x4D -void tegra_i2c_ll_write_data(uint data, uint config) -{ - struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; +#define AS3722_LDO2VOLTAGE_REG 0x12 /* VPP_FUSE */ +#define AS3722_LDO6VOLTAGE_REG 0x16 /* VDD_SDMMC */ +#define AS3722_LDCONTROL_REG 0x4E - writel(data, ®->cmd_data1); - writel(config, ®->cnfg); -} +#if defined(CONFIG_TARGET_VENICE2) +#define AS3722_SD0VOLTAGE_DATA (0x2800 | AS3722_SD0VOLTAGE_REG) +#else /* TK1 or Nyan-Big */ +#define AS3722_SD0VOLTAGE_DATA (0x3C00 | AS3722_SD0VOLTAGE_REG) +#endif +#define AS3722_SD0CONTROL_DATA (0x0100 | AS3722_SDCONTROL_REG) + +#if defined(CONFIG_TARGET_JETSON_TK1) || defined(CONFIG_TARGET_CEI_TK1_SOM) +#define AS3722_SD1VOLTAGE_DATA (0x2800 | AS3722_SD1VOLTAGE_REG) +#define AS3722_SD1CONTROL_DATA (0x0200 | AS3722_SDCONTROL_REG) +#endif + +#define AS3722_SD6CONTROL_DATA (0x4000 | AS3722_SDCONTROL_REG) +#define AS3722_SD6VOLTAGE_DATA (0x2800 | AS3722_SD6VOLTAGE_REG) + +#define AS3722_LDO2CONTROL_DATA (0x0400 | AS3722_LDCONTROL_REG) +#define AS3722_LDO2VOLTAGE_DATA (0x1000 | AS3722_LDO2VOLTAGE_REG) + +#define AS3722_LDO6CONTROL_DATA (0x4000 | AS3722_LDCONTROL_REG) +#define AS3722_LDO6VOLTAGE_DATA (0x3F00 | AS3722_LDO6VOLTAGE_REG) + +/* AS3722-PMIC-specific early init code - get CPU rails up, etc */ void pmic_enable_cpu_vdd(void) { diff --git a/board/nvidia/venice2/as3722_init.h b/board/nvidia/venice2/as3722_init.h deleted file mode 100644 index 17e7d76ae7aa..000000000000 --- a/board/nvidia/venice2/as3722_init.h +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * (C) Copyright 2013 - * NVIDIA Corporation - */ - -/* AS3722-PMIC-specific early init regs */ - -#define AS3722_I2C_ADDR 0x80 - -#define AS3722_SD0VOLTAGE_REG 0x00 /* CPU */ -#define AS3722_SD1VOLTAGE_REG 0x01 /* CORE, already set by OTP */ -#define AS3722_SD6VOLTAGE_REG 0x06 /* GPU */ -#define AS3722_SDCONTROL_REG 0x4D - -#define AS3722_LDO2VOLTAGE_REG 0x12 /* VPP_FUSE */ -#define AS3722_LDO6VOLTAGE_REG 0x16 /* VDD_SDMMC */ -#define AS3722_LDCONTROL_REG 0x4E - -#if defined(CONFIG_TARGET_VENICE2) -#define AS3722_SD0VOLTAGE_DATA (0x2800 | AS3722_SD0VOLTAGE_REG) -#else /* TK1 or Nyan-Big */ -#define AS3722_SD0VOLTAGE_DATA (0x3C00 | AS3722_SD0VOLTAGE_REG) -#endif -#define AS3722_SD0CONTROL_DATA (0x0100 | AS3722_SDCONTROL_REG) - -#if defined(CONFIG_TARGET_JETSON_TK1) || defined(CONFIG_TARGET_CEI_TK1_SOM) -#define AS3722_SD1VOLTAGE_DATA (0x2800 | AS3722_SD1VOLTAGE_REG) -#define AS3722_SD1CONTROL_DATA (0x0200 | AS3722_SDCONTROL_REG) -#endif - -#define AS3722_SD6CONTROL_DATA (0x4000 | AS3722_SDCONTROL_REG) -#define AS3722_SD6VOLTAGE_DATA (0x2800 | AS3722_SD6VOLTAGE_REG) - -#define AS3722_LDO2CONTROL_DATA (0x0400 | AS3722_LDCONTROL_REG) -#define AS3722_LDO2VOLTAGE_DATA (0x1000 | AS3722_LDO2VOLTAGE_REG) - -#define AS3722_LDO6CONTROL_DATA (0x4000 | AS3722_LDCONTROL_REG) -#define AS3722_LDO6VOLTAGE_DATA (0x3F00 | AS3722_LDO6VOLTAGE_REG) - -#define I2C_SEND_2_BYTES 0x0A02 - -void pmic_enable_cpu_vdd(void); diff --git a/board/toradex/apalis-tk1/as3722_init.c b/board/toradex/apalis-tk1/as3722_init.c index 68169f554808..4cf4699c7b9c 100644 --- a/board/toradex/apalis-tk1/as3722_init.c +++ b/board/toradex/apalis-tk1/as3722_init.c @@ -7,26 +7,42 @@ #include #include #include +#include #include -#include "as3722_init.h" -/* AS3722-PMIC-specific early init code - get CPU rails up, etc */ +/* AS3722-PMIC-specific early init regs */ -void tegra_i2c_ll_write_addr(uint addr, uint config) -{ - struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; +#define AS3722_I2C_ADDR 0x80 - writel(addr, ®->cmd_addr0); - writel(config, ®->cnfg); -} +#define AS3722_SD0VOLTAGE_REG 0x00 /* CPU */ +#define AS3722_SD1VOLTAGE_REG 0x01 /* CORE, already set by OTP */ +#define AS3722_SD6VOLTAGE_REG 0x06 /* GPU */ +#define AS3722_SDCONTROL_REG 0x4D -void tegra_i2c_ll_write_data(uint data, uint config) -{ - struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; +#define AS3722_LDO1VOLTAGE_REG 0x11 /* VDD_SDMMC1 */ +#define AS3722_LDO2VOLTAGE_REG 0x12 /* VPP_FUSE */ +#define AS3722_LDO6VOLTAGE_REG 0x16 /* VDD_SDMMC3 */ +#define AS3722_LDCONTROL_REG 0x4E - writel(data, ®->cmd_data1); - writel(config, ®->cnfg); -} +#define AS3722_SD0VOLTAGE_DATA (0x3C00 | AS3722_SD0VOLTAGE_REG) +#define AS3722_SD0CONTROL_DATA (0x0100 | AS3722_SDCONTROL_REG) + +#define AS3722_SD1VOLTAGE_DATA (0x3200 | AS3722_SD1VOLTAGE_REG) +#define AS3722_SD1CONTROL_DATA (0x0200 | AS3722_SDCONTROL_REG) + +#define AS3722_SD6CONTROL_DATA (0x4000 | AS3722_SDCONTROL_REG) +#define AS3722_SD6VOLTAGE_DATA (0x2800 | AS3722_SD6VOLTAGE_REG) + +#define AS3722_LDO1CONTROL_DATA (0x0200 | AS3722_LDCONTROL_REG) +#define AS3722_LDO1VOLTAGE_DATA (0x7F00 | AS3722_LDO1VOLTAGE_REG) + +#define AS3722_LDO2CONTROL_DATA (0x0400 | AS3722_LDCONTROL_REG) +#define AS3722_LDO2VOLTAGE_DATA (0x1000 | AS3722_LDO2VOLTAGE_REG) + +#define AS3722_LDO6CONTROL_DATA (0x4000 | AS3722_LDCONTROL_REG) +#define AS3722_LDO6VOLTAGE_DATA (0x3F00 | AS3722_LDO6VOLTAGE_REG) + +/* AS3722-PMIC-specific early init code - get CPU rails up, etc */ void pmic_enable_cpu_vdd(void) { diff --git a/board/toradex/apalis-tk1/as3722_init.h b/board/toradex/apalis-tk1/as3722_init.h deleted file mode 100644 index 99836de96623..000000000000 --- a/board/toradex/apalis-tk1/as3722_init.h +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 2012-2016 Toradex, Inc. - */ - -/* AS3722-PMIC-specific early init regs */ - -#define AS3722_I2C_ADDR 0x80 - -#define AS3722_SD0VOLTAGE_REG 0x00 /* CPU */ -#define AS3722_SD1VOLTAGE_REG 0x01 /* CORE, already set by OTP */ -#define AS3722_SD6VOLTAGE_REG 0x06 /* GPU */ -#define AS3722_SDCONTROL_REG 0x4D - -#define AS3722_LDO1VOLTAGE_REG 0x11 /* VDD_SDMMC1 */ -#define AS3722_LDO2VOLTAGE_REG 0x12 /* VPP_FUSE */ -#define AS3722_LDO6VOLTAGE_REG 0x16 /* VDD_SDMMC3 */ -#define AS3722_LDCONTROL_REG 0x4E - -#define AS3722_SD0VOLTAGE_DATA (0x3C00 | AS3722_SD0VOLTAGE_REG) -#define AS3722_SD0CONTROL_DATA (0x0100 | AS3722_SDCONTROL_REG) - -#define AS3722_SD1VOLTAGE_DATA (0x3200 | AS3722_SD1VOLTAGE_REG) -#define AS3722_SD1CONTROL_DATA (0x0200 | AS3722_SDCONTROL_REG) - -#define AS3722_SD6CONTROL_DATA (0x4000 | AS3722_SDCONTROL_REG) -#define AS3722_SD6VOLTAGE_DATA (0x2800 | AS3722_SD6VOLTAGE_REG) - -#define AS3722_LDO1CONTROL_DATA (0x0200 | AS3722_LDCONTROL_REG) -#define AS3722_LDO1VOLTAGE_DATA (0x7F00 | AS3722_LDO1VOLTAGE_REG) - -#define AS3722_LDO2CONTROL_DATA (0x0400 | AS3722_LDCONTROL_REG) -#define AS3722_LDO2VOLTAGE_DATA (0x1000 | AS3722_LDO2VOLTAGE_REG) - -#define AS3722_LDO6CONTROL_DATA (0x4000 | AS3722_LDCONTROL_REG) -#define AS3722_LDO6VOLTAGE_DATA (0x3F00 | AS3722_LDO6VOLTAGE_REG) - -#define I2C_SEND_2_BYTES 0x0A02 - -void pmic_enable_cpu_vdd(void); From 42651320b58d6dbcfd8bbf63507b030862acfdd6 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Mon, 7 Nov 2022 10:16:14 +0200 Subject: [PATCH 17/45] board: tegra30: use pre-dm i2c write Signed-off-by: Svyatoslav Ryhel --- arch/arm/mach-tegra/tegra30/cpu.c | 35 ----------------- board/avionic-design/tec-ng/Makefile | 4 +- board/avionic-design/tec-ng/tec-ng-spl.c | 33 ++++++++++++++++ board/nvidia/beaver/Makefile | 2 + board/nvidia/beaver/beaver-spl.c | 42 +++++++++++++++++++++ board/nvidia/cardhu/Makefile | 4 +- board/nvidia/cardhu/cardhu-spl.c | 42 +++++++++++++++++++++ board/toradex/apalis_t30/Makefile | 2 + board/toradex/apalis_t30/apalis_t30-spl.c | 33 ++++++++++++++++ board/toradex/colibri_t30/Makefile | 2 + board/toradex/colibri_t30/colibri_t30-spl.c | 33 ++++++++++++++++ include/configs/beaver.h | 3 -- include/configs/cardhu.h | 3 -- scripts/config_whitelist.txt | 2 - 14 files changed, 195 insertions(+), 45 deletions(-) create mode 100644 board/avionic-design/tec-ng/tec-ng-spl.c create mode 100644 board/nvidia/beaver/beaver-spl.c create mode 100644 board/nvidia/cardhu/cardhu-spl.c create mode 100644 board/toradex/apalis_t30/apalis_t30-spl.c create mode 100644 board/toradex/colibri_t30/colibri_t30-spl.c diff --git a/arch/arm/mach-tegra/tegra30/cpu.c b/arch/arm/mach-tegra/tegra30/cpu.c index 6dda73e5e8f8..aa84f505c872 100644 --- a/arch/arm/mach-tegra/tegra30/cpu.c +++ b/arch/arm/mach-tegra/tegra30/cpu.c @@ -16,20 +16,6 @@ #include #include "../cpu.h" -#define TPS62366A_I2C_ADDR 0xC0 -#define TPS62366A_SET1_REG 0x01 -#define TPS62366A_SET1_DATA (0x4600 | TPS62366A_SET1_REG) - -#define TPS62361B_I2C_ADDR 0xC0 -#define TPS62361B_SET3_REG 0x03 -#define TPS62361B_SET3_DATA (0x4600 | TPS62361B_SET3_REG) - -#define TPS65911_I2C_ADDR 0x5A -#define TPS65911_VDDCTRL_OP_REG 0x28 -#define TPS65911_VDDCTRL_SR_REG 0x27 -#define TPS65911_VDDCTRL_OP_DATA (0x2400 | TPS65911_VDDCTRL_OP_REG) -#define TPS65911_VDDCTRL_SR_DATA (0x0100 | TPS65911_VDDCTRL_SR_REG) - /* In case this function is not defined */ __weak void pmic_enable_cpu_vdd(void) {} @@ -42,27 +28,6 @@ static void enable_cpu_power_rail(void) reg = readl(&pmc->pmc_cntrl); reg |= CPUPWRREQ_OE; writel(reg, &pmc->pmc_cntrl); - - /* Set VDD_CORE to 1.200V. */ -#ifdef CONFIG_TEGRA_VDD_CORE_TPS62366A_SET1 - tegra_i2c_ll_write_addr(TPS62366A_I2C_ADDR, 2); - tegra_i2c_ll_write_data(TPS62366A_SET1_DATA, I2C_SEND_2_BYTES); -#endif -#ifdef CONFIG_TEGRA_VDD_CORE_TPS62361B_SET3 - tegra_i2c_ll_write_addr(TPS62361B_I2C_ADDR, 2); - tegra_i2c_ll_write_data(TPS62361B_SET3_DATA, I2C_SEND_2_BYTES); -#endif - udelay(1000); - - /* - * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus. - * First set VDD to 1.0125V, then enable the VDD regulator. - */ - tegra_i2c_ll_write_addr(TPS65911_I2C_ADDR, 2); - tegra_i2c_ll_write_data(TPS65911_VDDCTRL_OP_DATA, I2C_SEND_2_BYTES); - udelay(1000); - tegra_i2c_ll_write_data(TPS65911_VDDCTRL_SR_DATA, I2C_SEND_2_BYTES); - udelay(10 * 1000); } /** diff --git a/board/avionic-design/tec-ng/Makefile b/board/avionic-design/tec-ng/Makefile index 46df14d991c5..d6890e5797fd 100644 --- a/board/avionic-design/tec-ng/Makefile +++ b/board/avionic-design/tec-ng/Makefile @@ -3,4 +3,6 @@ # (C) Copyright 2013 # Avionic Design GmbH -obj-y := ../common/tamonten-ng.o +obj-$(CONFIG_SPL_BUILD) += tec-ng-spl.o + +obj-y += ../common/tamonten-ng.o diff --git a/board/avionic-design/tec-ng/tec-ng-spl.c b/board/avionic-design/tec-ng/tec-ng-spl.c new file mode 100644 index 000000000000..c56dc7d10537 --- /dev/null +++ b/board/avionic-design/tec-ng/tec-ng-spl.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2010-2013 + * NVIDIA Corporation + * + * (C) Copyright 2021 + * Svyatoslav Ryhel + */ + +#include +#include +#include + +/* I2C addr is in 8 bit */ +#define TPS65911_I2C_ADDR 0x5A +#define TPS65911_VDDCTRL_OP_REG 0x28 +#define TPS65911_VDDCTRL_SR_REG 0x27 +#define TPS65911_VDDCTRL_OP_DATA (0x2400 | TPS65911_VDDCTRL_OP_REG) +#define TPS65911_VDDCTRL_SR_DATA (0x0100 | TPS65911_VDDCTRL_SR_REG) + +void pmic_enable_cpu_vdd(void) +{ + /* + * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus. + * First set VDD to 1.0125V, then enable the VDD regulator. + */ + udelay(1000); + tegra_i2c_ll_write_addr(TPS65911_I2C_ADDR, 2); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_OP_DATA, I2C_SEND_2_BYTES); + udelay(1000); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_SR_DATA, I2C_SEND_2_BYTES); + udelay(10 * 1000); +} diff --git a/board/nvidia/beaver/Makefile b/board/nvidia/beaver/Makefile index 80cff3eb9ccb..5e9e70825c76 100644 --- a/board/nvidia/beaver/Makefile +++ b/board/nvidia/beaver/Makefile @@ -2,4 +2,6 @@ # # Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. +obj-$(CONFIG_SPL_BUILD) += beaver-spl.o + obj-y = ../cardhu/cardhu.o diff --git a/board/nvidia/beaver/beaver-spl.c b/board/nvidia/beaver/beaver-spl.c new file mode 100644 index 000000000000..863e054c566c --- /dev/null +++ b/board/nvidia/beaver/beaver-spl.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2010-2013 + * NVIDIA Corporation + * + * (C) Copyright 2021 + * Svyatoslav Ryhel + */ + +#include +#include +#include + +/* I2C addr is in 8 bit */ +#define TPS65911_I2C_ADDR 0x5A +#define TPS65911_VDDCTRL_OP_REG 0x28 +#define TPS65911_VDDCTRL_SR_REG 0x27 +#define TPS65911_VDDCTRL_OP_DATA (0x2400 | TPS65911_VDDCTRL_OP_REG) +#define TPS65911_VDDCTRL_SR_DATA (0x0100 | TPS65911_VDDCTRL_SR_REG) + +#define TPS62366A_I2C_ADDR 0xC0 +#define TPS62366A_SET1_REG 0x01 +#define TPS62366A_SET1_DATA (0x4600 | TPS62366A_SET1_REG) + +void pmic_enable_cpu_vdd(void) +{ + /* Set VDD_CORE to 1.200V. */ + tegra_i2c_ll_write_addr(TPS62366A_I2C_ADDR, 2); + tegra_i2c_ll_write_data(TPS62366A_SET1_DATA, I2C_SEND_2_BYTES); + + udelay(1000); + + /* + * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus. + * First set VDD to 1.0125V, then enable the VDD regulator. + */ + tegra_i2c_ll_write_addr(TPS65911_I2C_ADDR, 2); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_OP_DATA, I2C_SEND_2_BYTES); + udelay(1000); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_SR_DATA, I2C_SEND_2_BYTES); + udelay(10 * 1000); +} diff --git a/board/nvidia/cardhu/Makefile b/board/nvidia/cardhu/Makefile index 95971053d9b4..6f480cdfd3be 100644 --- a/board/nvidia/cardhu/Makefile +++ b/board/nvidia/cardhu/Makefile @@ -3,4 +3,6 @@ # (C) Copyright 2010-2012 # NVIDIA Corporation -obj-y := cardhu.o +obj-$(CONFIG_SPL_BUILD) += cardhu-spl.o + +obj-y += cardhu.o diff --git a/board/nvidia/cardhu/cardhu-spl.c b/board/nvidia/cardhu/cardhu-spl.c new file mode 100644 index 000000000000..a72bba669403 --- /dev/null +++ b/board/nvidia/cardhu/cardhu-spl.c @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2010-2013 + * NVIDIA Corporation + * + * (C) Copyright 2021 + * Svyatoslav Ryhel + */ + +#include +#include +#include + +/* I2C addr is in 8 bit */ +#define TPS65911_I2C_ADDR 0x5A +#define TPS65911_VDDCTRL_OP_REG 0x28 +#define TPS65911_VDDCTRL_SR_REG 0x27 +#define TPS65911_VDDCTRL_OP_DATA (0x2400 | TPS65911_VDDCTRL_OP_REG) +#define TPS65911_VDDCTRL_SR_DATA (0x0100 | TPS65911_VDDCTRL_SR_REG) + +#define TPS62361B_I2C_ADDR 0xC0 +#define TPS62361B_SET3_REG 0x03 +#define TPS62361B_SET3_DATA (0x4600 | TPS62361B_SET3_REG) + +void pmic_enable_cpu_vdd(void) +{ + /* Set VDD_CORE to 1.200V. */ + tegra_i2c_ll_write_addr(TPS62361B_I2C_ADDR, 2); + tegra_i2c_ll_write_data(TPS62361B_SET3_DATA, I2C_SEND_2_BYTES); + + udelay(1000); + + /* + * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus. + * First set VDD to 1.0125V, then enable the VDD regulator. + */ + tegra_i2c_ll_write_addr(TPS65911_I2C_ADDR, 2); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_OP_DATA, I2C_SEND_2_BYTES); + udelay(1000); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_SR_DATA, I2C_SEND_2_BYTES); + udelay(10 * 1000); +} diff --git a/board/toradex/apalis_t30/Makefile b/board/toradex/apalis_t30/Makefile index 0ea3d8f217db..eed607043fc3 100644 --- a/board/toradex/apalis_t30/Makefile +++ b/board/toradex/apalis_t30/Makefile @@ -1,4 +1,6 @@ # Copyright (c) 2014 Marcel Ziswiler # SPDX-License-Identifier: GPL-2.0+ +obj-$(CONFIG_SPL_BUILD) += apalis_t30-spl.o + obj-y += apalis_t30.o diff --git a/board/toradex/apalis_t30/apalis_t30-spl.c b/board/toradex/apalis_t30/apalis_t30-spl.c new file mode 100644 index 000000000000..c56dc7d10537 --- /dev/null +++ b/board/toradex/apalis_t30/apalis_t30-spl.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2010-2013 + * NVIDIA Corporation + * + * (C) Copyright 2021 + * Svyatoslav Ryhel + */ + +#include +#include +#include + +/* I2C addr is in 8 bit */ +#define TPS65911_I2C_ADDR 0x5A +#define TPS65911_VDDCTRL_OP_REG 0x28 +#define TPS65911_VDDCTRL_SR_REG 0x27 +#define TPS65911_VDDCTRL_OP_DATA (0x2400 | TPS65911_VDDCTRL_OP_REG) +#define TPS65911_VDDCTRL_SR_DATA (0x0100 | TPS65911_VDDCTRL_SR_REG) + +void pmic_enable_cpu_vdd(void) +{ + /* + * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus. + * First set VDD to 1.0125V, then enable the VDD regulator. + */ + udelay(1000); + tegra_i2c_ll_write_addr(TPS65911_I2C_ADDR, 2); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_OP_DATA, I2C_SEND_2_BYTES); + udelay(1000); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_SR_DATA, I2C_SEND_2_BYTES); + udelay(10 * 1000); +} diff --git a/board/toradex/colibri_t30/Makefile b/board/toradex/colibri_t30/Makefile index 4242902daece..8f333235b176 100644 --- a/board/toradex/colibri_t30/Makefile +++ b/board/toradex/colibri_t30/Makefile @@ -1,4 +1,6 @@ # Copyright (c) 2013-2014 Stefan Agner # SPDX-License-Identifier: GPL-2.0+ +obj-$(CONFIG_SPL_BUILD) += colibri_t30-spl.o + obj-y += colibri_t30.o diff --git a/board/toradex/colibri_t30/colibri_t30-spl.c b/board/toradex/colibri_t30/colibri_t30-spl.c new file mode 100644 index 000000000000..c56dc7d10537 --- /dev/null +++ b/board/toradex/colibri_t30/colibri_t30-spl.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2010-2013 + * NVIDIA Corporation + * + * (C) Copyright 2021 + * Svyatoslav Ryhel + */ + +#include +#include +#include + +/* I2C addr is in 8 bit */ +#define TPS65911_I2C_ADDR 0x5A +#define TPS65911_VDDCTRL_OP_REG 0x28 +#define TPS65911_VDDCTRL_SR_REG 0x27 +#define TPS65911_VDDCTRL_OP_DATA (0x2400 | TPS65911_VDDCTRL_OP_REG) +#define TPS65911_VDDCTRL_SR_DATA (0x0100 | TPS65911_VDDCTRL_SR_REG) + +void pmic_enable_cpu_vdd(void) +{ + /* + * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus. + * First set VDD to 1.0125V, then enable the VDD regulator. + */ + udelay(1000); + tegra_i2c_ll_write_addr(TPS65911_I2C_ADDR, 2); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_OP_DATA, I2C_SEND_2_BYTES); + udelay(1000); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_SR_DATA, I2C_SEND_2_BYTES); + udelay(10 * 1000); +} diff --git a/include/configs/beaver.h b/include/configs/beaver.h index 1d51bb4e4c48..660800ba9441 100644 --- a/include/configs/beaver.h +++ b/include/configs/beaver.h @@ -10,9 +10,6 @@ #include "tegra30-common.h" -/* VDD core PMIC */ -#define CONFIG_TEGRA_VDD_CORE_TPS62366A_SET1 - /* High-level configuration options */ #define CONFIG_TEGRA_BOARD_STRING "NVIDIA Beaver" diff --git a/include/configs/cardhu.h b/include/configs/cardhu.h index f3416b534b23..8de1be9c6eb3 100644 --- a/include/configs/cardhu.h +++ b/include/configs/cardhu.h @@ -10,9 +10,6 @@ #include "tegra30-common.h" -/* VDD core PMIC */ -#define CONFIG_TEGRA_VDD_CORE_TPS62361B_SET3 - /* High-level configuration options */ #define CONFIG_TEGRA_BOARD_STRING "NVIDIA Cardhu" diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index c0f55e41a50b..b33c08b6b955 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -959,8 +959,6 @@ CONFIG_TEGRA_SLINK_CTRLS CONFIG_TEGRA_SPI CONFIG_TEGRA_UARTA_GPU CONFIG_TEGRA_UARTA_SDIO1 -CONFIG_TEGRA_VDD_CORE_TPS62361B_SET3 -CONFIG_TEGRA_VDD_CORE_TPS62366A_SET1 CONFIG_TESTPIN_MASK CONFIG_TESTPIN_REG CONFIG_THOR_RESET_OFF From dbcf50117548b374878e3760cc8320270b33faa3 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Tue, 22 Mar 2022 12:19:16 +0200 Subject: [PATCH 18/45] ARM: tegra: convert CONFIG_TEGRA_LP0 to Kconfig Signed-off-by: Svyatoslav Ryhel --- arch/arm/mach-tegra/tegra20/Kconfig | 4 ++++ configs/seaboard_defconfig | 1 + include/configs/seaboard.h | 2 -- scripts/config_whitelist.txt | 1 - 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-tegra/tegra20/Kconfig b/arch/arm/mach-tegra/tegra20/Kconfig index 5c4d35b5673d..4172a19b4707 100644 --- a/arch/arm/mach-tegra/tegra20/Kconfig +++ b/arch/arm/mach-tegra/tegra20/Kconfig @@ -45,6 +45,10 @@ endchoice config SYS_SOC default "tegra20" +config TEGRA_LP0 + bool "Enable LP0 suspend state support on T20" + default n + source "board/nvidia/harmony/Kconfig" source "board/avionic-design/medcom-wide/Kconfig" source "board/compal/paz00/Kconfig" diff --git a/configs/seaboard_defconfig b/configs/seaboard_defconfig index 686a3c062b1d..131d461371a2 100644 --- a/configs/seaboard_defconfig +++ b/configs/seaboard_defconfig @@ -10,6 +10,7 @@ CONFIG_SPL_TEXT_BASE=0x00108000 CONFIG_SYS_PROMPT="Tegra20 (SeaBoard) # " CONFIG_TEGRA20=y CONFIG_TARGET_SEABOARD=y +CONFIG_TEGRA_LP0=y CONFIG_SYS_LOAD_ADDR=0x1000000 CONFIG_OF_SYSTEM_SETUP=y CONFIG_USE_PREBOOT=y diff --git a/include/configs/seaboard.h b/include/configs/seaboard.h index c7f03a1e7543..161155a108d4 100644 --- a/include/configs/seaboard.h +++ b/include/configs/seaboard.h @@ -9,8 +9,6 @@ #include -/* LP0 suspend / resume */ -#define CONFIG_TEGRA_LP0 #define CONFIG_TEGRA_PMU #define CONFIG_TPS6586X_POWER #define CONFIG_TEGRA_CLOCK_SCALING diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index b33c08b6b955..4df27b39dc3c 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -953,7 +953,6 @@ CONFIG_TEGRA_BOARD_STRING CONFIG_TEGRA_CLOCK_SCALING CONFIG_TEGRA_ENABLE_UARTA CONFIG_TEGRA_ENABLE_UARTD -CONFIG_TEGRA_LP0 CONFIG_TEGRA_PMU CONFIG_TEGRA_SLINK_CTRLS CONFIG_TEGRA_SPI From 9c4eed259c20ddb04c26eac3ac520e2bbd2730b2 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Tue, 22 Mar 2022 12:22:24 +0200 Subject: [PATCH 19/45] ARM: tegra: expose crypto module for all Tegra SoC's Signed-off-by: Svyatoslav Ryhel --- arch/arm/mach-tegra/Kconfig | 5 +++++ arch/arm/mach-tegra/Makefile | 1 + arch/arm/mach-tegra/{tegra20 => }/crypto.c | 0 arch/arm/mach-tegra/{tegra20 => }/crypto.h | 0 arch/arm/mach-tegra/tegra20/Kconfig | 1 + arch/arm/mach-tegra/tegra20/Makefile | 2 +- 6 files changed, 8 insertions(+), 1 deletion(-) rename arch/arm/mach-tegra/{tegra20 => }/crypto.c (100%) rename arch/arm/mach-tegra/{tegra20 => }/crypto.h (100%) diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 09ad2d6f5aec..1bef2fb2338e 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -15,6 +15,11 @@ config SPL_SERIAL config TEGRA_CLKRST bool +config TEGRA_CRYPTO + bool "Tegra AES128 crypto module" + select AES + default n + config TEGRA_GP_PADCTRL bool diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 7165d70a60da..9147050b3233 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_TEGRA_GP_PADCTRL) += ap.o obj-y += board.o board2.o obj-y += cache.o obj-$(CONFIG_TEGRA_CLKRST) += clock.o +obj-$(CONFIG_$(SPL_)TEGRA_CRYPTO) += crypto.o obj-$(CONFIG_TEGRA_PINCTRL) += pinmux-common.o obj-$(CONFIG_TEGRA_PMC) += powergate.o obj-y += xusb-padctl-dummy.o diff --git a/arch/arm/mach-tegra/tegra20/crypto.c b/arch/arm/mach-tegra/crypto.c similarity index 100% rename from arch/arm/mach-tegra/tegra20/crypto.c rename to arch/arm/mach-tegra/crypto.c diff --git a/arch/arm/mach-tegra/tegra20/crypto.h b/arch/arm/mach-tegra/crypto.h similarity index 100% rename from arch/arm/mach-tegra/tegra20/crypto.h rename to arch/arm/mach-tegra/crypto.h diff --git a/arch/arm/mach-tegra/tegra20/Kconfig b/arch/arm/mach-tegra/tegra20/Kconfig index 4172a19b4707..5644edbea950 100644 --- a/arch/arm/mach-tegra/tegra20/Kconfig +++ b/arch/arm/mach-tegra/tegra20/Kconfig @@ -47,6 +47,7 @@ config SYS_SOC config TEGRA_LP0 bool "Enable LP0 suspend state support on T20" + select TEGRA_CRYPTO default n source "board/nvidia/harmony/Kconfig" diff --git a/arch/arm/mach-tegra/tegra20/Makefile b/arch/arm/mach-tegra/tegra20/Makefile index bb17c90cca29..67454ff5f4c5 100644 --- a/arch/arm/mach-tegra/tegra20/Makefile +++ b/arch/arm/mach-tegra/tegra20/Makefile @@ -13,6 +13,6 @@ CFLAGS_warmboot_avp.o = -march=armv4t -U__LINUX_ARM_ARCH__ \ CFLAGS_REMOVE_warmboot_avp.o := $(LTO_CFLAGS) obj-y += clock.o funcmux.o pinmux.o -obj-$(CONFIG_TEGRA_LP0) += warmboot.o crypto.o warmboot_avp.o +obj-$(CONFIG_TEGRA_LP0) += warmboot.o warmboot_avp.o obj-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o obj-$(CONFIG_TEGRA_PMU) += pmu.o From 53f186986b7a971f04238b1b633c258cf0e9c3bc Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Tue, 22 Mar 2022 13:03:49 +0200 Subject: [PATCH 20/45] ARM: tegra: crypto: extend crypto functional Add support for encryption, decryption and signinig with non-zero key saving backward compatibility. Signed-off-by: Svyatoslav Ryhel --- arch/arm/include/asm/arch-tegra/crypto.h | 47 ++++++++++++++++++++ arch/arm/mach-tegra/crypto.c | 55 +++++++++++++++++------- arch/arm/mach-tegra/crypto.h | 19 -------- 3 files changed, 87 insertions(+), 34 deletions(-) create mode 100644 arch/arm/include/asm/arch-tegra/crypto.h delete mode 100644 arch/arm/mach-tegra/crypto.h diff --git a/arch/arm/include/asm/arch-tegra/crypto.h b/arch/arm/include/asm/arch-tegra/crypto.h new file mode 100644 index 000000000000..9a6103ad11da --- /dev/null +++ b/arch/arm/include/asm/arch-tegra/crypto.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2011 The Chromium OS Authors. + * (C) Copyright 2010 - 2011 NVIDIA Corporation + */ + +#ifndef _CRYPTO_H_ +#define _CRYPTO_H_ + +/** + * Sign a block of data + * + * \param source Source data + * \param length Size of source data + * \param signature Destination address for signature, AES_KEY_LENGTH bytes + */ +int sign_data_block(u8 *source, unsigned length, u8 *signature); + +/** + * Sign an encrypted block of data + * + * \param source Source data + * \param length Size of source data + * \param signature Destination address for signature, AES_KEY_LENGTH bytes + * \param key AES128 encryption key + */ +int sign_enc_data_block(u8 *source, unsigned length, u8 *signature, u8 *key); + +/** + * Encrypt a block of data + * + * \param source Source data + * \param length Size of source data + * \param key AES128 encryption key + */ +int encrypt_data_block(u8 *source, unsigned length, u8 *key); + +/** + * Decrypt a block of data + * + * \param source Source data + * \param length Size of source data + * \param key AES128 encryption key + */ +int decrypt_data_block(u8 *source, unsigned length, u8 *key); + +#endif /* #ifndef _CRYPTO_H_ */ diff --git a/arch/arm/mach-tegra/crypto.c b/arch/arm/mach-tegra/crypto.c index 1efaa5c3ecd7..6e85701d421a 100644 --- a/arch/arm/mach-tegra/crypto.c +++ b/arch/arm/mach-tegra/crypto.c @@ -7,7 +7,7 @@ #include #include #include -#include "crypto.h" +#include #include "uboot_aes.h" static u8 zero_key[16]; @@ -17,6 +17,7 @@ static u8 zero_key[16]; enum security_op { SECURITY_SIGN = 1 << 0, /* Sign the data */ SECURITY_ENCRYPT = 1 << 1, /* Encrypt the data */ + SECURITY_DECRYPT = 1 << 2, /* Dectypt the data */ }; /** @@ -92,7 +93,7 @@ static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst, } /** - * Encrypt and sign a block of data (depending on security mode). + * Decrypt, encrypt or sign a block of data (depending on security mode). * * \param key Input AES key, length AES128_KEY_LENGTH * \param oper Security operations mask to perform (enum security_op) @@ -100,44 +101,68 @@ static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst, * \param length Size of source data * \param sig_dst Destination address for signature, AES128_KEY_LENGTH bytes */ -static int encrypt_and_sign(u8 *key, enum security_op oper, u8 *src, +static int tegra_crypto_core(u8 *key, enum security_op oper, u8 *src, u32 length, u8 *sig_dst) { u32 num_aes_blocks; u8 key_schedule[AES128_EXPAND_KEY_LENGTH]; u8 iv[AES128_KEY_LENGTH] = {0}; - debug("encrypt_and_sign: length = %d\n", length); + debug("tegra_crypto_core: length = %d\n", length); - /* - * The only need for a key is for signing/checksum purposes, so - * if not encrypting, expand a key of 0s. - */ - aes_expand_key(oper & SECURITY_ENCRYPT ? key : zero_key, - AES128_KEY_LENGTH, key_schedule); + aes_expand_key(key, AES128_KEY_LENGTH, key_schedule); num_aes_blocks = (length + AES128_KEY_LENGTH - 1) / AES128_KEY_LENGTH; + if (oper & SECURITY_DECRYPT) { + /* Perform this in place, resulting in src being decrypted. */ + debug("tegra_crypto_core: begin decryption\n"); + aes_cbc_decrypt_blocks(AES128_KEY_LENGTH, key_schedule, iv, src, + src, num_aes_blocks); + debug("tegra_crypto_core: end decryption\n"); + } + if (oper & SECURITY_ENCRYPT) { /* Perform this in place, resulting in src being encrypted. */ - debug("encrypt_and_sign: begin encryption\n"); + debug("tegra_crypto_core: begin encryption\n"); aes_cbc_encrypt_blocks(AES128_KEY_LENGTH, key_schedule, iv, src, src, num_aes_blocks); - debug("encrypt_and_sign: end encryption\n"); + debug("tegra_crypto_core: end encryption\n"); } if (oper & SECURITY_SIGN) { /* encrypt the data, overwriting the result in signature. */ - debug("encrypt_and_sign: begin signing\n"); + debug("tegra_crypto_core: begin signing\n"); sign_object(key, key_schedule, src, sig_dst, num_aes_blocks); - debug("encrypt_and_sign: end signing\n"); + debug("tegra_crypto_core: end signing\n"); } return 0; } +/** + * Tegra crypto group + */ int sign_data_block(u8 *source, unsigned length, u8 *signature) { - return encrypt_and_sign(zero_key, SECURITY_SIGN, source, + return tegra_crypto_core(zero_key, SECURITY_SIGN, source, length, signature); } + +int sign_enc_data_block(u8 *source, unsigned length, u8 *signature, u8 *key) +{ + return tegra_crypto_core(key, SECURITY_SIGN, source, + length, signature); +} + +int encrypt_data_block(u8 *source, unsigned length, u8 *key) +{ + return tegra_crypto_core(key, SECURITY_ENCRYPT, source, + length, NULL); +} + +int decrypt_data_block(u8 *source, unsigned length, u8 *key) +{ + return tegra_crypto_core(key, SECURITY_DECRYPT, source, + length, NULL); +} diff --git a/arch/arm/mach-tegra/crypto.h b/arch/arm/mach-tegra/crypto.h deleted file mode 100644 index a773d03fc742..000000000000 --- a/arch/arm/mach-tegra/crypto.h +++ /dev/null @@ -1,19 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * (C) Copyright 2010 - 2011 NVIDIA Corporation - */ - -#ifndef _CRYPTO_H_ -#define _CRYPTO_H_ - -/** - * Sign a block of data - * - * \param source Source data - * \param length Size of source data - * \param signature Destination address for signature, AES_KEY_LENGTH bytes - */ -int sign_data_block(u8 *source, unsigned length, u8 *signature); - -#endif /* #ifndef _CRYPTO_H_ */ From 01fcdcea3d536b9b1040357ea545d65121a226b5 Mon Sep 17 00:00:00 2001 From: Ramin Khonsari Date: Tue, 22 Mar 2022 20:03:48 +0200 Subject: [PATCH 21/45] ARM: tegra30: implement BCT patching Signed-off-by: Ramin Khonsari Signed-off-by: Svyatoslav Ryhel --- arch/arm/include/asm/arch-tegra/crypto.h | 7 ++ arch/arm/mach-tegra/tegra30/Makefile | 1 + arch/arm/mach-tegra/tegra30/bct.c | 81 ++++++++++++++++++++++++ arch/arm/mach-tegra/tegra30/bct.h | 42 ++++++++++++ 4 files changed, 131 insertions(+) create mode 100644 arch/arm/mach-tegra/tegra30/bct.c create mode 100644 arch/arm/mach-tegra/tegra30/bct.h diff --git a/arch/arm/include/asm/arch-tegra/crypto.h b/arch/arm/include/asm/arch-tegra/crypto.h index 9a6103ad11da..62c58f65f1f8 100644 --- a/arch/arm/include/asm/arch-tegra/crypto.h +++ b/arch/arm/include/asm/arch-tegra/crypto.h @@ -44,4 +44,11 @@ int encrypt_data_block(u8 *source, unsigned length, u8 *key); */ int decrypt_data_block(u8 *source, unsigned length, u8 *key); +/** + * Pass AES key from board + * + * \param key AES128 encryption key + */ +void get_secure_key(u8 *key); + #endif /* #ifndef _CRYPTO_H_ */ diff --git a/arch/arm/mach-tegra/tegra30/Makefile b/arch/arm/mach-tegra/tegra30/Makefile index 9f170576e7c4..e7eaafb4f6f8 100644 --- a/arch/arm/mach-tegra/tegra30/Makefile +++ b/arch/arm/mach-tegra/tegra30/Makefile @@ -3,5 +3,6 @@ # Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. obj-$(CONFIG_SPL_BUILD) += cpu.o +obj-$(CONFIG_$(SPL_)TEGRA_CRYPTO) += bct.o obj-y += clock.o funcmux.o pinmux.o diff --git a/arch/arm/mach-tegra/tegra30/bct.c b/arch/arm/mach-tegra/tegra30/bct.c new file mode 100644 index 000000000000..d79f6b3ed060 --- /dev/null +++ b/arch/arm/mach-tegra/tegra30/bct.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022, Ramin + * Copyright (c) 2022, Svyatoslav Ryhel + */ + +#include +#include +#include +#include +#include "bct.h" +#include "uboot_aes.h" + +/* If board does not pass sbk, keep it 0 */ +__weak void get_secure_key(u8 *key) {} + +/* + * \param bct boot config table start in RAM + * \param ect bootloader start in RAM + * \param ebt_size bootloader file size in bytes + */ +static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size) +{ + u8 ebt_hash[AES128_KEY_LENGTH] = { 0 }; + u8 sbk[AES128_KEY_LENGTH] = { 0 }; + nvboot_config_table *bct_tbl = NULL; + u8 *bct_hash = bct; + int ret; + + get_secure_key(sbk); + + bct += BCT_HASH; + + ret = decrypt_data_block(bct, BCT_LENGTH, sbk); + if (ret) + return 1; + + ebt_size = roundup(ebt_size, EBT_ALIGNMENT); + + ret = encrypt_data_block(ebt, ebt_size, sbk); + if (ret) + return 1; + + ret = sign_enc_data_block(ebt, ebt_size, ebt_hash, sbk); + if (ret) + return 1; + + bct_tbl = (nvboot_config_table *)bct; + + memcpy((u8 *)&bct_tbl->bootloader[0].crypto_hash, + ebt_hash, NVBOOT_CMAC_AES_HASH_LENGTH * 4); + bct_tbl->bootloader[0].entry_point = CONFIG_SPL_TEXT_BASE; + bct_tbl->bootloader[0].load_addr = CONFIG_SPL_TEXT_BASE; + bct_tbl->bootloader[0].length = ebt_size; + + ret = encrypt_data_block(bct, BCT_LENGTH, sbk); + if (ret) + return 1; + + ret = sign_enc_data_block(bct, BCT_LENGTH, bct_hash, sbk); + if (ret) + return 1; + + return 0; +} + +static int do_ebtupdate(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + u32 bct_addr = hextoul(argv[1], NULL); + u32 ebt_addr = hextoul(argv[2], NULL); + u32 ebt_size = hextoul(argv[3], NULL); + + return bct_patch((u8 *)bct_addr, (u8 *)ebt_addr, ebt_size); +} + +U_BOOT_CMD( + ebtupdate, 4, 0, do_ebtupdate, + "update bootloader on Tegra30 devices", + "" +); diff --git a/arch/arm/mach-tegra/tegra30/bct.h b/arch/arm/mach-tegra/tegra30/bct.h new file mode 100644 index 000000000000..ed8d6f4ead4d --- /dev/null +++ b/arch/arm/mach-tegra/tegra30/bct.h @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#ifndef _BCT_H_ +#define _BCT_H_ + +/* + * Defines the BCT parametres for T30 + */ +#define BCT_LENGTH 0x17E0 +#define BCT_HASH 0x10 +#define EBT_ALIGNMENT 0x10 + +/* + * Defines the CMAC-AES-128 hash length in 32 bit words. (128 bits = 4 words) + */ +#define NVBOOT_CMAC_AES_HASH_LENGTH 4 + +/* + * Defines the maximum number of bootloader descriptions in the BCT. + */ +#define NVBOOT_MAX_BOOTLOADERS 4 + +typedef struct nv_bootloader_info_rec { + u32 version; + u32 start_blk; + u32 start_page; + u32 length; + u32 load_addr; + u32 entry_point; + u32 attribute; + u32 crypto_hash[NVBOOT_CMAC_AES_HASH_LENGTH]; +} nv_bootloader_info; + +typedef struct nvboot_config_table_rec { + u32 unused0[4]; + u32 boot_data_version; + u32 unused1[972]; + nv_bootloader_info bootloader[NVBOOT_MAX_BOOTLOADERS]; + u32 unused2[508]; +} nvboot_config_table; + +#endif /* _BCT_H_ */ From 64f93ff2d2f0b2ee312100afc4cb86c7aafd6488 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Sun, 6 Nov 2022 15:49:45 +0200 Subject: [PATCH 22/45] ARM: tegra20: implement BCT patching Signed-off-by: Ramin Khonsari Signed-off-by: Svyatoslav Ryhel --- arch/arm/mach-tegra/tegra20/Makefile | 5 +- arch/arm/mach-tegra/tegra20/bct.c | 81 ++++++++++++++++++++++++++++ arch/arm/mach-tegra/tegra20/bct.h | 42 +++++++++++++++ 3 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-tegra/tegra20/bct.c create mode 100644 arch/arm/mach-tegra/tegra20/bct.h diff --git a/arch/arm/mach-tegra/tegra20/Makefile b/arch/arm/mach-tegra/tegra20/Makefile index 67454ff5f4c5..343cf368fed4 100644 --- a/arch/arm/mach-tegra/tegra20/Makefile +++ b/arch/arm/mach-tegra/tegra20/Makefile @@ -2,9 +2,8 @@ # # (C) Copyright 2010,2011 Nvidia Corporation. -ifdef CONFIG_SPL_BUILD -obj-y += cpu.o -endif +obj-$(CONFIG_SPL_BUILD) += cpu.o +obj-$(CONFIG_$(SPL_)TEGRA_CRYPTO) += bct.o # The AVP is ARMv4T architecture so we must use special compiler # flags for any startup files it might use. diff --git a/arch/arm/mach-tegra/tegra20/bct.c b/arch/arm/mach-tegra/tegra20/bct.c new file mode 100644 index 000000000000..e3e6dc02946b --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/bct.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022, Ramin + * Copyright (c) 2022, Svyatoslav Ryhel + */ + +#include +#include +#include +#include +#include "bct.h" +#include "uboot_aes.h" + +/* If board does not pass sbk, keep it 0 */ +__weak void get_secure_key(u8 *key) {} + +/* + * \param bct boot config table start in RAM + * \param ect bootloader start in RAM + * \param ebt_size bootloader file size in bytes + */ +static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size) +{ + u8 ebt_hash[AES128_KEY_LENGTH] = { 0 }; + u8 sbk[AES128_KEY_LENGTH] = { 0 }; + nvboot_config_table *bct_tbl = NULL; + u8 *bct_hash = bct; + int ret; + + get_secure_key(sbk); + + bct += BCT_HASH; + + ret = decrypt_data_block(bct, BCT_LENGTH, sbk); + if (ret) + return 1; + + ebt_size = roundup(ebt_size, EBT_ALIGNMENT); + + ret = encrypt_data_block(ebt, ebt_size, sbk); + if (ret) + return 1; + + ret = sign_enc_data_block(ebt, ebt_size, ebt_hash, sbk); + if (ret) + return 1; + + bct_tbl = (nvboot_config_table *)bct; + + memcpy((u8 *)&bct_tbl->bootloader[0].crypto_hash, + ebt_hash, NVBOOT_CMAC_AES_HASH_LENGTH * 4); + bct_tbl->bootloader[0].entry_point = CONFIG_SPL_TEXT_BASE; + bct_tbl->bootloader[0].load_addr = CONFIG_SPL_TEXT_BASE; + bct_tbl->bootloader[0].length = ebt_size; + + ret = encrypt_data_block(bct, BCT_LENGTH, sbk); + if (ret) + return 1; + + ret = sign_enc_data_block(bct, BCT_LENGTH, bct_hash, sbk); + if (ret) + return 1; + + return 0; +} + +static int do_ebtupdate(struct cmd_tbl *cmdtp, int flag, int argc, + char *const argv[]) +{ + u32 bct_addr = hextoul(argv[1], NULL); + u32 ebt_addr = hextoul(argv[2], NULL); + u32 ebt_size = hextoul(argv[3], NULL); + + return bct_patch((u8 *)bct_addr, (u8 *)ebt_addr, ebt_size); +} + +U_BOOT_CMD( + ebtupdate, 4, 0, do_ebtupdate, + "update bootloader on Tegra20 devices", + "" +); diff --git a/arch/arm/mach-tegra/tegra20/bct.h b/arch/arm/mach-tegra/tegra20/bct.h new file mode 100644 index 000000000000..d1f20c0a71aa --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/bct.h @@ -0,0 +1,42 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#ifndef _BCT_H_ +#define _BCT_H_ + +/* + * Defines the BCT parametres for T20 + */ +#define BCT_LENGTH 0xFF0 +#define BCT_HASH 0x10 +#define EBT_ALIGNMENT 0x10 + +/* + * Defines the CMAC-AES-128 hash length in 32 bit words. (128 bits = 4 words) + */ +#define NVBOOT_CMAC_AES_HASH_LENGTH 4 + +/* + * Defines the maximum number of bootloader descriptions in the BCT. + */ +#define NVBOOT_MAX_BOOTLOADERS 4 + +typedef struct nv_bootloader_info_rec { + u32 version; + u32 start_blk; + u32 start_page; + u32 length; + u32 load_addr; + u32 entry_point; + u32 attribute; + u32 crypto_hash[NVBOOT_CMAC_AES_HASH_LENGTH]; +} nv_bootloader_info; + +typedef struct nvboot_config_table_rec { + u32 unused0[4]; + u32 boot_data_version; + u32 unused1[672]; + nv_bootloader_info bootloader[NVBOOT_MAX_BOOTLOADERS]; + u32 unused2[508]; +} nvboot_config_table; + +#endif /* _BCT_H_ */ From 48c809d7695bb58b3239fb2c85c96eaf2576ee7a Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 8 Jul 2022 20:00:19 +0300 Subject: [PATCH 23/45] configs: tegra-common-post: add GPIO keyboard as STDIN device Signed-off-by: Svyatoslav Ryhel --- include/configs/tegra-common-post.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/configs/tegra-common-post.h b/include/configs/tegra-common-post.h index 69acabf19fdd..527dec17d901 100644 --- a/include/configs/tegra-common-post.h +++ b/include/configs/tegra-common-post.h @@ -35,6 +35,12 @@ #define STDIN_KBD_USB "" #endif +#ifdef CONFIG_GPIO_KEYBOARD +#define STDIN_KBD_GPIO ",gpio-kbd" +#else +#define STDIN_KBD_GPIO "" +#endif + #ifdef CONFIG_VIDEO #define STDOUT_VIDEO ",vidconsole" #else @@ -48,7 +54,7 @@ #endif #define TEGRA_DEVICE_SETTINGS \ - "stdin=serial" STDIN_KBD_KBC STDIN_KBD_USB STDOUT_CROS_EC "\0" \ + "stdin=serial" STDIN_KBD_KBC STDIN_KBD_USB STDOUT_CROS_EC STDIN_KBD_GPIO"\0" \ "stdout=serial" STDOUT_VIDEO "\0" \ "stderr=serial" STDOUT_VIDEO "\0" \ "" From c34851d41bdbae5178c9f46c5273cd1d5600bdd8 Mon Sep 17 00:00:00 2001 From: Tobias Zagorni Date: Tue, 28 Sep 2021 22:56:32 +0300 Subject: [PATCH 24/45] disk: part_efi: add partition detection workaround for eMMC Tegra devices on Android have proprietary partition table based on GPT. Signed-off-by: Tobias Zagorni Signed-off-by: Svyatoslav Ryhel --- arch/arm/mach-tegra/Kconfig | 4 ++++ disk/part_efi.c | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 1bef2fb2338e..a8956dcdc857 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -31,6 +31,10 @@ config TEGRA_IVC U-Boot, it is typically used for communication between the main CPU and various auxiliary processors. +config TEGRA_LEGACY_PT + bool "Tegra Legacy eMMC partition table support" + default n + config TEGRA_MC bool diff --git a/disk/part_efi.c b/disk/part_efi.c index 18f7e5840507..7303b806a5f7 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -310,6 +310,15 @@ static int part_test_efi(struct blk_desc *dev_desc) { ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz); +#ifdef CONFIG_TEGRA_LEGACY_PT + /* + * Tegra based boards use custom gpt based partition table on eMMC. + * This function fails for eMMC though gpt exists there. Lets skip it. + */ + if (dev_desc->uclass_id == UCLASS_MMC && dev_desc->devnum == 0) + return 0; +#endif + /* Read legacy MBR from block 0 and validate it */ if ((blk_dread(dev_desc, 0, 1, (ulong *)legacymbr) != 1) || (is_pmbr_valid(legacymbr) != 1)) { @@ -1037,6 +1046,17 @@ static int is_gpt_valid(struct blk_desc *dev_desc, u64 lba, return 2; } +#ifdef CONFIG_TEGRA_LEGACY_PT + /* + * Invalid but nothing to tell about! If board uses own Tegra partition + * table primary gpt header for eMMC will constantly fail. Use backup. + */ + if (dev_desc->uclass_id == UCLASS_MMC && dev_desc->devnum == 0) { + if (le64_to_cpu(pgpt_head->signature) != GPT_HEADER_SIGNATURE_UBOOT) + return 2; + }; +#endif + if (validate_gpt_header(pgpt_head, (lbaint_t)lba, dev_desc->lba)) return 0; From 34a5119c445bb3c8bdacbabb3c3c2291cf9cf91b Mon Sep 17 00:00:00 2001 From: Ion Agorria Date: Wed, 17 Aug 2022 19:40:57 +0200 Subject: [PATCH 25/45] fastboot: multiresponse support --- drivers/fastboot/fb_command.c | 10 ++++++++++ drivers/usb/gadget/f_fastboot.c | 26 ++++++++++++++++++++++++++ include/fastboot.h | 8 ++++++++ net/fastboot.c | 28 +++++++++++++++++++++------- 4 files changed, 65 insertions(+), 7 deletions(-) diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c index bdfdf262c8a3..3aacb30cd593 100644 --- a/drivers/fastboot/fb_command.c +++ b/drivers/fastboot/fb_command.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -166,6 +167,15 @@ int fastboot_handle_command(char *cmd_string, char *response) return -1; } +void fastboot_multiresponse(int cmd, char *response) +{ + switch (cmd) { + default: + fastboot_fail("Unknown multiresponse command", response); + break; + } +} + /** * okay() - Send bare OKAY response * diff --git a/drivers/usb/gadget/f_fastboot.c b/drivers/usb/gadget/f_fastboot.c index 07b1681c8a9a..cb66b914e91f 100644 --- a/drivers/usb/gadget/f_fastboot.c +++ b/drivers/usb/gadget/f_fastboot.c @@ -495,6 +495,23 @@ static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req) do_exit_on_complete(ep, req); } +int multiresponse_cmd = -1; +static void multiresponse_on_complete(struct usb_ep *ep, struct usb_request *req) +{ + char response[FASTBOOT_RESPONSE_LEN] = {0}; + if (multiresponse_cmd == -1) return; + + //Call handler to obtain next response + fastboot_multiresponse(multiresponse_cmd, response); + fastboot_tx_write_str(response); + + //If response is not an INFO disconnect this handler and unset cmd + if (strncmp("INFO", response, 4) != 0) { + multiresponse_cmd = -1; + fastboot_func->in_req->complete = fastboot_complete; + } +} + #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) static void do_acmd_complete(struct usb_ep *ep, struct usb_request *req) { @@ -524,6 +541,15 @@ static void rx_handler_command(struct usb_ep *ep, struct usb_request *req) fastboot_fail("buffer overflow", response); } + if (!strncmp("MORE", response, 4)) { + multiresponse_cmd = cmd; + fastboot_multiresponse(multiresponse_cmd, response); + //Only add if first is a INFO + if (!strncmp("INFO", response, 4)) { + fastboot_func->in_req->complete = multiresponse_on_complete; + } + } + if (!strncmp("DATA", response, 4)) { req->complete = rx_handler_dl_image; req->length = rx_bytes_expected(ep); diff --git a/include/fastboot.h b/include/fastboot.h index 57daaf129821..46a0183fcac2 100644 --- a/include/fastboot.h +++ b/include/fastboot.h @@ -173,6 +173,14 @@ void fastboot_data_download(const void *fastboot_data, */ void fastboot_data_complete(char *response); +/** + * fastboot_handle_multiresponse() - Called for each response to send + * + * @cmd: Command id that requested multiresponse + * @response: Pointer to fastboot response buffer + */ +void fastboot_multiresponse(int cmd, char *response); + #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) void fastboot_acmd_complete(void); #endif diff --git a/net/fastboot.c b/net/fastboot.c index 139233b86c61..18aa4555df01 100644 --- a/net/fastboot.c +++ b/net/fastboot.c @@ -42,18 +42,16 @@ static int fastboot_our_port; static void boot_downloaded_image(void); -#if CONFIG_IS_ENABLED(FASTBOOT_FLASH) /** - * fastboot_udp_send_info() - Send an INFO packet during long commands. + * fastboot_udp_send_response() - Send an response into UDP * - * @msg: String describing the reason for waiting + * @response: Response to send */ -static void fastboot_udp_send_info(const char *msg) +static void fastboot_udp_send_response(const char *response) { uchar *packet; uchar *packet_base; int len = 0; - char response[FASTBOOT_RESPONSE_LEN] = {0}; struct fastboot_header response_header = { .id = FASTBOOT_FASTBOOT, @@ -68,7 +66,6 @@ static void fastboot_udp_send_info(const char *msg) memcpy(packet, &response_header, sizeof(response_header)); packet += sizeof(response_header); /* Write response */ - fastboot_response("INFO", response, "%s", msg); memcpy(packet, response, strlen(response)); packet += strlen(response); @@ -82,6 +79,7 @@ static void fastboot_udp_send_info(const char *msg) fastboot_remote_port, fastboot_our_port, len); } +#if CONFIG_IS_ENABLED(FASTBOOT_FLASH) /** * fastboot_timed_send_info() - Send INFO packet every 30 seconds * @@ -93,6 +91,7 @@ static void fastboot_udp_send_info(const char *msg) static void fastboot_timed_send_info(const char *msg) { static ulong start; + char response[FASTBOOT_RESPONSE_LEN] = {0}; /* Initialize timer */ if (start == 0) @@ -101,7 +100,8 @@ static void fastboot_timed_send_info(const char *msg) /* Send INFO packet to host every 30 seconds */ if (time >= 30000) { start = get_timer(0); - fastboot_udp_send_info(msg); + fastboot_response("INFO", response, "%s", msg); + fastboot_udp_send_response(response); } } #endif @@ -183,6 +183,20 @@ static void fastboot_send(struct fastboot_header header, char *fastboot_data, } else { cmd = fastboot_handle_command(command, response); pending_command = false; + + if (!strncmp("MORE", response, 4)) { + while (1) { + //Call handler to obtain next response + fastboot_multiresponse(multiresponse_cmd, response); + + //Send INFO or break to send final response + if (!strncmp("INFO", response, 4)) { + fastboot_udp_send_response(response); + } else { + break; + } + } + } } /* * Sent some INFO packets, need to update sequence number in From 921e1bfa9c8f2227d18bce950bd61749ae316ff0 Mon Sep 17 00:00:00 2001 From: Ion Agorria Date: Thu, 18 Aug 2022 00:05:39 +0200 Subject: [PATCH 26/45] fastboot: implement "getvar all" This commit implements "fastboot getvar all" listing by iterating the existing dispatchers that don't require parameters (as we pass NULL), uses fastboot multiresponse. --- drivers/fastboot/fb_command.c | 3 ++ drivers/fastboot/fb_getvar.c | 76 +++++++++++++++++++++++++++++------ include/fastboot-internal.h | 7 ++++ 3 files changed, 73 insertions(+), 13 deletions(-) diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c index 3aacb30cd593..08387b46becd 100644 --- a/drivers/fastboot/fb_command.c +++ b/drivers/fastboot/fb_command.c @@ -170,6 +170,9 @@ int fastboot_handle_command(char *cmd_string, char *response) void fastboot_multiresponse(int cmd, char *response) { switch (cmd) { + case FASTBOOT_COMMAND_GETVAR: + fastboot_getvar_all(response); + break; default: fastboot_fail("Unknown multiresponse command", response); break; diff --git a/drivers/fastboot/fb_getvar.c b/drivers/fastboot/fb_getvar.c index 018989dd1667..b773981958cb 100644 --- a/drivers/fastboot/fb_getvar.c +++ b/drivers/fastboot/fb_getvar.c @@ -34,53 +34,67 @@ static void getvar_is_userspace(char *var_parameter, char *response); static const struct { const char *variable; + bool list; void (*dispatch)(char *var_parameter, char *response); } getvar_dispatch[] = { { .variable = "version", - .dispatch = getvar_version + .dispatch = getvar_version, + .list = true, }, { .variable = "version-bootloader", - .dispatch = getvar_version_bootloader + .dispatch = getvar_version_bootloader, + .list = true }, { .variable = "downloadsize", - .dispatch = getvar_downloadsize + .dispatch = getvar_downloadsize, + .list = true }, { .variable = "max-download-size", - .dispatch = getvar_downloadsize + .dispatch = getvar_downloadsize, + .list = true }, { .variable = "serialno", - .dispatch = getvar_serialno + .dispatch = getvar_serialno, + .list = true }, { .variable = "version-baseband", - .dispatch = getvar_version_baseband + .dispatch = getvar_version_baseband, + .list = true }, { .variable = "product", - .dispatch = getvar_product + .dispatch = getvar_product, + .list = true }, { .variable = "platform", - .dispatch = getvar_platform + .dispatch = getvar_platform, + .list = true }, { .variable = "current-slot", - .dispatch = getvar_current_slot + .dispatch = getvar_current_slot, + .list = true #if CONFIG_IS_ENABLED(FASTBOOT_FLASH) }, { .variable = "has-slot", - .dispatch = getvar_has_slot + .dispatch = getvar_has_slot, + .list = false #endif #if CONFIG_IS_ENABLED(FASTBOOT_FLASH_MMC) }, { .variable = "partition-type", - .dispatch = getvar_partition_type + .dispatch = getvar_partition_type, + .list = false #endif #if CONFIG_IS_ENABLED(FASTBOOT_FLASH) }, { .variable = "partition-size", - .dispatch = getvar_partition_size + .dispatch = getvar_partition_size, + .list = false #endif }, { .variable = "is-userspace", - .dispatch = getvar_is_userspace + .dispatch = getvar_is_userspace, + .list = true } }; @@ -251,6 +265,38 @@ static void getvar_is_userspace(char *var_parameter, char *response) fastboot_okay("no", response); } +int current_all_dispatch = 0; +void fastboot_getvar_all(char *response) { + //TODO add way to iterate envs starting with FASTBOOT_ENV_PREFIX? + + //Find a dispatch getvar that can be listed and send it as INFO until we reach end + while (current_all_dispatch < ARRAY_SIZE(getvar_dispatch)) { + if (!getvar_dispatch[current_all_dispatch].list) { + //Try next one if can be listed + current_all_dispatch++; + continue; + } + + char envstr[FASTBOOT_RESPONSE_LEN] = { 0 }; + getvar_dispatch[current_all_dispatch].dispatch(NULL, envstr); + + //Handle OKAY/FAIL and assemble response + char* envstr_start = envstr; + if (!strncmp("OKAY", envstr, 4) || !strncmp("FAIL", envstr, 4)) { + envstr_start += 4; + } + fastboot_response("INFO", response, "%s: %s", getvar_dispatch[current_all_dispatch].variable, envstr_start); + + //We will be called again for next var + current_all_dispatch++; + return; + } + + //We listed all, send final response + fastboot_response("OKAY", response, NULL); + current_all_dispatch = 0; +} + /** * fastboot_getvar() - Writes variable indicated by cmd_parameter to response. * @@ -268,6 +314,10 @@ void fastboot_getvar(char *cmd_parameter, char *response) { if (!cmd_parameter) { fastboot_fail("missing var", response); + } else if (!strncmp("all", cmd_parameter, 3) && strlen(cmd_parameter) == 3) { + //Call multiresponse handler which will call fastboot_getvar_all + current_all_dispatch = 0; + fastboot_response("MORE", response, NULL); } else { #define FASTBOOT_ENV_PREFIX "fastboot." int i; diff --git a/include/fastboot-internal.h b/include/fastboot-internal.h index bf2f2b3c8914..610d4f914140 100644 --- a/include/fastboot-internal.h +++ b/include/fastboot-internal.h @@ -18,6 +18,13 @@ extern u32 fastboot_buf_size; */ extern void (*fastboot_progress_callback)(const char *msg); +/** + * fastboot_getvar_all() - Writes current variable being listed from "all" to response. + * + * @response: Pointer to fastboot response buffer + */ +void fastboot_getvar_all(char *response); + /** * fastboot_getvar() - Writes variable indicated by cmd_parameter to response. * From 9783aa132a7739e8894c4d846e2af2a857ed7d25 Mon Sep 17 00:00:00 2001 From: Ion Agorria Date: Wed, 17 Aug 2022 19:42:37 +0200 Subject: [PATCH 27/45] console: separate record overflow logic and add console_record_isempty as avail doesn't serve to know output has been read fully with readline's --- common/console.c | 15 ++++++++++++--- include/console.h | 14 ++++++++++++++ test/ut.c | 9 ++++----- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/common/console.c b/common/console.c index 0c9bf66c3f6d..ea88d9cb355a 100644 --- a/common/console.c +++ b/common/console.c @@ -818,6 +818,8 @@ int console_record_init(void) ret = membuff_new((struct membuff *)&gd->console_in, CONFIG_CONSOLE_RECORD_IN_SIZE); + gd->flags |= GD_FLG_RECORD; + return ret; } @@ -836,11 +838,13 @@ int console_record_reset_enable(void) return 0; } -int console_record_readline(char *str, int maxlen) +bool console_record_overflow(void) { - if (gd->flags & GD_FLG_RECORD_OVF) - return -ENOSPC; + return gd->flags & GD_FLG_RECORD_OVF ? true : false; +} +int console_record_readline(char *str, int maxlen) +{ return membuff_readline((struct membuff *)&gd->console_out, str, maxlen, ' '); } @@ -850,6 +854,11 @@ int console_record_avail(void) return membuff_avail((struct membuff *)&gd->console_out); } +bool console_record_isempty(void) +{ + return membuff_isempty((struct membuff *)&gd->console_out); +} + int console_in_puts(const char *str) { return membuff_put((struct membuff *)&gd->console_in, str, strlen(str)); diff --git a/include/console.h b/include/console.h index ceb733b5cb69..dd983ad02dab 100644 --- a/include/console.h +++ b/include/console.h @@ -64,6 +64,13 @@ void console_record_reset(void); */ int console_record_reset_enable(void); +/** + * console_record_overflow() - returns state of buffers overflow + * + * Return: true if the console buffer was overflowed + */ +bool console_record_overflow(void); + /** * console_record_readline() - Read a line from the console output * @@ -84,6 +91,13 @@ int console_record_readline(char *str, int maxlen); */ int console_record_avail(void); +/** + * console_record_isempty() - Returns if console output is empty + * + * Return: true if empty + */ +bool console_record_isempty(void); + /** * console_in_puts() - Write a string to the console input buffer * diff --git a/test/ut.c b/test/ut.c index 28da417686e4..d202644a1590 100644 --- a/test/ut.c +++ b/test/ut.c @@ -53,15 +53,14 @@ long ut_check_delta(ulong last) static int readline_check(struct unit_test_state *uts) { - int ret; - - ret = console_record_readline(uts->actual_str, sizeof(uts->actual_str)); - if (ret == -ENOSPC) { + if (console_record_overflow()) { ut_fail(uts, __FILE__, __LINE__, __func__, "Console record buffer too small - increase CONFIG_CONSOLE_RECORD_OUT_SIZE"); - return ret; + return -ENOSPC; } + console_record_readline(uts->actual_str, sizeof(uts->actual_str)); + return 0; } From 2b08d409365aaf1807c1ea88d5eae70ae4a05b72 Mon Sep 17 00:00:00 2001 From: Ion Agorria Date: Wed, 17 Aug 2022 20:42:35 +0200 Subject: [PATCH 28/45] membuff: fix readline not returning line if didn't fit added this behavior as optional and documented properly --- common/console.c | 3 +-- include/membuff.h | 5 +++-- lib/membuff.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/common/console.c b/common/console.c index ea88d9cb355a..8c760a6c86c2 100644 --- a/common/console.c +++ b/common/console.c @@ -845,8 +845,7 @@ bool console_record_overflow(void) int console_record_readline(char *str, int maxlen) { - return membuff_readline((struct membuff *)&gd->console_out, str, - maxlen, ' '); + return membuff_readline((struct membuff *)&gd->console_out, str, maxlen, ' ', false); } int console_record_avail(void) diff --git a/include/membuff.h b/include/membuff.h index 21051b0c54ef..4eba626ce1c2 100644 --- a/include/membuff.h +++ b/include/membuff.h @@ -192,10 +192,11 @@ int membuff_free(struct membuff *mb); * @mb: membuff to adjust * @str: Place to put the line * @maxlen: Maximum line length (excluding terminator) + * @must_fit: If true then str is empty if line doesn't fit * Return: number of bytes read (including terminator) if a line has been - * read, 0 if nothing was there + * read, 0 if nothing was there or line didn't fit when must_fit is set */ -int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch); +int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit); /** * membuff_extend_by() - expand a membuff diff --git a/lib/membuff.c b/lib/membuff.c index 36dc43a523fb..964e504d5b06 100644 --- a/lib/membuff.c +++ b/lib/membuff.c @@ -288,7 +288,7 @@ int membuff_free(struct membuff *mb) (mb->end - mb->start) - 1 - membuff_avail(mb); } -int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch) +int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch, bool must_fit) { int len; /* number of bytes read (!= string length) */ char *s, *end; @@ -310,7 +310,7 @@ int membuff_readline(struct membuff *mb, char *str, int maxlen, int minch) } /* couldn't get the whole string */ - if (!ok) { + if (!ok && must_fit) { if (maxlen) *orig = '\0'; return 0; From 04e3f2f40f0c18112d38d278b59876a69fa0e9d6 Mon Sep 17 00:00:00 2001 From: Ion Agorria Date: Wed, 17 Aug 2022 19:44:17 +0200 Subject: [PATCH 29/45] fastboot: add oem console and oem cmd --- drivers/fastboot/Kconfig | 15 ++++++ drivers/fastboot/fb_command.c | 98 +++++++++++++++++++++++++++++++++++ include/fastboot.h | 6 +++ 3 files changed, 119 insertions(+) diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig index b97c67bf6094..cf37004b2d95 100644 --- a/drivers/fastboot/Kconfig +++ b/drivers/fastboot/Kconfig @@ -218,6 +218,21 @@ config FASTBOOT_CMD_OEM_BOOTBUS Add support for the "oem bootbus" command from a client. This set the mmc boot configuration for the selecting eMMC device. +config FASTBOOT_CMD_OEM_CONSOLE + bool "Enable the 'oem console' command" + depends on CONSOLE_RECORD + help + Add support for the "oem console" command to input and read console + record buffer. + +config FASTBOOT_CMD_OEM_CMD + bool "Enable the 'oem cmd' command" + help + Add support for the "oem cmd" command to run a command and read + console record buffer if is enabled. Be aware that you provide full + access to any U-Boot command, including working with memory and may + open a huge backdoor when enabling this option. + endif # FASTBOOT endmenu diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c index 08387b46becd..0f019758b3b1 100644 --- a/drivers/fastboot/fb_command.c +++ b/drivers/fastboot/fb_command.c @@ -48,6 +48,12 @@ static void oem_partconf(char *, char *); #if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS) static void oem_bootbus(char *, char *); #endif +#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_CONSOLE) +static void oem_console(char *, char *); +#endif +#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_CMD) +static void oem_cmd(char *, char *); +#endif #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) static void run_ucmd(char *, char *); @@ -122,6 +128,18 @@ static const struct { .dispatch = oem_bootbus, }, #endif +#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_CONSOLE) + [FASTBOOT_COMMAND_OEM_CONSOLE] = { + .command = "oem console", + .dispatch = oem_console, + }, +#endif +#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_CMD) + [FASTBOOT_COMMAND_OEM_CMD] = { + .command = "oem cmd", + .dispatch = oem_cmd, + }, +#endif #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) [FASTBOOT_COMMAND_UCMD] = { .command = "UCmd", @@ -173,6 +191,33 @@ void fastboot_multiresponse(int cmd, char *response) case FASTBOOT_COMMAND_GETVAR: fastboot_getvar_all(response); break; +#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_CONSOLE) || CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_CMD) + case FASTBOOT_COMMAND_OEM_CONSOLE: + case FASTBOOT_COMMAND_OEM_CMD: + { +#ifdef CONFIG_CONSOLE_RECORD + char buf[FASTBOOT_RESPONSE_LEN] = { 0 }; + if (console_record_isempty()) { + //Flush the console records to empty buffer + console_record_reset(); + //We are done here + fastboot_okay(NULL, response); + break; + } else { + int ret = console_record_readline(buf, sizeof(buf) - 5); + if (ret < 0) { + fastboot_fail("Error reading console", response); + } else { + fastboot_response("INFO", response, "%s", buf); + } + } +#else + //Shouldn't reach here anyway + fastboot_okay(NULL, response); +#endif + break; + } +#endif default: fastboot_fail("Unknown multiresponse command", response); break; @@ -526,3 +571,56 @@ static void oem_bootbus(char *cmd_parameter, char *response) fastboot_okay(NULL, response); } #endif + +#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_CONSOLE) +/** + * oem_console() - Execute the OEM console command + * + * @cmd_parameter: Pointer to command parameter + * @response: Pointer to fastboot response buffer + */ +static void oem_console(char *cmd_parameter, char *response) +{ + if (cmd_parameter) { + console_in_puts(cmd_parameter); + } + + if (console_record_isempty()) { + fastboot_fail("Empty console", response); + } else { + fastboot_response("MORE", response, NULL); + } +} +#endif + +#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_CMD) +/** + * oem_cmd() - Execute the OEM cmd command + * + * @cmd_parameter: Pointer to command parameter + * @response: Pointer to fastboot response buffer + */ +static void oem_cmd(char *cmd_parameter, char *response) +{ + if (!cmd_parameter) { + fastboot_fail("No command was provided", response); + return; + } + + if (run_command(cmd_parameter, 0)) { + fastboot_fail("Error running command", response); + return; + } + + //Return console if recording or just OK +#ifdef CONFIG_CONSOLE_RECORD + if (console_record_isempty()) { + fastboot_okay(NULL, response); + } else { + fastboot_response("MORE", response, NULL); + } +#else + fastboot_okay(NULL, response); +#endif +} +#endif diff --git a/include/fastboot.h b/include/fastboot.h index 46a0183fcac2..980e7bff22bd 100644 --- a/include/fastboot.h +++ b/include/fastboot.h @@ -44,6 +44,12 @@ enum { #if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_BOOTBUS) FASTBOOT_COMMAND_OEM_BOOTBUS, #endif +#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_CONSOLE) + FASTBOOT_COMMAND_OEM_CONSOLE, +#endif +#if CONFIG_IS_ENABLED(FASTBOOT_CMD_OEM_CMD) + FASTBOOT_COMMAND_OEM_CMD, +#endif #if CONFIG_IS_ENABLED(FASTBOOT_UUU_SUPPORT) FASTBOOT_COMMAND_ACMD, FASTBOOT_COMMAND_UCMD, From 8300a5f4b1ca78e432b5b11b9139113d0e1404bd Mon Sep 17 00:00:00 2001 From: Dmitry Osipenko Date: Sat, 16 Oct 2021 14:40:12 +0300 Subject: [PATCH 30/45] Tegra: Support Tegra20 QEMU board Add device-tree and config for Tegra20 QEMU. Link: https://github.com/grate-driver/tegra2_qemu Signed-off-by: Dmitry Osipenko --- arch/arm/dts/Makefile | 1 + arch/arm/dts/tegra20-qemu.dts | 121 ++++++++++++++++++++++++++++++++++ configs/qemu_tegra2_defconfig | 52 +++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 arch/arm/dts/tegra20-qemu.dts create mode 100644 configs/qemu_tegra2_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 43951a7731ea..7df44a6cdda5 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -214,6 +214,7 @@ dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ tegra20-trimslice.dtb \ tegra20-ventana.dtb \ tegra20-colibri.dtb \ + tegra20-qemu.dtb \ tegra30-apalis.dtb \ tegra30-beaver.dtb \ tegra30-cardhu.dtb \ diff --git a/arch/arm/dts/tegra20-qemu.dts b/arch/arm/dts/tegra20-qemu.dts new file mode 100644 index 000000000000..0d11f5f80d9b --- /dev/null +++ b/arch/arm/dts/tegra20-qemu.dts @@ -0,0 +1,121 @@ +/dts-v1/; + +// /memreserve/ 0x2E600000 0x11A00000; /* for Tegra2VDE-reTool */ + +#include +#include "tegra20.dtsi" + +/ { + model = "Tegra20 QEMU"; + compatible = "grate,qemu", "nvidia,tegra20"; + + memory@0 { + reg = <0x00000000 0x40000000>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + rtc0 = "/rtc@7000e000"; + serial0 = &uartd; + usb0 = "/usb@c5000000"; + usb2 = "/usb@c5008000"; + mmc0 = "/sdhci@c8000600"; + }; + + host1x@50000000 { + dc@54200000 { + rgb { + status = "okay"; + + nvidia,panel = <&panel>; + }; + }; + }; + + pmc@7000e400 { + nvidia,invert-interrupt; + nvidia,suspend-mode = <1>; + nvidia,cpu-pwr-good-time = <2000>; + nvidia,cpu-pwr-off-time = <100>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <458>; + nvidia,sys-clock-req-active-high; + core-supply = <&vdd_core>; + }; + + serial@70006300 { + status = "okay"; + }; + + panel: panel { + compatible = "chunghwa,claa101wa01a"; + + power-supply = <&vdd_pnl_reg>; + }; + + clk32k_in: clock-32k { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + sdhci@c8000600 { + status = "okay"; + bus-width = <4>; + non-removable; + }; + + usb@c5000000 { + status = "okay"; + }; + + usb-phy@c5000000 { + status = "okay"; + }; + + usb@c5008000 { + status = "okay"; + }; + + usb-phy@c5008000 { + status = "okay"; + }; + + vdd_3v3_reg: regulator-0 { + compatible = "regulator-fixed"; + regulator-name = "vdd_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vdd_pnl_reg: regulator-1 { + compatible = "regulator-fixed"; + regulator-name = "vdd_pnl"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + + vdd_core: regulator-2 { + compatible = "regulator-fixed"; + regulator-name = "vdd_core"; + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + }; + + ethernet@a0000000 { + compatible = "smsc,lan9118", "smsc,lan9115"; + reg = <0xa0000000 0x10000>; + interrupts = ; + phy-mode = "mii"; + reg-io-width = <4>; + smsc,irq-active-high; + smsc,irq-push-pull; + vdd33a-supply = <&vdd_3v3_reg>; + vddvario-supply = <&vdd_3v3_reg>; + }; +}; diff --git a/configs/qemu_tegra2_defconfig b/configs/qemu_tegra2_defconfig new file mode 100644 index 000000000000..c1758c2d57e7 --- /dev/null +++ b/configs/qemu_tegra2_defconfig @@ -0,0 +1,52 @@ +CONFIG_ARM=y +CONFIG_ARCH_TEGRA=y +CONFIG_SUPPORT_PASSING_ATAGS=y +CONFIG_SETUP_MEMORY_TAGS=y +CONFIG_SYS_TEXT_BASE=0x00110000 +CONFIG_NR_DRAM_BANKS=2 +CONFIG_ENV_SIZE=0x2000 +CONFIG_ENV_OFFSET=0xFFFFE000 +CONFIG_DEFAULT_DEVICE_TREE="tegra20-qemu" +CONFIG_SPL_TEXT_BASE=0x00108000 +CONFIG_TEGRA20=y +CONFIG_TARGET_VENTANA=y +CONFIG_SYS_LOAD_ADDR=0x1000000 +CONFIG_OF_SYSTEM_SETUP=y +CONFIG_USE_PREBOOT=y +CONFIG_SYS_PROMPT="Tegra20 (QEMU) # " +# CONFIG_CMD_IMI is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_MMC=y +CONFIG_CMD_USB=y +# CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_NFS is not set +CONFIG_CMD_PMIC=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_SPL_DM=y +CONFIG_DM_PMIC=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_PWM_TEGRA=y +CONFIG_SYS_NS16550=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_HOST_ETHER=y +CONFIG_USB_ETHER_ASIX=y +CONFIG_DM_VIDEO=y +# CONFIG_VIDEO_BPP8 is not set +CONFIG_VIDEO_TEGRA20=y +CONFIG_CONSOLE_SCROLL_LINES=10 +CONFIG_DM_ETH=y +CONFIG_SMC911X=y +CONFIG_SMC911X_32_BIT=y From 6d621e8b11df48ed4259c22a73b606709a9d0e75 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Thu, 27 Jan 2022 19:42:04 +0200 Subject: [PATCH 31/45] asus: add transformer t20 board support Board derives from Ventana board. Signed-off-by: Svyatoslav Ryhel --- arch/arm/dts/tegra20-asus-transformer.dtsi | 648 +++++++++++++++++++ arch/arm/mach-tegra/tegra20/Kconfig | 5 + board/asus/transformer-t20/Kconfig | 12 + board/asus/transformer-t20/MAINTAINERS | 6 + board/asus/transformer-t20/Makefile | 9 + board/asus/transformer-t20/transformer-t20.c | 118 ++++ configs/transformer_t20_defconfig | 78 +++ include/configs/transformer-common.h | 234 +++++++ include/configs/transformer-t20.h | 56 ++ 9 files changed, 1166 insertions(+) create mode 100644 arch/arm/dts/tegra20-asus-transformer.dtsi create mode 100644 board/asus/transformer-t20/Kconfig create mode 100644 board/asus/transformer-t20/MAINTAINERS create mode 100644 board/asus/transformer-t20/Makefile create mode 100644 board/asus/transformer-t20/transformer-t20.c create mode 100644 configs/transformer_t20_defconfig create mode 100644 include/configs/transformer-common.h create mode 100644 include/configs/transformer-t20.h diff --git a/arch/arm/dts/tegra20-asus-transformer.dtsi b/arch/arm/dts/tegra20-asus-transformer.dtsi new file mode 100644 index 000000000000..400cc4aee382 --- /dev/null +++ b/arch/arm/dts/tegra20-asus-transformer.dtsi @@ -0,0 +1,648 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "tegra20.dtsi" + +#include +#include + +/ { + compatible = "asus,transformer", "nvidia,tegra20"; + + chosen { + stdout-path = &uartd; + }; + + aliases { + i2c0 = &pmic_i2c; + + mmc0 = &sdmmc4; /* eMMC */ + mmc1 = &sdmmc3; /* MicroSD */ + + rtc0 = &pmic; + rtc1 = "/rtc@7000e000"; + + usb0 = &usb1; + usb1 = &usb3; /* Dock USB */ + }; + + memory { + device_type = "memory"; + reg = <0x00000000 0x40000000>; + }; + + host1x@50000000 { + status = "okay"; + dc@54200000 { + status = "okay"; + rgb { + status = "okay"; + + nvidia,panel = <&panel>; + + display-timings { + timing@0 { + clock-frequency = <71200000>; + hactive = <1280>; + vactive = <800>; + hfront-porch = <8>; + hback-porch = <18>; + hsync-len = <184>; + vsync-len = <3>; + vfront-porch = <4>; + vback-porch = <8>; + hsync-active = <1>; + }; + }; + }; + }; + }; + + pinmux@70000014 { + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pinmux { + ata { + nvidia,pins = "ata"; + nvidia,function = "ide"; + }; + atb { + nvidia,pins = "atb", "gma", "gme"; + nvidia,function = "sdio4"; + }; + atc { + nvidia,pins = "atc"; + nvidia,function = "nand"; + }; + atd { + nvidia,pins = "atd", "ate", "gmb", "spia", + "spib", "spic"; + nvidia,function = "gmi"; + }; + cdev1 { + nvidia,pins = "cdev1"; + nvidia,function = "plla_out"; + }; + cdev2 { + nvidia,pins = "cdev2"; + nvidia,function = "pllp_out4"; + }; + crtp { + nvidia,pins = "crtp", "lm1"; + nvidia,function = "crt"; + }; + csus { + nvidia,pins = "csus"; + nvidia,function = "vi_sensor_clk"; + }; + dap1 { + nvidia,pins = "dap1"; + nvidia,function = "dap1"; + }; + dap2 { + nvidia,pins = "dap2"; + nvidia,function = "dap2"; + }; + dap3 { + nvidia,pins = "dap3"; + nvidia,function = "dap3"; + }; + dap4 { + nvidia,pins = "dap4"; + nvidia,function = "dap4"; + }; + dta { + nvidia,pins = "dta", "dtb", "dtc", "dtd", "dte"; + nvidia,function = "vi"; + }; + dtf { + nvidia,pins = "dtf"; + nvidia,function = "i2c3"; + }; + gmc { + nvidia,pins = "gmc"; + nvidia,function = "uartd"; + }; + gmd { + nvidia,pins = "gmd"; + nvidia,function = "sflash"; + }; + gpu { + nvidia,pins = "gpu"; + nvidia,function = "pwm"; + }; + gpu7 { + nvidia,pins = "gpu7"; + nvidia,function = "rtck"; + }; + gpv { + nvidia,pins = "gpv", "slxa", "slxk"; + nvidia,function = "pcie"; + }; + hdint { + nvidia,pins = "hdint"; + nvidia,function = "hdmi"; + }; + i2cp { + nvidia,pins = "i2cp"; + nvidia,function = "i2cp"; + }; + irrx { + nvidia,pins = "irrx", "irtx"; + nvidia,function = "uartb"; + }; + kbca { + nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd", + "kbce", "kbcf"; + nvidia,function = "kbc"; + }; + lcsn { + nvidia,pins = "lcsn", "ldc", "lm0", "lpw1", + "lsdi", "lvp0"; + nvidia,function = "rsvd4"; + }; + 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", "lhs", "lpp", "lpw0", + "lpw2", "lsc0", "lsc1", "lsck", "lsda", + "lspi", "lvp1", "lvs"; + nvidia,function = "displaya"; + }; + owc { + nvidia,pins = "owc", "spdi", "spdo", "uac"; + nvidia,function = "rsvd2"; + }; + pmc { + nvidia,pins = "pmc"; + nvidia,function = "pwr_on"; + }; + rm { + nvidia,pins = "rm"; + nvidia,function = "i2c1"; + }; + sdb { + nvidia,pins = "sdb", "sdc", "sdd", "slxc"; + nvidia,function = "sdio3"; + }; + sdio1 { + nvidia,pins = "sdio1"; + nvidia,function = "sdio1"; + }; + slxd { + nvidia,pins = "slxd"; + nvidia,function = "spdif"; + }; + spid { + nvidia,pins = "spid", "spie", "spif"; + nvidia,function = "spi1"; + }; + spig { + nvidia,pins = "spig", "spih"; + nvidia,function = "spi2_alt"; + }; + uaa { + nvidia,pins = "uaa", "uab", "uda"; + nvidia,function = "ulpi"; + }; + uad { + nvidia,pins = "uad"; + nvidia,function = "irda"; + }; + uca { + nvidia,pins = "uca", "ucb"; + nvidia,function = "uartc"; + }; + conf_ata { + nvidia,pins = "ata", "atb", "atc", "atd", + "cdev1", "cdev2", "dap1", "dap2", + "dap4", "ddc", "dtf", "gma", "gmc", + "gme", "gpu", "gpu7", "i2cp", "irrx", + "irtx", "pta", "rm", "sdc", "sdd", + "slxc", "slxd", "slxk", "spdi", "spdo", + "uac", "uad", "uca", "ucb", "uda"; + nvidia,pull = ; + nvidia,tristate = ; + }; + conf_ate { + nvidia,pins = "ate", "csus", "dap3", "gmd", + "gpv", "owc", "spia", "spib", "spic", + "spid", "spie", "spig"; + nvidia,pull = ; + nvidia,tristate = ; + }; + conf_ck32 { + nvidia,pins = "ck32", "ddrc", "pmca", "pmcb", + "pmcc", "pmcd", "pmce", "xm2c", "xm2d"; + nvidia,pull = ; + }; + conf_crtp { + nvidia,pins = "crtp", "gmb", "slxa", "spih"; + nvidia,pull = ; + nvidia,tristate = ; + }; + conf_dta { + nvidia,pins = "dta", "dtb", "dtc", "dtd"; + nvidia,pull = ; + nvidia,tristate = ; + }; + conf_dte { + nvidia,pins = "dte", "spif"; + nvidia,pull = ; + nvidia,tristate = ; + }; + conf_hdint { + nvidia,pins = "hdint", "lcsn", "ldc", "lm1", + "lpw1", "lsck", "lsda", "lsdi", "lvp0"; + nvidia,tristate = ; + }; + conf_kbca { + nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd", + "kbce", "kbcf", "sdio1", "uaa", "uab"; + nvidia,pull = ; + nvidia,tristate = ; + }; + conf_lc { + nvidia,pins = "lc", "ls"; + nvidia,pull = ; + }; + 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", "lhs", "lm0", "lpp", + "lpw0", "lpw2", "lsc0", "lsc1", "lspi", + "lvp1", "lvs", "pmc", "sdb"; + nvidia,tristate = ; + }; + conf_ld17_0 { + nvidia,pins = "ld17_0", "ld19_18", "ld21_20", + "ld23_22"; + nvidia,pull = ; + }; + drive_sdio1 { + nvidia,pins = "drive_sdio1"; + 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 = ; + }; + }; + + state_i2cmux_ddc: pinmux_i2cmux_ddc { + ddc { + nvidia,pins = "ddc"; + nvidia,function = "i2c2"; + }; + pta { + nvidia,pins = "pta"; + nvidia,function = "rsvd4"; + }; + }; + + state_i2cmux_pta: pinmux_i2cmux_pta { + ddc { + nvidia,pins = "ddc"; + nvidia,function = "rsvd4"; + }; + pta { + nvidia,pins = "pta"; + nvidia,function = "i2c2"; + }; + }; + + state_i2cmux_idle: pinmux_i2cmux_idle { + ddc { + nvidia,pins = "ddc"; + nvidia,function = "rsvd4"; + }; + pta { + nvidia,pins = "pta"; + nvidia,function = "rsvd4"; + }; + }; + }; + + uartd: serial@70006300 { + status = "okay"; + clock-frequency = <216000000>; + }; + + pwm: pwm@7000a000 { + status = "okay"; + }; + + i2c@7000c000 { + status = "okay"; + clock-frequency = <400000>; + }; + + i2c2: i2c@7000c400 { + status = "okay"; + clock-frequency = <100000>; + }; + + i2cmux { + compatible = "i2c-mux-pinctrl"; + #address-cells = <1>; + #size-cells = <0>; + + i2c-parent = <&i2c2>; + + pinctrl-names = "ddc", "pta", "idle"; + pinctrl-0 = <&state_i2cmux_ddc>; + pinctrl-1 = <&state_i2cmux_pta>; + pinctrl-2 = <&state_i2cmux_idle>; + + hdmi_ddc: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + lvds_ddc: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + + i2c@7000c500 { + status = "okay"; + clock-frequency = <400000>; + }; + + pmic_i2c: i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + pmic: tps6586x@34 { + compatible = "ti,tps6586x"; + reg = <0x34>; + interrupts = ; + + ti,system-power-controller; + + #gpio-cells = <2>; + gpio-controller; + + sys-supply = <&vdd_5v0_reg>; + vin-sm0-supply = <&sys_reg>; + vin-sm1-supply = <&sys_reg>; + vin-sm2-supply = <&sys_reg>; + vinldo01-supply = <&sm2_reg>; + vinldo23-supply = <&sm2_reg>; + vinldo4-supply = <&sm2_reg>; + vinldo678-supply = <&sm2_reg>; + vinldo9-supply = <&sm2_reg>; + + regulators { + sys_reg: sys { + regulator-name = "vdd_sys"; + regulator-always-on; + }; + + sm0 { + regulator-name = "vdd_sm0,vdd_core"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + }; + + sm1 { + regulator-name = "vdd_sm1,vdd_cpu"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-always-on; + }; + + sm2_reg: sm2 { + regulator-name = "vdd_sm2,vin_ldo*"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + regulator-always-on; + }; + + /* LDO0 is not connected to anything */ + + ldo1 { + regulator-name = "vdd_ldo1,avdd_pll*"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-always-on; + }; + + ldo2 { + regulator-name = "vdd_ldo2,vdd_rtc"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + ldo3 { + regulator-name = "vdd_ldo3,avdd_usb*"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + ldo4 { + regulator-name = "vdd_ldo4,avdd_osc,vddio_sys"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + ldo5 { + regulator-name = "vdd_ldo5,vcore_mmc"; + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2850000>; + regulator-always-on; + }; + + ldo6 { + regulator-name = "vdd_ldo6,avdd_vdac"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + hdmi_vdd_reg: ldo7 { + regulator-name = "vdd_ldo7,avdd_hdmi,vdd_fuse"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + hdmi_pll_reg: ldo8 { + regulator-name = "vdd_ldo8,avdd_hdmi_pll"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + ldo9 { + regulator-name = "vdd_ldo9,avdd_2v85,vdd_ddr_rx"; + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2850000>; + regulator-always-on; + }; + + ldo_rtc { + regulator-name = "vdd_rtc_out,vdd_cell"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + }; + }; + + pmc@7000e400 { + nvidia,invert-interrupt; + nvidia,suspend-mode = <1>; + nvidia,cpu-pwr-good-time = <2000>; + nvidia,cpu-pwr-off-time = <100>; + nvidia,core-pwr-good-time = <3845 3845>; + nvidia,core-pwr-off-time = <458>; + nvidia,sys-clock-req-active-high; + }; + + /* USB via ASUS connector */ + usb1: usb@c5000000 { + status = "okay"; + dr_mode = "otg"; + }; + + /* Dock's USB port */ + usb3: usb@c5008000 { + status = "okay"; + }; + + sdmmc3: sdhci@c8000400 { + status = "okay"; + bus-width = <4>; + + cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; + wp-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>; + power-gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_HIGH>; + }; + + sdmmc4: sdhci@c8000600 { + status = "okay"; + bus-width = <8>; + non-removable; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + + enable-gpios = <&gpio TEGRA_GPIO(D, 4) GPIO_ACTIVE_HIGH>; + power-supply = <&vdd_bl_reg>; + pwms = <&pwm 2 5000000>; + + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + clk32k_in: clock@0 { + compatible = "fixed-clock"; + reg=<0>; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + + gpio-keyboard { + compatible = "gpio-kbd"; + + power { + label = "Power"; + gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-up { + label = "Volume Up"; + gpios = <&gpio TEGRA_GPIO(Q, 5) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-down { + label = "Volume Down"; + gpios = <&gpio TEGRA_GPIO(Q, 4) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + panel: panel { + compatible = "simple-panel"; + + power-supply = <&vdd_pnl_reg>; + enable-gpios = <&gpio TEGRA_GPIO(B, 2) GPIO_ACTIVE_HIGH>; + + backlight = <&backlight>; + ddc-i2c-bus = <&lvds_ddc>; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + vdd_5v0_reg: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "vdd_5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "vdd_1v5"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; + gpio = <&pmic 0 GPIO_ACTIVE_HIGH>; + }; + + regulator@2 { + compatible = "regulator-fixed"; + reg = <2>; + regulator-name = "vdd_1v2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + gpio = <&pmic 1 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_pnl_reg: regulator@3 { + compatible = "regulator-fixed"; + reg = <3>; + regulator-name = "vdd_pnl"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + gpio = <&gpio TEGRA_GPIO(C, 6) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_bl_reg: regulator@4 { + compatible = "regulator-fixed"; + reg = <4>; + regulator-name = "vdd_bl"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + gpio = <&gpio TEGRA_GPIO(W, 0) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; +}; diff --git a/arch/arm/mach-tegra/tegra20/Kconfig b/arch/arm/mach-tegra/tegra20/Kconfig index 5644edbea950..dbdc08d51aa9 100644 --- a/arch/arm/mach-tegra/tegra20/Kconfig +++ b/arch/arm/mach-tegra/tegra20/Kconfig @@ -28,6 +28,10 @@ config TARGET_TEC bool "Avionic Design Tamonten Evaluation Carrier" select BOARD_LATE_INIT +config TARGET_TRANSFORMER_T20 + bool "Asus Tegra20 Transformer board" + select BOARD_LATE_INIT + config TARGET_TRIMSLICE bool "Compulab TrimSlice board" select BOARD_LATE_INIT @@ -50,6 +54,7 @@ config TEGRA_LP0 select TEGRA_CRYPTO default n +source "board/asus/transformer-t20/Kconfig" source "board/nvidia/harmony/Kconfig" source "board/avionic-design/medcom-wide/Kconfig" source "board/compal/paz00/Kconfig" diff --git a/board/asus/transformer-t20/Kconfig b/board/asus/transformer-t20/Kconfig new file mode 100644 index 000000000000..d5fe41282897 --- /dev/null +++ b/board/asus/transformer-t20/Kconfig @@ -0,0 +1,12 @@ +if TARGET_TRANSFORMER_T20 + +config SYS_BOARD + default "transformer-t20" + +config SYS_VENDOR + default "asus" + +config SYS_CONFIG_NAME + default "transformer-t20" + +endif diff --git a/board/asus/transformer-t20/MAINTAINERS b/board/asus/transformer-t20/MAINTAINERS new file mode 100644 index 000000000000..a957925dcdef --- /dev/null +++ b/board/asus/transformer-t20/MAINTAINERS @@ -0,0 +1,6 @@ +TF101 BOARD +M: Svyatoslav Ryhel +S: Maintained +F: board/asus/transformer-t20/ +F: include/configs/transformer-t20.h +F: configs/transformer_t20_defconfig diff --git a/board/asus/transformer-t20/Makefile b/board/asus/transformer-t20/Makefile new file mode 100644 index 000000000000..03e0af75e14a --- /dev/null +++ b/board/asus/transformer-t20/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# (C) Copyright 2010,2011 +# NVIDIA Corporation +# +# (C) Copyright 2021 +# Svyatoslav Ryhel + +obj-y := transformer-t20.o diff --git a/board/asus/transformer-t20/transformer-t20.c b/board/asus/transformer-t20/transformer-t20.c new file mode 100644 index 000000000000..1442f39d6e12 --- /dev/null +++ b/board/asus/transformer-t20/transformer-t20.c @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2010,2011 + * NVIDIA Corporation + * + * (C) Copyright 2021 + * Svyatoslav Ryhel + */ + +/* T20 Transformers derive from Ventana board */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_TEGRA_CRYPTO +#include +#include "uboot_aes.h" +#endif + +#define PMU_I2C_ADDRESS 0x34 + +#define TPS6586X_SUPPLYENE 0x14 +#define EXITSLREQ_BIT BIT(1) +#define SLEEP_MODE_BIT BIT(3) + +#ifdef CONFIG_CMD_POWEROFF +int do_poweroff(struct cmd_tbl *cmdtp, + int flag, int argc, char *const argv[]) +{ + struct udevice *dev; + uchar data_buffer[1]; + int ret; + + ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); + if (ret) { + debug("%s: Cannot find PMIC I2C chip\n", __func__); + return 0; + } + + ret = dm_i2c_read(dev, TPS6586X_SUPPLYENE, data_buffer, 1); + if (ret) + return ret; + + data_buffer[0] &= ~EXITSLREQ_BIT; + + ret = dm_i2c_write(dev, TPS6586X_SUPPLYENE, data_buffer, 1); + if (ret) + return ret; + + data_buffer[0] |= SLEEP_MODE_BIT; + + ret = dm_i2c_write(dev, TPS6586X_SUPPLYENE, data_buffer, 1); + if (ret) + return ret; + + // wait some time and then print error + mdelay(5000); + printf("Failed to power off!!!\n"); + return 1; +} +#endif + +#ifdef CONFIG_TEGRA_CRYPTO +/* + * Pass sbk for boards where it is common + */ +void get_secure_key(u8 *key) +{ + /* SBK1 support only for now! */ + u8 sbk[AES128_KEY_LENGTH] = { + 0x16, 0x82, 0xCC, 0xD8, 0x8A, 0x1A, 0x43, 0xEA, + 0xA5, 0x32, 0xEE, 0xB6, 0xEC, 0xFE, 0x1D, 0x98 + }; + + memcpy(key, sbk, AES128_KEY_LENGTH); +} +#endif + +#ifdef CONFIG_MMC_SDHCI_TEGRA +/* + * Routine: pin_mux_mmc + * Description: setup the pin muxes/tristate values for the SDMMC(s) + */ +void pin_mux_mmc(void) +{ + funcmux_select(PERIPH_ID_SDMMC4, FUNCMUX_SDMMC4_ATB_GMA_GME_8_BIT); + funcmux_select(PERIPH_ID_SDMMC3, FUNCMUX_SDMMC3_SDB_4BIT); + + /* For power GPIO PI6 */ + pinmux_tristate_disable(PMUX_PINGRP_ATA); + /* For CD GPIO PI5 */ + pinmux_tristate_disable(PMUX_PINGRP_ATC); +} +#endif + +void pin_mux_usb(void) +{ + /* For USB0's GPIO PD0. For now, since we have no pinmux in fdt */ + pinmux_tristate_disable(PMUX_PINGRP_SLXK); + /* For USB1's ULPI signals */ + funcmux_select(PERIPH_ID_USB2, FUNCMUX_USB2_ULPI); + pinmux_set_func(PMUX_PINGRP_CDEV2, PMUX_FUNC_PLLP_OUT4); + pinmux_tristate_disable(PMUX_PINGRP_CDEV2); + /* USB1 PHY reset GPIO */ + pinmux_tristate_disable(PMUX_PINGRP_UAC); +} diff --git a/configs/transformer_t20_defconfig b/configs/transformer_t20_defconfig new file mode 100644 index 000000000000..ddcdfc5bb236 --- /dev/null +++ b/configs/transformer_t20_defconfig @@ -0,0 +1,78 @@ +CONFIG_ARM=y +CONFIG_SYS_L2CACHE_OFF=y +CONFIG_ARCH_TEGRA=y +CONFIG_SUPPORT_PASSING_ATAGS=y +CONFIG_SETUP_MEMORY_TAGS=y +CONFIG_CMDLINE_TAG=y +CONFIG_INITRD_TAG=y +CONFIG_TEXT_BASE=0x00110000 +CONFIG_NR_DRAM_BANKS=2 +CONFIG_ENV_SIZE=0x3000 +CONFIG_ENV_OFFSET=0xFFFFD000 +CONFIG_DEFAULT_DEVICE_TREE="tegra20-asus-transformer" +CONFIG_SPL_TEXT_BASE=0x00108000 +CONFIG_SYS_PROMPT="Tegra20 (Transformer) # " +CONFIG_TEGRA_CRYPTO=y +CONFIG_TEGRA_LEGACY_PT=y +CONFIG_TEGRA20=y +CONFIG_TARGET_TRANSFORMER_T20=y +CONFIG_SYS_LOAD_ADDR=0x1000000 +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_UART_PHYS=0x70006300 +CONFIG_OF_SYSTEM_SETUP=y +CONFIG_BOOTDELAY=0 +CONFIG_AUTOBOOT_KEYED=y +CONFIG_AUTOBOOT_KEYED_CTRLC=y +CONFIG_SPL_FOOTPRINT_LIMIT=y +CONFIG_SPL_MAX_FOOTPRINT=0x8000 +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_STACK=0xffffc +CONFIG_SYS_SPL_MALLOC=y +CONFIG_HAS_CUSTOM_SPL_MALLOC_START=y +CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x90000 +CONFIG_SYS_SPL_MALLOC_SIZE=0x10000 +CONFIG_SYS_MAXARGS=64 +CONFIG_SYS_PBSIZE=2085 +CONFIG_CMD_BOOTMENU=y +# CONFIG_CMD_IMI is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_MMC=y +CONFIG_CMD_POWEROFF=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_NFS is not set +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_SPL_DM=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x11000000 +CONFIG_FASTBOOT_BUF_SIZE=0x10000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_SYS_I2C_TEGRA=y +CONFIG_GPIO_KEYBOARD=y +CONFIG_DM_PMIC=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_PWM_TEGRA=y +CONFIG_SYS_NS16550=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="ASUS" +CONFIG_USB_GADGET_VENDOR_NUM=0x0b05 +CONFIG_CI_UDC=y +CONFIG_VIDEO=y +# CONFIG_VIDEO_LOGO is not set +# CONFIG_VIDEO_BPP8 is not set +CONFIG_VIDEO_TEGRA20=y diff --git a/include/configs/transformer-common.h b/include/configs/transformer-common.h new file mode 100644 index 000000000000..dafad983471b --- /dev/null +++ b/include/configs/transformer-common.h @@ -0,0 +1,234 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2022, Svyatoslav Ryhel . + */ + +#ifndef __TRANSFORMER_COMMON_H +#define __TRANSFORMER_COMMON_H + +/* High-level configuration options */ +#define CONFIG_TEGRA_BOARD_STRING "ASUS Transformer" + +/* + * SOS and LNX offset is relative to + * mmcblk0 start on both t20 and t30 + */ + +#define TRANSFORMER_T20_EMMC_LAYOUT \ + "bct_addr_r=0x1000000\0" \ + "bct_size=0xFF0\0" \ + "bct_block_size=0x100000\0" \ + "ebt_addr_r=0x1100000\0" \ + "ebt_block_size=0x300000\0" \ + "sos_offset_m=0x1C00\0" \ + "sos_size=0x2800\0" \ + "lnx_offset_m=0x4400\0" \ + "lnx_size=0x4000\0" + +#define TRANSFORMER_T30_EMMC_LAYOUT \ + "spi_size=0x400000\0" \ + "bct_addr_r=0x81000000\0" \ + "bct_size=0x17F0\0" \ + "bct_block_size=0x100000\0" \ + "ebt_addr_r=0x81100000\0" \ + "ebt_block_size=0x300000\0" \ + "sos_offset_m=0x3C00\0" \ + "sos_size=0x4000\0" \ + "lnx_offset_m=0x7C00\0" \ + "lnx_size=0x4000\0" + +#define TRANSFORMER_BOOTZ \ + "bootkernel=bootz ${kernel_addr_r} - ${fdt_addr_r}\0" \ + "bootrdkernel=bootz ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}\0" + +#define TRANSFORMER_BOOT_CUSTOM_KERNEL \ + "boot_custom_kernel=echo Loading DTB;" \ + "load ${dev_type} ${mmcdev}:${mmcpart} ${fdt_addr_r} ${dtb_file};" \ + "echo Loading Kernel;" \ + "load ${dev_type} ${mmcdev}:${mmcpart} ${kernel_addr_r} ${kernel_file};" \ + "echo Loading Initramfs;" \ + "if load ${dev_type} ${mmcdev}:${mmcpart} ${ramdisk_addr_r} ${ramdisk_file};" \ + "then echo Booting Kernel;" \ + "run bootrdkernel;" \ + "else echo Booting Kernel;" \ + "run bootkernel; fi\0" + +#define TRANSFORMER_BOOT_SCRIPT \ + TRANSFORMER_BOOT_CUSTOM_KERNEL \ + "boot_script=echo Loading boot script;" \ + "for i in 1 2 3 4 5 6 7 8 9 10;" \ + "do; if load mmc 1:$i ${scriptaddr} uboot-transformer.bcs;" \ + "then env import -t -r ${scriptaddr} ${filesize};" \ + "run boot_custom_kernel; fi;" \ + "done;" \ + "for i in 1 2 3 4 5 6 7 8 9 10;" \ + "do; if load mmc 0:$i ${scriptaddr} uboot-transformer.bcs;" \ + "then env import -t -r ${scriptaddr} ${filesize};" \ + "run boot_custom_kernel; fi;" \ + "done;" \ + "echo Boot Configuration NOT FOUND!;" \ + "echo Press ANY key to return to bootmenu;" \ + "continue; bootmenu\0" + +#define TRANSFORMER_BOOT_SOS \ + "boot_sos=echo Reading SOS partition;" \ + "mmc dev;" \ + "if mmc read ${kernel_addr_r} ${sos_offset_m} ${sos_size};" \ + "then echo Booting Kernel;" \ + "bootm ${kernel_addr_r};" \ + "else echo Reading SOS failed;" \ + "echo Press ANY key to return to bootmenu;" \ + "continue; bootmenu; fi\0" + +#define TRANSFORMER_BOOT_LNX \ + "boot_lnx=echo Reading LNX partition;" \ + "mmc dev;" \ + "if mmc read ${kernel_addr_r} ${lnx_offset_m} ${lnx_size};" \ + "then echo Booting Kernel;" \ + "bootm ${kernel_addr_r};" \ + "else echo Reading LNX failed;" \ + "echo Press ANY key to return to bootmenu;" \ + "continue; bootmenu; fi\0" + +#define TRANSFORMER_BRICKSAFE_HOOK \ + "bricksafe_hook=echo Loading bricksafe.img;" \ + "if load mmc 1:1 0x81000000 bricksafe.img;" \ + "then echo Restoring bricksafe.img;" \ + "mmc dev 0 1;" \ + "mmc write 0x81000000 0 0x1000;" \ + "mmc dev 0 2;" \ + "mmc write 0x81200000 0 0x1000;" \ + "mmc dev;" \ + "mmc write 0x81400000 0 0x3C00;" \ + "echo Restoration of bricksafe.img completed;" \ + "echo Rebooting...;" \ + "sleep 3;" \ + "reset;" \ + "else echo Reading bricksafe.img;" \ + "mmc dev 0 1;" \ + "mmc read 0x81000000 0 0x1000;" \ + "mmc dev 0 2;" \ + "mmc read 0x81200000 0 0x1000;" \ + "mmc dev;" \ + "mmc read 0x81400000 0 0x3C00;" \ + "if fatwrite mmc 1:1 0x81000000 bricksafe.img 0xB80000;" \ + "then echo bricksafe.img dumped successfully;" \ + "echo Press ANY key to turn off device; continue; poweroff;" \ + "else bricksafe.img dump FAILED! ABORTING...;" \ + "echo Press ANY key to return to bootmenu; continue; bootmenu; fi; fi\0" + +#define TRANSFORMER_FLASH_UBOOT \ + "flash_uboot=echo Preparing RAM;" \ + "mw ${bct_addr_r} 0 0x100000;" \ + "echo Reading BCT;" \ + "mmc dev 0 1;" \ + "mmc read ${bct_addr_r} 0 0x10;" \ + "echo Reading bootloader;" \ + "if load mmc 1:1 ${ebt_addr_r} ${bootloader_file};" \ + "then echo Calculating bootloader size;" \ + "size mmc 1:1 ${bootloader_file};" \ + "ebtupdate ${bct_addr_r} ${ebt_addr_r} ${filesize};" \ + "echo Writing bootloader to eMMC;" \ + "mmc dev 0 1;" \ + "mmc write ${bct_addr_r} 0 0x10;" \ + "mmc dev 0 2;" \ + "mmc write ${ebt_addr_r} 0xC00 0x400;" \ + "mmc dev;" \ + "mmc write 0x81180000 0 0x1400;" \ + "echo Bootloader written successfully;" \ + "echo Press ANY key to reboot device; continue; reset;" \ + "else echo Reading bootloader failed;" \ + "echo Press ANY key to return to bootmenu; continue; bootmenu; fi\0" + +#define TRANSFORMER_FLASH_SPI \ + "update_spi=sf probe 0:1;" \ + "echo Dumping current SPI flash content ...;" \ + "sf read ${bct_addr_r} 0x0 ${spi_size};" \ + "if fatwrite mmc 1:1 ${bct_addr_r} spi-flash-backup.bin ${spi_size};" \ + "then echo SPI flash content was successfully written into spi-flash-backup.bin;" \ + "echo Reading SPI flash binary;" \ + "if load mmc 1:1 ${bct_addr_r} bootloader-update.bin;" \ + "then echo Writing bootloader into SPI flash;" \ + "sf probe 0:1;" \ + "sf update ${bct_addr_r} 0x0 ${spi_size};" \ + "poweroff;" \ + "else echo Preparing RAM;" \ + "mw ${bct_addr_r} 0 0x100000;" \ + "echo Reading BCT;" \ + "sf read ${bct_addr_r} 0x0 ${bct_size};" \ + "echo Reading bootloader;" \ + "if load mmc 1:1 ${ebt_addr_r} ${bootloader_file};" \ + "then echo Calculating bootloader size;" \ + "size mmc 1:1 ${bootloader_file};" \ + "ebtupdate ${bct_addr_r} ${ebt_addr_r} ${filesize};" \ + "echo Writing bootloader into SPI flash;" \ + "sf probe 0:1;" \ + "sf update ${bct_addr_r} 0x0 ${spi_size};" \ + "echo Bootloader written successfully; reset;" \ + "else echo Reading bootloader failed;" \ + "poweroff; fi;" \ + "fi;" \ + "else echo SPI flash backup FAILED! Aborting ...;" \ + "poweroff; fi\0" + +#define TRANSFORMER_REFRESH_USB \ + "refresh_usb=usb start; usb reset; usb tree; usb info;" \ + "echo Press ANY key to return to bootmenu;" \ + "continue; bootmenu\0" + +#define TRANSFORMER_FASTBOOT_ALIAS \ + "fastboot_raw_partition_boot=${lnx_offset_m} ${lnx_size} mmcpart 0\0" \ + "fastboot_raw_partition_recovery=${sos_offset_m} ${sos_size} mmcpart 0\0" \ + "fastboot_partition_alias_system=APP\0" \ + "fastboot_partition_alias_cache=CAC\0" \ + "fastboot_partition_alias_misc=MSC\0" \ + "fastboot_partition_alias_staging=USP\0" \ + "fastboot_partition_alias_vendor=VDR\0" \ + "fastboot_partition_alias_userdata=UDA\0" + +#define TRANSFORMER_BOOTMENU \ + TRANSFORMER_BOOT_SCRIPT \ + TRANSFORMER_BOOT_SOS \ + TRANSFORMER_BOOT_LNX \ + TRANSFORMER_BRICKSAFE_HOOK \ + TRANSFORMER_FLASH_UBOOT \ + TRANSFORMER_FLASH_SPI \ + TRANSFORMER_REFRESH_USB \ + TRANSFORMER_FASTBOOT_ALIAS \ + "bootmenu_0=boot with script=run boot_script\0" \ + "bootmenu_1=boot LNX=run boot_lnx\0" \ + "bootmenu_2=boot SOS=run boot_sos\0" \ + "bootmenu_3=fastboot=echo Starting Fastboot protocol ...; fastboot usb 0; bootmenu\0" \ + "bootmenu_4=bricksafe=run bricksafe_hook\0" \ + "bootmenu_5=update bootloader=run flash_uboot\0" \ + "bootmenu_6=refresh USB=run refresh_usb\0" \ + "bootmenu_7=reboot RCM=enterrcm\0" \ + "bootmenu_8=reboot=reset\0" \ + "bootmenu_9=power off=poweroff\0" \ + "bootmenu_delay=-1\0" + +#define TRANSFORMER_BUTTON_CHECK \ + "check_button=gpio input ${gpio_button}; test $? -eq 0;\0" + +#define TRANSFORMER_DEFAULT_FILESET \ + "kernel_file=vmlinuz\0" \ + "ramdisk_file=uInitrd\0" \ + "bootloader_file=u-boot-dtb-tegra.bin\0" + +#define TRANSFORMER_LOAD_KERNEL \ + "echo Loading Kernel;" \ + "if load mmc ${bootdev}:1 ${kernel_addr_r} ${kernel_file};" \ + "then echo Loading DTB;" \ + "load mmc ${bootdev}:1 ${fdt_addr_r} ${fdtfile};" \ + "fdt addr ${fdt_addr_r};" \ + "fdt rm /firmware;" \ + "fdt rm /reserved-memory/trustzone@bfe00000;" \ + "setenv bootargs console=ttyS0,115200n8 root=/dev/mmcblk${bootdev}p${rootpart} rw gpt;" \ + "echo Loading Initramfs;" \ + "if load mmc ${bootdev}:1 ${ramdisk_addr_r} ${ramdisk_file};" \ + "then echo Booting Kernel;" \ + "run bootrdkernel;" \ + "else echo Booting Kernel;" \ + "run bootkernel; fi;" + +#endif /* __CONFIG_H */ diff --git a/include/configs/transformer-t20.h b/include/configs/transformer-t20.h new file mode 100644 index 000000000000..826abc2e21fb --- /dev/null +++ b/include/configs/transformer-t20.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * (C) Copyright 2010,2011 + * NVIDIA Corporation + * + * (C) Copyright 2022 + * Svyatoslav Ryhel + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +#include "tegra20-common.h" +#include "transformer-common.h" + +#define BOARD_EXTRA_ENV_SETTINGS \ + TRANSFORMER_T20_EMMC_LAYOUT \ + TRANSFORMER_DEFAULT_FILESET \ + TRANSFORMER_BOOTZ \ + TRANSFORMER_BUTTON_CHECK \ + TRANSFORMER_BOOTMENU + +#undef CONFIG_BOOTCOMMAND +#define CONFIG_BOOTCOMMAND \ + "setenv gpio_button 148;" \ + "if run check_button;" \ + "then poweroff; fi;" \ + "setenv gpio_button 132;" \ + "if run check_button;" \ + "then bootmenu;" \ + "else echo Loading from uSD...;" \ + "setenv bootdev 1;" \ + "setenv rootpart 2;" \ + TRANSFORMER_LOAD_KERNEL \ + "else echo Loading from uSD failed!;" \ + "echo Loading from eMMC...;" \ + "setenv bootdev 0;" \ + "setenv rootpart 7;" \ + TRANSFORMER_LOAD_KERNEL \ + "else echo Loading Kernel FAILED! Turning power off;" \ + "poweroff; fi;" \ + "fi;" \ + "fi;" + +/* Board-specific serial config */ +#define CONFIG_TEGRA_ENABLE_UARTD +#define CONFIG_SYS_NS16550_COM1 NV_PA_APB_UARTD_BASE + +/* Used for downstream */ +#define CONFIG_MACH_TYPE MACH_TYPE_VENTANA + +#include "tegra-common-post.h" + +#endif /* __CONFIG_H */ From a870dfeb8c216c9cb59f7d3e8680d0b0291e05f6 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Thu, 27 Jan 2022 19:45:12 +0200 Subject: [PATCH 32/45] asus: transformer: add t20 based device family Includes 3 devices: - Asus Eee Pad Transformer TF101 and TF101G - Asus Eee Pad Slider SL101 Tested-by: Antoni Aloy Torrens # ASUS TF101 Signed-off-by: Svyatoslav Ryhel --- arch/arm/dts/Makefile | 6 +++++- arch/arm/dts/tegra20-asus-sl101.dts | 8 ++++++++ arch/arm/dts/tegra20-asus-tf101.dts | 8 ++++++++ arch/arm/dts/tegra20-asus-tf101g.dts | 8 ++++++++ configs/sl101.config | 2 ++ configs/tf101.config | 2 ++ configs/tf101g.config | 2 ++ 7 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/tegra20-asus-sl101.dts create mode 100644 arch/arm/dts/tegra20-asus-tf101.dts create mode 100644 arch/arm/dts/tegra20-asus-tf101g.dts create mode 100644 configs/sl101.config create mode 100644 configs/tf101.config create mode 100644 configs/tf101g.config diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 7df44a6cdda5..c6310b243bbc 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -205,7 +205,11 @@ dtb-$(CONFIG_ARCH_MESON) += \ meson-sm1-odroid-c4.dtb \ meson-sm1-odroid-hc4.dtb \ meson-sm1-sei610.dtb -dtb-$(CONFIG_ARCH_TEGRA) += tegra20-harmony.dtb \ +dtb-$(CONFIG_ARCH_TEGRA) += \ + tegra20-asus-sl101.dtb \ + tegra20-asus-tf101.dtb \ + tegra20-asus-tf101g.dtb \ + tegra20-harmony.dtb \ tegra20-medcom-wide.dtb \ tegra20-paz00.dtb \ tegra20-plutux.dtb \ diff --git a/arch/arm/dts/tegra20-asus-sl101.dts b/arch/arm/dts/tegra20-asus-sl101.dts new file mode 100644 index 000000000000..68451b8f2072 --- /dev/null +++ b/arch/arm/dts/tegra20-asus-sl101.dts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/dts-v1/; + +#include "tegra20-asus-transformer.dtsi" + +/ { + model = "ASUS EeePad Slider SL101"; +}; diff --git a/arch/arm/dts/tegra20-asus-tf101.dts b/arch/arm/dts/tegra20-asus-tf101.dts new file mode 100644 index 000000000000..a6fb2b1806f1 --- /dev/null +++ b/arch/arm/dts/tegra20-asus-tf101.dts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/dts-v1/; + +#include "tegra20-asus-transformer.dtsi" + +/ { + model = "ASUS EeePad Transformer TF101"; +}; diff --git a/arch/arm/dts/tegra20-asus-tf101g.dts b/arch/arm/dts/tegra20-asus-tf101g.dts new file mode 100644 index 000000000000..8dc345068eb9 --- /dev/null +++ b/arch/arm/dts/tegra20-asus-tf101g.dts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/dts-v1/; + +#include "tegra20-asus-transformer.dtsi" + +/ { + model = "ASUS EeePad Transformer TF101G"; +}; diff --git a/configs/sl101.config b/configs/sl101.config new file mode 100644 index 000000000000..b35c2ed823a2 --- /dev/null +++ b/configs/sl101.config @@ -0,0 +1,2 @@ +CONFIG_DEFAULT_DEVICE_TREE="tegra20-asus-sl101" +CONFIG_USB_GADGET_PRODUCT_NUM=0x4e0f diff --git a/configs/tf101.config b/configs/tf101.config new file mode 100644 index 000000000000..401d96c0f1e0 --- /dev/null +++ b/configs/tf101.config @@ -0,0 +1,2 @@ +CONFIG_DEFAULT_DEVICE_TREE="tegra20-asus-tf101" +CONFIG_USB_GADGET_PRODUCT_NUM=0x4e0f diff --git a/configs/tf101g.config b/configs/tf101g.config new file mode 100644 index 000000000000..b26e400433e1 --- /dev/null +++ b/configs/tf101g.config @@ -0,0 +1,2 @@ +CONFIG_DEFAULT_DEVICE_TREE="tegra20-asus-tf101g" +CONFIG_USB_GADGET_PRODUCT_NUM=0x4e0f From 1ff24b5ac424abf125f456db7a2fff3c01d6a3a3 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Thu, 27 Jan 2022 19:52:55 +0200 Subject: [PATCH 33/45] asus: add transformer t30 board support Board derives from Cardhu board. Signed-off-by: Svyatoslav Ryhel --- arch/arm/dts/tegra30-asus-transformer.dtsi | 84 ++++ arch/arm/mach-tegra/tegra30/Kconfig | 5 + board/asus/transformer-t30/Kconfig | 27 ++ board/asus/transformer-t30/MAINTAINERS | 6 + board/asus/transformer-t30/Makefile | 11 + .../pinmux-config-transformer.h | 396 ++++++++++++++++++ .../transformer-t30/transformer-t30-spl.c | 44 ++ board/asus/transformer-t30/transformer-t30.c | 222 ++++++++++ configs/transformer_t30_defconfig | 79 ++++ include/configs/transformer-t30.h | 73 ++++ 10 files changed, 947 insertions(+) create mode 100644 arch/arm/dts/tegra30-asus-transformer.dtsi create mode 100644 board/asus/transformer-t30/Kconfig create mode 100644 board/asus/transformer-t30/MAINTAINERS create mode 100644 board/asus/transformer-t30/Makefile create mode 100644 board/asus/transformer-t30/pinmux-config-transformer.h create mode 100644 board/asus/transformer-t30/transformer-t30-spl.c create mode 100644 board/asus/transformer-t30/transformer-t30.c create mode 100644 configs/transformer_t30_defconfig create mode 100644 include/configs/transformer-t30.h diff --git a/arch/arm/dts/tegra30-asus-transformer.dtsi b/arch/arm/dts/tegra30-asus-transformer.dtsi new file mode 100644 index 000000000000..eac0e80b7d9c --- /dev/null +++ b/arch/arm/dts/tegra30-asus-transformer.dtsi @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "tegra30.dtsi" + +/ { + compatible = "asus,transformer", "nvidia,tegra30"; + + chosen { + stdout-path = &uarta; + }; + + aliases { + i2c0 = &pmic_i2c; + i2c1 = &lcd_ddc; + + mmc0 = &sdmmc4; /* eMMC */ + mmc1 = &sdmmc1; /* uSD slot */ + + rtc0 = &pmic; + rtc1 = "/rtc@7000e000"; + + usb0 = &usb1; + usb1 = &usb3; /* Dock USB */ + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x40000000>; + }; + + uarta: serial@70006000 { + status = "okay"; + }; + + pwm: pwm@7000a000 { + status = "okay"; + }; + + lcd_ddc: i2c@7000c000 { + status = "okay"; + clock-frequency = <100000>; + }; + + sdmmc1: sdhci@78000000 { + status = "okay"; + bus-width = <4>; + + cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; + power-gpios = <&gpio TEGRA_GPIO(D, 7) GPIO_ACTIVE_HIGH>; + + vmmc-supply = <&vdd_usd>; + vqmmc-supply = <&vddio_usd>; + }; + + sdmmc4: sdhci@78000600 { + status = "okay"; + bus-width = <8>; + non-removable; + }; + + /* USB via ASUS connector */ + usb1: usb@7d000000 { + status = "okay"; + dr_mode = "otg"; + }; + + /* Dock's USB port */ + usb3: usb@7d008000 { + status = "okay"; + }; + + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + clk32k_in: clock@0 { + compatible = "fixed-clock"; + reg = <0>; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; +}; diff --git a/arch/arm/mach-tegra/tegra30/Kconfig b/arch/arm/mach-tegra/tegra30/Kconfig index 85b8ce294f27..229443b3d4f6 100644 --- a/arch/arm/mach-tegra/tegra30/Kconfig +++ b/arch/arm/mach-tegra/tegra30/Kconfig @@ -24,11 +24,16 @@ config TARGET_TEC_NG bool "Avionic Design TEC-NG board" select BOARD_LATE_INIT +config TARGET_TRANSFORMER_T30 + bool "Asus Tegra30 Transformer board" + select BOARD_LATE_INIT + endchoice config SYS_SOC default "tegra30" +source "board/asus/transformer-t30/Kconfig" source "board/toradex/apalis_t30/Kconfig" source "board/nvidia/beaver/Kconfig" source "board/nvidia/cardhu/Kconfig" diff --git a/board/asus/transformer-t30/Kconfig b/board/asus/transformer-t30/Kconfig new file mode 100644 index 000000000000..301844739127 --- /dev/null +++ b/board/asus/transformer-t30/Kconfig @@ -0,0 +1,27 @@ +if TARGET_TRANSFORMER_T30 + +config SYS_BOARD + default "transformer-t30" + +config SYS_VENDOR + default "asus" + +config SYS_CONFIG_NAME + default "transformer-t30" + +config TRANSFORMER_SPI_BOOT + bool "Enable support for SPI based flash" + default n + help + Tegra 3 based Transformers with Windows RT have core + boot sequence (BCT, PT, EBT) on separate SPI FLASH + memory with 4MB size. + +config TRANSFORMER_TF700T_MIPI + bool "Enable support for TF700T MIPI panel configuration" + default n + help + TF700T has different panel configuration then other + Transformers and uses I2C bridge. + +endif diff --git a/board/asus/transformer-t30/MAINTAINERS b/board/asus/transformer-t30/MAINTAINERS new file mode 100644 index 000000000000..7a75a1c4816e --- /dev/null +++ b/board/asus/transformer-t30/MAINTAINERS @@ -0,0 +1,6 @@ +TRANSFORMER BOARD +M: Svyatoslav Ryhel +S: Maintained +F: board/asus/transformer-t30/ +F: include/configs/transformer-t30.h +F: configs/transformer_t30_defconfig diff --git a/board/asus/transformer-t30/Makefile b/board/asus/transformer-t30/Makefile new file mode 100644 index 000000000000..da0682fb5e4e --- /dev/null +++ b/board/asus/transformer-t30/Makefile @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# (C) Copyright 2010-2012 +# NVIDIA Corporation +# +# (C) Copyright 2021 +# Svyatoslav Ryhel + +obj-$(CONFIG_SPL_BUILD) += transformer-t30-spl.o + +obj-y += transformer-t30.o diff --git a/board/asus/transformer-t30/pinmux-config-transformer.h b/board/asus/transformer-t30/pinmux-config-transformer.h new file mode 100644 index 000000000000..c4544b07e901 --- /dev/null +++ b/board/asus/transformer-t30/pinmux-config-transformer.h @@ -0,0 +1,396 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * Copyright (c) 2021, Svyatoslav Ryhel. + */ + +#ifndef _PINMUX_CONFIG_TRANSFORMER_H_ +#define _PINMUX_CONFIG_TRANSFORMER_H_ + +#define DEFAULT_PINMUX(_pingrp, _mux, _pull, _tri, _io) \ + { \ + .pingrp = PMUX_PINGRP_##_pingrp, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ + .tristate = PMUX_TRI_##_tri, \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_DEFAULT, \ + .od = PMUX_PIN_OD_DEFAULT, \ + .ioreset = PMUX_PIN_IO_RESET_DEFAULT, \ + } + +#define I2C_PINMUX(_pingrp, _mux, _pull, _tri, _io, _lock, _od) \ + { \ + .pingrp = PMUX_PINGRP_##_pingrp, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ + .tristate = PMUX_TRI_##_tri, \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_##_lock, \ + .od = PMUX_PIN_OD_##_od, \ + .ioreset = PMUX_PIN_IO_RESET_DEFAULT, \ + } + +#define LV_PINMUX(_pingrp, _mux, _pull, _tri, _io, _lock, _ioreset) \ + { \ + .pingrp = PMUX_PINGRP_##_pingrp, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ + .tristate = PMUX_TRI_##_tri, \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_##_lock, \ + .od = PMUX_PIN_OD_DEFAULT, \ + .ioreset = PMUX_PIN_IO_RESET_##_ioreset \ + } + +#define DEFAULT_PADCFG(_drvgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) \ + { \ + .drvgrp = PMUX_DRVGRP_##_drvgrp, \ + .slwf = _slwf, \ + .slwr = _slwr, \ + .drvup = _drvup, \ + .drvdn = _drvdn, \ + .lpmd = PMUX_LPMD_##_lpmd, \ + .schmt = PMUX_SCHMT_##_schmt, \ + .hsm = PMUX_HSM_##_hsm, \ + } + +static struct pmux_pingrp_config tegra3_pinmux_common[] = { + /* SDMMC1 pinmux */ + DEFAULT_PINMUX(SDMMC1_CLK_PZ0, SDMMC1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_CMD_PZ1, SDMMC1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT3_PY4, SDMMC1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT2_PY5, SDMMC1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT1_PY6, SDMMC1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT0_PY7, SDMMC1, UP, NORMAL, INPUT), + + /* SDMMC3 pinmux */ + DEFAULT_PINMUX(SDMMC3_CLK_PA6, SDMMC3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_CMD_PA7, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT0_PB7, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT1_PB6, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT2_PB5, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT3_PB4, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT6_PD3, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT7_PD4, SDMMC3, UP, NORMAL, INPUT), + + /* SDMMC4 pinmux */ + LV_PINMUX(SDMMC4_CLK_PCC4, SDMMC4, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_CMD_PT7, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT0_PAA0, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT1_PAA1, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT2_PAA2, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT3_PAA3, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT4_PAA4, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT5_PAA5, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT6_PAA6, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT7_PAA7, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_RST_N_PCC3, RSVD1, DOWN, NORMAL, INPUT, DISABLE, DISABLE), + + /* I2C1 pinmux */ + I2C_PINMUX(GEN1_I2C_SCL_PC4, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(GEN1_I2C_SDA_PC5, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* I2C2 pinmux */ + I2C_PINMUX(GEN2_I2C_SCL_PT5, I2C2, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(GEN2_I2C_SDA_PT6, I2C2, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* I2C3 pinmux */ + I2C_PINMUX(CAM_I2C_SCL_PBB1, I2C3, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(CAM_I2C_SDA_PBB2, I2C3, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* I2C4 pinmux */ + I2C_PINMUX(DDC_SCL_PV4, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(DDC_SDA_PV5, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* Power I2C pinmux */ + I2C_PINMUX(PWR_I2C_SCL_PZ6, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(PWR_I2C_SDA_PZ7, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* HDMI-CEC pinmux */ + DEFAULT_PINMUX(HDMI_CEC_PEE3, CEC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(HDMI_INT_PN7, RSVD1, NORMAL, TRISTATE, INPUT), + + /* UART-A pinmux */ + DEFAULT_PINMUX(ULPI_DATA0_PO1, UARTA, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(ULPI_DATA1_PO2, UARTA, DOWN, TRISTATE, INPUT), + DEFAULT_PINMUX(ULPI_DATA2_PO3, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA3_PO4, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA4_PO5, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA5_PO6, UARTA, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(ULPI_DATA6_PO7, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA7_PO0, UARTA, NORMAL, NORMAL, INPUT), + + /* UART-D pinmux */ + DEFAULT_PINMUX(ULPI_CLK_PY0, UARTD, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(ULPI_DIR_PY1, UARTD, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(ULPI_NXT_PY2, UARTD, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(ULPI_STP_PY3, UARTD, NORMAL, TRISTATE, OUTPUT), + + /* DAP3 pinmux */ + DEFAULT_PINMUX(DAP3_FS_PP0, I2S2, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(DAP3_DIN_PP1, I2S2, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(DAP3_DOUT_PP2, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP3_SCLK_PP3, I2S2, NORMAL, NORMAL, INPUT), + + DEFAULT_PINMUX(PV2, RSVD1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PV3, RSVD1, NORMAL, TRISTATE, OUTPUT), + + /* CLK2 pinmux */ + DEFAULT_PINMUX(CLK2_OUT_PW5, EXTPERIPH2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CLK2_REQ_PCC5, DAP, NORMAL, NORMAL, INPUT), + + /* DISPLAY-A pinmux */ + DEFAULT_PINMUX(LCD_PWR1_PC1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_PWR2_PC6, DISPLAYA, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(LCD_SDIN_PZ2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_SDOUT_PN5, DISPLAYA, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(LCD_WR_N_PZ3, DISPLAYA, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(LCD_CS0_N_PN4, DISPLAYA, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(LCD_DC0_PN6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_SCK_PZ4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_PWR0_PB2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_PCLK_PB3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_DE_PJ1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_HSYNC_PJ3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_VSYNC_PJ4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D0_PE0, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D1_PE1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D2_PE2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D3_PE3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D4_PE4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D5_PE5, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D6_PE6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D7_PE7, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D8_PF0, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D9_PF1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D10_PF2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D11_PF3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D12_PF4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D13_PF5, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D14_PF6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D15_PF7, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D16_PM0, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D17_PM1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D18_PM2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D19_PM3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D20_PM4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D21_PM5, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D22_PM6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D23_PM7, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_CS1_N_PW0, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_M1_PW1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_DC1_PD2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CRT_HSYNC_PV6, CRT, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(CRT_VSYNC_PV7, CRT, NORMAL, TRISTATE, OUTPUT), + + /* VI-group pinmux */ + LV_PINMUX(VI_D0_PT4, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D1_PD5, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D2_PL0, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D3_PL1, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D4_PL2, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D5_PL3, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D7_PL5, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D10_PT2, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_MCLK_PT1, VI, UP, NORMAL, INPUT, DISABLE, DISABLE), + + /* UART-B pinmux */ + DEFAULT_PINMUX(UART2_RXD_PC3, UARTB, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART2_TXD_PC2, UARTB, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(UART2_RTS_N_PJ6, UARTB, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(UART2_CTS_N_PJ5, UARTB, NORMAL, NORMAL, INPUT), + + /* UART-C pinmux */ + DEFAULT_PINMUX(UART3_TXD_PW6, UARTC, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(UART3_RXD_PW7, UARTC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART3_CTS_N_PA1, UARTC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART3_RTS_N_PC0, UARTC, NORMAL, NORMAL, OUTPUT), + + /* PU-gpio group pinmux */ + DEFAULT_PINMUX(PU0, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PU1, RSVD1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PU2, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PU3, RSVD1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PU4, RSVD1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(PU5, PWM2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PU6, RSVD1, DOWN, NORMAL, INPUT), + + /* DAP4 pinmux */ + DEFAULT_PINMUX(DAP4_FS_PP4, I2S3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP4_DIN_PP5, I2S3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP4_DOUT_PP6, I2S3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP4_SCLK_PP7, I2S3, NORMAL, NORMAL, INPUT), + + /* CLK3 pinmux */ + DEFAULT_PINMUX(CLK3_OUT_PEE0, EXTPERIPH3, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(CLK3_REQ_PEE1, DEV3, NORMAL, TRISTATE, INPUT), + + /* GMI pinmux */ + DEFAULT_PINMUX(GMI_WP_N_PC7, RSVD1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(GMI_CS2_N_PK3, RSVD1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(GMI_AD8_PH0, PWM0, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_AD10_PH2, NAND, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_A16_PJ7, SPI4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_A17_PB0, SPI4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_A18_PB1, SPI4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_A19_PK7, SPI4, NORMAL, NORMAL, INPUT), + + DEFAULT_PINMUX(CAM_MCLK_PCC0, VI_ALT3, UP, NORMAL, INPUT), + + DEFAULT_PINMUX(PCC1, RSVD1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(PBB0, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PBB3, VGP3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PBB5, VGP5, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PBB6, VGP6, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PBB7, I2S4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PCC2, I2S4, NORMAL, NORMAL, INPUT), + + DEFAULT_PINMUX(JTAG_RTCK_PU7, RTCK, NORMAL, NORMAL, OUTPUT), + + /* KBC keys */ + DEFAULT_PINMUX(KB_ROW0_PR0, RSVD4, UP, NORMAL, OUTPUT), + DEFAULT_PINMUX(KB_ROW1_PR1, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW2_PR2, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW3_PR3, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW4_PR4, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW5_PR5, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW6_PR6, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW7_PR7, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW8_PS0, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW9_PS1, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW10_PS2, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW11_PS3, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW12_PS4, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW13_PS5, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_ROW14_PS6, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW15_PS7, KBC, UP, NORMAL, INPUT), + + DEFAULT_PINMUX(KB_COL0_PQ0, KBC, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(KB_COL1_PQ1, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL2_PQ2, RSVD4, UP, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_COL3_PQ3, RSVD4, UP, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_COL4_PQ4, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_COL5_PQ5, KBC, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(KB_COL6_PQ6, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL7_PQ7, KBC, NORMAL, TRISTATE, INPUT), + + DEFAULT_PINMUX(PV0, RSVD1, UP, TRISTATE, INPUT), + + /* CLK */ + DEFAULT_PINMUX(CLK_32K_OUT_PA0, BLINK, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(SYS_CLK_REQ_PZ5, SYSCLK, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(OWR, OWR, NORMAL, NORMAL, INPUT), + + /* DAP1 pinmux */ + DEFAULT_PINMUX(DAP1_FS_PN0, I2S0, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(DAP1_DIN_PN1, I2S0, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(DAP1_DOUT_PN2, I2S0, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(DAP1_SCLK_PN3, I2S0, NORMAL, TRISTATE, INPUT), + + /* CLK1 pinmux */ + DEFAULT_PINMUX(CLK1_REQ_PEE2, DAP, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CLK1_OUT_PW4, EXTPERIPH1, NORMAL, NORMAL, INPUT), + + /* SPDIF pinmux */ + DEFAULT_PINMUX(SPDIF_IN_PK6, SPDIF, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(SPDIF_OUT_PK5, SPDIF, NORMAL, TRISTATE, OUTPUT), + + /* DAP2 pinmux */ + DEFAULT_PINMUX(DAP2_FS_PA2, I2S1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_DIN_PA4, I2S1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_DOUT_PA5, I2S1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_SCLK_PA3, I2S1, NORMAL, NORMAL, INPUT), + + /* SPI pinmux */ + DEFAULT_PINMUX(SPI2_CS1_N_PW2, SPI2, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SPI1_MOSI_PX4, SPI1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(SPI1_SCK_PX5, SPI1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(SPI1_CS0_N_PX6, SPI1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(SPI1_MISO_PX7, SPI1, NORMAL, TRISTATE, INPUT), + + /* PEX pinmux */ + DEFAULT_PINMUX(PEX_L0_PRSNT_N_PDD0, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L0_RST_N_PDD1, PCIE, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PEX_L0_CLKREQ_N_PDD2, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_WAKE_N_PDD3, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L1_PRSNT_N_PDD4, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L1_RST_N_PDD5, PCIE, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PEX_L1_CLKREQ_N_PDD6, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L2_PRSNT_N_PDD7, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L2_RST_N_PCC6, PCIE, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PEX_L2_CLKREQ_N_PCC7, PCIE, NORMAL, NORMAL, INPUT), + + /* GPIOs */ + /* SDMMC1 CD gpio */ + DEFAULT_PINMUX(GMI_IORDY_PI5, RSVD1, UP, NORMAL, INPUT), + /* SDMMC1 WP gpio */ + LV_PINMUX(VI_D11_PT3, RSVD1, UP, NORMAL, INPUT, DISABLE, DISABLE), + + /* Touch panel GPIO */ + /* Touch IRQ */ + DEFAULT_PINMUX(GMI_AD12_PH4, NAND, UP, NORMAL, INPUT), + + /* Touch RESET */ + DEFAULT_PINMUX(GMI_AD14_PH6, NAND, NORMAL, NORMAL, OUTPUT), + + /* Vibrator control */ + DEFAULT_PINMUX(GMI_AD15_PH7, NAND, DOWN, NORMAL, OUTPUT), + + /* Power rails GPIO */ + DEFAULT_PINMUX(SPI2_SCK_PX2, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PBB4, VGP4, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW8_PS0, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT5_PD0, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT4_PD1, SDMMC3, UP, NORMAL, INPUT), + + LV_PINMUX(VI_D6_PL4, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D8_PL6, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D9_PL7, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_PCLK_PT0, RSVD1, UP, TRISTATE, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_HSYNC_PD7, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_VSYNC_PD6, RSVD1, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), +}; + +#ifdef CONFIG_TRANSFORMER_TF700T_MIPI +static struct pmux_pingrp_config tf700t_mipi_pinmux[] = { + DEFAULT_PINMUX(LCD_PWR2_PC6, DISPLAYA, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(LCD_DC1_PD2, DISPLAYA, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PBB3, VGP3, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PBB7, I2S4, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(SPI2_MOSI_PX0, SPI2, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(KB_ROW7_PR7, KBC, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_CS4_N_PK2, GMI, UP, NORMAL, INPUT), + DEFAULT_PINMUX(CAM_MCLK_PCC0, VI_ALT3, UP, TRISTATE, INPUT), +}; +#endif + +static struct pmux_pingrp_config unused_pins_lowpower[] = { + DEFAULT_PINMUX(GMI_WAIT_PI7, RSVD1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(GMI_ADV_N_PK0, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_CLK_PK1, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_CS3_N_PK4, RSVD1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(GMI_CS7_N_PI6, NAND, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_AD0_PG0, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD1_PG1, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD2_PG2, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD3_PG3, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD4_PG4, NAND, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_AD5_PG5, NAND, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_AD6_PG6, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD7_PG7, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_AD9_PH1, PWM1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_AD11_PH3, NAND, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_AD13_PH5, NAND, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_WR_N_PI0, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_OE_N_PI1, NAND, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(GMI_DQS_PI2, NAND, NORMAL, TRISTATE, OUTPUT), +}; + +static struct pmux_drvgrp_config cardhu_padctrl[] = { + /* (_drvgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) */ + DEFAULT_PADCFG(SDIO1, SDIOCFG_DRVUP_SLWF, SDIOCFG_DRVDN_SLWR, \ + SDIOCFG_DRVUP, SDIOCFG_DRVDN, NONE, DISABLE, DISABLE), +}; +#endif /* _PINMUX_CONFIG_TRANSFORMER_H_ */ diff --git a/board/asus/transformer-t30/transformer-t30-spl.c b/board/asus/transformer-t30/transformer-t30-spl.c new file mode 100644 index 000000000000..a947a31f66ef --- /dev/null +++ b/board/asus/transformer-t30/transformer-t30-spl.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * T30 Transformers SPL stage configuration + * + * (C) Copyright 2010-2013 + * NVIDIA Corporation + * + * (C) Copyright 2021 + * Svyatoslav Ryhel + */ + +#include +#include +#include + +/* I2C addr is in 8 bit */ +#define TPS65911_I2C_ADDR 0x5A +#define TPS65911_VDDCTRL_OP_REG 0x28 +#define TPS65911_VDDCTRL_SR_REG 0x27 +#define TPS65911_VDDCTRL_OP_DATA (0x2400 | TPS65911_VDDCTRL_OP_REG) +#define TPS65911_VDDCTRL_SR_DATA (0x0100 | TPS65911_VDDCTRL_SR_REG) + +#define TPS62361B_I2C_ADDR 0xC0 +#define TPS62361B_SET3_REG 0x03 +#define TPS62361B_SET3_DATA (0x4600 | TPS62361B_SET3_REG) + +void pmic_enable_cpu_vdd(void) +{ + /* Set VDD_CORE to 1.200V. */ + tegra_i2c_ll_write_addr(TPS62361B_I2C_ADDR, 2); + tegra_i2c_ll_write_data(TPS62361B_SET3_DATA, I2C_SEND_2_BYTES); + + udelay(1000); + + /* + * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus. + * First set VDD to 1.0125V, then enable the VDD regulator. + */ + tegra_i2c_ll_write_addr(TPS65911_I2C_ADDR, 2); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_OP_DATA, I2C_SEND_2_BYTES); + udelay(1000); + tegra_i2c_ll_write_data(TPS65911_VDDCTRL_SR_DATA, I2C_SEND_2_BYTES); + udelay(10 * 1000); +} diff --git a/board/asus/transformer-t30/transformer-t30.c b/board/asus/transformer-t30/transformer-t30.c new file mode 100644 index 000000000000..622b40d67d1c --- /dev/null +++ b/board/asus/transformer-t30/transformer-t30.c @@ -0,0 +1,222 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2010-2013 + * NVIDIA Corporation + * + * (C) Copyright 2021 + * Svyatoslav Ryhel + */ + +/* T30 Transformers derive from Cardhu board */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pinmux-config-transformer.h" + +#ifdef CONFIG_TEGRA_CRYPTO +#include +#include "uboot_aes.h" +#endif + +#define PMU_I2C_ADDRESS 0x2D +#define MAX_I2C_RETRY 3 + +#define TPS65911_LDO1 0x30 +#define TPS65911_LDO2 0x31 +#define TPS65911_LDO5 0x32 +#define TPS65911_LDO3 0x37 + +#define TPS65911_GPIO0 0x60 +#define TPS65911_GPIO1 0x61 +#define TPS65911_GPIO2 0x62 +#define TPS65911_GPIO3 0x63 +#define TPS65911_GPIO4 0x64 +#define TPS65911_GPIO5 0x65 +#define TPS65911_GPIO6 0x66 +#define TPS65911_GPIO7 0x67 +#define TPS65911_GPIO8 0x68 + +#define TPS65911_DEVCTRL 0x3F +#define DEVCTRL_PWR_OFF_MASK 0x80 +#define DEVCTRL_DEV_OFF_MASK 0x01 +#define DEVCTRL_DEV_ON_MASK 0x04 + +#ifdef CONFIG_CMD_POWEROFF +int do_poweroff(struct cmd_tbl *cmdtp, + int flag, int argc, char *const argv[]) +{ + struct udevice *dev; + uchar data_buffer[1]; + int ret; + + ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); + if (ret) { + debug("%s: Cannot find PMIC I2C chip\n", __func__); + return 0; + } + + ret = dm_i2c_read(dev, TPS65911_DEVCTRL, data_buffer, 1); + if (ret) + return ret; + + data_buffer[0] |= DEVCTRL_PWR_OFF_MASK; + + ret = dm_i2c_write(dev, TPS65911_DEVCTRL, data_buffer, 1); + if (ret) + return ret; + + data_buffer[0] |= DEVCTRL_DEV_OFF_MASK; + data_buffer[0] &= ~DEVCTRL_DEV_ON_MASK; + + ret = dm_i2c_write(dev, TPS65911_DEVCTRL, data_buffer, 1); + if (ret) + return ret; + + // wait some time and then print error + mdelay(5000); + printf("Failed to power off!!!\n"); + return 1; +} +#endif + +#ifdef CONFIG_TEGRA_CRYPTO +/* + * Pass sbk for boards where it is common + */ +void get_secure_key(u8 *key) +{ + /* SBK is device/board specific, insert your here instead of 0x00 */ + u8 sbk[AES128_KEY_LENGTH] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + memcpy(key, sbk, AES128_KEY_LENGTH); +} +#endif + +/* + * Routine: pinmux_init + * Description: Do individual peripheral pinmux configs + */ +void pinmux_init(void) +{ + pinmux_config_pingrp_table(tegra3_pinmux_common, + ARRAY_SIZE(tegra3_pinmux_common)); + + pinmux_config_pingrp_table(unused_pins_lowpower, + ARRAY_SIZE(unused_pins_lowpower)); + + /* Initialize any non-default pad configs (APB_MISC_GP regs) */ + pinmux_config_drvgrp_table(cardhu_padctrl, ARRAY_SIZE(cardhu_padctrl)); + +#ifdef CONFIG_TRANSFORMER_TF700T_MIPI + pinmux_config_pingrp_table(tf700t_mipi_pinmux, + ARRAY_SIZE(tf700t_mipi_pinmux)); +#endif +} + +#ifdef CONFIG_MMC_SDHCI_TEGRA +/* + * Do I2C/PMU writes to bring up SD card and eMMC bus power + */ +void board_sdmmc_voltage_init(void) +{ + struct udevice *dev; + uchar data_buffer[1]; + int ret; + int i; + + ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, 1, &dev); + if (ret) { + debug("%s: Cannot find PMIC I2C chip\n", __func__); + return; + } + + /* TPS659110: LDO1_REG = 3.3v, ACTIVE to SDMMC4 */ + data_buffer[0] = 0xc9; + + for (i = 0; i < MAX_I2C_RETRY; ++i) { + if (dm_i2c_write(dev, TPS65911_LDO1, data_buffer, 1)) + udelay(100); + } + + /* TPS659110: LDO2_REG = 3.1v, ACTIVE to SDMMC1 */ + data_buffer[0] = 0xb9; + + for (i = 0; i < MAX_I2C_RETRY; ++i) { + if (dm_i2c_write(dev, TPS65911_LDO2, data_buffer, 1)) + udelay(100); + } + + /* TPS659110: LDO3_REG = 3.1v, ACTIVE to SDMMC1 VIO */ + data_buffer[0] = 0x5d; + + for (i = 0; i < MAX_I2C_RETRY; ++i) { + if (dm_i2c_write(dev, TPS65911_LDO3, data_buffer, 1)) + udelay(100); + } + + /* TPS659110: LDO5_REG = 3.3v, ACTIVE to SDMMC1 VIO */ + data_buffer[0] = 0x65; + + for (i = 0; i < MAX_I2C_RETRY; ++i) { + if (dm_i2c_write(dev, TPS65911_LDO5, data_buffer, 1)) + udelay(100); + } + + /* TPS659110: GPIO0_REG output high to VDD_5V0_SBY */ + data_buffer[0] = 0x07; + + for (i = 0; i < MAX_I2C_RETRY; ++i) { + if (dm_i2c_write(dev, TPS65911_GPIO0, data_buffer, 1)) + udelay(100); + } + + /* TPS659110: GPIO6_REG output high to VDD_3V3_SYS */ + data_buffer[0] = 0x07; + + for (i = 0; i < MAX_I2C_RETRY; ++i) { + if (dm_i2c_write(dev, TPS65911_GPIO6, data_buffer, 1)) + udelay(100); + } + + /* TPS659110: GPIO7_REG output high to VDD_1V5_DDR */ + data_buffer[0] = 0x07; + + for (i = 0; i < MAX_I2C_RETRY; ++i) { + if (dm_i2c_write(dev, TPS65911_GPIO7, data_buffer, 1)) + udelay(100); + } + + /* TPS659110: GPIO8_REG pull_down output high to VDD_5V0_SYS */ + data_buffer[0] = 0x0f; + + for (i = 0; i < MAX_I2C_RETRY; ++i) { + if (dm_i2c_write(dev, TPS65911_GPIO8, data_buffer, 1)) + udelay(100); + } +} + +/* + * Routine: pin_mux_mmc + * Description: setup the MMC muxes, power rails, etc. + */ +void pin_mux_mmc(void) +{ + /* + * NOTE: We don't do mmc-specific pin muxes here. + * They were done globally in pinmux_init(). + */ + + /* Bring up uSD and eMMC power */ + board_sdmmc_voltage_init(); +} +#endif /* MMC */ diff --git a/configs/transformer_t30_defconfig b/configs/transformer_t30_defconfig new file mode 100644 index 000000000000..d0f31f2ccb0d --- /dev/null +++ b/configs/transformer_t30_defconfig @@ -0,0 +1,79 @@ +CONFIG_ARM=y +CONFIG_SYS_L2CACHE_OFF=y +CONFIG_ARCH_TEGRA=y +CONFIG_SUPPORT_PASSING_ATAGS=y +CONFIG_SETUP_MEMORY_TAGS=y +CONFIG_CMDLINE_TAG=y +CONFIG_INITRD_TAG=y +CONFIG_TEXT_BASE=0x80110000 +CONFIG_NR_DRAM_BANKS=2 +CONFIG_ENV_SIZE=0x3000 +CONFIG_ENV_OFFSET=0xFFFFD000 +CONFIG_DEFAULT_DEVICE_TREE="tegra30-asus-transformer" +CONFIG_SPL_TEXT_BASE=0x80108000 +CONFIG_SYS_PROMPT="Tegra30 (Transformer) # " +CONFIG_TEGRA_CRYPTO=y +CONFIG_TEGRA_LEGACY_PT=y +CONFIG_TEGRA30=y +CONFIG_TARGET_TRANSFORMER_T30=y +CONFIG_SYS_LOAD_ADDR=0x81000000 +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_UART_PHYS=0x70006000 +CONFIG_OF_SYSTEM_SETUP=y +CONFIG_BOOTDELAY=0 +CONFIG_AUTOBOOT_KEYED=y +CONFIG_AUTOBOOT_KEYED_CTRLC=y +CONFIG_SPL_FOOTPRINT_LIMIT=y +CONFIG_SPL_MAX_FOOTPRINT=0x8000 +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_STACK=0x800ffffc +CONFIG_SYS_SPL_MALLOC=y +CONFIG_HAS_CUSTOM_SPL_MALLOC_START=y +CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x80090000 +CONFIG_SYS_SPL_MALLOC_SIZE=0x10000 +CONFIG_SYS_MAXARGS=64 +CONFIG_SYS_PBSIZE=2084 +CONFIG_CMD_BOOTMENU=y +# CONFIG_CMD_IMI is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_SPI=y +CONFIG_CMD_USB=y +CONFIG_CMD_POWEROFF=y +# CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_NFS is not set +CONFIG_CMD_FS_GENERIC=y +CONFIG_CMD_EXT4_WRITE=y +# CONFIG_SPL_DOS_PARTITION is not set +# CONFIG_SPL_EFI_PARTITION is not set +CONFIG_ENV_OVERWRITE=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_SYS_MMC_ENV_PART=2 +CONFIG_SPL_DM=y +CONFIG_GPIO_KEYBOARD=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x91000000 +CONFIG_FASTBOOT_BUF_SIZE=0x10000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_SYS_I2C_TEGRA=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_GPIO=y +CONFIG_DM_PMIC=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_PWM_TEGRA=y +CONFIG_SYS_NS16550=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_TEGRA=y +CONFIG_USB_KEYBOARD=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="ASUS" +CONFIG_USB_GADGET_VENDOR_NUM=0x0b05 +CONFIG_CI_UDC=y +CONFIG_VIDEO=y +# CONFIG_VIDEO_LOGO is not set +CONFIG_VIDEO_TEGRA20=y diff --git a/include/configs/transformer-t30.h b/include/configs/transformer-t30.h new file mode 100644 index 000000000000..35cdb04f7640 --- /dev/null +++ b/include/configs/transformer-t30.h @@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * (C) Copyright 2010,2012 + * NVIDIA Corporation + * + * (C) Copyright 2022 + * Svyatoslav Ryhel + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +#include "tegra30-common.h" +#include "transformer-common.h" + +#ifdef CONFIG_TRANSFORMER_SPI_BOOT +#define TRANSFORMER_VOLDOWN_ACTION \ + "setenv gpio_button 222;" \ + "if run check_button;" \ + "then poweroff; fi;" \ + "setenv gpio_button 132;" \ + "if run check_button;" \ + "then echo Starting SPI flash update ...;" \ + "run update_spi;" +/* SPI */ +#define CONFIG_TEGRA_SLINK_CTRLS 6 +#define CONFIG_SPI_FLASH_SIZE (4 << 20) +#else +#define TRANSFORMER_VOLDOWN_ACTION \ + "setenv gpio_button 150;" \ + "if run check_button;" \ + "then poweroff; fi;" \ + "setenv gpio_button 131;" \ + "if run check_button;" \ + "then bootmenu;" +#endif + +#define BOARD_EXTRA_ENV_SETTINGS \ + TRANSFORMER_T30_EMMC_LAYOUT \ + TRANSFORMER_DEFAULT_FILESET \ + TRANSFORMER_BOOTZ \ + TRANSFORMER_BUTTON_CHECK \ + TRANSFORMER_BOOTMENU + +#undef CONFIG_BOOTCOMMAND +#define CONFIG_BOOTCOMMAND \ + TRANSFORMER_VOLDOWN_ACTION \ + "else echo Loading from uSD...;" \ + "setenv bootdev 1;" \ + "setenv rootpart 2;" \ + TRANSFORMER_LOAD_KERNEL \ + "else echo Loading from uSD failed!;" \ + "echo Loading from eMMC...;" \ + "setenv bootdev 0;" \ + "setenv rootpart 8;" \ + TRANSFORMER_LOAD_KERNEL \ + "else echo Loading Kernel FAILED! Turning power off;" \ + "poweroff; fi;" \ + "fi;" \ + "fi;" + +/* Board-specific serial config */ +#define CONFIG_TEGRA_ENABLE_UARTA +#define CONFIG_SYS_NS16550_COM1 NV_PA_APB_UARTA_BASE + +/* Used for downstream */ +#define CONFIG_MACH_TYPE MACH_TYPE_CARDHU + +#include "tegra-common-post.h" + +#endif /* __CONFIG_H */ From 97a25a2f03489a78db95eb1a2188c668d685a317 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Thu, 27 Jan 2022 19:54:46 +0200 Subject: [PATCH 34/45] asus: transformer: add t30 based device family Includes 7 ASUS devices: - Transformer Prime TF201 - Transformer Pad TF300T/TF300TG/TF300TL - VivoTab RT TF600T (Windows RT based) - Transformer Infinity TF700T - Transformer AiO P1801-T Tested-by: Andreas Westman Dorcsak # all devices Signed-off-by: Svyatoslav Ryhel --- arch/arm/dts/Makefile | 7 ++ arch/arm/dts/tegra30-asus-p1801-t.dts | 83 ++++++++++++++ arch/arm/dts/tegra30-asus-tf201.dts | 152 ++++++++++++++++++++++++++ arch/arm/dts/tegra30-asus-tf300t.dts | 152 ++++++++++++++++++++++++++ arch/arm/dts/tegra30-asus-tf300tg.dts | 152 ++++++++++++++++++++++++++ arch/arm/dts/tegra30-asus-tf300tl.dts | 152 ++++++++++++++++++++++++++ arch/arm/dts/tegra30-asus-tf600t.dts | 92 ++++++++++++++++ arch/arm/dts/tegra30-asus-tf700t.dts | 115 +++++++++++++++++++ configs/p1801-t.config | 2 + configs/tf201.config | 2 + configs/tf300t.config | 2 + configs/tf300tg.config | 2 + configs/tf300tl.config | 2 + configs/tf600t.config | 7 ++ configs/tf700t.config | 3 + 15 files changed, 925 insertions(+) create mode 100644 arch/arm/dts/tegra30-asus-p1801-t.dts create mode 100644 arch/arm/dts/tegra30-asus-tf201.dts create mode 100644 arch/arm/dts/tegra30-asus-tf300t.dts create mode 100644 arch/arm/dts/tegra30-asus-tf300tg.dts create mode 100644 arch/arm/dts/tegra30-asus-tf300tl.dts create mode 100644 arch/arm/dts/tegra30-asus-tf600t.dts create mode 100644 arch/arm/dts/tegra30-asus-tf700t.dts create mode 100644 configs/p1801-t.config create mode 100644 configs/tf201.config create mode 100644 configs/tf300t.config create mode 100644 configs/tf300tg.config create mode 100644 configs/tf300tl.config create mode 100644 configs/tf600t.config create mode 100644 configs/tf700t.config diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index c6310b243bbc..e3b8a2c07a17 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -220,6 +220,13 @@ dtb-$(CONFIG_ARCH_TEGRA) += \ tegra20-colibri.dtb \ tegra20-qemu.dtb \ tegra30-apalis.dtb \ + tegra30-asus-p1801-t.dtb \ + tegra30-asus-tf201.dtb \ + tegra30-asus-tf300t.dtb \ + tegra30-asus-tf300tg.dtb \ + tegra30-asus-tf300tl.dtb \ + tegra30-asus-tf600t.dtb \ + tegra30-asus-tf700t.dtb \ tegra30-beaver.dtb \ tegra30-cardhu.dtb \ tegra30-colibri.dtb \ diff --git a/arch/arm/dts/tegra30-asus-p1801-t.dts b/arch/arm/dts/tegra30-asus-p1801-t.dts new file mode 100644 index 000000000000..9f3b175e1007 --- /dev/null +++ b/arch/arm/dts/tegra30-asus-p1801-t.dts @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/dts-v1/; + +#include +#include + +#include "tegra30-asus-transformer.dtsi" + +/ { + model = "Asus Transformer AiO P1801-T"; + + pmic_i2c: i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + /* Texas Instruments TPS659110 PMIC */ + pmic: tps65911@2d { + compatible = "ti,tps65911"; + reg = <0x2d>; + + interrupts = ; + #interrupt-cells = <2>; + interrupt-controller; + + ti,system-power-controller; + + #gpio-cells = <2>; + gpio-controller; + + regulators { + /* eMMC VDD */ + vcore_emmc: ldo1 { + regulator-name = "vdd_emmc_core"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + /* uSD slot VDD */ + vdd_usd: ldo2 { + regulator-name = "vdd_usd"; + regulator-min-microvolt = <3100000>; + regulator-max-microvolt = <3100000>; + }; + + /* uSD slot VDDIO */ + vddio_usd: ldo3 { + regulator-name = "vddio_usd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3100000>; + }; + }; + }; + }; + + gpio-keyboard { + compatible = "gpio-kbd"; + + power { + label = "Power"; + gpios = <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-up { + label = "Volume Up"; + gpios = <&gpio TEGRA_GPIO(Q, 2) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-down { + label = "Volume Down"; + gpios = <&gpio TEGRA_GPIO(Q, 3) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + mode { + label = "Mode"; + gpios = <&gpio TEGRA_GPIO(K, 2) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; +}; diff --git a/arch/arm/dts/tegra30-asus-tf201.dts b/arch/arm/dts/tegra30-asus-tf201.dts new file mode 100644 index 000000000000..0d84edf7ceef --- /dev/null +++ b/arch/arm/dts/tegra30-asus-tf201.dts @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/dts-v1/; + +#include +#include + +#include "tegra30-asus-transformer.dtsi" + +/ { + model = "Asus Transformer Prime TF201"; + + host1x@50000000 { + status = "okay"; + dc@54200000 { + status = "okay"; + rgb { + status = "okay"; + + nvidia,panel = <&panel>; + + display-timings { + timing@0 { + /* 1280x800@60Hz */ + clock-frequency = <68000000>; + hactive = <1280>; + vactive = <800>; + hfront-porch = <48>; + hback-porch = <18>; + hsync-len = <30>; + vsync-len = <5>; + vfront-porch = <3>; + vback-porch = <12>; + hsync-active = <1>; + }; + }; + }; + }; + }; + + pmic_i2c: i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + /* Texas Instruments TPS659110 PMIC */ + pmic: tps65911@2d { + compatible = "ti,tps65911"; + reg = <0x2d>; + + interrupts = ; + #interrupt-cells = <2>; + interrupt-controller; + + ti,system-power-controller; + + #gpio-cells = <2>; + gpio-controller; + + regulators { + /* eMMC VDD */ + vcore_emmc: ldo1 { + regulator-name = "vdd_emmc_core"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + /* uSD slot VDD */ + vdd_usd: ldo2 { + regulator-name = "vdd_usd"; + regulator-min-microvolt = <3100000>; + regulator-max-microvolt = <3100000>; + }; + + /* uSD slot VDDIO */ + vddio_usd: ldo3 { + regulator-name = "vddio_usd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3100000>; + }; + }; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + + enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>; + power-supply = <&vdd_5v0_bl>; + pwms = <&pwm 0 4000000>; + + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + + gpio-keyboard { + compatible = "gpio-kbd"; + + power { + label = "Power"; + gpios = <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-up { + label = "Volume Up"; + gpios = <&gpio TEGRA_GPIO(Q, 2) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-down { + label = "Volume Down"; + gpios = <&gpio TEGRA_GPIO(Q, 3) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + panel: panel { + compatible = "simple-panel"; + + power-supply = <&vdd_pnl_reg>; + enable-gpios = <&gpio TEGRA_GPIO(N, 6) GPIO_ACTIVE_HIGH>; + + backlight = <&backlight>; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + vdd_pnl_reg: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "vdd_panel"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio TEGRA_GPIO(W, 1) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_5v0_bl: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "vdd_5v0_bl"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + gpio = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; +}; diff --git a/arch/arm/dts/tegra30-asus-tf300t.dts b/arch/arm/dts/tegra30-asus-tf300t.dts new file mode 100644 index 000000000000..2bfb981e0c5a --- /dev/null +++ b/arch/arm/dts/tegra30-asus-tf300t.dts @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/dts-v1/; + +#include +#include + +#include "tegra30-asus-transformer.dtsi" + +/ { + model = "Asus Transformer Pad TF300T"; + + host1x@50000000 { + status = "okay"; + dc@54200000 { + status = "okay"; + rgb { + status = "okay"; + + nvidia,panel = <&panel>; + + display-timings { + timing@0 { + /* 1280x800@60Hz */ + clock-frequency = <68000000>; + hactive = <1280>; + vactive = <800>; + hfront-porch = <48>; + hback-porch = <18>; + hsync-len = <30>; + vsync-len = <5>; + vfront-porch = <3>; + vback-porch = <12>; + hsync-active = <1>; + }; + }; + }; + }; + }; + + pmic_i2c: i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + /* Texas Instruments TPS659110 PMIC */ + pmic: tps65911@2d { + compatible = "ti,tps65911"; + reg = <0x2d>; + + interrupts = ; + #interrupt-cells = <2>; + interrupt-controller; + + ti,system-power-controller; + + #gpio-cells = <2>; + gpio-controller; + + regulators { + /* eMMC VDD */ + vcore_emmc: ldo1 { + regulator-name = "vdd_emmc_core"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + /* uSD slot VDD */ + vdd_usd: ldo2 { + regulator-name = "vdd_usd"; + regulator-min-microvolt = <3100000>; + regulator-max-microvolt = <3100000>; + }; + + /* uSD slot VDDIO */ + vddio_usd: ldo3 { + regulator-name = "vddio_usd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3100000>; + }; + }; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + + enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>; + power-supply = <&vdd_5v0_bl>; + pwms = <&pwm 0 4000000>; + + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + + gpio-keyboard { + compatible = "gpio-kbd"; + + power { + label = "Power"; + gpios = <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-up { + label = "Volume Up"; + gpios = <&gpio TEGRA_GPIO(Q, 2) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-down { + label = "Volume Down"; + gpios = <&gpio TEGRA_GPIO(Q, 3) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + panel: panel { + compatible = "simple-panel"; + + power-supply = <&vdd_pnl_reg>; + enable-gpios = <&gpio TEGRA_GPIO(N, 6) GPIO_ACTIVE_HIGH>; + + backlight = <&backlight>; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + vdd_pnl_reg: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "vdd_panel"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio TEGRA_GPIO(W, 1) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_5v0_bl: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "vdd_5v0_bl"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + gpio = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; +}; diff --git a/arch/arm/dts/tegra30-asus-tf300tg.dts b/arch/arm/dts/tegra30-asus-tf300tg.dts new file mode 100644 index 000000000000..1366de266de7 --- /dev/null +++ b/arch/arm/dts/tegra30-asus-tf300tg.dts @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/dts-v1/; + +#include +#include + +#include "tegra30-asus-transformer.dtsi" + +/ { + model = "Asus Transformer Pad 3G TF300TG"; + + host1x@50000000 { + status = "okay"; + dc@54200000 { + status = "okay"; + rgb { + status = "okay"; + + nvidia,panel = <&panel>; + + display-timings { + timing@0 { + /* 1280x800@60Hz */ + clock-frequency = <68000000>; + hactive = <1280>; + vactive = <800>; + hfront-porch = <48>; + hback-porch = <18>; + hsync-len = <30>; + vsync-len = <5>; + vfront-porch = <3>; + vback-porch = <12>; + hsync-active = <1>; + }; + }; + }; + }; + }; + + pmic_i2c: i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + /* Texas Instruments TPS659110 PMIC */ + pmic: tps65911@2d { + compatible = "ti,tps65911"; + reg = <0x2d>; + + interrupts = ; + #interrupt-cells = <2>; + interrupt-controller; + + ti,system-power-controller; + + #gpio-cells = <2>; + gpio-controller; + + regulators { + /* eMMC VDD */ + vcore_emmc: ldo1 { + regulator-name = "vdd_emmc_core"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + /* uSD slot VDD */ + vdd_usd: ldo2 { + regulator-name = "vdd_usd"; + regulator-min-microvolt = <3100000>; + regulator-max-microvolt = <3100000>; + }; + + /* uSD slot VDDIO */ + vddio_usd: ldo3 { + regulator-name = "vddio_usd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3100000>; + }; + }; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + + enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>; + power-supply = <&vdd_5v0_bl>; + pwms = <&pwm 0 4000000>; + + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + + gpio-keyboard { + compatible = "gpio-kbd"; + + power { + label = "Power"; + gpios = <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-up { + label = "Volume Up"; + gpios = <&gpio TEGRA_GPIO(Q, 2) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-down { + label = "Volume Down"; + gpios = <&gpio TEGRA_GPIO(Q, 3) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + panel: panel { + compatible = "simple-panel"; + + power-supply = <&vdd_pnl_reg>; + enable-gpios = <&gpio TEGRA_GPIO(N, 6) GPIO_ACTIVE_HIGH>; + + backlight = <&backlight>; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + vdd_pnl_reg: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "vdd_panel"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio TEGRA_GPIO(W, 1) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_5v0_bl: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "vdd_5v0_bl"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + gpio = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; +}; diff --git a/arch/arm/dts/tegra30-asus-tf300tl.dts b/arch/arm/dts/tegra30-asus-tf300tl.dts new file mode 100644 index 000000000000..b3be2f2fd20f --- /dev/null +++ b/arch/arm/dts/tegra30-asus-tf300tl.dts @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/dts-v1/; + +#include +#include + +#include "tegra30-asus-transformer.dtsi" + +/ { + model = "Asus Transformer Pad LTE TF300TL"; + + host1x@50000000 { + status = "okay"; + dc@54200000 { + status = "okay"; + rgb { + status = "okay"; + + nvidia,panel = <&panel>; + + display-timings { + timing@0 { + /* 1280x800@60Hz */ + clock-frequency = <68000000>; + hactive = <1280>; + vactive = <800>; + hfront-porch = <48>; + hback-porch = <18>; + hsync-len = <30>; + vsync-len = <5>; + vfront-porch = <3>; + vback-porch = <12>; + hsync-active = <1>; + }; + }; + }; + }; + }; + + pmic_i2c: i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + /* Texas Instruments TPS659110 PMIC */ + pmic: tps65911@2d { + compatible = "ti,tps65911"; + reg = <0x2d>; + + interrupts = ; + #interrupt-cells = <2>; + interrupt-controller; + + ti,system-power-controller; + + #gpio-cells = <2>; + gpio-controller; + + regulators { + /* eMMC VDD */ + vcore_emmc: ldo1 { + regulator-name = "vdd_emmc_core"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + /* uSD slot VDD */ + vdd_usd: ldo2 { + regulator-name = "vdd_usd"; + regulator-min-microvolt = <3100000>; + regulator-max-microvolt = <3100000>; + }; + + /* uSD slot VDDIO */ + vddio_usd: ldo3 { + regulator-name = "vddio_usd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3100000>; + }; + }; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + + enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>; + power-supply = <&vdd_5v0_bl>; + pwms = <&pwm 0 4000000>; + + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + + gpio-keyboard { + compatible = "gpio-kbd"; + + power { + label = "Power"; + gpios = <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-up { + label = "Volume Up"; + gpios = <&gpio TEGRA_GPIO(Q, 2) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-down { + label = "Volume Down"; + gpios = <&gpio TEGRA_GPIO(Q, 3) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + panel: panel { + compatible = "simple-panel"; + + power-supply = <&vdd_pnl_reg>; + enable-gpios = <&gpio TEGRA_GPIO(N, 6) GPIO_ACTIVE_HIGH>; + + backlight = <&backlight>; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + vdd_pnl_reg: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "vdd_panel"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio TEGRA_GPIO(W, 1) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_5v0_bl: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "vdd_5v0_bl"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + gpio = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; +}; diff --git a/arch/arm/dts/tegra30-asus-tf600t.dts b/arch/arm/dts/tegra30-asus-tf600t.dts new file mode 100644 index 000000000000..779104bd73b3 --- /dev/null +++ b/arch/arm/dts/tegra30-asus-tf600t.dts @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/dts-v1/; + +#include +#include + +#include "tegra30-asus-transformer.dtsi" + +/ { + model = "ASUS VivoTab RT TF600T"; + + aliases { + spi0 = &spi4; + }; + + pmic_i2c: i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + /* Texas Instruments TPS659110 PMIC */ + pmic: tps65911@2d { + compatible = "ti,tps65911"; + reg = <0x2d>; + + interrupts = ; + #interrupt-cells = <2>; + interrupt-controller; + + ti,system-power-controller; + + #gpio-cells = <2>; + gpio-controller; + + regulators { + /* uSD slot VDDIO */ + vddio_usd: ldo5 { + regulator-name = "vddio_sdmmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + }; + }; + + spi4: spi@7000da00 { + status = "okay"; + spi-max-frequency = <25000000>; + + spi-flash@1 { + compatible = "winbond,w25q32", "jedec,spi-nor"; + reg = <1>; + spi-max-frequency = <20000000>; + }; + }; + + gpio-keyboard { + compatible = "gpio-kbd"; + + power { + label = "Power"; + gpios = <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-up { + label = "Volume Up"; + gpios = <&gpio TEGRA_GPIO(Q, 3) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-down { + label = "Volume Down"; + gpios = <&gpio TEGRA_GPIO(Q, 4) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + vdd_usd: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "vdd_usd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + }; +}; diff --git a/arch/arm/dts/tegra30-asus-tf700t.dts b/arch/arm/dts/tegra30-asus-tf700t.dts new file mode 100644 index 000000000000..0d74c45fdfba --- /dev/null +++ b/arch/arm/dts/tegra30-asus-tf700t.dts @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/dts-v1/; + +#include +#include + +#include "tegra30-asus-transformer.dtsi" + +/ { + model = "Asus Transformer Infinity TF700T"; + + pmic_i2c: i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + /* Texas Instruments TPS659110 PMIC */ + pmic: tps65911@2d { + compatible = "ti,tps65911"; + reg = <0x2d>; + + interrupts = ; + #interrupt-cells = <2>; + interrupt-controller; + + ti,system-power-controller; + + #gpio-cells = <2>; + gpio-controller; + + regulators { + /* eMMC VDD */ + vcore_emmc: ldo1 { + regulator-name = "vdd_emmc_core"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + /* uSD slot VDD */ + vdd_usd: ldo2 { + regulator-name = "vdd_usd"; + regulator-min-microvolt = <3100000>; + regulator-max-microvolt = <3100000>; + }; + + /* uSD slot VDDIO */ + vddio_usd: ldo3 { + regulator-name = "vddio_usd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3100000>; + }; + }; + }; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + + enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>; + power-supply = <&vdd_5v0_bl>; + pwms = <&pwm 0 4000000>; + + brightness-levels = <0 4 8 16 32 64 128 255>; + default-brightness-level = <6>; + }; + + gpio-keyboard { + compatible = "gpio-kbd"; + + power { + label = "Power"; + gpios = <&gpio TEGRA_GPIO(V, 0) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-up { + label = "Volume Up"; + gpios = <&gpio TEGRA_GPIO(Q, 2) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + volume-down { + label = "Volume Down"; + gpios = <&gpio TEGRA_GPIO(Q, 3) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + vdd_pnl_reg: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "vdd_panel"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio TEGRA_GPIO(W, 1) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_5v0_bl: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "vdd_5v0_bl"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + gpio = <&gpio TEGRA_GPIO(H, 3) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; +}; diff --git a/configs/p1801-t.config b/configs/p1801-t.config new file mode 100644 index 000000000000..fab2912132c2 --- /dev/null +++ b/configs/p1801-t.config @@ -0,0 +1,2 @@ +CONFIG_DEFAULT_DEVICE_TREE="tegra30-asus-p1801-t" +CONFIG_USB_GADGET_PRODUCT_NUM=0x4cb0 diff --git a/configs/tf201.config b/configs/tf201.config new file mode 100644 index 000000000000..296743b77484 --- /dev/null +++ b/configs/tf201.config @@ -0,0 +1,2 @@ +CONFIG_DEFAULT_DEVICE_TREE="tegra30-asus-tf201" +CONFIG_USB_GADGET_PRODUCT_NUM=0x4d00 diff --git a/configs/tf300t.config b/configs/tf300t.config new file mode 100644 index 000000000000..32a92fe76fa0 --- /dev/null +++ b/configs/tf300t.config @@ -0,0 +1,2 @@ +CONFIG_DEFAULT_DEVICE_TREE="tegra30-asus-tf300t" +CONFIG_USB_GADGET_PRODUCT_NUM=0x4d00 diff --git a/configs/tf300tg.config b/configs/tf300tg.config new file mode 100644 index 000000000000..1396294f6de9 --- /dev/null +++ b/configs/tf300tg.config @@ -0,0 +1,2 @@ +CONFIG_DEFAULT_DEVICE_TREE="tegra30-asus-tf300tg" +CONFIG_USB_GADGET_PRODUCT_NUM=0x4c80 diff --git a/configs/tf300tl.config b/configs/tf300tl.config new file mode 100644 index 000000000000..3db033c8df4a --- /dev/null +++ b/configs/tf300tl.config @@ -0,0 +1,2 @@ +CONFIG_DEFAULT_DEVICE_TREE="tegra30-asus-tf300tl" +CONFIG_USB_GADGET_PRODUCT_NUM=0x4d00 diff --git a/configs/tf600t.config b/configs/tf600t.config new file mode 100644 index 000000000000..e0b33dcdae84 --- /dev/null +++ b/configs/tf600t.config @@ -0,0 +1,7 @@ +CONFIG_DEFAULT_DEVICE_TREE="tegra30-asus-tf600t" +# CONFIG_TEGRA_LEGACY_PT is not set +CONFIG_TRANSFORMER_SPI_BOOT=y +CONFIG_USB_GADGET_PRODUCT_NUM=0x4d00 +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_TEGRA20_SLINK=y diff --git a/configs/tf700t.config b/configs/tf700t.config new file mode 100644 index 000000000000..79bacf3bb5f0 --- /dev/null +++ b/configs/tf700t.config @@ -0,0 +1,3 @@ +CONFIG_DEFAULT_DEVICE_TREE="tegra30-asus-tf700t" +CONFIG_TRANSFORMER_TF700T_MIPI=y +CONFIG_USB_GADGET_PRODUCT_NUM=0x4c90 From 1fbe0ab9a22a341ae7d6715065790c3b63676957 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Sun, 10 Jul 2022 16:51:58 +0300 Subject: [PATCH 35/45] lg: x3: Optimus 4X HD and Optimus Vu support Signed-off-by: Svyatoslav Ryhel --- arch/arm/dts/Makefile | 2 + arch/arm/dts/tegra30-lge-p880.dts | 68 +++++ arch/arm/dts/tegra30-lge-p895.dts | 82 +++++ arch/arm/dts/tegra30-lge-x3.dtsi | 169 +++++++++++ arch/arm/mach-tegra/tegra30/Kconfig | 5 + board/lg/x3-t30/Kconfig | 26 ++ board/lg/x3-t30/MAINTAINERS | 6 + board/lg/x3-t30/Makefile | 11 + board/lg/x3-t30/pinmux-config-x3.h | 449 ++++++++++++++++++++++++++++ board/lg/x3-t30/x3-late.c | 160 ++++++++++ board/lg/x3-t30/x3-t30-spl.c | 53 ++++ board/lg/x3-t30/x3-t30.c | 188 ++++++++++++ configs/p880.config | 4 + configs/p895.config | 4 + configs/x3_t30_defconfig | 84 ++++++ include/configs/x3-t30.h | 203 +++++++++++++ 16 files changed, 1514 insertions(+) create mode 100644 arch/arm/dts/tegra30-lge-p880.dts create mode 100644 arch/arm/dts/tegra30-lge-p895.dts create mode 100644 arch/arm/dts/tegra30-lge-x3.dtsi create mode 100644 board/lg/x3-t30/Kconfig create mode 100644 board/lg/x3-t30/MAINTAINERS create mode 100644 board/lg/x3-t30/Makefile create mode 100644 board/lg/x3-t30/pinmux-config-x3.h create mode 100644 board/lg/x3-t30/x3-late.c create mode 100644 board/lg/x3-t30/x3-t30-spl.c create mode 100644 board/lg/x3-t30/x3-t30.c create mode 100644 configs/p880.config create mode 100644 configs/p895.config create mode 100644 configs/x3_t30_defconfig create mode 100644 include/configs/x3-t30.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index e3b8a2c07a17..f203319b8ea9 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -230,6 +230,8 @@ dtb-$(CONFIG_ARCH_TEGRA) += \ tegra30-beaver.dtb \ tegra30-cardhu.dtb \ tegra30-colibri.dtb \ + tegra30-lge-p880.dtb \ + tegra30-lge-p895.dtb \ tegra30-tec-ng.dtb \ tegra114-dalmore.dtb \ tegra124-apalis.dtb \ diff --git a/arch/arm/dts/tegra30-lge-p880.dts b/arch/arm/dts/tegra30-lge-p880.dts new file mode 100644 index 000000000000..1db361084873 --- /dev/null +++ b/arch/arm/dts/tegra30-lge-p880.dts @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/dts-v1/; + +#include "tegra30-lge-x3.dtsi" + +/ { + model = "LG Optimus 4X HD"; + compatible = "lge,p880", "nvidia,tegra30"; + + aliases { + mmc1 = &sdmmc3; /* uSD slot */ + }; + + host1x@50000000 { + status = "okay"; + dc@54200000 { + status = "okay"; + rgb { + status = "okay"; + + nvidia,panel = <&bridge>; + + display-timings { + timing@0 { + /* 1280x720@60Hz */ + clock-frequency = <68000000>; + hactive = <720>; + vactive = <1280>; + hfront-porch = <92>; + hback-porch = <62>; + hsync-len = <4>; + vsync-len = <1>; + vfront-porch = <6>; + vback-porch = <3>; + }; + }; + }; + }; + }; + + sdmmc3: sdhci@78000400 { + status = "okay"; + bus-width = <4>; + + cd-gpios = <&gpio TEGRA_GPIO(W, 5) GPIO_ACTIVE_LOW>; + + vmmc-supply = <&vdd_usd>; + vqmmc-supply = <&vdd_1v8_vio>; + }; + + gpio-keyboard { + key-volume-up { + label = "Volume Up"; + gpios = <&gpio TEGRA_GPIO(O, 7) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + panel: panel { + compatible = "jdi,dx12d100vm0eaa"; + + enable-gpios = <&gpio TEGRA_GPIO(Y, 0) GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio TEGRA_GPIO(W, 0) GPIO_ACTIVE_HIGH>; + + backlight = <&backlight>; + bridge-spi = <&spi_bus>; + }; +}; diff --git a/arch/arm/dts/tegra30-lge-p895.dts b/arch/arm/dts/tegra30-lge-p895.dts new file mode 100644 index 000000000000..a17261059b77 --- /dev/null +++ b/arch/arm/dts/tegra30-lge-p895.dts @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/dts-v1/; + +#include "tegra30-lge-x3.dtsi" + +/ { + model = "LG Optimus Vu"; + compatible = "lge,p895", "nvidia,tegra30"; + + host1x@50000000 { + status = "okay"; + dc@54200000 { + status = "okay"; + rgb { + status = "okay"; + + nvidia,panel = <&bridge>; + + display-timings { + timing@0 { + /* 1024x768@60Hz */ + clock-frequency = <62000000>; + hactive = <768>; + vactive = <1024>; + hfront-porch = <116>; + hback-porch = <81>; + hsync-len = <5>; + vsync-len = <2>; + vfront-porch = <24>; + vback-porch = <8>; + }; + }; + }; + }; + }; + + gpio-keyboard { + key-volume-up { + label = "Volume Up"; + gpios = <&gpio TEGRA_GPIO(I, 6) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + panel: panel { + compatible = "hitachi,tx13d100vm0eaa"; + + reset-gpios = <&gpio TEGRA_GPIO(W, 0) GPIO_ACTIVE_HIGH>; + + vcc-supply = <&vcc_3v0_lcd>; + iovcc-supply = <&iovcc_1v8_lcd>; + + backlight = <&backlight>; + bridge-spi = <&spi_bus>; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + vcc_3v0_lcd: regulator@0 { + compatible = "regulator-fixed"; + reg = <0>; + regulator-name = "vcc_3v0_lcd"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + gpio = <&gpio TEGRA_GPIO(BB, 0) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + iovcc_1v8_lcd: regulator@1 { + compatible = "regulator-fixed"; + reg = <1>; + regulator-name = "iovcc_1v8_lcd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&gpio TEGRA_GPIO(Y, 0) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + }; +}; diff --git a/arch/arm/dts/tegra30-lge-x3.dtsi b/arch/arm/dts/tegra30-lge-x3.dtsi new file mode 100644 index 000000000000..261382994136 --- /dev/null +++ b/arch/arm/dts/tegra30-lge-x3.dtsi @@ -0,0 +1,169 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include + +#include "tegra30.dtsi" + +/ { + chosen { + stdout-path = &uartd; + }; + + aliases { + i2c0 = &pwr_i2c; + i2c1 = &gen2_i2c; + + mmc0 = &sdmmc4; /* eMMC */ + + rtc0 = &pmic; + rtc1 = "/rtc@7000e000"; + + spi0 = &dsi_spi; + + usb0 = µ_usb; + }; + + memory { + device_type = "memory"; + reg = <0x80000000 0x40000000>; + }; + + uartd: serial@70006300 { + status = "okay"; + }; + + gen2_i2c: i2c@7000c400 { + status = "okay"; + clock-frequency = <400000>; + + backlight: lm3533@36 { + compatible = "ti,lm3533"; + reg = <0x36>; + + enable-gpios = <&gpio TEGRA_GPIO(N, 6) GPIO_ACTIVE_HIGH>; + }; + + muic@44 { + compatible = "maxim,max14526-muic"; + reg = <0x44>; + + maxim,ap-usb; + + usif-gpios = <&gpio TEGRA_GPIO(Y, 3) GPIO_ACTIVE_HIGH>; + dp2t-gpios = <&gpio TEGRA_GPIO(CC, 2) GPIO_ACTIVE_HIGH>; + }; + }; + + pwr_i2c: i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + pmic: max77663@1c { + compatible = "maxim,max77663"; + reg = <0x1c>; + + interrupts = ; + #interrupt-cells = <2>; + interrupt-controller; + + #gpio-cells = <2>; + gpio-controller; + + system-power-controller; + + regulators { + vdd_1v8_vio: sd2 { + regulator-name = "vdd_1v8_gen"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_usd: ldo3 { + regulator-name = "vdd_sdmmc3"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + }; + + vcore_emmc: ldo5 { + regulator-name = "vdd_ddr_rx"; + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2850000>; + regulator-always-on; + regulator-boot-on; + }; + }; + }; + }; + + dsi_spi: spi@7000dc00 { + status = "okay"; + spi-max-frequency = <25000000>; + + spi_bus: bridge-spi@2 { + compatible = "lge,bridge-spi"; + reg = <2>; + + spi-cpol; + spi-cpha; + + spi-max-frequency = <1000000>; + }; + }; + + sdmmc4: sdhci@78000600 { + status = "okay"; + bus-width = <8>; + non-removable; + + vmmc-supply = <&vcore_emmc>; + vqmmc-supply = <&vdd_1v8_vio>; + }; + + micro_usb: usb@7d000000 { + status = "okay"; + dr_mode = "otg"; + }; + + clocks { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <0>; + + clk32k_in: clock@0 { + compatible = "fixed-clock"; + reg = <0>; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + }; + + gpio-keyboard { + compatible = "gpio-kbd"; + + key-power { + label = "Power"; + gpios = <&gpio TEGRA_GPIO(C, 7) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + + key-volume-down { + label = "Volume Down"; + gpios = <&gpio TEGRA_GPIO(O, 4) GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + bridge: bridge { + compatible = "solomon,ssd2825"; + + enable-gpios = <&gpio TEGRA_GPIO(B, 1) GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio TEGRA_GPIO(O, 2) GPIO_ACTIVE_HIGH>; + + panel = <&panel>; + }; +}; diff --git a/arch/arm/mach-tegra/tegra30/Kconfig b/arch/arm/mach-tegra/tegra30/Kconfig index 229443b3d4f6..dab932c4b54a 100644 --- a/arch/arm/mach-tegra/tegra30/Kconfig +++ b/arch/arm/mach-tegra/tegra30/Kconfig @@ -28,6 +28,10 @@ config TARGET_TRANSFORMER_T30 bool "Asus Tegra30 Transformer board" select BOARD_LATE_INIT +config TARGET_X3_T30 + bool "LG X3 Tegra30 board" + select BOARD_LATE_INIT + endchoice config SYS_SOC @@ -39,5 +43,6 @@ source "board/nvidia/beaver/Kconfig" source "board/nvidia/cardhu/Kconfig" source "board/toradex/colibri_t30/Kconfig" source "board/avionic-design/tec-ng/Kconfig" +source "board/lg/x3-t30/Kconfig" endif diff --git a/board/lg/x3-t30/Kconfig b/board/lg/x3-t30/Kconfig new file mode 100644 index 000000000000..20ea4f5f3243 --- /dev/null +++ b/board/lg/x3-t30/Kconfig @@ -0,0 +1,26 @@ +if TARGET_X3_T30 + +config SYS_BOARD + default "x3-t30" + +config SYS_VENDOR + default "lg" + +config SYS_CONFIG_NAME + default "x3-t30" + +config DEVICE_P880 + bool "Enable support for LG Optimus 4X HD" + default n + help + LG Optimus 4X HD derives from x3 board but has slight + differences. + +config DEVICE_P895 + bool "Enable support for LG Optimus Vu" + default n + help + LG Optimus Vu derives from x3 board but has slight + differences. + +endif diff --git a/board/lg/x3-t30/MAINTAINERS b/board/lg/x3-t30/MAINTAINERS new file mode 100644 index 000000000000..707efe39d474 --- /dev/null +++ b/board/lg/x3-t30/MAINTAINERS @@ -0,0 +1,6 @@ +X3 BOARD +M: Svyatoslav Ryhel +S: Maintained +F: board/lg/x3-t30/ +F: include/configs/x3-t30.h +F: configs/x3_t30_defconfig diff --git a/board/lg/x3-t30/Makefile b/board/lg/x3-t30/Makefile new file mode 100644 index 000000000000..623b3cf2db20 --- /dev/null +++ b/board/lg/x3-t30/Makefile @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# (C) Copyright 2010-2012 +# NVIDIA Corporation +# +# (C) Copyright 2021 +# Svyatoslav Ryhel + +obj-$(CONFIG_SPL_BUILD) += x3-t30-spl.o + +obj-y += x3-t30.o x3-late.o diff --git a/board/lg/x3-t30/pinmux-config-x3.h b/board/lg/x3-t30/pinmux-config-x3.h new file mode 100644 index 000000000000..f5df322324e7 --- /dev/null +++ b/board/lg/x3-t30/pinmux-config-x3.h @@ -0,0 +1,449 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2010-2013, NVIDIA CORPORATION. All rights reserved. + * + * Copyright (c) 2021, Svyatoslav Ryhel. + */ + +#ifndef _PINMUX_CONFIG_X3_H_ +#define _PINMUX_CONFIG_X3_H_ + +#define DEFAULT_PINMUX(_pingrp, _mux, _pull, _tri, _io) \ + { \ + .pingrp = PMUX_PINGRP_##_pingrp, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ + .tristate = PMUX_TRI_##_tri, \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_DEFAULT, \ + .od = PMUX_PIN_OD_DEFAULT, \ + .ioreset = PMUX_PIN_IO_RESET_DEFAULT, \ + } + +#define I2C_PINMUX(_pingrp, _mux, _pull, _tri, _io, _lock, _od) \ + { \ + .pingrp = PMUX_PINGRP_##_pingrp, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ + .tristate = PMUX_TRI_##_tri, \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_##_lock, \ + .od = PMUX_PIN_OD_##_od, \ + .ioreset = PMUX_PIN_IO_RESET_DEFAULT, \ + } + +#define LV_PINMUX(_pingrp, _mux, _pull, _tri, _io, _lock, _ioreset) \ + { \ + .pingrp = PMUX_PINGRP_##_pingrp, \ + .func = PMUX_FUNC_##_mux, \ + .pull = PMUX_PULL_##_pull, \ + .tristate = PMUX_TRI_##_tri, \ + .io = PMUX_PIN_##_io, \ + .lock = PMUX_PIN_LOCK_##_lock, \ + .od = PMUX_PIN_OD_DEFAULT, \ + .ioreset = PMUX_PIN_IO_RESET_##_ioreset \ + } + +static struct pmux_pingrp_config tegra3_x3_pinmux_common[] = { + /* SDMMC1 pinmux */ + DEFAULT_PINMUX(SDMMC1_CLK_PZ0, SDMMC1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_CMD_PZ1, SDMMC1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT3_PY4, SDMMC1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT2_PY5, SDMMC1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT1_PY6, SDMMC1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC1_DAT0_PY7, SDMMC1, UP, NORMAL, INPUT), + + /* SDMMC3 pinmux */ +// DEFAULT_PINMUX(SDMMC3_CLK_PA6, SDMMC3, NORMAL, TRISTATE, INPUT), // device specific +// DEFAULT_PINMUX(SDMMC3_CMD_PA7, SDMMC3, NORMAL, TRISTATE, INPUT), // device specific +// DEFAULT_PINMUX(SDMMC3_DAT0_PB7, RSVD1, NORMAL, TRISTATE, INPUT), // device specific +// DEFAULT_PINMUX(SDMMC3_DAT1_PB6, RSVD1, NORMAL, NORMAL, INPUT), // device specific +// DEFAULT_PINMUX(SDMMC3_DAT2_PB5, RSVD1, NORMAL, TRISTATE, INPUT), // device specific +// DEFAULT_PINMUX(SDMMC3_DAT3_PB4, RSVD1, NORMAL, TRISTATE, INPUT), // device specific +// DEFAULT_PINMUX(SDMMC3_DAT4_PD1, SDMMC3, NORMAL, TRISTATE, INPUT), // device specific +// DEFAULT_PINMUX(SDMMC3_DAT5_PD0, SDMMC3, NORMAL, TRISTATE, INPUT), // device specific +// DEFAULT_PINMUX(SDMMC3_DAT6_PD3, SDMMC3, NORMAL, TRISTATE, INPUT), // device specific +// DEFAULT_PINMUX(SDMMC3_DAT7_PD4, RSVD2, NORMAL, TRISTATE, INPUT), // device specific + + /* SDMMC4 pinmux */ + LV_PINMUX(SDMMC4_CLK_PCC4, SDMMC4, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), +// LV_PINMUX(SDMMC4_CMD_PT7, SDMMC4, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), // device specific + LV_PINMUX(SDMMC4_DAT0_PAA0, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT1_PAA1, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT2_PAA2, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT3_PAA3, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT4_PAA4, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT5_PAA5, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT6_PAA6, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_DAT7_PAA7, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(SDMMC4_RST_N_PCC3, RSVD2, DOWN, NORMAL, INPUT, DISABLE, DISABLE), + + /* I2C1 pinmux */ + I2C_PINMUX(GEN1_I2C_SCL_PC4, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(GEN1_I2C_SDA_PC5, I2C1, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* I2C2 pinmux */ + I2C_PINMUX(GEN2_I2C_SCL_PT5, I2C2, UP, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(GEN2_I2C_SDA_PT6, I2C2, UP, NORMAL, INPUT, DISABLE, ENABLE), + + /* I2C3 pinmux */ + I2C_PINMUX(CAM_I2C_SCL_PBB1, I2C3, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(CAM_I2C_SDA_PBB2, I2C3, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* I2C4 pinmux */ + I2C_PINMUX(DDC_SCL_PV4, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(DDC_SDA_PV5, I2C4, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* Power I2C pinmux */ + I2C_PINMUX(PWR_I2C_SCL_PZ6, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + I2C_PINMUX(PWR_I2C_SDA_PZ7, I2CPWR, NORMAL, NORMAL, INPUT, DISABLE, ENABLE), + + /* HDMI-CEC pinmux */ + DEFAULT_PINMUX(HDMI_CEC_PEE3, CEC, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(HDMI_INT_PN7, RSVD1, NORMAL, TRISTATE, INPUT), + + /* ULPI pinmux */ + DEFAULT_PINMUX(ULPI_DATA0_PO1, SPI3, UP, TRISTATE, OUTPUT), + DEFAULT_PINMUX(ULPI_DATA1_PO2, SPI3, UP, NORMAL, OUTPUT), // LCD_BRIDGE_RESET_N + DEFAULT_PINMUX(ULPI_DATA2_PO3, SPI3, UP, TRISTATE, INPUT), + DEFAULT_PINMUX(ULPI_DATA3_PO4, SPI3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(ULPI_DATA4_PO5, ULPI, UP, NORMAL, INPUT), +// DEFAULT_PINMUX(ULPI_DATA5_PO6, SPI2, UP, TRISTATE, INPUT), // unconfigured +// DEFAULT_PINMUX(ULPI_DATA6_PO7, SPI2, UP, NORMAL, INPUT), // device specific +// DEFAULT_PINMUX(ULPI_DATA7_PO0, SPI2, UP, NORMAL, INPUT), // unconfigured + DEFAULT_PINMUX(ULPI_CLK_PY0, RSVD2, DOWN, NORMAL, OUTPUT), // LCD_EN + DEFAULT_PINMUX(ULPI_DIR_PY1, RSVD2, UP, NORMAL, OUTPUT), + DEFAULT_PINMUX(ULPI_NXT_PY2, RSVD2, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(ULPI_STP_PY3, SPI1, NORMAL, NORMAL, OUTPUT), + + /* DAP3 pinmux */ + DEFAULT_PINMUX(DAP3_FS_PP0, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP3_DIN_PP1, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP3_DOUT_PP2, I2S2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP3_SCLK_PP3, I2S2, NORMAL, NORMAL, INPUT), + + DEFAULT_PINMUX(PV0, RSVD1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(PV1, RSVD1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PV2, OWR, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PV3, RSVD2, DOWN, NORMAL, INPUT), + + /* CLK2 pinmux */ + DEFAULT_PINMUX(CLK2_OUT_PW5, RSVD2, UP, NORMAL, INPUT), + DEFAULT_PINMUX(CLK2_REQ_PCC5, DAP, NORMAL, NORMAL, OUTPUT), + + /* LCD pinmux */ + DEFAULT_PINMUX(LCD_PWR1_PC1, DISPLAYA, NORMAL, NORMAL, OUTPUT), +// DEFAULT_PINMUX(LCD_PWR2_PC6, DISPLAYA, DOWN, TRISTATE, OUTPUT), // unconfigured + DEFAULT_PINMUX(LCD_SDIN_PZ2, SPI5, NORMAL, NORMAL, INPUT), // LCD_RGB_SDI + DEFAULT_PINMUX(LCD_SDOUT_PN5, SPI5, NORMAL, NORMAL, INPUT), // LCD_RGB_SDO + DEFAULT_PINMUX(LCD_WR_N_PZ3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_CS0_N_PN4, SPI5, NORMAL, NORMAL, INPUT), // LCD_RGB_CS + DEFAULT_PINMUX(LCD_DC0_PN6, RSVD3, NORMAL, NORMAL, OUTPUT), // LCD_CP_EN / BL + DEFAULT_PINMUX(LCD_SCK_PZ4, SPI5, NORMAL, NORMAL, INPUT), // LCD_RGB_SCL + DEFAULT_PINMUX(LCD_PWR0_PB2, DISPLAYA, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(LCD_PCLK_PB3, DISPLAYA, NORMAL, NORMAL, INPUT), // LCD_RGB_PCLK + DEFAULT_PINMUX(LCD_DE_PJ1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_HSYNC_PJ3, DISPLAYA, NORMAL, NORMAL, INPUT), // LCD_RGB_HSYNC + DEFAULT_PINMUX(LCD_VSYNC_PJ4, DISPLAYA, NORMAL, NORMAL, INPUT), // LCD_RGB_VSYNC + DEFAULT_PINMUX(LCD_D0_PE0, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D1_PE1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D2_PE2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D3_PE3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D4_PE4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D5_PE5, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D6_PE6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D7_PE7, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D8_PF0, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D9_PF1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D10_PF2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D11_PF3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D12_PF4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D13_PF5, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D14_PF6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D15_PF7, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D16_PM0, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D17_PM1, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D18_PM2, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D19_PM3, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D20_PM4, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D21_PM5, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D22_PM6, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_D23_PM7, DISPLAYA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(LCD_CS1_N_PW0, RSVD4, UP, NORMAL, OUTPUT), // LCD_RESET_N + DEFAULT_PINMUX(LCD_M1_PW1, DISPLAYA, NORMAL, TRISTATE, OUTPUT), // LCD_MAKER_ID + DEFAULT_PINMUX(LCD_DC1_PD2, RSVD3, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(CRT_HSYNC_PV6, RSVD2, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CRT_VSYNC_PV7, RSVD2, NORMAL, NORMAL, INPUT), + + /* VI-group pinmux */ + LV_PINMUX(VI_D0_PT4, RSVD2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D1_PD5, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D2_PL0, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D3_PL1, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D4_PL2, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D5_PL3, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D6_PL4, VI, NORMAL, NORMAL, OUTPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D7_PL5, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D8_PL6, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D9_PL7, SDMMC2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D10_PT2, RSVD2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_D11_PT3, RSVD2, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_PCLK_PT0, RSVD1, UP, TRISTATE, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_MCLK_PT1, VI, UP, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_HSYNC_PD7, RSVD2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + LV_PINMUX(VI_VSYNC_PD6, RSVD2, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + + /* UART-B pinmux */ +// DEFAULT_PINMUX(UART2_RXD_PC3, UARTB, NORMAL, NORMAL, INPUT), // device specific +// DEFAULT_PINMUX(UART2_TXD_PC2, UARTB, NORMAL, NORMAL, OUTPUT), // device specific + DEFAULT_PINMUX(UART2_RTS_N_PJ6, UARTB, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART2_CTS_N_PJ5, UARTB, NORMAL, NORMAL, INPUT), + + /* UART-C pinmux */ + DEFAULT_PINMUX(UART3_TXD_PW6, UARTC, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(UART3_RXD_PW7, UARTC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART3_CTS_N_PA1, UARTC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART3_RTS_N_PC0, UARTC, NORMAL, NORMAL, OUTPUT), + + /* PU-gpio group pinmux */ +// DEFAULT_PINMUX(PU0, UARTA, NORMAL, NORMAL, OUTPUT), // device specific +// DEFAULT_PINMUX(PU1, UARTA, NORMAL, NORMAL, INPUT), // device specific +// DEFAULT_PINMUX(PU2, RSVD1, NORMAL, TRISTATE, INPUT), // device specific +// DEFAULT_PINMUX(PU3, PWM0, NORMAL, TRISTATE, INPUT), // device specific +// DEFAULT_PINMUX(PU4, PWM1, NORMAL, TRISTATE, INPUT), // device specific + DEFAULT_PINMUX(PU5, RSVD4, DOWN, NORMAL, OUTPUT), + DEFAULT_PINMUX(PU6, PWM3, DOWN, NORMAL, INPUT), + + /* DAP4 pinmux */ + DEFAULT_PINMUX(DAP4_FS_PP4, I2S3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP4_DIN_PP5, I2S3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP4_DOUT_PP6, I2S3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP4_SCLK_PP7, I2S3, NORMAL, NORMAL, INPUT), + + /* CLK3 pinmux */ + DEFAULT_PINMUX(CLK3_OUT_PEE0, EXTPERIPH3, NORMAL, NORMAL, OUTPUT), // MIPI_BRIDGE_CLK + DEFAULT_PINMUX(CLK3_REQ_PEE1, DEV3, NORMAL, NORMAL, INPUT), + + DEFAULT_PINMUX(CAM_MCLK_PCC0, VI_ALT2, UP, NORMAL, INPUT), + + DEFAULT_PINMUX(PCC1, RSVD3, NORMAL, NORMAL, OUTPUT), +// DEFAULT_PINMUX(PBB0, RSVD2, NORMAL, NORMAL, OUTPUT), // device specific + DEFAULT_PINMUX(PBB3, VGP3, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PBB4, VGP4, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PBB5, VGP5, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PBB6, VGP6, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PBB7, I2S4, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(PCC2, RSVD3, NORMAL, NORMAL, OUTPUT), + + DEFAULT_PINMUX(JTAG_RTCK_PU7, RTCK, NORMAL, NORMAL, OUTPUT), + + /* KBC keys */ + DEFAULT_PINMUX(KB_ROW0_PR0, RSVD4, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(KB_ROW1_PR1, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW2_PR2, RSVD4, DOWN, NORMAL, OUTPUT), + DEFAULT_PINMUX(KB_ROW3_PR3, RSVD3, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(KB_ROW4_PR4, RSVD4, DOWN, NORMAL, OUTPUT), + DEFAULT_PINMUX(KB_ROW5_PR5, KBC, DOWN, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW6_PR6, KBC, DOWN, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW7_PR7, KBC, DOWN, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW8_PS0, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW9_PS1, KBC, DOWN, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW10_PS2, KBC, DOWN, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW11_PS3, KBC, DOWN, NORMAL, OUTPUT), + DEFAULT_PINMUX(KB_ROW12_PS4, KBC, DOWN, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW13_PS5, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW14_PS6, KBC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_ROW15_PS7, KBC, DOWN, NORMAL, INPUT), + + DEFAULT_PINMUX(KB_COL0_PQ0, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL1_PQ1, KBC, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(KB_COL2_PQ2, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL3_PQ3, KBC, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL4_PQ4, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL5_PQ5, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL6_PQ6, KBC, UP, NORMAL, INPUT), + DEFAULT_PINMUX(KB_COL7_PQ7, KBC, UP, NORMAL, INPUT), + + /* CLK */ + DEFAULT_PINMUX(CLK_32K_OUT_PA0, BLINK, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SYS_CLK_REQ_PZ5, SYSCLK, NORMAL, NORMAL, INPUT), +// DEFAULT_PINMUX(CORE_PWR_REQ, RSVD1, NORMAL, NORMAL, INPUT), // unconfigured +// DEFAULT_PINMUX(CPU_PWR_REQ, RSVD1, NORMAL, NORMAL, INPUT), // unconfigured +// DEFAULT_PINMUX(PWR_INT_N, RSVD1, NORMAL, NORMAL, INPUT), // unconfigured +// DEFAULT_PINMUX(CLK_32K_IN, RSVD1, NORMAL, NORMAL, INPUT), // unconfigured + DEFAULT_PINMUX(OWR, OWR, NORMAL, NORMAL, INPUT), + + /* DAP1 pinmux */ + DEFAULT_PINMUX(DAP1_FS_PN0, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_DIN_PN1, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_DOUT_PN2, I2S0, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(DAP1_SCLK_PN3, I2S0, NORMAL, NORMAL, INPUT), + + /* CLK1 pinmux */ + DEFAULT_PINMUX(CLK1_REQ_PEE2, DAP, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(CLK1_OUT_PW4, EXTPERIPH1, DOWN, NORMAL, INPUT), + + /* SPDIF pinmux */ + DEFAULT_PINMUX(SPDIF_IN_PK6, SPDIF, NORMAL, NORMAL, OUTPUT), +// DEFAULT_PINMUX(SPDIF_OUT_PK5, SPDIF, DOWN, NORMAL, OUTPUT), // device specific + + /* DAP2 pinmux */ + DEFAULT_PINMUX(DAP2_FS_PA2, HDA, DOWN, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_DIN_PA4, HDA, DOWN, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_DOUT_PA5, HDA, DOWN, NORMAL, INPUT), + DEFAULT_PINMUX(DAP2_SCLK_PA3, HDA, DOWN, NORMAL, INPUT), + + /* SPI pinmux */ + DEFAULT_PINMUX(SPI1_MOSI_PX4, SPI2, NORMAL, NORMAL, OUTPUT), +// DEFAULT_PINMUX(SPI1_SCK_PX5, SPI1, NORMAL, NORMAL, OUTPUT), // device specific +// DEFAULT_PINMUX(SPI1_CS0_N_PX6, GMI, NORMAL, NORMAL, INPUT), // device specific + DEFAULT_PINMUX(SPI1_MISO_PX7, RSVD4, NORMAL, NORMAL, OUTPUT), + + DEFAULT_PINMUX(SPI2_MOSI_PX0, SPI2, DOWN, NORMAL, OUTPUT), + DEFAULT_PINMUX(SPI2_MISO_PX1, GMI, NORMAL, NORMAL, OUTPUT), +// DEFAULT_PINMUX(SPI2_CS0_N_PX3, SPI6, UP, NORMAL, INPUT), // unconfigured +// DEFAULT_PINMUX(SPI2_SCK_PX2, SPI6, UP, NORMAL, INPUT), // unconfigured + DEFAULT_PINMUX(SPI2_CS1_N_PW2, SPI2, NORMAL, NORMAL, INPUT), +// DEFAULT_PINMUX(SPI2_CS2_N_PW3, SPI2, UP, TRISTATE, INPUT), // unconfigured + + /* PEX pinmux */ + DEFAULT_PINMUX(PEX_L0_PRSNT_N_PDD0, PCIE, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(PEX_L0_RST_N_PDD1, PCIE, NORMAL, TRISTATE, OUTPUT), + DEFAULT_PINMUX(PEX_L0_CLKREQ_N_PDD2, PCIE, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(PEX_WAKE_N_PDD3, PCIE, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(PEX_L1_PRSNT_N_PDD4, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L1_RST_N_PDD5, PCIE, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PEX_L1_CLKREQ_N_PDD6, PCIE, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PEX_L2_PRSNT_N_PDD7, PCIE, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(PEX_L2_RST_N_PCC6, PCIE, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(PEX_L2_CLKREQ_N_PCC7, PCIE, NORMAL, TRISTATE, INPUT), + + /* GMI pinmux */ + DEFAULT_PINMUX(GMI_WP_N_PC7, GMI, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_IORDY_PI5, RSVD1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_WAIT_PI7, GMI, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_ADV_N_PK0, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_CLK_PK1, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_CS0_N_PJ0, GMI, UP, TRISTATE, INPUT), // LCD_RGB_DE + DEFAULT_PINMUX(GMI_CS1_N_PJ2, RSVD1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_CS2_N_PK3, RSVD1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_CS3_N_PK4, RSVD1, NORMAL, NORMAL, OUTPUT), +// DEFAULT_PINMUX(GMI_CS4_N_PK2, RSVD4, UP, NORMAL, INPUT), // device specific + DEFAULT_PINMUX(GMI_CS6_N_PI3, GMI, UP, NORMAL, INPUT), +// DEFAULT_PINMUX(GMI_CS7_N_PI6, GMI, UP, NORMAL, INPUT), // device specific + DEFAULT_PINMUX(GMI_AD0_PG0, GMI, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(GMI_AD1_PG1, GMI, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(GMI_AD2_PG2, GMI, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(GMI_AD3_PG3, GMI, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(GMI_AD4_PG4, GMI, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(GMI_AD5_PG5, GMI, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(GMI_AD6_PG6, GMI, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(GMI_AD7_PG7, GMI, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(GMI_AD8_PH0, GMI, DOWN, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_AD9_PH1, GMI, DOWN, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_AD10_PH2, GMI, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_AD11_PH3, PWM3, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_AD12_PH4, RSVD4, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_AD13_PH5, RSVD4, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_AD14_PH6, GMI, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_AD15_PH7, GMI, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(GMI_A16_PJ7, UARTD, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_A17_PB0, UARTD, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_A18_PB1, UARTD, DOWN, NORMAL, OUTPUT), // RGB_IC_EN + DEFAULT_PINMUX(GMI_A19_PK7, UARTD, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_WR_N_PI0, GMI, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_OE_N_PI1, RSVD1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(GMI_DQS_PI2, GMI, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(GMI_RST_N_PI4, GMI, UP, NORMAL, INPUT), +}; + +#ifdef CONFIG_DEVICE_P880 +static struct pmux_pingrp_config tegra3_p880_pinmux[] = { + /* SDMMC3 pinmux */ + DEFAULT_PINMUX(SDMMC3_CLK_PA6, SDMMC3, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_CMD_PA7, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT0_PB7, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT1_PB6, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT2_PB5, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT3_PB4, SDMMC3, UP, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT4_PD1, SDMMC3, UP, TRISTATE, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT5_PD0, SDMMC3, UP, TRISTATE, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT6_PD3, SDMMC3, UP, TRISTATE, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT7_PD4, SDMMC3, UP, TRISTATE, INPUT), + + /* SDMMC4 pinmux */ + LV_PINMUX(SDMMC4_CMD_PT7, SDMMC4, UP, NORMAL, INPUT, DISABLE, DISABLE), + + /* ULPI pinmux */ + DEFAULT_PINMUX(ULPI_DATA6_PO7, SPI2, NORMAL, NORMAL, INPUT), + + /* UART-B pinmux */ + DEFAULT_PINMUX(UART2_RXD_PC3, UARTB, UP, NORMAL, INPUT), + DEFAULT_PINMUX(UART2_TXD_PC2, UARTB, UP, NORMAL, OUTPUT), + + /* GPIO group pinmux */ + DEFAULT_PINMUX(PU0, UARTA, UP, NORMAL, OUTPUT), + DEFAULT_PINMUX(PU1, UARTA, UP, NORMAL, INPUT), + DEFAULT_PINMUX(PU2, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PU3, UARTA, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PU4, PWM1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PBB0, I2S4, NORMAL, TRISTATE, INPUT), + + /* SPDIF pinmux */ + DEFAULT_PINMUX(SPDIF_OUT_PK5, SPDIF, UP, TRISTATE, OUTPUT), + + /* SPI pinmux */ + DEFAULT_PINMUX(SPI1_SCK_PX5, SPI2, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(SPI1_CS0_N_PX6, SPI1, NORMAL, NORMAL, INPUT), + + /* GMI pinmux */ + DEFAULT_PINMUX(GMI_CS4_N_PK2, RSVD1, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_CS7_N_PI6, GMI, DOWN, NORMAL, OUTPUT), +}; +#endif /* CONFIG_DEVICE_P880 */ + +#ifdef CONFIG_DEVICE_P895 +static struct pmux_pingrp_config tegra3_p895_pinmux[] = { + /* SDMMC3 pinmux */ + DEFAULT_PINMUX(SDMMC3_CLK_PA6, SDMMC3, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(SDMMC3_CMD_PA7, SDMMC3, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT0_PB7, RSVD1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT1_PB6, RSVD1, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT2_PB5, RSVD1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT3_PB4, RSVD1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT4_PD1, SDMMC3, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT5_PD0, SDMMC3, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT6_PD3, SDMMC3, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(SDMMC3_DAT7_PD4, RSVD2, NORMAL, TRISTATE, INPUT), + + /* SDMMC4 pinmux */ + LV_PINMUX(SDMMC4_CMD_PT7, SDMMC4, NORMAL, NORMAL, INPUT, DISABLE, DISABLE), + + /* ULPI pinmux */ + DEFAULT_PINMUX(ULPI_DATA6_PO7, SPI2, UP, NORMAL, INPUT), + + /* UART-B pinmux */ + DEFAULT_PINMUX(UART2_RXD_PC3, UARTB, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(UART2_TXD_PC2, UARTB, NORMAL, NORMAL, OUTPUT), + + /* Gpio group pinmux */ + DEFAULT_PINMUX(PU0, UARTA, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(PU1, UARTA, NORMAL, NORMAL, INPUT), + DEFAULT_PINMUX(PU2, RSVD1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(PU3, PWM0, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(PU4, PWM1, NORMAL, TRISTATE, INPUT), + DEFAULT_PINMUX(PBB0, RSVD2, NORMAL, NORMAL, OUTPUT), // LCD_EN_3V0 + + /* SPDIF pinmux */ + DEFAULT_PINMUX(SPDIF_OUT_PK5, SPDIF, DOWN, NORMAL, OUTPUT), + + /* SPI pinmux */ + DEFAULT_PINMUX(SPI1_SCK_PX5, SPI1, NORMAL, NORMAL, OUTPUT), + DEFAULT_PINMUX(SPI1_CS0_N_PX6, GMI, NORMAL, NORMAL, INPUT), + + /* GMI pinmux */ + DEFAULT_PINMUX(GMI_CS4_N_PK2, RSVD4, UP, NORMAL, INPUT), + DEFAULT_PINMUX(GMI_CS7_N_PI6, GMI, UP, NORMAL, INPUT), +}; +#endif /* CONFIG_DEVICE_P895 */ +#endif /* _PINMUX_CONFIG_X3_H_ */ diff --git a/board/lg/x3-t30/x3-late.c b/board/lg/x3-t30/x3-late.c new file mode 100644 index 000000000000..eb1fac84b8d4 --- /dev/null +++ b/board/lg/x3-t30/x3-late.c @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2022 + * Svyatoslav Ryhel + */ + +#include +#include +#include +#include +#include +#include +#include + +#define TEGRA_FUSE_BASE 0x7000F800 +#define TEGRA_CAR_BASE 0x60006000 + +#define FUSE_VENDOR_CODE 0x200 +#define FUSE_FAB_CODE 0x204 +#define FUSE_LOT_CODE_0 0x208 +#define FUSE_LOT_CODE_1 0x20c +#define FUSE_WAFER_ID 0x210 +#define FUSE_X_COORDINATE 0x214 +#define FUSE_Y_COORDINATE 0x218 + +#define FUSE_VENDOR_CODE_MASK 0xf +#define FUSE_FAB_CODE_MASK 0x3f +#define FUSE_WAFER_ID_MASK 0x3f +#define FUSE_X_COORDINATE_MASK 0x1ff +#define FUSE_Y_COORDINATE_MASK 0x1ff + +static u32 tegra_fuse_readl(unsigned long offset) +{ + return readl(TEGRA_FUSE_BASE + offset); +} + +static void tegra_set_fuse(void) +{ + u32 reg; + + gpio_request(TEGRA_GPIO(K, 7), "fuse_en"); + gpio_direction_output(TEGRA_GPIO(K, 7), 0); + gpio_set_value(TEGRA_GPIO(K, 7), 1); + + reg = readl_relaxed(TEGRA_CAR_BASE + 0x48); + reg |= BIT(28); + writel(reg, TEGRA_CAR_BASE + 0x48); + + /* + * Enable FUSE clock. This needs to be hardcoded because the clock + * subsystem is not active during early boot. + */ + reg = readl(TEGRA_CAR_BASE + 0x14); + reg |= BIT(7); + writel(reg, TEGRA_CAR_BASE + 0x14); +} + +static unsigned long long tegra_chip_uid(void) +{ + u64 uid = 0ull; + u32 reg; + u32 cid; + u32 vendor; + u32 fab; + u32 lot; + u32 wafer; + u32 x; + u32 y; + u32 i; + + tegra_set_fuse(); + + /* This used to be so much easier in prior chips. Unfortunately, there + is no one-stop shopping for the unique id anymore. It must be + constructed from various bits of information burned into the fuses + during the manufacturing process. The 64-bit unique id is formed + by concatenating several bit fields. The notation used for the + various fields is with the UID composed + thusly: + + Where: + Field Bits Position Data + ------- ---- -------- ---------------------------------------- + CID 4 60 Chip id + VENDOR 4 56 Vendor code + FAB 6 50 FAB code + LOT 26 24 Lot code (5-digit base-36-coded-decimal, + re-encoded to 26 bits binary) + WAFER 6 18 Wafer id + X 9 9 Wafer X-coordinate + Y 9 0 Wafer Y-coordinate + ------- ---- + Total 64 + */ + + /* chip id is 0 for tegra 3 */ + cid = 0; + + vendor = tegra_fuse_readl(FUSE_VENDOR_CODE) & FUSE_VENDOR_CODE_MASK; + fab = tegra_fuse_readl(FUSE_FAB_CODE) & FUSE_FAB_CODE_MASK; + + /* Lot code must be re-encoded from a 5 digit base-36 'BCD' number + to a binary number. */ + lot = 0; + reg = tegra_fuse_readl(FUSE_LOT_CODE_0) << 2; + + for (i = 0; i < 5; ++i) { + u32 digit = (reg & 0xFC000000) >> 26; + lot *= 36; + lot += digit; + reg <<= 6; + } + + wafer = tegra_fuse_readl(FUSE_WAFER_ID) & FUSE_WAFER_ID_MASK; + x = tegra_fuse_readl(FUSE_X_COORDINATE) & FUSE_X_COORDINATE_MASK; + y = tegra_fuse_readl(FUSE_Y_COORDINATE) & FUSE_Y_COORDINATE_MASK; + + uid = ((unsigned long long)cid << 60ull) + | ((unsigned long long)vendor << 56ull) + | ((unsigned long long)fab << 50ull) + | ((unsigned long long)lot << 24ull) + | ((unsigned long long)wafer << 18ull) + | ((unsigned long long)x << 9ull) + | ((unsigned long long)y << 0ull); + + return uid; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +int ft_board_setup(void *blob, struct bd_info *bd) +{ + /* First 3 bytes refer to LG vendor */ + u8 btmacaddr[6] = { 0x00, 0x00, 0x00, 0xD0, 0xC9, 0x88 }; + + /* Generate device 3 bytes based on chip sd */ + u64 bt_device = tegra_chip_uid() >> 24ull; + + btmacaddr[0] = (bt_device >> 1 & 0x0F) | + (bt_device >> 5 & 0xF0); + btmacaddr[1] = (bt_device >> 11 & 0x0F) | + (bt_device >> 17 & 0xF0); + btmacaddr[2] = (bt_device >> 23 & 0x0F) | + (bt_device >> 29 & 0xF0); + + /* Set BT MAC address */ + fdt_find_and_setprop(blob, "/serial@70006200/bluetooth", + "local-bd-address", btmacaddr, 6, 1); + return 0; +} +#endif + +void nvidia_board_late_init(void) +{ + char serialno_str[17]; + + /* Set chip id as serialno */ + sprintf(serialno_str, "%016llx", tegra_chip_uid()); + env_set("serial#", serialno_str); + env_set("platform", "Tegra 3 T30"); +} diff --git a/board/lg/x3-t30/x3-t30-spl.c b/board/lg/x3-t30/x3-t30-spl.c new file mode 100644 index 000000000000..7e4e3cc5a83f --- /dev/null +++ b/board/lg/x3-t30/x3-t30-spl.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * T30 LGE X3 SPL stage configuration + * + * (C) Copyright 2010-2013 + * NVIDIA Corporation + * + * (C) Copyright 2022 + * Svyatoslav Ryhel + */ + +#include +#include +#include + +/* I2C addr is in 8 bit */ +#define MAX77663_I2C_ADDR 0x38 + +#define MAX77663_REG_SD0 0x16 +#define MAX77663_REG_SD0_DATA (0x2100 | MAX77663_REG_SD0) +#define MAX77663_REG_SD1 0x17 +#define MAX77663_REG_SD1_DATA (0x3000 | MAX77663_REG_SD1) +#define MAX77663_REG_LDO4 0x2B +#define MAX77663_REG_LDO4_DATA (0xE000 | MAX77663_REG_LDO4) + +#define MAX77620_REG_GPIO1 0x37 +#define MAX77620_REG_GPIO1_DATA (0x0800 | MAX77620_REG_GPIO1) +#define MAX77620_REG_GPIO4 0x3A +#define MAX77620_REG_GPIO4_DATA (0x0100 | MAX77620_REG_GPIO4) + +void pmic_enable_cpu_vdd(void) +{ + /* Set VDD_CORE to 1.200V. */ + tegra_i2c_ll_write_addr(MAX77663_I2C_ADDR, 2); + tegra_i2c_ll_write_data(MAX77663_REG_SD1_DATA, I2C_SEND_2_BYTES); + + udelay(1000); + + /* Bring up VDD_CPU to 1.0125V. */ + tegra_i2c_ll_write_addr(MAX77663_I2C_ADDR, 2); + tegra_i2c_ll_write_data(MAX77663_REG_SD0_DATA, I2C_SEND_2_BYTES); + udelay(1000); + + /* Bring up VDD_RTC to 1.200V. */ + tegra_i2c_ll_write_addr(MAX77663_I2C_ADDR, 2); + tegra_i2c_ll_write_data(MAX77663_REG_LDO4_DATA, I2C_SEND_2_BYTES); + udelay(10 * 1000); + + /* Set GPIO4 and GPIO1 states */ + tegra_i2c_ll_write_addr(MAX77663_I2C_ADDR, 2); + tegra_i2c_ll_write_data(MAX77620_REG_GPIO4_DATA, I2C_SEND_2_BYTES); + tegra_i2c_ll_write_data(MAX77620_REG_GPIO1_DATA, I2C_SEND_2_BYTES); +} diff --git a/board/lg/x3-t30/x3-t30.c b/board/lg/x3-t30/x3-t30.c new file mode 100644 index 000000000000..01658f94c879 --- /dev/null +++ b/board/lg/x3-t30/x3-t30.c @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2010-2013 + * NVIDIA Corporation + * + * (C) Copyright 2022 + * Svyatoslav Ryhel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pinmux-config-x3.h" + +#ifdef CONFIG_TEGRA_CRYPTO +#include +#include "uboot_aes.h" +#endif + +#define PMC_CLK_OUT_CNTRL_0 0x01A8 + +#define MAX77663_I2C_ADDR 0x1C /* 7 bit */ +#define MAX77663_REG_SD2 0x18 +#define MAX77663_REG_LDO2 0x27 +#define MAX77663_REG_LDO3 0x29 +#define MAX77663_REG_LDO5 0x2D +#define MAX77663_REG_ONOFF_CFG1 0x41 +#define MAX77663_ONOFF_PWR_OFF 0x02 + +#ifdef CONFIG_CMD_POWEROFF +int do_poweroff(struct cmd_tbl *cmdtp, int flag, + int argc, char *const argv[]) +{ + struct udevice *dev; + uchar data_buffer[1]; + int ret; + + ret = i2c_get_chip_for_busnum(0, MAX77663_I2C_ADDR, 1, &dev); + if (ret) { + printf("%s: Cannot find PMIC I2C chip\n", __func__); + return 0; + } + + ret = dm_i2c_read(dev, MAX77663_REG_ONOFF_CFG1, data_buffer, 1); + if (ret) + return ret; + + data_buffer[0] |= MAX77663_ONOFF_PWR_OFF; + + ret = dm_i2c_write(dev, MAX77663_REG_ONOFF_CFG1, data_buffer, 1); + if (ret) + return ret; + + /* wait some time and then print error */ + mdelay(5000); + + printf("Failed to power off!!!\n"); + return 1; +} +#endif + +#ifdef CONFIG_TEGRA_CRYPTO +/* + * Pass sbk for boards where it is common + */ +void get_secure_key(u8 *key) +{ + /* SBK is device/board specific */ +#ifdef CONFIG_DEVICE_P880 + u8 sbk[AES128_KEY_LENGTH] = { + 0xc1, 0x82, 0x69, 0xee, 0x09, 0x00, 0xce, 0x58, + 0x48, 0x2a, 0xbe, 0x34, 0xbf, 0xf1, 0xbc, 0x01 + }; +#endif +#ifdef CONFIG_DEVICE_P895 + u8 sbk[AES128_KEY_LENGTH] = { + 0x95, 0x08, 0x21, 0xad, 0x09, 0x64, 0xce, 0x58, + 0xfe, 0x98, 0xbe, 0x34, 0xbf, 0xf1, 0xac, 0x02 + }; +#endif + + memcpy(key, sbk, AES128_KEY_LENGTH); +} +#endif + +/* + * Routine: pinmux_init + * Description: Do individual peripheral pinmux configs + */ +void pinmux_init(void) +{ + pinmux_config_pingrp_table(tegra3_x3_pinmux_common, + ARRAY_SIZE(tegra3_x3_pinmux_common)); + +#ifdef CONFIG_DEVICE_P880 + pinmux_config_pingrp_table(tegra3_p880_pinmux, + ARRAY_SIZE(tegra3_p880_pinmux)); +#endif + +#ifdef CONFIG_DEVICE_P895 + pinmux_config_pingrp_table(tegra3_p895_pinmux, + ARRAY_SIZE(tegra3_p895_pinmux)); +#endif +} + +#ifdef CONFIG_MMC_SDHCI_TEGRA +/* + * Do I2C/PMU writes to bring up SD card and eMMC bus power + */ +void board_sdmmc_voltage_init(void) +{ + struct udevice *dev; + uchar val; + int ret; + + ret = i2c_get_chip_for_busnum(0, MAX77663_I2C_ADDR, 1, &dev); + if (ret) { + debug("%s: Cannot find PMIC I2C chip\n", __func__); + return; + } + + /* 0x60 for 1.8v, bit7:0 = voltage */ + val = 0x60; + ret = dm_i2c_write(dev, MAX77663_REG_SD2, &val, 1); + if (ret) + printf("vdd_1v8_vio set failed: %d\n", ret); + + /* 0xF2 for 3.30v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */ + val = 0xF2; + ret = dm_i2c_write(dev, MAX77663_REG_LDO2, &val, 1); + if (ret) + printf("avdd_usb set failed: %d\n", ret); + + /* 0xEC for 3.00v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */ + val = 0xEC; + ret = dm_i2c_write(dev, MAX77663_REG_LDO3, &val, 1); + if (ret) + printf("vdd_usd set failed: %d\n", ret); + + /* 0xE9 for 2.85v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */ + val = 0xE9; + ret = dm_i2c_write(dev, MAX77663_REG_LDO5, &val, 1); + if (ret) + printf("vcore_emmc set failed: %d\n", ret); +} + +/* + * Routine: pin_mux_mmc + * Description: setup the MMC muxes, power rails, etc. + */ +void pin_mux_mmc(void) +{ + /* + * NOTE: We don't do mmc-specific pin muxes here. + * They were done globally in pinmux_init(). + */ + + /* Bring up uSD and eMMC power */ + board_sdmmc_voltage_init(); +} +#endif /* MMC */ + +int nvidia_board_init(void) +{ + u32 value; + + clock_start_periph_pll(PERIPH_ID_EXTPERIPH3, CLOCK_ID_PERIPH, + 24 * 1000000); + clock_enable(PERIPH_ID_EXTPERIPH3); + udelay(5); + reset_set_enable(PERIPH_ID_EXTPERIPH3, 0); + + /* Configure clk_out_3 */ + value = tegra_pmc_readl(PMC_CLK_OUT_CNTRL_0); + tegra_pmc_writel(value | BIT(18) | BIT(22) | BIT(23), + PMC_CLK_OUT_CNTRL_0); + + return 0; +} diff --git a/configs/p880.config b/configs/p880.config new file mode 100644 index 000000000000..2c119e5d584f --- /dev/null +++ b/configs/p880.config @@ -0,0 +1,4 @@ +CONFIG_DEFAULT_DEVICE_TREE="tegra30-lge-p880" +CONFIG_DEVICE_P880=y +CONFIG_SYS_PROMPT="Tegra30 (P880) # " +CONFIG_PANEL_RENESAS_R69328=y diff --git a/configs/p895.config b/configs/p895.config new file mode 100644 index 000000000000..4275fc6fc1d9 --- /dev/null +++ b/configs/p895.config @@ -0,0 +1,4 @@ +CONFIG_DEFAULT_DEVICE_TREE="tegra30-lge-p895" +CONFIG_DEVICE_P895=y +CONFIG_SYS_PROMPT="Tegra30 (P895) # " +CONFIG_PANEL_KOE_TX13D100VM0EAA=y diff --git a/configs/x3_t30_defconfig b/configs/x3_t30_defconfig new file mode 100644 index 000000000000..34b245414147 --- /dev/null +++ b/configs/x3_t30_defconfig @@ -0,0 +1,84 @@ +CONFIG_ARM=y +CONFIG_SYS_L2CACHE_OFF=y +CONFIG_ARCH_TEGRA=y +CONFIG_SUPPORT_PASSING_ATAGS=y +CONFIG_CMDLINE_TAG=y +CONFIG_INITRD_TAG=y +CONFIG_TEXT_BASE=0x80110000 +CONFIG_NR_DRAM_BANKS=2 +CONFIG_ENV_SIZE=0x3000 +CONFIG_ENV_OFFSET=0xFFFFD000 +CONFIG_DEFAULT_DEVICE_TREE="tegra30-lge-x3" +CONFIG_SPL_TEXT_BASE=0x80108000 +CONFIG_SYS_PROMPT="Tegra30 (x3) # " +CONFIG_TEGRA_CRYPTO=y +CONFIG_TEGRA_LEGACY_PT=y +CONFIG_TEGRA30=y +CONFIG_TARGET_X3_T30=y +CONFIG_SYS_LOAD_ADDR=0x81000000 +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_UART_PHYS=0x70006300 +CONFIG_OF_BOARD_SETUP=y +CONFIG_OF_SYSTEM_SETUP=y +CONFIG_BOOTDELAY=0 +CONFIG_AUTOBOOT_KEYED=y +CONFIG_AUTOBOOT_KEYED_CTRLC=y +CONFIG_SPL_FOOTPRINT_LIMIT=y +CONFIG_SPL_MAX_FOOTPRINT=0x8000 +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_STACK=0x800ffffc +CONFIG_SYS_SPL_MALLOC=y +CONFIG_HAS_CUSTOM_SPL_MALLOC_START=y +CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x80090000 +CONFIG_SYS_SPL_MALLOC_SIZE=0x10000 +CONFIG_SYS_MAXARGS=64 +CONFIG_SYS_PBSIZE=2084 +CONFIG_CMD_BOOTMENU=y +# CONFIG_CMD_IMI is not set +CONFIG_CMD_GPIO=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +CONFIG_CMD_POWEROFF=y +CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_NFS is not set +CONFIG_CMD_EXT4_WRITE=y +# CONFIG_SPL_DOS_PARTITION is not set +# CONFIG_SPL_EFI_PARTITION is not set +CONFIG_ENV_OVERWRITE=y +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_SYS_MMC_ENV_PART=2 +CONFIG_SPL_DM=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x91000000 +CONFIG_FASTBOOT_BUF_SIZE=0x10000000 +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 +CONFIG_SYS_I2C_TEGRA=y +CONFIG_GPIO_KEYBOARD=y +CONFIG_EXTCON_MAX14526=y +CONFIG_DM_PMIC=y +CONFIG_DM_REGULATOR=y +CONFIG_DM_REGULATOR_FIXED=y +CONFIG_PWM_TEGRA=y +CONFIG_SYS_NS16550=y +CONFIG_TEGRA20_SLINK=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_TEGRA=y +CONFIG_USB_KEYBOARD=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="LGE" +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_TEGRA20=y +CONFIG_BACKLIGHT_LM3533=y +CONFIG_BRIDGE_SOLOMON_SSD2825=y +CONFIG_CONSOLE_RECORD=y +CONFIG_CONSOLE_RECORD_OUT_SIZE=0x10000 +CONFIG_FASTBOOT_CMD_OEM_CONSOLE=y +CONFIG_FASTBOOT_CMD_OEM_CMD=y diff --git a/include/configs/x3-t30.h b/include/configs/x3-t30.h new file mode 100644 index 000000000000..d13ca15d47f0 --- /dev/null +++ b/include/configs/x3-t30.h @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * (C) Copyright 2010,2012 + * NVIDIA Corporation + * + * (C) Copyright 2022 + * Svyatoslav Ryhel + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include + +#include "tegra30-common.h" + +#define X3_SD_LOAD_KERNEL \ + "echo Loading Kernel;" \ + "if load mmc ${bootdev}:${bootpart} ${kernel_addr_r} ${kernel_file};" \ + "then echo Loading DTB;" \ + "load mmc ${bootdev}:${bootpart} ${fdt_addr_r} ${fdtfile};" \ + "fdt addr ${fdt_addr_r};" \ + "fdt rm /firmware;" \ + "fdt rm /reserved-memory/trustzone@bfe00000;" \ + "echo Loading Initramfs;" \ + "if load mmc ${bootdev}:${bootpart} ${ramdisk_addr_r} ${ramdisk_file};" \ + "then echo Booting Kernel;" \ + "run bootrdkernel;" \ + "else echo Booting Kernel;" \ + "run bootkernel; fi;" + +#ifdef CONFIG_DEVICE_P880 +/* High-level configuration options */ +#define CONFIG_TEGRA_BOARD_STRING "LG Optimus 4X HD" + +#define X3_BOOTMENU_3_4 \ + "bootmenu_3=mount microsd=usb start && ums 0 mmc 1; bootmenu\0" \ + "bootmenu_4=mount /cache=usb start && ums 0 mmc 0:4; bootmenu\0" + +#define X3_BOOTCOMMAND \ + "echo Loading from uSD...;" \ + "setenv bootargs console=ttyS0,115200n8 root=/dev/mmcblk1p2 rw gpt;" \ + "setenv bootdev 1;" \ + "setenv bootpart 1;" \ + X3_SD_LOAD_KERNEL \ + "else echo Loading from uSD failed!;" \ + "echo Loading from eMMC...;" \ + "setenv bootargs console=ttyS0,115200n8 root=/dev/mmcblk0p8 rw gpt;" \ + "setenv bootdev 0;" \ + "setenv bootpart 4;" \ + X3_SD_LOAD_KERNEL \ + "else echo Loading Kernel FAILED! Turning power off;" \ + "poweroff;" \ + "fi;" \ + "fi;" +#endif + +#ifdef CONFIG_DEVICE_P895 +/* High-level configuration options */ +#define CONFIG_TEGRA_BOARD_STRING "LG Optimus Vu" + +#define X3_BOOTMENU_3_4 \ + "bootmenu_3=mount /boot=usb start && ums 0 mmc 0:4; bootmenu\0" \ + "bootmenu_4=mount /root=usb start && ums 0 mmc 0:8; bootmenu\0" + +#define X3_BOOTCOMMAND \ + "echo Loading from eMMC...;" \ + "setenv bootargs console=ttyS0,115200n8 root=/dev/mmcblk0p8 rw gpt;" \ + "setenv bootdev 0;" \ + "setenv bootpart 4;" \ + X3_SD_LOAD_KERNEL \ + "else echo Loading Kernel FAILED! Turning power off;" \ + "poweroff;" \ + "fi;" +#endif + +#define X3_BOOT_CUSTOM_KERNEL \ + "boot_custom_kernel=echo Loading Kernel;" \ + "load ${dev_type} ${mmcdev}:${mmcpart} ${kernel_addr_r} ${kernel_file};" \ + "echo Loading DTB;" \ + "load ${dev_type} ${mmcdev}:${mmcpart} ${fdt_addr_r} ${dtb_file};" \ + "fdt addr ${fdt_addr_r};" \ + "fdt rm /firmware;" \ + "fdt rm /reserved-memory/trustzone@bfe00000;" \ + "echo Loading Initramfs;" \ + "if load ${dev_type} ${mmcdev}:${mmcpart} ${ramdisk_addr_r} ${ramdisk_file};" \ + "then echo Booting Kernel;" \ + "run bootrdkernel;" \ + "else echo Booting Kernel;" \ + "run bootkernel; fi\0" + +#define X3_BOOT_SCRIPT \ + X3_BOOT_CUSTOM_KERNEL \ + "boot_script=echo Loading boot script;" \ + "if load mmc 0:4 ${scriptaddr} uboot-x3.bcs;" \ + "then env import -t -r ${scriptaddr} ${filesize};" \ + "run boot_custom_kernel;" \ + "else if load mmc 1:1 ${scriptaddr} uboot-x3.bcs;" \ + "then env import -t -r ${scriptaddr} ${filesize};" \ + "run boot_custom_kernel;" \ + "else echo Boot Configuration NOT FOUND!;" \ + "echo Press ANY key to return to bootmenu;" \ + "continue; bootmenu; fi;" \ + "fi\0" + +#define X3_BOOT_SOS \ + "boot_sos=echo Reading SOS partition;" \ + "mmc dev;" \ + "if mmc read ${kernel_addr_r} ${sos_offset_m} ${sos_size};" \ + "then echo Booting Kernel;" \ + "bootm ${kernel_addr_r};" \ + "else echo Reading SOS failed;" \ + "echo Press ANY key to return to bootmenu;" \ + "continue; bootmenu; fi\0" + +#define X3_BOOT_LNX \ + "boot_lnx=echo Reading LNX partition;" \ + "mmc dev;" \ + "if mmc read ${kernel_addr_r} ${lnx_offset_m} ${lnx_size};" \ + "then echo Booting Kernel;" \ + "bootm ${kernel_addr_r};" \ + "else echo Reading LNX failed;" \ + "echo Press ANY key to return to bootmenu;" \ + "continue; bootmenu; fi\0" + +#define X3_FLASH_UBOOT \ + "flash_uboot=echo Preparing RAM;" \ + "mw ${bct_addr_r} 0 ${bct_block_size_r};" \ + "mw ${ebt_addr_r} 0 ${ebt_block_size_r};" \ + "echo Reading BCT;" \ + "mmc dev 0 1;" \ + "mmc read ${bct_addr_r} 0 ${bct_block_size};" \ + "echo Reading bootloader;" \ + "if load mmc 0:4 ${ebt_addr_r} ${bootloader_file};" \ + "then echo Calculating bootloader size;" \ + "size mmc 0:4 ${bootloader_file};" \ + "ebtupdate ${bct_addr_r} ${ebt_addr_r} ${filesize};" \ + "echo Writing bootloader to eMMC;" \ + "mmc dev 0 1;" \ + "mmc write ${bct_addr_r} 0 ${bct_block_size};" \ + "mmc dev 0 2;" \ + "mmc write ${bct_addr_r} 0 ${bct_block_size};" \ + "mmc dev;" \ + "mmc write ${ebt_addr_r} ${ebt_block_shift} ${ebt_block_size};" \ + "echo Bootloader written successfully;" \ + "echo Press ANY key to reboot device; continue; reset;" \ + "else echo Reading bootloader failed;" \ + "echo Press ANY key to return to bootmenu; continue; bootmenu; fi\0" + +#define X3_BOOTMENU \ + X3_BOOT_SCRIPT \ + X3_BOOT_SOS \ + X3_BOOT_LNX \ + X3_FLASH_UBOOT \ + "bootmenu_0=boot with script=run boot_script\0" \ + "bootmenu_1=boot LNX=run boot_lnx\0" \ + "bootmenu_2=boot SOS=run boot_sos\0" \ + X3_BOOTMENU_3_4 \ + "bootmenu_5=fastboot=echo Starting Fastboot protocol ...; fastboot usb 0; bootmenu\0" \ + "bootmenu_6=update bootloader=run flash_uboot\0" \ + "bootmenu_7=reboot RCM=enterrcm\0" \ + "bootmenu_8=reboot=reset\0" \ + "bootmenu_9=power off=poweroff\0" \ + "bootmenu_delay=-1\0" + +#define X3_EMMC_LAYOUT \ + "bct_addr_r=0x81000000\0" \ + "bct_block_size_r=0x200000\0" \ + "bct_block_size=0x1000\0" \ + "ebt_addr_r=0x81200000\0" \ + "ebt_block_size_r=0x600000\0" \ + "ebt_block_size=0x3000\0" \ + "ebt_block_shift=0x1000\0" \ + "sos_offset_m=0x7000\0" \ + "sos_size=0x5000\0" \ + "lnx_offset_m=0xC000\0" \ + "lnx_size=0x5000\0" + +#define BOARD_EXTRA_ENV_SETTINGS \ + "kernel_file=vmlinuz\0" \ + "ramdisk_file=uInitrd\0" \ + "bootloader_file=u-boot-dtb-tegra.bin\0" \ + "bootkernel=bootz ${kernel_addr_r} - ${fdt_addr_r}\0" \ + "bootrdkernel=bootz ${kernel_addr_r} ${ramdisk_addr_r} ${fdt_addr_r}\0" \ + "check_button=gpio input ${gpio_button}; test $? -eq 0\0" \ + X3_EMMC_LAYOUT \ + X3_BOOTMENU + +#undef CONFIG_BOOTCOMMAND +#define CONFIG_BOOTCOMMAND \ + "setenv gpio_button 116;" \ + "if run check_button;" \ + "then bootmenu; else " \ + X3_BOOTCOMMAND \ + "fi;" + +/* Board-specific serial config */ +#define CONFIG_TEGRA_ENABLE_UARTD +#define CONFIG_SYS_NS16550_COM1 NV_PA_APB_UARTD_BASE + +#include "tegra-common-post.h" + +#endif /* __CONFIG_H */ From 96e6c84299ec21ac3f63fb267082c9dacab5f299 Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 21 Oct 2022 12:41:54 +0300 Subject: [PATCH 36/45] ARM: tegra: remap clock_osc_freq for all Tegra family MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enum clock_osc_freq was designed to use only with T20. This patch remaps it to use additional frequencies, added in T30+ SoC while maintaining backwards compatibility with T20. Tested-by: Andreas Westman Dorcsak # ASUS TF600T T30 Tested-by: Jonas Schwöbel # Surface RT T30 Tested-by: Robert Eckelmann # ASUS TF101 T20 Tested-by: Svyatoslav Ryhel # LG P895 T30 Signed-off-by: Svyatoslav Ryhel --- arch/arm/include/asm/arch-tegra/clock.h | 9 ++-- arch/arm/mach-tegra/clock.c | 17 ++++-- arch/arm/mach-tegra/cpu.c | 70 ++++++++++++++++++++----- arch/arm/mach-tegra/tegra114/clock.c | 13 ++--- arch/arm/mach-tegra/tegra124/clock.c | 13 ++--- arch/arm/mach-tegra/tegra20/clock.c | 4 +- arch/arm/mach-tegra/tegra210/clock.c | 22 ++------ arch/arm/mach-tegra/tegra30/clock.c | 10 +--- drivers/usb/host/ehci-tegra.c | 46 ++++++++++++---- 9 files changed, 131 insertions(+), 73 deletions(-) diff --git a/arch/arm/include/asm/arch-tegra/clock.h b/arch/arm/include/asm/arch-tegra/clock.h index 6586015fd232..1dd5d0742c49 100644 --- a/arch/arm/include/asm/arch-tegra/clock.h +++ b/arch/arm/include/asm/arch-tegra/clock.h @@ -13,12 +13,13 @@ struct udevice; /* Set of oscillator frequencies supported in the internal API. */ enum clock_osc_freq { /* All in MHz, so 13_0 is 13.0MHz */ - CLOCK_OSC_FREQ_13_0, - CLOCK_OSC_FREQ_19_2, - CLOCK_OSC_FREQ_12_0, - CLOCK_OSC_FREQ_26_0, + CLOCK_OSC_FREQ_13_0 = 0, + CLOCK_OSC_FREQ_16_8, + CLOCK_OSC_FREQ_19_2 = 4, CLOCK_OSC_FREQ_38_4, + CLOCK_OSC_FREQ_12_0 = 8, CLOCK_OSC_FREQ_48_0, + CLOCK_OSC_FREQ_26_0 = 12, CLOCK_OSC_FREQ_COUNT, }; diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c index 77c8ad978e56..11bffc170168 100644 --- a/arch/arm/mach-tegra/clock.c +++ b/arch/arm/mach-tegra/clock.c @@ -28,16 +28,23 @@ static unsigned pll_rate[CLOCK_ID_COUNT]; /* - * The oscillator frequency is fixed to one of four set values. Based on this + * The oscillator frequency is fixed to one of seven set values. Based on this * the other clocks are set up appropriately. */ static unsigned osc_freq[CLOCK_OSC_FREQ_COUNT] = { 13000000, + 16800000, + 0, + 0, 19200000, - 12000000, - 26000000, 38400000, + 0, + 0, + 12000000, 48000000, + 0, + 0, + 26000000, }; /* return 1 if a peripheral ID is in range */ @@ -766,6 +773,7 @@ void tegra30_set_up_pllp(void) */ switch (clock_get_osc_freq()) { case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ + case CLOCK_OSC_FREQ_48_0: /* OSC is 48Mhz */ clock_set_rate(CLOCK_ID_PERIPH, 408, 12, 0, 8); clock_set_rate(CLOCK_ID_CGENERAL, 456, 12, 1, 8); break; @@ -776,10 +784,13 @@ void tegra30_set_up_pllp(void) break; case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ + case CLOCK_OSC_FREQ_16_8: /* OSC is 16.8Mhz */ clock_set_rate(CLOCK_ID_PERIPH, 408, 13, 0, 8); clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); break; + case CLOCK_OSC_FREQ_19_2: + case CLOCK_OSC_FREQ_38_4: default: /* * These are not supported. It is too early to print a diff --git a/arch/arm/mach-tegra/cpu.c b/arch/arm/mach-tegra/cpu.c index 65b15b79fe9b..59ca8aeabac7 100644 --- a/arch/arm/mach-tegra/cpu.c +++ b/arch/arm/mach-tegra/cpu.c @@ -55,11 +55,18 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = { */ { { .n = 1000, .m = 13, .p = 0, .cpcon = 12 }, /* OSC: 13.0 MHz */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ { .n = 625, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 19.2 MHz */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ { .n = 1000, .m = 12, .p = 0, .cpcon = 12 }, /* OSC: 12.0 MHz */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ { .n = 1000, .m = 26, .p = 0, .cpcon = 12 }, /* OSC: 26.0 MHz */ - { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* OSC: 38.4 MHz (N/A) */ - { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* OSC: 48.0 MHz (N/A) */ }, /* * T25: 1.2 GHz @@ -73,11 +80,18 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = { */ { { .n = 923, .m = 10, .p = 0, .cpcon = 12 }, /* OSC: 13.0 MHz */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ { .n = 750, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 19.2 MHz */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ { .n = 600, .m = 6, .p = 0, .cpcon = 12 }, /* OSC: 12.0 MHz */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ { .n = 600, .m = 13, .p = 0, .cpcon = 12 }, /* OSC: 26.0 MHz */ - { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* OSC: 38.4 MHz (N/A) */ - { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* OSC: 48.0 MHz (N/A) */ }, /* * T30: 600 MHz @@ -91,11 +105,18 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = { */ { { .n = 600, .m = 13, .p = 0, .cpcon = 8 }, /* OSC: 13.0 MHz */ + { .n = 600, .m = 13, .p = 0, .cpcon = 8 }, /* OSC: 16.8 MHz */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ { .n = 500, .m = 16, .p = 0, .cpcon = 8 }, /* OSC: 19.2 MHz */ + { .n = 500, .m = 16, .p = 0, .cpcon = 8 }, /* OSC: 38.4 MHz */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ { .n = 600, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 12.0 MHz */ + { .n = 600, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 48.0 MHz */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ + { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* N/A */ { .n = 600, .m = 26, .p = 0, .cpcon = 8 }, /* OSC: 26.0 MHz */ - { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* OSC: 38.4 MHz (N/A) */ - { .n = 0, .m = 0, .p = 0, .cpcon = 0 }, /* OSC: 48.0 MHz (N/A) */ }, /* * T114: 700 MHz @@ -108,11 +129,18 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = { */ { { .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz */ + { .n = 108, .m = 1, .p = 1 }, /* OSC: 16.8 MHz */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ { .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz */ + { .n = 73, .m = 1, .p = 1 }, /* OSC: 38.4 MHz */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ { .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz */ + { .n = 116, .m = 1, .p = 1 }, /* OSC: 48.0 MHz */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ { .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz */ - { .n = 0, .m = 0, .p = 0 }, /* OSC: 38.4 MHz (N/A) */ - { .n = 0, .m = 0, .p = 0 }, /* OSC: 48.0 MHz (N/A) */ }, /* @@ -126,11 +154,18 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = { */ { { .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz */ + { .n = 108, .m = 1, .p = 1 }, /* OSC: 16.8 MHz */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ { .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz */ + { .n = 73, .m = 1, .p = 1 }, /* OSC: 38.4 MHz */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ { .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz */ + { .n = 116, .m = 1, .p = 1 }, /* OSC: 48.0 MHz */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ { .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz */ - { .n = 0, .m = 0, .p = 0 }, /* OSC: 38.4 MHz (N/A) */ - { .n = 0, .m = 0, .p = 0 }, /* OSC: 48.0 MHz (N/A) */ }, /* @@ -143,12 +178,19 @@ struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = { * PLLX_BASE m 7: 0 8 */ { - { .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz = 702 MHz*/ - { .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz = 700.8 MHz*/ - { .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz = 696 MHz*/ - { .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz = 702 MHz*/ + { .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz = 702 MHz */ + { .n = 108, .m = 1, .p = 1 }, /* OSC: 16.0 MHz = 702 MHz */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ + { .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz = 700.8 MHz */ { .n = 36, .m = 1, .p = 1 }, /* OSC: 38.4 MHz = 691.2 MHz */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ + { .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz = 696 MHz */ { .n = 58, .m = 2, .p = 1 }, /* OSC: 48.0 MHz = 696 MHz */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ + { .n = 0, .m = 0, .p = 0 }, /* (N/A) */ + { .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz = 702 MHz */ }, }; diff --git a/arch/arm/mach-tegra/tegra114/clock.c b/arch/arm/mach-tegra/tegra114/clock.c index 703a2314e70a..143f86863ff4 100644 --- a/arch/arm/mach-tegra/tegra114/clock.c +++ b/arch/arm/mach-tegra/tegra114/clock.c @@ -459,8 +459,7 @@ struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = { /* * Get the oscillator frequency, from the corresponding hardware configuration - * field. Note that T30/T114 support 3 new higher freqs, but we map back - * to the old T20 freqs. Support for the higher oscillators is TBD. + * field. Note that T30+ supports 3 new higher freqs. */ enum clock_osc_freq clock_get_osc_freq(void) { @@ -469,12 +468,7 @@ enum clock_osc_freq clock_get_osc_freq(void) u32 reg; reg = readl(&clkrst->crc_osc_ctrl); - reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; - - if (reg & 1) /* one of the newer freqs */ - printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg); - - return reg >> 2; /* Map to most common (T20) freqs */ + return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; } /* Returns a pointer to the clock source register for a peripheral */ @@ -674,6 +668,7 @@ void clock_early_init(void) */ switch (clock_get_osc_freq()) { case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ + case CLOCK_OSC_FREQ_48_0: /* OSC is 48Mhz */ clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12); break; @@ -684,10 +679,12 @@ void clock_early_init(void) break; case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ + case CLOCK_OSC_FREQ_16_8: /* OSC is 16.8Mhz */ clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12); break; case CLOCK_OSC_FREQ_19_2: + case CLOCK_OSC_FREQ_38_4: default: /* * These are not supported. It is too early to print a diff --git a/arch/arm/mach-tegra/tegra124/clock.c b/arch/arm/mach-tegra/tegra124/clock.c index bbfe1846526d..da38b26c27d5 100644 --- a/arch/arm/mach-tegra/tegra124/clock.c +++ b/arch/arm/mach-tegra/tegra124/clock.c @@ -601,8 +601,7 @@ struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = { /* * Get the oscillator frequency, from the corresponding hardware configuration - * field. Note that Tegra30+ support 3 new higher freqs, but we map back - * to the old T20 freqs. Support for the higher oscillators is TBD. + * field. Note that T30+ supports 3 new higher freqs. */ enum clock_osc_freq clock_get_osc_freq(void) { @@ -611,12 +610,7 @@ enum clock_osc_freq clock_get_osc_freq(void) u32 reg; reg = readl(&clkrst->crc_osc_ctrl); - reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; - - if (reg & 1) /* one of the newer freqs */ - printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg); - - return reg >> 2; /* Map to most common (T20) freqs */ + return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; } /* Returns a pointer to the clock source register for a peripheral */ @@ -854,6 +848,7 @@ void clock_early_init(void) */ switch (clock_get_osc_freq()) { case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ + case CLOCK_OSC_FREQ_48_0: /* OSC is 48Mhz */ clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12); break; @@ -864,10 +859,12 @@ void clock_early_init(void) break; case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ + case CLOCK_OSC_FREQ_16_8: /* OSC is 16.8Mhz */ clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12); break; case CLOCK_OSC_FREQ_19_2: + case CLOCK_OSC_FREQ_38_4: default: /* * These are not supported. It is too early to print a diff --git a/arch/arm/mach-tegra/tegra20/clock.c b/arch/arm/mach-tegra/tegra20/clock.c index 3b50a8119423..8c127430aada 100644 --- a/arch/arm/mach-tegra/tegra20/clock.c +++ b/arch/arm/mach-tegra/tegra20/clock.c @@ -399,7 +399,9 @@ enum clock_osc_freq clock_get_osc_freq(void) u32 reg; reg = readl(&clkrst->crc_osc_ctrl); - return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; + reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; + + return reg << 2; } /* Returns a pointer to the clock source register for a peripheral */ diff --git a/arch/arm/mach-tegra/tegra210/clock.c b/arch/arm/mach-tegra/tegra210/clock.c index 10c2478df7f2..330753f2ad1a 100644 --- a/arch/arm/mach-tegra/tegra210/clock.c +++ b/arch/arm/mach-tegra/tegra210/clock.c @@ -672,8 +672,7 @@ struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = { /* * Get the oscillator frequency, from the corresponding hardware configuration - * field. Note that Tegra30+ support 3 new higher freqs, but we map back - * to the old T20 freqs. Support for the higher oscillators is TBD. + * field. Note that T30+ supports 3 new higher freqs. */ enum clock_osc_freq clock_get_osc_freq(void) { @@ -682,22 +681,7 @@ enum clock_osc_freq clock_get_osc_freq(void) u32 reg; reg = readl(&clkrst->crc_osc_ctrl); - reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; - /* - * 0 = 13MHz, 1 = 16.8MHz, 4 = 19.2MHz, 5 = 38.4MHz, - * 8 = 12MHz, 9 = 48MHz, 12 = 26MHz - */ - if (reg == 5) { - debug("OSC_FREQ is 38.4MHz (%d) ...\n", reg); - /* Map it to the 5th CLOCK_OSC_ enum, i.e. 4 */ - return 4; - } - - /* - * Map to most common (T20) freqs (except 38.4, handled above): - * 13/16.8 = 0, 19.2 = 1, 12/48 = 2, 26 = 3 - */ - return reg >> 2; + return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; } /* Returns a pointer to the clock source register for a peripheral */ @@ -986,6 +970,7 @@ void clock_early_init(void) */ switch (clock_get_osc_freq()) { case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ + case CLOCK_OSC_FREQ_48_0: /* OSC is 48Mhz */ clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12); break; @@ -996,6 +981,7 @@ void clock_early_init(void) break; case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ + case CLOCK_OSC_FREQ_16_8: /* OSC is 16.8Mhz */ clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12); break; diff --git a/arch/arm/mach-tegra/tegra30/clock.c b/arch/arm/mach-tegra/tegra30/clock.c index 54855d6be72e..04ad5c504dda 100644 --- a/arch/arm/mach-tegra/tegra30/clock.c +++ b/arch/arm/mach-tegra/tegra30/clock.c @@ -439,8 +439,7 @@ struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = { /* * Get the oscillator frequency, from the corresponding hardware configuration - * field. Note that T30 supports 3 new higher freqs, but we map back - * to the old T20 freqs. Support for the higher oscillators is TBD. + * field. Note that T30+ supports 3 new higher freqs. */ enum clock_osc_freq clock_get_osc_freq(void) { @@ -449,12 +448,7 @@ enum clock_osc_freq clock_get_osc_freq(void) u32 reg; reg = readl(&clkrst->crc_osc_ctrl); - reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; - - if (reg & 1) /* one of the newer freqs */ - printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg); - - return reg >> 2; /* Map to most common (T20) freqs */ + return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; } /* Returns a pointer to the clock source register for a peripheral */ diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index b02ee89c3eca..6fe8594d48a9 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -127,42 +127,70 @@ struct fdt_usb { static const unsigned T20_usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = { /* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */ { 0x3C0, 0x0D, 0x00, 0xC, 0, 0x02, 0x33, 0x05, 0x7F, 0x7EF4, 5 }, + { 0x3C0, 0x0D, 0x00, 0xC, 0, 0x02, 0x33, 0x05, 0x7F, 0x7EF4, 5 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, + { 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x06, 0xBB, 0xBB80, 7 }, { 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x06, 0xBB, 0xBB80, 7 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, + { 0x3C0, 0x0C, 0x00, 0xC, 0, 0x02, 0x2F, 0x04, 0x76, 0x7530, 5 }, { 0x3C0, 0x0C, 0x00, 0xC, 0, 0x02, 0x2F, 0x04, 0x76, 0x7530, 5 }, - { 0x3C0, 0x1A, 0x00, 0xC, 0, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 9 }, { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, - { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 } + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, + { 0x3C0, 0x1A, 0x00, 0xC, 0, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 9 } }; static const unsigned T30_usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = { /* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */ { 0x3C0, 0x0D, 0x00, 0xC, 1, 0x02, 0x33, 0x09, 0x7F, 0x7EF4, 5 }, + { 0x3C0, 0x0D, 0x00, 0xC, 1, 0x02, 0x33, 0x09, 0x7F, 0x7EF4, 5 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, { 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x0C, 0xBB, 0xBB80, 7 }, + { 0x0C8, 0x04, 0x00, 0x3, 0, 0x03, 0x4B, 0x0C, 0xBB, 0xBB80, 7 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, { 0x3C0, 0x0C, 0x00, 0xC, 1, 0x02, 0x2F, 0x08, 0x76, 0x7530, 5 }, - { 0x3C0, 0x1A, 0x00, 0xC, 1, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 9 }, + { 0x3C0, 0x0C, 0x00, 0xC, 1, 0x02, 0x2F, 0x08, 0x76, 0x7530, 5 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, - { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 } + { 0x3C0, 0x1A, 0x00, 0xC, 1, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 9 } }; static const unsigned T114_usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = { /* DivN, DivM, DivP, CPCON, LFCON, Delays Debounce, Bias */ { 0x3C0, 0x0D, 0x00, 0xC, 2, 0x02, 0x33, 0x09, 0x7F, 0x7EF4, 6 }, + { 0x3C0, 0x0D, 0x00, 0xC, 2, 0x02, 0x33, 0x09, 0x7F, 0x7EF4, 6 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, + { 0x0C8, 0x04, 0x00, 0x3, 2, 0x03, 0x4B, 0x0C, 0xBB, 0xBB80, 8 }, { 0x0C8, 0x04, 0x00, 0x3, 2, 0x03, 0x4B, 0x0C, 0xBB, 0xBB80, 8 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, + { 0x3C0, 0x0C, 0x00, 0xC, 2, 0x02, 0x2F, 0x08, 0x76, 0x7530, 5 }, { 0x3C0, 0x0C, 0x00, 0xC, 2, 0x02, 0x2F, 0x08, 0x76, 0x7530, 5 }, - { 0x3C0, 0x1A, 0x00, 0xC, 2, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 11 }, { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, - { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 } + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0x0000, 0 }, + { 0x3C0, 0x1A, 0x00, 0xC, 2, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 11 } }; /* NOTE: 13/26MHz settings are N/A for T210, so dupe 12MHz settings for now */ static const unsigned T210_usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = { /* DivN, DivM, DivP, KCP, KVCO, Delays Debounce, Bias */ { 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 32500, 5 }, + { 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 32500, 5 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 }, { 0x019, 0x01, 0x01, 0x0, 0, 0x03, 0x4B, 0x0C, 0xBB, 48000, 8 }, - { 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 30000, 5 }, - { 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 65000, 5 }, { 0x019, 0x02, 0x01, 0x0, 0, 0x05, 0x96, 0x18, 0x177, 96000, 15 }, - { 0x028, 0x04, 0x01, 0x0, 0, 0x04, 0x66, 0x09, 0xFE, 120000, 20 } + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 }, + { 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 30000, 5 }, + { 0x028, 0x04, 0x01, 0x0, 0, 0x04, 0x66, 0x09, 0xFE, 120000, 20 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 }, + { 0x000, 0x00, 0x00, 0x0, 0, 0x00, 0x00, 0x00, 0x00, 0, 0 }, + { 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 65000, 5 } }; /* UTMIP Idle Wait Delay */ From 16a60bfc7fe03ab6f65ff47c1f18cff6f448d18e Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 21 Oct 2022 13:38:20 +0300 Subject: [PATCH 37/45] drivers: timer: add timer driver for ARMv7 based Tegra devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add timer support for T20/T30/T114 and T124 based devices. Driver is based on DM, has device tree support and can be used on SPL and early boot stage. Tested-by: Andreas Westman Dorcsak # ASUS TF600T T30 Tested-by: Jonas Schwöbel # Surface RT T30 Tested-by: Robert Eckelmann # ASUS TF101 T20 Tested-by: Svyatoslav Ryhel # LG P895 T30 Co-developed-by: Jonas Schwöbel Signed-off-by: Jonas Schwöbel Signed-off-by: Svyatoslav Ryhel --- drivers/timer/Kconfig | 8 +++ drivers/timer/Makefile | 1 + drivers/timer/tegra-timer.c | 124 ++++++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+) create mode 100644 drivers/timer/tegra-timer.c diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index 6d6665005cf8..f32bd16227e3 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -252,6 +252,14 @@ config STM32_TIMER Select this to enable support for the timer found on STM32 devices. +config TEGRA_TIMER + bool "Tegra timer support" + depends on TIMER + select TIMER_EARLY + help + Select this to enable support for the timer found on + Tegra devices. + config X86_TSC_TIMER bool "x86 Time-Stamp Counter (TSC) timer support" depends on TIMER && X86 diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile index 6470fd54266e..3c92113fc6fd 100644 --- a/drivers/timer/Makefile +++ b/drivers/timer/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_SP804_TIMER) += sp804_timer.o obj-$(CONFIG_$(SPL_)SIFIVE_CLINT) += sifive_clint_timer.o obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o obj-$(CONFIG_STM32_TIMER) += stm32_timer.o +obj-$(CONFIG_TEGRA_TIMER) += tegra-timer.o obj-$(CONFIG_X86_TSC_TIMER) += tsc_timer.o obj-$(CONFIG_MTK_TIMER) += mtk_timer.o obj-$(CONFIG_MCHP_PIT64B_TIMER) += mchp-pit64b-timer.o diff --git a/drivers/timer/tegra-timer.c b/drivers/timer/tegra-timer.c new file mode 100644 index 000000000000..cda460921f0c --- /dev/null +++ b/drivers/timer/tegra-timer.c @@ -0,0 +1,124 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2022 Svyatoslav Ryhel + */ + +#include +#include +#include +#include + +#include +#include +#include + +#define TEGRA_OSC_CLK_ENB_L_SET (NV_PA_CLK_RST_BASE + 0x320) +#define TEGRA_OSC_SET_CLK_ENB_TMR BIT(5) + +#define TEGRA_TIMER_USEC_CNTR (NV_PA_TMRUS_BASE + 0) +#define TEGRA_TIMER_USEC_CFG (NV_PA_TMRUS_BASE + 4) + +#define TEGRA_TIMER_RATE 1000000 /* 1 MHz */ + +u64 notrace timer_early_get_count(void) +{ + /* At this stage raw timer is used */ + return readl(TEGRA_TIMER_USEC_CNTR); +} + +unsigned long notrace timer_early_get_rate(void) +{ + return TEGRA_TIMER_RATE; +} + +#if CONFIG_IS_ENABLED(BOOTSTAGE) +ulong timer_get_boot_us(void) +{ + u64 ticks = 0; + int ret; + + ret = dm_timer_init(); + if (!ret) + timer_get_count(gd->timer, &ticks); + else + ticks = timer_early_get_count(); + + return ticks; +} +#endif + +static notrace u64 tegra_timer_get_count(struct udevice *dev) +{ + u32 val = timer_early_get_count(); + return timer_conv_64(val); +} + +static int tegra_timer_probe(struct udevice *dev) +{ + struct timer_dev_priv *uc_priv = dev_get_uclass_priv(dev); + u32 usec_config, value; + + /* Timer rate has to be set unconditionally */ + uc_priv->clock_rate = TEGRA_TIMER_RATE; + + /* + * Configure microsecond timers to have 1MHz clock + * Config register is 0xqqww, where qq is "dividend", ww is "divisor" + * Uses n+1 scheme + */ + switch (clock_get_osc_freq()) { + case CLOCK_OSC_FREQ_13_0: + usec_config = 0x000c; /* (12+1)/(0+1) */ + break; + case CLOCK_OSC_FREQ_19_2: + usec_config = 0x045f; /* (95+1)/(4+1) */ + break; + case CLOCK_OSC_FREQ_12_0: + usec_config = 0x000b; /* (11+1)/(0+1) */ + break; + case CLOCK_OSC_FREQ_26_0: + usec_config = 0x0019; /* (25+1)/(0+1) */ + break; + case CLOCK_OSC_FREQ_16_8: + usec_config = 0x0453; /* (83+1)/(4+1) */ + break; + case CLOCK_OSC_FREQ_38_4: + usec_config = 0x04bf; /* (191+1)/(4+1) */ + break; + case CLOCK_OSC_FREQ_48_0: + usec_config = 0x002f; /* (47+1)/(0+1) */ + break; + default: + return -EINVAL; + } + + /* Enable clock to timer hardware */ + value = readl_relaxed(TEGRA_OSC_CLK_ENB_L_SET); + writel_relaxed(value | TEGRA_OSC_SET_CLK_ENB_TMR, + TEGRA_OSC_CLK_ENB_L_SET); + + writel_relaxed(usec_config, TEGRA_TIMER_USEC_CFG); + + return 0; +} + +static const struct timer_ops tegra_timer_ops = { + .get_count = tegra_timer_get_count, +}; + +static const struct udevice_id tegra_timer_ids[] = { + { .compatible = "nvidia,tegra20-timer" }, + { .compatible = "nvidia,tegra30-timer" }, + { .compatible = "nvidia,tegra114-timer" }, + { .compatible = "nvidia,tegra124-timer" }, + { } +}; + +U_BOOT_DRIVER(tegra_timer) = { + .name = "tegra_timer", + .id = UCLASS_TIMER, + .of_match = tegra_timer_ids, + .probe = tegra_timer_probe, + .ops = &tegra_timer_ops, + .flags = DM_FLAG_PRE_RELOC, +}; From 91bb6e1859fef8c0fdcc6b7d00f3e5386b43f16e Mon Sep 17 00:00:00 2001 From: Svyatoslav Ryhel Date: Fri, 21 Oct 2022 13:39:23 +0300 Subject: [PATCH 38/45] ARM: tegra: include timer as default option Enable TIMER as default option for add Tegra devices and enable TEGRA_TIMER for TEGRA_ARMV7_COMMON. Additionally enable SPL_TIMER if build as SPL part and drop deprecated configs from common header. Signed-off-by: Svyatoslav Ryhel --- arch/arm/Kconfig | 1 + arch/arm/mach-tegra/Kconfig | 2 ++ include/configs/tegra-common.h | 6 ------ 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f95ed71b2466..8009c90f08ec 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1334,6 +1334,7 @@ config ARCH_TEGRA select GPIO_EXTRA_HEADER imply DISTRO_DEFAULTS imply FAT_WRITE + imply SPL_TIMER if SPL config ARCH_VEXPRESS64 bool "Support ARMv8 Arm Ltd. VExpress based boards and models" diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index a8956dcdc857..d2224327e464 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -66,6 +66,7 @@ config TEGRA_COMMON select MISC select OF_CONTROL select SPI + select TIMER imply CMD_DM imply CRC32_VERIFY @@ -91,6 +92,7 @@ config TEGRA_ARMV7_COMMON select TEGRA_NO_BPMP select TEGRA_PINCTRL select TEGRA_PMC + select TEGRA_TIMER config TEGRA_ARMV8_COMMON bool "Tegra 64-bit common options" diff --git a/include/configs/tegra-common.h b/include/configs/tegra-common.h index 2915db7f8bf7..390a2387ea18 100644 --- a/include/configs/tegra-common.h +++ b/include/configs/tegra-common.h @@ -15,12 +15,6 @@ #include /* get chip and board defs */ -/* Use the Tegra US timer on ARMv7, but the architected timer on ARMv8. */ -#ifndef CONFIG_ARM64 -#define CONFIG_SYS_TIMER_RATE 1000000 -#define CONFIG_SYS_TIMER_COUNTER NV_PA_TMRUS_BASE -#endif - /* Environment */ /* From b4f35ac595646eb58a1c49bd26e53ce1bfbb5039 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sat, 25 Jan 2020 18:35:55 +0100 Subject: [PATCH 39/45] ARM: tegra: add nvec driver Adopted version of nvec driver from linux kernel with keyboard support only. Signed-off-by: Andrey Danin [squashed, forward ported, and cleaned up] Signed-off-by: Marc Dietrich --- arch/arm/include/asm/arch-tegra/tegra_nvec.h | 117 ++++ .../asm/arch-tegra/tegra_nvec_events.h | 31 ++ drivers/i2c/Kconfig | 5 + drivers/i2c/Makefile | 1 + drivers/i2c/tegra_nvec.c | 524 ++++++++++++++++++ include/fdtdec.h | 1 + lib/fdtdec.c | 1 + 7 files changed, 680 insertions(+) create mode 100644 arch/arm/include/asm/arch-tegra/tegra_nvec.h create mode 100644 arch/arm/include/asm/arch-tegra/tegra_nvec_events.h create mode 100644 drivers/i2c/tegra_nvec.c diff --git a/arch/arm/include/asm/arch-tegra/tegra_nvec.h b/arch/arm/include/asm/arch-tegra/tegra_nvec.h new file mode 100644 index 000000000000..1c300281a8f5 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra/tegra_nvec.h @@ -0,0 +1,117 @@ +/* + * (C) Copyright 2013 + * Andrey Danin + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _TEGRA_NVEC_H_ +#define _TEGRA_NVEC_H_ + +#define I2C_CNFG 0x00 +#define I2C_CNFG_PACKET_MODE_EN (1<<10) +#define I2C_CNFG_NEW_MASTER_SFM (1<<11) +#define I2C_CNFG_DEBOUNCE_CNT_SHIFT 12 + +#define I2C_SL_CNFG 0x20 +#define I2C_SL_NEWSL (1<<2) +#define I2C_SL_NACK (1<<1) +#define I2C_SL_RESP (1<<0) +#define I2C_SL_IRQ (1<<3) +#define END_TRANS (1<<4) +#define RCVD (1<<2) +#define RNW (1<<1) + +#define I2C_SL_RCVD 0x24 +#define I2C_SL_STATUS 0x28 +#define I2C_SL_ADDR1 0x2c +#define I2C_SL_ADDR2 0x30 +#define I2C_SL_DELAY_COUNT 0x3c + + +enum nvec_msg_type { + NVEC_KEYBOARD = 0, + NVEC_SYS = 1, + NVEC_BAT, + NVEC_GPIO, + NVEC_SLEEP, + NVEC_KBD, + NVEC_PS2, + NVEC_CNTL, + NVEC_OEM0 = 0x0d, + NVEC_KB_EVT = 0x80, + NVEC_PS2_EVT, +}; + +enum nvec_event_size { + NVEC_2BYTES, + NVEC_3BYTES, + NVEC_VAR_SIZE, +}; + +enum sys_subcmds { + SYS_GET_STATUS, + SYS_CNFG_EVENT_REPORTING, + SYS_ACK_STATUS, + SYS_CNFG_WAKE = 0xfd, +}; + +enum kbd_subcmds { + CNFG_WAKE = 3, + CNFG_WAKE_KEY_REPORTING, + SET_LEDS = 0xed, + ENABLE_KBD = 0xf4, + DISABLE_KBD, +}; + +enum cntl_subcmds { + CNTL_RESET_EC = 0x00, + CNTL_SELF_TEST = 0x01, + CNTL_NOOP = 0x02, + CNTL_GET_EC_SPEC_VER = 0x10, + CNTL_GET_FIRMWARE_VERSION = 0x15, +}; + +enum nvec_sleep_subcmds { + GLOBAL_EVENTS, + AP_PWR_DOWN, + AP_SUSPEND, +}; + +#define MOUSE_SEND_CMD 0x01 +#define MOUSE_RESET 0xff + + +int board_nvec_init(void); + +int nvec_msg_is_event(const unsigned char *msg); +int nvec_msg_event_type(const unsigned char *msg); + +/** + * Send request and read response. If write or read failed + * operation will be repeated NVEC_ATTEMPTS_MAX times. + * + * @param buf request data + * @param size request data size + * @return 0 if ok, -1 on error + */ +int nvec_do_request(char *buf, int size); + + +#endif /* _TEGRA_NVEC_H_ */ diff --git a/arch/arm/include/asm/arch-tegra/tegra_nvec_events.h b/arch/arm/include/asm/arch-tegra/tegra_nvec_events.h new file mode 100644 index 000000000000..7d659214a877 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra/tegra_nvec_events.h @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2013 + * Andrey Danin + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _TEGRA_NVEC_EVENTS_H_ +#define _TEGRA_NVEC_EVENTS_H_ + + +int nvec_read_events(void); + + +#endif /* _TEGRA_NVEC_EVENTS_H_ */ diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 08b6c7bdcc42..2e119fb2e782 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -721,6 +721,11 @@ config SYS_I2C_IHS help Support for gdsys IHS I2C driver on FPGA bus. +config TEGRA_NVEC + bool "Enable Tegra 2 NVEC driver" + help + Support for Tegra 2 I2C NVEC keyboard. + source "drivers/i2c/muxes/Kconfig" endif diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 920aafb91c59..9d242fa2882f 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_$(SPL_)I2C_CROS_EC_TUNNEL) += cros_ec_tunnel.o obj-$(CONFIG_$(SPL_)I2C_CROS_EC_LDO) += cros_ec_ldo.o obj-$(CONFIG_$(SPL_)SYS_I2C_LEGACY) += i2c_core.o +obj-$(CONFIG_TEGRA_NVEC) += tegra_nvec.o obj-$(CONFIG_SYS_I2C_ASPEED) += ast_i2c.o obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o diff --git a/drivers/i2c/tegra_nvec.c b/drivers/i2c/tegra_nvec.c new file mode 100644 index 000000000000..bc76dfe56803 --- /dev/null +++ b/drivers/i2c/tegra_nvec.c @@ -0,0 +1,524 @@ +/* + * (C) Copyright 2013 + * Andrey Danin + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#define DEBUG 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef CONFIG_TEGRA_NVEC +#error "You should enable CONFIG_TEGRA_NVEC" +#endif + +DECLARE_GLOBAL_DATA_PTR; +#define TRACE() debug("nvec: %s\n", __func__) +#define error(fmt, args...) printf(pr_fmt(fmt), ##args) + +#define GPIO_ACTIVE 1 +#define GPIO_INACTIVE 0 + +/* Nvec perfroms io interval is beteween 20 and 500 ms, +no response in 600 ms means error */ +enum { + NVEC_TIMEOUT_MIN = 20, + NVEC_TIMEOUT_MAX = 600, +}; +enum { + NVEC_WAIT_FOR_EC = 1, + NVEC_DONT_WAIT_FOR_EC = 0, + NVEC_ATTEMPTS_MAX = 10, +}; + +enum { + nvec_io_error = -1, + nvec_io_timeout, + nvec_io_read_ok, + nvec_io_write_ok, + nvec_io_not_ready, + nvec_io_retry, +}; + +enum { + NVST_BEGIN = 0, + NVST_CMD = 1, + NVST_SUBCMD = 2, + NVST_READ = 3, + NVST_WRITE_SIZE = 4, + NVST_WRITE = 5, +}; + +struct nvec_t { + struct gpio_desc request_gpio; + int i2c_addr; + int i2c_clk; + void __iomem *base; + int state; + char rx_buf[34]; + int rx_pos; + char *tx_buf; + int tx_pos; + int tx_size; +} *nvec_data; + +#if 0 +struct fdt_nvec_config { + int gpio; + int i2c_addr; + int i2c_clk; + fdt_addr_t base_addr; + struct gpio_desc request_gpio; +}; +#endif + + +/* nvec commands */ +char noop[] = { NVEC_CNTL, CNTL_NOOP }; + + +int nvec_msg_is_event(const unsigned char *msg) +{ + return msg[0] >> 7; +} + + +int nvec_msg_event_type(const unsigned char *msg) +{ + return msg[0] & 0x0f; +} + + +/** + * Process incoming io message. + * If message is keyboard event then key code will + * be added to keys buffer. + * + * See: nvec_push_key, nvec_pop_key, nvec_have_key + * + * @param nvec nvec state struct + */ +void nvec_process_msg(struct nvec_t *nvec) +{ + const unsigned char *msg = (const unsigned char *)nvec->rx_buf; + int event_type; + + if (!nvec_msg_is_event(msg)) + return; + + event_type = nvec_msg_event_type(msg); + if (event_type == NVEC_KEYBOARD) + nvec_process_keyboard_msg(msg); +} + + +static inline int is_read(unsigned long status) +{ + return (status & RNW) == 0; +} + + +static inline int is_ready(unsigned long status) +{ + return status & I2C_SL_IRQ; +} + + +/** + * Perform complete io operation (read or write). + * NOTE: function will wait NVEC_TIMEOUT_MIN (20ms) + * before status check to avoid nvec hang. + * + * @param nvec nvec state struct + * @param wait_for_ec if 1(NVEC_WAIT_FOR_EC) operation + * timeout is NVEC_TIMEOUT_MAX (600ms), + * otherwise function will return if io + * is not ready. + * + * @return nvec_io_* code + */ +int nvec_do_io(struct nvec_t *nvec, int wait_for_ec) +{ + unsigned int poll_start_ms = 0; + unsigned long status; + unsigned int received = 0; + unsigned int to_send = 0; + unsigned int timeout_ms = NVEC_TIMEOUT_MAX; + int is_first_iteration = 1; + + if (!nvec_data) + return nvec_io_not_ready; + + poll_start_ms = get_timer(0); + mdelay(NVEC_TIMEOUT_MIN); + + while (1) { + status = readl(nvec->base + I2C_SL_STATUS); + if (!is_ready(status)) { + if (is_first_iteration && !wait_for_ec) + return nvec_io_not_ready; + + if (get_timer(poll_start_ms) > timeout_ms) + return nvec_io_timeout; + + is_first_iteration = 0; + udelay(100); + continue; + } + is_first_iteration = 0; + + if (is_read(status)) + received = readl(nvec->base + I2C_SL_RCVD); + + if (status == (I2C_SL_IRQ | RCVD)) { + nvec->state = NVST_BEGIN; + nvec->rx_pos = 0; + nvec->tx_pos = 0; + } + + switch (nvec->state) { + case NVST_BEGIN: + nvec->rx_pos = 0; + nvec->tx_pos = 0; + if (received != nvec->i2c_addr) { + error("NVEC io: unknown addr 0x%x", received); + return nvec_io_error; + } + nvec->state = NVST_CMD; + break; + + case NVST_CMD: + nvec->rx_buf[nvec->rx_pos++] = (char)received; + nvec->state = NVST_SUBCMD; + break; + + case NVST_SUBCMD: + if (status == (I2C_SL_IRQ | RNW | RCVD)) { + if (nvec->rx_buf[0] != 0x01) { + error("NVEC io: wrong read"); + nvec->state = NVST_BEGIN; + return nvec_io_error; + } + nvec->state = NVST_WRITE; + if (nvec->tx_buf == 0) { + debug("NVEC io: error, tx buffer is 0\n"); + nvec->tx_buf = noop; + nvec->tx_size = 2; + nvec->tx_pos = 0; + } + to_send = nvec->tx_size; + writel(to_send, nvec->base + I2C_SL_RCVD); + if (dm_gpio_set_value(&nvec_data->request_gpio, GPIO_INACTIVE)) + error("NVEC io: failed to set gpio value to INACTIVE"); + nvec->state = NVST_WRITE; + } else { + nvec->state = NVST_READ; + nvec->rx_buf[nvec->rx_pos] = (char)received; + ++nvec->rx_pos; + } + break; + + case NVST_READ: + if (nvec->rx_pos >= 34) { + error("NVEC io: read buffer is full"); + break; + } + nvec->rx_buf[nvec->rx_pos++] = (char)received; + if (status & END_TRANS) { + nvec_process_msg(nvec); + nvec->rx_pos = 0; + return nvec_io_read_ok; + } + break; + + case NVST_WRITE_SIZE: + to_send = nvec->tx_size; + writel(to_send, nvec->base + I2C_SL_RCVD); + nvec->state = NVST_WRITE; + break; + + case NVST_WRITE: + if (nvec->tx_pos >= nvec->tx_size) { + if (status & END_TRANS) + return nvec_io_write_ok; + + error("NVEC io: no data to write"); + return nvec_io_error; + } + to_send = nvec->tx_buf[nvec->tx_pos++]; + writel(to_send, nvec->base + I2C_SL_RCVD); + if (status & END_TRANS) { + nvec->tx_pos = 0; + nvec->tx_buf = 0; + return nvec_io_write_ok; + } + + break; + + default: + error("NVEC io: unknown state"); + break; + } + if (status & END_TRANS) + return nvec_io_retry; + } +} + + +/** + * Send request and read response. If write or read failed + * operation will be repeated NVEC_ATTEMPTS_MAX times. + * + * @param buf request data + * @param size request data size + * @return 0 if ok, -1 on error + */ +int nvec_do_request(char *buf, int size) +{ + int res = 0; + int i = 0; + int send_failed = 0; + int recv_failed = 0; + int gpio_failed = 0; + + nvec_data->tx_buf = buf; + nvec_data->tx_size = size; + + while (i++ < NVEC_ATTEMPTS_MAX) { + nvec_data->tx_pos = 0; + + /* request */ + if (dm_gpio_set_value(&nvec_data->request_gpio, GPIO_ACTIVE)) { + ++gpio_failed; + error("NVEC io: failed to set gpio value to ACTIVE"); + } + + res = nvec_do_io(nvec_data, NVEC_WAIT_FOR_EC); + if (res != nvec_io_write_ok) { + ++send_failed; + debug("warning: nvec failed to send request\n"); + continue; + } + + /* response */ + res = nvec_do_io(nvec_data, NVEC_WAIT_FOR_EC); + if (res != nvec_io_read_ok) { + ++recv_failed; + debug("warning: nvec failed to read response\n"); + continue; + } + + nvec_data->tx_buf = 0; + nvec_data->tx_size = 0; + nvec_data->tx_pos = 0; + + return 0; + } + + error("nvec failed to perform request (send: %d, recv: %d, gpio: %d)", + send_failed, recv_failed, gpio_failed); + return -1; +} + + +/** + * Init i2c controller to operate in slave mode. + * + * @param nvec nvec state struct + */ +static void nvec_init_i2c_slave(struct nvec_t *nvec) +{ + unsigned long val; + + val = I2C_CNFG_NEW_MASTER_SFM | I2C_CNFG_PACKET_MODE_EN | + (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT); + writel(val, nvec->base + I2C_CNFG); + + /* i2c3 -> 67 */ + clock_start_periph_pll(67, CLOCK_ID_PERIPH, + nvec->i2c_clk * 8); + + reset_periph(67, 1); + + writel(I2C_SL_NEWSL, nvec->base + I2C_SL_CNFG); + writel(0x1E, nvec->base + I2C_SL_DELAY_COUNT); + + writel(nvec->i2c_addr>>1, nvec->base + I2C_SL_ADDR1); + writel(0, nvec->base + I2C_SL_ADDR2); + + funcmux_select(67, FUNCMUX_DEFAULT); +} + + +/** + * Decode the nvec information from the fdt. + * + * @param blob fdt blob + * @param config structure to store fdt config into + * @return 0 if ok, -ve on error + */ +static int nvec_decode_fdt(const void *blob, int node, + struct nvec_t *nvec) +{ +// int ret; + +// ret = gpio_request_by_name_nodev(blob, node, "request-gpios", 0, +// &nvec->request_gpio, GPIOD_IS_OUT); +// if (ret < 0) { +// error("Failed to get request-gpios (%d)", ret); +// return -ENOENT; +// } + + nvec->base = (void __iomem *)fdtdec_get_addr(blob, node, "reg"); + if (nvec->base == (void __iomem *)FDT_ADDR_T_NONE) { + error("No NVEC controller address"); + return -ENOENT; + } + nvec->i2c_addr = fdtdec_get_int(blob, node, "slave-addr", -1); + nvec->i2c_clk = fdtdec_get_int(blob, node, "clock-frequency", -1); + + return 0; +} + +static int nvec_probe(struct udevice *dev) +{ + struct nvec_t *nvec = dev_get_priv(dev); + const void *blob = gd->fdt_blob; + int node = dev->node.of_offset; + int res; + + TRACE(); + nvec_data = nvec; + + nvec_data->rx_pos = 0; + nvec_data->tx_buf = 0; + nvec_data->tx_pos = 0; + nvec_data->tx_size = 0; + nvec_data->state = NVST_BEGIN; + + debug("NVEC initialization...\n"); + + if (nvec_decode_fdt(blob, node, nvec_data)) { + error("Failed to decode fdt"); + return -EBUSY; + } + + res = gpio_request_by_name(dev, "request-gpios", 0, &nvec_data->request_gpio, GPIOD_IS_OUT); + if (res != 0) + error("NVEC: err, gpio_request (%d)", res); + debug("request-gpios flags: 0x%lx\n", nvec_data->request_gpio.flags); + res = dm_gpio_set_value(&nvec_data->request_gpio, GPIO_INACTIVE); + if (res != 0) + error("NVEC: err, dm_gpio_set_value to INACTIVE error (%d)", res); + udelay(100); + + nvec_init_i2c_slave(nvec_data); + + nvec_enable_kbd_events(); + + // TODO: free gpios and memory + + return 0; +} + + +int nvec_read_events(void) +{ + int res; + int cnt = 0; + + while (++cnt <= 8) { + res = nvec_do_io(nvec_data, NVEC_DONT_WAIT_FOR_EC); + switch (res) { + case nvec_io_not_ready: + return 0; + + case nvec_io_read_ok: + case nvec_io_retry: + break; + + case nvec_io_error: + case nvec_io_timeout: + debug("NVEC events: io failed %d\n", res); + return 0; + + case nvec_io_write_ok: + default: + debug("NVEC events: unexpected io result %d\n", res); + return 0; + } + } + + return 0; +} + +static int nvec_set_bus_speed(struct udevice *dev, unsigned int speed) +{ + TRACE(); + return 0; +} + +static int nvec_xfer(struct udevice *dev, struct i2c_msg *msg, + int nmsgs) +{ + TRACE(); + return 0; +} + +/* Probe to see if a chip is present. */ +static int nvec_probe_chip(struct udevice *bus, uint chip_addr, + uint chip_flags) +{ + /* Shift 7-bit address over for lower-level i2c functions */ + /*rc = tegra_i2c_write_data(i2c_bus, chip_addr << 1, ®, sizeof(reg), + false);*/ + TRACE(); + + return 0; +} + +static const struct dm_i2c_ops i2c_nvec_ops = { + .xfer = nvec_xfer, + .probe_chip = nvec_probe_chip, + .set_bus_speed = nvec_set_bus_speed, +}; + +static const struct udevice_id i2c_nvec_ids[] = { + { .compatible = "nvidia,tegra20-nvec" }, + { } +}; + +U_BOOT_DRIVER(i2c_nvec) = { + .name = "i2c-nvec", + .id = UCLASS_I2C, + .of_match = i2c_nvec_ids, + .probe = nvec_probe, + .priv_auto_alloc_size = sizeof(struct nvec_t), + .ops = &i2c_nvec_ops, +}; diff --git a/include/fdtdec.h b/include/fdtdec.h index 12355afd7fa1..c03bf33e5452 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -168,6 +168,7 @@ enum fdt_compat_id { COMPAT_NVIDIA_TEGRA20_EMC, /* Tegra20 memory controller */ COMPAT_NVIDIA_TEGRA20_EMC_TABLE, /* Tegra20 memory timing table */ COMPAT_NVIDIA_TEGRA20_NAND, /* Tegra2 NAND controller */ + COMPAT_NVIDIA_TEGRA20_NVEC, /* Tegra 2 EC controller */ COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL, /* Tegra124 XUSB pad controller */ COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL, diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 64c5b3da15ef..312e370e6af4 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -47,6 +47,7 @@ static const char * const compat_names[COMPAT_COUNT] = { COMPAT(NVIDIA_TEGRA20_EMC, "nvidia,tegra20-emc"), COMPAT(NVIDIA_TEGRA20_EMC_TABLE, "nvidia,tegra20-emc-table"), COMPAT(NVIDIA_TEGRA20_NAND, "nvidia,tegra20-nand"), + COMPAT(NVIDIA_TEGRA20_NVEC, "nvidia,tegra20-nvec"), COMPAT(NVIDIA_TEGRA124_XUSB_PADCTL, "nvidia,tegra124-xusb-padctl"), COMPAT(NVIDIA_TEGRA210_XUSB_PADCTL, "nvidia,tegra210-xusb-padctl"), COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"), From 5df65c444c84b57996cb7a73bc2e72eabf5274f3 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sat, 25 Jan 2020 18:40:40 +0100 Subject: [PATCH 40/45] ARM: tegra: add nvec keyboard driver Adopted version of nvec keyboard driver from linux kernel. Signed-off-by: Andrey Danin [squashed, forward ported, and cleaned up] Signed-off-by: Marc Dietrich --- .../asm/arch-tegra/tegra_nvec_keyboard.h | 36 ++ .../asm/arch-tegra/tegra_nvec_keytable.h | 313 ++++++++++++++++++ drivers/i2c/Makefile | 1 + drivers/i2c/tegra_nvec_keyboard.c | 112 +++++++ drivers/input/Kconfig | 6 + drivers/input/Makefile | 1 + drivers/input/tegra-nvec-kbc.c | 143 ++++++++ 7 files changed, 612 insertions(+) create mode 100644 arch/arm/include/asm/arch-tegra/tegra_nvec_keyboard.h create mode 100644 arch/arm/include/asm/arch-tegra/tegra_nvec_keytable.h create mode 100644 drivers/i2c/tegra_nvec_keyboard.c create mode 100644 drivers/input/tegra-nvec-kbc.c diff --git a/arch/arm/include/asm/arch-tegra/tegra_nvec_keyboard.h b/arch/arm/include/asm/arch-tegra/tegra_nvec_keyboard.h new file mode 100644 index 000000000000..b25a1d89388d --- /dev/null +++ b/arch/arm/include/asm/arch-tegra/tegra_nvec_keyboard.h @@ -0,0 +1,36 @@ +/* + * (C) Copyright 2013 + * Andrey Danin + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _TEGRA_NVEC_KEYBOARD_H_ +#define _TEGRA_NVEC_KEYBOARD_H_ + + +#define NVEC_KEYS_QUEUE_SIZE 256 + +void nvec_enable_kbd_events(void); +void nvec_process_keyboard_msg(const unsigned char *msg); +int nvec_pop_key(void); +int nvec_have_keys(void); + + +#endif /* _TEGRA_NVEC_KEYBOARD_H_ */ diff --git a/arch/arm/include/asm/arch-tegra/tegra_nvec_keytable.h b/arch/arm/include/asm/arch-tegra/tegra_nvec_keytable.h new file mode 100644 index 000000000000..8fbf96c05bf2 --- /dev/null +++ b/arch/arm/include/asm/arch-tegra/tegra_nvec_keytable.h @@ -0,0 +1,313 @@ +/* + * Keyboard class input driver for keyboards connected to an NvEc compliant + * embedded controller + * + * Copyright (c) 2009, NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _TEGRA_NVEC_KEYTABLE_H_ +#define _TEGRA_NVEC_KEYTABLE_H_ + +#include + + +static unsigned short code_tab_102us[] = { + /* 0x00 */ + KEY_GRAVE, + KEY_ESC, + KEY_1, + KEY_2, + KEY_3, + KEY_4, + KEY_5, + KEY_6, + KEY_7, + KEY_8, + KEY_9, + KEY_0, + KEY_MINUS, + KEY_EQUAL, + KEY_BACKSPACE, + KEY_TAB, + /* 0x10 */ + KEY_Q, + KEY_W, + KEY_E, + KEY_R, + KEY_T, + KEY_Y, + KEY_U, + KEY_I, + KEY_O, + KEY_P, + KEY_LEFTBRACE, + KEY_RIGHTBRACE, + KEY_ENTER, + KEY_LEFTCTRL, + KEY_A, + KEY_S, + /* 0x20 */ + KEY_D, + KEY_F, + KEY_G, + KEY_H, + KEY_J, + KEY_K, + KEY_L, + KEY_SEMICOLON, + KEY_APOSTROPHE, + KEY_GRAVE, + KEY_LEFTSHIFT, + KEY_BACKSLASH, + KEY_Z, + KEY_X, + KEY_C, + KEY_V, + /* 0x30 */ + KEY_B, + KEY_N, + KEY_M, + KEY_COMMA, + KEY_DOT, + KEY_SLASH, + KEY_RIGHTSHIFT, + KEY_KPASTERISK, + KEY_LEFTALT, + KEY_SPACE, + KEY_CAPSLOCK, + KEY_F1, + KEY_F2, + KEY_F3, + KEY_F4, + KEY_F5, + /* 0x40 */ + KEY_F6, + KEY_F7, + KEY_F8, + KEY_F9, + KEY_F10, + KEY_FN, + /* VK_SCROLL */ + 0, + KEY_KP7, + KEY_KP8, + KEY_KP9, + KEY_KPMINUS, + KEY_KP4, + KEY_KP5, + KEY_KP6, + KEY_KPPLUS, + KEY_KP1, + /* 0x50 */ + KEY_KP2, + KEY_KP3, + KEY_KP0, + KEY_KPDOT, + /* VK_SNAPSHOT */ + 0, /* KEY_MENU, */ + KEY_POWER, + /* VK_OEM_102 */ + KEY_102ND, + KEY_F11, + KEY_F12, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + /* 0x60 */ + 0, + 0, + 0, + 0, /* KEY_SEARCH, */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + /* 0x70 */ + 0, + 0, + 0, + KEY_KP5, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + KEY_KP9, +}; + +static unsigned short extcode_tab_us102[] = { + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + /* 0x10 */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + /* VK_MEDIA_NEXT_TRACK */ + 0, + 0, + 0, + /* VK_RETURN */ + 0, + KEY_RIGHTCTRL, + 0, + 0, + /* 0x20 */ + KEY_MUTE, + /* VK_LAUNCH_APP1 */ + 0, + /* VK_MEDIA_PLAY_PAUSE */ + 0, + 0, + /* VK_MEDIA_STOP */ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + /* 0x30 */ + KEY_VOLUMEUP, + 0, + /* VK_BROWSER_HOME */ + 0, + 0, + 0, + /* VK_DIVIDE */ + KEY_KPSLASH, + 0, + /* VK_SNAPSHOT */ + KEY_SYSRQ, + /* VK_RMENU */ + KEY_RIGHTALT, + /* VK_OEM_NV_BACKLIGHT_UP */ + 0, + /* VK_OEM_NV_BACKLIGHT_DN */ + 0, + /* VK_OEM_NV_BACKLIGHT_AUTOTOGGLE */ + 0, + /* VK_OEM_NV_POWER_INFO */ + 0, + /* VK_OEM_NV_WIFI_TOGGLE */ + 0, + /* VK_OEM_NV_DISPLAY_SELECT */ + 0, + /* VK_OEM_NV_AIRPLANE_TOGGLE */ + 0, + /* 0x40 */ + 0, + KEY_LEFT, + 0, + 0, + 0, + 0, + 0, /* KEY_CANCEL, */ + KEY_HOME, + KEY_UP, + KEY_PAGEUP, + 0, + KEY_LEFT, + 0, + KEY_RIGHT, + 0, + KEY_END, + /* 0x50 */ + KEY_DOWN, + KEY_PAGEDOWN, + KEY_INSERT, + KEY_DELETE, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + KEY_LEFTMETA, + 0, + KEY_ESC, + KEY_KPMINUS, + 0, + 0, + 0, + 0, + 0, + 0, + /* VK_BROWSER_SEARCH */ + 0, + /* VK_BROWSER_FAVORITES */ + 0, + /* VK_BROWSER_REFRESH */ + 0, + /* VK_BROWSER_STOP */ + 0, + /* VK_BROWSER_FORWARD */ + 0, + /* VK_BROWSER_BACK */ + 0, + /* VK_LAUNCH_APP2 */ + 0, + /* VK_LAUNCH_MAIL */ + 0, + /* VK_LAUNCH_MEDIA_SELECT */ + 0, +}; + +static unsigned short *code_tabs[] = { code_tab_102us, extcode_tab_us102 }; + +#endif /* _TEGRA_NVEC_KEYTABLE_H_ */ diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 9d242fa2882f..a9dd8814d769 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_$(SPL_)I2C_CROS_EC_LDO) += cros_ec_ldo.o obj-$(CONFIG_$(SPL_)SYS_I2C_LEGACY) += i2c_core.o obj-$(CONFIG_TEGRA_NVEC) += tegra_nvec.o +obj-$(CONFIG_TEGRA_NVEC_KEYBOARD) += tegra_nvec_keyboard.o obj-$(CONFIG_SYS_I2C_ASPEED) += ast_i2c.o obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o diff --git a/drivers/i2c/tegra_nvec_keyboard.c b/drivers/i2c/tegra_nvec_keyboard.c new file mode 100644 index 000000000000..158a6009ebb4 --- /dev/null +++ b/drivers/i2c/tegra_nvec_keyboard.c @@ -0,0 +1,112 @@ +/* + * (C) Copyright 2013 + * Andrey Danin + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + + +#define TRACE() debug("nvec keyboard: %s\n", __func__) +#define error(fmt, args...) printf(pr_fmt(fmt), ##args) + +circbuf_t key_buf = { 0, 0, NULL, NULL, NULL, NULL }; + +/* nvec commands */ +static char enable_kbd[] = { NVEC_KBD, ENABLE_KBD }; +static char reset_kbd[] = { NVEC_PS2, MOUSE_SEND_CMD, MOUSE_RESET, 3 }; +static char clear_leds[] = { NVEC_KBD, SET_LEDS, 0 }; + + +void nvec_push_key(unsigned short code, unsigned short state) +{ + int code_state; + + assert(key_buf.totalsize > 0); + + if (key_buf.size == key_buf.totalsize) + return; + + code_state = ((state << 16) | code); + buf_push(&key_buf, (const char *)&code_state, sizeof(code_state)); +} + + +int nvec_have_keys(void) +{ + return key_buf.size > 0; +} + + +int nvec_pop_key(void) +{ + int code_state; + int len = buf_pop(&key_buf, (char *)&code_state, sizeof(code_state)); + + if (len < sizeof(code_state)) + return -1; + + return code_state; +} + + +void nvec_process_keyboard_msg(const unsigned char *msg) +{ + int code, state; + int event_type; + int _size; + + event_type = nvec_msg_event_type(msg); + if (event_type != NVEC_KEYBOARD) + return; + + _size = (msg[0] & (3 << 5)) >> 5; + + if (_size == NVEC_VAR_SIZE) + return; + + if (_size == NVEC_3BYTES) + msg++; + + code = msg[1] & 0x7f; + state = msg[1] & 0x80; + + nvec_push_key(code_tabs[_size][code], state); +} + + +void nvec_enable_kbd_events(void) +{ + TRACE(); + buf_init(&key_buf, NVEC_KEYS_QUEUE_SIZE * sizeof(int)); + + if (nvec_do_request(reset_kbd, 4)) + error("NVEC: failed to reset keyboard\n"); + if (nvec_do_request(clear_leds, 3)) + error("NVEC: failed to clear leds\n"); + if (nvec_do_request(enable_kbd, 2)) + error("NVEC: failed to enable keyboard\n"); + + debug("NVEC: keyboard initialization finished\n"); +} diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig index 6f682efde5ec..5700d8cbf34f 100644 --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -87,6 +87,12 @@ config TEGRA_KEYBOARD A matrix keyboard connected directly to the internal keyboard controller on Tegra SoCs. +config TEGRA_NVEC_KEYBOARD + bool "Enable NVEC keyboard" + depends on TEGRA_NVEC + help + This adds NVEC keyboard driver. + config TWL4030_INPUT bool "Enable TWL4030 Input controller" help diff --git a/drivers/input/Makefile b/drivers/input/Makefile index c56415dffd08..71551d002cf6 100644 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -12,6 +12,7 @@ ifndef CONFIG_SPL_BUILD obj-$(CONFIG_APPLE_SPI_KEYB) += apple_spi_kbd.o obj-$(CONFIG_I8042_KEYB) += i8042.o obj-$(CONFIG_TEGRA_KEYBOARD) += input.o tegra-kbc.o +obj-$(CONFIG_TEGRA_NVEC_KEYBOARD) += tegra-nvec-kbc.o obj-$(CONFIG_TWL4030_INPUT) += twl4030.o obj-$(CONFIG_TWL6030_INPUT) += twl6030.o obj-$(CONFIG_GPIO_KEYBOARD) += gpio-kbd.o diff --git a/drivers/input/tegra-nvec-kbc.c b/drivers/input/tegra-nvec-kbc.c new file mode 100644 index 000000000000..d46b768635d4 --- /dev/null +++ b/drivers/input/tegra-nvec-kbc.c @@ -0,0 +1,143 @@ +/* + * (C) Copyright 2011,2013 + * Andrey Danin + * NVIDIA Corporation + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#define DEBUG 0 + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TRACE() debug("%s\n", __func__) + +enum { + KBC_MAX_KPENT = 8, +}; + +enum { + KBC_REPEAT_RATE_MS = 30, + KBC_REPEAT_DELAY_MS = 240, +}; + +/** + * Check the tegra nvec keyboard, and send any keys that are pressed. + * + * This is called by input_tstc() and input_getc() when they need more + * characters + * + * @param input Input configuration + * @return 1, to indicate that we have something to look at + */ +int tegra_nvec_kbc_check(struct input_config *input) +{ + int res = 0; + int fifo[KBC_MAX_KPENT]; + int cnt = 0; + + if (!nvec_have_keys()) + nvec_read_events(); + + while (nvec_have_keys() && cnt < KBC_MAX_KPENT) { + res = 1; + fifo[cnt++] = nvec_pop_key(); + if (cnt == KBC_MAX_KPENT) { + input_send_keycodes(input, fifo, cnt); + cnt = 0; + } + } + + if (cnt > 0) + input_send_keycodes(input, fifo, cnt); + + return res; +} + + +static int tegra_nvec_kbd_start(struct udevice *dev) +{ + (void)dev; + + debug("%s: Tegra nvec keyboard ready\n", __func__); + + return 0; +} + +/** + * Set up the tegra keyboard. This is called by the stdio device handler + * + * We want to do this init when the keyboard is actually used rather than + * at start-up, since keyboard input may not currently be selected. + * + * Once the keyboard starts there will be a period during which we must + * wait for the keyboard to init. We do this only when a key is first + * read - see kbd_wait_for_fifo_init(). + * + * @return 0 if ok, -ve on error + */ +static int tegra_nvec_kbd_probe(struct udevice *dev) +{ + (void)dev; + struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); + struct stdio_dev *sdev = &uc_priv->sdev; + struct input_config *input = &uc_priv->input; + int ret; + + TRACE(); + input_set_delays(input, KBC_REPEAT_DELAY_MS, KBC_REPEAT_RATE_MS); + + input->dev = dev; + input->read_keys = tegra_nvec_kbc_check; + input_add_tables(input, false); + strcpy(sdev->name, "tegra-nvec-kbc"); + ret = input_stdio_register(sdev); + if (ret) { + debug("%s: input_stdio_register() failed\n", __func__); + return ret; + } + + debug("tegra kbc is initialized\n"); + + return 0; +} + +static const struct keyboard_ops tegra_nvec_kbd_ops = { + .start = tegra_nvec_kbd_start, +}; + +static const struct udevice_id tegra_nvec_kbd_ids[] = { + { .compatible = "nvidia,tegra20-nvec-kbc" }, + { } +}; + +U_BOOT_DRIVER(tegra_kbd) = { + .name = "tegra_nvec_kbd", + .id = UCLASS_KEYBOARD, + .of_match = tegra_nvec_kbd_ids, + .probe = tegra_nvec_kbd_probe, + .ops = &tegra_nvec_kbd_ops, +}; From c51651890908fa2d12960260b624b92e0afca489 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Sat, 25 Jan 2020 19:02:13 +0100 Subject: [PATCH 41/45] ARM: tegra: paz00: enable nvec keyboard support Signed-off-by: Andrey Danin [squashed, forward ported, and cleaned up] Signed-off-by: Marc Dietrich --- arch/arm/dts/tegra20-paz00.dts | 15 +++++++++++++++ configs/paz00_defconfig | 1 + include/configs/paz00.h | 12 ++++++++++++ include/configs/tegra-common-post.h | 2 ++ 4 files changed, 30 insertions(+) diff --git a/arch/arm/dts/tegra20-paz00.dts b/arch/arm/dts/tegra20-paz00.dts index ecf9fbd2ca70..08fe8a81b086 100644 --- a/arch/arm/dts/tegra20-paz00.dts +++ b/arch/arm/dts/tegra20-paz00.dts @@ -633,4 +633,19 @@ <&tegra_car TEGRA20_CLK_CDEV1>; clock-names = "pll_a", "pll_a_out0", "mclk"; }; + + nvec { + compatible = "nvidia,tegra20-nvec"; + reg = <0x7000c500 0x100>; + clock-frequency = <80000>; + request-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>; + slave-addr = <138>; + #address-cells = <1>; + #size-cells = <1>; + + kbc@0x1 { + reg = <0x0 0x0>; + compatible = "nvidia,tegra20-nvec-kbc"; + }; + }; }; diff --git a/configs/paz00_defconfig b/configs/paz00_defconfig index 558375da9f3e..1163494883c0 100644 --- a/configs/paz00_defconfig +++ b/configs/paz00_defconfig @@ -9,6 +9,7 @@ CONFIG_DEFAULT_DEVICE_TREE="tegra20-paz00" CONFIG_SPL_TEXT_BASE=0x00108000 CONFIG_SYS_PROMPT="Tegra20 (Paz00) MOD # " CONFIG_TEGRA20=y +CONFIG_DM_I2C=y CONFIG_TARGET_PAZ00=y CONFIG_SYS_LOAD_ADDR=0x1000000 CONFIG_OF_SYSTEM_SETUP=y diff --git a/include/configs/paz00.h b/include/configs/paz00.h index c12f4d0937d5..2a8f296e342c 100644 --- a/include/configs/paz00.h +++ b/include/configs/paz00.h @@ -21,6 +21,18 @@ /* Environment in eMMC, at the end of 2nd "boot sector" */ +/* Keyboard support */ +#define CONFIG_KEYBOARD +#define CONFIG_TEGRA_NVEC_KEYBOARD +/* NVEC support */ +#define CONFIG_CMD_I2C +#define CONFIG_SYS_I2C_INIT_BOARD +#define CONFIG_TEGRA_NVEC +#define BOARD_EXTRA_ENV_SETTINGS \ + "i2c dev 0" "\0" \ + "i2c dev 1" "\0" \ + "i2c dev 2" "\0" + #include "tegra-common-post.h" #endif /* __CONFIG_H */ diff --git a/include/configs/tegra-common-post.h b/include/configs/tegra-common-post.h index 527dec17d901..195fb31fa04d 100644 --- a/include/configs/tegra-common-post.h +++ b/include/configs/tegra-common-post.h @@ -25,6 +25,8 @@ #ifdef CONFIG_TEGRA_KEYBOARD #define STDIN_KBD_KBC ",tegra-kbc" +#elif defined(CONFIG_TEGRA_NVEC_KEYBOARD) +#define STDIN_KBD_KBC ",tegra-nvec-kbc" #else #define STDIN_KBD_KBC "" #endif From 72ae62d08198eac7593fb73d32a14051c777a5e0 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Wed, 14 Apr 2021 22:48:30 +0200 Subject: [PATCH 42/45] i2c: tegra_nvec: Use dev_read_addr_ptr/u32_default Signed-off-by: Nicolas Chauvet --- drivers/i2c/tegra_nvec.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/i2c/tegra_nvec.c b/drivers/i2c/tegra_nvec.c index bc76dfe56803..52ecbcb3b294 100644 --- a/drivers/i2c/tegra_nvec.c +++ b/drivers/i2c/tegra_nvec.c @@ -24,6 +24,7 @@ #define DEBUG 0 #include +#include #include #include #include @@ -379,12 +380,11 @@ static void nvec_init_i2c_slave(struct nvec_t *nvec) /** * Decode the nvec information from the fdt. * - * @param blob fdt blob - * @param config structure to store fdt config into + * @param dev nvec device + * @param config structure to store fdt config into * @return 0 if ok, -ve on error */ -static int nvec_decode_fdt(const void *blob, int node, - struct nvec_t *nvec) +static int nvec_decode_fdt(struct udevice *dev, struct nvec_t *nvec) { // int ret; @@ -395,13 +395,12 @@ static int nvec_decode_fdt(const void *blob, int node, // return -ENOENT; // } - nvec->base = (void __iomem *)fdtdec_get_addr(blob, node, "reg"); - if (nvec->base == (void __iomem *)FDT_ADDR_T_NONE) { - error("No NVEC controller address"); - return -ENOENT; - } - nvec->i2c_addr = fdtdec_get_int(blob, node, "slave-addr", -1); - nvec->i2c_clk = fdtdec_get_int(blob, node, "clock-frequency", -1); + nvec->base = dev_read_addr_ptr(dev); + if (!nvec->base) + return -ENOMEM; + + nvec->i2c_addr = dev_read_u32_default(dev, "slave-addr", -1); + nvec->i2c_clk = dev_read_u32_default(dev, "clock-frequency", -1); return 0; } @@ -409,8 +408,6 @@ static int nvec_decode_fdt(const void *blob, int node, static int nvec_probe(struct udevice *dev) { struct nvec_t *nvec = dev_get_priv(dev); - const void *blob = gd->fdt_blob; - int node = dev->node.of_offset; int res; TRACE(); @@ -424,7 +421,7 @@ static int nvec_probe(struct udevice *dev) debug("NVEC initialization...\n"); - if (nvec_decode_fdt(blob, node, nvec_data)) { + if (nvec_decode_fdt(dev, nvec_data)) { error("Failed to decode fdt"); return -EBUSY; } @@ -519,6 +516,6 @@ U_BOOT_DRIVER(i2c_nvec) = { .id = UCLASS_I2C, .of_match = i2c_nvec_ids, .probe = nvec_probe, - .priv_auto_alloc_size = sizeof(struct nvec_t), + .priv_auto = sizeof(struct nvec_t), .ops = &i2c_nvec_ops, }; From 24e073562832f948b8cbe5fe1827aa543f2167f5 Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 25 Nov 2022 15:54:26 +0100 Subject: [PATCH 43/45] Select CIRCBUF for TEGRA_NVEC Signed-off-by: Nicolas Chauvet --- drivers/i2c/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 2e119fb2e782..902c694bba24 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -723,6 +723,7 @@ config SYS_I2C_IHS config TEGRA_NVEC bool "Enable Tegra 2 NVEC driver" + select CIRCBUF help Support for Tegra 2 I2C NVEC keyboard. From 2cba2cfd6150b4ecfba5d833ee399c2cecb5cf0e Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 25 Nov 2022 16:01:14 +0100 Subject: [PATCH 44/45] Switch to DM_KEYBOARD Signed-off-by: Nicolas Chauvet --- configs/paz00_defconfig | 1 + include/configs/paz00.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/configs/paz00_defconfig b/configs/paz00_defconfig index 1163494883c0..ec8ae29ec28a 100644 --- a/configs/paz00_defconfig +++ b/configs/paz00_defconfig @@ -40,6 +40,7 @@ CONFIG_ENV_IS_IN_MMC=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_SYS_MMC_ENV_PART=2 CONFIG_SPL_DM=y +CONFIG_DM_KEYBOARD=y CONFIG_DM_PMIC=y CONFIG_DM_REGULATOR=y CONFIG_DM_REGULATOR_FIXED=y diff --git a/include/configs/paz00.h b/include/configs/paz00.h index 2a8f296e342c..3a5b8ff3a739 100644 --- a/include/configs/paz00.h +++ b/include/configs/paz00.h @@ -22,7 +22,6 @@ /* Environment in eMMC, at the end of 2nd "boot sector" */ /* Keyboard support */ -#define CONFIG_KEYBOARD #define CONFIG_TEGRA_NVEC_KEYBOARD /* NVEC support */ #define CONFIG_CMD_I2C From 82ae625d268f0bd4cee64aff36127ec6d6e6c6ba Mon Sep 17 00:00:00 2001 From: Nicolas Chauvet Date: Fri, 25 Nov 2022 16:09:44 +0100 Subject: [PATCH 45/45] Switch NVEC KEYBOARD to defconfig Signed-off-by: Nicolas Chauvet --- configs/paz00_defconfig | 2 ++ include/configs/paz00.h | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/configs/paz00_defconfig b/configs/paz00_defconfig index ec8ae29ec28a..f9a994887cd8 100644 --- a/configs/paz00_defconfig +++ b/configs/paz00_defconfig @@ -55,3 +55,5 @@ CONFIG_VIDEO=y # CONFIG_VIDEO_BPP8 is not set CONFIG_VIDEO_TEGRA20=y CONFIG_CONSOLE_SCROLL_LINES=10 +CONFIG_TEGRA_NVEC=y +CONFIG_TEGRA_NVEC_KEYBOARD=y diff --git a/include/configs/paz00.h b/include/configs/paz00.h index 3a5b8ff3a739..fb5c6b51a53e 100644 --- a/include/configs/paz00.h +++ b/include/configs/paz00.h @@ -21,12 +21,9 @@ /* Environment in eMMC, at the end of 2nd "boot sector" */ -/* Keyboard support */ -#define CONFIG_TEGRA_NVEC_KEYBOARD /* NVEC support */ #define CONFIG_CMD_I2C #define CONFIG_SYS_I2C_INIT_BOARD -#define CONFIG_TEGRA_NVEC #define BOARD_EXTRA_ENV_SETTINGS \ "i2c dev 0" "\0" \ "i2c dev 1" "\0" \