blob: 42456d7be334dab74d67df839d3c1c040cc1cee2 [file] [log] [blame]
mushtaq khan66d9dbe2007-04-20 14:23:02 +05301/*
Wolfgang Denk3162eb82007-05-15 23:38:05 +02002 * Copyright (C) Procsys. All rights reserved.
3 * Author: Mushtaq Khan <mushtaq_k@procsys.com>
4 * <mushtaqk_921@yahoo.co.in>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 * MA 02111-1307 USA
20 *
21 * with the reference to ata_piix driver in kernel 2.4.32
22 */
mushtaq khan66d9dbe2007-04-20 14:23:02 +053023
24/*
Wolfgang Denk3162eb82007-05-15 23:38:05 +020025 * This file contains SATA controller and SATA drive initialization functions
26 */
mushtaq khan66d9dbe2007-04-20 14:23:02 +053027
28#include <common.h>
29#include <pci.h>
30#include <command.h>
31#include <config.h>
32#include <asm/byteorder.h>
33#include <ide.h>
34#include <ata.h>
35
36#ifdef CFG_ATA_PIIX /*ata_piix driver */
37
38#define DEBUG_SATA 0 /*For debug prints set DEBUG_SATA to 1 */
39
40#define DRV_DECL /*For file specific declarations */
41#include <sata.h>
42#undef DRV_DECL
43
44/*Macros realted to PCI*/
45#define PCI_SATA_BUS 0x00
46#define PCI_SATA_DEV 0x1f
47#define PCI_SATA_FUNC 0x02
48
49#define PCI_SATA_BASE1 0x10
50#define PCI_SATA_BASE2 0x14
51#define PCI_SATA_BASE3 0x18
52#define PCI_SATA_BASE4 0x1c
53#define PCI_SATA_BASE5 0x20
54#define PCI_PMR 0x90
55#define PCI_PI 0x09
56#define PCI_PCS 0x92
57#define PCI_DMA_CTL 0x48
58
59#define PORT_PRESENT (1<<0)
60#define PORT_ENABLED (1<<4)
61
62u32 bdf;
63u32 iobase1 = 0; /*Primary cmd block */
64u32 iobase2 = 0; /*Primary ctl block */
65u32 iobase3 = 0; /*Sec cmd block */
66u32 iobase4 = 0; /*sec ctl block */
67u32 iobase5 = 0; /*BMDMA*/
68int
69pci_sata_init (void)
70{
71 u32 bus = PCI_SATA_BUS;
72 u32 dev = PCI_SATA_DEV;
73 u32 fun = PCI_SATA_FUNC;
74 u16 cmd = 0;
75 u8 lat = 0, pcibios_max_latency = 0xff;
76 u8 pmr; /*Port mapping reg */
77 u8 pi; /*Prgming Interface reg */
78
79 bdf = PCI_BDF (bus, dev, fun);
80 pci_read_config_dword (bdf, PCI_SATA_BASE1, &iobase1);
81 pci_read_config_dword (bdf, PCI_SATA_BASE2, &iobase2);
82 pci_read_config_dword (bdf, PCI_SATA_BASE3, &iobase3);
83 pci_read_config_dword (bdf, PCI_SATA_BASE4, &iobase4);
84 pci_read_config_dword (bdf, PCI_SATA_BASE5, &iobase5);
85
86 if ((iobase1 == 0xFFFFFFFF) || (iobase2 == 0xFFFFFFFF) ||
87 (iobase3 == 0xFFFFFFFF) || (iobase4 == 0xFFFFFFFF) ||
88 (iobase5 == 0xFFFFFFFF)) {
89 printf ("error no base addr for SATA controller\n");
90 return 1;
91 /*ERROR*/}
92
93 iobase1 &= 0xFFFFFFFE;
94 iobase2 &= 0xFFFFFFFE;
95 iobase3 &= 0xFFFFFFFE;
96 iobase4 &= 0xFFFFFFFE;
97 iobase5 &= 0xFFFFFFFE;
98
99 /*check for mode */
100 pci_read_config_byte (bdf, PCI_PMR, &pmr);
101 if (pmr > 1) {
102 printf ("combined mode not supported\n");
103 return 1;
104 }
105
106 pci_read_config_byte (bdf, PCI_PI, &pi);
107 if ((pi & 0x05) != 0x05) {
108 printf ("Sata is in Legacy mode\n");
109 return 1;
110 } else {
111 printf ("sata is in Native mode\n");
112 }
113
114 /*MASTER CFG AND IO CFG */
115 pci_read_config_word (bdf, PCI_COMMAND, &cmd);
116 cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
117 pci_write_config_word (bdf, PCI_COMMAND, cmd);
118 pci_read_config_byte (dev, PCI_LATENCY_TIMER, &lat);
119
120 if (lat < 16)
121 lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
122 else if (lat > pcibios_max_latency)
123 lat = pcibios_max_latency;
124 pci_write_config_byte (dev, PCI_LATENCY_TIMER, lat);
125
126 return 0;
127}
128
129int
130sata_bus_probe (int port_no)
131{
132 int orig_mask, mask;
133 u16 pcs;
134
135 mask = (PORT_PRESENT << port_no);
136 pci_read_config_word (bdf, PCI_PCS, &pcs);
137 orig_mask = (int) pcs & 0xff;
138 if ((orig_mask & mask) != mask)
139 return 0;
140 else
141 return 1;
142}
143
144int
145init_sata (void)
146{
147 u8 i, rv = 0;
148
149 for (i = 0; i < CFG_SATA_MAXDEVICES; i++) {
150 sata_dev_desc[i].type = DEV_TYPE_UNKNOWN;
151 sata_dev_desc[i].if_type = IF_TYPE_IDE;
152 sata_dev_desc[i].dev = i;
153 sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
154 sata_dev_desc[i].blksz = 0;
155 sata_dev_desc[i].lba = 0;
156 sata_dev_desc[i].block_read = sata_read;
157 }
158
159 rv = pci_sata_init ();
160 if (rv == 1) {
161 printf ("pci initialization failed\n");
162 return 1;
163 }
164
165 port[0].port_no = 0;
166 port[0].ioaddr.cmd_addr = iobase1;
167 port[0].ioaddr.altstatus_addr = port[0].ioaddr.ctl_addr =
168 iobase2 | ATA_PCI_CTL_OFS;
169 port[0].ioaddr.bmdma_addr = iobase5;
170
171 port[1].port_no = 1;
172 port[1].ioaddr.cmd_addr = iobase3;
173 port[1].ioaddr.altstatus_addr = port[1].ioaddr.ctl_addr =
174 iobase4 | ATA_PCI_CTL_OFS;
175 port[1].ioaddr.bmdma_addr = iobase5 + 0x8;
176
177 for (i = 0; i < CFG_SATA_MAXBUS; i++)
178 sata_port (&port[i].ioaddr);
179
180 for (i = 0; i < CFG_SATA_MAXBUS; i++) {
181 if (!(sata_bus_probe (i))) {
182 port[i].port_state = 0;
183 printf ("SATA#%d port is not present \n", i);
184 } else {
185 printf ("SATA#%d port is present\n", i);
186 if (sata_bus_softreset (i)) {
187 port[i].port_state = 0;
188 } else {
189 port[i].port_state = 1;
190 }
191 }
192 }
193
194 for (i = 0; i < CFG_SATA_MAXBUS; i++) {
195 u8 j, devno;
196
197 if (port[i].port_state == 0)
198 continue;
199 for (j = 0; j < CFG_SATA_DEVS_PER_BUS; j++) {
200 sata_identify (i, j);
201 set_Feature_cmd (i, j);
202 devno = i * CFG_SATA_DEVS_PER_BUS + j;
203 if ((sata_dev_desc[devno].lba > 0) &&
204 (sata_dev_desc[devno].blksz > 0)) {
205 dev_print (&sata_dev_desc[devno]);
206 /* initialize partition type */
207 init_part (&sata_dev_desc[devno]);
208 if (curr_dev < 0)
209 curr_dev =
210 i * CFG_SATA_DEVS_PER_BUS + j;
211 }
212 }
213 }
214 return 0;
215}
216#endif