Hi All,
I'm using IBM redwood6 stb025xx(ppc405gp) platform
with 2.6.14 kernel. I'm trying to get DMA working for IDE interface (PIO is
working). The problem I'm facing is that my DMA is completing and I'm getting a
error in DMA status register that "A DMA request from an external
device is pending"
I'm attaching (inline) the console message(in red
color) along with the sample code of the driver(in blue color). Please help
me to resolve this issue. What I feel is that DMA is completing and IDE is not
getting anything. ( IDE status register is giving 0x58).
Any pointers to same will be highly
appreciated.
Regards,
Akhilesh
IBM Set-Top-Box BIOS 1.50 (Feb-16-2004)
Platform support <Redwood6/STBx25xx 1.03
(Jun/24/2002)>
Initializing devices, please
wait.....
------- System Info --------
Processor speed = 252 MHz
EBIU speed = 63
MHz
Amount of RAM = 64
MBytes
DM9000 : dmfe_probe() : Checking DM9000 chip
DM9000 : Chip Found ID : 90000a46
--- Device Configuration ---
Power-On Test Devices:
000 Disabled System Memory
[RAM]
----------------------------
Boot Sources:
001 Disabled Application in
Flash [FLASH]
002 Enabled Ethernet
[ENET]
local=192.168.18.28 remote=192.168.18.101
hwaddr=bad0add00000
003 Disabled Serial Port 1
[S1]
Baud = 9600
----------------------------
Update Flash : Disabled
Automatic Boot: Disabled
----------------------------
1 - Toggle Power-On Tests
2 - Change a Boot Device
3 - Change IP Addresses
4 - Ping test
5 - Change Baud Rate for S1 Boot
6 - Toggle Update Flash
7 - Toggle Automatic Boot
B - Bootlogo Management
D - Display Configuration
S - Save Changes
Z - Set Ethernet HW Address
0 - Exit Menu and Boot Application
C - Enable CHOIS Debug
->0
DM900 : dmfe_init_dm9000 : initialising
dm9000
Booting from [ENET] Ethernet...
Sending bootp request ...
bootp packets sent = 1
DM900 : dmfe_send :
hold frame collision, outbound frame.
Got bootp response from :
192.168.18.101
My ip address is :
192.168.18.28
Loading file "zImage.treeboot" by TFTP for net boot
...
block 268
block 1440
Transfer
completed, 897568 bytes received
Loaded successfully ...
Entry point at 0x500000 ...
loaded at: 00500000
005DC164
relocated to: 00400000 004DC164
board data at: 004DA124 004DA164
relocated to: 0040515C 0040519C
zimage at: 0040591D
004D9A6C
avail ram: 004DD000
02000000
Linux/PPC load: ip=on
Uncompressing Linux...done.
Now booting the kernel
ocp: ocp_early_init()...
ocp: ocp_add_one_device()...
ocp: ocp_add_one_device()...done
ocp: ocp_add_one_device()...
ocp: ocp_add_one_device()...done
ocp: ocp_add_one_device()...
ocp: ocp_add_one_device()...done
ocp: ocp_add_one_device()...
ocp: ocp_add_one_device()...done
ocp: ocp_add_one_device()...
ocp: ocp_add_one_device()...done
ocp: ocp_add_one_device()...
ocp: ocp_add_one_device()...done
ocp: ocp_early_init()... done.
IBM Redwood6 (STBx25XX) Platform
Built 1 zonelists
Kernel command line: ip=on
PID hash table entries: 256 (order: 8, 4096
bytes)
Dentry cache hash table entries: 8192 (order: 3, 32768
bytes)
Inode-cache hash table entries: 4096 (order: 2, 16384
bytes)
Memory: 30488k available (1452k kernel code, 344k data,
96k init, 0k highmem)
Mount-cache hash table entries: 512
NET: Registered protocol family 16
ocp: ocp_driver_init()...
ocp: ocp_driver_init()... done.
Adding platform devices
Serial: 8250/16550 driver $Revision: 1.90 $ 4 ports,
IRQ sharing disabled
ttyS0 at MMIO 0x0 (irq = 22) is a 16550A
ttyS1 at MMIO 0x0 (irq = 20) is a 16550A
ttyS2 at MMIO 0x0 (irq = 21) is a 16550A
io scheduler noop registered
io scheduler anticipatory registered
io scheduler deadline registered
io scheduler cfq registered
RAMDISK driver initialized: 16 RAM disks of 4096K size
1024 blocksize
loop: loaded (max 8 devices)
dm9000 Ethernet Driver
dm9000_set_io : byte_width 2
eth0: dm9000 at c3000000,c3000004 IRQ 26 MAC:
ba:d0:ad:d0:00:00
Uniform Multi-Platform E-IDE driver Revision:
7.00alpha2
ide: Assuming 50MHz system bus speed for PIO modes;
override with idebus=xx
NET: Registered protocol family 2
IP route cache hash table entries: 512 (order: -1, 2048
bytes)
TCP established hash table entries: 2048 (order: 1,
8192 bytes)
TCP bind hash table entries: 2048 (order: 1, 8192
bytes)
TCP: Hash tables configured (established 2048 bind
2048)
TCP reno registered
TCP bic registered
NET: Registered protocol family 1
inside stb04xxx_ide_init
IBM STB025xx OCP IDE driver version 1.0 f2100000
ide_redwood: waiting for drive ready......Drive spun up
ocp_ide_setup_dma
probing for hda: present=0, media=32,
probetype=ATA
hda: probing with STATUS(0x51) instead of
ALTSTATUS(0x00)
hda: WDC WD400EB-00CPF0, ATA DISK drive
probing for hdb: present=0, media=32,
probetype=ATA
probing for hdb: present=0, media=32,
probetype=ATAPI
hdb: probing with STATUS(0x01) instead of
ALTSTATUS(0x00)
ocp_ide_tune_drive pio 4
got ocp_ide_dma_off_quietly
got ocp_ide_dma_check
redwood_config_drive_for_dma 22
ocp_ide_tune_drive pio 4
got ocp_ide_dma_on
ide0 at 0xc3004000-0xc3004007,0xc3006000 on irq
27
hda: max request size: 128KiB
ide_execute_command : 0x91
ide_execute_command : 0x10
ide_execute_command : 0xf8
hda: 78165360 sectors (40020 MB) w/2048KiB Cache,
CHS=65535/16/63, (U)DMA
hda: cache flushes not supported
hda:__ide_do_rw_disk : dma 1 lba48 0
LBA=0
got ocp_ide_dma_setup
ide_execute_command : 0xc8
got ocp_ide_dma_begin 0x1000
DMA addr c0340000 340000 count 8 dmastat 0
got ocp_ide_dma_test_irq
got ocp_ide_dma_end 0 20000000
ide_dma_intr : stat 50
DMA complete stat 0 500000
hda1
IDE probe finished
eth0: link up, 100Mbps, full-duplex, lpa
0x41E1
Sending BOOTP and RARP requests . OK
IP-Config: Got BOOTP answer from 192.168.18.101, my
address is 192.168.18.28
IP-Config: Complete:
device=eth0,
addr=192.168.18.28, mask=255.255.255.0, gw=192.168.18.1,
host=192.168.18.28, domain=,
nis-domain=(none),
bootserver=192.168.18.101,
rootserver=192.168.18.101, rootpath=/opt/eldk/ppc_4xx
Looking up port of RPC 100003/2 on
192.168.18.101
Looking up port of RPC 100005/1 on
192.168.18.101
VFS: Mounted root (nfs filesystem)
readonly.
Freeing unused kernel memory: 96k init
modprobe: FATAL: Could not load
/lib/modules/2.6.14/modules.dep: No such file or directory
modprobe: FATAL: Could not load
/lib/modules/2.6.14/modules.dep: No such file or directory
INIT: version 2.85 booting
Came here in
rc.sysinit creating var\n
mounting
ln: `/proc/mounts': File
exists
Welcome to DENX Embedded Linux
Environment
Press 'I' to enter interactive startup.
Building
the cache [ OK ]
storage network audio done[ OK
]
modprobe: FATAL: Could not load /lib/modules/2.6.14/modules.dep: No such
file or directory
Cannot access the Hardware Clock via any known
method.
Use the --debug option to see the details of our search for an access
method.
Setting clock : Thu Jan 1 01:00:12 MET 1970 [ OK
]
Setting hostname CHOISpad-110: [ OK ]
Mounting local
filesystems: [ OK ]
Enabling swap space: [
OK ]
INIT: Entering runlevel: 3
Entering non-interactive
startup
Bringing up loopback interface: modprobe: FATAL: Could not load
/lib/modules/2.6.14/modules.dep: No such file or directory
arping: socket: Address family not supported by
protocol
Error, some other host already uses address
127.0.0.1.
[FAILED]
Starting system logger: [ OK ]
Starting
kernel logger: [ OK ]
Starting portmap: [ OK
]
Mounting NFS filesystems: [ OK ]
Mounting other
filesystems: [ OK ]
Starting xinetd: [ OK
]
DENX ELDK version 4.0 build 2006-01-11
Linux 2.6.14
on a ppc
CHOISpad-110 login: root
Last login: Thu Jan 1
01:00:19 on console
bash-3.00#
bash-3.00#
bash-3.00#
bash-3.00#
bash-3.00#
bash-3.00# hdparm -t /dev/hda
/dev/hda:
multcount =
0 (off)
I/O support = 0 (default
16-bit)
unmaskirq = 1
(on)
using_dma = 1 (on)
keepsettings
= 0 (off)
nowerr = 0
(off)
readonly = 0
(off)
readahead = 256
(on)
geometry = 65535/16/63, sectors =
78165360, start = 0
bash-3.00#
bash-3.00#
bash-3.00#
bash-3.00#
bash-3.00# hdparm -t /dev/hda
/dev/hda:
Timing buffered__ide_do_rw_disk :
dma 1 lba48 0 LBA=0
disk reads: got ocp_ide_dma_setup
ide_execute_command : 0xc8
got ocp_ide_dma_begin 0x1000
DMA addr c1238000 1238000 count 8 dmastat
0
DMA complete stat 20001000 0
hda: lost interrupt
got ocp_ide_dma_end 0 20000000
ide_dma_intr : stat 58
hda: dma_intr: status=0x58 { DriveReady SeekComplete
DataRequest }
ide: failed opcode was: unknown
__ide_do_rw_disk : dma 1 lba48 0 LBA=0
got ocp_ide_dma_setup
ide_execute_command : 0xc8
got ocp_ide_dma_begin 0x1000
DMA addr c1238000 1238000 count 8 dmastat
0
DMA complete stat 20001000 0
hda: lost interrupt
got ocp_ide_dma_end 0 20000000
ide_dma_intr : stat 58
hda: dma_intr: status=0x58 { DriveReady SeekComplete
DataRequest }
ide: failed opcode was: unknown
ide_execute_command : 0x10
__ide_do_rw_disk : dma 1 lba48 0 LBA=0
got ocp_ide_dma_setup
ide_execute_command : 0xc8
got ocp_ide_dma_begin 0x1000
DMA addr c1238000 1238000 count 8 dmastat
0
DMA complete stat 20001000 0
hda: lost interrupt
got ocp_ide_dma_end 0 20000000
ide_dma_intr : stat 58
hda: dma_intr: status=0x58 { DriveReady SeekComplete
DataRequest }
ide: failed opcode was: unknown
__ide_do_rw_disk : dma 1 lba48 0 LBA=0
got ocp_ide_dma_setup
ide_execute_command : 0xc8
got ocp_ide_dma_begin 0x1000
DMA addr c1238000 1238000 count 8 dmastat
0
DMA complete stat 20001000 0
hda: lost interrupt
got ocp_ide_dma_end 0 20000000
ide_dma_intr : stat 58
hda: dma_intr: status=0x58 { DriveReady SeekComplete
DataRequest }
ide: failed opcode was: unknown
got ocp_ide_dma_off_quietly
ide0: reset: master: error (0x00?)
ide_execute_command : 0x91
ide_execute_command : 0x10
__ide_do_rw_disk : dma 1 lba48 0 LBA=0
got ocp_ide_dma_setup
ide_execute_command : 0xc8
got ocp_ide_dma_begin 0x1000
DMA addr c1238000 1238000 count 8 dmastat
0
DMA complete stat 20001000 0
hda: lost interrupt
got ocp_ide_dma_end 0 20000000
ide_dma_intr : stat 58
hda: dma_intr: status=0x58 { DriveReady SeekComplete
DataRequest }
ide: failed opcode was: unknown
__ide_do_rw_disk : dma 1 lba48 0 LBA=0
got ocp_ide_dma_setup
ide_execute_command : 0xc8
got ocp_ide_dma_begin 0x1000
DMA addr c1238000 1238000 count 8 dmastat
0
DMA complete stat 20001000 0
hda: lost interrupt
got ocp_ide_dma_end 0 20000000
ide_dma_intr : stat 58
hda: dma_intr: status=0x58 { DriveReady SeekComplete
DataRequest }
ide: failed opcode was: unknown
ide_execute_command : 0x10
__ide_do_rw_disk : dma 1 lba48 0 LBA=0
got ocp_ide_dma_setup
ide_execute_command : 0xc8
got ocp_ide_dma_begin 0x1000
DMA addr c1238000 1238000 count 8 dmastat
0
DMA complete stat 20001000 0
hda: lost interrupt
got ocp_ide_dma_end 0 20000000
ide_dma_intr : stat 58
hda: dma_intr: status=0x58 { DriveReady SeekComplete
DataRequest }
ide: failed opcode was: unknown
__ide_do_rw_disk : dma 1 lba48 0 LBA=0
got ocp_ide_dma_setup
ide_execute_command : 0xc8
got ocp_ide_dma_begin 0x1000
DMA addr c1238000 1238000 count 8 dmastat
0
DMA complete stat 20001000 0
hda: lost interrupt
got ocp_ide_dma_end 0 20000000
ide_dma_intr : stat 58
hda: dma_intr: status=0x58 { DriveReady SeekComplete
DataRequest }
ide: failed opcode was: unknown
got ocp_ide_dma_off_quietly
ide0: reset: master: error (0x00?)
end_request: I/O error, dev hda, sector 0
Buffer I/O error on device hda, logical block
0
end_request: I/O error, dev hda, sector 8
Buffer I/O error on device hda, logical block
1
end_request: I/O error, dev hda, sector 16
Buffer I/O error on device hda, logical block
2
end_request: I/O error, dev hda, sector 24
Buffer I/O error on device hda, logical block
3
end_request: I/O error, dev hda, sector 32
Buffer I/O error on device hda, logical block
4
end_request: I/O error, dev hda, sector 40
Buffer I/O error on device hda, logical block
5
end_request: I/O error, dev hda, sector 48
Buffer I/O error on device hda, logical block
6
end_request: I/O error, dev hda, sector 56
Buffer I/O error on device hda, logical block
7
end_request: I/O error, dev hda, sector 64
Buffer I/O error on device hda, logical block
8
end_request: I/O error, dev hda, sector 72
Buffer I/O error on device hda, logical block
9
end_request: I/O error, dev hda, sector 80
end_request: I/O error, dev hda, sector 88
end_request: I/O error, dev hda, sector 96
end_request: I/O error, dev hda, sector
104
end_request: I/O error, dev hda, sector
112
end_request: I/O error, dev hda, sector
120
end_request: I/O error, dev hda, sector
128
end_request: I/O error, dev hda, sector
136
end_request: I/O error, dev hda, sector
144
end_request: I/O error, dev hda, sector
152
end_request: I/O error, dev hda, sector
160
end_request: I/O error, dev hda, sector
168
end_request: I/O error, dev hda, sector
176
end_request: I/O error, dev hda, sector
184
end_request: I/O error, dev hda, sector
192
end_request: I/O error, dev hda, sector
200
end_request: I/O error, dev hda, sector
208
end_request: I/O error, dev hda, sector
216
end_request: I/O error, dev hda, sector
224
end_request: I/O error, dev hda, sector
232
end_request: I/O error, dev hda, sector
240
end_request: I/O error, dev hda, sector
248
end_request: I/O error, dev hda, sector
256
end_request: I/O error, dev hda, sector
264
end_request: I/O error, dev hda, sector
272
end_request: I/O error, dev hda, sector
280
end_request: I/O error, dev hda, sector
288
end_request: I/O error, dev hda, sector
296
end_request: I/O error, dev hda, sector
304
end_request: I/O error, dev hda, sector
312
end_request: I/O error, dev hda, sector
320
end_request: I/O error, dev hda, sector
328
end_request: I/O error, dev hda, sector
336
end_request: I/O error, dev hda, sector
344
end_request: I/O error, dev hda, sector
352
end_request: I/O error, dev hda, sector
360
end_request: I/O error, dev hda, sector
368
end_request: I/O error, dev hda, sector
376
end_request: I/O error, dev hda, sector
384
end_request: I/O error, dev hda, sector
392
end_request: I/O error, dev hda, sector
400
end_request: I/O error, dev hda, sector
408
end_request: I/O error, dev hda, sector
416
end_request: I/O error, dev hda, sector
424
end_request: I/O error, dev hda, sector
432
end_request: I/O error, dev hda, sector
440
end_request: I/O error, dev hda, sector
448
end_request: I/O error, dev hda, sector
456
end_request: I/O error, dev hda, sector
464
end_request: I/O error, dev hda, sector
472
end_request: I/O error, dev hda, sector
480
end_request: I/O error, dev hda, sector
488
end_request: I/O error, dev hda, sector
496
end_request: I/O error, dev hda, sector
504
end_request: I/O error, dev hda, sector 0
read() failed: Input/output error
bash-3.00#
static void ocp_ide_dma_begin(ide_drive_t
*drive){
int i,reading=0,length;
struct request * const rq =
HWGROUP(drive)->rq;
unsigned long control;
if(rq_data_dir (rq) == READ) reading =
1;
printk("got ocp_ide_dma_begin
0x%x\n",mfdcr(DCRN_DMASR));
/* enable DMA
*/
ppc4xx_enable_dma_interrupt(IDE_DMACH);
/*dmastat =
mfdcr(DCRN_DMASR);
mtdcr(DCRN_DMASR,((u32)DMA_CH2_ERR | (u32)DMA_CS2 |
(u32)DMA_TS2));
*/
mtdcr(DCRN_DMASR,0x22200120);
/*Configure
CIC reg for line mode DMA*/
#ifdef
WMODE
mtdcr(DCRN_CICCR,(mfdcr(DCRN_CICCR) |
0x00000400));
#else
mtdcr(DCRN_CICCR,(mfdcr(DCRN_CICCR) &
~0x00000400));
#endif
if(drive->media != ide_disk)
{
printk("ocp_ide_dma_begin : Invalid media
\n");
return;
}
if(ppc4xx_get_channel_config(IDE_DMACH,&dma_ch)
& DMA_CHANNEL_BUSY){
printk("DMA channel busy
\n");
return;
}
memset(rq->buffer,0,rq->current_nr_sectors*512);
if(reading){
dma_cache_inv((unsigned
long) rq->buffer, rq->current_nr_sectors * 512);
#ifdef
WMODE
mtdcr(DCRN_DMASA2,(u32)0x00000000);// set src address for
DMA channel
2
mtdcr(DCRN_DMADA2,(u32)virt_to_bus(rq->buffer));//set dst
address for DMA channel
2
mtdcr(DCRN_DCRXBCR,0x00000000);
control =
0xE600CB02;
#else
mtdcr(DCRN_DMASA2,(u32)0xfce00000);// set
src address for DMA channel
2
mtdcr(DCRN_DMADA2,(u32)virt_to_bus(rq->buffer));//set dst
address for DMA channel
2
mtdcr(DCRN_DCRXBCR,0x90000000);
control =
0xEE602b02;
#endif
}
else
{
dma_cache_wback_inv((unsigned long) rq->buffer,
rq->current_nr_sectors * 512);
#ifdef
WMODE
mtdcr(DCRN_DMASA2,(u32)0x00000000);// set dst address for
DMA channel
2
mtdcr(DCRN_DMADA2,(u32)virt_to_bus(rq->buffer));// set src
address for DMA channel
2
mtdcr(DCRN_DCRXBCR,0x00000000);
control =
0xC600CB02;
#else
mtdcr(DCRN_DMADA2,(u32)0xfce00000);// set
dst address for DMA channel
2
mtdcr(DCRN_DMASA2,(u32)virt_to_bus(rq->buffer));// set src
address for DMA channel
2
mtdcr(DCRN_DCRXBCR,0xB0000000);
control =
0xcd602b02;
#endif
}
#ifdef WMODE
length =
(rq->current_nr_sectors *512)/2;
#else
length =
(rq->current_nr_sectors
*512)/16;
#endif
mtdcr(DCRN_DMACT2,length);
/*control = mfdcr(DCRN_DMACR2);
control
|= DMA_CIE_ENABLE; Channel Interrupt Enable
*/
control
&= ~DMA_CIE_ENABLE;
mtdcr(DCRN_DMACR2,
control);
//ppc4xx_enable_dma_interrupt(IDE_DMACH);
printk("DMA
addr %x %x count %d dmastat
%x\n",rq->buffer,virt_to_bus(rq->buffer),rq->current_nr_sectors,dmastat);
/*
wait for dma to complete (channel 2 terminal count) */
for (i = 0; i
< 500000; i++) {
if(i%1000 == 0)
dmastat
= mfdcr(DCRN_DMASR);
if (dmastat &
DMA_CS2)
break;
}
printk("DMA complete
stat %x
%d\n",dmastat,i);
mtdcr(DCRN_DCRXBCR,0x00000000);
mtdcr(DCRN_DMACR2,
0x00000000);
drive->waiting_for_dma = 0;
//dmastat =
0;
}
static int ocp_ide_dma_end(ide_drive_t *drive){
unsigned int tmp =
mfdcr(DCRN_DMASR);
mtdcr (DCRN_UIC_SR(UIC0),(0x80000000ul >>
IDE_DMA_INT));
mtdcr(DCRN_DMASR,0x22200120);
dmastat =
mfdcr(DCRN_DMASR);
printk("got ocp_ide_dma_end %x
%x\n",dmastat,tmp);
drive->waiting_for_dma = 0;
/* disable
DMA */
//ppc4xx_disable_dma_interrupt(IDE_DMACH);
return 0;
}
static void
ocp_ide_setup_dma (ide_hwif_t * const
hwif)
{
printk("ocp_ide_setup_dma \n");
hwif->dma = IDE_DMACH;
#ifdef
WMODE
/*Word Mode psc(11-12)=00,pwc(13-18)=000110,
phc(19-21)=010, 22=1, 30=1 ---- 0xCB02*/
dma_ch.mode =TM_S_MM; /* xfer
from peripheral to mem */
dma_ch.td =
DMA_TD;
dma_ch.buffer_enable = FALSE;
dma_ch.tce_enable =
FALSE;
dma_ch.etd_output = FALSE;
dma_ch.pce =
FALSE;
dma_ch.pl = EXTERNAL_PERIPHERAL; /* no op
*/
dma_ch.pwidth = PW_16;
dma_ch.dai =
TRUE;
dma_ch.sai = FALSE;
dma_ch.psc =
0;
/* set the max setup cycles */
dma_ch.pwc =
6;
/* set the max wait cycles */
dma_ch.phc =
2;
/* set the max hold cycles */
dma_ch.cp =
PRIORITY_LOW;
dma_ch.int_enable = FALSE;
dma_ch.ch_enable =
FALSE; /* No chaining */
dma_ch.tcd_disable =
TRUE; /* No chaining */
#else
/*Line Mode
psc(11-12)=00,pwc(13-18)=000001, phc(19-21)=010, 22=1, 30=1 ----
0x2B02*/
dma_ch.mode =DMA_MODE_MM_DEVATSRC; /* xfer
from peripheral to mem */
dma_ch.td =
DMA_TD;
dma_ch.buffer_enable = FALSE;
dma_ch.tce_enable =
FALSE;
dma_ch.etd_output = FALSE;
dma_ch.pce =
FALSE;
dma_ch.pl = EXTERNAL_PERIPHERAL; /* no op
*/
dma_ch.pwidth = PW_64; /* Line mode on stbs
*/
dma_ch.dai = TRUE;
dma_ch.sai = FALSE;
dma_ch.psc
=
0;
/* set the max setup cycles */
dma_ch.pwc =
1;
/* set the max wait cycles */
dma_ch.phc =
2;
/* set the max hold cycles */
dma_ch.cp =
PRIORITY_LOW;
dma_ch.int_enable = FALSE;
dma_ch.ch_enable =
FALSE; /* No chaining */
dma_ch.tcd_disable =
TRUE; /* No chaining */
#endif
if (ppc4xx_init_dma_channel(IDE_DMACH,
&dma_ch) != DMA_STATUS_GOOD){
printk("ppc4xx_init_dma_channel
failed\n");
return
-EBUSY;
}
//ppc4xx_disable_dma_interrupt(IDE_DMACH);
/*init CIC control register to enable IDE
interface PIO mode*/
mtdcr(DCRN_CICCR,(mfdcr(DCRN_CICCR) &
0xffff7bff) | 0x00000003);
mtdcr(DCRN_DMACR2,
0);
ppc4xx_clr_dma_status(IDE_DMACH);
/* init CIC select2 reg
to connect external DMA port 3 to internal
* DMA channel
2
*/
mtdcr(DCRN_DMAS2,(mfdcr(DCRN_DMAS2)
& 0xfffffff0) | 0x00000002);
hwif->autodma =
1;hwif->udma_four=0;
hwif->drives[0].autotune =
hwif->drives[1].autotune =
IDE_TUNE_AUTO;
hwif->drives[0].autodma =
hwif->drives[1].autodma = hwif->autodma;
hwif->atapi_dma =
0;
hwif->ultra_mask = hwif->udma_four ? 0x1f :
0x07;
hwif->mwdma_mask = 0x07;
hwif->swdma_mask =
0x00;
/* set everything to something != NULL
*/
hwif->ide_dma_host_off =
&ocp_ide_dma_off_quietly;
hwif->ide_dma_host_on
= &ocp_ide_dma_on;
hwif->ide_dma_check =
&ocp_ide_dma_check;
hwif->ide_dma_off_quietly =
&ocp_ide_dma_off_quietly;
hwif->ide_dma_on
= &ocp_ide_dma_on;
hwif->dma_setup =
&ocp_ide_dma_setup;
hwif->dma_exec_cmd =
&ocp_dma_exec_cmd;
hwif->dma_start
= &ocp_ide_dma_begin;
hwif->ide_dma_end
= &ocp_ide_dma_end;
hwif->ide_dma_test_irq =
&ocp_ide_dma_test_irq;
hwif->ide_dma_lostirq =
&ocp_ide_dma_lostirq;
hwif->ide_dma_timeout =
&ocp_ide_dma_timeout;
}
static int
__init
stb025xx_ide_probe (struct ocp_device * const
ocp)
{
int
err;
unsigned
int
uicdcr;
volatile unsigned long ide_regs;
unsigned
long
flags,ioaddr;
ide_hwif_t
* const hwif = &ide_hwifs[0];
unsigned
char *
ip;
int
i;
printk ("IBM STB025xx OCP IDE driver version %s
%x \n", IDEVR,ocp->def->paddr);
if
(!request_region(REDWOOD_IDE_CMD, 0x10, "IDE"))
return
-EBUSY;
if (!request_region(REDWOOD_IDE_CTRL, 2, "IDE"))
{
release_region(REDWOOD_IDE_CMD, 0x10);
return
-EBUSY;
}
ide_regs = ioaddr = (unsigned long)
ioremap(REDWOOD_IDE_CMD, 0x10);
for (i = IDE_DATA_OFFSET; i <=
IDE_STATUS_OFFSET; i++) {
hwif->io_ports[i] =
ioaddr;
ioaddr +=
2;
}
hwif->io_ports[IDE_CONTROL_OFFSET]
=
(unsigned long) ioremap(REDWOOD_IDE_CTRL,
2);
ocp_force_power_on (ocp);
/*
initialize */
hwif->gendev.parent =
&ocp->dev;
ocp_set_drvdata (ocp, hwif);
/* setup MMIO ops */
default_hwif_mmiops
(hwif);
/* tell common code _not_ to mess with resources
*/
hwif->mmio = 2;
ide_set_hwifdata (hwif, (void *)
ide_regs);
hwif->chipset =
ide_generic;
hwif->irq =
IDE0_IRQ;
hwif->noprobe =
0;
hwif->hold = 1;
hwif->udma_four =
0;
hwif->tuneproc =
&ocp_ide_tune_drive;
hwif->speedproc =
&ocp_ide_tune_chipset;
hwif->drives[0].io_32bit =
hwif->drives[1].io_32bit = 0;
hwif->drives[0].unmask
= hwif->drives[1].unmask = 1;
pio_mode[0] = pio_mode[1]
= -1;
ibm25xx_ide_spinup(0);
ocp_ide_setup_dma
(hwif);
probe_hwif_init (hwif);
create_proc_ide_interfaces
();
printk("IDE probe finished \n");
return 0;
}
static
int ocp_ide_dma_end(ide_drive_t *drive){
unsigned int tmp =
mfdcr(DCRN_DMASR);
mtdcr (DCRN_UIC_SR(UIC0),(0x80000000ul >>
IDE_DMA_INT));
mtdcr(DCRN_DMASR,0x22200120);
dmastat =
mfdcr(DCRN_DMASR);
printk("got ocp_ide_dma_end %x
%x\n",dmastat,tmp);
drive->waiting_for_dma = 0;
/* disable
DMA */
//ppc4xx_disable_dma_interrupt(IDE_DMACH);
return 0;
}
static int
ocp_ide_dma_test_irq(ide_drive_t *drive){
printk("got
ocp_ide_dma_test_irq\n");
return 1; /* returns 1 if dma irq
issued, 0 otherwise */
}
static int ocp_ide_dma_verbose(ide_drive_t
*drive){
printk("got
ocp_ide_dma_verbose\n");
return 1;
}
static int
ocp_ide_dma_lostirq(ide_drive_t *drive){
printk("got
ocp_ide_dma_lostirq\n");
return 1;
}
static int
ocp_ide_dma_timeout(ide_drive_t *drive){
printk("got
ocp_ide_dma_timeout\n");
return 1;
}
static
void
ocp_dma_exec_cmd (ide_drive_t * const drive, u8 command){
ide_hwif_t
*hwif = HWIF(drive);
//hwif->OUTBSYNC(drive,command,
IDE_COMMAND_REG);
//printk("ide_dma_exec_cmd
%x\n",command);
ide_execute_command (drive, command,&ide_dma_intr,
2*WAIT_CMD, NULL);
}
static int ocp_ide_dma_setup(ide_drive_t * const
drive){
ide_hwif_t * const hwif = HWIF(drive);
struct
request * const rq = HWGROUP(drive)->rq;
printk("got ocp_ide_dma_setup
\n");
/*if(rq->current_nr_sectors <
2){
printk("request for less no of sectors
%d\n",rq->current_nr_sectors);
ide_map_sg(drive,rq);drive->waiting_for_dma=0;
return 1;
}*/
drive->waiting_for_dma =
1;
return 0;
}