Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 357723
b: refs/heads/master
c: 0d35583
h: refs/heads/master
i:
  357721: 4205ce7
  357719: 24e587c
v: v3
  • Loading branch information
Mark A. Greer authored and Herbert Xu committed Jan 19, 2013
1 parent 56175e3 commit 74f7599
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 34 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: b4b87a934c30fb91cbdd18ae028acdc361e1cf0f
refs/heads/master: 0d35583a13ad29af06375678daa2e11772ec9267
158 changes: 125 additions & 33 deletions trunk/drivers/crypto/omap-aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*
* Copyright (c) 2010 Nokia Corporation
* Author: Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
* Copyright (c) 2011 Texas Instruments Incorporated
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as published
Expand Down Expand Up @@ -42,10 +43,11 @@
#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end))
#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))

#define AES_REG_KEY(x) (0x1C - ((x ^ 0x01) * 0x04))
#define AES_REG_IV(x) (0x20 + ((x) * 0x04))
#define AES_REG_KEY(dd, x) ((dd)->pdata->key_ofs - \
((x ^ 0x01) * 0x04))
#define AES_REG_IV(dd, x) ((dd)->pdata->iv_ofs + ((x) * 0x04))

#define AES_REG_CTRL 0x30
#define AES_REG_CTRL(dd) ((dd)->pdata->ctrl_ofs)
#define AES_REG_CTRL_CTR_WIDTH (1 << 7)
#define AES_REG_CTRL_CTR (1 << 6)
#define AES_REG_CTRL_CBC (1 << 5)
Expand All @@ -54,23 +56,19 @@
#define AES_REG_CTRL_INPUT_READY (1 << 1)
#define AES_REG_CTRL_OUTPUT_READY (1 << 0)

#define AES_REG_DATA 0x34
#define AES_REG_DATA_N(x) (0x34 + ((x) * 0x04))
#define AES_REG_DATA_N(dd, x) ((dd)->pdata->data_ofs + ((x) * 0x04))

#define AES_REG_REV 0x44
#define AES_REG_REV_MAJOR 0xF0
#define AES_REG_REV_MINOR 0x0F
#define AES_REG_REV(dd) ((dd)->pdata->rev_ofs)

#define AES_REG_MASK 0x48
#define AES_REG_MASK(dd) ((dd)->pdata->mask_ofs)
#define AES_REG_MASK_SIDLE (1 << 6)
#define AES_REG_MASK_START (1 << 5)
#define AES_REG_MASK_DMA_OUT_EN (1 << 3)
#define AES_REG_MASK_DMA_IN_EN (1 << 2)
#define AES_REG_MASK_SOFTRESET (1 << 1)
#define AES_REG_AUTOIDLE (1 << 0)

#define AES_REG_SYSSTATUS 0x4C
#define AES_REG_SYSSTATUS_RESETDONE (1 << 0)
#define AES_REG_LENGTH_N(x) (0x54 + ((x) * 0x04))

#define DEFAULT_TIMEOUT (5*HZ)

Expand Down Expand Up @@ -98,6 +96,26 @@ struct omap_aes_reqctx {
#define OMAP_AES_QUEUE_LENGTH 1
#define OMAP_AES_CACHE_SIZE 0

struct omap_aes_pdata {
void (*trigger)(struct omap_aes_dev *dd, int length);

u32 key_ofs;
u32 iv_ofs;
u32 ctrl_ofs;
u32 data_ofs;
u32 rev_ofs;
u32 mask_ofs;

u32 dma_enable_in;
u32 dma_enable_out;
u32 dma_start;

u32 major_mask;
u32 major_shift;
u32 minor_mask;
u32 minor_shift;
};

struct omap_aes_dev {
struct list_head list;
unsigned long phys_base;
Expand Down Expand Up @@ -132,6 +150,8 @@ struct omap_aes_dev {
int dma_out;
struct dma_chan *dma_lch_out;
dma_addr_t dma_addr_out;

const struct omap_aes_pdata *pdata;
};

/* keep registered devices data here */
Expand Down Expand Up @@ -194,26 +214,16 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
if (err)
return err;

val = 0;
if (dd->dma_lch_out != NULL)
val |= AES_REG_MASK_DMA_OUT_EN;
if (dd->dma_lch_in != NULL)
val |= AES_REG_MASK_DMA_IN_EN;

mask = AES_REG_MASK_DMA_IN_EN | AES_REG_MASK_DMA_OUT_EN;

omap_aes_write_mask(dd, AES_REG_MASK, val, mask);

key32 = dd->ctx->keylen / sizeof(u32);

/* it seems a key should always be set even if it has not changed */
for (i = 0; i < key32; i++) {
omap_aes_write(dd, AES_REG_KEY(i),
omap_aes_write(dd, AES_REG_KEY(dd, i),
__le32_to_cpu(dd->ctx->key[i]));
}

if ((dd->flags & FLAGS_CBC) && dd->req->info)
omap_aes_write_n(dd, AES_REG_IV(0), dd->req->info, 4);
omap_aes_write_n(dd, AES_REG_IV(dd, 0), dd->req->info, 4);

val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3);
if (dd->flags & FLAGS_CBC)
Expand All @@ -224,11 +234,47 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd)
mask = AES_REG_CTRL_CBC | AES_REG_CTRL_DIRECTION |
AES_REG_CTRL_KEY_SIZE;

omap_aes_write_mask(dd, AES_REG_CTRL, val, mask);
omap_aes_write_mask(dd, AES_REG_CTRL(dd), val, mask);

return 0;
}

