SUPERH platform development
 help / color / mirror / Atom feed
* Re: [PATCH 33/57] fbdev: sh_mobile_lcdc: Add sh_mobile_format_info() function
From: Laurent Pinchart @ 2011-12-14 11:30 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1323784972-24205-34-git-send-email-laurent.pinchart@ideasonboard.com>

Hi Damian,

On Wednesday 14 December 2011 04:04:52 Damian Hobson-Garcia wrote:
> On 2011/12/13 23:02, Laurent Pinchart wrote:
> > --- a/drivers/video/sh_mobile_lcdcfb.c
> > +++ b/drivers/video/sh_mobile_lcdcfb.c
> > @@ -447,6 +447,75 @@ static int sh_mobile_lcdc_display_notify(struct
> > sh_mobile_lcdc_chan *ch,
> > 
> >   * Format helpers
> >   */
> > 
> > +struct sh_mobile_lcdc_format_info {
> > +	u32 fourcc;
> > +	unsigned int bpp;
> > +	bool yuv;
> > +	u32 lddfr;
> > +};
> > +
> > +static const struct sh_mobile_lcdc_format_info sh_mobile_format_infos[]
> > = { +	{
> > +		.fourcc = V4L2_PIX_FMT_RGB565,
> > +		.bpp = 12,
> 
> I think that this should be 16 instead of 12.

Oops, you're right. Thanks. I'll fix that.

> > @@ -665,37 +726,20 @@ static void __sh_mobile_lcdc_start(struct
> > sh_mobile_lcdc_priv *priv)
> > 
> >  	/* Setup geometry, format, frame buffer memory and operation mode. */
> >  	for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
> > 
> > +		const struct sh_mobile_lcdc_format_info *format;
> > +		u32 fourcc;
> > +
> > 
> >  		ch = &priv->ch[k];
> >  		if (!ch->enabled)
> >  		
> >  			continue;
> >  		
> >  		sh_mobile_lcdc_geometry(ch);
> > 
> > -		switch (sh_mobile_format_fourcc(&ch->info->var)) {
> > -		case V4L2_PIX_FMT_RGB565:
> > -			tmp = LDDFR_PKF_RGB16;
> > -			break;
> > -		case V4L2_PIX_FMT_BGR24:
> > -			tmp = LDDFR_PKF_RGB24;
> > -			break;
> > -		case V4L2_PIX_FMT_BGR32:
> > -			tmp = LDDFR_PKF_ARGB32;
> > -			break;
> > -		case V4L2_PIX_FMT_NV12:
> > -		case V4L2_PIX_FMT_NV21:
> > -			tmp = LDDFR_CC | LDDFR_YF_420;
> > -			break;
> > -		case V4L2_PIX_FMT_NV16:
> > -		case V4L2_PIX_FMT_NV61:
> > -			tmp = LDDFR_CC | LDDFR_YF_422;
> > -			break;
> > -		case V4L2_PIX_FMT_NV24:
> > -		case V4L2_PIX_FMT_NV42:
> > -			tmp = LDDFR_CC | LDDFR_YF_444;
> > -			break;
> > -		}
> > +		fourcc = sh_mobile_format_fourcc(&ch->info->var);
> > +		format = sh_mobile_format_info(fourcc);
> > +		tmp = format->lddfr;
> 
> Do you need to check if format is NULL here?

The fourcc is validated in both sh_mobile_lcdc_channel_init() (for the value 
passed to the driver through platform data) and sh_mobile_check_var() (for the 
value requested by userspace). format should thus never be NULL here.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH/RFC] mmc: add a device PM QoS constraint when a host is
From: Ulf Hansson @ 2011-12-14 11:12 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Guennadi Liakhovetski, linux-mmc@vger.kernel.org,
	linux-pm@vger.kernel.org, Chris Ball, linux-sh@vger.kernel.org
In-Reply-To: <201112141115.00945.rjw@sisk.pl>


>> You have a point. But I am not convinced. :-)
>>
>> Some host drivers already make use of autosuspend. I think this is most 
>> straightforward solution to this problem right now.
> 
> The problem is not about _when_ to suspend (which autosuspend is about),
> but _what_ _state_ to go when suspended.  That's quite a different issue.

I was kind of taking a more simple approach, I were considering 
runtime_suspend as _one_ state. Right now there is no host driver having 
different levels of runtime_suspend state, if I am correct. But ofcourse 
that could be the future.

Moreover, I definitely do not think that a fixed timeout of 100us is 
applicable for all use cases, this must at least be configurable.

> 
>> However, we could also do pm_runtime_get_sync of the host device in 
>> claim host and vice verse in release host, thus preventing the host 
>> driver from triggering runtime_suspend|resume for every request. Though, 
>> I am not 100% sure this is really what you want either.
> 
> No, I don't want that.  I want the device to be suspended when possible,
> but I don't want that to cause the system to go into an overly deep power
> state as a result.

Before just skipping my proposal, I think you should know some more 
background to why I suggested this:

1.
mmc_claim_host is using mmc_host_enable, which kind of mean the same 
thing for a host driver as doing get_sync. Vice verse for mmc_release_host.

2.
When executing mmc/sd commands/requests the host must always be claimed 
(and thus the host is always enabled). But more important some mmc/sd 
commands must be executed as a sequence, without the host being disabled 
in between the commands (since a disable might mean that the clock to 
card gets disabled). To solve this, the mmc_claim_host is used, to make 
sure the host is enabled during the complete command sequence.

I happily continue this discussion, to see if someone more can break the 
idea about having get_sync in mmc_host_enable. :-)

> 
>> Using PM QoS as you propose, might prevent some hosts from doing 
>> runtime_suspend|resume completely and thus those might not fulfill power 
>> consumption requirements instead.
> 
> I'm not sure what scenario you have in mind.  Care to elaborate?

Well, suppose a the host drivers start considering the PM QoS 
requirement, but never can fulfill the requirement of 100us for it's 
runtime_suspend callback function...

> 
>> I do not think we can take this decision at this level. Is performance more
>> important than power save, that is kind of the question.
> 
> Yes, it is.  Also, the number used here is somewhat arbitrary.

For you maybe power management is less important, but I doubt everybody 
else agree to that. It is a more complex balance I believe.

> 
> However, since no one except for SH7372 is now using device PM QoS, no one
> else will be affected by this change at the moment.

True, but that is not a good reason for adding more stuff to the mmc core.

> 
> Thanks,
> Rafael
> 

By the way, I like to discuss with you so please take no offense from my 
comments. :-)


BR
Ulf Hansson

^ permalink raw reply

* Re: [PATCH 11/57] fbdev: sh_mobile_lcdc: Handle HDMI/MIPI transmitter device directly
From: Laurent Pinchart @ 2011-12-14 11:10 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1323784972-24205-12-git-send-email-laurent.pinchart@ideasonboard.com>

Hi Guennadi,

On Wednesday 14 December 2011 01:03:06 Guennadi Liakhovetski wrote:
> On Tue, 13 Dec 2011, Laurent Pinchart wrote:
> > Pass a pointer to the transmitter device through platform data, retrieve
> > the corresponding sh_mobile_lcdc_entity structure in the probe method
> > and call the transmitter display_on/off methods directly.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > ---
> > 
> >  drivers/video/sh_mobile_lcdcfb.c |   33
> >  ++++++++++++++++++++++++++++----- drivers/video/sh_mobile_lcdcfb.h |   
> >  2 ++
> >  include/video/sh_mobile_lcdc.h   |    2 ++
> >  3 files changed, 32 insertions(+), 5 deletions(-)
> > 
> > diff --git a/drivers/video/sh_mobile_lcdcfb.c
> > b/drivers/video/sh_mobile_lcdcfb.c index afa1fac..f1bbae6 100644
> > --- a/drivers/video/sh_mobile_lcdcfb.c
> > +++ b/drivers/video/sh_mobile_lcdcfb.c
> > @@ -338,6 +338,13 @@ static void sh_mobile_lcdc_deferred_io_touch(struct
> > fb_info *info)
> > 
> >  static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
> >  {
> >  
> >  	struct sh_mobile_lcdc_board_cfg	*board_cfg = &ch->cfg.board_cfg;
> > 
> > +	int ret;
> > +
> > +	if (ch->tx_dev) {
> > +		ret = ch->tx_dev->ops->display_on(ch->tx_dev, ch->info);
> 
> ->ops or ->display_o{n,ff}() cannot be NULL?

They must be provided, at least with the transmitters we currently have. This 
code will likely get reworked to support things like HDMI-on-DSI, so I don't 
think adding a pre

> also
> 
> +		int ret = ch->tx_dev->ops->display_on(ch->tx_dev, ch->info);
> 
> would suffice;-)

Or even if (ch->tx_dev->ops->display_on(ch->tx_dev, ch->info) < 0)

I'll fix that.

> > +		if (ret < 0)
> > +			return;
> > +	}
> > 
> >  	/* HDMI must be enabled before LCDC configuration */
> >  	if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
> > 
> > @@ -354,6 +361,9 @@ static void sh_mobile_lcdc_display_off(struct
> > sh_mobile_lcdc_chan *ch)
> > 
> >  		board_cfg->display_off(board_cfg->board_data);
> >  		module_put(board_cfg->owner);
> >  	
> >  	}
> > 
> > +
> > +	if (ch->tx_dev)
> > +		ch->tx_dev->ops->display_off(ch->tx_dev);
> > 
> >  }
> >  
> >  /*
> >  -----------------------------------------------------------------------
> >  ------
> > 
> > @@ -1490,18 +1500,21 @@ static int sh_mobile_lcdc_remove(struct
> > platform_device *pdev)
> > 
> >  	sh_mobile_lcdc_stop(priv);
> >  	
> >  	for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
> > 
> > -		info = priv->ch[i].info;
> > +		struct sh_mobile_lcdc_chan *ch = &priv->ch[i];
> > 
> > +		info = ch->info;
> > 
> >  		if (!info || !info->device)
> >  		
> >  			continue;
> > 
> > -		if (priv->ch[i].sglist)
> > -			vfree(priv->ch[i].sglist);
> > +		if (ch->tx_dev)
> > +			module_put(ch->cfg.tx_dev->dev.driver->owner);
> 
> This is now the same ->owner, as the one taken in your
> sh_mobile_lcdc_display_o{n,ff}() functions? IIUC, you're now adding this
> new ->owner field to later (17/57) remove the original one?

It's the same owner, yes. The idea is to get a reference to the transmitter 
device module at probe() time and release it at remove() time instead of doing 
so in display_on() and display_off(), and to remove the owner field hack from 
platform data.

> > +
> > +		if (ch->sglist)
> > +			vfree(ch->sglist);
> > 
> >  		if (info->screen_base)
> >  		
> >  			dma_free_coherent(&pdev->dev, info->fix.smem_len,
> > 
> > -					  info->screen_base,
> > -					  priv->ch[i].dma_handle);
> > +					  info->screen_base, ch->dma_handle);
> > 
> >  		fb_dealloc_cmap(&info->cmap);
> >  		framebuffer_release(info);
> >  	
> >  	}
> > 
> > @@ -1596,6 +1609,16 @@ sh_mobile_lcdc_channel_init(struct
> > sh_mobile_lcdc_priv *priv,
> > 
> >  	info->pseudo_palette = &ch->pseudo_palette;
> >  	info->flags = FBINFO_FLAG_DEFAULT;
> > 
> > +	if (cfg->tx_dev) {
> > +		if (!cfg->tx_dev->dev.driver ||
> > +		    !try_module_get(cfg->tx_dev->dev.driver->owner)) {
> > +			dev_warn(priv->dev, "unable to get transmitter "
> > +				 "device\n");
> 
> Grrr... Pleeeease, don't split strings. If you really have to program on
> vt220;-) at least do
> 
> +			dev_warn(priv->dev,
> +				 "unable to get transmitter device\n");

Sorry about that. Will fix.

> > +			return -EINVAL;
> > +		}
> > +		ch->tx_dev = platform_get_drvdata(cfg->tx_dev);
> > +	}
> > +
> > 
> >  	/* Iterate through the modes to validate them and find the highest
> >  	
> >  	 * resolution.
> >  	 */
> > 
> > diff --git a/drivers/video/sh_mobile_lcdcfb.h
> > b/drivers/video/sh_mobile_lcdcfb.h index d79e5aa..9601b92 100644
> > --- a/drivers/video/sh_mobile_lcdcfb.h
> > +++ b/drivers/video/sh_mobile_lcdcfb.h
> > @@ -41,6 +41,8 @@ struct sh_mobile_lcdc_entity {
> > 
> >   */
> >  
> >  struct sh_mobile_lcdc_chan {
> >  
> >  	struct sh_mobile_lcdc_priv *lcdc;
> > 
> > +	struct sh_mobile_lcdc_entity *tx_dev;
> > +
> > 
> >  	unsigned long *reg_offs;
> >  	unsigned long ldmt1r_value;
> >  	unsigned long enabled; /* ME and SE in LDCNT2R */
> > 
> > diff --git a/include/video/sh_mobile_lcdc.h
> > b/include/video/sh_mobile_lcdc.h index fe30b75..0ec59e1 100644
> > --- a/include/video/sh_mobile_lcdc.h
> > +++ b/include/video/sh_mobile_lcdc.h
> > @@ -186,6 +186,8 @@ struct sh_mobile_lcdc_chan_cfg {
> > 
> >  	struct sh_mobile_lcdc_bl_info bl_info;
> >  	struct sh_mobile_lcdc_sys_bus_cfg sys_bus_cfg; /* only for SYSn I/F */
> >  	struct sh_mobile_meram_cfg *meram_cfg;
> > 
> > +
> > +	struct platform_device *tx_dev;	/* HDMI/MIPI transmitter device */
> 
> "MIPI" is too generic, IMHO

Will HDMI/DSI do ?

> Hm, could we, maybe, have different names for sh_mobile_lcdc_chan::tx_dev
> and sh_mobile_lcdc_chan_cfg::tx_dev?;-)

Sure. Do you have any suggestion ? :-)

> >  };
> >  
> >  struct sh_mobile_lcdc_info {

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH 02/57] fbdev: sh_mobile_lcdc: Mark init-only symbols with
From: Guennadi Liakhovetski @ 2011-12-14 11:07 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1323784972-24205-3-git-send-email-laurent.pinchart@ideasonboard.com>

On Wed, 14 Dec 2011, Laurent Pinchart wrote:

> Hi Guennadi,
> 
> On Tuesday 13 December 2011 23:23:32 Guennadi Liakhovetski wrote:
> > On Tue, 13 Dec 2011, Laurent Pinchart wrote:
> > > default_720p and sh_mobile_lcdc_check_interface are used at device
> > > initialization time only. Mark them as __devinitconst and __devinit
> > > respectively.
> > > 
> > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > > ---
> > > 
> > >  drivers/video/sh_mobile_lcdcfb.c |    5 +++--
> > >  1 files changed, 3 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/video/sh_mobile_lcdcfb.c
> > > b/drivers/video/sh_mobile_lcdcfb.c index 8b18360..a6bf4fb 100644
> > > --- a/drivers/video/sh_mobile_lcdcfb.c
> > > +++ b/drivers/video/sh_mobile_lcdcfb.c
> > > @@ -1459,7 +1459,7 @@ static int sh_mobile_lcdc_notify(struct
> > > notifier_block *nb,
> > > 
> > >   * Probe/remove and driver init/exit
> > >   */
> > > 
> > > -static const struct fb_videomode default_720p = {
> > > +static const struct fb_videomode default_720p __devinitconst = {
> > > 
> > >  	.name = "HDMI 720p",
> > >  	.xres = 1280,
> > >  	.yres = 720,
> > > 
> > > @@ -1528,7 +1528,8 @@ static int sh_mobile_lcdc_remove(struct
> > > platform_device *pdev)
> > > 
> > >  	return 0;
> > >  
> > >  }
> > > 
> > > -static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan
> > > *ch) +static int __devinit
> > > +sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
> > 
> > Personally, I don't like this type of line splitting very much, I prefer
> > the grep output to show the function type and all attributes, but this,
> > certainly, would not be the reason to change this specific hunk:-) But
> > this might be: the whole file so far has all function definitions at least
> > up to and including the first parameter on one line, so, I find, this
> > change would introduce an inconsistency in the file style. The line would
> > __only__ be 83 characters long if you put it all on one line. I think, it
> > would look better then:-)
> 
> It's a matter of limits, as usual... I find 80 to be a nice limit, although in 
> some cases I'm fine with exceeding it (one example is a long list of #defines 
> with a small comment describing each macro, as in the list of FOURCCs in 
> linux/videodev2.h for instance). For code I try to respect the 80 characters 
> limit. Another reason is that it produces checkpatch.pl warnings, which force 
> me to manually look at all the warnings to check which ones are acceptable.
> 
> Regarding consistency, other patches in this series use the same style, so 
> that function won't feel alone anymore ;-)
> 
> I can change this (and other instances of the same coding style) if you 
> insist. BTW, a possible improvement would be to shorten the sh_mobile_lcdc_ 
> prefix. I find it too long, and I was thinking about reducing it to shm_lcdc_ 
> (although shm reffers to shared memory, so that might not be the best idea).

