1
2
3
4
5
6
7
8#define __EXTERN_INLINE inline
9#include <asm/io.h>
10#include <asm/core_marvel.h>
11#undef __EXTERN_INLINE
12
13#include <linux/types.h>
14#include <linux/pci.h>
15#include <linux/sched.h>
16#include <linux/init.h>
17#include <linux/vmalloc.h>
18#include <linux/mc146818rtc.h>
19#include <linux/rtc.h>
20#include <linux/module.h>
21#include <linux/memblock.h>
22
23#include <asm/ptrace.h>
24#include <asm/smp.h>
25#include <asm/gct.h>
26#include <asm/tlbflush.h>
27#include <asm/vga.h>
28
29#include "proto.h"
30#include "pci_impl.h"
31
32
33
34
35
36#define DEBUG_CONFIG 0
37
38#if DEBUG_CONFIG
39# define DBG_CFG(args) printk args
40#else
41# define DBG_CFG(args)
42#endif
43
44
45
46
47
48static struct io7 *io7_head = NULL;
49
50
51
52
53
54static unsigned long __attribute__ ((unused))
55read_ev7_csr(int pe, unsigned long offset)
56{
57 ev7_csr *ev7csr = EV7_CSR_KERN(pe, offset);
58 unsigned long q;
59
60 mb();
61 q = ev7csr->csr;
62 mb();
63
64 return q;
65}
66
67static void __attribute__ ((unused))
68write_ev7_csr(int pe, unsigned long offset, unsigned long q)
69{
70 ev7_csr *ev7csr = EV7_CSR_KERN(pe, offset);
71
72 mb();
73 ev7csr->csr = q;
74 mb();
75}
76
77static char * __init
78mk_resource_name(int pe, int port, char *str)
79{
80 char tmp[80];
81 char *name;
82
83 sprintf(tmp, "PCI %s PE %d PORT %d", str, pe, port);
84 name = memblock_alloc(strlen(tmp) + 1, SMP_CACHE_BYTES);
85 if (!name)
86 panic("%s: Failed to allocate %zu bytes\n", __func__,
87 strlen(tmp) + 1);
88 strcpy(name, tmp);
89
90 return name;
91}
92
93inline struct io7 *
94marvel_next_io7(struct io7 *prev)
95{
96 return (prev ? prev->next : io7_head);
97}
98
99struct io7 *
100marvel_find_io7(int pe)
101{
102 struct io7 *io7;
103
104 for (io7 = io7_head; io7 && io7->pe != pe; io7 = io7->next)
105 continue;
106
107 return io7;
108}
109
110static struct io7 * __init
111alloc_io7(unsigned int pe)
112{
113 struct io7 *io7;
114 struct io7 *insp;
115 int h;
116
117 if (marvel_find_io7(pe)) {
118 printk(KERN_WARNING "IO7 at PE %d already allocated!\n", pe);
119 return NULL;
120 }
121
122 io7 = memblock_alloc(sizeof(*io7), SMP_CACHE_BYTES);
123 if (!io7)
124 panic("%s: Failed to allocate %zu bytes\n", __func__,
125 sizeof(*io7));
126 io7->pe = pe;
127 raw_spin_lock_init(&io7->irq_lock);
128
129 for (h = 0; h < 4; h++) {
130 io7->ports[h].io7 = io7;
131 io7->ports[h].port = h;
132 io7->ports[h].enabled = 0;
133 }
134
135
136
137
138 if (NULL == io7_head)
139 io7_head = io7;
140 else if (io7_head->pe > io7->pe) {
141 io7->next = io7_head;
142 io7_head = io7;
143 } else {
144 for (insp = io7_head; insp; insp = insp->next) {
145 if (insp->pe == io7->pe) {
146 printk(KERN_ERR "Too many IO7s at PE %d\n",
147 io7->pe);
148 return NULL;
149 }
150
151 if (NULL == insp->next ||
152 insp->next->pe > io7->pe) {
153 io7->next = insp->next;
154 insp->next = io7;
155 break;
156 }
157 }
158
159 if (NULL == insp) {
160 printk(KERN_WARNING "Failed to insert IO7 at PE %d "
161 " - adding at head of list\n", io7->pe);
162 io7->next = io7_head;
163 io7_head = io7;
164 }
165 }
166
167 return io7;
168}
169
170void
171io7_clear_errors(struct io7 *io7)
172{
173 io7_port7_csrs *p7csrs;
174 io7_ioport_csrs *csrs;
175 int port;
176
177
178
179
180
181 for (port = 0; port < 4; port++) {
182 csrs = IO7_CSRS_KERN(io7->pe, port);
183
184 csrs->POx_ERR_SUM.csr = -1UL;
185 csrs->POx_TLB_ERR.csr = -1UL;
186 csrs->POx_SPL_COMPLT.csr = -1UL;
187 csrs->POx_TRANS_SUM.csr = -1UL;
188 }
189
190
191
192
193 p7csrs = IO7_PORT7_CSRS_KERN(io7->pe);
194
195 p7csrs->PO7_ERROR_SUM.csr = -1UL;
196 p7csrs->PO7_UNCRR_SYM.csr = -1UL;
197 p7csrs->PO7_CRRCT_SYM.csr = -1UL;
198}
199
200
201
202
203
204static void __init
205io7_init_hose(struct io7 *io7, int port)
206{
207 static int hose_index = 0;
208
209 struct pci_controller *hose = alloc_pci_controller();
210 struct io7_port *io7_port = &io7->ports[port];
211 io7_ioport_csrs *csrs = IO7_CSRS_KERN(io7->pe, port);
212 int i;
213
214 hose->index = hose_index++;
215
216
217
218
219
220
221
222
223
224 if (hose->index == 0)
225 pci_isa_hose = hose;
226
227 io7_port->csrs = csrs;
228 io7_port->hose = hose;
229 hose->sysdata = io7_port;
230
231 hose->io_space = alloc_resource();
232 hose->mem_space = alloc_resource();
233
234
235
236
237
238 hose->sparse_mem_base = hose->sparse_io_base = 0;
239 hose->dense_mem_base = IO7_MEM_PHYS(io7->pe, port);
240 hose->dense_io_base = IO7_IO_PHYS(io7->pe, port);
241
242
243
244
245 hose->config_space_base = (unsigned long)IO7_CONF_KERN(io7->pe, port);
246
247 hose->io_space->start = (unsigned long)IO7_IO_KERN(io7->pe, port);
248 hose->io_space->end = hose->io_space->start + IO7_IO_SPACE - 1;
249 hose->io_space->name = mk_resource_name(io7->pe, port, "IO");
250 hose->io_space->flags = IORESOURCE_IO;
251
252 hose->mem_space->start = (unsigned long)IO7_MEM_KERN(io7->pe, port);
253 hose->mem_space->end = hose->mem_space->start + IO7_MEM_SPACE - 1;
254 hose->mem_space->name = mk_resource_name(io7->pe, port, "MEM");
255 hose->mem_space->flags = IORESOURCE_MEM;
256
257 if (request_resource(&ioport_resource, hose->io_space) < 0)
258 printk(KERN_ERR "Failed to request IO on hose %d\n",
259 hose->index);
260 if (request_resource(&iomem_resource, hose->mem_space) < 0)
261 printk(KERN_ERR "Failed to request MEM on hose %d\n",
262 hose->index);
263
264
265
266
267 for (i = 0; i < 4; i++) {
268 io7_port->saved_wbase[i] = csrs->POx_WBASE[i].csr;
269 io7_port->saved_wmask[i] = csrs->POx_WMASK[i].csr;
270 io7_port->saved_tbase[i] = csrs->POx_TBASE[i].csr;
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285 marvel_pci_tbi(hose, 0, -1);
286
287
288
289
290 hose->sg_isa = iommu_arena_new_node(0, hose, 0x00800000, 0x00800000, 0);
291 hose->sg_isa->align_entry = 8;
292 csrs->POx_WBASE[0].csr =
293 hose->sg_isa->dma_base | wbase_m_ena | wbase_m_sg;
294 csrs->POx_WMASK[0].csr = (hose->sg_isa->size - 1) & wbase_m_addr;
295 csrs->POx_TBASE[0].csr = virt_to_phys(hose->sg_isa->ptes);
296
297
298
299
300 csrs->POx_WBASE[1].csr = __direct_map_base | wbase_m_ena;
301 csrs->POx_WMASK[1].csr = (__direct_map_size - 1) & wbase_m_addr;
302 csrs->POx_TBASE[1].csr = 0;
303
304
305
306
307 hose->sg_pci = iommu_arena_new_node(0, hose, 0xc0000000, 0x40000000, 0);
308 hose->sg_pci->align_entry = 8;
309 csrs->POx_WBASE[2].csr =
310 hose->sg_pci->dma_base | wbase_m_ena | wbase_m_sg;
311 csrs->POx_WMASK[2].csr = (hose->sg_pci->size - 1) & wbase_m_addr;
312 csrs->POx_TBASE[2].csr = virt_to_phys(hose->sg_pci->ptes);
313
314
315
316
317 csrs->POx_WBASE[3].csr = 0;
318
319
320
321
322 csrs->POx_CTRL.csr &= ~(1UL << 61);
323
324#if 1
325 printk("FIXME: disabling master aborts\n");
326 csrs->POx_MSK_HEI.csr &= ~(3UL << 14);
327#endif
328
329
330
331 marvel_pci_tbi(hose, 0, -1);
332}
333
334static void __init
335marvel_init_io7(struct io7 *io7)
336{
337 int i;
338
339 printk("Initializing IO7 at PID %d\n", io7->pe);
340
341
342
343
344 io7->csrs = IO7_PORT7_CSRS_KERN(io7->pe);
345
346
347
348
349 for (i = 0; i < IO7_NUM_PORTS; i++) {
350 io7_ioport_csrs *csrs = IO7_CSRS_KERN(io7->pe, i);
351 if (csrs->POx_CACHE_CTL.csr == 8) {
352 io7->ports[i].enabled = 1;
353 io7_init_hose(io7, i);
354 }
355 }
356}
357
358void __init
359marvel_io7_present(gct6_node *node)
360{
361 int pe;
362
363 if (node->type != GCT_TYPE_HOSE ||
364 node->subtype != GCT_SUBTYPE_IO_PORT_MODULE)
365 return;
366
367 pe = (node->id >> 8) & 0xff;
368 printk("Found an IO7 at PID %d\n", pe);
369
370 alloc_io7(pe);
371}
372
373static void __init
374marvel_find_console_vga_hose(void)
375{
376#ifdef CONFIG_VGA_HOSE
377 u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset);
378
379 if (pu64[7] == 3) {
380 struct pci_controller *hose = NULL;
381 int h = (pu64[30] >> 24) & 0xff;
382 struct io7 *io7;
383 int pid, port;
384
385
386
387
388
389
390 printk("console graphics is on hose %d (console)\n", h);
391
392
393
394
395
396
397
398
399
400 pid = h >> 2;
401 port = h & 3;
402 if ((io7 = marvel_find_io7(pid)))
403 hose = io7->ports[port].hose;
404
405 if (hose) {
406 printk("Console graphics on hose %d\n", hose->index);
407 pci_vga_hose = hose;
408 }
409 }
410#endif
411}
412
413gct6_search_struct gct_wanted_node_list[] __initdata = {
414 { GCT_TYPE_HOSE, GCT_SUBTYPE_IO_PORT_MODULE, marvel_io7_present },
415 { 0, 0, NULL }
416};
417
418
419
420
421
422
423static int __init
424marvel_specify_io7(char *str)
425{
426 unsigned long pid;
427 struct io7 *io7;
428 char *pchar;
429
430 do {
431 pid = simple_strtoul(str, &pchar, 0);
432 if (pchar != str) {
433 printk("User-specified IO7 at PID %lu\n", pid);
434 io7 = alloc_io7(pid);
435 if (io7) marvel_init_io7(io7);
436 }
437
438 if (pchar == str) pchar++;
439 str = pchar;
440 } while(*str);
441
442 return 1;
443}
444__setup("io7=", marvel_specify_io7);
445
446void __init
447marvel_init_arch(void)
448{
449 struct io7 *io7;
450
451
452 ioport_resource.end = ~0UL;
453
454
455 __direct_map_base = 0x80000000;
456 __direct_map_size = 0x40000000;
457
458
459 gct6_find_nodes(GCT_NODE_PTR(0), gct_wanted_node_list);
460
461
462 for (io7 = NULL; NULL != (io7 = marvel_next_io7(io7)); )
463 marvel_init_io7(io7);
464
465
466 marvel_find_console_vga_hose();
467}
468
469void
470marvel_kill_arch(int mode)
471{
472}
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502static inline unsigned long
503build_conf_addr(struct pci_controller *hose, u8 bus,
504 unsigned int devfn, int where)
505{
506 return (hose->config_space_base | (bus << 16) | (devfn << 8) | where);
507}
508
509static unsigned long
510mk_conf_addr(struct pci_bus *pbus, unsigned int devfn, int where)
511{
512 struct pci_controller *hose = pbus->sysdata;
513 struct io7_port *io7_port;
514 unsigned long addr = 0;
515 u8 bus = pbus->number;
516
517 if (!hose)
518 return addr;
519
520
521 io7_port = hose->sysdata;
522 if (!io7_port->enabled)
523 return addr;
524
525 if (!pbus->parent) {
526
527 if (devfn >= PCI_DEVFN(21, 0))
528 return addr;
529 bus = 0;
530 }
531
532 addr = build_conf_addr(hose, bus, devfn, where);
533
534 DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
535 return addr;
536}
537
538static int
539marvel_read_config(struct pci_bus *bus, unsigned int devfn, int where,
540 int size, u32 *value)
541{
542 unsigned long addr;
543
544 if (0 == (addr = mk_conf_addr(bus, devfn, where)))
545 return PCIBIOS_DEVICE_NOT_FOUND;
546
547 switch(size) {
548 case 1:
549 *value = __kernel_ldbu(*(vucp)addr);
550 break;
551 case 2:
552 *value = __kernel_ldwu(*(vusp)addr);
553 break;
554 case 4:
555 *value = *(vuip)addr;
556 break;
557 default:
558 return PCIBIOS_FUNC_NOT_SUPPORTED;
559 }
560
561 return PCIBIOS_SUCCESSFUL;
562}
563
564static int
565marvel_write_config(struct pci_bus *bus, unsigned int devfn, int where,
566 int size, u32 value)
567{
568 unsigned long addr;
569
570 if (0 == (addr = mk_conf_addr(bus, devfn, where)))
571 return PCIBIOS_DEVICE_NOT_FOUND;
572
573 switch (size) {
574 case 1:
575 __kernel_stb(value, *(vucp)addr);
576 mb();
577 __kernel_ldbu(*(vucp)addr);
578 break;
579 case 2:
580 __kernel_stw(value, *(vusp)addr);
581 mb();
582 __kernel_ldwu(*(vusp)addr);
583 break;
584 case 4:
585 *(vuip)addr = value;
586 mb();
587 *(vuip)addr;
588 break;
589 default:
590 return PCIBIOS_FUNC_NOT_SUPPORTED;
591 }
592
593 return PCIBIOS_SUCCESSFUL;
594}
595
596struct pci_ops marvel_pci_ops =
597{
598 .read = marvel_read_config,
599 .write = marvel_write_config,
600};
601
602
603
604
605
606void
607marvel_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
608{
609 io7_ioport_csrs *csrs = ((struct io7_port *)hose->sysdata)->csrs;
610
611 wmb();
612 csrs->POx_SG_TBIA.csr = 0;
613 mb();
614 csrs->POx_SG_TBIA.csr;
615}
616
617
618
619
620
621
622struct marvel_rtc_access_info {
623 unsigned long function;
624 unsigned long index;
625 unsigned long data;
626};
627
628static void
629__marvel_access_rtc(void *info)
630{
631 struct marvel_rtc_access_info *rtc_access = info;
632
633 register unsigned long __r0 __asm__("$0");
634 register unsigned long __r16 __asm__("$16") = rtc_access->function;
635 register unsigned long __r17 __asm__("$17") = rtc_access->index;
636 register unsigned long __r18 __asm__("$18") = rtc_access->data;
637
638 __asm__ __volatile__(
639 "call_pal %4 # cserve rtc"
640 : "=r"(__r16), "=r"(__r17), "=r"(__r18), "=r"(__r0)
641 : "i"(PAL_cserve), "0"(__r16), "1"(__r17), "2"(__r18)
642 : "$1", "$22", "$23", "$24", "$25");
643
644 rtc_access->data = __r0;
645}
646
647static u8
648__marvel_rtc_io(u8 b, unsigned long addr, int write)
649{
650 static u8 index = 0;
651
652 struct marvel_rtc_access_info rtc_access;
653 u8 ret = 0;
654
655 switch(addr) {
656 case 0x70:
657 if (write) index = b;
658 ret = index;
659 break;
660
661 case 0x71:
662 rtc_access.index = index;
663 rtc_access.data = bcd2bin(b);
664 rtc_access.function = 0x48 + !write;
665
666 __marvel_access_rtc(&rtc_access);
667
668 ret = bin2bcd(rtc_access.data);
669 break;
670
671 default:
672 printk(KERN_WARNING "Illegal RTC port %lx\n", addr);
673 break;
674 }
675
676 return ret;
677}
678
679
680
681
682
683void __iomem *
684marvel_ioremap(unsigned long addr, unsigned long size)
685{
686 struct pci_controller *hose;
687 unsigned long baddr, last;
688 struct vm_struct *area;
689 unsigned long vaddr;
690 unsigned long *ptes;
691 unsigned long pfn;
692
693
694
695
696 FIXUP_MEMADDR_VGA(addr);
697
698
699
700
701 for (hose = hose_head; hose; hose = hose->next) {
702 if ((addr >> 32) == (hose->mem_space->start >> 32))
703 break;
704 }
705 if (!hose)
706 return NULL;
707
708
709
710
711 baddr = addr - hose->mem_space->start;
712 last = baddr + size - 1;
713
714
715
716
717 if ((baddr >= __direct_map_base) &&
718 ((baddr + size - 1) < __direct_map_base + __direct_map_size)) {
719 addr = IDENT_ADDR | (baddr - __direct_map_base);
720 return (void __iomem *) addr;
721 }
722
723
724
725
726 if (hose->sg_pci &&
727 baddr >= (unsigned long)hose->sg_pci->dma_base &&
728 last < (unsigned long)hose->sg_pci->dma_base + hose->sg_pci->size) {
729
730
731
732
733 baddr -= hose->sg_pci->dma_base;
734 last -= hose->sg_pci->dma_base;
735 baddr &= PAGE_MASK;
736 size = PAGE_ALIGN(last) - baddr;
737
738
739
740
741 area = get_vm_area(size, VM_IOREMAP);
742 if (!area)
743 return NULL;
744
745 ptes = hose->sg_pci->ptes;
746 for (vaddr = (unsigned long)area->addr;
747 baddr <= last;
748 baddr += PAGE_SIZE, vaddr += PAGE_SIZE) {
749 pfn = ptes[baddr >> PAGE_SHIFT];
750 if (!(pfn & 1)) {
751 printk("ioremap failed... pte not valid...\n");
752 vfree(area->addr);
753 return NULL;
754 }
755 pfn >>= 1;
756
757 if (__alpha_remap_area_pages(vaddr,
758 pfn << PAGE_SHIFT,
759 PAGE_SIZE, 0)) {
760 printk("FAILED to map...\n");
761 vfree(area->addr);
762 return NULL;
763 }
764 }
765
766 flush_tlb_all();
767
768 vaddr = (unsigned long)area->addr + (addr & ~PAGE_MASK);
769
770 return (void __iomem *) vaddr;
771 }
772
773
774 vaddr = baddr + hose->mem_space->start;
775 return (void __iomem *) vaddr;
776}
777
778void
779marvel_iounmap(volatile void __iomem *xaddr)
780{
781 unsigned long addr = (unsigned long) xaddr;
782 if (addr >= VMALLOC_START)
783 vfree((void *)(PAGE_MASK & addr));
784}
785
786int
787marvel_is_mmio(const volatile void __iomem *xaddr)
788{
789 unsigned long addr = (unsigned long) xaddr;
790
791 if (addr >= VMALLOC_START)
792 return 1;
793 else
794 return (addr & 0xFF000000UL) == 0;
795}
796
797#define __marvel_is_port_kbd(a) (((a) == 0x60) || ((a) == 0x64))
798#define __marvel_is_port_rtc(a) (((a) == 0x70) || ((a) == 0x71))
799
800void __iomem *marvel_ioportmap (unsigned long addr)
801{
802 FIXUP_IOADDR_VGA(addr);
803 return (void __iomem *)addr;
804}
805
806unsigned int
807marvel_ioread8(const void __iomem *xaddr)
808{
809 unsigned long addr = (unsigned long) xaddr;
810 if (__marvel_is_port_kbd(addr))
811 return 0;
812 else if (__marvel_is_port_rtc(addr))
813 return __marvel_rtc_io(0, addr, 0);
814 else if (marvel_is_ioaddr(addr))
815 return __kernel_ldbu(*(vucp)addr);
816 else
817
818
819
820
821 return ~0;
822}
823
824void
825marvel_iowrite8(u8 b, void __iomem *xaddr)
826{
827 unsigned long addr = (unsigned long) xaddr;
828 if (__marvel_is_port_kbd(addr))
829 return;
830 else if (__marvel_is_port_rtc(addr))
831 __marvel_rtc_io(b, addr, 1);
832 else if (marvel_is_ioaddr(addr))
833 __kernel_stb(b, *(vucp)addr);
834}
835
836#ifndef CONFIG_ALPHA_GENERIC
837EXPORT_SYMBOL(marvel_ioremap);
838EXPORT_SYMBOL(marvel_iounmap);
839EXPORT_SYMBOL(marvel_is_mmio);
840EXPORT_SYMBOL(marvel_ioportmap);
841EXPORT_SYMBOL(marvel_ioread8);
842EXPORT_SYMBOL(marvel_iowrite8);
843#endif
844
845
846
847
848#include <linux/agp_backend.h>
849#include <asm/agp_backend.h>
850#include <linux/slab.h>
851#include <linux/delay.h>
852
853struct marvel_agp_aperture {
854 struct pci_iommu_arena *arena;
855 long pg_start;
856 long pg_count;
857};
858
859static int
860marvel_agp_setup(alpha_agp_info *agp)
861{
862 struct marvel_agp_aperture *aper;
863
864 if (!alpha_agpgart_size)
865 return -ENOMEM;
866
867 aper = kmalloc(sizeof(*aper), GFP_KERNEL);
868 if (aper == NULL) return -ENOMEM;
869
870 aper->arena = agp->hose->sg_pci;
871 aper->pg_count = alpha_agpgart_size / PAGE_SIZE;
872 aper->pg_start = iommu_reserve(aper->arena, aper->pg_count,
873 aper->pg_count - 1);
874
875 if (aper->pg_start < 0) {
876 printk(KERN_ERR "Failed to reserve AGP memory\n");
877 kfree(aper);
878 return -ENOMEM;
879 }
880
881 agp->aperture.bus_base =
882 aper->arena->dma_base + aper->pg_start * PAGE_SIZE;
883 agp->aperture.size = aper->pg_count * PAGE_SIZE;
884 agp->aperture.sysdata = aper;
885
886 return 0;
887}
888
889static void
890marvel_agp_cleanup(alpha_agp_info *agp)
891{
892 struct marvel_agp_aperture *aper = agp->aperture.sysdata;
893 int status;
894
895 status = iommu_release(aper->arena, aper->pg_start, aper->pg_count);
896 if (status == -EBUSY) {
897 printk(KERN_WARNING
898 "Attempted to release bound AGP memory - unbinding\n");
899 iommu_unbind(aper->arena, aper->pg_start, aper->pg_count);
900 status = iommu_release(aper->arena, aper->pg_start,
901 aper->pg_count);
902 }
903 if (status < 0)
904 printk(KERN_ERR "Failed to release AGP memory\n");
905
906 kfree(aper);
907 kfree(agp);
908}
909
910static int
911marvel_agp_configure(alpha_agp_info *agp)
912{
913 io7_ioport_csrs *csrs = ((struct io7_port *)agp->hose->sysdata)->csrs;
914 struct io7 *io7 = ((struct io7_port *)agp->hose->sysdata)->io7;
915 unsigned int new_rate = 0;
916 unsigned long agp_pll;
917
918
919
920
921
922
923 agp_pll = io7->csrs->POx_RST[IO7_AGP_PORT].csr;
924 switch(IO7_PLL_RNGB(agp_pll)) {
925 case 0x4:
926
927
928
929
930 if (agp->mode.bits.rate != 2)
931 new_rate = 2;
932 break;
933
934 case 0x6:
935
936
937
938
939 if (agp->mode.bits.rate == 2)
940 new_rate = 1;
941 break;
942
943 default:
944
945
946
947
948 printk("%s: unknown PLL setting RNGB=%lx (PLL6_CTL=%016lx)\n",
949 __func__, IO7_PLL_RNGB(agp_pll), agp_pll);
950 break;
951 }
952
953
954
955
956 if (new_rate) {
957 printk("Requested AGP Rate %dX not compatible "
958 "with PLL setting - using %dX\n",
959 agp->mode.bits.rate,
960 new_rate);
961
962 agp->mode.bits.rate = new_rate;
963 }
964
965 printk("Enabling AGP on hose %d: %dX%s RQ %d\n",
966 agp->hose->index, agp->mode.bits.rate,
967 agp->mode.bits.sba ? " - SBA" : "", agp->mode.bits.rq);
968
969 csrs->AGP_CMD.csr = agp->mode.lw;
970
971 return 0;
972}
973
974static int
975marvel_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *mem)
976{
977 struct marvel_agp_aperture *aper = agp->aperture.sysdata;
978 return iommu_bind(aper->arena, aper->pg_start + pg_start,
979 mem->page_count, mem->pages);
980}
981
982static int
983marvel_agp_unbind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *mem)
984{
985 struct marvel_agp_aperture *aper = agp->aperture.sysdata;
986 return iommu_unbind(aper->arena, aper->pg_start + pg_start,
987 mem->page_count);
988}
989
990static unsigned long
991marvel_agp_translate(alpha_agp_info *agp, dma_addr_t addr)
992{
993 struct marvel_agp_aperture *aper = agp->aperture.sysdata;
994 unsigned long baddr = addr - aper->arena->dma_base;
995 unsigned long pte;
996
997 if (addr < agp->aperture.bus_base ||
998 addr >= agp->aperture.bus_base + agp->aperture.size) {
999 printk("%s: addr out of range\n", __func__);
1000 return -EINVAL;
1001 }
1002
1003 pte = aper->arena->ptes[baddr >> PAGE_SHIFT];
1004 if (!(pte & 1)) {
1005 printk("%s: pte not valid\n", __func__);
1006 return -EINVAL;
1007 }
1008 return (pte >> 1) << PAGE_SHIFT;
1009}
1010
1011struct alpha_agp_ops marvel_agp_ops =
1012{
1013 .setup = marvel_agp_setup,
1014 .cleanup = marvel_agp_cleanup,
1015 .configure = marvel_agp_configure,
1016 .bind = marvel_agp_bind_memory,
1017 .unbind = marvel_agp_unbind_memory,
1018 .translate = marvel_agp_translate
1019};
1020
1021alpha_agp_info *
1022marvel_agp_info(void)
1023{
1024 struct pci_controller *hose;
1025 io7_ioport_csrs *csrs;
1026 alpha_agp_info *agp;
1027 struct io7 *io7;
1028
1029
1030
1031
1032
1033
1034
1035 hose = NULL;
1036 for (io7 = NULL; (io7 = marvel_next_io7(io7)) != NULL; ) {
1037 struct pci_controller *h;
1038 vuip addr;
1039
1040 if (!io7->ports[IO7_AGP_PORT].enabled)
1041 continue;
1042
1043 h = io7->ports[IO7_AGP_PORT].hose;
1044 addr = (vuip)build_conf_addr(h, 0, PCI_DEVFN(5, 0), 0);
1045
1046 if (*addr != 0xffffffffu) {
1047 hose = h;
1048 break;
1049 }
1050 }
1051
1052 if (!hose || !hose->sg_pci)
1053 return NULL;
1054
1055 printk("MARVEL - using hose %d as AGP\n", hose->index);
1056
1057
1058
1059
1060 csrs = ((struct io7_port *)hose->sysdata)->csrs;
1061
1062
1063
1064
1065 agp = kmalloc(sizeof(*agp), GFP_KERNEL);
1066 if (!agp)
1067 return NULL;
1068
1069
1070
1071
1072 agp->hose = hose;
1073 agp->private = NULL;
1074 agp->ops = &marvel_agp_ops;
1075
1076
1077
1078
1079 agp->aperture.bus_base = 0;
1080 agp->aperture.size = 0;
1081 agp->aperture.sysdata = NULL;
1082
1083
1084
1085
1086
1087
1088
1089
1090 agp->capability.lw = csrs->AGP_STAT.csr;
1091 agp->capability.bits.rq = 0xf;
1092
1093
1094
1095
1096 agp->mode.lw = csrs->AGP_CMD.csr;
1097
1098 return agp;
1099}
1100