All of lore.kernel.org
 help / color / mirror / Atom feed
* On register r/w macros/procedures of drivers/media/pci
@ 2015-04-19  7:36 Andrey Utkin
  2015-04-19  8:28 ` Hans Verkuil
  2015-04-20 11:18 ` Krzysztof Hałasa
  0 siblings, 2 replies; 7+ messages in thread
From: Andrey Utkin @ 2015-04-19  7:36 UTC (permalink / raw)
  To: Linux Media, kernel-mentors, linux-kernel
  Cc: Hans Verkuil, hans.verkuil, khalasa

I am starting a work on driver for techwell tw5864 media grabber&encoder.
I am basing on tw68 driver (mentorship, advising and testing by board
owners are appreciated). And here (and in some other
drivers/media/pci/ drivers) I see what confuses me:

tw68-core.c:
        dev->lmmio = ioremap(pci_resource_start(pci_dev, 0),
                             pci_resource_len(pci_dev, 0));
        dev->bmmio = (__u8 __iomem *)dev->lmmio;

tw68.h:
#define tw_readl(reg)           readl(dev->lmmio + ((reg) >> 2))
#define tw_readb(reg)           readb(dev->bmmio + (reg))
#define tw_writel(reg, value)   writel((value), dev->lmmio + ((reg) >> 2))
#define tw_writeb(reg, value)   writeb((value), dev->bmmio + (reg))

I am mostly userland developer and I wouldn't expect bmmio pointer to
contain value numerically different from lmmio after such simple
casting.
But still, if this is correct, then how should I implement
tw_{read,write}w to operate on 2 bytes (a word)? Similarly, it would
look like this:
#define tw_readl(reg)           readl(dev->lmmio + ((reg) >> 1))
That looks odd.

In contrary, in drivers/media/pci/dm1105, we see no explicit shifting
of register address. It uses {in,out}{b,w,l} macros, which seem to
turn out the same {read,write}{b,w,l} (with some reservations):
http://lxr.free-electrons.com/source/include/asm-generic/io.h#L354

dm1105.c:#define dm_io_mem(reg) ((unsigned long)(&dev->io_mem[reg]))
dm1105.c:#define dm_readb(reg)          inb(dm_io_mem(reg))
dm1105.c:#define dm_writeb(reg, value)  outb((value), (dm_io_mem(reg)))
dm1105.c:#define dm_readw(reg)          inw(dm_io_mem(reg))
dm1105.c:#define dm_writew(reg, value)  outw((value), (dm_io_mem(reg)))
dm1105.c:#define dm_readl(reg)          inl(dm_io_mem(reg))
dm1105.c:#define dm_writel(reg, value)  outl((value), (dm_io_mem(reg)))

This looks like contradiction to me (shifting register address vs. no
shifting), so that one practice may be even just wrong and broken
(which is hard to believe due to active maintenance of all drivers).
I highly appreciate your help me in determining the best practice to
follow in this new driver.
Thanks.

-- 
Bluecherry developer.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: On register r/w macros/procedures of drivers/media/pci
  2015-04-19  7:36 On register r/w macros/procedures of drivers/media/pci Andrey Utkin
