int write_kernel_memory(long offset, long value) { int old_value = read_kernel_memory(offset); int scaled_offset = (offset-(offset & 0xFFFF0000L)); if(regutil_mem) regutil_mem[scaled_offset/sizeof(long)] = value; return old_value; }
int main(int argc, char **argv) { uint32_t debug0, debug1; if (argc != 3 && argc != 1) { printf("Usage: %s [[DEBUG0] [DEBUG1]]\n", argv[0]); printf("If no parameters are specified, current debug registers are read\n"); return 1; } if (argc == 3) { debug0 = strtoul(argv[1], NULL, 0); debug1 = strtoul(argv[2], NULL, 0); } else { debug0 = read_kernel_memory(0x01ffc728, 0, 4); debug1 = read_kernel_memory(0x01ffc72c, 0, 4); } printf("LTSSM current state: 0x%x (%s)\n", (debug0>>0) & 0x3f, ltssm_states[(debug0>>0) & 0x3f]); printf("PIPE transmit K indication: %d\n", (debug0>>6) & 3); printf("PIPE Transmit data: 0x%x\n", (debug0>>8) & 0xffff); printf("Receiver is receiving logical idle: %s\n", yesno((debug0>>25)&1)); printf("Second symbol is also idle (16-bit PHY interface only): %s\n", yesno((debug0>>24)&1)); printf("Currently receiving k237 (PAD) in place of link number: %s\n", yesno((debug0>>26)&1)); printf("Currently receiving k237 (PAD) in place of lane number: %s\n", yesno((debug0>>27)&1)); printf("Link control bits advertised by link partner: 0x%x\n", (debug0>>28)&0xf); printf("Receiver detected lane reversal: %s\n", yesno((debug1>>(32-32))&1)); printf("TS2 training sequence received: %s\n", yesno((debug1>>(33-32))&1)); printf("TS1 training sequence received: %s\n", yesno((debug1>>(34-32))&1)); printf("Receiver reports skip reception: %s\n", yesno((debug1>>(35-32))&1)); printf("LTSSM reports PHY link up: %s\n", yesno((debug1>>(36-32))&1)); printf("A skip ordered set has been transmitted: %s\n", yesno((debug1>>(37-32))&1)); printf("Link number advertised/confirmed by link partner: %d\n", (debug1>>(40-32))&0xff); printf("Application request to initiate training reset: %s\n", yesno((debug1>>(51-32))&1)); printf("PIPE transmit compliance request: %s\n", yesno((debug1>>(52-32))&1)); printf("PIPE transmit electrical idle request: %s\n", yesno((debug1>>(53-32))&1)); printf("PIPE receiver detect/loopback request: %s\n", yesno((debug1>>(54-32))&1)); printf("LTSSM-negotiated link reset: %s\n", yesno((debug1>>(59-32))&1)); printf("LTSSM testing for polarity reversal: %s\n", yesno((debug1>>(60-32))&1)); printf("LTSSM performing link training: %s\n", yesno((debug1>>(61-32))&1)); printf("LTSSM in DISABLE state; link inoperable: %s\n", yesno((debug1>>(62-32))&1)); printf("Scrambling disabled for the link: %s\n", yesno((debug1>>(63-32))&1)); return 0; }
// returns 1 if there is a TV present // returns 0 if there isn't one static int sink_status() { unsigned int gplr2; unsigned int hpd_state; // gpio_gplr2, bits 95:64 gplr2 = read_kernel_memory(0xd4019008, 0, 4); hpd_state = gplr2 & 0x08000000 ? SINK_CONNECTED : SINK_DISCONNECTED; return hpd_state; }
static int write_kernel_memory(long offset, long value, int virtualized, int size) { int old_value = read_kernel_memory(offset, virtualized, size); int scaled_offset = (offset-(offset&~0xFFFF)); if(size==1) mem_8[scaled_offset/sizeof(char)] = value; else if(size==2) mem_16[scaled_offset/sizeof(short)] = value; else mem_32[scaled_offset/sizeof(long)] = value; return old_value; }
int gpio_get_value(int gpio) { uint32_t base; long offset; if (gpio < 32) base = 0xd4019000; else if (gpio < 64) base = 0xd4019004; else if (gpio < 96) base = 0xd4019008; else base = 0xd4019100; offset = 0; return !!(read_kernel_memory(base+offset, 0, 4) & (1<<(gpio & 0x1f))); }
volatile int gpio_get_bank(int bank) { uint32_t base; if (bank == 0) base = 0xd4019000; else if (bank == 1) base = 0xd4019004; else if (bank == 2) base = 0xd4019008; else if (bank == 3) base = 0xd4019100; else { fprintf(stderr, "Invalid GPIO bank: %d\n", bank); return -1; } return read_kernel_memory(base, 0, 4); }
int main(int argc, char **argv) { char *prog = argv[0]; unsigned int a1; char port; argv++; argc--; setup_fpga(); setup_fpga_cs1(); if(!argc) { print_usage(prog); return 1; } while(argc > 0) { if(!strcmp(*argv, "-h")) { argc--; argv++; print_usage(prog); } else if(!strcmp(*argv, "-v")) { argc--; argv++; printf( "FPGA version code: %04hx.%04hx\n", read_kernel_memory(FPGA_R_V_MINOR, 0, 2), read_kernel_memory(FPGA_R_V_MAJOR, 0, 2) ); } else if(!strcmp(*argv, "-da")) { argc--; argv++; if( argc != 1 ) { printf( "usage -da <code>\n" ); return 1; } a1 = strtoul(*argv, NULL, 10); argc--; argv++; dac_a_set(a1 * 4); // implementation sends 2 dummy bits } else if(!strcmp(*argv, "-db")) { argc--; argv++; if( argc != 1 ) { printf( "usage -db <code>\n" ); return 1; } a1 = strtoul(*argv, NULL, 10); argc--; argv++; dac_b_set(a1 * 4); } else if(!strcmp(*argv, "-a")) { argc--; argv++; if( argc != 1 ) { printf( "usage -a <chan>\n" ); return 1; } a1 = strtoul(*argv, NULL, 10); argc--; argv++; adc_chan(a1); printf( "ADC channel %d: %d\n", a1, adc_read() );; } else if(!strcmp(*argv, "-hv")) { argc--; argv++; setvddio(1); } else if(!strcmp(*argv, "-lv")) { argc--; argv++; setvddio(0); } else if(!strcmp(*argv, "-oea")) { argc--; argv++; if( argc != 1 ) { printf( "usage -oea <drive>\n" ); return 1; } a1 = strtoul(*argv, NULL, 10); argc--; argv++; oe_state(a1, OE_A); } else if(!strcmp(*argv, "-oeb")) { argc--; argv++; if( argc != 1 ) { printf( "usage -oeb <drive>\n" ); return 1; } a1 = strtoul(*argv, NULL, 10); argc--; argv++; oe_state(a1, OE_B); } else if(!strcmp(*argv, "-p")) { argc--; argv++; if( argc < 1 ) { printf( "usage -p <port> [hex value]\n" ); return 1; } if( argv[0][0] == 'a' || argv[0][0] == 'A' ) port = PORT_A; else if ( argv[0][0] == 'b' || argv[0][0] == 'B' ) port = PORT_B; else { printf( "Invalid port, must be one of a,b\n" ); break; } argc--; argv++; if( argc == 0 ) { // it's a read op printf( "%c: %02x\n", port ? 'b' : 'a', gpbb_output_state( port ) ); } else { // it's a write op a1 = strtoul(*argv, NULL, 16); argc--; argv++; gpbb_port_write( port ? PORT_B : PORT_A, PORT_VAL, (unsigned short) a1 ); } } else if(!strcmp(*argv, "-p_set")) { argc--; argv++; if( argc != 2 ) { printf( "usage -p_set <port> <bit>\n" ); return 1; } if( argv[0][0] == 'a' || argv[0][0] == 'A' ) port = PORT_A; else if ( argv[0][0] == 'b' || argv[0][0] == 'B' ) port = PORT_B; else { printf( "Invalid port, must be one of a,b\n" ); break; } argc--; argv++; a1 = strtoul(*argv, NULL, 10); argc--; argv++; gpbb_port_write( port ? PORT_B : PORT_A, PORT_SET, (unsigned short) a1 ); } else if(!strcmp(*argv, "-p_clr")) { argc--; argv++; if( argc != 2 ) { printf( "usage -p_set <port> <bit>\n" ); return 1; } if( argv[0][0] == 'a' || argv[0][0] == 'A' ) port = PORT_A; else if ( argv[0][0] == 'b' || argv[0][0] == 'B' ) port = PORT_B; else { printf( "Invalid port, must be one of a,b\n" ); break; } argc--; argv++; a1 = strtoul(*argv, NULL, 10); argc--; argv++; gpbb_port_write( port ? PORT_B : PORT_A, PORT_CLR, (unsigned short) a1 ); } else if(!strcmp(*argv, "-rp")) { argc--; argv++; printf( "input port: %02x\n", gpbb_read()); } else if(!strcmp(*argv, "-testcs1")) { argc--; argv++; testcs1(); } else { print_usage(prog); return 1; } } return 0; }
void setup_fpga_cs1() { int i; // printf( "setting up EIM CS1 (burst interface) pads and configuring timing\n" ); // ASSUME: setup_fpga() is already called to configure gpio mux setting. // this just gets the pads set to high-speed mode // set up pads to be mapped to EIM for( i = 0; i < 16; i++ ) { write_kernel_memory( 0x20e0428 + i*4, 0xb0f1, 0, 4 ); // pad strength config'd for a 200MHz rate } // pad strength write_kernel_memory( 0x20e046c, 0xb0f1, 0, 4 ); // BCLK // write_kernel_memory( 0x20e040c, 0xb0b1, 0, 4 ); // CS0 write_kernel_memory( 0x20e0410, 0xb0f1, 0, 4 ); // CS1 write_kernel_memory( 0x20e0414, 0xb0f1, 0, 4 ); // OE write_kernel_memory( 0x20e0418, 0xb0f1, 0, 4 ); // RW write_kernel_memory( 0x20e041c, 0xb0f1, 0, 4 ); // LBA write_kernel_memory( 0x20e0468, 0xb0f1, 0, 4 ); // WAIT write_kernel_memory( 0x20e0408, 0xb0f1, 0, 4 ); // A16 write_kernel_memory( 0x20e0404, 0xb0f1, 0, 4 ); // A17 write_kernel_memory( 0x20e0400, 0xb0f1, 0, 4 ); // A18 // EIM_CS1GCR1 // 0011 0 001 1 001 0 001 00 00 1 011 1 0 1 1 1 1 1 1 // PSZ WP GBC AUS CSREC SP DSZ BCS BCD WC BL CREP CRE RFL WFL MUM SRD SWR CSEN // // PSZ = 0011 64 words page size // WP = 0 (not protected) // GBC = 001 min 1 cycles between chip select changes // AUS = 0 address shifted according to port size // CSREC = 001 min 1 cycles between CS, OE, WE signals // SP = 0 no supervisor protect (user mode access allowed) // DSZ = 001 16-bit port resides on DATA[15:0] // BCS = 00 0 clock delay for burst generation // BCD = 00 divide EIM clock by 0 for burst clock // WC = 1 write accesses are continuous burst length // BL = 011 32 word memory wrap length // CREP = 1 non-PSRAM, set to 1 // CRE = 0 CRE is disabled // RFL = 1 fixed latency reads // WFL = 1 fixed latency writes // MUM = 1 multiplexed mode enabled // SRD = 1 synch reads // SWR = 1 synch writes // CSEN = 1 chip select is enabled // 0101 0111 1111 0001 1100 0000 1011 1 0 0 1 // 0x5 7 F 1 C 0 B 9 // 0101 0001 1001 0001 1100 0000 1011 1001 // 5 1 9 1 c 0 B 9 // 0011 0001 1001 0001 0000 1011 1011 1111 write_kernel_memory( 0x21b8000 + 0x18, 0x31910BBF, 0, 4 ); // EIM_CS1GCR2 // MUX16_BYP_GRANT = 1 // ADH = 0 (0 cycles) // 0x1000 write_kernel_memory( 0x21b8004 + 0x18, 0x1000, 0, 4 ); // 9 cycles is total length of read // 2 cycles for address // +4 more cycles for first data to show up // EIM_CS1RCR1 // 00 000100 0 000 0 001 0 010 0 000 0 000 0 000 // RWSC RADVA RAL RADVN OEA OEN RCSA RCSN // // 00 001001 0 000 0 001 0 110 0 000 0 000 0 000 // RWSC RADVA RAL RADVN OEA OEN RCSA RCSN // // 0000 0111 0000 0011 0000 0000 0000 0000 // 0 7 0 3 0 0 0 0 // 0000 0101 0000 0000 0 000 0 000 0 000 0 000 // write_kernel_memory( 0x21b8008, 0x05000000, 0, 4 ); // 0000 0011 0000 0001 0001 0000 0000 0000 // 0000 1001 0000 0001 0110 0000 0000 0000 // write_kernel_memory( 0x21b8008 + 0x18, 0x09014000, 0, 4 ); // EIM_CS1RCR2 // 0000 0000 0 000 00 00 0 010 0 001 // APR PAT RL RBEA RBEN // APR = 0 mandatory because MUM = 1 // PAT = XXX because APR = 0 // RL = 00 because async mode // RBEA = 000 these match RCSA/RCSN from previous field // RBEN = 000 // 0000 0000 0000 0000 0000 0000 write_kernel_memory( 0x21b800c + 0x18, 0x00000200, 0, 4 ); // EIM_CS1WCR1 // 0 0 000010 000 001 000 000 010 000 000 000 // WAL WBED WWSC WADVA WADVN WBEA WBEN WEA WEN WCSA WCSN // WAL = 0 use WADVN // WBED = 0 allow BE during write // WWSC = 000100 4 write wait states // WADVA = 000 same as RADVA // WADVN = 000 this sets WE length to 1 (this value +1) // WBEA = 000 same as RBEA // WBEN = 000 same as RBEN // WEA = 010 2 cycles between beginning of access and WE assertion // WEN = 000 1 cycles to end of WE assertion // WCSA = 000 cycles to CS assertion // WCSN = 000 cycles to CS negation // 1000 0111 1110 0001 0001 0100 0101 0001 // 8 7 E 1 1 4 5 1 // 0000 0111 0000 0100 0000 1000 0000 0000 // 0 7 0 4 0 8 0 0 // 0000 0100 0000 0000 0000 0100 0000 0000 // 0 4 0 0 0 4 0 0 // 0000 0010 0000 0000 0000 0010 0000 0000 // 0000 0010 0000 0100 0000 0100 0000 0000 write_kernel_memory( 0x21b8010 + 0x18, 0x02040400, 0, 4 ); // EIM_WCR // BCM = 1 free-run BCLK // GBCD = 0 divide the burst clock by 1 // add timeout watchdog after 1024 bclk cycles write_kernel_memory( 0x21b8090, 0x701, 0, 4 ); // EIM_WIAR // ACLK_EN = 1 write_kernel_memory( 0x21b8094, 0x10, 0, 4 ); // printf( "resetting CS0 space to 64M and enabling 64M CS1 space.\n" ); write_kernel_memory( 0x20e0004, (read_kernel_memory(0x20e0004, 0, 4) & 0xFFFFFFC0) | 0x1B, 0, 4); // printf( "done.\n" ); }