18369ae33SRafał Miłecki /* 28369ae33SRafał Miłecki * Broadcom specific AMBA 38369ae33SRafał Miłecki * ChipCommon core driver 48369ae33SRafał Miłecki * 58369ae33SRafał Miłecki * Copyright 2005, Broadcom Corporation 6eb032b98SMichael Büsch * Copyright 2006, 2007, Michael Buesch <m@bues.ch> 78369ae33SRafał Miłecki * 88369ae33SRafał Miłecki * Licensed under the GNU/GPL. See COPYING for details. 98369ae33SRafał Miłecki */ 108369ae33SRafał Miłecki 118369ae33SRafał Miłecki #include "bcma_private.h" 1244a8e377SPaul Gortmaker #include <linux/export.h> 138369ae33SRafał Miłecki #include <linux/bcma/bcma.h> 148369ae33SRafał Miłecki 158369ae33SRafał Miłecki static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset, 168369ae33SRafał Miłecki u32 mask, u32 value) 178369ae33SRafał Miłecki { 188369ae33SRafał Miłecki value &= mask; 198369ae33SRafał Miłecki value |= bcma_cc_read32(cc, offset) & ~mask; 208369ae33SRafał Miłecki bcma_cc_write32(cc, offset, value); 218369ae33SRafał Miłecki 228369ae33SRafał Miłecki return value; 238369ae33SRafał Miłecki } 248369ae33SRafał Miłecki 258369ae33SRafał Miłecki void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) 268369ae33SRafał Miłecki { 2718dfa495SRafał Miłecki u32 leddc_on = 10; 2818dfa495SRafał Miłecki u32 leddc_off = 90; 2918dfa495SRafał Miłecki 30517f43e5SHauke Mehrtens if (cc->setup_done) 31517f43e5SHauke Mehrtens return; 32517f43e5SHauke Mehrtens 338369ae33SRafał Miłecki if (cc->core->id.rev >= 11) 348369ae33SRafał Miłecki cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT); 358369ae33SRafał Miłecki cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP); 368369ae33SRafał Miłecki if (cc->core->id.rev >= 35) 378369ae33SRafał Miłecki cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT); 388369ae33SRafał Miłecki 391073e4eeSRafał Miłecki if (cc->core->id.rev >= 20) { 401073e4eeSRafał Miłecki bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0); 411073e4eeSRafał Miłecki bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0); 421073e4eeSRafał Miłecki } 438369ae33SRafał Miłecki 448369ae33SRafał Miłecki if (cc->capabilities & BCMA_CC_CAP_PMU) 458369ae33SRafał Miłecki bcma_pmu_init(cc); 468369ae33SRafał Miłecki if (cc->capabilities & BCMA_CC_CAP_PCTL) 473d9d8af3SRafał Miłecki bcma_err(cc->core->bus, "Power control not implemented!\n"); 4818dfa495SRafał Miłecki 4918dfa495SRafał Miłecki if (cc->core->id.rev >= 16) { 5018dfa495SRafał Miłecki if (cc->core->bus->sprom.leddc_on_time && 5118dfa495SRafał Miłecki cc->core->bus->sprom.leddc_off_time) { 5218dfa495SRafał Miłecki leddc_on = cc->core->bus->sprom.leddc_on_time; 5318dfa495SRafał Miłecki leddc_off = cc->core->bus->sprom.leddc_off_time; 5418dfa495SRafał Miłecki } 5518dfa495SRafał Miłecki bcma_cc_write32(cc, BCMA_CC_GPIOTIMER, 5618dfa495SRafał Miłecki ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) | 5718dfa495SRafał Miłecki (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT))); 5818dfa495SRafał Miłecki } 59517f43e5SHauke Mehrtens 60517f43e5SHauke Mehrtens cc->setup_done = true; 618369ae33SRafał Miłecki } 628369ae33SRafał Miłecki 638369ae33SRafał Miłecki /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ 648369ae33SRafał Miłecki void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks) 658369ae33SRafał Miłecki { 668369ae33SRafał Miłecki /* instant NMI */ 678369ae33SRafał Miłecki bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks); 688369ae33SRafał Miłecki } 698369ae33SRafał Miłecki 708369ae33SRafał Miłecki void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value) 718369ae33SRafał Miłecki { 728369ae33SRafał Miłecki bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value); 738369ae33SRafał Miłecki } 748369ae33SRafał Miłecki 758369ae33SRafał Miłecki u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask) 768369ae33SRafał Miłecki { 778369ae33SRafał Miłecki return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask; 788369ae33SRafał Miłecki } 798369ae33SRafał Miłecki 808369ae33SRafał Miłecki u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask) 818369ae33SRafał Miłecki { 828369ae33SRafał Miłecki return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask; 838369ae33SRafał Miłecki } 848369ae33SRafał Miłecki 858369ae33SRafał Miłecki u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value) 868369ae33SRafał Miłecki { 878369ae33SRafał Miłecki return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value); 888369ae33SRafał Miłecki } 898369ae33SRafał Miłecki 908369ae33SRafał Miłecki u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value) 918369ae33SRafał Miłecki { 928369ae33SRafał Miłecki return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value); 938369ae33SRafał Miłecki } 948369ae33SRafał Miłecki 958369ae33SRafał Miłecki u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value) 968369ae33SRafał Miłecki { 978369ae33SRafał Miłecki return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value); 988369ae33SRafał Miłecki } 998369ae33SRafał Miłecki EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control); 1008369ae33SRafał Miłecki 1018369ae33SRafał Miłecki u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value) 1028369ae33SRafał Miłecki { 1038369ae33SRafał Miłecki return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value); 1048369ae33SRafał Miłecki } 1058369ae33SRafał Miłecki 1068369ae33SRafał Miłecki u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value) 1078369ae33SRafał Miłecki { 1088369ae33SRafał Miłecki return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value); 1098369ae33SRafał Miłecki } 110e3afe0e5SHauke Mehrtens 111e3afe0e5SHauke Mehrtens #ifdef CONFIG_BCMA_DRIVER_MIPS 112e3afe0e5SHauke Mehrtens void bcma_chipco_serial_init(struct bcma_drv_cc *cc) 113e3afe0e5SHauke Mehrtens { 114e3afe0e5SHauke Mehrtens unsigned int irq; 115e3afe0e5SHauke Mehrtens u32 baud_base; 116e3afe0e5SHauke Mehrtens u32 i; 117e3afe0e5SHauke Mehrtens unsigned int ccrev = cc->core->id.rev; 118e3afe0e5SHauke Mehrtens struct bcma_serial_port *ports = cc->serial_ports; 119e3afe0e5SHauke Mehrtens 120e3afe0e5SHauke Mehrtens if (ccrev >= 11 && ccrev != 15) { 121e3afe0e5SHauke Mehrtens /* Fixed ALP clock */ 122e3afe0e5SHauke Mehrtens baud_base = bcma_pmu_alp_clock(cc); 123e3afe0e5SHauke Mehrtens if (ccrev >= 21) { 124e3afe0e5SHauke Mehrtens /* Turn off UART clock before switching clocksource. */ 125e3afe0e5SHauke Mehrtens bcma_cc_write32(cc, BCMA_CC_CORECTL, 126e3afe0e5SHauke Mehrtens bcma_cc_read32(cc, BCMA_CC_CORECTL) 127e3afe0e5SHauke Mehrtens & ~BCMA_CC_CORECTL_UARTCLKEN); 128e3afe0e5SHauke Mehrtens } 129e3afe0e5SHauke Mehrtens /* Set the override bit so we don't divide it */ 130e3afe0e5SHauke Mehrtens bcma_cc_write32(cc, BCMA_CC_CORECTL, 131e3afe0e5SHauke Mehrtens bcma_cc_read32(cc, BCMA_CC_CORECTL) 132e3afe0e5SHauke Mehrtens | BCMA_CC_CORECTL_UARTCLK0); 133e3afe0e5SHauke Mehrtens if (ccrev >= 21) { 134e3afe0e5SHauke Mehrtens /* Re-enable the UART clock. */ 135e3afe0e5SHauke Mehrtens bcma_cc_write32(cc, BCMA_CC_CORECTL, 136e3afe0e5SHauke Mehrtens bcma_cc_read32(cc, BCMA_CC_CORECTL) 137e3afe0e5SHauke Mehrtens | BCMA_CC_CORECTL_UARTCLKEN); 138e3afe0e5SHauke Mehrtens } 139e3afe0e5SHauke Mehrtens } else { 1409a89c3a8SRafał Miłecki bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n", ccrev); 141e3afe0e5SHauke Mehrtens return; 142e3afe0e5SHauke Mehrtens } 143e3afe0e5SHauke Mehrtens 144e3afe0e5SHauke Mehrtens irq = bcma_core_mips_irq(cc->core); 145e3afe0e5SHauke Mehrtens 146e3afe0e5SHauke Mehrtens /* Determine the registers of the UARTs */ 147e3afe0e5SHauke Mehrtens cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART); 148e3afe0e5SHauke Mehrtens for (i = 0; i < cc->nr_serial_ports; i++) { 149e3afe0e5SHauke Mehrtens ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA + 150e3afe0e5SHauke Mehrtens (i * 256); 151e3afe0e5SHauke Mehrtens ports[i].irq = irq; 152e3afe0e5SHauke Mehrtens ports[i].baud_base = baud_base; 153e3afe0e5SHauke Mehrtens ports[i].reg_shift = 0; 154e3afe0e5SHauke Mehrtens } 155e3afe0e5SHauke Mehrtens } 156e3afe0e5SHauke Mehrtens #endif /* CONFIG_BCMA_DRIVER_MIPS */ 157