linux/drivers/bcma/driver_chipcommon.c
<<
>>
Prefs
   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
  15static 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
  25void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
  26{
  27        u32 leddc_on = 10;
  28        u32 leddc_off = 90;
  29
  30        if (cc->setup_done)
  31                return;
  32
  33        if (cc->core->id.rev >= 11)
  34                cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
  35        cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
  36        if (cc->core->id.rev >= 35)
  37                cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
  38
  39        if (cc->core->id.rev >= 20) {
  40                bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
  41                bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0);
  42        }
  43
  44        if (cc->capabilities & BCMA_CC_CAP_PMU)
  45                bcma_pmu_init(cc);
  46        if (cc->capabilities & BCMA_CC_CAP_PCTL)
  47                bcma_err(cc->core->bus, "Power control not implemented!\n");
  48
  49        if (cc->core->id.rev >= 16) {
  50                if (cc->core->bus->sprom.leddc_on_time &&
  51                    cc->core->bus->sprom.leddc_off_time) {
  52                        leddc_on = cc->core->bus->sprom.leddc_on_time;
  53                        leddc_off = cc->core->bus->sprom.leddc_off_time;
  54                }
  55                bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
  56                        ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
  57                         (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
  58        }
  59
  60        cc->setup_done = true;
  61}
  62
  63/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
  64void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
  65{
  66        /* instant NMI */
  67        bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
  68}
  69
  70void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
  71{
  72        bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value);
  73}
  74
  75u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask)
  76{
  77        return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask;
  78}
  79
  80u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
  81{
  82        return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
  83}
  84
  85u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
  86{
  87        return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
  88}
  89
  90u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
  91{
  92        return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
  93}
  94
  95u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
  96{
  97        return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
  98}
  99EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
 100
 101u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
 102{
 103        return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
 104}
 105
 106u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
 107{
 108        return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
 109}
 110
 111#ifdef CONFIG_BCMA_DRIVER_MIPS
 112void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
 113{
 114        unsigned int irq;
 115        u32 baud_base;
 116        u32 i;
 117        unsigned int ccrev = cc->core->id.rev;
 118        struct bcma_serial_port *ports = cc->serial_ports;
 119
 120        if (ccrev >= 11 && ccrev != 15) {
 121                /* Fixed ALP clock */
 122                baud_base = bcma_pmu_alp_clock(cc);
 123                if (ccrev >= 21) {
 124                        /* Turn off UART clock before switching clocksource. */
 125                        bcma_cc_write32(cc, BCMA_CC_CORECTL,
 126                                       bcma_cc_read32(cc, BCMA_CC_CORECTL)
 127                                       & ~BCMA_CC_CORECTL_UARTCLKEN);
 128                }
 129                /* Set the override bit so we don't divide it */
 130                bcma_cc_write32(cc, BCMA_CC_CORECTL,
 131                               bcma_cc_read32(cc, BCMA_CC_CORECTL)
 132                               | BCMA_CC_CORECTL_UARTCLK0);
 133                if (ccrev >= 21) {
 134                        /* Re-enable the UART clock. */
 135                        bcma_cc_write32(cc, BCMA_CC_CORECTL,
 136                                       bcma_cc_read32(cc, BCMA_CC_CORECTL)
 137                                       | BCMA_CC_CORECTL_UARTCLKEN);
 138                }
 139        } else {
 140                bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n", ccrev);
 141                return;
 142        }
 143
 144        irq = bcma_core_mips_irq(cc->core);
 145
 146        /* Determine the registers of the UARTs */
 147        cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
 148        for (i = 0; i < cc->nr_serial_ports; i++) {
 149                ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
 150                                (i * 256);
 151                ports[i].irq = irq;
 152                ports[i].baud_base = baud_base;
 153                ports[i].reg_shift = 0;
 154        }
 155}
 156#endif /* CONFIG_BCMA_DRIVER_MIPS */
 157
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.