Nick: carldani E-mail: c-d.hailfinger.devel.2006@gmx.net Board: VIA VL805 Contents: VIA VL805 driver Signed-off-by: Carl-Daniel Hailfinger diff -r 4b544f581ca3 -r ae63f00af9b7 Makefile --- a/Makefile Tue Dec 24 15:54:40 2019 +0100 +++ b/Makefile Wed Dec 25 00:21:10 2019 +0100 @@ -683,6 +683,9 @@ # Disable J-Link for now. CONFIG_JLINK_SPI ?= no +# Enable VIA VL805 programmer for now. +CONFIG_VL805 ?= yes + #PLACEHOLDER_NEWPROG_DEFAULTCONFIG # Disable wiki printing by default. It is only useful if you have wiki access. @@ -980,6 +983,12 @@ PROGRAMMER_OBJS += mstarddc_spi.o endif +ifeq ($(CONFIG_VL805), yes) +FEATURE_CFLAGS += -D'CONFIG_VL805=1' +PROGRAMMER_OBJS += vl805.o +NEED_PCI := yes +endif + #PLACEHOLDER_NEWPROG_COMPILERULE ifeq ($(CONFIG_CH341A_SPI), yes) diff -r 4b544f581ca3 -r ae63f00af9b7 flashrom.8.tmpl --- a/flashrom.8.tmpl Tue Dec 24 15:54:40 2019 +0100 +++ b/flashrom.8.tmpl Wed Dec 25 00:21:10 2019 +0100 @@ -343,6 +343,8 @@ .sp .BR "* ni845x_spi" " (for SPI flash ROMs attached to National Instruments USB-8451 or USB-8452)" .sp +.BR "* vl805" " (VIA VL805 programmer)" +.sp .\"PLACEHOLDER_NEWPROG_MAN_SHORTDESCRIPTION Some programmers have optional or mandatory parameters which are described in detail in the @@ -1261,6 +1263,9 @@ syntax where \fBfrequency\fP is the SPI clock frequency in kHz. The maximum speed depends on the device in use. .SS +.SS +.BR "vl805 " programmer +Please describe the programmer parameters here. .\"PLACEHOLDER_NEWPROG_MAN_LONGDESCRIPTION .SH EXAMPLES To back up and update your BIOS, run @@ -1339,6 +1344,9 @@ .B ogp needs PCI configuration space read access and raw memory access. .sp +.B vl805 +Please describe the programmer requirements here. +.sp .\"PLACEHOLDER_NEWPROG_MAN_REQUIREMENTS On OpenBSD, you can obtain raw access permission by setting .B "securelevel=-1" diff -r 4b544f581ca3 -r ae63f00af9b7 flashrom.c --- a/flashrom.c Tue Dec 24 15:54:40 2019 +0100 +++ b/flashrom.c Wed Dec 25 00:21:10 2019 +0100 @@ -461,6 +461,18 @@ }, #endif +#if CONFIG_VL805 == 1 + { + .name = "vl805", + .type = PCI, + .devs.dev = devs_vl805, + .init = vl805_init, + .map_flash_region = fallback_map, + .unmap_flash_region = fallback_unmap, + .delay = internal_delay, + }, +#endif + //PLACEHOLDER_NEWPROG_PROGRAMMER_ARRAY {0}, /* This entry corresponds to PROGRAMMER_INVALID. */ }; diff -r 4b544f581ca3 -r ae63f00af9b7 programmer.h --- a/programmer.h Tue Dec 24 15:54:40 2019 +0100 +++ b/programmer.h Wed Dec 25 00:21:10 2019 +0100 @@ -124,6 +124,9 @@ #if CONFIG_NI845X_SPI == 1 PROGRAMMER_NI845X_SPI, #endif +#if CONFIG_VL805 == 1 + PROGRAMMER_VL805, +#endif //PLACEHOLDER_NEWPROG_PROGRAMMER_ENUM PROGRAMMER_INVALID /* This must always be the last entry. */ }; @@ -565,6 +568,13 @@ int ni845x_spi_init(void); #endif +/* vl805.c */ +#if CONFIG_VL805 == 1 +int vl805_init(void); +extern const struct dev_entry devs_vl805[]; + +#endif + //PLACEHOLDER_NEWPROG_PUBLICFUNCTIONS /* flashrom.c */ diff -r 4b544f581ca3 -r ae63f00af9b7 vl805.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vl805.c Wed Dec 25 00:21:10 2019 +0100 @@ -0,0 +1,167 @@ +/* + * This file is part of the flashrom project. + * + * Copyright (C) 2019 Carl-Daniel Hailfinger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Driver for the VIA VL805 programmer hardware by VIA. + * See http://www.via.com/ for more info. + */ + +#include "flash.h" +#include "programmer.h" +#include "hwaccess.h" +#include "spi.h" + +const struct dev_entry devs_vl805[] = { + {0x1106, 0x3483, NT, "VIA", "VL805"}, + + {0}, +}; + +static struct pci_dev *dev = NULL; + +/* Include string.h for memset to get the template to compile . Remove this. */ +#include +static int vl805_spi_send_command(struct flashctx *flash, + unsigned int writecnt, unsigned int readcnt, + const unsigned char *writearr, + unsigned char *readarr) +{ + /* Send a SPI command to the flash chip. */ + /* Set readarr to 0xff to get the template to compile and run without segfaults. */ + memset(readarr, 0xff, readcnt); + + return 0; +} + +static const struct spi_master spi_master_vl805 = { + .max_data_read = 64 * 1024, /* Maximum data read size in one go (excluding opcode+address). */ + .max_data_write = 256, /* Maximum data write size in one go (excluding opcode+address). */ + .command = vl805_spi_send_command, + .multicommand = default_spi_send_multicommand, + .read = default_spi_read, + .write_256 = default_spi_write_256, +}; + +static void vl805_setregval(int reg, uint32_t val) +{ + pci_write_long(dev, 120, reg); + pci_write_long(dev, 124, val); +} + +static uint32_t vl805_getregval(int reg) +{ + pci_write_long(dev, 120, reg); + return pci_read_long(dev, 124); +} + +#define VL805_REG_0x30004 0x00030004 +#define VL805_REG_0x4000c 0x0004000c +#define VL805_REG_0x40020 0x00040020 +#define VL805_REG_SPI_OUTDATA 0x000400d0 +#define VL805_REG_SPI_INDATA 0x000400e0 +#define VL805_REG_SPI_TRANSACTION 0x000400f0 +#define VL805_REG_0x400f8 0x000400f8 +#define VL805_REG_SPI_CHIP_ENABLE_LEVEL 0x000400fc + +static int vl805_jedec_rems(void) +{ + /* Run JEDEC_REMS. TODO: Make this a generic SPI command function. */ + uint32_t val; + uint32_t outdata = JEDEC_REMS << 24 | (0); + + vl805_setregval(VL805_REG_SPI_CHIP_ENABLE_LEVEL, 0x00000000); + vl805_setregval(VL805_REG_SPI_OUTDATA, outdata); + vl805_setregval(VL805_REG_SPI_TRANSACTION, 0x00000580 | 0x40); + val = vl805_getregval(VL805_REG_SPI_INDATA); + msg_pdbg("REMS response is 0x%08x\n", val); + if (val != 0xef10ef10) + return 1; + vl805_setregval(VL805_REG_SPI_CHIP_ENABLE_LEVEL, 0x00000001); + return 0; +} + +static void vl805_programmer_active(uint8_t val) +{ + pci_write_byte(dev, 67, val); +} + +static int vl805_shutdown(void *data) +{ + /* Shutdown stuff. */ + return 0; +} + +int vl805_init(void) +{ + /* Init stuff (i.e. parameter parsing) here which does not need to be + * undone. + */ + if (rget_io_perms()) + return 1; + + dev = pcidev_init(ata_via, PCI_ROM_ADDRESS); /* FIXME typo Acutally no BAR setup needed at all. */ + if (!dev) + return 1; + + vl805_programmer_active(0x1); + uint32_t val = pci_read_long(dev, 80); + msg_pdbg("VL805 firmware version 0x%08x\n", val); + vl805_programmer_active(0x0); + + /* Some sort of init sequence, just copied from the logs. */ + vl805_programmer_active(0x1); + vl805_setregval(VL805_REG_SPI_CHIP_ENABLE_LEVEL, 0x00000001); + val = vl805_getregval(VL805_REG_0x30004); + if (val != 0x00000200) { + msg_perr("VL805_REG_0x30004 returned unexpected value 0x%08x\n", val); + return 1; + } + vl805_setregval(VL805_REG_0x30004, 0x00000200); + val = vl805_getregval(VL805_REG_0x40020); + if (val != 0xffffffff) { + msg_perr("VL805_REG_0x40020 returned unexpected value 0x%08x\n", val); + return 1; + } + vl805_setregval(VL805_REG_0x40020, 0xffffff01); + val = vl805_getregval(VL805_REG_0x4000c); + if (val != 0x00000001) { + msg_perr("VL805_REG_0x4000c returned unexpected value 0x%08x\n", val); + return 1; + } + vl805_setregval(VL805_REG_0x4000c, 0x00000001); + vl805_setregval(VL805_REG_SPI_TRANSACTION, 0x000005a0); + vl805_setregval(VL805_REG_0x400f8, 0x0000000a); + + /* Run JEDEC_REMS */ + if (vl805_jedec_rems()) + return 1; + + /* Some sort of cleanup sequence, just copied from the logs. */ + vl805_setregval(VL805_REG_SPI_TRANSACTION, 0x00000000); + vl805_programmer_active(0x0); + + /* If your shutdown function takes a parameter, replace NULL with it. */ + register_shutdown(vl805_shutdown, NULL); + + /* Init stuff which needs to be undone on shutdown. */ + + register_spi_master(&spi_master_vl805); + + /* Return an error for now. */ + return 1; +}