aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mfd/lpc_ich.c
diff options
context:
space:
mode:
authorPeter Tyser <ptyser@xes-inc.com>2014-03-10 17:34:54 -0400
committerLee Jones <lee.jones@linaro.org>2014-03-19 05:00:02 -0400
commiteb71d4dec4a5e010e34b9d7afdb5af41884c388e (patch)
tree0ff010846f1be30a6a08c49bafd36cc05ef85e5c /drivers/mfd/lpc_ich.c
parent429b941abd503c8936e116c819362323aafdbd50 (diff)
mfd: lpc_ich: Add support for iTCO v3
Some newer Atom CPUs, eg Avoton and Bay Trail, use slightly different register layouts for the iTCO than the current v1 and v2 iTCO. Differences from previous iTCO versions include: - The ACPI space is enabled in the "ACPI base address" register instead of the "ACPI control register" - The "no reboot" functionality is set in the "Power Management Configuration" register instead of the "General Control and Status" (GCS) register or PCI configuration space. - The "ACPI Control Register" is not present on v3. The "Power Management Configuration Base Address" register resides at the same address is Avoton/Bay Trail. To differentiate these newer chipsets create a new v3 iTCO version and update the MFD driver to support them. Signed-off-by: Peter Tyser <ptyser@xes-inc.com> Tested-by: Rajat Jain <rajatjain@juniper.net> Reviewed-by: Guenter Roeck <linux@roeck-us.net> Signed-off-by: Lee Jones <lee.jones@linaro.org>
Diffstat (limited to 'drivers/mfd/lpc_ich.c')
-rw-r--r--drivers/mfd/lpc_ich.c81
1 files changed, 67 insertions, 14 deletions
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
index b24bae2bcdea..c0683370abbf 100644
--- a/drivers/mfd/lpc_ich.c
+++ b/drivers/mfd/lpc_ich.c
@@ -71,9 +71,11 @@
71#define ACPIBASE_GPE_END 0x2f 71#define ACPIBASE_GPE_END 0x2f
72#define ACPIBASE_SMI_OFF 0x30 72#define ACPIBASE_SMI_OFF 0x30
73#define ACPIBASE_SMI_END 0x33 73#define ACPIBASE_SMI_END 0x33
74#define ACPIBASE_PMC_OFF 0x08
75#define ACPIBASE_PMC_END 0x0c
74#define ACPIBASE_TCO_OFF 0x60 76#define ACPIBASE_TCO_OFF 0x60
75#define ACPIBASE_TCO_END 0x7f 77#define ACPIBASE_TCO_END 0x7f
76#define ACPICTRL 0x44 78#define ACPICTRL_PMCBASE 0x44
77 79
78#define ACPIBASE_GCS_OFF 0x3410 80#define ACPIBASE_GCS_OFF 0x3410
79#define ACPIBASE_GCS_END 0x3414 81#define ACPIBASE_GCS_END 0x3414
@@ -93,11 +95,12 @@ struct lpc_ich_priv {
93 int chipset; 95 int chipset;
94 96
95 int abase; /* ACPI base */ 97 int abase; /* ACPI base */
96 int actrl; /* ACPI control or PMC base */ 98 int actrl_pbase; /* ACPI control or PMC base */
97 int gbase; /* GPIO base */ 99 int gbase; /* GPIO base */
98 int gctrl; /* GPIO control */ 100 int gctrl; /* GPIO control */
99 101
100 int actrl_save; /* Cached ACPI control base value */ 102 int abase_save; /* Cached ACPI base value */
103 int actrl_pbase_save; /* Cached ACPI control or PMC base value */
101 int gctrl_save; /* Cached GPIO control value */ 104 int gctrl_save; /* Cached GPIO control value */
102}; 105};
103 106
@@ -110,7 +113,7 @@ static struct resource wdt_ich_res[] = {
110 { 113 {
111 .flags = IORESOURCE_IO, 114 .flags = IORESOURCE_IO,
112 }, 115 },
113 /* GCS */ 116 /* GCS or PMC */
114 { 117 {
115 .flags = IORESOURCE_MEM, 118 .flags = IORESOURCE_MEM,
116 }, 119 },
@@ -742,9 +745,15 @@ static void lpc_ich_restore_config_space(struct pci_dev *dev)
742{ 745{
743 struct lpc_ich_priv *priv = pci_get_drvdata(dev); 746 struct lpc_ich_priv *priv = pci_get_drvdata(dev);
744 747
745 if (priv->actrl_save >= 0) { 748 if (priv->abase_save >= 0) {
746 pci_write_config_byte(dev, priv->actrl, priv->actrl_save); 749 pci_write_config_byte(dev, priv->abase, priv->abase_save);
747 priv->actrl_save = -1; 750 priv->abase_save = -1;
751 }
752
753 if (priv->actrl_pbase_save >= 0) {
754 pci_write_config_byte(dev, priv->actrl_pbase,
755 priv->actrl_pbase_save);
756 priv->actrl_pbase_save = -1;
748 } 757 }
749 758
750 if (priv->gctrl_save >= 0) { 759 if (priv->gctrl_save >= 0) {
@@ -758,9 +767,26 @@ static void lpc_ich_enable_acpi_space(struct pci_dev *dev)
758 struct lpc_ich_priv *priv = pci_get_drvdata(dev); 767 struct lpc_ich_priv *priv = pci_get_drvdata(dev);
759 u8 reg_save; 768 u8 reg_save;
760 769
761 pci_read_config_byte(dev, priv->actrl, &reg_save); 770 switch (lpc_chipset_info[priv->chipset].iTCO_version) {
762 pci_write_config_byte(dev, priv->actrl, reg_save | 0x80); 771 case 3:
763 priv->actrl_save = reg_save; 772 /*
773 * Some chipsets (eg Avoton) enable the ACPI space in the
774 * ACPI BASE register.
775 */
776 pci_read_config_byte(dev, priv->abase, &reg_save);
777 pci_write_config_byte(dev, priv->abase, reg_save | 0x2);
778 priv->abase_save = reg_save;
779 break;
780 default:
781 /*
782 * Most chipsets enable the ACPI space in the ACPI control
783 * register.
784 */
785 pci_read_config_byte(dev, priv->actrl_pbase, &reg_save);
786 pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x80);
787 priv->actrl_pbase_save = reg_save;
788 break;
789 }
764} 790}
765 791
766static void lpc_ich_enable_gpio_space(struct pci_dev *dev) 792static void lpc_ich_enable_gpio_space(struct pci_dev *dev)
@@ -773,6 +799,17 @@ static void lpc_ich_enable_gpio_space(struct pci_dev *dev)
773 priv->gctrl_save = reg_save; 799 priv->gctrl_save = reg_save;
774} 800}
775 801
802static void lpc_ich_enable_pmc_space(struct pci_dev *dev)
803{
804 struct lpc_ich_priv *priv = pci_get_drvdata(dev);
805 u8 reg_save;
806
807 pci_read_config_byte(dev, priv->actrl_pbase, &reg_save);
808 pci_write_config_byte(dev, priv->actrl_pbase, reg_save | 0x2);
809
810 priv->actrl_pbase_save = reg_save;
811}
812
776static void lpc_ich_finalize_cell(struct pci_dev *dev, struct mfd_cell *cell) 813static void lpc_ich_finalize_cell(struct pci_dev *dev, struct mfd_cell *cell)
777{ 814{
778 struct lpc_ich_priv *priv = pci_get_drvdata(dev); 815 struct lpc_ich_priv *priv = pci_get_drvdata(dev);
@@ -910,14 +947,20 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
910 lpc_ich_enable_acpi_space(dev); 947 lpc_ich_enable_acpi_space(dev);
911 948
912 /* 949 /*
950 * iTCO v2:
913 * Get the Memory-Mapped GCS register. To get access to it 951 * Get the Memory-Mapped GCS register. To get access to it
914 * we have to read RCBA from PCI Config space 0xf0 and use 952 * we have to read RCBA from PCI Config space 0xf0 and use
915 * it as base. GCS = RCBA + ICH6_GCS(0x3410). 953 * it as base. GCS = RCBA + ICH6_GCS(0x3410).
954 *
955 * iTCO v3:
956 * Get the Power Management Configuration register. To get access
957 * to it we have to read the PMC BASE from config space and address
958 * the register at offset 0x8.
916 */ 959 */
917 if (lpc_chipset_info[priv->chipset].iTCO_version == 1) { 960 if (lpc_chipset_info[priv->chipset].iTCO_version == 1) {
918 /* Don't register iomem for TCO ver 1 */ 961 /* Don't register iomem for TCO ver 1 */
919 lpc_ich_cells[LPC_WDT].num_resources--; 962 lpc_ich_cells[LPC_WDT].num_resources--;
920 } else { 963 } else if (lpc_chipset_info[priv->chipset].iTCO_version == 2) {
921 pci_read_config_dword(dev, RCBABASE, &base_addr_cfg); 964 pci_read_config_dword(dev, RCBABASE, &base_addr_cfg);
922 base_addr = base_addr_cfg & 0xffffc000; 965 base_addr = base_addr_cfg & 0xffffc000;
923 if (!(base_addr_cfg & 1)) { 966 if (!(base_addr_cfg & 1)) {
@@ -926,9 +969,17 @@ static int lpc_ich_init_wdt(struct pci_dev *dev)
926 ret = -ENODEV; 969 ret = -ENODEV;
927 goto wdt_done; 970 goto wdt_done;
928 } 971 }
929 res = wdt_mem_res(ICH_RES_MEM_GCS); 972 res = wdt_mem_res(ICH_RES_MEM_GCS_PMC);
930 res->start = base_addr + ACPIBASE_GCS_OFF; 973 res->start = base_addr + ACPIBASE_GCS_OFF;
931 res->end = base_addr + ACPIBASE_GCS_END; 974 res->end = base_addr + ACPIBASE_GCS_END;
975 } else if (lpc_chipset_info[priv->chipset].iTCO_version == 3) {
976 lpc_ich_enable_pmc_space(dev);
977 pci_read_config_dword(dev, ACPICTRL_PMCBASE, &base_addr_cfg);
978 base_addr = base_addr_cfg & 0xfffffe00;
979
980 res = wdt_mem_res(ICH_RES_MEM_GCS_PMC);
981 res->start = base_addr + ACPIBASE_PMC_OFF;
982 res->end = base_addr + ACPIBASE_PMC_END;
932 } 983 }
933 984
934 lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]); 985 lpc_ich_finalize_cell(dev, &lpc_ich_cells[LPC_WDT]);
@@ -953,9 +1004,11 @@ static int lpc_ich_probe(struct pci_dev *dev,
953 1004
954 priv->chipset = id->driver_data; 1005 priv->chipset = id->driver_data;
955 1006
956 priv->actrl_save = -1; 1007 priv->actrl_pbase_save = -1;
1008 priv->abase_save = -1;
1009
957 priv->abase = ACPIBASE; 1010 priv->abase = ACPIBASE;
958 priv->actrl = ACPICTRL; 1011 priv->actrl_pbase = ACPICTRL_PMCBASE;
959 1012
960 priv->gctrl_save = -1; 1013 priv->gctrl_save = -1;
961 if (priv->chipset <= LPC_ICH5) { 1014 if (priv->chipset <= LPC_ICH5) {