[U-Boot] [PATCH 1/7] eSPI: add the eSPI register support

Signed-off-by: Mingkai Hu Mingkai.hu@freescale.com --- include/asm-ppc/immap_85xx.h | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-)
diff --git a/include/asm-ppc/immap_85xx.h b/include/asm-ppc/immap_85xx.h index 094fb9c..f3ab750 100644 --- a/include/asm-ppc/immap_85xx.h +++ b/include/asm-ppc/immap_85xx.h @@ -258,6 +258,21 @@ typedef struct ccsr_lbc { } ccsr_lbc_t;
/* + * eSPI Registers(0x7000-0x8000) + */ +typedef struct ccsr_espi { + uint mode; /* 0x00 - eSPI mode register */ + uint event; /* 0x04 - eSPI event register */ + uint mask; /* 0x08 - eSPI mask register */ + uint com; /* 0x0c - eSPI command register */ + uint tx; /* 0x10 - eSPI transmit FIFO access register */ + uint rx; /* 0x14 - eSPI receive FIFO access register */ + char res1[8]; /* reserved */ + uint csmode[4]; /* 0x20 - 0x2c: sSPI CS0/1/2/3 mode register */ + char res2[4048]; /* fill up to 0x1000 */ +} ccsr_espi_t; + +/* * PCI Registers(0x8000-0x9000) */ typedef struct ccsr_pcix { @@ -1682,6 +1697,8 @@ typedef struct ccsr_gur { #define CONFIG_SYS_MPC85xx_DDR2_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_DDR2_OFFSET) #define CONFIG_SYS_MPC85xx_LBC_OFFSET (0x5000) #define CONFIG_SYS_MPC85xx_LBC_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_LBC_OFFSET) +#define CONFIG_SYS_MPC85xx_ESPI_OFFSET (0x7000) +#define CONFIG_SYS_MPC85xx_ESPI_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_ESPI_OFFSET) #define CONFIG_SYS_MPC85xx_PCIX_OFFSET (0x8000) #define CONFIG_SYS_MPC85xx_PCIX_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC85xx_PCIX_OFFSET) #define CONFIG_SYS_MPC85xx_PCIX2_OFFSET (0x9000)

Add MTD SPI Flash support for S25FL008A, S25FL016A, S25FL032A, S25FL064A, S25FL128P.
Signed-off-by: Mingkai Hu Mingkai.hu@freescale.com --- drivers/mtd/spi/Makefile | 1 + drivers/mtd/spi/spansion.c | 356 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 357 insertions(+), 0 deletions(-) create mode 100644 drivers/mtd/spi/spansion.c
diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile index 3d4f892..3f46de2 100644 --- a/drivers/mtd/spi/Makefile +++ b/drivers/mtd/spi/Makefile @@ -28,6 +28,7 @@ LIB := $(obj)libspi_flash.a COBJS-$(CONFIG_SPI_FLASH) += spi_flash.o COBJS-$(CONFIG_SPI_FLASH_ATMEL) += atmel.o COBJS-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.o +COBJS-$(CONFIG_SPI_FLASH_SPANSION) += spansion.o
COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/mtd/spi/spansion.c b/drivers/mtd/spi/spansion.c new file mode 100644 index 0000000..9de4b7b --- /dev/null +++ b/drivers/mtd/spi/spansion.c @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2009 Freescale Semiconductor, Inc. + * + * Author: Mingkai Hu (Mingkai.hu@freescale.com) + * Based on stmicro.c by Wolfgang Denk (wd@denx.de), + * TsiChung Liew (Tsi-Chung.Liew@freescale.com), + * and Jason McMullan (mcmullan@netapp.com) + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <malloc.h> +#include <spi_flash.h> + +#include "spi_flash_internal.h" + +/* S25FLxx-specific commands */ +#define CMD_S25FLXX_READ 0x03 /* Read Data Bytes */ +#define CMD_S25FLXX_FAST_READ 0x0b /* Read Data Bytes at Higher Speed */ +#define CMD_S25FLXX_READID 0x90 /* Read Manufacture ID and Device ID */ +#define CMD_S25FLXX_WREN 0x06 /* Write Enable */ +#define CMD_S25FLXX_WRDI 0x04 /* Write Disable */ +#define CMD_S25FLXX_RDSR 0x05 /* Read Status Register */ +#define CMD_S25FLXX_WRSR 0x01 /* Write Status Register */ +#define CMD_S25FLXX_PP 0x02 /* Page Program */ +#define CMD_S25FLXX_SE 0xd8 /* Sector Erase */ +#define CMD_S25FLXX_BE 0xc7 /* Bulk Erase */ +#define CMD_S25FLXX_DP 0xb9 /* Deep Power-down */ +#define CMD_S25FLXX_RES 0xab /* Release from DP, and Read Signature */ + +#define SPSN_ID_S25FL008A 0x0213 +#define SPSN_ID_S25FL016A 0x0214 +#define SPSN_ID_S25FL032A 0x0215 +#define SPSN_ID_S25FL064A 0x0216 +#define SPSN_ID_S25FL128P 0x2018 +#define SPSN_EXT_ID_S25FL128P_256KB 0x0300 +#define SPSN_EXT_ID_S25FL128P_64KB 0x0301 + +#define SPANSION_SR_WIP (1 << 0) /* Write-in-Progress */ + +struct spansion_spi_flash_params { + u16 idcode1; + u16 idcode2; + u16 page_size; + u16 pages_per_sector; + u16 nr_sectors; + const char *name; +}; + +struct spansion_spi_flash { + struct spi_flash flash; + const struct spansion_spi_flash_params *params; +}; + +static inline struct spansion_spi_flash *to_spansion_spi_flash(struct spi_flash + *flash) +{ + return container_of(flash, struct spansion_spi_flash, flash); +} + +static const struct spansion_spi_flash_params spansion_spi_flash_table[] = { + { + .idcode1 = SPSN_ID_S25FL008A, + .idcode2 = 0, + .page_size = 256, + .pages_per_sector = 256, + .nr_sectors = 16, + .name = "S25FL008A", + }, + { + .idcode1 = SPSN_ID_S25FL016A, + .idcode2 = 0, + .page_size = 256, + .pages_per_sector = 256, + .nr_sectors = 32, + .name = "S25FL016A", + }, + { + .idcode1 = SPSN_ID_S25FL032A, + .idcode2 = 0, + .page_size = 256, + .pages_per_sector = 256, + .nr_sectors = 64, + .name = "S25FL032A", + }, + { + .idcode1 = SPSN_ID_S25FL064A, + .idcode2 = 0, + .page_size = 256, + .pages_per_sector = 256, + .nr_sectors = 128, + .name = "S25FL064A", + }, + { + .idcode1 = SPSN_ID_S25FL128P, + .idcode2 = SPSN_EXT_ID_S25FL128P_64KB, + .page_size = 256, + .pages_per_sector = 256, + .nr_sectors = 256, + .name = "S25FL128P_64K", + }, + { + .idcode1 = SPSN_ID_S25FL128P, + .idcode2 = SPSN_EXT_ID_S25FL128P_256KB, + .page_size = 256, + .pages_per_sector = 1024, + .nr_sectors = 64, + .name = "S25FL128P_256K", + }, +}; + +static int spansion_wait_ready(struct spi_flash *flash, unsigned long timeout) +{ + struct spi_slave *spi = flash->spi; + unsigned long timebase; + int ret; + u8 status; + + timebase = get_timer(0); + do { + ret = spi_flash_cmd(spi, CMD_S25FLXX_RDSR, &status, sizeof(status)); + if (ret) + return -1; + + if ((status & SPANSION_SR_WIP) == 0) + break; + + } while (get_timer(timebase) < timeout); + + + if ((status & SPANSION_SR_WIP) == 0) + return 0; + + /* Timed out */ + return -1; +} + +static int spansion_read_fast(struct spi_flash *flash, + u32 offset, size_t len, void *buf) +{ + struct spansion_spi_flash *spsn = to_spansion_spi_flash(flash); + unsigned long page_addr; + unsigned long page_size; + u8 cmd[5]; + + page_size = spsn->params->page_size; + page_addr = offset / page_size; + + cmd[0] = CMD_READ_ARRAY_FAST; + cmd[1] = page_addr >> 8; + cmd[2] = page_addr; + cmd[3] = offset % page_size; + cmd[4] = 0x00; + + debug + ("READ: 0x%x => cmd = { 0x%02x 0x%02x%02x%02x%02x } len = 0x%x\n", + offset, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], len); + + return spi_flash_read_common(flash, cmd, sizeof(cmd), buf, len); +} + +static int spansion_write(struct spi_flash *flash, + u32 offset, size_t len, const void *buf) +{ + struct spansion_spi_flash *spsn = to_spansion_spi_flash(flash); + unsigned long page_addr; + unsigned long byte_addr; + unsigned long page_size; + size_t chunk_len; + size_t actual; + int ret; + u8 cmd[4]; + + page_size = spsn->params->page_size; + page_addr = offset / page_size; + byte_addr = offset % page_size; + + ret = spi_claim_bus(flash->spi); + if (ret) { + debug("SF: Unable to claim SPI bus\n"); + return ret; + } + + ret = 0; + for (actual = 0; actual < len; actual += chunk_len) { + chunk_len = min(len - actual, page_size - byte_addr); + + cmd[0] = CMD_S25FLXX_PP; + cmd[1] = page_addr >> 8; + cmd[2] = page_addr; + cmd[3] = byte_addr; + + debug + ("PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %d\n", + buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len); + + ret = spi_flash_cmd(flash->spi, CMD_S25FLXX_WREN, NULL, 0); + if (ret < 0) { + debug("SF: Enabling Write failed\n"); + break; + } + + ret = spi_flash_cmd_write(flash->spi, cmd, 4, + buf + actual, chunk_len); + if (ret < 0) { + debug("SF: SPANSION Page Program failed\n"); + break; + } + + ret = spansion_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT); + if (ret < 0) { + debug("SF: SPANSION page programming timed out\n"); + break; + } + + page_addr++; + byte_addr = 0; + } + + debug("SF: SPANSION: Successfully programmed %u bytes @ 0x%x\n", + len, offset); + + spi_release_bus(flash->spi); + return ret; +} + +int spansion_erase(struct spi_flash *flash, u32 offset, size_t len) +{ + struct spansion_spi_flash *spsn = to_spansion_spi_flash(flash); + unsigned long sector_size; + size_t actual; + int ret; + u8 cmd[4]; + + /* + * This function currently uses sector erase only. + * probably speed things up by using bulk erase + * when possible. + */ + + sector_size = spsn->params->page_size * spsn->params->pages_per_sector; + + if (offset % sector_size || len % sector_size) { + debug("SF: Erase offset/length not multiple of sector size\n"); + return -1; + } + + len /= sector_size; + cmd[0] = CMD_S25FLXX_SE; + cmd[2] = 0x00; + cmd[3] = 0x00; + + ret = spi_claim_bus(flash->spi); + if (ret) { + debug("SF: Unable to claim SPI bus\n"); + return ret; + } + + ret = 0; + for (actual = 0; actual < len; actual++) { + cmd[1] = (offset / sector_size) + actual; + + ret = spi_flash_cmd(flash->spi, CMD_S25FLXX_WREN, NULL, 0); + if (ret < 0) { + debug("SF: Enabling Write failed\n"); + break; + } + + ret = spi_flash_cmd_write(flash->spi, cmd, 4, NULL, 0); + if (ret < 0) { + debug("SF: SPANSION page erase failed\n"); + break; + } + + /* Up to 2 seconds */ + ret = spansion_wait_ready(flash, 2 * CONFIG_SYS_HZ); + if (ret < 0) { + debug("SF: SPANSION page erase timed out\n"); + break; + } + } + + debug("SF: SPANSION: Successfully erased %u bytes @ 0x%x\n", + len * sector_size, offset); + + spi_release_bus(flash->spi); + return ret; +} + +struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode) +{ + const struct spansion_spi_flash_params *params; + struct spansion_spi_flash *spsn; + unsigned int i; + unsigned short jedec, ext_jedec; + int ret; + u8 id[5] = {0}; + + ret = spi_flash_cmd(spi, CMD_READ_ID, id, sizeof(id)); + if (ret) + return NULL; + + jedec = id[1] << 8 | id[2]; + ext_jedec = id[3] << 8 | id[4]; + + for (i = 0; i < ARRAY_SIZE(spansion_spi_flash_table); i++) { + params = &spansion_spi_flash_table[i]; + if (params->idcode1 == jedec) { + if (params->idcode2 == ext_jedec) + break; + } + } + + if (i == ARRAY_SIZE(spansion_spi_flash_table)) { + debug("SF: Unsupported SPANSION ID %04x %04x\n", jedec, ext_jedec); + return NULL; + } + + spsn = malloc(sizeof(struct spansion_spi_flash)); + if (!spsn) { + debug("SF: Failed to allocate memory\n"); + return NULL; + } + + spsn->params = params; + spsn->flash.spi = spi; + spsn->flash.name = params->name; + + spsn->flash.write = spansion_write; + spsn->flash.erase = spansion_erase; + spsn->flash.read = spansion_read_fast; + spsn->flash.size = params->page_size * params->pages_per_sector + * params->nr_sectors; + + debug("SF: Detected %s with page size %u, total %u bytes\n", + params->name, params->page_size, spsn->flash.size); + + return &spsn->flash; +}

Add eSPI controller support under the SPI framework.
Signed-off-by: Mingkai Hu Mingkai.hu@freescale.com --- drivers/mtd/spi/spi_flash.c | 94 +++++++++++++++++- drivers/spi/Makefile | 1 + drivers/spi/fsl_espi.c | 232 +++++++++++++++++++++++++++++++++++++++++++ include/spi.h | 30 ++++++ 4 files changed, 354 insertions(+), 3 deletions(-) create mode 100644 drivers/spi/fsl_espi.c
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index d1d81af..fa97896 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -1,6 +1,8 @@ /* * SPI flash interface + * Add support for Freescale eSPI controller * + * Copyright (C) 2009 Freescale Semiconductor, Inc. * Copyright (C) 2008 Atmel Corporation */ #define DEBUG @@ -16,6 +18,7 @@ int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len) unsigned long flags = SPI_XFER_BEGIN; int ret;
+#ifndef CONFIG_FSL_ESPI if (len == 0) flags |= SPI_XFER_END;
@@ -31,6 +34,35 @@ int spi_flash_cmd(struct spi_slave *spi, u8 cmd, void *response, size_t len) debug("SF: Failed to read response (%zu bytes): %d\n", len, ret); } +#else + struct espi_transfer transfer[1]; + unsigned char *buffer; + + buffer = (unsigned char *)malloc(len + 2); + if (!buffer) { + debug("SF: Failed to malloc memory.\n"); + return 1; + } + memcpy(buffer, &cmd, 1); + + transfer[0].cmd_len = 1; + transfer[0].data_len = len; + transfer[0].tx_buf = buffer; + transfer[0].rx_buf = buffer + 1; + transfer[0].flags = flags | SPI_XFER_END; + + spi->transfer = &transfer[0]; + ret = espi_xfer(spi); + if (ret) { + debug("SF: Failed to send command %02x: %d\n", cmd, ret); + return ret; + } + + if (len) + memcpy(response, transfer[0].rx_buf + 1, len); + + free(buffer); +#endif
return ret; } @@ -41,6 +73,7 @@ int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd, unsigned long flags = SPI_XFER_BEGIN; int ret;
+#ifndef CONFIG_FSL_ESPI if (data_len == 0) flags |= SPI_XFER_END;
@@ -54,6 +87,33 @@ int spi_flash_cmd_read(struct spi_slave *spi, const u8 *cmd, debug("SF: Failed to read %zu bytes of data: %d\n", data_len, ret); } +#else + struct espi_transfer transfer[1]; + unsigned char *buffer; + + buffer = (unsigned char *)malloc(2 * cmd_len + data_len); + if (!buffer) { + debug("SF: Failed to malloc memory.\n"); + return 1; + } + memcpy(buffer, cmd, cmd_len); + + transfer[0].cmd_len = cmd_len; + transfer[0].data_len = data_len; + transfer[0].tx_buf = buffer; + transfer[0].rx_buf = buffer + cmd_len; + transfer[0].flags = flags | SPI_XFER_END; + + spi->transfer = &transfer[0]; + ret = espi_xfer(spi); + if (ret) { + debug("SF: Failed to read %zu bytes of data: %d\n", + data_len, ret); + } + + memcpy(data, transfer[0].rx_buf + cmd_len, data_len); + free(buffer); +#endif
return ret; } @@ -64,6 +124,7 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len, unsigned long flags = SPI_XFER_BEGIN; int ret;
+#ifndef CONFIG_FSL_ESPI if (data_len == 0) flags |= SPI_XFER_END;
@@ -77,6 +138,33 @@ int spi_flash_cmd_write(struct spi_slave *spi, const u8 *cmd, size_t cmd_len, debug("SF: Failed to read %zu bytes of data: %d\n", data_len, ret); } +#else + struct espi_transfer transfer[1]; + unsigned char *buffer; + + buffer = (unsigned char *)malloc(cmd_len + data_len); + if (!buffer) { + debug("SF: Failed to malloc memory.\n"); + return 1; + } + memcpy(buffer, cmd, cmd_len); + memcpy(buffer + cmd_len, data, data_len); + + transfer[0].cmd_len = cmd_len; + transfer[0].data_len = data_len; + transfer[0].tx_buf = buffer; + transfer[0].rx_buf = NULL; + transfer[0].flags = flags | SPI_XFER_END; + + spi->transfer = &transfer[0]; + ret = espi_xfer(spi); + if (ret) { + debug("SF: Failed to read %zu bytes of data: %d\n", + data_len, ret); + } + + free(buffer); +#endif
return ret; } @@ -101,7 +189,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, struct spi_slave *spi; struct spi_flash *flash; int ret; - u8 idcode[3]; + u8 idcode[5];
spi = spi_setup_slave(bus, cs, max_hz, spi_mode); if (!spi) { @@ -120,8 +208,8 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, if (ret) goto err_read_id;
- debug("SF: Got idcode %02x %02x %02x\n", idcode[0], - idcode[1], idcode[2]); + debug("SF: Got idcode %02x %02x %02x %02x %02x\n", idcode[0], + idcode[1], idcode[2], idcode[3], idcode[4]);
switch (idcode[0]) { #ifdef CONFIG_SPI_FLASH_SPANSION diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 6e2c121..406881a 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -30,6 +30,7 @@ COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o +COBJS-$(CONFIG_FSL_ESPI) += fsl_espi.o
COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/spi/fsl_espi.c b/drivers/spi/fsl_espi.c new file mode 100644 index 0000000..78d7b25 --- /dev/null +++ b/drivers/spi/fsl_espi.c @@ -0,0 +1,232 @@ +/* + * eSPI controller driver. + * + * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved. + * Author: Mingkai Hu (Mingkai.hu@freescale.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> + +#include <malloc.h> +#include <spi.h> +#include <asm/immap_85xx.h> + +#define ESPI_MAX_CS_NUM 4 + +#define ESPI_EV_RNE (1 << 9) +#define ESPI_EV_TNF (1 << 8) + +#define ESPI_MODE_EN (1 << 31) /* Enable interface */ +#define ESPI_MODE_TXTHR(x) ((x) << 8) /* Tx FIFO threshold */ +#define ESPI_MODE_RXTHR(x) ((x) << 0) /* Rx FIFO threshold */ + +#define ESPI_COM_CS(x) ((x) << 30) +#define ESPI_COM_TRANLEN(x) ((x) << 0) + +#define ESPI_CSMODE_CI_INACTIVEHIGH (1 << 31) +#define ESPI_CSMODE_CP_BEGIN_EDGCLK (1 << 30) +#define ESPI_CSMODE_REV_MSB_FIRST (1 << 29) +#define ESPI_CSMODE_DIV16 (1 << 28) +#define ESPI_CSMODE_PM(x) ((x) << 24) +#define ESPI_CSMODE_POL_ASSERTED_LOW (1 << 20) +#define ESPI_CSMODE_LEN(x) ((x) << 16) +#define ESPI_CSMODE_CSBEF(x) ((x) << 12) +#define ESPI_CSMODE_CSAFT(x) ((x) << 8) +#define ESPI_CSMODE_CSCG(x) ((x) << 3) + +#define ESPI_CSMODE_INIT_VAL (ESPI_CSMODE_POL_ASSERTED_LOW | \ + ESPI_CSMODE_CSBEF(0) | ESPI_CSMODE_CSAFT(0) | \ + ESPI_CSMODE_CSCG(1)) + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + volatile ccsr_espi_t *espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR); + struct spi_slave *slave; + sys_info_t sysinfo; + unsigned long spibrg = 0; + unsigned char pm = 0; + int i; + + if (!spi_cs_is_valid(bus, cs)) + return NULL; + + slave = malloc(sizeof(struct spi_slave)); + if (!slave) + return NULL; + + slave->bus = bus; + slave->cs = cs; + + /* Enable eSPI interface */ + espi->mode = ESPI_MODE_RXTHR(3) | ESPI_MODE_TXTHR(4) | ESPI_MODE_EN; + + espi->event = 0xffffffff; /* Clear all eSPI events */ + espi->mask = 0x00000000; /* Mask all eSPI interrupts */ + + /* Init CS mode interface */ + for (i = 0; i < ESPI_MAX_CS_NUM; i++) + espi->csmode[i] = ESPI_CSMODE_INIT_VAL; + + espi->csmode[cs] &= ~(ESPI_CSMODE_PM(0xF) | ESPI_CSMODE_DIV16 + | ESPI_CSMODE_CI_INACTIVEHIGH | ESPI_CSMODE_CP_BEGIN_EDGCLK + | ESPI_CSMODE_REV_MSB_FIRST | ESPI_CSMODE_LEN(0xF)); + + /* Set eSPI BRG clock source */ + get_sys_info(&sysinfo); + spibrg = sysinfo.freqSystemBus / 2; + if ((spibrg / max_hz) > 32) { + espi->csmode[cs] |= ESPI_CSMODE_DIV16; + pm = spibrg / (max_hz * 16 * 2); + if (pm > 16) { + pm = 16; + debug("Requested speed is too low: %d Hz" + " %d Hz is used.\n", max_hz, spibrg / (32 * 16)); + } + } else + pm = spibrg / (max_hz * 2); + if (pm) + pm--; + espi->csmode[cs] |= ESPI_CSMODE_PM(pm); + + /* Set eSPI mode */ + if (mode & SPI_CPHA) + espi->csmode[cs] |= ESPI_CSMODE_CP_BEGIN_EDGCLK; + if (mode & SPI_CPOL) + espi->csmode[cs] |= ESPI_CSMODE_CI_INACTIVEHIGH; + + /* Character bit order: msb first */ + espi->csmode[cs] |= ESPI_CSMODE_REV_MSB_FIRST; + + /* Character length in bits, between 0x3~0xf, i.e. 4bits~16bits */ + espi->csmode[cs] |= ESPI_CSMODE_LEN(7); + + return slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + free(slave); +} + +void spi_init(void) +{ + +} + +int spi_claim_bus(struct spi_slave *slave) +{ + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ + +} + +int espi_xfer(struct spi_slave *slave) +{ + volatile ccsr_espi_t *espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR); + unsigned int tmpdout, tmpdin, event; + struct espi_transfer *t = slave->transfer; + unsigned int len = t->cmd_len + t->data_len; + const void *dout = t->tx_buf; + void *din = t->rx_buf; + unsigned long flags = t->flags; + int numBlks = len / 4 + (len % 4 ? 1 : 0); + unsigned char charsize = 4; + + debug("spi_xfer: slave %u:%u dout %08X(%08x) din %08X(%08x) len %u\n", + slave->bus, slave->cs, *(uint *) dout, dout, *(uint *) din, din, len); + + if (flags & SPI_XFER_BEGIN) + spi_cs_activate(slave); + + /* Clear all eSPI events */ + espi->event = 0xffffffff; + + /* handle data in 32-bit chunks */ + while (numBlks--) { + charsize = (len >= 4 ? 4 : len); + + event = espi->event; + if (event & ESPI_EV_TNF) { + tmpdout = *(u32 *)dout; + + /* Set up the next iteration if sending > 4 bytes */ + if (len > 4) { + len -= 4; + dout += 4; + } + + espi->tx = tmpdout; + espi->event |= ESPI_EV_TNF; + } + debug("*** espi_xfer: ... %08x written\n", tmpdout); + + /* Wait for eSPI transmit to get out */ + udelay(80); + + event = espi->event; + if (event & ESPI_EV_RNE) { + tmpdin = espi->rx; + *(u32 *) din = tmpdin; + + if (charsize == 4) { + din += 4; + } + + espi->event |= ESPI_EV_RNE; + } + debug("*** espi_xfer: ... %08x readed\n", tmpdin); + } + + if (flags & SPI_XFER_END) + spi_cs_deactivate(slave); + + return 0; +} + +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + return bus == 0 && cs < ESPI_MAX_CS_NUM; +} + +void spi_cs_activate(struct spi_slave *slave) +{ + volatile ccsr_espi_t *espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR); + struct espi_transfer *t = slave->transfer; + unsigned int com = 0; + unsigned int len = t->cmd_len + t->data_len; + + com &= ~(ESPI_COM_CS(0x3) | ESPI_COM_TRANLEN(0xFFFF)); + com |= ESPI_COM_CS(slave->cs); + com |= ESPI_COM_TRANLEN(len - 1); + espi->com = com; + + return; +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + volatile ccsr_espi_t *espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR); + + /* clear the RXCNT and TXCNT */ + espi->mode &= ~ESPI_MODE_EN; + espi->mode |= ESPI_MODE_EN; +} diff --git a/include/spi.h b/include/spi.h index 320e50e..948a565 100644 --- a/include/spi.h +++ b/include/spi.h @@ -50,16 +50,38 @@ #define SPI_XFER_END 0x02 /* Deassert CS after transfer */
/*----------------------------------------------------------------------- + * Representation of a eSPI transaction, which is always embeded in + * structure spi_slave. + * + * cmd_len: Length of the command. + * data_len: Length of the transmit/receive data. + * tx_buf: Buffer to store the transmit command and data. + * rx_buf: Buffer to store the receive data. + * flags: Flags to indicate the begin/end of the transfer. + */ +struct espi_transfer { + unsigned int cmd_len; + unsigned int data_len; + const void *tx_buf; + void *rx_buf; + + unsigned long flags; +}; + +/*----------------------------------------------------------------------- * Representation of a SPI slave, i.e. what we're communicating with. * * Drivers are expected to extend this with controller-specific data. * * bus: ID of the bus that the slave is attached to. * cs: ID of the chip select connected to the slave. + * transfer: Represent an eSPI transaction. */ struct spi_slave { unsigned int bus; unsigned int cs; + + struct espi_transfer *transfer; };
/*----------------------------------------------------------------------- @@ -148,6 +170,14 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, void *din, unsigned long flags);
/*----------------------------------------------------------------------- + * eSPI transfer + * + * Returns: 0 on success, not 0 on failure + */ +int espi_xfer(struct spi_slave *slave); + + +/*----------------------------------------------------------------------- * Determine if a SPI chipselect is valid. * This function is provided by the board if the low-level SPI driver * needs it to determine if a given chipselect is actually valid.

On the MPC8536 processor, the eSPI chip selects and the eSDHC data interface have four pin-muxed pins shared between them, so if the eSDHC data interface is expanded to 8-bits, no eSPI chip selects are routed.
Signed-off-by: Mingkai Hu Mingkai.hu@freescale.com --- board/freescale/mpc8536ds/mpc8536ds.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/board/freescale/mpc8536ds/mpc8536ds.c b/board/freescale/mpc8536ds/mpc8536ds.c index 31c1e15..1f028c2 100644 --- a/board/freescale/mpc8536ds/mpc8536ds.c +++ b/board/freescale/mpc8536ds/mpc8536ds.c @@ -50,8 +50,7 @@ int board_early_init_f (void) volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
setbits_be32(&gur->pmuxcr, - (MPC85xx_PMUXCR_SD_DATA | - MPC85xx_PMUXCR_SDHC_CD | + (MPC85xx_PMUXCR_SDHC_CD | MPC85xx_PMUXCR_SDHC_WP));
#endif

This patch is used to generate a special version u-boot, together with the data structure on the SDcard/SPI flash, can be used to booting from SDcard/SPI flash on 8536DS board.
The boot ROM in CPU and the data structure on SD card will initialize the DDR, set a large tlb0 for DDR and CCSR, set law0 for DDR. The special version uboot avoid initializing the DDR. Try to reseve the law0 for DDR by adding a CONFIG_SYS_RESERVED_LAW0 macro for the "dynamic law allocation" code. But keep the original tlb initialize code for DDR, disabled the large tlb0 which was set in the boot ROM.
This patch is intend for those who are interested in the function of booting from SD card on 8536DS board and not for opensource. An utility is needed to write the data structure and the special version u-boot onto the SD card which has filesystem on it or onto the SPI flash.
Signed-off-by: Jason Jin Jason.jin@freescale.com Signed-off-by: Mingkai Hu Mingkai.hu@freescale.com --- Makefile | 12 +++ board/freescale/mpc8536ds/config.mk | 2 + board/freescale/mpc8536ds/mpc8536ds.c | 4 + board/freescale/mpc8536ds/tlb.c | 3 + board/freescale/mpc8536ds/u-boot-sdboot.lds | 139 +++++++++++++++++++++++++++ config.mk | 4 +- cpu/mpc85xx/cpu_init.c | 70 +++++++++++++- cpu/mpc85xx/start.S | 17 +++- drivers/misc/fsl_law.c | 4 + include/configs/MPC8536DS.h | 12 ++- 10 files changed, 262 insertions(+), 5 deletions(-) create mode 100644 board/freescale/mpc8536ds/u-boot-sdboot.lds
diff --git a/Makefile b/Makefile index e8b4c13..c18a2e0 100644 --- a/Makefile +++ b/Makefile @@ -2360,6 +2360,18 @@ ATUM8548_config: unconfig MPC8536DS_config: unconfig @$(MKCONFIG) $(@:_config=) ppc mpc85xx mpc8536ds freescale
+MPC8536DS_SPIFLASH_config \ +MPC8536DS_SDCARD_config: unconfig + @echo "" >$(obj)include/config.h; + @if [ "$(findstring _SPIFLASH_,$@)" ] ; then \ + echo "#define CONFIG_SPIFLASH_U_BOOT" >> $(obj)include/config.h ; \ + fi ; + @echo "#define CONFIG_SDCARD_U_BOOT" >> $(obj)include/config.h ; + @$(MKCONFIG) -a MPC8536DS ppc mpc85xx mpc8536ds freescale ; \ + echo "TEXT_BASE = 0x11001000" > $(obj)board/freescale/mpc8536ds/config.tmp ; \ + echo "#define CONFIG_SDCARD_U_BOOT" >> $(obj)include/config.h ; \ + echo "CONFIG_SDCARD_U_BOOT = y" >> $(obj)include/config.mk ; + MPC8540ADS_config: unconfig @$(MKCONFIG) $(@:_config=) ppc mpc85xx mpc8540ads freescale
diff --git a/board/freescale/mpc8536ds/config.mk b/board/freescale/mpc8536ds/config.mk index 9775ff4..b1c6251 100644 --- a/board/freescale/mpc8536ds/config.mk +++ b/board/freescale/mpc8536ds/config.mk @@ -23,6 +23,8 @@ # # mpc8536ds board # +sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp + ifndef TEXT_BASE TEXT_BASE = 0xeff80000 endif diff --git a/board/freescale/mpc8536ds/mpc8536ds.c b/board/freescale/mpc8536ds/mpc8536ds.c index 1f028c2..f4ce72f 100644 --- a/board/freescale/mpc8536ds/mpc8536ds.c +++ b/board/freescale/mpc8536ds/mpc8536ds.c @@ -73,6 +73,10 @@ initdram(int board_type)
puts("Initializing....");
+#ifdef CONFIG_SDCARD_U_BOOT + return CONFIG_SYS_SDRAM_SIZE * 1024 * 1024; +#endif + #ifdef CONFIG_SPD_EEPROM dram_size = fsl_ddr_sdram(); #else diff --git a/board/freescale/mpc8536ds/tlb.c b/board/freescale/mpc8536ds/tlb.c index 35a13d4..cb570ef 100644 --- a/board/freescale/mpc8536ds/tlb.c +++ b/board/freescale/mpc8536ds/tlb.c @@ -27,6 +27,8 @@ #include <asm/mmu.h>
struct fsl_e_tlb_entry tlb_table[] = { + +#if !defined(CONFIG_SDCARD_U_BOOT) /* TLB 0 - for temp stack in cache */ SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR, CONFIG_SYS_INIT_RAM_ADDR, MAS3_SX|MAS3_SW|MAS3_SR, 0, @@ -40,6 +42,7 @@ struct fsl_e_tlb_entry tlb_table[] = { SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024 , CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024, MAS3_SX|MAS3_SW|MAS3_SR, 0, 0, 0, BOOKE_PAGESZ_4K, 0), +#endif
SET_TLB_ENTRY(0, PIXIS_BASE, PIXIS_BASE_PHYS, MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, diff --git a/board/freescale/mpc8536ds/u-boot-sdboot.lds b/board/freescale/mpc8536ds/u-boot-sdboot.lds new file mode 100644 index 0000000..f4a0e91 --- /dev/null +++ b/board/freescale/mpc8536ds/u-boot-sdboot.lds @@ -0,0 +1,139 @@ +/* + * Copyright (C)2009 Freescale Semiconductor, Inc. All rights reserved. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_ARCH(powerpc) +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } + .plt : { *(.plt) } + .text : + { + *(.text) + *(.fixup) + *(.got1) + } + _etext = .; + PROVIDE (etext = .); + .rodata : + { + *(.rodata) + *(.rodata1) + *(.rodata.str1.4) + *(.eh_frame) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + + /* Read-write section, merged into data segment: */ + . = (. + 0x00FF) & 0xFFFFFF00; + _erotext = .; + PROVIDE (erotext = .); + .reloc : + { + *(.got) + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + + . = .; + __u_boot_cmd_start = .; + .u_boot_cmd : { *(.u_boot_cmd) } + __u_boot_cmd_end = .; + + . = .; + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + . = ALIGN(256); + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(256); + __init_end = .; + + .bootpg ADDR(.text) - 0x1000 : + { + cpu/mpc85xx/start.o (.bootpg) + } = 0xffff + + .resetvec ADDR(.text) + 0x7fffc - 0x1000 : + { + *(.resetvec) + } = 0xffff + + . = ADDR(.text) + 0x80000 - 0x1000; + + __bss_start = .; + .bss (NOLOAD) : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + + . = ALIGN(4); + _end = . ; + PROVIDE (end = .); +} diff --git a/config.mk b/config.mk index b1254e9..3300b75 100644 --- a/config.mk +++ b/config.mk @@ -112,8 +112,8 @@ DBGFLAGS= -g # -DDEBUG OPTFLAGS= -Os #-fomit-frame-pointer ifndef LDSCRIPT #LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug -ifeq ($(CONFIG_NAND_U_BOOT),y) -LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds +ifeq ($(CONFIG_SDCARD_U_BOOT),y) +LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-sdboot.lds else LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds endif diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c index 0b7c609..f2fd168 100644 --- a/cpu/mpc85xx/cpu_init.c +++ b/cpu/mpc85xx/cpu_init.c @@ -1,5 +1,9 @@ /* - * Copyright 2007 Freescale Semiconductor. + * Copyright (C) 2007,2009 Freescale Semiconductor, Inc. + * + * (C) 2009 Freescale Semiconductor, Inc. + * Modified by Jason Jin, Jason.jin@freescale.com, + * Mingkai hu, Mingkai.hu@freescale.com * * (C) Copyright 2003 Motorola Inc. * Modified by Xianghua Xiao, X.Xiao@motorola.com @@ -164,6 +168,70 @@ void cpu_init_early_f(void) init_tlbs(); }
+#ifdef CONFIG_SDCARD_U_BOOT +/* + * Used for booting from SD. + * The ROM code has set a 4G space in tlb0, and on the sd data structure, + * there also has a law0 setting for DDR(usually 1G, can be changed). + * we try to use those space as much as we can and will change those + * setting later. + * Change the CCSRBAR firstly as needed. +*/ +void cpu_init_early_f_sd(void) +{ + unsigned int law_size; + + /* set up CCSR if we want it moved */ +#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS) + { + u32 temp; + temp = in_be32((volatile u32 *)CONFIG_SYS_CCSRBAR_DEFAULT); + out_be32((volatile u32 *)CONFIG_SYS_CCSRBAR_DEFAULT, CONFIG_SYS_CCSRBAR_PHYS >> 12); + + temp = in_be32((volatile u32 *)CONFIG_SYS_CCSRBAR); + } +#endif + + /* Pointer is writable since we allocated a register for it. + * the gd->used_law will be used in the init_laws(), + * we prepared it here. + */ + gd = (gd_t *) (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); + + /* Clear initial global data */ + memset((void *)gd, 0, sizeof(gd_t)); + + /* law0 has been set for DDR in the SD data structure, we defined a + * CFG_RESERVED_LAW macro in the header file, try to avoid it being + * overlaped in the init_laws(). + */ + init_laws(); + + /*set a temp tlb15 in address space 1 for DDR*/ + set_tlb(1, CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DDR_SDRAM_BASE, + MAS3_SX|MAS3_SW|MAS3_SR, 0, + 1, 15, BOOKE_PAGESZ_1G, 1); + + /*And tlb14 for CCSR registers*/ + set_tlb(1, CONFIG_SYS_CCSRBAR, CONFIG_SYS_CCSRBAR_PHYS, + MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, + 1, 14, BOOKE_PAGESZ_1M, 1); +} + +/*This run in space 1 */ +void cpu_init_early_f_sd_continue(void) +{ + /* Disable tlb0 which intialized in the ROM + * Normal init for space 0 + */ + disable_tlb(0); + init_tlbs(); + + /*Reinitialize the tlb for DDR in space 0*/ + setup_ddr_tlbs(CONFIG_SYS_SDRAM_SIZE); +} +#endif + /* * Breathe some life into the CPU... * diff --git a/cpu/mpc85xx/start.S b/cpu/mpc85xx/start.S index 80f9677..4601c0a 100644 --- a/cpu/mpc85xx/start.S +++ b/cpu/mpc85xx/start.S @@ -184,6 +184,7 @@ _start_e500: mtspr DBCR0,r0 #endif
+#if !defined(CONFIG_SDCARD_U_BOOT) /* create a temp mapping in AS=1 to the 4M boot window */ lis r6,FSL_BOOKE_MAS0(1, 15, 0)@h ori r6,r6,FSL_BOOKE_MAS0(1, 15, 0)@l @@ -254,9 +255,10 @@ switch_as: dcbtls 0,r0,r3 addi r3,r3,CONFIG_SYS_CACHELINE_SIZE bdnz 1b +#endif
/* Jump out the last 4K page and continue to 'normal' start */ -#ifdef CONFIG_SYS_RAMBOOT +#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SDCARD_U_BOOT) b _start_cont #else /* Calculate absolute address in FLASH and jump there */ @@ -296,7 +298,20 @@ _start_cont: stw r0,+12(r1) /* Save return addr (underflow vect) */
GET_GOT +#if !defined(CONFIG_SDCARD_U_BOOT) bl cpu_init_early_f +#else + bl cpu_init_early_f_sd + + /*Then switch to space 1*/ + lis r3,(MSR_CE|MSR_ME|MSR_DE|MSR_IS|MSR_DS)@h + ori r3,r3,(MSR_CE|MSR_ME|MSR_DE|MSR_IS|MSR_DS)@l + mtmsr r3 + isync + msync + + bl cpu_init_early_f_sd_continue +#endif
/* switch back to AS = 0 */ lis r3,(MSR_CE|MSR_ME|MSR_DE)@h diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c index 58340c1..1d709dd 100644 --- a/drivers/misc/fsl_law.c +++ b/drivers/misc/fsl_law.c @@ -168,6 +168,10 @@ void init_laws(void)
gd->used_laws = ~((1 << FSL_HW_NUM_LAWS) - 1);
+#ifdef CONFIG_SDCARD_U_BOOT + gd->used_laws |= (1 << CONFIG_SYS_RESERVED_LAW0); +#endif + for (i = 0; i < num_law_entries; i++) { if (law_table[i].index == -1) set_next_law(law_table[i].addr, law_table[i].size, diff --git a/include/configs/MPC8536DS.h b/include/configs/MPC8536DS.h index bbb448d..b19f028 100644 --- a/include/configs/MPC8536DS.h +++ b/include/configs/MPC8536DS.h @@ -116,7 +116,7 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); #define CONFIG_SYS_SPD_BUS_NUM 1
/* These are used when DDR doesn't use SPD. */ -#define CONFIG_SYS_SDRAM_SIZE 256 /* DDR is 256MB */ +#define CONFIG_SYS_SDRAM_SIZE 512 /* DDR is 512MB */ #define CONFIG_SYS_DDR_CS0_BNDS 0x0000001F #define CONFIG_SYS_DDR_CS0_CONFIG 0x80010102 /* Enable, no interleaving */ #define CONFIG_SYS_DDR_TIMING_3 0x00000000 @@ -235,9 +235,15 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); #define PIXIS_VCLKL 0x1A /* VELA VCLKL register */ #define CONFIG_SYS_PIXIS_VBOOT_MASK 0xc0
+#if !defined(CONFIG_SDCARD_U_BOOT) #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xffd00000 /* Initial L1 address */ #define CONFIG_SYS_INIT_RAM_END 0x00004000 /* End of used area in RAM */ +#else +#undef CONFIG_SYS_INIT_RAM_LOCK +#define CONFIG_SYS_INIT_RAM_ADDR 0x07d00000 /* unused memory region */ +#define CONFIG_SYS_INIT_RAM_END 0x4000 /* we have SDRAM initialized */ +#endif
#define CONFIG_SYS_GBL_DATA_SIZE 128 /* num bytes initial data */ #define CONFIG_SYS_GBL_DATA_OFFSET (CONFIG_SYS_INIT_RAM_END - CONFIG_SYS_GBL_DATA_SIZE) @@ -246,6 +252,10 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); #define CONFIG_SYS_MONITOR_LEN (256 * 1024) /* Reserve 256 kB for Mon */ #define CONFIG_SYS_MALLOC_LEN (1024 * 1024) /* Reserved for malloc */
+#ifdef CONFIG_SDCARD_U_BOOT +#define CONFIG_SYS_RESERVED_LAW0 0 +#endif + #define CONFIG_SYS_NAND_BASE 0xffa00000 #define CONFIG_SYS_NAND_BASE_PHYS CONFIG_SYS_NAND_BASE #define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE,\

When after booting from SDcard, the environment variables can to be saved on it, this patch add the operation support.
Signed-off-by: Jason Jin Jason.jin@freescale.com Signed-off-by: Mingkai Hu Mingkai.hu@freescale.com --- common/Makefile | 1 + common/cmd_nvedit.c | 3 +- common/env_common.c | 3 +- common/env_sdcard.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 common/env_sdcard.c
diff --git a/common/Makefile b/common/Makefile index f13cd11..c768344 100644 --- a/common/Makefile +++ b/common/Makefile @@ -57,6 +57,7 @@ COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o COBJS-$(CONFIG_ENV_IS_IN_NVRAM) += env_nvram.o COBJS-$(CONFIG_ENV_IS_IN_ONENAND) += env_onenand.o COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o +COBJS-$(CONFIG_ENV_IS_IN_SDCARD) += env_sdcard.o COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o
# command diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 68c673e..fb6ba8d 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -59,8 +59,9 @@ DECLARE_GLOBAL_DATA_PTR; !defined(CONFIG_ENV_IS_IN_NAND) && \ !defined(CONFIG_ENV_IS_IN_ONENAND) && \ !defined(CONFIG_ENV_IS_IN_SPI_FLASH) && \ + !defined(CONFIG_ENV_IS_IN_SDCARD) && \ !defined(CONFIG_ENV_IS_NOWHERE) -# error Define one of CONFIG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|ONENAND|SPI_FLASH|NOWHERE} +# error Define one of CONFIG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|ONENAND|SPI_FLASH|SDCARD|NOWHERE} #endif
#define XMK_STR(x) #x diff --git a/common/env_common.c b/common/env_common.c index 6be3bb0..f1aaed2 100644 --- a/common/env_common.c +++ b/common/env_common.c @@ -140,7 +140,8 @@ uchar default_environment[] = { };
#if defined(CONFIG_ENV_IS_IN_NAND) /* Environment is in Nand Flash */ \ - || defined(CONFIG_ENV_IS_IN_SPI_FLASH) + || defined(CONFIG_ENV_IS_IN_SPI_FLASH) \ + || defined(CONFIG_ENV_IS_IN_SDCARD) int default_environment_size = sizeof(default_environment); #endif
diff --git a/common/env_sdcard.c b/common/env_sdcard.c new file mode 100644 index 0000000..1afcbbb --- /dev/null +++ b/common/env_sdcard.c @@ -0,0 +1,129 @@ + /* + * Copyright (C) 2009 Freescale Semiconductor, Inc. All rights reserved. + * Author: Jason.jin jason.jin@freescale.com + * + * Changelog: + * July 2008, Intial version. + * March 2009, Use the MMC framework's read/write function. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This file is only used for booting from SD card, During the + * booting up process, the environments was reading into memory + * together with the u-boot images. The environments locate + * from the last 8K of the 512k special version u-boot image. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include <common.h> +#include <mmc.h> + +#ifdef CONFIG_ENV_IS_IN_SDCARD + +#include <environment.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define SD_BLK_SIZE 512 + +/* references to names in env_common.c */ +extern uchar default_environment[]; +extern int default_environment_size; + +char *env_name_spec = "SD CARD"; +env_t *env_ptr; + +uchar env_get_char_spec(int index) +{ + return *((uchar *)(gd->env_addr + index)); +} + +int saveenv(void) +{ + int env_blknr, env_blkcnt; + int code_offset, code_len, env_addr; + uchar tmp_buf[512]; + int n, tmp_crc; + struct mmc *mmc = find_mmc_device(0); + + mmc_init(mmc); + + /* read out the first block, get the config data information */ + env_blknr = 0; + env_blkcnt = 1; + n = mmc->block_dev.block_read(0, env_blknr, env_blkcnt, tmp_buf); + if (n != env_blkcnt) + return 1; + + /* Get the Source Address, from offset 0x50 */ + code_offset = *(unsigned long *)(tmp_buf + 0x50); + + /* Get the code size from offset 0x48, the size incude the env size 8K */ + code_len = *(unsigned long *)(tmp_buf + 0x48); + env_addr = code_offset + code_len - CONFIG_ENV_SIZE; + + env_blknr = env_addr / SD_BLK_SIZE; + env_blkcnt = CONFIG_ENV_SIZE / SD_BLK_SIZE; + + n = mmc->block_dev.block_write(0, env_blknr, env_blkcnt, env_ptr); + if (n != env_blkcnt) + return 1; + + puts("done\n"); + return 0; +} + +void env_relocate_spec(void) +{ + /*Just copy to relocate place*/ + memcpy((u8 *)env_ptr, (u8 *)CONFIG_ENV_ADDR_IN_RAM, CONFIG_ENV_SIZE); + + if (crc32(0, env_ptr->data, ENV_SIZE) != env_ptr->crc) { + puts("*** Warning - bad CRC, using default environment\n\n"); + + if (default_environment_size > CONFIG_ENV_SIZE) { + gd->env_valid = 0; + puts("*** Error - default environment is too large\n\n"); + return; + } + + memset(env_ptr, 0, sizeof(env_t)); + memcpy(env_ptr->data, default_environment, default_environment_size); + env_ptr->crc = crc32(0, env_ptr->data, ENV_SIZE); + } + gd->env_valid = 1; +} + +int env_init(void) +{ + /* The ROM code has copied the u-boot and the env to RAM + * But we need to know if there're env settings there by crc check + */ + + env_t *env_ptr_tmp = (env_t *)CONFIG_ENV_ADDR_IN_RAM; + if (crc32(0, env_ptr_tmp->data, ENV_SIZE) == env_ptr_tmp->crc) { + gd->env_addr = (ulong)&(env_ptr_tmp->data); + gd->env_valid = 1; + return 0; + } + + gd->env_addr = (ulong)&default_environment[0]; + gd->env_valid = 0; + return 0; +} + +#endif /* CONFIG_ENV_IS_IN_SDCARD */

MPC8536DS offer booting from SDcard or SPI flash. When after booting from SD card/SPI flash, the environment variables can to be saved on it, so this patch should be used together with the MMC driver and eSPI controller/SPI flash driver in u-boot.
Signed-off-by: Mingkai Hu Mingkai.hu@freescale.com --- include/configs/MPC8536DS.h | 43 +++++++++++++++++++++++++++++++++++++------ 1 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/include/configs/MPC8536DS.h b/include/configs/MPC8536DS.h index b19f028..974e432 100644 --- a/include/configs/MPC8536DS.h +++ b/include/configs/MPC8536DS.h @@ -366,6 +366,19 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); #define CONFIG_SYS_EEPROM_BUS_NUM 1
/* + * eSPI - Enhanced SPI + */ +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_SPANSION + +#define CONFIG_HARD_SPI +#define CONFIG_FSL_ESPI + +#define CONFIG_CMD_SF +#define CONFIG_SF_DEFAULT_SPEED 10000000 +#define CONFIG_SF_DEFAULT_MODE 0 + +/* * General PCI * Memory space is mapped 1-1, but I/O space must start from 0. */ @@ -507,14 +520,32 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); /* * Environment */ -#define CONFIG_ENV_IS_IN_FLASH 1 -#if CONFIG_SYS_MONITOR_BASE > 0xfff80000 -#define CONFIG_ENV_ADDR 0xfff80000 +#if !defined(CONFIG_SDCARD_U_BOOT) + #define CONFIG_ENV_IS_IN_FLASH 1 + #if CONFIG_SYS_MONITOR_BASE > 0xfff80000 + #define CONFIG_ENV_ADDR 0xfff80000 + #else + #define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SECT_SIZE) + #endif + #define CONFIG_ENV_SIZE 0x2000 + #define CONFIG_ENV_SECT_SIZE 0x20000 /* 128K (one sector) */ #else -#define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SECT_SIZE) +#ifdef CONFIG_SPIFLASH_U_BOOT + #define CONFIG_ENV_IS_IN_SPI_FLASH 1 + #define CONFIG_ENV_SPI_BUS 0 + #define CONFIG_ENV_SPI_CS 0 + #define CONFIG_ENV_SPI_MAX_HZ 10000000 + #define CONFIG_ENV_SPI_MODE 0 + #define CONFIG_ENV_SIZE 0x2000 /* 8KB */ + #define CONFIG_ENV_OFFSET 0x100000 /* 1MB */ + #define CONFIG_ENV_SECT_SIZE 0x10000 +#else + #define CONFIG_ENV_IS_IN_SDCARD 1 + #define CONFIG_ENV_SIZE 0x2000 + /*env located after the u-boot image, size is 8K*/ + #define CONFIG_ENV_ADDR_IN_RAM ((TEXT_BASE - 0x1000) + 0x80000) +#endif #endif -#define CONFIG_ENV_SIZE 0x2000 -#define CONFIG_ENV_SECT_SIZE 0x20000 /* 128K (one sector) */
#define CONFIG_LOADS_ECHO 1 /* echo on for serial download */ #define CONFIG_SYS_LOADS_BAUD_CHANGE 1 /* allow baudrate change */

Dear Mingkai Hu,
In message 1237171943-11938-7-git-send-email-Mingkai.hu@freescale.com you wrote:
MPC8536DS offer booting from SDcard or SPI flash. When after booting from SD card/SPI flash, the environment variables can to be saved on it, so this patch should be used together with the MMC driver and eSPI controller/SPI flash driver in u-boot.
Signed-off-by: Mingkai Hu Mingkai.hu@freescale.com
...
+#if !defined(CONFIG_SDCARD_U_BOOT)
...
Please swap cases and use positive logic.
Best regards,
Wolfgang Denk

On Sunday 15 March 2009 22:52:22 Mingkai Hu wrote:
When after booting from SDcard, the environment variables can to be saved on it, this patch add the operation support.
so your board treats the SD storage as a raw block ? you cant actually put a filesystem on it or what ? considering SD cards are most often partitioned & formatted as FAT, this seems really weird ... -mike

Dear Mingkai Hu,
In message 1237171943-11938-5-git-send-email-Mingkai.hu@freescale.com you wrote:
This patch is used to generate a special version u-boot, together with the data structure on the SDcard/SPI flash, can be used to booting from SDcard/SPI flash on 8536DS board.
The boot ROM in CPU and the data structure on SD card will initialize the DDR, set a large tlb0 for DDR and CCSR, set law0 for DDR. The special version uboot avoid initializing the DDR. Try to reseve the law0 for DDR by adding a CONFIG_SYS_RESERVED_LAW0 macro for the "dynamic law allocation" code. But keep the original tlb initialize code for DDR, disabled the large tlb0 which was set in the boot ROM.
This patch is intend for those who are interested in the function of booting from SD card on 8536DS board and not for opensource.
-------------------------------------------^^^^^^^^^^^^^^^^^^^^
Can you please explain what exactly this is supposed to mean?
An utility is needed to write the data structure and the special version u-boot onto the SD card which has filesystem on it or onto the SPI flash.
Cannot this be done with U-Boot, or with Linux running on any other system that das a SDCard reader/writer attached to it?
@@ -2360,6 +2360,18 @@ ATUM8548_config: unconfig MPC8536DS_config: unconfig @$(MKCONFIG) $(@:_config=) ppc mpc85xx mpc8536ds freescale
+MPC8536DS_SPIFLASH_config \ +MPC8536DS_SDCARD_config: unconfig
- @echo "" >$(obj)include/config.h;
- @if [ "$(findstring _SPIFLASH_,$@)" ] ; then \
echo "#define CONFIG_SPIFLASH_U_BOOT" >> $(obj)include/config.h ; \
- fi ;
- @echo "#define CONFIG_SDCARD_U_BOOT" >> $(obj)include/config.h ;
- @$(MKCONFIG) -a MPC8536DS ppc mpc85xx mpc8536ds freescale ; \
echo "TEXT_BASE = 0x11001000" > $(obj)board/freescale/mpc8536ds/config.tmp ; \
echo "#define CONFIG_SDCARD_U_BOOT" >> $(obj)include/config.h ; \
echo "CONFIG_SDCARD_U_BOOT = y" >> $(obj)include/config.mk ;
Please do noty swamp the top level Makefile with configuration options for one board.
diff --git a/board/freescale/mpc8536ds/tlb.c b/board/freescale/mpc8536ds/tlb.c index 35a13d4..cb570ef 100644 --- a/board/freescale/mpc8536ds/tlb.c +++ b/board/freescale/mpc8536ds/tlb.c @@ -27,6 +27,8 @@ #include <asm/mmu.h>
struct fsl_e_tlb_entry tlb_table[] = {
+#if !defined(CONFIG_SDCARD_U_BOOT) /* TLB 0 - for temp stack in cache */ SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR, CONFIG_SYS_INIT_RAM_ADDR, MAS3_SX|MAS3_SW|MAS3_SR, 0, @@ -40,6 +42,7 @@ struct fsl_e_tlb_entry tlb_table[] = { SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024 , CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024,
Line length. [I know this is old code, anyway...]
+} diff --git a/config.mk b/config.mk index b1254e9..3300b75 100644 --- a/config.mk +++ b/config.mk @@ -112,8 +112,8 @@ DBGFLAGS= -g # -DDEBUG OPTFLAGS= -Os #-fomit-frame-pointer ifndef LDSCRIPT #LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug -ifeq ($(CONFIG_NAND_U_BOOT),y) -LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds +ifeq ($(CONFIG_SDCARD_U_BOOT),y) +LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-sdboot.lds else LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds endif
Is it absolutely necessary to set this in the top level config.mk file?
diff --git a/cpu/mpc85xx/cpu_init.c b/cpu/mpc85xx/cpu_init.c index 0b7c609..f2fd168 100644 --- a/cpu/mpc85xx/cpu_init.c +++ b/cpu/mpc85xx/cpu_init.c @@ -1,5 +1,9 @@ /*
- Copyright 2007 Freescale Semiconductor.
- Copyright (C) 2007,2009 Freescale Semiconductor, Inc.
- (C) 2009 Freescale Semiconductor, Inc.
- Modified by Jason Jin, Jason.jin@freescale.com,
Mingkai hu, Mingkai.hu@freescale.com
Please do not add such "Modified by" comments. We use git to track the history of changes.
+#if (CONFIG_SYS_CCSRBAR_DEFAULT != CONFIG_SYS_CCSRBAR_PHYS)
- {
u32 temp;
temp = in_be32((volatile u32 *)CONFIG_SYS_CCSRBAR_DEFAULT);
out_be32((volatile u32 *)CONFIG_SYS_CCSRBAR_DEFAULT, CONFIG_SYS_CCSRBAR_PHYS >> 12);
Line length.
-#ifdef CONFIG_SYS_RAMBOOT +#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SDCARD_U_BOOT)
Please create a new config name to invoid an ever growing list of ...||...||...||...
+#if !defined(CONFIG_SDCARD_U_BOOT) bl cpu_init_early_f +#else
- bl cpu_init_early_f_sd
- /*Then switch to space 1*/
- lis r3,(MSR_CE|MSR_ME|MSR_DE|MSR_IS|MSR_DS)@h
- ori r3,r3,(MSR_CE|MSR_ME|MSR_DE|MSR_IS|MSR_DS)@l
- mtmsr r3
- isync
- msync
- bl cpu_init_early_f_sd_continue
+#endif
Please swap cases and use positive logic instead.
diff --git a/include/configs/MPC8536DS.h b/include/configs/MPC8536DS.h index bbb448d..b19f028 100644 --- a/include/configs/MPC8536DS.h +++ b/include/configs/MPC8536DS.h @@ -116,7 +116,7 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); #define CONFIG_SYS_SPD_BUS_NUM 1
/* These are used when DDR doesn't use SPD. */ -#define CONFIG_SYS_SDRAM_SIZE 256 /* DDR is 256MB */ +#define CONFIG_SYS_SDRAM_SIZE 512 /* DDR is 512MB */
Line length.
#define CONFIG_SYS_DDR_CS0_BNDS 0x0000001F #define CONFIG_SYS_DDR_CS0_CONFIG 0x80010102 /* Enable, no interleaving */ #define CONFIG_SYS_DDR_TIMING_3 0x00000000 @@ -235,9 +235,15 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy); #define PIXIS_VCLKL 0x1A /* VELA VCLKL register */ #define CONFIG_SYS_PIXIS_VBOOT_MASK 0xc0
+#if !defined(CONFIG_SDCARD_U_BOOT) #define CONFIG_SYS_INIT_RAM_LOCK 1 #define CONFIG_SYS_INIT_RAM_ADDR 0xffd00000 /* Initial L1 address */ #define CONFIG_SYS_INIT_RAM_END 0x00004000 /* End of used area in RAM */ +#else +#undef CONFIG_SYS_INIT_RAM_LOCK +#define CONFIG_SYS_INIT_RAM_ADDR 0x07d00000 /* unused memory region */ +#define CONFIG_SYS_INIT_RAM_END 0x4000 /* we have SDRAM initialized */
Line length.
Best regards,
Wolfgang Denk

-----Original Message----- From: Wolfgang Denk [mailto:wd@denx.de] Sent: Monday, March 16, 2009 4:56 PM To: Hu Mingkai-B21284 Cc: Fleming Andy-AFLEMING; u-boot@lists.denx.de; Jin Zhengxiong-R64188 Subject: Re: [U-Boot] [PATCH 5/7] Make a special uboot used for booting from SDcard or SPI flash
Dear Mingkai Hu,
In message 1237171943-11938-5-git-send-email-Mingkai.hu@freescale.com you wrote:
This patch is used to generate a special version u-boot,
together with
the data structure on the SDcard/SPI flash, can be used to booting from SDcard/SPI flash on 8536DS board.
The boot ROM in CPU and the data structure on SD card will
initialize
the DDR, set a large tlb0 for DDR and CCSR, set law0 for DDR. The special version uboot avoid initializing the DDR. Try to reseve the law0 for DDR by adding a CONFIG_SYS_RESERVED_LAW0 macro for
the "dynamic law allocation"
code. But keep the original tlb initialize code for DDR,
disabled the
large tlb0 which was set in the boot ROM.
This patch is intend for those who are interested in the
function of
booting from SD card on 8536DS board and not for opensource.
-------------------------------------------^^^^^^^^^^^^^^^^^^^^
Can you please explain what exactly this is supposed to mean?
Oh, it should be deleted :-)
An utility is needed to write the data structure and the special version u-boot onto the SD card which has filesystem on it
or onto the
SPI flash.
Cannot this be done with U-Boot, or with Linux running on any other system that das a SDCard reader/writer attached to it?
It's hard to do that, in order to support booting from the SDCard, we place the data structure onto the unused space on the MBR on the SDCard.
@@ -2360,6 +2360,18 @@ ATUM8548_config: unconfig MPC8536DS_config: unconfig @$(MKCONFIG) $(@:_config=) ppc mpc85xx mpc8536ds freescale
+MPC8536DS_SPIFLASH_config \ +MPC8536DS_SDCARD_config: unconfig
- @echo "" >$(obj)include/config.h;
- @if [ "$(findstring _SPIFLASH_,$@)" ] ; then \
echo "#define CONFIG_SPIFLASH_U_BOOT" >>
$(obj)include/config.h ; \
- fi ;
- @echo "#define CONFIG_SDCARD_U_BOOT" >> $(obj)include/config.h ;
- @$(MKCONFIG) -a MPC8536DS ppc mpc85xx mpc8536ds freescale ; \
echo "TEXT_BASE = 0x11001000" >
$(obj)board/freescale/mpc8536ds/config.tmp ; \
echo "#define CONFIG_SDCARD_U_BOOT" >>
$(obj)include/config.h ; \
echo "CONFIG_SDCARD_U_BOOT = y" >>
$(obj)include/config.mk ;
Please do noty swamp the top level Makefile with configuration options for one board.
Could you give me some suggestion? ;-) Where is the proper position to handle this?
diff --git a/board/freescale/mpc8536ds/tlb.c b/board/freescale/mpc8536ds/tlb.c index 35a13d4..cb570ef 100644 --- a/board/freescale/mpc8536ds/tlb.c +++ b/board/freescale/mpc8536ds/tlb.c @@ -27,6 +27,8 @@ #include <asm/mmu.h>
struct fsl_e_tlb_entry tlb_table[] = {
+#if !defined(CONFIG_SDCARD_U_BOOT) /* TLB 0 - for temp stack in cache */ SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR,
CONFIG_SYS_INIT_RAM_ADDR,
MAS3_SX|MAS3_SW|MAS3_SR, 0,
@@ -40,6 +42,7 @@ struct fsl_e_tlb_entry tlb_table[] = { SET_TLB_ENTRY(0, CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024 , CONFIG_SYS_INIT_RAM_ADDR + 12 * 1024,
Line length. [I know this is old code, anyway...]
Ok, I'll fix the line length issue.
+} diff --git a/config.mk b/config.mk index b1254e9..3300b75 100644 --- a/config.mk +++ b/config.mk @@ -112,8 +112,8 @@ DBGFLAGS= -g # -DDEBUG OPTFLAGS= -Os #-fomit-frame-pointer ifndef LDSCRIPT #LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug -ifeq ($(CONFIG_NAND_U_BOOT),y) -LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds +ifeq ($(CONFIG_SDCARD_U_BOOT),y) +LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-sdboot.lds else LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds endif
Is it absolutely necessary to set this in the top level config.mk file?
Maybe combined with u-boot.lds.
+#if !defined(CONFIG_SDCARD_U_BOOT) bl cpu_init_early_f +#else
- bl cpu_init_early_f_sd
- /*Then switch to space 1*/
- lis r3,(MSR_CE|MSR_ME|MSR_DE|MSR_IS|MSR_DS)@h
- ori r3,r3,(MSR_CE|MSR_ME|MSR_DE|MSR_IS|MSR_DS)@l
- mtmsr r3
- isync
- msync
- bl cpu_init_early_f_sd_continue
+#endif
Please swap cases and use positive logic instead.
Oh, thanks, I'll fix it.
Best regards,
Wolfgang Denk
-- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de Sometimes, too long is too long. - Joe Crowe
Thanks, Mingkai

Dear "Hu Mingkai-B21284",
In message 73839B4A0818E747864426270AC332C303E411DE@zmy16exm20.fsl.freescale.net you wrote:
Cannot this be done with U-Boot, or with Linux running on any other system that das a SDCard reader/writer attached to it?
It's hard to do that, in order to support booting from the SDCard, we place the data structure onto the unused space on the MBR on the SDCard.
What exactly is the difficault part there?
Reading and modifying the MBR is just like reading or writing any other block on the device. Where is the problem?
@@ -2360,6 +2360,18 @@ ATUM8548_config: unconfig MPC8536DS_config: unconfig @$(MKCONFIG) $(@:_config=) ppc mpc85xx mpc8536ds freescale
+MPC8536DS_SPIFLASH_config \ +MPC8536DS_SDCARD_config: unconfig
- @echo "" >$(obj)include/config.h;
- @if [ "$(findstring _SPIFLASH_,$@)" ] ; then \
echo "#define CONFIG_SPIFLASH_U_BOOT" >>
$(obj)include/config.h ; \
- fi ;
- @echo "#define CONFIG_SDCARD_U_BOOT" >> $(obj)include/config.h ;
- @$(MKCONFIG) -a MPC8536DS ppc mpc85xx mpc8536ds freescale ; \
echo "TEXT_BASE = 0x11001000" >
$(obj)board/freescale/mpc8536ds/config.tmp ; \
echo "#define CONFIG_SDCARD_U_BOOT" >>
$(obj)include/config.h ; \
echo "CONFIG_SDCARD_U_BOOT = y" >>
$(obj)include/config.mk ;
Please do noty swamp the top level Makefile with configuration options for one board.
Could you give me some suggestion? ;-) Where is the proper position to handle this?
Options if a board has (or uses) SPI flash and/or a SDCard and/or other things belong into the board config file. It makes no sense to provide long lists of make targets and then again long code to analyze these options in the top level Makefile. For example, above code would not allow for the case that a customer wants to use a board with SPI flash *and* SDCard - it covers only the *or* case. And no, please do not attempt to add even more such targets. This is not the way to go. It doesn't scale.
Assume each of the hundrets of boards would add code like this.
--- a/config.mk +++ b/config.mk @@ -112,8 +112,8 @@ DBGFLAGS= -g # -DDEBUG OPTFLAGS= -Os #-fomit-frame-pointer ifndef LDSCRIPT #LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug -ifeq ($(CONFIG_NAND_U_BOOT),y) -LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds +ifeq ($(CONFIG_SDCARD_U_BOOT),y) +LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-sdboot.lds else LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds endif
Is it absolutely necessary to set this in the top level config.mk file?
Maybe combined with u-boot.lds.
Or moved to a processor or board specific config.mk.
Best regards,
Wolfgang Denk

On Tue, Mar 17, 2009 at 01:30:38PM +0100, Wolfgang Denk wrote:
Options if a board has (or uses) SPI flash and/or a SDCard and/or other things belong into the board config file. It makes no sense to provide long lists of make targets and then again long code to analyze these options in the top level Makefile. For example, above code would not allow for the case that a customer wants to use a board with SPI flash *and* SDCard - it covers only the *or* case. And no, please do not attempt to add even more such targets. This is not the way to go. It doesn't scale.
Unless I'm mistaken, those targets aren't for boards that merely *have* such things, but are trying to boot from the device in question, similar to the alternate configs for booting from NAND.
Assume each of the hundrets of boards would add code like this.
That's why we need kconfig. :-)
But until then...
-Scott

Dear Scott Wood,
In message 20090318171535.GB3314@loki.buserror.net you wrote:
Unless I'm mistaken, those targets aren't for boards that merely *have* such things, but are trying to boot from the device in question, similar to the alternate configs for booting from NAND.
Assume each of the hundrets of boards would add code like this.
That's why we need kconfig. :-)
But until then...
...we should limit the number of make targets per board and not let grow it out of bound in an unreasonable way.
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
Dear Scott Wood,
In message 20090318171535.GB3314@loki.buserror.net you wrote:
Unless I'm mistaken, those targets aren't for boards that merely *have* such things, but are trying to boot from the device in question, similar to the alternate configs for booting from NAND.
Assume each of the hundrets of boards would add code like this.
That's why we need kconfig. :-)
But until then...
...we should limit the number of make targets per board and not let grow it out of bound in an unreasonable way.
You'd rather tell the user they can't boot from a given device because it would clutter the makefile?
-Scott

Dear Scott,
In message 49C1522D.904@freescale.com you wrote:
You'd rather tell the user they can't boot from a given device because it would clutter the makefile?
Select it in the board config file?
Best regards,
Wolfgang Denk

Wolfgang Denk wrote:
Dear Scott,
In message 49C1522D.904@freescale.com you wrote:
You'd rather tell the user they can't boot from a given device because it would clutter the makefile?
Select it in the board config file?
So the options are: 1. Make the user hand-edit the board config file, 2. Duplicate the board config file, or 3. Put up with a little clutter in the makefile until a better system is put into place -- and hopefully the clutter will serve as encouragement for this to actually happen. :-)
I'm not sure which of #1 or #2 you're advocating, but I much prefer #3.
-Scott

