From owner-freebsd-embedded@FreeBSD.ORG Tue Mar 16 14:22:50 2010 Return-Path: Delivered-To: embedded@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7FD32106566B for ; Tue, 16 Mar 2010 14:22:50 +0000 (UTC) (envelope-from loos.br@gmail.com) Received: from mail-px0-f200.google.com (mail-px0-f200.google.com [209.85.216.200]) by mx1.freebsd.org (Postfix) with ESMTP id 436828FC12 for ; Tue, 16 Mar 2010 14:22:50 +0000 (UTC) Received: by pxi38 with SMTP id 38so1642670pxi.27 for ; Tue, 16 Mar 2010 07:22:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:subject:mime-version :content-type:from:in-reply-to:date:cc:message-id:references:to :x-mailer; bh=DQSBk8rDQuqcP5i9bPq5fpe47QX6EnLI75dHdDXIjlg=; b=LuwB+dy+1/2wVquUOuLxX9bmrMI5VBng3C2xsoohiR143x9rDArnaMLDK4TaNHuFpD Kh+mFYScOdsVPZ6iP+gD/u8OvKrWMAGdL/QBCLwKwT3vYb3NmxCgb8nrebJoqYzIMETH zbG1T8QTZxS1l+uw9MO5KoWHUmRDJ8fFEgGeQ= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=subject:mime-version:content-type:from:in-reply-to:date:cc :message-id:references:to:x-mailer; b=IaxSVIF8Vg78mA/9TMVVYkZKkD1DQ6KOtJsYPtteyy6hmOEWBWHzx0t0qC03I8aTyj UgTcxsEd02NHIvT0aXfAb5n/sO/7o3pXhaCyhnc3FdDexqGKmKrttmAodIqYxMsMaQz9 dodFieB0qbSKUShI5JyunDuwqqERL77Koqy+M= Received: by 10.142.119.22 with SMTP id r22mr57187wfc.191.1268749369493; Tue, 16 Mar 2010 07:22:49 -0700 (PDT) Received: from [192.168.0.86] ([187.39.15.241]) by mx.google.com with ESMTPS id 23sm550527ywh.15.2010.03.16.07.22.46 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 16 Mar 2010 07:22:48 -0700 (PDT) Mime-Version: 1.0 (Apple Message framework v1077) Content-Type: multipart/mixed; boundary=Apple-Mail-32-531872463 From: Luiz Otavio O Souza In-Reply-To: <4B9F72BC.1050609@semihalf.com> Date: Tue, 16 Mar 2010 11:22:44 -0300 Message-Id: <776ADF3A-4C68-486A-8640-DE0DD6B8874E@gmail.com> References: <0AE04EFA-A3EB-4939-BD81-607C00355B67@semihalf.com> <20100314165825.121d346b@fubar.geek.nz> <4B9E1697.9090602@semihalf.com> <20100316101044.0401295e@fubar.geek.nz> <4B9F72BC.1050609@semihalf.com> To: Grzegorz Bernacki X-Mailer: Apple Mail (2.1077) Cc: embedded@freebsd.org, Andrew Turner Subject: Re: NAND Flash Framework for review X-BeenThere: freebsd-embedded@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Dedicated and Embedded Systems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Mar 2010 14:22:50 -0000 --Apple-Mail-32-531872463 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii On Mar 16, 2010, at 8:59 AM, Grzegorz Bernacki wrote: > Andrew Turner wrote: >> On Mon, 15 Mar 2010 12:14:31 +0100 >> Grzegorz Bernacki wrote: >>>>> Chip drivers: >>>>> - lnand and snand have magic numbers to figure out which drive to >>>>> use. We should move these to a flag in the chip parameters. >>>> We just need to add the chip size in nand_params and based on that >>>> we can calculate the number of address cycles (see below) and the >>>> type of chip (if chip >=3D 128MB and pagesize > 512 then you have a >>>> large page device). >>>>=20 >>> Yes, I was thinking about adding size of page and column address to >>> parameters of nfc_send_address. >> Why not just send each address byte separately like when the command = is >> sent? This will then push the requirement to know how many address >> bytes to the chip driver. >=20 > I choose to send whole address in one call to make implementation of = mpc8572 > driver easier. This controller requires to divide address into block = number and > page & column number and write them into corresponding registers. It = would be > complicated (however, not impossible) to combine full address from = bytes sending > via consecutive nfc_send_address calls. On the other hand sending = whole address > in one call should not complicated drivers for controllers which just = send address > byte after byte. > I was thinking about adding address type parameter to = nfc_send_address(). It will > tell controller how many address cycles chip requires. It will be = defined > using pattern (row_bytes << 4) | (col_bytes), for example: > #define ADDR_TYPE_2ROW_1COL 0x21 > #define ADDR_TYPE_2ROW_2COL 0x22 > #define ADDR_TYPE_2ROW 0x20 (for erase command) > #define ADDR_TYPE_ID 0xff (for read id command) > It will allow to get rid of (-1) value for unused parameters. Also = maybe it would be > better to define address as a structure > struct nand_addr { > uint32_t row; > uint32_t column; > uint8_t id; > uint8_t type; > } But then we need to keep the logic for sending the address cycles on the = driver (and we'll get a lot of duplicated code on the tree). Look at my patch on how it simplify the send_address routine on nfc_mv.c And yes, you need to deal with multiple calls in some kind of = drivers/controllers. > The second thing is wait for ready/busy pin. I will add it to nfc = methods. When not > implemented it will return ENXIO by default. It will be used in = nandbus_wait_ready function. It will be called in loop instead of = sending STATUS command (unless it return ENXIO on first invocation). > Is it good approach? What do you think? Well, they are different things... The ready/busy pin tells you when the chip is busy in some internal = operation (erasing a block, putting data on the buffer after you send = all the address cycles for a read, etc). You should use the ready/busy pin to wait for the right time to read the = data after sending the command and when you don't have access to this = pin you can fallback to default delays. The read status command is used to tell when a read/write/erase command = fails. If you have a fail after write or erase blocks then you have a = bad block. About the patch (what it changes): I've changed the blocks_per_chip to chip_size, because there are a few = chips that support a kind of extended id bytes which contains the basic = chip information (page size, spare size, access time, block size and = organization - 8X16 bits) but not the number of blocks per chip, so if = we have the chip size we can calculate all the rest. The readextendedid() routine is not on the patch, i'll add it in the = next days (i've it here somewhere...). I did not touch on onfi routines (don't know too much about it and don't = have a device to test). You can ignore the changes on ecc bytes positions for now (but the = original positions you are using overlaps with bad block mark byte). The patch also fixes the probe of small and large page devices (no more = magic numbers :-)). There is another two fixes on large page routines, the original code = tries to read the status right after sending the address cycles and then = you can't read the real data, you just read the status register. That's it. Thanks, Luiz --Apple-Mail-32-531872463 Content-Disposition: attachment; filename=nand2-20100316-diff.txt Content-Type: text/plain; name="nand2-20100316-diff.txt" Content-Transfer-Encoding: quoted-printable diff -ru nand2/sys/dev/nand/nand.c mips-nand2/src/sys/dev/nand/nand.c --- nand2/sys/dev/nand/nand.c 2010-03-07 12:26:49.000000000 -0300 +++ mips-nand2/src/sys/dev/nand/nand.c 2010-03-16 10:38:19.000000000 = -0300 @@ -114,10 +114,13 @@ nand_set_params(struct nand_chip *chip, struct nand_params *params) { struct chip_geom *cg; + uint32_t blocks_per_chip; =20 cg =3D &chip->chip_geom; + blocks_per_chip =3D (params->chip_size << 20) / + (params->page_size * params->pages_per_block); =20 - init_chip_geom(cg, 1, params->blocks_per_chip, + init_chip_geom(cg, 1, blocks_per_chip, params->pages_per_block, params->page_size, params->oob_size); =20 @@ -186,7 +189,6 @@ cg->block_size =3D cg->page_size * cg->pgs_per_blk; cg->chip_size =3D cg->block_size * cg->blks_per_chip; =20 - shift =3D fls(cg->pgs_per_blk - 1); cg->pg_mask =3D (1 << shift) - 1; cg->blk_shift =3D shift; diff -ru nand2/sys/dev/nand/nand.h mips-nand2/src/sys/dev/nand/nand.h --- nand2/sys/dev/nand/nand.h 2010-03-07 12:26:49.000000000 -0300 +++ mips-nand2/src/sys/dev/nand/nand.h 2010-03-16 08:39:45.000000000 = -0300 @@ -116,19 +116,20 @@ #define NAND_ECC_MODE_MASK 0x3f =20 #define NAND_MAN_SAMSUNG 0xec +#define NAND_MAN_HYNIX 0xad =20 struct nand_id { - uint8_t manufacturer_id; - uint8_t device_id; + uint8_t man_id; + uint8_t dev_id; }; =20 struct nand_params { struct nand_id id; char *name; + uint32_t chip_size; uint32_t page_size; uint32_t oob_size; uint32_t pages_per_block; - uint32_t blocks_per_chip; uint32_t flags; }; =20 diff -ru nand2/sys/dev/nand/nand_ecc_pos.h = mips-nand2/src/sys/dev/nand/nand_ecc_pos.h --- nand2/sys/dev/nand/nand_ecc_pos.h 2010-03-07 12:26:50.000000000 = -0300 +++ mips-nand2/src/sys/dev/nand/nand_ecc_pos.h 2010-03-12 = 22:06:08.000000000 -0300 @@ -29,13 +29,14 @@ #ifndef _DEV_NAND_ECC_POS_H_ #define _DEV_NAND_ECC_POS_H_ =20 -static uint16_t default_software_ecc_positions_16[] =3D {0, 1, 2, 3, 4, = 5}; +/*static uint16_t default_software_ecc_positions_16[] =3D {0, 1, 2, 3, = 6, 7}; */ +static uint16_t default_software_ecc_positions_16[] =3D {10, 8, 9, 15, = 13, 14}; =20 static uint16_t default_software_ecc_positions_64[] =3D { - 0, 1, 2, 3, 4, 5, - 15, 16, 17, 18, 19, 20, 21, - 31, 32, 33, 34, 35, 36, 37, - 47, 48, 49, 50, 51, 52, 53 + + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63 }; =20 #endif /* _DEV_NAND_ECC_POS_H_ */ diff -ru nand2/sys/dev/nand/nand_generic.c = mips-nand2/src/sys/dev/nand/nand_generic.c --- nand2/sys/dev/nand/nand_generic.c 2010-03-07 18:38:33.000000000 = -0300 +++ mips-nand2/src/sys/dev/nand/nand_generic.c 2010-03-16 = 10:39:18.000000000 -0300 @@ -88,6 +88,9 @@ static int onfi_read_parameter(struct nand_chip *chip, struct onfi_params *params); =20 +static int nand_send_address(device_t nand, int32_t row, int32_t col, + int8_t id); + static device_method_t onand_methods[] =3D { /* device interface */ DEVMETHOD(device_probe, onfi_nand_probe), @@ -180,9 +183,8 @@ struct nandbus_ivar *ivar; =20 ivar =3D device_get_ivars(dev); - if (ivar && !ivar->is_onfi && - (ivar->man_id =3D=3D NAND_MAN_SAMSUNG) && (ivar->dev_id =3D=3D= 0xd3)) { - device_set_desc(dev, "Large Samsung NAND"); + if (ivar && !ivar->is_onfi && ivar->params->page_size >=3D 512) = { + device_set_desc(dev, ivar->params->name); return (BUS_PROBE_DEFAULT); } =20 @@ -195,9 +197,8 @@ struct nandbus_ivar *ivar; =20 ivar =3D device_get_ivars(dev); - if (ivar && !ivar->is_onfi && - (ivar->man_id =3D=3D NAND_MAN_SAMSUNG) && (ivar->dev_id =3D=3D= 0x75)) { - device_set_desc(dev, "Small Samsung NAND"); + if (ivar && !ivar->is_onfi && ivar->params->page_size =3D=3D = 512) { + device_set_desc(dev, ivar->params->name); return (BUS_PROBE_DEFAULT); } =20 @@ -208,7 +209,6 @@ generic_nand_attach(device_t dev) { struct nand_chip *chip; - struct nand_params *chip_params; struct nandbus_ivar *ivar; struct onfi_params *onfi_params; device_t nandbus, nfc; @@ -218,8 +218,8 @@ chip->dev =3D dev; =20 ivar =3D device_get_ivars(dev); - chip->id.manufacturer_id =3D ivar->man_id; - chip->id.device_id =3D ivar->dev_id; + chip->id.man_id =3D ivar->man_id; + chip->id.dev_id =3D ivar->dev_id; chip->num =3D ivar->cs; =20 /* TODO remove when HW ECC supported */ @@ -243,16 +243,8 @@ free(onfi_params, M_DEVBUF); =20 } else { - chip_params =3D nand_get_params(&chip->id); - if (chip_params =3D=3D NULL) { - debug("Chip description not found!" - "(manuf: 0x%0x, chipid: 0x%0x)\n", - chip->id.manufacturer_id, - chip->id.device_id); - return (EINVAL); - } =20 - nand_set_params(chip, chip_params); + nand_set_params(chip, ivar->params); } =20 err =3D nand_init_stat(chip); @@ -343,7 +335,7 @@ if (nandbus_send_command(nandbus, NAND_CMD_READ_PARAMETER)) return (ENXIO); =20 - if (nandbus_send_address(nandbus, -1, -1, PAGE_PARAMETER_DEF)) + if (nand_send_address(chip->dev, -1, -1, PAGE_PARAMETER_DEF)) return (ENXIO); =20 if (nandbus_start_command(nandbus)) @@ -360,13 +352,15 @@ } =20 static int -send_read_page(device_t nandbus, uint8_t start_command, uint8_t = end_command, +send_read_page(device_t nand, uint8_t start_command, uint8_t = end_command, uint32_t row, uint32_t column) { + device_t nandbus =3D device_get_parent(nand); + if (nandbus_send_command(nandbus, start_command)) return (ENXIO); =20 - if (nandbus_send_address(nandbus, row, column, -1)) + if (nand_send_address(nand, row, column, -1)) return (ENXIO); =20 if (nandbus_send_command(nandbus, end_command)) @@ -396,16 +390,17 @@ =20 page_to_row(&chip->chip_geom, page, &row); =20 - if (send_read_page(nandbus, NAND_CMD_READ, NAND_CMD_READ_END, = row, + if (send_read_page(nand, NAND_CMD_READ, NAND_CMD_READ_END, row, offset)) return (ENXIO); =20 DELAY(chip->t_r); - if (check_fail(nandbus)) - return (ENXIO); =20 nandbus_read_buffer(nandbus, buf, len); =20 + if (check_fail(nandbus)) + return (ENXIO); + pg_stat =3D &(chip->pg_stat[page]); pg_stat->page_raw_read++; =20 @@ -431,27 +426,29 @@ =20 offset +=3D chip->chip_geom.page_size; =20 - if (send_read_page(nandbus, NAND_CMD_READ, NAND_CMD_READ_END, = row, + if (send_read_page(nand, NAND_CMD_READ, NAND_CMD_READ_END, row, offset)) return (ENXIO); =20 DELAY(chip->t_r); =20 + nandbus_read_buffer(nandbus, buf, len); + if (check_fail(nandbus)) return (ENXIO); =20 - nandbus_read_buffer(nandbus, buf, len); - return (0); } =20 static int -send_start_program_page(device_t nandbus, uint32_t row, uint32_t = column) +send_start_program_page(device_t nand, uint32_t row, uint32_t column) { + device_t nandbus =3D device_get_parent(nand); + if (nandbus_send_command(nandbus, NAND_CMD_PROG)) return (ENXIO); =20 - if (nandbus_send_address(nandbus, row, column, -1)) + if (nand_send_address(nand, row, column, -1)) return (ENXIO); =20 return (0); @@ -491,7 +488,7 @@ if (!can_write(nandbus)) return (ENXIO); =20 - if (send_start_program_page(nandbus, row, offset)) + if (send_start_program_page(nand, row, offset)) return (ENXIO); =20 nandbus_write_buffer(nandbus, buf, len); @@ -531,7 +528,7 @@ if (!can_write(nandbus)) return (ENXIO); =20 - if (send_start_program_page(nandbus, row, offset)) + if (send_start_program_page(nand, row, offset)) return (ENXIO); =20 nandbus_write_buffer(nandbus, buf, len); @@ -571,7 +568,7 @@ if (!can_write(nandbus)) return (ENXIO); =20 - if (send_start_program_page(nandbus, row, offset)) + if (send_start_program_page(nand, row, offset)) return (ENXIO); =20 nandbus_write_buffer(nandbus, buf, len); @@ -588,13 +585,14 @@ } =20 static int -send_erase_block(device_t nandbus, uint32_t row, uint8_t = second_command) +send_erase_block(device_t nand, uint32_t row, uint8_t second_command) { + device_t nandbus =3D device_get_parent(nand); =20 if (nandbus_send_command(nandbus, NAND_CMD_ERASE)) return (ENXIO); =20 - if (nandbus_send_address(nandbus, row, -1, -1)) + if (nand_send_address(nand, row, -1, -1)) return (ENXIO); =20 if (nandbus_send_command(nandbus, second_command)) @@ -615,8 +613,8 @@ int row; =20 debug("%p erase block %x", nand, block); - chip =3D device_get_softc(nand); nandbus =3D device_get_parent(nand); + chip =3D device_get_softc(nand); =20 if (block >=3D (chip->chip_geom.blks_per_lun * = chip->chip_geom.luns)) return (ENXIO); @@ -629,7 +627,7 @@ if (!can_write(nandbus)) return (ENXIO); =20 - send_erase_block(nandbus, row, NAND_CMD_ERASE_END); + send_erase_block(nand, row, NAND_CMD_ERASE_END); =20 DELAY(chip->t_bers); =20 @@ -651,8 +649,8 @@ int row; =20 debug("%p erase block %x", nand, block); - chip =3D device_get_softc(nand); nandbus =3D device_get_parent(nand); + chip =3D device_get_softc(nand); =20 if (block >=3D (chip->chip_geom.blks_per_lun * = chip->chip_geom.luns)) return (ENXIO); @@ -663,7 +661,7 @@ if (!can_write(nandbus)) return (ENXIO); =20 - send_erase_block(nandbus, row, NAND_CMD_ERASE_INTLV); + send_erase_block(nand, row, NAND_CMD_ERASE_INTLV); =20 DELAY(chip->t_bers); =20 @@ -720,13 +718,15 @@ } =20 static int -send_small_read_page(device_t nandbus, uint8_t start_command, +send_small_read_page(device_t nand, uint8_t start_command, uint32_t row, uint32_t column) { + device_t nandbus =3D device_get_parent(nand); + if (nandbus_send_command(nandbus, start_command)) return (ENXIO); =20 - if (nandbus_send_address(nandbus, row, column, -1)) + if (nand_send_address(nand, row, column, -1)) return (ENXIO); =20 if (nandbus_start_command(nandbus)) @@ -755,10 +755,10 @@ page_to_row(&chip->chip_geom, page, &row); =20 if (offset < 256) { - if (send_small_read_page(nandbus, NAND_CMD_SMALLA, row, = offset)) + if (send_small_read_page(nand, NAND_CMD_SMALLA, row, = offset)) return (ENXIO); } else { - if (send_small_read_page(nandbus, NAND_CMD_SMALLB, row, = offset)) + if (send_small_read_page(nand, NAND_CMD_SMALLB, row, = offset)) return (ENXIO); } =20 @@ -790,7 +790,7 @@ =20 page_to_row(&chip->chip_geom, page, &row); =20 - if (send_small_read_page(nandbus, NAND_CMD_SMALLOOB, row, = offset)) + if (send_small_read_page(nand, NAND_CMD_SMALLOOB, row, offset)) return (ENXIO); =20 DELAY(chip->t_r); @@ -831,7 +831,7 @@ return (ENXIO); } =20 - if (send_start_program_page(nandbus, row, offset)) + if (send_start_program_page(nand, row, offset)) return (ENXIO); =20 nandbus_write_buffer(nandbus, buf, len); @@ -870,7 +870,7 @@ if (nandbus_send_command(nandbus, NAND_CMD_SMALLOOB)) return (ENXIO); =20 - if (send_start_program_page(nandbus, row, offset)) + if (send_start_program_page(nand, row, offset)) return (ENXIO); =20 nandbus_write_buffer(nandbus, buf, len); @@ -886,6 +886,46 @@ return (0); } =20 +int +nand_send_address(device_t nand, int32_t row, int32_t col, int8_t id) +{ + struct nandbus_ivar *ivar; + device_t nandbus; + uint8_t addr; + int err =3D 0; + int i; + + nandbus =3D device_get_parent(nand); + ivar =3D device_get_ivars(nand); + + if (id !=3D -1) { + debug("send_address: send id %02x", id); + err =3D nandbus_send_address(nandbus, id); + } + + if (!err && col !=3D -1) { + for (i =3D 0; i < ivar->cols; i++, col >>=3D 8) { + addr =3D (uint8_t)(col & 0xff); + debug("send_address: send address column %02x", = addr); + err =3D nandbus_send_address(nandbus, addr); + if (err) + break; + } + } + + if (!err && row !=3D -1) { + for (i =3D 0; i < ivar->rows; i++, row >>=3D 8) { + addr =3D (uint8_t)(row & 0xff); + debug("send_address: send address row %02x", = addr); + err =3D nandbus_send_address(nandbus, addr); + if (err) + break; + } + } + + return (err); +} + #if 0 int nand_chng_read_col(device_t nand, uint32_t col, void *buf, size_t len) @@ -960,7 +1000,7 @@ =20 page_to_row(&chip->chip_geom, page, &row); =20 - if (send_read_page(nandbus, NAND_CMD_READ, NAND_CMD_READ_CPBK, = row, 0)) + if (send_read_page(nand, NAND_CMD_READ, NAND_CMD_READ_CPBK, row, = 0)) return (ENXIO); =20 DELAY(chip->t_r); @@ -1040,7 +1080,7 @@ if (!can_write(nandbus)) return (ENXIO); =20 - if (send_start_program_page(nandbus, row, 0)) + if (send_start_program_page(nand, row, 0)) return (ENXIO); =20 if (send_end_program_page(nandbus, NAND_CMD_PROG_INTLV)) @@ -1079,7 +1119,7 @@ if (!can_write(nandbus)) return (ENXIO); =20 - if (send_start_program_page(nandbus, row, 0)) + if (send_start_program_page(dev, row, 0)) return (ENXIO); =20 nandbus_write_buffer(nandbus, buf, len); diff -ru nand2/sys/dev/nand/nand_geom.c = mips-nand2/src/sys/dev/nand/nand_geom.c --- nand2/sys/dev/nand/nand_geom.c 2010-03-07 12:26:50.000000000 = -0300 +++ mips-nand2/src/sys/dev/nand/nand_geom.c 2010-03-16 = 10:40:30.000000000 -0300 @@ -252,7 +252,8 @@ disk->d_name =3D "gnand"; disk->d_drv1 =3D chip; disk->d_maxsize =3D chip->chip_geom.block_size; - disk->d_sectorsize =3D chip->chip_geom.block_size; +// disk->d_sectorsize =3D chip->chip_geom.block_size; + disk->d_sectorsize =3D chip->chip_geom.page_size; disk->d_mediasize =3D chip->chip_geom.chip_size; disk->d_pagesize =3D chip->chip_geom.page_size; disk->d_oobsize =3D chip->chip_geom.oob_size; @@ -262,8 +263,7 @@ disk->d_flags =3D DISKFLAG_CANDELETE; =20 snprintf(disk->d_ident, sizeof(disk->d_ident), - "nand: Man:0x%02x Dev:0x%02x", chip->id.manufacturer_id, - chip->id.device_id); + "nand: Man:0x%02x Dev:0x%02x", chip->id.man_id, = chip->id.dev_id); =20 gnand_create(disk); =20 @@ -279,7 +279,7 @@ TASK_INIT(&chip->iotask, 0, nand_io_proc, chip); =20 device_printf(chip->dev, "Created gnand%d for chip [0x%0x, = 0x%0x]\n", - disk->d_unit, chip->id.manufacturer_id, chip->id.device_id); + disk->d_unit, chip->id.man_id, chip->id.dev_id); =20 return (0); } diff -ru nand2/sys/dev/nand/nand_id.c = mips-nand2/src/sys/dev/nand/nand_id.c --- nand2/sys/dev/nand/nand_id.c 2010-03-07 12:26:50.000000000 = -0300 +++ mips-nand2/src/sys/dev/nand/nand_id.c 2010-03-16 = 08:45:12.000000000 -0300 @@ -33,13 +33,17 @@ #include =20 struct nand_params nand_ids[] =3D { - {{NAND_MAN_SAMSUNG, 0x75}, - "Samsung K9F5608U0B", 0x200, 0x10, - 0x20, 0x800, 0 }, - - {{NAND_MAN_SAMSUNG, 0xd3}, - "Samsung NAND 1GiB 3,3V 8-bit", 0x800, 0x40, - 0x40, 0x2000, 0 }, + { { NAND_MAN_SAMSUNG, 0x75 }, "Samsung K9F5608U0B", + 0x20, 0x200, 0x10, 0x20, 0 }, + + { { NAND_MAN_SAMSUNG, 0xd3 }, "Samsung NAND 1GiB 3,3V 8-bit", + 0x400, 0x800, 0x40, 0x40, 0 }, + + { { NAND_MAN_HYNIX, 0x76 }, "Hynix NAND 64MiB 3,3V 8-bit", + 0x40, 0x200, 0x10, 0x20, 0 }, + + { { NAND_MAN_HYNIX, 0xdc }, "Hynix NAND 512MiB 3,3V 8-bit", + 0x200, 0x800, 0x40, 0x80, 0 }, }; =20 struct nand_params *nand_get_params(struct nand_id *id) @@ -47,8 +51,8 @@ int i; =20 for (i =3D 0; i < sizeof(nand_ids) / sizeof(nand_ids[0]); i++) - if (nand_ids[i].id.manufacturer_id =3D=3D = id->manufacturer_id && - nand_ids[i].id.device_id =3D=3D id->device_id) + if (nand_ids[i].id.man_id =3D=3D id->man_id && + nand_ids[i].id.dev_id =3D=3D id->dev_id) return (&nand_ids[i]); =20 return (NULL); diff -ru nand2/sys/dev/nand/nandbus.c = mips-nand2/src/sys/dev/nand/nandbus.c --- nand2/sys/dev/nand/nandbus.c 2010-03-07 12:26:51.000000000 = -0300 +++ mips-nand2/src/sys/dev/nand/nandbus.c 2010-03-16 = 10:41:57.000000000 -0300 @@ -146,10 +146,12 @@ nandbus_attach(device_t dev) { device_t child, nfc; + struct nand_id chip_id; struct nandbus_softc *sc; struct nandbus_ivar *ivar; - struct nand_softc* nfc_sc; - uint8_t cs, man_id, dev_id, onfi, found =3D 0; + struct nand_softc *nfc_sc; + struct nand_params *chip_params; + uint8_t cs, onfi, found =3D 0; =20 sc =3D device_get_softc(dev); sc->dev =3D dev; @@ -172,10 +174,10 @@ continue; =20 /* Read manufacturer and device id */ - if (nand_readid(dev, &man_id, &dev_id)) + if (nand_readid(dev, &chip_id.man_id, &chip_id.dev_id)) continue; =20 - if (man_id =3D=3D 0xff) + if (chip_id.man_id =3D=3D 0xff) continue; =20 /* Check if chip is ONFI compliant */ @@ -183,17 +185,39 @@ continue; } =20 + chip_params =3D nand_get_params(&chip_id); + if (chip_params =3D=3D NULL) { + debug("Chip description not found!" + "(manuf: 0x%0x, chipid: 0x%0x)\n", + chip_id.man_id, chip_id.dev_id); + continue; + } + ivar =3D malloc(sizeof(struct nandbus_ivar), M_DEVBUF, M_NOWAIT); if (!ivar) return (ENOMEM); =20 ivar->cs =3D cs; - ivar->man_id =3D man_id; - ivar->dev_id =3D dev_id; + ivar->cols =3D 1; + ivar->rows =3D 2; + ivar->params =3D chip_params; + ivar->man_id =3D chip_id.man_id; + ivar->dev_id =3D chip_id.dev_id; ivar->is_onfi =3D onfi; ivar->chip_cdev_name =3D nfc_sc->chip_cdev_name; =20 + /* + * check what type of device we have. + * devices bigger than 32MiB have on more row (3) + */=20 + if (chip_params->chip_size > 32) + ivar->rows++; + /* large page devices have one more col (2) */ + if (chip_params->chip_size >=3D 128 && + chip_params->page_size > 512) + ivar->cols++; + child =3D device_add_child(dev, NULL, -1); device_set_ivars(child, ivar); found =3D 1; @@ -254,7 +278,7 @@ return (ENXIO); } =20 - if (NFC_SEND_ADDRESS(nfc, -1, -1, 0)) { + if (NFC_SEND_ADDRESS(nfc, 0)) { debug("Error : could not sent address to chip"); return (ENXIO); } @@ -290,7 +314,7 @@ return (ENXIO); } =20 - if (NFC_SEND_ADDRESS(nfc, -1, -1, ONFI_SIG_ADDR)) { + if (NFC_SEND_ADDRESS(nfc, ONFI_SIG_ADDR)) { debug("Error : could not sent address to chip"); return (ENXIO); } @@ -381,13 +405,12 @@ } =20 int -nandbus_send_address(device_t dev, int32_t row, int32_t col, int8_t = off) +nandbus_send_address(device_t dev, uint8_t address) { int err; =20 - if ((err =3D NFC_SEND_ADDRESS(device_get_parent(dev), row, col, = off))) - debug("Err: Could not send %x-%x-%x address, err %d", - row, col, off, err); + if ((err =3D NFC_SEND_ADDRESS(device_get_parent(dev), address))) + debug("Err: Could not send address %x, err %x", address, = err); =20 return (err); } diff -ru nand2/sys/dev/nand/nandbus.h = mips-nand2/src/sys/dev/nand/nandbus.h --- nand2/sys/dev/nand/nandbus.h 2010-03-07 12:26:51.000000000 = -0300 +++ mips-nand2/src/sys/dev/nand/nandbus.h 2010-03-16 = 09:34:06.000000000 -0300 @@ -30,11 +30,14 @@ #define _NANDBUS_H_ =20 struct nandbus_ivar { - uint8_t cs; - uint8_t man_id; - uint8_t dev_id; - uint8_t is_onfi; - char *chip_cdev_name; + uint8_t cs; + uint8_t cols; + uint8_t rows; + uint8_t man_id; + uint8_t dev_id; + uint8_t is_onfi; + char *chip_cdev_name; + struct nand_params *params; }; =20 extern devclass_t nandbus_devclass; @@ -47,7 +50,7 @@ void nandbus_read_buffer(device_t dev, void *buf, uint32_t len); int nandbus_select_cs(device_t dev, uint8_t cs); int nandbus_send_command(device_t dev, uint8_t command); -int nandbus_send_address(device_t dev, int32_t row, int32_t col, int8_t = off); +int nandbus_send_address(device_t dev, uint8_t address); int nandbus_start_command(device_t dev); int nandbus_wait_ready(device_t dev, uint8_t *status); void nandbus_write_buffer(device_t dev, void *buf, uint32_t len); diff -ru nand2/sys/dev/nand/nfc_if.m = mips-nand2/src/sys/dev/nand/nfc_if.m --- nand2/sys/dev/nand/nfc_if.m 2010-03-07 12:26:52.000000000 -0300 +++ mips-nand2/src/sys/dev/nand/nfc_if.m 2010-03-16 = 07:36:05.000000000 -0300 @@ -57,9 +57,7 @@ # METHOD int send_address { device_t dev; - int32_t page; - int32_t column; - int8_t id; + uint8_t address; }; =20 # Read byte diff -ru nand2/sys/dev/nand/nfc_mv.c = mips-nand2/src/sys/dev/nand/nfc_mv.c --- nand2/sys/dev/nand/nfc_mv.c 2010-03-07 12:34:07.000000000 -0300 +++ mips-nand2/src/sys/dev/nand/nfc_mv.c 2010-03-16 = 08:10:25.000000000 -0300 @@ -74,8 +74,7 @@ static int mv_nand_attach(device_t dev); static int mv_nand_probe(device_t dev); static int mv_nand_send_command(device_t dev, uint8_t command); -static int mv_nand_send_address(device_t dev, int32_t row, - int32_t column, int8_t id); +static int mv_nand_send_address(device_t dev, uint8_t addr); static uint8_t mv_nand_read_byte(device_t dev); static void mv_nand_read_buf(device_t dev, void* buf, uint32_t len); static void mv_nand_write_buf(device_t dev, void* buf, uint32_t = len); @@ -140,30 +139,10 @@ =20 =20 static int -mv_nand_send_address(device_t dev, int32_t row, int32_t column, - int8_t id) +mv_nand_send_address(device_t dev, uint8_t addr) { - struct mv_nand_softc *sc; - sc =3D device_get_softc(dev); - - if (id !=3D -1) { - debug("mv_nand: send address %x", id); - MV_NAND_WRITE(MV_NAND_ADDRESS, id); - } =20 - /* TODO add number of address cycles to function parameters */ - if (column !=3D -1) { - debug("mv_nand: send address %x", - column & 0xff); - MV_NAND_WRITE(MV_NAND_ADDRESS, column & 0xff); - } - - if (row !=3D -1) { - debug("mv_nand: send address %x %x", - row & 0xff, (row >> 8) & 0xff); - MV_NAND_WRITE(MV_NAND_ADDRESS, row & 0xff); - MV_NAND_WRITE(MV_NAND_ADDRESS, (row >> 8) & 0xff); - } + MV_NAND_WRITE(MV_NAND_ADDRESS, addr); =20 return (0); } --Apple-Mail-32-531872463--