nand_samsung.c revision 1.2 1 /* $NetBSD: nand_samsung.c,v 1.2 2012/10/30 22:43:36 riz Exp $ */
2
3 /*-
4 * Copyright (c) 2012 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Hoka.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * Device specific functions for legacy Samsung NAND chips
34 *
35 * Currently supported:
36 * K9XXG08UXA
37 */
38
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: nand_samsung.c,v 1.2 2012/10/30 22:43:36 riz Exp $");
41
42 #include "nand.h"
43 #include "onfi.h"
44
45 int
46 nand_read_parameters_samsung(device_t self, struct nand_chip * const chip)
47 {
48 uint8_t mfgrid;
49 uint8_t devid;
50 uint8_t params1;
51 uint8_t params2;
52 uint8_t params3;
53
54 /* Only for Samsung devices, obviously */
55 if (chip->nc_manf_id != NAND_MFR_SAMSUNG) {
56 return 1;
57 }
58
59 nand_select(self, true);
60 nand_command(self, ONFI_READ_ID);
61 nand_address(self, 0x00);
62 nand_read_1(self, &mfgrid);
63 nand_read_1(self, &devid);
64 nand_read_1(self, ¶ms1);
65 nand_read_1(self, ¶ms2);
66 nand_read_1(self, ¶ms3);
67 nand_select(self, false);
68
69 enum {
70 NAND_SAMSUNG_PAGEMASK = 0x3,
71 NAND_SAMSUNG_BLOCKMASK = 0x3 << 4,
72 NAND_SAMSUNG_SPAREMASK = 0x1 << 2,
73 NAND_SAMSUNG_BITSMASK = 0x1 << 6
74 };
75
76 /* K9XXG08UXA */
77 if (devid == 0xdc) {
78 switch (params2 & NAND_SAMSUNG_PAGEMASK) {
79 case 0x0:
80 chip->nc_page_size = 1024;
81 break;
82 case 0x1:
83 chip->nc_page_size = 2048;
84 break;
85 case 0x2:
86 chip->nc_page_size = 4096;
87 break;
88 case 0x3:
89 chip->nc_page_size = 8192;
90 break;
91 }
92
93 switch ((params2 & NAND_SAMSUNG_PAGEMASK) >> 4) {
94 case 0x0:
95 chip->nc_block_size = 64 * 1024;
96 break;
97 case 0x1:
98 chip->nc_block_size = 128 * 1024;
99 break;
100 case 0x2:
101 chip->nc_block_size = 256 * 1024;
102 break;
103 case 0x3:
104 chip->nc_block_size = 512 * 1024;
105 break;
106 }
107
108 /* 8/16 bytes per 512 bytes! XXX do i get this right? */
109 switch ((params2 & NAND_SAMSUNG_SPAREMASK) >> 2) {
110 case 0x0:
111 chip->nc_spare_size = 8 * chip->nc_page_size / 512;
112 break;
113 case 0x1:
114 chip->nc_spare_size = 16 * chip->nc_page_size / 512;
115 break;
116 }
117
118 switch ((params2 & NAND_SAMSUNG_BITSMASK) >> 6) {
119 case 0x0:
120 /* its an 8bit chip */
121 break;
122 case 0x1:
123 chip->nc_flags |= NC_BUSWIDTH_16;
124 break;
125 }
126
127 // TODO make this nice like the above
128 chip->nc_size = (((params3 >> 4) & 0x7) + 1) * 64 * 1024 * 1024;
129 } else {
130 return 1;
131 }
132
133 return 0;
134 }
135
136