Dear Scott Wood,
In message 49C15672.2000502@freescale.com you wrote:
So the options are:
- Make the user hand-edit the board config file,
- Duplicate the board config file, or
- Put up with a little clutter in the makefile until a better system is
put into place -- and hopefully the clutter will serve as encouragement for this to actually happen. :-)
I'm not sure which of #1 or #2 you're advocating, but I much prefer #3.
I'm seeing a pretty strong and growing tendency for Freescale boards to have 30+ lines entries in the Makefile. This is something that must stop.
If you want to handle this typo through Makefile configuration, then at least write much shorter code.
Best regards,
Wolfgang Denk

Hi Wolfgang,
First truly sorry for the long time delay. I'm not on purpose.
I reworked this patch and unified the implementation of booting from NAND/SDCard/SPI flash for MPC85xx platform, and sent to the U-Boot list on August: http://lists.denx.de/pipermail/u-boot/2009-August/058803.html
Also we tried a method that not to swamp the top level Makefile with different configuration options. Hope you can find some time to give some comments.
Please find comments inline about this patch.
-----Original Message----- From: Wolfgang Denk [mailto:wd@denx.de] Sent: Tuesday, March 17, 2009 8:31 PM To: Hu Mingkai-B21284 Cc: Fleming Andy-AFLEMING; u-boot@lists.denx.de; Subject: Re: [U-Boot] [PATCH 5/7] Make a special uboot used for booting from SDcard or SPI flash
Dear "Hu Mingkai-B21284",
In message <73839B4A0818E747864426270AC332C303E411DE@zmy16exm20.fsl.frees cale.net> you wrote:
Cannot this be done with U-Boot, or with Linux running on
any other
system that das a SDCard reader/writer attached to it?
It's hard to do that, in order to support booting from the
SDCard, we
place the data structure onto the unused space on the MBR on the SDCard.
What exactly is the difficault part there?
Reading and modifying the MBR is just like reading or writing any other block on the device. Where is the problem?
Yes, you're right. We just need to put the specific info to the assigned address.
@@ -2360,6 +2360,18 @@ ATUM8548_config: unconfig MPC8536DS_config: unconfig @$(MKCONFIG) $(@:_config=) ppc mpc85xx
mpc8536ds freescale
+MPC8536DS_SPIFLASH_config \ +MPC8536DS_SDCARD_config: unconfig
- @echo "" >$(obj)include/config.h;
- @if [ "$(findstring _SPIFLASH_,$@)" ] ; then \
echo "#define CONFIG_SPIFLASH_U_BOOT" >>
$(obj)include/config.h ; \
- fi ;
- @echo "#define CONFIG_SDCARD_U_BOOT" >>
$(obj)include/config.h ;
- @$(MKCONFIG) -a MPC8536DS ppc mpc85xx mpc8536ds
freescale ; \
echo "TEXT_BASE = 0x11001000" >
$(obj)board/freescale/mpc8536ds/config.tmp ; \
echo "#define CONFIG_SDCARD_U_BOOT" >>
$(obj)include/config.h ; \
echo "CONFIG_SDCARD_U_BOOT = y" >>
$(obj)include/config.mk ;
Please do noty swamp the top level Makefile with configuration options for one board.
Could you give me some suggestion? ;-) Where is the proper
position to
handle this?
Options if a board has (or uses) SPI flash and/or a SDCard and/or other things belong into the board config file. It makes no sense to provide long lists of make targets and then again long code to analyze these options in the top level Makefile. For example, above code would not allow for the case that a customer wants to use a board with SPI flash *and* SDCard - it covers only the *or* case. And no, please do not attempt to add even more such targets. This is not the way to go. It doesn't scale.
Assume each of the hundrets of boards would add code like this.
So we add another option (-t) on the mkconfig file to parse the target to individual targets, and put them to config.h and config.mk, then leave the board config file and board makefile to handle the different options. http://lists.denx.de/pipermail/u-boot/2009-August/058804.html
Really need your suggestions.
--- a/config.mk +++ b/config.mk @@ -112,8 +112,8 @@ DBGFLAGS= -g # -DDEBUG OPTFLAGS= -Os #-fomit-frame-pointer ifndef LDSCRIPT #LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds.debug -ifeq ($(CONFIG_NAND_U_BOOT),y) -LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-nand.lds +ifeq ($(CONFIG_SDCARD_U_BOOT),y) +LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot-sdboot.lds else LDSCRIPT := $(TOPDIR)/board/$(BOARDDIR)/u-boot.lds endif
Is it absolutely necessary to set this in the top level config.mk file?
Maybe combined with u-boot.lds.
Or moved to a processor or board specific config.mk.
Reused the u-boot.lds for booting from SDCard/SPI flash.
Best regards,
Wolfgang Denk
Sorry again for the delayed response.
Many thanks, Mingkai

