1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  Broadcom Silicon Backplane PCI support	File: sb_pci_machdep.c
5    *
6    *  Author:  Ed Satterthwaite
7    *
8    *********************************************************************
9    *
10    *  Copyright 2003,2004
11    *  Broadcom Corporation. All rights reserved.
12    *
13    *  This software is furnished under license and may be used and
14    *  copied only in accordance with the following terms and
15    *  conditions.  Subject to these conditions, you may download,
16    *  copy, install, use, modify and distribute modified or unmodified
17    *  copies of this software in source and/or binary form.  No title
18    *  or ownership is transferred hereby.
19    *
20    *  1) Any source code used, modified or distributed must reproduce
21    *     and retain this copyright notice and list of conditions
22    *     as they appear in the source file.
23    *
24    *  2) No right is granted to use any trade name, trademark, or
25    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
26    *     name may not be used to endorse or promote products derived
27    *     from this software without the prior written permission of
28    *     Broadcom Corporation.
29    *
30    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
31    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
32    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
33    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
34    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
35    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
36    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
38    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
39    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
40    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
41    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
42    *     THE POSSIBILITY OF SUCH DAMAGE.
43    ********************************************************************* */
44
45/*
46 * Silicon Backplane machine-specific functions for PCI autoconfiguration.
47 */
48
49#include "cfe.h"
50
51#include "sb_bp.h"
52#include "sb_pci.h"
53#include "sb_utils.h"
54
55#include "pcivar.h"
56#include "pci_internal.h"
57#include "pcireg.h"
58
59#include "lib_try.h"
60
61void pci_ext_arb_set(int enable);
62void pci_ext_clk_set(int enable);
63
64extern int _pciverbose;
65
66const cons_t pci_optnames[] = {
67    {"verbose", PCI_FLG_VERBOSE},
68    {NULL, 0}
69};
70
71
72/* Templates for bus attributes. */
73
74static const struct pci_bus init_pci_bus = {
75	0,		/* minimum grant */
76	255,		/* maximum latency */
77	0,		/* devsel time = unknown */
78	0,		/* configure fast back-to-back */
79	0,		/* we don't prefetch */
80	0,		/* configure 66 MHz */
81	0,		/* we don't support 64 bits */
82	4000000,	/* bandwidth: in 0.25us cycles / sec */
83	0,		/* initially no devices on bus */
84};
85
86#define MAXBUS	10
87static struct pci_bus _pci_bus[MAXBUS];
88static int _pci_nbus = 0;
89
90static int _ext_arb = 0;
91static int _ext_clk = 0;
92
93#define PCI_MAKE_TAG(b,d,f) \
94    (((b) << 16) | ((d) << 11) | ((f) << 8))
95
96/* Access functions (XXX use (upgraded?) lib_physio) */
97
98#define PTR_TO_PHYS(x) (PHYSADDR((uintptr_t)(x)))
99#define PHYS_TO_PTR(a) ((uint8_t *)UNCADDR(a))
100
101/* PCI "enumeration" space */
102
103#define READCSR(x)    \
104  (*(volatile uint32_t *)PHYS_TO_PTR(SB_PCI_BASE+(x)))
105#define WRITECSR(x,v) \
106  (*(volatile uint32_t *)PHYS_TO_PTR(SB_PCI_BASE+(x)) = (v))
107
108/* PCI spaces mapped by the core in Host mode. */
109
110#define SB_PCI_CFG_BASE  0x0C000000
111#define SB_PCI_MEM_BASE  0x08000000
112
113#define CFG_ADDR(x)      ((x) | SB_PCI_CFG_BASE)
114#define MEM_ADDR(x)      ((x) | SB_PCI_MEM_BASE)
115
116#define READCFG(x)       (*(volatile uint32_t *)PHYS_TO_PTR(CFG_ADDR(x)))
117#define WRITECFG(x,v)    (*(volatile uint32_t *)PHYS_TO_PTR(CFG_ADDR(x)) = (v))
118
119
120/* The following should return the index of the last usable bus port. */
121int
122pci_maxport (void)
123{
124    return PCI_HOST_PORTS - 1;
125}
126
127
128/* The following must either fail or return the next sequential bus
129   number to make secondary/subordinate numbering work correctly. */
130int
131pci_nextbus (int port)
132{
133    int bus = _pci_nbus;
134
135    if (bus >= MAXBUS)
136	return -1;
137    _pci_nbus++;
138    return bus;
139}
140
141int
142pci_maxbus (int port)
143{
144    return _pci_nbus - 1;
145}
146
147struct pci_bus *
148pci_businfo (int port, int bus)
149{
150    return (bus < _pci_nbus ? &_pci_bus[bus] : NULL);
151}
152
153/*
154 * PCI address resources.
155 * NB: initial limits for address allocation are assumed to be aligned
156 * appropriately for PCI bridges (4K boundaries for I/O, 1M for memory).
157 *
158 * The standard Silicon Backplane address map provides two
159 * configurable PCI regions in host mode.  Thus it is not possible to
160 * provide memory, i/o and configuration space simultaneously.  For
161 * now, i/o space is not implemented.
162 */
163
164pcireg_t
165pci_minmemaddr (int port)
166{
167    return SB_PCI_MEM_BASE;
168}
169
170pcireg_t
171pci_maxmemaddr (int port)
172{
173    return SB_PCI_MEM_BASE + 0x04000000;
174}
175
176pcireg_t
177pci_minioaddr (int port)
178{
179    return 0x00000000;
180}
181
182pcireg_t
183pci_maxioaddr (int port)
184{
185    return 0x00000000;
186}
187
188
189/* The PCI core (a host bridge in Host mode) */
190
191#define SB_PCI_BRIDGE     (PCI_MAKE_TAG(0,0,0))
192
193/* Called to initialise the host bridge at the beginning of time. */
194static void
195phb_init (void)
196{
197    pcireg_t csr;
198
199    /* stop the servicing of any further PCI */
200    pci_conf_write(SB_PCI_BRIDGE, PCI_COMMAND_STATUS_REG, 0);
201    cfe_usleep(100);
202
203    /* Set up the BARs (BAR0 for cores, BAR1 for SDRAM) */
204#ifdef SB_CHIPC_BASE
205    pci_conf_write(SB_PCI_BRIDGE, PCI_PCIBAR0WINDOW_REG, SB_CHIPC_BASE);
206#else
207    pci_conf_write(SB_PCI_BRIDGE, PCI_PCIBAR0WINDOW_REG, SB_EXTIF_BASE);
208#endif
209    pci_conf_write(SB_PCI_BRIDGE, PCI_MAPREG(0), 0x20000000);
210    pci_conf_write(SB_PCI_BRIDGE, PCI_PCIBAR1WINDOW_REG, 0x00000000);
211    pci_conf_write(SB_PCI_BRIDGE, PCI_MAPREG(1), 0x00000000);
212    pci_conf_write(SB_PCI_BRIDGE, PCI_BAR1BURSTCTRL_REG,
213		   M_BAR1BURST_PE | M_BAR1BURST_WB);
214
215    /* enable bridge to PCI and PCI memory accesses, including
216       write-invalidate, plus error handling */
217    csr = PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_MEM_ENABLE |
218          PCI_COMMAND_INVALIDATE_ENABLE |
219          PCI_COMMAND_SERR_ENABLE |  PCI_COMMAND_PARITY_ENABLE;
220    pci_conf_write(SB_PCI_BRIDGE, PCI_COMMAND_STATUS_REG, csr);
221
222    /* clear errors */
223    csr = pci_conf_read(SB_PCI_BRIDGE, PCI_COMMAND_STATUS_REG);
224    csr |= PCI_STATUS_PARITY_ERROR | PCI_STATUS_SYSTEM_ERROR |
225           PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT |
226           PCI_STATUS_TARGET_TARGET_ABORT | PCI_STATUS_PARITY_DETECT;
227    pci_conf_write(SB_PCI_BRIDGE, PCI_COMMAND_STATUS_REG, csr);
228
229    (void)pci_conf_read(SB_PCI_BRIDGE, PCI_ID_REG);   /* push */
230}
231
232
233/* Allow us to work with external arbiter */
234void
235pci_ext_arb_set (int enable)
236{
237    _ext_arb = enable;
238}
239
240/* Allow us to work with external clock */
241void
242pci_ext_clk_set (int enable)
243{
244    _ext_clk = enable;
245}
246
247
248#ifndef PCI_CLOCK
249#define PCI_CLOCK 33000000
250#endif
251
252int
253pci_hwinit (int port, pci_flags_t flags)
254{
255    uint32_t ctrl;
256    uint32_t cpu_clock;
257    int i;
258
259    /* Enable PCI clock and release reset */
260    if (_ext_clk) {
261        ctrl = M_PCICTL_OE;              /* enable reset output */
262        }
263    else {
264        ctrl = M_PCICTL_OE | M_PCICTL_CE;/* enable the tristate drivers */
265        WRITECSR(R_PCI_CONTROL, ctrl);
266        ctrl |= M_PCICTL_CO;             /* enable the PCI clock */
267        }
268    WRITECSR(R_PCI_CONTROL, ctrl);
269    cfe_usleep(100);                    /* delay 100 us */
270    ctrl |= M_PCICTL_RO;                /* release reset */
271    WRITECSR(R_PCI_CONTROL, ctrl);
272
273    /* Set PCI clock frequency */
274    cpu_clock = sb_clock();
275    sb_setclock(cpu_clock, PCI_CLOCK);
276
277    if (_ext_arb) {
278        /* Enable the external arbiter */
279        WRITECSR(R_PCI_ARB_CONTROL, M_PCIARB_EA);
280        }
281    else {
282	/* Enable the internal arbiter.  PARK_LAST apparently locks the bus
283	   when there is no response. */
284	WRITECSR(R_PCI_ARB_CONTROL, M_PCIARB_IA);
285	}
286
287    /* Map the PCI memory window transparently. */
288    WRITECSR(R_SB_TO_PCI_TRANSLATION0,
289	     (SB_PCI_MEM_BASE & M_SBXLAT_UA) | M_SBXLAT_PE | M_SBXLAT_WB
290	     | V_SBXLAT_AT(K_AT_RW));
291
292    _pci_bus[_pci_nbus] = init_pci_bus;
293    _pci_bus[_pci_nbus].port = port;
294    _pci_nbus++;
295    for (i = _pci_nbus; i < MAXBUS; i++)
296	_pci_bus[i] = init_pci_bus;
297
298    cfe_sleep(CFE_HZ/2);                /* let devices initialize */
299
300    phb_init();
301
302    /* Allow the standard PCI interrupts. */
303    WRITECSR(R_INT_MASK, M_PCIINT_PA | M_PCIINT_PB);
304
305    return 0;
306}
307
308/* Called to update the host bridge after we've scanned each PCI
309   device and know what is possible. */
310void
311pci_hwreinit (int port, pci_flags_t flags)
312{
313}
314
315
316/* The following functions provide for device-specific setup required
317   during configuration.  There is nothing host-specific about them,
318   and it would be better to do the packaging and registration in a
319   more modular way. */
320
321/* Dispatch functions for device pre- and post-configuration hooks. */
322
323/* Called for each hostbridge, to discover and scan secondary buses */
324void
325pci_businit_hostbridge (pcitag_t tag, pci_flags_t flags)
326{
327}
328
329/* Called for each function prior to assigning PCI resources.  */
330int
331pci_device_preset (pcitag_t tag)
332{
333    /* Check for a host bridge seen internally, in which case
334       we don't want to allocate any address space for its BARs. */
335
336    return (tag == SB_PCI_BRIDGE ? 1 : 0);
337}
338
339
340/* Called for each non-bridge (Type 0) function after assigning the
341   BAR and InterruptLine resources. */
342void
343pci_device_setup (pcitag_t tag)
344{
345}
346
347/* Called for each bridge (Type 1) function after configuring the
348   secondary bus, to allow device-specific initialization. */
349void
350pci_bridge_setup (pcitag_t tag, pci_flags_t flags)
351{
352}
353
354
355/* Machine dependent access primitives and utility functions */
356
357void
358pci_flush (void)
359{
360}
361
362
363pcitag_t
364pci_make_tag (int port, int bus, int device, int function)
365{
366    return PCI_MAKE_TAG(bus, device, function);
367}
368
369void
370pci_break_tag (pcitag_t tag,
371	       int *portp, int *busp, int *devicep, int *functionp)
372{
373    if (portp) *portp = 0;
374    if (busp) *busp = (tag >> 16) & PCI_BUSMAX;
375    if (devicep) *devicep = (tag >> 11) & PCI_DEVMAX;
376    if (functionp) *functionp = (tag >> 8) & PCI_FUNCMAX;
377}
378
379
380/* Read/write access to PCI configuration registers.  Type0 addresses
381   are used for bus 0, with a unary encoding of IDSEL in which device
382   n is mapped to bit 16+n (16 possible devices, 0..15). */
383
384int
385pci_canscan (pcitag_t tag)
386{
387    int bus, device, function;
388
389    pci_break_tag(tag, NULL, &bus, &device, &function);
390    if (bus > PCI_BUSMAX || device > PCI_DEVMAX || function > PCI_FUNCMAX)
391	return 0;
392
393    return (bus != 0 || (device >= 0 && device < 16));
394}
395
396int
397pci_probe_tag(pcitag_t tag)
398{
399    pcireg_t data;
400    jmpbuf_t *jb;
401
402    if (!pci_canscan(tag))
403	return 0;
404
405    jb = exc_initialize_block();
406    if (jb == NULL)
407	return 0;
408
409    if (exc_try(jb) == 0)
410	data = pci_conf_read(tag, PCI_ID_REG);  /* bus error if no response */
411    else
412	data = 0xffffffff;
413
414    exc_cleanup_block(jb);
415
416    /* if it returned all vendor id bits set, it's not a device */
417    return (PCI_VENDOR(data) != 0xffff);
418}
419
420
421/* Note that READCFG/WRITECFG uses below can generate bus errors that
422   are not caught; guard calls with these functions with pci_probe_tag. */
423
424pcireg_t
425pci_conf_read(pcitag_t tag, int reg)
426{
427    int bus, device, function;
428    pcireg_t data;
429    uint32_t addr;
430
431    pci_break_tag(tag, NULL, &bus, &device, &function);
432
433    addr = (function << 8) | (reg & 0xFC);  /* common part */
434    if (bus == 0) {
435	if (device < 16) {
436	    /* Generate a Type0 configuration cycle. */
437	    addr |= (1 << (16 + device));
438	    WRITECSR(R_SB_TO_PCI_TRANSLATION1,
439		     (addr & M_SBXLAT_UA) | V_SBXLAT_AT(K_AT_CFG0_RW));
440	    (void)READCSR(R_SB_TO_PCI_TRANSLATION1);  /* push */
441	    addr &= ~M_SBXLAT_UA;
442	    data = READCFG(addr);
443	    }
444	else
445	    data = 0xFFFFFFFF;
446	}
447    else {
448	/* Generate a Type1 configuration cycle. */
449	addr |= (bus << 16) | (device << 11);
450	WRITECSR(R_SB_TO_PCI_TRANSLATION1,
451		 (addr & M_SBXLAT_UA) | V_SBXLAT_AT(K_AT_CFG1_RW));
452	(void)READCSR(R_SB_TO_PCI_TRANSLATION1);  /* push */
453	addr &= ~M_SBXLAT_UA;
454	data = READCFG(addr);
455	}
456
457    return data;
458}
459
460void
461pci_conf_write(pcitag_t tag, int reg, pcireg_t data)
462{
463    int bus, device, function;
464    uint32_t addr;
465
466    pci_break_tag(tag, NULL, &bus, &device, &function);
467
468    addr = (function << 8) | (reg & 0xFC);  /* common part */
469    if (bus == 0) {
470	if (device < 16) {
471	    /* Generate a Type0 configuration cycle. */
472	    addr |= (1 << (16 + device));
473	    WRITECSR(R_SB_TO_PCI_TRANSLATION1,
474		     (addr & M_SBXLAT_UA) | V_SBXLAT_AT(K_AT_CFG0_RW));
475	    (void)READCSR(R_SB_TO_PCI_TRANSLATION1);  /* push */
476	    addr &= ~M_SBXLAT_UA;
477	    WRITECFG(addr & ~SB_PCI_CFG_BASE, data);
478	    }
479	}
480    else {
481	/* Generate a Type1 configuration cycle. */
482	addr |= (bus << 16) | (device << 11);
483	WRITECSR(R_SB_TO_PCI_TRANSLATION1,
484		 (addr & M_SBXLAT_UA) | V_SBXLAT_AT(K_AT_CFG1_RW));
485	addr &= ~M_SBXLAT_UA;
486	(void)READCSR(R_SB_TO_PCI_TRANSLATION1);  /* push */
487	WRITECFG(addr, data);
488	}
489}
490
491int
492pci_conf_write_acked(pcitag_t tag, int reg, pcireg_t data)
493{
494    pci_conf_write(tag, reg, data);
495    (void) pci_conf_read(tag, reg);
496    return 1;
497}
498
499
500int
501pci_map_io(pcitag_t tag, int reg, pci_endian_t endian, phys_addr_t *pap)
502{
503    pci_tagprintf(tag, "pci_map_io: i/o regions not supported\n");
504    return -1;
505}
506
507int
508pci_map_mem(pcitag_t tag, int reg, pci_endian_t endian, phys_addr_t *pap)
509{
510    pcireg_t address;
511    phys_addr_t pa;
512
513    if (reg == PCI_MAPREG_ROM) {
514	/* expansion ROM */
515	address = pci_conf_read(tag, reg);
516	if ((address & PCI_MAPREG_ROM_ENABLE) == 0) {
517	    pci_tagprintf(tag, "pci_map_mem: attempt to map missing rom\n");
518	    return -1;
519	    }
520	pa = address & PCI_MAPREG_ROM_ADDR_MASK;
521	}
522    else {
523	if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) {
524	    if (_pciverbose != 0)
525		pci_tagprintf(tag, "pci_map_mem: bad request\n");
526	    return -1;
527	    }
528
529	address = pci_conf_read(tag, reg);
530
531	if ((address & PCI_MAPREG_TYPE_IO) != 0) {
532	    if (_pciverbose != 0)
533		pci_tagprintf(tag, "pci_map_mem: attempt to memory map an I/O region\n");
534	    return -1;
535	    }
536
537	pa = address & PCI_MAPREG_MEM_ADDR_MASK;
538
539	switch (address & PCI_MAPREG_MEM_TYPE_MASK) {
540	    case PCI_MAPREG_MEM_TYPE_32BIT:
541	    case PCI_MAPREG_MEM_TYPE_32BIT_1M:
542		break;
543	    case PCI_MAPREG_MEM_TYPE_64BIT:
544		if (reg + 4 < PCI_MAPREG_END)
545		    pa |= ((phys_addr_t)pci_conf_read(tag, reg+4) << 32);
546		else {
547		    if (_pciverbose != 0)
548			pci_tagprintf(tag, "pci_map_mem: bad 64-bit reguest\n");
549		    return -1;
550		    }
551		break;
552	    default:
553		if (_pciverbose != 0)
554		    pci_tagprintf(tag, "pci_map_mem: reserved mapping type\n");
555		return -1;
556	    }
557	}
558
559    /* XXX Do something about endian.  Byte-swapping in cross-endian
560       systems cannot really be handled here.  In the BCM47xx cores,
561       swapping of DRAM accesses (only) is controlled by a bit in the
562       DRAM address, not in the PCI address as in the BCM1250. */
563    *pap = pa;
564    return 0;
565}
566
567
568/* ISA-style i/o access (not supported) */
569
570uint8_t
571inb (unsigned int port)
572{
573    xprintf("inb: i/o regions not supported\n");
574    return 0xFF;
575}
576
577uint16_t
578inw (unsigned int port)
579{
580    xprintf("inw: i/o regions not supported\n");
581    return 0xFFFF;
582}
583
584uint32_t
585inl (unsigned int port)
586{
587    xprintf("inl: i/o regions not supported\n");
588    return 0xFFFFFFFF;
589}
590
591void
592outb (unsigned int port, uint8_t val)
593{
594    xprintf("outb: i/o regions not supported\n");
595}
596
597void
598outw (unsigned int port, uint16_t val)
599{
600    xprintf("outw: i/o regions not supported\n");
601}
602
603void
604outl (unsigned int port, uint32_t val)
605{
606    xprintf("outl: i/o regions not supported\n");
607}
608
609
610/* Interrupt slot wiring.  Eval boards apparently connect only INTA
611   and INTB but use INTA<->INTA for all devices and slots.
612
613   This should be board specific except that, for all boards, all PCI
614   interrupts are reduced to a single backplane flag before being
615   routed to the CPU. */
616
617/* Map PCI interrupts A, B, C, D into a value for the IntLine
618   register.  Return the source number used by the
619   interrupt mapper, or 0xff if none. */
620uint8_t
621pci_int_line(uint8_t pci_int)
622{
623    uint32_t flag;
624
625    flag = READCSR(R_SBTPSFLAG);
626    return (pci_int == 0) ? 0xFF : G_SBTSF_FN(flag);
627}
628