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

rzg2l_adc.c (14006B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * RZ/G2L A/D Converter driver
      4 *
      5 *  Copyright (c) 2021 Renesas Electronics Europe GmbH
      6 *
      7 * Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
      8 */
      9
     10#include <linux/bitfield.h>
     11#include <linux/clk.h>
     12#include <linux/completion.h>
     13#include <linux/delay.h>
     14#include <linux/iio/iio.h>
     15#include <linux/interrupt.h>
     16#include <linux/io.h>
     17#include <linux/mod_devicetable.h>
     18#include <linux/module.h>
     19#include <linux/platform_device.h>
     20#include <linux/pm_runtime.h>
     21#include <linux/reset.h>
     22
     23#define DRIVER_NAME		"rzg2l-adc"
     24
     25#define RZG2L_ADM(n)			((n) * 0x4)
     26#define RZG2L_ADM0_ADCE			BIT(0)
     27#define RZG2L_ADM0_ADBSY		BIT(1)
     28#define RZG2L_ADM0_PWDWNB		BIT(2)
     29#define RZG2L_ADM0_SRESB		BIT(15)
     30#define RZG2L_ADM1_TRG			BIT(0)
     31#define RZG2L_ADM1_MS			BIT(2)
     32#define RZG2L_ADM1_BS			BIT(4)
     33#define RZG2L_ADM1_EGA_MASK		GENMASK(13, 12)
     34#define RZG2L_ADM2_CHSEL_MASK		GENMASK(7, 0)
     35#define RZG2L_ADM3_ADIL_MASK		GENMASK(31, 24)
     36#define RZG2L_ADM3_ADCMP_MASK		GENMASK(23, 16)
     37#define RZG2L_ADM3_ADCMP_E		FIELD_PREP(RZG2L_ADM3_ADCMP_MASK, 0xe)
     38#define RZG2L_ADM3_ADSMP_MASK		GENMASK(15, 0)
     39
     40#define RZG2L_ADINT			0x20
     41#define RZG2L_ADINT_INTEN_MASK		GENMASK(7, 0)
     42#define RZG2L_ADINT_CSEEN		BIT(16)
     43#define RZG2L_ADINT_INTS		BIT(31)
     44
     45#define RZG2L_ADSTS			0x24
     46#define RZG2L_ADSTS_CSEST		BIT(16)
     47#define RZG2L_ADSTS_INTST_MASK		GENMASK(7, 0)
     48
     49#define RZG2L_ADIVC			0x28
     50#define RZG2L_ADIVC_DIVADC_MASK		GENMASK(8, 0)
     51#define RZG2L_ADIVC_DIVADC_4		FIELD_PREP(RZG2L_ADIVC_DIVADC_MASK, 0x4)
     52
     53#define RZG2L_ADFIL			0x2c
     54
     55#define RZG2L_ADCR(n)			(0x30 + ((n) * 0x4))
     56#define RZG2L_ADCR_AD_MASK		GENMASK(11, 0)
     57
     58#define RZG2L_ADSMP_DEFAULT_SAMPLING	0x578
     59
     60#define RZG2L_ADC_MAX_CHANNELS		8
     61#define RZG2L_ADC_CHN_MASK		0x7
     62#define RZG2L_ADC_TIMEOUT		usecs_to_jiffies(1 * 4)
     63
     64struct rzg2l_adc_data {
     65	const struct iio_chan_spec *channels;
     66	u8 num_channels;
     67};
     68
     69struct rzg2l_adc {
     70	void __iomem *base;
     71	struct clk *pclk;
     72	struct clk *adclk;
     73	struct reset_control *presetn;
     74	struct reset_control *adrstn;
     75	struct completion completion;
     76	const struct rzg2l_adc_data *data;
     77	struct mutex lock;
     78	u16 last_val[RZG2L_ADC_MAX_CHANNELS];
     79};
     80
     81static const char * const rzg2l_adc_channel_name[] = {
     82	"adc0",
     83	"adc1",
     84	"adc2",
     85	"adc3",
     86	"adc4",
     87	"adc5",
     88	"adc6",
     89	"adc7",
     90};
     91
     92static unsigned int rzg2l_adc_readl(struct rzg2l_adc *adc, u32 reg)
     93{
     94	return readl(adc->base + reg);
     95}
     96
     97static void rzg2l_adc_writel(struct rzg2l_adc *adc, unsigned int reg, u32 val)
     98{
     99	writel(val, adc->base + reg);
    100}
    101
    102static void rzg2l_adc_pwr(struct rzg2l_adc *adc, bool on)
    103{
    104	u32 reg;
    105
    106	reg = rzg2l_adc_readl(adc, RZG2L_ADM(0));
    107	if (on)
    108		reg |= RZG2L_ADM0_PWDWNB;
    109	else
    110		reg &= ~RZG2L_ADM0_PWDWNB;
    111	rzg2l_adc_writel(adc, RZG2L_ADM(0), reg);
    112	udelay(2);
    113}
    114
    115static void rzg2l_adc_start_stop(struct rzg2l_adc *adc, bool start)
    116{
    117	int timeout = 5;
    118	u32 reg;
    119
    120	reg = rzg2l_adc_readl(adc, RZG2L_ADM(0));
    121	if (start)
    122		reg |= RZG2L_ADM0_ADCE;
    123	else
    124		reg &= ~RZG2L_ADM0_ADCE;
    125	rzg2l_adc_writel(adc, RZG2L_ADM(0), reg);
    126
    127	if (start)
    128		return;
    129
    130	do {
    131		usleep_range(100, 200);
    132		reg = rzg2l_adc_readl(adc, RZG2L_ADM(0));
    133		timeout--;
    134		if (!timeout) {
    135			pr_err("%s stopping ADC timed out\n", __func__);
    136			break;
    137		}
    138	} while (((reg & RZG2L_ADM0_ADBSY) || (reg & RZG2L_ADM0_ADCE)));
    139}
    140
    141static void rzg2l_set_trigger(struct rzg2l_adc *adc)
    142{
    143	u32 reg;
    144
    145	/*
    146	 * Setup ADM1 for SW trigger
    147	 * EGA[13:12] - Set 00 to indicate hardware trigger is invalid
    148	 * BS[4] - Enable 1-buffer mode
    149	 * MS[1] - Enable Select mode
    150	 * TRG[0] - Enable software trigger mode
    151	 */
    152	reg = rzg2l_adc_readl(adc, RZG2L_ADM(1));
    153	reg &= ~RZG2L_ADM1_EGA_MASK;
    154	reg &= ~RZG2L_ADM1_BS;
    155	reg &= ~RZG2L_ADM1_TRG;
    156	reg |= RZG2L_ADM1_MS;
    157	rzg2l_adc_writel(adc, RZG2L_ADM(1), reg);
    158}
    159
    160static int rzg2l_adc_conversion_setup(struct rzg2l_adc *adc, u8 ch)
    161{
    162	u32 reg;
    163
    164	if (rzg2l_adc_readl(adc, RZG2L_ADM(0)) & RZG2L_ADM0_ADBSY)
    165		return -EBUSY;
    166
    167	rzg2l_set_trigger(adc);
    168
    169	/* Select analog input channel subjected to conversion. */
    170	reg = rzg2l_adc_readl(adc, RZG2L_ADM(2));
    171	reg &= ~RZG2L_ADM2_CHSEL_MASK;
    172	reg |= BIT(ch);
    173	rzg2l_adc_writel(adc, RZG2L_ADM(2), reg);
    174
    175	/*
    176	 * Setup ADINT
    177	 * INTS[31] - Select pulse signal
    178	 * CSEEN[16] - Enable channel select error interrupt
    179	 * INTEN[7:0] - Select channel interrupt
    180	 */
    181	reg = rzg2l_adc_readl(adc, RZG2L_ADINT);
    182	reg &= ~RZG2L_ADINT_INTS;
    183	reg &= ~RZG2L_ADINT_INTEN_MASK;
    184	reg |= (RZG2L_ADINT_CSEEN | BIT(ch));
    185	rzg2l_adc_writel(adc, RZG2L_ADINT, reg);
    186
    187	return 0;
    188}
    189
    190static int rzg2l_adc_set_power(struct iio_dev *indio_dev, bool on)
    191{
    192	struct device *dev = indio_dev->dev.parent;
    193
    194	if (on)
    195		return pm_runtime_resume_and_get(dev);
    196
    197	return pm_runtime_put_sync(dev);
    198}
    199
    200static int rzg2l_adc_conversion(struct iio_dev *indio_dev, struct rzg2l_adc *adc, u8 ch)
    201{
    202	int ret;
    203
    204	ret = rzg2l_adc_set_power(indio_dev, true);
    205	if (ret)
    206		return ret;
    207
    208	ret = rzg2l_adc_conversion_setup(adc, ch);
    209	if (ret) {
    210		rzg2l_adc_set_power(indio_dev, false);
    211		return ret;
    212	}
    213
    214	reinit_completion(&adc->completion);
    215
    216	rzg2l_adc_start_stop(adc, true);
    217
    218	if (!wait_for_completion_timeout(&adc->completion, RZG2L_ADC_TIMEOUT)) {
    219		rzg2l_adc_writel(adc, RZG2L_ADINT,
    220				 rzg2l_adc_readl(adc, RZG2L_ADINT) & ~RZG2L_ADINT_INTEN_MASK);
    221		rzg2l_adc_start_stop(adc, false);
    222		rzg2l_adc_set_power(indio_dev, false);
    223		return -ETIMEDOUT;
    224	}
    225
    226	return rzg2l_adc_set_power(indio_dev, false);
    227}
    228
    229static int rzg2l_adc_read_raw(struct iio_dev *indio_dev,
    230			      struct iio_chan_spec const *chan,
    231			      int *val, int *val2, long mask)
    232{
    233	struct rzg2l_adc *adc = iio_priv(indio_dev);
    234	int ret;
    235	u8 ch;
    236
    237	switch (mask) {
    238	case IIO_CHAN_INFO_RAW:
    239		if (chan->type != IIO_VOLTAGE)
    240			return -EINVAL;
    241
    242		mutex_lock(&adc->lock);
    243		ch = chan->channel & RZG2L_ADC_CHN_MASK;
    244		ret = rzg2l_adc_conversion(indio_dev, adc, ch);
    245		if (ret) {
    246			mutex_unlock(&adc->lock);
    247			return ret;
    248		}
    249		*val = adc->last_val[ch];
    250		mutex_unlock(&adc->lock);
    251
    252		return IIO_VAL_INT;
    253
    254	default:
    255		return -EINVAL;
    256	}
    257}
    258
    259static int rzg2l_adc_read_label(struct iio_dev *iio_dev,
    260				const struct iio_chan_spec *chan,
    261				char *label)
    262{
    263	if (chan->channel >= RZG2L_ADC_MAX_CHANNELS)
    264		return -EINVAL;
    265
    266	return sysfs_emit(label, "%s\n", rzg2l_adc_channel_name[chan->channel]);
    267}
    268
    269static const struct iio_info rzg2l_adc_iio_info = {
    270	.read_raw = rzg2l_adc_read_raw,
    271	.read_label = rzg2l_adc_read_label,
    272};
    273
    274static irqreturn_t rzg2l_adc_isr(int irq, void *dev_id)
    275{
    276	struct rzg2l_adc *adc = dev_id;
    277	unsigned long intst;
    278	u32 reg;
    279	int ch;
    280
    281	reg = rzg2l_adc_readl(adc, RZG2L_ADSTS);
    282
    283	/* A/D conversion channel select error interrupt */
    284	if (reg & RZG2L_ADSTS_CSEST) {
    285		rzg2l_adc_writel(adc, RZG2L_ADSTS, reg);
    286		return IRQ_HANDLED;
    287	}
    288
    289	intst = reg & RZG2L_ADSTS_INTST_MASK;
    290	if (!intst)
    291		return IRQ_NONE;
    292
    293	for_each_set_bit(ch, &intst, RZG2L_ADC_MAX_CHANNELS)
    294		adc->last_val[ch] = rzg2l_adc_readl(adc, RZG2L_ADCR(ch)) & RZG2L_ADCR_AD_MASK;
    295
    296	/* clear the channel interrupt */
    297	rzg2l_adc_writel(adc, RZG2L_ADSTS, reg);
    298
    299	complete(&adc->completion);
    300
    301	return IRQ_HANDLED;
    302}
    303
    304static int rzg2l_adc_parse_properties(struct platform_device *pdev, struct rzg2l_adc *adc)
    305{
    306	struct iio_chan_spec *chan_array;
    307	struct fwnode_handle *fwnode;
    308	struct rzg2l_adc_data *data;
    309	unsigned int channel;
    310	int num_channels;
    311	int ret;
    312	u8 i;
    313
    314	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
    315	if (!data)
    316		return -ENOMEM;
    317
    318	num_channels = device_get_child_node_count(&pdev->dev);
    319	if (!num_channels) {
    320		dev_err(&pdev->dev, "no channel children\n");
    321		return -ENODEV;
    322	}
    323
    324	if (num_channels > RZG2L_ADC_MAX_CHANNELS) {
    325		dev_err(&pdev->dev, "num of channel children out of range\n");
    326		return -EINVAL;
    327	}
    328
    329	chan_array = devm_kcalloc(&pdev->dev, num_channels, sizeof(*chan_array),
    330				  GFP_KERNEL);
    331	if (!chan_array)
    332		return -ENOMEM;
    333
    334	i = 0;
    335	device_for_each_child_node(&pdev->dev, fwnode) {
    336		ret = fwnode_property_read_u32(fwnode, "reg", &channel);
    337		if (ret) {
    338			fwnode_handle_put(fwnode);
    339			return ret;
    340		}
    341
    342		if (channel >= RZG2L_ADC_MAX_CHANNELS) {
    343			fwnode_handle_put(fwnode);
    344			return -EINVAL;
    345		}
    346
    347		chan_array[i].type = IIO_VOLTAGE;
    348		chan_array[i].indexed = 1;
    349		chan_array[i].channel = channel;
    350		chan_array[i].info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
    351		chan_array[i].datasheet_name = rzg2l_adc_channel_name[channel];
    352		i++;
    353	}
    354
    355	data->num_channels = num_channels;
    356	data->channels = chan_array;
    357	adc->data = data;
    358
    359	return 0;
    360}
    361
    362static int rzg2l_adc_hw_init(struct rzg2l_adc *adc)
    363{
    364	int timeout = 5;
    365	u32 reg;
    366	int ret;
    367
    368	ret = clk_prepare_enable(adc->pclk);
    369	if (ret)
    370		return ret;
    371
    372	/* SW reset */
    373	reg = rzg2l_adc_readl(adc, RZG2L_ADM(0));
    374	reg |= RZG2L_ADM0_SRESB;
    375	rzg2l_adc_writel(adc, RZG2L_ADM(0), reg);
    376
    377	while (!(rzg2l_adc_readl(adc, RZG2L_ADM(0)) & RZG2L_ADM0_SRESB)) {
    378		if (!timeout) {
    379			ret = -EBUSY;
    380			goto exit_hw_init;
    381		}
    382		timeout--;
    383		usleep_range(100, 200);
    384	}
    385
    386	/* Only division by 4 can be set */
    387	reg = rzg2l_adc_readl(adc, RZG2L_ADIVC);
    388	reg &= ~RZG2L_ADIVC_DIVADC_MASK;
    389	reg |= RZG2L_ADIVC_DIVADC_4;
    390	rzg2l_adc_writel(adc, RZG2L_ADIVC, reg);
    391
    392	/*
    393	 * Setup AMD3
    394	 * ADIL[31:24] - Should be always set to 0
    395	 * ADCMP[23:16] - Should be always set to 0xe
    396	 * ADSMP[15:0] - Set default (0x578) sampling period
    397	 */
    398	reg = rzg2l_adc_readl(adc, RZG2L_ADM(3));
    399	reg &= ~RZG2L_ADM3_ADIL_MASK;
    400	reg &= ~RZG2L_ADM3_ADCMP_MASK;
    401	reg &= ~RZG2L_ADM3_ADSMP_MASK;
    402	reg |= (RZG2L_ADM3_ADCMP_E | RZG2L_ADSMP_DEFAULT_SAMPLING);
    403	rzg2l_adc_writel(adc, RZG2L_ADM(3), reg);
    404
    405exit_hw_init:
    406	clk_disable_unprepare(adc->pclk);
    407
    408	return ret;
    409}
    410
    411static void rzg2l_adc_pm_runtime_disable(void *data)
    412{
    413	struct device *dev = data;
    414
    415	pm_runtime_disable(dev->parent);
    416}
    417
    418static void rzg2l_adc_pm_runtime_set_suspended(void *data)
    419{
    420	struct device *dev = data;
    421
    422	pm_runtime_set_suspended(dev->parent);
    423}
    424
    425static void rzg2l_adc_reset_assert(void *data)
    426{
    427	reset_control_assert(data);
    428}
    429
    430static int rzg2l_adc_probe(struct platform_device *pdev)
    431{
    432	struct device *dev = &pdev->dev;
    433	struct iio_dev *indio_dev;
    434	struct rzg2l_adc *adc;
    435	int ret;
    436	int irq;
    437
    438	indio_dev = devm_iio_device_alloc(dev, sizeof(*adc));
    439	if (!indio_dev)
    440		return -ENOMEM;
    441
    442	adc = iio_priv(indio_dev);
    443
    444	ret = rzg2l_adc_parse_properties(pdev, adc);
    445	if (ret)
    446		return ret;
    447
    448	mutex_init(&adc->lock);
    449
    450	adc->base = devm_platform_ioremap_resource(pdev, 0);
    451	if (IS_ERR(adc->base))
    452		return PTR_ERR(adc->base);
    453
    454	adc->pclk = devm_clk_get(dev, "pclk");
    455	if (IS_ERR(adc->pclk)) {
    456		dev_err(dev, "Failed to get pclk");
    457		return PTR_ERR(adc->pclk);
    458	}
    459
    460	adc->adclk = devm_clk_get(dev, "adclk");
    461	if (IS_ERR(adc->adclk)) {
    462		dev_err(dev, "Failed to get adclk");
    463		return PTR_ERR(adc->adclk);
    464	}
    465
    466	adc->adrstn = devm_reset_control_get_exclusive(dev, "adrst-n");
    467	if (IS_ERR(adc->adrstn)) {
    468		dev_err(dev, "failed to get adrstn\n");
    469		return PTR_ERR(adc->adrstn);
    470	}
    471
    472	adc->presetn = devm_reset_control_get_exclusive(dev, "presetn");
    473	if (IS_ERR(adc->presetn)) {
    474		dev_err(dev, "failed to get presetn\n");
    475		return PTR_ERR(adc->presetn);
    476	}
    477
    478	ret = reset_control_deassert(adc->adrstn);
    479	if (ret) {
    480		dev_err(&pdev->dev, "failed to deassert adrstn pin, %d\n", ret);
    481		return ret;
    482	}
    483
    484	ret = devm_add_action_or_reset(&pdev->dev,
    485				       rzg2l_adc_reset_assert, adc->adrstn);
    486	if (ret) {
    487		dev_err(&pdev->dev, "failed to register adrstn assert devm action, %d\n",
    488			ret);
    489		return ret;
    490	}
    491
    492	ret = reset_control_deassert(adc->presetn);
    493	if (ret) {
    494		dev_err(&pdev->dev, "failed to deassert presetn pin, %d\n", ret);
    495		return ret;
    496	}
    497
    498	ret = devm_add_action_or_reset(&pdev->dev,
    499				       rzg2l_adc_reset_assert, adc->presetn);
    500	if (ret) {
    501		dev_err(&pdev->dev, "failed to register presetn assert devm action, %d\n",
    502			ret);
    503		return ret;
    504	}
    505
    506	ret = rzg2l_adc_hw_init(adc);
    507	if (ret) {
    508		dev_err(&pdev->dev, "failed to initialize ADC HW, %d\n", ret);
    509		return ret;
    510	}
    511
    512	irq = platform_get_irq(pdev, 0);
    513	if (irq < 0)
    514		return irq;
    515
    516	ret = devm_request_irq(dev, irq, rzg2l_adc_isr,
    517			       0, dev_name(dev), adc);
    518	if (ret < 0)
    519		return ret;
    520
    521	init_completion(&adc->completion);
    522
    523	platform_set_drvdata(pdev, indio_dev);
    524
    525	indio_dev->name = DRIVER_NAME;
    526	indio_dev->info = &rzg2l_adc_iio_info;
    527	indio_dev->modes = INDIO_DIRECT_MODE;
    528	indio_dev->channels = adc->data->channels;
    529	indio_dev->num_channels = adc->data->num_channels;
    530
    531	pm_runtime_set_suspended(dev);
    532	ret = devm_add_action_or_reset(&pdev->dev,
    533				       rzg2l_adc_pm_runtime_set_suspended, &indio_dev->dev);
    534	if (ret)
    535		return ret;
    536
    537	pm_runtime_enable(dev);
    538	ret = devm_add_action_or_reset(&pdev->dev,
    539				       rzg2l_adc_pm_runtime_disable, &indio_dev->dev);
    540	if (ret)
    541		return ret;
    542
    543	return devm_iio_device_register(dev, indio_dev);
    544}
    545
    546static const struct of_device_id rzg2l_adc_match[] = {
    547	{ .compatible = "renesas,rzg2l-adc",},
    548	{ /* sentinel */ }
    549};
    550MODULE_DEVICE_TABLE(of, rzg2l_adc_match);
    551
    552static int __maybe_unused rzg2l_adc_pm_runtime_suspend(struct device *dev)
    553{
    554	struct iio_dev *indio_dev = dev_get_drvdata(dev);
    555	struct rzg2l_adc *adc = iio_priv(indio_dev);
    556
    557	rzg2l_adc_pwr(adc, false);
    558	clk_disable_unprepare(adc->adclk);
    559	clk_disable_unprepare(adc->pclk);
    560
    561	return 0;
    562}
    563
    564static int __maybe_unused rzg2l_adc_pm_runtime_resume(struct device *dev)
    565{
    566	struct iio_dev *indio_dev = dev_get_drvdata(dev);
    567	struct rzg2l_adc *adc = iio_priv(indio_dev);
    568	int ret;
    569
    570	ret = clk_prepare_enable(adc->pclk);
    571	if (ret)
    572		return ret;
    573
    574	ret = clk_prepare_enable(adc->adclk);
    575	if (ret) {
    576		clk_disable_unprepare(adc->pclk);
    577		return ret;
    578	}
    579
    580	rzg2l_adc_pwr(adc, true);
    581
    582	return 0;
    583}
    584
    585static const struct dev_pm_ops rzg2l_adc_pm_ops = {
    586	SET_RUNTIME_PM_OPS(rzg2l_adc_pm_runtime_suspend,
    587			   rzg2l_adc_pm_runtime_resume,
    588			   NULL)
    589};
    590
    591static struct platform_driver rzg2l_adc_driver = {
    592	.probe		= rzg2l_adc_probe,
    593	.driver		= {
    594		.name		= DRIVER_NAME,
    595		.of_match_table = rzg2l_adc_match,
    596		.pm		= &rzg2l_adc_pm_ops,
    597	},
    598};
    599
    600module_platform_driver(rzg2l_adc_driver);
    601
    602MODULE_AUTHOR("Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>");
    603MODULE_DESCRIPTION("Renesas RZ/G2L ADC driver");
    604MODULE_LICENSE("GPL v2");