0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include "ssb_private.h"
0014
0015 #include <linux/serial.h>
0016 #include <linux/serial_core.h>
0017 #include <linux/serial_reg.h>
0018
0019
0020 static inline u32 extif_read32(struct ssb_extif *extif, u16 offset)
0021 {
0022 return ssb_read32(extif->dev, offset);
0023 }
0024
0025 static inline void extif_write32(struct ssb_extif *extif, u16 offset, u32 value)
0026 {
0027 ssb_write32(extif->dev, offset, value);
0028 }
0029
0030 static inline u32 extif_write32_masked(struct ssb_extif *extif, u16 offset,
0031 u32 mask, u32 value)
0032 {
0033 value &= mask;
0034 value |= extif_read32(extif, offset) & ~mask;
0035 extif_write32(extif, offset, value);
0036
0037 return value;
0038 }
0039
0040 #ifdef CONFIG_SSB_SERIAL
0041 static bool serial_exists(u8 *regs)
0042 {
0043 u8 save_mcr, msr = 0;
0044
0045 if (regs) {
0046 save_mcr = regs[UART_MCR];
0047 regs[UART_MCR] = (UART_MCR_LOOP | UART_MCR_OUT2 | UART_MCR_RTS);
0048 msr = regs[UART_MSR] & (UART_MSR_DCD | UART_MSR_RI
0049 | UART_MSR_CTS | UART_MSR_DSR);
0050 regs[UART_MCR] = save_mcr;
0051 }
0052 return (msr == (UART_MSR_DCD | UART_MSR_CTS));
0053 }
0054
0055 int ssb_extif_serial_init(struct ssb_extif *extif, struct ssb_serial_port *ports)
0056 {
0057 u32 i, nr_ports = 0;
0058
0059
0060 extif_write32(extif, SSB_EXTIF_GPIO_INTPOL, 0);
0061 extif_write32(extif, SSB_EXTIF_GPIO_INTMASK, 0);
0062
0063 for (i = 0; i < 2; i++) {
0064 void __iomem *uart_regs;
0065
0066 uart_regs = ioremap(SSB_EUART, 16);
0067 if (uart_regs) {
0068 uart_regs += (i * 8);
0069
0070 if (serial_exists(uart_regs) && ports) {
0071 extif_write32(extif, SSB_EXTIF_GPIO_INTMASK, 2);
0072
0073 nr_ports++;
0074 ports[i].regs = uart_regs;
0075 ports[i].irq = 2;
0076 ports[i].baud_base = 13500000;
0077 ports[i].reg_shift = 0;
0078 }
0079 iounmap(uart_regs);
0080 }
0081 }
0082 return nr_ports;
0083 }
0084 #endif
0085
0086 void ssb_extif_timing_init(struct ssb_extif *extif, unsigned long ns)
0087 {
0088 u32 tmp;
0089
0090
0091 extif_write32(extif, SSB_EXTIF_PROG_CFG, SSB_EXTCFG_EN);
0092
0093
0094 tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT;
0095 tmp |= DIV_ROUND_UP(40, ns) << SSB_PROG_WCNT_1_SHIFT;
0096 tmp |= DIV_ROUND_UP(120, ns);
0097 extif_write32(extif, SSB_EXTIF_PROG_WAITCNT, tmp);
0098
0099
0100 tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT;
0101 tmp |= DIV_ROUND_UP(20, ns) << SSB_PROG_WCNT_2_SHIFT;
0102 tmp |= DIV_ROUND_UP(100, ns) << SSB_PROG_WCNT_1_SHIFT;
0103 tmp |= DIV_ROUND_UP(120, ns);
0104 extif_write32(extif, SSB_EXTIF_PROG_WAITCNT, tmp);
0105 }
0106
0107 void ssb_extif_get_clockcontrol(struct ssb_extif *extif,
0108 u32 *pll_type, u32 *n, u32 *m)
0109 {
0110 *pll_type = SSB_PLLTYPE_1;
0111 *n = extif_read32(extif, SSB_EXTIF_CLOCK_N);
0112 *m = extif_read32(extif, SSB_EXTIF_CLOCK_SB);
0113 }
0114
0115 u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks)
0116 {
0117 struct ssb_extif *extif = bcm47xx_wdt_get_drvdata(wdt);
0118
0119 return ssb_extif_watchdog_timer_set(extif, ticks);
0120 }
0121
0122 u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms)
0123 {
0124 struct ssb_extif *extif = bcm47xx_wdt_get_drvdata(wdt);
0125 u32 ticks = (SSB_EXTIF_WATCHDOG_CLK / 1000) * ms;
0126
0127 ticks = ssb_extif_watchdog_timer_set(extif, ticks);
0128
0129 return (ticks * 1000) / SSB_EXTIF_WATCHDOG_CLK;
0130 }
0131
0132 u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks)
0133 {
0134 if (ticks > SSB_EXTIF_WATCHDOG_MAX_TIMER)
0135 ticks = SSB_EXTIF_WATCHDOG_MAX_TIMER;
0136 extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks);
0137
0138 return ticks;
0139 }
0140
0141 void ssb_extif_init(struct ssb_extif *extif)
0142 {
0143 if (!extif->dev)
0144 return;
0145 spin_lock_init(&extif->gpio_lock);
0146 }
0147
0148 u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
0149 {
0150 return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask;
0151 }
0152
0153 u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value)
0154 {
0155 unsigned long flags;
0156 u32 res = 0;
0157
0158 spin_lock_irqsave(&extif->gpio_lock, flags);
0159 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0),
0160 mask, value);
0161 spin_unlock_irqrestore(&extif->gpio_lock, flags);
0162
0163 return res;
0164 }
0165
0166 u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value)
0167 {
0168 unsigned long flags;
0169 u32 res = 0;
0170
0171 spin_lock_irqsave(&extif->gpio_lock, flags);
0172 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0),
0173 mask, value);
0174 spin_unlock_irqrestore(&extif->gpio_lock, flags);
0175
0176 return res;
0177 }
0178
0179 u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value)
0180 {
0181 unsigned long flags;
0182 u32 res = 0;
0183
0184 spin_lock_irqsave(&extif->gpio_lock, flags);
0185 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value);
0186 spin_unlock_irqrestore(&extif->gpio_lock, flags);
0187
0188 return res;
0189 }
0190
0191 u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value)
0192 {
0193 unsigned long flags;
0194 u32 res = 0;
0195
0196 spin_lock_irqsave(&extif->gpio_lock, flags);
0197 res = extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value);
0198 spin_unlock_irqrestore(&extif->gpio_lock, flags);
0199
0200 return res;
0201 }