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

db8500-prcmu.c (12189B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) ST-Ericsson SA 2010
      4 *
      5 * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
      6 *          Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson
      7 *
      8 * Power domain regulators on DB8500
      9 */
     10
     11#include <linux/kernel.h>
     12#include <linux/init.h>
     13#include <linux/err.h>
     14#include <linux/spinlock.h>
     15#include <linux/platform_device.h>
     16#include <linux/mfd/dbx500-prcmu.h>
     17#include <linux/regulator/driver.h>
     18#include <linux/regulator/machine.h>
     19#include <linux/regulator/db8500-prcmu.h>
     20#include <linux/regulator/of_regulator.h>
     21#include <linux/of.h>
     22#include <linux/module.h>
     23#include "dbx500-prcmu.h"
     24
     25static int db8500_regulator_enable(struct regulator_dev *rdev)
     26{
     27	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
     28
     29	if (info == NULL)
     30		return -EINVAL;
     31
     32	dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n",
     33		info->desc.name);
     34
     35	if (!info->is_enabled) {
     36		info->is_enabled = true;
     37		if (!info->exclude_from_power_state)
     38			power_state_active_enable();
     39	}
     40
     41	return 0;
     42}
     43
     44static int db8500_regulator_disable(struct regulator_dev *rdev)
     45{
     46	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
     47	int ret = 0;
     48
     49	if (info == NULL)
     50		return -EINVAL;
     51
     52	dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n",
     53		info->desc.name);
     54
     55	if (info->is_enabled) {
     56		info->is_enabled = false;
     57		if (!info->exclude_from_power_state)
     58			ret = power_state_active_disable();
     59	}
     60
     61	return ret;
     62}
     63
     64static int db8500_regulator_is_enabled(struct regulator_dev *rdev)
     65{
     66	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
     67
     68	if (info == NULL)
     69		return -EINVAL;
     70
     71	dev_vdbg(rdev_get_dev(rdev), "regulator-%s-is_enabled (is_enabled):"
     72		" %i\n", info->desc.name, info->is_enabled);
     73
     74	return info->is_enabled;
     75}
     76
     77/* db8500 regulator operations */
     78static const struct regulator_ops db8500_regulator_ops = {
     79	.enable			= db8500_regulator_enable,
     80	.disable		= db8500_regulator_disable,
     81	.is_enabled		= db8500_regulator_is_enabled,
     82};
     83
     84/*
     85 * EPOD control
     86 */
     87static bool epod_on[NUM_EPOD_ID];
     88static bool epod_ramret[NUM_EPOD_ID];
     89
     90static int enable_epod(u16 epod_id, bool ramret)
     91{
     92	int ret;
     93
     94	if (ramret) {
     95		if (!epod_on[epod_id]) {
     96			ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
     97			if (ret < 0)
     98				return ret;
     99		}
    100		epod_ramret[epod_id] = true;
    101	} else {
    102		ret = prcmu_set_epod(epod_id, EPOD_STATE_ON);
    103		if (ret < 0)
    104			return ret;
    105		epod_on[epod_id] = true;
    106	}
    107
    108	return 0;
    109}
    110
    111static int disable_epod(u16 epod_id, bool ramret)
    112{
    113	int ret;
    114
    115	if (ramret) {
    116		if (!epod_on[epod_id]) {
    117			ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
    118			if (ret < 0)
    119				return ret;
    120		}
    121		epod_ramret[epod_id] = false;
    122	} else {
    123		if (epod_ramret[epod_id]) {
    124			ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
    125			if (ret < 0)
    126				return ret;
    127		} else {
    128			ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
    129			if (ret < 0)
    130				return ret;
    131		}
    132		epod_on[epod_id] = false;
    133	}
    134
    135	return 0;
    136}
    137
    138/*
    139 * Regulator switch
    140 */
    141static int db8500_regulator_switch_enable(struct regulator_dev *rdev)
    142{
    143	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
    144	int ret;
    145
    146	if (info == NULL)
    147		return -EINVAL;
    148
    149	dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-enable\n",
    150		info->desc.name);
    151
    152	ret = enable_epod(info->epod_id, info->is_ramret);
    153	if (ret < 0) {
    154		dev_err(rdev_get_dev(rdev),
    155			"regulator-switch-%s-enable: prcmu call failed\n",
    156			info->desc.name);
    157		goto out;
    158	}
    159
    160	info->is_enabled = true;
    161out:
    162	return ret;
    163}
    164
    165static int db8500_regulator_switch_disable(struct regulator_dev *rdev)
    166{
    167	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
    168	int ret;
    169
    170	if (info == NULL)
    171		return -EINVAL;
    172
    173	dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-disable\n",
    174		info->desc.name);
    175
    176	ret = disable_epod(info->epod_id, info->is_ramret);
    177	if (ret < 0) {
    178		dev_err(rdev_get_dev(rdev),
    179			"regulator_switch-%s-disable: prcmu call failed\n",
    180			info->desc.name);
    181		goto out;
    182	}
    183
    184	info->is_enabled = false;
    185out:
    186	return ret;
    187}
    188
    189static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev)
    190{
    191	struct dbx500_regulator_info *info = rdev_get_drvdata(rdev);
    192
    193	if (info == NULL)
    194		return -EINVAL;
    195
    196	dev_vdbg(rdev_get_dev(rdev),
    197		"regulator-switch-%s-is_enabled (is_enabled): %i\n",
    198		info->desc.name, info->is_enabled);
    199
    200	return info->is_enabled;
    201}
    202
    203static const struct regulator_ops db8500_regulator_switch_ops = {
    204	.enable			= db8500_regulator_switch_enable,
    205	.disable		= db8500_regulator_switch_disable,
    206	.is_enabled		= db8500_regulator_switch_is_enabled,
    207};
    208
    209/*
    210 * Regulator information
    211 */
    212static struct dbx500_regulator_info
    213dbx500_regulator_info[DB8500_NUM_REGULATORS] = {
    214	[DB8500_REGULATOR_VAPE] = {
    215		.desc = {
    216			.name	= "db8500-vape",
    217			.of_match = of_match_ptr("db8500_vape"),
    218			.id	= DB8500_REGULATOR_VAPE,
    219			.ops	= &db8500_regulator_ops,
    220			.type	= REGULATOR_VOLTAGE,
    221			.owner	= THIS_MODULE,
    222		},
    223	},
    224	[DB8500_REGULATOR_VARM] = {
    225		.desc = {
    226			.name	= "db8500-varm",
    227			.of_match = of_match_ptr("db8500_varm"),
    228			.id	= DB8500_REGULATOR_VARM,
    229			.ops	= &db8500_regulator_ops,
    230			.type	= REGULATOR_VOLTAGE,
    231			.owner	= THIS_MODULE,
    232		},
    233	},
    234	[DB8500_REGULATOR_VMODEM] = {
    235		.desc = {
    236			.name	= "db8500-vmodem",
    237			.of_match = of_match_ptr("db8500_vmodem"),
    238			.id	= DB8500_REGULATOR_VMODEM,
    239			.ops	= &db8500_regulator_ops,
    240			.type	= REGULATOR_VOLTAGE,
    241			.owner	= THIS_MODULE,
    242		},
    243	},
    244	[DB8500_REGULATOR_VPLL] = {
    245		.desc = {
    246			.name	= "db8500-vpll",
    247			.of_match = of_match_ptr("db8500_vpll"),
    248			.id	= DB8500_REGULATOR_VPLL,
    249			.ops	= &db8500_regulator_ops,
    250			.type	= REGULATOR_VOLTAGE,
    251			.owner	= THIS_MODULE,
    252		},
    253	},
    254	[DB8500_REGULATOR_VSMPS1] = {
    255		.desc = {
    256			.name	= "db8500-vsmps1",
    257			.of_match = of_match_ptr("db8500_vsmps1"),
    258			.id	= DB8500_REGULATOR_VSMPS1,
    259			.ops	= &db8500_regulator_ops,
    260			.type	= REGULATOR_VOLTAGE,
    261			.owner	= THIS_MODULE,
    262		},
    263	},
    264	[DB8500_REGULATOR_VSMPS2] = {
    265		.desc = {
    266			.name	= "db8500-vsmps2",
    267			.of_match = of_match_ptr("db8500_vsmps2"),
    268			.id	= DB8500_REGULATOR_VSMPS2,
    269			.ops	= &db8500_regulator_ops,
    270			.type	= REGULATOR_VOLTAGE,
    271			.owner	= THIS_MODULE,
    272			.fixed_uV = 1800000,
    273			.n_voltages = 1,
    274		},
    275		.exclude_from_power_state = true,
    276	},
    277	[DB8500_REGULATOR_VSMPS3] = {
    278		.desc = {
    279			.name	= "db8500-vsmps3",
    280			.of_match = of_match_ptr("db8500_vsmps3"),
    281			.id	= DB8500_REGULATOR_VSMPS3,
    282			.ops	= &db8500_regulator_ops,
    283			.type	= REGULATOR_VOLTAGE,
    284			.owner	= THIS_MODULE,
    285		},
    286	},
    287	[DB8500_REGULATOR_VRF1] = {
    288		.desc = {
    289			.name	= "db8500-vrf1",
    290			.of_match = of_match_ptr("db8500_vrf1"),
    291			.id	= DB8500_REGULATOR_VRF1,
    292			.ops	= &db8500_regulator_ops,
    293			.type	= REGULATOR_VOLTAGE,
    294			.owner	= THIS_MODULE,
    295		},
    296	},
    297	[DB8500_REGULATOR_SWITCH_SVAMMDSP] = {
    298		.desc = {
    299			.name	= "db8500-sva-mmdsp",
    300			.of_match = of_match_ptr("db8500_sva_mmdsp"),
    301			.id	= DB8500_REGULATOR_SWITCH_SVAMMDSP,
    302			.ops	= &db8500_regulator_switch_ops,
    303			.type	= REGULATOR_VOLTAGE,
    304			.owner	= THIS_MODULE,
    305		},
    306		.epod_id = EPOD_ID_SVAMMDSP,
    307	},
    308	[DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = {
    309		.desc = {
    310			.name	= "db8500-sva-mmdsp-ret",
    311			.of_match = of_match_ptr("db8500_sva_mmdsp_ret"),
    312			.id	= DB8500_REGULATOR_SWITCH_SVAMMDSPRET,
    313			.ops	= &db8500_regulator_switch_ops,
    314			.type	= REGULATOR_VOLTAGE,
    315			.owner	= THIS_MODULE,
    316		},
    317		.epod_id = EPOD_ID_SVAMMDSP,
    318		.is_ramret = true,
    319	},
    320	[DB8500_REGULATOR_SWITCH_SVAPIPE] = {
    321		.desc = {
    322			.name	= "db8500-sva-pipe",
    323			.of_match = of_match_ptr("db8500_sva_pipe"),
    324			.id	= DB8500_REGULATOR_SWITCH_SVAPIPE,
    325			.ops	= &db8500_regulator_switch_ops,
    326			.type	= REGULATOR_VOLTAGE,
    327			.owner	= THIS_MODULE,
    328		},
    329		.epod_id = EPOD_ID_SVAPIPE,
    330	},
    331	[DB8500_REGULATOR_SWITCH_SIAMMDSP] = {
    332		.desc = {
    333			.name	= "db8500-sia-mmdsp",
    334			.of_match = of_match_ptr("db8500_sia_mmdsp"),
    335			.id	= DB8500_REGULATOR_SWITCH_SIAMMDSP,
    336			.ops	= &db8500_regulator_switch_ops,
    337			.type	= REGULATOR_VOLTAGE,
    338			.owner	= THIS_MODULE,
    339		},
    340		.epod_id = EPOD_ID_SIAMMDSP,
    341	},
    342	[DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = {
    343		.desc = {
    344			.name	= "db8500-sia-mmdsp-ret",
    345			.of_match = of_match_ptr("db8500_sia_mmdsp_ret"),
    346			.id	= DB8500_REGULATOR_SWITCH_SIAMMDSPRET,
    347			.ops	= &db8500_regulator_switch_ops,
    348			.type	= REGULATOR_VOLTAGE,
    349			.owner	= THIS_MODULE,
    350		},
    351		.epod_id = EPOD_ID_SIAMMDSP,
    352		.is_ramret = true,
    353	},
    354	[DB8500_REGULATOR_SWITCH_SIAPIPE] = {
    355		.desc = {
    356			.name	= "db8500-sia-pipe",
    357			.of_match = of_match_ptr("db8500_sia_pipe"),
    358			.id	= DB8500_REGULATOR_SWITCH_SIAPIPE,
    359			.ops	= &db8500_regulator_switch_ops,
    360			.type	= REGULATOR_VOLTAGE,
    361			.owner	= THIS_MODULE,
    362		},
    363		.epod_id = EPOD_ID_SIAPIPE,
    364	},
    365	[DB8500_REGULATOR_SWITCH_SGA] = {
    366		.desc = {
    367			.name	= "db8500-sga",
    368			.of_match = of_match_ptr("db8500_sga"),
    369			.id	= DB8500_REGULATOR_SWITCH_SGA,
    370			.ops	= &db8500_regulator_switch_ops,
    371			.type	= REGULATOR_VOLTAGE,
    372			.owner	= THIS_MODULE,
    373		},
    374		.epod_id = EPOD_ID_SGA,
    375	},
    376	[DB8500_REGULATOR_SWITCH_B2R2_MCDE] = {
    377		.desc = {
    378			.name	= "db8500-b2r2-mcde",
    379			.of_match = of_match_ptr("db8500_b2r2_mcde"),
    380			.id	= DB8500_REGULATOR_SWITCH_B2R2_MCDE,
    381			.ops	= &db8500_regulator_switch_ops,
    382			.type	= REGULATOR_VOLTAGE,
    383			.owner	= THIS_MODULE,
    384		},
    385		.epod_id = EPOD_ID_B2R2_MCDE,
    386	},
    387	[DB8500_REGULATOR_SWITCH_ESRAM12] = {
    388		.desc = {
    389			.name	= "db8500-esram12",
    390			.of_match = of_match_ptr("db8500_esram12"),
    391			.id	= DB8500_REGULATOR_SWITCH_ESRAM12,
    392			.ops	= &db8500_regulator_switch_ops,
    393			.type	= REGULATOR_VOLTAGE,
    394			.owner	= THIS_MODULE,
    395		},
    396		.epod_id	= EPOD_ID_ESRAM12,
    397		.is_enabled	= true,
    398	},
    399	[DB8500_REGULATOR_SWITCH_ESRAM12RET] = {
    400		.desc = {
    401			.name	= "db8500-esram12-ret",
    402			.of_match = of_match_ptr("db8500_esram12_ret"),
    403			.id	= DB8500_REGULATOR_SWITCH_ESRAM12RET,
    404			.ops	= &db8500_regulator_switch_ops,
    405			.type	= REGULATOR_VOLTAGE,
    406			.owner	= THIS_MODULE,
    407		},
    408		.epod_id = EPOD_ID_ESRAM12,
    409		.is_ramret = true,
    410	},
    411	[DB8500_REGULATOR_SWITCH_ESRAM34] = {
    412		.desc = {
    413			.name	= "db8500-esram34",
    414			.of_match = of_match_ptr("db8500_esram34"),
    415			.id	= DB8500_REGULATOR_SWITCH_ESRAM34,
    416			.ops	= &db8500_regulator_switch_ops,
    417			.type	= REGULATOR_VOLTAGE,
    418			.owner	= THIS_MODULE,
    419		},
    420		.epod_id	= EPOD_ID_ESRAM34,
    421		.is_enabled	= true,
    422	},
    423	[DB8500_REGULATOR_SWITCH_ESRAM34RET] = {
    424		.desc = {
    425			.name	= "db8500-esram34-ret",
    426			.of_match = of_match_ptr("db8500_esram34_ret"),
    427			.id	= DB8500_REGULATOR_SWITCH_ESRAM34RET,
    428			.ops	= &db8500_regulator_switch_ops,
    429			.type	= REGULATOR_VOLTAGE,
    430			.owner	= THIS_MODULE,
    431		},
    432		.epod_id = EPOD_ID_ESRAM34,
    433		.is_ramret = true,
    434	},
    435};
    436
    437static int db8500_regulator_probe(struct platform_device *pdev)
    438{
    439	struct regulator_init_data *db8500_init_data;
    440	struct dbx500_regulator_info *info;
    441	struct regulator_config config = { };
    442	struct regulator_dev *rdev;
    443	int err, i;
    444
    445	db8500_init_data = dev_get_platdata(&pdev->dev);
    446
    447	for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
    448		/* assign per-regulator data */
    449		info = &dbx500_regulator_info[i];
    450
    451		config.driver_data = info;
    452		config.dev = &pdev->dev;
    453		if (db8500_init_data)
    454			config.init_data = &db8500_init_data[i];
    455
    456		rdev = devm_regulator_register(&pdev->dev, &info->desc,
    457					       &config);
    458		if (IS_ERR(rdev)) {
    459			err = PTR_ERR(rdev);
    460			dev_err(&pdev->dev, "failed to register %s: err %i\n",
    461				info->desc.name, err);
    462			return err;
    463		}
    464		dev_dbg(&pdev->dev, "regulator-%s-probed\n", info->desc.name);
    465	}
    466
    467	ux500_regulator_debug_init(pdev, dbx500_regulator_info,
    468				   ARRAY_SIZE(dbx500_regulator_info));
    469	return 0;
    470}
    471
    472static int db8500_regulator_remove(struct platform_device *pdev)
    473{
    474	ux500_regulator_debug_exit();
    475
    476	return 0;
    477}
    478
    479static struct platform_driver db8500_regulator_driver = {
    480	.driver = {
    481		.name = "db8500-prcmu-regulators",
    482	},
    483	.probe = db8500_regulator_probe,
    484	.remove = db8500_regulator_remove,
    485};
    486
    487static int __init db8500_regulator_init(void)
    488{
    489	return platform_driver_register(&db8500_regulator_driver);
    490}
    491
    492static void __exit db8500_regulator_exit(void)
    493{
    494	platform_driver_unregister(&db8500_regulator_driver);
    495}
    496
    497arch_initcall(db8500_regulator_init);
    498module_exit(db8500_regulator_exit);
    499
    500MODULE_AUTHOR("STMicroelectronics/ST-Ericsson");
    501MODULE_DESCRIPTION("DB8500 regulator driver");
    502MODULE_LICENSE("GPL v2");