aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/skylake/skl-messages.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel/skylake/skl-messages.c')
-rw-r--r--sound/soc/intel/skylake/skl-messages.c124
1 files changed, 109 insertions, 15 deletions
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c
index 4629372d7c8e..79c5089b85d6 100644
--- a/sound/soc/intel/skylake/skl-messages.c
+++ b/sound/soc/intel/skylake/skl-messages.c
@@ -72,17 +72,47 @@ static void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable)
72 skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)&mask); 72 skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)&mask);
73} 73}
74 74
75static struct skl_dsp_loader_ops skl_get_loader_ops(void)
76{
77 struct skl_dsp_loader_ops loader_ops;
78
79 memset(&loader_ops, 0, sizeof(struct skl_dsp_loader_ops));
80
81 loader_ops.alloc_dma_buf = skl_alloc_dma_buf;
82 loader_ops.free_dma_buf = skl_free_dma_buf;
83
84 return loader_ops;
85};
86
87static const struct skl_dsp_ops dsp_ops[] = {
88 {
89 .id = 0x9d70,
90 .loader_ops = skl_get_loader_ops,
91 .init = skl_sst_dsp_init,
92 .cleanup = skl_sst_dsp_cleanup
93 },
94};
95
96static int skl_get_dsp_ops(int pci_id)
97{
98 int i;
99
100 for (i = 0; i < ARRAY_SIZE(dsp_ops); i++) {
101 if (dsp_ops[i].id == pci_id)
102 return i;
103 }
104
105 return -EINVAL;
106}
107
75int skl_init_dsp(struct skl *skl) 108int skl_init_dsp(struct skl *skl)
76{ 109{
77 void __iomem *mmio_base; 110 void __iomem *mmio_base;
78 struct hdac_ext_bus *ebus = &skl->ebus; 111 struct hdac_ext_bus *ebus = &skl->ebus;
79 struct hdac_bus *bus = ebus_to_hbus(ebus); 112 struct hdac_bus *bus = ebus_to_hbus(ebus);
80 int irq = bus->irq;
81 struct skl_dsp_loader_ops loader_ops; 113 struct skl_dsp_loader_ops loader_ops;
82 int ret; 114 int irq = bus->irq;
83 115 int ret, index;
84 loader_ops.alloc_dma_buf = skl_alloc_dma_buf;
85 loader_ops.free_dma_buf = skl_free_dma_buf;
86 116
87 /* enable ppcap interrupt */ 117 /* enable ppcap interrupt */
88 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true); 118 snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
@@ -95,8 +125,14 @@ int skl_init_dsp(struct skl *skl)
95 return -ENXIO; 125 return -ENXIO;
96 } 126 }
97 127
98 ret = skl_sst_dsp_init(bus->dev, mmio_base, irq, 128 index = skl_get_dsp_ops(skl->pci->device);
129 if (index < 0)
130 return -EINVAL;
131
132 loader_ops = dsp_ops[index].loader_ops();
133 ret = dsp_ops[index].init(bus->dev, mmio_base, irq,
99 skl->fw_name, loader_ops, &skl->skl_sst); 134 skl->fw_name, loader_ops, &skl->skl_sst);
135
100 if (ret < 0) 136 if (ret < 0)
101 return ret; 137 return ret;
102 138
@@ -106,18 +142,26 @@ int skl_init_dsp(struct skl *skl)
106 return ret; 142 return ret;
107} 143}
108 144
109void skl_free_dsp(struct skl *skl) 145int skl_free_dsp(struct skl *skl)
110{ 146{
111 struct hdac_ext_bus *ebus = &skl->ebus; 147 struct hdac_ext_bus *ebus = &skl->ebus;
112 struct hdac_bus *bus = ebus_to_hbus(ebus); 148 struct hdac_bus *bus = ebus_to_hbus(ebus);
113 struct skl_sst *ctx = skl->skl_sst; 149 struct skl_sst *ctx = skl->skl_sst;
150 int index;
114 151
115 /* disable ppcap interrupt */ 152 /* disable ppcap interrupt */
116 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false); 153 snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false);
117 154
118 skl_sst_dsp_cleanup(bus->dev, ctx); 155 index = skl_get_dsp_ops(skl->pci->device);
156 if (index < 0)
157 return -EIO;
158
159 dsp_ops[index].cleanup(bus->dev, ctx);
160
119 if (ctx->dsp->addr.lpe) 161 if (ctx->dsp->addr.lpe)
120 iounmap(ctx->dsp->addr.lpe); 162 iounmap(ctx->dsp->addr.lpe);
163
164 return 0;
121} 165}
122 166
123int skl_suspend_dsp(struct skl *skl) 167int skl_suspend_dsp(struct skl *skl)
@@ -238,9 +282,8 @@ static void skl_copy_copier_caps(struct skl_module_cfg *mconfig,
238 * Calculate the gatewat settings required for copier module, type of 282 * Calculate the gatewat settings required for copier module, type of
239 * gateway and index of gateway to use 283 * gateway and index of gateway to use
240 */ 284 */
241static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx, 285static u32 skl_get_node_id(struct skl_sst *ctx,
242 struct skl_module_cfg *mconfig, 286 struct skl_module_cfg *mconfig)
243 struct skl_cpr_cfg *cpr_mconfig)
244{ 287{
245 union skl_connector_node_id node_id = {0}; 288 union skl_connector_node_id node_id = {0};
246 union skl_ssp_dma_node ssp_node = {0}; 289 union skl_ssp_dma_node ssp_node = {0};
@@ -289,13 +332,24 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
289 break; 332 break;
290 333
291 default: 334 default:
292 cpr_mconfig->gtw_cfg.node_id = SKL_NON_GATEWAY_CPR_NODE_ID; 335 node_id.val = 0xFFFFFFFF;
336 break;
337 }
338
339 return node_id.val;
340}
341
342static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
343 struct skl_module_cfg *mconfig,
344 struct skl_cpr_cfg *cpr_mconfig)
345{
346 cpr_mconfig->gtw_cfg.node_id = skl_get_node_id(ctx, mconfig);
347
348 if (cpr_mconfig->gtw_cfg.node_id == SKL_NON_GATEWAY_CPR_NODE_ID) {
293 cpr_mconfig->cpr_feature_mask = 0; 349 cpr_mconfig->cpr_feature_mask = 0;
294 return; 350 return;
295 } 351 }
296 352
297 cpr_mconfig->gtw_cfg.node_id = node_id.val;
298
299 if (SKL_CONN_SOURCE == mconfig->hw_conn_type) 353 if (SKL_CONN_SOURCE == mconfig->hw_conn_type)
300 cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->obs; 354 cpr_mconfig->gtw_cfg.dma_buffer_size = 2 * mconfig->obs;
301 else 355 else
@@ -307,6 +361,46 @@ static void skl_setup_cpr_gateway_cfg(struct skl_sst *ctx,
307 skl_copy_copier_caps(mconfig, cpr_mconfig); 361 skl_copy_copier_caps(mconfig, cpr_mconfig);
308} 362}
309 363
364#define DMA_CONTROL_ID 5
365
366int skl_dsp_set_dma_control(struct skl_sst *ctx, struct skl_module_cfg *mconfig)
367{
368 struct skl_dma_control *dma_ctrl;
369 struct skl_i2s_config_blob config_blob;
370 struct skl_ipc_large_config_msg msg = {0};
371 int err = 0;
372
373
374 /*
375 * if blob size is same as capablity size, then no dma control
376 * present so return
377 */
378 if (mconfig->formats_config.caps_size == sizeof(config_blob))
379 return 0;
380
381 msg.large_param_id = DMA_CONTROL_ID;
382 msg.param_data_size = sizeof(struct skl_dma_control) +
383 mconfig->formats_config.caps_size;
384
385 dma_ctrl = kzalloc(msg.param_data_size, GFP_KERNEL);
386 if (dma_ctrl == NULL)
387 return -ENOMEM;
388
389 dma_ctrl->node_id = skl_get_node_id(ctx, mconfig);
390
391 /* size in dwords */
392 dma_ctrl->config_length = sizeof(config_blob) / 4;
393
394 memcpy(dma_ctrl->config_data, mconfig->formats_config.caps,
395 mconfig->formats_config.caps_size);
396
397 err = skl_ipc_set_large_config(&ctx->ipc, &msg, (u32 *)dma_ctrl);
398
399 kfree(dma_ctrl);
400
401 return err;
402}
403
310static void skl_setup_out_format(struct skl_sst *ctx, 404static void skl_setup_out_format(struct skl_sst *ctx,
311 struct skl_module_cfg *mconfig, 405 struct skl_module_cfg *mconfig,
312 struct skl_audio_data_format *out_fmt) 406 struct skl_audio_data_format *out_fmt)