diff mbox

[v3,1/7] firmware: rockchip: sip: Add rockchip SIP runtime service

Message ID 1469178440-4668-2-git-send-email-hl@rock-chips.com
State New
Headers show

Commit Message

huang lin July 22, 2016, 9:07 a.m. UTC
From: Shengfei xu <xsf@rock-chips.com>

This patch adds support for the SiP interface, we can pass dram
paramtert to bl31, and control ddr frequency scaling in bl31.

Signed-off-by: Shengfei xu <xsf@rock-chips.com>
Signed-off-by: Lin Huang <hl@rock-chips.com>
---
Changes in v3:
- None

Changes in v2:
- None

Changes in v1:
- None

 drivers/firmware/Kconfig        |  7 +++++
 drivers/firmware/Makefile       |  1 +
 drivers/firmware/rockchip_sip.c | 64 +++++++++++++++++++++++++++++++++++++++++
 drivers/firmware/rockchip_sip.h | 59 +++++++++++++++++++++++++++++++++++++
 4 files changed, 131 insertions(+)
 create mode 100644 drivers/firmware/rockchip_sip.c
 create mode 100644 drivers/firmware/rockchip_sip.h

Comments

Heiko Stübner July 22, 2016, 10 a.m. UTC | #1
Hi,

Am Freitag, 22. Juli 2016, 17:07:14 schrieb Lin Huang:
> From: Shengfei xu <xsf@rock-chips.com>
> 
> This patch adds support for the SiP interface, we can pass dram
> paramtert to bl31, and control ddr frequency scaling in bl31.
> 
> Signed-off-by: Shengfei xu <xsf@rock-chips.com>
> Signed-off-by: Lin Huang <hl@rock-chips.com>

[...]

> +++ b/drivers/firmware/rockchip_sip.c
> @@ -0,0 +1,64 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that 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.
> + *
> + * Copyright (C) 2016 ARM Limited
> + */
> +#include <linux/errno.h>
> +#include <linux/linkage.h>
> +#include <linux/of.h>
> +#include <linux/pm.h>
> +#include <linux/printk.h>
> +#include "rockchip_sip.h"
> +
> +typedef unsigned long (psci_fn)(unsigned long, unsigned long,
> +				unsigned long, unsigned long);
> +asmlinkage psci_fn __invoke_psci_fn_smc;
> +
> +#define CONFIG_DRAM_INIT	0x00
> +#define CONFIG_DRAM_SET_RATE	0x01
> +#define CONFIG_DRAM_ROUND_RATE	0x02
> +#define CONFIG_DRAM_SET_AT_SR	0x03
> +#define CONFIG_DRAM_GET_BW	0x04
> +#define CONFIG_DRAM_GET_RATE	0x05
> +#define CONFIG_DRAM_CLR_IRQ	0x06
> +#define CONFIG_DRAM_SET_PARAM   0x07
> +
> +uint64_t sip_smc_ddr_init(void)

if I'm reading the ATF writers guide [0] correctly, the SiP calls are soc-
specific things:
"For example, two SoC providers can use the same Function ID within the SiP
Service calls OEN range to mean different things - as these calls should be
specific to the SoC. "

So I guess the function calls, as well as the constants should have a prefix.
ROCKCHIP_SIP_DDR_FREQ, rockchip_sip_smc_set_ddr_param(), etc.

Looking at Zynq in the ATF [1] seems to strengthen that theory with the 
similar constants having the ZYNQMP_ prefix.

I guess it doesn't matter to much on the ATF side, as you build a soc-specific 
image, but on the kernel-side I think it should unambiguos, especially as 
functions and constants are part of a public header.

I think the code itself looks fine though :-)


Heiko

[0] https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/rt-svc-writers-guide.md
[1] https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/xilinx/zynqmp/sip_svc_setup.c



