uboot/board/renesas/sh7785lcr/rtl8169_mac.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2008 Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <common.h>
   8#include "rtl8169.h"
   9
  10static unsigned char *PCI_MEMR;
  11
  12static void mac_delay(unsigned int cnt)
  13{
  14        udelay(cnt);
  15}
  16
  17static void mac_pci_setup(void)
  18{
  19        unsigned long pci_data;
  20
  21        PCI_PAR = 0x00000010;
  22        PCI_PDR = 0x00001000;
  23        PCI_PAR = 0x00000004;
  24        pci_data = PCI_PDR;
  25        PCI_PDR = pci_data | 0x00000007;
  26        PCI_PAR = 0x00000010;
  27
  28        PCI_MEMR = (unsigned char *)((PCI_PDR | 0xFE240050) & 0xFFFFFFF0);
  29}
  30
  31static void EECS(int level)
  32{
  33        unsigned char data = *PCI_MEMR;
  34
  35        if (level)
  36                *PCI_MEMR = data | 0x08;
  37        else
  38                *PCI_MEMR = data & 0xf7;
  39}
  40
  41static void EECLK(int level)
  42{
  43        unsigned char data = *PCI_MEMR;
  44
  45        if (level)
  46                *PCI_MEMR = data | 0x04;
  47        else
  48                *PCI_MEMR = data & 0xfb;
  49}
  50
  51static void EEDI(int level)
  52{
  53        unsigned char data = *PCI_MEMR;
  54
  55        if (level)
  56                *PCI_MEMR = data | 0x02;
  57        else
  58                *PCI_MEMR = data & 0xfd;
  59}
  60
  61static inline void sh7785lcr_bitset(unsigned short bit)
  62{
  63        if (bit)
  64                EEDI(HIGH);
  65        else
  66                EEDI(LOW);
  67
  68        EECLK(LOW);
  69        mac_delay(TIME1);
  70        EECLK(HIGH);
  71        mac_delay(TIME1);
  72        EEDI(LOW);
  73}
  74
  75static inline unsigned char sh7785lcr_bitget(void)
  76{
  77        unsigned char bit;
  78
  79        EECLK(LOW);
  80        mac_delay(TIME1);
  81        bit = *PCI_MEMR & 0x01;
  82        EECLK(HIGH);
  83        mac_delay(TIME1);
  84
  85        return bit;
  86}
  87
  88static inline void sh7785lcr_setcmd(unsigned char command)
  89{
  90        sh7785lcr_bitset(BIT_DUMMY);
  91        switch (command) {
  92        case MAC_EEP_READ:
  93                sh7785lcr_bitset(1);
  94                sh7785lcr_bitset(1);
  95                sh7785lcr_bitset(0);
  96                break;
  97        case MAC_EEP_WRITE:
  98                sh7785lcr_bitset(1);
  99                sh7785lcr_bitset(0);
 100                sh7785lcr_bitset(1);
 101                break;
 102        case MAC_EEP_ERACE:
 103                sh7785lcr_bitset(1);
 104                sh7785lcr_bitset(1);
 105                sh7785lcr_bitset(1);
 106                break;
 107        case MAC_EEP_EWEN:
 108                sh7785lcr_bitset(1);
 109                sh7785lcr_bitset(0);
 110                sh7785lcr_bitset(0);
 111                break;
 112        case MAC_EEP_EWDS:
 113                sh7785lcr_bitset(1);
 114                sh7785lcr_bitset(0);
 115                sh7785lcr_bitset(0);
 116                break;
 117        default:
 118                break;
 119        }
 120}
 121
 122static inline unsigned short sh7785lcr_getdt(void)
 123{
 124        unsigned short data = 0;
 125        int i;
 126
 127        sh7785lcr_bitget();                     /* DUMMY */
 128        for (i = 0 ; i < 16 ; i++) {
 129                data <<= 1;
 130                data |= sh7785lcr_bitget();
 131        }
 132        return data;
 133}
 134
 135static inline void sh7785lcr_setadd(unsigned short address)
 136{
 137        sh7785lcr_bitset(address & 0x0020);     /* A5 */
 138        sh7785lcr_bitset(address & 0x0010);     /* A4 */
 139        sh7785lcr_bitset(address & 0x0008);     /* A3 */
 140        sh7785lcr_bitset(address & 0x0004);     /* A2 */
 141        sh7785lcr_bitset(address & 0x0002);     /* A1 */
 142        sh7785lcr_bitset(address & 0x0001);     /* A0 */
 143}
 144
 145static inline void sh7785lcr_setdata(unsigned short data)
 146{
 147        sh7785lcr_bitset(data & 0x8000);
 148        sh7785lcr_bitset(data & 0x4000);
 149        sh7785lcr_bitset(data & 0x2000);
 150        sh7785lcr_bitset(data & 0x1000);
 151        sh7785lcr_bitset(data & 0x0800);
 152        sh7785lcr_bitset(data & 0x0400);
 153        sh7785lcr_bitset(data & 0x0200);
 154        sh7785lcr_bitset(data & 0x0100);
 155        sh7785lcr_bitset(data & 0x0080);
 156        sh7785lcr_bitset(data & 0x0040);
 157        sh7785lcr_bitset(data & 0x0020);
 158        sh7785lcr_bitset(data & 0x0010);
 159        sh7785lcr_bitset(data & 0x0008);
 160        sh7785lcr_bitset(data & 0x0004);
 161        sh7785lcr_bitset(data & 0x0002);
 162        sh7785lcr_bitset(data & 0x0001);
 163}
 164
 165static void sh7785lcr_datawrite(const unsigned short *data, unsigned short address,
 166                         unsigned int count)
 167{
 168        unsigned int i;
 169
 170        for (i = 0; i < count; i++) {
 171                EECS(HIGH);
 172                EEDI(LOW);
 173                mac_delay(TIME1);
 174
 175                sh7785lcr_setcmd(MAC_EEP_WRITE);
 176                sh7785lcr_setadd(address++);
 177                sh7785lcr_setdata(*(data + i));
 178
 179                EECLK(LOW);
 180                EEDI(LOW);
 181                EECS(LOW);
 182                mac_delay(TIME2);
 183        }
 184}
 185
 186static void sh7785lcr_macerase(void)
 187{
 188        unsigned int i;
 189        unsigned short pci_address = 7;
 190
 191        for (i = 0; i < 3; i++) {
 192                EECS(HIGH);
 193                EEDI(LOW);
 194                mac_delay(TIME1);
 195                sh7785lcr_setcmd(MAC_EEP_ERACE);
 196                sh7785lcr_setadd(pci_address++);
 197                mac_delay(TIME1);
 198                EECLK(LOW);
 199                EEDI(LOW);
 200                EECS(LOW);
 201        }
 202
 203        mac_delay(TIME2);
 204
 205        printf("\n\nErace End\n");
 206        for (i = 0; i < 10; i++)
 207                mac_delay(TIME2);
 208}
 209
 210static void sh7785lcr_macwrite(unsigned short *data)
 211{
 212        sh7785lcr_macerase();
 213
 214        sh7785lcr_datawrite(EEPROM_W_Data_8169_A, 0x0000, 7);
 215        sh7785lcr_datawrite(data, PCI_EEP_ADDRESS, PCI_MAC_ADDRESS_SIZE);
 216        sh7785lcr_datawrite(EEPROM_W_Data_8169_B, 0x000a, 54);
 217}
 218
 219void sh7785lcr_macdtrd(unsigned char *buf, unsigned short address, unsigned int count)
 220{
 221        unsigned int i;
 222        unsigned short wk;
 223
 224        for (i = 0 ; i < count; i++) {
 225                EECS(HIGH);
 226                EEDI(LOW);
 227                mac_delay(TIME1);
 228                sh7785lcr_setcmd(MAC_EEP_READ);
 229                sh7785lcr_setadd(address++);
 230                wk = sh7785lcr_getdt();
 231
 232                *buf++ = (unsigned char)(wk & 0xff);
 233                *buf++ = (unsigned char)((wk >> 8) & 0xff);
 234                EECLK(LOW);
 235                EEDI(LOW);
 236                EECS(LOW);
 237        }
 238}
 239
 240static void sh7785lcr_macadrd(unsigned char *buf)
 241{
 242        *PCI_MEMR = PCI_PROG;
 243
 244        sh7785lcr_macdtrd(buf, PCI_EEP_ADDRESS, PCI_MAC_ADDRESS_SIZE);
 245}
 246
 247static void sh7785lcr_eepewen(void)
 248{
 249        *PCI_MEMR = PCI_PROG;
 250        mac_delay(TIME1);
 251        EECS(LOW);
 252        EECLK(LOW);
 253        EEDI(LOW);
 254        EECS(HIGH);
 255        mac_delay(TIME1);
 256
 257        sh7785lcr_setcmd(MAC_EEP_EWEN);
 258        sh7785lcr_bitset(1);
 259        sh7785lcr_bitset(1);
 260        sh7785lcr_bitset(BIT_DUMMY);
 261        sh7785lcr_bitset(BIT_DUMMY);
 262        sh7785lcr_bitset(BIT_DUMMY);
 263        sh7785lcr_bitset(BIT_DUMMY);
 264
 265        EECLK(LOW);
 266        EEDI(LOW);
 267        EECS(LOW);
 268        mac_delay(TIME1);
 269}
 270
 271void mac_write(unsigned short *data)
 272{
 273        mac_pci_setup();
 274        sh7785lcr_eepewen();
 275        sh7785lcr_macwrite(data);
 276}
 277
 278void mac_read(void)
 279{
 280        unsigned char data[6];
 281
 282        mac_pci_setup();
 283        sh7785lcr_macadrd(data);
 284        printf("Mac = %02x:%02x:%02x:%02x:%02x:%02x\n",
 285                data[0], data[1], data[2], data[3], data[4], data[5]);
 286}
 287
 288int do_set_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 289{
 290        int i;
 291        unsigned char mac[6];
 292        char *s, *e;
 293
 294        if (argc != 2)
 295                return cmd_usage(cmdtp);
 296
 297        s = argv[1];
 298
 299        for (i = 0; i < 6; i++) {
 300                mac[i] = s ? simple_strtoul(s, &e, 16) : 0;
 301                if (s)
 302                        s = (*e) ? e + 1 : e;
 303        }
 304        mac_write((unsigned short *)mac);
 305
 306        return 0;
 307}
 308
 309U_BOOT_CMD(
 310        setmac, 2,      1,      do_set_mac,
 311        "write MAC address for RTL8110SCL",
 312        "\n"
 313        "setmac <mac address> - write MAC address for RTL8110SCL"
 314);
 315
 316int do_print_mac(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 317{
 318        if (argc != 1)
 319                return cmd_usage(cmdtp);
 320
 321        mac_read();
 322
 323        return 0;
 324}
 325
 326U_BOOT_CMD(
 327        printmac,       1,      1,      do_print_mac,
 328        "print MAC address for RTL8110",
 329        "\n"
 330        "    - print MAC address for RTL8110"
 331);
 332