aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/pinmux.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/pinmux.c')
-rw-r--r--arch/arm/mach-tegra/pinmux.c163
1 files changed, 132 insertions, 31 deletions
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
index f80d507671bc..1d201650d7a4 100644
--- a/arch/arm/mach-tegra/pinmux.c
+++ b/arch/arm/mach-tegra/pinmux.c
@@ -20,6 +20,7 @@
20#include <linux/errno.h> 20#include <linux/errno.h>
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/platform_device.h>
23 24
24#include <mach/iomap.h> 25#include <mach/iomap.h>
25#include <mach/pinmux.h> 26#include <mach/pinmux.h>
@@ -169,15 +170,17 @@ static const char *pupd_name(unsigned long val)
169 } 170 }
170} 171}
171 172
173static int nbanks;
174static void __iomem **regs;
172 175
173static inline unsigned long pg_readl(unsigned long offset) 176static inline u32 pg_readl(u32 bank, u32 reg)
174{ 177{
175 return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); 178 return readl(regs[bank] + reg);
176} 179}
177 180
178static inline void pg_writel(unsigned long value, unsigned long offset) 181static inline void pg_writel(u32 val, u32 bank, u32 reg)
179{ 182{
180 writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); 183 writel(val, regs[bank] + reg);
181} 184}
182 185
183static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config) 186static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
@@ -217,10 +220,10 @@ static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
217 220
218 spin_lock_irqsave(&mux_lock, flags); 221 spin_lock_irqsave(&mux_lock, flags);
219 222
220 reg = pg_readl(pingroups[pg].mux_reg); 223 reg = pg_readl(pingroups[pg].mux_bank, pingroups[pg].mux_reg);
221 reg &= ~(0x3 << pingroups[pg].mux_bit); 224 reg &= ~(0x3 << pingroups[pg].mux_bit);
222 reg |= mux << pingroups[pg].mux_bit; 225 reg |= mux << pingroups[pg].mux_bit;
223 pg_writel(reg, pingroups[pg].mux_reg); 226 pg_writel(reg, pingroups[pg].mux_bank, pingroups[pg].mux_reg);
224 227
225 spin_unlock_irqrestore(&mux_lock, flags); 228 spin_unlock_irqrestore(&mux_lock, flags);
226 229
@@ -241,11 +244,11 @@ int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
241 244
242 spin_lock_irqsave(&mux_lock, flags); 245 spin_lock_irqsave(&mux_lock, flags);
243 246
244 reg = pg_readl(pingroups[pg].tri_reg); 247 reg = pg_readl(pingroups[pg].tri_bank, pingroups[pg].tri_reg);
245 reg &= ~(0x1 << pingroups[pg].tri_bit); 248 reg &= ~(0x1 << pingroups[pg].tri_bit);
246 if (tristate) 249 if (tristate)
247 reg |= 1 << pingroups[pg].tri_bit; 250 reg |= 1 << pingroups[pg].tri_bit;
248 pg_writel(reg, pingroups[pg].tri_reg); 251 pg_writel(reg, pingroups[pg].tri_bank, pingroups[pg].tri_reg);
249 252
250 spin_unlock_irqrestore(&mux_lock, flags); 253 spin_unlock_irqrestore(&mux_lock, flags);
251 254
@@ -272,10 +275,10 @@ int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
272 275
273 spin_lock_irqsave(&mux_lock, flags); 276 spin_lock_irqsave(&mux_lock, flags);
274 277
275 reg = pg_readl(pingroups[pg].pupd_reg); 278 reg = pg_readl(pingroups[pg].pupd_bank, pingroups[pg].pupd_reg);
276 reg &= ~(0x3 << pingroups[pg].pupd_bit); 279 reg &= ~(0x3 << pingroups[pg].pupd_bit);
277 reg |= pupd << pingroups[pg].pupd_bit; 280 reg |= pupd << pingroups[pg].pupd_bit;
278 pg_writel(reg, pingroups[pg].pupd_reg); 281 pg_writel(reg, pingroups[pg].pupd_bank, pingroups[pg].pupd_reg);
279 282
280 spin_unlock_irqrestore(&mux_lock, flags); 283 spin_unlock_irqrestore(&mux_lock, flags);
281 284
@@ -362,12 +365,12 @@ static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg,
362 365
363 spin_lock_irqsave(&mux_lock, flags); 366 spin_lock_irqsave(&mux_lock, flags);
364 367
365 reg = pg_readl(drive_pingroups[pg].reg); 368 reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
366 if (hsm == TEGRA_HSM_ENABLE) 369 if (hsm == TEGRA_HSM_ENABLE)
367 reg |= (1 << 2); 370 reg |= (1 << 2);
368 else 371 else
369 reg &= ~(1 << 2); 372 reg &= ~(1 << 2);
370 pg_writel(reg, drive_pingroups[pg].reg); 373 pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
371 374
372 spin_unlock_irqrestore(&mux_lock, flags); 375 spin_unlock_irqrestore(&mux_lock, flags);
373 376
@@ -387,12 +390,12 @@ static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg,
387 390
388 spin_lock_irqsave(&mux_lock, flags); 391 spin_lock_irqsave(&mux_lock, flags);
389 392
390 reg = pg_readl(drive_pingroups[pg].reg); 393 reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
391 if (schmitt == TEGRA_SCHMITT_ENABLE) 394 if (schmitt == TEGRA_SCHMITT_ENABLE)
392 reg |= (1 << 3); 395 reg |= (1 << 3);
393 else 396 else
394 reg &= ~(1 << 3); 397 reg &= ~(1 << 3);
395 pg_writel(reg, drive_pingroups[pg].reg); 398 pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
396 399
397 spin_unlock_irqrestore(&mux_lock, flags); 400 spin_unlock_irqrestore(&mux_lock, flags);
398 401
@@ -412,10 +415,10 @@ static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg,
412 415
413 spin_lock_irqsave(&mux_lock, flags); 416 spin_lock_irqsave(&mux_lock, flags);
414 417
415 reg = pg_readl(drive_pingroups[pg].reg); 418 reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
416 reg &= ~(0x3 << 4); 419 reg &= ~(0x3 << 4);
417 reg |= drive << 4; 420 reg |= drive << 4;
418 pg_writel(reg, drive_pingroups[pg].reg); 421 pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
419 422
420 spin_unlock_irqrestore(&mux_lock, flags); 423 spin_unlock_irqrestore(&mux_lock, flags);
421 424
@@ -435,10 +438,10 @@ static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg,
435 438
436 spin_lock_irqsave(&mux_lock, flags); 439 spin_lock_irqsave(&mux_lock, flags);
437 440
438 reg = pg_readl(drive_pingroups[pg].reg); 441 reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
439 reg &= ~(0x1f << 12); 442 reg &= ~(0x1f << 12);
440 reg |= pull_down << 12; 443 reg |= pull_down << 12;
441 pg_writel(reg, drive_pingroups[pg].reg); 444 pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
442 445
443 spin_unlock_irqrestore(&mux_lock, flags); 446 spin_unlock_irqrestore(&mux_lock, flags);
444 447
@@ -458,10 +461,10 @@ static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg,
458 461
459 spin_lock_irqsave(&mux_lock, flags); 462 spin_lock_irqsave(&mux_lock, flags);
460 463
461 reg = pg_readl(drive_pingroups[pg].reg); 464 reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
462 reg &= ~(0x1f << 12); 465 reg &= ~(0x1f << 12);
463 reg |= pull_up << 12; 466 reg |= pull_up << 12;
464 pg_writel(reg, drive_pingroups[pg].reg); 467 pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
465 468
466 spin_unlock_irqrestore(&mux_lock, flags); 469 spin_unlock_irqrestore(&mux_lock, flags);
467 470
@@ -481,10 +484,10 @@ static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg,
481 484
482 spin_lock_irqsave(&mux_lock, flags); 485 spin_lock_irqsave(&mux_lock, flags);
483 486
484 reg = pg_readl(drive_pingroups[pg].reg); 487 reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
485 reg &= ~(0x3 << 28); 488 reg &= ~(0x3 << 28);
486 reg |= slew_rising << 28; 489 reg |= slew_rising << 28;
487 pg_writel(reg, drive_pingroups[pg].reg); 490 pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
488 491
489 spin_unlock_irqrestore(&mux_lock, flags); 492 spin_unlock_irqrestore(&mux_lock, flags);
490 493
@@ -504,10 +507,10 @@ static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg,
504 507
505 spin_lock_irqsave(&mux_lock, flags); 508 spin_lock_irqsave(&mux_lock, flags);
506 509
507 reg = pg_readl(drive_pingroups[pg].reg); 510 reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
508 reg &= ~(0x3 << 30); 511 reg &= ~(0x3 << 30);
509 reg |= slew_falling << 30; 512 reg |= slew_falling << 30;
510 pg_writel(reg, drive_pingroups[pg].reg); 513 pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
511 514
512 spin_unlock_irqrestore(&mux_lock, flags); 515 spin_unlock_irqrestore(&mux_lock, flags);
513 516
@@ -665,6 +668,99 @@ void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *co
665 } 668 }
666} 669}
667 670
671static int __devinit tegra_pinmux_probe(struct platform_device *pdev)
672{
673 struct resource *res;
674 int i;
675 int config_bad = 0;
676
677 for (i = 0; ; i++) {
678 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
679 if (!res)
680 break;
681 }
682 nbanks = i;
683
684 for (i = 0; i < TEGRA_MAX_PINGROUP; i++) {
685 if (pingroups[i].tri_bank >= nbanks) {
686 dev_err(&pdev->dev, "pingroup %d: bad tri_bank\n", i);
687 config_bad = 1;
688 }
689
690 if (pingroups[i].mux_bank >= nbanks) {
691 dev_err(&pdev->dev, "pingroup %d: bad mux_bank\n", i);
692 config_bad = 1;
693 }
694
695 if (pingroups[i].pupd_bank >= nbanks) {
696 dev_err(&pdev->dev, "pingroup %d: bad pupd_bank\n", i);
697 config_bad = 1;
698 }
699 }
700
701 for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) {
702 if (drive_pingroups[i].reg_bank >= nbanks) {
703 dev_err(&pdev->dev,
704 "drive pingroup %d: bad reg_bank\n", i);
705 config_bad = 1;
706 }
707 }
708
709 if (config_bad)
710 return -ENODEV;
711
712 regs = devm_kzalloc(&pdev->dev, nbanks * sizeof(*regs), GFP_KERNEL);
713 if (!regs) {
714 dev_err(&pdev->dev, "Can't alloc regs pointer\n");
715 return -ENODEV;
716 }
717
718 for (i = 0; i < nbanks; i++) {
719 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
720 if (!res) {
721 dev_err(&pdev->dev, "Missing MEM resource\n");
722 return -ENODEV;
723 }
724
725 if (!devm_request_mem_region(&pdev->dev, res->start,
726 resource_size(res),
727 dev_name(&pdev->dev))) {
728 dev_err(&pdev->dev,
729 "Couldn't request MEM resource %d\n", i);
730 return -ENODEV;
731 }
732
733 regs[i] = devm_ioremap(&pdev->dev, res->start,
734 resource_size(res));
735 if (!regs) {
736 dev_err(&pdev->dev, "Couldn't ioremap regs %d\n", i);
737 return -ENODEV;
738 }
739 }
740
741 return 0;
742}
743
744static struct of_device_id tegra_pinmux_of_match[] __devinitdata = {
745 { .compatible = "nvidia,tegra20-pinmux", },
746 { },
747};
748
749static struct platform_driver tegra_pinmux_driver = {
750 .driver = {
751 .name = "tegra-pinmux",
752 .owner = THIS_MODULE,
753 .of_match_table = tegra_pinmux_of_match,
754 },
755 .probe = tegra_pinmux_probe,
756};
757
758static int __init tegra_pinmux_init(void)
759{
760 return platform_driver_register(&tegra_pinmux_driver);
761}
762postcore_initcall(tegra_pinmux_init);
763
668#ifdef CONFIG_DEBUG_FS 764#ifdef CONFIG_DEBUG_FS
669 765
670#include <linux/debugfs.h> 766#include <linux/debugfs.h>
@@ -684,6 +780,7 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
684 int len; 780 int len;
685 781
686 for (i = 0; i < TEGRA_MAX_PINGROUP; i++) { 782 for (i = 0; i < TEGRA_MAX_PINGROUP; i++) {
783 unsigned long reg;
687 unsigned long tri; 784 unsigned long tri;
688 unsigned long mux; 785 unsigned long mux;
689 unsigned long pupd; 786 unsigned long pupd;
@@ -696,8 +793,9 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
696 seq_printf(s, "TEGRA_MUX_NONE"); 793 seq_printf(s, "TEGRA_MUX_NONE");
697 len = strlen("NONE"); 794 len = strlen("NONE");
698 } else { 795 } else {
699 mux = (pg_readl(pingroups[i].mux_reg) >> 796 reg = pg_readl(pingroups[i].mux_bank,
700 pingroups[i].mux_bit) & 0x3; 797 pingroups[i].mux_reg);
798 mux = (reg >> pingroups[i].mux_bit) & 0x3;
701 if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) { 799 if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) {
702 seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1); 800 seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1);
703 len = 5; 801 len = 5;
@@ -713,8 +811,9 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
713 seq_printf(s, "TEGRA_PUPD_NORMAL"); 811 seq_printf(s, "TEGRA_PUPD_NORMAL");
714 len = strlen("NORMAL"); 812 len = strlen("NORMAL");
715 } else { 813 } else {
716 pupd = (pg_readl(pingroups[i].pupd_reg) >> 814 reg = pg_readl(pingroups[i].pupd_bank,
717 pingroups[i].pupd_bit) & 0x3; 815 pingroups[i].pupd_reg);
816 pupd = (reg >> pingroups[i].pupd_bit) & 0x3;
718 seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd)); 817 seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd));
719 len = strlen(pupd_name(pupd)); 818 len = strlen(pupd_name(pupd));
720 } 819 }
@@ -723,8 +822,9 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
723 if (pingroups[i].tri_reg < 0) { 822 if (pingroups[i].tri_reg < 0) {
724 seq_printf(s, "TEGRA_TRI_NORMAL"); 823 seq_printf(s, "TEGRA_TRI_NORMAL");
725 } else { 824 } else {
726 tri = (pg_readl(pingroups[i].tri_reg) >> 825 reg = pg_readl(pingroups[i].tri_bank,
727 pingroups[i].tri_bit) & 0x1; 826 pingroups[i].tri_reg);
827 tri = (reg >> pingroups[i].tri_bit) & 0x1;
728 828
729 seq_printf(s, "TEGRA_TRI_%s", tri_name(tri)); 829 seq_printf(s, "TEGRA_TRI_%s", tri_name(tri));
730 } 830 }
@@ -759,7 +859,8 @@ static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
759 dbg_pad_field(s, 7 - len); 859 dbg_pad_field(s, 7 - len);
760 860
761 861
762 reg = pg_readl(drive_pingroups[i].reg); 862 reg = pg_readl(drive_pingroups[i].reg_bank,
863 drive_pingroups[i].reg);
763 if (HSM_EN(reg)) { 864 if (HSM_EN(reg)) {
764 seq_printf(s, "TEGRA_HSM_ENABLE"); 865 seq_printf(s, "TEGRA_HSM_ENABLE");
765 len = 16; 866 len = 16;