@ 2015-04-19  8:28 ` Hans Verkuil
  2015-04-19  8:55   ` Andrey Utkin
  2015-04-20 11:18 ` Krzysztof Hałasa
  1 sibling, 1 reply; 7+ messages in thread
From: Hans Verkuil @ 2015-04-19  8:28 UTC (permalink / raw)
  To: Andrey Utkin, Linux Media, kernel-mentors, linux-kernel
  Cc: hans.verkuil, khalasa

On 04/19/2015 09:36 AM, Andrey Utkin wrote:
> I am starting a work on driver for techwell tw5864 media grabber&encoder.
> I am basing on tw68 driver (mentorship, advising and testing by board
> owners are appreciated). And here (and in some other
> drivers/media/pci/ drivers) I see what confuses me:
> 
> tw68-core.c:
>         dev->lmmio = ioremap(pci_resource_start(pci_dev, 0),
>                              pci_resource_len(pci_dev, 0));
>         dev->bmmio = (__u8 __iomem *)dev->lmmio;
> 
> tw68.h:
> #define tw_readl(reg)           readl(dev->lmmio + ((reg) >> 2))
> #define tw_readb(reg)           readb(dev->bmmio + (reg))
> #define tw_writel(reg, value)   writel((value), dev->lmmio + ((reg) >> 2))
> #define tw_writeb(reg, value)   writeb((value), dev->bmmio + (reg))
> 
> I am mostly userland developer and I wouldn't expect bmmio pointer to
> contain value numerically different from lmmio after such simple
> casting.

Check the types of llmio and bbmio:

        u32                     __iomem *lmmio;
        u8                      __iomem *bmmio;

So the values of the pointers are the same, but the types are not.

So 'lmmio + 1' == 'bmmio + sizeof(u32)' == 'bbmio + 4'.

Since all the registers are defined as byte offsets relative to the start
of the memory map you cannot just do 'lmmio + reg' since that would be a
factor 4 off. Instead you have to divide by 4 to get it back in line.

Frankly, I don't think lmmio is necessary at all since readl/writel don't
need a u32 pointer at all since they use void pointers. I never noticed
that when I cleaned up the tw68 driver. Using 'void __iomem *mmio' instead
of lmmio/bmmio and dropping the shifts in the tw_ macros would work just
as well.

> But still, if this is correct, then how should I implement
> tw_{read,write}w to operate on 2 bytes (a word)? Similarly, it would
> look like this:
> #define tw_readl(reg)           readl(dev->lmmio + ((reg) >> 1))

As suggested above, just use a single void __iomem *mmio pointer.

> That looks odd.
> 
> In contrary, in drivers/media/pci/dm1105, we see no explicit shifting
> of register address. It uses {in,out}{b,w,l} macros, which seem to
> turn out the same {read,write}{b,w,l} (with some reservations):
> http://lxr.free-electrons.com/source/include/asm-generic/io.h#L354
> 
> dm1105.c:#define dm_io_mem(reg) ((unsigned long)(&dev->io_mem[reg]))
> dm1105.c:#define dm_readb(reg)          inb(dm_io_mem(reg))
> dm1105.c:#define dm_writeb(reg, value)  outb((value), (dm_io_mem(reg)))
> dm1105.c:#define dm_readw(reg)          inw(dm_io_mem(reg))
> dm1105.c:#define dm_writew(reg, value)  outw((value), (dm_io_mem(reg)))
> dm1105.c:#define dm_readl(reg)          inl(dm_io_mem(reg))
> dm1105.c:#define dm_writel(reg, value)  outl((value), (dm_io_mem(reg)))
> 
> This looks like contradiction to me (shifting register address vs. no
> shifting), so that one practice may be even just wrong and broken
> (which is hard to believe due to active maintenance of all drivers).
> I highly appreciate your help me in determining the best practice to
> follow in this new driver.
> Thanks.
> 

Hope this helps,

	Hans

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: On register r/w macros/procedures of drivers/media/pci
  2015-04-19  8:28 ` Hans Verkuil
@ 2015-04-19  8:55   ` Andrey Utkin
  0 siblings, 0 replies; 7+ messages in thread
From: Andrey Utkin @ 2015-04-19  8:55 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Linux Media, kernel-mentors, linux-kernel, hans.verkuil, khalasa

On Sun, Apr 19, 2015 at 11:28 AM, Hans Verkuil <hverkuil@xs4all.nl> wrote:
> Check the types of llmio and bbmio:
>
>         u32                     __iomem *lmmio;
>         u8                      __iomem *bmmio;
>
> So the values of the pointers are the same, but the types are not.
>
> So 'lmmio + 1' == 'bmmio + sizeof(u32)' == 'bbmio + 4'.
>
> Since all the registers are defined as byte offsets relative to the start
> of the memory map you cannot just do 'lmmio + reg' since that would be a
> factor 4 off. Instead you have to divide by 4 to get it back in line.
>
> Frankly, I don't think lmmio is necessary at all since readl/writel don't
> need a u32 pointer at all since they use void pointers. I never noticed
> that when I cleaned up the tw68 driver. Using 'void __iomem *mmio' instead
> of lmmio/bmmio and dropping the shifts in the tw_ macros would work just
> as well.

>
> Hope this helps,

Oh, indeed, I have forgot this basic thing of pointer arithmetics.
Thanks a lot for elaboration and the proposed solution.

-- 
Bluecherry developer.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: On register r/w macros/procedures of drivers/media/pci
  2015-04-19  7:36 On register r/w macros/procedures of drivers/media/pci Andrey Utkin
  2015-04-19  8:28 ` Hans Verkuil
@ 2015-04-20 11:18 ` Krzysztof Hałasa
  2015-04-20 11:20   ` Andrey Utkin
  1 sibling, 1 reply; 7+ messages in thread