How about sh_lcdc?

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply

* Re: [PATCH 06/57] fbdev: sh_mobile_hdmi: Don't access LCDC channel in notifier callback
From: Laurent Pinchart @ 2011-12-14 10:47 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1323784972-24205-7-git-send-email-laurent.pinchart@ideasonboard.com>

Hi Guennadi,

On Wednesday 14 December 2011 00:02:11 Guennadi Liakhovetski wrote:
> On Tue, 13 Dec 2011, Laurent Pinchart wrote:
> > Instead of relying on info->par being a pointer to an LCDC channel, cast
> > the notifier block pointer to an sh_hdmi pointer.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > ---
> > 
> >  drivers/video/sh_mobile_hdmi.c |    6 +++---
> >  1 files changed, 3 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/video/sh_mobile_hdmi.c
> > b/drivers/video/sh_mobile_hdmi.c index 647ba98..b1e90f5 100644
> > --- a/drivers/video/sh_mobile_hdmi.c
> > +++ b/drivers/video/sh_mobile_hdmi.c
> > @@ -225,6 +225,8 @@ struct sh_hdmi {
> > 
> >  	struct notifier_block notifier;
> >  
> >  };
> > 
> > +#define notifier_to_hdmi(n)	container_of(n, struct sh_hdmi, notifier)
> > +
> > 
> >  static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
> >  {
> >  
> >  	iowrite8(data, hdmi->base + reg);
> > 
> > @@ -1204,9 +1206,7 @@ static int sh_hdmi_notify(struct notifier_block
> > *nb,
> > 
> >  {
> >  
> >  	struct fb_event *event = data;
> >  	struct fb_info *info = event->info;
> > 
> > -	struct sh_mobile_lcdc_chan *ch = info->par;
> > -	struct sh_mobile_lcdc_board_cfg	*board_cfg = &ch->cfg.board_cfg;
> > -	struct sh_hdmi *hdmi = board_cfg->board_data;
> > +	struct sh_hdmi *hdmi = notifier_to_hdmi(nb);
> > 
> >  	if (!hdmi || nb != &hdmi->notifier || hdmi->info != info)
> 
> Then you also can drop the first two of the three checks above. If I'm not
> mistaken, in a HDMI / LCD set up, if this notifier is called for the LCD
> panel, hdmi will wtill point to the HDMI-related sh_hdmi object, whose
> ->info will then mismatch the info pointer, derived from the notifier
> "data" pointer.

That's correct. The first two checks don't hurt, but will always be false. 
I'll remove them.

> >  		return NOTIFY_DONE;

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH 06/57] fbdev: sh_mobile_hdmi: Don't access LCDC channel in notifier callback
From: Laurent Pinchart @ 2011-12-14 10:41 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1323784972-24205-7-git-send-email-laurent.pinchart@ideasonboard.com>

On Wednesday 14 December 2011 00:02:11 Guennadi Liakhovetski wrote:
> On Tue, 13 Dec 2011, Laurent Pinchart wrote:
> > Instead of relying on info->par being a pointer to an LCDC channel, cast
> > the notifier block pointer to an sh_hdmi pointer.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > ---
> > 
> >  drivers/video/sh_mobile_hdmi.c |    6 +++---
> >  1 files changed, 3 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/video/sh_mobile_hdmi.c
> > b/drivers/video/sh_mobile_hdmi.c index 647ba98..b1e90f5 100644
> > --- a/drivers/video/sh_mobile_hdmi.c
> > +++ b/drivers/video/sh_mobile_hdmi.c
> > @@ -225,6 +225,8 @@ struct sh_hdmi {
> > 
> >  	struct notifier_block notifier;
> >  
> >  };
> > 
> > +#define notifier_to_hdmi(n)	container_of(n, struct sh_hdmi, notifier)
> > +
> > 
> >  static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
> >  {
> >  
> >  	iowrite8(data, hdmi->base + reg);
> > 
> > @@ -1204,9 +1206,7 @@ static int sh_hdmi_notify(struct notifier_block
> > *nb,
> > 
> >  {
> >  
> >  	struct fb_event *event = data;
> >  	struct fb_info *info = event->info;
> > 
> > -	struct sh_mobile_lcdc_chan *ch = info->par;
> > -	struct sh_mobile_lcdc_board_cfg	*board_cfg = &ch->cfg.board_cfg;
> > -	struct sh_hdmi *hdmi = board_cfg->board_data;
> > +	struct sh_hdmi *hdmi = notifier_to_hdmi(nb);
> > 
> >  	if (!hdmi || nb != &hdmi->notifier || hdmi->info != info)
> 
> Then you also can drop the first two of the three checks above. If I'm not
> mistaken, in a HDMI / LCD set up, if this notifier is called for the LCD
> panel, hdmi will wtill point to the HDMI-related sh_hdmi object, whose
> ->info will then mismatch the info pointer, derived from the notifier
> "data" pointer.
> 
> >  		return NOTIFY_DONE;
> 
> Thanks
> Guennadi
> ---
> Guennadi Liakhovetski, Ph.D.
> Freelance Open-Source Software Developer
> http://www.open-technology.de/

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH 02/57] fbdev: sh_mobile_lcdc: Mark init-only symbols with __devinit(const)
From: Laurent Pinchart @ 2011-12-14 10:40 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1323784972-24205-3-git-send-email-laurent.pinchart@ideasonboard.com>

Hi Guennadi,

On Tuesday 13 December 2011 23:23:32 Guennadi Liakhovetski wrote:
> On Tue, 13 Dec 2011, Laurent Pinchart wrote:
> > default_720p and sh_mobile_lcdc_check_interface are used at device
> > initialization time only. Mark them as __devinitconst and __devinit
> > respectively.
> > 
> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > ---
> > 
> >  drivers/video/sh_mobile_lcdcfb.c |    5 +++--
> >  1 files changed, 3 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/video/sh_mobile_lcdcfb.c
> > b/drivers/video/sh_mobile_lcdcfb.c index 8b18360..a6bf4fb 100644
> > --- a/drivers/video/sh_mobile_lcdcfb.c
> > +++ b/drivers/video/sh_mobile_lcdcfb.c
> > @@ -1459,7 +1459,7 @@ static int sh_mobile_lcdc_notify(struct
> > notifier_block *nb,
> > 
> >   * Probe/remove and driver init/exit
> >   */
> > 
> > -static const struct fb_videomode default_720p = {
> > +static const struct fb_videomode default_720p __devinitconst = {
> > 
> >  	.name = "HDMI 720p",
> >  	.xres = 1280,
> >  	.yres = 720,
> > 
> > @@ -1528,7 +1528,8 @@ static int sh_mobile_lcdc_remove(struct
> > platform_device *pdev)
> > 
> >  	return 0;
> >  
> >  }
> > 
> > -static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan
> > *ch) +static int __devinit
> > +sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
> 
> Personally, I don't like this type of line splitting very much, I prefer
> the grep output to show the function type and all attributes, but this,
> certainly, would not be the reason to change this specific hunk:-) But
> this might be: the whole file so far has all function definitions at least
> up to and including the first parameter on one line, so, I find, this
> change would introduce an inconsistency in the file style. The line would
> __only__ be 83 characters long if you put it all on one line. I think, it
> would look better then:-)

It's a matter of limits, as usual... I find 80 to be a nice limit, although in 
some cases I'm fine with exceeding it (one example is a long list of #defines 
with a small comment describing each macro, as in the list of FOURCCs in 
linux/videodev2.h for instance). For code I try to respect the 80 characters 
limit. Another reason is that it produces checkpatch.pl warnings, which force 
me to manually look at all the warnings to check which ones are acceptable.

Regarding consistency, other patches in this series use the same style, so 
that function won't feel alone anymore ;-)

I can change this (and other instances of the same coding style) if you 
insist. BTW, a possible improvement would be to shorten the sh_mobile_lcdc_ 
prefix. I find it too long, and I was thinking about reducing it to shm_lcdc_ 
(although shm reffers to shared memory, so that might not be the best idea).

> >  {
> >  
> >  	int interface_type = ch->cfg.interface_type;

-- 
Regards,

Laurent Pinchart

^ permalink raw reply

* Re: [PATCH/RFC] mmc: add a device PM QoS constraint when a host is first claimed
From: Rafael J. Wysocki @ 2011-12-14 10:28 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Ulf Hansson, Guennadi Liakhovetski, linux-mmc@vger.kernel.org,
	linux-pm@vger.kernel.org, Chris Ball, linux-sh@vger.kernel.org
In-Reply-To: <CACRpkdZnmCUfk0h+wK=KUvrv5oCudEAdEc_TY6=yZg_3uTqkgw@mail.gmail.com>

On Wednesday, December 14, 2011, Linus Walleij wrote:
> On Wed, Dec 14, 2011 at 10:00 AM, Ulf Hansson
> <ulf.hansson@stericsson.com> wrote:
> > Guennadi Liakhovetski wrote:
> 
> > Using PM QoS as you propose, might prevent some hosts from doing
> > runtime_suspend|resume completely and thus those might not fulfill power
> > consumption requirements instead. I do not think we can take this decision
> > at this level. Is performance more important than power save, that is kind
> > of the question.
> 
> I agree with this point. The problematic part of the patch (IMHO) is this:
> 
> >> + This constraint prevents runtime-suspending the
> >> + device, if the expected wakeup latency is larger than 100us.
> (...)
> >> +                       int ret = dev_pm_qos_add_request(host->parent,
> >> +                                                        &host->pm_qos, 100);
> 
> So we hardcode 100us (is that really 100us by the way? I cannot
> follow this code path but usually these figures are in ms, but what
> do I know) as the in-between back-to-back transfers.

They are in microseconds.

> But this delta is dependent on a lot of stuff that only the platform
> knows, like nominal CPU frequency, bus speed etc, so certainly the
> platform must be able to modify that number.

You seem to be confusing things.  The exact meaning of this number is:
"I may want to use the device 100 us from now (but not earlier), so please
make it possible to do that".  [It roughly means "don't put the device into
a low-power state that takes more than 100 us to resume from", but it's a bit
more complicated than that.]  It doesn't mean "don't suspend the device for
the next 100 us".

> At the very least, please make this stuff optional using Kconfig
> so it can be shut off, because I fear it will screw up our PM usecases.

I'm not sure how that's possible, at least until your platform starts
to use device PM QoS.

> Ulfs patch to the mmci driver actually use 50ms for back-to-back
> intergap between any two hardware-affecting calls into the driver.

Which is kind of independent.

Thanks,
Rafael

^ permalink raw reply

* Re: [PATCH/RFC] mmc: add a device PM QoS constraint when a host is first claimed
From: Rafael J. Wysocki @ 2011-12-14 10:15 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Guennadi Liakhovetski, linux-mmc@vger.kernel.org,
	linux-pm@vger.kernel.org, Chris Ball, linux-sh@vger.kernel.org
In-Reply-To: <4EE865CA.8000407@stericsson.com>

On Wednesday, December 14, 2011, Ulf Hansson wrote:
> Guennadi Liakhovetski wrote:
> > Hi Ulf
> > 
> > On Tue, 13 Dec 2011, Ulf Hansson wrote:
> > 
> >> Guennadi Liakhovetski wrote:
> >>> Some MMC hosts implement a fine-grained runtime PM, whereby they
> >>> runtime-suspend and -resume the host interface on each transfer. This can
> >>> negatively affect performance, if the user was trying to transfer data
> >>> blocks back-to-back. This patch adds a PM QoS constraint to avoid such a
> >>> throughput reduction. This constraint prevents runtime-suspending the
> >>> device, if the expected wakeup latency is larger than 100us.
> >>>
> >>> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> >> I think host drivers can use autosuspend with some ms delay for this instead.
> >> This will mean that requests coming in bursts will not be affected (well only
> >> the first request in the burst will suffer from the runtime resume latency).
> > 
> > I think, Rafael is the best person to explain, why exactly this is not 
> > desired. In short, this is the wrong location to make such decisions and 
> > to define these criteria. The only thing, that the driver may be aware of 
> > is how quickly it wants to be able to wake up, if it got suspended. And 
> > it's already the PM subsystem, that has to decide, whether it can satisfy 
> > this requirement or not. Rafael will correct me, if my explanation is 
> > wrong.
> 
> You have a point. But I am not convinced. :-)
> 
> Some host drivers already make use of autosuspend. I think this is most 
> straightforward solution to this problem right now.

The problem is not about _when_ to suspend (which autosuspend is about),
but _what_ _state_ to go when suspended.  That's quite a different issue.

> However, we could also do pm_runtime_get_sync of the host device in 
> claim host and vice verse in release host, thus preventing the host 
> driver from triggering runtime_suspend|resume for every request. Though, 
> I am not 100% sure this is really what you want either.

No, I don't want that.  I want the device to be suspended when possible,
but I don't want that to cause the system to go into an overly deep power
state as a result.

> Using PM QoS as you propose, might prevent some hosts from doing 
> runtime_suspend|resume completely and thus those might not fulfill power 
> consumption requirements instead.

I'm not sure what scenario you have in mind.  Care to elaborate?

> I do not think we can take this decision at this level. Is performance more
> important than power save, that is kind of the question.

Yes, it is.  Also, the number used here is somewhat arbitrary.

However, since no one except for SH7372 is now using device PM QoS, no one
else will be affected by this change at the moment.

Thanks,
Rafael

^ permalink raw reply

* Re: [PATCH/RFC] mmc: add a device PM QoS constraint when a host is
From: Linus Walleij @ 2011-12-14  9:27 UTC (permalink / raw)
  To: Ulf Hansson, Guennadi Liakhovetski
  Cc: linux-mmc@vger.kernel.org, linux-pm@vger.kernel.org, Chris Ball,
	linux-sh@vger.kernel.org, Rafael J. Wysocki
In-Reply-To: <4EE865CA.8000407@stericsson.com>

On Wed, Dec 14, 2011 at 10:00 AM, Ulf Hansson
<ulf.hansson@stericsson.com> wrote:
> Guennadi Liakhovetski wrote:

> Using PM QoS as you propose, might prevent some hosts from doing
> runtime_suspend|resume completely and thus those might not fulfill power
> consumption requirements instead. I do not think we can take this decision
> at this level. Is performance more important than power save, that is kind
> of the question.

I agree with this point. The problematic part of the patch (IMHO) is this:

>> + This constraint prevents runtime-suspending the
>> + device, if the expected wakeup latency is larger than 100us.
(...)
>> +                       int ret = dev_pm_qos_add_request(host->parent,
>> +                                                        &host->pm_qos, 100);

So we hardcode 100us (is that really 100us by the way? I cannot
follow this code path but usually these figures are in ms, but what
do I know) as the in-between back-to-back transfers.
But this delta is dependent on a lot of stuff that only the platform
knows, like nominal CPU frequency, bus speed etc, so certainly the
platform must be able to modify that number.

At the very least, please make this stuff optional using Kconfig
so it can be shut off, because I fear it will screw up our PM usecases.

Ulfs patch to the mmci driver actually use 50ms for back-to-back
intergap between any two hardware-affecting calls into the driver.

Yours,
Linus Walleij

^ permalink raw reply

* Re: [PATCH/RFC] mmc: add a device PM QoS constraint when a host is
From: Ulf Hansson @ 2011-12-14  9:00 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: linux-mmc@vger.kernel.org, linux-pm@vger.kernel.org, Chris Ball,
	linux-sh@vger.kernel.org, Rafael J. Wysocki
In-Reply-To: <Pine.LNX.4.64.1112131658330.20293@axis700.grange>

Guennadi Liakhovetski wrote:
> Hi Ulf
> 
> On Tue, 13 Dec 2011, Ulf Hansson wrote:
> 
>> Guennadi Liakhovetski wrote:
>>> Some MMC hosts implement a fine-grained runtime PM, whereby they
>>> runtime-suspend and -resume the host interface on each transfer. This can
>>> negatively affect performance, if the user was trying to transfer data
>>> blocks back-to-back. This patch adds a PM QoS constraint to avoid such a
>>> throughput reduction. This constraint prevents runtime-suspending the
>>> device, if the expected wakeup latency is larger than 100us.
>>>
>>> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
>> I think host drivers can use autosuspend with some ms delay for this instead.
>> This will mean that requests coming in bursts will not be affected (well only
>> the first request in the burst will suffer from the runtime resume latency).
> 
> I think, Rafael is the best person to explain, why exactly this is not 
> desired. In short, this is the wrong location to make such decisions and 
> to define these criteria. The only thing, that the driver may be aware of 
> is how quickly it wants to be able to wake up, if it got suspended. And 
> it's already the PM subsystem, that has to decide, whether it can satisfy 
> this requirement or not. Rafael will correct me, if my explanation is 
> wrong.

You have a point. But I am not convinced. :-)

