diff options
-rw-r--r-- | src/soc/mediatek/mt8173/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/mediatek/mt8173/include/soc/mt6311.h | 52 | ||||
-rw-r--r-- | src/soc/mediatek/mt8173/mt6311.c | 131 |
3 files changed, 184 insertions, 0 deletions
diff --git a/src/soc/mediatek/mt8173/Makefile.inc b/src/soc/mediatek/mt8173/Makefile.inc index e18e6fe311..6ba533adad 100644 --- a/src/soc/mediatek/mt8173/Makefile.inc +++ b/src/soc/mediatek/mt8173/Makefile.inc @@ -66,6 +66,7 @@ ramstage-y += soc.c mtcmos.c ramstage-y += timer.c ramstage-$(CONFIG_DRIVERS_UART) += uart.c ramstage-y += pmic_wrap.c mt6391.c i2c.c +ramstage-y += mt6311.c ramstage-y += gpio.c ramstage-y += wdt.c ramstage-y += pll.c diff --git a/src/soc/mediatek/mt8173/include/soc/mt6311.h b/src/soc/mediatek/mt8173/include/soc/mt6311.h new file mode 100644 index 0000000000..3b0b79a8c7 --- /dev/null +++ b/src/soc/mediatek/mt8173/include/soc/mt6311.h @@ -0,0 +1,52 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 MediaTek 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. + */ + +#ifndef __SOC_MEDIATEK_MT8173_MT6311_H__ +#define __SOC_MEDIATEK_MT8173_MT6311_H__ + +void mt6311_probe(uint8_t i2c_num); + +enum { + MT6311_CID = 0x0, + MT6311_SWCID = 0x1, + MT6311_GPIO_MODE = 0x04, + MT6311_TOP_CON = 0x0A, + MT6311_TOP_RST_CON = 0x15, + MT6311_TOP_INT_CON = 0x18, + MT6311_STRUP_CON5 = 0x1F, + MT6311_EFUSE_DOUT_56_63 = 0x40, + MT6311_EFUSE_DOUT_64_71 = 0x41, + MT6311_BUCK_ALL_CON23 = 0x69, + MT6311_STRUP_ANA_CON1 = 0x6D, + MT6311_STRUP_ANA_CON2 = 0x6E, + MT6311_VDVFS1_ANA_CON10 = 0x84, + MT6311_VDVFS11_CON7 = 0x88, + MT6311_VDVFS11_CON9 = 0x8A, + MT6311_VDVFS11_CON10 = 0x8B, + MT6311_VDVFS11_CON11 = 0x8C, + MT6311_VDVFS11_CON12 = 0x8D, + MT6311_VDVFS11_CON13 = 0x8E, + MT6311_VDVFS11_CON14 = 0x8F, + MT6311_VDVFS11_CON19 = 0x94, + MT6311_LDO_CON3 = 0xCF, +}; + +enum { + MT6311_E1_CID_CODE = 0x0110, + MT6311_E2_CID_CODE = 0x0120, + MT6311_E3_CID_CODE = 0x0130, +}; + +#endif diff --git a/src/soc/mediatek/mt8173/mt6311.c b/src/soc/mediatek/mt8173/mt6311.c new file mode 100644 index 0000000000..8390dfd4d0 --- /dev/null +++ b/src/soc/mediatek/mt8173/mt6311.c @@ -0,0 +1,131 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 MediaTek 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 <console/console.h> +#include <device/i2c.h> +#include <soc/mt6311.h> + +enum { + MT6311_SLAVE_ADDR = 0x6B, +}; + +static u32 get_mt6311_chip_id(uint8_t i2c_num) +{ + unsigned char id[2] = {0}; + + i2c_read_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_CID, + &id[0], 0xFF, 0); + i2c_read_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_SWCID, + &id[1], 0xFF, 0); + + return (u32)(id[0] << 8 | id[1]); +} + +static void mt6311_hw_init(uint8_t i2c_num) +{ + int ret = 0; + unsigned char var[3] = {0}; + + + /* + * Phase Shedding Trim Software Setting + * The phase 2 of MT6311 will enter PWM mode if the threshold is + * reached. + * The threshold is set according to EFUSE value. + */ + ret |= i2c_read_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_EFUSE_DOUT_56_63, &var[0], + 0x3, 1); + ret |= i2c_read_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_EFUSE_DOUT_56_63, &var[1], + 0x1, 7); + ret |= i2c_read_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_EFUSE_DOUT_64_71, &var[2], + 0x1, 0); + + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_VDVFS1_ANA_CON10, + var[0] | var[1] << 2 | var[2] << 3, 0xf, 0); + + /* I2C_CONFIG; pushpull setting, Opendrain is '0' */ + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_TOP_INT_CON, + 0x1, 0x1, 2); + /* RG_WDTRSTB_EN; CC, initial WDRSTB setting. */ + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_TOP_RST_CON, + 0x1, 0x1, 5); + /* initial INT function */ + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_GPIO_MODE, + 0x1, 0x7, 3); + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, MT6311_STRUP_CON5, + 0, 1 << 2 | 1 << 1 | 1 << 0, 0); + + /* Vo max is 1.15V */ + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_STRUP_ANA_CON1, 0x3, 0x3, 5); + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_BUCK_ALL_CON23, 0x1, 0x1, 0); + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_STRUP_ANA_CON2, 0x3, 0x3, 0); + /* Suspend HW control from SPM */ + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_TOP_CON, 0x1, 0x1, 0); + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_VDVFS11_CON7, 0x1, 0x1, 0); + /* default VDVFS power on */ + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_VDVFS11_CON9, 0x1, 0x1, 0); + /* for DVFS slew rate rising=0.67us */ + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_VDVFS11_CON10, 0x1, 0x7f, 0); + /* for DVFS slew rate, falling 2.0us */ + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_VDVFS11_CON11, 0x5, 0x7f, 0); + /* default VDVFS11_VOSEL 1.0V, SW control */ + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_VDVFS11_CON12, 0x40, 0x7f, 0); + /* default VDVFS11_VOSEL_ON 1.0V, HW control */ + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_VDVFS11_CON13, 0x40, 0x7f, 0); + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_VDVFS11_CON14, 0x40, 0x7f, 0); + /* for DVFS sof change, falling 50us */ + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_VDVFS11_CON19, 0x3, 0x3, 0); + /* for DVFS sof change, falling only */ + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_VDVFS11_CON19, 0x1, 0x3, 4); + /* OFF LDO */ + ret |= i2c_write_field(i2c_num, MT6311_SLAVE_ADDR, + MT6311_LDO_CON3, 0, 0x1, 0); + + if (ret) + printk(BIOS_ERR, "ERROR: %s failed\n", __func__); +} + +void mt6311_probe(uint8_t i2c_num) +{ + u32 val = 0; + + /* Check device ID is MT6311 */ + val = get_mt6311_chip_id(i2c_num); + printk(BIOS_INFO, "%s: device ID = %#x\n", __func__, val); + + if (val < MT6311_E1_CID_CODE) { + printk(BIOS_ERR, "ERROR: unknown MT6311 device_id\n"); + return; + } + + mt6311_hw_init(i2c_num); +} |