xref: /netbsd/sys/dev/nand/nand_samsung.c (revision b57d92b4)
1*b57d92b4Sjmcneill /*	$NetBSD: nand_samsung.c,v 1.10 2017/11/09 21:45:24 jmcneill Exp $	*/
2a167cf5eSahoka 
3a167cf5eSahoka /*-
4a167cf5eSahoka  * Copyright (c) 2012 The NetBSD Foundation, Inc.
5a167cf5eSahoka  * All rights reserved.
6a167cf5eSahoka  *
7a167cf5eSahoka  * This code is derived from software contributed to The NetBSD Foundation
8a167cf5eSahoka  * by Adam Hoka.
9a167cf5eSahoka  *
10a167cf5eSahoka  * Redistribution and use in source and binary forms, with or without
11a167cf5eSahoka  * modification, are permitted provided that the following conditions
12a167cf5eSahoka  * are met:
13a167cf5eSahoka  * 1. Redistributions of source code must retain the above copyright
14a167cf5eSahoka  *    notice, this list of conditions and the following disclaimer.
15a167cf5eSahoka  * 2. Redistributions in binary form must reproduce the above copyright
16a167cf5eSahoka  *    notice, this list of conditions and the following disclaimer in the
17a167cf5eSahoka  *    documentation and/or other materials provided with the distribution.
18a167cf5eSahoka  *
19a167cf5eSahoka  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20a167cf5eSahoka  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21a167cf5eSahoka  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22a167cf5eSahoka  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23a167cf5eSahoka  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24a167cf5eSahoka  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25a167cf5eSahoka  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26a167cf5eSahoka  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27a167cf5eSahoka  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28a167cf5eSahoka  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29a167cf5eSahoka  * POSSIBILITY OF SUCH DAMAGE.
30a167cf5eSahoka  */
31a167cf5eSahoka 
32a167cf5eSahoka /*
33a167cf5eSahoka  * Device specific functions for legacy Samsung NAND chips
34a167cf5eSahoka  *
35a167cf5eSahoka  * Currently supported:
36a167cf5eSahoka  * K9XXG08UXA
37a167cf5eSahoka  */
38a167cf5eSahoka 
39a167cf5eSahoka #include <sys/cdefs.h>
40*b57d92b4Sjmcneill __KERNEL_RCSID(0, "$NetBSD: nand_samsung.c,v 1.10 2017/11/09 21:45:24 jmcneill Exp $");
41a167cf5eSahoka 
42a167cf5eSahoka #include "nand.h"
43a167cf5eSahoka #include "onfi.h"
44a167cf5eSahoka 
4557668a09Sahoka enum {
4657668a09Sahoka 	NAND_SAMSUNG_PAGEMASK = 0x3,
4757668a09Sahoka 	NAND_SAMSUNG_SPAREMASK = 0x1 << 2,
48971be162Sahoka 	NAND_SAMSUNG_BLOCKMASK = 0x3 << 4,
4957668a09Sahoka 	NAND_SAMSUNG_BITSMASK = 0x1 << 6
5057668a09Sahoka };
5157668a09Sahoka 
5257668a09Sahoka enum {
5357668a09Sahoka 	NAND_SAMSUNG_PLANENUMMASK = 0x3 << 2,
5457668a09Sahoka 	NAND_SAMSUNG_PLANESIZEMASK = 0x7 << 4
5557668a09Sahoka };
5657668a09Sahoka 
57a167cf5eSahoka int
nand_read_parameters_samsung(device_t self,struct nand_chip * const chip)58a167cf5eSahoka nand_read_parameters_samsung(device_t self, struct nand_chip * const chip)
59a167cf5eSahoka {
60a167cf5eSahoka 	uint8_t mfgrid;
61a167cf5eSahoka 	uint8_t devid;
629f8c2498Sriz 	uint8_t params1;
63a167cf5eSahoka 	uint8_t params2;
649f8c2498Sriz 	uint8_t params3;
65a167cf5eSahoka 
66a167cf5eSahoka 	/* Only for Samsung devices, obviously */
67a167cf5eSahoka 	if (chip->nc_manf_id != NAND_MFR_SAMSUNG) {
68a167cf5eSahoka 		return 1;
69a167cf5eSahoka 	}
70a167cf5eSahoka 
71a167cf5eSahoka 	nand_select(self, true);
72a167cf5eSahoka 	nand_command(self, ONFI_READ_ID);
73a167cf5eSahoka 	nand_address(self, 0x00);
74a167cf5eSahoka 	nand_read_1(self, &mfgrid);
75a167cf5eSahoka 	nand_read_1(self, &devid);
76a167cf5eSahoka 	nand_read_1(self, &params1);
77a167cf5eSahoka 	nand_read_1(self, &params2);
78a167cf5eSahoka 	nand_read_1(self, &params3);
79a167cf5eSahoka 	nand_select(self, false);
80a167cf5eSahoka 
81971be162Sahoka 	aprint_debug_dev(self,
82971be162Sahoka 	    "ID Definition table: 0x%2.x 0x%2.x 0x%2.x 0x%2.x 0x%2.x\n",
83971be162Sahoka 	    mfgrid, devid, params1, params2, params3);
84971be162Sahoka 
85a167cf5eSahoka 	/* K9XXG08UXA */
86a167cf5eSahoka 	if (devid == 0xdc) {
8757668a09Sahoka 		/* From the documentation */
8857668a09Sahoka 		chip->nc_addr_cycles_column = 2;
8957668a09Sahoka 		chip->nc_addr_cycles_row = 3;
9057668a09Sahoka 
91a167cf5eSahoka 		switch (params2 & NAND_SAMSUNG_PAGEMASK) {
92a167cf5eSahoka 		case 0x0:
93a167cf5eSahoka 			chip->nc_page_size = 1024;
94a167cf5eSahoka 			break;
95a167cf5eSahoka 		case 0x1:
96a167cf5eSahoka 			chip->nc_page_size = 2048;
97a167cf5eSahoka 			break;
98a167cf5eSahoka 		case 0x2:
99a167cf5eSahoka 			chip->nc_page_size = 4096;
100a167cf5eSahoka 			break;
101a167cf5eSahoka 		case 0x3:
102a167cf5eSahoka 			chip->nc_page_size = 8192;
103a167cf5eSahoka 			break;
104f713271fSahoka 		default:
105f713271fSahoka 			KASSERTMSG(false, "ID Data parsing bug detected!");
106a167cf5eSahoka 		}
107a167cf5eSahoka 
108971be162Sahoka 		switch ((params2 & NAND_SAMSUNG_BLOCKMASK) >> 4) {
109a167cf5eSahoka 		case 0x0:
110a167cf5eSahoka 			chip->nc_block_size = 64 * 1024;
111a167cf5eSahoka 			break;
1129f8c2498Sriz 		case 0x1:
113a167cf5eSahoka 			chip->nc_block_size = 128 * 1024;
114a167cf5eSahoka 			break;
1159f8c2498Sriz 		case 0x2:
116a167cf5eSahoka 			chip->nc_block_size = 256 * 1024;
117a167cf5eSahoka 			break;
1189f8c2498Sriz 		case 0x3:
119a167cf5eSahoka 			chip->nc_block_size = 512 * 1024;
120a167cf5eSahoka 			break;
121f713271fSahoka 		default:
122f713271fSahoka 			KASSERTMSG(false, "ID Data parsing bug detected!");
123a167cf5eSahoka 		}
124a167cf5eSahoka 
125a167cf5eSahoka 		/* 8/16 bytes per 512 bytes! XXX do i get this right? */
126a167cf5eSahoka 		switch ((params2 & NAND_SAMSUNG_SPAREMASK) >> 2) {
127a167cf5eSahoka 		case 0x0:
128a167cf5eSahoka 			chip->nc_spare_size = 8 * chip->nc_page_size / 512;
129a167cf5eSahoka 			break;
130a167cf5eSahoka 		case 0x1:
131a167cf5eSahoka 			chip->nc_spare_size = 16 * chip->nc_page_size / 512;
132a167cf5eSahoka 			break;
133f713271fSahoka 		default:
134f713271fSahoka 			KASSERTMSG(false, "ID Data parsing bug detected!");
135a167cf5eSahoka 		}
136a167cf5eSahoka 
137a167cf5eSahoka 		switch ((params2 & NAND_SAMSUNG_BITSMASK) >> 6) {
138a167cf5eSahoka 		case 0x0:
139a167cf5eSahoka 			/* its an 8bit chip */
140a167cf5eSahoka 			break;
141a167cf5eSahoka 		case 0x1:
142a167cf5eSahoka 			chip->nc_flags |= NC_BUSWIDTH_16;
143a167cf5eSahoka 			break;
144f713271fSahoka 		default:
145f713271fSahoka 			KASSERTMSG(false, "ID Data parsing bug detected!");
146a167cf5eSahoka 		}
147a167cf5eSahoka 
14857668a09Sahoka 		switch ((params3 & NAND_SAMSUNG_PLANENUMMASK) >> 2) {
14957668a09Sahoka 		case 0x0:
15057668a09Sahoka 			chip->nc_num_luns = 1;
15157668a09Sahoka 			break;
15257668a09Sahoka 		case 0x1:
15357668a09Sahoka 			chip->nc_num_luns = 2;
15457668a09Sahoka 			break;
15557668a09Sahoka 		case 0x2:
15657668a09Sahoka 			chip->nc_num_luns = 4;
15757668a09Sahoka 			break;
15857668a09Sahoka 		case 0x3:
15957668a09Sahoka 			chip->nc_num_luns = 8;
16057668a09Sahoka 			break;
161f713271fSahoka 		default:
162f713271fSahoka 			KASSERTMSG(false, "ID Data parsing bug detected!");
16357668a09Sahoka 		}
16457668a09Sahoka 
165355588e0Sahoka 		/* This one reads in megabit for some reason */
166878a9939Sriz 		uint64_t planesize = 0;
16757668a09Sahoka 		switch ((params3 & NAND_SAMSUNG_PLANESIZEMASK) >> 4) {
16857668a09Sahoka 		case 0x0:
169355588e0Sahoka 			planesize = 64 * 1024 * 1024 / 8;
17057668a09Sahoka 			break;
17157668a09Sahoka 		case 0x1:
172355588e0Sahoka 			planesize = 128 * 1024 * 1024 / 8;
17357668a09Sahoka 			break;
17457668a09Sahoka 		case 0x2:
175355588e0Sahoka 			planesize = 256 * 1024 * 1024 / 8;
17657668a09Sahoka 			break;
17757668a09Sahoka 		case 0x3:
178355588e0Sahoka 			planesize = 512 * 1024 * 1024 / 8;
17957668a09Sahoka 			break;
18057668a09Sahoka 		case 0x4:
181355588e0Sahoka 			planesize = 1024 * 1024 * 1024 / 8;
18257668a09Sahoka 			break;
18357668a09Sahoka 		case 0x5:
184*b57d92b4Sjmcneill 			planesize = 2ull * 1024 * 1024 * 1024 / 8;
18557668a09Sahoka 			break;
18657668a09Sahoka 		case 0x6:
187*b57d92b4Sjmcneill 			planesize = 4ull * 1024 * 1024 * 1024 / 8;
18857668a09Sahoka 			break;
18957668a09Sahoka 		case 0x7:
190*b57d92b4Sjmcneill 			planesize = 8ull * 1024 * 1024 * 1024 / 8;
19157668a09Sahoka 			break;
192f713271fSahoka 		default:
193f713271fSahoka 			KASSERTMSG(false, "ID Data parsing bug detected!");
19457668a09Sahoka 		}
19557668a09Sahoka 
19657668a09Sahoka 		chip->nc_lun_blocks = planesize / chip->nc_block_size;
19757668a09Sahoka 		chip->nc_size = planesize * chip->nc_num_luns;
19857668a09Sahoka 
19957668a09Sahoka 		aprint_normal_dev(self, "vendor: Samsung, model: K9XXG08UXA\n");
200a167cf5eSahoka 	} else {
201a167cf5eSahoka 		return 1;
202a167cf5eSahoka 	}
203a167cf5eSahoka 
204a167cf5eSahoka 	return 0;
205a167cf5eSahoka }
206