Some host drivers already make use of autosuspend. I think this is most 
straightforward solution to this problem right now.

However, we could also do pm_runtime_get_sync of the host device in 
claim host and vice verse in release host, thus preventing the host 
driver from triggering runtime_suspend|resume for every request. Though, 
I am not 100% sure this is really what you want either.

Using PM QoS as you propose, might prevent some hosts from doing 
runtime_suspend|resume completely and thus those might not fulfill power 
consumption requirements instead. I do not think we can take this 
decision at this level. Is performance more important than power save, 
that is kind of the question.


> 
>> I believe that runtime resume callback should ofcourse be optimized so they
>> are executed as fast as possible. But moreover, if they take more 100us, is
>> that really a reason for not executing them at all?
> 
> I think it is a reason not to execute them during an intensive IO, yes. I 
> cannot imagine a case, where if you have multiple IO requests waiting in 
> the queue to your medium, you would want to switch off and immediately on 
> again. Well, of course, such situations might exist, but then you just 
> have to define and use a different governor on your system. This is also 
> the flexibility, that this API is giving you.

I totally agree.

> 
> Thanks
> Guennadi
> ---
> Guennadi Liakhovetski, Ph.D.
> Freelance Open-Source Software Developer
> http://www.open-technology.de/
> 


Br
Ulf Hansson

^ permalink raw reply

* Re: [PATCH 33/57] fbdev: sh_mobile_lcdc: Add sh_mobile_format_info()
From: Damian Hobson-Garcia @ 2011-12-14  3:04 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1323784972-24205-34-git-send-email-laurent.pinchart@ideasonboard.com>

Hi Laurent,


