18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * I/O Processor (IOP) defines and structures, mostly snagged from A/UX 48c2ecf20Sopenharmony_ci * header files. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * The original header from which this was taken is copyrighted. I've done some 78c2ecf20Sopenharmony_ci * rewriting (in fact my changes make this a bit more readable, IMHO) but some 88c2ecf20Sopenharmony_ci * more should be done. 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci/* 128c2ecf20Sopenharmony_ci * This is the base address of the IOPs. Use this as the address of 138c2ecf20Sopenharmony_ci * a "struct iop" (see below) to see where the actual registers fall. 148c2ecf20Sopenharmony_ci */ 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#define SCC_IOP_BASE_IIFX (0x50F04000) 178c2ecf20Sopenharmony_ci#define ISM_IOP_BASE_IIFX (0x50F12000) 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define SCC_IOP_BASE_QUADRA (0x50F0C000) 208c2ecf20Sopenharmony_ci#define ISM_IOP_BASE_QUADRA (0x50F1E000) 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci/* IOP status/control register bits: */ 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#define IOP_BYPASS 0x01 /* bypass-mode hardware access */ 258c2ecf20Sopenharmony_ci#define IOP_AUTOINC 0x02 /* allow autoincrement of ramhi/lo */ 268c2ecf20Sopenharmony_ci#define IOP_RUN 0x04 /* set to 0 to reset IOP chip */ 278c2ecf20Sopenharmony_ci#define IOP_IRQ 0x08 /* generate IRQ to IOP if 1 */ 288c2ecf20Sopenharmony_ci#define IOP_INT0 0x10 /* intr priority from IOP to host */ 298c2ecf20Sopenharmony_ci#define IOP_INT1 0x20 /* intr priority from IOP to host */ 308c2ecf20Sopenharmony_ci#define IOP_HWINT 0x40 /* IRQ from hardware; bypass mode only */ 318c2ecf20Sopenharmony_ci#define IOP_DMAINACTIVE 0x80 /* no DMA request active; bypass mode only */ 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#define NUM_IOPS 2 348c2ecf20Sopenharmony_ci#define NUM_IOP_CHAN 7 358c2ecf20Sopenharmony_ci#define NUM_IOP_MSGS NUM_IOP_CHAN*8 368c2ecf20Sopenharmony_ci#define IOP_MSG_LEN 32 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci/* IOP reference numbers, used by the globally-visible iop_xxx functions */ 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci#define IOP_NUM_SCC 0 418c2ecf20Sopenharmony_ci#define IOP_NUM_ISM 1 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/* IOP channel states */ 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci#define IOP_MSG_IDLE 0 /* idle */ 468c2ecf20Sopenharmony_ci#define IOP_MSG_NEW 1 /* new message sent */ 478c2ecf20Sopenharmony_ci#define IOP_MSG_RCVD 2 /* message received; processing */ 488c2ecf20Sopenharmony_ci#define IOP_MSG_COMPLETE 3 /* message processing complete */ 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci/* IOP message status codes */ 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci#define IOP_MSGSTATUS_UNUSED 0 /* Unused message structure */ 538c2ecf20Sopenharmony_ci#define IOP_MSGSTATUS_WAITING 1 /* waiting for channel */ 548c2ecf20Sopenharmony_ci#define IOP_MSGSTATUS_SENT 2 /* message sent, awaiting reply */ 558c2ecf20Sopenharmony_ci#define IOP_MSGSTATUS_COMPLETE 3 /* message complete and reply rcvd */ 568c2ecf20Sopenharmony_ci#define IOP_MSGSTATUS_UNSOL 6 /* message is unsolicited */ 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci/* IOP memory addresses of the members of the mac_iop_kernel structure. */ 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci#define IOP_ADDR_MAX_SEND_CHAN 0x0200 618c2ecf20Sopenharmony_ci#define IOP_ADDR_SEND_STATE 0x0201 628c2ecf20Sopenharmony_ci#define IOP_ADDR_PATCH_CTRL 0x021F 638c2ecf20Sopenharmony_ci#define IOP_ADDR_SEND_MSG 0x0220 648c2ecf20Sopenharmony_ci#define IOP_ADDR_MAX_RECV_CHAN 0x0300 658c2ecf20Sopenharmony_ci#define IOP_ADDR_RECV_STATE 0x0301 668c2ecf20Sopenharmony_ci#define IOP_ADDR_ALIVE 0x031F 678c2ecf20Sopenharmony_ci#define IOP_ADDR_RECV_MSG 0x0320 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci#ifndef __ASSEMBLY__ 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci/* 728c2ecf20Sopenharmony_ci * IOP Control registers, staggered because in usual Apple style they were 738c2ecf20Sopenharmony_ci * too lazy to decode the A0 bit. This structure is assumed to begin at 748c2ecf20Sopenharmony_ci * one of the xxx_IOP_BASE addresses given above. 758c2ecf20Sopenharmony_ci */ 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistruct mac_iop { 788c2ecf20Sopenharmony_ci __u8 ram_addr_hi; /* shared RAM address hi byte */ 798c2ecf20Sopenharmony_ci __u8 pad0; 808c2ecf20Sopenharmony_ci __u8 ram_addr_lo; /* shared RAM address lo byte */ 818c2ecf20Sopenharmony_ci __u8 pad1; 828c2ecf20Sopenharmony_ci __u8 status_ctrl; /* status/control register */ 838c2ecf20Sopenharmony_ci __u8 pad2[3]; 848c2ecf20Sopenharmony_ci __u8 ram_data; /* RAM data byte at ramhi/lo */ 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci __u8 pad3[23]; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci /* Bypass-mode hardware access registers */ 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci union { 918c2ecf20Sopenharmony_ci struct { /* SCC registers */ 928c2ecf20Sopenharmony_ci __u8 sccb_cmd; /* SCC B command reg */ 938c2ecf20Sopenharmony_ci __u8 pad4; 948c2ecf20Sopenharmony_ci __u8 scca_cmd; /* SCC A command reg */ 958c2ecf20Sopenharmony_ci __u8 pad5; 968c2ecf20Sopenharmony_ci __u8 sccb_data; /* SCC B data */ 978c2ecf20Sopenharmony_ci __u8 pad6; 988c2ecf20Sopenharmony_ci __u8 scca_data; /* SCC A data */ 998c2ecf20Sopenharmony_ci } scc_regs; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci struct { /* ISM registers */ 1028c2ecf20Sopenharmony_ci __u8 wdata; /* write a data byte */ 1038c2ecf20Sopenharmony_ci __u8 pad7; 1048c2ecf20Sopenharmony_ci __u8 wmark; /* write a mark byte */ 1058c2ecf20Sopenharmony_ci __u8 pad8; 1068c2ecf20Sopenharmony_ci __u8 wcrc; /* write 2-byte crc to disk */ 1078c2ecf20Sopenharmony_ci __u8 pad9; 1088c2ecf20Sopenharmony_ci __u8 wparams; /* write the param regs */ 1098c2ecf20Sopenharmony_ci __u8 pad10; 1108c2ecf20Sopenharmony_ci __u8 wphase; /* write the phase states & dirs */ 1118c2ecf20Sopenharmony_ci __u8 pad11; 1128c2ecf20Sopenharmony_ci __u8 wsetup; /* write the setup register */ 1138c2ecf20Sopenharmony_ci __u8 pad12; 1148c2ecf20Sopenharmony_ci __u8 wzeroes; /* mode reg: 1's clr bits, 0's are x */ 1158c2ecf20Sopenharmony_ci __u8 pad13; 1168c2ecf20Sopenharmony_ci __u8 wones; /* mode reg: 1's set bits, 0's are x */ 1178c2ecf20Sopenharmony_ci __u8 pad14; 1188c2ecf20Sopenharmony_ci __u8 rdata; /* read a data byte */ 1198c2ecf20Sopenharmony_ci __u8 pad15; 1208c2ecf20Sopenharmony_ci __u8 rmark; /* read a mark byte */ 1218c2ecf20Sopenharmony_ci __u8 pad16; 1228c2ecf20Sopenharmony_ci __u8 rerror; /* read the error register */ 1238c2ecf20Sopenharmony_ci __u8 pad17; 1248c2ecf20Sopenharmony_ci __u8 rparams; /* read the param regs */ 1258c2ecf20Sopenharmony_ci __u8 pad18; 1268c2ecf20Sopenharmony_ci __u8 rphase; /* read the phase states & dirs */ 1278c2ecf20Sopenharmony_ci __u8 pad19; 1288c2ecf20Sopenharmony_ci __u8 rsetup; /* read the setup register */ 1298c2ecf20Sopenharmony_ci __u8 pad20; 1308c2ecf20Sopenharmony_ci __u8 rmode; /* read the mode register */ 1318c2ecf20Sopenharmony_ci __u8 pad21; 1328c2ecf20Sopenharmony_ci __u8 rhandshake; /* read the handshake register */ 1338c2ecf20Sopenharmony_ci } ism_regs; 1348c2ecf20Sopenharmony_ci } b; 1358c2ecf20Sopenharmony_ci}; 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci/* This structure is used to track IOP messages in the Linux kernel */ 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_cistruct iop_msg { 1408c2ecf20Sopenharmony_ci struct iop_msg *next; /* next message in queue or NULL */ 1418c2ecf20Sopenharmony_ci uint iop_num; /* IOP number */ 1428c2ecf20Sopenharmony_ci uint channel; /* channel number */ 1438c2ecf20Sopenharmony_ci void *caller_priv; /* caller private data */ 1448c2ecf20Sopenharmony_ci int status; /* status of this message */ 1458c2ecf20Sopenharmony_ci __u8 message[IOP_MSG_LEN]; /* the message being sent/received */ 1468c2ecf20Sopenharmony_ci __u8 reply[IOP_MSG_LEN]; /* the reply to the message */ 1478c2ecf20Sopenharmony_ci void (*handler)(struct iop_msg *); 1488c2ecf20Sopenharmony_ci /* function to call when reply recvd */ 1498c2ecf20Sopenharmony_ci}; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ciextern int iop_scc_present,iop_ism_present; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ciextern int iop_listen(uint, uint, 1548c2ecf20Sopenharmony_ci void (*handler)(struct iop_msg *), 1558c2ecf20Sopenharmony_ci const char *); 1568c2ecf20Sopenharmony_ciextern int iop_send_message(uint, uint, void *, uint, __u8 *, 1578c2ecf20Sopenharmony_ci void (*)(struct iop_msg *)); 1588c2ecf20Sopenharmony_ciextern void iop_complete_message(struct iop_msg *); 1598c2ecf20Sopenharmony_ciextern void iop_upload_code(uint, __u8 *, uint, __u16); 1608c2ecf20Sopenharmony_ciextern void iop_download_code(uint, __u8 *, uint, __u16); 1618c2ecf20Sopenharmony_ciextern __u8 *iop_compare_code(uint, __u8 *, uint, __u16); 1628c2ecf20Sopenharmony_ciextern void iop_ism_irq_poll(uint); 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ciextern void iop_register_interrupts(void); 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci#endif /* __ASSEMBLY__ */ 167