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