18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * This file is provided under a dual BSD/GPLv2 license. When using or 38c2ecf20Sopenharmony_ci * redistributing this file, you may do so under either license. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * GPL LICENSE SUMMARY 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright (C) 2016 Advanced Micro Devices, Inc. All Rights Reserved. 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * This program is free software; you can redistribute it and/or modify 108c2ecf20Sopenharmony_ci * it under the terms of version 2 of the GNU General Public License as 118c2ecf20Sopenharmony_ci * published by the Free Software Foundation. 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci * BSD LICENSE 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * Copyright (C) 2016 Advanced Micro Devices, Inc. All Rights Reserved. 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 188c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions 198c2ecf20Sopenharmony_ci * are met: 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * * Redistributions of source code must retain the above copyright 228c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer. 238c2ecf20Sopenharmony_ci * * Redistributions in binary form must reproduce the above copy 248c2ecf20Sopenharmony_ci * notice, this list of conditions and the following disclaimer in 258c2ecf20Sopenharmony_ci * the documentation and/or other materials provided with the 268c2ecf20Sopenharmony_ci * distribution. 278c2ecf20Sopenharmony_ci * * Neither the name of AMD Corporation nor the names of its 288c2ecf20Sopenharmony_ci * contributors may be used to endorse or promote products derived 298c2ecf20Sopenharmony_ci * from this software without specific prior written permission. 308c2ecf20Sopenharmony_ci * 318c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 328c2ecf20Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 338c2ecf20Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 348c2ecf20Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 358c2ecf20Sopenharmony_ci * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 368c2ecf20Sopenharmony_ci * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 378c2ecf20Sopenharmony_ci * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 388c2ecf20Sopenharmony_ci * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 398c2ecf20Sopenharmony_ci * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 408c2ecf20Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 418c2ecf20Sopenharmony_ci * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 428c2ecf20Sopenharmony_ci * 438c2ecf20Sopenharmony_ci * AMD PCIe NTB Linux driver 448c2ecf20Sopenharmony_ci * 458c2ecf20Sopenharmony_ci * Contact Information: 468c2ecf20Sopenharmony_ci * Xiangliang Yu <Xiangliang.Yu@amd.com> 478c2ecf20Sopenharmony_ci */ 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#ifndef NTB_HW_AMD_H 508c2ecf20Sopenharmony_ci#define NTB_HW_AMD_H 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci#include <linux/ntb.h> 538c2ecf20Sopenharmony_ci#include <linux/pci.h> 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#define AMD_LINK_HB_TIMEOUT msecs_to_jiffies(1000) 568c2ecf20Sopenharmony_ci#define NTB_LNK_STA_SPEED_MASK 0x000F0000 578c2ecf20Sopenharmony_ci#define NTB_LNK_STA_WIDTH_MASK 0x03F00000 588c2ecf20Sopenharmony_ci#define NTB_LNK_STA_SPEED(x) (((x) & NTB_LNK_STA_SPEED_MASK) >> 16) 598c2ecf20Sopenharmony_ci#define NTB_LNK_STA_WIDTH(x) (((x) & NTB_LNK_STA_WIDTH_MASK) >> 20) 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci#ifndef read64 628c2ecf20Sopenharmony_ci#ifdef readq 638c2ecf20Sopenharmony_ci#define read64 readq 648c2ecf20Sopenharmony_ci#else 658c2ecf20Sopenharmony_ci#define read64 _read64 668c2ecf20Sopenharmony_cistatic inline u64 _read64(void __iomem *mmio) 678c2ecf20Sopenharmony_ci{ 688c2ecf20Sopenharmony_ci u64 low, high; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci low = readl(mmio); 718c2ecf20Sopenharmony_ci high = readl(mmio + sizeof(u32)); 728c2ecf20Sopenharmony_ci return low | (high << 32); 738c2ecf20Sopenharmony_ci} 748c2ecf20Sopenharmony_ci#endif 758c2ecf20Sopenharmony_ci#endif 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci#ifndef write64 788c2ecf20Sopenharmony_ci#ifdef writeq 798c2ecf20Sopenharmony_ci#define write64 writeq 808c2ecf20Sopenharmony_ci#else 818c2ecf20Sopenharmony_ci#define write64 _write64 828c2ecf20Sopenharmony_cistatic inline void _write64(u64 val, void __iomem *mmio) 838c2ecf20Sopenharmony_ci{ 848c2ecf20Sopenharmony_ci writel(val, mmio); 858c2ecf20Sopenharmony_ci writel(val >> 32, mmio + sizeof(u32)); 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci#endif 888c2ecf20Sopenharmony_ci#endif 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_cienum { 918c2ecf20Sopenharmony_ci /* AMD NTB Capability */ 928c2ecf20Sopenharmony_ci AMD_DB_CNT = 16, 938c2ecf20Sopenharmony_ci AMD_MSIX_VECTOR_CNT = 24, 948c2ecf20Sopenharmony_ci AMD_SPADS_CNT = 16, 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci /* AMD NTB register offset */ 978c2ecf20Sopenharmony_ci AMD_CNTL_OFFSET = 0x200, 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci /* NTB control register bits */ 1008c2ecf20Sopenharmony_ci PMM_REG_CTL = BIT(21), 1018c2ecf20Sopenharmony_ci SMM_REG_CTL = BIT(20), 1028c2ecf20Sopenharmony_ci SMM_REG_ACC_PATH = BIT(18), 1038c2ecf20Sopenharmony_ci PMM_REG_ACC_PATH = BIT(17), 1048c2ecf20Sopenharmony_ci NTB_CLK_EN = BIT(16), 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci AMD_STA_OFFSET = 0x204, 1078c2ecf20Sopenharmony_ci AMD_PGSLV_OFFSET = 0x208, 1088c2ecf20Sopenharmony_ci AMD_SPAD_MUX_OFFSET = 0x20C, 1098c2ecf20Sopenharmony_ci AMD_SPAD_OFFSET = 0x210, 1108c2ecf20Sopenharmony_ci AMD_RSMU_HCID = 0x250, 1118c2ecf20Sopenharmony_ci AMD_RSMU_SIID = 0x254, 1128c2ecf20Sopenharmony_ci AMD_PSION_OFFSET = 0x300, 1138c2ecf20Sopenharmony_ci AMD_SSION_OFFSET = 0x330, 1148c2ecf20Sopenharmony_ci AMD_MMINDEX_OFFSET = 0x400, 1158c2ecf20Sopenharmony_ci AMD_MMDATA_OFFSET = 0x404, 1168c2ecf20Sopenharmony_ci AMD_SIDEINFO_OFFSET = 0x408, 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci AMD_SIDE_MASK = BIT(0), 1198c2ecf20Sopenharmony_ci AMD_SIDE_READY = BIT(1), 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci /* limit register */ 1228c2ecf20Sopenharmony_ci AMD_ROMBARLMT_OFFSET = 0x410, 1238c2ecf20Sopenharmony_ci AMD_BAR1LMT_OFFSET = 0x414, 1248c2ecf20Sopenharmony_ci AMD_BAR23LMT_OFFSET = 0x418, 1258c2ecf20Sopenharmony_ci AMD_BAR45LMT_OFFSET = 0x420, 1268c2ecf20Sopenharmony_ci /* xlat address */ 1278c2ecf20Sopenharmony_ci AMD_POMBARXLAT_OFFSET = 0x428, 1288c2ecf20Sopenharmony_ci AMD_BAR1XLAT_OFFSET = 0x430, 1298c2ecf20Sopenharmony_ci AMD_BAR23XLAT_OFFSET = 0x438, 1308c2ecf20Sopenharmony_ci AMD_BAR45XLAT_OFFSET = 0x440, 1318c2ecf20Sopenharmony_ci /* doorbell and interrupt */ 1328c2ecf20Sopenharmony_ci AMD_DBFM_OFFSET = 0x450, 1338c2ecf20Sopenharmony_ci AMD_DBREQ_OFFSET = 0x454, 1348c2ecf20Sopenharmony_ci AMD_MIRRDBSTAT_OFFSET = 0x458, 1358c2ecf20Sopenharmony_ci AMD_DBMASK_OFFSET = 0x45C, 1368c2ecf20Sopenharmony_ci AMD_DBSTAT_OFFSET = 0x460, 1378c2ecf20Sopenharmony_ci AMD_INTMASK_OFFSET = 0x470, 1388c2ecf20Sopenharmony_ci AMD_INTSTAT_OFFSET = 0x474, 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci /* event type */ 1418c2ecf20Sopenharmony_ci AMD_PEER_FLUSH_EVENT = BIT(0), 1428c2ecf20Sopenharmony_ci AMD_PEER_RESET_EVENT = BIT(1), 1438c2ecf20Sopenharmony_ci AMD_PEER_D3_EVENT = BIT(2), 1448c2ecf20Sopenharmony_ci AMD_PEER_PMETO_EVENT = BIT(3), 1458c2ecf20Sopenharmony_ci AMD_PEER_D0_EVENT = BIT(4), 1468c2ecf20Sopenharmony_ci AMD_LINK_UP_EVENT = BIT(5), 1478c2ecf20Sopenharmony_ci AMD_LINK_DOWN_EVENT = BIT(6), 1488c2ecf20Sopenharmony_ci AMD_EVENT_INTMASK = (AMD_PEER_FLUSH_EVENT | 1498c2ecf20Sopenharmony_ci AMD_PEER_RESET_EVENT | AMD_PEER_D3_EVENT | 1508c2ecf20Sopenharmony_ci AMD_PEER_PMETO_EVENT | AMD_PEER_D0_EVENT | 1518c2ecf20Sopenharmony_ci AMD_LINK_UP_EVENT | AMD_LINK_DOWN_EVENT), 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci AMD_PMESTAT_OFFSET = 0x480, 1548c2ecf20Sopenharmony_ci AMD_PMSGTRIG_OFFSET = 0x490, 1558c2ecf20Sopenharmony_ci AMD_LTRLATENCY_OFFSET = 0x494, 1568c2ecf20Sopenharmony_ci AMD_FLUSHTRIG_OFFSET = 0x498, 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_ci /* SMU register*/ 1598c2ecf20Sopenharmony_ci AMD_SMUACK_OFFSET = 0x4A0, 1608c2ecf20Sopenharmony_ci AMD_SINRST_OFFSET = 0x4A4, 1618c2ecf20Sopenharmony_ci AMD_RSPNUM_OFFSET = 0x4A8, 1628c2ecf20Sopenharmony_ci AMD_SMU_SPADMUTEX = 0x4B0, 1638c2ecf20Sopenharmony_ci AMD_SMU_SPADOFFSET = 0x4B4, 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci AMD_PEER_OFFSET = 0x400, 1668c2ecf20Sopenharmony_ci}; 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_cistruct ntb_dev_data { 1698c2ecf20Sopenharmony_ci const unsigned char mw_count; 1708c2ecf20Sopenharmony_ci const unsigned int mw_idx; 1718c2ecf20Sopenharmony_ci}; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_cistruct amd_ntb_dev; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_cistruct amd_ntb_vec { 1768c2ecf20Sopenharmony_ci struct amd_ntb_dev *ndev; 1778c2ecf20Sopenharmony_ci int num; 1788c2ecf20Sopenharmony_ci}; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_cistruct amd_ntb_dev { 1818c2ecf20Sopenharmony_ci struct ntb_dev ntb; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci u32 ntb_side; 1848c2ecf20Sopenharmony_ci u32 lnk_sta; 1858c2ecf20Sopenharmony_ci u32 cntl_sta; 1868c2ecf20Sopenharmony_ci u32 peer_sta; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci struct ntb_dev_data *dev_data; 1898c2ecf20Sopenharmony_ci unsigned char mw_count; 1908c2ecf20Sopenharmony_ci unsigned char spad_count; 1918c2ecf20Sopenharmony_ci unsigned char db_count; 1928c2ecf20Sopenharmony_ci unsigned char msix_vec_count; 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci u64 db_valid_mask; 1958c2ecf20Sopenharmony_ci u64 db_mask; 1968c2ecf20Sopenharmony_ci u64 db_last_bit; 1978c2ecf20Sopenharmony_ci u32 int_mask; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci struct msix_entry *msix; 2008c2ecf20Sopenharmony_ci struct amd_ntb_vec *vec; 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ci /* synchronize rmw access of db_mask and hw reg */ 2038c2ecf20Sopenharmony_ci spinlock_t db_mask_lock; 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci void __iomem *self_mmio; 2068c2ecf20Sopenharmony_ci void __iomem *peer_mmio; 2078c2ecf20Sopenharmony_ci unsigned int self_spad; 2088c2ecf20Sopenharmony_ci unsigned int peer_spad; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci struct delayed_work hb_timer; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci struct dentry *debugfs_dir; 2138c2ecf20Sopenharmony_ci struct dentry *debugfs_info; 2148c2ecf20Sopenharmony_ci}; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci#define ntb_ndev(__ntb) container_of(__ntb, struct amd_ntb_dev, ntb) 2178c2ecf20Sopenharmony_ci#define hb_ndev(__work) container_of(__work, struct amd_ntb_dev, hb_timer.work) 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_cistatic void amd_set_side_info_reg(struct amd_ntb_dev *ndev, bool peer); 2208c2ecf20Sopenharmony_cistatic void amd_clear_side_info_reg(struct amd_ntb_dev *ndev, bool peer); 2218c2ecf20Sopenharmony_cistatic int amd_poll_link(struct amd_ntb_dev *ndev); 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci#endif 224