1*15f3201dSjmcneill /* $NetBSD: nand_samsung.c,v 1.10 2017/11/09 21:45:24 jmcneill Exp $ */
29867e976Sahoka
39867e976Sahoka /*-
49867e976Sahoka * Copyright (c) 2012 The NetBSD Foundation, Inc.
59867e976Sahoka * All rights reserved.
69867e976Sahoka *
79867e976Sahoka * This code is derived from software contributed to The NetBSD Foundation
89867e976Sahoka * by Adam Hoka.
99867e976Sahoka *
109867e976Sahoka * Redistribution and use in source and binary forms, with or without
119867e976Sahoka * modification, are permitted provided that the following conditions
129867e976Sahoka * are met:
139867e976Sahoka * 1. Redistributions of source code must retain the above copyright
149867e976Sahoka * notice, this list of conditions and the following disclaimer.
159867e976Sahoka * 2. Redistributions in binary form must reproduce the above copyright
169867e976Sahoka * notice, this list of conditions and the following disclaimer in the
179867e976Sahoka * documentation and/or other materials provided with the distribution.
189867e976Sahoka *
199867e976Sahoka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
209867e976Sahoka * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
219867e976Sahoka * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
229867e976Sahoka * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
239867e976Sahoka * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
249867e976Sahoka * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
259867e976Sahoka * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
269867e976Sahoka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
279867e976Sahoka * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
289867e976Sahoka * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
299867e976Sahoka * POSSIBILITY OF SUCH DAMAGE.
309867e976Sahoka */
319867e976Sahoka
329867e976Sahoka /*
339867e976Sahoka * Device specific functions for legacy Samsung NAND chips
349867e976Sahoka *
359867e976Sahoka * Currently supported:
369867e976Sahoka * K9XXG08UXA
379867e976Sahoka */
389867e976Sahoka
399867e976Sahoka #include <sys/cdefs.h>
40*15f3201dSjmcneill __KERNEL_RCSID(0, "$NetBSD: nand_samsung.c,v 1.10 2017/11/09 21:45:24 jmcneill Exp $");
419867e976Sahoka
429867e976Sahoka #include "nand.h"
439867e976Sahoka #include "onfi.h"
449867e976Sahoka
450aaf7066Sahoka enum {
460aaf7066Sahoka NAND_SAMSUNG_PAGEMASK = 0x3,
470aaf7066Sahoka NAND_SAMSUNG_SPAREMASK = 0x1 << 2,
489dcc74b0Sahoka NAND_SAMSUNG_BLOCKMASK = 0x3 << 4,
490aaf7066Sahoka NAND_SAMSUNG_BITSMASK = 0x1 << 6
500aaf7066Sahoka };
510aaf7066Sahoka
520aaf7066Sahoka enum {
530aaf7066Sahoka NAND_SAMSUNG_PLANENUMMASK = 0x3 << 2,
540aaf7066Sahoka NAND_SAMSUNG_PLANESIZEMASK = 0x7 << 4
550aaf7066Sahoka };
560aaf7066Sahoka
579867e976Sahoka int
nand_read_parameters_samsung(device_t self,struct nand_chip * const chip)589867e976Sahoka nand_read_parameters_samsung(device_t self, struct nand_chip * const chip)
599867e976Sahoka {
609867e976Sahoka uint8_t mfgrid;
619867e976Sahoka uint8_t devid;
6250c33ca8Sriz uint8_t params1;
639867e976Sahoka uint8_t params2;
6450c33ca8Sriz uint8_t params3;
659867e976Sahoka
669867e976Sahoka /* Only for Samsung devices, obviously */
679867e976Sahoka if (chip->nc_manf_id != NAND_MFR_SAMSUNG) {
689867e976Sahoka return 1;
699867e976Sahoka }
709867e976Sahoka
719867e976Sahoka nand_select(self, true);
729867e976Sahoka nand_command(self, ONFI_READ_ID);
739867e976Sahoka nand_address(self, 0x00);
749867e976Sahoka nand_read_1(self, &mfgrid);
759867e976Sahoka nand_read_1(self, &devid);
769867e976Sahoka nand_read_1(self, ¶ms1);
779867e976Sahoka nand_read_1(self, ¶ms2);
789867e976Sahoka nand_read_1(self, ¶ms3);
799867e976Sahoka nand_select(self, false);
809867e976Sahoka
819dcc74b0Sahoka aprint_debug_dev(self,
829dcc74b0Sahoka "ID Definition table: 0x%2.x 0x%2.x 0x%2.x 0x%2.x 0x%2.x\n",
839dcc74b0Sahoka mfgrid, devid, params1, params2, params3);
849dcc74b0Sahoka
859867e976Sahoka /* K9XXG08UXA */
869867e976Sahoka if (devid == 0xdc) {
870aaf7066Sahoka /* From the documentation */
880aaf7066Sahoka chip->nc_addr_cycles_column = 2;
890aaf7066Sahoka chip->nc_addr_cycles_row = 3;
900aaf7066Sahoka
919867e976Sahoka switch (params2 & NAND_SAMSUNG_PAGEMASK) {
929867e976Sahoka case 0x0:
939867e976Sahoka chip->nc_page_size = 1024;
949867e976Sahoka break;
959867e976Sahoka case 0x1:
969867e976Sahoka chip->nc_page_size = 2048;
979867e976Sahoka break;
989867e976Sahoka case 0x2:
999867e976Sahoka chip->nc_page_size = 4096;
1009867e976Sahoka break;
1019867e976Sahoka case 0x3:
1029867e976Sahoka chip->nc_page_size = 8192;
1039867e976Sahoka break;
104e476cc66Sahoka default:
105e476cc66Sahoka KASSERTMSG(false, "ID Data parsing bug detected!");
1069867e976Sahoka }
1079867e976Sahoka
1089dcc74b0Sahoka switch ((params2 & NAND_SAMSUNG_BLOCKMASK) >> 4) {
1099867e976Sahoka case 0x0:
1109867e976Sahoka chip->nc_block_size = 64 * 1024;
1119867e976Sahoka break;
11250c33ca8Sriz case 0x1:
1139867e976Sahoka chip->nc_block_size = 128 * 1024;
1149867e976Sahoka break;
11550c33ca8Sriz case 0x2:
1169867e976Sahoka chip->nc_block_size = 256 * 1024;
1179867e976Sahoka break;
11850c33ca8Sriz case 0x3:
1199867e976Sahoka chip->nc_block_size = 512 * 1024;
1209867e976Sahoka break;
121e476cc66Sahoka default:
122e476cc66Sahoka KASSERTMSG(false, "ID Data parsing bug detected!");
1239867e976Sahoka }
1249867e976Sahoka
1259867e976Sahoka /* 8/16 bytes per 512 bytes! XXX do i get this right? */
1269867e976Sahoka switch ((params2 & NAND_SAMSUNG_SPAREMASK) >> 2) {
1279867e976Sahoka case 0x0:
1289867e976Sahoka chip->nc_spare_size = 8 * chip->nc_page_size / 512;
1299867e976Sahoka break;
1309867e976Sahoka case 0x1:
1319867e976Sahoka chip->nc_spare_size = 16 * chip->nc_page_size / 512;
1329867e976Sahoka break;
133e476cc66Sahoka default:
134e476cc66Sahoka KASSERTMSG(false, "ID Data parsing bug detected!");
1359867e976Sahoka }
1369867e976Sahoka
1379867e976Sahoka switch ((params2 & NAND_SAMSUNG_BITSMASK) >> 6) {
1389867e976Sahoka case 0x0:
1399867e976Sahoka /* its an 8bit chip */
1409867e976Sahoka break;
1419867e976Sahoka case 0x1:
1429867e976Sahoka chip->nc_flags |= NC_BUSWIDTH_16;
1439867e976Sahoka break;
144e476cc66Sahoka default:
145e476cc66Sahoka KASSERTMSG(false, "ID Data parsing bug detected!");
1469867e976Sahoka }
1479867e976Sahoka
1480aaf7066Sahoka switch ((params3 & NAND_SAMSUNG_PLANENUMMASK) >> 2) {
1490aaf7066Sahoka case 0x0:
1500aaf7066Sahoka chip->nc_num_luns = 1;
1510aaf7066Sahoka break;
1520aaf7066Sahoka case 0x1:
1530aaf7066Sahoka chip->nc_num_luns = 2;
1540aaf7066Sahoka break;
1550aaf7066Sahoka case 0x2:
1560aaf7066Sahoka chip->nc_num_luns = 4;
1570aaf7066Sahoka break;
1580aaf7066Sahoka case 0x3:
1590aaf7066Sahoka chip->nc_num_luns = 8;
1600aaf7066Sahoka break;
161e476cc66Sahoka default:
162e476cc66Sahoka KASSERTMSG(false, "ID Data parsing bug detected!");
1630aaf7066Sahoka }
1640aaf7066Sahoka
165b8273ad8Sahoka /* This one reads in megabit for some reason */
1668160a915Sriz uint64_t planesize = 0;
1670aaf7066Sahoka switch ((params3 & NAND_SAMSUNG_PLANESIZEMASK) >> 4) {
1680aaf7066Sahoka case 0x0:
169b8273ad8Sahoka planesize = 64 * 1024 * 1024 / 8;
1700aaf7066Sahoka break;
1710aaf7066Sahoka case 0x1:
172b8273ad8Sahoka planesize = 128 * 1024 * 1024 / 8;
1730aaf7066Sahoka break;
1740aaf7066Sahoka case 0x2:
175b8273ad8Sahoka planesize = 256 * 1024 * 1024 / 8;
1760aaf7066Sahoka break;
1770aaf7066Sahoka case 0x3:
178b8273ad8Sahoka planesize = 512 * 1024 * 1024 / 8;
1790aaf7066Sahoka break;
1800aaf7066Sahoka case 0x4:
181b8273ad8Sahoka planesize = 1024 * 1024 * 1024 / 8;
1820aaf7066Sahoka break;
1830aaf7066Sahoka case 0x5:
184*15f3201dSjmcneill planesize = 2ull * 1024 * 1024 * 1024 / 8;
1850aaf7066Sahoka break;
1860aaf7066Sahoka case 0x6:
187*15f3201dSjmcneill planesize = 4ull * 1024 * 1024 * 1024 / 8;
1880aaf7066Sahoka break;
1890aaf7066Sahoka case 0x7:
190*15f3201dSjmcneill planesize = 8ull * 1024 * 1024 * 1024 / 8;
1910aaf7066Sahoka break;
192e476cc66Sahoka default:
193e476cc66Sahoka KASSERTMSG(false, "ID Data parsing bug detected!");
1940aaf7066Sahoka }
1950aaf7066Sahoka
1960aaf7066Sahoka chip->nc_lun_blocks = planesize / chip->nc_block_size;
1970aaf7066Sahoka chip->nc_size = planesize * chip->nc_num_luns;
1980aaf7066Sahoka
1990aaf7066Sahoka aprint_normal_dev(self, "vendor: Samsung, model: K9XXG08UXA\n");
2009867e976Sahoka } else {
2019867e976Sahoka return 1;
2029867e976Sahoka }
2039867e976Sahoka
2049867e976Sahoka return 0;
2059867e976Sahoka }
206