Message ID | 57472450.4000709@arm.com |
---|---|
State | New |
Headers | show |
On 30/05/16 09:30, Neil Armstrong wrote: > On 05/27/2016 10:17 AM, Neil Armstrong wrote: [..] > > While looking for other ARMv8 based platform, I found that the RK3368 > platform has the same SCPI implementation as Amlogic. > > They extended it with DDR, system and thermal commands. > > Look at : > https://github.com/geekboxzone/mmallow_kernel/blob/geekbox/drivers/mailbox/scpi_cmd.h > >https://github.com/geekboxzone/mmallow_kernel/blob/geekbox/drivers/mailbox/scpi_protocol.c > > So the SCPI must have a framework to allow different protocol > versions, and must allow command extension. Grouping Rockchip and > Amlogic should be done, thus needing a generic name like vendor_scpi > or with a version. > Makes sense. I understand the need to reuse and I need a bit of time to have a look at the code(both Amlogic one's you have pointed out and the Rockchip one) in detail to see what's the best way to proceed. I will have a look at this later this week and get back to you. > Sudeep, could you somehow find out which version of the protocol > AmLogic and Rockchip based their SCPI development ? > Yes I tried checking with Rockchip but didn't get a response. But my guess is that it was some preliminary unpublished version of SCPI unfortunately :( -- Regards, Sudeep
On 01/06/16 17:30, Kevin Hilman wrote: > [ + Heiko, who may know about the Rockchip implementation ] > > Sudeep Holla <sudeep.holla@arm.com> writes: > >> On 30/05/16 09:30, Neil Armstrong wrote: >>> On 05/27/2016 10:17 AM, Neil Armstrong wrote: >> >> [..] >> >>> >>> While looking for other ARMv8 based platform, I found that the RK3368 >>> platform has the same SCPI implementation as Amlogic. >>> >>> They extended it with DDR, system and thermal commands. >>> >>> Look at : >>> https://github.com/geekboxzone/mmallow_kernel/blob/geekbox/drivers/mailbox/scpi_cmd.h >>> >>> https://github.com/geekboxzone/mmallow_kernel/blob/geekbox/drivers/mailbox/scpi_protocol.c >>> >> >> >>> So the SCPI must have a framework to allow different protocol >>> versions, and must allow command extension. Grouping Rockchip and >>> Amlogic should be done, thus needing a generic name like vendor_scpi >>> or with a version. >>> >> >> Makes sense. I understand the need to reuse and I need a bit of time to >> have a look at the code(both Amlogic one's you have pointed out and the >> Rockchip one) in detail to see what's the best way to proceed. I will >> have a look at this later this week and get back to you. >> >>> Sudeep, could you somehow find out which version of the protocol >>> AmLogic and Rockchip based their SCPI development ? >>> >> >> Yes I tried checking with Rockchip but didn't get a response. But my >> guess is that it was some preliminary unpublished version of SCPI >> unfortunately :( > > And if one partner did that, probably everyone else did as well, but > this being the ARM universe, they all did it slightly differently. :( > No doubt :) > We know from experience, that this happens all the time in the absence > of a clear standard, so this framework will need to be extended to be > useful. > Completely agreed, better to gather all the information possible before we proceed. I will try to check if I can get hold of old version internally in the meantime. -- Regards, Sudeep
On 30/05/16 09:30, Neil Armstrong wrote: > On 05/27/2016 10:17 AM, Neil Armstrong wrote: > > While looking for other ARMv8 based platform, I found that the RK3368 > platform has the same SCPI implementation as Amlogic. > > They extended it with DDR, system and thermal commands. > > Look at : > https://github.com/geekboxzone/mmallow_kernel/blob/geekbox/drivers/mailbox/scpi_cmd.h > >https://github.com/geekboxzone/mmallow_kernel/blob/geekbox/driver/mailbox/scpi_protocol.c > > So the SCPI must have a framework to allow different protocol > versions, and must allow command extension. Grouping Rockchip and > Amlogic should be done, thus needing a generic name like vendor_scpi > or with a version. > > Sudeep, could you somehow find out which version of the protocol > AmLogic and Rockchip based their SCPI development ? > > As Caesar Wang replied, they had a previous version of SCPI and I suggested on how to extend the command set previously in private. Not sure whats the progress on that Anyways I had a look at geekbox driver and it looks mostly based on the initial driver I wrote for initial SCPI versions. I am worried that your extension might help people to develop their own protocol instead of following the existing standards. SCPI is published now, so I vendors use that rather than making up their own. Also ARM is trying to standardize something in this area like PSCI, but that may take little more time as it's under discussion with vendors. Though this initial version of SCPI is not published, I am sure it is almost same as v1.0 except that the CMD is not part of payload like v1.0. In v1.0 it's part of payload and the mailbox is used just for doorbell mechanism. IMO, we can add some compatible to indicate the pre v1.0 protocol and add the support to the existing driver itself. Let me know your thoughts. -- Regards, Sudeep
diff --git i/drivers/firmware/arm_scpi.c w/drivers/firmware/arm_scpi.c index 7e3e595c9f30..7e46aa103690 100644 --- i/drivers/firmware/arm_scpi.c +++ w/drivers/firmware/arm_scpi.c @@ -46,6 +46,8 @@ #define CMD_ID_SHIFT 0 #define CMD_ID_MASK 0x7f +#define CMD_SET_SHIFT 7 +#define CMD_SET_MASK 0x1 #define CMD_TOKEN_ID_SHIFT 8 #define CMD_TOKEN_ID_MASK 0xff #define CMD_DATA_SIZE_SHIFT 16 @@ -53,6 +55,10 @@ #define PACK_SCPI_CMD(cmd_id, tx_sz) \ ((((cmd_id) & CMD_ID_MASK) << CMD_ID_SHIFT) | \ (((tx_sz) & CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT)) +#define PACK_EXT_SCPI_CMD(cmd_id, tx_sz) \ + ((((cmd_id) & CMD_ID_MASK) << CMD_ID_SHIFT) | \ + (CMD_SET_MASK << CMD_SET_SHIFT) | \ + (((tx_sz) & CMD_DATA_SIZE_MASK) << CMD_DATA_SIZE_SHIFT)) #define ADD_SCPI_TOKEN(cmd, token) \ ((cmd) |= (((token) & CMD_TOKEN_ID_MASK) << CMD_TOKEN_ID_SHIFT)) @@ -132,6 +138,9 @@ enum scpi_std_cmd { SCPI_CMD_COUNT }; +enum scpi_vendor_ext_cmd { +}; + struct scpi_xfer { u32 slot; /* has to be first element */ u32 cmd; @@ -165,6 +174,7 @@ struct scpi_drvinfo { struct scpi_ops *scpi_ops; struct scpi_chan *channels; struct scpi_dvfs_info *dvfs[MAX_DVFS_DOMAINS]; + void *scpi_ext_ops; }; /* @@ -343,8 +353,8 @@ static void put_scpi_xfer(struct scpi_xfer *t, struct scpi_chan *ch) mutex_unlock(&ch->xfers_lock); } -static int scpi_send_message(u8 cmd, void *tx_buf, unsigned int tx_len, - void *rx_buf, unsigned int rx_len) +static int __scpi_send_message(u8 cmd, void *tx_buf, unsigned int tx_len, + void *rx_buf, unsigned int rx_len, bool extn) { int ret; u8 chan; @@ -359,7 +369,8 @@ static int scpi_send_message(u8 cmd, void *tx_buf, unsigned int tx_len, return -ENOMEM; msg->slot = BIT(SCPI_SLOT); - msg->cmd = PACK_SCPI_CMD(cmd, tx_len); + msg->cmd = extn ? PACK_EXT_SCPI_CMD(cmd, tx_len) : + PACK_SCPI_CMD(cmd, tx_len); msg->tx_buf = tx_buf; msg->tx_len = tx_len; msg->rx_buf = rx_buf; @@ -384,6 +395,18 @@ static int scpi_send_message(u8 cmd, void *tx_buf, unsigned int tx_len, return ret > 0 ? scpi_to_linux_errno(ret) : ret; } +static int scpi_send_message(u8 cmd, void *tx_buf, unsigned int tx_len, + void *rx_buf, unsigned int rx_len) +{ + return __scpi_send_message(cmd, tx_buf, tx_len, rx_buf, rx_len, false); +} + +static int scpi_send_ext_message(u8 cmd, void *tx_buf, unsigned int tx_len, + void *rx_buf, unsigned int rx_len) +{ + return __scpi_send_message(cmd, tx_buf, tx_len, rx_buf, rx_len, true); +} + static u32 scpi_get_version(void) { return scpi_info->protocol_version; @@ -574,6 +597,29 @@ static int scpi_init_versions(struct scpi_drvinfo *info) return ret; } +static struct scpi_vendor_ext_ops scpi_vendor_ext_ops = { +}; + +void *get_scpi_ext_ops(void) +{ + return scpi_info ? scpi_info->scpi_ext_ops : NULL; +} +EXPORT_SYMBOL_GPL(get_scpi_ext_ops); + +static const struct of_device_id scpi_extentions_of_match[] = { + {.compatible = "vendor,scpi", .data = &scpi_vendor_ext_ops}, + {}, +}; + +static void +scpi_init_extensions(struct scpi_drvinfo *info, struct device_node *np) +{ + const struct of_device_id *of_id; + + if (np && (of_id = of_match_node(scpi_extentions_of_match, np))) + info->scpi_ext_ops = (void *)of_id->data; +} + static ssize_t protocol_version_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -745,6 +791,8 @@ static int scpi_probe(struct platform_device *pdev) FW_REV_PATCH(scpi_info->firmware_version)); scpi_info->scpi_ops = &scpi_ops; + scpi_init_extensions(scpi_info, np); + ret = sysfs_create_groups(&dev->kobj, versions_groups); if (ret) dev_err(dev, "unable to create sysfs version group\n"); diff --git i/include/linux/scpi_protocol.h w/include/linux/scpi_protocol.h index 35de50a65665..052f6aa1ae4b 100644 --- i/include/linux/scpi_protocol.h +++ w/include/linux/scpi_protocol.h @@ -72,8 +72,13 @@ struct scpi_ops { int (*sensor_get_value)(u16, u64 *); }; +struct scpi_vendor_ext_ops { +}; + #if IS_REACHABLE(CONFIG_ARM_SCPI_PROTOCOL) struct scpi_ops *get_scpi_ops(void); +void *get_scpi_ext_ops(void); #else static inline struct scpi_ops *get_scpi_ops(void) { return NULL; } +static inline void *get_scpi_ext_ops(void) { return NULL; } #endif