diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/cache/Kconfig | 6 | ||||
-rw-r--r-- | drivers/cache/Makefile | 2 | ||||
-rw-r--r-- | drivers/cache/cache-andes-l2.c (renamed from drivers/cache/cache-v5l2.c) | 40 | ||||
-rw-r--r-- | drivers/cpu/riscv_cpu.c | 2 | ||||
-rw-r--r-- | drivers/crypto/nuvoton/npcm_sha.c | 1024 | ||||
-rw-r--r-- | drivers/dma/ti/k3-udma.c | 4 | ||||
-rw-r--r-- | drivers/net/ti/am65-cpsw-nuss.c | 11 | ||||
-rw-r--r-- | drivers/phy/phy-npcm-usb.c | 27 | ||||
-rw-r--r-- | drivers/pinctrl/pinctrl-uclass.c | 2 | ||||
-rw-r--r-- | drivers/remoteproc/ti_k3_dsp_rproc.c | 13 | ||||
-rw-r--r-- | drivers/remoteproc/ti_k3_r5f_rproc.c | 29 | ||||
-rw-r--r-- | drivers/usb/dwc3/Kconfig | 14 | ||||
-rw-r--r-- | drivers/usb/dwc3/Makefile | 1 | ||||
-rw-r--r-- | drivers/usb/dwc3/dwc3-am62.c | 125 |
14 files changed, 480 insertions, 820 deletions
diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig index 26c2d80a1c5..4f358657444 100644 --- a/drivers/cache/Kconfig +++ b/drivers/cache/Kconfig @@ -22,11 +22,11 @@ config L2X0_CACHE ARMv7(32-bit) devices. The driver configures the cache settings found in the device tree. -config V5L2_CACHE - bool "Andes V5L2 cache driver" +config ANDES_L2_CACHE + bool "Andes L2 cache driver" select CACHE help - Support Andes V5L2 cache controller in AE350 platform. + Support Andes L2 cache controller in AE350 platform. It will configure tag and data ram timing control from the device tree and enable L2 cache. diff --git a/drivers/cache/Makefile b/drivers/cache/Makefile index 78e673d09e5..e1b71e0ed51 100644 --- a/drivers/cache/Makefile +++ b/drivers/cache/Makefile @@ -3,6 +3,6 @@ obj-$(CONFIG_$(SPL_TPL_)CACHE) += cache-uclass.o obj-$(CONFIG_SANDBOX) += sandbox_cache.o obj-$(CONFIG_L2X0_CACHE) += cache-l2x0.o obj-$(CONFIG_NCORE_CACHE) += cache-ncore.o -obj-$(CONFIG_V5L2_CACHE) += cache-v5l2.o +obj-$(CONFIG_ANDES_L2_CACHE) += cache-andes-l2.o obj-$(CONFIG_SIFIVE_CCACHE) += cache-sifive-ccache.o obj-$(CONFIG_SIFIVE_PL2) += cache-sifive-pl2.o diff --git a/drivers/cache/cache-v5l2.c b/drivers/cache/cache-andes-l2.c index f0b8ecc8807..7de8f16852d 100644 --- a/drivers/cache/cache-v5l2.c +++ b/drivers/cache/cache-andes-l2.c @@ -72,7 +72,7 @@ static u32 status_bit_offset = 0x4; DECLARE_GLOBAL_DATA_PTR; -struct v5l2_plat { +struct andes_l2_plat { struct l2cache *regs; u32 iprefetch; u32 dprefetch; @@ -80,9 +80,9 @@ struct v5l2_plat { u32 dram_ctl[2]; }; -static int v5l2_enable(struct udevice *dev) +static int andes_l2_enable(struct udevice *dev) { - struct v5l2_plat *plat = dev_get_plat(dev); + struct andes_l2_plat *plat = dev_get_plat(dev); volatile struct l2cache *regs = plat->regs; if (regs) @@ -91,9 +91,9 @@ static int v5l2_enable(struct udevice *dev) return 0; } -static int v5l2_disable(struct udevice *dev) +static int andes_l2_disable(struct udevice *dev) { - struct v5l2_plat *plat = dev_get_plat(dev); + struct andes_l2_plat *plat = dev_get_plat(dev); volatile struct l2cache *regs = plat->regs; u8 hart = gd->arch.boot_hart; void __iomem *cctlcmd = (void __iomem *)CCTL_CMD_REG(regs, hart); @@ -113,9 +113,9 @@ static int v5l2_disable(struct udevice *dev) return 0; } -static int v5l2_of_to_plat(struct udevice *dev) +static int andes_l2_of_to_plat(struct udevice *dev) { - struct v5l2_plat *plat = dev_get_plat(dev); + struct andes_l2_plat *plat = dev_get_plat(dev); struct l2cache *regs; regs = dev_read_addr_ptr(dev); @@ -137,9 +137,9 @@ static int v5l2_of_to_plat(struct udevice *dev) return 0; } -static int v5l2_probe(struct udevice *dev) +static int andes_l2_probe(struct udevice *dev) { - struct v5l2_plat *plat = dev_get_plat(dev); + struct andes_l2_plat *plat = dev_get_plat(dev); struct l2cache *regs = plat->regs; u32 cfg_val, ctl_val; @@ -182,23 +182,23 @@ static int v5l2_probe(struct udevice *dev) return 0; } -static const struct udevice_id v5l2_cache_ids[] = { +static const struct udevice_id andes_l2_cache_ids[] = { { .compatible = "cache" }, {} }; -static const struct cache_ops v5l2_cache_ops = { - .enable = v5l2_enable, - .disable = v5l2_disable, +static const struct cache_ops andes_l2_cache_ops = { + .enable = andes_l2_enable, + .disable = andes_l2_disable, }; -U_BOOT_DRIVER(v5l2_cache) = { - .name = "v5l2_cache", +U_BOOT_DRIVER(andes_l2_cache) = { + .name = "andes_l2_cache", .id = UCLASS_CACHE, - .of_match = v5l2_cache_ids, - .of_to_plat = v5l2_of_to_plat, - .probe = v5l2_probe, - .plat_auto = sizeof(struct v5l2_plat), - .ops = &v5l2_cache_ops, + .of_match = andes_l2_cache_ids, + .of_to_plat = andes_l2_of_to_plat, + .probe = andes_l2_probe, + .plat_auto = sizeof(struct andes_l2_plat), + .ops = &andes_l2_cache_ops, .flags = DM_FLAG_PRE_RELOC, }; diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c index 4f2958a23ce..4fff4658b5f 100644 --- a/drivers/cpu/riscv_cpu.c +++ b/drivers/cpu/riscv_cpu.c @@ -23,7 +23,7 @@ static int riscv_cpu_get_desc(const struct udevice *dev, char *buf, int size) const char *cpu; cpu = dev_read_string(dev, "compatible"); - if (size < (strlen(cpu) + 1)) + if (!cpu || size < (strlen(cpu) + 1)) return -ENOSPC; strcpy(buf, cpu); diff --git a/drivers/crypto/nuvoton/npcm_sha.c b/drivers/crypto/nuvoton/npcm_sha.c index f06be86ca59..6da162069aa 100644 --- a/drivers/crypto/nuvoton/npcm_sha.c +++ b/drivers/crypto/nuvoton/npcm_sha.c @@ -1,867 +1,344 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (c) 2022 Nuvoton Technology Corp. + * Copyright (c) 2024 Nuvoton Technology Corp. */ #include <dm.h> #include <hash.h> #include <malloc.h> -#include <uboot_aes.h> #include <asm/io.h> +#include <linux/iopoll.h> -#define HASH_DIG_H_NUM 8 +#define SHA512_BLOCK_LENGTH (1024 / 8) +/* Register fields */ #define HASH_CTR_STS_SHA_EN BIT(0) #define HASH_CTR_STS_SHA_BUSY BIT(1) #define HASH_CTR_STS_SHA_RST BIT(2) #define HASH_CFG_SHA1_SHA2 BIT(0) - -/* SHA type */ -enum npcm_sha_type { - npcm_sha_type_sha2 = 0, - npcm_sha_type_sha1, - npcm_sha_type_num +#define SHA512_CMD_SHA_512 BIT(3) +#define SHA512_CMD_INTERNAL_ROUND BIT(2) +#define SHA512_CMD_WRITE BIT(1) +#define SHA512_CMD_READ BIT(0) + +enum { + type_sha1 = 0, + type_sha256, + type_sha384, + type_sha512, }; struct npcm_sha_regs { - unsigned int hash_data_in; - unsigned char hash_ctr_sts; - unsigned char reserved_0[0x03]; - unsigned char hash_cfg; - unsigned char reserved_1[0x03]; - unsigned char hash_ver; - unsigned char reserved_2[0x13]; - unsigned int hash_dig[HASH_DIG_H_NUM]; + u8 data_in; + u8 data_out; + u8 ctr_sts; + u8 hash_cfg; + u8 sha512_cmd; }; -struct npcm_sha_priv { - struct npcm_sha_regs *regs; +struct hash_info { + u32 block_sz; + u32 digest_len; + u8 length_bytes; + u8 type; }; -static struct npcm_sha_priv *sha_priv; +struct message_block { + u64 length[2]; + u64 nonhash_sz; + u8 buffer[SHA512_BLOCK_LENGTH * 2]; +}; -#ifdef SHA_DEBUG_MODULE -#define sha_print(fmt, args...) printf(fmt, ##args) -#else -#define sha_print(fmt, args...) (void)0 -#endif - -#define SHA_BLOCK_LENGTH (512 / 8) -#define SHA_2_HASH_LENGTH (256 / 8) -#define SHA_1_HASH_LENGTH (160 / 8) -#define SHA_HASH_LENGTH(type) ((type == npcm_sha_type_sha2) ? \ - (SHA_2_HASH_LENGTH) : (SHA_1_HASH_LENGTH)) - -#define SHA_SECRUN_BUFF_SIZE 64 -#define SHA_TIMEOUT 100 -#define SHA_DATA_LAST_BYTE 0x80 - -#define SHA2_NUM_OF_SELF_TESTS 3 -#define SHA1_NUM_OF_SELF_TESTS 4 - -#define NUVOTON_ALIGNMENT 4 - -/*-----------------------------------------------------------------------------*/ -/* SHA instance struct handler */ -/*-----------------------------------------------------------------------------*/ -struct SHA_HANDLE_T { - u32 hv[SHA_2_HASH_LENGTH / sizeof(u32)]; - u32 length0; - u32 length1; - u32 block[SHA_BLOCK_LENGTH / sizeof(u32)]; - u8 type; - bool active; +struct npcm_sha_priv { + void *base; + struct npcm_sha_regs *regs; + struct hash_info *hash; + struct message_block block; + bool internal_round; + bool support_sha512; }; -// The # of bytes currently in the sha block buffer -#define SHA_BUFF_POS(length) ((length) & (SHA_BLOCK_LENGTH - 1)) - -// The # of free bytes in the sha block buffer -#define SHA_BUFF_FREE(length) (SHA_BLOCK_LENGTH - SHA_BUFF_POS(length)) - -static void SHA_FlushLocalBuffer_l(const u32 *buff); -static int SHA_BusyWait_l(void); -static void SHA_GetShaDigest_l(u8 *hashdigest, u8 type); -static void SHA_SetShaDigest_l(const u32 *hashdigest, u8 type); -static void SHA_SetBlock_l(const u8 *data, u32 len, u16 position, u32 *block); -static void SHA_ClearBlock_l(u16 len, u16 position, u32 *block); -static void SHA_SetLength32_l(struct SHA_HANDLE_T *handleptr, u32 *block); - -static int SHA_Init(struct SHA_HANDLE_T *handleptr); -static int SHA_Start(struct SHA_HANDLE_T *handleptr, u8 type); -static int SHA_Update(struct SHA_HANDLE_T *handleptr, const u8 *buffer, u32 len); -static int SHA_Finish(struct SHA_HANDLE_T *handleptr, u8 *hashdigest); -static int SHA_Reset(void); -static int SHA_Power(bool on); -#ifdef SHA_PRINT -static void SHA_PrintRegs(void); -static void SHA_PrintVersion(void); -#endif - -static struct SHA_HANDLE_T sha_handle; - -/*----------------------------------------------------------------------------*/ -/* Checks if give function returns int error, and returns the error */ -/* immediately after SHA disabling */ -/*----------------------------------------------------------------------------*/ -int npcm_sha_check(int status) -{ - if (status != 0) { - SHA_Power(false); - return status; - } - return 0; -} +static struct npcm_sha_regs npcm_sha_reg_tbl[] = { + { .data_in = 0x0, .data_out = 0x20, .ctr_sts = 0x4, .hash_cfg = 0x8 }, + { .data_in = 0x10, .data_out = 0x1c, .ctr_sts = 0x14, .sha512_cmd = 0x18 }, +}; -/*----------------------------------------------------------------------------*/ -/* Function: npcm_sha_calc */ -/* */ -/* Parameters: type - SHA module type */ -/* inBuff - Pointer to a buffer containing the data to */ -/* be hashed */ -/* len - Length of the data to hash */ -/* hashDigest - Pointer to a buffer where the reseulting */ -/* digest will be copied to */ -/* */ -/* Returns: 0 on success or other int error code on error */ -/* Side effects: */ -/* Description: */ -/* This routine performs complete SHA calculation in one */ -/* step */ -/*----------------------------------------------------------------------------*/ -int npcm_sha_calc(u8 type, const u8 *inbuff, u32 len, u8 *hashdigest) -{ - int status; - struct SHA_HANDLE_T handle; - - SHA_Init(&handle); - SHA_Power(true); - SHA_Reset(); - SHA_Start(&handle, type); - status = SHA_Update(&handle, inbuff, len); - npcm_sha_check(status); - status = SHA_Finish(&handle, hashdigest); - npcm_sha_check(status); - SHA_Power(false); +static struct hash_info npcm_hash_tbl[] = { + { .type = type_sha1, .block_sz = 64, .digest_len = 160, .length_bytes = 8 }, + { .type = type_sha256, .block_sz = 64, .digest_len = 256, .length_bytes = 8 }, + { .type = type_sha384, .block_sz = 128, .digest_len = 384, .length_bytes = 16 }, + { .type = type_sha512, .block_sz = 128, .digest_len = 512, .length_bytes = 16 }, +}; - return 0; -} +static struct npcm_sha_priv *sha_priv; -/* - * Computes hash value of input pbuf using h/w acceleration - * - * @param in_addr A pointer to the input buffer - * @param bufleni Byte length of input buffer - * @param out_addr A pointer to the output buffer. When complete - * 32 bytes are copied to pout[0]...pout[31]. Thus, a user - * should allocate at least 32 bytes at pOut in advance. - * @param chunk_size chunk size for sha256 - */ -void hw_sha256(const uchar *in_addr, uint buflen, uchar *out_addr, uint chunk_size) +static int npcm_sha_init(u8 type) { - puts("\nhw_sha256 using BMC HW accelerator\t"); - npcm_sha_calc(npcm_sha_type_sha2, (u8 *)in_addr, buflen, (u8 *)out_addr); -} + struct message_block *block = &sha_priv->block; -/* - * Computes hash value of input pbuf using h/w acceleration - * - * @param in_addr A pointer to the input buffer - * @param bufleni Byte length of input buffer - * @param out_addr A pointer to the output buffer. When complete - * 32 bytes are copied to pout[0]...pout[31]. Thus, a user - * should allocate at least 32 bytes at pOut in advance. - * @param chunk_size chunk_size for sha1 - */ -void hw_sha1(const uchar *in_addr, uint buflen, uchar *out_addr, uint chunk_size) -{ - puts("\nhw_sha1 using BMC HW accelerator\t"); - npcm_sha_calc(npcm_sha_type_sha1, (u8 *)in_addr, buflen, (u8 *)out_addr); -} + if (type > type_sha512 || + (!sha_priv->support_sha512 && + (type == type_sha384 || type == type_sha512))) + return -ENOTSUPP; -/* - * Create the context for sha progressive hashing using h/w acceleration - * - * @algo: Pointer to the hash_algo struct - * @ctxp: Pointer to the pointer of the context for hashing - * @return 0 if ok, -ve on error - */ -int hw_sha_init(struct hash_algo *algo, void **ctxp) -{ - const char *algo_name1 = "sha1"; - const char *algo_name2 = "sha256"; - - SHA_Init(&sha_handle); - SHA_Power(true); - SHA_Reset(); - if (!strcmp(algo_name1, algo->name)) - return SHA_Start(&sha_handle, npcm_sha_type_sha1); - else if (!strcmp(algo_name2, algo->name)) - return SHA_Start(&sha_handle, npcm_sha_type_sha2); - else - return -EPROTO; -} + sha_priv->regs = &npcm_sha_reg_tbl[type / 2]; + sha_priv->hash = &npcm_hash_tbl[type]; + block->length[0] = 0; + block->length[1] = 0; + block->nonhash_sz = 0; + sha_priv->internal_round = false; -/* - * Update buffer for sha progressive hashing using h/w acceleration - * - * The context is freed by this function if an error occurs. - * - * @algo: Pointer to the hash_algo struct - * @ctx: Pointer to the context for hashing - * @buf: Pointer to the buffer being hashed - * @size: Size of the buffer being hashed - * @is_last: 1 if this is the last update; 0 otherwise - * @return 0 if ok, -ve on error - */ -int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf, - unsigned int size, int is_last) -{ - return SHA_Update(&sha_handle, buf, size); + return 0; } -/* - * Copy sha hash result at destination location - * - * The context is freed after completion of hash operation or after an error. - * - * @algo: Pointer to the hash_algo struct - * @ctx: Pointer to the context for hashing - * @dest_buf: Pointer to the destination buffer where hash is to be copied - * @size: Size of the buffer being hashed - * @return 0 if ok, -ve on error - */ -int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf, int size) +static void npcm_sha_reset(void) { - int status; - - status = SHA_Finish(&sha_handle, dest_buf); - npcm_sha_check(status); - return SHA_Power(false); + struct npcm_sha_regs *regs = sha_priv->regs; + struct hash_info *hash = sha_priv->hash; + u8 val; + + if (hash->type == type_sha1) + writeb(HASH_CFG_SHA1_SHA2, sha_priv->base + regs->hash_cfg); + else if (hash->type == type_sha256) + writeb(0, sha_priv->base + regs->hash_cfg); + else if (hash->type == type_sha384) + writeb(0, sha_priv->base + regs->sha512_cmd); + else if (hash->type == type_sha512) + writeb(SHA512_CMD_SHA_512, sha_priv->base + regs->sha512_cmd); + + val = readb(sha_priv->base + regs->ctr_sts) & ~HASH_CTR_STS_SHA_EN; + writeb(val | HASH_CTR_STS_SHA_RST, sha_priv->base + regs->ctr_sts); } -/*----------------------------------------------------------------------------*/ -/* Function: SHA_Init */ -/* */ -/* Parameters: handlePtr - SHA processing handle pointer */ -/* Returns: 0 on success or other int error code on error. */ -/* Side effects: */ -/* Description: */ -/* This routine initialize the SHA module */ -/*----------------------------------------------------------------------------*/ -static int SHA_Init(struct SHA_HANDLE_T *handleptr) +static void npcm_sha_enable(bool on) { - handleptr->active = false; + struct npcm_sha_regs *regs = sha_priv->regs; + u8 val; - return 0; + val = readb(sha_priv->base + regs->ctr_sts) & ~HASH_CTR_STS_SHA_EN; + val |= on; + writeb(val | on, sha_priv->base + regs->ctr_sts); } -/*----------------------------------------------------------------------------*/ -/* Function: SHA_Start */ -/* */ -/* Parameters: handlePtr - SHA processing handle pointer */ -/* type - SHA module type */ -/* */ -/* Returns: 0 on success or other int error code on error. */ -/* Side effects: */ -/* Description: */ -/* This routine start a single SHA process */ -/*----------------------------------------------------------------------------*/ -static int SHA_Start(struct SHA_HANDLE_T *handleptr, u8 type) +static int npcm_sha_flush_block(u8 *block) { struct npcm_sha_regs *regs = sha_priv->regs; + struct hash_info *hash = sha_priv->hash; + u32 *blk_dw = (u32 *)block; + u8 val; + int i; + + if (readb_poll_timeout(sha_priv->base + regs->ctr_sts, val, + !(val & HASH_CTR_STS_SHA_BUSY), 100)) + return -ETIMEDOUT; + + if (hash->type == type_sha384 || hash->type == type_sha512) { + val = SHA512_CMD_WRITE; + if (hash->type == type_sha512) + val |= SHA512_CMD_SHA_512; + if (sha_priv->internal_round) + val |= SHA512_CMD_INTERNAL_ROUND; + writeb(val, sha_priv->base + regs->sha512_cmd); + } + for (i = 0; i < (hash->block_sz / sizeof(u32)); i++) + writel(blk_dw[i], sha_priv->base + regs->data_in); - // Initialize handle - handleptr->length0 = 0; - handleptr->length1 = 0; - handleptr->type = type; - handleptr->active = true; - - // Set SHA type - writeb(handleptr->type & HASH_CFG_SHA1_SHA2, ®s->hash_cfg); - - // Reset SHA hardware - SHA_Reset(); - - /* The handlePtr->hv is initialized with the correct IV as the SHA engine - * automatically fill the HASH_DIG_Hn registers according to SHA spec - * (following SHA_RST assertion) - */ - SHA_GetShaDigest_l((u8 *)handleptr->hv, type); - - // Init block with zeros - memset(handleptr->block, 0, sizeof(handleptr->block)); + sha_priv->internal_round = true; return 0; } -/*----------------------------------------------------------------------------*/ -/* Function: SHA_Update */ -/* */ -/* Parameters: handlePtr - SHA processing handle pointer */ -/* buffer - Pointer to the data that will be added to */ -/* the hash calculation */ -/* len - Length of data to add to SHA calculation */ -/* */ -/* */ -/* Returns: 0 on success or other int error code on error */ -/* Side effects: */ -/* Description: */ -/* This routine adds data to previously started SHA */ -/* calculation */ -/*----------------------------------------------------------------------------*/ -static int SHA_Update(struct SHA_HANDLE_T *handleptr, const u8 *buffer, u32 len) +static int npcm_sha_update_block(const u8 *in, u32 len) { - struct npcm_sha_regs *regs = sha_priv->regs; - u32 localbuffer[SHA_SECRUN_BUFF_SIZE / sizeof(u32)]; - u32 bufferlen = len; - u16 pos = 0; - u8 *blockptr; - int status; - - // Error check - if (!handleptr->active) - return -EPROTO; - - // Wait till SHA is not busy - status = SHA_BusyWait_l(); - npcm_sha_check(status); - - // Set SHA type - writeb(handleptr->type & HASH_CFG_SHA1_SHA2, ®s->hash_cfg); - - // Write SHA latest digest into SHA module - SHA_SetShaDigest_l(handleptr->hv, handleptr->type); - - // Set number of unhashed bytes which remained from last update - pos = SHA_BUFF_POS(handleptr->length0); - - // Copy unhashed bytes which remained from last update to secrun buffer - SHA_SetBlock_l((u8 *)handleptr->block, pos, 0, localbuffer); - - while (len) { - // Wait for the hardware to be available (in case we are hashing) - status = SHA_BusyWait_l(); - npcm_sha_check(status); - - // Move as much bytes as we can into the secrun buffer - bufferlen = min(len, SHA_BUFF_FREE(handleptr->length0)); - - // Copy current given buffer to the secrun buffer - SHA_SetBlock_l((u8 *)buffer, bufferlen, pos, localbuffer); - - // Update size of hashed bytes - handleptr->length0 += bufferlen; - - if (handleptr->length0 < bufferlen) - handleptr->length1++; - - // Update length of data left to digest - len -= bufferlen; - - // Update given buffer pointer - buffer += bufferlen; - - // If secrun buffer is full - if (SHA_BUFF_POS(handleptr->length0) == 0) { - /* We just filled up the buffer perfectly, so let it hash (we'll - * unload the hash only when we are done with all hashing) - */ - SHA_FlushLocalBuffer_l(localbuffer); - - pos = 0; - bufferlen = 0; - } + struct message_block *block = &sha_priv->block; + struct hash_info *hash = sha_priv->hash; + u8 *buffer = &block->buffer[0]; + u32 block_sz = hash->block_sz; + u32 hash_sz; + + hash_sz = (block->nonhash_sz + len) > block_sz ? + (block_sz - block->nonhash_sz) : len; + memcpy(buffer + block->nonhash_sz, in, hash_sz); + block->nonhash_sz += hash_sz; + block->length[0] += hash_sz; + if (block->length[0] < hash_sz) + block->length[1]++; + + if (block->nonhash_sz == block_sz) { + block->nonhash_sz = 0; + if (npcm_sha_flush_block(buffer)) + return -EBUSY; } - // Wait till SHA is not busy - status = SHA_BusyWait_l(); - npcm_sha_check(status); - - /* Copy unhashed bytes from given buffer to handle block for next update/finish */ - blockptr = (u8 *)handleptr->block; - while (bufferlen) - blockptr[--bufferlen + pos] = *(--buffer); - - // Save SHA current digest - SHA_GetShaDigest_l((u8 *)handleptr->hv, handleptr->type); - - return 0; + return hash_sz; } -/*----------------------------------------------------------------------------*/ -/* Function: SHA_Finish */ -/* */ -/* Parameters: handlePtr - SHA processing handle pointer */ -/* hashDigest - Pointer to a buffer where the final digest */ -/* will be copied to */ -/* */ -/* Returns: 0 on success or other int error code on error */ -/* Side effects: */ -/* Description: */ -/* This routine finish SHA calculation and get */ -/* the resulting SHA digest */ -/*----------------------------------------------------------------------------*/ -static int SHA_Finish(struct SHA_HANDLE_T *handleptr, u8 *hashdigest) +static int npcm_sha_update(const u8 *input, u32 len) { - struct npcm_sha_regs *regs = sha_priv->regs; - u32 localbuffer[SHA_SECRUN_BUFF_SIZE / sizeof(u32)]; - const u8 lastbyte = SHA_DATA_LAST_BYTE; - u16 pos; - int status; - - // Error check - if (!handleptr->active) - return -EPROTO; - - // Set SHA type - writeb(handleptr->type & HASH_CFG_SHA1_SHA2, ®s->hash_cfg); - - // Wait till SHA is not busy - status = SHA_BusyWait_l(); - npcm_sha_check(status); - - // Finish off the current buffer with the SHA spec'ed padding - pos = SHA_BUFF_POS(handleptr->length0); - - // Init SHA digest - SHA_SetShaDigest_l(handleptr->hv, handleptr->type); - - // Load data into secrun buffer - SHA_SetBlock_l((u8 *)handleptr->block, pos, 0, localbuffer); - - // Set data last byte as in SHA algorithm spec - SHA_SetBlock_l(&lastbyte, 1, pos++, localbuffer); + int hash_sz; - // If the remainder of data is longer then one block - if (pos > (SHA_BLOCK_LENGTH - 8)) { - /* The length will be in the next block Pad the rest of the last block with 0's */ - SHA_ClearBlock_l((SHA_BLOCK_LENGTH - pos), pos, localbuffer); - - // Hash the current block - SHA_FlushLocalBuffer_l(localbuffer); - - pos = 0; - - // Wait till SHA is not busy - status = SHA_BusyWait_l(); - npcm_sha_check(status); + while (len) { + hash_sz = npcm_sha_update_block(input, len); + if (hash_sz < 0) { + printf("SHA512 module busy\n"); + return -EBUSY; + } + len -= hash_sz; + input += hash_sz; } - // Pad the rest of the last block with 0's except for the last 8-3 bytes - SHA_ClearBlock_l((SHA_BLOCK_LENGTH - (8 - 3)) - pos, pos, localbuffer); - - /* The last 8-3 bytes are set to the bit-length of the message in big-endian form */ - SHA_SetLength32_l(handleptr, localbuffer); - - // Hash all that, and save the hash for the caller - SHA_FlushLocalBuffer_l(localbuffer); - - // Wait till SHA is not busy - status = SHA_BusyWait_l(); - npcm_sha_check(status); - - // Save SHA final digest into given buffer - SHA_GetShaDigest_l(hashdigest, handleptr->type); - - // Free handle - handleptr->active = false; - return 0; } -/*----------------------------------------------------------------------------*/ -/* Function: SHA_Reset */ -/* */ -/* Parameters: none */ -/* Returns: none */ -/* Side effects: */ -/* Description: */ -/* This routine reset SHA module */ -/*----------------------------------------------------------------------------*/ -static int SHA_Reset(void) +static int npcm_sha_finish(u8 *out) { struct npcm_sha_regs *regs = sha_priv->regs; - - writel(readl(®s->hash_ctr_sts) | HASH_CTR_STS_SHA_RST, ®s->hash_ctr_sts); + struct message_block *block = &sha_priv->block; + struct hash_info *hash = sha_priv->hash; + u8 *buffer = &block->buffer[0]; + u32 block_sz = hash->block_sz; + u32 *out32 = (u32 *)out; + u32 zero_len, val; + u64 *length; + u8 reg_data_out; + int i; + + /* Padding, minimal padding size is last_byte+length_bytes */ + if ((block_sz - block->nonhash_sz) >= (hash->length_bytes + 1)) + zero_len = block_sz - block->nonhash_sz - (hash->length_bytes + 1); + else + zero_len = block_sz * 2 - block->nonhash_sz - (hash->length_bytes + 1); + /* Last byte */ + buffer[block->nonhash_sz++] = 0x80; + /* Zero bits padding */ + memset(&buffer[block->nonhash_sz], 0, zero_len); + block->nonhash_sz += zero_len; + /* Message length */ + length = (u64 *)&buffer[block->nonhash_sz]; + if (hash->length_bytes == 16) { + *length++ = cpu_to_be64(block->length[1] << 3 | block->length[0] >> 61); + block->nonhash_sz += 8; + } + *length = cpu_to_be64(block->length[0] << 3); + block->nonhash_sz += 8; + if (npcm_sha_flush_block(&block->buffer[0])) + return -ETIMEDOUT; + + /* After padding, the last message may produce 2 blocks */ + if (block->nonhash_sz > block_sz) { + if (npcm_sha_flush_block(&block->buffer[block_sz])) + return -ETIMEDOUT; + } + /* Read digest */ + if (readb_poll_timeout(sha_priv->base + regs->ctr_sts, val, + !(val & HASH_CTR_STS_SHA_BUSY), 100)) + return -ETIMEDOUT; + if (hash->type == type_sha384) + writeb(SHA512_CMD_READ, sha_priv->base + regs->sha512_cmd); + else if (hash->type == type_sha512) + writeb(SHA512_CMD_SHA_512 | SHA512_CMD_READ, + sha_priv->base + regs->sha512_cmd); + + reg_data_out = regs->data_out; + for (i = 0; i < (hash->digest_len / 32); i++) { + *out32 = readl(sha_priv->base + reg_data_out); + out32++; + if (hash->type == type_sha1 || hash->type == type_sha256) + reg_data_out += 4; + } return 0; } -/*----------------------------------------------------------------------------*/ -/* Function: SHA_Power */ -/* */ -/* Parameters: on - true enable the module, false disable the module */ -/* Returns: none */ -/* Side effects: */ -/* Description: */ -/* This routine set SHA module power on/off */ -/*----------------------------------------------------------------------------*/ -static int SHA_Power(bool on) +int npcm_sha_calc(const u8 *input, u32 len, u8 *output, u8 type) { - struct npcm_sha_regs *regs = sha_priv->regs; - u8 hash_sts; - - hash_sts = readb(®s->hash_ctr_sts) & ~HASH_CTR_STS_SHA_EN; - writeb(hash_sts | (on & HASH_CTR_STS_SHA_EN), ®s->hash_ctr_sts); + if (npcm_sha_init(type)) + return -ENOTSUPP; + npcm_sha_reset(); + npcm_sha_enable(true); + npcm_sha_update(input, len); + npcm_sha_finish(output); + npcm_sha_enable(false); return 0; } -#ifdef SHA_PRINT -/*----------------------------------------------------------------------------*/ -/* Function: SHA_PrintRegs */ -/* */ -/* Parameters: none */ -/* Returns: none */ -/* Side effects: */ -/* Description: */ -/* This routine prints the module registers */ -/*----------------------------------------------------------------------------*/ -static void SHA_PrintRegs(void) +void hw_sha512(const unsigned char *input, unsigned int len, + unsigned char *output, unsigned int chunk_sz) { -#ifdef SHA_DEBUG_MODULE - struct npcm_sha_regs *regs = sha_priv->regs; -#endif - unsigned int i; - - sha_print("/*--------------*/\n"); - sha_print("/* SHA */\n"); - sha_print("/*--------------*/\n\n"); - - sha_print("HASH_CTR_STS = 0x%02X\n", readb(®s->hash_ctr_sts)); - sha_print("HASH_CFG = 0x%02X\n", readb(®s->hash_cfg)); - - for (i = 0; i < HASH_DIG_H_NUM; i++) - sha_print("HASH_DIG_H%d = 0x%08X\n", i, readl(®s->hash_dig[i])); - - sha_print("HASH_VER = 0x%08X\n", readb(®s->hash_ver)); - - sha_print("\n"); + if (!sha_priv->support_sha512) { + puts(" HW accelerator not support\n"); + return; + } + puts(" using BMC HW accelerator\n"); + npcm_sha_calc(input, len, output, type_sha512); } -/*----------------------------------------------------------------------------*/ -/* Function: SHA_PrintVersion */ -/* */ -/* Parameters: none */ -/* Returns: none */ -/* Side effects: */ -/* Description: */ -/* This routine prints the module version */ -/*----------------------------------------------------------------------------*/ -static void SHA_PrintVersion(void) -{ - struct npcm_sha_regs *regs = sha_priv->regs; - - printf("SHA MODULE VER = %d\n", readb(®s->hash_ver)); -} -#endif - -/*----------------------------------------------------------------------------*/ -/* Function: npcm_sha_selftest */ -/* */ -/* Parameters: type - SHA module type */ -/* Returns: 0 on success or other int error code on error */ -/* Side effects: */ -/* Description: */ -/* This routine performs various tests on the SHA HW and SW */ -/*----------------------------------------------------------------------------*/ -int npcm_sha_selftest(u8 type) +void hw_sha384(const unsigned char *input, unsigned int len, + unsigned char *output, unsigned int chunk_sz) { - int status; - struct SHA_HANDLE_T handle; - u8 hashdigest[max(SHA_1_HASH_LENGTH, SHA_2_HASH_LENGTH)]; - u16 i, j; - - /*------------------------------------------------------------------------*/ - /* SHA1 tests info */ - /*------------------------------------------------------------------------*/ - - static const u8 sha1selftestbuff[SHA1_NUM_OF_SELF_TESTS][94] = { - {"abc"}, - {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"}, - {"0123456789012345678901234567890123456789012345678901234567890123"}, - {0x30, 0x5c, 0x30, 0x2c, 0x02, 0x01, 0x00, 0x30, 0x09, 0x06, 0x05, 0x2b, - 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x30, 0x06, 0x06, 0x04, 0x67, 0x2a, - 0x01, 0x0c, 0x04, 0x14, 0xe1, 0xb6, 0x93, 0xfe, 0x33, 0x43, 0xc1, 0x20, - 0x5d, 0x4b, 0xaa, 0xb8, 0x63, 0xfb, 0xcf, 0x6c, 0x46, 0x1e, 0x88, 0x04, - 0x30, 0x2c, 0x02, 0x01, 0x00, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, - 0x02, 0x1a, 0x05, 0x00, 0x30, 0x06, 0x06, 0x04, 0x67, 0x2a, 0x01, 0x0c, - 0x04, 0x14, 0x13, 0xc1, 0x0c, 0xfc, 0xc8, 0x92, 0xd7, 0xde, 0x07, 0x1c, - 0x40, 0xde, 0x4f, 0xcd, 0x07, 0x5b, 0x68, 0x20, 0x5a, 0x6c} - }; - - static const u8 sha1selftestbufflen[SHA1_NUM_OF_SELF_TESTS] = { - 3, 56, 64, 94 - }; - - static const u8 sha1selftestexpres[SHA1_NUM_OF_SELF_TESTS][SHA_1_HASH_LENGTH] = { - {0xA9, 0x99, 0x3E, 0x36, - 0x47, 0x06, 0x81, 0x6A, - 0xBA, 0x3E, 0x25, 0x71, - 0x78, 0x50, 0xC2, 0x6C, - 0x9C, 0xD0, 0xD8, 0x9D}, - {0x84, 0x98, 0x3E, 0x44, - 0x1C, 0x3B, 0xD2, 0x6E, - 0xBA, 0xAE, 0x4A, 0xA1, - 0xF9, 0x51, 0x29, 0xE5, - 0xE5, 0x46, 0x70, 0xF1}, - {0xCF, 0x08, 0x00, 0xF7, - 0x64, 0x4A, 0xCE, 0x3C, - 0xB4, 0xC3, 0xFA, 0x33, - 0x38, 0x8D, 0x3B, 0xA0, - 0xEA, 0x3C, 0x8B, 0x6E}, - {0xc9, 0x84, 0x45, 0xc8, - 0x64, 0x04, 0xb1, 0xe3, - 0x3c, 0x6b, 0x0a, 0x8c, - 0x8b, 0x80, 0x94, 0xfc, - 0xf3, 0xc9, 0x98, 0xab} - }; - - /*------------------------------------------------------------------------*/ - /* SHA2 tests info */ - /*------------------------------------------------------------------------*/ - - static const u8 sha2selftestbuff[SHA2_NUM_OF_SELF_TESTS][100] = { - { "abc" }, - { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, - {'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', - 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'} - }; - - static const u8 sha2selftestbufflen[SHA2_NUM_OF_SELF_TESTS] = { - 3, 56, 100 - }; - - static const u8 sha2selftestexpres[SHA2_NUM_OF_SELF_TESTS][SHA_2_HASH_LENGTH] = { - /* - * SHA-256 test vectors - */ - { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, - 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, - 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, - 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD }, - { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, - 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, - 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, - 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }, - { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, - 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67, - 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E, - 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 }, - }; - - if (type == npcm_sha_type_sha1) { - /*--------------------------------------------------------------------*/ - /* SHA 1 TESTS */ - /*--------------------------------------------------------------------*/ - for (i = 0; i < SHA1_NUM_OF_SELF_TESTS; i++) { - if (i != 3) { - status = npcm_sha_calc(npcm_sha_type_sha1, sha1selftestbuff[i], sha1selftestbufflen[i], hashdigest); - npcm_sha_check(status); - } else { - SHA_Power(true); - SHA_Reset(); - status = SHA_Start(&handle, npcm_sha_type_sha1); - npcm_sha_check(status); - status = SHA_Update(&handle, sha1selftestbuff[i], 73); - npcm_sha_check(status); - status = SHA_Update(&handle, &sha1selftestbuff[i][73], sha1selftestbufflen[i] - 73); - npcm_sha_check(status); - status = SHA_Finish(&handle, hashdigest); - npcm_sha_check(status); - SHA_Power(false); - } - - if (memcmp(hashdigest, sha1selftestexpres[i], SHA_1_HASH_LENGTH)) - return -1; - } - - } else { - /*--------------------------------------------------------------------*/ - /* SHA 2 TESTS */ - /*--------------------------------------------------------------------*/ - for (i = 0; i < SHA2_NUM_OF_SELF_TESTS; i++) { - SHA_Power(true); - SHA_Reset(); - status = SHA_Start(&handle, npcm_sha_type_sha2); - npcm_sha_check(status); - if (i == 2) { - for (j = 0; j < 10000; j++) { //not working - status = SHA_Update(&handle, sha2selftestbuff[i], sha2selftestbufflen[i]); - npcm_sha_check(status); - } - } else { - status = SHA_Update(&handle, sha2selftestbuff[i], sha2selftestbufflen[i]); - npcm_sha_check(status); - } - - status = SHA_Finish(&handle, hashdigest); - npcm_sha_check(status); - SHA_Power(false); - if (memcmp(hashdigest, sha2selftestexpres[i], SHA_2_HASH_LENGTH)) - return -1; - - npcm_sha_calc(npcm_sha_type_sha2, sha2selftestbuff[i], sha2selftestbufflen[i], hashdigest); - if (memcmp(hashdigest, sha2selftestexpres[i], SHA_2_HASH_LENGTH)) - return -1; - } + if (!sha_priv->support_sha512) { + puts(" HW accelerator not support\n"); + return; } - - return 0; + puts(" using BMC HW accelerator\n"); + npcm_sha_calc(input, len, output, type_sha384); } -/*----------------------------------------------------------------------------*/ -/* Function: SHA_FlushLocalBuffer_l */ -/* */ -/* Parameters: */ -/* Returns: none */ -/* Side effects: */ -/* Description: This routine flush secrun buffer to SHA module */ -/*----------------------------------------------------------------------------*/ -static void SHA_FlushLocalBuffer_l(const u32 *buff) +void hw_sha256(const unsigned char *input, unsigned int len, + unsigned char *output, unsigned int chunk_sz) { - struct npcm_sha_regs *regs = sha_priv->regs; - u32 i; - - for (i = 0; i < (SHA_BLOCK_LENGTH / sizeof(u32)); i++) - writel(buff[i], ®s->hash_data_in); + puts(" using BMC HW accelerator\n"); + npcm_sha_calc(input, len, output, type_sha256); } -/*----------------------------------------------------------------------------*/ -/* Function: SHA_BusyWait_l */ -/* */ -/* Parameters: */ -/* Returns: 0 if no error was found or DEFS_STATUS_ERROR otherwise */ -/* Side effects: */ -/* Description: This routine wait for SHA unit to no longer be busy */ -/*----------------------------------------------------------------------------*/ -static int SHA_BusyWait_l(void) +void hw_sha1(const unsigned char *input, unsigned int len, + unsigned char *output, unsigned int chunk_sz) { - struct npcm_sha_regs *regs = sha_priv->regs; - u32 timeout = SHA_TIMEOUT; - - do { - if (timeout-- == 0) - return -ETIMEDOUT; - } while ((readb(®s->hash_ctr_sts) & HASH_CTR_STS_SHA_BUSY) - == HASH_CTR_STS_SHA_BUSY); - - return 0; + puts(" using BMC HW accelerator\n"); + npcm_sha_calc(input, len, output, type_sha1); } -/*----------------------------------------------------------------------------*/ -/* Function: SHA_GetShaDigest_l */ -/* */ -/* Parameters: hashDigest - buffer for the hash output. */ -/* type - SHA module type */ -/* Returns: none */ -/* Side effects: */ -/* Description: This routine copy the hash digest from the hardware */ -/* and into given buffer (in ram) */ -/*----------------------------------------------------------------------------*/ -static void SHA_GetShaDigest_l(u8 *hashdigest, u8 type) +int hw_sha_init(struct hash_algo *algo, void **ctxp) { - struct npcm_sha_regs *regs = sha_priv->regs; - u16 j; - u8 len = SHA_HASH_LENGTH(type) / sizeof(u32); - - // Copy Bytes from SHA module to given buffer - for (j = 0; j < len; j++) - ((u32 *)hashdigest)[j] = readl(®s->hash_dig[j]); -} + if (!strcmp("sha1", algo->name)) { + npcm_sha_init(type_sha1); + } else if (!strcmp("sha256", algo->name)) { + npcm_sha_init(type_sha256); + } else if (!strcmp("sha384", algo->name)) { + if (!sha_priv->support_sha512) + return -ENOTSUPP; + npcm_sha_init(type_sha384); + } else if (!strcmp("sha512", algo->name)) { + if (!sha_priv->support_sha512) + return -ENOTSUPP; + npcm_sha_init(type_sha512); + } else { + return -ENOTSUPP; + } -/*----------------------------------------------------------------------------*/ -/* Function: SHA_SetShaDigest_l */ -/* */ -/* Parameters: hashDigest - input buffer to set as hash digest */ -/* type - SHA module type */ -/* Returns: none */ -/* Side effects: */ -/* Description: This routine set the hash digest in the hardware from */ -/* a given buffer (in ram) */ -/*----------------------------------------------------------------------------*/ -static void SHA_SetShaDigest_l(const u32 *hashdigest, u8 type) -{ - struct npcm_sha_regs *regs = sha_priv->regs; - u16 j; - u8 len = SHA_HASH_LENGTH(type) / sizeof(u32); + printf("Using npcm SHA engine\n"); + npcm_sha_reset(); + npcm_sha_enable(true); - // Copy Bytes from given buffer to SHA module - for (j = 0; j < len; j++) - writel(hashdigest[j], ®s->hash_dig[j]); + return 0; } -/*----------------------------------------------------------------------------*/ -/* Function: SHA_SetBlock_l */ -/* */ -/* Parameters: data - data to copy */ -/* len - size of data */ -/* position - byte offset into the block at which data */ -/* should be placed */ -/* block - block buffer */ -/* Returns: none */ -/* Side effects: */ -/* Description: This routine load bytes into block buffer */ -/*----------------------------------------------------------------------------*/ -static void SHA_SetBlock_l(const u8 *data, u32 len, u16 position, u32 *block) +int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf, + unsigned int size, int is_last) { - u8 *dest = (u8 *)block; - - memcpy(dest + position, data, len); + return npcm_sha_update(buf, size); } -/*----------------------------------------------------------------------------*/ -/* Function: SHA_SetBlock_l */ -/* */ -/* Parameters: */ -/* len - size of data */ -/* position - byte offset into the block at which data */ -/* should be placed */ -/* block - block buffer */ -/* Returns: none */ -/* Side effects: */ -/* Description: This routine load zero's into the block buffer */ -/*----------------------------------------------------------------------------*/ -static void SHA_ClearBlock_l(u16 len, u16 position, u32 *block) +int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf, + int size) { - u8 *dest = (u8 *)block; + int ret; - memset(dest + position, 0, len); -} + ret = npcm_sha_finish(dest_buf); + npcm_sha_enable(false); -/*----------------------------------------------------------------------------*/ -/* Function: SHA_SetLength32_l */ -/* */ -/* Parameters: */ -/* handlePtr - SHA processing handle pointer */ -/* block - block buffer */ -/* Returns: none */ -/* Side effects: */ -/* Description: This routine set the length of the hash's data */ -/* len is the 32-bit byte length of the message */ -/*lint -efunc(734,SHA_SetLength32_l) Supperess loss of percision lint warning */ -/*----------------------------------------------------------------------------*/ -static void SHA_SetLength32_l(struct SHA_HANDLE_T *handleptr, u32 *block) -{ - u16 *secrunbufferswappedptr = (u16 *)(void *)(block); - - secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 1] = (u16) - ((handleptr->length0 << 3) << 8) | ((u16)(handleptr->length0 << 3) >> 8); - secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 2] = (u16) - ((handleptr->length0 >> (16 - 3)) >> 8) | ((u16)(handleptr->length0 >> (16 - 3)) << 8); - secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 3] = (u16) - ((handleptr->length1 << 3) << 8) | ((u16)(handleptr->length1 << 3) >> 8); - secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 4] = (u16) - ((handleptr->length1 >> (16 - 3)) >> 8) | ((u16)(handleptr->length1 >> (16 - 3)) << 8); + return ret; } static int npcm_sha_bind(struct udevice *dev) @@ -870,12 +347,15 @@ static int npcm_sha_bind(struct udevice *dev) if (!sha_priv) return -ENOMEM; - sha_priv->regs = dev_remap_addr_index(dev, 0); - if (!sha_priv->regs) { + sha_priv->base = dev_read_addr_ptr(dev); + if (!sha_priv->base) { printf("Cannot find sha reg address, binding failed\n"); return -EINVAL; } + if (IS_ENABLED(CONFIG_ARCH_NPCM8XX)) + sha_priv->support_sha512 = true; + printf("SHA: NPCM SHA module bind OK\n"); return 0; diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index 8e11d817a5b..da341a24778 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -11,6 +11,7 @@ #include <asm/io.h> #include <asm/bitops.h> #include <malloc.h> +#include <net.h> #include <linux/bitops.h> #include <linux/dma-mapping.h> #include <linux/sizes.h> @@ -2676,6 +2677,9 @@ int udma_prepare_rcv_buf(struct dma *dma, void *dst, size_t size) cppi5_hdesc_set_pktlen(desc_rx, size); cppi5_hdesc_attach_buf(desc_rx, dma_dst, size, dma_dst, size); + invalidate_dcache_range((unsigned long)dma_dst, + (unsigned long)(dma_dst + size)); + flush_dcache_range((unsigned long)desc_rx, ALIGN((unsigned long)desc_rx + uc->config.hdesc_size, ARCH_DMA_MINALIGN)); diff --git a/drivers/net/ti/am65-cpsw-nuss.c b/drivers/net/ti/am65-cpsw-nuss.c index 335c8bee3fe..c70b42f6bcc 100644 --- a/drivers/net/ti/am65-cpsw-nuss.c +++ b/drivers/net/ti/am65-cpsw-nuss.c @@ -327,6 +327,9 @@ static int am65_cpsw_start(struct udevice *dev) struct ti_udma_drv_chan_cfg_data *dma_rx_cfg_data; int ret, i; + if (common->started) + return 0; + ret = power_domain_on(&common->pwrdmn); if (ret) { dev_err(dev, "power_domain_on() failed %d\n", ret); @@ -358,7 +361,7 @@ static int am65_cpsw_start(struct udevice *dev) UDMA_RX_BUF_SIZE); if (ret) { dev_err(dev, "RX dma add buf failed %d\n", ret); - goto err_free_tx; + goto err_free_rx; } } @@ -487,6 +490,9 @@ static int am65_cpsw_send(struct udevice *dev, void *packet, int length) struct ti_udma_drv_packet_data packet_data; int ret; + if (!common->started) + return -ENETDOWN; + packet_data.pkt_type = AM65_CPSW_CPPI_PKT_TYPE; packet_data.dest_tag = priv->port_id; ret = dma_send(&common->dma_tx, packet, length, &packet_data); @@ -503,6 +509,9 @@ static int am65_cpsw_recv(struct udevice *dev, int flags, uchar **packetp) struct am65_cpsw_priv *priv = dev_get_priv(dev); struct am65_cpsw_common *common = priv->cpsw_common; + if (!common->started) + return -ENETDOWN; + /* try to receive a new packet */ return dma_receive(&common->dma_rx, (void **)packetp, NULL); } diff --git a/drivers/phy/phy-npcm-usb.c b/drivers/phy/phy-npcm-usb.c index 028fedf92dc..2cca0f4a054 100644 --- a/drivers/phy/phy-npcm-usb.c +++ b/drivers/phy/phy-npcm-usb.c @@ -11,6 +11,7 @@ #include <dm/device_compat.h> #include <linux/bitfield.h> #include <linux/delay.h> +#include <dt-bindings/phy/nuvoton,npcm-usbphy.h> /* GCR Register Offsets */ #define GCR_INTCR3 0x9C @@ -31,14 +32,6 @@ #define USBPHY3SW_HOST2 FIELD_PREP(USBPHY3SW, 1) #define USBPHY3SW_DEV8_PHY3 FIELD_PREP(USBPHY3SW, 3) -enum controller_id { - UDC0_7, - UDC8, - UDC9, - USBH1, - USBH2, -}; - enum phy_id { PHY1 = 1, PHY2, @@ -46,13 +39,13 @@ enum phy_id { }; /* Phy Switch Settings */ -#define USBDPHY1 ((PHY1 << 8) | UDC0_7) /* Connect UDC0~7 to PHY1 */ -#define USBD8PHY1 ((PHY1 << 8) | UDC8) /* Connect UDC8 to PHY1 */ -#define USBD9PHY1 ((PHY1 << 8) | UDC9) /* Connect UDC9 to PHY1 */ -#define USBD9PHY2 ((PHY2 << 8) | UDC9) /* Connect UDC9 to PHY2 */ -#define USBH1PHY2 ((PHY2 << 8) | USBH1) /* Connect USBH1 to PHY2 */ -#define USBD8PHY3 ((PHY3 << 8) | UDC8) /* Connect UDC8 to PHY3 */ -#define USBH2PHY3 ((PHY3 << 8) | USBH2) /* Connect USBH2 to PHY3 */ +#define USBDPHY1 ((PHY1 << 8) | NPCM_UDC0_7) /* Connect UDC0~7 to PHY1 */ +#define USBD8PHY1 ((PHY1 << 8) | NPCM_UDC8) /* Connect UDC8 to PHY1 */ +#define USBD9PHY1 ((PHY1 << 8) | NPCM_UDC9) /* Connect UDC9 to PHY1 */ +#define USBD9PHY2 ((PHY2 << 8) | NPCM_UDC9) /* Connect UDC9 to PHY2 */ +#define USBH1PHY2 ((PHY2 << 8) | NPCM_USBH1) /* Connect USBH1 to PHY2 */ +#define USBD8PHY3 ((PHY3 << 8) | NPCM_UDC8) /* Connect UDC8 to PHY3 */ +#define USBH2PHY3 ((PHY3 << 8) | NPCM_USBH2) /* Connect USBH2 to PHY3 */ struct npcm_usbphy { struct regmap *syscon; @@ -152,12 +145,12 @@ static int npcm_usb_phy_exit(struct phy *phy) return 0; } -static int npcm_usb_phy_xlate(struct phy *phy, struct ofnode_phandle_args *args) +static int npcm_usb_phy_xlate(struct phy *phy, struct ofnode_phandle_args *args) { struct npcm_usbphy *priv = dev_get_priv(phy->dev); u16 phy_switch; - if (args->args_count < 1 || args->args[0] > USBH2) + if (args->args_count < 1 || args->args[0] > NPCM_MAX_USB_CTRL_ID) return -EINVAL; phy_switch = (priv->id << 8) | args->args[0]; diff --git a/drivers/pinctrl/pinctrl-uclass.c b/drivers/pinctrl/pinctrl-uclass.c index d9bda7494e2..d9c76898a96 100644 --- a/drivers/pinctrl/pinctrl-uclass.c +++ b/drivers/pinctrl/pinctrl-uclass.c @@ -209,7 +209,7 @@ pinctrl_gpio_get_pinctrl_and_offset(struct udevice *dev, unsigned offset, pfc_base = args.args[1]; pfc_pins = args.args[2]; - if (offset >= gpio_offset && offset <= gpio_offset + pfc_pins) + if (offset >= gpio_offset && offset < gpio_offset + pfc_pins) break; } diff --git a/drivers/remoteproc/ti_k3_dsp_rproc.c b/drivers/remoteproc/ti_k3_dsp_rproc.c index 57fe1037da0..076b6f2acdb 100644 --- a/drivers/remoteproc/ti_k3_dsp_rproc.c +++ b/drivers/remoteproc/ti_k3_dsp_rproc.c @@ -338,7 +338,8 @@ static int k3_dsp_of_get_memories(struct udevice *dev) for (i = 0; i < dsp->num_mems; i++) { /* C71 cores only have a L1P Cache, there are no L1P SRAMs */ if (((device_is_compatible(dev, "ti,j721e-c71-dsp")) || - (device_is_compatible(dev, "ti,j721s2-c71-dsp"))) && + (device_is_compatible(dev, "ti,j721s2-c71-dsp")) || + (device_is_compatible(dev, "ti,am62a-c7xv-dsp"))) && !strcmp(mem_names[i], "l1pram")) { dsp->mem[i].bus_addr = FDT_ADDR_T_NONE; dsp->mem[i].dev_addr = FDT_ADDR_T_NONE; @@ -346,7 +347,14 @@ static int k3_dsp_of_get_memories(struct udevice *dev) dsp->mem[i].size = 0; continue; } - + if (device_is_compatible(dev, "ti,am62a-c7xv-dsp") && + !strcmp(mem_names[i], "l1dram")) { + dsp->mem[i].bus_addr = FDT_ADDR_T_NONE; + dsp->mem[i].dev_addr = FDT_ADDR_T_NONE; + dsp->mem[i].cpu_addr = NULL; + dsp->mem[i].size = 0; + continue; + } dsp->mem[i].bus_addr = dev_read_addr_size_name(dev, mem_names[i], (fdt_addr_t *)&dsp->mem[i].size); if (dsp->mem[i].bus_addr == FDT_ADDR_T_NONE) { @@ -458,6 +466,7 @@ static const struct udevice_id k3_dsp_ids[] = { { .compatible = "ti,j721e-c66-dsp", .data = (ulong)&c66_data, }, { .compatible = "ti,j721e-c71-dsp", .data = (ulong)&c71_data, }, { .compatible = "ti,j721s2-c71-dsp", .data = (ulong)&c71_data, }, + { .compatible = "ti,am62a-c7xv-dsp", .data = (ulong)&c71_data, }, {} }; diff --git a/drivers/remoteproc/ti_k3_r5f_rproc.c b/drivers/remoteproc/ti_k3_r5f_rproc.c index b55b1dc10d4..74bf0433e12 100644 --- a/drivers/remoteproc/ti_k3_r5f_rproc.c +++ b/drivers/remoteproc/ti_k3_r5f_rproc.c @@ -39,6 +39,8 @@ #define PROC_BOOT_CFG_FLAG_GEN_IGN_BOOTVECTOR 0x10000000 /* Available from J7200 SoCs onwards */ #define PROC_BOOT_CFG_FLAG_R5_MEM_INIT_DIS 0x00004000 +#define PROC_BOOT_CFG_FLAG_R5_SINGLE_CORE 0x00008000 + /* R5 TI-SCI Processor Control Flags */ #define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001 @@ -54,6 +56,8 @@ enum cluster_mode { CLUSTER_MODE_SPLIT = 0, CLUSTER_MODE_LOCKSTEP, + CLUSTER_MODE_SINGLECPU, + CLUSTER_MODE_SINGLECORE, }; /** @@ -64,6 +68,7 @@ enum cluster_mode { struct k3_r5f_ip_data { bool tcm_is_double; bool tcm_ecc_autoinit; + bool is_single_core; }; /** @@ -598,8 +603,10 @@ static int k3_r5f_rproc_configure(struct k3_r5f_core *core) /* Sanity check for Lockstep mode */ lockstep_permitted = !!(sts & PROC_BOOT_STATUS_FLAG_R5_LOCKSTEP_PERMITTED); - if (cluster->mode && is_primary_core(core) && !lockstep_permitted) { - dev_err(core->dev, "LockStep mode not permitted on this device\n"); + if (cluster->mode == CLUSTER_MODE_LOCKSTEP && is_primary_core(core) && + !lockstep_permitted) { + dev_err(core->dev, "LockStep mode not permitted on this \ + device\n"); ret = -EINVAL; goto out; } @@ -614,6 +621,9 @@ static int k3_r5f_rproc_configure(struct k3_r5f_core *core) clr_cfg |= PROC_BOOT_CFG_FLAG_R5_LOCKSTEP; } + if (core->ipdata->is_single_core) + set_cfg = PROC_BOOT_CFG_FLAG_R5_SINGLE_CORE; + if (core->atcm_enable) set_cfg |= PROC_BOOT_CFG_FLAG_R5_ATCM_EN; else @@ -852,11 +862,19 @@ static int k3_r5f_remove(struct udevice *dev) static const struct k3_r5f_ip_data k3_data = { .tcm_is_double = false, .tcm_ecc_autoinit = false, + .is_single_core = false, }; static const struct k3_r5f_ip_data j7200_j721s2_data = { .tcm_is_double = true, .tcm_ecc_autoinit = true, + .is_single_core = false, +}; + +static const struct k3_r5f_ip_data am62_data = { + .tcm_is_double = false, + .tcm_ecc_autoinit = false, + .is_single_core = true, }; static const struct udevice_id k3_r5f_rproc_ids[] = { @@ -864,6 +882,7 @@ static const struct udevice_id k3_r5f_rproc_ids[] = { { .compatible = "ti,j721e-r5f", .data = (ulong)&k3_data, }, { .compatible = "ti,j7200-r5f", .data = (ulong)&j7200_j721s2_data, }, { .compatible = "ti,j721s2-r5f", .data = (ulong)&j7200_j721s2_data, }, + { .compatible = "ti,am62-r5f", .data = (ulong)&am62_data, }, {} }; @@ -886,6 +905,11 @@ static int k3_r5f_cluster_probe(struct udevice *dev) cluster->mode = dev_read_u32_default(dev, "ti,cluster-mode", CLUSTER_MODE_LOCKSTEP); + if (device_is_compatible(dev, "ti,am62-r5fss")) { + cluster->mode = CLUSTER_MODE_SINGLECORE; + return 0; + } + if (device_get_child_count(dev) != 2) { dev_err(dev, "Invalid number of R5 cores"); return -EINVAL; @@ -902,6 +926,7 @@ static const struct udevice_id k3_r5fss_ids[] = { { .compatible = "ti,j721e-r5fss"}, { .compatible = "ti,j7200-r5fss"}, { .compatible = "ti,j721s2-r5fss"}, + { .compatible = "ti,am62-r5fss"}, {} }; diff --git a/drivers/usb/dwc3/Kconfig b/drivers/usb/dwc3/Kconfig index c0c8c16fd9c..0100723a68b 100644 --- a/drivers/usb/dwc3/Kconfig +++ b/drivers/usb/dwc3/Kconfig @@ -37,6 +37,20 @@ config SPL_USB_DWC3_GENERIC Select this for Xilinx ZynqMP and similar Platforms. This wrapper supports Host and Peripheral operation modes. +config SPL_USB_DWC3_AM62 + bool "TI AM62 USB wrapper" + depends on SPL_DM_USB && SPL_USB_DWC3_GENERIC && SPL_SYSCON + help + Select this for TI AM62 Platforms. + This wrapper supports Host and Peripheral operation modes. + +config USB_DWC3_AM62 + bool "TI AM62 USB wrapper" + depends on DM_USB && USB_DWC3_GENERIC && SYSCON + help + Select this for TI AM62 Platforms. + This wrapper supports Host and Peripheral operation modes. + config USB_DWC3_MESON_G12A bool "Amlogic Meson G12A USB wrapper" depends on DM_USB && USB_DWC3 && ARCH_MESON diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile index 97b4f7191ca..a46b6824ab7 100644 --- a/drivers/usb/dwc3/Makefile +++ b/drivers/usb/dwc3/Makefile @@ -6,6 +6,7 @@ dwc3-y := core.o obj-$(CONFIG_USB_DWC3_GADGET) += gadget.o ep0.o +obj-$(CONFIG_$(SPL_)USB_DWC3_AM62) += dwc3-am62.o obj-$(CONFIG_USB_DWC3_OMAP) += dwc3-omap.o obj-$(CONFIG_USB_DWC3_MESON_G12A) += dwc3-meson-g12a.o obj-$(CONFIG_USB_DWC3_MESON_GXL) += dwc3-meson-gxl.o diff --git a/drivers/usb/dwc3/dwc3-am62.c b/drivers/usb/dwc3/dwc3-am62.c new file mode 100644 index 00000000000..99519602eb2 --- /dev/null +++ b/drivers/usb/dwc3/dwc3-am62.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * TI AM62 specific glue layer for DWC3 + */ + +#include <dm.h> +#include <dm/device_compat.h> +#include <regmap.h> +#include <syscon.h> +#include <asm/io.h> + +#include "dwc3-generic.h" + +#define USBSS_MODE_CONTROL 0x1c +#define USBSS_PHY_CONFIG 0x8 +#define USBSS_PHY_VBUS_SEL_MASK GENMASK(2, 1) +#define USBSS_PHY_VBUS_SEL_SHIFT 1 +#define USBSS_MODE_VALID BIT(0) +#define PHY_PLL_REFCLK_MASK GENMASK(3, 0) +static const int dwc3_ti_am62_rate_table[] = { /* in KHZ */ + 9600, + 10000, + 12000, + 19200, + 20000, + 24000, + 25000, + 26000, + 38400, + 40000, + 58000, + 50000, + 52000, +}; + +static void dwc3_ti_am62_glue_configure(struct udevice *dev, int index, + enum usb_dr_mode mode) +{ + struct clk usb2_refclk; + int rate_code, i, ret; + unsigned long rate; + u32 reg; + void *usbss; + bool vbus_divider; + struct regmap *syscon; + struct ofnode_phandle_args args; + + usbss = dev_remap_addr_index(dev, 0); + if (IS_ERR(usbss)) { + dev_err(dev, "can't map IOMEM resource\n"); + return; + } + + ret = clk_get_by_name(dev, "ref", &usb2_refclk); + if (ret) { + dev_err(dev, "can't get usb2_refclk\n"); + return; + } + + /* Calculate the rate code */ + rate = clk_get_rate(&usb2_refclk); + rate /= 1000; /* To KHz */ + for (i = 0; i < ARRAY_SIZE(dwc3_ti_am62_rate_table); i++) { + if (dwc3_ti_am62_rate_table[i] == rate) + break; + } + + if (i == ARRAY_SIZE(dwc3_ti_am62_rate_table)) { + dev_err(dev, "unsupported usb2_refclk rate: %lu KHz\n", rate); + return; + } + + rate_code = i; + + /* Read the syscon property */ + syscon = syscon_regmap_lookup_by_phandle(dev, "ti,syscon-phy-pll-refclk"); + if (IS_ERR(syscon)) { + dev_err(dev, "unable to get ti,syscon-phy-pll-refclk regmap\n"); + return; + } + + ret = ofnode_parse_phandle_with_args(dev_ofnode(dev), "ti,syscon-phy-pll-refclk", NULL, 1, + 0, &args); + if (ret) + return; + + /* Program PHY PLL refclk by reading syscon property */ + ret = regmap_update_bits(syscon, args.args[0], PHY_PLL_REFCLK_MASK, rate_code); + if (ret) { + dev_err(dev, "failed to set phy pll reference clock rate\n"); + return; + } + + /* VBUS divider select */ + reg = readl(usbss + USBSS_PHY_CONFIG); + vbus_divider = dev_read_bool(dev, "ti,vbus-divider"); + if (vbus_divider) + reg |= 1 << USBSS_PHY_VBUS_SEL_SHIFT; + + writel(reg, usbss + USBSS_PHY_CONFIG); + + /* Set mode valid */ + reg = readl(usbss + USBSS_MODE_CONTROL); + reg |= USBSS_MODE_VALID; + writel(reg, usbss + USBSS_MODE_CONTROL); +} + +struct dwc3_glue_ops ti_am62_ops = { + .glue_configure = dwc3_ti_am62_glue_configure, +}; + +static const struct udevice_id dwc3_am62_match[] = { + { .compatible = "ti,am62-usb", .data = (ulong)&ti_am62_ops }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(dwc3_am62_wrapper) = { + .name = "dwc3-am62", + .id = UCLASS_SIMPLE_BUS, + .of_match = dwc3_am62_match, + .bind = dwc3_glue_bind, + .probe = dwc3_glue_probe, + .remove = dwc3_glue_remove, + .plat_auto = sizeof(struct dwc3_glue_data), +}; |