From: Krzysztof Hałasa @ 2015-04-20 11:18 UTC (permalink / raw)
  To: Andrey Utkin
  Cc: Linux Media, kernel-mentors, linux-kernel, Hans Verkuil, hans.verkuil

Andrey Utkin <andrey.utkin@corp.bluecherry.net> writes:

> I am starting a work on driver for techwell tw5864 media grabber&encoder.

If this is tw6864 then I have a driver mostly completed.
Actually I'm using tw6869 but I think this is very similar (4 channels
instead of 8 and PCI instead of PCIe). I have 6864s but haven't yet
tried using them for trivial reasons.

This is BTW completely different chip (family) than the old tw68x.
-- 
Krzysztof Halasa

Research Institute for Automation and Measurements PIAP
Al. Jerozolimskie 202, 02-486 Warsaw, Poland

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: On register r/w macros/procedures of drivers/media/pci
  2015-04-20 11:18 ` Krzysztof Hałasa
@ 2015-04-20 11:20   ` Andrey Utkin
  2015-04-20 12:45     ` Krzysztof Hałasa
  0 siblings, 1 reply; 7+ messages in thread
From: Andrey Utkin @ 2015-04-20 11:20 UTC (permalink / raw)
  To: Krzysztof Hałasa
  Cc: Linux Media, kernel-mentors, linux-kernel, Hans Verkuil, hans.verkuil

On Mon, Apr 20, 2015 at 2:18 PM, Krzysztof Hałasa <khalasa@piap.pl> wrote:
> Andrey Utkin <andrey.utkin@corp.bluecherry.net> writes:
>
>> I am starting a work on driver for techwell tw5864 media grabber&encoder.
>
> If this is tw6864 then I have a driver mostly completed.
> Actually I'm using tw6869 but I think this is very similar (4 channels
> instead of 8 and PCI instead of PCIe). I have 6864s but haven't yet
> tried using them for trivial reasons.
>
> This is BTW completely different chip (family) than the old tw68x.

Please check first digit. I mean _5_864, in your post there's 6869.
Please specify.
Very interested.anyway. Thanks.

-- 
Bluecherry developer.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: On register r/w macros/procedures of drivers/media/pci
  2015-04-20 11:20   ` Andrey Utkin
@ 2015-04-20 12:45     ` Krzysztof Hałasa
  2015-04-20 13:00       ` Andrey Utkin
  0 siblings, 1 reply; 7+ messages in thread
From: Krzysztof Hałasa @ 2015-04-20 12:45 UTC (permalink / raw)
  To: Andrey Utkin
  Cc: Linux Media, kernel-mentors, linux-kernel, Hans Verkuil, hans.verkuil

Andrey Utkin <andrey.utkin@corp.bluecherry.net> writes:

> Please check first digit. I mean _5_864, in your post there's 6869.

Ok, I just thought it may be a typo. I can now see 5864 is a H.264
encoder, while 686x are simpler frame-grabbers only.

Sorry for the noise.
-- 
Krzysztof Halasa

Research Institute for Automation and Measurements PIAP
Al. Jerozolimskie 202, 02-486 Warsaw, Poland

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: On register r/w macros/procedures of drivers/media/pci
  2015-04-20 12:45     ` Krzysztof Hałasa
@ 2015-04-20 13:00       ` Andrey Utkin
  0 siblings, 0 replies; 7+ messages in thread
From: Andrey Utkin @ 2015-04-20 13:00 UTC (permalink / raw)
  To: Krzysztof Hałasa
  Cc: Linux Media, kernel-mentors, linux-kernel, Hans Verkuil, hans.verkuil

On Mon, Apr 20, 2015 at 3:45 PM, Krzysztof Hałasa <khalasa@piap.pl> wrote:
> Andrey Utkin <andrey.utkin@corp.bluecherry.net> writes:
>
>> Please check first digit. I mean _5_864, in your post there's 6869.
>
> Ok, I just thought it may be a typo. I can now see 5864 is a H.264
> encoder, while 686x are simpler frame-grabbers only.
>
> Sorry for the noise.

Nothing to excuse for!
Thanks for the info anyway!

-- 
Bluecherry developer.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-04-20 13:00 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-19  7:36 On register r/w macros/procedures of drivers/media/pci Andrey Utkin
2015-04-19  8:28 ` Hans Verkuil
2015-04-19  8:55   ` Andrey Utkin
2015-04-20 11:18 ` Krzysztof Hałasa
2015-04-20 11:20   ` Andrey Utkin
2015-04-20 12:45     ` Krzysztof Hałasa
2015-04-20 13:00       ` Andrey Utkin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.