Re: [PATCH 3/9] dm355 ccdc module for vpfe capture driver

2009-06-18 Thread Laurent Pinchart
Hi,

sorry not to have answered sooner.

On Tuesday 09 June 2009 00:05:10 Karicheri, Muralidharan wrote:
   +
   +/* register access routines */
   +static inline u32 regr(u32 offset)
   +{
   + if (offset = ccdc_addr_size)
 
  This should be .
 
   + return __raw_readl(ccdc_base_addr + offset);
   + else {
   + dev_err(dev, offset exceeds ccdc register address space\n);
   + return -1;
   + }
   +}
   +
   +static inline u32 regw(u32 val, u32 offset)
   +{
   + if (offset = ccdc_addr_size) {
 
  This should be .

 [MK] I removed above two checks since we are getting the required IO block
 mapped and this check is not needed. if some reason there is an offset
 outside the valid range, it is a bug and will be caught through oops,
 right?.

Not necessarily. I'm not sure how ioremap works exactly, but accessing data 
outside the remapped region might end up being a valid access. Anyway this 
shouldn't happen unless a bug creeps in the driver. If you want to validate 
the size it should be done in ccdc_set_ccdc_base instead, but that's not 
really required.

   + __raw_writel(val, ccdc_base_addr + offset);
   + return val;
   + } else {
   + dev_err(dev, offset exceeds ccdc register address space\n);
   + return -1;
   + }
   +}
 
  Can't you check that ccdc_addr_size is big enough in ccdc_set_ccdc_base ?
  The read/write access functions could then be made much simpler.

 [MK] See above comment

   + }
   +
   + switch (ctrl-id) {
   + case CCDC_CID_R_GAIN:
   + gain-r_ye = ctrl-value  CCDC_GAIN_MASK;
   + break;
   + case CCDC_CID_GR_GAIN:
   + gain-gr_cy = ctrl-value  CCDC_GAIN_MASK;
   + break;
   + case CCDC_CID_GB_GAIN:
   + gain-gb_g = ctrl-value   CCDC_GAIN_MASK;
   + break;
   +
   + case CCDC_CID_B_GAIN:
   + gain-b_mg = ctrl-value   CCDC_GAIN_MASK;
   + break;
 
   case CCDC_CID_OFFSET: ?
 
   + default:
   + ccdc_hw_params_raw.ccdc_offset = ctrl-value 
   CCDC_OFFSET_MASK;

 [MK] default is for offset. We are validating the ids above for any of the
 checked values in the switch statement

If you're sure that the control ID is one of the above cases, use 
CCDC_CID_OFFSET instead of default, the code will be easier to read.

   +
   +static void ccdc_reset(void)
   +{
   + int i;
   + /* disable CCDC */
   + dev_dbg(dev, \nstarting ccdc_reset...);
   + ccdc_enable(0);
   + /* set all registers to default value */
   + for (i = 0; i = 0x15c; i += 4)
   + regw(0, i);
 
  Ouch ! Not all registers have a 0 default value. Beside, blindly resetting
  all registers sounds hackish. According to the documentation, the proper
  way to reset the VPFE/VPSS is through the power  sleep controller.

 [MK] This function actually write default values in the registers since the
 implementation assume this. So I have renamed it as ccdc_restore_defaults().
 We don't want to reset the ccdc here, only want to write default values.

Some registers have a non-0 default value according to the datasheet.

   +/*
   + *  ccdc_setwin  
   + *
   + * This function will configure the window size to
   + * be capture in CCDC reg
   + */
   +static void ccdc_setwin(struct ccdc_imgwin *image_win,
   + enum ccdc_frmfmt frm_fmt, int ppc)
 
  What's does ppc stand for ?

 [MK] per pixel count. I documented this.

   +{
   + int horz_start, horz_nr_pixels;
 
  Does horz_nr_pixels really store the number of pixels ? It seems to me it
  counts the number of bytes. hstart and hsize would then be more
  appropriate names.

 [MK]. It is storing number of pixels and the documentation say so. So names
 used are fine as per hw spec.

Then I'm puzzled by

horz_start = image_win-left  (ppc - 1);

image_win-left is a number of pixels. Shifting it left by 1 in the YUV case 
will give a number of bytes.

   + int vert_start, vert_nr_lines;
 
  If the above comment is correct, this could become vstart and vsize to be
  consistent.

 [MK] No change. See above

   + return 0;
   +}
   +static enum ccdc_buftype ccdc_get_buftype(void)
   +{
   + if (ccdc_if_type == VPFE_RAW_BAYER)
   + return ccdc_hw_params_raw.buf_type;
   + return ccdc_hw_params_ycbcr.buf_type;
   +}
   +
   +static int ccdc_enum_pix(enum vpfe_hw_pix_format *hw_pix, int i)
   +{
   + int ret = -EINVAL;
   + if (ccdc_if_type == VPFE_RAW_BAYER) {
   + if (i  CCDC_MAX_RAW_BAYER_FORMATS) {
   + *hw_pix = ccdc_raw_bayer_hw_formats[i];
 
  How does this compare to memcpy in term of code size and run time ?

 [MK] not sure what you are asking here.

I was wondering which of

*hw_pix = ccdc_raw_bayer_hw_formats[i];

and

memcpy(hw_pix, ccdc_raw_bayer_hw_formats[i], sizeof(*hw_pix));

lead to a smaller code size and run time. It's a minor issue, it can always be 
changed later if memcpy is found to be smaller and faster.

   + return 0;
   +}
  
   +#define CCDC_WIN_PAL {0, 0, 720, 

RE: [PATCH 3/9] dm355 ccdc module for vpfe capture driver

2009-06-08 Thread Karicheri, Muralidharan
Laurent,

Laurent,

Thanks for reviewing this. See my response below for few comments. Rest of them 
I have incorporated into my next patch.

Murali Karicheri
Software Design Engineer
Texas Instruments Inc.
Germantown, MD 20874
Phone : 301-515-3736
email: m-kariche...@ti.com
 +
 +/* register access routines */
 +static inline u32 regr(u32 offset)
 +{
 +if (offset = ccdc_addr_size)

This should be .

 +return __raw_readl(ccdc_base_addr + offset);
 +else {
 +dev_err(dev, offset exceeds ccdc register address space\n);
 +return -1;
 +}
 +}
 +
 +static inline u32 regw(u32 val, u32 offset)
 +{
 +if (offset = ccdc_addr_size) {

This should be .
[MK] I removed above two checks since we are getting the required IO block 
mapped and this check is not needed. if some reason there is an offset outside 
the valid range, it is a bug and will be caught through oops, right?.

 +__raw_writel(val, ccdc_base_addr + offset);
 +return val;
 +} else {
 +dev_err(dev, offset exceeds ccdc register address space\n);
 +return -1;
 +}
 +}

Can't you check that ccdc_addr_size is big enough in ccdc_set_ccdc_base ?
The
read/write access functions could then be made much simpler.

[MK] See above comment
 +
 +
 +/* Query control. Only applicable for Bayer capture */
 +static int ccdc_queryctrl(struct v4l2_queryctrl *qctrl)
 +{
 +int i, id;
 +struct v4l2_queryctrl *control = NULL;
 +
 +dev_dbg(dev, ccdc_queryctrl: start\n);
 +if (NULL == qctrl) {

Can this happen ?

[MK] No. removed
 +dev_err(dev, ccdc_queryctrl : invalid user ptr\n);
 +return -EINVAL;
 +}
 +
 +if (VPFE_RAW_BAYER != ccdc_if_type) {
 +dev_err(dev,
 +   ccdc_queryctrl : Not doing Raw Bayer Capture\n);
 +return -EINVAL;
 +}
 +
 +id = qctrl-id;
 +memset(qctrl, 0, sizeof(struct v4l2_queryctrl));
 +for (i = 0; i  CCDC_MAX_CONTROLS; i++) {
 +control = ccdc_control_info[i];
 +if (control-id == id)
 +break;
 +}
 +if (i == CCDC_MAX_CONTROLS) {
 +if (NULL == ctrl) {
 +dev_err(dev, ccdc_setcontrol: invalid user ptr\n);
 +return -EINVAL;
 +}
 +
 +if (ccdc_if_type != VPFE_RAW_BAYER) {
 +dev_err(dev,
 +   ccdc_setcontrol: Not doing Raw Bayer Capture\n);

Should user-triggered errors use dev_err or dev_dbg ? I'm not sure we want
to
fill the kernel log with KERN_ERR message just because an application
doesn't
get its control ids right.

[MK] changed to dev_dbg

 +}
 +
 +switch (ctrl-id) {
 +case CCDC_CID_R_GAIN:
 +gain-r_ye = ctrl-value  CCDC_GAIN_MASK;
 +break;
 +case CCDC_CID_GR_GAIN:
 +gain-gr_cy = ctrl-value  CCDC_GAIN_MASK;
 +break;
 +case CCDC_CID_GB_GAIN:
 +gain-gb_g = ctrl-value   CCDC_GAIN_MASK;
 +break;
 +
 +case CCDC_CID_B_GAIN:
 +gain-b_mg = ctrl-value   CCDC_GAIN_MASK;
 +break;

   case CCDC_CID_OFFSET: ?

 +default:
 +ccdc_hw_params_raw.ccdc_offset = ctrl-value 
CCDC_OFFSET_MASK;
[MK] default is for offset. We are validating the ids above for any of the 
checked values in the switch statement
 +
 +static void ccdc_reset(void)
 +{
 +int i;
 +/* disable CCDC */
 +dev_dbg(dev, \nstarting ccdc_reset...);
 +ccdc_enable(0);
 +/* set all registers to default value */
 +for (i = 0; i = 0x15c; i += 4)
 +regw(0, i);

Ouch ! Not all registers have a 0 default value. Beside, blindly resetting
all
registers sounds hackish. According to the documentation, the proper way to
reset the VPFE/VPSS is through the power  sleep controller.

[MK] This function actually write default values in the registers since the 
implementation assume this. So I have renamed it as ccdc_restore_defaults(). We 
don't want to reset the ccdc here, only want to write default values.
 +/* no culling support */
 +regw(0x, CULH);
 +regw(0xff, CULV);
 +/* Set default Gain and Offset */
 +ccdc_hw_params_raw.gain.r_ye = 256;
 +ccdc_hw_params_raw.gain.gb_g = 256;
 +ccdc_hw_params_raw.gain.gr_cy = 256;
 +ccdc_hw_params_raw.gain.b_mg = 256;
 +ccdc_hw_params_raw.ccdc_offset = 0;
 +ccdc_config_gain_offset();
 +/* up to 12 bit sensor */
 +regw(0x0FFF, OUTCLIP);
 +/* CCDC input Mux select directly from sensor */
 +regw_bl(0x00, CCDCMUX);
 +dev_dbg(dev, \nEnd of ccdc_reset...);
 +}
 +
 +static int ccdc_open(struct device *device)
 +{
 +dev = device;
 +ccdc_reset();
 +return 0;
 +}
 +
 +static int ccdc_close(struct device *device)
 +{
 +/* do nothing for now */
 +return 0;
 +}
 +/*
 + *  ccdc_setwin  
 + *
 + * This function will configure the window size to
 + * be capture in CCDC reg
 + */
 +static void ccdc_setwin(struct ccdc_imgwin 

Re: [PATCH 3/9] dm355 ccdc module for vpfe capture driver

2009-06-04 Thread Laurent Pinchart
Hi,

On Tuesday 02 June 2009 02:12:41 Kevin Hilman wrote:
 Karicheri, Muralidharan m-kariche...@ti.com writes:
  Thanks for reviewing this. I have not gone through all of your comments,
  but would like to respond to the following one first. I will respond to
  the rest as I do the rework.
 
   I've had a quick look at the DM355 and DM6446 datasheets. The CCDC and
   VPSS registers share the same memory block. Can't you use a single
   resource ?
  
   One nice (and better in my opinion) solution would be to declare a
   structure with all the VPSS/CCDC registers as they are implemented in
   hardware and access the structure fields with __raw_read/write*. You
   would then store a single pointer only. Check
   arch/powerpc/include/asm/immap_cpm2.h for an example.
 
  I think, a better solution will be to move the vpss system module
  part to the board specific file dm355.c or dm6446.c

 Just to clarify, the files you mention are SoC specific files, not
 board-specific files...

  and export functions to configure them as needed by the different
  drivers.

 My first reaction to this is... no.  I'm reluctant to have a bunch of
 driver specific hooks in the core davinci SoC specific code.  I'd much
 rather see this stuff kept along with the driver in drivers/media/*
 and abstracted as necessary there.

I agree with Kevin on this. arch/* is mostly meant for platform-specific 
infrastructure code. Device drivers should go in drivers/*. The 
VPSS/VPFE/CCDC/... abstraction should live in drivers/media/video/*. SoC-
specific code that can be shared between multiple drivers (I remember we 
discussed IRQ routing for instance) can go in arch/*.

  The vpss has evolved quite a lot from DM6446 to DM355 to
  DM365. Registers such as INTSEL and INTSTAT and others are
  applicable to other modules as well, not just the ccdc module. The
  VPBE and resizer drivers will need to configure them too. Also the
  vpss system module features available in DM365 is much more than
  that in DM355.

The VPBE and resizer modules will live in drivers/media/video/* as well 
(correct me if I'm wrong), so most abstraction can go there. INTSEL and 
INTSTAT could be handled in arch/*, but they're located in the ISP registers 
block, so I suppose they're only applicable to video-related modules.

 Based on this, it sounds to me that this driver needs to be broken up
 a little bit more and some of the shared pieces need to be abstracted
 out so they can be shared among the modules.

  Interrupts line to ARM are programmable in DM365 vpss and multiple
  vpss irq lines can be muxed to the ARM side. So I would imaging
  functions enable/disable irq line to arm, clearing irq bits,
  enabling various clocks etc can be done in a specific soc specific
  file (dm355.c, dm365.c or dm6446.c) and can be exported for use in
  specific drivers. I just want to get your feedback so that I can
  make this change. With this change, there is no need to use
  structures for holding register offsets as you have suggested.

I agree with that. Interrupt handling, clock routing and other SoC-specific 
infrastructure code that isn't module-dependent should live in arch/*.

Best regards,

Laurent Pinchart

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 3/9] dm355 ccdc module for vpfe capture driver

2009-06-04 Thread Karicheri, Muralidharan

 My first reaction to this is... no.  I'm reluctant to have a bunch of
 driver specific hooks in the core davinci SoC specific code.  I'd much
 rather see this stuff kept along with the driver in drivers/media/*
 and abstracted as necessary there.

I agree with Kevin on this. arch/* is mostly meant for platform-specific
infrastructure code. Device drivers should go in drivers/*. The
VPSS/VPFE/CCDC/... abstraction should live in drivers/media/video/*. SoC-
specific code that can be shared between multiple drivers (I remember we
discussed IRQ routing for instance) can go in arch/*.

[MK] yes. As per your definition vpss module registers are shared across all 
video drivers. So it appears it has to go in arch/*. But I am now more inclined 
to write a platform driver for vpss that live inside media/video/davinci/ and 
shall export a bunch of library functions shared across drivers. I will make 
this change and will send it as part of v2 version of the patch series...

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [PATCH 3/9] dm355 ccdc module for vpfe capture driver

2009-06-01 Thread Karicheri, Muralidharan
Laurent,

Thanks for reviewing this. I have not gone through all of your comments, but 
would like to respond to the following one first. I will respond to the rest as 
I do the rework.

I've had a quick look at the DM355 and DM6446 datasheets. The CCDC and VPSS
registers share the same memory block. Can't you use a single resource ?

One nice (and better in my opinion) solution would be to declare a
structure
with all the VPSS/CCDC registers as they are implemented in hardware and
access the structure fields with __raw_read/write*. You would then store a
single pointer only. Check arch/powerpc/include/asm/immap_cpm2.h for an
example.

I think, a better solution will be to move the vpss system module part to the 
board specific file dm355.c or dm6446.c and export functions to configure them 
as needed by the different drivers. The vpss has evolved quite a lot from 
DM6446 to DM355 to DM365. Registers such as INTSEL and INTSTAT and others are 
applicable to other modules as well, not just the ccdc module. The VPBE and 
resizer drivers will need to configure them too. Also the vpss system module 
features available in DM365 is much more than that in DM355. Interrupts line to 
ARM are programmable in DM365 vpss and multiple vpss irq lines can be muxed to 
the ARM side. So I would imaging functions enable/disable irq line to arm, 
clearing irq bits, enabling various clocks etc can be done in a specific soc 
specific file (dm355.c, dm365.c or dm6446.c) and can be exported for use in 
specific drivers. I just want to get your feedback so that I can make this 
change. With this change, there is no need to use structures for holding 
register offsets as you have suggested.
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/9] dm355 ccdc module for vpfe capture driver

2009-06-01 Thread Kevin Hilman
Karicheri, Muralidharan m-kariche...@ti.com writes:

 Laurent,

 Thanks for reviewing this. I have not gone through all of your comments, but 
 would like to respond to the following one first. I will respond to the rest 
 as I do the rework.

I've had a quick look at the DM355 and DM6446 datasheets. The CCDC and VPSS
registers share the same memory block. Can't you use a single resource ?

One nice (and better in my opinion) solution would be to declare a
structure
with all the VPSS/CCDC registers as they are implemented in hardware and
access the structure fields with __raw_read/write*. You would then store a
single pointer only. Check arch/powerpc/include/asm/immap_cpm2.h for an
example.

 I think, a better solution will be to move the vpss system module
 part to the board specific file dm355.c or dm6446.c 

Just to clarify, the files you mention are SoC specific files, not
board-specific files...

 and export functions to configure them as needed by the different
 drivers.

My first reaction to this is... no.  I'm reluctant to have a bunch of
driver specific hooks in the core davinci SoC specific code.  I'd much
rather see this stuff kept along with the driver in drivers/media/*
and abstracted as necessary there.

 The vpss has evolved quite a lot from DM6446 to DM355 to
 DM365. Registers such as INTSEL and INTSTAT and others are
 applicable to other modules as well, not just the ccdc module. The
 VPBE and resizer drivers will need to configure them too. Also the
 vpss system module features available in DM365 is much more than
 that in DM355. 

Based on this, it sounds to me that this driver needs to be broken up
a little bit more and some of the shared pieces need to be abstracted
out so they can be shared among the modules.

 Interrupts line to ARM are programmable in DM365 vpss and multiple
 vpss irq lines can be muxed to the ARM side. So I would imaging
 functions enable/disable irq line to arm, clearing irq bits,
 enabling various clocks etc can be done in a specific soc specific
 file (dm355.c, dm365.c or dm6446.c) and can be exported for use in
 specific drivers. I just want to get your feedback so that I can
 make this change. With this change, there is no need to use
 structures for holding register offsets as you have suggested.

Kevin

--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/9] dm355 ccdc module for vpfe capture driver

2009-05-28 Thread Hans Verkuil
On Thursday 28 May 2009 15:18:17 Laurent Pinchart wrote:
 Hi,

 most comments here apply to the DM6446 CCDC module as well. Generic
 comments apply throughout the source code.

 Hans, I'd appreciate if you could review my comments, as some of them
 might made according to personal preferences more than best practice
 rules.

I did a quick review of your review :-) and it looks fine to me!

Regards,

Hans

-- 
Hans Verkuil - video4linux developer - sponsored by TANDBERG Telecom
--
To unsubscribe from this list: send the line unsubscribe linux-media in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html