162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Renesas Mobile SDHI 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2017 Horms Solutions Ltd., Simon Horman 662306a36Sopenharmony_ci * Copyright (C) 2017-19 Renesas Electronics Corporation 762306a36Sopenharmony_ci */ 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#ifndef RENESAS_SDHI_H 1062306a36Sopenharmony_ci#define RENESAS_SDHI_H 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/platform_device.h> 1362306a36Sopenharmony_ci#include "tmio_mmc.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistruct renesas_sdhi_scc { 1662306a36Sopenharmony_ci unsigned long clk_rate; /* clock rate for SDR104 */ 1762306a36Sopenharmony_ci u32 tap; /* sampling clock position for SDR104/HS400 (8 TAP) */ 1862306a36Sopenharmony_ci u32 tap_hs400_4tap; /* sampling clock position for HS400 (4 TAP) */ 1962306a36Sopenharmony_ci}; 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define SDHI_FLAG_NEED_CLKH_FALLBACK BIT(0) 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistruct renesas_sdhi_of_data { 2462306a36Sopenharmony_ci unsigned long tmio_flags; 2562306a36Sopenharmony_ci u32 tmio_ocr_mask; 2662306a36Sopenharmony_ci unsigned long capabilities; 2762306a36Sopenharmony_ci unsigned long capabilities2; 2862306a36Sopenharmony_ci enum dma_slave_buswidth dma_buswidth; 2962306a36Sopenharmony_ci dma_addr_t dma_rx_offset; 3062306a36Sopenharmony_ci unsigned int bus_shift; 3162306a36Sopenharmony_ci int scc_offset; 3262306a36Sopenharmony_ci struct renesas_sdhi_scc *taps; 3362306a36Sopenharmony_ci int taps_num; 3462306a36Sopenharmony_ci unsigned int max_blk_count; 3562306a36Sopenharmony_ci unsigned short max_segs; 3662306a36Sopenharmony_ci unsigned long sdhi_flags; 3762306a36Sopenharmony_ci}; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#define SDHI_CALIB_TABLE_MAX 32 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci#define sdhi_has_quirk(p, q) ((p)->quirks && (p)->quirks->q) 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_cistruct renesas_sdhi_quirks { 4462306a36Sopenharmony_ci bool hs400_disabled; 4562306a36Sopenharmony_ci bool hs400_4taps; 4662306a36Sopenharmony_ci bool fixed_addr_mode; 4762306a36Sopenharmony_ci bool dma_one_rx_only; 4862306a36Sopenharmony_ci bool manual_tap_correction; 4962306a36Sopenharmony_ci bool old_info1_layout; 5062306a36Sopenharmony_ci u32 hs400_bad_taps; 5162306a36Sopenharmony_ci const u8 (*hs400_calib_table)[SDHI_CALIB_TABLE_MAX]; 5262306a36Sopenharmony_ci}; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_cistruct renesas_sdhi_of_data_with_quirks { 5562306a36Sopenharmony_ci const struct renesas_sdhi_of_data *of_data; 5662306a36Sopenharmony_ci const struct renesas_sdhi_quirks *quirks; 5762306a36Sopenharmony_ci}; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci/* We want both end_flags to be set before we mark DMA as finished */ 6062306a36Sopenharmony_ci#define SDHI_DMA_END_FLAG_DMA 0 6162306a36Sopenharmony_ci#define SDHI_DMA_END_FLAG_ACCESS 1 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistruct renesas_sdhi_dma { 6462306a36Sopenharmony_ci unsigned long end_flags; 6562306a36Sopenharmony_ci enum dma_slave_buswidth dma_buswidth; 6662306a36Sopenharmony_ci bool (*filter)(struct dma_chan *chan, void *arg); 6762306a36Sopenharmony_ci void (*enable)(struct tmio_mmc_host *host, bool enable); 6862306a36Sopenharmony_ci struct completion dma_dataend; 6962306a36Sopenharmony_ci struct tasklet_struct dma_complete; 7062306a36Sopenharmony_ci}; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistruct renesas_sdhi { 7362306a36Sopenharmony_ci struct clk *clk; 7462306a36Sopenharmony_ci struct clk *clkh; 7562306a36Sopenharmony_ci struct clk *clk_cd; 7662306a36Sopenharmony_ci struct tmio_mmc_data mmc_data; 7762306a36Sopenharmony_ci struct renesas_sdhi_dma dma_priv; 7862306a36Sopenharmony_ci const struct renesas_sdhi_quirks *quirks; 7962306a36Sopenharmony_ci struct pinctrl *pinctrl; 8062306a36Sopenharmony_ci struct pinctrl_state *pins_default, *pins_uhs; 8162306a36Sopenharmony_ci void __iomem *scc_ctl; 8262306a36Sopenharmony_ci u32 scc_tappos; 8362306a36Sopenharmony_ci u32 scc_tappos_hs400; 8462306a36Sopenharmony_ci const u8 *adjust_hs400_calib_table; 8562306a36Sopenharmony_ci bool needs_adjust_hs400; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci /* Tuning values: 1 for success, 0 for failure */ 8862306a36Sopenharmony_ci DECLARE_BITMAP(taps, BITS_PER_LONG); 8962306a36Sopenharmony_ci /* Sampling data comparison: 1 for match, 0 for mismatch */ 9062306a36Sopenharmony_ci DECLARE_BITMAP(smpcmp, BITS_PER_LONG); 9162306a36Sopenharmony_ci unsigned int tap_num; 9262306a36Sopenharmony_ci unsigned int tap_set; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci struct reset_control *rstc; 9562306a36Sopenharmony_ci}; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci#define host_to_priv(host) \ 9862306a36Sopenharmony_ci container_of((host)->pdata, struct renesas_sdhi, mmc_data) 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ciint renesas_sdhi_probe(struct platform_device *pdev, 10162306a36Sopenharmony_ci const struct tmio_mmc_dma_ops *dma_ops, 10262306a36Sopenharmony_ci const struct renesas_sdhi_of_data *of_data, 10362306a36Sopenharmony_ci const struct renesas_sdhi_quirks *quirks); 10462306a36Sopenharmony_civoid renesas_sdhi_remove(struct platform_device *pdev); 10562306a36Sopenharmony_ci#endif 106