diff options
author | Hakim Giydan <hgiydan@marvell.com> | 2016-09-08 10:49:24 -0700 |
---|---|---|
committer | Martin Roth <martinroth@google.com> | 2016-09-13 16:57:42 +0200 |
commit | 53620b85be65f5582791ed670a3ccfa9bdcc86ee (patch) | |
tree | cc78feceb722a962fa57c7bb1aa4ca54931261d7 /src/soc/marvell/mvmap2315/apmu.c | |
parent | 93e6f1a917b6b17c6e62ad0fff1699416ab00d29 (diff) | |
download | coreboot-53620b85be65f5582791ed670a3ccfa9bdcc86ee.tar.xz |
soc/marvell/mvmap2315: Add APMU driver
APMU is the AP power management unit.
It is a separate processor that handles enabling
individual power rails.
This driver handles sending and receiving commands
from/to APMU.
Testing: booted successfully.
Change-Id: I5ae07849f8432bece8a0ae9066a3f786e6e8d2fe
Signed-off-by: Hakim Giydan <hgiydan@marvell.com>
Reviewed-on: https://review.coreboot.org/15518
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/soc/marvell/mvmap2315/apmu.c')
-rw-r--r-- | src/soc/marvell/mvmap2315/apmu.c | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/src/soc/marvell/mvmap2315/apmu.c b/src/soc/marvell/mvmap2315/apmu.c new file mode 100644 index 0000000000..d6cbc7f4e8 --- /dev/null +++ b/src/soc/marvell/mvmap2315/apmu.c @@ -0,0 +1,131 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 Marvell, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> + +#include <arch/io.h> +#include <console/console.h> +#include <soc/apmu.h> +#include <soc/clock.h> + +void apmu_start(void) +{ + u32 reg; + + printk(BIOS_DEBUG, "APMU init...\n"); + + /* TODO: remove in real silicon */ + write32(&mvmap2315_apmu_pwrctl->scratch0, 0x900dc0de); + + /* Dedicate LCM area to the APMU */ + reg = MVMAP2315_LCM_START_BANK | + MVMAP2315_LCM_END_BANK | + MVMAP2315_LCM_DIRACCESS_EN; + write32(&mvmap2315_lcm_regs->lcm_access, reg); + + /* Taking APMU out of reset */ + setbits_le32(&mvmap2315_apmu_clk->apaonclk_apmucpu_clkgenconfig, + MVMAP2315_APMU_CLK_EN); + + setbits_le32(&mvmap2315_apmu_clk->apaonclk_apmucpu_clkgenconfig, + MVMAP2315_APMU_CLK_RSTN); +} + +static int apmu_sending_cmd(u32 cmd) +{ + int success; + u32 timeout = 0; + + printk(BIOS_DEBUG, "sending cmd: %x\n", cmd); + + /* Send a sync command */ + write32(&mvmap2315_apmu_pwrctl->pwrcmdfifo, + cmd | MVMAP2315_APMU_PWRCMDFIFO_DONEIRQ); + + while (!(read32(&mvmap2315_apmu_pwrctl->intstatus) & + (MVMAP2315_APMU_ISTCLR_DONE | + MVMAP2315_APMU_ISTCLR_ERROR)) && + (timeout < MVMAP2315_APMU_PWRCMDFIFO_TIMEOUT)) + timeout++; + + if (timeout >= MVMAP2315_APMU_PWRCMDFIFO_TIMEOUT) { + printk(BIOS_DEBUG, "cmd Timed out\n"); + success = -2; + } + + if (read32(&mvmap2315_apmu_pwrctl->intstatus) & + MVMAP2315_APMU_ISTCLR_DONE) { + printk(BIOS_DEBUG, "Completed cmd: %x\n", + read32(&mvmap2315_apmu_pwrctl->doneirq)); + + setbits_le32(&mvmap2315_apmu_pwrctl->intstatusclear, + MVMAP2315_APMU_ISTCLR_DONE); + success = 0; + + } else if (read32(&mvmap2315_apmu_pwrctl->intstatus) & + MVMAP2315_APMU_ISTCLR_ERROR) { + printk(BIOS_DEBUG, "Error cmd: %x\n", + read32(&mvmap2315_apmu_pwrctl->errorirq)); + + setbits_le32(&mvmap2315_apmu_pwrctl->intstatusclear, + MVMAP2315_APMU_ISTCLR_ERROR); + + success = -1; + } + + return success; +} + +int apmu_set_dev(u32 dev, u32 state) +{ + u32 cmd; + + cmd = MVMAP2315_APMU_PWRCMDFIFO_DONEIRQ; + cmd |= MVMAP2315_APMU_OPCODE_PWRST << MVMAP2315_APMU_OPCODE_SHIFT; + cmd |= state << MVMAP2315_APMU_DEV_STATE_SHIFT; + cmd |= dev << MVMAP2315_APMU_DEV_OBJECT_SHIFT; + + return apmu_sending_cmd(cmd); +} + +int apmu_set_pll(u32 dev, u32 state, u32 freq) +{ + u32 cmd; + + cmd = MVMAP2315_APMU_PWRCMDFIFO_DONEIRQ; + cmd |= MVMAP2315_APMU_OPCODE_PWRST << MVMAP2315_APMU_OPCODE_SHIFT; + cmd |= freq << MVMAP2315_APMU_DEV_FREQ_SHIFT; + cmd |= state << MVMAP2315_APMU_DEV_STATE_SHIFT; + cmd |= dev << MVMAP2315_APMU_DEV_OBJECT_SHIFT; + + return apmu_sending_cmd(cmd); +} + + +int apmu_set_clk(u32 clk, u32 state, u32 div, u32 src) +{ + u32 cmd; + + cmd = MVMAP2315_APMU_PWRCMDFIFO_DONEIRQ; + cmd |= MVMAP2315_APMU_OPCODE_CLKST << MVMAP2315_APMU_OPCODE_SHIFT; + cmd |= state << MVMAP2315_APMU_CLK_STATE_SHIFT; + cmd |= div << MVMAP2315_APMU_CLK_DIV_SHIFT; + cmd |= src << MVMAP2315_APMU_CLK_SOURCE_SHIFT; + cmd |= clk << MVMAP2315_APMU_CLK_OBJECT_SHIFT; + + return apmu_sending_cmd(cmd); +} |