From owner-freebsd-mips@FreeBSD.ORG Mon Oct 26 04:05:59 2009 Return-Path: Delivered-To: freebsd-mips@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 395781065670; Mon, 26 Oct 2009 04:05:59 +0000 (UTC) (envelope-from awmdpt@gmail.com) Received: from mail-gx0-f218.google.com (mail-gx0-f218.google.com [209.85.217.218]) by mx1.freebsd.org (Postfix) with ESMTP id D1C6F8FC1F; Mon, 26 Oct 2009 04:05:58 +0000 (UTC) Received: by gxk10 with SMTP id 10so9861761gxk.3 for ; Sun, 25 Oct 2009 21:05:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:sender:subject:from:to:cc :content-type:date:message-id:mime-version:x-mailer; bh=fDDZ+73lUSbDg13muEci2c2D56VwwxYFFcfBCPcizBs=; b=lm2ETYMAwx1f3e1iqW80vgiXWna3b2NihhA/aYAzKKmynsG/KdkSFcumDRtDcMkS8W aNNyRzEWL6/ezq6jZhg5y92JpYIavUHQkZnHE3Wj/yuqa4WEFvyMOrTadzA1pz4GkByI Cbz7x+N4RHBjLGWLjtQvLju5xmvLb/9h7wsPk= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:subject:from:to:cc:content-type:date:message-id:mime-version :x-mailer; b=DwUdDOK4K1+/s5clajPktBxXsQS7NQJgKwqnAilN+Eh6XNoxhwPmWpcV92hHqFxiUo K1A5DJgPHbb9TuIwNHl3RR1wiCGvDbtkIlzVNixFsJ3l/YhishmtM/RJELehZQNT9LHs CalaNTyClyY2gYqyiB9CdRE6Z0Jh1S6hWHLe0= Received: by 10.100.74.13 with SMTP id w13mr279473ana.168.1256528278082; Sun, 25 Oct 2009 20:37:58 -0700 (PDT) Received: from ?192.168.10.117? (114-33-76-31.HINET-IP.hinet.net [114.33.76.31]) by mx.google.com with ESMTPS id 20sm1207299yxe.38.2009.10.25.20.37.55 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sun, 25 Oct 2009 20:37:57 -0700 (PDT) Sender: Eric From: Eric To: gonzo@freebsd.org Content-Type: multipart/mixed; boundary="=-cGh19E6cDpSf0EFAbWSZ" Date: Mon, 26 Oct 2009 11:37:52 +0800 Message-ID: <1256528272.31398.28.camel@localhost> Mime-Version: 1.0 X-Mailer: Evolution 2.28.1 FreeBSD GNOME Team Port Cc: freebsd-mips@freebsd.org Subject: Add Wistron RPAA-82 board support X-BeenThere: freebsd-mips@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Porting FreeBSD to MIPS List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Oct 2009 04:05:59 -0000 --=-cGh19E6cDpSf0EFAbWSZ Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit Hi I added my ar7161 board support last weekend. It's flash is come from Spansion. -- Best Regards, Eric L. Chen --=-cGh19E6cDpSf0EFAbWSZ Content-Disposition: attachment; filename="patch-mips-spiflash.diff" Content-Type: text/x-patch; name="patch-mips-spiflash.diff"; charset="UTF-8" Content-Transfer-Encoding: 7bit Index: src-mips/sys/dev/flash/mx25l.c =================================================================== --- src-mips/sys/dev/flash/mx25l.c (revision 198476) +++ src-mips/sys/dev/flash/mx25l.c (working copy) @@ -59,6 +59,8 @@ device_t sc_dev; uint8_t sc_manufacturer_id; uint16_t sc_device_id; + unsigned int sc_sectorsize; + unsigned int sc_sectorcount; struct mtx sc_mtx; struct disk *sc_disk; struct proc *sc_p; @@ -85,6 +87,7 @@ { "mx25ll32", 0xc2, 0x2016, 64 * 1024, 64 }, { "mx25ll64", 0xc2, 0x2017, 64 * 1024, 128 }, { "mx25ll128", 0xc2, 0x2018, 64 * 1024, 256 }, + { "s25fl128", 0x01, 0x2018, 64 * 1024, 256 }, }; static uint8_t @@ -172,6 +175,7 @@ cmd.rx_cmd = rxBuf; cmd.rx_cmd_sz = 1; cmd.tx_cmd_sz = 1; + mx25l_wait_for_device_ready(dev); err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); } @@ -182,7 +186,6 @@ struct spi_command cmd; int err; - mx25l_wait_for_device_ready(dev); mx25l_set_writable(dev, 1); memset(&cmd, 0, sizeof(cmd)); @@ -197,10 +200,134 @@ txBuf[1] = ((sector >> 16) & 0xff); txBuf[2] = ((sector >> 8) & 0xff); txBuf[3] = (sector & 0xff); + mx25l_wait_for_device_ready(dev); err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); } +static void +mx25l_write_sector(device_t dev, off_t offset, caddr_t data) +{ + struct mx25l_softc *sc = device_get_softc(dev); + uint8_t txBuf[4], rxBuf[4]; + struct spi_command cmd; + uint8_t *ptr = (uint8_t*)data; + long n; + int err; + + for (n = 0; n < sc->sc_sectorsize; n += FLASH_PAGE_SIZE) { + bzero(&cmd, sizeof(cmd)); + bzero(txBuf, sizeof(txBuf)); + bzero(rxBuf, sizeof(rxBuf)); + + cmd.tx_cmd_sz = 4; + cmd.rx_cmd_sz = 4; + cmd.tx_cmd = txBuf; + cmd.rx_cmd = rxBuf; + + txBuf[0] = CMD_PAGE_PROGRAM; + txBuf[1] = (((offset + n) >> 16) & 0xff); + txBuf[2] = (((offset + n) >> 8) & 0xff); + txBuf[3] = ((offset + n) & 0xff); + + cmd.tx_data = ptr + n; + cmd.tx_data_sz = FLASH_PAGE_SIZE; + cmd.rx_data = ptr + n; + cmd.rx_data_sz = FLASH_PAGE_SIZE; + + mx25l_set_writable(dev, 1); + mx25l_wait_for_device_ready(dev); + err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); + } +} + static int +mx25l_read(device_t dev, off_t offset, long count, caddr_t data) +{ + uint8_t txBuf[8], rxBuf[8]; + struct spi_command cmd; + int ret; + + bzero(&cmd, sizeof(cmd)); + bzero(txBuf, sizeof(txBuf)); + bzero(rxBuf, sizeof(rxBuf)); + + cmd.tx_cmd_sz = 5; + cmd.rx_cmd_sz = 5; + + txBuf[0] = CMD_FAST_READ; + txBuf[1] = ((offset >> 16) & 0xff); + txBuf[2] = ((offset >> 8) & 0xff); + txBuf[3] = (offset & 0xff); + txBuf[4] = 0; /* Dummy byte required by fast read */ + + cmd.tx_cmd = txBuf; + cmd.rx_cmd = rxBuf; + cmd.tx_data = data; + cmd.tx_data_sz = count; + cmd.rx_data = data; + cmd.rx_data_sz = count; + mx25l_wait_for_device_ready(dev); + ret = SPIBUS_TRANSFER(device_get_parent(dev), dev, &cmd); + + return ret; +} + +static int +mx25l_write(device_t dev, off_t offset, long count, caddr_t data) +{ + struct mx25l_softc *sc = device_get_softc(dev); + off_t sector; + int sector_offset, sector_remain, i, n; + uint8_t *temp, *ptr = (uint8_t*)data; + + temp = malloc(sc->sc_sectorsize, M_TEMP, M_WAITOK); + if (NULL == temp){ + printf("%s: failed to alloc.\n", __func__); + return -1; + } + + sector_offset = offset % sc->sc_sectorsize; + sector_remain = sc->sc_sectorsize - sector_offset; + sector = offset - sector_offset; + + if (sector_remain >= count) { + /* in sector */ + mx25l_read(dev, sector, sc->sc_sectorsize, temp); + bcopy(ptr, temp + sector_offset, count); + mx25l_erase_sector(dev, sector); + mx25l_write_sector(dev, sector, temp); + } else { + /* cross sectoer, first */ + mx25l_read(dev, sector, sc->sc_sectorsize, temp); + bcopy(ptr, temp + sector_offset, sector_remain); + mx25l_erase_sector(dev, sector); + mx25l_write_sector(dev, sector, temp); + count -= sector_remain; + ptr += sector_remain; + + /* inter */ + n = count / sc->sc_sectorsize; + for (i = 0; i < n; i++) { + mx25l_erase_sector(dev, sector); + mx25l_write_sector(dev, sector, ptr); + count -= sc->sc_sectorsize; + sector += sc->sc_sectorsize; + ptr += sc->sc_sectorsize; + } + /* last */ + if (count > 0) { + mx25l_read(dev, sector, sc->sc_sectorsize, temp); + bcopy(ptr, temp, count); + mx25l_erase_sector(dev, sector); + mx25l_write_sector(dev, sector, temp); + } + + } + free(temp, M_TEMP); + return 0; +} + +static int mx25l_probe(device_t dev) { device_set_desc(dev, "M25Pxx Flash Family"); @@ -223,6 +350,11 @@ mx25l_wait_for_device_ready(sc->sc_dev); + sc->sc_manufacturer_id = ident->manufacturer_id; + sc->sc_device_id = ident->device_id; + sc->sc_sectorsize = ident->sectorsize; + sc->sc_sectorcount = ident->sectorcount; + sc->sc_disk = disk_alloc(); sc->sc_disk->d_open = mx25l_open; sc->sc_disk->d_close = mx25l_close; @@ -231,7 +363,7 @@ sc->sc_disk->d_name = "flash/spi"; sc->sc_disk->d_drv1 = sc; sc->sc_disk->d_maxsize = DFLTPHYS; - sc->sc_disk->d_sectorsize = ident->sectorsize; + sc->sc_disk->d_sectorsize = 512; sc->sc_disk->d_mediasize = ident->sectorsize * ident->sectorcount; sc->sc_disk->d_unit = device_get_unit(sc->sc_dev); sc->sc_disk->d_dump = NULL; /* NB: no dumps */ @@ -294,15 +426,10 @@ { struct mx25l_softc *sc = (struct mx25l_softc*)arg; struct bio *bp; - uint8_t txBuf[8], rxBuf[8]; - struct spi_command cmd; - device_t dev, pdev; - off_t write_offset; - long bytes_to_write, bytes_writen; + device_t dev; + dev = sc->sc_dev; for (;;) { - dev = sc->sc_dev; - pdev = device_get_parent(dev); M25PXX_LOCK(sc); do { bp = bioq_first(&sc->sc_bio_queue); @@ -312,84 +439,16 @@ bioq_remove(&sc->sc_bio_queue, bp); M25PXX_UNLOCK(sc); - if (bp->bio_cmd == BIO_READ) { - txBuf[0] = CMD_FAST_READ; - cmd.tx_cmd_sz = 5; - cmd.rx_cmd_sz = 5; - - txBuf[1] = (((bp->bio_offset) >> 16) & 0xff); - txBuf[2] = (((bp->bio_offset) >> 8) & 0xff); - txBuf[3] = ((bp->bio_offset) & 0xff); - /* Dummy byte */ - txBuf[4] = 0; - - cmd.tx_cmd = txBuf; - cmd.rx_cmd = rxBuf; - cmd.tx_data = bp->bio_data; - cmd.tx_data_sz = bp->bio_bcount; - cmd.rx_data = bp->bio_data; - cmd.rx_data_sz = bp->bio_bcount; - - bp->bio_error = SPIBUS_TRANSFER(pdev, dev, &cmd); + switch(bp->bio_cmd) { + case BIO_READ: + bp->bio_error = mx25l_read(dev, bp->bio_offset, bp->bio_bcount, bp->bio_data); + bp->bio_resid = 0; + break; + case BIO_WRITE: + bp->bio_error = mx25l_write(dev, bp->bio_offset, bp->bio_bcount, bp->bio_data); + bp->bio_resid = 0; + break; } - else if (bp->bio_cmd == BIO_WRITE) { - mx25l_erase_sector(dev, bp->bio_offset); - - cmd.tx_cmd_sz = 4; - cmd.rx_cmd_sz = 4; - - bytes_writen = 0; - write_offset = bp->bio_offset; - - /* - * I assume here that we write per-sector only - * and sector size should be 256 bytes aligned - */ - KASSERT(write_offset % FLASH_PAGE_SIZE == 0, - ("offset for BIO_WRITE is not %d bytes aliIgned", - FLASH_PAGE_SIZE)); - - /* - * Maximum write size for CMD_PAGE_PROGRAM is - * FLASH_PAGE_SIZE, so split data to chunks - * FLASH_PAGE_SIZE bytes eash and write them - * one by one - */ - while (bytes_writen < bp->bio_bcount) { - txBuf[0] = CMD_PAGE_PROGRAM; - txBuf[1] = ((write_offset >> 16) & 0xff); - txBuf[2] = ((write_offset >> 8) & 0xff); - txBuf[3] = (write_offset & 0xff); - - bytes_to_write = MIN(FLASH_PAGE_SIZE, - bp->bio_bcount - bytes_writen); - cmd.tx_cmd = txBuf; - cmd.rx_cmd = rxBuf; - cmd.tx_data = bp->bio_data + bytes_writen; - cmd.tx_data_sz = bytes_to_write; - cmd.rx_data = bp->bio_data + bytes_writen; - cmd.rx_data_sz = bytes_to_write; - - /* - * Eash completed write operation resets WEL - * (write enable latch) to disabled state, - * so we re-enable it here - */ - mx25l_wait_for_device_ready(dev); - mx25l_set_writable(dev, 1); - - bp->bio_error = SPIBUS_TRANSFER(pdev, dev, &cmd); - if (bp->bio_error) - break; - - bytes_writen += bytes_to_write; - write_offset += bytes_to_write; - } - } - else - bp->bio_error = EINVAL; - - biodone(bp); } } Index: src-mips/sys/dev/flash/mx25lreg.h =================================================================== --- src-mips/sys/dev/flash/mx25lreg.h (revision 198476) +++ src-mips/sys/dev/flash/mx25lreg.h (working copy) @@ -46,6 +46,7 @@ * Status register flags */ #define STATUS_SRWD (1 << 7) +#define STATUS_BP3 (1 << 5) #define STATUS_BP2 (1 << 4) #define STATUS_BP1 (1 << 3) #define STATUS_BP0 (1 << 2) Index: src-mips/sys/geom/geom_redboot.c =================================================================== --- src-mips/sys/geom/geom_redboot.c (revision 198476) +++ src-mips/sys/geom/geom_redboot.c (working copy) @@ -366,16 +366,23 @@ return (NULL); g_topology_unlock(); head = NULL; - offset = cp->provider->mediasize - blksize; -again: - buf = g_read_data(cp, offset, blksize, NULL); + /* + * Find out FIS Directory block by block + */ + buf = g_read_data(cp, 0, blksize, NULL); if (buf != NULL) - head = parse_fis_directory(buf, blksize, offset, offmask); - if (head == NULL && offset != 0) { - if (buf != NULL) - g_free(buf); - offset = 0; /* check the front */ - goto again; + head = parse_fis_directory(buf, blksize, 0, offmask); + if (head == NULL) { + g_free(buf); + for (offset = cp->provider->mediasize - blksize; offset > 0; offset -= blksize) { + buf = g_read_data(cp, offset, blksize, NULL); + if (buf != NULL) + head = parse_fis_directory(buf, blksize, offset, offmask); + if (head) + break; + if (buf != NULL) + g_free(buf); + } } g_topology_lock(); if (head == NULL) { --=-cGh19E6cDpSf0EFAbWSZ--