/** * struct ftide010 - state container for the Faraday FTIDE010 * @dev: pointer back to the device representing this controller * @base: remapped I/O space address * @pclk: peripheral clock for the IDE block * @host: pointer to the ATA host for this device * @master_cbl: master cable type * @slave_cbl: slave cable type * @sg: Gemini SATA bridge pointer, if running on the Gemini * @master_to_sata0: Gemini SATA bridge: the ATA master is connected * to the SATA0 bridge * @slave_to_sata0: Gemini SATA bridge: the ATA slave is connected * to the SATA0 bridge * @master_to_sata1: Gemini SATA bridge: the ATA master is connected * to the SATA1 bridge * @slave_to_sata1: Gemini SATA bridge: the ATA slave is connected * to the SATA1 bridge
*/ struct ftide010 { struct device *dev; void __iomem *base; struct clk *pclk; struct ata_host *host; unsignedint master_cbl; unsignedint slave_cbl; /* Gemini-specific properties */ struct sata_gemini *sg; bool master_to_sata0; bool slave_to_sata0; bool master_to_sata1; bool slave_to_sata1;
};
/* * Bus timings * * The unit of the below required timings is two clock periods of the ATA * reference clock which is 30 nanoseconds per unit at 66MHz and 20 * nanoseconds per unit at 50 MHz. The PIO timings assume 33MHz speed for * PIO. * * pio_active_time: array of 5 elements for T2 timing for Mode 0, * 1, 2, 3 and 4. Range 0..15. * pio_recovery_time: array of 5 elements for T2l timing for Mode 0, * 1, 2, 3 and 4. Range 0..15. * mdma_50_active_time: array of 4 elements for Td timing for multi * word DMA, Mode 0, 1, and 2 at 50 MHz. Range 0..15. * mdma_50_recovery_time: array of 4 elements for Tk timing for * multi word DMA, Mode 0, 1 and 2 at 50 MHz. Range 0..15. * mdma_66_active_time: array of 4 elements for Td timing for multi * word DMA, Mode 0, 1 and 2 at 66 MHz. Range 0..15. * mdma_66_recovery_time: array of 4 elements for Tk timing for * multi word DMA, Mode 0, 1 and 2 at 66 MHz. Range 0..15. * udma_50_setup_time: array of 4 elements for Tvds timing for ultra * DMA, Mode 0, 1, 2, 3, 4 and 5 at 50 MHz. Range 0..7. * udma_50_hold_time: array of 4 elements for Tdvh timing for * multi word DMA, Mode 0, 1, 2, 3, 4 and 5 at 50 MHz, Range 0..7. * udma_66_setup_time: array of 4 elements for Tvds timing for multi * word DMA, Mode 0, 1, 2, 3, 4, 5 and 6 at 66 MHz. Range 0..7. * udma_66_hold_time: array of 4 elements for Tdvh timing for * multi word DMA, Mode 0, 1, 2, 3, 4, 5 and 6 at 66 MHz. Range 0..7.
*/ staticconst u8 pio_active_time[5] = {10, 10, 10, 3, 3}; staticconst u8 pio_recovery_time[5] = {10, 3, 1, 3, 1}; staticconst u8 mwdma_50_active_time[3] = {6, 2, 2}; staticconst u8 mwdma_50_recovery_time[3] = {6, 2, 1}; staticconst u8 mwdma_66_active_time[3] = {8, 3, 3}; staticconst u8 mwdma_66_recovery_time[3] = {8, 2, 1}; staticconst u8 udma_50_setup_time[6] = {3, 3, 2, 2, 1, 1}; staticconst u8 udma_50_hold_time[6] = {3, 1, 1, 1, 1, 1}; staticconst u8 udma_66_setup_time[7] = {4, 4, 3, 2, }; staticconst u8 udma_66_hold_time[7] = {};
/* * We set 66 MHz for all MWDMA modes
*/ staticconstbool set_mdma_66_mhz[] = { true, true, true, true };
/* * We set 66 MHz for UDMA modes 3, 4 and 6 and no others
*/ staticconstbool set_udma_66_mhz[] = { false, false, false, true, true, false, true };
/* * Store the current device (master or slave) in ap->private_data * so that .qc_issue() can detect if this changes and reprogram * the DMA settings.
*/
ap->private_data = adev;
dev_dbg(ftide->dev, "set PIO mode %02x, index %d\n",
adev->pio_mode, pio);
writeb(pio_active_time[pio] << 4 | pio_recovery_time[pio],
ftide->base + FTIDE010_PIO_TIMING);
}
/* * We implement our own qc_issue() callback since we may need to set up * the timings differently for master and slave transfers: the CLK_MOD_REG * and MWDMA_TIMING_REG is shared between master and slave, so reprogramming * this may be necessary.
*/ staticunsignedint ftide010_qc_issue(struct ata_queued_cmd *qc)
{ struct ata_port *ap = qc->ap; struct ata_device *adev = qc->dev;
/* * If the device changed, i.e. slave->master, master->slave, * then set up the DMA mode again so we are sure the timings * are correct.
*/ if (adev != ap->private_data && ata_dma_enabled(adev))
ftide010_set_dmamode(ap, adev);
/* Flag port as SATA-capable */ if (gemini_sata_bridge_enabled(sg, is_ata1))
pi->flags |= ATA_FLAG_SATA;
/* This device has broken DMA, only PIO works */ if (of_machine_is_compatible("itian,sq201")) {
pi->mwdma_mask = 0;
pi->udma_mask = 0;
}
/* * We assume that a simple 40-wire cable is used in the PATA mode. * if you're adding a system using the PATA interface, make sure * the right cable is set up here, it might be necessary to use * special hardware detection or encode the cable type in the device * tree with special properties.
*/ if (!is_ata1) { switch (muxmode) { case GEMINI_MUXMODE_0:
ftide->master_cbl = ATA_CBL_SATA;
ftide->slave_cbl = ATA_CBL_PATA40;
ftide->master_to_sata0 = true; break; case GEMINI_MUXMODE_1:
ftide->master_cbl = ATA_CBL_SATA;
ftide->slave_cbl = ATA_CBL_NONE;
ftide->master_to_sata0 = true; break; case GEMINI_MUXMODE_2:
ftide->master_cbl = ATA_CBL_PATA40;
ftide->slave_cbl = ATA_CBL_PATA40; break; case GEMINI_MUXMODE_3:
ftide->master_cbl = ATA_CBL_SATA;
ftide->slave_cbl = ATA_CBL_SATA;
ftide->master_to_sata0 = true;
ftide->slave_to_sata1 = true; break;
}
} else { switch (muxmode) { case GEMINI_MUXMODE_0:
ftide->master_cbl = ATA_CBL_SATA;
ftide->slave_cbl = ATA_CBL_NONE;
ftide->master_to_sata1 = true; break; case GEMINI_MUXMODE_1:
ftide->master_cbl = ATA_CBL_SATA;
ftide->slave_cbl = ATA_CBL_PATA40;
ftide->master_to_sata1 = true; break; case GEMINI_MUXMODE_2:
ftide->master_cbl = ATA_CBL_SATA;
ftide->slave_cbl = ATA_CBL_SATA;
ftide->slave_to_sata0 = true;
ftide->master_to_sata1 = true; break; case GEMINI_MUXMODE_3:
ftide->master_cbl = ATA_CBL_PATA40;
ftide->slave_cbl = ATA_CBL_PATA40; break;
}
}
dev_info(dev, "set up Gemini PATA%d\n", is_ata1);
irq = platform_get_irq(pdev, 0); if (irq < 0) return irq;
ftide->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(ftide->base)) return PTR_ERR(ftide->base);
ftide->pclk = devm_clk_get(dev, "PCLK"); if (!IS_ERR(ftide->pclk)) {
ret = clk_prepare_enable(ftide->pclk); if (ret) {
dev_err(dev, "failed to enable PCLK\n"); return ret;
}
}
/* Some special Cortina Gemini init, if needed */ if (of_device_is_compatible(np, "cortina,gemini-pata")) { /* * We need to know which instance is probing (the * Gemini has two instances of FTIDE010) and we do * this simply by looking at the physical base * address, which is 0x63400000 for ATA1, else we * are ATA0. This will also set up the cable types.
*/
ret = pata_ftide010_gemini_init(ftide,
&pi,
(res->start == 0x63400000)); if (ret) goto err_dis_clk;
} else { /* Else assume we are connected using PATA40 */
ftide->master_cbl = ATA_CBL_PATA40;
ftide->slave_cbl = ATA_CBL_PATA40;
}
ftide->host = ata_host_alloc_pinfo(dev, ppi, 1); if (!ftide->host) {
ret = -ENOMEM; goto err_dis_clk;
}
ftide->host->private_data = ftide;
for (i = 0; i < ftide->host->n_ports; i++) { struct ata_port *ap = ftide->host->ports[i]; struct ata_ioports *ioaddr = &ap->ioaddr;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.