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