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

pmic-cpcap.c (7092B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * pmic-cpcap.c - CPCAP-specific functions for the OPP code
      4 *
      5 * Adapted from Motorola Mapphone Android Linux kernel
      6 * Copyright (C) 2011 Motorola, Inc.
      7 */
      8
      9#include <linux/err.h>
     10#include <linux/io.h>
     11#include <linux/kernel.h>
     12
     13#include "soc.h"
     14#include "pm.h"
     15#include "voltage.h"
     16
     17#include <linux/init.h>
     18#include "vc.h"
     19
     20/**
     21 * omap_cpcap_vsel_to_vdc - convert CPCAP VSEL value to microvolts DC
     22 * @vsel: CPCAP VSEL value to convert
     23 *
     24 * Returns the microvolts DC that the CPCAP PMIC should generate when
     25 * programmed with @vsel.
     26 */
     27static unsigned long omap_cpcap_vsel_to_uv(unsigned char vsel)
     28{
     29	if (vsel > 0x44)
     30		vsel = 0x44;
     31	return (((vsel * 125) + 6000)) * 100;
     32}
     33
     34/**
     35 * omap_cpcap_uv_to_vsel - convert microvolts DC to CPCAP VSEL value
     36 * @uv: microvolts DC to convert
     37 *
     38 * Returns the VSEL value necessary for the CPCAP PMIC to
     39 * generate an output voltage equal to or greater than @uv microvolts DC.
     40 */
     41static unsigned char omap_cpcap_uv_to_vsel(unsigned long uv)
     42{
     43	if (uv < 600000)
     44		uv = 600000;
     45	else if (uv > 1450000)
     46		uv = 1450000;
     47	return DIV_ROUND_UP(uv - 600000, 12500);
     48}
     49
     50static struct omap_voltdm_pmic omap_cpcap_core = {
     51	.slew_rate = 4000,
     52	.step_size = 12500,
     53	.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
     54	.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
     55	.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
     56	.vddmin = 900000,
     57	.vddmax = 1350000,
     58	.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
     59	.i2c_slave_addr = 0x02,
     60	.volt_reg_addr = 0x00,
     61	.cmd_reg_addr = 0x01,
     62	.i2c_high_speed = false,
     63	.vsel_to_uv = omap_cpcap_vsel_to_uv,
     64	.uv_to_vsel = omap_cpcap_uv_to_vsel,
     65};
     66
     67static struct omap_voltdm_pmic omap_cpcap_iva = {
     68	.slew_rate = 4000,
     69	.step_size = 12500,
     70	.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
     71	.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
     72	.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
     73	.vddmin = 900000,
     74	.vddmax = 1375000,
     75	.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
     76	.i2c_slave_addr = 0x44,
     77	.volt_reg_addr = 0x0,
     78	.cmd_reg_addr = 0x01,
     79	.i2c_high_speed = false,
     80	.vsel_to_uv = omap_cpcap_vsel_to_uv,
     81	.uv_to_vsel = omap_cpcap_uv_to_vsel,
     82};
     83
     84/**
     85 * omap_max8952_vsel_to_vdc - convert MAX8952 VSEL value to microvolts DC
     86 * @vsel: MAX8952 VSEL value to convert
     87 *
     88 * Returns the microvolts DC that the MAX8952 Regulator should generate when
     89 * programmed with @vsel.
     90 */
     91static unsigned long omap_max8952_vsel_to_uv(unsigned char vsel)
     92{
     93	if (vsel > 0x3F)
     94		vsel = 0x3F;
     95	return (((vsel * 100) + 7700)) * 100;
     96}
     97
     98/**
     99 * omap_max8952_uv_to_vsel - convert microvolts DC to MAX8952 VSEL value
    100 * @uv: microvolts DC to convert
    101 *
    102 * Returns the VSEL value necessary for the MAX8952 Regulator to
    103 * generate an output voltage equal to or greater than @uv microvolts DC.
    104 */
    105static unsigned char omap_max8952_uv_to_vsel(unsigned long uv)
    106{
    107	if (uv < 770000)
    108		uv = 770000;
    109	else if (uv > 1400000)
    110		uv = 1400000;
    111	return DIV_ROUND_UP(uv - 770000, 10000);
    112}
    113
    114static struct omap_voltdm_pmic omap443x_max8952_mpu = {
    115	.slew_rate = 16000,
    116	.step_size = 10000,
    117	.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
    118	.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
    119	.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
    120	.vddmin = 900000,
    121	.vddmax = 1400000,
    122	.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
    123	.i2c_slave_addr = 0x60,
    124	.volt_reg_addr = 0x03,
    125	.cmd_reg_addr = 0x03,
    126	.i2c_high_speed = false,
    127	.vsel_to_uv = omap_max8952_vsel_to_uv,
    128	.uv_to_vsel = omap_max8952_uv_to_vsel,
    129};
    130
    131/**
    132 * omap_fan5355_vsel_to_vdc - convert FAN535503 VSEL value to microvolts DC
    133 * @vsel: FAN535503 VSEL value to convert
    134 *
    135 * Returns the microvolts DC that the FAN535503 Regulator should generate when
    136 * programmed with @vsel.
    137 */
    138static unsigned long omap_fan535503_vsel_to_uv(unsigned char vsel)
    139{
    140	/* Extract bits[5:0] */
    141	vsel &= 0x3F;
    142
    143	return (((vsel * 125) + 7500)) * 100;
    144}
    145
    146/**
    147 * omap_fan535508_vsel_to_vdc - convert FAN535508 VSEL value to microvolts DC
    148 * @vsel: FAN535508 VSEL value to convert
    149 *
    150 * Returns the microvolts DC that the FAN535508 Regulator should generate when
    151 * programmed with @vsel.
    152 */
    153static unsigned long omap_fan535508_vsel_to_uv(unsigned char vsel)
    154{
    155	/* Extract bits[5:0] */
    156	vsel &= 0x3F;
    157
    158	if (vsel > 0x37)
    159		vsel = 0x37;
    160	return (((vsel * 125) + 7500)) * 100;
    161}
    162
    163
    164/**
    165 * omap_fan535503_uv_to_vsel - convert microvolts DC to FAN535503 VSEL value
    166 * @uv: microvolts DC to convert
    167 *
    168 * Returns the VSEL value necessary for the MAX8952 Regulator to
    169 * generate an output voltage equal to or greater than @uv microvolts DC.
    170 */
    171static unsigned char omap_fan535503_uv_to_vsel(unsigned long uv)
    172{
    173	unsigned char vsel;
    174	if (uv < 750000)
    175		uv = 750000;
    176	else if (uv > 1537500)
    177		uv = 1537500;
    178
    179	vsel = DIV_ROUND_UP(uv - 750000, 12500);
    180	return vsel | 0xC0;
    181}
    182
    183/**
    184 * omap_fan535508_uv_to_vsel - convert microvolts DC to FAN535508 VSEL value
    185 * @uv: microvolts DC to convert
    186 *
    187 * Returns the VSEL value necessary for the MAX8952 Regulator to
    188 * generate an output voltage equal to or greater than @uv microvolts DC.
    189 */
    190static unsigned char omap_fan535508_uv_to_vsel(unsigned long uv)
    191{
    192	unsigned char vsel;
    193	if (uv < 750000)
    194		uv = 750000;
    195	else if (uv > 1437500)
    196		uv = 1437500;
    197
    198	vsel = DIV_ROUND_UP(uv - 750000, 12500);
    199	return vsel | 0xC0;
    200}
    201
    202/* fan5335-core */
    203static struct omap_voltdm_pmic omap4_fan_core = {
    204	.slew_rate = 4000,
    205	.step_size = 12500,
    206	.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
    207	.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
    208	.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
    209	.vddmin = 850000,
    210	.vddmax = 1375000,
    211	.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
    212	.i2c_slave_addr = 0x4A,
    213	.i2c_high_speed = false,
    214	.volt_reg_addr = 0x01,
    215	.cmd_reg_addr = 0x01,
    216	.vsel_to_uv = omap_fan535508_vsel_to_uv,
    217	.uv_to_vsel = omap_fan535508_uv_to_vsel,
    218};
    219
    220/* fan5335 iva */
    221static struct omap_voltdm_pmic omap4_fan_iva = {
    222	.slew_rate = 4000,
    223	.step_size = 12500,
    224	.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
    225	.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
    226	.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
    227	.vddmin = 850000,
    228	.vddmax = 1375000,
    229	.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
    230	.i2c_slave_addr = 0x48,
    231	.volt_reg_addr = 0x01,
    232	.cmd_reg_addr = 0x01,
    233	.i2c_high_speed = false,
    234	.vsel_to_uv = omap_fan535503_vsel_to_uv,
    235	.uv_to_vsel = omap_fan535503_uv_to_vsel,
    236};
    237
    238int __init omap4_cpcap_init(void)
    239{
    240	struct voltagedomain *voltdm;
    241
    242	if (!of_find_compatible_node(NULL, NULL, "motorola,cpcap"))
    243		return -ENODEV;
    244
    245	voltdm = voltdm_lookup("mpu");
    246	omap_voltage_register_pmic(voltdm, &omap443x_max8952_mpu);
    247
    248	if (of_machine_is_compatible("motorola,droid-bionic")) {
    249		voltdm = voltdm_lookup("core");
    250		omap_voltage_register_pmic(voltdm, &omap_cpcap_core);
    251
    252		voltdm = voltdm_lookup("iva");
    253		omap_voltage_register_pmic(voltdm, &omap_cpcap_iva);
    254	} else {
    255		voltdm = voltdm_lookup("core");
    256		omap_voltage_register_pmic(voltdm, &omap4_fan_core);
    257
    258		voltdm = voltdm_lookup("iva");
    259		omap_voltage_register_pmic(voltdm, &omap4_fan_iva);
    260	}
    261
    262	return 0;
    263}
    264
    265static int __init cpcap_late_init(void)
    266{
    267	omap4_vc_set_pmic_signaling(PWRDM_POWER_RET);
    268
    269	return 0;
    270}
    271omap_late_initcall(cpcap_late_init);