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