aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb/driver_chipcommon_pmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ssb/driver_chipcommon_pmu.c')
-rw-r--r--drivers/ssb/driver_chipcommon_pmu.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c
index 4aaddeec55a2..64abd11f6fbb 100644
--- a/drivers/ssb/driver_chipcommon_pmu.c
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -28,6 +28,21 @@ static void ssb_chipco_pll_write(struct ssb_chipcommon *cc,
28 chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, value); 28 chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, value);
29} 29}
30 30
31static void ssb_chipco_regctl_maskset(struct ssb_chipcommon *cc,
32 u32 offset, u32 mask, u32 set)
33{
34 u32 value;
35
36 chipco_read32(cc, SSB_CHIPCO_REGCTL_ADDR);
37 chipco_write32(cc, SSB_CHIPCO_REGCTL_ADDR, offset);
38 chipco_read32(cc, SSB_CHIPCO_REGCTL_ADDR);
39 value = chipco_read32(cc, SSB_CHIPCO_REGCTL_DATA);
40 value &= mask;
41 value |= set;
42 chipco_write32(cc, SSB_CHIPCO_REGCTL_DATA, value);
43 chipco_read32(cc, SSB_CHIPCO_REGCTL_DATA);
44}
45
31struct pmu0_plltab_entry { 46struct pmu0_plltab_entry {
32 u16 freq; /* Crystal frequency in kHz.*/ 47 u16 freq; /* Crystal frequency in kHz.*/
33 u8 xf; /* Crystal frequency value for PMU control */ 48 u8 xf; /* Crystal frequency value for PMU control */
@@ -506,3 +521,82 @@ void ssb_pmu_init(struct ssb_chipcommon *cc)
506 ssb_pmu_pll_init(cc); 521 ssb_pmu_pll_init(cc);
507 ssb_pmu_resources_init(cc); 522 ssb_pmu_resources_init(cc);
508} 523}
524
525void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
526 enum ssb_pmu_ldo_volt_id id, u32 voltage)
527{
528 struct ssb_bus *bus = cc->dev->bus;
529 u32 addr, shift, mask;
530
531 switch (bus->chip_id) {
532 case 0x4328:
533 case 0x5354:
534 switch (id) {
535 case LDO_VOLT1:
536 addr = 2;
537 shift = 25;
538 mask = 0xF;
539 break;
540 case LDO_VOLT2:
541 addr = 3;
542 shift = 1;
543 mask = 0xF;
544 break;
545 case LDO_VOLT3:
546 addr = 3;
547 shift = 9;
548 mask = 0xF;
549 break;
550 case LDO_PAREF:
551 addr = 3;
552 shift = 17;
553 mask = 0x3F;
554 break;
555 default:
556 SSB_WARN_ON(1);
557 return;
558 }
559 break;
560 case 0x4312:
561 if (SSB_WARN_ON(id != LDO_PAREF))
562 return;
563 addr = 0;
564 shift = 21;
565 mask = 0x3F;
566 break;
567 default:
568 return;
569 }
570
571 ssb_chipco_regctl_maskset(cc, addr, ~(mask << shift),
572 (voltage & mask) << shift);
573}
574
575void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on)
576{
577 struct ssb_bus *bus = cc->dev->bus;
578 int ldo;
579
580 switch (bus->chip_id) {
581 case 0x4312:
582 ldo = SSB_PMURES_4312_PA_REF_LDO;
583 break;
584 case 0x4328:
585 ldo = SSB_PMURES_4328_PA_REF_LDO;
586 break;
587 case 0x5354:
588 ldo = SSB_PMURES_5354_PA_REF_LDO;
589 break;
590 default:
591 return;
592 }
593
594 if (on)
595 chipco_set32(cc, SSB_CHIPCO_PMU_MINRES_MSK, 1 << ldo);
596 else
597 chipco_mask32(cc, SSB_CHIPCO_PMU_MINRES_MSK, ~(1 << ldo));
598 chipco_read32(cc, SSB_CHIPCO_PMU_MINRES_MSK); //SPEC FIXME found via mmiotrace - dummy read?
599}
600
601EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
602EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);