Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 249419
b: refs/heads/master
c: afe9194
h: refs/heads/master
i:
  249417: 406775b
  249415: 2503e91
v: v3
  • Loading branch information
Vinod Koul authored and Greg Kroah-Hartman committed May 10, 2011
1 parent 0af34dc commit a89bd35
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 28 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 31dea7385174596f4369f71c712f1d1006a3fa05
refs/heads/master: afe9194d58e87b38993fafb2b716a6c7756fab93
67 changes: 63 additions & 4 deletions trunk/drivers/staging/intel_sst/intel_sst.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,25 @@ static int __devinit intel_sst_probe(struct pci_dev *pci,
if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
ret = misc_register(&lpe_dev);
if (ret) {
pr_err("couldn't register misc driver\n");
pr_err("couldn't register LPE device\n");
goto do_free_misc;
}
} else if (sst_drv_ctx->pci_id == SST_MFLD_PCI_ID) {
u32 csr;

/*allocate mem for fw context save during suspend*/
sst_drv_ctx->fw_cntx = kzalloc(FW_CONTEXT_MEM, GFP_KERNEL);
if (!sst_drv_ctx->fw_cntx) {
ret = -ENOMEM;
goto do_free_misc;
}
/*setting zero as that is valid mem to restore*/
sst_drv_ctx->fw_cntx_size = 0;

/*set lpe start clock and ram size*/
csr = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
csr |= 0x30060; /*remove the clock ratio after fw fix*/
sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr);
}
sst_drv_ctx->lpe_stalled = 0;
pm_runtime_set_active(&pci->dev);
Expand Down Expand Up @@ -374,16 +390,17 @@ static void __devexit intel_sst_remove(struct pci_dev *pci)
sst_drv_ctx->sst_state = SST_UN_INIT;
mutex_unlock(&sst_drv_ctx->sst_lock);
misc_deregister(&lpe_ctrl);
if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)
misc_deregister(&lpe_dev);
free_irq(pci->irq, sst_drv_ctx);
iounmap(sst_drv_ctx->dram);
iounmap(sst_drv_ctx->iram);
iounmap(sst_drv_ctx->mailbox);
iounmap(sst_drv_ctx->shim);
sst_drv_ctx->pmic_state = SND_MAD_UN_INIT;
if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)
if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
misc_deregister(&lpe_dev);
kfree(sst_drv_ctx->mmap_mem);
} else
kfree(sst_drv_ctx->fw_cntx);
flush_scheduled_work();
destroy_workqueue(sst_drv_ctx->process_reply_wq);
destroy_workqueue(sst_drv_ctx->process_msg_wq);
Expand All @@ -398,6 +415,46 @@ static void __devexit intel_sst_remove(struct pci_dev *pci)
pci_set_drvdata(pci, NULL);
}

void sst_save_dsp_context(void)
{
struct snd_sst_ctxt_params fw_context;
unsigned int pvt_id, i;
struct ipc_post *msg = NULL;

/*check cpu type*/
if (sst_drv_ctx->pci_id != SST_MFLD_PCI_ID)
return;
/*not supported for rest*/
if (sst_drv_ctx->sst_state != SST_FW_RUNNING) {
pr_debug("fw not running no context save ...\n");
return;
}

/*send msg to fw*/
if (sst_create_large_msg(&msg))
return;
pvt_id = sst_assign_pvt_id(sst_drv_ctx);
i = sst_get_block_stream(sst_drv_ctx);
sst_drv_ctx->alloc_block[i].sst_id = pvt_id;
sst_fill_header(&msg->header, IPC_IA_GET_FW_CTXT, 1, pvt_id);
msg->header.part.data = sizeof(fw_context) + sizeof(u32);
fw_context.address = virt_to_phys((void *)sst_drv_ctx->fw_cntx);
fw_context.size = FW_CONTEXT_MEM;
memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
memcpy(msg->mailbox_data + sizeof(u32),
&fw_context, sizeof(fw_context));
spin_lock(&sst_drv_ctx->list_spin_lock);
list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
spin_unlock(&sst_drv_ctx->list_spin_lock);
sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
/*wait for reply*/
if (sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->alloc_block[i]))
pr_debug("err fw context save timeout ...\n");
sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
pr_debug("fw context saved ...\n");
return;
}

