aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorMike Rapoport <mike@compulab.co.il>2009-02-17 06:54:47 -0500
committerDavid Woodhouse <David.Woodhouse@intel.com>2009-03-20 14:37:44 -0400
commitf271049e2010b918f83dc1c7bbd5d75f4710506a (patch)
treee39389588aa6ea62c23dffddb4f77cf40db44286 /drivers/mtd
parent82a72d108b4fbcc8f651b7c4e34c6f18a605d58d (diff)
[MTD] [NAND] pxa3xx_nand: add ability to keep controller settings defined by OBM/bootloader
Signed-off-by: Mike Rapoport <mike@compulab.co.il> Acked-by: Eric Miao <eric.miao@marvell.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c103
1 files changed, 102 insertions, 1 deletions
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index ead4a7a72d44..2857a6a37b5c 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -171,7 +171,13 @@ static int use_dma = 1;
171module_param(use_dma, bool, 0444); 171module_param(use_dma, bool, 0444);
172MODULE_PARM_DESC(use_dma, "enable DMA for data transfering to/from NAND HW"); 172MODULE_PARM_DESC(use_dma, "enable DMA for data transfering to/from NAND HW");
173 173
174#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN 174/*
175 * Default NAND flash controller configuration setup by the
176 * bootloader. This configuration is used only when pdata->keep_config is set
177 */
178static struct pxa3xx_nand_timing default_timing;
179static struct pxa3xx_nand_flash default_flash;
180
175static struct pxa3xx_nand_cmdset smallpage_cmdset = { 181static struct pxa3xx_nand_cmdset smallpage_cmdset = {
176 .read1 = 0x0000, 182 .read1 = 0x0000,
177 .read2 = 0x0050, 183 .read2 = 0x0050,
@@ -198,6 +204,7 @@ static struct pxa3xx_nand_cmdset largepage_cmdset = {
198 .lock_status = 0x007A, 204 .lock_status = 0x007A,
199}; 205};
200 206
207#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN
201static struct pxa3xx_nand_timing samsung512MbX16_timing = { 208static struct pxa3xx_nand_timing samsung512MbX16_timing = {
202 .tCH = 10, 209 .tCH = 10,
203 .tCS = 0, 210 .tCS = 0,
@@ -297,9 +304,23 @@ static struct pxa3xx_nand_flash *builtin_flash_types[] = {
297#define NDTR1_tWHR(c) (min((c), 15) << 4) 304#define NDTR1_tWHR(c) (min((c), 15) << 4)
298#define NDTR1_tAR(c) (min((c), 15) << 0) 305#define NDTR1_tAR(c) (min((c), 15) << 0)
299 306
307#define tCH_NDTR0(r) (((r) >> 19) & 0x7)
308#define tCS_NDTR0(r) (((r) >> 16) & 0x7)
309#define tWH_NDTR0(r) (((r) >> 11) & 0x7)
310#define tWP_NDTR0(r) (((r) >> 8) & 0x7)
311#define tRH_NDTR0(r) (((r) >> 3) & 0x7)
312#define tRP_NDTR0(r) (((r) >> 0) & 0x7)
313
314#define tR_NDTR1(r) (((r) >> 16) & 0xffff)
315#define tWHR_NDTR1(r) (((r) >> 4) & 0xf)
316#define tAR_NDTR1(r) (((r) >> 0) & 0xf)
317
300/* convert nano-seconds to nand flash controller clock cycles */ 318/* convert nano-seconds to nand flash controller clock cycles */
301#define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) - 1) 319#define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) - 1)
302 320
321/* convert nand flash controller clock cycles to nano-seconds */
322#define cycle2ns(c, clk) ((((c) + 1) * 1000000 + clk / 500) / (clk / 1000))
323
303static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info, 324static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info,
304 const struct pxa3xx_nand_timing *t) 325 const struct pxa3xx_nand_timing *t)
305{ 326{
@@ -921,6 +942,82 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
921 return 0; 942 return 0;
922} 943}
923 944
945static void pxa3xx_nand_detect_timing(struct pxa3xx_nand_info *info,
946 struct pxa3xx_nand_timing *t)
947{
948 unsigned long nand_clk = clk_get_rate(info->clk);
949 uint32_t ndtr0 = nand_readl(info, NDTR0CS0);
950 uint32_t ndtr1 = nand_readl(info, NDTR1CS0);
951
952 t->tCH = cycle2ns(tCH_NDTR0(ndtr0), nand_clk);
953 t->tCS = cycle2ns(tCS_NDTR0(ndtr0), nand_clk);
954 t->tWH = cycle2ns(tWH_NDTR0(ndtr0), nand_clk);
955 t->tWP = cycle2ns(tWP_NDTR0(ndtr0), nand_clk);
956 t->tRH = cycle2ns(tRH_NDTR0(ndtr0), nand_clk);
957 t->tRP = cycle2ns(tRP_NDTR0(ndtr0), nand_clk);
958
959 t->tR = cycle2ns(tR_NDTR1(ndtr1), nand_clk);
960 t->tWHR = cycle2ns(tWHR_NDTR1(ndtr1), nand_clk);
961 t->tAR = cycle2ns(tAR_NDTR1(ndtr1), nand_clk);
962}
963
964static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
965{
966 uint32_t ndcr = nand_readl(info, NDCR);
967 struct nand_flash_dev *type = NULL;
968 uint32_t id = -1;
969 int i;
970
971 default_flash.page_per_block = ndcr & NDCR_PG_PER_BLK ? 64 : 32;
972 default_flash.page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
973 default_flash.flash_width = ndcr & NDCR_DWIDTH_M ? 16 : 8;
974 default_flash.dfc_width = ndcr & NDCR_DWIDTH_C ? 16 : 8;
975
976 if (default_flash.page_size == 2048)
977 default_flash.cmdset = &largepage_cmdset;
978 else
979 default_flash.cmdset = &smallpage_cmdset;
980
981 /* set info fields needed to __readid */
982 info->flash_info = &default_flash;
983 info->read_id_bytes = (default_flash.page_size == 2048) ? 4 : 2;
984 info->reg_ndcr = ndcr;
985
986 if (__readid(info, &id))
987 return -ENODEV;
988
989 /* Lookup the flash id */
990 id = (id >> 8) & 0xff; /* device id is byte 2 */
991 for (i = 0; nand_flash_ids[i].name != NULL; i++) {
992 if (id == nand_flash_ids[i].id) {
993 type = &nand_flash_ids[i];
994 break;
995 }
996 }
997
998 if (!type)
999 return -ENODEV;
1000
1001 /* fill the missing flash information */
1002 i = __ffs(default_flash.page_per_block * default_flash.page_size);
1003 default_flash.num_blocks = type->chipsize << (20 - i);
1004
1005 info->oob_size = (default_flash.page_size == 2048) ? 64 : 16;
1006
1007 /* calculate addressing information */
1008 info->col_addr_cycles = (default_flash.page_size == 2048) ? 2 : 1;
1009
1010 if (default_flash.num_blocks * default_flash.page_per_block > 65536)
1011 info->row_addr_cycles = 3;
1012 else
1013 info->row_addr_cycles = 2;
1014
1015 pxa3xx_nand_detect_timing(info, &default_timing);
1016 default_flash.timing = &default_timing;
1017
1018 return 0;
1019}
1020
924static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info, 1021static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info,
925 const struct pxa3xx_nand_platform_data *pdata) 1022 const struct pxa3xx_nand_platform_data *pdata)
926{ 1023{
@@ -928,6 +1025,10 @@ static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info,
928 uint32_t id = -1; 1025 uint32_t id = -1;
929 int i; 1026 int i;
930 1027
1028 if (pdata->keep_config)
1029 if (pxa3xx_nand_detect_config(info) == 0)
1030 return 0;
1031
931 for (i = 0; i<pdata->num_flash; ++i) { 1032 for (i = 0; i<pdata->num_flash; ++i) {
932 f = pdata->flash + i; 1033 f = pdata->flash + i;
933 1034