soc/apollolake/pmutil: Get PMC base address dynamically
Instead of using a hardcoded address for PMC device BAR0, read it dynamically. This allows the allocator to move the BAR without needing a fixed resource. Note that we cannot do the same for the ACPI BAR (index 0x20), as it cannot be read back. Change-Id: If43e1ccb693ffb17b78bdd76140a0849493a0010 Signed-off-by: Alexandru Gagniuc <alexandrux.gagniuc@intel.com> Reviewed-on: https://review.coreboot.org/14633 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
614ef40815
commit
a63398059b
|
@ -15,15 +15,23 @@
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define __SIMPLE_DEVICE__
|
||||||
|
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <rules.h>
|
#include <rules.h>
|
||||||
#include <device/pci_def.h>
|
#include <device/pci_def.h>
|
||||||
#include <soc/iomap.h>
|
#include <soc/iomap.h>
|
||||||
|
#include <soc/pci_devs.h>
|
||||||
#include <soc/pm.h>
|
#include <soc/pm.h>
|
||||||
#include <device/device.h>
|
#include <device/device.h>
|
||||||
#include <device/pci.h>
|
#include <device/pci.h>
|
||||||
|
|
||||||
|
static uintptr_t read_pmc_mmio_bar(void)
|
||||||
|
{
|
||||||
|
uint32_t bar = pci_read_config32(PMC_DEV, PCI_BASE_ADDRESS_0);
|
||||||
|
return bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
static void print_num_status_bits(int num_bits, uint32_t status,
|
static void print_num_status_bits(int num_bits, uint32_t status,
|
||||||
const char * const bit_names[])
|
const char * const bit_names[])
|
||||||
|
@ -261,13 +269,14 @@ void clear_pmc_status(void)
|
||||||
{
|
{
|
||||||
uint32_t prsts;
|
uint32_t prsts;
|
||||||
uint32_t gen_pmcon1;
|
uint32_t gen_pmcon1;
|
||||||
|
uintptr_t pmc_bar0 = read_pmc_mmio_bar();
|
||||||
|
|
||||||
prsts = read32((void *)(PMC_BAR0 + PRSTS));
|
prsts = read32((void *)(pmc_bar0 + PRSTS));
|
||||||
gen_pmcon1 = read32((void *)(PMC_BAR0 + GEN_PMCON1));
|
gen_pmcon1 = read32((void *)(pmc_bar0 + GEN_PMCON1));
|
||||||
|
|
||||||
/* Clear the status bits. The RPS field is cleared on a 0 write. */
|
/* Clear the status bits. The RPS field is cleared on a 0 write. */
|
||||||
write32((void *)(PMC_BAR0 + GEN_PMCON1), gen_pmcon1 & ~RPS);
|
write32((void *)(pmc_bar0 + GEN_PMCON1), gen_pmcon1 & ~RPS);
|
||||||
write32((void *)(PMC_BAR0 + PRSTS), prsts);
|
write32((void *)(pmc_bar0 + PRSTS), prsts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -296,14 +305,16 @@ int chipset_prev_sleep_state(struct chipset_power_state *ps)
|
||||||
int fill_power_state(struct chipset_power_state *ps)
|
int fill_power_state(struct chipset_power_state *ps)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
uintptr_t pmc_bar0 = read_pmc_mmio_bar();
|
||||||
|
|
||||||
ps->pm1_sts = inw(ACPI_PMIO_BASE + PM1_STS);
|
ps->pm1_sts = inw(ACPI_PMIO_BASE + PM1_STS);
|
||||||
ps->pm1_en = inw(ACPI_PMIO_BASE + PM1_EN);
|
ps->pm1_en = inw(ACPI_PMIO_BASE + PM1_EN);
|
||||||
ps->pm1_cnt = inl(ACPI_PMIO_BASE + PM1_CNT);
|
ps->pm1_cnt = inl(ACPI_PMIO_BASE + PM1_CNT);
|
||||||
ps->tco_sts = inl(ACPI_PMIO_BASE + TCO_STS);
|
ps->tco_sts = inl(ACPI_PMIO_BASE + TCO_STS);
|
||||||
ps->prsts = read32((void *)(PMC_BAR0 + PRSTS));
|
ps->prsts = read32((void *)(pmc_bar0 + PRSTS));
|
||||||
ps->gen_pmcon1 =read32((void *)(PMC_BAR0 + GEN_PMCON1));
|
ps->gen_pmcon1 =read32((void *)(pmc_bar0 + GEN_PMCON1));
|
||||||
ps->gen_pmcon2 = read32((void *)(PMC_BAR0 + GEN_PMCON2));
|
ps->gen_pmcon2 = read32((void *)(pmc_bar0 + GEN_PMCON2));
|
||||||
ps->gen_pmcon3 = read32((void *)(PMC_BAR0 + GEN_PMCON3));
|
ps->gen_pmcon3 = read32((void *)(pmc_bar0 + GEN_PMCON3));
|
||||||
|
|
||||||
ps->prev_sleep_state = chipset_prev_sleep_state(ps);
|
ps->prev_sleep_state = chipset_prev_sleep_state(ps);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue