hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/clk/mvebu/armada-37xx-periph.c
....@@ -18,6 +18,7 @@
1818 */
1919
2020 #include <linux/clk-provider.h>
21
+#include <linux/io.h>
2122 #include <linux/mfd/syscon.h>
2223 #include <linux/of.h>
2324 #include <linux/of_device.h>
....@@ -56,6 +57,15 @@
5657 struct clk_periph_driver_data {
5758 struct clk_hw_onecell_data *hw_data;
5859 spinlock_t lock;
60
+ void __iomem *reg;
61
+
62
+ /* Storage registers for suspend/resume operations */
63
+ u32 tbg_sel;
64
+ u32 div_sel0;
65
+ u32 div_sel1;
66
+ u32 div_sel2;
67
+ u32 clk_sel;
68
+ u32 clk_dis;
5969 };
6070
6171 struct clk_double_div {
....@@ -294,6 +304,7 @@
294304 PERIPH_CLK_FULL_DD(sdio, 11, 14, DIV_SEL0, DIV_SEL0, 3, 6);
295305 PERIPH_CLK_FULL_DD(usb32_usb2_sys, 16, 16, DIV_SEL0, DIV_SEL0, 9, 12);
296306 PERIPH_CLK_FULL_DD(usb32_ss_sys, 17, 18, DIV_SEL0, DIV_SEL0, 15, 18);
307
+static PERIPH_GATE(pcie, 14);
297308
298309 static struct clk_periph_data data_sb[] = {
299310 REF_CLK_MUX_DD(gbe_50),
....@@ -309,6 +320,7 @@
309320 REF_CLK_FULL_DD(sdio),
310321 REF_CLK_FULL_DD(usb32_usb2_sys),
311322 REF_CLK_FULL_DD(usb32_ss_sys),
323
+ REF_CLK_GATE(pcie, "gbe_core"),
312324 { },
313325 };
314326
....@@ -679,6 +691,40 @@
679691 return PTR_ERR_OR_ZERO(*hw);
680692 }
681693
694
+static int __maybe_unused armada_3700_periph_clock_suspend(struct device *dev)
695
+{
696
+ struct clk_periph_driver_data *data = dev_get_drvdata(dev);
697
+
698
+ data->tbg_sel = readl(data->reg + TBG_SEL);
699
+ data->div_sel0 = readl(data->reg + DIV_SEL0);
700
+ data->div_sel1 = readl(data->reg + DIV_SEL1);
701
+ data->div_sel2 = readl(data->reg + DIV_SEL2);
702
+ data->clk_sel = readl(data->reg + CLK_SEL);
703
+ data->clk_dis = readl(data->reg + CLK_DIS);
704
+
705
+ return 0;
706
+}
707
+
708
+static int __maybe_unused armada_3700_periph_clock_resume(struct device *dev)
709
+{
710
+ struct clk_periph_driver_data *data = dev_get_drvdata(dev);
711
+
712
+ /* Follow the same order than what the Cortex-M3 does (ATF code) */
713
+ writel(data->clk_dis, data->reg + CLK_DIS);
714
+ writel(data->div_sel0, data->reg + DIV_SEL0);
715
+ writel(data->div_sel1, data->reg + DIV_SEL1);
716
+ writel(data->div_sel2, data->reg + DIV_SEL2);
717
+ writel(data->tbg_sel, data->reg + TBG_SEL);
718
+ writel(data->clk_sel, data->reg + CLK_SEL);
719
+
720
+ return 0;
721
+}
722
+
723
+static const struct dev_pm_ops armada_3700_periph_clock_pm_ops = {
724
+ SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(armada_3700_periph_clock_suspend,
725
+ armada_3700_periph_clock_resume)
726
+};
727
+
682728 static int armada_3700_periph_clock_probe(struct platform_device *pdev)
683729 {
684730 struct clk_periph_driver_data *driver_data;
....@@ -687,7 +733,6 @@
687733 struct device *dev = &pdev->dev;
688734 int num_periph = 0, i, ret;
689735 struct resource *res;
690
- void __iomem *reg;
691736
692737 data = of_device_get_match_data(dev);
693738 if (!data)
....@@ -695,11 +740,6 @@
695740
696741 while (data[num_periph].name)
697742 num_periph++;
698
-
699
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
700
- reg = devm_ioremap_resource(dev, res);
701
- if (IS_ERR(reg))
702
- return PTR_ERR(reg);
703743
704744 driver_data = devm_kzalloc(dev, sizeof(*driver_data), GFP_KERNEL);
705745 if (!driver_data)
....@@ -713,12 +753,16 @@
713753 return -ENOMEM;
714754 driver_data->hw_data->num = num_periph;
715755
756
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
757
+ driver_data->reg = devm_ioremap_resource(dev, res);
758
+ if (IS_ERR(driver_data->reg))
759
+ return PTR_ERR(driver_data->reg);
760
+
716761 spin_lock_init(&driver_data->lock);
717762
718763 for (i = 0; i < num_periph; i++) {
719764 struct clk_hw **hw = &driver_data->hw_data->hws[i];
720
-
721
- if (armada_3700_add_composite_clk(&data[i], reg,
765
+ if (armada_3700_add_composite_clk(&data[i], driver_data->reg,
722766 &driver_data->lock, dev, hw))
723767 dev_err(dev, "Can't register periph clock %s\n",
724768 data[i].name);
....@@ -756,6 +800,7 @@
756800 .driver = {
757801 .name = "marvell-armada-3700-periph-clock",
758802 .of_match_table = armada_3700_periph_clock_of_match,
803
+ .pm = &armada_3700_periph_clock_pm_ops,
759804 },
760805 };
761806