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