xref: /linux/drivers/net/wireless/morsemicro/mm81x/hw.h (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1*b1906ceaSLachlan Hodges /* SPDX-License-Identifier: GPL-2.0-only */
2*b1906ceaSLachlan Hodges /*
3*b1906ceaSLachlan Hodges  * Copyright (c) 2017-2026 Morse Micro
4*b1906ceaSLachlan Hodges  */
5*b1906ceaSLachlan Hodges 
6*b1906ceaSLachlan Hodges #ifndef _MM81X_HW_H_
7*b1906ceaSLachlan Hodges #define _MM81X_HW_H_
8*b1906ceaSLachlan Hodges 
9*b1906ceaSLachlan Hodges #include <linux/gpio/consumer.h>
10*b1906ceaSLachlan Hodges #include "core.h"
11*b1906ceaSLachlan Hodges #include "command_defs.h"
12*b1906ceaSLachlan Hodges 
13*b1906ceaSLachlan Hodges /* This should be at a fixed location for a family of chipset */
14*b1906ceaSLachlan Hodges #define MM8108_REG_CHIP_ID 0x00002d20
15*b1906ceaSLachlan Hodges 
16*b1906ceaSLachlan Hodges #define MM81X_SDIO_RW_ADDR_BOUNDARY_MASK ((u32)0xFFFF0000)
17*b1906ceaSLachlan Hodges 
18*b1906ceaSLachlan Hodges #define MM81X_CONFIG_ACCESS_1BYTE 0
19*b1906ceaSLachlan Hodges #define MM81X_CONFIG_ACCESS_2BYTE 1
20*b1906ceaSLachlan Hodges #define MM81X_CONFIG_ACCESS_4BYTE 2
21*b1906ceaSLachlan Hodges 
22*b1906ceaSLachlan Hodges #define MM81X_REG_TRGR_BASE(mors) ((mors)->regs->trgr_base_address)
23*b1906ceaSLachlan Hodges #define MM81X_REG_TRGR1_STS(mors) (MM81X_REG_TRGR_BASE(mors) + 0x00)
24*b1906ceaSLachlan Hodges #define MM81X_REG_TRGR1_SET(mors) (MM81X_REG_TRGR_BASE(mors) + 0x04)
25*b1906ceaSLachlan Hodges #define MM81X_REG_TRGR1_CLR(mors) (MM81X_REG_TRGR_BASE(mors) + 0x08)
26*b1906ceaSLachlan Hodges #define MM81X_REG_TRGR1_EN(mors) (MM81X_REG_TRGR_BASE(mors) + 0x0C)
27*b1906ceaSLachlan Hodges #define MM81X_REG_TRGR2_STS(mors) (MM81X_REG_TRGR_BASE(mors) + 0x10)
28*b1906ceaSLachlan Hodges #define MM81X_REG_TRGR2_SET(mors) (MM81X_REG_TRGR_BASE(mors) + 0x14)
29*b1906ceaSLachlan Hodges #define MM81X_REG_TRGR2_CLR(mors) (MM81X_REG_TRGR_BASE(mors) + 0x18)
30*b1906ceaSLachlan Hodges #define MM81X_REG_TRGR2_EN(mors) (MM81X_REG_TRGR_BASE(mors) + 0x1C)
31*b1906ceaSLachlan Hodges 
32*b1906ceaSLachlan Hodges #define MM81X_REG_INT_BASE(mors) ((mors)->regs->irq_base_address)
33*b1906ceaSLachlan Hodges #define MM81X_REG_INT1_STS(mors) (MM81X_REG_INT_BASE(mors) + 0x00)
34*b1906ceaSLachlan Hodges #define MM81X_REG_INT1_SET(mors) (MM81X_REG_INT_BASE(mors) + 0x04)
35*b1906ceaSLachlan Hodges #define MM81X_REG_INT1_CLR(mors) (MM81X_REG_INT_BASE(mors) + 0x08)
36*b1906ceaSLachlan Hodges #define MM81X_REG_INT1_EN(mors) (MM81X_REG_INT_BASE(mors) + 0x0C)
37*b1906ceaSLachlan Hodges #define MM81X_REG_INT2_STS(mors) (MM81X_REG_INT_BASE(mors) + 0x10)
38*b1906ceaSLachlan Hodges #define MM81X_REG_INT2_SET(mors) (MM81X_REG_INT_BASE(mors) + 0x14)
39*b1906ceaSLachlan Hodges #define MM81X_REG_INT2_CLR(mors) (MM81X_REG_INT_BASE(mors) + 0x18)
40*b1906ceaSLachlan Hodges #define MM81X_REG_INT2_EN(mors) (MM81X_REG_INT_BASE(mors) + 0x1C)
41*b1906ceaSLachlan Hodges 
42*b1906ceaSLachlan Hodges #define MM81X_REG_CHIP_ID(mors) ((mors)->regs->chip_id_address)
43*b1906ceaSLachlan Hodges 
44*b1906ceaSLachlan Hodges #define MM81X_REG_MSI(mors) ((mors)->regs->msi_address)
45*b1906ceaSLachlan Hodges #define MM81X_REG_MSI_HOST_INT(mors) ((mors)->regs->msi_value)
46*b1906ceaSLachlan Hodges 
47*b1906ceaSLachlan Hodges #define MM81X_REG_HOST_MAGIC_VALUE(mors) ((mors)->regs->magic_num_value)
48*b1906ceaSLachlan Hodges 
49*b1906ceaSLachlan Hodges #define MM81X_REG_RESET(mors) ((mors)->regs->cpu_reset_address)
50*b1906ceaSLachlan Hodges #define MM81X_REG_RESET_VALUE(mors) ((mors)->regs->cpu_reset_value)
51*b1906ceaSLachlan Hodges 
52*b1906ceaSLachlan Hodges #define MM81X_REG_HOST_MANIFEST_PTR(mors) ((mors)->regs->manifest_ptr_address)
53*b1906ceaSLachlan Hodges 
54*b1906ceaSLachlan Hodges #define MM81X_REG_EARLY_CLK_CTRL_VALUE(mors) \
55*b1906ceaSLachlan Hodges 	((mors)->regs->early_clk_ctrl_value)
56*b1906ceaSLachlan Hodges 
57*b1906ceaSLachlan Hodges #define MM81X_REG_CLK_CTRL(mors) ((mors)->regs->clk_ctrl_address)
58*b1906ceaSLachlan Hodges #define MM81X_REG_CLK_CTRL_VALUE(mors) ((mors)->regs->clk_ctrl_value)
59*b1906ceaSLachlan Hodges 
60*b1906ceaSLachlan Hodges #define MM81X_REG_BOOT_ADDR(mors) ((mors)->regs->boot_address)
61*b1906ceaSLachlan Hodges #define MM81X_REG_BOOT_ADDR_VALUE(mors) ((mors)->regs->boot_value)
62*b1906ceaSLachlan Hodges 
63*b1906ceaSLachlan Hodges #define MM81X_REG_AON_ADDR(mors) ((mors)->regs->aon)
64*b1906ceaSLachlan Hodges #define MM81X_REG_AON_COUNT(mors) ((mors)->regs->aon_count)
65*b1906ceaSLachlan Hodges #define MM81X_REG_AON_LATCH_ADDR(mors) ((mors)->regs->aon_latch)
66*b1906ceaSLachlan Hodges #define MM81X_REG_AON_LATCH_MASK(mors) ((mors)->regs->aon_latch_mask)
67*b1906ceaSLachlan Hodges #define MM81X_REG_AON_USB_RESET(mors) ((mors)->regs->aon_reset_usb_value)
68*b1906ceaSLachlan Hodges 
69*b1906ceaSLachlan Hodges /* Bit 17 to 24 reserved for the beacon VIF 0 to 7 interrupts */
70*b1906ceaSLachlan Hodges #define MM81X_INT_BEACON_VIF_MASK_ALL (GENMASK(24, 17))
71*b1906ceaSLachlan Hodges #define MM81X_INT_BEACON_BASE_NUM (17)
72*b1906ceaSLachlan Hodges 
73*b1906ceaSLachlan Hodges /* PV0 NDP probe interrupts (VIF 0 and 1). */
74*b1906ceaSLachlan Hodges #define MM81X_INT_NDP_PROBE_REQ_PV0_VIF_MASK_ALL (GENMASK(26, 25))
75*b1906ceaSLachlan Hodges #define MM81X_INT_NDP_PROBE_REQ_PV0_BASE_NUM (25)
76*b1906ceaSLachlan Hodges 
77*b1906ceaSLachlan Hodges /* Bit 27 Chip to Host stop notify */
78*b1906ceaSLachlan Hodges #define MM81X_INT_HW_STOP_NOTIFICATION_NUM (27)
79*b1906ceaSLachlan Hodges #define MM81X_INT_HW_STOP_NOTIFICATION BIT(MM81X_INT_HW_STOP_NOTIFICATION_NUM)
80*b1906ceaSLachlan Hodges 
81*b1906ceaSLachlan Hodges /* Chip IDs */
82*b1906ceaSLachlan Hodges #define CHIP_ID_MM8108 0x809
83*b1906ceaSLachlan Hodges 
84*b1906ceaSLachlan Hodges /*
85*b1906ceaSLachlan Hodges  * Minimum time we must wait between attempting to reload the HW after a
86*b1906ceaSLachlan Hodges  * stop notification
87*b1906ceaSLachlan Hodges  */
88*b1906ceaSLachlan Hodges #define HW_RELOAD_AFTER_STOP_WINDOW 5
89*b1906ceaSLachlan Hodges 
90*b1906ceaSLachlan Hodges enum host_table_firmware_flags {
91*b1906ceaSLachlan Hodges 	MM81X_FW_FLAGS_SUPPORT_S1G = BIT(0),
92*b1906ceaSLachlan Hodges 	MM81X_FW_FLAGS_BUSY_ACTIVE_LOW = BIT(1),
93*b1906ceaSLachlan Hodges 	MM81X_FW_FLAGS_REPORTS_TX_BEACON_COMPLETION = BIT(2),
94*b1906ceaSLachlan Hodges 	MM81X_FW_FLAGS_SUPPORT_HW_SCAN = BIT(3),
95*b1906ceaSLachlan Hodges 	MM81X_FW_FLAGS_SUPPORT_CHIP_HALT_IRQ = BIT(4),
96*b1906ceaSLachlan Hodges };
97*b1906ceaSLachlan Hodges 
98*b1906ceaSLachlan Hodges struct host_table {
99*b1906ceaSLachlan Hodges 	__le32 magic_number;
100*b1906ceaSLachlan Hodges 	__le32 fw_version_number;
101*b1906ceaSLachlan Hodges 	__le32 host_flags;
102*b1906ceaSLachlan Hodges 	__le32 fw_flags;
103*b1906ceaSLachlan Hodges 	__le32 memcmd_cmd_addr;
104*b1906ceaSLachlan Hodges 	__le32 memcmd_resp_addr;
105*b1906ceaSLachlan Hodges 	__le32 ext_host_tbl_addr;
106*b1906ceaSLachlan Hodges } __packed;
107*b1906ceaSLachlan Hodges 
108*b1906ceaSLachlan Hodges struct mm81x_regs {
109*b1906ceaSLachlan Hodges 	u32 chip_id_address;
110*b1906ceaSLachlan Hodges 	u32 irq_base_address;
111*b1906ceaSLachlan Hodges 	u32 trgr_base_address;
112*b1906ceaSLachlan Hodges 	u32 cpu_reset_address;
113*b1906ceaSLachlan Hodges 	u32 cpu_reset_value;
114*b1906ceaSLachlan Hodges 	u32 msi_address;
115*b1906ceaSLachlan Hodges 	u32 msi_value;
116*b1906ceaSLachlan Hodges 	u32 manifest_ptr_address;
117*b1906ceaSLachlan Hodges 	u32 magic_num_value;
118*b1906ceaSLachlan Hodges 	u32 clk_ctrl_address;
119*b1906ceaSLachlan Hodges 	u32 clk_ctrl_value;
120*b1906ceaSLachlan Hodges 	u32 early_clk_ctrl_value;
121*b1906ceaSLachlan Hodges 	u32 boot_address;
122*b1906ceaSLachlan Hodges 	u32 boot_value;
123*b1906ceaSLachlan Hodges 	u32 pager_base_address;
124*b1906ceaSLachlan Hodges 	u32 aon_latch;
125*b1906ceaSLachlan Hodges 	u32 aon_latch_mask;
126*b1906ceaSLachlan Hodges 	u32 aon_reset_usb_value;
127*b1906ceaSLachlan Hodges 	u32 aon;
128*b1906ceaSLachlan Hodges 	u8 aon_count;
129*b1906ceaSLachlan Hodges };
130*b1906ceaSLachlan Hodges 
131*b1906ceaSLachlan Hodges int mm81x_hw_otp_get_board_type(struct mm81x *mors);
132*b1906ceaSLachlan Hodges bool mm81x_hw_otp_valid_board_type(u32 board_type);
133*b1906ceaSLachlan Hodges int mm81x_hw_otp_get_mac_addr(struct mm81x *mors);
134*b1906ceaSLachlan Hodges 
135*b1906ceaSLachlan Hodges void mm81x_hw_irq_enable(struct mm81x *mors, u32 irq, bool enable);
136*b1906ceaSLachlan Hodges int mm81x_hw_irq_handle(struct mm81x *mors);
137*b1906ceaSLachlan Hodges void mm81x_hw_irq_clear(struct mm81x *mors);
138*b1906ceaSLachlan Hodges void mm81x_hw_toggle_aon_latch(struct mm81x *mors);
139*b1906ceaSLachlan Hodges void mm81x_hw_enable_burst_mode(struct mm81x *mors, const u8 burst_mode);
140*b1906ceaSLachlan Hodges int mm81x_hw_digital_reset(struct mm81x *mors);
141*b1906ceaSLachlan Hodges void mm81x_hw_pre_firmware_ndr_hook(struct mm81x *mors);
142*b1906ceaSLachlan Hodges void mm81x_hw_post_firmware_ndr_hook(struct mm81x *mors);
143*b1906ceaSLachlan Hodges 
144*b1906ceaSLachlan Hodges enum sdio_burst_mode {
145*b1906ceaSLachlan Hodges 	SDIO_WORD_BURST_DISABLE =
146*b1906ceaSLachlan Hodges 		0, /* Intentionally duplicate to make it clear it's disabled */
147*b1906ceaSLachlan Hodges 	SDIO_WORD_BURST_SIZE_0 = 0, /* 000: no bursting (single 32bit word) */
148*b1906ceaSLachlan Hodges 	SDIO_WORD_BURST_SIZE_2 = 1, /* 001: bursts of 2 words */
149*b1906ceaSLachlan Hodges 	SDIO_WORD_BURST_SIZE_4 = 2, /* 010: bursts of 4 words */
150*b1906ceaSLachlan Hodges 	SDIO_WORD_BURST_SIZE_8 = 3, /* 011: bursts of 8 words */
151*b1906ceaSLachlan Hodges 	SDIO_WORD_BURST_SIZE_16 = 4, /* 100: bursts of 16 words */
152*b1906ceaSLachlan Hodges 	SDIO_WORD_BURST_MASK = 7,
153*b1906ceaSLachlan Hodges };
154*b1906ceaSLachlan Hodges 
155*b1906ceaSLachlan Hodges extern const struct mm81x_regs mm8108_regs;
156*b1906ceaSLachlan Hodges 
157*b1906ceaSLachlan Hodges void mm81x_hw_enable_stop_notifications(struct mm81x *mors, bool enable);
158*b1906ceaSLachlan Hodges 
159*b1906ceaSLachlan Hodges #endif /* !_MM81X_HW_H_ */
160