Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is provided under a dual BSD/GPLv2 license.  When using or
0003  *   redistributing this file, you may do so under either license.
0004  *
0005  *   GPL LICENSE SUMMARY
0006  *
0007  *   Copyright (C) 2016 Advanced Micro Devices, Inc. All Rights Reserved.
0008  *
0009  *   This program is free software; you can redistribute it and/or modify
0010  *   it under the terms of version 2 of the GNU General Public License as
0011  *   published by the Free Software Foundation.
0012  *
0013  *   BSD LICENSE
0014  *
0015  *   Copyright (C) 2016 Advanced Micro Devices, Inc. All Rights Reserved.
0016  *
0017  *   Redistribution and use in source and binary forms, with or without
0018  *   modification, are permitted provided that the following conditions
0019  *   are met:
0020  *
0021  *     * Redistributions of source code must retain the above copyright
0022  *       notice, this list of conditions and the following disclaimer.
0023  *     * Redistributions in binary form must reproduce the above copy
0024  *       notice, this list of conditions and the following disclaimer in
0025  *       the documentation and/or other materials provided with the
0026  *       distribution.
0027  *     * Neither the name of AMD Corporation nor the names of its
0028  *       contributors may be used to endorse or promote products derived
0029  *       from this software without specific prior written permission.
0030  *
0031  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0032  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0033  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0034  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0035  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0036  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0037  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0038  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0039  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0040  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0041  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0042  *
0043  * AMD PCIe NTB Linux driver
0044  *
0045  * Contact Information:
0046  * Xiangliang Yu <Xiangliang.Yu@amd.com>
0047  */
0048 
0049 #ifndef NTB_HW_AMD_H
0050 #define NTB_HW_AMD_H
0051 
0052 #include <linux/ntb.h>
0053 #include <linux/pci.h>
0054 
0055 #define AMD_LINK_HB_TIMEOUT msecs_to_jiffies(1000)
0056 #define NTB_LNK_STA_SPEED_MASK  0x000F0000
0057 #define NTB_LNK_STA_WIDTH_MASK  0x03F00000
0058 #define NTB_LNK_STA_SPEED(x)    (((x) & NTB_LNK_STA_SPEED_MASK) >> 16)
0059 #define NTB_LNK_STA_WIDTH(x)    (((x) & NTB_LNK_STA_WIDTH_MASK) >> 20)
0060 
0061 #ifndef read64
0062 #ifdef readq
0063 #define read64 readq
0064 #else
0065 #define read64 _read64
0066 static inline u64 _read64(void __iomem *mmio)
0067 {
0068     u64 low, high;
0069 
0070     low = readl(mmio);
0071     high = readl(mmio + sizeof(u32));
0072     return low | (high << 32);
0073 }
0074 #endif
0075 #endif
0076 
0077 #ifndef write64
0078 #ifdef writeq
0079 #define write64 writeq
0080 #else
0081 #define write64 _write64
0082 static inline void _write64(u64 val, void __iomem *mmio)
0083 {
0084     writel(val, mmio);
0085     writel(val >> 32, mmio + sizeof(u32));
0086 }
0087 #endif
0088 #endif
0089 
0090 enum {
0091     /* AMD NTB Capability */
0092     AMD_DB_CNT      = 16,
0093     AMD_MSIX_VECTOR_CNT = 24,
0094     AMD_SPADS_CNT       = 16,
0095 
0096     /*  AMD NTB register offset */
0097     AMD_CNTL_OFFSET     = 0x200,
0098 
0099     /* NTB control register bits */
0100     PMM_REG_CTL     = BIT(21),
0101     SMM_REG_CTL     = BIT(20),
0102     SMM_REG_ACC_PATH    = BIT(18),
0103     PMM_REG_ACC_PATH    = BIT(17),
0104     NTB_CLK_EN      = BIT(16),
0105 
0106     AMD_STA_OFFSET      = 0x204,
0107     AMD_PGSLV_OFFSET    = 0x208,
0108     AMD_SPAD_MUX_OFFSET = 0x20C,
0109     AMD_SPAD_OFFSET     = 0x210,
0110     AMD_RSMU_HCID       = 0x250,
0111     AMD_RSMU_SIID       = 0x254,
0112     AMD_PSION_OFFSET    = 0x300,
0113     AMD_SSION_OFFSET    = 0x330,
0114     AMD_MMINDEX_OFFSET  = 0x400,
0115     AMD_MMDATA_OFFSET   = 0x404,
0116     AMD_SIDEINFO_OFFSET = 0x408,
0117 
0118     AMD_SIDE_MASK       = BIT(0),
0119     AMD_SIDE_READY      = BIT(1),
0120 
0121     /* limit register */
0122     AMD_ROMBARLMT_OFFSET    = 0x410,
0123     AMD_BAR1LMT_OFFSET  = 0x414,
0124     AMD_BAR23LMT_OFFSET = 0x418,
0125     AMD_BAR45LMT_OFFSET = 0x420,
0126     /* xlat address */
0127     AMD_POMBARXLAT_OFFSET   = 0x428,
0128     AMD_BAR1XLAT_OFFSET = 0x430,
0129     AMD_BAR23XLAT_OFFSET    = 0x438,
0130     AMD_BAR45XLAT_OFFSET    = 0x440,
0131     /* doorbell and interrupt */
0132     AMD_DBFM_OFFSET     = 0x450,
0133     AMD_DBREQ_OFFSET    = 0x454,
0134     AMD_MIRRDBSTAT_OFFSET   = 0x458,
0135     AMD_DBMASK_OFFSET   = 0x45C,
0136     AMD_DBSTAT_OFFSET   = 0x460,
0137     AMD_INTMASK_OFFSET  = 0x470,
0138     AMD_INTSTAT_OFFSET  = 0x474,
0139 
0140     /* event type */
0141     AMD_PEER_FLUSH_EVENT    = BIT(0),
0142     AMD_PEER_RESET_EVENT    = BIT(1),
0143     AMD_PEER_D3_EVENT   = BIT(2),
0144     AMD_PEER_PMETO_EVENT    = BIT(3),
0145     AMD_PEER_D0_EVENT   = BIT(4),
0146     AMD_LINK_UP_EVENT   = BIT(5),
0147     AMD_LINK_DOWN_EVENT = BIT(6),
0148     AMD_EVENT_INTMASK   = (AMD_PEER_FLUSH_EVENT |
0149                 AMD_PEER_RESET_EVENT | AMD_PEER_D3_EVENT |
0150                 AMD_PEER_PMETO_EVENT | AMD_PEER_D0_EVENT |
0151                 AMD_LINK_UP_EVENT | AMD_LINK_DOWN_EVENT),
0152 
0153     AMD_PMESTAT_OFFSET  = 0x480,
0154     AMD_PMSGTRIG_OFFSET = 0x490,
0155     AMD_LTRLATENCY_OFFSET   = 0x494,
0156     AMD_FLUSHTRIG_OFFSET    = 0x498,
0157 
0158     /* SMU register*/
0159     AMD_SMUACK_OFFSET   = 0x4A0,
0160     AMD_SINRST_OFFSET   = 0x4A4,
0161     AMD_RSPNUM_OFFSET   = 0x4A8,
0162     AMD_SMU_SPADMUTEX   = 0x4B0,
0163     AMD_SMU_SPADOFFSET  = 0x4B4,
0164 
0165     AMD_PEER_OFFSET     = 0x400,
0166 };
0167 
0168 struct ntb_dev_data {
0169     const unsigned char mw_count;
0170     const unsigned int mw_idx;
0171 };
0172 
0173 struct amd_ntb_dev;
0174 
0175 struct amd_ntb_vec {
0176     struct amd_ntb_dev  *ndev;
0177     int         num;
0178 };
0179 
0180 struct amd_ntb_dev {
0181     struct ntb_dev ntb;
0182 
0183     u32 ntb_side;
0184     u32 lnk_sta;
0185     u32 cntl_sta;
0186     u32 peer_sta;
0187 
0188     struct ntb_dev_data *dev_data;
0189     unsigned char mw_count;
0190     unsigned char spad_count;
0191     unsigned char db_count;
0192     unsigned char msix_vec_count;
0193 
0194     u64 db_valid_mask;
0195     u64 db_mask;
0196     u64 db_last_bit;
0197     u32 int_mask;
0198 
0199     struct msix_entry *msix;
0200     struct amd_ntb_vec *vec;
0201 
0202     /* synchronize rmw access of db_mask and hw reg */
0203     spinlock_t db_mask_lock;
0204 
0205     void __iomem *self_mmio;
0206     void __iomem *peer_mmio;
0207     unsigned int self_spad;
0208     unsigned int peer_spad;
0209 
0210     struct delayed_work hb_timer;
0211 
0212     struct dentry *debugfs_dir;
0213     struct dentry *debugfs_info;
0214 };
0215 
0216 #define ntb_ndev(__ntb) container_of(__ntb, struct amd_ntb_dev, ntb)
0217 #define hb_ndev(__work) container_of(__work, struct amd_ntb_dev, hb_timer.work)
0218 
0219 static void amd_set_side_info_reg(struct amd_ntb_dev *ndev, bool peer);
0220 static void amd_clear_side_info_reg(struct amd_ntb_dev *ndev, bool peer);
0221 static int amd_poll_link(struct amd_ntb_dev *ndev);
0222 
0223 #endif