diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2008-03-30 14:17:49 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2008-03-30 14:17:49 +0000 |
commit | 41c4d8fced2068df2998cf9b2c0b1565c3eccaca (patch) | |
tree | 0a3a8c34c4f7b3ab60e002b79748da2635f29d7b /sys/dev/pci | |
parent | 30d0264c3a34ccdad67f4dfd08b6e75171ec0da4 (diff) |
Add code to configure the vendor specific opcodes of the SPI Flash.
From NetBSD.
ok dlg@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/if_lii.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/sys/dev/pci/if_lii.c b/sys/dev/pci/if_lii.c index 383e1a5864a..9b4ae4fe046 100644 --- a/sys/dev/pci/if_lii.c +++ b/sys/dev/pci/if_lii.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_lii.c,v 1.8 2008/03/30 14:09:56 jsing Exp $ */ +/* $OpenBSD: if_lii.c,v 1.9 2008/03/30 14:17:48 jsing Exp $ */ /* * Copyright (c) 2007 The NetBSD Foundation. @@ -141,6 +141,7 @@ int atl2_reset(struct atl2_softc *); int atl2_eeprom_present(struct atl2_softc *); int atl2_read_macaddr(struct atl2_softc *, uint8_t *); int atl2_eeprom_read(struct atl2_softc *, uint32_t, uint32_t *); +void atl2_spi_configure(struct atl2_softc *); int atl2_spi_read(struct atl2_softc *, uint32_t, uint32_t *); void atl2_setmulti(struct atl2_softc *); void atl2_tick(void *); @@ -231,7 +232,7 @@ atl2_attach(struct device *parent, struct device *self, void *aux) if (atl2_reset(sc)) return; - /* XXX set correct opcodes for the flash */ + atl2_spi_configure(sc); if (atl2_eeprom_present(sc)) sc->sc_memread = atl2_eeprom_read; @@ -340,6 +341,56 @@ atl2_eeprom_read(struct atl2_softc *sc, uint32_t reg, uint32_t *val) return pci_vpd_read(sc->sc_pc, sc->sc_tag, reg, 1, (pcireg_t *)val); } +void +atl2_spi_configure(struct atl2_softc *sc) +{ + /* + * We don't offer a way to configure the SPI Flash vendor parameter, so + * the table is given for reference + */ + static const struct lii_spi_flash_vendor { + const char *sfv_name; + const uint8_t sfv_opcodes[9]; + } lii_sfv[] = { + { "Atmel", { 0x00, 0x03, 0x02, 0x06, 0x04, 0x05, 0x15, 0x52, 0x62 } }, + { "SST", { 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0x90, 0x20, 0x60 } }, + { "ST", { 0x01, 0x03, 0x02, 0x06, 0x04, 0x05, 0xab, 0xd8, 0xc7 } }, + }; +#define SF_OPCODE_WRSR 0 +#define SF_OPCODE_READ 1 +#define SF_OPCODE_PRGM 2 +#define SF_OPCODE_WREN 3 +#define SF_OPCODE_WRDI 4 +#define SF_OPCODE_RDSR 5 +#define SF_OPCODE_RDID 6 +#define SF_OPCODE_SECT_ER 7 +#define SF_OPCODE_CHIP_ER 8 + +#define SF_DEFAULT_VENDOR 0 + static const uint8_t vendor = SF_DEFAULT_VENDOR; + + /* + * Why isn't WRDI used? Heck if I know. + */ + + AT_WRITE_1(sc, ATL2_SFOP_WRSR, + lii_sfv[vendor].sfv_opcodes[SF_OPCODE_WRSR]); + AT_WRITE_1(sc, ATL2_SFOP_READ, + lii_sfv[vendor].sfv_opcodes[SF_OPCODE_READ]); + AT_WRITE_1(sc, ATL2_SFOP_PROGRAM, + lii_sfv[vendor].sfv_opcodes[SF_OPCODE_PRGM]); + AT_WRITE_1(sc, ATL2_SFOP_WREN, + lii_sfv[vendor].sfv_opcodes[SF_OPCODE_WREN]); + AT_WRITE_1(sc, ATL2_SFOP_RDSR, + lii_sfv[vendor].sfv_opcodes[SF_OPCODE_RDSR]); + AT_WRITE_1(sc, ATL2_SFOP_RDID, + lii_sfv[vendor].sfv_opcodes[SF_OPCODE_RDID]); + AT_WRITE_1(sc, ATL2_SFOP_SC_ERASE, + lii_sfv[vendor].sfv_opcodes[SF_OPCODE_SECT_ER]); + AT_WRITE_1(sc, ATL2_SFOP_CHIP_ERASE, + lii_sfv[vendor].sfv_opcodes[SF_OPCODE_CHIP_ER]); +} + #define MAKE_SFC(cssetup, clkhi, clklo, cshold, cshi, ins) \ ( (((cssetup) & SFC_CS_SETUP_MASK) \ << SFC_CS_SETUP_SHIFT) \ |