core_irongate.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:15k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * linux/arch/alpha/kernel/core_irongate.c
  3.  *
  4.  * Based on code written by David A. Rusling (david.rusling@reo.mts.dec.com).
  5.  *
  6.  * Copyright (C) 1999 Alpha Processor, Inc.,
  7.  * (David Daniel, Stig Telfer, Soohoon Lee)
  8.  *
  9.  * Code common to all IRONGATE core logic chips.
  10.  */
  11. #include <linux/kernel.h>
  12. #include <linux/types.h>
  13. #include <linux/pci.h>
  14. #include <linux/sched.h>
  15. #include <linux/init.h>
  16. #include <asm/ptrace.h>
  17. #include <asm/system.h>
  18. #include <asm/pci.h>
  19. #include <asm/hwrpb.h>
  20. #define __EXTERN_INLINE inline
  21. #include <asm/io.h>
  22. #include <asm/core_irongate.h>
  23. #undef __EXTERN_INLINE
  24. #include "proto.h"
  25. #include "pci_impl.h"
  26. #undef DEBUG_IRONGATE  /* define to enable verbose Irongate debug */
  27. #define IRONGATE_DEFAULT_AGP_APER_SIZE (256*1024*1024) /* 256MB */
  28. /*
  29.  * BIOS32-style PCI interface:
  30.  */
  31. #define DEBUG_CONFIG 0
  32. #if DEBUG_CONFIG
  33. # define DBG_CFG(args) printk args
  34. #else
  35. # define DBG_CFG(args)
  36. #endif
  37. /*
  38.  * Given a bus, device, and function number, compute resulting
  39.  * configuration space address accordingly.  It is therefore not safe
  40.  * to have concurrent invocations to configuration space access
  41.  * routines, but there really shouldn't be any need for this.
  42.  *
  43.  * addr[31:24] reserved
  44.  * addr[23:16] bus number (8 bits = 128 possible buses)
  45.  * addr[15:11] Device number (5 bits)
  46.  * addr[10: 8] function number
  47.  * addr[ 7: 2] register number
  48.  *
  49.  * For IRONGATE:
  50.  *    if (bus = addr[23:16]) == 0
  51.  *    then
  52.  *   type 0 config cycle:
  53.  *       addr_on_pci[31:11] = id selection for device = addr[15:11]
  54.  *       addr_on_pci[10: 2] = addr[10: 2] ???
  55.  *       addr_on_pci[ 1: 0] = 00
  56.  *    else
  57.  *   type 1 config cycle (pass on with no decoding):
  58.  *       addr_on_pci[31:24] = 0
  59.  *       addr_on_pci[23: 2] = addr[23: 2]
  60.  *       addr_on_pci[ 1: 0] = 01
  61.  *    fi
  62.  *
  63.  * Notes:
  64.  * The function number selects which function of a multi-function device
  65.  * (e.g., SCSI and Ethernet).
  66.  *
  67.  * The register selects a DWORD (32 bit) register offset. Hence it
  68.  * doesn't get shifted by 2 bits as we want to "drop" the bottom two
  69.  * bits.
  70.  */
  71. static int
  72. mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
  73.      unsigned char *type1)
  74. {
  75. unsigned long addr;
  76. u8 bus = dev->bus->number;
  77. u8 device_fn = dev->devfn;
  78. DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
  79.  "pci_addr=0x%p, type1=0x%p)n",
  80.  bus, device_fn, where, pci_addr, type1));
  81. *type1 = (bus != 0);
  82. addr = (bus << 16) | (device_fn << 8) | where;
  83. addr |= IRONGATE_CONF;
  84. *pci_addr = addr;
  85. DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lxn", addr));
  86. return 0;
  87. }
  88. static int
  89. irongate_read_config_byte(struct pci_dev *dev, int where, u8 *value)
  90. {
  91. unsigned long addr;
  92. unsigned char type1;
  93. if (mk_conf_addr(dev, where, &addr, &type1))
  94. return PCIBIOS_DEVICE_NOT_FOUND;
  95. *value = __kernel_ldbu(*(vucp)addr);
  96. return PCIBIOS_SUCCESSFUL;
  97. }
  98. static int
  99. irongate_read_config_word(struct pci_dev *dev, int where, u16 *value)
  100. {
  101. unsigned long addr;
  102. unsigned char type1;
  103. if (mk_conf_addr(dev, where, &addr, &type1))
  104. return PCIBIOS_DEVICE_NOT_FOUND;
  105. *value = __kernel_ldwu(*(vusp)addr);
  106. return PCIBIOS_SUCCESSFUL;
  107. }
  108. static int
  109. irongate_read_config_dword(struct pci_dev *dev, int where, u32 *value)
  110. {
  111. unsigned long addr;
  112. unsigned char type1;
  113. if (mk_conf_addr(dev, where, &addr, &type1))
  114. return PCIBIOS_DEVICE_NOT_FOUND;
  115. *value = *(vuip)addr;
  116. return PCIBIOS_SUCCESSFUL;
  117. }
  118. static int
  119. irongate_write_config_byte(struct pci_dev *dev, int where, u8 value)
  120. {
  121. unsigned long addr;
  122. unsigned char type1;
  123. if (mk_conf_addr(dev, where, &addr, &type1))
  124. return PCIBIOS_DEVICE_NOT_FOUND;
  125. __kernel_stb(value, *(vucp)addr);
  126. mb();
  127. __kernel_ldbu(*(vucp)addr);
  128. return PCIBIOS_SUCCESSFUL;
  129. }
  130. static int
  131. irongate_write_config_word(struct pci_dev *dev, int where, u16 value)
  132. {
  133. unsigned long addr;
  134. unsigned char type1;
  135. if (mk_conf_addr(dev, where, &addr, &type1))
  136. return PCIBIOS_DEVICE_NOT_FOUND;
  137. __kernel_stw(value, *(vusp)addr);
  138. mb();
  139. __kernel_ldwu(*(vusp)addr);
  140. return PCIBIOS_SUCCESSFUL;
  141. }
  142. static int
  143. irongate_write_config_dword(struct pci_dev *dev, int where, u32 value)
  144. {
  145. unsigned long addr;
  146. unsigned char type1;
  147. if (mk_conf_addr(dev, where, &addr, &type1))
  148. return PCIBIOS_DEVICE_NOT_FOUND;
  149. *(vuip)addr = value;
  150. mb();
  151. *(vuip)addr;
  152. return PCIBIOS_SUCCESSFUL;
  153. }
  154. struct pci_ops irongate_pci_ops =
  155. {
  156. read_byte: irongate_read_config_byte,
  157. read_word: irongate_read_config_word,
  158. read_dword: irongate_read_config_dword,
  159. write_byte: irongate_write_config_byte,
  160. write_word: irongate_write_config_word,
  161. write_dword: irongate_write_config_dword
  162. };
  163. #ifdef DEBUG_IRONGATE
  164. static void
  165. irongate_register_dump(const char *function_name)
  166. {
  167. printk("%s: Irongate registers:n"
  168.        "tFunction 0:n"
  169.        "tdev_vendort0x%08xn"
  170.        "tstat_cmdt0x%08xn"
  171.        "tclasstt0x%08xn"
  172.        "tlatencytt0x%08xn"
  173.        "tbar0tt0x%08xn"
  174.        "tbar1tt0x%08xn"
  175.        "tbar2tt0x%08xn"
  176.        "trsrvd0[0]t0x%08xn"
  177.        "trsrvd0[1]t0x%08xn"
  178.        "trsrvd0[2]t0x%08xn"
  179.        "trsrvd0[3]t0x%08xn"
  180.        "trsrvd0[4]t0x%08xn"
  181.        "trsrvd0[5]t0x%08xn"
  182.        "tcapptrtt0x%08xn"
  183.        "trsrvd1[0]t0x%08xn"
  184.        "trsrvd1[1]t0x%08xn"
  185.        "tbacsr10tt0x%08xn"
  186.        "tbacsr32tt0x%08xn"
  187.        "tbacsr54tt0x%08xn"
  188.        "trsrvd2[0]t0x%08xn"
  189.        "tdrammaptt0x%08xn"
  190.        "tdramtmtt0x%08xn"
  191.        "tdrammstt0x%08xn"
  192.        "trsrvd3[0]t0x%08xn"
  193.        "tbiu0tt0x%08xn"
  194.        "tbiusiptt0x%08xn"
  195.        "trsrvd4[0]t0x%08xn"
  196.        "trsrvd4[1]t0x%08xn"
  197.        "tmrott0x%08xn"
  198.        "trsrvd5[0]t0x%08xn"
  199.        "trsrvd5[1]t0x%08xn"
  200.        "trsrvd5[2]t0x%08xn"
  201.        "twhamitt0x%08xn"
  202.        "tpciarbtt0x%08xn"
  203.        "tpcicfgtt0x%08xn"
  204.        "trsrvd6[0]t0x%08xn"
  205.        "trsrvd6[1]t0x%08xn"
  206.        "trsrvd6[2]t0x%08xn"
  207.        "trsrvd6[3]t0x%08xn"
  208.        "trsrvd6[4]t0x%08xn"
  209.        "tagpcaptt0x%08xn"
  210.        "tagpstattt0x%08xn"
  211.        "tagpcmdtt0x%08xn"
  212.        "tagpvatt0x%08xn"
  213.        "tagpmodett0x%08xn"
  214.        "ntFunction 1:n"
  215.        "tdev_vendor:t0x%08xn"
  216.        "tcmd_status:t0x%08xn"
  217.        "trevid_etc :t0x%08xn"
  218.        "thtype_etc :t0x%08xn"
  219.        "trsrvd0[0] :t0x%08xn"
  220.        "trsrvd0[1] :t0x%08xn"
  221.        "tbus_nmbers:t0x%08xn"
  222.        "tio_baselim:t0x%08xn"
  223.        "tmem_bselim:t0x%08xn"
  224.        "tpf_baselib:t0x%08xn"
  225.        "trsrvd1[0] :t0x%08xn"
  226.        "trsrvd1[1] :t0x%08xn"
  227.        "tio_baselim:t0x%08xn"
  228.        "trsrvd2[0] :t0x%08xn"
  229.        "trsrvd2[1] :t0x%08xn"
  230.        "tinterrupt :t0x%08xn",
  231.        function_name,
  232.        IRONGATE0->dev_vendor,
  233.        IRONGATE0->stat_cmd,
  234.        IRONGATE0->class,
  235.        IRONGATE0->latency,
  236.        IRONGATE0->bar0,
  237.        IRONGATE0->bar1,
  238.        IRONGATE0->bar2,
  239.        IRONGATE0->rsrvd0[0],
  240.        IRONGATE0->rsrvd0[1],
  241.        IRONGATE0->rsrvd0[2],
  242.        IRONGATE0->rsrvd0[3],
  243.        IRONGATE0->rsrvd0[4],
  244.        IRONGATE0->rsrvd0[5],
  245.        IRONGATE0->capptr,
  246.        IRONGATE0->rsrvd1[0],
  247.        IRONGATE0->rsrvd1[1],
  248.        IRONGATE0->bacsr10,
  249.        IRONGATE0->bacsr32,
  250.        IRONGATE0->bacsr54,
  251.        IRONGATE0->rsrvd2[0],
  252.        IRONGATE0->drammap,
  253.        IRONGATE0->dramtm,
  254.        IRONGATE0->dramms,
  255.        IRONGATE0->rsrvd3[0],
  256.        IRONGATE0->biu0,
  257.        IRONGATE0->biusip,
  258.        IRONGATE0->rsrvd4[0],
  259.        IRONGATE0->rsrvd4[1],
  260.        IRONGATE0->mro,
  261.        IRONGATE0->rsrvd5[0],
  262.        IRONGATE0->rsrvd5[1],
  263.        IRONGATE0->rsrvd5[2],
  264.        IRONGATE0->whami,
  265.        IRONGATE0->pciarb,
  266.        IRONGATE0->pcicfg,
  267.        IRONGATE0->rsrvd6[0],
  268.        IRONGATE0->rsrvd6[1],
  269.        IRONGATE0->rsrvd6[2],
  270.        IRONGATE0->rsrvd6[3],
  271.        IRONGATE0->rsrvd6[4],
  272.        IRONGATE0->agpcap,
  273.        IRONGATE0->agpstat,
  274.        IRONGATE0->agpcmd,
  275.        IRONGATE0->agpva,
  276.        IRONGATE0->agpmode,
  277.        IRONGATE1->dev_vendor,
  278.        IRONGATE1->stat_cmd,
  279.        IRONGATE1->class,
  280.        IRONGATE1->htype,
  281.        IRONGATE1->rsrvd0[0],
  282.        IRONGATE1->rsrvd0[1],
  283.        IRONGATE1->busnos,
  284.        IRONGATE1->io_baselim_regs,
  285.        IRONGATE1->mem_baselim,
  286.        IRONGATE1->pfmem_baselim,
  287.        IRONGATE1->rsrvd1[0],
  288.        IRONGATE1->rsrvd1[1],
  289.        IRONGATE1->io_baselim,
  290.        IRONGATE1->rsrvd2[0],
  291.        IRONGATE1->rsrvd2[1],
  292.        IRONGATE1->interrupt );
  293. }
  294. #else
  295. #define irongate_register_dump(x)
  296. #endif
  297. int
  298. irongate_pci_clr_err(void)
  299. {
  300. unsigned int nmi_ctl=0;
  301. unsigned int IRONGATE_jd;
  302. again:
  303. IRONGATE_jd = IRONGATE0->stat_cmd;
  304. printk("Iron stat_cmd %xn", IRONGATE_jd);
  305. IRONGATE0->stat_cmd = IRONGATE_jd; /* write again clears error bits */
  306. mb();
  307. IRONGATE_jd = IRONGATE0->stat_cmd;  /* re-read to force write */
  308. IRONGATE_jd = IRONGATE0->dramms;
  309. printk("Iron dramms %xn", IRONGATE_jd);
  310. IRONGATE0->dramms = IRONGATE_jd; /* write again clears error bits */
  311. mb();
  312. IRONGATE_jd = IRONGATE0->dramms;  /* re-read to force write */
  313. /* Clear ALI NMI */
  314.         nmi_ctl = inb(0x61);
  315.         nmi_ctl |= 0x0c;
  316.         outb(nmi_ctl, 0x61);
  317.         nmi_ctl &= ~0x0c;
  318.         outb(nmi_ctl, 0x61);
  319. IRONGATE_jd = IRONGATE0->dramms;
  320. if (IRONGATE_jd & 0x300) goto again;
  321. return 0;
  322. }
  323. void __init
  324. irongate_init_arch(void)
  325. {
  326. struct pci_controller *hose;
  327. IRONGATE0->stat_cmd = IRONGATE0->stat_cmd & ~0x100;
  328. irongate_pci_clr_err();
  329. irongate_register_dump(__FUNCTION__);
  330. /*
  331.  * HACK: set AGP aperture size to 256MB.
  332.  * This should really be changed during PCI probe, when the
  333.  * size of the aperture the AGP card wants is known.
  334.  */
  335. printk("irongate_init_arch: AGPVA was 0x%xn", IRONGATE0->agpva);
  336. IRONGATE0->agpva = (IRONGATE0->agpva & ~0x0000000f) | 0x00000007;
  337. /*
  338.  * Create our single hose.
  339.  */
  340. pci_isa_hose = hose = alloc_pci_controller();
  341. hose->io_space = &ioport_resource;
  342. hose->mem_space = &iomem_resource;
  343. hose->index = 0;
  344. /* This is for userland consumption.  For some reason, the 40-bit
  345.    PIO bias that we use in the kernel through KSEG didn't work for
  346.    the page table based user mappings.  So make sure we get the
  347.    43-bit PIO bias.  */
  348. hose->sparse_mem_base = 0;
  349. hose->sparse_io_base = 0;
  350. hose->dense_mem_base
  351.   = (IRONGATE_MEM & 0xffffffffff) | 0x80000000000;
  352. hose->dense_io_base
  353.   = (IRONGATE_IO & 0xffffffffff) | 0x80000000000;
  354. hose->sg_isa = hose->sg_pci = NULL;
  355. __direct_map_base = 0;
  356. __direct_map_size = 0xffffffff;
  357. }
  358. /*
  359.  * IO map and AGP support
  360.  */
  361. #include <linux/vmalloc.h>
  362. #include <asm/pgalloc.h>
  363. static inline void 
  364. irongate_remap_area_pte(pte_t * pte, unsigned long address, unsigned long size, 
  365.      unsigned long phys_addr, unsigned long flags)
  366. {
  367. unsigned long end;
  368. address &= ~PMD_MASK;
  369. end = address + size;
  370. if (end > PMD_SIZE)
  371. end = PMD_SIZE;
  372. if (address >= end)
  373. BUG();
  374. do {
  375. if (!pte_none(*pte)) {
  376. printk("irongate_remap_area_pte: page already existsn");
  377. BUG();
  378. }
  379. set_pte(pte, 
  380. mk_pte_phys(phys_addr, 
  381.     __pgprot(_PAGE_VALID | _PAGE_ASM | 
  382.      _PAGE_KRE | _PAGE_KWE | flags)));
  383. address += PAGE_SIZE;
  384. phys_addr += PAGE_SIZE;
  385. pte++;
  386. } while (address && (address < end));
  387. }
  388. static inline int 
  389. irongate_remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, 
  390.      unsigned long phys_addr, unsigned long flags)
  391. {
  392. unsigned long end;
  393. address &= ~PGDIR_MASK;
  394. end = address + size;
  395. if (end > PGDIR_SIZE)
  396. end = PGDIR_SIZE;
  397. phys_addr -= address;
  398. if (address >= end)
  399. BUG();
  400. do {
  401. pte_t * pte = pte_alloc(&init_mm, pmd, address);
  402. if (!pte)
  403. return -ENOMEM;
  404. irongate_remap_area_pte(pte, address, end - address, 
  405.      address + phys_addr, flags);
  406. address = (address + PMD_SIZE) & PMD_MASK;
  407. pmd++;
  408. } while (address && (address < end));
  409. return 0;
  410. }
  411. static int
  412. irongate_remap_area_pages(unsigned long address, unsigned long phys_addr,
  413.        unsigned long size, unsigned long flags)
  414. {
  415. pgd_t * dir;
  416. unsigned long end = address + size;
  417. phys_addr -= address;
  418. dir = pgd_offset(&init_mm, address);
  419. flush_cache_all();
  420. if (address >= end)
  421. BUG();
  422. do {
  423. pmd_t *pmd;
  424. pmd = pmd_alloc(&init_mm, dir, address);
  425. if (!pmd)
  426. return -ENOMEM;
  427. if (irongate_remap_area_pmd(pmd, address, end - address,
  428.  phys_addr + address, flags))
  429. return -ENOMEM;
  430. address = (address + PGDIR_SIZE) & PGDIR_MASK;
  431. dir++;
  432. } while (address && (address < end));
  433. return 0;
  434. }
  435. #include <linux/agp_backend.h>
  436. #include <linux/agpgart.h>
  437. #define GET_PAGE_DIR_OFF(addr) (addr >> 22)
  438. #define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr))
  439. #define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12) 
  440. #define GET_GATT(addr) (gatt_pages[GET_PAGE_DIR_IDX(addr)])
  441. unsigned long
  442. irongate_ioremap(unsigned long addr, unsigned long size)
  443. {
  444. struct vm_struct *area;
  445. unsigned long vaddr;
  446. unsigned long baddr, last;
  447. u32 *mmio_regs, *gatt_pages, *cur_gatt, pte;
  448. unsigned long gart_bus_addr, gart_aper_size;
  449. gart_bus_addr = (unsigned long)IRONGATE0->bar0 &
  450. PCI_BASE_ADDRESS_MEM_MASK; 
  451. if (!gart_bus_addr) /* FIXME - there must be a better way!!! */
  452. return addr + IRONGATE_MEM;
  453. gart_aper_size = IRONGATE_DEFAULT_AGP_APER_SIZE; /* FIXME */
  454. /* 
  455.  * Check for within the AGP aperture...
  456.  */
  457. do {
  458. /*
  459.  * Check the AGP area
  460.  */
  461. if (addr >= gart_bus_addr && addr + size - 1 < 
  462.     gart_bus_addr + gart_aper_size)
  463. break;
  464. /*
  465.  * Not found - assume legacy ioremap
  466.  */
  467. return addr + IRONGATE_MEM;
  468. } while(0);
  469. mmio_regs = (u32 *)(((unsigned long)IRONGATE0->bar1 &
  470. PCI_BASE_ADDRESS_MEM_MASK) + IRONGATE_MEM);
  471. gatt_pages = (u32 *)(phys_to_virt(mmio_regs[1])); /* FIXME */
  472. /*
  473.  * Adjust the limits (mappings must be page aligned)
  474.  */
  475. if (addr & ~PAGE_MASK) {
  476. printk("AGP ioremap failed... addr not page aligned (0x%lx)n",
  477.        addr);
  478. return addr + IRONGATE_MEM;
  479. }
  480. last = addr + size - 1;
  481. size = PAGE_ALIGN(last) - addr;
  482. #if 0
  483. printk("irongate_ioremap(0x%lx, 0x%lx)n", addr, size);
  484. printk("irongate_ioremap:  gart_bus_addr  0x%lxn", gart_bus_addr);
  485. printk("irongate_ioremap:  gart_aper_size 0x%lxn", gart_aper_size);
  486. printk("irongate_ioremap:  mmio_regs      %pn", mmio_regs);
  487. printk("irongate_ioremap:  gatt_pages     %pn", gatt_pages);
  488. for(baddr = addr; baddr <= last; baddr += PAGE_SIZE)
  489. {
  490. cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1);
  491. pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1;
  492. printk("irongate_ioremap:  cur_gatt %p pte 0x%xn",
  493.        cur_gatt, pte);
  494. }
  495. #endif
  496. /*
  497.  * Map it
  498.  */
  499. area = get_vm_area(size, VM_IOREMAP);
  500. if (!area) return (unsigned long)NULL;
  501. for(baddr = addr, vaddr = (unsigned long)area->addr; 
  502.     baddr <= last; 
  503.     baddr += PAGE_SIZE, vaddr += PAGE_SIZE)
  504. {
  505. cur_gatt = phys_to_virt(GET_GATT(baddr) & ~1);
  506. pte = cur_gatt[GET_GATT_OFF(baddr)] & ~1;
  507. if (irongate_remap_area_pages(VMALLOC_VMADDR(vaddr), 
  508.    pte, PAGE_SIZE, 0)) {
  509. printk("AGP ioremap: FAILED to map...n");
  510. vfree(area->addr);
  511. return (unsigned long)NULL;
  512. }
  513. }
  514. flush_tlb_all();
  515. vaddr = (unsigned long)area->addr + (addr & ~PAGE_MASK);
  516. #if 0
  517. printk("irongate_ioremap(0x%lx, 0x%lx) returning 0x%lxn",
  518.        addr, size, vaddr);
  519. #endif
  520. return vaddr;
  521. }
  522. void
  523. irongate_iounmap(unsigned long addr)
  524. {
  525. if (((long)addr >> 41) == -2)
  526. return; /* kseg map, nothing to do */
  527. if (addr) return vfree((void *)(PAGE_MASK & addr)); 
  528. }