> +{
> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0,
> +				    0, CONFIG_DRAM_INIT);
> +}
> +
> +uint64_t sip_smc_set_ddr_param(uint64_t param)
> +{
> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, param,
> +				    0, CONFIG_DRAM_SET_PARAM);
> +}
> +
> +uint64_t sip_smc_set_ddr_rate(uint64_t rate)
> +{
> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, rate, 0,
> +				    CONFIG_DRAM_SET_RATE);
> +}
> +
> +uint64_t sip_smc_get_ddr_rate(void)
> +{
> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0, 0, CONFIG_DRAM_GET_RATE);
> +}
> +
> +uint64_t sip_smc_clr_ddr_irq(void)
> +{
> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0, 0, CONFIG_DRAM_CLR_IRQ);
> +}
> +
> +uint64_t sip_smc_get_call_count(void)
> +{
> +	return __invoke_psci_fn_smc(SIP_SVC_CALL_COUNT, 0, 0, 0);
> +}
> diff --git a/drivers/firmware/rockchip_sip.h
> b/drivers/firmware/rockchip_sip.h new file mode 100644
> index 0000000..6487734
> --- /dev/null
> +++ b/drivers/firmware/rockchip_sip.h
> @@ -0,0 +1,59 @@
> +/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 and
> + * only version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that 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.
> + */
> +#ifndef __SIP_INT_H
> +#define __SIP_INT_H
> +
> +/* SMC function IDs for SiP Service queries */
> +#define SIP_SVC_CALL_COUNT		0x8200ff00
> +#define SIP_SVC_UID			0x8200ff01
> +#define SIP_SVC_VERSION			0x8200ff03
> +#define SIP_DDR_FREQ			0xC2000008
> +
> +#if IS_ENABLED(CONFIG_ROCKCHIP_SIP)
> +uint64_t sip_smc_set_ddr_rate(uint64_t rate);
> +uint64_t sip_smc_get_ddr_rate(void);
> +uint64_t sip_smc_clr_ddr_irq(void);
> +uint64_t sip_smc_get_call_count(void);
> +uint64_t sip_smc_ddr_init(void);
> +uint64_t sip_smc_set_ddr_param(uint64_t param);
> +#else
> +static inline uint64_t sip_smc_set_ddr_rate(uint64_t rate)
> +{
> +	return 0;
> +}
> +
> +static inline uint64_t sip_smc_get_ddr_rate(void)
> +{
> +	return 0;
> +}
> +
> +static inline uint64_t sip_smc_clr_ddr_irq(void)
> +{
> +	return 0;
> +}
> +
> +static inline uint64_t sip_smc_get_call_count(void)
> +{
> +	return 0;
> +}
> +
> +static inline uint64_t sip_smc_ddr_init(void)
> +{
> +	return 0;
> +}
> +
> +static inline uint64_t sip_smc_set_ddr_param(uint64_t param)
> +{
> +	return 0;
> +}
> +#endif
> +#endif
Heiko Stübner July 22, 2016, 8:50 p.m. UTC | #2
Hi again,

one bigger thing I noticed only now.

Am Freitag, 22. Juli 2016, 17:07:14 schrieben Sie:
> diff --git a/drivers/firmware/rockchip_sip.c
> b/drivers/firmware/rockchip_sip.c new file mode 100644
> index 0000000..7756af9
> --- /dev/null
> +++ b/drivers/firmware/rockchip_sip.c
> @@ -0,0 +1,64 @@
> +/*
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that 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.
> + *
> + * Copyright (C) 2016 ARM Limited
> + */
> +#include <linux/errno.h>
> +#include <linux/linkage.h>
> +#include <linux/of.h>
> +#include <linux/pm.h>
> +#include <linux/printk.h>
> +#include "rockchip_sip.h"
> +
> +typedef unsigned long (psci_fn)(unsigned long, unsigned long,
> +				unsigned long, unsigned long);
> +asmlinkage psci_fn __invoke_psci_fn_smc;
> +
> +#define CONFIG_DRAM_INIT	0x00
> +#define CONFIG_DRAM_SET_RATE	0x01
> +#define CONFIG_DRAM_ROUND_RATE	0x02
> +#define CONFIG_DRAM_SET_AT_SR	0x03
> +#define CONFIG_DRAM_GET_BW	0x04
> +#define CONFIG_DRAM_GET_RATE	0x05
> +#define CONFIG_DRAM_CLR_IRQ	0x06
> +#define CONFIG_DRAM_SET_PARAM   0x07
> +
> +uint64_t sip_smc_ddr_init(void)
> +{
> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0,
> +				    0, CONFIG_DRAM_INIT);

I don't think that is legal to use. For one this function itself is declared 
static in the psci code - most likely for a specific reason.

And also if anything invoke_psci_fn would hold the correct pointer depending 
on the calling method.

But as said above, accessing psci static stuff is most likely wrong. Maybe the 
two psci people I've included can tell us how this is to be accessed.


Heiko

