diff options
author | henryc.chen <henryc.chen@mediatek.com> | 2021-03-04 09:44:42 +0800 |
---|---|---|
committer | Hung-Te Lin <hungte@chromium.org> | 2021-06-18 08:47:06 +0000 |
commit | 21e4bd4e8cedcf11d2bf82fb727b0863c19aa310 (patch) | |
tree | ada0f1e487a4ee6456eacb95b2599230cc1a25ee /src | |
parent | f2c259cf2a16714bd2695507b9241080de660e05 (diff) |
soc/mediatek/mt8195: add mt6691 driver
Add mt6691 buck control for DRAM to run fast calibration test.
It is needed to get and set voltage during testing.
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
Change-Id: I4fb9f7245d44383a6a3a0cf8d00f7f503cbdeb06
Reviewed-on: https://review.coreboot.org/c/coreboot/+/55575
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Reviewed-by: Hung-Te Lin <hungte@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/soc/mediatek/mt8195/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/mediatek/mt8195/include/soc/mt6691.h | 37 | ||||
-rw-r--r-- | src/soc/mediatek/mt8195/mt6691.c | 74 |
3 files changed, 112 insertions, 0 deletions
diff --git a/src/soc/mediatek/mt8195/Makefile.inc b/src/soc/mediatek/mt8195/Makefile.inc index 181e99c91d..e584620868 100644 --- a/src/soc/mediatek/mt8195/Makefile.inc +++ b/src/soc/mediatek/mt8195/Makefile.inc @@ -45,6 +45,7 @@ romstage-y += ../common/pmif_spi.c pmif_spi.c romstage-y += ../common/pmif_spmi.c pmif_spmi.c romstage-y += ../common/mt6315.c mt6315.c romstage-y += ../common/mt6359p.c mt6359p.c +romstage-y += mt6691.c romstage-y += ../common/rtc.c ../common/rtc_osc_init.c ../common/rtc_mt6359p.c ramstage-y += ../common/auxadc.c diff --git a/src/soc/mediatek/mt8195/include/soc/mt6691.h b/src/soc/mediatek/mt8195/include/soc/mt6691.h new file mode 100644 index 0000000000..c347c41d93 --- /dev/null +++ b/src/soc/mediatek/mt8195/include/soc/mt6691.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __SOC_MEDIATEK_MT8195_MT6691_H__ +#define __SOC_MEDIATEK_MT8195_MT6691_H__ + +#include <stdint.h> + +void mt6691_probe(uint8_t i2c_num); +int mt6691_set_voltage(uint8_t i2c_num, unsigned int volt_uv); +int mt6691_get_voltage(uint8_t i2c_num); + +#define MT6691_CID_CODE 0x01 + +#define MT6691_VDD2_ID 0x0000 +#define MT6691_VDDQ_ID 0x0000 +#define MT6691_PGOOD_SHIFT 7 +#define MT6691_DN_SR_MASK 0x7 +#define MT6691_DN_SR_SHIFT 5 + +enum { + /* Voltage setting */ + MT6691_VSEL0 = 0x00, + MT6691_VSEL1 = 0x01, + /* Control register */ + MT6691_CONTROL = 0x02, + /* IC Type */ + MT6691_ID1 = 0x03, + /* IC mask version */ + MT6691_ID2 = 0x04, + /* Monitor register */ + MT6691_MONITOR = 0x05, + MT6691_CTRL2 = 0x06, + MT6691_CTRL3 = 0x07, + MT6691_CTRL4 = 0x08, +}; + +#endif diff --git a/src/soc/mediatek/mt8195/mt6691.c b/src/soc/mediatek/mt8195/mt6691.c new file mode 100644 index 0000000000..3f224215ef --- /dev/null +++ b/src/soc/mediatek/mt8195/mt6691.c @@ -0,0 +1,74 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/i2c_simple.h> +#include <soc/mt6691.h> + +#define MT6691_MIN_VOLTAGE 300000 +#define MT6691_MAX_VOLTAGE 1300000 +#define MT6691_STEP_UV 5000 + +enum { + MT6691_SLAVE_ADDR = 0x51, +}; + +int mt6691_set_voltage(uint8_t i2c_num, unsigned int volt_uv) +{ + uint8_t selector; + + if (volt_uv > MT6691_MAX_VOLTAGE || volt_uv < MT6691_MIN_VOLTAGE) { + printk(BIOS_ERR, "%s: voltage out of range\n", __func__); + return -1; + } + + selector = DIV_ROUND_UP(volt_uv - MT6691_MIN_VOLTAGE, MT6691_STEP_UV); + + return i2c_write_field(i2c_num, MT6691_SLAVE_ADDR, + MT6691_VSEL0, selector, 0xFF, 0); +} + +int mt6691_get_voltage(uint8_t i2c_num) +{ + uint8_t selector = 0; + unsigned int volt; + + if (i2c_read_field(i2c_num, MT6691_SLAVE_ADDR, MT6691_VSEL0, + &selector, 0xFF, 0) < 0) { + printk(BIOS_ERR, "%s: failed to get voltage from i2c\n", __func__); + return -1; + } + + volt = (selector * MT6691_STEP_UV) + MT6691_MIN_VOLTAGE; + + if (volt > MT6691_MAX_VOLTAGE) { + printk(BIOS_ERR, "%s: voltage out of range\n", __func__); + return -1; + } + + return volt; +} + +static uint8_t get_mt6691_chip_id(uint8_t i2c_num) +{ + uint8_t id; + + if (i2c_read_field(i2c_num, MT6691_SLAVE_ADDR, MT6691_MONITOR, + &id, 0x1, MT6691_PGOOD_SHIFT) < 0) { + printk(BIOS_ERR, "%s: failed to read from i2c", __func__); + return 0; + } + + return id; +} + +void mt6691_probe(uint8_t i2c_num) +{ + /* Check device ID is MT6691 */ + if (!get_mt6691_chip_id(i2c_num)) { + printk(BIOS_ERR, "ERROR: unknown MT6691 chip_id\n"); + return; + } + /* Slew rate 12mV */ + i2c_write_field(i2c_num, MT6691_SLAVE_ADDR, MT6691_CTRL2, 0x1, + MT6691_DN_SR_MASK, MT6691_DN_SR_SHIFT); +} |