From: Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
To: Andrey Gusakov <dron0gus@gmail.com>
Cc: "Sylwester Nawrocki" <sylvester.nawrocki@gmail.com>,
"Tomasz Figa" <tomasz.figa@gmail.com>,
"In-Bae Jeong" <kukyakya@gmail.com>,
"Heiko Stübner" <heiko@sntech.de>,
LMML <linux-media@vger.kernel.org>,
linux-samsung-soc <linux-samsung-soc@vger.kernel.org>
Subject: Re: S3C244X/S3C64XX SoC camera host interface driver questions
Date: Fri, 09 Nov 2012 09:14:25 +0100 [thread overview]
Message-ID: <509CBB61.40206@gmail.com> (raw)
In-Reply-To: <CAA11ShCn3S_nxXg5_pAsgcMsPFpER7XrHsvg71DrznAmONu7Lg@mail.gmail.com>
Hi,
On 11/08/2012 07:47 PM, Andrey Gusakov wrote:
>> Ok, thanks. I will add the missing CONFIG_PM_RUNTIME dependency in Kconfig.
>> The driver has to have PM_RUNTIME enabled since on s3c64xx SoCs there are
>> power domains and the camera power domain needs to be enabled for the CAMIF
>> operation. The pm_runtime_* calls in the driver are supposed to ensure that.
>> I wonder why it works for you without PM_RUNTIME, i.e. how comes the power
>> domain is enabled. It is supposed to be off by default.
> DS says that all power domaint are on after reset. My bootloader did
> not switch then off. So when linux start everything is on.
> CONFIG_PM_RUNTIME was disabled, so nothing switch them off in linux
> too.
Yes, indeed. But there was a PM code added that is supposed to disable all
unused power domains on the system boot. I noticed that one needs to call
explicitly s3c64xx_pm_init() function from machine_init() callback within
the board file. So far this function is called only in mach-crag6410.c.
I'm not sure it it won't kill the display if you use it though. Probably
PM domain state should be read from a respective register and this
information passed to pm_genpd_init() function within s3c64_pm_init().
>>>> I hope to eventually prepare the ov9650 sensor driver for mainline. Your
>>>> help in making it ready for VER=0x52 would be very much appreciated. :-)
>>>
>>> I'll try to helpful.
>>>
>>>
>>>>> Next step is to make ov2460 work.
>>>>
>>>> For now I can only recommend you to make the ov2460 driver more similar
>>>> to the ov9650 one.
>>>
>>> Thanks, I'll try.
>>>
>>> P.S. I add support of image effects just for fun. And found in DS that
>>> s3c2450 also support effects. It's FIMC in-between of 2440 and
>>> 6400/6410. Does anyone have s3c2450 hardware to test it?
>
>> Patches adding image effect are welcome. I'm bit to busy to play with these
>> things, other than I don't have hardware to test it.
>> I wasn't really aware of CAMIF in s3c2450. I think a separate variant data
>> structure would need to be defined for s3c2450. If anyone ever needs it
>> it could be added easily. For now I'll pretend this version doesn't exist.
>> :-)
> Attached.
>
> I often get "VIDIOC_QUERYCAP: failed: Inappropriate ioctl for device"
This is an issue in the v4l2-ctl, it is going to be fixed by adding
VIDIOC_SUBDEV_QUERYCAP ioctl for subdevs. It has been just discussed today.
I guess you get it when running v4l2-ctl on /dev/v4l-subdev* ?
> or "system error: Inappropriate ioctl for device"
I think this one is caused by unimplemented VIDIOC_G/S_PARM ioctls
at the s3c-camif driver.
> Is it because of not implemented set/get framerate func? How this
Yes, I think so. ioctls as above.
> should work? I mean framerate heavy depend of sensor's settings. So
> set/get framerate call to fimc should get/set framerate from sensor.
> What is mechanism of such things?
With user space subdev API one should control frame interval directly
on the sensor subdev device node [1]. For Gstreamer to work with
VIDIOC_G/S_PARM ioctls we need a dedicated v4l2 library (possibly with
a plugin for s3c-camif, but that shouldn't be needed since it is very
simple driver) that will translate those video node ioctls into the
subdev node ioctls [2]. Unfortunately such library is still not available.
> And same question about synchronizing format of sensor and FIMC pads.
> I make ov2640 work, but if did not call media-ctl for sensor, format
> of FIMC sink pad and format of sensor source pad different. I think I
> missed something, but reading other sources did not help.
As I explained previously, s3c-fimc is supposed to synchronize format
with the sensor subdev. Have you got pad level get_fmt callback
implemented in the ov2640 driver ?
Could you post your 'media-ctl -p' output, run right after the system boot ?
[1]
http://linuxtv.org/downloads/v4l-dvb-apis/vidioc-subdev-g-frame-interval.html
[2] http://git.linuxtv.org/v4l-utils.git/tree/
-----------------------------------------------------------------------------
From 04b88737f65f772f8b375234a92c7cdd481eac1b Mon Sep 17 00:00:00 2001
From: Andrey Gusakov <dron_gus@mail.ru>
Date: Mon, 5 Nov 2012 15:50:23 +0400
Subject: [PATCH] S3C-FIMC: add effect controls
SN:
I prefer using s3c-camif name, FIMC appears only in later version of
the SoCs. Also would be nice to put at least some brief description why
this patch is needed.
Signed-off-by: Andrey Gusakov <dron_gus@mail.ru>
---
drivers/media/platform/s3c-camif/camif-capture.c | 58
++++++++++++++++++++--
drivers/media/platform/s3c-camif/camif-core.h | 5 ++
drivers/media/platform/s3c-camif/camif-regs.c | 38 ++++++++++----
drivers/media/platform/s3c-camif/camif-regs.h | 6 ++-
4 files changed, 89 insertions(+), 18 deletions(-)
diff --git a/drivers/media/platform/s3c-camif/camif-capture.c
b/drivers/media/platform/s3c-camif/camif-capture.c
index ca31c45..046ebf6 100644
--- a/drivers/media/platform/s3c-camif/camif-capture.c
+++ b/drivers/media/platform/s3c-camif/camif-capture.c
@@ -81,6 +81,9 @@ static int s3c_camif_hw_init(struct camif_dev *camif,
struct camif_vp *vp)
camif_hw_set_source_format(camif);
camif_hw_set_camera_crop(camif);
camif_hw_set_test_pattern(camif, camif->test_pattern->val);
+ if (ip_rev >= S3C2450_CAMIF_IP_REV)
+ camif_hw_set_effect(camif, camif->effect->val,
+ camif->effect_cr->val, camif->effect_cb->val);
if (ip_rev == S3C6410_CAMIF_IP_REV)
camif_hw_set_input_path(vp);
camif_cfg_video_path(vp);
@@ -108,8 +111,8 @@ static int s3c_camif_hw_vp_init(struct camif_dev
*camif, struct camif_vp *vp)
if (ip_rev == S3C244X_CAMIF_IP_REV)
camif_hw_clear_fifo_overflow(vp);
camif_cfg_video_path(vp);
- if (ip_rev == S3C6410_CAMIF_IP_REV)
- camif_hw_set_effect(vp, false);
+ if (ip_rev >= S3C2450_CAMIF_IP_REV)
+ camif_hw_set_effect(camif, 0, 0, 0);
vp->state &= ~ST_VP_CONFIG;
spin_unlock_irqrestore(&camif->slock, flags);
@@ -374,6 +377,10 @@ irqreturn_t s3c_camif_irq_handler(int irq, void *priv)
camif_hw_set_scaler(vp);
camif_hw_set_flip(vp);
camif_hw_set_test_pattern(camif, camif->test_pattern->val);
+ if (ip_rev >= S3C2450_CAMIF_IP_REV)
+ camif_hw_set_effect(camif, camif->effect->val,
+ camif->effect_cr->val,
+ camif->effect_cb->val);
vp->state &= ~ST_VP_CONFIG;
}
unlock:
@@ -1530,7 +1537,7 @@ static const struct v4l2_ctrl_ops
s3c_camif_subdev_ctrl_ops = {
.s_ctrl = s3c_camif_subdev_s_ctrl,
};
-static const struct v4l2_ctrl_config s3c_camif_priv_ctrl = {
+static const struct v4l2_ctrl_config s3c_camif_priv_ctrl_test = {
.ops = &s3c_camif_subdev_ctrl_ops,
.id = V4L2_CTRL_CLASS_USER | 0x1001,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -1541,6 +1548,39 @@ static const struct v4l2_ctrl_config
s3c_camif_priv_ctrl = {
.def = 0,
};
+static const struct v4l2_ctrl_config s3c_camif_priv_ctrl_eff = {
+ .ops = &s3c_camif_subdev_ctrl_ops,
+ .id = V4L2_CTRL_CLASS_USER | 0x1002,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Effect",
+ .min = 0,
+ .max = 5,
+ .step = 1,
+ .def = 0,
+};
+
+static const struct v4l2_ctrl_config s3c_camif_priv_ctrl_eff_cb = {
+ .ops = &s3c_camif_subdev_ctrl_ops,
+ .id = V4L2_CTRL_CLASS_USER | 0x1003,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "PAT_Cb",
+ .min = 16,
+ .max = 240,
+ .step = 1,
+ .def = 128,
+};
+
+static const struct v4l2_ctrl_config s3c_camif_priv_ctrl_eff_cr = {
+ .ops = &s3c_camif_subdev_ctrl_ops,
+ .id = V4L2_CTRL_CLASS_USER | 0x1004,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "PAT_Cr",
+ .min = 16,
+ .max = 240,
+ .step = 1,
+ .def = 128,
+};
SN:
There is no need to create these 3 private controls, we have now standard
controls for this image effect. Can you rework it to use V4L2_CID_COLORFX
and V4L2_CID_COLORFX_CBCR controls ? Not used option of V4L2_CID_COLORFX
can be easily masked off by passing proper mask to v4l2_ctrl_new_std().
Unfortunately the CB/CR coefficients will have fixed min and max values
then - 0, 255. That shouldn't be a big issue though.
AFAICT the range for CB/CR depends on the CSCR2Y_c bit which means:
"YCbCr Data Dynamic Range Selection for the Color Space Conversion RGB
to YCbCr"
CSCR2Y_c 1 : Wide => Y/Cb/Cr (0 ~ 255) : Wide default
0 : Narrow => Y (16 ~ 235), Cb/Cr (16 ~ 240)
By default CSCR2Y_c bit is set so we get 0 ~ 255 range.
int s3c_camif_create_subdev(struct camif_dev *camif)
{
struct v4l2_ctrl_handler *handler = &camif->ctrl_handler;
@@ -1560,10 +1600,18 @@ int s3c_camif_create_subdev(struct camif_dev *camif)
if (ret)
return ret;
- v4l2_ctrl_handler_init(handler, 1);
+ v4l2_ctrl_handler_init(handler, 4);
camif->test_pattern = v4l2_ctrl_new_custom(handler,
- &s3c_camif_priv_ctrl, NULL);
+ &s3c_camif_priv_ctrl_test, NULL);
+ camif->effect = v4l2_ctrl_new_custom(handler,
+ &s3c_camif_priv_ctrl_eff, NULL);
+ camif->effect_cr = v4l2_ctrl_new_custom(handler,
+ &s3c_camif_priv_ctrl_eff_cb, NULL);
+ camif->effect_cb = v4l2_ctrl_new_custom(handlerEffect,
+ &s3c_camif_priv_ctrl_eff_cr, NULL);
+
if (handler->error) {
+ v4l2_ctrl_handler_free(handler);
media_entity_cleanup(&sd->entity);
return handler->error;
}
diff --git a/drivers/media/platform/s3c-camif/camif-core.h
b/drivers/media/platform/s3c-camif/camif-core.h
index 96f5d3d..5f9eb3a 100644
--- a/drivers/media/platform/s3c-camif/camif-core.h
+++ b/drivers/media/platform/s3c-camif/camif-core.h
@@ -39,6 +39,8 @@
#define CAMIF_STOP_TIMEOUT 1500 /* ms */
#define S3C244X_CAMIF_IP_REV 0x20 /* 2.0 */
+#define S3C2450_CAMIF_IP_REV 0x30 /* 3.0 - not implemented, not tested */
+#define S3C6400_CAMIF_IP_REV 0x31 /* 3.1 - not implemented, not tested */
#define S3C6410_CAMIF_IP_REV 0x32 /* 3.2 */
/* struct camif_vp::state */
@@ -277,6 +279,9 @@ struct camif_dev {
struct v4l2_ctrl_handler ctrl_handler;
struct v4l2_ctrl *test_pattern;
+ struct v4l2_ctrl *effect;
+ struct v4l2_ctrl *effect_cb;
+ struct v4l2_ctrl *effect_cr;
As explained above 2 controls can be used instead.
struct camif_vp vp[CAMIF_VP_NUM];
struct vb2_alloc_ctx *alloc_ctx;
diff --git a/drivers/media/platform/s3c-camif/camif-regs.c
b/drivers/media/platform/s3c-camif/camif-regs.c
index d8c55dc..1b03f73 100644
--- a/drivers/media/platform/s3c-camif/camif-regs.c
+++ b/drivers/media/platform/s3c-camif/camif-regs.c
@@ -57,6 +57,33 @@ void camif_hw_set_test_pattern(struct camif_dev
*camif, unsigned int pattern)
camif_write(camif, S3C_CAMIF_REG_CIGCTRL, cfg);
}
+void camif_hw_set_effect(struct camif_dev *camif, unsigned int effect,
+ unsigned int cr, unsigned int cb)
+{
+ u32 cfg;
+
+ if (camif->variant->ip_revision < S3C2450_CAMIF_IP_REV)
+ return;
I think you can remove this check. Since camif_hw_set_effect() is always
called conditionally.
+
+ cfg = camif_read(camif, S3C_CAMIF_REG_CIIMGEFF(camif->vp->offset));
+ /* Set effect */
+ cfg &= ~CIIMGEFF_FIN_MASK;
+ cfg |= (effect << 26);
+ /* Set both paths */
+ if (camif->variant->ip_revision >= S3C6400_CAMIF_IP_REV) {
+ if (effect)
+ cfg |= CIIMGEFF_IE_ENABLE_MASK;
+ else
+ cfg &= ~CIIMGEFF_IE_ENABLE_MASK;
+ }
+ /* Set Cr, Cb */
+ if (effect == CIIMGEFF_FIN_ARBITRARY) {
+ cfg &= ~CIIMGEFF_PAT_CBCR_MASK;
+ cfg |= ((cb & 0xFF) << 13) | (cr & 0xFF);
Can you please use lower case for hex numbers ?
+ }
+ camif_write(camif, S3C_CAMIF_REG_CIIMGEFF(camif->vp->offset), cfg);
+}
+
static const u32 src_pixfmt_map[8][2] = {
{ V4L2_MBUS_FMT_YUYV8_2X8, CISRCFMT_ORDER422_YCBYCR },
{ V4L2_MBUS_FMT_YVYU8_2X8, CISRCFMT_ORDER422_YCRYCB },
@@ -473,17 +500,6 @@ void camif_hw_set_lastirq(struct camif_vp *vp, int
enable)
camif_write(vp->camif, addr, cfg);
}
-void camif_hw_set_effect(struct camif_vp *vp, bool active)
-{
- u32 cfg = 0;
-
- if (active) {
- /* TODO: effects support on 64xx */
- }
-
- camif_write(vp->camif, S3C_CAMIF_REG_CIIMGEFF, cfg);
-}
-
void camif_hw_enable_capture(struct camif_vp *vp)
{
struct camif_dev *camif = vp->camif;
diff --git a/drivers/media/platform/s3c-camif/camif-regs.h
b/drivers/media/platform/s3c-camif/camif-regs.h
index a3488ca..213adbc 100644
--- a/drivers/media/platform/s3c-camif/camif-regs.h
+++ b/drivers/media/platform/s3c-camif/camif-regs.h
@@ -177,8 +177,9 @@
#define S3C_CAMIF_REG_CICPTSEQ 0xc4
/* Image effects */
-#define S3C_CAMIF_REG_CIIMGEFF 0xd0
+#define S3C_CAMIF_REG_CIIMGEFF(_offs) (0xb0 + (_offs))
#define CIIMGEFF_IE_ENABLE(id) (1 << (30 + (id)))
+#define CIIMGEFF_IE_ENABLE_MASK (3 << 30)
/* Image effect: 1 - after scaler, 0 - before scaler */
#define CIIMGEFF_IE_AFTER_SC (1 << 29)
#define CIIMGEFF_FIN_MASK (7 << 26)
@@ -243,7 +244,6 @@ void camif_hw_clear_fifo_overflow(struct camif_vp *vp);
void camif_hw_set_lastirq(struct camif_vp *vp, int enable);
void camif_hw_set_input_path(struct camif_vp *vp);
void camif_hw_enable_scaler(struct camif_vp *vp, bool on);
-void camif_hw_set_effect(struct camif_vp *vp, bool active);
void camif_hw_enable_capture(struct camif_vp *vp);
void camif_hw_disable_capture(struct camif_vp *vp);
void camif_hw_set_camera_bus(struct camif_dev *camif);
@@ -254,6 +254,8 @@ void camif_hw_set_flip(struct camif_vp *vp);
void camif_hw_set_output_dma(struct camif_vp *vp);
void camif_hw_set_target_format(struct camif_vp *vp);
void camif_hw_set_test_pattern(struct camif_dev *camif, unsigned int
pattern);
+void camif_hw_set_effect(struct camif_dev *camif, unsigned int effect,
+ unsigned int cr, unsigned int cb);
void camif_hw_set_output_addr(struct camif_vp *vp, struct camif_addr
*paddr,
int index);
void camif_hw_dump_regs(struct camif_dev *camif, const char *label);
-- 1.7.0.4
Otherwise looks good.
--
Thanks,
Sylwester
next prev parent reply other threads:[~2012-11-09 8:14 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CAA11ShCpH7Z8eLok=MEh4bcSb6XjtVFfLQEYh2icUtYc-j5hEQ@mail.gmail.com>
[not found] ` <5096C561.5000108@gmail.com>
[not found] ` <CAA11ShCKFfdmd_ydxxCYo9Sv0VhgZW9kCk_F7LAQDg3mr5prrw@mail.gmail.com>
2012-11-04 22:14 ` S3C244X/S3C64XX SoC camera host interface driver questions Sylwester Nawrocki
2012-11-04 22:23 ` Tomasz Figa
2012-11-05 9:44 ` Andrey Gusakov
2012-11-05 10:48 ` Sylwester Nawrocki
2012-11-05 11:11 ` Andrey Gusakov
2012-11-05 22:26 ` Sylwester Nawrocki
2012-11-06 21:34 ` Andrey Gusakov
2012-11-07 21:57 ` Sylwester Nawrocki
2012-11-08 18:47 ` Andrey Gusakov
2012-11-09 8:14 ` Sylwester Nawrocki [this message]
2012-11-11 13:26 ` Andrey Gusakov
2012-11-13 22:54 ` Sylwester Nawrocki
2012-11-17 12:07 ` Andrey Gusakov
2012-11-17 17:24 ` Sylwester Nawrocki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=509CBB61.40206@gmail.com \
--to=sylvester.nawrocki@gmail.com \
--cc=dron0gus@gmail.com \
--cc=heiko@sntech.de \
--cc=kukyakya@gmail.com \
--cc=linux-media@vger.kernel.org \
--cc=linux-samsung-soc@vger.kernel.org \
--cc=tomasz.figa@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox