root/drivers/ssb/driver_extif.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. extif_read32
  2. extif_write32
  3. extif_write32_masked
  4. serial_exists
  5. ssb_extif_serial_init
  6. ssb_extif_timing_init
  7. ssb_extif_get_clockcontrol
  8. ssb_extif_watchdog_timer_set_wdt
  9. ssb_extif_watchdog_timer_set_ms
  10. ssb_extif_watchdog_timer_set
  11. ssb_extif_init
  12. ssb_extif_gpio_in
  13. ssb_extif_gpio_out
  14. ssb_extif_gpio_outen
  15. ssb_extif_gpio_polarity
  16. ssb_extif_gpio_intmask

   1 /*
   2  * Sonics Silicon Backplane
   3  * Broadcom EXTIF core driver
   4  *
   5  * Copyright 2005, Broadcom Corporation
   6  * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
   7  * Copyright 2006, 2007, Felix Fietkau <nbd@openwrt.org>
   8  * Copyright 2007, Aurelien Jarno <aurelien@aurel32.net>
   9  *
  10  * Licensed under the GNU/GPL. See COPYING for details.
  11  */
  12 
  13 #include "ssb_private.h"
  14 
  15 #include <linux/serial.h>
  16 #include <linux/serial_core.h>
  17 #include <linux/serial_reg.h>
  18 
  19 
  20 static inline u32 extif_read32(struct ssb_extif *extif, u16 offset)
  21 {
  22         return ssb_read32(extif->dev, offset);
  23 }
  24 
  25 static inline void extif_write32(struct ssb_extif *extif, u16 offset, u32 value)
  26 {
  27         ssb_write32(extif->dev, offset, value);
  28 }
  29 
  30 static inline u32 extif_write32_masked(struct ssb_extif *extif, u16 offset,
  31                                        u32 mask, u32 value)
  32 {
  33         value &= mask;
  34         value |= extif_read32(extif, offset) & ~mask;
  35         extif_write32(extif, offset, value);
  36 
  37         return value;
  38 }
  39 
  40 #ifdef CONFIG_SSB_SERIAL
  41 static bool serial_exists(u8 *regs)
  42 {
  43         u8 save_mcr, msr = 0;
  44 
  45         if (regs) {
  46                 save_mcr = regs[UART_MCR];
  47                 regs[UART_MCR] = (UART_MCR_LOOP | UART_MCR_OUT2 | UART_MCR_RTS);
  48                 msr = regs[UART_MSR] & (UART_MSR_DCD | UART_MSR_RI
  49                                         | UART_MSR_CTS | UART_MSR_DSR);
  50                 regs[UART_MCR] = save_mcr;
  51         }
  52         return (msr == (UART_MSR_DCD | UART_MSR_CTS));
  53 }
  54 
  55 int ssb_extif_serial_init(struct ssb_extif *extif, struct ssb_serial_port *ports)
  56 {
  57         u32 i, nr_ports = 0;
  58 
  59         /* Disable GPIO interrupt initially */
  60         extif_write32(extif, SSB_EXTIF_GPIO_INTPOL, 0);
  61         extif_write32(extif, SSB_EXTIF_GPIO_INTMASK, 0);
  62 
  63         for (i = 0; i < 2; i++) {
  64                 void __iomem *uart_regs;
  65 
  66                 uart_regs = ioremap_nocache(SSB_EUART, 16);
  67                 if (uart_regs) {
  68                         uart_regs += (i * 8);
  69 
  70                         if (serial_exists(uart_regs) && ports) {
  71                                 extif_write32(extif, SSB_EXTIF_GPIO_INTMASK, 2);
  72 
  73                                 nr_ports++;
  74                                 ports[i].regs = uart_regs;
  75                                 ports[i].irq = 2;
  76                                 ports[i].baud_base = 13500000;
  77                                 ports[i].reg_shift = 0;
  78                         }
  79                         iounmap(uart_regs);
  80                 }
  81         }
  82         return nr_ports;
  83 }
  84 #endif /* CONFIG_SSB_SERIAL */
  85 
  86 void ssb_extif_timing_init(struct ssb_extif *extif, unsigned long ns)
  87 {
  88         u32 tmp;
  89 
  90         /* Initialize extif so we can get to the LEDs and external UART */
  91         extif_write32(extif, SSB_EXTIF_PROG_CFG, SSB_EXTCFG_EN);
  92 
  93         /* Set timing for the flash */
  94         tmp  = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT;
  95         tmp |= DIV_ROUND_UP(40, ns) << SSB_PROG_WCNT_1_SHIFT;
  96         tmp |= DIV_ROUND_UP(120, ns);
  97         extif_write32(extif, SSB_EXTIF_PROG_WAITCNT, tmp);
  98 
  99         /* Set programmable interface timing for external uart */
 100         tmp  = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT;
 101         tmp |= DIV_ROUND_UP(20, ns) << SSB_PROG_WCNT_2_SHIFT;
 102         tmp |= DIV_ROUND_UP(100, ns) << SSB_PROG_WCNT_1_SHIFT;
 103         tmp |= DIV_ROUND_UP(120, ns);
 104         extif_write32(extif, SSB_EXTIF_PROG_WAITCNT, tmp);
 105 }
 106 
 107 void ssb_extif_get_clockcontrol(struct ssb_extif *extif,
 108                                 u32 *pll_type, u32 *n, u32 *m)
 109 {
 110         *pll_type = SSB_PLLTYPE_1;
 111         *n = extif_read32(extif, SSB_EXTIF_CLOCK_N);
 112         *m = extif_read32(extif, SSB_EXTIF_CLOCK_SB);
 113 }
 114 
 115 u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks)
 116 {
 117         struct ssb_extif *extif = bcm47xx_wdt_get_drvdata(wdt);
 118 
 119         return ssb_extif_watchdog_timer_set(extif, ticks);
 120 }
 121 
 122 u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms)
 123 {
 124         struct ssb_extif *extif = bcm47xx_wdt_get_drvdata(wdt);
 125         u32 ticks = (SSB_EXTIF_WATCHDOG_CLK / 1000) * ms;
 126 
 127         ticks = ssb_extif_watchdog_timer_set(extif, ticks);
 128 
 129         return (ticks * 1000) / SSB_EXTIF_WATCHDOG_CLK;
 130 }
 131 
 132 u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks)
 133 {
 134         if (ticks > SSB_EXTIF_WATCHDOG_MAX_TIMER)
 135                 ticks = SSB_EXTIF_WATCHDOG_MAX_TIMER;
 136         extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks);
 137 
 138         return ticks;
 139 }
 140 
 141 void ssb_extif_init(struct ssb_extif *extif)
 142 {
 143         if (!extif->dev)
 144                 return; /* We don't have a Extif core */
 145         spin_lock_init(&extif->gpio_lock);
 146 }
 147 
 148 u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
 149 {
 150         return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask;
 151 }
 152 
 153 u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value)
 154 {
 155         unsigned long flags;
 156         u32 res = 0;
 157 
 158         spin_lock_irqsave(&extif->gpio_lock, flags);
 159         res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),
 160                                    mask, value);
 161         spin_unlock_irqrestore(&extif->gpio_lock, flags);
 162 
 163         return res;
 164 }
 165 
 166 u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value)
 167 {
 168         unsigned long flags;
 169         u32 res = 0;
 170 
 171         spin_lock_irqsave(&extif->gpio_lock, flags);
 172         res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),
 173                                    mask, value);
 174         spin_unlock_irqrestore(&extif->gpio_lock, flags);
 175 
 176         return res;
 177 }
 178 
 179 u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value)
 180 {
 181         unsigned long flags;
 182         u32 res = 0;
 183 
 184         spin_lock_irqsave(&extif->gpio_lock, flags);
 185         res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);
 186         spin_unlock_irqrestore(&extif->gpio_lock, flags);
 187 
 188         return res;
 189 }
 190 
 191 u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value)
 192 {
 193         unsigned long flags;
 194         u32 res = 0;
 195 
 196         spin_lock_irqsave(&extif->gpio_lock, flags);
 197         res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);
 198         spin_unlock_irqrestore(&extif->gpio_lock, flags);
 199 
 200         return res;
 201 }

/* [<][>][^][v][top][bottom][index][help] */