2 Copyright © 2004-2011, The AROS Development Team. All rights reserved.
5 Desc: PCI bus driver for ata.device
11 #include <aros/asmcall.h>
12 #include <aros/debug.h>
13 #include <aros/symbolsets.h>
15 #include <asm/amcc440.h>
16 #include <exec/lists.h>
18 #include <resources/processor.h>
19 #include <proto/exec.h>
20 #include <proto/oop.h>
21 #include <proto/processor.h>
29 struct ataBase
*ATABase
;
31 OOP_AttrBase HiddPCIDeviceAttrBase
;
32 OOP_MethodID HiddPCIDriverMethodBase
;
35 static VOID
ata460_out(UBYTE val
, UWORD offset
, IPTR port
, APTR data
)
38 outb(val
, (uint8_t *)(port
+ offset
+ data
));
41 static UBYTE
ata460_in(UWORD offset
, IPTR port
, APTR data
)
44 return inb((uint8_t *)(port
+ offset
+ data
));
47 static VOID
ata460_outl(ULONG val
, UWORD offset
, IPTR port
, APTR data
)
50 outl(val
, (uint32_t *)(port
+ offset
+ data
));
53 static VOID
ata460_insw(APTR address
, UWORD port
, ULONG count
, APTR data
)
55 UWORD
*addr
= address
;
56 UWORD
*p
= (UWORD
*)(port
+ data
);
65 static VOID
ata460_insl(APTR address
, UWORD port
, ULONG count
, APTR data
)
67 ata460_insw(address
, port
, count
, data
);
70 static VOID
ata460_outsw(APTR address
, UWORD port
, ULONG count
, APTR data
)
72 UWORD
*addr
= address
;
73 UWORD
*p
= (UWORD
*)(port
+ data
);
82 static VOID
ata460_outsl(APTR address
, UWORD port
, ULONG count
, APTR data
)
84 ata460_outsw(address
, port
, count
, data
);
87 static AROS_INTH1(ata460_Interrupt
, struct ata_Bus
*, bus
)
91 * Our interrupt handler should call this function.
100 /* Actually a quick hack. Proper implementation really needs HIDDizing this code. */
101 static BOOL
ata460_CreateInterrupt(struct ata_Bus
*bus
)
103 bus
->ab_IntHandler
.is_Node
.ln_Type
= NT_INTERRUPT
;
104 bus
->ab_IntHandler
.is_Node
.ln_Name
= "Sam460ex SATA/IDE";
105 bus
->ab_IntHandler
.is_Node
.ln_Pri
= 0;
106 bus
->ab_IntHandler
.is_Code
= (VOID_FUNC
)ata460_Interrupt
;
107 bus
->ab_IntHandler
.is_Data
= bus
;
109 AddIntServer(INTB_KERNEL
+ bus
->ab_IRQ
, &bus
->ab_IntHandler
);
114 static const struct ata_BusDriver ppc460_driver
=
123 ata460_CreateInterrupt
126 static inline ULONG
GetPVR(void)
128 struct Library
*ProcessorBase
= OpenResource(PROCESSORNAME
);
132 struct TagItem tags
[] = {
133 { GCIT_Model
, (IPTR
)&pvr
},
142 #define SDR0_PE0_PHY_CTL_RST 0x30f
145 /* Requires supervisor */
146 ULONG
getSDR0_PE0_PHY_CTL_RST(VOID
)
148 wrdcr(SDR0_CFGADDR
, SDR0_PE0_PHY_CTL_RST
);
149 return rddcr(SDR0_CFGDATA
);
152 static int ata460_Scan(struct ataBase
*base
)
154 if (GetPVR() == PVR_PPC460EX_B
) {
156 ULONG pe0_mode
= Supervisor(getSDR0_PE0_PHY_CTL_RST
) & 0x3;
158 D(bug("[ATA] Sam460EX PE0 mode = 0x%08x\n", pe0_mode
));
160 ULONG scr0
= inl_le(SATA0_SCR0
);
161 if ((scr0
& 0xf) == 0x3) {
162 D(bug("[ATA] Enabling Sam460EX SATA in ATA PIO mode\n"));
163 ata_RegisterBus(0, 0x18, INTR_UIC3_SATA
, 0,
164 ARBF_EarlyInterrupt
| ARBF_80Wire
, &ppc460_driver
,
165 (APTR
)SATA0_CDR0
, base
);
174 * ata.device main code has two init routines with 0 and 127 priorities.
175 * All bus scanners must run between them.
177 ADD2INITLIB(ata460_Scan
, 40)