1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * this file included by nicstar.c
41da177e4SLinus Torvalds */
51da177e4SLinus Torvalds
61da177e4SLinus Torvalds /*
71da177e4SLinus Torvalds * nicstarmac.c
81da177e4SLinus Torvalds * Read this ForeRunner's MAC address from eprom/eeprom
91da177e4SLinus Torvalds */
101da177e4SLinus Torvalds
1136fe55d6SAhmed S. Darwish #include <linux/kernel.h>
1236fe55d6SAhmed S. Darwish
131da177e4SLinus Torvalds typedef void __iomem *virt_addr_t;
141da177e4SLinus Torvalds
151da177e4SLinus Torvalds #define CYCLE_DELAY 5
161da177e4SLinus Torvalds
171da177e4SLinus Torvalds #define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \
181da177e4SLinus Torvalds udelay((useconds));}
19098fde11Schas williams - CONTRACTOR /*
20098fde11Schas williams - CONTRACTOR * The following tables represent the timing diagrams found in
211da177e4SLinus Torvalds * the Data Sheet for the Xicor X25020 EEProm. The #defines below
221da177e4SLinus Torvalds * represent the bits in the NICStAR's General Purpose register
231da177e4SLinus Torvalds * that must be toggled for the corresponding actions on the EEProm
241da177e4SLinus Torvalds * to occur.
251da177e4SLinus Torvalds */
261da177e4SLinus Torvalds
271da177e4SLinus Torvalds /* Write Data To EEProm from SI line on rising edge of CLK */
281da177e4SLinus Torvalds /* Read Data From EEProm on falling edge of CLK */
291da177e4SLinus Torvalds
301da177e4SLinus Torvalds #define CS_HIGH 0x0002 /* Chip select high */
311da177e4SLinus Torvalds #define CS_LOW 0x0000 /* Chip select low (active low) */
321da177e4SLinus Torvalds #define CLK_HIGH 0x0004 /* Clock high */
331da177e4SLinus Torvalds #define CLK_LOW 0x0000 /* Clock low */
341da177e4SLinus Torvalds #define SI_HIGH 0x0001 /* Serial input data high */
351da177e4SLinus Torvalds #define SI_LOW 0x0000 /* Serial input data low */
361da177e4SLinus Torvalds
371da177e4SLinus Torvalds /* Read Status Register = 0000 0101b */
381da177e4SLinus Torvalds #if 0
39098fde11Schas williams - CONTRACTOR static u_int32_t rdsrtab[] = {
401da177e4SLinus Torvalds CS_HIGH | CLK_HIGH,
411da177e4SLinus Torvalds CS_LOW | CLK_LOW,
421da177e4SLinus Torvalds CLK_HIGH, /* 0 */
431da177e4SLinus Torvalds CLK_LOW,
441da177e4SLinus Torvalds CLK_HIGH, /* 0 */
451da177e4SLinus Torvalds CLK_LOW,
461da177e4SLinus Torvalds CLK_HIGH, /* 0 */
471da177e4SLinus Torvalds CLK_LOW,
481da177e4SLinus Torvalds CLK_HIGH, /* 0 */
491da177e4SLinus Torvalds CLK_LOW,
501da177e4SLinus Torvalds CLK_HIGH, /* 0 */
511da177e4SLinus Torvalds CLK_LOW | SI_HIGH,
521da177e4SLinus Torvalds CLK_HIGH | SI_HIGH, /* 1 */
531da177e4SLinus Torvalds CLK_LOW | SI_LOW,
541da177e4SLinus Torvalds CLK_HIGH, /* 0 */
551da177e4SLinus Torvalds CLK_LOW | SI_HIGH,
561da177e4SLinus Torvalds CLK_HIGH | SI_HIGH /* 1 */
571da177e4SLinus Torvalds };
581da177e4SLinus Torvalds #endif /* 0 */
591da177e4SLinus Torvalds
601da177e4SLinus Torvalds /* Read from EEPROM = 0000 0011b */
61098fde11Schas williams - CONTRACTOR static u_int32_t readtab[] = {
621da177e4SLinus Torvalds /*
631da177e4SLinus Torvalds CS_HIGH | CLK_HIGH,
641da177e4SLinus Torvalds */
651da177e4SLinus Torvalds CS_LOW | CLK_LOW,
661da177e4SLinus Torvalds CLK_HIGH, /* 0 */
671da177e4SLinus Torvalds CLK_LOW,
681da177e4SLinus Torvalds CLK_HIGH, /* 0 */
691da177e4SLinus Torvalds CLK_LOW,
701da177e4SLinus Torvalds CLK_HIGH, /* 0 */
711da177e4SLinus Torvalds CLK_LOW,
721da177e4SLinus Torvalds CLK_HIGH, /* 0 */
731da177e4SLinus Torvalds CLK_LOW,
741da177e4SLinus Torvalds CLK_HIGH, /* 0 */
751da177e4SLinus Torvalds CLK_LOW,
761da177e4SLinus Torvalds CLK_HIGH, /* 0 */
771da177e4SLinus Torvalds CLK_LOW | SI_HIGH,
781da177e4SLinus Torvalds CLK_HIGH | SI_HIGH, /* 1 */
791da177e4SLinus Torvalds CLK_LOW | SI_HIGH,
801da177e4SLinus Torvalds CLK_HIGH | SI_HIGH /* 1 */
811da177e4SLinus Torvalds };
821da177e4SLinus Torvalds
831da177e4SLinus Torvalds /* Clock to read from/write to the eeprom */
84098fde11Schas williams - CONTRACTOR static u_int32_t clocktab[] = {
851da177e4SLinus Torvalds CLK_LOW,
861da177e4SLinus Torvalds CLK_HIGH,
871da177e4SLinus Torvalds CLK_LOW,
881da177e4SLinus Torvalds CLK_HIGH,
891da177e4SLinus Torvalds CLK_LOW,
901da177e4SLinus Torvalds CLK_HIGH,
911da177e4SLinus Torvalds CLK_LOW,
921da177e4SLinus Torvalds CLK_HIGH,
931da177e4SLinus Torvalds CLK_LOW,
941da177e4SLinus Torvalds CLK_HIGH,
951da177e4SLinus Torvalds CLK_LOW,
961da177e4SLinus Torvalds CLK_HIGH,
971da177e4SLinus Torvalds CLK_LOW,
981da177e4SLinus Torvalds CLK_HIGH,
991da177e4SLinus Torvalds CLK_LOW,
1001da177e4SLinus Torvalds CLK_HIGH,
1011da177e4SLinus Torvalds CLK_LOW
1021da177e4SLinus Torvalds };
1031da177e4SLinus Torvalds
1041da177e4SLinus Torvalds #define NICSTAR_REG_WRITE(bs, reg, val) \
1051da177e4SLinus Torvalds while ( readl(bs + STAT) & 0x0200 ) ; \
1061da177e4SLinus Torvalds writel((val),(base)+(reg))
1071da177e4SLinus Torvalds #define NICSTAR_REG_READ(bs, reg) \
1081da177e4SLinus Torvalds readl((base)+(reg))
1091da177e4SLinus Torvalds #define NICSTAR_REG_GENERAL_PURPOSE GP
1101da177e4SLinus Torvalds
1111da177e4SLinus Torvalds /*
1121da177e4SLinus Torvalds * This routine will clock the Read_Status_reg function into the X2520
1131da177e4SLinus Torvalds * eeprom, then pull the result from bit 16 of the NicSTaR's General Purpose
1141da177e4SLinus Torvalds * register.
1151da177e4SLinus Torvalds */
1161da177e4SLinus Torvalds #if 0
117098fde11Schas williams - CONTRACTOR u_int32_t nicstar_read_eprom_status(virt_addr_t base)
1181da177e4SLinus Torvalds {
1191da177e4SLinus Torvalds u_int32_t val;
1201da177e4SLinus Torvalds u_int32_t rbyte;
1211da177e4SLinus Torvalds int32_t i, j;
1221da177e4SLinus Torvalds
1231da177e4SLinus Torvalds /* Send read instruction */
1241da177e4SLinus Torvalds val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
1251da177e4SLinus Torvalds
126098fde11Schas williams - CONTRACTOR for (i = 0; i < ARRAY_SIZE(rdsrtab); i++) {
1271da177e4SLinus Torvalds NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
1281da177e4SLinus Torvalds (val | rdsrtab[i]));
1291da177e4SLinus Torvalds osp_MicroDelay(CYCLE_DELAY);
1301da177e4SLinus Torvalds }
1311da177e4SLinus Torvalds
1321da177e4SLinus Torvalds /* Done sending instruction - now pull data off of bit 16, MSB first */
1331da177e4SLinus Torvalds /* Data clocked out of eeprom on falling edge of clock */
1341da177e4SLinus Torvalds
1351da177e4SLinus Torvalds rbyte = 0;
136098fde11Schas williams - CONTRACTOR for (i = 7, j = 0; i >= 0; i--) {
1371da177e4SLinus Torvalds NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
1381da177e4SLinus Torvalds (val | clocktab[j++]));
1391da177e4SLinus Torvalds rbyte |= (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
1401da177e4SLinus Torvalds & 0x00010000) >> 16) << i);
1411da177e4SLinus Torvalds NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
1421da177e4SLinus Torvalds (val | clocktab[j++]));
1431da177e4SLinus Torvalds osp_MicroDelay(CYCLE_DELAY);
1441da177e4SLinus Torvalds }
1451da177e4SLinus Torvalds NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
1461da177e4SLinus Torvalds osp_MicroDelay(CYCLE_DELAY);
1471da177e4SLinus Torvalds return rbyte;
1481da177e4SLinus Torvalds }
1491da177e4SLinus Torvalds #endif /* 0 */
1501da177e4SLinus Torvalds
1511da177e4SLinus Torvalds /*
1521da177e4SLinus Torvalds * This routine will clock the Read_data function into the X2520
1531da177e4SLinus Torvalds * eeprom, followed by the address to read from, through the NicSTaR's General
1541da177e4SLinus Torvalds * Purpose register.
1551da177e4SLinus Torvalds */
1561da177e4SLinus Torvalds
read_eprom_byte(virt_addr_t base,u_int8_t offset)157098fde11Schas williams - CONTRACTOR static u_int8_t read_eprom_byte(virt_addr_t base, u_int8_t offset)
1581da177e4SLinus Torvalds {
1591da177e4SLinus Torvalds u_int32_t val = 0;
1601da177e4SLinus Torvalds int i, j = 0;
1611da177e4SLinus Torvalds u_int8_t tempread = 0;
1621da177e4SLinus Torvalds
1631da177e4SLinus Torvalds val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
1641da177e4SLinus Torvalds
1651da177e4SLinus Torvalds /* Send READ instruction */
166098fde11Schas williams - CONTRACTOR for (i = 0; i < ARRAY_SIZE(readtab); i++) {
1671da177e4SLinus Torvalds NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
1681da177e4SLinus Torvalds (val | readtab[i]));
1691da177e4SLinus Torvalds osp_MicroDelay(CYCLE_DELAY);
1701da177e4SLinus Torvalds }
1711da177e4SLinus Torvalds
1721da177e4SLinus Torvalds /* Next, we need to send the byte address to read from */
173098fde11Schas williams - CONTRACTOR for (i = 7; i >= 0; i--) {
1741da177e4SLinus Torvalds NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
1751da177e4SLinus Torvalds (val | clocktab[j++] | ((offset >> i) & 1)));
1761da177e4SLinus Torvalds osp_MicroDelay(CYCLE_DELAY);
1771da177e4SLinus Torvalds NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
1781da177e4SLinus Torvalds (val | clocktab[j++] | ((offset >> i) & 1)));
1791da177e4SLinus Torvalds osp_MicroDelay(CYCLE_DELAY);
1801da177e4SLinus Torvalds }
1811da177e4SLinus Torvalds
1821da177e4SLinus Torvalds j = 0;
1831da177e4SLinus Torvalds
1841da177e4SLinus Torvalds /* Now, we can read data from the eeprom by clocking it in */
185098fde11Schas williams - CONTRACTOR for (i = 7; i >= 0; i--) {
1861da177e4SLinus Torvalds NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
1871da177e4SLinus Torvalds (val | clocktab[j++]));
1881da177e4SLinus Torvalds osp_MicroDelay(CYCLE_DELAY);
189098fde11Schas williams - CONTRACTOR tempread |=
190098fde11Schas williams - CONTRACTOR (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
1911da177e4SLinus Torvalds & 0x00010000) >> 16) << i);
1921da177e4SLinus Torvalds NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
1931da177e4SLinus Torvalds (val | clocktab[j++]));
1941da177e4SLinus Torvalds osp_MicroDelay(CYCLE_DELAY);
1951da177e4SLinus Torvalds }
1961da177e4SLinus Torvalds
1971da177e4SLinus Torvalds NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
1981da177e4SLinus Torvalds osp_MicroDelay(CYCLE_DELAY);
1991da177e4SLinus Torvalds return tempread;
2001da177e4SLinus Torvalds }
2011da177e4SLinus Torvalds
nicstar_init_eprom(virt_addr_t base)202098fde11Schas williams - CONTRACTOR static void nicstar_init_eprom(virt_addr_t base)
2031da177e4SLinus Torvalds {
2041da177e4SLinus Torvalds u_int32_t val;
2051da177e4SLinus Torvalds
2061da177e4SLinus Torvalds /*
2071da177e4SLinus Torvalds * turn chip select off
2081da177e4SLinus Torvalds */
2091da177e4SLinus Torvalds val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
2101da177e4SLinus Torvalds
2111da177e4SLinus Torvalds NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
2121da177e4SLinus Torvalds (val | CS_HIGH | CLK_HIGH));
2131da177e4SLinus Torvalds osp_MicroDelay(CYCLE_DELAY);
2141da177e4SLinus Torvalds
2151da177e4SLinus Torvalds NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
2161da177e4SLinus Torvalds (val | CS_HIGH | CLK_LOW));
2171da177e4SLinus Torvalds osp_MicroDelay(CYCLE_DELAY);
2181da177e4SLinus Torvalds
2191da177e4SLinus Torvalds NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
2201da177e4SLinus Torvalds (val | CS_HIGH | CLK_HIGH));
2211da177e4SLinus Torvalds osp_MicroDelay(CYCLE_DELAY);
2221da177e4SLinus Torvalds
2231da177e4SLinus Torvalds NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
2241da177e4SLinus Torvalds (val | CS_HIGH | CLK_LOW));
2251da177e4SLinus Torvalds osp_MicroDelay(CYCLE_DELAY);
2261da177e4SLinus Torvalds }
2271da177e4SLinus Torvalds
2281da177e4SLinus Torvalds /*
2291da177e4SLinus Torvalds * This routine will be the interface to the ReadPromByte function
2301da177e4SLinus Torvalds * above.
2311da177e4SLinus Torvalds */
2321da177e4SLinus Torvalds
2331da177e4SLinus Torvalds static void
nicstar_read_eprom(virt_addr_t base,u_int8_t prom_offset,u_int8_t * buffer,u_int32_t nbytes)234098fde11Schas williams - CONTRACTOR nicstar_read_eprom(virt_addr_t base,
235098fde11Schas williams - CONTRACTOR u_int8_t prom_offset, u_int8_t * buffer, u_int32_t nbytes)
2361da177e4SLinus Torvalds {
2371da177e4SLinus Torvalds u_int i;
2381da177e4SLinus Torvalds
239098fde11Schas williams - CONTRACTOR for (i = 0; i < nbytes; i++) {
2401da177e4SLinus Torvalds buffer[i] = read_eprom_byte(base, prom_offset);
2411da177e4SLinus Torvalds ++prom_offset;
2421da177e4SLinus Torvalds osp_MicroDelay(CYCLE_DELAY);
2431da177e4SLinus Torvalds }
2441da177e4SLinus Torvalds }
245