All of lore.kernel.org
 help / color / mirror / Atom feed
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, &reg_map);
> +			return pmc_setup_dev(pdev, ent);
>  	}
>  	/* Device not found. */
>  	return -ENODEV;
> 


  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.