1/* $Id: ide.h,v 1.1.1.1 2008/10/15 03:29:18 james26_jang Exp $
2 * ide.h: Ultra/PCI specific IDE glue.
3 *
4 * Copyright (C) 1997  David S. Miller (davem@caip.rutgers.edu)
5 * Copyright (C) 1998  Eddie C. Dost   (ecd@skynet.be)
6 */
7
8#ifndef _SPARC64_IDE_H
9#define _SPARC64_IDE_H
10
11#ifdef __KERNEL__
12
13#include <linux/config.h>
14#include <asm/pgalloc.h>
15#include <asm/io.h>
16#include <asm/hdreg.h>
17#include <asm/page.h>
18#include <asm/spitfire.h>
19
20#undef  MAX_HWIFS
21#define MAX_HWIFS	2
22
23#define	ide__sti()	__sti()
24
25static __inline__ int ide_default_irq(ide_ioreg_t base)
26{
27	return 0;
28}
29
30static __inline__ ide_ioreg_t ide_default_io_base(int index)
31{
32	return 0;
33}
34
35static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
36{
37	ide_ioreg_t reg =  data_port;
38	int i;
39
40	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
41		hw->io_ports[i] = reg;
42		reg += 1;
43	}
44	if (ctrl_port) {
45		hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
46	} else {
47		hw->io_ports[IDE_CONTROL_OFFSET] = 0;
48	}
49	if (irq != NULL)
50		*irq = 0;
51	hw->io_ports[IDE_IRQ_OFFSET] = 0;
52}
53
54/*
55 * This registers the standard ports for this architecture with the IDE
56 * driver.
57 */
58static __inline__ void ide_init_default_hwifs(void)
59{
60#ifndef CONFIG_BLK_DEV_IDEPCI
61	hw_regs_t hw;
62	int index;
63
64	for (index = 0; index < MAX_HWIFS; index++) {
65		ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, NULL);
66		hw.irq = ide_default_irq(ide_default_io_base(index));
67		ide_register_hw(&hw, NULL);
68	}
69#endif /* CONFIG_BLK_DEV_IDEPCI */
70}
71
72typedef union {
73	unsigned int		all	: 8;	/* all of the bits together */
74	struct {
75		unsigned int	bit7	: 1;
76		unsigned int	lba	: 1;
77		unsigned int	bit5	: 1;
78		unsigned int	unit	: 1;
79		unsigned int	head	: 4;
80	} b;
81} select_t;
82
83typedef union {
84	unsigned int all		: 8;	/* all of the bits together */
85	struct {
86		unsigned int HOB	: 1;	/* 48-bit address ordering */
87		unsigned int reserved456: 3;
88		unsigned bit3		: 1;	/* ATA-2 thingy */
89		unsigned int SRST	: 1;	/* host soft reset bit */
90		unsigned int nIEN	: 1;	/* device INTRQ to host */
91		unsigned int bit0	: 1;
92	} b;
93} control_t;
94
95static __inline__ int ide_request_irq(unsigned int irq,
96				      void (*handler)(int, void *, struct pt_regs *),
97				      unsigned long flags, const char *name, void *devid)
98{
99	return request_irq(irq, handler, SA_SHIRQ, name, devid);
100}
101
102static __inline__ void ide_free_irq(unsigned int irq, void *dev_id)
103{
104	free_irq(irq, dev_id);
105}
106
107static __inline__ int ide_check_region(ide_ioreg_t base, unsigned int size)
108{
109	return check_region(base, size);
110}
111
112static __inline__ void ide_request_region(ide_ioreg_t base, unsigned int size,
113					  const char *name)
114{
115	request_region(base, size, name);
116}
117
118static __inline__ void ide_release_region(ide_ioreg_t base, unsigned int size)
119{
120	release_region(base, size);
121}
122
123#undef  SUPPORT_SLOW_DATA_PORTS
124#define SUPPORT_SLOW_DATA_PORTS 0
125
126#undef  SUPPORT_VLB_SYNC
127#define SUPPORT_VLB_SYNC 0
128
129#undef  HD_DATA
130#define HD_DATA ((ide_ioreg_t)0)
131
132/* From m68k code... */
133
134#ifdef insl
135#undef insl
136#endif
137#ifdef outsl
138#undef outsl
139#endif
140#ifdef insw
141#undef insw
142#endif
143#ifdef outsw
144#undef outsw
145#endif
146
147#define insl(data_reg, buffer, wcount) insw(data_reg, buffer, (wcount)<<1)
148#define outsl(data_reg, buffer, wcount) outsw(data_reg, buffer, (wcount)<<1)
149
150#define insw(port, buf, nr) ide_insw((port), (buf), (nr))
151#define outsw(port, buf, nr) ide_outsw((port), (buf), (nr))
152
153static __inline__ unsigned int inw_be(unsigned long addr)
154{
155	unsigned int ret;
156
157	__asm__ __volatile__("lduha [%1] %2, %0"
158			     : "=r" (ret)
159			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
160
161	return ret;
162}
163
164static __inline__ void ide_insw(unsigned long port,
165				void *dst,
166				unsigned long count)
167{
168#if (L1DCACHE_SIZE > PAGE_SIZE)		    /* is there D$ aliasing problem */
169	unsigned long end = (unsigned long)dst + (count << 1);
170#endif
171	u16 *ps = dst;
172	u32 *pi;
173
174	if(((u64)ps) & 0x2) {
175		*ps++ = inw_be(port);
176		count--;
177	}
178	pi = (u32 *)ps;
179	while(count >= 2) {
180		u32 w;
181
182		w  = inw_be(port) << 16;
183		w |= inw_be(port);
184		*pi++ = w;
185		count -= 2;
186	}
187	ps = (u16 *)pi;
188	if(count)
189		*ps++ = inw_be(port);
190
191#if (L1DCACHE_SIZE > PAGE_SIZE)		    /* is there D$ aliasing problem */
192	__flush_dcache_range((unsigned long)dst, end);
193#endif
194}
195
196static __inline__ void outw_be(unsigned short w, unsigned long addr)
197{
198	__asm__ __volatile__("stha %0, [%1] %2"
199			     : /* no outputs */
200			     : "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
201}
202
203static __inline__ void ide_outsw(unsigned long port,
204				 const void *src,
205				 unsigned long count)
206{
207#if (L1DCACHE_SIZE > PAGE_SIZE)		    /* is there D$ aliasing problem */
208	unsigned long end = (unsigned long)src + (count << 1);
209#endif
210	const u16 *ps = src;
211	const u32 *pi;
212
213	if(((u64)src) & 0x2) {
214		outw_be(*ps++, port);
215		count--;
216	}
217	pi = (const u32 *)ps;
218	while(count >= 2) {
219		u32 w;
220
221		w = *pi++;
222		outw_be((w >> 16), port);
223		outw_be(w, port);
224		count -= 2;
225	}
226	ps = (const u16 *)pi;
227	if(count)
228		outw_be(*ps, port);
229
230#if (L1DCACHE_SIZE > PAGE_SIZE)		    /* is there D$ aliasing problem */
231	__flush_dcache_range((unsigned long)src, end);
232#endif
233}
234
235static __inline__ void ide_fix_driveid(struct hd_driveid *id)
236{
237	int i;
238	u16 *stringcast;
239
240	id->config         = __le16_to_cpu(id->config);
241	id->cyls           = __le16_to_cpu(id->cyls);
242	id->reserved2      = __le16_to_cpu(id->reserved2);
243	id->heads          = __le16_to_cpu(id->heads);
244	id->track_bytes    = __le16_to_cpu(id->track_bytes);
245	id->sector_bytes   = __le16_to_cpu(id->sector_bytes);
246	id->sectors        = __le16_to_cpu(id->sectors);
247	id->vendor0        = __le16_to_cpu(id->vendor0);
248	id->vendor1        = __le16_to_cpu(id->vendor1);
249	id->vendor2        = __le16_to_cpu(id->vendor2);
250	stringcast = (u16 *)&id->serial_no[0];
251	for (i = 0; i < (20/2); i++)
252	        stringcast[i] = __le16_to_cpu(stringcast[i]);
253	id->buf_type       = __le16_to_cpu(id->buf_type);
254	id->buf_size       = __le16_to_cpu(id->buf_size);
255	id->ecc_bytes      = __le16_to_cpu(id->ecc_bytes);
256	stringcast = (u16 *)&id->fw_rev[0];
257	for (i = 0; i < (8/2); i++)
258	        stringcast[i] = __le16_to_cpu(stringcast[i]);
259	stringcast = (u16 *)&id->model[0];
260	for (i = 0; i < (40/2); i++)
261	        stringcast[i] = __le16_to_cpu(stringcast[i]);
262	id->dword_io       = __le16_to_cpu(id->dword_io);
263	id->reserved50     = __le16_to_cpu(id->reserved50);
264	id->field_valid    = __le16_to_cpu(id->field_valid);
265	id->cur_cyls       = __le16_to_cpu(id->cur_cyls);
266	id->cur_heads      = __le16_to_cpu(id->cur_heads);
267	id->cur_sectors    = __le16_to_cpu(id->cur_sectors);
268	id->cur_capacity0  = __le16_to_cpu(id->cur_capacity0);
269	id->cur_capacity1  = __le16_to_cpu(id->cur_capacity1);
270	id->lba_capacity   = __le32_to_cpu(id->lba_capacity);
271	id->dma_1word      = __le16_to_cpu(id->dma_1word);
272	id->dma_mword      = __le16_to_cpu(id->dma_mword);
273	id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
274	id->eide_dma_min   = __le16_to_cpu(id->eide_dma_min);
275	id->eide_dma_time  = __le16_to_cpu(id->eide_dma_time);
276	id->eide_pio       = __le16_to_cpu(id->eide_pio);
277	id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
278	for (i = 0; i < 2; i++)
279		id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
280        for (i = 0; i < 4; i++)
281                id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
282	id->queue_depth	   = __le16_to_cpu(id->queue_depth);
283	for (i = 0; i < 4; i++)
284		id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
285	id->major_rev_num  = __le16_to_cpu(id->major_rev_num);
286	id->minor_rev_num  = __le16_to_cpu(id->minor_rev_num);
287	id->command_set_1  = __le16_to_cpu(id->command_set_1);
288	id->command_set_2  = __le16_to_cpu(id->command_set_2);
289	id->cfsse          = __le16_to_cpu(id->cfsse);
290	id->cfs_enable_1   = __le16_to_cpu(id->cfs_enable_1);
291	id->cfs_enable_2   = __le16_to_cpu(id->cfs_enable_2);
292	id->csf_default    = __le16_to_cpu(id->csf_default);
293	id->dma_ultra      = __le16_to_cpu(id->dma_ultra);
294	id->word89         = __le16_to_cpu(id->word89);
295	id->word90         = __le16_to_cpu(id->word90);
296	id->CurAPMvalues   = __le16_to_cpu(id->CurAPMvalues);
297	id->word92         = __le16_to_cpu(id->word92);
298	id->hw_config      = __le16_to_cpu(id->hw_config);
299	id->acoustic       = __le16_to_cpu(id->acoustic);
300	for (i = 0; i < 5; i++)
301		id->words95_99[i]  = __le16_to_cpu(id->words95_99[i]);
302	id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
303	for (i = 0; i < 22; i++)
304		id->words104_125[i]   = __le16_to_cpu(id->words104_125[i]);
305	id->last_lun       = __le16_to_cpu(id->last_lun);
306	id->word127        = __le16_to_cpu(id->word127);
307	id->dlf            = __le16_to_cpu(id->dlf);
308	id->csfo           = __le16_to_cpu(id->csfo);
309	for (i = 0; i < 26; i++)
310		id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
311	id->word156        = __le16_to_cpu(id->word156);
312	for (i = 0; i < 3; i++)
313		id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
314	id->cfa_power      = __le16_to_cpu(id->cfa_power);
315	for (i = 0; i < 14; i++)
316		id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
317	for (i = 0; i < 31; i++)
318		id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
319	for (i = 0; i < 48; i++)
320		id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
321	id->integrity_word  = __le16_to_cpu(id->integrity_word);
322}
323
324/*
325 * The following are not needed for the non-m68k ports
326 */
327#define ide_ack_intr(hwif)		(1)
328#define ide_release_lock(lock)		do {} while (0)
329#define ide_get_lock(lock, hdlr, data)	do {} while (0)
330
331#endif /* __KERNEL__ */
332
333#endif /* _SPARC64_IDE_H */
334