forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
kernel/drivers/pinctrl/tegra/pinctrl-tegra.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Driver for the NVIDIA Tegra pinmux
34 *
....@@ -7,15 +8,6 @@
78 * Copyright (C) 2010 Google, Inc.
89 * Copyright (C) 2010 NVIDIA Corporation
910 * Copyright (C) 2009-2011 ST-Ericsson AB
10
- *
11
- * This program is free software; you can redistribute it and/or modify it
12
- * under the terms and conditions of the GNU General Public License,
13
- * version 2, as published by the Free Software Foundation.
14
- *
15
- * This program is distributed in the hope it will be useful, but WITHOUT
16
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18
- * more details.
1911 */
2012
2113 #include <linux/err.h>
....@@ -283,18 +275,64 @@
283275 return 0;
284276 }
285277
278
+static int tegra_pinctrl_gpio_request_enable(struct pinctrl_dev *pctldev,
279
+ struct pinctrl_gpio_range *range,
280
+ unsigned int offset)
281
+{
282
+ struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
283
+ const struct tegra_pingroup *group;
284
+ u32 value;
285
+
286
+ if (!pmx->soc->sfsel_in_mux)
287
+ return 0;
288
+
289
+ group = &pmx->soc->groups[offset];
290
+
291
+ if (group->mux_reg < 0 || group->sfsel_bit < 0)
292
+ return -EINVAL;
293
+
294
+ value = pmx_readl(pmx, group->mux_bank, group->mux_reg);
295
+ value &= ~BIT(group->sfsel_bit);
296
+ pmx_writel(pmx, value, group->mux_bank, group->mux_reg);
297
+
298
+ return 0;
299
+}
300
+
301
+static void tegra_pinctrl_gpio_disable_free(struct pinctrl_dev *pctldev,
302
+ struct pinctrl_gpio_range *range,
303
+ unsigned int offset)
304
+{
305
+ struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
306
+ const struct tegra_pingroup *group;
307
+ u32 value;
308
+
309
+ if (!pmx->soc->sfsel_in_mux)
310
+ return;
311
+
312
+ group = &pmx->soc->groups[offset];
313
+
314
+ if (group->mux_reg < 0 || group->sfsel_bit < 0)
315
+ return;
316
+
317
+ value = pmx_readl(pmx, group->mux_bank, group->mux_reg);
318
+ value |= BIT(group->sfsel_bit);
319
+ pmx_writel(pmx, value, group->mux_bank, group->mux_reg);
320
+}
321
+
286322 static const struct pinmux_ops tegra_pinmux_ops = {
287323 .get_functions_count = tegra_pinctrl_get_funcs_count,
288324 .get_function_name = tegra_pinctrl_get_func_name,
289325 .get_function_groups = tegra_pinctrl_get_func_groups,
290326 .set_mux = tegra_pinctrl_set_mux,
327
+ .gpio_request_enable = tegra_pinctrl_gpio_request_enable,
328
+ .gpio_disable_free = tegra_pinctrl_gpio_disable_free,
291329 };
292330
293331 static int tegra_pinconf_reg(struct tegra_pmx *pmx,
294332 const struct tegra_pingroup *g,
295333 enum tegra_pinconf_param param,
296334 bool report_err,
297
- s8 *bank, s16 *reg, s8 *bit, s8 *width)
335
+ s8 *bank, s32 *reg, s8 *bit, s8 *width)
298336 {
299337 switch (param) {
300338 case TEGRA_PINCONF_PARAM_PULL:
....@@ -453,7 +491,7 @@
453491 const struct tegra_pingroup *g;
454492 int ret;
455493 s8 bank, bit, width;
456
- s16 reg;
494
+ s32 reg;
457495 u32 val, mask;
458496
459497 g = &pmx->soc->groups[group];
....@@ -482,7 +520,7 @@
482520 const struct tegra_pingroup *g;
483521 int ret, i;
484522 s8 bank, bit, width;
485
- s16 reg;
523
+ s32 reg;
486524 u32 val, mask;
487525
488526 g = &pmx->soc->groups[group];
....@@ -550,7 +588,7 @@
550588 const struct tegra_pingroup *g;
551589 int i, ret;
552590 s8 bank, bit, width;
553
- s16 reg;
591
+ s32 reg;
554592 u32 val;
555593
556594 g = &pmx->soc->groups[group];
....@@ -623,20 +661,86 @@
623661
624662 for (i = 0; i < pmx->soc->ngroups; ++i) {
625663 g = &pmx->soc->groups[i];
626
- if (g->parked_bit >= 0) {
627
- val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
628
- val &= ~(1 << g->parked_bit);
629
- pmx_writel(pmx, val, g->mux_bank, g->mux_reg);
664
+ if (g->parked_bitmask > 0) {
665
+ unsigned int bank, reg;
666
+
667
+ if (g->mux_reg != -1) {
668
+ bank = g->mux_bank;
669
+ reg = g->mux_reg;
670
+ } else {
671
+ bank = g->drv_bank;
672
+ reg = g->drv_reg;
673
+ }
674
+
675
+ val = pmx_readl(pmx, bank, reg);
676
+ val &= ~g->parked_bitmask;
677
+ pmx_writel(pmx, val, bank, reg);
630678 }
631679 }
632680 }
633681
634
-static bool gpio_node_has_range(const char *compatible)
682
+static size_t tegra_pinctrl_get_bank_size(struct device *dev,
683
+ unsigned int bank_id)
684
+{
685
+ struct platform_device *pdev = to_platform_device(dev);
686
+ struct resource *res;
687
+
688
+ res = platform_get_resource(pdev, IORESOURCE_MEM, bank_id);
689
+
690
+ return resource_size(res) / 4;
691
+}
692
+
693
+static int tegra_pinctrl_suspend(struct device *dev)
694
+{
695
+ struct tegra_pmx *pmx = dev_get_drvdata(dev);
696
+ u32 *backup_regs = pmx->backup_regs;
697
+ u32 __iomem *regs;
698
+ size_t bank_size;
699
+ unsigned int i, k;
700
+
701
+ for (i = 0; i < pmx->nbanks; i++) {
702
+ bank_size = tegra_pinctrl_get_bank_size(dev, i);
703
+ regs = pmx->regs[i];
704
+ for (k = 0; k < bank_size; k++)
705
+ *backup_regs++ = readl_relaxed(regs++);
706
+ }
707
+
708
+ return pinctrl_force_sleep(pmx->pctl);
709
+}
710
+
711
+static int tegra_pinctrl_resume(struct device *dev)
712
+{
713
+ struct tegra_pmx *pmx = dev_get_drvdata(dev);
714
+ u32 *backup_regs = pmx->backup_regs;
715
+ u32 __iomem *regs;
716
+ size_t bank_size;
717
+ unsigned int i, k;
718
+
719
+ for (i = 0; i < pmx->nbanks; i++) {
720
+ bank_size = tegra_pinctrl_get_bank_size(dev, i);
721
+ regs = pmx->regs[i];
722
+ for (k = 0; k < bank_size; k++)
723
+ writel_relaxed(*backup_regs++, regs++);
724
+ }
725
+
726
+ /* flush all the prior writes */
727
+ readl_relaxed(pmx->regs[0]);
728
+ /* wait for pinctrl register read to complete */
729
+ rmb();
730
+ return 0;
731
+}
732
+
733
+const struct dev_pm_ops tegra_pinctrl_pm = {
734
+ .suspend_noirq = &tegra_pinctrl_suspend,
735
+ .resume_noirq = &tegra_pinctrl_resume
736
+};
737
+
738
+static bool tegra_pinctrl_gpio_node_has_range(struct tegra_pmx *pmx)
635739 {
636740 struct device_node *np;
637741 bool has_prop = false;
638742
639
- np = of_find_compatible_node(NULL, NULL, compatible);
743
+ np = of_find_compatible_node(NULL, NULL, pmx->soc->gpio_compatible);
640744 if (!np)
641745 return has_prop;
642746
....@@ -655,6 +759,7 @@
655759 int i;
656760 const char **group_pins;
657761 int fn, gn, gfn;
762
+ unsigned long backup_regs_size = 0;
658763
659764 pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
660765 if (!pmx)
....@@ -707,6 +812,7 @@
707812 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
708813 if (!res)
709814 break;
815
+ backup_regs_size += resource_size(res);
710816 }
711817 pmx->nbanks = i;
712818
....@@ -715,9 +821,13 @@
715821 if (!pmx->regs)
716822 return -ENOMEM;
717823
824
+ pmx->backup_regs = devm_kzalloc(&pdev->dev, backup_regs_size,
825
+ GFP_KERNEL);
826
+ if (!pmx->backup_regs)
827
+ return -ENOMEM;
828
+
718829 for (i = 0; i < pmx->nbanks; i++) {
719
- res = platform_get_resource(pdev, IORESOURCE_MEM, i);
720
- pmx->regs[i] = devm_ioremap_resource(&pdev->dev, res);
830
+ pmx->regs[i] = devm_platform_ioremap_resource(pdev, i);
721831 if (IS_ERR(pmx->regs[i]))
722832 return PTR_ERR(pmx->regs[i]);
723833 }
....@@ -730,7 +840,7 @@
730840
731841 tegra_pinctrl_clear_parked_bits(pmx);
732842
733
- if (!gpio_node_has_range(pmx->soc->gpio_compatible))
843
+ if (pmx->soc->ngpios > 0 && !tegra_pinctrl_gpio_node_has_range(pmx))
734844 pinctrl_add_gpio_range(pmx->pctl, &tegra_pinctrl_gpio_range);
735845
736846 platform_set_drvdata(pdev, pmx);
....@@ -739,4 +849,3 @@
739849
740850 return 0;
741851 }
742
-EXPORT_SYMBOL_GPL(tegra_pinctrl_probe);