1 1.10 jmcneill /* $NetBSD: nand_samsung.c,v 1.10 2017/11/09 21:45:24 jmcneill Exp $ */ 2 1.1 ahoka 3 1.1 ahoka /*- 4 1.1 ahoka * Copyright (c) 2012 The NetBSD Foundation, Inc. 5 1.1 ahoka * All rights reserved. 6 1.1 ahoka * 7 1.1 ahoka * This code is derived from software contributed to The NetBSD Foundation 8 1.1 ahoka * by Adam Hoka. 9 1.1 ahoka * 10 1.1 ahoka * Redistribution and use in source and binary forms, with or without 11 1.1 ahoka * modification, are permitted provided that the following conditions 12 1.1 ahoka * are met: 13 1.1 ahoka * 1. Redistributions of source code must retain the above copyright 14 1.1 ahoka * notice, this list of conditions and the following disclaimer. 15 1.1 ahoka * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 ahoka * notice, this list of conditions and the following disclaimer in the 17 1.1 ahoka * documentation and/or other materials provided with the distribution. 18 1.1 ahoka * 19 1.1 ahoka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 ahoka * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 ahoka * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 ahoka * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 ahoka * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 ahoka * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 ahoka * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 ahoka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 ahoka * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 ahoka * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 ahoka * POSSIBILITY OF SUCH DAMAGE. 30 1.1 ahoka */ 31 1.1 ahoka 32 1.1 ahoka /* 33 1.1 ahoka * Device specific functions for legacy Samsung NAND chips 34 1.1 ahoka * 35 1.1 ahoka * Currently supported: 36 1.1 ahoka * K9XXG08UXA 37 1.1 ahoka */ 38 1.1 ahoka 39 1.1 ahoka #include <sys/cdefs.h> 40 1.10 jmcneill __KERNEL_RCSID(0, "$NetBSD: nand_samsung.c,v 1.10 2017/11/09 21:45:24 jmcneill Exp $"); 41 1.1 ahoka 42 1.1 ahoka #include "nand.h" 43 1.1 ahoka #include "onfi.h" 44 1.1 ahoka 45 1.3 ahoka enum { 46 1.3 ahoka NAND_SAMSUNG_PAGEMASK = 0x3, 47 1.5 ahoka NAND_SAMSUNG_SPAREMASK = 0x1 << 2, 48 1.3 ahoka NAND_SAMSUNG_BLOCKMASK = 0x3 << 4, 49 1.3 ahoka NAND_SAMSUNG_BITSMASK = 0x1 << 6 50 1.3 ahoka }; 51 1.3 ahoka 52 1.3 ahoka enum { 53 1.3 ahoka NAND_SAMSUNG_PLANENUMMASK = 0x3 << 2, 54 1.3 ahoka NAND_SAMSUNG_PLANESIZEMASK = 0x7 << 4 55 1.3 ahoka }; 56 1.3 ahoka 57 1.1 ahoka int 58 1.1 ahoka nand_read_parameters_samsung(device_t self, struct nand_chip * const chip) 59 1.1 ahoka { 60 1.1 ahoka uint8_t mfgrid; 61 1.1 ahoka uint8_t devid; 62 1.2 riz uint8_t params1; 63 1.1 ahoka uint8_t params2; 64 1.2 riz uint8_t params3; 65 1.1 ahoka 66 1.1 ahoka /* Only for Samsung devices, obviously */ 67 1.1 ahoka if (chip->nc_manf_id != NAND_MFR_SAMSUNG) { 68 1.1 ahoka return 1; 69 1.1 ahoka } 70 1.1 ahoka 71 1.1 ahoka nand_select(self, true); 72 1.1 ahoka nand_command(self, ONFI_READ_ID); 73 1.1 ahoka nand_address(self, 0x00); 74 1.1 ahoka nand_read_1(self, &mfgrid); 75 1.1 ahoka nand_read_1(self, &devid); 76 1.1 ahoka nand_read_1(self, ¶ms1); 77 1.1 ahoka nand_read_1(self, ¶ms2); 78 1.1 ahoka nand_read_1(self, ¶ms3); 79 1.1 ahoka nand_select(self, false); 80 1.1 ahoka 81 1.5 ahoka aprint_debug_dev(self, 82 1.5 ahoka "ID Definition table: 0x%2.x 0x%2.x 0x%2.x 0x%2.x 0x%2.x\n", 83 1.5 ahoka mfgrid, devid, params1, params2, params3); 84 1.5 ahoka 85 1.1 ahoka /* K9XXG08UXA */ 86 1.1 ahoka if (devid == 0xdc) { 87 1.3 ahoka /* From the documentation */ 88 1.3 ahoka chip->nc_addr_cycles_column = 2; 89 1.3 ahoka chip->nc_addr_cycles_row = 3; 90 1.3 ahoka 91 1.1 ahoka switch (params2 & NAND_SAMSUNG_PAGEMASK) { 92 1.1 ahoka case 0x0: 93 1.1 ahoka chip->nc_page_size = 1024; 94 1.1 ahoka break; 95 1.1 ahoka case 0x1: 96 1.1 ahoka chip->nc_page_size = 2048; 97 1.1 ahoka break; 98 1.1 ahoka case 0x2: 99 1.1 ahoka chip->nc_page_size = 4096; 100 1.1 ahoka break; 101 1.1 ahoka case 0x3: 102 1.1 ahoka chip->nc_page_size = 8192; 103 1.1 ahoka break; 104 1.6 ahoka default: 105 1.6 ahoka KASSERTMSG(false, "ID Data parsing bug detected!"); 106 1.1 ahoka } 107 1.1 ahoka 108 1.5 ahoka switch ((params2 & NAND_SAMSUNG_BLOCKMASK) >> 4) { 109 1.1 ahoka case 0x0: 110 1.1 ahoka chip->nc_block_size = 64 * 1024; 111 1.1 ahoka break; 112 1.2 riz case 0x1: 113 1.1 ahoka chip->nc_block_size = 128 * 1024; 114 1.1 ahoka break; 115 1.2 riz case 0x2: 116 1.1 ahoka chip->nc_block_size = 256 * 1024; 117 1.1 ahoka break; 118 1.2 riz case 0x3: 119 1.1 ahoka chip->nc_block_size = 512 * 1024; 120 1.1 ahoka break; 121 1.6 ahoka default: 122 1.6 ahoka KASSERTMSG(false, "ID Data parsing bug detected!"); 123 1.1 ahoka } 124 1.1 ahoka 125 1.1 ahoka /* 8/16 bytes per 512 bytes! XXX do i get this right? */ 126 1.1 ahoka switch ((params2 & NAND_SAMSUNG_SPAREMASK) >> 2) { 127 1.1 ahoka case 0x0: 128 1.1 ahoka chip->nc_spare_size = 8 * chip->nc_page_size / 512; 129 1.1 ahoka break; 130 1.1 ahoka case 0x1: 131 1.1 ahoka chip->nc_spare_size = 16 * chip->nc_page_size / 512; 132 1.1 ahoka break; 133 1.6 ahoka default: 134 1.6 ahoka KASSERTMSG(false, "ID Data parsing bug detected!"); 135 1.1 ahoka } 136 1.1 ahoka 137 1.1 ahoka switch ((params2 & NAND_SAMSUNG_BITSMASK) >> 6) { 138 1.1 ahoka case 0x0: 139 1.1 ahoka /* its an 8bit chip */ 140 1.1 ahoka break; 141 1.1 ahoka case 0x1: 142 1.1 ahoka chip->nc_flags |= NC_BUSWIDTH_16; 143 1.1 ahoka break; 144 1.6 ahoka default: 145 1.6 ahoka KASSERTMSG(false, "ID Data parsing bug detected!"); 146 1.1 ahoka } 147 1.5 ahoka 148 1.3 ahoka switch ((params3 & NAND_SAMSUNG_PLANENUMMASK) >> 2) { 149 1.3 ahoka case 0x0: 150 1.3 ahoka chip->nc_num_luns = 1; 151 1.3 ahoka break; 152 1.3 ahoka case 0x1: 153 1.3 ahoka chip->nc_num_luns = 2; 154 1.3 ahoka break; 155 1.3 ahoka case 0x2: 156 1.3 ahoka chip->nc_num_luns = 4; 157 1.3 ahoka break; 158 1.3 ahoka case 0x3: 159 1.3 ahoka chip->nc_num_luns = 8; 160 1.3 ahoka break; 161 1.6 ahoka default: 162 1.6 ahoka KASSERTMSG(false, "ID Data parsing bug detected!"); 163 1.3 ahoka } 164 1.3 ahoka 165 1.8 ahoka /* This one reads in megabit for some reason */ 166 1.4 riz uint64_t planesize = 0; 167 1.3 ahoka switch ((params3 & NAND_SAMSUNG_PLANESIZEMASK) >> 4) { 168 1.3 ahoka case 0x0: 169 1.8 ahoka planesize = 64 * 1024 * 1024 / 8; 170 1.3 ahoka break; 171 1.3 ahoka case 0x1: 172 1.8 ahoka planesize = 128 * 1024 * 1024 / 8; 173 1.3 ahoka break; 174 1.3 ahoka case 0x2: 175 1.8 ahoka planesize = 256 * 1024 * 1024 / 8; 176 1.3 ahoka break; 177 1.3 ahoka case 0x3: 178 1.8 ahoka planesize = 512 * 1024 * 1024 / 8; 179 1.3 ahoka break; 180 1.3 ahoka case 0x4: 181 1.8 ahoka planesize = 1024 * 1024 * 1024 / 8; 182 1.3 ahoka break; 183 1.3 ahoka case 0x5: 184 1.10 jmcneill planesize = 2ull * 1024 * 1024 * 1024 / 8; 185 1.3 ahoka break; 186 1.3 ahoka case 0x6: 187 1.10 jmcneill planesize = 4ull * 1024 * 1024 * 1024 / 8; 188 1.3 ahoka break; 189 1.3 ahoka case 0x7: 190 1.10 jmcneill planesize = 8ull * 1024 * 1024 * 1024 / 8; 191 1.3 ahoka break; 192 1.6 ahoka default: 193 1.6 ahoka KASSERTMSG(false, "ID Data parsing bug detected!"); 194 1.3 ahoka } 195 1.3 ahoka 196 1.3 ahoka chip->nc_lun_blocks = planesize / chip->nc_block_size; 197 1.3 ahoka chip->nc_size = planesize * chip->nc_num_luns; 198 1.3 ahoka 199 1.3 ahoka aprint_normal_dev(self, "vendor: Samsung, model: K9XXG08UXA\n"); 200 1.1 ahoka } else { 201 1.1 ahoka return 1; 202 1.1 ahoka } 203 1.5 ahoka 204 1.1 ahoka return 0; 205 1.1 ahoka } 206