xref: /linux/drivers/platform/x86/amd/pmc/mp1_stb.c (revision c9c0543b52d8cfe3a3b15d1e39ab9dbc91be6df4)
10e914063SShyam Sundar S K // SPDX-License-Identifier: GPL-2.0-or-later
20e914063SShyam Sundar S K /*
30e914063SShyam Sundar S K  * AMD MP1 Smart Trace Buffer (STB) Layer
40e914063SShyam Sundar S K  *
50e914063SShyam Sundar S K  * Copyright (c) 2024, Advanced Micro Devices, Inc.
60e914063SShyam Sundar S K  * All Rights Reserved.
70e914063SShyam Sundar S K  *
80e914063SShyam Sundar S K  * Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
90e914063SShyam Sundar S K  *          Sanket Goswami <Sanket.Goswami@amd.com>
100e914063SShyam Sundar S K  */
110e914063SShyam Sundar S K 
120e914063SShyam Sundar S K #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
130e914063SShyam Sundar S K 
140e914063SShyam Sundar S K #include <asm/amd_nb.h>
150e914063SShyam Sundar S K #include <linux/debugfs.h>
160e914063SShyam Sundar S K #include <linux/seq_file.h>
170e914063SShyam Sundar S K #include <linux/uaccess.h>
180e914063SShyam Sundar S K 
190e914063SShyam Sundar S K #include "pmc.h"
200e914063SShyam Sundar S K 
210e914063SShyam Sundar S K /* STB Spill to DRAM Parameters */
220e914063SShyam Sundar S K #define S2D_TELEMETRY_DRAMBYTES_MAX	0x1000000
230e914063SShyam Sundar S K #define S2D_TELEMETRY_BYTES_MAX		0x100000U
240e914063SShyam Sundar S K #define S2D_RSVD_RAM_SPACE		0x100000
250e914063SShyam Sundar S K 
260e914063SShyam Sundar S K /* STB Registers */
2700a8d002SShyam Sundar S K #define AMD_STB_PMI_0			0x03E30600
280e914063SShyam Sundar S K #define AMD_PMC_STB_DUMMY_PC	0xC6000007
290e914063SShyam Sundar S K 
300e914063SShyam Sundar S K /* STB Spill to DRAM Message Definition */
310e914063SShyam Sundar S K #define STB_FORCE_FLUSH_DATA		0xCF
320e914063SShyam Sundar S K #define FIFO_SIZE		4096
330e914063SShyam Sundar S K 
343279f7a6SShyam Sundar S K /* STB S2D(Spill to DRAM) has different message port offset */
353279f7a6SShyam Sundar S K #define AMD_S2D_REGISTER_MESSAGE	0xA20
363279f7a6SShyam Sundar S K #define AMD_S2D_REGISTER_RESPONSE	0xA80
373279f7a6SShyam Sundar S K #define AMD_S2D_REGISTER_ARGUMENT	0xA88
383279f7a6SShyam Sundar S K 
39*382fe403SShyam Sundar S K /* STB S2D (Spill to DRAM) message port offset for 44h model */
40*382fe403SShyam Sundar S K #define AMD_GNR_REGISTER_MESSAGE	0x524
41*382fe403SShyam Sundar S K #define AMD_GNR_REGISTER_RESPONSE	0x570
42*382fe403SShyam Sundar S K #define AMD_GNR_REGISTER_ARGUMENT	0xA40
43*382fe403SShyam Sundar S K 
440e914063SShyam Sundar S K static bool enable_stb;
450e914063SShyam Sundar S K module_param(enable_stb, bool, 0644);
460e914063SShyam Sundar S K MODULE_PARM_DESC(enable_stb, "Enable the STB debug mechanism");
470e914063SShyam Sundar S K 
480e914063SShyam Sundar S K static bool dump_custom_stb;
490e914063SShyam Sundar S K module_param(dump_custom_stb, bool, 0644);
500e914063SShyam Sundar S K MODULE_PARM_DESC(dump_custom_stb, "Enable to dump full STB buffer");
510e914063SShyam Sundar S K 
520e914063SShyam Sundar S K enum s2d_arg {
530e914063SShyam Sundar S K 	S2D_TELEMETRY_SIZE = 0x01,
540e914063SShyam Sundar S K 	S2D_PHYS_ADDR_LOW,
550e914063SShyam Sundar S K 	S2D_PHYS_ADDR_HIGH,
560e914063SShyam Sundar S K 	S2D_NUM_SAMPLES,
570e914063SShyam Sundar S K 	S2D_DRAM_SIZE,
580e914063SShyam Sundar S K };
590e914063SShyam Sundar S K 
6000a8d002SShyam Sundar S K struct amd_stb_v2_data {
610e914063SShyam Sundar S K 	size_t size;
620e914063SShyam Sundar S K 	u8 data[] __counted_by(size);
630e914063SShyam Sundar S K };
640e914063SShyam Sundar S K 
6500a8d002SShyam Sundar S K int amd_stb_write(struct amd_pmc_dev *dev, u32 data)
660e914063SShyam Sundar S K {
670e914063SShyam Sundar S K 	int err;
680e914063SShyam Sundar S K 
6900a8d002SShyam Sundar S K 	err = amd_smn_write(0, AMD_STB_PMI_0, data);
700e914063SShyam Sundar S K 	if (err) {
7100a8d002SShyam Sundar S K 		dev_err(dev->dev, "failed to write data in stb: 0x%X\n", AMD_STB_PMI_0);
720e914063SShyam Sundar S K 		return pcibios_err_to_errno(err);
730e914063SShyam Sundar S K 	}
740e914063SShyam Sundar S K 
750e914063SShyam Sundar S K 	return 0;
760e914063SShyam Sundar S K }
770e914063SShyam Sundar S K 
7800a8d002SShyam Sundar S K int amd_stb_read(struct amd_pmc_dev *dev, u32 *buf)
790e914063SShyam Sundar S K {
800e914063SShyam Sundar S K 	int i, err;
810e914063SShyam Sundar S K 
820e914063SShyam Sundar S K 	for (i = 0; i < FIFO_SIZE; i++) {
8300a8d002SShyam Sundar S K 		err = amd_smn_read(0, AMD_STB_PMI_0, buf++);
840e914063SShyam Sundar S K 		if (err) {
8500a8d002SShyam Sundar S K 			dev_err(dev->dev, "error reading data from stb: 0x%X\n", AMD_STB_PMI_0);
860e914063SShyam Sundar S K 			return pcibios_err_to_errno(err);
870e914063SShyam Sundar S K 		}
880e914063SShyam Sundar S K 	}
890e914063SShyam Sundar S K 
900e914063SShyam Sundar S K 	return 0;
910e914063SShyam Sundar S K }
920e914063SShyam Sundar S K 
9300a8d002SShyam Sundar S K static int amd_stb_debugfs_open(struct inode *inode, struct file *filp)
940e914063SShyam Sundar S K {
950e914063SShyam Sundar S K 	struct amd_pmc_dev *dev = filp->f_inode->i_private;
960e914063SShyam Sundar S K 	u32 size = FIFO_SIZE * sizeof(u32);
970e914063SShyam Sundar S K 	u32 *buf;
980e914063SShyam Sundar S K 	int rc;
990e914063SShyam Sundar S K 
1000e914063SShyam Sundar S K 	buf = kzalloc(size, GFP_KERNEL);
1010e914063SShyam Sundar S K 	if (!buf)
1020e914063SShyam Sundar S K 		return -ENOMEM;
1030e914063SShyam Sundar S K 
10400a8d002SShyam Sundar S K 	rc = amd_stb_read(dev, buf);
1050e914063SShyam Sundar S K 	if (rc) {
1060e914063SShyam Sundar S K 		kfree(buf);
1070e914063SShyam Sundar S K 		return rc;
1080e914063SShyam Sundar S K 	}
1090e914063SShyam Sundar S K 
1100e914063SShyam Sundar S K 	filp->private_data = buf;
1110e914063SShyam Sundar S K 	return rc;
1120e914063SShyam Sundar S K }
1130e914063SShyam Sundar S K 
11400a8d002SShyam Sundar S K static ssize_t amd_stb_debugfs_read(struct file *filp, char __user *buf, size_t size, loff_t *pos)
1150e914063SShyam Sundar S K {
1160e914063SShyam Sundar S K 	if (!filp->private_data)
1170e914063SShyam Sundar S K 		return -EINVAL;
1180e914063SShyam Sundar S K 
1190e914063SShyam Sundar S K 	return simple_read_from_buffer(buf, size, pos, filp->private_data,
1200e914063SShyam Sundar S K 				       FIFO_SIZE * sizeof(u32));
1210e914063SShyam Sundar S K }
1220e914063SShyam Sundar S K 
12300a8d002SShyam Sundar S K static int amd_stb_debugfs_release(struct inode *inode, struct file *filp)
1240e914063SShyam Sundar S K {
1250e914063SShyam Sundar S K 	kfree(filp->private_data);
1260e914063SShyam Sundar S K 	return 0;
1270e914063SShyam Sundar S K }
1280e914063SShyam Sundar S K 
12900a8d002SShyam Sundar S K static const struct file_operations amd_stb_debugfs_fops = {
1300e914063SShyam Sundar S K 	.owner = THIS_MODULE,
13100a8d002SShyam Sundar S K 	.open = amd_stb_debugfs_open,
13200a8d002SShyam Sundar S K 	.read = amd_stb_debugfs_read,
13300a8d002SShyam Sundar S K 	.release = amd_stb_debugfs_release,
1340e914063SShyam Sundar S K };
1350e914063SShyam Sundar S K 
1360e914063SShyam Sundar S K /* Enhanced STB Firmware Reporting Mechanism */
13700a8d002SShyam Sundar S K static int amd_stb_handle_efr(struct file *filp)
1380e914063SShyam Sundar S K {
1390e914063SShyam Sundar S K 	struct amd_pmc_dev *dev = filp->f_inode->i_private;
14000a8d002SShyam Sundar S K 	struct amd_stb_v2_data *stb_data_arr;
1410e914063SShyam Sundar S K 	u32 fsize;
1420e914063SShyam Sundar S K 
1430e914063SShyam Sundar S K 	fsize = dev->dram_size - S2D_RSVD_RAM_SPACE;
1440e914063SShyam Sundar S K 	stb_data_arr = kmalloc(struct_size(stb_data_arr, data, fsize), GFP_KERNEL);
1450e914063SShyam Sundar S K 	if (!stb_data_arr)
1460e914063SShyam Sundar S K 		return -ENOMEM;
1470e914063SShyam Sundar S K 
1480e914063SShyam Sundar S K 	stb_data_arr->size = fsize;
1490e914063SShyam Sundar S K 	memcpy_fromio(stb_data_arr->data, dev->stb_virt_addr, fsize);
1500e914063SShyam Sundar S K 	filp->private_data = stb_data_arr;
1510e914063SShyam Sundar S K 
1520e914063SShyam Sundar S K 	return 0;
1530e914063SShyam Sundar S K }
1540e914063SShyam Sundar S K 
15500a8d002SShyam Sundar S K static int amd_stb_debugfs_open_v2(struct inode *inode, struct file *filp)
1560e914063SShyam Sundar S K {
1570e914063SShyam Sundar S K 	struct amd_pmc_dev *dev = filp->f_inode->i_private;
1580e914063SShyam Sundar S K 	u32 fsize, num_samples, val, stb_rdptr_offset = 0;
15900a8d002SShyam Sundar S K 	struct amd_stb_v2_data *stb_data_arr;
1600e914063SShyam Sundar S K 	int ret;
1610e914063SShyam Sundar S K 
1620e914063SShyam Sundar S K 	/* Write dummy postcode while reading the STB buffer */
16300a8d002SShyam Sundar S K 	ret = amd_stb_write(dev, AMD_PMC_STB_DUMMY_PC);
1640e914063SShyam Sundar S K 	if (ret)
1650e914063SShyam Sundar S K 		dev_err(dev->dev, "error writing to STB: %d\n", ret);
1660e914063SShyam Sundar S K 
1670e914063SShyam Sundar S K 	/* Spill to DRAM num_samples uses separate SMU message port */
1682851f4f8SShyam Sundar S K 	dev->msg_port = MSG_PORT_S2D;
1690e914063SShyam Sundar S K 
1700e914063SShyam Sundar S K 	ret = amd_pmc_send_cmd(dev, 0, &val, STB_FORCE_FLUSH_DATA, 1);
1710e914063SShyam Sundar S K 	if (ret)
1720e914063SShyam Sundar S K 		dev_dbg_once(dev->dev, "S2D force flush not supported: %d\n", ret);
1730e914063SShyam Sundar S K 
1740e914063SShyam Sundar S K 	/*
1750e914063SShyam Sundar S K 	 * We have a custom stb size and the PMFW is supposed to give
1760e914063SShyam Sundar S K 	 * the enhanced dram size. Note that we land here only for the
1770e914063SShyam Sundar S K 	 * platforms that support enhanced dram size reporting.
1780e914063SShyam Sundar S K 	 */
1790e914063SShyam Sundar S K 	if (dump_custom_stb)
18000a8d002SShyam Sundar S K 		return amd_stb_handle_efr(filp);
1810e914063SShyam Sundar S K 
1820e914063SShyam Sundar S K 	/* Get the num_samples to calculate the last push location */
1833279f7a6SShyam Sundar S K 	ret = amd_pmc_send_cmd(dev, S2D_NUM_SAMPLES, &num_samples, dev->stb_arg.s2d_msg_id, true);
1840e914063SShyam Sundar S K 	/* Clear msg_port for other SMU operation */
1852851f4f8SShyam Sundar S K 	dev->msg_port = MSG_PORT_PMC;
1860e914063SShyam Sundar S K 	if (ret) {
1870e914063SShyam Sundar S K 		dev_err(dev->dev, "error: S2D_NUM_SAMPLES not supported : %d\n", ret);
1880e914063SShyam Sundar S K 		return ret;
1890e914063SShyam Sundar S K 	}
1900e914063SShyam Sundar S K 
1910e914063SShyam Sundar S K 	fsize = min(num_samples, S2D_TELEMETRY_BYTES_MAX);
1920e914063SShyam Sundar S K 	stb_data_arr = kmalloc(struct_size(stb_data_arr, data, fsize), GFP_KERNEL);
1930e914063SShyam Sundar S K 	if (!stb_data_arr)
1940e914063SShyam Sundar S K 		return -ENOMEM;
1950e914063SShyam Sundar S K 
1960e914063SShyam Sundar S K 	stb_data_arr->size = fsize;
1970e914063SShyam Sundar S K 
1980e914063SShyam Sundar S K 	/*
1990e914063SShyam Sundar S K 	 * Start capturing data from the last push location.
2000e914063SShyam Sundar S K 	 * This is for general cases, where the stb limits
2010e914063SShyam Sundar S K 	 * are meant for standard usage.
2020e914063SShyam Sundar S K 	 */
2030e914063SShyam Sundar S K 	if (num_samples > S2D_TELEMETRY_BYTES_MAX) {
2040e914063SShyam Sundar S K 		/* First read oldest data starting 1 behind last write till end of ringbuffer */
2050e914063SShyam Sundar S K 		stb_rdptr_offset = num_samples % S2D_TELEMETRY_BYTES_MAX;
2060e914063SShyam Sundar S K 		fsize = S2D_TELEMETRY_BYTES_MAX - stb_rdptr_offset;
2070e914063SShyam Sundar S K 
2080e914063SShyam Sundar S K 		memcpy_fromio(stb_data_arr->data, dev->stb_virt_addr + stb_rdptr_offset, fsize);
2090e914063SShyam Sundar S K 		/* Second copy the newer samples from offset 0 - last write */
2100e914063SShyam Sundar S K 		memcpy_fromio(stb_data_arr->data + fsize, dev->stb_virt_addr, stb_rdptr_offset);
2110e914063SShyam Sundar S K 	} else {
2120e914063SShyam Sundar S K 		memcpy_fromio(stb_data_arr->data, dev->stb_virt_addr, fsize);
2130e914063SShyam Sundar S K 	}
2140e914063SShyam Sundar S K 
2150e914063SShyam Sundar S K 	filp->private_data = stb_data_arr;
2160e914063SShyam Sundar S K 
2170e914063SShyam Sundar S K 	return 0;
2180e914063SShyam Sundar S K }
2190e914063SShyam Sundar S K 
22000a8d002SShyam Sundar S K static ssize_t amd_stb_debugfs_read_v2(struct file *filp, char __user *buf, size_t size,
2210e914063SShyam Sundar S K 				       loff_t *pos)
2220e914063SShyam Sundar S K {
22300a8d002SShyam Sundar S K 	struct amd_stb_v2_data *data = filp->private_data;
2240e914063SShyam Sundar S K 
2250e914063SShyam Sundar S K 	return simple_read_from_buffer(buf, size, pos, data->data, data->size);
2260e914063SShyam Sundar S K }
2270e914063SShyam Sundar S K 
22800a8d002SShyam Sundar S K static int amd_stb_debugfs_release_v2(struct inode *inode, struct file *filp)
2290e914063SShyam Sundar S K {
2300e914063SShyam Sundar S K 	kfree(filp->private_data);
2310e914063SShyam Sundar S K 	return 0;
2320e914063SShyam Sundar S K }
2330e914063SShyam Sundar S K 
23400a8d002SShyam Sundar S K static const struct file_operations amd_stb_debugfs_fops_v2 = {
2350e914063SShyam Sundar S K 	.owner = THIS_MODULE,
23600a8d002SShyam Sundar S K 	.open = amd_stb_debugfs_open_v2,
23700a8d002SShyam Sundar S K 	.read = amd_stb_debugfs_read_v2,
23800a8d002SShyam Sundar S K 	.release = amd_stb_debugfs_release_v2,
2390e914063SShyam Sundar S K };
2400e914063SShyam Sundar S K 
241*382fe403SShyam Sundar S K static void amd_stb_update_args(struct amd_pmc_dev *dev)
242*382fe403SShyam Sundar S K {
243*382fe403SShyam Sundar S K 	if (cpu_feature_enabled(X86_FEATURE_ZEN5))
244*382fe403SShyam Sundar S K 		switch (boot_cpu_data.x86_model) {
245*382fe403SShyam Sundar S K 		case 0x44:
246*382fe403SShyam Sundar S K 			dev->stb_arg.msg = AMD_GNR_REGISTER_MESSAGE;
247*382fe403SShyam Sundar S K 			dev->stb_arg.arg = AMD_GNR_REGISTER_ARGUMENT;
248*382fe403SShyam Sundar S K 			dev->stb_arg.resp = AMD_GNR_REGISTER_RESPONSE;
249*382fe403SShyam Sundar S K 			return;
250*382fe403SShyam Sundar S K 		default:
251*382fe403SShyam Sundar S K 			break;
252*382fe403SShyam Sundar S K 	}
253*382fe403SShyam Sundar S K 
254*382fe403SShyam Sundar S K 	dev->stb_arg.msg = AMD_S2D_REGISTER_MESSAGE;
255*382fe403SShyam Sundar S K 	dev->stb_arg.arg = AMD_S2D_REGISTER_ARGUMENT;
256*382fe403SShyam Sundar S K 	dev->stb_arg.resp = AMD_S2D_REGISTER_RESPONSE;
257*382fe403SShyam Sundar S K }
258*382fe403SShyam Sundar S K 
25900a8d002SShyam Sundar S K static bool amd_is_stb_supported(struct amd_pmc_dev *dev)
2600e914063SShyam Sundar S K {
2610e914063SShyam Sundar S K 	switch (dev->cpu_id) {
2620e914063SShyam Sundar S K 	case AMD_CPU_ID_YC:
2630e914063SShyam Sundar S K 	case AMD_CPU_ID_CB:
264*382fe403SShyam Sundar S K 		if (boot_cpu_data.x86_model == 0x44)
265*382fe403SShyam Sundar S K 			dev->stb_arg.s2d_msg_id = 0x9B;
266*382fe403SShyam Sundar S K 		else
2673279f7a6SShyam Sundar S K 			dev->stb_arg.s2d_msg_id = 0xBE;
2683279f7a6SShyam Sundar S K 		break;
2690e914063SShyam Sundar S K 	case AMD_CPU_ID_PS:
2703279f7a6SShyam Sundar S K 		dev->stb_arg.s2d_msg_id = 0x85;
2713279f7a6SShyam Sundar S K 		break;
2720e914063SShyam Sundar S K 	case PCI_DEVICE_ID_AMD_1AH_M20H_ROOT:
2730e914063SShyam Sundar S K 	case PCI_DEVICE_ID_AMD_1AH_M60H_ROOT:
2744aeca317SShyam Sundar S K 		if (boot_cpu_data.x86_model == 0x70)
2754aeca317SShyam Sundar S K 			dev->stb_arg.s2d_msg_id = 0xF1;
2764aeca317SShyam Sundar S K 		else
2773279f7a6SShyam Sundar S K 			dev->stb_arg.s2d_msg_id = 0xDE;
2783279f7a6SShyam Sundar S K 		break;
2790e914063SShyam Sundar S K 	default:
2800e914063SShyam Sundar S K 		return false;
2810e914063SShyam Sundar S K 	}
2823279f7a6SShyam Sundar S K 
283*382fe403SShyam Sundar S K 	amd_stb_update_args(dev);
2843279f7a6SShyam Sundar S K 	return true;
2850e914063SShyam Sundar S K }
2860e914063SShyam Sundar S K 
28700a8d002SShyam Sundar S K int amd_stb_s2d_init(struct amd_pmc_dev *dev)
2880e914063SShyam Sundar S K {
2890e914063SShyam Sundar S K 	u32 phys_addr_low, phys_addr_hi;
2900e914063SShyam Sundar S K 	u64 stb_phys_addr;
2910e914063SShyam Sundar S K 	u32 size = 0;
2920e914063SShyam Sundar S K 	int ret;
2930e914063SShyam Sundar S K 
2940e914063SShyam Sundar S K 	if (!enable_stb)
2950e914063SShyam Sundar S K 		return 0;
2960e914063SShyam Sundar S K 
29700a8d002SShyam Sundar S K 	if (amd_is_stb_supported(dev)) {
2980e914063SShyam Sundar S K 		debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
29900a8d002SShyam Sundar S K 				    &amd_stb_debugfs_fops_v2);
3000e914063SShyam Sundar S K 	} else {
3010e914063SShyam Sundar S K 		debugfs_create_file("stb_read", 0644, dev->dbgfs_dir, dev,
30200a8d002SShyam Sundar S K 				    &amd_stb_debugfs_fops);
3030e914063SShyam Sundar S K 		return 0;
3040e914063SShyam Sundar S K 	}
3050e914063SShyam Sundar S K 
3060e914063SShyam Sundar S K 	/* Spill to DRAM feature uses separate SMU message port */
3072851f4f8SShyam Sundar S K 	dev->msg_port = MSG_PORT_S2D;
3080e914063SShyam Sundar S K 
3093279f7a6SShyam Sundar S K 	amd_pmc_send_cmd(dev, S2D_TELEMETRY_SIZE, &size, dev->stb_arg.s2d_msg_id, true);
3100e914063SShyam Sundar S K 	if (size != S2D_TELEMETRY_BYTES_MAX)
3110e914063SShyam Sundar S K 		return -EIO;
3120e914063SShyam Sundar S K 
3130e914063SShyam Sundar S K 	/* Get DRAM size */
3143279f7a6SShyam Sundar S K 	ret = amd_pmc_send_cmd(dev, S2D_DRAM_SIZE, &dev->dram_size, dev->stb_arg.s2d_msg_id, true);
3150e914063SShyam Sundar S K 	if (ret || !dev->dram_size)
3160e914063SShyam Sundar S K 		dev->dram_size = S2D_TELEMETRY_DRAMBYTES_MAX;
3170e914063SShyam Sundar S K 
3180e914063SShyam Sundar S K 	/* Get STB DRAM address */
3193279f7a6SShyam Sundar S K 	amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_LOW, &phys_addr_low, dev->stb_arg.s2d_msg_id, true);
3203279f7a6SShyam Sundar S K 	amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_HIGH, &phys_addr_hi, dev->stb_arg.s2d_msg_id, true);
3210e914063SShyam Sundar S K 
3220e914063SShyam Sundar S K 	stb_phys_addr = ((u64)phys_addr_hi << 32 | phys_addr_low);
3230e914063SShyam Sundar S K 
3240e914063SShyam Sundar S K 	/* Clear msg_port for other SMU operation */
3252851f4f8SShyam Sundar S K 	dev->msg_port = MSG_PORT_PMC;
3260e914063SShyam Sundar S K 
3270e914063SShyam Sundar S K 	dev->stb_virt_addr = devm_ioremap(dev->dev, stb_phys_addr, dev->dram_size);
3280e914063SShyam Sundar S K 	if (!dev->stb_virt_addr)
3290e914063SShyam Sundar S K 		return -ENOMEM;
3300e914063SShyam Sundar S K 
3310e914063SShyam Sundar S K 	return 0;
3320e914063SShyam Sundar S K }
333