aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/bfa/bfa_ioc_ct.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/bfa/bfa_ioc_ct.c')
-rw-r--r--drivers/scsi/bfa/bfa_ioc_ct.c282
1 files changed, 179 insertions, 103 deletions
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c
index 2eb0c6a2938..bd53150e4ee 100644
--- a/drivers/scsi/bfa/bfa_ioc_ct.c
+++ b/drivers/scsi/bfa/bfa_ioc_ct.c
@@ -43,6 +43,12 @@ static void bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc);
static void bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc);
static bfa_boolean_t bfa_ioc_ct_sync_complete(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_set_cur_ioc_fwstate(
+ struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate);
+static enum bfi_ioc_state bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc);
+static void bfa_ioc_ct_set_alt_ioc_fwstate(
+ struct bfa_ioc_s *ioc, enum bfi_ioc_state fwstate);
+static enum bfi_ioc_state bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc);
static struct bfa_ioc_hwif_s hwif_ct;
static struct bfa_ioc_hwif_s hwif_ct2;
@@ -57,13 +63,6 @@ bfa_ioc_ct_firmware_lock(struct bfa_ioc_s *ioc)
u32 usecnt;
struct bfi_ioc_image_hdr_s fwhdr;
- /*
- * If bios boot (flash based) -- do not increment usage count
- */
- if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) <
- BFA_IOC_FWIMG_MINSZ)
- return BFA_TRUE;
-
bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
usecnt = readl(ioc->ioc_regs.ioc_usage_reg);
@@ -115,13 +114,6 @@ bfa_ioc_ct_firmware_unlock(struct bfa_ioc_s *ioc)
u32 usecnt;
/*
- * If bios boot (flash based) -- do not decrement usage count
- */
- if (bfa_cb_image_get_size(bfa_ioc_asic_gen(ioc)) <
- BFA_IOC_FWIMG_MINSZ)
- return;
-
- /*
* decrement usage count
*/
bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
@@ -400,13 +392,12 @@ static void
bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc)
{
- if (bfa_ioc_is_cna(ioc)) {
- bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
- writel(0, ioc->ioc_regs.ioc_usage_reg);
- readl(ioc->ioc_regs.ioc_usage_sem_reg);
- writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
- }
+ bfa_ioc_sem_get(ioc->ioc_regs.ioc_usage_sem_reg);
+ writel(0, ioc->ioc_regs.ioc_usage_reg);
+ readl(ioc->ioc_regs.ioc_usage_sem_reg);
+ writel(1, ioc->ioc_regs.ioc_usage_sem_reg);
+ writel(0, ioc->ioc_regs.ioc_fail_sync);
/*
* Read the hw sem reg to make sure that it is locked
* before we clear it. If it is not locked, writing 1
@@ -527,6 +518,10 @@ bfa_ioc_set_ctx_hwif(struct bfa_ioc_s *ioc, struct bfa_ioc_hwif_s *hwif)
hwif->ioc_sync_leave = bfa_ioc_ct_sync_leave;
hwif->ioc_sync_ack = bfa_ioc_ct_sync_ack;
hwif->ioc_sync_complete = bfa_ioc_ct_sync_complete;
+ hwif->ioc_set_fwstate = bfa_ioc_ct_set_cur_ioc_fwstate;
+ hwif->ioc_get_fwstate = bfa_ioc_ct_get_cur_ioc_fwstate;
+ hwif->ioc_set_alt_fwstate = bfa_ioc_ct_set_alt_ioc_fwstate;
+ hwif->ioc_get_alt_fwstate = bfa_ioc_ct_get_alt_ioc_fwstate;
}
/**
@@ -759,25 +754,6 @@ bfa_ioc_ct2_mem_init(void __iomem *rb)
void
bfa_ioc_ct2_mac_reset(void __iomem *rb)
{
- u32 r32;
-
- bfa_ioc_ct2_sclk_init(rb);
- bfa_ioc_ct2_lclk_init(rb);
-
- /*
- * release soft reset on s_clk & l_clk
- */
- r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG));
- writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET,
- (rb + CT2_APP_PLL_SCLK_CTL_REG));
-
- /*
- * release soft reset on s_clk & l_clk
- */
- r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG));
- writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
- (rb + CT2_APP_PLL_LCLK_CTL_REG));
-
/* put port0, port1 MAC & AHB in reset */
writel((__CSI_MAC_RESET | __CSI_MAC_AHB_RESET),
rb + CT2_CSI_MAC_CONTROL_REG(0));
@@ -785,8 +761,21 @@ bfa_ioc_ct2_mac_reset(void __iomem *rb)
rb + CT2_CSI_MAC_CONTROL_REG(1));
}
+static void
+bfa_ioc_ct2_enable_flash(void __iomem *rb)
+{
+ u32 r32;
+
+ r32 = readl((rb + PSS_GPIO_OUT_REG));
+ writel(r32 & ~1, (rb + PSS_GPIO_OUT_REG));
+ r32 = readl((rb + PSS_GPIO_OE_REG));
+ writel(r32 | 1, (rb + PSS_GPIO_OE_REG));
+}
+
#define CT2_NFC_MAX_DELAY 1000
-#define CT2_NFC_VER_VALID 0x143
+#define CT2_NFC_PAUSE_MAX_DELAY 4000
+#define CT2_NFC_VER_VALID 0x147
+#define CT2_NFC_STATE_RUNNING 0x20000001
#define BFA_IOC_PLL_POLL 1000000
static bfa_boolean_t
@@ -802,6 +791,20 @@ bfa_ioc_ct2_nfc_halted(void __iomem *rb)
}
static void
+bfa_ioc_ct2_nfc_halt(void __iomem *rb)
+{
+ int i;
+
+ writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_SET_REG);
+ for (i = 0; i < CT2_NFC_MAX_DELAY; i++) {
+ if (bfa_ioc_ct2_nfc_halted(rb))
+ break;
+ udelay(1000);
+ }
+ WARN_ON(!bfa_ioc_ct2_nfc_halted(rb));
+}
+
+static void
bfa_ioc_ct2_nfc_resume(void __iomem *rb)
{
u32 r32;
@@ -817,105 +820,178 @@ bfa_ioc_ct2_nfc_resume(void __iomem *rb)
WARN_ON(1);
}
-bfa_status_t
-bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode)
+static void
+bfa_ioc_ct2_clk_reset(void __iomem *rb)
{
- u32 wgn, r32, nfc_ver, i;
+ u32 r32;
- wgn = readl(rb + CT2_WGN_STATUS);
- nfc_ver = readl(rb + CT2_RSC_GPR15_REG);
+ bfa_ioc_ct2_sclk_init(rb);
+ bfa_ioc_ct2_lclk_init(rb);
- if ((wgn == (__A2T_AHB_LOAD | __WGN_READY)) &&
- (nfc_ver >= CT2_NFC_VER_VALID)) {
- if (bfa_ioc_ct2_nfc_halted(rb))
- bfa_ioc_ct2_nfc_resume(rb);
+ /*
+ * release soft reset on s_clk & l_clk
+ */
+ r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG));
+ writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET,
+ (rb + CT2_APP_PLL_SCLK_CTL_REG));
- writel(__RESET_AND_START_SCLK_LCLK_PLLS,
- rb + CT2_CSI_FW_CTL_SET_REG);
+ r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG));
+ writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
+ (rb + CT2_APP_PLL_LCLK_CTL_REG));
- for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
- r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
- if (r32 & __RESET_AND_START_SCLK_LCLK_PLLS)
- break;
- }
+}
- WARN_ON(!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS));
+static void
+bfa_ioc_ct2_nfc_clk_reset(void __iomem *rb)
+{
+ u32 r32, i;
- for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
- r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
- if (!(r32 & __RESET_AND_START_SCLK_LCLK_PLLS))
- break;
- }
+ r32 = readl((rb + PSS_CTL_REG));
+ r32 |= (__PSS_LPU0_RESET | __PSS_LPU1_RESET);
+ writel(r32, (rb + PSS_CTL_REG));
+
+ writel(__RESET_AND_START_SCLK_LCLK_PLLS, rb + CT2_CSI_FW_CTL_SET_REG);
+
+ for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
+ r32 = readl(rb + CT2_NFC_FLASH_STS_REG);
+
+ if ((r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS))
+ break;
+ }
+ WARN_ON(!(r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS));
+
+ for (i = 0; i < BFA_IOC_PLL_POLL; i++) {
+ r32 = readl(rb + CT2_NFC_FLASH_STS_REG);
+
+ if (!(r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS))
+ break;
+ }
+ WARN_ON((r32 & __FLASH_PLL_INIT_AND_RESET_IN_PROGRESS));
+
+ r32 = readl(rb + CT2_CSI_FW_CTL_REG);
+ WARN_ON((r32 & __RESET_AND_START_SCLK_LCLK_PLLS));
+}
+
+static void
+bfa_ioc_ct2_wait_till_nfc_running(void __iomem *rb)
+{
+ u32 r32;
+ int i;
- WARN_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS);
+ if (bfa_ioc_ct2_nfc_halted(rb))
+ bfa_ioc_ct2_nfc_resume(rb);
+ for (i = 0; i < CT2_NFC_PAUSE_MAX_DELAY; i++) {
+ r32 = readl(rb + CT2_NFC_STS_REG);
+ if (r32 == CT2_NFC_STATE_RUNNING)
+ return;
udelay(1000);
+ }
- r32 = readl(rb + CT2_CSI_FW_CTL_REG);
- WARN_ON(r32 & __RESET_AND_START_SCLK_LCLK_PLLS);
- } else {
- writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_SET_REG);
- for (i = 0; i < CT2_NFC_MAX_DELAY; i++) {
- r32 = readl(rb + CT2_NFC_CSR_SET_REG);
- if (r32 & __NFC_CONTROLLER_HALTED)
- break;
- udelay(1000);
- }
+ r32 = readl(rb + CT2_NFC_STS_REG);
+ WARN_ON(!(r32 == CT2_NFC_STATE_RUNNING));
+}
- bfa_ioc_ct2_mac_reset(rb);
- bfa_ioc_ct2_sclk_init(rb);
- bfa_ioc_ct2_lclk_init(rb);
+bfa_status_t
+bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode)
+{
+ u32 wgn, r32, nfc_ver;
- /*
- * release soft reset on s_clk & l_clk
- */
- r32 = readl(rb + CT2_APP_PLL_SCLK_CTL_REG);
- writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET,
- (rb + CT2_APP_PLL_SCLK_CTL_REG));
+ wgn = readl(rb + CT2_WGN_STATUS);
+ if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) {
/*
- * release soft reset on s_clk & l_clk
+ * If flash is corrupted, enable flash explicitly
*/
- r32 = readl(rb + CT2_APP_PLL_LCLK_CTL_REG);
- writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET,
- (rb + CT2_APP_PLL_LCLK_CTL_REG));
- }
+ bfa_ioc_ct2_clk_reset(rb);
+ bfa_ioc_ct2_enable_flash(rb);
- /*
- * Announce flash device presence, if flash was corrupted.
- */
- if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) {
- r32 = readl(rb + PSS_GPIO_OUT_REG);
- writel(r32 & ~1, (rb + PSS_GPIO_OUT_REG));
- r32 = readl(rb + PSS_GPIO_OE_REG);
- writel(r32 | 1, (rb + PSS_GPIO_OE_REG));
+ bfa_ioc_ct2_mac_reset(rb);
+
+ bfa_ioc_ct2_clk_reset(rb);
+ bfa_ioc_ct2_enable_flash(rb);
+
+ } else {
+ nfc_ver = readl(rb + CT2_RSC_GPR15_REG);
+
+ if ((nfc_ver >= CT2_NFC_VER_VALID) &&
+ (wgn == (__A2T_AHB_LOAD | __WGN_READY))) {
+
+ bfa_ioc_ct2_wait_till_nfc_running(rb);
+
+ bfa_ioc_ct2_nfc_clk_reset(rb);
+ } else {
+ bfa_ioc_ct2_nfc_halt(rb);
+
+ bfa_ioc_ct2_clk_reset(rb);
+ bfa_ioc_ct2_mac_reset(rb);
+ bfa_ioc_ct2_clk_reset(rb);
+
+ }
}
+ /*
+ * The very first PCIe DMA Read done by LPU fails with a fatal error,
+ * when Address Translation Cache (ATC) has been enabled by system BIOS.
+ *
+ * Workaround:
+ * Disable Invalidated Tag Match Enable capability by setting the bit 26
+ * of CHIP_MISC_PRG to 0, by default it is set to 1.
+ */
+ r32 = readl(rb + CT2_CHIP_MISC_PRG);
+ writel((r32 & 0xfbffffff), (rb + CT2_CHIP_MISC_PRG));
/*
* Mask the interrupts and clear any
- * pending interrupts.
+ * pending interrupts left by BIOS/EFI
*/
+
writel(1, (rb + CT2_LPU0_HOSTFN_MBOX0_MSK));
writel(1, (rb + CT2_LPU1_HOSTFN_MBOX0_MSK));
/* For first time initialization, no need to clear interrupts */
r32 = readl(rb + HOST_SEM5_REG);
if (r32 & 0x1) {
- r32 = readl(rb + CT2_LPU0_HOSTFN_CMD_STAT);
+ r32 = readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
if (r32 == 1) {
- writel(1, rb + CT2_LPU0_HOSTFN_CMD_STAT);
+ writel(1, (rb + CT2_LPU0_HOSTFN_CMD_STAT));
readl((rb + CT2_LPU0_HOSTFN_CMD_STAT));
}
- r32 = readl(rb + CT2_LPU1_HOSTFN_CMD_STAT);
+ r32 = readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
if (r32 == 1) {
- writel(1, rb + CT2_LPU1_HOSTFN_CMD_STAT);
- readl(rb + CT2_LPU1_HOSTFN_CMD_STAT);
+ writel(1, (rb + CT2_LPU1_HOSTFN_CMD_STAT));
+ readl((rb + CT2_LPU1_HOSTFN_CMD_STAT));
}
}
bfa_ioc_ct2_mem_init(rb);
- writel(BFI_IOC_UNINIT, rb + CT2_BFA_IOC0_STATE_REG);
- writel(BFI_IOC_UNINIT, rb + CT2_BFA_IOC1_STATE_REG);
+ writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC0_STATE_REG));
+ writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC1_STATE_REG));
return BFA_STATUS_OK;
}
+
+static void
+bfa_ioc_ct_set_cur_ioc_fwstate(struct bfa_ioc_s *ioc,
+ enum bfi_ioc_state fwstate)
+{
+ writel(fwstate, ioc->ioc_regs.ioc_fwstate);
+}
+
+static enum bfi_ioc_state
+bfa_ioc_ct_get_cur_ioc_fwstate(struct bfa_ioc_s *ioc)
+{
+ return (enum bfi_ioc_state)readl(ioc->ioc_regs.ioc_fwstate);
+}
+
+static void
+bfa_ioc_ct_set_alt_ioc_fwstate(struct bfa_ioc_s *ioc,
+ enum bfi_ioc_state fwstate)
+{
+ writel(fwstate, ioc->ioc_regs.alt_ioc_fwstate);
+}
+
+static enum bfi_ioc_state
+bfa_ioc_ct_get_alt_ioc_fwstate(struct bfa_ioc_s *ioc)
+{
+ return (enum bfi_ioc_state) readl(ioc->ioc_regs.alt_ioc_fwstate);
+}