58d5ff5bb754fd41d772a2d481a2f610e0193b2e
[coreboot.git] / src / southbridge / broadcom / bcm5785 / bcm5785_sata.c
1 /*
2  * Copyright  2005 AMD
3  *  by yinghai.lu@amd.com
4  */
5
6 #include <console/console.h>
7 #include <device/device.h>
8 #include <delay.h>
9 #include <device/pci.h>
10 #include <device/pci_ids.h>
11 #include <device/pci_ops.h>
12 #include <arch/io.h>
13 #include "bcm5785.h"
14
15 static void sata_init(struct device *dev)
16 {
17         uint8_t byte;
18
19         u32 mmio;
20         struct resource *res;
21         u32 mmio_base;
22         int i;
23
24         if(!(dev->path.pci.devfn & 7)) { // only set it in Func0
25                 byte = pci_read_config8(dev, 0x78);
26                 byte |= (1<<7);
27                 pci_write_config8(dev, 0x78, byte);
28
29                 res = find_resource(dev, 0x24);
30                 mmio_base = res->base;
31                 mmio_base &= 0xfffffffc;
32
33                 write32(mmio_base + 0x10f0, 0x40000001);
34                 write32(mmio_base + 0x8c, 0x00ff2007);
35                 mdelay( 10 );
36                 write32(mmio_base + 0x8c, 0x78592009);
37                 mdelay( 10 );
38                 write32(mmio_base + 0x8c, 0x00082004);
39                 mdelay( 10 );
40                 write32(mmio_base + 0x8c, 0x00002004);
41                 mdelay( 10 );
42
43                 //init PHY
44
45                 printk(BIOS_DEBUG, "init PHY...\n");
46                 for(i=0; i<4; i++) {
47                         mmio = res->base + 0x100 * i;
48                         byte = read8(mmio + 0x40);
49                         printk(BIOS_DEBUG, "port %d PHY status = %02x\n", i, byte);
50                         if(byte & 0x4) {// bit 2 is set
51                                 byte = read8(mmio+0x48);
52                                 write8(mmio + 0x48, byte | 1);
53                                 write8(mmio + 0x48, byte & (~1));
54                                 byte = read8(mmio + 0x40);
55                                 printk(BIOS_DEBUG, "after reset port %d PHY status = %02x\n", i, byte);
56                         }
57                 }
58         }
59 }
60
61 static void lpci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
62 {
63         pci_write_config32(dev, 0x40,
64                 ((device & 0xffff) << 16) | (vendor & 0xffff));
65 }
66 static struct pci_operations lops_pci = {
67         .set_subsystem = lpci_set_subsystem,
68 };
69
70 static struct device_operations sata_ops  = {
71         .read_resources   = pci_dev_read_resources,
72         .set_resources    = pci_dev_set_resources,
73         .enable_resources = pci_dev_enable_resources,
74 //      .enable           = bcm5785_enable,
75         .init             = sata_init,
76         .scan_bus         = 0,
77         .ops_pci          = &lops_pci,
78 };
79
80 static const struct pci_driver sata0_driver __pci_driver = {
81         .ops    = &sata_ops,
82         .vendor = PCI_VENDOR_ID_SERVERWORKS,
83         .device = PCI_DEVICE_ID_SERVERWORKS_BCM5785_SATA,
84 };
85