Date: Tue, 21 Sep 2010 04:29:27 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r212947 - in stable/8: share/man/man4/man4.powerpc sys/dev/powermac_nvram Message-ID: <201009210429.o8L4TRu9078897@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Tue Sep 21 04:29:27 2010 New Revision: 212947 URL: http://svn.freebsd.org/changeset/base/212947 Log: MFC r212240: Add support for the Sharp/Micron flash chips to powermac_mvram(4). Tested on PowerMac G4 AGP. Modified: stable/8/share/man/man4/man4.powerpc/powermac_nvram.4 stable/8/sys/dev/powermac_nvram/powermac_nvram.c stable/8/sys/dev/powermac_nvram/powermac_nvramvar.h Directory Properties: stable/8/share/man/man4/ (props changed) stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) Modified: stable/8/share/man/man4/man4.powerpc/powermac_nvram.4 ============================================================================== --- stable/8/share/man/man4/man4.powerpc/powermac_nvram.4 Tue Sep 21 04:23:27 2010 (r212946) +++ stable/8/share/man/man4/man4.powerpc/powermac_nvram.4 Tue Sep 21 04:29:27 2010 (r212947) @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 1, 2006 +.Dd September 5, 2010 .Dt POWERMAC_NVRAM 4 powerpc .Os .Sh NAME @@ -63,8 +63,3 @@ The .Nm driver was written by .An Maxim Sobolev Aq sobomax@FreeBSD.org . -.Sh BUGS -Currently, the -.Nm -driver only supports systems equipped with an AMD flash part and is only -tested on Apple G4-based Mac Mini machines. Modified: stable/8/sys/dev/powermac_nvram/powermac_nvram.c ============================================================================== --- stable/8/sys/dev/powermac_nvram/powermac_nvram.c Tue Sep 21 04:23:27 2010 (r212946) +++ stable/8/sys/dev/powermac_nvram/powermac_nvram.c Tue Sep 21 04:29:27 2010 (r212947) @@ -115,7 +115,10 @@ powermac_nvram_probe(device_t dev) if (type == NULL || compatible == NULL) return ENXIO; - if (strcmp(type, "nvram") != 0 || strcmp(compatible, "amd-0137") != 0) + if (strcmp(type, "nvram") != 0) + return ENXIO; + if (strcmp(compatible, "amd-0137") != 0 && + strcmp(compatible, "nvram,flash") != 0) return ENXIO; device_set_desc(dev, "Apple NVRAM"); @@ -126,6 +129,7 @@ static int powermac_nvram_attach(device_t dev) { struct powermac_nvram_softc *sc; + const char *compatible; phandle_t node; u_int32_t reg[3]; int gen0, gen1, i; @@ -139,6 +143,12 @@ powermac_nvram_attach(device_t dev) sc->sc_dev = dev; sc->sc_node = node; + compatible = ofw_bus_get_compat(dev); + if (strcmp(compatible, "amd-0137") == 0) + sc->sc_type = FLASH_TYPE_AMD; + else + sc->sc_type = FLASH_TYPE_SM; + /* * Find which byte of reg corresponds to the 32-bit physical address. * We should probably read #address-cells from /chosen instead. @@ -342,7 +352,7 @@ adler_checksum(uint8_t *data, int len) #define OUTB_DELAY(a, v) outb(a, v); DELAY(1); static int -wait_operation_complete(uint8_t *bank) +wait_operation_complete_amd(uint8_t *bank) { int i; @@ -353,7 +363,7 @@ wait_operation_complete(uint8_t *bank) } static int -erase_bank(device_t dev, uint8_t *bank) +erase_bank_amd(device_t dev, uint8_t *bank) { unsigned int i; @@ -368,7 +378,7 @@ erase_bank(device_t dev, uint8_t *bank) OUTB_DELAY(bank + 0x2aa, 0x55); OUTB_DELAY(bank, 0x30); - if (wait_operation_complete(bank) != 0) { + if (wait_operation_complete_amd(bank) != 0) { device_printf(dev, "flash erase timeout\n"); return -1; } @@ -386,7 +396,7 @@ erase_bank(device_t dev, uint8_t *bank) } static int -write_bank(device_t dev, uint8_t *bank, uint8_t *data) +write_bank_amd(device_t dev, uint8_t *bank, uint8_t *data) { unsigned int i; @@ -399,7 +409,7 @@ write_bank(device_t dev, uint8_t *bank, /* Write single word */ OUTB_DELAY(bank + 0x555, 0xa0); OUTB_DELAY(bank + i, data[i]); - if (wait_operation_complete(bank) != 0) { + if (wait_operation_complete_amd(bank) != 0) { device_printf(dev, "flash write timeout\n"); return -1; } @@ -416,3 +426,91 @@ write_bank(device_t dev, uint8_t *bank, } return 0; } + +static int +wait_operation_complete_sm(uint8_t *bank) +{ + int i; + + for (i = 1000000; i != 0; i--) { + outb(bank, SM_FLASH_CMD_READ_STATUS); + if (inb(bank) & SM_FLASH_STATUS_DONE) + return (0); + } + return (-1); +} + +static int +erase_bank_sm(device_t dev, uint8_t *bank) +{ + unsigned int i; + + outb(bank, SM_FLASH_CMD_ERASE_SETUP); + outb(bank, SM_FLASH_CMD_ERASE_CONFIRM); + + if (wait_operation_complete_sm(bank) != 0) { + device_printf(dev, "flash erase timeout\n"); + return (-1); + } + + outb(bank, SM_FLASH_CMD_CLEAR_STATUS); + outb(bank, SM_FLASH_CMD_RESET); + + for (i = 0; i < NVRAM_SIZE; i++) { + if (bank[i] != 0xff) { + device_printf(dev, "flash write has failed\n"); + return (-1); + } + } + return (0); +} + +static int +write_bank_sm(device_t dev, uint8_t *bank, uint8_t *data) +{ + unsigned int i; + + for (i = 0; i < NVRAM_SIZE; i++) { + OUTB_DELAY(bank + i, SM_FLASH_CMD_WRITE_SETUP); + outb(bank + i, data[i]); + if (wait_operation_complete_sm(bank) != 0) { + device_printf(dev, "flash write error/timeout\n"); + break; + } + } + + outb(bank, SM_FLASH_CMD_CLEAR_STATUS); + outb(bank, SM_FLASH_CMD_RESET); + + for (i = 0; i < NVRAM_SIZE; i++) { + if (bank[i] != data[i]) { + device_printf(dev, "flash write has failed\n"); + return (-1); + } + } + return (0); +} + +static int +erase_bank(device_t dev, uint8_t *bank) +{ + struct powermac_nvram_softc *sc; + + sc = device_get_softc(dev); + if (sc->sc_type == FLASH_TYPE_AMD) + return (erase_bank_amd(dev, bank)); + else + return (erase_bank_sm(dev, bank)); +} + +static int +write_bank(device_t dev, uint8_t *bank, uint8_t *data) +{ + struct powermac_nvram_softc *sc; + + sc = device_get_softc(dev); + if (sc->sc_type == FLASH_TYPE_AMD) + return (write_bank_amd(dev, bank, data)); + else + return (write_bank_sm(dev, bank, data)); +} Modified: stable/8/sys/dev/powermac_nvram/powermac_nvramvar.h ============================================================================== --- stable/8/sys/dev/powermac_nvram/powermac_nvramvar.h Tue Sep 21 04:23:27 2010 (r212946) +++ stable/8/sys/dev/powermac_nvram/powermac_nvramvar.h Tue Sep 21 04:29:27 2010 (r212947) @@ -33,6 +33,16 @@ #define CORE99_SIGNATURE 0x5a +#define SM_FLASH_CMD_ERASE_CONFIRM 0xd0 +#define SM_FLASH_CMD_ERASE_SETUP 0x20 +#define SM_FLASH_CMD_RESET 0xff +#define SM_FLASH_CMD_WRITE_SETUP 0x40 +#define SM_FLASH_CMD_CLEAR_STATUS 0x50 +#define SM_FLASH_CMD_READ_STATUS 0x70 + +#define SM_FLASH_STATUS_DONE 0x80 +#define SM_FLASH_STATUS_ERR 0x38 + #ifdef _KERNEL struct powermac_nvram_softc { @@ -44,6 +54,9 @@ struct powermac_nvram_softc { uint8_t sc_data[NVRAM_SIZE]; struct cdev * sc_cdev; + int sc_type; +#define FLASH_TYPE_SM 0 +#define FLASH_TYPE_AMD 1 int sc_isopen; int sc_rpos; int sc_wpos;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201009210429.o8L4TRu9078897>