diff options
author | Krishna Gudipati <kgudipat@brocade.com> | 2011-06-24 23:23:38 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-06-29 17:59:59 -0400 |
commit | 10a07379247078448c076690657a076076bf89aa (patch) | |
tree | 9d1a18ccf937203a0e9f0bb24ed601391c80b1e8 /drivers/scsi/bfa/bfa_ioc_ct.c | |
parent | a714134a857d3984250ee52fda7850b61bf8a94e (diff) |
[SCSI] bfa: Brocade-1860 Fabric Adapter PLL init fixes.
- If flash controller is halted unconditionally, this results in
illegal write access to flash controller register domain. Since
flash controller registers are only accessible once s_clk is started
- added logic to check for WGN status and halt flash controller only
if it is already running.
- Added check to wait for flash controller halt to be completed before
proceeding with s_clk/l_clk initializations.
- Removed unnecessary reset logic for PMM 1T memory and moved memory
initialization after flash access enable.
- Disable Brocade-1860 asic MBOX interrupt before PLL initialization.
- Remove reset enable for S_CLK/L_CLK after both PLL initializations
are complete.
Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/bfa/bfa_ioc_ct.c')
-rw-r--r-- | drivers/scsi/bfa/bfa_ioc_ct.c | 180 |
1 files changed, 103 insertions, 77 deletions
diff --git a/drivers/scsi/bfa/bfa_ioc_ct.c b/drivers/scsi/bfa/bfa_ioc_ct.c index 216016c50d1..77f2b4470a6 100644 --- a/drivers/scsi/bfa/bfa_ioc_ct.c +++ b/drivers/scsi/bfa/bfa_ioc_ct.c | |||
@@ -564,10 +564,12 @@ bfa_ioc_set_ct2_hwif(struct bfa_ioc_s *ioc) | |||
564 | * Temporary workaround for MSI-X resource allocation for catapult-2. | 564 | * Temporary workaround for MSI-X resource allocation for catapult-2. |
565 | */ | 565 | */ |
566 | #define HOSTFN_MSIX_DEFAULT 16 | 566 | #define HOSTFN_MSIX_DEFAULT 16 |
567 | #define HOSTFN_MSIX_VT_INDEX_MBOX_ERR 0x30138 | ||
567 | #define HOSTFN_MSIX_VT_OFST_NUMVT 0x3013c | 568 | #define HOSTFN_MSIX_VT_OFST_NUMVT 0x3013c |
568 | #define __MSIX_VT_NUMVT__MK 0x003ff800 | 569 | #define __MSIX_VT_NUMVT__MK 0x003ff800 |
569 | #define __MSIX_VT_NUMVT__SH 11 | 570 | #define __MSIX_VT_NUMVT__SH 11 |
570 | #define __MSIX_VT_NUMVT_(_v) ((_v) << __MSIX_VT_NUMVT__SH) | 571 | #define __MSIX_VT_NUMVT_(_v) ((_v) << __MSIX_VT_NUMVT__SH) |
572 | #define __MSIX_VT_OFST_ 0x000007ff | ||
571 | void | 573 | void |
572 | bfa_ioc_ct2_poweron(struct bfa_ioc_s *ioc) | 574 | bfa_ioc_ct2_poweron(struct bfa_ioc_s *ioc) |
573 | { | 575 | { |
@@ -575,12 +577,17 @@ bfa_ioc_ct2_poweron(struct bfa_ioc_s *ioc) | |||
575 | u32 r32; | 577 | u32 r32; |
576 | 578 | ||
577 | r32 = readl(rb + HOSTFN_MSIX_VT_OFST_NUMVT); | 579 | r32 = readl(rb + HOSTFN_MSIX_VT_OFST_NUMVT); |
578 | if (r32 & __MSIX_VT_NUMVT__MK) | 580 | if (r32 & __MSIX_VT_NUMVT__MK) { |
581 | writel(r32 & __MSIX_VT_OFST_, | ||
582 | rb + HOSTFN_MSIX_VT_INDEX_MBOX_ERR); | ||
579 | return; | 583 | return; |
584 | } | ||
580 | 585 | ||
581 | writel(__MSIX_VT_NUMVT_(HOSTFN_MSIX_DEFAULT - 1) | | 586 | writel(__MSIX_VT_NUMVT_(HOSTFN_MSIX_DEFAULT - 1) | |
582 | HOSTFN_MSIX_DEFAULT * bfa_ioc_pcifn(ioc), | 587 | HOSTFN_MSIX_DEFAULT * bfa_ioc_pcifn(ioc), |
583 | rb + HOSTFN_MSIX_VT_OFST_NUMVT); | 588 | rb + HOSTFN_MSIX_VT_OFST_NUMVT); |
589 | writel(HOSTFN_MSIX_DEFAULT * bfa_ioc_pcifn(ioc), | ||
590 | rb + HOSTFN_MSIX_VT_INDEX_MBOX_ERR); | ||
584 | } | 591 | } |
585 | 592 | ||
586 | bfa_status_t | 593 | bfa_status_t |
@@ -649,17 +656,8 @@ bfa_ioc_ct_pll_init(void __iomem *rb, enum bfi_asic_mode mode) | |||
649 | return BFA_STATUS_OK; | 656 | return BFA_STATUS_OK; |
650 | } | 657 | } |
651 | 658 | ||
652 | static struct { u32 sclk, speed, half_speed; } ct2_pll[] = { | ||
653 | {0}, /* unused */ | ||
654 | {__APP_PLL_SCLK_CLK_DIV2, 0, 0}, /* FC 8G */ | ||
655 | {0, 0, 0}, /* FC 16G */ | ||
656 | {__APP_PLL_SCLK_REFCLK_SEL | __APP_PLL_SCLK_CLK_DIV2, 0, /* ETH */ | ||
657 | __APP_LPUCLK_HALFSPEED}, | ||
658 | {0, 0, 0}, /* COMBO */ | ||
659 | }; | ||
660 | |||
661 | static void | 659 | static void |
662 | bfa_ioc_ct2_sclk_init(void __iomem *rb, enum bfi_asic_mode mode) | 660 | bfa_ioc_ct2_sclk_init(void __iomem *rb) |
663 | { | 661 | { |
664 | u32 r32; | 662 | u32 r32; |
665 | 663 | ||
@@ -673,11 +671,12 @@ bfa_ioc_ct2_sclk_init(void __iomem *rb, enum bfi_asic_mode mode) | |||
673 | writel(r32, (rb + CT2_APP_PLL_SCLK_CTL_REG)); | 671 | writel(r32, (rb + CT2_APP_PLL_SCLK_CTL_REG)); |
674 | 672 | ||
675 | /* | 673 | /* |
676 | * select clock speed based on mode | 674 | * Ignore mode and program for the max clock (which is FC16) |
675 | * Firmware/NFC will do the PLL init appropiately | ||
677 | */ | 676 | */ |
678 | r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); | 677 | r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); |
679 | r32 &= ~(__APP_PLL_SCLK_REFCLK_SEL | __APP_PLL_SCLK_CLK_DIV2); | 678 | r32 &= ~(__APP_PLL_SCLK_REFCLK_SEL | __APP_PLL_SCLK_CLK_DIV2); |
680 | writel(r32 | ct2_pll[mode].sclk, (rb + CT2_APP_PLL_SCLK_CTL_REG)); | 679 | writel(r32, (rb + CT2_APP_PLL_SCLK_CTL_REG)); |
681 | 680 | ||
682 | /* | 681 | /* |
683 | * while doing PLL init dont clock gate ethernet subsystem | 682 | * while doing PLL init dont clock gate ethernet subsystem |
@@ -700,30 +699,10 @@ bfa_ioc_ct2_sclk_init(void __iomem *rb, enum bfi_asic_mode mode) | |||
700 | * poll for s_clk lock or delay 1ms | 699 | * poll for s_clk lock or delay 1ms |
701 | */ | 700 | */ |
702 | udelay(1000); | 701 | udelay(1000); |
703 | |||
704 | /* | ||
705 | * release soft reset on s_clk & l_clk | ||
706 | */ | ||
707 | r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); | ||
708 | writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET, | ||
709 | (rb + CT2_APP_PLL_SCLK_CTL_REG)); | ||
710 | |||
711 | /* | ||
712 | * clock gating for ethernet subsystem if not in ethernet mode | ||
713 | */ | ||
714 | if (mode != BFI_ASIC_MODE_ETH) { | ||
715 | r32 = readl((rb + CT2_CHIP_MISC_PRG)); | ||
716 | writel(r32 & ~__ETH_CLK_ENABLE_PORT0, | ||
717 | (rb + CT2_CHIP_MISC_PRG)); | ||
718 | |||
719 | r32 = readl((rb + CT2_PCIE_MISC_REG)); | ||
720 | writel(r32 & ~__ETH_CLK_ENABLE_PORT1, | ||
721 | (rb + CT2_PCIE_MISC_REG)); | ||
722 | } | ||
723 | } | 702 | } |
724 | 703 | ||
725 | static void | 704 | static void |
726 | bfa_ioc_ct2_lclk_init(void __iomem *rb, enum bfi_asic_mode mode) | 705 | bfa_ioc_ct2_lclk_init(void __iomem *rb) |
727 | { | 706 | { |
728 | u32 r32; | 707 | u32 r32; |
729 | 708 | ||
@@ -737,97 +716,144 @@ bfa_ioc_ct2_lclk_init(void __iomem *rb, enum bfi_asic_mode mode) | |||
737 | writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG)); | 716 | writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG)); |
738 | 717 | ||
739 | /* | 718 | /* |
740 | * set LPU speed | 719 | * set LPU speed (set for FC16 which will work for other modes) |
741 | */ | 720 | */ |
742 | r32 = readl((rb + CT2_CHIP_MISC_PRG)); | 721 | r32 = readl((rb + CT2_CHIP_MISC_PRG)); |
743 | writel(r32 | ct2_pll[mode].speed, | 722 | writel(r32, (rb + CT2_CHIP_MISC_PRG)); |
744 | (rb + CT2_CHIP_MISC_PRG)); | ||
745 | 723 | ||
746 | /* | 724 | /* |
747 | * set LPU half speed | 725 | * set LPU half speed (set for FC16 which will work for other modes) |
748 | */ | 726 | */ |
749 | r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); | 727 | r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); |
750 | writel(r32 | ct2_pll[mode].half_speed, | 728 | writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG)); |
751 | (rb + CT2_APP_PLL_LCLK_CTL_REG)); | ||
752 | 729 | ||
753 | /* | 730 | /* |
754 | * set lclk for mode | 731 | * set lclk for mode (set for FC16) |
755 | */ | 732 | */ |
756 | r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); | 733 | r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); |
757 | r32 &= (__P_LCLK_PLL_LOCK | __APP_LPUCLK_HALFSPEED); | 734 | r32 &= (__P_LCLK_PLL_LOCK | __APP_LPUCLK_HALFSPEED); |
758 | if (mode == BFI_ASIC_MODE_FC || mode == BFI_ASIC_MODE_FC16 || | 735 | r32 |= 0x20c1731b; |
759 | mode == BFI_ASIC_MODE_ETH) | ||
760 | r32 |= 0x20c1731b; | ||
761 | else | ||
762 | r32 |= 0x2081731b; | ||
763 | writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG)); | 736 | writel(r32, (rb + CT2_APP_PLL_LCLK_CTL_REG)); |
764 | 737 | ||
765 | /* | 738 | /* |
766 | * poll for s_clk lock or delay 1ms | 739 | * poll for s_clk lock or delay 1ms |
767 | */ | 740 | */ |
768 | udelay(1000); | 741 | udelay(1000); |
769 | |||
770 | /* | ||
771 | * release soft reset on s_clk & l_clk | ||
772 | */ | ||
773 | r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); | ||
774 | writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET, | ||
775 | (rb + CT2_APP_PLL_LCLK_CTL_REG)); | ||
776 | } | 742 | } |
777 | 743 | ||
778 | static void | 744 | static void |
779 | bfa_ioc_ct2_mem_init(void __iomem *rb, enum bfi_asic_mode mode) | 745 | bfa_ioc_ct2_mem_init(void __iomem *rb) |
780 | { | 746 | { |
781 | bfa_boolean_t fcmode; | ||
782 | u32 r32; | 747 | u32 r32; |
783 | 748 | ||
784 | fcmode = (mode == BFI_ASIC_MODE_FC) || (mode == BFI_ASIC_MODE_FC16); | ||
785 | if (!fcmode) { | ||
786 | writel(__PMM_1T_PNDB_P | __PMM_1T_RESET_P, | ||
787 | (rb + CT2_PMM_1T_CONTROL_REG_P0)); | ||
788 | writel(__PMM_1T_PNDB_P | __PMM_1T_RESET_P, | ||
789 | (rb + CT2_PMM_1T_CONTROL_REG_P1)); | ||
790 | } | ||
791 | |||
792 | r32 = readl((rb + PSS_CTL_REG)); | 749 | r32 = readl((rb + PSS_CTL_REG)); |
793 | r32 &= ~__PSS_LMEM_RESET; | 750 | r32 &= ~__PSS_LMEM_RESET; |
794 | writel(r32, (rb + PSS_CTL_REG)); | 751 | writel(r32, (rb + PSS_CTL_REG)); |
795 | udelay(1000); | 752 | udelay(1000); |
796 | 753 | ||
797 | if (!fcmode) { | ||
798 | writel(__PMM_1T_PNDB_P, (rb + CT2_PMM_1T_CONTROL_REG_P0)); | ||
799 | writel(__PMM_1T_PNDB_P, (rb + CT2_PMM_1T_CONTROL_REG_P1)); | ||
800 | } | ||
801 | |||
802 | writel(__EDRAM_BISTR_START, (rb + CT2_MBIST_CTL_REG)); | 754 | writel(__EDRAM_BISTR_START, (rb + CT2_MBIST_CTL_REG)); |
803 | udelay(1000); | 755 | udelay(1000); |
804 | writel(0, (rb + CT2_MBIST_CTL_REG)); | 756 | writel(0, (rb + CT2_MBIST_CTL_REG)); |
805 | } | 757 | } |
806 | 758 | ||
759 | void | ||
760 | bfa_ioc_ct2_mac_reset(void __iomem *rb) | ||
761 | { | ||
762 | u32 r32; | ||
763 | |||
764 | bfa_ioc_ct2_sclk_init(rb); | ||
765 | bfa_ioc_ct2_lclk_init(rb); | ||
766 | |||
767 | /* | ||
768 | * release soft reset on s_clk & l_clk | ||
769 | */ | ||
770 | r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); | ||
771 | writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET, | ||
772 | (rb + CT2_APP_PLL_SCLK_CTL_REG)); | ||
773 | |||
774 | /* | ||
775 | * release soft reset on s_clk & l_clk | ||
776 | */ | ||
777 | r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); | ||
778 | writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET, | ||
779 | (rb + CT2_APP_PLL_LCLK_CTL_REG)); | ||
780 | |||
781 | /* put port0, port1 MAC & AHB in reset */ | ||
782 | writel((__CSI_MAC_RESET | __CSI_MAC_AHB_RESET), | ||
783 | rb + CT2_CSI_MAC_CONTROL_REG(0)); | ||
784 | writel((__CSI_MAC_RESET | __CSI_MAC_AHB_RESET), | ||
785 | rb + CT2_CSI_MAC_CONTROL_REG(1)); | ||
786 | } | ||
787 | |||
788 | #define CT2_NFC_MAX_DELAY 1000 | ||
807 | bfa_status_t | 789 | bfa_status_t |
808 | bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode) | 790 | bfa_ioc_ct2_pll_init(void __iomem *rb, enum bfi_asic_mode mode) |
809 | { | 791 | { |
810 | u32 r32; | 792 | u32 wgn, r32; |
793 | int i; | ||
811 | 794 | ||
812 | /* | 795 | /* |
813 | * Initialize PLL if not already done by NFC | 796 | * Initialize PLL if not already done by NFC |
814 | */ | 797 | */ |
815 | r32 = readl((rb + CT2_WGN_STATUS)); | 798 | wgn = readl(rb + CT2_WGN_STATUS); |
799 | if (!(wgn & __GLBL_PF_VF_CFG_RDY)) { | ||
800 | writel(__HALT_NFC_CONTROLLER, rb + CT2_NFC_CSR_SET_REG); | ||
801 | for (i = 0; i < CT2_NFC_MAX_DELAY; i++) { | ||
802 | r32 = readl(rb + CT2_NFC_CSR_SET_REG); | ||
803 | if (r32 & __NFC_CONTROLLER_HALTED) | ||
804 | break; | ||
805 | udelay(1000); | ||
806 | } | ||
807 | } | ||
816 | 808 | ||
817 | writel(__HALT_NFC_CONTROLLER, (rb + CT2_NFC_CSR_SET_REG)); | 809 | /* |
810 | * Mask the interrupts and clear any | ||
811 | * pending interrupts. | ||
812 | */ | ||
813 | writel(1, (rb + CT2_LPU0_HOSTFN_MBOX0_MSK)); | ||
814 | writel(1, (rb + CT2_LPU1_HOSTFN_MBOX0_MSK)); | ||
818 | 815 | ||
819 | bfa_ioc_ct2_sclk_init(rb, mode); | 816 | r32 = readl((rb + CT2_LPU0_HOSTFN_CMD_STAT)); |
820 | bfa_ioc_ct2_lclk_init(rb, mode); | 817 | if (r32 == 1) { |
821 | bfa_ioc_ct2_mem_init(rb, mode); | 818 | writel(1, (rb + CT2_LPU0_HOSTFN_CMD_STAT)); |
819 | readl((rb + CT2_LPU0_HOSTFN_CMD_STAT)); | ||
820 | } | ||
821 | r32 = readl((rb + CT2_LPU1_HOSTFN_CMD_STAT)); | ||
822 | if (r32 == 1) { | ||
823 | writel(1, (rb + CT2_LPU1_HOSTFN_CMD_STAT)); | ||
824 | readl((rb + CT2_LPU1_HOSTFN_CMD_STAT)); | ||
825 | } | ||
826 | |||
827 | bfa_ioc_ct2_mac_reset(rb); | ||
828 | bfa_ioc_ct2_sclk_init(rb); | ||
829 | bfa_ioc_ct2_lclk_init(rb); | ||
830 | |||
831 | /* | ||
832 | * release soft reset on s_clk & l_clk | ||
833 | */ | ||
834 | r32 = readl((rb + CT2_APP_PLL_SCLK_CTL_REG)); | ||
835 | writel(r32 & ~__APP_PLL_SCLK_LOGIC_SOFT_RESET, | ||
836 | (rb + CT2_APP_PLL_SCLK_CTL_REG)); | ||
837 | |||
838 | /* | ||
839 | * release soft reset on s_clk & l_clk | ||
840 | */ | ||
841 | r32 = readl((rb + CT2_APP_PLL_LCLK_CTL_REG)); | ||
842 | writel(r32 & ~__APP_PLL_LCLK_LOGIC_SOFT_RESET, | ||
843 | (rb + CT2_APP_PLL_LCLK_CTL_REG)); | ||
822 | 844 | ||
823 | /* | 845 | /* |
824 | * Announce flash device presence, if flash was corrupted. | 846 | * Announce flash device presence, if flash was corrupted. |
825 | */ | 847 | */ |
826 | if (r32 == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) { | 848 | if (wgn == (__WGN_READY | __GLBL_PF_VF_CFG_RDY)) { |
827 | writel(0, (rb + PSS_GPIO_OUT_REG)); | 849 | r32 = readl((rb + PSS_GPIO_OUT_REG)); |
828 | writel(1, (rb + PSS_GPIO_OE_REG)); | 850 | writel(r32 & ~1, (rb + PSS_GPIO_OUT_REG)); |
851 | r32 = readl((rb + PSS_GPIO_OE_REG)); | ||
852 | writel(r32 | 1, (rb + PSS_GPIO_OE_REG)); | ||
829 | } | 853 | } |
830 | 854 | ||
855 | bfa_ioc_ct2_mem_init(rb); | ||
856 | |||
831 | writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC0_STATE_REG)); | 857 | writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC0_STATE_REG)); |
832 | writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC1_STATE_REG)); | 858 | writel(BFI_IOC_UNINIT, (rb + CT2_BFA_IOC1_STATE_REG)); |
833 | return BFA_STATUS_OK; | 859 | return BFA_STATUS_OK; |