crypto: msm: Add multi-core crypto support

Add support for multiple crypto instances, new apis are added
to provide information on the crypto instances available.
Crypto uses RPM to enable clocks, this has the fix to rename
the clocks to use the npa node.

Change-Id: Ia568b9ee82235aa686713b039725d27492f4a8e7
Signed-off-by: William Clark <wclark@codeaurora.org>
This commit is contained in:
William Clark 2014-08-15 14:59:37 -07:00
parent d5fc7ff608
commit 249c33273d
5 changed files with 104 additions and 18 deletions

View File

@ -124,6 +124,7 @@ struct ce_hw_support {
bool use_sw_aes_ccm_algo;
bool clk_mgmt_sus_res;
unsigned int ce_device;
unsigned int ce_hw_instance;
};
/* Sha operation parameters */

View File

@ -5198,6 +5198,12 @@ static int __qce_get_device_tree_data(struct platform_device *pdev,
pr_err("Fail to get CE device information.\n");
return -EINVAL;
}
if (of_property_read_u32((&pdev->dev)->of_node,
"qcom,ce-hw-instance",
&pce_dev->ce_sps.ce_hw_instance)) {
pr_err("Fail to get CE hw instance information.\n");
return -EINVAL;
}
pce_dev->ce_sps.dest_pipe_index = 2 * pce_dev->ce_sps.pipe_pair_index;
pce_dev->ce_sps.src_pipe_index = pce_dev->ce_sps.dest_pipe_index + 1;
@ -5249,7 +5255,6 @@ err_getting_bam_info:
static int __qce_init_clk(struct qce_device *pce_dev)
{
int rc = 0;
struct clk *ce_core_clk;
struct clk *ce_clk;
struct clk *ce_core_src_clk;
struct clk *ce_bus_clk;
@ -5259,8 +5264,8 @@ static int __qce_init_clk(struct qce_device *pce_dev)
if (!IS_ERR(ce_core_src_clk)) {
pce_dev->ce_core_src_clk = ce_core_src_clk;
/* Set the core src clk @100Mhz */
rc = clk_set_rate(pce_dev->ce_core_src_clk, 100000000);
/* Set the core src clk @171.43Mhz */
rc = clk_set_rate(pce_dev->ce_core_src_clk, 171430000);
if (rc) {
clk_put(pce_dev->ce_core_src_clk);
pce_dev->ce_core_src_clk = NULL;
@ -5272,17 +5277,6 @@ static int __qce_init_clk(struct qce_device *pce_dev)
pce_dev->ce_core_src_clk = NULL;
}
/* Get CE core clk */
ce_core_clk = clk_get(pce_dev->pdev, "core_clk");
if (IS_ERR(ce_core_clk)) {
rc = PTR_ERR(ce_core_clk);
pr_err("Unable to get CE core clk\n");
if (pce_dev->ce_core_src_clk != NULL)
clk_put(pce_dev->ce_core_src_clk);
goto err_clk;
}
pce_dev->ce_core_clk = ce_core_clk;
/* Get CE Interface clk */
ce_clk = clk_get(pce_dev->pdev, "iface_clk");
if (IS_ERR(ce_clk)) {
@ -5340,8 +5334,8 @@ int qce_enable_clk(void *handle)
int rc = 0;
/* Enable CE core clk */
if (pce_dev->ce_core_clk != NULL) {
rc = clk_prepare_enable(pce_dev->ce_core_clk);
if (pce_dev->ce_core_src_clk != NULL) {
rc = clk_prepare_enable(pce_dev->ce_core_src_clk);
if (rc) {
pr_err("Unable to enable/prepare CE core clk\n");
return rc;
@ -5378,8 +5372,8 @@ int qce_disable_clk(void *handle)
if (pce_dev->ce_clk != NULL)
clk_disable_unprepare(pce_dev->ce_clk);
if (pce_dev->ce_core_clk != NULL)
clk_disable_unprepare(pce_dev->ce_core_clk);
if (pce_dev->ce_core_src_clk != NULL)
clk_disable_unprepare(pce_dev->ce_core_src_clk);
if (pce_dev->ce_bus_clk != NULL)
clk_disable_unprepare(pce_dev->ce_bus_clk);
@ -5532,6 +5526,7 @@ int qce_hw_support(void *handle, struct ce_hw_support *ce_support)
ce_support->use_sw_aes_ccm_algo =
pce_dev->use_sw_aes_ccm_algo;
ce_support->ce_device = pce_dev->ce_sps.ce_device;
ce_support->ce_hw_instance = pce_dev->ce_sps.ce_hw_instance;
return 0;
}
EXPORT_SYMBOL(qce_hw_support);

View File

@ -178,6 +178,7 @@ struct ce_sps_data {
struct scatterlist *src;
struct scatterlist *dst;
uint32_t ce_device;
uint32_t ce_hw_instance;
unsigned int pipe_pair_index;
unsigned int src_pipe_index;
unsigned int dest_pipe_index;

View File

@ -129,6 +129,7 @@ struct crypto_engine {
u64 err_req;
u32 unit;
u32 ce_device;
u32 ce_hw_instance;
unsigned int signature;
enum qcrypto_bus_state bw_state;
@ -230,6 +231,63 @@ static struct crypto_engine *_qrypto_find_pengine_device(struct crypto_priv *cp,
return entry;
}
static struct crypto_engine *_qrypto_find_pengine_device_hw
(struct crypto_priv *cp,
u32 device,
u32 hw_instance)
{
struct crypto_engine *entry = NULL;
unsigned long flags;
spin_lock_irqsave(&cp->lock, flags);
list_for_each_entry(entry, &cp->engine_list, elist) {
if ((entry->ce_device == device) &&
(entry->ce_hw_instance == hw_instance))
break;
}
spin_unlock_irqrestore(&cp->lock, flags);
if (((entry != NULL) &&
((entry->ce_device != device)
|| (entry->ce_hw_instance != hw_instance)))
|| (entry == NULL)) {
pr_err("Device node for CE device %d NOT FOUND!!\n",
device);
return NULL;
}
return entry;
}
int qcrypto_get_num_engines()
{
struct crypto_priv *cp = &qcrypto_dev;
struct crypto_engine *entry = NULL;
int count = 0;
list_for_each_entry(entry, &cp->engine_list, elist) {
count++;
}
return count;
}
EXPORT_SYMBOL(qcrypto_get_num_engines);
void qcrypto_get_engine_list(size_t num_engines,
struct crypto_engine_entry *arr)
{
struct crypto_priv *cp = &qcrypto_dev;
struct crypto_engine *entry = NULL;
size_t arr_index = 0;
list_for_each_entry(entry, &cp->engine_list, elist) {
arr[arr_index].ce_device = entry->ce_device;
arr[arr_index].hw_instance = entry->ce_hw_instance;
arr_index++;
if (arr_index >= num_engines)
break;
}
}
EXPORT_SYMBOL(qcrypto_get_engine_list);
static void qcrypto_unlock_ce(struct work_struct *work)
{
int response = 0;
@ -3826,6 +3884,22 @@ int qcrypto_cipher_set_device(struct ablkcipher_request *req, unsigned int dev)
};
EXPORT_SYMBOL(qcrypto_cipher_set_device);
int qcrypto_cipher_set_device_hw(struct ablkcipher_request *req, u32 dev,
u32 hw_inst)
{
struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
struct crypto_priv *cp = ctx->cp;
struct crypto_engine *pengine = NULL;
pengine = _qrypto_find_pengine_device_hw(cp, dev, hw_inst);
if (pengine == NULL)
return -ENODEV;
ctx->pengine = pengine;
return 0;
}
EXPORT_SYMBOL(qcrypto_cipher_set_device_hw);
int qcrypto_aead_set_device(struct aead_request *req, unsigned int dev)
{
struct qcrypto_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
@ -4524,6 +4598,7 @@ static int _qcrypto_probe(struct platform_device *pdev)
spin_unlock_irqrestore(&cp->lock, flags);
qce_hw_support(pengine->qce, &cp->ce_support);
pengine->ce_hw_instance = cp->ce_support.ce_hw_instance;
if (cp->ce_support.bam) {
cp->platform_support.ce_shared = cp->ce_support.is_shared;
cp->platform_support.shared_ce_resource = 0;

View File

@ -38,4 +38,18 @@ int qcrypto_cipher_clear_flag(struct ablkcipher_request *req,
int qcrypto_ahash_clear_flag(struct ahash_request *req, unsigned int flags);
int qcrypto_aead_clear_flag(struct aead_request *req, unsigned int flags);
struct crypto_engine_entry {
u32 hw_instance;
u32 ce_device;
int shared;
};
int qcrypto_get_num_engines(void);
void qcrypto_get_engine_list(size_t num_engines,
struct crypto_engine_entry *arr);
int qcrypto_cipher_set_device_hw(struct ablkcipher_request *req,
unsigned int fde_pfe,
unsigned int hw_inst);
#endif /* _DRIVERS_CRYPTO_MSM_QCRYPTO_H */