Re: [PATCH v8 3/3] PM / AVS: SVS: Introduce SVS engine

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 22/05/2020 11:40, Roger Lu wrote:
> 
> Hi Enric,
> 
> On Tue, 2020-05-19 at 17:30 +0200, Enric Balletbo Serra wrote:
>> Hi Roger,
>>
>> Thank you for your patch. I have the feeling that this driver is
>> complex and difficult to follow and I am wondering if it wouldn't be
>> better if you can send a version that simply adds basic functionality
>> for now. Some comments below.
> 
> Thanks for the advices. I'll submit SVS v9 with basic functionality
> patch + step by step functionalities' patches. 
> 
>>
>> Missatge de Roger Lu <roger.lu@xxxxxxxxxxxx> del dia dl., 18 de maig
>> 2020 a les 11:25:
>>>
>>> The SVS (Smart Voltage Scaling) engine is a piece
>>> of hardware which is used to calculate optimized
>>> voltage values of several power domains,
>>> e.g. CPU/GPU/CCI, according to chip process corner,
>>> temperatures, and other factors. Then DVFS driver
>>> could apply those optimized voltage values to reduce
>>> power consumption.
>>>
>>> Signed-off-by: Roger Lu <roger.lu@xxxxxxxxxxxx>
>>> ---
>>>  drivers/power/avs/Kconfig     |   10 +
>>>  drivers/power/avs/Makefile    |    1 +
>>>  drivers/power/avs/mtk_svs.c   | 2119 +++++++++++++++++++++++++++++++++
>>>  include/linux/power/mtk_svs.h |   23 +
>>>  4 files changed, 2153 insertions(+)
>>>  create mode 100644 drivers/power/avs/mtk_svs.c
>>>  create mode 100644 include/linux/power/mtk_svs.h
>>>
>>> diff --git a/drivers/power/avs/Kconfig b/drivers/power/avs/Kconfig
>>> index cdb4237bfd02..67089ac6040e 100644
>>> --- a/drivers/power/avs/Kconfig
>>> +++ b/drivers/power/avs/Kconfig
>>> @@ -35,3 +35,13 @@ config ROCKCHIP_IODOMAIN
>>>           Say y here to enable support io domains on Rockchip SoCs. It is
>>>           necessary for the io domain setting of the SoC to match the
>>>           voltage supplied by the regulators.
>>> +
>>> +config MTK_SVS
>>> +       bool "MediaTek Smart Voltage Scaling(SVS)"
>>
>> Can't be this a module? Why? In such case, you should use tristate option
> 
> Generally, MTK_SVS is needed in MTK SoC(mt81xx) products. So, we don't provide
> module option in config. If, somehow, SVS isn't needed, we suggest
> CONFIG_MTK_SVS=n to be set.
> 

The question here is if it needs to be probed before we probe the modules. If
not, we should add a Kconfig option for MT81xx SoCs to select MTK_SVS.