/* Power Management */
/*
* intel_sst_suspend - PCI suspend function
Expand All @@ -417,6 +474,8 @@ int intel_sst_suspend(struct pci_dev *pci, pm_message_t state)
pr_err("active streams,not able to suspend\n");
return -EBUSY;
}
/*save fw context*/
sst_save_dsp_context();
/*Assert RESET on LPE Processor*/
csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
csr.full = csr.full | 0x2;
Expand Down
9 changes: 6 additions & 3 deletions trunk/drivers/staging/intel_sst/intel_sst_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,16 @@
* Common private declarations for SST
*/

#define SST_DRIVER_VERSION "1.2.09"
#define SST_VERSION_NUM 0x1209
#define SST_DRIVER_VERSION "1.2.11"
#define SST_VERSION_NUM 0x1211

/* driver names */
#define SST_DRV_NAME "intel_sst_driver"
#define SST_MRST_PCI_ID 0x080A
#define SST_MFLD_PCI_ID 0x082F
#define PCI_ID_LENGTH 4
#define SST_SUSPEND_DELAY 2000
#define FW_CONTEXT_MEM (64*1024)

enum sst_states {
SST_FW_LOADED = 1,
Expand Down Expand Up @@ -94,7 +95,7 @@ enum sst_ram_type {
/* SST shim registers to structure mapping */
union config_status_reg {
struct {
u32 rsvd0:1;
u32 mfld_strb:1;
u32 sst_reset:1;
u32 hw_rsvd:3;
u32 sst_clk:2;
Expand Down Expand Up @@ -417,6 +418,8 @@ struct intel_sst_drv {
unsigned int audio_start;
dev_t devt_d, devt_c;
unsigned int max_streams;
unsigned int *fw_cntx;
unsigned int fw_cntx_size;
};

extern struct intel_sst_drv *sst_drv_ctx;
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/staging/intel_sst/intel_sst_drv_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,7 @@ int register_sst_card(struct intel_sst_card_ops *card)
sst_drv_ctx->pmic_state = SND_MAD_INIT_DONE;
sst_drv_ctx->rx_time_slot_status = 0; /*default AMIC*/
card->pcm_control = sst_pmic_ops.pcm_control;
sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT;
return 0;
} else {
pr_err("strcmp fail %s\n", card->module_name);
Expand All @@ -519,6 +520,7 @@ int register_sst_card(struct intel_sst_card_ops *card)
pr_err("Repeat for registration..denied\n");
return -EBADRQC;
}
sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT;
return 0;
}
EXPORT_SYMBOL_GPL(register_sst_card);
Expand Down
14 changes: 10 additions & 4 deletions trunk/drivers/staging/intel_sst/intel_sst_dsp.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ static int intel_sst_reset_dsp_medfield(void)
union config_status_reg csr;

pr_debug("Resetting the DSP in medfield\n");
csr.full = 0x048303E2;
csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
csr.full |= 0x382;
sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);

return 0;
Expand Down Expand Up @@ -109,11 +110,16 @@ static int sst_start_medfield(void)
{
union config_status_reg csr;

csr.full = 0x04830062;
csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
csr.part.bypass = 0;
sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
csr.full = 0x04830063;
csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
csr.part.mfld_strb = 1;
sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
csr.full = 0x04830061;
csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
csr.part.run_stall = 0;
csr.part.sst_reset = 0;
pr_debug("Starting the DSP_medfld %x\n", csr.full);
sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
pr_debug("Starting the DSP_medfld\n");

Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/staging/intel_sst/intel_sst_fw_ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
#define IPC_IA_GET_FW_VERSION 0x04
#define IPC_IA_GET_FW_BUILD_INF 0x05
#define IPC_IA_GET_FW_INFO 0x06
#define IPC_IA_GET_FW_CTXT 0x07
#define IPC_IA_SET_FW_CTXT 0x08

/* I2L Codec Config/control msgs */
#define IPC_IA_SET_CODEC_PARAMS 0x10
Expand Down Expand Up @@ -406,4 +408,8 @@ struct ipc_post {
char *mailbox_data;
};

struct snd_sst_ctxt_params {
u32 address; /* Physical Address in DDR where the context is stored */
u32 size; /* size of the context */
};
#endif /* __INTEL_SST_FW_IPC_H__ */
56 changes: 52 additions & 4 deletions trunk/drivers/staging/intel_sst/intel_sst_ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,37 @@ void sst_clear_interrupt(void)
sst_shim_write(sst_drv_ctx->shim, SST_IMRX, imr.full);
}

void sst_restore_fw_context(void)
{
struct snd_sst_ctxt_params fw_context;
struct ipc_post *msg = NULL;

pr_debug("restore_fw_context\n");
/*check cpu type*/
if (sst_drv_ctx->pci_id != SST_MFLD_PCI_ID)
return;
/*not supported for rest*/
if (!sst_drv_ctx->fw_cntx_size)
return;
/*nothing to restore*/
pr_debug("restoring context......\n");
/*send msg to fw*/
if (sst_create_large_msg(&msg))
return;

sst_fill_header(&msg->header, IPC_IA_SET_FW_CTXT, 1, 0);
msg->header.part.data = sizeof(fw_context) + sizeof(u32);
fw_context.address = virt_to_phys((void *)sst_drv_ctx->fw_cntx);
fw_context.size = sst_drv_ctx->fw_cntx_size;
memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
memcpy(msg->mailbox_data + sizeof(u32),
&fw_context, sizeof(fw_context));
spin_lock(&sst_drv_ctx->list_spin_lock);
list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
spin_unlock(&sst_drv_ctx->list_spin_lock);
sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
return;
}
/*
* process_fw_init - process the FW init msg
*
Expand Down Expand Up @@ -184,13 +215,13 @@ int process_fw_init(struct sst_ipc_msg_wq *msg)
sst_drv_ctx->sst_state = SST_FW_RUNNING;
sst_drv_ctx->lpe_stalled = 0;
mutex_unlock(&sst_drv_ctx->sst_lock);
pr_debug("FW Version %x.%x\n",
init->fw_version.major, init->fw_version.minor);
pr_debug("Build No %x Type %x\n",
init->fw_version.build, init->fw_version.type);
pr_debug("FW Version %02x.%02x.%02x\n", init->fw_version.major,
init->fw_version.minor, init->fw_version.build);
pr_debug("Build Type %x\n", init->fw_version.type);
pr_debug(" Build date %s Time %s\n",
init->build_info.date, init->build_info.time);
sst_wake_up_alloc_block(sst_drv_ctx, FW_DWNL_ID, retval, NULL);
sst_restore_fw_context();
return retval;
}
/**
Expand Down Expand Up @@ -615,12 +646,18 @@ void sst_process_reply(struct work_struct *work)
break;

case IPC_IA_FREE_STREAM:
str_info = &sst_drv_ctx->streams[str_id];
if (!msg->header.part.data) {
pr_debug("Stream %d freed\n", str_id);
} else {
pr_err("Free for %d ret error %x\n",
str_id, msg->header.part.data);
}
if (str_info->ctrl_blk.on == true) {
str_info->ctrl_blk.on = false;
str_info->ctrl_blk.condition = true;
wake_up(&sst_drv_ctx->wait_queue);
}
break;
case IPC_IA_ALLOC_STREAM: {
/* map to stream, call play */
Expand Down Expand Up @@ -699,6 +736,17 @@ void sst_process_reply(struct work_struct *work)
case IPC_IA_START_STREAM:
pr_debug("reply for START STREAM %x\n", msg->header.full);
break;

case IPC_IA_GET_FW_CTXT:
pr_debug("reply for get fw ctxt %x\n", msg->header.full);
if (msg->header.part.data)
sst_drv_ctx->fw_cntx_size = 0;
else
sst_drv_ctx->fw_cntx_size = *sst_drv_ctx->fw_cntx;
pr_debug("fw copied data %x\n", sst_drv_ctx->fw_cntx_size);
sst_wake_up_alloc_block(
sst_drv_ctx, str_id, msg->header.part.data, NULL);
break;
default:
/* Illegal case */
pr_err("process reply:default = %x\n", msg->header.full);
Expand Down
11 changes: 7 additions & 4 deletions trunk/drivers/staging/intel_sst/intel_sst_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <linux/pci.h>
#include <linux/firmware.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include "intel_sst_ioctl.h"
#include "intel_sst.h"
#include "intel_sst_fw_ipc.h"
Expand Down Expand Up @@ -519,10 +520,6 @@ int sst_drain_stream(int str_id)
str_info->data_blk.on = true;
retval = sst_wait_interruptible(sst_drv_ctx, &str_info->data_blk);
str_info->need_draining = false;
if (retval == -SST_ERR_INVALID_STREAM_ID) {
retval = -EINVAL;
sst_clean_stream(str_info);
}
return retval;
}

