Re: [PATCH v4 1/4] [media] exynos-scaler: Add new driver for Exynos5 SCALER

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Mauro,

Thanks for the review comments.

On Fri, Jan 3, 2014 at 1:48 AM, Mauro Carvalho Chehab
<m.chehab@xxxxxxxxxxx> wrote:
> Em Fri,  4 Oct 2013 17:56:31 +0530
> Shaik Ameer Basha <shaik.ameer@xxxxxxxxxxx> escreveu:
>
>> This patch adds support for SCALER device which is a new device
>> for scaling, blending, color fill  and color space conversion
>> on EXYNOS5410 and EXYNOS5420 SoCs.
>>
>> This device supports the followings as key feature.
>>     input image format
>>         - YCbCr420 2P(UV/VU), 3P
>>         - YCbCr422 1P(YUYV/UYVY/YVYU), 2P(UV,VU), 3P
>>         - YCbCr444 2P(UV,VU), 3P
>>         - RGB565, ARGB1555, ARGB4444, ARGB8888, RGBA8888
>>         - Pre-multiplexed ARGB8888, L8A8 and L8
>>     output image format
>>         - YCbCr420 2P(UV/VU), 3P
>>         - YCbCr422 1P(YUYV/UYVY/YVYU), 2P(UV,VU), 3P
>>         - YCbCr444 2P(UV,VU), 3P
>>         - RGB565, ARGB1555, ARGB4444, ARGB8888, RGBA8888
>>         - Pre-multiplexed ARGB8888
>>     input rotation
>>         - 0/90/180/270 degree, X/Y/XY Flip
>>     scale ratio
>>         - 1/4 scale down to 16 scale up
>>     color space conversion
>>         - RGB to YUV / YUV to RGB
>>     Size - Exynos5420
>>         - Input : 16x16 to 8192x8192
>>         - Output:   4x4 to 8192x8192
>>     Size - Exynos5410
>>         - Input/Output: 4x4 to 4096x4096
>>     alpha blending, color fill
>>
>> Signed-off-by: Shaik Ameer Basha <shaik.ameer@xxxxxxxxxxx>
>> ---
>>  drivers/media/platform/exynos-scaler/scaler-regs.c |  336 ++++++++++++++++++++
>>  drivers/media/platform/exynos-scaler/scaler-regs.h |  331 +++++++++++++++++++
>>  2 files changed, 667 insertions(+)
>>  create mode 100644 drivers/media/platform/exynos-scaler/scaler-regs.c
>>  create mode 100644 drivers/media/platform/exynos-scaler/scaler-regs.h
>>
>> diff --git a/drivers/media/platform/exynos-scaler/scaler-regs.c b/drivers/media/platform/exynos-scaler/scaler-regs.c
>> new file mode 100644
>> index 0000000..ae4a548
>> --- /dev/null
>> +++ b/drivers/media/platform/exynos-scaler/scaler-regs.c
>> @@ -0,0 +1,336 @@
>> +/*
>> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
>> + *           http://www.samsung.com
>> + *
>> + * Samsung EXYNOS5 SoC series SCALER driver
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#include <linux/delay.h>
>> +#include <linux/platform_device.h>
>> +
>> +#include "scaler-regs.h"
>> +
>> +/* Scaler reset timeout in milliseconds */
>> +#define SCALER_RESET_TIMEOUT 50
>> +
>> +void scaler_hw_set_sw_reset(struct scaler_dev *dev)
>> +{
>> +     u32 cfg;
>> +
>> +     cfg = scaler_read(dev, SCALER_CFG);
>> +     cfg |= SCALER_CFG_SOFT_RESET;
>> +
>> +     scaler_write(dev, SCALER_CFG, cfg);
>> +}
>> +
>> +int scaler_wait_reset(struct scaler_dev *dev)
>> +{
>> +     unsigned long end = jiffies + msecs_to_jiffies(SCALER_RESET_TIMEOUT);
>> +     u32 cfg, reset_done = 0;
>> +
>> +     while (time_before(jiffies, end)) {
>> +             cfg = scaler_read(dev, SCALER_CFG);
>> +             if (!(cfg & SCALER_CFG_SOFT_RESET)) {
>> +                     reset_done = 1;
>> +                     break;
>> +             }
>> +             usleep_range(10, 20);
>
> Hmm... that doesn't seem right... the timeout can take up to 50,000 us, and
> you're sleeping from 10 to 20us... that means that this loop can have up to
> 5000 interactions... It seems that you're wasting power here without need.
>
> I suspect that you should consider sleeping for a longer time here.

I will check what is the average time taken for the reset process.
If it is much more than 20us then i will increase this sleeping time.

>
> Btw, instead of using time_before(jiffies, end), you could do:
>         time_is_after_jiffies(end)
>

Ok. I will modify.

> As, from jiffies.h:
>         /* time_is_after_jiffies(a) return true if a is after jiffies */
>         #define time_is_after_jiffies(a) time_before(jiffies, a)
>
>> +     }
>> +
>> +     /*
>> +      * Write any value to read/write register and read it back.
>> +      * If the written and read value matches, then the reset process is
>> +      * succeeded.
>> +      */
>> +     while (reset_done) {
>
> This is tricky. If the reset fail, it will return busy. Otherwise, it
> can loop forever here. Worse than that, you're don't even sleeping
> before retries, again wasting power.
>
> Why don't you just change it to something similar to:
>
>         if (!reset_done)
>                 return -EBUSY;
>
>         end = jiffies + msecs_to_jiffies(SCALER_RESET_TIMEOUT);
>         while (time_is_after_jiffies(end)) {
>                 scaler_write(dev, SCALER_CFG_SOFT_RESET_CHECK_REG,
>                                 SCALER_CFG_SOFT_RESET_CHECK_VAL);
>                 if (SCALER_CFG_SOFT_RESET_CHECK_VAL ==
>                         scaler_read(dev, SCALER_CFG_SOFT_RESET_CHECK_REG))
>                         return 0;
>                 msleep(10);
>         }


My Intention is to complete the reset process ASAP.
Again I need to check the average time here. As per you comments if
the time taken is more
then I will go with adding sleep here.

Regards,
Shaik Ameer Basha

>
>> +
>> +             /*
>> +              * TODO: need to define number of tries before returning
>> +              * -EBUSY to the caller
>> +              */
>> +
>> +             scaler_write(dev, SCALER_CFG_SOFT_RESET_CHECK_REG,
>> +                             SCALER_CFG_SOFT_RESET_CHECK_VAL);
>> +             if (SCALER_CFG_SOFT_RESET_CHECK_VAL ==
>> +                     scaler_read(dev, SCALER_CFG_SOFT_RESET_CHECK_REG))
>> +                     return 0;
>> +     }
>> +
>> +     return -EBUSY;
>> +}
>> +
>> +void scaler_hw_set_irq(struct scaler_dev *dev, int irq_num, bool enable)
>> +{
>> +     u32 cfg;
>> +
>> +     if ((irq_num < SCALER_INT_FRAME_END) ||
>> +         (irq_num > SCALER_INT_TIMEOUT))
>> +             return;
>> +
>> +     cfg = scaler_read(dev, SCALER_INT_EN);
>> +     if (enable)
>> +             cfg |= (1 << irq_num);
>
> Why do you need parenthesis here?
>
>> +     else
>> +             cfg &= ~(1 << irq_num);
>
>
>> +     scaler_write(dev, SCALER_INT_EN, cfg);
>> +}
>> +
>> +void scaler_hw_set_input_addr(struct scaler_dev *dev, struct scaler_addr *addr)
>> +{
>> +     scaler_dbg(dev, "src_buf: 0x%x, cb: 0x%x, cr: 0x%x",
>> +                             addr->y, addr->cb, addr->cr);
>> +     scaler_write(dev, SCALER_SRC_Y_BASE, addr->y);
>> +     scaler_write(dev, SCALER_SRC_CB_BASE, addr->cb);
>> +     scaler_write(dev, SCALER_SRC_CR_BASE, addr->cr);
>> +}
>> +
>> +void scaler_hw_set_output_addr(struct scaler_dev *dev,
>> +                          struct scaler_addr *addr)
>> +{
>> +     scaler_dbg(dev, "dst_buf: 0x%x, cb: 0x%x, cr: 0x%x",
>> +                     addr->y, addr->cb, addr->cr);
>> +     scaler_write(dev, SCALER_DST_Y_BASE, addr->y);
>> +     scaler_write(dev, SCALER_DST_CB_BASE, addr->cb);
>> +     scaler_write(dev, SCALER_DST_CR_BASE, addr->cr);
>> +}
>> +
>> +void scaler_hw_set_in_size(struct scaler_ctx *ctx)
>> +{
>> +     struct scaler_dev *dev = ctx->scaler_dev;
>> +     struct scaler_frame *frame = &ctx->s_frame;
>> +     u32 cfg;
>> +
>> +     /* set input pixel offset */
>> +     cfg = (frame->selection.left & SCALER_SRC_YH_POS_MASK) <<
>> +                               SCALER_SRC_YH_POS_SHIFT;
>> +     cfg |= ((frame->selection.top & SCALER_SRC_YV_POS_MASK) <<
>> +                                SCALER_SRC_YV_POS_SHIFT);
>> +     scaler_write(dev, SCALER_SRC_Y_POS, cfg);
>> +
>> +     /* TODO: calculate 'C' plane h/v offset using 'Y' plane h/v offset */
>> +
>> +     /* Set input span */
>> +     cfg = (frame->f_width & SCALER_SRC_Y_SPAN_MASK) <<
>> +                             SCALER_SRC_Y_SPAN_SHIFT;
>> +     if (is_yuv420_2p(frame->fmt))
>> +             cfg |= ((frame->f_width & SCALER_SRC_C_SPAN_MASK) <<
>> +                                       SCALER_SRC_C_SPAN_SHIFT);
>> +     else /* TODO: Verify */
>> +             cfg |= ((frame->f_width & SCALER_SRC_C_SPAN_MASK) <<
>> +                                       SCALER_SRC_C_SPAN_SHIFT);
>> +
>> +     scaler_write(dev, SCALER_SRC_SPAN, cfg);
>> +
>> +     /* Set input cropped size */
>> +     cfg = (frame->selection.width & SCALER_SRC_WIDTH_MASK) <<
>> +                                SCALER_SRC_WIDTH_SHIFT;
>> +     cfg |= ((frame->selection.height & SCALER_SRC_HEIGHT_MASK) <<
>> +                                   SCALER_SRC_HEIGHT_SHIFT);
>> +     scaler_write(dev, SCALER_SRC_WH, cfg);
>> +
>> +     scaler_dbg(dev, "src: posx: %d, posY: %d, spanY: %d, spanC: %d, cropX: %d, cropY: %d\n",
>> +             frame->selection.left, frame->selection.top,
>> +             frame->f_width, frame->f_width, frame->selection.width,
>> +             frame->selection.height);
>> +}
>> +
>> +void scaler_hw_set_in_image_format(struct scaler_ctx *ctx)
>> +{
>> +     struct scaler_dev *dev = ctx->scaler_dev;
>> +     struct scaler_frame *frame = &ctx->s_frame;
>> +     u32 cfg;
>> +
>> +     cfg = scaler_read(dev, SCALER_SRC_CFG);
>> +     cfg &= ~(SCALER_SRC_COLOR_FORMAT_MASK << SCALER_SRC_COLOR_FORMAT_SHIFT);
>> +     cfg |= ((frame->fmt->scaler_color & SCALER_SRC_COLOR_FORMAT_MASK) <<
>> +                                        SCALER_SRC_COLOR_FORMAT_SHIFT);
>> +
>> +     /* Setting tiled/linear format */
>> +     if (is_tiled_fmt(frame->fmt))
>> +             cfg |= SCALER_SRC_TILE_EN;
>> +     else
>> +             cfg &= ~SCALER_SRC_TILE_EN;
>> +
>> +     scaler_write(dev, SCALER_SRC_CFG, cfg);
>> +}
>> +
>> +void scaler_hw_set_out_size(struct scaler_ctx *ctx)
>> +{
>> +     struct scaler_dev *dev = ctx->scaler_dev;
>> +     struct scaler_frame *frame = &ctx->d_frame;
>> +     u32 cfg;
>> +
>> +     /* Set output pixel offset */
>> +     cfg = (frame->selection.left & SCALER_DST_H_POS_MASK) <<
>> +                               SCALER_DST_H_POS_SHIFT;
>> +     cfg |= (frame->selection.top & SCALER_DST_V_POS_MASK) <<
>> +                               SCALER_DST_V_POS_SHIFT;
>> +     scaler_write(dev, SCALER_DST_POS, cfg);
>> +
>> +     /* Set output span */
>> +     cfg = (frame->f_width & SCALER_DST_Y_SPAN_MASK) <<
>> +                             SCALER_DST_Y_SPAN_SHIFT;
>> +     if (is_yuv420_2p(frame->fmt))
>> +             cfg |= (((frame->f_width / 2) & SCALER_DST_C_SPAN_MASK) <<
>> +                                          SCALER_DST_C_SPAN_SHIFT);
>> +     else
>> +             cfg |= (((frame->f_width) & SCALER_DST_C_SPAN_MASK) <<
>> +                                          SCALER_DST_C_SPAN_SHIFT);
>> +     scaler_write(dev, SCALER_DST_SPAN, cfg);
>> +
>> +     /* Set output scaled size */
>> +     cfg = (frame->selection.width & SCALER_DST_WIDTH_MASK) <<
>> +                                SCALER_DST_WIDTH_SHIFT;
>> +     cfg |= (frame->selection.height & SCALER_DST_HEIGHT_MASK) <<
>> +                                  SCALER_DST_HEIGHT_SHIFT;
>> +     scaler_write(dev, SCALER_DST_WH, cfg);
>> +
>> +     scaler_dbg(dev, "dst: pos X: %d, pos Y: %d, span Y: %d, span C: %d, crop X: %d, crop Y: %d\n",
>> +             frame->selection.left, frame->selection.top,
>> +             frame->f_width, frame->f_width, frame->selection.width,
>> +             frame->selection.height);
>> +}
>> +
>> +void scaler_hw_set_out_image_format(struct scaler_ctx *ctx)
>> +{
>> +     struct scaler_dev *dev = ctx->scaler_dev;
>> +     struct scaler_frame *frame = &ctx->d_frame;
>> +     u32 cfg;
>> +
>> +     cfg = scaler_read(dev, SCALER_DST_CFG);
>> +     cfg &= ~SCALER_DST_COLOR_FORMAT_MASK;
>> +     cfg |= (frame->fmt->scaler_color & SCALER_DST_COLOR_FORMAT_MASK);
>> +
>> +     scaler_write(dev, SCALER_DST_CFG, cfg);
>> +}
>> +
>> +void scaler_hw_set_scaler_ratio(struct scaler_ctx *ctx)
>> +{
>> +     struct scaler_dev *dev = ctx->scaler_dev;
>> +     struct scaler_scaler *sc = &ctx->scaler;
>> +     u32 cfg;
>> +
>> +     cfg = (sc->hratio & SCALER_H_RATIO_MASK) << SCALER_H_RATIO_SHIFT;
>> +     scaler_write(dev, SCALER_H_RATIO, cfg);
>> +
>> +     cfg = (sc->vratio & SCALER_V_RATIO_MASK) << SCALER_V_RATIO_SHIFT;
>> +     scaler_write(dev, SCALER_V_RATIO, cfg);
>> +}
>> +
>> +void scaler_hw_set_rotation(struct scaler_ctx *ctx)
>> +{
>> +     struct scaler_dev *dev = ctx->scaler_dev;
>> +     u32 cfg = 0;
>> +
>> +     cfg = ((ctx->ctrls_scaler.rotate->val / 90) & SCALER_ROTMODE_MASK) <<
>> +                                                   SCALER_ROTMODE_SHIFT;
>> +
>> +     if (ctx->ctrls_scaler.hflip->val)
>> +             cfg |= SCALER_FLIP_X_EN;
>> +
>> +     if (ctx->ctrls_scaler.vflip->val)
>> +             cfg |= SCALER_FLIP_Y_EN;
>> +
>> +     scaler_write(dev, SCALER_ROT_CFG, cfg);
>> +}
>> +
>> +void scaler_hw_set_csc_coeff(struct scaler_ctx *ctx)
>> +{
>> +     struct scaler_dev *dev = ctx->scaler_dev;
>> +     enum scaler_csc_coeff type;
>> +     u32 cfg = 0;
>> +     int i, j;
>> +     static const u32 csc_coeff[SCALER_CSC_COEFF_MAX][3][3] = {
>> +             { /* YCbCr to RGB */
>> +                     {0x254, 0x000, 0x331},
>> +                     {0x254, 0xec8, 0xFA0},
>> +                     {0x254, 0x409, 0x000}
>> +             },
>> +             { /* RGB to YCbCr */
>> +                     {0x084, 0x102, 0x032},
>> +                     {0xe4c, 0xe95, 0x0e1},
>> +                     {0x0e1, 0xebc, 0xe24}
>> +             } };
>> +
>> +     /* TODO: add check for BT.601,BT.709 narrow/wide ranges */
>> +     if (is_rgb(ctx->s_frame.fmt) == is_rgb(ctx->d_frame.fmt)) {
>> +             type = SCALER_CSC_COEFF_NONE;
>> +     } else if (is_rgb(ctx->d_frame.fmt)) {
>> +             type = SCALER_CSC_COEFF_YCBCR_TO_RGB;
>> +             scaler_hw_src_y_offset_en(ctx->scaler_dev, true);
>> +     } else {
>> +             type = SCALER_CSC_COEFF_RGB_TO_YCBCR;
>> +             scaler_hw_src_y_offset_en(ctx->scaler_dev, true);
>> +     }
>> +
>> +     if (type == ctx->scaler_dev->coeff_type || type >= SCALER_CSC_COEFF_MAX)
>> +             return;
>> +
>> +     for (i = 0; i < 3; i++) {
>> +             for (j = 0; j < 3; j++) {
>> +                     cfg = csc_coeff[type][i][j];
>> +                     scaler_write(dev, SCALER_CSC_COEF(i, j), cfg);
>> +             }
>> +     }
>> +
>> +     ctx->scaler_dev->coeff_type = type;
>> +}
>> +
>> +void scaler_hw_src_y_offset_en(struct scaler_dev *dev, bool on)
>> +{
>> +     u32 cfg;
>> +
>> +     cfg = scaler_read(dev, SCALER_CFG);
>> +     if (on)
>> +             cfg |= SCALER_CFG_CSC_Y_OFFSET_SRC_EN;
>> +     else
>> +             cfg &= ~SCALER_CFG_CSC_Y_OFFSET_SRC_EN;
>> +
>> +     scaler_write(dev, SCALER_CFG, cfg);
>> +}
>> +
>> +void scaler_hw_dst_y_offset_en(struct scaler_dev *dev, bool on)
>> +{
>> +     u32 cfg;
>> +
>> +     cfg = scaler_read(dev, SCALER_CFG);
>> +     if (on)
>> +             cfg |= SCALER_CFG_CSC_Y_OFFSET_DST_EN;
>> +     else
>> +             cfg &= ~SCALER_CFG_CSC_Y_OFFSET_DST_EN;
>> +
>> +     scaler_write(dev, SCALER_CFG, cfg);
>> +}
>> +
>> +void scaler_hw_enable_control(struct scaler_dev *dev, bool on)
>> +{
>> +     u32 cfg;
>> +
>> +     if (on)
>> +             scaler_write(dev, SCALER_INT_EN, 0xffffffff);
>> +
>> +     cfg = scaler_read(dev, SCALER_CFG);
>> +     cfg |= SCALER_CFG_16_BURST_MODE;
>> +     if (on)
>> +             cfg |= SCALER_CFG_START_CMD;
>> +     else
>> +             cfg &= ~SCALER_CFG_START_CMD;
>> +
>> +     scaler_dbg(dev, "%s: SCALER_CFG:0x%x\n", __func__, cfg);
>> +
>> +     scaler_write(dev, SCALER_CFG, cfg);
>> +}
>> +
>> +unsigned int scaler_hw_get_irq_status(struct scaler_dev *dev)
>> +{
>> +     return scaler_read(dev, SCALER_INT_STATUS);
>> +}
>> +
>> +void scaler_hw_clear_irq(struct scaler_dev *dev, unsigned int irq)
>> +{
>> +     scaler_write(dev, SCALER_INT_STATUS, irq);
>> +}
>> diff --git a/drivers/media/platform/exynos-scaler/scaler-regs.h b/drivers/media/platform/exynos-scaler/scaler-regs.h
>> new file mode 100644
>> index 0000000..2170df5
>> --- /dev/null
>> +++ b/drivers/media/platform/exynos-scaler/scaler-regs.h
>> @@ -0,0 +1,331 @@
>> +/*
>> + * Copyright (c) 2013 Samsung Electronics Co., Ltd.
>> + *           http://www.samsung.com
>> + *
>> + * Samsung EXYNOS5 SoC series SCALER driver
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + */
>> +
>> +#ifndef REGS_SCALER_H_
>> +#define REGS_SCALER_H_
>> +
>> +#include "scaler.h"
>> +
>> +/* SCALER status */
>> +#define SCALER_STATUS                                0x00
>> +#define SCALER_STATUS_RUNNING                        (1 << 1)
>> +#define SCALER_STATUS_READY_CLK_DOWN         (1 << 0)
>> +
>> +/* SCALER config */
>> +#define SCALER_CFG                           0x04
>> +#define SCALER_CFG_FILL_EN                   (1 << 24)
>> +#define SCALER_CFG_BLEND_CLR_DIV_ALPHA_EN    (1 << 17)
>> +#define SCALER_CFG_BLEND_EN                  (1 << 16)
>> +#define SCALER_CFG_CSC_Y_OFFSET_SRC_EN               (1 << 10)
>> +#define SCALER_CFG_CSC_Y_OFFSET_DST_EN               (1 << 9)
>> +#define SCALER_CFG_16_BURST_MODE             (1 << 8)
>> +#define SCALER_CFG_SOFT_RESET                        (1 << 1)
>> +#define SCALER_CFG_START_CMD                 (1 << 0)
>> +
>> +/* SCALER interrupts */
>> +#define SCALER_INT_TIMEOUT                   31
>> +#define SCALER_INT_ILLEGAL_BLEND             24
>> +#define SCALER_INT_ILLEGAL_RATIO             23
>> +#define SCALER_INT_ILLEGAL_DST_HEIGHT                22
>> +#define SCALER_INT_ILLEGAL_DST_WIDTH         21
>> +#define SCALER_INT_ILLEGAL_DST_V_POS         20
>> +#define SCALER_INT_ILLEGAL_DST_H_POS         19
>> +#define SCALER_INT_ILLEGAL_DST_C_SPAN                18
>> +#define SCALER_INT_ILLEGAL_DST_Y_SPAN                17
>> +#define SCALER_INT_ILLEGAL_DST_CR_BASE               16
>> +#define SCALER_INT_ILLEGAL_DST_CB_BASE               15
>> +#define SCALER_INT_ILLEGAL_DST_Y_BASE                14
>> +#define SCALER_INT_ILLEGAL_DST_COLOR         13
>> +#define SCALER_INT_ILLEGAL_SRC_HEIGHT                12
>> +#define SCALER_INT_ILLEGAL_SRC_WIDTH         11
>> +#define SCALER_INT_ILLEGAL_SRC_CV_POS                10
>> +#define SCALER_INT_ILLEGAL_SRC_CH_POS                9
>> +#define SCALER_INT_ILLEGAL_SRC_YV_POS                8
>> +#define SCALER_INT_ILLEGAL_SRC_YH_POS                7
>> +#define SCALER_INT_ILLEGAL_SRC_C_SPAN                6
>> +#define SCALER_INT_ILLEGAL_SRC_Y_SPAN                5
>> +#define SCALER_INT_ILLEGAL_SRC_CR_BASE               4
>> +#define SCALER_INT_ILLEGAL_SRC_CB_BASE               3
>> +#define SCALER_INT_ILLEGAL_SRC_Y_BASE                2
>> +#define SCALER_INT_ILLEGAL_SRC_COLOR         1
>> +#define SCALER_INT_FRAME_END                 0
>> +
>> +/* SCALER interrupt enable */
>> +#define SCALER_INT_EN                                0x08
>> +#define SCALER_INT_EN_DEFAULT                        0x81ffffff
>> +
>> +/* SCALER interrupt status */
>> +#define SCALER_INT_STATUS                    0x0c
>> +#define SCALER_INT_STATUS_CLEAR                      0xffffffff
>> +#define SCALER_INT_STATUS_ERROR                      0x81fffffe
>> +
>> +/* SCALER source format configuration */
>> +#define SCALER_SRC_CFG                               0x10
>> +#define SCALER_SRC_TILE_EN                   (0x1 << 10)
>> +#define SCALER_SRC_BYTE_SWAP_MASK            0x3
>> +#define SCALER_SRC_BYTE_SWAP_SHIFT           5
>> +#define SCALER_SRC_COLOR_FORMAT_MASK         0xf
>> +#define SCALER_SRC_COLOR_FORMAT_SHIFT                0
>> +
>> +/* SCALER source y-base */
>> +#define SCALER_SRC_Y_BASE                    0x14
>> +
>> +/* SCALER source cb-base */
>> +#define SCALER_SRC_CB_BASE                   0x18
>> +
>> +/* SCALER source cr-base */
>> +#define SCALER_SRC_CR_BASE                   0x294
>> +
>> +/* SCALER source span */
>> +#define SCALER_SRC_SPAN                              0x1c
>> +#define SCALER_SRC_C_SPAN_MASK                       0x3fff
>> +#define SCALER_SRC_C_SPAN_SHIFT                      16
>> +#define SCALER_SRC_Y_SPAN_MASK                       0x3fff
>> +#define SCALER_SRC_Y_SPAN_SHIFT                      0
>> +
>> +/*
>> + * SCALER source y-position
>> + * 14.2 fixed-point format
>> + *      - 14 bits at the MSB are for the integer part.
>> + *      - 2 bits at LSB are for fractional part and always has to be set to 0.
>> + */
>> +#define SCALER_SRC_Y_POS                     0x20
>> +#define SCALER_SRC_YH_POS_MASK                       0xfffc
>> +#define SCALER_SRC_YH_POS_SHIFT                      16
>> +#define SCALER_SRC_YV_POS_MASK                       0xfffc
>> +#define SCALER_SRC_YV_POS_SHIFT                      0
>> +
>> +/* SCALER source width/height */
>> +#define SCALER_SRC_WH                                0x24
>> +#define SCALER_SRC_WIDTH_MASK                        0x3fff
>> +#define SCALER_SRC_WIDTH_SHIFT                       16
>> +#define SCALER_SRC_HEIGHT_MASK                       0x3fff
>> +#define SCALER_SRC_HEIGHT_SHIFT                      0
>> +
>> +/*
>> + * SCALER source c-position
>> + * 14.2 fixed-point format
>> + *      - 14 bits at the MSB are for the integer part.
>> + *      - 2 bits at LSB are for fractional part and always has to be set to 0.
>> + */
>> +#define SCALER_SRC_C_POS                     0x28
>> +#define SCALER_SRC_CH_POS_MASK                       0xfffc
>> +#define SCALER_SRC_CH_POS_SHIFT                      16
>> +#define SCALER_SRC_CV_POS_MASK                       0xfffc
>> +#define SCALER_SRC_CV_POS_SHIFT                      0
>> +
>> +/* SCALER destination format configuration */
>> +#define SCALER_DST_CFG                               0x30
>> +#define SCALER_DST_BYTE_SWAP_MASK            0x3
>> +#define SCALER_DST_BYTE_SWAP_SHIFT           5
>> +#define SCALER_DST_COLOR_FORMAT_MASK         0xf
>> +
>> +/* SCALER destination y-base */
>> +#define SCALER_DST_Y_BASE                    0x34
>> +
>> +/* SCALER destination cb-base */
>> +#define SCALER_DST_CB_BASE                   0x38
>> +
>> +/* SCALER destination cr-base */
>> +#define SCALER_DST_CR_BASE                   0x298
>> +
>> +/* SCALER destination span */
>> +#define SCALER_DST_SPAN                              0x3c
>> +#define SCALER_DST_C_SPAN_MASK                       0x3fff
>> +#define SCALER_DST_C_SPAN_SHIFT                      16
>> +#define SCALER_DST_Y_SPAN_MASK                       0x3fff
>> +#define SCALER_DST_Y_SPAN_SHIFT                      0
>> +
>> +/* SCALER destination width/height */
>> +#define SCALER_DST_WH                                0x40
>> +#define SCALER_DST_WIDTH_MASK                        0x3fff
>> +#define SCALER_DST_WIDTH_SHIFT                       16
>> +#define SCALER_DST_HEIGHT_MASK                       0x3fff
>> +#define SCALER_DST_HEIGHT_SHIFT                      0
>> +
>> +/* SCALER destination position */
>> +#define SCALER_DST_POS                               0x44
>> +#define SCALER_DST_H_POS_MASK                        0x3fff
>> +#define SCALER_DST_H_POS_SHIFT                       16
>> +#define SCALER_DST_V_POS_MASK                        0x3fff
>> +#define SCALER_DST_V_POS_SHIFT                       0
>> +
>> +/* SCALER horizontal scale ratio */
>> +#define SCALER_H_RATIO                               0x50
>> +#define SCALER_H_RATIO_MASK                  0x7ffff
>> +#define SCALER_H_RATIO_SHIFT                 0
>> +
>> +/* SCALER vertical scale ratio */
>> +#define SCALER_V_RATIO                               0x54
>> +#define SCALER_V_RATIO_MASK                  0x7ffff
>> +#define SCALER_V_RATIO_SHIFT                 0
>> +
>> +/* SCALER rotation config */
>> +#define SCALER_ROT_CFG                               0x58
>> +#define SCALER_FLIP_X_EN                     (1 << 3)
>> +#define SCALER_FLIP_Y_EN                     (1 << 2)
>> +#define SCALER_ROTMODE_MASK                  0x3
>> +#define SCALER_ROTMODE_SHIFT                 0
>> +
>> +/* SCALER csc coefficients */
>> +#define SCALER_CSC_COEF(x, y)                        (0x220 + ((x * 12) + (y * 4)))
>> +
>> +/* SCALER dither config */
>> +#define SCALER_DITH_CFG                              0x250
>> +#define SCALER_DITHER_R_TYPE_MASK            0x7
>> +#define SCALER_DITHER_R_TYPE_SHIFT           6
>> +#define SCALER_DITHER_G_TYPE_MASK            0x7
>> +#define SCALER_DITHER_G_TYPE_SHIFT           3
>> +#define SCALER_DITHER_B_TYPE_MASK            0x7
>> +#define SCALER_DITHER_B_TYPE_SHIFT           0
>> +
>> +/* SCALER src blend color */
>> +#define SCALER_SRC_BLEND_COLOR                       0x280
>> +#define SCALER_SRC_COLOR_SEL_INV             (1 << 31)
>> +#define SCALER_SRC_COLOR_SEL_MASK            0x3
>> +#define SCALER_SRC_COLOR_SEL_SHIFT           29
>> +#define SCALER_SRC_COLOR_OP_SEL_INV          (1 << 28)
>> +#define SCALER_SRC_COLOR_OP_SEL_MASK         0xf
>> +#define SCALER_SRC_COLOR_OP_SEL_SHIFT                24
>> +#define SCALER_SRC_GLOBAL_COLOR0_MASK                0xff
>> +#define SCALER_SRC_GLOBAL_COLOR0_SHIFT               16
>> +#define SCALER_SRC_GLOBAL_COLOR1_MASK                0xff
>> +#define SCALER_SRC_GLOBAL_COLOR1_SHIFT               8
>> +#define SCALER_SRC_GLOBAL_COLOR2_MASK                0xff
>> +#define SCALER_SRC_GLOBAL_COLOR2_SHIFT               0
>> +
>> +/* SCALER src blend alpha */
>> +#define SCALER_SRC_BLEND_ALPHA                       0x284
>> +#define SCALER_SRC_ALPHA_SEL_INV             (1 << 31)
>> +#define SCALER_SRC_ALPHA_SEL_MASK            0x3
>> +#define SCALER_SRC_ALPHA_SEL_SHIFT           29
>> +#define SCALER_SRC_ALPHA_OP_SEL_INV          (1 << 28)
>> +#define SCALER_SRC_ALPHA_OP_SEL_MASK         0xf
>> +#define SCALER_SRC_ALPHA_OP_SEL_SHIFT                24
>> +#define SCALER_SRC_GLOBAL_ALPHA_MASK         0xff
>> +#define SCALER_SRC_GLOBAL_ALPHA_SHIFT                0
>> +
>> +/* SCALER dst blend color */
>> +#define SCALER_DST_BLEND_COLOR                       0x288
>> +#define SCALER_DST_COLOR_SEL_INV             (1 << 31)
>> +#define SCALER_DST_COLOR_SEL_MASK            0x3
>> +#define SCALER_DST_COLOR_SEL_SHIFT           29
>> +#define SCALER_DST_COLOR_OP_SEL_INV          (1 << 28)
>> +#define SCALER_DST_COLOR_OP_SEL_MASK         0xf
>> +#define SCALER_DST_COLOR_OP_SEL_SHIFT                24
>> +#define SCALER_DST_GLOBAL_COLOR0_MASK                0xff
>> +#define SCALER_DST_GLOBAL_COLOR0_SHIFT               16
>> +#define SCALER_DST_GLOBAL_COLOR1_MASK                0xff
>> +#define SCALER_DST_GLOBAL_COLOR1_SHIFT               8
>> +#define SCALER_DST_GLOBAL_COLOR2_MASK                0xff
>> +#define SCALER_DST_GLOBAL_COLOR2_SHIFT               0
>> +
>> +/* SCALER dst blend alpha */
>> +#define SCALER_DST_BLEND_ALPHA                       0x28c
>> +#define SCALER_DST_ALPHA_SEL_INV             (1 << 31)
>> +#define SCALER_DST_ALPHA_SEL_MASK            0x3
>> +#define SCALER_DST_ALPHA_SEL_SHIFT           29
>> +#define SCALER_DST_ALPHA_OP_SEL_INV          (1 << 28)
>> +#define SCALER_DST_ALPHA_OP_SEL_MASK         0xf
>> +#define SCALER_DST_ALPHA_OP_SEL_SHIFT                24
>> +#define SCALER_DST_GLOBAL_ALPHA_MASK         0xff
>> +#define SCALER_DST_GLOBAL_ALPHA_SHIFT                0
>> +
>> +/* SCALER fill color */
>> +#define SCALER_FILL_COLOR                    0x290
>> +#define SCALER_FILL_ALPHA_MASK                       0xff
>> +#define SCALER_FILL_ALPHA_SHIFT                      24
>> +#define SCALER_FILL_COLOR0_MASK                      0xff
>> +#define SCALER_FILL_COLOR0_SHIFT             16
>> +#define SCALER_FILL_COLOR1_MASK                      0xff
>> +#define SCALER_FILL_COLOR1_SHIFT             8
>> +#define SCALER_FILL_COLOR2_MASK                      0xff
>> +#define SCALER_FILL_COLOR2_SHIFT             0
>> +
>> +/* SCALER address queue config */
>> +#define SCALER_ADDR_QUEUE_CONFIG             0x2a0
>> +#define SCALER_ADDR_QUEUE_RST                        0x1
>> +
>> +/* Arbitrary R/W register and value to check if soft reset succeeded */
>> +#define SCALER_CFG_SOFT_RESET_CHECK_REG              SCALER_SRC_CFG
>> +#define SCALER_CFG_SOFT_RESET_CHECK_VAL              0x3
>> +
>> +struct scaler_error {
>> +     u32 irq_num;
>> +     const char * const name;
>> +};
>> +
>> +static const struct scaler_error scaler_errors[] = {
>> +     {SCALER_INT_TIMEOUT,                    "Timeout"},
>> +     {SCALER_INT_ILLEGAL_BLEND,              "Illegal Blend setting"},
>> +     {SCALER_INT_ILLEGAL_RATIO,              "Illegal Scale ratio setting"},
>> +     {SCALER_INT_ILLEGAL_DST_HEIGHT,         "Illegal Dst Height"},
>> +     {SCALER_INT_ILLEGAL_DST_WIDTH,          "Illegal Dst Width"},
>> +     {SCALER_INT_ILLEGAL_DST_V_POS,          "Illegal Dst V-Pos"},
>> +     {SCALER_INT_ILLEGAL_DST_H_POS,          "Illegal Dst H-Pos"},
>> +     {SCALER_INT_ILLEGAL_DST_C_SPAN,         "Illegal Dst C-Span"},
>> +     {SCALER_INT_ILLEGAL_DST_Y_SPAN,         "Illegal Dst Y-span"},
>> +     {SCALER_INT_ILLEGAL_DST_CR_BASE,        "Illegal Dst Cr-base"},
>> +     {SCALER_INT_ILLEGAL_DST_CB_BASE,        "Illegal Dst Cb-base"},
>> +     {SCALER_INT_ILLEGAL_DST_Y_BASE,         "Illegal Dst Y-base"},
>> +     {SCALER_INT_ILLEGAL_DST_COLOR,          "Illegal Dst Color"},
>> +     {SCALER_INT_ILLEGAL_SRC_HEIGHT,         "Illegal Src Height"},
>> +     {SCALER_INT_ILLEGAL_SRC_WIDTH,          "Illegal Src Width"},
>> +     {SCALER_INT_ILLEGAL_SRC_CV_POS,         "Illegal Src Chroma V-pos"},
>> +     {SCALER_INT_ILLEGAL_SRC_CH_POS,         "Illegal Src Chroma H-pos"},
>> +     {SCALER_INT_ILLEGAL_SRC_YV_POS,         "Illegal Src Luma V-pos"},
>> +     {SCALER_INT_ILLEGAL_SRC_YH_POS,         "Illegal Src Luma H-pos"},
>> +     {SCALER_INT_ILLEGAL_SRC_C_SPAN,         "Illegal Src C-span"},
>> +     {SCALER_INT_ILLEGAL_SRC_Y_SPAN,         "Illegal Src Y-span"},
>> +     {SCALER_INT_ILLEGAL_SRC_CR_BASE,        "Illegal Src Cr-base"},
>> +     {SCALER_INT_ILLEGAL_SRC_CB_BASE,        "Illegal Src Cb-base"},
>> +     {SCALER_INT_ILLEGAL_SRC_Y_BASE,         "Illegal Src Y-base"},
>> +     {SCALER_INT_ILLEGAL_SRC_COLOR,          "Illegal Src Color setting"},
>> +};
>> +
>> +#define SCALER_NUM_ERRORS    ARRAY_SIZE(scaler_errors)
>> +
>> +static inline u32 scaler_read(struct scaler_dev *dev, u32 offset)
>> +{
>> +     return readl(dev->regs + offset);
>> +}
>> +
>> +static inline void scaler_write(struct scaler_dev *dev, u32 offset, u32 value)
>> +{
>> +     writel(value, dev->regs + offset);
>> +}
>> +
>> +static inline void scaler_hw_address_queue_reset(struct scaler_ctx *ctx)
>> +{
>> +     scaler_write(ctx->scaler_dev, SCALER_ADDR_QUEUE_CONFIG,
>> +                                     SCALER_ADDR_QUEUE_RST);
>> +}
>> +
>> +void scaler_hw_set_sw_reset(struct scaler_dev *dev);
>> +int scaler_wait_reset(struct scaler_dev *dev);
>> +void scaler_hw_set_irq(struct scaler_dev *dev, int interrupt, bool mask);
>> +void scaler_hw_set_input_addr(struct scaler_dev *dev, struct scaler_addr *addr);
>> +void scaler_hw_set_output_addr(struct scaler_dev *dev,
>> +                             struct scaler_addr *addr);
>> +void scaler_hw_set_in_size(struct scaler_ctx *ctx);
>> +void scaler_hw_set_in_image_format(struct scaler_ctx *ctx);
>> +void scaler_hw_set_out_size(struct scaler_ctx *ctx);
>> +void scaler_hw_set_out_image_format(struct scaler_ctx *ctx);
>> +void scaler_hw_set_scaler_ratio(struct scaler_ctx *ctx);
>> +void scaler_hw_set_rotation(struct scaler_ctx *ctx);
>> +void scaler_hw_set_csc_coeff(struct scaler_ctx *ctx);
>> +void scaler_hw_src_y_offset_en(struct scaler_dev *dev, bool on);
>> +void scaler_hw_dst_y_offset_en(struct scaler_dev *dev, bool on);
>> +void scaler_hw_enable_control(struct scaler_dev *dev, bool on);
>> +unsigned int scaler_hw_get_irq_status(struct scaler_dev *dev);
>> +void scaler_hw_clear_irq(struct scaler_dev *dev, unsigned int irq);
>> +
>> +#endif /* REGS_SCALER_H_ */
>
>
> --
>
> Cheers,
> Mauro
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux