Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/intel/atom/sst/sst_pci.c
26516 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* sst_pci.c - SST (LPE) driver init file for pci enumeration.
4
*
5
* Copyright (C) 2008-14 Intel Corp
6
* Authors: Vinod Koul <[email protected]>
7
* Harsha Priya <[email protected]>
8
* Dharageswari R <[email protected]>
9
* KP Jeeja <[email protected]>
10
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11
*
12
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
13
*/
14
#include <linux/module.h>
15
#include <linux/pci.h>
16
#include <linux/fs.h>
17
#include <linux/firmware.h>
18
#include <sound/core.h>
19
#include <sound/soc.h>
20
#include <asm/platform_sst_audio.h>
21
#include "../sst-mfld-platform.h"
22
#include "sst.h"
23
24
static int sst_platform_get_resources(struct intel_sst_drv *ctx)
25
{
26
int ddr_base, ret = 0;
27
struct pci_dev *pci = ctx->pci;
28
29
ret = pcim_request_all_regions(pci, SST_DRV_NAME);
30
if (ret)
31
return ret;
32
33
/* map registers */
34
/* DDR base */
35
if (ctx->dev_id == PCI_DEVICE_ID_INTEL_SST_TNG) {
36
ctx->ddr_base = pci_resource_start(pci, 0);
37
/* check that the relocated IMR base matches with FW Binary */
38
ddr_base = relocate_imr_addr_mrfld(ctx->ddr_base);
39
if (!ctx->pdata->lib_info) {
40
dev_err(ctx->dev, "lib_info pointer NULL\n");
41
return -EINVAL;
42
}
43
if (ddr_base != ctx->pdata->lib_info->mod_base) {
44
dev_err(ctx->dev,
45
"FW LSP DDR BASE does not match with IFWI\n");
46
return -EINVAL;
47
}
48
ctx->ddr_end = pci_resource_end(pci, 0);
49
50
ctx->ddr = pcim_iomap(pci, 0, 0);
51
if (!ctx->ddr)
52
return -ENOMEM;
53
54
dev_dbg(ctx->dev, "sst: DDR Ptr %p\n", ctx->ddr);
55
} else {
56
ctx->ddr = NULL;
57
}
58
/* SHIM */
59
ctx->shim_phy_add = pci_resource_start(pci, 1);
60
ctx->shim = pcim_iomap(pci, 1, 0);
61
if (!ctx->shim)
62
return -ENOMEM;
63
64
dev_dbg(ctx->dev, "SST Shim Ptr %p\n", ctx->shim);
65
66
/* Shared SRAM */
67
ctx->mailbox_add = pci_resource_start(pci, 2);
68
ctx->mailbox = pcim_iomap(pci, 2, 0);
69
if (!ctx->mailbox)
70
return -ENOMEM;
71
72
dev_dbg(ctx->dev, "SRAM Ptr %p\n", ctx->mailbox);
73
74
/* IRAM */
75
ctx->iram_end = pci_resource_end(pci, 3);
76
ctx->iram_base = pci_resource_start(pci, 3);
77
ctx->iram = pcim_iomap(pci, 3, 0);
78
if (!ctx->iram)
79
return -ENOMEM;
80
81
dev_dbg(ctx->dev, "IRAM Ptr %p\n", ctx->iram);
82
83
/* DRAM */
84
ctx->dram_end = pci_resource_end(pci, 4);
85
ctx->dram_base = pci_resource_start(pci, 4);
86
ctx->dram = pcim_iomap(pci, 4, 0);
87
if (!ctx->dram)
88
return -ENOMEM;
89
90
dev_dbg(ctx->dev, "DRAM Ptr %p\n", ctx->dram);
91
return 0;
92
}
93
94
/*
95
* intel_sst_probe - PCI probe function
96
*
97
* @pci: PCI device structure
98
* @pci_id: PCI device ID structure
99
*
100
*/
101
static int intel_sst_probe(struct pci_dev *pci,
102
const struct pci_device_id *pci_id)
103
{
104
int ret = 0;
105
struct intel_sst_drv *sst_drv_ctx;
106
struct sst_platform_info *sst_pdata = pci->dev.platform_data;
107
108
dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device);
109
ret = sst_alloc_drv_context(&sst_drv_ctx, &pci->dev, pci->device);
110
if (ret < 0)
111
return ret;
112
113
sst_drv_ctx->pdata = sst_pdata;
114
sst_drv_ctx->irq_num = pci->irq;
115
snprintf(sst_drv_ctx->firmware_name, sizeof(sst_drv_ctx->firmware_name),
116
"%s%04x%s", "fw_sst_",
117
sst_drv_ctx->dev_id, ".bin");
118
119
ret = sst_context_init(sst_drv_ctx);
120
if (ret < 0)
121
return ret;
122
123
/* Init the device */
124
ret = pcim_enable_device(pci);
125
if (ret) {
126
dev_err(sst_drv_ctx->dev,
127
"device can't be enabled. Returned err: %d\n", ret);
128
goto do_free_drv_ctx;
129
}
130
sst_drv_ctx->pci = pci_dev_get(pci);
131
ret = sst_platform_get_resources(sst_drv_ctx);
132
if (ret < 0)
133
goto do_free_drv_ctx;
134
135
pci_set_drvdata(pci, sst_drv_ctx);
136
sst_configure_runtime_pm(sst_drv_ctx);
137
138
return ret;
139
140
do_free_drv_ctx:
141
sst_context_cleanup(sst_drv_ctx);
142
dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret);
143
return ret;
144
}
145
146
/**
147
* intel_sst_remove - PCI remove function
148
*
149
* @pci: PCI device structure
150
*
151
* This function is called by OS when a device is unloaded
152
* This frees the interrupt etc
153
*/
154
static void intel_sst_remove(struct pci_dev *pci)
155
{
156
struct intel_sst_drv *sst_drv_ctx = pci_get_drvdata(pci);
157
158
sst_context_cleanup(sst_drv_ctx);
159
pci_dev_put(sst_drv_ctx->pci);
160
pci_set_drvdata(pci, NULL);
161
}
162
163
/* PCI Routines */
164
static const struct pci_device_id intel_sst_ids[] = {
165
{ PCI_DEVICE_DATA(INTEL, SST_TNG, 0) },
166
{ 0, }
167
};
168
169
static struct pci_driver sst_driver = {
170
.name = SST_DRV_NAME,
171
.id_table = intel_sst_ids,
172
.probe = intel_sst_probe,
173
.remove = intel_sst_remove,
174
#ifdef CONFIG_PM
175
.driver = {
176
.pm = &intel_sst_pm,
177
},
178
#endif
179
};
180
181
module_pci_driver(sst_driver);
182
183
MODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine PCI Driver");
184
MODULE_AUTHOR("Vinod Koul <[email protected]>");
185
MODULE_AUTHOR("Harsha Priya <[email protected]>");
186
MODULE_AUTHOR("Dharageswari R <[email protected]>");
187
MODULE_AUTHOR("KP Jeeja <[email protected]>");
188
MODULE_LICENSE("GPL v2");
189
MODULE_ALIAS("sst");
190
191