cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

omap_twl.c (6852B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * OMAP and TWL PMIC specific initializations.
      4 *
      5 * Copyright (C) 2010 Texas Instruments Incorporated.
      6 * Thara Gopinath
      7 * Copyright (C) 2009 Texas Instruments Incorporated.
      8 * Nishanth Menon
      9 * Copyright (C) 2009 Nokia Corporation
     10 * Paul Walmsley
     11 */
     12
     13#include <linux/err.h>
     14#include <linux/io.h>
     15#include <linux/kernel.h>
     16#include <linux/mfd/twl.h>
     17
     18#include "soc.h"
     19#include "voltage.h"
     20
     21#include "pm.h"
     22
     23#define OMAP3_SRI2C_SLAVE_ADDR		0x12
     24#define OMAP3_VDD_MPU_SR_CONTROL_REG	0x00
     25#define OMAP3_VDD_CORE_SR_CONTROL_REG	0x01
     26#define OMAP3_VP_CONFIG_ERROROFFSET	0x00
     27#define OMAP3_VP_VSTEPMIN_VSTEPMIN	0x1
     28#define OMAP3_VP_VSTEPMAX_VSTEPMAX	0x04
     29#define OMAP3_VP_VLIMITTO_TIMEOUT_US	200
     30
     31#define OMAP4_SRI2C_SLAVE_ADDR		0x12
     32#define OMAP4_VDD_MPU_SR_VOLT_REG	0x55
     33#define OMAP4_VDD_MPU_SR_CMD_REG	0x56
     34#define OMAP4_VDD_IVA_SR_VOLT_REG	0x5B
     35#define OMAP4_VDD_IVA_SR_CMD_REG	0x5C
     36#define OMAP4_VDD_CORE_SR_VOLT_REG	0x61
     37#define OMAP4_VDD_CORE_SR_CMD_REG	0x62
     38
     39static bool is_offset_valid;
     40static u8 smps_offset;
     41
     42#define REG_SMPS_OFFSET         0xE0
     43
     44static unsigned long twl4030_vsel_to_uv(const u8 vsel)
     45{
     46	return (((vsel * 125) + 6000)) * 100;
     47}
     48
     49static u8 twl4030_uv_to_vsel(unsigned long uv)
     50{
     51	return DIV_ROUND_UP(uv - 600000, 12500);
     52}
     53
     54static unsigned long twl6030_vsel_to_uv(const u8 vsel)
     55{
     56	/*
     57	 * In TWL6030 depending on the value of SMPS_OFFSET
     58	 * efuse register the voltage range supported in
     59	 * standard mode can be either between 0.6V - 1.3V or
     60	 * 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse
     61	 * is programmed to all 0's where as starting from
     62	 * TWL6030 ES1.1 the efuse is programmed to 1
     63	 */
     64	if (!is_offset_valid) {
     65		twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset,
     66				REG_SMPS_OFFSET);
     67		is_offset_valid = true;
     68	}
     69
     70	if (!vsel)
     71		return 0;
     72	/*
     73	 * There is no specific formula for voltage to vsel
     74	 * conversion above 1.3V. There are special hardcoded
     75	 * values for voltages above 1.3V. Currently we are
     76	 * hardcoding only for 1.35 V which is used for 1GH OPP for
     77	 * OMAP4430.
     78	 */
     79	if (vsel == 0x3A)
     80		return 1350000;
     81
     82	if (smps_offset & 0x8)
     83		return ((((vsel - 1) * 1266) + 70900)) * 10;
     84	else
     85		return ((((vsel - 1) * 1266) + 60770)) * 10;
     86}
     87
     88static u8 twl6030_uv_to_vsel(unsigned long uv)
     89{
     90	/*
     91	 * In TWL6030 depending on the value of SMPS_OFFSET
     92	 * efuse register the voltage range supported in
     93	 * standard mode can be either between 0.6V - 1.3V or
     94	 * 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse
     95	 * is programmed to all 0's where as starting from
     96	 * TWL6030 ES1.1 the efuse is programmed to 1
     97	 */
     98	if (!is_offset_valid) {
     99		twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset,
    100				REG_SMPS_OFFSET);
    101		is_offset_valid = true;
    102	}
    103
    104	if (!uv)
    105		return 0x00;
    106	/*
    107	 * There is no specific formula for voltage to vsel
    108	 * conversion above 1.3V. There are special hardcoded
    109	 * values for voltages above 1.3V. Currently we are
    110	 * hardcoding only for 1.35 V which is used for 1GH OPP for
    111	 * OMAP4430.
    112	 */
    113	if (uv > twl6030_vsel_to_uv(0x39)) {
    114		if (uv == 1350000)
    115			return 0x3A;
    116		pr_err("%s:OUT OF RANGE! non mapped vsel for %ld Vs max %ld\n",
    117			__func__, uv, twl6030_vsel_to_uv(0x39));
    118		return 0x3A;
    119	}
    120
    121	if (smps_offset & 0x8)
    122		return DIV_ROUND_UP(uv - 709000, 12660) + 1;
    123	else
    124		return DIV_ROUND_UP(uv - 607700, 12660) + 1;
    125}
    126
    127static struct omap_voltdm_pmic omap3_mpu_pmic = {
    128	.slew_rate		= 4000,
    129	.step_size		= 12500,
    130	.vp_erroroffset		= OMAP3_VP_CONFIG_ERROROFFSET,
    131	.vp_vstepmin		= OMAP3_VP_VSTEPMIN_VSTEPMIN,
    132	.vp_vstepmax		= OMAP3_VP_VSTEPMAX_VSTEPMAX,
    133	.vddmin			= 600000,
    134	.vddmax			= 1450000,
    135	.vp_timeout_us		= OMAP3_VP_VLIMITTO_TIMEOUT_US,
    136	.i2c_slave_addr		= OMAP3_SRI2C_SLAVE_ADDR,
    137	.volt_reg_addr		= OMAP3_VDD_MPU_SR_CONTROL_REG,
    138	.i2c_high_speed		= true,
    139	.vsel_to_uv		= twl4030_vsel_to_uv,
    140	.uv_to_vsel		= twl4030_uv_to_vsel,
    141};
    142
    143static struct omap_voltdm_pmic omap3_core_pmic = {
    144	.slew_rate		= 4000,
    145	.step_size		= 12500,
    146	.vp_erroroffset		= OMAP3_VP_CONFIG_ERROROFFSET,
    147	.vp_vstepmin		= OMAP3_VP_VSTEPMIN_VSTEPMIN,
    148	.vp_vstepmax		= OMAP3_VP_VSTEPMAX_VSTEPMAX,
    149	.vddmin			= 600000,
    150	.vddmax			= 1450000,
    151	.vp_timeout_us		= OMAP3_VP_VLIMITTO_TIMEOUT_US,
    152	.i2c_slave_addr		= OMAP3_SRI2C_SLAVE_ADDR,
    153	.volt_reg_addr		= OMAP3_VDD_CORE_SR_CONTROL_REG,
    154	.i2c_high_speed		= true,
    155	.vsel_to_uv		= twl4030_vsel_to_uv,
    156	.uv_to_vsel		= twl4030_uv_to_vsel,
    157};
    158
    159static struct omap_voltdm_pmic omap4_mpu_pmic = {
    160	.slew_rate		= 4000,
    161	.step_size		= 12660,
    162	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
    163	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
    164	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
    165	.vddmin			= 0,
    166	.vddmax			= 2100000,
    167	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
    168	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
    169	.volt_reg_addr		= OMAP4_VDD_MPU_SR_VOLT_REG,
    170	.cmd_reg_addr		= OMAP4_VDD_MPU_SR_CMD_REG,
    171	.i2c_high_speed		= true,
    172	.i2c_pad_load		= 3,
    173	.vsel_to_uv		= twl6030_vsel_to_uv,
    174	.uv_to_vsel		= twl6030_uv_to_vsel,
    175};
    176
    177static struct omap_voltdm_pmic omap4_iva_pmic = {
    178	.slew_rate		= 4000,
    179	.step_size		= 12660,
    180	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
    181	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
    182	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
    183	.vddmin			= 0,
    184	.vddmax			= 2100000,
    185	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
    186	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
    187	.volt_reg_addr		= OMAP4_VDD_IVA_SR_VOLT_REG,
    188	.cmd_reg_addr		= OMAP4_VDD_IVA_SR_CMD_REG,
    189	.i2c_high_speed		= true,
    190	.i2c_pad_load		= 3,
    191	.vsel_to_uv		= twl6030_vsel_to_uv,
    192	.uv_to_vsel		= twl6030_uv_to_vsel,
    193};
    194
    195static struct omap_voltdm_pmic omap4_core_pmic = {
    196	.slew_rate		= 4000,
    197	.step_size		= 12660,
    198	.vp_erroroffset		= OMAP4_VP_CONFIG_ERROROFFSET,
    199	.vp_vstepmin		= OMAP4_VP_VSTEPMIN_VSTEPMIN,
    200	.vp_vstepmax		= OMAP4_VP_VSTEPMAX_VSTEPMAX,
    201	.vddmin			= 0,
    202	.vddmax			= 2100000,
    203	.vp_timeout_us		= OMAP4_VP_VLIMITTO_TIMEOUT_US,
    204	.i2c_slave_addr		= OMAP4_SRI2C_SLAVE_ADDR,
    205	.volt_reg_addr		= OMAP4_VDD_CORE_SR_VOLT_REG,
    206	.cmd_reg_addr		= OMAP4_VDD_CORE_SR_CMD_REG,
    207	.i2c_high_speed		= true,
    208	.i2c_pad_load		= 3,
    209	.vsel_to_uv		= twl6030_vsel_to_uv,
    210	.uv_to_vsel		= twl6030_uv_to_vsel,
    211};
    212
    213int __init omap4_twl_init(void)
    214{
    215	struct voltagedomain *voltdm;
    216
    217	if (!cpu_is_omap44xx() ||
    218	    of_find_compatible_node(NULL, NULL, "motorola,cpcap"))
    219		return -ENODEV;
    220
    221	voltdm = voltdm_lookup("mpu");
    222	omap_voltage_register_pmic(voltdm, &omap4_mpu_pmic);
    223
    224	voltdm = voltdm_lookup("iva");
    225	omap_voltage_register_pmic(voltdm, &omap4_iva_pmic);
    226
    227	voltdm = voltdm_lookup("core");
    228	omap_voltage_register_pmic(voltdm, &omap4_core_pmic);
    229
    230	return 0;
    231}
    232
    233int __init omap3_twl_init(void)
    234{
    235	struct voltagedomain *voltdm;
    236
    237	if (!cpu_is_omap34xx())
    238		return -ENODEV;
    239
    240	voltdm = voltdm_lookup("mpu_iva");
    241	omap_voltage_register_pmic(voltdm, &omap3_mpu_pmic);
    242
    243	voltdm = voltdm_lookup("core");
    244	omap_voltage_register_pmic(voltdm, &omap3_core_pmic);
    245
    246	return 0;
    247}