iwlwifi: mvm: support ucode load for family_8000 B0 only
authorEran Harary <eran.harary@intel.com>
Sun, 19 Oct 2014 10:20:14 +0000 (12:20 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Mon, 1 Dec 2014 11:00:16 +0000 (13:00 +0200)
The ucode load flow changed for B0 hardware step.
Change the code accordingly.

Signed-off-by: Eran Harary <eran.harary@intel.com>
Signed-off-by: Liad Kaufman <liad.kaufman@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/iwlwifi/iwl-prph.h
drivers/net/wireless/iwlwifi/pcie/trans.c

index 1dae702..2df51ea 100644 (file)
@@ -322,6 +322,7 @@ enum secure_boot_config_reg {
        LMPM_SECURE_BOOT_CONFIG_INSPECTOR_NOT_REQ       = 0x00000002,
 };
 
+#define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0   (0xA01E30)
 #define LMPM_SECURE_BOOT_CPU1_STATUS_ADDR      (0x1E30)
 #define LMPM_SECURE_BOOT_CPU2_STATUS_ADDR      (0x1E34)
 enum secure_boot_status_reg {
@@ -333,6 +334,7 @@ enum secure_boot_status_reg {
        LMPM_SECURE_BOOT_STATUS_SUCCESS                 = 0x00000003,
 };
 
+#define FH_UCODE_LOAD_STATUS           (0x1AF0)
 #define CSR_UCODE_LOAD_STATUS_ADDR     (0x1E70)
 enum secure_load_status_reg {
        LMPM_CPU_UCODE_LOADING_STARTED                  = 0x00000001,
@@ -349,10 +351,10 @@ enum secure_load_status_reg {
 
 #define LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE   (0x400000)
 #define LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE   (0x402000)
-#define LMPM_SECURE_CPU1_HDR_MEM_SPACE         (0x404000)
-#define LMPM_SECURE_CPU2_HDR_MEM_SPACE         (0x405000)
+#define LMPM_SECURE_CPU1_HDR_MEM_SPACE         (0x420000)
+#define LMPM_SECURE_CPU2_HDR_MEM_SPACE         (0x420400)
 
-#define LMPM_SECURE_TIME_OUT   (50000) /* 5 msec */
+#define LMPM_SECURE_TIME_OUT   (100) /* 10 micro */
 
 /* Rx FIFO */
 #define RXF_SIZE_ADDR                  (0xa00c88)
index 7d7f05e..666925c 100644 (file)
@@ -665,14 +665,14 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
        return ret;
 }
 
-static int iwl_pcie_load_cpu_secured_sections(struct iwl_trans *trans,
-                                             const struct fw_img *image,
-                                             int cpu,
-                                             int *first_ucode_section)
+static int iwl_pcie_load_cpu_sections_8000b(struct iwl_trans *trans,
+                                           const struct fw_img *image,
+                                           int cpu,
+                                           int *first_ucode_section)
 {
        int shift_param;
-       int i, ret = 0;
-       u32 last_read_idx = 0;
+       int i, ret = 0, sec_num = 0x1;
+       u32 val, last_read_idx = 0;
 
        if (cpu == 1) {
                shift_param = 0;
@@ -693,21 +693,16 @@ static int iwl_pcie_load_cpu_secured_sections(struct iwl_trans *trans,
                        break;
                }
 
-               if (i == (*first_ucode_section) + 1)
-                       /* set CPU to started */
-                       iwl_set_bits_prph(trans,
-                                         CSR_UCODE_LOAD_STATUS_ADDR,
-                                         LMPM_CPU_HDRS_LOADING_COMPLETED
-                                         << shift_param);
-
                ret = iwl_pcie_load_section(trans, i, &image->sec[i]);
                if (ret)
                        return ret;
+
+               /* Notify the ucode of the loaded section number and status */
+               val = iwl_read_direct32(trans, FH_UCODE_LOAD_STATUS);
+               val = val | (sec_num << shift_param);
+               iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, val);
+               sec_num = (sec_num << 1) | 0x1;
        }
-       /* image loading complete */
-       iwl_set_bits_prph(trans,
-                         CSR_UCODE_LOAD_STATUS_ADDR,
-                         LMPM_CPU_UCODE_LOADING_COMPLETED << shift_param);
 
        *first_ucode_section = last_read_idx;
 
@@ -767,39 +762,13 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
        int ret = 0;
        int first_ucode_section;
 
-       IWL_DEBUG_FW(trans,
-                    "working with %s CPU\n",
+       IWL_DEBUG_FW(trans, "working with %s CPU\n",
                     image->is_dual_cpus ? "Dual" : "Single");
 
-       /* configure the ucode to be ready to get the secured image */
-       if (iwl_has_secure_boot(trans->hw_rev, trans->cfg->device_family)) {
-               /* set secure boot inspector addresses */
-               iwl_write_prph(trans,
-                              LMPM_SECURE_INSPECTOR_CODE_ADDR,
-                              LMPM_SECURE_INSPECTOR_CODE_MEM_SPACE);
-
-               iwl_write_prph(trans,
-                              LMPM_SECURE_INSPECTOR_DATA_ADDR,
-                              LMPM_SECURE_INSPECTOR_DATA_MEM_SPACE);
-
-               /* set CPU1 header address */
-               iwl_write_prph(trans,
-                              LMPM_SECURE_UCODE_LOAD_CPU1_HDR_ADDR,
-                              LMPM_SECURE_CPU1_HDR_MEM_SPACE);
-
-               /* load to FW the binary Secured sections of CPU1 */
-               ret = iwl_pcie_load_cpu_secured_sections(trans, image, 1,
-                                                        &first_ucode_section);
-               if (ret)
-                       return ret;
-
-       } else {
-               /* load to FW the binary Non secured sections of CPU1 */
-               ret = iwl_pcie_load_cpu_sections(trans, image, 1,
-                                                &first_ucode_section);
-               if (ret)
-                       return ret;
-       }
+       /* load to FW the binary non secured sections of CPU1 */
+       ret = iwl_pcie_load_cpu_sections(trans, image, 1, &first_ucode_section);
+       if (ret)
+               return ret;
 
        if (image->is_dual_cpus) {
                /* set CPU2 header address */
@@ -808,14 +777,8 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
                               LMPM_SECURE_CPU2_HDR_MEM_SPACE);
 
                /* load to FW the binary sections of CPU2 */
-               if (iwl_has_secure_boot(trans->hw_rev,
-                                       trans->cfg->device_family))
-                       ret = iwl_pcie_load_cpu_secured_sections(
-                                                       trans, image, 2,
-                                                       &first_ucode_section);
-               else
-                       ret = iwl_pcie_load_cpu_sections(trans, image, 2,
-                                                        &first_ucode_section);
+               ret = iwl_pcie_load_cpu_sections(trans, image, 2,
+                                                &first_ucode_section);
                if (ret)
                        return ret;
        }
@@ -840,18 +803,50 @@ static int iwl_pcie_load_given_ucode(struct iwl_trans *trans,
        else
                iwl_write32(trans, CSR_RESET, 0);
 
-       if (iwl_has_secure_boot(trans->hw_rev, trans->cfg->device_family)) {
-               /* wait for image verification to complete  */
-               ret = iwl_poll_prph_bit(trans,
-                                       LMPM_SECURE_BOOT_CPU1_STATUS_ADDR,
-                                       LMPM_SECURE_BOOT_STATUS_SUCCESS,
-                                       LMPM_SECURE_BOOT_STATUS_SUCCESS,
-                                       LMPM_SECURE_TIME_OUT);
+       return 0;
+}
 
-               if (ret < 0) {
-                       IWL_ERR(trans, "Time out on secure boot process\n");
-                       return ret;
-               }
+static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
+                                          const struct fw_img *image)
+{
+       int ret = 0;
+       int first_ucode_section;
+       u32 reg;
+
+       IWL_DEBUG_FW(trans, "working with %s CPU\n",
+                    image->is_dual_cpus ? "Dual" : "Single");
+
+       /* configure the ucode to be ready to get the secured image */
+       /* release CPU reset */
+       iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT);
+
+       /* load to FW the binary Secured sections of CPU1 */
+       ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 1,
+                                              &first_ucode_section);
+       if (ret)
+               return ret;
+
+       /* load to FW the binary sections of CPU2 */
+       ret = iwl_pcie_load_cpu_sections_8000b(trans, image, 2,
+                                              &first_ucode_section);
+       if (ret)
+               return ret;
+
+       /* Notify FW loading is done */
+       iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF);
+
+       /* wait for image verification to complete  */
+       ret = iwl_poll_prph_bit(trans, LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0,
+                               LMPM_SECURE_BOOT_STATUS_SUCCESS,
+                               LMPM_SECURE_BOOT_STATUS_SUCCESS,
+                               LMPM_SECURE_TIME_OUT);
+       if (ret < 0) {
+               reg = iwl_read_prph(trans,
+                                   LMPM_SECURE_BOOT_CPU1_STATUS_ADDR_B0);
+
+               IWL_ERR(trans, "Timeout on secure boot process, reg = %x\n",
+                       reg);
+               return ret;
        }
 
        return 0;
@@ -903,7 +898,11 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans,
        iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
 
        /* Load the given image to the HW */
-       return iwl_pcie_load_given_ucode(trans, fw);
+       if ((trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) &&
+           (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_B_STEP))
+               return iwl_pcie_load_given_ucode_8000b(trans, fw);
+       else
+               return iwl_pcie_load_given_ucode(trans, fw);
 }
 
 static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans, u32 scd_addr)