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