Expand Down Expand Up @@ -563,6 +560,12 @@ int sst_free_stream(int str_id)
str_info->data_blk.ret_code = 0;
wake_up(&sst_drv_ctx->wait_queue);
}
str_info->data_blk.on = true;
str_info->data_blk.condition = false;
retval = sst_wait_interruptible_timeout(sst_drv_ctx,
&str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
pr_debug("wait for free returned %d\n", retval);
msleep(100);
mutex_lock(&sst_drv_ctx->stream_lock);
sst_clean_stream(str_info);
mutex_unlock(&sst_drv_ctx->stream_lock);
Expand Down
8 changes: 2 additions & 6 deletions trunk/drivers/staging/intel_sst/intel_sst_stream_encoded.c
Original file line number Diff line number Diff line change
Expand Up @@ -363,20 +363,18 @@ int sst_parse_target(struct snd_sst_slot_info *slot)
pr_err("SST_Activate_target_fail\n");
else
pr_err("SST_Activate_target_pass\n");
return retval;
} else if (slot->action == SND_SST_PORT_PREPARE &&
slot->device_type == SND_SST_DEVICE_PCM) {
retval = sst_prepare_target(slot);
if (retval)
pr_err("SST_prepare_target_fail\n");
else
pr_err("SST_prepare_target_pass\n");
return retval;
} else {
pr_err("slot_action : %d, device_type: %d\n",
slot->action, slot->device_type);
return retval;
}
return retval;
}

