static void usbphy_charger_identify(uint8_t sel) { if (sel > PMU_CHARGER_IDENTIFY_MAX) return; clock_gate_switch(USB_CLOCKGATE_UNK1, ON); SET_REG(USB_PHY + OPHYUNK3, (GET_REG(USB_PHY + OPHYUNK3) & (~0x6)) | (sel*2)); clock_gate_switch(USB_CLOCKGATE_UNK1, OFF); }
int dma_setup() { clock_gate_switch(DMAC0_CLOCKGATE, ON); clock_gate_switch(DMAC1_CLOCKGATE, ON); interrupt_install(DMAC0_INTERRUPT, dmaIRQHandler, 1); interrupt_install(DMAC1_INTERRUPT, dmaIRQHandler, 2); interrupt_enable(DMAC0_INTERRUPT); interrupt_enable(DMAC1_INTERRUPT); return 0; }
int gpio_setup() { int i; GPIORegs = (GPIORegisters*) GPIO; for(i = 0; i < GPIO_NUMINTGROUPS; i++) { // writes to all the interrupt status register to acknowledge and discard any pending SET_REG(GPIOIC + GPIO_INTSTAT + (i * 0x4), GPIO_INTSTAT_RESET); // disable all interrupts SET_REG(GPIOIC + GPIO_INTEN + (i * 0x4), GPIO_INTEN_RESET); } memset(InterruptGroups, 0, sizeof(InterruptGroups)); interrupt_install(0x21, gpio_handle_interrupt, 0); interrupt_install(0x20, gpio_handle_interrupt, 1); interrupt_install(0x1f, gpio_handle_interrupt, 2); interrupt_install(0x03, gpio_handle_interrupt, 3); interrupt_install(0x02, gpio_handle_interrupt, 4); interrupt_install(0x01, gpio_handle_interrupt, 5); interrupt_install(0x00, gpio_handle_interrupt, 6); interrupt_enable(0x21); interrupt_enable(0x20); interrupt_enable(0x1f); interrupt_enable(0x03); interrupt_enable(0x02); interrupt_enable(0x01); interrupt_enable(0x00); clock_gate_switch(GPIO_CLOCKGATE, ON); return 0; }
int spi_setup() { int i; for(i = 0; i < SPICount; i++) { // Only enable SPIs 1-3. if(((0x7 >> i) & 1) == 0) continue; SPIRegisters *regs = &SPIRegs[i]; SPIStruct *data = &SPIData[i]; memset(data, 0, sizeof(*data)); data->registers = regs; data->clockSource = NCLK; clock_gate_switch(regs->gate, ON); SET_REG(data->registers->control, 0); interrupt_install(regs->irq, spi_irq_handler, i); interrupt_enable(regs->irq); } return 0; }
int spi_setup() { clock_gate_switch(SPI0_CLOCKGATE, ON); clock_gate_switch(SPI1_CLOCKGATE, ON); clock_gate_switch(SPI2_CLOCKGATE, ON); memset(spi_info, 0, sizeof(SPIInfo) * NUM_SPIPORTS); int i; for(i = 0; i < NUM_SPIPORTS; i++) { spi_info[i].clockSource = NCLK; SET_REG(SPIRegs[i].control, 0); } interrupt_install(SPI0_IRQ, spiIRQHandler, 0); interrupt_install(SPI1_IRQ, spiIRQHandler, 1); interrupt_install(SPI2_IRQ, spiIRQHandler, 2); interrupt_enable(SPI0_IRQ); interrupt_enable(SPI1_IRQ); interrupt_enable(SPI2_IRQ); return 0; }
int uart_setup() { int i; if(UartHasInit) { return 0; } clock_gate_switch(UART_CLOCKGATE, ON); for(i = 0; i < NUM_UARTS; i++) { // set all uarts to transmit 8 bit frames, one stop bit per frame, no parity, no infrared mode SET_REG(HWUarts[i].ULCON, UART_8BITS); // set all uarts to use polling for rx/tx, no breaks, no loopback, no error status interrupts, // no timeouts, pulse interrupts for rx/tx, peripheral clock. Basically, the defaults. SET_REG(HWUarts[i].UCON, (UART_UCON_MODE_IRQORPOLL << UART_UCON_RXMODE_SHIFT) | (UART_UCON_MODE_IRQORPOLL << UART_UCON_TXMODE_SHIFT)); // Initialize the settings array a bit so the helper functions can be used properly UARTs[i].ureg = i; UARTs[i].baud = 115200; uart_set_clk(i, UART_CLOCK_EXT_UCLK0); uart_set_sample_rate(i, 16); } // Set flow control uart_set_flow_control(0, OFF); uart_set_flow_control(1, ON); uart_set_flow_control(2, ON); uart_set_flow_control(3, ON); uart_set_flow_control(4, OFF); // Reset and enable fifo for(i = 0; i < NUM_UARTS; i++) { SET_REG(HWUarts[i].UFCON, UART_FIFO_RESET_TX | UART_FIFO_RESET_RX); SET_REG(HWUarts[i].UFCON, UART_FIFO_ENABLE); UARTs[i].fifo = ON; } for(i = 0; i < NUM_UARTS; i++) { uart_set_mode(i, UART_POLL_MODE); } uart_set_mode(0, UART_POLL_MODE); UartHasInit = TRUE; return 0; }
int gpio_setup() { int i; GPIORegs = (GPIORegisters*) GPIO; for(i = 0; i < NUM_GPIO; i++) { SET_REG(GPIO_POWER + POWER_GPIO_CONFIG0, POWER_GPIO_CONFIG0_RESET); SET_REG(GPIO_POWER + POWER_GPIO_CONFIG1, POWER_GPIO_CONFIG1_RESET); } // iBoot also sets up interrupt handlers, but those are never unmasked clock_gate_switch(GPIO_CLOCKGATE, ON); return 0; }
static void init_i2c(I2CInfo* i2c) { clock_gate_switch(i2c->clockgate, ON); gpio_custom_io(i2c->iic_sda_gpio, 2); // pull sda low? int i; for (i = 0; i < 19; i++) { gpio_custom_io(i2c->iic_scl_gpio, (i % 2) ? 2 : 0); udelay(5); } gpio_custom_io(i2c->iic_scl_gpio, 5); // generate stop condition? gpio_custom_io(i2c->iic_sda_gpio, 5); SET_REG(i2c->register_8, 0x30); SET_REG(i2c->register_C, 0x37); i2c->operation_result = 0; interrupt_install(i2c->interrupt, i2cIRQHandler, (uint32_t)i2c); interrupt_enable(i2c->interrupt); }
int timer_setup() { /* timer needs clock signal */ clock_gate_switch(TIMER_CLOCKGATE, ON); /* stop/cleanup any existing timers */ timer_stop_all(); /* do some voodoo */ timer_init_rtc(); int i; for(i = 0; i < NUM_TIMERS; i++) { timer_setup_clk(i, 1, 2, 0); } // In our implementation, event dispatch timer setup is handled by a subsequent function // Install the timer interrupt interrupt_install(TIMER_IRQ, timerIRQHandler, 1); interrupt_enable(TIMER_IRQ); return 0; }
int usb_setup() { int i; if(usb_inited) { return 0; } InEPRegs = (USBEPRegisters*)(USB + USB_INREGS); OutEPRegs = (USBEPRegisters*)(USB + USB_OUTREGS); change_state(USBStart); // Power on hardware power_ctrl(POWER_USB, ON); udelay(USB_START_DELAYUS); // Initialize our data structures for(i = 0; i < USB_NUM_ENDPOINTS; i++) { switch(USB_EP_DIRECTION(i)) { case USB_ENDPOINT_DIRECTIONS_BIDIR: endpoint_directions[i] = USBBiDir; break; case USB_ENDPOINT_DIRECTIONS_IN: endpoint_directions[i] = USBIn; break; case USB_ENDPOINT_DIRECTIONS_OUT: endpoint_directions[i] = USBOut; break; } bufferPrintf("EP %d: %d\r\n", i, endpoint_directions[i]); } memset(endpoint_handlers, 0, sizeof(endpoint_handlers)); // Set up the hardware clock_gate_switch(USB_OTGCLOCKGATE, ON); clock_gate_switch(USB_PHYCLOCKGATE, ON); clock_gate_switch(EDRAM_CLOCKGATE, ON); // Generate a soft disconnect on host SET_REG(USB + DCTL, GET_REG(USB + DCTL) | DCTL_SFTDISCONNECT); udelay(USB_SFTDISCONNECT_DELAYUS); // power on OTG SET_REG(USB + USB_ONOFF, GET_REG(USB + USB_ONOFF) & (~USB_ONOFF_OFF)); udelay(USB_ONOFFSTART_DELAYUS); // power on PHY SET_REG(USB_PHY + OPHYPWR, OPHYPWR_POWERON); udelay(USB_PHYPWRPOWERON_DELAYUS); // select clock SET_REG(USB_PHY + OPHYCLK, (GET_REG(USB_PHY + OPHYCLK) & OPHYCLK_CLKSEL_MASK) | OPHYCLK_CLKSEL_48MHZ); // reset phy SET_REG(USB_PHY + ORSTCON, GET_REG(USB_PHY + ORSTCON) | ORSTCON_PHYSWRESET); udelay(USB_RESET2_DELAYUS); SET_REG(USB_PHY + ORSTCON, GET_REG(USB_PHY + ORSTCON) & (~ORSTCON_PHYSWRESET)); udelay(USB_RESET_DELAYUS); SET_REG(USB + GRSTCTL, GRSTCTL_CORESOFTRESET); // wait until reset takes while((GET_REG(USB + GRSTCTL) & GRSTCTL_CORESOFTRESET) == GRSTCTL_CORESOFTRESET); // wait until reset completes while((GET_REG(USB + GRSTCTL) & ~GRSTCTL_AHBIDLE) != 0); udelay(USB_RESETWAITFINISH_DELAYUS); // allow host to reconnect SET_REG(USB + DCTL, GET_REG(USB + DCTL) & (~DCTL_SFTDISCONNECT)); udelay(USB_SFTCONNECT_DELAYUS); // flag all interrupts as positive, maybe to disable them // Set 7th EP? This is what iBoot does InEPRegs[USB_NUM_ENDPOINTS].interrupt = USB_EPINT_INEPNakEff | USB_EPINT_INTknEPMis | USB_EPINT_INTknTXFEmp | USB_EPINT_TimeOUT | USB_EPINT_AHBErr | USB_EPINT_EPDisbld | USB_EPINT_XferCompl; OutEPRegs[USB_NUM_ENDPOINTS].interrupt = USB_EPINT_OUTTknEPDis | USB_EPINT_SetUp | USB_EPINT_AHBErr | USB_EPINT_EPDisbld | USB_EPINT_XferCompl; for(i = 0; i < USB_NUM_ENDPOINTS; i++) { InEPRegs[i].interrupt = USB_EPINT_INEPNakEff | USB_EPINT_INTknEPMis | USB_EPINT_INTknTXFEmp | USB_EPINT_TimeOUT | USB_EPINT_AHBErr | USB_EPINT_EPDisbld | USB_EPINT_XferCompl; OutEPRegs[i].interrupt = USB_EPINT_OUTTknEPDis | USB_EPINT_SetUp | USB_EPINT_AHBErr | USB_EPINT_EPDisbld | USB_EPINT_XferCompl; } // disable all interrupts until endpoint descriptors and configuration structures have been setup SET_REG(USB + GINTMSK, GINTMSK_NONE); SET_REG(USB + DIEPMSK, USB_EPINT_NONE); SET_REG(USB + DOEPMSK, USB_EPINT_NONE); interrupt_install(USB_INTERRUPT, usbIRQHandler, 0); usb_inited = TRUE; return 0; }
int dma_setup() { clock_gate_switch(0x25, ON); return 0; }
int nand_setup() { if(HasNANDInit) return 0; NANDSetting1 = 7; NANDSetting2 = 7; NANDSetting3 = 7; NANDSetting4 = 7; bufferPrintf("nand: Probing flash controller...\r\n"); clock_gate_switch(NAND_CLOCK_GATE1, ON); clock_gate_switch(NAND_CLOCK_GATE2, ON); int bank; for(bank = 0; bank < NAND_NUM_BANKS; bank++) { banksTable[bank] = bank; } NumValidBanks = 0; const NANDDeviceType* nandType = NULL; SET_REG(NAND + NAND_SETUP, 0); SET_REG(NAND + NAND_SETUP, GET_REG(NAND + NAND_SETUP) | (ECCType << 4)); for(bank = 0; bank < NAND_NUM_BANKS; bank++) { nand_bank_reset(bank, 100); SET_REG(NAND + NAND_CON, NAND_CON_SETTING1); SET_REG(NAND + NAND_CONFIG, ((NANDSetting1 & NAND_CONFIG_SETTING1MASK) << NAND_CONFIG_SETTING1SHIFT) | ((NANDSetting2 & NAND_CONFIG_SETTING2MASK) << NAND_CONFIG_SETTING2SHIFT) | (1 << (banksTable[bank] + 1)) | NAND_CONFIG_DEFAULTS); SET_REG(NAND + NAND_CMD, NAND_CMD_ID); wait_for_ready(500); SET_REG(NAND + NAND_CONFIG4, 0); SET_REG(NAND + NAND_CONFIG3, 0); SET_REG(NAND + NAND_CON, NAND_CON_ADDRESSDONE); wait_for_address_complete(500); nand_bank_reset_helper(bank, 100); SET_REG(NAND + NAND_TRANSFERSIZE, 8); SET_REG(NAND + NAND_CON, NAND_CON_BEGINTRANSFER); wait_for_status_bit_3(500); uint32_t id = GET_REG(NAND + NAND_DMA_SOURCE); const NANDDeviceType* candidate = SupportedDevices; while(candidate->id != 0) { if(candidate->id == id) { if(nandType == NULL) { nandType = candidate; } else if(nandType != candidate) { bufferPrintf("nand: Mismatched device IDs (0x%08x after 0x%08x)\r\n", id, nandType->id); return ERROR_ARG; } banksTable[NumValidBanks++] = bank; } candidate++; } SET_REG(NAND + NAND_CON, NAND_CON_SETTING1); } if(nandType == NULL) { bufferPrintf("nand: No supported NAND found\r\n"); return ERROR_ARG; } Data.DeviceID = nandType->id; Data.banksTable = banksTable; NANDSetting2 = (((clock_get_frequency(FrequencyBaseBus) * (nandType->NANDSetting2 + 1)) + 99999999)/100000000) - 1; NANDSetting1 = (((clock_get_frequency(FrequencyBaseBus) * (nandType->NANDSetting1 + 1)) + 99999999)/100000000) - 1; NANDSetting3 = (((clock_get_frequency(FrequencyBaseBus) * (nandType->NANDSetting3 + 1)) + 99999999)/100000000) - 1; NANDSetting4 = (((clock_get_frequency(FrequencyBaseBus) * (nandType->NANDSetting4 + 1)) + 99999999)/100000000) - 1; if(NANDSetting2 > 7) NANDSetting2 = 7; if(NANDSetting1 > 7) NANDSetting1 = 7; if(NANDSetting3 > 7) NANDSetting3 = 7; if(NANDSetting4 > 7) NANDSetting4 = 7; Data.blocksPerBank = nandType->blocksPerBank; Data.banksTotal = NumValidBanks; Data.sectorsPerPage = nandType->sectorsPerPage; Data.userSubBlksTotal = nandType->userSubBlksTotal; Data.bytesPerSpare = nandType->bytesPerSpare; Data.field_2E = 4; Data.field_2F = 3; Data.pagesPerBlock = nandType->pagesPerBlock; if(Data.sectorsPerPage > 4) { LargePages = TRUE; } else { LargePages = FALSE; } if(nandType->ecc1 == 6) { ECCType = 4; TotalECCDataSize = Data.sectorsPerPage * 15; } else if(nandType->ecc1 == 8) { ECCType = 8; TotalECCDataSize = Data.sectorsPerPage * 20; } else if(nandType->ecc1 == 4) { ECCType = 0; TotalECCDataSize = Data.sectorsPerPage * 10; } if(nandType->ecc2 == 6) { ECCType2 = 4; } else if(nandType->ecc2 == 8) { ECCType2 = 8; } else if(nandType->ecc2 == 4) { ECCType2 = 0; } Data.field_4 = 5; Data.bytesPerPage = SECTOR_SIZE * Data.sectorsPerPage; Data.pagesPerBank = Data.pagesPerBlock * Data.blocksPerBank; Data.pagesTotal = Data.pagesPerBank * Data.banksTotal; Data.pagesPerSubBlk = Data.pagesPerBlock * Data.banksTotal; Data.userPagesTotal = Data.userSubBlksTotal * Data.pagesPerSubBlk; Data.subBlksTotal = (Data.banksTotal * Data.blocksPerBank) / Data.banksTotal; Data2.field_2 = Data.subBlksTotal - Data.userSubBlksTotal - 28; Data2.field_0 = Data2.field_2 + 4; Data2.field_4 = Data2.field_2 + 5; Data2.field_6 = 3; Data2.field_8 = 23; if(Data2.field_8 == 0) Data.field_22 = 0; int bits = 0; int i = Data2.field_8; while((i <<= 1) != 0) { bits++; } Data.field_22 = bits; bufferPrintf("nand: DEVICE: %08x\r\n", Data.DeviceID); bufferPrintf("nand: BANKS_TOTAL: %d\r\n", Data.banksTotal); bufferPrintf("nand: BLOCKS_PER_BANK: %d\r\n", Data.blocksPerBank); bufferPrintf("nand: SUBLKS_TOTAL: %d\r\n", Data.subBlksTotal); bufferPrintf("nand: USER_SUBLKS_TOTAL: %d\r\n", Data.userSubBlksTotal); bufferPrintf("nand: PAGES_PER_SUBLK: %d\r\n", Data.pagesPerSubBlk); bufferPrintf("nand: PAGES_PER_BANK: %d\r\n", Data.pagesPerBank); bufferPrintf("nand: SECTORS_PER_PAGE: %d\r\n", Data.sectorsPerPage); bufferPrintf("nand: BYTES_PER_SPARE: %d\r\n", Data.bytesPerSpare); bufferPrintf("nand: BYTES_PER_PAGE: %d\r\n", Data.bytesPerPage); bufferPrintf("nand: PAGES_PER_BLOCK: %d\r\n", Data.pagesPerBlock); aTemporaryReadEccBuf = (uint8_t*) malloc(Data.bytesPerPage); memset(aTemporaryReadEccBuf, 0xFF, SECTOR_SIZE); aTemporarySBuf = (uint8_t*) malloc(Data.bytesPerSpare); HasNANDInit = TRUE; return 0; }
int nand_setup() { if(HasNANDInit) return 0; WEHighHoldTime = 7; WPPulseTime = 7; NANDSetting3 = 7; NANDSetting4 = 7; bufferPrintf("nand: Probing flash controller...\r\n"); clock_gate_switch(NAND_CLOCK_GATE1, ON); clock_gate_switch(NAND_CLOCK_GATE2, ON); int bank; for(bank = 0; bank < NAND_NUM_BANKS; bank++) { banksTable[bank] = bank; } NumValidBanks = 0; const NANDDeviceType* nandType = NULL; SET_REG(NAND + RSCTRL, 0); SET_REG(NAND + RSCTRL, GET_REG(NAND + RSCTRL) | (ECCType << 4)); for(bank = 0; bank < NAND_NUM_BANKS; bank++) { nand_bank_reset(bank, 100); SET_REG(NAND + FMCTRL1, FMCTRL1_FLUSHFIFOS); SET_REG(NAND + FMCTRL0, ((WEHighHoldTime & FMCTRL_TWH_MASK) << FMCTRL_TWH_SHIFT) | ((WPPulseTime & FMCTRL_TWP_MASK) << FMCTRL_TWP_SHIFT) | (1 << (banksTable[bank] + 1)) | FMCTRL0_ON | FMCTRL0_WPB); SET_REG(NAND + NAND_CMD, NAND_CMD_ID); wait_for_ready(500); SET_REG(NAND + FMANUM, 0); SET_REG(NAND + FMADDR0, 0); SET_REG(NAND + FMCTRL1, FMCTRL1_DOTRANSADDR); wait_for_address_done(500); wait_for_command_done(bank, 100); SET_REG(NAND + FMDNUM, 8); SET_REG(NAND + FMCTRL1, FMCTRL1_DOREADDATA); wait_for_transfer_done(500); uint32_t id = GET_REG(NAND + FMFIFO); const NANDDeviceType* candidate = SupportedDevices; while(candidate->id != 0) { if(candidate->id == id) { if(nandType == NULL) { nandType = candidate; } else if(nandType != candidate) { bufferPrintf("nand: Mismatched device IDs (0x%08x after 0x%08x)\r\n", id, nandType->id); return ERROR_ARG; } banksTable[NumValidBanks++] = bank; } candidate++; } SET_REG(NAND + FMCTRL1, FMCTRL1_FLUSHFIFOS); } if(nandType == NULL) { bufferPrintf("nand: No supported NAND found\r\n"); return ERROR_ARG; } Geometry.DeviceID = nandType->id; Geometry.banksTable = banksTable; WPPulseTime = (((clock_get_frequency(FrequencyBaseBus) * (nandType->WPPulseTime + 1)) + 99999999)/100000000) - 1; WEHighHoldTime = (((clock_get_frequency(FrequencyBaseBus) * (nandType->WEHighHoldTime + 1)) + 99999999)/100000000) - 1; NANDSetting3 = (((clock_get_frequency(FrequencyBaseBus) * (nandType->NANDSetting3 + 1)) + 99999999)/100000000) - 1; NANDSetting4 = (((clock_get_frequency(FrequencyBaseBus) * (nandType->NANDSetting4 + 1)) + 99999999)/100000000) - 1; if(WPPulseTime > 7) WPPulseTime = 7; if(WEHighHoldTime > 7) WEHighHoldTime = 7; if(NANDSetting3 > 7) NANDSetting3 = 7; if(NANDSetting4 > 7) NANDSetting4 = 7; Geometry.blocksPerBank = nandType->blocksPerBank; Geometry.banksTotal = NumValidBanks; Geometry.sectorsPerPage = nandType->sectorsPerPage; Geometry.userSuBlksTotal = nandType->userSuBlksTotal; Geometry.bytesPerSpare = nandType->bytesPerSpare; Geometry.field_2E = 4; Geometry.field_2F = 3; Geometry.pagesPerBlock = nandType->pagesPerBlock; if(Geometry.sectorsPerPage > 4) { LargePages = TRUE; } else { LargePages = FALSE; } if(nandType->ecc1 == 6) { ECCType = 4; TotalECCDataSize = Geometry.sectorsPerPage * 15; } else if(nandType->ecc1 == 8) { ECCType = 8; TotalECCDataSize = Geometry.sectorsPerPage * 20; } else if(nandType->ecc1 == 4) { ECCType = 0; TotalECCDataSize = Geometry.sectorsPerPage * 10; } if(nandType->ecc2 == 6) { ECCType2 = 4; } else if(nandType->ecc2 == 8) { ECCType2 = 8; } else if(nandType->ecc2 == 4) { ECCType2 = 0; } Geometry.field_4 = 5; Geometry.bytesPerPage = SECTOR_SIZE * Geometry.sectorsPerPage; Geometry.pagesPerBank = Geometry.pagesPerBlock * Geometry.blocksPerBank; Geometry.pagesTotal = Geometry.pagesPerBank * Geometry.banksTotal; Geometry.pagesPerSuBlk = Geometry.pagesPerBlock * Geometry.banksTotal; Geometry.userPagesTotal = Geometry.userSuBlksTotal * Geometry.pagesPerSuBlk; Geometry.suBlksTotal = (Geometry.banksTotal * Geometry.blocksPerBank) / Geometry.banksTotal; FTLData.field_2 = Geometry.suBlksTotal - Geometry.userSuBlksTotal - 28; FTLData.sysSuBlks = FTLData.field_2 + 4; FTLData.field_4 = FTLData.field_2 + 5; FTLData.field_6 = 3; FTLData.field_8 = 23; if(FTLData.field_8 == 0) Geometry.field_22 = 0; int bits = 0; int i = FTLData.field_8; while((i <<= 1) != 0) { bits++; } Geometry.field_22 = bits; bufferPrintf("nand: DEVICE: %08x\r\n", Geometry.DeviceID); bufferPrintf("nand: BANKS_TOTAL: %d\r\n", Geometry.banksTotal); bufferPrintf("nand: BLOCKS_PER_BANK: %d\r\n", Geometry.blocksPerBank); bufferPrintf("nand: SUBLKS_TOTAL: %d\r\n", Geometry.suBlksTotal); bufferPrintf("nand: USER_SUBLKS_TOTAL: %d\r\n", Geometry.userSuBlksTotal); bufferPrintf("nand: PAGES_PER_SUBLK: %d\r\n", Geometry.pagesPerSuBlk); bufferPrintf("nand: PAGES_PER_BANK: %d\r\n", Geometry.pagesPerBank); bufferPrintf("nand: SECTORS_PER_PAGE: %d\r\n", Geometry.sectorsPerPage); bufferPrintf("nand: BYTES_PER_SPARE: %d\r\n", Geometry.bytesPerSpare); bufferPrintf("nand: BYTES_PER_PAGE: %d\r\n", Geometry.bytesPerPage); bufferPrintf("nand: PAGES_PER_BLOCK: %d\r\n", Geometry.pagesPerBlock); aTemporaryReadEccBuf = (uint8_t*) malloc(Geometry.bytesPerPage); memset(aTemporaryReadEccBuf, 0xFF, SECTOR_SIZE); aTemporarySBuf = (uint8_t*) malloc(Geometry.bytesPerSpare); HasNANDInit = TRUE; return 0; }
int gpio_setup() { #if !defined(CONFIG_IPHONE_4) && !defined(CONFIG_IPAD) int i; GPIORegs = (GPIORegisters*) GPIO; for(i = 0; i < GPIO_NUMINTGROUPS; i++) { // writes to all the interrupt status register to acknowledge and discard any pending SET_REG(GPIOIC + GPIO_INTSTAT + (i * 0x4), GPIO_INTSTAT_RESET); // disable all interrupts SET_REG(GPIOIC + GPIO_INTEN + (i * 0x4), GPIO_INTEN_RESET); } memset(InterruptGroups, 0, sizeof(InterruptGroups)); interrupt_install(0x21, gpio_handle_interrupt, 0); interrupt_install(0x20, gpio_handle_interrupt, 1); interrupt_install(0x1f, gpio_handle_interrupt, 2); interrupt_install(0x03, gpio_handle_interrupt, 3); interrupt_install(0x02, gpio_handle_interrupt, 4); interrupt_install(0x01, gpio_handle_interrupt, 5); interrupt_install(0x00, gpio_handle_interrupt, 6); interrupt_enable(0x21); interrupt_enable(0x20); interrupt_enable(0x1f); interrupt_enable(0x03); interrupt_enable(0x02); interrupt_enable(0x01); interrupt_enable(0x00); clock_gate_switch(GPIO_CLOCKGATE, ON); return 0; #else uint8_t v[8]; if (!(GET_REG(GPIO) & 1)) { gpio_set(0x502, 0); gpio_set(0x503, 0); gpio_set(0x504, 0); gpio_switch(0x502, 0xFFFFFFFF); gpio_switch(0x503, 0xFFFFFFFF); gpio_switch(0x504, 0xFFFFFFFF); gpio_set(0x202, 0); gpio_set(0x301, 0); gpio_set(0x304, 0); gpio_set(0x305, 0); gpio_switch(0x202, 0xFFFFFFFF); gpio_switch(0x301, 0xFFFFFFFF); gpio_switch(0x304, 0xFFFFFFFF); gpio_switch(0x305, 0xFFFFFFFF); udelay(100); v[0] = chipid_get_gpio(); v[1] = gpio_pin_state(0x504); v[2] = gpio_pin_state(0x503); v[3] = gpio_pin_state(0x502); v[4] = gpio_pin_state(0x305); v[5] = gpio_pin_state(0x304); v[6] = gpio_pin_state(0x301); v[7] = gpio_pin_state(0x202); gpio_set(0x502, 4); gpio_set(0x503, 4); gpio_set(0x504, 4); gpio_set(0x202, 4); gpio_set(0x301, 4); gpio_set(0x304, 4); gpio_set(0x305, 4); uint32_t new_status = ((v[0] << 3 | v[1] << 2 | v[2] << 1 | v[3]) << 16) | ((v[4] << 3 | v[5] << 2 | v[6] << 1 | v[7]) << 8) | 1; SET_REG(POWER + POWER_ID, (GET_BITS(GET_REG(POWER + POWER_ID), 24, 8)) | (new_status & 0xFFFFFF)); } return 0; #endif }
int usb_setup(USBEnumerateHandler hEnumerate, USBStartHandler hStart) { usb_shutdown(); // This is not relevant to the hardware, // and usb_setup is called when setting up a new // USB protocol. So we should reset the EP // handlers here! -- Ricky26 memset(endpoint_handlers, 0, sizeof(endpoint_handlers)); startHandler = hStart; enumerateHandler = hEnumerate; setupHandler = NULL; if(usb_inited) return 0; if(controlSendBuffer == NULL) controlSendBuffer = memalign(DMA_ALIGN, CONTROL_SEND_BUFFER_LEN); if(controlRecvBuffer == NULL) controlRecvBuffer = memalign(DMA_ALIGN, CONTROL_RECV_BUFFER_LEN); InEPRegs = (USBEPRegisters*)(USB + USB_INREGS); OutEPRegs = (USBEPRegisters*)(USB + USB_OUTREGS); change_state(USBStart); initializeDescriptors(); // Initialize our data structures memset(usb_message_queue, 0, sizeof(usb_message_queue)); #ifdef USB_PHY_1G // Power on hardware power_ctrl(POWER_USB, ON); udelay(USB_START_DELAYUS); #else // Wait for USB hardware to come alive udelay(10000); #endif // Set up the hardware clock_gate_switch(USB_OTGCLOCKGATE, ON); clock_gate_switch(USB_PHYCLOCKGATE, ON); #ifdef USB_PHY_1G clock_gate_switch(EDRAM_CLOCKGATE, ON); #endif // power on OTG SET_REG(USB + PCGCCTL, (GET_REG(USB + PCGCCTL) & (~PCGCCTL_ONOFF_MASK)) | PCGCCTL_ON); udelay(USB_ONOFFSTART_DELAYUS); // Generate a soft disconnect on host //SET_REG(USB + DCTL, GET_REG(USB + DCTL) | DCTL_SFTDISCONNECT); //udelay(USB_SFTDISCONNECT_DELAYUS); // Initialise PHY usb_phy_init(); bufferPrintf("USB: Hardware Configuration\n" " HWCFG1 = 0x%08x\n" " HWCFG2 = 0x%08x\n" " HWCFG3 = 0x%08x\n" " HWCFG4 = 0x%08x\n", GET_REG(USB+GHWCFG1), GET_REG(USB+GHWCFG2), GET_REG(USB+GHWCFG3), GET_REG(USB+GHWCFG4)); usb_inited = TRUE; interrupt_install(USB_INTERRUPT, usbIRQHandler, 0); // Start USB usb_start(); return 0; }