aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/pinmux.c
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2011-10-12 11:54:27 -0400
committerOlof Johansson <olof@lixom.net>2011-10-13 18:04:53 -0400
commit48f2eceefb9d1b79e4c37795d2121933fcbc34f5 (patch)
tree80ecd64222b3c06f0369c17cedaf400e2cda6832 /arch/arm/mach-tegra/pinmux.c
parent88d8951e5896da908d31bc24735efae801566066 (diff)
arm/tegra: pinmux: ioremap registers
Use ioremap to obtain access to registers instead of using static mappings. This reduces the number of users of the static mappings, which will eventually allow them to be removed. Note that on Tegra30, the number of register "banks" will decrease to 2, and the packing of specific bits into registers will change significantly. That's why this change adds the "*_bank" fields to the pingroup tables, rather than implementing some more hard-coded scheme. Also, completely remove the implementation of suspend/resume; Tegra doesn't yet support suspend/resume, and the implementation is complex for the general pinmux driver: * Not all registers are used within each bank, so we probably shouldn't just iterate over every register in the bank, and save/restore it, since that would mean touching undefined registers. * Registers are shared between pingroups, so we can't simply iterate over each pingroup, and save/restore the registers it uses. It'd probably be best have probe() calculate a bitmask of actually-used registers for each bank, and have suspend/resume iterate over those bitmaps. Oh, and Real Soon Now, I should be looking into converting this driver to the new pinmux/pinctrl subsystem, so I didn't want to put too much work into the current incarnation. v2: s/space/bank/ to match comments on reg_* fields in pinmux.h. Re-order bank/reg parameters to pg_readl/pg_writel. Signed-off-by: Stephen Warren <swarren@nvidia.com> Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'arch/arm/mach-tegra/pinmux.c')
-rw-r--r--arch/arm/mach-tegra/pinmux.c137
1 files changed, 106 insertions, 31 deletions
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
index fb212177c515..1d201650d7a4 100644
--- a/arch/arm/mach-tegra/pinmux.c
+++ b/arch/arm/mach-tegra/pinmux.c
@@ -170,15 +170,17 @@ static const char *pupd_name(unsigned long val)
170 } 170 }
171} 171}
172 172
173static int nbanks;
174static void __iomem **regs;
173 175
174static inline unsigned long pg_readl(unsigned long offset) 176static inline u32 pg_readl(u32 bank, u32 reg)
175{ 177{
176 return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); 178 return readl(regs[bank] + reg);
177} 179}
178 180
179static inline void pg_writel(unsigned long value, unsigned long offset) 181static inline void pg_writel(u32 val, u32 bank, u32 reg)
180{ 182{
181 writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset)); 183 writel(val, regs[bank] + reg);
182} 184}
183 185
184static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config) 186static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
@@ -218,10 +220,10 @@ static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
218 220
219 spin_lock_irqsave(&mux_lock, flags); 221 spin_lock_irqsave(&mux_lock, flags);
220 222
221 reg = pg_readl(pingroups[pg].mux_reg); 223 reg = pg_readl(pingroups[pg].mux_bank, pingroups[pg].mux_reg);
222 reg &= ~(0x3 << pingroups[pg].mux_bit); 224 reg &= ~(0x3 << pingroups[pg].mux_bit);
223 reg |= mux << pingroups[pg].mux_bit; 225 reg |= mux << pingroups[pg].mux_bit;
224 pg_writel(reg, pingroups[pg].mux_reg); 226 pg_writel(reg, pingroups[pg].mux_bank, pingroups[pg].mux_reg);
225 227
226 spin_unlock_irqrestore(&mux_lock, flags); 228 spin_unlock_irqrestore(&mux_lock, flags);
227 229
@@ -242,11 +244,11 @@ int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
242 244
243 spin_lock_irqsave(&mux_lock, flags); 245 spin_lock_irqsave(&mux_lock, flags);
244 246
245 reg = pg_readl(pingroups[pg].tri_reg); 247 reg = pg_readl(pingroups[pg].tri_bank, pingroups[pg].tri_reg);
246 reg &= ~(0x1 << pingroups[pg].tri_bit); 248 reg &= ~(0x1 << pingroups[pg].tri_bit);
247 if (tristate) 249 if (tristate)
248 reg |= 1 << pingroups[pg].tri_bit; 250 reg |= 1 << pingroups[pg].tri_bit;
249 pg_writel(reg, pingroups[pg].tri_reg); 251 pg_writel(reg, pingroups[pg].tri_bank, pingroups[pg].tri_reg);
250 252
251 spin_unlock_irqrestore(&mux_lock, flags); 253 spin_unlock_irqrestore(&mux_lock, flags);
252 254
@@ -273,10 +275,10 @@ int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
273 275
274 spin_lock_irqsave(&mux_lock, flags); 276 spin_lock_irqsave(&mux_lock, flags);
275 277
276 reg = pg_readl(pingroups[pg].pupd_reg); 278 reg = pg_readl(pingroups[pg].pupd_bank, pingroups[pg].pupd_reg);
277 reg &= ~(0x3 << pingroups[pg].pupd_bit); 279 reg &= ~(0x3 << pingroups[pg].pupd_bit);
278 reg |= pupd << pingroups[pg].pupd_bit; 280 reg |= pupd << pingroups[pg].pupd_bit;
279 pg_writel(reg, pingroups[pg].pupd_reg); 281 pg_writel(reg, pingroups[pg].pupd_bank, pingroups[pg].pupd_reg);
280 282
281 spin_unlock_irqrestore(&mux_lock, flags); 283 spin_unlock_irqrestore(&mux_lock, flags);
282 284
@@ -363,12 +365,12 @@ static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg,
363 365
364 spin_lock_irqsave(&mux_lock, flags); 366 spin_lock_irqsave(&mux_lock, flags);
365 367
366 reg = pg_readl(drive_pingroups[pg].reg); 368 reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
367 if (hsm == TEGRA_HSM_ENABLE) 369 if (hsm == TEGRA_HSM_ENABLE)
368 reg |= (1 << 2); 370 reg |= (1 << 2);
369 else 371 else
370 reg &= ~(1 << 2); 372 reg &= ~(1 << 2);
371 pg_writel(reg, drive_pingroups[pg].reg); 373 pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
372 374
373 spin_unlock_irqrestore(&mux_lock, flags); 375 spin_unlock_irqrestore(&mux_lock, flags);
374 376
@@ -388,12 +390,12 @@ static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg,
388 390
389 spin_lock_irqsave(&mux_lock, flags); 391 spin_lock_irqsave(&mux_lock, flags);
390 392
391 reg = pg_readl(drive_pingroups[pg].reg); 393 reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
392 if (schmitt == TEGRA_SCHMITT_ENABLE) 394 if (schmitt == TEGRA_SCHMITT_ENABLE)
393 reg |= (1 << 3); 395 reg |= (1 << 3);
394 else 396 else
395 reg &= ~(1 << 3); 397 reg &= ~(1 << 3);
396 pg_writel(reg, drive_pingroups[pg].reg); 398 pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
397 399
398 spin_unlock_irqrestore(&mux_lock, flags); 400 spin_unlock_irqrestore(&mux_lock, flags);
399 401
@@ -413,10 +415,10 @@ static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg,
413 415
414 spin_lock_irqsave(&mux_lock, flags); 416 spin_lock_irqsave(&mux_lock, flags);
415 417
416 reg = pg_readl(drive_pingroups[pg].reg); 418 reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
417 reg &= ~(0x3 << 4); 419 reg &= ~(0x3 << 4);
418 reg |= drive << 4; 420 reg |= drive << 4;
419 pg_writel(reg, drive_pingroups[pg].reg); 421 pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
420 422
421 spin_unlock_irqrestore(&mux_lock, flags); 423 spin_unlock_irqrestore(&mux_lock, flags);
422 424
@@ -436,10 +438,10 @@ static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg,
436 438
437 spin_lock_irqsave(&mux_lock, flags); 439 spin_lock_irqsave(&mux_lock, flags);
438 440
439 reg = pg_readl(drive_pingroups[pg].reg); 441 reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
440 reg &= ~(0x1f << 12); 442 reg &= ~(0x1f << 12);
441 reg |= pull_down << 12; 443 reg |= pull_down << 12;
442 pg_writel(reg, drive_pingroups[pg].reg); 444 pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
443 445
444 spin_unlock_irqrestore(&mux_lock, flags); 446 spin_unlock_irqrestore(&mux_lock, flags);
445 447
@@ -459,10 +461,10 @@ static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg,
459 461
460 spin_lock_irqsave(&mux_lock, flags); 462 spin_lock_irqsave(&mux_lock, flags);
461 463
462 reg = pg_readl(drive_pingroups[pg].reg); 464 reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
463 reg &= ~(0x1f << 12); 465 reg &= ~(0x1f << 12);
464 reg |= pull_up << 12; 466 reg |= pull_up << 12;
465 pg_writel(reg, drive_pingroups[pg].reg); 467 pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
466 468
467 spin_unlock_irqrestore(&mux_lock, flags); 469 spin_unlock_irqrestore(&mux_lock, flags);
468 470
@@ -482,10 +484,10 @@ static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg,
482 484
483 spin_lock_irqsave(&mux_lock, flags); 485 spin_lock_irqsave(&mux_lock, flags);
484 486
485 reg = pg_readl(drive_pingroups[pg].reg); 487 reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
486 reg &= ~(0x3 << 28); 488 reg &= ~(0x3 << 28);
487 reg |= slew_rising << 28; 489 reg |= slew_rising << 28;
488 pg_writel(reg, drive_pingroups[pg].reg); 490 pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
489 491
490 spin_unlock_irqrestore(&mux_lock, flags); 492 spin_unlock_irqrestore(&mux_lock, flags);
491 493
@@ -505,10 +507,10 @@ static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg,
505 507
506 spin_lock_irqsave(&mux_lock, flags); 508 spin_lock_irqsave(&mux_lock, flags);
507 509
508 reg = pg_readl(drive_pingroups[pg].reg); 510 reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
509 reg &= ~(0x3 << 30); 511 reg &= ~(0x3 << 30);
510 reg |= slew_falling << 30; 512 reg |= slew_falling << 30;
511 pg_writel(reg, drive_pingroups[pg].reg); 513 pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
512 514
513 spin_unlock_irqrestore(&mux_lock, flags); 515 spin_unlock_irqrestore(&mux_lock, flags);
514 516
@@ -668,6 +670,74 @@ void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *co
668 670
669static int __devinit tegra_pinmux_probe(struct platform_device *pdev) 671static int __devinit tegra_pinmux_probe(struct platform_device *pdev)
670{ 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
671 return 0; 741 return 0;
672} 742}
673 743
@@ -710,6 +780,7 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
710 int len; 780 int len;
711 781
712 for (i = 0; i < TEGRA_MAX_PINGROUP; i++) { 782 for (i = 0; i < TEGRA_MAX_PINGROUP; i++) {
783 unsigned long reg;
713 unsigned long tri; 784 unsigned long tri;
714 unsigned long mux; 785 unsigned long mux;
715 unsigned long pupd; 786 unsigned long pupd;
@@ -722,8 +793,9 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
722 seq_printf(s, "TEGRA_MUX_NONE"); 793 seq_printf(s, "TEGRA_MUX_NONE");
723 len = strlen("NONE"); 794 len = strlen("NONE");
724 } else { 795 } else {
725 mux = (pg_readl(pingroups[i].mux_reg) >> 796 reg = pg_readl(pingroups[i].mux_bank,
726 pingroups[i].mux_bit) & 0x3; 797 pingroups[i].mux_reg);
798 mux = (reg >> pingroups[i].mux_bit) & 0x3;
727 if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) { 799 if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) {
728 seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1); 800 seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1);
729 len = 5; 801 len = 5;
@@ -739,8 +811,9 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
739 seq_printf(s, "TEGRA_PUPD_NORMAL"); 811 seq_printf(s, "TEGRA_PUPD_NORMAL");
740 len = strlen("NORMAL"); 812 len = strlen("NORMAL");
741 } else { 813 } else {
742 pupd = (pg_readl(pingroups[i].pupd_reg) >> 814 reg = pg_readl(pingroups[i].pupd_bank,
743 pingroups[i].pupd_bit) & 0x3; 815 pingroups[i].pupd_reg);
816 pupd = (reg >> pingroups[i].pupd_bit) & 0x3;
744 seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd)); 817 seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd));
745 len = strlen(pupd_name(pupd)); 818 len = strlen(pupd_name(pupd));
746 } 819 }
@@ -749,8 +822,9 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
749 if (pingroups[i].tri_reg < 0) { 822 if (pingroups[i].tri_reg < 0) {
750 seq_printf(s, "TEGRA_TRI_NORMAL"); 823 seq_printf(s, "TEGRA_TRI_NORMAL");
751 } else { 824 } else {
752 tri = (pg_readl(pingroups[i].tri_reg) >> 825 reg = pg_readl(pingroups[i].tri_bank,
753 pingroups[i].tri_bit) & 0x1; 826 pingroups[i].tri_reg);
827 tri = (reg >> pingroups[i].tri_bit) & 0x1;
754 828
755 seq_printf(s, "TEGRA_TRI_%s", tri_name(tri)); 829 seq_printf(s, "TEGRA_TRI_%s", tri_name(tri));
756 } 830 }
@@ -785,7 +859,8 @@ static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
785 dbg_pad_field(s, 7 - len); 859 dbg_pad_field(s, 7 - len);
786 860
787 861
788 reg = pg_readl(drive_pingroups[i].reg); 862 reg = pg_readl(drive_pingroups[i].reg_bank,
863 drive_pingroups[i].reg);
789 if (HSM_EN(reg)) { 864 if (HSM_EN(reg)) {
790 seq_printf(s, "TEGRA_HSM_ENABLE"); 865 seq_printf(s, "TEGRA_HSM_ENABLE");
791 len = 16; 866 len = 16;