Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * this file included by nicstar.c
0004  */
0005 
0006 /*
0007  * nicstarmac.c
0008  * Read this ForeRunner's MAC address from eprom/eeprom
0009  */
0010 
0011 #include <linux/kernel.h>
0012 
0013 typedef void __iomem *virt_addr_t;
0014 
0015 #define CYCLE_DELAY 5
0016 
0017 #define osp_MicroDelay(microsec) {unsigned long useconds = (microsec); \
0018                                   udelay((useconds));}
0019 /*
0020  * The following tables represent the timing diagrams found in
0021  * the Data Sheet for the Xicor X25020 EEProm.  The #defines below
0022  * represent the bits in the NICStAR's General Purpose register
0023  * that must be toggled for the corresponding actions on the EEProm
0024  * to occur.
0025  */
0026 
0027 /* Write Data To EEProm from SI line on rising edge of CLK */
0028 /* Read Data From EEProm on falling edge of CLK */
0029 
0030 #define CS_HIGH     0x0002  /* Chip select high */
0031 #define CS_LOW      0x0000  /* Chip select low (active low) */
0032 #define CLK_HIGH    0x0004  /* Clock high */
0033 #define CLK_LOW     0x0000  /* Clock low  */
0034 #define SI_HIGH     0x0001  /* Serial input data high */
0035 #define SI_LOW      0x0000  /* Serial input data low */
0036 
0037 /* Read Status Register = 0000 0101b */
0038 #if 0
0039 static u_int32_t rdsrtab[] = {
0040     CS_HIGH | CLK_HIGH,
0041     CS_LOW | CLK_LOW,
0042     CLK_HIGH,       /* 0 */
0043     CLK_LOW,
0044     CLK_HIGH,       /* 0 */
0045     CLK_LOW,
0046     CLK_HIGH,       /* 0 */
0047     CLK_LOW,
0048     CLK_HIGH,       /* 0 */
0049     CLK_LOW,
0050     CLK_HIGH,       /* 0 */
0051     CLK_LOW | SI_HIGH,
0052     CLK_HIGH | SI_HIGH, /* 1 */
0053     CLK_LOW | SI_LOW,
0054     CLK_HIGH,       /* 0 */
0055     CLK_LOW | SI_HIGH,
0056     CLK_HIGH | SI_HIGH  /* 1 */
0057 };
0058 #endif /*  0  */
0059 
0060 /* Read from EEPROM = 0000 0011b */
0061 static u_int32_t readtab[] = {
0062     /*
0063        CS_HIGH | CLK_HIGH,
0064      */
0065     CS_LOW | CLK_LOW,
0066     CLK_HIGH,       /* 0 */
0067     CLK_LOW,
0068     CLK_HIGH,       /* 0 */
0069     CLK_LOW,
0070     CLK_HIGH,       /* 0 */
0071     CLK_LOW,
0072     CLK_HIGH,       /* 0 */
0073     CLK_LOW,
0074     CLK_HIGH,       /* 0 */
0075     CLK_LOW,
0076     CLK_HIGH,       /* 0 */
0077     CLK_LOW | SI_HIGH,
0078     CLK_HIGH | SI_HIGH, /* 1 */
0079     CLK_LOW | SI_HIGH,
0080     CLK_HIGH | SI_HIGH  /* 1 */
0081 };
0082 
0083 /* Clock to read from/write to the eeprom */
0084 static u_int32_t clocktab[] = {
0085     CLK_LOW,
0086     CLK_HIGH,
0087     CLK_LOW,
0088     CLK_HIGH,
0089     CLK_LOW,
0090     CLK_HIGH,
0091     CLK_LOW,
0092     CLK_HIGH,
0093     CLK_LOW,
0094     CLK_HIGH,
0095     CLK_LOW,
0096     CLK_HIGH,
0097     CLK_LOW,
0098     CLK_HIGH,
0099     CLK_LOW,
0100     CLK_HIGH,
0101     CLK_LOW
0102 };
0103 
0104 #define NICSTAR_REG_WRITE(bs, reg, val) \
0105     while ( readl(bs + STAT) & 0x0200 ) ; \
0106     writel((val),(base)+(reg))
0107 #define NICSTAR_REG_READ(bs, reg) \
0108     readl((base)+(reg))
0109 #define NICSTAR_REG_GENERAL_PURPOSE GP
0110 
0111 /*
0112  * This routine will clock the Read_Status_reg function into the X2520
0113  * eeprom, then pull the result from bit 16 of the NicSTaR's General Purpose 
0114  * register.  
0115  */
0116 #if 0
0117 u_int32_t nicstar_read_eprom_status(virt_addr_t base)
0118 {
0119     u_int32_t val;
0120     u_int32_t rbyte;
0121     int32_t i, j;
0122 
0123     /* Send read instruction */
0124     val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
0125 
0126     for (i = 0; i < ARRAY_SIZE(rdsrtab); i++) {
0127         NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
0128                   (val | rdsrtab[i]));
0129         osp_MicroDelay(CYCLE_DELAY);
0130     }
0131 
0132     /* Done sending instruction - now pull data off of bit 16, MSB first */
0133     /* Data clocked out of eeprom on falling edge of clock */
0134 
0135     rbyte = 0;
0136     for (i = 7, j = 0; i >= 0; i--) {
0137         NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
0138                   (val | clocktab[j++]));
0139         rbyte |= (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
0140                 & 0x00010000) >> 16) << i);
0141         NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
0142                   (val | clocktab[j++]));
0143         osp_MicroDelay(CYCLE_DELAY);
0144     }
0145     NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
0146     osp_MicroDelay(CYCLE_DELAY);
0147     return rbyte;
0148 }
0149 #endif /*  0  */
0150 
0151 /*
0152  * This routine will clock the Read_data function into the X2520
0153  * eeprom, followed by the address to read from, through the NicSTaR's General
0154  * Purpose register.  
0155  */
0156 
0157 static u_int8_t read_eprom_byte(virt_addr_t base, u_int8_t offset)
0158 {
0159     u_int32_t val = 0;
0160     int i, j = 0;
0161     u_int8_t tempread = 0;
0162 
0163     val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
0164 
0165     /* Send READ instruction */
0166     for (i = 0; i < ARRAY_SIZE(readtab); i++) {
0167         NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
0168                   (val | readtab[i]));
0169         osp_MicroDelay(CYCLE_DELAY);
0170     }
0171 
0172     /* Next, we need to send the byte address to read from */
0173     for (i = 7; i >= 0; i--) {
0174         NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
0175                   (val | clocktab[j++] | ((offset >> i) & 1)));
0176         osp_MicroDelay(CYCLE_DELAY);
0177         NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
0178                   (val | clocktab[j++] | ((offset >> i) & 1)));
0179         osp_MicroDelay(CYCLE_DELAY);
0180     }
0181 
0182     j = 0;
0183 
0184     /* Now, we can read data from the eeprom by clocking it in */
0185     for (i = 7; i >= 0; i--) {
0186         NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
0187                   (val | clocktab[j++]));
0188         osp_MicroDelay(CYCLE_DELAY);
0189         tempread |=
0190             (((NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE)
0191                & 0x00010000) >> 16) << i);
0192         NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
0193                   (val | clocktab[j++]));
0194         osp_MicroDelay(CYCLE_DELAY);
0195     }
0196 
0197     NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE, 2);
0198     osp_MicroDelay(CYCLE_DELAY);
0199     return tempread;
0200 }
0201 
0202 static void nicstar_init_eprom(virt_addr_t base)
0203 {
0204     u_int32_t val;
0205 
0206     /*
0207      * turn chip select off
0208      */
0209     val = NICSTAR_REG_READ(base, NICSTAR_REG_GENERAL_PURPOSE) & 0xFFFFFFF0;
0210 
0211     NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
0212               (val | CS_HIGH | CLK_HIGH));
0213     osp_MicroDelay(CYCLE_DELAY);
0214 
0215     NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
0216               (val | CS_HIGH | CLK_LOW));
0217     osp_MicroDelay(CYCLE_DELAY);
0218 
0219     NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
0220               (val | CS_HIGH | CLK_HIGH));
0221     osp_MicroDelay(CYCLE_DELAY);
0222 
0223     NICSTAR_REG_WRITE(base, NICSTAR_REG_GENERAL_PURPOSE,
0224               (val | CS_HIGH | CLK_LOW));
0225     osp_MicroDelay(CYCLE_DELAY);
0226 }
0227 
0228 /*
0229  * This routine will be the interface to the ReadPromByte function
0230  * above.
0231  */
0232 
0233 static void
0234 nicstar_read_eprom(virt_addr_t base,
0235            u_int8_t prom_offset, u_int8_t * buffer, u_int32_t nbytes)
0236 {
0237     u_int i;
0238 
0239     for (i = 0; i < nbytes; i++) {
0240         buffer[i] = read_eprom_byte(base, prom_offset);
0241         ++prom_offset;
0242         osp_MicroDelay(CYCLE_DELAY);
0243     }
0244 }