Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
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;
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
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;
}
Пример #7
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;
}
Пример #8
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);
}
Пример #9
0
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;
}
Пример #10
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;
}
Пример #11
0
int dma_setup() {
	clock_gate_switch(0x25, ON);

	return 0;
}
Пример #12
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;
}
Пример #13
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;
}
Пример #14
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
}
Пример #15
0
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;
}