Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1427549 > unrolled thread
| Started by | Neil Armstrong <narmstrong@baylibre.com> |
|---|---|
| First post | 2016-06-21 12:10 +0200 |
| Last post | 2016-06-24 04:40 +0200 |
| Articles | 9 — 3 participants |
Back to article view | Back to linux.kernel
[RFC PATCH v2 0/9] scpi: Add SCPI registry to handle legacy protocol Neil Armstrong <narmstrong@baylibre.com> - 2016-06-21 12:10 +0200
[RFC PATCH v2 5/9] firmware: scpi: Switch arm_scpi to use new registry Neil Armstrong <narmstrong@baylibre.com> - 2016-06-21 12:10 +0200
[RFC PATCH v2 8/9] ARM64: dts: meson-gxbb: Add SRAM node Neil Armstrong <narmstrong@baylibre.com> - 2016-06-21 12:10 +0200
[RFC PATCH v2 6/9] firmware: Add legacy SCPI protocol driver Neil Armstrong <narmstrong@baylibre.com> - 2016-06-21 12:10 +0200
Re: [RFC PATCH v2 6/9] firmware: Add legacy SCPI protocol driver Sudeep Holla <sudeep.holla@arm.com> - 2016-06-30 13:00 +0200
[RFC PATCH v2 9/9] ARM64: dts: meson-gxbb: Add SCPI with cpufreq & sensors Nodes Neil Armstrong <narmstrong@baylibre.com> - 2016-06-21 12:10 +0200
Re: [RFC PATCH v2 0/9] scpi: Add SCPI registry to handle legacy protocol Frank Wang <frank.wang@rock-chips.com> - 2016-06-22 05:10 +0200
Re: [RFC PATCH v2 0/9] scpi: Add SCPI registry to handle legacy protocol Neil Armstrong <narmstrong@baylibre.com> - 2016-06-23 14:50 +0200
Re: [RFC PATCH v2 0/9] scpi: Add SCPI registry to handle legacy protocol Frank Wang <frank.wang@rock-chips.com> - 2016-06-24 04:40 +0200
| From | Neil Armstrong <narmstrong@baylibre.com> |
|---|---|
| Date | 2016-06-21 12:10 +0200 |
| Subject | [RFC PATCH v2 0/9] scpi: Add SCPI registry to handle legacy protocol |
| Message-ID | <rMqN3-4mp-21@gated-at.bofh.it> |
This patchset aims to support the legacy SCPI firmware implementation that was delivered as early technology preview for the JUNO platform. Finally a stable, maintained and public implementation for the SCPI protocol has been upstreamed part of the JUNO support and it is the recommended way of implementing SCP communication on ARMv8 platforms. The Amlogic GXBB platform is using this legacy protocol, as the RK3368 & RK3399 platforms. Only the GXBB example is provided here, but it's unclear if other Amlogic ARMv8 based SoCs uses this legacy procotol. In order to support the legacy protocol : - Move the scpi_get_ops to a thin registry layer - Change the arm_scpi.c to use the registry layer - Add a separate config option to build the registry layer - Add the legacy SCPI driver based on the new implementation - For example, add the Amlogic GXBB MHU and SCPI DT cpufreq & sensors nodes Initial RFC discution tread can be found at https://lkml.org/lkml/2016/5/26/111 Neil Armstrong (9): mailbox: Add Amlogic Meson Message-Handling-Unit dt-bindings: mailbox: Add Amlogic Meson MHU Bindings ARM64: dts: meson-gxbb: Add Meson MHU Node firmware: Add a SCPI registry to handle multiple implementations firmware: scpi: Switch arm_scpi to use new registry firmware: Add legacy SCPI protocol driver dt-bindings: arm: Update arm,scpi bindings with Meson GXBB SCPI ARM64: dts: meson-gxbb: Add SRAM node ARM64: dts: meson-gxbb: Add SCPI with cpufreq & sensors Nodes Documentation/devicetree/bindings/arm/arm,scpi.txt | 8 +- .../devicetree/bindings/mailbox/meson-mhu.txt | 33 ++ arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 53 ++ drivers/firmware/Kconfig | 24 + drivers/firmware/Makefile | 2 + drivers/firmware/arm_scpi.c | 14 +- drivers/firmware/legacy_scpi.c | 644 +++++++++++++++++++++ drivers/firmware/scpi.c | 94 +++ drivers/mailbox/Makefile | 2 + drivers/mailbox/meson_mhu.c | 199 +++++++ include/linux/scpi_protocol.h | 15 +- 11 files changed, 1075 insertions(+), 13 deletions(-) create mode 100644 Documentation/devicetree/bindings/mailbox/meson-mhu.txt create mode 100644 drivers/firmware/legacy_scpi.c create mode 100644 drivers/firmware/scpi.c create mode 100644 drivers/mailbox/meson_mhu.c -- 2.7.0
[toc] | [next] | [standalone]
| From | Neil Armstrong <narmstrong@baylibre.com> |
|---|---|
| Date | 2016-06-21 12:10 +0200 |
| Subject | [RFC PATCH v2 5/9] firmware: scpi: Switch arm_scpi to use new registry |
| Message-ID | <rMqN4-4mp-59@gated-at.bofh.it> |
| In reply to | #1427549 |
Change the arm_scpi.c to use the registry layer instead of returning it's
context ->ops pointer.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/firmware/arm_scpi.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
index 7e3e595..ba6bc53 100644
--- a/drivers/firmware/arm_scpi.c
+++ b/drivers/firmware/arm_scpi.c
@@ -162,7 +162,6 @@ struct scpi_drvinfo {
u32 firmware_version;
int num_chans;
atomic_t next_chan;
- struct scpi_ops *scpi_ops;
struct scpi_chan *channels;
struct scpi_dvfs_info *dvfs[MAX_DVFS_DOMAINS];
};
@@ -526,7 +525,7 @@ static int scpi_sensor_get_info(u16 sensor_id, struct scpi_sensor_info *info)
return ret;
}
-int scpi_sensor_get_value(u16 sensor, u64 *val)
+static int scpi_sensor_get_value(u16 sensor, u64 *val)
{
__le16 id = cpu_to_le16(sensor);
struct sensor_value buf;
@@ -554,12 +553,6 @@ static struct scpi_ops scpi_ops = {
.sensor_get_value = scpi_sensor_get_value,
};
-struct scpi_ops *get_scpi_ops(void)
-{
- return scpi_info ? scpi_info->scpi_ops : NULL;
-}
-EXPORT_SYMBOL_GPL(get_scpi_ops);
-
static int scpi_init_versions(struct scpi_drvinfo *info)
{
int ret;
@@ -743,7 +736,10 @@ err:
FW_REV_MAJOR(scpi_info->firmware_version),
FW_REV_MINOR(scpi_info->firmware_version),
FW_REV_PATCH(scpi_info->firmware_version));
- scpi_info->scpi_ops = &scpi_ops;
+
+ ret = devm_scpi_ops_register(dev, &scpi_ops);
+ if (ret)
+ return ret;
ret = sysfs_create_groups(&dev->kobj, versions_groups);
if (ret)
--
2.7.0
[toc] | [prev] | [next] | [standalone]
| From | Neil Armstrong <narmstrong@baylibre.com> |
|---|---|
| Date | 2016-06-21 12:10 +0200 |
| Subject | [RFC PATCH v2 8/9] ARM64: dts: meson-gxbb: Add SRAM node |
| Message-ID | <rMqN4-4mp-67@gated-at.bofh.it> |
| In reply to | #1427549 |
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index 77381d0..913ba86 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -124,6 +124,15 @@
#size-cells = <2>;
ranges;
+ sram: sram@c8000000 {
+ compatible = "amlogic,meson-gxbb-sram", "mmio-sram";
+ reg = <0x0 0xc8000000 0x0 0x14000>;
+
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x0 0xc8000000 0x14000>;
+ };
+
cbus: cbus@c1100000 {
compatible = "simple-bus";
reg = <0x0 0xc1100000 0x0 0x100000>;
--
2.7.0
[toc] | [prev] | [next] | [standalone]
| From | Neil Armstrong <narmstrong@baylibre.com> |
|---|---|
| Date | 2016-06-21 12:10 +0200 |
| Subject | [RFC PATCH v2 6/9] firmware: Add legacy SCPI protocol driver |
| Message-ID | <rMqN5-4mp-81@gated-at.bofh.it> |
| In reply to | #1427549 |
Add legacy SCPI driver based on the latest SCPI driver but modified to behave
like an earlier technology preview SCPI implementation that at least the
Amlogic GXBB ARMv8 based platform uses in it's SCP firmware implementation.
The main differences between the mainline, public and recommended SCPI
implementation are :
- virtual channels is not implemented
- command word is passed by the MHU instead of the virtual channel ID
- uses "sender id" in the command word for each commands groups
- payload size shift in command word is different
- command word is not in SRAM, so command queuing is not possible
- command indexes are different
- command data structures differs
- commands are redirected to low or high priority channels by their indexes,
so round-robin redirection is not possible
A clear disclaimer is added to make it clear this implementation should not
be used for new products and is only here to support already released SoCs.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/firmware/Kconfig | 20 ++
drivers/firmware/Makefile | 1 +
drivers/firmware/legacy_scpi.c | 644 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 665 insertions(+)
create mode 100644 drivers/firmware/legacy_scpi.c
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 95b01f4..b9c2a33 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -31,6 +31,26 @@ config ARM_SCPI_PROTOCOL
This protocol library provides interface for all the client drivers
making use of the features offered by the SCP.
+config LEGACY_SCPI_PROTOCOL
+ bool "Legacy System Control and Power Interface (SCPI) Message Protocol"
+ default y if ARCH_MESON
+ select ARM_SCPI_FW
+ help
+ System Control and Power Interface (SCPI) Message Protocol is
+ defined for the purpose of communication between the Application
+ Cores(AP) and the System Control Processor(SCP). The MHU peripheral
+ provides a mechanism for inter-processor communication between SCP
+ and AP.
+
+ SCP controls most of the power managament on the Application
+ Processors. It offers control and management of: the core/cluster
+ power states, various power domain DVFS including the core/cluster,
+ certain system clocks configuration, thermal sensors and many
+ others.
+
+ This protocol library provides interface for all the client drivers
+ making use of the features offered by the legacy SCP protocol.
+
config EDD
tristate "BIOS Enhanced Disk Drive calls determine boot disk"
depends on X86
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index b697462..c2cac9c 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -4,6 +4,7 @@
obj-$(CONFIG_ARM_PSCI_FW) += psci.o
obj-$(CONFIG_SCPI_FW) += scpi.o
obj-$(CONFIG_ARM_SCPI_PROTOCOL) += arm_scpi.o
+obj-$(CONFIG_LEGACY_SCPI_PROTOCOL) += legacy_scpi.o
obj-$(CONFIG_DMI) += dmi_scan.o
obj-$(CONFIG_DMI_SYSFS) += dmi-sysfs.o
obj-$(CONFIG_EDD) += edd.o
diff --git a/drivers/firmware/legacy_scpi.c b/drivers/firmware/legacy_scpi.c
new file mode 100644
index 0000000..4bd3ff7
--- /dev/null
+++ b/drivers/firmware/legacy_scpi.c
@@ -0,0 +1,644 @@
+/*
+ * Legacy System Control and Power Interface (SCPI) Message Protocol driver
+ *
+ * SCPI Message Protocol is used between the System Control Processor(SCP)
+ * and the Application Processors(AP). The Message Handling Unit(MHU)
+ * provides a mechanism for inter-processor communication between SCP's
+ * Cortex M3 and AP.
+ *
+ * SCP offers control and management of the core/cluster power states,
+ * various power domain DVFS including the core/cluster, certain system
+ * clocks configuration, thermal sensors and many others.
+ *
+ * Copyright (C) 2016 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ *
+ * Heavily based on arm_scpi.c from :
+ * Copyright (C) 2015 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * DISCLAIMER
+ *
+ * This SCPI implementation is based on a technology preview release
+ * and new ARMv8 SoCs implementations should use the standard SCPI
+ * implementation as defined in the ARM DUI 0922G and implemented
+ * in the arm_scpi.c driver.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/bitmap.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/export.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mailbox_client.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/printk.h>
+#include <linux/scpi_protocol.h>
+#include <linux/slab.h>
+#include <linux/sort.h>
+#include <linux/spinlock.h>
+
+#define CMD_ID_SHIFT 0
+#define CMD_ID_MASK 0x7f
+#define CMD_SENDER_ID_SHIFT 8
+#define CMD_SENDER_ID_MASK 0xff
+#define CMD_DATA_SIZE_SHIFT 20
+#define CMD_DATA_SIZE_MASK 0x1ff
+#define PACK_SCPI_CMD(cmd_id, sender, tx_sz) \
+ ((((cmd_id) & CMD_ID_MASK) << CMD_ID_SHIFT) | \
+ (((sender) & CMD_SENDER_ID_MASK) << CMD_SENDER_ID_SHIFT) | \
+ (((tx_sz) & CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT))
+
+#define CMD_SIZE(cmd) (((cmd) >> CMD_DATA_SIZE_SHIFT) & CMD_DATA_SIZE_MASK)
+#define CMD_UNIQ_MASK (CMD_TOKEN_ID_MASK << CMD_TOKEN_ID_SHIFT | CMD_ID_MASK)
+#define CMD_XTRACT_UNIQ(cmd) ((cmd) & CMD_UNIQ_MASK)
+
+#define MAX_DVFS_DOMAINS 3
+#define MAX_DVFS_OPPS 16
+#define DVFS_LATENCY(hdr) (le32_to_cpu(hdr) >> 16)
+#define DVFS_OPP_COUNT(hdr) ((le32_to_cpu(hdr) >> 8) & 0xff)
+
+#define MAX_RX_TIMEOUT (msecs_to_jiffies(30))
+
+enum legacy_scpi_error_codes {
+ SCPI_SUCCESS = 0, /* Success */
+ SCPI_ERR_PARAM = 1, /* Invalid parameter(s) */
+ SCPI_ERR_ALIGN = 2, /* Invalid alignment */
+ SCPI_ERR_SIZE = 3, /* Invalid size */
+ SCPI_ERR_HANDLER = 4, /* Invalid handler/callback */
+ SCPI_ERR_ACCESS = 5, /* Invalid access/permission denied */
+ SCPI_ERR_RANGE = 6, /* Value out of range */
+ SCPI_ERR_TIMEOUT = 7, /* Timeout has occurred */
+ SCPI_ERR_NOMEM = 8, /* Invalid memory area or pointer */
+ SCPI_ERR_PWRSTATE = 9, /* Invalid power state */
+ SCPI_ERR_SUPPORT = 10, /* Not supported or disabled */
+ SCPI_ERR_DEVICE = 11, /* Device error */
+ SCPI_ERR_BUSY = 12, /* Device busy */
+ SCPI_ERR_MAX
+};
+
+enum legacy_scpi_client_id {
+ SCPI_CL_NONE,
+ SCPI_CL_CLOCKS,
+ SCPI_CL_DVFS,
+ SCPI_CL_POWER,
+ SCPI_CL_THERMAL,
+ SCPI_CL_REMOTE,
+ SCPI_CL_LED_TIMER,
+ SCPI_MAX,
+};
+
+enum legacy_scpi_std_cmd {
+ SCPI_CMD_INVALID = 0x00,
+ SCPI_CMD_SCPI_READY = 0x01,
+ SCPI_CMD_SCPI_CAPABILITIES = 0x02,
+ SCPI_CMD_EVENT = 0x03,
+ SCPI_CMD_SET_CSS_PWR_STATE = 0x04,
+ SCPI_CMD_GET_CSS_PWR_STATE = 0x05,
+ SCPI_CMD_CFG_PWR_STATE_STAT = 0x06,
+ SCPI_CMD_GET_PWR_STATE_STAT = 0x07,
+ SCPI_CMD_SYS_PWR_STATE = 0x08,
+ SCPI_CMD_L2_READY = 0x09,
+ SCPI_CMD_SET_AP_TIMER = 0x0a,
+ SCPI_CMD_CANCEL_AP_TIME = 0x0b,
+ SCPI_CMD_DVFS_CAPABILITIES = 0x0c,
+ SCPI_CMD_GET_DVFS_INFO = 0x0d,
+ SCPI_CMD_SET_DVFS = 0x0e,
+ SCPI_CMD_GET_DVFS = 0x0f,
+ SCPI_CMD_GET_DVFS_STAT = 0x10,
+ SCPI_CMD_SET_RTC = 0x11,
+ SCPI_CMD_GET_RTC = 0x12,
+ SCPI_CMD_CLOCK_CAPABILITIES = 0x13,
+ SCPI_CMD_SET_CLOCK_INDEX = 0x14,
+ SCPI_CMD_SET_CLOCK_VALUE = 0x15,
+ SCPI_CMD_GET_CLOCK_VALUE = 0x16,
+ SCPI_CMD_PSU_CAPABILITIES = 0x17,
+ SCPI_CMD_SET_PSU = 0x18,
+ SCPI_CMD_GET_PSU = 0x19,
+ SCPI_CMD_SENSOR_CAPABILITIES = 0x1a,
+ SCPI_CMD_SENSOR_INFO = 0x1b,
+ SCPI_CMD_SENSOR_VALUE = 0x1c,
+ SCPI_CMD_SENSOR_CFG_PERIODIC = 0x1d,
+ SCPI_CMD_SENSOR_CFG_BOUNDS = 0x1e,
+ SCPI_CMD_SENSOR_ASYNC_VALUE = 0x1f,
+ SCPI_CMD_COUNT
+};
+
+struct legacy_scpi_xfer {
+ u32 cmd;
+ u32 status;
+ const void *tx_buf;
+ void *rx_buf;
+ unsigned int tx_len;
+ unsigned int rx_len;
+ struct completion done;
+};
+
+struct legacy_scpi_chan {
+ struct mbox_client cl;
+ struct mbox_chan *chan;
+ void __iomem *tx_payload;
+ void __iomem *rx_payload;
+ spinlock_t rx_lock; /* locking for the rx pending list */
+ struct mutex xfers_lock;
+ struct legacy_scpi_xfer t;
+};
+
+struct legacy_scpi_drvinfo {
+ int num_chans;
+ struct legacy_scpi_chan *channels;
+ struct scpi_dvfs_info *dvfs[MAX_DVFS_DOMAINS];
+};
+
+/*
+ * The SCP firmware only executes in little-endian mode, so any buffers
+ * shared through SCPI should have their contents converted to little-endian
+ */
+struct legacy_scpi_shared_mem {
+ __le32 status;
+ u8 payload[0];
+} __packed;
+
+struct scp_capabilities {
+ __le32 protocol_version;
+ __le32 event_version;
+ __le32 platform_version;
+ __le32 commands[4];
+} __packed;
+
+struct clk_get_info {
+ __le16 id;
+ __le16 flags;
+ __le32 min_rate;
+ __le32 max_rate;
+ u8 name[20];
+} __packed;
+
+struct clk_get_value {
+ __le32 rate;
+} __packed;
+
+struct clk_set_value {
+ __le32 rate;
+ __le16 id;
+ __le16 reserved;
+} __packed;
+
+struct dvfs_info {
+ __le32 header;
+ struct {
+ __le32 freq;
+ __le32 m_volt;
+ } opps[MAX_DVFS_OPPS];
+} __packed;
+
+struct dvfs_get {
+ u8 index;
+} __packed;
+
+struct dvfs_set {
+ u8 domain;
+ u8 index;
+} __packed;
+
+struct sensor_capabilities {
+ __le16 sensors;
+} __packed;
+
+struct sensor_info {
+ __le16 sensor_id;
+ u8 class;
+ u8 trigger_type;
+ char name[20];
+};
+
+struct sensor_value {
+ __le32 val;
+} __packed;
+
+static struct legacy_scpi_drvinfo *legacy_scpi_info;
+
+static int legacy_scpi_linux_errmap[SCPI_ERR_MAX] = {
+ /* better than switch case as long as return value is continuous */
+ 0, /* SCPI_SUCCESS */
+ -EINVAL, /* SCPI_ERR_PARAM */
+ -ENOEXEC, /* SCPI_ERR_ALIGN */
+ -EMSGSIZE, /* SCPI_ERR_SIZE */
+ -EINVAL, /* SCPI_ERR_HANDLER */
+ -EACCES, /* SCPI_ERR_ACCESS */
+ -ERANGE, /* SCPI_ERR_RANGE */
+ -ETIMEDOUT, /* SCPI_ERR_TIMEOUT */
+ -ENOMEM, /* SCPI_ERR_NOMEM */
+ -EINVAL, /* SCPI_ERR_PWRSTATE */
+ -EOPNOTSUPP, /* SCPI_ERR_SUPPORT */
+ -EIO, /* SCPI_ERR_DEVICE */
+ -EBUSY, /* SCPI_ERR_BUSY */
+};
+
+static inline int legacy_scpi_to_linux_errno(int errno)
+{
+ if (errno >= SCPI_SUCCESS && errno < SCPI_ERR_MAX)
+ return legacy_scpi_linux_errmap[errno];
+ return -EIO;
+}
+
+static void legacy_scpi_handle_remote_msg(struct mbox_client *c, void *msg)
+{
+ struct legacy_scpi_chan *ch = container_of(c, struct legacy_scpi_chan, cl);
+ struct legacy_scpi_shared_mem *mem = ch->rx_payload;
+ unsigned long flags;
+ unsigned int len;
+
+ spin_lock_irqsave(&ch->rx_lock, flags);
+
+ len = ch->t.rx_len;
+
+ ch->t.status = le32_to_cpu(mem->status);
+ if (len)
+ memcpy_fromio(ch->t.rx_buf, mem->payload, len);
+
+ complete(&ch->t.done);
+
+ spin_unlock_irqrestore(&ch->rx_lock, flags);
+}
+
+static void legacy_scpi_tx_prepare(struct mbox_client *c, void *msg)
+{
+ struct legacy_scpi_chan *ch = container_of(c, struct legacy_scpi_chan, cl);
+
+ if (ch->t.tx_buf && ch->t.tx_len)
+ memcpy_toio(ch->tx_payload, ch->t.tx_buf, ch->t.tx_len);
+}
+
+static int high_priority_cmds[] = {
+ SCPI_CMD_GET_CSS_PWR_STATE,
+ SCPI_CMD_CFG_PWR_STATE_STAT,
+ SCPI_CMD_GET_PWR_STATE_STAT,
+ SCPI_CMD_SET_DVFS,
+ SCPI_CMD_GET_DVFS,
+ SCPI_CMD_SET_RTC,
+ SCPI_CMD_GET_RTC,
+ SCPI_CMD_SET_CLOCK_INDEX,
+ SCPI_CMD_SET_CLOCK_VALUE,
+ SCPI_CMD_GET_CLOCK_VALUE,
+ SCPI_CMD_SET_PSU,
+ SCPI_CMD_GET_PSU,
+ SCPI_CMD_SENSOR_CFG_PERIODIC,
+ SCPI_CMD_SENSOR_CFG_BOUNDS,
+};
+
+static int legacy_scpi_get_chan(u8 cmd)
+{
+ int idx;
+
+ for (idx = 0; idx < ARRAY_SIZE(high_priority_cmds); idx++)
+ if (cmd == high_priority_cmds[idx])
+ return 1;
+
+ return 0;
+}
+
+static int legacy_scpi_send_message(u8 cmd, unsigned int sender,
+ void *tx_buf, unsigned int tx_len,
+ void *rx_buf, unsigned int rx_len)
+{
+ int ret;
+ u8 chan;
+ struct legacy_scpi_xfer *msg;
+ struct legacy_scpi_chan *legacy_scpi_chan;
+
+ chan = legacy_scpi_get_chan(cmd);
+ legacy_scpi_chan = legacy_scpi_info->channels + chan;
+
+ msg = &legacy_scpi_chan->t;
+
+ msg->cmd = PACK_SCPI_CMD(cmd, sender, tx_len);
+ msg->tx_buf = tx_buf;
+ msg->tx_len = tx_len;
+ msg->rx_buf = rx_buf;
+ msg->rx_len = rx_len;
+ init_completion(&msg->done);
+
+ ret = mbox_send_message(legacy_scpi_chan->chan, &msg->cmd);
+ if (ret < 0)
+ goto out;
+
+ if (!wait_for_completion_timeout(&msg->done, MAX_RX_TIMEOUT))
+ ret = -ETIMEDOUT;
+ else
+ /* first status word */
+ ret = msg->status;
+out:
+ /* SCPI error codes > 0, translate them to Linux scale*/
+ return ret > 0 ? legacy_scpi_to_linux_errno(ret) : ret;
+}
+
+static u32 legacy_scpi_get_version(void)
+{
+ /* TOFIX */
+ return 0;
+}
+
+static unsigned long legacy_scpi_clk_get_val(u16 clk_id)
+{
+ int ret;
+ struct clk_get_value clk;
+ __le16 le_clk_id = cpu_to_le16(clk_id);
+
+ ret = legacy_scpi_send_message(SCPI_CMD_GET_CLOCK_VALUE, SCPI_CL_CLOCKS,
+ &le_clk_id, sizeof(le_clk_id),
+ &clk, sizeof(clk));
+
+ return ret ? ret : le32_to_cpu(clk.rate);
+}
+
+static int legacy_scpi_clk_set_val(u16 clk_id, unsigned long rate)
+{
+ int stat;
+ struct clk_set_value clk = {
+ .id = cpu_to_le16(clk_id),
+ .rate = cpu_to_le32(rate)
+ };
+
+ return legacy_scpi_send_message(SCPI_CMD_SET_CLOCK_VALUE, SCPI_CL_CLOCKS,
+ &clk, sizeof(clk),
+ &stat, sizeof(stat));
+}
+
+static int legacy_scpi_dvfs_get_idx(u8 domain)
+{
+ int ret;
+ struct dvfs_get dvfs;
+
+ ret = legacy_scpi_send_message(SCPI_CMD_GET_DVFS, SCPI_CL_DVFS,
+ &domain, sizeof(domain),
+ &dvfs, sizeof(dvfs));
+
+ return ret ? ret : dvfs.index;
+}
+
+static int legacy_scpi_dvfs_set_idx(u8 domain, u8 index)
+{
+ int stat;
+ struct dvfs_set dvfs = {domain, index};
+
+ return legacy_scpi_send_message(SCPI_CMD_SET_DVFS, SCPI_CL_DVFS,
+ &dvfs, sizeof(dvfs),
+ &stat, sizeof(stat));
+}
+
+static struct scpi_dvfs_info *legacy_scpi_dvfs_get_info(u8 domain)
+{
+ struct scpi_dvfs_info *info;
+ struct scpi_opp *opp;
+ struct dvfs_info buf;
+ int ret, i;
+
+ if (domain >= MAX_DVFS_DOMAINS)
+ return ERR_PTR(-EINVAL);
+
+ if (legacy_scpi_info->dvfs[domain]) /* data already populated */
+ return legacy_scpi_info->dvfs[domain];
+
+ ret = legacy_scpi_send_message(SCPI_CMD_GET_DVFS_INFO, SCPI_CL_DVFS,
+ &domain, sizeof(domain),
+ &buf, sizeof(buf));
+
+ if (ret)
+ return ERR_PTR(ret);
+
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ return ERR_PTR(-ENOMEM);
+
+ info->count = DVFS_OPP_COUNT(buf.header);
+ info->latency = DVFS_LATENCY(buf.header) * 1000; /* uS to nS */
+
+ info->opps = kcalloc(info->count, sizeof(*opp), GFP_KERNEL);
+ if (!info->opps) {
+ kfree(info);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ for (i = 0, opp = info->opps; i < info->count; i++, opp++) {
+ opp->freq = le32_to_cpu(buf.opps[i].freq);
+ opp->m_volt = le32_to_cpu(buf.opps[i].m_volt);
+ }
+
+ legacy_scpi_info->dvfs[domain] = info;
+ return info;
+}
+
+static int legacy_scpi_sensor_get_capability(u16 *sensors)
+{
+ struct sensor_capabilities cap_buf;
+ int ret;
+
+ ret = legacy_scpi_send_message(SCPI_CMD_SENSOR_CAPABILITIES,
+ SCPI_CL_THERMAL, NULL, 0, &cap_buf,
+ sizeof(cap_buf));
+ if (!ret)
+ *sensors = le16_to_cpu(cap_buf.sensors);
+
+ return ret;
+}
+
+static int legacy_scpi_sensor_get_info(u16 sensor_id,
+ struct scpi_sensor_info *info)
+{
+ __le16 id = cpu_to_le16(sensor_id);
+ struct sensor_info _info;
+ int ret;
+
+ ret = legacy_scpi_send_message(SCPI_CMD_SENSOR_INFO, SCPI_CL_THERMAL,
+ &id, sizeof(id),
+ &_info, sizeof(_info));
+ if (!ret) {
+ memcpy(info, &_info, sizeof(*info));
+ info->sensor_id = le16_to_cpu(_info.sensor_id);
+ }
+
+ return ret;
+}
+
+static int legacy_scpi_sensor_get_value(u16 sensor, u64 *val)
+{
+ __le16 id = cpu_to_le16(sensor);
+ struct sensor_value buf;
+ int ret;
+
+ ret = legacy_scpi_send_message(SCPI_CMD_SENSOR_VALUE, SCPI_CL_THERMAL,
+ &id, sizeof(id),
+ &buf, sizeof(buf));
+ if (!ret)
+ *val = (u64)le32_to_cpu(buf.val);
+
+ return ret;
+}
+
+static struct scpi_ops legacy_scpi_ops = {
+ .get_version = legacy_scpi_get_version,
+ .clk_get_val = legacy_scpi_clk_get_val,
+ .clk_set_val = legacy_scpi_clk_set_val,
+ .dvfs_get_idx = legacy_scpi_dvfs_get_idx,
+ .dvfs_set_idx = legacy_scpi_dvfs_set_idx,
+ .dvfs_get_info = legacy_scpi_dvfs_get_info,
+ .sensor_get_capability = legacy_scpi_sensor_get_capability,
+ .sensor_get_info = legacy_scpi_sensor_get_info,
+ .sensor_get_value = legacy_scpi_sensor_get_value,
+};
+
+static void legacy_scpi_free_channels(struct device *dev,
+ struct legacy_scpi_chan *pchan, int count)
+{
+ int i;
+
+ for (i = 0; i < count && pchan->chan; i++, pchan++)
+ mbox_free_channel(pchan->chan);
+}
+
+static int legacy_scpi_remove(struct platform_device *pdev)
+{
+ int i;
+ struct device *dev = &pdev->dev;
+ struct legacy_scpi_drvinfo *info = platform_get_drvdata(pdev);
+
+ /* stop exporting SCPI ops */
+ legacy_scpi_info = NULL;
+
+ of_platform_depopulate(dev);
+ legacy_scpi_free_channels(dev, info->channels, info->num_chans);
+ platform_set_drvdata(pdev, NULL);
+
+ for (i = 0; i < MAX_DVFS_DOMAINS && info->dvfs[i]; i++) {
+ kfree(info->dvfs[i]->opps);
+ kfree(info->dvfs[i]);
+ }
+
+ return 0;
+}
+
+static int legacy_scpi_probe(struct platform_device *pdev)
+{
+ int count, idx, ret;
+ struct resource res;
+ struct legacy_scpi_chan *legacy_scpi_chan;
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+
+ legacy_scpi_info = devm_kzalloc(dev, sizeof(*legacy_scpi_info), GFP_KERNEL);
+ if (!legacy_scpi_info)
+ return -ENOMEM;
+
+ count = of_count_phandle_with_args(np, "mboxes", "#mbox-cells");
+ if (count < 0) {
+ dev_err(dev, "no mboxes property in '%s'\n", np->full_name);
+ return -ENODEV;
+ }
+
+ legacy_scpi_chan = devm_kcalloc(dev, count,
+ sizeof(*legacy_scpi_chan), GFP_KERNEL);
+ if (!legacy_scpi_chan)
+ return -ENOMEM;
+
+ for (idx = 0; idx < count; idx++) {
+ resource_size_t size;
+ struct legacy_scpi_chan *pchan = legacy_scpi_chan + idx;
+ struct mbox_client *cl = &pchan->cl;
+ struct device_node *shmem = of_parse_phandle(np, "shmem", idx);
+
+ if (of_address_to_resource(shmem, 0, &res)) {
+ dev_err(dev, "failed to get SCPI payload mem resource\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ size = resource_size(&res);
+
+ dev_dbg(dev, "chan%d: sram start=%llx size=%lld\n",
+ idx, res.start, size);
+
+ pchan->rx_payload = devm_ioremap(dev, res.start, size);
+ if (!pchan->rx_payload) {
+ dev_err(dev, "failed to ioremap SCPI payload\n");
+ ret = -EADDRNOTAVAIL;
+ goto err;
+ }
+ pchan->tx_payload = pchan->rx_payload + (size >> 1);
+
+ dev_dbg(dev, "chan%d: payload rx=%p tx=%p\n",
+ idx, pchan->rx_payload, pchan->tx_payload);
+
+ cl->dev = dev;
+ cl->rx_callback = legacy_scpi_handle_remote_msg;
+ cl->tx_prepare = legacy_scpi_tx_prepare;
+ cl->tx_block = true;
+ cl->tx_tout = 20;
+ cl->knows_txdone = false; /* controller can't ack */
+
+ spin_lock_init(&pchan->rx_lock);
+ mutex_init(&pchan->xfers_lock);
+
+ pchan->chan = mbox_request_channel(cl, idx);
+ if (!IS_ERR(pchan->chan))
+ continue;
+ else
+ ret = PTR_ERR(pchan->chan);
+err:
+ legacy_scpi_free_channels(dev, legacy_scpi_chan, idx);
+ legacy_scpi_info = NULL;
+ return ret;
+ }
+
+ legacy_scpi_info->channels = legacy_scpi_chan;
+ legacy_scpi_info->num_chans = count;
+ platform_set_drvdata(pdev, legacy_scpi_info);
+
+ ret = devm_scpi_ops_register(dev, &legacy_scpi_ops);
+ if (ret)
+ return ret;
+
+ return of_platform_populate(dev->of_node, NULL, NULL, dev);
+}
+
+static const struct of_device_id legacy_scpi_of_match[] = {
+ {.compatible = "arm,legacy-scpi"},
+ {.compatible = "amlogic,meson-gxbb-scpi"},
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, legacy_scpi_of_match);
+
+static struct platform_driver legacy_scpi_driver = {
+ .driver = {
+ .name = "legacy-scpi",
+ .of_match_table = legacy_scpi_of_match,
+ },
+ .probe = legacy_scpi_probe,
+ .remove = legacy_scpi_remove,
+};
+module_platform_driver(legacy_scpi_driver);
+
+MODULE_AUTHOR("Sudeep Holla <sudeep.holla@arm.com>");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_DESCRIPTION("ARM Legacy SCPI mailbox protocol driver");
+MODULE_LICENSE("GPL v2");
--
2.7.0
[toc] | [prev] | [next] | [standalone]
| From | Sudeep Holla <sudeep.holla@arm.com> |
|---|---|
| Date | 2016-06-30 13:00 +0200 |
| Subject | Re: [RFC PATCH v2 6/9] firmware: Add legacy SCPI protocol driver |
| Message-ID | <rPHRo-72-13@gated-at.bofh.it> |
| In reply to | #1427557 |
On 21/06/16 11:02, Neil Armstrong wrote:
> Add legacy SCPI driver based on the latest SCPI driver but modified to behave
> like an earlier technology preview SCPI implementation that at least the
> Amlogic GXBB ARMv8 based platform uses in it's SCP firmware implementation.
>
> The main differences between the mainline, public and recommended SCPI
> implementation are :
> - virtual channels is not implemented
> - command word is passed by the MHU instead of the virtual channel ID
> - uses "sender id" in the command word for each commands groups
> - payload size shift in command word is different
> - command word is not in SRAM, so command queuing is not possible
> - command indexes are different
> - command data structures differs
> - commands are redirected to low or high priority channels by their indexes,
> so round-robin redirection is not possible
I doubt if that's the case. At-least the original arm scp f/w didn't
check that. Can you please trying sending any commands on any channel ?
>
> A clear disclaimer is added to make it clear this implementation should not
> be used for new products and is only here to support already released SoCs.
>
> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
> drivers/firmware/Kconfig | 20 ++
> drivers/firmware/Makefile | 1 +
> drivers/firmware/legacy_scpi.c | 644 +++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 665 insertions(+)
> create mode 100644 drivers/firmware/legacy_scpi.c
>
> diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
> index 95b01f4..b9c2a33 100644
> --- a/drivers/firmware/Kconfig
> +++ b/drivers/firmware/Kconfig
> @@ -31,6 +31,26 @@ config ARM_SCPI_PROTOCOL
> This protocol library provides interface for all the client drivers
> making use of the features offered by the SCP.
>
> +config LEGACY_SCPI_PROTOCOL
> + bool "Legacy System Control and Power Interface (SCPI) Message Protocol"
Do we really need to add another config ? I thought we could just manage
with compatibles.
> + default y if ARCH_MESON
> + select ARM_SCPI_FW
> + help
> + System Control and Power Interface (SCPI) Message Protocol is
> + defined for the purpose of communication between the Application
> + Cores(AP) and the System Control Processor(SCP). The MHU peripheral
> + provides a mechanism for inter-processor communication between SCP
> + and AP.
[...]
> diff --git a/drivers/firmware/legacy_scpi.c b/drivers/firmware/legacy_scpi.c
> new file mode 100644
> index 0000000..4bd3ff7
> --- /dev/null
> +++ b/drivers/firmware/legacy_scpi.c
> @@ -0,0 +1,644 @@
[...]
> +
> +#define CMD_ID_SHIFT 0
> +#define CMD_ID_MASK 0x7f
> +#define CMD_SENDER_ID_SHIFT 8
> +#define CMD_SENDER_ID_MASK 0xff
Again this is something I introduced in the earlier driver. But from SCP
f/w perspective, it just sends that as is to the sender. I think we
retain token concept as is from the latest driver. Could you check
dropping them and check if f/w makes any assumption about these. It
should not IMO.
> +#define CMD_DATA_SIZE_SHIFT 20
> +#define CMD_DATA_SIZE_MASK 0x1ff
> +#define PACK_SCPI_CMD(cmd_id, sender, tx_sz) \
> + ((((cmd_id) & CMD_ID_MASK) << CMD_ID_SHIFT) | \
> + (((sender) & CMD_SENDER_ID_MASK) << CMD_SENDER_ID_SHIFT) | \
> + (((tx_sz) & CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT))
> +
> +#define CMD_SIZE(cmd) (((cmd) >> CMD_DATA_SIZE_SHIFT) & CMD_DATA_SIZE_MASK)
> +#define CMD_UNIQ_MASK (CMD_TOKEN_ID_MASK << CMD_TOKEN_ID_SHIFT | CMD_ID_MASK)
> +#define CMD_XTRACT_UNIQ(cmd) ((cmd) & CMD_UNIQ_MASK)
> +
> +#define MAX_DVFS_DOMAINS 3
> +#define MAX_DVFS_OPPS 16
> +#define DVFS_LATENCY(hdr) (le32_to_cpu(hdr) >> 16)
> +#define DVFS_OPP_COUNT(hdr) ((le32_to_cpu(hdr) >> 8) & 0xff)
> +
> +#define MAX_RX_TIMEOUT (msecs_to_jiffies(30))
> +
> +enum legacy_scpi_error_codes {
This along with many other defines are exactly same, not need to
duplicate them.
> + SCPI_SUCCESS = 0, /* Success */
> + SCPI_ERR_PARAM = 1, /* Invalid parameter(s) */
> + SCPI_ERR_ALIGN = 2, /* Invalid alignment */
> + SCPI_ERR_SIZE = 3, /* Invalid size */
> + SCPI_ERR_HANDLER = 4, /* Invalid handler/callback */
> + SCPI_ERR_ACCESS = 5, /* Invalid access/permission denied */
> + SCPI_ERR_RANGE = 6, /* Value out of range */
> + SCPI_ERR_TIMEOUT = 7, /* Timeout has occurred */
> + SCPI_ERR_NOMEM = 8, /* Invalid memory area or pointer */
> + SCPI_ERR_PWRSTATE = 9, /* Invalid power state */
> + SCPI_ERR_SUPPORT = 10, /* Not supported or disabled */
> + SCPI_ERR_DEVICE = 11, /* Device error */
> + SCPI_ERR_BUSY = 12, /* Device busy */
> + SCPI_ERR_MAX
> +};
> +
> +enum legacy_scpi_client_id {
Could be removed as mentioned above ?
> + SCPI_CL_NONE,
> + SCPI_CL_CLOCKS,
> + SCPI_CL_DVFS,
> + SCPI_CL_POWER,
> + SCPI_CL_THERMAL,
> + SCPI_CL_REMOTE,
> + SCPI_CL_LED_TIMER,
> + SCPI_MAX,
> +};
> +
> +enum legacy_scpi_std_cmd {
> + SCPI_CMD_INVALID = 0x00,
> + SCPI_CMD_SCPI_READY = 0x01,
> + SCPI_CMD_SCPI_CAPABILITIES = 0x02,
> + SCPI_CMD_EVENT = 0x03,
> + SCPI_CMD_SET_CSS_PWR_STATE = 0x04,
> + SCPI_CMD_GET_CSS_PWR_STATE = 0x05,
> + SCPI_CMD_CFG_PWR_STATE_STAT = 0x06,
> + SCPI_CMD_GET_PWR_STATE_STAT = 0x07,
> + SCPI_CMD_SYS_PWR_STATE = 0x08,
> + SCPI_CMD_L2_READY = 0x09,
> + SCPI_CMD_SET_AP_TIMER = 0x0a,
> + SCPI_CMD_CANCEL_AP_TIME = 0x0b,
> + SCPI_CMD_DVFS_CAPABILITIES = 0x0c,
> + SCPI_CMD_GET_DVFS_INFO = 0x0d,
> + SCPI_CMD_SET_DVFS = 0x0e,
> + SCPI_CMD_GET_DVFS = 0x0f,
> + SCPI_CMD_GET_DVFS_STAT = 0x10,
> + SCPI_CMD_SET_RTC = 0x11,
> + SCPI_CMD_GET_RTC = 0x12,
> + SCPI_CMD_CLOCK_CAPABILITIES = 0x13,
> + SCPI_CMD_SET_CLOCK_INDEX = 0x14,
> + SCPI_CMD_SET_CLOCK_VALUE = 0x15,
> + SCPI_CMD_GET_CLOCK_VALUE = 0x16,
> + SCPI_CMD_PSU_CAPABILITIES = 0x17,
> + SCPI_CMD_SET_PSU = 0x18,
> + SCPI_CMD_GET_PSU = 0x19,
> + SCPI_CMD_SENSOR_CAPABILITIES = 0x1a,
> + SCPI_CMD_SENSOR_INFO = 0x1b,
> + SCPI_CMD_SENSOR_VALUE = 0x1c,
> + SCPI_CMD_SENSOR_CFG_PERIODIC = 0x1d,
> + SCPI_CMD_SENSOR_CFG_BOUNDS = 0x1e,
> + SCPI_CMD_SENSOR_ASYNC_VALUE = 0x1f,
> + SCPI_CMD_COUNT
> +};
> +
> +struct legacy_scpi_xfer {
> + u32 cmd;
> + u32 status;
> + const void *tx_buf;
> + void *rx_buf;
> + unsigned int tx_len;
> + unsigned int rx_len;
> + struct completion done;
> +};
> +
> +struct legacy_scpi_chan {
> + struct mbox_client cl;
> + struct mbox_chan *chan;
> + void __iomem *tx_payload;
> + void __iomem *rx_payload;
> + spinlock_t rx_lock; /* locking for the rx pending list */
> + struct mutex xfers_lock;
> + struct legacy_scpi_xfer t;
> +};
> +
> +struct legacy_scpi_drvinfo {
> + int num_chans;
> + struct legacy_scpi_chan *channels;
> + struct scpi_dvfs_info *dvfs[MAX_DVFS_DOMAINS];
> +};
> +
Even these data structures could remain, and mended wherever needed or
an alternate can be added at worse. Complete copy paste seems
unnecessary to me.
> + legacy_scpi_info->channels = legacy_scpi_chan;
> + legacy_scpi_info->num_chans = count;
> + platform_set_drvdata(pdev, legacy_scpi_info);
> +
> + ret = devm_scpi_ops_register(dev, &legacy_scpi_ops);
Though the concept of registering scpi ops is really nice, I think we
may not require that for support this legacy scpi protocol.
In general, I see lot of code duplication, can you try not add another
file or config and introduce the legacy support into arm_scpi.c itself ?
--
Regards,
Sudeep
[toc] | [prev] | [next] | [standalone]
| From | Neil Armstrong <narmstrong@baylibre.com> |
|---|---|
| Date | 2016-06-21 12:10 +0200 |
| Subject | [RFC PATCH v2 9/9] ARM64: dts: meson-gxbb: Add SCPI with cpufreq & sensors Nodes |
| Message-ID | <rMqN5-4mp-85@gated-at.bofh.it> |
| In reply to | #1427549 |
Add the vcpu DVFS clock, the SCPU shared SRAM and the SCPI sensors nodes.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 36 +++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
index 913ba86..0f2596e 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -61,6 +61,7 @@
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0x0 0x0>;
enable-method = "psci";
+ clocks = <&scpi_dvfs 0>;
};
cpu1: cpu@1 {
@@ -68,6 +69,7 @@
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0x0 0x1>;
enable-method = "psci";
+ clocks = <&scpi_dvfs 0>;
};
cpu2: cpu@2 {
@@ -75,6 +77,7 @@
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0x0 0x2>;
enable-method = "psci";
+ clocks = <&scpi_dvfs 0>;
};
cpu3: cpu@3 {
@@ -82,6 +85,7 @@
compatible = "arm,cortex-a53", "arm,armv8";
reg = <0x0 0x3>;
enable-method = "psci";
+ clocks = <&scpi_dvfs 0>;
};
};
@@ -99,6 +103,28 @@
method = "smc";
};
+ scpi {
+ compatible = "amlogic,meson-gxbb-scpi";
+ mboxes = <&mailbox 0 &mailbox 1>;
+ shmem = <&cpu_scp_lpri &cpu_scp_hpri>;
+
+ clocks {
+ compatible = "arm,scpi-clocks";
+
+ scpi_dvfs: scpi_clocks@0 {
+ compatible = "arm,scpi-dvfs-clocks";
+ #clock-cells = <1>;
+ clock-indices = <0>;
+ clock-output-names = "vcpu";
+ };
+ };
+
+ scpi_sensors: sensors {
+ compatible = "arm,scpi-sensors";
+ #thermal-sensor-cells = <1>;
+ };
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13
@@ -131,6 +157,16 @@
#address-cells = <1>;
#size-cells = <1>;
ranges = <0 0x0 0xc8000000 0x14000>;
+
+ cpu_scp_lpri: scp-shmem@0 {
+ compatible = "amlogic,meson-gxbb-scp-shmem";
+ reg = <0x13000 0x400>;
+ };
+
+ cpu_scp_hpri: scp-shmem@200 {
+ compatible = "amlogic,meson-gxbb-scp-shmem";
+ reg = <0x13400 0x400>;
+ };
};
cbus: cbus@c1100000 {
--
2.7.0
[toc] | [prev] | [next] | [standalone]
| From | Frank Wang <frank.wang@rock-chips.com> |
|---|---|
| Date | 2016-06-22 05:10 +0200 |
| Subject | Re: [RFC PATCH v2 0/9] scpi: Add SCPI registry to handle legacy protocol |
| Message-ID | <rMGI9-6js-1@gated-at.bofh.it> |
| In reply to | #1427549 |
Hi Neil, On 2016/6/21 18:02, Neil Armstrong wrote: > This patchset aims to support the legacy SCPI firmware implementation that was > delivered as early technology preview for the JUNO platform. > > Finally a stable, maintained and public implementation for the SCPI protocol > has been upstreamed part of the JUNO support and it is the recommended way > of implementing SCP communication on ARMv8 platforms. > > The Amlogic GXBB platform is using this legacy protocol, as the RK3368 & RK3399 > platforms. Only the GXBB example is provided here, but it's unclear if other > Amlogic ARMv8 based SoCs uses this legacy procotol. > > In order to support the legacy protocol : > - Move the scpi_get_ops to a thin registry layer > - Change the arm_scpi.c to use the registry layer > - Add a separate config option to build the registry layer > - Add the legacy SCPI driver based on the new implementation > - For example, add the Amlogic GXBB MHU and SCPI DT cpufreq & sensors nodes Two comments may be not very associated with this series. First, do you have any plan to implement the APIs for extended set ID of SCPI? If these APIs do not care commands, just focus on a message transmission access, something like a library role, and extended command can define in consumers driver module, I think it can more help for other consumers like Rockchip to send/receive nonstandard command data conveniently. Can it be? Second, As far as I know, some legacy mailbox hardware which like Altera, Rockchip... need write command and data register sequentially, then it can create a interrupt, however, arm-scpi first use inner scpi_xfer structure to package the message, then data is passed to msg_submit (At mailbox.c), further into the bottom mailbox driver, but the data type is converted void*, so the mailbox driver could not extract the contents of message, if it do cast type, it may become non-general from driver view. Hence, is it possible to add a message header into scpi_xfer which for the bottom mailbox driver or dope out any other methods to solve it? BR. Frank > Initial RFC discution tread can be found at https://lkml.org/lkml/2016/5/26/111 > > Neil Armstrong (9): > mailbox: Add Amlogic Meson Message-Handling-Unit > dt-bindings: mailbox: Add Amlogic Meson MHU Bindings > ARM64: dts: meson-gxbb: Add Meson MHU Node > firmware: Add a SCPI registry to handle multiple implementations > firmware: scpi: Switch arm_scpi to use new registry > firmware: Add legacy SCPI protocol driver > dt-bindings: arm: Update arm,scpi bindings with Meson GXBB SCPI > ARM64: dts: meson-gxbb: Add SRAM node > ARM64: dts: meson-gxbb: Add SCPI with cpufreq & sensors Nodes > > Documentation/devicetree/bindings/arm/arm,scpi.txt | 8 +- > .../devicetree/bindings/mailbox/meson-mhu.txt | 33 ++ > arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 53 ++ > drivers/firmware/Kconfig | 24 + > drivers/firmware/Makefile | 2 + > drivers/firmware/arm_scpi.c | 14 +- > drivers/firmware/legacy_scpi.c | 644 +++++++++++++++++++++ > drivers/firmware/scpi.c | 94 +++ > drivers/mailbox/Makefile | 2 + > drivers/mailbox/meson_mhu.c | 199 +++++++ > include/linux/scpi_protocol.h | 15 +- > 11 files changed, 1075 insertions(+), 13 deletions(-) > create mode 100644 Documentation/devicetree/bindings/mailbox/meson-mhu.txt > create mode 100644 drivers/firmware/legacy_scpi.c > create mode 100644 drivers/firmware/scpi.c > create mode 100644 drivers/mailbox/meson_mhu.c >
[toc] | [prev] | [next] | [standalone]
| From | Neil Armstrong <narmstrong@baylibre.com> |
|---|---|
| Date | 2016-06-23 14:50 +0200 |
| Subject | Re: [RFC PATCH v2 0/9] scpi: Add SCPI registry to handle legacy protocol |
| Message-ID | <rNceZ-1AV-15@gated-at.bofh.it> |
| In reply to | #1428372 |
On 06/22/2016 04:54 AM, Frank Wang wrote: > Hi Neil, > > On 2016/6/21 18:02, Neil Armstrong wrote: >> This patchset aims to support the legacy SCPI firmware implementation that was >> delivered as early technology preview for the JUNO platform. >> >> Finally a stable, maintained and public implementation for the SCPI protocol >> has been upstreamed part of the JUNO support and it is the recommended way >> of implementing SCP communication on ARMv8 platforms. >> >> The Amlogic GXBB platform is using this legacy protocol, as the RK3368 & RK3399 >> platforms. Only the GXBB example is provided here, but it's unclear if other >> Amlogic ARMv8 based SoCs uses this legacy procotol. >> >> In order to support the legacy protocol : >> - Move the scpi_get_ops to a thin registry layer >> - Change the arm_scpi.c to use the registry layer >> - Add a separate config option to build the registry layer >> - Add the legacy SCPI driver based on the new implementation >> - For example, add the Amlogic GXBB MHU and SCPI DT cpufreq & sensors nodes > > Two comments may be not very associated with this series. > > First, do you have any plan to implement the APIs for extended set ID of SCPI? If these APIs do not care commands, just focus on a message transmission access, something like a library role, and extended command can define in consumers driver module, I think it can more help for other consumers like Rockchip to send/receive nonstandard command data conveniently. Can it be? Yes, Amlogic only have a single extended command, but supporting Rockchips extended API is necessary. I'll need to think about a convenient way to extend vendor API in a separate driver with a set or read/write functions, but keeping the compatibility with the official SCPI extension API. > Second, As far as I know, some legacy mailbox hardware which like Altera, Rockchip... need write command and data register sequentially, then it can create a interrupt, however, arm-scpi first use inner scpi_xfer structure to package the message, then data is passed to msg_submit (At mailbox.c), further into the bottom mailbox driver, but the data type is converted void*, so the mailbox driver could not extract the contents of message, if it do cast type, it may become non-general from driver view. Hence, is it possible to add a message header into scpi_xfer which for the bottom mailbox driver or dope out any other methods to solve it? Well, the message type should be considered "known" between the mailbox client and controller, but here Amlogic did copy ARM's MHU so we can simply cast the data into a uint32_t and push the word in the status register, but the interface was not designed to handle a "message", only a status. In your case, you seem to have used the message capability of the mailbox to transmit a proper message containing the command word and return length. Therefore, I must think about implementing a per-vendor transmit layer, because a generic way won't work among the different mailbox controllers. Would it be possible to actually test the next revision of the legacy SCPI implementation on your platform ? I'll try to implement it for rockchip with what I understood, but I'll need your help for the DT declaration side. Regards, Neil > BR. > Frank > >> Initial RFC discution tread can be found at https://lkml.org/lkml/2016/5/26/111 >> >> Neil Armstrong (9): >> mailbox: Add Amlogic Meson Message-Handling-Unit >> dt-bindings: mailbox: Add Amlogic Meson MHU Bindings >> ARM64: dts: meson-gxbb: Add Meson MHU Node >> firmware: Add a SCPI registry to handle multiple implementations >> firmware: scpi: Switch arm_scpi to use new registry >> firmware: Add legacy SCPI protocol driver >> dt-bindings: arm: Update arm,scpi bindings with Meson GXBB SCPI >> ARM64: dts: meson-gxbb: Add SRAM node >> ARM64: dts: meson-gxbb: Add SCPI with cpufreq & sensors Nodes >> >> Documentation/devicetree/bindings/arm/arm,scpi.txt | 8 +- >> .../devicetree/bindings/mailbox/meson-mhu.txt | 33 ++ >> arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 53 ++ >> drivers/firmware/Kconfig | 24 + >> drivers/firmware/Makefile | 2 + >> drivers/firmware/arm_scpi.c | 14 +- >> drivers/firmware/legacy_scpi.c | 644 +++++++++++++++++++++ >> drivers/firmware/scpi.c | 94 +++ >> drivers/mailbox/Makefile | 2 + >> drivers/mailbox/meson_mhu.c | 199 +++++++ >> include/linux/scpi_protocol.h | 15 +- >> 11 files changed, 1075 insertions(+), 13 deletions(-) >> create mode 100644 Documentation/devicetree/bindings/mailbox/meson-mhu.txt >> create mode 100644 drivers/firmware/legacy_scpi.c >> create mode 100644 drivers/firmware/scpi.c >> create mode 100644 drivers/mailbox/meson_mhu.c >> > >
[toc] | [prev] | [next] | [standalone]
| From | Frank Wang <frank.wang@rock-chips.com> |
|---|---|
| Date | 2016-06-24 04:40 +0200 |
| Subject | Re: [RFC PATCH v2 0/9] scpi: Add SCPI registry to handle legacy protocol |
| Message-ID | <rNpcd-29c-9@gated-at.bofh.it> |
| In reply to | #1429780 |
Hi Neil & Caesar, On 2016/6/23 20:45, Neil Armstrong wrote: > On 06/22/2016 04:54 AM, Frank Wang wrote: >> Hi Neil, >> >> On 2016/6/21 18:02, Neil Armstrong wrote: >>> This patchset aims to support the legacy SCPI firmware implementation that was >>> delivered as early technology preview for the JUNO platform. >>> >>> Finally a stable, maintained and public implementation for the SCPI protocol >>> has been upstreamed part of the JUNO support and it is the recommended way >>> of implementing SCP communication on ARMv8 platforms. >>> >>> The Amlogic GXBB platform is using this legacy protocol, as the RK3368 & RK3399 >>> platforms. Only the GXBB example is provided here, but it's unclear if other >>> Amlogic ARMv8 based SoCs uses this legacy procotol. >>> >>> In order to support the legacy protocol : >>> - Move the scpi_get_ops to a thin registry layer >>> - Change the arm_scpi.c to use the registry layer >>> - Add a separate config option to build the registry layer >>> - Add the legacy SCPI driver based on the new implementation >>> - For example, add the Amlogic GXBB MHU and SCPI DT cpufreq & sensors nodes >> Two comments may be not very associated with this series. >> >> First, do you have any plan to implement the APIs for extended set ID of SCPI? If these APIs do not care commands, just focus on a message transmission access, something like a library role, and extended command can define in consumers driver module, I think it can more help for other consumers like Rockchip to send/receive nonstandard command data conveniently. Can it be? > Yes, Amlogic only have a single extended command, but supporting Rockchips extended API is necessary. > I'll need to think about a convenient way to extend vendor API in a separate driver with a set or read/write functions, but > keeping the compatibility with the official SCPI extension API. Well, sounds great, how soon can you deliver it? >> Second, As far as I know, some legacy mailbox hardware which like Altera, Rockchip... need write command and data register sequentially, then it can create a interrupt, however, arm-scpi first use inner scpi_xfer structure to package the message, then data is passed to msg_submit (At mailbox.c), further into the bottom mailbox driver, but the data type is converted void*, so the mailbox driver could not extract the contents of message, if it do cast type, it may become non-general from driver view. Hence, is it possible to add a message header into scpi_xfer which for the bottom mailbox driver or dope out any other methods to solve it? > Well, the message type should be considered "known" between the mailbox client and controller, but here Amlogic did copy ARM's MHU so we can simply cast the data into a uint32_t and push the > word in the status register, but the interface was not designed to handle a "message", only a status. > In your case, you seem to have used the message capability of the mailbox to transmit a proper message containing the command word and return length. Yeah, you are right, Rockchip mailbox need command word and RX size to ensure data integrity in current, however RX size may be replaced from other item of xfer data. Plus, as last mail I mentioned that a interrupt can only be created via writing command register and data register (filled RX size at present) sequentially . So from controller view, knowing a proper value of data which it should know is required. > Therefore, I must think about implementing a per-vendor transmit layer, because a generic way won't work among the different mailbox controllers. > > Would it be possible to actually test the next revision of the legacy SCPI implementation on your platform ? I'll try to implement it for rockchip with what I understood, but I'll need your help for the DT declaration side. Of course, I will be glad to. @Caesar, would you like to share any other good comments? BR. Frank > Regards, > Neil >>> Initial RFC discution tread can be found at https://lkml.org/lkml/2016/5/26/111 >>> >>> Neil Armstrong (9): >>> mailbox: Add Amlogic Meson Message-Handling-Unit >>> dt-bindings: mailbox: Add Amlogic Meson MHU Bindings >>> ARM64: dts: meson-gxbb: Add Meson MHU Node >>> firmware: Add a SCPI registry to handle multiple implementations >>> firmware: scpi: Switch arm_scpi to use new registry >>> firmware: Add legacy SCPI protocol driver >>> dt-bindings: arm: Update arm,scpi bindings with Meson GXBB SCPI >>> ARM64: dts: meson-gxbb: Add SRAM node >>> ARM64: dts: meson-gxbb: Add SCPI with cpufreq & sensors Nodes >>> >>> Documentation/devicetree/bindings/arm/arm,scpi.txt | 8 +- >>> .../devicetree/bindings/mailbox/meson-mhu.txt | 33 ++ >>> arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 53 ++ >>> drivers/firmware/Kconfig | 24 + >>> drivers/firmware/Makefile | 2 + >>> drivers/firmware/arm_scpi.c | 14 +- >>> drivers/firmware/legacy_scpi.c | 644 +++++++++++++++++++++ >>> drivers/firmware/scpi.c | 94 +++ >>> drivers/mailbox/Makefile | 2 + >>> drivers/mailbox/meson_mhu.c | 199 +++++++ >>> include/linux/scpi_protocol.h | 15 +- >>> 11 files changed, 1075 insertions(+), 13 deletions(-) >>> create mode 100644 Documentation/devicetree/bindings/mailbox/meson-mhu.txt >>> create mode 100644 drivers/firmware/legacy_scpi.c >>> create mode 100644 drivers/firmware/scpi.c >>> create mode 100644 drivers/mailbox/meson_mhu.c >>> >>
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web