diff --git a/arch/arm/dts/tegra114.dtsi b/arch/arm/dts/tegra114.dtsi index 8932ea3afd5f44bc6a728b257a2dee04167d34ce..68ee7f316563b18c2213ac2b7b6cd04f5f4ccdfd 100644 --- a/arch/arm/dts/tegra114.dtsi +++ b/arch/arm/dts/tegra114.dtsi @@ -312,7 +312,7 @@ }; pwm: pwm@7000a000 { - compatible = "nvidia,tegra114-pwm", "nvidia,tegra20-pwm"; + compatible = "nvidia,tegra114-pwm"; reg = <0x7000a000 0x100>; #pwm-cells = <2>; clocks = <&tegra_car TEGRA114_CLK_PWM>; diff --git a/arch/arm/dts/tegra124.dtsi b/arch/arm/dts/tegra124.dtsi index f473ba28e4a645e3b588436ad9bc2b8c8b479b37..ffec9cae09d01081b7d01bdf24830a7c3ec43a0c 100644 --- a/arch/arm/dts/tegra124.dtsi +++ b/arch/arm/dts/tegra124.dtsi @@ -377,7 +377,7 @@ }; pwm: pwm@7000a000 { - compatible = "nvidia,tegra124-pwm", "nvidia,tegra20-pwm"; + compatible = "nvidia,tegra124-pwm", "nvidia,tegra114-pwm"; reg = <0x7000a000 0x100>; #pwm-cells = <2>; clocks = <&tegra_car TEGRA124_CLK_PWM>; diff --git a/arch/arm/include/asm/arch-tegra/clock.h b/arch/arm/include/asm/arch-tegra/clock.h index 1dd5d0742c495d591d4a4a1425e3347275025dcd..61ef81e7fe43b43283872ca3a74db7ff21377134 100644 --- a/arch/arm/include/asm/arch-tegra/clock.h +++ b/arch/arm/include/asm/arch-tegra/clock.h @@ -270,6 +270,19 @@ void clock_ll_start_uart(enum periph_id periph_id); */ int clock_decode_periph_id(struct udevice *dev); +/** + * Get periph clock id and its parent from device tree. + * + * This works by looking up the peripheral's 'clocks' node and reading out + * the second and fourth cells, which are the peripheral and PLL clock numbers. + * + * @param dev udevice associated with FDT node + * @param clk_id pointer to int array of 2 values + * first is periph clock, second is + * its PLL parent according to FDT. + */ +int clock_decode_pair(struct udevice *dev, int *clk_id); + /** * Checks if the oscillator bypass is enabled (XOBP bit) * @@ -354,6 +367,14 @@ int get_periph_clock_source(enum periph_id periph_id, */ enum periph_id clk_id_to_periph_id(int clk_id); +/* + * Convert a device tree clock ID to our PLL ID. + * + * @param clk_id Clock ID according to tegra device tree binding + * Return: clock ID, or CLOCK_ID_NONE if the clock ID is invalid + */ +enum clock_id clk_id_to_pll_id(int clk_id); + /** * Set the output frequency you want for each PLL clock. * PLL output frequencies are programmed by setting their N, M and P values. 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 0000000000000000000000000000000000000000..7646163b97b24b292a9b5e2de437be05ed0432de --- /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 <www.nvidia.com> + */ + +#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 int 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 int 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 int 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 int length, u8 *key); + +#endif /* #ifndef _CRYPTO_H_ */ diff --git a/arch/arm/include/asm/arch-tegra/sys_proto.h b/arch/arm/include/asm/arch-tegra/sys_proto.h index c3a2673e6c3c04efe184e865626975d21eb74bcb..566666a9a052bd45a2ae965c63eec393129046d7 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/include/asm/arch-tegra/tegra_i2c.h b/arch/arm/include/asm/arch-tegra/tegra_i2c.h index c49f43251dc884db904a8a599eab18410262c150..afec6bbdda339174d7e69d9df3069a31447f4ad5 100644 --- a/arch/arm/include/asm/arch-tegra/tegra_i2c.h +++ b/arch/arm/include/asm/arch-tegra/tegra_i2c.h @@ -8,6 +8,7 @@ #ifndef _TEGRA_I2C_H_ #define _TEGRA_I2C_H_ +#include <asm/io.h> #include <asm/types.h> struct udevice; @@ -154,4 +155,20 @@ struct i2c_ctlr { */ int tegra_i2c_get_dvc_bus(struct udevice **busp); +/* Pre-dm section used for initial setup of PMIC */ +#define I2C_SEND_2_BYTES 0x0A02 + +static inline void tegra_i2c_ll_write(uint addr, uint data) +{ + struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE; + + writel(addr, ®->cmd_addr0); + writel(0x2, ®->cnfg); + + writel(data, ®->cmd_data1); + writel(I2C_SEND_2_BYTES, ®->cnfg); +} + +void pmic_enable_cpu_vdd(void); + #endif /* _TEGRA_I2C_H_ */ diff --git a/arch/arm/include/asm/arch-tegra30/clock-tables.h b/arch/arm/include/asm/arch-tegra30/clock-tables.h index 8588009c61ded71829bad5cfeff452086786b04a..6c899ff64c8c8b1f477951e5a5a75b5564286939 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/Kconfig b/arch/arm/mach-tegra/Kconfig index 4fc79ebadbfa796b21c58a04fb4fbdb6fed627fa..464bd0798f62e0c1662c7a58a1b26d3dfd2e2534 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 @@ -224,4 +229,13 @@ config CMD_ENTERRCM for mechanical button actuators, or hooking up relays/... to the button. +config CMD_EBTUPDATE + bool "Enable 'ebtupdate' command" + depends on TEGRA20 || TEGRA30 + select TEGRA_CRYPTO + help + Updating u-boot from within u-boot in rather complex or even + impossible on production devices. To make it easier procedure of + re-cryption was created. If your device was re-crypted choose Y. + endif diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 7165d70a60da926be271ac2df8ec564f319c77f4..9147050b323340e3446fb25490676a177c12e5fe 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/board2.c b/arch/arm/mach-tegra/board2.c index c7a45f4ff82afa896501c2203be489fca32fdd75..0df18360ca63c29fa8ae2c51f1fcc61e87594ca9 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; } diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c index 11bffc170168c499b889355cd453b9e852737d04..966009f3752c22c4c2a09afb06a14b774bb03005 100644 --- a/arch/arm/mach-tegra/clock.c +++ b/arch/arm/mach-tegra/clock.c @@ -678,6 +678,29 @@ int clock_decode_periph_id(struct udevice *dev) assert(clock_periph_id_isvalid(id)); return id; } + +/* + * Get periph clock id and its parent from device tree. + * + * @param dev udevice associated with FDT node + * @param clk_id pointer to u32 array of 2 values + * first is periph clock, second is + * its PLL parent according to FDT. + */ +int clock_decode_pair(struct udevice *dev, int *clk_id) +{ + u32 cell[4]; + int err; + + err = dev_read_u32_array(dev, "clocks", cell, ARRAY_SIZE(cell)); + if (err) + return -EINVAL; + + clk_id[0] = clk_id_to_periph_id(cell[1]); + clk_id[1] = clk_id_to_pll_id(cell[3]); + + return 0; +} #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ int clock_verify(void) diff --git a/arch/arm/mach-tegra/cpu.h b/arch/arm/mach-tegra/cpu.h index d541825441a3caab39ae2592e6f7b5aef75cc89c..006aae3d07052cc8a646652e850487c434ea826b 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/tegra20/crypto.c b/arch/arm/mach-tegra/crypto.c similarity index 68% rename from arch/arm/mach-tegra/tegra20/crypto.c rename to arch/arm/mach-tegra/crypto.c index 1efaa5c3ecd7a644b674aed37fc0b4b52c24e1b7..893da35e0b9dfcdc5cba70a7e0f5f37ec0f2b87a 100644 --- a/arch/arm/mach-tegra/tegra20/crypto.c +++ b/arch/arm/mach-tegra/crypto.c @@ -7,7 +7,7 @@ #include <common.h> #include <log.h> #include <linux/errno.h> -#include "crypto.h" +#include <asm/arch-tegra/crypto.h> #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 */ }; /** @@ -54,7 +55,7 @@ static void sign_object(u8 *key, u8 *key_schedule, u8 *src, u8 *dst, u8 left[AES128_KEY_LENGTH]; u8 k1[AES128_KEY_LENGTH]; u8 *cbc_chain_data; - unsigned i; + unsigned int i; cbc_chain_data = zero_key; /* Convenient array of 0's for IV */ @@ -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, - u32 length, u8 *sig_dst) +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("%s: length = %d\n", __func__, 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("%s: begin decryption\n", __func__); + aes_cbc_decrypt_blocks(AES128_KEY_LENGTH, key_schedule, iv, src, + src, num_aes_blocks); + debug("%s: end decryption\n", __func__); + } + if (oper & SECURITY_ENCRYPT) { /* Perform this in place, resulting in src being encrypted. */ - debug("encrypt_and_sign: begin encryption\n"); + debug("%s: begin encryption\n", __func__); aes_cbc_encrypt_blocks(AES128_KEY_LENGTH, key_schedule, iv, src, src, num_aes_blocks); - debug("encrypt_and_sign: end encryption\n"); + debug("%s: end encryption\n", __func__); } if (oper & SECURITY_SIGN) { /* encrypt the data, overwriting the result in signature. */ - debug("encrypt_and_sign: begin signing\n"); + debug("%s: begin signing\n", __func__); sign_object(key, key_schedule, src, sig_dst, num_aes_blocks); - debug("encrypt_and_sign: end signing\n"); + debug("%s: end signing\n", __func__); } return 0; } -int sign_data_block(u8 *source, unsigned length, u8 *signature) +/** + * Tegra crypto group + */ +int sign_data_block(u8 *source, unsigned int length, u8 *signature) +{ + return tegra_crypto_core(zero_key, SECURITY_SIGN, source, + length, signature); +} + +int sign_enc_data_block(u8 *source, unsigned int length, u8 *signature, u8 *key) +{ + return tegra_crypto_core(key, SECURITY_SIGN, source, + length, signature); +} + +int encrypt_data_block(u8 *source, unsigned int length, u8 *key) +{ + return tegra_crypto_core(key, SECURITY_ENCRYPT, source, + length, NULL); +} + +int decrypt_data_block(u8 *source, unsigned int length, u8 *key) { - return encrypt_and_sign(zero_key, SECURITY_SIGN, source, - length, signature); + return tegra_crypto_core(key, SECURITY_DECRYPT, source, + length, NULL); } diff --git a/arch/arm/mach-tegra/tegra114/clock.c b/arch/arm/mach-tegra/tegra114/clock.c index 143f86863ff45d0a850cd06f97c4c21b15a00705..8ad71f590fa71121bed4ad686dd27bdba8520867 100644 --- a/arch/arm/mach-tegra/tegra114/clock.c +++ b/arch/arm/mach-tegra/tegra114/clock.c @@ -19,6 +19,8 @@ #include <fdtdec.h> #include <linux/delay.h> +#include <dt-bindings/clock/tegra114-car.h> + /* * Clock types that we can use as a source. The Tegra114 has muxes for the * peripheral clocks, and in most cases there are four options for the clock @@ -646,6 +648,41 @@ enum periph_id clk_id_to_periph_id(int clk_id) return clk_id; } } + +/* + * Convert a device tree clock ID to our PLL ID. + * + * @param clk_id Clock ID according to tegra114 device tree binding + * Return: clock ID, or CLOCK_ID_NONE if the clock ID is invalid + */ +enum clock_id clk_id_to_pll_id(int clk_id) +{ + switch (clk_id) { + case TEGRA114_CLK_PLL_C: + return CLOCK_ID_CGENERAL; + case TEGRA114_CLK_PLL_M: + return CLOCK_ID_MEMORY; + case TEGRA114_CLK_PLL_P: + return CLOCK_ID_PERIPH; + case TEGRA114_CLK_PLL_A: + return CLOCK_ID_AUDIO; + case TEGRA114_CLK_PLL_U: + return CLOCK_ID_USB; + case TEGRA114_CLK_PLL_D: + case TEGRA114_CLK_PLL_D_OUT0: + return CLOCK_ID_DISPLAY; + case TEGRA114_CLK_PLL_X: + return CLOCK_ID_XCPU; + case TEGRA114_CLK_PLL_E_OUT0: + return CLOCK_ID_EPCI; + case TEGRA114_CLK_CLK_32K: + return CLOCK_ID_32KHZ; + case TEGRA114_CLK_CLK_M: + return CLOCK_ID_CLK_M; + default: + return CLOCK_ID_NONE; + } +} #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ void clock_early_init(void) @@ -745,7 +782,7 @@ struct periph_clk_init periph_clk_init_table[] = { { PERIPH_ID_SDMMC2, CLOCK_ID_PERIPH }, { PERIPH_ID_SDMMC3, CLOCK_ID_PERIPH }, { PERIPH_ID_SDMMC4, CLOCK_ID_PERIPH }, - { PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ }, + { PERIPH_ID_PWM, CLOCK_ID_PERIPH }, { PERIPH_ID_I2C1, CLOCK_ID_PERIPH }, { PERIPH_ID_I2C2, CLOCK_ID_PERIPH }, { PERIPH_ID_I2C3, CLOCK_ID_PERIPH }, diff --git a/arch/arm/mach-tegra/tegra124/clock.c b/arch/arm/mach-tegra/tegra124/clock.c index da38b26c27d5776e35f89b9b16e6241ef4cc8b7a..ca9549a318688737dfc16d841037b0484832c595 100644 --- a/arch/arm/mach-tegra/tegra124/clock.c +++ b/arch/arm/mach-tegra/tegra124/clock.c @@ -19,6 +19,9 @@ #include <fdtdec.h> #include <linux/delay.h> +#include <dt-bindings/clock/tegra124-car.h> +#include <dt-bindings/clock/tegra124-car-common.h> + /* * Clock types that we can use as a source. The Tegra124 has muxes for the * peripheral clocks, and in most cases there are four options for the clock @@ -826,6 +829,41 @@ enum periph_id clk_id_to_periph_id(int clk_id) return clk_id; } } + +/* + * Convert a device tree clock ID to our PLL ID. + * + * @param clk_id Clock ID according to tegra124 device tree binding + * Return: clock ID, or CLOCK_ID_NONE if the clock ID is invalid + */ +enum clock_id clk_id_to_pll_id(int clk_id) +{ + switch (clk_id) { + case TEGRA124_CLK_PLL_C: + return CLOCK_ID_CGENERAL; + case TEGRA124_CLK_PLL_M: + return CLOCK_ID_MEMORY; + case TEGRA124_CLK_PLL_P: + return CLOCK_ID_PERIPH; + case TEGRA124_CLK_PLL_A: + return CLOCK_ID_AUDIO; + case TEGRA124_CLK_PLL_U: + return CLOCK_ID_USB; + case TEGRA124_CLK_PLL_D: + case TEGRA124_CLK_PLL_D_OUT0: + return CLOCK_ID_DISPLAY; + case TEGRA124_CLK_PLL_X: + return CLOCK_ID_XCPU; + case TEGRA124_CLK_PLL_E: + return CLOCK_ID_EPCI; + case TEGRA124_CLK_CLK_32K: + return CLOCK_ID_32KHZ; + case TEGRA124_CLK_CLK_M: + return CLOCK_ID_CLK_M; + default: + return CLOCK_ID_NONE; + } +} #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ void clock_early_init(void) @@ -1170,7 +1208,7 @@ struct periph_clk_init periph_clk_init_table[] = { { PERIPH_ID_SDMMC2, CLOCK_ID_PERIPH }, { PERIPH_ID_SDMMC3, CLOCK_ID_PERIPH }, { PERIPH_ID_SDMMC4, CLOCK_ID_PERIPH }, - { PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ }, + { PERIPH_ID_PWM, CLOCK_ID_PERIPH }, { PERIPH_ID_I2C1, CLOCK_ID_PERIPH }, { PERIPH_ID_I2C2, CLOCK_ID_PERIPH }, { PERIPH_ID_I2C3, CLOCK_ID_PERIPH }, diff --git a/arch/arm/mach-tegra/tegra124/cpu.c b/arch/arm/mach-tegra/tegra124/cpu.c index d5f2683b266cb202667ea7e969822e5d3f4ff0cf..b1bfe8fb5e139937f5ed9347a20de53d15302700 100644 --- a/arch/arm/mach-tegra/tegra124/cpu.c +++ b/arch/arm/mach-tegra/tegra124/cpu.c @@ -14,10 +14,14 @@ #include <asm/arch/tegra.h> #include <asm/arch-tegra/clk_rst.h> #include <asm/arch-tegra/pmc.h> +#include <asm/arch-tegra/tegra_i2c.h> #include <asm/arch-tegra/ap.h> #include <linux/delay.h> #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/tegra20/Kconfig b/arch/arm/mach-tegra/tegra20/Kconfig index 955786c0c4841a4e1ea5c6a32c714bd0ecbd083f..57d11024bfc23e3d2369e67ed9072c0115d31e57 100644 --- a/arch/arm/mach-tegra/tegra20/Kconfig +++ b/arch/arm/mach-tegra/tegra20/Kconfig @@ -3,6 +3,7 @@ if TEGRA20 config TEGRA_LP0 bool select TEGRA_CLOCK_SCALING + select TEGRA_CRYPTO config TEGRA_PMU bool diff --git a/arch/arm/mach-tegra/tegra20/Makefile b/arch/arm/mach-tegra/tegra20/Makefile index bb17c90cca29539bf7bf7230bf5a76e1452d4f9e..991cabeec56a62f2b677c5f9308fd06a97ca0167 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_)CMD_EBTUPDATE) += bct.o # The AVP is ARMv4T architecture so we must use special compiler # flags for any startup files it might use. @@ -13,6 +12,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 diff --git a/arch/arm/mach-tegra/tegra20/bct.c b/arch/arm/mach-tegra/tegra20/bct.c new file mode 100644 index 0000000000000000000000000000000000000000..5eb48990b6c3eb708686d6ba4b54fe682fa5b8f3 --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/bct.c @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022, Ramin <raminterex@yahoo.com> + * Copyright (c) 2022, Svyatoslav Ryhel <clamor95@gmail.com> + */ + +#include <common.h> +#include <command.h> +#include <log.h> +#include <asm/arch-tegra/crypto.h> +#include "bct.h" +#include "uboot_aes.h" + +/* + * @param bct boot config table start in RAM + * @param ect bootloader start in RAM + * @param ebt_size bootloader file size in bytes + * Return: 0, or 1 if failed + */ +static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size) +{ + struct nvboot_config_table *bct_tbl = NULL; + u8 ebt_hash[AES128_KEY_LENGTH] = { 0 }; + u8 sbk[AES128_KEY_LENGTH] = { 0 }; + u8 *bct_hash = bct; + int ret; + + bct += BCT_HASH; + + memcpy(sbk, (u8 *)(bct + BCT_LENGTH), + NVBOOT_CMAC_AES_HASH_LENGTH * 4); + + 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 = (struct 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 re-crypted 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 0000000000000000000000000000000000000000..4b78aef7cfd20fb2693c1d087bfa6a073468c02d --- /dev/null +++ b/arch/arm/mach-tegra/tegra20/bct.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _BCT_H_ +#define _BCT_H_ + +/* + * Defines the BCT parametres for T20 + */ +#define BCT_LENGTH 0xFE0 +#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 + +struct nv_bootloader_info { + 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]; +}; + +struct nvboot_config_table { + u32 unused0[4]; + u32 boot_data_version; + u32 unused1[668]; + struct nv_bootloader_info bootloader[NVBOOT_MAX_BOOTLOADERS]; + u32 unused2[508]; +}; + +#endif /* _BCT_H_ */ diff --git a/arch/arm/mach-tegra/tegra20/clock.c b/arch/arm/mach-tegra/tegra20/clock.c index 8c127430aada7bbedd290c17de7b7048d8bf6395..067a9f1a2f1201fb8931c08f024a0361b1d3050a 100644 --- a/arch/arm/mach-tegra/tegra20/clock.c +++ b/arch/arm/mach-tegra/tegra20/clock.c @@ -20,6 +20,8 @@ #include <fdtdec.h> #include <linux/delay.h> +#include <dt-bindings/clock/tegra20-car.h> + /* * Clock types that we can use as a source. The Tegra20 has muxes for the * peripheral clocks, and in most cases there are four options for the clock @@ -578,6 +580,41 @@ enum periph_id clk_id_to_periph_id(int clk_id) return clk_id; } } + +/* + * Convert a device tree clock ID to our PLL ID. + * + * @param clk_id Clock ID according to tegra20 device tree binding + * Return: clock ID, or CLOCK_ID_NONE if the clock ID is invalid + */ +enum clock_id clk_id_to_pll_id(int clk_id) +{ + switch (clk_id) { + case TEGRA20_CLK_PLL_C: + return CLOCK_ID_CGENERAL; + case TEGRA20_CLK_PLL_M: + return CLOCK_ID_MEMORY; + case TEGRA20_CLK_PLL_P: + return CLOCK_ID_PERIPH; + case TEGRA20_CLK_PLL_A: + return CLOCK_ID_AUDIO; + case TEGRA20_CLK_PLL_U: + return CLOCK_ID_USB; + case TEGRA20_CLK_PLL_D: + case TEGRA20_CLK_PLL_D_OUT0: + return CLOCK_ID_DISPLAY; + case TEGRA20_CLK_PLL_X: + return CLOCK_ID_XCPU; + case TEGRA20_CLK_PLL_E: + return CLOCK_ID_EPCI; + case TEGRA20_CLK_CLK_32K: + return CLOCK_ID_32KHZ; + case TEGRA20_CLK_CLK_M: + return CLOCK_ID_CLK_M; + default: + return CLOCK_ID_NONE; + } +} #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ void clock_early_init(void) @@ -760,14 +797,14 @@ struct periph_clk_init periph_clk_init_table[] = { { PERIPH_ID_SBC2, CLOCK_ID_PERIPH }, { PERIPH_ID_SBC3, CLOCK_ID_PERIPH }, { PERIPH_ID_SBC4, CLOCK_ID_PERIPH }, - { PERIPH_ID_HOST1X, CLOCK_ID_PERIPH }, - { PERIPH_ID_DISP1, CLOCK_ID_CGENERAL }, + { PERIPH_ID_HOST1X, CLOCK_ID_CGENERAL }, + { PERIPH_ID_DISP1, CLOCK_ID_PERIPH }, { PERIPH_ID_NDFLASH, CLOCK_ID_PERIPH }, { PERIPH_ID_SDMMC1, CLOCK_ID_PERIPH }, { PERIPH_ID_SDMMC2, CLOCK_ID_PERIPH }, { PERIPH_ID_SDMMC3, CLOCK_ID_PERIPH }, { PERIPH_ID_SDMMC4, CLOCK_ID_PERIPH }, - { PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ }, + { PERIPH_ID_PWM, CLOCK_ID_PERIPH }, { PERIPH_ID_DVC_I2C, CLOCK_ID_PERIPH }, { PERIPH_ID_I2C1, CLOCK_ID_PERIPH }, { PERIPH_ID_I2C2, CLOCK_ID_PERIPH }, diff --git a/arch/arm/mach-tegra/tegra20/crypto.h b/arch/arm/mach-tegra/tegra20/crypto.h deleted file mode 100644 index a773d03fc742dd44add11a50dfa977934819af10..0000000000000000000000000000000000000000 --- a/arch/arm/mach-tegra/tegra20/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 <www.nvidia.com> - */ - -#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_ */ diff --git a/arch/arm/mach-tegra/tegra210/clock.c b/arch/arm/mach-tegra/tegra210/clock.c index 330753f2ad1a30b70f177adb5ad97ef50241738d..900537afbe50831c3f6abd6c65c68495cd265fae 100644 --- a/arch/arm/mach-tegra/tegra210/clock.c +++ b/arch/arm/mach-tegra/tegra210/clock.c @@ -22,6 +22,8 @@ #include <linux/bitops.h> #include <linux/delay.h> +#include <dt-bindings/clock/tegra210-car.h> + /* * Clock types that we can use as a source. The Tegra210 has muxes for the * peripheral clocks, and in most cases there are four options for the clock @@ -914,6 +916,41 @@ enum periph_id clk_id_to_periph_id(int clk_id) return clk_id; } } + +/* + * Convert a device tree clock ID to our PLL ID. + * + * @param clk_id Clock ID according to tegra210 device tree binding + * Return: clock ID, or CLOCK_ID_NONE if the clock ID is invalid + */ +enum clock_id clk_id_to_pll_id(int clk_id) +{ + switch (clk_id) { + case TEGRA210_CLK_PLL_C: + return CLOCK_ID_CGENERAL; + case TEGRA210_CLK_PLL_M: + return CLOCK_ID_MEMORY; + case TEGRA210_CLK_PLL_P: + return CLOCK_ID_PERIPH; + case TEGRA210_CLK_PLL_A: + return CLOCK_ID_AUDIO; + case TEGRA210_CLK_PLL_U: + return CLOCK_ID_USB; + case TEGRA210_CLK_PLL_D: + case TEGRA210_CLK_PLL_D_OUT0: + return CLOCK_ID_DISPLAY; + case TEGRA210_CLK_PLL_X: + return CLOCK_ID_XCPU; + case TEGRA210_CLK_PLL_E: + return CLOCK_ID_EPCI; + case TEGRA210_CLK_CLK_32K: + return CLOCK_ID_32KHZ; + case TEGRA210_CLK_CLK_M: + return CLOCK_ID_CLK_M; + default: + return CLOCK_ID_NONE; + } +} #endif /* CONFIG_OF_CONTROL */ /* @@ -1241,7 +1278,7 @@ struct periph_clk_init periph_clk_init_table[] = { { PERIPH_ID_SDMMC2, CLOCK_ID_PERIPH }, { PERIPH_ID_SDMMC3, CLOCK_ID_PERIPH }, { PERIPH_ID_SDMMC4, CLOCK_ID_PERIPH }, - { PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ }, + { PERIPH_ID_PWM, CLOCK_ID_PERIPH }, { PERIPH_ID_I2C1, CLOCK_ID_PERIPH }, { PERIPH_ID_I2C2, CLOCK_ID_PERIPH }, { PERIPH_ID_I2C3, CLOCK_ID_PERIPH }, diff --git a/arch/arm/mach-tegra/tegra30/Kconfig b/arch/arm/mach-tegra/tegra30/Kconfig index 5619d1cd42f73fe2e78bcaefac362b88e147abcd..85b8ce294f275ef83b3254398200204fa2e17b47 100644 --- a/arch/arm/mach-tegra/tegra30/Kconfig +++ b/arch/arm/mach-tegra/tegra30/Kconfig @@ -1,11 +1,5 @@ if TEGRA30 -config TEGRA_VDD_CORE_TPS62361B_SET3 - bool - -config TEGRA_VDD_CORE_TPS62366A_SET1 - bool - choice prompt "Tegra30 board select" optional @@ -17,12 +11,10 @@ config TARGET_APALIS_T30 config TARGET_BEAVER bool "NVIDIA Tegra30 Beaver evaluation board" select BOARD_LATE_INIT - select TEGRA_VDD_CORE_TPS62366A_SET1 config TARGET_CARDHU bool "NVIDIA Tegra30 Cardhu evaluation board" select BOARD_LATE_INIT - select TEGRA_VDD_CORE_TPS62361B_SET3 config TARGET_COLIBRI_T30 bool "Toradex Colibri T30 board" diff --git a/arch/arm/mach-tegra/tegra30/Makefile b/arch/arm/mach-tegra/tegra30/Makefile index 9f170576e7c49faf7f9c281fa8602adae9fcdcbb..28dd486d8ddc8b57800ed131ff1b23f44f65b800 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_)CMD_EBTUPDATE) += 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 0000000000000000000000000000000000000000..c56958da6919585cad5700084e6bb2097b4f6179 --- /dev/null +++ b/arch/arm/mach-tegra/tegra30/bct.c @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022, Ramin <raminterex@yahoo.com> + * Copyright (c) 2022, Svyatoslav Ryhel <clamor95@gmail.com> + */ + +#include <common.h> +#include <command.h> +#include <log.h> +#include <asm/arch-tegra/crypto.h> +#include "bct.h" +#include "uboot_aes.h" + +/* + * @param bct boot config table start in RAM + * @param ect bootloader start in RAM + * @param ebt_size bootloader file size in bytes + * Return: 0, or 1 if failed + */ +static int bct_patch(u8 *bct, u8 *ebt, u32 ebt_size) +{ + struct nvboot_config_table *bct_tbl = NULL; + u8 ebt_hash[AES128_KEY_LENGTH] = { 0 }; + u8 sbk[AES128_KEY_LENGTH] = { 0 }; + u8 *bct_hash = bct; + int ret; + + bct += BCT_HASH; + + memcpy(sbk, (u8 *)(bct + BCT_LENGTH), + NVBOOT_CMAC_AES_HASH_LENGTH * 4); + + 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 = (struct 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 re-crypted 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 0000000000000000000000000000000000000000..9797384da32cd62fb7b4b33a8bbcefaa2cf02ad8 --- /dev/null +++ b/arch/arm/mach-tegra/tegra30/bct.h @@ -0,0 +1,42 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#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 + +struct nv_bootloader_info { + 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]; +}; + +struct nvboot_config_table { + u32 unused0[4]; + u32 boot_data_version; + u32 unused1[972]; + struct nv_bootloader_info bootloader[NVBOOT_MAX_BOOTLOADERS]; + u32 unused2[508]; +}; + +#endif /* _BCT_H_ */ diff --git a/arch/arm/mach-tegra/tegra30/clock.c b/arch/arm/mach-tegra/tegra30/clock.c index 449b66e3b2c96db9b60c642d16d4cae367e0fc47..1dc9d09dba86749560bd7a9ef17798a5b9ec766d 100644 --- a/arch/arm/mach-tegra/tegra30/clock.c +++ b/arch/arm/mach-tegra/tegra30/clock.c @@ -19,6 +19,8 @@ #include <fdtdec.h> #include <linux/delay.h> +#include <dt-bindings/clock/tegra30-car.h> + /* * Clock types that we can use as a source. The Tegra30 has muxes for the * peripheral clocks, and in most cases there are four options for the clock @@ -377,9 +379,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, @@ -628,11 +630,87 @@ enum periph_id clk_id_to_periph_id(int clk_id) return clk_id; } } + +/* + * Convert a device tree clock ID to our PLL ID. + * + * @param clk_id Clock ID according to tegra30 device tree binding + * Return: clock ID, or CLOCK_ID_NONE if the clock ID is invalid + */ +enum clock_id clk_id_to_pll_id(int clk_id) +{ + switch (clk_id) { + case TEGRA30_CLK_PLL_C: + return CLOCK_ID_CGENERAL; + case TEGRA30_CLK_PLL_M: + return CLOCK_ID_MEMORY; + case TEGRA30_CLK_PLL_P: + return CLOCK_ID_PERIPH; + case TEGRA30_CLK_PLL_A: + return CLOCK_ID_AUDIO; + case TEGRA30_CLK_PLL_U: + return CLOCK_ID_USB; + case TEGRA30_CLK_PLL_D: + case TEGRA30_CLK_PLL_D_OUT0: + return CLOCK_ID_DISPLAY; + case TEGRA30_CLK_PLL_X: + return CLOCK_ID_XCPU; + case TEGRA30_CLK_PLL_E: + return CLOCK_ID_EPCI; + case TEGRA30_CLK_CLK_32K: + return CLOCK_ID_32KHZ; + case TEGRA30_CLK_CLK_M: + return CLOCK_ID_CLK_M; + default: + return CLOCK_ID_NONE; + } +} #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ void clock_early_init(void) { + struct clk_rst_ctlr *clkrst = + (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; + struct clk_pll_info *pllinfo; + u32 data; + tegra30_set_up_pllp(); + + /* + * PLLD output frequency set to 925Mhz + */ + 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_DISPLAY, 925, 12, 0, 12); + break; + + case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ + clock_set_rate(CLOCK_ID_DISPLAY, 925, 26, 0, 12); + 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_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 + * message and the UART likely won't work anyway due to the + * oscillator being wrong. + */ + break; + } + + /* PLLD_MISC: Set CLKENABLE, CPCON 12, LFCON 1, and enable lock */ + pllinfo = &tegra_pll_info_table[CLOCK_ID_DISPLAY]; + data = (12 << pllinfo->kcp_shift) | (1 << pllinfo->kvco_shift); + data |= (1 << PLLD_CLKENABLE) | (1 << pllinfo->lock_ena); + writel(data, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc); + udelay(2); } void arch_timer_init(void) @@ -799,14 +877,14 @@ struct periph_clk_init periph_clk_init_table[] = { { PERIPH_ID_SBC4, CLOCK_ID_PERIPH }, { PERIPH_ID_SBC5, CLOCK_ID_PERIPH }, { PERIPH_ID_SBC6, CLOCK_ID_PERIPH }, - { PERIPH_ID_HOST1X, CLOCK_ID_PERIPH }, - { PERIPH_ID_DISP1, CLOCK_ID_CGENERAL }, + { PERIPH_ID_HOST1X, CLOCK_ID_CGENERAL }, + { PERIPH_ID_DISP1, CLOCK_ID_PERIPH }, { PERIPH_ID_NDFLASH, CLOCK_ID_PERIPH }, { PERIPH_ID_SDMMC1, CLOCK_ID_PERIPH }, { PERIPH_ID_SDMMC2, CLOCK_ID_PERIPH }, { PERIPH_ID_SDMMC3, CLOCK_ID_PERIPH }, { PERIPH_ID_SDMMC4, CLOCK_ID_PERIPH }, - { PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ }, + { PERIPH_ID_PWM, CLOCK_ID_PERIPH }, { PERIPH_ID_DVC_I2C, CLOCK_ID_PERIPH }, { PERIPH_ID_I2C1, CLOCK_ID_PERIPH }, { PERIPH_ID_I2C2, CLOCK_ID_PERIPH }, diff --git a/arch/arm/mach-tegra/tegra30/cpu.c b/arch/arm/mach-tegra/tegra30/cpu.c index 651edd27ee87f9ba132eeb64b67d11a4567a974d..60bbf13ea5259837f19b13ceb6ffbf981702e93e 100644 --- a/arch/arm/mach-tegra/tegra30/cpu.c +++ b/arch/arm/mach-tegra/tegra30/cpu.c @@ -15,37 +15,8 @@ #include <linux/delay.h> #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) - -#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) -#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) { @@ -56,27 +27,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); } /** @@ -142,6 +92,7 @@ void start_cpu(u32 reset_vector) /* Enable VDD_CPU */ enable_cpu_power_rail(); + pmic_enable_cpu_vdd(); set_cpu_running(0); diff --git a/board/avionic-design/tec-ng/Makefile b/board/avionic-design/tec-ng/Makefile index 46df14d991c56e042cc036775db14fecd9df96d2..d6890e5797fdbae35d6dc0ee58f95e9ddc42fe4d 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 <www.avionic-design.de> -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 0000000000000000000000000000000000000000..6e544641833e7184f980492ac0df97f87f5be862 --- /dev/null +++ b/board/avionic-design/tec-ng/tec-ng-spl.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2010-2013 + * NVIDIA Corporation <www.nvidia.com> + * + * (C) Copyright 2021 + * Svyatoslav Ryhel <clamor95@gmail.com> + */ + +#include <common.h> +#include <asm/arch-tegra/tegra_i2c.h> +#include <linux/delay.h> + +/* 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(TPS65911_I2C_ADDR, + TPS65911_VDDCTRL_OP_DATA); + udelay(1000); + tegra_i2c_ll_write(TPS65911_I2C_ADDR, + TPS65911_VDDCTRL_SR_DATA); + udelay(10 * 1000); +} diff --git a/board/nvidia/beaver/Makefile b/board/nvidia/beaver/Makefile index 80cff3eb9ccb6efd5bcdd940237fcb357ec3f4ae..5e9e70825c76ac1c3e542ebd101e2499d9cbd783 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 0000000000000000000000000000000000000000..b5d0c14854dd46020545c54854eae89cd9d85eff --- /dev/null +++ b/board/nvidia/beaver/beaver-spl.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2010-2013 + * NVIDIA Corporation <www.nvidia.com> + * + * (C) Copyright 2021 + * Svyatoslav Ryhel <clamor95@gmail.com> + */ + +#include <common.h> +#include <asm/arch-tegra/tegra_i2c.h> +#include <linux/delay.h> + +/* 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(TPS62366A_I2C_ADDR, + TPS62366A_SET1_DATA); + + udelay(1000); + + /* + * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus. + * First set VDD to 1.0125V, then enable the VDD regulator. + */ + tegra_i2c_ll_write(TPS65911_I2C_ADDR, + TPS65911_VDDCTRL_OP_DATA); + udelay(1000); + tegra_i2c_ll_write(TPS65911_I2C_ADDR, + TPS65911_VDDCTRL_SR_DATA); + udelay(10 * 1000); +} diff --git a/board/nvidia/cardhu/Makefile b/board/nvidia/cardhu/Makefile index 95971053d9b46cbfe0e36e41b64c6efd8f63ee6c..6f480cdfd3befbb960ec1d84959f2c4e5f0b7543 100644 --- a/board/nvidia/cardhu/Makefile +++ b/board/nvidia/cardhu/Makefile @@ -3,4 +3,6 @@ # (C) Copyright 2010-2012 # NVIDIA Corporation <www.nvidia.com> -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 0000000000000000000000000000000000000000..de2fa300f1c89b99fff230ff49928a6d8ccdd722 --- /dev/null +++ b/board/nvidia/cardhu/cardhu-spl.c @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2010-2013 + * NVIDIA Corporation <www.nvidia.com> + * + * (C) Copyright 2021 + * Svyatoslav Ryhel <clamor95@gmail.com> + */ + +#include <common.h> +#include <asm/arch-tegra/tegra_i2c.h> +#include <linux/delay.h> + +/* 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(TPS62361B_I2C_ADDR, + TPS62361B_SET3_DATA); + + udelay(1000); + + /* + * Bring up CPU VDD via the TPS65911x PMIC on the DVC I2C bus. + * First set VDD to 1.0125V, then enable the VDD regulator. + */ + tegra_i2c_ll_write(TPS65911_I2C_ADDR, + TPS65911_VDDCTRL_OP_DATA); + udelay(1000); + tegra_i2c_ll_write(TPS65911_I2C_ADDR, + TPS65911_VDDCTRL_SR_DATA); + udelay(10 * 1000); +} diff --git a/board/nvidia/venice2/as3722_init.c b/board/nvidia/venice2/as3722_init.c index ba676547d3ecee6dcaa78c856869aad7ba9e720f..395bdd99c78915411aa07feb6701cb8a145168c4 100644 --- a/board/nvidia/venice2/as3722_init.c +++ b/board/nvidia/venice2/as3722_init.c @@ -9,25 +9,42 @@ #include <asm/io.h> #include <asm/arch-tegra/tegra_i2c.h> #include <linux/delay.h> -#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) { @@ -37,8 +54,8 @@ void pmic_enable_cpu_vdd(void) /* Set up VDD_CORE, for boards where OTP is incorrect*/ debug("%s: Setting VDD_CORE via AS3722 reg 1\n", __func__); /* Configure VDD_CORE via the AS3722 PMIC on the PWR I2C bus */ - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(AS3722_SD1VOLTAGE_DATA, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, + AS3722_SD1VOLTAGE_DATA); /* * Don't write SDCONTROL - it's already 0x7F, i.e. all SDs enabled. * tegra_i2c_ll_write_data(AS3722_SD1CONTROL_DATA, I2C_SEND_2_BYTES); @@ -51,8 +68,8 @@ void pmic_enable_cpu_vdd(void) * Bring up VDD_CPU via the AS3722 PMIC on the PWR I2C bus. * First set VDD to 1.0V, then enable the VDD regulator. */ - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(AS3722_SD0VOLTAGE_DATA, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, + AS3722_SD0VOLTAGE_DATA); /* * Don't write SDCONTROL - it's already 0x7F, i.e. all SDs enabled. * tegra_i2c_ll_write_data(AS3722_SD0CONTROL_DATA, I2C_SEND_2_BYTES); @@ -64,8 +81,8 @@ void pmic_enable_cpu_vdd(void) * Bring up VDD_GPU via the AS3722 PMIC on the PWR I2C bus. * First set VDD to 1.0V, then enable the VDD regulator. */ - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(AS3722_SD6VOLTAGE_DATA, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, + AS3722_SD6VOLTAGE_DATA); /* * Don't write SDCONTROL - it's already 0x7F, i.e. all SDs enabled. * tegra_i2c_ll_write_data(AS3722_SD6CONTROL_DATA, I2C_SEND_2_BYTES); @@ -77,8 +94,8 @@ void pmic_enable_cpu_vdd(void) * Bring up VPP_FUSE via the AS3722 PMIC on the PWR I2C bus. * First set VDD to 1.2V, then enable the VDD regulator. */ - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(AS3722_LDO2VOLTAGE_DATA, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, + AS3722_LDO2VOLTAGE_DATA); /* * Don't write LDCONTROL - it's already 0xFF, i.e. all LDOs enabled. * tegra_i2c_ll_write_data(AS3722_LDO2CONTROL_DATA, I2C_SEND_2_BYTES); @@ -93,8 +110,8 @@ void pmic_enable_cpu_vdd(void) * NOTE: We do this early because doing it later seems to hose the CPU * power rail/partition startup. Need to debug. */ - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(AS3722_LDO6VOLTAGE_DATA, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, + AS3722_LDO6VOLTAGE_DATA); /* * Don't write LDCONTROL - it's already 0xFF, i.e. all LDOs enabled. * tegra_i2c_ll_write_data(AS3722_LDO6CONTROL_DATA, I2C_SEND_2_BYTES); diff --git a/board/nvidia/venice2/as3722_init.h b/board/nvidia/venice2/as3722_init.h deleted file mode 100644 index 17e7d76ae7aa7ebe6a5355adb8ff2f3a8b6a505e..0000000000000000000000000000000000000000 --- a/board/nvidia/venice2/as3722_init.h +++ /dev/null @@ -1,43 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * (C) Copyright 2013 - * NVIDIA Corporation <www.nvidia.com> - */ - -/* 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 68169f55480860b63cd9cb943897cf8ab09c0f9a..e9bd1028bed5013658aba7a871c81bf410876770 100644 --- a/board/toradex/apalis-tk1/as3722_init.c +++ b/board/toradex/apalis-tk1/as3722_init.c @@ -8,25 +8,40 @@ #include <asm/io.h> #include <asm/arch-tegra/tegra_i2c.h> #include <linux/delay.h> -#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) { @@ -36,8 +51,8 @@ void pmic_enable_cpu_vdd(void) /* Set up VDD_CORE, for boards where OTP is incorrect*/ debug("%s: Setting VDD_CORE via AS3722 reg 1\n", __func__); /* Configure VDD_CORE via the AS3722 PMIC on the PWR I2C bus */ - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(AS3722_SD1VOLTAGE_DATA, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, + AS3722_SD1VOLTAGE_DATA); /* * Don't write SDCONTROL - it's already 0x7F, i.e. all SDs enabled. * tegra_i2c_ll_write_data(AS3722_SD1CONTROL_DATA, I2C_SEND_2_BYTES); @@ -49,23 +64,17 @@ void pmic_enable_cpu_vdd(void) * Make sure all non-fused regulators are down. * That way we're in known state after software reboot from linux */ - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(0x0003, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, 0x0003); udelay(10 * 1000); - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(0x0004, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, 0x0004); udelay(10 * 1000); - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(0x001b, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, 0x001b); udelay(10 * 1000); - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(0x0014, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, 0x0014); udelay(10 * 1000); - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(0x001a, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, 0x001a); udelay(10 * 1000); - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(0x0019, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, 0x0019); udelay(10 * 1000); debug("%s: Setting VDD_CPU to 1.0V via AS3722 reg 0/4D\n", __func__); @@ -73,8 +82,8 @@ void pmic_enable_cpu_vdd(void) * Bring up VDD_CPU via the AS3722 PMIC on the PWR I2C bus. * First set VDD to 1.0V, then enable the VDD regulator. */ - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(AS3722_SD0VOLTAGE_DATA, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, + AS3722_SD0VOLTAGE_DATA); /* * Don't write SDCONTROL - it's already 0x7F, i.e. all SDs enabled. * tegra_i2c_ll_write_data(AS3722_SD0CONTROL_DATA, I2C_SEND_2_BYTES); @@ -86,8 +95,8 @@ void pmic_enable_cpu_vdd(void) * Bring up VDD_GPU via the AS3722 PMIC on the PWR I2C bus. * First set VDD to 1.0V, then enable the VDD regulator. */ - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(AS3722_SD6VOLTAGE_DATA, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, + AS3722_SD6VOLTAGE_DATA); /* * Don't write SDCONTROL - it's already 0x7F, i.e. all SDs enabled. * tegra_i2c_ll_write_data(AS3722_SD6CONTROL_DATA, I2C_SEND_2_BYTES); @@ -99,8 +108,8 @@ void pmic_enable_cpu_vdd(void) * Bring up VPP_FUSE via the AS3722 PMIC on the PWR I2C bus. * First set VDD to 1.2V, then enable the VDD regulator. */ - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(AS3722_LDO2VOLTAGE_DATA, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, + AS3722_LDO2VOLTAGE_DATA); /* * Don't write LDCONTROL - it's already 0xFF, i.e. all LDOs enabled. * tegra_i2c_ll_write_data(AS3722_LDO2CONTROL_DATA, I2C_SEND_2_BYTES); @@ -115,8 +124,8 @@ void pmic_enable_cpu_vdd(void) * NOTE: We do this early because doing it later seems to hose the CPU * power rail/partition startup. Need to debug. */ - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(AS3722_LDO1VOLTAGE_DATA, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, + AS3722_LDO1VOLTAGE_DATA); /* * Don't write LDCONTROL - it's already 0xFF, i.e. all LDOs enabled. * tegra_i2c_ll_write_data(AS3722_LDO1CONTROL_DATA, I2C_SEND_2_BYTES); @@ -131,8 +140,8 @@ void pmic_enable_cpu_vdd(void) * NOTE: We do this early because doing it later seems to hose the CPU * power rail/partition startup. Need to debug. */ - tegra_i2c_ll_write_addr(AS3722_I2C_ADDR, 2); - tegra_i2c_ll_write_data(AS3722_LDO6VOLTAGE_DATA, I2C_SEND_2_BYTES); + tegra_i2c_ll_write(AS3722_I2C_ADDR, + AS3722_LDO6VOLTAGE_DATA); /* * Don't write LDCONTROL - it's already 0xFF, i.e. all LDOs enabled. * tegra_i2c_ll_write_data(AS3722_LDO6CONTROL_DATA, I2C_SEND_2_BYTES); diff --git a/board/toradex/apalis-tk1/as3722_init.h b/board/toradex/apalis-tk1/as3722_init.h deleted file mode 100644 index 99836de96623e9fc9c7eabcb18dc9c3b0d5d5dfb..0000000000000000000000000000000000000000 --- 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); diff --git a/board/toradex/apalis_t30/Makefile b/board/toradex/apalis_t30/Makefile index 0ea3d8f217db798bb172777e7a1d7b0343888451..eed607043fc3b21e4be4f8a576a785476d42981c 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 0000000000000000000000000000000000000000..6e544641833e7184f980492ac0df97f87f5be862 --- /dev/null +++ b/board/toradex/apalis_t30/apalis_t30-spl.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2010-2013 + * NVIDIA Corporation <www.nvidia.com> + * + * (C) Copyright 2021 + * Svyatoslav Ryhel <clamor95@gmail.com> + */ + +#include <common.h> +#include <asm/arch-tegra/tegra_i2c.h> +#include <linux/delay.h> + +/* 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(TPS65911_I2C_ADDR, + TPS65911_VDDCTRL_OP_DATA); + udelay(1000); + tegra_i2c_ll_write(TPS65911_I2C_ADDR, + TPS65911_VDDCTRL_SR_DATA); + udelay(10 * 1000); +} diff --git a/board/toradex/colibri_t30/Makefile b/board/toradex/colibri_t30/Makefile index 4242902daecee20c8246de5c32050bfc0408a88a..8f333235b1768a89fd216c7aa869284cdf8ad691 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 0000000000000000000000000000000000000000..6e544641833e7184f980492ac0df97f87f5be862 --- /dev/null +++ b/board/toradex/colibri_t30/colibri_t30-spl.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * (C) Copyright 2010-2013 + * NVIDIA Corporation <www.nvidia.com> + * + * (C) Copyright 2021 + * Svyatoslav Ryhel <clamor95@gmail.com> + */ + +#include <common.h> +#include <asm/arch-tegra/tegra_i2c.h> +#include <linux/delay.h> + +/* 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(TPS65911_I2C_ADDR, + TPS65911_VDDCTRL_OP_DATA); + udelay(1000); + tegra_i2c_ll_write(TPS65911_I2C_ADDR, + TPS65911_VDDCTRL_SR_DATA); + udelay(10 * 1000); +} diff --git a/configs/beaver_defconfig b/configs/beaver_defconfig index 94baba45c7af50634a940ef5ca495439af8332aa..0a782ad2d9939f5ad6adf5213f18b4aa69795449 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 702f6bc20c1c505ce408c72c7a6f23497c2a48af..8d9351ea9de03e4824f2cac8596bc209a557badf 100644 --- a/configs/cei-tk1-som_defconfig +++ b/configs/cei-tk1-som_defconfig @@ -70,8 +70,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 e5fd0d5f5033eb602489d36f3ebacf47651ba762..baa2632d6c7d193af0a3e2b977350d2eda9c21dc 100644 --- a/configs/dalmore_defconfig +++ b/configs/dalmore_defconfig @@ -60,8 +60,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 fc5360a50ce041fe94729d06898a510ecce2b982..fb1f3376476c150ed1028d07711cef7bf7fd46e4 100644 --- a/configs/jetson-tk1_defconfig +++ b/configs/jetson-tk1_defconfig @@ -70,8 +70,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 6d6d8903c2463f9b9ce4a74644acf0a12f651e27..2017d5c700769d57b7070a9d98e62d4842d9f64f 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 e8074914c8a069902b52d86b256c1b34e3bfb442..2962a7db75a284a677b04c5fa9ac4fd998c646f5 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 ea62e18f7384952dfc6b0740346776eeacf74379..6b44361b5b0872288abb5c0b078cfcbfe05439cc 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 bc3fb3e5ae37262da7ea07653056e5750c6777a7..00b0dc6109e68f7fd9d43d4daf6e9f8df71fba9e 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 8e16afde9135f867c92fdcd165bfba60b5d485f3..d35bea42204495ed13f900c9a01c8f56428c8cac 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 09fa53199a6fef4fd312b13500bcb38da2fe5eb9..c30bd2538c588edeba08bce9c7e8cb397e2a78ea 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/doc/usage/cmd/ebtupdate.rst b/doc/usage/cmd/ebtupdate.rst new file mode 100644 index 0000000000000000000000000000000000000000..d90474ccec3d8a4d30dfe7c97ed227f36fe417b0 --- /dev/null +++ b/doc/usage/cmd/ebtupdate.rst @@ -0,0 +1,69 @@ +.. SPDX-License-Identifier: GPL-2.0+: + +ebtupdate command +================= + +Synopsis +-------- + +:: + + ebtupdate [<bct> [<ebt>] [<size>]] + +Description +----------- + +The "ebtupdate" command is used to self-update bootloader on Tegra 2 and Tegra 3 +production devices which were processed using re-cryption. + +The "ebtupdate" performs encryption of new bootloader and decryption, patching +and re-encryption of BCT "in situ". After BCT and bootloader can be written in +their respective places. + +bct + address of BCT block pre-loaded into RAM. + +ebt + address of the bootloader pre-loaded into RAM. + +size + size of the pre-loaded bootloader. + +Example +------- + +This is the boot log of a LG Optimus Vu: + +:: + + => mmc dev 0 1 + switch to partitions #1, OK + mmc0(part 1) is current device + => mmc read $kernel_addr_r 0 $boot_block_size + MMC read: dev # 0, block # 0, count 4096 ... 4096 blocks read: OK + => load mmc 0:1 $ramdisk_addr_r $bootloader_file + 684783 bytes read in 44 ms (14.8 MiB/s) + => size mmc 0:1 $bootloader_file + => ebtupdate $kernel_addr_r $ramdisk_addr_r $filesize + => mmc dev 0 1 + switch to partitions #1, OK + mmc0(part 1) is current device + => mmc write $kernel_addr_r 0 $boot_block_size + MMC write: dev # 0, block # 0, count 4096 ... 4096 blocks written: OK + => mmc dev 0 2 + switch to partitions #2, OK + mmc0(part 2) is current device + => mmc write $ramdisk_addr_r 0 $boot_block_size + MMC write: dev # 0, block # 0, count 4096 ... 4096 blocks written: OK + +Configuration +------------- + +The ebtupdate command is only available if CONFIG_CMD_EBTUPDATE=y and +only on Tegra 2 and Tegra 3 configurations. + +Return value +------------ + +The return value $? is set to 0 (true) if everything went successfully. If an +error occurs, the return value $? is set to 1 (false). diff --git a/doc/usage/index.rst b/doc/usage/index.rst index cde7dcb14a6f197e0649fd4a66aecda1fc198080..840c20c934d1eb175baa0669a9acce0d0f4de53e 100644 --- a/doc/usage/index.rst +++ b/doc/usage/index.rst @@ -41,6 +41,7 @@ Shell commands cmd/conitrace cmd/cyclic cmd/dm + cmd/ebtupdate cmd/echo cmd/eficonfig cmd/env diff --git a/drivers/pwm/tegra_pwm.c b/drivers/pwm/tegra_pwm.c index 36c35c608b29dcbdad233ef22cca5195e29ed939..95fc26458b89d4f6e5619465de1bd2699aa5fa16 100644 --- a/drivers/pwm/tegra_pwm.c +++ b/drivers/pwm/tegra_pwm.c @@ -20,19 +20,21 @@ static int tegra_pwm_set_config(struct udevice *dev, uint channel, { struct tegra_pwm_priv *priv = dev_get_priv(dev); struct pwm_ctlr *regs = priv->regs; + const u32 pwm_max_freq = dev_get_driver_data(dev); uint pulse_width; u32 reg; if (channel >= 4) return -EINVAL; debug("%s: Configure '%s' channel %u\n", __func__, dev->name, channel); - /* We ignore the period here and just use 32KHz */ - clock_start_periph_pll(PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ, 32768); + + clock_start_periph_pll(PERIPH_ID_PWM, CLOCK_ID_PERIPH, pwm_max_freq); pulse_width = duty_ns * 255 / period_ns; reg = pulse_width << PWM_WIDTH_SHIFT; reg |= 1 << PWM_DIVIDER_SHIFT; + reg |= PWM_ENABLE_MASK; writel(reg, ®s[channel].control); debug("%s: pulse_width=%u\n", __func__, pulse_width); @@ -68,8 +70,8 @@ static const struct pwm_ops tegra_pwm_ops = { }; static const struct udevice_id tegra_pwm_ids[] = { - { .compatible = "nvidia,tegra124-pwm" }, - { .compatible = "nvidia,tegra20-pwm" }, + { .compatible = "nvidia,tegra20-pwm", .data = 48 * 1000000 }, + { .compatible = "nvidia,tegra114-pwm", .data = 408 * 1000000 }, { } }; diff --git a/drivers/spi/tegra20_slink.c b/drivers/spi/tegra20_slink.c index 209ba8b0ccf2fa5f1ee53f15a62e1b329a34544e..d0e788539e0b92f4c56099d1dac29b68284d6eef 100644 --- a/drivers/spi/tegra20_slink.c +++ b/drivers/spi/tegra20_slink.c @@ -208,16 +208,14 @@ static int tegra30_spi_xfer(struct udevice *dev, unsigned int bitlen, u32 reg, tmpdout, tmpdin = 0; const u8 *dout = data_out; u8 *din = data_in; - int num_bytes; - int ret; + int num_bytes, overflow; + 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); + overflow = bitlen % 8; reg = readl(®s->status); writel(reg, ®s->status); /* Clear all SPI events via R/W */ @@ -254,8 +252,13 @@ 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); + if (overflow && !num_bytes) + clrsetbits_le32(®s->command, SLINK_CMD_BIT_LENGTH_MASK, + (bytes - 1) * 8 + overflow - 1); + else + clrsetbits_le32(®s->command, SLINK_CMD_BIT_LENGTH_MASK, + bytes * 8 - 1); + writel(tmpdout, ®s->tx_fifo); setbits_le32(®s->command, SLINK_CMD_GO); diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index e120efeb00737274747a8c6a1f0e2b2a15052f2b..941f97c96d026dec25bd729727d3fb3148a812c0 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