From patchwork Mon Jan 7 06:44:29 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sachin Kamat X-Patchwork-Id: 13861 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 6DAAE23E2A for ; Mon, 7 Jan 2013 06:52:41 +0000 (UTC) Received: from mail-vc0-f172.google.com (mail-vc0-f172.google.com [209.85.220.172]) by fiordland.canonical.com (Postfix) with ESMTP id E2C1EA18495 for ; Mon, 7 Jan 2013 06:52:40 +0000 (UTC) Received: by mail-vc0-f172.google.com with SMTP id fw7so18970654vcb.17 for ; Sun, 06 Jan 2013 22:52:40 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:x-forwarded-to:x-forwarded-for:delivered-to:x-received :received-spf:x-received:from:to:cc:subject:date:message-id:x-mailer :x-gm-message-state; bh=4AEWisTajajS2HqO0Qnm0nT+4Pr1mTsVZw2PXhWCHe0=; b=WWOopL0Qqtr63aGzRo+iNBsNBs1pmWfr8QkMGj0DF5faR/RvgaflqDEZwtzVPG4xP+ i4vpc3B4eUOh0uf0E/FX6JBQJyccPqTBE/ZavrXN2AZV4V2uDieJN3Ow4WXs4h/ptBfL 2ExO0nABFXU1Vg4m6vTa77y1n62a8fpSC4xObenDptfuTBViazmWmPSWBDX38/nvCbik XfR7yHxbCi7hWtNGj5hUVaHfOxUVC5qKPnjPy4/ehCUKmJvKbS0bWV0Y9z9EyUOR4Sh8 mDch7CTYLWF076gHbebLQhDcjyQ0RA30sWhcJQ5dCjzmG1DG3YG5qcDmNItQq+Dotxb9 4ypw== X-Received: by 10.52.70.205 with SMTP id o13mr71483618vdu.75.1357541560352; Sun, 06 Jan 2013 22:52:40 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.58.145.101 with SMTP id st5csp48698veb; Sun, 6 Jan 2013 22:52:39 -0800 (PST) X-Received: by 10.68.197.68 with SMTP id is4mr182560609pbc.30.1357541558792; Sun, 06 Jan 2013 22:52:38 -0800 (PST) Received: from mail-pa0-f53.google.com (mail-pa0-f53.google.com [209.85.220.53]) by mx.google.com with ESMTPS id p7si58665188pav.21.2013.01.06.22.52.38 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 06 Jan 2013 22:52:38 -0800 (PST) Received-SPF: neutral (google.com: 209.85.220.53 is neither permitted nor denied by best guess record for domain of sachin.kamat@linaro.org) client-ip=209.85.220.53; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.53 is neither permitted nor denied by best guess record for domain of sachin.kamat@linaro.org) smtp.mail=sachin.kamat@linaro.org Received: by mail-pa0-f53.google.com with SMTP id hz1so10487475pad.40 for ; Sun, 06 Jan 2013 22:52:38 -0800 (PST) X-Received: by 10.66.9.2 with SMTP id v2mr174773237paa.18.1357541558228; Sun, 06 Jan 2013 22:52:38 -0800 (PST) Received: from localhost.localdomain ([115.113.119.130]) by mx.google.com with ESMTPS id rs7sm37114338pbc.2.2013.01.06.22.52.35 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 06 Jan 2013 22:52:37 -0800 (PST) From: Sachin Kamat To: linux-media@vger.kernel.org Cc: ajaykumar.rs@samsung.com, s.nawrocki@samsung.com, sachin.kamat@linaro.org, patches@linaro.org, Kamil Debski Subject: [PATCH] s5p-g2d: Add support for G2D H/W Rev.4.1 Date: Mon, 7 Jan 2013 12:14:29 +0530 Message-Id: <1357541069-7898-1-git-send-email-sachin.kamat@linaro.org> X-Mailer: git-send-email 1.7.4.1 X-Gm-Message-State: ALoCoQnQzKvfLFic7Bcf/8wKd3j9weYKUpOxtwh+IJhVlVxDDtMwaGzBwpmz4FMf4Onk7ExMJoiL Modified the G2D driver (which initially supported only H/W Rev.3) to support H/W Rev.4.1 present on Exynos4x12 and Exynos52x0 SOCs. -- Set the SRC and DST type to 'memory' instead of using reset values. -- FIMG2D v4.1 H/W uses different logic for stretching(scaling). -- Use CACHECTL_REG only with FIMG2D v3. Signed-off-by: Ajay Kumar Signed-off-by: Sachin Kamat Cc: Kamil Debski --- Earlier attempts at adding this support can be found at: http://patchwork.linuxtv.org/patch/10833/ This version addresses all the previous comments. --- drivers/media/platform/s5p-g2d/g2d-hw.c | 16 ++++++++--- drivers/media/platform/s5p-g2d/g2d-regs.h | 8 +++++ drivers/media/platform/s5p-g2d/g2d.c | 43 +++++++++++++++++++++++++++- drivers/media/platform/s5p-g2d/g2d.h | 13 ++++++--- 4 files changed, 70 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/s5p-g2d/g2d-hw.c b/drivers/media/platform/s5p-g2d/g2d-hw.c index 5b86cbe..e87bd93 100644 --- a/drivers/media/platform/s5p-g2d/g2d-hw.c +++ b/drivers/media/platform/s5p-g2d/g2d-hw.c @@ -28,6 +28,7 @@ void g2d_set_src_size(struct g2d_dev *d, struct g2d_frame *f) { u32 n; + w(0, SRC_SELECT_REG); w(f->stride & 0xFFFF, SRC_STRIDE_REG); n = f->o_height & 0xFFF; @@ -52,6 +53,7 @@ void g2d_set_dst_size(struct g2d_dev *d, struct g2d_frame *f) { u32 n; + w(0, DST_SELECT_REG); w(f->stride & 0xFFFF, DST_STRIDE_REG); n = f->o_height & 0xFFF; @@ -82,10 +84,14 @@ void g2d_set_flip(struct g2d_dev *d, u32 r) w(r, SRC_MSK_DIRECT_REG); } -u32 g2d_cmd_stretch(u32 e) +void g2d_set_v41_stretch(struct g2d_dev *d, struct g2d_frame *src, + struct g2d_frame *dst) { - e &= 1; - return e << 4; + w(DEFAULT_SCALE_MODE, SRC_SCALE_CTRL_REG); + + /* inversed scaling factor: src is numerator */ + w((src->c_width << 16) / dst->c_width, SRC_XSCALE_REG); + w((src->c_height << 16) / dst->c_height, SRC_YSCALE_REG); } void g2d_set_cmd(struct g2d_dev *d, u32 c) @@ -96,7 +102,9 @@ void g2d_set_cmd(struct g2d_dev *d, u32 c) void g2d_start(struct g2d_dev *d) { /* Clear cache */ - w(0x7, CACHECTL_REG); + if (d->variant->hw_rev == TYPE_G2D_3X) + w(0x7, CACHECTL_REG); + /* Enable interrupt */ w(1, INTEN_REG); /* Start G2D engine */ diff --git a/drivers/media/platform/s5p-g2d/g2d-regs.h b/drivers/media/platform/s5p-g2d/g2d-regs.h index 02e1cf5..950c742 100644 --- a/drivers/media/platform/s5p-g2d/g2d-regs.h +++ b/drivers/media/platform/s5p-g2d/g2d-regs.h @@ -35,6 +35,9 @@ #define SRC_COLOR_MODE_REG 0x030C /* Src Image Color Mode reg */ #define SRC_LEFT_TOP_REG 0x0310 /* Src Left Top Coordinate reg */ #define SRC_RIGHT_BOTTOM_REG 0x0314 /* Src Right Bottom Coordinate reg */ +#define SRC_SCALE_CTRL_REG 0x0328 /* Src Scaling type select */ +#define SRC_XSCALE_REG 0x032c /* Src X Scaling ratio */ +#define SRC_YSCALE_REG 0x0330 /* Src Y Scaling ratio */ /* Parameter Setting Registers (Dest) */ #define DST_SELECT_REG 0x0400 /* Dest Image Selection reg */ @@ -113,3 +116,8 @@ #define DEFAULT_WIDTH 100 #define DEFAULT_HEIGHT 100 +#define DEFAULT_SCALE_MODE (2 << 0) + +/* Command mode register values */ +#define CMD_V3_ENABLE_STRETCH (1 << 4) + diff --git a/drivers/media/platform/s5p-g2d/g2d.c b/drivers/media/platform/s5p-g2d/g2d.c index 1bfbc32..6c9a589 100644 --- a/drivers/media/platform/s5p-g2d/g2d.c +++ b/drivers/media/platform/s5p-g2d/g2d.c @@ -604,8 +604,13 @@ static void device_run(void *prv) g2d_set_flip(dev, ctx->flip); if (ctx->in.c_width != ctx->out.c_width || - ctx->in.c_height != ctx->out.c_height) - cmd |= g2d_cmd_stretch(1); + ctx->in.c_height != ctx->out.c_height) { + if (dev->variant->hw_rev == TYPE_G2D_3X) + cmd |= CMD_V3_ENABLE_STRETCH; + else + g2d_set_v41_stretch(dev, &ctx->in, &ctx->out); + } + g2d_set_cmd(dev, cmd); g2d_start(dev); @@ -690,6 +695,8 @@ static struct v4l2_m2m_ops g2d_m2m_ops = { .unlock = g2d_unlock, }; +static void *g2d_get_drv_data(struct platform_device *pdev); + static int g2d_probe(struct platform_device *pdev) { struct g2d_dev *dev; @@ -791,6 +798,7 @@ static int g2d_probe(struct platform_device *pdev) } def_frame.stride = (def_frame.width * def_frame.fmt->depth) >> 3; + dev->variant = g2d_get_drv_data(pdev); return 0; @@ -830,9 +838,40 @@ static int g2d_remove(struct platform_device *pdev) return 0; } +static void *g2d_get_drv_data(struct platform_device *pdev) +{ + struct g2d_variant *driver_data = NULL; + + driver_data = (struct g2d_variant *) + platform_get_device_id(pdev)->driver_data; + + return driver_data; +} + +struct g2d_variant g2d_drvdata_v3x = { + .hw_rev = TYPE_G2D_3X, +}; + +struct g2d_variant g2d_drvdata_v4x = { + .hw_rev = TYPE_G2D_4X, /* Revision 4.1 for Exynos4X12 and Exynos5 */ +}; + +static struct platform_device_id g2d_driver_ids[] = { + { + .name = "s5p-g2d", + .driver_data = (unsigned long)&g2d_drvdata_v3x, + }, { + .name = "s5p-g2d-v4x", + .driver_data = (unsigned long)&g2d_drvdata_v4x, + }, + {}, +}; +MODULE_DEVICE_TABLE(platform, g2d_driver_ids); + static struct platform_driver g2d_pdrv = { .probe = g2d_probe, .remove = g2d_remove, + .id_table = g2d_driver_ids, .driver = { .name = G2D_NAME, .owner = THIS_MODULE, diff --git a/drivers/media/platform/s5p-g2d/g2d.h b/drivers/media/platform/s5p-g2d/g2d.h index 6b765b0..3fb4555 100644 --- a/drivers/media/platform/s5p-g2d/g2d.h +++ b/drivers/media/platform/s5p-g2d/g2d.h @@ -14,6 +14,8 @@ #include #define G2D_NAME "s5p-g2d" +#define TYPE_G2D_3X 3 +#define TYPE_G2D_4X 4 struct g2d_dev { struct v4l2_device v4l2_dev; @@ -27,6 +29,7 @@ struct g2d_dev { struct clk *clk; struct clk *gate; struct g2d_ctx *curr; + struct g2d_variant *variant; int irq; wait_queue_head_t irq_queue; }; @@ -53,7 +56,7 @@ struct g2d_frame { struct g2d_ctx { struct v4l2_fh fh; struct g2d_dev *dev; - struct v4l2_m2m_ctx *m2m_ctx; + struct v4l2_m2m_ctx *m2m_ctx; struct g2d_frame in; struct g2d_frame out; struct v4l2_ctrl *ctrl_hflip; @@ -70,6 +73,9 @@ struct g2d_fmt { u32 hw; }; +struct g2d_variant { + unsigned short hw_rev; +}; void g2d_reset(struct g2d_dev *d); void g2d_set_src_size(struct g2d_dev *d, struct g2d_frame *f); @@ -80,7 +86,6 @@ void g2d_start(struct g2d_dev *d); void g2d_clear_int(struct g2d_dev *d); void g2d_set_rop4(struct g2d_dev *d, u32 r); void g2d_set_flip(struct g2d_dev *d, u32 r); -u32 g2d_cmd_stretch(u32 e); +void g2d_set_v41_stretch(struct g2d_dev *d, + struct g2d_frame *src, struct g2d_frame *dst); void g2d_set_cmd(struct g2d_dev *d, u32 c); - -