On 10:52 Mon 16 Mar , Mingkai Hu wrote:
Add eSPI controller support under the SPI framework.
Signed-off-by: Mingkai Hu Mingkai.hu@freescale.com
drivers/mtd/spi/spi_flash.c | 94 +++++++++++++++++- drivers/spi/Makefile | 1 + drivers/spi/fsl_espi.c | 232 +++++++++++++++++++++++++++++++++++++++++++ include/spi.h | 30 ++++++ 4 files changed, 354 insertions(+), 3 deletions(-) create mode 100644 drivers/spi/fsl_espi.c
please use the spi framework, their is no need to touch the spi_flash support ti add and use the fsl_espi
Best Regards, J.

On Monday 16 March 2009 02:15:27 Jean-Christophe PLAGNIOL-VILLARD wrote:
On 10:52 Mon 16 Mar , Mingkai Hu wrote:
Add eSPI controller support under the SPI framework.
Signed-off-by: Mingkai Hu Mingkai.hu@freescale.com
drivers/mtd/spi/spi_flash.c | 94 +++++++++++++++++- drivers/spi/Makefile | 1 + drivers/spi/fsl_espi.c | 232 +++++++++++++++++++++++++++++++++++++++++++ include/spi.h | 30 ++++++ 4 files changed, 354 insertions(+), 3 deletions(-) create mode 100644 drivers/spi/fsl_espi.c
please use the spi framework, their is no need to touch the spi_flash support ti add and use the fsl_espi
indeed ... i was so happy to see the spansion driver i glossed over this ... those spi_flash.c changes are almost assuredly wrong and indicate you arent fitting into the framework correctly. -mike

