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 registers for SOCs are
consistent. The D3_STS1 and FUNC_DIS2 registers, however
are not aligned. This is fixed by adding an extra field,
fn_dis bit, in the dev_map. Any deviations in these registers
should be addressed in this manner.

Signed-off-by: Kumar P Mahesh <[email protected]>
Signed-off-by: Aubrey Li <[email protected]>
Acked-by: Alan Cox <[email protected]>
---
 arch/x86/include/asm/pmc_atom.h |   30 ++++++++++----
 arch/x86/kernel/pmc_atom.c      |   87 +++++++++++++++++++++++++++++++++------
 2 files changed, 98 insertions(+), 19 deletions(-)

diff --git a/arch/x86/include/asm/pmc_atom.h b/arch/x86/include/asm/pmc_atom.h
index fc7a17c..581ad43 100644
--- a/arch/x86/include/asm/pmc_atom.h
+++ b/arch/x86/include/asm/pmc_atom.h
@@ -17,7 +17,10 @@
 #define PMC_ATOM_H
 
 /* ValleyView Power Control Unit PCI Device ID */
-#define        PCI_DEVICE_ID_VLV_PMC   0x0F1C
+#define        PCI_DEVICE_ID_BYT_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
@@ -25,9 +28,6 @@
 #define        PMC_MMIO_REG_LEN        0x100
 #define        PMC_REG_BIT_WIDTH       32
 
-/* BIOS uses FUNC_DIS to disable specific function */
-#define        PMC_FUNC_DIS            0x34
-#define        PMC_FUNC_DIS_2          0x38
 
 /* S0ix wake event control */
 #define        PMC_S0IX_WAKE_EN        0x3C
@@ -56,6 +56,7 @@
 /* These registers reflect D3 status of functions */
 #define        PMC_D3_STS_0            0xA0
 
+/* common bit definition */
 #define        BIT_LPSS1_F0_DMA        BIT(0)
 #define        BIT_LPSS1_F1_PWM1       BIT(1)
 #define        BIT_LPSS1_F2_PWM2       BIT(2)
@@ -91,9 +92,24 @@
 
 #define        PMC_D3_STS_1            0xA4
 #define        BIT_SMB                 BIT(0)
-#define        BIT_OTG_SS_PHY          BIT(1)
-#define        BIT_USH_SS_PHY          BIT(2)
-#define        BIT_DFX                 BIT(3)
+
+/*BYT specific bits in PMC_D3_STS_1 register*/
+#define        BIT_OTG_SS_PHY_BYT              BIT(1)
+#define        BIT_USH_SS_PHY_BYT              BIT(2)
+#define        BIT_DFX_BYT                     BIT(3)
+
+/*CHT specific bits in PMC_D3_STS_1 register*/
+#define        BIT_GMM_CHT                     BIT(1)
+#define        BIT_ISH_CHT                     BIT(2)
+
+/* BIOS uses FUNC_DIS to disable specific function */
+#define        PMC_FUNC_DIS            0x34
+#define        PMC_FUNC_DIS_2          0x38
+
+/*CHT specific bits in FUNC_DIS2 register*/
+#define        BIT_GMM_FD_CHT          BIT(3)
+#define        BIT_ISH_FD_CHT          BIT(4)
+
 
 /* PMC I/O Registers */
 #define        ACPI_BASE_ADDR_OFFSET   0x40
diff --git a/arch/x86/kernel/pmc_atom.c b/arch/x86/kernel/pmc_atom.c
index 0c424a6..822fb6a 100644
--- a/arch/x86/kernel/pmc_atom.c
+++ b/arch/x86/kernel/pmc_atom.c
@@ -40,10 +40,13 @@ static u32 acpi_base_addr;
 
 struct pmc_dev_map {
        const char *name;
-       u32 bit_mask;
+       u32 d3_sts_bit;
+       u32 fn_dis_bit;
 };
 
