summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2021-09-02 09:25:43 -0400
committerTom Rini <[email protected]>2021-09-02 09:25:43 -0400
commit4bb7de1b3c09ada52ec42249221f745a6cbd3360 (patch)
tree9ab48619163e5fe33161a54cb8403438d099ac3c /drivers
parente2e5eec6ce1c2cb496a2a5e019a175a9fbdbed2a (diff)
parent73059529b2046638971aeaa3c75c857458a5ec82 (diff)
Merge branch '2021-09-02-assorted-fixes' into next
- Drop old OpenSSL support - Add DM_HASH support, use it. - Assorted "stemmy" platform updates - Various bugfixes
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/Kconfig7
-rw-r--r--drivers/ata/Makefile2
-rw-r--r--drivers/crypto/Kconfig2
-rw-r--r--drivers/crypto/Makefile1
-rw-r--r--drivers/crypto/hash/Kconfig16
-rw-r--r--drivers/crypto/hash/Makefile6
-rw-r--r--drivers/crypto/hash/hash-uclass.c121
-rw-r--r--drivers/crypto/hash/hash_sw.c301
-rw-r--r--drivers/rtc/ds1307.c69
9 files changed, 511 insertions, 14 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 6f0b7723836..96c7c30375b 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -36,10 +36,17 @@ menu "SATA/SCSI device support"
config AHCI_PCI
bool "Support for PCI-based AHCI controller"
+ depends on DM_PCI
depends on DM_SCSI
help
Enables support for the PCI-based AHCI controller.
+config SPL_AHCI_PCI
+ bool "Support for PCI-based AHCI controller for SPL"
+ depends on SPL
+ depends on SPL_PCI
+ depends on SPL_SATA_SUPPORT && DM_SCSI
+
config SATA_CEVA
bool "Ceva Sata controller"
depends on AHCI
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 4811b2f82c4..cd88131dcd1 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -5,7 +5,7 @@
obj-$(CONFIG_DWC_AHCI) += dwc_ahci.o
obj-$(CONFIG_AHCI) += ahci-uclass.o
-obj-$(CONFIG_AHCI_PCI) += ahci-pci.o
+obj-$(CONFIG_$(SPL_)AHCI_PCI) += ahci-pci.o
obj-$(CONFIG_SCSI_AHCI) += ahci.o
obj-$(CONFIG_DWC_AHSATA) += dwc_ahsata.o
obj-$(CONFIG_FSL_SATA) += fsl_sata.o
diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig
index 1ea116be750..0082177c21f 100644
--- a/drivers/crypto/Kconfig
+++ b/drivers/crypto/Kconfig
@@ -1,5 +1,7 @@
menu "Hardware crypto devices"
+source drivers/crypto/hash/Kconfig
+
source drivers/crypto/fsl/Kconfig
endmenu
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index efbd1d3fca0..4a12b56be6f 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -6,3 +6,4 @@
obj-$(CONFIG_EXYNOS_ACE_SHA) += ace_sha.o
obj-y += rsa_mod_exp/
obj-y += fsl/
+obj-y += hash/
diff --git a/drivers/crypto/hash/Kconfig b/drivers/crypto/hash/Kconfig
new file mode 100644
index 00000000000..cd29a5c6a4f
--- /dev/null
+++ b/drivers/crypto/hash/Kconfig
@@ -0,0 +1,16 @@
+config DM_HASH
+ bool "Enable Driver Model for Hash"
+ depends on DM
+ help
+ If you want to use driver model for Hash, say Y.
+
+config HASH_SOFTWARE
+ bool "Enable driver for Hash in software"
+ depends on DM_HASH
+ depends on MD5
+ depends on SHA1
+ depends on SHA256
+ depends on SHA512_ALGO
+ help
+ Enable driver for hashing operations in software. Currently
+ it support multiple hash algorithm including CRC/MD5/SHA.
diff --git a/drivers/crypto/hash/Makefile b/drivers/crypto/hash/Makefile
new file mode 100644
index 00000000000..33d88161ed4
--- /dev/null
+++ b/drivers/crypto/hash/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (c) 2021 ASPEED Technology Inc.
+
+obj-$(CONFIG_DM_HASH) += hash-uclass.o
+obj-$(CONFIG_HASH_SOFTWARE) += hash_sw.o
diff --git a/drivers/crypto/hash/hash-uclass.c b/drivers/crypto/hash/hash-uclass.c
new file mode 100644
index 00000000000..446eb9e56a4
--- /dev/null
+++ b/drivers/crypto/hash/hash-uclass.c
@@ -0,0 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021 ASPEED Technology Inc.
+ * Author: ChiaWei Wang <[email protected]>
+ */
+
+#define LOG_CATEGORY UCLASS_HASH
+
+#include <common.h>
+#include <dm.h>
+#include <asm/global_data.h>
+#include <u-boot/hash.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <linux/list.h>
+
+struct hash_info {
+ char *name;
+ uint32_t digest_size;
+};
+
+static const struct hash_info hash_info[HASH_ALGO_NUM] = {
+ [HASH_ALGO_CRC16_CCITT] = { "crc16-ccitt", 2 },
+ [HASH_ALGO_CRC32] = { "crc32", 4 },
+ [HASH_ALGO_MD5] = { "md5", 16 },
+ [HASH_ALGO_SHA1] = { "sha1", 20 },
+ [HASH_ALGO_SHA256] = { "sha256", 32 },
+ [HASH_ALGO_SHA384] = { "sha384", 48 },
+ [HASH_ALGO_SHA512] = { "sha512", 64},
+};
+
+enum HASH_ALGO hash_algo_lookup_by_name(const char *name)
+{
+ int i;
+
+ if (!name)
+ return HASH_ALGO_INVALID;
+
+ for (i = 0; i < HASH_ALGO_NUM; ++i)
+ if (!strcmp(name, hash_info[i].name))
+ return i;
+
+ return HASH_ALGO_INVALID;
+}
+
+ssize_t hash_algo_digest_size(enum HASH_ALGO algo)
+{
+ if (algo >= HASH_ALGO_NUM)
+ return -EINVAL;
+
+ return hash_info[algo].digest_size;
+}
+
+const char *hash_algo_name(enum HASH_ALGO algo)
+{
+ if (algo >= HASH_ALGO_NUM)
+ return NULL;
+
+ return hash_info[algo].name;
+}
+
+int hash_digest(struct udevice *dev, enum HASH_ALGO algo,
+ const void *ibuf, const uint32_t ilen,
+ void *obuf)
+{
+ struct hash_ops *ops = (struct hash_ops *)device_get_ops(dev);
+
+ if (!ops->hash_digest)
+ return -ENOSYS;
+
+ return ops->hash_digest(dev, algo, ibuf, ilen, obuf);
+}
+
+int hash_digest_wd(struct udevice *dev, enum HASH_ALGO algo,
+ const void *ibuf, const uint32_t ilen,
+ void *obuf, uint32_t chunk_sz)
+{
+ struct hash_ops *ops = (struct hash_ops *)device_get_ops(dev);
+
+ if (!ops->hash_digest_wd)
+ return -ENOSYS;
+
+ return ops->hash_digest_wd(dev, algo, ibuf, ilen, obuf, chunk_sz);
+}
+
+int hash_init(struct udevice *dev, enum HASH_ALGO algo, void **ctxp)
+{
+ struct hash_ops *ops = (struct hash_ops *)device_get_ops(dev);
+
+ if (!ops->hash_init)
+ return -ENOSYS;
+
+ return ops->hash_init(dev, algo, ctxp);
+}
+
+int hash_update(struct udevice *dev, void *ctx, const void *ibuf, const uint32_t ilen)
+{
+ struct hash_ops *ops = (struct hash_ops *)device_get_ops(dev);
+
+ if (!ops->hash_update)
+ return -ENOSYS;
+
+ return ops->hash_update(dev, ctx, ibuf, ilen);
+}
+
+int hash_finish(struct udevice *dev, void *ctx, void *obuf)
+{
+ struct hash_ops *ops = (struct hash_ops *)device_get_ops(dev);
+
+ if (!ops->hash_finish)
+ return -ENOSYS;
+
+ return ops->hash_finish(dev, ctx, obuf);
+}
+
+UCLASS_DRIVER(hash) = {
+ .id = UCLASS_HASH,
+ .name = "hash",
+};
diff --git a/drivers/crypto/hash/hash_sw.c b/drivers/crypto/hash/hash_sw.c
new file mode 100644
index 00000000000..fea9d126096
--- /dev/null
+++ b/drivers/crypto/hash/hash_sw.c
@@ -0,0 +1,301 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021 ASPEED Technology Inc.
+ * Author: ChiaWei Wang <[email protected]>
+ */
+#include <config.h>
+#include <common.h>
+#include <dm.h>
+#include <log.h>
+#include <malloc.h>
+#include <watchdog.h>
+#include <u-boot/hash.h>
+#include <u-boot/crc.h>
+#include <u-boot/md5.h>
+#include <u-boot/sha1.h>
+#include <u-boot/sha256.h>
+#include <u-boot/sha512.h>
+
+/* CRC16-CCITT */
+static void hash_init_crc16_ccitt(void *ctx)
+{
+ *((uint16_t *)ctx) = 0;
+}
+
+static void hash_update_crc16_ccitt(void *ctx, const void *ibuf, uint32_t ilen)
+{
+ *((uint16_t *)ctx) = crc16_ccitt(*((uint16_t *)ctx), ibuf, ilen);
+}
+
+static void hash_finish_crc16_ccitt(void *ctx, void *obuf)
+{
+ *((uint16_t *)obuf) = *((uint16_t *)ctx);
+}
+
+/* CRC32 */
+static void hash_init_crc32(void *ctx)
+{
+ *((uint32_t *)ctx) = 0;
+}
+
+static void hash_update_crc32(void *ctx, const void *ibuf, uint32_t ilen)
+{
+ *((uint32_t *)ctx) = crc32(*((uint32_t *)ctx), ibuf, ilen);
+}
+
+static void hash_finish_crc32(void *ctx, void *obuf)
+{
+ *((uint32_t *)obuf) = *((uint32_t *)ctx);
+}
+
+/* MD5 */
+static void hash_init_md5(void *ctx)
+{
+ MD5Init((struct MD5Context *)ctx);
+}
+
+static void hash_update_md5(void *ctx, const void *ibuf, uint32_t ilen)
+{
+ MD5Update((struct MD5Context *)ctx, ibuf, ilen);
+}
+
+static void hash_finish_md5(void *ctx, void *obuf)
+{
+ MD5Final(obuf, (struct MD5Context *)ctx);
+}
+
+/* SHA1 */
+static void hash_init_sha1(void *ctx)
+{
+ sha1_starts((sha1_context *)ctx);
+}
+
+static void hash_update_sha1(void *ctx, const void *ibuf, uint32_t ilen)
+{
+ sha1_update((sha1_context *)ctx, ibuf, ilen);
+}
+
+static void hash_finish_sha1(void *ctx, void *obuf)
+{
+ sha1_finish((sha1_context *)ctx, obuf);
+}
+
+/* SHA256 */
+static void hash_init_sha256(void *ctx)
+{
+ sha256_starts((sha256_context *)ctx);
+}
+
+static void hash_update_sha256(void *ctx, const void *ibuf, uint32_t ilen)
+{
+ sha256_update((sha256_context *)ctx, ibuf, ilen);
+}
+
+static void hash_finish_sha256(void *ctx, void *obuf)
+{
+ sha256_finish((sha256_context *)ctx, obuf);
+}
+
+/* SHA384 */
+static void hash_init_sha384(void *ctx)
+{
+ sha384_starts((sha512_context *)ctx);
+}
+
+static void hash_update_sha384(void *ctx, const void *ibuf, uint32_t ilen)
+{
+ sha384_update((sha512_context *)ctx, ibuf, ilen);
+}
+
+static void hash_finish_sha384(void *ctx, void *obuf)
+{
+ sha384_finish((sha512_context *)ctx, obuf);
+}
+
+/* SHA512 */
+static void hash_init_sha512(void *ctx)
+{
+ sha512_starts((sha512_context *)ctx);
+}
+
+static void hash_update_sha512(void *ctx, const void *ibuf, uint32_t ilen)
+{
+ sha512_update((sha512_context *)ctx, ibuf, ilen);
+}
+
+static void hash_finish_sha512(void *ctx, void *obuf)
+{
+ sha512_finish((sha512_context *)ctx, obuf);
+}
+
+struct sw_hash_ctx {
+ enum HASH_ALGO algo;
+ uint8_t algo_ctx[];
+};
+
+struct sw_hash_impl {
+ void (*init)(void *ctx);
+ void (*update)(void *ctx, const void *ibuf, uint32_t ilen);
+ void (*finish)(void *ctx, void *obuf);
+ uint32_t ctx_alloc_sz;
+};
+
+static struct sw_hash_impl sw_hash_impl[HASH_ALGO_NUM] = {
+ [HASH_ALGO_CRC16_CCITT] = {
+ .init = hash_init_crc16_ccitt,
+ .update = hash_update_crc16_ccitt,
+ .finish = hash_finish_crc16_ccitt,
+ .ctx_alloc_sz = sizeof(uint16_t),
+ },
+
+ [HASH_ALGO_CRC32] = {
+ .init = hash_init_crc32,
+ .update = hash_update_crc32,
+ .finish = hash_finish_crc32,
+ .ctx_alloc_sz = sizeof(uint32_t),
+ },
+
+ [HASH_ALGO_MD5] = {
+ .init = hash_init_md5,
+ .update = hash_update_md5,
+ .finish = hash_finish_md5,
+ .ctx_alloc_sz = sizeof(struct MD5Context),
+ },
+
+ [HASH_ALGO_SHA1] = {
+ .init = hash_init_sha1,
+ .update = hash_update_sha1,
+ .finish = hash_finish_sha1,
+ .ctx_alloc_sz = sizeof(sha1_context),
+ },
+
+ [HASH_ALGO_SHA256] = {
+ .init = hash_init_sha256,
+ .update = hash_update_sha256,
+ .finish = hash_finish_sha256,
+ .ctx_alloc_sz = sizeof(sha256_context),
+ },
+
+ [HASH_ALGO_SHA384] = {
+ .init = hash_init_sha384,
+ .update = hash_update_sha384,
+ .finish = hash_finish_sha384,
+ .ctx_alloc_sz = sizeof(sha512_context),
+ },
+
+ [HASH_ALGO_SHA512] = {
+ .init = hash_init_sha512,
+ .update = hash_update_sha512,
+ .finish = hash_finish_sha512,
+ .ctx_alloc_sz = sizeof(sha512_context),
+ },
+};
+
+static int sw_hash_init(struct udevice *dev, enum HASH_ALGO algo, void **ctxp)
+{
+ struct sw_hash_ctx *hash_ctx;
+ struct sw_hash_impl *hash_impl = &sw_hash_impl[algo];
+
+ hash_ctx = malloc(sizeof(hash_ctx->algo) + hash_impl->ctx_alloc_sz);
+ if (!hash_ctx)
+ return -ENOMEM;
+
+ hash_ctx->algo = algo;
+
+ hash_impl->init(hash_ctx->algo_ctx);
+
+ *ctxp = hash_ctx;
+
+ return 0;
+}
+
+static int sw_hash_update(struct udevice *dev, void *ctx, const void *ibuf, uint32_t ilen)
+{
+ struct sw_hash_ctx *hash_ctx = ctx;
+ struct sw_hash_impl *hash_impl = &sw_hash_impl[hash_ctx->algo];
+
+ hash_impl->update(hash_ctx->algo_ctx, ibuf, ilen);
+
+ return 0;
+}
+
+static int sw_hash_finish(struct udevice *dev, void *ctx, void *obuf)
+{
+ struct sw_hash_ctx *hash_ctx = ctx;
+ struct sw_hash_impl *hash_impl = &sw_hash_impl[hash_ctx->algo];
+
+ hash_impl->finish(hash_ctx->algo_ctx, obuf);
+
+ free(ctx);
+
+ return 0;
+}
+
+static int sw_hash_digest_wd(struct udevice *dev, enum HASH_ALGO algo,
+ const void *ibuf, const uint32_t ilen,
+ void *obuf, uint32_t chunk_sz)
+{
+ int rc;
+ void *ctx;
+ const void *cur, *end;
+ uint32_t chunk;
+
+ rc = sw_hash_init(dev, algo, &ctx);
+ if (rc)
+ return rc;
+
+ if (CONFIG_IS_ENABLED(HW_WATCHDOG) || CONFIG_IS_ENABLED(WATCHDOG)) {
+ cur = ibuf;
+ end = ibuf + ilen;
+
+ while (cur < end) {
+ chunk = end - cur;
+ if (chunk > chunk_sz)
+ chunk = chunk_sz;
+
+ rc = sw_hash_update(dev, ctx, cur, chunk);
+ if (rc)
+ return rc;
+
+ cur += chunk;
+ WATCHDOG_RESET();
+ }
+ } else {
+ rc = sw_hash_update(dev, ctx, ibuf, ilen);
+ if (rc)
+ return rc;
+ }
+
+ rc = sw_hash_finish(dev, ctx, obuf);
+ if (rc)
+ return rc;
+
+ return 0;
+}
+
+static int sw_hash_digest(struct udevice *dev, enum HASH_ALGO algo,
+ const void *ibuf, const uint32_t ilen,
+ void *obuf)
+{
+ /* re-use the watchdog version with input length as the chunk_sz */
+ return sw_hash_digest_wd(dev, algo, ibuf, ilen, obuf, ilen);
+}
+
+static const struct hash_ops hash_ops_sw = {
+ .hash_init = sw_hash_init,
+ .hash_update = sw_hash_update,
+ .hash_finish = sw_hash_finish,
+ .hash_digest_wd = sw_hash_digest_wd,
+ .hash_digest = sw_hash_digest,
+};
+
+U_BOOT_DRIVER(hash_sw) = {
+ .name = "hash_sw",
+ .id = UCLASS_HASH,
+ .ops = &hash_ops_sw,
+ .flags = DM_FLAG_PRE_RELOC,
+};
+
+U_BOOT_DRVINFO(hash_sw) = {
+ .name = "hash_sw",
+};
diff --git a/drivers/rtc/ds1307.c b/drivers/rtc/ds1307.c
index 2015ce9bbcd..3be97c9d933 100644
--- a/drivers/rtc/ds1307.c
+++ b/drivers/rtc/ds1307.c
@@ -43,11 +43,21 @@ enum ds_type {
#define RTC_SEC_BIT_CH 0x80 /* Clock Halt (in Register 0) */
+/* DS1307-specific bits */
#define RTC_CTL_BIT_RS0 0x01 /* Rate select 0 */
#define RTC_CTL_BIT_RS1 0x02 /* Rate select 1 */
#define RTC_CTL_BIT_SQWE 0x10 /* Square Wave Enable */
#define RTC_CTL_BIT_OUT 0x80 /* Output Control */
+/* DS1337-specific bits */
+#define DS1337_CTL_BIT_RS1 0x08 /* Rate select 1 */
+#define DS1337_CTL_BIT_RS2 0x10 /* Rate select 2 */
+#define DS1337_CTL_BIT_EOSC 0x80 /* Enable Oscillator */
+
+/* DS1340-specific bits */
+#define DS1340_SEC_BIT_EOSC 0x80 /* Enable Oscillator */
+#define DS1340_CTL_BIT_OUT 0x80 /* Output Control */
+
/* MCP7941X-specific bits */
#define MCP7941X_BIT_ST 0x80
#define MCP7941X_BIT_VBATEN 0x08
@@ -261,9 +271,25 @@ read_rtc:
buf[RTC_SEC_REG_ADDR]);
return -1;
}
- }
-
- if (type == m41t11) {
+ } else if (type == ds_1337) {
+ if (buf[RTC_CTL_REG_ADDR] & DS1337_CTL_BIT_EOSC) {
+ printf("### Warning: RTC oscillator has stopped\n");
+ /* clear the not oscillator enable (~EOSC) flag */
+ buf[RTC_CTL_REG_ADDR] &= ~DS1337_CTL_BIT_EOSC;
+ dm_i2c_reg_write(dev, RTC_CTL_REG_ADDR,
+ buf[RTC_CTL_REG_ADDR]);
+ return -1;
+ }
+ } else if (type == ds_1340) {
+ if (buf[RTC_SEC_REG_ADDR] & DS1340_SEC_BIT_EOSC) {
+ printf("### Warning: RTC oscillator has stopped\n");
+ /* clear the not oscillator enable (~EOSC) flag */
+ buf[RTC_SEC_REG_ADDR] &= ~DS1340_SEC_BIT_EOSC;
+ dm_i2c_reg_write(dev, RTC_SEC_REG_ADDR,
+ buf[RTC_SEC_REG_ADDR]);
+ return -1;
+ }
+ } else if (type == m41t11) {
/* clock halted? turn it on, so clock can tick. */
if (buf[RTC_SEC_REG_ADDR] & RTC_SEC_BIT_CH) {
buf[RTC_SEC_REG_ADDR] &= ~RTC_SEC_BIT_CH;
@@ -273,9 +299,7 @@ read_rtc:
buf[RTC_SEC_REG_ADDR]);
goto read_rtc;
}
- }
-
- if (type == mcp794xx) {
+ } else if (type == mcp794xx) {
/* make sure that the backup battery is enabled */
if (!(buf[RTC_DAY_REG_ADDR] & MCP7941X_BIT_VBATEN)) {
dm_i2c_reg_write(dev, RTC_DAY_REG_ADDR,
@@ -314,18 +338,37 @@ read_rtc:
static int ds1307_rtc_reset(struct udevice *dev)
{
int ret;
+ enum ds_type type = dev_get_driver_data(dev);
- /* clear Clock Halt */
+ /*
+ * reset clock/oscillator in the seconds register:
+ * on DS1307 bit 7 enables Clock Halt (CH),
+ * on DS1340 bit 7 disables the oscillator (not EOSC)
+ * on MCP794xx bit 7 enables Start Oscillator (ST)
+ */
ret = dm_i2c_reg_write(dev, RTC_SEC_REG_ADDR, 0x00);
if (ret < 0)
return ret;
- ret = dm_i2c_reg_write(dev, RTC_CTL_REG_ADDR,
- RTC_CTL_BIT_SQWE | RTC_CTL_BIT_RS1 |
- RTC_CTL_BIT_RS0);
- if (ret < 0)
- return ret;
- return 0;
+ if (type == ds_1307) {
+ /* Write control register in order to enable square-wave
+ * output (SQWE) and set a default rate of 32.768kHz (RS1|RS0).
+ */
+ ret = dm_i2c_reg_write(dev, RTC_CTL_REG_ADDR,
+ RTC_CTL_BIT_SQWE | RTC_CTL_BIT_RS1 |
+ RTC_CTL_BIT_RS0);
+ } else if (type == ds_1337) {
+ /* Write control register in order to enable oscillator output
+ * (not EOSC) and set a default rate of 32.768kHz (RS2|RS1).
+ */
+ ret = dm_i2c_reg_write(dev, RTC_CTL_REG_ADDR,
+ DS1337_CTL_BIT_RS2 | DS1337_CTL_BIT_RS1);
+ } else if (type == ds_1340 || type == mcp794xx || type == m41t11) {
+ /* Reset clock calibration, frequency test and output level. */
+ ret = dm_i2c_reg_write(dev, RTC_CTL_REG_ADDR, 0x00);
+ }
+
+ return ret;
}
static int ds1307_probe(struct udevice *dev)