/* * 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 #include #include #include #include #include #include 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); }