1 /* 2 * Broadcom specific AMBA 3 * ChipCommon core driver 4 * 5 * Copyright 2005, Broadcom Corporation 6 * Copyright 2006, 2007, Michael Buesch <m@bues.ch> 7 * 8 * Licensed under the GNU/GPL. See COPYING for details. 9 */ 10 11 #include "bcma_private.h" 12 #include <linux/export.h> 13 #include <linux/bcma/bcma.h> 14 15 static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset, 16 u32 mask, u32 value) 17 { 18 value &= mask; 19 value |= bcma_cc_read32(cc, offset) & ~mask; 20 bcma_cc_write32(cc, offset, value); 21 22 return value; 23 } 24 25 void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc) 26 { 27 if (cc->early_setup_done) 28 return; 29 30 if (cc->core->id.rev >= 11) 31 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT); 32 cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP); 33 if (cc->core->id.rev >= 35) 34 cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT); 35 36 if (cc->capabilities & BCMA_CC_CAP_PMU) 37 bcma_pmu_early_init(cc); 38 39 cc->early_setup_done = true; 40 } 41 42 void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) 43 { 44 u32 leddc_on = 10; 45 u32 leddc_off = 90; 46 47 if (cc->setup_done) 48 return; 49 50 bcma_core_chipcommon_early_init(cc); 51 52 if (cc->core->id.rev >= 20) { 53 bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0); 54 bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0); 55 } 56 57 if (cc->capabilities & BCMA_CC_CAP_PMU) 58 bcma_pmu_init(cc); 59 if (cc->capabilities & BCMA_CC_CAP_PCTL) 60 bcma_err(cc->core->bus, "Power control not implemented!\n"); 61 62 if (cc->core->id.rev >= 16) { 63 if (cc->core->bus->sprom.leddc_on_time && 64 cc->core->bus->sprom.leddc_off_time) { 65 leddc_on = cc->core->bus->sprom.leddc_on_time; 66 leddc_off = cc->core->bus->sprom.leddc_off_time; 67 } 68 bcma_cc_write32(cc, BCMA_CC_GPIOTIMER, 69 ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) | 70 (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT))); 71 } 72 73 cc->setup_done = true; 74 } 75 76 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ 77 void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks) 78 { 79 /* instant NMI */ 80 bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks); 81 } 82 83 void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value) 84 { 85 bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value); 86 } 87 88 u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask) 89 { 90 return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask; 91 } 92 93 u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask) 94 { 95 return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask; 96 } 97 98 u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value) 99 { 100 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value); 101 } 102 103 u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value) 104 { 105 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value); 106 } 107 108 u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value) 109 { 110 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value); 111 } 112 EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control); 113 114 u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value) 115 { 116 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value); 117 } 118 119 u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value) 120 { 121 return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value); 122 } 123 124 #ifdef CONFIG_BCMA_DRIVER_MIPS 125 void bcma_chipco_serial_init(struct bcma_drv_cc *cc) 126 { 127 unsigned int irq; 128 u32 baud_base; 129 u32 i; 130 unsigned int ccrev = cc->core->id.rev; 131 struct bcma_serial_port *ports = cc->serial_ports; 132 133 if (ccrev >= 11 && ccrev != 15) { 134 /* Fixed ALP clock */ 135 baud_base = bcma_pmu_alp_clock(cc); 136 if (ccrev >= 21) { 137 /* Turn off UART clock before switching clocksource. */ 138 bcma_cc_write32(cc, BCMA_CC_CORECTL, 139 bcma_cc_read32(cc, BCMA_CC_CORECTL) 140 & ~BCMA_CC_CORECTL_UARTCLKEN); 141 } 142 /* Set the override bit so we don't divide it */ 143 bcma_cc_write32(cc, BCMA_CC_CORECTL, 144 bcma_cc_read32(cc, BCMA_CC_CORECTL) 145 | BCMA_CC_CORECTL_UARTCLK0); 146 if (ccrev >= 21) { 147 /* Re-enable the UART clock. */ 148 bcma_cc_write32(cc, BCMA_CC_CORECTL, 149 bcma_cc_read32(cc, BCMA_CC_CORECTL) 150 | BCMA_CC_CORECTL_UARTCLKEN); 151 } 152 } else { 153 bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n", ccrev); 154 return; 155 } 156 157 irq = bcma_core_mips_irq(cc->core); 158 159 /* Determine the registers of the UARTs */ 160 cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART); 161 for (i = 0; i < cc->nr_serial_ports; i++) { 162 ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA + 163 (i * 256); 164 ports[i].irq = irq; 165 ports[i].baud_base = baud_base; 166 ports[i].reg_shift = 0; 167 } 168 } 169 #endif /* CONFIG_BCMA_DRIVER_MIPS */ 170