| #include "memio.h" |
| #include "articiaS.h" |
| |
| #ifndef FALSE |
| #define FALSE 0 |
| #endif |
| |
| #ifndef TRUE |
| #define TRUE 1 |
| #endif |
| |
| |
| void sm_write_mode(void) |
| { |
| out_byte(0xA539, 0x00); |
| out_byte(0xA53A, 0x03); |
| } |
| |
| void sm_read_mode(void) |
| { |
| out_byte(0xA53A, 0x02); |
| out_byte(0xA539, 0x02); |
| } |
| |
| void sm_write_byte(uint8 writeme) |
| { |
| int i; |
| int level; |
| |
| out_byte(0xA539, 0x00); |
| |
| level = 0; |
| |
| for (i=0; i<8; i++) |
| { |
| if ((writeme & 0x80) == (level<<7)) |
| { |
| /* Bit did not change, rewrite strobe */ |
| out_byte(0xA539, level | 0x02); |
| out_byte(0xA539, level); |
| } |
| else |
| { |
| /* Bit changed, set bit, then strobe */ |
| level = (writeme & 0x80) >> 7; |
| out_byte(0xA539, level); |
| out_byte(0xA539, level | 0x02); |
| out_byte(0xA539, level); |
| } |
| writeme <<= 1; |
| } |
| out_byte(0xA539, 0x00); |
| } |
| |
| uint8 sm_read_byte(void) |
| { |
| uint8 retme, r; |
| int i; |
| |
| retme = 0; |
| for (i=0; i<8; i++) |
| { |
| retme <<= 1; |
| out_byte(0xA539, 0x00); |
| out_byte(0xA539, 0x02); |
| r = in_byte(0xA538) & 0x01; |
| retme |= r; |
| } |
| |
| return retme; |
| } |
| |
| int sm_get_ack(void) |
| { |
| uint8 r; |
| r = in_byte(0xA538); |
| if ((r&0x01) == 0) return TRUE; |
| else return FALSE; |
| } |
| |
| void sm_write_ack(void) |
| { |
| out_byte(0xA539, 0x00); |
| out_byte(0xA539, 0x02); |
| out_byte(0xA539, 0x00); |
| } |
| |
| void sm_write_nack(void) |
| { |
| out_byte(0xA539, 0x01); |
| out_byte(0xA539, 0x03); |
| out_byte(0xA539, 0x01); |
| } |
| |
| void sm_send_start(void) |
| { |
| out_byte(0xA539, 0x03); |
| out_byte(0xA539, 0x02); |
| } |
| |
| void sm_send_stop(void) |
| { |
| out_byte(0xA539, 0x02); |
| out_byte(0xA539, 0x03); |
| } |
| |
| int sm_read_byte_from_device(uint8 addr, uint8 reg, uint8 *storage) |
| { |
| /* S Addr Wr */ |
| sm_write_mode(); |
| sm_send_start(); |
| sm_write_byte((addr<<1)); |
| |
| /* [A] */ |
| sm_read_mode(); |
| if (sm_get_ack() == FALSE) return FALSE; |
| |
| /* Comm */ |
| sm_write_mode(); |
| sm_write_byte(reg); |
| |
| /* [A] */ |
| sm_read_mode(); |
| if (sm_get_ack() == FALSE) return FALSE; |
| |
| /* S Addr Rd */ |
| sm_write_mode(); |
| sm_send_start(); |
| sm_write_byte((addr<<1)|1); |
| |
| /* [A] */ |
| sm_read_mode(); |
| if (sm_get_ack() == FALSE) return FALSE; |
| |
| /* [Data] */ |
| *storage = sm_read_byte(); |
| |
| /* NA */ |
| sm_write_mode(); |
| sm_write_nack(); |
| sm_send_stop(); |
| |
| return TRUE; |
| } |
| |
| void sm_init(void) |
| { |
| /* Switch to PMC mode */ |
| pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER)); |
| |
| /* Set GPIO Base */ |
| pci_write_cfg_long(0, 0, 0x40, 0xa500); |
| |
| /* Enable GPIO */ |
| pci_write_cfg_byte(0, 0, 0x44, 0x11); |
| |
| /* Set both GPIO 0 and 1 as output */ |
| out_byte(0xA53A, 0x03); |
| } |
| |
| |
| void sm_term(void) |
| { |
| /* Switch to normal mode */ |
| pci_write_cfg_byte(0, 0, REG_GROUP, 0); |
| } |
| |
| |
| int sm_get_data(uint8 *DataArray, int dimm_socket) |
| { |
| int j; |
| |
| #if 0 |
| /* Switch to PMC mode */ |
| pci_write_cfg_byte(0, 0, REG_GROUP, (uint8)(REG_GROUP_SPECIAL|REG_GROUP_POWER)); |
| |
| /* Set GPIO Base */ |
| pci_write_cfg_long(0, 0, 0x40, 0xa500); |
| |
| /* Enable GPIO */ |
| pci_write_cfg_byte(0, 0, 0x44, 0x11); |
| |
| /* Set both GPIO 0 and 1 as output */ |
| out_byte(0xA53A, 0x03); |
| #endif |
| |
| sm_init(); |
| /* Start reading the rom */ |
| |
| j = 0; |
| |
| do |
| { |
| if (sm_read_byte_from_device(dimm_socket, (uint8)j, DataArray) == FALSE) |
| { |
| sm_term(); |
| return FALSE; |
| } |
| |
| DataArray++; |
| j++; |
| } while (j < 128); |
| |
| sm_term(); |
| return TRUE; |
| } |