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(&regs->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