This commit is contained in:
Tom Rini 2023-02-23 17:32:22 -05:00
commit 0024e7f72b
58 changed files with 1057 additions and 315 deletions

View file

@ -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>;

View file

@ -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>;

View file

@ -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.

View file

@ -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_ */

View file

@ -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

View file

@ -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, &reg->cmd_addr0);
writel(0x2, &reg->cnfg);
writel(data, &reg->cmd_data1);
writel(I2C_SEND_2_BYTES, &reg->cnfg);
}
void pmic_enable_cpu_vdd(void);
#endif /* _TEGRA_I2C_H_ */

View file

@ -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,

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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)

View file

@ -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);

View file

@ -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 encrypt_and_sign(zero_key, SECURITY_SIGN, source,
length, 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 tegra_crypto_core(key, SECURITY_DECRYPT, source,
length, NULL);
}

View file

@ -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 },

View file

@ -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 },

View file

@ -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)

View file

@ -3,6 +3,7 @@ if TEGRA20
config TEGRA_LP0
bool
select TEGRA_CLOCK_SCALING
select TEGRA_CRYPTO
config TEGRA_PMU
bool

View file

@ -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

View file

@ -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",
""
);

View file

@ -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_ */

View file

@ -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 },

View file

@ -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_ */

View file

@ -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 },

View file

@ -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"

View file

@ -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

View file

@ -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",
""
);

View file

@ -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_ */

View file

@ -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 },

View file

@ -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, &reg->cmd_addr0);
writel(config, &reg->cnfg);
}
void tegra_i2c_ll_write_data(uint data, uint config)
{
struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
writel(data, &reg->cmd_data1);
writel(config, &reg->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);

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -9,26 +9,43 @@
#include <asm/io.h>
#include <asm/arch-tegra/tegra_i2c.h>
#include <linux/delay.h>
#include "as3722_init.h"
/* 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)
/* AS3722-PMIC-specific early init code - get CPU rails up, etc */
void tegra_i2c_ll_write_addr(uint addr, uint config)
{
struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
writel(addr, &reg->cmd_addr0);
writel(config, &reg->cnfg);
}
void tegra_i2c_ll_write_data(uint data, uint config)
{
struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
writel(data, &reg->cmd_data1);
writel(config, &reg->cnfg);
}
void pmic_enable_cpu_vdd(void)
{
debug("%s entry\n", __func__);
@ -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);

View file

@ -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);

View file

@ -8,26 +8,41 @@
#include <asm/io.h>
#include <asm/arch-tegra/tegra_i2c.h>
#include <linux/delay.h>
#include "as3722_init.h"
/* 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)
/* AS3722-PMIC-specific early init code - get CPU rails up, etc */
void tegra_i2c_ll_write_addr(uint addr, uint config)
{
struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
writel(addr, &reg->cmd_addr0);
writel(config, &reg->cnfg);
}
void tegra_i2c_ll_write_data(uint data, uint config)
{
struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
writel(data, &reg->cmd_data1);
writel(config, &reg->cnfg);
}
void pmic_enable_cpu_vdd(void)
{
debug("%s entry\n", __func__);
@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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).

View file

@ -41,6 +41,7 @@ Shell commands
cmd/conitrace
cmd/cyclic
cmd/dm
cmd/ebtupdate
cmd/echo
cmd/eficonfig
cmd/env

View file

@ -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, &regs[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 },
{ }
};

View file

@ -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(&regs->status);
writel(reg, &regs->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(&regs->command, SLINK_CMD_BIT_LENGTH_MASK,
bytes * 8 - 1);
if (overflow && !num_bytes)
clrsetbits_le32(&regs->command, SLINK_CMD_BIT_LENGTH_MASK,
(bytes - 1) * 8 + overflow - 1);
else
clrsetbits_le32(&regs->command, SLINK_CMD_BIT_LENGTH_MASK,
bytes * 8 - 1);
writel(tmpdout, &regs->tx_fifo);
setbits_le32(&regs->command, SLINK_CMD_GO);

View file

@ -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