-----Original Message----- From: Mike Frysinger [mailto:vapier@gentoo.org] Sent: Monday, March 16, 2009 3:28 PM To: u-boot@lists.denx.de Cc: Jean-Christophe PLAGNIOL-VILLARD; Hu Mingkai-B21284; Fleming Andy-AFLEMING Subject: Re: [U-Boot] [PATCH 3/7] eSPI: add eSPI controller support
On Monday 16 March 2009 02:15:27 Jean-Christophe PLAGNIOL-VILLARD wrote:
On 10:52 Mon 16 Mar , Mingkai Hu wrote:
Add eSPI controller support under the SPI framework.
Signed-off-by: Mingkai Hu Mingkai.hu@freescale.com
drivers/mtd/spi/spi_flash.c | 94 +++++++++++++++++- drivers/spi/Makefile | 1 + drivers/spi/fsl_espi.c | 232 +++++++++++++++++++++++++++++++++++++++++++ include/spi.h
|
30 ++++++ 4 files changed, 354 insertions(+), 3 deletions(-) create mode 100644 drivers/spi/fsl_espi.c
please use the spi framework, their is no need to touch the
spi_flash
support ti add and use the fsl_espi
indeed ... i was so happy to see the spansion driver i glossed over this ... those spi_flash.c changes are almost assuredly wrong and indicate you arent fitting into the framework correctly. -mike
There is difference between the SPI and eSPI chip select signal. Generally, the SPI chip select is controlled by GPIO, so SW can control when to assert the chip select signal and when to stop the chip select signal. But the eSPI controller integrate the chip select into the controller itself, it use the transfer length to control the duration of the chip select signal.
The spi_flash_cmd_* function split the transfer into two steps: first the command transfer and then the data transfer. At the first step, the transfer length is set to the command length, and when transferred the command, the chip select will be negated, so the eSPI controller thinks the transfer is cancelled and doesn't transfer the data again.
I'm in a dilemma on this issue and really need your suggestion :-)
Thanks, Mingkai

