123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- /*
- * sst_pci.c - SST (LPE) driver init file for pci enumeration.
- *
- * Copyright (C) 2008-14 Intel Corp
- * Authors: Vinod Koul <vinod.koul@intel.com>
- * Harsha Priya <priya.harsha@intel.com>
- * Dharageswari R <dharageswari.r@intel.com>
- * KP Jeeja <jeeja.kp@intel.com>
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
- #include <linux/module.h>
- #include <linux/pci.h>
- #include <linux/fs.h>
- #include <linux/firmware.h>
- #include <linux/pm_runtime.h>
- #include <sound/core.h>
- #include <sound/soc.h>
- #include <asm/platform_sst_audio.h>
- #include "../sst-mfld-platform.h"
- #include "sst.h"
- static int sst_platform_get_resources(struct intel_sst_drv *ctx)
- {
- int ddr_base, ret = 0;
- struct pci_dev *pci = ctx->pci;
- ret = pci_request_regions(pci, SST_DRV_NAME);
- if (ret)
- return ret;
- /* map registers */
- /* DDR base */
- if (ctx->dev_id == SST_MRFLD_PCI_ID) {
- ctx->ddr_base = pci_resource_start(pci, 0);
- /* check that the relocated IMR base matches with FW Binary */
- ddr_base = relocate_imr_addr_mrfld(ctx->ddr_base);
- if (!ctx->pdata->lib_info) {
- dev_err(ctx->dev, "lib_info pointer NULL\n");
- ret = -EINVAL;
- goto do_release_regions;
- }
- if (ddr_base != ctx->pdata->lib_info->mod_base) {
- dev_err(ctx->dev,
- "FW LSP DDR BASE does not match with IFWI\n");
- ret = -EINVAL;
- goto do_release_regions;
- }
- ctx->ddr_end = pci_resource_end(pci, 0);
- ctx->ddr = pcim_iomap(pci, 0,
- pci_resource_len(pci, 0));
- if (!ctx->ddr) {
- ret = -EINVAL;
- goto do_release_regions;
- }
- dev_dbg(ctx->dev, "sst: DDR Ptr %p\n", ctx->ddr);
- } else {
- ctx->ddr = NULL;
- }
- /* SHIM */
- ctx->shim_phy_add = pci_resource_start(pci, 1);
- ctx->shim = pcim_iomap(pci, 1, pci_resource_len(pci, 1));
- if (!ctx->shim) {
- ret = -EINVAL;
- goto do_release_regions;
- }
- dev_dbg(ctx->dev, "SST Shim Ptr %p\n", ctx->shim);
- /* Shared SRAM */
- ctx->mailbox_add = pci_resource_start(pci, 2);
- ctx->mailbox = pcim_iomap(pci, 2, pci_resource_len(pci, 2));
- if (!ctx->mailbox) {
- ret = -EINVAL;
- goto do_release_regions;
- }
- dev_dbg(ctx->dev, "SRAM Ptr %p\n", ctx->mailbox);
- /* IRAM */
- ctx->iram_end = pci_resource_end(pci, 3);
- ctx->iram_base = pci_resource_start(pci, 3);
- ctx->iram = pcim_iomap(pci, 3, pci_resource_len(pci, 3));
- if (!ctx->iram) {
- ret = -EINVAL;
- goto do_release_regions;
- }
- dev_dbg(ctx->dev, "IRAM Ptr %p\n", ctx->iram);
- /* DRAM */
- ctx->dram_end = pci_resource_end(pci, 4);
- ctx->dram_base = pci_resource_start(pci, 4);
- ctx->dram = pcim_iomap(pci, 4, pci_resource_len(pci, 4));
- if (!ctx->dram) {
- ret = -EINVAL;
- goto do_release_regions;
- }
- dev_dbg(ctx->dev, "DRAM Ptr %p\n", ctx->dram);
- do_release_regions:
- pci_release_regions(pci);
- return 0;
- }
- /*
- * intel_sst_probe - PCI probe function
- *
- * @pci: PCI device structure
- * @pci_id: PCI device ID structure
- *
- */
- static int intel_sst_probe(struct pci_dev *pci,
- const struct pci_device_id *pci_id)
- {
- int ret = 0;
- struct intel_sst_drv *sst_drv_ctx;
- struct sst_platform_info *sst_pdata = pci->dev.platform_data;
- dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device);
- ret = sst_alloc_drv_context(&sst_drv_ctx, &pci->dev, pci->device);
- if (ret < 0)
- return ret;
- sst_drv_ctx->pdata = sst_pdata;
- sst_drv_ctx->irq_num = pci->irq;
- snprintf(sst_drv_ctx->firmware_name, sizeof(sst_drv_ctx->firmware_name),
- "/*(DEBLOBBED)*/");
- ret = sst_context_init(sst_drv_ctx);
- if (ret < 0)
- return ret;
- /* Init the device */
- ret = pcim_enable_device(pci);
- if (ret) {
- dev_err(sst_drv_ctx->dev,
- "device can't be enabled. Returned err: %d\n", ret);
- goto do_free_drv_ctx;
- }
- sst_drv_ctx->pci = pci_dev_get(pci);
- ret = sst_platform_get_resources(sst_drv_ctx);
- if (ret < 0)
- goto do_free_drv_ctx;
- pci_set_drvdata(pci, sst_drv_ctx);
- sst_configure_runtime_pm(sst_drv_ctx);
- return ret;
- do_free_drv_ctx:
- sst_context_cleanup(sst_drv_ctx);
- dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret);
- return ret;
- }
- /**
- * intel_sst_remove - PCI remove function
- *
- * @pci: PCI device structure
- *
- * This function is called by OS when a device is unloaded
- * This frees the interrupt etc
- */
- static void intel_sst_remove(struct pci_dev *pci)
- {
- struct intel_sst_drv *sst_drv_ctx = pci_get_drvdata(pci);
- sst_context_cleanup(sst_drv_ctx);
- pci_dev_put(sst_drv_ctx->pci);
- pci_release_regions(pci);
- pci_set_drvdata(pci, NULL);
- }
- /* PCI Routines */
- static struct pci_device_id intel_sst_ids[] = {
- { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0},
- { 0, }
- };
- static struct pci_driver sst_driver = {
- .name = SST_DRV_NAME,
- .id_table = intel_sst_ids,
- .probe = intel_sst_probe,
- .remove = intel_sst_remove,
- #ifdef CONFIG_PM
- .driver = {
- .pm = &intel_sst_pm,
- },
- #endif
- };
- module_pci_driver(sst_driver);
- MODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine PCI Driver");
- MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
- MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
- MODULE_AUTHOR("Dharageswari R <dharageswari.r@intel.com>");
- MODULE_AUTHOR("KP Jeeja <jeeja.kp@intel.com>");
- MODULE_LICENSE("GPL v2");
- MODULE_ALIAS("sst");
|