cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

byt.c (13141B)


      1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
      2//
      3// This file is provided under a dual BSD/GPLv2 license.  When using or
      4// redistributing this file, you may do so under either license.
      5//
      6// Copyright(c) 2018 Intel Corporation. All rights reserved.
      7//
      8// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
      9//
     10
     11/*
     12 * Hardware interface for audio DSP on Baytrail, Braswell and Cherrytrail.
     13 */
     14
     15#include <linux/module.h>
     16#include <sound/sof.h>
     17#include <sound/sof/xtensa.h>
     18#include <sound/soc-acpi.h>
     19#include <sound/soc-acpi-intel-match.h>
     20#include <sound/intel-dsp-config.h>
     21#include "../ops.h"
     22#include "atom.h"
     23#include "shim.h"
     24#include "../sof-acpi-dev.h"
     25#include "../sof-audio.h"
     26#include "../../intel/common/soc-intel-quirks.h"
     27
     28static const struct snd_sof_debugfs_map byt_debugfs[] = {
     29	{"dmac0", DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
     30	 SOF_DEBUGFS_ACCESS_ALWAYS},
     31	{"dmac1", DSP_BAR, DMAC1_OFFSET, DMAC_SIZE,
     32	 SOF_DEBUGFS_ACCESS_ALWAYS},
     33	{"ssp0", DSP_BAR, SSP0_OFFSET, SSP_SIZE,
     34	 SOF_DEBUGFS_ACCESS_ALWAYS},
     35	{"ssp1", DSP_BAR, SSP1_OFFSET, SSP_SIZE,
     36	 SOF_DEBUGFS_ACCESS_ALWAYS},
     37	{"ssp2", DSP_BAR, SSP2_OFFSET, SSP_SIZE,
     38	 SOF_DEBUGFS_ACCESS_ALWAYS},
     39	{"iram", DSP_BAR, IRAM_OFFSET, IRAM_SIZE,
     40	 SOF_DEBUGFS_ACCESS_D0_ONLY},
     41	{"dram", DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
     42	 SOF_DEBUGFS_ACCESS_D0_ONLY},
     43	{"shim", DSP_BAR, SHIM_OFFSET, SHIM_SIZE_BYT,
     44	 SOF_DEBUGFS_ACCESS_ALWAYS},
     45};
     46
     47static const struct snd_sof_debugfs_map cht_debugfs[] = {
     48	{"dmac0", DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
     49	 SOF_DEBUGFS_ACCESS_ALWAYS},
     50	{"dmac1", DSP_BAR, DMAC1_OFFSET, DMAC_SIZE,
     51	 SOF_DEBUGFS_ACCESS_ALWAYS},
     52	{"dmac2", DSP_BAR, DMAC2_OFFSET, DMAC_SIZE,
     53	 SOF_DEBUGFS_ACCESS_ALWAYS},
     54	{"ssp0", DSP_BAR, SSP0_OFFSET, SSP_SIZE,
     55	 SOF_DEBUGFS_ACCESS_ALWAYS},
     56	{"ssp1", DSP_BAR, SSP1_OFFSET, SSP_SIZE,
     57	 SOF_DEBUGFS_ACCESS_ALWAYS},
     58	{"ssp2", DSP_BAR, SSP2_OFFSET, SSP_SIZE,
     59	 SOF_DEBUGFS_ACCESS_ALWAYS},
     60	{"ssp3", DSP_BAR, SSP3_OFFSET, SSP_SIZE,
     61	 SOF_DEBUGFS_ACCESS_ALWAYS},
     62	{"ssp4", DSP_BAR, SSP4_OFFSET, SSP_SIZE,
     63	 SOF_DEBUGFS_ACCESS_ALWAYS},
     64	{"ssp5", DSP_BAR, SSP5_OFFSET, SSP_SIZE,
     65	 SOF_DEBUGFS_ACCESS_ALWAYS},
     66	{"iram", DSP_BAR, IRAM_OFFSET, IRAM_SIZE,
     67	 SOF_DEBUGFS_ACCESS_D0_ONLY},
     68	{"dram", DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
     69	 SOF_DEBUGFS_ACCESS_D0_ONLY},
     70	{"shim", DSP_BAR, SHIM_OFFSET, SHIM_SIZE_CHT,
     71	 SOF_DEBUGFS_ACCESS_ALWAYS},
     72};
     73
     74static void byt_reset_dsp_disable_int(struct snd_sof_dev *sdev)
     75{
     76	/* Disable Interrupt from both sides */
     77	snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX, 0x3, 0x3);
     78	snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRD, 0x3, 0x3);
     79
     80	/* Put DSP into reset, set reset vector */
     81	snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_CSR,
     82				  SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL,
     83				  SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL);
     84}
     85
     86static int byt_suspend(struct snd_sof_dev *sdev, u32 target_state)
     87{
     88	byt_reset_dsp_disable_int(sdev);
     89
     90	return 0;
     91}
     92
     93static int byt_resume(struct snd_sof_dev *sdev)
     94{
     95	/* enable BUSY and disable DONE Interrupt by default */
     96	snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX,
     97				  SHIM_IMRX_BUSY | SHIM_IMRX_DONE,
     98				  SHIM_IMRX_DONE);
     99
    100	return 0;
    101}
    102
    103static int byt_remove(struct snd_sof_dev *sdev)
    104{
    105	byt_reset_dsp_disable_int(sdev);
    106
    107	return 0;
    108}
    109
    110static int byt_acpi_probe(struct snd_sof_dev *sdev)
    111{
    112	struct snd_sof_pdata *pdata = sdev->pdata;
    113	const struct sof_dev_desc *desc = pdata->desc;
    114	struct platform_device *pdev =
    115		container_of(sdev->dev, struct platform_device, dev);
    116	const struct sof_intel_dsp_desc *chip;
    117	struct resource *mmio;
    118	u32 base, size;
    119	int ret;
    120
    121	chip = get_chip_info(sdev->pdata);
    122	if (!chip) {
    123		dev_err(sdev->dev, "error: no such device supported\n");
    124		return -EIO;
    125	}
    126
    127	sdev->num_cores = chip->cores_num;
    128
    129	/* DSP DMA can only access low 31 bits of host memory */
    130	ret = dma_coerce_mask_and_coherent(sdev->dev, DMA_BIT_MASK(31));
    131	if (ret < 0) {
    132		dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret);
    133		return ret;
    134	}
    135
    136	/* LPE base */
    137	mmio = platform_get_resource(pdev, IORESOURCE_MEM,
    138				     desc->resindex_lpe_base);
    139	if (mmio) {
    140		base = mmio->start;
    141		size = resource_size(mmio);
    142	} else {
    143		dev_err(sdev->dev, "error: failed to get LPE base at idx %d\n",
    144			desc->resindex_lpe_base);
    145		return -EINVAL;
    146	}
    147
    148	dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
    149	sdev->bar[DSP_BAR] = devm_ioremap(sdev->dev, base, size);
    150	if (!sdev->bar[DSP_BAR]) {
    151		dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n",
    152			base, size);
    153		return -ENODEV;
    154	}
    155	dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[DSP_BAR]);
    156
    157	/* TODO: add offsets */
    158	sdev->mmio_bar = DSP_BAR;
    159	sdev->mailbox_bar = DSP_BAR;
    160
    161	/* IMR base - optional */
    162	if (desc->resindex_imr_base == -1)
    163		goto irq;
    164
    165	mmio = platform_get_resource(pdev, IORESOURCE_MEM,
    166				     desc->resindex_imr_base);
    167	if (mmio) {
    168		base = mmio->start;
    169		size = resource_size(mmio);
    170	} else {
    171		dev_err(sdev->dev, "error: failed to get IMR base at idx %d\n",
    172			desc->resindex_imr_base);
    173		return -ENODEV;
    174	}
    175
    176	/* some BIOSes don't map IMR */
    177	if (base == 0x55aa55aa || base == 0x0) {
    178		dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n");
    179		goto irq;
    180	}
    181
    182	dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size);
    183	sdev->bar[IMR_BAR] = devm_ioremap(sdev->dev, base, size);
    184	if (!sdev->bar[IMR_BAR]) {
    185		dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n",
    186			base, size);
    187		return -ENODEV;
    188	}
    189	dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[IMR_BAR]);
    190
    191irq:
    192	/* register our IRQ */
    193	sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc);
    194	if (sdev->ipc_irq < 0)
    195		return sdev->ipc_irq;
    196
    197	dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
    198	ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
    199					atom_irq_handler, atom_irq_thread,
    200					IRQF_SHARED, "AudioDSP", sdev);
    201	if (ret < 0) {
    202		dev_err(sdev->dev, "error: failed to register IRQ %d\n",
    203			sdev->ipc_irq);
    204		return ret;
    205	}
    206
    207	/* enable BUSY and disable DONE Interrupt by default */
    208	snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX,
    209				  SHIM_IMRX_BUSY | SHIM_IMRX_DONE,
    210				  SHIM_IMRX_DONE);
    211
    212	/* set default mailbox offset for FW ready message */
    213	sdev->dsp_box.offset = MBOX_OFFSET;
    214
    215	return ret;
    216}
    217
    218/* baytrail ops */
    219static struct snd_sof_dsp_ops sof_byt_ops = {
    220	/* device init */
    221	.probe		= byt_acpi_probe,
    222	.remove		= byt_remove,
    223
    224	/* DSP core boot / reset */
    225	.run		= atom_run,
    226	.reset		= atom_reset,
    227
    228	/* Register IO */
    229	.write		= sof_io_write,
    230	.read		= sof_io_read,
    231	.write64	= sof_io_write64,
    232	.read64		= sof_io_read64,
    233
    234	/* Block IO */
    235	.block_read	= sof_block_read,
    236	.block_write	= sof_block_write,
    237
    238	/* Mailbox IO */
    239	.mailbox_read	= sof_mailbox_read,
    240	.mailbox_write	= sof_mailbox_write,
    241
    242	/* doorbell */
    243	.irq_handler	= atom_irq_handler,
    244	.irq_thread	= atom_irq_thread,
    245
    246	/* ipc */
    247	.send_msg	= atom_send_msg,
    248	.get_mailbox_offset = atom_get_mailbox_offset,
    249	.get_window_offset = atom_get_window_offset,
    250
    251	.ipc_msg_data	= sof_ipc_msg_data,
    252	.set_stream_data_offset = sof_set_stream_data_offset,
    253
    254	/* machine driver */
    255	.machine_select = atom_machine_select,
    256	.machine_register = sof_machine_register,
    257	.machine_unregister = sof_machine_unregister,
    258	.set_mach_params = atom_set_mach_params,
    259
    260	/* debug */
    261	.debug_map	= byt_debugfs,
    262	.debug_map_count	= ARRAY_SIZE(byt_debugfs),
    263	.dbg_dump	= atom_dump,
    264	.debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
    265
    266	/* stream callbacks */
    267	.pcm_open	= sof_stream_pcm_open,
    268	.pcm_close	= sof_stream_pcm_close,
    269
    270	/*Firmware loading */
    271	.load_firmware	= snd_sof_load_firmware_memcpy,
    272
    273	/* PM */
    274	.suspend = byt_suspend,
    275	.resume = byt_resume,
    276
    277	/* DAI drivers */
    278	.drv = atom_dai,
    279	.num_drv = 3, /* we have only 3 SSPs on byt*/
    280
    281	/* ALSA HW info flags */
    282	.hw_info =	SNDRV_PCM_INFO_MMAP |
    283			SNDRV_PCM_INFO_MMAP_VALID |
    284			SNDRV_PCM_INFO_INTERLEAVED |
    285			SNDRV_PCM_INFO_PAUSE |
    286			SNDRV_PCM_INFO_BATCH,
    287
    288	.dsp_arch_ops = &sof_xtensa_arch_ops,
    289};
    290
    291static const struct sof_intel_dsp_desc byt_chip_info = {
    292	.cores_num = 1,
    293	.host_managed_cores_mask = 1,
    294	.hw_ip_version = SOF_INTEL_BAYTRAIL,
    295};
    296
    297/* cherrytrail and braswell ops */
    298static struct snd_sof_dsp_ops sof_cht_ops = {
    299	/* device init */
    300	.probe		= byt_acpi_probe,
    301	.remove		= byt_remove,
    302
    303	/* DSP core boot / reset */
    304	.run		= atom_run,
    305	.reset		= atom_reset,
    306
    307	/* Register IO */
    308	.write		= sof_io_write,
    309	.read		= sof_io_read,
    310	.write64	= sof_io_write64,
    311	.read64		= sof_io_read64,
    312
    313	/* Block IO */
    314	.block_read	= sof_block_read,
    315	.block_write	= sof_block_write,
    316
    317	/* Mailbox IO */
    318	.mailbox_read	= sof_mailbox_read,
    319	.mailbox_write	= sof_mailbox_write,
    320
    321	/* doorbell */
    322	.irq_handler	= atom_irq_handler,
    323	.irq_thread	= atom_irq_thread,
    324
    325	/* ipc */
    326	.send_msg	= atom_send_msg,
    327	.get_mailbox_offset = atom_get_mailbox_offset,
    328	.get_window_offset = atom_get_window_offset,
    329
    330	.ipc_msg_data	= sof_ipc_msg_data,
    331	.set_stream_data_offset = sof_set_stream_data_offset,
    332
    333	/* machine driver */
    334	.machine_select = atom_machine_select,
    335	.machine_register = sof_machine_register,
    336	.machine_unregister = sof_machine_unregister,
    337	.set_mach_params = atom_set_mach_params,
    338
    339	/* debug */
    340	.debug_map	= cht_debugfs,
    341	.debug_map_count	= ARRAY_SIZE(cht_debugfs),
    342	.dbg_dump	= atom_dump,
    343	.debugfs_add_region_item = snd_sof_debugfs_add_region_item_iomem,
    344
    345	/* stream callbacks */
    346	.pcm_open	= sof_stream_pcm_open,
    347	.pcm_close	= sof_stream_pcm_close,
    348
    349	/*Firmware loading */
    350	.load_firmware	= snd_sof_load_firmware_memcpy,
    351
    352	/* PM */
    353	.suspend = byt_suspend,
    354	.resume = byt_resume,
    355
    356	/* DAI drivers */
    357	.drv = atom_dai,
    358	/* all 6 SSPs may be available for cherrytrail */
    359	.num_drv = 6,
    360
    361	/* ALSA HW info flags */
    362	.hw_info =	SNDRV_PCM_INFO_MMAP |
    363			SNDRV_PCM_INFO_MMAP_VALID |
    364			SNDRV_PCM_INFO_INTERLEAVED |
    365			SNDRV_PCM_INFO_PAUSE |
    366			SNDRV_PCM_INFO_BATCH,
    367
    368	.dsp_arch_ops = &sof_xtensa_arch_ops,
    369};
    370
    371static const struct sof_intel_dsp_desc cht_chip_info = {
    372	.cores_num = 1,
    373	.host_managed_cores_mask = 1,
    374	.hw_ip_version = SOF_INTEL_BAYTRAIL,
    375};
    376
    377/* BYTCR uses different IRQ index */
    378static const struct sof_dev_desc sof_acpi_baytrailcr_desc = {
    379	.machines = snd_soc_acpi_intel_baytrail_machines,
    380	.resindex_lpe_base = 0,
    381	.resindex_pcicfg_base = 1,
    382	.resindex_imr_base = 2,
    383	.irqindex_host_ipc = 0,
    384	.chip_info = &byt_chip_info,
    385	.ipc_supported_mask = BIT(SOF_IPC),
    386	.ipc_default = SOF_IPC,
    387	.default_fw_path = {
    388		[SOF_IPC] = "intel/sof",
    389	},
    390	.default_tplg_path = {
    391		[SOF_IPC] = "intel/sof-tplg",
    392	},
    393	.default_fw_filename = {
    394		[SOF_IPC] = "sof-byt.ri",
    395	},
    396	.nocodec_tplg_filename = "sof-byt-nocodec.tplg",
    397	.ops = &sof_byt_ops,
    398};
    399
    400static const struct sof_dev_desc sof_acpi_baytrail_desc = {
    401	.machines = snd_soc_acpi_intel_baytrail_machines,
    402	.resindex_lpe_base = 0,
    403	.resindex_pcicfg_base = 1,
    404	.resindex_imr_base = 2,
    405	.irqindex_host_ipc = 5,
    406	.chip_info = &byt_chip_info,
    407	.ipc_supported_mask = BIT(SOF_IPC),
    408	.ipc_default = SOF_IPC,
    409	.default_fw_path = {
    410		[SOF_IPC] = "intel/sof",
    411	},
    412	.default_tplg_path = {
    413		[SOF_IPC] = "intel/sof-tplg",
    414	},
    415	.default_fw_filename = {
    416		[SOF_IPC] = "sof-byt.ri",
    417	},
    418	.nocodec_tplg_filename = "sof-byt-nocodec.tplg",
    419	.ops = &sof_byt_ops,
    420};
    421
    422static const struct sof_dev_desc sof_acpi_cherrytrail_desc = {
    423	.machines = snd_soc_acpi_intel_cherrytrail_machines,
    424	.resindex_lpe_base = 0,
    425	.resindex_pcicfg_base = 1,
    426	.resindex_imr_base = 2,
    427	.irqindex_host_ipc = 5,
    428	.chip_info = &cht_chip_info,
    429	.ipc_supported_mask = BIT(SOF_IPC),
    430	.ipc_default = SOF_IPC,
    431	.default_fw_path = {
    432		[SOF_IPC] = "intel/sof",
    433	},
    434	.default_tplg_path = {
    435		[SOF_IPC] = "intel/sof-tplg",
    436	},
    437	.default_fw_filename = {
    438		[SOF_IPC] = "sof-cht.ri",
    439	},
    440	.nocodec_tplg_filename = "sof-cht-nocodec.tplg",
    441	.ops = &sof_cht_ops,
    442};
    443
    444static const struct acpi_device_id sof_baytrail_match[] = {
    445	{ "80860F28", (unsigned long)&sof_acpi_baytrail_desc },
    446	{ "808622A8", (unsigned long)&sof_acpi_cherrytrail_desc },
    447	{ }
    448};
    449MODULE_DEVICE_TABLE(acpi, sof_baytrail_match);
    450
    451static int sof_baytrail_probe(struct platform_device *pdev)
    452{
    453	struct device *dev = &pdev->dev;
    454	const struct sof_dev_desc *desc;
    455	const struct acpi_device_id *id;
    456	int ret;
    457
    458	id = acpi_match_device(dev->driver->acpi_match_table, dev);
    459	if (!id)
    460		return -ENODEV;
    461
    462	ret = snd_intel_acpi_dsp_driver_probe(dev, id->id);
    463	if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) {
    464		dev_dbg(dev, "SOF ACPI driver not selected, aborting probe\n");
    465		return -ENODEV;
    466	}
    467
    468	desc = device_get_match_data(&pdev->dev);
    469	if (!desc)
    470		return -ENODEV;
    471
    472	if (desc == &sof_acpi_baytrail_desc && soc_intel_is_byt_cr(pdev))
    473		desc = &sof_acpi_baytrailcr_desc;
    474
    475	return sof_acpi_probe(pdev, desc);
    476}
    477
    478/* acpi_driver definition */
    479static struct platform_driver snd_sof_acpi_intel_byt_driver = {
    480	.probe = sof_baytrail_probe,
    481	.remove = sof_acpi_remove,
    482	.driver = {
    483		.name = "sof-audio-acpi-intel-byt",
    484		.pm = &sof_acpi_pm,
    485		.acpi_match_table = sof_baytrail_match,
    486	},
    487};
    488module_platform_driver(snd_sof_acpi_intel_byt_driver);
    489
    490MODULE_LICENSE("Dual BSD/GPL");
    491MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HIFI_EP_IPC);
    492MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
    493MODULE_IMPORT_NS(SND_SOC_SOF_ACPI_DEV);
    494MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_ATOM_HIFI_EP);