summaryrefslogtreecommitdiff
path: root/drivers/soc
diff options
context:
space:
mode:
authorZhang Ying-22455 <ying.zhang22455@nxp.com>2017-09-19 08:32:52 (GMT)
committerXie Xiaobo <xiaobo.xie@nxp.com>2017-09-28 08:04:59 (GMT)
commit42561e5cb637843ec09a33f7ca53c1448d35eddf (patch)
tree2d314bdba7630bfc2c1402f12b93520fad98d736 /drivers/soc
parentf929ec10f7e2f62ab4d2765690e40ad34efed4ee (diff)
downloadlinux-42561e5cb637843ec09a33f7ca53c1448d35eddf.tar.xz
soc: fsl: set rcpm bit for FTM
Set RCPM for FTM when using FTM as wakeup source. Because the RCPM module of each platform has different big-end and little-end mode, there need to set RCPM depending on the platform. Signed-off-by: Zhang Ying-22455 <ying.zhang22455@nxp.com>
Diffstat (limited to 'drivers/soc')
-rw-r--r--drivers/soc/fsl/layerscape/ftm_alarm.c90
1 files changed, 85 insertions, 5 deletions
diff --git a/drivers/soc/fsl/layerscape/ftm_alarm.c b/drivers/soc/fsl/layerscape/ftm_alarm.c
index 6f9882f..d1b947f 100644
--- a/drivers/soc/fsl/layerscape/ftm_alarm.c
+++ b/drivers/soc/fsl/layerscape/ftm_alarm.c
@@ -16,6 +16,9 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/libata.h>
#define FTM_SC 0x00
#define FTM_SC_CLK_SHIFT 3
@@ -40,6 +43,57 @@ static void __iomem *rcpm_ftm_addr;
static u32 alarm_freq;
static bool big_endian;
+enum pmu_endian_type {
+ BIG_ENDIAN,
+ LITTLE_ENDIAN,
+};
+
+struct rcpm_cfg {
+ enum pmu_endian_type big_endian; /* Big/Little endian of PMU module */
+ u32 flextimer_set_bit; /* FlexTimer1 is not powerdown during device LPM20 */
+};
+
+static struct rcpm_cfg ls1012a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1021a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1043a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1046a_rcpm_cfg = {
+ .big_endian = BIG_ENDIAN,
+ .flextimer_set_bit = 0x20000,
+};
+
+static struct rcpm_cfg ls1088a_rcpm_cfg = {
+ .big_endian = LITTLE_ENDIAN,
+ .flextimer_set_bit = 0x4000,
+};
+
+static struct rcpm_cfg ls208xa_rcpm_cfg = {
+ .big_endian = LITTLE_ENDIAN,
+ .flextimer_set_bit = 0x4000,
+};
+
+static const struct of_device_id ippdexpcr_of_match[] = {
+ { .compatible = "fsl,ls1012a-ftm", .data = &ls1012a_rcpm_cfg},
+ { .compatible = "fsl,ls1021a-ftm", .data = &ls1021a_rcpm_cfg},
+ { .compatible = "fsl,ls1043a-ftm", .data = &ls1043a_rcpm_cfg},
+ { .compatible = "fsl,ls1046a-ftm", .data = &ls1046a_rcpm_cfg},
+ { .compatible = "fsl,ls1088a-ftm", .data = &ls1088a_rcpm_cfg},
+ { .compatible = "fsl,ls208xa-ftm", .data = &ls208xa_rcpm_cfg},
+ {},
+};
+MODULE_DEVICE_TABLE(of, ippdexpcr_of_match);
+
static inline u32 ftm_readl(void __iomem *addr)
{
if (big_endian)
@@ -214,7 +268,10 @@ static int ftm_alarm_probe(struct platform_device *pdev)
struct resource *r;
int irq;
int ret;
- u32 ippdexpcr;
+ struct rcpm_cfg *rcpm_cfg;
+ u32 ippdexpcr, flextimer;
+ const struct of_device_id *of_id;
+ enum pmu_endian_type endian;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r)
@@ -224,14 +281,32 @@ static int ftm_alarm_probe(struct platform_device *pdev)
if (IS_ERR(ftm1_base))
return PTR_ERR(ftm1_base);
+ of_id = of_match_node(ippdexpcr_of_match, np);
+ if (!of_id)
+ return -ENODEV;
+
+ rcpm_cfg = devm_kzalloc(&pdev->dev, sizeof(*rcpm_cfg), GFP_KERNEL);
+ if (!rcpm_cfg)
+ return -ENOMEM;
+
+ rcpm_cfg = (struct rcpm_cfg*)of_id->data;
+ endian = rcpm_cfg->big_endian;
+ flextimer = rcpm_cfg->flextimer_set_bit;
+
r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "FlexTimer1");
if (r) {
rcpm_ftm_addr = devm_ioremap_resource(&pdev->dev, r);
if (IS_ERR(rcpm_ftm_addr))
return PTR_ERR(rcpm_ftm_addr);
- ippdexpcr = ioread32be(rcpm_ftm_addr);
- ippdexpcr |= 0x20000;
- iowrite32be(ippdexpcr, rcpm_ftm_addr);
+ if (endian == BIG_ENDIAN)
+ ippdexpcr = ioread32be(rcpm_ftm_addr);
+ else
+ ippdexpcr = ioread32(rcpm_ftm_addr);
+ ippdexpcr |= flextimer;
+ if (endian == BIG_ENDIAN)
+ iowrite32be(ippdexpcr, rcpm_ftm_addr);
+ else
+ iowrite32(ippdexpcr, rcpm_ftm_addr);
}
irq = irq_of_parse_and_map(np, 0);
@@ -265,7 +340,12 @@ static int ftm_alarm_probe(struct platform_device *pdev)
}
static const struct of_device_id ftm_alarm_match[] = {
- { .compatible = "fsl,ftm-alarm", },
+ { .compatible = "fsl,ls1012a-ftm", },
+ { .compatible = "fsl,ls1021a-ftm", },
+ { .compatible = "fsl,ls1043a-ftm", },
+ { .compatible = "fsl,ls1046a-ftm", },
+ { .compatible = "fsl,ls1088a-ftm", },
+ { .compatible = "fsl,ls208xa-ftm", },
{ .compatible = "fsl,ftm-timer", },
{ },
};