[PATCH] crypto: rockchip: Don't dequeue the request when device is busy
The device can only process one request at a time. So if multiple requests came at the same time, we can enqueue them first, and dequeue them one by one when the device is idle. Signed-off-by: zain wang <w...@rock-chips.com> --- drivers/crypto/rockchip/rk3288_crypto.c| 46 ++- drivers/crypto/rockchip/rk3288_crypto.h| 11 +- drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 118 -- drivers/crypto/rockchip/rk3288_crypto_ahash.c | 133 ++--- 4 files changed, 160 insertions(+), 148 deletions(-) diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c index 57c3783..c9d622a 100644 --- a/drivers/crypto/rockchip/rk3288_crypto.c +++ b/drivers/crypto/rockchip/rk3288_crypto.c @@ -184,15 +184,53 @@ static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) return IRQ_HANDLED; } +static int rk_crypto_enqueue(struct rk_crypto_info *dev, + struct crypto_async_request *async_req) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(>lock, flags); + ret = crypto_enqueue_request(>queue, async_req); + if (dev->busy) { + spin_unlock_irqrestore(>lock, flags); + return ret; + } + dev->busy = true; + spin_unlock_irqrestore(>lock, flags); + tasklet_schedule(>queue_task); + + return ret; +} + static void rk_crypto_queue_task_cb(unsigned long data) { struct rk_crypto_info *dev = (struct rk_crypto_info *)data; + struct crypto_async_request *async_req, *backlog; + unsigned long flags; int err = 0; dev->err = 0; + spin_lock_irqsave(>lock, flags); + backlog = crypto_get_backlog(>queue); + async_req = crypto_dequeue_request(>queue); + + if (!async_req) { + dev->busy = false; + spin_unlock_irqrestore(>lock, flags); + return; + } + spin_unlock_irqrestore(>lock, flags); + + if (backlog) { + backlog->complete(backlog, -EINPROGRESS); + backlog = NULL; + } + + dev->async_req = async_req; err = dev->start(dev); if (err) - dev->complete(dev, err); + dev->complete(dev->async_req, err); } static void rk_crypto_done_task_cb(unsigned long data) @@ -200,13 +238,13 @@ static void rk_crypto_done_task_cb(unsigned long data) struct rk_crypto_info *dev = (struct rk_crypto_info *)data; if (dev->err) { - dev->complete(dev, dev->err); + dev->complete(dev->async_req, dev->err); return; } dev->err = dev->update(dev); if (dev->err) - dev->complete(dev, dev->err); + dev->complete(dev->async_req, dev->err); } static struct rk_crypto_tmp *rk_cipher_algs[] = { @@ -365,6 +403,8 @@ static int rk_crypto_probe(struct platform_device *pdev) crypto_info->disable_clk = rk_crypto_disable_clk; crypto_info->load_data = rk_load_data; crypto_info->unload_data = rk_unload_data; + crypto_info->enqueue = rk_crypto_enqueue; + crypto_info->busy = false; err = rk_crypto_register(crypto_info); if (err) { diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h index 65ad1c2..ab6a1b4 100644 --- a/drivers/crypto/rockchip/rk3288_crypto.h +++ b/drivers/crypto/rockchip/rk3288_crypto.h @@ -192,8 +192,7 @@ struct rk_crypto_info { struct crypto_queue queue; struct tasklet_struct queue_task; struct tasklet_struct done_task; - struct ablkcipher_request *ablk_req; - struct ahash_request*ahash_req; + struct crypto_async_request *async_req; int err; /* device lock */ spinlock_t lock; @@ -210,18 +209,20 @@ struct rk_crypto_info { size_t nents; unsigned inttotal; unsigned intcount; - u32 mode; dma_addr_t addr_in; dma_addr_t addr_out; + boolbusy; int (*start)(struct rk_crypto_info *dev); int (*update)(struct rk_crypto_info *dev); - void (*complete)(struct rk_crypto_info *dev, int err); + void (*complete)(struct crypto_async_request *base, int err); int (*enable_clk)(struct rk_crypto_info *dev); void (*disable_clk)(struct rk_crypto_info *dev); int (*load_data)(struct rk_crypto_info *dev, struct scatterlist *sg_src, struct scatt
[PATCH] crypto: rockchip: Don't dequeue the request when device is busy
The device can only process one request at a time. So if multiple requests came at the same time, we can enqueue them first, and dequeue them one by one when the device is idle. Signed-off-by: zain wang --- drivers/crypto/rockchip/rk3288_crypto.c| 46 ++- drivers/crypto/rockchip/rk3288_crypto.h| 11 +- drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 118 -- drivers/crypto/rockchip/rk3288_crypto_ahash.c | 133 ++--- 4 files changed, 160 insertions(+), 148 deletions(-) diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c index 57c3783..c9d622a 100644 --- a/drivers/crypto/rockchip/rk3288_crypto.c +++ b/drivers/crypto/rockchip/rk3288_crypto.c @@ -184,15 +184,53 @@ static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) return IRQ_HANDLED; } +static int rk_crypto_enqueue(struct rk_crypto_info *dev, + struct crypto_async_request *async_req) +{ + unsigned long flags; + int ret; + + spin_lock_irqsave(>lock, flags); + ret = crypto_enqueue_request(>queue, async_req); + if (dev->busy) { + spin_unlock_irqrestore(>lock, flags); + return ret; + } + dev->busy = true; + spin_unlock_irqrestore(>lock, flags); + tasklet_schedule(>queue_task); + + return ret; +} + static void rk_crypto_queue_task_cb(unsigned long data) { struct rk_crypto_info *dev = (struct rk_crypto_info *)data; + struct crypto_async_request *async_req, *backlog; + unsigned long flags; int err = 0; dev->err = 0; + spin_lock_irqsave(>lock, flags); + backlog = crypto_get_backlog(>queue); + async_req = crypto_dequeue_request(>queue); + + if (!async_req) { + dev->busy = false; + spin_unlock_irqrestore(>lock, flags); + return; + } + spin_unlock_irqrestore(>lock, flags); + + if (backlog) { + backlog->complete(backlog, -EINPROGRESS); + backlog = NULL; + } + + dev->async_req = async_req; err = dev->start(dev); if (err) - dev->complete(dev, err); + dev->complete(dev->async_req, err); } static void rk_crypto_done_task_cb(unsigned long data) @@ -200,13 +238,13 @@ static void rk_crypto_done_task_cb(unsigned long data) struct rk_crypto_info *dev = (struct rk_crypto_info *)data; if (dev->err) { - dev->complete(dev, dev->err); + dev->complete(dev->async_req, dev->err); return; } dev->err = dev->update(dev); if (dev->err) - dev->complete(dev, dev->err); + dev->complete(dev->async_req, dev->err); } static struct rk_crypto_tmp *rk_cipher_algs[] = { @@ -365,6 +403,8 @@ static int rk_crypto_probe(struct platform_device *pdev) crypto_info->disable_clk = rk_crypto_disable_clk; crypto_info->load_data = rk_load_data; crypto_info->unload_data = rk_unload_data; + crypto_info->enqueue = rk_crypto_enqueue; + crypto_info->busy = false; err = rk_crypto_register(crypto_info); if (err) { diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h index 65ad1c2..ab6a1b4 100644 --- a/drivers/crypto/rockchip/rk3288_crypto.h +++ b/drivers/crypto/rockchip/rk3288_crypto.h @@ -192,8 +192,7 @@ struct rk_crypto_info { struct crypto_queue queue; struct tasklet_struct queue_task; struct tasklet_struct done_task; - struct ablkcipher_request *ablk_req; - struct ahash_request*ahash_req; + struct crypto_async_request *async_req; int err; /* device lock */ spinlock_t lock; @@ -210,18 +209,20 @@ struct rk_crypto_info { size_t nents; unsigned inttotal; unsigned intcount; - u32 mode; dma_addr_t addr_in; dma_addr_t addr_out; + boolbusy; int (*start)(struct rk_crypto_info *dev); int (*update)(struct rk_crypto_info *dev); - void (*complete)(struct rk_crypto_info *dev, int err); + void (*complete)(struct crypto_async_request *base, int err); int (*enable_clk)(struct rk_crypto_info *dev); void (*disable_clk)(struct rk_crypto_info *dev); int (*load_data)(struct rk_crypto_info *dev, struct scatterlist *sg_src, struct scatterlist
Re: Some ideas about tcpm driver
在 2017/8/3 21:02, Guenter Roeck 写道: On Thu, Aug 3, 2017 at 12:28 AM, Zain Wang <w...@rock-chips.com> wrote: Hi all, In recent days, I tested the fusb302 driver with tcpm. (RK3399 evb board) But I found an issues: There is not a regulator for type-c vbus power-supply in my board. The vbus is just controlled by a gpio-pin, and unable to support other voltage except 5V. gpio-regulator does not work ? Thanks for you idea, it works well with regulator-gpio. Zain But now, I can't use fusb302 driver without workaround fix. Could you fix it in next version? @Yueyao The altmode looks not complete. I can't enter DP Alt Mode now. Yes, I know. Patches welcome. And we'd like to used extcon function (used in Chrome) to link usb, dp and type-c together. Plan is to use the extcon driver (from cros-ec) to register with the type-c infrastructure. I have not thought about how to tie low level drivers (fusb/tcpm) with extcon. Ideas welcome. Guenter How do you think about it? @Guenter Thanks Zain
Re: Some ideas about tcpm driver
在 2017/8/3 21:02, Guenter Roeck 写道: On Thu, Aug 3, 2017 at 12:28 AM, Zain Wang wrote: Hi all, In recent days, I tested the fusb302 driver with tcpm. (RK3399 evb board) But I found an issues: There is not a regulator for type-c vbus power-supply in my board. The vbus is just controlled by a gpio-pin, and unable to support other voltage except 5V. gpio-regulator does not work ? Thanks for you idea, it works well with regulator-gpio. Zain But now, I can't use fusb302 driver without workaround fix. Could you fix it in next version? @Yueyao The altmode looks not complete. I can't enter DP Alt Mode now. Yes, I know. Patches welcome. And we'd like to used extcon function (used in Chrome) to link usb, dp and type-c together. Plan is to use the extcon driver (from cros-ec) to register with the type-c infrastructure. I have not thought about how to tie low level drivers (fusb/tcpm) with extcon. Ideas welcome. Guenter How do you think about it? @Guenter Thanks Zain
Some ideas about tcpm driver
Hi all, In recent days, I tested the fusb302 driver with tcpm. (RK3399 evb board) But I found an issues: There is not a regulator for type-c vbus power-supply in my board. The vbus is just controlled by a gpio-pin, and unable to support other voltage except 5V. But now, I can't use fusb302 driver without workaround fix. Could you fix it in next version? @Yueyao The altmode looks not complete. I can't enter DP Alt Mode now. And we'd like to used extcon function (used in Chrome) to link usb, dp and type-c together. How do you think about it? @Guenter Thanks Zain
Some ideas about tcpm driver
Hi all, In recent days, I tested the fusb302 driver with tcpm. (RK3399 evb board) But I found an issues: There is not a regulator for type-c vbus power-supply in my board. The vbus is just controlled by a gpio-pin, and unable to support other voltage except 5V. But now, I can't use fusb302 driver without workaround fix. Could you fix it in next version? @Yueyao The altmode looks not complete. I can't enter DP Alt Mode now. And we'd like to used extcon function (used in Chrome) to link usb, dp and type-c together. How do you think about it? @Guenter Thanks Zain
[RESEND PATCH 1/2] crypto: rockchip - move the crypto completion from interrupt context
It's illegal to call the completion function from hardirq context, it will cause runtime tests to fail. Let's build a new task (done_task) for moving update operation from hardirq context. Signed-off-by: zain wang <w...@rock-chips.com> --- drivers/crypto/rockchip/rk3288_crypto.c| 39 -- drivers/crypto/rockchip/rk3288_crypto.h| 4 ++- drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 2 +- drivers/crypto/rockchip/rk3288_crypto_ahash.c | 2 +- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c index d0f80c6..c2b1dd7 100644 --- a/drivers/crypto/rockchip/rk3288_crypto.c +++ b/drivers/crypto/rockchip/rk3288_crypto.c @@ -169,24 +169,22 @@ static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) { struct rk_crypto_info *dev = platform_get_drvdata(dev_id); u32 interrupt_status; - int err = 0; spin_lock(>lock); interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS); CRYPTO_WRITE(dev, RK_CRYPTO_INTSTS, interrupt_status); + if (interrupt_status & 0x0a) { dev_warn(dev->dev, "DMA Error\n"); - err = -EFAULT; - } else if (interrupt_status & 0x05) { - err = dev->update(dev); + dev->err = -EFAULT; } - if (err) - dev->complete(dev, err); + tasklet_schedule(>done_task); + spin_unlock(>lock); return IRQ_HANDLED; } -static void rk_crypto_tasklet_cb(unsigned long data) +static void rk_crypto_queue_task_cb(unsigned long data) { struct rk_crypto_info *dev = (struct rk_crypto_info *)data; struct crypto_async_request *async_req, *backlog; @@ -210,11 +208,26 @@ static void rk_crypto_tasklet_cb(unsigned long data) dev->ablk_req = ablkcipher_request_cast(async_req); else dev->ahash_req = ahash_request_cast(async_req); + dev->err = 0; err = dev->start(dev); if (err) dev->complete(dev, err); } +static void rk_crypto_done_task_cb(unsigned long data) +{ + struct rk_crypto_info *dev = (struct rk_crypto_info *)data; + + if (dev->err) { + dev->complete(dev, dev->err); + return; + } + + dev->err = dev->update(dev); + if (dev->err) + dev->complete(dev, dev->err); +} + static struct rk_crypto_tmp *rk_cipher_algs[] = { _ecb_aes_alg, _cbc_aes_alg, @@ -361,8 +374,10 @@ static int rk_crypto_probe(struct platform_device *pdev) crypto_info->dev = >dev; platform_set_drvdata(pdev, crypto_info); - tasklet_init(_info->crypto_tasklet, -rk_crypto_tasklet_cb, (unsigned long)crypto_info); + tasklet_init(_info->queue_task, +rk_crypto_queue_task_cb, (unsigned long)crypto_info); + tasklet_init(_info->done_task, +rk_crypto_done_task_cb, (unsigned long)crypto_info); crypto_init_queue(_info->queue, 50); crypto_info->enable_clk = rk_crypto_enable_clk; @@ -380,7 +395,8 @@ static int rk_crypto_probe(struct platform_device *pdev) return 0; err_register_alg: - tasklet_kill(_info->crypto_tasklet); + tasklet_kill(_info->queue_task); + tasklet_kill(_info->done_task); err_crypto: return err; } @@ -390,7 +406,8 @@ static int rk_crypto_remove(struct platform_device *pdev) struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev); rk_crypto_unregister(); - tasklet_kill(_tmp->crypto_tasklet); + tasklet_kill(_tmp->done_task); + tasklet_kill(_tmp->queue_task); return 0; } diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h index d7b71fe..65ad1c2 100644 --- a/drivers/crypto/rockchip/rk3288_crypto.h +++ b/drivers/crypto/rockchip/rk3288_crypto.h @@ -190,9 +190,11 @@ struct rk_crypto_info { void __iomem*reg; int irq; struct crypto_queue queue; - struct tasklet_struct crypto_tasklet; + struct tasklet_struct queue_task; + struct tasklet_struct done_task; struct ablkcipher_request *ablk_req; struct ahash_request*ahash_req; + int err; /* device lock */ spinlock_t lock; diff --git a/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c b/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c index b5a3afe..8787e44 100644 --- a/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c +++ b/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c @@ -42,7 +42,7 @@ static int rk_handle_re
[RESEND PATCH 1/2] crypto: rockchip - move the crypto completion from interrupt context
It's illegal to call the completion function from hardirq context, it will cause runtime tests to fail. Let's build a new task (done_task) for moving update operation from hardirq context. Signed-off-by: zain wang --- drivers/crypto/rockchip/rk3288_crypto.c| 39 -- drivers/crypto/rockchip/rk3288_crypto.h| 4 ++- drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 2 +- drivers/crypto/rockchip/rk3288_crypto_ahash.c | 2 +- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c index d0f80c6..c2b1dd7 100644 --- a/drivers/crypto/rockchip/rk3288_crypto.c +++ b/drivers/crypto/rockchip/rk3288_crypto.c @@ -169,24 +169,22 @@ static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) { struct rk_crypto_info *dev = platform_get_drvdata(dev_id); u32 interrupt_status; - int err = 0; spin_lock(>lock); interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS); CRYPTO_WRITE(dev, RK_CRYPTO_INTSTS, interrupt_status); + if (interrupt_status & 0x0a) { dev_warn(dev->dev, "DMA Error\n"); - err = -EFAULT; - } else if (interrupt_status & 0x05) { - err = dev->update(dev); + dev->err = -EFAULT; } - if (err) - dev->complete(dev, err); + tasklet_schedule(>done_task); + spin_unlock(>lock); return IRQ_HANDLED; } -static void rk_crypto_tasklet_cb(unsigned long data) +static void rk_crypto_queue_task_cb(unsigned long data) { struct rk_crypto_info *dev = (struct rk_crypto_info *)data; struct crypto_async_request *async_req, *backlog; @@ -210,11 +208,26 @@ static void rk_crypto_tasklet_cb(unsigned long data) dev->ablk_req = ablkcipher_request_cast(async_req); else dev->ahash_req = ahash_request_cast(async_req); + dev->err = 0; err = dev->start(dev); if (err) dev->complete(dev, err); } +static void rk_crypto_done_task_cb(unsigned long data) +{ + struct rk_crypto_info *dev = (struct rk_crypto_info *)data; + + if (dev->err) { + dev->complete(dev, dev->err); + return; + } + + dev->err = dev->update(dev); + if (dev->err) + dev->complete(dev, dev->err); +} + static struct rk_crypto_tmp *rk_cipher_algs[] = { _ecb_aes_alg, _cbc_aes_alg, @@ -361,8 +374,10 @@ static int rk_crypto_probe(struct platform_device *pdev) crypto_info->dev = >dev; platform_set_drvdata(pdev, crypto_info); - tasklet_init(_info->crypto_tasklet, -rk_crypto_tasklet_cb, (unsigned long)crypto_info); + tasklet_init(_info->queue_task, +rk_crypto_queue_task_cb, (unsigned long)crypto_info); + tasklet_init(_info->done_task, +rk_crypto_done_task_cb, (unsigned long)crypto_info); crypto_init_queue(_info->queue, 50); crypto_info->enable_clk = rk_crypto_enable_clk; @@ -380,7 +395,8 @@ static int rk_crypto_probe(struct platform_device *pdev) return 0; err_register_alg: - tasklet_kill(_info->crypto_tasklet); + tasklet_kill(_info->queue_task); + tasklet_kill(_info->done_task); err_crypto: return err; } @@ -390,7 +406,8 @@ static int rk_crypto_remove(struct platform_device *pdev) struct rk_crypto_info *crypto_tmp = platform_get_drvdata(pdev); rk_crypto_unregister(); - tasklet_kill(_tmp->crypto_tasklet); + tasklet_kill(_tmp->done_task); + tasklet_kill(_tmp->queue_task); return 0; } diff --git a/drivers/crypto/rockchip/rk3288_crypto.h b/drivers/crypto/rockchip/rk3288_crypto.h index d7b71fe..65ad1c2 100644 --- a/drivers/crypto/rockchip/rk3288_crypto.h +++ b/drivers/crypto/rockchip/rk3288_crypto.h @@ -190,9 +190,11 @@ struct rk_crypto_info { void __iomem*reg; int irq; struct crypto_queue queue; - struct tasklet_struct crypto_tasklet; + struct tasklet_struct queue_task; + struct tasklet_struct done_task; struct ablkcipher_request *ablk_req; struct ahash_request*ahash_req; + int err; /* device lock */ spinlock_t lock; diff --git a/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c b/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c index b5a3afe..8787e44 100644 --- a/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c +++ b/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c @@ -42,7 +42,7 @@ static int rk_handle_req(stru
[RESEND PATCH 2/2] crypto: rockchip - return the err code when unable dequeue the crypto request
Sometime we would unable to dequeue the crypto request, in this case, we should finish crypto and return the err code. Signed-off-by: zain wang <w...@rock-chips.com> --- drivers/crypto/rockchip/rk3288_crypto.c| 19 --- drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 15 +++ drivers/crypto/rockchip/rk3288_crypto_ahash.c | 14 ++ 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c index c2b1dd7..57c3783 100644 --- a/drivers/crypto/rockchip/rk3288_crypto.c +++ b/drivers/crypto/rockchip/rk3288_crypto.c @@ -187,27 +187,8 @@ static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) static void rk_crypto_queue_task_cb(unsigned long data) { struct rk_crypto_info *dev = (struct rk_crypto_info *)data; - struct crypto_async_request *async_req, *backlog; - unsigned long flags; int err = 0; - spin_lock_irqsave(>lock, flags); - backlog = crypto_get_backlog(>queue); - async_req = crypto_dequeue_request(>queue); - spin_unlock_irqrestore(>lock, flags); - if (!async_req) { - dev_err(dev->dev, "async_req is NULL !!\n"); - return; - } - if (backlog) { - backlog->complete(backlog, -EINPROGRESS); - backlog = NULL; - } - - if (crypto_tfm_alg_type(async_req->tfm) == CRYPTO_ALG_TYPE_ABLKCIPHER) - dev->ablk_req = ablkcipher_request_cast(async_req); - else - dev->ahash_req = ahash_request_cast(async_req); dev->err = 0; err = dev->start(dev); if (err) diff --git a/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c b/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c index 8787e44..dbe78de 100644 --- a/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c +++ b/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c @@ -25,6 +25,7 @@ static int rk_handle_req(struct rk_crypto_info *dev, struct ablkcipher_request *req) { unsigned long flags; + struct crypto_async_request *async_req, *backlog; int err; if (!IS_ALIGNED(req->nbytes, dev->align_size)) @@ -41,7 +42,21 @@ static int rk_handle_req(struct rk_crypto_info *dev, spin_lock_irqsave(>lock, flags); err = ablkcipher_enqueue_request(>queue, req); + backlog = crypto_get_backlog(>queue); + async_req = crypto_dequeue_request(>queue); spin_unlock_irqrestore(>lock, flags); + + if (!async_req) { + dev_err(dev->dev, "async_req is NULL !!\n"); + return err; + } + if (backlog) { + backlog->complete(backlog, -EINPROGRESS); + backlog = NULL; + } + + dev->ablk_req = ablkcipher_request_cast(async_req); + tasklet_schedule(>queue_task); return err; } diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c index 9b55585..ebc46e0 100644 --- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c +++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c @@ -166,6 +166,7 @@ static int rk_ahash_digest(struct ahash_request *req) { struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); struct rk_ahash_ctx *tctx = crypto_tfm_ctx(req->base.tfm); + struct crypto_async_request *async_req, *backlog; struct rk_crypto_info *dev = NULL; unsigned long flags; int ret; @@ -202,8 +203,21 @@ static int rk_ahash_digest(struct ahash_request *req) spin_lock_irqsave(>lock, flags); ret = crypto_enqueue_request(>queue, >base); + backlog = crypto_get_backlog(>queue); + async_req = crypto_dequeue_request(>queue); spin_unlock_irqrestore(>lock, flags); + if (!async_req) { + dev_err(dev->dev, "async_req is NULL !!\n"); + return ret; + } + if (backlog) { + backlog->complete(backlog, -EINPROGRESS); + backlog = NULL; + } + + dev->ahash_req = ahash_request_cast(async_req); + tasklet_schedule(>queue_task); /* -- 1.9.1
[RESEND PATCH 2/2] crypto: rockchip - return the err code when unable dequeue the crypto request
Sometime we would unable to dequeue the crypto request, in this case, we should finish crypto and return the err code. Signed-off-by: zain wang --- drivers/crypto/rockchip/rk3288_crypto.c| 19 --- drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 15 +++ drivers/crypto/rockchip/rk3288_crypto_ahash.c | 14 ++ 3 files changed, 29 insertions(+), 19 deletions(-) diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c index c2b1dd7..57c3783 100644 --- a/drivers/crypto/rockchip/rk3288_crypto.c +++ b/drivers/crypto/rockchip/rk3288_crypto.c @@ -187,27 +187,8 @@ static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) static void rk_crypto_queue_task_cb(unsigned long data) { struct rk_crypto_info *dev = (struct rk_crypto_info *)data; - struct crypto_async_request *async_req, *backlog; - unsigned long flags; int err = 0; - spin_lock_irqsave(>lock, flags); - backlog = crypto_get_backlog(>queue); - async_req = crypto_dequeue_request(>queue); - spin_unlock_irqrestore(>lock, flags); - if (!async_req) { - dev_err(dev->dev, "async_req is NULL !!\n"); - return; - } - if (backlog) { - backlog->complete(backlog, -EINPROGRESS); - backlog = NULL; - } - - if (crypto_tfm_alg_type(async_req->tfm) == CRYPTO_ALG_TYPE_ABLKCIPHER) - dev->ablk_req = ablkcipher_request_cast(async_req); - else - dev->ahash_req = ahash_request_cast(async_req); dev->err = 0; err = dev->start(dev); if (err) diff --git a/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c b/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c index 8787e44..dbe78de 100644 --- a/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c +++ b/drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c @@ -25,6 +25,7 @@ static int rk_handle_req(struct rk_crypto_info *dev, struct ablkcipher_request *req) { unsigned long flags; + struct crypto_async_request *async_req, *backlog; int err; if (!IS_ALIGNED(req->nbytes, dev->align_size)) @@ -41,7 +42,21 @@ static int rk_handle_req(struct rk_crypto_info *dev, spin_lock_irqsave(>lock, flags); err = ablkcipher_enqueue_request(>queue, req); + backlog = crypto_get_backlog(>queue); + async_req = crypto_dequeue_request(>queue); spin_unlock_irqrestore(>lock, flags); + + if (!async_req) { + dev_err(dev->dev, "async_req is NULL !!\n"); + return err; + } + if (backlog) { + backlog->complete(backlog, -EINPROGRESS); + backlog = NULL; + } + + dev->ablk_req = ablkcipher_request_cast(async_req); + tasklet_schedule(>queue_task); return err; } diff --git a/drivers/crypto/rockchip/rk3288_crypto_ahash.c b/drivers/crypto/rockchip/rk3288_crypto_ahash.c index 9b55585..ebc46e0 100644 --- a/drivers/crypto/rockchip/rk3288_crypto_ahash.c +++ b/drivers/crypto/rockchip/rk3288_crypto_ahash.c @@ -166,6 +166,7 @@ static int rk_ahash_digest(struct ahash_request *req) { struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); struct rk_ahash_ctx *tctx = crypto_tfm_ctx(req->base.tfm); + struct crypto_async_request *async_req, *backlog; struct rk_crypto_info *dev = NULL; unsigned long flags; int ret; @@ -202,8 +203,21 @@ static int rk_ahash_digest(struct ahash_request *req) spin_lock_irqsave(>lock, flags); ret = crypto_enqueue_request(>queue, >base); + backlog = crypto_get_backlog(>queue); + async_req = crypto_dequeue_request(>queue); spin_unlock_irqrestore(>lock, flags); + if (!async_req) { + dev_err(dev->dev, "async_req is NULL !!\n"); + return ret; + } + if (backlog) { + backlog->complete(backlog, -EINPROGRESS); + backlog = NULL; + } + + dev->ahash_req = ahash_request_cast(async_req); + tasklet_schedule(>queue_task); /* -- 1.9.1
[RESEND PATCH 0/2] crypto/rockchip: fix some issue which causes crypto failed
These patches fix some bugs on rockchip's crypto which would cause crypto failed. zain wang (2): crypto: rockchip - move the crypto completion from interrupt context crypto: rockchip - return the err code when unable dequeue the crypto request drivers/crypto/rockchip/rk3288_crypto.c| 58 +++--- drivers/crypto/rockchip/rk3288_crypto.h| 4 +- drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 17 ++- drivers/crypto/rockchip/rk3288_crypto_ahash.c | 16 +- 4 files changed, 62 insertions(+), 33 deletions(-) -- 1.9.1
[RESEND PATCH 0/2] crypto/rockchip: fix some issue which causes crypto failed
These patches fix some bugs on rockchip's crypto which would cause crypto failed. zain wang (2): crypto: rockchip - move the crypto completion from interrupt context crypto: rockchip - return the err code when unable dequeue the crypto request drivers/crypto/rockchip/rk3288_crypto.c| 58 +++--- drivers/crypto/rockchip/rk3288_crypto.h| 4 +- drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 17 ++- drivers/crypto/rockchip/rk3288_crypto_ahash.c | 16 +- 4 files changed, 62 insertions(+), 33 deletions(-) -- 1.9.1
Re: [PATCH] drm/bridge: analogix_dp: Don't return -EBUSY when msg->size is 0 in aux transaction
Hi Tomasz, 在 2017/2/20 10:40, Tomasz Figa 写道: Hi Zain, On Mon, Feb 13, 2017 at 6:27 PM, zain wang <w...@rock-chips.com> wrote: The analogix_dp_transfer() will return -EBUSY if num_transferred is zero. But sometimes we will send a bare address packet to start the transaction, like drm_dp_i2c_xfer() show: .. /* Send a bare address packet to start the transaction. * Zero sized messages specify an address only (bare * address) transaction. */ msg.buffer = NULL; msg.size = 0; err = drm_dp_i2c_do_msg(aux, ); .. In this case, the msg->size is zero, so the num_transferred will be zero too. We can't return -EBUSY here, let's we return num_transferred if num_transferred equals msg->size. Please see my question inline. Signed-off-by: zain wang <w...@rock-chips.com> --- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index 303083a..5384aca 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -1162,5 +1162,5 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ) msg->reply = DP_AUX_NATIVE_REPLY_ACK; - return num_transferred > 0 ? num_transferred : -EBUSY; + return (num_transferred == msg->size) ? num_transferred : -EBUSY; I might be missing something but, looking at the code, I don't see any possibility of num_transferred ever being different than msg->size. To be honest, it doesn't seem to even make any sense keeping the local variable there, because msg->size can be simply always returned, as errors are handled by jumping to aux_error label. Yeah, I agree with you. The better way to fix this issue is to revert the changes https://patchwork.kernel.org/patch/9411711/ (returning num_transferred directly may be better here) Maybe we can revert the changes above with some new comment. @Sean, How do you think about Tomasz's comment? Thanks Zain Best regards, Tomasz
Re: [PATCH] drm/bridge: analogix_dp: Don't return -EBUSY when msg->size is 0 in aux transaction
Hi Tomasz, 在 2017/2/20 10:40, Tomasz Figa 写道: Hi Zain, On Mon, Feb 13, 2017 at 6:27 PM, zain wang wrote: The analogix_dp_transfer() will return -EBUSY if num_transferred is zero. But sometimes we will send a bare address packet to start the transaction, like drm_dp_i2c_xfer() show: .. /* Send a bare address packet to start the transaction. * Zero sized messages specify an address only (bare * address) transaction. */ msg.buffer = NULL; msg.size = 0; err = drm_dp_i2c_do_msg(aux, ); .. In this case, the msg->size is zero, so the num_transferred will be zero too. We can't return -EBUSY here, let's we return num_transferred if num_transferred equals msg->size. Please see my question inline. Signed-off-by: zain wang --- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index 303083a..5384aca 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -1162,5 +1162,5 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ) msg->reply = DP_AUX_NATIVE_REPLY_ACK; - return num_transferred > 0 ? num_transferred : -EBUSY; + return (num_transferred == msg->size) ? num_transferred : -EBUSY; I might be missing something but, looking at the code, I don't see any possibility of num_transferred ever being different than msg->size. To be honest, it doesn't seem to even make any sense keeping the local variable there, because msg->size can be simply always returned, as errors are handled by jumping to aux_error label. Yeah, I agree with you. The better way to fix this issue is to revert the changes https://patchwork.kernel.org/patch/9411711/ (returning num_transferred directly may be better here) Maybe we can revert the changes above with some new comment. @Sean, How do you think about Tomasz's comment? Thanks Zain Best regards, Tomasz
Re: [PATCH] drm/bridge: analogix_dp: Don't return -EBUSY when msg->size is 0 in aux transaction
Hi Sean, Could you give some comments for this patch? Thanks Zain 在 2017/2/13 17:27, zain wang 写道: The analogix_dp_transfer() will return -EBUSY if num_transferred is zero. But sometimes we will send a bare address packet to start the transaction, like drm_dp_i2c_xfer() show: .. /* Send a bare address packet to start the transaction. * Zero sized messages specify an address only (bare * address) transaction. */ msg.buffer = NULL; msg.size = 0; err = drm_dp_i2c_do_msg(aux, ); .. In this case, the msg->size is zero, so the num_transferred will be zero too. We can't return -EBUSY here, let's we return num_transferred if num_transferred equals msg->size. Signed-off-by: zain wang <w...@rock-chips.com> --- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index 303083a..5384aca 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -1162,5 +1162,5 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ) msg->reply = DP_AUX_NATIVE_REPLY_ACK; - return num_transferred > 0 ? num_transferred : -EBUSY; + return (num_transferred == msg->size) ? num_transferred : -EBUSY; }
Re: [PATCH] drm/bridge: analogix_dp: Don't return -EBUSY when msg->size is 0 in aux transaction
Hi Sean, Could you give some comments for this patch? Thanks Zain 在 2017/2/13 17:27, zain wang 写道: The analogix_dp_transfer() will return -EBUSY if num_transferred is zero. But sometimes we will send a bare address packet to start the transaction, like drm_dp_i2c_xfer() show: .. /* Send a bare address packet to start the transaction. * Zero sized messages specify an address only (bare * address) transaction. */ msg.buffer = NULL; msg.size = 0; err = drm_dp_i2c_do_msg(aux, ); .. In this case, the msg->size is zero, so the num_transferred will be zero too. We can't return -EBUSY here, let's we return num_transferred if num_transferred equals msg->size. Signed-off-by: zain wang --- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index 303083a..5384aca 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -1162,5 +1162,5 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ) msg->reply = DP_AUX_NATIVE_REPLY_ACK; - return num_transferred > 0 ? num_transferred : -EBUSY; + return (num_transferred == msg->size) ? num_transferred : -EBUSY; }
[PATCH] drm/bridge: analogix_dp: Don't return -EBUSY when msg->size is 0 in aux transaction
The analogix_dp_transfer() will return -EBUSY if num_transferred is zero. But sometimes we will send a bare address packet to start the transaction, like drm_dp_i2c_xfer() show: .. /* Send a bare address packet to start the transaction. * Zero sized messages specify an address only (bare * address) transaction. */ msg.buffer = NULL; msg.size = 0; err = drm_dp_i2c_do_msg(aux, ); .. In this case, the msg->size is zero, so the num_transferred will be zero too. We can't return -EBUSY here, let's we return num_transferred if num_transferred equals msg->size. Signed-off-by: zain wang <w...@rock-chips.com> --- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index 303083a..5384aca 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -1162,5 +1162,5 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ) msg->reply = DP_AUX_NATIVE_REPLY_ACK; - return num_transferred > 0 ? num_transferred : -EBUSY; + return (num_transferred == msg->size) ? num_transferred : -EBUSY; } -- 1.9.1
[PATCH] drm/bridge: analogix_dp: Don't return -EBUSY when msg->size is 0 in aux transaction
The analogix_dp_transfer() will return -EBUSY if num_transferred is zero. But sometimes we will send a bare address packet to start the transaction, like drm_dp_i2c_xfer() show: .. /* Send a bare address packet to start the transaction. * Zero sized messages specify an address only (bare * address) transaction. */ msg.buffer = NULL; msg.size = 0; err = drm_dp_i2c_do_msg(aux, ); .. In this case, the msg->size is zero, so the num_transferred will be zero too. We can't return -EBUSY here, let's we return num_transferred if num_transferred equals msg->size. Signed-off-by: zain wang --- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index 303083a..5384aca 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -1162,5 +1162,5 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ) msg->reply = DP_AUX_NATIVE_REPLY_ACK; - return num_transferred > 0 ? num_transferred : -EBUSY; + return (num_transferred == msg->size) ? num_transferred : -EBUSY; } -- 1.9.1
[PATCH v2] drm/bridge: analogix: Don't return -EINVAL when panel not support PSR in PSR functions
We will ignored PSR setting if panel not support it. So, in this case, we should return from analogix_dp_enable/disable_psr() without any error code. Let's retrun 0 instead of -EINVAL when panel not support PSR in analogix_dp_enable/disable_psr(). Signed-off-by: zain wang <w...@rock-chips.com> --- Changes in v2: - Remove dev_warn if panel not support PSR. drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 6e0447f..eb9bf87 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -112,7 +112,7 @@ int analogix_dp_enable_psr(struct device *dev) struct edp_vsc_psr psr_vsc; if (!dp->psr_support) - return -EINVAL; + return 0; /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); @@ -135,7 +135,7 @@ int analogix_dp_disable_psr(struct device *dev) struct edp_vsc_psr psr_vsc; if (!dp->psr_support) - return -EINVAL; + return 0; /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); -- 1.9.1
[PATCH v2] drm/bridge: analogix: Don't return -EINVAL when panel not support PSR in PSR functions
We will ignored PSR setting if panel not support it. So, in this case, we should return from analogix_dp_enable/disable_psr() without any error code. Let's retrun 0 instead of -EINVAL when panel not support PSR in analogix_dp_enable/disable_psr(). Signed-off-by: zain wang --- Changes in v2: - Remove dev_warn if panel not support PSR. drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 6e0447f..eb9bf87 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -112,7 +112,7 @@ int analogix_dp_enable_psr(struct device *dev) struct edp_vsc_psr psr_vsc; if (!dp->psr_support) - return -EINVAL; + return 0; /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); @@ -135,7 +135,7 @@ int analogix_dp_disable_psr(struct device *dev) struct edp_vsc_psr psr_vsc; if (!dp->psr_support) - return -EINVAL; + return 0; /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); -- 1.9.1
[PATCH] drm/bridge: analogix: Don't return -EINVAL when panel not support PSR in PSR functions
We will ignored PSR setting if panel not support it. So, in this case, we should return from analogix_dp_enable/disable_psr() without any error code. Let's retrun 0 instead of -EINVAL when panel not support PSR in analogix_dp_enable/disable_psr(). Signed-off-by: zain wang <w...@rock-chips.com> --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 6e0447f..0cb3695 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -112,7 +112,7 @@ int analogix_dp_enable_psr(struct device *dev) struct edp_vsc_psr psr_vsc; if (!dp->psr_support) - return -EINVAL; + return 0; /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); @@ -135,7 +135,7 @@ int analogix_dp_disable_psr(struct device *dev) struct edp_vsc_psr psr_vsc; if (!dp->psr_support) - return -EINVAL; + return 0; /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); @@ -878,6 +878,8 @@ static void analogix_dp_commit(struct analogix_dp_device *dp) dp->psr_support = analogix_dp_detect_sink_psr(dp); if (dp->psr_support) analogix_dp_enable_sink_psr(dp); + else + dev_warn(dp->dev, "Sink not support PSR\n"); } /* -- 1.9.1
[PATCH] drm/bridge: analogix: Don't return -EINVAL when panel not support PSR in PSR functions
We will ignored PSR setting if panel not support it. So, in this case, we should return from analogix_dp_enable/disable_psr() without any error code. Let's retrun 0 instead of -EINVAL when panel not support PSR in analogix_dp_enable/disable_psr(). Signed-off-by: zain wang --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 6e0447f..0cb3695 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -112,7 +112,7 @@ int analogix_dp_enable_psr(struct device *dev) struct edp_vsc_psr psr_vsc; if (!dp->psr_support) - return -EINVAL; + return 0; /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); @@ -135,7 +135,7 @@ int analogix_dp_disable_psr(struct device *dev) struct edp_vsc_psr psr_vsc; if (!dp->psr_support) - return -EINVAL; + return 0; /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); @@ -878,6 +878,8 @@ static void analogix_dp_commit(struct analogix_dp_device *dp) dp->psr_support = analogix_dp_detect_sink_psr(dp); if (dp->psr_support) analogix_dp_enable_sink_psr(dp); + else + dev_warn(dp->dev, "Sink not support PSR\n"); } /* -- 1.9.1
[PATCH] drm/panel: simple: add 8bit-bps for Sharp lq123p1jx31
Sharp lq123p1jx31 support 8bit bps. Signed-off-by: zain wang <w...@rock-chips.com> --- drivers/gpu/drm/panel/panel-simple.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 113db3c..6b0c026 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1409,6 +1409,7 @@ static const struct drm_display_mode sharp_lq123p1jx31_mode = { static const struct panel_desc sharp_lq123p1jx31 = { .modes = _lq123p1jx31_mode, .num_modes = 1, + .bpc = 8, .size = { .width = 259, .height = 173, -- 1.9.1
[PATCH] drm/panel: simple: add 8bit-bps for Sharp lq123p1jx31
Sharp lq123p1jx31 support 8bit bps. Signed-off-by: zain wang --- drivers/gpu/drm/panel/panel-simple.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 113db3c..6b0c026 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -1409,6 +1409,7 @@ static const struct drm_display_mode sharp_lq123p1jx31_mode = { static const struct panel_desc sharp_lq123p1jx31 = { .modes = _lq123p1jx31_mode, .num_modes = 1, + .bpc = 8, .size = { .width = 259, .height = 173, -- 1.9.1
[PATCH v3 4/6] drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr
From: zain wang <w...@rock-chips.com> turn off Main-link and power down eDP PHY when enable psr, turn on Main-link and power up eDP PHY when disable psr. Signed-off-by: zain wang <w...@rock-chips.com> --- Changes in v3: - detecting PSR state at enable/disable_psr() avoid to make link training when sink in not PSR State. Changes in v2: - misc changes drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 123 + 1 file changed, 76 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index c4f139a..c662e5d 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -98,50 +98,6 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp) return 0; } -int analogix_dp_enable_psr(struct device *dev) -{ - struct analogix_dp_device *dp = dev_get_drvdata(dev); - struct edp_vsc_psr psr_vsc; - - if (!dp->psr_support) - return -EINVAL; - - /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ - memset(_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - psr_vsc.sdp_header.HB2 = 0x2; - psr_vsc.sdp_header.HB3 = 0x8; - - psr_vsc.DB0 = 0; - psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; - - return analogix_dp_send_psr_spd(dp, _vsc); -} -EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); - -int analogix_dp_disable_psr(struct device *dev) -{ - struct analogix_dp_device *dp = dev_get_drvdata(dev); - struct edp_vsc_psr psr_vsc; - - if (!dp->psr_support) - return -EINVAL; - - /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ - memset(_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - psr_vsc.sdp_header.HB2 = 0x2; - psr_vsc.sdp_header.HB3 = 0x8; - - psr_vsc.DB0 = 0; - psr_vsc.DB1 = 0; - - return analogix_dp_send_psr_spd(dp, _vsc); -} -EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); - static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp) { unsigned char psr_version; @@ -162,12 +118,11 @@ static void analogix_dp_enable_sink_psr(struct analogix_dp_device *dp) drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); /* Main-Link transmitter remains active during PSR active states */ - psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION; + psr_en = DP_PSR_CRC_VERIFICATION; drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); /* Enable psr function */ - psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE | -DP_PSR_CRC_VERIFICATION; + psr_en = DP_PSR_ENABLE | DP_PSR_CRC_VERIFICATION; drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); analogix_dp_enable_psr_crc(dp); @@ -870,6 +825,80 @@ static void analogix_dp_commit(struct analogix_dp_device *dp) analogix_dp_enable_sink_psr(dp); } +int analogix_dp_enable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + int retval; + u8 sink; + + if (!dp->psr_support) + return -EINVAL; + + drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, ); + if (sink == DP_PSR_SINK_ACTIVE_RFB) + return 0; + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x2; + psr_vsc.sdp_header.HB3 = 0x8; + + psr_vsc.DB0 = 0; + psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; + + retval = analogix_dp_send_psr_spd(dp, _vsc); + + if (!retval) { + /* Power down the eDP PHY */ + analogix_dp_set_analog_power_down(dp, POWER_ALL, true); + } + + return retval; +} +EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); + +int analogix_dp_disable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + int ret; + u8 sink; + + if (!dp->psr_support) + return -EINVAL; + + /* Power up the eDP PHY */ + analogix_dp_set_analog_power_down(dp, POWER_ALL, false); + + drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, ); + if (sink == DP_PSR_SINK_INACTIVE) + return 0; + + ret = drm_dp_dpcd_writeb(>aux, DP_SET_POWER, DP_SET_POWER_D0); + if (ret < 0) { + dev_err(dp->dev, "Failed to set DP Power0\n"); + } + + analogix_dp_set_link_train(dp, dp->video_info.max_lane_count, + dp->video_info.max_link_rate); + + /* Prepare VSC packet
[PATCH 6/6] drm: bridge/analogix: enable vop standby when entry PSR
From: zain wang <w...@rock-chips.com> make VOP standby when entry PSR to save some power. Signed-off-by: zain wang <w...@rock-chips.com> --- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 29 ++--- drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 1 + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 19 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 1c2d756..e0f3ed3 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -113,6 +113,13 @@ static void analogix_dp_psr_work(struct work_struct *work) if (!crtc) return; + spin_lock_irqsave(>psr_lock, flags); + psr_state = dp->psr_state; + spin_unlock_irqrestore(>psr_lock, flags); + + if (psr_state != EDP_VSC_PSR_STATE_ACTIVE) + rockchip_drm_vop_set_standby(crtc, false); + vact_end = crtc->mode.vtotal - crtc->mode.vsync_start + crtc->mode.vdisplay; ret = rockchip_drm_wait_line_flag(dp->encoder.crtc, vact_end, @@ -122,14 +129,20 @@ static void analogix_dp_psr_work(struct work_struct *work) return; } - spin_lock_irqsave(>psr_lock, flags); - psr_state = dp->psr_state; - spin_unlock_irqrestore(>psr_lock, flags); - - if (psr_state == EDP_VSC_PSR_STATE_ACTIVE) - analogix_dp_enable_psr(dp->dev); - else - analogix_dp_disable_psr(dp->dev); + if (psr_state == EDP_VSC_PSR_STATE_ACTIVE) { + ret = analogix_dp_enable_psr(dp->dev); + if (ret) { + dev_err(dp->dev, "failed to enable psr\n"); + return; + } + rockchip_drm_vop_set_standby(crtc, true); + } else { + ret = analogix_dp_disable_psr(dp->dev); + if (ret) { + dev_err(dp->dev, "failed to disable psr\n"); + return; + } + } } static int rockchip_dp_pre_init(struct rockchip_dp_device *dp) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index fb6226c..7149c69 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -74,5 +74,6 @@ void rockchip_drm_dma_detach_device(struct drm_device *drm_dev, struct device *dev); int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num, unsigned int mstimeout); +void rockchip_drm_vop_set_standby(struct drm_crtc *crtc, bool enabled); #endif /* _ROCKCHIP_DRM_DRV_H_ */ diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 1740a0b..13eabda 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1478,6 +1478,25 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num, } EXPORT_SYMBOL(rockchip_drm_wait_line_flag); +void rockchip_drm_vop_set_standby(struct drm_crtc *crtc, bool enabled) +{ + struct vop *vop = to_vop(crtc); + + if (!crtc || !vop->is_enabled) + return; + + spin_lock(>reg_lock); + + if (enabled) + VOP_CTRL_SET(vop, standby, 1); + else + VOP_CTRL_SET(vop, standby, 0); + + spin_unlock(>reg_lock); + +} +EXPORT_SYMBOL(rockchip_drm_vop_set_standby); + static int vop_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); -- 1.9.1
[PATCH v3 4/6] drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr
From: zain wang turn off Main-link and power down eDP PHY when enable psr, turn on Main-link and power up eDP PHY when disable psr. Signed-off-by: zain wang --- Changes in v3: - detecting PSR state at enable/disable_psr() avoid to make link training when sink in not PSR State. Changes in v2: - misc changes drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 123 + 1 file changed, 76 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index c4f139a..c662e5d 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -98,50 +98,6 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp) return 0; } -int analogix_dp_enable_psr(struct device *dev) -{ - struct analogix_dp_device *dp = dev_get_drvdata(dev); - struct edp_vsc_psr psr_vsc; - - if (!dp->psr_support) - return -EINVAL; - - /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ - memset(_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - psr_vsc.sdp_header.HB2 = 0x2; - psr_vsc.sdp_header.HB3 = 0x8; - - psr_vsc.DB0 = 0; - psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; - - return analogix_dp_send_psr_spd(dp, _vsc); -} -EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); - -int analogix_dp_disable_psr(struct device *dev) -{ - struct analogix_dp_device *dp = dev_get_drvdata(dev); - struct edp_vsc_psr psr_vsc; - - if (!dp->psr_support) - return -EINVAL; - - /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ - memset(_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - psr_vsc.sdp_header.HB2 = 0x2; - psr_vsc.sdp_header.HB3 = 0x8; - - psr_vsc.DB0 = 0; - psr_vsc.DB1 = 0; - - return analogix_dp_send_psr_spd(dp, _vsc); -} -EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); - static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp) { unsigned char psr_version; @@ -162,12 +118,11 @@ static void analogix_dp_enable_sink_psr(struct analogix_dp_device *dp) drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); /* Main-Link transmitter remains active during PSR active states */ - psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION; + psr_en = DP_PSR_CRC_VERIFICATION; drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); /* Enable psr function */ - psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE | -DP_PSR_CRC_VERIFICATION; + psr_en = DP_PSR_ENABLE | DP_PSR_CRC_VERIFICATION; drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); analogix_dp_enable_psr_crc(dp); @@ -870,6 +825,80 @@ static void analogix_dp_commit(struct analogix_dp_device *dp) analogix_dp_enable_sink_psr(dp); } +int analogix_dp_enable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + int retval; + u8 sink; + + if (!dp->psr_support) + return -EINVAL; + + drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, ); + if (sink == DP_PSR_SINK_ACTIVE_RFB) + return 0; + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x2; + psr_vsc.sdp_header.HB3 = 0x8; + + psr_vsc.DB0 = 0; + psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; + + retval = analogix_dp_send_psr_spd(dp, _vsc); + + if (!retval) { + /* Power down the eDP PHY */ + analogix_dp_set_analog_power_down(dp, POWER_ALL, true); + } + + return retval; +} +EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); + +int analogix_dp_disable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + int ret; + u8 sink; + + if (!dp->psr_support) + return -EINVAL; + + /* Power up the eDP PHY */ + analogix_dp_set_analog_power_down(dp, POWER_ALL, false); + + drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, ); + if (sink == DP_PSR_SINK_INACTIVE) + return 0; + + ret = drm_dp_dpcd_writeb(>aux, DP_SET_POWER, DP_SET_POWER_D0); + if (ret < 0) { + dev_err(dp->dev, "Failed to set DP Power0\n"); + } + + analogix_dp_set_link_train(dp, dp->video_info.max_lane_count, + dp->video_info.max_link_rate); + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc,
[PATCH 6/6] drm: bridge/analogix: enable vop standby when entry PSR
From: zain wang make VOP standby when entry PSR to save some power. Signed-off-by: zain wang --- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 29 ++--- drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 1 + drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 19 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 1c2d756..e0f3ed3 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -113,6 +113,13 @@ static void analogix_dp_psr_work(struct work_struct *work) if (!crtc) return; + spin_lock_irqsave(>psr_lock, flags); + psr_state = dp->psr_state; + spin_unlock_irqrestore(>psr_lock, flags); + + if (psr_state != EDP_VSC_PSR_STATE_ACTIVE) + rockchip_drm_vop_set_standby(crtc, false); + vact_end = crtc->mode.vtotal - crtc->mode.vsync_start + crtc->mode.vdisplay; ret = rockchip_drm_wait_line_flag(dp->encoder.crtc, vact_end, @@ -122,14 +129,20 @@ static void analogix_dp_psr_work(struct work_struct *work) return; } - spin_lock_irqsave(>psr_lock, flags); - psr_state = dp->psr_state; - spin_unlock_irqrestore(>psr_lock, flags); - - if (psr_state == EDP_VSC_PSR_STATE_ACTIVE) - analogix_dp_enable_psr(dp->dev); - else - analogix_dp_disable_psr(dp->dev); + if (psr_state == EDP_VSC_PSR_STATE_ACTIVE) { + ret = analogix_dp_enable_psr(dp->dev); + if (ret) { + dev_err(dp->dev, "failed to enable psr\n"); + return; + } + rockchip_drm_vop_set_standby(crtc, true); + } else { + ret = analogix_dp_disable_psr(dp->dev); + if (ret) { + dev_err(dp->dev, "failed to disable psr\n"); + return; + } + } } static int rockchip_dp_pre_init(struct rockchip_dp_device *dp) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index fb6226c..7149c69 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -74,5 +74,6 @@ void rockchip_drm_dma_detach_device(struct drm_device *drm_dev, struct device *dev); int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num, unsigned int mstimeout); +void rockchip_drm_vop_set_standby(struct drm_crtc *crtc, bool enabled); #endif /* _ROCKCHIP_DRM_DRV_H_ */ diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index 1740a0b..13eabda 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -1478,6 +1478,25 @@ int rockchip_drm_wait_line_flag(struct drm_crtc *crtc, unsigned int line_num, } EXPORT_SYMBOL(rockchip_drm_wait_line_flag); +void rockchip_drm_vop_set_standby(struct drm_crtc *crtc, bool enabled) +{ + struct vop *vop = to_vop(crtc); + + if (!crtc || !vop->is_enabled) + return; + + spin_lock(>reg_lock); + + if (enabled) + VOP_CTRL_SET(vop, standby, 1); + else + VOP_CTRL_SET(vop, standby, 0); + + spin_unlock(>reg_lock); + +} +EXPORT_SYMBOL(rockchip_drm_vop_set_standby); + static int vop_bind(struct device *dev, struct device *master, void *data) { struct platform_device *pdev = to_platform_device(dev); -- 1.9.1
[PATCH v3 5/6] drm: bridge/analogix: add fast link train for eDP
From: zain wang <w...@rock-chips.com> we would meet a short black screen when exit PSR with the full link training, In this case, we should use fast link train instead of full link training. Signed-off-by: zain wang <w...@rock-chips.com> --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 89 +- drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 1 + 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 561b644..0516621 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,8 @@ #define to_dp(nm) container_of(nm, struct analogix_dp_device, nm) +static const int FAST_LINK_VERIFICATION = false; + struct bridge_init { struct i2c_client *client; struct device_node *node; @@ -244,6 +247,7 @@ static int analogix_dp_link_start(struct analogix_dp_device *dp) usleep_range(90, 120); } + /* Set training pattern 1 */ analogix_dp_set_training_pattern(dp, TRAINING_PTN1); @@ -481,7 +485,7 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp) { int lane, lane_count, retval; u32 reg; - u8 link_align, link_status[2], adjust_request[2]; + u8 link_align, link_status[2], adjust_request[2], spread; usleep_range(400, 401); @@ -524,6 +528,12 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp) dev_dbg(dp->dev, "final lane count = %.2x\n", dp->link_train.lane_count); + drm_dp_dpcd_readb(>aux, DP_MAX_DOWNSPREAD, ); + dp->fast_train_support = (spread & + DP_NO_AUX_HANDSHAKE_LINK_TRAINING) ? true : false; + dev_dbg(dp->dev, "fast link training %s\n", + dp->fast_train_support ? "supported" : "unsupported"); + /* set enhanced mode if available */ analogix_dp_set_enhanced_mode(dp); dp->link_train.lt_state = FINISHED; @@ -655,6 +665,75 @@ static int analogix_dp_sw_link_training(struct analogix_dp_device *dp) return retval; } +static int analogix_dp_full_link_train(struct analogix_dp_device *dp, + u32 count, u32 bwtype) +{ + analogix_dp_init_training(dp, count, bwtype); + return analogix_dp_sw_link_training(dp); +} + +static int analogix_dp_fast_link_train(struct analogix_dp_device *dp) +{ + int lane; + int retval; + u8 link_align, link_status[2]; + enum pll_status status; + + analogix_dp_reset_macro(dp); + + analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate); + analogix_dp_set_lane_count(dp, dp->link_train.lane_count); + + for (lane = 0; lane < dp->link_train.lane_count; lane++) { + analogix_dp_set_lane_link_training(dp, + dp->link_train.training_lane[lane], lane); + } + + retval = readx_poll_timeout(analogix_dp_get_pll_lock_status, dp, status, + status != PLL_UNLOCKED, + 120, 120 * DP_TIMEOUT_LOOP_COUNT); + + if (retval) + return retval; + + /* source Set training pattern 1 */ + analogix_dp_set_training_pattern(dp, TRAINING_PTN1); + usleep_range(500, 600); + + analogix_dp_set_training_pattern(dp, TRAINING_PTN2); + usleep_range(500, 600); + + /* TODO: enhanced_mode?*/ + analogix_dp_set_training_pattern(dp, DP_NONE); + + if (FAST_LINK_VERIFICATION) { + retval = drm_dp_dpcd_readb(>aux, + DP_LANE_ALIGN_STATUS_UPDATED, + _align); + if (retval < 0) + return retval; + + retval = drm_dp_dpcd_read(>aux, DP_LANE0_1_STATUS, + link_status, 2); + if (retval < 0) + return retval; + + if (analogix_dp_clock_recovery_ok(link_status, + dp->link_train.lane_count)) { + analogix_dp_reduce_link_rate(dp); + return -EIO; + } + + if (analogix_dp_channel_eq_ok(link_status, link_align, + dp->link_train.lane_count)) { + analogix_dp_reduce_link_rate(dp); + return -EIO; + } + } + + return 0; +} + static int analogix_dp_set_link_train(str
[PATCH v3 5/6] drm: bridge/analogix: add fast link train for eDP
From: zain wang we would meet a short black screen when exit PSR with the full link training, In this case, we should use fast link train instead of full link training. Signed-off-by: zain wang --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 89 +- drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 1 + 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 561b644..0516621 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,8 @@ #define to_dp(nm) container_of(nm, struct analogix_dp_device, nm) +static const int FAST_LINK_VERIFICATION = false; + struct bridge_init { struct i2c_client *client; struct device_node *node; @@ -244,6 +247,7 @@ static int analogix_dp_link_start(struct analogix_dp_device *dp) usleep_range(90, 120); } + /* Set training pattern 1 */ analogix_dp_set_training_pattern(dp, TRAINING_PTN1); @@ -481,7 +485,7 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp) { int lane, lane_count, retval; u32 reg; - u8 link_align, link_status[2], adjust_request[2]; + u8 link_align, link_status[2], adjust_request[2], spread; usleep_range(400, 401); @@ -524,6 +528,12 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp) dev_dbg(dp->dev, "final lane count = %.2x\n", dp->link_train.lane_count); + drm_dp_dpcd_readb(>aux, DP_MAX_DOWNSPREAD, ); + dp->fast_train_support = (spread & + DP_NO_AUX_HANDSHAKE_LINK_TRAINING) ? true : false; + dev_dbg(dp->dev, "fast link training %s\n", + dp->fast_train_support ? "supported" : "unsupported"); + /* set enhanced mode if available */ analogix_dp_set_enhanced_mode(dp); dp->link_train.lt_state = FINISHED; @@ -655,6 +665,75 @@ static int analogix_dp_sw_link_training(struct analogix_dp_device *dp) return retval; } +static int analogix_dp_full_link_train(struct analogix_dp_device *dp, + u32 count, u32 bwtype) +{ + analogix_dp_init_training(dp, count, bwtype); + return analogix_dp_sw_link_training(dp); +} + +static int analogix_dp_fast_link_train(struct analogix_dp_device *dp) +{ + int lane; + int retval; + u8 link_align, link_status[2]; + enum pll_status status; + + analogix_dp_reset_macro(dp); + + analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate); + analogix_dp_set_lane_count(dp, dp->link_train.lane_count); + + for (lane = 0; lane < dp->link_train.lane_count; lane++) { + analogix_dp_set_lane_link_training(dp, + dp->link_train.training_lane[lane], lane); + } + + retval = readx_poll_timeout(analogix_dp_get_pll_lock_status, dp, status, + status != PLL_UNLOCKED, + 120, 120 * DP_TIMEOUT_LOOP_COUNT); + + if (retval) + return retval; + + /* source Set training pattern 1 */ + analogix_dp_set_training_pattern(dp, TRAINING_PTN1); + usleep_range(500, 600); + + analogix_dp_set_training_pattern(dp, TRAINING_PTN2); + usleep_range(500, 600); + + /* TODO: enhanced_mode?*/ + analogix_dp_set_training_pattern(dp, DP_NONE); + + if (FAST_LINK_VERIFICATION) { + retval = drm_dp_dpcd_readb(>aux, + DP_LANE_ALIGN_STATUS_UPDATED, + _align); + if (retval < 0) + return retval; + + retval = drm_dp_dpcd_read(>aux, DP_LANE0_1_STATUS, + link_status, 2); + if (retval < 0) + return retval; + + if (analogix_dp_clock_recovery_ok(link_status, + dp->link_train.lane_count)) { + analogix_dp_reduce_link_rate(dp); + return -EIO; + } + + if (analogix_dp_channel_eq_ok(link_status, link_align, + dp->link_train.lane_count)) { + analogix_dp_reduce_link_rate(dp); + return -EIO; + } + } + + return 0; +} + static int analogix_dp_set_link_train(struct analogix_dp_device *dp,
[PATCH v3 3/6] drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR
From: Yakir Yang <y...@rock-chips.com> Make sure the request PSR state takes effect in analogix_dp_send_psr_spd() function, or print the sink PSR error state if we failed to apply the requested PSR setting. Signed-off-by: zain wang <w...@rock-chips.com> Signed-off-by: Yakir Yang <y...@rock-chips.com> --- Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 6 ++ drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 6 -- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 -- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 6 -- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index bcae4dd..7faad93 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -124,8 +124,7 @@ int analogix_dp_enable_psr(struct device *dev) psr_vsc.DB0 = 0; psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; - analogix_dp_send_psr_spd(dp, _vsc); - return 0; + return analogix_dp_send_psr_spd(dp, _vsc); } EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); @@ -147,8 +146,7 @@ int analogix_dp_disable_psr(struct device *dev) psr_vsc.DB0 = 0; psr_vsc.DB1 = 0; - analogix_dp_send_psr_spd(dp, _vsc); - return 0; + return analogix_dp_send_psr_spd(dp, _vsc); } EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index 5c6a288..cdc0535 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -20,6 +20,8 @@ #define MAX_CR_LOOP 5 #define MAX_EQ_LOOP 5 +#define DP_TIMEOUT_PSR_LOOP_MS msecs_to_jiffies(300) + /* DP_MAX_LANE_COUNT */ #define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) #define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) @@ -247,8 +249,8 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp); void analogix_dp_enable_scrambling(struct analogix_dp_device *dp); void analogix_dp_disable_scrambling(struct analogix_dp_device *dp); void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp); -void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, - struct edp_vsc_psr *vsc); +int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, +struct edp_vsc_psr *vsc); ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, struct drm_dp_aux_msg *msg); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index cd37ac0..9e1177c 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -992,10 +992,12 @@ void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp) writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON); } -void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, - struct edp_vsc_psr *vsc) +int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, +struct edp_vsc_psr *vsc) { + unsigned long timeout; unsigned int val; + u8 sink; /* don't send info frame */ val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); @@ -1036,6 +1038,25 @@ void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); val |= IF_EN; writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); + + timeout = jiffies + DP_TIMEOUT_PSR_LOOP_MS; + while (time_before(jiffies, timeout)) { + val = drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, ); + if (val != 1) { + dev_err(dp->dev, "PSR_STATUS read failed ret=%d", val); + return -EBUSY; + } + + if ((vsc->DB1 && sink == DP_PSR_SINK_ACTIVE_RFB) || + (!vsc->DB1 && sink == DP_PSR_SINK_INACTIVE)) + return 0; + + usleep_range(1000, 1500); + } + + dev_warn(dp->dev, "Failed to apply PSR, sink state was [%x]", sink); + + return -ETIMEDOUT; } ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index e5471e7..1c2d756 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -105,7 +105,7 @@ static void analogix_dp_psr_work(struct work_struct *work) struct ro
[PATCH v3 3/6] drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR
From: Yakir Yang Make sure the request PSR state takes effect in analogix_dp_send_psr_spd() function, or print the sink PSR error state if we failed to apply the requested PSR setting. Signed-off-by: zain wang Signed-off-by: Yakir Yang --- Changes in v3: None Changes in v2: None drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 6 ++ drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 6 -- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 -- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 6 -- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index bcae4dd..7faad93 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -124,8 +124,7 @@ int analogix_dp_enable_psr(struct device *dev) psr_vsc.DB0 = 0; psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; - analogix_dp_send_psr_spd(dp, _vsc); - return 0; + return analogix_dp_send_psr_spd(dp, _vsc); } EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); @@ -147,8 +146,7 @@ int analogix_dp_disable_psr(struct device *dev) psr_vsc.DB0 = 0; psr_vsc.DB1 = 0; - analogix_dp_send_psr_spd(dp, _vsc); - return 0; + return analogix_dp_send_psr_spd(dp, _vsc); } EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index 5c6a288..cdc0535 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -20,6 +20,8 @@ #define MAX_CR_LOOP 5 #define MAX_EQ_LOOP 5 +#define DP_TIMEOUT_PSR_LOOP_MS msecs_to_jiffies(300) + /* DP_MAX_LANE_COUNT */ #define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) #define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) @@ -247,8 +249,8 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp); void analogix_dp_enable_scrambling(struct analogix_dp_device *dp); void analogix_dp_disable_scrambling(struct analogix_dp_device *dp); void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp); -void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, - struct edp_vsc_psr *vsc); +int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, +struct edp_vsc_psr *vsc); ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, struct drm_dp_aux_msg *msg); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index cd37ac0..9e1177c 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -992,10 +992,12 @@ void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp) writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON); } -void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, - struct edp_vsc_psr *vsc) +int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, +struct edp_vsc_psr *vsc) { + unsigned long timeout; unsigned int val; + u8 sink; /* don't send info frame */ val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); @@ -1036,6 +1038,25 @@ void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); val |= IF_EN; writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); + + timeout = jiffies + DP_TIMEOUT_PSR_LOOP_MS; + while (time_before(jiffies, timeout)) { + val = drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, ); + if (val != 1) { + dev_err(dp->dev, "PSR_STATUS read failed ret=%d", val); + return -EBUSY; + } + + if ((vsc->DB1 && sink == DP_PSR_SINK_ACTIVE_RFB) || + (!vsc->DB1 && sink == DP_PSR_SINK_INACTIVE)) + return 0; + + usleep_range(1000, 1500); + } + + dev_warn(dp->dev, "Failed to apply PSR, sink state was [%x]", sink); + + return -ETIMEDOUT; } ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index e5471e7..1c2d756 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -105,7 +105,7 @@ static void analogix_dp_psr_work(struct work_struct *work) struct rockchip_dp_device *dp = container_of(work, typeof(*
[PATCH v3 1/6] drm/bridge: analogix_dp: set psr activate/deactivate when enable/disable bridge
From: zain wang <w...@rock-chips.com> There's a race between when bridge_disable and when vop_crtc_disable are called. If the flush timer triggers a new psr work between these, we will operate eDP without power shutdowned by bridge_disable. In this case, moving activate/deactivate to enable/disable bridge to avoid it. Signed-off-by: zain wang <w...@rock-chips.com> --- Changes in v3: - remove changes before. - move psr activat/deactivate to enable/disable bridge. Changes in v2: - add spin_lock to protect dpms_mode drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 4 ++-- drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 30 - drivers/gpu/drm/rockchip/rockchip_drm_psr.h | 4 ++-- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 8548e82..e5471e7 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -159,7 +159,7 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data) return ret; } - return 0; + return rockchip_drm_psr_activate(>encoder); } static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data) @@ -168,7 +168,7 @@ static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data) clk_disable_unprepare(dp->pclk); - return 0; + return rockchip_drm_psr_deactivate(>encoder); } static int rockchip_dp_get_modes(struct analogix_dp_plat_data *plat_data, diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c index a553e18..4c379e9 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c @@ -57,6 +57,24 @@ out: return psr; } +static struct psr_drv *find_psr_by_encoder(struct drm_encoder *encoder) +{ + struct rockchip_drm_private *drm_drv = encoder->dev->dev_private; + struct psr_drv *psr; + unsigned long flags; + + spin_lock_irqsave(_drv->psr_list_lock, flags); + list_for_each_entry(psr, _drv->psr_list, list) { + if (psr->encoder == encoder) + goto out; + } + psr = ERR_PTR(-ENODEV); + +out: + spin_unlock_irqrestore(_drv->psr_list_lock, flags); + return psr; +} + static void psr_set_state_locked(struct psr_drv *psr, enum psr_state state) { /* @@ -115,14 +133,14 @@ static void psr_flush_handler(unsigned long data) /** * rockchip_drm_psr_activate - activate PSR on the given pipe - * @crtc: CRTC to obtain the PSR encoder + * @encoder: encoder to obtain the PSR encoder * * Returns: * Zero on success, negative errno on failure. */ -int rockchip_drm_psr_activate(struct drm_crtc *crtc) +int rockchip_drm_psr_activate(struct drm_encoder *encoder) { - struct psr_drv *psr = find_psr_by_crtc(crtc); + struct psr_drv *psr = find_psr_by_encoder(encoder); unsigned long flags; if (IS_ERR(psr)) @@ -138,14 +156,14 @@ EXPORT_SYMBOL(rockchip_drm_psr_activate); /** * rockchip_drm_psr_deactivate - deactivate PSR on the given pipe - * @crtc: CRTC to obtain the PSR encoder + * @encoder: encoder to obtain the PSR encoder * * Returns: * Zero on success, negative errno on failure. */ -int rockchip_drm_psr_deactivate(struct drm_crtc *crtc) +int rockchip_drm_psr_deactivate(struct drm_encoder *encoder) { - struct psr_drv *psr = find_psr_by_crtc(crtc); + struct psr_drv *psr = find_psr_by_encoder(encoder); unsigned long flags; if (IS_ERR(psr)) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h index b420cf1..b1ea015 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h @@ -18,8 +18,8 @@ void rockchip_drm_psr_flush_all(struct drm_device *dev); int rockchip_drm_psr_flush(struct drm_crtc *crtc); -int rockchip_drm_psr_activate(struct drm_crtc *crtc); -int rockchip_drm_psr_deactivate(struct drm_crtc *crtc); +int rockchip_drm_psr_activate(struct drm_encoder *encoder); +int rockchip_drm_psr_deactivate(struct drm_encoder *encoder); int rockchip_drm_psr_register(struct drm_encoder *encoder, void (*psr_set)(struct drm_encoder *, bool enable)); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index c7eba30..1740a0b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -566,8 +566,6 @@ static void vop_crtc_disable(struct drm_crtc *crtc) WARN_ON(vop->event); - rockchip_drm_psr_deactivate(>crtc); - /* * We need to make sure that all windows are disabled before
[PATCH v3 2/6] drm/bridge: remove dp init from analogix_dp_bind
From: zain wang <w...@rock-chips.com> phy_power_on() and analogix_dp_init_dp would be called in bridge_eanble, so remove them from analogix_dp_bind to be clear. Signed-off-by: zain wang <w...@rock-chips.com> --- Changes in v3: - remove changes before - remove phy_power_on() and analogix_dp_init_dp from analogix_dp_bind(). Changes in v2: None drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 001b075..bcae4dd 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1389,10 +1389,6 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, pm_runtime_enable(dev); - phy_power_on(dp->phy); - - analogix_dp_init_dp(dp); - ret = devm_request_threaded_irq(>dev, dp->irq, analogix_dp_hardirq, analogix_dp_irq_thread, -- 1.9.1
[PATCH v3 1/6] drm/bridge: analogix_dp: set psr activate/deactivate when enable/disable bridge
From: zain wang There's a race between when bridge_disable and when vop_crtc_disable are called. If the flush timer triggers a new psr work between these, we will operate eDP without power shutdowned by bridge_disable. In this case, moving activate/deactivate to enable/disable bridge to avoid it. Signed-off-by: zain wang --- Changes in v3: - remove changes before. - move psr activat/deactivate to enable/disable bridge. Changes in v2: - add spin_lock to protect dpms_mode drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 4 ++-- drivers/gpu/drm/rockchip/rockchip_drm_psr.c | 30 - drivers/gpu/drm/rockchip/rockchip_drm_psr.h | 4 ++-- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 4 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index 8548e82..e5471e7 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -159,7 +159,7 @@ static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data) return ret; } - return 0; + return rockchip_drm_psr_activate(>encoder); } static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data) @@ -168,7 +168,7 @@ static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data) clk_disable_unprepare(dp->pclk); - return 0; + return rockchip_drm_psr_deactivate(>encoder); } static int rockchip_dp_get_modes(struct analogix_dp_plat_data *plat_data, diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c index a553e18..4c379e9 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.c @@ -57,6 +57,24 @@ out: return psr; } +static struct psr_drv *find_psr_by_encoder(struct drm_encoder *encoder) +{ + struct rockchip_drm_private *drm_drv = encoder->dev->dev_private; + struct psr_drv *psr; + unsigned long flags; + + spin_lock_irqsave(_drv->psr_list_lock, flags); + list_for_each_entry(psr, _drv->psr_list, list) { + if (psr->encoder == encoder) + goto out; + } + psr = ERR_PTR(-ENODEV); + +out: + spin_unlock_irqrestore(_drv->psr_list_lock, flags); + return psr; +} + static void psr_set_state_locked(struct psr_drv *psr, enum psr_state state) { /* @@ -115,14 +133,14 @@ static void psr_flush_handler(unsigned long data) /** * rockchip_drm_psr_activate - activate PSR on the given pipe - * @crtc: CRTC to obtain the PSR encoder + * @encoder: encoder to obtain the PSR encoder * * Returns: * Zero on success, negative errno on failure. */ -int rockchip_drm_psr_activate(struct drm_crtc *crtc) +int rockchip_drm_psr_activate(struct drm_encoder *encoder) { - struct psr_drv *psr = find_psr_by_crtc(crtc); + struct psr_drv *psr = find_psr_by_encoder(encoder); unsigned long flags; if (IS_ERR(psr)) @@ -138,14 +156,14 @@ EXPORT_SYMBOL(rockchip_drm_psr_activate); /** * rockchip_drm_psr_deactivate - deactivate PSR on the given pipe - * @crtc: CRTC to obtain the PSR encoder + * @encoder: encoder to obtain the PSR encoder * * Returns: * Zero on success, negative errno on failure. */ -int rockchip_drm_psr_deactivate(struct drm_crtc *crtc) +int rockchip_drm_psr_deactivate(struct drm_encoder *encoder) { - struct psr_drv *psr = find_psr_by_crtc(crtc); + struct psr_drv *psr = find_psr_by_encoder(encoder); unsigned long flags; if (IS_ERR(psr)) diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h index b420cf1..b1ea015 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_psr.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_psr.h @@ -18,8 +18,8 @@ void rockchip_drm_psr_flush_all(struct drm_device *dev); int rockchip_drm_psr_flush(struct drm_crtc *crtc); -int rockchip_drm_psr_activate(struct drm_crtc *crtc); -int rockchip_drm_psr_deactivate(struct drm_crtc *crtc); +int rockchip_drm_psr_activate(struct drm_encoder *encoder); +int rockchip_drm_psr_deactivate(struct drm_encoder *encoder); int rockchip_drm_psr_register(struct drm_encoder *encoder, void (*psr_set)(struct drm_encoder *, bool enable)); diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c index c7eba30..1740a0b 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c @@ -566,8 +566,6 @@ static void vop_crtc_disable(struct drm_crtc *crtc) WARN_ON(vop->event); - rockchip_drm_psr_deactivate(>crtc); - /* * We need to make sure that all windows are disabled before we * disable that crtc. Otherwise we m
[PATCH v3 2/6] drm/bridge: remove dp init from analogix_dp_bind
From: zain wang phy_power_on() and analogix_dp_init_dp would be called in bridge_eanble, so remove them from analogix_dp_bind to be clear. Signed-off-by: zain wang --- Changes in v3: - remove changes before - remove phy_power_on() and analogix_dp_init_dp from analogix_dp_bind(). Changes in v2: None drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 001b075..bcae4dd 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1389,10 +1389,6 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, pm_runtime_enable(dev); - phy_power_on(dp->phy); - - analogix_dp_init_dp(dp); - ret = devm_request_threaded_irq(>dev, dp->irq, analogix_dp_hardirq, analogix_dp_irq_thread, -- 1.9.1
[PATCH v3 0/6] Misc changes to Rockchip PSR drivers
This serise of patches works for saving power on eDP PHY and VOP during PSR. BR, - Zain Changes in v3: - add new patch to support fast link training. - add new patch to make VOP standby when entry PSR. - Misc changes. Changes in v2: - add spin_lock to protect dpms_mode - misc changes. Yakir Yang (1): drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR zain wang (5): drm/bridge: analogix_dp: set psr activate/deactivate when enable/disable bridge drm/bridge: remove dp init from analogix_dp_bind drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr drm: bridge/analogix: add fast link train for eDP drm: bridge/analogix: enable vop standby when entry PSR drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 218 +++-- drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 7 +- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 ++- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 33 +++- drivers/gpu/drm/rockchip/rockchip_drm_drv.h| 1 + drivers/gpu/drm/rockchip/rockchip_drm_psr.c| 30 ++- drivers/gpu/drm/rockchip/rockchip_drm_psr.h| 4 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c| 23 ++- 8 files changed, 259 insertions(+), 82 deletions(-) -- 1.9.1
[PATCH v3 0/6] Misc changes to Rockchip PSR drivers
This serise of patches works for saving power on eDP PHY and VOP during PSR. BR, - Zain Changes in v3: - add new patch to support fast link training. - add new patch to make VOP standby when entry PSR. - Misc changes. Changes in v2: - add spin_lock to protect dpms_mode - misc changes. Yakir Yang (1): drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR zain wang (5): drm/bridge: analogix_dp: set psr activate/deactivate when enable/disable bridge drm/bridge: remove dp init from analogix_dp_bind drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr drm: bridge/analogix: add fast link train for eDP drm: bridge/analogix: enable vop standby when entry PSR drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 218 +++-- drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 7 +- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 ++- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 33 +++- drivers/gpu/drm/rockchip/rockchip_drm_drv.h| 1 + drivers/gpu/drm/rockchip/rockchip_drm_psr.c| 30 ++- drivers/gpu/drm/rockchip/rockchip_drm_psr.h| 4 +- drivers/gpu/drm/rockchip/rockchip_drm_vop.c| 23 ++- 8 files changed, 259 insertions(+), 82 deletions(-) -- 1.9.1
[PATCH v2 3/4] drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR
From: Yakir Yang <y...@rock-chips.com> Make sure the request PSR state takes effect in analogix_dp_send_psr_spd() function, or print the sink PSR error state if we failed to apply the requested PSR setting. Signed-off-by: Yakir Yang <y...@rock-chips.com> Signed-off-by: Zain Wang <w...@rock-chips.com> --- Changes in v2: None drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 6 ++ drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 6 -- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 -- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 8 --- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 1bd190e..bf87891 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -142,8 +142,7 @@ int analogix_dp_enable_psr(struct device *dev) psr_vsc.DB0 = 0; psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; - analogix_dp_send_psr_spd(dp, _vsc); - return 0; + return analogix_dp_send_psr_spd(dp, _vsc); } EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); @@ -168,8 +167,7 @@ int analogix_dp_disable_psr(struct device *dev) psr_vsc.DB0 = 0; psr_vsc.DB1 = 0; - analogix_dp_send_psr_spd(dp, _vsc); - return 0; + return analogix_dp_send_psr_spd(dp, _vsc); } EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index 776c844..553c411 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -20,6 +20,8 @@ #define MAX_CR_LOOP 5 #define MAX_EQ_LOOP 5 +#define DP_TIMEOUT_PSR_LOOP_MS msecs_to_jiffies(300) + /* DP_MAX_LANE_COUNT */ #define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) #define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) @@ -248,8 +250,8 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp); void analogix_dp_enable_scrambling(struct analogix_dp_device *dp); void analogix_dp_disable_scrambling(struct analogix_dp_device *dp); void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp); -void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, - struct edp_vsc_psr *vsc); +int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, +struct edp_vsc_psr *vsc); ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, struct drm_dp_aux_msg *msg); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index cd37ac0..9e1177c 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -992,10 +992,12 @@ void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp) writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON); } -void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, - struct edp_vsc_psr *vsc) +int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, +struct edp_vsc_psr *vsc) { + unsigned long timeout; unsigned int val; + u8 sink; /* don't send info frame */ val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); @@ -1036,6 +1038,25 @@ void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); val |= IF_EN; writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); + + timeout = jiffies + DP_TIMEOUT_PSR_LOOP_MS; + while (time_before(jiffies, timeout)) { + val = drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, ); + if (val != 1) { + dev_err(dp->dev, "PSR_STATUS read failed ret=%d", val); + return -EBUSY; + } + + if ((vsc->DB1 && sink == DP_PSR_SINK_ACTIVE_RFB) || + (!vsc->DB1 && sink == DP_PSR_SINK_INACTIVE)) + return 0; + + usleep_range(1000, 1500); + } + + dev_warn(dp->dev, "Failed to apply PSR, sink state was [%x]", sink); + + return -ETIMEDOUT; } ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index e83be15..dc106d0 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -102,10 +102,10 @@ static void analogix_dp_psr_work(struct work_struct *work) struct rockchip_dp_device
[PATCH v2 4/4] drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr
turn off Main-link and power down eDP PHY when enable psr, turn on Main-link and power up eDP PHY when disable psr. Signed-off-by: zain wang <w...@rock-chips.com> --- Changes in v2: - misc changes drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 124 - 1 file changed, 70 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index bf87891..58fa1c1 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -120,57 +120,6 @@ static int analogix_dp_get_dpms_mode(struct analogix_dp_device *dp) return mode; } - -int analogix_dp_enable_psr(struct device *dev) -{ - struct analogix_dp_device *dp = dev_get_drvdata(dev); - struct edp_vsc_psr psr_vsc; - - if (!dp->psr_support) - return -EINVAL; - - if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON) - return -EBUSY; - - /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ - memset(_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - psr_vsc.sdp_header.HB2 = 0x2; - psr_vsc.sdp_header.HB3 = 0x8; - - psr_vsc.DB0 = 0; - psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; - - return analogix_dp_send_psr_spd(dp, _vsc); -} -EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); - -int analogix_dp_disable_psr(struct device *dev) -{ - struct analogix_dp_device *dp = dev_get_drvdata(dev); - struct edp_vsc_psr psr_vsc; - - if (!dp->psr_support) - return -EINVAL; - - if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON) - return -EBUSY; - - /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ - memset(_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - psr_vsc.sdp_header.HB2 = 0x2; - psr_vsc.sdp_header.HB3 = 0x8; - - psr_vsc.DB0 = 0; - psr_vsc.DB1 = 0; - - return analogix_dp_send_psr_spd(dp, _vsc); -} -EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); - static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp) { unsigned char psr_version; @@ -191,12 +140,11 @@ static void analogix_dp_enable_sink_psr(struct analogix_dp_device *dp) drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); /* Main-Link transmitter remains active during PSR active states */ - psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION; + psr_en = DP_PSR_CRC_VERIFICATION; drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); /* Enable psr function */ - psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE | -DP_PSR_CRC_VERIFICATION; + psr_en = DP_PSR_ENABLE | DP_PSR_CRC_VERIFICATION; drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); analogix_dp_enable_psr_crc(dp); @@ -899,6 +847,74 @@ static void analogix_dp_commit(struct analogix_dp_device *dp) analogix_dp_enable_sink_psr(dp); } +int analogix_dp_enable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + + if (!dp->psr_support) + return -EINVAL; + + if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON) + return -EBUSY; + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x2; + psr_vsc.sdp_header.HB3 = 0x8; + + psr_vsc.DB0 = 0; + psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; + + analogix_dp_send_psr_spd(dp, _vsc); + + /* Power down the eDP PHY */ + analogix_dp_set_analog_power_down(dp, POWER_ALL, true); + + return 0; +} +EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); + +int analogix_dp_disable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + int ret; + + if (!dp->psr_support) + return -EINVAL; + + if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON) + return -EBUSY; + + /* Power up the eDP PHY */ + analogix_dp_set_analog_power_down(dp, POWER_ALL, false); + + ret = drm_dp_dpcd_writeb(>aux, DP_SET_POWER, DP_SET_POWER_D0); + if (ret < 0) { + dev_err(dp->dev, "Failed to set DP Power0\n"); + } + + analogix_dp_set_link_train(dp, dp->video_info.max_lane_count, + dp->video_info.max_link_rate); + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_he
[PATCH v2 3/4] drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR
From: Yakir Yang Make sure the request PSR state takes effect in analogix_dp_send_psr_spd() function, or print the sink PSR error state if we failed to apply the requested PSR setting. Signed-off-by: Yakir Yang Signed-off-by: Zain Wang --- Changes in v2: None drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 6 ++ drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 6 -- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 -- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 8 --- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 1bd190e..bf87891 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -142,8 +142,7 @@ int analogix_dp_enable_psr(struct device *dev) psr_vsc.DB0 = 0; psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; - analogix_dp_send_psr_spd(dp, _vsc); - return 0; + return analogix_dp_send_psr_spd(dp, _vsc); } EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); @@ -168,8 +167,7 @@ int analogix_dp_disable_psr(struct device *dev) psr_vsc.DB0 = 0; psr_vsc.DB1 = 0; - analogix_dp_send_psr_spd(dp, _vsc); - return 0; + return analogix_dp_send_psr_spd(dp, _vsc); } EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index 776c844..553c411 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -20,6 +20,8 @@ #define MAX_CR_LOOP 5 #define MAX_EQ_LOOP 5 +#define DP_TIMEOUT_PSR_LOOP_MS msecs_to_jiffies(300) + /* DP_MAX_LANE_COUNT */ #define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) #define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) @@ -248,8 +250,8 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp); void analogix_dp_enable_scrambling(struct analogix_dp_device *dp); void analogix_dp_disable_scrambling(struct analogix_dp_device *dp); void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp); -void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, - struct edp_vsc_psr *vsc); +int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, +struct edp_vsc_psr *vsc); ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, struct drm_dp_aux_msg *msg); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index cd37ac0..9e1177c 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -992,10 +992,12 @@ void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp) writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON); } -void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, - struct edp_vsc_psr *vsc) +int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, +struct edp_vsc_psr *vsc) { + unsigned long timeout; unsigned int val; + u8 sink; /* don't send info frame */ val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); @@ -1036,6 +1038,25 @@ void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); val |= IF_EN; writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); + + timeout = jiffies + DP_TIMEOUT_PSR_LOOP_MS; + while (time_before(jiffies, timeout)) { + val = drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, ); + if (val != 1) { + dev_err(dp->dev, "PSR_STATUS read failed ret=%d", val); + return -EBUSY; + } + + if ((vsc->DB1 && sink == DP_PSR_SINK_ACTIVE_RFB) || + (!vsc->DB1 && sink == DP_PSR_SINK_INACTIVE)) + return 0; + + usleep_range(1000, 1500); + } + + dev_warn(dp->dev, "Failed to apply PSR, sink state was [%x]", sink); + + return -ETIMEDOUT; } ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index e83be15..dc106d0 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -102,10 +102,10 @@ static void analogix_dp_psr_work(struct work_struct *work) struct rockchip_dp_device *dp = container_of(work, typeof(*dp), psr_work);
[PATCH v2 4/4] drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr
turn off Main-link and power down eDP PHY when enable psr, turn on Main-link and power up eDP PHY when disable psr. Signed-off-by: zain wang --- Changes in v2: - misc changes drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 124 - 1 file changed, 70 insertions(+), 54 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index bf87891..58fa1c1 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -120,57 +120,6 @@ static int analogix_dp_get_dpms_mode(struct analogix_dp_device *dp) return mode; } - -int analogix_dp_enable_psr(struct device *dev) -{ - struct analogix_dp_device *dp = dev_get_drvdata(dev); - struct edp_vsc_psr psr_vsc; - - if (!dp->psr_support) - return -EINVAL; - - if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON) - return -EBUSY; - - /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ - memset(_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - psr_vsc.sdp_header.HB2 = 0x2; - psr_vsc.sdp_header.HB3 = 0x8; - - psr_vsc.DB0 = 0; - psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; - - return analogix_dp_send_psr_spd(dp, _vsc); -} -EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); - -int analogix_dp_disable_psr(struct device *dev) -{ - struct analogix_dp_device *dp = dev_get_drvdata(dev); - struct edp_vsc_psr psr_vsc; - - if (!dp->psr_support) - return -EINVAL; - - if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON) - return -EBUSY; - - /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ - memset(_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - psr_vsc.sdp_header.HB2 = 0x2; - psr_vsc.sdp_header.HB3 = 0x8; - - psr_vsc.DB0 = 0; - psr_vsc.DB1 = 0; - - return analogix_dp_send_psr_spd(dp, _vsc); -} -EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); - static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp) { unsigned char psr_version; @@ -191,12 +140,11 @@ static void analogix_dp_enable_sink_psr(struct analogix_dp_device *dp) drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); /* Main-Link transmitter remains active during PSR active states */ - psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION; + psr_en = DP_PSR_CRC_VERIFICATION; drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); /* Enable psr function */ - psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE | -DP_PSR_CRC_VERIFICATION; + psr_en = DP_PSR_ENABLE | DP_PSR_CRC_VERIFICATION; drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); analogix_dp_enable_psr_crc(dp); @@ -899,6 +847,74 @@ static void analogix_dp_commit(struct analogix_dp_device *dp) analogix_dp_enable_sink_psr(dp); } +int analogix_dp_enable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + + if (!dp->psr_support) + return -EINVAL; + + if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON) + return -EBUSY; + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x2; + psr_vsc.sdp_header.HB3 = 0x8; + + psr_vsc.DB0 = 0; + psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; + + analogix_dp_send_psr_spd(dp, _vsc); + + /* Power down the eDP PHY */ + analogix_dp_set_analog_power_down(dp, POWER_ALL, true); + + return 0; +} +EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); + +int analogix_dp_disable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + int ret; + + if (!dp->psr_support) + return -EINVAL; + + if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON) + return -EBUSY; + + /* Power up the eDP PHY */ + analogix_dp_set_analog_power_down(dp, POWER_ALL, false); + + ret = drm_dp_dpcd_writeb(>aux, DP_SET_POWER, DP_SET_POWER_D0); + if (ret < 0) { + dev_err(dp->dev, "Failed to set DP Power0\n"); + } + + analogix_dp_set_link_train(dp, dp->video_info.max_lane_count, + dp->video_info.max_link_rate); + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.H
[PATCH v2 1/4] drm/bridge: analogix_dp: prevent runing enable_psr when disabled bridge.
When disabled bridge, analogix_dp_enable_psr() may run due to timer was set by rockchip_drm_do_flush(), in this case we should return -EBUSY. Signed-off-by: zain wang <w...@rock-chips.com> --- Changes in v2: - add spin_lock to protect dpms_mode drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 43 +++--- drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 1 + 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 0f2e423..b4ce16a 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -98,6 +98,29 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp) return 0; } +static void analogix_dp_set_dpms_mode(struct analogix_dp_device *dp, int mode) +{ + unsigned long flags; + + spin_lock_irqsave(>dpms_mode_lock, flags); + dp->dpms_mode = mode; + spin_unlock_irqrestore(>dpms_mode_lock, flags); + +} + +static int analogix_dp_get_dpms_mode(struct analogix_dp_device *dp) +{ + unsigned long flags; + int mode; + + spin_lock_irqsave(>dpms_mode_lock, flags); + mode = dp->dpms_mode; + spin_unlock_irqrestore(>dpms_mode_lock, flags); + + return mode; +} + + int analogix_dp_enable_psr(struct device *dev) { struct analogix_dp_device *dp = dev_get_drvdata(dev); @@ -106,6 +129,9 @@ int analogix_dp_enable_psr(struct device *dev) if (!dp->psr_support) return -EINVAL; + if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON) + return -EBUSY; + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); psr_vsc.sdp_header.HB0 = 0; @@ -129,6 +155,9 @@ int analogix_dp_disable_psr(struct device *dev) if (!dp->psr_support) return -EINVAL; + if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON) + return -EBUSY; + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); psr_vsc.sdp_header.HB0 = 0; @@ -1073,7 +1102,7 @@ static void analogix_dp_bridge_enable(struct drm_bridge *bridge) { struct analogix_dp_device *dp = bridge->driver_private; - if (dp->dpms_mode == DRM_MODE_DPMS_ON) + if (analogix_dp_get_dpms_mode(dp) == DRM_MODE_DPMS_ON) return; pm_runtime_get_sync(dp->dev); @@ -1086,7 +1115,7 @@ static void analogix_dp_bridge_enable(struct drm_bridge *bridge) enable_irq(dp->irq); analogix_dp_commit(dp); - dp->dpms_mode = DRM_MODE_DPMS_ON; + analogix_dp_set_dpms_mode(dp, DRM_MODE_DPMS_ON); } static void analogix_dp_bridge_disable(struct drm_bridge *bridge) @@ -1094,9 +1123,11 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge) struct analogix_dp_device *dp = bridge->driver_private; int ret; - if (dp->dpms_mode != DRM_MODE_DPMS_ON) + if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON) return; + analogix_dp_set_dpms_mode(dp, DRM_MODE_DPMS_OFF); + if (dp->plat_data->panel) { if (drm_panel_disable(dp->plat_data->panel)) { DRM_ERROR("failed to disable the panel\n"); @@ -1115,8 +1146,6 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge) ret = analogix_dp_prepare_panel(dp, false, true); if (ret) DRM_ERROR("failed to setup the panel ret = %d\n", ret); - - dp->dpms_mode = DRM_MODE_DPMS_OFF; } static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge, @@ -1299,7 +1328,9 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, dev_set_drvdata(dev, dp); dp->dev = >dev; - dp->dpms_mode = DRM_MODE_DPMS_OFF; + + spin_lock_init(>dpms_mode_lock); + analogix_dp_set_dpms_mode(dp, DRM_MODE_DPMS_OFF); mutex_init(>panel_lock); dp->panel_is_modeset = false; diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index 5c6a288..776c844 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -166,6 +166,7 @@ struct analogix_dp_device { struct link_train link_train; struct phy *phy; int dpms_mode; + spinlock_t dpms_mode_lock; int hpd_gpio; boolforce_hpd; boolpsr_support; -- 1.9.1
[PATCH v2 2/4] drm/bridge: analogix_dp: get sync PM when init eDP
Signed-off-by: zain wang <w...@rock-chips.com> --- Changes in v2: None drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index b4ce16a..1bd190e 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1411,10 +1411,12 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, } pm_runtime_enable(dev); + pm_runtime_get_sync(dev); phy_power_on(dp->phy); analogix_dp_init_dp(dp); + pm_runtime_put_sync(dev); ret = devm_request_threaded_irq(>dev, dp->irq, analogix_dp_hardirq, -- 1.9.1
[PATCH v2 1/4] drm/bridge: analogix_dp: prevent runing enable_psr when disabled bridge.
When disabled bridge, analogix_dp_enable_psr() may run due to timer was set by rockchip_drm_do_flush(), in this case we should return -EBUSY. Signed-off-by: zain wang --- Changes in v2: - add spin_lock to protect dpms_mode drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 43 +++--- drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 1 + 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 0f2e423..b4ce16a 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -98,6 +98,29 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp) return 0; } +static void analogix_dp_set_dpms_mode(struct analogix_dp_device *dp, int mode) +{ + unsigned long flags; + + spin_lock_irqsave(>dpms_mode_lock, flags); + dp->dpms_mode = mode; + spin_unlock_irqrestore(>dpms_mode_lock, flags); + +} + +static int analogix_dp_get_dpms_mode(struct analogix_dp_device *dp) +{ + unsigned long flags; + int mode; + + spin_lock_irqsave(>dpms_mode_lock, flags); + mode = dp->dpms_mode; + spin_unlock_irqrestore(>dpms_mode_lock, flags); + + return mode; +} + + int analogix_dp_enable_psr(struct device *dev) { struct analogix_dp_device *dp = dev_get_drvdata(dev); @@ -106,6 +129,9 @@ int analogix_dp_enable_psr(struct device *dev) if (!dp->psr_support) return -EINVAL; + if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON) + return -EBUSY; + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); psr_vsc.sdp_header.HB0 = 0; @@ -129,6 +155,9 @@ int analogix_dp_disable_psr(struct device *dev) if (!dp->psr_support) return -EINVAL; + if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON) + return -EBUSY; + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); psr_vsc.sdp_header.HB0 = 0; @@ -1073,7 +1102,7 @@ static void analogix_dp_bridge_enable(struct drm_bridge *bridge) { struct analogix_dp_device *dp = bridge->driver_private; - if (dp->dpms_mode == DRM_MODE_DPMS_ON) + if (analogix_dp_get_dpms_mode(dp) == DRM_MODE_DPMS_ON) return; pm_runtime_get_sync(dp->dev); @@ -1086,7 +1115,7 @@ static void analogix_dp_bridge_enable(struct drm_bridge *bridge) enable_irq(dp->irq); analogix_dp_commit(dp); - dp->dpms_mode = DRM_MODE_DPMS_ON; + analogix_dp_set_dpms_mode(dp, DRM_MODE_DPMS_ON); } static void analogix_dp_bridge_disable(struct drm_bridge *bridge) @@ -1094,9 +1123,11 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge) struct analogix_dp_device *dp = bridge->driver_private; int ret; - if (dp->dpms_mode != DRM_MODE_DPMS_ON) + if (analogix_dp_get_dpms_mode(dp) != DRM_MODE_DPMS_ON) return; + analogix_dp_set_dpms_mode(dp, DRM_MODE_DPMS_OFF); + if (dp->plat_data->panel) { if (drm_panel_disable(dp->plat_data->panel)) { DRM_ERROR("failed to disable the panel\n"); @@ -1115,8 +1146,6 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge) ret = analogix_dp_prepare_panel(dp, false, true); if (ret) DRM_ERROR("failed to setup the panel ret = %d\n", ret); - - dp->dpms_mode = DRM_MODE_DPMS_OFF; } static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge, @@ -1299,7 +1328,9 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, dev_set_drvdata(dev, dp); dp->dev = >dev; - dp->dpms_mode = DRM_MODE_DPMS_OFF; + + spin_lock_init(>dpms_mode_lock); + analogix_dp_set_dpms_mode(dp, DRM_MODE_DPMS_OFF); mutex_init(>panel_lock); dp->panel_is_modeset = false; diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index 5c6a288..776c844 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -166,6 +166,7 @@ struct analogix_dp_device { struct link_train link_train; struct phy *phy; int dpms_mode; + spinlock_t dpms_mode_lock; int hpd_gpio; boolforce_hpd; boolpsr_support; -- 1.9.1
[PATCH v2 2/4] drm/bridge: analogix_dp: get sync PM when init eDP
Signed-off-by: zain wang --- Changes in v2: None drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index b4ce16a..1bd190e 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1411,10 +1411,12 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, } pm_runtime_enable(dev); + pm_runtime_get_sync(dev); phy_power_on(dp->phy); analogix_dp_init_dp(dp); + pm_runtime_put_sync(dev); ret = devm_request_threaded_irq(>dev, dp->irq, analogix_dp_hardirq, -- 1.9.1
[PATCH v2 0/4] Misc changes to Rockchip PSR drivers
1. prevent runing enable_psr when disabled bridge 2. get sync PM when init eDP 3. detect Sink PSR state after configuring the PSR 4. switch Main-Link and eDP phy when enable/disable psr BR, - Zain Changes in v2: - add spin_lock to protect dpms_mode - misc changes Yakir Yang (1): drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR zain wang (3): drm/bridge: analogix_dp: prevent runing enable_psr when disabled bridge. drm/bridge: analogix_dp: get sync PM when init eDP drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 137 ++--- drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 7 +- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 +++- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 8 +- 4 files changed, 125 insertions(+), 52 deletions(-) -- 1.9.1
[PATCH v2 0/4] Misc changes to Rockchip PSR drivers
1. prevent runing enable_psr when disabled bridge 2. get sync PM when init eDP 3. detect Sink PSR state after configuring the PSR 4. switch Main-Link and eDP phy when enable/disable psr BR, - Zain Changes in v2: - add spin_lock to protect dpms_mode - misc changes Yakir Yang (1): drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR zain wang (3): drm/bridge: analogix_dp: prevent runing enable_psr when disabled bridge. drm/bridge: analogix_dp: get sync PM when init eDP drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 137 ++--- drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 7 +- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 +++- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 8 +- 4 files changed, 125 insertions(+), 52 deletions(-) -- 1.9.1
[PATCH v1 4/4] drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr
turn off Main-link and power down eDP PHY when enable psr, turn on Main-link and power up eDP PHY when disable psr. Signed-off-by: zain wang <w...@rock-chips.com> --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 105 ++--- 1 file changed, 52 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 7177f5f..1bc98ab 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -98,56 +98,6 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp) return 0; } -int analogix_dp_enable_psr(struct device *dev) -{ - struct analogix_dp_device *dp = dev_get_drvdata(dev); - struct edp_vsc_psr psr_vsc; - - if (!dp->psr_support) - return -EINVAL; - - if (dp->dpms_mode != DRM_MODE_DPMS_ON) - return -EBUSY; - - /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ - memset(_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - psr_vsc.sdp_header.HB2 = 0x2; - psr_vsc.sdp_header.HB3 = 0x8; - - psr_vsc.DB0 = 0; - psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; - - return analogix_dp_send_psr_spd(dp, _vsc); -} -EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); - -int analogix_dp_disable_psr(struct device *dev) -{ - struct analogix_dp_device *dp = dev_get_drvdata(dev); - struct edp_vsc_psr psr_vsc; - - if (!dp->psr_support) - return -EINVAL; - - if (dp->dpms_mode != DRM_MODE_DPMS_ON) - return -EBUSY; - - /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ - memset(_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - psr_vsc.sdp_header.HB2 = 0x2; - psr_vsc.sdp_header.HB3 = 0x8; - - psr_vsc.DB0 = 0; - psr_vsc.DB1 = 0; - - return analogix_dp_send_psr_spd(dp, _vsc); -} -EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); - static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp) { unsigned char psr_version; @@ -168,12 +118,11 @@ static void analogix_dp_enable_sink_psr(struct analogix_dp_device *dp) drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); /* Main-Link transmitter remains active during PSR active states */ - psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION; + psr_en = DP_PSR_CRC_VERIFICATION; drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); /* Enable psr function */ - psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE | -DP_PSR_CRC_VERIFICATION; + psr_en = DP_PSR_ENABLE | DP_PSR_CRC_VERIFICATION; drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); analogix_dp_enable_psr_crc(dp); @@ -876,6 +825,56 @@ static void analogix_dp_commit(struct analogix_dp_device *dp) analogix_dp_enable_sink_psr(dp); } +int analogix_dp_enable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + + if (!dp->psr_support) + return -EINVAL; + + if (dp->dpms_mode != DRM_MODE_DPMS_ON) + return -EBUSY; + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x2; + psr_vsc.sdp_header.HB3 = 0x8; + + psr_vsc.DB0 = 0; + psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; + + return analogix_dp_send_psr_spd(dp, _vsc); +} +EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); + +int analogix_dp_disable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + + if (!dp->psr_support) + return -EINVAL; + + if (dp->dpms_mode != DRM_MODE_DPMS_ON) + return -EBUSY; + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x2; + psr_vsc.sdp_header.HB3 = 0x8; + + psr_vsc.DB0 = 0; + psr_vsc.DB1 = 0; + + return analogix_dp_send_psr_spd(dp, _vsc); +} +EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); + /* * This function is a bit of a catch-all for panel preparation, hopefully * simplifying the logic of functions that need to prepare/unprepare the panel -- 1.9.1
[PATCH v1 4/4] drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr
turn off Main-link and power down eDP PHY when enable psr, turn on Main-link and power up eDP PHY when disable psr. Signed-off-by: zain wang --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 105 ++--- 1 file changed, 52 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 7177f5f..1bc98ab 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -98,56 +98,6 @@ static int analogix_dp_detect_hpd(struct analogix_dp_device *dp) return 0; } -int analogix_dp_enable_psr(struct device *dev) -{ - struct analogix_dp_device *dp = dev_get_drvdata(dev); - struct edp_vsc_psr psr_vsc; - - if (!dp->psr_support) - return -EINVAL; - - if (dp->dpms_mode != DRM_MODE_DPMS_ON) - return -EBUSY; - - /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ - memset(_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - psr_vsc.sdp_header.HB2 = 0x2; - psr_vsc.sdp_header.HB3 = 0x8; - - psr_vsc.DB0 = 0; - psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; - - return analogix_dp_send_psr_spd(dp, _vsc); -} -EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); - -int analogix_dp_disable_psr(struct device *dev) -{ - struct analogix_dp_device *dp = dev_get_drvdata(dev); - struct edp_vsc_psr psr_vsc; - - if (!dp->psr_support) - return -EINVAL; - - if (dp->dpms_mode != DRM_MODE_DPMS_ON) - return -EBUSY; - - /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ - memset(_vsc, 0, sizeof(psr_vsc)); - psr_vsc.sdp_header.HB0 = 0; - psr_vsc.sdp_header.HB1 = 0x7; - psr_vsc.sdp_header.HB2 = 0x2; - psr_vsc.sdp_header.HB3 = 0x8; - - psr_vsc.DB0 = 0; - psr_vsc.DB1 = 0; - - return analogix_dp_send_psr_spd(dp, _vsc); -} -EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); - static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp) { unsigned char psr_version; @@ -168,12 +118,11 @@ static void analogix_dp_enable_sink_psr(struct analogix_dp_device *dp) drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); /* Main-Link transmitter remains active during PSR active states */ - psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION; + psr_en = DP_PSR_CRC_VERIFICATION; drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); /* Enable psr function */ - psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE | -DP_PSR_CRC_VERIFICATION; + psr_en = DP_PSR_ENABLE | DP_PSR_CRC_VERIFICATION; drm_dp_dpcd_writeb(>aux, DP_PSR_EN_CFG, psr_en); analogix_dp_enable_psr_crc(dp); @@ -876,6 +825,56 @@ static void analogix_dp_commit(struct analogix_dp_device *dp) analogix_dp_enable_sink_psr(dp); } +int analogix_dp_enable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + + if (!dp->psr_support) + return -EINVAL; + + if (dp->dpms_mode != DRM_MODE_DPMS_ON) + return -EBUSY; + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x2; + psr_vsc.sdp_header.HB3 = 0x8; + + psr_vsc.DB0 = 0; + psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; + + return analogix_dp_send_psr_spd(dp, _vsc); +} +EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); + +int analogix_dp_disable_psr(struct device *dev) +{ + struct analogix_dp_device *dp = dev_get_drvdata(dev); + struct edp_vsc_psr psr_vsc; + + if (!dp->psr_support) + return -EINVAL; + + if (dp->dpms_mode != DRM_MODE_DPMS_ON) + return -EBUSY; + + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ + memset(_vsc, 0, sizeof(psr_vsc)); + psr_vsc.sdp_header.HB0 = 0; + psr_vsc.sdp_header.HB1 = 0x7; + psr_vsc.sdp_header.HB2 = 0x2; + psr_vsc.sdp_header.HB3 = 0x8; + + psr_vsc.DB0 = 0; + psr_vsc.DB1 = 0; + + return analogix_dp_send_psr_spd(dp, _vsc); +} +EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); + /* * This function is a bit of a catch-all for panel preparation, hopefully * simplifying the logic of functions that need to prepare/unprepare the panel -- 1.9.1
[PATCH v1 3/4] drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR
From: Yakir Yang <y...@rock-chips.com> Make sure the request PSR state takes effect in analogix_dp_send_psr_spd() function, or print the sink PSR error state if we failed to apply the requested PSR setting. Signed-off-by: Yakir Yang <y...@rock-chips.com> Signed-off-by: Zain Wang <w...@rock-chips.com> --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 6 ++ drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 6 -- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 -- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 8 --- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 026ec91..7177f5f 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -119,8 +119,7 @@ int analogix_dp_enable_psr(struct device *dev) psr_vsc.DB0 = 0; psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; - analogix_dp_send_psr_spd(dp, _vsc); - return 0; + return analogix_dp_send_psr_spd(dp, _vsc); } EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); @@ -145,8 +144,7 @@ int analogix_dp_disable_psr(struct device *dev) psr_vsc.DB0 = 0; psr_vsc.DB1 = 0; - analogix_dp_send_psr_spd(dp, _vsc); - return 0; + return analogix_dp_send_psr_spd(dp, _vsc); } EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index 5c6a288..cdc0535 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -20,6 +20,8 @@ #define MAX_CR_LOOP 5 #define MAX_EQ_LOOP 5 +#define DP_TIMEOUT_PSR_LOOP_MS msecs_to_jiffies(300) + /* DP_MAX_LANE_COUNT */ #define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) #define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) @@ -247,8 +249,8 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp); void analogix_dp_enable_scrambling(struct analogix_dp_device *dp); void analogix_dp_disable_scrambling(struct analogix_dp_device *dp); void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp); -void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, - struct edp_vsc_psr *vsc); +int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, +struct edp_vsc_psr *vsc); ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, struct drm_dp_aux_msg *msg); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index cd37ac0..9e1177c 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -992,10 +992,12 @@ void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp) writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON); } -void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, - struct edp_vsc_psr *vsc) +int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, +struct edp_vsc_psr *vsc) { + unsigned long timeout; unsigned int val; + u8 sink; /* don't send info frame */ val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); @@ -1036,6 +1038,25 @@ void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); val |= IF_EN; writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); + + timeout = jiffies + DP_TIMEOUT_PSR_LOOP_MS; + while (time_before(jiffies, timeout)) { + val = drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, ); + if (val != 1) { + dev_err(dp->dev, "PSR_STATUS read failed ret=%d", val); + return -EBUSY; + } + + if ((vsc->DB1 && sink == DP_PSR_SINK_ACTIVE_RFB) || + (!vsc->DB1 && sink == DP_PSR_SINK_INACTIVE)) + return 0; + + usleep_range(1000, 1500); + } + + dev_warn(dp->dev, "Failed to apply PSR, sink state was [%x]", sink); + + return -ETIMEDOUT; } ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index e83be15..dc106d0 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -102,10 +102,10 @@ static void analogix_dp_psr_work(struct work_struct *work) struct rockchip_dp_device *dp =
[PATCH v1 3/4] drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR
From: Yakir Yang Make sure the request PSR state takes effect in analogix_dp_send_psr_spd() function, or print the sink PSR error state if we failed to apply the requested PSR setting. Signed-off-by: Yakir Yang Signed-off-by: Zain Wang --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 6 ++ drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 6 -- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 -- drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 8 --- 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 026ec91..7177f5f 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -119,8 +119,7 @@ int analogix_dp_enable_psr(struct device *dev) psr_vsc.DB0 = 0; psr_vsc.DB1 = EDP_VSC_PSR_STATE_ACTIVE | EDP_VSC_PSR_CRC_VALUES_VALID; - analogix_dp_send_psr_spd(dp, _vsc); - return 0; + return analogix_dp_send_psr_spd(dp, _vsc); } EXPORT_SYMBOL_GPL(analogix_dp_enable_psr); @@ -145,8 +144,7 @@ int analogix_dp_disable_psr(struct device *dev) psr_vsc.DB0 = 0; psr_vsc.DB1 = 0; - analogix_dp_send_psr_spd(dp, _vsc); - return 0; + return analogix_dp_send_psr_spd(dp, _vsc); } EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index 5c6a288..cdc0535 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -20,6 +20,8 @@ #define MAX_CR_LOOP 5 #define MAX_EQ_LOOP 5 +#define DP_TIMEOUT_PSR_LOOP_MS msecs_to_jiffies(300) + /* DP_MAX_LANE_COUNT */ #define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) #define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) @@ -247,8 +249,8 @@ void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp); void analogix_dp_enable_scrambling(struct analogix_dp_device *dp); void analogix_dp_disable_scrambling(struct analogix_dp_device *dp); void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp); -void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, - struct edp_vsc_psr *vsc); +int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, +struct edp_vsc_psr *vsc); ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, struct drm_dp_aux_msg *msg); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index cd37ac0..9e1177c 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -992,10 +992,12 @@ void analogix_dp_enable_psr_crc(struct analogix_dp_device *dp) writel(PSR_VID_CRC_ENABLE, dp->reg_base + ANALOGIX_DP_CRC_CON); } -void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, - struct edp_vsc_psr *vsc) +int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, +struct edp_vsc_psr *vsc) { + unsigned long timeout; unsigned int val; + u8 sink; /* don't send info frame */ val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); @@ -1036,6 +1038,25 @@ void analogix_dp_send_psr_spd(struct analogix_dp_device *dp, val = readl(dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); val |= IF_EN; writel(val, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); + + timeout = jiffies + DP_TIMEOUT_PSR_LOOP_MS; + while (time_before(jiffies, timeout)) { + val = drm_dp_dpcd_readb(>aux, DP_PSR_STATUS, ); + if (val != 1) { + dev_err(dp->dev, "PSR_STATUS read failed ret=%d", val); + return -EBUSY; + } + + if ((vsc->DB1 && sink == DP_PSR_SINK_ACTIVE_RFB) || + (!vsc->DB1 && sink == DP_PSR_SINK_INACTIVE)) + return 0; + + usleep_range(1000, 1500); + } + + dev_warn(dp->dev, "Failed to apply PSR, sink state was [%x]", sink); + + return -ETIMEDOUT; } ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, diff --git a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c index e83be15..dc106d0 100644 --- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c +++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c @@ -102,10 +102,10 @@ static void analogix_dp_psr_work(struct work_struct *work) struct rockchip_dp_device *dp = container_of(work, typeof(*dp), psr_work); st
[PATCH v1 0/4] Misc changes to Rockchip PSR drivers
1. prevent runing enable_psr when disabled bridge 2. get sync PM when init eDP 3. detect Sink PSR state after configuring the PSR 4. switch Main-Link and eDP phy when enable/disable psr BR, - Zain Yakir Yang (1): drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR zain wang (3): drm/bridge: analogix_dp: prevent runing enable_psr when disabled bridge. drm/bridge: analogix_dp: get sync PM when init eDP drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 107 +++-- drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 6 +- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 - drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 8 +- 4 files changed, 88 insertions(+), 58 deletions(-) -- 1.9.1
[PATCH v1 1/4] drm/bridge: analogix_dp: prevent runing enable_psr when disabled bridge.
When disabled bridge, analogix_dp_enable_psr() may run due to timer was set by rockchip_drm_do_flush(), in this case we should return -EBUSY. Signed-off-by: zain wang <w...@rock-chips.com> --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 0f2e423..206529a 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -106,6 +106,9 @@ int analogix_dp_enable_psr(struct device *dev) if (!dp->psr_support) return -EINVAL; + if (dp->dpms_mode != DRM_MODE_DPMS_ON) + return -EBUSY; + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); psr_vsc.sdp_header.HB0 = 0; @@ -129,6 +132,9 @@ int analogix_dp_disable_psr(struct device *dev) if (!dp->psr_support) return -EINVAL; + if (dp->dpms_mode != DRM_MODE_DPMS_ON) + return -EBUSY; + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); psr_vsc.sdp_header.HB0 = 0; @@ -1097,6 +1103,8 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge) if (dp->dpms_mode != DRM_MODE_DPMS_ON) return; + dp->dpms_mode = DRM_MODE_DPMS_OFF; + if (dp->plat_data->panel) { if (drm_panel_disable(dp->plat_data->panel)) { DRM_ERROR("failed to disable the panel\n"); @@ -1115,8 +1123,6 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge) ret = analogix_dp_prepare_panel(dp, false, true); if (ret) DRM_ERROR("failed to setup the panel ret = %d\n", ret); - - dp->dpms_mode = DRM_MODE_DPMS_OFF; } static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge, -- 1.9.1
[PATCH v1 2/4] drm/bridge: analogix_dp: get sync PM when init eDP
Signed-off-by: zain wang <w...@rock-chips.com> --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 206529a..026ec91 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1386,10 +1386,12 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, } pm_runtime_enable(dev); + pm_runtime_get_sync(dev); phy_power_on(dp->phy); analogix_dp_init_dp(dp); + pm_runtime_put_sync(dev); ret = devm_request_threaded_irq(>dev, dp->irq, analogix_dp_hardirq, -- 1.9.1
[PATCH v1 0/4] Misc changes to Rockchip PSR drivers
1. prevent runing enable_psr when disabled bridge 2. get sync PM when init eDP 3. detect Sink PSR state after configuring the PSR 4. switch Main-Link and eDP phy when enable/disable psr BR, - Zain Yakir Yang (1): drm/bridge: analogix_dp: detect Sink PSR state after configuring the PSR zain wang (3): drm/bridge: analogix_dp: prevent runing enable_psr when disabled bridge. drm/bridge: analogix_dp: get sync PM when init eDP drm: bridge/analogix: switch Main-link and eDP PHY when enable/disable psr drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 107 +++-- drivers/gpu/drm/bridge/analogix/analogix_dp_core.h | 6 +- drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c | 25 - drivers/gpu/drm/rockchip/analogix_dp-rockchip.c| 8 +- 4 files changed, 88 insertions(+), 58 deletions(-) -- 1.9.1
[PATCH v1 1/4] drm/bridge: analogix_dp: prevent runing enable_psr when disabled bridge.
When disabled bridge, analogix_dp_enable_psr() may run due to timer was set by rockchip_drm_do_flush(), in this case we should return -EBUSY. Signed-off-by: zain wang --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 0f2e423..206529a 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -106,6 +106,9 @@ int analogix_dp_enable_psr(struct device *dev) if (!dp->psr_support) return -EINVAL; + if (dp->dpms_mode != DRM_MODE_DPMS_ON) + return -EBUSY; + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); psr_vsc.sdp_header.HB0 = 0; @@ -129,6 +132,9 @@ int analogix_dp_disable_psr(struct device *dev) if (!dp->psr_support) return -EINVAL; + if (dp->dpms_mode != DRM_MODE_DPMS_ON) + return -EBUSY; + /* Prepare VSC packet as per EDP 1.4 spec, Table 6.9 */ memset(_vsc, 0, sizeof(psr_vsc)); psr_vsc.sdp_header.HB0 = 0; @@ -1097,6 +1103,8 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge) if (dp->dpms_mode != DRM_MODE_DPMS_ON) return; + dp->dpms_mode = DRM_MODE_DPMS_OFF; + if (dp->plat_data->panel) { if (drm_panel_disable(dp->plat_data->panel)) { DRM_ERROR("failed to disable the panel\n"); @@ -1115,8 +1123,6 @@ static void analogix_dp_bridge_disable(struct drm_bridge *bridge) ret = analogix_dp_prepare_panel(dp, false, true); if (ret) DRM_ERROR("failed to setup the panel ret = %d\n", ret); - - dp->dpms_mode = DRM_MODE_DPMS_OFF; } static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge, -- 1.9.1
[PATCH v1 2/4] drm/bridge: analogix_dp: get sync PM when init eDP
Signed-off-by: zain wang --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 206529a..026ec91 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1386,10 +1386,12 @@ int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, } pm_runtime_enable(dev); + pm_runtime_get_sync(dev); phy_power_on(dp->phy); analogix_dp_init_dp(dp); + pm_runtime_put_sync(dev); ret = devm_request_threaded_irq(>dev, dp->irq, analogix_dp_hardirq, -- 1.9.1
Re: [PATCH v5 2/4] clk: rockchip: set an ID for crypto clk
On 2015年11月25日 16:14, Heiko Stübner wrote: > Hi Zain, > > Am Mittwoch, 25. November 2015, 13:43:31 schrieb Zain Wang: >> Set an ID for crypto clk, so that it can be called in other part. >> >> Signed-off-by: Zain Wang >> Acked-by: Michael Turquette >> Tested-by: Heiko Stuebner > I've already taken this patch, so no need to resubmit on further version. Thanks for your reminding. Zain > > Heiko > > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5 2/4] clk: rockchip: set an ID for crypto clk
On 2015年11月25日 16:14, Heiko Stübner wrote: > Hi Zain, > > Am Mittwoch, 25. November 2015, 13:43:31 schrieb Zain Wang: >> Set an ID for crypto clk, so that it can be called in other part. >> >> Signed-off-by: Zain Wang <zain.w...@rock-chips.com> >> Acked-by: Michael Turquette <mturque...@baylibre.com> >> Tested-by: Heiko Stuebner <he...@sntech.de> > I've already taken this patch, so no need to resubmit on further version. Thanks for your reminding. Zain > > Heiko > > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288
Crypto driver support: ecb(aes) cbc(aes) ecb(des) cbc(des) ecb(des3_ede) cbc(des3_ede) You can alloc tags above in your case. And other algorithms and platforms will be added later on. Signed-off-by: Zain Wang Tested-by: Heiko Stuebner --- Changed in v5: - copy IV back after operation - use cra_block_size to tell AES from DES instaed flag AES/TDES Changed in v4: - modify irq function - add devm_add_action in probe - fix some minor mistakes Changed in v3: - add OF depended in Kconfig - rename some variate - add reset property - remove crypto_p variate Changed in v2: - remove some part about hash - add weak key detection - changed some variate's type Changed in v1: - modify some variate's name - modify some variate's type - modify some return value - remove or modify some print info - use more dev_xxx in probe - modify the prio of cipher - add Kconfig drivers/crypto/Kconfig | 11 + drivers/crypto/Makefile| 1 + drivers/crypto/rockchip/Makefile | 3 + drivers/crypto/rockchip/rk3288_crypto.c| 393 drivers/crypto/rockchip/rk3288_crypto.h| 216 + drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 503 + 6 files changed, 1127 insertions(+) create mode 100644 drivers/crypto/rockchip/Makefile create mode 100644 drivers/crypto/rockchip/rk3288_crypto.c create mode 100644 drivers/crypto/rockchip/rk3288_crypto.h create mode 100644 drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 5357bc1..95dccde 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -497,4 +497,15 @@ config CRYPTO_DEV_SUN4I_SS To compile this driver as a module, choose M here: the module will be called sun4i-ss. +config CRYPTO_DEV_ROCKCHIP + tristate "Rockchip's Cryptographic Engine driver" + depends on OF && ARCH_ROCKCHIP + select CRYPTO_AES + select CRYPTO_DES + select CRYPTO_BLKCIPHER + + help + This driver interfaces with the hardware crypto accelerator. + Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode. + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index c3ced6f..713de9d 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -29,3 +29,4 @@ obj-$(CONFIG_CRYPTO_DEV_QAT) += qat/ obj-$(CONFIG_CRYPTO_DEV_QCE) += qce/ obj-$(CONFIG_CRYPTO_DEV_VMX) += vmx/ obj-$(CONFIG_CRYPTO_DEV_SUN4I_SS) += sunxi-ss/ +obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rockchip/ diff --git a/drivers/crypto/rockchip/Makefile b/drivers/crypto/rockchip/Makefile new file mode 100644 index 000..7051c6c --- /dev/null +++ b/drivers/crypto/rockchip/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rk_crypto.o +rk_crypto-objs := rk3288_crypto.o \ + rk3288_crypto_ablkcipher.o \ diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c new file mode 100644 index 000..6b72f8d --- /dev/null +++ b/drivers/crypto/rockchip/rk3288_crypto.c @@ -0,0 +1,393 @@ +/* + * Crypto acceleration support for Rockchip RK3288 + * + * Copyright (c) 2015, Fuzhou Rockchip Electronics Co., Ltd + * + * Author: Zain Wang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * Some ideas are from marvell-cesa.c and s5p-sss.c driver. + */ + +#include "rk3288_crypto.h" +#include +#include +#include +#include +#include +#include + +static int rk_crypto_enable_clk(struct rk_crypto_info *dev) +{ + int err; + + err = clk_prepare_enable(dev->sclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock sclk\n", + __func__, __LINE__); + goto err_return; + } + err = clk_prepare_enable(dev->aclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock aclk\n", + __func__, __LINE__); + goto err_aclk; + } + err = clk_prepare_enable(dev->hclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock hclk\n", + __func__, __LINE__); + goto err_hclk; + } + err = clk_prepare_enable(dev->dmaclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock dmaclk\n", + __func__, __LINE__); + goto err_dmaclk; + } + return err; +err_dmaclk: + clk_disable_unprepare(dev->hclk); +err_hclk: + clk_disable_unprepare(dev->aclk); +err_aclk: + clk_disable_unprepare(dev->sclk)
[PATCH v5 2/4] clk: rockchip: set an ID for crypto clk
Set an ID for crypto clk, so that it can be called in other part. Signed-off-by: Zain Wang Acked-by: Michael Turquette Tested-by: Heiko Stuebner --- Changed in v5: - None Changed in v4: - None Changed in v3: - None Changed in v2: - None Changed in v1: - define SCLK_CRYPTO in rk3288-cru.h - use SCLK_CRYPTO instead of SRST_CRYPTO drivers/clk/rockchip/clk-rk3288.c | 2 +- include/dt-bindings/clock/rk3288-cru.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 9040878..3fceda1 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -295,7 +295,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKGATE_CON(0), 4, GFLAGS), GATE(0, "c2c_host", "aclk_cpu_src", 0, RK3288_CLKGATE_CON(13), 8, GFLAGS), - COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, + COMPOSITE_NOMUX(SCLK_CRYPTO, "crypto", "aclk_cpu_pre", 0, RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, RK3288_CLKGATE_CON(5), 4, GFLAGS), GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, diff --git a/include/dt-bindings/clock/rk3288-cru.h b/include/dt-bindings/clock/rk3288-cru.h index c719aac..30dcd60 100644 --- a/include/dt-bindings/clock/rk3288-cru.h +++ b/include/dt-bindings/clock/rk3288-cru.h @@ -86,6 +86,7 @@ #define SCLK_USBPHY480M_SRC122 #define SCLK_PVTM_CORE 123 #define SCLK_PVTM_GPU 124 +#define SCLK_CRYPTO125 #define SCLK_MAC 151 #define SCLK_MACREF_OUT152 -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 1/4] crypto: rockchip/crypto - add DT bindings documentation
Add DT bindings documentation for the rk3288 crypto drivers. Signed-off-by: Zain Wang Acked-by: Rob Herring Tested-by: Heiko Stuebner --- Changed in v5: - None Changed in v4: - None Changed in v3: - add reset property Changed in v2: - None Changed in v1: - remove the _crypto suffix - use "rockchip,rk3288-crypto" instead of "rockchip,rk3288" - remove the description of status .../devicetree/bindings/crypto/rockchip-crypto.txt | 29 ++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt diff --git a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt new file mode 100644 index 000..096df34 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt @@ -0,0 +1,29 @@ +Rockchip Electronics And Security Accelerator + +Required properties: +- compatible: Should be "rockchip,rk3288-crypto" +- reg: Base physical address of the engine and length of memory mapped + region +- interrupts: Interrupt number +- clocks: Reference to the clocks about crypto +- clock-names: "aclk" used to clock data + "hclk" used to clock data + "sclk" used to clock crypto accelerator + "apb_pclk" used to clock dma +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must include the name "crypto-rst". + +Examples: + + crypto: cypto-controller@ff8a { + compatible = "rockchip,rk3288-crypto"; + reg = <0xff8a 0x4000>; + interrupts = ; + clocks = < ACLK_CRYPTO>, < HCLK_CRYPTO>, +< SCLK_CRYPTO>, < ACLK_DMAC1>; + clock-names = "aclk", "hclk", "sclk", "apb_pclk"; + resets = < SRST_CRYPTO>; + reset-names = "crypto-rst"; + status = "okay"; + }; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 0/4] crypto: add crypto accelerator support for rk3288
Changed in v5: - copy IV back after operation - use cra_block_size to tell AES from DES instaed flag AES/TDES Changed in v4: - modify irq function - add devm_add_action in probe - fix some minor mistakes Changed in v3: - add OF depended in Kconfig - rename some variate - add reset property - remove crypto_p variate Changed in v2: - remove some part about hash - add weak key detection - changed some variate's type Changed in v1: - modify some variate's name - modify some variate's type - modify some return value - remove or modify some print info - use more dev_xxx in probe - modify the prio of cipher - add Kconfig Zain Wang (4): crypto: rockchip/crypto - add DT bindings documentation clk: rockchip: set an ID for crypto clk Crypto: rockchip/crypto - add crypto driver for rk3288 ARM: dts: rockchip: Add Crypto node for rk3288 .../devicetree/bindings/crypto/rockchip-crypto.txt | 29 ++ arch/arm/boot/dts/rk3288.dtsi | 12 + drivers/clk/rockchip/clk-rk3288.c | 2 +- drivers/crypto/Kconfig | 11 + drivers/crypto/Makefile| 1 + drivers/crypto/rockchip/Makefile | 3 + drivers/crypto/rockchip/rk3288_crypto.c| 393 drivers/crypto/rockchip/rk3288_crypto.h| 216 + drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 503 + include/dt-bindings/clock/rk3288-cru.h | 1 + 10 files changed, 1170 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt create mode 100644 drivers/crypto/rockchip/Makefile create mode 100644 drivers/crypto/rockchip/rk3288_crypto.c create mode 100644 drivers/crypto/rockchip/rk3288_crypto.h create mode 100644 drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 4/4] ARM: dts: rockchip: Add Crypto node for rk3288
Add Crypto node for rk3288 including crypto controller and dma clk. Signed-off-by: Zain Wang Tested-by: Heiko Stuebner --- Changed in v5: - None Changed in v4: - None Changed in v3: - add reset property Changed in v2: - None Changed in v1: - remove the _crypto suffix - use "rockchip,rk3288-crypto" instead of "rockchip,rk3288" arch/arm/boot/dts/rk3288.dtsi | 12 1 file changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index ad44d80..c6b1aa4 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -781,6 +781,18 @@ status = "disabled"; }; + crypto: cypto-controller@ff8a { + compatible = "rockchip,rk3288-crypto"; + reg = <0xff8a 0x4000>; + interrupts = ; + clocks = < ACLK_CRYPTO>, < HCLK_CRYPTO>, +< SCLK_CRYPTO>, < ACLK_DMAC1>; + clock-names = "aclk", "hclk", "sclk", "apb_pclk"; + resets = < SRST_CRYPTO>; + reset-names = "crypto-rst"; + status = "okay"; + }; + vopb: vop@ff93 { compatible = "rockchip,rk3288-vop"; reg = <0xff93 0x19c>; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 4/4] ARM: dts: rockchip: Add Crypto node for rk3288
Add Crypto node for rk3288 including crypto controller and dma clk. Signed-off-by: Zain Wang <zain.w...@rock-chips.com> Tested-by: Heiko Stuebner <he...@sntech.de> --- Changed in v5: - None Changed in v4: - None Changed in v3: - add reset property Changed in v2: - None Changed in v1: - remove the _crypto suffix - use "rockchip,rk3288-crypto" instead of "rockchip,rk3288" arch/arm/boot/dts/rk3288.dtsi | 12 1 file changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index ad44d80..c6b1aa4 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -781,6 +781,18 @@ status = "disabled"; }; + crypto: cypto-controller@ff8a { + compatible = "rockchip,rk3288-crypto"; + reg = <0xff8a 0x4000>; + interrupts = ; + clocks = < ACLK_CRYPTO>, < HCLK_CRYPTO>, +< SCLK_CRYPTO>, < ACLK_DMAC1>; + clock-names = "aclk", "hclk", "sclk", "apb_pclk"; + resets = < SRST_CRYPTO>; + reset-names = "crypto-rst"; + status = "okay"; + }; + vopb: vop@ff93 { compatible = "rockchip,rk3288-vop"; reg = <0xff93 0x19c>; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 0/4] crypto: add crypto accelerator support for rk3288
Changed in v5: - copy IV back after operation - use cra_block_size to tell AES from DES instaed flag AES/TDES Changed in v4: - modify irq function - add devm_add_action in probe - fix some minor mistakes Changed in v3: - add OF depended in Kconfig - rename some variate - add reset property - remove crypto_p variate Changed in v2: - remove some part about hash - add weak key detection - changed some variate's type Changed in v1: - modify some variate's name - modify some variate's type - modify some return value - remove or modify some print info - use more dev_xxx in probe - modify the prio of cipher - add Kconfig Zain Wang (4): crypto: rockchip/crypto - add DT bindings documentation clk: rockchip: set an ID for crypto clk Crypto: rockchip/crypto - add crypto driver for rk3288 ARM: dts: rockchip: Add Crypto node for rk3288 .../devicetree/bindings/crypto/rockchip-crypto.txt | 29 ++ arch/arm/boot/dts/rk3288.dtsi | 12 + drivers/clk/rockchip/clk-rk3288.c | 2 +- drivers/crypto/Kconfig | 11 + drivers/crypto/Makefile| 1 + drivers/crypto/rockchip/Makefile | 3 + drivers/crypto/rockchip/rk3288_crypto.c| 393 drivers/crypto/rockchip/rk3288_crypto.h| 216 + drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 503 + include/dt-bindings/clock/rk3288-cru.h | 1 + 10 files changed, 1170 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt create mode 100644 drivers/crypto/rockchip/Makefile create mode 100644 drivers/crypto/rockchip/rk3288_crypto.c create mode 100644 drivers/crypto/rockchip/rk3288_crypto.h create mode 100644 drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 1/4] crypto: rockchip/crypto - add DT bindings documentation
Add DT bindings documentation for the rk3288 crypto drivers. Signed-off-by: Zain Wang <zain.w...@rock-chips.com> Acked-by: Rob Herring <r...@kernel.org> Tested-by: Heiko Stuebner <he...@sntech.de> --- Changed in v5: - None Changed in v4: - None Changed in v3: - add reset property Changed in v2: - None Changed in v1: - remove the _crypto suffix - use "rockchip,rk3288-crypto" instead of "rockchip,rk3288" - remove the description of status .../devicetree/bindings/crypto/rockchip-crypto.txt | 29 ++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt diff --git a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt new file mode 100644 index 000..096df34 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt @@ -0,0 +1,29 @@ +Rockchip Electronics And Security Accelerator + +Required properties: +- compatible: Should be "rockchip,rk3288-crypto" +- reg: Base physical address of the engine and length of memory mapped + region +- interrupts: Interrupt number +- clocks: Reference to the clocks about crypto +- clock-names: "aclk" used to clock data + "hclk" used to clock data + "sclk" used to clock crypto accelerator + "apb_pclk" used to clock dma +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must include the name "crypto-rst". + +Examples: + + crypto: cypto-controller@ff8a { + compatible = "rockchip,rk3288-crypto"; + reg = <0xff8a 0x4000>; + interrupts = ; + clocks = < ACLK_CRYPTO>, < HCLK_CRYPTO>, +< SCLK_CRYPTO>, < ACLK_DMAC1>; + clock-names = "aclk", "hclk", "sclk", "apb_pclk"; + resets = < SRST_CRYPTO>; + reset-names = "crypto-rst"; + status = "okay"; + }; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 2/4] clk: rockchip: set an ID for crypto clk
Set an ID for crypto clk, so that it can be called in other part. Signed-off-by: Zain Wang <zain.w...@rock-chips.com> Acked-by: Michael Turquette <mturque...@baylibre.com> Tested-by: Heiko Stuebner <he...@sntech.de> --- Changed in v5: - None Changed in v4: - None Changed in v3: - None Changed in v2: - None Changed in v1: - define SCLK_CRYPTO in rk3288-cru.h - use SCLK_CRYPTO instead of SRST_CRYPTO drivers/clk/rockchip/clk-rk3288.c | 2 +- include/dt-bindings/clock/rk3288-cru.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 9040878..3fceda1 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -295,7 +295,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKGATE_CON(0), 4, GFLAGS), GATE(0, "c2c_host", "aclk_cpu_src", 0, RK3288_CLKGATE_CON(13), 8, GFLAGS), - COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, + COMPOSITE_NOMUX(SCLK_CRYPTO, "crypto", "aclk_cpu_pre", 0, RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, RK3288_CLKGATE_CON(5), 4, GFLAGS), GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, diff --git a/include/dt-bindings/clock/rk3288-cru.h b/include/dt-bindings/clock/rk3288-cru.h index c719aac..30dcd60 100644 --- a/include/dt-bindings/clock/rk3288-cru.h +++ b/include/dt-bindings/clock/rk3288-cru.h @@ -86,6 +86,7 @@ #define SCLK_USBPHY480M_SRC122 #define SCLK_PVTM_CORE 123 #define SCLK_PVTM_GPU 124 +#define SCLK_CRYPTO125 #define SCLK_MAC 151 #define SCLK_MACREF_OUT152 -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288
Crypto driver support: ecb(aes) cbc(aes) ecb(des) cbc(des) ecb(des3_ede) cbc(des3_ede) You can alloc tags above in your case. And other algorithms and platforms will be added later on. Signed-off-by: Zain Wang <zain.w...@rock-chips.com> Tested-by: Heiko Stuebner <he...@sntech.de> --- Changed in v5: - copy IV back after operation - use cra_block_size to tell AES from DES instaed flag AES/TDES Changed in v4: - modify irq function - add devm_add_action in probe - fix some minor mistakes Changed in v3: - add OF depended in Kconfig - rename some variate - add reset property - remove crypto_p variate Changed in v2: - remove some part about hash - add weak key detection - changed some variate's type Changed in v1: - modify some variate's name - modify some variate's type - modify some return value - remove or modify some print info - use more dev_xxx in probe - modify the prio of cipher - add Kconfig drivers/crypto/Kconfig | 11 + drivers/crypto/Makefile| 1 + drivers/crypto/rockchip/Makefile | 3 + drivers/crypto/rockchip/rk3288_crypto.c| 393 drivers/crypto/rockchip/rk3288_crypto.h| 216 + drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 503 + 6 files changed, 1127 insertions(+) create mode 100644 drivers/crypto/rockchip/Makefile create mode 100644 drivers/crypto/rockchip/rk3288_crypto.c create mode 100644 drivers/crypto/rockchip/rk3288_crypto.h create mode 100644 drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 5357bc1..95dccde 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -497,4 +497,15 @@ config CRYPTO_DEV_SUN4I_SS To compile this driver as a module, choose M here: the module will be called sun4i-ss. +config CRYPTO_DEV_ROCKCHIP + tristate "Rockchip's Cryptographic Engine driver" + depends on OF && ARCH_ROCKCHIP + select CRYPTO_AES + select CRYPTO_DES + select CRYPTO_BLKCIPHER + + help + This driver interfaces with the hardware crypto accelerator. + Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode. + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index c3ced6f..713de9d 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -29,3 +29,4 @@ obj-$(CONFIG_CRYPTO_DEV_QAT) += qat/ obj-$(CONFIG_CRYPTO_DEV_QCE) += qce/ obj-$(CONFIG_CRYPTO_DEV_VMX) += vmx/ obj-$(CONFIG_CRYPTO_DEV_SUN4I_SS) += sunxi-ss/ +obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rockchip/ diff --git a/drivers/crypto/rockchip/Makefile b/drivers/crypto/rockchip/Makefile new file mode 100644 index 000..7051c6c --- /dev/null +++ b/drivers/crypto/rockchip/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rk_crypto.o +rk_crypto-objs := rk3288_crypto.o \ + rk3288_crypto_ablkcipher.o \ diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c new file mode 100644 index 000..6b72f8d --- /dev/null +++ b/drivers/crypto/rockchip/rk3288_crypto.c @@ -0,0 +1,393 @@ +/* + * Crypto acceleration support for Rockchip RK3288 + * + * Copyright (c) 2015, Fuzhou Rockchip Electronics Co., Ltd + * + * Author: Zain Wang <zain.w...@rock-chips.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * Some ideas are from marvell-cesa.c and s5p-sss.c driver. + */ + +#include "rk3288_crypto.h" +#include +#include +#include +#include +#include +#include + +static int rk_crypto_enable_clk(struct rk_crypto_info *dev) +{ + int err; + + err = clk_prepare_enable(dev->sclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock sclk\n", + __func__, __LINE__); + goto err_return; + } + err = clk_prepare_enable(dev->aclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock aclk\n", + __func__, __LINE__); + goto err_aclk; + } + err = clk_prepare_enable(dev->hclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock hclk\n", + __func__, __LINE__); + goto err_hclk; + } + err = clk_prepare_enable(dev->dmaclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock dmaclk\n", + __func__, __LINE__); + goto err_dmaclk; + } + return err; +err_dmaclk: + clk_disable_unprepare(dev->hclk); +err_hclk: + clk_disable_unprepa
Re: [PATCH v4 2/4] clk: rockchip: set an ID for crypto clk
On 2015年11月24日 07:24, Heiko Stübner wrote: > Hi Zain, > > Am Dienstag, 17. November 2015, 12:00:45 schrieb Zain Wang: >> Set an ID for crypto clk, so that it can be called in other part. >> >> Signed-off-by: Zain Wang >> Acked-by: Michael Turquette >> Tested-by: Heiko Stuebner > I've split this into the header and clk-rk3288.c changes and applied it to my > clk-ids and clock branch for 4.5 Thanks for your responding. Thanks Zain > > Thanks > Heiko > > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v4 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288
On 2015年11月23日 20:51, Herbert Xu wrote: > On Tue, Nov 17, 2015 at 12:00:46PM +0800, Zain Wang wrote: >> +static void rk_ablk_hw_init(struct rk_crypto_info *dev) >> +{ >> +struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(dev->ablk_req); >> +struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm); >> +u32 conf_reg = 0; >> + >> +if (dev->mode & TDES) { >> +dev->mode &= ~TDES; >> +dev->mode |= RK_CRYPTO_TDES_FIFO_MODE | >> + RK_CRYPTO_TDES_BYTESWAP_KEY | >> + RK_CRYPTO_TDES_BYTESWAP_IV; >> +CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, dev->mode); >> + >> +memcpy(dev->reg + RK_CRYPTO_TDES_IV_0, dev->ablk_req->info, 8); > Please ensure that the IV is copied back after the operation. > I know that many existing drivers are buggy in this regard but > they will be fixed soon and we will start enforcing this rule > so I don't want to add any new drivers that break this rule. Thanks your responding, I will fix it in v5. > > Thanks, -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v4 2/4] clk: rockchip: set an ID for crypto clk
On 2015年11月24日 07:24, Heiko Stübner wrote: > Hi Zain, > > Am Dienstag, 17. November 2015, 12:00:45 schrieb Zain Wang: >> Set an ID for crypto clk, so that it can be called in other part. >> >> Signed-off-by: Zain Wang <zain.w...@rock-chips.com> >> Acked-by: Michael Turquette <mturque...@baylibre.com> >> Tested-by: Heiko Stuebner <he...@sntech.de> > I've split this into the header and clk-rk3288.c changes and applied it to my > clk-ids and clock branch for 4.5 Thanks for your responding. Thanks Zain > > Thanks > Heiko > > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v4 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288
On 2015年11月23日 20:51, Herbert Xu wrote: > On Tue, Nov 17, 2015 at 12:00:46PM +0800, Zain Wang wrote: >> +static void rk_ablk_hw_init(struct rk_crypto_info *dev) >> +{ >> +struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(dev->ablk_req); >> +struct rk_cipher_ctx *ctx = crypto_ablkcipher_ctx(tfm); >> +u32 conf_reg = 0; >> + >> +if (dev->mode & TDES) { >> +dev->mode &= ~TDES; >> +dev->mode |= RK_CRYPTO_TDES_FIFO_MODE | >> + RK_CRYPTO_TDES_BYTESWAP_KEY | >> + RK_CRYPTO_TDES_BYTESWAP_IV; >> +CRYPTO_WRITE(dev, RK_CRYPTO_TDES_CTRL, dev->mode); >> + >> +memcpy(dev->reg + RK_CRYPTO_TDES_IV_0, dev->ablk_req->info, 8); > Please ensure that the IV is copied back after the operation. > I know that many existing drivers are buggy in this regard but > they will be fixed soon and we will start enforcing this rule > so I don't want to add any new drivers that break this rule. Thanks your responding, I will fix it in v5. > > Thanks, -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 0/4] crypto: add crypto accelerator support for rk3288
This commit support three cipher(AES/DES/DES3) and two chainmode(ecb/cbc), and the more algorithms and new hash drivers will be added later on. Changed in v4: - modify irq function - add devm_add_action in probe - fix some minor mistakes Changed in v3: - add OF depended in Kconfig - rename some variate - add reset property - remove crypto_p variate Changed in v2: - remove some part about hash - add weak key detection - changed some variate's type Changed in v1: - modify some variate's name - modify some variate's type - modify some return value - remove or modify some print info - use more dev_xxx in probe - modify the prio of cipher - add Kconfig Zain Wang (4): crypto: rockchip/crypto - add DT bindings documentation clk: rockchip: set an ID for crypto clk Crypto: rockchip/crypto - add crypto driver for rk3288 ARM: dts: rockchip: Add Crypto node for rk3288 .../devicetree/bindings/crypto/rockchip-crypto.txt | 29 ++ arch/arm/boot/dts/rk3288.dtsi | 12 + drivers/clk/rockchip/clk-rk3288.c | 2 +- drivers/crypto/Kconfig | 11 + drivers/crypto/Makefile| 1 + drivers/crypto/rockchip/Makefile | 3 + drivers/crypto/rockchip/rk3288_crypto.c| 396 + drivers/crypto/rockchip/rk3288_crypto.h| 216 + drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 489 + include/dt-bindings/clock/rk3288-cru.h | 1 + 10 files changed, 1159 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt create mode 100644 drivers/crypto/rockchip/Makefile create mode 100644 drivers/crypto/rockchip/rk3288_crypto.c create mode 100644 drivers/crypto/rockchip/rk3288_crypto.h create mode 100644 drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 2/4] clk: rockchip: set an ID for crypto clk
Set an ID for crypto clk, so that it can be called in other part. Signed-off-by: Zain Wang Acked-by: Michael Turquette Tested-by: Heiko Stuebner --- Changed in v4: - None Changed in v3: - None Changed in v2: - None Changed in v1: - define SCLK_CRYPTO in rk3288-cru.h - use SCLK_CRYPTO instead of SRST_CRYPTO drivers/clk/rockchip/clk-rk3288.c | 2 +- include/dt-bindings/clock/rk3288-cru.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 9040878..3fceda1 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -295,7 +295,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKGATE_CON(0), 4, GFLAGS), GATE(0, "c2c_host", "aclk_cpu_src", 0, RK3288_CLKGATE_CON(13), 8, GFLAGS), - COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, + COMPOSITE_NOMUX(SCLK_CRYPTO, "crypto", "aclk_cpu_pre", 0, RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, RK3288_CLKGATE_CON(5), 4, GFLAGS), GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, diff --git a/include/dt-bindings/clock/rk3288-cru.h b/include/dt-bindings/clock/rk3288-cru.h index c719aac..30dcd60 100644 --- a/include/dt-bindings/clock/rk3288-cru.h +++ b/include/dt-bindings/clock/rk3288-cru.h @@ -86,6 +86,7 @@ #define SCLK_USBPHY480M_SRC122 #define SCLK_PVTM_CORE 123 #define SCLK_PVTM_GPU 124 +#define SCLK_CRYPTO125 #define SCLK_MAC 151 #define SCLK_MACREF_OUT152 -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288
Crypto driver support: ecb(aes) cbc(aes) ecb(des) cbc(des) ecb(des3_ede) cbc(des3_ede) You can alloc tags above in your case. And other algorithms and platforms will be added later on. Signed-off-by: Zain Wang Tested-by: Heiko Stuebner --- Changed in v4: - modify irq function - add devm_add_action in probe - fix some minor mistakes Changed in v3: - add OF depended in Kconfig - rename some variate - add reset property - remove crypto_p variate Changed in v2: - remove some part about hash - add weak key detection - changed some variate's type Changed in v1: - modify some variate's name - modify some variate's type - modify some return value - remove or modify some print info - use more dev_xxx in probe - modify the prio of cipher - add Kconfig drivers/crypto/Kconfig | 11 + drivers/crypto/Makefile| 1 + drivers/crypto/rockchip/Makefile | 3 + drivers/crypto/rockchip/rk3288_crypto.c| 396 + drivers/crypto/rockchip/rk3288_crypto.h| 216 + drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 489 + 6 files changed, 1116 insertions(+) create mode 100644 drivers/crypto/rockchip/Makefile create mode 100644 drivers/crypto/rockchip/rk3288_crypto.c create mode 100644 drivers/crypto/rockchip/rk3288_crypto.h create mode 100644 drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 2569e04..e5451b6 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -498,4 +498,15 @@ config CRYPTO_DEV_SUN4I_SS To compile this driver as a module, choose M here: the module will be called sun4i-ss. +config CRYPTO_DEV_ROCKCHIP + tristate "Rockchip's Cryptographic Engine driver" + depends on OF && ARCH_ROCKCHIP + select CRYPTO_AES + select CRYPTO_DES + select CRYPTO_BLKCIPHER + + help + This driver interfaces with the hardware crypto accelerator. + Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode. + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index c3ced6f..713de9d 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -29,3 +29,4 @@ obj-$(CONFIG_CRYPTO_DEV_QAT) += qat/ obj-$(CONFIG_CRYPTO_DEV_QCE) += qce/ obj-$(CONFIG_CRYPTO_DEV_VMX) += vmx/ obj-$(CONFIG_CRYPTO_DEV_SUN4I_SS) += sunxi-ss/ +obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rockchip/ diff --git a/drivers/crypto/rockchip/Makefile b/drivers/crypto/rockchip/Makefile new file mode 100644 index 000..7051c6c --- /dev/null +++ b/drivers/crypto/rockchip/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rk_crypto.o +rk_crypto-objs := rk3288_crypto.o \ + rk3288_crypto_ablkcipher.o \ diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c new file mode 100644 index 000..3c79902 --- /dev/null +++ b/drivers/crypto/rockchip/rk3288_crypto.c @@ -0,0 +1,396 @@ +/* + * Crypto acceleration support for Rockchip RK3288 + * + * Copyright (c) 2015, Fuzhou Rockchip Electronics Co., Ltd + * + * Author: Zain Wang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * Some ideas are from marvell-cesa.c and s5p-sss.c driver. + */ + +#include "rk3288_crypto.h" +#include +#include +#include +#include +#include +#include + +static int rk_crypto_enable_clk(struct rk_crypto_info *dev) +{ + int err; + + err = clk_prepare_enable(dev->sclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock sclk\n", + __func__, __LINE__); + goto err_return; + } + err = clk_prepare_enable(dev->aclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock aclk\n", + __func__, __LINE__); + goto err_aclk; + } + err = clk_prepare_enable(dev->hclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock hclk\n", + __func__, __LINE__); + goto err_hclk; + } + err = clk_prepare_enable(dev->dmaclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock dmaclk\n", + __func__, __LINE__); + goto err_dmaclk; + } + return err; +err_dmaclk: + clk_disable_unprepare(dev->hclk); +err_hclk: + clk_disable_unprepare(dev->aclk); +err_aclk: + clk_disable_unprepare(dev->sclk); +err_return: + return err; +} + +static void rk_crypto_disable_clk(struct rk_crypto_info *dev) +{ + clk_disabl
[PATCH v4 4/4] ARM: dts: rockchip: Add Crypto node for rk3288
Add Crypto node for rk3288 including crypto controller and dma clk. Signed-off-by: Zain Wang Tested-by: Heiko Stuebner --- Changed in v4: - None Changed in v3: - add reset property Changed in v2: - None Changed in v1: - remove the _crypto suffix - use "rockchip,rk3288-crypto" instead of "rockchip,rk3288" arch/arm/boot/dts/rk3288.dtsi | 12 1 file changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 6a79c9c..f0d1217 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -778,6 +778,18 @@ status = "disabled"; }; + crypto: cypto-controller@ff8a { + compatible = "rockchip,rk3288-crypto"; + reg = <0xff8a 0x4000>; + interrupts = ; + clocks = < ACLK_CRYPTO>, < HCLK_CRYPTO>, +< SCLK_CRYPTO>, < ACLK_DMAC1>; + clock-names = "aclk", "hclk", "sclk", "apb_pclk"; + resets = < SRST_CRYPTO>; + reset-names = "crypto-rst"; + status = "okay"; + }; + vopb: vop@ff93 { compatible = "rockchip,rk3288-vop"; reg = <0xff93 0x19c>; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 1/4] crypto: rockchip/crypto - add DT bindings documentation
Add DT bindings documentation for the rk3288 crypto drivers. Signed-off-by: Zain Wang Acked-by: Rob Herring Tested-by: Heiko Stuebner --- Changed in v4: - None Changed in v3: - add reset property Changed in v2: - None Changed in v1: - remove the _crypto suffix - use "rockchip,rk3288-crypto" instead of "rockchip,rk3288" - remove the description of status .../devicetree/bindings/crypto/rockchip-crypto.txt | 29 ++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt diff --git a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt new file mode 100644 index 000..096df34 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt @@ -0,0 +1,29 @@ +Rockchip Electronics And Security Accelerator + +Required properties: +- compatible: Should be "rockchip,rk3288-crypto" +- reg: Base physical address of the engine and length of memory mapped + region +- interrupts: Interrupt number +- clocks: Reference to the clocks about crypto +- clock-names: "aclk" used to clock data + "hclk" used to clock data + "sclk" used to clock crypto accelerator + "apb_pclk" used to clock dma +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must include the name "crypto-rst". + +Examples: + + crypto: cypto-controller@ff8a { + compatible = "rockchip,rk3288-crypto"; + reg = <0xff8a 0x4000>; + interrupts = ; + clocks = < ACLK_CRYPTO>, < HCLK_CRYPTO>, +< SCLK_CRYPTO>, < ACLK_DMAC1>; + clock-names = "aclk", "hclk", "sclk", "apb_pclk"; + resets = < SRST_CRYPTO>; + reset-names = "crypto-rst"; + status = "okay"; + }; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288
Crypto driver support: ecb(aes) cbc(aes) ecb(des) cbc(des) ecb(des3_ede) cbc(des3_ede) You can alloc tags above in your case. And other algorithms and platforms will be added later on. Signed-off-by: Zain Wang <zain.w...@rock-chips.com> Tested-by: Heiko Stuebner <he...@sntech.de> --- Changed in v4: - modify irq function - add devm_add_action in probe - fix some minor mistakes Changed in v3: - add OF depended in Kconfig - rename some variate - add reset property - remove crypto_p variate Changed in v2: - remove some part about hash - add weak key detection - changed some variate's type Changed in v1: - modify some variate's name - modify some variate's type - modify some return value - remove or modify some print info - use more dev_xxx in probe - modify the prio of cipher - add Kconfig drivers/crypto/Kconfig | 11 + drivers/crypto/Makefile| 1 + drivers/crypto/rockchip/Makefile | 3 + drivers/crypto/rockchip/rk3288_crypto.c| 396 + drivers/crypto/rockchip/rk3288_crypto.h| 216 + drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 489 + 6 files changed, 1116 insertions(+) create mode 100644 drivers/crypto/rockchip/Makefile create mode 100644 drivers/crypto/rockchip/rk3288_crypto.c create mode 100644 drivers/crypto/rockchip/rk3288_crypto.h create mode 100644 drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 2569e04..e5451b6 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -498,4 +498,15 @@ config CRYPTO_DEV_SUN4I_SS To compile this driver as a module, choose M here: the module will be called sun4i-ss. +config CRYPTO_DEV_ROCKCHIP + tristate "Rockchip's Cryptographic Engine driver" + depends on OF && ARCH_ROCKCHIP + select CRYPTO_AES + select CRYPTO_DES + select CRYPTO_BLKCIPHER + + help + This driver interfaces with the hardware crypto accelerator. + Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode. + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index c3ced6f..713de9d 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -29,3 +29,4 @@ obj-$(CONFIG_CRYPTO_DEV_QAT) += qat/ obj-$(CONFIG_CRYPTO_DEV_QCE) += qce/ obj-$(CONFIG_CRYPTO_DEV_VMX) += vmx/ obj-$(CONFIG_CRYPTO_DEV_SUN4I_SS) += sunxi-ss/ +obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rockchip/ diff --git a/drivers/crypto/rockchip/Makefile b/drivers/crypto/rockchip/Makefile new file mode 100644 index 000..7051c6c --- /dev/null +++ b/drivers/crypto/rockchip/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rk_crypto.o +rk_crypto-objs := rk3288_crypto.o \ + rk3288_crypto_ablkcipher.o \ diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c new file mode 100644 index 000..3c79902 --- /dev/null +++ b/drivers/crypto/rockchip/rk3288_crypto.c @@ -0,0 +1,396 @@ +/* + * Crypto acceleration support for Rockchip RK3288 + * + * Copyright (c) 2015, Fuzhou Rockchip Electronics Co., Ltd + * + * Author: Zain Wang <zain.w...@rock-chips.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * Some ideas are from marvell-cesa.c and s5p-sss.c driver. + */ + +#include "rk3288_crypto.h" +#include +#include +#include +#include +#include +#include + +static int rk_crypto_enable_clk(struct rk_crypto_info *dev) +{ + int err; + + err = clk_prepare_enable(dev->sclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock sclk\n", + __func__, __LINE__); + goto err_return; + } + err = clk_prepare_enable(dev->aclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock aclk\n", + __func__, __LINE__); + goto err_aclk; + } + err = clk_prepare_enable(dev->hclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock hclk\n", + __func__, __LINE__); + goto err_hclk; + } + err = clk_prepare_enable(dev->dmaclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock dmaclk\n", + __func__, __LINE__); + goto err_dmaclk; + } + return err; +err_dmaclk: + clk_disable_unprepare(dev->hclk); +err_hclk: + clk_disable_unprepare(dev->aclk); +err_aclk: + clk_disable_unprepare(dev->sclk); +err_return: + retur
[PATCH v4 4/4] ARM: dts: rockchip: Add Crypto node for rk3288
Add Crypto node for rk3288 including crypto controller and dma clk. Signed-off-by: Zain Wang <zain.w...@rock-chips.com> Tested-by: Heiko Stuebner <he...@sntech.de> --- Changed in v4: - None Changed in v3: - add reset property Changed in v2: - None Changed in v1: - remove the _crypto suffix - use "rockchip,rk3288-crypto" instead of "rockchip,rk3288" arch/arm/boot/dts/rk3288.dtsi | 12 1 file changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 6a79c9c..f0d1217 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -778,6 +778,18 @@ status = "disabled"; }; + crypto: cypto-controller@ff8a { + compatible = "rockchip,rk3288-crypto"; + reg = <0xff8a 0x4000>; + interrupts = ; + clocks = < ACLK_CRYPTO>, < HCLK_CRYPTO>, +< SCLK_CRYPTO>, < ACLK_DMAC1>; + clock-names = "aclk", "hclk", "sclk", "apb_pclk"; + resets = < SRST_CRYPTO>; + reset-names = "crypto-rst"; + status = "okay"; + }; + vopb: vop@ff93 { compatible = "rockchip,rk3288-vop"; reg = <0xff93 0x19c>; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 1/4] crypto: rockchip/crypto - add DT bindings documentation
Add DT bindings documentation for the rk3288 crypto drivers. Signed-off-by: Zain Wang <zain.w...@rock-chips.com> Acked-by: Rob Herring <r...@kernel.org> Tested-by: Heiko Stuebner <he...@sntech.de> --- Changed in v4: - None Changed in v3: - add reset property Changed in v2: - None Changed in v1: - remove the _crypto suffix - use "rockchip,rk3288-crypto" instead of "rockchip,rk3288" - remove the description of status .../devicetree/bindings/crypto/rockchip-crypto.txt | 29 ++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt diff --git a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt new file mode 100644 index 000..096df34 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt @@ -0,0 +1,29 @@ +Rockchip Electronics And Security Accelerator + +Required properties: +- compatible: Should be "rockchip,rk3288-crypto" +- reg: Base physical address of the engine and length of memory mapped + region +- interrupts: Interrupt number +- clocks: Reference to the clocks about crypto +- clock-names: "aclk" used to clock data + "hclk" used to clock data + "sclk" used to clock crypto accelerator + "apb_pclk" used to clock dma +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must include the name "crypto-rst". + +Examples: + + crypto: cypto-controller@ff8a { + compatible = "rockchip,rk3288-crypto"; + reg = <0xff8a 0x4000>; + interrupts = ; + clocks = < ACLK_CRYPTO>, < HCLK_CRYPTO>, +< SCLK_CRYPTO>, < ACLK_DMAC1>; + clock-names = "aclk", "hclk", "sclk", "apb_pclk"; + resets = < SRST_CRYPTO>; + reset-names = "crypto-rst"; + status = "okay"; + }; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 2/4] clk: rockchip: set an ID for crypto clk
Set an ID for crypto clk, so that it can be called in other part. Signed-off-by: Zain Wang <zain.w...@rock-chips.com> Acked-by: Michael Turquette <mturque...@baylibre.com> Tested-by: Heiko Stuebner <he...@sntech.de> --- Changed in v4: - None Changed in v3: - None Changed in v2: - None Changed in v1: - define SCLK_CRYPTO in rk3288-cru.h - use SCLK_CRYPTO instead of SRST_CRYPTO drivers/clk/rockchip/clk-rk3288.c | 2 +- include/dt-bindings/clock/rk3288-cru.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 9040878..3fceda1 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -295,7 +295,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKGATE_CON(0), 4, GFLAGS), GATE(0, "c2c_host", "aclk_cpu_src", 0, RK3288_CLKGATE_CON(13), 8, GFLAGS), - COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, + COMPOSITE_NOMUX(SCLK_CRYPTO, "crypto", "aclk_cpu_pre", 0, RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, RK3288_CLKGATE_CON(5), 4, GFLAGS), GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, diff --git a/include/dt-bindings/clock/rk3288-cru.h b/include/dt-bindings/clock/rk3288-cru.h index c719aac..30dcd60 100644 --- a/include/dt-bindings/clock/rk3288-cru.h +++ b/include/dt-bindings/clock/rk3288-cru.h @@ -86,6 +86,7 @@ #define SCLK_USBPHY480M_SRC122 #define SCLK_PVTM_CORE 123 #define SCLK_PVTM_GPU 124 +#define SCLK_CRYPTO125 #define SCLK_MAC 151 #define SCLK_MACREF_OUT152 -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 0/4] crypto: add crypto accelerator support for rk3288
This commit support three cipher(AES/DES/DES3) and two chainmode(ecb/cbc), and the more algorithms and new hash drivers will be added later on. Changed in v4: - modify irq function - add devm_add_action in probe - fix some minor mistakes Changed in v3: - add OF depended in Kconfig - rename some variate - add reset property - remove crypto_p variate Changed in v2: - remove some part about hash - add weak key detection - changed some variate's type Changed in v1: - modify some variate's name - modify some variate's type - modify some return value - remove or modify some print info - use more dev_xxx in probe - modify the prio of cipher - add Kconfig Zain Wang (4): crypto: rockchip/crypto - add DT bindings documentation clk: rockchip: set an ID for crypto clk Crypto: rockchip/crypto - add crypto driver for rk3288 ARM: dts: rockchip: Add Crypto node for rk3288 .../devicetree/bindings/crypto/rockchip-crypto.txt | 29 ++ arch/arm/boot/dts/rk3288.dtsi | 12 + drivers/clk/rockchip/clk-rk3288.c | 2 +- drivers/crypto/Kconfig | 11 + drivers/crypto/Makefile| 1 + drivers/crypto/rockchip/Makefile | 3 + drivers/crypto/rockchip/rk3288_crypto.c| 396 + drivers/crypto/rockchip/rk3288_crypto.h| 216 + drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 489 + include/dt-bindings/clock/rk3288-cru.h | 1 + 10 files changed, 1159 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt create mode 100644 drivers/crypto/rockchip/Makefile create mode 100644 drivers/crypto/rockchip/rk3288_crypto.c create mode 100644 drivers/crypto/rockchip/rk3288_crypto.h create mode 100644 drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v3 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288
On 2015年11月15日 06:41, Heiko Stuebner wrote: > Hi Zain, > > Am Freitag, 13. November 2015, 14:44:43 schrieb Zain: >> On 2015年11月12日 20:32, Heiko Stuebner wrote: >>> Hi Zain, >>> >>> I was able to sucessfully test your crypto-driver, but have found some >>> improvements below that should probably get looked at: >>> >>> Am Mittwoch, 11. November 2015, 14:35:58 schrieb Zain Wang: >>>> Crypto driver support: >>>> ecb(aes) cbc(aes) ecb(des) cbc(des) ecb(des3_ede) cbc(des3_ede) >>>> You can alloc tags above in your case. >>>> >>>> And other algorithms and platforms will be added later on. >>>> >>>> Signed-off-by: Zain Wang >>>> --- >>> [...] >>> >>>> diff --git a/drivers/crypto/rockchip/rk3288_crypto.c >>>> b/drivers/crypto/rockchip/rk3288_crypto.c >>>> new file mode 100644 >>>> index 000..bb36baa >>>> --- /dev/null >>>> +++ b/drivers/crypto/rockchip/rk3288_crypto.c >>>> @@ -0,0 +1,392 @@ > [...] > > static void rk_crypto_action(void *data) > { > struct rk_crypto_info *crypto_info = data; > > reset_control_assert(crypto_info->rst); > } > >>>> +static int rk_crypto_probe(struct platform_device *pdev) >>>> +{ >>>> + struct resource *res; >>>> + struct device *dev = >dev; >>>> + struct rk_crypto_info *crypto_info; >>>> + int err = 0; >>>> + >>>> + crypto_info = devm_kzalloc(>dev, >>>> + sizeof(*crypto_info), GFP_KERNEL); >>>> + if (!crypto_info) { >>>> + err = -ENOMEM; >>>> + goto err_crypto; >>>> + } >>>> + >>>> + crypto_info->rst = devm_reset_control_get(dev, "crypto-rst"); >>>> + if (IS_ERR(crypto_info->rst)) { >>>> + err = PTR_ERR(crypto_info->rst); >>>> + goto err_crypto; >>>> + } >>>> + >>>> + reset_control_assert(crypto_info->rst); >>>> + usleep_range(10, 20); >>>> + reset_control_deassert(crypto_info->rst); > err = devm_add_action(dev, rk_crypto_action, crypto_info); > if (err) { > reset_control_assert(crypto_info->rst); > return err; > } > > from here onwards the devm_action will always be executed when either > _probe fails, or after remove finishes, so no need to assert the reset > manually. I have known this function, rk_crypto_action will be executed next to either failed _probe, or _remove automatically. It also make sure reset_control_assert can be executed after tasklet_kill. OK! Done! > >>>> + >>>> + spin_lock_init(_info->lock); >>>> + >>>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); >>>> + crypto_info->reg = devm_ioremap_resource(>dev, res); >>>> + if (IS_ERR(crypto_info->reg)) { >>>> + err = PTR_ERR(crypto_info->reg); >>>> + goto err_ioremap; >>>> + } >>>> + >>>> + crypto_info->aclk = devm_clk_get(>dev, "aclk"); >>>> + if (IS_ERR(crypto_info->aclk)) { >>>> + err = PTR_ERR(crypto_info->aclk); >>>> + goto err_ioremap; >>>> + } >>>> + >>>> + crypto_info->hclk = devm_clk_get(>dev, "hclk"); >>>> + if (IS_ERR(crypto_info->hclk)) { >>>> + err = PTR_ERR(crypto_info->hclk); >>>> + goto err_ioremap; >>>> + } >>>> + >>>> + crypto_info->sclk = devm_clk_get(>dev, "sclk"); >>>> + if (IS_ERR(crypto_info->sclk)) { >>>> + err = PTR_ERR(crypto_info->sclk); >>>> + goto err_ioremap; >>>> + } >>>> + >>>> + crypto_info->dmaclk = devm_clk_get(>dev, "apb_pclk"); >>>> + if (IS_ERR(crypto_info->dmaclk)) { >>>> + err = PTR_ERR(crypto_info->dmaclk); >>>> + goto err_ioremap; >>>> + } >>>> + >>>> + crypto_info->irq = platform_get_irq(pdev, 0); >>>> + if (crypto_info->irq < 0) { >>>> + dev_warn(crypto_info->dev, >>>> + "control Interrupt is not available.\n"); >>>> + err = crypto_info->irq; >>>> +
Re: [PATCH v3 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288
On 2015年11月15日 06:41, Heiko Stuebner wrote: > Hi Zain, > > Am Freitag, 13. November 2015, 14:44:43 schrieb Zain: >> On 2015年11月12日 20:32, Heiko Stuebner wrote: >>> Hi Zain, >>> >>> I was able to sucessfully test your crypto-driver, but have found some >>> improvements below that should probably get looked at: >>> >>> Am Mittwoch, 11. November 2015, 14:35:58 schrieb Zain Wang: >>>> Crypto driver support: >>>> ecb(aes) cbc(aes) ecb(des) cbc(des) ecb(des3_ede) cbc(des3_ede) >>>> You can alloc tags above in your case. >>>> >>>> And other algorithms and platforms will be added later on. >>>> >>>> Signed-off-by: Zain Wang <zain.w...@rock-chips.com> >>>> --- >>> [...] >>> >>>> diff --git a/drivers/crypto/rockchip/rk3288_crypto.c >>>> b/drivers/crypto/rockchip/rk3288_crypto.c >>>> new file mode 100644 >>>> index 000..bb36baa >>>> --- /dev/null >>>> +++ b/drivers/crypto/rockchip/rk3288_crypto.c >>>> @@ -0,0 +1,392 @@ > [...] > > static void rk_crypto_action(void *data) > { > struct rk_crypto_info *crypto_info = data; > > reset_control_assert(crypto_info->rst); > } > >>>> +static int rk_crypto_probe(struct platform_device *pdev) >>>> +{ >>>> + struct resource *res; >>>> + struct device *dev = >dev; >>>> + struct rk_crypto_info *crypto_info; >>>> + int err = 0; >>>> + >>>> + crypto_info = devm_kzalloc(>dev, >>>> + sizeof(*crypto_info), GFP_KERNEL); >>>> + if (!crypto_info) { >>>> + err = -ENOMEM; >>>> + goto err_crypto; >>>> + } >>>> + >>>> + crypto_info->rst = devm_reset_control_get(dev, "crypto-rst"); >>>> + if (IS_ERR(crypto_info->rst)) { >>>> + err = PTR_ERR(crypto_info->rst); >>>> + goto err_crypto; >>>> + } >>>> + >>>> + reset_control_assert(crypto_info->rst); >>>> + usleep_range(10, 20); >>>> + reset_control_deassert(crypto_info->rst); > err = devm_add_action(dev, rk_crypto_action, crypto_info); > if (err) { > reset_control_assert(crypto_info->rst); > return err; > } > > from here onwards the devm_action will always be executed when either > _probe fails, or after remove finishes, so no need to assert the reset > manually. I have known this function, rk_crypto_action will be executed next to either failed _probe, or _remove automatically. It also make sure reset_control_assert can be executed after tasklet_kill. OK! Done! > >>>> + >>>> + spin_lock_init(_info->lock); >>>> + >>>> + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); >>>> + crypto_info->reg = devm_ioremap_resource(>dev, res); >>>> + if (IS_ERR(crypto_info->reg)) { >>>> + err = PTR_ERR(crypto_info->reg); >>>> + goto err_ioremap; >>>> + } >>>> + >>>> + crypto_info->aclk = devm_clk_get(>dev, "aclk"); >>>> + if (IS_ERR(crypto_info->aclk)) { >>>> + err = PTR_ERR(crypto_info->aclk); >>>> + goto err_ioremap; >>>> + } >>>> + >>>> + crypto_info->hclk = devm_clk_get(>dev, "hclk"); >>>> + if (IS_ERR(crypto_info->hclk)) { >>>> + err = PTR_ERR(crypto_info->hclk); >>>> + goto err_ioremap; >>>> + } >>>> + >>>> + crypto_info->sclk = devm_clk_get(>dev, "sclk"); >>>> + if (IS_ERR(crypto_info->sclk)) { >>>> + err = PTR_ERR(crypto_info->sclk); >>>> + goto err_ioremap; >>>> + } >>>> + >>>> + crypto_info->dmaclk = devm_clk_get(>dev, "apb_pclk"); >>>> + if (IS_ERR(crypto_info->dmaclk)) { >>>> + err = PTR_ERR(crypto_info->dmaclk); >>>> + goto err_ioremap; >>>> + } >>>> + >>>> + crypto_info->irq = platform_get_irq(pdev, 0); >>>> + if (crypto_info->irq < 0) { >>>> + dev_warn(crypto_info->dev, >>>> + "control Interrupt is not available.\n"); >>>> + err = crypto_i
Re: [PATCH v3 2/4] clk: rockchip: set an ID for crypto clk
On 2015年11月12日 16:40, Heiko Stuebner wrote: > Am Donnerstag, 12. November 2015, 09:13:20 schrieb Zain: >> On 2015年11月12日 07:57, Heiko Stuebner wrote: >>> Am Mittwoch, 11. November 2015, 14:35:57 schrieb Zain Wang: >>>> Set an ID for crypto clk, so that it can be called in other part. >>>> >>>> Signed-off-by: Zain Wang >>> this should go in together with patch4, the dts change, so an Ack from the >>> clock-maintainers would be nice :-) >>> >>> >>> Heiko >> Ok! Done! >> Thanks. > I'm not sure I understand that. > > There is nothing to do for you here, I was merely stating the fact that > we will need to get an Acked-by from the clock maintainers, to allow > me to take both this and the devicetree patch :-) > > > Heiko I am sorry that I think you told me to put the two patches together in next version at first. Thanks for your writing back. Zain > >>>> --- >>>> >>>> Changed in v3: >>>> - None >>>> >>>> Changed in v2: >>>> - None >>>> >>>> Changed in v1: >>>> - define SCLK_CRYPTO in rk3288-cru.h >>>> - use SCLK_CRYPTO instead of SRST_CRYPTO >>>> >>>> drivers/clk/rockchip/clk-rk3288.c | 2 +- >>>> include/dt-bindings/clock/rk3288-cru.h | 1 + >>>> 2 files changed, 2 insertions(+), 1 deletion(-) >>>> >>>> diff --git a/drivers/clk/rockchip/clk-rk3288.c >>>> b/drivers/clk/rockchip/clk-rk3288.c >>>> index 9040878..3fceda1 100644 >>>> --- a/drivers/clk/rockchip/clk-rk3288.c >>>> +++ b/drivers/clk/rockchip/clk-rk3288.c >>>> @@ -295,7 +295,7 @@ static struct rockchip_clk_branch >>>> rk3288_clk_branches[] __initdata = { >>>>RK3288_CLKGATE_CON(0), 4, GFLAGS), >>>>GATE(0, "c2c_host", "aclk_cpu_src", 0, >>>>RK3288_CLKGATE_CON(13), 8, GFLAGS), >>>> - COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, >>>> + COMPOSITE_NOMUX(SCLK_CRYPTO, "crypto", "aclk_cpu_pre", 0, >>>>RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, >>>>RK3288_CLKGATE_CON(5), 4, GFLAGS), >>>>GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, >>>> diff --git a/include/dt-bindings/clock/rk3288-cru.h >>>> b/include/dt-bindings/clock/rk3288-cru.h >>>> index c719aac..30dcd60 100644 >>>> --- a/include/dt-bindings/clock/rk3288-cru.h >>>> +++ b/include/dt-bindings/clock/rk3288-cru.h >>>> @@ -86,6 +86,7 @@ >>>> #define SCLK_USBPHY480M_SRC 122 >>>> #define SCLK_PVTM_CORE123 >>>> #define SCLK_PVTM_GPU 124 >>>> +#define SCLK_CRYPTO 125 >>>> >>>> #define SCLK_MAC 151 >>>> #define SCLK_MACREF_OUT 152 >>>> >>> >>> >> >> > > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v3 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288
On 2015年11月12日 20:32, Heiko Stuebner wrote: > Hi Zain, > > I was able to sucessfully test your crypto-driver, but have found some > improvements below that should probably get looked at: > > Am Mittwoch, 11. November 2015, 14:35:58 schrieb Zain Wang: >> Crypto driver support: >> ecb(aes) cbc(aes) ecb(des) cbc(des) ecb(des3_ede) cbc(des3_ede) >> You can alloc tags above in your case. >> >> And other algorithms and platforms will be added later on. >> >> Signed-off-by: Zain Wang >> --- > [...] > >> diff --git a/drivers/crypto/rockchip/rk3288_crypto.c >> b/drivers/crypto/rockchip/rk3288_crypto.c >> new file mode 100644 >> index 000..bb36baa >> --- /dev/null >> +++ b/drivers/crypto/rockchip/rk3288_crypto.c >> @@ -0,0 +1,392 @@ > [...] > >> +static irqreturn_t crypto_irq_handle(int irq, void *dev_id) > that function should probably also get a "rk_" prefix? OK! good idea. I will add it to next version. >> +{ >> +struct rk_crypto_info *dev = platform_get_drvdata(dev_id); >> +u32 interrupt_status; >> +int err = 0; >> + >> +spin_lock(>lock); >> + >> +if (irq == dev->irq) { > I'm not sure I understand that line. Interrupt handlers are only > called for the interrupt they are registered for, which would be dev->irq > in any case, so that should always be true and therefore be unnecessary? You are right, it is unnecessary. It will be remove in next version. > >> +interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS); >> +CRYPTO_WRITE(dev, RK_CRYPTO_INTSTS, interrupt_status); >> +if (interrupt_status & 0x0a) { >> +dev_warn(dev->dev, "DMA Error\n"); >> +err = -EFAULT; >> +} else if (interrupt_status & 0x05) { >> +err = dev->update(dev); >> +} >> + >> +if (err) >> +dev->complete(dev, err); >> +} >> +spin_unlock(>lock); >> +return IRQ_HANDLED; >> +} > [...] > >> +static int rk_crypto_probe(struct platform_device *pdev) >> +{ >> +struct resource *res; >> +struct device *dev = >dev; >> +struct rk_crypto_info *crypto_info; >> +int err = 0; >> + >> +crypto_info = devm_kzalloc(>dev, >> + sizeof(*crypto_info), GFP_KERNEL); >> +if (!crypto_info) { >> +err = -ENOMEM; >> +goto err_crypto; >> +} >> + >> +crypto_info->rst = devm_reset_control_get(dev, "crypto-rst"); >> +if (IS_ERR(crypto_info->rst)) { >> +err = PTR_ERR(crypto_info->rst); >> +goto err_crypto; >> +} >> + >> +reset_control_assert(crypto_info->rst); >> +usleep_range(10, 20); >> +reset_control_deassert(crypto_info->rst); >> + >> +spin_lock_init(_info->lock); >> + >> +res = platform_get_resource(pdev, IORESOURCE_MEM, 0); >> +crypto_info->reg = devm_ioremap_resource(>dev, res); >> +if (IS_ERR(crypto_info->reg)) { >> +err = PTR_ERR(crypto_info->reg); >> +goto err_ioremap; >> +} >> + >> +crypto_info->aclk = devm_clk_get(>dev, "aclk"); >> +if (IS_ERR(crypto_info->aclk)) { >> +err = PTR_ERR(crypto_info->aclk); >> +goto err_ioremap; >> +} >> + >> +crypto_info->hclk = devm_clk_get(>dev, "hclk"); >> +if (IS_ERR(crypto_info->hclk)) { >> +err = PTR_ERR(crypto_info->hclk); >> +goto err_ioremap; >> +} >> + >> +crypto_info->sclk = devm_clk_get(>dev, "sclk"); >> +if (IS_ERR(crypto_info->sclk)) { >> +err = PTR_ERR(crypto_info->sclk); >> +goto err_ioremap; >> +} >> + >> +crypto_info->dmaclk = devm_clk_get(>dev, "apb_pclk"); >> +if (IS_ERR(crypto_info->dmaclk)) { >> +err = PTR_ERR(crypto_info->dmaclk); >> +goto err_ioremap; >> +} >> + >> +crypto_info->irq = platform_get_irq(pdev, 0); >> +if (crypto_info->irq < 0) { >> +dev_warn(crypto_info->dev, >> + "control Interrupt is not available.\n"); >> +err = crypto_info->irq; >> +goto err_ioremap; >> +} &
Re: [PATCH v3 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288
On 2015年11月12日 20:32, Heiko Stuebner wrote: > Hi Zain, > > I was able to sucessfully test your crypto-driver, but have found some > improvements below that should probably get looked at: > > Am Mittwoch, 11. November 2015, 14:35:58 schrieb Zain Wang: >> Crypto driver support: >> ecb(aes) cbc(aes) ecb(des) cbc(des) ecb(des3_ede) cbc(des3_ede) >> You can alloc tags above in your case. >> >> And other algorithms and platforms will be added later on. >> >> Signed-off-by: Zain Wang <zain.w...@rock-chips.com> >> --- > [...] > >> diff --git a/drivers/crypto/rockchip/rk3288_crypto.c >> b/drivers/crypto/rockchip/rk3288_crypto.c >> new file mode 100644 >> index 000..bb36baa >> --- /dev/null >> +++ b/drivers/crypto/rockchip/rk3288_crypto.c >> @@ -0,0 +1,392 @@ > [...] > >> +static irqreturn_t crypto_irq_handle(int irq, void *dev_id) > that function should probably also get a "rk_" prefix? OK! good idea. I will add it to next version. >> +{ >> +struct rk_crypto_info *dev = platform_get_drvdata(dev_id); >> +u32 interrupt_status; >> +int err = 0; >> + >> +spin_lock(>lock); >> + >> +if (irq == dev->irq) { > I'm not sure I understand that line. Interrupt handlers are only > called for the interrupt they are registered for, which would be dev->irq > in any case, so that should always be true and therefore be unnecessary? You are right, it is unnecessary. It will be remove in next version. > >> +interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS); >> +CRYPTO_WRITE(dev, RK_CRYPTO_INTSTS, interrupt_status); >> +if (interrupt_status & 0x0a) { >> +dev_warn(dev->dev, "DMA Error\n"); >> +err = -EFAULT; >> +} else if (interrupt_status & 0x05) { >> +err = dev->update(dev); >> +} >> + >> +if (err) >> +dev->complete(dev, err); >> +} >> +spin_unlock(>lock); >> +return IRQ_HANDLED; >> +} > [...] > >> +static int rk_crypto_probe(struct platform_device *pdev) >> +{ >> +struct resource *res; >> +struct device *dev = >dev; >> +struct rk_crypto_info *crypto_info; >> +int err = 0; >> + >> +crypto_info = devm_kzalloc(>dev, >> + sizeof(*crypto_info), GFP_KERNEL); >> +if (!crypto_info) { >> +err = -ENOMEM; >> +goto err_crypto; >> +} >> + >> +crypto_info->rst = devm_reset_control_get(dev, "crypto-rst"); >> +if (IS_ERR(crypto_info->rst)) { >> +err = PTR_ERR(crypto_info->rst); >> +goto err_crypto; >> +} >> + >> +reset_control_assert(crypto_info->rst); >> +usleep_range(10, 20); >> +reset_control_deassert(crypto_info->rst); >> + >> +spin_lock_init(_info->lock); >> + >> +res = platform_get_resource(pdev, IORESOURCE_MEM, 0); >> +crypto_info->reg = devm_ioremap_resource(>dev, res); >> +if (IS_ERR(crypto_info->reg)) { >> +err = PTR_ERR(crypto_info->reg); >> +goto err_ioremap; >> +} >> + >> +crypto_info->aclk = devm_clk_get(>dev, "aclk"); >> +if (IS_ERR(crypto_info->aclk)) { >> +err = PTR_ERR(crypto_info->aclk); >> +goto err_ioremap; >> +} >> + >> +crypto_info->hclk = devm_clk_get(>dev, "hclk"); >> +if (IS_ERR(crypto_info->hclk)) { >> +err = PTR_ERR(crypto_info->hclk); >> +goto err_ioremap; >> +} >> + >> +crypto_info->sclk = devm_clk_get(>dev, "sclk"); >> +if (IS_ERR(crypto_info->sclk)) { >> +err = PTR_ERR(crypto_info->sclk); >> +goto err_ioremap; >> +} >> + >> +crypto_info->dmaclk = devm_clk_get(>dev, "apb_pclk"); >> +if (IS_ERR(crypto_info->dmaclk)) { >> +err = PTR_ERR(crypto_info->dmaclk); >> +goto err_ioremap; >> +} >> + >> +crypto_info->irq = platform_get_irq(pdev, 0); >> +if (crypto_info->irq < 0) { >> +dev_warn(crypto_info->dev, >> + "control Interrupt is not available.\n"); >> +err = crypto_info->irq; >> +goto err
Re: [PATCH v3 2/4] clk: rockchip: set an ID for crypto clk
On 2015年11月12日 16:40, Heiko Stuebner wrote: > Am Donnerstag, 12. November 2015, 09:13:20 schrieb Zain: >> On 2015年11月12日 07:57, Heiko Stuebner wrote: >>> Am Mittwoch, 11. November 2015, 14:35:57 schrieb Zain Wang: >>>> Set an ID for crypto clk, so that it can be called in other part. >>>> >>>> Signed-off-by: Zain Wang <zain.w...@rock-chips.com> >>> this should go in together with patch4, the dts change, so an Ack from the >>> clock-maintainers would be nice :-) >>> >>> >>> Heiko >> Ok! Done! >> Thanks. > I'm not sure I understand that. > > There is nothing to do for you here, I was merely stating the fact that > we will need to get an Acked-by from the clock maintainers, to allow > me to take both this and the devicetree patch :-) > > > Heiko I am sorry that I think you told me to put the two patches together in next version at first. Thanks for your writing back. Zain > >>>> --- >>>> >>>> Changed in v3: >>>> - None >>>> >>>> Changed in v2: >>>> - None >>>> >>>> Changed in v1: >>>> - define SCLK_CRYPTO in rk3288-cru.h >>>> - use SCLK_CRYPTO instead of SRST_CRYPTO >>>> >>>> drivers/clk/rockchip/clk-rk3288.c | 2 +- >>>> include/dt-bindings/clock/rk3288-cru.h | 1 + >>>> 2 files changed, 2 insertions(+), 1 deletion(-) >>>> >>>> diff --git a/drivers/clk/rockchip/clk-rk3288.c >>>> b/drivers/clk/rockchip/clk-rk3288.c >>>> index 9040878..3fceda1 100644 >>>> --- a/drivers/clk/rockchip/clk-rk3288.c >>>> +++ b/drivers/clk/rockchip/clk-rk3288.c >>>> @@ -295,7 +295,7 @@ static struct rockchip_clk_branch >>>> rk3288_clk_branches[] __initdata = { >>>>RK3288_CLKGATE_CON(0), 4, GFLAGS), >>>>GATE(0, "c2c_host", "aclk_cpu_src", 0, >>>>RK3288_CLKGATE_CON(13), 8, GFLAGS), >>>> - COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, >>>> + COMPOSITE_NOMUX(SCLK_CRYPTO, "crypto", "aclk_cpu_pre", 0, >>>>RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, >>>>RK3288_CLKGATE_CON(5), 4, GFLAGS), >>>>GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, >>>> diff --git a/include/dt-bindings/clock/rk3288-cru.h >>>> b/include/dt-bindings/clock/rk3288-cru.h >>>> index c719aac..30dcd60 100644 >>>> --- a/include/dt-bindings/clock/rk3288-cru.h >>>> +++ b/include/dt-bindings/clock/rk3288-cru.h >>>> @@ -86,6 +86,7 @@ >>>> #define SCLK_USBPHY480M_SRC 122 >>>> #define SCLK_PVTM_CORE123 >>>> #define SCLK_PVTM_GPU 124 >>>> +#define SCLK_CRYPTO 125 >>>> >>>> #define SCLK_MAC 151 >>>> #define SCLK_MACREF_OUT 152 >>>> >>> >>> >> >> > > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v3 1/4] crypto: rockchip/crypto - add DT bindings documentation
Hi Rob, On 2015年11月12日 04:24, Rob Herring wrote: > On Wed, Nov 11, 2015 at 02:35:56PM +0800, Zain Wang wrote: >> Add DT bindings documentation for the rk3288 crypto drivers. >> >> Signed-off-by: Zain Wang > Acked-by: Rob Herring Thanks you for responding. -Zain > >> --- >> >> Changed in v3: >> - add reset property >> >> Changed in v2: >> - None >> >> Changed in v1: >> - remove the _crypto suffix >> - use "rockchip,rk3288-crypto" instead of "rockchip,rk3288" >> - remove the description of status >> >> >> .../devicetree/bindings/crypto/rockchip-crypto.txt | 29 >> ++ >> 1 file changed, 29 insertions(+) >> create mode 100644 >> Documentation/devicetree/bindings/crypto/rockchip-crypto.txt >> >> diff --git a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt >> b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt >> new file mode 100644 >> index 000..096df34 >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt >> @@ -0,0 +1,29 @@ >> +Rockchip Electronics And Security Accelerator >> + >> +Required properties: >> +- compatible: Should be "rockchip,rk3288-crypto" >> +- reg: Base physical address of the engine and length of memory mapped >> + region >> +- interrupts: Interrupt number >> +- clocks: Reference to the clocks about crypto >> +- clock-names: "aclk" used to clock data >> + "hclk" used to clock data >> + "sclk" used to clock crypto accelerator >> + "apb_pclk" used to clock dma >> +- resets: Must contain an entry for each entry in reset-names. >> + See ../reset/reset.txt for details. >> +- reset-names: Must include the name "crypto-rst". >> + >> +Examples: >> + >> +crypto: cypto-controller@ff8a { >> +compatible = "rockchip,rk3288-crypto"; >> +reg = <0xff8a 0x4000>; >> +interrupts = ; >> +clocks = < ACLK_CRYPTO>, < HCLK_CRYPTO>, >> + < SCLK_CRYPTO>, < ACLK_DMAC1>; >> +clock-names = "aclk", "hclk", "sclk", "apb_pclk"; >> +resets = < SRST_CRYPTO>; >> +reset-names = "crypto-rst"; >> +status = "okay"; >> +}; >> -- >> 1.9.1 >> >> > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v3 2/4] clk: rockchip: set an ID for crypto clk
On 2015年11月12日 07:57, Heiko Stuebner wrote: > Am Mittwoch, 11. November 2015, 14:35:57 schrieb Zain Wang: >> Set an ID for crypto clk, so that it can be called in other part. >> >> Signed-off-by: Zain Wang > this should go in together with patch4, the dts change, so an Ack from the > clock-maintainers would be nice :-) > > > Heiko Ok! Done! Thanks. > >> --- >> >> Changed in v3: >> - None >> >> Changed in v2: >> - None >> >> Changed in v1: >> - define SCLK_CRYPTO in rk3288-cru.h >> - use SCLK_CRYPTO instead of SRST_CRYPTO >> >> drivers/clk/rockchip/clk-rk3288.c | 2 +- >> include/dt-bindings/clock/rk3288-cru.h | 1 + >> 2 files changed, 2 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/clk/rockchip/clk-rk3288.c >> b/drivers/clk/rockchip/clk-rk3288.c >> index 9040878..3fceda1 100644 >> --- a/drivers/clk/rockchip/clk-rk3288.c >> +++ b/drivers/clk/rockchip/clk-rk3288.c >> @@ -295,7 +295,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] >> __initdata = { >> RK3288_CLKGATE_CON(0), 4, GFLAGS), >> GATE(0, "c2c_host", "aclk_cpu_src", 0, >> RK3288_CLKGATE_CON(13), 8, GFLAGS), >> -COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, >> +COMPOSITE_NOMUX(SCLK_CRYPTO, "crypto", "aclk_cpu_pre", 0, >> RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, >> RK3288_CLKGATE_CON(5), 4, GFLAGS), >> GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, >> diff --git a/include/dt-bindings/clock/rk3288-cru.h >> b/include/dt-bindings/clock/rk3288-cru.h >> index c719aac..30dcd60 100644 >> --- a/include/dt-bindings/clock/rk3288-cru.h >> +++ b/include/dt-bindings/clock/rk3288-cru.h >> @@ -86,6 +86,7 @@ >> #define SCLK_USBPHY480M_SRC 122 >> #define SCLK_PVTM_CORE 123 >> #define SCLK_PVTM_GPU 124 >> +#define SCLK_CRYPTO 125 >> >> #define SCLK_MAC151 >> #define SCLK_MACREF_OUT 152 >> > > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v3 2/4] clk: rockchip: set an ID for crypto clk
On 2015年11月12日 07:57, Heiko Stuebner wrote: > Am Mittwoch, 11. November 2015, 14:35:57 schrieb Zain Wang: >> Set an ID for crypto clk, so that it can be called in other part. >> >> Signed-off-by: Zain Wang <zain.w...@rock-chips.com> > this should go in together with patch4, the dts change, so an Ack from the > clock-maintainers would be nice :-) > > > Heiko Ok! Done! Thanks. > >> --- >> >> Changed in v3: >> - None >> >> Changed in v2: >> - None >> >> Changed in v1: >> - define SCLK_CRYPTO in rk3288-cru.h >> - use SCLK_CRYPTO instead of SRST_CRYPTO >> >> drivers/clk/rockchip/clk-rk3288.c | 2 +- >> include/dt-bindings/clock/rk3288-cru.h | 1 + >> 2 files changed, 2 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/clk/rockchip/clk-rk3288.c >> b/drivers/clk/rockchip/clk-rk3288.c >> index 9040878..3fceda1 100644 >> --- a/drivers/clk/rockchip/clk-rk3288.c >> +++ b/drivers/clk/rockchip/clk-rk3288.c >> @@ -295,7 +295,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] >> __initdata = { >> RK3288_CLKGATE_CON(0), 4, GFLAGS), >> GATE(0, "c2c_host", "aclk_cpu_src", 0, >> RK3288_CLKGATE_CON(13), 8, GFLAGS), >> -COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, >> +COMPOSITE_NOMUX(SCLK_CRYPTO, "crypto", "aclk_cpu_pre", 0, >> RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, >> RK3288_CLKGATE_CON(5), 4, GFLAGS), >> GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, >> diff --git a/include/dt-bindings/clock/rk3288-cru.h >> b/include/dt-bindings/clock/rk3288-cru.h >> index c719aac..30dcd60 100644 >> --- a/include/dt-bindings/clock/rk3288-cru.h >> +++ b/include/dt-bindings/clock/rk3288-cru.h >> @@ -86,6 +86,7 @@ >> #define SCLK_USBPHY480M_SRC 122 >> #define SCLK_PVTM_CORE 123 >> #define SCLK_PVTM_GPU 124 >> +#define SCLK_CRYPTO 125 >> >> #define SCLK_MAC151 >> #define SCLK_MACREF_OUT 152 >> > > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v3 1/4] crypto: rockchip/crypto - add DT bindings documentation
Hi Rob, On 2015年11月12日 04:24, Rob Herring wrote: > On Wed, Nov 11, 2015 at 02:35:56PM +0800, Zain Wang wrote: >> Add DT bindings documentation for the rk3288 crypto drivers. >> >> Signed-off-by: Zain Wang <zain.w...@rock-chips.com> > Acked-by: Rob Herring <r...@kernel.org> Thanks you for responding. -Zain > >> --- >> >> Changed in v3: >> - add reset property >> >> Changed in v2: >> - None >> >> Changed in v1: >> - remove the _crypto suffix >> - use "rockchip,rk3288-crypto" instead of "rockchip,rk3288" >> - remove the description of status >> >> >> .../devicetree/bindings/crypto/rockchip-crypto.txt | 29 >> ++ >> 1 file changed, 29 insertions(+) >> create mode 100644 >> Documentation/devicetree/bindings/crypto/rockchip-crypto.txt >> >> diff --git a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt >> b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt >> new file mode 100644 >> index 000..096df34 >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt >> @@ -0,0 +1,29 @@ >> +Rockchip Electronics And Security Accelerator >> + >> +Required properties: >> +- compatible: Should be "rockchip,rk3288-crypto" >> +- reg: Base physical address of the engine and length of memory mapped >> + region >> +- interrupts: Interrupt number >> +- clocks: Reference to the clocks about crypto >> +- clock-names: "aclk" used to clock data >> + "hclk" used to clock data >> + "sclk" used to clock crypto accelerator >> + "apb_pclk" used to clock dma >> +- resets: Must contain an entry for each entry in reset-names. >> + See ../reset/reset.txt for details. >> +- reset-names: Must include the name "crypto-rst". >> + >> +Examples: >> + >> +crypto: cypto-controller@ff8a { >> +compatible = "rockchip,rk3288-crypto"; >> +reg = <0xff8a 0x4000>; >> +interrupts = ; >> +clocks = < ACLK_CRYPTO>, < HCLK_CRYPTO>, >> + < SCLK_CRYPTO>, < ACLK_DMAC1>; >> +clock-names = "aclk", "hclk", "sclk", "apb_pclk"; >> +resets = < SRST_CRYPTO>; >> +reset-names = "crypto-rst"; >> +status = "okay"; >> +}; >> -- >> 1.9.1 >> >> > > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 4/4] ARM: dts: rockchip: Add Crypto node for rk3288
Add Crypto node for rk3288 including crypto controller and dma clk. Signed-off-by: Zain Wang --- Changed in v3: - add reset property Changed in v2: - None Changed in v1: - remove the _crypto suffix - use "rockchip,rk3288-crypto" instead of "rockchip,rk3288" arch/arm/boot/dts/rk3288.dtsi | 12 1 file changed, 12 insertions(+) diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi index 6a79c9c..f0d1217 100644 --- a/arch/arm/boot/dts/rk3288.dtsi +++ b/arch/arm/boot/dts/rk3288.dtsi @@ -778,6 +778,18 @@ status = "disabled"; }; + crypto: cypto-controller@ff8a { + compatible = "rockchip,rk3288-crypto"; + reg = <0xff8a 0x4000>; + interrupts = ; + clocks = < ACLK_CRYPTO>, < HCLK_CRYPTO>, +< SCLK_CRYPTO>, < ACLK_DMAC1>; + clock-names = "aclk", "hclk", "sclk", "apb_pclk"; + resets = < SRST_CRYPTO>; + reset-names = "crypto-rst"; + status = "okay"; + }; + vopb: vop@ff93 { compatible = "rockchip,rk3288-vop"; reg = <0xff93 0x19c>; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 3/4] Crypto: rockchip/crypto - add crypto driver for rk3288
Crypto driver support: ecb(aes) cbc(aes) ecb(des) cbc(des) ecb(des3_ede) cbc(des3_ede) You can alloc tags above in your case. And other algorithms and platforms will be added later on. Signed-off-by: Zain Wang --- Changed in v3: - add OF depended in Kconfig - remove crypto_p variate - fix of_device_id - add reset property Changed in v2: - remove some part about hash - add weak key detection - changed some variate's type Changde in v1: - modify some variate's name - modify some variate's type - modify some return value - remove or modify some print info - use more dev_xxx in probe - modify the prio of cipher drivers/crypto/Kconfig | 11 + drivers/crypto/Makefile| 1 + drivers/crypto/rockchip/Makefile | 3 + drivers/crypto/rockchip/rk3288_crypto.c| 392 +++ drivers/crypto/rockchip/rk3288_crypto.h| 220 + drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 527 + 6 files changed, 1154 insertions(+) create mode 100644 drivers/crypto/rockchip/Makefile create mode 100644 drivers/crypto/rockchip/rk3288_crypto.c create mode 100644 drivers/crypto/rockchip/rk3288_crypto.h create mode 100644 drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 2569e04..e5451b6 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -498,4 +498,15 @@ config CRYPTO_DEV_SUN4I_SS To compile this driver as a module, choose M here: the module will be called sun4i-ss. +config CRYPTO_DEV_ROCKCHIP + tristate "Rockchip's Cryptographic Engine driver" + depends on OF && ARCH_ROCKCHIP + select CRYPTO_AES + select CRYPTO_DES + select CRYPTO_BLKCIPHER + + help + This driver interfaces with the hardware crypto accelerator. + Supporting cbc/ecb chainmode, and aes/des/des3_ede cipher mode. + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index c3ced6f..713de9d 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -29,3 +29,4 @@ obj-$(CONFIG_CRYPTO_DEV_QAT) += qat/ obj-$(CONFIG_CRYPTO_DEV_QCE) += qce/ obj-$(CONFIG_CRYPTO_DEV_VMX) += vmx/ obj-$(CONFIG_CRYPTO_DEV_SUN4I_SS) += sunxi-ss/ +obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rockchip/ diff --git a/drivers/crypto/rockchip/Makefile b/drivers/crypto/rockchip/Makefile new file mode 100644 index 000..7051c6c --- /dev/null +++ b/drivers/crypto/rockchip/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_CRYPTO_DEV_ROCKCHIP) += rk_crypto.o +rk_crypto-objs := rk3288_crypto.o \ + rk3288_crypto_ablkcipher.o \ diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c new file mode 100644 index 000..bb36baa --- /dev/null +++ b/drivers/crypto/rockchip/rk3288_crypto.c @@ -0,0 +1,392 @@ +/* + *Crypto acceleration support for Rockchip RK3288 + * + * Copyright (c) 2015, Fuzhou Rockchip Electronics Co., Ltd + * + * Author: Zain Wang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * Some ideas are from marvell-cesa.c and s5p-sss.c driver. + */ + +#include "rk3288_crypto.h" +#include +#include +#include +#include +#include +#include + +static int rk_crypto_enable_clk(struct rk_crypto_info *dev) +{ + int err; + + err = clk_prepare_enable(dev->sclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock 'sclk'\n", + __func__, __LINE__); + goto err_return; + } + err = clk_prepare_enable(dev->aclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock 'aclk'\n", + __func__, __LINE__); + goto err_aclk; + } + err = clk_prepare_enable(dev->hclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock 'hclk'\n", + __func__, __LINE__); + goto err_hclk; + } + + err = clk_prepare_enable(dev->dmaclk); + if (err) { + dev_err(dev->dev, "[%s:%d], Couldn't enable clock 'dmaclk'\n", + __func__, __LINE__); + goto err_dmaclk; + } + return err; +err_dmaclk: + clk_disable_unprepare(dev->hclk); +err_hclk: + clk_disable_unprepare(dev->aclk); +err_aclk: + clk_disable_unprepare(dev->sclk); +err_return: + return err; +} + +static void rk_crypto_disable_clk(struct rk_crypto_info *dev) +{ + clk_disable_unprepare(dev->dmaclk); + clk_disable_unprepare(dev->hclk); + clk_disable_unprepare(dev-&g
[PATCH v3 1/4] crypto: rockchip/crypto - add DT bindings documentation
Add DT bindings documentation for the rk3288 crypto drivers. Signed-off-by: Zain Wang --- Changed in v3: - add reset property Changed in v2: - None Changed in v1: - remove the _crypto suffix - use "rockchip,rk3288-crypto" instead of "rockchip,rk3288" - remove the description of status .../devicetree/bindings/crypto/rockchip-crypto.txt | 29 ++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt diff --git a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt new file mode 100644 index 000..096df34 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt @@ -0,0 +1,29 @@ +Rockchip Electronics And Security Accelerator + +Required properties: +- compatible: Should be "rockchip,rk3288-crypto" +- reg: Base physical address of the engine and length of memory mapped + region +- interrupts: Interrupt number +- clocks: Reference to the clocks about crypto +- clock-names: "aclk" used to clock data + "hclk" used to clock data + "sclk" used to clock crypto accelerator + "apb_pclk" used to clock dma +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must include the name "crypto-rst". + +Examples: + + crypto: cypto-controller@ff8a { + compatible = "rockchip,rk3288-crypto"; + reg = <0xff8a 0x4000>; + interrupts = ; + clocks = < ACLK_CRYPTO>, < HCLK_CRYPTO>, +< SCLK_CRYPTO>, < ACLK_DMAC1>; + clock-names = "aclk", "hclk", "sclk", "apb_pclk"; + resets = < SRST_CRYPTO>; + reset-names = "crypto-rst"; + status = "okay"; + }; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 2/4] clk: rockchip: set an ID for crypto clk
Set an ID for crypto clk, so that it can be called in other part. Signed-off-by: Zain Wang --- Changed in v3: - None Changed in v2: - None Changed in v1: - define SCLK_CRYPTO in rk3288-cru.h - use SCLK_CRYPTO instead of SRST_CRYPTO drivers/clk/rockchip/clk-rk3288.c | 2 +- include/dt-bindings/clock/rk3288-cru.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/clk/rockchip/clk-rk3288.c b/drivers/clk/rockchip/clk-rk3288.c index 9040878..3fceda1 100644 --- a/drivers/clk/rockchip/clk-rk3288.c +++ b/drivers/clk/rockchip/clk-rk3288.c @@ -295,7 +295,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = { RK3288_CLKGATE_CON(0), 4, GFLAGS), GATE(0, "c2c_host", "aclk_cpu_src", 0, RK3288_CLKGATE_CON(13), 8, GFLAGS), - COMPOSITE_NOMUX(0, "crypto", "aclk_cpu_pre", 0, + COMPOSITE_NOMUX(SCLK_CRYPTO, "crypto", "aclk_cpu_pre", 0, RK3288_CLKSEL_CON(26), 6, 2, DFLAGS, RK3288_CLKGATE_CON(5), 4, GFLAGS), GATE(0, "aclk_bus_2pmu", "aclk_cpu_pre", CLK_IGNORE_UNUSED, diff --git a/include/dt-bindings/clock/rk3288-cru.h b/include/dt-bindings/clock/rk3288-cru.h index c719aac..30dcd60 100644 --- a/include/dt-bindings/clock/rk3288-cru.h +++ b/include/dt-bindings/clock/rk3288-cru.h @@ -86,6 +86,7 @@ #define SCLK_USBPHY480M_SRC122 #define SCLK_PVTM_CORE 123 #define SCLK_PVTM_GPU 124 +#define SCLK_CRYPTO125 #define SCLK_MAC 151 #define SCLK_MACREF_OUT152 -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 0/4] crypto: add crypto accelerator support for rk3288
This commit support three cipher(AES/DES/DES3) and two chainmode(ecb/cbc), and the more algorithms and new hash drivers will be added later on. Changed in v3: - add OF depended in Kconfig - rename some variate - add reset property - remove crypto_p variate Changed in v2: - remove some part about hash - add weak key detection - changed some variate's type Changed in v1: - modify some variate's name - modify some variate's type - modify some return value - remove or modify some print info - use more dev_xxx in probe - modify the prio of cipher - add Kconfig Zain Wang (4): crypto: rockchip/crypto - add DT bindings documentation clk: rockchip: set an ID for crypto clk Crypto: rockchip/crypto - add crypto driver for rk3288 ARM: dts: rockchip: Add Crypto node for rk3288 .../devicetree/bindings/crypto/rockchip-crypto.txt | 29 ++ arch/arm/boot/dts/rk3288.dtsi | 12 + drivers/clk/rockchip/clk-rk3288.c | 2 +- drivers/crypto/Kconfig | 11 + drivers/crypto/Makefile| 1 + drivers/crypto/rockchip/Makefile | 3 + drivers/crypto/rockchip/rk3288_crypto.c| 392 +++ drivers/crypto/rockchip/rk3288_crypto.h| 220 + drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c | 527 + include/dt-bindings/clock/rk3288-cru.h | 1 + 10 files changed, 1197 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt create mode 100644 drivers/crypto/rockchip/Makefile create mode 100644 drivers/crypto/rockchip/rk3288_crypto.c create mode 100644 drivers/crypto/rockchip/rk3288_crypto.h create mode 100644 drivers/crypto/rockchip/rk3288_crypto_ablkcipher.c -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 1/4] crypto: rockchip/crypto - add DT bindings documentation
Add DT bindings documentation for the rk3288 crypto drivers. Signed-off-by: Zain Wang <zain.w...@rock-chips.com> --- Changed in v3: - add reset property Changed in v2: - None Changed in v1: - remove the _crypto suffix - use "rockchip,rk3288-crypto" instead of "rockchip,rk3288" - remove the description of status .../devicetree/bindings/crypto/rockchip-crypto.txt | 29 ++ 1 file changed, 29 insertions(+) create mode 100644 Documentation/devicetree/bindings/crypto/rockchip-crypto.txt diff --git a/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt new file mode 100644 index 000..096df34 --- /dev/null +++ b/Documentation/devicetree/bindings/crypto/rockchip-crypto.txt @@ -0,0 +1,29 @@ +Rockchip Electronics And Security Accelerator + +Required properties: +- compatible: Should be "rockchip,rk3288-crypto" +- reg: Base physical address of the engine and length of memory mapped + region +- interrupts: Interrupt number +- clocks: Reference to the clocks about crypto +- clock-names: "aclk" used to clock data + "hclk" used to clock data + "sclk" used to clock crypto accelerator + "apb_pclk" used to clock dma +- resets: Must contain an entry for each entry in reset-names. + See ../reset/reset.txt for details. +- reset-names: Must include the name "crypto-rst". + +Examples: + + crypto: cypto-controller@ff8a { + compatible = "rockchip,rk3288-crypto"; + reg = <0xff8a 0x4000>; + interrupts = ; + clocks = < ACLK_CRYPTO>, < HCLK_CRYPTO>, +< SCLK_CRYPTO>, < ACLK_DMAC1>; + clock-names = "aclk", "hclk", "sclk", "apb_pclk"; + resets = < SRST_CRYPTO>; + reset-names = "crypto-rst"; + status = "okay"; + }; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/