> +}
> +
> +uint64_t sip_smc_set_ddr_param(uint64_t param)
> +{
> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, param,
> +				    0, CONFIG_DRAM_SET_PARAM);
> +}
> +
> +uint64_t sip_smc_set_ddr_rate(uint64_t rate)
> +{
> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, rate, 0,
> +				    CONFIG_DRAM_SET_RATE);
> +}
> +
> +uint64_t sip_smc_get_ddr_rate(void)
> +{
> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0, 0, CONFIG_DRAM_GET_RATE);
> +}
> +
> +uint64_t sip_smc_clr_ddr_irq(void)
> +{
> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0, 0, CONFIG_DRAM_CLR_IRQ);
> +}
> +
> +uint64_t sip_smc_get_call_count(void)
> +{
> +	return __invoke_psci_fn_smc(SIP_SVC_CALL_COUNT, 0, 0, 0);
> +}
kernel test robot July 22, 2016, 9:32 p.m. UTC | #3
Hi,

[auto build test ERROR on next-20160722]
[also build test ERROR on v4.7-rc7]
[cannot apply to rockchip/for-next stable/master linux/master v4.7-rc7 v4.7-rc6 v4.7-rc5]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Lin-Huang/rk3399-support-ddr-frequency-scaling/20160722-173343
config: arm64-allmodconfig (attached as .config)
compiler: aarch64-linux-gnu-gcc (Debian 5.4.0-6) 5.4.0 20160609
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=arm64 

