diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/crypto/fsl/Makefile | 2 | ||||
-rw-r--r-- | drivers/crypto/fsl/desc.h | 15 | ||||
-rw-r--r-- | drivers/crypto/fsl/fsl_blob.c | 52 | ||||
-rw-r--r-- | drivers/crypto/fsl/jobdesc.c | 149 | ||||
-rw-r--r-- | drivers/crypto/fsl/jobdesc.h | 14 | ||||
-rw-r--r-- | drivers/crypto/fsl/jr.c | 31 | ||||
-rw-r--r-- | drivers/gpio/Makefile | 4 | ||||
-rw-r--r-- | drivers/gpio/tegra_gpio.c | 27 | ||||
-rw-r--r-- | drivers/mmc/fsl_esdhc.c | 33 | ||||
-rw-r--r-- | drivers/mtd/nand/omap_gpmc.c | 28 | ||||
-rw-r--r-- | drivers/net/designware.c | 9 | ||||
-rw-r--r-- | drivers/net/designware.h | 4 | ||||
-rw-r--r-- | drivers/video/am335x-fb.c | 13 | ||||
-rw-r--r-- | drivers/video/am335x-fb.h | 9 |
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(®s->irja, 1); @@ -187,6 +199,13 @@ static int jr_dequeue(void) void *arg = NULL; while (sec_in32(®s->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(®s->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(®s->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(®s->irqstat, -1); @@ -509,6 +524,10 @@ static int esdhc_init(struct mmc *mmc) /* Set timout to the maximum value */ esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16); +#ifdef CONFIG_SYS_FSL_ESDHC_FORCE_VSELECT + esdhc_setbits32(®s->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 */ }; |