xref: /rk3399_ARM-atf/drivers/st/pmic/stm32mp_pmic.c (revision 1fc2130c5b8aad9abf54d71ce0124b19f44c69ce)
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