123684d0eSYann Gautier /* 223684d0eSYann Gautier * Copyright (c) 2017-2019, STMicroelectronics - All Rights Reserved 323684d0eSYann Gautier * 423684d0eSYann Gautier * SPDX-License-Identifier: BSD-3-Clause 523684d0eSYann Gautier */ 623684d0eSYann Gautier 723684d0eSYann Gautier #include <errno.h> 823684d0eSYann Gautier #include <stdbool.h> 923684d0eSYann Gautier 1023684d0eSYann Gautier #include <libfdt.h> 1123684d0eSYann Gautier 1223684d0eSYann Gautier #include <platform_def.h> 1323684d0eSYann Gautier 1423684d0eSYann Gautier #include <common/debug.h> 1523684d0eSYann Gautier #include <drivers/delay_timer.h> 1623684d0eSYann Gautier #include <drivers/st/stm32mp_pmic.h> 1723684d0eSYann Gautier #include <drivers/st/stm32_gpio.h> 1823684d0eSYann Gautier #include <drivers/st/stm32mp1_clk.h> 1923684d0eSYann Gautier #include <drivers/st/stpmic1.h> 2023684d0eSYann Gautier #include <lib/mmio.h> 2123684d0eSYann Gautier #include <lib/utils_def.h> 2223684d0eSYann Gautier 2323684d0eSYann Gautier /* I2C Timing hard-coded value, for I2C clock source is HSI at 64MHz */ 2423684d0eSYann Gautier #define I2C_TIMING 0x10D07DB5 2523684d0eSYann Gautier 2623684d0eSYann Gautier #define I2C_TIMEOUT 0xFFFFF 2723684d0eSYann Gautier 2823684d0eSYann Gautier #define MASK_RESET_BUCK3 BIT(2) 2923684d0eSYann Gautier 3023684d0eSYann Gautier #define STPMIC1_LDO12356_OUTPUT_MASK (uint8_t)(GENMASK(6, 2)) 3123684d0eSYann Gautier #define STPMIC1_LDO12356_OUTPUT_SHIFT 2 3223684d0eSYann Gautier #define STPMIC1_LDO3_MODE (uint8_t)(BIT(7)) 3323684d0eSYann Gautier #define STPMIC1_LDO3_DDR_SEL 31U 3423684d0eSYann Gautier #define STPMIC1_LDO3_1800000 (9U << STPMIC1_LDO12356_OUTPUT_SHIFT) 3523684d0eSYann Gautier 3623684d0eSYann Gautier #define STPMIC1_BUCK_OUTPUT_SHIFT 2 3723684d0eSYann Gautier #define STPMIC1_BUCK3_1V8 (39U << STPMIC1_BUCK_OUTPUT_SHIFT) 3823684d0eSYann Gautier 3923684d0eSYann Gautier #define STPMIC1_DEFAULT_START_UP_DELAY_MS 1 4023684d0eSYann Gautier 4123684d0eSYann Gautier static struct i2c_handle_s i2c_handle; 4223684d0eSYann Gautier static uint32_t pmic_i2c_addr; 4323684d0eSYann Gautier 4423684d0eSYann Gautier static int dt_get_pmic_node(void *fdt) 4523684d0eSYann Gautier { 4623684d0eSYann Gautier return fdt_node_offset_by_compatible(fdt, -1, "st,stpmic1"); 4723684d0eSYann Gautier } 4823684d0eSYann Gautier 4923684d0eSYann Gautier bool dt_check_pmic(void) 5023684d0eSYann Gautier { 5123684d0eSYann Gautier int node; 5223684d0eSYann Gautier void *fdt; 5323684d0eSYann Gautier 5423684d0eSYann Gautier if (fdt_get_address(&fdt) == 0) { 5523684d0eSYann Gautier return false; 5623684d0eSYann Gautier } 5723684d0eSYann Gautier 5823684d0eSYann Gautier node = dt_get_pmic_node(fdt); 5923684d0eSYann Gautier if (node < 0) { 6023684d0eSYann Gautier VERBOSE("%s: No PMIC node found in DT\n", __func__); 6123684d0eSYann Gautier return false; 6223684d0eSYann Gautier } 6323684d0eSYann Gautier 64*1fc2130cSYann Gautier return fdt_get_status(node); 6523684d0eSYann Gautier } 6623684d0eSYann Gautier 6723684d0eSYann Gautier static int dt_pmic_i2c_config(struct dt_node_info *i2c_info) 6823684d0eSYann Gautier { 6923684d0eSYann Gautier int pmic_node, i2c_node; 7023684d0eSYann Gautier void *fdt; 7123684d0eSYann Gautier const fdt32_t *cuint; 7223684d0eSYann Gautier 7323684d0eSYann Gautier if (fdt_get_address(&fdt) == 0) { 7423684d0eSYann Gautier return -ENOENT; 7523684d0eSYann Gautier } 7623684d0eSYann Gautier 7723684d0eSYann Gautier pmic_node = dt_get_pmic_node(fdt); 7823684d0eSYann Gautier if (pmic_node < 0) { 7923684d0eSYann Gautier return -FDT_ERR_NOTFOUND; 8023684d0eSYann Gautier } 8123684d0eSYann Gautier 8223684d0eSYann Gautier cuint = fdt_getprop(fdt, pmic_node, "reg", NULL); 8323684d0eSYann Gautier if (cuint == NULL) { 8423684d0eSYann Gautier return -FDT_ERR_NOTFOUND; 8523684d0eSYann Gautier } 8623684d0eSYann Gautier 8723684d0eSYann Gautier pmic_i2c_addr = fdt32_to_cpu(*cuint) << 1; 8823684d0eSYann Gautier if (pmic_i2c_addr > UINT16_MAX) { 8923684d0eSYann Gautier return -EINVAL; 9023684d0eSYann Gautier } 9123684d0eSYann Gautier 9223684d0eSYann Gautier i2c_node = fdt_parent_offset(fdt, pmic_node); 9323684d0eSYann Gautier if (i2c_node < 0) { 9423684d0eSYann Gautier return -FDT_ERR_NOTFOUND; 9523684d0eSYann Gautier } 9623684d0eSYann Gautier 9723684d0eSYann Gautier dt_fill_device_info(i2c_info, i2c_node); 9823684d0eSYann Gautier if (i2c_info->base == 0U) { 9923684d0eSYann Gautier return -FDT_ERR_NOTFOUND; 10023684d0eSYann Gautier } 10123684d0eSYann Gautier 10223684d0eSYann Gautier return dt_set_pinctrl_config(i2c_node); 10323684d0eSYann Gautier } 10423684d0eSYann Gautier 10523684d0eSYann Gautier int dt_pmic_enable_boot_on_regulators(void) 10623684d0eSYann Gautier { 10723684d0eSYann Gautier int pmic_node, regulators_node, regulator_node; 10823684d0eSYann Gautier void *fdt; 10923684d0eSYann Gautier 11023684d0eSYann Gautier if (fdt_get_address(&fdt) == 0) { 11123684d0eSYann Gautier return -ENOENT; 11223684d0eSYann Gautier } 11323684d0eSYann Gautier 11423684d0eSYann Gautier pmic_node = dt_get_pmic_node(fdt); 11523684d0eSYann Gautier if (pmic_node < 0) { 11623684d0eSYann Gautier return -FDT_ERR_NOTFOUND; 11723684d0eSYann Gautier } 11823684d0eSYann Gautier 11923684d0eSYann Gautier regulators_node = fdt_subnode_offset(fdt, pmic_node, "regulators"); 12023684d0eSYann Gautier 12123684d0eSYann Gautier fdt_for_each_subnode(regulator_node, fdt, regulators_node) { 12223684d0eSYann Gautier const fdt32_t *cuint; 12323684d0eSYann Gautier const char *node_name; 12423684d0eSYann Gautier uint16_t voltage; 12523684d0eSYann Gautier 12623684d0eSYann Gautier if (fdt_getprop(fdt, regulator_node, "regulator-boot-on", 12723684d0eSYann Gautier NULL) == NULL) { 12823684d0eSYann Gautier continue; 12923684d0eSYann Gautier } 13023684d0eSYann Gautier 13123684d0eSYann Gautier cuint = fdt_getprop(fdt, regulator_node, 13223684d0eSYann Gautier "regulator-min-microvolt", NULL); 13323684d0eSYann Gautier if (cuint == NULL) { 13423684d0eSYann Gautier continue; 13523684d0eSYann Gautier } 13623684d0eSYann Gautier 13723684d0eSYann Gautier /* DT uses microvolts, whereas driver awaits millivolts */ 13823684d0eSYann Gautier voltage = (uint16_t)(fdt32_to_cpu(*cuint) / 1000U); 13923684d0eSYann Gautier node_name = fdt_get_name(fdt, regulator_node, NULL); 14023684d0eSYann Gautier 14123684d0eSYann Gautier if (stpmic1_is_regulator_enabled(node_name) == 0U) { 14223684d0eSYann Gautier int status; 14323684d0eSYann Gautier 14423684d0eSYann Gautier status = stpmic1_regulator_voltage_set(node_name, 14523684d0eSYann Gautier voltage); 14623684d0eSYann Gautier if (status != 0) { 14723684d0eSYann Gautier return status; 14823684d0eSYann Gautier } 14923684d0eSYann Gautier 15023684d0eSYann Gautier status = stpmic1_regulator_enable(node_name); 15123684d0eSYann Gautier if (status != 0) { 15223684d0eSYann Gautier return status; 15323684d0eSYann Gautier } 15423684d0eSYann Gautier } 15523684d0eSYann Gautier } 15623684d0eSYann Gautier 15723684d0eSYann Gautier return 0; 15823684d0eSYann Gautier } 15923684d0eSYann Gautier 16023684d0eSYann Gautier void initialize_pmic_i2c(void) 16123684d0eSYann Gautier { 16223684d0eSYann Gautier int ret; 16323684d0eSYann Gautier struct dt_node_info i2c_info; 16423684d0eSYann Gautier 16523684d0eSYann Gautier if (dt_pmic_i2c_config(&i2c_info) != 0) { 16623684d0eSYann Gautier ERROR("I2C configuration failed\n"); 16723684d0eSYann Gautier panic(); 16823684d0eSYann Gautier } 16923684d0eSYann Gautier 17023684d0eSYann Gautier if (stm32mp1_clk_enable((uint32_t)i2c_info.clock) < 0) { 17123684d0eSYann Gautier ERROR("I2C clock enable failed\n"); 17223684d0eSYann Gautier panic(); 17323684d0eSYann Gautier } 17423684d0eSYann Gautier 17523684d0eSYann Gautier /* Initialize PMIC I2C */ 17623684d0eSYann Gautier i2c_handle.i2c_base_addr = i2c_info.base; 17723684d0eSYann Gautier i2c_handle.i2c_init.timing = I2C_TIMING; 17823684d0eSYann Gautier i2c_handle.i2c_init.own_address1 = pmic_i2c_addr; 17923684d0eSYann Gautier i2c_handle.i2c_init.addressing_mode = I2C_ADDRESSINGMODE_7BIT; 18023684d0eSYann Gautier i2c_handle.i2c_init.dual_address_mode = I2C_DUALADDRESS_DISABLE; 18123684d0eSYann Gautier i2c_handle.i2c_init.own_address2 = 0; 18223684d0eSYann Gautier i2c_handle.i2c_init.own_address2_masks = I2C_OAR2_OA2NOMASK; 18323684d0eSYann Gautier i2c_handle.i2c_init.general_call_mode = I2C_GENERALCALL_DISABLE; 18423684d0eSYann Gautier i2c_handle.i2c_init.no_stretch_mode = I2C_NOSTRETCH_DISABLE; 18523684d0eSYann Gautier 18623684d0eSYann Gautier ret = stm32_i2c_init(&i2c_handle); 18723684d0eSYann Gautier if (ret != 0) { 18823684d0eSYann Gautier ERROR("Cannot initialize I2C %x (%d)\n", 18923684d0eSYann Gautier i2c_handle.i2c_base_addr, ret); 19023684d0eSYann Gautier panic(); 19123684d0eSYann Gautier } 19223684d0eSYann Gautier 19323684d0eSYann Gautier ret = stm32_i2c_config_analog_filter(&i2c_handle, 19423684d0eSYann Gautier I2C_ANALOGFILTER_ENABLE); 19523684d0eSYann Gautier if (ret != 0) { 19623684d0eSYann Gautier ERROR("Cannot initialize I2C analog filter (%d)\n", ret); 19723684d0eSYann Gautier panic(); 19823684d0eSYann Gautier } 19923684d0eSYann Gautier 20023684d0eSYann Gautier ret = stm32_i2c_is_device_ready(&i2c_handle, (uint16_t)pmic_i2c_addr, 1, 20123684d0eSYann Gautier I2C_TIMEOUT); 20223684d0eSYann Gautier if (ret != 0) { 20323684d0eSYann Gautier ERROR("I2C device not ready (%d)\n", ret); 20423684d0eSYann Gautier panic(); 20523684d0eSYann Gautier } 20623684d0eSYann Gautier 20723684d0eSYann Gautier stpmic1_bind_i2c(&i2c_handle, (uint16_t)pmic_i2c_addr); 20823684d0eSYann Gautier } 20923684d0eSYann Gautier 21023684d0eSYann Gautier void initialize_pmic(void) 21123684d0eSYann Gautier { 21223684d0eSYann Gautier int status; 21323684d0eSYann Gautier uint8_t read_val; 21423684d0eSYann Gautier 21523684d0eSYann Gautier initialize_pmic_i2c(); 21623684d0eSYann Gautier 21723684d0eSYann Gautier status = stpmic1_register_read(VERSION_STATUS_REG, &read_val); 21823684d0eSYann Gautier if (status != 0) { 21923684d0eSYann Gautier panic(); 22023684d0eSYann Gautier } 22123684d0eSYann Gautier 22223684d0eSYann Gautier INFO("PMIC version = 0x%x\n", read_val); 22323684d0eSYann Gautier 22423684d0eSYann Gautier /* Keep VDD on during the reset cycle */ 22523684d0eSYann Gautier status = stpmic1_register_update(MASK_RESET_BUCK_REG, 22623684d0eSYann Gautier MASK_RESET_BUCK3, 22723684d0eSYann Gautier MASK_RESET_BUCK3); 22823684d0eSYann Gautier if (status != 0) { 22923684d0eSYann Gautier panic(); 23023684d0eSYann Gautier } 23123684d0eSYann Gautier } 23223684d0eSYann Gautier 23323684d0eSYann Gautier int pmic_ddr_power_init(enum ddr_type ddr_type) 23423684d0eSYann Gautier { 23523684d0eSYann Gautier bool buck3_at_1v8 = false; 23623684d0eSYann Gautier uint8_t read_val; 23723684d0eSYann Gautier int status; 23823684d0eSYann Gautier 23923684d0eSYann Gautier switch (ddr_type) { 24023684d0eSYann Gautier case STM32MP_DDR3: 24123684d0eSYann Gautier /* Set LDO3 to sync mode */ 24223684d0eSYann Gautier status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val); 24323684d0eSYann Gautier if (status != 0) { 24423684d0eSYann Gautier return status; 24523684d0eSYann Gautier } 24623684d0eSYann Gautier 24723684d0eSYann Gautier read_val &= ~STPMIC1_LDO3_MODE; 24823684d0eSYann Gautier read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK; 24923684d0eSYann Gautier read_val |= STPMIC1_LDO3_DDR_SEL << 25023684d0eSYann Gautier STPMIC1_LDO12356_OUTPUT_SHIFT; 25123684d0eSYann Gautier 25223684d0eSYann Gautier status = stpmic1_register_write(LDO3_CONTROL_REG, read_val); 25323684d0eSYann Gautier if (status != 0) { 25423684d0eSYann Gautier return status; 25523684d0eSYann Gautier } 25623684d0eSYann Gautier 25723684d0eSYann Gautier status = stpmic1_regulator_voltage_set("buck2", 1350); 25823684d0eSYann Gautier if (status != 0) { 25923684d0eSYann Gautier return status; 26023684d0eSYann Gautier } 26123684d0eSYann Gautier 26223684d0eSYann Gautier status = stpmic1_regulator_enable("buck2"); 26323684d0eSYann Gautier if (status != 0) { 26423684d0eSYann Gautier return status; 26523684d0eSYann Gautier } 26623684d0eSYann Gautier 26723684d0eSYann Gautier mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); 26823684d0eSYann Gautier 26923684d0eSYann Gautier status = stpmic1_regulator_enable("vref_ddr"); 27023684d0eSYann Gautier if (status != 0) { 27123684d0eSYann Gautier return status; 27223684d0eSYann Gautier } 27323684d0eSYann Gautier 27423684d0eSYann Gautier mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); 27523684d0eSYann Gautier 27623684d0eSYann Gautier status = stpmic1_regulator_enable("ldo3"); 27723684d0eSYann Gautier if (status != 0) { 27823684d0eSYann Gautier return status; 27923684d0eSYann Gautier } 28023684d0eSYann Gautier 28123684d0eSYann Gautier mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); 28223684d0eSYann Gautier break; 28323684d0eSYann Gautier 28423684d0eSYann Gautier case STM32MP_LPDDR2: 28523684d0eSYann Gautier /* 28623684d0eSYann Gautier * Set LDO3 to 1.8V 28723684d0eSYann Gautier * Set LDO3 to bypass mode if BUCK3 = 1.8V 28823684d0eSYann Gautier * Set LDO3 to normal mode if BUCK3 != 1.8V 28923684d0eSYann Gautier */ 29023684d0eSYann Gautier status = stpmic1_register_read(BUCK3_CONTROL_REG, &read_val); 29123684d0eSYann Gautier if (status != 0) { 29223684d0eSYann Gautier return status; 29323684d0eSYann Gautier } 29423684d0eSYann Gautier 29523684d0eSYann Gautier if ((read_val & STPMIC1_BUCK3_1V8) == STPMIC1_BUCK3_1V8) { 29623684d0eSYann Gautier buck3_at_1v8 = true; 29723684d0eSYann Gautier } 29823684d0eSYann Gautier 29923684d0eSYann Gautier status = stpmic1_register_read(LDO3_CONTROL_REG, &read_val); 30023684d0eSYann Gautier if (status != 0) { 30123684d0eSYann Gautier return status; 30223684d0eSYann Gautier } 30323684d0eSYann Gautier 30423684d0eSYann Gautier read_val &= ~STPMIC1_LDO3_MODE; 30523684d0eSYann Gautier read_val &= ~STPMIC1_LDO12356_OUTPUT_MASK; 30623684d0eSYann Gautier read_val |= STPMIC1_LDO3_1800000; 30723684d0eSYann Gautier if (buck3_at_1v8) { 30823684d0eSYann Gautier read_val |= STPMIC1_LDO3_MODE; 30923684d0eSYann Gautier } 31023684d0eSYann Gautier 31123684d0eSYann Gautier status = stpmic1_register_write(LDO3_CONTROL_REG, read_val); 31223684d0eSYann Gautier if (status != 0) { 31323684d0eSYann Gautier return status; 31423684d0eSYann Gautier } 31523684d0eSYann Gautier 31623684d0eSYann Gautier status = stpmic1_regulator_voltage_set("buck2", 1200); 31723684d0eSYann Gautier if (status != 0) { 31823684d0eSYann Gautier return status; 31923684d0eSYann Gautier } 32023684d0eSYann Gautier 32123684d0eSYann Gautier status = stpmic1_regulator_enable("ldo3"); 32223684d0eSYann Gautier if (status != 0) { 32323684d0eSYann Gautier return status; 32423684d0eSYann Gautier } 32523684d0eSYann Gautier 32623684d0eSYann Gautier mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); 32723684d0eSYann Gautier 32823684d0eSYann Gautier status = stpmic1_regulator_enable("buck2"); 32923684d0eSYann Gautier if (status != 0) { 33023684d0eSYann Gautier return status; 33123684d0eSYann Gautier } 33223684d0eSYann Gautier 33323684d0eSYann Gautier mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); 33423684d0eSYann Gautier 33523684d0eSYann Gautier status = stpmic1_regulator_enable("vref_ddr"); 33623684d0eSYann Gautier if (status != 0) { 33723684d0eSYann Gautier return status; 33823684d0eSYann Gautier } 33923684d0eSYann Gautier 34023684d0eSYann Gautier mdelay(STPMIC1_DEFAULT_START_UP_DELAY_MS); 34123684d0eSYann Gautier break; 34223684d0eSYann Gautier 34323684d0eSYann Gautier default: 34423684d0eSYann Gautier break; 34523684d0eSYann Gautier }; 34623684d0eSYann Gautier 34723684d0eSYann Gautier return 0; 34823684d0eSYann Gautier } 349