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