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(marvel_cpuid_to_nid(io7->pe),
291 hose, 0x00800000, 0x00800000, 0);
292 hose->sg_isa->align_entry = 8;
293 csrs->POx_WBASE[0].csr =
294 hose->sg_isa->dma_base | wbase_m_ena | wbase_m_sg;
295 csrs->POx_WMASK[0].csr = (hose->sg_isa->size - 1) & wbase_m_addr;
296 csrs->POx_TBASE[0].csr = virt_to_phys(hose->sg_isa->ptes);
297
298
299
300
301 csrs->POx_WBASE[1].csr = __direct_map_base | wbase_m_ena;
302 csrs->POx_WMASK[1].csr = (__direct_map_size - 1) & wbase_m_addr;
303 csrs->POx_TBASE[1].csr = 0;
304
305
306
307
308 hose->sg_pci = iommu_arena_new_node(marvel_cpuid_to_nid(io7->pe),
309 hose, 0xc0000000, 0x40000000, 0);
310 hose->sg_pci->align_entry = 8;
311 csrs->POx_WBASE[2].csr =
312 hose->sg_pci->dma_base | wbase_m_ena | wbase_m_sg;
313 csrs->POx_WMASK[2].csr = (hose->sg_pci->size - 1) & wbase_m_addr;
314 csrs->POx_TBASE[2].csr = virt_to_phys(hose->sg_pci->ptes);
315
316
317
318
319 csrs->POx_WBASE[3].csr = 0;
320
321
322
323
324 csrs->POx_CTRL.csr &= ~(1UL << 61);
325
326#if 1
327 printk("FIXME: disabling master aborts\n");
328 csrs->POx_MSK_HEI.csr &= ~(3UL << 14);
329#endif
330
331
332
333 marvel_pci_tbi(hose, 0, -1);
334}
335
336static void __init
337marvel_init_io7(struct io7 *io7)
338{
339 int i;
340
341 printk("Initializing IO7 at PID %d\n", io7->pe);
342
343
344
345
346 io7->csrs = IO7_PORT7_CSRS_KERN(io7->pe);
347
348
349
350
351 for (i = 0; i < IO7_NUM_PORTS; i++) {
352 io7_ioport_csrs *csrs = IO7_CSRS_KERN(io7->pe, i);
353 if (csrs->POx_CACHE_CTL.csr == 8) {
354 io7->ports[i].enabled = 1;
355 io7_init_hose(io7, i);
356 }
357 }
358}
359
360void __init
361marvel_io7_present(gct6_node *node)
362{
363 int pe;
364
365 if (node->type != GCT_TYPE_HOSE ||
366 node->subtype != GCT_SUBTYPE_IO_PORT_MODULE)
367 return;
368
369 pe = (node->id >> 8) & 0xff;
370 printk("Found an IO7 at PID %d\n", pe);
371
372 alloc_io7(pe);
373}
374
375static void __init
376marvel_find_console_vga_hose(void)
377{
378#ifdef CONFIG_VGA_HOSE
379 u64 *pu64 = (u64 *)((u64)hwrpb + hwrpb->ctbt_offset);
380
381 if (pu64[7] == 3) {
382 struct pci_controller *hose = NULL;
383 int h = (pu64[30] >> 24) & 0xff;
384 struct io7 *io7;
385 int pid, port;
386
387
388
389
390
391
392 printk("console graphics is on hose %d (console)\n", h);
393
394
395
396
397
398
399
400
401
402 pid = h >> 2;
403 port = h & 3;
404 if ((io7 = marvel_find_io7(pid)))
405 hose = io7->ports[port].hose;
406
407 if (hose) {
408 printk("Console graphics on hose %d\n", hose->index);
409 pci_vga_hose = hose;
410 }
411 }
412#endif
413}
414
415gct6_search_struct gct_wanted_node_list[] __initdata = {
416 { GCT_TYPE_HOSE, GCT_SUBTYPE_IO_PORT_MODULE, marvel_io7_present },
417 { 0, 0, NULL }
418};
419
420
421
422
423
424
425static int __init
426marvel_specify_io7(char *str)
427{
428 unsigned long pid;
429 struct io7 *io7;
430 char *pchar;
431
432 do {
433 pid = simple_strtoul(str, &pchar, 0);
434 if (pchar != str) {
435 printk("User-specified IO7 at PID %lu\n", pid);
436 io7 = alloc_io7(pid);
437 if (io7) marvel_init_io7(io7);
438 }
439
440 if (pchar == str) pchar++;
441 str = pchar;
442 } while(*str);
443
444 return 1;
445}
446__setup("io7=", marvel_specify_io7);
447
448void __init
449marvel_init_arch(void)
450{
451 struct io7 *io7;
452
453
454 ioport_resource.end = ~0UL;
455
456
457 __direct_map_base = 0x80000000;
458 __direct_map_size = 0x40000000;
459
460
461 gct6_find_nodes(GCT_NODE_PTR(0), gct_wanted_node_list);
462
463
464 for (io7 = NULL; NULL != (io7 = marvel_next_io7(io7)); )
465 marvel_init_io7(io7);
466
467
468 marvel_find_console_vga_hose();
469}
470
471void
472marvel_kill_arch(int mode)
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
502
503
504static inline unsigned long
505build_conf_addr(struct pci_controller *hose, u8 bus,
506 unsigned int devfn, int where)
507{
508 return (hose->config_space_base | (bus << 16) | (devfn << 8) | where);
509}
510
511static unsigned long
512mk_conf_addr(struct pci_bus *pbus, unsigned int devfn, int where)
513{
514 struct pci_controller *hose = pbus->sysdata;
515 struct io7_port *io7_port;
516 unsigned long addr = 0;
517 u8 bus = pbus->number;
518
519 if (!hose)
520 return addr;
521
522
523 io7_port = hose->sysdata;
524 if (!io7_port->enabled)
525 return addr;
526
527 if (!pbus->parent) {
528
529 if (devfn >= PCI_DEVFN(21, 0))
530 return addr;
531 bus = 0;
532 }
533
534 addr = build_conf_addr(hose, bus, devfn, where);
535
536 DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
537 return addr;
538}
539
540static int
541marvel_read_config(struct pci_bus *bus, unsigned int devfn, int where,
542 int size, u32 *value)
543{
544 unsigned long addr;
545
546 if (0 == (addr = mk_conf_addr(bus, devfn, where)))
547 return PCIBIOS_DEVICE_NOT_FOUND;
548
549 switch(size) {
550 case 1:
551 *value = __kernel_ldbu(*(vucp)addr);
552 break;
553 case 2:
554 *value = __kernel_ldwu(*(vusp)addr);
555 break;
556 case 4:
557 *value = *(vuip)addr;
558 break;
559 default:
560 return PCIBIOS_FUNC_NOT_SUPPORTED;
561 }
562
563 return PCIBIOS_SUCCESSFUL;
564}
565
566static int
567marvel_write_config(struct pci_bus *bus, unsigned int devfn, int where,
568 int size, u32 value)
569{
570 unsigned long addr;
571
572 if (0 == (addr = mk_conf_addr(bus, devfn, where)))
573 return PCIBIOS_DEVICE_NOT_FOUND;
574
575 switch (size) {
576 case 1:
577 __kernel_stb(value, *(vucp)addr);
578 mb();
579 __kernel_ldbu(*(vucp)addr);
580 break;
581 case 2:
582 __kernel_stw(value, *(vusp)addr);
583 mb();
584 __kernel_ldwu(*(vusp)addr);
585 break;
586 case 4:
587 *(vuip)addr = value;
588 mb();
589 *(vuip)addr;
590 break;
591 default:
592 return PCIBIOS_FUNC_NOT_SUPPORTED;
593 }
594
595 return PCIBIOS_SUCCESSFUL;
596}
597
598struct pci_ops marvel_pci_ops =
599{
600 .read = marvel_read_config,
601 .write = marvel_write_config,
602};
603
604
605
606
607
608void
609marvel_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
610{
611 io7_ioport_csrs *csrs = ((struct io7_port *)hose->sysdata)->csrs;
612
613 wmb();
614 csrs->POx_SG_TBIA.csr = 0;
615 mb();
616 csrs->POx_SG_TBIA.csr;
617}
618
619
620
621
622
623
624struct marvel_rtc_access_info {
625 unsigned long function;
626 unsigned long index;
627 unsigned long data;
628};
629
630static void
631__marvel_access_rtc(void *info)
632{
633 struct marvel_rtc_access_info *rtc_access = info;
634
635 register unsigned long __r0 __asm__("$0");
636 register unsigned long __r16 __asm__("$16") = rtc_access->function;
637 register unsigned long __r17 __asm__("$17") = rtc_access->index;
638 register unsigned long __r18 __asm__("$18") = rtc_access->data;
639
640 __asm__ __volatile__(
641 "call_pal %4 # cserve rtc"
642 : "=r"(__r16), "=r"(__r17), "=r"(__r18), "=r"(__r0)
643 : "i"(PAL_cserve), "0"(__r16), "1"(__r17), "2"(__r18)
644 : "$1", "$22", "$23", "$24", "$25");
645
646 rtc_access->data = __r0;
647}
648
649static u8
650__marvel_rtc_io(u8 b, unsigned long addr, int write)
651{
652 static u8 index = 0;
653
654 struct marvel_rtc_access_info rtc_access;
655 u8 ret = 0;
656
657 switch(addr) {
658 case 0x70:
659 if (write) index = b;
660 ret = index;
661 break;
662
663 case 0x71:
664 rtc_access.index = index;
665 rtc_access.data = bcd2bin(b);
666 rtc_access.function = 0x48 + !write;
667
668 __marvel_access_rtc(&rtc_access);
669
670 ret = bin2bcd(rtc_access.data);
671 break;
672
673 default:
674 printk(KERN_WARNING "Illegal RTC port %lx\n", addr);
675 break;
676 }
677
678 return ret;
679}
680
681
682
683
684
685void __iomem *
686marvel_ioremap(unsigned long addr, unsigned long size)
687{
688 struct pci_controller *hose;
689 unsigned long baddr, last;
690 struct vm_struct *area;
691 unsigned long vaddr;
692 unsigned long *ptes;
693 unsigned long pfn;
694
695
696
697
698 FIXUP_MEMADDR_VGA(addr);
699
700
701
702
703 for (hose = hose_head; hose; hose = hose->next) {
704 if ((addr >> 32) == (hose->mem_space->start >> 32))
705 break;
706 }
707 if (!hose)
708 return NULL;
709
710
711
712
713 baddr = addr - hose->mem_space->start;
714 last = baddr + size - 1;
715
716
717
718
719 if ((baddr >= __direct_map_base) &&
720 ((baddr + size - 1) < __direct_map_base + __direct_map_size)) {
721 addr = IDENT_ADDR | (baddr - __direct_map_base);
722 return (void __iomem *) addr;
723 }
724
725
726
727
728 if (hose->sg_pci &&
729 baddr >= (unsigned long)hose->sg_pci->dma_base &&
730 last < (unsigned long)hose->sg_pci->dma_base + hose->sg_pci->size) {
731
732
733
734
735 baddr -= hose->sg_pci->dma_base;
736 last -= hose->sg_pci->dma_base;
737 baddr &= PAGE_MASK;
738 size = PAGE_ALIGN(last) - baddr;
739
740
741
742
743 area = get_vm_area(size, VM_IOREMAP);
744 if (!area)
745 return NULL;
746
747 ptes = hose->sg_pci->ptes;
748 for (vaddr = (unsigned long)area->addr;
749 baddr <= last;
750 baddr += PAGE_SIZE, vaddr += PAGE_SIZE) {
751 pfn = ptes[baddr >> PAGE_SHIFT];
752 if (!(pfn & 1)) {
753 printk("ioremap failed... pte not valid...\n");
754 vfree(area->addr);
755 return NULL;
756 }
757 pfn >>= 1;
758
759 if (__alpha_remap_area_pages(vaddr,
760 pfn << PAGE_SHIFT,
761 PAGE_SIZE, 0)) {
762 printk("FAILED to map...\n");
763 vfree(area->addr);
764 return NULL;
765 }
766 }
767
768 flush_tlb_all();
769
770 vaddr = (unsigned long)area->addr + (addr & ~PAGE_MASK);
771
772 return (void __iomem *) vaddr;
773 }
774
775
776 vaddr = baddr + hose->mem_space->start;
777 return (void __iomem *) vaddr;
778}
779
780void
781marvel_iounmap(volatile void __iomem *xaddr)
782{
783 unsigned long addr = (unsigned long) xaddr;
784 if (addr >= VMALLOC_START)
785 vfree((void *)(PAGE_MASK & addr));
786}
787
788int
789marvel_is_mmio(const volatile void __iomem *xaddr)
790{
791 unsigned long addr = (unsigned long) xaddr;
792
793 if (addr >= VMALLOC_START)
794 return 1;
795 else
796 return (addr & 0xFF000000UL) == 0;
797}
798
799#define __marvel_is_port_kbd(a) (((a) == 0x60) || ((a) == 0x64))
800#define __marvel_is_port_rtc(a) (((a) == 0x70) || ((a) == 0x71))
801
802void __iomem *marvel_ioportmap (unsigned long addr)
803{
804 FIXUP_IOADDR_VGA(addr);
805 return (void __iomem *)addr;
806}
807
808unsigned int
809marvel_ioread8(const void __iomem *xaddr)
810{
811 unsigned long addr = (unsigned long) xaddr;
812 if (__marvel_is_port_kbd(addr))
813 return 0;
814 else if (__marvel_is_port_rtc(addr))
815 return __marvel_rtc_io(0, addr, 0);
816 else if (marvel_is_ioaddr(addr))
817 return __kernel_ldbu(*(vucp)addr);
818 else
819
820
821
822
823 return ~0;
824}
825
826void
827marvel_iowrite8(u8 b, void __iomem *xaddr)
828{
829 unsigned long addr = (unsigned long) xaddr;
830 if (__marvel_is_port_kbd(addr))
831 return;
832 else if (__marvel_is_port_rtc(addr))
833 __marvel_rtc_io(b, addr, 1);
834 else if (marvel_is_ioaddr(addr))
835 __kernel_stb(b, *(vucp)addr);
836}
837
838#ifndef CONFIG_ALPHA_GENERIC
839EXPORT_SYMBOL(marvel_ioremap);
840EXPORT_SYMBOL(marvel_iounmap);
841EXPORT_SYMBOL(marvel_is_mmio);
842EXPORT_SYMBOL(marvel_ioportmap);
843EXPORT_SYMBOL(marvel_ioread8);
844EXPORT_SYMBOL(marvel_iowrite8);
845#endif
846
847
848
849
850
851
852
853
854
855int
856marvel_pa_to_nid(unsigned long pa)
857{
858 int cpuid;
859
860 if ((pa >> 43) & 1)
861 cpuid = (~(pa >> 35) & 0xff);
862 else
863 cpuid = ((pa >> 34) & 0x3) | ((pa >> (37 - 2)) & (0x1f << 2));
864
865 return marvel_cpuid_to_nid(cpuid);
866}
867
868int
869marvel_cpuid_to_nid(int cpuid)
870{
871 return cpuid;
872}
873
874unsigned long
875marvel_node_mem_start(int nid)
876{
877 unsigned long pa;
878
879 pa = (nid & 0x3) | ((nid & (0x1f << 2)) << 1);
880 pa <<= 34;
881
882 return pa;
883}
884
885unsigned long
886marvel_node_mem_size(int nid)
887{
888 return 16UL * 1024 * 1024 * 1024;
889}
890
891
892
893
894
895#include <linux/agp_backend.h>
896#include <asm/agp_backend.h>
897#include <linux/slab.h>
898#include <linux/delay.h>
899
900struct marvel_agp_aperture {
901 struct pci_iommu_arena *arena;
902 long pg_start;
903 long pg_count;
904};
905
906static int
907marvel_agp_setup(alpha_agp_info *agp)
908{
909 struct marvel_agp_aperture *aper;
910
911 if (!alpha_agpgart_size)
912 return -ENOMEM;
913
914 aper = kmalloc(sizeof(*aper), GFP_KERNEL);
915 if (aper == NULL) return -ENOMEM;
916
917 aper->arena = agp->hose->sg_pci;
918 aper->pg_count = alpha_agpgart_size / PAGE_SIZE;
919 aper->pg_start = iommu_reserve(aper->arena, aper->pg_count,
920 aper->pg_count - 1);
921
922 if (aper->pg_start < 0) {
923 printk(KERN_ERR "Failed to reserve AGP memory\n");
924 kfree(aper);
925 return -ENOMEM;
926 }
927
928 agp->aperture.bus_base =
929 aper->arena->dma_base + aper->pg_start * PAGE_SIZE;
930 agp->aperture.size = aper->pg_count * PAGE_SIZE;
931 agp->aperture.sysdata = aper;
932
933 return 0;
934}
935
936static void
937marvel_agp_cleanup(alpha_agp_info *agp)
938{
939 struct marvel_agp_aperture *aper = agp->aperture.sysdata;
940 int status;
941
942 status = iommu_release(aper->arena, aper->pg_start, aper->pg_count);
943 if (status == -EBUSY) {
944 printk(KERN_WARNING
945 "Attempted to release bound AGP memory - unbinding\n");
946 iommu_unbind(aper->arena, aper->pg_start, aper->pg_count);
947 status = iommu_release(aper->arena, aper->pg_start,
948 aper->pg_count);
949 }
950 if (status < 0)
951 printk(KERN_ERR "Failed to release AGP memory\n");
952
953 kfree(aper);
954 kfree(agp);
955}
956
957static int
958marvel_agp_configure(alpha_agp_info *agp)
959{
960 io7_ioport_csrs *csrs = ((struct io7_port *)agp->hose->sysdata)->csrs;
961 struct io7 *io7 = ((struct io7_port *)agp->hose->sysdata)->io7;
962 unsigned int new_rate = 0;
963 unsigned long agp_pll;
964
965
966
967
968
969
970 agp_pll = io7->csrs->POx_RST[IO7_AGP_PORT].csr;
971 switch(IO7_PLL_RNGB(agp_pll)) {
972 case 0x4:
973
974
975
976
977 if (agp->mode.bits.rate != 2)
978 new_rate = 2;
979 break;
980
981 case 0x6:
982
983
984
985
986 if (agp->mode.bits.rate == 2)
987 new_rate = 1;
988 break;
989
990 default:
991
992
993
994
995 printk("%s: unknown PLL setting RNGB=%lx (PLL6_CTL=%016lx)\n",
996 __func__, IO7_PLL_RNGB(agp_pll), agp_pll);
997 break;
998 }
999
1000
1001
1002
1003 if (new_rate) {
1004 printk("Requested AGP Rate %dX not compatible "
1005 "with PLL setting - using %dX\n",
1006 agp->mode.bits.rate,
1007 new_rate);
1008
1009 agp->mode.bits.rate = new_rate;
1010 }
1011
1012 printk("Enabling AGP on hose %d: %dX%s RQ %d\n",
1013 agp->hose->index, agp->mode.bits.rate,
1014 agp->mode.bits.sba ? " - SBA" : "", agp->mode.bits.rq);
1015
1016 csrs->AGP_CMD.csr = agp->mode.lw;
1017
1018 return 0;
1019}
1020
1021static int
1022marvel_agp_bind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *mem)
1023{
1024 struct marvel_agp_aperture *aper = agp->aperture.sysdata;
1025 return iommu_bind(aper->arena, aper->pg_start + pg_start,
1026 mem->page_count, mem->pages);
1027}
1028
1029static int
1030marvel_agp_unbind_memory(alpha_agp_info *agp, off_t pg_start, struct agp_memory *mem)
1031{
1032 struct marvel_agp_aperture *aper = agp->aperture.sysdata;
1033 return iommu_unbind(aper->arena, aper->pg_start + pg_start,
1034 mem->page_count);
1035}
1036
1037static unsigned long
1038marvel_agp_translate(alpha_agp_info *agp, dma_addr_t addr)
1039{
1040 struct marvel_agp_aperture *aper = agp->aperture.sysdata;
1041 unsigned long baddr = addr - aper->arena->dma_base;
1042 unsigned long pte;
1043
1044 if (addr < agp->aperture.bus_base ||
1045 addr >= agp->aperture.bus_base + agp->aperture.size) {
1046 printk("%s: addr out of range\n", __func__);
1047 return -EINVAL;
1048 }
1049
1050 pte = aper->arena->ptes[baddr >> PAGE_SHIFT];
1051 if (!(pte & 1)) {
1052 printk("%s: pte not valid\n", __func__);
1053 return -EINVAL;
1054 }
1055 return (pte >> 1) << PAGE_SHIFT;
1056}
1057
1058struct alpha_agp_ops marvel_agp_ops =
1059{
1060 .setup = marvel_agp_setup,
1061 .cleanup = marvel_agp_cleanup,
1062 .configure = marvel_agp_configure,
1063 .bind = marvel_agp_bind_memory,
1064 .unbind = marvel_agp_unbind_memory,
1065 .translate = marvel_agp_translate
1066};
1067
1068alpha_agp_info *
1069marvel_agp_info(void)
1070{
1071 struct pci_controller *hose;
1072 io7_ioport_csrs *csrs;
1073 alpha_agp_info *agp;
1074 struct io7 *io7;
1075
1076
1077
1078
1079
1080
1081
1082 hose = NULL;
1083 for (io7 = NULL; (io7 = marvel_next_io7(io7)) != NULL; ) {
1084 struct pci_controller *h;
1085 vuip addr;
1086
1087 if (!io7->ports[IO7_AGP_PORT].enabled)
1088 continue;
1089
1090 h = io7->ports[IO7_AGP_PORT].hose;
1091 addr = (vuip)build_conf_addr(h, 0, PCI_DEVFN(5, 0), 0);
1092
1093 if (*addr != 0xffffffffu) {
1094 hose = h;
1095 break;
1096 }
1097 }
1098
1099 if (!hose || !hose->sg_pci)
1100 return NULL;
1101
1102 printk("MARVEL - using hose %d as AGP\n", hose->index);
1103
1104
1105
1106
1107 csrs = ((struct io7_port *)hose->sysdata)->csrs;
1108
1109
1110
1111
1112 agp = kmalloc(sizeof(*agp), GFP_KERNEL);
1113 if (!agp)
1114 return NULL;
1115
1116
1117
1118
1119 agp->hose = hose;
1120 agp->private = NULL;
1121 agp->ops = &marvel_agp_ops;
1122
1123
1124
1125
1126 agp->aperture.bus_base = 0;
1127 agp->aperture.size = 0;
1128 agp->aperture.sysdata = NULL;
1129
1130
1131
1132
1133
1134
1135
1136
1137 agp->capability.lw = csrs->AGP_STAT.csr;
1138 agp->capability.bits.rq = 0xf;
1139
1140
1141
1142
1143 agp->mode.lw = csrs->AGP_CMD.csr;
1144
1145 return agp;
1146}
1147