10a20de44SKrishna Gudipati /* 2*889d0d42SAnil Gurumurthy * Copyright (c) 2005-2014 Brocade Communications Systems, Inc. 3*889d0d42SAnil Gurumurthy * Copyright (c) 2014- QLogic Corporation. 40a20de44SKrishna Gudipati * All rights reserved 5*889d0d42SAnil Gurumurthy * www.qlogic.com 60a20de44SKrishna Gudipati * 70a20de44SKrishna Gudipati * Linux driver for Brocade Fibre Channel Host Bus Adapter. 80a20de44SKrishna Gudipati * 90a20de44SKrishna Gudipati * This program is free software; you can redistribute it and/or modify it 100a20de44SKrishna Gudipati * under the terms of the GNU General Public License (GPL) Version 2 as 110a20de44SKrishna Gudipati * published by the Free Software Foundation 120a20de44SKrishna Gudipati * 130a20de44SKrishna Gudipati * This program is distributed in the hope that it will be useful, but 140a20de44SKrishna Gudipati * WITHOUT ANY WARRANTY; without even the implied warranty of 150a20de44SKrishna Gudipati * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 160a20de44SKrishna Gudipati * General Public License for more details. 170a20de44SKrishna Gudipati */ 180a20de44SKrishna Gudipati 19f16a1750SMaggie Zhang #include "bfad_drv.h" 20a36c61f9SKrishna Gudipati #include "bfa_ioc.h" 2111189208SKrishna Gudipati #include "bfi_reg.h" 22a36c61f9SKrishna Gudipati #include "bfa_defs.h" 230a20de44SKrishna Gudipati 240a20de44SKrishna Gudipati BFA_TRC_FILE(CNA, IOC_CT); 250a20de44SKrishna Gudipati 26f1d584d7SKrishna Gudipati #define bfa_ioc_ct_sync_pos(__ioc) \ 27f1d584d7SKrishna Gudipati ((uint32_t) (1 << bfa_ioc_pcifn(__ioc))) 28f1d584d7SKrishna Gudipati #define BFA_IOC_SYNC_REQD_SH 16 29f1d584d7SKrishna Gudipati #define bfa_ioc_ct_get_sync_ackd(__val) (__val & 0x0000ffff) 30f1d584d7SKrishna Gudipati #define bfa_ioc_ct_clear_sync_ackd(__val) (__val & 0xffff0000) 31f1d584d7SKrishna Gudipati #define bfa_ioc_ct_get_sync_reqd(__val) (__val >> BFA_IOC_SYNC_REQD_SH) 32f1d584d7SKrishna Gudipati #define bfa_ioc_ct_sync_reqd_pos(__ioc) \ 33f1d584d7SKrishna Gudipati (bfa_ioc_ct_sync_pos(__ioc) << BFA_IOC_SYNC_REQD_SH) 34f1d584d7SKrishna Gudipati 350a20de44SKrishna Gudipati /* 360a20de44SKrishna Gudipati * forward declarations 370a20de44SKrishna Gudipati */ 380a20de44SKrishna Gudipati static bfa_boolean_t bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc); 390a20de44SKrishna Gudipati static void bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc); 40f1d584d7SKrishna Gudipati static void bfa_ioc_ct_notify_fail(struct bfa_ioc_s *ioc); 410a20de44SKrishna Gudipati static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc); 4245d7f0ccSJing Huang static bfa_boolean_t bfa_ioc_ct_sync_start(struct bfa_ioc_s *ioc); 43f1d584d7SKrishna Gudipati static void bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc); 44f1d584d7SKrishna Gudipati static void bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc); 45f1d584d7SKrishna Gudipati static void bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc); 46f1d584d7SKrishna Gudipati static bfa_boolean_t bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc); 47c679b599SVijaya Mohan Guvva static void bfa_ioc_ct_set_cur_ioc_fwstate( 48c679b599SVijaya Mohan Guvva struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate); 49c679b599SVijaya Mohan Guvva static enum bfi_ioc_state bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc); 50c679b599SVijaya Mohan Guvva static void bfa_ioc_ct_set_alt_ioc_fwstate( 51c679b599SVijaya Mohan Guvva struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate); 52c679b599SVijaya Mohan Guvva static enum bfi_ioc_state bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc); 530a20de44SKrishna Gudipati 5452f94b6fSMaggie static struct bfa_ioc_hwif_s hwif_ct; 5511189208SKrishna Gudipati static struct bfa_ioc_hwif_s hwif_ct2; 560a20de44SKrishna Gudipati 575fbe25c7SJing Huang /* 580a20de44SKrishna Gudipati * Return true if firmware of current driver matches the running firmware. 590a20de44SKrishna Gudipati */ 600a20de44SKrishna Gudipati static bfa_boolean_t 610a20de44SKrishna Gudipati bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc) 620a20de44SKrishna Gudipati { 630a20de44SKrishna Gudipati enum bfi_ioc_state ioc_fwstate; 64d1c61f8eSKrishna Gudipati u32 usecnt; 650a20de44SKrishna Gudipati struct bfi_ioc_image_hdr_s fwhdr; 660a20de44SKrishna Gudipati 670a20de44SKrishna Gudipati bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); 6853440260SJing Huang usecnt = readl(ioc->ioc_regs.ioc_usage_reg); 690a20de44SKrishna Gudipati 705fbe25c7SJing Huang /* 710a20de44SKrishna Gudipati * If usage count is 0, always return TRUE. 720a20de44SKrishna Gudipati */ 730a20de44SKrishna Gudipati if (usecnt == 0) { 7453440260SJing Huang writel(1, ioc->ioc_regs.ioc_usage_reg); 755a0adaedSKrishna Gudipati readl(ioc->ioc_regs.ioc_usage_sem_reg); 76f7f73812SMaggie Zhang writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 77f1d584d7SKrishna Gudipati writel(0, ioc->ioc_regs.ioc_fail_sync); 780a20de44SKrishna Gudipati bfa_trc(ioc, usecnt); 790a20de44SKrishna Gudipati return BFA_TRUE; 800a20de44SKrishna Gudipati } 810a20de44SKrishna Gudipati 8253440260SJing Huang ioc_fwstate = readl(ioc->ioc_regs.ioc_fwstate); 830a20de44SKrishna Gudipati bfa_trc(ioc, ioc_fwstate); 840a20de44SKrishna Gudipati 855fbe25c7SJing Huang /* 860a20de44SKrishna Gudipati * Use count cannot be non-zero and chip in uninitialized state. 870a20de44SKrishna Gudipati */ 88d4b671c5SJing Huang WARN_ON(ioc_fwstate == BFI_IOC_UNINIT); 890a20de44SKrishna Gudipati 905fbe25c7SJing Huang /* 910a20de44SKrishna Gudipati * Check if another driver with a different firmware is active 920a20de44SKrishna Gudipati */ 930a20de44SKrishna Gudipati bfa_ioc_fwver_get(ioc, &fwhdr); 940a20de44SKrishna Gudipati if (!bfa_ioc_fwver_cmp(ioc, &fwhdr)) { 955a0adaedSKrishna Gudipati readl(ioc->ioc_regs.ioc_usage_sem_reg); 96f7f73812SMaggie Zhang writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 970a20de44SKrishna Gudipati bfa_trc(ioc, usecnt); 980a20de44SKrishna Gudipati return BFA_FALSE; 990a20de44SKrishna Gudipati } 1000a20de44SKrishna Gudipati 1015fbe25c7SJing Huang /* 1020a20de44SKrishna Gudipati * Same firmware version. Increment the reference count. 1030a20de44SKrishna Gudipati */ 1040a20de44SKrishna Gudipati usecnt++; 10553440260SJing Huang writel(usecnt, ioc->ioc_regs.ioc_usage_reg); 1065a0adaedSKrishna Gudipati readl(ioc->ioc_regs.ioc_usage_sem_reg); 107f7f73812SMaggie Zhang writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 1080a20de44SKrishna Gudipati bfa_trc(ioc, usecnt); 1090a20de44SKrishna Gudipati return BFA_TRUE; 1100a20de44SKrishna Gudipati } 1110a20de44SKrishna Gudipati 1120a20de44SKrishna Gudipati static void 1130a20de44SKrishna Gudipati bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc) 1140a20de44SKrishna Gudipati { 115d1c61f8eSKrishna Gudipati u32 usecnt; 1160a20de44SKrishna Gudipati 1175fbe25c7SJing Huang /* 1180a20de44SKrishna Gudipati * decrement usage count 1190a20de44SKrishna Gudipati */ 1200a20de44SKrishna Gudipati bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); 12153440260SJing Huang usecnt = readl(ioc->ioc_regs.ioc_usage_reg); 122d4b671c5SJing Huang WARN_ON(usecnt <= 0); 1230a20de44SKrishna Gudipati 1240a20de44SKrishna Gudipati usecnt--; 12553440260SJing Huang writel(usecnt, ioc->ioc_regs.ioc_usage_reg); 1260a20de44SKrishna Gudipati bfa_trc(ioc, usecnt); 1270a20de44SKrishna Gudipati 1285a0adaedSKrishna Gudipati readl(ioc->ioc_regs.ioc_usage_sem_reg); 129f7f73812SMaggie Zhang writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 1300a20de44SKrishna Gudipati } 1310a20de44SKrishna Gudipati 1325fbe25c7SJing Huang /* 1330a20de44SKrishna Gudipati * Notify other functions on HB failure. 1340a20de44SKrishna Gudipati */ 1350a20de44SKrishna Gudipati static void 136f1d584d7SKrishna Gudipati bfa_ioc_ct_notify_fail(struct bfa_ioc_s *ioc) 1370a20de44SKrishna Gudipati { 13811189208SKrishna Gudipati if (bfa_ioc_is_cna(ioc)) { 13953440260SJing Huang writel(__FW_INIT_HALT_P, ioc->ioc_regs.ll_halt); 140f1d584d7SKrishna Gudipati writel(__FW_INIT_HALT_P, ioc->ioc_regs.alt_ll_halt); 1410a20de44SKrishna Gudipati /* Wait for halt to take effect */ 14253440260SJing Huang readl(ioc->ioc_regs.ll_halt); 143f1d584d7SKrishna Gudipati readl(ioc->ioc_regs.alt_ll_halt); 144816e49b8SKrishna Gudipati } else { 14511189208SKrishna Gudipati writel(~0U, ioc->ioc_regs.err_set); 14653440260SJing Huang readl(ioc->ioc_regs.err_set); 147816e49b8SKrishna Gudipati } 1480a20de44SKrishna Gudipati } 1490a20de44SKrishna Gudipati 1505fbe25c7SJing Huang /* 1510a20de44SKrishna Gudipati * Host to LPU mailbox message addresses 1520a20de44SKrishna Gudipati */ 15311189208SKrishna Gudipati static struct { u32 hfn_mbox, lpu_mbox, hfn_pgn; } ct_fnreg[] = { 1540a20de44SKrishna Gudipati { HOSTFN0_LPU_MBOX0_0, LPU_HOSTFN0_MBOX0_0, HOST_PAGE_NUM_FN0 }, 1550a20de44SKrishna Gudipati { HOSTFN1_LPU_MBOX0_8, LPU_HOSTFN1_MBOX0_8, HOST_PAGE_NUM_FN1 }, 1560a20de44SKrishna Gudipati { HOSTFN2_LPU_MBOX0_0, LPU_HOSTFN2_MBOX0_0, HOST_PAGE_NUM_FN2 }, 1570a20de44SKrishna Gudipati { HOSTFN3_LPU_MBOX0_8, LPU_HOSTFN3_MBOX0_8, HOST_PAGE_NUM_FN3 } 1580a20de44SKrishna Gudipati }; 1590a20de44SKrishna Gudipati 1605fbe25c7SJing Huang /* 1610a20de44SKrishna Gudipati * Host <-> LPU mailbox command/status registers - port 0 1620a20de44SKrishna Gudipati */ 16311189208SKrishna Gudipati static struct { u32 hfn, lpu; } ct_p0reg[] = { 16411189208SKrishna Gudipati { HOSTFN0_LPU0_CMD_STAT, LPU0_HOSTFN0_CMD_STAT }, 16511189208SKrishna Gudipati { HOSTFN1_LPU0_CMD_STAT, LPU0_HOSTFN1_CMD_STAT }, 16611189208SKrishna Gudipati { HOSTFN2_LPU0_CMD_STAT, LPU0_HOSTFN2_CMD_STAT }, 16711189208SKrishna Gudipati { HOSTFN3_LPU0_CMD_STAT, LPU0_HOSTFN3_CMD_STAT } 1680a20de44SKrishna Gudipati }; 1690a20de44SKrishna Gudipati 1705fbe25c7SJing Huang /* 1710a20de44SKrishna Gudipati * Host <-> LPU mailbox command/status registers - port 1 1720a20de44SKrishna Gudipati */ 17311189208SKrishna Gudipati static struct { u32 hfn, lpu; } ct_p1reg[] = { 17411189208SKrishna Gudipati { HOSTFN0_LPU1_CMD_STAT, LPU1_HOSTFN0_CMD_STAT }, 17511189208SKrishna Gudipati { HOSTFN1_LPU1_CMD_STAT, LPU1_HOSTFN1_CMD_STAT }, 17611189208SKrishna Gudipati { HOSTFN2_LPU1_CMD_STAT, LPU1_HOSTFN2_CMD_STAT }, 17711189208SKrishna Gudipati { HOSTFN3_LPU1_CMD_STAT, LPU1_HOSTFN3_CMD_STAT } 17811189208SKrishna Gudipati }; 17911189208SKrishna Gudipati 1808b070b4aSKrishna Gudipati static struct { uint32_t hfn_mbox, lpu_mbox, hfn_pgn, hfn, lpu, lpu_read; } 1818b070b4aSKrishna Gudipati ct2_reg[] = { 18211189208SKrishna Gudipati { CT2_HOSTFN_LPU0_MBOX0, CT2_LPU0_HOSTFN_MBOX0, CT2_HOSTFN_PAGE_NUM, 1838b070b4aSKrishna Gudipati CT2_HOSTFN_LPU0_CMD_STAT, CT2_LPU0_HOSTFN_CMD_STAT, 1848b070b4aSKrishna Gudipati CT2_HOSTFN_LPU0_READ_STAT}, 18511189208SKrishna Gudipati { CT2_HOSTFN_LPU1_MBOX0, CT2_LPU1_HOSTFN_MBOX0, CT2_HOSTFN_PAGE_NUM, 1868b070b4aSKrishna Gudipati CT2_HOSTFN_LPU1_CMD_STAT, CT2_LPU1_HOSTFN_CMD_STAT, 1878b070b4aSKrishna Gudipati CT2_HOSTFN_LPU1_READ_STAT}, 1880a20de44SKrishna Gudipati }; 1890a20de44SKrishna Gudipati 1900a20de44SKrishna Gudipati static void 1910a20de44SKrishna Gudipati bfa_ioc_ct_reg_init(struct bfa_ioc_s *ioc) 1920a20de44SKrishna Gudipati { 19353440260SJing Huang void __iomem *rb; 1940a20de44SKrishna Gudipati int pcifn = bfa_ioc_pcifn(ioc); 1950a20de44SKrishna Gudipati 1960a20de44SKrishna Gudipati rb = bfa_ioc_bar0(ioc); 1970a20de44SKrishna Gudipati 19811189208SKrishna Gudipati ioc->ioc_regs.hfn_mbox = rb + ct_fnreg[pcifn].hfn_mbox; 19911189208SKrishna Gudipati ioc->ioc_regs.lpu_mbox = rb + ct_fnreg[pcifn].lpu_mbox; 20011189208SKrishna Gudipati ioc->ioc_regs.host_page_num_fn = rb + ct_fnreg[pcifn].hfn_pgn; 2010a20de44SKrishna Gudipati 2020a20de44SKrishna Gudipati if (ioc->port_id == 0) { 2030a20de44SKrishna Gudipati ioc->ioc_regs.heartbeat = rb + BFA_IOC0_HBEAT_REG; 2040a20de44SKrishna Gudipati ioc->ioc_regs.ioc_fwstate = rb + BFA_IOC0_STATE_REG; 205f1d584d7SKrishna Gudipati ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC1_STATE_REG; 20611189208SKrishna Gudipati ioc->ioc_regs.hfn_mbox_cmd = rb + ct_p0reg[pcifn].hfn; 20711189208SKrishna Gudipati ioc->ioc_regs.lpu_mbox_cmd = rb + ct_p0reg[pcifn].lpu; 2080a20de44SKrishna Gudipati ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0; 209f1d584d7SKrishna Gudipati ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P1; 2100a20de44SKrishna Gudipati } else { 2110a20de44SKrishna Gudipati ioc->ioc_regs.heartbeat = (rb + BFA_IOC1_HBEAT_REG); 2120a20de44SKrishna Gudipati ioc->ioc_regs.ioc_fwstate = (rb + BFA_IOC1_STATE_REG); 213f1d584d7SKrishna Gudipati ioc->ioc_regs.alt_ioc_fwstate = rb + BFA_IOC0_STATE_REG; 21411189208SKrishna Gudipati ioc->ioc_regs.hfn_mbox_cmd = rb + ct_p1reg[pcifn].hfn; 21511189208SKrishna Gudipati ioc->ioc_regs.lpu_mbox_cmd = rb + ct_p1reg[pcifn].lpu; 2160a20de44SKrishna Gudipati ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1; 217f1d584d7SKrishna Gudipati ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P0; 2180a20de44SKrishna Gudipati } 2190a20de44SKrishna Gudipati 2200a20de44SKrishna Gudipati /* 2210a20de44SKrishna Gudipati * PSS control registers 2220a20de44SKrishna Gudipati */ 2230a20de44SKrishna Gudipati ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); 2248b651b42SKrishna Gudipati ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG); 22511189208SKrishna Gudipati ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + APP_PLL_LCLK_CTL_REG); 22611189208SKrishna Gudipati ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + APP_PLL_SCLK_CTL_REG); 2270a20de44SKrishna Gudipati 2280a20de44SKrishna Gudipati /* 2290a20de44SKrishna Gudipati * IOC semaphore registers and serialization 2300a20de44SKrishna Gudipati */ 2310a20de44SKrishna Gudipati ioc->ioc_regs.ioc_sem_reg = (rb + HOST_SEM0_REG); 2320a20de44SKrishna Gudipati ioc->ioc_regs.ioc_usage_sem_reg = (rb + HOST_SEM1_REG); 2330a20de44SKrishna Gudipati ioc->ioc_regs.ioc_init_sem_reg = (rb + HOST_SEM2_REG); 2340a20de44SKrishna Gudipati ioc->ioc_regs.ioc_usage_reg = (rb + BFA_FW_USE_COUNT); 235f1d584d7SKrishna Gudipati ioc->ioc_regs.ioc_fail_sync = (rb + BFA_IOC_FAIL_SYNC); 2360a20de44SKrishna Gudipati 2375fbe25c7SJing Huang /* 2380a20de44SKrishna Gudipati * sram memory access 2390a20de44SKrishna Gudipati */ 2400a20de44SKrishna Gudipati ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); 2410a20de44SKrishna Gudipati ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT; 242816e49b8SKrishna Gudipati 243816e49b8SKrishna Gudipati /* 244816e49b8SKrishna Gudipati * err set reg : for notification of hb failure in fcmode 245816e49b8SKrishna Gudipati */ 246816e49b8SKrishna Gudipati ioc->ioc_regs.err_set = (rb + ERR_SET_REG); 2470a20de44SKrishna Gudipati } 2480a20de44SKrishna Gudipati 24911189208SKrishna Gudipati static void 25011189208SKrishna Gudipati bfa_ioc_ct2_reg_init(struct bfa_ioc_s *ioc) 25111189208SKrishna Gudipati { 25211189208SKrishna Gudipati void __iomem *rb; 25311189208SKrishna Gudipati int port = bfa_ioc_portid(ioc); 25411189208SKrishna Gudipati 25511189208SKrishna Gudipati rb = bfa_ioc_bar0(ioc); 25611189208SKrishna Gudipati 25711189208SKrishna Gudipati ioc->ioc_regs.hfn_mbox = rb + ct2_reg[port].hfn_mbox; 25811189208SKrishna Gudipati ioc->ioc_regs.lpu_mbox = rb + ct2_reg[port].lpu_mbox; 25911189208SKrishna Gudipati ioc->ioc_regs.host_page_num_fn = rb + ct2_reg[port].hfn_pgn; 26011189208SKrishna Gudipati ioc->ioc_regs.hfn_mbox_cmd = rb + ct2_reg[port].hfn; 26111189208SKrishna Gudipati ioc->ioc_regs.lpu_mbox_cmd = rb + ct2_reg[port].lpu; 2628b070b4aSKrishna Gudipati ioc->ioc_regs.lpu_read_stat = rb + ct2_reg[port].lpu_read; 26311189208SKrishna Gudipati 26411189208SKrishna Gudipati if (port == 0) { 26511189208SKrishna Gudipati ioc->ioc_regs.heartbeat = rb + CT2_BFA_IOC0_HBEAT_REG; 26611189208SKrishna Gudipati ioc->ioc_regs.ioc_fwstate = rb + CT2_BFA_IOC0_STATE_REG; 26711189208SKrishna Gudipati ioc->ioc_regs.alt_ioc_fwstate = rb + CT2_BFA_IOC1_STATE_REG; 26811189208SKrishna Gudipati ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P0; 26911189208SKrishna Gudipati ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P1; 27011189208SKrishna Gudipati } else { 27111189208SKrishna Gudipati ioc->ioc_regs.heartbeat = (rb + CT2_BFA_IOC1_HBEAT_REG); 27211189208SKrishna Gudipati ioc->ioc_regs.ioc_fwstate = (rb + CT2_BFA_IOC1_STATE_REG); 27311189208SKrishna Gudipati ioc->ioc_regs.alt_ioc_fwstate = rb + CT2_BFA_IOC0_STATE_REG; 27411189208SKrishna Gudipati ioc->ioc_regs.ll_halt = rb + FW_INIT_HALT_P1; 27511189208SKrishna Gudipati ioc->ioc_regs.alt_ll_halt = rb + FW_INIT_HALT_P0; 27611189208SKrishna Gudipati } 27711189208SKrishna Gudipati 27811189208SKrishna Gudipati /* 27911189208SKrishna Gudipati * PSS control registers 28011189208SKrishna Gudipati */ 28111189208SKrishna Gudipati ioc->ioc_regs.pss_ctl_reg = (rb + PSS_CTL_REG); 28211189208SKrishna Gudipati ioc->ioc_regs.pss_err_status_reg = (rb + PSS_ERR_STATUS_REG); 28311189208SKrishna Gudipati ioc->ioc_regs.app_pll_fast_ctl_reg = (rb + CT2_APP_PLL_LCLK_CTL_REG); 28411189208SKrishna Gudipati ioc->ioc_regs.app_pll_slow_ctl_reg = (rb + CT2_APP_PLL_SCLK_CTL_REG); 28511189208SKrishna Gudipati 28611189208SKrishna Gudipati /* 28711189208SKrishna Gudipati * IOC semaphore registers and serialization 28811189208SKrishna Gudipati */ 28911189208SKrishna Gudipati ioc->ioc_regs.ioc_sem_reg = (rb + CT2_HOST_SEM0_REG); 29011189208SKrishna Gudipati ioc->ioc_regs.ioc_usage_sem_reg = (rb + CT2_HOST_SEM1_REG); 29111189208SKrishna Gudipati ioc->ioc_regs.ioc_init_sem_reg = (rb + CT2_HOST_SEM2_REG); 292775c7742SKrishna Gudipati ioc->ioc_regs.ioc_usage_reg = (rb + CT2_BFA_FW_USE_COUNT); 293775c7742SKrishna Gudipati ioc->ioc_regs.ioc_fail_sync = (rb + CT2_BFA_IOC_FAIL_SYNC); 29411189208SKrishna Gudipati 29511189208SKrishna Gudipati /* 29611189208SKrishna Gudipati * sram memory access 29711189208SKrishna Gudipati */ 29811189208SKrishna Gudipati ioc->ioc_regs.smem_page_start = (rb + PSS_SMEM_PAGE_START); 29911189208SKrishna Gudipati ioc->ioc_regs.smem_pg0 = BFI_IOC_SMEM_PG0_CT; 30011189208SKrishna Gudipati 30111189208SKrishna Gudipati /* 30211189208SKrishna Gudipati * err set reg : for notification of hb failure in fcmode 30311189208SKrishna Gudipati */ 30411189208SKrishna Gudipati ioc->ioc_regs.err_set = (rb + ERR_SET_REG); 30511189208SKrishna Gudipati } 30611189208SKrishna Gudipati 3075fbe25c7SJing Huang /* 3080a20de44SKrishna Gudipati * Initialize IOC to port mapping. 3090a20de44SKrishna Gudipati */ 3100a20de44SKrishna Gudipati 3110a20de44SKrishna Gudipati #define FNC_PERS_FN_SHIFT(__fn) ((__fn) * 8) 3120a20de44SKrishna Gudipati static void 3130a20de44SKrishna Gudipati bfa_ioc_ct_map_port(struct bfa_ioc_s *ioc) 3140a20de44SKrishna Gudipati { 31553440260SJing Huang void __iomem *rb = ioc->pcidev.pci_bar_kva; 316d1c61f8eSKrishna Gudipati u32 r32; 3170a20de44SKrishna Gudipati 3185fbe25c7SJing Huang /* 3190a20de44SKrishna Gudipati * For catapult, base port id on personality register and IOC type 3200a20de44SKrishna Gudipati */ 32153440260SJing Huang r32 = readl(rb + FNC_PERS_REG); 3220a20de44SKrishna Gudipati r32 >>= FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc)); 3230a20de44SKrishna Gudipati ioc->port_id = (r32 & __F0_PORT_MAP_MK) >> __F0_PORT_MAP_SH; 3240a20de44SKrishna Gudipati 3250a20de44SKrishna Gudipati bfa_trc(ioc, bfa_ioc_pcifn(ioc)); 3260a20de44SKrishna Gudipati bfa_trc(ioc, ioc->port_id); 3270a20de44SKrishna Gudipati } 3280a20de44SKrishna Gudipati 32911189208SKrishna Gudipati static void 33011189208SKrishna Gudipati bfa_ioc_ct2_map_port(struct bfa_ioc_s *ioc) 33111189208SKrishna Gudipati { 3325a0adaedSKrishna Gudipati void __iomem *rb = ioc->pcidev.pci_bar_kva; 3335a0adaedSKrishna Gudipati u32 r32; 3345a0adaedSKrishna Gudipati 3355a0adaedSKrishna Gudipati r32 = readl(rb + CT2_HOSTFN_PERSONALITY0); 3365a0adaedSKrishna Gudipati ioc->port_id = ((r32 & __FC_LL_PORT_MAP__MK) >> __FC_LL_PORT_MAP__SH); 33711189208SKrishna Gudipati 33811189208SKrishna Gudipati bfa_trc(ioc, bfa_ioc_pcifn(ioc)); 33911189208SKrishna Gudipati bfa_trc(ioc, ioc->port_id); 34011189208SKrishna Gudipati } 34111189208SKrishna Gudipati 3425fbe25c7SJing Huang /* 3430a20de44SKrishna Gudipati * Set interrupt mode for a function: INTX or MSIX 3440a20de44SKrishna Gudipati */ 3450a20de44SKrishna Gudipati static void 3460a20de44SKrishna Gudipati bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix) 3470a20de44SKrishna Gudipati { 34853440260SJing Huang void __iomem *rb = ioc->pcidev.pci_bar_kva; 349d1c61f8eSKrishna Gudipati u32 r32, mode; 3500a20de44SKrishna Gudipati 35153440260SJing Huang r32 = readl(rb + FNC_PERS_REG); 3520a20de44SKrishna Gudipati bfa_trc(ioc, r32); 3530a20de44SKrishna Gudipati 3540a20de44SKrishna Gudipati mode = (r32 >> FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))) & 3550a20de44SKrishna Gudipati __F0_INTX_STATUS; 3560a20de44SKrishna Gudipati 3575fbe25c7SJing Huang /* 3580a20de44SKrishna Gudipati * If already in desired mode, do not change anything 3590a20de44SKrishna Gudipati */ 36011189208SKrishna Gudipati if ((!msix && mode) || (msix && !mode)) 3610a20de44SKrishna Gudipati return; 3620a20de44SKrishna Gudipati 3630a20de44SKrishna Gudipati if (msix) 3640a20de44SKrishna Gudipati mode = __F0_INTX_STATUS_MSIX; 3650a20de44SKrishna Gudipati else 3660a20de44SKrishna Gudipati mode = __F0_INTX_STATUS_INTA; 3670a20de44SKrishna Gudipati 3680a20de44SKrishna Gudipati r32 &= ~(__F0_INTX_STATUS << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); 3690a20de44SKrishna Gudipati r32 |= (mode << FNC_PERS_FN_SHIFT(bfa_ioc_pcifn(ioc))); 3700a20de44SKrishna Gudipati bfa_trc(ioc, r32); 3710a20de44SKrishna Gudipati 37253440260SJing Huang writel(r32, rb + FNC_PERS_REG); 3730a20de44SKrishna Gudipati } 3740a20de44SKrishna Gudipati 3758b070b4aSKrishna Gudipati bfa_boolean_t 3768b070b4aSKrishna Gudipati bfa_ioc_ct2_lpu_read_stat(struct bfa_ioc_s *ioc) 3778b070b4aSKrishna Gudipati { 3788b070b4aSKrishna Gudipati u32 r32; 3798b070b4aSKrishna Gudipati 3808b070b4aSKrishna Gudipati r32 = readl(ioc->ioc_regs.lpu_read_stat); 3818b070b4aSKrishna Gudipati if (r32) { 3828b070b4aSKrishna Gudipati writel(1, ioc->ioc_regs.lpu_read_stat); 3838b070b4aSKrishna Gudipati return BFA_TRUE; 3848b070b4aSKrishna Gudipati } 3858b070b4aSKrishna Gudipati 3868b070b4aSKrishna Gudipati return BFA_FALSE; 3878b070b4aSKrishna Gudipati } 3888b070b4aSKrishna Gudipati 3895fbe25c7SJing Huang /* 3900a20de44SKrishna Gudipati * Cleanup hw semaphore and usecnt registers 3910a20de44SKrishna Gudipati */ 3920a20de44SKrishna Gudipati static void 3930a20de44SKrishna Gudipati bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc) 3940a20de44SKrishna Gudipati { 3950a20de44SKrishna Gudipati 3960a20de44SKrishna Gudipati bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg); 39753440260SJing Huang writel(0, ioc->ioc_regs.ioc_usage_reg); 3985a0adaedSKrishna Gudipati readl(ioc->ioc_regs.ioc_usage_sem_reg); 399f7f73812SMaggie Zhang writel(1, ioc->ioc_regs.ioc_usage_sem_reg); 4000a20de44SKrishna Gudipati 4017ac83b1fSKrishna Gudipati writel(0, ioc->ioc_regs.ioc_fail_sync); 4020a20de44SKrishna Gudipati /* 4030a20de44SKrishna Gudipati * Read the hw sem reg to make sure that it is locked 4040a20de44SKrishna Gudipati * before we clear it. If it is not locked, writing 1 4050a20de44SKrishna Gudipati * will lock it instead of clearing it. 4060a20de44SKrishna Gudipati */ 40753440260SJing Huang readl(ioc->ioc_regs.ioc_sem_reg); 408f7f73812SMaggie Zhang writel(1, ioc->ioc_regs.ioc_sem_reg); 4090a20de44SKrishna Gudipati } 410a36c61f9SKrishna Gudipati 41145d7f0ccSJing Huang static bfa_boolean_t 41245d7f0ccSJing Huang bfa_ioc_ct_sync_start(struct bfa_ioc_s *ioc) 41345d7f0ccSJing Huang { 41445d7f0ccSJing Huang uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync); 41545d7f0ccSJing Huang uint32_t sync_reqd = bfa_ioc_ct_get_sync_reqd(r32); 41645d7f0ccSJing Huang 41745d7f0ccSJing Huang /* 41845d7f0ccSJing Huang * Driver load time. If the sync required bit for this PCI fn 41945d7f0ccSJing Huang * is set, it is due to an unclean exit by the driver for this 42045d7f0ccSJing Huang * PCI fn in the previous incarnation. Whoever comes here first 42145d7f0ccSJing Huang * should clean it up, no matter which PCI fn. 42245d7f0ccSJing Huang */ 42345d7f0ccSJing Huang 42445d7f0ccSJing Huang if (sync_reqd & bfa_ioc_ct_sync_pos(ioc)) { 42545d7f0ccSJing Huang writel(0, ioc->ioc_regs.ioc_fail_sync); 42645d7f0ccSJing Huang writel(1, ioc->ioc_regs.ioc_usage_reg); 42745d7f0ccSJing Huang writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate); 42845d7f0ccSJing Huang writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate); 42945d7f0ccSJing Huang return BFA_TRUE; 43045d7f0ccSJing Huang } 43145d7f0ccSJing Huang 43245d7f0ccSJing Huang return bfa_ioc_ct_sync_complete(ioc); 43345d7f0ccSJing Huang } 43445d7f0ccSJing Huang 4358f4bfaddSJing Huang /* 436f1d584d7SKrishna Gudipati * Synchronized IOC failure processing routines 437f1d584d7SKrishna Gudipati */ 438f1d584d7SKrishna Gudipati static void 439f1d584d7SKrishna Gudipati bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc) 440f1d584d7SKrishna Gudipati { 441f1d584d7SKrishna Gudipati uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync); 442f1d584d7SKrishna Gudipati uint32_t sync_pos = bfa_ioc_ct_sync_reqd_pos(ioc); 443a36c61f9SKrishna Gudipati 444f1d584d7SKrishna Gudipati writel((r32 | sync_pos), ioc->ioc_regs.ioc_fail_sync); 445f1d584d7SKrishna Gudipati } 446f1d584d7SKrishna Gudipati 447f1d584d7SKrishna Gudipati static void 448f1d584d7SKrishna Gudipati bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc) 449f1d584d7SKrishna Gudipati { 450f1d584d7SKrishna Gudipati uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync); 451f1d584d7SKrishna Gudipati uint32_t sync_msk = bfa_ioc_ct_sync_reqd_pos(ioc) | 452f1d584d7SKrishna Gudipati bfa_ioc_ct_sync_pos(ioc); 453f1d584d7SKrishna Gudipati 454f1d584d7SKrishna Gudipati writel((r32 & ~sync_msk), ioc->ioc_regs.ioc_fail_sync); 455f1d584d7SKrishna Gudipati } 456f1d584d7SKrishna Gudipati 457f1d584d7SKrishna Gudipati static void 458f1d584d7SKrishna Gudipati bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc) 459f1d584d7SKrishna Gudipati { 460f1d584d7SKrishna Gudipati uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync); 461f1d584d7SKrishna Gudipati 462f1d584d7SKrishna Gudipati writel((r32 | bfa_ioc_ct_sync_pos(ioc)), 463f1d584d7SKrishna Gudipati ioc->ioc_regs.ioc_fail_sync); 464f1d584d7SKrishna Gudipati } 465f1d584d7SKrishna Gudipati 466f1d584d7SKrishna Gudipati static bfa_boolean_t 467f1d584d7SKrishna Gudipati bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc) 468f1d584d7SKrishna Gudipati { 469f1d584d7SKrishna Gudipati uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync); 470f1d584d7SKrishna Gudipati uint32_t sync_reqd = bfa_ioc_ct_get_sync_reqd(r32); 471f1d584d7SKrishna Gudipati uint32_t sync_ackd = bfa_ioc_ct_get_sync_ackd(r32); 472f1d584d7SKrishna Gudipati uint32_t tmp_ackd; 473f1d584d7SKrishna Gudipati 474f1d584d7SKrishna Gudipati if (sync_ackd == 0) 475f1d584d7SKrishna Gudipati return BFA_TRUE; 476f1d584d7SKrishna Gudipati 4778f4bfaddSJing Huang /* 478f1d584d7SKrishna Gudipati * The check below is to see whether any other PCI fn 479f1d584d7SKrishna Gudipati * has reinitialized the ASIC (reset sync_ackd bits) 480f1d584d7SKrishna Gudipati * and failed again while this IOC was waiting for hw 481f1d584d7SKrishna Gudipati * semaphore (in bfa_iocpf_sm_semwait()). 482f1d584d7SKrishna Gudipati */ 483f1d584d7SKrishna Gudipati tmp_ackd = sync_ackd; 484f1d584d7SKrishna Gudipati if ((sync_reqd & bfa_ioc_ct_sync_pos(ioc)) && 485f1d584d7SKrishna Gudipati !(sync_ackd & bfa_ioc_ct_sync_pos(ioc))) 486f1d584d7SKrishna Gudipati sync_ackd |= bfa_ioc_ct_sync_pos(ioc); 487f1d584d7SKrishna Gudipati 488f1d584d7SKrishna Gudipati if (sync_reqd == sync_ackd) { 489f1d584d7SKrishna Gudipati writel(bfa_ioc_ct_clear_sync_ackd(r32), 490f1d584d7SKrishna Gudipati ioc->ioc_regs.ioc_fail_sync); 491f1d584d7SKrishna Gudipati writel(BFI_IOC_FAIL, ioc->ioc_regs.ioc_fwstate); 492f1d584d7SKrishna Gudipati writel(BFI_IOC_FAIL, ioc->ioc_regs.alt_ioc_fwstate); 493f1d584d7SKrishna Gudipati return BFA_TRUE; 494f1d584d7SKrishna Gudipati } 495f1d584d7SKrishna Gudipati 4968f4bfaddSJing Huang /* 497f1d584d7SKrishna Gudipati * If another PCI fn reinitialized and failed again while 498f1d584d7SKrishna Gudipati * this IOC was waiting for hw sem, the sync_ackd bit for 499f1d584d7SKrishna Gudipati * this IOC need to be set again to allow reinitialization. 500f1d584d7SKrishna Gudipati */ 501f1d584d7SKrishna Gudipati if (tmp_ackd != sync_ackd) 502f1d584d7SKrishna Gudipati writel((r32 | sync_ackd), ioc->ioc_regs.ioc_fail_sync); 503f1d584d7SKrishna Gudipati 504f1d584d7SKrishna Gudipati return BFA_FALSE; 505f1d584d7SKrishna Gudipati } 506a36c61f9SKrishna Gudipati 50711189208SKrishna Gudipati /** 50811189208SKrishna Gudipati * Called from bfa_ioc_attach() to map asic specific calls. 509a36c61f9SKrishna Gudipati */ 51011189208SKrishna Gudipati static void 51111189208SKrishna Gudipati bfa_ioc_set_ctx_hwif(struct bfa_ioc_s *ioc, struct bfa_ioc_hwif_s *hwif) 512a36c61f9SKrishna Gudipati { 51311189208SKrishna Gudipati hwif->ioc_firmware_lock = bfa_ioc_ct_firmware_lock; 51411189208SKrishna Gudipati hwif->ioc_firmware_unlock = bfa_ioc_ct_firmware_unlock; 51511189208SKrishna Gudipati hwif->ioc_notify_fail = bfa_ioc_ct_notify_fail; 51611189208SKrishna Gudipati hwif->ioc_ownership_reset = bfa_ioc_ct_ownership_reset; 51711189208SKrishna Gudipati hwif->ioc_sync_start = bfa_ioc_ct_sync_start; 51811189208SKrishna Gudipati hwif->ioc_sync_join = bfa_ioc_ct_sync_join; 51911189208SKrishna Gudipati hwif->ioc_sync_leave = bfa_ioc_ct_sync_leave; 52011189208SKrishna Gudipati hwif->ioc_sync_ack = bfa_ioc_ct_sync_ack; 52111189208SKrishna Gudipati hwif->ioc_sync_complete = bfa_ioc_ct_sync_complete; 522c679b599SVijaya Mohan Guvva hwif->ioc_set_fwstate = bfa_ioc_ct_set_cur_ioc_fwstate; 523c679b599SVijaya Mohan Guvva hwif->ioc_get_fwstate = bfa_ioc_ct_get_cur_ioc_fwstate; 524c679b599SVijaya Mohan Guvva hwif->ioc_set_alt_fwstate = bfa_ioc_ct_set_alt_ioc_fwstate; 525c679b599SVijaya Mohan Guvva hwif->ioc_get_alt_fwstate = bfa_ioc_ct_get_alt_ioc_fwstate; 52611189208SKrishna Gudipati } 527a36c61f9SKrishna Gudipati 52811189208SKrishna Gudipati /** 52911189208SKrishna Gudipati * Called from bfa_ioc_attach() to map asic specific calls. 53011189208SKrishna Gudipati */ 53111189208SKrishna Gudipati void 53211189208SKrishna Gudipati bfa_ioc_set_ct_hwif(struct bfa_ioc_s *ioc) 53311189208SKrishna Gudipati { 53411189208SKrishna Gudipati bfa_ioc_set_ctx_hwif(ioc, &hwif_ct); 53511189208SKrishna Gudipati 53611189208SKrishna Gudipati hwif_ct.ioc_pll_init = bfa_ioc_ct_pll_init; 53711189208SKrishna Gudipati hwif_ct.ioc_reg_init = bfa_ioc_ct_reg_init; 53811189208SKrishna Gudipati hwif_ct.ioc_map_port = bfa_ioc_ct_map_port; 53911189208SKrishna Gudipati hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set; 54011189208SKrishna Gudipati ioc->ioc_hwif = &hwif_ct; 54111189208SKrishna Gudipati } 54211189208SKrishna Gudipati 54311189208SKrishna Gudipati /** 54411189208SKrishna Gudipati * Called from bfa_ioc_attach() to map asic specific calls. 54511189208SKrishna Gudipati */ 54611189208SKrishna Gudipati void 54711189208SKrishna Gudipati bfa_ioc_set_ct2_hwif(struct bfa_ioc_s *ioc) 54811189208SKrishna Gudipati { 54911189208SKrishna Gudipati bfa_ioc_set_ctx_hwif(ioc, &hwif_ct2); 55011189208SKrishna Gudipati 55111189208SKrishna Gudipati hwif_ct2.ioc_pll_init = bfa_ioc_ct2_pll_init; 55211189208SKrishna Gudipati hwif_ct2.ioc_reg_init = bfa_ioc_ct2_reg_init; 55311189208SKrishna Gudipati hwif_ct2.ioc_map_port = bfa_ioc_ct2_map_port; 5548b070b4aSKrishna Gudipati hwif_ct2.ioc_lpu_read_stat = bfa_ioc_ct2_lpu_read_stat; 55511189208SKrishna Gudipati hwif_ct2.ioc_isr_mode_set = NULL; 55611189208SKrishna Gudipati ioc->ioc_hwif = &hwif_ct2; 55711189208SKrishna Gudipati } 55811189208SKrishna Gudipati 55911189208SKrishna Gudipati /* 5603fd45980SKrishna Gudipati * Workaround for MSI-X resource allocation for catapult-2 with no asic block 56111189208SKrishna Gudipati */ 5623fd45980SKrishna Gudipati #define HOSTFN_MSIX_DEFAULT 64 56310a07379SKrishna Gudipati #define HOSTFN_MSIX_VT_INDEX_MBOX_ERR 0x30138 56411189208SKrishna Gudipati #define HOSTFN_MSIX_VT_OFST_NUMVT 0x3013c 56511189208SKrishna Gudipati #define __MSIX_VT_NUMVT__MK 0x003ff800 56611189208SKrishna Gudipati #define __MSIX_VT_NUMVT__SH 11 56711189208SKrishna Gudipati #define __MSIX_VT_NUMVT_(_v) ((_v) << __MSIX_VT_NUMVT__SH) 56810a07379SKrishna Gudipati #define __MSIX_VT_OFST_ 0x000007ff 56911189208SKrishna Gudipati void 57011189208SKrishna Gudipati bfa_ioc_ct2_poweron(struct bfa_ioc_s *ioc) 57111189208SKrishna Gudipati { 57211189208SKrishna Gudipati void __iomem *rb = ioc->pcidev.pci_bar_kva; 57311189208SKrishna Gudipati u32 r32; 57411189208SKrishna Gudipati 57511189208SKrishna Gudipati r32 = readl(rb + HOSTFN_MSIX_VT_OFST_NUMVT); 57610a07379SKrishna Gudipati if (r32 & __MSIX_VT_NUMVT__MK) { 57710a07379SKrishna Gudipati writel(r32 & __MSIX_VT_OFST_, 57810a07379SKrishna Gudipati rb + HOSTFN_MSIX_VT_INDEX_MBOX_ERR); 57911189208SKrishna Gudipati return; 58010a07379SKrishna Gudipati } 58111189208SKrishna Gudipati 58211189208SKrishna Gudipati writel(__MSIX_VT_NUMVT_(HOSTFN_MSIX_DEFAULT - 1) | 58311189208SKrishna Gudipati HOSTFN_MSIX_DEFAULT * bfa_ioc_pcifn(ioc), 58411189208SKrishna Gudipati rb + HOSTFN_MSIX_VT_OFST_NUMVT); 58510a07379SKrishna Gudipati writel(HOSTFN_MSIX_DEFAULT * bfa_ioc_pcifn(ioc), 58610a07379SKrishna Gudipati rb + HOSTFN_MSIX_VT_INDEX_MBOX_ERR); 587a36c61f9SKrishna Gudipati } 588a36c61f9SKrishna Gudipati 589a36c61f9SKrishna Gudipati bfa_status_t 59011189208SKrishna Gudipati bfa_ioc_ct_pll_init(void __iomem *rb, enum bfi_asic_mode mode) 591a36c61f9SKrishna Gudipati { 592a36c61f9SKrishna Gudipati u32 pll_sclk, pll_fclk, r32; 59311189208SKrishna Gudipati bfa_boolean_t fcmode = (mode == BFI_ASIC_MODE_FC); 594a36c61f9SKrishna Gudipati 59511189208SKrishna Gudipati pll_sclk = __APP_PLL_SCLK_LRESETN | __APP_PLL_SCLK_ENARST | 59611189208SKrishna Gudipati __APP_PLL_SCLK_RSEL200500 | __APP_PLL_SCLK_P0_1(3U) | 59711189208SKrishna Gudipati __APP_PLL_SCLK_JITLMT0_1(3U) | 59811189208SKrishna Gudipati __APP_PLL_SCLK_CNTLMT0_1(1U); 59911189208SKrishna Gudipati pll_fclk = __APP_PLL_LCLK_LRESETN | __APP_PLL_LCLK_ENARST | 60011189208SKrishna Gudipati __APP_PLL_LCLK_RSEL200500 | __APP_PLL_LCLK_P0_1(3U) | 60111189208SKrishna Gudipati __APP_PLL_LCLK_JITLMT0_1(3U) | 60211189208SKrishna Gudipati __APP_PLL_LCLK_CNTLMT0_1(1U); 60311189208SKrishna Gudipati 604a36c61f9SKrishna Gudipati if (fcmode) { 60553440260SJing Huang writel(0, (rb + OP_MODE)); 60653440260SJing Huang writel(__APP_EMS_CMLCKSEL | __APP_EMS_REFCKBUFEN2 | 60753440260SJing Huang __APP_EMS_CHANNEL_SEL, (rb + ETH_MAC_SER_REG)); 608a36c61f9SKrishna Gudipati } else { 60953440260SJing Huang writel(__GLOBAL_FCOE_MODE, (rb + OP_MODE)); 61053440260SJing Huang writel(__APP_EMS_REFCKBUFEN1, (rb + ETH_MAC_SER_REG)); 611a36c61f9SKrishna Gudipati } 61253440260SJing Huang writel(BFI_IOC_UNINIT, (rb + BFA_IOC0_STATE_REG)); 61353440260SJing Huang writel(BFI_IOC_UNINIT, (rb + BFA_IOC1_STATE_REG)); 61453440260SJing Huang writel(0xffffffffU, (rb + HOSTFN0_INT_MSK)); 61553440260SJing Huang writel(0xffffffffU, (rb + HOSTFN1_INT_MSK)); 61653440260SJing Huang writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS)); 61753440260SJing Huang writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS)); 61853440260SJing Huang writel(0xffffffffU, (rb + HOSTFN0_INT_MSK)); 61953440260SJing Huang writel(0xffffffffU, (rb + HOSTFN1_INT_MSK)); 62011189208SKrishna Gudipati writel(pll_sclk | __APP_PLL_SCLK_LOGIC_SOFT_RESET, 62111189208SKrishna Gudipati rb + APP_PLL_SCLK_CTL_REG); 62211189208SKrishna Gudipati writel(pll_fclk | __APP_PLL_LCLK_LOGIC_SOFT_RESET, 62311189208SKrishna Gudipati rb + APP_PLL_LCLK_CTL_REG); 62411189208SKrishna Gudipati writel(pll_sclk | __APP_PLL_SCLK_LOGIC_SOFT_RESET | 62511189208SKrishna Gudipati __APP_PLL_SCLK_ENABLE, rb + APP_PLL_SCLK_CTL_REG); 62611189208SKrishna Gudipati writel(pll_fclk | __APP_PLL_LCLK_LOGIC_SOFT_RESET | 62711189208SKrishna Gudipati __APP_PLL_LCLK_ENABLE, rb + APP_PLL_LCLK_CTL_REG); 62853440260SJing Huang readl(rb + HOSTFN0_INT_MSK); 6296a18b167SJing Huang udelay(2000); 63053440260SJing Huang writel(0xffffffffU, (rb + HOSTFN0_INT_STATUS)); 63153440260SJing Huang writel(0xffffffffU, (rb + HOSTFN1_INT_STATUS)); 63211189208SKrishna Gudipati writel(pll_sclk | __APP_PLL_SCLK_ENABLE, rb + APP_PLL_SCLK_CTL_REG); 63311189208SKrishna Gudipati writel(pll_fclk | __APP_PLL_LCLK_ENABLE, rb + APP_PLL_LCLK_CTL_REG); 63411189208SKrishna Gudipati 635a36c61f9SKrishna Gudipati if (!fcmode) { 63653440260SJing Huang writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P0)); 63753440260SJing Huang writel(__PMM_1T_RESET_P, (rb + PMM_1T_RESET_REG_P1)); 638a36c61f9SKrishna Gudipati } 63953440260SJing Huang r32 = readl((rb + PSS_CTL_REG)); 640a36c61f9SKrishna Gudipati r32 &= ~__PSS_LMEM_RESET; 64153440260SJing Huang writel(r32, (rb + PSS_CTL_REG)); 6426a18b167SJing Huang udelay(1000); 643a36c61f9SKrishna Gudipati if (!fcmode) { 64453440260SJing Huang writel(0, (rb + PMM_1T_RESET_REG_P0)); 64553440260SJing Huang writel(0, (rb + PMM_1T_RESET_REG_P1)); 646a36c61f9SKrishna Gudipati } 647a36c61f9SKrishna Gudipati 64853440260SJing Huang writel(__EDRAM_BISTR_START, (rb + MBIST_CTL_REG)); 6496a18b167SJing Huang udelay(1000); 65053440260SJing Huang r32 = readl((rb + MBIST_STAT_REG)); 65153440260SJing Huang writel(0, (rb + MBIST_CTL_REG)); 652a36c61f9SKrishna Gudipati return BFA_STATUS_OK; 653a36c61f9SKrishna Gudipati } 65411189208SKrishna Gudipati 65511189208SKrishna Gudipati static void 65610a07379SKrishna Gudipati bfa_ioc_ct2_sclk_init(void __iomem *rb) 65711189208SKrishna Gudipati { 65811189208SKrishna Gudipati u32 r32; 65911189208SKrishna Gudipati 66011189208SKrishna Gudipati /* 66111189208SKrishna Gudipati * put s_clk PLL and PLL FSM in reset 66211189208SKrishna Gudipati */ 66311189208SKrishna Gudipati r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); 66411189208SKrishna Gudipati r32 &= ~(__APP_PLL_SCLK_ENABLE | __APP_PLL_SCLK_LRESETN); 66511189208SKrishna Gudipati r32 |= (__APP_PLL_SCLK_ENARST | __APP_PLL_SCLK_BYPASS | 66611189208SKrishna Gudipati __APP_PLL_SCLK_LOGIC_SOFT_RESET); 66711189208SKrishna Gudipati writel(r32, (rb + CT2_APP_PLL_SCLK_CTL_REG)); 66811189208SKrishna Gudipati 66911189208SKrishna Gudipati /* 67010a07379SKrishna Gudipati * Ignore mode and program for the max clock (which is FC16) 67110a07379SKrishna Gudipati * Firmware/NFC will do the PLL init appropiately 67211189208SKrishna Gudipati */ 67311189208SKrishna Gudipati r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); 67411189208SKrishna Gudipati r32 &= ~(__APP_PLL_SCLK_REFCLK_SEL | __APP_PLL_SCLK_CLK_DIV2); 67510a07379SKrishna Gudipati writel(r32, (rb + CT2_APP_PLL_SCLK_CTL_REG)); 67611189208SKrishna Gudipati 67711189208SKrishna Gudipati /* 678775c7742SKrishna Gudipati * while doing PLL init dont clock gate ethernet subsystem 67911189208SKrishna Gudipati */ 68011189208SKrishna Gudipati r32 = readl((rb + CT2_CHIP_MISC_PRG)); 68111189208SKrishna Gudipati writel(r32 | __ETH_CLK_ENABLE_PORT0, (rb + CT2_CHIP_MISC_PRG)); 68211189208SKrishna Gudipati 68311189208SKrishna Gudipati r32 = readl((rb + CT2_PCIE_MISC_REG)); 68411189208SKrishna Gudipati writel(r32 | __ETH_CLK_ENABLE_PORT1, (rb + CT2_PCIE_MISC_REG)); 68511189208SKrishna Gudipati 68611189208SKrishna Gudipati /* 68711189208SKrishna Gudipati * set sclk value 68811189208SKrishna Gudipati */ 68911189208SKrishna Gudipati r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); 69011189208SKrishna Gudipati r32 &= (__P_SCLK_PLL_LOCK | __APP_PLL_SCLK_REFCLK_SEL | 69111189208SKrishna Gudipati __APP_PLL_SCLK_CLK_DIV2); 69211189208SKrishna Gudipati writel(r32 | 0x1061731b, (rb + CT2_APP_PLL_SCLK_CTL_REG)); 69311189208SKrishna Gudipati 69411189208SKrishna Gudipati /* 69511189208SKrishna Gudipati * poll for s_clk lock or delay 1ms 69611189208SKrishna Gudipati */ 69711189208SKrishna Gudipati udelay(1000); 69811189208SKrishna Gudipati } 69911189208SKrishna Gudipati 70011189208SKrishna Gudipati static void 70110a07379SKrishna Gudipati bfa_ioc_ct2_lclk_init(void __iomem *rb) 70211189208SKrishna Gudipati { 70311189208SKrishna Gudipati u32 r32; 70411189208SKrishna Gudipati 70511189208SKrishna Gudipati /* 70611189208SKrishna Gudipati * put l_clk PLL and PLL FSM in reset 70711189208SKrishna Gudipati */ 70811189208SKrishna Gudipati r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); 70911189208SKrishna Gudipati r32 &= ~(__APP_PLL_LCLK_ENABLE | __APP_PLL_LCLK_LRESETN); 71011189208SKrishna Gudipati r32 |= (__APP_PLL_LCLK_ENARST | __APP_PLL_LCLK_BYPASS | 71111189208SKrishna Gudipati __APP_PLL_LCLK_LOGIC_SOFT_RESET); 71211189208SKrishna Gudipati writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG)); 71311189208SKrishna Gudipati 71411189208SKrishna Gudipati /* 71510a07379SKrishna Gudipati * set LPU speed (set for FC16 which will work for other modes) 71611189208SKrishna Gudipati */ 71711189208SKrishna Gudipati r32 = readl((rb + CT2_CHIP_MISC_PRG)); 71810a07379SKrishna Gudipati writel(r32, (rb + CT2_CHIP_MISC_PRG)); 71911189208SKrishna Gudipati 72011189208SKrishna Gudipati /* 72110a07379SKrishna Gudipati * set LPU half speed (set for FC16 which will work for other modes) 72211189208SKrishna Gudipati */ 72311189208SKrishna Gudipati r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); 72410a07379SKrishna Gudipati writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG)); 72511189208SKrishna Gudipati 72611189208SKrishna Gudipati /* 72710a07379SKrishna Gudipati * set lclk for mode (set for FC16) 72811189208SKrishna Gudipati */ 72911189208SKrishna Gudipati r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); 73011189208SKrishna Gudipati r32 &= (__P_LCLK_PLL_LOCK | __APP_LPUCLK_HALFSPEED); 73111189208SKrishna Gudipati r32 |= 0x20c1731b; 73211189208SKrishna Gudipati writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG)); 73311189208SKrishna Gudipati 73411189208SKrishna Gudipati /* 73511189208SKrishna Gudipati * poll for s_clk lock or delay 1ms 73611189208SKrishna Gudipati */ 73711189208SKrishna Gudipati udelay(1000); 73810a07379SKrishna Gudipati } 73910a07379SKrishna Gudipati 74010a07379SKrishna Gudipati static void 74110a07379SKrishna Gudipati bfa_ioc_ct2_mem_init(void __iomem *rb) 74210a07379SKrishna Gudipati { 74310a07379SKrishna Gudipati u32 r32; 74410a07379SKrishna Gudipati 74510a07379SKrishna Gudipati r32 = readl((rb + PSS_CTL_REG)); 74610a07379SKrishna Gudipati r32 &= ~__PSS_LMEM_RESET; 74710a07379SKrishna Gudipati writel(r32, (rb + PSS_CTL_REG)); 74810a07379SKrishna Gudipati udelay(1000); 74910a07379SKrishna Gudipati 75010a07379SKrishna Gudipati writel(__EDRAM_BISTR_START, (rb + CT2_MBIST_CTL_REG)); 75110a07379SKrishna Gudipati udelay(1000); 75210a07379SKrishna Gudipati writel(0, (rb + CT2_MBIST_CTL_REG)); 75310a07379SKrishna Gudipati } 75410a07379SKrishna Gudipati 75510a07379SKrishna Gudipati void 75610a07379SKrishna Gudipati bfa_ioc_ct2_mac_reset(void __iomem *rb) 75710a07379SKrishna Gudipati { 75810a07379SKrishna Gudipati /* put port0, port1 MAC & AHB in reset */ 75910a07379SKrishna Gudipati writel((__CSI_MAC_RESET | __CSI_MAC_AHB_RESET), 76010a07379SKrishna Gudipati rb + CT2_CSI_MAC_CONTROL_REG(0)); 76110a07379SKrishna Gudipati writel((__CSI_MAC_RESET | __CSI_MAC_AHB_RESET), 76210a07379SKrishna Gudipati rb + CT2_CSI_MAC_CONTROL_REG(1)); 76311189208SKrishna Gudipati } 76411189208SKrishna Gudipati 765227fab90SKrishna Gudipati static void 766227fab90SKrishna Gudipati bfa_ioc_ct2_enable_flash(void __iomem *rb) 767227fab90SKrishna Gudipati { 768227fab90SKrishna Gudipati u32 r32; 769227fab90SKrishna Gudipati 770227fab90SKrishna Gudipati r32 = readl((rb + PSS_GPIO_OUT_REG)); 771227fab90SKrishna Gudipati writel(r32 & ~1, (rb + PSS_GPIO_OUT_REG)); 772227fab90SKrishna Gudipati r32 = readl((rb + PSS_GPIO_OE_REG)); 773227fab90SKrishna Gudipati writel(r32 | 1, (rb + PSS_GPIO_OE_REG)); 774227fab90SKrishna Gudipati } 775227fab90SKrishna Gudipati 77610a07379SKrishna Gudipati #define CT2_NFC_MAX_DELAY 1000 777227fab90SKrishna Gudipati #define CT2_NFC_PAUSE_MAX_DELAY 4000 778227fab90SKrishna Gudipati #define CT2_NFC_VER_VALID 0x147 779227fab90SKrishna Gudipati #define CT2_NFC_STATE_RUNNING 0x20000001 780a6b963dbSKrishna Gudipati #define BFA_IOC_PLL_POLL 1000000 781a6b963dbSKrishna Gudipati 782a6b963dbSKrishna Gudipati static bfa_boolean_t 783a6b963dbSKrishna Gudipati bfa_ioc_ct2_nfc_halted(void __iomem *rb) 784a6b963dbSKrishna Gudipati { 785a6b963dbSKrishna Gudipati u32 r32; 786a6b963dbSKrishna Gudipati 787a6b963dbSKrishna Gudipati r32 = readl(rb + CT2_NFC_CSR_SET_REG); 788a6b963dbSKrishna Gudipati if (r32 & __NFC_CONTROLLER_HALTED) 789a6b963dbSKrishna Gudipati return BFA_TRUE; 790a6b963dbSKrishna Gudipati 791a6b963dbSKrishna Gudipati return BFA_FALSE; 792a6b963dbSKrishna Gudipati } 793a6b963dbSKrishna Gudipati 794a6b963dbSKrishna Gudipati static void 795227fab90SKrishna Gudipati bfa_ioc_ct2_nfc_halt(void __iomem *rb) 796227fab90SKrishna Gudipati { 797227fab90SKrishna Gudipati int i; 798227fab90SKrishna Gudipati 799227fab90SKrishna Gudipati writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_SET_REG); 800227fab90SKrishna Gudipati for (i = 0; i < CT2_NFC_MAX_DELAY; i++) { 801227fab90SKrishna Gudipati if (bfa_ioc_ct2_nfc_halted(rb)) 802227fab90SKrishna Gudipati break; 803227fab90SKrishna Gudipati udelay(1000); 804227fab90SKrishna Gudipati } 805227fab90SKrishna Gudipati WARN_ON(!bfa_ioc_ct2_nfc_halted(rb)); 806227fab90SKrishna Gudipati } 807227fab90SKrishna Gudipati 808227fab90SKrishna Gudipati static void 809a6b963dbSKrishna Gudipati bfa_ioc_ct2_nfc_resume(void __iomem *rb) 810a6b963dbSKrishna Gudipati { 811a6b963dbSKrishna Gudipati u32 r32; 812a6b963dbSKrishna Gudipati int i; 813a6b963dbSKrishna Gudipati 814a6b963dbSKrishna Gudipati writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_CLR_REG); 815a6b963dbSKrishna Gudipati for (i = 0; i < CT2_NFC_MAX_DELAY; i++) { 816a6b963dbSKrishna Gudipati r32 = readl(rb + CT2_NFC_CSR_SET_REG); 817a6b963dbSKrishna Gudipati if (!(r32 & __NFC_CONTROLLER_HALTED)) 818a6b963dbSKrishna Gudipati return; 819a6b963dbSKrishna Gudipati udelay(1000); 820a6b963dbSKrishna Gudipati } 821a6b963dbSKrishna Gudipati WARN_ON(1); 822a6b963dbSKrishna Gudipati } 823a6b963dbSKrishna Gudipati 824227fab90SKrishna Gudipati static void 825227fab90SKrishna Gudipati bfa_ioc_ct2_clk_reset(void __iomem *rb) 82611189208SKrishna Gudipati { 827227fab90SKrishna Gudipati u32 r32; 8288b070b4aSKrishna Gudipati 82910a07379SKrishna Gudipati bfa_ioc_ct2_sclk_init(rb); 83010a07379SKrishna Gudipati bfa_ioc_ct2_lclk_init(rb); 83110a07379SKrishna Gudipati 83210a07379SKrishna Gudipati /* 83310a07379SKrishna Gudipati * release soft reset on s_clk & l_clk 83410a07379SKrishna Gudipati */ 835227fab90SKrishna Gudipati r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); 83610a07379SKrishna Gudipati writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET, 83710a07379SKrishna Gudipati (rb + CT2_APP_PLL_SCLK_CTL_REG)); 83810a07379SKrishna Gudipati 839227fab90SKrishna Gudipati r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); 84010a07379SKrishna Gudipati writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET, 84110a07379SKrishna Gudipati (rb + CT2_APP_PLL_LCLK_CTL_REG)); 842227fab90SKrishna Gudipati 843a6b963dbSKrishna Gudipati } 84411189208SKrishna Gudipati 845227fab90SKrishna Gudipati static void 846227fab90SKrishna Gudipati bfa_ioc_ct2_nfc_clk_reset(void __iomem *rb) 847227fab90SKrishna Gudipati { 848227fab90SKrishna Gudipati u32 r32, i; 849227fab90SKrishna Gudipati 850227fab90SKrishna Gudipati r32 = readl((rb + PSS_CTL_REG)); 851227fab90SKrishna Gudipati r32 |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET); 852227fab90SKrishna Gudipati writel(r32, (rb + PSS_CTL_REG)); 853227fab90SKrishna Gudipati 854227fab90SKrishna Gudipati writel(__RESET_AND_START_SCLK_LCLK_PLLS, rb + CT2_CSI_FW_CTL_SET_REG); 855227fab90SKrishna Gudipati 856227fab90SKrishna Gudipati for (i = 0; i < BFA_IOC_PLL_POLL; i++) { 857227fab90SKrishna Gudipati r32 = readl(rb + CT2_NFC_FLASH_STS_REG); 858227fab90SKrishna Gudipati 859227fab90SKrishna Gudipati if ((r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS)) 860227fab90SKrishna Gudipati break; 861227fab90SKrishna Gudipati } 862227fab90SKrishna Gudipati WARN_ON(!(r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS)); 863227fab90SKrishna Gudipati 864227fab90SKrishna Gudipati for (i = 0; i < BFA_IOC_PLL_POLL; i++) { 865227fab90SKrishna Gudipati r32 = readl(rb + CT2_NFC_FLASH_STS_REG); 866227fab90SKrishna Gudipati 867227fab90SKrishna Gudipati if (!(r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS)) 868227fab90SKrishna Gudipati break; 869227fab90SKrishna Gudipati } 870227fab90SKrishna Gudipati WARN_ON((r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS)); 871227fab90SKrishna Gudipati 872227fab90SKrishna Gudipati r32 = readl(rb + CT2_CSI_FW_CTL_REG); 873227fab90SKrishna Gudipati WARN_ON((r32 & __RESET_AND_START_SCLK_LCLK_PLLS)); 874227fab90SKrishna Gudipati } 875227fab90SKrishna Gudipati 876227fab90SKrishna Gudipati static void 877227fab90SKrishna Gudipati bfa_ioc_ct2_wait_till_nfc_running(void __iomem *rb) 878227fab90SKrishna Gudipati { 879227fab90SKrishna Gudipati u32 r32; 880227fab90SKrishna Gudipati int i; 881227fab90SKrishna Gudipati 882227fab90SKrishna Gudipati if (bfa_ioc_ct2_nfc_halted(rb)) 883227fab90SKrishna Gudipati bfa_ioc_ct2_nfc_resume(rb); 884227fab90SKrishna Gudipati for (i = 0; i < CT2_NFC_PAUSE_MAX_DELAY; i++) { 885227fab90SKrishna Gudipati r32 = readl(rb + CT2_NFC_STS_REG); 886227fab90SKrishna Gudipati if (r32 == CT2_NFC_STATE_RUNNING) 887227fab90SKrishna Gudipati return; 888227fab90SKrishna Gudipati udelay(1000); 889227fab90SKrishna Gudipati } 890227fab90SKrishna Gudipati 891227fab90SKrishna Gudipati r32 = readl(rb + CT2_NFC_STS_REG); 892227fab90SKrishna Gudipati WARN_ON(!(r32 == CT2_NFC_STATE_RUNNING)); 893227fab90SKrishna Gudipati } 894227fab90SKrishna Gudipati 895227fab90SKrishna Gudipati bfa_status_t 896227fab90SKrishna Gudipati bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode) 897227fab90SKrishna Gudipati { 898227fab90SKrishna Gudipati u32 wgn, r32, nfc_ver; 899227fab90SKrishna Gudipati 900227fab90SKrishna Gudipati wgn = readl(rb + CT2_WGN_STATUS); 901227fab90SKrishna Gudipati 90210a07379SKrishna Gudipati if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) { 903227fab90SKrishna Gudipati /* 904227fab90SKrishna Gudipati * If flash is corrupted, enable flash explicitly 905227fab90SKrishna Gudipati */ 906227fab90SKrishna Gudipati bfa_ioc_ct2_clk_reset(rb); 907227fab90SKrishna Gudipati bfa_ioc_ct2_enable_flash(rb); 908227fab90SKrishna Gudipati 909227fab90SKrishna Gudipati bfa_ioc_ct2_mac_reset(rb); 910227fab90SKrishna Gudipati 911227fab90SKrishna Gudipati bfa_ioc_ct2_clk_reset(rb); 912227fab90SKrishna Gudipati bfa_ioc_ct2_enable_flash(rb); 913227fab90SKrishna Gudipati 914227fab90SKrishna Gudipati } else { 915227fab90SKrishna Gudipati nfc_ver = readl(rb + CT2_RSC_GPR15_REG); 916227fab90SKrishna Gudipati 917227fab90SKrishna Gudipati if ((nfc_ver >= CT2_NFC_VER_VALID) && 918227fab90SKrishna Gudipati (wgn == (__A2T_AHB_LOAD | __WGN_READY))) { 919227fab90SKrishna Gudipati 920227fab90SKrishna Gudipati bfa_ioc_ct2_wait_till_nfc_running(rb); 921227fab90SKrishna Gudipati 922227fab90SKrishna Gudipati bfa_ioc_ct2_nfc_clk_reset(rb); 923227fab90SKrishna Gudipati } else { 924227fab90SKrishna Gudipati bfa_ioc_ct2_nfc_halt(rb); 925227fab90SKrishna Gudipati 926227fab90SKrishna Gudipati bfa_ioc_ct2_clk_reset(rb); 927227fab90SKrishna Gudipati bfa_ioc_ct2_mac_reset(rb); 928227fab90SKrishna Gudipati bfa_ioc_ct2_clk_reset(rb); 929227fab90SKrishna Gudipati 930227fab90SKrishna Gudipati } 9318b070b4aSKrishna Gudipati } 932e1aaab89SVijaya Mohan Guvva /* 933e1aaab89SVijaya Mohan Guvva * The very first PCIe DMA Read done by LPU fails with a fatal error, 934e1aaab89SVijaya Mohan Guvva * when Address Translation Cache (ATC) has been enabled by system BIOS. 935e1aaab89SVijaya Mohan Guvva * 936e1aaab89SVijaya Mohan Guvva * Workaround: 937e1aaab89SVijaya Mohan Guvva * Disable Invalidated Tag Match Enable capability by setting the bit 26 938e1aaab89SVijaya Mohan Guvva * of CHIP_MISC_PRG to 0, by default it is set to 1. 939e1aaab89SVijaya Mohan Guvva */ 940e1aaab89SVijaya Mohan Guvva r32 = readl(rb + CT2_CHIP_MISC_PRG); 941e1aaab89SVijaya Mohan Guvva writel((r32 & 0xfbffffff), (rb + CT2_CHIP_MISC_PRG)); 942775c7742SKrishna Gudipati 943a6b963dbSKrishna Gudipati /* 944a6b963dbSKrishna Gudipati * Mask the interrupts and clear any 945227fab90SKrishna Gudipati * pending interrupts left by BIOS/EFI 946a6b963dbSKrishna Gudipati */ 947227fab90SKrishna Gudipati 948a6b963dbSKrishna Gudipati writel(1, (rb + CT2_LPU0_HOSTFN_MBOX0_MSK)); 949a6b963dbSKrishna Gudipati writel(1, (rb + CT2_LPU1_HOSTFN_MBOX0_MSK)); 950a6b963dbSKrishna Gudipati 951a6b963dbSKrishna Gudipati /* For first time initialization, no need to clear interrupts */ 952a6b963dbSKrishna Gudipati r32 = readl(rb + HOST_SEM5_REG); 953a6b963dbSKrishna Gudipati if (r32 & 0x1) { 954227fab90SKrishna Gudipati r32 = readl((rb + CT2_LPU0_HOSTFN_CMD_STAT)); 955a6b963dbSKrishna Gudipati if (r32 == 1) { 956227fab90SKrishna Gudipati writel(1, (rb + CT2_LPU0_HOSTFN_CMD_STAT)); 957a6b963dbSKrishna Gudipati readl((rb + CT2_LPU0_HOSTFN_CMD_STAT)); 958a6b963dbSKrishna Gudipati } 959227fab90SKrishna Gudipati r32 = readl((rb + CT2_LPU1_HOSTFN_CMD_STAT)); 960a6b963dbSKrishna Gudipati if (r32 == 1) { 961227fab90SKrishna Gudipati writel(1, (rb + CT2_LPU1_HOSTFN_CMD_STAT)); 962227fab90SKrishna Gudipati readl((rb + CT2_LPU1_HOSTFN_CMD_STAT)); 963a6b963dbSKrishna Gudipati } 964a6b963dbSKrishna Gudipati } 965a6b963dbSKrishna Gudipati 96610a07379SKrishna Gudipati bfa_ioc_ct2_mem_init(rb); 96710a07379SKrishna Gudipati 968227fab90SKrishna Gudipati writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC0_STATE_REG)); 969227fab90SKrishna Gudipati writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC1_STATE_REG)); 970a6b963dbSKrishna Gudipati 97111189208SKrishna Gudipati return BFA_STATUS_OK; 97211189208SKrishna Gudipati } 973c679b599SVijaya Mohan Guvva 974c679b599SVijaya Mohan Guvva static void 975c679b599SVijaya Mohan Guvva bfa_ioc_ct_set_cur_ioc_fwstate(struct bfa_ioc_s *ioc, 976c679b599SVijaya Mohan Guvva enum bfi_ioc_state fwstate) 977c679b599SVijaya Mohan Guvva { 978c679b599SVijaya Mohan Guvva writel(fwstate, ioc->ioc_regs.ioc_fwstate); 979c679b599SVijaya Mohan Guvva } 980c679b599SVijaya Mohan Guvva 981c679b599SVijaya Mohan Guvva static enum bfi_ioc_state 982c679b599SVijaya Mohan Guvva bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc) 983c679b599SVijaya Mohan Guvva { 984c679b599SVijaya Mohan Guvva return (enum bfi_ioc_state)readl(ioc->ioc_regs.ioc_fwstate); 985c679b599SVijaya Mohan Guvva } 986c679b599SVijaya Mohan Guvva 987c679b599SVijaya Mohan Guvva static void 988c679b599SVijaya Mohan Guvva bfa_ioc_ct_set_alt_ioc_fwstate(struct bfa_ioc_s *ioc, 989c679b599SVijaya Mohan Guvva enum bfi_ioc_state fwstate) 990c679b599SVijaya Mohan Guvva { 991c679b599SVijaya Mohan Guvva writel(fwstate, ioc->ioc_regs.alt_ioc_fwstate); 992c679b599SVijaya Mohan Guvva } 993c679b599SVijaya Mohan Guvva 994c679b599SVijaya Mohan Guvva static enum bfi_ioc_state 995c679b599SVijaya Mohan Guvva bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc) 996c679b599SVijaya Mohan Guvva { 997c679b599SVijaya Mohan Guvva return (enum bfi_ioc_state) readl(ioc->ioc_regs.alt_ioc_fwstate); 998c679b599SVijaya Mohan Guvva } 999