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

stm32-pwr.c (4548B)


      1// SPDX-License-Identifier: GPL-2.0
      2// Copyright (C) STMicroelectronics 2019
      3// Authors: Gabriel Fernandez <gabriel.fernandez@st.com>
      4//          Pascal Paillet <p.paillet@st.com>.
      5
      6#include <linux/io.h>
      7#include <linux/iopoll.h>
      8#include <linux/module.h>
      9#include <linux/of_address.h>
     10#include <linux/of_device.h>
     11#include <linux/platform_device.h>
     12#include <linux/regulator/driver.h>
     13#include <linux/regulator/of_regulator.h>
     14
     15/*
     16 * Registers description
     17 */
     18#define REG_PWR_CR3 0x0C
     19
     20#define USB_3_3_EN BIT(24)
     21#define USB_3_3_RDY BIT(26)
     22#define REG_1_8_EN BIT(28)
     23#define REG_1_8_RDY BIT(29)
     24#define REG_1_1_EN BIT(30)
     25#define REG_1_1_RDY BIT(31)
     26
     27/* list of supported regulators */
     28enum {
     29	PWR_REG11,
     30	PWR_REG18,
     31	PWR_USB33,
     32	STM32PWR_REG_NUM_REGS
     33};
     34
     35static u32 ready_mask_table[STM32PWR_REG_NUM_REGS] = {
     36	[PWR_REG11] = REG_1_1_RDY,
     37	[PWR_REG18] = REG_1_8_RDY,
     38	[PWR_USB33] = USB_3_3_RDY,
     39};
     40
     41struct stm32_pwr_reg {
     42	void __iomem *base;
     43	u32 ready_mask;
     44};
     45
     46static int stm32_pwr_reg_is_ready(struct regulator_dev *rdev)
     47{
     48	struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev);
     49	u32 val;
     50
     51	val = readl_relaxed(priv->base + REG_PWR_CR3);
     52
     53	return (val & priv->ready_mask);
     54}
     55
     56static int stm32_pwr_reg_is_enabled(struct regulator_dev *rdev)
     57{
     58	struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev);
     59	u32 val;
     60
     61	val = readl_relaxed(priv->base + REG_PWR_CR3);
     62
     63	return (val & rdev->desc->enable_mask);
     64}
     65
     66static int stm32_pwr_reg_enable(struct regulator_dev *rdev)
     67{
     68	struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev);
     69	int ret;
     70	u32 val;
     71
     72	val = readl_relaxed(priv->base + REG_PWR_CR3);
     73	val |= rdev->desc->enable_mask;
     74	writel_relaxed(val, priv->base + REG_PWR_CR3);
     75
     76	/* use an arbitrary timeout of 20ms */
     77	ret = readx_poll_timeout(stm32_pwr_reg_is_ready, rdev, val, val,
     78				 100, 20 * 1000);
     79	if (ret)
     80		dev_err(&rdev->dev, "regulator enable timed out!\n");
     81
     82	return ret;
     83}
     84
     85static int stm32_pwr_reg_disable(struct regulator_dev *rdev)
     86{
     87	struct stm32_pwr_reg *priv = rdev_get_drvdata(rdev);
     88	int ret;
     89	u32 val;
     90
     91	val = readl_relaxed(priv->base + REG_PWR_CR3);
     92	val &= ~rdev->desc->enable_mask;
     93	writel_relaxed(val, priv->base + REG_PWR_CR3);
     94
     95	/* use an arbitrary timeout of 20ms */
     96	ret = readx_poll_timeout(stm32_pwr_reg_is_ready, rdev, val, !val,
     97				 100, 20 * 1000);
     98	if (ret)
     99		dev_err(&rdev->dev, "regulator disable timed out!\n");
    100
    101	return ret;
    102}
    103
    104static const struct regulator_ops stm32_pwr_reg_ops = {
    105	.enable		= stm32_pwr_reg_enable,
    106	.disable	= stm32_pwr_reg_disable,
    107	.is_enabled	= stm32_pwr_reg_is_enabled,
    108};
    109
    110#define PWR_REG(_id, _name, _volt, _en, _supply) \
    111	[_id] = { \
    112		.id = _id, \
    113		.name = _name, \
    114		.of_match = of_match_ptr(_name), \
    115		.n_voltages = 1, \
    116		.type = REGULATOR_VOLTAGE, \
    117		.fixed_uV = _volt, \
    118		.ops = &stm32_pwr_reg_ops, \
    119		.enable_mask = _en, \
    120		.owner = THIS_MODULE, \
    121		.supply_name = _supply, \
    122	} \
    123
    124static const struct regulator_desc stm32_pwr_desc[] = {
    125	PWR_REG(PWR_REG11, "reg11", 1100000, REG_1_1_EN, "vdd"),
    126	PWR_REG(PWR_REG18, "reg18", 1800000, REG_1_8_EN, "vdd"),
    127	PWR_REG(PWR_USB33, "usb33", 3300000, USB_3_3_EN, "vdd_3v3_usbfs"),
    128};
    129
    130static int stm32_pwr_regulator_probe(struct platform_device *pdev)
    131{
    132	struct device_node *np = pdev->dev.of_node;
    133	struct stm32_pwr_reg *priv;
    134	void __iomem *base;
    135	struct regulator_dev *rdev;
    136	struct regulator_config config = { };
    137	int i, ret = 0;
    138
    139	base = of_iomap(np, 0);
    140	if (!base) {
    141		dev_err(&pdev->dev, "Unable to map IO memory\n");
    142		return -ENOMEM;
    143	}
    144
    145	config.dev = &pdev->dev;
    146
    147	for (i = 0; i < STM32PWR_REG_NUM_REGS; i++) {
    148		priv = devm_kzalloc(&pdev->dev, sizeof(struct stm32_pwr_reg),
    149				    GFP_KERNEL);
    150		if (!priv)
    151			return -ENOMEM;
    152		priv->base = base;
    153		priv->ready_mask = ready_mask_table[i];
    154		config.driver_data = priv;
    155
    156		rdev = devm_regulator_register(&pdev->dev,
    157					       &stm32_pwr_desc[i],
    158					       &config);
    159		if (IS_ERR(rdev)) {
    160			ret = PTR_ERR(rdev);
    161			dev_err(&pdev->dev,
    162				"Failed to register regulator: %d\n", ret);
    163			break;
    164		}
    165	}
    166	return ret;
    167}
    168
    169static const struct of_device_id __maybe_unused stm32_pwr_of_match[] = {
    170	{ .compatible = "st,stm32mp1,pwr-reg", },
    171	{},
    172};
    173MODULE_DEVICE_TABLE(of, stm32_pwr_of_match);
    174
    175static struct platform_driver stm32_pwr_driver = {
    176	.probe = stm32_pwr_regulator_probe,
    177	.driver = {
    178		.name  = "stm32-pwr-regulator",
    179		.of_match_table = of_match_ptr(stm32_pwr_of_match),
    180	},
    181};
    182module_platform_driver(stm32_pwr_driver);
    183
    184MODULE_DESCRIPTION("STM32MP1 PWR voltage regulator driver");
    185MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>");
    186MODULE_LICENSE("GPL v2");