On Monday 16 March 2009 04:56:22 Hu Mingkai-B21284 wrote:
From: Mike Frysinger [mailto:vapier@gentoo.org]
On Monday 16 March 2009 02:15:27 Jean-Christophe wrote:
On 10:52 Mon 16 Mar , Mingkai Hu wrote:
Add eSPI controller support under the SPI framework.
Signed-off-by: Mingkai Hu Mingkai.hu@freescale.com
drivers/mtd/spi/spi_flash.c | 94 +++++++++++++++++- drivers/spi/Makefile | 1 + drivers/spi/fsl_espi.c | 232 +++++++++++++++++++++++++++++++++++++++++++ include/spi.h
30 ++++++ 4 files changed, 354 insertions(+), 3 deletions(-) create mode 100644 drivers/spi/fsl_espi.c
please use the spi framework, their is no need to touch the spi_flash support ti add and use the fsl_espi
indeed ... i was so happy to see the spansion driver i glossed over this ... those spi_flash.c changes are almost assuredly wrong and indicate you arent fitting into the framework correctly.
There is difference between the SPI and eSPI chip select signal. Generally, the SPI chip select is controlled by GPIO, so SW can control when to assert the chip select signal and when to stop the chip select signal.
that is incorrect. the SPI framework does not care how the controller manages the CS. the Blackfin SPI controller for example has dedicated CS's which the controller manages automatically.
But the eSPI controller integrate the chip select into the controller itself, it use the transfer length to control the duration of the chip select signal.
so you must tell the controller ahead of time how many bytes are going to be transferred ? this sounds like a retarded hardware implementation to me. how exactly do you support arbitrary transfer lengths ?
The spi_flash_cmd_* function split the transfer into two steps: first the command transfer and then the data transfer. At the first step, the transfer length is set to the command length, and when transferred the command, the chip select will be negated, so the eSPI controller thinks the transfer is cancelled and doesn't transfer the data again.
the transfer state is passed in via the flags parameter. this way the SPI controller knows when a transfer starts (SPI_XFER_BEGIN) and when it ends (SPI_XFER_END). -mike

