Skip to content

Instantly share code, notes, and snippets.

@halmartin
Last active January 8, 2017 18:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save halmartin/a4b84699c1d7715c8288544a742758fa to your computer and use it in GitHub Desktop.
Save halmartin/a4b84699c1d7715c8288544a742758fa to your computer and use it in GitHub Desktop.
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