On 2011/12/13 23:02, Laurent Pinchart wrote:
> --- a/drivers/video/sh_mobile_lcdcfb.c
> +++ b/drivers/video/sh_mobile_lcdcfb.c
> @@ -447,6 +447,75 @@ static int sh_mobile_lcdc_display_notify(struct sh_mobile_lcdc_chan *ch,
>   * Format helpers
>   */
>  
> +struct sh_mobile_lcdc_format_info {
> +	u32 fourcc;
> +	unsigned int bpp;
> +	bool yuv;
> +	u32 lddfr;
> +};
> +
> +static const struct sh_mobile_lcdc_format_info sh_mobile_format_infos[] = {
> +	{
> +		.fourcc = V4L2_PIX_FMT_RGB565,
> +		.bpp = 12,
I think that this should be 16 instead of 12.


> @@ -665,37 +726,20 @@ static void __sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
>  
>  	/* Setup geometry, format, frame buffer memory and operation mode. */
>  	for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
> +		const struct sh_mobile_lcdc_format_info *format;
> +		u32 fourcc;
> +
>  		ch = &priv->ch[k];
>  		if (!ch->enabled)
>  			continue;
>  
>  		sh_mobile_lcdc_geometry(ch);
>  
> -		switch (sh_mobile_format_fourcc(&ch->info->var)) {
> -		case V4L2_PIX_FMT_RGB565:
> -			tmp = LDDFR_PKF_RGB16;
> -			break;
> -		case V4L2_PIX_FMT_BGR24:
> -			tmp = LDDFR_PKF_RGB24;
> -			break;
> -		case V4L2_PIX_FMT_BGR32:
> -			tmp = LDDFR_PKF_ARGB32;
> -			break;
> -		case V4L2_PIX_FMT_NV12:
> -		case V4L2_PIX_FMT_NV21:
> -			tmp = LDDFR_CC | LDDFR_YF_420;
> -			break;
> -		case V4L2_PIX_FMT_NV16:
> -		case V4L2_PIX_FMT_NV61:
> -			tmp = LDDFR_CC | LDDFR_YF_422;
> -			break;
> -		case V4L2_PIX_FMT_NV24:
> -		case V4L2_PIX_FMT_NV42:
> -			tmp = LDDFR_CC | LDDFR_YF_444;
> -			break;
> -		}
> +		fourcc = sh_mobile_format_fourcc(&ch->info->var);
> +		format = sh_mobile_format_info(fourcc);
> +		tmp = format->lddfr;
Do you need to check if format is NULL here?


Damian

^ permalink raw reply

* Re: [PATCH 11/57] fbdev: sh_mobile_lcdc: Handle HDMI/MIPI transmitter
From: Guennadi Liakhovetski @ 2011-12-14  0:03 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1323784972-24205-12-git-send-email-laurent.pinchart@ideasonboard.com>

On Tue, 13 Dec 2011, Laurent Pinchart wrote:

> Pass a pointer to the transmitter device through platform data, retrieve
> the corresponding sh_mobile_lcdc_entity structure in the probe method
> and call the transmitter display_on/off methods directly.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  drivers/video/sh_mobile_lcdcfb.c |   33 ++++++++++++++++++++++++++++-----
>  drivers/video/sh_mobile_lcdcfb.h |    2 ++
>  include/video/sh_mobile_lcdc.h   |    2 ++
>  3 files changed, 32 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
> index afa1fac..f1bbae6 100644
> --- a/drivers/video/sh_mobile_lcdcfb.c
> +++ b/drivers/video/sh_mobile_lcdcfb.c
> @@ -338,6 +338,13 @@ static void sh_mobile_lcdc_deferred_io_touch(struct fb_info *info)
>  static void sh_mobile_lcdc_display_on(struct sh_mobile_lcdc_chan *ch)
>  {
>  	struct sh_mobile_lcdc_board_cfg	*board_cfg = &ch->cfg.board_cfg;
> +	int ret;
> +
> +	if (ch->tx_dev) {
> +		ret = ch->tx_dev->ops->display_on(ch->tx_dev, ch->info);

->ops or ->display_o{n,ff}() cannot be NULL?

also

+		int ret = ch->tx_dev->ops->display_on(ch->tx_dev, ch->info);

would suffice;-)

> +		if (ret < 0)
> +			return;
> +	}
>  
>  	/* HDMI must be enabled before LCDC configuration */
>  	if (board_cfg->display_on && try_module_get(board_cfg->owner)) {
> @@ -354,6 +361,9 @@ static void sh_mobile_lcdc_display_off(struct sh_mobile_lcdc_chan *ch)
>  		board_cfg->display_off(board_cfg->board_data);
>  		module_put(board_cfg->owner);
>  	}
> +
> +	if (ch->tx_dev)
> +		ch->tx_dev->ops->display_off(ch->tx_dev);
>  }
>  
>  /* -----------------------------------------------------------------------------
> @@ -1490,18 +1500,21 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
>  	sh_mobile_lcdc_stop(priv);
>  
>  	for (i = 0; i < ARRAY_SIZE(priv->ch); i++) {
> -		info = priv->ch[i].info;
> +		struct sh_mobile_lcdc_chan *ch = &priv->ch[i];
>  
> +		info = ch->info;
>  		if (!info || !info->device)
>  			continue;
>  
> -		if (priv->ch[i].sglist)
> -			vfree(priv->ch[i].sglist);
> +		if (ch->tx_dev)
> +			module_put(ch->cfg.tx_dev->dev.driver->owner);

This is now the same ->owner, as the one taken in your 
sh_mobile_lcdc_display_o{n,ff}() functions? IIUC, you're now adding this 
new ->owner field to later (17/57) remove the original one?

> +
> +		if (ch->sglist)
> +			vfree(ch->sglist);
>  
>  		if (info->screen_base)
>  			dma_free_coherent(&pdev->dev, info->fix.smem_len,
> -					  info->screen_base,
> -					  priv->ch[i].dma_handle);
> +					  info->screen_base, ch->dma_handle);
>  		fb_dealloc_cmap(&info->cmap);
>  		framebuffer_release(info);
>  	}
> @@ -1596,6 +1609,16 @@ sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_priv *priv,
>  	info->pseudo_palette = &ch->pseudo_palette;
>  	info->flags = FBINFO_FLAG_DEFAULT;
>  
> +	if (cfg->tx_dev) {
> +		if (!cfg->tx_dev->dev.driver ||
> +		    !try_module_get(cfg->tx_dev->dev.driver->owner)) {
> +			dev_warn(priv->dev, "unable to get transmitter "
> +				 "device\n");

Grrr... Pleeeease, don't split strings. If you really have to program on 
vt220;-) at least do

+			dev_warn(priv->dev,
+				 "unable to get transmitter device\n");


> +			return -EINVAL;
> +		}
> +		ch->tx_dev = platform_get_drvdata(cfg->tx_dev);
> +	}
> +
>  	/* Iterate through the modes to validate them and find the highest
>  	 * resolution.
>  	 */
> diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/sh_mobile_lcdcfb.h
> index d79e5aa..9601b92 100644
> --- a/drivers/video/sh_mobile_lcdcfb.h
> +++ b/drivers/video/sh_mobile_lcdcfb.h
> @@ -41,6 +41,8 @@ struct sh_mobile_lcdc_entity {
>   */
>  struct sh_mobile_lcdc_chan {
>  	struct sh_mobile_lcdc_priv *lcdc;
> +	struct sh_mobile_lcdc_entity *tx_dev;
> +
>  	unsigned long *reg_offs;
>  	unsigned long ldmt1r_value;
>  	unsigned long enabled; /* ME and SE in LDCNT2R */
> diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
> index fe30b75..0ec59e1 100644
> --- a/include/video/sh_mobile_lcdc.h
> +++ b/include/video/sh_mobile_lcdc.h
> @@ -186,6 +186,8 @@ struct sh_mobile_lcdc_chan_cfg {
>  	struct sh_mobile_lcdc_bl_info bl_info;
>  	struct sh_mobile_lcdc_sys_bus_cfg sys_bus_cfg; /* only for SYSn I/F */
>  	struct sh_mobile_meram_cfg *meram_cfg;
> +
> +	struct platform_device *tx_dev;	/* HDMI/MIPI transmitter device */

"MIPI" is too generic, IMHO

Hm, could we, maybe, have different names for sh_mobile_lcdc_chan::tx_dev 
and sh_mobile_lcdc_chan_cfg::tx_dev?;-)

>  };
>  
>  struct sh_mobile_lcdc_info {
> -- 
> 1.7.3.4

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply

* Re: [PATCH 06/57] fbdev: sh_mobile_hdmi: Don't access LCDC channel
From: Guennadi Liakhovetski @ 2011-12-13 23:02 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1323784972-24205-7-git-send-email-laurent.pinchart@ideasonboard.com>

On Tue, 13 Dec 2011, Laurent Pinchart wrote:

> Instead of relying on info->par being a pointer to an LCDC channel, cast
> the notifier block pointer to an sh_hdmi pointer.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  drivers/video/sh_mobile_hdmi.c |    6 +++---
>  1 files changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c
> index 647ba98..b1e90f5 100644
> --- a/drivers/video/sh_mobile_hdmi.c
> +++ b/drivers/video/sh_mobile_hdmi.c
> @@ -225,6 +225,8 @@ struct sh_hdmi {
>  	struct notifier_block notifier;
>  };
>  
> +#define notifier_to_hdmi(n)	container_of(n, struct sh_hdmi, notifier)
> +
>  static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg)
>  {
>  	iowrite8(data, hdmi->base + reg);
> @@ -1204,9 +1206,7 @@ static int sh_hdmi_notify(struct notifier_block *nb,
>  {
>  	struct fb_event *event = data;
>  	struct fb_info *info = event->info;
> -	struct sh_mobile_lcdc_chan *ch = info->par;
> -	struct sh_mobile_lcdc_board_cfg	*board_cfg = &ch->cfg.board_cfg;
> -	struct sh_hdmi *hdmi = board_cfg->board_data;
> +	struct sh_hdmi *hdmi = notifier_to_hdmi(nb);
>  
>  	if (!hdmi || nb != &hdmi->notifier || hdmi->info != info)

Then you also can drop the first two of the three checks above. If I'm not 
mistaken, in a HDMI / LCD set up, if this notifier is called for the LCD 
panel, hdmi will wtill point to the HDMI-related sh_hdmi object, whose 
->info will then mismatch the info pointer, derived from the notifier 
"data" pointer.

>  		return NOTIFY_DONE;
> -- 
> 1.7.3.4

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply

* Re: [PATCH 02/57] fbdev: sh_mobile_lcdc: Mark init-only symbols with
From: Guennadi Liakhovetski @ 2011-12-13 22:23 UTC (permalink / raw)
  To: linux-fbdev
In-Reply-To: <1323784972-24205-3-git-send-email-laurent.pinchart@ideasonboard.com>

Hi Laurent

On Tue, 13 Dec 2011, Laurent Pinchart wrote:

> default_720p and sh_mobile_lcdc_check_interface are used at device
> initialization time only. Mark them as __devinitconst and __devinit
> respectively.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
>  drivers/video/sh_mobile_lcdcfb.c |    5 +++--
>  1 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
> index 8b18360..a6bf4fb 100644
> --- a/drivers/video/sh_mobile_lcdcfb.c
> +++ b/drivers/video/sh_mobile_lcdcfb.c
> @@ -1459,7 +1459,7 @@ static int sh_mobile_lcdc_notify(struct notifier_block *nb,
>   * Probe/remove and driver init/exit
>   */
>  
> -static const struct fb_videomode default_720p = {
> +static const struct fb_videomode default_720p __devinitconst = {
>  	.name = "HDMI 720p",
>  	.xres = 1280,
>  	.yres = 720,
> @@ -1528,7 +1528,8 @@ static int sh_mobile_lcdc_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> -static int sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)
> +static int __devinit
> +sh_mobile_lcdc_check_interface(struct sh_mobile_lcdc_chan *ch)

Personally, I don't like this type of line splitting very much, I prefer 
the grep output to show the function type and all attributes, but this, 
certainly, would not be the reason to change this specific hunk:-) But 
this might be: the whole file so far has all function definitions at least 
up to and including the first parameter on one line, so, I find, this 
change would introduce an inconsistency in the file style. The line would 
__only__ be 83 characters long if you put it all on one line. I think, it 
would look better then:-)

>  {
>  	int interface_type = ch->cfg.interface_type;
>  
> -- 
> 1.7.3.4

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply

* Re: [PATCH/RFC] mmc: add a device PM QoS constraint when a host is first claimed
From: Rafael J. Wysocki @ 2011-12-13 21:08 UTC (permalink / raw)
  To: Guennadi Liakhovetski
  Cc: Ulf Hansson, linux-mmc@vger.kernel.org, linux-pm@vger.kernel.org,
	Chris Ball, linux-sh@vger.kernel.org
In-Reply-To: <Pine.LNX.4.64.1112131658330.20293@axis700.grange>

On Tuesday, December 13, 2011, Guennadi Liakhovetski wrote:
> Hi Ulf
> 
> On Tue, 13 Dec 2011, Ulf Hansson wrote:
> 
> > Guennadi Liakhovetski wrote:
> > > Some MMC hosts implement a fine-grained runtime PM, whereby they
> > > runtime-suspend and -resume the host interface on each transfer. This can
> > > negatively affect performance, if the user was trying to transfer data
> > > blocks back-to-back. This patch adds a PM QoS constraint to avoid such a
> > > throughput reduction. This constraint prevents runtime-suspending the
> > > device, if the expected wakeup latency is larger than 100us.
> > > 
> > > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> > 
> > I think host drivers can use autosuspend with some ms delay for this instead.
> > This will mean that requests coming in bursts will not be affected (well only
> > the first request in the burst will suffer from the runtime resume latency).
> 
> I think, Rafael is the best person to explain, why exactly this is not 
> desired. In short, this is the wrong location to make such decisions and 
> to define these criteria. The only thing, that the driver may be aware of 
> is how quickly it wants to be able to wake up, if it got suspended. And 
> it's already the PM subsystem, that has to decide, whether it can satisfy 
> this requirement or not. Rafael will correct me, if my explanation is 
> wrong.

It is correct.  More specifically, the problem is, for example, that there
may be two different low-power states of the system that may be entered
when the device is suspended, one of which is relatively shallow, but
having a low exit latency, while the other one is deep with a correspondingly
longer exit latency.  This happens when the device is a member of a power
domain that may be turned off entirely when it is suspended under certain
conditions and at the same time the device's individual clock may be turned
off and on almost instantaneously.  In that case there's no reason to avoid
suspending the device whenever possible, allowing its clock to be turned
off to save energy, but there may be a good reason to avoid turning off the
power domain due to latency constraints.  No amount of playing with
autosuspends is going to help here, unless the driver is aware of the exact
system hardware configuration it is in, which is rather impractical if you
think of universal drivers (such that may be used with different platforms,
for example).

Thanks,
Rafael

^ permalink raw reply

* [PATCH 05/05] ARM: mach-shmobile: Marzen LAN89218 support
From: Magnus Damm @ 2011-12-13 16:36 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Add LAN89218 support to the r8a7779 Marzen board.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/arm/mach-shmobile/board-marzen.c |   36 +++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

--- 0022/arch/arm/mach-shmobile/board-marzen.c
+++ work/arch/arm/mach-shmobile/board-marzen.c	2011-12-14 00:12:32.000000000 +0900
@@ -27,6 +27,7 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/dma-mapping.h>
+#include <linux/smsc911x.h>
 #include <mach/hardware.h>
 #include <mach/r8a7779.h>
 #include <mach/common.h>
@@ -37,7 +38,38 @@
 #include <asm/hardware/gic.h>
 #include <asm/traps.h>
 
+/* SMSC LAN89218 */
+static struct resource smsc911x_resources[] = {
+	[0] = {
+		.start		= 0x18000000, /* ExCS0 */
+		.end		= 0x180000ff, /* A1->A7 */
+		.flags		= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start		= gic_spi(28), /* IRQ 1 */
+		.flags		= IORESOURCE_IRQ,
+	},
+};
+
+static struct smsc911x_platform_config smsc911x_platdata = {
+	.flags		= SMSC911X_USE_32BIT, /* 32-bit SW on 16-bit HW bus */
+	.phy_interface	= PHY_INTERFACE_MODE_MII,
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
+};
+
+static struct platform_device eth_device = {
+	.name		= "smsc911x",
+	.id		= 0,
+	.dev  = {
+		.platform_data = &smsc911x_platdata,
+	},
+	.resource	= smsc911x_resources,
+	.num_resources	= ARRAY_SIZE(smsc911x_resources),
+};
+
 static struct platform_device *marzen_devices[] __initdata = {
+	&eth_device,
 };
 
 static struct map_desc marzen_io_desc[] __initdata = {
@@ -95,6 +127,10 @@ static void __init marzen_init(void)
 	gpio_request(GPIO_FN_TX4, NULL);
 	gpio_request(GPIO_FN_RX4, NULL);
 
+	/* LAN89218 */
+	gpio_request(GPIO_FN_EX_CS0, NULL); /* nCS */
+	gpio_request(GPIO_FN_IRQ1_B, NULL); /* IRQ + PME */
+
 	r8a7779_add_standard_devices();
 	platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
 }

^ permalink raw reply

* [PATCH 04/05] ARM: mach-shmobile: Marzen SCIF2/SCIF4 support
From: Magnus Damm @ 2011-12-13 16:36 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Add SCIF2 and SCIF4 pin configuration code to
the r8a7779 Marzen board.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 arch/arm/mach-shmobile/board-marzen.c |    9 +++++++++
 1 file changed, 9 insertions(+)

--- 0020/arch/arm/mach-shmobile/board-marzen.c
+++ work/arch/arm/mach-shmobile/board-marzen.c	2011-12-14 00:06:37.000000000 +0900
@@ -25,6 +25,7 @@
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
 #include <linux/dma-mapping.h>
 #include <mach/hardware.h>
 #include <mach/r8a7779.h>
@@ -86,6 +87,14 @@ static void __init marzen_init(void)
 {
 	r8a7779_pinmux_init();
 
+	/* SCIF2 (CN18: DEBUG0) */
+	gpio_request(GPIO_FN_TX2_C, NULL);
+	gpio_request(GPIO_FN_RX2_C, NULL);
+
+	/* SCIF4 (CN19: DEBUG1) */
+	gpio_request(GPIO_FN_TX4, NULL);
+	gpio_request(GPIO_FN_RX4, NULL);
+
 	r8a7779_add_standard_devices();
 	platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
 }

^ permalink raw reply

* [PATCH 02/05] ARM: mach-shmobile: r8a7779 PFC GPIO-only support V2
From: Magnus Damm @ 2011-12-13 16:36 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Add GPIO-only r8a7779 PFC support V2. 

Only regular GPIOs are supported at this time. GPIO_FN are not
supported because they require variable bit width support in be
the shared pfc code.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 Chances since V1:
 - Make use of separately submitted ioremap() and PMMR patches
 - Register window base address fixes

 arch/arm/mach-shmobile/Kconfig                |    2 
 arch/arm/mach-shmobile/Makefile               |    1 
 arch/arm/mach-shmobile/board-marzen.c         |    2 
 arch/arm/mach-shmobile/include/mach/common.h  |    1 
 arch/arm/mach-shmobile/include/mach/r8a7779.h |   63 +++
 arch/arm/mach-shmobile/pfc-r8a7779.c          |  472 +++++++++++++++++++++++++
 6 files changed, 540 insertions(+), 1 deletion(-)

--- 0019/arch/arm/mach-shmobile/Kconfig
+++ work/arch/arm/mach-shmobile/Kconfig	2011-12-13 12:13:38.000000000 +0900
@@ -33,6 +33,7 @@ config ARCH_R8A7779
 	select CPU_V7
 	select SH_CLK_CPG
 	select ARM_GIC
+	select ARCH_WANT_OPTIONAL_GPIOLIB
 
 comment "SH-Mobile Board Type"
 
@@ -84,6 +85,7 @@ config MACH_KOTA2
 config MACH_MARZEN
 	bool "MARZEN board"
 	depends on ARCH_R8A7779
+	select ARCH_REQUIRE_GPIOLIB
 
 comment "SH-Mobile System Configuration"
 
--- 0019/arch/arm/mach-shmobile/Makefile
+++ work/arch/arm/mach-shmobile/Makefile	2011-12-13 12:13:38.000000000 +0900
@@ -24,6 +24,7 @@ pfc-$(CONFIG_ARCH_SH7367)	+= pfc-sh7367.
 pfc-$(CONFIG_ARCH_SH7377)	+= pfc-sh7377.o
 pfc-$(CONFIG_ARCH_SH7372)	+= pfc-sh7372.o
 pfc-$(CONFIG_ARCH_SH73A0)	+= pfc-sh73a0.o
+pfc-$(CONFIG_ARCH_R8A7779)	+= pfc-r8a7779.o
 
 # IRQ objects
 obj-$(CONFIG_ARCH_SH7367)	+= entry-intc.o
--- 0019/arch/arm/mach-shmobile/board-marzen.c
+++ work/arch/arm/mach-shmobile/board-marzen.c	2011-12-13 12:13:38.000000000 +0900
@@ -84,6 +84,8 @@ static void __init marzen_init_early(voi
 
 static void __init marzen_init(void)
 {
+	r8a7779_pinmux_init();
+
 	r8a7779_add_standard_devices();
 	platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
 }
--- 0019/arch/arm/mach-shmobile/include/mach/common.h
+++ work/arch/arm/mach-shmobile/include/mach/common.h	2011-12-13 12:13:38.000000000 +0900
@@ -57,5 +57,6 @@ extern void r8a7779_init_irq(void);
 extern void r8a7779_add_early_devices(void);
 extern void r8a7779_add_standard_devices(void);
 extern void r8a7779_clock_init(void);
+extern void r8a7779_pinmux_init(void);
 
 #endif /* __ARCH_MACH_COMMON_H */
--- 0019/arch/arm/mach-shmobile/include/mach/r8a7779.h
+++ work/arch/arm/mach-shmobile/include/mach/r8a7779.h	2011-12-13 12:13:38.000000000 +0900
@@ -1,6 +1,67 @@
 #ifndef __ASM_R8A7779_H__
 #define __ASM_R8A7779_H__
 
-/* Nothing at this point */
+/* Pin Function Controller:
+ * GPIO_GP_x_x - GPIO mapped to real I/O pin on CPU
+ */
+enum {
+	GPIO_GP_0_0, GPIO_GP_0_1, GPIO_GP_0_2, GPIO_GP_0_3,
+	GPIO_GP_0_4, GPIO_GP_0_5, GPIO_GP_0_6, GPIO_GP_0_7,
+	GPIO_GP_0_8, GPIO_GP_0_9, GPIO_GP_0_10, GPIO_GP_0_11,
+	GPIO_GP_0_12, GPIO_GP_0_13, GPIO_GP_0_14, GPIO_GP_0_15,
+	GPIO_GP_0_16, GPIO_GP_0_17, GPIO_GP_0_18, GPIO_GP_0_19,
+	GPIO_GP_0_20, GPIO_GP_0_21, GPIO_GP_0_22, GPIO_GP_0_23,
+	GPIO_GP_0_24, GPIO_GP_0_25, GPIO_GP_0_26, GPIO_GP_0_27,
+	GPIO_GP_0_28, GPIO_GP_0_29, GPIO_GP_0_30, GPIO_GP_0_31,
+
+	GPIO_GP_1_0, GPIO_GP_1_1, GPIO_GP_1_2, GPIO_GP_1_3,
+	GPIO_GP_1_4, GPIO_GP_1_5, GPIO_GP_1_6, GPIO_GP_1_7,
+	GPIO_GP_1_8, GPIO_GP_1_9, GPIO_GP_1_10, GPIO_GP_1_11,
+	GPIO_GP_1_12, GPIO_GP_1_13, GPIO_GP_1_14, GPIO_GP_1_15,
+	GPIO_GP_1_16, GPIO_GP_1_17, GPIO_GP_1_18, GPIO_GP_1_19,
+	GPIO_GP_1_20, GPIO_GP_1_21, GPIO_GP_1_22, GPIO_GP_1_23,
+	GPIO_GP_1_24, GPIO_GP_1_25, GPIO_GP_1_26, GPIO_GP_1_27,
+	GPIO_GP_1_28, GPIO_GP_1_29, GPIO_GP_1_30, GPIO_GP_1_31,
+
+	GPIO_GP_2_0, GPIO_GP_2_1, GPIO_GP_2_2, GPIO_GP_2_3,
+	GPIO_GP_2_4, GPIO_GP_2_5, GPIO_GP_2_6, GPIO_GP_2_7,
+	GPIO_GP_2_8, GPIO_GP_2_9, GPIO_GP_2_10, GPIO_GP_2_11,
+	GPIO_GP_2_12, GPIO_GP_2_13, GPIO_GP_2_14, GPIO_GP_2_15,
+	GPIO_GP_2_16, GPIO_GP_2_17, GPIO_GP_2_18, GPIO_GP_2_19,
+	GPIO_GP_2_20, GPIO_GP_2_21, GPIO_GP_2_22, GPIO_GP_2_23,
+	GPIO_GP_2_24, GPIO_GP_2_25, GPIO_GP_2_26, GPIO_GP_2_27,
+	GPIO_GP_2_28, GPIO_GP_2_29, GPIO_GP_2_30, GPIO_GP_2_31,
+
+	GPIO_GP_3_0, GPIO_GP_3_1, GPIO_GP_3_2, GPIO_GP_3_3,
+	GPIO_GP_3_4, GPIO_GP_3_5, GPIO_GP_3_6, GPIO_GP_3_7,
+	GPIO_GP_3_8, GPIO_GP_3_9, GPIO_GP_3_10, GPIO_GP_3_11,
+	GPIO_GP_3_12, GPIO_GP_3_13, GPIO_GP_3_14, GPIO_GP_3_15,
+	GPIO_GP_3_16, GPIO_GP_3_17, GPIO_GP_3_18, GPIO_GP_3_19,
+	GPIO_GP_3_20, GPIO_GP_3_21, GPIO_GP_3_22, GPIO_GP_3_23,
+	GPIO_GP_3_24, GPIO_GP_3_25, GPIO_GP_3_26, GPIO_GP_3_27,
+	GPIO_GP_3_28, GPIO_GP_3_29, GPIO_GP_3_30, GPIO_GP_3_31,
+
+	GPIO_GP_4_0, GPIO_GP_4_1, GPIO_GP_4_2, GPIO_GP_4_3,
+	GPIO_GP_4_4, GPIO_GP_4_5, GPIO_GP_4_6, GPIO_GP_4_7,
+	GPIO_GP_4_8, GPIO_GP_4_9, GPIO_GP_4_10, GPIO_GP_4_11,
+	GPIO_GP_4_12, GPIO_GP_4_13, GPIO_GP_4_14, GPIO_GP_4_15,
+	GPIO_GP_4_16, GPIO_GP_4_17, GPIO_GP_4_18, GPIO_GP_4_19,
+	GPIO_GP_4_20, GPIO_GP_4_21, GPIO_GP_4_22, GPIO_GP_4_23,
+	GPIO_GP_4_24, GPIO_GP_4_25, GPIO_GP_4_26, GPIO_GP_4_27,
+	GPIO_GP_4_28, GPIO_GP_4_29, GPIO_GP_4_30, GPIO_GP_4_31,
+
+	GPIO_GP_5_0, GPIO_GP_5_1, GPIO_GP_5_2, GPIO_GP_5_3,
+	GPIO_GP_5_4, GPIO_GP_5_5, GPIO_GP_5_6, GPIO_GP_5_7,
+	GPIO_GP_5_8, GPIO_GP_5_9, GPIO_GP_5_10, GPIO_GP_5_11,
+	GPIO_GP_5_12, GPIO_GP_5_13, GPIO_GP_5_14, GPIO_GP_5_15,
+	GPIO_GP_5_16, GPIO_GP_5_17, GPIO_GP_5_18, GPIO_GP_5_19,
+	GPIO_GP_5_20, GPIO_GP_5_21, GPIO_GP_5_22, GPIO_GP_5_23,
+	GPIO_GP_5_24, GPIO_GP_5_25, GPIO_GP_5_26, GPIO_GP_5_27,
+	GPIO_GP_5_28, GPIO_GP_5_29, GPIO_GP_5_30, GPIO_GP_5_31,
+
+	GPIO_GP_6_0, GPIO_GP_6_1, GPIO_GP_6_2, GPIO_GP_6_3,
+	GPIO_GP_6_4, GPIO_GP_6_5, GPIO_GP_6_6, GPIO_GP_6_7,
+	GPIO_GP_6_8,
+};
 
 #endif /* __ASM_R8A7779_H__ */
--- /dev/null
+++ work/arch/arm/mach-shmobile/pfc-r8a7779.c	2011-12-13 12:15:57.000000000 +0900
@@ -0,0 +1,472 @@
+/*
+ * r8a7779 processor support - PFC hardware block
+ *
+ * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011  Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/ioport.h>
+#include <mach/r8a7779.h>
+
+#define CPU_32_PORT(fn, pfx, sfx)				\
+	PORT_10(fn, pfx, sfx), PORT_10(fn, pfx##1, sfx),	\
+	PORT_10(fn, pfx##2, sfx), PORT_1(fn, pfx##30, sfx),	\
+	PORT_1(fn, pfx##31, sfx)
+
+#define CPU_32_PORT6(fn, pfx, sfx)				\
+	PORT_1(fn, pfx##0, sfx), PORT_1(fn, pfx##1, sfx),	\
+	PORT_1(fn, pfx##2, sfx), PORT_1(fn, pfx##3, sfx),	\
+	PORT_1(fn, pfx##4, sfx), PORT_1(fn, pfx##5, sfx),	\
+	PORT_1(fn, pfx##6, sfx), PORT_1(fn, pfx##7, sfx),	\
+	PORT_1(fn, pfx##8, sfx)
+
+#define CPU_ALL_PORT(fn, pfx, sfx)				\
+	CPU_32_PORT(fn, pfx##_0_, sfx),				\
+	CPU_32_PORT(fn, pfx##_1_, sfx),				\
+	CPU_32_PORT(fn, pfx##_2_, sfx),				\
+	CPU_32_PORT(fn, pfx##_3_, sfx),				\
+	CPU_32_PORT(fn, pfx##_4_, sfx),				\
+	CPU_32_PORT(fn, pfx##_5_, sfx),				\
+	CPU_32_PORT6(fn, pfx##_6_, sfx)
+
+#define _GP_GPIO(pfx, sfx) PINMUX_GPIO(GPIO_GP##pfx, GP##pfx##_DATA)
+#define _GP_DATA(pfx, sfx) PINMUX_DATA(GP##pfx##_DATA, GP##pfx##_FN,	\
+				       GP##pfx##_IN, GP##pfx##_OUT)
+
+#define _GP_INOUTSEL(pfx, sfx) GP##pfx##_IN, GP##pfx##_OUT
+#define _GP_INDT(pfx, sfx) GP##pfx##_DATA
+
+#define GP_ALL(str)	CPU_ALL_PORT(_PORT_ALL, GP, str)
+#define PINMUX_GPIO_GP_ALL()	CPU_ALL_PORT(_GP_GPIO, , unused)
+#define PINMUX_DATA_GP_ALL()	CPU_ALL_PORT(_GP_DATA, , unused)
+
+
+#define PORT_10_REV(fn, pfx, sfx)				\
+	PORT_1(fn, pfx##9, sfx), PORT_1(fn, pfx##8, sfx),	\
+	PORT_1(fn, pfx##7, sfx), PORT_1(fn, pfx##6, sfx),	\
+	PORT_1(fn, pfx##5, sfx), PORT_1(fn, pfx##4, sfx),	\
+	PORT_1(fn, pfx##3, sfx), PORT_1(fn, pfx##2, sfx),	\
+	PORT_1(fn, pfx##1, sfx), PORT_1(fn, pfx##0, sfx)
+
+#define CPU_32_PORT_REV(fn, pfx, sfx)					\
+	PORT_1(fn, pfx##31, sfx), PORT_1(fn, pfx##30, sfx),		\
+	PORT_10_REV(fn, pfx##2, sfx), PORT_10_REV(fn, pfx##1, sfx),	\
+	PORT_10_REV(fn, pfx, sfx)
+
+#define GP_INOUTSEL(bank) CPU_32_PORT_REV(_GP_INOUTSEL, _##bank##_, unused)
+#define GP_INDT(bank) CPU_32_PORT_REV(_GP_INDT, _##bank##_, unused)
+
+enum {
+	PINMUX_RESERVED = 0,
+
+	PINMUX_DATA_BEGIN,
+	GP_ALL(DATA), /* GP_0_0_DATA -> GP_6_8_DATA */
+	PINMUX_DATA_END,
+
+	PINMUX_INPUT_BEGIN,
+	GP_ALL(IN), /* GP_0_0_IN -> GP_6_8_IN */
+	PINMUX_INPUT_END,
+
+	PINMUX_OUTPUT_BEGIN,
+	GP_ALL(OUT), /* GP_0_0_OUT -> GP_6_8_OUT */
+	PINMUX_OUTPUT_END,
+
+	PINMUX_FUNCTION_BEGIN,
+	GP_ALL(FN), /* GP_0_0_FN -> GP_6_8_FN */
+
+	/* GPSR0 */
+	FN_AVS1, FN_AVS2, FN_IP0_7_6, FN_A17,
+	FN_A18, FN_A19, FN_IP0_9_8, FN_IP0_11_10,
+	FN_IP0_13_12, FN_IP0_15_14, FN_IP0_18_16, FN_IP0_22_19,
+	FN_IP0_24_23, FN_IP0_25, FN_IP0_27_26, FN_IP1_1_0,
+	FN_IP1_3_2, FN_IP1_6_4, FN_IP1_10_7, FN_IP1_14_11,
+	FN_IP1_18_15, FN_IP0_5_3, FN_IP0_30_28, FN_IP2_18_16,
+	FN_IP2_21_19, FN_IP2_30_28, FN_IP3_2_0, FN_IP3_11_9,
+	FN_IP3_14_12, FN_IP3_22_21, FN_IP3_26_24, FN_IP3_31_29,
+
+	/* GPSR1 */
+	FN_IP4_1_0, FN_IP4_4_2, FN_IP4_7_5, FN_IP4_10_8,
+	FN_IP4_11, FN_IP4_12, FN_IP4_13, FN_IP4_14,
+	FN_IP4_15, FN_IP4_16, FN_IP4_19_17, FN_IP4_22_20,
+	FN_IP4_23, FN_IP4_24, FN_IP4_25, FN_IP4_26,
+	FN_IP4_27, FN_IP4_28, FN_IP4_31_29, FN_IP5_2_0,
+	FN_IP5_3, FN_IP5_4, FN_IP5_5, FN_IP5_6,
+	FN_IP5_7, FN_IP5_8, FN_IP5_10_9, FN_IP5_12_11,
+	FN_IP5_14_13, FN_IP5_16_15, FN_IP5_20_17, FN_IP5_23_21,
+
+	/* GPSR2 */
+	FN_IP5_27_24, FN_IP8_20, FN_IP8_22_21, FN_IP8_24_23,
+	FN_IP8_27_25, FN_IP8_30_28, FN_IP9_1_0, FN_IP9_3_2,
+	FN_IP9_4, FN_IP9_5, FN_IP9_6, FN_IP9_7,
+	FN_IP9_9_8, FN_IP9_11_10, FN_IP9_13_12, FN_IP9_15_14,
+	FN_IP9_18_16, FN_IP9_21_19, FN_IP9_23_22, FN_IP9_25_24,
+	FN_IP9_27_26, FN_IP9_29_28, FN_IP10_2_0, FN_IP10_5_3,
+	FN_IP10_8_6, FN_IP10_11_9, FN_IP10_14_12, FN_IP10_17_15,
+	FN_IP10_20_18, FN_IP10_23_21, FN_IP10_25_24, FN_IP10_28_26,
+
+	/* GPSR3 */
+	FN_IP10_31_29, FN_IP11_2_0, FN_IP11_5_3, FN_IP11_8_6,
+	FN_IP11_11_9, FN_IP11_14_12, FN_IP11_17_15, FN_IP11_20_18,
+	FN_IP11_23_21, FN_IP11_26_24, FN_IP11_29_27, FN_IP12_2_0,
+	FN_IP12_5_3, FN_IP12_8_6, FN_IP12_11_9, FN_IP12_14_12,
+	FN_IP12_17_15, FN_IP7_16_15, FN_IP7_18_17, FN_IP7_28_27,
+	FN_IP7_30_29, FN_IP7_20_19, FN_IP7_22_21, FN_IP7_24_23,
+	FN_IP7_26_25, FN_IP1_20_19, FN_IP1_22_21, FN_IP1_24_23,
+	FN_IP5_28, FN_IP5_30_29, FN_IP6_1_0, FN_IP6_3_2,
+
+	/* GPSR4 */
+	FN_IP6_5_4, FN_IP6_7_6, FN_IP6_8, FN_IP6_11_9,
+	FN_IP6_14_12, FN_IP6_17_15, FN_IP6_19_18, FN_IP6_22_20,
+	FN_IP6_24_23, FN_IP6_26_25, FN_IP6_30_29, FN_IP7_1_0,
+	FN_IP7_3_2, FN_IP7_6_4, FN_IP7_9_7, FN_IP7_12_10,
+	FN_IP7_14_13, FN_IP2_7_4, FN_IP2_11_8, FN_IP2_15_12,
+	FN_IP1_28_25, FN_IP2_3_0, FN_IP8_3_0, FN_IP8_7_4,
+	FN_IP8_11_8, FN_IP8_15_12, FN_PENC0, FN_PENC1,
+	FN_IP0_2_0, FN_IP8_17_16, FN_IP8_18, FN_IP8_19,
+
+	/* GPSR5 */
+	FN_A1, FN_A2, FN_A3, FN_A4,
+	FN_A5, FN_A6, FN_A7, FN_A8,
+	FN_A9, FN_A10, FN_A11, FN_A12,
+	FN_A13, FN_A14, FN_A15, FN_A16,
+	FN_RD, FN_WE0, FN_WE1, FN_EX_WAIT0,
+	FN_IP3_23, FN_IP3_27, FN_IP3_28, FN_IP2_22,
+	FN_IP2_23, FN_IP2_24, FN_IP2_25, FN_IP2_26,
+	FN_IP2_27, FN_IP3_3, FN_IP3_4, FN_IP3_5,
+
+	/* GPSR6 */
+	FN_IP3_6, FN_IP3_7, FN_IP3_8, FN_IP3_15,
+	FN_IP3_16, FN_IP3_17, FN_IP3_18, FN_IP3_19,
+	FN_IP3_20,
+	PINMUX_FUNCTION_END,
+};
+
+static pinmux_enum_t pinmux_data[] = {
+	PINMUX_DATA_GP_ALL(), /* PINMUX_DATA(GP_M_N_DATA, GP_M_N_FN...), */
+};
+
+static struct pinmux_gpio pinmux_gpios[] = {
+	PINMUX_GPIO_GP_ALL(),
+};
+
+static struct pinmux_cfg_reg pinmux_config_regs[] = {
+	{ PINMUX_CFG_REG("GPSR0", 0xfffc0004, 32, 1) {
+		GP_0_31_FN, FN_IP3_31_29,
+		GP_0_30_FN, FN_IP3_26_24,
+		GP_0_29_FN, FN_IP3_22_21,
+		GP_0_28_FN, FN_IP3_14_12,
+		GP_0_27_FN, FN_IP3_11_9,
+		GP_0_26_FN, FN_IP3_2_0,
+		GP_0_25_FN, FN_IP2_30_28,
+		GP_0_24_FN, FN_IP2_21_19,
+		GP_0_23_FN, FN_IP2_18_16,
+		GP_0_22_FN, FN_IP0_30_28,
+		GP_0_21_FN, FN_IP0_5_3,
+		GP_0_20_FN, FN_IP1_18_15,
+		GP_0_19_FN, FN_IP1_14_11,
+		GP_0_18_FN, FN_IP1_10_7,
+		GP_0_17_FN, FN_IP1_6_4,
+		GP_0_16_FN, FN_IP1_3_2,
+		GP_0_15_FN, FN_IP1_1_0,
+		GP_0_14_FN, FN_IP0_27_26,
+		GP_0_13_FN, FN_IP0_25,
+		GP_0_12_FN, FN_IP0_24_23,
+		GP_0_11_FN, FN_IP0_22_19,
+		GP_0_10_FN, FN_IP0_18_16,
+		GP_0_9_FN, FN_IP0_15_14,
+		GP_0_8_FN, FN_IP0_13_12,
+		GP_0_7_FN, FN_IP0_11_10,
+		GP_0_6_FN, FN_IP0_9_8,
+		GP_0_5_FN, FN_A19,
+		GP_0_4_FN, FN_A18,
+		GP_0_3_FN, FN_A17,
+		GP_0_2_FN, FN_IP0_7_6,
+		GP_0_1_FN, FN_AVS2,
+		GP_0_0_FN, FN_AVS1 }
+	},
+	{ PINMUX_CFG_REG("GPSR1", 0xfffc0008, 32, 1) {
+		GP_1_31_FN, FN_IP5_23_21,
+		GP_1_30_FN, FN_IP5_20_17,
+		GP_1_29_FN, FN_IP5_16_15,
+		GP_1_28_FN, FN_IP5_14_13,
+		GP_1_27_FN, FN_IP5_12_11,
+		GP_1_26_FN, FN_IP5_10_9,
+		GP_1_25_FN, FN_IP5_8,
+		GP_1_24_FN, FN_IP5_7,
+		GP_1_23_FN, FN_IP5_6,
+		GP_1_22_FN, FN_IP5_5,
+		GP_1_21_FN, FN_IP5_4,
+		GP_1_20_FN, FN_IP5_3,
+		GP_1_19_FN, FN_IP5_2_0,
+		GP_1_18_FN, FN_IP4_31_29,
+		GP_1_17_FN, FN_IP4_28,
+		GP_1_16_FN, FN_IP4_27,
+		GP_1_15_FN, FN_IP4_26,
+		GP_1_14_FN, FN_IP4_25,
+		GP_1_13_FN, FN_IP4_24,
+		GP_1_12_FN, FN_IP4_23,
+		GP_1_11_FN, FN_IP4_22_20,
+		GP_1_10_FN, FN_IP4_19_17,
+		GP_1_9_FN, FN_IP4_16,
+		GP_1_8_FN, FN_IP4_15,
+		GP_1_7_FN, FN_IP4_14,
+		GP_1_6_FN, FN_IP4_13,
+		GP_1_5_FN, FN_IP4_12,
+		GP_1_4_FN, FN_IP4_11,
+		GP_1_3_FN, FN_IP4_10_8,
+		GP_1_2_FN, FN_IP4_7_5,
+		GP_1_1_FN, FN_IP4_4_2,
+		GP_1_0_FN, FN_IP4_1_0 }
+	},
+	{ PINMUX_CFG_REG("GPSR2", 0xfffc000c, 32, 1) {
+		GP_2_31_FN, FN_IP10_28_26,
+		GP_2_30_FN, FN_IP10_25_24,
+		GP_2_29_FN, FN_IP10_23_21,
+		GP_2_28_FN, FN_IP10_20_18,
+		GP_2_27_FN, FN_IP10_17_15,
+		GP_2_26_FN, FN_IP10_14_12,
+		GP_2_25_FN, FN_IP10_11_9,
+		GP_2_24_FN, FN_IP10_8_6,
+		GP_2_23_FN, FN_IP10_5_3,
+		GP_2_22_FN, FN_IP10_2_0,
+		GP_2_21_FN, FN_IP9_29_28,
+		GP_2_20_FN, FN_IP9_27_26,
+		GP_2_19_FN, FN_IP9_25_24,
+		GP_2_18_FN, FN_IP9_23_22,
+		GP_2_17_FN, FN_IP9_21_19,
+		GP_2_16_FN, FN_IP9_18_16,
+		GP_2_15_FN, FN_IP9_15_14,
+		GP_2_14_FN, FN_IP9_13_12,
+		GP_2_13_FN, FN_IP9_11_10,
+		GP_2_12_FN, FN_IP9_9_8,
+		GP_2_11_FN, FN_IP9_7,
+		GP_2_10_FN, FN_IP9_6,
+		GP_2_9_FN, FN_IP9_5,
+		GP_2_8_FN, FN_IP9_4,
+		GP_2_7_FN, FN_IP9_3_2,
+		GP_2_6_FN, FN_IP9_1_0,
+		GP_2_5_FN, FN_IP8_30_28,
+		GP_2_4_FN, FN_IP8_27_25,
+		GP_2_3_FN, FN_IP8_24_23,
+		GP_2_2_FN, FN_IP8_22_21,
+		GP_2_1_FN, FN_IP8_20,
+		GP_2_0_FN, FN_IP5_27_24 }
+	},
+	{ PINMUX_CFG_REG("GPSR3", 0xfffc0010, 32, 1) {
+		GP_3_31_FN, FN_IP6_3_2,
+		GP_3_30_FN, FN_IP6_1_0,
+		GP_3_29_FN, FN_IP5_30_29,
+		GP_3_28_FN, FN_IP5_28,
+		GP_3_27_FN, FN_IP1_24_23,
+		GP_3_26_FN, FN_IP1_22_21,
+		GP_3_25_FN, FN_IP1_20_19,
+		GP_3_24_FN, FN_IP7_26_25,
+		GP_3_23_FN, FN_IP7_24_23,
+		GP_3_22_FN, FN_IP7_22_21,
+		GP_3_21_FN, FN_IP7_20_19,
+		GP_3_20_FN, FN_IP7_30_29,
+		GP_3_19_FN, FN_IP7_28_27,
+		GP_3_18_FN, FN_IP7_18_17,
+		GP_3_17_FN, FN_IP7_16_15,
+		GP_3_16_FN, FN_IP12_17_15,
+		GP_3_15_FN, FN_IP12_14_12,
+		GP_3_14_FN, FN_IP12_11_9,
+		GP_3_13_FN, FN_IP12_8_6,
+		GP_3_12_FN, FN_IP12_5_3,
+		GP_3_11_FN, FN_IP12_2_0,
+		GP_3_10_FN, FN_IP11_29_27,
+		GP_3_9_FN, FN_IP11_26_24,
+		GP_3_8_FN, FN_IP11_23_21,
+		GP_3_7_FN, FN_IP11_20_18,
+		GP_3_6_FN, FN_IP11_17_15,
+		GP_3_5_FN, FN_IP11_14_12,
+		GP_3_4_FN, FN_IP11_11_9,
+		GP_3_3_FN, FN_IP11_8_6,
+		GP_3_2_FN, FN_IP11_5_3,
+		GP_3_1_FN, FN_IP11_2_0,
+		GP_3_0_FN, FN_IP10_31_29 }
+	},
+	{ PINMUX_CFG_REG("GPSR4", 0xfffc0014, 32, 1) {
+		GP_4_31_FN, FN_IP8_19,
+		GP_4_30_FN, FN_IP8_18,
+		GP_4_29_FN, FN_IP8_17_16,
+		GP_4_28_FN, FN_IP0_2_0,
+		GP_4_27_FN, FN_PENC1,
+		GP_4_26_FN, FN_PENC0,
+		GP_4_25_FN, FN_IP8_15_12,
+		GP_4_24_FN, FN_IP8_11_8,
+		GP_4_23_FN, FN_IP8_7_4,
+		GP_4_22_FN, FN_IP8_3_0,
+		GP_4_21_FN, FN_IP2_3_0,
+		GP_4_20_FN, FN_IP1_28_25,
+		GP_4_19_FN, FN_IP2_15_12,
+		GP_4_18_FN, FN_IP2_11_8,
+		GP_4_17_FN, FN_IP2_7_4,
+		GP_4_16_FN, FN_IP7_14_13,
+		GP_4_15_FN, FN_IP7_12_10,
+		GP_4_14_FN, FN_IP7_9_7,
+		GP_4_13_FN, FN_IP7_6_4,
+		GP_4_12_FN, FN_IP7_3_2,
+		GP_4_11_FN, FN_IP7_1_0,
+		GP_4_10_FN, FN_IP6_30_29,
+		GP_4_9_FN, FN_IP6_26_25,
+		GP_4_8_FN, FN_IP6_24_23,
+		GP_4_7_FN, FN_IP6_22_20,
+		GP_4_6_FN, FN_IP6_19_18,
+		GP_4_5_FN, FN_IP6_17_15,
+		GP_4_4_FN, FN_IP6_14_12,
+		GP_4_3_FN, FN_IP6_11_9,
+		GP_4_2_FN, FN_IP6_8,
+		GP_4_1_FN, FN_IP6_7_6,
+		GP_4_0_FN, FN_IP6_5_4 }
+	},
+	{ PINMUX_CFG_REG("GPSR5", 0xfffc0018, 32, 1) {
+		GP_5_31_FN, FN_IP3_5,
+		GP_5_30_FN, FN_IP3_4,
+		GP_5_29_FN, FN_IP3_3,
+		GP_5_28_FN, FN_IP2_27,
+		GP_5_27_FN, FN_IP2_26,
+		GP_5_26_FN, FN_IP2_25,
+		GP_5_25_FN, FN_IP2_24,
+		GP_5_24_FN, FN_IP2_23,
+		GP_5_23_FN, FN_IP2_22,
+		GP_5_22_FN, FN_IP3_28,
+		GP_5_21_FN, FN_IP3_27,
+		GP_5_20_FN, FN_IP3_23,
+		GP_5_19_FN, FN_EX_WAIT0,
+		GP_5_18_FN, FN_WE1,
+		GP_5_17_FN, FN_WE0,
+		GP_5_16_FN, FN_RD,
+		GP_5_15_FN, FN_A16,
+		GP_5_14_FN, FN_A15,
+		GP_5_13_FN, FN_A14,
+		GP_5_12_FN, FN_A13,
+		GP_5_11_FN, FN_A12,
+		GP_5_10_FN, FN_A11,
+		GP_5_9_FN, FN_A10,
+		GP_5_8_FN, FN_A9,
+		GP_5_7_FN, FN_A8,
+		GP_5_6_FN, FN_A7,
+		GP_5_5_FN, FN_A6,
+		GP_5_4_FN, FN_A5,
+		GP_5_3_FN, FN_A4,
+		GP_5_2_FN, FN_A3,
+		GP_5_1_FN, FN_A2,
+		GP_5_0_FN, FN_A1 }
+	},
+	{ PINMUX_CFG_REG("GPSR6", 0xfffc001c, 32, 1) {
+		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		GP_6_8_FN, FN_IP3_20,
+		GP_6_7_FN, FN_IP3_19,
+		GP_6_6_FN, FN_IP3_18,
+		GP_6_5_FN, FN_IP3_17,
+		GP_6_4_FN, FN_IP3_16,
+		GP_6_3_FN, FN_IP3_15,
+		GP_6_2_FN, FN_IP3_8,
+		GP_6_1_FN, FN_IP3_7,
+		GP_6_0_FN, FN_IP3_6 }
+	},
+	{ PINMUX_CFG_REG("INOUTSEL0", 0xffc40004, 32, 1) { GP_INOUTSEL(0) } },
+	{ PINMUX_CFG_REG("INOUTSEL1", 0xffc41004, 32, 1) { GP_INOUTSEL(1) } },
+	{ PINMUX_CFG_REG("INOUTSEL2", 0xffc42004, 32, 1) { GP_INOUTSEL(2) } },
+	{ PINMUX_CFG_REG("INOUTSEL3", 0xffc43004, 32, 1) { GP_INOUTSEL(3) } },
+	{ PINMUX_CFG_REG("INOUTSEL4", 0xffc44004, 32, 1) { GP_INOUTSEL(4) } },
+	{ PINMUX_CFG_REG("INOUTSEL5", 0xffc45004, 32, 1) { GP_INOUTSEL(5) } },
+	{ PINMUX_CFG_REG("INOUTSEL6", 0xffc46004, 32, 1) {
+		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0,
+		0, 0,
+		0, 0,
+		GP_6_8_IN, GP_6_8_OUT,
+		GP_6_7_IN, GP_6_7_OUT,
+		GP_6_6_IN, GP_6_6_OUT,
+		GP_6_5_IN, GP_6_5_OUT,
+		GP_6_4_IN, GP_6_4_OUT,
+		GP_6_3_IN, GP_6_3_OUT,
+		GP_6_2_IN, GP_6_2_OUT,
+		GP_6_1_IN, GP_6_1_OUT,
+		GP_6_0_IN, GP_6_0_OUT, }
+	},
+	{ },
+};
+
+static struct pinmux_data_reg pinmux_data_regs[] = {
+	{ PINMUX_DATA_REG("INDT0", 0xffc40008, 32) { GP_INDT(0) } },
+	{ PINMUX_DATA_REG("INDT1", 0xffc41008, 32) { GP_INDT(1) } },
+	{ PINMUX_DATA_REG("INDT2", 0xffc42008, 32) { GP_INDT(2) } },
+	{ PINMUX_DATA_REG("INDT3", 0xffc43008, 32) { GP_INDT(3) } },
+	{ PINMUX_DATA_REG("INDT4", 0xffc44008, 32) { GP_INDT(4) } },
+	{ PINMUX_DATA_REG("INDT5", 0xffc45008, 32) { GP_INDT(5) } },
+	{ PINMUX_DATA_REG("INDT6", 0xffc46008, 32) {
+		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0,
+		0, 0, 0, 0, 0, 0, 0, GP_6_8_DATA,
+		GP_6_7_DATA, GP_6_6_DATA, GP_6_5_DATA, GP_6_4_DATA,
+		GP_6_3_DATA, GP_6_2_DATA, GP_6_1_DATA, GP_6_0_DATA }
+	},
+	{ },
+};
+
+static struct resource r8a7779_pfc_resources[] = {
+	[0] = {
+		.start	= 0xfffc0000,
+		.end	= 0xfffc023b,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 0xffc40000,
+		.end	= 0xffc46fff,
+		.flags	= IORESOURCE_MEM,
+	}
+};
+
+static struct pinmux_info r8a7779_pinmux_info = {
+	.name = "r8a7779_pfc",
+
+	.resource = r8a7779_pfc_resources,
+	.num_resources = ARRAY_SIZE(r8a7779_pfc_resources),
+
+	.unlock_reg = 0xfffc0000, /* PMMR */
+
+	.reserved_id = PINMUX_RESERVED,
+	.data = { PINMUX_DATA_BEGIN, PINMUX_DATA_END },
+	.input = { PINMUX_INPUT_BEGIN, PINMUX_INPUT_END },
+	.output = { PINMUX_OUTPUT_BEGIN, PINMUX_OUTPUT_END },
+	.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
+
+	.first_gpio = GPIO_GP_0_0,
+	.last_gpio = GPIO_GP_6_8,
+
+	.gpios = pinmux_gpios,
+	.cfg_regs = pinmux_config_regs,
+	.data_regs = pinmux_data_regs,
+
+	.gpio_data = pinmux_data,
+	.gpio_data_size = ARRAY_SIZE(pinmux_data),
+};
+
+void r8a7779_pinmux_init(void)
+{
+	register_pinmux(&r8a7779_pinmux_info);
+}

^ permalink raw reply

* [PATCH 01/05] ARM: mach-shmobile: r8a7779 and Marzen base support V2
From: Magnus Damm @ 2011-12-13 16:36 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Initial support for the r8a7779 SoC and the Marzen board (V2).

Only SCIF ports and the TMU are supported at this point.

To keep things simple only entity-mapped virt-to-phys mappings
are supported. This forces drivers and other SoC glue code to
make use of ioremap(). We cannot support early serial console
due to virtual address space collisions with the ARM kernel.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 Changes since V1:
 - Nothing, just dropped prototype status.

 arch/arm/mach-shmobile/Kconfig                |   10 +
 arch/arm/mach-shmobile/Makefile               |    3 
 arch/arm/mach-shmobile/board-marzen.c         |  110 +++++++++++
 arch/arm/mach-shmobile/clock-r8a7779.c        |  105 +++++++++++
 arch/arm/mach-shmobile/include/mach/common.h  |    5 
 arch/arm/mach-shmobile/include/mach/r8a7779.h |    6 
 arch/arm/mach-shmobile/intc-r8a7779.c         |   58 ++++++
 arch/arm/mach-shmobile/setup-r8a7779.c        |  231 +++++++++++++++++++++++++
 8 files changed, 528 insertions(+)

--- 0001/arch/arm/mach-shmobile/Kconfig
+++ work/arch/arm/mach-shmobile/Kconfig	2011-12-07 00:36:10.000000000 +0900
@@ -28,6 +28,12 @@ config ARCH_SH73A0
 	select ARM_GIC
 	select I2C
 
+config ARCH_R8A7779
+	bool "R-Car H1 (R8A77790)"
+	select CPU_V7
+	select SH_CLK_CPG
+	select ARM_GIC
+
 comment "SH-Mobile Board Type"
 
 config MACH_G3EVM
@@ -75,6 +81,10 @@ config MACH_KOTA2
 	select ARCH_REQUIRE_GPIOLIB
 	depends on ARCH_SH73A0
 
+config MACH_MARZEN
+	bool "MARZEN board"
+	depends on ARCH_R8A7779
+
 comment "SH-Mobile System Configuration"
 
 menu "Memory configuration"
--- 0001/arch/arm/mach-shmobile/Makefile
+++ work/arch/arm/mach-shmobile/Makefile	2011-12-07 00:37:58.000000000 +0900
@@ -10,6 +10,7 @@ obj-$(CONFIG_ARCH_SH7367)	+= setup-sh736
 obj-$(CONFIG_ARCH_SH7377)	+= setup-sh7377.o clock-sh7377.o intc-sh7377.o
 obj-$(CONFIG_ARCH_SH7372)	+= setup-sh7372.o clock-sh7372.o intc-sh7372.o
 obj-$(CONFIG_ARCH_SH73A0)	+= setup-sh73a0.o clock-sh73a0.o intc-sh73a0.o
+obj-$(CONFIG_ARCH_R8A7779)	+= setup-r8a7779.o clock-r8a7779.o
 
 # SMP objects
 smp-y				:= platsmp.o headsmp.o
@@ -29,6 +30,7 @@ obj-$(CONFIG_ARCH_SH7367)	+= entry-intc.
 obj-$(CONFIG_ARCH_SH7377)	+= entry-intc.o
 obj-$(CONFIG_ARCH_SH7372)	+= entry-intc.o
 obj-$(CONFIG_ARCH_SH73A0)	+= entry-gic.o
+obj-$(CONFIG_ARCH_R8A7779)	+= entry-gic.o intc-r8a7779.o
 
 # PM objects
 obj-$(CONFIG_SUSPEND)		+= suspend.o
@@ -42,6 +44,7 @@ obj-$(CONFIG_MACH_AP4EVB)	+= board-ap4ev
 obj-$(CONFIG_MACH_AG5EVM)	+= board-ag5evm.o
 obj-$(CONFIG_MACH_MACKEREL)	+= board-mackerel.o
 obj-$(CONFIG_MACH_KOTA2)	+= board-kota2.o
+obj-$(CONFIG_MACH_MARZEN)	+= board-marzen.o
 
 # Framework support
 obj-$(CONFIG_SMP)		+= $(smp-y)
--- /dev/null
+++ work/arch/arm/mach-shmobile/board-marzen.c	2011-12-07 00:36:11.000000000 +0900
@@ -0,0 +1,110 @@
+/*
+ * marzen board support
+ *
+ * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011  Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <mach/hardware.h>
+#include <mach/r8a7779.h>
+#include <mach/common.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/time.h>
+#include <asm/hardware/gic.h>
+#include <asm/traps.h>
+
+static struct platform_device *marzen_devices[] __initdata = {
+};
+
+static struct map_desc marzen_io_desc[] __initdata = {
+	/* 2M entity map for 0xf0000000 (MPCORE) */
+	{
+		.virtual	= 0xf0000000,
+		.pfn		= __phys_to_pfn(0xf0000000),
+		.length		= SZ_2M,
+		.type		= MT_DEVICE_NONSHARED
+	},
+	/* 16M entity map for 0xfexxxxxx (DMAC-S/HPBREG/INTC2/LRAM/DBSC) */
+	{
+		.virtual	= 0xfe000000,
+		.pfn		= __phys_to_pfn(0xfe000000),
+		.length		= SZ_16M,
+		.type		= MT_DEVICE_NONSHARED
+	},
+};
+
+static void __init marzen_map_io(void)
+{
+	iotable_init(marzen_io_desc, ARRAY_SIZE(marzen_io_desc));
+}
+
+static void __init marzen_init_early(void)
+{
+	r8a7779_add_early_devices();
+
+	/* Early serial console setup is not included here due to
+	 * memory map collisions. The SCIF serial ports in r8a7779
+	 * are difficult to entity map 1:1 due to collision with the
+	 * virtual memory range used by the coherent DMA code on ARM.
+	 *
+	 * Anyone wanting to debug early can remove UPF_IOREMAP from
+	 * the sh-sci serial console platform data, adjust mapbase
+	 * to a static M:N virt:phys mapping that needs to be added to
+	 * the mappings passed with iotable_init() above.
+	 *
+	 * Then add a call to shmobile_setup_console() from this function.
+	 *
+	 * As a final step pass earlyprint=sh-sci.2,115200 on the kernel
+	 * command line.
+	 */
+}
+
+static void __init marzen_init(void)
+{
+	r8a7779_add_standard_devices();
+	platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
+}
+
+static void __init marzen_timer_init(void)
+{
+	r8a7779_clock_init();
+	shmobile_timer.init();
+	return;
+}
+
+struct sys_timer marzen_timer = {
+	.init	= marzen_timer_init,
+};
+
+MACHINE_START(MARZEN, "marzen")
+	.map_io		= marzen_map_io,
+	.init_early	= marzen_init_early,
+	.nr_irqs	= NR_IRQS_LEGACY,
+	.init_irq	= r8a7779_init_irq,
+	.handle_irq	= shmobile_handle_irq_gic,
+	.init_machine	= marzen_init,
+	.timer		= &marzen_timer,
+MACHINE_END
--- /dev/null
+++ work/arch/arm/mach-shmobile/clock-r8a7779.c	2011-12-07 00:36:11.000000000 +0900
@@ -0,0 +1,105 @@
+/*
+ * r8a7779 clock framework support
+ *
+ * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011  Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/sh_clk.h>
+#include <linux/clkdev.h>
+#include <mach/common.h>
+
+#define FRQMR   0xffc80014
+#define MSTPCR0 0xffc80030
+#define MSTPCR1 0xffc80034
+#define MSTPCR3 0xffc8003c
+#define MSTPSR1 0xffc80044
+#define MSTPSR4 0xffc80048
+#define MSTPSR6 0xffc8004c
+#define MSTPCR4 0xffc80050
+#define MSTPCR5 0xffc80054
+#define MSTPCR6 0xffc80058
+#define MSTPCR7 0xffc80040
+
+/* ioremap() through clock mapping mandatory to avoid
+ * collision with ARM coherent DMA virtual memory range.
+ */
+
+static struct clk_mapping cpg_mapping = {
+	.phys	= 0xffc80000,
+	.len	= 0x80,
+};
+
+static struct clk clkp = {
+	.rate	= 62500000, /* FIXME: shortcut */
+	.flags	= CLK_ENABLE_ON_INIT,
+	.mapping = &cpg_mapping,
+};
+
+static struct clk *main_clks[] = {
+	&clkp,
+};
+
+enum { MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021,
+	MSTP016, MSTP015, MSTP014,
+	MSTP_NR };
+
+#define MSTP(_parent, _reg, _bit, _flags) \
+	SH_CLK_MSTP32(_parent, _reg, _bit, _flags)
+
+static struct clk mstp_clks[MSTP_NR] = {
+	[MSTP026] = MSTP(&clkp, MSTPCR0, 26, 0), /* SCIF0 */
+	[MSTP025] = MSTP(&clkp, MSTPCR0, 25, 0), /* SCIF1 */
+	[MSTP024] = MSTP(&clkp, MSTPCR0, 24, 0), /* SCIF2 */
+	[MSTP023] = MSTP(&clkp, MSTPCR0, 23, 0), /* SCIF3 */
+	[MSTP022] = MSTP(&clkp, MSTPCR0, 22, 0), /* SCIF4 */
+	[MSTP021] = MSTP(&clkp, MSTPCR0, 21, 0), /* SCIF5 */
+	[MSTP016] = MSTP(&clkp, MSTPCR0, 16, 0), /* TMU0 */
+	[MSTP015] = MSTP(&clkp, MSTPCR0, 15, 0), /* TMU1 */
+	[MSTP014] = MSTP(&clkp, MSTPCR0, 14, 0), /* TMU2 */
+};
+
+static struct clk_lookup lookups[] = {
+	/* MSTP32 clocks */
+	CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP016]), /* TMU00 */
+	CLKDEV_DEV_ID("sh_tmu.1", &mstp_clks[MSTP016]), /* TMU01 */
+	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP026]), /* SCIF0 */
+	CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP025]), /* SCIF1 */
+	CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP024]), /* SCIF2 */
+	CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP023]), /* SCIF3 */
+	CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP022]), /* SCIF4 */
+	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP021]), /* SCIF6 */
+};
+
+void __init r8a7779_clock_init(void)
+{
+	int k, ret = 0;
+
+	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
+		ret = clk_register(main_clks[k]);
+
+	if (!ret)
+		ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	if (!ret)
+		clk_init();
+	else
+		panic("failed to setup r8a7779 clocks\n");
+}
--- 0001/arch/arm/mach-shmobile/include/mach/common.h
+++ work/arch/arm/mach-shmobile/include/mach/common.h	2011-12-07 00:36:10.000000000 +0900
@@ -53,4 +53,9 @@ extern void sh73a0_secondary_init(unsign
 extern int sh73a0_boot_secondary(unsigned int cpu);
 extern void sh73a0_smp_prepare_cpus(void);
 
+extern void r8a7779_init_irq(void);
+extern void r8a7779_add_early_devices(void);
+extern void r8a7779_add_standard_devices(void);
+extern void r8a7779_clock_init(void);
+
 #endif /* __ARCH_MACH_COMMON_H */
--- /dev/null
+++ work/arch/arm/mach-shmobile/include/mach/r8a7779.h	2011-12-07 00:36:11.000000000 +0900
@@ -0,0 +1,6 @@
+#ifndef __ASM_R8A7779_H__
+#define __ASM_R8A7779_H__
+
+/* Nothing at this point */
+
+#endif /* __ASM_R8A7779_H__ */
--- /dev/null
+++ work/arch/arm/mach-shmobile/intc-r8a7779.c	2011-12-07 00:36:11.000000000 +0900
@@ -0,0 +1,58 @@
+/*
+ * r8a7779 processor support - INTC hardware block
+ *
+ * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011  Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/common.h>
+#include <mach/intc.h>
+#include <mach/r8a7779.h>
+#include <asm/hardware/gic.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#define INT2SMSKCR0 0xfe7822a0
+#define INT2SMSKCR1 0xfe7822a4
+#define INT2SMSKCR2 0xfe7822a8
+#define INT2SMSKCR3 0xfe7822ac
+#define INT2SMSKCR4 0xfe7822b0
+
+static int r8a7779_set_wake(struct irq_data *data, unsigned int on)
+{
+	return 0; /* always allow wakeup */
+}
+
+void __init r8a7779_init_irq(void)
+{
+	void __iomem *gic_dist_base = __io(0xf0001000);
+	void __iomem *gic_cpu_base = __io(0xf0000100);
+
+	/* use GIC to handle interrupts */
+	gic_init(0, 29, gic_dist_base, gic_cpu_base);
+	gic_arch_extn.irq_set_wake = r8a7779_set_wake;
+
+	/* unmask all known interrupts in INTCS2 */
+	__raw_writel(0xfffffff0, INT2SMSKCR0);
+	__raw_writel(0xfff7ffff, INT2SMSKCR1);
+	__raw_writel(0xfffbffdf, INT2SMSKCR2);
+	__raw_writel(0xbffffffc, INT2SMSKCR3);
+	__raw_writel(0x003fee3f, INT2SMSKCR4);
+}
--- /dev/null
+++ work/arch/arm/mach-shmobile/setup-r8a7779.c	2011-12-07 00:36:11.000000000 +0900
@@ -0,0 +1,231 @@
+/*
+ * r8a7779 processor support
+ *
+ * Copyright (C) 2011  Renesas Solutions Corp.
+ * Copyright (C) 2011  Magnus Damm
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/io.h>
+#include <linux/serial_sci.h>
+#include <linux/sh_intc.h>
+#include <linux/sh_timer.h>
+#include <mach/hardware.h>
+#include <mach/r8a7779.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+static struct plat_sci_port scif0_platform_data = {
+	.mapbase	= 0xffe40000,
+	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+	.scbrr_algo_id	= SCBRR_ALGO_2,
+	.type		= PORT_SCIF,
+	.irqs		= { gic_spi(88), gic_spi(88),
+			    gic_spi(88), gic_spi(88) },
+};
+
+static struct platform_device scif0_device = {
+	.name		= "sh-sci",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &scif0_platform_data,
+	},
+};
+
+static struct plat_sci_port scif1_platform_data = {
+	.mapbase	= 0xffe41000,
+	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+	.scbrr_algo_id	= SCBRR_ALGO_2,
+	.type		= PORT_SCIF,
+	.irqs		= { gic_spi(89), gic_spi(89),
+			    gic_spi(89), gic_spi(89) },
+};
+
+static struct platform_device scif1_device = {
+	.name		= "sh-sci",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &scif1_platform_data,
+	},
+};
+
+static struct plat_sci_port scif2_platform_data = {
+	.mapbase	= 0xffe42000,
+	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+	.scbrr_algo_id	= SCBRR_ALGO_2,
+	.type		= PORT_SCIF,
+	.irqs		= { gic_spi(90), gic_spi(90),
+			    gic_spi(90), gic_spi(90) },
+};
+
+static struct platform_device scif2_device = {
+	.name		= "sh-sci",
+	.id		= 2,
+	.dev		= {
+		.platform_data	= &scif2_platform_data,
+	},
+};
+
+static struct plat_sci_port scif3_platform_data = {
+	.mapbase	= 0xffe43000,
+	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+	.scbrr_algo_id	= SCBRR_ALGO_2,
+	.type		= PORT_SCIF,
+	.irqs		= { gic_spi(91), gic_spi(91),
+			    gic_spi(91), gic_spi(91) },
+};
+
+static struct platform_device scif3_device = {
+	.name		= "sh-sci",
+	.id		= 3,
+	.dev		= {
+		.platform_data	= &scif3_platform_data,
+	},
+};
+
+static struct plat_sci_port scif4_platform_data = {
+	.mapbase	= 0xffe44000,
+	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+	.scbrr_algo_id	= SCBRR_ALGO_2,
+	.type		= PORT_SCIF,
+	.irqs		= { gic_spi(92), gic_spi(92),
+			    gic_spi(92), gic_spi(92) },
+};
+
+static struct platform_device scif4_device = {
+	.name		= "sh-sci",
+	.id		= 4,
+	.dev		= {
+		.platform_data	= &scif4_platform_data,
+	},
+};
+
+static struct plat_sci_port scif5_platform_data = {
+	.mapbase	= 0xffe45000,
+	.flags		= UPF_BOOT_AUTOCONF | UPF_IOREMAP,
+	.scscr		= SCSCR_RE | SCSCR_TE | SCSCR_CKE1,
+	.scbrr_algo_id	= SCBRR_ALGO_2,
+	.type		= PORT_SCIF,
+	.irqs		= { gic_spi(93), gic_spi(93),
+			    gic_spi(93), gic_spi(93) },
+};
+
+static struct platform_device scif5_device = {
+	.name		= "sh-sci",
+	.id		= 5,
+	.dev		= {
+		.platform_data	= &scif5_platform_data,
+	},
+};
+
+/* TMU */
+static struct sh_timer_config tmu00_platform_data = {
+	.name = "TMU00",
+	.channel_offset = 0x4,
+	.timer_bit = 0,
+	.clockevent_rating = 200,
+};
+
+static struct resource tmu00_resources[] = {
+	[0] = {
+		.name	= "TMU00",
+		.start	= 0xffd80008,
+		.end	= 0xffd80013,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gic_spi(32),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device tmu00_device = {
+	.name		= "sh_tmu",
+	.id		= 0,
+	.dev = {
+		.platform_data	= &tmu00_platform_data,
+	},
+	.resource	= tmu00_resources,
+	.num_resources	= ARRAY_SIZE(tmu00_resources),
+};
+
+static struct sh_timer_config tmu01_platform_data = {
+	.name = "TMU01",
+	.channel_offset = 0x10,
+	.timer_bit = 1,
+	.clocksource_rating = 200,
+};
+
+static struct resource tmu01_resources[] = {
+	[0] = {
+		.name	= "TMU01",
+		.start	= 0xffd80014,
+		.end	= 0xffd8001f,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gic_spi(33),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device tmu01_device = {
+	.name		= "sh_tmu",
+	.id		= 1,
+	.dev = {
+		.platform_data	= &tmu01_platform_data,
+	},
+	.resource	= tmu01_resources,
+	.num_resources	= ARRAY_SIZE(tmu01_resources),
+};
+
+static struct platform_device *r8a7779_early_devices[] __initdata = {
+	&scif0_device,
+	&scif1_device,
+	&scif2_device,
+	&scif3_device,
+	&scif4_device,
+	&scif5_device,
+	&tmu00_device,
+	&tmu01_device,
+};
+
+static struct platform_device *r8a7779_late_devices[] __initdata = {
+};
+
+void __init r8a7779_add_standard_devices(void)
+{
+	platform_add_devices(r8a7779_early_devices,
+			    ARRAY_SIZE(r8a7779_early_devices));
+	platform_add_devices(r8a7779_late_devices,
+			    ARRAY_SIZE(r8a7779_late_devices));
+}
+
+void __init r8a7779_add_early_devices(void)
+{
+	early_platform_add_devices(r8a7779_early_devices,
+				   ARRAY_SIZE(r8a7779_early_devices));
+}

^ permalink raw reply

* [PATCH 00/05] ARM: mach-shmobile: r8a7779 and Marzen V2
From: Magnus Damm @ 2011-12-13 16:36 UTC (permalink / raw)
  To: linux-sh

ARM: mach-shmobile: r8a7779 and Marzen V2

[PATCH 01/05] ARM: mach-shmobile: r8a7779 and Marzen base support V2
[PATCH 02/05] ARM: mach-shmobile: r8a7779 PFC GPIO-only support V2
[PATCH 03/05] ARM: mach-shmobile: r8a7779 PFC function support
[PATCH 04/05] ARM: mach-shmobile: Marzen SCIF2/SCIF4 support
[PATCH 05/05] ARM: mach-shmobile: Marzen LAN89218 support

On the SoC-level simple things like the SCIF console, the TMU timer,
the GIC interrupt controller, initial CPG clock framework code and
now full PFC support are implemented. On the Marzen board the only
code for now is support for SCIF2/SCIF4 and the LAN89218 ethernet
chip.

Changes since V1:
- Various CPG and PFC changes have now been submitted separately
- Local CPG and PFC workarounds have been dropped
- The r8a7779 PFC code has been updated to fix incorrect register base address
- PMMR support has been added to the PFC code
- r8a7779 PFC function support has been added
- The PFC function code is now used to configure SCIF2/SCIF4 pins
- LAN89218 platform data and pin configuration via PFC function code

People interested in mach-type entry and serial debug code can look at:
[PATCH 00/07] ARM: mach-shmobile: r8a7779 and Marzen prototype V1

Feel free to contact me privately for the following patch that may
be rejected by mailing lists due to size issues:
[PATCH 03/05] ARM: mach-shmobile: r8a7779 PFC function support

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 Again, will most likely clash with A1 support written by Morimoto-san.
 Built on top of linus rc- git with Kota2 patches destined for -rc.

 Depends on the following patches for CPG and PFC:
  [PATCH 00/04] sh: clock / CPG ioremap() update
  [PATCH 01/04] sh: extend clock struct with mapped_reg member
  [PATCH 02/04] sh: use ioread32/iowrite32 and mapped_reg for mstp32
  [PATCH 03/04] sh: use ioread32/iowrite32 and mapped_reg for div4
  [PATCH 04/04] sh: use ioread32/iowrite32 and mapped_reg for div6
  [PATCH] sh: pfc: ioremap() support
  [PATCH 00/05] sh: pfc: Variable bitfield width and unlock reg patches
  [PATCH 01/05] sh: pfc: Add gpio_read_bit() for data register access
  [PATCH 02/05] sh: pfc: Convert index to field and value pair
  [PATCH 03/05] sh: pfc: Add config_reg_helper() function
  [PATCH 04/05] sh: pfc: Variable bitfield width config register support
  [PATCH 05/05] sh: pfc: Unlock register support

 arch/arm/mach-shmobile/Kconfig                |   12 
 arch/arm/mach-shmobile/Makefile               |    4 
 arch/arm/mach-shmobile/board-marzen.c         |  157 +
 arch/arm/mach-shmobile/clock-r8a7779.c        |  105 
 arch/arm/mach-shmobile/include/mach/common.h  |    6 
 arch/arm/mach-shmobile/include/mach/r8a7779.h |  327 +++
 arch/arm/mach-shmobile/intc-r8a7779.c         |   58 
 arch/arm/mach-shmobile/pfc-r8a7779.c          | 2647 ++++++++++++++++++++++++-
 arch/arm/mach-shmobile/setup-r8a7779.c        |  231 ++
 9 files changed, 3545 insertions(+), 2 deletions(-)


^ permalink raw reply

* Re: [PATCH/RFC] mmc: add a device PM QoS constraint when a host is
From: Guennadi Liakhovetski @ 2011-12-13 16:13 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: linux-mmc@vger.kernel.org, linux-pm@vger.kernel.org, Chris Ball,
	linux-sh@vger.kernel.org, Rafael J. Wysocki
In-Reply-To: <4EE76CC2.9080308@stericsson.com>

Hi Ulf

On Tue, 13 Dec 2011, Ulf Hansson wrote:

> Guennadi Liakhovetski wrote:
> > Some MMC hosts implement a fine-grained runtime PM, whereby they
> > runtime-suspend and -resume the host interface on each transfer. This can
> > negatively affect performance, if the user was trying to transfer data
> > blocks back-to-back. This patch adds a PM QoS constraint to avoid such a
> > throughput reduction. This constraint prevents runtime-suspending the
> > device, if the expected wakeup latency is larger than 100us.
> > 
> > Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> 
> I think host drivers can use autosuspend with some ms delay for this instead.
> This will mean that requests coming in bursts will not be affected (well only
> the first request in the burst will suffer from the runtime resume latency).

I think, Rafael is the best person to explain, why exactly this is not 
desired. In short, this is the wrong location to make such decisions and 
to define these criteria. The only thing, that the driver may be aware of 
is how quickly it wants to be able to wake up, if it got suspended. And 
it's already the PM subsystem, that has to decide, whether it can satisfy 
this requirement or not. Rafael will correct me, if my explanation is 
wrong.

> I believe that runtime resume callback should ofcourse be optimized so they
> are executed as fast as possible. But moreover, if they take more 100us, is
> that really a reason for not executing them at all?

I think it is a reason not to execute them during an intensive IO, yes. I 
cannot imagine a case, where if you have multiple IO requests waiting in 
the queue to your medium, you would want to switch off and immediately on 
again. Well, of course, such situations might exist, but then you just 
have to define and use a different governor on your system. This is also 
the flexibility, that this API is giving you.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

^ permalink raw reply

* [PATCH 05/05] sh: pfc: Unlock register support
From: Magnus Damm @ 2011-12-13 16:01 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Add PFC support for a 32-bit unlock register. Needed to
drive the r8a7779 PFC that comes with a funky PMMR register.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/sh/pfc.c       |   22 ++++++++++------------
 include/linux/sh_pfc.h |    2 ++
 2 files changed, 12 insertions(+), 12 deletions(-)

--- 0017/drivers/sh/pfc.c
+++ work/drivers/sh/pfc.c	2011-12-13 11:39:55.000000000 +0900
@@ -210,7 +210,7 @@ static void write_config_reg(struct pinm
 			     unsigned long field, unsigned long value)
 {
 	void __iomem *mapped_reg;
-	unsigned long mask, pos;
+	unsigned long mask, pos, data;
 
 	config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
 
@@ -221,17 +221,15 @@ static void write_config_reg(struct pinm
 	mask = ~(mask << pos);
 	value = value << pos;
 
-	switch (crp->reg_width) {
-	case 8:
-		iowrite8((ioread8(mapped_reg) & mask) | value, mapped_reg);
-		break;
-	case 16:
-		iowrite16((ioread16(mapped_reg) & mask) | value, mapped_reg);
-		break;
-	case 32:
-		iowrite32((ioread32(mapped_reg) & mask) | value, mapped_reg);
-		break;
-	}
+	data = gpio_read_raw_reg(mapped_reg, crp->reg_width);
+	data &= mask;
+	data |= value;
+
+	if (gpioc->unlock_reg)
+		gpio_write_raw_reg(pfc_phys_to_virt(gpioc, gpioc->unlock_reg),
+				   32, ~data);
+
+	gpio_write_raw_reg(mapped_reg, crp->reg_width, data);
 }
 
 static int setup_data_reg(struct pinmux_info *gpioc, unsigned gpio)
--- 0017/include/linux/sh_pfc.h
+++ work/include/linux/sh_pfc.h	2011-12-13 11:35:55.000000000 +0900
@@ -116,6 +116,8 @@ struct pinmux_info {
 	unsigned int num_resources;
 	struct pfc_window *window;
 
+	unsigned long unlock_reg;
+
 	struct gpio_chip chip;
 };
 

^ permalink raw reply

* [PATCH 04/05] sh: pfc: Variable bitfield width config register support
From: Magnus Damm @ 2011-12-13 16:01 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Add support for variable config reg hardware by adding
the macro PINMUX_CFG_REG_VAR(). The width of each bitfield
needs to be passed to the macro, and the correct space must
be consumed by each bitfield in the enum table following the
macro. Data registers still need to have fixed bitfields.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/sh/pfc.c       |   44 +++++++++++++++++++++++++++++++++-----------
 include/linux/sh_pfc.h |    9 ++++++++-
 2 files changed, 41 insertions(+), 12 deletions(-)

--- 0019/drivers/sh/pfc.c
+++ work/drivers/sh/pfc.c	2011-12-12 20:29:56.000000000 +0900
@@ -174,10 +174,19 @@ static void config_reg_helper(struct pin
 			      unsigned long *maskp,
 			      unsigned long *posp)
 {
+	int k;
+
 	*mapped_regp = pfc_phys_to_virt(gpioc, crp->reg);
 
-	*maskp = (1 << crp->field_width) - 1;
-	*posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
+	if (crp->field_width) {
+		*maskp = (1 << crp->field_width) - 1;
+		*posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
+	} else {
+		*maskp = (1 << crp->var_field_width[in_pos]) - 1;
+		*posp = crp->reg_width;
+		for (k = 0; k <= in_pos; k++)
+			*posp -= crp->var_field_width[k];
+	}
 }
 
 static int read_config_reg(struct pinmux_info *gpioc,
@@ -300,8 +309,8 @@ static int get_config_reg(struct pinmux_
 			  unsigned long **cntp)
 {
 	struct pinmux_cfg_reg *config_reg;
-	unsigned long r_width, f_width;
-	int k, n;
+	unsigned long r_width, f_width, curr_width, ncomb;
+	int k, m, n, pos, bit_pos;
 
 	k = 0;
 	while (1) {
@@ -312,14 +321,27 @@ static int get_config_reg(struct pinmux_
 
 		if (!r_width)
 			break;
-		for (n = 0; n < (r_width / f_width) * (1 << f_width); n++) {
-			if (config_reg->enum_ids[n] = enum_id) {
-				*crp = config_reg;
-				*fieldp = n / (1 << f_width);
-				*valuep = n % (1 << f_width);
-				*cntp = &config_reg->cnt[n / (1 << f_width)];
-				return 0;
+
+		pos = 0;
+		m = 0;
+		for (bit_pos = 0; bit_pos < r_width; bit_pos += curr_width) {
+			if (f_width)
+				curr_width = f_width;
+			else
+				curr_width = config_reg->var_field_width[m];
+
+			ncomb = 1 << curr_width;
+			for (n = 0; n < ncomb; n++) {
+				if (config_reg->enum_ids[pos + n] = enum_id) {
+					*crp = config_reg;
+					*fieldp = m;
+					*valuep = n;
+					*cntp = &config_reg->cnt[m];
+					return 0;
+				}
 			}
+			pos += ncomb;
+			m++;
 		}
 		k++;
 	}
--- 0013/include/linux/sh_pfc.h
+++ work/include/linux/sh_pfc.h	2011-12-12 19:40:30.000000000 +0900
@@ -45,12 +45,19 @@ struct pinmux_cfg_reg {
 	unsigned long reg, reg_width, field_width;
 	unsigned long *cnt;
 	pinmux_enum_t *enum_ids;
+	unsigned long *var_field_width;
 };
 
 #define PINMUX_CFG_REG(name, r, r_width, f_width) \
 	.reg = r, .reg_width = r_width, .field_width = f_width,		\
 	.cnt = (unsigned long [r_width / f_width]) {}, \
-	.enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)]) \
+	.enum_ids = (pinmux_enum_t [(r_width / f_width) * (1 << f_width)])
+
+#define PINMUX_CFG_REG_VAR(name, r, r_width, var_fw0, var_fwn...) \
+	.reg = r, .reg_width = r_width,	\
+	.cnt = (unsigned long [r_width]) {}, \
+	.var_field_width = (unsigned long [r_width]) { var_fw0, var_fwn, 0 }, \
+	.enum_ids = (pinmux_enum_t [])
 
 struct pinmux_data_reg {
 	unsigned long reg, reg_width, reg_shadow;

^ permalink raw reply

* [PATCH 03/05] sh: pfc: Add config_reg_helper() function
From: Magnus Damm @ 2011-12-13 16:00 UTC (permalink / raw)
  To: linux-sh

From: Magnus Damm <damm@opensource.se>

Add a helper function for shared config reg access
calculations. This allows us to reduce the amount
of duplicated code, and at the same time prepare
for a common place for future variable bitwidth
config reg support.

Signed-off-by: Magnus Damm <damm@opensource.se>
---

 drivers/sh/pfc.c |   76 ++++++++++++++++++++++--------------------------------
 1 file changed, 32 insertions(+), 44 deletions(-)

--- 0019/drivers/sh/pfc.c
+++ work/drivers/sh/pfc.c	2011-12-12 21:02:51.000000000 +0900
@@ -167,41 +167,52 @@ static void gpio_write_bit(struct pinmux
 	gpio_write_raw_reg(dr->mapped_reg, dr->reg_width, dr->reg_shadow);
 }
 
-static int gpio_read_reg(void __iomem *mapped_reg, unsigned long reg_width,
-			 unsigned long field_width, unsigned long in_pos,
-			 unsigned long reg)
+static void config_reg_helper(struct pinmux_info *gpioc,
+			      struct pinmux_cfg_reg *crp,
+			      unsigned long in_pos,
+			      void __iomem **mapped_regp,
+			      unsigned long *maskp,
+			      unsigned long *posp)
 {
-	unsigned long data, mask, pos;
+	*mapped_regp = pfc_phys_to_virt(gpioc, crp->reg);
 
-	data = 0;
-	mask = (1 << field_width) - 1;
-	pos = reg_width - ((in_pos + 1) * field_width);
+	*maskp = (1 << crp->field_width) - 1;
+	*posp = crp->reg_width - ((in_pos + 1) * crp->field_width);
+}
+
+static int read_config_reg(struct pinmux_info *gpioc,
+			   struct pinmux_cfg_reg *crp,
+			   unsigned long field)
+{
+	void __iomem *mapped_reg;
+	unsigned long mask, pos;
+
+	config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
 
-	pr_debug("read_reg: addr = %lx, pos = %ld, "
+	pr_debug("read_reg: addr = %lx, field = %ld, "
 		 "r_width = %ld, f_width = %ld\n",
-		 reg, pos, reg_width, field_width);
+		 crp->reg, field, crp->reg_width, crp->field_width);
 
-	data = gpio_read_raw_reg(mapped_reg, reg_width);
-	return (data >> pos) & mask;
+	return (gpio_read_raw_reg(mapped_reg, crp->reg_width) >> pos) & mask;
 }
 
-static void gpio_write_reg(void __iomem *mapped_reg, unsigned long reg_width,
-			   unsigned long field_width, unsigned long in_pos,
-			   unsigned long value, unsigned long reg)
+static void write_config_reg(struct pinmux_info *gpioc,
+			     struct pinmux_cfg_reg *crp,
+			     unsigned long field, unsigned long value)
 {
+	void __iomem *mapped_reg;
 	unsigned long mask, pos;
 
-	mask = (1 << field_width) - 1;
-	pos = reg_width - ((in_pos + 1) * field_width);
+	config_reg_helper(gpioc, crp, field, &mapped_reg, &mask, &pos);
 
-	pr_debug("write_reg addr = %lx, value = %ld, pos = %ld, "
+	pr_debug("write_reg addr = %lx, value = %ld, field = %ld, "
 		 "r_width = %ld, f_width = %ld\n",
-		 reg, value, pos, reg_width, field_width);
+		 crp->reg, value, field, crp->reg_width, crp->field_width);
 
 	mask = ~(mask << pos);
 	value = value << pos;
 
-	switch (reg_width) {
+	switch (crp->reg_width) {
 	case 8:
 		iowrite8((ioread8(mapped_reg) & mask) | value, mapped_reg);
 		break;
@@ -349,29 +360,6 @@ static int get_gpio_enum_id(struct pinmu
 	return -1;
 }
 
-static void write_config_reg(struct pinmux_info *gpioc,
-			     struct pinmux_cfg_reg *crp,
-			     int field, int value)
-{
-	void __iomem *mapped_reg = pfc_phys_to_virt(gpioc, crp->reg);
-
-	gpio_write_reg(mapped_reg, crp->reg_width, crp->field_width,
-		       field, value, crp->reg);
-}
-
-static int check_config_reg(struct pinmux_info *gpioc,
-			    struct pinmux_cfg_reg *crp,
-			    int field, int value)
-{
-	void __iomem *mapped_reg = pfc_phys_to_virt(gpioc, crp->reg);
-
-	if (gpio_read_reg(mapped_reg, crp->reg_width,
-			  crp->field_width, field, crp->reg) = value)
-		return 0;
-
-	return -1;
-}
-
 enum { GPIO_CFG_DRYRUN, GPIO_CFG_REQ, GPIO_CFG_FREE };
 
 static int pinmux_config_gpio(struct pinmux_info *gpioc, unsigned gpio,
@@ -465,8 +453,8 @@ static int pinmux_config_gpio(struct pin
 
 		switch (cfg_mode) {
 		case GPIO_CFG_DRYRUN:
-			if (!*cntp || !check_config_reg(gpioc, cr,
-							field, value))
+			if (!*cntp ||
+			    (read_config_reg(gpioc, cr, field) != value))
 				continue;
 			break;
 

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox