From 21e4bd4e8cedcf11d2bf82fb727b0863c19aa310 Mon Sep 17 00:00:00 2001 From: "henryc.chen" Date: Thu, 4 Mar 2021 09:44:42 +0800 Subject: 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 Change-Id: I4fb9f7245d44383a6a3a0cf8d00f7f503cbdeb06 Reviewed-on: https://review.coreboot.org/c/coreboot/+/55575 Reviewed-by: Yu-Ping Wu Reviewed-by: Hung-Te Lin Tested-by: build bot (Jenkins) --- src/soc/mediatek/mt8195/Makefile.inc | 1 + src/soc/mediatek/mt8195/include/soc/mt6691.h | 37 ++++++++++++++ src/soc/mediatek/mt8195/mt6691.c | 74 ++++++++++++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 src/soc/mediatek/mt8195/include/soc/mt6691.h create mode 100644 src/soc/mediatek/mt8195/mt6691.c (limited to 'src/soc/mediatek/mt8195') 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 + +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 +#include +#include + +#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); +} -- cgit v1.2.3