sst_pci.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * sst_pci.c - SST (LPE) driver init file for pci enumeration.
  3. *
  4. * Copyright (C) 2008-14 Intel Corp
  5. * Authors: Vinod Koul <vinod.koul@intel.com>
  6. * Harsha Priya <priya.harsha@intel.com>
  7. * Dharageswari R <dharageswari.r@intel.com>
  8. * KP Jeeja <jeeja.kp@intel.com>
  9. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; version 2 of the License.
  14. *
  15. * This program is distributed in the hope that it will be useful, but
  16. * WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  18. * General Public License for more details.
  19. *
  20. * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  21. */
  22. #include <linux/module.h>
  23. #include <linux/pci.h>
  24. #include <linux/fs.h>
  25. #include <linux/firmware.h>
  26. #include <linux/pm_runtime.h>
  27. #include <sound/core.h>
  28. #include <sound/soc.h>
  29. #include <asm/platform_sst_audio.h>
  30. #include "../sst-mfld-platform.h"
  31. #include "sst.h"
  32. static int sst_platform_get_resources(struct intel_sst_drv *ctx)
  33. {
  34. int ddr_base, ret = 0;
  35. struct pci_dev *pci = ctx->pci;
  36. ret = pci_request_regions(pci, SST_DRV_NAME);
  37. if (ret)
  38. return ret;
  39. /* map registers */
  40. /* DDR base */
  41. if (ctx->dev_id == SST_MRFLD_PCI_ID) {
  42. ctx->ddr_base = pci_resource_start(pci, 0);
  43. /* check that the relocated IMR base matches with FW Binary */
  44. ddr_base = relocate_imr_addr_mrfld(ctx->ddr_base);
  45. if (!ctx->pdata->lib_info) {
  46. dev_err(ctx->dev, "lib_info pointer NULL\n");
  47. ret = -EINVAL;
  48. goto do_release_regions;
  49. }
  50. if (ddr_base != ctx->pdata->lib_info->mod_base) {
  51. dev_err(ctx->dev,
  52. "FW LSP DDR BASE does not match with IFWI\n");
  53. ret = -EINVAL;
  54. goto do_release_regions;
  55. }
  56. ctx->ddr_end = pci_resource_end(pci, 0);
  57. ctx->ddr = pcim_iomap(pci, 0,
  58. pci_resource_len(pci, 0));
  59. if (!ctx->ddr) {
  60. ret = -EINVAL;
  61. goto do_release_regions;
  62. }
  63. dev_dbg(ctx->dev, "sst: DDR Ptr %p\n", ctx->ddr);
  64. } else {
  65. ctx->ddr = NULL;
  66. }
  67. /* SHIM */
  68. ctx->shim_phy_add = pci_resource_start(pci, 1);
  69. ctx->shim = pcim_iomap(pci, 1, pci_resource_len(pci, 1));
  70. if (!ctx->shim) {
  71. ret = -EINVAL;
  72. goto do_release_regions;
  73. }
  74. dev_dbg(ctx->dev, "SST Shim Ptr %p\n", ctx->shim);
  75. /* Shared SRAM */
  76. ctx->mailbox_add = pci_resource_start(pci, 2);
  77. ctx->mailbox = pcim_iomap(pci, 2, pci_resource_len(pci, 2));
  78. if (!ctx->mailbox) {
  79. ret = -EINVAL;
  80. goto do_release_regions;
  81. }
  82. dev_dbg(ctx->dev, "SRAM Ptr %p\n", ctx->mailbox);
  83. /* IRAM */
  84. ctx->iram_end = pci_resource_end(pci, 3);
  85. ctx->iram_base = pci_resource_start(pci, 3);
  86. ctx->iram = pcim_iomap(pci, 3, pci_resource_len(pci, 3));
  87. if (!ctx->iram) {
  88. ret = -EINVAL;
  89. goto do_release_regions;
  90. }
  91. dev_dbg(ctx->dev, "IRAM Ptr %p\n", ctx->iram);
  92. /* DRAM */
  93. ctx->dram_end = pci_resource_end(pci, 4);
  94. ctx->dram_base = pci_resource_start(pci, 4);
  95. ctx->dram = pcim_iomap(pci, 4, pci_resource_len(pci, 4));
  96. if (!ctx->dram) {
  97. ret = -EINVAL;
  98. goto do_release_regions;
  99. }
  100. dev_dbg(ctx->dev, "DRAM Ptr %p\n", ctx->dram);
  101. do_release_regions:
  102. pci_release_regions(pci);
  103. return 0;
  104. }
  105. /*
  106. * intel_sst_probe - PCI probe function
  107. *
  108. * @pci: PCI device structure
  109. * @pci_id: PCI device ID structure
  110. *
  111. */
  112. static int intel_sst_probe(struct pci_dev *pci,
  113. const struct pci_device_id *pci_id)
  114. {
  115. int ret = 0;
  116. struct intel_sst_drv *sst_drv_ctx;
  117. struct sst_platform_info *sst_pdata = pci->dev.platform_data;
  118. dev_dbg(&pci->dev, "Probe for DID %x\n", pci->device);
  119. ret = sst_alloc_drv_context(&sst_drv_ctx, &pci->dev, pci->device);
  120. if (ret < 0)
  121. return ret;
  122. sst_drv_ctx->pdata = sst_pdata;
  123. sst_drv_ctx->irq_num = pci->irq;
  124. snprintf(sst_drv_ctx->firmware_name, sizeof(sst_drv_ctx->firmware_name),
  125. "/*(DEBLOBBED)*/");
  126. ret = sst_context_init(sst_drv_ctx);
  127. if (ret < 0)
  128. return ret;
  129. /* Init the device */
  130. ret = pcim_enable_device(pci);
  131. if (ret) {
  132. dev_err(sst_drv_ctx->dev,
  133. "device can't be enabled. Returned err: %d\n", ret);
  134. goto do_free_drv_ctx;
  135. }
  136. sst_drv_ctx->pci = pci_dev_get(pci);
  137. ret = sst_platform_get_resources(sst_drv_ctx);
  138. if (ret < 0)
  139. goto do_free_drv_ctx;
  140. pci_set_drvdata(pci, sst_drv_ctx);
  141. sst_configure_runtime_pm(sst_drv_ctx);
  142. return ret;
  143. do_free_drv_ctx:
  144. sst_context_cleanup(sst_drv_ctx);
  145. dev_err(sst_drv_ctx->dev, "Probe failed with %d\n", ret);
  146. return ret;
  147. }
  148. /**
  149. * intel_sst_remove - PCI remove function
  150. *
  151. * @pci: PCI device structure
  152. *
  153. * This function is called by OS when a device is unloaded
  154. * This frees the interrupt etc
  155. */
  156. static void intel_sst_remove(struct pci_dev *pci)
  157. {
  158. struct intel_sst_drv *sst_drv_ctx = pci_get_drvdata(pci);
  159. sst_context_cleanup(sst_drv_ctx);
  160. pci_dev_put(sst_drv_ctx->pci);
  161. pci_release_regions(pci);
  162. pci_set_drvdata(pci, NULL);
  163. }
  164. /* PCI Routines */
  165. static struct pci_device_id intel_sst_ids[] = {
  166. { PCI_VDEVICE(INTEL, SST_MRFLD_PCI_ID), 0},
  167. { 0, }
  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. module_pci_driver(sst_driver);
  181. MODULE_DESCRIPTION("Intel (R) SST(R) Audio Engine PCI Driver");
  182. MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
  183. MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
  184. MODULE_AUTHOR("Dharageswari R <dharageswari.r@intel.com>");
  185. MODULE_AUTHOR("KP Jeeja <jeeja.kp@intel.com>");
  186. MODULE_LICENSE("GPL v2");
  187. MODULE_ALIAS("sst");