3ce3041abace326d0ae01782f8f7d1599caba373
[coreboot.git] / src / southbridge / nvidia / ck804 / ck804_nic.c
1 /*
2  * Copyright 2004 Tyan Computer
3  *  by yhlu@tyan.com
4  */
5 #include <console/console.h>
6 #include <device/device.h>
7 #include <device/smbus.h>
8 #include <device/pci.h>
9 #include <device/pci_ids.h>
10 #include <device/pci_ops.h>
11 #include <arch/io.h>
12 #include "ck804.h"
13
14
15 static void nic_init(struct device *dev)
16 {
17         uint32_t dword, old;
18         uint32_t mac_h, mac_l;
19         int eeprom_valid = 0;
20         struct southbridge_nvidia_ck804_config *conf;
21
22         static uint32_t nic_index = 0;
23
24         uint8_t *base;
25         struct resource *res;
26
27         res = find_resource(dev, 0x10);
28
29         base = res->base;
30
31 #define NvRegPhyInterface  0xC0
32 #define PHY_RGMII          0x10000000
33
34         writel(PHY_RGMII, base + NvRegPhyInterface);
35
36         old = dword = pci_read_config32(dev, 0x30);
37         dword &= ~(0xf);
38         dword |= 0xf;
39         if(old != dword) {
40                 pci_write_config32(dev, 0x30 , dword);
41         }
42
43         conf = dev->chip_info;
44        
45         if(conf->mac_eeprom_smbus != 0) { 
46 //      read MAC address from EEPROM at first
47                 struct device *dev_eeprom;
48                 dev_eeprom = dev_find_slot_on_smbus(conf->mac_eeprom_smbus, conf->mac_eeprom_addr);
49
50                 if(dev_eeprom) {
51                 //      if that is valid we will use that
52                         unsigned char dat[6];
53                         int status;
54                         int i;
55                         for(i=0;i<6;i++) {
56                                 status = smbus_read_byte(dev_eeprom, i);
57                                 if(status < 0) break;
58                                 dat[i] = status & 0xff;
59                         }
60                         if(status >= 0) {
61                                 mac_l = 0;
62                                 for(i=3;i>=0;i--) {
63                                         mac_l <<= 8;
64                                         mac_l += dat[i];
65                                 }
66                                 if(mac_l != 0xffffffff) {
67                                         mac_l += nic_index;
68                                         mac_h = 0;
69                                         for(i=5;i>=4;i--) {
70                                                 mac_h <<= 8;
71                                                 mac_h += dat[i];
72                                         }
73                                         eeprom_valid = 1;       
74                                 }
75                         }
76                 }
77         }
78 //      if that is invalid we will read that from romstrap
79         if(!eeprom_valid) {
80                 unsigned long mac_pos;
81                 mac_pos = 0xffffffd0; // refer to romstrap.inc and romstrap.lds
82                 mac_l = readl(mac_pos) + nic_index;
83                 mac_h = readl(mac_pos + 4);
84         }
85 #if 1   
86 //      set that into NIC MMIO
87 #define NvRegMacAddrA  0xA8
88 #define NvRegMacAddrB  0xAC
89         writel(mac_l, base + NvRegMacAddrA);
90         writel(mac_h, base + NvRegMacAddrB);
91 #else
92 //      set that into NIC
93         pci_write_config32(dev, 0xa8, mac_l);
94         pci_write_config32(dev, 0xac, mac_h);
95 #endif
96
97         nic_index++;
98
99 #if CONFIG_PCI_ROM_RUN == 1
100         pci_dev_init(dev);// it will init option rom
101 #endif
102
103 }
104
105 static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
106 {
107         pci_write_config32(dev, 0x40,
108                 ((device & 0xffff) << 16) | (vendor & 0xffff));
109 }
110
111 static struct pci_operations lops_pci = {
112         .set_subsystem = lpci_set_subsystem,
113 };
114
115 static struct device_operations nic_ops  = {
116         .read_resources   = pci_dev_read_resources,
117         .set_resources    = pci_dev_set_resources,
118         .enable_resources = pci_dev_enable_resources,
119         .init             = nic_init,
120         .scan_bus         = 0,
121 //      .enable           = ck804_enable,
122         .ops_pci          = &lops_pci,
123 };
124 static struct pci_driver nic_driver __pci_driver = {
125         .ops    = &nic_ops,
126         .vendor = PCI_VENDOR_ID_NVIDIA,
127         .device = PCI_DEVICE_ID_NVIDIA_CK804_NIC,
128 };
129 static struct pci_driver nic_bridge_driver __pci_driver = {
130         .ops    = &nic_ops,
131         .vendor = PCI_VENDOR_ID_NVIDIA,
132         .device = PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE,
133 };