summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host/renesas_sdhi.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc/host/renesas_sdhi.h')
-rw-r--r--drivers/mmc/host/renesas_sdhi.h105
1 files changed, 105 insertions, 0 deletions
diff --git a/drivers/mmc/host/renesas_sdhi.h b/drivers/mmc/host/renesas_sdhi.h
new file mode 100644
index 0000000000..c1fb9740ea
--- /dev/null
+++ b/drivers/mmc/host/renesas_sdhi.h
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Renesas Mobile SDHI
+ *
+ * Copyright (C) 2017 Horms Solutions Ltd., Simon Horman
+ * Copyright (C) 2017-19 Renesas Electronics Corporation
+ */
+
+#ifndef RENESAS_SDHI_H
+#define RENESAS_SDHI_H
+
+#include <linux/platform_device.h>
+#include "tmio_mmc.h"
+
+struct renesas_sdhi_scc {
+ unsigned long clk_rate; /* clock rate for SDR104 */
+ u32 tap; /* sampling clock position for SDR104/HS400 (8 TAP) */
+ u32 tap_hs400_4tap; /* sampling clock position for HS400 (4 TAP) */
+};
+
+#define SDHI_FLAG_NEED_CLKH_FALLBACK BIT(0)
+
+struct renesas_sdhi_of_data {
+ unsigned long tmio_flags;
+ u32 tmio_ocr_mask;
+ unsigned long capabilities;
+ unsigned long capabilities2;
+ enum dma_slave_buswidth dma_buswidth;
+ dma_addr_t dma_rx_offset;
+ unsigned int bus_shift;
+ int scc_offset;
+ struct renesas_sdhi_scc *taps;
+ int taps_num;
+ unsigned int max_blk_count;
+ unsigned short max_segs;
+ unsigned long sdhi_flags;
+};
+
+#define SDHI_CALIB_TABLE_MAX 32
+
+#define sdhi_has_quirk(p, q) ((p)->quirks && (p)->quirks->q)
+
+struct renesas_sdhi_quirks {
+ bool hs400_disabled;
+ bool hs400_4taps;
+ bool fixed_addr_mode;
+ bool dma_one_rx_only;
+ bool manual_tap_correction;
+ bool old_info1_layout;
+ u32 hs400_bad_taps;
+ const u8 (*hs400_calib_table)[SDHI_CALIB_TABLE_MAX];
+};
+
+struct renesas_sdhi_of_data_with_quirks {
+ const struct renesas_sdhi_of_data *of_data;
+ const struct renesas_sdhi_quirks *quirks;
+};
+
+/* We want both end_flags to be set before we mark DMA as finished */
+#define SDHI_DMA_END_FLAG_DMA 0
+#define SDHI_DMA_END_FLAG_ACCESS 1
+
+struct renesas_sdhi_dma {
+ unsigned long end_flags;
+ enum dma_slave_buswidth dma_buswidth;
+ bool (*filter)(struct dma_chan *chan, void *arg);
+ void (*enable)(struct tmio_mmc_host *host, bool enable);
+ struct completion dma_dataend;
+ struct tasklet_struct dma_complete;
+};
+
+struct renesas_sdhi {
+ struct clk *clk;
+ struct clk *clkh;
+ struct clk *clk_cd;
+ struct tmio_mmc_data mmc_data;
+ struct renesas_sdhi_dma dma_priv;
+ const struct renesas_sdhi_quirks *quirks;
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pins_default, *pins_uhs;
+ void __iomem *scc_ctl;
+ u32 scc_tappos;
+ u32 scc_tappos_hs400;
+ const u8 *adjust_hs400_calib_table;
+ bool needs_adjust_hs400;
+
+ /* Tuning values: 1 for success, 0 for failure */
+ DECLARE_BITMAP(taps, BITS_PER_LONG);
+ /* Sampling data comparison: 1 for match, 0 for mismatch */
+ DECLARE_BITMAP(smpcmp, BITS_PER_LONG);
+ unsigned int tap_num;
+ unsigned int tap_set;
+
+ struct reset_control *rstc;
+};
+
+#define host_to_priv(host) \
+ container_of((host)->pdata, struct renesas_sdhi, mmc_data)
+
+int renesas_sdhi_probe(struct platform_device *pdev,
+ const struct tmio_mmc_dma_ops *dma_ops,
+ const struct renesas_sdhi_of_data *of_data,
+ const struct renesas_sdhi_quirks *quirks);
+void renesas_sdhi_remove(struct platform_device *pdev);
+#endif