From: Neil Armstrong <hidden> Date: 2016-08-18 10:11:25
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.
This patchset add support for the legacy protocol in the arm_scpi.c file,
avoiding code duplication.
Last RFC discution tread can be found at : https://lkml.org/lkml/2016/8/9/210
The first patch is here to provide vendor commands on the official SCPI protocol,
it can be delayed to another patchset.
Patches 8 & 9 are only here to demo how Rockchip support could be implemented, these
patches should be delayed to a rockchip specific patchset.
The last patch depends on the "Platform MHU" dtsi patch.
Neil Armstrong (13):
scpi: Add vendor_send_message to enable access to vendor commands
scpi: Add alternative legacy structures and macros
scpi: Add legacy send, prepare and handle remote functions
scpi: Add legacy SCP functions calling legacy_scpi_send_message
scpi: move of_match table before probe functions
scpi: add priv_scpi_ops and fill legacy structure
scpi: ignore init_versions failure if reported not supported
scpi: add a vendor_msg mechanism in case the mailbox message differs
scpi: implement rockchip support via the vendor_msg mechanism
scpi: grow MAX_DVFS_OPPS to 16 entries
dt-bindings: Add support for Amlogic GXBB SCPI Interface
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 +-
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 45 ++
drivers/firmware/arm_scpi.c | 455 ++++++++++++++++++++-
include/linux/scpi_protocol.h | 4 +
4 files changed, 490 insertions(+), 22 deletions(-)
--
1.9.1
From: Neil Armstrong <hidden> Date: 2016-08-18 10:11:27
In order to support the legacy SCPI procotol, add specific message_send,
prepare_tx and handle_remote functions since the legacy procotol
do not support message queuing and does not store the command word in the
tx_payload data.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 69 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
@@ -202,6 +202,7 @@ struct scpi_chan {spinlock_trx_lock;/* locking for the rx pending list */structmutexxfers_lock;u8token;+structscpi_xfer*t;};structscpi_drvinfo{
@@ -434,6 +461,48 @@ static void put_scpi_xfer(struct scpi_xfer *t, struct scpi_chan *ch)mutex_unlock(&ch->xfers_lock);}+staticintlegacy_scpi_send_message(u8cmd,void*tx_buf,unsignedinttx_len,+void*rx_buf,unsignedintrx_len)+{+intret;+u8chan;+structscpi_xfer*msg;+structscpi_chan*scpi_chan;++chan=legacy_scpi_get_chan(cmd);+scpi_chan=scpi_info->channels+chan;++msg=get_scpi_xfer(scpi_chan);+if(!msg)+return-ENOMEM;++mutex_lock(&scpi_chan->xfers_lock);++msg->cmd=PACK_LEGACY_SCPI_CMD(cmd,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);+scpi_chan->t=msg;++ret=mbox_send_message(scpi_chan->chan,&msg->cmd);+if(ret<0)+gotoout;++if(!wait_for_completion_timeout(&msg->done,MAX_RX_TIMEOUT))+ret=-ETIMEDOUT;+else+/* first status word */+ret=msg->status;+out:+mutex_unlock(&scpi_chan->xfers_lock);++put_scpi_xfer(msg,scpi_chan);+/* SCPI error codes > 0, translate them to Linux scale*/+returnret>0?scpi_to_linux_errno(ret):ret;+}+staticint__scpi_send_message(u8cmd,void*tx_buf,unsignedinttx_len,void*rx_buf,unsignedintrx_len,boolextn){
In order to support the legacy SCPI procotol, add specific message_send,
prepare_tx and handle_remote functions since the legacy procotol
do not support message queuing and does not store the command word in the
tx_payload data.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 69 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
@@ -202,6 +202,7 @@ struct scpi_chan {spinlock_trx_lock;/* locking for the rx pending list */structmutexxfers_lock;u8token;+structscpi_xfer*t;};structscpi_drvinfo{
I see that you are not using the list. Any particular reason for that ?
IMO, that *might* help to reuse more code, but I may be wrong. Let's see
Some commands like DVFS take more time compared to simple query type of
commands. Queuing does help there instead of blocking the channel until
the receipt of response.
quoted hunk
+}
+
static int legacy_high_priority_cmds[] = {
LEGACY_SCPI_CMD_GET_CSS_PWR_STATE,
LEGACY_SCPI_CMD_CFG_PWR_STATE_STAT,
If slot is initialized to cmd, then you can pass msg itself above.
Then you can evaluate how much this function deviates from
scpi_send_message and try to re-use.
+ 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:
+ mutex_unlock(&scpi_chan->xfers_lock);
+
+ put_scpi_xfer(msg, scpi_chan);
+ /* SCPI error codes > 0, translate them to Linux scale*/
+ 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, bool extn)
{
[Nit]: Not sure if we need this as a separate patch. It might just
generate warnings, anyways we can merge into one later.
--
Regards,
Sudeep
From: Neil Armstrong <hidden> Date: 2016-08-23 08:20:53
On 08/19/2016 06:13 PM, Sudeep Holla wrote:
On 18/08/16 11:10, Neil Armstrong wrote:
quoted
In order to support the legacy SCPI procotol, add specific message_send,
prepare_tx and handle_remote functions since the legacy procotol
do not support message queuing and does not store the command word in the
tx_payload data.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 69 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
@@ -202,6 +202,7 @@ struct scpi_chan {spinlock_trx_lock;/* locking for the rx pending list */structmutexxfers_lock;u8token;+structscpi_xfer*t;};structscpi_drvinfo{
I see that you are not using the list. Any particular reason for that ?
IMO, that *might* help to reuse more code, but I may be wrong. Let's see
Some commands like DVFS take more time compared to simple query type of
commands. Queuing does help there instead of blocking the channel until
the receipt of response.
I'll like to use the list, but, the "cmd" value is not stored in the shared tx
memory, so we cannot recover the original tranfer from reading the tx memory cmd.
This is why I added a "struct scpi_xfer *t;" in the scpi_chan structure to store
the current transfer.
quoted
+}
+
static int legacy_high_priority_cmds[] = {
LEGACY_SCPI_CMD_GET_CSS_PWR_STATE,
LEGACY_SCPI_CMD_CFG_PWR_STATE_STAT,
May be you can copy msg->cmd to msg->slot and that may help to reuse
more code or worst-case keep them aligned.
Yes, it could be. But since the msg is not reused bu the tx_prepare and handle_response,
we can pass anything here.
And for the rockchip case, we must pass an xfer unrelated pointer here since they need
a specially crafted memory structure for the mailbox.
If slot is initialized to cmd, then you can pass msg itself above.
Then you can evaluate how much this function deviates from
scpi_send_message and try to re-use.
The function deviates quite a lot since the queing is not used.
quoted
+ 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:
+ mutex_unlock(&scpi_chan->xfers_lock);
+
+ put_scpi_xfer(msg, scpi_chan);
+ /* SCPI error codes > 0, translate them to Linux scale*/
+ 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, bool extn)
{
[Nit]: Not sure if we need this as a separate patch. It might just
generate warnings, anyways we can merge into one later.
I'll prefer to have functionnaly separate patches for now to clarify the changes.
I'll eventually merge them for the final apply if needed.
Thanks,
Neil
In order to support the legacy SCPI procotol, add specific message_send,
prepare_tx and handle_remote functions since the legacy procotol
do not support message queuing and does not store the command word in the
tx_payload data.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 69 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 69 insertions(+)
I see that you are not using the list. Any particular reason for that ?
IMO, that *might* help to reuse more code, but I may be wrong. Let's see
Some commands like DVFS take more time compared to simple query type of
commands. Queuing does help there instead of blocking the channel until
the receipt of response.
I'll like to use the list, but, the "cmd" value is not stored in the shared tx
memory, so we cannot recover the original tranfer from reading the tx memory cmd.
Even in the current driver we read the mem->command and search the list
in scpi_process_cmd. Instead *(u32 *)msg gives the command value, no ?
This is why I added a "struct scpi_xfer *t;" in the scpi_chan structure to store
the current transfer.
I don't like that. I am trying to get rid of that.
1. list is not being used
2. scpi_xfer is stashed even though we have only one command in
progress at any time in your case.
quoted
quoted
+}
+
static int legacy_high_priority_cmds[] = {
LEGACY_SCPI_CMD_GET_CSS_PWR_STATE,
LEGACY_SCPI_CMD_CFG_PWR_STATE_STAT,
If slot is initialized to cmd, then you can pass msg itself above.
Then you can evaluate how much this function deviates from
scpi_send_message and try to re-use.
The function deviates quite a lot since the queing is not used.
You have not given me the reason for not using the list yet.
If the msg ptr is used in scpi_handle_remote_msg, you should be able to
make use of it.
quoted
quoted
+ 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:
+ mutex_unlock(&scpi_chan->xfers_lock);
+
+ put_scpi_xfer(msg, scpi_chan);
+ /* SCPI error codes > 0, translate them to Linux scale*/
+ 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, bool extn)
{
[Nit]: Not sure if we need this as a separate patch. It might just
generate warnings, anyways we can merge into one later.
I'll prefer to have functionnaly separate patches for now to clarify the changes.
I'll eventually merge them for the final apply if needed.
From: Neil Armstrong <hidden> Date: 2016-08-18 10:11:33
In order to use the legacy functions variants, add a new priv_scpi_ops
structure that will contain the internal alterne functions and then use these
alternate call in the probe function.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 68 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 64 insertions(+), 4 deletions(-)
@@ -986,11 +1026,18 @@ static int scpi_probe(struct platform_device *pdev)structscpi_chan*scpi_chan;structdevice*dev=&pdev->dev;structdevice_node*np=dev->of_node;+conststructof_device_id*match;++match=of_match_device(scpi_of_match,&pdev->dev);+if(!match)+return-EINVAL;scpi_info=devm_kzalloc(dev,sizeof(*scpi_info),GFP_KERNEL);if(!scpi_info)return-ENOMEM;+scpi_info->ops=match->data;+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);
@@ -1023,7 +1070,13 @@ static int scpi_probe(struct platform_device *pdev)pchan->tx_payload=pchan->rx_payload+(size>>1);cl->dev=dev;-cl->rx_callback=scpi_handle_remote_msg;+if(scpi_info->ops&&scpi_info->ops->handle_remote_msg)+cl->rx_callback=scpi_info->ops->handle_remote_msg;+else+cl->rx_callback=scpi_handle_remote_msg;+if(scpi_info->ops&&scpi_info->ops->tx_prepare)+cl->tx_prepare=scpi_info->ops->tx_prepare;+elsecl->tx_prepare=scpi_tx_prepare;cl->tx_block=true;cl->tx_tout=20;
@@ -1054,6 +1107,9 @@ err:scpi_info->num_chans=count;platform_set_drvdata(pdev,scpi_info);+if(scpi_info->ops&&scpi_info->ops->init_versions)+ret=scpi_info->ops->init_versions(scpi_info);+elseret=scpi_init_versions(scpi_info);if(ret){dev_err(dev,"incorrect or no SCP firmware found\n");
In order to use the legacy functions variants, add a new priv_scpi_ops
structure that will contain the internal alterne functions and then use these
alternate call in the probe function.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 68 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 64 insertions(+), 4 deletions(-)
From: Neil Armstrong <hidden> Date: 2016-08-23 08:22:32
On 08/19/2016 06:39 PM, Sudeep Holla wrote:
On 18/08/16 11:10, Neil Armstrong wrote:
quoted
In order to use the legacy functions variants, add a new priv_scpi_ops
structure that will contain the internal alterne functions and then use these
alternate call in the probe function.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 68 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 64 insertions(+), 4 deletions(-)
I think we need not have this at all if you follow the suggestion I had
in the previous patch. Try and let's see how it would look.
If you confirm you want the if/else as said in patch 4.
But clk_get_range, device_get/set_power_state are not available in legacy,
I think we should still have this alternate structure.
In order to use the legacy functions variants, add a new priv_scpi_ops
structure that will contain the internal alterne functions and then use these
alternate call in the probe function.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 68 ++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 64 insertions(+), 4 deletions(-)
I think we need not have this at all if you follow the suggestion I had
in the previous patch. Try and let's see how it would look.
If you confirm you want the if/else as said in patch 4.
But clk_get_range, device_get/set_power_state are not available in legacy,
I think we should still have this alternate structure.
I was thinking of overriding the pointers accordingly at the probe time
as the common list is bigger than the one that differs.
--
Regards,
Sudeep
@@ -7,7 +7,7 @@ by Linux to initiate various system control and power operations. Required properties:-- compatible : should be "arm,scpi"+- compatible : should be "arm,scpi" or "amlogic,meson-gxbb-scpi" - mboxes: List of phandle and mailbox channel specifiers All the channels reserved by remote SCP firmware for use by SCPI message protocol should be specified in any order
@@ -60,7 +60,8 @@ A small area of SRAM is reserved for SCPI communication between application processors and SCP. Required properties:-- compatible : should be "arm,juno-sram-ns" for Non-secure SRAM on Juno+- compatible : should be "arm,juno-sram-ns" for Non-secure SRAM on Juno,+ or "amlogic,meson-gxbb-sram" for Amlogic GXBB SoC. The rest of the properties should follow the generic mmio-sram description found in ../../sram/sram.txt
@@ -70,7 +71,8 @@ Each sub-node represents the reserved area for SCPI. Required sub-node properties: - reg : The base offset and size of the reserved area with the SRAM - compatible : should be "arm,juno-scp-shmem" for Non-secure SRAM based- shared memory on Juno platforms+ shared memory on Juno platforms or+ "amlogic,meson-gxbb-scp-shmem" for Amlogic GXBB SoC. Sensor bindings for the sensors based on SCPI Message Protocol --------------------------------------------------------------
From: Neil Armstrong <hidden> Date: 2016-08-18 10:12:19
Since Amlogic SoCs reports more than 8 OPPs per domains, grow the structure
size to 16.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
From: Neil Armstrong <hidden> Date: 2016-08-18 10:12:36
In order to support the Rockchip legacy procotol, implement the vendor
mailbox specific functions and add ops to the of_match table.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 43 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 43 insertions(+)
@@ -455,6 +455,37 @@ static int legacy_scpi_get_chan(u8 cmd)return0;}+/* Rockchip SoCs needs a special structure as a message */++structrockchip_scpi_xfer{+u32cmd;+intrx_size;+};++staticintrockchip_init(structdevice*dev,structscpi_chan*chan)+{+chan->vendor_data=devm_kmalloc(dev,+sizeof(structrockchip_scpi_xfer),+GFP_KERNEL);+if(!chan->vendor_data)+return-ENOMEM;++return0;+}++staticintrockchip_prepare(structscpi_chan*chan)+{+structscpi_xfer*msg=chan->t;+structrockchip_scpi_xfer*xfer=chan->vendor_data;++xfer->cmd=msg->cmd;+xfer->rx_size=msg->rx_len;++msg->vendor_msg=xfer;++return0;+}+staticstructscpi_xfer*get_scpi_xfer(structscpi_chan*ch){structscpi_xfer*t;
From: Neil Armstrong <hidden> Date: 2016-08-18 10:12:37
In case the mailbox message pointer must contain a specific structure.
add a mechanism to override the pointer sent to the mailbox by a
vendor specific data initialized by a vendor speficic function.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
@@ -302,6 +304,8 @@ struct dev_pstate_set {structpriv_scpi_ops{/* Internal Specific Ops */+int(*init)(structdevice*dev,structscpi_chan*chan);+int(*prepare)(structscpi_chan*chan);void(*handle_remote_msg)(structmbox_client*c,void*msg);void(*tx_prepare)(structmbox_client*c,void*msg);/* Message Specific Ops */
@@ -498,7 +502,18 @@ static int legacy_scpi_send_message(u8 cmd, void *tx_buf, unsigned int tx_len,init_completion(&msg->done);scpi_chan->t=msg;-ret=mbox_send_message(scpi_chan->chan,&msg->cmd);+/* Call the prepare hook to eventually set the vendor_msg */+if(scpi_info->ops&&+scpi_info->ops->prepare){+ret=scpi_info->ops->prepare(scpi_chan);+if(ret){+mutex_unlock(&scpi_chan->xfers_lock);+returnret;+}+}else+msg->vendor_msg=&msg->cmd;++ret=mbox_send_message(scpi_chan->chan,msg->vendor_msg);if(ret<0)gotoout;
@@ -1069,6 +1084,12 @@ static int scpi_probe(struct platform_device *pdev)}pchan->tx_payload=pchan->rx_payload+(size>>1);+if(scpi_info->ops&&scpi_info->ops->init){+ret=scpi_info->ops->init(dev,pchan);+if(ret)+gotoerr;+}+cl->dev=dev;if(scpi_info->ops&&scpi_info->ops->handle_remote_msg)cl->rx_callback=scpi_info->ops->handle_remote_msg;
In case the mailbox message pointer must contain a specific structure.
add a mechanism to override the pointer sent to the mailbox by a
vendor specific data initialized by a vendor speficic function.
As discussed, I won't look at this and next patch. You can drop from now.
--
Regards,
Sudeep
From: Neil Armstrong <hidden> Date: 2016-08-18 10:13:02
In Amlogic GXBB Legacy SCPI, the LEGACY_SCPI_CMD_SCPI_CAPABILITIES report
as SCPI_ERR_SUPPORT, so do not fail if this command is not supported.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
@@ -1111,12 +1111,13 @@ err:ret=scpi_info->ops->init_versions(scpi_info);elseret=scpi_init_versions(scpi_info);-if(ret){+if(ret&&ret!=-EOPNOTSUPP){dev_err(dev,"incorrect or no SCP firmware found\n");scpi_remove(pdev);returnret;}+if(ret!=-EOPNOTSUPP){_dev_info(dev,"SCP Protocol %d.%d Firmware %d.%d.%d version\n",PROTOCOL_REV_MAJOR(scpi_info->protocol_version),PROTOCOL_REV_MINOR(scpi_info->protocol_version),
@@ -1124,15 +1125,16 @@ err:FW_REV_MINOR(scpi_info->firmware_version),FW_REV_PATCH(scpi_info->firmware_version));+ret=sysfs_create_groups(&dev->kobj,versions_groups);+if(ret)+dev_err(dev,"unable to create sysfs version group\n");+}+if(scpi_info->ops&&scpi_info->ops->scpi_ops)scpi_info->scpi_ops=scpi_info->ops->scpi_ops;elsescpi_info->scpi_ops=&scpi_ops;-ret=sysfs_create_groups(&dev->kobj,versions_groups);-if(ret)-dev_err(dev,"unable to create sysfs version group\n");-returnof_platform_populate(dev->of_node,NULL,NULL,dev);}
In Amlogic GXBB Legacy SCPI, the LEGACY_SCPI_CMD_SCPI_CAPABILITIES report
as SCPI_ERR_SUPPORT, so do not fail if this command is not supported.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
@@ -1111,12 +1111,13 @@ err:ret=scpi_info->ops->init_versions(scpi_info);elseret=scpi_init_versions(scpi_info);-if(ret){+if(ret&&ret!=-EOPNOTSUPP){dev_err(dev,"incorrect or no SCP firmware found\n");scpi_remove(pdev);returnret;}
Why not have default value like 0.0 ? Just add a comment. Since get
version is exported out, IMO having default value makes more sense. What
do you think ?
quoted hunk
@@ -1124,15 +1125,16 @@ err: FW_REV_MINOR(scpi_info->firmware_version), FW_REV_PATCH(scpi_info->firmware_version));+ ret = sysfs_create_groups(&dev->kobj, versions_groups);+ if (ret)+ dev_err(dev, "unable to create sysfs version group\n");+ }+
Again this can stay as is if we have default.
--
Regards,
Sudeep
From: Neil Armstrong <hidden> Date: 2016-08-23 08:23:45
On 08/19/2016 06:46 PM, Sudeep Holla wrote:
On 18/08/16 11:11, Neil Armstrong wrote:
quoted
In Amlogic GXBB Legacy SCPI, the LEGACY_SCPI_CMD_SCPI_CAPABILITIES report
as SCPI_ERR_SUPPORT, so do not fail if this command is not supported.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
@@ -1111,12 +1111,13 @@ err:ret=scpi_info->ops->init_versions(scpi_info);elseret=scpi_init_versions(scpi_info);-if(ret){+if(ret&&ret!=-EOPNOTSUPP){dev_err(dev,"incorrect or no SCP firmware found\n");scpi_remove(pdev);returnret;}
Why not have default value like 0.0 ? Just add a comment. Since get
version is exported out, IMO having default value makes more sense. What
do you think ?
quoted
@@ -1124,15 +1125,16 @@ err: FW_REV_MINOR(scpi_info->firmware_version), FW_REV_PATCH(scpi_info->firmware_version));+ ret = sysfs_create_groups(&dev->kobj, versions_groups);+ if (ret)+ dev_err(dev, "unable to create sysfs version group\n");+ }+
Again this can stay as is if we have default.
Printing version 0.0 firmware 0.0.0 is a nonsense for me...
Neil
In Amlogic GXBB Legacy SCPI, the LEGACY_SCPI_CMD_SCPI_CAPABILITIES report
as SCPI_ERR_SUPPORT, so do not fail if this command is not supported.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
@@ -1111,12 +1111,13 @@ err:ret=scpi_info->ops->init_versions(scpi_info);elseret=scpi_init_versions(scpi_info);-if(ret){+if(ret&&ret!=-EOPNOTSUPP){dev_err(dev,"incorrect or no SCP firmware found\n");scpi_remove(pdev);returnret;}
Why not have default value like 0.0 ? Just add a comment. Since get
version is exported out, IMO having default value makes more sense. What
do you think ?
quoted
@@ -1124,15 +1125,16 @@ err: FW_REV_MINOR(scpi_info->firmware_version), FW_REV_PATCH(scpi_info->firmware_version));+ ret = sysfs_create_groups(&dev->kobj, versions_groups);+ if (ret)+ dev_err(dev, "unable to create sysfs version group\n");+ }+
Again this can stay as is if we have default.
Printing version 0.0 firmware 0.0.0 is a nonsense for me...
OK 0.0 was a wrong example. May be 0.1 ?
Since the driver has already exposed, hypothetically user-space can use
that information, so IMO, we need to expose some static version for pre-v1.0
I am surprised that capability is not supported as this was present even
in that legacy SCPI. Do you know what happens if you send that command ?
Have you done some experiments on that ?
--
Regards,
Sudeep
From: Neil Armstrong <hidden> Date: 2016-08-23 15:03:55
On 08/23/2016 04:54 PM, Sudeep Holla wrote:
On 23/08/16 09:23, Neil Armstrong wrote:
quoted
On 08/19/2016 06:46 PM, Sudeep Holla wrote:
quoted
On 18/08/16 11:11, Neil Armstrong wrote:
quoted
In Amlogic GXBB Legacy SCPI, the LEGACY_SCPI_CMD_SCPI_CAPABILITIES report
as SCPI_ERR_SUPPORT, so do not fail if this command is not supported.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
@@ -1111,12 +1111,13 @@ err:ret=scpi_info->ops->init_versions(scpi_info);elseret=scpi_init_versions(scpi_info);-if(ret){+if(ret&&ret!=-EOPNOTSUPP){dev_err(dev,"incorrect or no SCP firmware found\n");scpi_remove(pdev);returnret;}
Why not have default value like 0.0 ? Just add a comment. Since get
version is exported out, IMO having default value makes more sense. What
do you think ?
quoted
@@ -1124,15 +1125,16 @@ err: FW_REV_MINOR(scpi_info->firmware_version), FW_REV_PATCH(scpi_info->firmware_version));+ ret = sysfs_create_groups(&dev->kobj, versions_groups);+ if (ret)+ dev_err(dev, "unable to create sysfs version group\n");+ }+
Again this can stay as is if we have default.
Printing version 0.0 firmware 0.0.0 is a nonsense for me...
OK 0.0 was a wrong example. May be 0.1 ?
Since the driver has already exposed, hypothetically user-space can use
that information, so IMO, we need to expose some static version for pre-v1.0
I am surprised that capability is not supported as this was present even
in that legacy SCPI. Do you know what happens if you send that command ?
Have you done some experiments on that ?
I've experimented and returns EOPNOTSUPP, Amlogic confirmed to us the command was not implemented.
This a clearly a corner-case.
Neil
In Amlogic GXBB Legacy SCPI, the LEGACY_SCPI_CMD_SCPI_CAPABILITIES report
as SCPI_ERR_SUPPORT, so do not fail if this command is not supported.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
@@ -1111,12 +1111,13 @@ err:ret=scpi_info->ops->init_versions(scpi_info);elseret=scpi_init_versions(scpi_info);-if(ret){+if(ret&&ret!=-EOPNOTSUPP){dev_err(dev,"incorrect or no SCP firmware found\n");scpi_remove(pdev);returnret;}
Why not have default value like 0.0 ? Just add a comment. Since get
version is exported out, IMO having default value makes more sense. What
do you think ?
quoted
@@ -1124,15 +1125,16 @@ err: FW_REV_MINOR(scpi_info->firmware_version), FW_REV_PATCH(scpi_info->firmware_version));+ ret = sysfs_create_groups(&dev->kobj, versions_groups);+ if (ret)+ dev_err(dev, "unable to create sysfs version group\n");+ }+
Again this can stay as is if we have default.
Printing version 0.0 firmware 0.0.0 is a nonsense for me...
OK 0.0 was a wrong example. May be 0.1 ?
Since the driver has already exposed, hypothetically user-space can use
that information, so IMO, we need to expose some static version for pre-v1.0
I am surprised that capability is not supported as this was present even
in that legacy SCPI. Do you know what happens if you send that command ?
Have you done some experiments on that ?
I've experimented and returns EOPNOTSUPP, Amlogic confirmed to us the command was not implemented.
This a clearly a corner-case.
OK, thanks for the confirmation.
Not exporting anything could be kind of breaking ABI as it was not made
optional when introduced :( (you can blame me ;))
--
Regards,
Sudeep
From: Neil Armstrong <hidden> Date: 2016-08-18 10:13:16
Move the of_match table to prapre adding new compatible strings, with
match data in order to be used by the probe function.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
From: Neil Armstrong <hidden> Date: 2016-08-18 10:13:35
In order to support legacy SCP functions from kernel-wide driver, add legacy
functions using the legacy command enums and calling legacy_scpi_send_message.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 118 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 118 insertions(+)
@@ -578,6 +578,8 @@ scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max)returnret;}+/* scpi_clk_get_range not available for legacy */+staticunsignedlongscpi_clk_get_val(u16clk_id){intret;
@@ -589,6 +591,18 @@ static unsigned long scpi_clk_get_val(u16 clk_id)returnret?ret:le32_to_cpu(clk.rate);}+staticunsignedlonglegacy_scpi_clk_get_val(u16clk_id)+{+intret;+structclk_get_valueclk;+__le16le_clk_id=cpu_to_le16(clk_id);++ret=legacy_scpi_send_message(LEGACY_SCPI_CMD_GET_CLOCK_VALUE,+&le_clk_id,sizeof(le_clk_id),+&clk,sizeof(clk));+returnret?ret:le32_to_cpu(clk.rate);+}+staticintscpi_clk_set_val(u16clk_id,unsignedlongrate){intstat;
@@ -601,6 +615,19 @@ static int scpi_clk_set_val(u16 clk_id, unsigned long rate)&stat,sizeof(stat));}+staticintlegacy_scpi_clk_set_val(u16clk_id,unsignedlongrate)+{+intstat;+structlegacy_clk_set_valueclk={+.id=cpu_to_le16(clk_id),+.rate=cpu_to_le32(rate)+};++returnlegacy_scpi_send_message(LEGACY_SCPI_CMD_SET_CLOCK_VALUE,+&clk,sizeof(clk),+&stat,sizeof(stat));+}+staticintscpi_dvfs_get_idx(u8domain){intret;
@@ -611,6 +638,17 @@ static int scpi_dvfs_get_idx(u8 domain)returnret?ret:dvfs_idx;}+staticintlegacy_scpi_dvfs_get_idx(u8domain)+{+intret;+u8dvfs_idx;++ret=legacy_scpi_send_message(LEGACY_SCPI_CMD_GET_DVFS,+&domain,sizeof(domain),+&dvfs_idx,sizeof(dvfs_idx));+returnret?ret:dvfs_idx;+}+staticintscpi_dvfs_set_idx(u8domain,u8index){intstat;
@@ -620,6 +658,16 @@ static int scpi_dvfs_set_idx(u8 domain, u8 index)&stat,sizeof(stat));}+staticintlegacy_scpi_dvfs_set_idx(u8domain,u8index)+{+intstat;+structdvfs_setdvfs={domain,index};++returnlegacy_scpi_send_message(LEGACY_SCPI_CMD_SET_DVFS,+&dvfs,sizeof(dvfs),+&stat,sizeof(stat));+}+staticintopp_cmp_func(constvoid*opp1,constvoid*opp2){conststructscpi_opp*t1=opp1,*t2=opp2;
In order to support legacy SCP functions from kernel-wide driver, add legacy
functions using the legacy command enums and calling legacy_scpi_send_message.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 118 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 118 insertions(+)
@@ -578,6 +578,8 @@ scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max)returnret;}+/* scpi_clk_get_range not available for legacy */+staticunsignedlongscpi_clk_get_val(u16clk_id){intret;
@@ -589,6 +591,18 @@ static unsigned long scpi_clk_get_val(u16 clk_id)returnret?ret:le32_to_cpu(clk.rate);}+staticunsignedlonglegacy_scpi_clk_get_val(u16clk_id)+{+intret;+structclk_get_valueclk;+__le16le_clk_id=cpu_to_le16(clk_id);++ret=legacy_scpi_send_message(LEGACY_SCPI_CMD_GET_CLOCK_VALUE,+&le_clk_id,sizeof(le_clk_id),+&clk,sizeof(clk));+returnret?ret:le32_to_cpu(clk.rate);+}+staticintscpi_clk_set_val(u16clk_id,unsignedlongrate){intstat;
@@ -601,6 +615,19 @@ static int scpi_clk_set_val(u16 clk_id, unsigned long rate)&stat,sizeof(stat));}+staticintlegacy_scpi_clk_set_val(u16clk_id,unsignedlongrate)+{+intstat;+structlegacy_clk_set_valueclk={+.id=cpu_to_le16(clk_id),+.rate=cpu_to_le32(rate)+};++returnlegacy_scpi_send_message(LEGACY_SCPI_CMD_SET_CLOCK_VALUE,+&clk,sizeof(clk),+&stat,sizeof(stat));
Except this one which has a different structure format, why do we need
to define legacy versions of other functions ? Can't we play with
function pointer or have a boolean in drvinfo structure and use then in
the existing functions as I had shown in one of the earlier emails.
--
Regards,
Sudeep
From: Neil Armstrong <hidden> Date: 2016-08-23 08:19:51
On 08/19/2016 06:22 PM, Sudeep Holla wrote:
On 18/08/16 11:10, Neil Armstrong wrote:
quoted
In order to support legacy SCP functions from kernel-wide driver, add legacy
functions using the legacy command enums and calling legacy_scpi_send_message.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 118 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 118 insertions(+)
@@ -578,6 +578,8 @@ scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max)returnret;}+/* scpi_clk_get_range not available for legacy */+staticunsignedlongscpi_clk_get_val(u16clk_id){intret;
@@ -589,6 +591,18 @@ static unsigned long scpi_clk_get_val(u16 clk_id)returnret?ret:le32_to_cpu(clk.rate);}+staticunsignedlonglegacy_scpi_clk_get_val(u16clk_id)+{+intret;+structclk_get_valueclk;+__le16le_clk_id=cpu_to_le16(clk_id);++ret=legacy_scpi_send_message(LEGACY_SCPI_CMD_GET_CLOCK_VALUE,+&le_clk_id,sizeof(le_clk_id),+&clk,sizeof(clk));+returnret?ret:le32_to_cpu(clk.rate);+}+staticintscpi_clk_set_val(u16clk_id,unsignedlongrate){intstat;
@@ -601,6 +615,19 @@ static int scpi_clk_set_val(u16 clk_id, unsigned long rate)&stat,sizeof(stat));}+staticintlegacy_scpi_clk_set_val(u16clk_id,unsignedlongrate)+{+intstat;+structlegacy_clk_set_valueclk={+.id=cpu_to_le16(clk_id),+.rate=cpu_to_le32(rate)+};++returnlegacy_scpi_send_message(LEGACY_SCPI_CMD_SET_CLOCK_VALUE,+&clk,sizeof(clk),+&stat,sizeof(stat));
Except this one which has a different structure format, why do we need
to define legacy versions of other functions ? Can't we play with
function pointer or have a boolean in drvinfo structure and use then in
the existing functions as I had shown in one of the earlier emails.
The main problem is that the command indexes deviates starting at
SCPI_CMD_SET_CSS_PWR_STATE, I'll be pleased to know how to implement it.
Should I add a test :
if (scpi_drvinfo->is_legacy)
legacy_scpi_send_message(...)
else
scpi_send_message(...)
In each function ?
My strategy was to leave the "final" function untouched ans provide
alternatives to legacy.
I can add this "is_legacy" if/else instead of ops structures.
Please tell me how you'll implement this, so I'll adapt the merge.
Neil
In order to support legacy SCP functions from kernel-wide driver, add legacy
functions using the legacy command enums and calling legacy_scpi_send_message.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 118 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 118 insertions(+)
@@ -578,6 +578,8 @@ scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max)returnret;}+/* scpi_clk_get_range not available for legacy */+staticunsignedlongscpi_clk_get_val(u16clk_id){intret;
@@ -589,6 +591,18 @@ static unsigned long scpi_clk_get_val(u16 clk_id)returnret?ret:le32_to_cpu(clk.rate);}+staticunsignedlonglegacy_scpi_clk_get_val(u16clk_id)+{+intret;+structclk_get_valueclk;+__le16le_clk_id=cpu_to_le16(clk_id);++ret=legacy_scpi_send_message(LEGACY_SCPI_CMD_GET_CLOCK_VALUE,+&le_clk_id,sizeof(le_clk_id),+&clk,sizeof(clk));+returnret?ret:le32_to_cpu(clk.rate);+}+staticintscpi_clk_set_val(u16clk_id,unsignedlongrate){intstat;
@@ -601,6 +615,19 @@ static int scpi_clk_set_val(u16 clk_id, unsigned long rate)&stat,sizeof(stat));}+staticintlegacy_scpi_clk_set_val(u16clk_id,unsignedlongrate)+{+intstat;+structlegacy_clk_set_valueclk={+.id=cpu_to_le16(clk_id),+.rate=cpu_to_le32(rate)+};++returnlegacy_scpi_send_message(LEGACY_SCPI_CMD_SET_CLOCK_VALUE,+&clk,sizeof(clk),+&stat,sizeof(stat));
Except this one which has a different structure format, why do we need
to define legacy versions of other functions ? Can't we play with
function pointer or have a boolean in drvinfo structure and use then in
the existing functions as I had shown in one of the earlier emails.
The main problem is that the command indexes deviates starting at
SCPI_CMD_SET_CSS_PWR_STATE, I'll be pleased to know how to implement it.
Yes, I was thinking of some kind of mapping to new index using an array.
--
Regards,
Sudeep
From: Neil Armstrong <hidden> Date: 2016-08-18 10:13:49
In order to support the legacy SCPI protocol variant, add back the structures
and macros that varies against the final specification.
Signed-off-by: Neil Armstrong <redacted>
---
I checked against Amlogic implementation documentation and on-device, the channel selection
via legacy_scpi_get_chan() is needed and fails without it.
The sender_id is not needed so it was dropped.
drivers/firmware/arm_scpi.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
@@ -138,6 +143,42 @@ enum scpi_std_cmd {SCPI_CMD_COUNT};+enumlegacy_scpi_std_cmd{+LEGACY_SCPI_CMD_INVALID=0x00,+LEGACY_SCPI_CMD_SCPI_READY=0x01,+LEGACY_SCPI_CMD_SCPI_CAPABILITIES=0x02,+LEGACY_SCPI_CMD_EVENT=0x03,+LEGACY_SCPI_CMD_SET_CSS_PWR_STATE=0x04,+LEGACY_SCPI_CMD_GET_CSS_PWR_STATE=0x05,+LEGACY_SCPI_CMD_CFG_PWR_STATE_STAT=0x06,+LEGACY_SCPI_CMD_GET_PWR_STATE_STAT=0x07,+LEGACY_SCPI_CMD_SYS_PWR_STATE=0x08,+LEGACY_SCPI_CMD_L2_READY=0x09,+LEGACY_SCPI_CMD_SET_AP_TIMER=0x0a,+LEGACY_SCPI_CMD_CANCEL_AP_TIME=0x0b,+LEGACY_SCPI_CMD_DVFS_CAPABILITIES=0x0c,+LEGACY_SCPI_CMD_GET_DVFS_INFO=0x0d,+LEGACY_SCPI_CMD_SET_DVFS=0x0e,+LEGACY_SCPI_CMD_GET_DVFS=0x0f,+LEGACY_SCPI_CMD_GET_DVFS_STAT=0x10,+LEGACY_SCPI_CMD_SET_RTC=0x11,+LEGACY_SCPI_CMD_GET_RTC=0x12,+LEGACY_SCPI_CMD_CLOCK_CAPABILITIES=0x13,+LEGACY_SCPI_CMD_SET_CLOCK_INDEX=0x14,+LEGACY_SCPI_CMD_SET_CLOCK_VALUE=0x15,+LEGACY_SCPI_CMD_GET_CLOCK_VALUE=0x16,+LEGACY_SCPI_CMD_PSU_CAPABILITIES=0x17,+LEGACY_SCPI_CMD_SET_PSU=0x18,+LEGACY_SCPI_CMD_GET_PSU=0x19,+LEGACY_SCPI_CMD_SENSOR_CAPABILITIES=0x1a,+LEGACY_SCPI_CMD_SENSOR_INFO=0x1b,+LEGACY_SCPI_CMD_SENSOR_VALUE=0x1c,+LEGACY_SCPI_CMD_SENSOR_CFG_PERIODIC=0x1d,+LEGACY_SCPI_CMD_SENSOR_CFG_BOUNDS=0x1e,+LEGACY_SCPI_CMD_SENSOR_ASYNC_VALUE=0x1f,+LEGACY_SCPI_CMD_COUNT+};+structscpi_xfer{u32slot;/* has to be first element */u32cmd;
In order to support the legacy SCPI protocol variant, add back the structures
and macros that varies against the final specification.
Signed-off-by: Neil Armstrong <redacted>
---
I checked against Amlogic implementation documentation and on-device, the channel selection
via legacy_scpi_get_chan() is needed and fails without it.
The sender_id is not needed so it was dropped.
drivers/firmware/arm_scpi.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
From: Neil Armstrong <hidden> Date: 2016-08-23 08:36:05
On 08/18/2016 07:16 PM, Sudeep Holla wrote:
On 18/08/16 11:10, Neil Armstrong wrote:
quoted
In order to support the legacy SCPI protocol variant, add back the structures
and macros that varies against the final specification.
Signed-off-by: Neil Armstrong <redacted>
---
I checked against Amlogic implementation documentation and on-device, the channel selection
via legacy_scpi_get_chan() is needed and fails without it.
The sender_id is not needed so it was dropped.
drivers/firmware/arm_scpi.c | 84 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
From: Neil Armstrong <hidden> Date: 2016-08-18 10:14:10
Adds an optional vendor_send_message to the scpi to enable sending
vendor platform specific commands to the SCP firmware.
Signed-off-by: Neil Armstrong <redacted>
---
drivers/firmware/arm_scpi.c | 26 +++++++++++++++++++++++---
include/linux/scpi_protocol.h | 4 ++++
2 files changed, 27 insertions(+), 3 deletions(-)
Adds an optional vendor_send_message to the scpi to enable sending
vendor platform specific commands to the SCP firmware.
I don't see any users of vendor_send_message in this series, so I prefer
it to be dropped and introduced when required.
Also I had a different view on how to introduce this[1]. I would rather
wait until the requirement comes that enables us to make use of it.
Looks like you took parts of it and introduces vendor_send_message
allowing users to send any data which I don't like especially without
knowing how will it be (ab)used.
--
Regards,
Sudeep
[1] http://www.spinics.net/lists/kernel/msg2263649.html
From: Neil Armstrong <hidden> Date: 2016-08-19 08:00:51
On 08/18/2016 05:53 PM, Sudeep Holla wrote:
On 18/08/16 11:10, Neil Armstrong wrote:
quoted
Adds an optional vendor_send_message to the scpi to enable sending
vendor platform specific commands to the SCP firmware.
I don't see any users of vendor_send_message in this series, so I prefer
it to be dropped and introduced when required.
Also I had a different view on how to introduce this[1]. I would rather
wait until the requirement comes that enables us to make use of it.
Looks like you took parts of it and introduces vendor_send_message
allowing users to send any data which I don't like especially without
knowing how will it be (ab)used.
Hi Sudeep,
Indeed, I won't ask you to merge patches 1, 8 and 9, they need refactoring and
a separate patchset.
Vendor commands are not necessary for Amlogic, this is a nice to have since they
have a "user" command that can be extended by a firmware loaded by u-boot.
Could you review the following patches and I'll post a reduced v2 ASAP.
Thanks,
Neil
Adds an optional vendor_send_message to the scpi to enable sending
vendor platform specific commands to the SCP firmware.
I don't see any users of vendor_send_message in this series, so I prefer
it to be dropped and introduced when required.
Also I had a different view on how to introduce this[1]. I would rather
wait until the requirement comes that enables us to make use of it.
Looks like you took parts of it and introduces vendor_send_message
allowing users to send any data which I don't like especially without
knowing how will it be (ab)used.
Hi Sudeep,
Indeed, I won't ask you to merge patches 1, 8 and 9, they need refactoring and
a separate patchset.
Ah OK,then better if you put then at the end. Otherwise it makes it
difficult to review.
Vendor commands are not necessary for Amlogic, this is a nice to have
since they have a "user" command that can be extended by a firmware
loaded by u-boot.
Good :)
Could you review the following patches and I'll post a reduced v2
ASAP.
Yes I was doing that yesterday, sorry got distracted. I will continue today.
--
Regards,
Sudeep