diff options
author | Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> | 2016-08-12 17:27:47 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2016-08-15 10:14:57 -0400 |
commit | a68bc0d43e1b96c374c4b03eb9baa662778357b3 (patch) | |
tree | 09037f20bf5d43d2e9193dca476894338cb9ad45 | |
parent | 5d98f58fd66ea164d7e317d57de77b7d7c1391ff (diff) |
ASoC: Intel: Atom: auto-detection of Baytrail-CR
BYT-CR needs special handling to deal with BIOS issues.
For some reason the IPC interrupt index is also modified from
the Baytrail-T reference.
Use PUNIT BIOS config bits to infer platform details.
Assume regular Baytrail configs if status is incorrect or
CONFIG_IOSF_MBI is not enabled.
SSP0 routing issues are solved without dedicated firmware
in following patches
Tested on Asus T100TA and T100TAF.
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/intel/atom/sst/sst_acpi.c | 82 |
1 files changed, 78 insertions, 4 deletions
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c index 4d3184971227..0c2cc4207b95 100644 --- a/sound/soc/intel/atom/sst/sst_acpi.c +++ b/sound/soc/intel/atom/sst/sst_acpi.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <acpi/platform/aclinux.h> | 39 | #include <acpi/platform/aclinux.h> |
40 | #include <acpi/actypes.h> | 40 | #include <acpi/actypes.h> |
41 | #include <acpi/acpi_bus.h> | 41 | #include <acpi/acpi_bus.h> |
42 | #include <asm/cpu_device_id.h> | ||
43 | #include <asm/iosf_mbi.h> | ||
42 | #include "../sst-mfld-platform.h" | 44 | #include "../sst-mfld-platform.h" |
43 | #include "../../common/sst-dsp.h" | 45 | #include "../../common/sst-dsp.h" |
44 | #include "../../common/sst-acpi.h" | 46 | #include "../../common/sst-acpi.h" |
@@ -113,6 +115,28 @@ static const struct sst_res_info byt_rvp_res_info = { | |||
113 | .acpi_ipc_irq_index = 5, | 115 | .acpi_ipc_irq_index = 5, |
114 | }; | 116 | }; |
115 | 117 | ||
118 | /* BYTCR has different BIOS from BYT */ | ||
119 | static const struct sst_res_info bytcr_res_info = { | ||
120 | .shim_offset = 0x140000, | ||
121 | .shim_size = 0x000100, | ||
122 | .shim_phy_addr = SST_BYT_SHIM_PHY_ADDR, | ||
123 | .ssp0_offset = 0xa0000, | ||
124 | .ssp0_size = 0x1000, | ||
125 | .dma0_offset = 0x98000, | ||
126 | .dma0_size = 0x4000, | ||
127 | .dma1_offset = 0x9c000, | ||
128 | .dma1_size = 0x4000, | ||
129 | .iram_offset = 0x0c0000, | ||
130 | .iram_size = 0x14000, | ||
131 | .dram_offset = 0x100000, | ||
132 | .dram_size = 0x28000, | ||
133 | .mbox_offset = 0x144000, | ||
134 | .mbox_size = 0x1000, | ||
135 | .acpi_lpe_res_index = 0, | ||
136 | .acpi_ddr_index = 2, | ||
137 | .acpi_ipc_irq_index = 0 | ||
138 | }; | ||
139 | |||
116 | static struct sst_platform_info byt_rvp_platform_data = { | 140 | static struct sst_platform_info byt_rvp_platform_data = { |
117 | .probe_data = &byt_fwparse_info, | 141 | .probe_data = &byt_fwparse_info, |
118 | .ipc_info = &byt_ipc_info, | 142 | .ipc_info = &byt_ipc_info, |
@@ -215,6 +239,47 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
215 | return 0; | 239 | return 0; |
216 | } | 240 | } |
217 | 241 | ||
242 | |||
243 | static int is_byt_cr(struct device *dev, bool *bytcr) | ||
244 | { | ||
245 | int status = 0; | ||
246 | |||
247 | if (IS_ENABLED(CONFIG_IOSF_MBI)) { | ||
248 | static const struct x86_cpu_id cpu_ids[] __initconst = { | ||
249 | { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */ | ||
250 | {} | ||
251 | }; | ||
252 | int status; | ||
253 | u32 bios_status; | ||
254 | |||
255 | if (!x86_match_cpu(cpu_ids) || !iosf_mbi_available()) { | ||
256 | /* bail silently */ | ||
257 | return status; | ||
258 | } | ||
259 | |||
260 | status = iosf_mbi_read(BT_MBI_UNIT_PMC, /* 0x04 PUNIT */ | ||
261 | MBI_REG_READ, /* 0x10 */ | ||
262 | 0x006, /* BIOS_CONFIG */ | ||
263 | &bios_status); | ||
264 | |||
265 | if (status) { | ||
266 | dev_err(dev, "could not read PUNIT BIOS_CONFIG\n"); | ||
267 | } else { | ||
268 | /* bits 26:27 mirror PMIC options */ | ||
269 | bios_status = (bios_status >> 26) & 3; | ||
270 | |||
271 | if ((bios_status == 1) || (bios_status == 3)) | ||
272 | *bytcr = true; | ||
273 | else | ||
274 | dev_info(dev, "BYT-CR not detected\n"); | ||
275 | } | ||
276 | } else { | ||
277 | dev_info(dev, "IOSF_MBI not enabled, no BYT-CR detection\n"); | ||
278 | } | ||
279 | return status; | ||
280 | } | ||
281 | |||
282 | |||
218 | static int sst_acpi_probe(struct platform_device *pdev) | 283 | static int sst_acpi_probe(struct platform_device *pdev) |
219 | { | 284 | { |
220 | struct device *dev = &pdev->dev; | 285 | struct device *dev = &pdev->dev; |
@@ -226,6 +291,7 @@ static int sst_acpi_probe(struct platform_device *pdev) | |||
226 | struct platform_device *plat_dev; | 291 | struct platform_device *plat_dev; |
227 | struct sst_platform_info *pdata; | 292 | struct sst_platform_info *pdata; |
228 | unsigned int dev_id; | 293 | unsigned int dev_id; |
294 | bool bytcr = false; | ||
229 | 295 | ||
230 | id = acpi_match_device(dev->driver->acpi_match_table, dev); | 296 | id = acpi_match_device(dev->driver->acpi_match_table, dev); |
231 | if (!id) | 297 | if (!id) |
@@ -251,6 +317,18 @@ static int sst_acpi_probe(struct platform_device *pdev) | |||
251 | 317 | ||
252 | dev_dbg(dev, "ACPI device id: %x\n", dev_id); | 318 | dev_dbg(dev, "ACPI device id: %x\n", dev_id); |
253 | 319 | ||
320 | ret = sst_alloc_drv_context(&ctx, dev, dev_id); | ||
321 | if (ret < 0) | ||
322 | return ret; | ||
323 | |||
324 | ret = is_byt_cr(dev, &bytcr); | ||
325 | if (!((ret < 0) || (bytcr == false))) { | ||
326 | dev_info(dev, "Detected Baytrail-CR platform\n"); | ||
327 | |||
328 | /* override resource info */ | ||
329 | byt_rvp_platform_data.res_info = &bytcr_res_info; | ||
330 | } | ||
331 | |||
254 | plat_dev = platform_device_register_data(dev, pdata->platform, -1, | 332 | plat_dev = platform_device_register_data(dev, pdata->platform, -1, |
255 | NULL, 0); | 333 | NULL, 0); |
256 | if (IS_ERR(plat_dev)) { | 334 | if (IS_ERR(plat_dev)) { |
@@ -271,10 +349,6 @@ static int sst_acpi_probe(struct platform_device *pdev) | |||
271 | return PTR_ERR(mdev); | 349 | return PTR_ERR(mdev); |
272 | } | 350 | } |
273 | 351 | ||
274 | ret = sst_alloc_drv_context(&ctx, dev, dev_id); | ||
275 | if (ret < 0) | ||
276 | return ret; | ||
277 | |||
278 | /* Fill sst platform data */ | 352 | /* Fill sst platform data */ |
279 | ctx->pdata = pdata; | 353 | ctx->pdata = pdata; |
280 | strcpy(ctx->firmware_name, mach->fw_filename); | 354 | strcpy(ctx->firmware_name, mach->fw_filename); |