-static const struct pmc_dev_map dev_map[] = {
+static  struct pmc_dev_map *dev_map;
+static int dev_num;
+static  struct pmc_dev_map byt_dev_map[] = {
        {"0  - LPSS1_F0_DMA",           BIT_LPSS1_F0_DMA},
        {"1  - LPSS1_F1_PWM1",          BIT_LPSS1_F1_PWM1},
        {"2  - LPSS1_F2_PWM2",          BIT_LPSS1_F2_PWM2},
@@ -77,9 +80,47 @@ static const struct pmc_dev_map dev_map[] = {
        {"30 - LPSS2_F6_I2C6",          BIT_LPSS2_F6_I2C6},
        {"31 - LPSS2_F7_I2C7",          BIT_LPSS2_F7_I2C7},
        {"32 - SMB",                    BIT_SMB},
-       {"33 - OTG_SS_PHY",             BIT_OTG_SS_PHY},
-       {"34 - USH_SS_PHY",             BIT_USH_SS_PHY},
-       {"35 - DFX",                    BIT_DFX},
+       {"33 - OTG_SS_PHY",             BIT_OTG_SS_PHY_BYT},
+       {"34 - USH_SS_PHY",             BIT_USH_SS_PHY_BYT},
+       {"35 - DFX",                    BIT_DFX_BYT},
+};
+
+static struct pmc_dev_map cht_dev_map[] = {
+       {"0  - LPSS1_F0_DMA",           BIT_LPSS1_F0_DMA},
+       {"1  - LPSS1_F1_PWM1",          BIT_LPSS1_F1_PWM1},
+       {"2  - LPSS1_F2_PWM2",          BIT_LPSS1_F2_PWM2},
+       {"3  - LPSS1_F3_HSUART1",       BIT_LPSS1_F3_HSUART1},
+       {"4  - LPSS1_F4_HSUART2",       BIT_LPSS1_F4_HSUART2},
+       {"5  - LPSS1_F5_SPI",           BIT_LPSS1_F5_SPI},
+       {"6  - LPSS1_F6_Reserved",      BIT_LPSS1_F6_XXX},
+       {"7  - LPSS1_F7_Reserved",      BIT_LPSS1_F7_XXX},
+       {"8  - SCC_EMMC",               BIT_SCC_EMMC},
+       {"9  - SCC_SDIO",               BIT_SCC_SDIO},
+       {"10 - SCC_SDCARD",             BIT_SCC_SDCARD},
+       {"11 - SCC_MIPI",               BIT_SCC_MIPI},
+       {"12 - HDA",                    BIT_HDA},
+       {"13 - LPE",                    BIT_LPE},
+       {"14 - OTG",                    BIT_OTG},
+       {"15 - USH",                    BIT_USH},
+       {"16 - GBE",                    BIT_GBE},
+       {"17 - SATA",                   BIT_SATA},
+       {"18 - USB_XHCI",               BIT_USB_EHCI},
+       {"19 - SEC",                    BIT_SEC},
+       {"20 - PCIE_PORT0",             BIT_PCIE_PORT0},
+       {"21 - PCIE_PORT1",             BIT_PCIE_PORT1},
+       {"22 - PCIE_PORT2",             BIT_PCIE_PORT2},
+       {"23 - PCIE_PORT3",             BIT_PCIE_PORT3},
+       {"24 - LPSS2_F0_DMA",           BIT_LPSS2_F0_DMA},
+       {"25 - LPSS2_F1_I2C1",          BIT_LPSS2_F1_I2C1},
+       {"26 - LPSS2_F2_I2C2",          BIT_LPSS2_F2_I2C2},
+       {"27 - LPSS2_F3_I2C3",          BIT_LPSS2_F3_I2C3},
+       {"28 - LPSS2_F3_I2C4",          BIT_LPSS2_F4_I2C4},
+       {"29 - LPSS2_F5_I2C5",          BIT_LPSS2_F5_I2C5},
+       {"30 - LPSS2_F6_I2C6",          BIT_LPSS2_F6_I2C6},
+       {"31 - LPSS2_F7_I2C7",          BIT_LPSS2_F7_I2C7},
+       {"32 - SMB",    BIT_SMB},
+       {"33 - GMM",    BIT_GMM_CHT,    BIT_GMM_FD_CHT},
+       {"34 - ISH",    BIT_ISH_CHT,    BIT_ISH_FD_CHT},
 };
 
 static inline u32 pmc_reg_read(struct pmc_dev *pmc, int reg_offset)
@@ -128,30 +169,33 @@ static int pmc_dev_state_show(struct seq_file *s, void 
*unused)
        struct pmc_dev *pmc = s->private;
        u32 func_dis, func_dis_2, func_dis_index;
        u32 d3_sts_0, d3_sts_1, d3_sts_index;
-       int dev_num, dev_index, reg_index;
+       int dev_index, reg_index;
 
        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);
 
-       dev_num = ARRAY_SIZE(dev_map);
 
        for (dev_index = 0; dev_index < dev_num; dev_index++) {
                reg_index = dev_index / PMC_REG_BIT_WIDTH;
+
+
                if (reg_index) {
-                       func_dis_index = func_dis_2;
+                       func_dis_index =
+                               (func_dis_2 & dev_map[dev_index].fn_dis_bit);
                        d3_sts_index = d3_sts_1;
                } else {
-                       func_dis_index = func_dis;
+                       func_dis_index =
+                               func_dis & dev_map[dev_index].fn_dis_bit;
                        d3_sts_index = d3_sts_0;
                }
 
                seq_printf(s, "Dev: %-32s\tState: %s [%s]\n",
                        dev_map[dev_index].name,
-                       dev_map[dev_index].bit_mask & func_dis_index ?
+                       func_dis_index ?
                        "Disabled" : "Enabled ",
-                       dev_map[dev_index].bit_mask & d3_sts_index ?
+                       dev_map[dev_index].d3_sts_bit & d3_sts_index ?
                        "D3" : "D0");
        }
        return 0;
@@ -241,6 +285,7 @@ static int pmc_setup_dev(struct pci_dev *pdev)
 {
        struct pmc_dev *pmc = &pmc_device;
        int ret;
+       int dev_index, reg_index;
 
        /* Obtain ACPI base address */
        pci_read_config_dword(pdev, ACPI_BASE_ADDR_OFFSET, &acpi_base_addr);
@@ -262,6 +307,13 @@ static int pmc_setup_dev(struct pci_dev *pdev)
        /* PMC hardware registers setup */
        pmc_hw_reg_setup(pmc);
 
+       for (dev_index = 0; dev_index < dev_num; dev_index++) {
+               reg_index = dev_index / PMC_REG_BIT_WIDTH;
+               if (!dev_map[dev_index].fn_dis_bit)
+                               dev_map[dev_index].fn_dis_bit =
+                                       dev_map[dev_index].d3_sts_bit;
+       }
+
 #ifdef CONFIG_DEBUG_FS
        ret = pmc_dbgfs_register(pmc, pdev);
        if (ret) {
@@ -281,7 +333,8 @@ static int pmc_setup_dev(struct pci_dev *pdev)
  * 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_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_BYT_PMC) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_CHT_PMC) },
        { 0, },
 };
 
@@ -304,6 +357,16 @@ static int __init pmc_atom_init(void)
        for_each_pci_dev(pdev) {
                ent = pci_match_id(pmc_pci_ids, pdev);
                if (ent) {
+                       switch (ent->device) {
+                       case PCI_DEVICE_ID_BYT_PMC:
+                               dev_map = byt_dev_map;
+                               dev_num = ARRAY_SIZE(byt_dev_map);
+                               break;
+                       case PCI_DEVICE_ID_CHT_PMC:
+                               dev_map = cht_dev_map;
+                               dev_num = ARRAY_SIZE(cht_dev_map);
+                               break;
+                       }
                        err = pmc_setup_dev(pdev);
                        goto out;
                }
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to