Hi Mike,
First truly sorry for the long time delay. Please find comments inline.
-----Original Message----- From: Mike Frysinger [mailto:vapier@gentoo.org] Sent: Monday, March 16, 2009 6:06 PM To: Hu Mingkai-B21284 Cc: u-boot@lists.denx.de; Jean-Christophe PLAGNIOL-VILLARD; Fleming Andy-AFLEMING Subject: Re: [U-Boot] [PATCH 3/7] eSPI: add eSPI controller support
On Monday 16 March 2009 04:56:22 Hu Mingkai-B21284 wrote:
From: Mike Frysinger [mailto:vapier@gentoo.org]
On Monday 16 March 2009 02:15:27 Jean-Christophe wrote:
On 10:52 Mon 16 Mar , Mingkai Hu wrote:
Add eSPI controller support under the SPI framework.
Signed-off-by: Mingkai Hu Mingkai.hu@freescale.com
drivers/mtd/spi/spi_flash.c | 94 +++++++++++++++++- drivers/spi/Makefile | 1 + drivers/spi/fsl_espi.c | 232 +++++++++++++++++++++++++++++++++++++++++++ include/spi.h
30 ++++++ 4 files changed, 354 insertions(+), 3 deletions(-)
create mode
100644 drivers/spi/fsl_espi.c
please use the spi framework, their is no need to touch the spi_flash support ti add and use the fsl_espi
indeed ... i was so happy to see the spansion driver i
glossed over
this ... those spi_flash.c changes are almost assuredly wrong and indicate you arent fitting into the framework correctly.
There is difference between the SPI and eSPI chip select signal. Generally, the SPI chip select is controlled by GPIO, so SW can control when to assert the chip select signal and when to stop the chip select signal.
that is incorrect. the SPI framework does not care how the controller manages the CS. the Blackfin SPI controller for example has dedicated CS's which the controller manages automatically.
But the eSPI controller integrate the chip select into the
controller
itself, it use the transfer length to control the duration
of the chip
select signal.
so you must tell the controller ahead of time how many bytes are going to be transferred ? this sounds like a retarded hardware implementation to me. how exactly do you support arbitrary transfer lengths ?
IIRC every transaction byte length control every transaction.
The spi_flash_cmd_* function split the transfer into two
steps: first
the command transfer and then the data transfer. At the first step, the transfer length is set to the command length, and when
transferred
the command, the chip select will be negated, so the eSPI
controller
thinks the transfer is cancelled and doesn't transfer the
data again.
the transfer state is passed in via the flags parameter. this way the SPI controller knows when a transfer starts (SPI_XFER_BEGIN) and when it ends (SPI_XFER_END). -mike
As above, we can't use the start/end flags parameter.
Sorry again for the delayed response.
Many thanks, Mingkai

