]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/memory/brcmstb_dpfe.c
Merge tag 'ceph-for-5.5-rc1' of git://github.com/ceph/ceph-client
[linux.git] / drivers / memory / brcmstb_dpfe.c
index f905a0076db7582c6a9700f7bb0ceb98e1a9c62c..82b415be18d1ff4ac04516f13e561446a33d3d9b 100644 (file)
@@ -127,7 +127,6 @@ enum dpfe_msg_fields {
        MSG_COMMAND,
        MSG_ARG_COUNT,
        MSG_ARG0,
-       MSG_CHKSUM,
        MSG_FIELD_MAX   = 16 /* Max number of arguments */
 };
 
@@ -232,9 +231,13 @@ static struct attribute *dpfe_v3_attrs[] = {
 };
 ATTRIBUTE_GROUPS(dpfe_v3);
 
-/* API v2 firmware commands */
-static const struct dpfe_api dpfe_api_v2 = {
-       .version = 2,
+/*
+ * Old API v2 firmware commands, as defined in the rev 0.61 specification, we
+ * use a version set to 1 to denote that it is not compatible with the new API
+ * v2 and onwards.
+ */
+static const struct dpfe_api dpfe_api_old_v2 = {
+       .version = 1,
        .fw_name = "dpfe.bin",
        .sysfs_attrs = dpfe_v2_groups,
        .command = {
@@ -243,21 +246,42 @@ static const struct dpfe_api dpfe_api_v2 = {
                        [MSG_COMMAND] = 1,
                        [MSG_ARG_COUNT] = 1,
                        [MSG_ARG0] = 1,
-                       [MSG_CHKSUM] = 4,
                },
                [DPFE_CMD_GET_REFRESH] = {
                        [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
                        [MSG_COMMAND] = 2,
                        [MSG_ARG_COUNT] = 1,
                        [MSG_ARG0] = 1,
-                       [MSG_CHKSUM] = 5,
                },
                [DPFE_CMD_GET_VENDOR] = {
                        [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
                        [MSG_COMMAND] = 2,
                        [MSG_ARG_COUNT] = 1,
                        [MSG_ARG0] = 2,
-                       [MSG_CHKSUM] = 6,
+               },
+       }
+};
+
+/*
+ * API v2 firmware commands, as defined in the rev 0.8 specification, named new
+ * v2 here
+ */
+static const struct dpfe_api dpfe_api_new_v2 = {
+       .version = 2,
+       .fw_name = NULL, /* We expect the firmware to have been downloaded! */
+       .sysfs_attrs = dpfe_v2_groups,
+       .command = {
+               [DPFE_CMD_GET_INFO] = {
+                       [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
+                       [MSG_COMMAND] = 0x101,
+               },
+               [DPFE_CMD_GET_REFRESH] = {
+                       [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
+                       [MSG_COMMAND] = 0x201,
+               },
+               [DPFE_CMD_GET_VENDOR] = {
+                       [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
+                       [MSG_COMMAND] = 0x202,
                },
        }
 };
@@ -273,18 +297,11 @@ static const struct dpfe_api dpfe_api_v3 = {
                        [MSG_COMMAND] = 0x0101,
                        [MSG_ARG_COUNT] = 1,
                        [MSG_ARG0] = 1,
-                       [MSG_CHKSUM] = 0x104,
                },
                [DPFE_CMD_GET_REFRESH] = {
                        [MSG_HEADER] = DPFE_MSG_TYPE_COMMAND,
                        [MSG_COMMAND] = 0x0202,
                        [MSG_ARG_COUNT] = 0,
-                       /*
-                        * This is a bit ugly. Without arguments, the checksum
-                        * follows right after the argument count and not at
-                        * offset MSG_CHKSUM.
-                        */
-                       [MSG_ARG0] = 0x203,
                },
                /* There's no GET_VENDOR command in API v3. */
        },
@@ -401,7 +418,7 @@ static void __finalize_command(struct brcmstb_dpfe_priv *priv)
         * It depends on the API version which MBOX register we have to write to
         * to signal we are done.
         */
-       release_mbox = (priv->dpfe_api->version < 3)
+       release_mbox = (priv->dpfe_api->version < 2)
                        ? REG_TO_HOST_MBOX : REG_TO_DCPU_MBOX;
        writel_relaxed(0, priv->regs + release_mbox);
 }
@@ -432,9 +449,17 @@ static int __send_command(struct brcmstb_dpfe_priv *priv, unsigned int cmd,
                return -ETIMEDOUT;
        }
 
+       /* Compute checksum over the message */
+       chksum_idx = msg[MSG_ARG_COUNT] + MSG_ARG_COUNT + 1;
+       chksum = get_msg_chksum(msg, chksum_idx);
+
        /* Write command and arguments to message area */
-       for (i = 0; i < MSG_FIELD_MAX; i++)
-               writel_relaxed(msg[i], regs + DCPU_MSG_RAM(i));
+       for (i = 0; i < MSG_FIELD_MAX; i++) {
+               if (i == chksum_idx)
+                       writel_relaxed(chksum, regs + DCPU_MSG_RAM(i));
+               else
+                       writel_relaxed(msg[i], regs + DCPU_MSG_RAM(i));
+       }
 
        /* Tell DCPU there is a command waiting */
        writel_relaxed(1, regs + REG_TO_DCPU_MBOX);
@@ -614,10 +639,13 @@ static int brcmstb_dpfe_download_firmware(struct brcmstb_dpfe_priv *priv)
        if (!priv->dpfe_api->fw_name)
                return -ENODEV;
 
-       ret = request_firmware(&fw, priv->dpfe_api->fw_name, dev);
-       /* request_firmware() prints its own error messages. */
+       ret = firmware_request_nowarn(&fw, priv->dpfe_api->fw_name, dev);
+       /*
+        * Defer the firmware download if the firmware file couldn't be found.
+        * The root file system may not be available yet.
+        */
        if (ret)
-               return ret;
+               return (ret == -ENOENT) ? -EPROBE_DEFER : ret;
 
        ret = __verify_firmware(&init, fw);
        if (ret)
@@ -862,7 +890,8 @@ static int brcmstb_dpfe_probe(struct platform_device *pdev)
 
        ret = brcmstb_dpfe_download_firmware(priv);
        if (ret) {
-               dev_err(dev, "Couldn't download firmware -- %d\n", ret);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(dev, "Couldn't download firmware -- %d\n", ret);
                return ret;
        }
 
@@ -885,10 +914,10 @@ static int brcmstb_dpfe_remove(struct platform_device *pdev)
 
 static const struct of_device_id brcmstb_dpfe_of_match[] = {
        /* Use legacy API v2 for a select number of chips */
-       { .compatible = "brcm,bcm7268-dpfe-cpu", .data = &dpfe_api_v2 },
-       { .compatible = "brcm,bcm7271-dpfe-cpu", .data = &dpfe_api_v2 },
-       { .compatible = "brcm,bcm7278-dpfe-cpu", .data = &dpfe_api_v2 },
-       { .compatible = "brcm,bcm7211-dpfe-cpu", .data = &dpfe_api_v2 },
+       { .compatible = "brcm,bcm7268-dpfe-cpu", .data = &dpfe_api_old_v2 },
+       { .compatible = "brcm,bcm7271-dpfe-cpu", .data = &dpfe_api_old_v2 },
+       { .compatible = "brcm,bcm7278-dpfe-cpu", .data = &dpfe_api_old_v2 },
+       { .compatible = "brcm,bcm7211-dpfe-cpu", .data = &dpfe_api_new_v2 },
        /* API v3 is the default going forward */
        { .compatible = "brcm,dpfe-cpu", .data = &dpfe_api_v3 },
        {}