xref: /openbmc/linux/drivers/mmc/host/renesas_sdhi.h (revision 80c602b1)
1f707079dSWolfram Sang /* SPDX-License-Identifier: GPL-2.0 */
2c2a96987SSimon Horman /*
3c2a96987SSimon Horman  * Renesas Mobile SDHI
4c2a96987SSimon Horman  *
5c2a96987SSimon Horman  * Copyright (C) 2017 Horms Solutions Ltd., Simon Horman
6f49bdcdeSWolfram Sang  * Copyright (C) 2017-19 Renesas Electronics Corporation
7c2a96987SSimon Horman  */
8c2a96987SSimon Horman 
9c2a96987SSimon Horman #ifndef RENESAS_SDHI_H
10c2a96987SSimon Horman #define RENESAS_SDHI_H
11c2a96987SSimon Horman 
129d08428aSSimon Horman #include <linux/platform_device.h>
13c2a96987SSimon Horman #include "tmio_mmc.h"
14c2a96987SSimon Horman 
159d08428aSSimon Horman struct renesas_sdhi_scc {
169d08428aSSimon Horman 	unsigned long clk_rate;	/* clock rate for SDR104 */
17c1a49782SWolfram Sang 	u32 tap;		/* sampling clock position for SDR104/HS400 (8 TAP) */
18c1a49782SWolfram Sang 	u32 tap_hs400_4tap;	/* sampling clock position for HS400 (4 TAP) */
199d08428aSSimon Horman };
209d08428aSSimon Horman 
21627151b4SWolfram Sang #define SDHI_FLAG_NEED_CLKH_FALLBACK	BIT(0)
22627151b4SWolfram Sang 
239d08428aSSimon Horman struct renesas_sdhi_of_data {
249d08428aSSimon Horman 	unsigned long tmio_flags;
259d08428aSSimon Horman 	u32	      tmio_ocr_mask;
269d08428aSSimon Horman 	unsigned long capabilities;
279d08428aSSimon Horman 	unsigned long capabilities2;
289d08428aSSimon Horman 	enum dma_slave_buswidth dma_buswidth;
299d08428aSSimon Horman 	dma_addr_t dma_rx_offset;
30f2218db8SSimon Horman 	unsigned int bus_shift;
319d08428aSSimon Horman 	int scc_offset;
329d08428aSSimon Horman 	struct renesas_sdhi_scc *taps;
339d08428aSSimon Horman 	int taps_num;
34603aa14dSYoshihiro Shimoda 	unsigned int max_blk_count;
35603aa14dSYoshihiro Shimoda 	unsigned short max_segs;
36627151b4SWolfram Sang 	unsigned long sdhi_flags;
379d08428aSSimon Horman };
389d08428aSSimon Horman 
39ce6f92c2SWolfram Sang #define SDHI_CALIB_TABLE_MAX 32
40ce6f92c2SWolfram Sang 
4148c917faSWolfram Sang #define sdhi_has_quirk(p, q) ((p)->quirks && (p)->quirks->q)
4248c917faSWolfram Sang 
437af08206SWolfram Sang struct renesas_sdhi_quirks {
447af08206SWolfram Sang 	bool hs400_disabled;
457af08206SWolfram Sang 	bool hs400_4taps;
46c0a43968SWolfram Sang 	bool fixed_addr_mode;
47bcfa7f15SWolfram Sang 	bool dma_one_rx_only;
4800e8c11cSTakeshi Saito 	bool manual_tap_correction;
49ec9e80aeSWolfram Sang 	bool old_info1_layout;
50a38c078fSTakeshi Saito 	u32 hs400_bad_taps;
51ce6f92c2SWolfram Sang 	const u8 (*hs400_calib_table)[SDHI_CALIB_TABLE_MAX];
527af08206SWolfram Sang };
537af08206SWolfram Sang 
5471b7597cSYoshihiro Shimoda struct renesas_sdhi_of_data_with_quirks {
5571b7597cSYoshihiro Shimoda 	const struct renesas_sdhi_of_data *of_data;
5671b7597cSYoshihiro Shimoda 	const struct renesas_sdhi_quirks *quirks;
5771b7597cSYoshihiro Shimoda };
5871b7597cSYoshihiro Shimoda 
59c330601cSWolfram Sang /* We want both end_flags to be set before we mark DMA as finished */
60ffbace43SWolfram Sang #define SDHI_DMA_END_FLAG_DMA		0
61ffbace43SWolfram Sang #define SDHI_DMA_END_FLAG_ACCESS	1
62c330601cSWolfram Sang 
637f3ea248SWolfram Sang struct renesas_sdhi_dma {
64c330601cSWolfram Sang 	unsigned long end_flags;
65058db286SMasahiro Yamada 	enum dma_slave_buswidth dma_buswidth;
66058db286SMasahiro Yamada 	bool (*filter)(struct dma_chan *chan, void *arg);
67058db286SMasahiro Yamada 	void (*enable)(struct tmio_mmc_host *host, bool enable);
6890d95106SMasahiro Yamada 	struct completion dma_dataend;
6990d95106SMasahiro Yamada 	struct tasklet_struct dma_complete;
70058db286SMasahiro Yamada };
71058db286SMasahiro Yamada 
72058db286SMasahiro Yamada struct renesas_sdhi {
73058db286SMasahiro Yamada 	struct clk *clk;
74bb6d3fa9SWolfram Sang 	struct clk *clkh;
75058db286SMasahiro Yamada 	struct clk *clk_cd;
76058db286SMasahiro Yamada 	struct tmio_mmc_data mmc_data;
777f3ea248SWolfram Sang 	struct renesas_sdhi_dma dma_priv;
787af08206SWolfram Sang 	const struct renesas_sdhi_quirks *quirks;
79058db286SMasahiro Yamada 	struct pinctrl *pinctrl;
80058db286SMasahiro Yamada 	struct pinctrl_state *pins_default, *pins_uhs;
81058db286SMasahiro Yamada 	void __iomem *scc_ctl;
82852d258fSMasahiro Yamada 	u32 scc_tappos;
83f0c8234cSTakeshi Saito 	u32 scc_tappos_hs400;
84ce6f92c2SWolfram Sang 	const u8 *adjust_hs400_calib_table;
85ce6f92c2SWolfram Sang 	bool needs_adjust_hs400;
86b2dd9a13SWolfram Sang 
87b2dd9a13SWolfram Sang 	/* Tuning values: 1 for success, 0 for failure */
88fcc958d6SGeert Uytterhoeven 	DECLARE_BITMAP(taps, BITS_PER_LONG);
895fb6bf51SWolfram Sang 	/* Sampling data comparison: 1 for match, 0 for mismatch */
905fb6bf51SWolfram Sang 	DECLARE_BITMAP(smpcmp, BITS_PER_LONG);
91b2dd9a13SWolfram Sang 	unsigned int tap_num;
9274f6bdb8SWolfram Sang 	unsigned int tap_set;
93b4d86f37SWolfram Sang 
94b4d86f37SWolfram Sang 	struct reset_control *rstc;
95058db286SMasahiro Yamada };
96058db286SMasahiro Yamada 
97058db286SMasahiro Yamada #define host_to_priv(host) \
98058db286SMasahiro Yamada 	container_of((host)->pdata, struct renesas_sdhi, mmc_data)
99058db286SMasahiro Yamada 
1009d08428aSSimon Horman int renesas_sdhi_probe(struct platform_device *pdev,
10171b7597cSYoshihiro Shimoda 		       const struct tmio_mmc_dma_ops *dma_ops,
10271b7597cSYoshihiro Shimoda 		       const struct renesas_sdhi_of_data *of_data,
10371b7597cSYoshihiro Shimoda 		       const struct renesas_sdhi_quirks *quirks);
104*80c602b1SYangtao Li void renesas_sdhi_remove(struct platform_device *pdev);
105c2a96987SSimon Horman #endif
106