1 // SPDX-License-Identifier: GPL-2.0-only
3 * HP Quicksilver AGP GART routines
5 * Copyright (c) 2006, Kyle McMartin <kyle@parisc-linux.org>
7 * Based on drivers/char/agpgart/hp-agp.c which is
8 * (c) Copyright 2002, 2003 Hewlett-Packard Development Company, L.P.
9 * Bjorn Helgaas <bjorn.helgaas@hp.com>
12 #include <linux/module.h>
13 #include <linux/pci.h>
14 #include <linux/init.h>
15 #include <linux/klist.h>
16 #include <linux/agp_backend.h>
17 #include <linux/log2.h>
18 #include <linux/slab.h>
20 #include <asm/parisc-device.h>
21 #include <asm/ropes.h>
25 #define DRVNAME "quicksilver"
26 #define DRVPFX DRVNAME ": "
28 #define AGP8X_MODE_BIT 3
29 #define AGP8X_MODE (1 << AGP8X_MODE_BIT)
32 parisc_agp_mask_memory(struct agp_bridge_data
*bridge
, dma_addr_t addr
,
35 static struct _parisc_agp_info
{
36 void __iomem
*ioc_regs
;
37 void __iomem
*lba_regs
;
48 int io_pages_per_kpage
;
51 static struct gatt_mask parisc_agp_masks
[] =
54 .mask
= SBA_PDIR_VALID_BIT
,
59 static struct aper_size_info_fixed parisc_agp_sizes
[] =
61 {0, 0, 0}, /* filled in by parisc_agp_fetch_size() */
65 parisc_agp_fetch_size(void)
69 size
= parisc_agp_info
.gart_size
/ MB(1);
70 parisc_agp_sizes
[0].size
= size
;
71 agp_bridge
->current_size
= (void *) &parisc_agp_sizes
[0];
77 parisc_agp_configure(void)
79 struct _parisc_agp_info
*info
= &parisc_agp_info
;
81 agp_bridge
->gart_bus_addr
= info
->gart_base
;
82 agp_bridge
->capndx
= info
->lba_cap_offset
;
83 agp_bridge
->mode
= readl(info
->lba_regs
+info
->lba_cap_offset
+PCI_AGP_STATUS
);
89 parisc_agp_tlbflush(struct agp_memory
*mem
)
91 struct _parisc_agp_info
*info
= &parisc_agp_info
;
93 /* force fdc ops to be visible to IOMMU */
96 writeq(info
->gart_base
| ilog2(info
->gart_size
), info
->ioc_regs
+IOC_PCOM
);
97 readq(info
->ioc_regs
+IOC_PCOM
); /* flush */
101 parisc_agp_create_gatt_table(struct agp_bridge_data
*bridge
)
103 struct _parisc_agp_info
*info
= &parisc_agp_info
;
106 for (i
= 0; i
< info
->gatt_entries
; i
++) {
107 info
->gatt
[i
] = cpu_to_le64(agp_bridge
->scratch_page
);
114 parisc_agp_free_gatt_table(struct agp_bridge_data
*bridge
)
116 struct _parisc_agp_info
*info
= &parisc_agp_info
;
118 info
->gatt
[0] = SBA_AGPGART_COOKIE
;
124 parisc_agp_insert_memory(struct agp_memory
*mem
, off_t pg_start
, int type
)
126 struct _parisc_agp_info
*info
= &parisc_agp_info
;
128 off_t j
, io_pg_start
;
131 if (type
!= mem
->type
||
132 agp_bridge
->driver
->agp_type_to_mask_type(agp_bridge
, type
)) {
136 io_pg_start
= info
->io_pages_per_kpage
* pg_start
;
137 io_pg_count
= info
->io_pages_per_kpage
* mem
->page_count
;
138 if ((io_pg_start
+ io_pg_count
) > info
->gatt_entries
) {
143 while (j
< (io_pg_start
+ io_pg_count
)) {
149 if (!mem
->is_flushed
) {
150 global_cache_flush();
151 mem
->is_flushed
= true;
154 for (i
= 0, j
= io_pg_start
; i
< mem
->page_count
; i
++) {
157 paddr
= page_to_phys(mem
->pages
[i
]);
159 k
< info
->io_pages_per_kpage
;
160 k
++, j
++, paddr
+= info
->io_page_size
) {
161 info
->gatt
[j
] = cpu_to_le64(
162 parisc_agp_mask_memory(agp_bridge
,
164 asm_io_fdc(&info
->gatt
[j
]);
168 agp_bridge
->driver
->tlb_flush(mem
);
174 parisc_agp_remove_memory(struct agp_memory
*mem
, off_t pg_start
, int type
)
176 struct _parisc_agp_info
*info
= &parisc_agp_info
;
177 int i
, io_pg_start
, io_pg_count
;
179 if (type
!= mem
->type
||
180 agp_bridge
->driver
->agp_type_to_mask_type(agp_bridge
, type
)) {
184 io_pg_start
= info
->io_pages_per_kpage
* pg_start
;
185 io_pg_count
= info
->io_pages_per_kpage
* mem
->page_count
;
186 for (i
= io_pg_start
; i
< io_pg_count
+ io_pg_start
; i
++) {
187 info
->gatt
[i
] = cpu_to_le64(agp_bridge
->scratch_page
);
190 agp_bridge
->driver
->tlb_flush(mem
);
195 parisc_agp_mask_memory(struct agp_bridge_data
*bridge
, dma_addr_t addr
,
198 unsigned ci
; /* coherent index */
201 pa
= addr
& IOVP_MASK
;
202 asm("lci 0(%1), %0" : "=r" (ci
) : "r" (phys_to_virt(pa
)));
204 pa
|= (ci
>> PAGE_SHIFT
) & 0xff;/* move CI (8 bits) into lowest byte */
205 pa
|= SBA_PDIR_VALID_BIT
; /* set "valid" bit */
207 /* return native (big-endian) PDIR entry */
212 parisc_agp_enable(struct agp_bridge_data
*bridge
, u32 mode
)
214 struct _parisc_agp_info
*info
= &parisc_agp_info
;
217 command
= readl(info
->lba_regs
+ info
->lba_cap_offset
+ PCI_AGP_STATUS
);
219 command
= agp_collect_device_status(bridge
, mode
, command
);
220 command
|= 0x00000100;
222 writel(command
, info
->lba_regs
+ info
->lba_cap_offset
+ PCI_AGP_COMMAND
);
224 agp_device_command(command
, (mode
& AGP8X_MODE
) != 0);
227 static const struct agp_bridge_driver parisc_agp_driver
= {
228 .owner
= THIS_MODULE
,
229 .size_type
= FIXED_APER_SIZE
,
230 .configure
= parisc_agp_configure
,
231 .fetch_size
= parisc_agp_fetch_size
,
232 .tlb_flush
= parisc_agp_tlbflush
,
233 .mask_memory
= parisc_agp_mask_memory
,
234 .masks
= parisc_agp_masks
,
235 .agp_enable
= parisc_agp_enable
,
236 .cache_flush
= global_cache_flush
,
237 .create_gatt_table
= parisc_agp_create_gatt_table
,
238 .free_gatt_table
= parisc_agp_free_gatt_table
,
239 .insert_memory
= parisc_agp_insert_memory
,
240 .remove_memory
= parisc_agp_remove_memory
,
241 .alloc_by_type
= agp_generic_alloc_by_type
,
242 .free_by_type
= agp_generic_free_by_type
,
243 .agp_alloc_page
= agp_generic_alloc_page
,
244 .agp_alloc_pages
= agp_generic_alloc_pages
,
245 .agp_destroy_page
= agp_generic_destroy_page
,
246 .agp_destroy_pages
= agp_generic_destroy_pages
,
247 .agp_type_to_mask_type
= agp_generic_type_to_mask_type
,
248 .cant_use_aperture
= true,
252 agp_ioc_init(void __iomem
*ioc_regs
)
254 struct _parisc_agp_info
*info
= &parisc_agp_info
;
255 u64 iova_base
, io_tlb_ps
;
259 printk(KERN_INFO DRVPFX
"IO PDIR shared with sba_iommu\n");
261 info
->ioc_regs
= ioc_regs
;
263 io_tlb_ps
= readq(info
->ioc_regs
+IOC_TCNFG
);
265 case 0: io_tlb_shift
= 12; break;
266 case 1: io_tlb_shift
= 13; break;
267 case 2: io_tlb_shift
= 14; break;
268 case 3: io_tlb_shift
= 16; break;
270 printk(KERN_ERR DRVPFX
"Invalid IOTLB page size "
271 "configuration 0x%llx\n", io_tlb_ps
);
273 info
->gatt_entries
= 0;
276 info
->io_page_size
= 1 << io_tlb_shift
;
277 info
->io_pages_per_kpage
= PAGE_SIZE
/ info
->io_page_size
;
279 iova_base
= readq(info
->ioc_regs
+IOC_IBASE
) & ~0x1;
280 info
->gart_base
= iova_base
+ PLUTO_IOVA_SIZE
- PLUTO_GART_SIZE
;
282 info
->gart_size
= PLUTO_GART_SIZE
;
283 info
->gatt_entries
= info
->gart_size
/ info
->io_page_size
;
285 io_pdir
= phys_to_virt(readq(info
->ioc_regs
+IOC_PDIR_BASE
));
286 info
->gatt
= &io_pdir
[(PLUTO_IOVA_SIZE
/2) >> PAGE_SHIFT
];
288 if (info
->gatt
[0] != SBA_AGPGART_COOKIE
) {
290 info
->gatt_entries
= 0;
291 printk(KERN_ERR DRVPFX
"No reserved IO PDIR entry found; "
300 lba_find_capability(int cap
)
302 struct _parisc_agp_info
*info
= &parisc_agp_info
;
307 status
= readw(info
->lba_regs
+ PCI_STATUS
);
308 if (!(status
& PCI_STATUS_CAP_LIST
))
310 pos
= readb(info
->lba_regs
+ PCI_CAPABILITY_LIST
);
311 while (ttl
-- && pos
>= 0x40) {
313 id
= readb(info
->lba_regs
+ pos
+ PCI_CAP_LIST_ID
);
318 pos
= readb(info
->lba_regs
+ pos
+ PCI_CAP_LIST_NEXT
);
324 agp_lba_init(void __iomem
*lba_hpa
)
326 struct _parisc_agp_info
*info
= &parisc_agp_info
;
329 info
->lba_regs
= lba_hpa
;
330 info
->lba_cap_offset
= lba_find_capability(PCI_CAP_ID_AGP
);
332 cap
= readl(lba_hpa
+ info
->lba_cap_offset
) & 0xff;
333 if (cap
!= PCI_CAP_ID_AGP
) {
334 printk(KERN_ERR DRVPFX
"Invalid capability ID 0x%02x at 0x%x\n",
335 cap
, info
->lba_cap_offset
);
343 parisc_agp_setup(void __iomem
*ioc_hpa
, void __iomem
*lba_hpa
)
345 struct pci_dev
*fake_bridge_dev
= NULL
;
346 struct agp_bridge_data
*bridge
;
349 fake_bridge_dev
= pci_alloc_dev(NULL
);
350 if (!fake_bridge_dev
) {
355 error
= agp_ioc_init(ioc_hpa
);
359 error
= agp_lba_init(lba_hpa
);
363 bridge
= agp_alloc_bridge();
368 bridge
->driver
= &parisc_agp_driver
;
370 fake_bridge_dev
->vendor
= PCI_VENDOR_ID_HP
;
371 fake_bridge_dev
->device
= PCI_DEVICE_ID_HP_PCIX_LBA
;
372 bridge
->dev
= fake_bridge_dev
;
374 error
= agp_add_bridge(bridge
);
380 kfree(fake_bridge_dev
);
385 find_quicksilver(struct device
*dev
, void *data
)
387 struct parisc_device
**lba
= data
;
388 struct parisc_device
*padev
= to_parisc_device(dev
);
390 if (IS_QUICKSILVER(padev
))
397 parisc_agp_init(void)
400 struct parisc_device
*sba
= NULL
, *lba
= NULL
;
401 struct lba_device
*lbadev
= NULL
;
406 /* Find our parent Pluto */
408 if (!IS_PLUTO(sba
)) {
409 printk(KERN_INFO DRVPFX
"No Pluto found, so no AGPGART for you.\n");
413 /* Now search our Pluto for our precious AGP device... */
414 device_for_each_child(&sba
->dev
, &lba
, find_quicksilver
);
417 printk(KERN_INFO DRVPFX
"No AGP devices found.\n");
421 lbadev
= parisc_get_drvdata(lba
);
423 /* w00t, let's go find our cookies... */
424 parisc_agp_setup(sba_list
->ioc
[0].ioc_hpa
, lbadev
->hba
.base_addr
);
432 module_init(parisc_agp_init
);
434 MODULE_AUTHOR("Kyle McMartin <kyle@parisc-linux.org>");
435 MODULE_DESCRIPTION("HP Quicksilver AGP GART routines");
436 MODULE_LICENSE("GPL");