Commit 586667b4 authored by Alexander Dyachenko's avatar Alexander Dyachenko Committed by Sergei Poselenov

RM 1947: Copy the newer mmc and fsl_esdhc drivers from the Vybrid U-Boot repository

(cherry picked from commit 85502fd1becd71b365b71f4a8fd308ae4953025e)
parent bdf130d6
This diff is collapsed.
This diff is collapsed.
...@@ -54,4 +54,15 @@ static inline void invalidate_l2_cache(void) ...@@ -54,4 +54,15 @@ static inline void invalidate_l2_cache(void)
void l2_cache_enable(void); void l2_cache_enable(void);
void l2_cache_disable(void); void l2_cache_disable(void);
/*
* The current upper bound for ARM L1 data cache line sizes is 64 bytes. We
* use that value for aligning DMA buffers unless the board config has specified
* an alternate cache line size.
*/
#ifdef CONFIG_SYS_CACHELINE_SIZE
#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE
#else
#define ARCH_DMA_MINALIGN 64
#endif
#endif /* _ASM_CACHE_H */ #endif /* _ASM_CACHE_H */
...@@ -790,4 +790,70 @@ int cpu_release(int nr, int argc, char *argv[]); ...@@ -790,4 +790,70 @@ int cpu_release(int nr, int argc, char *argv[]);
#define ALIGN(x,a) __ALIGN_MASK((x),(typeof(x))(a)-1) #define ALIGN(x,a) __ALIGN_MASK((x),(typeof(x))(a)-1)
#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
/*
* ARCH_DMA_MINALIGN is defined in asm/cache.h for each architecture. It
* is used to align DMA buffers.
*/
#ifndef __ASSEMBLY__
#include <asm/cache.h>
#endif
/*
* The ALLOC_CACHE_ALIGN_BUFFER macro is used to allocate a buffer on the
* stack that meets the minimum architecture alignment requirements for DMA.
* Such a buffer is useful for DMA operations where flushing and invalidating
* the cache before and after a read and/or write operation is required for
* correct operations.
*
* When called the macro creates an array on the stack that is sized such
* that:
*
* 1) The beginning of the array can be advanced enough to be aligned.
*
* 2) The size of the aligned portion of the array is a multiple of the minimum
* architecture alignment required for DMA.
*
* 3) The aligned portion contains enough space for the original number of
* elements requested.
*
* The macro then creates a pointer to the aligned portion of this array and
* assigns to the pointer the address of the first element in the aligned
* portion of the array.
*
* Calling the macro as:
*
* ALLOC_CACHE_ALIGN_BUFFER(uint32_t, buffer, 1024);
*
* Will result in something similar to saying:
*
* uint32_t buffer[1024];
*
* The following differences exist:
*
* 1) The resulting buffer is guaranteed to be aligned to the value of
* ARCH_DMA_MINALIGN.
*
* 2) The buffer variable created by the macro is a pointer to the specified
* type, and NOT an array of the specified type. This can be very important
* if you want the address of the buffer, which you probably do, to pass it
* to the DMA hardware. The value of &buffer is different in the two cases.
* In the macro case it will be the address of the pointer, not the address
* of the space reserved for the buffer. However, in the second case it
* would be the address of the buffer. So if you are replacing hard coded
* stack buffers with this macro you need to make sure you remove the & from
* the locations where you are taking the address of the buffer.
*
* Note that the size parameter is the number of array elements to allocate,
* not the number of bytes.
*
* This macro can not be used outside of function scope, or for the creation
* of a function scoped static buffer. It can not be used to create a cache
* line aligned global buffer.
*/
#define ALLOC_CACHE_ALIGN_BUFFER(type, name, size) \
char __##name[ROUND(size * sizeof(type), ARCH_DMA_MINALIGN) + \
ARCH_DMA_MINALIGN - 1]; \
\
type *name = (type *) ALIGN((uintptr_t)__##name, ARCH_DMA_MINALIGN)
#endif /* __COMMON_H_ */ #endif /* __COMMON_H_ */
...@@ -16,5 +16,6 @@ ...@@ -16,5 +16,6 @@
#define CONFIG_GZIP 1 #define CONFIG_GZIP 1
#define CONFIG_ZLIB 1 #define CONFIG_ZLIB 1
#define CONFIG_PARTITIONS 1
#endif #endif
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* FSL SD/MMC Defines * FSL SD/MMC Defines
*------------------------------------------------------------------- *-------------------------------------------------------------------
* *
* Copyright 2007-2008, Freescale Semiconductor, Inc * Copyright 2007-2008,2010-2011 Freescale Semiconductor, Inc
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as * modify it under the terms of the GNU General Public License as
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#define SYSCTL_PEREN 0x00000004 #define SYSCTL_PEREN 0x00000004
#define SYSCTL_HCKEN 0x00000002 #define SYSCTL_HCKEN 0x00000002
#define SYSCTL_IPGEN 0x00000001 #define SYSCTL_IPGEN 0x00000001
#define SYSCTL_RSTA 0x01000000
#define IRQSTAT 0x0002e030 #define IRQSTAT 0x0002e030
#define IRQSTAT_DMAE (0x10000000) #define IRQSTAT_DMAE (0x10000000)
...@@ -89,6 +90,7 @@ ...@@ -89,6 +90,7 @@
#define PRSSTAT_CDPL (0x00040000) #define PRSSTAT_CDPL (0x00040000)
#define PRSSTAT_CINS (0x00010000) #define PRSSTAT_CINS (0x00010000)
#define PRSSTAT_BREN (0x00000800) #define PRSSTAT_BREN (0x00000800)
#define PRSSTAT_BWEN (0x00000400)
#define PRSSTAT_DLA (0x00000004) #define PRSSTAT_DLA (0x00000004)
#define PRSSTAT_CICHB (0x00000002) #define PRSSTAT_CICHB (0x00000002)
#define PRSSTAT_CIDHB (0x00000001) #define PRSSTAT_CIDHB (0x00000001)
...@@ -120,6 +122,7 @@ ...@@ -120,6 +122,7 @@
#define XFERTYP_DMAEN 0x00000001 #define XFERTYP_DMAEN 0x00000001
#define CINS_TIMEOUT 1000 #define CINS_TIMEOUT 1000
#define PIO_TIMEOUT 100000
#define DSADDR 0x2e004 #define DSADDR 0x2e004
...@@ -132,6 +135,21 @@ ...@@ -132,6 +135,21 @@
#define WML 0x2e044 #define WML 0x2e044
#define WML_WRITE 0x00010000 #define WML_WRITE 0x00010000
#ifdef CONFIG_FSL_SDHC_V2_3
#define WML_RD_WML_MAX 0x80
#define WML_WR_WML_MAX 0x80
#define WML_RD_WML_MAX_VAL 0x0
#define WML_WR_WML_MAX_VAL 0x0
#define WML_RD_WML_MASK 0x7f
#define WML_WR_WML_MASK 0x7f0000
#else
#define WML_RD_WML_MAX 0x10
#define WML_WR_WML_MAX 0x80
#define WML_RD_WML_MAX_VAL 0x10
#define WML_WR_WML_MAX_VAL 0x80
#define WML_RD_WML_MASK 0xff
#define WML_WR_WML_MASK 0xff0000
#endif
#define BLKATTR 0x2e004 #define BLKATTR 0x2e004
#define BLKATTR_CNT(x) ((x & 0xffff) << 16) #define BLKATTR_CNT(x) ((x & 0xffff) << 16)
...@@ -148,7 +166,6 @@ ...@@ -148,7 +166,6 @@
struct fsl_esdhc_cfg { struct fsl_esdhc_cfg {
u32 esdhc_base; u32 esdhc_base;
u32 no_snoop; u32 no_snoop;
u32 clk_enable;
}; };
/* Select the correct accessors depending on endianess */ /* Select the correct accessors depending on endianess */
......
/* /*
* Copyright 2008, Freescale Semiconductor, Inc * Copyright 2008,2010 Freescale Semiconductor, Inc
* Andy Fleming * Andy Fleming
* *
* Based (loosely) on the Linux code * Based (loosely) on the Linux code
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
...@@ -44,6 +44,8 @@ ...@@ -44,6 +44,8 @@
#define MMC_MODE_HS_52MHz 0x010 #define MMC_MODE_HS_52MHz 0x010
#define MMC_MODE_4BIT 0x100 #define MMC_MODE_4BIT 0x100
#define MMC_MODE_8BIT 0x200 #define MMC_MODE_8BIT 0x200
#define MMC_MODE_SPI 0x400
#define MMC_MODE_HC 0x800
#define SD_DATA_4BIT 0x00040000 #define SD_DATA_4BIT 0x00040000
...@@ -74,13 +76,20 @@ ...@@ -74,13 +76,20 @@
#define MMC_CMD_READ_MULTIPLE_BLOCK 18 #define MMC_CMD_READ_MULTIPLE_BLOCK 18
#define MMC_CMD_WRITE_SINGLE_BLOCK 24 #define MMC_CMD_WRITE_SINGLE_BLOCK 24
#define MMC_CMD_WRITE_MULTIPLE_BLOCK 25 #define MMC_CMD_WRITE_MULTIPLE_BLOCK 25
#define MMC_CMD_ERASE_GROUP_START 35
#define MMC_CMD_ERASE_GROUP_END 36
#define MMC_CMD_ERASE 38
#define MMC_CMD_APP_CMD 55 #define MMC_CMD_APP_CMD 55
#define MMC_CMD_SPI_READ_OCR 58
#define MMC_CMD_SPI_CRC_ON_OFF 59
#define SD_CMD_SEND_RELATIVE_ADDR 3 #define SD_CMD_SEND_RELATIVE_ADDR 3
#define SD_CMD_SWITCH_FUNC 6 #define SD_CMD_SWITCH_FUNC 6
#define SD_CMD_SEND_IF_COND 8 #define SD_CMD_SEND_IF_COND 8
#define SD_CMD_APP_SET_BUS_WIDTH 6 #define SD_CMD_APP_SET_BUS_WIDTH 6
#define SD_CMD_ERASE_WR_BLK_START 32
#define SD_CMD_ERASE_WR_BLK_END 33
#define SD_CMD_APP_SEND_OP_COND 41 #define SD_CMD_APP_SEND_OP_COND 41
#define SD_CMD_APP_SEND_SCR 51 #define SD_CMD_APP_SEND_SCR 51
...@@ -91,8 +100,19 @@ ...@@ -91,8 +100,19 @@
#define MMC_HS_TIMING 0x00000100 #define MMC_HS_TIMING 0x00000100
#define MMC_HS_52MHZ 0x2 #define MMC_HS_52MHZ 0x2
#define OCR_BUSY 0x80000000 #define OCR_BUSY 0x80000000
#define OCR_HCS 0x40000000 #define OCR_HCS 0x40000000
#define OCR_VOLTAGE_MASK 0x007FFF80
#define OCR_ACCESS_MODE 0x60000000
#define SECURE_ERASE 0x80000000
#define MMC_STATUS_MASK (~0x0206BF7F)
#define MMC_STATUS_RDY_FOR_DATA (1 << 8)
#define MMC_STATUS_CURR_STATE (0xf << 9)
#define MMC_STATUS_ERROR (1 << 19)
#define MMC_STATE_PRG (7 << 9)
#define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */ #define MMC_VDD_165_195 0x00000080 /* VDD voltage 1.65 - 1.95 */
#define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */ #define MMC_VDD_20_21 0x00000100 /* VDD voltage 2.0 ~ 2.1 */
...@@ -127,23 +147,26 @@ ...@@ -127,23 +147,26 @@
/* /*
* EXT_CSD fields * EXT_CSD fields
*/ */
#define EXT_CSD_PARTITIONING_SUPPORT 160 /* RO */
#define EXT_CSD_BUS_WIDTH 183 /* R/W */ #define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
#define EXT_CSD_HS_TIMING 185 /* R/W */ #define EXT_CSD_PART_CONF 179 /* R/W */
#define EXT_CSD_CARD_TYPE 196 /* RO */ #define EXT_CSD_BUS_WIDTH 183 /* R/W */
#define EXT_CSD_REV 192 /* RO */ #define EXT_CSD_HS_TIMING 185 /* R/W */
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */ #define EXT_CSD_REV 192 /* RO */
#define EXT_CSD_CARD_TYPE 196 /* RO */
#define EXT_CSD_SEC_CNT 212 /* RO, 4 bytes */
#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
/* /*
* EXT_CSD field definitions * EXT_CSD field definitions
*/ */
#define EXT_CSD_CMD_SET_NORMAL (1<<0) #define EXT_CSD_CMD_SET_NORMAL (1 << 0)
#define EXT_CSD_CMD_SET_SECURE (1<<1) #define EXT_CSD_CMD_SET_SECURE (1 << 1)
#define EXT_CSD_CMD_SET_CPSECURE (1<<2) #define EXT_CSD_CMD_SET_CPSECURE (1 << 2)
#define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */ #define EXT_CSD_CARD_TYPE_26 (1 << 0) /* Card can run at 26MHz */
#define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */ #define EXT_CSD_CARD_TYPE_52 (1 << 1) /* Card can run at 52MHz */
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */ #define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */ #define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
...@@ -153,22 +176,25 @@ ...@@ -153,22 +176,25 @@
#define R1_APP_CMD (1 << 5) #define R1_APP_CMD (1 << 5)
#define MMC_RSP_PRESENT (1 << 0) #define MMC_RSP_PRESENT (1 << 0)
#define MMC_RSP_136 (1 << 1) /* 136 bit response */ #define MMC_RSP_136 (1 << 1) /* 136 bit response */
#define MMC_RSP_CRC (1 << 2) /* expect valid crc */ #define MMC_RSP_CRC (1 << 2) /* expect valid crc */
#define MMC_RSP_BUSY (1 << 3) /* card may send busy */ #define MMC_RSP_BUSY (1 << 3) /* card may send busy */
#define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */ #define MMC_RSP_OPCODE (1 << 4) /* response contains opcode */
#define MMC_RSP_NONE (0) #define MMC_RSP_NONE (0)
#define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) #define MMC_RSP_R1 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R1b (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE| \ #define MMC_RSP_R1b (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE| \
MMC_RSP_BUSY) MMC_RSP_BUSY)
#define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC) #define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC)
#define MMC_RSP_R3 (MMC_RSP_PRESENT) #define MMC_RSP_R3 (MMC_RSP_PRESENT)
#define MMC_RSP_R4 (MMC_RSP_PRESENT) #define MMC_RSP_R4 (MMC_RSP_PRESENT)
#define MMC_RSP_R5 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) #define MMC_RSP_R5 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) #define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) #define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE)
#define MMCPART_NOAVAILABLE (0xff)
#define PART_ACCESS_MASK (0x7)
#define PART_SUPPORT (0x1)
struct mmc_cid { struct mmc_cid {
unsigned long psn; unsigned long psn;
...@@ -179,6 +205,16 @@ struct mmc_cid { ...@@ -179,6 +205,16 @@ struct mmc_cid {
char pnm[7]; char pnm[7];
}; };
/*
* WARNING!
*
* This structure is used by atmel_mci.c only.
* It works for the AVR32 architecture but NOT
* for ARM/AT91 architectures.
* Its use is highly depreciated.
* After the atmel_mci.c driver for AVR32 has
* been replaced this structure will be removed.
*/
struct mmc_csd struct mmc_csd
{ {
u8 csd_structure:2, u8 csd_structure:2,
...@@ -243,6 +279,7 @@ struct mmc { ...@@ -243,6 +279,7 @@ struct mmc {
void *priv; void *priv;
uint voltages; uint voltages;
uint version; uint version;
uint has_init;
uint f_min; uint f_min;
uint f_max; uint f_max;
int high_capacity; int high_capacity;
...@@ -255,26 +292,40 @@ struct mmc { ...@@ -255,26 +292,40 @@ struct mmc {
uint csd[4]; uint csd[4];
uint cid[4]; uint cid[4];
ushort rca; ushort rca;
char part_config;
char part_num;
uint tran_speed; uint tran_speed;
uint read_bl_len; uint read_bl_len;
uint write_bl_len; uint write_bl_len;
uint erase_grp_size;
u64 capacity; u64 capacity;
block_dev_desc_t block_dev; block_dev_desc_t block_dev;
int (*send_cmd)(struct mmc *mmc, int (*send_cmd)(struct mmc *mmc,
struct mmc_cmd *cmd, struct mmc_data *data); struct mmc_cmd *cmd, struct mmc_data *data);
void (*set_ios)(struct mmc *mmc); void (*set_ios)(struct mmc *mmc);
int (*init)(struct mmc *mmc); int (*init)(struct mmc *mmc);
int (*getcd)(struct mmc *mmc);
uint b_max;
}; };
int mmc_register(struct mmc *mmc); int mmc_register(struct mmc *mmc);
int mmc_initialize(bd_t *bis); int mmc_initialize(bd_t *bis);
int mmc_init(struct mmc *mmc); int mmc_init(struct mmc *mmc);
int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size); int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
void mmc_set_clock(struct mmc *mmc, uint clock);
struct mmc *find_mmc_device(int dev_num); struct mmc *find_mmc_device(int dev_num);
int mmc_set_dev(int dev_num);
void print_mmc_devices(char separator); void print_mmc_devices(char separator);
int board_mmc_getcd(u8 *cd, struct mmc *mmc); int get_mmc_num(void);
int board_mmc_getcd(struct mmc *mmc);
#ifndef CONFIG_GENERIC_MMC int mmc_switch_part(int dev_num, unsigned int part_num);
int mmc_getcd(struct mmc *mmc);
#ifdef CONFIG_GENERIC_MMC
#define mmc_host_is_spi(mmc) ((mmc)->host_caps & MMC_MODE_SPI)
struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
#else
int mmc_legacy_init(int verbose); int mmc_legacy_init(int verbose);
#endif #endif
#endif /* _MMC_H_ */ #endif /* _MMC_H_ */
...@@ -49,6 +49,9 @@ typedef struct block_dev_desc { ...@@ -49,6 +49,9 @@ typedef struct block_dev_desc {
unsigned long start, unsigned long start,
lbaint_t blkcnt, lbaint_t blkcnt,
const void *buffer); const void *buffer);
unsigned long (*block_erase)(int dev,
unsigned long start,
lbaint_t blkcnt);
void *priv; /* driver private struct pointer */ void *priv; /* driver private struct pointer */
}block_dev_desc_t; }block_dev_desc_t;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment