summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/crypto/fsl/Makefile2
-rw-r--r--drivers/crypto/fsl/desc.h15
-rw-r--r--drivers/crypto/fsl/fsl_blob.c52
-rw-r--r--drivers/crypto/fsl/jobdesc.c149
-rw-r--r--drivers/crypto/fsl/jobdesc.h14
-rw-r--r--drivers/crypto/fsl/jr.c31
-rw-r--r--drivers/gpio/Makefile4
-rw-r--r--drivers/gpio/tegra_gpio.c27
-rw-r--r--drivers/mmc/fsl_esdhc.c33
-rw-r--r--drivers/mtd/nand/omap_gpmc.c28
-rw-r--r--drivers/net/designware.c9
-rw-r--r--drivers/net/designware.h4
-rw-r--r--drivers/video/am335x-fb.c13
-rw-r--r--drivers/video/am335x-fb.h9
14 files changed, 349 insertions, 41 deletions
diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile
index c0cf64229e..4aa91e4393 100644
--- a/drivers/crypto/fsl/Makefile
+++ b/drivers/crypto/fsl/Makefile
@@ -8,5 +8,5 @@
obj-y += sec.o
obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
-obj-$(CONFIG_CMD_BLOB) += fsl_blob.o
+obj-$(CONFIG_CMD_BLOB)$(CONFIG_CMD_DEKBLOB) += fsl_blob.o
obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
diff --git a/drivers/crypto/fsl/desc.h b/drivers/crypto/fsl/desc.h
index 504f2b07d0..18e2ec8d26 100644
--- a/drivers/crypto/fsl/desc.h
+++ b/drivers/crypto/fsl/desc.h
@@ -12,11 +12,18 @@
#ifndef DESC_H
#define DESC_H
+#define KEY_BLOB_SIZE 32
+#define MAC_SIZE 16
+
/* Max size of any CAAM descriptor in 32-bit words, inclusive of header */
#define MAX_CAAM_DESCSIZE 64
+/* Size of DEK Blob descriptor, inclusive of header */
+#define DEK_BLOB_DESCSIZE 9
+
/* Block size of any entity covered/uncovered with a KEK/TKEK */
#define KEK_BLOCKSIZE 16
+
/*
* Supported descriptor command types as they show up
* inside a descriptor command word.
@@ -273,6 +280,13 @@
#define LDLEN_SET_OFIFO_OFFSET_MASK (3 << LDLEN_SET_OFIFO_OFFSET_SHIFT)
/*
+ * AAD Definitions
+ */
+#define AES_KEY_SHIFT 8
+#define LD_CCM_MODE 0x66
+#define KEY_AES_SRC (0x55 << AES_KEY_SHIFT)
+
+/*
* FIFO_LOAD/FIFO_STORE/SEQ_FIFO_LOAD/SEQ_FIFO_STORE
* Command Constructs
*/
@@ -418,6 +432,7 @@
#define OP_PCLID_MASK (0xff << 16)
/* Assuming OP_TYPE = OP_TYPE_UNI_PROTOCOL */
+#define OP_PCLID_SECMEM 0x08
#define OP_PCLID_BLOB (0x0d << OP_PCLID_SHIFT)
#define OP_PCLID_SECRETKEY (0x11 << OP_PCLID_SHIFT)
#define OP_PCLID_PUBLICKEYPAIR (0x14 << OP_PCLID_SHIFT)
diff --git a/drivers/crypto/fsl/fsl_blob.c b/drivers/crypto/fsl/fsl_blob.c
index 9923bcbfe9..8b25921272 100644
--- a/drivers/crypto/fsl/fsl_blob.c
+++ b/drivers/crypto/fsl/fsl_blob.c
@@ -7,6 +7,8 @@
#include <common.h>
#include <malloc.h>
+#include <fsl_sec.h>
+#include <asm-generic/errno.h>
#include "jobdesc.h"
#include "desc.h"
#include "jr.h"
@@ -59,3 +61,53 @@ int blob_encap(u8 *key_mod, u8 *src, u8 *dst, u32 len)
free(desc);
return ret;
}
+
+#ifdef CONFIG_CMD_DEKBLOB
+int blob_dek(const u8 *src, u8 *dst, u8 len)
+{
+ int ret, size, i = 0;
+ u32 *desc;
+
+ int out_sz = WRP_HDR_SIZE + len + KEY_BLOB_SIZE + MAC_SIZE;
+
+ puts("\nEncapsulating provided DEK to form blob\n");
+ desc = memalign(ARCH_DMA_MINALIGN,
+ sizeof(uint32_t) * DEK_BLOB_DESCSIZE);
+ if (!desc) {
+ debug("Not enough memory for descriptor allocation\n");
+ return -ENOMEM;
+ }
+
+ ret = inline_cnstr_jobdesc_blob_dek(desc, src, dst, len);
+ if (ret) {
+ debug("Error in Job Descriptor Construction: %d\n", ret);
+ } else {
+ size = roundup(sizeof(uint32_t) * DEK_BLOB_DESCSIZE,
+ ARCH_DMA_MINALIGN);
+ flush_dcache_range((unsigned long)desc,
+ (unsigned long)desc + size);
+ size = roundup(sizeof(uint8_t) * out_sz, ARCH_DMA_MINALIGN);
+ flush_dcache_range((unsigned long)dst,
+ (unsigned long)dst + size);
+
+ ret = run_descriptor_jr(desc);
+ }
+
+ if (ret) {
+ debug("Error in Encapsulation %d\n", ret);
+ goto err;
+ }
+
+ size = roundup(out_sz, ARCH_DMA_MINALIGN);
+ invalidate_dcache_range((unsigned long)dst, (unsigned long)dst+size);
+
+ puts("DEK Blob\n");
+ for (i = 0; i < out_sz; i++)
+ printf("%02X", ((uint8_t *)dst)[i]);
+ printf("\n");
+
+err:
+ free(desc);
+ return ret;
+}
+#endif
diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c
index cc0dcede7b..5695bef6fd 100644
--- a/drivers/crypto/fsl/jobdesc.c
+++ b/drivers/crypto/fsl/jobdesc.c
@@ -9,12 +9,157 @@
*/
#include <common.h>
+#include <fsl_sec.h>
#include "desc_constr.h"
#include "jobdesc.h"
#include "rsa_caam.h"
-#define KEY_BLOB_SIZE 32
-#define MAC_SIZE 16
+#ifdef CONFIG_MX6
+/*!
+ * Secure memory run command
+ *
+ * @param sec_mem_cmd Secure memory command register
+ * @return cmd_status Secure memory command status register
+ */
+uint32_t secmem_set_cmd(uint32_t sec_mem_cmd)
+{
+ uint32_t temp_reg;
+
+ sec_out32(CAAM_SMCJR0, sec_mem_cmd);
+
+ do {
+ temp_reg = sec_in32(CAAM_SMCSJR0);
+ } while (temp_reg & CMD_COMPLETE);
+
+ return temp_reg;
+}
+
+/*!
+ * CAAM page allocation:
+ * Allocates a partition from secure memory, with the id
+ * equal to partion_num. This will de-allocate the page
+ * if it is already allocated. The partition will have
+ * full access permissions. The permissions are set before,
+ * running a job descriptor. A memory page of secure RAM
+ * is allocated for the partition.
+ *
+ * @param page Number of the page to allocate.
+ * @param partition Number of the partition to allocate.
+ * @return 0 on success, ERROR_IN_PAGE_ALLOC otherwise
+ */
+int caam_page_alloc(uint8_t page_num, uint8_t partition_num)
+{
+ uint32_t temp_reg;
+
+ /*
+ * De-Allocate partition_num if already allocated to ARM core
+ */
+ if (sec_in32(CAAM_SMPO_0) & PARTITION_OWNER(partition_num)) {
+ temp_reg = secmem_set_cmd(PARTITION(partition_num) |
+ CMD_PART_DEALLOC);
+ if (temp_reg & SMCSJR_AERR) {
+ printf("Error: De-allocation status 0x%X\n", temp_reg);
+ return ERROR_IN_PAGE_ALLOC;
+ }
+ }
+
+ /* set the access rights to allow full access */
+ sec_out32(CAAM_SMAG1JR0(partition_num), 0xF);
+ sec_out32(CAAM_SMAG2JR0(partition_num), 0xF);
+ sec_out32(CAAM_SMAPJR0(partition_num), 0xFF);
+
+ /* Now need to allocate partition_num of secure RAM. */
+ /* De-Allocate page_num by starting with a page inquiry command */
+ temp_reg = secmem_set_cmd(PAGE(page_num) | CMD_INQUIRY);
+
+ /* if the page is owned, de-allocate it */
+ if ((temp_reg & SMCSJR_PO) == PAGE_OWNED) {
+ temp_reg = secmem_set_cmd(PAGE(page_num) | CMD_PAGE_DEALLOC);
+ if (temp_reg & SMCSJR_AERR) {
+ printf("Error: Allocation status 0x%X\n", temp_reg);
+ return ERROR_IN_PAGE_ALLOC;
+ }
+ }
+
+ /* Allocate page_num to partition_num */
+ temp_reg = secmem_set_cmd(PAGE(page_num) | PARTITION(partition_num)
+ | CMD_PAGE_ALLOC);
+ if (temp_reg & SMCSJR_AERR) {
+ printf("Error: Allocation status 0x%X\n", temp_reg);
+ return ERROR_IN_PAGE_ALLOC;
+ }
+ /* page inquiry command to ensure that the page was allocated */
+ temp_reg = secmem_set_cmd(PAGE(page_num) | CMD_INQUIRY);
+
+ /* if the page is not owned => problem */
+ if ((temp_reg & SMCSJR_PO) != PAGE_OWNED) {
+ printf("Allocation of page %d in partition %d failed 0x%X\n",
+ temp_reg, page_num, partition_num);
+
+ return ERROR_IN_PAGE_ALLOC;
+ }
+
+ return 0;
+}
+
+int inline_cnstr_jobdesc_blob_dek(uint32_t *desc, const uint8_t *plain_txt,
+ uint8_t *dek_blob, uint32_t in_sz)
+{
+ uint32_t ret = 0;
+ u32 aad_w1, aad_w2;
+ /* output blob will have 32 bytes key blob in beginning and
+ * 16 byte HMAC identifier at end of data blob */
+ uint32_t out_sz = in_sz + KEY_BLOB_SIZE + MAC_SIZE;
+ /* Setting HDR for blob */
+ uint8_t wrapped_key_hdr[8] = {HDR_TAG, 0x00, WRP_HDR_SIZE + out_sz,
+ HDR_PAR, HAB_MOD, HAB_ALG, in_sz, HAB_FLG};
+
+ /* initialize the blob array */
+ memset(dek_blob, 0, out_sz + 8);
+ /* Copy the header into the DEK blob buffer */
+ memcpy(dek_blob, wrapped_key_hdr, sizeof(wrapped_key_hdr));
+
+ /* allocating secure memory */
+ ret = caam_page_alloc(PAGE_1, PARTITION_1);
+ if (ret)
+ return ret;
+
+ /* Write DEK to secure memory */
+ memcpy((uint32_t *)SEC_MEM_PAGE1, (uint32_t *)plain_txt, in_sz);
+
+ unsigned long start = (unsigned long)SEC_MEM_PAGE1 &
+ ~(ARCH_DMA_MINALIGN - 1);
+ unsigned long end = ALIGN(start + 0x1000, ARCH_DMA_MINALIGN);
+ flush_dcache_range(start, end);
+
+ /* Now configure the access rights of the partition */
+ sec_out32(CAAM_SMAG1JR0(PARTITION_1), KS_G1); /* set group 1 */
+ sec_out32(CAAM_SMAG2JR0(PARTITION_1), 0); /* clear group 2 */
+ sec_out32(CAAM_SMAPJR0(PARTITION_1), PERM); /* set perm & locks */
+
+ /* construct aad for AES */
+ aad_w1 = (in_sz << OP_ALG_ALGSEL_SHIFT) | KEY_AES_SRC | LD_CCM_MODE;
+ aad_w2 = 0x0;
+
+ init_job_desc(desc, 0);
+
+ append_cmd(desc, CMD_LOAD | CLASS_2 | KEY_IMM | KEY_ENC |
+ (0x0c << LDST_OFFSET_SHIFT) | 0x08);
+
+ append_u32(desc, aad_w1);
+
+ append_u32(desc, aad_w2);
+
+ append_cmd_ptr(desc, (dma_addr_t)SEC_MEM_PAGE1, in_sz, CMD_SEQ_IN_PTR);
+
+ append_cmd_ptr(desc, (dma_addr_t)dek_blob + 8, out_sz, CMD_SEQ_OUT_PTR);
+
+ append_operation(desc, OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB |
+ OP_PCLID_SECMEM);
+
+ return ret;
+}
+#endif
void inline_cnstr_jobdesc_hash(uint32_t *desc,
const uint8_t *msg, uint32_t msgsz, uint8_t *digest,
diff --git a/drivers/crypto/fsl/jobdesc.h b/drivers/crypto/fsl/jobdesc.h
index 84b3edd6e2..112404c74d 100644
--- a/drivers/crypto/fsl/jobdesc.h
+++ b/drivers/crypto/fsl/jobdesc.h
@@ -14,6 +14,20 @@
#define KEY_IDNFR_SZ_BYTES 16
+#ifdef CONFIG_CMD_DEKBLOB
+/* inline_cnstr_jobdesc_blob_dek:
+ * Intializes and constructs the job descriptor for DEK encapsulation
+ * using the given parameters.
+ * @desc: reference to the job descriptor
+ * @plain_txt: reference to the DEK
+ * @enc_blob: reference where to store the blob
+ * @in_sz: size in bytes of the DEK
+ * @return: 0 on success, ECONSTRJDESC otherwise
+ */
+int inline_cnstr_jobdesc_blob_dek(uint32_t *desc, const uint8_t *plain_txt,
+ uint8_t *enc_blob, uint32_t in_sz);
+#endif
+
void inline_cnstr_jobdesc_hash(uint32_t *desc,
const uint8_t *msg, uint32_t msgsz, uint8_t *digest,
u32 alg_type, uint32_t alg_size, int sg_tbl);
diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c
index f9d4938834..f99d59480c 100644
--- a/drivers/crypto/fsl/jr.c
+++ b/drivers/crypto/fsl/jr.c
@@ -90,11 +90,13 @@ static int jr_init(void)
jr.liodn = DEFAULT_JR_LIODN;
#endif
jr.size = JR_SIZE;
- jr.input_ring = (dma_addr_t *)malloc(JR_SIZE * sizeof(dma_addr_t));
+ jr.input_ring = (dma_addr_t *)memalign(ARCH_DMA_MINALIGN,
+ JR_SIZE * sizeof(dma_addr_t));
if (!jr.input_ring)
return -1;
jr.output_ring =
- (struct op_ring *)malloc(JR_SIZE * sizeof(struct op_ring));
+ (struct op_ring *)memalign(ARCH_DMA_MINALIGN,
+ JR_SIZE * sizeof(struct op_ring));
if (!jr.output_ring)
return -1;
@@ -163,13 +165,23 @@ static int jr_enqueue(uint32_t *desc_addr,
CIRC_SPACE(jr.head, jr.tail, jr.size) <= 0)
return -1;
- jr.input_ring[head] = desc_phys_addr;
jr.info[head].desc_phys_addr = desc_phys_addr;
jr.info[head].desc_addr = (uint32_t)desc_addr;
jr.info[head].callback = (void *)callback;
jr.info[head].arg = arg;
jr.info[head].op_done = 0;
+ unsigned long start = (unsigned long)&jr.info[head] &
+ ~(ARCH_DMA_MINALIGN - 1);
+ unsigned long end = ALIGN(start + sizeof(struct jr_info),
+ ARCH_DMA_MINALIGN);
+ flush_dcache_range(start, end);
+
+ jr.input_ring[head] = desc_phys_addr;
+ start = (unsigned long)&jr.input_ring[head] & ~(ARCH_DMA_MINALIGN - 1);
+ end = ALIGN(start + sizeof(dma_addr_t), ARCH_DMA_MINALIGN);
+ flush_dcache_range(start, end);
+
jr.head = (head + 1) & (jr.size - 1);
sec_out32(&regs->irja, 1);
@@ -187,6 +199,13 @@ static int jr_dequeue(void)
void *arg = NULL;
while (sec_in32(&regs->orsf) && CIRC_CNT(jr.head, jr.tail, jr.size)) {
+ unsigned long start = (unsigned long)jr.output_ring &
+ ~(ARCH_DMA_MINALIGN - 1);
+ unsigned long end = ALIGN(start +
+ sizeof(struct op_ring)*JR_SIZE,
+ ARCH_DMA_MINALIGN);
+ invalidate_dcache_range(start, end);
+
found = 0;
dma_addr_t op_desc = jr.output_ring[jr.tail].desc;
@@ -333,13 +352,17 @@ static int instantiate_rng(void)
memset(&op, 0, sizeof(struct result));
- desc = malloc(sizeof(int) * 6);
+ desc = memalign(ARCH_DMA_MINALIGN, sizeof(uint32_t) * 6);
if (!desc) {
printf("cannot allocate RNG init descriptor memory\n");
return -1;
}
inline_cnstr_jobdesc_rng_instantiation(desc);
+ int size = roundup(sizeof(uint32_t) * 6, ARCH_DMA_MINALIGN);
+ flush_dcache_range((unsigned long)desc,
+ (unsigned long)desc + size);
+
ret = run_descriptor_jr(desc);
if (ret)
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index aa11f15423..fe9a3b2396 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -8,6 +8,10 @@
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_DM_GPIO) += gpio-uclass.o
endif
+/* TODO(sjg@chromium.org): Only tegra supports driver model in SPL */
+ifdef CONFIG_TEGRA_GPIO
+obj-$(CONFIG_DM_GPIO) += gpio-uclass.o
+endif
obj-$(CONFIG_AT91_GPIO) += at91_gpio.o
obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o
diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index 43928b8812..f870cdbddf 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -132,21 +132,6 @@ static void set_level(unsigned gpio, int high)
writel(u, &bank->gpio_out[GPIO_PORT(gpio)]);
}
-/* set GPIO pin 'gpio' as an output, with polarity 'value' */
-int tegra_spl_gpio_direction_output(int gpio, int value)
-{
- /* Configure as a GPIO */
- set_config(gpio, 1);
-
- /* Configure GPIO output value. */
- set_level(gpio, value);
-
- /* Configure GPIO direction as output. */
- set_direction(gpio, 1);
-
- return 0;
-}
-
/*
* Generic_GPIO primitives.
*/
@@ -338,12 +323,19 @@ static int gpio_tegra_bind(struct udevice *parent)
int bank_count;
int bank;
int ret;
- int len;
/* If this is a child device, there is nothing to do here */
if (plat)
return 0;
+ /* TODO(sjg@chromium.org): Remove once SPL supports device tree */
+#ifdef CONFIG_SPL_BUILD
+ ctlr = (struct gpio_ctlr *)NV_PA_GPIO_BASE;
+ bank_count = TEGRA_GPIO_BANKS;
+#else
+ {
+ int len;
+
/*
* This driver does not make use of interrupts, other than to figure
* out the number of GPIO banks
@@ -353,6 +345,8 @@ static int gpio_tegra_bind(struct udevice *parent)
bank_count = len / 3 / sizeof(u32);
ctlr = (struct gpio_ctlr *)fdtdec_get_addr(gd->fdt_blob,
parent->of_offset, "reg");
+ }
+#endif
for (bank = 0; bank < bank_count; bank++) {
int port;
@@ -388,4 +382,5 @@ U_BOOT_DRIVER(gpio_tegra) = {
.probe = gpio_tegra_probe,
.priv_auto_alloc_size = sizeof(struct tegra_port_info),
.ops = &gpio_tegra_ops,
+ .flags = DM_FLAG_PRE_RELOC,
};
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index f5d2ccba15..c5e270dd57 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -54,19 +54,21 @@ struct fsl_esdhc {
uint fevt; /* Force event register */
uint admaes; /* ADMA error status register */
uint adsaddr; /* ADMA system address register */
- char reserved2[160]; /* reserved */
+ char reserved2[100]; /* reserved */
+ uint vendorspec; /* Vendor Specific register */
+ char reserved3[59]; /* reserved */
uint hostver; /* Host controller version register */
- char reserved3[4]; /* reserved */
- uint dmaerraddr; /* DMA error address register */
char reserved4[4]; /* reserved */
- uint dmaerrattr; /* DMA error attribute register */
+ uint dmaerraddr; /* DMA error address register */
char reserved5[4]; /* reserved */
+ uint dmaerrattr; /* DMA error attribute register */
+ char reserved6[4]; /* reserved */
uint hostcapblt2; /* Host controller capabilities register 2 */
- char reserved6[8]; /* reserved */
+ char reserved7[8]; /* reserved */
uint tcr; /* Tuning control register */
- char reserved7[28]; /* reserved */
+ char reserved8[28]; /* reserved */
uint sddirctl; /* SD direction control register */
- char reserved8[712]; /* reserved */
+ char reserved9[712]; /* reserved */
uint scr; /* eSDHC control register */
};
@@ -342,6 +344,15 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
goto out;
}
+ /* Switch voltage to 1.8V if CMD11 succeeded */
+ if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V) {
+ esdhc_setbits32(&regs->vendorspec, ESDHC_VENDORSPEC_VSELECT);
+
+ printf("Run CMD11 1.8V switch\n");
+ /* Sleep for 5 ms - max time for card to switch to 1.8V */
+ udelay(5000);
+ }
+
/* Workaround for ESDHC errata ENGcm03648 */
if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
int timeout = 2500;
@@ -414,6 +425,10 @@ out:
while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD))
;
}
+
+ /* If this was CMD11, then notify that power cycle is needed */
+ if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V)
+ printf("CMD11 to switch to 1.8V mode failed, card requires power cycle.\n");
}
esdhc_write32(&regs->irqstat, -1);
@@ -509,6 +524,10 @@ static int esdhc_init(struct mmc *mmc)
/* Set timout to the maximum value */
esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
+#ifdef CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT
+ esdhc_setbits32(&regs->vendorspec, ESDHC_VENDORSPEC_VSELECT);
+#endif
+
return 0;
}
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index 24123fcfe5..610f9698e1 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -30,13 +30,22 @@ static u8 bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2,
static uint8_t cs_next;
static __maybe_unused struct nand_ecclayout omap_ecclayout;
+#if defined(CONFIG_NAND_OMAP_GPMC_WSCFG)
+static const int8_t wscfg[CONFIG_SYS_MAX_NAND_DEVICE] =
+ { CONFIG_NAND_OMAP_GPMC_WSCFG };
+#else
+/* wscfg is preset to zero since its a static variable */
+static const int8_t wscfg[CONFIG_SYS_MAX_NAND_DEVICE];
+#endif
+
/*
* Driver configurations
*/
struct omap_nand_info {
struct bch_control *control;
enum omap_ecc ecc_scheme;
- int cs;
+ uint8_t cs;
+ uint8_t ws; /* wait status pin (0,1) */
};
/* We are wasting a bit of memory but al least we are safe */
@@ -76,7 +85,9 @@ static void omap_nand_hwcontrol(struct mtd_info *mtd, int32_t cmd,
/* Check wait pin as dev ready indicator */
static int omap_dev_ready(struct mtd_info *mtd)
{
- return gpmc_cfg->status & (1 << 8);
+ register struct nand_chip *this = mtd->priv;
+ struct omap_nand_info *info = this->priv;
+ return gpmc_cfg->status & (1 << (8 + info->ws));
}
/*
@@ -901,8 +912,18 @@ int __maybe_unused omap_nand_switch_ecc(uint32_t hardware, uint32_t eccstrength)
return -EINVAL;
}
} else {
- err = omap_select_ecc_scheme(nand, OMAP_ECC_HAM1_CODE_SW,
+ if (eccstrength == 1) {
+ err = omap_select_ecc_scheme(nand,
+ OMAP_ECC_HAM1_CODE_SW,
mtd->writesize, mtd->oobsize);
+ } else if (eccstrength == 8) {
+ err = omap_select_ecc_scheme(nand,
+ OMAP_ECC_BCH8_CODE_HW_DETECTION_SW,
+ mtd->writesize, mtd->oobsize);
+ } else {
+ printf("nand: error: unsupported ECC scheme\n");
+ return -EINVAL;
+ }
}
/* Update NAND handling after ECC mode switch */
@@ -962,6 +983,7 @@ int board_nand_init(struct nand_chip *nand)
nand->IO_ADDR_W = (void __iomem *)&gpmc_cfg->cs[cs].nand_cmd;
omap_nand_info[cs].control = NULL;
omap_nand_info[cs].cs = cs;
+ omap_nand_info[cs].ws = wscfg[cs];
nand->priv = &omap_nand_info[cs];
nand->cmd_ctrl = omap_nand_hwcontrol;
nand->options |= NAND_NO_PADDING | NAND_CACHEPRG;
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index c03e935e2f..cc01604e60 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -253,11 +253,20 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis)
writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode);
+#ifndef CONFIG_DW_MAC_FORCE_THRESHOLD_MODE
writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD,
&dma_p->opmode);
+#else
+ writel(readl(&dma_p->opmode) | FLUSHTXFIFO,
+ &dma_p->opmode);
+#endif
writel(readl(&dma_p->opmode) | RXSTART | TXSTART, &dma_p->opmode);
+#ifdef CONFIG_DW_AXI_BURST_LEN
+ writel((CONFIG_DW_AXI_BURST_LEN & 0x1FF >> 1), &dma_p->axibus);
+#endif
+
/* Start up the PHY */
if (phy_startup(priv->phydev)) {
printf("Could not initialize PHY %s\n",
diff --git a/drivers/net/designware.h b/drivers/net/designware.h
index ce51102052..49d900cb3f 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -68,7 +68,9 @@ struct eth_dma_regs {
u32 status; /* 0x14 */
u32 opmode; /* 0x18 */
u32 intenable; /* 0x1c */
- u8 reserved[40];
+ u32 reserved1[2];
+ u32 axibus; /* 0x28 */
+ u32 reserved2[7];
u32 currhosttxdesc; /* 0x48 */
u32 currhostrxdesc; /* 0x4c */
u32 currhosttxbuffaddr; /* 0x50 */
diff --git a/drivers/video/am335x-fb.c b/drivers/video/am335x-fb.c
index ab9894102d..6f956499d7 100644
--- a/drivers/video/am335x-fb.c
+++ b/drivers/video/am335x-fb.c
@@ -127,6 +127,12 @@ int am335xfb_init(struct am335x_lcdpanel *panel)
memset((void *)gd->fb_base, 0, 0x20);
*(unsigned int *)gd->fb_base = 0x4000;
+ /* turn ON display through powercontrol function if accessible */
+ if (0 != panel->panel_power_ctrl)
+ panel->panel_power_ctrl(1);
+
+ debug("am335x-fb: wait for stable power ...\n");
+ mdelay(panel->pup_delay);
lcdhw->clkc_enable = LCD_CORECLKEN | LCD_LIDDCLKEN | LCD_DMACLKEN;
lcdhw->raster_ctrl = 0;
lcdhw->ctrl = LCD_CLK_DIVISOR(panel->pxl_clk_div) | LCD_RASTER_MODE;
@@ -159,11 +165,8 @@ int am335xfb_init(struct am335x_lcdpanel *panel)
gd->fb_base += 0x20; /* point fb behind palette */
- /* turn ON display through powercontrol function if accessible */
- if (0 != panel->panel_power_ctrl) {
- mdelay(panel->pon_delay);
- panel->panel_power_ctrl(1);
- }
+ debug("am335x-fb: waiting picture to be stable.\n.");
+ mdelay(panel->pon_delay);
return 0;
}
diff --git a/drivers/video/am335x-fb.h b/drivers/video/am335x-fb.h
index 8a0b131495..7f799d1f31 100644
--- a/drivers/video/am335x-fb.h
+++ b/drivers/video/am335x-fb.h
@@ -55,9 +55,14 @@ struct am335x_lcdpanel {
unsigned int vsw; /* Vertical Sync Pulse Width */
unsigned int pxl_clk_div; /* Pixel clock divider*/
unsigned int pol; /* polarity of sync, clock signals */
+ unsigned int pup_delay; /*
+ * time in ms after power on to
+ * initialization of lcd-controller
+ * (VCC ramp up time)
+ */
unsigned int pon_delay; /*
- * time in ms for turning on lcd after
- * initializing lcd-controller
+ * time in ms after initialization of
+ * lcd-controller (pic stabilization)
*/
void (*panel_power_ctrl)(int); /* fp for power on/off display */
};