// SPDX-License-Identifier: GPL-2.0-only /* * Faraday Technology FTIDE010 driver * Copyright (C) 2017 Linus Walleij <[email protected]> * * Includes portions of the SL2312/SL3516/Gemini PATA driver * Copyright (C) 2003 StorLine, Inc <[email protected]> * Copyright (C) 2009 Janos Laube <[email protected]> * Copyright (C) 2010 Frederic Pecourt <[email protected]> * Copyright (C) 2011 Tobias Waldvogel <[email protected]> */ #include <linux/platform_device.h> #include <linux/module.h> #include <linux/libata.h> #include <linux/bitops.h> #include <linux/of.h> #include <linux/clk.h> #include "sata_gemini.h" #define DRV_NAME … /** * 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 { … }; #define FTIDE010_DMA_REG … #define FTIDE010_DMA_STATUS … #define FTIDE010_IDE_BMDTPR … #define FTIDE010_IDE_DEVICE_ID … #define FTIDE010_PIO_TIMING … #define FTIDE010_MWDMA_TIMING … #define FTIDE010_UDMA_TIMING0 … #define FTIDE010_UDMA_TIMING1 … #define FTIDE010_CLK_MOD … /* These registers are mapped directly to the IDE registers */ #define FTIDE010_CMD_DATA … #define FTIDE010_ERROR_FEATURES … #define FTIDE010_NSECT … #define FTIDE010_LBAL … #define FTIDE010_LBAM … #define FTIDE010_LBAH … #define FTIDE010_DEVICE … #define FTIDE010_STATUS_COMMAND … #define FTIDE010_ALTSTAT_CTRL … /* Set this bit for UDMA mode 5 and 6 */ #define FTIDE010_UDMA_TIMING_MODE_56 … /* 0 = 50 MHz, 1 = 66 MHz */ #define FTIDE010_CLK_MOD_DEV0_CLK_SEL … #define FTIDE010_CLK_MOD_DEV1_CLK_SEL … /* Enable UDMA on a device */ #define FTIDE010_CLK_MOD_DEV0_UDMA_EN … #define FTIDE010_CLK_MOD_DEV1_UDMA_EN … static const struct scsi_host_template pata_ftide010_sht = …; /* * 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. */ static const u8 pio_active_time[5] = …; static const u8 pio_recovery_time[5] = …; static const u8 mwdma_50_active_time[3] = …; static const u8 mwdma_50_recovery_time[3] = …; static const u8 mwdma_66_active_time[3] = …; static const u8 mwdma_66_recovery_time[3] = …; static const u8 udma_50_setup_time[6] = …; static const u8 udma_50_hold_time[6] = …; static const u8 udma_66_setup_time[7] = …; static const u8 udma_66_hold_time[7] = …; /* * We set 66 MHz for all MWDMA modes */ static const bool set_mdma_66_mhz[] = …; /* * We set 66 MHz for UDMA modes 3, 4 and 6 and no others */ static const bool set_udma_66_mhz[] = …; static void ftide010_set_dmamode(struct ata_port *ap, struct ata_device *adev) { … } static void ftide010_set_piomode(struct ata_port *ap, struct ata_device *adev) { … } /* * 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. */ static unsigned int ftide010_qc_issue(struct ata_queued_cmd *qc) { … } static struct ata_port_operations pata_ftide010_port_ops = …; static struct ata_port_info ftide010_port_info = …; #if IS_ENABLED(CONFIG_SATA_GEMINI) static int pata_ftide010_gemini_port_start(struct ata_port *ap) { … } static void pata_ftide010_gemini_port_stop(struct ata_port *ap) { … } static int pata_ftide010_gemini_cable_detect(struct ata_port *ap) { … } static int pata_ftide010_gemini_init(struct ftide010 *ftide, struct ata_port_info *pi, bool is_ata1) { … } #else static int pata_ftide010_gemini_init(struct ftide010 *ftide, struct ata_port_info *pi, bool is_ata1) { return -ENOTSUPP; } #endif static int pata_ftide010_probe(struct platform_device *pdev) { … } static void pata_ftide010_remove(struct platform_device *pdev) { … } static const struct of_device_id pata_ftide010_of_match[] = …; static struct platform_driver pata_ftide010_driver = …; module_platform_driver(…) …; MODULE_DESCRIPTION(…) …; MODULE_AUTHOR(…) …; MODULE_LICENSE(…) …; MODULE_ALIAS(…) …;