~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/pci/ops-pmcmsp.c

Version: ~ [ linux-5.11-rc3 ] ~ [ linux-5.10.7 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.89 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.167 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.215 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.251 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.251 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * PMC-Sierra MSP board specific pci_ops
  3  *
  4  * Copyright 2001 MontaVista Software Inc.
  5  * Copyright 2005-2007 PMC-Sierra, Inc
  6  *
  7  * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
  8  *
  9  * Much of the code is derived from the original DDB5074 port by
 10  * Geert Uytterhoeven <geert@sonycom.com>
 11  *
 12  * This program is free software; you can redistribute  it and/or modify it
 13  * under  the terms of  the GNU General  Public License as published by the
 14  * Free Software Foundation;  either version 2 of the  License, or (at your
 15  * option) any later version.
 16  *
 17  */
 18 
 19 #define PCI_COUNTERS    1
 20 
 21 #include <linux/types.h>
 22 #include <linux/pci.h>
 23 #include <linux/interrupt.h>
 24 
 25 #if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
 26 #include <linux/proc_fs.h>
 27 #include <linux/seq_file.h>
 28 #endif /* CONFIG_PROC_FS && PCI_COUNTERS */
 29 
 30 #include <linux/kernel.h>
 31 #include <linux/init.h>
 32 
 33 #include <asm/byteorder.h>
 34 #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
 35 #include <asm/mipsmtregs.h>
 36 #endif
 37 
 38 #include <msp_prom.h>
 39 #include <msp_cic_int.h>
 40 #include <msp_pci.h>
 41 #include <msp_regs.h>
 42 #include <msp_regops.h>
 43 
 44 #define PCI_ACCESS_READ         0
 45 #define PCI_ACCESS_WRITE        1
 46 
 47 #if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
 48 static char proc_init;
 49 extern struct proc_dir_entry *proc_bus_pci_dir;
 50 unsigned int pci_int_count[32];
 51 
 52 static void pci_proc_init(void);
 53 
 54 /*****************************************************************************
 55  *
 56  *  FUNCTION: show_msp_pci_counts
 57  *  _________________________________________________________________________
 58  *
 59  *  DESCRIPTION: Prints the count of how many times each PCI
 60  *               interrupt has asserted. Can be invoked by the
 61  *               /proc filesystem.
 62  *
 63  *  INPUTS:      m       - synthetic file construction data
 64  *               v       - iterator
 65  *
 66  *  RETURNS:     0 or error
 67  *
 68  ****************************************************************************/
 69 static int show_msp_pci_counts(struct seq_file *m, void *v)
 70 {
 71         int i;
 72         unsigned int intcount, total = 0;
 73 
 74         for (i = 0; i < 32; ++i) {
 75                 intcount = pci_int_count[i];
 76                 if (intcount != 0) {
 77                         seq_printf(m, "[%d] = %u\n", i, intcount);
 78                         total += intcount;
 79                 }
 80         }
 81 
 82         seq_printf(m, "total = %u\n", total);
 83         return 0;
 84 }
 85 
 86 static int msp_pci_rd_cnt_open(struct inode *inode, struct file *file)
 87 {
 88         return single_open(file, show_msp_pci_counts, NULL);
 89 }
 90 
 91 static const struct file_operations msp_pci_rd_cnt_fops = {
 92         .open           = msp_pci_rd_cnt_open,
 93         .read           = seq_read,
 94         .llseek         = seq_lseek,
 95         .release        = single_release,
 96 };
 97 
 98 /*****************************************************************************
 99  *
100  *  FUNCTION: gen_pci_cfg_wr_show
101  *  _________________________________________________________________________
102  *
103  *  DESCRIPTION: Generates a configuration write cycle for debug purposes.
104  *               The IDSEL line asserted and location and data written are
105  *               immaterial. Just want to be able to prove that a
106  *               configuration write can be correctly generated on the
107  *               PCI bus.  Intent is that this function by invocable from
108  *               the /proc filesystem.
109  *
110  *  INPUTS:      m       - synthetic file construction data
111  *               v       - iterator
112  *
113  *  RETURNS:     0 or error
114  *
115  ****************************************************************************/
116 static int gen_pci_cfg_wr_show(struct seq_file *m, void *v)
117 {
118         unsigned char where = 0; /* Write to static Device/Vendor ID */
119         unsigned char bus_num = 0; /* Bus 0 */
120         unsigned char dev_fn = 0xF; /* Arbitrary device number */
121         u32 wr_data = 0xFF00AA00; /* Arbitrary data */
122         struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
123         unsigned long value;
124         int intr;
125 
126         seq_puts(m, "PMC MSP PCI: Beginning\n");
127 
128         if (proc_init == 0) {
129                 pci_proc_init();
130                 proc_init = ~0;
131         }
132 
133         seq_puts(m, "PMC MSP PCI: Before Cfg Wr\n");
134 
135         /*
136          * Generate PCI Configuration Write Cycle
137          */
138 
139         /* Clear cause register bits */
140         preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
141 
142         /* Setup address that is to appear on PCI bus */
143         preg->config_addr = BPCI_CFGADDR_ENABLE |
144                 (bus_num << BPCI_CFGADDR_BUSNUM_SHF) |
145                 (dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) |
146                 (where & 0xFC);
147 
148         value = cpu_to_le32(wr_data);
149 
150         /* Launch the PCI configuration write cycle */
151         *PCI_CONFIG_SPACE_REG = value;
152 
153         /*
154          * Check if the PCI configuration cycle (rd or wr) succeeded, by
155          * checking the status bits for errors like master or target abort.
156          */
157         intr = preg->if_status;
158 
159         seq_puts(m, "PMC MSP PCI: After Cfg Wr\n");
160         return 0;
161 }
162 
163 static int gen_pci_cfg_wr_open(struct inode *inode, struct file *file)
164 {
165         return single_open(file, gen_pci_cfg_wr_show, NULL);
166 }
167 
168 static const struct file_operations gen_pci_cfg_wr_fops = {
169         .open           = gen_pci_cfg_wr_open,
170         .read           = seq_read,
171         .llseek         = seq_lseek,
172         .release        = single_release,
173 };
174 
175 /*****************************************************************************
176  *
177  *  FUNCTION: pci_proc_init
178  *  _________________________________________________________________________
179  *
180  *  DESCRIPTION: Create entries in the /proc filesystem for debug access.
181  *
182  *  INPUTS:      none
183  *
184  *  OUTPUTS:     none
185  *
186  *  RETURNS:     none
187  *
188  ****************************************************************************/
189 static void pci_proc_init(void)
190 {
191         proc_create("pmc_msp_pci_rd_cnt", 0, NULL, &msp_pci_rd_cnt_fops);
192         proc_create("pmc_msp_pci_cfg_wr", 0, NULL, &gen_pci_cfg_wr_fops);
193 }
194 #endif /* CONFIG_PROC_FS && PCI_COUNTERS */
195 
196 static DEFINE_SPINLOCK(bpci_lock);
197 
198 /*****************************************************************************
199  *
200  *  STRUCT: pci_io_resource
201  *  _________________________________________________________________________
202  *
203  *  DESCRIPTION: Defines the address range that pciauto() will use to
204  *               assign to the I/O BARs of PCI devices.
205  *
206  *               Use the start and end addresses of the MSP7120 PCI Host
207  *               Controller I/O space, in the form that they appear on the
208  *               PCI bus AFTER MSP7120 has performed address translation.
209  *
210  *               For I/O accesses, MSP7120 ignores OATRAN and maps I/O
211  *               accesses into the bottom 0xFFF region of address space,
212  *               so that is the range to put into the pci_io_resource
213  *               struct.
214  *
215  *               In MSP4200, the start address was 0x04 instead of the
216  *               expected 0x00. Will just assume there was a good reason
217  *               for this!
218  *
219  *  NOTES:       Linux, by default, will assign I/O space to the lowest
220  *               region of address space. Since MSP7120 and Linux,
221  *               by default, have no offset in between how they map, the
222  *               io_offset element of pci_controller struct should be set
223  *               to zero.
224  *  ELEMENTS:
225  *    name       - String used for a meaningful name.
226  *
227  *    start      - Start address of MSP7120's I/O space, as MSP7120 presents
228  *                 the address on the PCI bus.
229  *
230  *    end        - End address of MSP7120's I/O space, as MSP7120 presents
231  *                 the address on the PCI bus.
232  *
233  *    flags      - Attributes indicating the type of resource. In this case,
234  *                 indicate I/O space.
235  *
236  ****************************************************************************/
237 static struct resource pci_io_resource = {
238         .name   = "pci IO space",
239         .start  = 0x04,
240         .end    = 0x0FFF,
241         .flags  = IORESOURCE_IO /* I/O space */
242 };
243 
244 /*****************************************************************************
245  *
246  *  STRUCT: pci_mem_resource
247  *  _________________________________________________________________________
248  *
249  *  DESCRIPTION: Defines the address range that pciauto() will use to
250  *               assign to the memory BARs of PCI devices.
251  *
252  *               The .start and .end values are dependent upon how address
253  *               translation is performed by the OATRAN regiser.
254  *
255  *               The values to use for .start and .end are the values
256  *               in the form they appear on the PCI bus AFTER MSP7120 has
257  *               performed OATRAN address translation.
258  *
259  *  ELEMENTS:
260  *    name       - String used for a meaningful name.
261  *
262  *    start      - Start address of MSP7120's memory space, as MSP7120 presents
263  *                 the address on the PCI bus.
264  *
265  *    end        - End address of MSP7120's memory space, as MSP7120 presents
266  *                 the address on the PCI bus.
267  *
268  *    flags      - Attributes indicating the type of resource. In this case,
269  *                 indicate memory space.
270  *
271  ****************************************************************************/
272 static struct resource pci_mem_resource = {
273         .name   = "pci memory space",
274         .start  = MSP_PCI_SPACE_BASE,
275         .end    = MSP_PCI_SPACE_END,
276         .flags  = IORESOURCE_MEM         /* memory space */
277 };
278 
279 /*****************************************************************************
280  *
281  *  FUNCTION: bpci_interrupt
282  *  _________________________________________________________________________
283  *
284  *  DESCRIPTION: PCI status interrupt handler. Updates the count of how
285  *               many times each status bit has been set, then clears
286  *               the status bits. If the appropriate macros are defined,
287  *               these counts can be viewed via the /proc filesystem.
288  *
289  *  INPUTS:      irq     - unused
290  *               dev_id  - unused
291  *               pt_regs - unused
292  *
293  *  OUTPUTS:     none
294  *
295  *  RETURNS:     PCIBIOS_SUCCESSFUL  - success
296  *
297  ****************************************************************************/
298 static irqreturn_t bpci_interrupt(int irq, void *dev_id)
299 {
300         struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
301         unsigned int stat = preg->if_status;
302 
303 #if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
304         int i;
305         for (i = 0; i < 32; ++i) {
306                 if ((1 << i) & stat)
307                         ++pci_int_count[i];
308         }
309 #endif /* PROC_FS && PCI_COUNTERS */
310 
311         /* printk("PCI ISR: Status=%08X\n", stat); */
312 
313         /* write to clear all asserted interrupts */
314         preg->if_status = stat;
315 
316         return IRQ_HANDLED;
317 }
318 
319 /*****************************************************************************
320  *
321  *  FUNCTION: msp_pcibios_config_access
322  *  _________________________________________________________________________
323  *
324  *  DESCRIPTION: Performs a PCI configuration access (rd or wr), then
325  *               checks that the access succeeded by querying MSP7120's
326  *               PCI status bits.
327  *
328  *  INPUTS:
329  *               access_type  - kind of PCI configuration cycle to perform
330  *                              (read or write). Legal values are
331  *                              PCI_ACCESS_WRITE and PCI_ACCESS_READ.
332  *
333  *               bus          - pointer to the bus number of the device to
334  *                              be targeted for the configuration cycle.
335  *                              The only element of the pci_bus structure
336  *                              used is bus->number. This argument determines
337  *                              if the configuration access will be Type 0 or
338  *                              Type 1. Since MSP7120 assumes itself to be the
339  *                              PCI Host, any non-zero bus->number generates
340  *                              a Type 1 access.
341  *
342  *               devfn        - this is an 8-bit field. The lower three bits
343  *                              specify the function number of the device to
344  *                              be targeted for the configuration cycle, with
345  *                              all three-bit combinations being legal. The
346  *                              upper five bits specify the device number,
347  *                              with legal values being 10 to 31.
348  *
349  *               where        - address within the Configuration Header
350  *                              space to access.
351  *
352  *               data         - for write accesses, contains the data to
353  *                              write.
354  *
355  *  OUTPUTS:
356  *               data         - for read accesses, contains the value read.
357  *
358  *  RETURNS:     PCIBIOS_SUCCESSFUL  - success
359  *               -1                  - access failure
360  *
361  ****************************************************************************/
362 int msp_pcibios_config_access(unsigned char access_type,
363                                 struct pci_bus *bus,
364                                 unsigned int devfn,
365                                 unsigned char where,
366                                 u32 *data)
367 {
368         struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
369         unsigned char bus_num = bus->number;
370         unsigned char dev_fn = (unsigned char)devfn;
371         unsigned long flags;
372         unsigned long intr;
373         unsigned long value;
374         static char pciirqflag;
375         int ret;
376 #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
377         unsigned int    vpe_status;
378 #endif
379 
380 #if defined(CONFIG_PROC_FS) && defined(PCI_COUNTERS)
381         if (proc_init == 0) {
382                 pci_proc_init();
383                 proc_init = ~0;
384         }
385 #endif /* CONFIG_PROC_FS && PCI_COUNTERS */
386 
387         /*
388          * Just the first time this function invokes, allocate
389          * an interrupt line for PCI host status interrupts. The
390          * allocation assigns an interrupt handler to the interrupt.
391          */
392         if (pciirqflag == 0) {
393                 ret = request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */
394                                 bpci_interrupt,
395                                 IRQF_SHARED,
396                                 "PMC MSP PCI Host",
397                                 preg);
398                 if (ret != 0)
399                         return ret;
400                 pciirqflag = ~0;
401         }
402 
403 #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
404         local_irq_save(flags);
405         vpe_status = dvpe();
406 #else
407         spin_lock_irqsave(&bpci_lock, flags);
408 #endif
409 
410         /*
411          * Clear PCI cause register bits.
412          *
413          * In Polo, the PCI Host had a dedicated DMA called the
414          * Block Copy (not to be confused with the general purpose Block
415          * Copy Engine block). There appear to have been special interrupts
416          * for this Block Copy, called Block Copy 0 Fault (BC0F) and
417          * Block Copy 1 Fault (BC1F). MSP4200 and MSP7120 don't have this
418          * dedicated Block Copy block, so these two interrupts are now
419          * marked reserved. In case the  Block Copy is resurrected in a
420          * future design, maintain the code that treats these two interrupts
421          * specially.
422          *
423          * Write to clear all interrupts in the PCI status register, aside
424          * from BC0F and BC1F.
425          */
426         preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
427 
428         /* Setup address that is to appear on PCI bus */
429         preg->config_addr = BPCI_CFGADDR_ENABLE |
430                 (bus_num << BPCI_CFGADDR_BUSNUM_SHF) |
431                 (dev_fn << BPCI_CFGADDR_FUNCTNUM_SHF) |
432                 (where & 0xFC);
433 
434         /* IF access is a PCI configuration write */
435         if (access_type == PCI_ACCESS_WRITE) {
436                 value = cpu_to_le32(*data);
437                 *PCI_CONFIG_SPACE_REG = value;
438         } else {
439                 /* ELSE access is a PCI configuration read */
440                 value = le32_to_cpu(*PCI_CONFIG_SPACE_REG);
441                 *data = value;
442         }
443 
444         /*
445          * Check if the PCI configuration cycle (rd or wr) succeeded, by
446          * checking the status bits for errors like master or target abort.
447          */
448         intr = preg->if_status;
449 
450         /* Clear config access */
451         preg->config_addr = 0;
452 
453         /* IF error occurred */
454         if (intr & ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F)) {
455                 /* Clear status bits */
456                 preg->if_status = ~(BPCI_IFSTATUS_BC0F | BPCI_IFSTATUS_BC1F);
457 
458 #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
459                 evpe(vpe_status);
460                 local_irq_restore(flags);
461 #else
462                 spin_unlock_irqrestore(&bpci_lock, flags);
463 #endif
464 
465                 return -1;
466         }
467 
468 #if defined(CONFIG_PMC_MSP7120_GW) || defined(CONFIG_PMC_MSP7120_EVAL)
469         evpe(vpe_status);
470         local_irq_restore(flags);
471 #else
472         spin_unlock_irqrestore(&bpci_lock, flags);
473 #endif
474 
475         return PCIBIOS_SUCCESSFUL;
476 }
477 
478 /*****************************************************************************
479  *
480  *  FUNCTION: msp_pcibios_read_config_byte
481  *  _________________________________________________________________________
482  *
483  *  DESCRIPTION: Read a byte from PCI configuration address spac
484  *               Since the hardware can't address 8 bit chunks
485  *               directly, read a 32-bit chunk, then mask off extraneous
486  *               bits.
487  *
488  *  INPUTS       bus    - structure containing attributes for the PCI bus
489  *                        that the read is destined for.
490  *               devfn  - device/function combination that the read is
491  *                        destined for.
492  *               where  - register within the Configuration Header space
493  *                        to access.
494  *
495  *  OUTPUTS      val    - read data
496  *
497  *  RETURNS:     PCIBIOS_SUCCESSFUL  - success
498  *               -1                  - read access failure
499  *
500  ****************************************************************************/
501 static int
502 msp_pcibios_read_config_byte(struct pci_bus *bus,
503                                 unsigned int devfn,
504                                 int where,
505                                 u32 *val)
506 {
507         u32 data = 0;
508 
509         /*
510          * If the config access did not complete normally (e.g., underwent
511          * master abort) do the PCI compliant thing, which is to supply an
512          * all ones value.
513          */
514         if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
515                                         where, &data)) {
516                 *val = 0xFFFFFFFF;
517                 return -1;
518         }
519 
520         *val = (data >> ((where & 3) << 3)) & 0x0ff;
521 
522         return PCIBIOS_SUCCESSFUL;
523 }
524 
525 /*****************************************************************************
526  *
527  *  FUNCTION: msp_pcibios_read_config_word
528  *  _________________________________________________________________________
529  *
530  *  DESCRIPTION: Read a word (16 bits) from PCI configuration address space.
531  *               Since the hardware can't address 16 bit chunks
532  *               directly, read a 32-bit chunk, then mask off extraneous
533  *               bits.
534  *
535  *  INPUTS       bus    - structure containing attributes for the PCI bus
536  *                        that the read is destined for.
537  *               devfn  - device/function combination that the read is
538  *                        destined for.
539  *               where  - register within the Configuration Header space
540  *                        to access.
541  *
542  *  OUTPUTS      val    - read data
543  *
544  *  RETURNS:     PCIBIOS_SUCCESSFUL           - success
545  *               PCIBIOS_BAD_REGISTER_NUMBER  - bad register address
546  *               -1                           - read access failure
547  *
548  ****************************************************************************/
549 static int
550 msp_pcibios_read_config_word(struct pci_bus *bus,
551                                 unsigned int devfn,
552                                 int where,
553                                 u32 *val)
554 {
555         u32 data = 0;
556 
557         /* if (where & 1) */    /* Commented out non-compliant code.
558                                  * Should allow word access to configuration
559                                  * registers, with only exception being when
560                                  * the word access would wrap around into
561                                  * the next dword.
562                                  */
563         if ((where & 3) == 3) {
564                 *val = 0xFFFFFFFF;
565                 return PCIBIOS_BAD_REGISTER_NUMBER;
566         }
567 
568         /*
569          * If the config access did not complete normally (e.g., underwent
570          * master abort) do the PCI compliant thing, which is to supply an
571          * all ones value.
572          */
573         if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
574                                         where, &data)) {
575                 *val = 0xFFFFFFFF;
576                 return -1;
577         }
578 
579         *val = (data >> ((where & 3) << 3)) & 0x0ffff;
580 
581         return PCIBIOS_SUCCESSFUL;
582 }
583 
584 /*****************************************************************************
585  *
586  *  FUNCTION: msp_pcibios_read_config_dword
587  *  _________________________________________________________________________
588  *
589  *  DESCRIPTION: Read a double word (32 bits) from PCI configuration
590  *               address space.
591  *
592  *  INPUTS       bus    - structure containing attributes for the PCI bus
593  *                        that the read is destined for.
594  *               devfn  - device/function combination that the read is
595  *                        destined for.
596  *               where  - register within the Configuration Header space
597  *                        to access.
598  *
599  *  OUTPUTS      val    - read data
600  *
601  *  RETURNS:     PCIBIOS_SUCCESSFUL           - success
602  *               PCIBIOS_BAD_REGISTER_NUMBER  - bad register address
603  *               -1                           - read access failure
604  *
605  ****************************************************************************/
606 static int
607 msp_pcibios_read_config_dword(struct pci_bus *bus,
608                                 unsigned int devfn,
609                                 int where,
610                                 u32 *val)
611 {
612         u32 data = 0;
613 
614         /* Address must be dword aligned. */
615         if (where & 3) {
616                 *val = 0xFFFFFFFF;
617                 return PCIBIOS_BAD_REGISTER_NUMBER;
618         }
619 
620         /*
621          * If the config access did not complete normally (e.g., underwent
622          * master abort) do the PCI compliant thing, which is to supply an
623          * all ones value.
624          */
625         if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
626                                         where, &data)) {
627                 *val = 0xFFFFFFFF;
628                 return -1;
629         }
630 
631         *val = data;
632 
633         return PCIBIOS_SUCCESSFUL;
634 }
635 
636 /*****************************************************************************
637  *
638  *  FUNCTION: msp_pcibios_write_config_byte
639  *  _________________________________________________________________________
640  *
641  *  DESCRIPTION: Write a byte to PCI configuration address space.
642  *               Since the hardware can't address 8 bit chunks
643  *               directly, a read-modify-write is performed.
644  *
645  *  INPUTS       bus    - structure containing attributes for the PCI bus
646  *                        that the write is destined for.
647  *               devfn  - device/function combination that the write is
648  *                        destined for.
649  *               where  - register within the Configuration Header space
650  *                        to access.
651  *               val    - value to write
652  *
653  *  OUTPUTS      none
654  *
655  *  RETURNS:     PCIBIOS_SUCCESSFUL  - success
656  *               -1                  - write access failure
657  *
658  ****************************************************************************/
659 static int
660 msp_pcibios_write_config_byte(struct pci_bus *bus,
661                                 unsigned int devfn,
662                                 int where,
663                                 u8 val)
664 {
665         u32 data = 0;
666 
667         /* read config space */
668         if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
669                                         where, &data))
670                 return -1;
671 
672         /* modify the byte within the dword */
673         data = (data & ~(0xff << ((where & 3) << 3))) |
674                         (val << ((where & 3) << 3));
675 
676         /* write back the full dword */
677         if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
678                                         where, &data))
679                 return -1;
680 
681         return PCIBIOS_SUCCESSFUL;
682 }
683 
684 /*****************************************************************************
685  *
686  *  FUNCTION: msp_pcibios_write_config_word
687  *  _________________________________________________________________________
688  *
689  *  DESCRIPTION: Write a word (16-bits) to PCI configuration address space.
690  *               Since the hardware can't address 16 bit chunks
691  *               directly, a read-modify-write is performed.
692  *
693  *  INPUTS       bus    - structure containing attributes for the PCI bus
694  *                        that the write is destined for.
695  *               devfn  - device/function combination that the write is
696  *                        destined for.
697  *               where  - register within the Configuration Header space
698  *                        to access.
699  *               val    - value to write
700  *
701  *  OUTPUTS      none
702  *
703  *  RETURNS:     PCIBIOS_SUCCESSFUL           - success
704  *               PCIBIOS_BAD_REGISTER_NUMBER  - bad register address
705  *               -1                           - write access failure
706  *
707  ****************************************************************************/
708 static int
709 msp_pcibios_write_config_word(struct pci_bus *bus,
710                                 unsigned int devfn,
711                                 int where,
712                                 u16 val)
713 {
714         u32 data = 0;
715 
716         /* Fixed non-compliance: if (where & 1) */
717         if ((where & 3) == 3)
718                 return PCIBIOS_BAD_REGISTER_NUMBER;
719 
720         /* read config space */
721         if (msp_pcibios_config_access(PCI_ACCESS_READ, bus, devfn,
722                                         where, &data))
723                 return -1;
724 
725         /* modify the word within the dword */
726         data = (data & ~(0xffff << ((where & 3) << 3))) |
727                         (val << ((where & 3) << 3));
728 
729         /* write back the full dword */
730         if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
731                                         where, &data))
732                 return -1;
733 
734         return PCIBIOS_SUCCESSFUL;
735 }
736 
737 /*****************************************************************************
738  *
739  *  FUNCTION: msp_pcibios_write_config_dword
740  *  _________________________________________________________________________
741  *
742  *  DESCRIPTION: Write a double word (32-bits) to PCI configuration address
743  *               space.
744  *
745  *  INPUTS       bus    - structure containing attributes for the PCI bus
746  *                        that the write is destined for.
747  *               devfn  - device/function combination that the write is
748  *                        destined for.
749  *               where  - register within the Configuration Header space
750  *                        to access.
751  *               val    - value to write
752  *
753  *  OUTPUTS      none
754  *
755  *  RETURNS:     PCIBIOS_SUCCESSFUL           - success
756  *               PCIBIOS_BAD_REGISTER_NUMBER  - bad register address
757  *               -1                           - write access failure
758  *
759  ****************************************************************************/
760 static int
761 msp_pcibios_write_config_dword(struct pci_bus *bus,
762                                 unsigned int devfn,
763                                 int where,
764                                 u32 val)
765 {
766         /* check that address is dword aligned */
767         if (where & 3)
768                 return PCIBIOS_BAD_REGISTER_NUMBER;
769 
770         /* perform write */
771         if (msp_pcibios_config_access(PCI_ACCESS_WRITE, bus, devfn,
772                                         where, &val))
773                 return -1;
774 
775         return PCIBIOS_SUCCESSFUL;
776 }
777 
778 /*****************************************************************************
779  *
780  *  FUNCTION: msp_pcibios_read_config
781  *  _________________________________________________________________________
782  *
783  *  DESCRIPTION: Interface the PCI configuration read request with
784  *               the appropriate function, based on how many bytes
785  *               the read request is.
786  *
787  *  INPUTS       bus    - structure containing attributes for the PCI bus
788  *                        that the write is destined for.
789  *               devfn  - device/function combination that the write is
790  *                        destined for.
791  *               where  - register within the Configuration Header space
792  *                        to access.
793  *               size   - in units of bytes, should be 1, 2, or 4.
794  *
795  *  OUTPUTS      val    - value read, with any extraneous bytes masked
796  *                        to zero.
797  *
798  *  RETURNS:     PCIBIOS_SUCCESSFUL   - success
799  *               -1                   - failure
800  *
801  ****************************************************************************/
802 int
803 msp_pcibios_read_config(struct pci_bus *bus,
804                         unsigned int    devfn,
805                         int where,
806                         int size,
807                         u32 *val)
808 {
809         if (size == 1) {
810                 if (msp_pcibios_read_config_byte(bus, devfn, where, val)) {
811                         return -1;
812                 }
813         } else if (size == 2) {
814                 if (msp_pcibios_read_config_word(bus, devfn, where, val)) {
815                         return -1;
816                 }
817         } else if (size == 4) {
818                 if (msp_pcibios_read_config_dword(bus, devfn, where, val)) {
819                         return -1;
820                 }
821         } else {
822                 *val = 0xFFFFFFFF;
823                 return -1;
824         }
825 
826         return PCIBIOS_SUCCESSFUL;
827 }
828 
829 /*****************************************************************************
830  *
831  *  FUNCTION: msp_pcibios_write_config
832  *  _________________________________________________________________________
833  *
834  *  DESCRIPTION: Interface the PCI configuration write request with
835  *               the appropriate function, based on how many bytes
836  *               the read request is.
837  *
838  *  INPUTS       bus    - structure containing attributes for the PCI bus
839  *                        that the write is destined for.
840  *               devfn  - device/function combination that the write is
841  *                        destined for.
842  *               where  - register within the Configuration Header space
843  *                        to access.
844  *               size   - in units of bytes, should be 1, 2, or 4.
845  *               val    - value to write
846  *
847  *  OUTPUTS:     none
848  *
849  *  RETURNS:     PCIBIOS_SUCCESSFUL   - success
850  *               -1                   - failure
851  *
852  ****************************************************************************/
853 int
854 msp_pcibios_write_config(struct pci_bus *bus,
855                         unsigned int devfn,
856                         int where,
857                         int size,
858                         u32 val)
859 {
860         if (size == 1) {
861                 if (msp_pcibios_write_config_byte(bus, devfn,
862                                                 where, (u8)(0xFF & val))) {
863                         return -1;
864                 }
865         } else if (size == 2) {
866                 if (msp_pcibios_write_config_word(bus, devfn,
867                                                 where, (u16)(0xFFFF & val))) {
868                         return -1;
869                 }
870         } else if (size == 4) {
871                 if (msp_pcibios_write_config_dword(bus, devfn, where, val)) {
872                         return -1;
873                 }
874         } else {
875                 return -1;
876         }
877 
878         return PCIBIOS_SUCCESSFUL;
879 }
880 
881 /*****************************************************************************
882  *
883  *  STRUCTURE: msp_pci_ops
884  *  _________________________________________________________________________
885  *
886  *  DESCRIPTION: structure to abstract the hardware specific PCI
887  *               configuration accesses.
888  *
889  *  ELEMENTS:
890  *    read      - function for Linux to generate PCI Configuration reads.
891  *    write     - function for Linux to generate PCI Configuration writes.
892  *
893  ****************************************************************************/
894 struct pci_ops msp_pci_ops = {
895         .read = msp_pcibios_read_config,
896         .write = msp_pcibios_write_config
897 };
898 
899 /*****************************************************************************
900  *
901  *  STRUCTURE: msp_pci_controller
902  *  _________________________________________________________________________
903  *
904  *  Describes the attributes of the MSP7120 PCI Host Controller
905  *
906  *  ELEMENTS:
907  *    pci_ops      - abstracts the hardware specific PCI configuration
908  *                   accesses.
909  *
910  *    mem_resource - address range pciauto() uses to assign to PCI device
911  *                   memory BARs.
912  *
913  *    mem_offset   - offset between how MSP7120 outbound PCI memory
914  *                   transaction addresses appear on the PCI bus and how Linux
915  *                   wants to configure memory BARs of the PCI devices.
916  *                   MSP7120 does nothing funky, so just set to zero.
917  *
918  *    io_resource  - address range pciauto() uses to assign to PCI device
919  *                   I/O BARs.
920  *
921  *    io_offset    - offset between how MSP7120 outbound PCI I/O
922  *                   transaction addresses appear on the PCI bus and how
923  *                   Linux defaults to configure I/O BARs of the PCI devices.
924  *                   MSP7120 maps outbound I/O accesses into the bottom
925  *                   bottom 4K of PCI address space (and ignores OATRAN).
926  *                   Since the Linux default is to configure I/O BARs to the
927  *                   bottom 4K, no special offset is needed. Just set to zero.
928  *
929  ****************************************************************************/
930 static struct pci_controller msp_pci_controller = {
931         .pci_ops        = &msp_pci_ops,
932         .mem_resource   = &pci_mem_resource,
933         .mem_offset     = 0,
934         .io_map_base    = MSP_PCI_IOSPACE_BASE,
935         .io_resource    = &pci_io_resource,
936         .io_offset      = 0
937 };
938 
939 /*****************************************************************************
940  *
941  *  FUNCTION: msp_pci_init
942  *  _________________________________________________________________________
943  *
944  *  DESCRIPTION: Initialize the PCI Host Controller and register it with
945  *               Linux so Linux can seize control of the PCI bus.
946  *
947  ****************************************************************************/
948 void __init msp_pci_init(void)
949 {
950         struct msp_pci_regs *preg = (void *)PCI_BASE_REG;
951         u32 id;
952 
953         /* Extract Device ID */
954         id = read_reg32(PCI_JTAG_DEVID_REG, 0xFFFF) >> 12;
955 
956         /* Check if JTAG ID identifies MSP7120 */
957         if (!MSP_HAS_PCI(id)) {
958                 printk(KERN_WARNING "PCI: No PCI; id reads as %x\n", id);
959                 goto no_pci;
960         }
961 
962         /*
963          * Enable flushing of the PCI-SDRAM queue upon a read
964          * of the SDRAM's Memory Configuration Register.
965          */
966         *(unsigned long *)QFLUSH_REG_1 = 3;
967 
968         /* Configure PCI Host Controller. */
969         preg->if_status = ~0;           /* Clear cause register bits */
970         preg->config_addr = 0;          /* Clear config access */
971         preg->oatran    = MSP_PCI_OATRAN; /* PCI outbound addr translation */
972         preg->if_mask   = 0xF8BF87C0;   /* Enable all PCI status interrupts */
973 
974         /* configure so inb(), outb(), and family are functional */
975         set_io_port_base(MSP_PCI_IOSPACE_BASE);
976 
977         /* Tell Linux the details of the MSP7120 PCI Host Controller */
978         register_pci_controller(&msp_pci_controller);
979 
980         return;
981 
982 no_pci:
983         /* Disable PCI channel */
984         printk(KERN_WARNING "PCI: no host PCI bus detected\n");
985 }
986 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp