Last active
January 8, 2017 18:54
-
-
Save halmartin/a4b84699c1d7715c8288544a742758fa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/drivers/net/wireless/st/cw1200/cw1200_sdio.c b/drivers/net/wireless/st/cw1200/cw1200_sdio.c | |
index d3acc85932a5..0c3db3c8f75d 100644 | |
--- a/drivers/net/wireless/st/cw1200/cw1200_sdio.c | |
+++ b/drivers/net/wireless/st/cw1200/cw1200_sdio.c | |
@@ -55,7 +55,7 @@ struct hwbus_priv { | |
#endif | |
#ifndef SDIO_DEVICE_ID_STE_CW1200 | |
-#define SDIO_DEVICE_ID_STE_CW1200 0x2280 | |
+#define SDIO_DEVICE_ID_STE_CW1200 0x2281 | |
#endif | |
static const struct sdio_device_id cw1200_sdio_ids[] = { | |
diff --git a/drivers/net/wireless/st/cw1200/fwio.c b/drivers/net/wireless/st/cw1200/fwio.c | |
index 30e7646d04af..54237b03f89e 100644 | |
--- a/drivers/net/wireless/st/cw1200/fwio.c | |
+++ b/drivers/net/wireless/st/cw1200/fwio.c | |
@@ -39,10 +39,14 @@ static int cw1200_get_hw_type(u32 config_reg_val, int *major_revision) | |
case 0x02: /* CW1x00 */ | |
case 0x04: /* CW1x60 */ | |
*major_revision = silicon_type; | |
- if (silicon_vers) | |
+ pr_err("silicon_vers: %d\n", silicon_vers); | |
+ if (silicon_vers) { | |
hw_type = HIF_8601_VERSATILE; | |
- else | |
+ pr_err("HIF_8601_VERSATILE\n"); | |
+ } else { | |
hw_type = HIF_8601_SILICON; | |
+ pr_err("HIF_8601_SILICON\n"); | |
+ } | |
break; | |
default: | |
break; | |
@@ -131,14 +135,11 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv) | |
APB_WRITE(DOWNLOAD_STATUS_REG, DOWNLOAD_PENDING); | |
APB_WRITE(DOWNLOAD_FLAGS_REG, 0); | |
- /* Write the NOP Instruction */ | |
- REG_WRITE(ST90TDS_SRAM_BASE_ADDR_REG_ID, 0xFFF20000); | |
- REG_WRITE(ST90TDS_AHB_DPORT_REG_ID, 0xEAFFFFFE); | |
- | |
/* Release CPU from RESET */ | |
REG_READ(ST90TDS_CONFIG_REG_ID, val32); | |
val32 &= ~ST90TDS_CONFIG_CPU_RESET_BIT; | |
REG_WRITE(ST90TDS_CONFIG_REG_ID, val32); | |
+ pr_err("CPU released from RESET\n"); | |
/* Enable Clock */ | |
val32 &= ~ST90TDS_CONFIG_CPU_CLK_DIS_BIT; | |
@@ -161,13 +162,16 @@ static int cw1200_load_firmware_cw1200(struct cw1200_common *priv) | |
/* Check if the bootloader is ready */ | |
for (i = 0; i < 100; i += 1 + i / 2) { | |
APB_READ(DOWNLOAD_IMAGE_SIZE_REG, val32); | |
- if (val32 == DOWNLOAD_I_AM_HERE) | |
+ if (val32 == DOWNLOAD_I_AM_HERE) { | |
+ pr_err("Bootloader reported ready after %d\n", i); | |
break; | |
- mdelay(i); | |
+ } else { | |
+ pr_err("DOWNLOAD_IMAGE_SIZE_REG: 0x%.8X\n", val32); | |
+ } | |
+ mdelay(10); | |
} /* End of for loop */ | |
- | |
if (val32 != DOWNLOAD_I_AM_HERE) { | |
- pr_err("Bootloader is not ready.\n"); | |
+ pr_err("Bootloader reports error 0x%.8X.\n", val32); | |
ret = -ETIMEDOUT; | |
goto free_buffer; | |
} | |
@@ -302,6 +306,37 @@ static int config_reg_write(struct cw1200_common *priv, u32 val) | |
return 0; | |
} | |
+static int cw1200_bootloader(struct cw1200_common *priv) | |
+{ | |
+ int ret = -1; | |
+ u32 i = 0; | |
+ const char *bl_path = BOOTLOADER_CW1X60; | |
+ u32 addr = SYS_BASE_ADDR_SILICON + 0x08000000; | |
+ u32 *data = NULL; | |
+ const struct firmware *bootloader = NULL; | |
+ | |
+ /* Load a bootloader file */ | |
+ ret = request_firmware(&bootloader, bl_path, priv->pdev); | |
+ if (ret) { | |
+ pr_err("can't load bootloader file %s.\n", bl_path); | |
+ goto error; | |
+ } | |
+ | |
+ /* Down bootloader. */ | |
+ data = (u32 *)bootloader->data; | |
+ for(i = 0; i < (bootloader->size)/4; i++, addr+=4) { | |
+ cw1200_reg_write_32(priv, ST90TDS_SRAM_BASE_ADDR_REG_ID, addr); | |
+ cw1200_reg_write_32(priv, ST90TDS_AHB_DPORT_REG_ID,data[i]); | |
+ } | |
+ pr_err("Bootloader complete\n"); | |
+ | |
+error: | |
+ if(bootloader) { | |
+ release_firmware(bootloader); | |
+ } | |
+ return ret; | |
+} | |
+ | |
int cw1200_load_firmware(struct cw1200_common *priv) | |
{ | |
int ret; | |
@@ -352,6 +387,8 @@ int cw1200_load_firmware(struct cw1200_common *priv) | |
cw1200_dpll_from_clk(priv->hw_refclk), val32); | |
ret = -EIO; | |
goto out; | |
+ } else { | |
+ pr_err("Set DPLL to: 0x%.8X.\n", val32); | |
} | |
/* Set wakeup bit in device */ | |
@@ -387,6 +424,8 @@ int cw1200_load_firmware(struct cw1200_common *priv) | |
pr_err("wait_for_wakeup: device is not responding.\n"); | |
ret = -ETIMEDOUT; | |
goto out; | |
+ } else { | |
+ pr_err("WLAN device is ready.\n"); | |
} | |
switch (major_revision) { | |
@@ -467,14 +506,19 @@ int cw1200_load_firmware(struct cw1200_common *priv) | |
pr_err("Device is already in QUEUE mode!\n"); | |
ret = -EINVAL; | |
goto out; | |
+ } else { | |
+ /* Download bootloader. */ | |
+ ret = cw1200_bootloader(priv); | |
+ if (ret < 0) { | |
+ pr_err("can't download bootloader.\n"); | |
+ goto out; | |
+ } | |
} | |
switch (priv->hw_type) { | |
case HIF_8601_SILICON: | |
if (priv->hw_revision == CW1X60_HW_REV) { | |
- pr_err("Can't handle CW1160/1260 firmware load yet.\n"); | |
- ret = -ENOTSUPP; | |
- goto out; | |
+ pr_err("Detected CW1160/1260.\n"); | |
} | |
ret = cw1200_load_firmware_cw1200(priv); | |
break; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment