1 /***********************************************************************
2  *
3  * Copyright 2001 MontaVista Software Inc.
4  * Author: jsun@mvista.com or jsun@junsun.net
5  *
6  * arch/mips/ddb5xxx/common/nile4.c
7  *     misc low-level routines for vrc-5xxx controllers.
8  *
9  * derived from original code by Geert Uytterhoeven <geert@sonycom.com>
10  *
11  * This program is free software; you can redistribute  it and/or modify it
12  * under  the terms of  the GNU General  Public License as published by the
13  * Free Software Foundation;  either version 2 of the  License, or (at your
14  * option) any later version.
15  *
16  ***********************************************************************
17  */
18 
19 #include <linux/types.h>
20 #include <linux/kernel.h>
21 
22 #include <asm/ddb5xxx/ddb5xxx.h>
23 
24 u32
ddb_calc_pdar(u32 phys,u32 size,int width,int on_memory_bus,int pci_visible)25 ddb_calc_pdar(u32 phys, u32 size, int width,
26 	      int on_memory_bus, int pci_visible)
27 {
28         u32 maskbits;
29         u32 widthbits;
30 
31         switch (size) {
32 #if 0                           /* We don't support 4 GB yet */
33         case 0x100000000:       /* 4 GB */
34                 maskbits = 4;
35                 break;
36 #endif
37         case 0x80000000:        /* 2 GB */
38                 maskbits = 5;
39                 break;
40         case 0x40000000:        /* 1 GB */
41                 maskbits = 6;
42                 break;
43         case 0x20000000:        /* 512 MB */
44                 maskbits = 7;
45                 break;
46         case 0x10000000:        /* 256 MB */
47                 maskbits = 8;
48                 break;
49         case 0x08000000:        /* 128 MB */
50                 maskbits = 9;
51                 break;
52         case 0x04000000:        /* 64 MB */
53                 maskbits = 10;
54                 break;
55         case 0x02000000:        /* 32 MB */
56                 maskbits = 11;
57                 break;
58         case 0x01000000:        /* 16 MB */
59                 maskbits = 12;
60                 break;
61         case 0x00800000:        /* 8 MB */
62                 maskbits = 13;
63                 break;
64         case 0x00400000:        /* 4 MB */
65                 maskbits = 14;
66                 break;
67         case 0x00200000:        /* 2 MB */
68                 maskbits = 15;
69                 break;
70         case 0:         /* OFF */
71                 maskbits = 0;
72                 break;
73         default:
74                 panic("nile4_set_pdar: unsupported size %p", (void *) size);
75         }
76         switch (width) {
77         case 8:
78                 widthbits = 0;
79                 break;
80         case 16:
81                 widthbits = 1;
82                 break;
83         case 32:
84                 widthbits = 2;
85                 break;
86         case 64:
87                 widthbits = 3;
88                 break;
89         default:
90                 panic("nile4_set_pdar: unsupported width %d", width);
91         }
92 
93 	return maskbits | (on_memory_bus ? 0x10 : 0) |
94 		(pci_visible ? 0x20 : 0) | (widthbits << 6) |
95 		(phys & 0xffe00000);
96 }
97 
98 void
ddb_set_pdar(u32 pdar,u32 phys,u32 size,int width,int on_memory_bus,int pci_visible)99 ddb_set_pdar(u32 pdar, u32 phys, u32 size, int width,
100 	     int on_memory_bus, int pci_visible)
101 {
102 	u32 temp= ddb_calc_pdar(phys, size, width, on_memory_bus, pci_visible);
103 	ddb_out32(pdar, temp);
104 	ddb_out32(pdar + 4, 0);
105 
106         /*
107          * When programming a PDAR, the register should be read immediately
108          * after writing it. This ensures that address decoders are properly
109          * configured.
110 	 * [jsun] is this really necesary?
111          */
112         ddb_in32(pdar);
113         ddb_in32(pdar + 4);
114 }
115 
116 /*
117  * routines that mess with PCIINITx registers
118  */
119 
ddb_set_pmr(u32 pmr,u32 type,u32 addr,u32 options)120 void ddb_set_pmr(u32 pmr, u32 type, u32 addr, u32 options)
121 {
122         switch (type) {
123         case DDB_PCICMD_IACK: /* PCI Interrupt Acknowledge */
124         case DDB_PCICMD_IO:   /* PCI I/O Space */
125         case DDB_PCICMD_MEM:  /* PCI Memory Space */
126         case DDB_PCICMD_CFG:  /* PCI Configuration Space */
127                 break;
128         default:
129                 panic("nile4_set_pmr: invalid type %d", type);
130         }
131         ddb_out32(pmr, (type << 1) | (addr & 0xffe00000) | options );
132         ddb_out32(pmr + 4, 0);
133 }
134