On Wednesday 26 August 2009 23:01:52 Hu Mingkai-B21284 wrote:
From: Mike Frysinger [mailto:vapier@gentoo.org]
On Monday 16 March 2009 04:56:22 Hu Mingkai-B21284 wrote:
But the eSPI controller integrate the chip select into the controller itself, it use the transfer length to control the duration of the chip select signal.
so you must tell the controller ahead of time how many bytes are going to be transferred ? this sounds like a retarded hardware implementation to me. how exactly do you support arbitrary transfer lengths ?
IIRC every transaction byte length control every transaction.
but what if you dont know the length of the transaction ahead of time ? if you look at the spi flash framework, it'll write a few bytes (like the opcode to read the status register) and then it'll just keep reading 1 byte at a time (polling the status register). there is no way of knowing the length ahead of time. most of the SPI code in u-boot operates this way.
The spi_flash_cmd_* function split the transfer into two steps: first the command transfer and then the data transfer. At the first step, the transfer length is set to the command length, and when transferred the command, the chip select will be negated, so the eSPI controller thinks the transfer is cancelled and doesn't transfer the data again.
the transfer state is passed in via the flags parameter. this way the SPI controller knows when a transfer starts (SPI_XFER_BEGIN) and when it ends (SPI_XFER_END).
As above, we can't use the start/end flags parameter.
then your controller wont be able to work with most (any?) of the code in u- boot. you need to reject every transfer that isnt done with both BEGIN and END flags set. -mike

