summaryrefslogtreecommitdiff
path: root/packages/linux/nas100d-kernel/2.6.15/60-nas100d-ide.patch
blob: fea83fbec7ba4ac5686b77e0f16f52bb2863629b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
 drivers/ide/pci/aec62xx.c |   67 +++++++++++++++++++++++++++++++++++++++++++---
 drivers/ide/setup-pci.c   |   12 +++++++-
 2 files changed, 75 insertions(+), 4 deletions(-)

--- linux-nas100d.orig/drivers/ide/pci/aec62xx.c	2005-11-21 20:49:50.000000000 +0100
+++ linux-nas100d/drivers/ide/pci/aec62xx.c	2005-11-21 22:15:21.000000000 +0100
@@ -145,6 +145,16 @@ static int aec6210_tune_chipset (ide_dri
 	unsigned long flags;
 
 	local_irq_save(flags);
+
+#ifdef CONFIG_MACH_NAS100D
+	printk(KERN_INFO "aec62xx: nas100d tuning\n");
+	pci_write_config_word(hwif->pci_dev, PCI_COMMAND, PCI_COMMAND_IO | PCI_COMMAND_MASTER);
+	pci_write_config_byte(hwif->pci_dev, PCI_LATENCY_TIMER, 0x80);
+	/* Enable burst mode & force 2 ports enable  */
+	pci_read_config_byte(hwif->pci_dev, 0x4a, &tmp0);
+	pci_write_config_byte(hwif->pci_dev, 0x4a, tmp0 | 0x80);
+#endif
+
 	/* 0x40|(2*drive->dn): Active, 0x41|(2*drive->dn): Recovery */
 	pci_read_config_word(dev, 0x40|(2*drive->dn), &d_conf);
 	tmp0 = pci_bus_clock_list(speed, BUSCLOCK(dev));
@@ -206,9 +216,17 @@ static int config_chipset_for_dma (ide_d
 {
 	u8 speed = ide_dma_speed(drive, aec62xx_ratemask(drive));	
 
+#ifdef CONFIG_MACH_NAS100D
+	ide_hwif_t *hwif= HWIF(drive);
+	u8 unit		= (drive->select.b.unit & 0x01);
+#endif
 	if (!(speed))
 		return 0;
 
+#ifdef CONFIG_MACH_NAS100D
+	outb((inb(hwif->dma_base+2) & ~(1<<(5+unit))), hwif->dma_base+2);
+#endif
+
 	(void) aec62xx_tune_chipset(drive, speed);
 	return ide_dma_enable(drive);
 }
@@ -299,6 +317,14 @@ static unsigned int __devinit init_chips
 {
 	int bus_speed = system_bus_clock();
 
+#ifdef CONFIG_MACH_NAS100D
+	/* enable both ports */
+	byte tmp;
+	printk(KERN_INFO "%s: nas100d ports enable\n", name);
+	pci_read_config_byte(dev, 0x4a, &tmp);
+	pci_write_config_byte(dev, 0x4a, tmp | 0x06);
+#endif
+
 	if (dev->resource[PCI_ROM_RESOURCE].start) {
 		pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
 		printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start);
@@ -312,12 +338,35 @@ static unsigned int __devinit init_chips
 	return dev->irq;
 }
 
+#ifdef CONFIG_MACH_NAS100D
+static void nas100d_insw (unsigned long port, u16 *addr, u32 count)
+{
+	while (count--)
+		*addr++ = __cpu_to_le16(inw(port));
+}
+
+static void nas100d_outw (u16 val, unsigned long port)
+{
+	u32 n, byte_enables, data;
+	n = port % 4;
+	byte_enables = (0xf & ~(BIT(n) | BIT(n+1))) << IXP4XX_PCI_NP_CBE_BESL;
+	data = val << (8*n);
+	ixp4xx_pci_write(port, byte_enables | NP_CMD_IOWRITE, __le16_to_cpu(data));
+}
+#endif
+
 static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
 {
 	hwif->autodma = 0;
 	hwif->tuneproc = &aec62xx_tune_drive;
 	hwif->speedproc = &aec62xx_tune_chipset;
 
+#ifdef CONFIG_MACH_NAS100D
+	printk(KERN_INFO "aec62xx: enabling nas100d iops\n");
+	hwif->OUTW = nas100d_outw;
+	hwif->INSW = nas100d_insw;
+#endif
+
 	if (hwif->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) {
 		hwif->serialized = hwif->channel;
 		hwif->no_dsc = 1;
@@ -360,11 +409,18 @@ static void __devinit init_dma_aec62xx(i
 	} else {
 		u8 ata66	= 0;
 		pci_read_config_byte(hwif->pci_dev, 0x49, &ata66);
-	        if (!(hwif->udma_four))
+		if (!(hwif->udma_four))
 			hwif->udma_four = (ata66&(hwif->channel?0x02:0x01))?0:1;
 	}
 
 	ide_setup_dma(hwif, dmabase, 8);
+#ifdef CONFIG_MACH_NAS100D
+	{
+		u8 dma_stat = hwif->INB(hwif->dma_status);
+		dma_stat |= (1 << 4);
+		hwif->OUTB(dma_stat, hwif->dma_status);
+	}
+#endif
 }
 
 static int __devinit init_setup_aec62xx(struct pci_dev *dev, ide_pci_device_t *d)
@@ -427,6 +483,9 @@ static ide_pci_device_t aec62xx_chipsets
 		.init_dma	= init_dma_aec62xx,
 		.channels	= 2,
 		.autodma	= AUTODMA,
+#ifdef CONFIG_MACH_NAS100D
+		.enablebits	= {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
+#endif
 		.bootable	= OFF_BOARD,
 	},{	/* 4 */
 		.name		= "AEC6X80R",
@@ -454,6 +513,8 @@ static int __devinit aec62xx_init_one(st
 {
 	ide_pci_device_t *d = &aec62xx_chipsets[id->driver_data];
 
+	printk(KERN_INFO "aec62xx: using config %lx\n", id->driver_data);
+
 	return d->init_setup(dev, d);
 }
 
--- linux-nas100d.orig/drivers/ide/setup-pci.c	2005-11-21 20:49:50.000000000 +0100
+++ linux-nas100d/drivers/ide/setup-pci.c	2005-11-21 22:01:22.000000000 +0100
@@ -602,10 +602,20 @@ void ide_pci_setup_ports(struct pci_dev 
 		if ((d->flags & IDEPCI_FLAG_FORCE_PDC) &&
 		    (secondpdc++==1) && (port==1))
 			goto controller_ok;
-			
+
 		if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||
 		    (tmp & e->mask) != e->val))
+#ifdef CONFIG_MACH_NAS100D
+		{
+			pci_write_config_byte(dev, e->reg, tmp & ~0x01);
+#endif
 			continue;	/* port not enabled */
+#ifdef CONFIG_MACH_NAS100D
+		}
+		else
+			pci_write_config_byte(dev, e->reg, tmp & ~0x01);
+#endif
+
 controller_ok:
 
 		if (d->channels	<= port)