/** * Setup timing and region config to support a specific IDE PIO * mode over the bootbus. * * @param cs0 Bootbus region number connected to CS0 on the IDE device * @param cs1 Bootbus region number connected to CS1 on the IDE device * @param pio_mode PIO mode to set (0-6) */ void cvmx_compactflash_set_piomode(int cs0, int cs1, int pio_mode) { cvmx_mio_boot_reg_cfgx_t mio_boot_reg_cfg; cvmx_mio_boot_reg_timx_t mio_boot_reg_tim; int cs; int clocks_us; /* Number of clock cycles per microsec */ int tim_mult; int use_iordy; /* Set for PIO0-4, not set for PIO5-6 */ int t1; /* These t names are timing parameters from the ATA spec */ int t2; int t2i; int t4; int t6; int t6z; int t9; /* PIO modes 0-4 all allow the device to deassert IORDY to slow down the host */ use_iordy = 1; /* Use the PIO mode to determine timing parameters */ switch(pio_mode) { case 6: /* CF spec say IORDY should be ignore in PIO 5 */ use_iordy = 0; t1 = 10; t2 = 55; t2i = 20; t4 = 5; t6 = 5; t6z = 20; t9 = 10; break; case 5: /* CF spec say IORDY should be ignore in PIO 6 */ use_iordy = 0; t1 = 15; t2 = 65; t2i = 25; t4 = 5; t6 = 5; t6z = 20; t9 = 10; break; case 4: t1 = 25; t2 = 70; t2i = 25; t4 = 10; t6 = 5; t6z = 30; t9 = 10; break; case 3: t1 = 30; t2 = 80; t2i = 70; t4 = 10; t6 = 5; t6z = 30; t9 = 10; break; case 2: t1 = 30; t2 = 100; t2i = 0; t4 = 15; t6 = 5; t6z = 30; t9 = 10; break; case 1: t1 = 50; t2 = 125; t2i = 0; t4 = 20; t6 = 5; t6z = 30; t9 = 15; break; default: t1 = 70; t2 = 165; t2i = 0; t4 = 30; t6 = 5; t6z = 30; t9 = 20; break; } /* Convert times in ns to clock cycles, rounding up */ clocks_us = FLASH_RoundUP((uint64_t)cvmx_sysinfo_get()->cpu_clock_hz, 1000000); /* Convert times in clock cycles, rounding up. Octeon parameters are in minus one notation, so take off one after the conversion */ t1 = FLASH_RoundUP(t1 * clocks_us, 1000); if (t1) t1--; t2 = FLASH_RoundUP(t2 * clocks_us, 1000); if (t2) t2--; t2i = FLASH_RoundUP(t2i * clocks_us, 1000); if (t2i) t2i--; t4 = FLASH_RoundUP(t4 * clocks_us, 1000); if (t4) t4--; t6 = FLASH_RoundUP(t6 * clocks_us, 1000); if (t6) t6--; t6z = FLASH_RoundUP(t6z * clocks_us, 1000); if (t6z) t6z--; t9 = FLASH_RoundUP(t9 * clocks_us, 1000); if (t9) t9--; /* Start using a scale factor of one cycle. Keep doubling it until the parameters fit in their fields. Since t2 is the largest number, we only need to check it */ tim_mult = 1; while (t2 >= 1<<6) { t1 = FLASH_RoundUP(t1, 2); t2 = FLASH_RoundUP(t2, 2); t2i = FLASH_RoundUP(t2i, 2); t4 = FLASH_RoundUP(t4, 2); t6 = FLASH_RoundUP(t6, 2); t6z = FLASH_RoundUP(t6z, 2); t9 = FLASH_RoundUP(t9, 2); tim_mult *= 2; } cs = cs0; do { mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs)); mio_boot_reg_cfg.s.dmack = 0; /* Don't assert DMACK on access */ switch(tim_mult) { case 1: mio_boot_reg_cfg.s.tim_mult = 1; break; case 2: mio_boot_reg_cfg.s.tim_mult = 2; break; case 4: mio_boot_reg_cfg.s.tim_mult = 0; break; case 8: default: mio_boot_reg_cfg.s.tim_mult = 3; break; } mio_boot_reg_cfg.s.rd_dly = 0; /* Sample on falling edge of BOOT_OE */ mio_boot_reg_cfg.s.sam = 0; /* Don't combine write and output enable */ mio_boot_reg_cfg.s.we_ext = 0; /* No write enable extension */ mio_boot_reg_cfg.s.oe_ext = 0; /* No read enable extension */ mio_boot_reg_cfg.s.en = 1; /* Enable this region */ mio_boot_reg_cfg.s.orbit = 0; /* Don't combine with previos region */ mio_boot_reg_cfg.s.width = 1; /* 16 bits wide */ cvmx_write_csr(CVMX_MIO_BOOT_REG_CFGX(cs), mio_boot_reg_cfg.u64); if(cs == cs0) cs = cs1; else cs = cs0; } while(cs != cs0); mio_boot_reg_tim.u64 = 0; mio_boot_reg_tim.s.pagem = 0; /* Disable page mode */ mio_boot_reg_tim.s.waitm = use_iordy; /* Enable dynamic timing */ mio_boot_reg_tim.s.pages = 0; /* Pages are disabled */ mio_boot_reg_tim.s.ale = 8; /* If someone uses ALE, this seems to work */ mio_boot_reg_tim.s.page = 0; /* Not used */ mio_boot_reg_tim.s.wait = 0; /* Time after IORDY to coninue to assert the data */ mio_boot_reg_tim.s.pause = 0; /* Time after CE that signals stay valid */ mio_boot_reg_tim.s.wr_hld = t9; /* How long to hold after a write */ mio_boot_reg_tim.s.rd_hld = t9; /* How long to wait after a read for device to tristate */ mio_boot_reg_tim.s.we = t2; /* How long write enable is asserted */ mio_boot_reg_tim.s.oe = t2; /* How long read enable is asserted */ mio_boot_reg_tim.s.ce = t1; /* Time after CE that read/write starts */ mio_boot_reg_tim.s.adr = 1; /* Time before CE that address is valid */ /* Program the bootbus region timing for both chip selects */ cvmx_write_csr(CVMX_MIO_BOOT_REG_TIMX(cs0), mio_boot_reg_tim.u64); cvmx_write_csr(CVMX_MIO_BOOT_REG_TIMX(cs1), mio_boot_reg_tim.u64); }
/** * Called after libata determines the needed PIO mode. This * function programs the Octeon bootbus regions to support the * timing requirements of the PIO mode. * * @ap: ATA port information * @dev: ATA device */ static void octeon_cf_set_piomode(struct ata_port *ap, struct ata_device *dev) { struct octeon_cf_data *ocd = ap->dev->platform_data; union cvmx_mio_boot_reg_timx reg_tim; int cs = ocd->base_region; int T; struct ata_timing timing; int use_iordy; int trh; int pause; /* These names are timing parameters from the ATA spec */ int t1; int t2; int t2i; T = (int)(2000000000000LL / octeon_get_clock_rate()); if (ata_timing_compute(dev, dev->pio_mode, &timing, T, T)) BUG(); t1 = timing.setup; if (t1) t1--; t2 = timing.active; if (t2) t2--; t2i = timing.act8b; if (t2i) t2i--; trh = ns_to_tim_reg(2, 20); if (trh) trh--; pause = timing.cycle - timing.active - timing.setup - trh; if (pause) pause--; octeon_cf_set_boot_reg_cfg(cs); if (ocd->dma_engine >= 0) /* True IDE mode, program both chip selects. */ octeon_cf_set_boot_reg_cfg(cs + 1); use_iordy = ata_pio_need_iordy(dev); reg_tim.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_TIMX(cs)); /* Disable page mode */ reg_tim.s.pagem = 0; /* Enable dynamic timing */ reg_tim.s.waitm = use_iordy; /* Pages are disabled */ reg_tim.s.pages = 0; /* We don't use multiplexed address mode */ reg_tim.s.ale = 0; /* Not used */ reg_tim.s.page = 0; /* Time after IORDY to coninue to assert the data */ reg_tim.s.wait = 0; /* Time to wait to complete the cycle. */ reg_tim.s.pause = pause; /* How long to hold after a write to de-assert CE. */ reg_tim.s.wr_hld = trh; /* How long to wait after a read to de-assert CE. */ reg_tim.s.rd_hld = trh; /* How long write enable is asserted */ reg_tim.s.we = t2; /* How long read enable is asserted */ reg_tim.s.oe = t2; /* Time after CE that read/write starts */ reg_tim.s.ce = ns_to_tim_reg(2, 5); /* Time before CE that address is valid */ reg_tim.s.adr = 0; /* Program the bootbus region timing for the data port chip select. */ cvmx_write_csr(CVMX_MIO_BOOT_REG_TIMX(cs), reg_tim.u64); if (ocd->dma_engine >= 0) /* True IDE mode, program both chip selects. */ cvmx_write_csr(CVMX_MIO_BOOT_REG_TIMX(cs + 1), reg_tim.u64); }