uboot/board/bct-brettl2/smsc9303.c
<<
>>
Prefs
   1/*
   2 * smsc9303.c - routines to initialize SMSC 9303 switch
   3 *
   4 * Copyright (c) 2010 BCT Electronic GmbH
   5 *
   6 * Licensed under the GPL-2 or later.
   7 */
   8
   9#include <common.h>
  10#include <config.h>
  11#include <miiphy.h>
  12
  13#include <asm/blackfin.h>
  14#include <asm/gpio.h>
  15
  16static int smc9303i_write_mii(unsigned char addr, unsigned char reg, unsigned short data)
  17{
  18        const char *devname = miiphy_get_current_dev();
  19
  20        if (!devname)
  21            return 0;
  22
  23        if (miiphy_write(devname, addr, reg, data) != 0)
  24            return 0;
  25
  26        return 1;
  27}
  28
  29static int smc9303i_write_reg(unsigned short reg, unsigned int data)
  30{
  31        const char *devname = miiphy_get_current_dev();
  32        unsigned char mii_addr = 0x10 | (reg >> 6);
  33        unsigned char mii_reg = (reg & 0x3c) >> 1;
  34
  35        if (!devname)
  36            return 0;
  37
  38        if (miiphy_write(devname, mii_addr, mii_reg|0, data & 0xffff) != 0)
  39            return 0;
  40
  41        if (miiphy_write(devname, mii_addr, mii_reg|1, data >> 16) != 0)
  42            return 0;
  43
  44        return 1;
  45}
  46
  47static int smc9303i_read_reg(unsigned short reg, unsigned int *data)
  48{
  49        const char *devname = miiphy_get_current_dev();
  50        unsigned char mii_addr = 0x10 | (reg >> 6);
  51        unsigned char mii_reg = (reg & 0x3c) >> 1;
  52        unsigned short tmp1, tmp2;
  53
  54        if (!devname)
  55            return 0;
  56
  57        if (miiphy_read(devname, mii_addr, mii_reg|0, &tmp1) != 0)
  58            return 0;
  59
  60        if (miiphy_read(devname, mii_addr, mii_reg|1, &tmp2) != 0)
  61            return 0;
  62
  63        *data = (tmp2 << 16) | tmp1;
  64
  65        return 1;
  66}
  67
  68#if 0
  69static int smc9303i_read_mii(unsigned char addr, unsigned char reg, unsigned short *data)
  70{
  71        const char *devname = miiphy_get_current_dev();
  72
  73        if (!devname)
  74            return 0;
  75
  76        if (miiphy_read(devname, addr, reg, data) != 0)
  77            return 0;
  78
  79        return 1;
  80}
  81#endif
  82
  83typedef struct {
  84        unsigned short reg;
  85        unsigned int value;
  86} smsc9303i_config_entry1_t;
  87
  88static const smsc9303i_config_entry1_t smsc9303i_config_table1[] =
  89{
  90        {0x1a0, 0x00000006}, /* Port 1 Manual Flow Control Register */
  91        {0x1a4, 0x00000006}, /* Port 2 Manual Flow Control Register */
  92        {0x1a8, 0x00000006}, /* Port 0 Manual Flow Control Register */
  93};
  94
  95typedef struct
  96{
  97        unsigned char addr;
  98        unsigned char reg;
  99        unsigned short value;
 100} smsc9303i_config_entry2_t;
 101
 102static const smsc9303i_config_entry2_t smsc9303i_config_table2[] =
 103{
 104        {0x01, 0x00, 0x0100}, /* Port0 PHY Basic Control Register */
 105        {0x02, 0x00, 0x1100}, /* Port1 PHY Basic Control Register */
 106        {0x03, 0x00, 0x1100}, /* Port2 PHY Basic Control Register */
 107
 108        {0x01, 0x04, 0x0001}, /* Port0 PHY Auto-Negotiation Advertisement Register */
 109        {0x02, 0x04, 0x2de1}, /* Port1 PHY Auto-Negotiation Advertisement Register */
 110        {0x03, 0x04, 0x2de1}, /* Port2 PHY Auto-Negotiation Advertisement Register */
 111
 112        {0x01, 0x11, 0x0000}, /* Port0 PHY Mode Control/Status Register */
 113        {0x02, 0x11, 0x0000}, /* Port1 PHY Mode Control/Status Register */
 114        {0x03, 0x11, 0x0000}, /* Port2 PHY Mode Control/Status Register */
 115
 116        {0x01, 0x12, 0x0021}, /* Port0 PHY Special Modes Register */
 117        {0x02, 0x12, 0x00e2}, /* Port1 PHY Special Modes Register */
 118        {0x03, 0x12, 0x00e3}, /* Port2 PHY Special Modes Register */
 119        {0x01, 0x1b, 0x0000}, /* Port0 PHY Special Control/Status Indication Register */
 120        {0x02, 0x1b, 0x0000}, /* Port1 PHY Special Control/Status Indication Register */
 121        {0x03, 0x1b, 0x0000}, /* Port2 PHY Special Control/Status Indication Register */
 122        {0x01, 0x1e, 0x0000}, /* Port0 PHY Interrupt Source Flags Register */
 123        {0x02, 0x1e, 0x0000}, /* Port1 PHY Interrupt Source Flags Register */
 124        {0x03, 0x1e, 0x0000}, /* Port2 PHY Interrupt Source Flags Register */
 125};
 126
 127int init_smsc9303i_mii(void)
 128{
 129        unsigned int data;
 130        unsigned int i;
 131
 132        printf("       reset SMSC LAN9303i\n");
 133
 134        gpio_request(GPIO_PG10, "smsc9303");
 135        gpio_direction_output(GPIO_PG10, 0);
 136        udelay(10000);
 137        gpio_direction_output(GPIO_PG10, 1);
 138        udelay(10000);
 139
 140        gpio_free(GPIO_PG10);
 141
 142#if defined(CONFIG_MII_INIT)
 143        mii_init();
 144#endif
 145
 146        printf("       write SMSC LAN9303i configuration\n");
 147
 148        if (!smc9303i_read_reg(0x50, &data))
 149                return 0;
 150
 151        if ((data >> 16) != 0x9303)     {
 152                /* chip id not found */
 153                printf("       error identifying SMSC LAN9303i\n");
 154                return 0;
 155        }
 156
 157        for (i = 0; i < ARRAY_SIZE(smsc9303i_config_table1); i++) {
 158                const smsc9303i_config_entry1_t *entry = &smsc9303i_config_table1[i];
 159
 160                if (!smc9303i_write_reg(entry->reg, entry->value)) {
 161                        printf("       error writing SMSC LAN9303i configuration\n");
 162                        return 0;
 163                }
 164        }
 165
 166        for (i = 0; i < ARRAY_SIZE(smsc9303i_config_table2); i++) {
 167                const smsc9303i_config_entry2_t *entry = &smsc9303i_config_table2[i];
 168
 169                if (!smc9303i_write_mii(entry->addr, entry->reg, entry->value)) {
 170                        printf("       error writing SMSC LAN9303i configuration\n");
 171                        return 0;
 172                }
 173        }
 174
 175        return 1;
 176}
 177