1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (c) 2024, Advanced Micro Devices, Inc.
8 * Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com>
11 #include <linux/debugfs.h>
12 #include <linux/device.h>
14 #include <linux/io-64-nonatomic-lo-hi.h>
15 #include <linux/iopoll.h>
16 #include <linux/pci.h>
17 #include <linux/sizes.h>
18 #include <linux/time.h>
23 #define VALID_RESPONSE 2
25 #define AMD_C2P_MSG0 0x10500
26 #define AMD_C2P_MSG1 0x10504
27 #define AMD_P2C_MSG0 0x10680
28 #define AMD_P2C_MSG1 0x10684
30 #define MP2_RESP_SLEEP_US 500
31 #define MP2_RESP_TIMEOUT_US (1600 * USEC_PER_MSEC)
33 #define MP2_STB_DATA_LEN_2KB 1
34 #define MP2_STB_DATA_LEN_16KB 4
36 #define MP2_MMIO_BAR 2
50 struct mp2_cmd_response
{
62 struct mp2_stb_data_valid
{
72 static int amd_mp2_wait_response(struct amd_mp2_dev
*mp2
, u8 cmd_id
, u32 command_sts
)
74 struct mp2_cmd_response cmd_resp
;
76 if (!readl_poll_timeout(mp2
->mmio
+ AMD_P2C_MSG0
, cmd_resp
.resp
,
77 (cmd_resp
.field
.response
== 0x0 &&
78 cmd_resp
.field
.status
== command_sts
&&
79 cmd_resp
.field
.cmd_id
== cmd_id
), MP2_RESP_SLEEP_US
,
81 return cmd_resp
.field
.status
;
86 static void amd_mp2_stb_send_cmd(struct amd_mp2_dev
*mp2
, u8 cmd_id
, bool is_dma_used
)
88 struct mp2_cmd_base cmd_base
;
91 cmd_base
.field
.cmd_id
= cmd_id
;
92 cmd_base
.field
.intr_disable
= 1;
93 cmd_base
.field
.is_dma_used
= is_dma_used
;
95 writeq(mp2
->dma_addr
, mp2
->mmio
+ AMD_C2P_MSG1
);
96 writel(cmd_base
.ul
, mp2
->mmio
+ AMD_C2P_MSG0
);
99 static int amd_mp2_stb_region(struct amd_mp2_dev
*mp2
)
101 struct device
*dev
= &mp2
->pdev
->dev
;
102 unsigned int len
= mp2
->stb_len
;
105 mp2
->vslbase
= dmam_alloc_coherent(dev
, len
, &mp2
->dma_addr
, GFP_KERNEL
);
109 mp2
->stbdata
= devm_kzalloc(dev
, len
, GFP_KERNEL
);
117 static int amd_mp2_process_cmd(struct amd_mp2_dev
*mp2
, struct file
*filp
)
119 struct device
*dev
= &mp2
->pdev
->dev
;
120 struct mp2_stb_data_valid stb_dv
;
123 stb_dv
.data_valid
= readl(mp2
->mmio
+ AMD_P2C_MSG1
);
125 if (stb_dv
.val
.valid
!= VALID_MSG
) {
126 dev_dbg(dev
, "Invalid STB data\n");
130 if (stb_dv
.val
.length
!= MP2_STB_DATA_LEN_2KB
&&
131 stb_dv
.val
.length
!= MP2_STB_DATA_LEN_16KB
) {
132 dev_dbg(dev
, "Unsupported length\n");
136 mp2
->stb_len
= BIT(stb_dv
.val
.length
) * SZ_1K
;
138 status
= amd_mp2_stb_region(mp2
);
140 dev_err(dev
, "Failed to init STB region, status %d\n", status
);
144 amd_mp2_stb_send_cmd(mp2
, VALID_MSG
, true);
145 status
= amd_mp2_wait_response(mp2
, VALID_MSG
, VALID_RESPONSE
);
146 if (status
== VALID_RESPONSE
) {
147 memcpy_fromio(mp2
->stbdata
, mp2
->vslbase
, mp2
->stb_len
);
148 filp
->private_data
= mp2
->stbdata
;
149 mp2
->is_stb_data
= true;
151 dev_err(dev
, "Failed to start STB dump, status %d\n", status
);
158 static int amd_mp2_stb_debugfs_open(struct inode
*inode
, struct file
*filp
)
160 struct amd_pmc_dev
*dev
= filp
->f_inode
->i_private
;
161 struct amd_mp2_dev
*mp2
= dev
->mp2
;
164 if (!mp2
->is_stb_data
)
165 return amd_mp2_process_cmd(mp2
, filp
);
167 filp
->private_data
= mp2
->stbdata
;
175 static ssize_t
amd_mp2_stb_debugfs_read(struct file
*filp
, char __user
*buf
, size_t size
,
178 struct amd_pmc_dev
*dev
= filp
->f_inode
->i_private
;
179 struct amd_mp2_dev
*mp2
= dev
->mp2
;
184 if (!filp
->private_data
)
187 return simple_read_from_buffer(buf
, size
, pos
, filp
->private_data
, mp2
->stb_len
);
190 static const struct file_operations amd_mp2_stb_debugfs_fops
= {
191 .owner
= THIS_MODULE
,
192 .open
= amd_mp2_stb_debugfs_open
,
193 .read
= amd_mp2_stb_debugfs_read
,
196 static void amd_mp2_dbgfs_register(struct amd_pmc_dev
*dev
)
201 debugfs_create_file("stb_read_previous_boot", 0644, dev
->dbgfs_dir
, dev
,
202 &amd_mp2_stb_debugfs_fops
);
205 void amd_mp2_stb_deinit(struct amd_pmc_dev
*dev
)
207 struct amd_mp2_dev
*mp2
= dev
->mp2
;
208 struct pci_dev
*pdev
;
210 if (mp2
&& mp2
->pdev
) {
214 pci_clear_master(pdev
);
219 devres_release_group(&pdev
->dev
, mp2
->devres_gid
);
225 void amd_mp2_stb_init(struct amd_pmc_dev
*dev
)
227 struct amd_mp2_dev
*mp2
= NULL
;
228 struct pci_dev
*pdev
;
231 mp2
= devm_kzalloc(dev
->dev
, sizeof(*mp2
), GFP_KERNEL
);
235 pdev
= pci_get_device(PCI_VENDOR_ID_AMD
, PCI_DEVICE_ID_AMD_MP2_STB
, NULL
);
242 mp2
->devres_gid
= devres_open_group(&pdev
->dev
, NULL
, GFP_KERNEL
);
243 if (!mp2
->devres_gid
) {
244 dev_err(&pdev
->dev
, "devres_open_group failed\n");
248 rc
= pcim_enable_device(pdev
);
250 dev_err(&pdev
->dev
, "pcim_enable_device failed\n");
254 rc
= pcim_iomap_regions(pdev
, BIT(MP2_MMIO_BAR
), "mp2 stb");
256 dev_err(&pdev
->dev
, "pcim_iomap_regions failed\n");
260 mp2
->mmio
= pcim_iomap_table(pdev
)[MP2_MMIO_BAR
];
262 dev_err(&pdev
->dev
, "pcim_iomap_table failed\n");
266 pci_set_master(pdev
);
268 rc
= dma_set_mask_and_coherent(&pdev
->dev
, DMA_BIT_MASK(64));
270 dev_err(&pdev
->dev
, "failed to set DMA mask\n");
274 amd_mp2_dbgfs_register(dev
);
279 amd_mp2_stb_deinit(dev
);