From: "Li, Aubrey" <aubrey.li@linux.intel.com>
To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
x86@kernel.org, "Rafael J . Wysocki" <rafael.j.wysocki@intel.com>,
"Kumar P, Mahesh" <mahesh.kumar.p@intel.com>,
linux-kernel@vger.kernel.org, linux-acpi@vger.kernel.org
Subject: Re: [PATCH v2 4/4] PMC driver: Add Cherrytrail PMC interface
Date: Thu, 22 Jan 2015 12:02:09 +0800 [thread overview]
Message-ID: <54C07641.7090706@linux.intel.com> (raw)
In-Reply-To: <1421790603-30097-5-git-send-email-andriy.shevchenko@linux.intel.com>
On 2015/1/21 5:50, Andy Shevchenko wrote:
> The patch adds CHT PMC interface. This exposes all the South IP device power
> states and S0ix states for CHT. The bit map of FUNC_DIS and D3_STS_0 registers
> for SoCs are consistent. The D3_STS_1 and FUNC_DIS_2 registers, however, are
> not aligned. This is fixed by splitting a common mapping on per register basis.
>
Should we define the bit map table completely separate for different
platforms? My concern is, when D3_STS_0 and FUNC_DIS becomes not
consistent in a new SoC, the implementation in this patch has to be
rewritten completely.
Defining entire bit map table for different platform introduces
reduplicated bit definitions, but when we add a new platform in future,
we don't need to consider the existing platforms definition, and no need
to change code structure any longer.
Thoughts?
Thanks,
-Aubrey
> Signed-off-by: Kumar P Mahesh <mahesh.kumar.p@intel.com>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> ---
> arch/x86/include/asm/pmc_atom.h | 25 +++++++++
> arch/x86/kernel/pmc_atom.c | 118 ++++++++++++++++++++++++++++++----------
> 2 files changed, 114 insertions(+), 29 deletions(-)
>
> diff --git a/arch/x86/include/asm/pmc_atom.h b/arch/x86/include/asm/pmc_atom.h
> index bc0fc08..000a223 100644
> --- a/arch/x86/include/asm/pmc_atom.h
> +++ b/arch/x86/include/asm/pmc_atom.h
> @@ -18,6 +18,8 @@
>
> /* ValleyView Power Control Unit PCI Device ID */
> #define PCI_DEVICE_ID_VLV_PMC 0x0F1C
> +/* CherryTrail Power Control Unit PCI Device ID */
> +#define PCI_DEVICE_ID_CHT_PMC 0x229C
>
> /* PMC Memory mapped IO registers */
> #define PMC_BASE_ADDR_OFFSET 0x44
> @@ -29,6 +31,10 @@
> #define PMC_FUNC_DIS 0x34
> #define PMC_FUNC_DIS_2 0x38
>
> +/* CHT specific bits in FUNC_DIS2 register */
> +#define BIT_FD_GMM BIT(3)
> +#define BIT_FD_ISH BIT(4)
> +
> /* S0ix wake event control */
> #define PMC_S0IX_WAKE_EN 0x3C
>
> @@ -75,6 +81,21 @@
> #define PMC_PSS_BIT_USB BIT(16)
> #define PMC_PSS_BIT_USB_SUS BIT(17)
>
> +/* CHT specific bits in PSS register */
> +#define PMC_PSS_BIT_CHT_UFS BIT(7)
> +#define PMC_PSS_BIT_CHT_UXD BIT(11)
> +#define PMC_PSS_BIT_CHT_UXD_FD BIT(12)
> +#define PMC_PSS_BIT_CHT_UX_ENG BIT(15)
> +#define PMC_PSS_BIT_CHT_USB_SUS BIT(16)
> +#define PMC_PSS_BIT_CHT_GMM BIT(17)
> +#define PMC_PSS_BIT_CHT_ISH BIT(18)
> +#define PMC_PSS_BIT_CHT_DFX_MASTER BIT(26)
> +#define PMC_PSS_BIT_CHT_DFX_CLUSTER1 BIT(27)
> +#define PMC_PSS_BIT_CHT_DFX_CLUSTER2 BIT(28)
> +#define PMC_PSS_BIT_CHT_DFX_CLUSTER3 BIT(29)
> +#define PMC_PSS_BIT_CHT_DFX_CLUSTER4 BIT(30)
> +#define PMC_PSS_BIT_CHT_DFX_CLUSTER5 BIT(31)
> +
> /* These registers reflect D3 status of functions */
> #define PMC_D3_STS_0 0xA0
>
> @@ -117,6 +138,10 @@
> #define BIT_USH_SS_PHY BIT(2)
> #define BIT_DFX BIT(3)
>
> +/* CHT specific bits in PMC_D3_STS_1 register */
> +#define BIT_STS_GMM BIT(1)
> +#define BIT_STS_ISH BIT(2)
> +
> /* PMC I/O Registers */
> #define ACPI_BASE_ADDR_OFFSET 0x40
> #define ACPI_BASE_ADDR_MASK 0xFFFFFE00
> diff --git a/arch/x86/kernel/pmc_atom.c b/arch/x86/kernel/pmc_atom.c
> index 0f24ef7..41f4a33 100644
> --- a/arch/x86/kernel/pmc_atom.c
> +++ b/arch/x86/kernel/pmc_atom.c
> @@ -31,7 +31,10 @@ struct pmc_bit_map {
> };
>
> struct pmc_reg_map {
> - const struct pmc_bit_map *dev;
> + const struct pmc_bit_map *d3_sts_0;
> + const struct pmc_bit_map *d3_sts_1;
> + const struct pmc_bit_map *func_dis;
> + const struct pmc_bit_map *func_dis_2;
> const struct pmc_bit_map *pss;
> };
>
> @@ -48,7 +51,7 @@ struct pmc_dev {
> static struct pmc_dev pmc_device;
> static u32 acpi_base_addr;
>
> -static const struct pmc_bit_map dev_map[] = {
> +static const struct pmc_bit_map d3_sts_0_map[] = {
> {"LPSS1_F0_DMA", BIT_LPSS1_F0_DMA},
> {"LPSS1_F1_PWM1", BIT_LPSS1_F1_PWM1},
> {"LPSS1_F2_PWM2", BIT_LPSS1_F2_PWM2},
> @@ -81,6 +84,10 @@ static const struct pmc_bit_map dev_map[] = {
> {"LPSS2_F5_I2C5", BIT_LPSS2_F5_I2C5},
> {"LPSS2_F6_I2C6", BIT_LPSS2_F6_I2C6},
> {"LPSS2_F7_I2C7", BIT_LPSS2_F7_I2C7},
> + {},
> +};
> +
> +static struct pmc_bit_map byt_d3_sts_1_map[] = {
> {"SMB", BIT_SMB},
> {"OTG_SS_PHY", BIT_OTG_SS_PHY},
> {"USH_SS_PHY", BIT_USH_SS_PHY},
> @@ -88,7 +95,21 @@ static const struct pmc_bit_map dev_map[] = {
> {},
> };
>
> -static const struct pmc_bit_map pss_map[] = {
> +static struct pmc_bit_map cht_d3_sts_1_map[] = {
> + {"SMB", BIT_SMB},
> + {"GMM", BIT_STS_GMM},
> + {"ISH", BIT_STS_ISH},
> + {},
> +};
> +
> +static struct pmc_bit_map cht_func_dis_2_map[] = {
> + {"SMB", BIT_SMB},
> + {"GMM", BIT_FD_GMM},
> + {"ISH", BIT_FD_ISH},
> + {},
> +};
> +
> +static const struct pmc_bit_map byt_pss_map[] = {
> {"GBE", PMC_PSS_BIT_GBE},
> {"SATA", PMC_PSS_BIT_SATA},
> {"HDA", PMC_PSS_BIT_HDA},
> @@ -110,9 +131,43 @@ static const struct pmc_bit_map pss_map[] = {
> {},
> };
>
> -static const struct pmc_reg_map reg_map = {
> - .dev = dev_map,
> - .pss = pss_map,
> +static const struct pmc_bit_map cht_pss_map[] = {
> + {"SATA", PMC_PSS_BIT_SATA},
> + {"HDA", PMC_PSS_BIT_HDA},
> + {"SEC", PMC_PSS_BIT_SEC},
> + {"PCIE", PMC_PSS_BIT_PCIE},
> + {"LPSS", PMC_PSS_BIT_LPSS},
> + {"LPE", PMC_PSS_BIT_LPE},
> + {"UFS", PMC_PSS_BIT_CHT_UFS},
> + {"UXD", PMC_PSS_BIT_CHT_UXD},
> + {"UXD_FD", PMC_PSS_BIT_CHT_UXD_FD},
> + {"UX_ENG", PMC_PSS_BIT_CHT_UX_ENG},
> + {"USB_SUS", PMC_PSS_BIT_CHT_USB_SUS},
> + {"GMM", PMC_PSS_BIT_CHT_GMM},
> + {"ISH", PMC_PSS_BIT_CHT_ISH},
> + {"DFX_MASTER", PMC_PSS_BIT_CHT_DFX_MASTER},
> + {"DFX_CLUSTER1", PMC_PSS_BIT_CHT_DFX_CLUSTER1},
> + {"DFX_CLUSTER2", PMC_PSS_BIT_CHT_DFX_CLUSTER2},
> + {"DFX_CLUSTER3", PMC_PSS_BIT_CHT_DFX_CLUSTER3},
> + {"DFX_CLUSTER4", PMC_PSS_BIT_CHT_DFX_CLUSTER4},
> + {"DFX_CLUSTER5", PMC_PSS_BIT_CHT_DFX_CLUSTER5},
> + {},
> +};
> +
> +static const struct pmc_reg_map byt_reg_map = {
> + .d3_sts_0 = d3_sts_0_map,
> + .d3_sts_1 = byt_d3_sts_1_map,
> + .func_dis = d3_sts_0_map,
> + .func_dis_2 = byt_d3_sts_1_map,
> + .pss = byt_pss_map,
> +};
> +
> +static const struct pmc_reg_map cht_reg_map = {
> + .d3_sts_0 = d3_sts_0_map,
> + .d3_sts_1 = cht_d3_sts_1_map,
> + .func_dis = d3_sts_0_map,
> + .func_dis_2 = cht_func_dis_2_map,
> + .pss = cht_pss_map,
> };
>
> static inline u32 pmc_reg_read(struct pmc_dev *pmc, int reg_offset)
> @@ -156,36 +211,39 @@ static void pmc_hw_reg_setup(struct pmc_dev *pmc)
> }
>
> #ifdef CONFIG_DEBUG_FS
> +static void pmc_dev_state_print(struct seq_file *s, int reg_index,
> + u32 sts, const struct pmc_bit_map *sts_map,
> + u32 fd, const struct pmc_bit_map *fd_map)
> +{
> + int offset = PMC_REG_BIT_WIDTH * reg_index;
> + int index;
> +
> + for (index = 0; sts_map[index].name; index++) {
> + seq_printf(s, "Dev: %-2d - %-32s\tState: %s [%s]\n",
> + offset + index, sts_map[index].name,
> + fd_map[index].bit_mask & fd ? "Disabled" : "Enabled ",
> + sts_map[index].bit_mask & sts ? "D3" : "D0");
> + }
> +}
> +
> static int pmc_dev_state_show(struct seq_file *s, void *unused)
> {
> struct pmc_dev *pmc = s->private;
> - const struct pmc_bit_map *map = pmc->map->dev;
> - u32 func_dis, func_dis_2, func_dis_index;
> - u32 d3_sts_0, d3_sts_1, d3_sts_index;
> - int index, reg_index;
> + const struct pmc_reg_map *m = pmc->map;
> + u32 func_dis, func_dis_2;
> + u32 d3_sts_0, d3_sts_1;
>
> func_dis = pmc_reg_read(pmc, PMC_FUNC_DIS);
> func_dis_2 = pmc_reg_read(pmc, PMC_FUNC_DIS_2);
> d3_sts_0 = pmc_reg_read(pmc, PMC_D3_STS_0);
> d3_sts_1 = pmc_reg_read(pmc, PMC_D3_STS_1);
>
> - for (index = 0; map[index].name; index++) {
> - reg_index = index / PMC_REG_BIT_WIDTH;
> - if (reg_index) {
> - func_dis_index = func_dis_2;
> - d3_sts_index = d3_sts_1;
> - } else {
> - func_dis_index = func_dis;
> - d3_sts_index = d3_sts_0;
> - }
> + /* Low part */
> + pmc_dev_state_print(s, 0, d3_sts_0, m->d3_sts_0, func_dis, m->func_dis);
> +
> + /* High part */
> + pmc_dev_state_print(s, 1, d3_sts_1, m->d3_sts_1, func_dis_2, m->func_dis_2);
>
> - seq_printf(s, "Dev: %-2d - %-32s\tState: %s [%s]\n",
> - index, map[index].name,
> - map[index].bit_mask & func_dis_index ?
> - "Disabled" : "Enabled ",
> - map[index].bit_mask & d3_sts_index ?
> - "D3" : "D0");
> - }
> return 0;
> }
>
> @@ -307,9 +365,10 @@ static int pmc_dbgfs_register(struct pmc_dev *pmc)
> }
> #endif /* CONFIG_DEBUG_FS */
>
> -static int pmc_setup_dev(struct pci_dev *pdev, const struct pmc_reg_map *map)
> +static int pmc_setup_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
> {
> struct pmc_dev *pmc = &pmc_device;
> + const struct pmc_reg_map *map = (struct pmc_reg_map *)ent->driver_data;
> int ret;
>
> /* Obtain ACPI base address */
> @@ -351,7 +410,8 @@ static int pmc_setup_dev(struct pci_dev *pdev, const struct pmc_reg_map *map)
> * a driver on the same PCI id.
> */
> static const struct pci_device_id pmc_pci_ids[] = {
> - { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_VLV_PMC) },
> + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_VLV_PMC), (kernel_ulong_t)&byt_reg_map },
> + { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_CHT_PMC), (kernel_ulong_t)&cht_reg_map },
> { 0, },
> };
>
> @@ -373,7 +433,7 @@ static int __init pmc_atom_init(void)
> for_each_pci_dev(pdev) {
> ent = pci_match_id(pmc_pci_ids, pdev);
> if (ent)
> - return pmc_setup_dev(pdev, ®_map);
> + return pmc_setup_dev(pdev, ent);
> }
> /* Device not found. */
> return -ENODEV;
>
next prev parent reply other threads:[~2015-01-22 4:02 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-20 21:49 [PATCH v2 0/4] x86: pmc_atom: Add Cherrytrail support Andy Shevchenko
2015-01-20 21:50 ` [PATCH v2 1/4] x86: pmc_atom: save struct device pointer in pmc Andy Shevchenko
2015-01-22 3:42 ` Li, Aubrey
2015-01-22 9:29 ` Andy Shevchenko
2015-01-20 21:50 ` [PATCH v2 2/4] x86: pmc_atom: print index of device in loop Andy Shevchenko
2015-01-22 3:45 ` Li, Aubrey
2015-01-22 9:40 ` Andy Shevchenko
2015-01-20 21:50 ` [PATCH v2 3/4] x86: pmc_atom: supply register mappings via pmc object Andy Shevchenko
2015-01-20 21:50 ` [PATCH v2 4/4] PMC driver: Add Cherrytrail PMC interface Andy Shevchenko
2015-01-22 4:02 ` Li, Aubrey [this message]
2015-01-22 9:26 ` Andy Shevchenko
2015-01-26 2:30 ` Li, Aubrey
2015-02-23 12:45 ` [PATCH v2 0/4] x86: pmc_atom: Add Cherrytrail support Andy Shevchenko
2015-03-02 6:26 ` Li, Aubrey
2015-03-03 3:37 ` Li, Aubrey
2015-03-04 10:44 ` Andy Shevchenko
2015-03-30 13:05 ` Shevchenko, Andriy
2015-03-30 13:05 ` Shevchenko, Andriy
2015-03-31 10:59 ` Ingo Molnar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=54C07641.7090706@linux.intel.com \
--to=aubrey.li@linux.intel.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mahesh.kumar.p@intel.com \
--cc=rafael.j.wysocki@intel.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.