/* * set the io pins * this needs a clean up for smaller tighter code * use *uint and set the address based on cmd + port */ static int do_iopset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint rcode = 0; iopin_t iopin; static uint port; static uint pin; static uint value; static enum { DIR, PAR, SOR, ODR, DAT, INT } cmd = DAT; if (argc != 5) { puts("iopset PORT PIN CMD VALUE\n"); return 1; } port = argv[1][0] - 'A'; if (port > 3) port -= 0x20; if (port > 3) rcode = 1; pin = simple_strtol(argv[2], NULL, 10); if (pin > 31) rcode = 1; switch (argv[3][0]) { case 'd': if (argv[3][1] == 'a') cmd = DAT; else if (argv[3][1] == 'i') cmd = DIR; else rcode = 1; break; case 'p': cmd = PAR; break; case 'o': cmd = ODR; break; case 's': cmd = SOR; break; case 'i': cmd = INT; break; default: printf("iopset: unknown command %s\n", argv[3]); rcode = 1; } if (argv[4][0] == '1') value = 1; else if (argv[4][0] == '0') value = 0; else rcode = 1; if (rcode == 0) { iopin.port = port; iopin.pin = pin; iopin.flag = 0; switch (cmd) { case DIR: if (value) iopin_set_out(&iopin); else iopin_set_in(&iopin); break; case PAR: if (value) iopin_set_ded(&iopin); else iopin_set_gen(&iopin); break; case SOR: if (value) iopin_set_opt2(&iopin); else iopin_set_opt1(&iopin); break; case ODR: if (value) iopin_set_odr(&iopin); else iopin_set_act(&iopin); break; case DAT: if (value) iopin_set_high(&iopin); else iopin_set_low(&iopin); break; case INT: if (value) iopin_set_falledge(&iopin); else iopin_set_anyedge(&iopin); break; } } return rcode; }
int fpga_load (int mezz, uchar *addr, ulong size) { hymod_conf_t *cp = &gd->bd->bi_hymod_conf; xlx_info_t *fp; xlx_iopins_t *fpgaio; volatile uchar *fpgabase; volatile uint cnt; uchar *eaddr = addr + size; int result; if (mezz) fp = &cp->mezz.xlx[0]; else fp = &cp->main.xlx[0]; if (!fp->mmap.prog.exists) return (LOAD_FAIL_NOCONF); fpgabase = (uchar *)fp->mmap.prog.base; fpgaio = &fp->iopins; /* set enable HIGH if required */ if (fpgaio->enable_pin.flag) iopin_set_high (&fpgaio->enable_pin); /* ensure INIT is released (set it to be an input) */ iopin_set_in (&fpgaio->init_pin); /* toggle PROG Low then High (will already be Low after Power-On) */ iopin_set_low (&fpgaio->prog_pin); udelay (1); /* minimum 300ns - 1usec should do it */ iopin_set_high (&fpgaio->prog_pin); /* wait for INIT High */ cnt = 0; while (!iopin_is_high (&fpgaio->init_pin)) if (++cnt == 10000000) { result = LOAD_FAIL_NOINIT; goto done; } /* write configuration data */ while (addr < eaddr) *fpgabase = *addr++; /* wait for DONE High */ cnt = 0; while (!iopin_is_high (&fpgaio->done_pin)) if (++cnt == 100000000) { result = LOAD_FAIL_NODONE; goto done; } /* success */ result = LOAD_SUCCESS; done: if (fpgaio->enable_pin.flag) iopin_set_low (&fpgaio->enable_pin); return (result); }