blob: 1dd50142190c4af6b2bef9ab02f88f8c152440de [file] [log] [blame]
/*
* drivers/amlogic/mtd/nand_flash.c
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* 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.
*
*/
#include "aml_mtd.h"
#include <linux/mtd/nand.h>
struct aml_nand_flash_dev aml_nand_flash_ids[] = {
{"A revision NAND 2GiB H27UAG8T2A",
{NAND_MFR_HYNIX, 0xd5, 0x94, 0x25, 0x44, 0x41},
4096,
2048,
0x80000,
224,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE)},
{"A revision NAND 4GiB H27UBG8T2A",
{NAND_MFR_HYNIX, 0xd7, 0x94, 0x9a, 0x74, 0x42},
8192,
4096,
0x200000,
448,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE)},
{"B revision NAND 2GiB H27UAG8T2B",
{NAND_MFR_HYNIX, 0xd5, 0x94, 0x9a, 0x74, 0x42},
8192,
2048,
0x200000,
448,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE)},
{"B revision 26nm NAND 4GiB H27UBG8T2B",
{NAND_MFR_HYNIX, 0xd7, 0x94, 0xda, 0x74, 0xc3},
8192,
4096,
0x200000,
640,
1,
16,
15,
0,
HYNIX_26NM_4GB,
/*need readretry, disable two plane mode*/
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"B revision 26nm NAND 8GiB H27UCG8T2M",
{NAND_MFR_HYNIX, 0xde, 0x94, 0xd2, 0x04, 0x43},
8192,
8192,
0x200000,
448,
1,
16,
15,
0,
HYNIX_26NM_8GB,
/*need readretry, disable two plane mode*/
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"C revision 20nm NAND 4GiB H27UBG8T2C",
{NAND_MFR_HYNIX, 0xd7, 0x94, 0x91, 0x60, 0x44},
8192,
4096,
0x200000,
640,
1,
16,
15,
0,
HYNIX_20NM_4GB,
/*need readretry, disable two plane mode*/
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"A revision 20nm NAND 8GiB H27UCG8T2A",
{NAND_MFR_HYNIX, 0xde, 0x94, 0xda, 0x74, 0xc4},
8192,
8192,
0x200000,
640,
1,
16,
15,
0,
HYNIX_20NM_8GB,
/*need readretry, disable two plane mode*/
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"B revision 20nm NAND 8GiB H27UCG8T2B",
{NAND_MFR_HYNIX, 0xde, 0x94, 0xeb, 0x74, 0x44},
16384,
8192,
0x400000,
1280,
1,
16,
15,
0,
HYNIX_20NM_8GB,
/*need readretry, disable two plane mode*/
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"E revision 1ynm NAND 8GiB H27UCG8T2E",
{NAND_MFR_HYNIX, 0xde, 0x14, 0xa7, 0x42, 0x4a},
16384,
8192,
0x400000,
1664,
1,
16,
15,
0,
HYNIX_1YNM_8GB,
/*need readretry, disable two plane mode*/
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"B revision NAND 8GiB MT29F64G08CBABA",
{NAND_MFR_MICRON, 0x64, 0x44, 0x4B, 0xA9},
8192,
8192,
0x200000,
744,
1,
16,
15,
5,
MICRON_20NM,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"D revision NAND 4GiB MT29F32G08CBADA",
{NAND_MFR_MICRON, 0x44, 0x44, 0x4B, 0xA9},
8192,
4096,
0x200000,
744,
1,
16,
15,
5,
MICRON_20NM,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"1 Generation NAND 8GiB JS29F64G08ACMF1",
{NAND_MFR_INTEL, 0x88, 0x24, 0x4b, 0xA9, 0x84},
8192,
8192,
0x200000,
448,
1,
20,
15,
0,
INTEL_20NM,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"A revision NAND 1GiB sF1G-A",
{NAND_MFR_AMD, 0xf1, 0x80, 0x1d, 0x01, 0xf1},
2048,
128,
0x20000,
64,
1,
16,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH12_MODE)},
{"A revision NAND 1GiB sF1G-A",
{NAND_MFR_AMD, 0xf1, 0x0, 0x1d, 0x01, 0xf1},
2048,
128,
0x20000,
64,
1,
16,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE)},
{"A revision NAND 1Gib W29N01GV ",
{NAND_ID_WINBOND, 0xf1, 0x80, 0x95, 0x00, 0x00},
2048,
128,
0x20000,
64,
1,
16,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE)},
{"A revision NAND 2Gib W29N02GV ",
{NAND_ID_WINBOND, 0xda, 0x90, 0x95, 0x04, 0x00},
2048,
256,
0x20000,
64,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE)},
{"A revision NAND 1GiB H27U1G8F2CTR ",
{NAND_MFR_HYNIX, 0xf1, 0x80, 0x1d, 0xad, 0xf1},
2048,
128,
0x20000,
64,
1,
16,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE)},
{"Slc NAND 4Gib MX30LF4G18AC ",
{NAND_MFR_MACRONIX, 0xdc, 0x90, 0x95, 0x56},
2048,
512,
0x20000,
64,
1,
16,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE)},
{"A revision NAND 4Gib EMST ",
{NAND_ID_ESMT, 0xac, 0x90, 0x15, 0x54, 0x7f},
2048,
512,
0x20000,
64,
1,
16,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE)},
{"ESMT SLC 256MiB 3.3V 8-bit",
{NAND_ID_ESMT, 0xda, 0x90, 0x95, 0x44, 0x7f},
2048,
256,
0x20000,
64,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE)},
{"A revision NAND 4Gib TC58NVG1S3HBAI4 ",
{NAND_MFR_TOSHIBA, 0xda, 0x90, 0x15, 0x76},
2048,
256,
0x20000,
64,
1,
20,
25,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE)},
{"A revision NAND 128MB TC58NVG0S3HTA00 ",
{NAND_MFR_TOSHIBA, 0xf1, 0x80, 0x15, 0x72},
2048,
128,
0x20000,
64,
1,
20,
25,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE)},
{"A revision NAND 512MB TC58NVG2S0HBAI6 ",
{NAND_MFR_TOSHIBA, 0xdc, 0x90, 0x26, 0x76},
4096,
512,
0x40000,
256,
1,
20,
25,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE)},
{"A revision NAND 2Gib MT29F2G08-A",
{NAND_MFR_MICRON, 0xda, 0x90, 0x95, 0x06},
2048,
256,
0x20000,
64,
1,
16,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE)},
{"A revision NAND 1GiB MT29F1G-A",
{NAND_MFR_MICRON, 0xf1, 0x80, 0x95, 0x04},
2048,
128,
0x20000,
64,
1,
16,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH12_MODE)},
{"A revision NAND 4GiB MT29F32G-A",
{NAND_MFR_MICRON, 0xd7, 0x94, 0x3e, 0x84},
4096,
4096,
0x80000,
218,
1,
16,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH12_MODE
| NAND_TWO_PLANE_MODE)},
{"A revision NAND 16GiB MT29F128G-A",
{NAND_MFR_MICRON, 0xd9, 0xd5, 0x3e, 0x88},
4096,
16384,
0x80000,
218,
1,
16,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH12_MODE
| NAND_TWO_PLANE_MODE)},
{"B revision NAND 4GiB MT29F32G-B",
{NAND_MFR_MICRON, 0x68, 0x04, 0x46, 0x89},
4096,
4096,
0x100000,
224,
1,
20,
15,
4,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE)},
{"B revision NAND 8GiB MT29F64G-B",
{NAND_MFR_MICRON, 0x88, 0x05, 0xc6, 0x89},
4096,
8192,
0x100000,
224,
1,
20,
15,
4,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE)},
{"C revision NAND 4GiB MT29F32G-C",
{NAND_MFR_MICRON, 0x68, 0x04, 0x4a, 0xa9},
4096,
4096,
0x100000,
224,
1,
16,
15,
5,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE)},
{"C revision NAND 8GiB MT29F64G-C",
{NAND_MFR_MICRON, 0x88, 0x04, 0x4b, 0xa9},
8192,
8192,
0x200000,
448,
1,
16,
15,
5,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE)},
{"C revision NAND 1GiB MT29F8G08ABABA",
{NAND_MFR_MICRON, 0x38, 0x00, 0x26, 0x85},
4096,
1024,
0x80000,
224,
1,
16,
15,
5,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
|NAND_TWO_PLANE_MODE)},
{"C revision NAND 32GiB MT29F256G-C",
{NAND_MFR_MICRON, 0xa8, 0x05, 0xcb, 0xa9},
8192,
16384,
0x200000,
448,
2,
16,
15,
5,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE | NAND_INTERLEAVING_MODE)},
{"1 Generation NAND 4GiB JS29F32G08AA-1",
{NAND_MFR_INTEL, 0x68, 0x04, 0x46, 0xA9},
4096,
4096,
0x100000,
218,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH12_MODE
| NAND_TWO_PLANE_MODE)},
{"1 Generation NAND 8GiB JS29F64G08AA-1",
{NAND_MFR_INTEL, 0x88, 0x24, 0x4b, 0xA9},
8192,
8192,
0x200000,
448,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE)},
{"E serials NAND 2GiB TC58NVG4D2ETA00",
{NAND_MFR_TOSHIBA, 0xD5, 0x94, 0x32, 0x76, 0x54},
8192,
2048,
0x100000,
376,
1,
20,
25,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH12_MODE
| NAND_TWO_PLANE_MODE)},
{"E serials NAND 4GiB TC58NVG5D2ETA00",
{NAND_MFR_TOSHIBA, 0xD7, 0x94, 0x32, 0x76, 0x54},
8192,
4096,
0x100000,
376,
1,
20,
25,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH12_MODE
| NAND_TWO_PLANE_MODE)},
{"F serials NAND 2GiB TC58NVG4D2FTA00",
{NAND_MFR_TOSHIBA, 0xD5, 0x94, 0x32, 0x76, 0x55},
8192,
2076,
0x100000,
448,
1,
20,
25,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE)},
{"F serials NAND 4GiB TC58NVG5D2FTA00",
{NAND_MFR_TOSHIBA, 0xD7, 0x94, 0x32, 0x76, 0x55},
8192,
4096,
0x100000,
448,
1,
20,
25,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE)},
{"F serials NAND 8GiB TC58NVG6D2FTA00",
{NAND_MFR_TOSHIBA, 0xDE, 0x94, 0x32, 0x76, 0x55},
8192,
8192,
0x100000,
448,
1,
20,
25,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE)},
{"F serials NAND 8GiB TH58NVG7D2FTA20",
{NAND_MFR_TOSHIBA, 0xDE, 0x95, 0x32, 0x7a, 0x55},
8192,
8200,
0x100000,
448,
2,
20,
25,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE | NAND_INTERLEAVING_MODE)},
{"F serials NAND 4GiB TC58NVG5D2HTA00",
{NAND_MFR_TOSHIBA, 0xD7, 0x94, 0x32, 0x76, 0x56},
8192,
4096,
0x100000,
640,
1,
20,
25,
0,
TOSHIBA_24NM,
/*need readretry, disable two plane mode*/
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"F serials NAND 8GiB TC58NVG6D2GTA00",
{NAND_MFR_TOSHIBA, 0xDE, 0x94, 0x82, 0x76, 0x56},
8192,
8192,
0x200000,
640,
1,
20,
25,
0,
TOSHIBA_24NM,
/*need readretry, disable two plane mode*/
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"F serials NAND 8GiB TC58TEG6DCJTA00",
{NAND_MFR_TOSHIBA, 0xDE, 0x84, 0x93, 0x72, 0x57},
16384,
8192,
0x400000,
1280,
1,
20,
25,
0,
TOSHIBA_24NM,
/*need readretry, disable two plane mode*/
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"A serials NAND 4GiB TC58TEG5DCJTA00 ",
{NAND_MFR_TOSHIBA, 0xD7, 0x84, 0x93, 0x72, 0x57},
16384,
4096,
0x400000,
1280,
1,
20,
25,
0,
TOSHIBA_24NM,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"A serials NAND 8GiB TC58TEG6DDKTA00 ",
{NAND_MFR_TOSHIBA, 0xDE, 0x94, 0x93, 0x76, 0x50},
16384,
8192,
0x400000,
1280,
1,
16,
15,
0,
TOSHIBA_A19NM,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"A serials NAND 16GiB TC58TEG7DCJTA00 ",
{NAND_MFR_TOSHIBA, 0xa3, 0x85, 0x93, 0x76, 0x57},
16384,
16384,
0x400000,
1280,
2,
20,
25,
0,
TOSHIBA_24NM,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"A serials NAND 8GiB SDTNQGAMA-008G ",
{NAND_MFR_SANDISK, 0xDE, 0x94, 0x93, 0x76, 0x57},
16384,
8192,
0x400000,
1280,
1,
20,
25,
0,
SANDISK_19NM,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"A serials NAND 4GiB SDTNQGAMA-004G ",
{NAND_MFR_SANDISK, 0xD7, 0x84, 0x93, 0x72, 0x57},
16384,
4096,
0x400000,
1280,
1,
20,
25,
0,
SANDISK_19NM,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"A serials NAND 8GiB SDTNPMAHEM-008G ",
{NAND_MFR_SANDISK, 0xDE, 0xA4, 0x82, 0x76, 0x56},
8192,
8192,
0x200000,
640,
1,
20,
25,
0,
SANDISK_24NM,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"A serials NAND 8GiB SDTNRGAMA-008G ",
{NAND_MFR_SANDISK, 0xDE, 0x94, 0x93, 0x76, 0x50},
16384,
8192,
0x400000,
1280,
1,
20,
25,
0,
SANDISK_A19NM,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"M Generation NAND 4Gib K9F4G08U0D",
{NAND_MFR_SAMSUNG, 0xDC, 0x10, 0x95, 0x54, 0XEC,},
2048,
512,
0x20000,
64,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE)},
{"M Generation NAND 2GiB K9GAG08U0M",
{NAND_MFR_SAMSUNG, 0xD5, 0x14, 0xb6, 0x74},
4096,
2048,
0x80000,
128,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH8_MODE)},
{"5 Generation NAND 2GiB K9GAG08X0D",
{NAND_MFR_SAMSUNG, 0xD5, 0x94, 0x29, 0x34, 0x41},
4096,
2048,
0x80000,
218,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH12_MODE
| NAND_TWO_PLANE_MODE)},
{"6 Generation NAND 2GiB K9GAG08U0E",
{NAND_MFR_SAMSUNG, 0xD5, 0x84, 0x72, 0x50, 0x42},
8192,
2048,
0x100000,
436,
1,
25,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH12_MODE)},
{"7 Generation NAND 2GiB K9GAG08U0F",
{NAND_MFR_SAMSUNG, 0xD5, 0x94, 0x76, 0x54, 0x43},
8192,
2048,
0x100000,
512,
1,
25,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE)},
{"6 Generation NAND 4GiB K9LBG08U0E",
{NAND_MFR_SAMSUNG, 0xD7, 0xC5, 0x72, 0x54, 0x42},
8192,
4096,
0x100000,
436,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH12_MODE
| NAND_TWO_PLANE_MODE)},
{"6 Generation NAND 8GiB K9HCG08U0E",
{NAND_MFR_SAMSUNG, 0xDE, 0xC5, 0x72, 0x54, 0x42},
8192,
8192,
0x100000,
436,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH12_MODE
| NAND_TWO_PLANE_MODE)},
{"2 Generation NAND 4GiB K9GBG08U0A",
{NAND_MFR_SAMSUNG, 0xD7, 0x94, 0x7a, 0x54, 0x43},
8192,
4152,
0x100000,
640,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE)},
{"2 Generation NAND 8GiB K9LCG08U0A",
{NAND_MFR_SAMSUNG, 0xDE, 0xD5, 0x7a, 0x58, 0x43},
8192,
8304,
0x100000,
640,
2,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE
| NAND_TWO_PLANE_MODE | NAND_INTERLEAVING_MODE)},
{"2 Generation NAND 4GiB K9GBG08U0B",
{NAND_MFR_SAMSUNG, 0xD7, 0x94, 0x7e, 0x64, 0x44},
8192,
4096,
0x100000,
640,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{"2 Generation NAND 8GiB K9LCG08U0B",
{NAND_MFR_SAMSUNG, 0xDE, 0xD5, 0x7e, 0x68, 0x44},
8192,
8192,
0x100000,
640,
1,
20,
15,
0,
0,
(NAND_TIMING_MODE5 | NAND_ECC_BCH16_MODE)},
{NULL,}
};
/* ******************** */
#ifdef CONFIG_PARAMETER_PAGE
struct parameter_page para_page;
void aml_nand_read_parameter_page(struct mtd_info *mtd, int ce, char *buf)
{
struct nand_chip *chip = mtd->priv;
NFC_SEND_CMD(ce | CLE | 0xec);
NFC_SEND_CMD(ce | ALE | 0x00);
NFC_SEND_CMD(ce | IDLE | 5);
signed long i, count;
memset(buf, 0, 256);
for (i = 0, count = 0; i < 256 && count < 256; i++) {
*buf = chip->read_byte(mtd);
if ((i == 0) && (*buf != 0x4f)) {
i = -1;
count++;
continue;
}
buf++;
}
}
void display_para_page(struct parameter_page para_page, unsigned long log_level)
{
unsigned long i;
signed long j;
unsigned char *buf = (unsigned char *)&para_page;
pr_info("\nNand parameter page:\n");
if ((para_page.signature[0] != 0x4f)
|| (para_page.signature[1] != 0x4e)
|| (para_page.signature[2] != 0x46)
|| (para_page.signature[3] != 0x49)) {
pr_info("Wrong parameter page reading.\n");
return;
}
if (log_level == 1) {
pr_info("The parameter value is show as following list ");
pr_info("please refer to ONFI SPEC for more information.\n");
pr_info("index val index val index val index val ");
for (i = 0; i < sizeof(para_page); i++, buf++) {
if (!(i % 4))
printf("\n");
if (i == 0)
pr_info("0~31 byte:Revision info and features blk:\n");
else if (i == 32)
pr_info("32~79 byte: Manufacturer info blk:\n");
else if (i == 80)
pr_info("80~127 byte: Memory organization blk:\n");
else if (i == 128)
pr_info("128~163 byte: Electrical parameters block:\n");
else if (i == 164)
pr_info("164~255 byte: Vendor block:\n");
pr_info("%03d 0x%02x ", i, *buf);
}
} else {
pr_info("Manu info: ");
for (j = 0; j < 12; j++)
pr_info("%c", para_page.dev_manu[j]);
pr_info("\n");
pr_info("ONFI v");
if (para_page.ver & 0x40)
pr_info("3.0 ");
if (para_page.ver & 0x20)
pr_info("2.3 ");
if (para_page.ver & 0x10)
pr_info("2.2 ");
if (para_page.ver & 0x08)
pr_info("2.1 ");
if (para_page.ver & 0x04)
pr_info("2.0 ");
if (para_page.ver & 0x02)
pr_info("1.0");
pr_info("\n");
pr_info("Feature supprot: 0x%x\n", para_page.feature);
pr_info("%d bytes per page.\n", para_page.data_bytes_perpage);
pr_info("%d spare bytes per page.\n",
para_page.spare_bytes_perpage);
pr_info("%d pages per block.\n", para_page.pages_perblk);
pr_info("%d blocks per LUN.\n", para_page.blks_perLUN);
pr_info("%d LUNs.\n", para_page.num_LUN);
para_page.num_addr_cycle;
pr_info("Column address cycles %d, Row address cycles %d.\n",
para_page.num_addr_cycle & 0xf0,
para_page.num_addr_cycle & 0xf);
pr_info("%d bits per cell.\n", para_page.bits_percell);
pr_info("Bad blocks maximum per LUN: %d\n",
para_page.max_badblk_perLUN);
pr_info("%d bits ECC correctability.\n",
para_page.bits_ECC_corretable);
pr_info("Support time mode: ");
for (j = 5; j >= 0; j--) {
if (para_page.asy_time_mode & (1<<j))
pr_info("%d ", j);
}
}
pr_info("\nEnd of Nand parameter page.\n\n");
}
#endif /* CONFIG_PARAMETER_PAGE */
/* ******************* */
uint8_t aml_nand_get_onfi_features(struct aml_nand_chip *aml_chip,
uint8_t *buf, int addr)
{
struct nand_chip *chip = &aml_chip->chip;
struct mtd_info *mtd = aml_chip->mtd;
int i, j;
for (i = 0; i < controller->chip_num; i++) {
if (aml_chip->valid_chip[i]) {
aml_chip->aml_nand_select_chip(aml_chip, i);
aml_chip->aml_nand_command(aml_chip,
NAND_CMD_GET_FEATURES, -1, -1, i);
chip->cmd_ctrl(mtd, addr,
NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE);
NFC_SEND_CMD_IDLE(controller, 20);
for (j = 0; j < 4; j++)
buf[j] = chip->read_byte(mtd);
}
}
return 0;
}
void aml_nand_set_onfi_features(struct aml_nand_chip *aml_chip,
uint8_t *buf, int addr)
{
int i, j;
struct nand_chip *chip = &aml_chip->chip;
struct mtd_info *mtd = aml_chip->mtd;
for (i = 0; i < controller->chip_num; i++) {
if (aml_chip->valid_chip[i]) {
aml_chip->aml_nand_select_chip(aml_chip, i);
aml_chip->aml_nand_command(aml_chip,
NAND_CMD_SET_FEATURES, -1, -1, i);
chip->cmd_ctrl(mtd, addr,
NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE);
NFC_SEND_CMD_IDLE(controller, 20);
for (j = 0; j < 4; j++)
aml_chip->aml_nand_write_byte(aml_chip, buf[j]);
aml_chip->aml_nand_wait_devready(aml_chip, i);
}
}
}
static struct aml_nand_flash_dev *aml_nand_get_flash_type(struct mtd_info *mtd,
struct nand_chip *chip,
int busw, int *maf_id)
{
struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd);
struct aml_nand_platform *plat = aml_chip->platform;
struct aml_nand_flash_dev *type = NULL;
int i, maf_idx;
u8 dev_id[MAX_ID_LEN];
/* int tmp_id, tmp_manf; */
/* Send the command for reading device ID */
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
/* Read manufacturer and device IDs */
for (i = 0; i < MAX_ID_LEN; i++)
dev_id[i] = chip->read_byte(mtd);
*maf_id = dev_id[0];
pr_info("NAND device id: %x %x %x %x %x %x\n",
dev_id[0], dev_id[1], dev_id[2], dev_id[3], dev_id[4], dev_id[5]);
/* Lookup the flash id */
for (i = 0; aml_nand_flash_ids[i].name != NULL; i++) {
if (!strncmp((char *)aml_nand_flash_ids[i].id,
(char *)dev_id,
strlen((const char *)aml_nand_flash_ids[i].id))) {
type = &aml_nand_flash_ids[i];
break;
}
}
if (!type) {
if (plat->nand_flash_dev) {
if (!strncmp((char *)plat->nand_flash_dev->id,
(char *)dev_id, strlen((const char *)plat->nand_flash_dev->id)))
type = plat->nand_flash_dev;
}
if (!type)
return ERR_PTR(-ENODEV);
}
if (type->new_type) {
pr_info("new nand support!!!\n");
aml_nand_new_nand_param_init(mtd, type);
}
#ifdef CONFIG_MTD_DEVICE
/* mtd->name = NULL; */
/* if (!mtd->info) */
mtd->info = type->name;
#else
if (!mtd->name)
mtd->name = type->name;
#endif
chip->chipsize = type->chipsize;
chip->chipsize = chip->chipsize << 20;
/* Newer devices have all the information in additional id bytes */
if (!type->pagesize) {
int extid;
/* The 3rd id byte holds MLC / multichip data */
/* chip->cellinfo = chip->read_byte(mtd); */
/* The 4th id byte is the important one */
extid = chip->read_byte(mtd);
/* Calc pagesize */
mtd->writesize = 1024 << (extid & 0x3);
extid >>= 2;
/* Calc oobsize */
mtd->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9);
extid >>= 2;
/* Calc blocksize. Blocksize is multiples of 64KiB */
mtd->erasesize = (64 * 1024) << (extid & 0x03);
extid >>= 2;
/* Get buswidth information */
busw = (extid & 0x01) ? NAND_BUSWIDTH_16 : 0;
} else {
/*
* Old devices have chip data hardcoded in the device id table
*/
mtd->erasesize = type->erasesize;
mtd->writesize = type->pagesize;
mtd->oobsize = type->oobsize;
busw = type->options & NAND_BUSW_OPTIONS_MASK;
}
/* Try to identify manufacturer */
for (maf_idx = 0; nand_manuf_ids[maf_idx].id != 0x0; maf_idx++) {
if (nand_manuf_ids[maf_idx].id == *maf_id)
break;
}
/*
* Check, if buswidth is correct. Hardware drivers should set
* chip correct !
*/
if (busw != (chip->options & NAND_BUSWIDTH_16)) {
pr_info("NAND device: Manufacturer ID: ");
pr_info("0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id,
dev_id[0], nand_manuf_ids[maf_idx].name, mtd->name);
pr_info("NAND bus width %d instead %d bit\n",
(chip->options & NAND_BUSWIDTH_16) ? 16 : 8,
busw ? 16 : 8);
return ERR_PTR(-EINVAL);
}
/* Calculate the address shift from the page size */
chip->page_shift = ffs(mtd->writesize) - 1;
/* Convert chipsize to number of pages per chip -1. */
chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
chip->bbt_erase_shift =
chip->phys_erase_shift = ffs(mtd->erasesize) - 1;
chip->chip_shift = ffs(chip->chipsize) - 1;
/* Set the bad block position */
chip->badblockpos = AML_BADBLK_POS;
/* Get chip options, preserve non chip based options */
/* chip->options &= ~NAND_CHIPOPTIONS_MSK; */
/* chip->options |= type->options & NAND_CHIPOPTIONS_MSK; */
/*
* Set chip as a default. Board drivers can override it, if necessary
*/
/* chip->options |= NAND_NO_AUTOINCR; */
/* Check if chip is a not a samsung device. Do not clear the
* options for chips which are not having an extended id.
*/
/* if (*maf_id != NAND_MFR_SAMSUNG && !type->pagesize) */
/* chip->options &= ~NAND_SAMSUNG_LP_OPTIONS; */
pr_info("NAND device: Manufacturer ID: ");
pr_info(" 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, dev_id[0],
nand_manuf_ids[maf_idx].name, type->name);
return type;
}
static int aml_nand_scan_ident(struct mtd_info *mtd, int maxchips)
{
int i, busw, nand_maf_id, valid_chip_num = 1;
struct nand_chip *chip = mtd->priv;
struct aml_nand_chip *aml_chip = mtd_to_nand_chip(mtd);
struct aml_nand_flash_dev *aml_type;
u8 dev_id[MAX_ID_LEN], onfi_features[4];
unsigned int temp_chip_shift;
/* Get buswidth to select the correct functions */
busw = chip->options & NAND_BUSWIDTH_16;
/* Select the device */
chip->select_chip(mtd, 0);
/* reset chip for some nand need reset after power up */
chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
aml_chip->aml_nand_wait_devready(aml_chip, 0);
/* Read the flash type */
aml_type = aml_nand_get_flash_type(mtd, chip, busw, &nand_maf_id);
if (IS_ERR(aml_type)) {
pr_info("No NAND device found!!!\n");
chip->select_chip(mtd, -1);
return PTR_ERR(aml_type);
}
if (aml_type->erasesize < 0x40000) {
aml_chip->keysize = aml_type->erasesize / 4;
aml_chip->dtbsize = aml_type->erasesize;
} else {
/*
*fix size key/dtb!!!
*max key/dtb size is 256KB
**/
aml_chip->keysize = 0x40000;
aml_chip->dtbsize = 0x40000;
}
chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1);
for (i = 0; i < MAX_ID_LEN; i++)
dev_id[i] = chip->read_byte(mtd);
if (!memcmp((char *)dev_id, "ONFI", 4))
aml_chip->onfi_mode = aml_type->onfi_mode;
aml_chip->T_REA = aml_type->T_REA;
aml_chip->T_RHOH = aml_type->T_RHOH;
aml_chip->mfr_type = aml_type->id[0];
#ifdef CONFIG_PARAMETER_PAGE
aml_nand_read_parameter_page(mtd, CE0, &para_page);
display_para_page(para_page, 0);
#endif
/* Check for a chip array */
for (i = 1; i < maxchips; i++) {
aml_chip->aml_nand_select_chip(aml_chip, i);
chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
aml_chip->aml_nand_wait_devready(aml_chip, i);
/* Send the command for reading device ID */
chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
/* Read manufacturer and device IDs */
if (nand_maf_id != chip->read_byte(mtd)
|| aml_type->id[1] != chip->read_byte(mtd))
aml_chip->valid_chip[i] = 0;
else
valid_chip_num++;
}
if (i > 1) {
pr_info("%d NAND chips detected\n", valid_chip_num);
/*
*if ((aml_chip->valid_chip[1] == 0)
* && (aml_chip->valid_chip[2] == 1)) {
* pr_info("ce1 and ce2 connected\n");
* aml_chip->chip_enable[2] =
* (aml_chip->chip_enable[1] & aml_chip->chip_enable[2]);
*}
**/
}
if (aml_chip->onfi_mode) {
aml_nand_set_onfi_features(aml_chip,
(uint8_t *)(&aml_chip->onfi_mode), ONFI_TIMING_ADDR);
aml_nand_get_onfi_features(aml_chip,
onfi_features, ONFI_TIMING_ADDR);
if (onfi_features[0] != aml_chip->onfi_mode) {
aml_chip->T_REA = DEFAULT_T_REA;
aml_chip->T_RHOH = DEFAULT_T_RHOH;
pr_info("onfi timing mode set failed: %x\n",
onfi_features[0]);
}
}
/* Store the number of chips and calc total size for mtd */
chip->numchips = 1;
if ((chip->chipsize >> 32) & 0xffffffff)
chip->chip_shift =
fls((u32)(chip->chipsize >> 32)) * valid_chip_num + 32 - 1;
else
chip->chip_shift =
fls((u32)chip->chipsize) * valid_chip_num - 1;
chip->pagemask =
((chip->chipsize * valid_chip_num) >> chip->page_shift) - 1;
chip->options &= ~NAND_CACHEPRG;
aml_chip->internal_chipnr = aml_type->internal_chipnr;
aml_chip->internal_page_nums = (chip->chipsize >> chip->page_shift);
aml_chip->internal_page_nums /= aml_chip->internal_chipnr;
aml_chip->internal_chip_shift =
fls((unsigned int)aml_chip->internal_page_nums) - 1;
temp_chip_shift = ffs((unsigned int)aml_chip->internal_page_nums) - 1;
if (aml_chip->internal_chip_shift != temp_chip_shift) {
aml_chip->internal_chip_shift += 1;
chip->chip_shift += 1;
chip->pagemask =
((1 << (chip->chip_shift + 1)) >> chip->page_shift) - 1;
}
aml_chip->options = aml_type->options;
aml_chip->page_size = aml_type->pagesize;
aml_chip->block_size = aml_type->erasesize;
aml_chip->oob_size = aml_type->oobsize;
mtd->erasesize = valid_chip_num * aml_type->erasesize;
mtd->writesize = valid_chip_num * aml_type->pagesize;
mtd->oobsize = valid_chip_num * aml_type->oobsize;
mtd->size = valid_chip_num * chip->chipsize;
/* overide bootloader's size consdering info page */
if (!strcmp(mtd->name, NAND_BOOT_NAME))
mtd->size = BOOT_PAGES_PER_COPY * mtd->writesize;
chip->cmdfunc = aml_nand_command;
chip->waitfunc = aml_nand_wait;
chip->erase = aml_nand_erase_cmd;
chip->write_page = aml_nand_write_page;
return 0;
}
int aml_nand_scan(struct mtd_info *mtd, int maxchips)
{
int ret;
ret = aml_nand_scan_ident(mtd, maxchips);
if (!ret)
ret = nand_scan_tail(mtd);
return ret;
}