>>
>>> +       depends on POWER_AVS && MTK_EFUSE && NVMEM
>>> +       help
>>> +         The SVS engine is a piece of hardware which is used to calculate
>>> +         optimized voltage values of several power domains, e.g.
>>> +         CPU clusters/GPU/CCI, according to chip process corner, temperatures,
>>> +         and other factors. Then DVFS driver could apply those optimized voltage
>>> +         values to reduce power consumption.
>>> diff --git a/drivers/power/avs/Makefile b/drivers/power/avs/Makefile
>>> index 9007d05853e2..231adf078582 100644
>>> --- a/drivers/power/avs/Makefile
>>> +++ b/drivers/power/avs/Makefile
>>> @@ -2,3 +2,4 @@
>>>  obj-$(CONFIG_POWER_AVS_OMAP)           += smartreflex.o
>>>  obj-$(CONFIG_QCOM_CPR)                 += qcom-cpr.o
>>>  obj-$(CONFIG_ROCKCHIP_IODOMAIN)                += rockchip-io-domain.o
>>> +obj-$(CONFIG_MTK_SVS)                  += mtk_svs.o
>>
>> Will this driver be SoC specific or the idea is to support different
>> SoCs? If the answer to the first question is yes, please name the file
>> with the SoC prefix (i.e mt8183_svs). However, If the answer to the
>> second question is yes, make sure you prefix common
>> functions/structs/defines with a generic prefix mtk_svs but use the
>> SoC prefix for the ones you expect will be different between SoC, i.e
>> mt8183_svs_. This helps the readability of the driver. Also, try to
>> avoid too generic names.
> 
> MTK_SVS is designed for supporting different MTK SoCs.Therefore, the answer is second
> question and thanks for the heads-up.
> 
>>
>>> diff --git a/drivers/power/avs/mtk_svs.c b/drivers/power/avs/mtk_svs.c
>>> new file mode 100644
>>> index 000000000000..a4083b3ef175
>>> --- /dev/null
>>> +++ b/drivers/power/avs/mtk_svs.c
>>> @@ -0,0 +1,2119 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>
>> I suspect you want this only GPLv2 compliant. Use GPL-2.0-only
> 
> OK. I'll use GPL-2.0-only.Thanks.
> 
>>
>>> +/*
>>> + * Copyright (C) 2020 MediaTek Inc.
>>> + */
>>> +
>>> +#define pr_fmt(fmt)    "[mtk_svs] " fmt
>>
>> I don't see any reason to use pr_fmt in this driver. Use dev_*
>> functions instead and remove the above.
> 
> Ok. I will remove it. Thanks.
> 
>>
>>> +
>>> +#include <linux/bits.h>
>>> +#include <linux/clk.h>
>>> +#include <linux/completion.h>
>>> +#include <linux/init.h>
>>> +#include <linux/interrupt.h>
>>> +#include <linux/kernel.h>
>>> +#include <linux/kthread.h>
>>> +#include <linux/module.h>
>>> +#include <linux/mutex.h>
>>> +#include <linux/nvmem-consumer.h>
>>> +#include <linux/of_address.h>
>>> +#include <linux/of_irq.h>
>>> +#include <linux/of_platform.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/pm_domain.h>
>>> +#include <linux/pm_opp.h>
>>> +#include <linux/pm_qos.h>
>>> +#include <linux/pm_runtime.h>
>>> +#include <linux/power/mtk_svs.h>
>>> +#include <linux/proc_fs.h>
>>> +#include <linux/regulator/consumer.h>
>>> +#include <linux/reset.h>
>>> +#include <linux/seq_file.h>
>>> +#include <linux/slab.h>
>>> +#include <linux/spinlock.h>
>>> +#include <linux/thermal.h>
>>> +#include <linux/uaccess.h>
>>> +
>>> +/* svs 1-line sw id */
>>> +#define SVS_CPU_LITTLE                 BIT(0)
>>> +#define SVS_CPU_BIG                    BIT(1)
>>> +#define SVS_CCI                                BIT(2)
>>> +#define SVS_GPU                                BIT(3)
>>> +
>>> +/* svs bank mode support */
>>> +#define SVSB_MODE_ALL_DISABLE          (0)
>>
>> nit: SVS_BMODE_?
> 
> Oh. If we add bank wording like SVS_Bxxx, it might cause some confusion when B combines
> with other words. So, I'll keep SVSB for SVS Bank representation.
> E.g: SVS_BDC_SIGNED_BIT might lead to be explained differently ("SVS bank + DC_SIGNED_BIT" or "SVS + BDC_SIGNED_BIT")
>      - "SVS bank + DC_SIGNED_BIT" is what we want for naming SVS_BDC_SIGNED_BIT but it might be misunderstood.
> 
>>
>>> +#define SVSB_MODE_INIT01               BIT(1)
>>> +#define SVSB_MODE_INIT02               BIT(2)
>>> +#define SVSB_MODE_MON                  BIT(3)
>>> +
>>> +/* svs bank init01 condition */
>>> +#define SVSB_INIT01_VOLT_IGNORE                BIT(1)
>>> +#define SVSB_INIT01_VOLT_INC_ONLY      BIT(2)
>>> +
>>> +/* svs bank common setting */
>>> +#define HIGH_TEMP_MAX                  (U32_MAX)
>>
>> nit: SVS_*
> 
> ok. I will add SVS or SVSB when it refers to SVS BANK.
> 
>>
>>> +#define RUNCONFIG_DEFAULT              (0x80000000)
>>
>> Btw, there is any public datasheet where I can see those addresses and
>> registers and bit fields?
> 
> Excuse us, there is no public datasheet. We can reply it on patchwork. Thanks.
> 
>>
>>> +#define DC_SIGNED_BIT                  (0x8000)
>>> +#define INTEN_INIT0x                   (0x00005f01)
>>> +#define INTEN_MONVOPEN                 (0x00ff0000)
>>> +#define SVSEN_OFF                      (0x0)
>>> +#define SVSEN_MASK                     (0x7)
>>> +#define SVSEN_INIT01                   (0x1)
>>> +#define SVSEN_INIT02                   (0x5)
>>> +#define SVSEN_MON                      (0x2)
>>> +#define INTSTS_MONVOP                  (0x00ff0000)
>>> +#define INTSTS_COMPLETE                        (0x1)
>>> +#define INTSTS_CLEAN                   (0x00ffffff)
>>> +
>>> +#define proc_fops_rw(name) \
>>> +       static int name ## _proc_open(struct inode *inode,      \
>>> +                                     struct file *file)        \
>>> +       {                                                       \
>>> +               return single_open(file, name ## _proc_show,    \
>>> +                                  PDE_DATA(inode));            \
>>> +       }                                                       \
>>> +       static const struct proc_ops name ## _proc_fops = {     \
>>> +               .proc_open      = name ## _proc_open,           \
>>> +               .proc_read      = seq_read,                     \
>>> +               .proc_lseek     = seq_lseek,                    \
>>> +               .proc_release   = single_release,               \
>>> +               .proc_write     = name ## _proc_write,          \
>>> +       }
>>> +
>>> +#define proc_fops_ro(name) \
>>> +       static int name ## _proc_open(struct inode *inode,      \
>>> +                                     struct file *file)        \
>>> +       {                                                       \
>>> +               return single_open(file, name ## _proc_show,    \
>>> +                                  PDE_DATA(inode));            \
>>> +       }                                                       \
>>> +       static const struct proc_ops name ## _proc_fops = {     \
>>> +               .proc_open      = name ## _proc_open,           \
>>> +               .proc_read      = seq_read,                     \
>>> +               .proc_lseek     = seq_lseek,                    \
>>> +               .proc_release   = single_release,               \
>>> +       }
>>> +
>>> +#define proc_entry(name)       {__stringify(name), &name ## _proc_fops}
>>> +
>>
>> /proc is usually the old way of exporting files to userspace, so
>> unless you have a really good reason use sysfs instead, or even
>> better, if it is only for debug purposes use debugfs. Also, you should
>> document the entries in Documentation.
> 
> Ok. I'll change it to debugfs and could you give us an example about entries in documentation?
> We can follow them. Thanks.
> 
>>
>>> +static DEFINE_SPINLOCK(mtk_svs_lock);
>>> +struct mtk_svs;
>>> +
>>> +enum svsb_phase {
>>
>> nit: mtk_svs_bphase?
> 
> ditto
> 
>>
>>> +       SVSB_PHASE_INIT01 = 0,
>>
>> nit: SVS_BPHASE_?
> 
> ditto
> 
>>
>>> +       SVSB_PHASE_INIT02,
>>> +       SVSB_PHASE_MON,
>>> +       SVSB_PHASE_ERROR,
>>> +};
>>> +
>>> +enum reg_index {
>>
>> nit: svs_reg_index?
> 
> OK. Thanks.
> 
>>
>>> +       TEMPMONCTL0 = 0,
>>> +       TEMPMONCTL1,
>>> +       TEMPMONCTL2,
>>> +       TEMPMONINT,
>>> +       TEMPMONINTSTS,
>>> +       TEMPMONIDET0,
>>> +       TEMPMONIDET1,
>>> +       TEMPMONIDET2,
>>> +       TEMPH2NTHRE,
>>> +       TEMPHTHRE,
>>> +       TEMPCTHRE,
>>> +       TEMPOFFSETH,
>>> +       TEMPOFFSETL,
>>> +       TEMPMSRCTL0,
>>> +       TEMPMSRCTL1,
>>> +       TEMPAHBPOLL,
>>> +       TEMPAHBTO,
>>> +       TEMPADCPNP0,
>>> +       TEMPADCPNP1,
>>> +       TEMPADCPNP2,
>>> +       TEMPADCMUX,
>>> +       TEMPADCEXT,
>>> +       TEMPADCEXT1,
>>> +       TEMPADCEN,
>>> +       TEMPPNPMUXADDR,
>>> +       TEMPADCMUXADDR,
>>> +       TEMPADCEXTADDR,
>>> +       TEMPADCEXT1ADDR,
>>> +       TEMPADCENADDR,
>>> +       TEMPADCVALIDADDR,
>>> +       TEMPADCVOLTADDR,
>>> +       TEMPRDCTRL,
>>> +       TEMPADCVALIDMASK,
>>> +       TEMPADCVOLTAGESHIFT,
>>> +       TEMPADCWRITECTRL,
>>> +       TEMPMSR0,
>>> +       TEMPMSR1,
>>> +       TEMPMSR2,
>>> +       TEMPADCHADDR,
>>> +       TEMPIMMD0,
>>> +       TEMPIMMD1,
>>> +       TEMPIMMD2,
>>> +       TEMPMONIDET3,
>>> +       TEMPADCPNP3,
>>> +       TEMPMSR3,
>>> +       TEMPIMMD3,
>>> +       TEMPPROTCTL,
>>> +       TEMPPROTTA,
>>> +       TEMPPROTTB,
>>> +       TEMPPROTTC,
>>> +       TEMPSPARE0,
>>> +       TEMPSPARE1,
>>> +       TEMPSPARE2,
>>> +       TEMPSPARE3,
>>> +       TEMPMSR0_1,
>>> +       TEMPMSR1_1,
>>> +       TEMPMSR2_1,
>>> +       TEMPMSR3_1,
>>> +       DESCHAR,
>>> +       TEMPCHAR,
>>> +       DETCHAR,
>>> +       AGECHAR,
>>> +       DCCONFIG,
>>> +       AGECONFIG,
>>> +       FREQPCT30,
>>> +       FREQPCT74,
>>> +       LIMITVALS,
>>> +       VBOOT,
>>> +       DETWINDOW,
>>> +       CONFIG,
>>> +       TSCALCS,
>>> +       RUNCONFIG,
>>> +       SVSEN,
>>> +       INIT2VALS,
>>> +       DCVALUES,
>>> +       AGEVALUES,
>>> +       VOP30,
>>> +       VOP74,
>>> +       TEMP,
>>> +       INTSTS,
>>> +       INTSTSRAW,
>>> +       INTEN,
>>> +       CHKINT,
>>> +       CHKSHIFT,
>>> +       STATUS,
>>> +       VDESIGN30,
>>> +       VDESIGN74,
>>> +       DVT30,
>>> +       DVT74,
>>> +       AGECOUNT,
>>> +       SMSTATE0,
>>> +       SMSTATE1,
>>> +       CTL0,
>>> +       DESDETSEC,
>>> +       TEMPAGESEC,
>>> +       CTRLSPARE0,
>>> +       CTRLSPARE1,
>>> +       CTRLSPARE2,
>>> +       CTRLSPARE3,
>>> +       CORESEL,
>>> +       THERMINTST,
>>> +       INTST,
>>> +       THSTAGE0ST,
>>> +       THSTAGE1ST,
>>> +       THSTAGE2ST,
>>> +       THAHBST0,
>>> +       THAHBST1,
>>> +       SPARE0,
>>> +       SPARE1,
>>> +       SPARE2,
>>> +       SPARE3,
>>> +       THSLPEVEB,
>>> +       reg_num,
>>> +};
>>> +
>>> +static const u32 svs_regs_v2[] = {
>>
>> Is this SoC specific or shared between SoCs?
> 
> Shared between SoCs. Some SVS in MTK SoCs use v2 register map.
> 

And which silicon uses v1 then? Is v2 a MediaTek internal naming you want to keep?

>>
>>> +       [TEMPMONCTL0]           = 0x000,
>>> +       [TEMPMONCTL1]           = 0x004,
>>> +       [TEMPMONCTL2]           = 0x008,
>>> +       [TEMPMONINT]            = 0x00c,
>>> +       [TEMPMONINTSTS]         = 0x010,
>>> +       [TEMPMONIDET0]          = 0x014,
>>> +       [TEMPMONIDET1]          = 0x018,
>>> +       [TEMPMONIDET2]          = 0x01c,
>>> +       [TEMPH2NTHRE]           = 0x024,
>>> +       [TEMPHTHRE]             = 0x028,
>>> +       [TEMPCTHRE]             = 0x02c,
>>> +       [TEMPOFFSETH]           = 0x030,
>>> +       [TEMPOFFSETL]           = 0x034,
>>> +       [TEMPMSRCTL0]           = 0x038,
>>> +       [TEMPMSRCTL1]           = 0x03c,
>>> +       [TEMPAHBPOLL]           = 0x040,
>>> +       [TEMPAHBTO]             = 0x044,
>>> +       [TEMPADCPNP0]           = 0x048,
>>> +       [TEMPADCPNP1]           = 0x04c,
>>> +       [TEMPADCPNP2]           = 0x050,
>>> +       [TEMPADCMUX]            = 0x054,
>>> +       [TEMPADCEXT]            = 0x058,
>>> +       [TEMPADCEXT1]           = 0x05c,
>>> +       [TEMPADCEN]             = 0x060,
>>> +       [TEMPPNPMUXADDR]        = 0x064,
>>> +       [TEMPADCMUXADDR]        = 0x068,
>>> +       [TEMPADCEXTADDR]        = 0x06c,
>>> +       [TEMPADCEXT1ADDR]       = 0x070,
>>> +       [TEMPADCENADDR]         = 0x074,
>>> +       [TEMPADCVALIDADDR]      = 0x078,
>>> +       [TEMPADCVOLTADDR]       = 0x07c,
>>> +       [TEMPRDCTRL]            = 0x080,
>>> +       [TEMPADCVALIDMASK]      = 0x084,
>>> +       [TEMPADCVOLTAGESHIFT]   = 0x088,
>>> +       [TEMPADCWRITECTRL]      = 0x08c,
>>> +       [TEMPMSR0]              = 0x090,
>>> +       [TEMPMSR1]              = 0x094,
>>> +       [TEMPMSR2]              = 0x098,
>>> +       [TEMPADCHADDR]          = 0x09c,
>>> +       [TEMPIMMD0]             = 0x0a0,
>>> +       [TEMPIMMD1]             = 0x0a4,
>>> +       [TEMPIMMD2]             = 0x0a8,
>>> +       [TEMPMONIDET3]          = 0x0b0,
>>> +       [TEMPADCPNP3]           = 0x0b4,
>>> +       [TEMPMSR3]              = 0x0b8,
>>> +       [TEMPIMMD3]             = 0x0bc,
>>> +       [TEMPPROTCTL]           = 0x0c0,
>>> +       [TEMPPROTTA]            = 0x0c4,
>>> +       [TEMPPROTTB]            = 0x0c8,
>>> +       [TEMPPROTTC]            = 0x0cc,
>>> +       [TEMPSPARE0]            = 0x0f0,
>>> +       [TEMPSPARE1]            = 0x0f4,
>>> +       [TEMPSPARE2]            = 0x0f8,
>>> +       [TEMPSPARE3]            = 0x0fc,
>>> +       [TEMPMSR0_1]            = 0x190,
>>> +       [TEMPMSR1_1]            = 0x194,
>>> +       [TEMPMSR2_1]            = 0x198,
>>> +       [TEMPMSR3_1]            = 0x1b8,
>>> +       [DESCHAR]               = 0xc00,
>>> +       [TEMPCHAR]              = 0xc04,
>>> +       [DETCHAR]               = 0xc08,
>>> +       [AGECHAR]               = 0xc0c,
>>> +       [DCCONFIG]              = 0xc10,
>>> +       [AGECONFIG]             = 0xc14,
>>> +       [FREQPCT30]             = 0xc18,
>>> +       [FREQPCT74]             = 0xc1c,
>>> +       [LIMITVALS]             = 0xc20,
>>> +       [VBOOT]                 = 0xc24,
>>> +       [DETWINDOW]             = 0xc28,
>>> +       [CONFIG]                = 0xc2c,
>>> +       [TSCALCS]               = 0xc30,
>>> +       [RUNCONFIG]             = 0xc34,
>>> +       [SVSEN]                 = 0xc38,
>>> +       [INIT2VALS]             = 0xc3c,
>>> +       [DCVALUES]              = 0xc40,
>>> +       [AGEVALUES]             = 0xc44,
>>> +       [VOP30]                 = 0xc48,
>>> +       [VOP74]                 = 0xc4c,
>>> +       [TEMP]                  = 0xc50,
>>> +       [INTSTS]                = 0xc54,
>>> +       [INTSTSRAW]             = 0xc58,
>>> +       [INTEN]                 = 0xc5c,
>>> +       [CHKINT]                = 0xc60,
>>> +       [CHKSHIFT]              = 0xc64,
>>> +       [STATUS]                = 0xc68,
>>> +       [VDESIGN30]             = 0xc6c,
>>> +       [VDESIGN74]             = 0xc70,
>>> +       [DVT30]                 = 0xc74,
>>> +       [DVT74]                 = 0xc78,
>>> +       [AGECOUNT]              = 0xc7c,
>>> +       [SMSTATE0]              = 0xc80,
>>> +       [SMSTATE1]              = 0xc84,
>>> +       [CTL0]                  = 0xc88,
>>> +       [DESDETSEC]             = 0xce0,
>>> +       [TEMPAGESEC]            = 0xce4,
>>> +       [CTRLSPARE0]            = 0xcf0,
>>> +       [CTRLSPARE1]            = 0xcf4,
>>> +       [CTRLSPARE2]            = 0xcf8,
>>> +       [CTRLSPARE3]            = 0xcfc,
>>> +       [CORESEL]               = 0xf00,
>>> +       [THERMINTST]            = 0xf04,
>>> +       [INTST]                 = 0xf08,
>>> +       [THSTAGE0ST]            = 0xf0c,
>>> +       [THSTAGE1ST]            = 0xf10,
>>> +       [THSTAGE2ST]            = 0xf14,
>>> +       [THAHBST0]              = 0xf18,
>>> +       [THAHBST1]              = 0xf1c,
>>> +       [SPARE0]                = 0xf20,
>>> +       [SPARE1]                = 0xf24,
>>> +       [SPARE2]                = 0xf28,
>>> +       [SPARE3]                = 0xf2c,
>>> +       [THSLPEVEB]             = 0xf30,
>>> +};
>>> +
>>> +struct thermal_parameter {
>>
>> In general, not only in this struct, would be good have some
>> documentation to have a better undestanding of the fields. That makes
>> the job of the reviewer a bit easier.
> 
> Ok. Could you share a documentation example to us? We'll share the
> information as much as we can. Thanks a lot.
> 

you should find that in all drivers, eg:
https://elixir.bootlin.com/linux/latest/source/drivers/soc/mediatek/mtk-scpsys.c#L111


Regards,
Matthias



[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]


  Powered by Linux