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

s2mpa01.c (10730B)


      1// SPDX-License-Identifier: GPL-2.0+
      2//
      3// Copyright (c) 2013 Samsung Electronics Co., Ltd
      4//		http://www.samsung.com
      5
      6#include <linux/bug.h>
      7#include <linux/err.h>
      8#include <linux/gpio.h>
      9#include <linux/slab.h>
     10#include <linux/module.h>
     11#include <linux/of.h>
     12#include <linux/regmap.h>
     13#include <linux/platform_device.h>
     14#include <linux/regulator/driver.h>
     15#include <linux/regulator/machine.h>
     16#include <linux/regulator/of_regulator.h>
     17#include <linux/mfd/samsung/core.h>
     18#include <linux/mfd/samsung/s2mpa01.h>
     19
     20struct s2mpa01_info {
     21	int ramp_delay24;
     22	int ramp_delay3;
     23	int ramp_delay5;
     24	int ramp_delay16;
     25	int ramp_delay7;
     26	int ramp_delay8910;
     27};
     28
     29static int get_ramp_delay(int ramp_delay)
     30{
     31	unsigned char cnt = 0;
     32
     33	ramp_delay /= 6250;
     34
     35	while (true) {
     36		ramp_delay = ramp_delay >> 1;
     37		if (ramp_delay == 0)
     38			break;
     39		cnt++;
     40	}
     41
     42	if (cnt > 3)
     43		cnt = 3;
     44
     45	return cnt;
     46}
     47
     48static int s2mpa01_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
     49				   unsigned int old_selector,
     50				   unsigned int new_selector)
     51{
     52	struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev);
     53	unsigned int ramp_delay = 0;
     54	int old_volt, new_volt;
     55
     56	switch (rdev_get_id(rdev)) {
     57	case S2MPA01_BUCK2:
     58	case S2MPA01_BUCK4:
     59		ramp_delay = s2mpa01->ramp_delay24;
     60		break;
     61	case S2MPA01_BUCK3:
     62		ramp_delay = s2mpa01->ramp_delay3;
     63		break;
     64	case S2MPA01_BUCK5:
     65		ramp_delay = s2mpa01->ramp_delay5;
     66		break;
     67	case S2MPA01_BUCK1:
     68	case S2MPA01_BUCK6:
     69		ramp_delay = s2mpa01->ramp_delay16;
     70		break;
     71	case S2MPA01_BUCK7:
     72		ramp_delay = s2mpa01->ramp_delay7;
     73		break;
     74	case S2MPA01_BUCK8:
     75	case S2MPA01_BUCK9:
     76	case S2MPA01_BUCK10:
     77		ramp_delay = s2mpa01->ramp_delay8910;
     78		break;
     79	}
     80
     81	if (ramp_delay == 0)
     82		ramp_delay = rdev->desc->ramp_delay;
     83
     84	old_volt = rdev->desc->min_uV + (rdev->desc->uV_step * old_selector);
     85	new_volt = rdev->desc->min_uV + (rdev->desc->uV_step * new_selector);
     86
     87	return DIV_ROUND_UP(abs(new_volt - old_volt), ramp_delay);
     88}
     89
     90static int s2mpa01_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
     91{
     92	struct s2mpa01_info *s2mpa01 = rdev_get_drvdata(rdev);
     93	unsigned int ramp_val, ramp_shift, ramp_reg = S2MPA01_REG_RAMP2;
     94	unsigned int ramp_enable = 1, enable_shift = 0;
     95	int ret;
     96
     97	switch (rdev_get_id(rdev)) {
     98	case S2MPA01_BUCK1:
     99		enable_shift = S2MPA01_BUCK1_RAMP_EN_SHIFT;
    100		if (!ramp_delay) {
    101			ramp_enable = 0;
    102			break;
    103		}
    104
    105		if (ramp_delay > s2mpa01->ramp_delay16)
    106			s2mpa01->ramp_delay16 = ramp_delay;
    107		else
    108			ramp_delay = s2mpa01->ramp_delay16;
    109
    110		ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT;
    111		break;
    112	case S2MPA01_BUCK2:
    113		enable_shift = S2MPA01_BUCK2_RAMP_EN_SHIFT;
    114		if (!ramp_delay) {
    115			ramp_enable = 0;
    116			break;
    117		}
    118
    119		if (ramp_delay > s2mpa01->ramp_delay24)
    120			s2mpa01->ramp_delay24 = ramp_delay;
    121		else
    122			ramp_delay = s2mpa01->ramp_delay24;
    123
    124		ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT;
    125		ramp_reg = S2MPA01_REG_RAMP1;
    126		break;
    127	case S2MPA01_BUCK3:
    128		enable_shift = S2MPA01_BUCK3_RAMP_EN_SHIFT;
    129		if (!ramp_delay) {
    130			ramp_enable = 0;
    131			break;
    132		}
    133
    134		s2mpa01->ramp_delay3 = ramp_delay;
    135		ramp_shift = S2MPA01_BUCK3_RAMP_SHIFT;
    136		ramp_reg = S2MPA01_REG_RAMP1;
    137		break;
    138	case S2MPA01_BUCK4:
    139		enable_shift = S2MPA01_BUCK4_RAMP_EN_SHIFT;
    140		if (!ramp_delay) {
    141			ramp_enable = 0;
    142			break;
    143		}
    144
    145		if (ramp_delay > s2mpa01->ramp_delay24)
    146			s2mpa01->ramp_delay24 = ramp_delay;
    147		else
    148			ramp_delay = s2mpa01->ramp_delay24;
    149
    150		ramp_shift = S2MPA01_BUCK24_RAMP_SHIFT;
    151		ramp_reg = S2MPA01_REG_RAMP1;
    152		break;
    153	case S2MPA01_BUCK5:
    154		s2mpa01->ramp_delay5 = ramp_delay;
    155		ramp_shift = S2MPA01_BUCK5_RAMP_SHIFT;
    156		break;
    157	case S2MPA01_BUCK6:
    158		if (ramp_delay > s2mpa01->ramp_delay16)
    159			s2mpa01->ramp_delay16 = ramp_delay;
    160		else
    161			ramp_delay = s2mpa01->ramp_delay16;
    162
    163		ramp_shift = S2MPA01_BUCK16_RAMP_SHIFT;
    164		break;
    165	case S2MPA01_BUCK7:
    166		s2mpa01->ramp_delay7 = ramp_delay;
    167		ramp_shift = S2MPA01_BUCK7_RAMP_SHIFT;
    168		break;
    169	case S2MPA01_BUCK8:
    170	case S2MPA01_BUCK9:
    171	case S2MPA01_BUCK10:
    172		if (ramp_delay > s2mpa01->ramp_delay8910)
    173			s2mpa01->ramp_delay8910 = ramp_delay;
    174		else
    175			ramp_delay = s2mpa01->ramp_delay8910;
    176
    177		ramp_shift = S2MPA01_BUCK8910_RAMP_SHIFT;
    178		break;
    179	default:
    180		return 0;
    181	}
    182
    183	if (!ramp_enable)
    184		goto ramp_disable;
    185
    186	/* Ramp delay can be enabled/disabled only for buck[1234] */
    187	if (rdev_get_id(rdev) >= S2MPA01_BUCK1 &&
    188			rdev_get_id(rdev) <= S2MPA01_BUCK4) {
    189		ret = regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1,
    190					 1 << enable_shift, 1 << enable_shift);
    191		if (ret) {
    192			dev_err(&rdev->dev, "failed to enable ramp rate\n");
    193			return ret;
    194		}
    195	}
    196
    197	ramp_val = get_ramp_delay(ramp_delay);
    198
    199	return regmap_update_bits(rdev->regmap, ramp_reg, 0x3 << ramp_shift,
    200				  ramp_val << ramp_shift);
    201
    202ramp_disable:
    203	return regmap_update_bits(rdev->regmap, S2MPA01_REG_RAMP1,
    204				  1 << enable_shift, 0);
    205}
    206
    207static const struct regulator_ops s2mpa01_ldo_ops = {
    208	.list_voltage		= regulator_list_voltage_linear,
    209	.map_voltage		= regulator_map_voltage_linear,
    210	.is_enabled		= regulator_is_enabled_regmap,
    211	.enable			= regulator_enable_regmap,
    212	.disable		= regulator_disable_regmap,
    213	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
    214	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
    215	.set_voltage_time_sel	= regulator_set_voltage_time_sel,
    216};
    217
    218static const struct regulator_ops s2mpa01_buck_ops = {
    219	.list_voltage		= regulator_list_voltage_linear,
    220	.map_voltage		= regulator_map_voltage_linear,
    221	.is_enabled		= regulator_is_enabled_regmap,
    222	.enable			= regulator_enable_regmap,
    223	.disable		= regulator_disable_regmap,
    224	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
    225	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
    226	.set_voltage_time_sel	= s2mpa01_regulator_set_voltage_time_sel,
    227	.set_ramp_delay		= s2mpa01_set_ramp_delay,
    228};
    229
    230#define regulator_desc_ldo(num, step) {			\
    231	.name		= "LDO"#num,			\
    232	.of_match	= of_match_ptr("LDO"#num),	\
    233	.regulators_node = of_match_ptr("regulators"),	\
    234	.id		= S2MPA01_LDO##num,		\
    235	.ops		= &s2mpa01_ldo_ops,		\
    236	.type		= REGULATOR_VOLTAGE,		\
    237	.owner		= THIS_MODULE,			\
    238	.min_uV		= MIN_800_MV,			\
    239	.uV_step	= step,				\
    240	.n_voltages	= S2MPA01_LDO_N_VOLTAGES,	\
    241	.vsel_reg	= S2MPA01_REG_L1CTRL + num - 1,	\
    242	.vsel_mask	= S2MPA01_LDO_VSEL_MASK,	\
    243	.enable_reg	= S2MPA01_REG_L1CTRL + num - 1,	\
    244	.enable_mask	= S2MPA01_ENABLE_MASK		\
    245}
    246
    247#define regulator_desc_buck1_4(num)	{			\
    248	.name		= "BUCK"#num,				\
    249	.of_match	= of_match_ptr("BUCK"#num),		\
    250	.regulators_node = of_match_ptr("regulators"),		\
    251	.id		= S2MPA01_BUCK##num,			\
    252	.ops		= &s2mpa01_buck_ops,			\
    253	.type		= REGULATOR_VOLTAGE,			\
    254	.owner		= THIS_MODULE,				\
    255	.min_uV		= MIN_600_MV,				\
    256	.uV_step	= STEP_6_25_MV,				\
    257	.n_voltages	= S2MPA01_BUCK_N_VOLTAGES,		\
    258	.ramp_delay	= S2MPA01_RAMP_DELAY,			\
    259	.vsel_reg	= S2MPA01_REG_B1CTRL2 + (num - 1) * 2,	\
    260	.vsel_mask	= S2MPA01_BUCK_VSEL_MASK,		\
    261	.enable_reg	= S2MPA01_REG_B1CTRL1 + (num - 1) * 2,	\
    262	.enable_mask	= S2MPA01_ENABLE_MASK			\
    263}
    264
    265#define regulator_desc_buck5	{				\
    266	.name		= "BUCK5",				\
    267	.of_match	= of_match_ptr("BUCK5"),		\
    268	.regulators_node = of_match_ptr("regulators"),		\
    269	.id		= S2MPA01_BUCK5,			\
    270	.ops		= &s2mpa01_buck_ops,			\
    271	.type		= REGULATOR_VOLTAGE,			\
    272	.owner		= THIS_MODULE,				\
    273	.min_uV		= MIN_800_MV,				\
    274	.uV_step	= STEP_6_25_MV,				\
    275	.n_voltages	= S2MPA01_BUCK_N_VOLTAGES,		\
    276	.ramp_delay	= S2MPA01_RAMP_DELAY,			\
    277	.vsel_reg	= S2MPA01_REG_B5CTRL2,			\
    278	.vsel_mask	= S2MPA01_BUCK_VSEL_MASK,		\
    279	.enable_reg	= S2MPA01_REG_B5CTRL1,			\
    280	.enable_mask	= S2MPA01_ENABLE_MASK			\
    281}
    282
    283#define regulator_desc_buck6_10(num, min, step) {			\
    284	.name		= "BUCK"#num,				\
    285	.of_match	= of_match_ptr("BUCK"#num),		\
    286	.regulators_node = of_match_ptr("regulators"),		\
    287	.id		= S2MPA01_BUCK##num,			\
    288	.ops		= &s2mpa01_buck_ops,			\
    289	.type		= REGULATOR_VOLTAGE,			\
    290	.owner		= THIS_MODULE,				\
    291	.min_uV		= min,					\
    292	.uV_step	= step,					\
    293	.n_voltages	= S2MPA01_BUCK_N_VOLTAGES,		\
    294	.ramp_delay	= S2MPA01_RAMP_DELAY,			\
    295	.vsel_reg	= S2MPA01_REG_B6CTRL2 + (num - 6) * 2,	\
    296	.vsel_mask	= S2MPA01_BUCK_VSEL_MASK,		\
    297	.enable_reg	= S2MPA01_REG_B6CTRL1 + (num - 6) * 2,	\
    298	.enable_mask	= S2MPA01_ENABLE_MASK			\
    299}
    300
    301static const struct regulator_desc regulators[] = {
    302	regulator_desc_ldo(1, STEP_25_MV),
    303	regulator_desc_ldo(2, STEP_50_MV),
    304	regulator_desc_ldo(3, STEP_50_MV),
    305	regulator_desc_ldo(4, STEP_50_MV),
    306	regulator_desc_ldo(5, STEP_25_MV),
    307	regulator_desc_ldo(6, STEP_25_MV),
    308	regulator_desc_ldo(7, STEP_50_MV),
    309	regulator_desc_ldo(8, STEP_50_MV),
    310	regulator_desc_ldo(9, STEP_50_MV),
    311	regulator_desc_ldo(10, STEP_50_MV),
    312	regulator_desc_ldo(11, STEP_50_MV),
    313	regulator_desc_ldo(12, STEP_50_MV),
    314	regulator_desc_ldo(13, STEP_50_MV),
    315	regulator_desc_ldo(14, STEP_50_MV),
    316	regulator_desc_ldo(15, STEP_50_MV),
    317	regulator_desc_ldo(16, STEP_50_MV),
    318	regulator_desc_ldo(17, STEP_50_MV),
    319	regulator_desc_ldo(18, STEP_50_MV),
    320	regulator_desc_ldo(19, STEP_50_MV),
    321	regulator_desc_ldo(20, STEP_50_MV),
    322	regulator_desc_ldo(21, STEP_50_MV),
    323	regulator_desc_ldo(22, STEP_50_MV),
    324	regulator_desc_ldo(23, STEP_50_MV),
    325	regulator_desc_ldo(24, STEP_50_MV),
    326	regulator_desc_ldo(25, STEP_50_MV),
    327	regulator_desc_ldo(26, STEP_25_MV),
    328	regulator_desc_buck1_4(1),
    329	regulator_desc_buck1_4(2),
    330	regulator_desc_buck1_4(3),
    331	regulator_desc_buck1_4(4),
    332	regulator_desc_buck5,
    333	regulator_desc_buck6_10(6, MIN_600_MV, STEP_6_25_MV),
    334	regulator_desc_buck6_10(7, MIN_600_MV, STEP_6_25_MV),
    335	regulator_desc_buck6_10(8, MIN_800_MV, STEP_12_5_MV),
    336	regulator_desc_buck6_10(9, MIN_1500_MV, STEP_12_5_MV),
    337	regulator_desc_buck6_10(10, MIN_1000_MV, STEP_12_5_MV),
    338};
    339
    340static int s2mpa01_pmic_probe(struct platform_device *pdev)
    341{
    342	struct sec_pmic_dev *iodev = dev_get_drvdata(pdev->dev.parent);
    343	struct regulator_config config = { };
    344	struct s2mpa01_info *s2mpa01;
    345	int i;
    346
    347	s2mpa01 = devm_kzalloc(&pdev->dev, sizeof(*s2mpa01), GFP_KERNEL);
    348	if (!s2mpa01)
    349		return -ENOMEM;
    350
    351	config.dev = iodev->dev;
    352	config.regmap = iodev->regmap_pmic;
    353	config.driver_data = s2mpa01;
    354
    355	for (i = 0; i < S2MPA01_REGULATOR_MAX; i++) {
    356		struct regulator_dev *rdev;
    357
    358		rdev = devm_regulator_register(&pdev->dev,
    359						&regulators[i], &config);
    360		if (IS_ERR(rdev)) {
    361			dev_err(&pdev->dev, "regulator init failed for %d\n",
    362				i);
    363			return PTR_ERR(rdev);
    364		}
    365	}
    366
    367	return 0;
    368}
    369
    370static const struct platform_device_id s2mpa01_pmic_id[] = {
    371	{ "s2mpa01-pmic", 0},
    372	{ },
    373};
    374MODULE_DEVICE_TABLE(platform, s2mpa01_pmic_id);
    375
    376static struct platform_driver s2mpa01_pmic_driver = {
    377	.driver = {
    378		.name = "s2mpa01-pmic",
    379	},
    380	.probe = s2mpa01_pmic_probe,
    381	.id_table = s2mpa01_pmic_id,
    382};
    383
    384module_platform_driver(s2mpa01_pmic_driver);
    385
    386/* Module information */
    387MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
    388MODULE_AUTHOR("Sachin Kamat <sachin.kamat@samsung.com>");
    389MODULE_DESCRIPTION("Samsung S2MPA01 Regulator Driver");
    390MODULE_LICENSE("GPL");