int sst_send_target(struct snd_sst_target_device *target)
Expand Down Expand Up @@ -886,8 +884,7 @@ static int sst_prepare_input_buffers_rar(struct stream_info *str_info,
int *input_index, int *in_copied,
int *input_index_valid_size, int *new_entry_flag)
{
int retval = 0;
int i;
int retval = 0, i;

if (str_info->ops == STREAM_OPS_PLAYBACK_DRM) {
struct RAR_buffer rar_buffers;
Expand Down Expand Up @@ -924,7 +921,6 @@ static int sst_prepare_input_buffers_rar(struct stream_info *str_info,
return retval;
}
#endif

/*This function is used to prepare the kernel input buffers with contents
before sending for decode*/
static int sst_prepare_input_buffers(struct stream_info *str_info,
Expand Down
2 changes: 0 additions & 2 deletions trunk/drivers/staging/intel_sst/intelmid.c
Original file line number Diff line number Diff line change
Expand Up @@ -802,8 +802,6 @@ static int __devinit snd_intelmad_sst_register(
pr_err("sst card registration failed\n");
return ret_val;
}
sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT;

sst_card_vendor_id = intelmaddata->sstdrv_ops->vendor_id;
intelmaddata->pmic_status = PMIC_UNINIT;
return ret_val;
Expand Down

0 comments on commit a89bd35

Please sign in to comment.