152fa7bf9SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2f844a0eaSJeff Kirsher /*
32732ba56SRasesh Mody  * Linux network driver for QLogic BR-series Converged Network Adapter.
4f844a0eaSJeff Kirsher  */
5f844a0eaSJeff Kirsher /*
62732ba56SRasesh Mody  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
72732ba56SRasesh Mody  * Copyright (c) 2014-2015 QLogic Corporation
8f844a0eaSJeff Kirsher  * All rights reserved
92732ba56SRasesh Mody  * www.qlogic.com
10f844a0eaSJeff Kirsher  */
11f844a0eaSJeff Kirsher 
12f844a0eaSJeff Kirsher #include "bfa_ioc.h"
13f844a0eaSJeff Kirsher #include "cna.h"
14f844a0eaSJeff Kirsher #include "bfi.h"
15f844a0eaSJeff Kirsher #include "bfi_reg.h"
16f844a0eaSJeff Kirsher #include "bfa_defs.h"
17f844a0eaSJeff Kirsher 
188e8942b1SIvan Vecera #define bfa_ioc_ct_sync_pos(__ioc)	BIT(bfa_ioc_pcifn(__ioc))
19f844a0eaSJeff Kirsher #define BFA_IOC_SYNC_REQD_SH		16
20f844a0eaSJeff Kirsher #define bfa_ioc_ct_get_sync_ackd(__val) (__val & 0x0000ffff)
21f844a0eaSJeff Kirsher #define bfa_ioc_ct_clear_sync_ackd(__val) (__val & 0xffff0000)
22f844a0eaSJeff Kirsher #define bfa_ioc_ct_get_sync_reqd(__val) (__val >> BFA_IOC_SYNC_REQD_SH)
23f844a0eaSJeff Kirsher #define bfa_ioc_ct_sync_reqd_pos(__ioc) \
24f844a0eaSJeff Kirsher 		(bfa_ioc_ct_sync_pos(__ioc) << BFA_IOC_SYNC_REQD_SH)
25f844a0eaSJeff Kirsher 
26f844a0eaSJeff Kirsher /*
27f844a0eaSJeff Kirsher  * forward declarations
28f844a0eaSJeff Kirsher  */
29f844a0eaSJeff Kirsher static bool bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc);
30f844a0eaSJeff Kirsher static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc);
31f844a0eaSJeff Kirsher static void bfa_ioc_ct_reg_init(struct bfa_ioc *ioc);
32be3a84d1SRasesh Mody static void bfa_ioc_ct2_reg_init(struct bfa_ioc *ioc);
33f844a0eaSJeff Kirsher static void bfa_ioc_ct_map_port(struct bfa_ioc *ioc);
34be3a84d1SRasesh Mody static void bfa_ioc_ct2_map_port(struct bfa_ioc *ioc);
35f844a0eaSJeff Kirsher static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix);
36f844a0eaSJeff Kirsher static void bfa_ioc_ct_notify_fail(struct bfa_ioc *ioc);
37f844a0eaSJeff Kirsher static void bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc);
38f844a0eaSJeff Kirsher static bool bfa_ioc_ct_sync_start(struct bfa_ioc *ioc);
39f844a0eaSJeff Kirsher static void bfa_ioc_ct_sync_join(struct bfa_ioc *ioc);
40f844a0eaSJeff Kirsher static void bfa_ioc_ct_sync_leave(struct bfa_ioc *ioc);
41f844a0eaSJeff Kirsher static void bfa_ioc_ct_sync_ack(struct bfa_ioc *ioc);
42f844a0eaSJeff Kirsher static bool bfa_ioc_ct_sync_complete(struct bfa_ioc *ioc);
4341ed903aSRasesh Mody static void bfa_ioc_ct_set_cur_ioc_fwstate(
4441ed903aSRasesh Mody 			struct bfa_ioc *ioc, enum bfi_ioc_state fwstate);
4541ed903aSRasesh Mody static enum bfi_ioc_state bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc *ioc);
4641ed903aSRasesh Mody static void bfa_ioc_ct_set_alt_ioc_fwstate(
4741ed903aSRasesh Mody 			struct bfa_ioc *ioc, enum bfi_ioc_state fwstate);
4841ed903aSRasesh Mody static enum bfi_ioc_state bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc *ioc);
49078086f3SRasesh Mody static enum bfa_status bfa_ioc_ct_pll_init(void __iomem *rb,
50078086f3SRasesh Mody 				enum bfi_asic_mode asic_mode);
51be3a84d1SRasesh Mody static enum bfa_status bfa_ioc_ct2_pll_init(void __iomem *rb,
52be3a84d1SRasesh Mody 				enum bfi_asic_mode asic_mode);
53be3a84d1SRasesh Mody static bool bfa_ioc_ct2_lpu_read_stat(struct bfa_ioc *ioc);
54f844a0eaSJeff Kirsher 
55d91d25d5Sstephen hemminger static const struct bfa_ioc_hwif nw_hwif_ct = {
56d91d25d5Sstephen hemminger 	.ioc_pll_init	     = bfa_ioc_ct_pll_init,
57d91d25d5Sstephen hemminger 	.ioc_firmware_lock   = bfa_ioc_ct_firmware_lock,
58d91d25d5Sstephen hemminger 	.ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock,
59d91d25d5Sstephen hemminger 	.ioc_reg_init	     = bfa_ioc_ct_reg_init,
60d91d25d5Sstephen hemminger 	.ioc_map_port	     = bfa_ioc_ct_map_port,
61d91d25d5Sstephen hemminger 	.ioc_isr_mode_set    = bfa_ioc_ct_isr_mode_set,
62d91d25d5Sstephen hemminger 	.ioc_notify_fail     = bfa_ioc_ct_notify_fail,
63d91d25d5Sstephen hemminger 	.ioc_ownership_reset = bfa_ioc_ct_ownership_reset,
64d91d25d5Sstephen hemminger 	.ioc_sync_start      = bfa_ioc_ct_sync_start,
65d91d25d5Sstephen hemminger 	.ioc_sync_join       = bfa_ioc_ct_sync_join,
66d91d25d5Sstephen hemminger 	.ioc_sync_leave	     = bfa_ioc_ct_sync_leave,
67d91d25d5Sstephen hemminger 	.ioc_sync_ack	     = bfa_ioc_ct_sync_ack,
68d91d25d5Sstephen hemminger 	.ioc_sync_complete   = bfa_ioc_ct_sync_complete,
6941ed903aSRasesh Mody 	.ioc_set_fwstate     = bfa_ioc_ct_set_cur_ioc_fwstate,
7041ed903aSRasesh Mody 	.ioc_get_fwstate     = bfa_ioc_ct_get_cur_ioc_fwstate,
7141ed903aSRasesh Mody 	.ioc_set_alt_fwstate     = bfa_ioc_ct_set_alt_ioc_fwstate,
7241ed903aSRasesh Mody 	.ioc_get_alt_fwstate     = bfa_ioc_ct_get_alt_ioc_fwstate,
73d91d25d5Sstephen hemminger };
74f844a0eaSJeff Kirsher 
75be3a84d1SRasesh Mody static const struct bfa_ioc_hwif nw_hwif_ct2 = {
76be3a84d1SRasesh Mody 	.ioc_pll_init	     = bfa_ioc_ct2_pll_init,
77be3a84d1SRasesh Mody 	.ioc_firmware_lock   = bfa_ioc_ct_firmware_lock,
78be3a84d1SRasesh Mody 	.ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock,
79be3a84d1SRasesh Mody 	.ioc_reg_init	     = bfa_ioc_ct2_reg_init,
80be3a84d1SRasesh Mody 	.ioc_map_port	     = bfa_ioc_ct2_map_port,
81be3a84d1SRasesh Mody 	.ioc_lpu_read_stat   = bfa_ioc_ct2_lpu_read_stat,
82be3a84d1SRasesh Mody 	.ioc_isr_mode_set    = NULL,
83be3a84d1SRasesh Mody 	.ioc_notify_fail     = bfa_ioc_ct_notify_fail,
84be3a84d1SRasesh Mody 	.ioc_ownership_reset = bfa_ioc_ct_ownership_reset,
85be3a84d1SRasesh Mody 	.ioc_sync_start      = bfa_ioc_ct_sync_start,
86be3a84d1SRasesh Mody 	.ioc_sync_join       = bfa_ioc_ct_sync_join,
87be3a84d1SRasesh Mody 	.ioc_sync_leave	     = bfa_ioc_ct_sync_leave,
88be3a84d1SRasesh Mody 	.ioc_sync_ack	     = bfa_ioc_ct_sync_ack,
89be3a84d1SRasesh Mody 	.ioc_sync_complete   = bfa_ioc_ct_sync_complete,
9041ed903aSRasesh Mody 	.ioc_set_fwstate     = bfa_ioc_ct_set_cur_ioc_fwstate,
9141ed903aSRasesh Mody 	.ioc_get_fwstate     = bfa_ioc_ct_get_cur_ioc_fwstate,
9241ed903aSRasesh Mody 	.ioc_set_alt_fwstate     = bfa_ioc_ct_set_alt_ioc_fwstate,
9341ed903aSRasesh Mody 	.ioc_get_alt_fwstate     = bfa_ioc_ct_get_alt_ioc_fwstate,
94be3a84d1SRasesh Mody };
95be3a84d1SRasesh Mody 
961aa8b471SBen Hutchings /* Called from bfa_ioc_attach() to map asic specific calls. */
97f844a0eaSJeff Kirsher void
bfa_nw_ioc_set_ct_hwif(struct bfa_ioc * ioc)98f844a0eaSJeff Kirsher bfa_nw_ioc_set_ct_hwif(struct bfa_ioc *ioc)
99f844a0eaSJeff Kirsher {
100f844a0eaSJeff Kirsher 	ioc->ioc_hwif = &nw_hwif_ct;
101f844a0eaSJeff Kirsher }
102f844a0eaSJeff Kirsher 
103be3a84d1SRasesh Mody void
bfa_nw_ioc_set_ct2_hwif(struct bfa_ioc * ioc)104be3a84d1SRasesh Mody bfa_nw_ioc_set_ct2_hwif(struct bfa_ioc *ioc)
105be3a84d1SRasesh Mody {
106be3a84d1SRasesh Mody 	ioc->ioc_hwif = &nw_hwif_ct2;
107be3a84d1SRasesh Mody }
108be3a84d1SRasesh Mody 
1091aa8b471SBen Hutchings /* Return true if firmware of current driver matches the running firmware. */
110f844a0eaSJeff Kirsher static bool
bfa_ioc_ct_firmware_lock(struct bfa_ioc * ioc)111f844a0eaSJeff Kirsher bfa_ioc_ct_firmware_lock(struct bfa_ioc *ioc)
112f844a0eaSJeff Kirsher {
113f844a0eaSJeff Kirsher 	enum bfi_ioc_state ioc_fwstate;
114f844a0eaSJeff Kirsher 	u32 usecnt;
115f844a0eaSJeff Kirsher 	struct bfi_ioc_image_hdr fwhdr;
116f844a0eaSJeff Kirsher 
117f844a0eaSJeff Kirsher 	/**
118f844a0eaSJeff Kirsher 	 * If bios boot (flash based) -- do not increment usage count
119f844a0eaSJeff Kirsher 	 */
120078086f3SRasesh Mody 	if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) <
121f844a0eaSJeff Kirsher 						BFA_IOC_FWIMG_MINSZ)
122f844a0eaSJeff Kirsher 		return true;
123f844a0eaSJeff Kirsher 
124f844a0eaSJeff Kirsher 	bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
125f844a0eaSJeff Kirsher 	usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
126f844a0eaSJeff Kirsher 
127f844a0eaSJeff Kirsher 	/**
128f844a0eaSJeff Kirsher 	 * If usage count is 0, always return TRUE.
129f844a0eaSJeff Kirsher 	 */
130f844a0eaSJeff Kirsher 	if (usecnt == 0) {
131f844a0eaSJeff Kirsher 		writel(1, ioc->ioc_regs.ioc_usage_reg);
132f844a0eaSJeff Kirsher 		bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
133f844a0eaSJeff Kirsher 		writel(0, ioc->ioc_regs.ioc_fail_sync);
134f844a0eaSJeff Kirsher 		return true;
135f844a0eaSJeff Kirsher 	}
136f844a0eaSJeff Kirsher 
137f844a0eaSJeff Kirsher 	ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate);
138f844a0eaSJeff Kirsher 
139f844a0eaSJeff Kirsher 	/**
140f844a0eaSJeff Kirsher 	 * Use count cannot be non-zero and chip in uninitialized state.
141f844a0eaSJeff Kirsher 	 */
142f844a0eaSJeff Kirsher 	BUG_ON(!(ioc_fwstate != BFI_IOC_UNINIT));
143f844a0eaSJeff Kirsher 
144f844a0eaSJeff Kirsher 	/**
145f844a0eaSJeff Kirsher 	 * Check if another driver with a different firmware is active
146f844a0eaSJeff Kirsher 	 */
147f844a0eaSJeff Kirsher 	bfa_nw_ioc_fwver_get(ioc, &fwhdr);
148f844a0eaSJeff Kirsher 	if (!bfa_nw_ioc_fwver_cmp(ioc, &fwhdr)) {
149f844a0eaSJeff Kirsher 		bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
150f844a0eaSJeff Kirsher 		return false;
151f844a0eaSJeff Kirsher 	}
152f844a0eaSJeff Kirsher 
153f844a0eaSJeff Kirsher 	/**
154f844a0eaSJeff Kirsher 	 * Same firmware version. Increment the reference count.
155f844a0eaSJeff Kirsher 	 */
156f844a0eaSJeff Kirsher 	usecnt++;
157f844a0eaSJeff Kirsher 	writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
158f844a0eaSJeff Kirsher 	bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
159f844a0eaSJeff Kirsher 	return true;
160f844a0eaSJeff Kirsher }
161f844a0eaSJeff Kirsher 
162f844a0eaSJeff Kirsher static void
bfa_ioc_ct_firmware_unlock(struct bfa_ioc * ioc)163f844a0eaSJeff Kirsher bfa_ioc_ct_firmware_unlock(struct bfa_ioc *ioc)
164f844a0eaSJeff Kirsher {
165f844a0eaSJeff Kirsher 	u32 usecnt;
166f844a0eaSJeff Kirsher 
167f844a0eaSJeff Kirsher 	/**
168f844a0eaSJeff Kirsher 	 * If bios boot (flash based) -- do not decrement usage count
169f844a0eaSJeff Kirsher 	 */
170078086f3SRasesh Mody 	if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) <
171f844a0eaSJeff Kirsher 						BFA_IOC_FWIMG_MINSZ)
172f844a0eaSJeff Kirsher 		return;
173f844a0eaSJeff Kirsher 
174f844a0eaSJeff Kirsher 	/**
175f844a0eaSJeff Kirsher 	 * decrement usage count
176f844a0eaSJeff Kirsher 	 */
177f844a0eaSJeff Kirsher 	bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
178f844a0eaSJeff Kirsher 	usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
179f844a0eaSJeff Kirsher 	BUG_ON(!(usecnt > 0));
180f844a0eaSJeff Kirsher 
181f844a0eaSJeff Kirsher 	usecnt--;
182f844a0eaSJeff Kirsher 	writel(usecnt, ioc->ioc_regs.ioc_usage_reg);
183f844a0eaSJeff Kirsher 
184f844a0eaSJeff Kirsher 	bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
185f844a0eaSJeff Kirsher }
186f844a0eaSJeff Kirsher 
1871aa8b471SBen Hutchings /* Notify other functions on HB failure. */
188f844a0eaSJeff Kirsher static void
bfa_ioc_ct_notify_fail(struct bfa_ioc * ioc)189f844a0eaSJeff Kirsher bfa_ioc_ct_notify_fail(struct bfa_ioc *ioc)
190f844a0eaSJeff Kirsher {
191f844a0eaSJeff Kirsher 	writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt);
192f844a0eaSJeff Kirsher 	writel(__FW_INIT_HALT_P, ioc->ioc_regs.alt_ll_halt);
193f844a0eaSJeff Kirsher 	/* Wait for halt to take effect */
194f844a0eaSJeff Kirsher 	readl(ioc->ioc_regs.ll_halt);
195f844a0eaSJeff Kirsher 	readl(ioc->ioc_regs.alt_ll_halt);
196f844a0eaSJeff Kirsher }
197f844a0eaSJeff Kirsher 
1981aa8b471SBen Hutchings /* Host to LPU mailbox message addresses */
199be3a84d1SRasesh Mody static const struct {
200be3a84d1SRasesh Mody 	u32	hfn_mbox;
201be3a84d1SRasesh Mody 	u32	lpu_mbox;
202be3a84d1SRasesh Mody 	u32	hfn_pgn;
203be3a84d1SRasesh Mody } ct_fnreg[] = {
204f844a0eaSJeff Kirsher 	{ HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 },
205f844a0eaSJeff Kirsher 	{ HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 },
206f844a0eaSJeff Kirsher 	{ HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 },
207f844a0eaSJeff Kirsher 	{ HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 }
208f844a0eaSJeff Kirsher };
209f844a0eaSJeff Kirsher 
2101aa8b471SBen Hutchings /* Host <-> LPU mailbox command/status registers - port 0 */
211be3a84d1SRasesh Mody static const struct {
212be3a84d1SRasesh Mody 	u32	hfn;
213be3a84d1SRasesh Mody 	u32	lpu;
214be3a84d1SRasesh Mody } ct_p0reg[] = {
215f844a0eaSJeff Kirsher 	{ HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT },
216f844a0eaSJeff Kirsher 	{ HOSTFN1_LPU0_CMD_STAT, LPU0_HOSTFN1_CMD_STAT },
217f844a0eaSJeff Kirsher 	{ HOSTFN2_LPU0_CMD_STAT, LPU0_HOSTFN2_CMD_STAT },
218f844a0eaSJeff Kirsher 	{ HOSTFN3_LPU0_CMD_STAT, LPU0_HOSTFN3_CMD_STAT }
219f844a0eaSJeff Kirsher };
220f844a0eaSJeff Kirsher 
2211aa8b471SBen Hutchings /* Host <-> LPU mailbox command/status registers - port 1 */
222be3a84d1SRasesh Mody static const struct {
223be3a84d1SRasesh Mody 	u32	hfn;
224be3a84d1SRasesh Mody 	u32	lpu;
225be3a84d1SRasesh Mody } ct_p1reg[] = {
226f844a0eaSJeff Kirsher 	{ HOSTFN0_LPU1_CMD_STAT, LPU1_HOSTFN0_CMD_STAT },
227f844a0eaSJeff Kirsher 	{ HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT },
228f844a0eaSJeff Kirsher 	{ HOSTFN2_LPU1_CMD_STAT, LPU1_HOSTFN2_CMD_STAT },
229f844a0eaSJeff Kirsher 	{ HOSTFN3_LPU1_CMD_STAT, LPU1_HOSTFN3_CMD_STAT }
230f844a0eaSJeff Kirsher };
231f844a0eaSJeff Kirsher 
232be3a84d1SRasesh Mody static const struct {
233be3a84d1SRasesh Mody 	u32	hfn_mbox;
234be3a84d1SRasesh Mody 	u32	lpu_mbox;
235be3a84d1SRasesh Mody 	u32	hfn_pgn;
236be3a84d1SRasesh Mody 	u32	hfn;
237be3a84d1SRasesh Mody 	u32	lpu;
238be3a84d1SRasesh Mody 	u32	lpu_read;
239be3a84d1SRasesh Mody } ct2_reg[] = {
240be3a84d1SRasesh Mody 	{ CT2_HOSTFN_LPU0_MBOX0, CT2_LPU0_HOSTFN_MBOX0, CT2_HOSTFN_PAGE_NUM,
241be3a84d1SRasesh Mody 	  CT2_HOSTFN_LPU0_CMD_STAT, CT2_LPU0_HOSTFN_CMD_STAT,
242be3a84d1SRasesh Mody 	  CT2_HOSTFN_LPU0_READ_STAT},
243be3a84d1SRasesh Mody 	{ CT2_HOSTFN_LPU1_MBOX0, CT2_LPU1_HOSTFN_MBOX0, CT2_HOSTFN_PAGE_NUM,
244be3a84d1SRasesh Mody 	  CT2_HOSTFN_LPU1_CMD_STAT, CT2_LPU1_HOSTFN_CMD_STAT,
245be3a84d1SRasesh Mody 	  CT2_HOSTFN_LPU1_READ_STAT},
246be3a84d1SRasesh Mody };
247be3a84d1SRasesh Mody 
248f844a0eaSJeff Kirsher static void
bfa_ioc_ct_reg_init(struct bfa_ioc * ioc)249f844a0eaSJeff Kirsher bfa_ioc_ct_reg_init(struct bfa_ioc *ioc)
250f844a0eaSJeff Kirsher {
251f844a0eaSJeff Kirsher 	void __iomem *rb;
252f844a0eaSJeff Kirsher 	int		pcifn = bfa_ioc_pcifn(ioc);
253f844a0eaSJeff Kirsher 
254f844a0eaSJeff Kirsher 	rb = bfa_ioc_bar0(ioc);
255f844a0eaSJeff Kirsher 
256078086f3SRasesh Mody 	ioc->ioc_regs.hfn_mbox = rb + ct_fnreg[pcifn].hfn_mbox;
257078086f3SRasesh Mody 	ioc->ioc_regs.lpu_mbox = rb + ct_fnreg[pcifn].lpu_mbox;
258078086f3SRasesh Mody 	ioc->ioc_regs.host_page_num_fn = rb + ct_fnreg[pcifn].hfn_pgn;
259f844a0eaSJeff Kirsher 
260f844a0eaSJeff Kirsher 	if (ioc->port_id == 0) {
261f844a0eaSJeff Kirsher 		ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG;
262f844a0eaSJeff Kirsher 		ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG;
263f844a0eaSJeff Kirsher 		ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC1_STATE_REG;
264f844a0eaSJeff Kirsher 		ioc->ioc_regs.hfn_mbox_cmd = rb + ct_p0reg[pcifn].hfn;
265f844a0eaSJeff Kirsher 		ioc->ioc_regs.lpu_mbox_cmd = rb + ct_p0reg[pcifn].lpu;
266f844a0eaSJeff Kirsher 		ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
267f844a0eaSJeff Kirsher 		ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P1;
268f844a0eaSJeff Kirsher 	} else {
269be3a84d1SRasesh Mody 		ioc->ioc_regs.heartbeat = rb + BFA_IOC1_HBEAT_REG;
270be3a84d1SRasesh Mody 		ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC1_STATE_REG;
271f844a0eaSJeff Kirsher 		ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC0_STATE_REG;
272f844a0eaSJeff Kirsher 		ioc->ioc_regs.hfn_mbox_cmd = rb + ct_p1reg[pcifn].hfn;
273f844a0eaSJeff Kirsher 		ioc->ioc_regs.lpu_mbox_cmd = rb + ct_p1reg[pcifn].lpu;
274f844a0eaSJeff Kirsher 		ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
275f844a0eaSJeff Kirsher 		ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P0;
276f844a0eaSJeff Kirsher 	}
277f844a0eaSJeff Kirsher 
278f844a0eaSJeff Kirsher 	/*
279f844a0eaSJeff Kirsher 	 * PSS control registers
280f844a0eaSJeff Kirsher 	 */
281be3a84d1SRasesh Mody 	ioc->ioc_regs.pss_ctl_reg = rb + PSS_CTL_REG;
282be3a84d1SRasesh Mody 	ioc->ioc_regs.pss_err_status_reg = rb + PSS_ERR_STATUS_REG;
283be3a84d1SRasesh Mody 	ioc->ioc_regs.app_pll_fast_ctl_reg = rb + APP_PLL_LCLK_CTL_REG;
284be3a84d1SRasesh Mody 	ioc->ioc_regs.app_pll_slow_ctl_reg = rb + APP_PLL_SCLK_CTL_REG;
285f844a0eaSJeff Kirsher 
286f844a0eaSJeff Kirsher 	/*
287f844a0eaSJeff Kirsher 	 * IOC semaphore registers and serialization
288f844a0eaSJeff Kirsher 	 */
289be3a84d1SRasesh Mody 	ioc->ioc_regs.ioc_sem_reg = rb + HOST_SEM0_REG;
290be3a84d1SRasesh Mody 	ioc->ioc_regs.ioc_usage_sem_reg = rb + HOST_SEM1_REG;
291be3a84d1SRasesh Mody 	ioc->ioc_regs.ioc_init_sem_reg = rb + HOST_SEM2_REG;
292be3a84d1SRasesh Mody 	ioc->ioc_regs.ioc_usage_reg = rb + BFA_FW_USE_COUNT;
293be3a84d1SRasesh Mody 	ioc->ioc_regs.ioc_fail_sync = rb + BFA_IOC_FAIL_SYNC;
294f844a0eaSJeff Kirsher 
295f844a0eaSJeff Kirsher 	/**
296f844a0eaSJeff Kirsher 	 * sram memory access
297f844a0eaSJeff Kirsher 	 */
298be3a84d1SRasesh Mody 	ioc->ioc_regs.smem_page_start = rb + PSS_SMEM_PAGE_START;
299f844a0eaSJeff Kirsher 	ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
300f844a0eaSJeff Kirsher 
301f844a0eaSJeff Kirsher 	/*
302f844a0eaSJeff Kirsher 	 * err set reg : for notification of hb failure in fcmode
303f844a0eaSJeff Kirsher 	 */
304f844a0eaSJeff Kirsher 	ioc->ioc_regs.err_set = (rb + ERR_SET_REG);
305f844a0eaSJeff Kirsher }
306f844a0eaSJeff Kirsher 
307be3a84d1SRasesh Mody static void
bfa_ioc_ct2_reg_init(struct bfa_ioc * ioc)308be3a84d1SRasesh Mody bfa_ioc_ct2_reg_init(struct bfa_ioc *ioc)
309be3a84d1SRasesh Mody {
310be3a84d1SRasesh Mody 	void __iomem *rb;
311be3a84d1SRasesh Mody 	int		port = bfa_ioc_portid(ioc);
312be3a84d1SRasesh Mody 
313be3a84d1SRasesh Mody 	rb = bfa_ioc_bar0(ioc);
314be3a84d1SRasesh Mody 
315be3a84d1SRasesh Mody 	ioc->ioc_regs.hfn_mbox = rb + ct2_reg[port].hfn_mbox;
316be3a84d1SRasesh Mody 	ioc->ioc_regs.lpu_mbox = rb + ct2_reg[port].lpu_mbox;
317be3a84d1SRasesh Mody 	ioc->ioc_regs.host_page_num_fn = rb + ct2_reg[port].hfn_pgn;
318be3a84d1SRasesh Mody 	ioc->ioc_regs.hfn_mbox_cmd = rb + ct2_reg[port].hfn;
319be3a84d1SRasesh Mody 	ioc->ioc_regs.lpu_mbox_cmd = rb + ct2_reg[port].lpu;
320be3a84d1SRasesh Mody 	ioc->ioc_regs.lpu_read_stat = rb + ct2_reg[port].lpu_read;
321be3a84d1SRasesh Mody 
322be3a84d1SRasesh Mody 	if (port == 0) {
323be3a84d1SRasesh Mody 		ioc->ioc_regs.heartbeat = rb + CT2_BFA_IOC0_HBEAT_REG;
324be3a84d1SRasesh Mody 		ioc->ioc_regs.ioc_fwstate = rb + CT2_BFA_IOC0_STATE_REG;
325be3a84d1SRasesh Mody 		ioc->ioc_regs.alt_ioc_fwstate = rb + CT2_BFA_IOC1_STATE_REG;
326be3a84d1SRasesh Mody 		ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0;
327be3a84d1SRasesh Mody 		ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P1;
328be3a84d1SRasesh Mody 	} else {
329be3a84d1SRasesh Mody 		ioc->ioc_regs.heartbeat = rb + CT2_BFA_IOC1_HBEAT_REG;
330be3a84d1SRasesh Mody 		ioc->ioc_regs.ioc_fwstate = rb + CT2_BFA_IOC1_STATE_REG;
331be3a84d1SRasesh Mody 		ioc->ioc_regs.alt_ioc_fwstate = rb + CT2_BFA_IOC0_STATE_REG;
332be3a84d1SRasesh Mody 		ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1;
333be3a84d1SRasesh Mody 		ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P0;
334be3a84d1SRasesh Mody 	}
335be3a84d1SRasesh Mody 
336be3a84d1SRasesh Mody 	/*
337be3a84d1SRasesh Mody 	 * PSS control registers
338be3a84d1SRasesh Mody 	 */
339be3a84d1SRasesh Mody 	ioc->ioc_regs.pss_ctl_reg = rb + PSS_CTL_REG;
340be3a84d1SRasesh Mody 	ioc->ioc_regs.pss_err_status_reg = rb + PSS_ERR_STATUS_REG;
341be3a84d1SRasesh Mody 	ioc->ioc_regs.app_pll_fast_ctl_reg = rb + CT2_APP_PLL_LCLK_CTL_REG;
342be3a84d1SRasesh Mody 	ioc->ioc_regs.app_pll_slow_ctl_reg = rb + CT2_APP_PLL_SCLK_CTL_REG;
343be3a84d1SRasesh Mody 
344be3a84d1SRasesh Mody 	/*
345be3a84d1SRasesh Mody 	 * IOC semaphore registers and serialization
346be3a84d1SRasesh Mody 	 */
347be3a84d1SRasesh Mody 	ioc->ioc_regs.ioc_sem_reg = rb + CT2_HOST_SEM0_REG;
348be3a84d1SRasesh Mody 	ioc->ioc_regs.ioc_usage_sem_reg = rb + CT2_HOST_SEM1_REG;
349be3a84d1SRasesh Mody 	ioc->ioc_regs.ioc_init_sem_reg = rb + CT2_HOST_SEM2_REG;
350be3a84d1SRasesh Mody 	ioc->ioc_regs.ioc_usage_reg = rb + CT2_BFA_FW_USE_COUNT;
351be3a84d1SRasesh Mody 	ioc->ioc_regs.ioc_fail_sync = rb + CT2_BFA_IOC_FAIL_SYNC;
352be3a84d1SRasesh Mody 
353be3a84d1SRasesh Mody 	/**
354be3a84d1SRasesh Mody 	 * sram memory access
355be3a84d1SRasesh Mody 	 */
356be3a84d1SRasesh Mody 	ioc->ioc_regs.smem_page_start = rb + PSS_SMEM_PAGE_START;
357be3a84d1SRasesh Mody 	ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT;
358be3a84d1SRasesh Mody 
359be3a84d1SRasesh Mody 	/*
360be3a84d1SRasesh Mody 	 * err set reg : for notification of hb failure in fcmode
361be3a84d1SRasesh Mody 	 */
362be3a84d1SRasesh Mody 	ioc->ioc_regs.err_set = rb + ERR_SET_REG;
363be3a84d1SRasesh Mody }
364be3a84d1SRasesh Mody 
3651aa8b471SBen Hutchings /* Initialize IOC to port mapping. */
366f844a0eaSJeff Kirsher 
367f844a0eaSJeff Kirsher #define FNC_PERS_FN_SHIFT(__fn)	((__fn) * 8)
368f844a0eaSJeff Kirsher static void
bfa_ioc_ct_map_port(struct bfa_ioc * ioc)369f844a0eaSJeff Kirsher bfa_ioc_ct_map_port(struct bfa_ioc *ioc)
370f844a0eaSJeff Kirsher {
371f844a0eaSJeff Kirsher 	void __iomem *rb = ioc->pcidev.pci_bar_kva;
372f844a0eaSJeff Kirsher 	u32	r32;
373f844a0eaSJeff Kirsher 
374f844a0eaSJeff Kirsher 	/**
375f844a0eaSJeff Kirsher 	 * For catapult, base port id on personality register and IOC type
376f844a0eaSJeff Kirsher 	 */
377f844a0eaSJeff Kirsher 	r32 = readl(rb + FNC_PERS_REG);
378f844a0eaSJeff Kirsher 	r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc));
379f844a0eaSJeff Kirsher 	ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH;
380f844a0eaSJeff Kirsher 
381f844a0eaSJeff Kirsher }
382f844a0eaSJeff Kirsher 
383be3a84d1SRasesh Mody static void
bfa_ioc_ct2_map_port(struct bfa_ioc * ioc)384be3a84d1SRasesh Mody bfa_ioc_ct2_map_port(struct bfa_ioc *ioc)
385be3a84d1SRasesh Mody {
386be3a84d1SRasesh Mody 	void __iomem *rb = ioc->pcidev.pci_bar_kva;
387be3a84d1SRasesh Mody 	u32	r32;
388be3a84d1SRasesh Mody 
389be3a84d1SRasesh Mody 	r32 = readl(rb + CT2_HOSTFN_PERSONALITY0);
390be3a84d1SRasesh Mody 	ioc->port_id = ((r32 & __FC_LL_PORT_MAP__MK) >> __FC_LL_PORT_MAP__SH);
391be3a84d1SRasesh Mody }
392be3a84d1SRasesh Mody 
3931aa8b471SBen Hutchings /* Set interrupt mode for a function: INTX or MSIX */
394f844a0eaSJeff Kirsher static void
bfa_ioc_ct_isr_mode_set(struct bfa_ioc * ioc,bool msix)395f844a0eaSJeff Kirsher bfa_ioc_ct_isr_mode_set(struct bfa_ioc *ioc, bool msix)
396f844a0eaSJeff Kirsher {
397f844a0eaSJeff Kirsher 	void __iomem *rb = ioc->pcidev.pci_bar_kva;
398f844a0eaSJeff Kirsher 	u32	r32, mode;
399f844a0eaSJeff Kirsher 
400f844a0eaSJeff Kirsher 	r32 = readl(rb + FNC_PERS_REG);
401f844a0eaSJeff Kirsher 
402f844a0eaSJeff Kirsher 	mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) &
403f844a0eaSJeff Kirsher 		__F0_INTX_STATUS;
404f844a0eaSJeff Kirsher 
405f844a0eaSJeff Kirsher 	/**
406f844a0eaSJeff Kirsher 	 * If already in desired mode, do not change anything
407f844a0eaSJeff Kirsher 	 */
408f844a0eaSJeff Kirsher 	if ((!msix && mode) || (msix && !mode))
409f844a0eaSJeff Kirsher 		return;
410f844a0eaSJeff Kirsher 
411f844a0eaSJeff Kirsher 	if (msix)
412f844a0eaSJeff Kirsher 		mode = __F0_INTX_STATUS_MSIX;
413f844a0eaSJeff Kirsher 	else
414f844a0eaSJeff Kirsher 		mode = __F0_INTX_STATUS_INTA;
415f844a0eaSJeff Kirsher 
416f844a0eaSJeff Kirsher 	r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
417f844a0eaSJeff Kirsher 	r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)));
418f844a0eaSJeff Kirsher 
419f844a0eaSJeff Kirsher 	writel(r32, rb + FNC_PERS_REG);
420f844a0eaSJeff Kirsher }
421f844a0eaSJeff Kirsher 
422be3a84d1SRasesh Mody static bool
bfa_ioc_ct2_lpu_read_stat(struct bfa_ioc * ioc)423be3a84d1SRasesh Mody bfa_ioc_ct2_lpu_read_stat(struct bfa_ioc *ioc)
424be3a84d1SRasesh Mody {
425be3a84d1SRasesh Mody 	u32 r32;
426be3a84d1SRasesh Mody 
427be3a84d1SRasesh Mody 	r32 = readl(ioc->ioc_regs.lpu_read_stat);
428be3a84d1SRasesh Mody 	if (r32) {
429be3a84d1SRasesh Mody 		writel(1, ioc->ioc_regs.lpu_read_stat);
430be3a84d1SRasesh Mody 		return true;
431be3a84d1SRasesh Mody 	}
432be3a84d1SRasesh Mody 
433be3a84d1SRasesh Mody 	return false;
434be3a84d1SRasesh Mody }
435be3a84d1SRasesh Mody 
4361aa8b471SBen Hutchings /* MSI-X resource allocation for 1860 with no asic block */
437be3a84d1SRasesh Mody #define HOSTFN_MSIX_DEFAULT		64
438be3a84d1SRasesh Mody #define HOSTFN_MSIX_VT_INDEX_MBOX_ERR	0x30138
439be3a84d1SRasesh Mody #define HOSTFN_MSIX_VT_OFST_NUMVT	0x3013c
440be3a84d1SRasesh Mody #define __MSIX_VT_NUMVT__MK		0x003ff800
441be3a84d1SRasesh Mody #define __MSIX_VT_NUMVT__SH		11
442be3a84d1SRasesh Mody #define __MSIX_VT_NUMVT_(_v)		((_v) << __MSIX_VT_NUMVT__SH)
443be3a84d1SRasesh Mody #define __MSIX_VT_OFST_			0x000007ff
444be3a84d1SRasesh Mody void
bfa_nw_ioc_ct2_poweron(struct bfa_ioc * ioc)44570f14381SRasesh Mody bfa_nw_ioc_ct2_poweron(struct bfa_ioc *ioc)
446be3a84d1SRasesh Mody {
447be3a84d1SRasesh Mody 	void __iomem *rb = ioc->pcidev.pci_bar_kva;
448be3a84d1SRasesh Mody 	u32 r32;
449be3a84d1SRasesh Mody 
450be3a84d1SRasesh Mody 	r32 = readl(rb + HOSTFN_MSIX_VT_OFST_NUMVT);
451be3a84d1SRasesh Mody 	if (r32 & __MSIX_VT_NUMVT__MK) {
452be3a84d1SRasesh Mody 		writel(r32 & __MSIX_VT_OFST_,
453be3a84d1SRasesh Mody 			rb + HOSTFN_MSIX_VT_INDEX_MBOX_ERR);
454be3a84d1SRasesh Mody 		return;
455be3a84d1SRasesh Mody 	}
456be3a84d1SRasesh Mody 
457be3a84d1SRasesh Mody 	writel(__MSIX_VT_NUMVT_(HOSTFN_MSIX_DEFAULT - 1) |
458be3a84d1SRasesh Mody 			HOSTFN_MSIX_DEFAULT * bfa_ioc_pcifn(ioc),
459be3a84d1SRasesh Mody 			rb + HOSTFN_MSIX_VT_OFST_NUMVT);
460be3a84d1SRasesh Mody 	writel(HOSTFN_MSIX_DEFAULT * bfa_ioc_pcifn(ioc),
461be3a84d1SRasesh Mody 			rb + HOSTFN_MSIX_VT_INDEX_MBOX_ERR);
462be3a84d1SRasesh Mody }
463be3a84d1SRasesh Mody 
4641aa8b471SBen Hutchings /* Cleanup hw semaphore and usecnt registers */
465f844a0eaSJeff Kirsher static void
bfa_ioc_ct_ownership_reset(struct bfa_ioc * ioc)466f844a0eaSJeff Kirsher bfa_ioc_ct_ownership_reset(struct bfa_ioc *ioc)
467f844a0eaSJeff Kirsher {
468f844a0eaSJeff Kirsher 	bfa_nw_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
469f844a0eaSJeff Kirsher 	writel(0, ioc->ioc_regs.ioc_usage_reg);
470f844a0eaSJeff Kirsher 	bfa_nw_ioc_sem_release(ioc->ioc_regs.ioc_usage_sem_reg);
471f844a0eaSJeff Kirsher 
472f844a0eaSJeff Kirsher 	/*
473f844a0eaSJeff Kirsher 	 * Read the hw sem reg to make sure that it is locked
474f844a0eaSJeff Kirsher 	 * before we clear it. If it is not locked, writing 1
475f844a0eaSJeff Kirsher 	 * will lock it instead of clearing it.
476f844a0eaSJeff Kirsher 	 */
477f844a0eaSJeff Kirsher 	readl(ioc->ioc_regs.ioc_sem_reg);
478f844a0eaSJeff Kirsher 	bfa_nw_ioc_hw_sem_release(ioc);
479f844a0eaSJeff Kirsher }
480f844a0eaSJeff Kirsher 
4811aa8b471SBen Hutchings /* Synchronized IOC failure processing routines */
482f844a0eaSJeff Kirsher static bool
bfa_ioc_ct_sync_start(struct bfa_ioc * ioc)483f844a0eaSJeff Kirsher bfa_ioc_ct_sync_start(struct bfa_ioc *ioc)
484f844a0eaSJeff Kirsher {
485f844a0eaSJeff Kirsher 	u32 r32 = readl(ioc->ioc_regs.ioc_fail_sync);
486f844a0eaSJeff Kirsher 	u32 sync_reqd = bfa_ioc_ct_get_sync_reqd(r32);
487f844a0eaSJeff Kirsher 
488f844a0eaSJeff Kirsher 	/*
489f844a0eaSJeff Kirsher 	 * Driver load time.  If the sync required bit for this PCI fn
490f844a0eaSJeff Kirsher 	 * is set, it is due to an unclean exit by the driver for this
491f844a0eaSJeff Kirsher 	 * PCI fn in the previous incarnation. Whoever comes here first
492f844a0eaSJeff Kirsher 	 * should clean it up, no matter which PCI fn.
493f844a0eaSJeff Kirsher 	 */
494f844a0eaSJeff Kirsher 
495f844a0eaSJeff Kirsher 	if (sync_reqd & bfa_ioc_ct_sync_pos(ioc)) {
496f844a0eaSJeff Kirsher 		writel(0, ioc->ioc_regs.ioc_fail_sync);
497f844a0eaSJeff Kirsher 		writel(1, ioc->ioc_regs.ioc_usage_reg);
498f844a0eaSJeff Kirsher 		writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
499f844a0eaSJeff Kirsher 		writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate);
500f844a0eaSJeff Kirsher 		return true;
501f844a0eaSJeff Kirsher 	}
502f844a0eaSJeff Kirsher 
503f844a0eaSJeff Kirsher 	return bfa_ioc_ct_sync_complete(ioc);
504f844a0eaSJeff Kirsher }
5051aa8b471SBen Hutchings /* Synchronized IOC failure processing routines */
506f844a0eaSJeff Kirsher static void
bfa_ioc_ct_sync_join(struct bfa_ioc * ioc)507f844a0eaSJeff Kirsher bfa_ioc_ct_sync_join(struct bfa_ioc *ioc)
508f844a0eaSJeff Kirsher {
509f844a0eaSJeff Kirsher 	u32 r32 = readl(ioc->ioc_regs.ioc_fail_sync);
510f844a0eaSJeff Kirsher 	u32 sync_pos = bfa_ioc_ct_sync_reqd_pos(ioc);
511f844a0eaSJeff Kirsher 
512f844a0eaSJeff Kirsher 	writel((r32 | sync_pos), ioc->ioc_regs.ioc_fail_sync);
513f844a0eaSJeff Kirsher }
514f844a0eaSJeff Kirsher 
515f844a0eaSJeff Kirsher static void
bfa_ioc_ct_sync_leave(struct bfa_ioc * ioc)516f844a0eaSJeff Kirsher bfa_ioc_ct_sync_leave(struct bfa_ioc *ioc)
517f844a0eaSJeff Kirsher {
518f844a0eaSJeff Kirsher 	u32 r32 = readl(ioc->ioc_regs.ioc_fail_sync);
519f844a0eaSJeff Kirsher 	u32 sync_msk = bfa_ioc_ct_sync_reqd_pos(ioc) |
520f844a0eaSJeff Kirsher 					bfa_ioc_ct_sync_pos(ioc);
521f844a0eaSJeff Kirsher 
522f844a0eaSJeff Kirsher 	writel((r32 & ~sync_msk), ioc->ioc_regs.ioc_fail_sync);
523f844a0eaSJeff Kirsher }
524f844a0eaSJeff Kirsher 
525f844a0eaSJeff Kirsher static void
bfa_ioc_ct_sync_ack(struct bfa_ioc * ioc)526f844a0eaSJeff Kirsher bfa_ioc_ct_sync_ack(struct bfa_ioc *ioc)
527f844a0eaSJeff Kirsher {
528f844a0eaSJeff Kirsher 	u32 r32 = readl(ioc->ioc_regs.ioc_fail_sync);
529f844a0eaSJeff Kirsher 
530ebb56d37SIvan Vecera 	writel(r32 | bfa_ioc_ct_sync_pos(ioc), ioc->ioc_regs.ioc_fail_sync);
531f844a0eaSJeff Kirsher }
532f844a0eaSJeff Kirsher 
533f844a0eaSJeff Kirsher static bool
bfa_ioc_ct_sync_complete(struct bfa_ioc * ioc)534f844a0eaSJeff Kirsher bfa_ioc_ct_sync_complete(struct bfa_ioc *ioc)
535f844a0eaSJeff Kirsher {
536f844a0eaSJeff Kirsher 	u32 r32 = readl(ioc->ioc_regs.ioc_fail_sync);
537f844a0eaSJeff Kirsher 	u32 sync_reqd = bfa_ioc_ct_get_sync_reqd(r32);
538f844a0eaSJeff Kirsher 	u32 sync_ackd = bfa_ioc_ct_get_sync_ackd(r32);
539f844a0eaSJeff Kirsher 	u32 tmp_ackd;
540f844a0eaSJeff Kirsher 
541f844a0eaSJeff Kirsher 	if (sync_ackd == 0)
542f844a0eaSJeff Kirsher 		return true;
543f844a0eaSJeff Kirsher 
544f844a0eaSJeff Kirsher 	/**
545f844a0eaSJeff Kirsher 	 * The check below is to see whether any other PCI fn
546f844a0eaSJeff Kirsher 	 * has reinitialized the ASIC (reset sync_ackd bits)
547f844a0eaSJeff Kirsher 	 * and failed again while this IOC was waiting for hw
548f844a0eaSJeff Kirsher 	 * semaphore (in bfa_iocpf_sm_semwait()).
549f844a0eaSJeff Kirsher 	 */
550f844a0eaSJeff Kirsher 	tmp_ackd = sync_ackd;
551f844a0eaSJeff Kirsher 	if ((sync_reqd &  bfa_ioc_ct_sync_pos(ioc)) &&
552f844a0eaSJeff Kirsher 			!(sync_ackd & bfa_ioc_ct_sync_pos(ioc)))
553f844a0eaSJeff Kirsher 		sync_ackd |= bfa_ioc_ct_sync_pos(ioc);
554f844a0eaSJeff Kirsher 
555f844a0eaSJeff Kirsher 	if (sync_reqd == sync_ackd) {
556f844a0eaSJeff Kirsher 		writel(bfa_ioc_ct_clear_sync_ackd(r32),
557f844a0eaSJeff Kirsher 				ioc->ioc_regs.ioc_fail_sync);
558f844a0eaSJeff Kirsher 		writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate);
559f844a0eaSJeff Kirsher 		writel(BFI_IOC_FAIL, ioc->ioc_regs.alt_ioc_fwstate);
560f844a0eaSJeff Kirsher 		return true;
561f844a0eaSJeff Kirsher 	}
562f844a0eaSJeff Kirsher 
563f844a0eaSJeff Kirsher 	/**
564f844a0eaSJeff Kirsher 	 * If another PCI fn reinitialized and failed again while
565f844a0eaSJeff Kirsher 	 * this IOC was waiting for hw sem, the sync_ackd bit for
566f844a0eaSJeff Kirsher 	 * this IOC need to be set again to allow reinitialization.
567f844a0eaSJeff Kirsher 	 */
568f844a0eaSJeff Kirsher 	if (tmp_ackd != sync_ackd)
569f844a0eaSJeff Kirsher 		writel((r32 | sync_ackd), ioc->ioc_regs.ioc_fail_sync);
570f844a0eaSJeff Kirsher 
571f844a0eaSJeff Kirsher 	return false;
572f844a0eaSJeff Kirsher }
573f844a0eaSJeff Kirsher 
57441ed903aSRasesh Mody static void
bfa_ioc_ct_set_cur_ioc_fwstate(struct bfa_ioc * ioc,enum bfi_ioc_state fwstate)57541ed903aSRasesh Mody bfa_ioc_ct_set_cur_ioc_fwstate(struct bfa_ioc *ioc,
57641ed903aSRasesh Mody 			       enum bfi_ioc_state fwstate)
57741ed903aSRasesh Mody {
57841ed903aSRasesh Mody 	writel(fwstate, ioc->ioc_regs.ioc_fwstate);
57941ed903aSRasesh Mody }
58041ed903aSRasesh Mody 
58141ed903aSRasesh Mody static enum bfi_ioc_state
bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc * ioc)58241ed903aSRasesh Mody bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc *ioc)
58341ed903aSRasesh Mody {
58441ed903aSRasesh Mody 	return (enum bfi_ioc_state)readl(ioc->ioc_regs.ioc_fwstate);
58541ed903aSRasesh Mody }
58641ed903aSRasesh Mody 
58741ed903aSRasesh Mody static void
bfa_ioc_ct_set_alt_ioc_fwstate(struct bfa_ioc * ioc,enum bfi_ioc_state fwstate)58841ed903aSRasesh Mody bfa_ioc_ct_set_alt_ioc_fwstate(struct bfa_ioc *ioc,
58941ed903aSRasesh Mody 			       enum bfi_ioc_state fwstate)
59041ed903aSRasesh Mody {
59141ed903aSRasesh Mody 	writel(fwstate, ioc->ioc_regs.alt_ioc_fwstate);
59241ed903aSRasesh Mody }
59341ed903aSRasesh Mody 
59441ed903aSRasesh Mody static enum bfi_ioc_state
bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc * ioc)59541ed903aSRasesh Mody bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc *ioc)
59641ed903aSRasesh Mody {
59741ed903aSRasesh Mody 	return (enum bfi_ioc_state)readl(ioc->ioc_regs.alt_ioc_fwstate);
59841ed903aSRasesh Mody }
59941ed903aSRasesh Mody 
600f844a0eaSJeff Kirsher static enum bfa_status
bfa_ioc_ct_pll_init(void __iomem * rb,enum bfi_asic_mode asic_mode)601078086f3SRasesh Mody bfa_ioc_ct_pll_init(void __iomem *rb, enum bfi_asic_mode asic_mode)
602f844a0eaSJeff Kirsher {
603f844a0eaSJeff Kirsher 	u32	pll_sclk, pll_fclk, r32;
604078086f3SRasesh Mody 	bool fcmode = (asic_mode == BFI_ASIC_MODE_FC);
605f844a0eaSJeff Kirsher 
606f844a0eaSJeff Kirsher 	pll_sclk = __APP_PLL_SCLK_LRESETN | __APP_PLL_SCLK_ENARST |
607f844a0eaSJeff Kirsher 		__APP_PLL_SCLK_RSEL200500 | __APP_PLL_SCLK_P0_1(3U) |
608f844a0eaSJeff Kirsher 		__APP_PLL_SCLK_JITLMT0_1(3U) |
609f844a0eaSJeff Kirsher 		__APP_PLL_SCLK_CNTLMT0_1(1U);
610f844a0eaSJeff Kirsher 	pll_fclk = __APP_PLL_LCLK_LRESETN | __APP_PLL_LCLK_ENARST |
611f844a0eaSJeff Kirsher 		__APP_PLL_LCLK_RSEL200500 | __APP_PLL_LCLK_P0_1(3U) |
612f844a0eaSJeff Kirsher 		__APP_PLL_LCLK_JITLMT0_1(3U) |
613f844a0eaSJeff Kirsher 		__APP_PLL_LCLK_CNTLMT0_1(1U);
614f844a0eaSJeff Kirsher 
615f844a0eaSJeff Kirsher 	if (fcmode) {
616f844a0eaSJeff Kirsher 		writel(0, (rb + OP_MODE));
617f844a0eaSJeff Kirsher 		writel(__APP_EMS_CMLCKSEL |
618f844a0eaSJeff Kirsher 				__APP_EMS_REFCKBUFEN2 |
619f844a0eaSJeff Kirsher 				__APP_EMS_CHANNEL_SEL,
620f844a0eaSJeff Kirsher 				(rb + ETH_MAC_SER_REG));
621f844a0eaSJeff Kirsher 	} else {
622f844a0eaSJeff Kirsher 		writel(__GLOBAL_FCOE_MODE, (rb + OP_MODE));
623f844a0eaSJeff Kirsher 		writel(__APP_EMS_REFCKBUFEN1,
624f844a0eaSJeff Kirsher 				(rb + ETH_MAC_SER_REG));
625f844a0eaSJeff Kirsher 	}
626f844a0eaSJeff Kirsher 	writel(BFI_IOC_UNINIT, (rb + BFA_IOC0_STATE_REG));
627f844a0eaSJeff Kirsher 	writel(BFI_IOC_UNINIT, (rb + BFA_IOC1_STATE_REG));
628f844a0eaSJeff Kirsher 	writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
629f844a0eaSJeff Kirsher 	writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
630f844a0eaSJeff Kirsher 	writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
631f844a0eaSJeff Kirsher 	writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
632f844a0eaSJeff Kirsher 	writel(0xffffffffU, (rb + HOSTFN0_INT_MSK));
633f844a0eaSJeff Kirsher 	writel(0xffffffffU, (rb + HOSTFN1_INT_MSK));
634f844a0eaSJeff Kirsher 	writel(pll_sclk |
635f844a0eaSJeff Kirsher 		__APP_PLL_SCLK_LOGIC_SOFT_RESET,
636f844a0eaSJeff Kirsher 		rb + APP_PLL_SCLK_CTL_REG);
637f844a0eaSJeff Kirsher 	writel(pll_fclk |
638f844a0eaSJeff Kirsher 		__APP_PLL_LCLK_LOGIC_SOFT_RESET,
639f844a0eaSJeff Kirsher 		rb + APP_PLL_LCLK_CTL_REG);
640f844a0eaSJeff Kirsher 	writel(pll_sclk |
641f844a0eaSJeff Kirsher 		__APP_PLL_SCLK_LOGIC_SOFT_RESET | __APP_PLL_SCLK_ENABLE,
642f844a0eaSJeff Kirsher 		rb + APP_PLL_SCLK_CTL_REG);
643f844a0eaSJeff Kirsher 	writel(pll_fclk |
644f844a0eaSJeff Kirsher 		__APP_PLL_LCLK_LOGIC_SOFT_RESET | __APP_PLL_LCLK_ENABLE,
645f844a0eaSJeff Kirsher 		rb + APP_PLL_LCLK_CTL_REG);
646f844a0eaSJeff Kirsher 	readl(rb + HOSTFN0_INT_MSK);
647f844a0eaSJeff Kirsher 	udelay(2000);
648f844a0eaSJeff Kirsher 	writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS));
649f844a0eaSJeff Kirsher 	writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS));
650f844a0eaSJeff Kirsher 	writel(pll_sclk |
651f844a0eaSJeff Kirsher 		__APP_PLL_SCLK_ENABLE,
652f844a0eaSJeff Kirsher 		rb + APP_PLL_SCLK_CTL_REG);
653f844a0eaSJeff Kirsher 	writel(pll_fclk |
654f844a0eaSJeff Kirsher 		__APP_PLL_LCLK_ENABLE,
655f844a0eaSJeff Kirsher 		rb + APP_PLL_LCLK_CTL_REG);
656f844a0eaSJeff Kirsher 
657f844a0eaSJeff Kirsher 	if (!fcmode) {
658f844a0eaSJeff Kirsher 		writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P0));
659f844a0eaSJeff Kirsher 		writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P1));
660f844a0eaSJeff Kirsher 	}
661ebb56d37SIvan Vecera 	r32 = readl(rb + PSS_CTL_REG);
662f844a0eaSJeff Kirsher 	r32 &= ~__PSS_LMEM_RESET;
663f844a0eaSJeff Kirsher 	writel(r32, (rb + PSS_CTL_REG));
664f844a0eaSJeff Kirsher 	udelay(1000);
665f844a0eaSJeff Kirsher 	if (!fcmode) {
666f844a0eaSJeff Kirsher 		writel(0, (rb + PMM_1T_RESET_REG_P0));
667f844a0eaSJeff Kirsher 		writel(0, (rb + PMM_1T_RESET_REG_P1));
668f844a0eaSJeff Kirsher 	}
669f844a0eaSJeff Kirsher 
670f844a0eaSJeff Kirsher 	writel(__EDRAM_BISTR_START, (rb + MBIST_CTL_REG));
671f844a0eaSJeff Kirsher 	udelay(1000);
672ebb56d37SIvan Vecera 	r32 = readl(rb + MBIST_STAT_REG);
673f844a0eaSJeff Kirsher 	writel(0, (rb + MBIST_CTL_REG));
674f844a0eaSJeff Kirsher 	return BFA_STATUS_OK;
675f844a0eaSJeff Kirsher }
676be3a84d1SRasesh Mody 
677be3a84d1SRasesh Mody static void
bfa_ioc_ct2_sclk_init(void __iomem * rb)678be3a84d1SRasesh Mody bfa_ioc_ct2_sclk_init(void __iomem *rb)
679be3a84d1SRasesh Mody {
680be3a84d1SRasesh Mody 	u32 r32;
681be3a84d1SRasesh Mody 
682be3a84d1SRasesh Mody 	/*
683be3a84d1SRasesh Mody 	 * put s_clk PLL and PLL FSM in reset
684be3a84d1SRasesh Mody 	 */
685ebb56d37SIvan Vecera 	r32 = readl(rb + CT2_APP_PLL_SCLK_CTL_REG);
686be3a84d1SRasesh Mody 	r32 &= ~(__APP_PLL_SCLK_ENABLE | __APP_PLL_SCLK_LRESETN);
687be3a84d1SRasesh Mody 	r32 |= (__APP_PLL_SCLK_ENARST | __APP_PLL_SCLK_BYPASS |
688be3a84d1SRasesh Mody 		__APP_PLL_SCLK_LOGIC_SOFT_RESET);
689be3a84d1SRasesh Mody 	writel(r32, (rb + CT2_APP_PLL_SCLK_CTL_REG));
690be3a84d1SRasesh Mody 
691be3a84d1SRasesh Mody 	/*
692be3a84d1SRasesh Mody 	 * Ignore mode and program for the max clock (which is FC16)
693dbedd44eSJoe Perches 	 * Firmware/NFC will do the PLL init appropriately
694be3a84d1SRasesh Mody 	 */
695ebb56d37SIvan Vecera 	r32 = readl(rb + CT2_APP_PLL_SCLK_CTL_REG);
696be3a84d1SRasesh Mody 	r32 &= ~(__APP_PLL_SCLK_REFCLK_SEL | __APP_PLL_SCLK_CLK_DIV2);
697be3a84d1SRasesh Mody 	writel(r32, (rb + CT2_APP_PLL_SCLK_CTL_REG));
698be3a84d1SRasesh Mody 
699be3a84d1SRasesh Mody 	/*
700be3a84d1SRasesh Mody 	 * while doing PLL init dont clock gate ethernet subsystem
701be3a84d1SRasesh Mody 	 */
702ebb56d37SIvan Vecera 	r32 = readl(rb + CT2_CHIP_MISC_PRG);
703ebb56d37SIvan Vecera 	writel(r32 | __ETH_CLK_ENABLE_PORT0,
704ebb56d37SIvan Vecera 	       rb + CT2_CHIP_MISC_PRG);
705be3a84d1SRasesh Mody 
706ebb56d37SIvan Vecera 	r32 = readl(rb + CT2_PCIE_MISC_REG);
707ebb56d37SIvan Vecera 	writel(r32 | __ETH_CLK_ENABLE_PORT1,
708ebb56d37SIvan Vecera 	       rb + CT2_PCIE_MISC_REG);
709be3a84d1SRasesh Mody 
710be3a84d1SRasesh Mody 	/*
711be3a84d1SRasesh Mody 	 * set sclk value
712be3a84d1SRasesh Mody 	 */
713ebb56d37SIvan Vecera 	r32 = readl(rb + CT2_APP_PLL_SCLK_CTL_REG);
714be3a84d1SRasesh Mody 	r32 &= (__P_SCLK_PLL_LOCK | __APP_PLL_SCLK_REFCLK_SEL |
715be3a84d1SRasesh Mody 		__APP_PLL_SCLK_CLK_DIV2);
716ebb56d37SIvan Vecera 	writel(r32 | 0x1061731b, rb + CT2_APP_PLL_SCLK_CTL_REG);
717be3a84d1SRasesh Mody 
718be3a84d1SRasesh Mody 	/*
719be3a84d1SRasesh Mody 	 * poll for s_clk lock or delay 1ms
720be3a84d1SRasesh Mody 	 */
721be3a84d1SRasesh Mody 	udelay(1000);
722be3a84d1SRasesh Mody 
723be3a84d1SRasesh Mody 	/*
724be3a84d1SRasesh Mody 	 * Dont do clock gating for ethernet subsystem, firmware/NFC will
725be3a84d1SRasesh Mody 	 * do this appropriately
726be3a84d1SRasesh Mody 	 */
727be3a84d1SRasesh Mody }
728be3a84d1SRasesh Mody 
729be3a84d1SRasesh Mody static void
bfa_ioc_ct2_lclk_init(void __iomem * rb)730be3a84d1SRasesh Mody bfa_ioc_ct2_lclk_init(void __iomem *rb)
731be3a84d1SRasesh Mody {
732be3a84d1SRasesh Mody 	u32 r32;
733be3a84d1SRasesh Mody 
734be3a84d1SRasesh Mody 	/*
735be3a84d1SRasesh Mody 	 * put l_clk PLL and PLL FSM in reset
736be3a84d1SRasesh Mody 	 */
737ebb56d37SIvan Vecera 	r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
738be3a84d1SRasesh Mody 	r32 &= ~(__APP_PLL_LCLK_ENABLE | __APP_PLL_LCLK_LRESETN);
739be3a84d1SRasesh Mody 	r32 |= (__APP_PLL_LCLK_ENARST | __APP_PLL_LCLK_BYPASS |
740be3a84d1SRasesh Mody 		__APP_PLL_LCLK_LOGIC_SOFT_RESET);
741ebb56d37SIvan Vecera 	writel(r32, rb + CT2_APP_PLL_LCLK_CTL_REG);
742be3a84d1SRasesh Mody 
743be3a84d1SRasesh Mody 	/*
744be3a84d1SRasesh Mody 	 * set LPU speed (set for FC16 which will work for other modes)
745be3a84d1SRasesh Mody 	 */
746ebb56d37SIvan Vecera 	r32 = readl(rb + CT2_CHIP_MISC_PRG);
747be3a84d1SRasesh Mody 	writel(r32, (rb + CT2_CHIP_MISC_PRG));
748be3a84d1SRasesh Mody 
749be3a84d1SRasesh Mody 	/*
750be3a84d1SRasesh Mody 	 * set LPU half speed (set for FC16 which will work for other modes)
751be3a84d1SRasesh Mody 	 */
752ebb56d37SIvan Vecera 	r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
753ebb56d37SIvan Vecera 	writel(r32, rb + CT2_APP_PLL_LCLK_CTL_REG);
754be3a84d1SRasesh Mody 
755be3a84d1SRasesh Mody 	/*
756be3a84d1SRasesh Mody 	 * set lclk for mode (set for FC16)
757be3a84d1SRasesh Mody 	 */
758ebb56d37SIvan Vecera 	r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
759be3a84d1SRasesh Mody 	r32 &= (__P_LCLK_PLL_LOCK | __APP_LPUCLK_HALFSPEED);
760be3a84d1SRasesh Mody 	r32 |= 0x20c1731b;
761be3a84d1SRasesh Mody 	writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG));
762be3a84d1SRasesh Mody 
763be3a84d1SRasesh Mody 	/*
764be3a84d1SRasesh Mody 	 * poll for s_clk lock or delay 1ms
765be3a84d1SRasesh Mody 	 */
766be3a84d1SRasesh Mody 	udelay(1000);
767be3a84d1SRasesh Mody }
768be3a84d1SRasesh Mody 
769be3a84d1SRasesh Mody static void
bfa_ioc_ct2_mem_init(void __iomem * rb)770be3a84d1SRasesh Mody bfa_ioc_ct2_mem_init(void __iomem *rb)
771be3a84d1SRasesh Mody {
772be3a84d1SRasesh Mody 	u32 r32;
773be3a84d1SRasesh Mody 
774ebb56d37SIvan Vecera 	r32 = readl(rb + PSS_CTL_REG);
775be3a84d1SRasesh Mody 	r32 &= ~__PSS_LMEM_RESET;
776ebb56d37SIvan Vecera 	writel(r32, rb + PSS_CTL_REG);
777be3a84d1SRasesh Mody 	udelay(1000);
778be3a84d1SRasesh Mody 
779ebb56d37SIvan Vecera 	writel(__EDRAM_BISTR_START, rb + CT2_MBIST_CTL_REG);
780be3a84d1SRasesh Mody 	udelay(1000);
781ebb56d37SIvan Vecera 	writel(0, rb + CT2_MBIST_CTL_REG);
782be3a84d1SRasesh Mody }
783be3a84d1SRasesh Mody 
784be3a84d1SRasesh Mody static void
bfa_ioc_ct2_mac_reset(void __iomem * rb)785be3a84d1SRasesh Mody bfa_ioc_ct2_mac_reset(void __iomem *rb)
786be3a84d1SRasesh Mody {
787be3a84d1SRasesh Mody 	volatile u32 r32;
788be3a84d1SRasesh Mody 
789be3a84d1SRasesh Mody 	bfa_ioc_ct2_sclk_init(rb);
790be3a84d1SRasesh Mody 	bfa_ioc_ct2_lclk_init(rb);
791be3a84d1SRasesh Mody 
792be3a84d1SRasesh Mody 	/*
793be3a84d1SRasesh Mody 	 * release soft reset on s_clk & l_clk
794be3a84d1SRasesh Mody 	 */
795ebb56d37SIvan Vecera 	r32 = readl(rb + CT2_APP_PLL_SCLK_CTL_REG);
796ebb56d37SIvan Vecera 	writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET,
797ebb56d37SIvan Vecera 	       rb + CT2_APP_PLL_SCLK_CTL_REG);
798be3a84d1SRasesh Mody 
799be3a84d1SRasesh Mody 	/*
800be3a84d1SRasesh Mody 	 * release soft reset on s_clk & l_clk
801be3a84d1SRasesh Mody 	 */
802ebb56d37SIvan Vecera 	r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
803ebb56d37SIvan Vecera 	writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
804ebb56d37SIvan Vecera 	       rb + CT2_APP_PLL_LCLK_CTL_REG);
805be3a84d1SRasesh Mody 
806be3a84d1SRasesh Mody 	/* put port0, port1 MAC & AHB in reset */
807ebb56d37SIvan Vecera 	writel(__CSI_MAC_RESET | __CSI_MAC_AHB_RESET,
808ebb56d37SIvan Vecera 	       rb + CT2_CSI_MAC_CONTROL_REG(0));
809ebb56d37SIvan Vecera 	writel(__CSI_MAC_RESET | __CSI_MAC_AHB_RESET,
810ebb56d37SIvan Vecera 	       rb + CT2_CSI_MAC_CONTROL_REG(1));
811be3a84d1SRasesh Mody }
812be3a84d1SRasesh Mody 
813be3a84d1SRasesh Mody #define CT2_NFC_MAX_DELAY       1000
8144d58cd64SJing Huang #define CT2_NFC_VER_VALID       0x143
8154d58cd64SJing Huang #define BFA_IOC_PLL_POLL        1000000
8164d58cd64SJing Huang 
8174d58cd64SJing Huang static bool
bfa_ioc_ct2_nfc_halted(void __iomem * rb)8184d58cd64SJing Huang bfa_ioc_ct2_nfc_halted(void __iomem *rb)
8194d58cd64SJing Huang {
8204d58cd64SJing Huang 	volatile u32 r32;
8214d58cd64SJing Huang 
8224d58cd64SJing Huang 	r32 = readl(rb + CT2_NFC_CSR_SET_REG);
8234d58cd64SJing Huang 	if (r32 & __NFC_CONTROLLER_HALTED)
8244d58cd64SJing Huang 		return true;
8254d58cd64SJing Huang 
8264d58cd64SJing Huang 	return false;
8274d58cd64SJing Huang }
8284d58cd64SJing Huang 
8294d58cd64SJing Huang static void
bfa_ioc_ct2_nfc_resume(void __iomem * rb)8304d58cd64SJing Huang bfa_ioc_ct2_nfc_resume(void __iomem *rb)
8314d58cd64SJing Huang {
8324d58cd64SJing Huang 	volatile u32 r32;
8334d58cd64SJing Huang 	int i;
8344d58cd64SJing Huang 
8354d58cd64SJing Huang 	writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_CLR_REG);
8364d58cd64SJing Huang 	for (i = 0; i < CT2_NFC_MAX_DELAY; i++) {
8374d58cd64SJing Huang 		r32 = readl(rb + CT2_NFC_CSR_SET_REG);
8384d58cd64SJing Huang 		if (!(r32 & __NFC_CONTROLLER_HALTED))
8394d58cd64SJing Huang 			return;
8404d58cd64SJing Huang 		udelay(1000);
8414d58cd64SJing Huang 	}
8424d58cd64SJing Huang 	BUG_ON(1);
8434d58cd64SJing Huang }
8444d58cd64SJing Huang 
845be3a84d1SRasesh Mody static enum bfa_status
bfa_ioc_ct2_pll_init(void __iomem * rb,enum bfi_asic_mode asic_mode)846be3a84d1SRasesh Mody bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode asic_mode)
847be3a84d1SRasesh Mody {
848be3a84d1SRasesh Mody 	volatile u32 wgn, r32;
8494d58cd64SJing Huang 	u32 nfc_ver, i;
850be3a84d1SRasesh Mody 
851be3a84d1SRasesh Mody 	wgn = readl(rb + CT2_WGN_STATUS);
8524d58cd64SJing Huang 
8534d58cd64SJing Huang 	nfc_ver = readl(rb + CT2_RSC_GPR15_REG);
8544d58cd64SJing Huang 
855ebb56d37SIvan Vecera 	if (wgn == (__A2T_AHB_LOAD | __WGN_READY) &&
856ebb56d37SIvan Vecera 	    nfc_ver >= CT2_NFC_VER_VALID) {
8574d58cd64SJing Huang 		if (bfa_ioc_ct2_nfc_halted(rb))
8584d58cd64SJing Huang 			bfa_ioc_ct2_nfc_resume(rb);
8594d58cd64SJing Huang 		writel(__RESET_AND_START_SCLK_LCLK_PLLS,
8604d58cd64SJing Huang 				rb + CT2_CSI_FW_CTL_SET_REG);
8614d58cd64SJing Huang 
8624d58cd64SJing Huang 		for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
8634d58cd64SJing Huang 			r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
8644d58cd64SJing Huang 			if (r32 & __RESET_AND_START_SCLK_LCLK_PLLS)
8654d58cd64SJing Huang 				break;
8664d58cd64SJing Huang 		}
8674d58cd64SJing Huang 		BUG_ON(!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS));
8684d58cd64SJing Huang 
8694d58cd64SJing Huang 		for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
8704d58cd64SJing Huang 			r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
8714d58cd64SJing Huang 			if (!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS))
8724d58cd64SJing Huang 				break;
8734d58cd64SJing Huang 		}
8744d58cd64SJing Huang 		BUG_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS);
8754d58cd64SJing Huang 		udelay(1000);
8764d58cd64SJing Huang 
8774d58cd64SJing Huang 		r32 = readl(rb + CT2_CSI_FW_CTL_REG);
8784d58cd64SJing Huang 		BUG_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS);
8794d58cd64SJing Huang 	} else {
880be3a84d1SRasesh Mody 		writel(__HALT_NFC_CONTROLLER, (rb + CT2_NFC_CSR_SET_REG));
881be3a84d1SRasesh Mody 		for (i = 0; i < CT2_NFC_MAX_DELAY; i++) {
882be3a84d1SRasesh Mody 			r32 = readl(rb + CT2_NFC_CSR_SET_REG);
883be3a84d1SRasesh Mody 			if (r32 & __NFC_CONTROLLER_HALTED)
884be3a84d1SRasesh Mody 				break;
885be3a84d1SRasesh Mody 			udelay(1000);
886be3a84d1SRasesh Mody 		}
8874d58cd64SJing Huang 
8884d58cd64SJing Huang 		bfa_ioc_ct2_mac_reset(rb);
8894d58cd64SJing Huang 		bfa_ioc_ct2_sclk_init(rb);
8904d58cd64SJing Huang 		bfa_ioc_ct2_lclk_init(rb);
8914d58cd64SJing Huang 
8924d58cd64SJing Huang 		/* release soft reset on s_clk & l_clk */
893ebb56d37SIvan Vecera 		r32 = readl(rb + CT2_APP_PLL_SCLK_CTL_REG);
8944d58cd64SJing Huang 		writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET,
8954d58cd64SJing Huang 				rb + CT2_APP_PLL_SCLK_CTL_REG);
896ebb56d37SIvan Vecera 		r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
8974d58cd64SJing Huang 		writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
8984d58cd64SJing Huang 				rb + CT2_APP_PLL_LCLK_CTL_REG);
8994d58cd64SJing Huang 	}
9004d58cd64SJing Huang 
9014d58cd64SJing Huang 	/* Announce flash device presence, if flash was corrupted. */
9024d58cd64SJing Huang 	if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) {
903ebb56d37SIvan Vecera 		r32 = readl(rb + PSS_GPIO_OUT_REG);
9044d58cd64SJing Huang 		writel(r32 & ~1, rb + PSS_GPIO_OUT_REG);
905ebb56d37SIvan Vecera 		r32 = readl(rb + PSS_GPIO_OE_REG);
9064d58cd64SJing Huang 		writel(r32 | 1, rb + PSS_GPIO_OE_REG);
907be3a84d1SRasesh Mody 	}
908be3a84d1SRasesh Mody 
909be3a84d1SRasesh Mody 	/*
910be3a84d1SRasesh Mody 	 * Mask the interrupts and clear any
911be3a84d1SRasesh Mody 	 * pending interrupts left by BIOS/EFI
912be3a84d1SRasesh Mody 	 */
913ebb56d37SIvan Vecera 	writel(1, rb + CT2_LPU0_HOSTFN_MBOX0_MSK);
914ebb56d37SIvan Vecera 	writel(1, rb + CT2_LPU1_HOSTFN_MBOX0_MSK);
915be3a84d1SRasesh Mody 
9164d58cd64SJing Huang 	/* For first time initialization, no need to clear interrupts */
9174d58cd64SJing Huang 	r32 = readl(rb + HOST_SEM5_REG);
9184d58cd64SJing Huang 	if (r32 & 0x1) {
919ebb56d37SIvan Vecera 		r32 = readl(rb + CT2_LPU0_HOSTFN_CMD_STAT);
920be3a84d1SRasesh Mody 		if (r32 == 1) {
921ebb56d37SIvan Vecera 			writel(1, rb + CT2_LPU0_HOSTFN_CMD_STAT);
922ebb56d37SIvan Vecera 			readl(rb + CT2_LPU0_HOSTFN_CMD_STAT);
923be3a84d1SRasesh Mody 		}
924ebb56d37SIvan Vecera 		r32 = readl(rb + CT2_LPU1_HOSTFN_CMD_STAT);
925be3a84d1SRasesh Mody 		if (r32 == 1) {
926ebb56d37SIvan Vecera 			writel(1, rb + CT2_LPU1_HOSTFN_CMD_STAT);
927ebb56d37SIvan Vecera 			readl(rb + CT2_LPU1_HOSTFN_CMD_STAT);
928be3a84d1SRasesh Mody 		}
929be3a84d1SRasesh Mody 	}
930be3a84d1SRasesh Mody 
931be3a84d1SRasesh Mody 	bfa_ioc_ct2_mem_init(rb);
932be3a84d1SRasesh Mody 
933ebb56d37SIvan Vecera 	writel(BFI_IOC_UNINIT, rb + CT2_BFA_IOC0_STATE_REG);
934ebb56d37SIvan Vecera 	writel(BFI_IOC_UNINIT, rb + CT2_BFA_IOC1_STATE_REG);
935be3a84d1SRasesh Mody 	return BFA_STATUS_OK;
936be3a84d1SRasesh Mody }
937