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

sc2731-regulator.c (8518B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 2017 Spreadtrum Communications Inc.
      4 */
      5
      6#include <linux/module.h>
      7#include <linux/of.h>
      8#include <linux/platform_device.h>
      9#include <linux/regmap.h>
     10#include <linux/regulator/driver.h>
     11#include <linux/regulator/of_regulator.h>
     12
     13/*
     14 * SC2731 regulator lock register
     15 */
     16#define SC2731_PWR_WR_PROT		0xf0c
     17#define SC2731_WR_UNLOCK_VALUE		0x6e7f
     18
     19/*
     20 * SC2731 enable register
     21 */
     22#define SC2731_POWER_PD_SW		0xc28
     23#define SC2731_LDO_CAMA0_PD		0xcfc
     24#define SC2731_LDO_CAMA1_PD		0xd04
     25#define SC2731_LDO_CAMMOT_PD		0xd0c
     26#define SC2731_LDO_VLDO_PD		0xd6c
     27#define SC2731_LDO_EMMCCORE_PD		0xd2c
     28#define SC2731_LDO_SDCORE_PD		0xd74
     29#define SC2731_LDO_SDIO_PD		0xd70
     30#define SC2731_LDO_WIFIPA_PD		0xd4c
     31#define SC2731_LDO_USB33_PD		0xd5c
     32#define SC2731_LDO_CAMD0_PD		0xd7c
     33#define SC2731_LDO_CAMD1_PD		0xd84
     34#define SC2731_LDO_CON_PD		0xd8c
     35#define SC2731_LDO_CAMIO_PD		0xd94
     36#define SC2731_LDO_SRAM_PD		0xd78
     37
     38/*
     39 * SC2731 enable mask
     40 */
     41#define SC2731_DCDC_CPU0_PD_MASK	BIT(4)
     42#define SC2731_DCDC_CPU1_PD_MASK	BIT(3)
     43#define SC2731_DCDC_RF_PD_MASK		BIT(11)
     44#define SC2731_LDO_CAMA0_PD_MASK	BIT(0)
     45#define SC2731_LDO_CAMA1_PD_MASK	BIT(0)
     46#define SC2731_LDO_CAMMOT_PD_MASK	BIT(0)
     47#define SC2731_LDO_VLDO_PD_MASK		BIT(0)
     48#define SC2731_LDO_EMMCCORE_PD_MASK	BIT(0)
     49#define SC2731_LDO_SDCORE_PD_MASK	BIT(0)
     50#define SC2731_LDO_SDIO_PD_MASK		BIT(0)
     51#define SC2731_LDO_WIFIPA_PD_MASK	BIT(0)
     52#define SC2731_LDO_USB33_PD_MASK	BIT(0)
     53#define SC2731_LDO_CAMD0_PD_MASK	BIT(0)
     54#define SC2731_LDO_CAMD1_PD_MASK	BIT(0)
     55#define SC2731_LDO_CON_PD_MASK		BIT(0)
     56#define SC2731_LDO_CAMIO_PD_MASK	BIT(0)
     57#define SC2731_LDO_SRAM_PD_MASK		BIT(0)
     58
     59/*
     60 * SC2731 vsel register
     61 */
     62#define SC2731_DCDC_CPU0_VOL		0xc54
     63#define SC2731_DCDC_CPU1_VOL		0xc64
     64#define SC2731_DCDC_RF_VOL		0xcb8
     65#define SC2731_LDO_CAMA0_VOL		0xd00
     66#define SC2731_LDO_CAMA1_VOL		0xd08
     67#define SC2731_LDO_CAMMOT_VOL		0xd10
     68#define SC2731_LDO_VLDO_VOL		0xd28
     69#define SC2731_LDO_EMMCCORE_VOL		0xd30
     70#define SC2731_LDO_SDCORE_VOL		0xd38
     71#define SC2731_LDO_SDIO_VOL		0xd40
     72#define SC2731_LDO_WIFIPA_VOL		0xd50
     73#define SC2731_LDO_USB33_VOL		0xd60
     74#define SC2731_LDO_CAMD0_VOL		0xd80
     75#define SC2731_LDO_CAMD1_VOL		0xd88
     76#define SC2731_LDO_CON_VOL		0xd90
     77#define SC2731_LDO_CAMIO_VOL		0xd98
     78#define SC2731_LDO_SRAM_VOL		0xdB0
     79
     80/*
     81 * SC2731 vsel register mask
     82 */
     83#define SC2731_DCDC_CPU0_VOL_MASK	GENMASK(8, 0)
     84#define SC2731_DCDC_CPU1_VOL_MASK	GENMASK(8, 0)
     85#define SC2731_DCDC_RF_VOL_MASK		GENMASK(8, 0)
     86#define SC2731_LDO_CAMA0_VOL_MASK	GENMASK(7, 0)
     87#define SC2731_LDO_CAMA1_VOL_MASK	GENMASK(7, 0)
     88#define SC2731_LDO_CAMMOT_VOL_MASK	GENMASK(7, 0)
     89#define SC2731_LDO_VLDO_VOL_MASK	GENMASK(7, 0)
     90#define SC2731_LDO_EMMCCORE_VOL_MASK	GENMASK(7, 0)
     91#define SC2731_LDO_SDCORE_VOL_MASK	GENMASK(7, 0)
     92#define SC2731_LDO_SDIO_VOL_MASK	GENMASK(7, 0)
     93#define SC2731_LDO_WIFIPA_VOL_MASK	GENMASK(7, 0)
     94#define SC2731_LDO_USB33_VOL_MASK	GENMASK(7, 0)
     95#define SC2731_LDO_CAMD0_VOL_MASK	GENMASK(6, 0)
     96#define SC2731_LDO_CAMD1_VOL_MASK	GENMASK(6, 0)
     97#define SC2731_LDO_CON_VOL_MASK		GENMASK(6, 0)
     98#define SC2731_LDO_CAMIO_VOL_MASK	GENMASK(6, 0)
     99#define SC2731_LDO_SRAM_VOL_MASK	GENMASK(6, 0)
    100
    101enum sc2731_regulator_id {
    102	SC2731_BUCK_CPU0,
    103	SC2731_BUCK_CPU1,
    104	SC2731_BUCK_RF,
    105	SC2731_LDO_CAMA0,
    106	SC2731_LDO_CAMA1,
    107	SC2731_LDO_CAMMOT,
    108	SC2731_LDO_VLDO,
    109	SC2731_LDO_EMMCCORE,
    110	SC2731_LDO_SDCORE,
    111	SC2731_LDO_SDIO,
    112	SC2731_LDO_WIFIPA,
    113	SC2731_LDO_USB33,
    114	SC2731_LDO_CAMD0,
    115	SC2731_LDO_CAMD1,
    116	SC2731_LDO_CON,
    117	SC2731_LDO_CAMIO,
    118	SC2731_LDO_SRAM,
    119};
    120
    121static const struct regulator_ops sc2731_regu_linear_ops = {
    122	.enable = regulator_enable_regmap,
    123	.disable = regulator_disable_regmap,
    124	.is_enabled = regulator_is_enabled_regmap,
    125	.list_voltage = regulator_list_voltage_linear,
    126	.get_voltage_sel = regulator_get_voltage_sel_regmap,
    127	.set_voltage_sel = regulator_set_voltage_sel_regmap,
    128};
    129
    130#define SC2731_REGU_LINEAR(_id, en_reg, en_mask, vreg, vmask,	\
    131			  vstep, vmin, vmax) {			\
    132	.name			= #_id,				\
    133	.of_match		= of_match_ptr(#_id),		\
    134	.ops			= &sc2731_regu_linear_ops,	\
    135	.type			= REGULATOR_VOLTAGE,		\
    136	.id			= SC2731_##_id,			\
    137	.owner			= THIS_MODULE,			\
    138	.min_uV			= vmin,				\
    139	.n_voltages		= ((vmax) - (vmin)) / (vstep) + 1,	\
    140	.uV_step		= vstep,			\
    141	.enable_is_inverted	= true,				\
    142	.enable_val		= 0,				\
    143	.enable_reg		= en_reg,			\
    144	.enable_mask		= en_mask,			\
    145	.vsel_reg		= vreg,				\
    146	.vsel_mask		= vmask,			\
    147}
    148
    149static const struct regulator_desc regulators[] = {
    150	SC2731_REGU_LINEAR(BUCK_CPU0, SC2731_POWER_PD_SW,
    151			   SC2731_DCDC_CPU0_PD_MASK, SC2731_DCDC_CPU0_VOL,
    152			   SC2731_DCDC_CPU0_VOL_MASK, 3125, 400000, 1996875),
    153	SC2731_REGU_LINEAR(BUCK_CPU1, SC2731_POWER_PD_SW,
    154			   SC2731_DCDC_CPU1_PD_MASK, SC2731_DCDC_CPU1_VOL,
    155			   SC2731_DCDC_CPU1_VOL_MASK, 3125, 400000, 1996875),
    156	SC2731_REGU_LINEAR(BUCK_RF, SC2731_POWER_PD_SW, SC2731_DCDC_RF_PD_MASK,
    157			   SC2731_DCDC_RF_VOL, SC2731_DCDC_RF_VOL_MASK,
    158			   3125, 600000, 2196875),
    159	SC2731_REGU_LINEAR(LDO_CAMA0, SC2731_LDO_CAMA0_PD,
    160			   SC2731_LDO_CAMA0_PD_MASK, SC2731_LDO_CAMA0_VOL,
    161			   SC2731_LDO_CAMA0_VOL_MASK, 10000, 1200000, 3750000),
    162	SC2731_REGU_LINEAR(LDO_CAMA1, SC2731_LDO_CAMA1_PD,
    163			   SC2731_LDO_CAMA1_PD_MASK, SC2731_LDO_CAMA1_VOL,
    164			   SC2731_LDO_CAMA1_VOL_MASK, 10000, 1200000, 3750000),
    165	SC2731_REGU_LINEAR(LDO_CAMMOT, SC2731_LDO_CAMMOT_PD,
    166			   SC2731_LDO_CAMMOT_PD_MASK, SC2731_LDO_CAMMOT_VOL,
    167			   SC2731_LDO_CAMMOT_VOL_MASK, 10000, 1200000, 3750000),
    168	SC2731_REGU_LINEAR(LDO_VLDO, SC2731_LDO_VLDO_PD,
    169			   SC2731_LDO_VLDO_PD_MASK, SC2731_LDO_VLDO_VOL,
    170			   SC2731_LDO_VLDO_VOL_MASK, 10000, 1200000, 3750000),
    171	SC2731_REGU_LINEAR(LDO_EMMCCORE, SC2731_LDO_EMMCCORE_PD,
    172			   SC2731_LDO_EMMCCORE_PD_MASK, SC2731_LDO_EMMCCORE_VOL,
    173			   SC2731_LDO_EMMCCORE_VOL_MASK, 10000, 1200000,
    174			   3750000),
    175	SC2731_REGU_LINEAR(LDO_SDCORE, SC2731_LDO_SDCORE_PD,
    176			   SC2731_LDO_SDCORE_PD_MASK, SC2731_LDO_SDCORE_VOL,
    177			   SC2731_LDO_SDCORE_VOL_MASK, 10000, 1200000, 3750000),
    178	SC2731_REGU_LINEAR(LDO_SDIO, SC2731_LDO_SDIO_PD,
    179			   SC2731_LDO_SDIO_PD_MASK, SC2731_LDO_SDIO_VOL,
    180			   SC2731_LDO_SDIO_VOL_MASK, 10000, 1200000, 3750000),
    181	SC2731_REGU_LINEAR(LDO_WIFIPA, SC2731_LDO_WIFIPA_PD,
    182			   SC2731_LDO_WIFIPA_PD_MASK, SC2731_LDO_WIFIPA_VOL,
    183			   SC2731_LDO_WIFIPA_VOL_MASK, 10000, 1200000, 3750000),
    184	SC2731_REGU_LINEAR(LDO_USB33, SC2731_LDO_USB33_PD,
    185			   SC2731_LDO_USB33_PD_MASK, SC2731_LDO_USB33_VOL,
    186			   SC2731_LDO_USB33_VOL_MASK, 10000, 1200000, 3750000),
    187	SC2731_REGU_LINEAR(LDO_CAMD0, SC2731_LDO_CAMD0_PD,
    188			   SC2731_LDO_CAMD0_PD_MASK, SC2731_LDO_CAMD0_VOL,
    189			   SC2731_LDO_CAMD0_VOL_MASK, 6250, 1000000, 1793750),
    190	SC2731_REGU_LINEAR(LDO_CAMD1, SC2731_LDO_CAMD1_PD,
    191			   SC2731_LDO_CAMD1_PD_MASK, SC2731_LDO_CAMD1_VOL,
    192			   SC2731_LDO_CAMD1_VOL_MASK, 6250, 1000000, 1793750),
    193	SC2731_REGU_LINEAR(LDO_CON, SC2731_LDO_CON_PD,
    194			   SC2731_LDO_CON_PD_MASK, SC2731_LDO_CON_VOL,
    195			   SC2731_LDO_CON_VOL_MASK, 6250, 1000000, 1793750),
    196	SC2731_REGU_LINEAR(LDO_CAMIO, SC2731_LDO_CAMIO_PD,
    197			   SC2731_LDO_CAMIO_PD_MASK, SC2731_LDO_CAMIO_VOL,
    198			   SC2731_LDO_CAMIO_VOL_MASK, 6250, 1000000, 1793750),
    199	SC2731_REGU_LINEAR(LDO_SRAM, SC2731_LDO_SRAM_PD,
    200			   SC2731_LDO_SRAM_PD_MASK, SC2731_LDO_SRAM_VOL,
    201			   SC2731_LDO_SRAM_VOL_MASK, 6250, 1000000, 1793750),
    202};
    203
    204static int sc2731_regulator_unlock(struct regmap *regmap)
    205{
    206	return regmap_write(regmap, SC2731_PWR_WR_PROT,
    207			    SC2731_WR_UNLOCK_VALUE);
    208}
    209
    210static int sc2731_regulator_probe(struct platform_device *pdev)
    211{
    212	int i, ret;
    213	struct regmap *regmap;
    214	struct regulator_config config = { };
    215	struct regulator_dev *rdev;
    216
    217	regmap = dev_get_regmap(pdev->dev.parent, NULL);
    218	if (!regmap) {
    219		dev_err(&pdev->dev, "failed to get regmap.\n");
    220		return -ENODEV;
    221	}
    222
    223	ret = sc2731_regulator_unlock(regmap);
    224	if (ret) {
    225		dev_err(&pdev->dev, "failed to release regulator lock\n");
    226		return ret;
    227	}
    228
    229	config.dev = &pdev->dev;
    230	config.regmap = regmap;
    231
    232	for (i = 0; i < ARRAY_SIZE(regulators); i++) {
    233		rdev = devm_regulator_register(&pdev->dev, &regulators[i],
    234					       &config);
    235		if (IS_ERR(rdev)) {
    236			dev_err(&pdev->dev, "failed to register regulator %s\n",
    237				regulators[i].name);
    238			return PTR_ERR(rdev);
    239		}
    240	}
    241
    242	return 0;
    243}
    244
    245static struct platform_driver sc2731_regulator_driver = {
    246	.driver = {
    247		.name = "sc27xx-regulator",
    248	},
    249	.probe = sc2731_regulator_probe,
    250};
    251
    252module_platform_driver(sc2731_regulator_driver);
    253
    254MODULE_AUTHOR("Chen Junhui <erick.chen@spreadtrum.com>");
    255MODULE_DESCRIPTION("Spreadtrum SC2731 regulator driver");
    256MODULE_LICENSE("GPL v2");