Path: blob/master/arch/ia64/sn/pci/pcibr/pcibr_reg.c
15133 views
/*1* This file is subject to the terms and conditions of the GNU General Public2* License. See the file "COPYING" in the main directory of this archive3* for more details.4*5* Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved.6*/78#include <linux/interrupt.h>9#include <linux/types.h>10#include <asm/sn/io.h>11#include <asm/sn/pcibr_provider.h>12#include <asm/sn/pcibus_provider_defs.h>13#include <asm/sn/pcidev.h>14#include <asm/sn/pic.h>15#include <asm/sn/tiocp.h>1617union br_ptr {18struct tiocp tio;19struct pic pic;20};2122/*23* Control Register Access -- Read/Write 0000_002024*/25void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, u64 bits)26{27union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;2829if (pcibus_info) {30switch (pcibus_info->pbi_bridge_type) {31case PCIBR_BRIDGETYPE_TIOCP:32__sn_clrq_relaxed(&ptr->tio.cp_control, bits);33break;34case PCIBR_BRIDGETYPE_PIC:35__sn_clrq_relaxed(&ptr->pic.p_wid_control, bits);36break;37default:38panic39("pcireg_control_bit_clr: unknown bridgetype bridge 0x%p",40ptr);41}42}43}4445void pcireg_control_bit_set(struct pcibus_info *pcibus_info, u64 bits)46{47union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;4849if (pcibus_info) {50switch (pcibus_info->pbi_bridge_type) {51case PCIBR_BRIDGETYPE_TIOCP:52__sn_setq_relaxed(&ptr->tio.cp_control, bits);53break;54case PCIBR_BRIDGETYPE_PIC:55__sn_setq_relaxed(&ptr->pic.p_wid_control, bits);56break;57default:58panic59("pcireg_control_bit_set: unknown bridgetype bridge 0x%p",60ptr);61}62}63}6465/*66* PCI/PCIX Target Flush Register Access -- Read Only 0000_005067*/68u64 pcireg_tflush_get(struct pcibus_info *pcibus_info)69{70union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;71u64 ret = 0;7273if (pcibus_info) {74switch (pcibus_info->pbi_bridge_type) {75case PCIBR_BRIDGETYPE_TIOCP:76ret = __sn_readq_relaxed(&ptr->tio.cp_tflush);77break;78case PCIBR_BRIDGETYPE_PIC:79ret = __sn_readq_relaxed(&ptr->pic.p_wid_tflush);80break;81default:82panic83("pcireg_tflush_get: unknown bridgetype bridge 0x%p",84ptr);85}86}8788/* Read of the Target Flush should always return zero */89if (ret != 0)90panic("pcireg_tflush_get:Target Flush failed\n");9192return ret;93}9495/*96* Interrupt Status Register Access -- Read Only 0000_010097*/98u64 pcireg_intr_status_get(struct pcibus_info * pcibus_info)99{100union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;101u64 ret = 0;102103if (pcibus_info) {104switch (pcibus_info->pbi_bridge_type) {105case PCIBR_BRIDGETYPE_TIOCP:106ret = __sn_readq_relaxed(&ptr->tio.cp_int_status);107break;108case PCIBR_BRIDGETYPE_PIC:109ret = __sn_readq_relaxed(&ptr->pic.p_int_status);110break;111default:112panic113("pcireg_intr_status_get: unknown bridgetype bridge 0x%p",114ptr);115}116}117return ret;118}119120/*121* Interrupt Enable Register Access -- Read/Write 0000_0108122*/123void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, u64 bits)124{125union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;126127if (pcibus_info) {128switch (pcibus_info->pbi_bridge_type) {129case PCIBR_BRIDGETYPE_TIOCP:130__sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits);131break;132case PCIBR_BRIDGETYPE_PIC:133__sn_clrq_relaxed(&ptr->pic.p_int_enable, bits);134break;135default:136panic137("pcireg_intr_enable_bit_clr: unknown bridgetype bridge 0x%p",138ptr);139}140}141}142143void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, u64 bits)144{145union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;146147if (pcibus_info) {148switch (pcibus_info->pbi_bridge_type) {149case PCIBR_BRIDGETYPE_TIOCP:150__sn_setq_relaxed(&ptr->tio.cp_int_enable, bits);151break;152case PCIBR_BRIDGETYPE_PIC:153__sn_setq_relaxed(&ptr->pic.p_int_enable, bits);154break;155default:156panic157("pcireg_intr_enable_bit_set: unknown bridgetype bridge 0x%p",158ptr);159}160}161}162163/*164* Intr Host Address Register (int_addr) -- Read/Write 0000_0130 - 0000_0168165*/166void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n,167u64 addr)168{169union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;170171if (pcibus_info) {172switch (pcibus_info->pbi_bridge_type) {173case PCIBR_BRIDGETYPE_TIOCP:174__sn_clrq_relaxed(&ptr->tio.cp_int_addr[int_n],175TIOCP_HOST_INTR_ADDR);176__sn_setq_relaxed(&ptr->tio.cp_int_addr[int_n],177(addr & TIOCP_HOST_INTR_ADDR));178break;179case PCIBR_BRIDGETYPE_PIC:180__sn_clrq_relaxed(&ptr->pic.p_int_addr[int_n],181PIC_HOST_INTR_ADDR);182__sn_setq_relaxed(&ptr->pic.p_int_addr[int_n],183(addr & PIC_HOST_INTR_ADDR));184break;185default:186panic187("pcireg_intr_addr_addr_get: unknown bridgetype bridge 0x%p",188ptr);189}190}191}192193/*194* Force Interrupt Register Access -- Write Only 0000_01C0 - 0000_01F8195*/196void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n)197{198union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;199200if (pcibus_info) {201switch (pcibus_info->pbi_bridge_type) {202case PCIBR_BRIDGETYPE_TIOCP:203writeq(1, &ptr->tio.cp_force_pin[int_n]);204break;205case PCIBR_BRIDGETYPE_PIC:206writeq(1, &ptr->pic.p_force_pin[int_n]);207break;208default:209panic210("pcireg_force_intr_set: unknown bridgetype bridge 0x%p",211ptr);212}213}214}215216/*217* Device(x) Write Buffer Flush Reg Access -- Read Only 0000_0240 - 0000_0258218*/219u64 pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device)220{221union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;222u64 ret = 0;223224if (pcibus_info) {225switch (pcibus_info->pbi_bridge_type) {226case PCIBR_BRIDGETYPE_TIOCP:227ret =228__sn_readq_relaxed(&ptr->tio.cp_wr_req_buf[device]);229break;230case PCIBR_BRIDGETYPE_PIC:231ret =232__sn_readq_relaxed(&ptr->pic.p_wr_req_buf[device]);233break;234default:235panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", ptr);236}237238}239/* Read of the Write Buffer Flush should always return zero */240return ret;241}242243void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index,244u64 val)245{246union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;247248if (pcibus_info) {249switch (pcibus_info->pbi_bridge_type) {250case PCIBR_BRIDGETYPE_TIOCP:251writeq(val, &ptr->tio.cp_int_ate_ram[ate_index]);252break;253case PCIBR_BRIDGETYPE_PIC:254writeq(val, &ptr->pic.p_int_ate_ram[ate_index]);255break;256default:257panic258("pcireg_int_ate_set: unknown bridgetype bridge 0x%p",259ptr);260}261}262}263264u64 __iomem *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index)265{266union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base;267u64 __iomem *ret = NULL;268269if (pcibus_info) {270switch (pcibus_info->pbi_bridge_type) {271case PCIBR_BRIDGETYPE_TIOCP:272ret = &ptr->tio.cp_int_ate_ram[ate_index];273break;274case PCIBR_BRIDGETYPE_PIC:275ret = &ptr->pic.p_int_ate_ram[ate_index];276break;277default:278panic279("pcireg_int_ate_addr: unknown bridgetype bridge 0x%p",280ptr);281}282}283return ret;284}285286287