> -Original Message-
> From: Biwen Li
> Sent: Friday, July 5, 2019 5:18 AM
> To: a.zu...@towertech.it; alexandre.bell...@bootlin.com; Leo Li
>
> Cc: linux-...@vger.kernel.org; linux-kernel@vger.kernel.org; Xiaobo Xie
> ; Jiafei Pan ; Ran Wang
> ; Biwen Li
> Subject: [PATCH 1/2] rtc/fsl: add FTM alarm driver as the wakeup source
>
> For the paltforms including LS1012A, LS1021A, LS1028A, LS1043A, LS1046A,
> LS1088A, LS208xA that has the FlexTimer module, implementing alarm
> functions within RTC subsystem to wakeup the system when system going to
> sleep.
>
> Signed-off-by: Biwen Li
> ---
> drivers/rtc/Kconfig | 14 ++
> drivers/rtc/Makefile| 1 +
> drivers/rtc/rtc-fsl-ftm-alarm.c | 417
>
> 3 files changed, 432 insertions(+)
> create mode 100644 drivers/rtc/rtc-fsl-ftm-alarm.c
>
> diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 03b60d5..0758a08
> 100644
> --- a/drivers/rtc/Kconfig
> +++ b/drivers/rtc/Kconfig
> @@ -1313,6 +1313,20 @@ config RTC_DRV_IMXDI
> This driver can also be built as a module, if so, the module
> will be called "rtc-imxdi".
>
> +config RTC_DRV_FSL_FTM_ALARM
> + tristate "Freescale FlexTimer alarm timer"
> + depends on ARCH_LAYERSCAPE
> + default y
> + help
> +For the FlexTimer in LS1012A, LS1021A, LS1028A, LS1043A, LS1046A,
> +LS1088A, LS208xA, we can use FTM as the wakeup source.
> +
> +Say y here to enable FTM alarm support. The FTM alarm provides
> +alarm functions for wakeup system from deep sleep.
> +
> +This driver can also be built as a module, if so, the module
> +will be called "rtc-fsl-ftm-alarm".
> +
> config RTC_DRV_MESON
> tristate "Amlogic Meson RTC"
> depends on (ARM && ARCH_MESON) || COMPILE_TEST diff --git
> a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 9d997fa..5cccb07 100644
> --- a/drivers/rtc/Makefile
> +++ b/drivers/rtc/Makefile
> @@ -79,6 +79,7 @@ obj-$(CONFIG_RTC_DRV_HID_SENSOR_TIME) += rtc-
> hid-sensor-time.o
> obj-$(CONFIG_RTC_DRV_HYM8563)+= rtc-hym8563.o
> obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o
> obj-$(CONFIG_RTC_DRV_IMX_SC) += rtc-imx-sc.o
> +obj-$(CONFIG_RTC_DRV_FSL_FTM_ALARM) += rtc-fsl-ftm-alarm.o
> obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o
> obj-$(CONFIG_RTC_DRV_ISL12026) += rtc-isl12026.o
> obj-$(CONFIG_RTC_DRV_ISL1208)+= rtc-isl1208.o
> diff --git a/drivers/rtc/rtc-fsl-ftm-alarm.c b/drivers/rtc/rtc-fsl-ftm-alarm.c
> new file mode 100644 index 000..e4075f0
> --- /dev/null
> +++ b/drivers/rtc/rtc-fsl-ftm-alarm.c
> @@ -0,0 +1,417 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Freescale FlexTimer Module (FTM) alarm device driver.
> + *
> + * Copyright 2014 Freescale Semiconductor, Inc.
> + * Copyright 2019 NXP
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + */
> +
> +#include
> +#include
> +#include
> +#include
> +#include
> +#include
> +#include
> +#include
> +#include
> +#include
> +#include
> +#include
> +#include
> +
> +#define FTM_SC_CLK(c)((c) << FTM_SC_CLK_MASK_SHIFT)
> +
> +/*
> + * Select Fixed frequency clock as clock source
> + * of FlexTimer Module
> + */
> +#define FTM_SC_CLKS_FIXED_FREQ 0x02
> +
> +#define FIXED_FREQ_CLK 32000
> +#define MAX_FREQ_DIV (1 << FTM_SC_PS_MASK)
> +#define MAX_COUNT_VAL0x
> +
> +struct ftm_rtc {
> + struct rtc_device *rtc_dev;
> + void __iomem *base;
> + bool endian;
> + u32 alarm_freq;
> +};
> +
> +enum pmu_endian_type {
> + BIG_ENDIAN,
> + LITTLE_ENDIAN,
> +};
> +
> +/*
> + * rcpm (Run Control and Power Management)
> + * is another IP block,different IP block
> + * has different endianness,so add new element
> + * big_endian to struct rcpm_cfg.
> + */
> +struct rcpm_cfg {
> + enum pmu_endian_type big_endian; /* Big/Little endian of PMU
> module */
> + u32 flextimer_set_bit; /* FTM is not powerdown during device
> sleep */
> +};
> +
> +static struct rcpm_cfg default_rcpm_cfg = {
> + .big_endian = LITTLE_ENDIAN,
> + .flextimer_set_bit = 0x4000,
> +};
> +
> +static struct rcpm_cfg ls1012a_rcpm_cfg = {
> + .big_endian = BIG_ENDIAN,
> + .flextimer_set_bit = 0x2,
> +};
> +
> +static struct rcpm_cfg ls1021a_rcpm_cfg = {
> + .big_endian = BIG_ENDIAN,
> + .flextimer_set_bit = 0x2,
> +};
> +
> +static struct rcpm_cfg ls1043a_rcpm_cfg = {
> + .big_endian = BIG_ENDIAN,
> + .flextimer_set_bit = 0x2,
> +};
> +
> +static struct rcpm_cfg ls1046a_rcpm_cfg = {
> + .big_endian = BIG_ENDIAN,
> + .flextimer_set_bit = 0x2,
> +};
> +
> +static struct rcpm_cfg ls1088a_rcpm_cfg = {
> + .big_end