root/drivers/ssb/driver_mipscore.c

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

DEFINITIONS

This source file includes following definitions.
  1. mips_read32
  2. mips_write32
  3. ssb_irqflag
  4. find_device
  5. ssb_mips_irq
  6. clear_irq
  7. set_irq
  8. print_irq
  9. dump_irq
  10. ssb_mips_serial_init
  11. ssb_mips_flash_detect
  12. ssb_cpu_clock
  13. ssb_mipscore_init

   1 /*
   2  * Sonics Silicon Backplane
   3  * Broadcom MIPS 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 "ssb_private.h"
  12 
  13 #include <linux/ssb/ssb.h>
  14 
  15 #include <linux/mtd/physmap.h>
  16 #include <linux/serial.h>
  17 #include <linux/serial_core.h>
  18 #include <linux/serial_reg.h>
  19 #include <linux/time.h>
  20 #ifdef CONFIG_BCM47XX
  21 #include <linux/bcm47xx_nvram.h>
  22 #endif
  23 
  24 static const char * const part_probes[] = { "bcm47xxpart", NULL };
  25 
  26 static struct physmap_flash_data ssb_pflash_data = {
  27         .part_probe_types       = part_probes,
  28 };
  29 
  30 static struct resource ssb_pflash_resource = {
  31         .name   = "ssb_pflash",
  32         .flags  = IORESOURCE_MEM,
  33 };
  34 
  35 struct platform_device ssb_pflash_dev = {
  36         .name           = "physmap-flash",
  37         .dev            = {
  38                 .platform_data  = &ssb_pflash_data,
  39         },
  40         .resource       = &ssb_pflash_resource,
  41         .num_resources  = 1,
  42 };
  43 
  44 static inline u32 mips_read32(struct ssb_mipscore *mcore,
  45                               u16 offset)
  46 {
  47         return ssb_read32(mcore->dev, offset);
  48 }
  49 
  50 static inline void mips_write32(struct ssb_mipscore *mcore,
  51                                 u16 offset,
  52                                 u32 value)
  53 {
  54         ssb_write32(mcore->dev, offset, value);
  55 }
  56 
  57 static const u32 ipsflag_irq_mask[] = {
  58         0,
  59         SSB_IPSFLAG_IRQ1,
  60         SSB_IPSFLAG_IRQ2,
  61         SSB_IPSFLAG_IRQ3,
  62         SSB_IPSFLAG_IRQ4,
  63 };
  64 
  65 static const u32 ipsflag_irq_shift[] = {
  66         0,
  67         SSB_IPSFLAG_IRQ1_SHIFT,
  68         SSB_IPSFLAG_IRQ2_SHIFT,
  69         SSB_IPSFLAG_IRQ3_SHIFT,
  70         SSB_IPSFLAG_IRQ4_SHIFT,
  71 };
  72 
  73 static inline u32 ssb_irqflag(struct ssb_device *dev)
  74 {
  75         u32 tpsflag = ssb_read32(dev, SSB_TPSFLAG);
  76         if (tpsflag)
  77                 return ssb_read32(dev, SSB_TPSFLAG) & SSB_TPSFLAG_BPFLAG;
  78         else
  79                 /* not irq supported */
  80                 return 0x3f;
  81 }
  82 
  83 static struct ssb_device *find_device(struct ssb_device *rdev, int irqflag)
  84 {
  85         struct ssb_bus *bus = rdev->bus;
  86         int i;
  87         for (i = 0; i < bus->nr_devices; i++) {
  88                 struct ssb_device *dev;
  89                 dev = &(bus->devices[i]);
  90                 if (ssb_irqflag(dev) == irqflag)
  91                         return dev;
  92         }
  93         return NULL;
  94 }
  95 
  96 /* Get the MIPS IRQ assignment for a specified device.
  97  * If unassigned, 0 is returned.
  98  * If disabled, 5 is returned.
  99  * If not supported, 6 is returned.
 100  */
 101 unsigned int ssb_mips_irq(struct ssb_device *dev)
 102 {
 103         struct ssb_bus *bus = dev->bus;
 104         struct ssb_device *mdev = bus->mipscore.dev;
 105         u32 irqflag;
 106         u32 ipsflag;
 107         u32 tmp;
 108         unsigned int irq;
 109 
 110         irqflag = ssb_irqflag(dev);
 111         if (irqflag == 0x3f)
 112                 return 6;
 113         ipsflag = ssb_read32(bus->mipscore.dev, SSB_IPSFLAG);
 114         for (irq = 1; irq <= 4; irq++) {
 115                 tmp = ((ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq]);
 116                 if (tmp == irqflag)
 117                         break;
 118         }
 119         if (irq == 5) {
 120                 if ((1 << irqflag) & ssb_read32(mdev, SSB_INTVEC))
 121                         irq = 0;
 122         }
 123 
 124         return irq;
 125 }
 126 
 127 static void clear_irq(struct ssb_bus *bus, unsigned int irq)
 128 {
 129         struct ssb_device *dev = bus->mipscore.dev;
 130 
 131         /* Clear the IRQ in the MIPScore backplane registers */
 132         if (irq == 0) {
 133                 ssb_write32(dev, SSB_INTVEC, 0);
 134         } else {
 135                 ssb_write32(dev, SSB_IPSFLAG,
 136                             ssb_read32(dev, SSB_IPSFLAG) |
 137                             ipsflag_irq_mask[irq]);
 138         }
 139 }
 140 
 141 static void set_irq(struct ssb_device *dev, unsigned int irq)
 142 {
 143         unsigned int oldirq = ssb_mips_irq(dev);
 144         struct ssb_bus *bus = dev->bus;
 145         struct ssb_device *mdev = bus->mipscore.dev;
 146         u32 irqflag = ssb_irqflag(dev);
 147 
 148         BUG_ON(oldirq == 6);
 149 
 150         dev->irq = irq + 2;
 151 
 152         /* clear the old irq */
 153         if (oldirq == 0)
 154                 ssb_write32(mdev, SSB_INTVEC, (~(1 << irqflag) & ssb_read32(mdev, SSB_INTVEC)));
 155         else if (oldirq != 5)
 156                 clear_irq(bus, oldirq);
 157 
 158         /* assign the new one */
 159         if (irq == 0) {
 160                 ssb_write32(mdev, SSB_INTVEC, ((1 << irqflag) | ssb_read32(mdev, SSB_INTVEC)));
 161         } else {
 162                 u32 ipsflag = ssb_read32(mdev, SSB_IPSFLAG);
 163                 if ((ipsflag & ipsflag_irq_mask[irq]) != ipsflag_irq_mask[irq]) {
 164                         u32 oldipsflag = (ipsflag & ipsflag_irq_mask[irq]) >> ipsflag_irq_shift[irq];
 165                         struct ssb_device *olddev = find_device(dev, oldipsflag);
 166                         if (olddev)
 167                                 set_irq(olddev, 0);
 168                 }
 169                 irqflag <<= ipsflag_irq_shift[irq];
 170                 irqflag |= (ipsflag & ~ipsflag_irq_mask[irq]);
 171                 ssb_write32(mdev, SSB_IPSFLAG, irqflag);
 172         }
 173         dev_dbg(dev->dev, "set_irq: core 0x%04x, irq %d => %d\n",
 174                 dev->id.coreid, oldirq+2, irq+2);
 175 }
 176 
 177 static void print_irq(struct ssb_device *dev, unsigned int irq)
 178 {
 179         static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
 180         dev_dbg(dev->dev,
 181                 "core 0x%04x, irq : %s%s %s%s %s%s %s%s %s%s %s%s %s%s\n",
 182                 dev->id.coreid,
 183                 irq_name[0], irq == 0 ? "*" : " ",
 184                 irq_name[1], irq == 1 ? "*" : " ",
 185                 irq_name[2], irq == 2 ? "*" : " ",
 186                 irq_name[3], irq == 3 ? "*" : " ",
 187                 irq_name[4], irq == 4 ? "*" : " ",
 188                 irq_name[5], irq == 5 ? "*" : " ",
 189                 irq_name[6], irq == 6 ? "*" : " ");
 190 }
 191 
 192 static void dump_irq(struct ssb_bus *bus)
 193 {
 194         int i;
 195         for (i = 0; i < bus->nr_devices; i++) {
 196                 struct ssb_device *dev;
 197                 dev = &(bus->devices[i]);
 198                 print_irq(dev, ssb_mips_irq(dev));
 199         }
 200 }
 201 
 202 static void ssb_mips_serial_init(struct ssb_mipscore *mcore)
 203 {
 204         struct ssb_bus *bus = mcore->dev->bus;
 205 
 206         if (ssb_extif_available(&bus->extif))
 207                 mcore->nr_serial_ports = ssb_extif_serial_init(&bus->extif, mcore->serial_ports);
 208         else if (ssb_chipco_available(&bus->chipco))
 209                 mcore->nr_serial_ports = ssb_chipco_serial_init(&bus->chipco, mcore->serial_ports);
 210         else
 211                 mcore->nr_serial_ports = 0;
 212 }
 213 
 214 static void ssb_mips_flash_detect(struct ssb_mipscore *mcore)
 215 {
 216         struct ssb_bus *bus = mcore->dev->bus;
 217         struct ssb_sflash *sflash = &mcore->sflash;
 218         struct ssb_pflash *pflash = &mcore->pflash;
 219 
 220         /* When there is no chipcommon on the bus there is 4MB flash */
 221         if (!ssb_chipco_available(&bus->chipco)) {
 222                 pflash->present = true;
 223                 pflash->buswidth = 2;
 224                 pflash->window = SSB_FLASH1;
 225                 pflash->window_size = SSB_FLASH1_SZ;
 226                 goto ssb_pflash;
 227         }
 228 
 229         /* There is ChipCommon, so use it to read info about flash */
 230         switch (bus->chipco.capabilities & SSB_CHIPCO_CAP_FLASHT) {
 231         case SSB_CHIPCO_FLASHT_STSER:
 232         case SSB_CHIPCO_FLASHT_ATSER:
 233                 dev_dbg(mcore->dev->dev, "Found serial flash\n");
 234                 ssb_sflash_init(&bus->chipco);
 235                 break;
 236         case SSB_CHIPCO_FLASHT_PARA:
 237                 dev_dbg(mcore->dev->dev, "Found parallel flash\n");
 238                 pflash->present = true;
 239                 pflash->window = SSB_FLASH2;
 240                 pflash->window_size = SSB_FLASH2_SZ;
 241                 if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG)
 242                                & SSB_CHIPCO_CFG_DS16) == 0)
 243                         pflash->buswidth = 1;
 244                 else
 245                         pflash->buswidth = 2;
 246                 break;
 247         }
 248 
 249 ssb_pflash:
 250         if (sflash->present) {
 251 #ifdef CONFIG_BCM47XX
 252                 bcm47xx_nvram_init_from_mem(sflash->window, sflash->size);
 253 #endif
 254         } else if (pflash->present) {
 255 #ifdef CONFIG_BCM47XX
 256                 bcm47xx_nvram_init_from_mem(pflash->window, pflash->window_size);
 257 #endif
 258 
 259                 ssb_pflash_data.width = pflash->buswidth;
 260                 ssb_pflash_resource.start = pflash->window;
 261                 ssb_pflash_resource.end = pflash->window + pflash->window_size;
 262         }
 263 }
 264 
 265 u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
 266 {
 267         struct ssb_bus *bus = mcore->dev->bus;
 268         u32 pll_type, n, m, rate = 0;
 269 
 270         if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
 271                 return ssb_pmu_get_cpu_clock(&bus->chipco);
 272 
 273         if (ssb_extif_available(&bus->extif)) {
 274                 ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m);
 275         } else if (ssb_chipco_available(&bus->chipco)) {
 276                 ssb_chipco_get_clockcpu(&bus->chipco, &pll_type, &n, &m);
 277         } else
 278                 return 0;
 279 
 280         if ((pll_type == SSB_PLLTYPE_5) || (bus->chip_id == 0x5365)) {
 281                 rate = 200000000;
 282         } else {
 283                 rate = ssb_calc_clock_rate(pll_type, n, m);
 284         }
 285 
 286         if (pll_type == SSB_PLLTYPE_6) {
 287                 rate *= 2;
 288         }
 289 
 290         return rate;
 291 }
 292 
 293 void ssb_mipscore_init(struct ssb_mipscore *mcore)
 294 {
 295         struct ssb_bus *bus;
 296         struct ssb_device *dev;
 297         unsigned long hz, ns;
 298         unsigned int irq, i;
 299 
 300         if (!mcore->dev)
 301                 return; /* We don't have a MIPS core */
 302 
 303         dev_dbg(mcore->dev->dev, "Initializing MIPS core...\n");
 304 
 305         bus = mcore->dev->bus;
 306         hz = ssb_clockspeed(bus);
 307         if (!hz)
 308                 hz = 100000000;
 309         ns = 1000000000 / hz;
 310 
 311         if (ssb_extif_available(&bus->extif))
 312                 ssb_extif_timing_init(&bus->extif, ns);
 313         else if (ssb_chipco_available(&bus->chipco))
 314                 ssb_chipco_timing_init(&bus->chipco, ns);
 315 
 316         /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */
 317         for (irq = 2, i = 0; i < bus->nr_devices; i++) {
 318                 int mips_irq;
 319                 dev = &(bus->devices[i]);
 320                 mips_irq = ssb_mips_irq(dev);
 321                 if (mips_irq > 4)
 322                         dev->irq = 0;
 323                 else
 324                         dev->irq = mips_irq + 2;
 325                 if (dev->irq > 5)
 326                         continue;
 327                 switch (dev->id.coreid) {
 328                 case SSB_DEV_USB11_HOST:
 329                         /* shouldn't need a separate irq line for non-4710, most of them have a proper
 330                          * external usb controller on the pci */
 331                         if ((bus->chip_id == 0x4710) && (irq <= 4)) {
 332                                 set_irq(dev, irq++);
 333                         }
 334                         break;
 335                 case SSB_DEV_PCI:
 336                 case SSB_DEV_ETHERNET:
 337                 case SSB_DEV_ETHERNET_GBIT:
 338                 case SSB_DEV_80211:
 339                 case SSB_DEV_USB20_HOST:
 340                         /* These devices get their own IRQ line if available, the rest goes on IRQ0 */
 341                         if (irq <= 4) {
 342                                 set_irq(dev, irq++);
 343                                 break;
 344                         }
 345                         /* fallthrough */
 346                 case SSB_DEV_EXTIF:
 347                         set_irq(dev, 0);
 348                         break;
 349                 }
 350         }
 351         dev_dbg(mcore->dev->dev, "after irq reconfiguration\n");
 352         dump_irq(bus);
 353 
 354         ssb_mips_serial_init(mcore);
 355         ssb_mips_flash_detect(mcore);
 356 }

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