149148020SSam Ravnborg /* 249148020SSam Ravnborg * Apple Peripheral System Controller (PSC) 349148020SSam Ravnborg * 449148020SSam Ravnborg * The PSC is used on the AV Macs to control IO functions not handled 549148020SSam Ravnborg * by the VIAs (Ethernet, DSP, SCC, Sound). This includes nine DMA 649148020SSam Ravnborg * channels. 749148020SSam Ravnborg * 849148020SSam Ravnborg * The first seven DMA channels appear to be "one-shot" and are actually 949148020SSam Ravnborg * sets of two channels; one member is active while the other is being 1049148020SSam Ravnborg * configured, and then you flip the active member and start all over again. 1149148020SSam Ravnborg * The one-shot channels are grouped together and are: 1249148020SSam Ravnborg * 1349148020SSam Ravnborg * 1. SCSI 1449148020SSam Ravnborg * 2. Ethernet Read 1549148020SSam Ravnborg * 3. Ethernet Write 1649148020SSam Ravnborg * 4. Floppy Disk Controller 1749148020SSam Ravnborg * 5. SCC Channel A Receive 1849148020SSam Ravnborg * 6. SCC Channel B Receive 1949148020SSam Ravnborg * 7. SCC Channel A Transmit 2049148020SSam Ravnborg * 2149148020SSam Ravnborg * The remaining two channels are handled somewhat differently. They appear 2249148020SSam Ravnborg * to be closely tied and share one set of registers. They also seem to run 2349148020SSam Ravnborg * continuously, although how you keep the buffer filled in this scenario is 2449148020SSam Ravnborg * not understood as there seems to be only one input and one output buffer 2549148020SSam Ravnborg * pointer. 2649148020SSam Ravnborg * 2749148020SSam Ravnborg * Much of this was extrapolated from what was known about the Ethernet 2849148020SSam Ravnborg * registers and subsequently confirmed using MacsBug (ie by pinging the 2949148020SSam Ravnborg * machine with easy-to-find patterns and looking for them in the DMA 3049148020SSam Ravnborg * buffers, or by sending a file over the serial ports and finding the 3149148020SSam Ravnborg * file in the buffers.) 3249148020SSam Ravnborg * 3349148020SSam Ravnborg * 1999-05-25 (jmt) 3449148020SSam Ravnborg */ 3549148020SSam Ravnborg 3649148020SSam Ravnborg #define PSC_BASE (0x50F31000) 3749148020SSam Ravnborg 3849148020SSam Ravnborg /* 3949148020SSam Ravnborg * The IER/IFR registers work like the VIA, except that it has 4 4049148020SSam Ravnborg * of them each on different interrupt levels, and each register 4149148020SSam Ravnborg * set only seems to handle four interrupts instead of seven. 4249148020SSam Ravnborg * 4349148020SSam Ravnborg * To access a particular set of registers, add 0xn0 to the base 4449148020SSam Ravnborg * where n = 3,4,5 or 6. 4549148020SSam Ravnborg */ 4649148020SSam Ravnborg 4749148020SSam Ravnborg #define pIFRbase 0x100 4849148020SSam Ravnborg #define pIERbase 0x104 4949148020SSam Ravnborg 5049148020SSam Ravnborg /* 5149148020SSam Ravnborg * One-shot DMA control registers 5249148020SSam Ravnborg */ 5349148020SSam Ravnborg 5449148020SSam Ravnborg #define PSC_MYSTERY 0x804 5549148020SSam Ravnborg 5649148020SSam Ravnborg #define PSC_CTL_BASE 0xC00 5749148020SSam Ravnborg 5849148020SSam Ravnborg #define PSC_SCSI_CTL 0xC00 5949148020SSam Ravnborg #define PSC_ENETRD_CTL 0xC10 6049148020SSam Ravnborg #define PSC_ENETWR_CTL 0xC20 6149148020SSam Ravnborg #define PSC_FDC_CTL 0xC30 6249148020SSam Ravnborg #define PSC_SCCA_CTL 0xC40 6349148020SSam Ravnborg #define PSC_SCCB_CTL 0xC50 6449148020SSam Ravnborg #define PSC_SCCATX_CTL 0xC60 6549148020SSam Ravnborg 6649148020SSam Ravnborg /* 6749148020SSam Ravnborg * DMA channels. Add +0x10 for the second channel in the set. 6849148020SSam Ravnborg * You're supposed to use one channel while the other runs and 6949148020SSam Ravnborg * then flip channels and do the whole thing again. 7049148020SSam Ravnborg */ 7149148020SSam Ravnborg 7249148020SSam Ravnborg #define PSC_ADDR_BASE 0x1000 7349148020SSam Ravnborg #define PSC_LEN_BASE 0x1004 7449148020SSam Ravnborg #define PSC_CMD_BASE 0x1008 7549148020SSam Ravnborg 7649148020SSam Ravnborg #define PSC_SET0 0x00 7749148020SSam Ravnborg #define PSC_SET1 0x10 7849148020SSam Ravnborg 7949148020SSam Ravnborg #define PSC_SCSI_ADDR 0x1000 /* confirmed */ 8049148020SSam Ravnborg #define PSC_SCSI_LEN 0x1004 /* confirmed */ 8149148020SSam Ravnborg #define PSC_SCSI_CMD 0x1008 /* confirmed */ 8249148020SSam Ravnborg #define PSC_ENETRD_ADDR 0x1020 /* confirmed */ 8349148020SSam Ravnborg #define PSC_ENETRD_LEN 0x1024 /* confirmed */ 8449148020SSam Ravnborg #define PSC_ENETRD_CMD 0x1028 /* confirmed */ 8549148020SSam Ravnborg #define PSC_ENETWR_ADDR 0x1040 /* confirmed */ 8649148020SSam Ravnborg #define PSC_ENETWR_LEN 0x1044 /* confirmed */ 8749148020SSam Ravnborg #define PSC_ENETWR_CMD 0x1048 /* confirmed */ 8849148020SSam Ravnborg #define PSC_FDC_ADDR 0x1060 /* strongly suspected */ 8949148020SSam Ravnborg #define PSC_FDC_LEN 0x1064 /* strongly suspected */ 9049148020SSam Ravnborg #define PSC_FDC_CMD 0x1068 /* strongly suspected */ 9149148020SSam Ravnborg #define PSC_SCCA_ADDR 0x1080 /* confirmed */ 9249148020SSam Ravnborg #define PSC_SCCA_LEN 0x1084 /* confirmed */ 9349148020SSam Ravnborg #define PSC_SCCA_CMD 0x1088 /* confirmed */ 9449148020SSam Ravnborg #define PSC_SCCB_ADDR 0x10A0 /* confirmed */ 9549148020SSam Ravnborg #define PSC_SCCB_LEN 0x10A4 /* confirmed */ 9649148020SSam Ravnborg #define PSC_SCCB_CMD 0x10A8 /* confirmed */ 9749148020SSam Ravnborg #define PSC_SCCATX_ADDR 0x10C0 /* confirmed */ 9849148020SSam Ravnborg #define PSC_SCCATX_LEN 0x10C4 /* confirmed */ 9949148020SSam Ravnborg #define PSC_SCCATX_CMD 0x10C8 /* confirmed */ 10049148020SSam Ravnborg 10149148020SSam Ravnborg /* 10249148020SSam Ravnborg * Free-running DMA registers. The only part known for sure are the bits in 10349148020SSam Ravnborg * the control register, the buffer addresses and the buffer length. Everything 10449148020SSam Ravnborg * else is anybody's guess. 10549148020SSam Ravnborg * 10649148020SSam Ravnborg * These registers seem to be mirrored every thirty-two bytes up until offset 10749148020SSam Ravnborg * 0x300. It's safe to assume then that a new set of registers starts there. 10849148020SSam Ravnborg */ 10949148020SSam Ravnborg 11049148020SSam Ravnborg #define PSC_SND_CTL 0x200 /* 11149148020SSam Ravnborg * [ 16-bit ] 11249148020SSam Ravnborg * Sound (Singer?) control register. 11349148020SSam Ravnborg * 11449148020SSam Ravnborg * bit 0 : ???? 11549148020SSam Ravnborg * bit 1 : ???? 11649148020SSam Ravnborg * bit 2 : Set to one to enable sound 11749148020SSam Ravnborg * output. Possibly a mute flag. 11849148020SSam Ravnborg * bit 3 : ???? 11949148020SSam Ravnborg * bit 4 : ???? 12049148020SSam Ravnborg * bit 5 : ???? 12149148020SSam Ravnborg * bit 6 : Set to one to enable pass-thru 12249148020SSam Ravnborg * audio. In this mode the audio data 12349148020SSam Ravnborg * seems to appear in both the input 12449148020SSam Ravnborg * buffer and the output buffer. 12549148020SSam Ravnborg * bit 7 : Set to one to activate the 12649148020SSam Ravnborg * sound input DMA or zero to 12749148020SSam Ravnborg * disable it. 12849148020SSam Ravnborg * bit 8 : Set to one to activate the 12949148020SSam Ravnborg * sound output DMA or zero to 13049148020SSam Ravnborg * disable it. 13149148020SSam Ravnborg * bit 9 : \ 13249148020SSam Ravnborg * bit 11 : | 13349148020SSam Ravnborg * These two bits control the sample 13449148020SSam Ravnborg * rate. Usually set to binary 10 and 13549148020SSam Ravnborg * MacOS 8.0 says I'm at 48 KHz. Using 13649148020SSam Ravnborg * a binary value of 01 makes things 13749148020SSam Ravnborg * sound about 1/2 speed (24 KHz?) and 13849148020SSam Ravnborg * binary 00 is slower still (22 KHz?) 13949148020SSam Ravnborg * 14049148020SSam Ravnborg * Setting this to 0x0000 is a good way to 14149148020SSam Ravnborg * kill all DMA at boot time so that the 14249148020SSam Ravnborg * PSC won't overwrite the kernel image 14349148020SSam Ravnborg * with sound data. 14449148020SSam Ravnborg */ 14549148020SSam Ravnborg 14649148020SSam Ravnborg /* 14749148020SSam Ravnborg * 0x0202 - 0x0203 is unused. Writing there 14849148020SSam Ravnborg * seems to clobber the control register. 14949148020SSam Ravnborg */ 15049148020SSam Ravnborg 15149148020SSam Ravnborg #define PSC_SND_SOURCE 0x204 /* 15249148020SSam Ravnborg * [ 32-bit ] 15349148020SSam Ravnborg * Controls input source and volume: 15449148020SSam Ravnborg * 15549148020SSam Ravnborg * bits 12-15 : input source volume, 0 - F 15649148020SSam Ravnborg * bits 16-19 : unknown, always 0x5 15749148020SSam Ravnborg * bits 20-23 : input source selection: 15849148020SSam Ravnborg * 0x3 = CD Audio 15949148020SSam Ravnborg * 0x4 = External Audio 16049148020SSam Ravnborg * 16149148020SSam Ravnborg * The volume is definitely not the general 16249148020SSam Ravnborg * output volume as it doesn't affect the 16349148020SSam Ravnborg * alert sound volume. 16449148020SSam Ravnborg */ 16549148020SSam Ravnborg #define PSC_SND_STATUS1 0x208 /* 16649148020SSam Ravnborg * [ 32-bit ] 16749148020SSam Ravnborg * Appears to be a read-only status register. 16849148020SSam Ravnborg * The usual value is 0x00400002. 16949148020SSam Ravnborg */ 17049148020SSam Ravnborg #define PSC_SND_HUH3 0x20C /* 17149148020SSam Ravnborg * [ 16-bit ] 17249148020SSam Ravnborg * Unknown 16-bit value, always 0x0000. 17349148020SSam Ravnborg */ 17449148020SSam Ravnborg #define PSC_SND_BITS2GO 0x20E /* 17549148020SSam Ravnborg * [ 16-bit ] 17649148020SSam Ravnborg * Counts down to zero from some constant 17749148020SSam Ravnborg * value. The value appears to be the 17849148020SSam Ravnborg * number of _bits_ remaining before the 17949148020SSam Ravnborg * buffer is full, which would make sense 18049148020SSam Ravnborg * since Apple's docs say the sound DMA 18149148020SSam Ravnborg * channels are 1 bit wide. 18249148020SSam Ravnborg */ 18349148020SSam Ravnborg #define PSC_SND_INADDR 0x210 /* 18449148020SSam Ravnborg * [ 32-bit ] 18549148020SSam Ravnborg * Address of the sound input DMA buffer 18649148020SSam Ravnborg */ 18749148020SSam Ravnborg #define PSC_SND_OUTADDR 0x214 /* 18849148020SSam Ravnborg * [ 32-bit ] 18949148020SSam Ravnborg * Address of the sound output DMA buffer 19049148020SSam Ravnborg */ 19149148020SSam Ravnborg #define PSC_SND_LEN 0x218 /* 19249148020SSam Ravnborg * [ 16-bit ] 19349148020SSam Ravnborg * Length of both buffers in eight-byte units. 19449148020SSam Ravnborg */ 19549148020SSam Ravnborg #define PSC_SND_HUH4 0x21A /* 19649148020SSam Ravnborg * [ 16-bit ] 19749148020SSam Ravnborg * Unknown, always 0x0000. 19849148020SSam Ravnborg */ 19949148020SSam Ravnborg #define PSC_SND_STATUS2 0x21C /* 20049148020SSam Ravnborg * [ 16-bit ] 20149148020SSam Ravnborg * Appears to e a read-only status register. 20249148020SSam Ravnborg * The usual value is 0x0200. 20349148020SSam Ravnborg */ 20449148020SSam Ravnborg #define PSC_SND_HUH5 0x21E /* 20549148020SSam Ravnborg * [ 16-bit ] 20649148020SSam Ravnborg * Unknown, always 0x0000. 20749148020SSam Ravnborg */ 20849148020SSam Ravnborg 20949148020SSam Ravnborg #ifndef __ASSEMBLY__ 21049148020SSam Ravnborg 21149148020SSam Ravnborg extern volatile __u8 *psc; 21249148020SSam Ravnborg extern int psc_present; 21349148020SSam Ravnborg 214ed04c97dSFinn Thain extern void psc_register_interrupts(void); 215ed04c97dSFinn Thain extern void psc_irq_enable(int); 216ed04c97dSFinn Thain extern void psc_irq_disable(int); 217ed04c97dSFinn Thain 21849148020SSam Ravnborg /* 21949148020SSam Ravnborg * Access functions 22049148020SSam Ravnborg */ 22149148020SSam Ravnborg 22249148020SSam Ravnborg static inline void psc_write_byte(int offset, __u8 data) 22349148020SSam Ravnborg { 22449148020SSam Ravnborg *((volatile __u8 *)(psc + offset)) = data; 22549148020SSam Ravnborg } 22649148020SSam Ravnborg 22749148020SSam Ravnborg static inline void psc_write_word(int offset, __u16 data) 22849148020SSam Ravnborg { 22949148020SSam Ravnborg *((volatile __u16 *)(psc + offset)) = data; 23049148020SSam Ravnborg } 23149148020SSam Ravnborg 23249148020SSam Ravnborg static inline void psc_write_long(int offset, __u32 data) 23349148020SSam Ravnborg { 23449148020SSam Ravnborg *((volatile __u32 *)(psc + offset)) = data; 23549148020SSam Ravnborg } 23649148020SSam Ravnborg 23749148020SSam Ravnborg static inline u8 psc_read_byte(int offset) 23849148020SSam Ravnborg { 23949148020SSam Ravnborg return *((volatile __u8 *)(psc + offset)); 24049148020SSam Ravnborg } 24149148020SSam Ravnborg 24249148020SSam Ravnborg static inline u16 psc_read_word(int offset) 24349148020SSam Ravnborg { 24449148020SSam Ravnborg return *((volatile __u16 *)(psc + offset)); 24549148020SSam Ravnborg } 24649148020SSam Ravnborg 24749148020SSam Ravnborg static inline u32 psc_read_long(int offset) 24849148020SSam Ravnborg { 24949148020SSam Ravnborg return *((volatile __u32 *)(psc + offset)); 25049148020SSam Ravnborg } 25149148020SSam Ravnborg 25249148020SSam Ravnborg #endif /* __ASSEMBLY__ */ 253