/** * gpmi_set_timings - set GPMI timings * @pdev: pointer to GPMI platform device * @tm: pointer to structure &gpmi_nand_timing with new timings * * During initialization, GPMI uses safe sub-optimal timings, which * can be changed after reading boot control blocks */ void gpmi_set_timings(struct lba_data *data, struct gpmi_nand_timing *tm) { u32 period_ns = 1000000 / clk_get_rate(data->clk) + 1; u32 address_cycles, data_setup_cycles; u32 data_hold_cycles, data_sample_cycles; u32 busy_timeout; u32 t0; address_cycles = gpmi_cycles_ceil(tm->address_setup, period_ns); data_setup_cycles = gpmi_cycles_ceil(tm->data_setup, period_ns); data_hold_cycles = gpmi_cycles_ceil(tm->data_hold, period_ns); data_sample_cycles = gpmi_cycles_ceil(tm->dsample_time + period_ns / 4, period_ns / 2); busy_timeout = gpmi_cycles_ceil(10000000 / 4096, period_ns); t0 = BF_GPMI_TIMING0_ADDRESS_SETUP(address_cycles) | BF_GPMI_TIMING0_DATA_SETUP(data_setup_cycles) | BF_GPMI_TIMING0_DATA_HOLD(data_hold_cycles); HW_GPMI_TIMING0_WR(t0); HW_GPMI_TIMING1_WR(BF_GPMI_TIMING1_DEVICE_BUSY_TIMEOUT(busy_timeout)); #ifdef CONFIG_ARCH_STMP378X HW_GPMI_CTRL1_CLR(BM_GPMI_CTRL1_RDN_DELAY); HW_GPMI_CTRL1_SET(BF_GPMI_CTRL1_RDN_DELAY(data_sample_cycles)); #else HW_GPMI_CTRL1_CLR(BM_GPMI_CTRL1_DSAMPLE_TIME); HW_GPMI_CTRL1_SET(BF_GPMI_CTRL1_DSAMPLE_TIME(data_sample_cycles)); #endif }
void gpmi_set_busy_timeout(uint32_t busyTimeout) { // Get current GPMI_CLK period in nanoseconds. // uint32_t u32GpmiPeriod_ns = gpmi_get_clock_period_ns(); // // // Convert from microseconds to nanoseconds. // uint64_t busyTimeout_ns = busyTimeout * 1000; // // // Divide the number of GPMI_CLK cycles for the timeout by 4096 as the // // timeout register expects. // uint32_t busyTimeout_gpmiclk = gpmi_find_cycles_ceiling(busyTimeout_ns, u32GpmiPeriod_ns, 0) / 4096; // // // The busy timeout field is only 16 bits, so make sure the desired timeout will fit. // if ((busyTimeout_gpmiclk & 0xffff0000) != 0) // { // // Set the timeout to the maximum value. // busyTimeout_gpmiclk = 0xffff; // } HW_GPMI_TIMING1_WR(BF_GPMI_TIMING1_DEVICE_BUSY_TIMEOUT(0xffff)); //busyTimeout_gpmiclk)); }
{ uint32_t value; struct resources *resources = &this->resources; /* set timing 2 register */ value = BF_GPMI_TIMING2_DATA_PAUSE(0x6) | BF_GPMI_TIMING2_CMDADD_PAUSE(0x4) | BF_GPMI_TIMING2_POSTAMBLE_DELAY(0x2) | BF_GPMI_TIMING2_PREAMBLE_DELAY(0x4) | BF_GPMI_TIMING2_CE_DELAY(0x2) | BF_GPMI_TIMING2_READ_LATENCY(0x2); __raw_writel(value, resources->gpmi_regs + HW_GPMI_TIMING2); /* set timing 1 register */ __raw_writel(BF_GPMI_TIMING1_DEVICE_BUSY_TIMEOUT(0x500), resources->gpmi_regs + HW_GPMI_TIMING1); /* Put GPMI in NAND mode, disable device reset, and make certain IRQRDY polarity is active high. */ value = BV_GPMI_CTRL1_GPMI_MODE__NAND | BM_GPMI_CTRL1_GANGED_RDYBUSY | BF_GPMI_CTRL1_WRN_DLY_SEL(0x3) | (BV_GPMI_CTRL1_DEV_RESET__DISABLED << 3) | (BV_GPMI_CTRL1_ATA_IRQRDY_POLARITY__ACTIVEHIGH << 2); __raw_writel(value, resources->gpmi_regs + HW_GPMI_CTRL1_SET); } /* This must be called in the context of enabling necessary clocks */ static void common_ddr_init(struct resources *resources)