Logo Search packages:      
Sourcecode: linux version File versions  Download package

pcibr_reg.c

/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved.
 */

#include <linux/interrupt.h>
#include <linux/types.h>
#include <asm/sn/io.h>
#include <asm/sn/pcibr_provider.h>
#include <asm/sn/pcibus_provider_defs.h>
#include <asm/sn/pcidev.h>
#include <asm/sn/pic.h>
#include <asm/sn/tiocp.h>

00018 union br_ptr {
      struct tiocp tio;
      struct pic pic;
};

/*
 * Control Register Access -- Read/Write                            0000_0020
 */
void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, u64 bits)
{
      union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;

      if (pcibus_info) {
            switch (pcibus_info->pbi_bridge_type) {
            case PCIBR_BRIDGETYPE_TIOCP:
                  __sn_clrq_relaxed(&ptr->tio.cp_control, bits);
                  break;
            case PCIBR_BRIDGETYPE_PIC:
                  __sn_clrq_relaxed(&ptr->pic.p_wid_control, bits);
                  break;
            default:
                  panic
                      ("pcireg_control_bit_clr: unknown bridgetype bridge 0x%p",
                       ptr);
            }
      }
}

void pcireg_control_bit_set(struct pcibus_info *pcibus_info, u64 bits)
{
      union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;

      if (pcibus_info) {
            switch (pcibus_info->pbi_bridge_type) {
            case PCIBR_BRIDGETYPE_TIOCP:
                  __sn_setq_relaxed(&ptr->tio.cp_control, bits);
                  break;
            case PCIBR_BRIDGETYPE_PIC:
                  __sn_setq_relaxed(&ptr->pic.p_wid_control, bits);
                  break;
            default:
                  panic
                      ("pcireg_control_bit_set: unknown bridgetype bridge 0x%p",
                       ptr);
            }
      }
}

/*
 * PCI/PCIX Target Flush Register Access -- Read Only           0000_0050
 */
u64 pcireg_tflush_get(struct pcibus_info *pcibus_info)
{
      union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
      u64 ret = 0;

      if (pcibus_info) {
            switch (pcibus_info->pbi_bridge_type) {
            case PCIBR_BRIDGETYPE_TIOCP:
                  ret = __sn_readq_relaxed(&ptr->tio.cp_tflush);
                  break;
            case PCIBR_BRIDGETYPE_PIC:
                  ret = __sn_readq_relaxed(&ptr->pic.p_wid_tflush);
                  break;
            default:
                  panic
                      ("pcireg_tflush_get: unknown bridgetype bridge 0x%p",
                       ptr);
            }
      }

      /* Read of the Target Flush should always return zero */
      if (ret != 0)
            panic("pcireg_tflush_get:Target Flush failed\n");

      return ret;
}

/*
 * Interrupt Status Register Access -- Read Only                0000_0100
 */
u64 pcireg_intr_status_get(struct pcibus_info * pcibus_info)
{
      union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
      u64 ret = 0;

      if (pcibus_info) {
            switch (pcibus_info->pbi_bridge_type) {
            case PCIBR_BRIDGETYPE_TIOCP:
                  ret = __sn_readq_relaxed(&ptr->tio.cp_int_status);
                  break;
            case PCIBR_BRIDGETYPE_PIC:
                  ret = __sn_readq_relaxed(&ptr->pic.p_int_status);
                  break;
            default:
                  panic
                      ("pcireg_intr_status_get: unknown bridgetype bridge 0x%p",
                       ptr);
            }
      }
      return ret;
}

/*
 * Interrupt Enable Register Access -- Read/Write                   0000_0108
 */
void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, u64 bits)
{
      union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;

      if (pcibus_info) {
            switch (pcibus_info->pbi_bridge_type) {
            case PCIBR_BRIDGETYPE_TIOCP:
                  __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits);
                  break;
            case PCIBR_BRIDGETYPE_PIC:
                  __sn_clrq_relaxed(&ptr->pic.p_int_enable, bits);
                  break;
            default:
                  panic
                      ("pcireg_intr_enable_bit_clr: unknown bridgetype bridge 0x%p",
                       ptr);
            }
      }
}

