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

rtc-msc313.c (6613B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Real time clocks driver for MStar/SigmaStar ARMv7 SoCs.
      4 * Based on "Real Time Clock driver for msb252x." that was contained
      5 * in various MStar kernels.
      6 *
      7 * (C) 2019 Daniel Palmer
      8 * (C) 2021 Romain Perier
      9 */
     10
     11#include <linux/clk.h>
     12#include <linux/delay.h>
     13#include <linux/io.h>
     14#include <linux/module.h>
     15#include <linux/mod_devicetable.h>
     16#include <linux/platform_device.h>
     17#include <linux/rtc.h>
     18
     19/* Registers */
     20#define REG_RTC_CTRL		0x00
     21#define REG_RTC_FREQ_CW_L	0x04
     22#define REG_RTC_FREQ_CW_H	0x08
     23#define REG_RTC_LOAD_VAL_L	0x0C
     24#define REG_RTC_LOAD_VAL_H	0x10
     25#define REG_RTC_MATCH_VAL_L	0x14
     26#define REG_RTC_MATCH_VAL_H	0x18
     27#define REG_RTC_STATUS_INT	0x1C
     28#define REG_RTC_CNT_VAL_L	0x20
     29#define REG_RTC_CNT_VAL_H	0x24
     30
     31/* Control bits for REG_RTC_CTRL */
     32#define SOFT_RSTZ_BIT		BIT(0)
     33#define CNT_EN_BIT		BIT(1)
     34#define WRAP_EN_BIT		BIT(2)
     35#define LOAD_EN_BIT		BIT(3)
     36#define READ_EN_BIT		BIT(4)
     37#define INT_MASK_BIT		BIT(5)
     38#define INT_FORCE_BIT		BIT(6)
     39#define INT_CLEAR_BIT		BIT(7)
     40
     41/* Control bits for REG_RTC_STATUS_INT */
     42#define RAW_INT_BIT		BIT(0)
     43#define ALM_INT_BIT		BIT(1)
     44
     45struct msc313_rtc {
     46	struct rtc_device *rtc_dev;
     47	void __iomem *rtc_base;
     48};
     49
     50static int msc313_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
     51{
     52	struct msc313_rtc *priv = dev_get_drvdata(dev);
     53	unsigned long seconds;
     54
     55	seconds = readw(priv->rtc_base + REG_RTC_MATCH_VAL_L)
     56			| ((unsigned long)readw(priv->rtc_base + REG_RTC_MATCH_VAL_H) << 16);
     57
     58	rtc_time64_to_tm(seconds, &alarm->time);
     59
     60	if (!(readw(priv->rtc_base + REG_RTC_CTRL) & INT_MASK_BIT))
     61		alarm->enabled = 1;
     62
     63	return 0;
     64}
     65
     66static int msc313_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
     67{
     68	struct msc313_rtc *priv = dev_get_drvdata(dev);
     69	u16 reg;
     70
     71	reg = readw(priv->rtc_base + REG_RTC_CTRL);
     72	if (enabled)
     73		reg &= ~INT_MASK_BIT;
     74	else
     75		reg |= INT_MASK_BIT;
     76	writew(reg, priv->rtc_base + REG_RTC_CTRL);
     77	return 0;
     78}
     79
     80static int msc313_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
     81{
     82	struct msc313_rtc *priv = dev_get_drvdata(dev);
     83	unsigned long seconds;
     84
     85	seconds = rtc_tm_to_time64(&alarm->time);
     86	writew((seconds & 0xFFFF), priv->rtc_base + REG_RTC_MATCH_VAL_L);
     87	writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_MATCH_VAL_H);
     88
     89	msc313_rtc_alarm_irq_enable(dev, alarm->enabled);
     90
     91	return 0;
     92}
     93
     94static bool msc313_rtc_get_enabled(struct msc313_rtc *priv)
     95{
     96	return readw(priv->rtc_base + REG_RTC_CTRL) & CNT_EN_BIT;
     97}
     98
     99static void msc313_rtc_set_enabled(struct msc313_rtc *priv)
    100{
    101	u16 reg;
    102
    103	reg = readw(priv->rtc_base + REG_RTC_CTRL);
    104	reg |= CNT_EN_BIT;
    105	writew(reg, priv->rtc_base + REG_RTC_CTRL);
    106}
    107
    108static int msc313_rtc_read_time(struct device *dev, struct rtc_time *tm)
    109{
    110	struct msc313_rtc *priv = dev_get_drvdata(dev);
    111	u32 seconds;
    112	u16 reg;
    113
    114	if (!msc313_rtc_get_enabled(priv))
    115		return -EINVAL;
    116
    117	reg = readw(priv->rtc_base + REG_RTC_CTRL);
    118	writew(reg | READ_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
    119
    120	/* Wait for HW latch done */
    121	while (readw(priv->rtc_base + REG_RTC_CTRL) & READ_EN_BIT)
    122		udelay(1);
    123
    124	seconds = readw(priv->rtc_base + REG_RTC_CNT_VAL_L)
    125			| ((unsigned long)readw(priv->rtc_base + REG_RTC_CNT_VAL_H) << 16);
    126
    127	rtc_time64_to_tm(seconds, tm);
    128
    129	return 0;
    130}
    131
    132static int msc313_rtc_set_time(struct device *dev, struct rtc_time *tm)
    133{
    134	struct msc313_rtc *priv = dev_get_drvdata(dev);
    135	unsigned long seconds;
    136	u16 reg;
    137
    138	seconds = rtc_tm_to_time64(tm);
    139	writew(seconds & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_L);
    140	writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_H);
    141
    142	/* Enable load for loading value into internal RTC counter */
    143	reg = readw(priv->rtc_base + REG_RTC_CTRL);
    144	writew(reg | LOAD_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
    145
    146	/* Wait for HW latch done */
    147	while (readw(priv->rtc_base + REG_RTC_CTRL) & LOAD_EN_BIT)
    148		udelay(1);
    149	msc313_rtc_set_enabled(priv);
    150	return 0;
    151}
    152
    153static const struct rtc_class_ops msc313_rtc_ops = {
    154	.read_time = msc313_rtc_read_time,
    155	.set_time = msc313_rtc_set_time,
    156	.read_alarm = msc313_rtc_read_alarm,
    157	.set_alarm = msc313_rtc_set_alarm,
    158	.alarm_irq_enable = msc313_rtc_alarm_irq_enable,
    159};
    160
    161static irqreturn_t msc313_rtc_interrupt(s32 irq, void *dev_id)
    162{
    163	struct msc313_rtc *priv = dev_get_drvdata(dev_id);
    164	u16 reg;
    165
    166	reg = readw(priv->rtc_base + REG_RTC_STATUS_INT);
    167	if (!(reg & ALM_INT_BIT))
    168		return IRQ_NONE;
    169
    170	reg = readw(priv->rtc_base + REG_RTC_CTRL);
    171	reg |= INT_CLEAR_BIT;
    172	reg &= ~INT_FORCE_BIT;
    173	writew(reg, priv->rtc_base + REG_RTC_CTRL);
    174
    175	rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF);
    176
    177	return IRQ_HANDLED;
    178}
    179
    180static int msc313_rtc_probe(struct platform_device *pdev)
    181{
    182	struct device *dev = &pdev->dev;
    183	struct msc313_rtc *priv;
    184	unsigned long rate;
    185	struct clk *clk;
    186	int ret;
    187	int irq;
    188
    189	priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL);
    190	if (!priv)
    191		return -ENOMEM;
    192
    193	priv->rtc_base = devm_platform_ioremap_resource(pdev, 0);
    194	if (IS_ERR(priv->rtc_base))
    195		return PTR_ERR(priv->rtc_base);
    196
    197	irq = platform_get_irq(pdev, 0);
    198	if (irq < 0)
    199		return -EINVAL;
    200
    201	priv->rtc_dev = devm_rtc_allocate_device(dev);
    202	if (IS_ERR(priv->rtc_dev))
    203		return PTR_ERR(priv->rtc_dev);
    204
    205	priv->rtc_dev->ops = &msc313_rtc_ops;
    206	priv->rtc_dev->range_max = U32_MAX;
    207
    208	ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,
    209			       dev_name(&pdev->dev), &pdev->dev);
    210	if (ret) {
    211		dev_err(dev, "Could not request IRQ\n");
    212		return ret;
    213	}
    214
    215	clk = devm_clk_get(dev, NULL);
    216	if (IS_ERR(clk)) {
    217		dev_err(dev, "No input reference clock\n");
    218		return PTR_ERR(clk);
    219	}
    220
    221	ret = clk_prepare_enable(clk);
    222	if (ret) {
    223		dev_err(dev, "Failed to enable the reference clock, %d\n", ret);
    224		return ret;
    225	}
    226
    227	ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, clk);
    228	if (ret)
    229		return ret;
    230
    231	rate = clk_get_rate(clk);
    232	writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
    233	writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
    234
    235	platform_set_drvdata(pdev, priv);
    236
    237	return devm_rtc_register_device(priv->rtc_dev);
    238}
    239
    240static const struct of_device_id msc313_rtc_of_match_table[] = {
    241	{ .compatible = "mstar,msc313-rtc" },
    242	{ }
    243};
    244MODULE_DEVICE_TABLE(of, msc313_rtc_of_match_table);
    245
    246static struct platform_driver msc313_rtc_driver = {
    247	.probe = msc313_rtc_probe,
    248	.driver = {
    249		.name = "msc313-rtc",
    250		.of_match_table = msc313_rtc_of_match_table,
    251	},
    252};
    253
    254module_platform_driver(msc313_rtc_driver);
    255
    256MODULE_AUTHOR("Daniel Palmer <daniel@thingy.jp>");
    257MODULE_AUTHOR("Romain Perier <romain.perier@gmail.com>");
    258MODULE_DESCRIPTION("MStar RTC Driver");
    259MODULE_LICENSE("GPL v2");