aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/s5p-g2d/g2d.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/s5p-g2d/g2d.c')
-rw-r--r--drivers/media/video/s5p-g2d/g2d.c63
1 files changed, 50 insertions, 13 deletions
diff --git a/drivers/media/video/s5p-g2d/g2d.c b/drivers/media/video/s5p-g2d/g2d.c
index febaa673d363..789de74014e5 100644
--- a/drivers/media/video/s5p-g2d/g2d.c
+++ b/drivers/media/video/s5p-g2d/g2d.c
@@ -178,6 +178,9 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
178{ 178{
179 struct g2d_ctx *ctx = container_of(ctrl->handler, struct g2d_ctx, 179 struct g2d_ctx *ctx = container_of(ctrl->handler, struct g2d_ctx,
180 ctrl_handler); 180 ctrl_handler);
181 unsigned long flags;
182
183 spin_lock_irqsave(&ctx->dev->ctrl_lock, flags);
181 switch (ctrl->id) { 184 switch (ctrl->id) {
182 case V4L2_CID_COLORFX: 185 case V4L2_CID_COLORFX:
183 if (ctrl->val == V4L2_COLORFX_NEGATIVE) 186 if (ctrl->val == V4L2_COLORFX_NEGATIVE)
@@ -185,10 +188,13 @@ static int g2d_s_ctrl(struct v4l2_ctrl *ctrl)
185 else 188 else
186 ctx->rop = ROP4_COPY; 189 ctx->rop = ROP4_COPY;
187 break; 190 break;
188 default: 191
189 v4l2_err(&ctx->dev->v4l2_dev, "unknown control\n"); 192 case V4L2_CID_HFLIP:
190 return -EINVAL; 193 ctx->flip = ctx->ctrl_hflip->val | (ctx->ctrl_vflip->val << 1);
194 break;
195
191 } 196 }
197 spin_unlock_irqrestore(&ctx->dev->ctrl_lock, flags);
192 return 0; 198 return 0;
193} 199}
194 200
@@ -200,11 +206,13 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx)
200{ 206{
201 struct g2d_dev *dev = ctx->dev; 207 struct g2d_dev *dev = ctx->dev;
202 208
203 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 1); 209 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
204 if (ctx->ctrl_handler.error) { 210
205 v4l2_err(&dev->v4l2_dev, "v4l2_ctrl_handler_init failed\n"); 211 ctx->ctrl_hflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &g2d_ctrl_ops,
206 return ctx->ctrl_handler.error; 212 V4L2_CID_HFLIP, 0, 1, 1, 0);
207 } 213
214 ctx->ctrl_vflip = v4l2_ctrl_new_std(&ctx->ctrl_handler, &g2d_ctrl_ops,
215 V4L2_CID_VFLIP, 0, 1, 1, 0);
208 216
209 v4l2_ctrl_new_std_menu( 217 v4l2_ctrl_new_std_menu(
210 &ctx->ctrl_handler, 218 &ctx->ctrl_handler,
@@ -215,10 +223,14 @@ int g2d_setup_ctrls(struct g2d_ctx *ctx)
215 V4L2_COLORFX_NONE); 223 V4L2_COLORFX_NONE);
216 224
217 if (ctx->ctrl_handler.error) { 225 if (ctx->ctrl_handler.error) {
218 v4l2_err(&dev->v4l2_dev, "v4l2_ctrl_handler_init failed\n"); 226 int err = ctx->ctrl_handler.error;
219 return ctx->ctrl_handler.error; 227 v4l2_err(&dev->v4l2_dev, "g2d_setup_ctrls failed\n");
228 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
229 return err;
220 } 230 }
221 231
232 v4l2_ctrl_cluster(2, &ctx->ctrl_hflip);
233
222 return 0; 234 return 0;
223} 235}
224 236
@@ -547,6 +559,7 @@ static void device_run(void *prv)
547 struct g2d_ctx *ctx = prv; 559 struct g2d_ctx *ctx = prv;
548 struct g2d_dev *dev = ctx->dev; 560 struct g2d_dev *dev = ctx->dev;
549 struct vb2_buffer *src, *dst; 561 struct vb2_buffer *src, *dst;
562 unsigned long flags;
550 u32 cmd = 0; 563 u32 cmd = 0;
551 564
552 dev->curr = ctx; 565 dev->curr = ctx;
@@ -557,6 +570,8 @@ static void device_run(void *prv)
557 clk_enable(dev->gate); 570 clk_enable(dev->gate);
558 g2d_reset(dev); 571 g2d_reset(dev);
559 572
573 spin_lock_irqsave(&dev->ctrl_lock, flags);
574
560 g2d_set_src_size(dev, &ctx->in); 575 g2d_set_src_size(dev, &ctx->in);
561 g2d_set_src_addr(dev, vb2_dma_contig_plane_dma_addr(src, 0)); 576 g2d_set_src_addr(dev, vb2_dma_contig_plane_dma_addr(src, 0));
562 577
@@ -564,11 +579,15 @@ static void device_run(void *prv)
564 g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0)); 579 g2d_set_dst_addr(dev, vb2_dma_contig_plane_dma_addr(dst, 0));
565 580
566 g2d_set_rop4(dev, ctx->rop); 581 g2d_set_rop4(dev, ctx->rop);
582 g2d_set_flip(dev, ctx->flip);
583
567 if (ctx->in.c_width != ctx->out.c_width || 584 if (ctx->in.c_width != ctx->out.c_width ||
568 ctx->in.c_height != ctx->out.c_height) 585 ctx->in.c_height != ctx->out.c_height)
569 cmd |= g2d_cmd_stretch(1); 586 cmd |= g2d_cmd_stretch(1);
570 g2d_set_cmd(dev, cmd); 587 g2d_set_cmd(dev, cmd);
571 g2d_start(dev); 588 g2d_start(dev);
589
590 spin_unlock_irqrestore(&dev->ctrl_lock, flags);
572} 591}
573 592
574static irqreturn_t g2d_isr(int irq, void *prv) 593static irqreturn_t g2d_isr(int irq, void *prv)
@@ -658,7 +677,7 @@ static int g2d_probe(struct platform_device *pdev)
658 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 677 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
659 if (!dev) 678 if (!dev)
660 return -ENOMEM; 679 return -ENOMEM;
661 spin_lock_init(&dev->irqlock); 680 spin_lock_init(&dev->ctrl_lock);
662 mutex_init(&dev->mutex); 681 mutex_init(&dev->mutex);
663 atomic_set(&dev->num_inst, 0); 682 atomic_set(&dev->num_inst, 0);
664 init_waitqueue_head(&dev->irq_queue); 683 init_waitqueue_head(&dev->irq_queue);
@@ -693,18 +712,30 @@ static int g2d_probe(struct platform_device *pdev)
693 goto unmap_regs; 712 goto unmap_regs;
694 } 713 }
695 714
715 ret = clk_prepare(dev->clk);
716 if (ret) {
717 dev_err(&pdev->dev, "failed to prepare g2d clock\n");
718 goto put_clk;
719 }
720
696 dev->gate = clk_get(&pdev->dev, "fimg2d"); 721 dev->gate = clk_get(&pdev->dev, "fimg2d");
697 if (IS_ERR_OR_NULL(dev->gate)) { 722 if (IS_ERR_OR_NULL(dev->gate)) {
698 dev_err(&pdev->dev, "failed to get g2d clock gate\n"); 723 dev_err(&pdev->dev, "failed to get g2d clock gate\n");
699 ret = -ENXIO; 724 ret = -ENXIO;
700 goto put_clk; 725 goto unprep_clk;
726 }
727
728 ret = clk_prepare(dev->gate);
729 if (ret) {
730 dev_err(&pdev->dev, "failed to prepare g2d clock gate\n");
731 goto put_clk_gate;
701 } 732 }
702 733
703 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 734 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
704 if (!res) { 735 if (!res) {
705 dev_err(&pdev->dev, "failed to find IRQ\n"); 736 dev_err(&pdev->dev, "failed to find IRQ\n");
706 ret = -ENXIO; 737 ret = -ENXIO;
707 goto put_clk_gate; 738 goto unprep_clk_gate;
708 } 739 }
709 740
710 dev->irq = res->start; 741 dev->irq = res->start;
@@ -764,8 +795,12 @@ alloc_ctx_cleanup:
764 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); 795 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
765rel_irq: 796rel_irq:
766 free_irq(dev->irq, dev); 797 free_irq(dev->irq, dev);
798unprep_clk_gate:
799 clk_unprepare(dev->gate);
767put_clk_gate: 800put_clk_gate:
768 clk_put(dev->gate); 801 clk_put(dev->gate);
802unprep_clk:
803 clk_unprepare(dev->clk);
769put_clk: 804put_clk:
770 clk_put(dev->clk); 805 clk_put(dev->clk);
771unmap_regs: 806unmap_regs:
@@ -787,7 +822,9 @@ static int g2d_remove(struct platform_device *pdev)
787 v4l2_device_unregister(&dev->v4l2_dev); 822 v4l2_device_unregister(&dev->v4l2_dev);
788 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx); 823 vb2_dma_contig_cleanup_ctx(dev->alloc_ctx);
789 free_irq(dev->irq, dev); 824 free_irq(dev->irq, dev);
825 clk_unprepare(dev->gate);
790 clk_put(dev->gate); 826 clk_put(dev->gate);
827 clk_unprepare(dev->clk);
791 clk_put(dev->clk); 828 clk_put(dev->clk);
792 iounmap(dev->regs); 829 iounmap(dev->regs);
793 release_resource(dev->res_regs); 830 release_resource(dev->res_regs);