xref: /freebsd/sys/contrib/dev/rtw88/sdio.h (revision 90aac0d8)
190aac0d8SBjoern A. Zeeb /* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
290aac0d8SBjoern A. Zeeb /* Copyright (C) 2021 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
390aac0d8SBjoern A. Zeeb  * Copyright (C) 2021 Jernej Skrabec <jernej.skrabec@gmail.com>
490aac0d8SBjoern A. Zeeb  */
590aac0d8SBjoern A. Zeeb 
690aac0d8SBjoern A. Zeeb #ifndef __REG_SDIO_H_
790aac0d8SBjoern A. Zeeb #define __REG_SDIO_H_
890aac0d8SBjoern A. Zeeb 
990aac0d8SBjoern A. Zeeb /* I/O bus domain address mapping */
1090aac0d8SBjoern A. Zeeb #define SDIO_LOCAL_OFFSET			0x10250000
1190aac0d8SBjoern A. Zeeb #define WLAN_IOREG_OFFSET			0x10260000
1290aac0d8SBjoern A. Zeeb #define FIRMWARE_FIFO_OFFSET			0x10270000
1390aac0d8SBjoern A. Zeeb #define TX_HIQ_OFFSET				0x10310000
1490aac0d8SBjoern A. Zeeb #define TX_MIQ_OFFSET				0x10320000
1590aac0d8SBjoern A. Zeeb #define TX_LOQ_OFFSET				0x10330000
1690aac0d8SBjoern A. Zeeb #define TX_EPQ_OFFSET				0x10350000
1790aac0d8SBjoern A. Zeeb #define RX_RX0FF_OFFSET				0x10340000
1890aac0d8SBjoern A. Zeeb 
1990aac0d8SBjoern A. Zeeb #define RTW_SDIO_BUS_MSK			0xffff0000
2090aac0d8SBjoern A. Zeeb #define SDIO_LOCAL_REG_MSK			0x00000fff
2190aac0d8SBjoern A. Zeeb #define WLAN_IOREG_REG_MSK			0x0000ffff
2290aac0d8SBjoern A. Zeeb 
2390aac0d8SBjoern A. Zeeb /* SDIO Tx Control */
2490aac0d8SBjoern A. Zeeb #define REG_SDIO_TX_CTRL			(SDIO_LOCAL_OFFSET + 0x0000)
2590aac0d8SBjoern A. Zeeb 
2690aac0d8SBjoern A. Zeeb /*SDIO status timeout*/
2790aac0d8SBjoern A. Zeeb #define REG_SDIO_TIMEOUT			(SDIO_LOCAL_OFFSET + 0x0002)
2890aac0d8SBjoern A. Zeeb 
2990aac0d8SBjoern A. Zeeb /* SDIO Host Interrupt Mask */
3090aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR				(SDIO_LOCAL_OFFSET + 0x0014)
3190aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_RX_REQUEST		BIT(0)
3290aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_AVAL			BIT(1)
3390aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_TXERR			BIT(2)
3490aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_RXERR			BIT(3)
3590aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_TXFOVW			BIT(4)
3690aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_RXFOVW			BIT(5)
3790aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_TXBCNOK			BIT(6)
3890aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_TXBCNERR			BIT(7)
3990aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_BCNERLY_INT		BIT(16)
4090aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_C2HCMD			BIT(17)
4190aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_CPWM1			BIT(18)
4290aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_CPWM2			BIT(19)
4390aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_HSISR_IND			BIT(20)
4490aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_GTINT3_IND		BIT(21)
4590aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_GTINT4_IND		BIT(22)
4690aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_PSTIMEOUT			BIT(23)
4790aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_OCPINT			BIT(24)
4890aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_ATIMEND			BIT(25)
4990aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_ATIMEND_E			BIT(26)
5090aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_CTWEND			BIT(27)
5190aac0d8SBjoern A. Zeeb /* the following two are RTL8188 SDIO Specific */
5290aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_MCU_ERR			BIT(28)
5390aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_TSF_BIT32_TOGGLE		BIT(29)
5490aac0d8SBjoern A. Zeeb 
5590aac0d8SBjoern A. Zeeb /* SDIO Host Interrupt Service Routine */
5690aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR				(SDIO_LOCAL_OFFSET + 0x0018)
5790aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_RX_REQUEST		BIT(0)
5890aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_AVAL			BIT(1)
5990aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_TXERR			BIT(2)
6090aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_RXERR			BIT(3)
6190aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_TXFOVW			BIT(4)
6290aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_RXFOVW			BIT(5)
6390aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_TXBCNOK			BIT(6)
6490aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_TXBCNERR			BIT(7)
6590aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_BCNERLY_INT		BIT(16)
6690aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_C2HCMD			BIT(17)
6790aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_CPWM1			BIT(18)
6890aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_CPWM2			BIT(19)
6990aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_HSISR_IND			BIT(20)
7090aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_GTINT3_IND		BIT(21)
7190aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_GTINT4_IND		BIT(22)
7290aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_PSTIMEOUT			BIT(23)
7390aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_OCPINT			BIT(24)
7490aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_ATIMEND			BIT(25)
7590aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_ATIMEND_E			BIT(26)
7690aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_CTWEND			BIT(27)
7790aac0d8SBjoern A. Zeeb /* the following two are RTL8188 SDIO Specific */
7890aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_MCU_ERR			BIT(28)
7990aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_TSF_BIT32_TOGGLE		BIT(29)
8090aac0d8SBjoern A. Zeeb 
8190aac0d8SBjoern A. Zeeb /* HCI Current Power Mode */
8290aac0d8SBjoern A. Zeeb #define REG_SDIO_HCPWM				(SDIO_LOCAL_OFFSET + 0x0019)
8390aac0d8SBjoern A. Zeeb /* RXDMA Request Length */
8490aac0d8SBjoern A. Zeeb #define REG_SDIO_RX0_REQ_LEN			(SDIO_LOCAL_OFFSET + 0x001C)
8590aac0d8SBjoern A. Zeeb /* OQT Free Page */
8690aac0d8SBjoern A. Zeeb #define REG_SDIO_OQT_FREE_PG			(SDIO_LOCAL_OFFSET + 0x001E)
8790aac0d8SBjoern A. Zeeb /* Free Tx Buffer Page */
8890aac0d8SBjoern A. Zeeb #define REG_SDIO_FREE_TXPG			(SDIO_LOCAL_OFFSET + 0x0020)
8990aac0d8SBjoern A. Zeeb /* HCI Current Power Mode 1 */
9090aac0d8SBjoern A. Zeeb #define REG_SDIO_HCPWM1				(SDIO_LOCAL_OFFSET + 0x0024)
9190aac0d8SBjoern A. Zeeb /* HCI Current Power Mode 2 */
9290aac0d8SBjoern A. Zeeb #define REG_SDIO_HCPWM2				(SDIO_LOCAL_OFFSET + 0x0026)
9390aac0d8SBjoern A. Zeeb /* Free Tx Page Sequence */
9490aac0d8SBjoern A. Zeeb #define REG_SDIO_FREE_TXPG_SEQ			(SDIO_LOCAL_OFFSET + 0x0028)
9590aac0d8SBjoern A. Zeeb /* HTSF Information */
9690aac0d8SBjoern A. Zeeb #define REG_SDIO_HTSFR_INFO			(SDIO_LOCAL_OFFSET + 0x0030)
9790aac0d8SBjoern A. Zeeb #define REG_SDIO_HCPWM1_V2			(SDIO_LOCAL_OFFSET + 0x0038)
9890aac0d8SBjoern A. Zeeb /* H2C */
9990aac0d8SBjoern A. Zeeb #define REG_SDIO_H2C				(SDIO_LOCAL_OFFSET + 0x0060)
10090aac0d8SBjoern A. Zeeb /* HCI Request Power Mode 1 */
10190aac0d8SBjoern A. Zeeb #define REG_SDIO_HRPWM1				(SDIO_LOCAL_OFFSET + 0x0080)
10290aac0d8SBjoern A. Zeeb /* HCI Request Power Mode 2 */
10390aac0d8SBjoern A. Zeeb #define REG_SDIO_HRPWM2				(SDIO_LOCAL_OFFSET + 0x0082)
10490aac0d8SBjoern A. Zeeb /* HCI Power Save Clock */
10590aac0d8SBjoern A. Zeeb #define REG_SDIO_HPS_CLKR			(SDIO_LOCAL_OFFSET + 0x0084)
10690aac0d8SBjoern A. Zeeb /* SDIO HCI Suspend Control */
10790aac0d8SBjoern A. Zeeb #define REG_SDIO_HSUS_CTRL			(SDIO_LOCAL_OFFSET + 0x0086)
10890aac0d8SBjoern A. Zeeb #define BIT_HCI_SUS_REQ				BIT(0)
10990aac0d8SBjoern A. Zeeb #define BIT_HCI_RESUME_RDY			BIT(1)
11090aac0d8SBjoern A. Zeeb /* SDIO Host Extension Interrupt Mask Always */
11190aac0d8SBjoern A. Zeeb #define REG_SDIO_HIMR_ON			(SDIO_LOCAL_OFFSET + 0x0090)
11290aac0d8SBjoern A. Zeeb /* SDIO Host Extension Interrupt Status Always */
11390aac0d8SBjoern A. Zeeb #define REG_SDIO_HISR_ON			(SDIO_LOCAL_OFFSET + 0x0091)
11490aac0d8SBjoern A. Zeeb 
11590aac0d8SBjoern A. Zeeb #define REG_SDIO_INDIRECT_REG_CFG		(SDIO_LOCAL_OFFSET + 0x0040)
11690aac0d8SBjoern A. Zeeb #define BIT_SDIO_INDIRECT_REG_CFG_WORD		BIT(16)
11790aac0d8SBjoern A. Zeeb #define BIT_SDIO_INDIRECT_REG_CFG_DWORD		BIT(17)
11890aac0d8SBjoern A. Zeeb #define BIT_SDIO_INDIRECT_REG_CFG_WRITE		BIT(18)
11990aac0d8SBjoern A. Zeeb #define BIT_SDIO_INDIRECT_REG_CFG_READ		BIT(19)
12090aac0d8SBjoern A. Zeeb #define BIT_SDIO_INDIRECT_REG_CFG_UNK20		BIT(20)
12190aac0d8SBjoern A. Zeeb #define REG_SDIO_INDIRECT_REG_DATA		(SDIO_LOCAL_OFFSET + 0x0044)
12290aac0d8SBjoern A. Zeeb 
12390aac0d8SBjoern A. Zeeb /* Sdio Address for SDIO Local Reg, TRX FIFO, MAC Reg */
12490aac0d8SBjoern A. Zeeb #define REG_SDIO_CMD_ADDR_MSK			GENMASK(16, 13)
12590aac0d8SBjoern A. Zeeb #define REG_SDIO_CMD_ADDR_SDIO_REG		0
12690aac0d8SBjoern A. Zeeb #define REG_SDIO_CMD_ADDR_MAC_REG		8
12790aac0d8SBjoern A. Zeeb #define REG_SDIO_CMD_ADDR_TXFF_HIGH		4
12890aac0d8SBjoern A. Zeeb #define REG_SDIO_CMD_ADDR_TXFF_LOW		6
12990aac0d8SBjoern A. Zeeb #define REG_SDIO_CMD_ADDR_TXFF_NORMAL		5
13090aac0d8SBjoern A. Zeeb #define REG_SDIO_CMD_ADDR_TXFF_EXTRA		7
13190aac0d8SBjoern A. Zeeb #define REG_SDIO_CMD_ADDR_RXFF			7
13290aac0d8SBjoern A. Zeeb 
13390aac0d8SBjoern A. Zeeb #define RTW_SDIO_BLOCK_SIZE			512
13490aac0d8SBjoern A. Zeeb #define RTW_SDIO_ADDR_RX_RX0FF_GEN(_id)		(0x0e000 | ((_id) & 0x3))
13590aac0d8SBjoern A. Zeeb 
13690aac0d8SBjoern A. Zeeb #define RTW_SDIO_DATA_PTR_ALIGN			8
13790aac0d8SBjoern A. Zeeb 
13890aac0d8SBjoern A. Zeeb struct sdio_func;
13990aac0d8SBjoern A. Zeeb struct sdio_device_id;
14090aac0d8SBjoern A. Zeeb 
14190aac0d8SBjoern A. Zeeb struct rtw_sdio_tx_data {
14290aac0d8SBjoern A. Zeeb 	u8 sn;
14390aac0d8SBjoern A. Zeeb };
14490aac0d8SBjoern A. Zeeb 
14590aac0d8SBjoern A. Zeeb struct rtw_sdio_work_data {
14690aac0d8SBjoern A. Zeeb 	struct work_struct work;
14790aac0d8SBjoern A. Zeeb 	struct rtw_dev *rtwdev;
14890aac0d8SBjoern A. Zeeb };
14990aac0d8SBjoern A. Zeeb 
15090aac0d8SBjoern A. Zeeb struct rtw_sdio {
15190aac0d8SBjoern A. Zeeb 	struct sdio_func *sdio_func;
15290aac0d8SBjoern A. Zeeb 
15390aac0d8SBjoern A. Zeeb 	u32 irq_mask;
15490aac0d8SBjoern A. Zeeb 	u8 rx_addr;
15590aac0d8SBjoern A. Zeeb 	bool sdio3_bus_mode;
15690aac0d8SBjoern A. Zeeb 
15790aac0d8SBjoern A. Zeeb 	void *irq_thread;
15890aac0d8SBjoern A. Zeeb 
15990aac0d8SBjoern A. Zeeb 	struct workqueue_struct *txwq;
16090aac0d8SBjoern A. Zeeb 	struct rtw_sdio_work_data *tx_handler_data;
16190aac0d8SBjoern A. Zeeb 	struct sk_buff_head tx_queue[RTK_MAX_TX_QUEUE_NUM];
16290aac0d8SBjoern A. Zeeb };
16390aac0d8SBjoern A. Zeeb 
16490aac0d8SBjoern A. Zeeb extern const struct dev_pm_ops rtw_sdio_pm_ops;
16590aac0d8SBjoern A. Zeeb 
16690aac0d8SBjoern A. Zeeb int rtw_sdio_probe(struct sdio_func *sdio_func,
16790aac0d8SBjoern A. Zeeb 		   const struct sdio_device_id *id);
16890aac0d8SBjoern A. Zeeb void rtw_sdio_remove(struct sdio_func *sdio_func);
16990aac0d8SBjoern A. Zeeb void rtw_sdio_shutdown(struct device *dev);
17090aac0d8SBjoern A. Zeeb 
rtw_sdio_is_sdio30_supported(struct rtw_dev * rtwdev)17190aac0d8SBjoern A. Zeeb static inline bool rtw_sdio_is_sdio30_supported(struct rtw_dev *rtwdev)
17290aac0d8SBjoern A. Zeeb {
17390aac0d8SBjoern A. Zeeb 	struct rtw_sdio *rtwsdio = (struct rtw_sdio *)rtwdev->priv;
17490aac0d8SBjoern A. Zeeb 
17590aac0d8SBjoern A. Zeeb 	return rtwsdio->sdio3_bus_mode;
17690aac0d8SBjoern A. Zeeb }
17790aac0d8SBjoern A. Zeeb 
17890aac0d8SBjoern A. Zeeb #endif
179