fsmc.h revision 6c009ab89a212b4364cdb74192d438f542fb291c
16c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij/* 26c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * incude/mtd/fsmc.h 36c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * 46c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * ST Microelectronics 56c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * Flexible Static Memory Controller (FSMC) 66c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * platform data interface and header file 76c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * 86c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * Copyright © 2010 ST Microelectronics 96c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * Vipin Kumar <vipin.kumar@st.com> 106c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * 116c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * This file is licensed under the terms of the GNU General Public 126c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * License version 2. This program is licensed "as is" without any 136c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * warranty of any kind, whether express or implied. 146c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij */ 156c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 166c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#ifndef __MTD_FSMC_H 176c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define __MTD_FSMC_H 186c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 196c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#include <linux/platform_device.h> 206c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#include <linux/mtd/physmap.h> 216c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#include <linux/types.h> 226c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#include <linux/mtd/partitions.h> 236c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#include <asm/param.h> 246c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 256c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_NAND_BW8 1 266c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_NAND_BW16 2 276c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 286c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij/* 296c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * The placement of the Command Latch Enable (CLE) and 306c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * Address Latch Enable (ALE) is twised around in the 316c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * SPEAR310 implementation. 326c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij */ 336c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#if defined(CONFIG_MACH_SPEAR310) 346c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define PLAT_NAND_CLE (1 << 17) 356c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define PLAT_NAND_ALE (1 << 16) 366c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#else 376c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define PLAT_NAND_CLE (1 << 16) 386c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define PLAT_NAND_ALE (1 << 17) 396c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#endif 406c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 416c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_MAX_NOR_BANKS 4 426c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_MAX_NAND_BANKS 4 436c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 446c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_FLASH_WIDTH8 1 456c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_FLASH_WIDTH16 2 466c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 476c009ab89a212b4364cdb74192d438f542fb291cLinus Walleijstruct fsmc_nor_bank_regs { 486c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t ctrl; 496c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t ctrl_tim; 506c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij}; 516c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 526c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij/* ctrl register definitions */ 536c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define BANK_ENABLE (1 << 0) 546c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define MUXED (1 << 1) 556c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define NOR_DEV (2 << 2) 566c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define WIDTH_8 (0 << 4) 576c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define WIDTH_16 (1 << 4) 586c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define RSTPWRDWN (1 << 6) 596c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define WPROT (1 << 7) 606c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define WRT_ENABLE (1 << 12) 616c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define WAIT_ENB (1 << 13) 626c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 636c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij/* ctrl_tim register definitions */ 646c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 656c009ab89a212b4364cdb74192d438f542fb291cLinus Walleijstruct fsms_nand_bank_regs { 666c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t pc; 676c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t sts; 686c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t comm; 696c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t attrib; 706c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t ioata; 716c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t ecc1; 726c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t ecc2; 736c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t ecc3; 746c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij}; 756c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 766c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_NOR_REG_SIZE 0x40 776c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 786c009ab89a212b4364cdb74192d438f542fb291cLinus Walleijstruct fsmc_regs { 796c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij struct fsmc_nor_bank_regs nor_bank_regs[FSMC_MAX_NOR_BANKS]; 806c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint8_t reserved_1[0x40 - 0x20]; 816c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij struct fsms_nand_bank_regs bank_regs[FSMC_MAX_NAND_BANKS]; 826c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint8_t reserved_2[0xfe0 - 0xc0]; 836c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t peripid0; /* 0xfe0 */ 846c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t peripid1; /* 0xfe4 */ 856c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t peripid2; /* 0xfe8 */ 866c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t peripid3; /* 0xfec */ 876c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t pcellid0; /* 0xff0 */ 886c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t pcellid1; /* 0xff4 */ 896c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t pcellid2; /* 0xff8 */ 906c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint32_t pcellid3; /* 0xffc */ 916c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij}; 926c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 936c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_BUSY_WAIT_TIMEOUT (1 * HZ) 946c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 956c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij/* pc register definitions */ 966c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_RESET (1 << 0) 976c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_WAITON (1 << 1) 986c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_ENABLE (1 << 2) 996c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_DEVTYPE_NAND (1 << 3) 1006c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_DEVWID_8 (0 << 4) 1016c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_DEVWID_16 (1 << 4) 1026c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_ECCEN (1 << 6) 1036c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_ECCPLEN_512 (0 << 7) 1046c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_ECCPLEN_256 (1 << 7) 1056c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_TCLR_1 (1 << 9) 1066c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_TAR_1 (1 << 13) 1076c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 1086c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij/* sts register definitions */ 1096c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_CODE_RDY (1 << 15) 1106c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 1116c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij/* comm register definitions */ 1126c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_TSET_0 (0 << 0) 1136c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_TWAIT_6 (6 << 8) 1146c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_THOLD_4 (4 << 16) 1156c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_THIZ_1 (1 << 24) 1166c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 1176c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij/* peripid2 register definitions */ 1186c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_REVISION_MSK (0xf) 1196c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_REVISION_SHFT (0x4) 1206c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 1216c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_VER1 1 1226c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_VER2 2 1236c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_VER3 3 1246c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_VER4 4 1256c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_VER5 5 1266c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_VER6 6 1276c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_VER7 7 1286c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define FSMC_VER8 8 1296c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 1306c009ab89a212b4364cdb74192d438f542fb291cLinus Walleijstatic inline uint32_t get_fsmc_version(struct fsmc_regs *regs) 1316c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij{ 1326c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij return (readl(®s->peripid2) >> FSMC_REVISION_SHFT) & 1336c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij FSMC_REVISION_MSK; 1346c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij} 1356c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 1366c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij/* 1376c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * There are 13 bytes of ecc for every 512 byte block in FSMC version 8 1386c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * and it has to be read consecutively and immediately after the 512 1396c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * byte data block for hardware to generate the error bit offsets 1406c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * Managing the ecc bytes in the following way is easier. This way is 1416c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * similar to oobfree structure maintained already in u-boot nand driver 1426c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij */ 1436c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#define MAX_ECCPLACE_ENTRIES 32 1446c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 1456c009ab89a212b4364cdb74192d438f542fb291cLinus Walleijstruct fsmc_nand_eccplace { 1466c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint8_t offset; 1476c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij uint8_t length; 1486c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij}; 1496c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 1506c009ab89a212b4364cdb74192d438f542fb291cLinus Walleijstruct fsmc_eccplace { 1516c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij struct fsmc_nand_eccplace eccplace[MAX_ECCPLACE_ENTRIES]; 1526c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij}; 1536c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 1546c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij/** 1556c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * fsmc_nand_platform_data - platform specific NAND controller config 1566c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * @partitions: partition table for the platform, use a default fallback 1576c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * if this is NULL 1586c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * @nr_partitions: the number of partitions in the previous entry 1596c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * @options: different options for the driver 1606c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * @width: bus width 1616c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * @bank: default bank 1626c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * @select_bank: callback to select a certain bank, this is 1636c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * platform-specific. If the controller only supports one bank 1646c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij * this may be set to NULL 1656c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij */ 1666c009ab89a212b4364cdb74192d438f542fb291cLinus Walleijstruct fsmc_nand_platform_data { 1676c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij struct mtd_partition *partitions; 1686c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij unsigned int nr_partitions; 1696c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij unsigned int options; 1706c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij unsigned int width; 1716c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij unsigned int bank; 1726c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij void (*select_bank)(uint32_t bank, uint32_t busw); 1736c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij}; 1746c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 1756c009ab89a212b4364cdb74192d438f542fb291cLinus Walleijextern int __init fsmc_nor_init(struct platform_device *pdev, 1766c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij unsigned long base, uint32_t bank, uint32_t width); 1776c009ab89a212b4364cdb74192d438f542fb291cLinus Walleijextern void __init fsmc_init_board_info(struct platform_device *pdev, 1786c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij struct mtd_partition *partitions, unsigned int nr_partitions, 1796c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij unsigned int width); 1806c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij 1816c009ab89a212b4364cdb74192d438f542fb291cLinus Walleij#endif /* __MTD_FSMC_H */ 182