From owner-svn-src-head@FreeBSD.ORG Sun Sep 5 20:04:02 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id CAF2610656B0; Sun, 5 Sep 2010 20:04:02 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id B97DF8FC17; Sun, 5 Sep 2010 20:04:02 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o85K42e4097268; Sun, 5 Sep 2010 20:04:02 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o85K429X097264; Sun, 5 Sep 2010 20:04:02 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201009052004.o85K429X097264@svn.freebsd.org> From: Alexander Motin Date: Sun, 5 Sep 2010 20:04:02 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r212240 - in head: share/man/man4/man4.powerpc sys/dev/powermac_nvram X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 05 Sep 2010 20:04:02 -0000 Author: mav Date: Sun Sep 5 20:04:02 2010 New Revision: 212240 URL: http://svn.freebsd.org/changeset/base/212240 Log: Add support for the Sharp/Micron flash chips to powermac_mvram(4). Tested on PowerMac G4 AGP. Reviewed by: nwhitehorn Modified: head/share/man/man4/man4.powerpc/powermac_nvram.4 head/sys/dev/powermac_nvram/powermac_nvram.c head/sys/dev/powermac_nvram/powermac_nvramvar.h Modified: head/share/man/man4/man4.powerpc/powermac_nvram.4 ============================================================================== --- head/share/man/man4/man4.powerpc/powermac_nvram.4 Sun Sep 5 19:57:24 2010 (r212239) +++ head/share/man/man4/man4.powerpc/powermac_nvram.4 Sun Sep 5 20:04:02 2010 (r212240) @@ -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: head/sys/dev/powermac_nvram/powermac_nvram.c ============================================================================== --- head/sys/dev/powermac_nvram/powermac_nvram.c Sun Sep 5 19:57:24 2010 (r212239) +++ head/sys/dev/powermac_nvram/powermac_nvram.c Sun Sep 5 20:04:02 2010 (r212240) @@ -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: head/sys/dev/powermac_nvram/powermac_nvramvar.h ============================================================================== --- head/sys/dev/powermac_nvram/powermac_nvramvar.h Sun Sep 5 19:57:24 2010 (r212239) +++ head/sys/dev/powermac_nvram/powermac_nvramvar.h Sun Sep 5 20:04:02 2010 (r212240) @@ -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;