All errors (new ones prefixed by >>):

   drivers/built-in.o: In function `sip_smc_ddr_init':
>> binder.c:(.text+0x279074): undefined reference to `__invoke_psci_fn_smc'
   drivers/built-in.o: In function `sip_smc_set_ddr_param':
   binder.c:(.text+0x2790ac): undefined reference to `__invoke_psci_fn_smc'
   drivers/built-in.o: In function `sip_smc_set_ddr_rate':
   binder.c:(.text+0x2790ec): undefined reference to `__invoke_psci_fn_smc'
   drivers/built-in.o: In function `sip_smc_get_ddr_rate':
   binder.c:(.text+0x279124): undefined reference to `__invoke_psci_fn_smc'
   drivers/built-in.o: In function `sip_smc_clr_ddr_irq':
   binder.c:(.text+0x279154): undefined reference to `__invoke_psci_fn_smc'
   drivers/built-in.o:binder.c:(.text+0x279184): more undefined references to `__invoke_psci_fn_smc' follow

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
huang lin July 24, 2016, 8 a.m. UTC | #4
Hi Heiko,

On 2016年07月23日 04:50, Heiko Stübner wrote:
> Hi again,
>
> one bigger thing I noticed only now.
>
> Am Freitag, 22. Juli 2016, 17:07:14 schrieben Sie:
>> diff --git a/drivers/firmware/rockchip_sip.c
>> b/drivers/firmware/rockchip_sip.c new file mode 100644
>> index 0000000..7756af9
>> --- /dev/null
>> +++ b/drivers/firmware/rockchip_sip.c
>> @@ -0,0 +1,64 @@
>> +/*
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that 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.
>> + *
>> + * Copyright (C) 2016 ARM Limited
>> + */
>> +#include <linux/errno.h>
>> +#include <linux/linkage.h>
>> +#include <linux/of.h>
>> +#include <linux/pm.h>
>> +#include <linux/printk.h>
>> +#include "rockchip_sip.h"
>> +
>> +typedef unsigned long (psci_fn)(unsigned long, unsigned long,
>> +				unsigned long, unsigned long);
>> +asmlinkage psci_fn __invoke_psci_fn_smc;
>> +
>> +#define CONFIG_DRAM_INIT	0x00
>> +#define CONFIG_DRAM_SET_RATE	0x01
>> +#define CONFIG_DRAM_ROUND_RATE	0x02
>> +#define CONFIG_DRAM_SET_AT_SR	0x03
>> +#define CONFIG_DRAM_GET_BW	0x04
>> +#define CONFIG_DRAM_GET_RATE	0x05
>> +#define CONFIG_DRAM_CLR_IRQ	0x06
>> +#define CONFIG_DRAM_SET_PARAM   0x07
>> +
>> +uint64_t sip_smc_ddr_init(void)
>> +{
>> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0,
>> +				    0, CONFIG_DRAM_INIT);
> I don't think that is legal to use. For one this function itself is declared
> static in the psci code - most likely for a specific reason.
>
> And also if anything invoke_psci_fn would hold the correct pointer depending
> on the calling method.
>
> But as said above, accessing psci static stuff is most likely wrong. Maybe the
> two psci people I've included can tell us how this is to be accessed.
>
   Thanks Heiko. Hope Sudeep Holla and Lorenzo Pieralisi can give me advice.
> Heiko
>
>> +}
>> +
>> +uint64_t sip_smc_set_ddr_param(uint64_t param)
>> +{
>> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, param,
>> +				    0, CONFIG_DRAM_SET_PARAM);
>> +}
>> +
>> +uint64_t sip_smc_set_ddr_rate(uint64_t rate)
>> +{
>> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, rate, 0,
>> +				    CONFIG_DRAM_SET_RATE);
>> +}
>> +
>> +uint64_t sip_smc_get_ddr_rate(void)
>> +{
>> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0, 0, CONFIG_DRAM_GET_RATE);
>> +}
>> +
>> +uint64_t sip_smc_clr_ddr_irq(void)
>> +{
>> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0, 0, CONFIG_DRAM_CLR_IRQ);
>> +}
>> +
>> +uint64_t sip_smc_get_call_count(void)
>> +{
>> +	return __invoke_psci_fn_smc(SIP_SVC_CALL_COUNT, 0, 0, 0);
>> +}
>
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
>
>
>
Sudeep Holla July 25, 2016, 5:36 p.m. UTC | #5
On 22/07/16 21:50, Heiko Stübner wrote:
> Hi again,
>
> one bigger thing I noticed only now.
>
> Am Freitag, 22. Juli 2016, 17:07:14 schrieben Sie:
>> diff --git a/drivers/firmware/rockchip_sip.c
>> b/drivers/firmware/rockchip_sip.c new file mode 100644
>> index 0000000..7756af9
>> --- /dev/null
>> +++ b/drivers/firmware/rockchip_sip.c
>> @@ -0,0 +1,64 @@
>> +/*
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that 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.
>> + *
>> + * Copyright (C) 2016 ARM Limited
>> + */
>> +#include <linux/errno.h>
>> +#include <linux/linkage.h>
>> +#include <linux/of.h>
>> +#include <linux/pm.h>
>> +#include <linux/printk.h>
>> +#include "rockchip_sip.h"
>> +
>> +typedef unsigned long (psci_fn)(unsigned long, unsigned long,
>> +				unsigned long, unsigned long);
>> +asmlinkage psci_fn __invoke_psci_fn_smc;
>> +
>> +#define CONFIG_DRAM_INIT	0x00
>> +#define CONFIG_DRAM_SET_RATE	0x01
>> +#define CONFIG_DRAM_ROUND_RATE	0x02
>> +#define CONFIG_DRAM_SET_AT_SR	0x03
>> +#define CONFIG_DRAM_GET_BW	0x04
>> +#define CONFIG_DRAM_GET_RATE	0x05
>> +#define CONFIG_DRAM_CLR_IRQ	0x06
>> +#define CONFIG_DRAM_SET_PARAM   0x07
>> +
>> +uint64_t sip_smc_ddr_init(void)
>> +{
>> +	return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0,
>> +				    0, CONFIG_DRAM_INIT);
>
> I don't think that is legal to use. For one this function itself is declared
> static in the psci code - most likely for a specific reason.
>
> And also if anything invoke_psci_fn would hold the correct pointer depending
> on the calling method.
>
> But as said above, accessing psci static stuff is most likely wrong. Maybe the
> two psci people I've included can tell us how this is to be accessed.
>

Thanks Heiko for looping us in this thread.

The feature being added in this series is completely out of scope of
PSCI specification and hence PSCI can't be used. Firstly we need to
audit if these are need in Linux and why they can't be handled within
the existing PSCI APIs. But yes, this series is misuse of PSCI.

I also see to know that ARM Trusted Firmware community has not accepted
this PSCI approach, so this patches are useless without that.

If they are still needed they need to make use of SMC Calling Convention
(arm_smccc_smc). Either make these smc function identifiers standard on
their platforms and use them directly in the driver. If they tend to
change too much across their platforms, use the DT approach with
appropriate bindings.
huang lin July 26, 2016, 1:13 a.m. UTC | #6
Hi Sudeep Holla,

On 2016年07月26日 01:36, Sudeep Holla wrote:
>
>
> On 22/07/16 21:50, Heiko Stübner wrote:
>> Hi again,
>>
>> one bigger thing I noticed only now.
>>
>> Am Freitag, 22. Juli 2016, 17:07:14 schrieben Sie:
>>> diff --git a/drivers/firmware/rockchip_sip.c
>>> b/drivers/firmware/rockchip_sip.c new file mode 100644
>>> index 0000000..7756af9
>>> --- /dev/null
>>> +++ b/drivers/firmware/rockchip_sip.c
>>> @@ -0,0 +1,64 @@
>>> +/*
>>> + * This program is free software; you can redistribute it and/or 
>>> modify
>>> + * it under the terms of the GNU General Public License version 2 as
>>> + * published by the Free Software Foundation.
>>> + *
>>> + * This program is distributed in the hope that 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.
>>> + *
>>> + * Copyright (C) 2016 ARM Limited
>>> + */
>>> +#include <linux/errno.h>
>>> +#include <linux/linkage.h>
>>> +#include <linux/of.h>
>>> +#include <linux/pm.h>
>>> +#include <linux/printk.h>
>>> +#include "rockchip_sip.h"
>>> +
>>> +typedef unsigned long (psci_fn)(unsigned long, unsigned long,
>>> +                unsigned long, unsigned long);
>>> +asmlinkage psci_fn __invoke_psci_fn_smc;
>>> +
>>> +#define CONFIG_DRAM_INIT    0x00
>>> +#define CONFIG_DRAM_SET_RATE    0x01
>>> +#define CONFIG_DRAM_ROUND_RATE    0x02
>>> +#define CONFIG_DRAM_SET_AT_SR    0x03
>>> +#define CONFIG_DRAM_GET_BW    0x04
>>> +#define CONFIG_DRAM_GET_RATE    0x05
>>> +#define CONFIG_DRAM_CLR_IRQ    0x06
>>> +#define CONFIG_DRAM_SET_PARAM   0x07
>>> +
>>> +uint64_t sip_smc_ddr_init(void)
>>> +{
>>> +    return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0,
>>> +                    0, CONFIG_DRAM_INIT);
>>
>> I don't think that is legal to use. For one this function itself is 
>> declared
>> static in the psci code - most likely for a specific reason.
>>
>> And also if anything invoke_psci_fn would hold the correct pointer 
>> depending
>> on the calling method.
>>
>> But as said above, accessing psci static stuff is most likely wrong. 
>> Maybe the
>> two psci people I've included can tell us how this is to be accessed.
>>
>
> Thanks Heiko for looping us in this thread.
>
> The feature being added in this series is completely out of scope of
> PSCI specification and hence PSCI can't be used. Firstly we need to
> audit if these are need in Linux and why they can't be handled within
> the existing PSCI APIs. But yes, this series is misuse of PSCI.
>
> I also see to know that ARM Trusted Firmware community has not accepted
> this PSCI approach, so this patches are useless without that.
>
> If they are still needed they need to make use of SMC Calling Convention
> (arm_smccc_smc). Either make these smc function identifiers standard on
> their platforms and use them directly in the driver. If they tend to
> change too much across their platforms, use the DT approach with
> appropriate bindings.
Thanks for your suggestion, i will update the code in next version.
Mark Rutland July 26, 2016, 6:29 p.m. UTC | #7
On Fri, Jul 22, 2016 at 05:07:14PM +0800, Lin Huang wrote:
> +config ROCKCHIP_SIP
> +	bool "Rockchip SIP interface"
> +	depends on ARM64 && ARM_PSCI_FW
> +	help
> +	  Say Y here if you want to enable SIP callbacks for Rockchip platforms
> +	  This option enables support for communicating with the ATF.

[...]

> +typedef unsigned long (psci_fn)(unsigned long, unsigned long,
> +				unsigned long, unsigned long);
> +asmlinkage psci_fn __invoke_psci_fn_smc;

Use the SMCCC wrappers (see include/linux/arm-smccc.h).

This is *not* PSCI, even if the same ATF FW provides both services.

NAK for using the PSCI functions.

Thanks,
Mark.
diff mbox

Patch

diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 0e22f24..6f585c5 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -206,6 +206,13 @@  config QCOM_SCM_64
 config HAVE_ARM_SMCCC
 	bool
 
+config ROCKCHIP_SIP
+	bool "Rockchip SIP interface"
+	depends on ARM64 && ARM_PSCI_FW
+	help
+	  Say Y here if you want to enable SIP callbacks for Rockchip platforms
+	  This option enables support for communicating with the ATF.
+
 source "drivers/firmware/broadcom/Kconfig"
 source "drivers/firmware/google/Kconfig"
 source "drivers/firmware/efi/Kconfig"
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 44a59dc..e9eab5b 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -25,3 +25,4 @@  obj-y				+= broadcom/
 obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
 obj-$(CONFIG_EFI)		+= efi/
 obj-$(CONFIG_UEFI_CPER)		+= efi/
+obj-$(CONFIG_ROCKCHIP_SIP)	+= rockchip_sip.o
diff --git a/drivers/firmware/rockchip_sip.c b/drivers/firmware/rockchip_sip.c
new file mode 100644
index 0000000..7756af9
--- /dev/null
+++ b/drivers/firmware/rockchip_sip.c
@@ -0,0 +1,64 @@ 
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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.
+ *
+ * Copyright (C) 2016 ARM Limited
+ */
+#include <linux/errno.h>
+#include <linux/linkage.h>
+#include <linux/of.h>
+#include <linux/pm.h>
+#include <linux/printk.h>
+#include "rockchip_sip.h"
+
+typedef unsigned long (psci_fn)(unsigned long, unsigned long,
+				unsigned long, unsigned long);
+asmlinkage psci_fn __invoke_psci_fn_smc;
+
+#define CONFIG_DRAM_INIT	0x00
+#define CONFIG_DRAM_SET_RATE	0x01
+#define CONFIG_DRAM_ROUND_RATE	0x02
+#define CONFIG_DRAM_SET_AT_SR	0x03
+#define CONFIG_DRAM_GET_BW	0x04
+#define CONFIG_DRAM_GET_RATE	0x05
+#define CONFIG_DRAM_CLR_IRQ	0x06
+#define CONFIG_DRAM_SET_PARAM   0x07
+
+uint64_t sip_smc_ddr_init(void)
+{
+	return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0,
+				    0, CONFIG_DRAM_INIT);
+}
+
+uint64_t sip_smc_set_ddr_param(uint64_t param)
+{
+	return __invoke_psci_fn_smc(SIP_DDR_FREQ, param,
+				    0, CONFIG_DRAM_SET_PARAM);
+}
+
+uint64_t sip_smc_set_ddr_rate(uint64_t rate)
+{
+	return __invoke_psci_fn_smc(SIP_DDR_FREQ, rate, 0,
+				    CONFIG_DRAM_SET_RATE);
+}
+
+uint64_t sip_smc_get_ddr_rate(void)
+{
+	return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0, 0, CONFIG_DRAM_GET_RATE);
+}
+
+uint64_t sip_smc_clr_ddr_irq(void)
+{
+	return __invoke_psci_fn_smc(SIP_DDR_FREQ, 0, 0, CONFIG_DRAM_CLR_IRQ);
+}
+
+uint64_t sip_smc_get_call_count(void)
+{
+	return __invoke_psci_fn_smc(SIP_SVC_CALL_COUNT, 0, 0, 0);
+}
diff --git a/drivers/firmware/rockchip_sip.h b/drivers/firmware/rockchip_sip.h
new file mode 100644
index 0000000..6487734
--- /dev/null
+++ b/drivers/firmware/rockchip_sip.h
@@ -0,0 +1,59 @@ 
+/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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.
+ */
+#ifndef __SIP_INT_H
+#define __SIP_INT_H
+
+/* SMC function IDs for SiP Service queries */
+#define SIP_SVC_CALL_COUNT		0x8200ff00
+#define SIP_SVC_UID			0x8200ff01
+#define SIP_SVC_VERSION			0x8200ff03
+#define SIP_DDR_FREQ			0xC2000008
+
+#if IS_ENABLED(CONFIG_ROCKCHIP_SIP)
+uint64_t sip_smc_set_ddr_rate(uint64_t rate);
+uint64_t sip_smc_get_ddr_rate(void);
+uint64_t sip_smc_clr_ddr_irq(void);
+uint64_t sip_smc_get_call_count(void);
+uint64_t sip_smc_ddr_init(void);
+uint64_t sip_smc_set_ddr_param(uint64_t param);
+#else
+static inline uint64_t sip_smc_set_ddr_rate(uint64_t rate)
+{
+	return 0;
+}
+
+static inline uint64_t sip_smc_get_ddr_rate(void)
+{
+	return 0;
+}
+
+static inline uint64_t sip_smc_clr_ddr_irq(void)
+{
+	return 0;
+}
+
+static inline uint64_t sip_smc_get_call_count(void)
+{
+	return 0;
+}
+
+static inline uint64_t sip_smc_ddr_init(void)
+{
+	return 0;
+}
+
+static inline uint64_t sip_smc_set_ddr_param(uint64_t param)
+{
+	return 0;
+}
+#endif
+#endif