-----Original Message----- From: u-boot-bounces@lists.denx.de [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Mike Frysinger Sent: Thursday, August 27, 2009 1:54 PM To: Hu Mingkai-B21284 Cc: u-boot@lists.denx.de; Fleming Andy-AFLEMING Subject: Re: [U-Boot] [PATCH 3/7] eSPI: add eSPI controller support
On Wednesday 26 August 2009 23:01:52 Hu Mingkai-B21284 wrote:
From: Mike Frysinger [mailto:vapier@gentoo.org]
On Monday 16 March 2009 04:56:22 Hu Mingkai-B21284 wrote:
But the eSPI controller integrate the chip select into the controller itself, it use the transfer length to control the duration of the chip select signal.
so you must tell the controller ahead of time how many bytes are going to be transferred ? this sounds like a retarded hardware implementation to me. how exactly do you support
arbitrary transfer
lengths ?
IIRC every transaction byte length control every transaction.
but what if you dont know the length of the transaction ahead of time ? if you look at the spi flash framework, it'll write a few bytes (like the opcode to read the status register) and then it'll just keep reading 1 byte at a time (polling the status register). there is no way of knowing the length ahead of time. most of the SPI code in u-boot operates this way.
So the driver use the length passed by SPI flash read function. If the length is greater than the max value that is limited by the transaction length register's bitfiled, the driver couldn't read anything. We'll dig into this issue for the furture.
The spi_flash_cmd_* function split the transfer into two steps: first the command transfer and then the data transfer. At the first step, the transfer length is set to the command
length, and
when transferred the command, the chip select will be
negated, so
the eSPI controller thinks the transfer is cancelled
and doesn't transfer the data again.
the transfer state is passed in via the flags parameter. this way the SPI controller knows when a transfer starts (SPI_XFER_BEGIN) and when it ends (SPI_XFER_END).
As above, we can't use the start/end flags parameter.
then your controller wont be able to work with most (any?) of the code in u- boot. you need to reject every transfer that snt done with both BEGIN and END flags set.
Looks like now.
-mike
Thanks, Mingkai

On Thursday 27 August 2009 02:27:30 Hu Mingkai-B21284 wrote:
but what if you dont know the length of the transaction ahead of time ? if you look at the spi flash framework, it'll write a few bytes (like the opcode to read the status register) and then it'll just keep reading 1 byte at a time (polling the status register). there is no way of knowing the length ahead of time. most of the SPI code in u-boot operates this way.
So the driver use the length passed by SPI flash read function. If the length is greater than the max value that is limited by the transaction length register's bitfiled, the driver couldn't read anything.
the length used by the first read covers just the length of the opcode, not any of the data returned by the part
as long as your driver rejects all of these things, it'll be detected at runtime and it should be fine to merge -mike

-----Original Message----- From: Mike Frysinger [mailto:vapier@gentoo.org] Sent: Thursday, August 27, 2009 2:43 PM To: Hu Mingkai-B21284 Cc: u-boot@lists.denx.de; Fleming Andy-AFLEMING Subject: Re: [U-Boot] [PATCH 3/7] eSPI: add eSPI controller support
On Thursday 27 August 2009 02:27:30 Hu Mingkai-B21284 wrote:
but what if you dont know the length of the transaction ahead of time ? if you look at the spi flash framework, it'll write a few bytes (like the opcode to read the status register) and then it'll just keep reading 1 byte at a
time (polling
the status register). there is no way of knowing the
length ahead
of time. most of the SPI code in u-boot operates this way.
So the driver use the length passed by SPI flash read function. If the length is greater than the max value that is limited by the transaction length register's bitfiled, the driver couldn't read anything.
the length used by the first read covers just the length of the opcode, not any of the data returned by the part
as long as your driver rejects all of these things, it'll be detected at runtime and it should be fine to merge -mike
So the driver combine the opcode length and the data length together, then pass to spi_xfer(for eSPI) . When return the read results, skip the first opcode length bytes.
Thanks, Mingkai

On Thursday 27 August 2009 02:59:34 Hu Mingkai-B21284 wrote:
From: Mike Frysinger [mailto:vapier@gentoo.org]
On Thursday 27 August 2009 02:27:30 Hu Mingkai-B21284 wrote:
but what if you dont know the length of the transaction ahead of time ? if you look at the spi flash framework, it'll write a few bytes (like the opcode to read the status register) and then it'll just keep reading 1 byte at a time (polling the status register). there is no way of knowing the length ahead of time. most of the SPI code in u-boot operates this way.
So the driver use the length passed by SPI flash read function. If the length is greater than the max value that is limited by the transaction length register's bitfiled, the driver couldn't read anything.
the length used by the first read covers just the length of the opcode, not any of the data returned by the part
as long as your driver rejects all of these things, it'll be detected at runtime and it should be fine to merge -mike
So the driver combine the opcode length and the data length together, then pass to spi_xfer(for eSPI) . When return the read results, skip the first opcode length bytes.
you dont get it ... there is no data length. the code does:
spi_write(~3 bytes for opcode, BEGIN flag); while (1) { spi_read(read 1 data byte); check_result(); } end_spi_transaction();
there is no "data length" which means your controller cannot support the SPI flash framework -mike

-----Original Message----- From: Mike Frysinger [mailto:vapier@gentoo.org] Sent: Thursday, August 27, 2009 3:23 PM To: Hu Mingkai-B21284 Cc: u-boot@lists.denx.de; Fleming Andy-AFLEMING Subject: Re: [U-Boot] [PATCH 3/7] eSPI: add eSPI controller support
On Thursday 27 August 2009 02:59:34 Hu Mingkai-B21284 wrote:
From: Mike Frysinger [mailto:vapier@gentoo.org]
On Thursday 27 August 2009 02:27:30 Hu Mingkai-B21284 wrote:
but what if you dont know the length of the
transaction ahead of
time ? if you look at the spi flash framework, it'll write a few bytes (like the opcode to read the status register) and then it'll just keep reading 1 byte at a time (polling the status register). there is no way of
knowing the
length ahead of time. most of the SPI code in u-boot
operates this way.
So the driver use the length passed by SPI flash read function. If the length is greater than the max value that is
limited by the
transaction length register's bitfiled, the driver
couldn't read
anything.
the length used by the first read covers just the length of the opcode, not any of the data returned by the part
as long as your driver rejects all of these things, it'll be detected at runtime and it should be fine to merge -mike
So the driver combine the opcode length and the data length
together,
then pass to spi_xfer(for eSPI) . When return the read
results, skip
the first opcode length bytes.
you dont get it ... there is no data length. the code does:
spi_write(~3 bytes for opcode, BEGIN flag); while (1) { spi_read(read 1 data byte); check_result(); } end_spi_transaction();
there is no "data length" which means your controller cannot support the SPI flash framework -mike
Sorry for the confusion, "the dirver" in my word refers to this patch that adds eSPI controller support. You're right, the controller can't support the SPI framework, that's the reason why this patch comes here. :-)
Thanks, Mingkai

diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index d1d81af..fa97896 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -1,6 +1,8 @@ /*
- SPI flash interface
- Add support for Freescale eSPI controller
*/
- Copyright (C) 2009 Freescale Semiconductor, Inc.
- Copyright (C) 2008 Atmel Corporation
Ummm ... call me crazy ... but this doesn't seem proper to me.
--Scott

On Sunday 15 March 2009 22:52:18 Mingkai Hu wrote:
Add MTD SPI Flash support for S25FL008A, S25FL016A, S25FL032A, S25FL064A, S25FL128P.
this doesnt really need to be part of this patch series and can be added all by itself
--- a/drivers/mtd/spi/Makefile +++ b/drivers/mtd/spi/Makefile @@ -28,6 +28,7 @@ LIB := $(obj)libspi_flash.a COBJS-$(CONFIG_SPI_FLASH) += spi_flash.o COBJS-$(CONFIG_SPI_FLASH_ATMEL) += atmel.o COBJS-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.o +COBJS-$(CONFIG_SPI_FLASH_SPANSION) += spansion.o
this should be above stmicro -- keep it sorted
also, the += is supposed to be indented with a tab, not spaces -mike

-----Original Message----- From: Mike Frysinger [mailto:vapier@gentoo.org] Sent: Monday, March 16, 2009 12:38 PM To: u-boot@lists.denx.de Cc: Hu Mingkai-B21284; Fleming Andy-AFLEMING Subject: Re: [U-Boot] [PATCH 2/7] mtd: SPI Flash: Support the Spansion Flash
On Sunday 15 March 2009 22:52:18 Mingkai Hu wrote:
Add MTD SPI Flash support for S25FL008A, S25FL016A, S25FL032A, S25FL064A, S25FL128P.
this doesnt really need to be part of this patch series and can be added all by itself
--- a/drivers/mtd/spi/Makefile +++ b/drivers/mtd/spi/Makefile @@ -28,6 +28,7 @@ LIB := $(obj)libspi_flash.a COBJS-$(CONFIG_SPI_FLASH) += spi_flash.o COBJS-$(CONFIG_SPI_FLASH_ATMEL) += atmel.o COBJS-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.o +COBJS-$(CONFIG_SPI_FLASH_SPANSION) += spansion.o
this should be above stmicro -- keep it sorted
also, the += is supposed to be indented with a tab, not spaces -mike
Thanks, I'll fix it.
Best Regards, Mingkai

On Monday 16 March 2009 02:23:50 Hu Mingkai-B21284 wrote:
From: Mike Frysinger [mailto:vapier@gentoo.org]
On Sunday 15 March 2009 22:52:18 Mingkai Hu wrote:
Add MTD SPI Flash support for S25FL008A, S25FL016A, S25FL032A, S25FL064A, S25FL128P.
this doesnt really need to be part of this patch series and can be added all by itself
--- a/drivers/mtd/spi/Makefile +++ b/drivers/mtd/spi/Makefile @@ -28,6 +28,7 @@ LIB := $(obj)libspi_flash.a COBJS-$(CONFIG_SPI_FLASH) += spi_flash.o COBJS-$(CONFIG_SPI_FLASH_ATMEL) += atmel.o COBJS-$(CONFIG_SPI_FLASH_STMICRO) += stmicro.o +COBJS-$(CONFIG_SPI_FLASH_SPANSION) += spansion.o
this should be above stmicro -- keep it sorted
also, the += is supposed to be indented with a tab, not spaces -mike
Thanks, I'll fix it.
can you post an updated spansion flash driver ? it can be merged independently of the eSPI patch series and it'd be good to get it merged sooner so i can push the sf patches without conflicts ... -mike

On Sunday 15 March 2009 22:52:18 Mingkai Hu wrote:
+int spansion_erase(struct spi_flash *flash, u32 offset, size_t len) +{ +...
ret = spansion_wait_ready(flash, 2 * CONFIG_SYS_HZ);
there is a common define you should use instead: SPI_FLASH_PAGE_ERASE_TIMEOUT -mike

-----Original Message----- From: Mike Frysinger [mailto:vapier@gentoo.org] Sent: Tuesday, March 31, 2009 9:12 AM To: u-boot@lists.denx.de Cc: Hu Mingkai-B21284; Fleming Andy-AFLEMING Subject: Re: [U-Boot] [PATCH 2/7] mtd: SPI Flash: Support the Spansion Flash
On Sunday 15 March 2009 22:52:18 Mingkai Hu wrote:
+int spansion_erase(struct spi_flash *flash, u32 offset,
size_t len) {
+...
ret = spansion_wait_ready(flash, 2 * CONFIG_SYS_HZ);
there is a common define you should use instead: SPI_FLASH_PAGE_ERASE_TIMEOUT -mike
Thanks, Mike, I'll fix it.
Best Regards, Mingkai
participants (7)
-
Hu Mingkai-B21284
-
Jean-Christophe PLAGNIOL-VILLARD
-
Mike Frysinger
-
Mingkai Hu
-
Scott McNutt
-
Scott Wood
-
Wolfgang Denk