void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, u64 bits)
{
      union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;

      if (pcibus_info) {
            switch (pcibus_info->pbi_bridge_type) {
            case PCIBR_BRIDGETYPE_TIOCP:
                  __sn_setq_relaxed(&ptr->tio.cp_int_enable, bits);
                  break;
            case PCIBR_BRIDGETYPE_PIC:
                  __sn_setq_relaxed(&ptr->pic.p_int_enable, bits);
                  break;
            default:
                  panic
                      ("pcireg_intr_enable_bit_set: unknown bridgetype bridge 0x%p",
                       ptr);
            }
      }
}

/*
 * Intr Host Address Register (int_addr) -- Read/Write  0000_0130 - 0000_0168
 */
void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n,
                         u64 addr)
{
      union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;

      if (pcibus_info) {
            switch (pcibus_info->pbi_bridge_type) {
            case PCIBR_BRIDGETYPE_TIOCP:
                  __sn_clrq_relaxed(&ptr->tio.cp_int_addr[int_n],
                      TIOCP_HOST_INTR_ADDR);
                  __sn_setq_relaxed(&ptr->tio.cp_int_addr[int_n],
                      (addr & TIOCP_HOST_INTR_ADDR));
                  break;
            case PCIBR_BRIDGETYPE_PIC:
                  __sn_clrq_relaxed(&ptr->pic.p_int_addr[int_n],
                      PIC_HOST_INTR_ADDR);
                  __sn_setq_relaxed(&ptr->pic.p_int_addr[int_n],
                      (addr & PIC_HOST_INTR_ADDR));
                  break;
            default:
                  panic
                      ("pcireg_intr_addr_addr_get: unknown bridgetype bridge 0x%p",
                       ptr);
            }
      }
}

/*
 * Force Interrupt Register Access -- Write Only      0000_01C0 - 0000_01F8
 */
void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n)
{
      union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;

      if (pcibus_info) {
            switch (pcibus_info->pbi_bridge_type) {
            case PCIBR_BRIDGETYPE_TIOCP:
                  writeq(1, &ptr->tio.cp_force_pin[int_n]);
                  break;
            case PCIBR_BRIDGETYPE_PIC:
                  writeq(1, &ptr->pic.p_force_pin[int_n]);
                  break;
            default:
                  panic
                      ("pcireg_force_intr_set: unknown bridgetype bridge 0x%p",
                       ptr);
            }
      }
}

/*
 * Device(x) Write Buffer Flush Reg Access -- Read Only 0000_0240 - 0000_0258
 */
u64 pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device)
{
      union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
      u64 ret = 0;

      if (pcibus_info) {
            switch (pcibus_info->pbi_bridge_type) {
            case PCIBR_BRIDGETYPE_TIOCP:
                  ret =
                      __sn_readq_relaxed(&ptr->tio.cp_wr_req_buf[device]);
                  break;
            case PCIBR_BRIDGETYPE_PIC:
                  ret =
                      __sn_readq_relaxed(&ptr->pic.p_wr_req_buf[device]);
                  break;
            default:
                  panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", ptr);
            }

      }
      /* Read of the Write Buffer Flush should always return zero */
      return ret;
}

void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index,
                  u64 val)
{
      union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;

      if (pcibus_info) {
            switch (pcibus_info->pbi_bridge_type) {
            case PCIBR_BRIDGETYPE_TIOCP:
                  writeq(val, &ptr->tio.cp_int_ate_ram[ate_index]);
                  break;
            case PCIBR_BRIDGETYPE_PIC:
                  writeq(val, &ptr->pic.p_int_ate_ram[ate_index]);
                  break;
            default:
                  panic
                      ("pcireg_int_ate_set: unknown bridgetype bridge 0x%p",
                       ptr);
            }
      }
}

u64 __iomem *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index)
{
      union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;
      u64 __iomem *ret = NULL;

      if (pcibus_info) {
            switch (pcibus_info->pbi_bridge_type) {
            case PCIBR_BRIDGETYPE_TIOCP:
                  ret = &ptr->tio.cp_int_ate_ram[ate_index];
                  break;
            case PCIBR_BRIDGETYPE_PIC:
                  ret = &ptr->pic.p_int_ate_ram[ate_index];
                  break;
            default:
                  panic
                      ("pcireg_int_ate_addr: unknown bridgetype bridge 0x%p",
                       ptr);
            }
      }
      return ret;
}

Generated by  Doxygen 1.6.0   Back to index