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