static void omap_aes_dma_trigger_omap2(struct omap_aes_dev *dd, int length)
{
u32 mask, val;

val = dd->pdata->dma_start;

if (dd->dma_lch_out != NULL)
val |= dd->pdata->dma_enable_out;
if (dd->dma_lch_in != NULL)
val |= dd->pdata->dma_enable_in;

mask = dd->pdata->dma_enable_out | dd->pdata->dma_enable_in |
dd->pdata->dma_start;

omap_aes_write_mask(dd, AES_REG_MASK(dd), val, mask);

}

static void omap_aes_dma_trigger_omap4(struct omap_aes_dev *dd, int length)
{
omap_aes_write(dd, AES_REG_LENGTH_N(0), length);
omap_aes_write(dd, AES_REG_LENGTH_N(1), 0);

omap_aes_dma_trigger_omap2(dd, length);
}

static void omap_aes_dma_stop(struct omap_aes_dev *dd)
{
u32 mask;

mask = dd->pdata->dma_enable_out | dd->pdata->dma_enable_in |
dd->pdata->dma_start;

omap_aes_write_mask(dd, AES_REG_MASK(dd), 0, mask);
}

static struct omap_aes_dev *omap_aes_find_dev(struct omap_aes_ctx *ctx)
{
struct omap_aes_dev *dd = NULL, *tmp;
Expand Down Expand Up @@ -413,8 +459,8 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm,

memset(&cfg, 0, sizeof(cfg));

cfg.src_addr = dd->phys_base + AES_REG_DATA;
cfg.dst_addr = dd->phys_base + AES_REG_DATA;
cfg.src_addr = dd->phys_base + AES_REG_DATA_N(dd, 0);
cfg.dst_addr = dd->phys_base + AES_REG_DATA_N(dd, 0);
cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
cfg.src_maxburst = DST_MAXBURST;
Expand Down Expand Up @@ -464,9 +510,8 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm,
dma_async_issue_pending(dd->dma_lch_in);
dma_async_issue_pending(dd->dma_lch_out);

/* start DMA or disable idle mode */
omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START,
AES_REG_MASK_START);
/* start DMA */
dd->pdata->trigger(dd, length);

return 0;
}
Expand Down Expand Up @@ -586,7 +631,7 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd)

pr_debug("total: %d\n", dd->total);

omap_aes_write_mask(dd, AES_REG_MASK, 0, AES_REG_MASK_START);
omap_aes_dma_stop(dd);

dmaengine_terminate_all(dd->dma_lch_in);
dmaengine_terminate_all(dd->dma_lch_out);
Expand Down Expand Up @@ -826,10 +871,48 @@ static struct crypto_alg algs[] = {
}
};

static const struct omap_aes_pdata omap_aes_pdata_omap2 = {
.trigger = omap_aes_dma_trigger_omap2,
.key_ofs = 0x1c,
.iv_ofs = 0x20,
.ctrl_ofs = 0x30,
.data_ofs = 0x34,
.rev_ofs = 0x44,
.mask_ofs = 0x48,
.dma_enable_in = BIT(2),
.dma_enable_out = BIT(3),
.dma_start = BIT(5),
.major_mask = 0xf0,
.major_shift = 4,
.minor_mask = 0x0f,
.minor_shift = 0,
};

#ifdef CONFIG_OF
static const struct omap_aes_pdata omap_aes_pdata_omap4 = {
.trigger = omap_aes_dma_trigger_omap4,
.key_ofs = 0x3c,
.iv_ofs = 0x40,
.ctrl_ofs = 0x50,
.data_ofs = 0x60,
.rev_ofs = 0x80,
.mask_ofs = 0x84,
.dma_enable_in = BIT(5),
.dma_enable_out = BIT(6),
.major_mask = 0x0700,
.major_shift = 8,
.minor_mask = 0x003f,
.minor_shift = 0,
};

static const struct of_device_id omap_aes_of_match[] = {
{
.compatible = "ti,omap2-aes",
.data = &omap_aes_pdata_omap2,
},
{
.compatible = "ti,omap4-aes",
.data = &omap_aes_pdata_omap4,
},
{},
};
Expand Down Expand Up @@ -859,6 +942,8 @@ static int omap_aes_get_res_of(struct omap_aes_dev *dd,
dd->dma_out = -1; /* Dummy value that's unused */
dd->dma_in = -1; /* Dummy value that's unused */

dd->pdata = match->data;

err:
return err;
}
Expand Down Expand Up @@ -908,6 +993,9 @@ static int omap_aes_get_res_pdev(struct omap_aes_dev *dd,
}
dd->dma_in = r->start;

/* Only OMAP2/3 can be non-DT */
dd->pdata = &omap_aes_pdata_omap2;

err:
return err;
}
Expand Down Expand Up @@ -947,12 +1035,16 @@ static int omap_aes_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);

reg = omap_aes_read(dd, AES_REG_REV);
dev_info(dev, "OMAP AES hw accel rev: %u.%u\n",
(reg & AES_REG_REV_MAJOR) >> 4, reg & AES_REG_REV_MINOR);
omap_aes_dma_stop(dd);

reg = omap_aes_read(dd, AES_REG_REV(dd));

pm_runtime_put_sync(dev);

dev_info(dev, "OMAP AES hw accel rev: %u.%u\n",
(reg & dd->pdata->major_mask) >> dd->pdata->major_shift,
(reg & dd->pdata->minor_mask) >> dd->pdata->minor_shift);

tasklet_init(&dd->done_task, omap_aes_done_task, (unsigned long)dd);
tasklet_init(&dd->queue_task, omap_aes_queue_task, (unsigned long)dd);

Expand Down

0 comments on commit 74f7599

Please sign in to comment.