diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-12-18 21:28:49 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-12-18 21:28:49 -0800 |
commit | 3c678d0c216d2c232cde41c942e8745bd66d1ddb (patch) | |
tree | 047898b5e8eda75cb852c61e93cba561049c9ce2 | |
parent | 796bd6b777e1f721b59411b9842176c62d7f30f7 (diff) | |
download | ltsi-kernel-3c678d0c216d2c232cde41c942e8745bd66d1ddb.tar.gz |
more renesas patches added.
236 files changed, 39432 insertions, 0 deletions
diff --git a/patches.renesas/0001-ASoC-ak4642-Remove-redundant-break.patch b/patches.renesas/0001-ASoC-ak4642-Remove-redundant-break.patch new file mode 100644 index 00000000000000..d5590aa4d2b95d --- /dev/null +++ b/patches.renesas/0001-ASoC-ak4642-Remove-redundant-break.patch @@ -0,0 +1,38 @@ +From d2f3de6962fd7377d4f6c6cc080b8db33926a679 Mon Sep 17 00:00:00 2001 +From: Sachin Kamat <sachin.kamat@linaro.org> +Date: Fri, 13 Sep 2013 15:50:50 +0530 +Subject: ASoC: ak4642: Remove redundant break + +'break' after return statement is redundant. Remove it. + +Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 0feb23d1bdf31db903069d3d94892e56b5c11981) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/codecs/ak4642.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c +index 2d0378709702..21c35ed778cc 100644 +--- a/sound/soc/codecs/ak4642.c ++++ b/sound/soc/codecs/ak4642.c +@@ -352,7 +352,6 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) + */ + default: + return -EINVAL; +- break; + } + snd_soc_update_bits(codec, MD_CTL1, DIF_MASK, data); + +@@ -405,7 +404,6 @@ static int ak4642_dai_hw_params(struct snd_pcm_substream *substream, + break; + default: + return -EINVAL; +- break; + } + snd_soc_update_bits(codec, MD_CTL2, FS_MASK, rate); + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0003-gpio-use-dev_get_platdata.patch b/patches.renesas/0003-gpio-use-dev_get_platdata.patch new file mode 100644 index 00000000000000..531c2389ccd5e7 --- /dev/null +++ b/patches.renesas/0003-gpio-use-dev_get_platdata.patch @@ -0,0 +1,64 @@ +From 2f6ea1b82053fabf20b89d9b44288ad3bf84b35e Mon Sep 17 00:00:00 2001 +From: Jingoo Han <jg1.han@samsung.com> +Date: Tue, 30 Jul 2013 17:08:05 +0900 +Subject: gpio: use dev_get_platdata() + +Use the wrapper function for retrieving the platform data instead of +accessing dev->platform_data directly. + +Signed-off-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +(cherry picked from commit e56aee1897fd27631c1cb28e12b0fb8f8f9736f7) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + drivers/gpio/gpio-74x164.c + drivers/gpio/gpio-adp5520.c + drivers/gpio/gpio-adp5588.c + drivers/gpio/gpio-arizona.c + drivers/gpio/gpio-da9052.c + drivers/gpio/gpio-da9055.c + drivers/gpio/gpio-ich.c + drivers/gpio/gpio-janz-ttl.c + drivers/gpio/gpio-kempld.c + drivers/gpio/gpio-max730x.c + drivers/gpio/gpio-max732x.c + drivers/gpio/gpio-mc33880.c + drivers/gpio/gpio-mcp23s08.c + drivers/gpio/gpio-msic.c + drivers/gpio/gpio-omap.c + drivers/gpio/gpio-pca953x.c + drivers/gpio/gpio-pcf857x.c + drivers/gpio/gpio-pl061.c + drivers/gpio/gpio-rcar.c + drivers/gpio/gpio-rdc321x.c + drivers/gpio/gpio-sta2x11.c + drivers/gpio/gpio-sx150x.c + drivers/gpio/gpio-timberdale.c + drivers/gpio/gpio-tps65912.c + drivers/gpio/gpio-ts5500.c + drivers/gpio/gpio-twl4030.c + drivers/gpio/gpio-ucb1400.c + drivers/gpio/gpio-wm831x.c + drivers/gpio/gpio-wm8350.c + drivers/gpio/gpio-wm8994.c +--- + drivers/gpio/gpio-em.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c +index 5cba855638bf..847987c4f04a 100644 +--- a/drivers/gpio/gpio-em.c ++++ b/drivers/gpio/gpio-em.c +@@ -237,7 +237,7 @@ static struct irq_domain_ops em_gio_irq_domain_ops = { + static int em_gio_probe(struct platform_device *pdev) + { + struct gpio_em_config pdata_dt; +- struct gpio_em_config *pdata = pdev->dev.platform_data; ++ struct gpio_em_config *pdata = dev_get_platdata(&pdev->dev); + struct em_gio_priv *p; + struct resource *io[2], *irq[2]; + struct gpio_chip *gpio_chip; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0004-gpio-em-Add-pinctrl-support.patch b/patches.renesas/0004-gpio-em-Add-pinctrl-support.patch new file mode 100644 index 00000000000000..7c15d2680fde39 --- /dev/null +++ b/patches.renesas/0004-gpio-em-Add-pinctrl-support.patch @@ -0,0 +1,93 @@ +From ccbea9b7d8121cdefb2d5458a67fac8282dd2b95 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 3 Jul 2013 13:14:32 +0900 +Subject: gpio: em: Add pinctrl support + +Register the GPIO pin range, and request and free GPIO pins using the +pinctrl API. The pctl_name platform data member should be used by +platform devices to point out which pinctrl device to use. + +Follows same style as "dc3465a gpio-rcar: Add pinctrl support", +by Laurent Pinchart, thanks to him. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +(cherry picked from commit 640efa08cb635ae43d5ceae302b20c2c3f2035e5) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpio/gpio-em.c | 25 +++++++++++++++++++++++++ + include/linux/platform_data/gpio-em.h | 1 + + 2 files changed, 26 insertions(+) + +diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c +index 847987c4f04a..c6e1f086efe8 100644 +--- a/drivers/gpio/gpio-em.c ++++ b/drivers/gpio/gpio-em.c +@@ -30,6 +30,7 @@ + #include <linux/gpio.h> + #include <linux/slab.h> + #include <linux/module.h> ++#include <linux/pinctrl/consumer.h> + #include <linux/platform_data/gpio-em.h> + + struct em_gio_priv { +@@ -216,6 +217,21 @@ static int em_gio_to_irq(struct gpio_chip *chip, unsigned offset) + return irq_create_mapping(gpio_to_priv(chip)->irq_domain, offset); + } + ++static int em_gio_request(struct gpio_chip *chip, unsigned offset) ++{ ++ return pinctrl_request_gpio(chip->base + offset); ++} ++ ++static void em_gio_free(struct gpio_chip *chip, unsigned offset) ++{ ++ pinctrl_free_gpio(chip->base + offset); ++ ++ /* Set the GPIO as an input to ensure that the next GPIO request won't ++ * drive the GPIO pin as an output. ++ */ ++ em_gio_direction_input(chip, offset); ++} ++ + static int em_gio_irq_domain_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) + { +@@ -308,6 +324,8 @@ static int em_gio_probe(struct platform_device *pdev) + gpio_chip->direction_output = em_gio_direction_output; + gpio_chip->set = em_gio_set; + gpio_chip->to_irq = em_gio_to_irq; ++ gpio_chip->request = em_gio_request; ++ gpio_chip->free = em_gio_free; + gpio_chip->label = name; + gpio_chip->owner = THIS_MODULE; + gpio_chip->base = pdata->gpio_base; +@@ -351,6 +369,13 @@ static int em_gio_probe(struct platform_device *pdev) + dev_err(&pdev->dev, "failed to add GPIO controller\n"); + goto err1; + } ++ ++ if (pdata->pctl_name) { ++ ret = gpiochip_add_pin_range(gpio_chip, pdata->pctl_name, 0, ++ gpio_chip->base, gpio_chip->ngpio); ++ if (ret < 0) ++ dev_warn(&pdev->dev, "failed to add pin range\n"); ++ } + return 0; + + err1: +diff --git a/include/linux/platform_data/gpio-em.h b/include/linux/platform_data/gpio-em.h +index 573edfb046c4..7c5a519d2dcd 100644 +--- a/include/linux/platform_data/gpio-em.h ++++ b/include/linux/platform_data/gpio-em.h +@@ -5,6 +5,7 @@ struct gpio_em_config { + unsigned int gpio_base; + unsigned int irq_base; + unsigned int number_of_pins; ++ const char *pctl_name; + }; + + #endif /* __GPIO_EM_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0005-drm-gem-Split-drm_gem_mmap-into-object-search-and-ob.patch b/patches.renesas/0005-drm-gem-Split-drm_gem_mmap-into-object-search-and-ob.patch new file mode 100644 index 00000000000000..54d5bcc112ac37 --- /dev/null +++ b/patches.renesas/0005-drm-gem-Split-drm_gem_mmap-into-object-search-and-ob.patch @@ -0,0 +1,151 @@ +From 3b9b9b1ff0826721d264a483f14a618f54b97911 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Tue, 16 Apr 2013 14:14:52 +0200 +Subject: drm/gem: Split drm_gem_mmap() into object search and object mapping + +The drm_gem_mmap() function first finds the GEM object to be mapped +based on the fake mmap offset and then maps the object. Split the object +mapping code into a standalone drm_gem_mmap_obj() function that can be +used to implement dma-buf mmap() operations. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Reviewed-by: Rob Clark <robdclark@gmail.com> +(cherry picked from commit 1c5aafa6eee2d5712f774676d407e5ab6dae9a1b) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/drm_gem.c | 83 +++++++++++++++++++++++++++++------------------ + include/drm/drmP.h | 2 ++ + 2 files changed, 54 insertions(+), 31 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c +index 239ef30f4a62..c9d7081acf59 100644 +--- a/drivers/gpu/drm/drm_gem.c ++++ b/drivers/gpu/drm/drm_gem.c +@@ -640,6 +640,55 @@ void drm_gem_vm_close(struct vm_area_struct *vma) + } + EXPORT_SYMBOL(drm_gem_vm_close); + ++/** ++ * drm_gem_mmap_obj - memory map a GEM object ++ * @obj: the GEM object to map ++ * @obj_size: the object size to be mapped, in bytes ++ * @vma: VMA for the area to be mapped ++ * ++ * Set up the VMA to prepare mapping of the GEM object using the gem_vm_ops ++ * provided by the driver. Depending on their requirements, drivers can either ++ * provide a fault handler in their gem_vm_ops (in which case any accesses to ++ * the object will be trapped, to perform migration, GTT binding, surface ++ * register allocation, or performance monitoring), or mmap the buffer memory ++ * synchronously after calling drm_gem_mmap_obj. ++ * ++ * This function is mainly intended to implement the DMABUF mmap operation, when ++ * the GEM object is not looked up based on its fake offset. To implement the ++ * DRM mmap operation, drivers should use the drm_gem_mmap() function. ++ * ++ * Return 0 or success or -EINVAL if the object size is smaller than the VMA ++ * size, or if no gem_vm_ops are provided. ++ */ ++int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size, ++ struct vm_area_struct *vma) ++{ ++ struct drm_device *dev = obj->dev; ++ ++ /* Check for valid size. */ ++ if (obj_size < vma->vm_end - vma->vm_start) ++ return -EINVAL; ++ ++ if (!dev->driver->gem_vm_ops) ++ return -EINVAL; ++ ++ vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP; ++ vma->vm_ops = dev->driver->gem_vm_ops; ++ vma->vm_private_data = obj; ++ vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); ++ ++ /* Take a ref for this mapping of the object, so that the fault ++ * handler can dereference the mmap offset's pointer to the object. ++ * This reference is cleaned up by the corresponding vm_close ++ * (which should happen whether the vma was created by this call, or ++ * by a vm_open due to mremap or partial unmap or whatever). ++ */ ++ drm_gem_object_reference(obj); ++ ++ drm_vm_open_locked(dev, vma); ++ return 0; ++} ++EXPORT_SYMBOL(drm_gem_mmap_obj); + + /** + * drm_gem_mmap - memory map routine for GEM objects +@@ -649,11 +698,9 @@ EXPORT_SYMBOL(drm_gem_vm_close); + * If a driver supports GEM object mapping, mmap calls on the DRM file + * descriptor will end up here. + * +- * If we find the object based on the offset passed in (vma->vm_pgoff will ++ * Look up the GEM object based on the offset passed in (vma->vm_pgoff will + * contain the fake offset we created when the GTT map ioctl was called on +- * the object), we set up the driver fault handler so that any accesses +- * to the object can be trapped, to perform migration, GTT binding, surface +- * register allocation, or performance monitoring. ++ * the object) and map it with a call to drm_gem_mmap_obj(). + */ + int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) + { +@@ -661,7 +708,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) + struct drm_device *dev = priv->minor->dev; + struct drm_gem_mm *mm = dev->mm_private; + struct drm_local_map *map = NULL; +- struct drm_gem_object *obj; + struct drm_hash_item *hash; + int ret = 0; + +@@ -682,32 +728,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) + goto out_unlock; + } + +- /* Check for valid size. */ +- if (map->size < vma->vm_end - vma->vm_start) { +- ret = -EINVAL; +- goto out_unlock; +- } +- +- obj = map->handle; +- if (!obj->dev->driver->gem_vm_ops) { +- ret = -EINVAL; +- goto out_unlock; +- } +- +- vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP; +- vma->vm_ops = obj->dev->driver->gem_vm_ops; +- vma->vm_private_data = map->handle; +- vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); +- +- /* Take a ref for this mapping of the object, so that the fault +- * handler can dereference the mmap offset's pointer to the object. +- * This reference is cleaned up by the corresponding vm_close +- * (which should happen whether the vma was created by this call, or +- * by a vm_open due to mremap or partial unmap or whatever). +- */ +- drm_gem_object_reference(obj); +- +- drm_vm_open_locked(dev, vma); ++ ret = drm_gem_mmap_obj(map->handle, map->size, vma); + + out_unlock: + mutex_unlock(&dev->struct_mutex); +diff --git a/include/drm/drmP.h b/include/drm/drmP.h +index 63d17ee9eb48..b836d131bb07 100644 +--- a/include/drm/drmP.h ++++ b/include/drm/drmP.h +@@ -1648,6 +1648,8 @@ int drm_gem_private_object_init(struct drm_device *dev, + void drm_gem_object_handle_free(struct drm_gem_object *obj); + void drm_gem_vm_open(struct vm_area_struct *vma); + void drm_gem_vm_close(struct vm_area_struct *vma); ++int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size, ++ struct vm_area_struct *vma); + int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); + + #include <drm/drm_global.h> +-- +1.8.5.rc3 + diff --git a/patches.renesas/0006-drm-GEM-CMA-Split-object-creation-into-object-alloc-.patch b/patches.renesas/0006-drm-GEM-CMA-Split-object-creation-into-object-alloc-.patch new file mode 100644 index 00000000000000..d791b7dc83b447 --- /dev/null +++ b/patches.renesas/0006-drm-GEM-CMA-Split-object-creation-into-object-alloc-.patch @@ -0,0 +1,147 @@ +From 05cf3547ea572cf46fe55f55d83b887bb9acb97c Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Sun, 17 Feb 2013 01:54:26 +0100 +Subject: drm: GEM CMA: Split object creation into object alloc and DMA memory + alloc + +This allows creating a GEM CMA object without an associated DMA memory +buffer, and will be used to implement DRM PRIME support. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Reviewed-by: Rob Clark <robdclark@gmail.com> +(cherry picked from commit a5ed8940d3f99f05d460ce31583182539f07fa0e) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/drm_gem_cma_helper.c | 83 +++++++++++++++++++++--------------- + 1 file changed, 48 insertions(+), 35 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c +index 0a7e011509bd..8cce3302b690 100644 +--- a/drivers/gpu/drm/drm_gem_cma_helper.c ++++ b/drivers/gpu/drm/drm_gem_cma_helper.c +@@ -32,62 +32,73 @@ static unsigned int get_gem_mmap_offset(struct drm_gem_object *obj) + return (unsigned int)obj->map_list.hash.key << PAGE_SHIFT; + } + +-static void drm_gem_cma_buf_destroy(struct drm_device *drm, +- struct drm_gem_cma_object *cma_obj) +-{ +- dma_free_writecombine(drm->dev, cma_obj->base.size, cma_obj->vaddr, +- cma_obj->paddr); +-} +- + /* +- * drm_gem_cma_create - allocate an object with the given size ++ * __drm_gem_cma_create - Create a GEM CMA object without allocating memory ++ * @drm: The drm device ++ * @size: The GEM object size + * +- * returns a struct drm_gem_cma_object* on success or ERR_PTR values +- * on failure. ++ * This function creates and initializes a GEM CMA object of the given size, but ++ * doesn't allocate any memory to back the object. ++ * ++ * Return a struct drm_gem_cma_object* on success or ERR_PTR values on failure. + */ +-struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, +- unsigned int size) ++static struct drm_gem_cma_object * ++__drm_gem_cma_create(struct drm_device *drm, unsigned int size) + { + struct drm_gem_cma_object *cma_obj; + struct drm_gem_object *gem_obj; + int ret; + +- size = round_up(size, PAGE_SIZE); +- + cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL); + if (!cma_obj) + return ERR_PTR(-ENOMEM); + +- cma_obj->vaddr = dma_alloc_writecombine(drm->dev, size, +- &cma_obj->paddr, GFP_KERNEL | __GFP_NOWARN); +- if (!cma_obj->vaddr) { +- dev_err(drm->dev, "failed to allocate buffer with size %d\n", size); +- ret = -ENOMEM; +- goto err_dma_alloc; +- } +- + gem_obj = &cma_obj->base; + + ret = drm_gem_object_init(drm, gem_obj, size); + if (ret) +- goto err_obj_init; ++ goto error; + + ret = drm_gem_create_mmap_offset(gem_obj); +- if (ret) +- goto err_create_mmap_offset; ++ if (ret) { ++ drm_gem_object_release(gem_obj); ++ goto error; ++ } + + return cma_obj; + +-err_create_mmap_offset: +- drm_gem_object_release(gem_obj); ++error: ++ kfree(cma_obj); ++ return ERR_PTR(ret); ++} + +-err_obj_init: +- drm_gem_cma_buf_destroy(drm, cma_obj); ++/* ++ * drm_gem_cma_create - allocate an object with the given size ++ * ++ * returns a struct drm_gem_cma_object* on success or ERR_PTR values ++ * on failure. ++ */ ++struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, ++ unsigned int size) ++{ ++ struct drm_gem_cma_object *cma_obj; + +-err_dma_alloc: +- kfree(cma_obj); ++ size = round_up(size, PAGE_SIZE); + +- return ERR_PTR(ret); ++ cma_obj = __drm_gem_cma_create(drm, size); ++ if (IS_ERR(cma_obj)) ++ return cma_obj; ++ ++ cma_obj->vaddr = dma_alloc_writecombine(drm->dev, size, ++ &cma_obj->paddr, GFP_KERNEL | __GFP_NOWARN); ++ if (!cma_obj->vaddr) { ++ dev_err(drm->dev, "failed to allocate buffer with size %d\n", ++ size); ++ drm_gem_cma_free_object(&cma_obj->base); ++ return ERR_PTR(-ENOMEM); ++ } ++ ++ return cma_obj; + } + EXPORT_SYMBOL_GPL(drm_gem_cma_create); + +@@ -143,11 +154,13 @@ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) + if (gem_obj->map_list.map) + drm_gem_free_mmap_offset(gem_obj); + +- drm_gem_object_release(gem_obj); +- + cma_obj = to_drm_gem_cma_obj(gem_obj); + +- drm_gem_cma_buf_destroy(gem_obj->dev, cma_obj); ++ if (cma_obj->vaddr) ++ dma_free_writecombine(gem_obj->dev->dev, cma_obj->base.size, ++ cma_obj->vaddr, cma_obj->paddr); ++ ++ drm_gem_object_release(gem_obj); + + kfree(cma_obj); + } +-- +1.8.5.rc3 + diff --git a/patches.renesas/0007-drm-GEM-CMA-Split-object-mapping-into-GEM-mapping-an.patch b/patches.renesas/0007-drm-GEM-CMA-Split-object-mapping-into-GEM-mapping-an.patch new file mode 100644 index 00000000000000..117abb4c92ee7c --- /dev/null +++ b/patches.renesas/0007-drm-GEM-CMA-Split-object-mapping-into-GEM-mapping-an.patch @@ -0,0 +1,65 @@ +From 3b60a60a94a9952eefc3676334324139076c3186 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Tue, 16 Apr 2013 14:32:34 +0200 +Subject: drm: GEM CMA: Split object mapping into GEM mapping and CMA mapping + +The CMA-specific mapping code will be used to implement dma-buf mmap +support. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Rob Clark <robdclark@gmail.com> +(cherry picked from commit ebaf9e033e6dc9b584176c1731f4e07360d4d231) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/drm_gem_cma_helper.c | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c +index 8cce3302b690..7a4db4e7a1ea 100644 +--- a/drivers/gpu/drm/drm_gem_cma_helper.c ++++ b/drivers/gpu/drm/drm_gem_cma_helper.c +@@ -228,13 +228,26 @@ const struct vm_operations_struct drm_gem_cma_vm_ops = { + }; + EXPORT_SYMBOL_GPL(drm_gem_cma_vm_ops); + ++static int drm_gem_cma_mmap_obj(struct drm_gem_cma_object *cma_obj, ++ struct vm_area_struct *vma) ++{ ++ int ret; ++ ++ ret = remap_pfn_range(vma, vma->vm_start, cma_obj->paddr >> PAGE_SHIFT, ++ vma->vm_end - vma->vm_start, vma->vm_page_prot); ++ if (ret) ++ drm_gem_vm_close(vma); ++ ++ return ret; ++} ++ + /* + * drm_gem_cma_mmap - (struct file_operation)->mmap callback function + */ + int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma) + { +- struct drm_gem_object *gem_obj; + struct drm_gem_cma_object *cma_obj; ++ struct drm_gem_object *gem_obj; + int ret; + + ret = drm_gem_mmap(filp, vma); +@@ -244,12 +257,7 @@ int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma) + gem_obj = vma->vm_private_data; + cma_obj = to_drm_gem_cma_obj(gem_obj); + +- ret = remap_pfn_range(vma, vma->vm_start, cma_obj->paddr >> PAGE_SHIFT, +- vma->vm_end - vma->vm_start, vma->vm_page_prot); +- if (ret) +- drm_gem_vm_close(vma); +- +- return ret; ++ return drm_gem_cma_mmap_obj(cma_obj, vma); + } + EXPORT_SYMBOL_GPL(drm_gem_cma_mmap); + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0008-drm-GEM-CMA-Add-DRM-PRIME-support.patch b/patches.renesas/0008-drm-GEM-CMA-Add-DRM-PRIME-support.patch new file mode 100644 index 00000000000000..dc99dc473d33ec --- /dev/null +++ b/patches.renesas/0008-drm-GEM-CMA-Add-DRM-PRIME-support.patch @@ -0,0 +1,400 @@ +From 3ae948b048338c0095f2121faef7f243be9624b3 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Sun, 17 Feb 2013 01:57:30 +0100 +Subject: drm: GEM CMA: Add DRM PRIME support + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Reviewed-by: Rob Clark <robdclark@gmail.com> +(cherry picked from commit 71d7282a0f1abb488e5be4d154893579624bc683) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/drm_gem_cma_helper.c | 317 ++++++++++++++++++++++++++++++++++- + include/drm/drm_gem_cma_helper.h | 9 + + 2 files changed, 323 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c +index 7a4db4e7a1ea..f94fcd752815 100644 +--- a/drivers/gpu/drm/drm_gem_cma_helper.c ++++ b/drivers/gpu/drm/drm_gem_cma_helper.c +@@ -21,6 +21,7 @@ + #include <linux/slab.h> + #include <linux/mutex.h> + #include <linux/export.h> ++#include <linux/dma-buf.h> + #include <linux/dma-mapping.h> + + #include <drm/drmP.h> +@@ -82,6 +83,8 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, + unsigned int size) + { + struct drm_gem_cma_object *cma_obj; ++ struct sg_table *sgt = NULL; ++ int ret; + + size = round_up(size, PAGE_SIZE); + +@@ -94,11 +97,29 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm, + if (!cma_obj->vaddr) { + dev_err(drm->dev, "failed to allocate buffer with size %d\n", + size); +- drm_gem_cma_free_object(&cma_obj->base); +- return ERR_PTR(-ENOMEM); ++ ret = -ENOMEM; ++ goto error; ++ } ++ ++ sgt = kzalloc(sizeof(*cma_obj->sgt), GFP_KERNEL); ++ if (sgt == NULL) { ++ ret = -ENOMEM; ++ goto error; + } + ++ ret = dma_get_sgtable(drm->dev, sgt, cma_obj->vaddr, ++ cma_obj->paddr, size); ++ if (ret < 0) ++ goto error; ++ ++ cma_obj->sgt = sgt; ++ + return cma_obj; ++ ++error: ++ kfree(sgt); ++ drm_gem_cma_free_object(&cma_obj->base); ++ return ERR_PTR(ret); + } + EXPORT_SYMBOL_GPL(drm_gem_cma_create); + +@@ -156,9 +177,16 @@ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) + + cma_obj = to_drm_gem_cma_obj(gem_obj); + +- if (cma_obj->vaddr) ++ if (cma_obj->vaddr) { + dma_free_writecombine(gem_obj->dev->dev, cma_obj->base.size, + cma_obj->vaddr, cma_obj->paddr); ++ if (cma_obj->sgt) { ++ sg_free_table(cma_obj->sgt); ++ kfree(cma_obj->sgt); ++ } ++ } else if (gem_obj->import_attach) { ++ drm_prime_gem_destroy(gem_obj, cma_obj->sgt); ++ } + + drm_gem_object_release(gem_obj); + +@@ -291,3 +319,286 @@ void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj, struct seq_file *m + } + EXPORT_SYMBOL_GPL(drm_gem_cma_describe); + #endif ++ ++/* ----------------------------------------------------------------------------- ++ * DMA-BUF ++ */ ++ ++struct drm_gem_cma_dmabuf_attachment { ++ struct sg_table sgt; ++ enum dma_data_direction dir; ++}; ++ ++static int drm_gem_cma_dmabuf_attach(struct dma_buf *dmabuf, struct device *dev, ++ struct dma_buf_attachment *attach) ++{ ++ struct drm_gem_cma_dmabuf_attachment *cma_attach; ++ ++ cma_attach = kzalloc(sizeof(*cma_attach), GFP_KERNEL); ++ if (!cma_attach) ++ return -ENOMEM; ++ ++ cma_attach->dir = DMA_NONE; ++ attach->priv = cma_attach; ++ ++ return 0; ++} ++ ++static void drm_gem_cma_dmabuf_detach(struct dma_buf *dmabuf, ++ struct dma_buf_attachment *attach) ++{ ++ struct drm_gem_cma_dmabuf_attachment *cma_attach = attach->priv; ++ struct sg_table *sgt; ++ ++ if (cma_attach == NULL) ++ return; ++ ++ sgt = &cma_attach->sgt; ++ ++ if (cma_attach->dir != DMA_NONE) ++ dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, ++ cma_attach->dir); ++ ++ sg_free_table(sgt); ++ kfree(cma_attach); ++ attach->priv = NULL; ++} ++ ++static struct sg_table * ++drm_gem_cma_dmabuf_map(struct dma_buf_attachment *attach, ++ enum dma_data_direction dir) ++{ ++ struct drm_gem_cma_dmabuf_attachment *cma_attach = attach->priv; ++ struct drm_gem_cma_object *cma_obj = attach->dmabuf->priv; ++ struct drm_device *drm = cma_obj->base.dev; ++ struct scatterlist *rd, *wr; ++ struct sg_table *sgt; ++ unsigned int i; ++ int nents, ret; ++ ++ DRM_DEBUG_PRIME("\n"); ++ ++ if (WARN_ON(dir == DMA_NONE)) ++ return ERR_PTR(-EINVAL); ++ ++ /* Return the cached mapping when possible. */ ++ if (cma_attach->dir == dir) ++ return &cma_attach->sgt; ++ ++ /* Two mappings with different directions for the same attachment are ++ * not allowed. ++ */ ++ if (WARN_ON(cma_attach->dir != DMA_NONE)) ++ return ERR_PTR(-EBUSY); ++ ++ sgt = &cma_attach->sgt; ++ ++ ret = sg_alloc_table(sgt, cma_obj->sgt->orig_nents, GFP_KERNEL); ++ if (ret) { ++ DRM_ERROR("failed to alloc sgt.\n"); ++ return ERR_PTR(-ENOMEM); ++ } ++ ++ mutex_lock(&drm->struct_mutex); ++ ++ rd = cma_obj->sgt->sgl; ++ wr = sgt->sgl; ++ for (i = 0; i < sgt->orig_nents; ++i) { ++ sg_set_page(wr, sg_page(rd), rd->length, rd->offset); ++ rd = sg_next(rd); ++ wr = sg_next(wr); ++ } ++ ++ nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir); ++ if (!nents) { ++ DRM_ERROR("failed to map sgl with iommu.\n"); ++ sg_free_table(sgt); ++ sgt = ERR_PTR(-EIO); ++ goto done; ++ } ++ ++ cma_attach->dir = dir; ++ attach->priv = cma_attach; ++ ++ DRM_DEBUG_PRIME("buffer size = %zu\n", cma_obj->base.size); ++ ++done: ++ mutex_unlock(&drm->struct_mutex); ++ return sgt; ++} ++ ++static void drm_gem_cma_dmabuf_unmap(struct dma_buf_attachment *attach, ++ struct sg_table *sgt, ++ enum dma_data_direction dir) ++{ ++ /* Nothing to do. */ ++} ++ ++static void drm_gem_cma_dmabuf_release(struct dma_buf *dmabuf) ++{ ++ struct drm_gem_cma_object *cma_obj = dmabuf->priv; ++ ++ DRM_DEBUG_PRIME("%s\n", __FILE__); ++ ++ /* ++ * drm_gem_cma_dmabuf_release() call means that file object's ++ * f_count is 0 and it calls drm_gem_object_handle_unreference() ++ * to drop the references that these values had been increased ++ * at drm_prime_handle_to_fd() ++ */ ++ if (cma_obj->base.export_dma_buf == dmabuf) { ++ cma_obj->base.export_dma_buf = NULL; ++ ++ /* ++ * drop this gem object refcount to release allocated buffer ++ * and resources. ++ */ ++ drm_gem_object_unreference_unlocked(&cma_obj->base); ++ } ++} ++ ++static void *drm_gem_cma_dmabuf_kmap_atomic(struct dma_buf *dmabuf, ++ unsigned long page_num) ++{ ++ /* TODO */ ++ ++ return NULL; ++} ++ ++static void drm_gem_cma_dmabuf_kunmap_atomic(struct dma_buf *dmabuf, ++ unsigned long page_num, void *addr) ++{ ++ /* TODO */ ++} ++ ++static void *drm_gem_cma_dmabuf_kmap(struct dma_buf *dmabuf, ++ unsigned long page_num) ++{ ++ /* TODO */ ++ ++ return NULL; ++} ++ ++static void drm_gem_cma_dmabuf_kunmap(struct dma_buf *dmabuf, ++ unsigned long page_num, void *addr) ++{ ++ /* TODO */ ++} ++ ++static int drm_gem_cma_dmabuf_mmap(struct dma_buf *dmabuf, ++ struct vm_area_struct *vma) ++{ ++ struct drm_gem_cma_object *cma_obj = dmabuf->priv; ++ struct drm_gem_object *gem_obj = &cma_obj->base; ++ int ret; ++ ++ ret = drm_gem_mmap_obj(gem_obj, gem_obj->size, vma); ++ if (ret < 0) ++ return ret; ++ ++ return drm_gem_cma_mmap_obj(cma_obj, vma); ++} ++ ++static void *drm_gem_cma_dmabuf_vmap(struct dma_buf *dmabuf) ++{ ++ struct drm_gem_cma_object *cma_obj = dmabuf->priv; ++ ++ return cma_obj->vaddr; ++} ++ ++static struct dma_buf_ops drm_gem_cma_dmabuf_ops = { ++ .attach = drm_gem_cma_dmabuf_attach, ++ .detach = drm_gem_cma_dmabuf_detach, ++ .map_dma_buf = drm_gem_cma_dmabuf_map, ++ .unmap_dma_buf = drm_gem_cma_dmabuf_unmap, ++ .kmap = drm_gem_cma_dmabuf_kmap, ++ .kmap_atomic = drm_gem_cma_dmabuf_kmap_atomic, ++ .kunmap = drm_gem_cma_dmabuf_kunmap, ++ .kunmap_atomic = drm_gem_cma_dmabuf_kunmap_atomic, ++ .mmap = drm_gem_cma_dmabuf_mmap, ++ .vmap = drm_gem_cma_dmabuf_vmap, ++ .release = drm_gem_cma_dmabuf_release, ++}; ++ ++struct dma_buf *drm_gem_cma_dmabuf_export(struct drm_device *drm, ++ struct drm_gem_object *obj, int flags) ++{ ++ struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj); ++ ++ return dma_buf_export(cma_obj, &drm_gem_cma_dmabuf_ops, ++ cma_obj->base.size, flags); ++} ++EXPORT_SYMBOL_GPL(drm_gem_cma_dmabuf_export); ++ ++struct drm_gem_object *drm_gem_cma_dmabuf_import(struct drm_device *drm, ++ struct dma_buf *dma_buf) ++{ ++ struct drm_gem_cma_object *cma_obj; ++ struct dma_buf_attachment *attach; ++ struct sg_table *sgt; ++ int ret; ++ ++ DRM_DEBUG_PRIME("%s\n", __FILE__); ++ ++ /* is this one of own objects? */ ++ if (dma_buf->ops == &drm_gem_cma_dmabuf_ops) { ++ struct drm_gem_object *obj; ++ ++ cma_obj = dma_buf->priv; ++ obj = &cma_obj->base; ++ ++ /* is it from our device? */ ++ if (obj->dev == drm) { ++ /* ++ * Importing dmabuf exported from out own gem increases ++ * refcount on gem itself instead of f_count of dmabuf. ++ */ ++ drm_gem_object_reference(obj); ++ dma_buf_put(dma_buf); ++ return obj; ++ } ++ } ++ ++ /* Create a CMA GEM buffer. */ ++ cma_obj = __drm_gem_cma_create(drm, dma_buf->size); ++ if (IS_ERR(cma_obj)) ++ return ERR_PTR(PTR_ERR(cma_obj)); ++ ++ /* Attach to the buffer and map it. Make sure the mapping is contiguous ++ * on the device memory bus, as that's all we support. ++ */ ++ attach = dma_buf_attach(dma_buf, drm->dev); ++ if (IS_ERR(attach)) { ++ ret = -EINVAL; ++ goto error_gem_free; ++ } ++ ++ sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); ++ if (IS_ERR_OR_NULL(sgt)) { ++ ret = sgt ? PTR_ERR(sgt) : -ENOMEM; ++ goto error_buf_detach; ++ } ++ ++ if (sgt->nents != 1) { ++ ret = -EINVAL; ++ goto error_buf_unmap; ++ } ++ ++ cma_obj->base.import_attach = attach; ++ cma_obj->paddr = sg_dma_address(sgt->sgl); ++ cma_obj->sgt = sgt; ++ ++ DRM_DEBUG_PRIME("dma_addr = 0x%x, size = %zu\n", cma_obj->paddr, ++ dma_buf->size); ++ ++ return &cma_obj->base; ++ ++error_buf_unmap: ++ dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL); ++error_buf_detach: ++ dma_buf_detach(dma_buf, attach); ++error_gem_free: ++ drm_gem_cma_free_object(&cma_obj->base); ++ return ERR_PTR(ret); ++} ++EXPORT_SYMBOL_GPL(drm_gem_cma_dmabuf_import); +diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h +index 63397ced9254..6e17251e9b28 100644 +--- a/include/drm/drm_gem_cma_helper.h ++++ b/include/drm/drm_gem_cma_helper.h +@@ -4,6 +4,9 @@ + struct drm_gem_cma_object { + struct drm_gem_object base; + dma_addr_t paddr; ++ struct sg_table *sgt; ++ ++ /* For objects with DMA memory allocated by GEM CMA */ + void *vaddr; + }; + +@@ -45,4 +48,10 @@ extern const struct vm_operations_struct drm_gem_cma_vm_ops; + void drm_gem_cma_describe(struct drm_gem_cma_object *obj, struct seq_file *m); + #endif + ++struct dma_buf *drm_gem_cma_dmabuf_export(struct drm_device *drm_dev, ++ struct drm_gem_object *obj, ++ int flags); ++struct drm_gem_object *drm_gem_cma_dmabuf_import(struct drm_device *drm_dev, ++ struct dma_buf *dma_buf); ++ + #endif /* __DRM_GEM_CMA_HELPER_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0009-drm-Renesas-R-Car-Display-Unit-DRM-driver.patch b/patches.renesas/0009-drm-Renesas-R-Car-Display-Unit-DRM-driver.patch new file mode 100644 index 00000000000000..c7ac09460c7970 --- /dev/null +++ b/patches.renesas/0009-drm-Renesas-R-Car-Display-Unit-DRM-driver.patch @@ -0,0 +1,3019 @@ +From 7f3fc5224e7eb0af6074ce3ab54f1bd10e81927a Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Wed, 19 Jun 2013 13:54:11 +0200 +Subject: drm: Renesas R-Car Display Unit DRM driver + +The R-Car Display Unit (DU) DRM driver supports both superposition +processors and all eight planes in RGB and YUV formats with alpha +blending. + +Only VGA and LVDS encoders and connectors are currently supported. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +(cherry picked from commit 4bf8e1962f91eed5dbee168d2348983dda0a518f) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/Kconfig | 2 + + drivers/gpu/drm/Makefile | 1 + + drivers/gpu/drm/rcar-du/Kconfig | 9 + + drivers/gpu/drm/rcar-du/Makefile | 8 + + drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 595 ++++++++++++++++++++++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 50 +++ + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 325 +++++++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_drv.h | 66 ++++ + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 245 +++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_kms.h | 59 ++++ + drivers/gpu/drm/rcar-du/rcar_du_lvds.c | 216 ++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_lvds.h | 24 ++ + drivers/gpu/drm/rcar-du/rcar_du_plane.c | 507 +++++++++++++++++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_plane.h | 67 ++++ + drivers/gpu/drm/rcar-du/rcar_du_regs.h | 445 ++++++++++++++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_vga.c | 149 ++++++++ + drivers/gpu/drm/rcar-du/rcar_du_vga.h | 24 ++ + include/linux/platform_data/rcar-du.h | 54 +++ + 18 files changed, 2846 insertions(+) + create mode 100644 drivers/gpu/drm/rcar-du/Kconfig + create mode 100644 drivers/gpu/drm/rcar-du/Makefile + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_crtc.c + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_crtc.h + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_drv.c + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_drv.h + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_kms.c + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_kms.h + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_lvds.c + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_lvds.h + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_plane.c + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_plane.h + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_regs.h + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_vga.c + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_vga.h + create mode 100644 include/linux/platform_data/rcar-du.h + +diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig +index b16c50ee769c..71ca63b79a4f 100644 +--- a/drivers/gpu/drm/Kconfig ++++ b/drivers/gpu/drm/Kconfig +@@ -213,6 +213,8 @@ source "drivers/gpu/drm/mgag200/Kconfig" + + source "drivers/gpu/drm/cirrus/Kconfig" + ++source "drivers/gpu/drm/rcar-du/Kconfig" ++ + source "drivers/gpu/drm/shmobile/Kconfig" + + source "drivers/gpu/drm/omapdrm/Kconfig" +diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile +index 1c9f24396002..44de0f316a08 100644 +--- a/drivers/gpu/drm/Makefile ++++ b/drivers/gpu/drm/Makefile +@@ -48,6 +48,7 @@ obj-$(CONFIG_DRM_EXYNOS) +=exynos/ + obj-$(CONFIG_DRM_GMA500) += gma500/ + obj-$(CONFIG_DRM_UDL) += udl/ + obj-$(CONFIG_DRM_AST) += ast/ ++obj-$(CONFIG_DRM_RCAR_DU) += rcar-du/ + obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/ + obj-$(CONFIG_DRM_OMAP) += omapdrm/ + obj-$(CONFIG_DRM_TILCDC) += tilcdc/ +diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig +new file mode 100644 +index 000000000000..72887df8dd76 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/Kconfig +@@ -0,0 +1,9 @@ ++config DRM_RCAR_DU ++ tristate "DRM Support for R-Car Display Unit" ++ depends on DRM && ARM ++ select DRM_KMS_HELPER ++ select DRM_KMS_CMA_HELPER ++ select DRM_GEM_CMA_HELPER ++ help ++ Choose this option if you have an R-Car chipset. ++ If M is selected the module will be called rcar-du-drm. +diff --git a/drivers/gpu/drm/rcar-du/Makefile b/drivers/gpu/drm/rcar-du/Makefile +new file mode 100644 +index 000000000000..7333c0094015 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/Makefile +@@ -0,0 +1,8 @@ ++rcar-du-drm-y := rcar_du_crtc.o \ ++ rcar_du_drv.o \ ++ rcar_du_kms.o \ ++ rcar_du_lvds.o \ ++ rcar_du_plane.o \ ++ rcar_du_vga.o ++ ++obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +new file mode 100644 +index 000000000000..24183fb93592 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +@@ -0,0 +1,595 @@ ++/* ++ * rcar_du_crtc.c -- R-Car Display Unit CRTCs ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <linux/clk.h> ++#include <linux/mutex.h> ++ ++#include <drm/drmP.h> ++#include <drm/drm_crtc.h> ++#include <drm/drm_crtc_helper.h> ++#include <drm/drm_fb_cma_helper.h> ++#include <drm/drm_gem_cma_helper.h> ++ ++#include "rcar_du_crtc.h" ++#include "rcar_du_drv.h" ++#include "rcar_du_kms.h" ++#include "rcar_du_lvds.h" ++#include "rcar_du_plane.h" ++#include "rcar_du_regs.h" ++#include "rcar_du_vga.h" ++ ++#define to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, crtc) ++ ++static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg) ++{ ++ struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ ++ return rcar_du_read(rcdu, rcrtc->mmio_offset + reg); ++} ++ ++static void rcar_du_crtc_write(struct rcar_du_crtc *rcrtc, u32 reg, u32 data) ++{ ++ struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ ++ rcar_du_write(rcdu, rcrtc->mmio_offset + reg, data); ++} ++ ++static void rcar_du_crtc_clr(struct rcar_du_crtc *rcrtc, u32 reg, u32 clr) ++{ ++ struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ ++ rcar_du_write(rcdu, rcrtc->mmio_offset + reg, ++ rcar_du_read(rcdu, rcrtc->mmio_offset + reg) & ~clr); ++} ++ ++static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set) ++{ ++ struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ ++ rcar_du_write(rcdu, rcrtc->mmio_offset + reg, ++ rcar_du_read(rcdu, rcrtc->mmio_offset + reg) | set); ++} ++ ++static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg, ++ u32 clr, u32 set) ++{ ++ struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ u32 value = rcar_du_read(rcdu, rcrtc->mmio_offset + reg); ++ ++ rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set); ++} ++ ++static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) ++{ ++ struct drm_crtc *crtc = &rcrtc->crtc; ++ struct rcar_du_device *rcdu = crtc->dev->dev_private; ++ const struct drm_display_mode *mode = &crtc->mode; ++ unsigned long clk; ++ u32 value; ++ u32 div; ++ ++ /* Dot clock */ ++ clk = clk_get_rate(rcdu->clock); ++ div = DIV_ROUND_CLOSEST(clk, mode->clock * 1000); ++ div = clamp(div, 1U, 64U) - 1; ++ ++ rcar_du_write(rcdu, rcrtc->index ? ESCR2 : ESCR, ++ ESCR_DCLKSEL_CLKS | div); ++ rcar_du_write(rcdu, rcrtc->index ? OTAR2 : OTAR, 0); ++ ++ /* Signal polarities */ ++ value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : DSMR_VSL) ++ | ((mode->flags & DRM_MODE_FLAG_PHSYNC) ? 0 : DSMR_HSL) ++ | DSMR_DIPM_DE; ++ rcar_du_crtc_write(rcrtc, DSMR, value); ++ ++ /* Display timings */ ++ rcar_du_crtc_write(rcrtc, HDSR, mode->htotal - mode->hsync_start - 19); ++ rcar_du_crtc_write(rcrtc, HDER, mode->htotal - mode->hsync_start + ++ mode->hdisplay - 19); ++ rcar_du_crtc_write(rcrtc, HSWR, mode->hsync_end - ++ mode->hsync_start - 1); ++ rcar_du_crtc_write(rcrtc, HCR, mode->htotal - 1); ++ ++ rcar_du_crtc_write(rcrtc, VDSR, mode->vtotal - mode->vsync_end - 2); ++ rcar_du_crtc_write(rcrtc, VDER, mode->vtotal - mode->vsync_end + ++ mode->vdisplay - 2); ++ rcar_du_crtc_write(rcrtc, VSPR, mode->vtotal - mode->vsync_end + ++ mode->vsync_start - 1); ++ rcar_du_crtc_write(rcrtc, VCR, mode->vtotal - 1); ++ ++ rcar_du_crtc_write(rcrtc, DESR, mode->htotal - mode->hsync_start); ++ rcar_du_crtc_write(rcrtc, DEWR, mode->hdisplay); ++} ++ ++static void rcar_du_crtc_set_routing(struct rcar_du_crtc *rcrtc) ++{ ++ struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ u32 dorcr = rcar_du_read(rcdu, DORCR); ++ ++ dorcr &= ~(DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_MASK); ++ ++ /* Set the DU1 pins sources. Select CRTC 0 if explicitly requested and ++ * CRTC 1 in all other cases to avoid cloning CRTC 0 to DU0 and DU1 by ++ * default. ++ */ ++ if (rcrtc->outputs & (1 << 1) && rcrtc->index == 0) ++ dorcr |= DORCR_PG2D_DS1; ++ else ++ dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2; ++ ++ rcar_du_write(rcdu, DORCR, dorcr); ++} ++ ++static void __rcar_du_start_stop(struct rcar_du_device *rcdu, bool start) ++{ ++ rcar_du_write(rcdu, DSYSR, ++ (rcar_du_read(rcdu, DSYSR) & ~(DSYSR_DRES | DSYSR_DEN)) | ++ (start ? DSYSR_DEN : DSYSR_DRES)); ++} ++ ++static void rcar_du_start_stop(struct rcar_du_device *rcdu, bool start) ++{ ++ /* Many of the configuration bits are only updated when the display ++ * reset (DRES) bit in DSYSR is set to 1, disabling *both* CRTCs. Some ++ * of those bits could be pre-configured, but others (especially the ++ * bits related to plane assignment to display timing controllers) need ++ * to be modified at runtime. ++ * ++ * Restart the display controller if a start is requested. Sorry for the ++ * flicker. It should be possible to move most of the "DRES-update" bits ++ * setup to driver initialization time and minimize the number of cases ++ * when the display controller will have to be restarted. ++ */ ++ if (start) { ++ if (rcdu->used_crtcs++ != 0) ++ __rcar_du_start_stop(rcdu, false); ++ __rcar_du_start_stop(rcdu, true); ++ } else { ++ if (--rcdu->used_crtcs == 0) ++ __rcar_du_start_stop(rcdu, false); ++ } ++} ++ ++void rcar_du_crtc_route_output(struct drm_crtc *crtc, unsigned int output) ++{ ++ struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); ++ ++ /* Store the route from the CRTC output to the DU output. The DU will be ++ * configured when starting the CRTC. ++ */ ++ rcrtc->outputs |= 1 << output; ++} ++ ++void rcar_du_crtc_update_planes(struct drm_crtc *crtc) ++{ ++ struct rcar_du_device *rcdu = crtc->dev->dev_private; ++ struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); ++ struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES]; ++ unsigned int num_planes = 0; ++ unsigned int prio = 0; ++ unsigned int i; ++ u32 dptsr = 0; ++ u32 dspr = 0; ++ ++ for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) { ++ struct rcar_du_plane *plane = &rcdu->planes.planes[i]; ++ unsigned int j; ++ ++ if (plane->crtc != &rcrtc->crtc || !plane->enabled) ++ continue; ++ ++ /* Insert the plane in the sorted planes array. */ ++ for (j = num_planes++; j > 0; --j) { ++ if (planes[j-1]->zpos <= plane->zpos) ++ break; ++ planes[j] = planes[j-1]; ++ } ++ ++ planes[j] = plane; ++ prio += plane->format->planes * 4; ++ } ++ ++ for (i = 0; i < num_planes; ++i) { ++ struct rcar_du_plane *plane = planes[i]; ++ unsigned int index = plane->hwindex; ++ ++ prio -= 4; ++ dspr |= (index + 1) << prio; ++ dptsr |= DPTSR_PnDK(index) | DPTSR_PnTS(index); ++ ++ if (plane->format->planes == 2) { ++ index = (index + 1) % 8; ++ ++ prio -= 4; ++ dspr |= (index + 1) << prio; ++ dptsr |= DPTSR_PnDK(index) | DPTSR_PnTS(index); ++ } ++ } ++ ++ /* Select display timing and dot clock generator 2 for planes associated ++ * with superposition controller 2. ++ */ ++ if (rcrtc->index) { ++ u32 value = rcar_du_read(rcdu, DPTSR); ++ ++ /* The DPTSR register is updated when the display controller is ++ * stopped. We thus need to restart the DU. Once again, sorry ++ * for the flicker. One way to mitigate the issue would be to ++ * pre-associate planes with CRTCs (either with a fixed 4/4 ++ * split, or through a module parameter). Flicker would then ++ * occur only if we need to break the pre-association. ++ */ ++ if (value != dptsr) { ++ rcar_du_write(rcdu, DPTSR, dptsr); ++ if (rcdu->used_crtcs) { ++ __rcar_du_start_stop(rcdu, false); ++ __rcar_du_start_stop(rcdu, true); ++ } ++ } ++ } ++ ++ rcar_du_write(rcdu, rcrtc->index ? DS2PR : DS1PR, dspr); ++} ++ ++static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc) ++{ ++ struct drm_crtc *crtc = &rcrtc->crtc; ++ struct rcar_du_device *rcdu = crtc->dev->dev_private; ++ unsigned int i; ++ ++ if (rcrtc->started) ++ return; ++ ++ if (WARN_ON(rcrtc->plane->format == NULL)) ++ return; ++ ++ /* Set display off and background to black */ ++ rcar_du_crtc_write(rcrtc, DOOR, DOOR_RGB(0, 0, 0)); ++ rcar_du_crtc_write(rcrtc, BPOR, BPOR_RGB(0, 0, 0)); ++ ++ /* Configure display timings and output routing */ ++ rcar_du_crtc_set_display_timing(rcrtc); ++ rcar_du_crtc_set_routing(rcrtc); ++ ++ mutex_lock(&rcdu->planes.lock); ++ rcrtc->plane->enabled = true; ++ rcar_du_crtc_update_planes(crtc); ++ mutex_unlock(&rcdu->planes.lock); ++ ++ /* Setup planes. */ ++ for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) { ++ struct rcar_du_plane *plane = &rcdu->planes.planes[i]; ++ ++ if (plane->crtc != crtc || !plane->enabled) ++ continue; ++ ++ rcar_du_plane_setup(plane); ++ } ++ ++ /* Select master sync mode. This enables display operation in master ++ * sync mode (with the HSYNC and VSYNC signals configured as outputs and ++ * actively driven). ++ */ ++ rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_MASTER); ++ ++ rcar_du_start_stop(rcdu, true); ++ ++ rcrtc->started = true; ++} ++ ++static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc) ++{ ++ struct drm_crtc *crtc = &rcrtc->crtc; ++ struct rcar_du_device *rcdu = crtc->dev->dev_private; ++ ++ if (!rcrtc->started) ++ return; ++ ++ mutex_lock(&rcdu->planes.lock); ++ rcrtc->plane->enabled = false; ++ rcar_du_crtc_update_planes(crtc); ++ mutex_unlock(&rcdu->planes.lock); ++ ++ /* Select switch sync mode. This stops display operation and configures ++ * the HSYNC and VSYNC signals as inputs. ++ */ ++ rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH); ++ ++ rcar_du_start_stop(rcdu, false); ++ ++ rcrtc->started = false; ++} ++ ++void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc) ++{ ++ struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ ++ rcar_du_crtc_stop(rcrtc); ++ rcar_du_put(rcdu); ++} ++ ++void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc) ++{ ++ struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ ++ if (rcrtc->dpms != DRM_MODE_DPMS_ON) ++ return; ++ ++ rcar_du_get(rcdu); ++ rcar_du_crtc_start(rcrtc); ++} ++ ++static void rcar_du_crtc_update_base(struct rcar_du_crtc *rcrtc) ++{ ++ struct drm_crtc *crtc = &rcrtc->crtc; ++ ++ rcar_du_plane_compute_base(rcrtc->plane, crtc->fb); ++ rcar_du_plane_update_base(rcrtc->plane); ++} ++ ++static void rcar_du_crtc_dpms(struct drm_crtc *crtc, int mode) ++{ ++ struct rcar_du_device *rcdu = crtc->dev->dev_private; ++ struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); ++ ++ if (rcrtc->dpms == mode) ++ return; ++ ++ if (mode == DRM_MODE_DPMS_ON) { ++ rcar_du_get(rcdu); ++ rcar_du_crtc_start(rcrtc); ++ } else { ++ rcar_du_crtc_stop(rcrtc); ++ rcar_du_put(rcdu); ++ } ++ ++ rcrtc->dpms = mode; ++} ++ ++static bool rcar_du_crtc_mode_fixup(struct drm_crtc *crtc, ++ const struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ /* TODO Fixup modes */ ++ return true; ++} ++ ++static void rcar_du_crtc_mode_prepare(struct drm_crtc *crtc) ++{ ++ struct rcar_du_device *rcdu = crtc->dev->dev_private; ++ struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); ++ ++ /* We need to access the hardware during mode set, acquire a reference ++ * to the DU. ++ */ ++ rcar_du_get(rcdu); ++ ++ /* Stop the CRTC and release the plane. Force the DPMS mode to off as a ++ * result. ++ */ ++ rcar_du_crtc_stop(rcrtc); ++ rcar_du_plane_release(rcrtc->plane); ++ ++ rcrtc->dpms = DRM_MODE_DPMS_OFF; ++} ++ ++static int rcar_du_crtc_mode_set(struct drm_crtc *crtc, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode, ++ int x, int y, ++ struct drm_framebuffer *old_fb) ++{ ++ struct rcar_du_device *rcdu = crtc->dev->dev_private; ++ struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); ++ const struct rcar_du_format_info *format; ++ int ret; ++ ++ format = rcar_du_format_info(crtc->fb->pixel_format); ++ if (format == NULL) { ++ dev_dbg(rcdu->dev, "mode_set: unsupported format %08x\n", ++ crtc->fb->pixel_format); ++ ret = -EINVAL; ++ goto error; ++ } ++ ++ ret = rcar_du_plane_reserve(rcrtc->plane, format); ++ if (ret < 0) ++ goto error; ++ ++ rcrtc->plane->format = format; ++ rcrtc->plane->pitch = crtc->fb->pitches[0]; ++ ++ rcrtc->plane->src_x = x; ++ rcrtc->plane->src_y = y; ++ rcrtc->plane->width = mode->hdisplay; ++ rcrtc->plane->height = mode->vdisplay; ++ ++ rcar_du_plane_compute_base(rcrtc->plane, crtc->fb); ++ ++ rcrtc->outputs = 0; ++ ++ return 0; ++ ++error: ++ /* There's no rollback/abort operation to clean up in case of error. We ++ * thus need to release the reference to the DU acquired in prepare() ++ * here. ++ */ ++ rcar_du_put(rcdu); ++ return ret; ++} ++ ++static void rcar_du_crtc_mode_commit(struct drm_crtc *crtc) ++{ ++ struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); ++ ++ /* We're done, restart the CRTC and set the DPMS mode to on. The ++ * reference to the DU acquired at prepare() time will thus be released ++ * by the DPMS handler (possibly called by the disable() handler). ++ */ ++ rcar_du_crtc_start(rcrtc); ++ rcrtc->dpms = DRM_MODE_DPMS_ON; ++} ++ ++static int rcar_du_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, ++ struct drm_framebuffer *old_fb) ++{ ++ struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); ++ ++ rcrtc->plane->src_x = x; ++ rcrtc->plane->src_y = y; ++ ++ rcar_du_crtc_update_base(to_rcar_crtc(crtc)); ++ ++ return 0; ++} ++ ++static void rcar_du_crtc_disable(struct drm_crtc *crtc) ++{ ++ struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); ++ ++ rcar_du_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); ++ rcar_du_plane_release(rcrtc->plane); ++} ++ ++static const struct drm_crtc_helper_funcs crtc_helper_funcs = { ++ .dpms = rcar_du_crtc_dpms, ++ .mode_fixup = rcar_du_crtc_mode_fixup, ++ .prepare = rcar_du_crtc_mode_prepare, ++ .commit = rcar_du_crtc_mode_commit, ++ .mode_set = rcar_du_crtc_mode_set, ++ .mode_set_base = rcar_du_crtc_mode_set_base, ++ .disable = rcar_du_crtc_disable, ++}; ++ ++void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc, ++ struct drm_file *file) ++{ ++ struct drm_pending_vblank_event *event; ++ struct drm_device *dev = rcrtc->crtc.dev; ++ unsigned long flags; ++ ++ /* Destroy the pending vertical blanking event associated with the ++ * pending page flip, if any, and disable vertical blanking interrupts. ++ */ ++ spin_lock_irqsave(&dev->event_lock, flags); ++ event = rcrtc->event; ++ if (event && event->base.file_priv == file) { ++ rcrtc->event = NULL; ++ event->base.destroy(&event->base); ++ drm_vblank_put(dev, rcrtc->index); ++ } ++ spin_unlock_irqrestore(&dev->event_lock, flags); ++} ++ ++static void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc) ++{ ++ struct drm_pending_vblank_event *event; ++ struct drm_device *dev = rcrtc->crtc.dev; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev->event_lock, flags); ++ event = rcrtc->event; ++ rcrtc->event = NULL; ++ spin_unlock_irqrestore(&dev->event_lock, flags); ++ ++ if (event == NULL) ++ return; ++ ++ spin_lock_irqsave(&dev->event_lock, flags); ++ drm_send_vblank_event(dev, rcrtc->index, event); ++ spin_unlock_irqrestore(&dev->event_lock, flags); ++ ++ drm_vblank_put(dev, rcrtc->index); ++} ++ ++static int rcar_du_crtc_page_flip(struct drm_crtc *crtc, ++ struct drm_framebuffer *fb, ++ struct drm_pending_vblank_event *event) ++{ ++ struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); ++ struct drm_device *dev = rcrtc->crtc.dev; ++ unsigned long flags; ++ ++ spin_lock_irqsave(&dev->event_lock, flags); ++ if (rcrtc->event != NULL) { ++ spin_unlock_irqrestore(&dev->event_lock, flags); ++ return -EBUSY; ++ } ++ spin_unlock_irqrestore(&dev->event_lock, flags); ++ ++ crtc->fb = fb; ++ rcar_du_crtc_update_base(rcrtc); ++ ++ if (event) { ++ event->pipe = rcrtc->index; ++ drm_vblank_get(dev, rcrtc->index); ++ spin_lock_irqsave(&dev->event_lock, flags); ++ rcrtc->event = event; ++ spin_unlock_irqrestore(&dev->event_lock, flags); ++ } ++ ++ return 0; ++} ++ ++static const struct drm_crtc_funcs crtc_funcs = { ++ .destroy = drm_crtc_cleanup, ++ .set_config = drm_crtc_helper_set_config, ++ .page_flip = rcar_du_crtc_page_flip, ++}; ++ ++int rcar_du_crtc_create(struct rcar_du_device *rcdu, unsigned int index) ++{ ++ struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index]; ++ struct drm_crtc *crtc = &rcrtc->crtc; ++ int ret; ++ ++ rcrtc->mmio_offset = index ? DISP2_REG_OFFSET : 0; ++ rcrtc->index = index; ++ rcrtc->dpms = DRM_MODE_DPMS_OFF; ++ rcrtc->plane = &rcdu->planes.planes[index]; ++ ++ rcrtc->plane->crtc = crtc; ++ ++ ret = drm_crtc_init(rcdu->ddev, crtc, &crtc_funcs); ++ if (ret < 0) ++ return ret; ++ ++ drm_crtc_helper_add(crtc, &crtc_helper_funcs); ++ ++ return 0; ++} ++ ++void rcar_du_crtc_enable_vblank(struct rcar_du_crtc *rcrtc, bool enable) ++{ ++ if (enable) { ++ rcar_du_crtc_write(rcrtc, DSRCR, DSRCR_VBCL); ++ rcar_du_crtc_set(rcrtc, DIER, DIER_VBE); ++ } else { ++ rcar_du_crtc_clr(rcrtc, DIER, DIER_VBE); ++ } ++} ++ ++void rcar_du_crtc_irq(struct rcar_du_crtc *rcrtc) ++{ ++ u32 status; ++ ++ status = rcar_du_crtc_read(rcrtc, DSSR); ++ rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK); ++ ++ if (status & DSSR_VBK) { ++ drm_handle_vblank(rcrtc->crtc.dev, rcrtc->index); ++ rcar_du_crtc_finish_page_flip(rcrtc); ++ } ++} +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +new file mode 100644 +index 000000000000..2a0365bcbd14 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +@@ -0,0 +1,50 @@ ++/* ++ * rcar_du_crtc.h -- R-Car Display Unit CRTCs ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#ifndef __RCAR_DU_CRTC_H__ ++#define __RCAR_DU_CRTC_H__ ++ ++#include <linux/mutex.h> ++ ++#include <drm/drmP.h> ++#include <drm/drm_crtc.h> ++ ++struct rcar_du_device; ++struct rcar_du_plane; ++ ++struct rcar_du_crtc { ++ struct drm_crtc crtc; ++ ++ unsigned int mmio_offset; ++ unsigned int index; ++ bool started; ++ ++ struct drm_pending_vblank_event *event; ++ unsigned int outputs; ++ int dpms; ++ ++ struct rcar_du_plane *plane; ++}; ++ ++int rcar_du_crtc_create(struct rcar_du_device *rcdu, unsigned int index); ++void rcar_du_crtc_enable_vblank(struct rcar_du_crtc *rcrtc, bool enable); ++void rcar_du_crtc_irq(struct rcar_du_crtc *rcrtc); ++void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc, ++ struct drm_file *file); ++void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc); ++void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc); ++ ++void rcar_du_crtc_route_output(struct drm_crtc *crtc, unsigned int output); ++void rcar_du_crtc_update_planes(struct drm_crtc *crtc); ++ ++#endif /* __RCAR_DU_CRTC_H__ */ +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +new file mode 100644 +index 000000000000..003b34ee38e3 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -0,0 +1,325 @@ ++/* ++ * rcar_du_drv.c -- R-Car Display Unit DRM driver ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <linux/clk.h> ++#include <linux/io.h> ++#include <linux/mm.h> ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/pm.h> ++#include <linux/slab.h> ++ ++#include <drm/drmP.h> ++#include <drm/drm_crtc_helper.h> ++#include <drm/drm_gem_cma_helper.h> ++ ++#include "rcar_du_crtc.h" ++#include "rcar_du_drv.h" ++#include "rcar_du_kms.h" ++#include "rcar_du_regs.h" ++ ++/* ----------------------------------------------------------------------------- ++ * Core device operations ++ */ ++ ++/* ++ * rcar_du_get - Acquire a reference to the DU ++ * ++ * Acquiring a reference enables the device clock and setup core registers. A ++ * reference must be held before accessing any hardware registers. ++ * ++ * This function must be called with the DRM mode_config lock held. ++ * ++ * Return 0 in case of success or a negative error code otherwise. ++ */ ++int rcar_du_get(struct rcar_du_device *rcdu) ++{ ++ int ret; ++ ++ if (rcdu->use_count) ++ goto done; ++ ++ /* Enable clocks before accessing the hardware. */ ++ ret = clk_prepare_enable(rcdu->clock); ++ if (ret < 0) ++ return ret; ++ ++ /* Enable extended features */ ++ rcar_du_write(rcdu, DEFR, DEFR_CODE | DEFR_DEFE); ++ rcar_du_write(rcdu, DEFR2, DEFR2_CODE | DEFR2_DEFE2G); ++ rcar_du_write(rcdu, DEFR3, DEFR3_CODE | DEFR3_DEFE3); ++ rcar_du_write(rcdu, DEFR4, DEFR4_CODE); ++ rcar_du_write(rcdu, DEFR5, DEFR5_CODE | DEFR5_DEFE5); ++ ++ /* Use DS1PR and DS2PR to configure planes priorities and connects the ++ * superposition 0 to DU0 pins. DU1 pins will be configured dynamically. ++ */ ++ rcar_du_write(rcdu, DORCR, DORCR_PG1D_DS1 | DORCR_DPRS); ++ ++done: ++ rcdu->use_count++; ++ return 0; ++} ++ ++/* ++ * rcar_du_put - Release a reference to the DU ++ * ++ * Releasing the last reference disables the device clock. ++ * ++ * This function must be called with the DRM mode_config lock held. ++ */ ++void rcar_du_put(struct rcar_du_device *rcdu) ++{ ++ if (--rcdu->use_count) ++ return; ++ ++ clk_disable_unprepare(rcdu->clock); ++} ++ ++/* ----------------------------------------------------------------------------- ++ * DRM operations ++ */ ++ ++static int rcar_du_unload(struct drm_device *dev) ++{ ++ drm_kms_helper_poll_fini(dev); ++ drm_mode_config_cleanup(dev); ++ drm_vblank_cleanup(dev); ++ drm_irq_uninstall(dev); ++ ++ dev->dev_private = NULL; ++ ++ return 0; ++} ++ ++static int rcar_du_load(struct drm_device *dev, unsigned long flags) ++{ ++ struct platform_device *pdev = dev->platformdev; ++ struct rcar_du_platform_data *pdata = pdev->dev.platform_data; ++ struct rcar_du_device *rcdu; ++ struct resource *ioarea; ++ struct resource *mem; ++ int ret; ++ ++ if (pdata == NULL) { ++ dev_err(dev->dev, "no platform data\n"); ++ return -ENODEV; ++ } ++ ++ rcdu = devm_kzalloc(&pdev->dev, sizeof(*rcdu), GFP_KERNEL); ++ if (rcdu == NULL) { ++ dev_err(dev->dev, "failed to allocate private data\n"); ++ return -ENOMEM; ++ } ++ ++ rcdu->dev = &pdev->dev; ++ rcdu->pdata = pdata; ++ rcdu->ddev = dev; ++ dev->dev_private = rcdu; ++ ++ /* I/O resources and clocks */ ++ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (mem == NULL) { ++ dev_err(&pdev->dev, "failed to get memory resource\n"); ++ return -EINVAL; ++ } ++ ++ ioarea = devm_request_mem_region(&pdev->dev, mem->start, ++ resource_size(mem), pdev->name); ++ if (ioarea == NULL) { ++ dev_err(&pdev->dev, "failed to request memory region\n"); ++ return -EBUSY; ++ } ++ ++ rcdu->mmio = devm_ioremap_nocache(&pdev->dev, ioarea->start, ++ resource_size(ioarea)); ++ if (rcdu->mmio == NULL) { ++ dev_err(&pdev->dev, "failed to remap memory resource\n"); ++ return -ENOMEM; ++ } ++ ++ rcdu->clock = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(rcdu->clock)) { ++ dev_err(&pdev->dev, "failed to get clock\n"); ++ return -ENOENT; ++ } ++ ++ /* DRM/KMS objects */ ++ ret = rcar_du_modeset_init(rcdu); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "failed to initialize DRM/KMS\n"); ++ goto done; ++ } ++ ++ /* IRQ and vblank handling */ ++ ret = drm_vblank_init(dev, (1 << rcdu->num_crtcs) - 1); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "failed to initialize vblank\n"); ++ goto done; ++ } ++ ++ ret = drm_irq_install(dev); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "failed to install IRQ handler\n"); ++ goto done; ++ } ++ ++ platform_set_drvdata(pdev, rcdu); ++ ++done: ++ if (ret) ++ rcar_du_unload(dev); ++ ++ return ret; ++} ++ ++static void rcar_du_preclose(struct drm_device *dev, struct drm_file *file) ++{ ++ struct rcar_du_device *rcdu = dev->dev_private; ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(rcdu->crtcs); ++i) ++ rcar_du_crtc_cancel_page_flip(&rcdu->crtcs[i], file); ++} ++ ++static irqreturn_t rcar_du_irq(int irq, void *arg) ++{ ++ struct drm_device *dev = arg; ++ struct rcar_du_device *rcdu = dev->dev_private; ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(rcdu->crtcs); ++i) ++ rcar_du_crtc_irq(&rcdu->crtcs[i]); ++ ++ return IRQ_HANDLED; ++} ++ ++static int rcar_du_enable_vblank(struct drm_device *dev, int crtc) ++{ ++ struct rcar_du_device *rcdu = dev->dev_private; ++ ++ rcar_du_crtc_enable_vblank(&rcdu->crtcs[crtc], true); ++ ++ return 0; ++} ++ ++static void rcar_du_disable_vblank(struct drm_device *dev, int crtc) ++{ ++ struct rcar_du_device *rcdu = dev->dev_private; ++ ++ rcar_du_crtc_enable_vblank(&rcdu->crtcs[crtc], false); ++} ++ ++static const struct file_operations rcar_du_fops = { ++ .owner = THIS_MODULE, ++ .open = drm_open, ++ .release = drm_release, ++ .unlocked_ioctl = drm_ioctl, ++#ifdef CONFIG_COMPAT ++ .compat_ioctl = drm_compat_ioctl, ++#endif ++ .poll = drm_poll, ++ .read = drm_read, ++ .fasync = drm_fasync, ++ .llseek = no_llseek, ++ .mmap = drm_gem_cma_mmap, ++}; ++ ++static struct drm_driver rcar_du_driver = { ++ .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET ++ | DRIVER_PRIME, ++ .load = rcar_du_load, ++ .unload = rcar_du_unload, ++ .preclose = rcar_du_preclose, ++ .irq_handler = rcar_du_irq, ++ .get_vblank_counter = drm_vblank_count, ++ .enable_vblank = rcar_du_enable_vblank, ++ .disable_vblank = rcar_du_disable_vblank, ++ .gem_free_object = drm_gem_cma_free_object, ++ .gem_vm_ops = &drm_gem_cma_vm_ops, ++ .prime_handle_to_fd = drm_gem_prime_handle_to_fd, ++ .prime_fd_to_handle = drm_gem_prime_fd_to_handle, ++ .gem_prime_import = drm_gem_cma_dmabuf_import, ++ .gem_prime_export = drm_gem_cma_dmabuf_export, ++ .dumb_create = drm_gem_cma_dumb_create, ++ .dumb_map_offset = drm_gem_cma_dumb_map_offset, ++ .dumb_destroy = drm_gem_cma_dumb_destroy, ++ .fops = &rcar_du_fops, ++ .name = "rcar-du", ++ .desc = "Renesas R-Car Display Unit", ++ .date = "20130110", ++ .major = 1, ++ .minor = 0, ++}; ++ ++/* ----------------------------------------------------------------------------- ++ * Power management ++ */ ++ ++#if CONFIG_PM_SLEEP ++static int rcar_du_pm_suspend(struct device *dev) ++{ ++ struct rcar_du_device *rcdu = dev_get_drvdata(dev); ++ ++ drm_kms_helper_poll_disable(rcdu->ddev); ++ /* TODO Suspend the CRTC */ ++ ++ return 0; ++} ++ ++static int rcar_du_pm_resume(struct device *dev) ++{ ++ struct rcar_du_device *rcdu = dev_get_drvdata(dev); ++ ++ /* TODO Resume the CRTC */ ++ ++ drm_kms_helper_poll_enable(rcdu->ddev); ++ return 0; ++} ++#endif ++ ++static const struct dev_pm_ops rcar_du_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(rcar_du_pm_suspend, rcar_du_pm_resume) ++}; ++ ++/* ----------------------------------------------------------------------------- ++ * Platform driver ++ */ ++ ++static int rcar_du_probe(struct platform_device *pdev) ++{ ++ return drm_platform_init(&rcar_du_driver, pdev); ++} ++ ++static int rcar_du_remove(struct platform_device *pdev) ++{ ++ drm_platform_exit(&rcar_du_driver, pdev); ++ ++ return 0; ++} ++ ++static struct platform_driver rcar_du_platform_driver = { ++ .probe = rcar_du_probe, ++ .remove = rcar_du_remove, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "rcar-du", ++ .pm = &rcar_du_pm_ops, ++ }, ++}; ++ ++module_platform_driver(rcar_du_platform_driver); ++ ++MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); ++MODULE_DESCRIPTION("Renesas R-Car Display Unit DRM Driver"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +new file mode 100644 +index 000000000000..193cc59d495c +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +@@ -0,0 +1,66 @@ ++/* ++ * rcar_du_drv.h -- R-Car Display Unit DRM driver ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#ifndef __RCAR_DU_DRV_H__ ++#define __RCAR_DU_DRV_H__ ++ ++#include <linux/kernel.h> ++#include <linux/mutex.h> ++#include <linux/platform_data/rcar-du.h> ++ ++#include "rcar_du_crtc.h" ++#include "rcar_du_plane.h" ++ ++struct clk; ++struct device; ++struct drm_device; ++ ++struct rcar_du_device { ++ struct device *dev; ++ const struct rcar_du_platform_data *pdata; ++ ++ void __iomem *mmio; ++ struct clk *clock; ++ unsigned int use_count; ++ ++ struct drm_device *ddev; ++ ++ struct rcar_du_crtc crtcs[2]; ++ unsigned int used_crtcs; ++ unsigned int num_crtcs; ++ ++ struct { ++ struct rcar_du_plane planes[RCAR_DU_NUM_SW_PLANES]; ++ unsigned int free; ++ struct mutex lock; ++ ++ struct drm_property *alpha; ++ struct drm_property *colorkey; ++ struct drm_property *zpos; ++ } planes; ++}; ++ ++int rcar_du_get(struct rcar_du_device *rcdu); ++void rcar_du_put(struct rcar_du_device *rcdu); ++ ++static inline u32 rcar_du_read(struct rcar_du_device *rcdu, u32 reg) ++{ ++ return ioread32(rcdu->mmio + reg); ++} ++ ++static inline void rcar_du_write(struct rcar_du_device *rcdu, u32 reg, u32 data) ++{ ++ iowrite32(data, rcdu->mmio + reg); ++} ++ ++#endif /* __RCAR_DU_DRV_H__ */ +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +new file mode 100644 +index 000000000000..9c63f39658de +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +@@ -0,0 +1,245 @@ ++/* ++ * rcar_du_kms.c -- R-Car Display Unit Mode Setting ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <drm/drmP.h> ++#include <drm/drm_crtc.h> ++#include <drm/drm_crtc_helper.h> ++#include <drm/drm_fb_cma_helper.h> ++#include <drm/drm_gem_cma_helper.h> ++ ++#include "rcar_du_crtc.h" ++#include "rcar_du_drv.h" ++#include "rcar_du_kms.h" ++#include "rcar_du_lvds.h" ++#include "rcar_du_regs.h" ++#include "rcar_du_vga.h" ++ ++/* ----------------------------------------------------------------------------- ++ * Format helpers ++ */ ++ ++static const struct rcar_du_format_info rcar_du_format_infos[] = { ++ { ++ .fourcc = DRM_FORMAT_RGB565, ++ .bpp = 16, ++ .planes = 1, ++ .pnmr = PnMR_SPIM_TP | PnMR_DDDF_16BPP, ++ .edf = PnDDCR4_EDF_NONE, ++ }, { ++ .fourcc = DRM_FORMAT_ARGB1555, ++ .bpp = 16, ++ .planes = 1, ++ .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_ARGB, ++ .edf = PnDDCR4_EDF_NONE, ++ }, { ++ .fourcc = DRM_FORMAT_XRGB1555, ++ .bpp = 16, ++ .planes = 1, ++ .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_ARGB, ++ .edf = PnDDCR4_EDF_NONE, ++ }, { ++ .fourcc = DRM_FORMAT_XRGB8888, ++ .bpp = 32, ++ .planes = 1, ++ .pnmr = PnMR_SPIM_TP | PnMR_DDDF_16BPP, ++ .edf = PnDDCR4_EDF_RGB888, ++ }, { ++ .fourcc = DRM_FORMAT_ARGB8888, ++ .bpp = 32, ++ .planes = 1, ++ .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_16BPP, ++ .edf = PnDDCR4_EDF_ARGB8888, ++ }, { ++ .fourcc = DRM_FORMAT_UYVY, ++ .bpp = 16, ++ .planes = 1, ++ .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC, ++ .edf = PnDDCR4_EDF_NONE, ++ }, { ++ .fourcc = DRM_FORMAT_YUYV, ++ .bpp = 16, ++ .planes = 1, ++ .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC, ++ .edf = PnDDCR4_EDF_NONE, ++ }, { ++ .fourcc = DRM_FORMAT_NV12, ++ .bpp = 12, ++ .planes = 2, ++ .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC, ++ .edf = PnDDCR4_EDF_NONE, ++ }, { ++ .fourcc = DRM_FORMAT_NV21, ++ .bpp = 12, ++ .planes = 2, ++ .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC, ++ .edf = PnDDCR4_EDF_NONE, ++ }, { ++ /* In YUV 4:2:2, only NV16 is supported (NV61 isn't) */ ++ .fourcc = DRM_FORMAT_NV16, ++ .bpp = 16, ++ .planes = 2, ++ .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC, ++ .edf = PnDDCR4_EDF_NONE, ++ }, ++}; ++ ++const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(rcar_du_format_infos); ++i) { ++ if (rcar_du_format_infos[i].fourcc == fourcc) ++ return &rcar_du_format_infos[i]; ++ } ++ ++ return NULL; ++} ++ ++/* ----------------------------------------------------------------------------- ++ * Common connector and encoder functions ++ */ ++ ++struct drm_encoder * ++rcar_du_connector_best_encoder(struct drm_connector *connector) ++{ ++ struct rcar_du_connector *rcon = to_rcar_connector(connector); ++ ++ return &rcon->encoder->encoder; ++} ++ ++void rcar_du_encoder_mode_prepare(struct drm_encoder *encoder) ++{ ++} ++ ++void rcar_du_encoder_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct rcar_du_encoder *renc = to_rcar_encoder(encoder); ++ ++ rcar_du_crtc_route_output(encoder->crtc, renc->output); ++} ++ ++void rcar_du_encoder_mode_commit(struct drm_encoder *encoder) ++{ ++} ++ ++/* ----------------------------------------------------------------------------- ++ * Frame buffer ++ */ ++ ++static struct drm_framebuffer * ++rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv, ++ struct drm_mode_fb_cmd2 *mode_cmd) ++{ ++ const struct rcar_du_format_info *format; ++ ++ format = rcar_du_format_info(mode_cmd->pixel_format); ++ if (format == NULL) { ++ dev_dbg(dev->dev, "unsupported pixel format %08x\n", ++ mode_cmd->pixel_format); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ if (mode_cmd->pitches[0] & 15 || mode_cmd->pitches[0] >= 8192) { ++ dev_dbg(dev->dev, "invalid pitch value %u\n", ++ mode_cmd->pitches[0]); ++ return ERR_PTR(-EINVAL); ++ } ++ ++ if (format->planes == 2) { ++ if (mode_cmd->pitches[1] != mode_cmd->pitches[0]) { ++ dev_dbg(dev->dev, ++ "luma and chroma pitches do not match\n"); ++ return ERR_PTR(-EINVAL); ++ } ++ } ++ ++ return drm_fb_cma_create(dev, file_priv, mode_cmd); ++} ++ ++static const struct drm_mode_config_funcs rcar_du_mode_config_funcs = { ++ .fb_create = rcar_du_fb_create, ++}; ++ ++int rcar_du_modeset_init(struct rcar_du_device *rcdu) ++{ ++ struct drm_device *dev = rcdu->ddev; ++ struct drm_encoder *encoder; ++ unsigned int i; ++ int ret; ++ ++ drm_mode_config_init(rcdu->ddev); ++ ++ rcdu->ddev->mode_config.min_width = 0; ++ rcdu->ddev->mode_config.min_height = 0; ++ rcdu->ddev->mode_config.max_width = 4095; ++ rcdu->ddev->mode_config.max_height = 2047; ++ rcdu->ddev->mode_config.funcs = &rcar_du_mode_config_funcs; ++ ++ ret = rcar_du_plane_init(rcdu); ++ if (ret < 0) ++ return ret; ++ ++ for (i = 0; i < ARRAY_SIZE(rcdu->crtcs); ++i) ++ rcar_du_crtc_create(rcdu, i); ++ ++ rcdu->used_crtcs = 0; ++ rcdu->num_crtcs = i; ++ ++ for (i = 0; i < rcdu->pdata->num_encoders; ++i) { ++ const struct rcar_du_encoder_data *pdata = ++ &rcdu->pdata->encoders[i]; ++ ++ if (pdata->output >= ARRAY_SIZE(rcdu->crtcs)) { ++ dev_warn(rcdu->dev, ++ "encoder %u references unexisting output %u, skipping\n", ++ i, pdata->output); ++ continue; ++ } ++ ++ switch (pdata->encoder) { ++ case RCAR_DU_ENCODER_VGA: ++ rcar_du_vga_init(rcdu, &pdata->u.vga, pdata->output); ++ break; ++ ++ case RCAR_DU_ENCODER_LVDS: ++ rcar_du_lvds_init(rcdu, &pdata->u.lvds, pdata->output); ++ break; ++ ++ default: ++ break; ++ } ++ } ++ ++ /* Set the possible CRTCs and possible clones. All encoders can be ++ * driven by the CRTC associated with the output they're connected to, ++ * as well as by CRTC 0. ++ */ ++ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { ++ struct rcar_du_encoder *renc = to_rcar_encoder(encoder); ++ ++ encoder->possible_crtcs = (1 << 0) | (1 << renc->output); ++ encoder->possible_clones = 1 << 0; ++ } ++ ++ ret = rcar_du_plane_register(rcdu); ++ if (ret < 0) ++ return ret; ++ ++ drm_kms_helper_poll_init(rcdu->ddev); ++ ++ drm_helper_disable_unused_functions(rcdu->ddev); ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.h b/drivers/gpu/drm/rcar-du/rcar_du_kms.h +new file mode 100644 +index 000000000000..e4d8db069a06 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.h +@@ -0,0 +1,59 @@ ++/* ++ * rcar_du_kms.h -- R-Car Display Unit Mode Setting ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#ifndef __RCAR_DU_KMS_H__ ++#define __RCAR_DU_KMS_H__ ++ ++#include <linux/types.h> ++ ++#include <drm/drm_crtc.h> ++ ++struct rcar_du_device; ++ ++struct rcar_du_format_info { ++ u32 fourcc; ++ unsigned int bpp; ++ unsigned int planes; ++ unsigned int pnmr; ++ unsigned int edf; ++}; ++ ++struct rcar_du_encoder { ++ struct drm_encoder encoder; ++ unsigned int output; ++}; ++ ++#define to_rcar_encoder(e) \ ++ container_of(e, struct rcar_du_encoder, encoder) ++ ++struct rcar_du_connector { ++ struct drm_connector connector; ++ struct rcar_du_encoder *encoder; ++}; ++ ++#define to_rcar_connector(c) \ ++ container_of(c, struct rcar_du_connector, connector) ++ ++const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc); ++ ++struct drm_encoder * ++rcar_du_connector_best_encoder(struct drm_connector *connector); ++void rcar_du_encoder_mode_prepare(struct drm_encoder *encoder); ++void rcar_du_encoder_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode); ++void rcar_du_encoder_mode_commit(struct drm_encoder *encoder); ++ ++int rcar_du_modeset_init(struct rcar_du_device *rcdu); ++ ++#endif /* __RCAR_DU_KMS_H__ */ +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvds.c b/drivers/gpu/drm/rcar-du/rcar_du_lvds.c +new file mode 100644 +index 000000000000..7aefe7267e1d +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_lvds.c +@@ -0,0 +1,216 @@ ++/* ++ * rcar_du_lvds.c -- R-Car Display Unit LVDS Encoder and Connector ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <drm/drmP.h> ++#include <drm/drm_crtc.h> ++#include <drm/drm_crtc_helper.h> ++ ++#include "rcar_du_drv.h" ++#include "rcar_du_kms.h" ++#include "rcar_du_lvds.h" ++ ++struct rcar_du_lvds_connector { ++ struct rcar_du_connector connector; ++ ++ const struct rcar_du_panel_data *panel; ++}; ++ ++#define to_rcar_lvds_connector(c) \ ++ container_of(c, struct rcar_du_lvds_connector, connector.connector) ++ ++/* ----------------------------------------------------------------------------- ++ * Connector ++ */ ++ ++static int rcar_du_lvds_connector_get_modes(struct drm_connector *connector) ++{ ++ struct rcar_du_lvds_connector *lvdscon = to_rcar_lvds_connector(connector); ++ struct drm_display_mode *mode; ++ ++ mode = drm_mode_create(connector->dev); ++ if (mode == NULL) ++ return 0; ++ ++ mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; ++ mode->clock = lvdscon->panel->mode.clock; ++ mode->hdisplay = lvdscon->panel->mode.hdisplay; ++ mode->hsync_start = lvdscon->panel->mode.hsync_start; ++ mode->hsync_end = lvdscon->panel->mode.hsync_end; ++ mode->htotal = lvdscon->panel->mode.htotal; ++ mode->vdisplay = lvdscon->panel->mode.vdisplay; ++ mode->vsync_start = lvdscon->panel->mode.vsync_start; ++ mode->vsync_end = lvdscon->panel->mode.vsync_end; ++ mode->vtotal = lvdscon->panel->mode.vtotal; ++ mode->flags = lvdscon->panel->mode.flags; ++ ++ drm_mode_set_name(mode); ++ drm_mode_probed_add(connector, mode); ++ ++ return 1; ++} ++ ++static int rcar_du_lvds_connector_mode_valid(struct drm_connector *connector, ++ struct drm_display_mode *mode) ++{ ++ return MODE_OK; ++} ++ ++static const struct drm_connector_helper_funcs connector_helper_funcs = { ++ .get_modes = rcar_du_lvds_connector_get_modes, ++ .mode_valid = rcar_du_lvds_connector_mode_valid, ++ .best_encoder = rcar_du_connector_best_encoder, ++}; ++ ++static void rcar_du_lvds_connector_destroy(struct drm_connector *connector) ++{ ++ drm_sysfs_connector_remove(connector); ++ drm_connector_cleanup(connector); ++} ++ ++static enum drm_connector_status ++rcar_du_lvds_connector_detect(struct drm_connector *connector, bool force) ++{ ++ return connector_status_connected; ++} ++ ++static const struct drm_connector_funcs connector_funcs = { ++ .dpms = drm_helper_connector_dpms, ++ .detect = rcar_du_lvds_connector_detect, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .destroy = rcar_du_lvds_connector_destroy, ++}; ++ ++static int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu, ++ struct rcar_du_encoder *renc, ++ const struct rcar_du_panel_data *panel) ++{ ++ struct rcar_du_lvds_connector *lvdscon; ++ struct drm_connector *connector; ++ int ret; ++ ++ lvdscon = devm_kzalloc(rcdu->dev, sizeof(*lvdscon), GFP_KERNEL); ++ if (lvdscon == NULL) ++ return -ENOMEM; ++ ++ lvdscon->panel = panel; ++ ++ connector = &lvdscon->connector.connector; ++ connector->display_info.width_mm = panel->width_mm; ++ connector->display_info.height_mm = panel->height_mm; ++ ++ ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs, ++ DRM_MODE_CONNECTOR_LVDS); ++ if (ret < 0) ++ return ret; ++ ++ drm_connector_helper_add(connector, &connector_helper_funcs); ++ ret = drm_sysfs_connector_add(connector); ++ if (ret < 0) ++ return ret; ++ ++ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); ++ drm_object_property_set_value(&connector->base, ++ rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF); ++ ++ ret = drm_mode_connector_attach_encoder(connector, &renc->encoder); ++ if (ret < 0) ++ return ret; ++ ++ connector->encoder = &renc->encoder; ++ lvdscon->connector.encoder = renc; ++ ++ return 0; ++} ++ ++/* ----------------------------------------------------------------------------- ++ * Encoder ++ */ ++ ++static void rcar_du_lvds_encoder_dpms(struct drm_encoder *encoder, int mode) ++{ ++} ++ ++static bool rcar_du_lvds_encoder_mode_fixup(struct drm_encoder *encoder, ++ const struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ const struct drm_display_mode *panel_mode; ++ struct drm_device *dev = encoder->dev; ++ struct drm_connector *connector; ++ bool found = false; ++ ++ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { ++ if (connector->encoder == encoder) { ++ found = true; ++ break; ++ } ++ } ++ ++ if (!found) { ++ dev_dbg(dev->dev, "mode_fixup: no connector found\n"); ++ return false; ++ } ++ ++ if (list_empty(&connector->modes)) { ++ dev_dbg(dev->dev, "mode_fixup: empty modes list\n"); ++ return false; ++ } ++ ++ panel_mode = list_first_entry(&connector->modes, ++ struct drm_display_mode, head); ++ ++ /* We're not allowed to modify the resolution. */ ++ if (mode->hdisplay != panel_mode->hdisplay || ++ mode->vdisplay != panel_mode->vdisplay) ++ return false; ++ ++ /* The flat panel mode is fixed, just copy it to the adjusted mode. */ ++ drm_mode_copy(adjusted_mode, panel_mode); ++ ++ return true; ++} ++ ++static const struct drm_encoder_helper_funcs encoder_helper_funcs = { ++ .dpms = rcar_du_lvds_encoder_dpms, ++ .mode_fixup = rcar_du_lvds_encoder_mode_fixup, ++ .prepare = rcar_du_encoder_mode_prepare, ++ .commit = rcar_du_encoder_mode_commit, ++ .mode_set = rcar_du_encoder_mode_set, ++}; ++ ++static const struct drm_encoder_funcs encoder_funcs = { ++ .destroy = drm_encoder_cleanup, ++}; ++ ++int rcar_du_lvds_init(struct rcar_du_device *rcdu, ++ const struct rcar_du_encoder_lvds_data *data, ++ unsigned int output) ++{ ++ struct rcar_du_encoder *renc; ++ int ret; ++ ++ renc = devm_kzalloc(rcdu->dev, sizeof(*renc), GFP_KERNEL); ++ if (renc == NULL) ++ return -ENOMEM; ++ ++ renc->output = output; ++ ++ ret = drm_encoder_init(rcdu->ddev, &renc->encoder, &encoder_funcs, ++ DRM_MODE_ENCODER_LVDS); ++ if (ret < 0) ++ return ret; ++ ++ drm_encoder_helper_add(&renc->encoder, &encoder_helper_funcs); ++ ++ return rcar_du_lvds_connector_init(rcdu, renc, &data->panel); ++} +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvds.h b/drivers/gpu/drm/rcar-du/rcar_du_lvds.h +new file mode 100644 +index 000000000000..b47f8328e103 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_lvds.h +@@ -0,0 +1,24 @@ ++/* ++ * rcar_du_lvds.h -- R-Car Display Unit LVDS Encoder and Connector ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#ifndef __RCAR_DU_LVDS_H__ ++#define __RCAR_DU_LVDS_H__ ++ ++struct rcar_du_device; ++struct rcar_du_encoder_lvds_data; ++ ++int rcar_du_lvds_init(struct rcar_du_device *rcdu, ++ const struct rcar_du_encoder_lvds_data *data, ++ unsigned int output); ++ ++#endif /* __RCAR_DU_LVDS_H__ */ +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c +new file mode 100644 +index 000000000000..a65f81ddf51d +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c +@@ -0,0 +1,507 @@ ++/* ++ * rcar_du_plane.c -- R-Car Display Unit Planes ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <drm/drmP.h> ++#include <drm/drm_crtc.h> ++#include <drm/drm_crtc_helper.h> ++#include <drm/drm_fb_cma_helper.h> ++#include <drm/drm_gem_cma_helper.h> ++ ++#include "rcar_du_drv.h" ++#include "rcar_du_kms.h" ++#include "rcar_du_plane.h" ++#include "rcar_du_regs.h" ++ ++#define RCAR_DU_COLORKEY_NONE (0 << 24) ++#define RCAR_DU_COLORKEY_SOURCE (1 << 24) ++#define RCAR_DU_COLORKEY_MASK (1 << 24) ++ ++struct rcar_du_kms_plane { ++ struct drm_plane plane; ++ struct rcar_du_plane *hwplane; ++}; ++ ++static inline struct rcar_du_plane *to_rcar_plane(struct drm_plane *plane) ++{ ++ return container_of(plane, struct rcar_du_kms_plane, plane)->hwplane; ++} ++ ++static u32 rcar_du_plane_read(struct rcar_du_device *rcdu, ++ unsigned int index, u32 reg) ++{ ++ return rcar_du_read(rcdu, index * PLANE_OFF + reg); ++} ++ ++static void rcar_du_plane_write(struct rcar_du_device *rcdu, ++ unsigned int index, u32 reg, u32 data) ++{ ++ rcar_du_write(rcdu, index * PLANE_OFF + reg, data); ++} ++ ++int rcar_du_plane_reserve(struct rcar_du_plane *plane, ++ const struct rcar_du_format_info *format) ++{ ++ struct rcar_du_device *rcdu = plane->dev; ++ unsigned int i; ++ int ret = -EBUSY; ++ ++ mutex_lock(&rcdu->planes.lock); ++ ++ for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) { ++ if (!(rcdu->planes.free & (1 << i))) ++ continue; ++ ++ if (format->planes == 1 || ++ rcdu->planes.free & (1 << ((i + 1) % 8))) ++ break; ++ } ++ ++ if (i == ARRAY_SIZE(rcdu->planes.planes)) ++ goto done; ++ ++ rcdu->planes.free &= ~(1 << i); ++ if (format->planes == 2) ++ rcdu->planes.free &= ~(1 << ((i + 1) % 8)); ++ ++ plane->hwindex = i; ++ ++ ret = 0; ++ ++done: ++ mutex_unlock(&rcdu->planes.lock); ++ return ret; ++} ++ ++void rcar_du_plane_release(struct rcar_du_plane *plane) ++{ ++ struct rcar_du_device *rcdu = plane->dev; ++ ++ if (plane->hwindex == -1) ++ return; ++ ++ mutex_lock(&rcdu->planes.lock); ++ rcdu->planes.free |= 1 << plane->hwindex; ++ if (plane->format->planes == 2) ++ rcdu->planes.free |= 1 << ((plane->hwindex + 1) % 8); ++ mutex_unlock(&rcdu->planes.lock); ++ ++ plane->hwindex = -1; ++} ++ ++void rcar_du_plane_update_base(struct rcar_du_plane *plane) ++{ ++ struct rcar_du_device *rcdu = plane->dev; ++ unsigned int index = plane->hwindex; ++ ++ /* According to the datasheet the Y position is expressed in raster line ++ * units. However, 32bpp formats seem to require a doubled Y position ++ * value. Similarly, for the second plane, NV12 and NV21 formats seem to ++ * require a halved Y position value. ++ */ ++ rcar_du_plane_write(rcdu, index, PnSPXR, plane->src_x); ++ rcar_du_plane_write(rcdu, index, PnSPYR, plane->src_y * ++ (plane->format->bpp == 32 ? 2 : 1)); ++ rcar_du_plane_write(rcdu, index, PnDSA0R, plane->dma[0]); ++ ++ if (plane->format->planes == 2) { ++ index = (index + 1) % 8; ++ ++ rcar_du_plane_write(rcdu, index, PnSPXR, plane->src_x); ++ rcar_du_plane_write(rcdu, index, PnSPYR, plane->src_y * ++ (plane->format->bpp == 16 ? 2 : 1) / 2); ++ rcar_du_plane_write(rcdu, index, PnDSA0R, plane->dma[1]); ++ } ++} ++ ++void rcar_du_plane_compute_base(struct rcar_du_plane *plane, ++ struct drm_framebuffer *fb) ++{ ++ struct drm_gem_cma_object *gem; ++ ++ gem = drm_fb_cma_get_gem_obj(fb, 0); ++ plane->dma[0] = gem->paddr + fb->offsets[0]; ++ ++ if (plane->format->planes == 2) { ++ gem = drm_fb_cma_get_gem_obj(fb, 1); ++ plane->dma[1] = gem->paddr + fb->offsets[1]; ++ } ++} ++ ++static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane, ++ unsigned int index) ++{ ++ struct rcar_du_device *rcdu = plane->dev; ++ u32 colorkey; ++ u32 pnmr; ++ ++ /* The PnALPHAR register controls alpha-blending in 16bpp formats ++ * (ARGB1555 and XRGB1555). ++ * ++ * For ARGB, set the alpha value to 0, and enable alpha-blending when ++ * the A bit is 0. This maps A=0 to alpha=0 and A=1 to alpha=255. ++ * ++ * For XRGB, set the alpha value to the plane-wide alpha value and ++ * enable alpha-blending regardless of the X bit value. ++ */ ++ if (plane->format->fourcc != DRM_FORMAT_XRGB1555) ++ rcar_du_plane_write(rcdu, index, PnALPHAR, PnALPHAR_ABIT_0); ++ else ++ rcar_du_plane_write(rcdu, index, PnALPHAR, ++ PnALPHAR_ABIT_X | plane->alpha); ++ ++ pnmr = PnMR_BM_MD | plane->format->pnmr; ++ ++ /* Disable color keying when requested. YUV formats have the ++ * PnMR_SPIM_TP_OFF bit set in their pnmr field, disabling color keying ++ * automatically. ++ */ ++ if ((plane->colorkey & RCAR_DU_COLORKEY_MASK) == RCAR_DU_COLORKEY_NONE) ++ pnmr |= PnMR_SPIM_TP_OFF; ++ ++ /* For packed YUV formats we need to select the U/V order. */ ++ if (plane->format->fourcc == DRM_FORMAT_YUYV) ++ pnmr |= PnMR_YCDF_YUYV; ++ ++ rcar_du_plane_write(rcdu, index, PnMR, pnmr); ++ ++ switch (plane->format->fourcc) { ++ case DRM_FORMAT_RGB565: ++ colorkey = ((plane->colorkey & 0xf80000) >> 8) ++ | ((plane->colorkey & 0x00fc00) >> 5) ++ | ((plane->colorkey & 0x0000f8) >> 3); ++ rcar_du_plane_write(rcdu, index, PnTC2R, colorkey); ++ break; ++ ++ case DRM_FORMAT_ARGB1555: ++ case DRM_FORMAT_XRGB1555: ++ colorkey = ((plane->colorkey & 0xf80000) >> 9) ++ | ((plane->colorkey & 0x00f800) >> 6) ++ | ((plane->colorkey & 0x0000f8) >> 3); ++ rcar_du_plane_write(rcdu, index, PnTC2R, colorkey); ++ break; ++ ++ case DRM_FORMAT_XRGB8888: ++ case DRM_FORMAT_ARGB8888: ++ rcar_du_plane_write(rcdu, index, PnTC3R, ++ PnTC3R_CODE | (plane->colorkey & 0xffffff)); ++ break; ++ } ++} ++ ++static void __rcar_du_plane_setup(struct rcar_du_plane *plane, ++ unsigned int index) ++{ ++ struct rcar_du_device *rcdu = plane->dev; ++ u32 ddcr2 = PnDDCR2_CODE; ++ u32 ddcr4; ++ u32 mwr; ++ ++ /* Data format ++ * ++ * The data format is selected by the DDDF field in PnMR and the EDF ++ * field in DDCR4. ++ */ ++ ddcr4 = rcar_du_plane_read(rcdu, index, PnDDCR4); ++ ddcr4 &= ~PnDDCR4_EDF_MASK; ++ ddcr4 |= plane->format->edf | PnDDCR4_CODE; ++ ++ rcar_du_plane_setup_mode(plane, index); ++ ++ if (plane->format->planes == 2) { ++ if (plane->hwindex != index) { ++ if (plane->format->fourcc == DRM_FORMAT_NV12 || ++ plane->format->fourcc == DRM_FORMAT_NV21) ++ ddcr2 |= PnDDCR2_Y420; ++ ++ if (plane->format->fourcc == DRM_FORMAT_NV21) ++ ddcr2 |= PnDDCR2_NV21; ++ ++ ddcr2 |= PnDDCR2_DIVU; ++ } else { ++ ddcr2 |= PnDDCR2_DIVY; ++ } ++ } ++ ++ rcar_du_plane_write(rcdu, index, PnDDCR2, ddcr2); ++ rcar_du_plane_write(rcdu, index, PnDDCR4, ddcr4); ++ ++ /* Memory pitch (expressed in pixels) */ ++ if (plane->format->planes == 2) ++ mwr = plane->pitch; ++ else ++ mwr = plane->pitch * 8 / plane->format->bpp; ++ ++ rcar_du_plane_write(rcdu, index, PnMWR, mwr); ++ ++ /* Destination position and size */ ++ rcar_du_plane_write(rcdu, index, PnDSXR, plane->width); ++ rcar_du_plane_write(rcdu, index, PnDSYR, plane->height); ++ rcar_du_plane_write(rcdu, index, PnDPXR, plane->dst_x); ++ rcar_du_plane_write(rcdu, index, PnDPYR, plane->dst_y); ++ ++ /* Wrap-around and blinking, disabled */ ++ rcar_du_plane_write(rcdu, index, PnWASPR, 0); ++ rcar_du_plane_write(rcdu, index, PnWAMWR, 4095); ++ rcar_du_plane_write(rcdu, index, PnBTR, 0); ++ rcar_du_plane_write(rcdu, index, PnMLR, 0); ++} ++ ++void rcar_du_plane_setup(struct rcar_du_plane *plane) ++{ ++ __rcar_du_plane_setup(plane, plane->hwindex); ++ if (plane->format->planes == 2) ++ __rcar_du_plane_setup(plane, (plane->hwindex + 1) % 8); ++ ++ rcar_du_plane_update_base(plane); ++} ++ ++static int ++rcar_du_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, ++ struct drm_framebuffer *fb, int crtc_x, int crtc_y, ++ unsigned int crtc_w, unsigned int crtc_h, ++ uint32_t src_x, uint32_t src_y, ++ uint32_t src_w, uint32_t src_h) ++{ ++ struct rcar_du_plane *rplane = to_rcar_plane(plane); ++ struct rcar_du_device *rcdu = plane->dev->dev_private; ++ const struct rcar_du_format_info *format; ++ unsigned int nplanes; ++ int ret; ++ ++ format = rcar_du_format_info(fb->pixel_format); ++ if (format == NULL) { ++ dev_dbg(rcdu->dev, "%s: unsupported format %08x\n", __func__, ++ fb->pixel_format); ++ return -EINVAL; ++ } ++ ++ if (src_w >> 16 != crtc_w || src_h >> 16 != crtc_h) { ++ dev_dbg(rcdu->dev, "%s: scaling not supported\n", __func__); ++ return -EINVAL; ++ } ++ ++ nplanes = rplane->format ? rplane->format->planes : 0; ++ ++ /* Reallocate hardware planes if the number of required planes has ++ * changed. ++ */ ++ if (format->planes != nplanes) { ++ rcar_du_plane_release(rplane); ++ ret = rcar_du_plane_reserve(rplane, format); ++ if (ret < 0) ++ return ret; ++ } ++ ++ rplane->crtc = crtc; ++ rplane->format = format; ++ rplane->pitch = fb->pitches[0]; ++ ++ rplane->src_x = src_x >> 16; ++ rplane->src_y = src_y >> 16; ++ rplane->dst_x = crtc_x; ++ rplane->dst_y = crtc_y; ++ rplane->width = crtc_w; ++ rplane->height = crtc_h; ++ ++ rcar_du_plane_compute_base(rplane, fb); ++ rcar_du_plane_setup(rplane); ++ ++ mutex_lock(&rcdu->planes.lock); ++ rplane->enabled = true; ++ rcar_du_crtc_update_planes(rplane->crtc); ++ mutex_unlock(&rcdu->planes.lock); ++ ++ return 0; ++} ++ ++static int rcar_du_plane_disable(struct drm_plane *plane) ++{ ++ struct rcar_du_device *rcdu = plane->dev->dev_private; ++ struct rcar_du_plane *rplane = to_rcar_plane(plane); ++ ++ if (!rplane->enabled) ++ return 0; ++ ++ mutex_lock(&rcdu->planes.lock); ++ rplane->enabled = false; ++ rcar_du_crtc_update_planes(rplane->crtc); ++ mutex_unlock(&rcdu->planes.lock); ++ ++ rcar_du_plane_release(rplane); ++ ++ rplane->crtc = NULL; ++ rplane->format = NULL; ++ ++ return 0; ++} ++ ++/* Both the .set_property and the .update_plane operations are called with the ++ * mode_config lock held. There is this no need to explicitly protect access to ++ * the alpha and colorkey fields and the mode register. ++ */ ++static void rcar_du_plane_set_alpha(struct rcar_du_plane *plane, u32 alpha) ++{ ++ if (plane->alpha == alpha) ++ return; ++ ++ plane->alpha = alpha; ++ if (!plane->enabled || plane->format->fourcc != DRM_FORMAT_XRGB1555) ++ return; ++ ++ rcar_du_plane_setup_mode(plane, plane->hwindex); ++} ++ ++static void rcar_du_plane_set_colorkey(struct rcar_du_plane *plane, ++ u32 colorkey) ++{ ++ if (plane->colorkey == colorkey) ++ return; ++ ++ plane->colorkey = colorkey; ++ if (!plane->enabled) ++ return; ++ ++ rcar_du_plane_setup_mode(plane, plane->hwindex); ++} ++ ++static void rcar_du_plane_set_zpos(struct rcar_du_plane *plane, ++ unsigned int zpos) ++{ ++ struct rcar_du_device *rcdu = plane->dev; ++ ++ mutex_lock(&rcdu->planes.lock); ++ if (plane->zpos == zpos) ++ goto done; ++ ++ plane->zpos = zpos; ++ if (!plane->enabled) ++ goto done; ++ ++ rcar_du_crtc_update_planes(plane->crtc); ++ ++done: ++ mutex_unlock(&rcdu->planes.lock); ++} ++ ++static int rcar_du_plane_set_property(struct drm_plane *plane, ++ struct drm_property *property, ++ uint64_t value) ++{ ++ struct rcar_du_device *rcdu = plane->dev->dev_private; ++ struct rcar_du_plane *rplane = to_rcar_plane(plane); ++ ++ if (property == rcdu->planes.alpha) ++ rcar_du_plane_set_alpha(rplane, value); ++ else if (property == rcdu->planes.colorkey) ++ rcar_du_plane_set_colorkey(rplane, value); ++ else if (property == rcdu->planes.zpos) ++ rcar_du_plane_set_zpos(rplane, value); ++ else ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static const struct drm_plane_funcs rcar_du_plane_funcs = { ++ .update_plane = rcar_du_plane_update, ++ .disable_plane = rcar_du_plane_disable, ++ .set_property = rcar_du_plane_set_property, ++ .destroy = drm_plane_cleanup, ++}; ++ ++static const uint32_t formats[] = { ++ DRM_FORMAT_RGB565, ++ DRM_FORMAT_ARGB1555, ++ DRM_FORMAT_XRGB1555, ++ DRM_FORMAT_XRGB8888, ++ DRM_FORMAT_ARGB8888, ++ DRM_FORMAT_UYVY, ++ DRM_FORMAT_YUYV, ++ DRM_FORMAT_NV12, ++ DRM_FORMAT_NV21, ++ DRM_FORMAT_NV16, ++}; ++ ++int rcar_du_plane_init(struct rcar_du_device *rcdu) ++{ ++ unsigned int i; ++ ++ mutex_init(&rcdu->planes.lock); ++ rcdu->planes.free = 0xff; ++ ++ rcdu->planes.alpha = ++ drm_property_create_range(rcdu->ddev, 0, "alpha", 0, 255); ++ if (rcdu->planes.alpha == NULL) ++ return -ENOMEM; ++ ++ /* The color key is expressed as an RGB888 triplet stored in a 32-bit ++ * integer in XRGB8888 format. Bit 24 is used as a flag to disable (0) ++ * or enable source color keying (1). ++ */ ++ rcdu->planes.colorkey = ++ drm_property_create_range(rcdu->ddev, 0, "colorkey", ++ 0, 0x01ffffff); ++ if (rcdu->planes.colorkey == NULL) ++ return -ENOMEM; ++ ++ rcdu->planes.zpos = ++ drm_property_create_range(rcdu->ddev, 0, "zpos", 1, 7); ++ if (rcdu->planes.zpos == NULL) ++ return -ENOMEM; ++ ++ for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) { ++ struct rcar_du_plane *plane = &rcdu->planes.planes[i]; ++ ++ plane->dev = rcdu; ++ plane->hwindex = -1; ++ plane->alpha = 255; ++ plane->colorkey = RCAR_DU_COLORKEY_NONE; ++ plane->zpos = 0; ++ } ++ ++ return 0; ++} ++ ++int rcar_du_plane_register(struct rcar_du_device *rcdu) ++{ ++ unsigned int i; ++ int ret; ++ ++ for (i = 0; i < RCAR_DU_NUM_KMS_PLANES; ++i) { ++ struct rcar_du_kms_plane *plane; ++ ++ plane = devm_kzalloc(rcdu->dev, sizeof(*plane), GFP_KERNEL); ++ if (plane == NULL) ++ return -ENOMEM; ++ ++ plane->hwplane = &rcdu->planes.planes[i + 2]; ++ plane->hwplane->zpos = 1; ++ ++ ret = drm_plane_init(rcdu->ddev, &plane->plane, ++ (1 << rcdu->num_crtcs) - 1, ++ &rcar_du_plane_funcs, formats, ++ ARRAY_SIZE(formats), false); ++ if (ret < 0) ++ return ret; ++ ++ drm_object_attach_property(&plane->plane.base, ++ rcdu->planes.alpha, 255); ++ drm_object_attach_property(&plane->plane.base, ++ rcdu->planes.colorkey, ++ RCAR_DU_COLORKEY_NONE); ++ drm_object_attach_property(&plane->plane.base, ++ rcdu->planes.zpos, 1); ++ } ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h +new file mode 100644 +index 000000000000..5397dba2fe57 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h +@@ -0,0 +1,67 @@ ++/* ++ * rcar_du_plane.h -- R-Car Display Unit Planes ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#ifndef __RCAR_DU_PLANE_H__ ++#define __RCAR_DU_PLANE_H__ ++ ++struct drm_crtc; ++struct drm_framebuffer; ++struct rcar_du_device; ++struct rcar_du_format_info; ++ ++/* The RCAR DU has 8 hardware planes, shared between KMS planes and CRTCs. As ++ * using KMS planes requires at least one of the CRTCs being enabled, no more ++ * than 7 KMS planes can be available. We thus create 7 KMS planes and ++ * 9 software planes (one for each KMS planes and one for each CRTC). ++ */ ++ ++#define RCAR_DU_NUM_KMS_PLANES 7 ++#define RCAR_DU_NUM_HW_PLANES 8 ++#define RCAR_DU_NUM_SW_PLANES 9 ++ ++struct rcar_du_plane { ++ struct rcar_du_device *dev; ++ struct drm_crtc *crtc; ++ ++ bool enabled; ++ ++ int hwindex; /* 0-based, -1 means unused */ ++ unsigned int alpha; ++ unsigned int colorkey; ++ unsigned int zpos; ++ ++ const struct rcar_du_format_info *format; ++ ++ unsigned long dma[2]; ++ unsigned int pitch; ++ ++ unsigned int width; ++ unsigned int height; ++ ++ unsigned int src_x; ++ unsigned int src_y; ++ unsigned int dst_x; ++ unsigned int dst_y; ++}; ++ ++int rcar_du_plane_init(struct rcar_du_device *rcdu); ++int rcar_du_plane_register(struct rcar_du_device *rcdu); ++void rcar_du_plane_setup(struct rcar_du_plane *plane); ++void rcar_du_plane_update_base(struct rcar_du_plane *plane); ++void rcar_du_plane_compute_base(struct rcar_du_plane *plane, ++ struct drm_framebuffer *fb); ++int rcar_du_plane_reserve(struct rcar_du_plane *plane, ++ const struct rcar_du_format_info *format); ++void rcar_du_plane_release(struct rcar_du_plane *plane); ++ ++#endif /* __RCAR_DU_PLANE_H__ */ +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_regs.h b/drivers/gpu/drm/rcar-du/rcar_du_regs.h +new file mode 100644 +index 000000000000..69f21f19b51c +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_regs.h +@@ -0,0 +1,445 @@ ++/* ++ * rcar_du_regs.h -- R-Car Display Unit Registers Definitions ++ * ++ * Copyright (C) 2013 Renesas Electronics Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 ++ * as published by the Free Software Foundation. ++ */ ++ ++#ifndef __RCAR_DU_REGS_H__ ++#define __RCAR_DU_REGS_H__ ++ ++#define DISP2_REG_OFFSET 0x30000 ++ ++/* ----------------------------------------------------------------------------- ++ * Display Control Registers ++ */ ++ ++#define DSYSR 0x00000 /* display 1 */ ++#define D2SYSR 0x30000 /* display 2 */ ++#define DSYSR_ILTS (1 << 29) ++#define DSYSR_DSEC (1 << 20) ++#define DSYSR_IUPD (1 << 16) ++#define DSYSR_DRES (1 << 9) ++#define DSYSR_DEN (1 << 8) ++#define DSYSR_TVM_MASTER (0 << 6) ++#define DSYSR_TVM_SWITCH (1 << 6) ++#define DSYSR_TVM_TVSYNC (2 << 6) ++#define DSYSR_TVM_MASK (3 << 6) ++#define DSYSR_SCM_INT_NONE (0 << 4) ++#define DSYSR_SCM_INT_SYNC (2 << 4) ++#define DSYSR_SCM_INT_VIDEO (3 << 4) ++ ++#define DSMR 0x00004 ++#define D2SMR 0x30004 ++#define DSMR_VSPM (1 << 28) ++#define DSMR_ODPM (1 << 27) ++#define DSMR_DIPM_DISP (0 << 25) ++#define DSMR_DIPM_CSYNC (1 << 25) ++#define DSMR_DIPM_DE (3 << 25) ++#define DSMR_DIPM_MASK (3 << 25) ++#define DSMR_CSPM (1 << 24) ++#define DSMR_DIL (1 << 19) ++#define DSMR_VSL (1 << 18) ++#define DSMR_HSL (1 << 17) ++#define DSMR_DDIS (1 << 16) ++#define DSMR_CDEL (1 << 15) ++#define DSMR_CDEM_CDE (0 << 13) ++#define DSMR_CDEM_LOW (2 << 13) ++#define DSMR_CDEM_HIGH (3 << 13) ++#define DSMR_CDEM_MASK (3 << 13) ++#define DSMR_CDED (1 << 12) ++#define DSMR_ODEV (1 << 8) ++#define DSMR_CSY_VH_OR (0 << 6) ++#define DSMR_CSY_333 (2 << 6) ++#define DSMR_CSY_222 (3 << 6) ++#define DSMR_CSY_MASK (3 << 6) ++ ++#define DSSR 0x00008 ++#define D2SSR 0x30008 ++#define DSSR_VC1FB_DSA0 (0 << 30) ++#define DSSR_VC1FB_DSA1 (1 << 30) ++#define DSSR_VC1FB_DSA2 (2 << 30) ++#define DSSR_VC1FB_INIT (3 << 30) ++#define DSSR_VC1FB_MASK (3 << 30) ++#define DSSR_VC0FB_DSA0 (0 << 28) ++#define DSSR_VC0FB_DSA1 (1 << 28) ++#define DSSR_VC0FB_DSA2 (2 << 28) ++#define DSSR_VC0FB_INIT (3 << 28) ++#define DSSR_VC0FB_MASK (3 << 28) ++#define DSSR_DFB(n) (1 << ((n)+15)) ++#define DSSR_TVR (1 << 15) ++#define DSSR_FRM (1 << 14) ++#define DSSR_VBK (1 << 11) ++#define DSSR_RINT (1 << 9) ++#define DSSR_HBK (1 << 8) ++#define DSSR_ADC(n) (1 << ((n)-1)) ++ ++#define DSRCR 0x0000c ++#define D2SRCR 0x3000c ++#define DSRCR_TVCL (1 << 15) ++#define DSRCR_FRCL (1 << 14) ++#define DSRCR_VBCL (1 << 11) ++#define DSRCR_RICL (1 << 9) ++#define DSRCR_HBCL (1 << 8) ++#define DSRCR_ADCL(n) (1 << ((n)-1)) ++#define DSRCR_MASK 0x0000cbff ++ ++#define DIER 0x00010 ++#define D2IER 0x30010 ++#define DIER_TVE (1 << 15) ++#define DIER_FRE (1 << 14) ++#define DIER_VBE (1 << 11) ++#define DIER_RIE (1 << 9) ++#define DIER_HBE (1 << 8) ++#define DIER_ADCE(n) (1 << ((n)-1)) ++ ++#define CPCR 0x00014 ++#define CPCR_CP4CE (1 << 19) ++#define CPCR_CP3CE (1 << 18) ++#define CPCR_CP2CE (1 << 17) ++#define CPCR_CP1CE (1 << 16) ++ ++#define DPPR 0x00018 ++#define DPPR_DPE(n) (1 << ((n)*4-1)) ++#define DPPR_DPS(n, p) (((p)-1) << DPPR_DPS_SHIFT(n)) ++#define DPPR_DPS_SHIFT(n) (((n)-1)*4) ++#define DPPR_BPP16 (DPPR_DPE(8) | DPPR_DPS(8, 1)) /* plane1 */ ++#define DPPR_BPP32_P1 (DPPR_DPE(7) | DPPR_DPS(7, 1)) ++#define DPPR_BPP32_P2 (DPPR_DPE(8) | DPPR_DPS(8, 2)) ++#define DPPR_BPP32 (DPPR_BPP32_P1 | DPPR_BPP32_P2) /* plane1 & 2 */ ++ ++#define DEFR 0x00020 ++#define D2EFR 0x30020 ++#define DEFR_CODE (0x7773 << 16) ++#define DEFR_EXSL (1 << 12) ++#define DEFR_EXVL (1 << 11) ++#define DEFR_EXUP (1 << 5) ++#define DEFR_VCUP (1 << 4) ++#define DEFR_DEFE (1 << 0) ++ ++#define DAPCR 0x00024 ++#define DAPCR_CODE (0x7773 << 16) ++#define DAPCR_AP2E (1 << 4) ++#define DAPCR_AP1E (1 << 0) ++ ++#define DCPCR 0x00028 ++#define DCPCR_CODE (0x7773 << 16) ++#define DCPCR_CA2B (1 << 13) ++#define DCPCR_CD2F (1 << 12) ++#define DCPCR_DC2E (1 << 8) ++#define DCPCR_CAB (1 << 5) ++#define DCPCR_CDF (1 << 4) ++#define DCPCR_DCE (1 << 0) ++ ++#define DEFR2 0x00034 ++#define D2EFR2 0x30034 ++#define DEFR2_CODE (0x7775 << 16) ++#define DEFR2_DEFE2G (1 << 0) ++ ++#define DEFR3 0x00038 ++#define D2EFR3 0x30038 ++#define DEFR3_CODE (0x7776 << 16) ++#define DEFR3_EVDA (1 << 14) ++#define DEFR3_EVDM_1 (1 << 12) ++#define DEFR3_EVDM_2 (2 << 12) ++#define DEFR3_EVDM_3 (3 << 12) ++#define DEFR3_VMSM2_EMA (1 << 6) ++#define DEFR3_VMSM1_ENA (1 << 4) ++#define DEFR3_DEFE3 (1 << 0) ++ ++#define DEFR4 0x0003c ++#define D2EFR4 0x3003c ++#define DEFR4_CODE (0x7777 << 16) ++#define DEFR4_LRUO (1 << 5) ++#define DEFR4_SPCE (1 << 4) ++ ++#define DVCSR 0x000d0 ++#define DVCSR_VCnFB2_DSA0(n) (0 << ((n)*2+16)) ++#define DVCSR_VCnFB2_DSA1(n) (1 << ((n)*2+16)) ++#define DVCSR_VCnFB2_DSA2(n) (2 << ((n)*2+16)) ++#define DVCSR_VCnFB2_INIT(n) (3 << ((n)*2+16)) ++#define DVCSR_VCnFB2_MASK(n) (3 << ((n)*2+16)) ++#define DVCSR_VCnFB_DSA0(n) (0 << ((n)*2)) ++#define DVCSR_VCnFB_DSA1(n) (1 << ((n)*2)) ++#define DVCSR_VCnFB_DSA2(n) (2 << ((n)*2)) ++#define DVCSR_VCnFB_INIT(n) (3 << ((n)*2)) ++#define DVCSR_VCnFB_MASK(n) (3 << ((n)*2)) ++ ++#define DEFR5 0x000e0 ++#define DEFR5_CODE (0x66 << 24) ++#define DEFR5_YCRGB2_DIS (0 << 14) ++#define DEFR5_YCRGB2_PRI1 (1 << 14) ++#define DEFR5_YCRGB2_PRI2 (2 << 14) ++#define DEFR5_YCRGB2_PRI3 (3 << 14) ++#define DEFR5_YCRGB2_MASK (3 << 14) ++#define DEFR5_YCRGB1_DIS (0 << 12) ++#define DEFR5_YCRGB1_PRI1 (1 << 12) ++#define DEFR5_YCRGB1_PRI2 (2 << 12) ++#define DEFR5_YCRGB1_PRI3 (3 << 12) ++#define DEFR5_YCRGB1_MASK (3 << 12) ++#define DEFR5_DEFE5 (1 << 0) ++ ++#define DDLTR 0x000e4 ++#define DDLTR_CODE (0x7766 << 16) ++#define DDLTR_DLAR2 (1 << 6) ++#define DDLTR_DLAY2 (1 << 5) ++#define DDLTR_DLAY1 (1 << 1) ++ ++#define DEFR6 0x000e8 ++#define DEFR6_CODE (0x7778 << 16) ++#define DEFR6_ODPM22_D2SMR (0 << 10) ++#define DEFR6_ODPM22_DISP (2 << 10) ++#define DEFR6_ODPM22_CDE (3 << 10) ++#define DEFR6_ODPM22_MASK (3 << 10) ++#define DEFR6_ODPM12_DSMR (0 << 8) ++#define DEFR6_ODPM12_DISP (2 << 8) ++#define DEFR6_ODPM12_CDE (3 << 8) ++#define DEFR6_ODPM12_MASK (3 << 8) ++#define DEFR6_TCNE2 (1 << 6) ++#define DEFR6_MLOS1 (1 << 2) ++#define DEFR6_DEFAULT (DEFR6_CODE | DEFR6_TCNE2) ++ ++/* ----------------------------------------------------------------------------- ++ * Display Timing Generation Registers ++ */ ++ ++#define HDSR 0x00040 ++#define HDER 0x00044 ++#define VDSR 0x00048 ++#define VDER 0x0004c ++#define HCR 0x00050 ++#define HSWR 0x00054 ++#define VCR 0x00058 ++#define VSPR 0x0005c ++#define EQWR 0x00060 ++#define SPWR 0x00064 ++#define CLAMPSR 0x00070 ++#define CLAMPWR 0x00074 ++#define DESR 0x00078 ++#define DEWR 0x0007c ++ ++/* ----------------------------------------------------------------------------- ++ * Display Attribute Registers ++ */ ++ ++#define CP1TR 0x00080 ++#define CP2TR 0x00084 ++#define CP3TR 0x00088 ++#define CP4TR 0x0008c ++ ++#define DOOR 0x00090 ++#define DOOR_RGB(r, g, b) (((r) << 18) | ((g) << 10) | ((b) << 2)) ++#define CDER 0x00094 ++#define CDER_RGB(r, g, b) (((r) << 18) | ((g) << 10) | ((b) << 2)) ++#define BPOR 0x00098 ++#define BPOR_RGB(r, g, b) (((r) << 18) | ((g) << 10) | ((b) << 2)) ++ ++#define RINTOFSR 0x0009c ++ ++#define DSHPR 0x000c8 ++#define DSHPR_CODE (0x7776 << 16) ++#define DSHPR_PRIH (0xa << 4) ++#define DSHPR_PRIL_BPP16 (0x8 << 0) ++#define DSHPR_PRIL_BPP32 (0x9 << 0) ++ ++/* ----------------------------------------------------------------------------- ++ * Display Plane Registers ++ */ ++ ++#define PLANE_OFF 0x00100 ++ ++#define PnMR 0x00100 /* plane 1 */ ++#define PnMR_VISL_VIN0 (0 << 26) /* use Video Input 0 */ ++#define PnMR_VISL_VIN1 (1 << 26) /* use Video Input 1 */ ++#define PnMR_VISL_VIN2 (2 << 26) /* use Video Input 2 */ ++#define PnMR_VISL_VIN3 (3 << 26) /* use Video Input 3 */ ++#define PnMR_YCDF_YUYV (1 << 20) /* YUYV format */ ++#define PnMR_TC_R (0 << 17) /* Tranparent color is PnTC1R */ ++#define PnMR_TC_CP (1 << 17) /* Tranparent color is color palette */ ++#define PnMR_WAE (1 << 16) /* Wrap around Enable */ ++#define PnMR_SPIM_TP (0 << 12) /* Transparent Color */ ++#define PnMR_SPIM_ALP (1 << 12) /* Alpha Blending */ ++#define PnMR_SPIM_EOR (2 << 12) /* EOR */ ++#define PnMR_SPIM_TP_OFF (1 << 14) /* No Transparent Color */ ++#define PnMR_CPSL_CP1 (0 << 8) /* Color Palette selected 1 */ ++#define PnMR_CPSL_CP2 (1 << 8) /* Color Palette selected 2 */ ++#define PnMR_CPSL_CP3 (2 << 8) /* Color Palette selected 3 */ ++#define PnMR_CPSL_CP4 (3 << 8) /* Color Palette selected 4 */ ++#define PnMR_DC (1 << 7) /* Display Area Change */ ++#define PnMR_BM_MD (0 << 4) /* Manual Display Change Mode */ ++#define PnMR_BM_AR (1 << 4) /* Auto Rendering Mode */ ++#define PnMR_BM_AD (2 << 4) /* Auto Display Change Mode */ ++#define PnMR_BM_VC (3 << 4) /* Video Capture Mode */ ++#define PnMR_DDDF_8BPP (0 << 0) /* 8bit */ ++#define PnMR_DDDF_16BPP (1 << 0) /* 16bit or 32bit */ ++#define PnMR_DDDF_ARGB (2 << 0) /* ARGB */ ++#define PnMR_DDDF_YC (3 << 0) /* YC */ ++#define PnMR_DDDF_MASK (3 << 0) ++ ++#define PnMWR 0x00104 ++ ++#define PnALPHAR 0x00108 ++#define PnALPHAR_ABIT_1 (0 << 12) ++#define PnALPHAR_ABIT_0 (1 << 12) ++#define PnALPHAR_ABIT_X (2 << 12) ++ ++#define PnDSXR 0x00110 ++#define PnDSYR 0x00114 ++#define PnDPXR 0x00118 ++#define PnDPYR 0x0011c ++ ++#define PnDSA0R 0x00120 ++#define PnDSA1R 0x00124 ++#define PnDSA2R 0x00128 ++#define PnDSA_MASK 0xfffffff0 ++ ++#define PnSPXR 0x00130 ++#define PnSPYR 0x00134 ++#define PnWASPR 0x00138 ++#define PnWAMWR 0x0013c ++ ++#define PnBTR 0x00140 ++ ++#define PnTC1R 0x00144 ++#define PnTC2R 0x00148 ++#define PnTC3R 0x0014c ++#define PnTC3R_CODE (0x66 << 24) ++ ++#define PnMLR 0x00150 ++ ++#define PnSWAPR 0x00180 ++#define PnSWAPR_DIGN (1 << 4) ++#define PnSWAPR_SPQW (1 << 3) ++#define PnSWAPR_SPLW (1 << 2) ++#define PnSWAPR_SPWD (1 << 1) ++#define PnSWAPR_SPBY (1 << 0) ++ ++#define PnDDCR 0x00184 ++#define PnDDCR_CODE (0x7775 << 16) ++#define PnDDCR_LRGB1 (1 << 11) ++#define PnDDCR_LRGB0 (1 << 10) ++ ++#define PnDDCR2 0x00188 ++#define PnDDCR2_CODE (0x7776 << 16) ++#define PnDDCR2_NV21 (1 << 5) ++#define PnDDCR2_Y420 (1 << 4) ++#define PnDDCR2_DIVU (1 << 1) ++#define PnDDCR2_DIVY (1 << 0) ++ ++#define PnDDCR4 0x00190 ++#define PnDDCR4_CODE (0x7766 << 16) ++#define PnDDCR4_SDFS_RGB (0 << 4) ++#define PnDDCR4_SDFS_YC (5 << 4) ++#define PnDDCR4_SDFS_MASK (7 << 4) ++#define PnDDCR4_EDF_NONE (0 << 0) ++#define PnDDCR4_EDF_ARGB8888 (1 << 0) ++#define PnDDCR4_EDF_RGB888 (2 << 0) ++#define PnDDCR4_EDF_RGB666 (3 << 0) ++#define PnDDCR4_EDF_MASK (7 << 0) ++ ++#define APnMR 0x0a100 ++#define APnMR_WAE (1 << 16) /* Wrap around Enable */ ++#define APnMR_DC (1 << 7) /* Display Area Change */ ++#define APnMR_BM_MD (0 << 4) /* Manual Display Change Mode */ ++#define APnMR_BM_AD (2 << 4) /* Auto Display Change Mode */ ++ ++#define APnMWR 0x0a104 ++#define APnDSA0R 0x0a120 ++#define APnDSA1R 0x0a124 ++#define APnDSA2R 0x0a128 ++#define APnMLR 0x0a150 ++ ++/* ----------------------------------------------------------------------------- ++ * Display Capture Registers ++ */ ++ ++#define DCMWR 0x0c104 ++#define DC2MWR 0x0c204 ++#define DCSAR 0x0c120 ++#define DC2SAR 0x0c220 ++#define DCMLR 0x0c150 ++#define DC2MLR 0x0c250 ++ ++/* ----------------------------------------------------------------------------- ++ * Color Palette Registers ++ */ ++ ++#define CP1_000R 0x01000 ++#define CP1_255R 0x013fc ++#define CP2_000R 0x02000 ++#define CP2_255R 0x023fc ++#define CP3_000R 0x03000 ++#define CP3_255R 0x033fc ++#define CP4_000R 0x04000 ++#define CP4_255R 0x043fc ++ ++/* ----------------------------------------------------------------------------- ++ * External Synchronization Control Registers ++ */ ++ ++#define ESCR 0x10000 ++#define ESCR2 0x31000 ++#define ESCR_DCLKOINV (1 << 25) ++#define ESCR_DCLKSEL_DCLKIN (0 << 20) ++#define ESCR_DCLKSEL_CLKS (1 << 20) ++#define ESCR_DCLKSEL_MASK (1 << 20) ++#define ESCR_DCLKDIS (1 << 16) ++#define ESCR_SYNCSEL_OFF (0 << 8) ++#define ESCR_SYNCSEL_EXVSYNC (2 << 8) ++#define ESCR_SYNCSEL_EXHSYNC (3 << 8) ++#define ESCR_FRQSEL_MASK (0x3f << 0) ++ ++#define OTAR 0x10004 ++#define OTAR2 0x31004 ++ ++/* ----------------------------------------------------------------------------- ++ * Dual Display Output Control Registers ++ */ ++ ++#define DORCR 0x11000 ++#define DORCR_PG2T (1 << 30) ++#define DORCR_DK2S (1 << 28) ++#define DORCR_PG2D_DS1 (0 << 24) ++#define DORCR_PG2D_DS2 (1 << 24) ++#define DORCR_PG2D_FIX0 (2 << 24) ++#define DORCR_PG2D_DOOR (3 << 24) ++#define DORCR_PG2D_MASK (3 << 24) ++#define DORCR_DR1D (1 << 21) ++#define DORCR_PG1D_DS1 (0 << 16) ++#define DORCR_PG1D_DS2 (1 << 16) ++#define DORCR_PG1D_FIX0 (2 << 16) ++#define DORCR_PG1D_DOOR (3 << 16) ++#define DORCR_PG1D_MASK (3 << 16) ++#define DORCR_RGPV (1 << 4) ++#define DORCR_DPRS (1 << 0) ++ ++#define DPTSR 0x11004 ++#define DPTSR_PnDK(n) (1 << ((n) + 16)) ++#define DPTSR_PnTS(n) (1 << (n)) ++ ++#define DAPTSR 0x11008 ++#define DAPTSR_APnDK(n) (1 << ((n) + 16)) ++#define DAPTSR_APnTS(n) (1 << (n)) ++ ++#define DS1PR 0x11020 ++#define DS2PR 0x11024 ++ ++/* ----------------------------------------------------------------------------- ++ * YC-RGB Conversion Coefficient Registers ++ */ ++ ++#define YNCR 0x11080 ++#define YNOR 0x11084 ++#define CRNOR 0x11088 ++#define CBNOR 0x1108c ++#define RCRCR 0x11090 ++#define GCRCR 0x11094 ++#define GCBCR 0x11098 ++#define BCBCR 0x1109c ++ ++#endif /* __RCAR_DU_REGS_H__ */ +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vga.c b/drivers/gpu/drm/rcar-du/rcar_du_vga.c +new file mode 100644 +index 000000000000..327289ec380d +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_vga.c +@@ -0,0 +1,149 @@ ++/* ++ * rcar_du_vga.c -- R-Car Display Unit VGA DAC and Connector ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <drm/drmP.h> ++#include <drm/drm_crtc.h> ++#include <drm/drm_crtc_helper.h> ++ ++#include "rcar_du_drv.h" ++#include "rcar_du_kms.h" ++#include "rcar_du_vga.h" ++ ++/* ----------------------------------------------------------------------------- ++ * Connector ++ */ ++ ++static int rcar_du_vga_connector_get_modes(struct drm_connector *connector) ++{ ++ return 0; ++} ++ ++static int rcar_du_vga_connector_mode_valid(struct drm_connector *connector, ++ struct drm_display_mode *mode) ++{ ++ return MODE_OK; ++} ++ ++static const struct drm_connector_helper_funcs connector_helper_funcs = { ++ .get_modes = rcar_du_vga_connector_get_modes, ++ .mode_valid = rcar_du_vga_connector_mode_valid, ++ .best_encoder = rcar_du_connector_best_encoder, ++}; ++ ++static void rcar_du_vga_connector_destroy(struct drm_connector *connector) ++{ ++ drm_sysfs_connector_remove(connector); ++ drm_connector_cleanup(connector); ++} ++ ++static enum drm_connector_status ++rcar_du_vga_connector_detect(struct drm_connector *connector, bool force) ++{ ++ return connector_status_unknown; ++} ++ ++static const struct drm_connector_funcs connector_funcs = { ++ .dpms = drm_helper_connector_dpms, ++ .detect = rcar_du_vga_connector_detect, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .destroy = rcar_du_vga_connector_destroy, ++}; ++ ++static int rcar_du_vga_connector_init(struct rcar_du_device *rcdu, ++ struct rcar_du_encoder *renc) ++{ ++ struct rcar_du_connector *rcon; ++ struct drm_connector *connector; ++ int ret; ++ ++ rcon = devm_kzalloc(rcdu->dev, sizeof(*rcon), GFP_KERNEL); ++ if (rcon == NULL) ++ return -ENOMEM; ++ ++ connector = &rcon->connector; ++ connector->display_info.width_mm = 0; ++ connector->display_info.height_mm = 0; ++ ++ ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs, ++ DRM_MODE_CONNECTOR_VGA); ++ if (ret < 0) ++ return ret; ++ ++ drm_connector_helper_add(connector, &connector_helper_funcs); ++ ret = drm_sysfs_connector_add(connector); ++ if (ret < 0) ++ return ret; ++ ++ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); ++ drm_object_property_set_value(&connector->base, ++ rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF); ++ ++ ret = drm_mode_connector_attach_encoder(connector, &renc->encoder); ++ if (ret < 0) ++ return ret; ++ ++ connector->encoder = &renc->encoder; ++ rcon->encoder = renc; ++ ++ return 0; ++} ++ ++/* ----------------------------------------------------------------------------- ++ * Encoder ++ */ ++ ++static void rcar_du_vga_encoder_dpms(struct drm_encoder *encoder, int mode) ++{ ++} ++ ++static bool rcar_du_vga_encoder_mode_fixup(struct drm_encoder *encoder, ++ const struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ return true; ++} ++ ++static const struct drm_encoder_helper_funcs encoder_helper_funcs = { ++ .dpms = rcar_du_vga_encoder_dpms, ++ .mode_fixup = rcar_du_vga_encoder_mode_fixup, ++ .prepare = rcar_du_encoder_mode_prepare, ++ .commit = rcar_du_encoder_mode_commit, ++ .mode_set = rcar_du_encoder_mode_set, ++}; ++ ++static const struct drm_encoder_funcs encoder_funcs = { ++ .destroy = drm_encoder_cleanup, ++}; ++ ++int rcar_du_vga_init(struct rcar_du_device *rcdu, ++ const struct rcar_du_encoder_vga_data *data, ++ unsigned int output) ++{ ++ struct rcar_du_encoder *renc; ++ int ret; ++ ++ renc = devm_kzalloc(rcdu->dev, sizeof(*renc), GFP_KERNEL); ++ if (renc == NULL) ++ return -ENOMEM; ++ ++ renc->output = output; ++ ++ ret = drm_encoder_init(rcdu->ddev, &renc->encoder, &encoder_funcs, ++ DRM_MODE_ENCODER_DAC); ++ if (ret < 0) ++ return ret; ++ ++ drm_encoder_helper_add(&renc->encoder, &encoder_helper_funcs); ++ ++ return rcar_du_vga_connector_init(rcdu, renc); ++} +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vga.h b/drivers/gpu/drm/rcar-du/rcar_du_vga.h +new file mode 100644 +index 000000000000..66b4d2d7190d +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_vga.h +@@ -0,0 +1,24 @@ ++/* ++ * rcar_du_vga.h -- R-Car Display Unit VGA DAC and Connector ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#ifndef __RCAR_DU_VGA_H__ ++#define __RCAR_DU_VGA_H__ ++ ++struct rcar_du_device; ++struct rcar_du_encoder_vga_data; ++ ++int rcar_du_vga_init(struct rcar_du_device *rcdu, ++ const struct rcar_du_encoder_vga_data *data, ++ unsigned int output); ++ ++#endif /* __RCAR_DU_VGA_H__ */ +diff --git a/include/linux/platform_data/rcar-du.h b/include/linux/platform_data/rcar-du.h +new file mode 100644 +index 000000000000..80587fdbba3e +--- /dev/null ++++ b/include/linux/platform_data/rcar-du.h +@@ -0,0 +1,54 @@ ++/* ++ * rcar_du.h -- R-Car Display Unit DRM driver ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#ifndef __RCAR_DU_H__ ++#define __RCAR_DU_H__ ++ ++#include <drm/drm_mode.h> ++ ++enum rcar_du_encoder_type { ++ RCAR_DU_ENCODER_UNUSED = 0, ++ RCAR_DU_ENCODER_VGA, ++ RCAR_DU_ENCODER_LVDS, ++}; ++ ++struct rcar_du_panel_data { ++ unsigned int width_mm; /* Panel width in mm */ ++ unsigned int height_mm; /* Panel height in mm */ ++ struct drm_mode_modeinfo mode; ++}; ++ ++struct rcar_du_encoder_lvds_data { ++ struct rcar_du_panel_data panel; ++}; ++ ++struct rcar_du_encoder_vga_data { ++ /* TODO: Add DDC information for EDID retrieval */ ++}; ++ ++struct rcar_du_encoder_data { ++ enum rcar_du_encoder_type encoder; ++ unsigned int output; ++ ++ union { ++ struct rcar_du_encoder_lvds_data lvds; ++ struct rcar_du_encoder_vga_data vga; ++ } u; ++}; ++ ++struct rcar_du_platform_data { ++ struct rcar_du_encoder_data *encoders; ++ unsigned int num_encoders; ++}; ++ ++#endif /* __RCAR_DU_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0010-drm-rcar-du-Don-t-ignore-rcar_du_crtc_create-return-.patch b/patches.renesas/0010-drm-rcar-du-Don-t-ignore-rcar_du_crtc_create-return-.patch new file mode 100644 index 00000000000000..7a94b5ff4d3220 --- /dev/null +++ b/patches.renesas/0010-drm-rcar-du-Don-t-ignore-rcar_du_crtc_create-return-.patch @@ -0,0 +1,36 @@ +From e9adc96a1b1b04e5e7996707d14306313f898f22 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 4 Jul 2013 20:05:50 +0200 +Subject: drm/rcar-du: Don't ignore rcar_du_crtc_create() return value + +Handle error cases correctly. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +(cherry picked from commit 3463ff67bc8d049098559adb850299c26b52350d) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +index 9c63f39658de..06cacf6532c0 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +@@ -191,8 +191,11 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + if (ret < 0) + return ret; + +- for (i = 0; i < ARRAY_SIZE(rcdu->crtcs); ++i) +- rcar_du_crtc_create(rcdu, i); ++ for (i = 0; i < ARRAY_SIZE(rcdu->crtcs); ++i) { ++ ret = rcar_du_crtc_create(rcdu, i); ++ if (ret < 0) ++ return ret; ++ } + + rcdu->used_crtcs = 0; + rcdu->num_crtcs = i; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0011-drm-rcar-du-Fix-buffer-pitch-alignment.patch b/patches.renesas/0011-drm-rcar-du-Fix-buffer-pitch-alignment.patch new file mode 100644 index 00000000000000..ca43c78565e574 --- /dev/null +++ b/patches.renesas/0011-drm-rcar-du-Fix-buffer-pitch-alignment.patch @@ -0,0 +1,89 @@ +From 0bfd4e77e36f620192682f5211edec62dcf7d7c9 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 4 Jul 2013 20:05:51 +0200 +Subject: drm/rcar-du: Fix buffer pitch alignment + +The DU requires a 16 pixels pitch alignement. Make sure dumb buffers are +allocated with the correct pitch, and validate the pitch when creating +frame buffers. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Dave Airlie <airlied@redhat.com> +(cherry picked from commit 59e32642d2e8fb170a1e777906dcb13359ea230f) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 2 +- + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 19 ++++++++++++++++++- + drivers/gpu/drm/rcar-du/rcar_du_kms.h | 3 +++ + 3 files changed, 22 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +index 003b34ee38e3..ff82877de876 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -251,7 +251,7 @@ static struct drm_driver rcar_du_driver = { + .prime_fd_to_handle = drm_gem_prime_fd_to_handle, + .gem_prime_import = drm_gem_cma_dmabuf_import, + .gem_prime_export = drm_gem_cma_dmabuf_export, +- .dumb_create = drm_gem_cma_dumb_create, ++ .dumb_create = rcar_du_dumb_create, + .dumb_map_offset = drm_gem_cma_dumb_map_offset, + .dumb_destroy = drm_gem_cma_dumb_destroy, + .fops = &rcar_du_fops, +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +index 06cacf6532c0..d30c2e29bee2 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +@@ -138,11 +138,25 @@ void rcar_du_encoder_mode_commit(struct drm_encoder *encoder) + * Frame buffer + */ + ++int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev, ++ struct drm_mode_create_dumb *args) ++{ ++ unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); ++ unsigned int align; ++ ++ /* The pitch must be aligned to a 16 pixels boundary. */ ++ align = 16 * args->bpp / 8; ++ args->pitch = roundup(max(args->pitch, min_pitch), align); ++ ++ return drm_gem_cma_dumb_create(file, dev, args); ++} ++ + static struct drm_framebuffer * + rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv, + struct drm_mode_fb_cmd2 *mode_cmd) + { + const struct rcar_du_format_info *format; ++ unsigned int align; + + format = rcar_du_format_info(mode_cmd->pixel_format); + if (format == NULL) { +@@ -151,7 +165,10 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv, + return ERR_PTR(-EINVAL); + } + +- if (mode_cmd->pitches[0] & 15 || mode_cmd->pitches[0] >= 8192) { ++ align = 16 * format->bpp / 8; ++ ++ if (mode_cmd->pitches[0] & (align - 1) || ++ mode_cmd->pitches[0] >= 8192) { + dev_dbg(dev->dev, "invalid pitch value %u\n", + mode_cmd->pitches[0]); + return ERR_PTR(-EINVAL); +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.h b/drivers/gpu/drm/rcar-du/rcar_du_kms.h +index e4d8db069a06..dba472263486 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.h +@@ -56,4 +56,7 @@ void rcar_du_encoder_mode_commit(struct drm_encoder *encoder); + + int rcar_du_modeset_init(struct rcar_du_device *rcdu); + ++int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev, ++ struct drm_mode_create_dumb *args); ++ + #endif /* __RCAR_DU_KMS_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0012-drm-rcar-du-Add-missing-alpha-plane-register-definit.patch b/patches.renesas/0012-drm-rcar-du-Add-missing-alpha-plane-register-definit.patch new file mode 100644 index 00000000000000..af5b9767a89de0 --- /dev/null +++ b/patches.renesas/0012-drm-rcar-du-Add-missing-alpha-plane-register-definit.patch @@ -0,0 +1,47 @@ +From d76d7566779648bca1ba9013c7ac13398b530ff6 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Mon, 3 Jun 2013 10:53:48 +0200 +Subject: drm/rcar-du: Add missing alpha plane register definitions + +Several alpha plane register definitions are missing, add them. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 6811b1bea98462e228fef2172c36f1543ac156fe) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_regs.h | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_regs.h b/drivers/gpu/drm/rcar-du/rcar_du_regs.h +index 69f21f19b51c..3aba27ffc065 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_regs.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_regs.h +@@ -349,10 +349,25 @@ + #define APnMR_BM_AD (2 << 4) /* Auto Display Change Mode */ + + #define APnMWR 0x0a104 ++ ++#define APnDSXR 0x0a110 ++#define APnDSYR 0x0a114 ++#define APnDPXR 0x0a118 ++#define APnDPYR 0x0a11c ++ + #define APnDSA0R 0x0a120 + #define APnDSA1R 0x0a124 + #define APnDSA2R 0x0a128 ++ ++#define APnSPXR 0x0a130 ++#define APnSPYR 0x0a134 ++#define APnWASPR 0x0a138 ++#define APnWAMWR 0x0a13c ++ ++#define APnBTR 0x0a140 ++ + #define APnMLR 0x0a150 ++#define APnSWAPR 0x0a180 + + /* ----------------------------------------------------------------------------- + * Display Capture Registers +-- +1.8.5.rc3 + diff --git a/patches.renesas/0013-drm-rcar-du-Use-devm_ioremap_resource.patch b/patches.renesas/0013-drm-rcar-du-Use-devm_ioremap_resource.patch new file mode 100644 index 00000000000000..07b4113f11ec31 --- /dev/null +++ b/patches.renesas/0013-drm-rcar-du-Use-devm_ioremap_resource.patch @@ -0,0 +1,58 @@ +From 5a59fb17be2ec494812e1e477d609c98e1b10e44 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Mon, 17 Jun 2013 02:29:07 +0200 +Subject: drm/rcar-du: Use devm_ioremap_resource() + +Replace the devm_request_mem_region() and devm_ioremap_nocache() calls +with devm_ioremap_resource(). + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit d5b6dcc45950bc727f6a02d0ee68c99d0b6052ea) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 22 +++------------------- + 1 file changed, 3 insertions(+), 19 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +index ff82877de876..910c1e179036 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -107,7 +107,6 @@ static int rcar_du_load(struct drm_device *dev, unsigned long flags) + struct platform_device *pdev = dev->platformdev; + struct rcar_du_platform_data *pdata = pdev->dev.platform_data; + struct rcar_du_device *rcdu; +- struct resource *ioarea; + struct resource *mem; + int ret; + +@@ -129,24 +128,9 @@ static int rcar_du_load(struct drm_device *dev, unsigned long flags) + + /* I/O resources and clocks */ + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (mem == NULL) { +- dev_err(&pdev->dev, "failed to get memory resource\n"); +- return -EINVAL; +- } +- +- ioarea = devm_request_mem_region(&pdev->dev, mem->start, +- resource_size(mem), pdev->name); +- if (ioarea == NULL) { +- dev_err(&pdev->dev, "failed to request memory region\n"); +- return -EBUSY; +- } +- +- rcdu->mmio = devm_ioremap_nocache(&pdev->dev, ioarea->start, +- resource_size(ioarea)); +- if (rcdu->mmio == NULL) { +- dev_err(&pdev->dev, "failed to remap memory resource\n"); +- return -ENOMEM; +- } ++ rcdu->mmio = devm_ioremap_resource(&pdev->dev, mem); ++ if (IS_ERR(rcdu->mmio)) ++ return PTR_ERR(rcdu->mmio); + + rcdu->clock = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(rcdu->clock)) { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0014-drm-rcar-du-Add-platform-module-device-table.patch b/patches.renesas/0014-drm-rcar-du-Add-platform-module-device-table.patch new file mode 100644 index 00000000000000..20b60e901fa2c8 --- /dev/null +++ b/patches.renesas/0014-drm-rcar-du-Add-platform-module-device-table.patch @@ -0,0 +1,96 @@ +From f6b84c4397f9085d223d70b06cdbe8f8d2737b78 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Fri, 14 Jun 2013 13:38:33 +0200 +Subject: drm/rcar-du: Add platform module device table + +The platform device id driver data field points to a device information +structure that only contains a (currently empty) features field for now. +Support for additional model-dependent features will be added later. + +Only the R8A7779 variant is currently supported. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 481d342e3500e71a88cac79a6fab7b62f7203c7c) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 13 +++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_drv.h | 15 +++++++++++++++ + 2 files changed, 28 insertions(+) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +index 910c1e179036..60836b8d6053 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -123,6 +123,7 @@ static int rcar_du_load(struct drm_device *dev, unsigned long flags) + + rcdu->dev = &pdev->dev; + rcdu->pdata = pdata; ++ rcdu->info = (struct rcar_du_device_info *)pdev->id_entry->driver_data; + rcdu->ddev = dev; + dev->dev_private = rcdu; + +@@ -292,6 +293,17 @@ static int rcar_du_remove(struct platform_device *pdev) + return 0; + } + ++static const struct rcar_du_device_info rcar_du_r8a7779_info = { ++ .features = 0, ++}; ++ ++static const struct platform_device_id rcar_du_id_table[] = { ++ { "rcar-du-r8a7779", (kernel_ulong_t)&rcar_du_r8a7779_info }, ++ { } ++}; ++ ++MODULE_DEVICE_TABLE(platform, rcar_du_id_table); ++ + static struct platform_driver rcar_du_platform_driver = { + .probe = rcar_du_probe, + .remove = rcar_du_remove, +@@ -300,6 +312,7 @@ static struct platform_driver rcar_du_platform_driver = { + .name = "rcar-du", + .pm = &rcar_du_pm_ops, + }, ++ .id_table = rcar_du_id_table, + }; + + module_platform_driver(rcar_du_platform_driver); +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +index 193cc59d495c..06dbf4ff139c 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +@@ -25,9 +25,18 @@ struct clk; + struct device; + struct drm_device; + ++/* ++ * struct rcar_du_device_info - DU model-specific information ++ * @features: device features (RCAR_DU_FEATURE_*) ++ */ ++struct rcar_du_device_info { ++ unsigned int features; ++}; ++ + struct rcar_du_device { + struct device *dev; + const struct rcar_du_platform_data *pdata; ++ const struct rcar_du_device_info *info; + + void __iomem *mmio; + struct clk *clock; +@@ -50,6 +59,12 @@ struct rcar_du_device { + } planes; + }; + ++static inline bool rcar_du_has(struct rcar_du_device *rcdu, ++ unsigned int feature) ++{ ++ return rcdu->info->features & feature; ++} ++ + int rcar_du_get(struct rcar_du_device *rcdu); + void rcar_du_put(struct rcar_du_device *rcdu); + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0015-drm-rcar-du-Support-per-CRTC-clock-and-IRQ.patch b/patches.renesas/0015-drm-rcar-du-Support-per-CRTC-clock-and-IRQ.patch new file mode 100644 index 00000000000000..5baa6295507554 --- /dev/null +++ b/patches.renesas/0015-drm-rcar-du-Support-per-CRTC-clock-and-IRQ.patch @@ -0,0 +1,415 @@ +From a803274d612a7b0e0abd78e6016954b3e582a8f6 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Fri, 14 Jun 2013 14:15:01 +0200 +Subject: drm/rcar-du: Support per-CRTC clock and IRQ + +Some of the DU revisions use one clock and IRQ per CRTC instead of one +clock and IRQ per device. Retrieve the correct clock and register the +correct IRQ for each CRTC. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit f66ee304ae8990bd31fa639b775a840d6757d746) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 120 +++++++++++++++++++++++++-------- + drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 2 +- + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 52 +++----------- + drivers/gpu/drm/rcar-du/rcar_du_drv.h | 3 +- + 4 files changed, 103 insertions(+), 74 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +index 24183fb93592..aefc8a0cbcbc 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +@@ -69,6 +69,30 @@ static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg, + rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set); + } + ++static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc) ++{ ++ struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ int ret; ++ ++ ret = clk_prepare_enable(rcrtc->clock); ++ if (ret < 0) ++ return ret; ++ ++ ret = rcar_du_get(rcdu); ++ if (ret < 0) ++ clk_disable_unprepare(rcrtc->clock); ++ ++ return ret; ++} ++ ++static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc) ++{ ++ struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ ++ rcar_du_put(rcdu); ++ clk_disable_unprepare(rcrtc->clock); ++} ++ + static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) + { + struct drm_crtc *crtc = &rcrtc->crtc; +@@ -79,7 +103,7 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) + u32 div; + + /* Dot clock */ +- clk = clk_get_rate(rcdu->clock); ++ clk = clk_get_rate(rcrtc->clock); + div = DIV_ROUND_CLOSEST(clk, mode->clock * 1000); + div = clamp(div, 1U, 64U) - 1; + +@@ -313,20 +337,16 @@ static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc) + + void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc) + { +- struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; +- + rcar_du_crtc_stop(rcrtc); +- rcar_du_put(rcdu); ++ rcar_du_crtc_put(rcrtc); + } + + void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc) + { +- struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; +- + if (rcrtc->dpms != DRM_MODE_DPMS_ON) + return; + +- rcar_du_get(rcdu); ++ rcar_du_crtc_get(rcrtc); + rcar_du_crtc_start(rcrtc); + } + +@@ -340,18 +360,17 @@ static void rcar_du_crtc_update_base(struct rcar_du_crtc *rcrtc) + + static void rcar_du_crtc_dpms(struct drm_crtc *crtc, int mode) + { +- struct rcar_du_device *rcdu = crtc->dev->dev_private; + struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); + + if (rcrtc->dpms == mode) + return; + + if (mode == DRM_MODE_DPMS_ON) { +- rcar_du_get(rcdu); ++ rcar_du_crtc_get(rcrtc); + rcar_du_crtc_start(rcrtc); + } else { + rcar_du_crtc_stop(rcrtc); +- rcar_du_put(rcdu); ++ rcar_du_crtc_put(rcrtc); + } + + rcrtc->dpms = mode; +@@ -367,13 +386,12 @@ static bool rcar_du_crtc_mode_fixup(struct drm_crtc *crtc, + + static void rcar_du_crtc_mode_prepare(struct drm_crtc *crtc) + { +- struct rcar_du_device *rcdu = crtc->dev->dev_private; + struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); + + /* We need to access the hardware during mode set, acquire a reference +- * to the DU. ++ * to the CRTC. + */ +- rcar_du_get(rcdu); ++ rcar_du_crtc_get(rcrtc); + + /* Stop the CRTC and release the plane. Force the DPMS mode to off as a + * result. +@@ -423,10 +441,10 @@ static int rcar_du_crtc_mode_set(struct drm_crtc *crtc, + + error: + /* There's no rollback/abort operation to clean up in case of error. We +- * thus need to release the reference to the DU acquired in prepare() ++ * thus need to release the reference to the CRTC acquired in prepare() + * here. + */ +- rcar_du_put(rcdu); ++ rcar_du_crtc_put(rcrtc); + return ret; + } + +@@ -514,6 +532,24 @@ static void rcar_du_crtc_finish_page_flip(struct rcar_du_crtc *rcrtc) + drm_vblank_put(dev, rcrtc->index); + } + ++static irqreturn_t rcar_du_crtc_irq(int irq, void *arg) ++{ ++ struct rcar_du_crtc *rcrtc = arg; ++ irqreturn_t ret = IRQ_NONE; ++ u32 status; ++ ++ status = rcar_du_crtc_read(rcrtc, DSSR); ++ rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK); ++ ++ if (status & DSSR_VBK) { ++ drm_handle_vblank(rcrtc->crtc.dev, rcrtc->index); ++ rcar_du_crtc_finish_page_flip(rcrtc); ++ ret = IRQ_HANDLED; ++ } ++ ++ return ret; ++} ++ + static int rcar_du_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event) +@@ -551,10 +587,29 @@ static const struct drm_crtc_funcs crtc_funcs = { + + int rcar_du_crtc_create(struct rcar_du_device *rcdu, unsigned int index) + { ++ struct platform_device *pdev = to_platform_device(rcdu->dev); + struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index]; + struct drm_crtc *crtc = &rcrtc->crtc; ++ unsigned int irqflags; ++ char clk_name[5]; ++ char *name; ++ int irq; + int ret; + ++ /* Get the CRTC clock. */ ++ if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) { ++ sprintf(clk_name, "du.%u", index); ++ name = clk_name; ++ } else { ++ name = NULL; ++ } ++ ++ rcrtc->clock = devm_clk_get(rcdu->dev, name); ++ if (IS_ERR(rcrtc->clock)) { ++ dev_err(rcdu->dev, "no clock for CRTC %u\n", index); ++ return PTR_ERR(rcrtc->clock); ++ } ++ + rcrtc->mmio_offset = index ? DISP2_REG_OFFSET : 0; + rcrtc->index = index; + rcrtc->dpms = DRM_MODE_DPMS_OFF; +@@ -568,6 +623,28 @@ int rcar_du_crtc_create(struct rcar_du_device *rcdu, unsigned int index) + + drm_crtc_helper_add(crtc, &crtc_helper_funcs); + ++ /* Register the interrupt handler. */ ++ if (rcar_du_has(rcdu, RCAR_DU_FEATURE_CRTC_IRQ_CLOCK)) { ++ irq = platform_get_irq(pdev, index); ++ irqflags = 0; ++ } else { ++ irq = platform_get_irq(pdev, 0); ++ irqflags = IRQF_SHARED; ++ } ++ ++ if (irq < 0) { ++ dev_err(rcdu->dev, "no IRQ for CRTC %u\n", index); ++ return ret; ++ } ++ ++ ret = devm_request_irq(rcdu->dev, irq, rcar_du_crtc_irq, irqflags, ++ dev_name(rcdu->dev), rcrtc); ++ if (ret < 0) { ++ dev_err(rcdu->dev, ++ "failed to register IRQ for CRTC %u\n", index); ++ return ret; ++ } ++ + return 0; + } + +@@ -580,16 +657,3 @@ void rcar_du_crtc_enable_vblank(struct rcar_du_crtc *rcrtc, bool enable) + rcar_du_crtc_clr(rcrtc, DIER, DIER_VBE); + } + } +- +-void rcar_du_crtc_irq(struct rcar_du_crtc *rcrtc) +-{ +- u32 status; +- +- status = rcar_du_crtc_read(rcrtc, DSSR); +- rcar_du_crtc_write(rcrtc, DSRCR, status & DSRCR_MASK); +- +- if (status & DSSR_VBK) { +- drm_handle_vblank(rcrtc->crtc.dev, rcrtc->index); +- rcar_du_crtc_finish_page_flip(rcrtc); +- } +-} +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +index 2a0365bcbd14..5b69e98a3b92 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +@@ -25,6 +25,7 @@ struct rcar_du_plane; + struct rcar_du_crtc { + struct drm_crtc crtc; + ++ struct clk *clock; + unsigned int mmio_offset; + unsigned int index; + bool started; +@@ -38,7 +39,6 @@ struct rcar_du_crtc { + + int rcar_du_crtc_create(struct rcar_du_device *rcdu, unsigned int index); + void rcar_du_crtc_enable_vblank(struct rcar_du_crtc *rcrtc, bool enable); +-void rcar_du_crtc_irq(struct rcar_du_crtc *rcrtc); + void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc, + struct drm_file *file); + void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc); +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +index 60836b8d6053..9b89dbf3fb32 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -35,8 +35,8 @@ + /* + * rcar_du_get - Acquire a reference to the DU + * +- * Acquiring a reference enables the device clock and setup core registers. A +- * reference must be held before accessing any hardware registers. ++ * Acquiring the first reference setups core registers. A reference must be ++ * held before accessing any hardware registers. + * + * This function must be called with the DRM mode_config lock held. + * +@@ -44,16 +44,9 @@ + */ + int rcar_du_get(struct rcar_du_device *rcdu) + { +- int ret; +- + if (rcdu->use_count) + goto done; + +- /* Enable clocks before accessing the hardware. */ +- ret = clk_prepare_enable(rcdu->clock); +- if (ret < 0) +- return ret; +- + /* Enable extended features */ + rcar_du_write(rcdu, DEFR, DEFR_CODE | DEFR_DEFE); + rcar_du_write(rcdu, DEFR2, DEFR2_CODE | DEFR2_DEFE2G); +@@ -74,16 +67,11 @@ done: + /* + * rcar_du_put - Release a reference to the DU + * +- * Releasing the last reference disables the device clock. +- * + * This function must be called with the DRM mode_config lock held. + */ + void rcar_du_put(struct rcar_du_device *rcdu) + { +- if (--rcdu->use_count) +- return; +- +- clk_disable_unprepare(rcdu->clock); ++ --rcdu->use_count; + } + + /* ----------------------------------------------------------------------------- +@@ -95,8 +83,8 @@ static int rcar_du_unload(struct drm_device *dev) + drm_kms_helper_poll_fini(dev); + drm_mode_config_cleanup(dev); + drm_vblank_cleanup(dev); +- drm_irq_uninstall(dev); + ++ dev->irq_enabled = 0; + dev->dev_private = NULL; + + return 0; +@@ -127,18 +115,12 @@ static int rcar_du_load(struct drm_device *dev, unsigned long flags) + rcdu->ddev = dev; + dev->dev_private = rcdu; + +- /* I/O resources and clocks */ ++ /* I/O resources */ + mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + rcdu->mmio = devm_ioremap_resource(&pdev->dev, mem); + if (IS_ERR(rcdu->mmio)) + return PTR_ERR(rcdu->mmio); + +- rcdu->clock = devm_clk_get(&pdev->dev, NULL); +- if (IS_ERR(rcdu->clock)) { +- dev_err(&pdev->dev, "failed to get clock\n"); +- return -ENOENT; +- } +- + /* DRM/KMS objects */ + ret = rcar_du_modeset_init(rcdu); + if (ret < 0) { +@@ -146,18 +128,14 @@ static int rcar_du_load(struct drm_device *dev, unsigned long flags) + goto done; + } + +- /* IRQ and vblank handling */ ++ /* vblank handling */ + ret = drm_vblank_init(dev, (1 << rcdu->num_crtcs) - 1); + if (ret < 0) { + dev_err(&pdev->dev, "failed to initialize vblank\n"); + goto done; + } + +- ret = drm_irq_install(dev); +- if (ret < 0) { +- dev_err(&pdev->dev, "failed to install IRQ handler\n"); +- goto done; +- } ++ dev->irq_enabled = 1; + + platform_set_drvdata(pdev, rcdu); + +@@ -177,18 +155,6 @@ static void rcar_du_preclose(struct drm_device *dev, struct drm_file *file) + rcar_du_crtc_cancel_page_flip(&rcdu->crtcs[i], file); + } + +-static irqreturn_t rcar_du_irq(int irq, void *arg) +-{ +- struct drm_device *dev = arg; +- struct rcar_du_device *rcdu = dev->dev_private; +- unsigned int i; +- +- for (i = 0; i < ARRAY_SIZE(rcdu->crtcs); ++i) +- rcar_du_crtc_irq(&rcdu->crtcs[i]); +- +- return IRQ_HANDLED; +-} +- + static int rcar_du_enable_vblank(struct drm_device *dev, int crtc) + { + struct rcar_du_device *rcdu = dev->dev_private; +@@ -221,12 +187,10 @@ static const struct file_operations rcar_du_fops = { + }; + + static struct drm_driver rcar_du_driver = { +- .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET +- | DRIVER_PRIME, ++ .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME, + .load = rcar_du_load, + .unload = rcar_du_unload, + .preclose = rcar_du_preclose, +- .irq_handler = rcar_du_irq, + .get_vblank_counter = drm_vblank_count, + .enable_vblank = rcar_du_enable_vblank, + .disable_vblank = rcar_du_disable_vblank, +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +index 06dbf4ff139c..7d2320fb948d 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +@@ -25,6 +25,8 @@ struct clk; + struct device; + struct drm_device; + ++#define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK (1 << 0) /* Per-CRTC IRQ and clock */ ++ + /* + * struct rcar_du_device_info - DU model-specific information + * @features: device features (RCAR_DU_FEATURE_*) +@@ -39,7 +41,6 @@ struct rcar_du_device { + const struct rcar_du_device_info *info; + + void __iomem *mmio; +- struct clk *clock; + unsigned int use_count; + + struct drm_device *ddev; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0016-drm-rcar-du-Clarify-comment-regarding-plane-Y-source.patch b/patches.renesas/0016-drm-rcar-du-Clarify-comment-regarding-plane-Y-source.patch new file mode 100644 index 00000000000000..1c3e46daf2f2e3 --- /dev/null +++ b/patches.renesas/0016-drm-rcar-du-Clarify-comment-regarding-plane-Y-source.patch @@ -0,0 +1,38 @@ +From 0a99fa36a3f7068d626cda0ae1110af6b642aba2 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Fri, 14 Jun 2013 20:54:16 +0200 +Subject: drm/rcar-du: Clarify comment regarding plane Y source coordinate + +The R8A7790 DU documentation contains further information regarding the +plane Y source coordinate. Update the comment accordingly. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 9e7db06d3ac0ffcd866e5b7114f9a7ba12f7b6ac) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_plane.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c +index a65f81ddf51d..38ebd20e4e8d 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c +@@ -103,9 +103,12 @@ void rcar_du_plane_update_base(struct rcar_du_plane *plane) + struct rcar_du_device *rcdu = plane->dev; + unsigned int index = plane->hwindex; + +- /* According to the datasheet the Y position is expressed in raster line +- * units. However, 32bpp formats seem to require a doubled Y position +- * value. Similarly, for the second plane, NV12 and NV21 formats seem to ++ /* The Y position is expressed in raster line units and must be doubled ++ * for 32bpp formats, according to the R8A7790 datasheet. No mention of ++ * doubling the Y position is found in the R8A7779 datasheet, but the ++ * rule seems to apply there as well. ++ * ++ * Similarly, for the second plane, NV12 and NV21 formats seem to + * require a halved Y position value. + */ + rcar_du_plane_write(rcdu, index, PnSPXR, plane->src_x); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0017-drm-rcar-du-Split-LVDS-encoder-and-connector.patch b/patches.renesas/0017-drm-rcar-du-Split-LVDS-encoder-and-connector.patch new file mode 100644 index 00000000000000..b153df55f651c3 --- /dev/null +++ b/patches.renesas/0017-drm-rcar-du-Split-LVDS-encoder-and-connector.patch @@ -0,0 +1,337 @@ +From 38d9143167e03586eb4a1063740cbe71ebde4856 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Sat, 15 Jun 2013 14:21:51 +0200 +Subject: drm/rcar-du: Split LVDS encoder and connector + +This prepares for the encoders rework. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 56c5dd00f8db27a429647b14c8c309bd5d9c1d15) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/Makefile | 1 + + drivers/gpu/drm/rcar-du/rcar_du_lvds.c | 120 +-------------------------- + drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c | 130 ++++++++++++++++++++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h | 25 ++++++ + 4 files changed, 158 insertions(+), 118 deletions(-) + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h + +diff --git a/drivers/gpu/drm/rcar-du/Makefile b/drivers/gpu/drm/rcar-du/Makefile +index 7333c0094015..5def510599b0 100644 +--- a/drivers/gpu/drm/rcar-du/Makefile ++++ b/drivers/gpu/drm/rcar-du/Makefile +@@ -2,6 +2,7 @@ rcar-du-drm-y := rcar_du_crtc.o \ + rcar_du_drv.o \ + rcar_du_kms.o \ + rcar_du_lvds.o \ ++ rcar_du_lvdscon.o \ + rcar_du_plane.o \ + rcar_du_vga.o + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvds.c b/drivers/gpu/drm/rcar-du/rcar_du_lvds.c +index 7aefe7267e1d..82e515741f89 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_lvds.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_lvds.c +@@ -1,5 +1,5 @@ + /* +- * rcar_du_lvds.c -- R-Car Display Unit LVDS Encoder and Connector ++ * rcar_du_lvds.c -- R-Car Display Unit LVDS Encoder + * + * Copyright (C) 2013 Renesas Corporation + * +@@ -18,123 +18,7 @@ + #include "rcar_du_drv.h" + #include "rcar_du_kms.h" + #include "rcar_du_lvds.h" +- +-struct rcar_du_lvds_connector { +- struct rcar_du_connector connector; +- +- const struct rcar_du_panel_data *panel; +-}; +- +-#define to_rcar_lvds_connector(c) \ +- container_of(c, struct rcar_du_lvds_connector, connector.connector) +- +-/* ----------------------------------------------------------------------------- +- * Connector +- */ +- +-static int rcar_du_lvds_connector_get_modes(struct drm_connector *connector) +-{ +- struct rcar_du_lvds_connector *lvdscon = to_rcar_lvds_connector(connector); +- struct drm_display_mode *mode; +- +- mode = drm_mode_create(connector->dev); +- if (mode == NULL) +- return 0; +- +- mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; +- mode->clock = lvdscon->panel->mode.clock; +- mode->hdisplay = lvdscon->panel->mode.hdisplay; +- mode->hsync_start = lvdscon->panel->mode.hsync_start; +- mode->hsync_end = lvdscon->panel->mode.hsync_end; +- mode->htotal = lvdscon->panel->mode.htotal; +- mode->vdisplay = lvdscon->panel->mode.vdisplay; +- mode->vsync_start = lvdscon->panel->mode.vsync_start; +- mode->vsync_end = lvdscon->panel->mode.vsync_end; +- mode->vtotal = lvdscon->panel->mode.vtotal; +- mode->flags = lvdscon->panel->mode.flags; +- +- drm_mode_set_name(mode); +- drm_mode_probed_add(connector, mode); +- +- return 1; +-} +- +-static int rcar_du_lvds_connector_mode_valid(struct drm_connector *connector, +- struct drm_display_mode *mode) +-{ +- return MODE_OK; +-} +- +-static const struct drm_connector_helper_funcs connector_helper_funcs = { +- .get_modes = rcar_du_lvds_connector_get_modes, +- .mode_valid = rcar_du_lvds_connector_mode_valid, +- .best_encoder = rcar_du_connector_best_encoder, +-}; +- +-static void rcar_du_lvds_connector_destroy(struct drm_connector *connector) +-{ +- drm_sysfs_connector_remove(connector); +- drm_connector_cleanup(connector); +-} +- +-static enum drm_connector_status +-rcar_du_lvds_connector_detect(struct drm_connector *connector, bool force) +-{ +- return connector_status_connected; +-} +- +-static const struct drm_connector_funcs connector_funcs = { +- .dpms = drm_helper_connector_dpms, +- .detect = rcar_du_lvds_connector_detect, +- .fill_modes = drm_helper_probe_single_connector_modes, +- .destroy = rcar_du_lvds_connector_destroy, +-}; +- +-static int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu, +- struct rcar_du_encoder *renc, +- const struct rcar_du_panel_data *panel) +-{ +- struct rcar_du_lvds_connector *lvdscon; +- struct drm_connector *connector; +- int ret; +- +- lvdscon = devm_kzalloc(rcdu->dev, sizeof(*lvdscon), GFP_KERNEL); +- if (lvdscon == NULL) +- return -ENOMEM; +- +- lvdscon->panel = panel; +- +- connector = &lvdscon->connector.connector; +- connector->display_info.width_mm = panel->width_mm; +- connector->display_info.height_mm = panel->height_mm; +- +- ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs, +- DRM_MODE_CONNECTOR_LVDS); +- if (ret < 0) +- return ret; +- +- drm_connector_helper_add(connector, &connector_helper_funcs); +- ret = drm_sysfs_connector_add(connector); +- if (ret < 0) +- return ret; +- +- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); +- drm_object_property_set_value(&connector->base, +- rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF); +- +- ret = drm_mode_connector_attach_encoder(connector, &renc->encoder); +- if (ret < 0) +- return ret; +- +- connector->encoder = &renc->encoder; +- lvdscon->connector.encoder = renc; +- +- return 0; +-} +- +-/* ----------------------------------------------------------------------------- +- * Encoder +- */ ++#include "rcar_du_lvdscon.h" + + static void rcar_du_lvds_encoder_dpms(struct drm_encoder *encoder, int mode) + { +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c +new file mode 100644 +index 000000000000..6cfcc9438c68 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c +@@ -0,0 +1,130 @@ ++/* ++ * rcar_du_lvdscon.c -- R-Car Display Unit LVDS Connector ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <drm/drmP.h> ++#include <drm/drm_crtc.h> ++#include <drm/drm_crtc_helper.h> ++ ++#include "rcar_du_drv.h" ++#include "rcar_du_kms.h" ++#include "rcar_du_lvdscon.h" ++ ++struct rcar_du_lvds_connector { ++ struct rcar_du_connector connector; ++ ++ const struct rcar_du_panel_data *panel; ++}; ++ ++#define to_rcar_lvds_connector(c) \ ++ container_of(c, struct rcar_du_lvds_connector, connector.connector) ++ ++static int rcar_du_lvds_connector_get_modes(struct drm_connector *connector) ++{ ++ struct rcar_du_lvds_connector *lvdscon = ++ to_rcar_lvds_connector(connector); ++ struct drm_display_mode *mode; ++ ++ mode = drm_mode_create(connector->dev); ++ if (mode == NULL) ++ return 0; ++ ++ mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; ++ mode->clock = lvdscon->panel->mode.clock; ++ mode->hdisplay = lvdscon->panel->mode.hdisplay; ++ mode->hsync_start = lvdscon->panel->mode.hsync_start; ++ mode->hsync_end = lvdscon->panel->mode.hsync_end; ++ mode->htotal = lvdscon->panel->mode.htotal; ++ mode->vdisplay = lvdscon->panel->mode.vdisplay; ++ mode->vsync_start = lvdscon->panel->mode.vsync_start; ++ mode->vsync_end = lvdscon->panel->mode.vsync_end; ++ mode->vtotal = lvdscon->panel->mode.vtotal; ++ mode->flags = lvdscon->panel->mode.flags; ++ ++ drm_mode_set_name(mode); ++ drm_mode_probed_add(connector, mode); ++ ++ return 1; ++} ++ ++static int rcar_du_lvds_connector_mode_valid(struct drm_connector *connector, ++ struct drm_display_mode *mode) ++{ ++ return MODE_OK; ++} ++ ++static const struct drm_connector_helper_funcs connector_helper_funcs = { ++ .get_modes = rcar_du_lvds_connector_get_modes, ++ .mode_valid = rcar_du_lvds_connector_mode_valid, ++ .best_encoder = rcar_du_connector_best_encoder, ++}; ++ ++static void rcar_du_lvds_connector_destroy(struct drm_connector *connector) ++{ ++ drm_sysfs_connector_remove(connector); ++ drm_connector_cleanup(connector); ++} ++ ++static enum drm_connector_status ++rcar_du_lvds_connector_detect(struct drm_connector *connector, bool force) ++{ ++ return connector_status_connected; ++} ++ ++static const struct drm_connector_funcs connector_funcs = { ++ .dpms = drm_helper_connector_dpms, ++ .detect = rcar_du_lvds_connector_detect, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .destroy = rcar_du_lvds_connector_destroy, ++}; ++ ++int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu, ++ struct rcar_du_encoder *renc, ++ const struct rcar_du_panel_data *panel) ++{ ++ struct rcar_du_lvds_connector *lvdscon; ++ struct drm_connector *connector; ++ int ret; ++ ++ lvdscon = devm_kzalloc(rcdu->dev, sizeof(*lvdscon), GFP_KERNEL); ++ if (lvdscon == NULL) ++ return -ENOMEM; ++ ++ lvdscon->panel = panel; ++ ++ connector = &lvdscon->connector.connector; ++ connector->display_info.width_mm = panel->width_mm; ++ connector->display_info.height_mm = panel->height_mm; ++ ++ ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs, ++ DRM_MODE_CONNECTOR_LVDS); ++ if (ret < 0) ++ return ret; ++ ++ drm_connector_helper_add(connector, &connector_helper_funcs); ++ ret = drm_sysfs_connector_add(connector); ++ if (ret < 0) ++ return ret; ++ ++ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); ++ drm_object_property_set_value(&connector->base, ++ rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF); ++ ++ ret = drm_mode_connector_attach_encoder(connector, &renc->encoder); ++ if (ret < 0) ++ return ret; ++ ++ connector->encoder = &renc->encoder; ++ lvdscon->connector.encoder = renc; ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h +new file mode 100644 +index 000000000000..bff8683699ca +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h +@@ -0,0 +1,25 @@ ++/* ++ * rcar_du_lvdscon.h -- R-Car Display Unit LVDS Connector ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#ifndef __RCAR_DU_LVDSCON_H__ ++#define __RCAR_DU_LVDSCON_H__ ++ ++struct rcar_du_device; ++struct rcar_du_encoder; ++struct rcar_du_panel_data; ++ ++int rcar_du_lvds_connector_init(struct rcar_du_device *rcdu, ++ struct rcar_du_encoder *renc, ++ const struct rcar_du_panel_data *panel); ++ ++#endif /* __RCAR_DU_LVDSCON_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0018-drm-rcar-du-Split-VGA-encoder-and-connector.patch b/patches.renesas/0018-drm-rcar-du-Split-VGA-encoder-and-connector.patch new file mode 100644 index 00000000000000..9141e3e6d737f9 --- /dev/null +++ b/patches.renesas/0018-drm-rcar-du-Split-VGA-encoder-and-connector.patch @@ -0,0 +1,279 @@ +From 2c68507e41c5653e86514c5f995ed0f12b00881c Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Sat, 15 Jun 2013 14:21:51 +0200 +Subject: drm/rcar-du: Split VGA encoder and connector + +This prepares for the encoders rework. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 9e8be27233c1e98b06edeb801640b1f96b09e466) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/Makefile | 3 +- + drivers/gpu/drm/rcar-du/rcar_du_vga.c | 86 +---------------------------- + drivers/gpu/drm/rcar-du/rcar_du_vga.h | 2 +- + drivers/gpu/drm/rcar-du/rcar_du_vgacon.c | 95 ++++++++++++++++++++++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_vgacon.h | 23 ++++++++ + 5 files changed, 123 insertions(+), 86 deletions(-) + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_vgacon.c + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_vgacon.h + +diff --git a/drivers/gpu/drm/rcar-du/Makefile b/drivers/gpu/drm/rcar-du/Makefile +index 5def510599b0..45a8479aed0d 100644 +--- a/drivers/gpu/drm/rcar-du/Makefile ++++ b/drivers/gpu/drm/rcar-du/Makefile +@@ -4,6 +4,7 @@ rcar-du-drm-y := rcar_du_crtc.o \ + rcar_du_lvds.o \ + rcar_du_lvdscon.o \ + rcar_du_plane.o \ +- rcar_du_vga.o ++ rcar_du_vga.o \ ++ rcar_du_vgacon.o + + obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vga.c b/drivers/gpu/drm/rcar-du/rcar_du_vga.c +index 327289ec380d..369ab32d5652 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_vga.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_vga.c +@@ -1,5 +1,5 @@ + /* +- * rcar_du_vga.c -- R-Car Display Unit VGA DAC and Connector ++ * rcar_du_vga.c -- R-Car Display Unit VGA DAC + * + * Copyright (C) 2013 Renesas Corporation + * +@@ -18,89 +18,7 @@ + #include "rcar_du_drv.h" + #include "rcar_du_kms.h" + #include "rcar_du_vga.h" +- +-/* ----------------------------------------------------------------------------- +- * Connector +- */ +- +-static int rcar_du_vga_connector_get_modes(struct drm_connector *connector) +-{ +- return 0; +-} +- +-static int rcar_du_vga_connector_mode_valid(struct drm_connector *connector, +- struct drm_display_mode *mode) +-{ +- return MODE_OK; +-} +- +-static const struct drm_connector_helper_funcs connector_helper_funcs = { +- .get_modes = rcar_du_vga_connector_get_modes, +- .mode_valid = rcar_du_vga_connector_mode_valid, +- .best_encoder = rcar_du_connector_best_encoder, +-}; +- +-static void rcar_du_vga_connector_destroy(struct drm_connector *connector) +-{ +- drm_sysfs_connector_remove(connector); +- drm_connector_cleanup(connector); +-} +- +-static enum drm_connector_status +-rcar_du_vga_connector_detect(struct drm_connector *connector, bool force) +-{ +- return connector_status_unknown; +-} +- +-static const struct drm_connector_funcs connector_funcs = { +- .dpms = drm_helper_connector_dpms, +- .detect = rcar_du_vga_connector_detect, +- .fill_modes = drm_helper_probe_single_connector_modes, +- .destroy = rcar_du_vga_connector_destroy, +-}; +- +-static int rcar_du_vga_connector_init(struct rcar_du_device *rcdu, +- struct rcar_du_encoder *renc) +-{ +- struct rcar_du_connector *rcon; +- struct drm_connector *connector; +- int ret; +- +- rcon = devm_kzalloc(rcdu->dev, sizeof(*rcon), GFP_KERNEL); +- if (rcon == NULL) +- return -ENOMEM; +- +- connector = &rcon->connector; +- connector->display_info.width_mm = 0; +- connector->display_info.height_mm = 0; +- +- ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs, +- DRM_MODE_CONNECTOR_VGA); +- if (ret < 0) +- return ret; +- +- drm_connector_helper_add(connector, &connector_helper_funcs); +- ret = drm_sysfs_connector_add(connector); +- if (ret < 0) +- return ret; +- +- drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); +- drm_object_property_set_value(&connector->base, +- rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF); +- +- ret = drm_mode_connector_attach_encoder(connector, &renc->encoder); +- if (ret < 0) +- return ret; +- +- connector->encoder = &renc->encoder; +- rcon->encoder = renc; +- +- return 0; +-} +- +-/* ----------------------------------------------------------------------------- +- * Encoder +- */ ++#include "rcar_du_vgacon.h" + + static void rcar_du_vga_encoder_dpms(struct drm_encoder *encoder, int mode) + { +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vga.h b/drivers/gpu/drm/rcar-du/rcar_du_vga.h +index 66b4d2d7190d..b969b2075b57 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_vga.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_vga.h +@@ -1,5 +1,5 @@ + /* +- * rcar_du_vga.h -- R-Car Display Unit VGA DAC and Connector ++ * rcar_du_vga.h -- R-Car Display Unit VGA DAC + * + * Copyright (C) 2013 Renesas Corporation + * +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c +new file mode 100644 +index 000000000000..2ee320333615 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c +@@ -0,0 +1,95 @@ ++/* ++ * rcar_du_vgacon.c -- R-Car Display Unit VGA Connector ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <drm/drmP.h> ++#include <drm/drm_crtc.h> ++#include <drm/drm_crtc_helper.h> ++ ++#include "rcar_du_drv.h" ++#include "rcar_du_kms.h" ++#include "rcar_du_vgacon.h" ++ ++static int rcar_du_vga_connector_get_modes(struct drm_connector *connector) ++{ ++ return 0; ++} ++ ++static int rcar_du_vga_connector_mode_valid(struct drm_connector *connector, ++ struct drm_display_mode *mode) ++{ ++ return MODE_OK; ++} ++ ++static const struct drm_connector_helper_funcs connector_helper_funcs = { ++ .get_modes = rcar_du_vga_connector_get_modes, ++ .mode_valid = rcar_du_vga_connector_mode_valid, ++ .best_encoder = rcar_du_connector_best_encoder, ++}; ++ ++static void rcar_du_vga_connector_destroy(struct drm_connector *connector) ++{ ++ drm_sysfs_connector_remove(connector); ++ drm_connector_cleanup(connector); ++} ++ ++static enum drm_connector_status ++rcar_du_vga_connector_detect(struct drm_connector *connector, bool force) ++{ ++ return connector_status_unknown; ++} ++ ++static const struct drm_connector_funcs connector_funcs = { ++ .dpms = drm_helper_connector_dpms, ++ .detect = rcar_du_vga_connector_detect, ++ .fill_modes = drm_helper_probe_single_connector_modes, ++ .destroy = rcar_du_vga_connector_destroy, ++}; ++ ++int rcar_du_vga_connector_init(struct rcar_du_device *rcdu, ++ struct rcar_du_encoder *renc) ++{ ++ struct rcar_du_connector *rcon; ++ struct drm_connector *connector; ++ int ret; ++ ++ rcon = devm_kzalloc(rcdu->dev, sizeof(*rcon), GFP_KERNEL); ++ if (rcon == NULL) ++ return -ENOMEM; ++ ++ connector = &rcon->connector; ++ connector->display_info.width_mm = 0; ++ connector->display_info.height_mm = 0; ++ ++ ret = drm_connector_init(rcdu->ddev, connector, &connector_funcs, ++ DRM_MODE_CONNECTOR_VGA); ++ if (ret < 0) ++ return ret; ++ ++ drm_connector_helper_add(connector, &connector_helper_funcs); ++ ret = drm_sysfs_connector_add(connector); ++ if (ret < 0) ++ return ret; ++ ++ drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); ++ drm_object_property_set_value(&connector->base, ++ rcdu->ddev->mode_config.dpms_property, DRM_MODE_DPMS_OFF); ++ ++ ret = drm_mode_connector_attach_encoder(connector, &renc->encoder); ++ if (ret < 0) ++ return ret; ++ ++ connector->encoder = &renc->encoder; ++ rcon->encoder = renc; ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vgacon.h b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.h +new file mode 100644 +index 000000000000..b12b0cf7f117 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.h +@@ -0,0 +1,23 @@ ++/* ++ * rcar_du_vgacon.h -- R-Car Display Unit VGA Connector ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#ifndef __RCAR_DU_VGACON_H__ ++#define __RCAR_DU_VGACON_H__ ++ ++struct rcar_du_device; ++struct rcar_du_encoder; ++ ++int rcar_du_vga_connector_init(struct rcar_du_device *rcdu, ++ struct rcar_du_encoder *renc); ++ ++#endif /* __RCAR_DU_VGACON_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0019-drm-rcar-du-Merge-LVDS-and-VGA-encoder-code.patch b/patches.renesas/0019-drm-rcar-du-Merge-LVDS-and-VGA-encoder-code.patch new file mode 100644 index 00000000000000..70327d225e26ab --- /dev/null +++ b/patches.renesas/0019-drm-rcar-du-Merge-LVDS-and-VGA-encoder-code.patch @@ -0,0 +1,535 @@ +From 29e17e341e43d36de051c0822a6c76a6df749f83 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Sat, 15 Jun 2013 15:02:12 +0200 +Subject: drm/rcar-du: Merge LVDS and VGA encoder code + +Create a single rcar_du_encoder structure that implements a KMS encoder. +The current implementation is straightforward and only configures CRTC +output routing. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 6978f123776594b251d26dac9bcdf3ce8e9781c8) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/Makefile | 3 +- + drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 2 - + .../rcar-du/{rcar_du_lvds.c => rcar_du_encoder.c} | 74 ++++++++++++++++++---- + drivers/gpu/drm/rcar-du/rcar_du_encoder.h | 45 +++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 49 ++------------ + drivers/gpu/drm/rcar-du/rcar_du_kms.h | 29 +-------- + drivers/gpu/drm/rcar-du/rcar_du_lvds.h | 24 ------- + drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c | 1 + + drivers/gpu/drm/rcar-du/rcar_du_vga.c | 67 -------------------- + drivers/gpu/drm/rcar-du/rcar_du_vga.h | 24 ------- + drivers/gpu/drm/rcar-du/rcar_du_vgacon.c | 1 + + 11 files changed, 118 insertions(+), 201 deletions(-) + rename drivers/gpu/drm/rcar-du/{rcar_du_lvds.c => rcar_du_encoder.c} (53%) + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_encoder.h + delete mode 100644 drivers/gpu/drm/rcar-du/rcar_du_lvds.h + delete mode 100644 drivers/gpu/drm/rcar-du/rcar_du_vga.c + delete mode 100644 drivers/gpu/drm/rcar-du/rcar_du_vga.h + +diff --git a/drivers/gpu/drm/rcar-du/Makefile b/drivers/gpu/drm/rcar-du/Makefile +index 45a8479aed0d..57b0fe1fa66e 100644 +--- a/drivers/gpu/drm/rcar-du/Makefile ++++ b/drivers/gpu/drm/rcar-du/Makefile +@@ -1,10 +1,9 @@ + rcar-du-drm-y := rcar_du_crtc.o \ + rcar_du_drv.o \ ++ rcar_du_encoder.o \ + rcar_du_kms.o \ +- rcar_du_lvds.o \ + rcar_du_lvdscon.o \ + rcar_du_plane.o \ +- rcar_du_vga.o \ + rcar_du_vgacon.o + + obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +index aefc8a0cbcbc..03dd7018dde8 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +@@ -23,10 +23,8 @@ + #include "rcar_du_crtc.h" + #include "rcar_du_drv.h" + #include "rcar_du_kms.h" +-#include "rcar_du_lvds.h" + #include "rcar_du_plane.h" + #include "rcar_du_regs.h" +-#include "rcar_du_vga.h" + + #define to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, crtc) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvds.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +similarity index 53% +rename from drivers/gpu/drm/rcar-du/rcar_du_lvds.c +rename to drivers/gpu/drm/rcar-du/rcar_du_encoder.c +index 82e515741f89..15a56433c80c 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_lvds.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +@@ -1,5 +1,5 @@ + /* +- * rcar_du_lvds.c -- R-Car Display Unit LVDS Encoder ++ * rcar_du_encoder.c -- R-Car Display Unit Encoder + * + * Copyright (C) 2013 Renesas Corporation + * +@@ -16,23 +16,44 @@ + #include <drm/drm_crtc_helper.h> + + #include "rcar_du_drv.h" ++#include "rcar_du_encoder.h" + #include "rcar_du_kms.h" +-#include "rcar_du_lvds.h" + #include "rcar_du_lvdscon.h" ++#include "rcar_du_vgacon.h" + +-static void rcar_du_lvds_encoder_dpms(struct drm_encoder *encoder, int mode) ++/* ----------------------------------------------------------------------------- ++ * Common connector functions ++ */ ++ ++struct drm_encoder * ++rcar_du_connector_best_encoder(struct drm_connector *connector) + { ++ struct rcar_du_connector *rcon = to_rcar_connector(connector); ++ ++ return &rcon->encoder->encoder; + } + +-static bool rcar_du_lvds_encoder_mode_fixup(struct drm_encoder *encoder, +- const struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) ++/* ----------------------------------------------------------------------------- ++ * Encoder ++ */ ++ ++static void rcar_du_encoder_dpms(struct drm_encoder *encoder, int mode) ++{ ++} ++ ++static bool rcar_du_encoder_mode_fixup(struct drm_encoder *encoder, ++ const struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) + { + const struct drm_display_mode *panel_mode; + struct drm_device *dev = encoder->dev; + struct drm_connector *connector; + bool found = false; + ++ /* DAC encoders have currently no restriction on the mode. */ ++ if (encoder->encoder_type == DRM_MODE_ENCODER_DAC) ++ return true; ++ + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + if (connector->encoder == encoder) { + found = true; +@@ -64,9 +85,26 @@ static bool rcar_du_lvds_encoder_mode_fixup(struct drm_encoder *encoder, + return true; + } + ++static void rcar_du_encoder_mode_prepare(struct drm_encoder *encoder) ++{ ++} ++ ++static void rcar_du_encoder_mode_commit(struct drm_encoder *encoder) ++{ ++} ++ ++static void rcar_du_encoder_mode_set(struct drm_encoder *encoder, ++ struct drm_display_mode *mode, ++ struct drm_display_mode *adjusted_mode) ++{ ++ struct rcar_du_encoder *renc = to_rcar_encoder(encoder); ++ ++ rcar_du_crtc_route_output(encoder->crtc, renc->output); ++} ++ + static const struct drm_encoder_helper_funcs encoder_helper_funcs = { +- .dpms = rcar_du_lvds_encoder_dpms, +- .mode_fixup = rcar_du_lvds_encoder_mode_fixup, ++ .dpms = rcar_du_encoder_dpms, ++ .mode_fixup = rcar_du_encoder_mode_fixup, + .prepare = rcar_du_encoder_mode_prepare, + .commit = rcar_du_encoder_mode_commit, + .mode_set = rcar_du_encoder_mode_set, +@@ -76,9 +114,9 @@ static const struct drm_encoder_funcs encoder_funcs = { + .destroy = drm_encoder_cleanup, + }; + +-int rcar_du_lvds_init(struct rcar_du_device *rcdu, +- const struct rcar_du_encoder_lvds_data *data, +- unsigned int output) ++int rcar_du_encoder_init(struct rcar_du_device *rcdu, ++ enum rcar_du_encoder_type type, unsigned int output, ++ const struct rcar_du_encoder_data *data) + { + struct rcar_du_encoder *renc; + int ret; +@@ -90,11 +128,21 @@ int rcar_du_lvds_init(struct rcar_du_device *rcdu, + renc->output = output; + + ret = drm_encoder_init(rcdu->ddev, &renc->encoder, &encoder_funcs, +- DRM_MODE_ENCODER_LVDS); ++ type); + if (ret < 0) + return ret; + + drm_encoder_helper_add(&renc->encoder, &encoder_helper_funcs); + +- return rcar_du_lvds_connector_init(rcdu, renc, &data->panel); ++ switch (type) { ++ case RCAR_DU_ENCODER_LVDS: ++ return rcar_du_lvds_connector_init(rcdu, renc, ++ &data->u.lvds.panel); ++ ++ case RCAR_DU_ENCODER_VGA: ++ return rcar_du_vga_connector_init(rcdu, renc); ++ ++ default: ++ return -EINVAL; ++ } + } +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h +new file mode 100644 +index 000000000000..4f76e16bca88 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h +@@ -0,0 +1,45 @@ ++/* ++ * rcar_du_encoder.h -- R-Car Display Unit Encoder ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#ifndef __RCAR_DU_ENCODER_H__ ++#define __RCAR_DU_ENCODER_H__ ++ ++#include <drm/drm_crtc.h> ++ ++struct rcar_du_device; ++struct rcar_du_encoder_data; ++ ++struct rcar_du_encoder { ++ struct drm_encoder encoder; ++ unsigned int output; ++}; ++ ++#define to_rcar_encoder(e) \ ++ container_of(e, struct rcar_du_encoder, encoder) ++ ++struct rcar_du_connector { ++ struct drm_connector connector; ++ struct rcar_du_encoder *encoder; ++}; ++ ++#define to_rcar_connector(c) \ ++ container_of(c, struct rcar_du_connector, connector) ++ ++struct drm_encoder * ++rcar_du_connector_best_encoder(struct drm_connector *connector); ++ ++int rcar_du_encoder_init(struct rcar_du_device *rcdu, ++ enum rcar_du_encoder_type type, unsigned int output, ++ const struct rcar_du_encoder_data *data); ++ ++#endif /* __RCAR_DU_ENCODER_H__ */ +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +index d30c2e29bee2..3f8483cc0483 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +@@ -19,10 +19,9 @@ + + #include "rcar_du_crtc.h" + #include "rcar_du_drv.h" ++#include "rcar_du_encoder.h" + #include "rcar_du_kms.h" +-#include "rcar_du_lvds.h" + #include "rcar_du_regs.h" +-#include "rcar_du_vga.h" + + /* ----------------------------------------------------------------------------- + * Format helpers +@@ -106,35 +105,6 @@ const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc) + } + + /* ----------------------------------------------------------------------------- +- * Common connector and encoder functions +- */ +- +-struct drm_encoder * +-rcar_du_connector_best_encoder(struct drm_connector *connector) +-{ +- struct rcar_du_connector *rcon = to_rcar_connector(connector); +- +- return &rcon->encoder->encoder; +-} +- +-void rcar_du_encoder_mode_prepare(struct drm_encoder *encoder) +-{ +-} +- +-void rcar_du_encoder_mode_set(struct drm_encoder *encoder, +- struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) +-{ +- struct rcar_du_encoder *renc = to_rcar_encoder(encoder); +- +- rcar_du_crtc_route_output(encoder->crtc, renc->output); +-} +- +-void rcar_du_encoder_mode_commit(struct drm_encoder *encoder) +-{ +-} +- +-/* ----------------------------------------------------------------------------- + * Frame buffer + */ + +@@ -221,6 +191,9 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + const struct rcar_du_encoder_data *pdata = + &rcdu->pdata->encoders[i]; + ++ if (pdata->encoder == RCAR_DU_ENCODER_UNUSED) ++ continue; ++ + if (pdata->output >= ARRAY_SIZE(rcdu->crtcs)) { + dev_warn(rcdu->dev, + "encoder %u references unexisting output %u, skipping\n", +@@ -228,18 +201,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + continue; + } + +- switch (pdata->encoder) { +- case RCAR_DU_ENCODER_VGA: +- rcar_du_vga_init(rcdu, &pdata->u.vga, pdata->output); +- break; +- +- case RCAR_DU_ENCODER_LVDS: +- rcar_du_lvds_init(rcdu, &pdata->u.lvds, pdata->output); +- break; +- +- default: +- break; +- } ++ rcar_du_encoder_init(rcdu, pdata->encoder, pdata->output, ++ pdata); + } + + /* Set the possible CRTCs and possible clones. All encoders can be +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.h b/drivers/gpu/drm/rcar-du/rcar_du_kms.h +index dba472263486..5750e6af5655 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.h +@@ -16,8 +16,9 @@ + + #include <linux/types.h> + +-#include <drm/drm_crtc.h> +- ++struct drm_file; ++struct drm_device; ++struct drm_mode_create_dumb; + struct rcar_du_device; + + struct rcar_du_format_info { +@@ -28,32 +29,8 @@ struct rcar_du_format_info { + unsigned int edf; + }; + +-struct rcar_du_encoder { +- struct drm_encoder encoder; +- unsigned int output; +-}; +- +-#define to_rcar_encoder(e) \ +- container_of(e, struct rcar_du_encoder, encoder) +- +-struct rcar_du_connector { +- struct drm_connector connector; +- struct rcar_du_encoder *encoder; +-}; +- +-#define to_rcar_connector(c) \ +- container_of(c, struct rcar_du_connector, connector) +- + const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc); + +-struct drm_encoder * +-rcar_du_connector_best_encoder(struct drm_connector *connector); +-void rcar_du_encoder_mode_prepare(struct drm_encoder *encoder); +-void rcar_du_encoder_mode_set(struct drm_encoder *encoder, +- struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode); +-void rcar_du_encoder_mode_commit(struct drm_encoder *encoder); +- + int rcar_du_modeset_init(struct rcar_du_device *rcdu); + + int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev, +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvds.h b/drivers/gpu/drm/rcar-du/rcar_du_lvds.h +deleted file mode 100644 +index b47f8328e103..000000000000 +--- a/drivers/gpu/drm/rcar-du/rcar_du_lvds.h ++++ /dev/null +@@ -1,24 +0,0 @@ +-/* +- * rcar_du_lvds.h -- R-Car Display Unit LVDS Encoder and Connector +- * +- * Copyright (C) 2013 Renesas Corporation +- * +- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) +- * +- * 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, or +- * (at your option) any later version. +- */ +- +-#ifndef __RCAR_DU_LVDS_H__ +-#define __RCAR_DU_LVDS_H__ +- +-struct rcar_du_device; +-struct rcar_du_encoder_lvds_data; +- +-int rcar_du_lvds_init(struct rcar_du_device *rcdu, +- const struct rcar_du_encoder_lvds_data *data, +- unsigned int output); +- +-#endif /* __RCAR_DU_LVDS_H__ */ +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c +index 6cfcc9438c68..4f3ba93cd91d 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c +@@ -16,6 +16,7 @@ + #include <drm/drm_crtc_helper.h> + + #include "rcar_du_drv.h" ++#include "rcar_du_encoder.h" + #include "rcar_du_kms.h" + #include "rcar_du_lvdscon.h" + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vga.c b/drivers/gpu/drm/rcar-du/rcar_du_vga.c +deleted file mode 100644 +index 369ab32d5652..000000000000 +--- a/drivers/gpu/drm/rcar-du/rcar_du_vga.c ++++ /dev/null +@@ -1,67 +0,0 @@ +-/* +- * rcar_du_vga.c -- R-Car Display Unit VGA DAC +- * +- * Copyright (C) 2013 Renesas Corporation +- * +- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) +- * +- * 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, or +- * (at your option) any later version. +- */ +- +-#include <drm/drmP.h> +-#include <drm/drm_crtc.h> +-#include <drm/drm_crtc_helper.h> +- +-#include "rcar_du_drv.h" +-#include "rcar_du_kms.h" +-#include "rcar_du_vga.h" +-#include "rcar_du_vgacon.h" +- +-static void rcar_du_vga_encoder_dpms(struct drm_encoder *encoder, int mode) +-{ +-} +- +-static bool rcar_du_vga_encoder_mode_fixup(struct drm_encoder *encoder, +- const struct drm_display_mode *mode, +- struct drm_display_mode *adjusted_mode) +-{ +- return true; +-} +- +-static const struct drm_encoder_helper_funcs encoder_helper_funcs = { +- .dpms = rcar_du_vga_encoder_dpms, +- .mode_fixup = rcar_du_vga_encoder_mode_fixup, +- .prepare = rcar_du_encoder_mode_prepare, +- .commit = rcar_du_encoder_mode_commit, +- .mode_set = rcar_du_encoder_mode_set, +-}; +- +-static const struct drm_encoder_funcs encoder_funcs = { +- .destroy = drm_encoder_cleanup, +-}; +- +-int rcar_du_vga_init(struct rcar_du_device *rcdu, +- const struct rcar_du_encoder_vga_data *data, +- unsigned int output) +-{ +- struct rcar_du_encoder *renc; +- int ret; +- +- renc = devm_kzalloc(rcdu->dev, sizeof(*renc), GFP_KERNEL); +- if (renc == NULL) +- return -ENOMEM; +- +- renc->output = output; +- +- ret = drm_encoder_init(rcdu->ddev, &renc->encoder, &encoder_funcs, +- DRM_MODE_ENCODER_DAC); +- if (ret < 0) +- return ret; +- +- drm_encoder_helper_add(&renc->encoder, &encoder_helper_funcs); +- +- return rcar_du_vga_connector_init(rcdu, renc); +-} +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vga.h b/drivers/gpu/drm/rcar-du/rcar_du_vga.h +deleted file mode 100644 +index b969b2075b57..000000000000 +--- a/drivers/gpu/drm/rcar-du/rcar_du_vga.h ++++ /dev/null +@@ -1,24 +0,0 @@ +-/* +- * rcar_du_vga.h -- R-Car Display Unit VGA DAC +- * +- * Copyright (C) 2013 Renesas Corporation +- * +- * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) +- * +- * 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, or +- * (at your option) any later version. +- */ +- +-#ifndef __RCAR_DU_VGA_H__ +-#define __RCAR_DU_VGA_H__ +- +-struct rcar_du_device; +-struct rcar_du_encoder_vga_data; +- +-int rcar_du_vga_init(struct rcar_du_device *rcdu, +- const struct rcar_du_encoder_vga_data *data, +- unsigned int output); +- +-#endif /* __RCAR_DU_VGA_H__ */ +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c +index 2ee320333615..36105db9bda1 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c +@@ -16,6 +16,7 @@ + #include <drm/drm_crtc_helper.h> + + #include "rcar_du_drv.h" ++#include "rcar_du_encoder.h" + #include "rcar_du_kms.h" + #include "rcar_du_vgacon.h" + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0020-drm-rcar-du-Rename-platform-data-fields-to-match-wha.patch b/patches.renesas/0020-drm-rcar-du-Rename-platform-data-fields-to-match-wha.patch new file mode 100644 index 00000000000000..15c64823fce4a0 --- /dev/null +++ b/patches.renesas/0020-drm-rcar-du-Rename-platform-data-fields-to-match-wha.patch @@ -0,0 +1,115 @@ +From e3dca5eb510aa12130188f1c49e214fe575a0840 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Sun, 16 Jun 2013 16:25:35 +0200 +Subject: drm/rcar-du: Rename platform data fields to match what they describe + +The struct rcar_du_encoder_data encoder::field describes the encoder +type, and the rcar_du_encoder_lvds_data and rcar_du_encoder_vga_data +structures describe connector properties. Rename them accordingly. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 9194731c5f9b2664c882a515b3398a29384a6864) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 2 +- + drivers/gpu/drm/rcar-du/rcar_du_encoder.h | 3 ++- + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 5 ++--- + include/linux/platform_data/rcar-du.h | 19 +++++++++++++------ + 4 files changed, 18 insertions(+), 11 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +index 15a56433c80c..0d0375c7ee44 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +@@ -137,7 +137,7 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, + switch (type) { + case RCAR_DU_ENCODER_LVDS: + return rcar_du_lvds_connector_init(rcdu, renc, +- &data->u.lvds.panel); ++ &data->connector.lvds.panel); + + case RCAR_DU_ENCODER_VGA: + return rcar_du_vga_connector_init(rcdu, renc); +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h +index 4f76e16bca88..08cde1293892 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h +@@ -14,10 +14,11 @@ + #ifndef __RCAR_DU_ENCODER_H__ + #define __RCAR_DU_ENCODER_H__ + ++#include <linux/platform_data/rcar-du.h> ++ + #include <drm/drm_crtc.h> + + struct rcar_du_device; +-struct rcar_du_encoder_data; + + struct rcar_du_encoder { + struct drm_encoder encoder; +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +index 3f8483cc0483..a8eef167d51a 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +@@ -191,7 +191,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + const struct rcar_du_encoder_data *pdata = + &rcdu->pdata->encoders[i]; + +- if (pdata->encoder == RCAR_DU_ENCODER_UNUSED) ++ if (pdata->type == RCAR_DU_ENCODER_UNUSED) + continue; + + if (pdata->output >= ARRAY_SIZE(rcdu->crtcs)) { +@@ -201,8 +201,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + continue; + } + +- rcar_du_encoder_init(rcdu, pdata->encoder, pdata->output, +- pdata); ++ rcar_du_encoder_init(rcdu, pdata->type, pdata->output, pdata); + } + + /* Set the possible CRTCs and possible clones. All encoders can be +diff --git a/include/linux/platform_data/rcar-du.h b/include/linux/platform_data/rcar-du.h +index 80587fdbba3e..64cd8635e6e6 100644 +--- a/include/linux/platform_data/rcar-du.h ++++ b/include/linux/platform_data/rcar-du.h +@@ -28,22 +28,29 @@ struct rcar_du_panel_data { + struct drm_mode_modeinfo mode; + }; + +-struct rcar_du_encoder_lvds_data { ++struct rcar_du_connector_lvds_data { + struct rcar_du_panel_data panel; + }; + +-struct rcar_du_encoder_vga_data { ++struct rcar_du_connector_vga_data { + /* TODO: Add DDC information for EDID retrieval */ + }; + ++/* ++ * struct rcar_du_encoder_data - Encoder platform data ++ * @type: the encoder type (RCAR_DU_ENCODER_*) ++ * @output: the DU output the connector is connected to ++ * @connector.lvds: platform data for LVDS connectors ++ * @connector.vga: platform data for VGA connectors ++ */ + struct rcar_du_encoder_data { +- enum rcar_du_encoder_type encoder; ++ enum rcar_du_encoder_type type; + unsigned int output; + + union { +- struct rcar_du_encoder_lvds_data lvds; +- struct rcar_du_encoder_vga_data vga; +- } u; ++ struct rcar_du_connector_lvds_data lvds; ++ struct rcar_du_connector_vga_data vga; ++ } connector; + }; + + struct rcar_du_platform_data { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0021-drm-rcar-du-Create-rcar_du_planes-structure.patch b/patches.renesas/0021-drm-rcar-du-Create-rcar_du_planes-structure.patch new file mode 100644 index 00000000000000..c55e2c0b3ecf51 --- /dev/null +++ b/patches.renesas/0021-drm-rcar-du-Create-rcar_du_planes-structure.patch @@ -0,0 +1,83 @@ +From 117fb0358a861aaa00e31cca4257a5e092a779e3 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Sun, 16 Jun 2013 21:02:49 +0200 +Subject: drm/rcar-du: Create rcar_du_planes structure + +Move the plane-related fields of struct rcar_du_device to their own +structure. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit ae425b6a77a1118b1b4f594efe4aaa4243bf222b) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_drv.h | 11 +---------- + drivers/gpu/drm/rcar-du/rcar_du_plane.h | 17 +++++++++++++++-- + 2 files changed, 16 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +index 7d2320fb948d..0305c21d71f3 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +@@ -15,7 +15,6 @@ + #define __RCAR_DU_DRV_H__ + + #include <linux/kernel.h> +-#include <linux/mutex.h> + #include <linux/platform_data/rcar-du.h> + + #include "rcar_du_crtc.h" +@@ -49,15 +48,7 @@ struct rcar_du_device { + unsigned int used_crtcs; + unsigned int num_crtcs; + +- struct { +- struct rcar_du_plane planes[RCAR_DU_NUM_SW_PLANES]; +- unsigned int free; +- struct mutex lock; +- +- struct drm_property *alpha; +- struct drm_property *colorkey; +- struct drm_property *zpos; +- } planes; ++ struct rcar_du_planes planes; + }; + + static inline bool rcar_du_has(struct rcar_du_device *rcdu, +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h +index 5397dba2fe57..5c8488ca019f 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h +@@ -14,8 +14,11 @@ + #ifndef __RCAR_DU_PLANE_H__ + #define __RCAR_DU_PLANE_H__ + +-struct drm_crtc; +-struct drm_framebuffer; ++#include <linux/mutex.h> ++ ++#include <drm/drmP.h> ++#include <drm/drm_crtc.h> ++ + struct rcar_du_device; + struct rcar_du_format_info; + +@@ -54,6 +57,16 @@ struct rcar_du_plane { + unsigned int dst_y; + }; + ++struct rcar_du_planes { ++ struct rcar_du_plane planes[RCAR_DU_NUM_SW_PLANES]; ++ unsigned int free; ++ struct mutex lock; ++ ++ struct drm_property *alpha; ++ struct drm_property *colorkey; ++ struct drm_property *zpos; ++}; ++ + int rcar_du_plane_init(struct rcar_du_device *rcdu); + int rcar_du_plane_register(struct rcar_du_device *rcdu); + void rcar_du_plane_setup(struct rcar_du_plane *plane); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0022-drm-rcar-du-Rename-rcar_du_plane_-init-register-to-r.patch b/patches.renesas/0022-drm-rcar-du-Rename-rcar_du_plane_-init-register-to-r.patch new file mode 100644 index 00000000000000..663039db40d486 --- /dev/null +++ b/patches.renesas/0022-drm-rcar-du-Rename-rcar_du_plane_-init-register-to-r.patch @@ -0,0 +1,80 @@ +From 4133d2bb9eb55443acfe8411ca5f2def731232f1 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Sun, 16 Jun 2013 19:18:31 +0200 +Subject: drm/rcar-du: Rename rcar_du_plane_(init|register) to rcar_du_planes_* + +The functions initialize or register all planes, rename them +accordingly. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 7fe99fda5f5c52a01b2c966aa68341a0b3d8ab33) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 4 ++-- + drivers/gpu/drm/rcar-du/rcar_du_plane.c | 4 ++-- + drivers/gpu/drm/rcar-du/rcar_du_plane.h | 5 +++-- + 3 files changed, 7 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +index a8eef167d51a..a1343fbde57a 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +@@ -174,7 +174,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + rcdu->ddev->mode_config.max_height = 2047; + rcdu->ddev->mode_config.funcs = &rcar_du_mode_config_funcs; + +- ret = rcar_du_plane_init(rcdu); ++ ret = rcar_du_planes_init(rcdu); + if (ret < 0) + return ret; + +@@ -215,7 +215,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + encoder->possible_clones = 1 << 0; + } + +- ret = rcar_du_plane_register(rcdu); ++ ret = rcar_du_planes_register(rcdu); + if (ret < 0) + return ret; + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c +index 38ebd20e4e8d..29f21477ef0e 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c +@@ -435,7 +435,7 @@ static const uint32_t formats[] = { + DRM_FORMAT_NV16, + }; + +-int rcar_du_plane_init(struct rcar_du_device *rcdu) ++int rcar_du_planes_init(struct rcar_du_device *rcdu) + { + unsigned int i; + +@@ -475,7 +475,7 @@ int rcar_du_plane_init(struct rcar_du_device *rcdu) + return 0; + } + +-int rcar_du_plane_register(struct rcar_du_device *rcdu) ++int rcar_du_planes_register(struct rcar_du_device *rcdu) + { + unsigned int i; + int ret; +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h +index 5c8488ca019f..bcf6f76f56a0 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h +@@ -67,8 +67,9 @@ struct rcar_du_planes { + struct drm_property *zpos; + }; + +-int rcar_du_plane_init(struct rcar_du_device *rcdu); +-int rcar_du_plane_register(struct rcar_du_device *rcdu); ++int rcar_du_planes_init(struct rcar_du_device *rcdu); ++int rcar_du_planes_register(struct rcar_du_device *rcdu); ++ + void rcar_du_plane_setup(struct rcar_du_plane *plane); + void rcar_du_plane_update_base(struct rcar_du_plane *plane); + void rcar_du_plane_compute_base(struct rcar_du_plane *plane, +-- +1.8.5.rc3 + diff --git a/patches.renesas/0023-drm-rcar-du-Introduce-CRTCs-groups.patch b/patches.renesas/0023-drm-rcar-du-Introduce-CRTCs-groups.patch new file mode 100644 index 00000000000000..ca56d8965609d7 --- /dev/null +++ b/patches.renesas/0023-drm-rcar-du-Introduce-CRTCs-groups.patch @@ -0,0 +1,1098 @@ +From 62db4469a68f3aa96132071ada5e265987c7900a Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Sun, 16 Jun 2013 21:01:02 +0200 +Subject: drm/rcar-du: Introduce CRTCs groups + +The R8A7779 DU is split in per-CRTC resources (scan-out engine, blending +unit, timings generator, ...) and device-global resources (start/stop +control, planes, ...) shared between the two CRTCs. + +The R8A7790 introduced a third CRTC with its own set of global resources +This would be modeled as two separate DU device instances if it wasn't +for a handful or resources that are shared between the three CRTCs +(mostly related to input and output routing). For this reason the +R8A7790 DU must be modeled as a single device with three CRTCs, two sets +of "semi-global" resources, and a few device-global resources. + +Introduce a new rcar_du_group driver-specific object, without any real +counterpart in the DU documentation, that models those semi-global +resources. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit cb2025d2509ffab1c426509fd9de3d83e40398b9) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/Makefile | 1 + + drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 92 ++++++------------- + drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 5 +- + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 46 ---------- + drivers/gpu/drm/rcar-du/rcar_du_drv.h | 10 +-- + drivers/gpu/drm/rcar-du/rcar_du_group.c | 127 ++++++++++++++++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_group.h | 47 ++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 11 ++- + drivers/gpu/drm/rcar-du/rcar_du_plane.c | 155 ++++++++++++++++---------------- + drivers/gpu/drm/rcar-du/rcar_du_plane.h | 8 +- + 10 files changed, 299 insertions(+), 203 deletions(-) + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_group.c + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_group.h + +diff --git a/drivers/gpu/drm/rcar-du/Makefile b/drivers/gpu/drm/rcar-du/Makefile +index 57b0fe1fa66e..b9b5e666fbba 100644 +--- a/drivers/gpu/drm/rcar-du/Makefile ++++ b/drivers/gpu/drm/rcar-du/Makefile +@@ -1,6 +1,7 @@ + rcar-du-drm-y := rcar_du_crtc.o \ + rcar_du_drv.o \ + rcar_du_encoder.o \ ++ rcar_du_group.o \ + rcar_du_kms.o \ + rcar_du_lvdscon.o \ + rcar_du_plane.o \ +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +index 03dd7018dde8..7784a3ba7854 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +@@ -30,21 +30,21 @@ + + static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg) + { +- struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ struct rcar_du_device *rcdu = rcrtc->group->dev; + + return rcar_du_read(rcdu, rcrtc->mmio_offset + reg); + } + + static void rcar_du_crtc_write(struct rcar_du_crtc *rcrtc, u32 reg, u32 data) + { +- struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ struct rcar_du_device *rcdu = rcrtc->group->dev; + + rcar_du_write(rcdu, rcrtc->mmio_offset + reg, data); + } + + static void rcar_du_crtc_clr(struct rcar_du_crtc *rcrtc, u32 reg, u32 clr) + { +- struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ struct rcar_du_device *rcdu = rcrtc->group->dev; + + rcar_du_write(rcdu, rcrtc->mmio_offset + reg, + rcar_du_read(rcdu, rcrtc->mmio_offset + reg) & ~clr); +@@ -52,7 +52,7 @@ static void rcar_du_crtc_clr(struct rcar_du_crtc *rcrtc, u32 reg, u32 clr) + + static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set) + { +- struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ struct rcar_du_device *rcdu = rcrtc->group->dev; + + rcar_du_write(rcdu, rcrtc->mmio_offset + reg, + rcar_du_read(rcdu, rcrtc->mmio_offset + reg) | set); +@@ -61,7 +61,7 @@ static void rcar_du_crtc_set(struct rcar_du_crtc *rcrtc, u32 reg, u32 set) + static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg, + u32 clr, u32 set) + { +- struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ struct rcar_du_device *rcdu = rcrtc->group->dev; + u32 value = rcar_du_read(rcdu, rcrtc->mmio_offset + reg); + + rcar_du_write(rcdu, rcrtc->mmio_offset + reg, (value & ~clr) | set); +@@ -69,14 +69,13 @@ static void rcar_du_crtc_clr_set(struct rcar_du_crtc *rcrtc, u32 reg, + + static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc) + { +- struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; + int ret; + + ret = clk_prepare_enable(rcrtc->clock); + if (ret < 0) + return ret; + +- ret = rcar_du_get(rcdu); ++ ret = rcar_du_group_get(rcrtc->group); + if (ret < 0) + clk_disable_unprepare(rcrtc->clock); + +@@ -85,17 +84,14 @@ static int rcar_du_crtc_get(struct rcar_du_crtc *rcrtc) + + static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc) + { +- struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; +- +- rcar_du_put(rcdu); ++ rcar_du_group_put(rcrtc->group); + clk_disable_unprepare(rcrtc->clock); + } + + static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) + { +- struct drm_crtc *crtc = &rcrtc->crtc; +- struct rcar_du_device *rcdu = crtc->dev->dev_private; +- const struct drm_display_mode *mode = &crtc->mode; ++ const struct drm_display_mode *mode = &rcrtc->crtc.mode; ++ struct rcar_du_device *rcdu = rcrtc->group->dev; + unsigned long clk; + u32 value; + u32 div; +@@ -136,7 +132,7 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) + + static void rcar_du_crtc_set_routing(struct rcar_du_crtc *rcrtc) + { +- struct rcar_du_device *rcdu = rcrtc->crtc.dev->dev_private; ++ struct rcar_du_device *rcdu = rcrtc->group->dev; + u32 dorcr = rcar_du_read(rcdu, DORCR); + + dorcr &= ~(DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_MASK); +@@ -153,36 +149,6 @@ static void rcar_du_crtc_set_routing(struct rcar_du_crtc *rcrtc) + rcar_du_write(rcdu, DORCR, dorcr); + } + +-static void __rcar_du_start_stop(struct rcar_du_device *rcdu, bool start) +-{ +- rcar_du_write(rcdu, DSYSR, +- (rcar_du_read(rcdu, DSYSR) & ~(DSYSR_DRES | DSYSR_DEN)) | +- (start ? DSYSR_DEN : DSYSR_DRES)); +-} +- +-static void rcar_du_start_stop(struct rcar_du_device *rcdu, bool start) +-{ +- /* Many of the configuration bits are only updated when the display +- * reset (DRES) bit in DSYSR is set to 1, disabling *both* CRTCs. Some +- * of those bits could be pre-configured, but others (especially the +- * bits related to plane assignment to display timing controllers) need +- * to be modified at runtime. +- * +- * Restart the display controller if a start is requested. Sorry for the +- * flicker. It should be possible to move most of the "DRES-update" bits +- * setup to driver initialization time and minimize the number of cases +- * when the display controller will have to be restarted. +- */ +- if (start) { +- if (rcdu->used_crtcs++ != 0) +- __rcar_du_start_stop(rcdu, false); +- __rcar_du_start_stop(rcdu, true); +- } else { +- if (--rcdu->used_crtcs == 0) +- __rcar_du_start_stop(rcdu, false); +- } +-} +- + void rcar_du_crtc_route_output(struct drm_crtc *crtc, unsigned int output) + { + struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); +@@ -195,8 +161,8 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc, unsigned int output) + + void rcar_du_crtc_update_planes(struct drm_crtc *crtc) + { +- struct rcar_du_device *rcdu = crtc->dev->dev_private; + struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); ++ struct rcar_du_device *rcdu = rcrtc->group->dev; + struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES]; + unsigned int num_planes = 0; + unsigned int prio = 0; +@@ -204,8 +170,8 @@ void rcar_du_crtc_update_planes(struct drm_crtc *crtc) + u32 dptsr = 0; + u32 dspr = 0; + +- for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) { +- struct rcar_du_plane *plane = &rcdu->planes.planes[i]; ++ for (i = 0; i < ARRAY_SIZE(rcrtc->group->planes.planes); ++i) { ++ struct rcar_du_plane *plane = &rcrtc->group->planes.planes[i]; + unsigned int j; + + if (plane->crtc != &rcrtc->crtc || !plane->enabled) +@@ -254,10 +220,8 @@ void rcar_du_crtc_update_planes(struct drm_crtc *crtc) + */ + if (value != dptsr) { + rcar_du_write(rcdu, DPTSR, dptsr); +- if (rcdu->used_crtcs) { +- __rcar_du_start_stop(rcdu, false); +- __rcar_du_start_stop(rcdu, true); +- } ++ if (rcrtc->group->used_crtcs) ++ rcar_du_group_restart(rcrtc->group); + } + } + +@@ -267,7 +231,6 @@ void rcar_du_crtc_update_planes(struct drm_crtc *crtc) + static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc) + { + struct drm_crtc *crtc = &rcrtc->crtc; +- struct rcar_du_device *rcdu = crtc->dev->dev_private; + unsigned int i; + + if (rcrtc->started) +@@ -284,14 +247,14 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc) + rcar_du_crtc_set_display_timing(rcrtc); + rcar_du_crtc_set_routing(rcrtc); + +- mutex_lock(&rcdu->planes.lock); ++ mutex_lock(&rcrtc->group->planes.lock); + rcrtc->plane->enabled = true; + rcar_du_crtc_update_planes(crtc); +- mutex_unlock(&rcdu->planes.lock); ++ mutex_unlock(&rcrtc->group->planes.lock); + + /* Setup planes. */ +- for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) { +- struct rcar_du_plane *plane = &rcdu->planes.planes[i]; ++ for (i = 0; i < ARRAY_SIZE(rcrtc->group->planes.planes); ++i) { ++ struct rcar_du_plane *plane = &rcrtc->group->planes.planes[i]; + + if (plane->crtc != crtc || !plane->enabled) + continue; +@@ -305,7 +268,7 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc) + */ + rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_MASTER); + +- rcar_du_start_stop(rcdu, true); ++ rcar_du_group_start_stop(rcrtc->group, true); + + rcrtc->started = true; + } +@@ -313,22 +276,21 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc) + static void rcar_du_crtc_stop(struct rcar_du_crtc *rcrtc) + { + struct drm_crtc *crtc = &rcrtc->crtc; +- struct rcar_du_device *rcdu = crtc->dev->dev_private; + + if (!rcrtc->started) + return; + +- mutex_lock(&rcdu->planes.lock); ++ mutex_lock(&rcrtc->group->planes.lock); + rcrtc->plane->enabled = false; + rcar_du_crtc_update_planes(crtc); +- mutex_unlock(&rcdu->planes.lock); ++ mutex_unlock(&rcrtc->group->planes.lock); + + /* Select switch sync mode. This stops display operation and configures + * the HSYNC and VSYNC signals as inputs. + */ + rcar_du_crtc_clr_set(rcrtc, DSYSR, DSYSR_TVM_MASK, DSYSR_TVM_SWITCH); + +- rcar_du_start_stop(rcdu, false); ++ rcar_du_group_start_stop(rcrtc->group, false); + + rcrtc->started = false; + } +@@ -406,8 +368,8 @@ static int rcar_du_crtc_mode_set(struct drm_crtc *crtc, + int x, int y, + struct drm_framebuffer *old_fb) + { +- struct rcar_du_device *rcdu = crtc->dev->dev_private; + struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); ++ struct rcar_du_device *rcdu = rcrtc->group->dev; + const struct rcar_du_format_info *format; + int ret; + +@@ -583,8 +545,9 @@ static const struct drm_crtc_funcs crtc_funcs = { + .page_flip = rcar_du_crtc_page_flip, + }; + +-int rcar_du_crtc_create(struct rcar_du_device *rcdu, unsigned int index) ++int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) + { ++ struct rcar_du_device *rcdu = rgrp->dev; + struct platform_device *pdev = to_platform_device(rcdu->dev); + struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index]; + struct drm_crtc *crtc = &rcrtc->crtc; +@@ -608,10 +571,11 @@ int rcar_du_crtc_create(struct rcar_du_device *rcdu, unsigned int index) + return PTR_ERR(rcrtc->clock); + } + ++ rcrtc->group = rgrp; + rcrtc->mmio_offset = index ? DISP2_REG_OFFSET : 0; + rcrtc->index = index; + rcrtc->dpms = DRM_MODE_DPMS_OFF; +- rcrtc->plane = &rcdu->planes.planes[index]; ++ rcrtc->plane = &rgrp->planes.planes[index]; + + rcrtc->plane->crtc = crtc; + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +index 5b69e98a3b92..542a7feceb20 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +@@ -19,7 +19,7 @@ + #include <drm/drmP.h> + #include <drm/drm_crtc.h> + +-struct rcar_du_device; ++struct rcar_du_group; + struct rcar_du_plane; + + struct rcar_du_crtc { +@@ -34,10 +34,11 @@ struct rcar_du_crtc { + unsigned int outputs; + int dpms; + ++ struct rcar_du_group *group; + struct rcar_du_plane *plane; + }; + +-int rcar_du_crtc_create(struct rcar_du_device *rcdu, unsigned int index); ++int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index); + void rcar_du_crtc_enable_vblank(struct rcar_du_crtc *rcrtc, bool enable); + void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc, + struct drm_file *file); +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +index 9b89dbf3fb32..8600b2b6aea4 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -29,52 +29,6 @@ + #include "rcar_du_regs.h" + + /* ----------------------------------------------------------------------------- +- * Core device operations +- */ +- +-/* +- * rcar_du_get - Acquire a reference to the DU +- * +- * Acquiring the first reference setups core registers. A reference must be +- * held before accessing any hardware registers. +- * +- * This function must be called with the DRM mode_config lock held. +- * +- * Return 0 in case of success or a negative error code otherwise. +- */ +-int rcar_du_get(struct rcar_du_device *rcdu) +-{ +- if (rcdu->use_count) +- goto done; +- +- /* Enable extended features */ +- rcar_du_write(rcdu, DEFR, DEFR_CODE | DEFR_DEFE); +- rcar_du_write(rcdu, DEFR2, DEFR2_CODE | DEFR2_DEFE2G); +- rcar_du_write(rcdu, DEFR3, DEFR3_CODE | DEFR3_DEFE3); +- rcar_du_write(rcdu, DEFR4, DEFR4_CODE); +- rcar_du_write(rcdu, DEFR5, DEFR5_CODE | DEFR5_DEFE5); +- +- /* Use DS1PR and DS2PR to configure planes priorities and connects the +- * superposition 0 to DU0 pins. DU1 pins will be configured dynamically. +- */ +- rcar_du_write(rcdu, DORCR, DORCR_PG1D_DS1 | DORCR_DPRS); +- +-done: +- rcdu->use_count++; +- return 0; +-} +- +-/* +- * rcar_du_put - Release a reference to the DU +- * +- * This function must be called with the DRM mode_config lock held. +- */ +-void rcar_du_put(struct rcar_du_device *rcdu) +-{ +- --rcdu->use_count; +-} +- +-/* ----------------------------------------------------------------------------- + * DRM operations + */ + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +index 0305c21d71f3..5b57a2f9b52a 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +@@ -18,11 +18,12 @@ + #include <linux/platform_data/rcar-du.h> + + #include "rcar_du_crtc.h" +-#include "rcar_du_plane.h" ++#include "rcar_du_group.h" + + struct clk; + struct device; + struct drm_device; ++struct rcar_du_device; + + #define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK (1 << 0) /* Per-CRTC IRQ and clock */ + +@@ -40,15 +41,13 @@ struct rcar_du_device { + const struct rcar_du_device_info *info; + + void __iomem *mmio; +- unsigned int use_count; + + struct drm_device *ddev; + + struct rcar_du_crtc crtcs[2]; +- unsigned int used_crtcs; + unsigned int num_crtcs; + +- struct rcar_du_planes planes; ++ struct rcar_du_group group; + }; + + static inline bool rcar_du_has(struct rcar_du_device *rcdu, +@@ -57,9 +56,6 @@ static inline bool rcar_du_has(struct rcar_du_device *rcdu, + return rcdu->info->features & feature; + } + +-int rcar_du_get(struct rcar_du_device *rcdu); +-void rcar_du_put(struct rcar_du_device *rcdu); +- + static inline u32 rcar_du_read(struct rcar_du_device *rcdu, u32 reg) + { + return ioread32(rcdu->mmio + reg); +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c +new file mode 100644 +index 000000000000..625b9f446965 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c +@@ -0,0 +1,127 @@ ++/* ++ * rcar_du_group.c -- R-Car Display Unit Channels Pair ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++/* ++ * The R8A7779 DU is split in per-CRTC resources (scan-out engine, blending ++ * unit, timings generator, ...) and device-global resources (start/stop ++ * control, planes, ...) shared between the two CRTCs. ++ * ++ * The R8A7790 introduced a third CRTC with its own set of global resources. ++ * This would be modeled as two separate DU device instances if it wasn't for ++ * a handful or resources that are shared between the three CRTCs (mostly ++ * related to input and output routing). For this reason the R8A7790 DU must be ++ * modeled as a single device with three CRTCs, two sets of "semi-global" ++ * resources, and a few device-global resources. ++ * ++ * The rcar_du_group object is a driver specific object, without any real ++ * counterpart in the DU documentation, that models those semi-global resources. ++ */ ++ ++#include <linux/io.h> ++ ++#include "rcar_du_drv.h" ++#include "rcar_du_group.h" ++#include "rcar_du_regs.h" ++ ++static u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg) ++{ ++ return rcar_du_read(rgrp->dev, rgrp->mmio_offset + reg); ++} ++ ++static void rcar_du_group_write(struct rcar_du_group *rgrp, u32 reg, u32 data) ++{ ++ rcar_du_write(rgrp->dev, rgrp->mmio_offset + reg, data); ++} ++ ++static void rcar_du_group_setup(struct rcar_du_group *rgrp) ++{ ++ /* Enable extended features */ ++ rcar_du_group_write(rgrp, DEFR, DEFR_CODE | DEFR_DEFE); ++ rcar_du_group_write(rgrp, DEFR2, DEFR2_CODE | DEFR2_DEFE2G); ++ rcar_du_group_write(rgrp, DEFR3, DEFR3_CODE | DEFR3_DEFE3); ++ rcar_du_group_write(rgrp, DEFR4, DEFR4_CODE); ++ rcar_du_group_write(rgrp, DEFR5, DEFR5_CODE | DEFR5_DEFE5); ++ ++ /* Use DS1PR and DS2PR to configure planes priorities and connects the ++ * superposition 0 to DU0 pins. DU1 pins will be configured dynamically. ++ */ ++ rcar_du_group_write(rgrp, DORCR, DORCR_PG1D_DS1 | DORCR_DPRS); ++} ++ ++/* ++ * rcar_du_group_get - Acquire a reference to the DU channels group ++ * ++ * Acquiring the first reference setups core registers. A reference must be held ++ * before accessing any hardware registers. ++ * ++ * This function must be called with the DRM mode_config lock held. ++ * ++ * Return 0 in case of success or a negative error code otherwise. ++ */ ++int rcar_du_group_get(struct rcar_du_group *rgrp) ++{ ++ if (rgrp->use_count) ++ goto done; ++ ++ rcar_du_group_setup(rgrp); ++ ++done: ++ rgrp->use_count++; ++ return 0; ++} ++ ++/* ++ * rcar_du_group_put - Release a reference to the DU ++ * ++ * This function must be called with the DRM mode_config lock held. ++ */ ++void rcar_du_group_put(struct rcar_du_group *rgrp) ++{ ++ --rgrp->use_count; ++} ++ ++static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start) ++{ ++ rcar_du_group_write(rgrp, DSYSR, ++ (rcar_du_group_read(rgrp, DSYSR) & ~(DSYSR_DRES | DSYSR_DEN)) | ++ (start ? DSYSR_DEN : DSYSR_DRES)); ++} ++ ++void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start) ++{ ++ /* Many of the configuration bits are only updated when the display ++ * reset (DRES) bit in DSYSR is set to 1, disabling *both* CRTCs. Some ++ * of those bits could be pre-configured, but others (especially the ++ * bits related to plane assignment to display timing controllers) need ++ * to be modified at runtime. ++ * ++ * Restart the display controller if a start is requested. Sorry for the ++ * flicker. It should be possible to move most of the "DRES-update" bits ++ * setup to driver initialization time and minimize the number of cases ++ * when the display controller will have to be restarted. ++ */ ++ if (start) { ++ if (rgrp->used_crtcs++ != 0) ++ __rcar_du_group_start_stop(rgrp, false); ++ __rcar_du_group_start_stop(rgrp, true); ++ } else { ++ if (--rgrp->used_crtcs == 0) ++ __rcar_du_group_start_stop(rgrp, false); ++ } ++} ++ ++void rcar_du_group_restart(struct rcar_du_group *rgrp) ++{ ++ __rcar_du_group_start_stop(rgrp, false); ++ __rcar_du_group_start_stop(rgrp, true); ++} +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.h b/drivers/gpu/drm/rcar-du/rcar_du_group.h +new file mode 100644 +index 000000000000..748331bbb8fe +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_group.h +@@ -0,0 +1,47 @@ ++/* ++ * rcar_du_group.c -- R-Car Display Unit Planes and CRTCs Group ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#ifndef __RCAR_DU_GROUP_H__ ++#define __RCAR_DU_GROUP_H__ ++ ++#include "rcar_du_plane.h" ++ ++struct rcar_du_device; ++ ++/* ++ * struct rcar_du_group - CRTCs and planes group ++ * @dev: the DU device ++ * @mmio_offset: registers offset in the device memory map ++ * @index: group index ++ * @use_count: number of users of the group (rcar_du_group_(get|put)) ++ * @used_crtcs: number of CRTCs currently in use ++ * @planes: planes handled by the group ++ */ ++struct rcar_du_group { ++ struct rcar_du_device *dev; ++ unsigned int mmio_offset; ++ unsigned int index; ++ ++ unsigned int use_count; ++ unsigned int used_crtcs; ++ ++ struct rcar_du_planes planes; ++}; ++ ++int rcar_du_group_get(struct rcar_du_group *rgrp); ++void rcar_du_group_put(struct rcar_du_group *rgrp); ++void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start); ++void rcar_du_group_restart(struct rcar_du_group *rgrp); ++ ++ ++#endif /* __RCAR_DU_GROUP_H__ */ +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +index a1343fbde57a..c32e0f9d4823 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +@@ -174,17 +174,20 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + rcdu->ddev->mode_config.max_height = 2047; + rcdu->ddev->mode_config.funcs = &rcar_du_mode_config_funcs; + +- ret = rcar_du_planes_init(rcdu); ++ rcdu->group.dev = rcdu; ++ rcdu->group.index = 0; ++ rcdu->group.used_crtcs = 0; ++ ++ ret = rcar_du_planes_init(&rcdu->group); + if (ret < 0) + return ret; + + for (i = 0; i < ARRAY_SIZE(rcdu->crtcs); ++i) { +- ret = rcar_du_crtc_create(rcdu, i); ++ ret = rcar_du_crtc_create(&rcdu->group, i); + if (ret < 0) + return ret; + } + +- rcdu->used_crtcs = 0; + rcdu->num_crtcs = i; + + for (i = 0; i < rcdu->pdata->num_encoders; ++i) { +@@ -215,7 +218,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + encoder->possible_clones = 1 << 0; + } + +- ret = rcar_du_planes_register(rcdu); ++ ret = rcar_du_planes_register(&rcdu->group); + if (ret < 0) + return ret; + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c +index 29f21477ef0e..1e9cf7c92f8e 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c +@@ -36,71 +36,73 @@ static inline struct rcar_du_plane *to_rcar_plane(struct drm_plane *plane) + return container_of(plane, struct rcar_du_kms_plane, plane)->hwplane; + } + +-static u32 rcar_du_plane_read(struct rcar_du_device *rcdu, ++static u32 rcar_du_plane_read(struct rcar_du_group *rgrp, + unsigned int index, u32 reg) + { +- return rcar_du_read(rcdu, index * PLANE_OFF + reg); ++ return rcar_du_read(rgrp->dev, ++ rgrp->mmio_offset + index * PLANE_OFF + reg); + } + +-static void rcar_du_plane_write(struct rcar_du_device *rcdu, ++static void rcar_du_plane_write(struct rcar_du_group *rgrp, + unsigned int index, u32 reg, u32 data) + { +- rcar_du_write(rcdu, index * PLANE_OFF + reg, data); ++ rcar_du_write(rgrp->dev, rgrp->mmio_offset + index * PLANE_OFF + reg, ++ data); + } + + int rcar_du_plane_reserve(struct rcar_du_plane *plane, + const struct rcar_du_format_info *format) + { +- struct rcar_du_device *rcdu = plane->dev; ++ struct rcar_du_group *rgrp = plane->group; + unsigned int i; + int ret = -EBUSY; + +- mutex_lock(&rcdu->planes.lock); ++ mutex_lock(&rgrp->planes.lock); + +- for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) { +- if (!(rcdu->planes.free & (1 << i))) ++ for (i = 0; i < ARRAY_SIZE(rgrp->planes.planes); ++i) { ++ if (!(rgrp->planes.free & (1 << i))) + continue; + + if (format->planes == 1 || +- rcdu->planes.free & (1 << ((i + 1) % 8))) ++ rgrp->planes.free & (1 << ((i + 1) % 8))) + break; + } + +- if (i == ARRAY_SIZE(rcdu->planes.planes)) ++ if (i == ARRAY_SIZE(rgrp->planes.planes)) + goto done; + +- rcdu->planes.free &= ~(1 << i); ++ rgrp->planes.free &= ~(1 << i); + if (format->planes == 2) +- rcdu->planes.free &= ~(1 << ((i + 1) % 8)); ++ rgrp->planes.free &= ~(1 << ((i + 1) % 8)); + + plane->hwindex = i; + + ret = 0; + + done: +- mutex_unlock(&rcdu->planes.lock); ++ mutex_unlock(&rgrp->planes.lock); + return ret; + } + + void rcar_du_plane_release(struct rcar_du_plane *plane) + { +- struct rcar_du_device *rcdu = plane->dev; ++ struct rcar_du_group *rgrp = plane->group; + + if (plane->hwindex == -1) + return; + +- mutex_lock(&rcdu->planes.lock); +- rcdu->planes.free |= 1 << plane->hwindex; ++ mutex_lock(&rgrp->planes.lock); ++ rgrp->planes.free |= 1 << plane->hwindex; + if (plane->format->planes == 2) +- rcdu->planes.free |= 1 << ((plane->hwindex + 1) % 8); +- mutex_unlock(&rcdu->planes.lock); ++ rgrp->planes.free |= 1 << ((plane->hwindex + 1) % 8); ++ mutex_unlock(&rgrp->planes.lock); + + plane->hwindex = -1; + } + + void rcar_du_plane_update_base(struct rcar_du_plane *plane) + { +- struct rcar_du_device *rcdu = plane->dev; ++ struct rcar_du_group *rgrp = plane->group; + unsigned int index = plane->hwindex; + + /* The Y position is expressed in raster line units and must be doubled +@@ -111,18 +113,18 @@ void rcar_du_plane_update_base(struct rcar_du_plane *plane) + * Similarly, for the second plane, NV12 and NV21 formats seem to + * require a halved Y position value. + */ +- rcar_du_plane_write(rcdu, index, PnSPXR, plane->src_x); +- rcar_du_plane_write(rcdu, index, PnSPYR, plane->src_y * ++ rcar_du_plane_write(rgrp, index, PnSPXR, plane->src_x); ++ rcar_du_plane_write(rgrp, index, PnSPYR, plane->src_y * + (plane->format->bpp == 32 ? 2 : 1)); +- rcar_du_plane_write(rcdu, index, PnDSA0R, plane->dma[0]); ++ rcar_du_plane_write(rgrp, index, PnDSA0R, plane->dma[0]); + + if (plane->format->planes == 2) { + index = (index + 1) % 8; + +- rcar_du_plane_write(rcdu, index, PnSPXR, plane->src_x); +- rcar_du_plane_write(rcdu, index, PnSPYR, plane->src_y * ++ rcar_du_plane_write(rgrp, index, PnSPXR, plane->src_x); ++ rcar_du_plane_write(rgrp, index, PnSPYR, plane->src_y * + (plane->format->bpp == 16 ? 2 : 1) / 2); +- rcar_du_plane_write(rcdu, index, PnDSA0R, plane->dma[1]); ++ rcar_du_plane_write(rgrp, index, PnDSA0R, plane->dma[1]); + } + } + +@@ -143,7 +145,7 @@ void rcar_du_plane_compute_base(struct rcar_du_plane *plane, + static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane, + unsigned int index) + { +- struct rcar_du_device *rcdu = plane->dev; ++ struct rcar_du_group *rgrp = plane->group; + u32 colorkey; + u32 pnmr; + +@@ -157,9 +159,9 @@ static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane, + * enable alpha-blending regardless of the X bit value. + */ + if (plane->format->fourcc != DRM_FORMAT_XRGB1555) +- rcar_du_plane_write(rcdu, index, PnALPHAR, PnALPHAR_ABIT_0); ++ rcar_du_plane_write(rgrp, index, PnALPHAR, PnALPHAR_ABIT_0); + else +- rcar_du_plane_write(rcdu, index, PnALPHAR, ++ rcar_du_plane_write(rgrp, index, PnALPHAR, + PnALPHAR_ABIT_X | plane->alpha); + + pnmr = PnMR_BM_MD | plane->format->pnmr; +@@ -175,14 +177,14 @@ static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane, + if (plane->format->fourcc == DRM_FORMAT_YUYV) + pnmr |= PnMR_YCDF_YUYV; + +- rcar_du_plane_write(rcdu, index, PnMR, pnmr); ++ rcar_du_plane_write(rgrp, index, PnMR, pnmr); + + switch (plane->format->fourcc) { + case DRM_FORMAT_RGB565: + colorkey = ((plane->colorkey & 0xf80000) >> 8) + | ((plane->colorkey & 0x00fc00) >> 5) + | ((plane->colorkey & 0x0000f8) >> 3); +- rcar_du_plane_write(rcdu, index, PnTC2R, colorkey); ++ rcar_du_plane_write(rgrp, index, PnTC2R, colorkey); + break; + + case DRM_FORMAT_ARGB1555: +@@ -190,12 +192,12 @@ static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane, + colorkey = ((plane->colorkey & 0xf80000) >> 9) + | ((plane->colorkey & 0x00f800) >> 6) + | ((plane->colorkey & 0x0000f8) >> 3); +- rcar_du_plane_write(rcdu, index, PnTC2R, colorkey); ++ rcar_du_plane_write(rgrp, index, PnTC2R, colorkey); + break; + + case DRM_FORMAT_XRGB8888: + case DRM_FORMAT_ARGB8888: +- rcar_du_plane_write(rcdu, index, PnTC3R, ++ rcar_du_plane_write(rgrp, index, PnTC3R, + PnTC3R_CODE | (plane->colorkey & 0xffffff)); + break; + } +@@ -204,7 +206,7 @@ static void rcar_du_plane_setup_mode(struct rcar_du_plane *plane, + static void __rcar_du_plane_setup(struct rcar_du_plane *plane, + unsigned int index) + { +- struct rcar_du_device *rcdu = plane->dev; ++ struct rcar_du_group *rgrp = plane->group; + u32 ddcr2 = PnDDCR2_CODE; + u32 ddcr4; + u32 mwr; +@@ -214,7 +216,7 @@ static void __rcar_du_plane_setup(struct rcar_du_plane *plane, + * The data format is selected by the DDDF field in PnMR and the EDF + * field in DDCR4. + */ +- ddcr4 = rcar_du_plane_read(rcdu, index, PnDDCR4); ++ ddcr4 = rcar_du_plane_read(rgrp, index, PnDDCR4); + ddcr4 &= ~PnDDCR4_EDF_MASK; + ddcr4 |= plane->format->edf | PnDDCR4_CODE; + +@@ -235,8 +237,8 @@ static void __rcar_du_plane_setup(struct rcar_du_plane *plane, + } + } + +- rcar_du_plane_write(rcdu, index, PnDDCR2, ddcr2); +- rcar_du_plane_write(rcdu, index, PnDDCR4, ddcr4); ++ rcar_du_plane_write(rgrp, index, PnDDCR2, ddcr2); ++ rcar_du_plane_write(rgrp, index, PnDDCR4, ddcr4); + + /* Memory pitch (expressed in pixels) */ + if (plane->format->planes == 2) +@@ -244,19 +246,19 @@ static void __rcar_du_plane_setup(struct rcar_du_plane *plane, + else + mwr = plane->pitch * 8 / plane->format->bpp; + +- rcar_du_plane_write(rcdu, index, PnMWR, mwr); ++ rcar_du_plane_write(rgrp, index, PnMWR, mwr); + + /* Destination position and size */ +- rcar_du_plane_write(rcdu, index, PnDSXR, plane->width); +- rcar_du_plane_write(rcdu, index, PnDSYR, plane->height); +- rcar_du_plane_write(rcdu, index, PnDPXR, plane->dst_x); +- rcar_du_plane_write(rcdu, index, PnDPYR, plane->dst_y); ++ rcar_du_plane_write(rgrp, index, PnDSXR, plane->width); ++ rcar_du_plane_write(rgrp, index, PnDSYR, plane->height); ++ rcar_du_plane_write(rgrp, index, PnDPXR, plane->dst_x); ++ rcar_du_plane_write(rgrp, index, PnDPYR, plane->dst_y); + + /* Wrap-around and blinking, disabled */ +- rcar_du_plane_write(rcdu, index, PnWASPR, 0); +- rcar_du_plane_write(rcdu, index, PnWAMWR, 4095); +- rcar_du_plane_write(rcdu, index, PnBTR, 0); +- rcar_du_plane_write(rcdu, index, PnMLR, 0); ++ rcar_du_plane_write(rgrp, index, PnWASPR, 0); ++ rcar_du_plane_write(rgrp, index, PnWAMWR, 4095); ++ rcar_du_plane_write(rgrp, index, PnBTR, 0); ++ rcar_du_plane_write(rgrp, index, PnMLR, 0); + } + + void rcar_du_plane_setup(struct rcar_du_plane *plane) +@@ -276,7 +278,7 @@ rcar_du_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, + uint32_t src_w, uint32_t src_h) + { + struct rcar_du_plane *rplane = to_rcar_plane(plane); +- struct rcar_du_device *rcdu = plane->dev->dev_private; ++ struct rcar_du_device *rcdu = rplane->group->dev; + const struct rcar_du_format_info *format; + unsigned int nplanes; + int ret; +@@ -319,26 +321,25 @@ rcar_du_plane_update(struct drm_plane *plane, struct drm_crtc *crtc, + rcar_du_plane_compute_base(rplane, fb); + rcar_du_plane_setup(rplane); + +- mutex_lock(&rcdu->planes.lock); ++ mutex_lock(&rplane->group->planes.lock); + rplane->enabled = true; + rcar_du_crtc_update_planes(rplane->crtc); +- mutex_unlock(&rcdu->planes.lock); ++ mutex_unlock(&rplane->group->planes.lock); + + return 0; + } + + static int rcar_du_plane_disable(struct drm_plane *plane) + { +- struct rcar_du_device *rcdu = plane->dev->dev_private; + struct rcar_du_plane *rplane = to_rcar_plane(plane); + + if (!rplane->enabled) + return 0; + +- mutex_lock(&rcdu->planes.lock); ++ mutex_lock(&rplane->group->planes.lock); + rplane->enabled = false; + rcar_du_crtc_update_planes(rplane->crtc); +- mutex_unlock(&rcdu->planes.lock); ++ mutex_unlock(&rplane->group->planes.lock); + + rcar_du_plane_release(rplane); + +@@ -380,9 +381,7 @@ static void rcar_du_plane_set_colorkey(struct rcar_du_plane *plane, + static void rcar_du_plane_set_zpos(struct rcar_du_plane *plane, + unsigned int zpos) + { +- struct rcar_du_device *rcdu = plane->dev; +- +- mutex_lock(&rcdu->planes.lock); ++ mutex_lock(&plane->group->planes.lock); + if (plane->zpos == zpos) + goto done; + +@@ -393,21 +392,21 @@ static void rcar_du_plane_set_zpos(struct rcar_du_plane *plane, + rcar_du_crtc_update_planes(plane->crtc); + + done: +- mutex_unlock(&rcdu->planes.lock); ++ mutex_unlock(&plane->group->planes.lock); + } + + static int rcar_du_plane_set_property(struct drm_plane *plane, + struct drm_property *property, + uint64_t value) + { +- struct rcar_du_device *rcdu = plane->dev->dev_private; + struct rcar_du_plane *rplane = to_rcar_plane(plane); ++ struct rcar_du_group *rgrp = rplane->group; + +- if (property == rcdu->planes.alpha) ++ if (property == rgrp->planes.alpha) + rcar_du_plane_set_alpha(rplane, value); +- else if (property == rcdu->planes.colorkey) ++ else if (property == rgrp->planes.colorkey) + rcar_du_plane_set_colorkey(rplane, value); +- else if (property == rcdu->planes.zpos) ++ else if (property == rgrp->planes.zpos) + rcar_du_plane_set_zpos(rplane, value); + else + return -EINVAL; +@@ -435,37 +434,39 @@ static const uint32_t formats[] = { + DRM_FORMAT_NV16, + }; + +-int rcar_du_planes_init(struct rcar_du_device *rcdu) ++int rcar_du_planes_init(struct rcar_du_group *rgrp) + { ++ struct rcar_du_planes *planes = &rgrp->planes; ++ struct rcar_du_device *rcdu = rgrp->dev; + unsigned int i; + +- mutex_init(&rcdu->planes.lock); +- rcdu->planes.free = 0xff; ++ mutex_init(&planes->lock); ++ planes->free = 0xff; + +- rcdu->planes.alpha = ++ planes->alpha = + drm_property_create_range(rcdu->ddev, 0, "alpha", 0, 255); +- if (rcdu->planes.alpha == NULL) ++ if (planes->alpha == NULL) + return -ENOMEM; + + /* The color key is expressed as an RGB888 triplet stored in a 32-bit + * integer in XRGB8888 format. Bit 24 is used as a flag to disable (0) + * or enable source color keying (1). + */ +- rcdu->planes.colorkey = ++ planes->colorkey = + drm_property_create_range(rcdu->ddev, 0, "colorkey", + 0, 0x01ffffff); +- if (rcdu->planes.colorkey == NULL) ++ if (planes->colorkey == NULL) + return -ENOMEM; + +- rcdu->planes.zpos = ++ planes->zpos = + drm_property_create_range(rcdu->ddev, 0, "zpos", 1, 7); +- if (rcdu->planes.zpos == NULL) ++ if (planes->zpos == NULL) + return -ENOMEM; + +- for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) { +- struct rcar_du_plane *plane = &rcdu->planes.planes[i]; ++ for (i = 0; i < ARRAY_SIZE(planes->planes); ++i) { ++ struct rcar_du_plane *plane = &planes->planes[i]; + +- plane->dev = rcdu; ++ plane->group = rgrp; + plane->hwindex = -1; + plane->alpha = 255; + plane->colorkey = RCAR_DU_COLORKEY_NONE; +@@ -475,8 +476,10 @@ int rcar_du_planes_init(struct rcar_du_device *rcdu) + return 0; + } + +-int rcar_du_planes_register(struct rcar_du_device *rcdu) ++int rcar_du_planes_register(struct rcar_du_group *rgrp) + { ++ struct rcar_du_planes *planes = &rgrp->planes; ++ struct rcar_du_device *rcdu = rgrp->dev; + unsigned int i; + int ret; + +@@ -487,7 +490,7 @@ int rcar_du_planes_register(struct rcar_du_device *rcdu) + if (plane == NULL) + return -ENOMEM; + +- plane->hwplane = &rcdu->planes.planes[i + 2]; ++ plane->hwplane = &planes->planes[i + 2]; + plane->hwplane->zpos = 1; + + ret = drm_plane_init(rcdu->ddev, &plane->plane, +@@ -498,12 +501,12 @@ int rcar_du_planes_register(struct rcar_du_device *rcdu) + return ret; + + drm_object_attach_property(&plane->plane.base, +- rcdu->planes.alpha, 255); ++ planes->alpha, 255); + drm_object_attach_property(&plane->plane.base, +- rcdu->planes.colorkey, ++ planes->colorkey, + RCAR_DU_COLORKEY_NONE); + drm_object_attach_property(&plane->plane.base, +- rcdu->planes.zpos, 1); ++ planes->zpos, 1); + } + + return 0; +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.h b/drivers/gpu/drm/rcar-du/rcar_du_plane.h +index bcf6f76f56a0..f94f9ce84998 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.h +@@ -19,8 +19,8 @@ + #include <drm/drmP.h> + #include <drm/drm_crtc.h> + +-struct rcar_du_device; + struct rcar_du_format_info; ++struct rcar_du_group; + + /* The RCAR DU has 8 hardware planes, shared between KMS planes and CRTCs. As + * using KMS planes requires at least one of the CRTCs being enabled, no more +@@ -33,7 +33,7 @@ struct rcar_du_format_info; + #define RCAR_DU_NUM_SW_PLANES 9 + + struct rcar_du_plane { +- struct rcar_du_device *dev; ++ struct rcar_du_group *group; + struct drm_crtc *crtc; + + bool enabled; +@@ -67,8 +67,8 @@ struct rcar_du_planes { + struct drm_property *zpos; + }; + +-int rcar_du_planes_init(struct rcar_du_device *rcdu); +-int rcar_du_planes_register(struct rcar_du_device *rcdu); ++int rcar_du_planes_init(struct rcar_du_group *rgrp); ++int rcar_du_planes_register(struct rcar_du_group *rgrp); + + void rcar_du_plane_setup(struct rcar_du_plane *plane); + void rcar_du_plane_update_base(struct rcar_du_plane *plane); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0024-drm-rcar-du-Use-dynamic-number-of-CRTCs-instead-of-C.patch b/patches.renesas/0024-drm-rcar-du-Use-dynamic-number-of-CRTCs-instead-of-C.patch new file mode 100644 index 00000000000000..e92aa173898274 --- /dev/null +++ b/patches.renesas/0024-drm-rcar-du-Use-dynamic-number-of-CRTCs-instead-of-C.patch @@ -0,0 +1,46 @@ +From e85b0c6345fe455c7b84e2dffc38c21704e82e3d Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Sun, 16 Jun 2013 22:22:23 +0200 +Subject: drm/rcar-du: Use dynamic number of CRTCs instead of CRTCs array size + +The rcar_du_device structure contains a field that stores the number of +CRTCs, use it instead of the CRTCs array size. This prepares the driver +to support a variable number of CRTCs. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 990d07a5a9582f14b4d6d13cde5311d6c694096a) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 2 +- + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +index 8600b2b6aea4..5a68024c8de4 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -105,7 +105,7 @@ static void rcar_du_preclose(struct drm_device *dev, struct drm_file *file) + struct rcar_du_device *rcdu = dev->dev_private; + unsigned int i; + +- for (i = 0; i < ARRAY_SIZE(rcdu->crtcs); ++i) ++ for (i = 0; i < rcdu->num_crtcs; ++i) + rcar_du_crtc_cancel_page_flip(&rcdu->crtcs[i], file); + } + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +index c32e0f9d4823..845bcb384863 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +@@ -197,7 +197,7 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + if (pdata->type == RCAR_DU_ENCODER_UNUSED) + continue; + +- if (pdata->output >= ARRAY_SIZE(rcdu->crtcs)) { ++ if (pdata->output >= rcdu->num_crtcs) { + dev_warn(rcdu->dev, + "encoder %u references unexisting output %u, skipping\n", + i, pdata->output); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0025-drm-rcar-du-Remove-register-definitions-for-the-seco.patch b/patches.renesas/0025-drm-rcar-du-Remove-register-definitions-for-the-seco.patch new file mode 100644 index 00000000000000..46ab645532993f --- /dev/null +++ b/patches.renesas/0025-drm-rcar-du-Remove-register-definitions-for-the-seco.patch @@ -0,0 +1,91 @@ +From cbbb8db454d1a21d30f53eb74d0539519679260a Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Sun, 16 Jun 2013 23:48:10 +0200 +Subject: drm/rcar-du: Remove register definitions for the second channel + +Channels are accessed through a global channel memory offset, there's no +need to define register addresses for the second channel. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 660bab56aa048c904a65ce6a8fc2eca2235eec6f) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_regs.h | 9 --------- + 1 file changed, 9 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_regs.h b/drivers/gpu/drm/rcar-du/rcar_du_regs.h +index 3aba27ffc065..195ed7e1756e 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_regs.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_regs.h +@@ -20,7 +20,6 @@ + */ + + #define DSYSR 0x00000 /* display 1 */ +-#define D2SYSR 0x30000 /* display 2 */ + #define DSYSR_ILTS (1 << 29) + #define DSYSR_DSEC (1 << 20) + #define DSYSR_IUPD (1 << 16) +@@ -35,7 +34,6 @@ + #define DSYSR_SCM_INT_VIDEO (3 << 4) + + #define DSMR 0x00004 +-#define D2SMR 0x30004 + #define DSMR_VSPM (1 << 28) + #define DSMR_ODPM (1 << 27) + #define DSMR_DIPM_DISP (0 << 25) +@@ -60,7 +58,6 @@ + #define DSMR_CSY_MASK (3 << 6) + + #define DSSR 0x00008 +-#define D2SSR 0x30008 + #define DSSR_VC1FB_DSA0 (0 << 30) + #define DSSR_VC1FB_DSA1 (1 << 30) + #define DSSR_VC1FB_DSA2 (2 << 30) +@@ -80,7 +77,6 @@ + #define DSSR_ADC(n) (1 << ((n)-1)) + + #define DSRCR 0x0000c +-#define D2SRCR 0x3000c + #define DSRCR_TVCL (1 << 15) + #define DSRCR_FRCL (1 << 14) + #define DSRCR_VBCL (1 << 11) +@@ -90,7 +86,6 @@ + #define DSRCR_MASK 0x0000cbff + + #define DIER 0x00010 +-#define D2IER 0x30010 + #define DIER_TVE (1 << 15) + #define DIER_FRE (1 << 14) + #define DIER_VBE (1 << 11) +@@ -114,7 +109,6 @@ + #define DPPR_BPP32 (DPPR_BPP32_P1 | DPPR_BPP32_P2) /* plane1 & 2 */ + + #define DEFR 0x00020 +-#define D2EFR 0x30020 + #define DEFR_CODE (0x7773 << 16) + #define DEFR_EXSL (1 << 12) + #define DEFR_EXVL (1 << 11) +@@ -137,12 +131,10 @@ + #define DCPCR_DCE (1 << 0) + + #define DEFR2 0x00034 +-#define D2EFR2 0x30034 + #define DEFR2_CODE (0x7775 << 16) + #define DEFR2_DEFE2G (1 << 0) + + #define DEFR3 0x00038 +-#define D2EFR3 0x30038 + #define DEFR3_CODE (0x7776 << 16) + #define DEFR3_EVDA (1 << 14) + #define DEFR3_EVDM_1 (1 << 12) +@@ -153,7 +145,6 @@ + #define DEFR3_DEFE3 (1 << 0) + + #define DEFR4 0x0003c +-#define D2EFR4 0x3003c + #define DEFR4_CODE (0x7777 << 16) + #define DEFR4_LRUO (1 << 5) + #define DEFR4_SPCE (1 << 4) +-- +1.8.5.rc3 + diff --git a/patches.renesas/0026-drm-rcar-du-Move-output-routing-configuration-to-gro.patch b/patches.renesas/0026-drm-rcar-du-Move-output-routing-configuration-to-gro.patch new file mode 100644 index 00000000000000..505a820ae2bcb3 --- /dev/null +++ b/patches.renesas/0026-drm-rcar-du-Move-output-routing-configuration-to-gro.patch @@ -0,0 +1,98 @@ +From 18d43412c08badd2c1df0411c19bd45a1967fd35 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Mon, 17 Jun 2013 00:11:05 +0200 +Subject: drm/rcar-du: Move output routing configuration to group + +Output routing is configured in group registers, move the corresponding +code from rcar_du_crtc.c to rcar_du_group.c. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 2fd22dba23e3847651bffa1d9cc37acea05cc351) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 21 +-------------------- + drivers/gpu/drm/rcar-du/rcar_du_group.c | 19 +++++++++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_group.h | 2 +- + 3 files changed, 21 insertions(+), 21 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +index 7784a3ba7854..6a2b9590bb74 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +@@ -130,25 +130,6 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) + rcar_du_crtc_write(rcrtc, DEWR, mode->hdisplay); + } + +-static void rcar_du_crtc_set_routing(struct rcar_du_crtc *rcrtc) +-{ +- struct rcar_du_device *rcdu = rcrtc->group->dev; +- u32 dorcr = rcar_du_read(rcdu, DORCR); +- +- dorcr &= ~(DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_MASK); +- +- /* Set the DU1 pins sources. Select CRTC 0 if explicitly requested and +- * CRTC 1 in all other cases to avoid cloning CRTC 0 to DU0 and DU1 by +- * default. +- */ +- if (rcrtc->outputs & (1 << 1) && rcrtc->index == 0) +- dorcr |= DORCR_PG2D_DS1; +- else +- dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2; +- +- rcar_du_write(rcdu, DORCR, dorcr); +-} +- + void rcar_du_crtc_route_output(struct drm_crtc *crtc, unsigned int output) + { + struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); +@@ -245,7 +226,7 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc) + + /* Configure display timings and output routing */ + rcar_du_crtc_set_display_timing(rcrtc); +- rcar_du_crtc_set_routing(rcrtc); ++ rcar_du_group_set_routing(rcrtc->group); + + mutex_lock(&rcrtc->group->planes.lock); + rcrtc->plane->enabled = true; +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c +index 625b9f446965..7e754515bba8 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c +@@ -125,3 +125,22 @@ void rcar_du_group_restart(struct rcar_du_group *rgrp) + __rcar_du_group_start_stop(rgrp, false); + __rcar_du_group_start_stop(rgrp, true); + } ++ ++void rcar_du_group_set_routing(struct rcar_du_group *rgrp) ++{ ++ struct rcar_du_crtc *crtc0 = &rgrp->dev->crtcs[rgrp->index * 2]; ++ u32 dorcr = rcar_du_group_read(rgrp, DORCR); ++ ++ dorcr &= ~(DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_MASK); ++ ++ /* Set the DU1 pins sources. Select CRTC 0 if explicitly requested and ++ * CRTC 1 in all other cases to avoid cloning CRTC 0 to DU0 and DU1 by ++ * default. ++ */ ++ if (crtc0->outputs & (1 << 1)) ++ dorcr |= DORCR_PG2D_DS1; ++ else ++ dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2; ++ ++ rcar_du_group_write(rgrp, DORCR, dorcr); ++} +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.h b/drivers/gpu/drm/rcar-du/rcar_du_group.h +index 748331bbb8fe..180c739812c9 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_group.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_group.h +@@ -42,6 +42,6 @@ int rcar_du_group_get(struct rcar_du_group *rgrp); + void rcar_du_group_put(struct rcar_du_group *rgrp); + void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start); + void rcar_du_group_restart(struct rcar_du_group *rgrp); +- ++void rcar_du_group_set_routing(struct rcar_du_group *rgrp); + + #endif /* __RCAR_DU_GROUP_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0027-drm-rcar-du-Add-support-for-the-R8A7790-DU.patch b/patches.renesas/0027-drm-rcar-du-Add-support-for-the-R8A7790-DU.patch new file mode 100644 index 00000000000000..a7aca449d21569 --- /dev/null +++ b/patches.renesas/0027-drm-rcar-du-Add-support-for-the-R8A7790-DU.patch @@ -0,0 +1,124 @@ +From cb7342965a26939902f88f7af3d0fcec8954336f Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Fri, 14 Jun 2013 14:16:35 +0200 +Subject: drm/rcar-du: Add support for the R8A7790 DU + +The DU revision in the R8A7790 SoC uses one IRQ and clock per CRTC. Add +a corresponding entry in the module platform ID table. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit ef2d84bec6a02c4536cab1e0a8f13792ad86a7bc) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 5 +++ + drivers/gpu/drm/rcar-du/rcar_du_regs.h | 66 ++++++++++++++++++++++++++++++++-- + 2 files changed, 68 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +index 5a68024c8de4..dc4c07e02d8c 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -215,8 +215,13 @@ static const struct rcar_du_device_info rcar_du_r8a7779_info = { + .features = 0, + }; + ++static const struct rcar_du_device_info rcar_du_r8a7790_info = { ++ .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK, ++}; ++ + static const struct platform_device_id rcar_du_id_table[] = { + { "rcar-du-r8a7779", (kernel_ulong_t)&rcar_du_r8a7779_info }, ++ { "rcar-du-r8a7790", (kernel_ulong_t)&rcar_du_r8a7790_info }, + { } + }; + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_regs.h b/drivers/gpu/drm/rcar-du/rcar_du_regs.h +index 195ed7e1756e..f62a9f36041a 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_regs.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_regs.h +@@ -196,6 +196,68 @@ + #define DEFR6_DEFAULT (DEFR6_CODE | DEFR6_TCNE2) + + /* ----------------------------------------------------------------------------- ++ * R8A7790-only Control Registers ++ */ ++ ++#define DD1SSR 0x20008 ++#define DD1SSR_TVR (1 << 15) ++#define DD1SSR_FRM (1 << 14) ++#define DD1SSR_BUF (1 << 12) ++#define DD1SSR_VBK (1 << 11) ++#define DD1SSR_RINT (1 << 9) ++#define DD1SSR_HBK (1 << 8) ++#define DD1SSR_ADC(n) (1 << ((n)-1)) ++ ++#define DD1SRCR 0x2000c ++#define DD1SRCR_TVR (1 << 15) ++#define DD1SRCR_FRM (1 << 14) ++#define DD1SRCR_BUF (1 << 12) ++#define DD1SRCR_VBK (1 << 11) ++#define DD1SRCR_RINT (1 << 9) ++#define DD1SRCR_HBK (1 << 8) ++#define DD1SRCR_ADC(n) (1 << ((n)-1)) ++ ++#define DD1IER 0x20010 ++#define DD1IER_TVR (1 << 15) ++#define DD1IER_FRM (1 << 14) ++#define DD1IER_BUF (1 << 12) ++#define DD1IER_VBK (1 << 11) ++#define DD1IER_RINT (1 << 9) ++#define DD1IER_HBK (1 << 8) ++#define DD1IER_ADC(n) (1 << ((n)-1)) ++ ++#define DEFR8 0x20020 ++#define DEFR8_CODE (0x7790 << 16) ++#define DEFR8_VSCS (1 << 6) ++#define DEFR8_DRGBS_DU(n) ((n) << 4) ++#define DEFR8_DRGBS_MASK (3 << 4) ++#define DEFR8_DEFE8 (1 << 0) ++ ++#define DOFLR 0x20024 ++#define DOFLR_CODE (0x7790 << 16) ++#define DOFLR_HSYCFL1 (1 << 13) ++#define DOFLR_VSYCFL1 (1 << 12) ++#define DOFLR_ODDFL1 (1 << 11) ++#define DOFLR_DISPFL1 (1 << 10) ++#define DOFLR_CDEFL1 (1 << 9) ++#define DOFLR_RGBFL1 (1 << 8) ++#define DOFLR_HSYCFL0 (1 << 5) ++#define DOFLR_VSYCFL0 (1 << 4) ++#define DOFLR_ODDFL0 (1 << 3) ++#define DOFLR_DISPFL0 (1 << 2) ++#define DOFLR_CDEFL0 (1 << 1) ++#define DOFLR_RGBFL0 (1 << 0) ++ ++#define DIDSR 0x20028 ++#define DIDSR_CODE (0x7790 << 16) ++#define DIDSR_LCDS_DCLKIN(n) (0 << (8 + (n) * 2)) ++#define DIDSR_LCDS_LVDS0(n) (2 << (8 + (n) * 2)) ++#define DIDSR_LCDS_LVDS1(n) (3 << (8 + (n) * 2)) ++#define DIDSR_LCDS_MASK(n) (3 << (8 + (n) * 2)) ++#define DIDSR_PCDS_CLK(n, clk) (clk << ((n) * 2)) ++#define DIDSR_PCDS_MASK(n) (3 << ((n) * 2)) ++ ++/* ----------------------------------------------------------------------------- + * Display Timing Generation Registers + */ + +@@ -364,12 +426,10 @@ + * Display Capture Registers + */ + ++#define DCMR 0x0c100 + #define DCMWR 0x0c104 +-#define DC2MWR 0x0c204 + #define DCSAR 0x0c120 +-#define DC2SAR 0x0c220 + #define DCMLR 0x0c150 +-#define DC2MLR 0x0c250 + + /* ----------------------------------------------------------------------------- + * Color Palette Registers +-- +1.8.5.rc3 + diff --git a/patches.renesas/0028-drm-rcar-du-Fix-buffer-pitch-alignment-for-R8A7790-D.patch b/patches.renesas/0028-drm-rcar-du-Fix-buffer-pitch-alignment-for-R8A7790-D.patch new file mode 100644 index 00000000000000..05218bb71a8e1e --- /dev/null +++ b/patches.renesas/0028-drm-rcar-du-Fix-buffer-pitch-alignment-for-R8A7790-D.patch @@ -0,0 +1,91 @@ +From 7e426b11a2c7fdfe41cb7301e1a22975cd48216e Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Fri, 14 Jun 2013 20:52:52 +0200 +Subject: drm/rcar-du: Fix buffer pitch alignment for R8A7790 DU + +The R8A7790 DU seems to require a 128 bytes pitch alignment, even though +the documentation only mentions a 16 pixels alignement as for the +R8A7779 DU. Make this configurable through a device flag. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 9e2d2de9e8107643ba50debc475fc966d3f77364) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 2 +- + drivers/gpu/drm/rcar-du/rcar_du_drv.h | 1 + + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 17 ++++++++++++++--- + 3 files changed, 16 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +index dc4c07e02d8c..ce0de4d1260a 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -216,7 +216,7 @@ static const struct rcar_du_device_info rcar_du_r8a7779_info = { + }; + + static const struct rcar_du_device_info rcar_du_r8a7790_info = { +- .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK, ++ .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | RCAR_DU_FEATURE_ALIGN_128B, + }; + + static const struct platform_device_id rcar_du_id_table[] = { +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +index 5b57a2f9b52a..072e28e09484 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +@@ -26,6 +26,7 @@ struct drm_device; + struct rcar_du_device; + + #define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK (1 << 0) /* Per-CRTC IRQ and clock */ ++#define RCAR_DU_FEATURE_ALIGN_128B (1 << 1) /* Align pitches to 128 bytes */ + + /* + * struct rcar_du_device_info - DU model-specific information +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +index 845bcb384863..418d902bc88d 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +@@ -111,11 +111,18 @@ const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc) + int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev, + struct drm_mode_create_dumb *args) + { ++ struct rcar_du_device *rcdu = dev->dev_private; + unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8); + unsigned int align; + +- /* The pitch must be aligned to a 16 pixels boundary. */ +- align = 16 * args->bpp / 8; ++ /* The R8A7779 DU requires a 16 pixels pitch alignment as documented, ++ * but the R8A7790 DU seems to require a 128 bytes pitch alignment. ++ */ ++ if (rcar_du_has(rcdu, RCAR_DU_FEATURE_ALIGN_128B)) ++ align = 128; ++ else ++ align = 16 * args->bpp / 8; ++ + args->pitch = roundup(max(args->pitch, min_pitch), align); + + return drm_gem_cma_dumb_create(file, dev, args); +@@ -125,6 +132,7 @@ static struct drm_framebuffer * + rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv, + struct drm_mode_fb_cmd2 *mode_cmd) + { ++ struct rcar_du_device *rcdu = dev->dev_private; + const struct rcar_du_format_info *format; + unsigned int align; + +@@ -135,7 +143,10 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv, + return ERR_PTR(-EINVAL); + } + +- align = 16 * format->bpp / 8; ++ if (rcar_du_has(rcdu, RCAR_DU_FEATURE_ALIGN_128B)) ++ align = 128; ++ else ++ align = 16 * format->bpp / 8; + + if (mode_cmd->pitches[0] & (align - 1) || + mode_cmd->pitches[0] >= 8192) { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0029-drm-rcar-du-Add-support-for-multiple-groups.patch b/patches.renesas/0029-drm-rcar-du-Add-support-for-multiple-groups.patch new file mode 100644 index 00000000000000..1447964ca222f8 --- /dev/null +++ b/patches.renesas/0029-drm-rcar-du-Add-support-for-multiple-groups.patch @@ -0,0 +1,307 @@ +From ee77ac8b69f422b13783b62a62651e3a0b59fad1 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Mon, 17 Jun 2013 00:29:25 +0200 +Subject: drm/rcar-du: Add support for multiple groups + +The R8A7790 DU has 3 CRTCs, split in two groups. Support them. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit a5f0ef593c4a130f5f5cd4cd506af946e32dd509) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 25 ++++++++++--------- + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 2 ++ + drivers/gpu/drm/rcar-du/rcar_du_drv.h | 6 +++-- + drivers/gpu/drm/rcar-du/rcar_du_group.c | 4 +-- + drivers/gpu/drm/rcar-du/rcar_du_group.h | 3 +++ + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 43 ++++++++++++++++++++++++--------- + drivers/gpu/drm/rcar-du/rcar_du_plane.c | 6 +++-- + drivers/gpu/drm/rcar-du/rcar_du_regs.h | 4 ++- + 8 files changed, 63 insertions(+), 30 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +index 6a2b9590bb74..a340224e08e6 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +@@ -91,7 +91,6 @@ static void rcar_du_crtc_put(struct rcar_du_crtc *rcrtc) + static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) + { + const struct drm_display_mode *mode = &rcrtc->crtc.mode; +- struct rcar_du_device *rcdu = rcrtc->group->dev; + unsigned long clk; + u32 value; + u32 div; +@@ -101,9 +100,9 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) + div = DIV_ROUND_CLOSEST(clk, mode->clock * 1000); + div = clamp(div, 1U, 64U) - 1; + +- rcar_du_write(rcdu, rcrtc->index ? ESCR2 : ESCR, +- ESCR_DCLKSEL_CLKS | div); +- rcar_du_write(rcdu, rcrtc->index ? OTAR2 : OTAR, 0); ++ rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? ESCR2 : ESCR, ++ ESCR_DCLKSEL_CLKS | div); ++ rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? OTAR2 : OTAR, 0); + + /* Signal polarities */ + value = ((mode->flags & DRM_MODE_FLAG_PVSYNC) ? 0 : DSMR_VSL) +@@ -143,7 +142,6 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc, unsigned int output) + void rcar_du_crtc_update_planes(struct drm_crtc *crtc) + { + struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); +- struct rcar_du_device *rcdu = rcrtc->group->dev; + struct rcar_du_plane *planes[RCAR_DU_NUM_HW_PLANES]; + unsigned int num_planes = 0; + unsigned int prio = 0; +@@ -189,8 +187,8 @@ void rcar_du_crtc_update_planes(struct drm_crtc *crtc) + /* Select display timing and dot clock generator 2 for planes associated + * with superposition controller 2. + */ +- if (rcrtc->index) { +- u32 value = rcar_du_read(rcdu, DPTSR); ++ if (rcrtc->index % 2) { ++ u32 value = rcar_du_group_read(rcrtc->group, DPTSR); + + /* The DPTSR register is updated when the display controller is + * stopped. We thus need to restart the DU. Once again, sorry +@@ -200,13 +198,14 @@ void rcar_du_crtc_update_planes(struct drm_crtc *crtc) + * occur only if we need to break the pre-association. + */ + if (value != dptsr) { +- rcar_du_write(rcdu, DPTSR, dptsr); ++ rcar_du_group_write(rcrtc->group, DPTSR, dptsr); + if (rcrtc->group->used_crtcs) + rcar_du_group_restart(rcrtc->group); + } + } + +- rcar_du_write(rcdu, rcrtc->index ? DS2PR : DS1PR, dspr); ++ rcar_du_group_write(rcrtc->group, rcrtc->index % 2 ? DS2PR : DS1PR, ++ dspr); + } + + static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc) +@@ -528,6 +527,10 @@ static const struct drm_crtc_funcs crtc_funcs = { + + int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) + { ++ static const unsigned int mmio_offsets[] = { ++ DU0_REG_OFFSET, DU1_REG_OFFSET, DU2_REG_OFFSET ++ }; ++ + struct rcar_du_device *rcdu = rgrp->dev; + struct platform_device *pdev = to_platform_device(rcdu->dev); + struct rcar_du_crtc *rcrtc = &rcdu->crtcs[index]; +@@ -553,10 +556,10 @@ int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index) + } + + rcrtc->group = rgrp; +- rcrtc->mmio_offset = index ? DISP2_REG_OFFSET : 0; ++ rcrtc->mmio_offset = mmio_offsets[index]; + rcrtc->index = index; + rcrtc->dpms = DRM_MODE_DPMS_OFF; +- rcrtc->plane = &rgrp->planes.planes[index]; ++ rcrtc->plane = &rgrp->planes.planes[index % 2]; + + rcrtc->plane->crtc = crtc; + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +index ce0de4d1260a..f3a2b52d6853 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -213,10 +213,12 @@ static int rcar_du_remove(struct platform_device *pdev) + + static const struct rcar_du_device_info rcar_du_r8a7779_info = { + .features = 0, ++ .num_crtcs = 2, + }; + + static const struct rcar_du_device_info rcar_du_r8a7790_info = { + .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | RCAR_DU_FEATURE_ALIGN_128B, ++ .num_crtcs = 3, + }; + + static const struct platform_device_id rcar_du_id_table[] = { +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +index 072e28e09484..160e5eb8f29d 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +@@ -31,9 +31,11 @@ struct rcar_du_device; + /* + * struct rcar_du_device_info - DU model-specific information + * @features: device features (RCAR_DU_FEATURE_*) ++ * @num_crtcs: total number of CRTCs + */ + struct rcar_du_device_info { + unsigned int features; ++ unsigned int num_crtcs; + }; + + struct rcar_du_device { +@@ -45,10 +47,10 @@ struct rcar_du_device { + + struct drm_device *ddev; + +- struct rcar_du_crtc crtcs[2]; ++ struct rcar_du_crtc crtcs[3]; + unsigned int num_crtcs; + +- struct rcar_du_group group; ++ struct rcar_du_group groups[2]; + }; + + static inline bool rcar_du_has(struct rcar_du_device *rcdu, +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c +index 7e754515bba8..0eb106efffc9 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c +@@ -33,12 +33,12 @@ + #include "rcar_du_group.h" + #include "rcar_du_regs.h" + +-static u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg) ++u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg) + { + return rcar_du_read(rgrp->dev, rgrp->mmio_offset + reg); + } + +-static void rcar_du_group_write(struct rcar_du_group *rgrp, u32 reg, u32 data) ++void rcar_du_group_write(struct rcar_du_group *rgrp, u32 reg, u32 data) + { + rcar_du_write(rgrp->dev, rgrp->mmio_offset + reg, data); + } +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.h b/drivers/gpu/drm/rcar-du/rcar_du_group.h +index 180c739812c9..4487e83fb2c1 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_group.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_group.h +@@ -38,6 +38,9 @@ struct rcar_du_group { + struct rcar_du_planes planes; + }; + ++u32 rcar_du_group_read(struct rcar_du_group *rgrp, u32 reg); ++void rcar_du_group_write(struct rcar_du_group *rgrp, u32 reg, u32 data); ++ + int rcar_du_group_get(struct rcar_du_group *rgrp); + void rcar_du_group_put(struct rcar_du_group *rgrp); + void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start); +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +index 418d902bc88d..816963ca1626 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +@@ -172,8 +172,13 @@ static const struct drm_mode_config_funcs rcar_du_mode_config_funcs = { + + int rcar_du_modeset_init(struct rcar_du_device *rcdu) + { ++ static const unsigned int mmio_offsets[] = { ++ DU0_REG_OFFSET, DU2_REG_OFFSET ++ }; ++ + struct drm_device *dev = rcdu->ddev; + struct drm_encoder *encoder; ++ unsigned int num_groups; + unsigned int i; + int ret; + +@@ -185,22 +190,33 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + rcdu->ddev->mode_config.max_height = 2047; + rcdu->ddev->mode_config.funcs = &rcar_du_mode_config_funcs; + +- rcdu->group.dev = rcdu; +- rcdu->group.index = 0; +- rcdu->group.used_crtcs = 0; ++ rcdu->num_crtcs = rcdu->info->num_crtcs; ++ ++ /* Initialize the groups. */ ++ num_groups = DIV_ROUND_UP(rcdu->num_crtcs, 2); ++ ++ for (i = 0; i < num_groups; ++i) { ++ struct rcar_du_group *rgrp = &rcdu->groups[i]; + +- ret = rcar_du_planes_init(&rcdu->group); +- if (ret < 0) +- return ret; ++ rgrp->dev = rcdu; ++ rgrp->mmio_offset = mmio_offsets[i]; ++ rgrp->index = i; + +- for (i = 0; i < ARRAY_SIZE(rcdu->crtcs); ++i) { +- ret = rcar_du_crtc_create(&rcdu->group, i); ++ ret = rcar_du_planes_init(rgrp); + if (ret < 0) + return ret; + } + +- rcdu->num_crtcs = i; ++ /* Create the CRTCs. */ ++ for (i = 0; i < rcdu->num_crtcs; ++i) { ++ struct rcar_du_group *rgrp = &rcdu->groups[i / 2]; ++ ++ ret = rcar_du_crtc_create(rgrp, i); ++ if (ret < 0) ++ return ret; ++ } + ++ /* Initialize the encoders. */ + for (i = 0; i < rcdu->pdata->num_encoders; ++i) { + const struct rcar_du_encoder_data *pdata = + &rcdu->pdata->encoders[i]; +@@ -229,9 +245,12 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + encoder->possible_clones = 1 << 0; + } + +- ret = rcar_du_planes_register(&rcdu->group); +- if (ret < 0) +- return ret; ++ /* Now that the CRTCs have been initialized register the planes. */ ++ for (i = 0; i < num_groups; ++i) { ++ ret = rcar_du_planes_register(&rcdu->groups[i]); ++ if (ret < 0) ++ return ret; ++ } + + drm_kms_helper_poll_init(rcdu->ddev); + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c +index 1e9cf7c92f8e..53000644733f 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c +@@ -480,9 +480,12 @@ int rcar_du_planes_register(struct rcar_du_group *rgrp) + { + struct rcar_du_planes *planes = &rgrp->planes; + struct rcar_du_device *rcdu = rgrp->dev; ++ unsigned int crtcs; + unsigned int i; + int ret; + ++ crtcs = ((1 << rcdu->num_crtcs) - 1) & (3 << (2 * rgrp->index)); ++ + for (i = 0; i < RCAR_DU_NUM_KMS_PLANES; ++i) { + struct rcar_du_kms_plane *plane; + +@@ -493,8 +496,7 @@ int rcar_du_planes_register(struct rcar_du_group *rgrp) + plane->hwplane = &planes->planes[i + 2]; + plane->hwplane->zpos = 1; + +- ret = drm_plane_init(rcdu->ddev, &plane->plane, +- (1 << rcdu->num_crtcs) - 1, ++ ret = drm_plane_init(rcdu->ddev, &plane->plane, crtcs, + &rcar_du_plane_funcs, formats, + ARRAY_SIZE(formats), false); + if (ret < 0) +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_regs.h b/drivers/gpu/drm/rcar-du/rcar_du_regs.h +index f62a9f36041a..73f7347f740b 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_regs.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_regs.h +@@ -13,7 +13,9 @@ + #ifndef __RCAR_DU_REGS_H__ + #define __RCAR_DU_REGS_H__ + +-#define DISP2_REG_OFFSET 0x30000 ++#define DU0_REG_OFFSET 0x00000 ++#define DU1_REG_OFFSET 0x30000 ++#define DU2_REG_OFFSET 0x40000 + + /* ----------------------------------------------------------------------------- + * Display Control Registers +-- +1.8.5.rc3 + diff --git a/patches.renesas/0030-drm-rcar-du-Add-support-for-DEFR8-register.patch b/patches.renesas/0030-drm-rcar-du-Add-support-for-DEFR8-register.patch new file mode 100644 index 00000000000000..36d7119edda5bd --- /dev/null +++ b/patches.renesas/0030-drm-rcar-du-Add-support-for-DEFR8-register.patch @@ -0,0 +1,58 @@ +From 8625c92ccc2945bd89f2677b8ff599914f46b8fa Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Sat, 15 Jun 2013 02:40:57 +0200 +Subject: drm/rcar-du: Add support for DEFR8 register + +The R8A7790 DU has a new extended function control register. Support it. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 38b62fb3808e6b57dbd7728e897e4f7674d1c998) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 3 ++- + drivers/gpu/drm/rcar-du/rcar_du_drv.h | 1 + + drivers/gpu/drm/rcar-du/rcar_du_group.c | 2 ++ + 3 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +index f3a2b52d6853..f99aa52dc65c 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -217,7 +217,8 @@ static const struct rcar_du_device_info rcar_du_r8a7779_info = { + }; + + static const struct rcar_du_device_info rcar_du_r8a7790_info = { +- .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | RCAR_DU_FEATURE_ALIGN_128B, ++ .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | RCAR_DU_FEATURE_ALIGN_128B ++ | RCAR_DU_FEATURE_DEFR8, + .num_crtcs = 3, + }; + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +index 160e5eb8f29d..70c335f51136 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +@@ -27,6 +27,7 @@ struct rcar_du_device; + + #define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK (1 << 0) /* Per-CRTC IRQ and clock */ + #define RCAR_DU_FEATURE_ALIGN_128B (1 << 1) /* Align pitches to 128 bytes */ ++#define RCAR_DU_FEATURE_DEFR8 (1 << 2) /* Has DEFR8 register */ + + /* + * struct rcar_du_device_info - DU model-specific information +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c +index 0eb106efffc9..f3ba0ca845e2 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c +@@ -51,6 +51,8 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp) + rcar_du_group_write(rgrp, DEFR3, DEFR3_CODE | DEFR3_DEFE3); + rcar_du_group_write(rgrp, DEFR4, DEFR4_CODE); + rcar_du_group_write(rgrp, DEFR5, DEFR5_CODE | DEFR5_DEFE5); ++ if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_DEFR8)) ++ rcar_du_group_write(rgrp, DEFR8, DEFR8_CODE | DEFR8_DEFE8); + + /* Use DS1PR and DS2PR to configure planes priorities and connects the + * superposition 0 to DU0 pins. DU1 pins will be configured dynamically. +-- +1.8.5.rc3 + diff --git a/patches.renesas/0031-drm-rcar-du-Rework-output-routing-support.patch b/patches.renesas/0031-drm-rcar-du-Rework-output-routing-support.patch new file mode 100644 index 00000000000000..3624ebe6e5e29a --- /dev/null +++ b/patches.renesas/0031-drm-rcar-du-Rework-output-routing-support.patch @@ -0,0 +1,345 @@ +From e82761b1b05648e17962223884fb0e6c8cd40221 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Mon, 17 Jun 2013 03:13:11 +0200 +Subject: drm/rcar-du: Rework output routing support + +Split the output routing specification between SoC-internal data, +specified in the rcar_du_device_info structure, and board data, passed +through platform data. + +The DU has 5 possible outputs (DPAD0/1, LVDS0/1, TCON). SoC-internal +output routing data specify which output are valid, which CRTCs can be +connected to the valid outputs, and the type of in-SoC encoder for the +output. + +Platform data then specifies external encoders and the output they are +connected to. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit ef67a902e946ad1ef51040cf287a45cc4714e2b5) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 6 ++++-- + drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 4 +++- + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 30 ++++++++++++++++++++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_drv.h | 16 ++++++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 26 +++++++++++++++++++++----- + drivers/gpu/drm/rcar-du/rcar_du_encoder.h | 5 +++-- + drivers/gpu/drm/rcar-du/rcar_du_group.c | 8 ++++---- + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 17 +++++++++++------ + include/linux/platform_data/rcar-du.h | 17 +++++++++++++++-- + 9 files changed, 107 insertions(+), 22 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +index a340224e08e6..680606ef11d8 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +@@ -129,14 +129,16 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) + rcar_du_crtc_write(rcrtc, DEWR, mode->hdisplay); + } + +-void rcar_du_crtc_route_output(struct drm_crtc *crtc, unsigned int output) ++void rcar_du_crtc_route_output(struct drm_crtc *crtc, ++ enum rcar_du_output output) + { + struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); ++ struct rcar_du_device *rcdu = rcrtc->group->dev; + + /* Store the route from the CRTC output to the DU output. The DU will be + * configured when starting the CRTC. + */ +- rcrtc->outputs |= 1 << output; ++ rcrtc->outputs |= BIT(output); + } + + void rcar_du_crtc_update_planes(struct drm_crtc *crtc) +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +index 542a7feceb20..39a983d13afb 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +@@ -15,6 +15,7 @@ + #define __RCAR_DU_CRTC_H__ + + #include <linux/mutex.h> ++#include <linux/platform_data/rcar-du.h> + + #include <drm/drmP.h> + #include <drm/drm_crtc.h> +@@ -45,7 +46,8 @@ void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc, + void rcar_du_crtc_suspend(struct rcar_du_crtc *rcrtc); + void rcar_du_crtc_resume(struct rcar_du_crtc *rcrtc); + +-void rcar_du_crtc_route_output(struct drm_crtc *crtc, unsigned int output); ++void rcar_du_crtc_route_output(struct drm_crtc *crtc, ++ enum rcar_du_output output); + void rcar_du_crtc_update_planes(struct drm_crtc *crtc); + + #endif /* __RCAR_DU_CRTC_H__ */ +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +index f99aa52dc65c..983bc5912588 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -214,12 +214,42 @@ static int rcar_du_remove(struct platform_device *pdev) + static const struct rcar_du_device_info rcar_du_r8a7779_info = { + .features = 0, + .num_crtcs = 2, ++ .routes = { ++ /* R8A7779 has two RGB outputs and one (currently unsupported) ++ * TCON output. ++ */ ++ [RCAR_DU_OUTPUT_DPAD0] = { ++ .possible_crtcs = BIT(0), ++ .encoder_type = DRM_MODE_ENCODER_NONE, ++ }, ++ [RCAR_DU_OUTPUT_DPAD1] = { ++ .possible_crtcs = BIT(1) | BIT(0), ++ .encoder_type = DRM_MODE_ENCODER_NONE, ++ }, ++ }, + }; + + static const struct rcar_du_device_info rcar_du_r8a7790_info = { + .features = RCAR_DU_FEATURE_CRTC_IRQ_CLOCK | RCAR_DU_FEATURE_ALIGN_128B + | RCAR_DU_FEATURE_DEFR8, + .num_crtcs = 3, ++ .routes = { ++ /* R8A7790 has one RGB output, two LVDS outputs and one ++ * (currently unsupported) TCON output. ++ */ ++ [RCAR_DU_OUTPUT_DPAD0] = { ++ .possible_crtcs = BIT(2) | BIT(1) | BIT(0), ++ .encoder_type = DRM_MODE_ENCODER_NONE, ++ }, ++ [RCAR_DU_OUTPUT_LVDS0] = { ++ .possible_crtcs = BIT(0), ++ .encoder_type = DRM_MODE_ENCODER_LVDS, ++ }, ++ [RCAR_DU_OUTPUT_LVDS1] = { ++ .possible_crtcs = BIT(2) | BIT(1), ++ .encoder_type = DRM_MODE_ENCODER_LVDS, ++ }, ++ }, + }; + + static const struct platform_device_id rcar_du_id_table[] = { +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +index 70c335f51136..d5243f493903 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +@@ -30,13 +30,29 @@ struct rcar_du_device; + #define RCAR_DU_FEATURE_DEFR8 (1 << 2) /* Has DEFR8 register */ + + /* ++ * struct rcar_du_output_routing - Output routing specification ++ * @possible_crtcs: bitmask of possible CRTCs for the output ++ * @encoder_type: DRM type of the internal encoder associated with the output ++ * ++ * The DU has 5 possible outputs (DPAD0/1, LVDS0/1, TCON). Output routing data ++ * specify the valid SoC outputs, which CRTCs can drive the output, and the type ++ * of in-SoC encoder for the output. ++ */ ++struct rcar_du_output_routing { ++ unsigned int possible_crtcs; ++ unsigned int encoder_type; ++}; ++ ++/* + * struct rcar_du_device_info - DU model-specific information + * @features: device features (RCAR_DU_FEATURE_*) + * @num_crtcs: total number of CRTCs ++ * @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*) + */ + struct rcar_du_device_info { + unsigned int features; + unsigned int num_crtcs; ++ struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX]; + }; + + struct rcar_du_device { +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +index 0d0375c7ee44..2aac28d21f87 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +@@ -115,10 +115,12 @@ static const struct drm_encoder_funcs encoder_funcs = { + }; + + int rcar_du_encoder_init(struct rcar_du_device *rcdu, +- enum rcar_du_encoder_type type, unsigned int output, ++ enum rcar_du_encoder_type type, ++ enum rcar_du_output output, + const struct rcar_du_encoder_data *data) + { + struct rcar_du_encoder *renc; ++ unsigned int encoder_type; + int ret; + + renc = devm_kzalloc(rcdu->dev, sizeof(*renc), GFP_KERNEL); +@@ -127,19 +129,33 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, + + renc->output = output; + ++ switch (type) { ++ case RCAR_DU_ENCODER_VGA: ++ encoder_type = DRM_MODE_ENCODER_DAC; ++ break; ++ case RCAR_DU_ENCODER_LVDS: ++ encoder_type = DRM_MODE_ENCODER_LVDS; ++ break; ++ case RCAR_DU_ENCODER_NONE: ++ default: ++ /* No external encoder, use the internal encoder type. */ ++ encoder_type = rcdu->info->routes[output].encoder_type; ++ break; ++ } ++ + ret = drm_encoder_init(rcdu->ddev, &renc->encoder, &encoder_funcs, +- type); ++ encoder_type); + if (ret < 0) + return ret; + + drm_encoder_helper_add(&renc->encoder, &encoder_helper_funcs); + +- switch (type) { +- case RCAR_DU_ENCODER_LVDS: ++ switch (encoder_type) { ++ case DRM_MODE_ENCODER_LVDS: + return rcar_du_lvds_connector_init(rcdu, renc, + &data->connector.lvds.panel); + +- case RCAR_DU_ENCODER_VGA: ++ case DRM_MODE_ENCODER_DAC: + return rcar_du_vga_connector_init(rcdu, renc); + + default: +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h +index 08cde1293892..2310416ea21f 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h +@@ -22,7 +22,7 @@ struct rcar_du_device; + + struct rcar_du_encoder { + struct drm_encoder encoder; +- unsigned int output; ++ enum rcar_du_output output; + }; + + #define to_rcar_encoder(e) \ +@@ -40,7 +40,8 @@ struct drm_encoder * + rcar_du_connector_best_encoder(struct drm_connector *connector); + + int rcar_du_encoder_init(struct rcar_du_device *rcdu, +- enum rcar_du_encoder_type type, unsigned int output, ++ enum rcar_du_encoder_type type, ++ enum rcar_du_output output, + const struct rcar_du_encoder_data *data); + + #endif /* __RCAR_DU_ENCODER_H__ */ +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c +index f3ba0ca845e2..9df6fb635c96 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c +@@ -135,11 +135,11 @@ void rcar_du_group_set_routing(struct rcar_du_group *rgrp) + + dorcr &= ~(DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_MASK); + +- /* Set the DU1 pins sources. Select CRTC 0 if explicitly requested and +- * CRTC 1 in all other cases to avoid cloning CRTC 0 to DU0 and DU1 by +- * default. ++ /* Set the DPAD1 pins sources. Select CRTC 0 if explicitly requested and ++ * CRTC 1 in all other cases to avoid cloning CRTC 0 to DPAD0 and DPAD1 ++ * by default. + */ +- if (crtc0->outputs & (1 << 1)) ++ if (crtc0->outputs & BIT(RCAR_DU_OUTPUT_DPAD1)) + dorcr |= DORCR_PG2D_DS1; + else + dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2; +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +index 816963ca1626..2b92e68a09f0 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +@@ -220,11 +220,14 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + for (i = 0; i < rcdu->pdata->num_encoders; ++i) { + const struct rcar_du_encoder_data *pdata = + &rcdu->pdata->encoders[i]; ++ const struct rcar_du_output_routing *route = ++ &rcdu->info->routes[pdata->output]; + + if (pdata->type == RCAR_DU_ENCODER_UNUSED) + continue; + +- if (pdata->output >= rcdu->num_crtcs) { ++ if (pdata->output >= RCAR_DU_OUTPUT_MAX || ++ route->possible_crtcs == 0) { + dev_warn(rcdu->dev, + "encoder %u references unexisting output %u, skipping\n", + i, pdata->output); +@@ -234,15 +237,17 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + rcar_du_encoder_init(rcdu, pdata->type, pdata->output, pdata); + } + +- /* Set the possible CRTCs and possible clones. All encoders can be +- * driven by the CRTC associated with the output they're connected to, +- * as well as by CRTC 0. ++ /* Set the possible CRTCs and possible clones. There's always at least ++ * one way for all encoders to clone each other, set all bits in the ++ * possible clones field. + */ + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { + struct rcar_du_encoder *renc = to_rcar_encoder(encoder); ++ const struct rcar_du_output_routing *route = ++ &rcdu->info->routes[renc->output]; + +- encoder->possible_crtcs = (1 << 0) | (1 << renc->output); +- encoder->possible_clones = 1 << 0; ++ encoder->possible_crtcs = route->possible_crtcs; ++ encoder->possible_clones = (1 << rcdu->pdata->num_encoders) - 1; + } + + /* Now that the CRTCs have been initialized register the planes. */ +diff --git a/include/linux/platform_data/rcar-du.h b/include/linux/platform_data/rcar-du.h +index 64cd8635e6e6..1a2e9901a22e 100644 +--- a/include/linux/platform_data/rcar-du.h ++++ b/include/linux/platform_data/rcar-du.h +@@ -16,8 +16,18 @@ + + #include <drm/drm_mode.h> + ++enum rcar_du_output { ++ RCAR_DU_OUTPUT_DPAD0, ++ RCAR_DU_OUTPUT_DPAD1, ++ RCAR_DU_OUTPUT_LVDS0, ++ RCAR_DU_OUTPUT_LVDS1, ++ RCAR_DU_OUTPUT_TCON, ++ RCAR_DU_OUTPUT_MAX, ++}; ++ + enum rcar_du_encoder_type { + RCAR_DU_ENCODER_UNUSED = 0, ++ RCAR_DU_ENCODER_NONE, + RCAR_DU_ENCODER_VGA, + RCAR_DU_ENCODER_LVDS, + }; +@@ -39,13 +49,16 @@ struct rcar_du_connector_vga_data { + /* + * struct rcar_du_encoder_data - Encoder platform data + * @type: the encoder type (RCAR_DU_ENCODER_*) +- * @output: the DU output the connector is connected to ++ * @output: the DU output the connector is connected to (RCAR_DU_OUTPUT_*) + * @connector.lvds: platform data for LVDS connectors + * @connector.vga: platform data for VGA connectors ++ * ++ * Encoder platform data describes an on-board encoder, its associated DU SoC ++ * output, and the connector. + */ + struct rcar_du_encoder_data { + enum rcar_du_encoder_type type; +- unsigned int output; ++ enum rcar_du_output output; + + union { + struct rcar_du_connector_lvds_data lvds; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0032-drm-rcar-du-Configure-RGB-output-routing-to-DPAD0.patch b/patches.renesas/0032-drm-rcar-du-Configure-RGB-output-routing-to-DPAD0.patch new file mode 100644 index 00000000000000..548e37caa4885b --- /dev/null +++ b/patches.renesas/0032-drm-rcar-du-Configure-RGB-output-routing-to-DPAD0.patch @@ -0,0 +1,144 @@ +From 23143c3fa488cc3f2645e75e1c0610a6623a1a5b Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Mon, 17 Jun 2013 03:20:08 +0200 +Subject: drm/rcar-du: Configure RGB output routing to DPAD0 + +The R8A7790 DU variant has a single RGB output called DPAD0 that can be +fed with the output of DU0, DU1 or DU2. Making the routing configurable. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 7cbc05cb518304b746bea00bc7c0b005217bcaf7) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 5 ++++ + drivers/gpu/drm/rcar-du/rcar_du_drv.h | 2 ++ + drivers/gpu/drm/rcar-du/rcar_du_group.c | 45 ++++++++++++++++++++++++++++++--- + drivers/gpu/drm/rcar-du/rcar_du_group.h | 2 +- + 4 files changed, 50 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +index 680606ef11d8..245800ddd1a8 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +@@ -139,6 +139,11 @@ void rcar_du_crtc_route_output(struct drm_crtc *crtc, + * configured when starting the CRTC. + */ + rcrtc->outputs |= BIT(output); ++ ++ /* Store RGB routing to DPAD0 for R8A7790. */ ++ if (rcar_du_has(rcdu, RCAR_DU_FEATURE_DEFR8) && ++ output == RCAR_DU_OUTPUT_DPAD0) ++ rcdu->dpad0_source = rcrtc->index; + } + + void rcar_du_crtc_update_planes(struct drm_crtc *crtc) +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +index d5243f493903..924f5e08f060 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +@@ -68,6 +68,8 @@ struct rcar_du_device { + unsigned int num_crtcs; + + struct rcar_du_group groups[2]; ++ ++ unsigned int dpad0_source; + }; + + static inline bool rcar_du_has(struct rcar_du_device *rcdu, +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.c b/drivers/gpu/drm/rcar-du/rcar_du_group.c +index 9df6fb635c96..eb53cd97e8c6 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_group.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_group.c +@@ -27,6 +27,7 @@ + * counterpart in the DU documentation, that models those semi-global resources. + */ + ++#include <linux/clk.h> + #include <linux/io.h> + + #include "rcar_du_drv.h" +@@ -43,6 +44,22 @@ void rcar_du_group_write(struct rcar_du_group *rgrp, u32 reg, u32 data) + rcar_du_write(rgrp->dev, rgrp->mmio_offset + reg, data); + } + ++static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp) ++{ ++ u32 defr8 = DEFR8_CODE | DEFR8_DEFE8; ++ ++ if (!rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_DEFR8)) ++ return; ++ ++ /* The DEFR8 register for the first group also controls RGB output ++ * routing to DPAD0 ++ */ ++ if (rgrp->index == 0) ++ defr8 |= DEFR8_DRGBS_DU(rgrp->dev->dpad0_source); ++ ++ rcar_du_group_write(rgrp, DEFR8, defr8); ++} ++ + static void rcar_du_group_setup(struct rcar_du_group *rgrp) + { + /* Enable extended features */ +@@ -51,8 +68,8 @@ static void rcar_du_group_setup(struct rcar_du_group *rgrp) + rcar_du_group_write(rgrp, DEFR3, DEFR3_CODE | DEFR3_DEFE3); + rcar_du_group_write(rgrp, DEFR4, DEFR4_CODE); + rcar_du_group_write(rgrp, DEFR5, DEFR5_CODE | DEFR5_DEFE5); +- if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_DEFR8)) +- rcar_du_group_write(rgrp, DEFR8, DEFR8_CODE | DEFR8_DEFE8); ++ ++ rcar_du_group_setup_defr8(rgrp); + + /* Use DS1PR and DS2PR to configure planes priorities and connects the + * superposition 0 to DU0 pins. DU1 pins will be configured dynamically. +@@ -128,7 +145,27 @@ void rcar_du_group_restart(struct rcar_du_group *rgrp) + __rcar_du_group_start_stop(rgrp, true); + } + +-void rcar_du_group_set_routing(struct rcar_du_group *rgrp) ++static int rcar_du_set_dpad0_routing(struct rcar_du_device *rcdu) ++{ ++ int ret; ++ ++ /* RGB output routing to DPAD0 is configured in the DEFR8 register of ++ * the first group. As this function can be called with the DU0 and DU1 ++ * CRTCs disabled, we need to enable the first group clock before ++ * accessing the register. ++ */ ++ ret = clk_prepare_enable(rcdu->crtcs[0].clock); ++ if (ret < 0) ++ return ret; ++ ++ rcar_du_group_setup_defr8(&rcdu->groups[0]); ++ ++ clk_disable_unprepare(rcdu->crtcs[0].clock); ++ ++ return 0; ++} ++ ++int rcar_du_group_set_routing(struct rcar_du_group *rgrp) + { + struct rcar_du_crtc *crtc0 = &rgrp->dev->crtcs[rgrp->index * 2]; + u32 dorcr = rcar_du_group_read(rgrp, DORCR); +@@ -145,4 +182,6 @@ void rcar_du_group_set_routing(struct rcar_du_group *rgrp) + dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2; + + rcar_du_group_write(rgrp, DORCR, dorcr); ++ ++ return rcar_du_set_dpad0_routing(rgrp->dev); + } +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_group.h b/drivers/gpu/drm/rcar-du/rcar_du_group.h +index 4487e83fb2c1..5025930972ec 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_group.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_group.h +@@ -45,6 +45,6 @@ int rcar_du_group_get(struct rcar_du_group *rgrp); + void rcar_du_group_put(struct rcar_du_group *rgrp); + void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start); + void rcar_du_group_restart(struct rcar_du_group *rgrp); +-void rcar_du_group_set_routing(struct rcar_du_group *rgrp); ++int rcar_du_group_set_routing(struct rcar_du_group *rgrp); + + #endif /* __RCAR_DU_GROUP_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0033-drm-rcar-du-Add-internal-LVDS-encoder-support.patch b/patches.renesas/0033-drm-rcar-du-Add-internal-LVDS-encoder-support.patch new file mode 100644 index 00000000000000..0ca6ab22c2abb0 --- /dev/null +++ b/patches.renesas/0033-drm-rcar-du-Add-internal-LVDS-encoder-support.patch @@ -0,0 +1,600 @@ +From 677d7e6700c3e1db5ab7a4051b33c36aa3fa4ac9 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Mon, 17 Jun 2013 13:48:27 +0200 +Subject: drm/rcar-du: Add internal LVDS encoder support + +The R8A7790 includes two internal LVDS encoders. Support them in the DU +driver. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 90374b5c25c9f04895c52a1e7a2468ee8dac525b) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/Kconfig | 7 ++ + drivers/gpu/drm/rcar-du/Makefile | 4 +- + drivers/gpu/drm/rcar-du/rcar_du_crtc.c | 2 - + drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 2 + + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 2 + + drivers/gpu/drm/rcar-du/rcar_du_drv.h | 4 + + drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 38 ++++++ + drivers/gpu/drm/rcar-du/rcar_du_encoder.h | 2 + + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 5 + + drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c | 196 ++++++++++++++++++++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h | 46 +++++++ + drivers/gpu/drm/rcar-du/rcar_lvds_regs.h | 69 +++++++++++ + 12 files changed, 374 insertions(+), 3 deletions(-) + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c + create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h + create mode 100644 drivers/gpu/drm/rcar-du/rcar_lvds_regs.h + +diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig +index 72887df8dd76..c590cd9dca0b 100644 +--- a/drivers/gpu/drm/rcar-du/Kconfig ++++ b/drivers/gpu/drm/rcar-du/Kconfig +@@ -7,3 +7,10 @@ config DRM_RCAR_DU + help + Choose this option if you have an R-Car chipset. + If M is selected the module will be called rcar-du-drm. ++ ++config DRM_RCAR_LVDS ++ bool "R-Car DU LVDS Encoder Support" ++ depends on DRM_RCAR_DU ++ help ++ Enable support the R-Car Display Unit embedded LVDS encoders ++ (currently only on R8A7790). +diff --git a/drivers/gpu/drm/rcar-du/Makefile b/drivers/gpu/drm/rcar-du/Makefile +index b9b5e666fbba..12b8d4477835 100644 +--- a/drivers/gpu/drm/rcar-du/Makefile ++++ b/drivers/gpu/drm/rcar-du/Makefile +@@ -7,4 +7,6 @@ rcar-du-drm-y := rcar_du_crtc.o \ + rcar_du_plane.o \ + rcar_du_vgacon.o + +-obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o ++rcar-du-drm-$(CONFIG_DRM_RCAR_LVDS) += rcar_du_lvdsenc.o ++ ++obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +index 245800ddd1a8..33df7a583143 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c +@@ -26,8 +26,6 @@ + #include "rcar_du_plane.h" + #include "rcar_du_regs.h" + +-#define to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, crtc) +- + static u32 rcar_du_crtc_read(struct rcar_du_crtc *rcrtc, u32 reg) + { + struct rcar_du_device *rcdu = rcrtc->group->dev; +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +index 39a983d13afb..43e7575c700c 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.h +@@ -39,6 +39,8 @@ struct rcar_du_crtc { + struct rcar_du_plane *plane; + }; + ++#define to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, crtc) ++ + int rcar_du_crtc_create(struct rcar_du_group *rgrp, unsigned int index); + void rcar_du_crtc_enable_vblank(struct rcar_du_crtc *rcrtc, bool enable); + void rcar_du_crtc_cancel_page_flip(struct rcar_du_crtc *rcrtc, +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +index 983bc5912588..a4c2007f5bb5 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -227,6 +227,7 @@ static const struct rcar_du_device_info rcar_du_r8a7779_info = { + .encoder_type = DRM_MODE_ENCODER_NONE, + }, + }, ++ .num_lvds = 0, + }; + + static const struct rcar_du_device_info rcar_du_r8a7790_info = { +@@ -250,6 +251,7 @@ static const struct rcar_du_device_info rcar_du_r8a7790_info = { + .encoder_type = DRM_MODE_ENCODER_LVDS, + }, + }, ++ .num_lvds = 2, + }; + + static const struct platform_device_id rcar_du_id_table[] = { +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +index 924f5e08f060..050d71c1f785 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +@@ -24,6 +24,7 @@ struct clk; + struct device; + struct drm_device; + struct rcar_du_device; ++struct rcar_du_lvdsenc; + + #define RCAR_DU_FEATURE_CRTC_IRQ_CLOCK (1 << 0) /* Per-CRTC IRQ and clock */ + #define RCAR_DU_FEATURE_ALIGN_128B (1 << 1) /* Align pitches to 128 bytes */ +@@ -48,11 +49,13 @@ struct rcar_du_output_routing { + * @features: device features (RCAR_DU_FEATURE_*) + * @num_crtcs: total number of CRTCs + * @routes: array of CRTC to output routes, indexed by output (RCAR_DU_OUTPUT_*) ++ * @num_lvds: number of internal LVDS encoders + */ + struct rcar_du_device_info { + unsigned int features; + unsigned int num_crtcs; + struct rcar_du_output_routing routes[RCAR_DU_OUTPUT_MAX]; ++ unsigned int num_lvds; + }; + + struct rcar_du_device { +@@ -70,6 +73,7 @@ struct rcar_du_device { + struct rcar_du_group groups[2]; + + unsigned int dpad0_source; ++ struct rcar_du_lvdsenc *lvds[2]; + }; + + static inline bool rcar_du_has(struct rcar_du_device *rcdu, +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +index 2aac28d21f87..3daa7a168dc6 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.c +@@ -11,6 +11,8 @@ + * (at your option) any later version. + */ + ++#include <linux/export.h> ++ + #include <drm/drmP.h> + #include <drm/drm_crtc.h> + #include <drm/drm_crtc_helper.h> +@@ -19,6 +21,7 @@ + #include "rcar_du_encoder.h" + #include "rcar_du_kms.h" + #include "rcar_du_lvdscon.h" ++#include "rcar_du_lvdsenc.h" + #include "rcar_du_vgacon.h" + + /* ----------------------------------------------------------------------------- +@@ -39,12 +42,17 @@ rcar_du_connector_best_encoder(struct drm_connector *connector) + + static void rcar_du_encoder_dpms(struct drm_encoder *encoder, int mode) + { ++ struct rcar_du_encoder *renc = to_rcar_encoder(encoder); ++ ++ if (renc->lvds) ++ rcar_du_lvdsenc_dpms(renc->lvds, encoder->crtc, mode); + } + + static bool rcar_du_encoder_mode_fixup(struct drm_encoder *encoder, + const struct drm_display_mode *mode, + struct drm_display_mode *adjusted_mode) + { ++ struct rcar_du_encoder *renc = to_rcar_encoder(encoder); + const struct drm_display_mode *panel_mode; + struct drm_device *dev = encoder->dev; + struct drm_connector *connector; +@@ -82,15 +90,32 @@ static bool rcar_du_encoder_mode_fixup(struct drm_encoder *encoder, + /* The flat panel mode is fixed, just copy it to the adjusted mode. */ + drm_mode_copy(adjusted_mode, panel_mode); + ++ /* The internal LVDS encoder has a clock frequency operating range of ++ * 30MHz to 150MHz. Clamp the clock accordingly. ++ */ ++ if (renc->lvds) ++ adjusted_mode->clock = clamp(adjusted_mode->clock, ++ 30000, 150000); ++ + return true; + } + + static void rcar_du_encoder_mode_prepare(struct drm_encoder *encoder) + { ++ struct rcar_du_encoder *renc = to_rcar_encoder(encoder); ++ ++ if (renc->lvds) ++ rcar_du_lvdsenc_dpms(renc->lvds, encoder->crtc, ++ DRM_MODE_DPMS_OFF); + } + + static void rcar_du_encoder_mode_commit(struct drm_encoder *encoder) + { ++ struct rcar_du_encoder *renc = to_rcar_encoder(encoder); ++ ++ if (renc->lvds) ++ rcar_du_lvdsenc_dpms(renc->lvds, encoder->crtc, ++ DRM_MODE_DPMS_ON); + } + + static void rcar_du_encoder_mode_set(struct drm_encoder *encoder, +@@ -129,6 +154,19 @@ int rcar_du_encoder_init(struct rcar_du_device *rcdu, + + renc->output = output; + ++ switch (output) { ++ case RCAR_DU_OUTPUT_LVDS0: ++ renc->lvds = rcdu->lvds[0]; ++ break; ++ ++ case RCAR_DU_OUTPUT_LVDS1: ++ renc->lvds = rcdu->lvds[1]; ++ break; ++ ++ default: ++ break; ++ } ++ + switch (type) { + case RCAR_DU_ENCODER_VGA: + encoder_type = DRM_MODE_ENCODER_DAC; +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h +index 2310416ea21f..0e5a65e45d0e 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_encoder.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_encoder.h +@@ -19,10 +19,12 @@ + #include <drm/drm_crtc.h> + + struct rcar_du_device; ++struct rcar_du_lvdsenc; + + struct rcar_du_encoder { + struct drm_encoder encoder; + enum rcar_du_output output; ++ struct rcar_du_lvdsenc *lvds; + }; + + #define to_rcar_encoder(e) \ +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +index 2b92e68a09f0..cc71b1a0c3ce 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +@@ -21,6 +21,7 @@ + #include "rcar_du_drv.h" + #include "rcar_du_encoder.h" + #include "rcar_du_kms.h" ++#include "rcar_du_lvdsenc.h" + #include "rcar_du_regs.h" + + /* ----------------------------------------------------------------------------- +@@ -217,6 +218,10 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + } + + /* Initialize the encoders. */ ++ ret = rcar_du_lvdsenc_init(rcdu); ++ if (ret < 0) ++ return ret; ++ + for (i = 0; i < rcdu->pdata->num_encoders; ++i) { + const struct rcar_du_encoder_data *pdata = + &rcdu->pdata->encoders[i]; +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c +new file mode 100644 +index 000000000000..a0f6a1781925 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.c +@@ -0,0 +1,196 @@ ++/* ++ * rcar_du_lvdsenc.c -- R-Car Display Unit LVDS Encoder ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <linux/clk.h> ++#include <linux/delay.h> ++#include <linux/io.h> ++#include <linux/platform_device.h> ++#include <linux/slab.h> ++ ++#include "rcar_du_drv.h" ++#include "rcar_du_encoder.h" ++#include "rcar_du_lvdsenc.h" ++#include "rcar_lvds_regs.h" ++ ++struct rcar_du_lvdsenc { ++ struct rcar_du_device *dev; ++ ++ unsigned int index; ++ void __iomem *mmio; ++ struct clk *clock; ++ int dpms; ++ ++ enum rcar_lvds_input input; ++}; ++ ++static void rcar_lvds_write(struct rcar_du_lvdsenc *lvds, u32 reg, u32 data) ++{ ++ iowrite32(data, lvds->mmio + reg); ++} ++ ++static int rcar_du_lvdsenc_start(struct rcar_du_lvdsenc *lvds, ++ struct rcar_du_crtc *rcrtc) ++{ ++ const struct drm_display_mode *mode = &rcrtc->crtc.mode; ++ unsigned int freq = mode->clock; ++ u32 lvdcr0; ++ u32 pllcr; ++ int ret; ++ ++ if (lvds->dpms == DRM_MODE_DPMS_ON) ++ return 0; ++ ++ ret = clk_prepare_enable(lvds->clock); ++ if (ret < 0) ++ return ret; ++ ++ /* PLL clock configuration */ ++ if (freq <= 38000) ++ pllcr = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_38M; ++ else if (freq <= 60000) ++ pllcr = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_60M; ++ else if (freq <= 121000) ++ pllcr = LVDPLLCR_CEEN | LVDPLLCR_COSEL | LVDPLLCR_PLLDLYCNT_121M; ++ else ++ pllcr = LVDPLLCR_PLLDLYCNT_150M; ++ ++ rcar_lvds_write(lvds, LVDPLLCR, pllcr); ++ ++ /* Hardcode the channels and control signals routing for now. ++ * ++ * HSYNC -> CTRL0 ++ * VSYNC -> CTRL1 ++ * DISP -> CTRL2 ++ * 0 -> CTRL3 ++ * ++ * Channels 1 and 3 are switched on ES1. ++ */ ++ rcar_lvds_write(lvds, LVDCTRCR, LVDCTRCR_CTR3SEL_ZERO | ++ LVDCTRCR_CTR2SEL_DISP | LVDCTRCR_CTR1SEL_VSYNC | ++ LVDCTRCR_CTR0SEL_HSYNC); ++ rcar_lvds_write(lvds, LVDCHCR, ++ LVDCHCR_CHSEL_CH(0, 0) | LVDCHCR_CHSEL_CH(1, 3) | ++ LVDCHCR_CHSEL_CH(2, 2) | LVDCHCR_CHSEL_CH(3, 1)); ++ ++ /* Select the input, hardcode mode 0, enable LVDS operation and turn ++ * bias circuitry on. ++ */ ++ lvdcr0 = LVDCR0_BEN | LVDCR0_LVEN; ++ if (rcrtc->index == 2) ++ lvdcr0 |= LVDCR0_DUSEL; ++ rcar_lvds_write(lvds, LVDCR0, lvdcr0); ++ ++ /* Turn all the channels on. */ ++ rcar_lvds_write(lvds, LVDCR1, LVDCR1_CHSTBY(3) | LVDCR1_CHSTBY(2) | ++ LVDCR1_CHSTBY(1) | LVDCR1_CHSTBY(0) | LVDCR1_CLKSTBY); ++ ++ /* Turn the PLL on, wait for the startup delay, and turn the output ++ * on. ++ */ ++ lvdcr0 |= LVDCR0_PLLEN; ++ rcar_lvds_write(lvds, LVDCR0, lvdcr0); ++ ++ usleep_range(100, 150); ++ ++ lvdcr0 |= LVDCR0_LVRES; ++ rcar_lvds_write(lvds, LVDCR0, lvdcr0); ++ ++ lvds->dpms = DRM_MODE_DPMS_ON; ++ return 0; ++} ++ ++static void rcar_du_lvdsenc_stop(struct rcar_du_lvdsenc *lvds) ++{ ++ if (lvds->dpms == DRM_MODE_DPMS_OFF) ++ return; ++ ++ rcar_lvds_write(lvds, LVDCR0, 0); ++ rcar_lvds_write(lvds, LVDCR1, 0); ++ ++ clk_disable_unprepare(lvds->clock); ++ ++ lvds->dpms = DRM_MODE_DPMS_OFF; ++} ++ ++int rcar_du_lvdsenc_dpms(struct rcar_du_lvdsenc *lvds, ++ struct drm_crtc *crtc, int mode) ++{ ++ if (mode == DRM_MODE_DPMS_OFF) { ++ rcar_du_lvdsenc_stop(lvds); ++ return 0; ++ } else if (crtc) { ++ struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); ++ return rcar_du_lvdsenc_start(lvds, rcrtc); ++ } else ++ return -EINVAL; ++} ++ ++static int rcar_du_lvdsenc_get_resources(struct rcar_du_lvdsenc *lvds, ++ struct platform_device *pdev) ++{ ++ struct resource *mem; ++ char name[7]; ++ ++ sprintf(name, "lvds.%u", lvds->index); ++ ++ mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); ++ if (mem == NULL) { ++ dev_err(&pdev->dev, "failed to get memory resource for %s\n", ++ name); ++ return -EINVAL; ++ } ++ ++ lvds->mmio = devm_ioremap_resource(&pdev->dev, mem); ++ if (lvds->mmio == NULL) { ++ dev_err(&pdev->dev, "failed to remap memory resource for %s\n", ++ name); ++ return -ENOMEM; ++ } ++ ++ lvds->clock = devm_clk_get(&pdev->dev, name); ++ if (IS_ERR(lvds->clock)) { ++ dev_err(&pdev->dev, "failed to get clock for %s\n", name); ++ return PTR_ERR(lvds->clock); ++ } ++ ++ return 0; ++} ++ ++int rcar_du_lvdsenc_init(struct rcar_du_device *rcdu) ++{ ++ struct platform_device *pdev = to_platform_device(rcdu->dev); ++ struct rcar_du_lvdsenc *lvds; ++ unsigned int i; ++ int ret; ++ ++ for (i = 0; i < rcdu->info->num_lvds; ++i) { ++ lvds = devm_kzalloc(&pdev->dev, sizeof(*lvds), GFP_KERNEL); ++ if (lvds == NULL) { ++ dev_err(&pdev->dev, "failed to allocate private data\n"); ++ return -ENOMEM; ++ } ++ ++ lvds->dev = rcdu; ++ lvds->index = i; ++ lvds->input = i ? RCAR_LVDS_INPUT_DU1 : RCAR_LVDS_INPUT_DU0; ++ lvds->dpms = DRM_MODE_DPMS_OFF; ++ ++ ret = rcar_du_lvdsenc_get_resources(lvds, pdev); ++ if (ret < 0) ++ return ret; ++ ++ rcdu->lvds[i] = lvds; ++ } ++ ++ return 0; ++} +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h +new file mode 100644 +index 000000000000..7051c6de19ae +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h +@@ -0,0 +1,46 @@ ++/* ++ * rcar_du_lvdsenc.h -- R-Car Display Unit LVDS Encoder ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#ifndef __RCAR_DU_LVDSENC_H__ ++#define __RCAR_DU_LVDSENC_H__ ++ ++#include <linux/io.h> ++#include <linux/module.h> ++#include <linux/platform_data/rcar-du.h> ++ ++struct rcar_drm_crtc; ++struct rcar_du_lvdsenc; ++ ++enum rcar_lvds_input { ++ RCAR_LVDS_INPUT_DU0, ++ RCAR_LVDS_INPUT_DU1, ++ RCAR_LVDS_INPUT_DU2, ++}; ++ ++#if IS_ENABLED(CONFIG_DRM_RCAR_LVDS) ++int rcar_du_lvdsenc_init(struct rcar_du_device *rcdu); ++int rcar_du_lvdsenc_dpms(struct rcar_du_lvdsenc *lvds, ++ struct drm_crtc *crtc, int mode); ++#else ++static inline int rcar_du_lvdsenc_init(struct rcar_du_device *rcdu) ++{ ++ return 0; ++} ++static inline int rcar_du_lvdsenc_dpms(struct rcar_du_lvdsenc *lvds, ++ struct drm_crtc *crtc, int mode) ++{ ++ return 0; ++} ++#endif ++ ++#endif /* __RCAR_DU_LVDSENC_H__ */ +diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h +new file mode 100644 +index 000000000000..77cf9289ab65 +--- /dev/null ++++ b/drivers/gpu/drm/rcar-du/rcar_lvds_regs.h +@@ -0,0 +1,69 @@ ++/* ++ * rcar_lvds_regs.h -- R-Car LVDS Interface Registers Definitions ++ * ++ * Copyright (C) 2013 Renesas Electronics Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 ++ * as published by the Free Software Foundation. ++ */ ++ ++#ifndef __RCAR_LVDS_REGS_H__ ++#define __RCAR_LVDS_REGS_H__ ++ ++#define LVDCR0 0x0000 ++#define LVDCR0_DUSEL (1 << 15) ++#define LVDCR0_DMD (1 << 12) ++#define LVDCR0_LVMD_MASK (0xf << 8) ++#define LVDCR0_LVMD_SHIFT 8 ++#define LVDCR0_PLLEN (1 << 4) ++#define LVDCR0_BEN (1 << 2) ++#define LVDCR0_LVEN (1 << 1) ++#define LVDCR0_LVRES (1 << 0) ++ ++#define LVDCR1 0x0004 ++#define LVDCR1_CKSEL (1 << 15) ++#define LVDCR1_CHSTBY(n) (3 << (2 + (n) * 2)) ++#define LVDCR1_CLKSTBY (3 << 0) ++ ++#define LVDPLLCR 0x0008 ++#define LVDPLLCR_CEEN (1 << 14) ++#define LVDPLLCR_FBEN (1 << 13) ++#define LVDPLLCR_COSEL (1 << 12) ++#define LVDPLLCR_PLLDLYCNT_150M (0x1bf << 0) ++#define LVDPLLCR_PLLDLYCNT_121M (0x22c << 0) ++#define LVDPLLCR_PLLDLYCNT_60M (0x77b << 0) ++#define LVDPLLCR_PLLDLYCNT_38M (0x69a << 0) ++#define LVDPLLCR_PLLDLYCNT_MASK (0x7ff << 0) ++ ++#define LVDCTRCR 0x000c ++#define LVDCTRCR_CTR3SEL_ZERO (0 << 12) ++#define LVDCTRCR_CTR3SEL_ODD (1 << 12) ++#define LVDCTRCR_CTR3SEL_CDE (2 << 12) ++#define LVDCTRCR_CTR3SEL_MASK (7 << 12) ++#define LVDCTRCR_CTR2SEL_DISP (0 << 8) ++#define LVDCTRCR_CTR2SEL_ODD (1 << 8) ++#define LVDCTRCR_CTR2SEL_CDE (2 << 8) ++#define LVDCTRCR_CTR2SEL_HSYNC (3 << 8) ++#define LVDCTRCR_CTR2SEL_VSYNC (4 << 8) ++#define LVDCTRCR_CTR2SEL_MASK (7 << 8) ++#define LVDCTRCR_CTR1SEL_VSYNC (0 << 4) ++#define LVDCTRCR_CTR1SEL_DISP (1 << 4) ++#define LVDCTRCR_CTR1SEL_ODD (2 << 4) ++#define LVDCTRCR_CTR1SEL_CDE (3 << 4) ++#define LVDCTRCR_CTR1SEL_HSYNC (4 << 4) ++#define LVDCTRCR_CTR1SEL_MASK (7 << 4) ++#define LVDCTRCR_CTR0SEL_HSYNC (0 << 0) ++#define LVDCTRCR_CTR0SEL_VSYNC (1 << 0) ++#define LVDCTRCR_CTR0SEL_DISP (2 << 0) ++#define LVDCTRCR_CTR0SEL_ODD (3 << 0) ++#define LVDCTRCR_CTR0SEL_CDE (4 << 0) ++#define LVDCTRCR_CTR0SEL_MASK (7 << 0) ++ ++#define LVDCHCR 0x0010 ++#define LVDCHCR_CHSEL_CH(n, c) ((((c) - (n)) & 3) << ((n) * 4)) ++#define LVDCHCR_CHSEL_MASK(n) (3 << ((n) * 4)) ++ ++#endif /* __RCAR_LVDS_REGS_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0034-drm-rcar-du-Add-FBDEV-emulation-support.patch b/patches.renesas/0034-drm-rcar-du-Add-FBDEV-emulation-support.patch new file mode 100644 index 00000000000000..d3819a110d5314 --- /dev/null +++ b/patches.renesas/0034-drm-rcar-du-Add-FBDEV-emulation-support.patch @@ -0,0 +1,170 @@ +From fc0913f6a501656257f93a2ac79c01b0ebd2c166 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 14 Mar 2013 22:45:22 +0100 +Subject: drm/rcar-du: Add FBDEV emulation support + +Use the FB CMA helpers to implement FBDEV emulation support. The VGA +connector status must be reported as connector_status_connected instead +of connector_status_unknown to be usable by the emulation layer. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 3864c6f446f3c2ebbeca1d45e28452682706c1aa) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpu/drm/rcar-du/rcar_du_drv.c | 14 +++++++++++++ + drivers/gpu/drm/rcar-du/rcar_du_drv.h | 2 ++ + drivers/gpu/drm/rcar-du/rcar_du_kms.c | 36 +++++++++++++++++++++++++------- + drivers/gpu/drm/rcar-du/rcar_du_vgacon.c | 2 +- + 4 files changed, 45 insertions(+), 9 deletions(-) + +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +index a4c2007f5bb5..c63914e66089 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c +@@ -21,6 +21,7 @@ + + #include <drm/drmP.h> + #include <drm/drm_crtc_helper.h> ++#include <drm/drm_fb_cma_helper.h> + #include <drm/drm_gem_cma_helper.h> + + #include "rcar_du_crtc.h" +@@ -34,6 +35,11 @@ + + static int rcar_du_unload(struct drm_device *dev) + { ++ struct rcar_du_device *rcdu = dev->dev_private; ++ ++ if (rcdu->fbdev) ++ drm_fbdev_cma_fini(rcdu->fbdev); ++ + drm_kms_helper_poll_fini(dev); + drm_mode_config_cleanup(dev); + drm_vblank_cleanup(dev); +@@ -109,6 +115,13 @@ static void rcar_du_preclose(struct drm_device *dev, struct drm_file *file) + rcar_du_crtc_cancel_page_flip(&rcdu->crtcs[i], file); + } + ++static void rcar_du_lastclose(struct drm_device *dev) ++{ ++ struct rcar_du_device *rcdu = dev->dev_private; ++ ++ drm_fbdev_cma_restore_mode(rcdu->fbdev); ++} ++ + static int rcar_du_enable_vblank(struct drm_device *dev, int crtc) + { + struct rcar_du_device *rcdu = dev->dev_private; +@@ -145,6 +158,7 @@ static struct drm_driver rcar_du_driver = { + .load = rcar_du_load, + .unload = rcar_du_unload, + .preclose = rcar_du_preclose, ++ .lastclose = rcar_du_lastclose, + .get_vblank_counter = drm_vblank_count, + .enable_vblank = rcar_du_enable_vblank, + .disable_vblank = rcar_du_disable_vblank, +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.h b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +index 050d71c1f785..65d2d636b002 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.h ++++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.h +@@ -23,6 +23,7 @@ + struct clk; + struct device; + struct drm_device; ++struct drm_fbdev_cma; + struct rcar_du_device; + struct rcar_du_lvdsenc; + +@@ -66,6 +67,7 @@ struct rcar_du_device { + void __iomem *mmio; + + struct drm_device *ddev; ++ struct drm_fbdev_cma *fbdev; + + struct rcar_du_crtc crtcs[3]; + unsigned int num_crtcs; +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +index cc71b1a0c3ce..b31ac080c4a7 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c +@@ -167,8 +167,16 @@ rcar_du_fb_create(struct drm_device *dev, struct drm_file *file_priv, + return drm_fb_cma_create(dev, file_priv, mode_cmd); + } + ++static void rcar_du_output_poll_changed(struct drm_device *dev) ++{ ++ struct rcar_du_device *rcdu = dev->dev_private; ++ ++ drm_fbdev_cma_hotplug_event(rcdu->fbdev); ++} ++ + static const struct drm_mode_config_funcs rcar_du_mode_config_funcs = { + .fb_create = rcar_du_fb_create, ++ .output_poll_changed = rcar_du_output_poll_changed, + }; + + int rcar_du_modeset_init(struct rcar_du_device *rcdu) +@@ -179,17 +187,18 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + + struct drm_device *dev = rcdu->ddev; + struct drm_encoder *encoder; ++ struct drm_fbdev_cma *fbdev; + unsigned int num_groups; + unsigned int i; + int ret; + +- drm_mode_config_init(rcdu->ddev); ++ drm_mode_config_init(dev); + +- rcdu->ddev->mode_config.min_width = 0; +- rcdu->ddev->mode_config.min_height = 0; +- rcdu->ddev->mode_config.max_width = 4095; +- rcdu->ddev->mode_config.max_height = 2047; +- rcdu->ddev->mode_config.funcs = &rcar_du_mode_config_funcs; ++ dev->mode_config.min_width = 0; ++ dev->mode_config.min_height = 0; ++ dev->mode_config.max_width = 4095; ++ dev->mode_config.max_height = 2047; ++ dev->mode_config.funcs = &rcar_du_mode_config_funcs; + + rcdu->num_crtcs = rcdu->info->num_crtcs; + +@@ -262,9 +271,20 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) + return ret; + } + +- drm_kms_helper_poll_init(rcdu->ddev); ++ drm_kms_helper_poll_init(dev); ++ ++ drm_helper_disable_unused_functions(dev); ++ ++ fbdev = drm_fbdev_cma_init(dev, 32, dev->mode_config.num_crtc, ++ dev->mode_config.num_connector); ++ if (IS_ERR(fbdev)) ++ return PTR_ERR(fbdev); ++ ++#ifndef CONFIG_FRAMEBUFFER_CONSOLE ++ drm_fbdev_cma_restore_mode(fbdev); ++#endif + +- drm_helper_disable_unused_functions(rcdu->ddev); ++ rcdu->fbdev = fbdev; + + return 0; + } +diff --git a/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c +index 36105db9bda1..41d563adfeaa 100644 +--- a/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c ++++ b/drivers/gpu/drm/rcar-du/rcar_du_vgacon.c +@@ -46,7 +46,7 @@ static void rcar_du_vga_connector_destroy(struct drm_connector *connector) + static enum drm_connector_status + rcar_du_vga_connector_detect(struct drm_connector *connector, bool force) + { +- return connector_status_unknown; ++ return connector_status_connected; + } + + static const struct drm_connector_funcs connector_funcs = { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0035-media-v4l-Add-media-format-codes-for-ARGB8888-and-AY.patch b/patches.renesas/0035-media-v4l-Add-media-format-codes-for-ARGB8888-and-AY.patch new file mode 100644 index 00000000000000..098ae2e8e0e714 --- /dev/null +++ b/patches.renesas/0035-media-v4l-Add-media-format-codes-for-ARGB8888-and-AY.patch @@ -0,0 +1,1378 @@ +From 77f394a03b1c86bb0bcf015c5f21a8c4b17a73de Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Wed, 5 Jun 2013 04:19:53 -0300 +Subject: [media] v4l: Add media format codes for ARGB8888 and AYUV8888 on + 32-bit busses + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com> +Acked-by: Hans Verkuil <hans.verkuil@cisco.com> +Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> +(cherry picked from commit f57fa2102cd5c0b50359def79a3d39cda8431204) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + Documentation/DocBook/media/v4l/subdev-formats.xml | 609 +++++++++------------ + Documentation/DocBook/media_api.tmpl | 6 + + include/uapi/linux/v4l2-mediabus.h | 6 +- + 3 files changed, 254 insertions(+), 367 deletions(-) + +diff --git a/Documentation/DocBook/media/v4l/subdev-formats.xml b/Documentation/DocBook/media/v4l/subdev-formats.xml +index adc61982df7b..98f66eb540b6 100644 +--- a/Documentation/DocBook/media/v4l/subdev-formats.xml ++++ b/Documentation/DocBook/media/v4l/subdev-formats.xml +@@ -97,31 +97,39 @@ + <colspec colname="id" align="left" /> + <colspec colname="code" align="center"/> + <colspec colname="bit" /> +- <colspec colnum="4" colname="b23" align="center" /> +- <colspec colnum="5" colname="b22" align="center" /> +- <colspec colnum="6" colname="b21" align="center" /> +- <colspec colnum="7" colname="b20" align="center" /> +- <colspec colnum="8" colname="b19" align="center" /> +- <colspec colnum="9" colname="b18" align="center" /> +- <colspec colnum="10" colname="b17" align="center" /> +- <colspec colnum="11" colname="b16" align="center" /> +- <colspec colnum="12" colname="b15" align="center" /> +- <colspec colnum="13" colname="b14" align="center" /> +- <colspec colnum="14" colname="b13" align="center" /> +- <colspec colnum="15" colname="b12" align="center" /> +- <colspec colnum="16" colname="b11" align="center" /> +- <colspec colnum="17" colname="b10" align="center" /> +- <colspec colnum="18" colname="b09" align="center" /> +- <colspec colnum="19" colname="b08" align="center" /> +- <colspec colnum="20" colname="b07" align="center" /> +- <colspec colnum="21" colname="b06" align="center" /> +- <colspec colnum="22" colname="b05" align="center" /> +- <colspec colnum="23" colname="b04" align="center" /> +- <colspec colnum="24" colname="b03" align="center" /> +- <colspec colnum="25" colname="b02" align="center" /> +- <colspec colnum="26" colname="b01" align="center" /> +- <colspec colnum="27" colname="b00" align="center" /> +- <spanspec namest="b23" nameend="b00" spanname="b0" /> ++ <colspec colnum="4" colname="b31" align="center" /> ++ <colspec colnum="5" colname="b20" align="center" /> ++ <colspec colnum="6" colname="b29" align="center" /> ++ <colspec colnum="7" colname="b28" align="center" /> ++ <colspec colnum="8" colname="b27" align="center" /> ++ <colspec colnum="9" colname="b26" align="center" /> ++ <colspec colnum="10" colname="b25" align="center" /> ++ <colspec colnum="11" colname="b24" align="center" /> ++ <colspec colnum="12" colname="b23" align="center" /> ++ <colspec colnum="13" colname="b22" align="center" /> ++ <colspec colnum="14" colname="b21" align="center" /> ++ <colspec colnum="15" colname="b20" align="center" /> ++ <colspec colnum="16" colname="b19" align="center" /> ++ <colspec colnum="17" colname="b18" align="center" /> ++ <colspec colnum="18" colname="b17" align="center" /> ++ <colspec colnum="19" colname="b16" align="center" /> ++ <colspec colnum="20" colname="b15" align="center" /> ++ <colspec colnum="21" colname="b14" align="center" /> ++ <colspec colnum="22" colname="b13" align="center" /> ++ <colspec colnum="23" colname="b12" align="center" /> ++ <colspec colnum="24" colname="b11" align="center" /> ++ <colspec colnum="25" colname="b10" align="center" /> ++ <colspec colnum="26" colname="b09" align="center" /> ++ <colspec colnum="27" colname="b08" align="center" /> ++ <colspec colnum="28" colname="b07" align="center" /> ++ <colspec colnum="29" colname="b06" align="center" /> ++ <colspec colnum="30" colname="b05" align="center" /> ++ <colspec colnum="31" colname="b04" align="center" /> ++ <colspec colnum="32" colname="b03" align="center" /> ++ <colspec colnum="33" colname="b02" align="center" /> ++ <colspec colnum="34" colname="b01" align="center" /> ++ <colspec colnum="35" colname="b00" align="center" /> ++ <spanspec namest="b31" nameend="b00" spanname="b0" /> + <thead> + <row> + <entry>Identifier</entry> +@@ -133,6 +141,14 @@ + <entry></entry> + <entry></entry> + <entry>Bit</entry> ++ <entry>31</entry> ++ <entry>30</entry> ++ <entry>29</entry> ++ <entry>28</entry> ++ <entry>27</entry> ++ <entry>26</entry> ++ <entry>25</entry> ++ <entry>24</entry> + <entry>23</entry> + <entry>22</entry> + <entry>21</entry> +@@ -164,7 +180,7 @@ + <entry>V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE</entry> + <entry>0x1001</entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>0</entry> + <entry>0</entry> + <entry>0</entry> +@@ -178,7 +194,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>g<subscript>3</subscript></entry> + <entry>g<subscript>2</subscript></entry> + <entry>g<subscript>1</subscript></entry> +@@ -192,7 +208,7 @@ + <entry>V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE</entry> + <entry>0x1002</entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>g<subscript>3</subscript></entry> + <entry>g<subscript>2</subscript></entry> + <entry>g<subscript>1</subscript></entry> +@@ -206,7 +222,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>0</entry> + <entry>0</entry> + <entry>0</entry> +@@ -220,7 +236,7 @@ + <entry>V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE</entry> + <entry>0x1003</entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>0</entry> + <entry>r<subscript>4</subscript></entry> + <entry>r<subscript>3</subscript></entry> +@@ -234,7 +250,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>g<subscript>2</subscript></entry> + <entry>g<subscript>1</subscript></entry> + <entry>g<subscript>0</subscript></entry> +@@ -248,7 +264,7 @@ + <entry>V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE</entry> + <entry>0x1004</entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>g<subscript>2</subscript></entry> + <entry>g<subscript>1</subscript></entry> + <entry>g<subscript>0</subscript></entry> +@@ -262,7 +278,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>0</entry> + <entry>r<subscript>4</subscript></entry> + <entry>r<subscript>3</subscript></entry> +@@ -276,7 +292,7 @@ + <entry>V4L2_MBUS_FMT_BGR565_2X8_BE</entry> + <entry>0x1005</entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>b<subscript>4</subscript></entry> + <entry>b<subscript>3</subscript></entry> + <entry>b<subscript>2</subscript></entry> +@@ -290,7 +306,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>g<subscript>2</subscript></entry> + <entry>g<subscript>1</subscript></entry> + <entry>g<subscript>0</subscript></entry> +@@ -304,7 +320,7 @@ + <entry>V4L2_MBUS_FMT_BGR565_2X8_LE</entry> + <entry>0x1006</entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>g<subscript>2</subscript></entry> + <entry>g<subscript>1</subscript></entry> + <entry>g<subscript>0</subscript></entry> +@@ -318,7 +334,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>b<subscript>4</subscript></entry> + <entry>b<subscript>3</subscript></entry> + <entry>b<subscript>2</subscript></entry> +@@ -332,7 +348,7 @@ + <entry>V4L2_MBUS_FMT_RGB565_2X8_BE</entry> + <entry>0x1007</entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>r<subscript>4</subscript></entry> + <entry>r<subscript>3</subscript></entry> + <entry>r<subscript>2</subscript></entry> +@@ -346,7 +362,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>g<subscript>2</subscript></entry> + <entry>g<subscript>1</subscript></entry> + <entry>g<subscript>0</subscript></entry> +@@ -360,7 +376,7 @@ + <entry>V4L2_MBUS_FMT_RGB565_2X8_LE</entry> + <entry>0x1008</entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>g<subscript>2</subscript></entry> + <entry>g<subscript>1</subscript></entry> + <entry>g<subscript>0</subscript></entry> +@@ -374,7 +390,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-16; ++ &dash-ent-24; + <entry>r<subscript>4</subscript></entry> + <entry>r<subscript>3</subscript></entry> + <entry>r<subscript>2</subscript></entry> +@@ -388,12 +404,7 @@ + <entry>V4L2_MBUS_FMT_RGB666_1X18</entry> + <entry>0x1009</entry> + <entry></entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-14; + <entry>r<subscript>5</subscript></entry> + <entry>r<subscript>4</subscript></entry> + <entry>r<subscript>3</subscript></entry> +@@ -417,6 +428,7 @@ + <entry>V4L2_MBUS_FMT_RGB888_1X24</entry> + <entry>0x100a</entry> + <entry></entry> ++ &dash-ent-8; + <entry>r<subscript>7</subscript></entry> + <entry>r<subscript>6</subscript></entry> + <entry>r<subscript>5</subscript></entry> +@@ -446,9 +458,7 @@ + <entry>V4L2_MBUS_FMT_RGB888_2X12_BE</entry> + <entry>0x100b</entry> + <entry></entry> +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-20; + <entry>r<subscript>7</subscript></entry> + <entry>r<subscript>6</subscript></entry> + <entry>r<subscript>5</subscript></entry> +@@ -466,9 +476,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-20; + <entry>g<subscript>3</subscript></entry> + <entry>g<subscript>2</subscript></entry> + <entry>g<subscript>1</subscript></entry> +@@ -486,9 +494,7 @@ + <entry>V4L2_MBUS_FMT_RGB888_2X12_LE</entry> + <entry>0x100c</entry> + <entry></entry> +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-20; + <entry>g<subscript>3</subscript></entry> + <entry>g<subscript>2</subscript></entry> + <entry>g<subscript>1</subscript></entry> +@@ -506,9 +512,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-20; + <entry>r<subscript>7</subscript></entry> + <entry>r<subscript>6</subscript></entry> + <entry>r<subscript>5</subscript></entry> +@@ -522,6 +526,43 @@ + <entry>g<subscript>5</subscript></entry> + <entry>g<subscript>4</subscript></entry> + </row> ++ <row id="V4L2-MBUS-FMT-ARGB888-1X32"> ++ <entry>V4L2_MBUS_FMT_ARGB888_1X32</entry> ++ <entry>0x100d</entry> ++ <entry></entry> ++ <entry>a<subscript>7</subscript></entry> ++ <entry>a<subscript>6</subscript></entry> ++ <entry>a<subscript>5</subscript></entry> ++ <entry>a<subscript>4</subscript></entry> ++ <entry>a<subscript>3</subscript></entry> ++ <entry>a<subscript>2</subscript></entry> ++ <entry>a<subscript>1</subscript></entry> ++ <entry>a<subscript>0</subscript></entry> ++ <entry>r<subscript>7</subscript></entry> ++ <entry>r<subscript>6</subscript></entry> ++ <entry>r<subscript>5</subscript></entry> ++ <entry>r<subscript>4</subscript></entry> ++ <entry>r<subscript>3</subscript></entry> ++ <entry>r<subscript>2</subscript></entry> ++ <entry>r<subscript>1</subscript></entry> ++ <entry>r<subscript>0</subscript></entry> ++ <entry>g<subscript>7</subscript></entry> ++ <entry>g<subscript>6</subscript></entry> ++ <entry>g<subscript>5</subscript></entry> ++ <entry>g<subscript>4</subscript></entry> ++ <entry>g<subscript>3</subscript></entry> ++ <entry>g<subscript>2</subscript></entry> ++ <entry>g<subscript>1</subscript></entry> ++ <entry>g<subscript>0</subscript></entry> ++ <entry>b<subscript>7</subscript></entry> ++ <entry>b<subscript>6</subscript></entry> ++ <entry>b<subscript>5</subscript></entry> ++ <entry>b<subscript>4</subscript></entry> ++ <entry>b<subscript>3</subscript></entry> ++ <entry>b<subscript>2</subscript></entry> ++ <entry>b<subscript>1</subscript></entry> ++ <entry>b<subscript>0</subscript></entry> ++ </row> + </tbody> + </tgroup> + </table> +@@ -1149,6 +1190,7 @@ + <listitem><para>y<subscript>x</subscript> for luma component bit number x</para></listitem> + <listitem><para>u<subscript>x</subscript> for blue chroma component bit number x</para></listitem> + <listitem><para>v<subscript>x</subscript> for red chroma component bit number x</para></listitem> ++ <listitem><para>a<subscript>x</subscript> for alpha component bit number x</para></listitem> + <listitem><para>- for non-available bits (for positions higher than the bus width)</para></listitem> + <listitem><para>d for dummy bits</para></listitem> + </itemizedlist> +@@ -1159,37 +1201,39 @@ + <colspec colname="id" align="left" /> + <colspec colname="code" align="center"/> + <colspec colname="bit" /> +- <colspec colnum="4" colname="b29" align="center" /> +- <colspec colnum="5" colname="b28" align="center" /> +- <colspec colnum="6" colname="b27" align="center" /> +- <colspec colnum="7" colname="b26" align="center" /> +- <colspec colnum="8" colname="b25" align="center" /> +- <colspec colnum="9" colname="b24" align="center" /> +- <colspec colnum="10" colname="b23" align="center" /> +- <colspec colnum="11" colname="b22" align="center" /> +- <colspec colnum="12" colname="b21" align="center" /> +- <colspec colnum="13" colname="b20" align="center" /> +- <colspec colnum="14" colname="b19" align="center" /> +- <colspec colnum="15" colname="b18" align="center" /> +- <colspec colnum="16" colname="b17" align="center" /> +- <colspec colnum="17" colname="b16" align="center" /> +- <colspec colnum="18" colname="b15" align="center" /> +- <colspec colnum="19" colname="b14" align="center" /> +- <colspec colnum="20" colname="b13" align="center" /> +- <colspec colnum="21" colname="b12" align="center" /> +- <colspec colnum="22" colname="b11" align="center" /> +- <colspec colnum="23" colname="b10" align="center" /> +- <colspec colnum="24" colname="b09" align="center" /> +- <colspec colnum="25" colname="b08" align="center" /> +- <colspec colnum="26" colname="b07" align="center" /> +- <colspec colnum="27" colname="b06" align="center" /> +- <colspec colnum="28" colname="b05" align="center" /> +- <colspec colnum="29" colname="b04" align="center" /> +- <colspec colnum="30" colname="b03" align="center" /> +- <colspec colnum="31" colname="b02" align="center" /> +- <colspec colnum="32" colname="b01" align="center" /> +- <colspec colnum="33" colname="b00" align="center" /> +- <spanspec namest="b29" nameend="b00" spanname="b0" /> ++ <colspec colnum="4" colname="b31" align="center" /> ++ <colspec colnum="5" colname="b20" align="center" /> ++ <colspec colnum="6" colname="b29" align="center" /> ++ <colspec colnum="7" colname="b28" align="center" /> ++ <colspec colnum="8" colname="b27" align="center" /> ++ <colspec colnum="9" colname="b26" align="center" /> ++ <colspec colnum="10" colname="b25" align="center" /> ++ <colspec colnum="11" colname="b24" align="center" /> ++ <colspec colnum="12" colname="b23" align="center" /> ++ <colspec colnum="13" colname="b22" align="center" /> ++ <colspec colnum="14" colname="b21" align="center" /> ++ <colspec colnum="15" colname="b20" align="center" /> ++ <colspec colnum="16" colname="b19" align="center" /> ++ <colspec colnum="17" colname="b18" align="center" /> ++ <colspec colnum="18" colname="b17" align="center" /> ++ <colspec colnum="19" colname="b16" align="center" /> ++ <colspec colnum="20" colname="b15" align="center" /> ++ <colspec colnum="21" colname="b14" align="center" /> ++ <colspec colnum="22" colname="b13" align="center" /> ++ <colspec colnum="23" colname="b12" align="center" /> ++ <colspec colnum="24" colname="b11" align="center" /> ++ <colspec colnum="25" colname="b10" align="center" /> ++ <colspec colnum="26" colname="b09" align="center" /> ++ <colspec colnum="27" colname="b08" align="center" /> ++ <colspec colnum="28" colname="b07" align="center" /> ++ <colspec colnum="29" colname="b06" align="center" /> ++ <colspec colnum="30" colname="b05" align="center" /> ++ <colspec colnum="31" colname="b04" align="center" /> ++ <colspec colnum="32" colname="b03" align="center" /> ++ <colspec colnum="33" colname="b02" align="center" /> ++ <colspec colnum="34" colname="b01" align="center" /> ++ <colspec colnum="35" colname="b00" align="center" /> ++ <spanspec namest="b31" nameend="b00" spanname="b0" /> + <thead> + <row> + <entry>Identifier</entry> +@@ -1201,6 +1245,8 @@ + <entry></entry> + <entry></entry> + <entry>Bit</entry> ++ <entry>31</entry> ++ <entry>30</entry> + <entry>29</entry> + <entry>28</entry> + <entry>27</entry> +@@ -1238,10 +1284,7 @@ + <entry>V4L2_MBUS_FMT_Y8_1X8</entry> + <entry>0x2001</entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1255,18 +1298,7 @@ + <entry>V4L2_MBUS_FMT_UV8_1X8</entry> + <entry>0x2015</entry> + <entry></entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>u<subscript>7</subscript></entry> + <entry>u<subscript>6</subscript></entry> + <entry>u<subscript>5</subscript></entry> +@@ -1280,18 +1312,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>v<subscript>7</subscript></entry> + <entry>v<subscript>6</subscript></entry> + <entry>v<subscript>5</subscript></entry> +@@ -1305,10 +1326,7 @@ + <entry>V4L2_MBUS_FMT_UYVY8_1_5X8</entry> + <entry>0x2002</entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>u<subscript>7</subscript></entry> + <entry>u<subscript>6</subscript></entry> + <entry>u<subscript>5</subscript></entry> +@@ -1322,10 +1340,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1339,10 +1354,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1356,10 +1368,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>v<subscript>7</subscript></entry> + <entry>v<subscript>6</subscript></entry> + <entry>v<subscript>5</subscript></entry> +@@ -1373,10 +1382,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1390,10 +1396,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1407,10 +1410,7 @@ + <entry>V4L2_MBUS_FMT_VYUY8_1_5X8</entry> + <entry>0x2003</entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>v<subscript>7</subscript></entry> + <entry>v<subscript>6</subscript></entry> + <entry>v<subscript>5</subscript></entry> +@@ -1424,10 +1424,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1441,10 +1438,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1458,10 +1452,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>u<subscript>7</subscript></entry> + <entry>u<subscript>6</subscript></entry> + <entry>u<subscript>5</subscript></entry> +@@ -1475,10 +1466,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1492,10 +1480,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1509,10 +1494,7 @@ + <entry>V4L2_MBUS_FMT_YUYV8_1_5X8</entry> + <entry>0x2004</entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1526,10 +1508,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1543,10 +1522,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>u<subscript>7</subscript></entry> + <entry>u<subscript>6</subscript></entry> + <entry>u<subscript>5</subscript></entry> +@@ -1560,10 +1536,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1577,10 +1550,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1594,10 +1564,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>v<subscript>7</subscript></entry> + <entry>v<subscript>6</subscript></entry> + <entry>v<subscript>5</subscript></entry> +@@ -1611,10 +1578,7 @@ + <entry>V4L2_MBUS_FMT_YVYU8_1_5X8</entry> + <entry>0x2005</entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1628,10 +1592,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1645,10 +1606,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>v<subscript>7</subscript></entry> + <entry>v<subscript>6</subscript></entry> + <entry>v<subscript>5</subscript></entry> +@@ -1662,10 +1620,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1679,10 +1634,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1696,10 +1648,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>u<subscript>7</subscript></entry> + <entry>u<subscript>6</subscript></entry> + <entry>u<subscript>5</subscript></entry> +@@ -1713,10 +1662,7 @@ + <entry>V4L2_MBUS_FMT_UYVY8_2X8</entry> + <entry>0x2006</entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>u<subscript>7</subscript></entry> + <entry>u<subscript>6</subscript></entry> + <entry>u<subscript>5</subscript></entry> +@@ -1730,10 +1676,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1747,10 +1690,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>v<subscript>7</subscript></entry> + <entry>v<subscript>6</subscript></entry> + <entry>v<subscript>5</subscript></entry> +@@ -1764,10 +1704,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1781,10 +1718,7 @@ + <entry>V4L2_MBUS_FMT_VYUY8_2X8</entry> + <entry>0x2007</entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>v<subscript>7</subscript></entry> + <entry>v<subscript>6</subscript></entry> + <entry>v<subscript>5</subscript></entry> +@@ -1798,10 +1732,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1815,10 +1746,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>u<subscript>7</subscript></entry> + <entry>u<subscript>6</subscript></entry> + <entry>u<subscript>5</subscript></entry> +@@ -1832,10 +1760,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1849,10 +1774,7 @@ + <entry>V4L2_MBUS_FMT_YUYV8_2X8</entry> + <entry>0x2008</entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1866,10 +1788,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>u<subscript>7</subscript></entry> + <entry>u<subscript>6</subscript></entry> + <entry>u<subscript>5</subscript></entry> +@@ -1883,10 +1802,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1900,10 +1816,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>v<subscript>7</subscript></entry> + <entry>v<subscript>6</subscript></entry> + <entry>v<subscript>5</subscript></entry> +@@ -1917,10 +1830,7 @@ + <entry>V4L2_MBUS_FMT_YVYU8_2X8</entry> + <entry>0x2009</entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1934,10 +1844,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>v<subscript>7</subscript></entry> + <entry>v<subscript>6</subscript></entry> + <entry>v<subscript>5</subscript></entry> +@@ -1951,10 +1858,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -1968,10 +1872,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-24; + <entry>u<subscript>7</subscript></entry> + <entry>u<subscript>6</subscript></entry> + <entry>u<subscript>5</subscript></entry> +@@ -1985,8 +1886,7 @@ + <entry>V4L2_MBUS_FMT_Y10_1X10</entry> + <entry>0x200a</entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; ++ &dash-ent-22; + <entry>y<subscript>9</subscript></entry> + <entry>y<subscript>8</subscript></entry> + <entry>y<subscript>7</subscript></entry> +@@ -2002,8 +1902,7 @@ + <entry>V4L2_MBUS_FMT_YUYV10_2X10</entry> + <entry>0x200b</entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; ++ &dash-ent-22; + <entry>y<subscript>9</subscript></entry> + <entry>y<subscript>8</subscript></entry> + <entry>y<subscript>7</subscript></entry> +@@ -2019,8 +1918,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; ++ &dash-ent-22; + <entry>u<subscript>9</subscript></entry> + <entry>u<subscript>8</subscript></entry> + <entry>u<subscript>7</subscript></entry> +@@ -2036,8 +1934,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; ++ &dash-ent-22; + <entry>y<subscript>9</subscript></entry> + <entry>y<subscript>8</subscript></entry> + <entry>y<subscript>7</subscript></entry> +@@ -2053,8 +1950,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; ++ &dash-ent-22; + <entry>v<subscript>9</subscript></entry> + <entry>v<subscript>8</subscript></entry> + <entry>v<subscript>7</subscript></entry> +@@ -2070,8 +1966,7 @@ + <entry>V4L2_MBUS_FMT_YVYU10_2X10</entry> + <entry>0x200c</entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; ++ &dash-ent-22; + <entry>y<subscript>9</subscript></entry> + <entry>y<subscript>8</subscript></entry> + <entry>y<subscript>7</subscript></entry> +@@ -2087,8 +1982,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; ++ &dash-ent-22; + <entry>v<subscript>9</subscript></entry> + <entry>v<subscript>8</subscript></entry> + <entry>v<subscript>7</subscript></entry> +@@ -2104,8 +1998,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; ++ &dash-ent-22; + <entry>y<subscript>9</subscript></entry> + <entry>y<subscript>8</subscript></entry> + <entry>y<subscript>7</subscript></entry> +@@ -2121,8 +2014,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- &dash-ent-10; ++ &dash-ent-22; + <entry>u<subscript>9</subscript></entry> + <entry>u<subscript>8</subscript></entry> + <entry>u<subscript>7</subscript></entry> +@@ -2138,15 +2030,7 @@ + <entry>V4L2_MBUS_FMT_Y12_1X12</entry> + <entry>0x2013</entry> + <entry></entry> +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-20; + <entry>y<subscript>11</subscript></entry> + <entry>y<subscript>10</subscript></entry> + <entry>y<subscript>9</subscript></entry> +@@ -2164,11 +2048,7 @@ + <entry>V4L2_MBUS_FMT_UYVY8_1X16</entry> + <entry>0x200f</entry> + <entry></entry> +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-16; + <entry>u<subscript>7</subscript></entry> + <entry>u<subscript>6</subscript></entry> + <entry>u<subscript>5</subscript></entry> +@@ -2190,11 +2070,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-16; + <entry>v<subscript>7</subscript></entry> + <entry>v<subscript>6</subscript></entry> + <entry>v<subscript>5</subscript></entry> +@@ -2216,11 +2092,7 @@ + <entry>V4L2_MBUS_FMT_VYUY8_1X16</entry> + <entry>0x2010</entry> + <entry></entry> +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-16; + <entry>v<subscript>7</subscript></entry> + <entry>v<subscript>6</subscript></entry> + <entry>v<subscript>5</subscript></entry> +@@ -2242,11 +2114,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-16; + <entry>u<subscript>7</subscript></entry> + <entry>u<subscript>6</subscript></entry> + <entry>u<subscript>5</subscript></entry> +@@ -2268,11 +2136,7 @@ + <entry>V4L2_MBUS_FMT_YUYV8_1X16</entry> + <entry>0x2011</entry> + <entry></entry> +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-16; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -2294,11 +2158,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-16; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -2320,11 +2180,7 @@ + <entry>V4L2_MBUS_FMT_YVYU8_1X16</entry> + <entry>0x2012</entry> + <entry></entry> +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-16; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -2346,11 +2202,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-16; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -2372,10 +2224,7 @@ + <entry>V4L2_MBUS_FMT_YDYUYDYV8_1X16</entry> + <entry>0x2014</entry> + <entry></entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-16; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -2397,10 +2246,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-16; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -2422,10 +2268,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-16; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -2447,10 +2290,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> +- <entry>-</entry> ++ &dash-ent-16; + <entry>y<subscript>7</subscript></entry> + <entry>y<subscript>6</subscript></entry> + <entry>y<subscript>5</subscript></entry> +@@ -2472,7 +2312,7 @@ + <entry>V4L2_MBUS_FMT_YUYV10_1X20</entry> + <entry>0x200d</entry> + <entry></entry> +- &dash-ent-10; ++ &dash-ent-12; + <entry>y<subscript>9</subscript></entry> + <entry>y<subscript>8</subscript></entry> + <entry>y<subscript>7</subscript></entry> +@@ -2498,7 +2338,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; ++ &dash-ent-12; + <entry>y<subscript>9</subscript></entry> + <entry>y<subscript>8</subscript></entry> + <entry>y<subscript>7</subscript></entry> +@@ -2524,7 +2364,7 @@ + <entry>V4L2_MBUS_FMT_YVYU10_1X20</entry> + <entry>0x200e</entry> + <entry></entry> +- &dash-ent-10; ++ &dash-ent-12; + <entry>y<subscript>9</subscript></entry> + <entry>y<subscript>8</subscript></entry> + <entry>y<subscript>7</subscript></entry> +@@ -2550,7 +2390,7 @@ + <entry></entry> + <entry></entry> + <entry></entry> +- &dash-ent-10; ++ &dash-ent-12; + <entry>y<subscript>9</subscript></entry> + <entry>y<subscript>8</subscript></entry> + <entry>y<subscript>7</subscript></entry> +@@ -2576,6 +2416,8 @@ + <entry>V4L2_MBUS_FMT_YUV10_1X30</entry> + <entry>0x2014</entry> + <entry></entry> ++ <entry>-</entry> ++ <entry>-</entry> + <entry>y<subscript>9</subscript></entry> + <entry>y<subscript>8</subscript></entry> + <entry>y<subscript>7</subscript></entry> +@@ -2607,6 +2449,43 @@ + <entry>v<subscript>1</subscript></entry> + <entry>v<subscript>0</subscript></entry> + </row> ++ <row id="V4L2-MBUS-FMT-AYUV8-1X32"> ++ <entry>V4L2_MBUS_FMT_AYUV8_1X32</entry> ++ <entry>0x2017</entry> ++ <entry></entry> ++ <entry>a<subscript>7</subscript></entry> ++ <entry>a<subscript>6</subscript></entry> ++ <entry>a<subscript>5</subscript></entry> ++ <entry>a<subscript>4</subscript></entry> ++ <entry>a<subscript>3</subscript></entry> ++ <entry>a<subscript>2</subscript></entry> ++ <entry>a<subscript>1</subscript></entry> ++ <entry>a<subscript>0</subscript></entry> ++ <entry>y<subscript>7</subscript></entry> ++ <entry>y<subscript>6</subscript></entry> ++ <entry>y<subscript>5</subscript></entry> ++ <entry>y<subscript>4</subscript></entry> ++ <entry>y<subscript>3</subscript></entry> ++ <entry>y<subscript>2</subscript></entry> ++ <entry>y<subscript>1</subscript></entry> ++ <entry>y<subscript>0</subscript></entry> ++ <entry>u<subscript>7</subscript></entry> ++ <entry>u<subscript>6</subscript></entry> ++ <entry>u<subscript>5</subscript></entry> ++ <entry>u<subscript>4</subscript></entry> ++ <entry>u<subscript>3</subscript></entry> ++ <entry>u<subscript>2</subscript></entry> ++ <entry>u<subscript>1</subscript></entry> ++ <entry>u<subscript>0</subscript></entry> ++ <entry>v<subscript>7</subscript></entry> ++ <entry>v<subscript>6</subscript></entry> ++ <entry>v<subscript>5</subscript></entry> ++ <entry>v<subscript>4</subscript></entry> ++ <entry>v<subscript>3</subscript></entry> ++ <entry>v<subscript>2</subscript></entry> ++ <entry>v<subscript>1</subscript></entry> ++ <entry>v<subscript>0</subscript></entry> ++ </row> + </tbody> + </tgroup> + </table> +diff --git a/Documentation/DocBook/media_api.tmpl b/Documentation/DocBook/media_api.tmpl +index 9c92bb879b6d..4c8d282545a2 100644 +--- a/Documentation/DocBook/media_api.tmpl ++++ b/Documentation/DocBook/media_api.tmpl +@@ -22,8 +22,14 @@ + + <!-- LinuxTV v4l-dvb repository. --> + <!ENTITY v4l-dvb "<ulink url='http://linuxtv.org/repo/'>http://linuxtv.org/repo/</ulink>"> ++<!ENTITY dash-ent-8 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>"> + <!ENTITY dash-ent-10 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>"> ++<!ENTITY dash-ent-12 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>"> ++<!ENTITY dash-ent-14 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>"> + <!ENTITY dash-ent-16 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>"> ++<!ENTITY dash-ent-20 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>"> ++<!ENTITY dash-ent-22 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>"> ++<!ENTITY dash-ent-24 "<entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry><entry>-</entry>"> + ]> + + <book id="media_api"> +diff --git a/include/uapi/linux/v4l2-mediabus.h b/include/uapi/linux/v4l2-mediabus.h +index 6ee63d09b32d..a9601257bb43 100644 +--- a/include/uapi/linux/v4l2-mediabus.h ++++ b/include/uapi/linux/v4l2-mediabus.h +@@ -37,7 +37,7 @@ + enum v4l2_mbus_pixelcode { + V4L2_MBUS_FMT_FIXED = 0x0001, + +- /* RGB - next is 0x100d */ ++ /* RGB - next is 0x100e */ + V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE = 0x1001, + V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE = 0x1002, + V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE = 0x1003, +@@ -50,8 +50,9 @@ enum v4l2_mbus_pixelcode { + V4L2_MBUS_FMT_RGB888_1X24 = 0x100a, + V4L2_MBUS_FMT_RGB888_2X12_BE = 0x100b, + V4L2_MBUS_FMT_RGB888_2X12_LE = 0x100c, ++ V4L2_MBUS_FMT_ARGB8888_1X32 = 0x100d, + +- /* YUV (including grey) - next is 0x2017 */ ++ /* YUV (including grey) - next is 0x2018 */ + V4L2_MBUS_FMT_Y8_1X8 = 0x2001, + V4L2_MBUS_FMT_UV8_1X8 = 0x2015, + V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002, +@@ -74,6 +75,7 @@ enum v4l2_mbus_pixelcode { + V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d, + V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e, + V4L2_MBUS_FMT_YUV10_1X30 = 0x2016, ++ V4L2_MBUS_FMT_AYUV8_1X32 = 0x2017, + + /* Bayer - next is 0x3019 */ + V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001, +-- +1.8.5.rc3 + diff --git a/patches.renesas/0036-media-v4l-Add-V4L2_PIX_FMT_NV16M-and-V4L2_PIX_FMT_NV.patch b/patches.renesas/0036-media-v4l-Add-V4L2_PIX_FMT_NV16M-and-V4L2_PIX_FMT_NV.patch new file mode 100644 index 00000000000000..a98d19cf493261 --- /dev/null +++ b/patches.renesas/0036-media-v4l-Add-V4L2_PIX_FMT_NV16M-and-V4L2_PIX_FMT_NV.patch @@ -0,0 +1,229 @@ +From 0c9ce7436f24244b7506636d991007e9580eacca Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Wed, 26 Jun 2013 09:46:42 -0300 +Subject: [media] v4l: Add V4L2_PIX_FMT_NV16M and V4L2_PIX_FMT_NV61M formats + +NV16M and NV61M are planar YCbCr 4:2:2 and YCrCb 4:2:2 formats with a +luma plane followed by an interleaved chroma plane. The planes are not +required to be contiguous in memory, and the formats can only be used +with the multi-planar formats API. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Reviewed-by: Sylwester Nawrocki <s.nawrocki@samsung.com> +Reviewed-by: Sakari Ailus <sakari.ailus@iki.fi> +Acked-by: Hans Verkuil <hans.verkuil@cisco.com> +Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> +(cherry picked from commit 8493054844145e47a8f0668f57e2b0073aca850f) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + Documentation/DocBook/media/v4l/pixfmt-nv16m.xml | 171 +++++++++++++++++++++++ + Documentation/DocBook/media/v4l/pixfmt.xml | 1 + + include/uapi/linux/videodev2.h | 2 + + 3 files changed, 174 insertions(+) + create mode 100644 Documentation/DocBook/media/v4l/pixfmt-nv16m.xml + +diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv16m.xml b/Documentation/DocBook/media/v4l/pixfmt-nv16m.xml +new file mode 100644 +index 000000000000..c51d5a4cda09 +--- /dev/null ++++ b/Documentation/DocBook/media/v4l/pixfmt-nv16m.xml +@@ -0,0 +1,171 @@ ++ <refentry> ++ <refmeta> ++ <refentrytitle>V4L2_PIX_FMT_NV16M ('NM16'), V4L2_PIX_FMT_NV61M ('NM61')</refentrytitle> ++ &manvol; ++ </refmeta> ++ <refnamediv> ++ <refname id="V4L2-PIX-FMT-NV16M"><constant>V4L2_PIX_FMT_NV16M</constant></refname> ++ <refname id="V4L2-PIX-FMT-NV61M"><constant>V4L2_PIX_FMT_NV61M</constant></refname> ++ <refpurpose>Variation of <constant>V4L2_PIX_FMT_NV16</constant> and <constant>V4L2_PIX_FMT_NV61</constant> with planes ++ non contiguous in memory. </refpurpose> ++ </refnamediv> ++ <refsect1> ++ <title>Description</title> ++ ++ <para>This is a multi-planar, two-plane version of the YUV 4:2:0 format. ++The three components are separated into two sub-images or planes. ++<constant>V4L2_PIX_FMT_NV16M</constant> differs from <constant>V4L2_PIX_FMT_NV16 ++</constant> in that the two planes are non-contiguous in memory, i.e. the chroma ++plane does not necessarily immediately follows the luma plane. ++The luminance data occupies the first plane. The Y plane has one byte per pixel. ++In the second plane there is chrominance data with alternating chroma samples. ++The CbCr plane is the same width and height, in bytes, as the Y plane. ++Each CbCr pair belongs to four pixels. For example, ++Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to ++Y'<subscript>00</subscript>, Y'<subscript>01</subscript>, ++Y'<subscript>10</subscript>, Y'<subscript>11</subscript>. ++<constant>V4L2_PIX_FMT_NV61M</constant> is the same as <constant>V4L2_PIX_FMT_NV16M</constant> ++except the Cb and Cr bytes are swapped, the CrCb plane starts with a Cr byte.</para> ++ ++ <para><constant>V4L2_PIX_FMT_NV16M</constant> and ++<constant>V4L2_PIX_FMT_NV61M</constant> are intended to be used only in drivers ++and applications that support the multi-planar API, described in ++<xref linkend="planar-apis"/>. </para> ++ ++ <example> ++ <title><constant>V4L2_PIX_FMT_NV16M</constant> 4 × 4 pixel image</title> ++ ++ <formalpara> ++ <title>Byte Order.</title> ++ <para>Each cell is one byte. ++ <informaltable frame="none"> ++ <tgroup cols="5" align="center"> ++ <colspec align="left" colwidth="2*" /> ++ <tbody valign="top"> ++ <row> ++ <entry>start0 + 0:</entry> ++ <entry>Y'<subscript>00</subscript></entry> ++ <entry>Y'<subscript>01</subscript></entry> ++ <entry>Y'<subscript>02</subscript></entry> ++ <entry>Y'<subscript>03</subscript></entry> ++ </row> ++ <row> ++ <entry>start0 + 4:</entry> ++ <entry>Y'<subscript>10</subscript></entry> ++ <entry>Y'<subscript>11</subscript></entry> ++ <entry>Y'<subscript>12</subscript></entry> ++ <entry>Y'<subscript>13</subscript></entry> ++ </row> ++ <row> ++ <entry>start0 + 8:</entry> ++ <entry>Y'<subscript>20</subscript></entry> ++ <entry>Y'<subscript>21</subscript></entry> ++ <entry>Y'<subscript>22</subscript></entry> ++ <entry>Y'<subscript>23</subscript></entry> ++ </row> ++ <row> ++ <entry>start0 + 12:</entry> ++ <entry>Y'<subscript>30</subscript></entry> ++ <entry>Y'<subscript>31</subscript></entry> ++ <entry>Y'<subscript>32</subscript></entry> ++ <entry>Y'<subscript>33</subscript></entry> ++ </row> ++ <row> ++ <entry></entry> ++ </row> ++ <row> ++ <entry>start1 + 0:</entry> ++ <entry>Cb<subscript>00</subscript></entry> ++ <entry>Cr<subscript>00</subscript></entry> ++ <entry>Cb<subscript>02</subscript></entry> ++ <entry>Cr<subscript>02</subscript></entry> ++ </row> ++ <row> ++ <entry>start1 + 4:</entry> ++ <entry>Cb<subscript>10</subscript></entry> ++ <entry>Cr<subscript>10</subscript></entry> ++ <entry>Cb<subscript>12</subscript></entry> ++ <entry>Cr<subscript>12</subscript></entry> ++ </row> ++ <row> ++ <entry>start1 + 8:</entry> ++ <entry>Cb<subscript>20</subscript></entry> ++ <entry>Cr<subscript>20</subscript></entry> ++ <entry>Cb<subscript>22</subscript></entry> ++ <entry>Cr<subscript>22</subscript></entry> ++ </row> ++ <row> ++ <entry>start1 + 12:</entry> ++ <entry>Cb<subscript>30</subscript></entry> ++ <entry>Cr<subscript>30</subscript></entry> ++ <entry>Cb<subscript>32</subscript></entry> ++ <entry>Cr<subscript>32</subscript></entry> ++ </row> ++ </tbody> ++ </tgroup> ++ </informaltable> ++ </para> ++ </formalpara> ++ ++ <formalpara> ++ <title>Color Sample Location.</title> ++ <para> ++ <informaltable frame="none"> ++ <tgroup cols="7" align="center"> ++ <tbody valign="top"> ++ <row> ++ <entry></entry> ++ <entry>0</entry><entry></entry><entry>1</entry><entry></entry> ++ <entry>2</entry><entry></entry><entry>3</entry> ++ </row> ++ <row> ++ <entry>0</entry> ++ <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry> ++ <entry>Y</entry><entry></entry><entry>Y</entry> ++ </row> ++ <row> ++ <entry></entry> ++ <entry></entry><entry>C</entry><entry></entry><entry></entry> ++ <entry></entry><entry>C</entry><entry></entry> ++ </row> ++ <row> ++ <entry>1</entry> ++ <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry> ++ <entry>Y</entry><entry></entry><entry>Y</entry> ++ </row> ++ <row> ++ <entry></entry> ++ <entry></entry><entry>C</entry><entry></entry><entry></entry> ++ <entry></entry><entry>C</entry><entry></entry> ++ </row> ++ <row> ++ <entry></entry> ++ </row> ++ <row> ++ <entry>2</entry> ++ <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry> ++ <entry>Y</entry><entry></entry><entry>Y</entry> ++ </row> ++ <row> ++ <entry></entry> ++ <entry></entry><entry>C</entry><entry></entry><entry></entry> ++ <entry></entry><entry>C</entry><entry></entry> ++ </row> ++ <row> ++ <entry>3</entry> ++ <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry> ++ <entry>Y</entry><entry></entry><entry>Y</entry> ++ </row> ++ <row> ++ <entry></entry> ++ <entry></entry><entry>C</entry><entry></entry><entry></entry> ++ <entry></entry><entry>C</entry><entry></entry> ++ </row> ++ </tbody> ++ </tgroup> ++ </informaltable> ++ </para> ++ </formalpara> ++ </example> ++ </refsect1> ++ </refentry> +diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml b/Documentation/DocBook/media/v4l/pixfmt.xml +index 99b8d2ad6e4f..16db350848af 100644 +--- a/Documentation/DocBook/media/v4l/pixfmt.xml ++++ b/Documentation/DocBook/media/v4l/pixfmt.xml +@@ -718,6 +718,7 @@ information.</para> + &sub-nv12m; + &sub-nv12mt; + &sub-nv16; ++ &sub-nv16m; + &sub-nv24; + &sub-m420; + </section> +diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h +index f40b41c7e108..1e3cb4e5270e 100644 +--- a/include/uapi/linux/videodev2.h ++++ b/include/uapi/linux/videodev2.h +@@ -348,6 +348,8 @@ struct v4l2_pix_format { + /* two non contiguous planes - one Y, one Cr + Cb interleaved */ + #define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */ + #define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') /* 21 Y/CrCb 4:2:0 */ ++#define V4L2_PIX_FMT_NV16M v4l2_fourcc('N', 'M', '1', '6') /* 16 Y/CbCr 4:2:2 */ ++#define V4L2_PIX_FMT_NV61M v4l2_fourcc('N', 'M', '6', '1') /* 16 Y/CrCb 4:2:2 */ + #define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */ + #define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 16x16 macroblocks */ + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0037-media-v4l-Renesas-R-Car-VSP1-driver.patch b/patches.renesas/0037-media-v4l-Renesas-R-Car-VSP1-driver.patch new file mode 100644 index 00000000000000..8976b88e104fa7 --- /dev/null +++ b/patches.renesas/0037-media-v4l-Renesas-R-Car-VSP1-driver.patch @@ -0,0 +1,4121 @@ +From 91e2b07fe3c6e8a907265953ba2b0d0dc37ba360 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Tue, 4 Jun 2013 11:22:30 -0300 +Subject: [media] v4l: Renesas R-Car VSP1 driver + +The VSP1 is a video processing engine that includes a blender, scalers, +filters and statistics computation. Configurable data path routing logic +allows ordering the internal blocks in a flexible way. +Due to the configurable nature of the pipeline the driver implements the +media controller API and doesn't use the V4L2 mem-to-mem framework, even +though the device usually operates in memory to memory mode. +Only the read pixel formatters, up/down scalers, write pixel formatters +and LCDC interface are supported at this stage. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Sakari Ailus <sakari.ailus@iki.fi> +Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> +(cherry picked from commit 26e0ca22c3b85b04f693dd0422f13a61846ccfa9) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + + drivers/media/platform/vsp1/vsp1_video.c +--- + drivers/media/platform/Kconfig | 10 + + drivers/media/platform/Makefile | 2 + + drivers/media/platform/vsp1/Makefile | 5 + + drivers/media/platform/vsp1/vsp1.h | 73 ++ + drivers/media/platform/vsp1/vsp1_drv.c | 492 +++++++++++++ + drivers/media/platform/vsp1/vsp1_entity.c | 181 +++++ + drivers/media/platform/vsp1/vsp1_entity.h | 68 ++ + drivers/media/platform/vsp1/vsp1_lif.c | 238 +++++++ + drivers/media/platform/vsp1/vsp1_lif.h | 37 + + drivers/media/platform/vsp1/vsp1_regs.h | 581 ++++++++++++++++ + drivers/media/platform/vsp1/vsp1_rpf.c | 209 ++++++ + drivers/media/platform/vsp1/vsp1_rwpf.c | 124 ++++ + drivers/media/platform/vsp1/vsp1_rwpf.h | 53 ++ + drivers/media/platform/vsp1/vsp1_uds.c | 346 ++++++++++ + drivers/media/platform/vsp1/vsp1_uds.h | 40 ++ + drivers/media/platform/vsp1/vsp1_video.c | 1071 +++++++++++++++++++++++++++++ + drivers/media/platform/vsp1/vsp1_video.h | 144 ++++ + drivers/media/platform/vsp1/vsp1_wpf.c | 233 +++++++ + include/linux/platform_data/vsp1.h | 25 + + 19 files changed, 3932 insertions(+) + create mode 100644 drivers/media/platform/vsp1/Makefile + create mode 100644 drivers/media/platform/vsp1/vsp1.h + create mode 100644 drivers/media/platform/vsp1/vsp1_drv.c + create mode 100644 drivers/media/platform/vsp1/vsp1_entity.c + create mode 100644 drivers/media/platform/vsp1/vsp1_entity.h + create mode 100644 drivers/media/platform/vsp1/vsp1_lif.c + create mode 100644 drivers/media/platform/vsp1/vsp1_lif.h + create mode 100644 drivers/media/platform/vsp1/vsp1_regs.h + create mode 100644 drivers/media/platform/vsp1/vsp1_rpf.c + create mode 100644 drivers/media/platform/vsp1/vsp1_rwpf.c + create mode 100644 drivers/media/platform/vsp1/vsp1_rwpf.h + create mode 100644 drivers/media/platform/vsp1/vsp1_uds.c + create mode 100644 drivers/media/platform/vsp1/vsp1_uds.h + create mode 100644 drivers/media/platform/vsp1/vsp1_video.c + create mode 100644 drivers/media/platform/vsp1/vsp1_video.h + create mode 100644 drivers/media/platform/vsp1/vsp1_wpf.c + create mode 100644 include/linux/platform_data/vsp1.h + +diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig +index 0494d2769fd7..e4a3de5258b0 100644 +--- a/drivers/media/platform/Kconfig ++++ b/drivers/media/platform/Kconfig +@@ -210,6 +210,16 @@ config VIDEO_SH_VEU + Support for the Video Engine Unit (VEU) on SuperH and + SH-Mobile SoCs. + ++config VIDEO_RENESAS_VSP1 ++ tristate "Renesas VSP1 Video Processing Engine" ++ depends on VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API ++ select VIDEOBUF2_DMA_CONTIG ++ ---help--- ++ This is a V4L2 driver for the Renesas VSP1 video processing engine. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called vsp1. ++ + endif # V4L_MEM2MEM_DRIVERS + + menuconfig V4L_TEST_DRIVERS +diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile +index eee28dd78d7d..4e4da482c522 100644 +--- a/drivers/media/platform/Makefile ++++ b/drivers/media/platform/Makefile +@@ -46,6 +46,8 @@ obj-$(CONFIG_VIDEO_SH_VOU) += sh_vou.o + + obj-$(CONFIG_SOC_CAMERA) += soc_camera/ + ++obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1/ ++ + obj-y += davinci/ + + obj-$(CONFIG_ARCH_OMAP) += omap/ +diff --git a/drivers/media/platform/vsp1/Makefile b/drivers/media/platform/vsp1/Makefile +new file mode 100644 +index 000000000000..4da226169e15 +--- /dev/null ++++ b/drivers/media/platform/vsp1/Makefile +@@ -0,0 +1,5 @@ ++vsp1-y := vsp1_drv.o vsp1_entity.o vsp1_video.o ++vsp1-y += vsp1_rpf.o vsp1_rwpf.o vsp1_wpf.o ++vsp1-y += vsp1_lif.o vsp1_uds.o ++ ++obj-$(CONFIG_VIDEO_RENESAS_VSP1) += vsp1.o +diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h +new file mode 100644 +index 000000000000..11ac94bec3a3 +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1.h +@@ -0,0 +1,73 @@ ++/* ++ * vsp1.h -- R-Car VSP1 Driver ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++#ifndef __VSP1_H__ ++#define __VSP1_H__ ++ ++#include <linux/io.h> ++#include <linux/list.h> ++#include <linux/mutex.h> ++#include <linux/platform_data/vsp1.h> ++ ++#include <media/media-device.h> ++#include <media/v4l2-device.h> ++#include <media/v4l2-subdev.h> ++ ++#include "vsp1_regs.h" ++ ++struct clk; ++struct device; ++ ++struct vsp1_platform_data; ++struct vsp1_lif; ++struct vsp1_rwpf; ++struct vsp1_uds; ++ ++#define VPS1_MAX_RPF 5 ++#define VPS1_MAX_UDS 3 ++#define VPS1_MAX_WPF 4 ++ ++struct vsp1_device { ++ struct device *dev; ++ struct vsp1_platform_data *pdata; ++ ++ void __iomem *mmio; ++ struct clk *clock; ++ ++ struct mutex lock; ++ int ref_count; ++ ++ struct vsp1_lif *lif; ++ struct vsp1_rwpf *rpf[VPS1_MAX_RPF]; ++ struct vsp1_uds *uds[VPS1_MAX_UDS]; ++ struct vsp1_rwpf *wpf[VPS1_MAX_WPF]; ++ ++ struct list_head entities; ++ ++ struct v4l2_device v4l2_dev; ++ struct media_device media_dev; ++}; ++ ++struct vsp1_device *vsp1_device_get(struct vsp1_device *vsp1); ++void vsp1_device_put(struct vsp1_device *vsp1); ++ ++static inline u32 vsp1_read(struct vsp1_device *vsp1, u32 reg) ++{ ++ return ioread32(vsp1->mmio + reg); ++} ++ ++static inline void vsp1_write(struct vsp1_device *vsp1, u32 reg, u32 data) ++{ ++ iowrite32(data, vsp1->mmio + reg); ++} ++ ++#endif /* __VSP1_H__ */ +diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c +new file mode 100644 +index 000000000000..e58e49c88415 +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1_drv.c +@@ -0,0 +1,492 @@ ++/* ++ * vsp1_drv.c -- R-Car VSP1 Driver ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <linux/clk.h> ++#include <linux/delay.h> ++#include <linux/device.h> ++#include <linux/interrupt.h> ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/videodev2.h> ++ ++#include "vsp1.h" ++#include "vsp1_lif.h" ++#include "vsp1_rwpf.h" ++#include "vsp1_uds.h" ++ ++/* ----------------------------------------------------------------------------- ++ * Interrupt Handling ++ */ ++ ++static irqreturn_t vsp1_irq_handler(int irq, void *data) ++{ ++ u32 mask = VI6_WFP_IRQ_STA_DFE | VI6_WFP_IRQ_STA_FRE; ++ struct vsp1_device *vsp1 = data; ++ irqreturn_t ret = IRQ_NONE; ++ unsigned int i; ++ ++ for (i = 0; i < VPS1_MAX_WPF; ++i) { ++ struct vsp1_rwpf *wpf = vsp1->wpf[i]; ++ struct vsp1_pipeline *pipe; ++ u32 status; ++ ++ if (wpf == NULL) ++ continue; ++ ++ pipe = to_vsp1_pipeline(&wpf->entity.subdev.entity); ++ status = vsp1_read(vsp1, VI6_WPF_IRQ_STA(i)); ++ vsp1_write(vsp1, VI6_WPF_IRQ_STA(i), ~status & mask); ++ ++ if (status & VI6_WFP_IRQ_STA_FRE) { ++ vsp1_pipeline_frame_end(pipe); ++ ret = IRQ_HANDLED; ++ } ++ } ++ ++ return ret; ++} ++ ++/* ----------------------------------------------------------------------------- ++ * Entities ++ */ ++ ++/* ++ * vsp1_create_links - Create links from all sources to the given sink ++ * ++ * This function creates media links from all valid sources to the given sink ++ * pad. Links that would be invalid according to the VSP1 hardware capabilities ++ * are skipped. Those include all links ++ * ++ * - from a UDS to a UDS (UDS entities can't be chained) ++ * - from an entity to itself (no loops are allowed) ++ */ ++static int vsp1_create_links(struct vsp1_device *vsp1, struct vsp1_entity *sink) ++{ ++ struct media_entity *entity = &sink->subdev.entity; ++ struct vsp1_entity *source; ++ unsigned int pad; ++ int ret; ++ ++ list_for_each_entry(source, &vsp1->entities, list_dev) { ++ u32 flags; ++ ++ if (source->type == sink->type) ++ continue; ++ ++ if (source->type == VSP1_ENTITY_LIF || ++ source->type == VSP1_ENTITY_WPF) ++ continue; ++ ++ flags = source->type == VSP1_ENTITY_RPF && ++ sink->type == VSP1_ENTITY_WPF && ++ source->index == sink->index ++ ? MEDIA_LNK_FL_ENABLED : 0; ++ ++ for (pad = 0; pad < entity->num_pads; ++pad) { ++ if (!(entity->pads[pad].flags & MEDIA_PAD_FL_SINK)) ++ continue; ++ ++ ret = media_entity_create_link(&source->subdev.entity, ++ source->source_pad, ++ entity, pad, flags); ++ if (ret < 0) ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static void vsp1_destroy_entities(struct vsp1_device *vsp1) ++{ ++ struct vsp1_entity *entity; ++ struct vsp1_entity *next; ++ ++ list_for_each_entry_safe(entity, next, &vsp1->entities, list_dev) { ++ list_del(&entity->list_dev); ++ vsp1_entity_destroy(entity); ++ } ++ ++ v4l2_device_unregister(&vsp1->v4l2_dev); ++ media_device_unregister(&vsp1->media_dev); ++} ++ ++static int vsp1_create_entities(struct vsp1_device *vsp1) ++{ ++ struct media_device *mdev = &vsp1->media_dev; ++ struct v4l2_device *vdev = &vsp1->v4l2_dev; ++ struct vsp1_entity *entity; ++ unsigned int i; ++ int ret; ++ ++ mdev->dev = vsp1->dev; ++ strlcpy(mdev->model, "VSP1", sizeof(mdev->model)); ++ ret = media_device_register(mdev); ++ if (ret < 0) { ++ dev_err(vsp1->dev, "media device registration failed (%d)\n", ++ ret); ++ return ret; ++ } ++ ++ vdev->mdev = mdev; ++ ret = v4l2_device_register(vsp1->dev, vdev); ++ if (ret < 0) { ++ dev_err(vsp1->dev, "V4L2 device registration failed (%d)\n", ++ ret); ++ goto done; ++ } ++ ++ /* Instantiate all the entities. */ ++ if (vsp1->pdata->features & VSP1_HAS_LIF) { ++ vsp1->lif = vsp1_lif_create(vsp1); ++ if (IS_ERR(vsp1->lif)) { ++ ret = PTR_ERR(vsp1->lif); ++ goto done; ++ } ++ ++ list_add_tail(&vsp1->lif->entity.list_dev, &vsp1->entities); ++ } ++ ++ for (i = 0; i < vsp1->pdata->rpf_count; ++i) { ++ struct vsp1_rwpf *rpf; ++ ++ rpf = vsp1_rpf_create(vsp1, i); ++ if (IS_ERR(rpf)) { ++ ret = PTR_ERR(rpf); ++ goto done; ++ } ++ ++ vsp1->rpf[i] = rpf; ++ list_add_tail(&rpf->entity.list_dev, &vsp1->entities); ++ } ++ ++ for (i = 0; i < vsp1->pdata->uds_count; ++i) { ++ struct vsp1_uds *uds; ++ ++ uds = vsp1_uds_create(vsp1, i); ++ if (IS_ERR(uds)) { ++ ret = PTR_ERR(uds); ++ goto done; ++ } ++ ++ vsp1->uds[i] = uds; ++ list_add_tail(&uds->entity.list_dev, &vsp1->entities); ++ } ++ ++ for (i = 0; i < vsp1->pdata->wpf_count; ++i) { ++ struct vsp1_rwpf *wpf; ++ ++ wpf = vsp1_wpf_create(vsp1, i); ++ if (IS_ERR(wpf)) { ++ ret = PTR_ERR(wpf); ++ goto done; ++ } ++ ++ vsp1->wpf[i] = wpf; ++ list_add_tail(&wpf->entity.list_dev, &vsp1->entities); ++ } ++ ++ /* Create links. */ ++ list_for_each_entry(entity, &vsp1->entities, list_dev) { ++ if (entity->type == VSP1_ENTITY_LIF || ++ entity->type == VSP1_ENTITY_RPF) ++ continue; ++ ++ ret = vsp1_create_links(vsp1, entity); ++ if (ret < 0) ++ goto done; ++ } ++ ++ if (vsp1->pdata->features & VSP1_HAS_LIF) { ++ ret = media_entity_create_link( ++ &vsp1->wpf[0]->entity.subdev.entity, RWPF_PAD_SOURCE, ++ &vsp1->lif->entity.subdev.entity, LIF_PAD_SINK, 0); ++ if (ret < 0) ++ return ret; ++ } ++ ++ /* Register all subdevs. */ ++ list_for_each_entry(entity, &vsp1->entities, list_dev) { ++ ret = v4l2_device_register_subdev(&vsp1->v4l2_dev, ++ &entity->subdev); ++ if (ret < 0) ++ goto done; ++ } ++ ++ ret = v4l2_device_register_subdev_nodes(&vsp1->v4l2_dev); ++ ++done: ++ if (ret < 0) ++ vsp1_destroy_entities(vsp1); ++ ++ return ret; ++} ++ ++static int vsp1_device_init(struct vsp1_device *vsp1) ++{ ++ unsigned int i; ++ u32 status; ++ ++ /* Reset any channel that might be running. */ ++ status = vsp1_read(vsp1, VI6_STATUS); ++ ++ for (i = 0; i < VPS1_MAX_WPF; ++i) { ++ unsigned int timeout; ++ ++ if (!(status & VI6_STATUS_SYS_ACT(i))) ++ continue; ++ ++ vsp1_write(vsp1, VI6_SRESET, VI6_SRESET_SRTS(i)); ++ for (timeout = 10; timeout > 0; --timeout) { ++ status = vsp1_read(vsp1, VI6_STATUS); ++ if (!(status & VI6_STATUS_SYS_ACT(i))) ++ break; ++ ++ usleep_range(1000, 2000); ++ } ++ ++ if (!timeout) { ++ dev_err(vsp1->dev, "failed to reset wpf.%u\n", i); ++ return -ETIMEDOUT; ++ } ++ } ++ ++ vsp1_write(vsp1, VI6_CLK_DCSWT, (8 << VI6_CLK_DCSWT_CSTPW_SHIFT) | ++ (8 << VI6_CLK_DCSWT_CSTRW_SHIFT)); ++ ++ for (i = 0; i < VPS1_MAX_RPF; ++i) ++ vsp1_write(vsp1, VI6_DPR_RPF_ROUTE(i), VI6_DPR_NODE_UNUSED); ++ ++ for (i = 0; i < VPS1_MAX_UDS; ++i) ++ vsp1_write(vsp1, VI6_DPR_UDS_ROUTE(i), VI6_DPR_NODE_UNUSED); ++ ++ vsp1_write(vsp1, VI6_DPR_SRU_ROUTE, VI6_DPR_NODE_UNUSED); ++ vsp1_write(vsp1, VI6_DPR_LUT_ROUTE, VI6_DPR_NODE_UNUSED); ++ vsp1_write(vsp1, VI6_DPR_CLU_ROUTE, VI6_DPR_NODE_UNUSED); ++ vsp1_write(vsp1, VI6_DPR_HST_ROUTE, VI6_DPR_NODE_UNUSED); ++ vsp1_write(vsp1, VI6_DPR_HSI_ROUTE, VI6_DPR_NODE_UNUSED); ++ vsp1_write(vsp1, VI6_DPR_BRU_ROUTE, VI6_DPR_NODE_UNUSED); ++ ++ vsp1_write(vsp1, VI6_DPR_HGO_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) | ++ (VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT)); ++ vsp1_write(vsp1, VI6_DPR_HGT_SMPPT, (7 << VI6_DPR_SMPPT_TGW_SHIFT) | ++ (VI6_DPR_NODE_UNUSED << VI6_DPR_SMPPT_PT_SHIFT)); ++ ++ return 0; ++} ++ ++/* ++ * vsp1_device_get - Acquire the VSP1 device ++ * ++ * Increment the VSP1 reference count and initialize the device if the first ++ * reference is taken. ++ * ++ * Return a pointer to the VSP1 device or NULL if an error occured. ++ */ ++struct vsp1_device *vsp1_device_get(struct vsp1_device *vsp1) ++{ ++ struct vsp1_device *__vsp1 = vsp1; ++ int ret; ++ ++ mutex_lock(&vsp1->lock); ++ if (vsp1->ref_count > 0) ++ goto done; ++ ++ ret = clk_prepare_enable(vsp1->clock); ++ if (ret < 0) { ++ __vsp1 = NULL; ++ goto done; ++ } ++ ++ ret = vsp1_device_init(vsp1); ++ if (ret < 0) { ++ clk_disable_unprepare(vsp1->clock); ++ __vsp1 = NULL; ++ goto done; ++ } ++ ++done: ++ if (__vsp1) ++ vsp1->ref_count++; ++ ++ mutex_unlock(&vsp1->lock); ++ return __vsp1; ++} ++ ++/* ++ * vsp1_device_put - Release the VSP1 device ++ * ++ * Decrement the VSP1 reference count and cleanup the device if the last ++ * reference is released. ++ */ ++void vsp1_device_put(struct vsp1_device *vsp1) ++{ ++ mutex_lock(&vsp1->lock); ++ ++ if (--vsp1->ref_count == 0) ++ clk_disable_unprepare(vsp1->clock); ++ ++ mutex_unlock(&vsp1->lock); ++} ++ ++/* ----------------------------------------------------------------------------- ++ * Power Management ++ */ ++ ++#ifdef CONFIG_PM_SLEEP ++static int vsp1_pm_suspend(struct device *dev) ++{ ++ struct vsp1_device *vsp1 = dev_get_drvdata(dev); ++ ++ WARN_ON(mutex_is_locked(&vsp1->lock)); ++ ++ if (vsp1->ref_count == 0) ++ return 0; ++ ++ clk_disable_unprepare(vsp1->clock); ++ return 0; ++} ++ ++static int vsp1_pm_resume(struct device *dev) ++{ ++ struct vsp1_device *vsp1 = dev_get_drvdata(dev); ++ ++ WARN_ON(mutex_is_locked(&vsp1->lock)); ++ ++ if (vsp1->ref_count) ++ return 0; ++ ++ return clk_prepare_enable(vsp1->clock); ++} ++#endif ++ ++static const struct dev_pm_ops vsp1_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(vsp1_pm_suspend, vsp1_pm_resume) ++}; ++ ++/* ----------------------------------------------------------------------------- ++ * Platform Driver ++ */ ++ ++static struct vsp1_platform_data * ++vsp1_get_platform_data(struct platform_device *pdev) ++{ ++ struct vsp1_platform_data *pdata = pdev->dev.platform_data; ++ ++ if (pdata == NULL) { ++ dev_err(&pdev->dev, "missing platform data\n"); ++ return NULL; ++ } ++ ++ if (pdata->rpf_count <= 0 || pdata->rpf_count > VPS1_MAX_RPF) { ++ dev_err(&pdev->dev, "invalid number of RPF (%u)\n", ++ pdata->rpf_count); ++ return NULL; ++ } ++ ++ if (pdata->uds_count <= 0 || pdata->uds_count > VPS1_MAX_UDS) { ++ dev_err(&pdev->dev, "invalid number of UDS (%u)\n", ++ pdata->uds_count); ++ return NULL; ++ } ++ ++ if (pdata->wpf_count <= 0 || pdata->wpf_count > VPS1_MAX_WPF) { ++ dev_err(&pdev->dev, "invalid number of WPF (%u)\n", ++ pdata->wpf_count); ++ return NULL; ++ } ++ ++ return pdata; ++} ++ ++static int vsp1_probe(struct platform_device *pdev) ++{ ++ struct vsp1_device *vsp1; ++ struct resource *irq; ++ struct resource *io; ++ int ret; ++ ++ vsp1 = devm_kzalloc(&pdev->dev, sizeof(*vsp1), GFP_KERNEL); ++ if (vsp1 == NULL) ++ return -ENOMEM; ++ ++ vsp1->dev = &pdev->dev; ++ mutex_init(&vsp1->lock); ++ INIT_LIST_HEAD(&vsp1->entities); ++ ++ vsp1->pdata = vsp1_get_platform_data(pdev); ++ if (vsp1->pdata == NULL) ++ return -ENODEV; ++ ++ /* I/O, IRQ and clock resources */ ++ io = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ vsp1->mmio = devm_ioremap_resource(&pdev->dev, io); ++ if (IS_ERR((void *)vsp1->mmio)) ++ return PTR_ERR((void *)vsp1->mmio); ++ ++ vsp1->clock = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(vsp1->clock)) { ++ dev_err(&pdev->dev, "failed to get clock\n"); ++ return PTR_ERR(vsp1->clock); ++ } ++ ++ irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); ++ if (!irq) { ++ dev_err(&pdev->dev, "missing IRQ\n"); ++ return -EINVAL; ++ } ++ ++ ret = devm_request_irq(&pdev->dev, irq->start, vsp1_irq_handler, ++ IRQF_SHARED, dev_name(&pdev->dev), vsp1); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "failed to request IRQ\n"); ++ return ret; ++ } ++ ++ /* Instanciate entities */ ++ ret = vsp1_create_entities(vsp1); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "failed to create entities\n"); ++ return ret; ++ } ++ ++ platform_set_drvdata(pdev, vsp1); ++ ++ return 0; ++} ++ ++static int vsp1_remove(struct platform_device *pdev) ++{ ++ struct vsp1_device *vsp1 = platform_get_drvdata(pdev); ++ ++ vsp1_destroy_entities(vsp1); ++ ++ return 0; ++} ++ ++static struct platform_driver vsp1_platform_driver = { ++ .probe = vsp1_probe, ++ .remove = vsp1_remove, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "vsp1", ++ .pm = &vsp1_pm_ops, ++ }, ++}; ++ ++module_platform_driver(vsp1_platform_driver); ++ ++MODULE_ALIAS("vsp1"); ++MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); ++MODULE_DESCRIPTION("Renesas VSP1 Driver"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/media/platform/vsp1/vsp1_entity.c b/drivers/media/platform/vsp1/vsp1_entity.c +new file mode 100644 +index 000000000000..9028f9d524f4 +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1_entity.c +@@ -0,0 +1,181 @@ ++/* ++ * vsp1_entity.c -- R-Car VSP1 Base Entity ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <linux/device.h> ++#include <linux/gfp.h> ++ ++#include <media/media-entity.h> ++#include <media/v4l2-subdev.h> ++ ++#include "vsp1.h" ++#include "vsp1_entity.h" ++ ++/* ----------------------------------------------------------------------------- ++ * V4L2 Subdevice Operations ++ */ ++ ++struct v4l2_mbus_framefmt * ++vsp1_entity_get_pad_format(struct vsp1_entity *entity, ++ struct v4l2_subdev_fh *fh, ++ unsigned int pad, u32 which) ++{ ++ switch (which) { ++ case V4L2_SUBDEV_FORMAT_TRY: ++ return v4l2_subdev_get_try_format(fh, pad); ++ case V4L2_SUBDEV_FORMAT_ACTIVE: ++ return &entity->formats[pad]; ++ default: ++ return NULL; ++ } ++} ++ ++/* ++ * vsp1_entity_init_formats - Initialize formats on all pads ++ * @subdev: V4L2 subdevice ++ * @fh: V4L2 subdev file handle ++ * ++ * Initialize all pad formats with default values. If fh is not NULL, try ++ * formats are initialized on the file handle. Otherwise active formats are ++ * initialized on the device. ++ */ ++void vsp1_entity_init_formats(struct v4l2_subdev *subdev, ++ struct v4l2_subdev_fh *fh) ++{ ++ struct v4l2_subdev_format format; ++ unsigned int pad; ++ ++ for (pad = 0; pad < subdev->entity.num_pads - 1; ++pad) { ++ memset(&format, 0, sizeof(format)); ++ ++ format.pad = pad; ++ format.which = fh ? V4L2_SUBDEV_FORMAT_TRY ++ : V4L2_SUBDEV_FORMAT_ACTIVE; ++ ++ v4l2_subdev_call(subdev, pad, set_fmt, fh, &format); ++ } ++} ++ ++static int vsp1_entity_open(struct v4l2_subdev *subdev, ++ struct v4l2_subdev_fh *fh) ++{ ++ vsp1_entity_init_formats(subdev, fh); ++ ++ return 0; ++} ++ ++const struct v4l2_subdev_internal_ops vsp1_subdev_internal_ops = { ++ .open = vsp1_entity_open, ++}; ++ ++/* ----------------------------------------------------------------------------- ++ * Media Operations ++ */ ++ ++static int vsp1_entity_link_setup(struct media_entity *entity, ++ const struct media_pad *local, ++ const struct media_pad *remote, u32 flags) ++{ ++ struct vsp1_entity *source; ++ ++ if (!(local->flags & MEDIA_PAD_FL_SOURCE)) ++ return 0; ++ ++ source = container_of(local->entity, struct vsp1_entity, subdev.entity); ++ ++ if (!source->route) ++ return 0; ++ ++ if (flags & MEDIA_LNK_FL_ENABLED) { ++ if (source->sink) ++ return -EBUSY; ++ source->sink = remote->entity; ++ } else { ++ source->sink = NULL; ++ } ++ ++ return 0; ++} ++ ++const struct media_entity_operations vsp1_media_ops = { ++ .link_setup = vsp1_entity_link_setup, ++ .link_validate = v4l2_subdev_link_validate, ++}; ++ ++/* ----------------------------------------------------------------------------- ++ * Initialization ++ */ ++ ++int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, ++ unsigned int num_pads) ++{ ++ static const struct { ++ unsigned int id; ++ unsigned int reg; ++ } routes[] = { ++ { VI6_DPR_NODE_LIF, 0 }, ++ { VI6_DPR_NODE_RPF(0), VI6_DPR_RPF_ROUTE(0) }, ++ { VI6_DPR_NODE_RPF(1), VI6_DPR_RPF_ROUTE(1) }, ++ { VI6_DPR_NODE_RPF(2), VI6_DPR_RPF_ROUTE(2) }, ++ { VI6_DPR_NODE_RPF(3), VI6_DPR_RPF_ROUTE(3) }, ++ { VI6_DPR_NODE_RPF(4), VI6_DPR_RPF_ROUTE(4) }, ++ { VI6_DPR_NODE_UDS(0), VI6_DPR_UDS_ROUTE(0) }, ++ { VI6_DPR_NODE_UDS(1), VI6_DPR_UDS_ROUTE(1) }, ++ { VI6_DPR_NODE_UDS(2), VI6_DPR_UDS_ROUTE(2) }, ++ { VI6_DPR_NODE_WPF(0), 0 }, ++ { VI6_DPR_NODE_WPF(1), 0 }, ++ { VI6_DPR_NODE_WPF(2), 0 }, ++ { VI6_DPR_NODE_WPF(3), 0 }, ++ }; ++ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(routes); ++i) { ++ if (routes[i].id == entity->id) { ++ entity->route = routes[i].reg; ++ break; ++ } ++ } ++ ++ if (i == ARRAY_SIZE(routes)) ++ return -EINVAL; ++ ++ entity->vsp1 = vsp1; ++ entity->source_pad = num_pads - 1; ++ ++ /* Allocate formats and pads. */ ++ entity->formats = devm_kzalloc(vsp1->dev, ++ num_pads * sizeof(*entity->formats), ++ GFP_KERNEL); ++ if (entity->formats == NULL) ++ return -ENOMEM; ++ ++ entity->pads = devm_kzalloc(vsp1->dev, num_pads * sizeof(*entity->pads), ++ GFP_KERNEL); ++ if (entity->pads == NULL) ++ return -ENOMEM; ++ ++ /* Initialize pads. */ ++ for (i = 0; i < num_pads - 1; ++i) ++ entity->pads[i].flags = MEDIA_PAD_FL_SINK; ++ ++ entity->pads[num_pads - 1].flags = MEDIA_PAD_FL_SOURCE; ++ ++ /* Initialize the media entity. */ ++ return media_entity_init(&entity->subdev.entity, num_pads, ++ entity->pads, 0); ++} ++ ++void vsp1_entity_destroy(struct vsp1_entity *entity) ++{ ++ media_entity_cleanup(&entity->subdev.entity); ++} +diff --git a/drivers/media/platform/vsp1/vsp1_entity.h b/drivers/media/platform/vsp1/vsp1_entity.h +new file mode 100644 +index 000000000000..c4feab2cbb81 +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1_entity.h +@@ -0,0 +1,68 @@ ++/* ++ * vsp1_entity.h -- R-Car VSP1 Base Entity ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++#ifndef __VSP1_ENTITY_H__ ++#define __VSP1_ENTITY_H__ ++ ++#include <linux/list.h> ++ ++#include <media/v4l2-subdev.h> ++ ++struct vsp1_device; ++ ++enum vsp1_entity_type { ++ VSP1_ENTITY_LIF, ++ VSP1_ENTITY_RPF, ++ VSP1_ENTITY_UDS, ++ VSP1_ENTITY_WPF, ++}; ++ ++struct vsp1_entity { ++ struct vsp1_device *vsp1; ++ ++ enum vsp1_entity_type type; ++ unsigned int index; ++ unsigned int id; ++ unsigned int route; ++ ++ struct list_head list_dev; ++ struct list_head list_pipe; ++ ++ struct media_pad *pads; ++ unsigned int source_pad; ++ ++ struct media_entity *sink; ++ ++ struct v4l2_subdev subdev; ++ struct v4l2_mbus_framefmt *formats; ++}; ++ ++static inline struct vsp1_entity *to_vsp1_entity(struct v4l2_subdev *subdev) ++{ ++ return container_of(subdev, struct vsp1_entity, subdev); ++} ++ ++int vsp1_entity_init(struct vsp1_device *vsp1, struct vsp1_entity *entity, ++ unsigned int num_pads); ++void vsp1_entity_destroy(struct vsp1_entity *entity); ++ ++extern const struct v4l2_subdev_internal_ops vsp1_subdev_internal_ops; ++extern const struct media_entity_operations vsp1_media_ops; ++ ++struct v4l2_mbus_framefmt * ++vsp1_entity_get_pad_format(struct vsp1_entity *entity, ++ struct v4l2_subdev_fh *fh, ++ unsigned int pad, u32 which); ++void vsp1_entity_init_formats(struct v4l2_subdev *subdev, ++ struct v4l2_subdev_fh *fh); ++ ++#endif /* __VSP1_ENTITY_H__ */ +diff --git a/drivers/media/platform/vsp1/vsp1_lif.c b/drivers/media/platform/vsp1/vsp1_lif.c +new file mode 100644 +index 000000000000..74a32e69ef10 +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1_lif.c +@@ -0,0 +1,238 @@ ++/* ++ * vsp1_lif.c -- R-Car VSP1 LCD Controller Interface ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <linux/device.h> ++#include <linux/gfp.h> ++ ++#include <media/v4l2-subdev.h> ++ ++#include "vsp1.h" ++#include "vsp1_lif.h" ++ ++#define LIF_MIN_SIZE 2U ++#define LIF_MAX_SIZE 2048U ++ ++/* ----------------------------------------------------------------------------- ++ * Device Access ++ */ ++ ++static inline u32 vsp1_lif_read(struct vsp1_lif *lif, u32 reg) ++{ ++ return vsp1_read(lif->entity.vsp1, reg); ++} ++ ++static inline void vsp1_lif_write(struct vsp1_lif *lif, u32 reg, u32 data) ++{ ++ vsp1_write(lif->entity.vsp1, reg, data); ++} ++ ++/* ----------------------------------------------------------------------------- ++ * V4L2 Subdevice Core Operations ++ */ ++ ++static int lif_s_stream(struct v4l2_subdev *subdev, int enable) ++{ ++ const struct v4l2_mbus_framefmt *format; ++ struct vsp1_lif *lif = to_lif(subdev); ++ unsigned int hbth = 1300; ++ unsigned int obth = 400; ++ unsigned int lbth = 200; ++ ++ if (!enable) { ++ vsp1_lif_write(lif, VI6_LIF_CTRL, 0); ++ return 0; ++ } ++ ++ format = &lif->entity.formats[LIF_PAD_SOURCE]; ++ ++ obth = min(obth, (format->width + 1) / 2 * format->height - 4); ++ ++ vsp1_lif_write(lif, VI6_LIF_CSBTH, ++ (hbth << VI6_LIF_CSBTH_HBTH_SHIFT) | ++ (lbth << VI6_LIF_CSBTH_LBTH_SHIFT)); ++ ++ vsp1_lif_write(lif, VI6_LIF_CTRL, ++ (obth << VI6_LIF_CTRL_OBTH_SHIFT) | ++ (format->code == 0 ? VI6_LIF_CTRL_CFMT : 0) | ++ VI6_LIF_CTRL_REQSEL | VI6_LIF_CTRL_LIF_EN); ++ ++ return 0; ++} ++ ++/* ----------------------------------------------------------------------------- ++ * V4L2 Subdevice Pad Operations ++ */ ++ ++static int lif_enum_mbus_code(struct v4l2_subdev *subdev, ++ struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_mbus_code_enum *code) ++{ ++ static const unsigned int codes[] = { ++ V4L2_MBUS_FMT_ARGB8888_1X32, ++ V4L2_MBUS_FMT_AYUV8_1X32, ++ }; ++ ++ if (code->pad == LIF_PAD_SINK) { ++ if (code->index >= ARRAY_SIZE(codes)) ++ return -EINVAL; ++ ++ code->code = codes[code->index]; ++ } else { ++ struct v4l2_mbus_framefmt *format; ++ ++ /* The LIF can't perform format conversion, the sink format is ++ * always identical to the source format. ++ */ ++ if (code->index) ++ return -EINVAL; ++ ++ format = v4l2_subdev_get_try_format(fh, LIF_PAD_SINK); ++ code->code = format->code; ++ } ++ ++ return 0; ++} ++ ++static int lif_enum_frame_size(struct v4l2_subdev *subdev, ++ struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_frame_size_enum *fse) ++{ ++ struct v4l2_mbus_framefmt *format; ++ ++ format = v4l2_subdev_get_try_format(fh, LIF_PAD_SINK); ++ ++ if (fse->index || fse->code != format->code) ++ return -EINVAL; ++ ++ if (fse->pad == LIF_PAD_SINK) { ++ fse->min_width = LIF_MIN_SIZE; ++ fse->max_width = LIF_MAX_SIZE; ++ fse->min_height = LIF_MIN_SIZE; ++ fse->max_height = LIF_MAX_SIZE; ++ } else { ++ fse->min_width = format->width; ++ fse->max_width = format->width; ++ fse->min_height = format->height; ++ fse->max_height = format->height; ++ } ++ ++ return 0; ++} ++ ++static int lif_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_format *fmt) ++{ ++ struct vsp1_lif *lif = to_lif(subdev); ++ ++ fmt->format = *vsp1_entity_get_pad_format(&lif->entity, fh, fmt->pad, ++ fmt->which); ++ ++ return 0; ++} ++ ++static int lif_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_format *fmt) ++{ ++ struct vsp1_lif *lif = to_lif(subdev); ++ struct v4l2_mbus_framefmt *format; ++ ++ /* Default to YUV if the requested format is not supported. */ ++ if (fmt->format.code != V4L2_MBUS_FMT_ARGB8888_1X32 && ++ fmt->format.code != V4L2_MBUS_FMT_AYUV8_1X32) ++ fmt->format.code = V4L2_MBUS_FMT_AYUV8_1X32; ++ ++ format = vsp1_entity_get_pad_format(&lif->entity, fh, fmt->pad, ++ fmt->which); ++ ++ if (fmt->pad == LIF_PAD_SOURCE) { ++ /* The LIF source format is always identical to its sink ++ * format. ++ */ ++ fmt->format = *format; ++ return 0; ++ } ++ ++ format->code = fmt->format.code; ++ format->width = clamp_t(unsigned int, fmt->format.width, ++ LIF_MIN_SIZE, LIF_MAX_SIZE); ++ format->height = clamp_t(unsigned int, fmt->format.height, ++ LIF_MIN_SIZE, LIF_MAX_SIZE); ++ format->field = V4L2_FIELD_NONE; ++ format->colorspace = V4L2_COLORSPACE_SRGB; ++ ++ fmt->format = *format; ++ ++ /* Propagate the format to the source pad. */ ++ format = vsp1_entity_get_pad_format(&lif->entity, fh, LIF_PAD_SOURCE, ++ fmt->which); ++ *format = fmt->format; ++ ++ return 0; ++} ++ ++/* ----------------------------------------------------------------------------- ++ * V4L2 Subdevice Operations ++ */ ++ ++static struct v4l2_subdev_video_ops lif_video_ops = { ++ .s_stream = lif_s_stream, ++}; ++ ++static struct v4l2_subdev_pad_ops lif_pad_ops = { ++ .enum_mbus_code = lif_enum_mbus_code, ++ .enum_frame_size = lif_enum_frame_size, ++ .get_fmt = lif_get_format, ++ .set_fmt = lif_set_format, ++}; ++ ++static struct v4l2_subdev_ops lif_ops = { ++ .video = &lif_video_ops, ++ .pad = &lif_pad_ops, ++}; ++ ++/* ----------------------------------------------------------------------------- ++ * Initialization and Cleanup ++ */ ++ ++struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1) ++{ ++ struct v4l2_subdev *subdev; ++ struct vsp1_lif *lif; ++ int ret; ++ ++ lif = devm_kzalloc(vsp1->dev, sizeof(*lif), GFP_KERNEL); ++ if (lif == NULL) ++ return ERR_PTR(-ENOMEM); ++ ++ lif->entity.type = VSP1_ENTITY_LIF; ++ lif->entity.id = VI6_DPR_NODE_LIF; ++ ++ ret = vsp1_entity_init(vsp1, &lif->entity, 2); ++ if (ret < 0) ++ return ERR_PTR(ret); ++ ++ /* Initialize the V4L2 subdev. */ ++ subdev = &lif->entity.subdev; ++ v4l2_subdev_init(subdev, &lif_ops); ++ ++ subdev->entity.ops = &vsp1_media_ops; ++ subdev->internal_ops = &vsp1_subdev_internal_ops; ++ snprintf(subdev->name, sizeof(subdev->name), "%s lif", ++ dev_name(vsp1->dev)); ++ v4l2_set_subdevdata(subdev, lif); ++ subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ++ ++ vsp1_entity_init_formats(subdev, NULL); ++ ++ return lif; ++} +diff --git a/drivers/media/platform/vsp1/vsp1_lif.h b/drivers/media/platform/vsp1/vsp1_lif.h +new file mode 100644 +index 000000000000..89b93af56fdc +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1_lif.h +@@ -0,0 +1,37 @@ ++/* ++ * vsp1_lif.h -- R-Car VSP1 LCD Controller Interface ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++#ifndef __VSP1_LIF_H__ ++#define __VSP1_LIF_H__ ++ ++#include <media/media-entity.h> ++#include <media/v4l2-subdev.h> ++ ++#include "vsp1_entity.h" ++ ++struct vsp1_device; ++ ++#define LIF_PAD_SINK 0 ++#define LIF_PAD_SOURCE 1 ++ ++struct vsp1_lif { ++ struct vsp1_entity entity; ++}; ++ ++static inline struct vsp1_lif *to_lif(struct v4l2_subdev *subdev) ++{ ++ return container_of(subdev, struct vsp1_lif, entity.subdev); ++} ++ ++struct vsp1_lif *vsp1_lif_create(struct vsp1_device *vsp1); ++ ++#endif /* __VSP1_LIF_H__ */ +diff --git a/drivers/media/platform/vsp1/vsp1_regs.h b/drivers/media/platform/vsp1/vsp1_regs.h +new file mode 100644 +index 000000000000..1d3304f1365b +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1_regs.h +@@ -0,0 +1,581 @@ ++/* ++ * vsp1_regs.h -- R-Car VSP1 Registers Definitions ++ * ++ * Copyright (C) 2013 Renesas Electronics Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 ++ * as published by the Free Software Foundation. ++ */ ++ ++#ifndef __VSP1_REGS_H__ ++#define __VSP1_REGS_H__ ++ ++/* ----------------------------------------------------------------------------- ++ * General Control Registers ++ */ ++ ++#define VI6_CMD(n) (0x0000 + (n) * 4) ++#define VI6_CMD_STRCMD (1 << 0) ++ ++#define VI6_CLK_DCSWT 0x0018 ++#define VI6_CLK_DCSWT_CSTPW_MASK (0xff << 8) ++#define VI6_CLK_DCSWT_CSTPW_SHIFT 8 ++#define VI6_CLK_DCSWT_CSTRW_MASK (0xff << 0) ++#define VI6_CLK_DCSWT_CSTRW_SHIFT 0 ++ ++#define VI6_SRESET 0x0028 ++#define VI6_SRESET_SRTS(n) (1 << (n)) ++ ++#define VI6_STATUS 0x0038 ++#define VI6_STATUS_SYS_ACT(n) (1 << ((n) + 8)) ++ ++#define VI6_WPF_IRQ_ENB(n) (0x0048 + (n) * 12) ++#define VI6_WFP_IRQ_ENB_DFEE (1 << 1) ++#define VI6_WFP_IRQ_ENB_FREE (1 << 0) ++ ++#define VI6_WPF_IRQ_STA(n) (0x004c + (n) * 12) ++#define VI6_WFP_IRQ_STA_DFE (1 << 1) ++#define VI6_WFP_IRQ_STA_FRE (1 << 0) ++ ++#define VI6_DISP_IRQ_ENB 0x0078 ++#define VI6_DISP_IRQ_ENB_DSTE (1 << 8) ++#define VI6_DISP_IRQ_ENB_MAEE (1 << 5) ++#define VI6_DISP_IRQ_ENB_LNEE(n) (1 << ((n) + 4)) ++ ++#define VI6_DISP_IRQ_STA 0x007c ++#define VI6_DISP_IRQ_STA_DSE (1 << 8) ++#define VI6_DISP_IRQ_STA_MAE (1 << 5) ++#define VI6_DISP_IRQ_STA_LNE(n) (1 << ((n) + 4)) ++ ++#define VI6_WPF_LINE_COUNT(n) (0x0084 + (n) * 4) ++#define VI6_WPF_LINE_COUNT_MASK (0x1fffff << 0) ++ ++/* ----------------------------------------------------------------------------- ++ * Display List Control Registers ++ */ ++ ++#define VI6_DL_CTRL 0x0100 ++#define VI6_DL_CTRL_AR_WAIT_MASK (0xffff << 16) ++#define VI6_DL_CTRL_AR_WAIT_SHIFT 16 ++#define VI6_DL_CTRL_DC2 (1 << 12) ++#define VI6_DL_CTRL_DC1 (1 << 8) ++#define VI6_DL_CTRL_DC0 (1 << 4) ++#define VI6_DL_CTRL_CFM0 (1 << 2) ++#define VI6_DL_CTRL_NH0 (1 << 1) ++#define VI6_DL_CTRL_DLE (1 << 0) ++ ++#define VI6_DL_HDR_ADDR(n) (0x0104 + (n) * 4) ++ ++#define VI6_DL_SWAP 0x0114 ++#define VI6_DL_SWAP_LWS (1 << 2) ++#define VI6_DL_SWAP_WDS (1 << 1) ++#define VI6_DL_SWAP_BTS (1 << 0) ++ ++#define VI6_DL_EXT_CTRL 0x011c ++#define VI6_DL_EXT_CTRL_NWE (1 << 16) ++#define VI6_DL_EXT_CTRL_POLINT_MASK (0x3f << 8) ++#define VI6_DL_EXT_CTRL_POLINT_SHIFT 8 ++#define VI6_DL_EXT_CTRL_DLPRI (1 << 5) ++#define VI6_DL_EXT_CTRL_EXPRI (1 << 4) ++#define VI6_DL_EXT_CTRL_EXT (1 << 0) ++ ++#define VI6_DL_BODY_SIZE 0x0120 ++#define VI6_DL_BODY_SIZE_UPD (1 << 24) ++#define VI6_DL_BODY_SIZE_BS_MASK (0x1ffff << 0) ++#define VI6_DL_BODY_SIZE_BS_SHIFT 0 ++ ++/* ----------------------------------------------------------------------------- ++ * RPF Control Registers ++ */ ++ ++#define VI6_RPF_OFFSET 0x100 ++ ++#define VI6_RPF_SRC_BSIZE 0x0300 ++#define VI6_RPF_SRC_BSIZE_BHSIZE_MASK (0x1fff << 16) ++#define VI6_RPF_SRC_BSIZE_BHSIZE_SHIFT 16 ++#define VI6_RPF_SRC_BSIZE_BVSIZE_MASK (0x1fff << 0) ++#define VI6_RPF_SRC_BSIZE_BVSIZE_SHIFT 0 ++ ++#define VI6_RPF_SRC_ESIZE 0x0304 ++#define VI6_RPF_SRC_ESIZE_EHSIZE_MASK (0x1fff << 16) ++#define VI6_RPF_SRC_ESIZE_EHSIZE_SHIFT 16 ++#define VI6_RPF_SRC_ESIZE_EVSIZE_MASK (0x1fff << 0) ++#define VI6_RPF_SRC_ESIZE_EVSIZE_SHIFT 0 ++ ++#define VI6_RPF_INFMT 0x0308 ++#define VI6_RPF_INFMT_VIR (1 << 28) ++#define VI6_RPF_INFMT_CIPM (1 << 16) ++#define VI6_RPF_INFMT_SPYCS (1 << 15) ++#define VI6_RPF_INFMT_SPUVS (1 << 14) ++#define VI6_RPF_INFMT_CEXT_ZERO (0 << 12) ++#define VI6_RPF_INFMT_CEXT_EXT (1 << 12) ++#define VI6_RPF_INFMT_CEXT_ONE (2 << 12) ++#define VI6_RPF_INFMT_CEXT_MASK (3 << 12) ++#define VI6_RPF_INFMT_RDTM_BT601 (0 << 9) ++#define VI6_RPF_INFMT_RDTM_BT601_EXT (1 << 9) ++#define VI6_RPF_INFMT_RDTM_BT709 (2 << 9) ++#define VI6_RPF_INFMT_RDTM_BT709_EXT (3 << 9) ++#define VI6_RPF_INFMT_RDTM_MASK (7 << 9) ++#define VI6_RPF_INFMT_CSC (1 << 8) ++#define VI6_RPF_INFMT_RDFMT_MASK (0x7f << 0) ++#define VI6_RPF_INFMT_RDFMT_SHIFT 0 ++ ++#define VI6_RPF_DSWAP 0x030c ++#define VI6_RPF_DSWAP_A_LLS (1 << 11) ++#define VI6_RPF_DSWAP_A_LWS (1 << 10) ++#define VI6_RPF_DSWAP_A_WDS (1 << 9) ++#define VI6_RPF_DSWAP_A_BTS (1 << 8) ++#define VI6_RPF_DSWAP_P_LLS (1 << 3) ++#define VI6_RPF_DSWAP_P_LWS (1 << 2) ++#define VI6_RPF_DSWAP_P_WDS (1 << 1) ++#define VI6_RPF_DSWAP_P_BTS (1 << 0) ++ ++#define VI6_RPF_LOC 0x0310 ++#define VI6_RPF_LOC_HCOORD_MASK (0x1fff << 16) ++#define VI6_RPF_LOC_HCOORD_SHIFT 16 ++#define VI6_RPF_LOC_VCOORD_MASK (0x1fff << 0) ++#define VI6_RPF_LOC_VCOORD_SHIFT 0 ++ ++#define VI6_RPF_ALPH_SEL 0x0314 ++#define VI6_RPF_ALPH_SEL_ASEL_PACKED (0 << 28) ++#define VI6_RPF_ALPH_SEL_ASEL_8B_PLANE (1 << 28) ++#define VI6_RPF_ALPH_SEL_ASEL_SELECT (2 << 28) ++#define VI6_RPF_ALPH_SEL_ASEL_1B_PLANE (3 << 28) ++#define VI6_RPF_ALPH_SEL_ASEL_FIXED (4 << 28) ++#define VI6_RPF_ALPH_SEL_ASEL_MASK (7 << 28) ++#define VI6_RPF_ALPH_SEL_ASEL_SHIFT 28 ++#define VI6_RPF_ALPH_SEL_IROP_MASK (0xf << 24) ++#define VI6_RPF_ALPH_SEL_IROP_SHIFT 24 ++#define VI6_RPF_ALPH_SEL_BSEL (1 << 23) ++#define VI6_RPF_ALPH_SEL_AEXT_ZERO (0 << 18) ++#define VI6_RPF_ALPH_SEL_AEXT_EXT (1 << 18) ++#define VI6_RPF_ALPH_SEL_AEXT_ONE (2 << 18) ++#define VI6_RPF_ALPH_SEL_AEXT_MASK (3 << 18) ++#define VI6_RPF_ALPH_SEL_ALPHA0_MASK (0xff << 8) ++#define VI6_RPF_ALPH_SEL_ALPHA0_SHIFT 8 ++#define VI6_RPF_ALPH_SEL_ALPHA1_MASK (0xff << 0) ++#define VI6_RPF_ALPH_SEL_ALPHA1_SHIFT 0 ++ ++#define VI6_RPF_VRTCOL_SET 0x0318 ++#define VI6_RPF_VRTCOL_SET_LAYA_MASK (0xff << 24) ++#define VI6_RPF_VRTCOL_SET_LAYA_SHIFT 24 ++#define VI6_RPF_VRTCOL_SET_LAYR_MASK (0xff << 16) ++#define VI6_RPF_VRTCOL_SET_LAYR_SHIFT 16 ++#define VI6_RPF_VRTCOL_SET_LAYG_MASK (0xff << 8) ++#define VI6_RPF_VRTCOL_SET_LAYG_SHIFT 8 ++#define VI6_RPF_VRTCOL_SET_LAYB_MASK (0xff << 0) ++#define VI6_RPF_VRTCOL_SET_LAYB_SHIFT 0 ++ ++#define VI6_RPF_MSK_CTRL 0x031c ++#define VI6_RPF_MSK_CTRL_MSK_EN (1 << 24) ++#define VI6_RPF_MSK_CTRL_MGR_MASK (0xff << 16) ++#define VI6_RPF_MSK_CTRL_MGR_SHIFT 16 ++#define VI6_RPF_MSK_CTRL_MGG_MASK (0xff << 8) ++#define VI6_RPF_MSK_CTRL_MGG_SHIFT 8 ++#define VI6_RPF_MSK_CTRL_MGB_MASK (0xff << 0) ++#define VI6_RPF_MSK_CTRL_MGB_SHIFT 0 ++ ++#define VI6_RPF_MSK_SET0 0x0320 ++#define VI6_RPF_MSK_SET1 0x0324 ++#define VI6_RPF_MSK_SET_MSA_MASK (0xff << 24) ++#define VI6_RPF_MSK_SET_MSA_SHIFT 24 ++#define VI6_RPF_MSK_SET_MSR_MASK (0xff << 16) ++#define VI6_RPF_MSK_SET_MSR_SHIFT 16 ++#define VI6_RPF_MSK_SET_MSG_MASK (0xff << 8) ++#define VI6_RPF_MSK_SET_MSG_SHIFT 8 ++#define VI6_RPF_MSK_SET_MSB_MASK (0xff << 0) ++#define VI6_RPF_MSK_SET_MSB_SHIFT 0 ++ ++#define VI6_RPF_CKEY_CTRL 0x0328 ++#define VI6_RPF_CKEY_CTRL_CV (1 << 4) ++#define VI6_RPF_CKEY_CTRL_SAPE1 (1 << 1) ++#define VI6_RPF_CKEY_CTRL_SAPE0 (1 << 0) ++ ++#define VI6_RPF_CKEY_SET0 0x032c ++#define VI6_RPF_CKEY_SET1 0x0330 ++#define VI6_RPF_CKEY_SET_AP_MASK (0xff << 24) ++#define VI6_RPF_CKEY_SET_AP_SHIFT 24 ++#define VI6_RPF_CKEY_SET_R_MASK (0xff << 16) ++#define VI6_RPF_CKEY_SET_R_SHIFT 16 ++#define VI6_RPF_CKEY_SET_GY_MASK (0xff << 8) ++#define VI6_RPF_CKEY_SET_GY_SHIFT 8 ++#define VI6_RPF_CKEY_SET_B_MASK (0xff << 0) ++#define VI6_RPF_CKEY_SET_B_SHIFT 0 ++ ++#define VI6_RPF_SRCM_PSTRIDE 0x0334 ++#define VI6_RPF_SRCM_PSTRIDE_Y_SHIFT 16 ++#define VI6_RPF_SRCM_PSTRIDE_C_SHIFT 0 ++ ++#define VI6_RPF_SRCM_ASTRIDE 0x0338 ++#define VI6_RPF_SRCM_PSTRIDE_A_SHIFT 0 ++ ++#define VI6_RPF_SRCM_ADDR_Y 0x033c ++#define VI6_RPF_SRCM_ADDR_C0 0x0340 ++#define VI6_RPF_SRCM_ADDR_C1 0x0344 ++#define VI6_RPF_SRCM_ADDR_AI 0x0348 ++ ++/* ----------------------------------------------------------------------------- ++ * WPF Control Registers ++ */ ++ ++#define VI6_WPF_OFFSET 0x100 ++ ++#define VI6_WPF_SRCRPF 0x1000 ++#define VI6_WPF_SRCRPF_VIRACT_DIS (0 << 28) ++#define VI6_WPF_SRCRPF_VIRACT_SUB (1 << 28) ++#define VI6_WPF_SRCRPF_VIRACT_MST (2 << 28) ++#define VI6_WPF_SRCRPF_VIRACT_MASK (3 << 28) ++#define VI6_WPF_SRCRPF_RPF_ACT_DIS(n) (0 << ((n) * 2)) ++#define VI6_WPF_SRCRPF_RPF_ACT_SUB(n) (1 << ((n) * 2)) ++#define VI6_WPF_SRCRPF_RPF_ACT_MST(n) (2 << ((n) * 2)) ++#define VI6_WPF_SRCRPF_RPF_ACT_MASK(n) (3 << ((n) * 2)) ++ ++#define VI6_WPF_HSZCLIP 0x1004 ++#define VI6_WPF_VSZCLIP 0x1008 ++#define VI6_WPF_SZCLIP_EN (1 << 28) ++#define VI6_WPF_SZCLIP_OFST_MASK (0xff << 16) ++#define VI6_WPF_SZCLIP_OFST_SHIFT 16 ++#define VI6_WPF_SZCLIP_SIZE_MASK (0x1fff << 0) ++#define VI6_WPF_SZCLIP_SIZE_SHIFT 0 ++ ++#define VI6_WPF_OUTFMT 0x100c ++#define VI6_WPF_OUTFMT_PDV_MASK (0xff << 24) ++#define VI6_WPF_OUTFMT_PDV_SHIFT 24 ++#define VI6_WPF_OUTFMT_PXA (1 << 23) ++#define VI6_WPF_OUTFMT_FLP (1 << 16) ++#define VI6_WPF_OUTFMT_SPYCS (1 << 15) ++#define VI6_WPF_OUTFMT_SPUVS (1 << 14) ++#define VI6_WPF_OUTFMT_DITH_DIS (0 << 12) ++#define VI6_WPF_OUTFMT_DITH_EN (3 << 12) ++#define VI6_WPF_OUTFMT_DITH_MASK (3 << 12) ++#define VI6_WPF_OUTFMT_WRTM_BT601 (0 << 9) ++#define VI6_WPF_OUTFMT_WRTM_BT601_EXT (1 << 9) ++#define VI6_WPF_OUTFMT_WRTM_BT709 (2 << 9) ++#define VI6_WPF_OUTFMT_WRTM_BT709_EXT (3 << 9) ++#define VI6_WPF_OUTFMT_WRTM_MASK (7 << 9) ++#define VI6_WPF_OUTFMT_CSC (1 << 8) ++#define VI6_WPF_OUTFMT_WRFMT_MASK (0x7f << 0) ++#define VI6_WPF_OUTFMT_WRFMT_SHIFT 0 ++ ++#define VI6_WPF_DSWAP 0x1010 ++#define VI6_WPF_DSWAP_P_LLS (1 << 3) ++#define VI6_WPF_DSWAP_P_LWS (1 << 2) ++#define VI6_WPF_DSWAP_P_WDS (1 << 1) ++#define VI6_WPF_DSWAP_P_BTS (1 << 0) ++ ++#define VI6_WPF_RNDCTRL 0x1014 ++#define VI6_WPF_RNDCTRL_CBRM (1 << 28) ++#define VI6_WPF_RNDCTRL_ABRM_TRUNC (0 << 24) ++#define VI6_WPF_RNDCTRL_ABRM_ROUND (1 << 24) ++#define VI6_WPF_RNDCTRL_ABRM_THRESH (2 << 24) ++#define VI6_WPF_RNDCTRL_ABRM_MASK (3 << 24) ++#define VI6_WPF_RNDCTRL_ATHRESH_MASK (0xff << 16) ++#define VI6_WPF_RNDCTRL_ATHRESH_SHIFT 16 ++#define VI6_WPF_RNDCTRL_CLMD_FULL (0 << 12) ++#define VI6_WPF_RNDCTRL_CLMD_CLIP (1 << 12) ++#define VI6_WPF_RNDCTRL_CLMD_EXT (2 << 12) ++#define VI6_WPF_RNDCTRL_CLMD_MASK (3 << 12) ++ ++#define VI6_WPF_DSTM_STRIDE_Y 0x101c ++#define VI6_WPF_DSTM_STRIDE_C 0x1020 ++#define VI6_WPF_DSTM_ADDR_Y 0x1024 ++#define VI6_WPF_DSTM_ADDR_C0 0x1028 ++#define VI6_WPF_DSTM_ADDR_C1 0x102c ++ ++#define VI6_WPF_WRBCK_CTRL 0x1034 ++#define VI6_WPF_WRBCK_CTRL_WBMD (1 << 0) ++ ++/* ----------------------------------------------------------------------------- ++ * DPR Control Registers ++ */ ++ ++#define VI6_DPR_RPF_ROUTE(n) (0x2000 + (n) * 4) ++ ++#define VI6_DPR_WPF_FPORCH(n) (0x2014 + (n) * 4) ++#define VI6_DPR_WPF_FPORCH_FP_WPFN (5 << 8) ++ ++#define VI6_DPR_SRU_ROUTE 0x2024 ++#define VI6_DPR_UDS_ROUTE(n) (0x2028 + (n) * 4) ++#define VI6_DPR_LUT_ROUTE 0x203c ++#define VI6_DPR_CLU_ROUTE 0x2040 ++#define VI6_DPR_HST_ROUTE 0x2044 ++#define VI6_DPR_HSI_ROUTE 0x2048 ++#define VI6_DPR_BRU_ROUTE 0x204c ++#define VI6_DPR_ROUTE_FXA_MASK (0xff << 8) ++#define VI6_DPR_ROUTE_FXA_SHIFT 16 ++#define VI6_DPR_ROUTE_FP_MASK (0xff << 8) ++#define VI6_DPR_ROUTE_FP_SHIFT 8 ++#define VI6_DPR_ROUTE_RT_MASK (0x3f << 0) ++#define VI6_DPR_ROUTE_RT_SHIFT 0 ++ ++#define VI6_DPR_HGO_SMPPT 0x2050 ++#define VI6_DPR_HGT_SMPPT 0x2054 ++#define VI6_DPR_SMPPT_TGW_MASK (7 << 8) ++#define VI6_DPR_SMPPT_TGW_SHIFT 8 ++#define VI6_DPR_SMPPT_PT_MASK (0x3f << 0) ++#define VI6_DPR_SMPPT_PT_SHIFT 0 ++ ++#define VI6_DPR_NODE_RPF(n) (n) ++#define VI6_DPR_NODE_SRU 16 ++#define VI6_DPR_NODE_UDS(n) (17 + (n)) ++#define VI6_DPR_NODE_LUT 22 ++#define VI6_DPR_NODE_BRU_IN(n) (23 + (n)) ++#define VI6_DPR_NODE_BRU_OUT 27 ++#define VI6_DPR_NODE_CLU 29 ++#define VI6_DPR_NODE_HST 30 ++#define VI6_DPR_NODE_HSI 31 ++#define VI6_DPR_NODE_LIF 55 ++#define VI6_DPR_NODE_WPF(n) (56 + (n)) ++#define VI6_DPR_NODE_UNUSED 63 ++ ++/* ----------------------------------------------------------------------------- ++ * SRU Control Registers ++ */ ++ ++#define VI6_SRU_CTRL0 0x2200 ++#define VI6_SRU_CTRL1 0x2204 ++#define VI6_SRU_CTRL2 0x2208 ++ ++/* ----------------------------------------------------------------------------- ++ * UDS Control Registers ++ */ ++ ++#define VI6_UDS_OFFSET 0x100 ++ ++#define VI6_UDS_CTRL 0x2300 ++#define VI6_UDS_CTRL_AMD (1 << 30) ++#define VI6_UDS_CTRL_FMD (1 << 29) ++#define VI6_UDS_CTRL_BLADV (1 << 28) ++#define VI6_UDS_CTRL_AON (1 << 25) ++#define VI6_UDS_CTRL_ATHON (1 << 24) ++#define VI6_UDS_CTRL_BC (1 << 20) ++#define VI6_UDS_CTRL_NE_A (1 << 19) ++#define VI6_UDS_CTRL_NE_RCR (1 << 18) ++#define VI6_UDS_CTRL_NE_GY (1 << 17) ++#define VI6_UDS_CTRL_NE_BCB (1 << 16) ++#define VI6_UDS_CTRL_TDIPC (1 << 1) ++ ++#define VI6_UDS_SCALE 0x2304 ++#define VI6_UDS_SCALE_HMANT_MASK (0xf << 28) ++#define VI6_UDS_SCALE_HMANT_SHIFT 28 ++#define VI6_UDS_SCALE_HFRAC_MASK (0xfff << 16) ++#define VI6_UDS_SCALE_HFRAC_SHIFT 16 ++#define VI6_UDS_SCALE_VMANT_MASK (0xf << 12) ++#define VI6_UDS_SCALE_VMANT_SHIFT 12 ++#define VI6_UDS_SCALE_VFRAC_MASK (0xfff << 0) ++#define VI6_UDS_SCALE_VFRAC_SHIFT 0 ++ ++#define VI6_UDS_ALPTH 0x2308 ++#define VI6_UDS_ALPTH_TH1_MASK (0xff << 8) ++#define VI6_UDS_ALPTH_TH1_SHIFT 8 ++#define VI6_UDS_ALPTH_TH0_MASK (0xff << 0) ++#define VI6_UDS_ALPTH_TH0_SHIFT 0 ++ ++#define VI6_UDS_ALPVAL 0x230c ++#define VI6_UDS_ALPVAL_VAL2_MASK (0xff << 16) ++#define VI6_UDS_ALPVAL_VAL2_SHIFT 16 ++#define VI6_UDS_ALPVAL_VAL1_MASK (0xff << 8) ++#define VI6_UDS_ALPVAL_VAL1_SHIFT 8 ++#define VI6_UDS_ALPVAL_VAL0_MASK (0xff << 0) ++#define VI6_UDS_ALPVAL_VAL0_SHIFT 0 ++ ++#define VI6_UDS_PASS_BWIDTH 0x2310 ++#define VI6_UDS_PASS_BWIDTH_H_MASK (0x7f << 16) ++#define VI6_UDS_PASS_BWIDTH_H_SHIFT 16 ++#define VI6_UDS_PASS_BWIDTH_V_MASK (0x7f << 0) ++#define VI6_UDS_PASS_BWIDTH_V_SHIFT 0 ++ ++#define VI6_UDS_IPC 0x2318 ++#define VI6_UDS_IPC_FIELD (1 << 27) ++#define VI6_UDS_IPC_VEDP_MASK (0xfff << 0) ++#define VI6_UDS_IPC_VEDP_SHIFT 0 ++ ++#define VI6_UDS_CLIP_SIZE 0x2324 ++#define VI6_UDS_CLIP_SIZE_HSIZE_MASK (0x1fff << 16) ++#define VI6_UDS_CLIP_SIZE_HSIZE_SHIFT 16 ++#define VI6_UDS_CLIP_SIZE_VSIZE_MASK (0x1fff << 0) ++#define VI6_UDS_CLIP_SIZE_VSIZE_SHIFT 0 ++ ++#define VI6_UDS_FILL_COLOR 0x2328 ++#define VI6_UDS_FILL_COLOR_RFILC_MASK (0xff << 16) ++#define VI6_UDS_FILL_COLOR_RFILC_SHIFT 16 ++#define VI6_UDS_FILL_COLOR_GFILC_MASK (0xff << 8) ++#define VI6_UDS_FILL_COLOR_GFILC_SHIFT 8 ++#define VI6_UDS_FILL_COLOR_BFILC_MASK (0xff << 0) ++#define VI6_UDS_FILL_COLOR_BFILC_SHIFT 0 ++ ++/* ----------------------------------------------------------------------------- ++ * LUT Control Registers ++ */ ++ ++#define VI6_LUT_CTRL 0x2800 ++ ++/* ----------------------------------------------------------------------------- ++ * CLU Control Registers ++ */ ++ ++#define VI6_CLU_CTRL 0x2900 ++ ++/* ----------------------------------------------------------------------------- ++ * HST Control Registers ++ */ ++ ++#define VI6_HST_CTRL 0x2a00 ++ ++/* ----------------------------------------------------------------------------- ++ * HSI Control Registers ++ */ ++ ++#define VI6_HSI_CTRL 0x2b00 ++ ++/* ----------------------------------------------------------------------------- ++ * BRU Control Registers ++ */ ++ ++#define VI6_BRU_INCTRL 0x2c00 ++#define VI6_BRU_VIRRPF_SIZE 0x2c04 ++#define VI6_BRU_VIRRPF_LOC 0x2c08 ++#define VI6_BRU_VIRRPF_COL 0x2c0c ++#define VI6_BRU_CTRL(n) (0x2c10 + (n) * 8) ++#define VI6_BRU_BLD(n) (0x2c14 + (n) * 8) ++#define VI6_BRU_ROP 0x2c30 ++ ++/* ----------------------------------------------------------------------------- ++ * HGO Control Registers ++ */ ++ ++#define VI6_HGO_OFFSET 0x3000 ++#define VI6_HGO_SIZE 0x3004 ++#define VI6_HGO_MODE 0x3008 ++#define VI6_HGO_LB_TH 0x300c ++#define VI6_HGO_LBn_H(n) (0x3010 + (n) * 8) ++#define VI6_HGO_LBn_V(n) (0x3014 + (n) * 8) ++#define VI6_HGO_R_HISTO 0x3030 ++#define VI6_HGO_R_MAXMIN 0x3130 ++#define VI6_HGO_R_SUM 0x3134 ++#define VI6_HGO_R_LB_DET 0x3138 ++#define VI6_HGO_G_HISTO 0x3140 ++#define VI6_HGO_G_MAXMIN 0x3240 ++#define VI6_HGO_G_SUM 0x3244 ++#define VI6_HGO_G_LB_DET 0x3248 ++#define VI6_HGO_B_HISTO 0x3250 ++#define VI6_HGO_B_MAXMIN 0x3350 ++#define VI6_HGO_B_SUM 0x3354 ++#define VI6_HGO_B_LB_DET 0x3358 ++#define VI6_HGO_REGRST 0x33fc ++ ++/* ----------------------------------------------------------------------------- ++ * HGT Control Registers ++ */ ++ ++#define VI6_HGT_OFFSET 0x3400 ++#define VI6_HGT_SIZE 0x3404 ++#define VI6_HGT_MODE 0x3408 ++#define VI6_HGT_HUE_AREA(n) (0x340c + (n) * 4) ++#define VI6_HGT_LB_TH 0x3424 ++#define VI6_HGT_LBn_H(n) (0x3438 + (n) * 8) ++#define VI6_HGT_LBn_V(n) (0x342c + (n) * 8) ++#define VI6_HGT_HISTO(m, n) (0x3450 + (m) * 128 + (n) * 4) ++#define VI6_HGT_MAXMIN 0x3750 ++#define VI6_HGT_SUM 0x3754 ++#define VI6_HGT_LB_DET 0x3758 ++#define VI6_HGT_REGRST 0x37fc ++ ++/* ----------------------------------------------------------------------------- ++ * LIF Control Registers ++ */ ++ ++#define VI6_LIF_CTRL 0x3b00 ++#define VI6_LIF_CTRL_OBTH_MASK (0x7ff << 16) ++#define VI6_LIF_CTRL_OBTH_SHIFT 16 ++#define VI6_LIF_CTRL_CFMT (1 << 4) ++#define VI6_LIF_CTRL_REQSEL (1 << 1) ++#define VI6_LIF_CTRL_LIF_EN (1 << 0) ++ ++#define VI6_LIF_CSBTH 0x3b04 ++#define VI6_LIF_CSBTH_HBTH_MASK (0x7ff << 16) ++#define VI6_LIF_CSBTH_HBTH_SHIFT 16 ++#define VI6_LIF_CSBTH_LBTH_MASK (0x7ff << 0) ++#define VI6_LIF_CSBTH_LBTH_SHIFT 0 ++ ++/* ----------------------------------------------------------------------------- ++ * Security Control Registers ++ */ ++ ++#define VI6_SECURITY_CTRL0 0x3d00 ++#define VI6_SECURITY_CTRL1 0x3d04 ++ ++/* ----------------------------------------------------------------------------- ++ * RPF CLUT Registers ++ */ ++ ++#define VI6_CLUT_TABLE 0x4000 ++ ++/* ----------------------------------------------------------------------------- ++ * 1D LUT Registers ++ */ ++ ++#define VI6_LUT_TABLE 0x7000 ++ ++/* ----------------------------------------------------------------------------- ++ * 3D LUT Registers ++ */ ++ ++#define VI6_CLU_ADDR 0x7400 ++#define VI6_CLU_DATA 0x7404 ++ ++/* ----------------------------------------------------------------------------- ++ * Formats ++ */ ++ ++#define VI6_FMT_RGB_332 0x00 ++#define VI6_FMT_XRGB_4444 0x01 ++#define VI6_FMT_RGBX_4444 0x02 ++#define VI6_FMT_XRGB_1555 0x04 ++#define VI6_FMT_RGBX_5551 0x05 ++#define VI6_FMT_RGB_565 0x06 ++#define VI6_FMT_AXRGB_86666 0x07 ++#define VI6_FMT_RGBXA_66668 0x08 ++#define VI6_FMT_XRGBA_66668 0x09 ++#define VI6_FMT_ARGBX_86666 0x0a ++#define VI6_FMT_AXRXGXB_8262626 0x0b ++#define VI6_FMT_XRXGXBA_2626268 0x0c ++#define VI6_FMT_ARXGXBX_8626262 0x0d ++#define VI6_FMT_RXGXBXA_6262628 0x0e ++#define VI6_FMT_XRGB_6666 0x0f ++#define VI6_FMT_RGBX_6666 0x10 ++#define VI6_FMT_XRXGXB_262626 0x11 ++#define VI6_FMT_RXGXBX_626262 0x12 ++#define VI6_FMT_ARGB_8888 0x13 ++#define VI6_FMT_RGBA_8888 0x14 ++#define VI6_FMT_RGB_888 0x15 ++#define VI6_FMT_XRGXGB_763763 0x16 ++#define VI6_FMT_XXRGB_86666 0x17 ++#define VI6_FMT_BGR_888 0x18 ++#define VI6_FMT_ARGB_4444 0x19 ++#define VI6_FMT_RGBA_4444 0x1a ++#define VI6_FMT_ARGB_1555 0x1b ++#define VI6_FMT_RGBA_5551 0x1c ++#define VI6_FMT_ABGR_4444 0x1d ++#define VI6_FMT_BGRA_4444 0x1e ++#define VI6_FMT_ABGR_1555 0x1f ++#define VI6_FMT_BGRA_5551 0x20 ++#define VI6_FMT_XBXGXR_262626 0x21 ++#define VI6_FMT_ABGR_8888 0x22 ++#define VI6_FMT_XXRGB_88565 0x23 ++ ++#define VI6_FMT_Y_UV_444 0x40 ++#define VI6_FMT_Y_UV_422 0x41 ++#define VI6_FMT_Y_UV_420 0x42 ++#define VI6_FMT_YUV_444 0x46 ++#define VI6_FMT_YUYV_422 0x47 ++#define VI6_FMT_YYUV_422 0x48 ++#define VI6_FMT_YUV_420 0x49 ++#define VI6_FMT_Y_U_V_444 0x4a ++#define VI6_FMT_Y_U_V_422 0x4b ++#define VI6_FMT_Y_U_V_420 0x4c ++ ++#endif /* __VSP1_REGS_H__ */ +diff --git a/drivers/media/platform/vsp1/vsp1_rpf.c b/drivers/media/platform/vsp1/vsp1_rpf.c +new file mode 100644 +index 000000000000..254871d3423e +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1_rpf.c +@@ -0,0 +1,209 @@ ++/* ++ * vsp1_rpf.c -- R-Car VSP1 Read Pixel Formatter ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <linux/device.h> ++ ++#include <media/v4l2-subdev.h> ++ ++#include "vsp1.h" ++#include "vsp1_rwpf.h" ++#include "vsp1_video.h" ++ ++#define RPF_MAX_WIDTH 8190 ++#define RPF_MAX_HEIGHT 8190 ++ ++/* ----------------------------------------------------------------------------- ++ * Device Access ++ */ ++ ++static inline u32 vsp1_rpf_read(struct vsp1_rwpf *rpf, u32 reg) ++{ ++ return vsp1_read(rpf->entity.vsp1, ++ reg + rpf->entity.index * VI6_RPF_OFFSET); ++} ++ ++static inline void vsp1_rpf_write(struct vsp1_rwpf *rpf, u32 reg, u32 data) ++{ ++ vsp1_write(rpf->entity.vsp1, ++ reg + rpf->entity.index * VI6_RPF_OFFSET, data); ++} ++ ++/* ----------------------------------------------------------------------------- ++ * V4L2 Subdevice Core Operations ++ */ ++ ++static int rpf_s_stream(struct v4l2_subdev *subdev, int enable) ++{ ++ struct vsp1_rwpf *rpf = to_rwpf(subdev); ++ const struct vsp1_format_info *fmtinfo = rpf->video.fmtinfo; ++ const struct v4l2_pix_format_mplane *format = &rpf->video.format; ++ u32 pstride; ++ u32 infmt; ++ ++ if (!enable) ++ return 0; ++ ++ /* Source size and stride. Cropping isn't supported yet. */ ++ vsp1_rpf_write(rpf, VI6_RPF_SRC_BSIZE, ++ (format->width << VI6_RPF_SRC_BSIZE_BHSIZE_SHIFT) | ++ (format->height << VI6_RPF_SRC_BSIZE_BVSIZE_SHIFT)); ++ vsp1_rpf_write(rpf, VI6_RPF_SRC_ESIZE, ++ (format->width << VI6_RPF_SRC_ESIZE_EHSIZE_SHIFT) | ++ (format->height << VI6_RPF_SRC_ESIZE_EVSIZE_SHIFT)); ++ ++ pstride = format->plane_fmt[0].bytesperline ++ << VI6_RPF_SRCM_PSTRIDE_Y_SHIFT; ++ if (format->num_planes > 1) ++ pstride |= format->plane_fmt[1].bytesperline ++ << VI6_RPF_SRCM_PSTRIDE_C_SHIFT; ++ ++ vsp1_rpf_write(rpf, VI6_RPF_SRCM_PSTRIDE, pstride); ++ ++ /* Format */ ++ infmt = VI6_RPF_INFMT_CIPM ++ | (fmtinfo->hwfmt << VI6_RPF_INFMT_RDFMT_SHIFT); ++ ++ if (fmtinfo->swap_yc) ++ infmt |= VI6_RPF_INFMT_SPYCS; ++ if (fmtinfo->swap_uv) ++ infmt |= VI6_RPF_INFMT_SPUVS; ++ ++ if (rpf->entity.formats[RWPF_PAD_SINK].code != ++ rpf->entity.formats[RWPF_PAD_SOURCE].code) ++ infmt |= VI6_RPF_INFMT_CSC; ++ ++ vsp1_rpf_write(rpf, VI6_RPF_INFMT, infmt); ++ vsp1_rpf_write(rpf, VI6_RPF_DSWAP, fmtinfo->swap); ++ ++ /* Output location. Composing isn't supported yet. */ ++ vsp1_rpf_write(rpf, VI6_RPF_LOC, 0); ++ ++ /* Disable alpha, mask and color key. Set the alpha channel to a fixed ++ * value of 255. ++ */ ++ vsp1_rpf_write(rpf, VI6_RPF_ALPH_SEL, VI6_RPF_ALPH_SEL_ASEL_FIXED); ++ vsp1_rpf_write(rpf, VI6_RPF_VRTCOL_SET, ++ 255 << VI6_RPF_VRTCOL_SET_LAYA_SHIFT); ++ vsp1_rpf_write(rpf, VI6_RPF_MSK_CTRL, 0); ++ vsp1_rpf_write(rpf, VI6_RPF_CKEY_CTRL, 0); ++ ++ return 0; ++} ++ ++/* ----------------------------------------------------------------------------- ++ * V4L2 Subdevice Operations ++ */ ++ ++static struct v4l2_subdev_video_ops rpf_video_ops = { ++ .s_stream = rpf_s_stream, ++}; ++ ++static struct v4l2_subdev_pad_ops rpf_pad_ops = { ++ .enum_mbus_code = vsp1_rwpf_enum_mbus_code, ++ .enum_frame_size = vsp1_rwpf_enum_frame_size, ++ .get_fmt = vsp1_rwpf_get_format, ++ .set_fmt = vsp1_rwpf_set_format, ++}; ++ ++static struct v4l2_subdev_ops rpf_ops = { ++ .video = &rpf_video_ops, ++ .pad = &rpf_pad_ops, ++}; ++ ++/* ----------------------------------------------------------------------------- ++ * Video Device Operations ++ */ ++ ++static void rpf_vdev_queue(struct vsp1_video *video, ++ struct vsp1_video_buffer *buf) ++{ ++ struct vsp1_rwpf *rpf = container_of(video, struct vsp1_rwpf, video); ++ ++ vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_Y, buf->addr[0]); ++ if (buf->buf.num_planes > 1) ++ vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C0, buf->addr[1]); ++ if (buf->buf.num_planes > 2) ++ vsp1_rpf_write(rpf, VI6_RPF_SRCM_ADDR_C1, buf->addr[2]); ++} ++ ++static const struct vsp1_video_operations rpf_vdev_ops = { ++ .queue = rpf_vdev_queue, ++}; ++ ++/* ----------------------------------------------------------------------------- ++ * Initialization and Cleanup ++ */ ++ ++struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index) ++{ ++ struct v4l2_subdev *subdev; ++ struct vsp1_video *video; ++ struct vsp1_rwpf *rpf; ++ int ret; ++ ++ rpf = devm_kzalloc(vsp1->dev, sizeof(*rpf), GFP_KERNEL); ++ if (rpf == NULL) ++ return ERR_PTR(-ENOMEM); ++ ++ rpf->max_width = RPF_MAX_WIDTH; ++ rpf->max_height = RPF_MAX_HEIGHT; ++ ++ rpf->entity.type = VSP1_ENTITY_RPF; ++ rpf->entity.index = index; ++ rpf->entity.id = VI6_DPR_NODE_RPF(index); ++ ++ ret = vsp1_entity_init(vsp1, &rpf->entity, 2); ++ if (ret < 0) ++ return ERR_PTR(ret); ++ ++ /* Initialize the V4L2 subdev. */ ++ subdev = &rpf->entity.subdev; ++ v4l2_subdev_init(subdev, &rpf_ops); ++ ++ subdev->entity.ops = &vsp1_media_ops; ++ subdev->internal_ops = &vsp1_subdev_internal_ops; ++ snprintf(subdev->name, sizeof(subdev->name), "%s rpf.%u", ++ dev_name(vsp1->dev), index); ++ v4l2_set_subdevdata(subdev, rpf); ++ subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ++ ++ vsp1_entity_init_formats(subdev, NULL); ++ ++ /* Initialize the video device. */ ++ video = &rpf->video; ++ ++ video->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; ++ video->vsp1 = vsp1; ++ video->ops = &rpf_vdev_ops; ++ ++ ret = vsp1_video_init(video, &rpf->entity); ++ if (ret < 0) ++ goto error_video; ++ ++ /* Connect the video device to the RPF. */ ++ ret = media_entity_create_link(&rpf->video.video.entity, 0, ++ &rpf->entity.subdev.entity, ++ RWPF_PAD_SINK, ++ MEDIA_LNK_FL_ENABLED | ++ MEDIA_LNK_FL_IMMUTABLE); ++ if (ret < 0) ++ goto error_link; ++ ++ return rpf; ++ ++error_link: ++ vsp1_video_cleanup(video); ++error_video: ++ media_entity_cleanup(&rpf->entity.subdev.entity); ++ return ERR_PTR(ret); ++} +diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.c b/drivers/media/platform/vsp1/vsp1_rwpf.c +new file mode 100644 +index 000000000000..9752d5516ceb +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1_rwpf.c +@@ -0,0 +1,124 @@ ++/* ++ * vsp1_rwpf.c -- R-Car VSP1 Read and Write Pixel Formatters ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <media/v4l2-subdev.h> ++ ++#include "vsp1.h" ++#include "vsp1_rwpf.h" ++#include "vsp1_video.h" ++ ++#define RWPF_MIN_WIDTH 1 ++#define RWPF_MIN_HEIGHT 1 ++ ++/* ----------------------------------------------------------------------------- ++ * V4L2 Subdevice Pad Operations ++ */ ++ ++int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, ++ struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_mbus_code_enum *code) ++{ ++ static const unsigned int codes[] = { ++ V4L2_MBUS_FMT_ARGB8888_1X32, ++ V4L2_MBUS_FMT_AYUV8_1X32, ++ }; ++ ++ if (code->index >= ARRAY_SIZE(codes)) ++ return -EINVAL; ++ ++ code->code = codes[code->index]; ++ ++ return 0; ++} ++ ++int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev, ++ struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_frame_size_enum *fse) ++{ ++ struct vsp1_rwpf *rwpf = to_rwpf(subdev); ++ struct v4l2_mbus_framefmt *format; ++ ++ format = v4l2_subdev_get_try_format(fh, fse->pad); ++ ++ if (fse->index || fse->code != format->code) ++ return -EINVAL; ++ ++ if (fse->pad == RWPF_PAD_SINK) { ++ fse->min_width = RWPF_MIN_WIDTH; ++ fse->max_width = rwpf->max_width; ++ fse->min_height = RWPF_MIN_HEIGHT; ++ fse->max_height = rwpf->max_height; ++ } else { ++ /* The size on the source pad are fixed and always identical to ++ * the size on the sink pad. ++ */ ++ fse->min_width = format->width; ++ fse->max_width = format->width; ++ fse->min_height = format->height; ++ fse->max_height = format->height; ++ } ++ ++ return 0; ++} ++ ++int vsp1_rwpf_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_format *fmt) ++{ ++ struct vsp1_rwpf *rwpf = to_rwpf(subdev); ++ ++ fmt->format = *vsp1_entity_get_pad_format(&rwpf->entity, fh, fmt->pad, ++ fmt->which); ++ ++ return 0; ++} ++ ++int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_format *fmt) ++{ ++ struct vsp1_rwpf *rwpf = to_rwpf(subdev); ++ struct v4l2_mbus_framefmt *format; ++ ++ /* Default to YUV if the requested format is not supported. */ ++ if (fmt->format.code != V4L2_MBUS_FMT_ARGB8888_1X32 && ++ fmt->format.code != V4L2_MBUS_FMT_AYUV8_1X32) ++ fmt->format.code = V4L2_MBUS_FMT_AYUV8_1X32; ++ ++ format = vsp1_entity_get_pad_format(&rwpf->entity, fh, fmt->pad, ++ fmt->which); ++ ++ if (fmt->pad == RWPF_PAD_SOURCE) { ++ /* The RWPF performs format conversion but can't scale, only the ++ * format code can be changed on the source pad. ++ */ ++ format->code = fmt->format.code; ++ fmt->format = *format; ++ return 0; ++ } ++ ++ format->code = fmt->format.code; ++ format->width = clamp_t(unsigned int, fmt->format.width, ++ RWPF_MIN_WIDTH, rwpf->max_width); ++ format->height = clamp_t(unsigned int, fmt->format.height, ++ RWPF_MIN_HEIGHT, rwpf->max_height); ++ format->field = V4L2_FIELD_NONE; ++ format->colorspace = V4L2_COLORSPACE_SRGB; ++ ++ fmt->format = *format; ++ ++ /* Propagate the format to the source pad. */ ++ format = vsp1_entity_get_pad_format(&rwpf->entity, fh, RWPF_PAD_SOURCE, ++ fmt->which); ++ *format = fmt->format; ++ ++ return 0; ++} +diff --git a/drivers/media/platform/vsp1/vsp1_rwpf.h b/drivers/media/platform/vsp1/vsp1_rwpf.h +new file mode 100644 +index 000000000000..c182d85f36b3 +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1_rwpf.h +@@ -0,0 +1,53 @@ ++/* ++ * vsp1_rwpf.h -- R-Car VSP1 Read and Write Pixel Formatters ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++#ifndef __VSP1_RWPF_H__ ++#define __VSP1_RWPF_H__ ++ ++#include <media/media-entity.h> ++#include <media/v4l2-subdev.h> ++ ++#include "vsp1.h" ++#include "vsp1_entity.h" ++#include "vsp1_video.h" ++ ++#define RWPF_PAD_SINK 0 ++#define RWPF_PAD_SOURCE 1 ++ ++struct vsp1_rwpf { ++ struct vsp1_entity entity; ++ struct vsp1_video video; ++ ++ unsigned int max_width; ++ unsigned int max_height; ++}; ++ ++static inline struct vsp1_rwpf *to_rwpf(struct v4l2_subdev *subdev) ++{ ++ return container_of(subdev, struct vsp1_rwpf, entity.subdev); ++} ++ ++struct vsp1_rwpf *vsp1_rpf_create(struct vsp1_device *vsp1, unsigned int index); ++struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index); ++ ++int vsp1_rwpf_enum_mbus_code(struct v4l2_subdev *subdev, ++ struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_mbus_code_enum *code); ++int vsp1_rwpf_enum_frame_size(struct v4l2_subdev *subdev, ++ struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_frame_size_enum *fse); ++int vsp1_rwpf_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_format *fmt); ++int vsp1_rwpf_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_format *fmt); ++ ++#endif /* __VSP1_RWPF_H__ */ +diff --git a/drivers/media/platform/vsp1/vsp1_uds.c b/drivers/media/platform/vsp1/vsp1_uds.c +new file mode 100644 +index 000000000000..0e50b37f060d +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1_uds.c +@@ -0,0 +1,346 @@ ++/* ++ * vsp1_uds.c -- R-Car VSP1 Up and Down Scaler ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <linux/device.h> ++#include <linux/gfp.h> ++ ++#include <media/v4l2-subdev.h> ++ ++#include "vsp1.h" ++#include "vsp1_uds.h" ++ ++#define UDS_MIN_SIZE 4U ++#define UDS_MAX_SIZE 8190U ++ ++#define UDS_MIN_FACTOR 0x0100 ++#define UDS_MAX_FACTOR 0xffff ++ ++/* ----------------------------------------------------------------------------- ++ * Device Access ++ */ ++ ++static inline u32 vsp1_uds_read(struct vsp1_uds *uds, u32 reg) ++{ ++ return vsp1_read(uds->entity.vsp1, ++ reg + uds->entity.index * VI6_UDS_OFFSET); ++} ++ ++static inline void vsp1_uds_write(struct vsp1_uds *uds, u32 reg, u32 data) ++{ ++ vsp1_write(uds->entity.vsp1, ++ reg + uds->entity.index * VI6_UDS_OFFSET, data); ++} ++ ++/* ----------------------------------------------------------------------------- ++ * Scaling Computation ++ */ ++ ++/* ++ * uds_output_size - Return the output size for an input size and scaling ratio ++ * @input: input size in pixels ++ * @ratio: scaling ratio in U4.12 fixed-point format ++ */ ++static unsigned int uds_output_size(unsigned int input, unsigned int ratio) ++{ ++ if (ratio > 4096) { ++ /* Down-scaling */ ++ unsigned int mp; ++ ++ mp = ratio / 4096; ++ mp = mp < 4 ? 1 : (mp < 8 ? 2 : 4); ++ ++ return (input - 1) / mp * mp * 4096 / ratio + 1; ++ } else { ++ /* Up-scaling */ ++ return (input - 1) * 4096 / ratio + 1; ++ } ++} ++ ++/* ++ * uds_output_limits - Return the min and max output sizes for an input size ++ * @input: input size in pixels ++ * @minimum: minimum output size (returned) ++ * @maximum: maximum output size (returned) ++ */ ++static void uds_output_limits(unsigned int input, ++ unsigned int *minimum, unsigned int *maximum) ++{ ++ *minimum = max(uds_output_size(input, UDS_MAX_FACTOR), UDS_MIN_SIZE); ++ *maximum = min(uds_output_size(input, UDS_MIN_FACTOR), UDS_MAX_SIZE); ++} ++ ++/* ++ * uds_passband_width - Return the passband filter width for a scaling ratio ++ * @ratio: scaling ratio in U4.12 fixed-point format ++ */ ++static unsigned int uds_passband_width(unsigned int ratio) ++{ ++ if (ratio >= 4096) { ++ /* Down-scaling */ ++ unsigned int mp; ++ ++ mp = ratio / 4096; ++ mp = mp < 4 ? 1 : (mp < 8 ? 2 : 4); ++ ++ return 64 * 4096 * mp / ratio; ++ } else { ++ /* Up-scaling */ ++ return 64; ++ } ++} ++ ++static unsigned int uds_compute_ratio(unsigned int input, unsigned int output) ++{ ++ /* TODO: This is an approximation that will need to be refined. */ ++ return (input - 1) * 4096 / (output - 1); ++} ++ ++static void uds_compute_ratios(struct vsp1_uds *uds) ++{ ++ struct v4l2_mbus_framefmt *input = &uds->entity.formats[UDS_PAD_SINK]; ++ struct v4l2_mbus_framefmt *output = ++ &uds->entity.formats[UDS_PAD_SOURCE]; ++ ++ uds->hscale = uds_compute_ratio(input->width, output->width); ++ uds->vscale = uds_compute_ratio(input->height, output->height); ++ ++ dev_dbg(uds->entity.vsp1->dev, "hscale %u vscale %u\n", ++ uds->hscale, uds->vscale); ++} ++ ++/* ----------------------------------------------------------------------------- ++ * V4L2 Subdevice Core Operations ++ */ ++ ++static int uds_s_stream(struct v4l2_subdev *subdev, int enable) ++{ ++ const struct v4l2_mbus_framefmt *format; ++ struct vsp1_uds *uds = to_uds(subdev); ++ ++ if (!enable) ++ return 0; ++ ++ /* Enable multi-tap scaling. */ ++ vsp1_uds_write(uds, VI6_UDS_CTRL, VI6_UDS_CTRL_BC); ++ ++ vsp1_uds_write(uds, VI6_UDS_PASS_BWIDTH, ++ (uds_passband_width(uds->hscale) ++ << VI6_UDS_PASS_BWIDTH_H_SHIFT) | ++ (uds_passband_width(uds->vscale) ++ << VI6_UDS_PASS_BWIDTH_V_SHIFT)); ++ ++ ++ /* Set the scaling ratios and the output size. */ ++ format = &uds->entity.formats[UDS_PAD_SOURCE]; ++ ++ vsp1_uds_write(uds, VI6_UDS_SCALE, ++ (uds->hscale << VI6_UDS_SCALE_HFRAC_SHIFT) | ++ (uds->vscale << VI6_UDS_SCALE_VFRAC_SHIFT)); ++ vsp1_uds_write(uds, VI6_UDS_CLIP_SIZE, ++ (format->width << VI6_UDS_CLIP_SIZE_HSIZE_SHIFT) | ++ (format->height << VI6_UDS_CLIP_SIZE_VSIZE_SHIFT)); ++ ++ return 0; ++} ++ ++/* ----------------------------------------------------------------------------- ++ * V4L2 Subdevice Pad Operations ++ */ ++ ++static int uds_enum_mbus_code(struct v4l2_subdev *subdev, ++ struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_mbus_code_enum *code) ++{ ++ static const unsigned int codes[] = { ++ V4L2_MBUS_FMT_ARGB8888_1X32, ++ V4L2_MBUS_FMT_AYUV8_1X32, ++ }; ++ ++ if (code->pad == UDS_PAD_SINK) { ++ if (code->index >= ARRAY_SIZE(codes)) ++ return -EINVAL; ++ ++ code->code = codes[code->index]; ++ } else { ++ struct v4l2_mbus_framefmt *format; ++ ++ /* The UDS can't perform format conversion, the sink format is ++ * always identical to the source format. ++ */ ++ if (code->index) ++ return -EINVAL; ++ ++ format = v4l2_subdev_get_try_format(fh, UDS_PAD_SINK); ++ code->code = format->code; ++ } ++ ++ return 0; ++} ++ ++static int uds_enum_frame_size(struct v4l2_subdev *subdev, ++ struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_frame_size_enum *fse) ++{ ++ struct v4l2_mbus_framefmt *format; ++ ++ format = v4l2_subdev_get_try_format(fh, UDS_PAD_SINK); ++ ++ if (fse->index || fse->code != format->code) ++ return -EINVAL; ++ ++ if (fse->pad == UDS_PAD_SINK) { ++ fse->min_width = UDS_MIN_SIZE; ++ fse->max_width = UDS_MAX_SIZE; ++ fse->min_height = UDS_MIN_SIZE; ++ fse->max_height = UDS_MAX_SIZE; ++ } else { ++ uds_output_limits(format->width, &fse->min_width, ++ &fse->max_width); ++ uds_output_limits(format->height, &fse->min_height, ++ &fse->max_height); ++ } ++ ++ return 0; ++} ++ ++static int uds_get_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_format *fmt) ++{ ++ struct vsp1_uds *uds = to_uds(subdev); ++ ++ fmt->format = *vsp1_entity_get_pad_format(&uds->entity, fh, fmt->pad, ++ fmt->which); ++ ++ return 0; ++} ++ ++static void uds_try_format(struct vsp1_uds *uds, struct v4l2_subdev_fh *fh, ++ unsigned int pad, struct v4l2_mbus_framefmt *fmt, ++ enum v4l2_subdev_format_whence which) ++{ ++ struct v4l2_mbus_framefmt *format; ++ unsigned int minimum; ++ unsigned int maximum; ++ ++ switch (pad) { ++ case UDS_PAD_SINK: ++ /* Default to YUV if the requested format is not supported. */ ++ if (fmt->code != V4L2_MBUS_FMT_ARGB8888_1X32 && ++ fmt->code != V4L2_MBUS_FMT_AYUV8_1X32) ++ fmt->code = V4L2_MBUS_FMT_AYUV8_1X32; ++ ++ fmt->width = clamp(fmt->width, UDS_MIN_SIZE, UDS_MAX_SIZE); ++ fmt->height = clamp(fmt->height, UDS_MIN_SIZE, UDS_MAX_SIZE); ++ break; ++ ++ case UDS_PAD_SOURCE: ++ /* The UDS scales but can't perform format conversion. */ ++ format = vsp1_entity_get_pad_format(&uds->entity, fh, ++ UDS_PAD_SINK, which); ++ fmt->code = format->code; ++ ++ uds_output_limits(format->width, &minimum, &maximum); ++ fmt->width = clamp(fmt->width, minimum, maximum); ++ uds_output_limits(format->height, &minimum, &maximum); ++ fmt->height = clamp(fmt->height, minimum, maximum); ++ break; ++ } ++ ++ fmt->field = V4L2_FIELD_NONE; ++ fmt->colorspace = V4L2_COLORSPACE_SRGB; ++} ++ ++static int uds_set_format(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh, ++ struct v4l2_subdev_format *fmt) ++{ ++ struct vsp1_uds *uds = to_uds(subdev); ++ struct v4l2_mbus_framefmt *format; ++ ++ uds_try_format(uds, fh, fmt->pad, &fmt->format, fmt->which); ++ ++ format = vsp1_entity_get_pad_format(&uds->entity, fh, fmt->pad, ++ fmt->which); ++ *format = fmt->format; ++ ++ if (fmt->pad == UDS_PAD_SINK) { ++ /* Propagate the format to the source pad. */ ++ format = vsp1_entity_get_pad_format(&uds->entity, fh, ++ UDS_PAD_SOURCE, fmt->which); ++ *format = fmt->format; ++ ++ uds_try_format(uds, fh, UDS_PAD_SOURCE, format, fmt->which); ++ } ++ ++ if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) ++ uds_compute_ratios(uds); ++ ++ return 0; ++} ++ ++/* ----------------------------------------------------------------------------- ++ * V4L2 Subdevice Operations ++ */ ++ ++static struct v4l2_subdev_video_ops uds_video_ops = { ++ .s_stream = uds_s_stream, ++}; ++ ++static struct v4l2_subdev_pad_ops uds_pad_ops = { ++ .enum_mbus_code = uds_enum_mbus_code, ++ .enum_frame_size = uds_enum_frame_size, ++ .get_fmt = uds_get_format, ++ .set_fmt = uds_set_format, ++}; ++ ++static struct v4l2_subdev_ops uds_ops = { ++ .video = &uds_video_ops, ++ .pad = &uds_pad_ops, ++}; ++ ++/* ----------------------------------------------------------------------------- ++ * Initialization and Cleanup ++ */ ++ ++struct vsp1_uds *vsp1_uds_create(struct vsp1_device *vsp1, unsigned int index) ++{ ++ struct v4l2_subdev *subdev; ++ struct vsp1_uds *uds; ++ int ret; ++ ++ uds = devm_kzalloc(vsp1->dev, sizeof(*uds), GFP_KERNEL); ++ if (uds == NULL) ++ return ERR_PTR(-ENOMEM); ++ ++ uds->entity.type = VSP1_ENTITY_UDS; ++ uds->entity.index = index; ++ uds->entity.id = VI6_DPR_NODE_UDS(index); ++ ++ ret = vsp1_entity_init(vsp1, &uds->entity, 2); ++ if (ret < 0) ++ return ERR_PTR(ret); ++ ++ /* Initialize the V4L2 subdev. */ ++ subdev = &uds->entity.subdev; ++ v4l2_subdev_init(subdev, &uds_ops); ++ ++ subdev->entity.ops = &vsp1_media_ops; ++ subdev->internal_ops = &vsp1_subdev_internal_ops; ++ snprintf(subdev->name, sizeof(subdev->name), "%s uds.%u", ++ dev_name(vsp1->dev), index); ++ v4l2_set_subdevdata(subdev, uds); ++ subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ++ ++ vsp1_entity_init_formats(subdev, NULL); ++ ++ return uds; ++} +diff --git a/drivers/media/platform/vsp1/vsp1_uds.h b/drivers/media/platform/vsp1/vsp1_uds.h +new file mode 100644 +index 000000000000..972a285abdb9 +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1_uds.h +@@ -0,0 +1,40 @@ ++/* ++ * vsp1_uds.h -- R-Car VSP1 Up and Down Scaler ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++#ifndef __VSP1_UDS_H__ ++#define __VSP1_UDS_H__ ++ ++#include <media/media-entity.h> ++#include <media/v4l2-subdev.h> ++ ++#include "vsp1_entity.h" ++ ++struct vsp1_device; ++ ++#define UDS_PAD_SINK 0 ++#define UDS_PAD_SOURCE 1 ++ ++struct vsp1_uds { ++ struct vsp1_entity entity; ++ ++ unsigned int hscale; ++ unsigned int vscale; ++}; ++ ++static inline struct vsp1_uds *to_uds(struct v4l2_subdev *subdev) ++{ ++ return container_of(subdev, struct vsp1_uds, entity.subdev); ++} ++ ++struct vsp1_uds *vsp1_uds_create(struct vsp1_device *vsp1, unsigned int index); ++ ++#endif /* __VSP1_UDS_H__ */ +diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c +new file mode 100644 +index 000000000000..279332e34710 +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1_video.c +@@ -0,0 +1,1071 @@ ++/* ++ * vsp1_video.c -- R-Car VSP1 Video Node ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <linux/list.h> ++#include <linux/module.h> ++#include <linux/mutex.h> ++#include <linux/sched.h> ++#include <linux/slab.h> ++#include <linux/v4l2-mediabus.h> ++#include <linux/videodev2.h> ++ ++#include <media/media-entity.h> ++#include <media/v4l2-dev.h> ++#include <media/v4l2-fh.h> ++#include <media/v4l2-ioctl.h> ++#include <media/v4l2-subdev.h> ++#include <media/videobuf2-core.h> ++#include <media/videobuf2-dma-contig.h> ++ ++#include "vsp1.h" ++#include "vsp1_entity.h" ++#include "vsp1_rwpf.h" ++#include "vsp1_video.h" ++ ++#define VSP1_VIDEO_DEF_FORMAT V4L2_PIX_FMT_YUYV ++#define VSP1_VIDEO_DEF_WIDTH 1024 ++#define VSP1_VIDEO_DEF_HEIGHT 768 ++ ++#define VSP1_VIDEO_MIN_WIDTH 2U ++#define VSP1_VIDEO_MAX_WIDTH 8190U ++#define VSP1_VIDEO_MIN_HEIGHT 2U ++#define VSP1_VIDEO_MAX_HEIGHT 8190U ++ ++/* ----------------------------------------------------------------------------- ++ * Helper functions ++ */ ++ ++static const struct vsp1_format_info vsp1_video_formats[] = { ++ { V4L2_PIX_FMT_RGB332, V4L2_MBUS_FMT_ARGB8888_1X32, ++ VI6_FMT_RGB_332, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, ++ 1, { 8, 0, 0 }, false, false, 1, 1 }, ++ { V4L2_PIX_FMT_RGB444, V4L2_MBUS_FMT_ARGB8888_1X32, ++ VI6_FMT_XRGB_4444, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS, ++ 1, { 16, 0, 0 }, false, false, 1, 1 }, ++ { V4L2_PIX_FMT_RGB555, V4L2_MBUS_FMT_ARGB8888_1X32, ++ VI6_FMT_XRGB_1555, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS, ++ 1, { 16, 0, 0 }, false, false, 1, 1 }, ++ { V4L2_PIX_FMT_RGB565, V4L2_MBUS_FMT_ARGB8888_1X32, ++ VI6_FMT_RGB_565, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS, ++ 1, { 16, 0, 0 }, false, false, 1, 1 }, ++ { V4L2_PIX_FMT_BGR24, V4L2_MBUS_FMT_ARGB8888_1X32, ++ VI6_FMT_BGR_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, ++ 1, { 24, 0, 0 }, false, false, 1, 1 }, ++ { V4L2_PIX_FMT_RGB24, V4L2_MBUS_FMT_ARGB8888_1X32, ++ VI6_FMT_RGB_888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, ++ 1, { 24, 0, 0 }, false, false, 1, 1 }, ++ { V4L2_PIX_FMT_BGR32, V4L2_MBUS_FMT_ARGB8888_1X32, ++ VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS, ++ 1, { 32, 0, 0 }, false, false, 1, 1 }, ++ { V4L2_PIX_FMT_RGB32, V4L2_MBUS_FMT_ARGB8888_1X32, ++ VI6_FMT_ARGB_8888, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, ++ 1, { 32, 0, 0 }, false, false, 1, 1 }, ++ { V4L2_PIX_FMT_UYVY, V4L2_MBUS_FMT_AYUV8_1X32, ++ VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, ++ 1, { 16, 0, 0 }, false, false, 2, 1 }, ++ { V4L2_PIX_FMT_VYUY, V4L2_MBUS_FMT_AYUV8_1X32, ++ VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, ++ 1, { 16, 0, 0 }, false, true, 2, 1 }, ++ { V4L2_PIX_FMT_YUYV, V4L2_MBUS_FMT_AYUV8_1X32, ++ VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, ++ 1, { 16, 0, 0 }, true, false, 2, 1 }, ++ { V4L2_PIX_FMT_YVYU, V4L2_MBUS_FMT_AYUV8_1X32, ++ VI6_FMT_YUYV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, ++ 1, { 16, 0, 0 }, true, true, 2, 1 }, ++ { V4L2_PIX_FMT_NV12M, V4L2_MBUS_FMT_AYUV8_1X32, ++ VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, ++ 2, { 8, 16, 0 }, false, false, 2, 2 }, ++ { V4L2_PIX_FMT_NV21M, V4L2_MBUS_FMT_AYUV8_1X32, ++ VI6_FMT_Y_UV_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, ++ 2, { 8, 16, 0 }, false, true, 2, 2 }, ++ { V4L2_PIX_FMT_NV16M, V4L2_MBUS_FMT_AYUV8_1X32, ++ VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, ++ 2, { 8, 16, 0 }, false, false, 2, 1 }, ++ { V4L2_PIX_FMT_NV61M, V4L2_MBUS_FMT_AYUV8_1X32, ++ VI6_FMT_Y_UV_422, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, ++ 2, { 8, 16, 0 }, false, true, 2, 1 }, ++ { V4L2_PIX_FMT_YUV420M, V4L2_MBUS_FMT_AYUV8_1X32, ++ VI6_FMT_Y_U_V_420, VI6_RPF_DSWAP_P_LLS | VI6_RPF_DSWAP_P_LWS | ++ VI6_RPF_DSWAP_P_WDS | VI6_RPF_DSWAP_P_BTS, ++ 3, { 8, 8, 8 }, false, false, 2, 2 }, ++}; ++ ++/* ++ * vsp1_get_format_info - Retrieve format information for a 4CC ++ * @fourcc: the format 4CC ++ * ++ * Return a pointer to the format information structure corresponding to the ++ * given V4L2 format 4CC, or NULL if no corresponding format can be found. ++ */ ++static const struct vsp1_format_info *vsp1_get_format_info(u32 fourcc) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE(vsp1_video_formats); ++i) { ++ const struct vsp1_format_info *info = &vsp1_video_formats[i]; ++ ++ if (info->fourcc == fourcc) ++ return info; ++ } ++ ++ return NULL; ++} ++ ++ ++static struct v4l2_subdev * ++vsp1_video_remote_subdev(struct media_pad *local, u32 *pad) ++{ ++ struct media_pad *remote; ++ ++ remote = media_entity_remote_source(local); ++ if (remote == NULL || ++ media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV) ++ return NULL; ++ ++ if (pad) ++ *pad = remote->index; ++ ++ return media_entity_to_v4l2_subdev(remote->entity); ++} ++ ++static int vsp1_video_verify_format(struct vsp1_video *video) ++{ ++ struct v4l2_subdev_format fmt; ++ struct v4l2_subdev *subdev; ++ int ret; ++ ++ subdev = vsp1_video_remote_subdev(&video->pad, &fmt.pad); ++ if (subdev == NULL) ++ return -EINVAL; ++ ++ fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE; ++ ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt); ++ if (ret < 0) ++ return ret == -ENOIOCTLCMD ? -EINVAL : ret; ++ ++ if (video->fmtinfo->mbus != fmt.format.code || ++ video->format.height != fmt.format.height || ++ video->format.width != fmt.format.width) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static int __vsp1_video_try_format(struct vsp1_video *video, ++ struct v4l2_pix_format_mplane *pix, ++ const struct vsp1_format_info **fmtinfo) ++{ ++ const struct vsp1_format_info *info; ++ unsigned int width = pix->width; ++ unsigned int height = pix->height; ++ unsigned int i; ++ ++ /* Retrieve format information and select the default format if the ++ * requested format isn't supported. ++ */ ++ info = vsp1_get_format_info(pix->pixelformat); ++ if (info == NULL) ++ info = vsp1_get_format_info(VSP1_VIDEO_DEF_FORMAT); ++ ++ pix->pixelformat = info->fourcc; ++ pix->colorspace = V4L2_COLORSPACE_SRGB; ++ pix->field = V4L2_FIELD_NONE; ++ memset(pix->reserved, 0, sizeof(pix->reserved)); ++ ++ /* Align the width and height for YUV 4:2:2 and 4:2:0 formats. */ ++ width = round_down(width, info->hsub); ++ height = round_down(height, info->vsub); ++ ++ /* Clamp the width and height. */ ++ pix->width = clamp(width, VSP1_VIDEO_MIN_WIDTH, VSP1_VIDEO_MAX_WIDTH); ++ pix->height = clamp(height, VSP1_VIDEO_MIN_HEIGHT, ++ VSP1_VIDEO_MAX_HEIGHT); ++ ++ /* Compute and clamp the stride and image size. While not documented in ++ * the datasheet, strides not aligned to a multiple of 128 bytes result ++ * in image corruption. ++ */ ++ for (i = 0; i < max(info->planes, 2U); ++i) { ++ unsigned int hsub = i > 0 ? info->hsub : 1; ++ unsigned int vsub = i > 0 ? info->vsub : 1; ++ unsigned int align = 128; ++ unsigned int bpl; ++ ++ bpl = clamp_t(unsigned int, pix->plane_fmt[i].bytesperline, ++ pix->width / hsub * info->bpp[i] / 8, ++ round_down(65535U, align)); ++ ++ pix->plane_fmt[i].bytesperline = round_up(bpl, align); ++ pix->plane_fmt[i].sizeimage = pix->plane_fmt[i].bytesperline ++ * pix->height / vsub; ++ } ++ ++ if (info->planes == 3) { ++ /* The second and third planes must have the same stride. */ ++ pix->plane_fmt[2].bytesperline = pix->plane_fmt[1].bytesperline; ++ pix->plane_fmt[2].sizeimage = pix->plane_fmt[1].sizeimage; ++ } ++ ++ pix->num_planes = info->planes; ++ ++ if (fmtinfo) ++ *fmtinfo = info; ++ ++ return 0; ++} ++ ++static bool ++vsp1_video_format_adjust(struct vsp1_video *video, ++ const struct v4l2_pix_format_mplane *format, ++ struct v4l2_pix_format_mplane *adjust) ++{ ++ unsigned int i; ++ ++ *adjust = *format; ++ __vsp1_video_try_format(video, adjust, NULL); ++ ++ if (format->width != adjust->width || ++ format->height != adjust->height || ++ format->pixelformat != adjust->pixelformat || ++ format->num_planes != adjust->num_planes) ++ return false; ++ ++ for (i = 0; i < format->num_planes; ++i) { ++ if (format->plane_fmt[i].bytesperline != ++ adjust->plane_fmt[i].bytesperline) ++ return false; ++ ++ adjust->plane_fmt[i].sizeimage = ++ max(adjust->plane_fmt[i].sizeimage, ++ format->plane_fmt[i].sizeimage); ++ } ++ ++ return true; ++} ++ ++/* ----------------------------------------------------------------------------- ++ * Pipeline Management ++ */ ++ ++static int vsp1_pipeline_validate_branch(struct vsp1_rwpf *input, ++ struct vsp1_rwpf *output) ++{ ++ struct vsp1_entity *entity; ++ unsigned int entities = 0; ++ struct media_pad *pad; ++ bool uds_found = false; ++ ++ pad = media_entity_remote_source(&input->entity.pads[RWPF_PAD_SOURCE]); ++ ++ while (1) { ++ if (pad == NULL) ++ return -EPIPE; ++ ++ /* We've reached a video node, that shouldn't have happened. */ ++ if (media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV) ++ return -EPIPE; ++ ++ entity = to_vsp1_entity(media_entity_to_v4l2_subdev(pad->entity)); ++ ++ /* We've reached the WPF, we're done. */ ++ if (entity->type == VSP1_ENTITY_WPF) ++ break; ++ ++ /* Ensure the branch has no loop. */ ++ if (entities & (1 << entity->subdev.entity.id)) ++ return -EPIPE; ++ ++ entities |= 1 << entity->subdev.entity.id; ++ ++ /* UDS can't be chained. */ ++ if (entity->type == VSP1_ENTITY_UDS) { ++ if (uds_found) ++ return -EPIPE; ++ uds_found = true; ++ } ++ ++ /* Follow the source link. The link setup operations ensure ++ * that the output fan-out can't be more than one, there is thus ++ * no need to verify here that only a single source link is ++ * activated. ++ */ ++ pad = &entity->pads[entity->source_pad]; ++ pad = media_entity_remote_source(pad); ++ } ++ ++ /* The last entity must be the output WPF. */ ++ if (entity != &output->entity) ++ return -EPIPE; ++ ++ return 0; ++} ++ ++static int vsp1_pipeline_validate(struct vsp1_pipeline *pipe, ++ struct vsp1_video *video) ++{ ++ struct media_entity_graph graph; ++ struct media_entity *entity = &video->video.entity; ++ struct media_device *mdev = entity->parent; ++ unsigned int i; ++ int ret; ++ ++ mutex_lock(&mdev->graph_mutex); ++ ++ /* Walk the graph to locate the entities and video nodes. */ ++ media_entity_graph_walk_start(&graph, entity); ++ ++ while ((entity = media_entity_graph_walk_next(&graph))) { ++ struct v4l2_subdev *subdev; ++ struct vsp1_rwpf *rwpf; ++ struct vsp1_entity *e; ++ ++ if (media_entity_type(entity) != MEDIA_ENT_T_V4L2_SUBDEV) { ++ pipe->num_video++; ++ continue; ++ } ++ ++ subdev = media_entity_to_v4l2_subdev(entity); ++ e = to_vsp1_entity(subdev); ++ list_add_tail(&e->list_pipe, &pipe->entities); ++ ++ if (e->type == VSP1_ENTITY_RPF) { ++ rwpf = to_rwpf(subdev); ++ pipe->inputs[pipe->num_inputs++] = rwpf; ++ rwpf->video.pipe_index = pipe->num_inputs; ++ } else if (e->type == VSP1_ENTITY_WPF) { ++ rwpf = to_rwpf(subdev); ++ pipe->output = to_rwpf(subdev); ++ rwpf->video.pipe_index = 0; ++ } else if (e->type == VSP1_ENTITY_LIF) { ++ pipe->lif = e; ++ } ++ } ++ ++ mutex_unlock(&mdev->graph_mutex); ++ ++ /* We need one output and at least one input. */ ++ if (pipe->num_inputs == 0 || !pipe->output) { ++ ret = -EPIPE; ++ goto error; ++ } ++ ++ /* Follow links downstream for each input and make sure the graph ++ * contains no loop and that all branches end at the output WPF. ++ */ ++ for (i = 0; i < pipe->num_inputs; ++i) { ++ ret = vsp1_pipeline_validate_branch(pipe->inputs[i], ++ pipe->output); ++ if (ret < 0) ++ goto error; ++ } ++ ++ return 0; ++ ++error: ++ INIT_LIST_HEAD(&pipe->entities); ++ pipe->buffers_ready = 0; ++ pipe->num_video = 0; ++ pipe->num_inputs = 0; ++ pipe->output = NULL; ++ pipe->lif = NULL; ++ return ret; ++} ++ ++static int vsp1_pipeline_init(struct vsp1_pipeline *pipe, ++ struct vsp1_video *video) ++{ ++ int ret; ++ ++ mutex_lock(&pipe->lock); ++ ++ /* If we're the first user validate and initialize the pipeline. */ ++ if (pipe->use_count == 0) { ++ ret = vsp1_pipeline_validate(pipe, video); ++ if (ret < 0) ++ goto done; ++ } ++ ++ pipe->use_count++; ++ ret = 0; ++ ++done: ++ mutex_unlock(&pipe->lock); ++ return ret; ++} ++ ++static void vsp1_pipeline_cleanup(struct vsp1_pipeline *pipe) ++{ ++ mutex_lock(&pipe->lock); ++ ++ /* If we're the last user clean up the pipeline. */ ++ if (--pipe->use_count == 0) { ++ INIT_LIST_HEAD(&pipe->entities); ++ pipe->state = VSP1_PIPELINE_STOPPED; ++ pipe->buffers_ready = 0; ++ pipe->num_video = 0; ++ pipe->num_inputs = 0; ++ pipe->output = NULL; ++ pipe->lif = NULL; ++ } ++ ++ mutex_unlock(&pipe->lock); ++} ++ ++static void vsp1_pipeline_run(struct vsp1_pipeline *pipe) ++{ ++ struct vsp1_device *vsp1 = pipe->output->entity.vsp1; ++ ++ vsp1_write(vsp1, VI6_CMD(pipe->output->entity.index), VI6_CMD_STRCMD); ++ pipe->state = VSP1_PIPELINE_RUNNING; ++ pipe->buffers_ready = 0; ++} ++ ++static int vsp1_pipeline_stop(struct vsp1_pipeline *pipe) ++{ ++ struct vsp1_entity *entity; ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&pipe->irqlock, flags); ++ pipe->state = VSP1_PIPELINE_STOPPING; ++ spin_unlock_irqrestore(&pipe->irqlock, flags); ++ ++ ret = wait_event_timeout(pipe->wq, pipe->state == VSP1_PIPELINE_STOPPED, ++ msecs_to_jiffies(500)); ++ ret = ret == 0 ? -ETIMEDOUT : 0; ++ ++ list_for_each_entry(entity, &pipe->entities, list_pipe) { ++ if (entity->route) ++ vsp1_write(entity->vsp1, entity->route, ++ VI6_DPR_NODE_UNUSED); ++ ++ v4l2_subdev_call(&entity->subdev, video, s_stream, 0); ++ } ++ ++ return ret; ++} ++ ++static bool vsp1_pipeline_ready(struct vsp1_pipeline *pipe) ++{ ++ unsigned int mask; ++ ++ mask = ((1 << pipe->num_inputs) - 1) << 1; ++ if (!pipe->lif) ++ mask |= 1 << 0; ++ ++ return pipe->buffers_ready == mask; ++} ++ ++/* ++ * vsp1_video_complete_buffer - Complete the current buffer ++ * @video: the video node ++ * ++ * This function completes the current buffer by filling its sequence number, ++ * time stamp and payload size, and hands it back to the videobuf core. ++ * ++ * Return the next queued buffer or NULL if the queue is empty. ++ */ ++static struct vsp1_video_buffer * ++vsp1_video_complete_buffer(struct vsp1_video *video) ++{ ++ struct vsp1_video_buffer *next = NULL; ++ struct vsp1_video_buffer *done; ++ unsigned long flags; ++ unsigned int i; ++ ++ spin_lock_irqsave(&video->irqlock, flags); ++ ++ if (list_empty(&video->irqqueue)) { ++ spin_unlock_irqrestore(&video->irqlock, flags); ++ return NULL; ++ } ++ ++ done = list_first_entry(&video->irqqueue, ++ struct vsp1_video_buffer, queue); ++ list_del(&done->queue); ++ ++ if (!list_empty(&video->irqqueue)) ++ next = list_first_entry(&video->irqqueue, ++ struct vsp1_video_buffer, queue); ++ ++ spin_unlock_irqrestore(&video->irqlock, flags); ++ ++ done->buf.v4l2_buf.sequence = video->sequence++; ++ v4l2_get_timestamp(&done->buf.v4l2_buf.timestamp); ++ for (i = 0; i < done->buf.num_planes; ++i) ++ vb2_set_plane_payload(&done->buf, i, done->length[i]); ++ vb2_buffer_done(&done->buf, VB2_BUF_STATE_DONE); ++ ++ return next; ++} ++ ++static void vsp1_video_frame_end(struct vsp1_pipeline *pipe, ++ struct vsp1_video *video) ++{ ++ struct vsp1_video_buffer *buf; ++ unsigned long flags; ++ ++ buf = vsp1_video_complete_buffer(video); ++ if (buf == NULL) ++ return; ++ ++ spin_lock_irqsave(&pipe->irqlock, flags); ++ ++ video->ops->queue(video, buf); ++ pipe->buffers_ready |= 1 << video->pipe_index; ++ ++ spin_unlock_irqrestore(&pipe->irqlock, flags); ++} ++ ++void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe) ++{ ++ unsigned long flags; ++ unsigned int i; ++ ++ if (pipe == NULL) ++ return; ++ ++ /* Complete buffers on all video nodes. */ ++ for (i = 0; i < pipe->num_inputs; ++i) ++ vsp1_video_frame_end(pipe, &pipe->inputs[i]->video); ++ ++ if (!pipe->lif) ++ vsp1_video_frame_end(pipe, &pipe->output->video); ++ ++ spin_lock_irqsave(&pipe->irqlock, flags); ++ ++ /* If a stop has been requested, mark the pipeline as stopped and ++ * return. ++ */ ++ if (pipe->state == VSP1_PIPELINE_STOPPING) { ++ pipe->state = VSP1_PIPELINE_STOPPED; ++ wake_up(&pipe->wq); ++ goto done; ++ } ++ ++ /* Restart the pipeline if ready. */ ++ if (vsp1_pipeline_ready(pipe)) ++ vsp1_pipeline_run(pipe); ++ ++done: ++ spin_unlock_irqrestore(&pipe->irqlock, flags); ++} ++ ++/* ----------------------------------------------------------------------------- ++ * videobuf2 Queue Operations ++ */ ++ ++static int ++vsp1_video_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, ++ unsigned int *nbuffers, unsigned int *nplanes, ++ unsigned int sizes[], void *alloc_ctxs[]) ++{ ++ struct vsp1_video *video = vb2_get_drv_priv(vq); ++ const struct v4l2_pix_format_mplane *format; ++ struct v4l2_pix_format_mplane pix_mp; ++ unsigned int i; ++ ++ if (fmt) { ++ /* Make sure the format is valid and adjust the sizeimage field ++ * if needed. ++ */ ++ if (!vsp1_video_format_adjust(video, &fmt->fmt.pix_mp, &pix_mp)) ++ return -EINVAL; ++ ++ format = &pix_mp; ++ } else { ++ format = &video->format; ++ } ++ ++ *nplanes = format->num_planes; ++ ++ for (i = 0; i < format->num_planes; ++i) { ++ sizes[i] = format->plane_fmt[i].sizeimage; ++ alloc_ctxs[i] = video->alloc_ctx; ++ } ++ ++ return 0; ++} ++ ++static int vsp1_video_buffer_prepare(struct vb2_buffer *vb) ++{ ++ struct vsp1_video *video = vb2_get_drv_priv(vb->vb2_queue); ++ struct vsp1_video_buffer *buf = to_vsp1_video_buffer(vb); ++ const struct v4l2_pix_format_mplane *format = &video->format; ++ unsigned int i; ++ ++ if (vb->num_planes < format->num_planes) ++ return -EINVAL; ++ ++ buf->video = video; ++ ++ for (i = 0; i < vb->num_planes; ++i) { ++ buf->addr[i] = vb2_dma_contig_plane_dma_addr(vb, i); ++ buf->length[i] = vb2_plane_size(vb, i); ++ ++ if (buf->length[i] < format->plane_fmt[i].sizeimage) ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static void vsp1_video_buffer_queue(struct vb2_buffer *vb) ++{ ++ struct vsp1_video *video = vb2_get_drv_priv(vb->vb2_queue); ++ struct vsp1_pipeline *pipe = to_vsp1_pipeline(&video->video.entity); ++ struct vsp1_video_buffer *buf = to_vsp1_video_buffer(vb); ++ unsigned long flags; ++ bool empty; ++ ++ spin_lock_irqsave(&video->irqlock, flags); ++ empty = list_empty(&video->irqqueue); ++ list_add_tail(&buf->queue, &video->irqqueue); ++ spin_unlock_irqrestore(&video->irqlock, flags); ++ ++ if (!empty) ++ return; ++ ++ spin_lock_irqsave(&pipe->irqlock, flags); ++ ++ video->ops->queue(video, buf); ++ pipe->buffers_ready |= 1 << video->pipe_index; ++ ++ if (vb2_is_streaming(&video->queue) && ++ vsp1_pipeline_ready(pipe)) ++ vsp1_pipeline_run(pipe); ++ ++ spin_unlock_irqrestore(&pipe->irqlock, flags); ++} ++ ++static void vsp1_entity_route_setup(struct vsp1_entity *source) ++{ ++ struct vsp1_entity *sink; ++ ++ if (source->route == 0) ++ return; ++ ++ sink = container_of(source->sink, struct vsp1_entity, subdev.entity); ++ vsp1_write(source->vsp1, source->route, sink->id); ++} ++ ++static int vsp1_video_start_streaming(struct vb2_queue *vq, unsigned int count) ++{ ++ struct vsp1_video *video = vb2_get_drv_priv(vq); ++ struct vsp1_pipeline *pipe = to_vsp1_pipeline(&video->video.entity); ++ struct vsp1_entity *entity; ++ unsigned long flags; ++ int ret; ++ ++ mutex_lock(&pipe->lock); ++ if (pipe->stream_count == pipe->num_video - 1) { ++ list_for_each_entry(entity, &pipe->entities, list_pipe) { ++ vsp1_entity_route_setup(entity); ++ ++ ret = v4l2_subdev_call(&entity->subdev, video, ++ s_stream, 1); ++ if (ret < 0) { ++ mutex_unlock(&pipe->lock); ++ return ret; ++ } ++ } ++ } ++ ++ pipe->stream_count++; ++ mutex_unlock(&pipe->lock); ++ ++ spin_lock_irqsave(&pipe->irqlock, flags); ++ if (vsp1_pipeline_ready(pipe)) ++ vsp1_pipeline_run(pipe); ++ spin_unlock_irqrestore(&pipe->irqlock, flags); ++ ++ return 0; ++} ++ ++static int vsp1_video_stop_streaming(struct vb2_queue *vq) ++{ ++ struct vsp1_video *video = vb2_get_drv_priv(vq); ++ struct vsp1_pipeline *pipe = to_vsp1_pipeline(&video->video.entity); ++ unsigned long flags; ++ int ret; ++ ++ mutex_lock(&pipe->lock); ++ if (--pipe->stream_count == 0) { ++ /* Stop the pipeline. */ ++ ret = vsp1_pipeline_stop(pipe); ++ if (ret == -ETIMEDOUT) ++ dev_err(video->vsp1->dev, "pipeline stop timeout\n"); ++ } ++ mutex_unlock(&pipe->lock); ++ ++ vsp1_pipeline_cleanup(pipe); ++ media_entity_pipeline_stop(&video->video.entity); ++ ++ /* Remove all buffers from the IRQ queue. */ ++ spin_lock_irqsave(&video->irqlock, flags); ++ INIT_LIST_HEAD(&video->irqqueue); ++ spin_unlock_irqrestore(&video->irqlock, flags); ++ ++ return 0; ++} ++ ++static struct vb2_ops vsp1_video_queue_qops = { ++ .queue_setup = vsp1_video_queue_setup, ++ .buf_prepare = vsp1_video_buffer_prepare, ++ .buf_queue = vsp1_video_buffer_queue, ++ .wait_prepare = vb2_ops_wait_prepare, ++ .wait_finish = vb2_ops_wait_finish, ++ .start_streaming = vsp1_video_start_streaming, ++ .stop_streaming = vsp1_video_stop_streaming, ++}; ++ ++/* ----------------------------------------------------------------------------- ++ * V4L2 ioctls ++ */ ++ ++static int ++vsp1_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap) ++{ ++ struct v4l2_fh *vfh = file->private_data; ++ struct vsp1_video *video = to_vsp1_video(vfh->vdev); ++ ++ cap->capabilities = V4L2_CAP_DEVICE_CAPS | V4L2_CAP_STREAMING ++ | V4L2_CAP_VIDEO_CAPTURE_MPLANE ++ | V4L2_CAP_VIDEO_OUTPUT_MPLANE; ++ ++ if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) ++ cap->device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE ++ | V4L2_CAP_STREAMING; ++ else ++ cap->device_caps = V4L2_CAP_VIDEO_OUTPUT_MPLANE ++ | V4L2_CAP_STREAMING; ++ ++ strlcpy(cap->driver, "vsp1", sizeof(cap->driver)); ++ strlcpy(cap->card, video->video.name, sizeof(cap->card)); ++ snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", ++ dev_name(video->vsp1->dev)); ++ ++ return 0; ++} ++ ++static int ++vsp1_video_get_format(struct file *file, void *fh, struct v4l2_format *format) ++{ ++ struct v4l2_fh *vfh = file->private_data; ++ struct vsp1_video *video = to_vsp1_video(vfh->vdev); ++ ++ if (format->type != video->queue.type) ++ return -EINVAL; ++ ++ mutex_lock(&video->lock); ++ format->fmt.pix_mp = video->format; ++ mutex_unlock(&video->lock); ++ ++ return 0; ++} ++ ++static int ++vsp1_video_try_format(struct file *file, void *fh, struct v4l2_format *format) ++{ ++ struct v4l2_fh *vfh = file->private_data; ++ struct vsp1_video *video = to_vsp1_video(vfh->vdev); ++ ++ if (format->type != video->queue.type) ++ return -EINVAL; ++ ++ return __vsp1_video_try_format(video, &format->fmt.pix_mp, NULL); ++} ++ ++static int ++vsp1_video_set_format(struct file *file, void *fh, struct v4l2_format *format) ++{ ++ struct v4l2_fh *vfh = file->private_data; ++ struct vsp1_video *video = to_vsp1_video(vfh->vdev); ++ const struct vsp1_format_info *info; ++ int ret; ++ ++ if (format->type != video->queue.type) ++ return -EINVAL; ++ ++ ret = __vsp1_video_try_format(video, &format->fmt.pix_mp, &info); ++ if (ret < 0) ++ return ret; ++ ++ mutex_lock(&video->lock); ++ ++ if (vb2_is_busy(&video->queue)) { ++ ret = -EBUSY; ++ goto done; ++ } ++ ++ video->format = format->fmt.pix_mp; ++ video->fmtinfo = info; ++ ++done: ++ mutex_unlock(&video->lock); ++ return ret; ++} ++ ++static int ++vsp1_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) ++{ ++ struct v4l2_fh *vfh = file->private_data; ++ struct vsp1_video *video = to_vsp1_video(vfh->vdev); ++ struct vsp1_pipeline *pipe; ++ int ret; ++ ++ mutex_lock(&video->lock); ++ ++ if (video->queue.owner && video->queue.owner != file->private_data) ++ return -EBUSY; ++ ++ video->sequence = 0; ++ ++ /* Start streaming on the pipeline. No link touching an entity in the ++ * pipeline can be activated or deactivated once streaming is started. ++ * ++ * Use the VSP1 pipeline object embedded in the first video object that ++ * starts streaming. ++ */ ++ pipe = video->video.entity.pipe ++ ? to_vsp1_pipeline(&video->video.entity) : &video->pipe; ++ ++ ret = media_entity_pipeline_start(&video->video.entity, &pipe->pipe); ++ if (ret < 0) ++ return ret; ++ ++ /* Verify that the configured format matches the output of the connected ++ * subdev. ++ */ ++ ret = vsp1_video_verify_format(video); ++ if (ret < 0) ++ goto err_stop; ++ ++ ret = vsp1_pipeline_init(pipe, video); ++ if (ret < 0) ++ goto err_stop; ++ ++ /* Start the queue. */ ++ ret = vb2_streamon(&video->queue, type); ++ if (ret < 0) ++ goto err_cleanup; ++ ++ return 0; ++ ++err_cleanup: ++ vsp1_pipeline_cleanup(pipe); ++err_stop: ++ media_entity_pipeline_stop(&video->video.entity); ++ return ret; ++} ++ ++static const struct v4l2_ioctl_ops vsp1_video_ioctl_ops = { ++ .vidioc_querycap = vsp1_video_querycap, ++ .vidioc_g_fmt_vid_cap_mplane = vsp1_video_get_format, ++ .vidioc_s_fmt_vid_cap_mplane = vsp1_video_set_format, ++ .vidioc_try_fmt_vid_cap_mplane = vsp1_video_try_format, ++ .vidioc_g_fmt_vid_out_mplane = vsp1_video_get_format, ++ .vidioc_s_fmt_vid_out_mplane = vsp1_video_set_format, ++ .vidioc_try_fmt_vid_out_mplane = vsp1_video_try_format, ++ .vidioc_reqbufs = vb2_ioctl_reqbufs, ++ .vidioc_querybuf = vb2_ioctl_querybuf, ++ .vidioc_qbuf = vb2_ioctl_qbuf, ++ .vidioc_dqbuf = vb2_ioctl_dqbuf, ++ .vidioc_create_bufs = vb2_ioctl_create_bufs, ++ .vidioc_prepare_buf = vb2_ioctl_prepare_buf, ++ .vidioc_streamon = vsp1_video_streamon, ++ .vidioc_streamoff = vb2_ioctl_streamoff, ++}; ++ ++/* ----------------------------------------------------------------------------- ++ * V4L2 File Operations ++ */ ++ ++static int vsp1_video_open(struct file *file) ++{ ++ struct vsp1_video *video = video_drvdata(file); ++ struct v4l2_fh *vfh; ++ int ret = 0; ++ ++ vfh = kzalloc(sizeof(*vfh), GFP_KERNEL); ++ if (vfh == NULL) ++ return -ENOMEM; ++ ++ v4l2_fh_init(vfh, &video->video); ++ v4l2_fh_add(vfh); ++ ++ file->private_data = vfh; ++ ++ if (!vsp1_device_get(video->vsp1)) { ++ ret = -EBUSY; ++ v4l2_fh_del(vfh); ++ kfree(vfh); ++ } ++ ++ return ret; ++} ++ ++static int vsp1_video_release(struct file *file) ++{ ++ struct vsp1_video *video = video_drvdata(file); ++ struct v4l2_fh *vfh = file->private_data; ++ ++ mutex_lock(&video->lock); ++ if (video->queue.owner == vfh) { ++ vb2_queue_release(&video->queue); ++ video->queue.owner = NULL; ++ } ++ mutex_unlock(&video->lock); ++ ++ vsp1_device_put(video->vsp1); ++ ++ v4l2_fh_release(file); ++ ++ file->private_data = NULL; ++ ++ return 0; ++} ++ ++static struct v4l2_file_operations vsp1_video_fops = { ++ .owner = THIS_MODULE, ++ .unlocked_ioctl = video_ioctl2, ++ .open = vsp1_video_open, ++ .release = vsp1_video_release, ++ .poll = vb2_fop_poll, ++ .mmap = vb2_fop_mmap, ++}; ++ ++/* ----------------------------------------------------------------------------- ++ * Initialization and Cleanup ++ */ ++ ++int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf) ++{ ++ const char *direction; ++ int ret; ++ ++ switch (video->type) { ++ case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: ++ direction = "output"; ++ video->pad.flags = MEDIA_PAD_FL_SINK; ++ break; ++ ++ case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: ++ direction = "input"; ++ video->pad.flags = MEDIA_PAD_FL_SOURCE; ++ video->video.vfl_dir = VFL_DIR_TX; ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ video->rwpf = rwpf; ++ ++ mutex_init(&video->lock); ++ spin_lock_init(&video->irqlock); ++ INIT_LIST_HEAD(&video->irqqueue); ++ ++ mutex_init(&video->pipe.lock); ++ spin_lock_init(&video->pipe.irqlock); ++ INIT_LIST_HEAD(&video->pipe.entities); ++ init_waitqueue_head(&video->pipe.wq); ++ video->pipe.state = VSP1_PIPELINE_STOPPED; ++ ++ /* Initialize the media entity... */ ++ ret = media_entity_init(&video->video.entity, 1, &video->pad, 0); ++ if (ret < 0) ++ return ret; ++ ++ /* ... and the format ... */ ++ video->fmtinfo = vsp1_get_format_info(VSP1_VIDEO_DEF_FORMAT); ++ video->format.pixelformat = video->fmtinfo->fourcc; ++ video->format.colorspace = V4L2_COLORSPACE_SRGB; ++ video->format.field = V4L2_FIELD_NONE; ++ video->format.width = VSP1_VIDEO_DEF_WIDTH; ++ video->format.height = VSP1_VIDEO_DEF_HEIGHT; ++ video->format.num_planes = 1; ++ video->format.plane_fmt[0].bytesperline = ++ video->format.width * video->fmtinfo->bpp[0] / 8; ++ video->format.plane_fmt[0].sizeimage = ++ video->format.plane_fmt[0].bytesperline * video->format.height; ++ ++ /* ... and the video node... */ ++ video->video.v4l2_dev = &video->vsp1->v4l2_dev; ++ video->video.fops = &vsp1_video_fops; ++ snprintf(video->video.name, sizeof(video->video.name), "%s %s", ++ rwpf->subdev.name, direction); ++ video->video.vfl_type = VFL_TYPE_GRABBER; ++ video->video.release = video_device_release_empty; ++ video->video.ioctl_ops = &vsp1_video_ioctl_ops; ++ ++ video_set_drvdata(&video->video, video); ++ ++ /* ... and the buffers queue... */ ++ video->alloc_ctx = vb2_dma_contig_init_ctx(video->vsp1->dev); ++ if (IS_ERR(video->alloc_ctx)) ++ goto error; ++ ++ video->queue.type = video->type; ++ video->queue.io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF; ++ video->queue.lock = &video->lock; ++ video->queue.drv_priv = video; ++ video->queue.buf_struct_size = sizeof(struct vsp1_video_buffer); ++ video->queue.ops = &vsp1_video_queue_qops; ++ video->queue.mem_ops = &vb2_dma_contig_memops; ++ video->queue.timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY; ++ ret = vb2_queue_init(&video->queue); ++ if (ret < 0) { ++ dev_err(video->vsp1->dev, "failed to initialize vb2 queue\n"); ++ goto error; ++ } ++ ++ /* ... and register the video device. */ ++ video->video.queue = &video->queue; ++ ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1); ++ if (ret < 0) { ++ dev_err(video->vsp1->dev, "failed to register video device\n"); ++ goto error; ++ } ++ ++ return 0; ++ ++error: ++ vb2_dma_contig_cleanup_ctx(video->alloc_ctx); ++ vsp1_video_cleanup(video); ++ return ret; ++} ++ ++void vsp1_video_cleanup(struct vsp1_video *video) ++{ ++ if (video_is_registered(&video->video)) ++ video_unregister_device(&video->video); ++ ++ vb2_dma_contig_cleanup_ctx(video->alloc_ctx); ++ media_entity_cleanup(&video->video.entity); ++} +diff --git a/drivers/media/platform/vsp1/vsp1_video.h b/drivers/media/platform/vsp1/vsp1_video.h +new file mode 100644 +index 000000000000..d8612a378345 +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1_video.h +@@ -0,0 +1,144 @@ ++/* ++ * vsp1_video.h -- R-Car VSP1 Video Node ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++#ifndef __VSP1_VIDEO_H__ ++#define __VSP1_VIDEO_H__ ++ ++#include <linux/list.h> ++#include <linux/spinlock.h> ++#include <linux/wait.h> ++ ++#include <media/media-entity.h> ++#include <media/videobuf2-core.h> ++ ++struct vsp1_video; ++ ++/* ++ * struct vsp1_format_info - VSP1 video format description ++ * @mbus: media bus format code ++ * @fourcc: V4L2 pixel format FCC identifier ++ * @planes: number of planes ++ * @bpp: bits per pixel ++ * @hwfmt: VSP1 hardware format ++ * @swap_yc: the Y and C components are swapped (Y comes before C) ++ * @swap_uv: the U and V components are swapped (V comes before U) ++ * @hsub: horizontal subsampling factor ++ * @vsub: vertical subsampling factor ++ */ ++struct vsp1_format_info { ++ u32 fourcc; ++ unsigned int mbus; ++ unsigned int hwfmt; ++ unsigned int swap; ++ unsigned int planes; ++ unsigned int bpp[3]; ++ bool swap_yc; ++ bool swap_uv; ++ unsigned int hsub; ++ unsigned int vsub; ++}; ++ ++enum vsp1_pipeline_state { ++ VSP1_PIPELINE_STOPPED, ++ VSP1_PIPELINE_RUNNING, ++ VSP1_PIPELINE_STOPPING, ++}; ++ ++/* ++ * struct vsp1_pipeline - A VSP1 hardware pipeline ++ * @media: the media pipeline ++ * @irqlock: protects the pipeline state ++ * @lock: protects the pipeline use count and stream count ++ */ ++struct vsp1_pipeline { ++ struct media_pipeline pipe; ++ ++ spinlock_t irqlock; ++ enum vsp1_pipeline_state state; ++ wait_queue_head_t wq; ++ ++ struct mutex lock; ++ unsigned int use_count; ++ unsigned int stream_count; ++ unsigned int buffers_ready; ++ ++ unsigned int num_video; ++ unsigned int num_inputs; ++ struct vsp1_rwpf *inputs[VPS1_MAX_RPF]; ++ struct vsp1_rwpf *output; ++ struct vsp1_entity *lif; ++ ++ struct list_head entities; ++}; ++ ++static inline struct vsp1_pipeline *to_vsp1_pipeline(struct media_entity *e) ++{ ++ if (likely(e->pipe)) ++ return container_of(e->pipe, struct vsp1_pipeline, pipe); ++ else ++ return NULL; ++} ++ ++struct vsp1_video_buffer { ++ struct vsp1_video *video; ++ struct vb2_buffer buf; ++ struct list_head queue; ++ ++ dma_addr_t addr[3]; ++ unsigned int length[3]; ++}; ++ ++static inline struct vsp1_video_buffer * ++to_vsp1_video_buffer(struct vb2_buffer *vb) ++{ ++ return container_of(vb, struct vsp1_video_buffer, buf); ++} ++ ++struct vsp1_video_operations { ++ void (*queue)(struct vsp1_video *video, struct vsp1_video_buffer *buf); ++}; ++ ++struct vsp1_video { ++ struct vsp1_device *vsp1; ++ struct vsp1_entity *rwpf; ++ ++ const struct vsp1_video_operations *ops; ++ ++ struct video_device video; ++ enum v4l2_buf_type type; ++ struct media_pad pad; ++ ++ struct mutex lock; ++ struct v4l2_pix_format_mplane format; ++ const struct vsp1_format_info *fmtinfo; ++ ++ struct vsp1_pipeline pipe; ++ unsigned int pipe_index; ++ ++ struct vb2_queue queue; ++ void *alloc_ctx; ++ spinlock_t irqlock; ++ struct list_head irqqueue; ++ unsigned int sequence; ++}; ++ ++static inline struct vsp1_video *to_vsp1_video(struct video_device *vdev) ++{ ++ return container_of(vdev, struct vsp1_video, video); ++} ++ ++int vsp1_video_init(struct vsp1_video *video, struct vsp1_entity *rwpf); ++void vsp1_video_cleanup(struct vsp1_video *video); ++ ++void vsp1_pipeline_frame_end(struct vsp1_pipeline *pipe); ++ ++#endif /* __VSP1_VIDEO_H__ */ +diff --git a/drivers/media/platform/vsp1/vsp1_wpf.c b/drivers/media/platform/vsp1/vsp1_wpf.c +new file mode 100644 +index 000000000000..db4b85ee05fc +--- /dev/null ++++ b/drivers/media/platform/vsp1/vsp1_wpf.c +@@ -0,0 +1,233 @@ ++/* ++ * vsp1_wpf.c -- R-Car VSP1 Write Pixel Formatter ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++ ++#include <linux/device.h> ++ ++#include <media/v4l2-subdev.h> ++ ++#include "vsp1.h" ++#include "vsp1_rwpf.h" ++#include "vsp1_video.h" ++ ++#define WPF_MAX_WIDTH 2048 ++#define WPF_MAX_HEIGHT 2048 ++ ++/* ----------------------------------------------------------------------------- ++ * Device Access ++ */ ++ ++static inline u32 vsp1_wpf_read(struct vsp1_rwpf *wpf, u32 reg) ++{ ++ return vsp1_read(wpf->entity.vsp1, ++ reg + wpf->entity.index * VI6_WPF_OFFSET); ++} ++ ++static inline void vsp1_wpf_write(struct vsp1_rwpf *wpf, u32 reg, u32 data) ++{ ++ vsp1_write(wpf->entity.vsp1, ++ reg + wpf->entity.index * VI6_WPF_OFFSET, data); ++} ++ ++/* ----------------------------------------------------------------------------- ++ * V4L2 Subdevice Core Operations ++ */ ++ ++static int wpf_s_stream(struct v4l2_subdev *subdev, int enable) ++{ ++ struct vsp1_rwpf *wpf = to_rwpf(subdev); ++ struct vsp1_pipeline *pipe = ++ to_vsp1_pipeline(&wpf->entity.subdev.entity); ++ struct vsp1_device *vsp1 = wpf->entity.vsp1; ++ const struct v4l2_mbus_framefmt *format = ++ &wpf->entity.formats[RWPF_PAD_SOURCE]; ++ unsigned int i; ++ u32 srcrpf = 0; ++ u32 outfmt = 0; ++ ++ if (!enable) { ++ vsp1_write(vsp1, VI6_WPF_IRQ_ENB(wpf->entity.index), 0); ++ return 0; ++ } ++ ++ /* Sources */ ++ for (i = 0; i < pipe->num_inputs; ++i) { ++ struct vsp1_rwpf *input = pipe->inputs[i]; ++ ++ srcrpf |= VI6_WPF_SRCRPF_RPF_ACT_MST(input->entity.index); ++ } ++ ++ vsp1_wpf_write(wpf, VI6_WPF_SRCRPF, srcrpf); ++ ++ /* Destination stride. Cropping isn't supported yet. */ ++ if (!pipe->lif) { ++ struct v4l2_pix_format_mplane *format = &wpf->video.format; ++ ++ vsp1_wpf_write(wpf, VI6_WPF_DSTM_STRIDE_Y, ++ format->plane_fmt[0].bytesperline); ++ if (format->num_planes > 1) ++ vsp1_wpf_write(wpf, VI6_WPF_DSTM_STRIDE_C, ++ format->plane_fmt[1].bytesperline); ++ } ++ ++ vsp1_wpf_write(wpf, VI6_WPF_HSZCLIP, ++ format->width << VI6_WPF_SZCLIP_SIZE_SHIFT); ++ vsp1_wpf_write(wpf, VI6_WPF_VSZCLIP, ++ format->height << VI6_WPF_SZCLIP_SIZE_SHIFT); ++ ++ /* Format */ ++ if (!pipe->lif) { ++ const struct vsp1_format_info *fmtinfo = wpf->video.fmtinfo; ++ ++ outfmt = fmtinfo->hwfmt << VI6_WPF_OUTFMT_WRFMT_SHIFT; ++ ++ if (fmtinfo->swap_yc) ++ outfmt |= VI6_WPF_OUTFMT_SPYCS; ++ if (fmtinfo->swap_uv) ++ outfmt |= VI6_WPF_OUTFMT_SPUVS; ++ ++ vsp1_wpf_write(wpf, VI6_WPF_DSWAP, fmtinfo->swap); ++ } ++ ++ if (wpf->entity.formats[RWPF_PAD_SINK].code != ++ wpf->entity.formats[RWPF_PAD_SOURCE].code) ++ outfmt |= VI6_WPF_OUTFMT_CSC; ++ ++ vsp1_wpf_write(wpf, VI6_WPF_OUTFMT, outfmt); ++ ++ vsp1_write(vsp1, VI6_DPR_WPF_FPORCH(wpf->entity.index), ++ VI6_DPR_WPF_FPORCH_FP_WPFN); ++ ++ vsp1_write(vsp1, VI6_WPF_WRBCK_CTRL, 0); ++ ++ /* Enable interrupts */ ++ vsp1_write(vsp1, VI6_WPF_IRQ_STA(wpf->entity.index), 0); ++ vsp1_write(vsp1, VI6_WPF_IRQ_ENB(wpf->entity.index), ++ VI6_WFP_IRQ_ENB_FREE); ++ ++ return 0; ++} ++ ++/* ----------------------------------------------------------------------------- ++ * V4L2 Subdevice Operations ++ */ ++ ++static struct v4l2_subdev_video_ops wpf_video_ops = { ++ .s_stream = wpf_s_stream, ++}; ++ ++static struct v4l2_subdev_pad_ops wpf_pad_ops = { ++ .enum_mbus_code = vsp1_rwpf_enum_mbus_code, ++ .enum_frame_size = vsp1_rwpf_enum_frame_size, ++ .get_fmt = vsp1_rwpf_get_format, ++ .set_fmt = vsp1_rwpf_set_format, ++}; ++ ++static struct v4l2_subdev_ops wpf_ops = { ++ .video = &wpf_video_ops, ++ .pad = &wpf_pad_ops, ++}; ++ ++/* ----------------------------------------------------------------------------- ++ * Video Device Operations ++ */ ++ ++static void wpf_vdev_queue(struct vsp1_video *video, ++ struct vsp1_video_buffer *buf) ++{ ++ struct vsp1_rwpf *wpf = container_of(video, struct vsp1_rwpf, video); ++ ++ vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_Y, buf->addr[0]); ++ if (buf->buf.num_planes > 1) ++ vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_C0, buf->addr[1]); ++ if (buf->buf.num_planes > 2) ++ vsp1_wpf_write(wpf, VI6_WPF_DSTM_ADDR_C1, buf->addr[2]); ++} ++ ++static const struct vsp1_video_operations wpf_vdev_ops = { ++ .queue = wpf_vdev_queue, ++}; ++ ++/* ----------------------------------------------------------------------------- ++ * Initialization and Cleanup ++ */ ++ ++struct vsp1_rwpf *vsp1_wpf_create(struct vsp1_device *vsp1, unsigned int index) ++{ ++ struct v4l2_subdev *subdev; ++ struct vsp1_video *video; ++ struct vsp1_rwpf *wpf; ++ unsigned int flags; ++ int ret; ++ ++ wpf = devm_kzalloc(vsp1->dev, sizeof(*wpf), GFP_KERNEL); ++ if (wpf == NULL) ++ return ERR_PTR(-ENOMEM); ++ ++ wpf->max_width = WPF_MAX_WIDTH; ++ wpf->max_height = WPF_MAX_HEIGHT; ++ ++ wpf->entity.type = VSP1_ENTITY_WPF; ++ wpf->entity.index = index; ++ wpf->entity.id = VI6_DPR_NODE_WPF(index); ++ ++ ret = vsp1_entity_init(vsp1, &wpf->entity, 2); ++ if (ret < 0) ++ return ERR_PTR(ret); ++ ++ /* Initialize the V4L2 subdev. */ ++ subdev = &wpf->entity.subdev; ++ v4l2_subdev_init(subdev, &wpf_ops); ++ ++ subdev->entity.ops = &vsp1_media_ops; ++ subdev->internal_ops = &vsp1_subdev_internal_ops; ++ snprintf(subdev->name, sizeof(subdev->name), "%s wpf.%u", ++ dev_name(vsp1->dev), index); ++ v4l2_set_subdevdata(subdev, wpf); ++ subdev->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; ++ ++ vsp1_entity_init_formats(subdev, NULL); ++ ++ /* Initialize the video device. */ ++ video = &wpf->video; ++ ++ video->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; ++ video->vsp1 = vsp1; ++ video->ops = &wpf_vdev_ops; ++ ++ ret = vsp1_video_init(video, &wpf->entity); ++ if (ret < 0) ++ goto error_video; ++ ++ /* Connect the video device to the WPF. All connections are immutable ++ * except for the WPF0 source link if a LIF is present. ++ */ ++ flags = MEDIA_LNK_FL_ENABLED; ++ if (!(vsp1->pdata->features & VSP1_HAS_LIF) || index != 0) ++ flags |= MEDIA_LNK_FL_IMMUTABLE; ++ ++ ret = media_entity_create_link(&wpf->entity.subdev.entity, ++ RWPF_PAD_SOURCE, ++ &wpf->video.video.entity, 0, flags); ++ if (ret < 0) ++ goto error_link; ++ ++ wpf->entity.sink = &wpf->video.video.entity; ++ ++ return wpf; ++ ++error_link: ++ vsp1_video_cleanup(video); ++error_video: ++ media_entity_cleanup(&wpf->entity.subdev.entity); ++ return ERR_PTR(ret); ++} +diff --git a/include/linux/platform_data/vsp1.h b/include/linux/platform_data/vsp1.h +new file mode 100644 +index 000000000000..a73a456d7f11 +--- /dev/null ++++ b/include/linux/platform_data/vsp1.h +@@ -0,0 +1,25 @@ ++/* ++ * vsp1.h -- R-Car VSP1 Platform Data ++ * ++ * Copyright (C) 2013 Renesas Corporation ++ * ++ * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com) ++ * ++ * 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, or ++ * (at your option) any later version. ++ */ ++#ifndef __PLATFORM_VSP1_H__ ++#define __PLATFORM_VSP1_H__ ++ ++#define VSP1_HAS_LIF (1 << 0) ++ ++struct vsp1_platform_data { ++ unsigned int features; ++ unsigned int rpf_count; ++ unsigned int uds_count; ++ unsigned int wpf_count; ++}; ++ ++#endif /* __PLATFORM_VSP1_H__ */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0038-media-vsp1-Fix-lack-of-the-sink-entity-registration-.patch b/patches.renesas/0038-media-vsp1-Fix-lack-of-the-sink-entity-registration-.patch new file mode 100644 index 00000000000000..67ebc100f87993 --- /dev/null +++ b/patches.renesas/0038-media-vsp1-Fix-lack-of-the-sink-entity-registration-.patch @@ -0,0 +1,42 @@ +From be8e1de59d33d8b661fad6a8a5aaeec63351e66d Mon Sep 17 00:00:00 2001 +From: Katsuya Matsubara <matsu@igel.co.jp> +Date: Fri, 26 Jul 2013 06:32:11 -0300 +Subject: [media] vsp1: Fix lack of the sink entity registration for enabled + links + +Each source entity maintains a pointer to the counterpart sink +entity while an enabled link connects them. It should be managed by +the setup_link callback in the media controller framework at runtime. +However, enabled links which connect RPFs and WPFs that have an +equivalent index number are created during initialization. +This registers the pointer to a sink entity from the source entity +when an enabled link is created. + +Signed-off-by: Katsuya Matsubara <matsu@igel.co.jp> +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Sakari Ailus <sakari.ailus@iki.fi> +Acked-by: Hans Verkuil <hans.verkuil@cisco.com> +Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> +(cherry picked from commit db32eb6c18d7617e61ca65eb13b66de4dea56f1f) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/media/platform/vsp1/vsp1_drv.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c +index e58e49c88415..41dd891d9737 100644 +--- a/drivers/media/platform/vsp1/vsp1_drv.c ++++ b/drivers/media/platform/vsp1/vsp1_drv.c +@@ -101,6 +101,9 @@ static int vsp1_create_links(struct vsp1_device *vsp1, struct vsp1_entity *sink) + entity, pad, flags); + if (ret < 0) + return ret; ++ ++ if (flags & MEDIA_LNK_FL_ENABLED) ++ source->sink = entity; + } + } + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0039-media-vsp1-Use-the-maximum-number-of-entities-define.patch b/patches.renesas/0039-media-vsp1-Use-the-maximum-number-of-entities-define.patch new file mode 100644 index 00000000000000..ea4be79cdd7f43 --- /dev/null +++ b/patches.renesas/0039-media-vsp1-Use-the-maximum-number-of-entities-define.patch @@ -0,0 +1,59 @@ +From a71352de52d6a052e3efab6dca59cd036435b6b3 Mon Sep 17 00:00:00 2001 +From: Katsuya Matsubara <matsu@igel.co.jp> +Date: Fri, 26 Jul 2013 06:32:12 -0300 +Subject: [media] vsp1: Use the maximum number of entities defined in platform + data + +The VSP1 driver allows to define the maximum number of each module +such as RPF, WPF, and UDS in a platform data definition. +This suppresses operations for nonexistent or unused modules. + +Signed-off-by: Katsuya Matsubara <matsu@igel.co.jp> +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Sakari Ailus <sakari.ailus@iki.fi> +Acked-by: Hans Verkuil <hans.verkuil@cisco.com> +Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> +(cherry picked from commit 83453a7cc8b703ce818c24c2298822b0b179e652) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/media/platform/vsp1/vsp1_drv.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c +index 41dd891d9737..8700842edcf2 100644 +--- a/drivers/media/platform/vsp1/vsp1_drv.c ++++ b/drivers/media/platform/vsp1/vsp1_drv.c +@@ -35,7 +35,7 @@ static irqreturn_t vsp1_irq_handler(int irq, void *data) + irqreturn_t ret = IRQ_NONE; + unsigned int i; + +- for (i = 0; i < VPS1_MAX_WPF; ++i) { ++ for (i = 0; i < vsp1->pdata->wpf_count; ++i) { + struct vsp1_rwpf *wpf = vsp1->wpf[i]; + struct vsp1_pipeline *pipe; + u32 status; +@@ -243,7 +243,7 @@ static int vsp1_device_init(struct vsp1_device *vsp1) + /* Reset any channel that might be running. */ + status = vsp1_read(vsp1, VI6_STATUS); + +- for (i = 0; i < VPS1_MAX_WPF; ++i) { ++ for (i = 0; i < vsp1->pdata->wpf_count; ++i) { + unsigned int timeout; + + if (!(status & VI6_STATUS_SYS_ACT(i))) +@@ -267,10 +267,10 @@ static int vsp1_device_init(struct vsp1_device *vsp1) + vsp1_write(vsp1, VI6_CLK_DCSWT, (8 << VI6_CLK_DCSWT_CSTPW_SHIFT) | + (8 << VI6_CLK_DCSWT_CSTRW_SHIFT)); + +- for (i = 0; i < VPS1_MAX_RPF; ++i) ++ for (i = 0; i < vsp1->pdata->rpf_count; ++i) + vsp1_write(vsp1, VI6_DPR_RPF_ROUTE(i), VI6_DPR_NODE_UNUSED); + +- for (i = 0; i < VPS1_MAX_UDS; ++i) ++ for (i = 0; i < vsp1->pdata->uds_count; ++i) + vsp1_write(vsp1, VI6_DPR_UDS_ROUTE(i), VI6_DPR_NODE_UNUSED); + + vsp1_write(vsp1, VI6_DPR_SRU_ROUTE, VI6_DPR_NODE_UNUSED); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0040-media-vsp1-Fix-a-sparse-warning.patch b/patches.renesas/0040-media-vsp1-Fix-a-sparse-warning.patch new file mode 100644 index 00000000000000..ec6cd167f7810c --- /dev/null +++ b/patches.renesas/0040-media-vsp1-Fix-a-sparse-warning.patch @@ -0,0 +1,40 @@ +From fef254ab94691e36a7b75072bec76caf68169d39 Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab <m.chehab@samsung.com> +Date: Sat, 24 Aug 2013 08:47:51 -0300 +Subject: [media] vsp1: Fix a sparse warning + +As reported by: kbuild test robot <fengguang.wu@intel.com>: + drivers/media/platform/vsp1/vsp1_drv.c:434:21: sparse: cast removes address space of expression + + 433 vsp1->mmio = devm_ioremap_resource(&pdev->dev, io); + > 434 if (IS_ERR((void *)vsp1->mmio)) + > 435 return PTR_ERR((void *)vsp1->mmio); + +There's no need to convert it to void *. + +Reported-by: kbuild test robot <fengguang.wu@intel.com> +Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> +(cherry picked from commit cbec6d3ab470565536480d3bd109a7fdb128c3c4) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/media/platform/vsp1/vsp1_drv.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c +index 8700842edcf2..ff8cd2d6be39 100644 +--- a/drivers/media/platform/vsp1/vsp1_drv.c ++++ b/drivers/media/platform/vsp1/vsp1_drv.c +@@ -434,8 +434,8 @@ static int vsp1_probe(struct platform_device *pdev) + /* I/O, IRQ and clock resources */ + io = platform_get_resource(pdev, IORESOURCE_MEM, 0); + vsp1->mmio = devm_ioremap_resource(&pdev->dev, io); +- if (IS_ERR((void *)vsp1->mmio)) +- return PTR_ERR((void *)vsp1->mmio); ++ if (IS_ERR(vsp1->mmio)) ++ return PTR_ERR(vsp1->mmio); + + vsp1->clock = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(vsp1->clock)) { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0041-media-v4l-vsp1-Initialize-media-device-bus_info-fiel.patch b/patches.renesas/0041-media-v4l-vsp1-Initialize-media-device-bus_info-fiel.patch new file mode 100644 index 00000000000000..7d5843d0deab46 --- /dev/null +++ b/patches.renesas/0041-media-v4l-vsp1-Initialize-media-device-bus_info-fiel.patch @@ -0,0 +1,31 @@ +From 5ea1ffa5349ca0e4e4ba50afbf2f5fec378dc2b9 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 22 Aug 2013 14:11:47 -0300 +Subject: [media] v4l: vsp1: Initialize media device bus_info field + +Fill bus_info with the VSP1 platform device name + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> +(cherry picked from commit 10d79b995be5399be0a59a72859ac4bfdf066299) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/media/platform/vsp1/vsp1_drv.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c +index ff8cd2d6be39..aa8b9b288e61 100644 +--- a/drivers/media/platform/vsp1/vsp1_drv.c ++++ b/drivers/media/platform/vsp1/vsp1_drv.c +@@ -134,6 +134,8 @@ static int vsp1_create_entities(struct vsp1_device *vsp1) + + mdev->dev = vsp1->dev; + strlcpy(mdev->model, "VSP1", sizeof(mdev->model)); ++ snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s", ++ dev_name(mdev->dev)); + ret = media_device_register(mdev); + if (ret < 0) { + dev_err(vsp1->dev, "media device registration failed (%d)\n", +-- +1.8.5.rc3 + diff --git a/patches.renesas/0042-media-v4l-vsp1-Add-support-for-RT-clock.patch b/patches.renesas/0042-media-v4l-vsp1-Add-support-for-RT-clock.patch new file mode 100644 index 00000000000000..65c1d062557914 --- /dev/null +++ b/patches.renesas/0042-media-v4l-vsp1-Add-support-for-RT-clock.patch @@ -0,0 +1,128 @@ +From fae12653260a4239292531c83e581ae4a84f83b1 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 22 Aug 2013 14:29:46 -0300 +Subject: [media] v4l: vsp1: Add support for RT clock + +The VSPR and VSPS instances use two clocks, the VSP1 system clock and +the VSP1 realtime clock. Both of them need to be enabled to access the +VSP1 registers. +Add support for an optional RT clock and enable/disable it along with +the system clock. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> +(cherry picked from commit f2226a33bf9a431f616b435aa10a9ad4fea1d042) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/media/platform/vsp1/vsp1.h | 1 + + drivers/media/platform/vsp1/vsp1_drv.c | 40 +++++++++++++++++++++++++++++----- + 2 files changed, 36 insertions(+), 5 deletions(-) + +diff --git a/drivers/media/platform/vsp1/vsp1.h b/drivers/media/platform/vsp1/vsp1.h +index 11ac94bec3a3..d6c6ecd039ff 100644 +--- a/drivers/media/platform/vsp1/vsp1.h ++++ b/drivers/media/platform/vsp1/vsp1.h +@@ -42,6 +42,7 @@ struct vsp1_device { + + void __iomem *mmio; + struct clk *clock; ++ struct clk *rt_clock; + + struct mutex lock; + int ref_count; +diff --git a/drivers/media/platform/vsp1/vsp1_drv.c b/drivers/media/platform/vsp1/vsp1_drv.c +index aa8b9b288e61..1c9e771aa15c 100644 +--- a/drivers/media/platform/vsp1/vsp1_drv.c ++++ b/drivers/media/platform/vsp1/vsp1_drv.c +@@ -290,6 +290,33 @@ static int vsp1_device_init(struct vsp1_device *vsp1) + return 0; + } + ++static int vsp1_clocks_enable(struct vsp1_device *vsp1) ++{ ++ int ret; ++ ++ ret = clk_prepare_enable(vsp1->clock); ++ if (ret < 0) ++ return ret; ++ ++ if (IS_ERR(vsp1->rt_clock)) ++ return 0; ++ ++ ret = clk_prepare_enable(vsp1->rt_clock); ++ if (ret < 0) { ++ clk_disable_unprepare(vsp1->clock); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static void vsp1_clocks_disable(struct vsp1_device *vsp1) ++{ ++ if (!IS_ERR(vsp1->rt_clock)) ++ clk_disable_unprepare(vsp1->rt_clock); ++ clk_disable_unprepare(vsp1->clock); ++} ++ + /* + * vsp1_device_get - Acquire the VSP1 device + * +@@ -307,7 +334,7 @@ struct vsp1_device *vsp1_device_get(struct vsp1_device *vsp1) + if (vsp1->ref_count > 0) + goto done; + +- ret = clk_prepare_enable(vsp1->clock); ++ ret = vsp1_clocks_enable(vsp1); + if (ret < 0) { + __vsp1 = NULL; + goto done; +@@ -315,7 +342,7 @@ struct vsp1_device *vsp1_device_get(struct vsp1_device *vsp1) + + ret = vsp1_device_init(vsp1); + if (ret < 0) { +- clk_disable_unprepare(vsp1->clock); ++ vsp1_clocks_disable(vsp1); + __vsp1 = NULL; + goto done; + } +@@ -339,7 +366,7 @@ void vsp1_device_put(struct vsp1_device *vsp1) + mutex_lock(&vsp1->lock); + + if (--vsp1->ref_count == 0) +- clk_disable_unprepare(vsp1->clock); ++ vsp1_clocks_disable(vsp1); + + mutex_unlock(&vsp1->lock); + } +@@ -358,7 +385,7 @@ static int vsp1_pm_suspend(struct device *dev) + if (vsp1->ref_count == 0) + return 0; + +- clk_disable_unprepare(vsp1->clock); ++ vsp1_clocks_disable(vsp1); + return 0; + } + +@@ -371,7 +398,7 @@ static int vsp1_pm_resume(struct device *dev) + if (vsp1->ref_count) + return 0; + +- return clk_prepare_enable(vsp1->clock); ++ return vsp1_clocks_enable(vsp1); + } + #endif + +@@ -445,6 +472,9 @@ static int vsp1_probe(struct platform_device *pdev) + return PTR_ERR(vsp1->clock); + } + ++ /* The RT clock is optional */ ++ vsp1->rt_clock = devm_clk_get(&pdev->dev, "rt"); ++ + irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!irq) { + dev_err(&pdev->dev, "missing IRQ\n"); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0043-media-v4l-vsp1-Fix-mutex-double-lock-at-streamon-tim.patch b/patches.renesas/0043-media-v4l-vsp1-Fix-mutex-double-lock-at-streamon-tim.patch new file mode 100644 index 00000000000000..2da3a66e3c7905 --- /dev/null +++ b/patches.renesas/0043-media-v4l-vsp1-Fix-mutex-double-lock-at-streamon-tim.patch @@ -0,0 +1,32 @@ +From 067a19bb32538fee8e59fb37b9bb687a8f7ec94e Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 22 Aug 2013 19:51:01 -0300 +Subject: [media] v4l: vsp1: Fix mutex double lock at streamon time + +A mutex_lock() was left when the driver was converted to use the vb2 +ioctl helpers, resulting in a deadlock at streamon time. Fix it. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> +(cherry picked from commit 26a20eb09d44dc064c4f5d1f024bd501c09edb4b) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/media/platform/vsp1/vsp1_video.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c +index 279332e34710..76718a9ea34f 100644 +--- a/drivers/media/platform/vsp1/vsp1_video.c ++++ b/drivers/media/platform/vsp1/vsp1_video.c +@@ -839,8 +839,6 @@ vsp1_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) + struct vsp1_pipeline *pipe; + int ret; + +- mutex_lock(&video->lock); +- + if (video->queue.owner && video->queue.owner != file->private_data) + return -EBUSY; + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0044-dma-add-driver-for-R-Car-HPB-DMAC.patch b/patches.renesas/0044-dma-add-driver-for-R-Car-HPB-DMAC.patch new file mode 100644 index 00000000000000..aed7aadd34edb0 --- /dev/null +++ b/patches.renesas/0044-dma-add-driver-for-R-Car-HPB-DMAC.patch @@ -0,0 +1,830 @@ +From 3305ec12892e49e5920c7ec9ff77af11a62748f9 Mon Sep 17 00:00:00 2001 +From: Max Filippov <max.filippov@cogentembedded.com> +Date: Sun, 25 Aug 2013 00:33:24 +0400 +Subject: dma: add driver for R-Car HPB-DMAC + +Add support for HPB-DMAC found in Renesas R-Car SoCs, using 'shdma-base' DMA +driver framework. + +Based on the original patch by Phil Edworthy <phil.edworthy@renesas.com>. + +Signed-off-by: Max Filippov <max.filippov@cogentembedded.com> +[Sergei: removed useless #include, sorted #include's, fixed HPB_DMA_TCR_MAX, +fixed formats and removed line breaks in the dev_dbg() calls, rephrased and +added IRQ # to the shdma_request_irq() failure message, added MODULE_AUTHOR(), +removed '__init'/'__exit' annotations from the probe()/remove() methods, removed +'__initdata' annotation from 'hpb_dmae_driver', fixed guard macro name in the +header file, fixed #define ASYNCRSTR_ASRST20, added #define ASYNCRSTR_ASRST24, +added the necessary runtime PM calls to the probe() and remove() methods, +handled errors returned by dma_async_device_register(), beautified comments +and #define's.] +Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> + +(cherry picked from commit c4f6c41ba790bbbfcebb4c47a709ac8ff1fe1af9) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/dma/sh/Kconfig | 6 + + drivers/dma/sh/Makefile | 1 + + drivers/dma/sh/rcar-hpbdma.c | 655 ++++++++++++++++++++++++++ + include/linux/platform_data/dma-rcar-hpbdma.h | 103 ++++ + 4 files changed, 765 insertions(+) + create mode 100644 drivers/dma/sh/rcar-hpbdma.c + create mode 100644 include/linux/platform_data/dma-rcar-hpbdma.h + +diff --git a/drivers/dma/sh/Kconfig b/drivers/dma/sh/Kconfig +index 5c1dee20c13e..e2b94d16f41f 100644 +--- a/drivers/dma/sh/Kconfig ++++ b/drivers/dma/sh/Kconfig +@@ -22,3 +22,9 @@ config SUDMAC + depends on SH_DMAE_BASE + help + Enable support for the Renesas SUDMAC controllers. ++ ++config RCAR_HPB_DMAE ++ tristate "Renesas R-Car HPB DMAC support" ++ depends on SH_DMAE_BASE ++ help ++ Enable support for the Renesas R-Car series DMA controllers. +diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile +index c07ca4612e46..3524b3056035 100644 +--- a/drivers/dma/sh/Makefile ++++ b/drivers/dma/sh/Makefile +@@ -1,3 +1,4 @@ + obj-$(CONFIG_SH_DMAE_BASE) += shdma-base.o + obj-$(CONFIG_SH_DMAE) += shdma.o + obj-$(CONFIG_SUDMAC) += sudmac.o ++obj-$(CONFIG_RCAR_HPB_DMAE) += rcar-hpbdma.o +diff --git a/drivers/dma/sh/rcar-hpbdma.c b/drivers/dma/sh/rcar-hpbdma.c +new file mode 100644 +index 000000000000..45a520281ce1 +--- /dev/null ++++ b/drivers/dma/sh/rcar-hpbdma.c +@@ -0,0 +1,655 @@ ++/* ++ * Copyright (C) 2011-2013 Renesas Electronics Corporation ++ * Copyright (C) 2013 Cogent Embedded, Inc. ++ * ++ * This file is based on the drivers/dma/sh/shdma.c ++ * ++ * Renesas SuperH DMA Engine support ++ * ++ * This 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, or ++ * (at your option) any later version. ++ * ++ * - DMA of SuperH does not have Hardware DMA chain mode. ++ * - max DMA size is 16MB. ++ * ++ */ ++ ++#include <linux/dmaengine.h> ++#include <linux/delay.h> ++#include <linux/init.h> ++#include <linux/interrupt.h> ++#include <linux/module.h> ++#include <linux/platform_data/dma-rcar-hpbdma.h> ++#include <linux/platform_device.h> ++#include <linux/pm_runtime.h> ++#include <linux/shdma-base.h> ++#include <linux/slab.h> ++ ++/* DMA channel registers */ ++#define HPB_DMAE_DSAR0 0x00 ++#define HPB_DMAE_DDAR0 0x04 ++#define HPB_DMAE_DTCR0 0x08 ++#define HPB_DMAE_DSAR1 0x0C ++#define HPB_DMAE_DDAR1 0x10 ++#define HPB_DMAE_DTCR1 0x14 ++#define HPB_DMAE_DSASR 0x18 ++#define HPB_DMAE_DDASR 0x1C ++#define HPB_DMAE_DTCSR 0x20 ++#define HPB_DMAE_DPTR 0x24 ++#define HPB_DMAE_DCR 0x28 ++#define HPB_DMAE_DCMDR 0x2C ++#define HPB_DMAE_DSTPR 0x30 ++#define HPB_DMAE_DSTSR 0x34 ++#define HPB_DMAE_DDBGR 0x38 ++#define HPB_DMAE_DDBGR2 0x3C ++#define HPB_DMAE_CHAN(n) (0x40 * (n)) ++ ++/* DMA command register (DCMDR) bits */ ++#define HPB_DMAE_DCMDR_BDOUT BIT(7) ++#define HPB_DMAE_DCMDR_DQSPD BIT(6) ++#define HPB_DMAE_DCMDR_DQSPC BIT(5) ++#define HPB_DMAE_DCMDR_DMSPD BIT(4) ++#define HPB_DMAE_DCMDR_DMSPC BIT(3) ++#define HPB_DMAE_DCMDR_DQEND BIT(2) ++#define HPB_DMAE_DCMDR_DNXT BIT(1) ++#define HPB_DMAE_DCMDR_DMEN BIT(0) ++ ++/* DMA forced stop register (DSTPR) bits */ ++#define HPB_DMAE_DSTPR_DMSTP BIT(0) ++ ++/* DMA status register (DSTSR) bits */ ++#define HPB_DMAE_DSTSR_DMSTS BIT(0) ++ ++/* DMA common registers */ ++#define HPB_DMAE_DTIMR 0x00 ++#define HPB_DMAE_DINTSR0 0x0C ++#define HPB_DMAE_DINTSR1 0x10 ++#define HPB_DMAE_DINTCR0 0x14 ++#define HPB_DMAE_DINTCR1 0x18 ++#define HPB_DMAE_DINTMR0 0x1C ++#define HPB_DMAE_DINTMR1 0x20 ++#define HPB_DMAE_DACTSR0 0x24 ++#define HPB_DMAE_DACTSR1 0x28 ++#define HPB_DMAE_HSRSTR(n) (0x40 + (n) * 4) ++#define HPB_DMAE_HPB_DMASPR(n) (0x140 + (n) * 4) ++#define HPB_DMAE_HPB_DMLVLR0 0x160 ++#define HPB_DMAE_HPB_DMLVLR1 0x164 ++#define HPB_DMAE_HPB_DMSHPT0 0x168 ++#define HPB_DMAE_HPB_DMSHPT1 0x16C ++ ++#define HPB_DMA_SLAVE_NUMBER 256 ++#define HPB_DMA_TCR_MAX 0x01000000 /* 16 MiB */ ++ ++struct hpb_dmae_chan { ++ struct shdma_chan shdma_chan; ++ int xfer_mode; /* DMA transfer mode */ ++#define XFER_SINGLE 1 ++#define XFER_DOUBLE 2 ++ unsigned plane_idx; /* current DMA information set */ ++ bool first_desc; /* first/next transfer */ ++ int xmit_shift; /* log_2(bytes_per_xfer) */ ++ void __iomem *base; ++ const struct hpb_dmae_slave_config *cfg; ++ char dev_id[16]; /* unique name per DMAC of channel */ ++}; ++ ++struct hpb_dmae_device { ++ struct shdma_dev shdma_dev; ++ spinlock_t reg_lock; /* comm_reg operation lock */ ++ struct hpb_dmae_pdata *pdata; ++ void __iomem *chan_reg; ++ void __iomem *comm_reg; ++ void __iomem *reset_reg; ++ void __iomem *mode_reg; ++}; ++ ++struct hpb_dmae_regs { ++ u32 sar; /* SAR / source address */ ++ u32 dar; /* DAR / destination address */ ++ u32 tcr; /* TCR / transfer count */ ++}; ++ ++struct hpb_desc { ++ struct shdma_desc shdma_desc; ++ struct hpb_dmae_regs hw; ++ unsigned plane_idx; ++}; ++ ++#define to_chan(schan) container_of(schan, struct hpb_dmae_chan, shdma_chan) ++#define to_desc(sdesc) container_of(sdesc, struct hpb_desc, shdma_desc) ++#define to_dev(sc) container_of(sc->shdma_chan.dma_chan.device, \ ++ struct hpb_dmae_device, shdma_dev.dma_dev) ++ ++static void ch_reg_write(struct hpb_dmae_chan *hpb_dc, u32 data, u32 reg) ++{ ++ iowrite32(data, hpb_dc->base + reg); ++} ++ ++static u32 ch_reg_read(struct hpb_dmae_chan *hpb_dc, u32 reg) ++{ ++ return ioread32(hpb_dc->base + reg); ++} ++ ++static void dcmdr_write(struct hpb_dmae_device *hpbdev, u32 data) ++{ ++ iowrite32(data, hpbdev->chan_reg + HPB_DMAE_DCMDR); ++} ++ ++static void hsrstr_write(struct hpb_dmae_device *hpbdev, u32 ch) ++{ ++ iowrite32(0x1, hpbdev->comm_reg + HPB_DMAE_HSRSTR(ch)); ++} ++ ++static u32 dintsr_read(struct hpb_dmae_device *hpbdev, u32 ch) ++{ ++ u32 v; ++ ++ if (ch < 32) ++ v = ioread32(hpbdev->comm_reg + HPB_DMAE_DINTSR0) >> ch; ++ else ++ v = ioread32(hpbdev->comm_reg + HPB_DMAE_DINTSR1) >> (ch - 32); ++ return v & 0x1; ++} ++ ++static void dintcr_write(struct hpb_dmae_device *hpbdev, u32 ch) ++{ ++ if (ch < 32) ++ iowrite32((0x1 << ch), hpbdev->comm_reg + HPB_DMAE_DINTCR0); ++ else ++ iowrite32((0x1 << (ch - 32)), ++ hpbdev->comm_reg + HPB_DMAE_DINTCR1); ++} ++ ++static void asyncmdr_write(struct hpb_dmae_device *hpbdev, u32 data) ++{ ++ iowrite32(data, hpbdev->mode_reg); ++} ++ ++static u32 asyncmdr_read(struct hpb_dmae_device *hpbdev) ++{ ++ return ioread32(hpbdev->mode_reg); ++} ++ ++static void hpb_dmae_enable_int(struct hpb_dmae_device *hpbdev, u32 ch) ++{ ++ u32 intreg; ++ ++ spin_lock_irq(&hpbdev->reg_lock); ++ if (ch < 32) { ++ intreg = ioread32(hpbdev->comm_reg + HPB_DMAE_DINTMR0); ++ iowrite32(BIT(ch) | intreg, ++ hpbdev->comm_reg + HPB_DMAE_DINTMR0); ++ } else { ++ intreg = ioread32(hpbdev->comm_reg + HPB_DMAE_DINTMR1); ++ iowrite32(BIT(ch - 32) | intreg, ++ hpbdev->comm_reg + HPB_DMAE_DINTMR1); ++ } ++ spin_unlock_irq(&hpbdev->reg_lock); ++} ++ ++static void hpb_dmae_async_reset(struct hpb_dmae_device *hpbdev, u32 data) ++{ ++ u32 rstr; ++ int timeout = 10000; /* 100 ms */ ++ ++ spin_lock(&hpbdev->reg_lock); ++ rstr = ioread32(hpbdev->reset_reg); ++ rstr |= data; ++ iowrite32(rstr, hpbdev->reset_reg); ++ do { ++ rstr = ioread32(hpbdev->reset_reg); ++ if ((rstr & data) == data) ++ break; ++ udelay(10); ++ } while (timeout--); ++ ++ if (timeout < 0) ++ dev_err(hpbdev->shdma_dev.dma_dev.dev, ++ "%s timeout\n", __func__); ++ ++ rstr &= ~data; ++ iowrite32(rstr, hpbdev->reset_reg); ++ spin_unlock(&hpbdev->reg_lock); ++} ++ ++static void hpb_dmae_set_async_mode(struct hpb_dmae_device *hpbdev, ++ u32 mask, u32 data) ++{ ++ u32 mode; ++ ++ spin_lock_irq(&hpbdev->reg_lock); ++ mode = asyncmdr_read(hpbdev); ++ mode &= ~mask; ++ mode |= data; ++ asyncmdr_write(hpbdev, mode); ++ spin_unlock_irq(&hpbdev->reg_lock); ++} ++ ++static void hpb_dmae_ctl_stop(struct hpb_dmae_device *hpbdev) ++{ ++ dcmdr_write(hpbdev, HPB_DMAE_DCMDR_DQSPD); ++} ++ ++static void hpb_dmae_reset(struct hpb_dmae_device *hpbdev) ++{ ++ u32 ch; ++ ++ for (ch = 0; ch < hpbdev->pdata->num_hw_channels; ch++) ++ hsrstr_write(hpbdev, ch); ++} ++ ++static unsigned int calc_xmit_shift(struct hpb_dmae_chan *hpb_chan) ++{ ++ struct hpb_dmae_device *hpbdev = to_dev(hpb_chan); ++ struct hpb_dmae_pdata *pdata = hpbdev->pdata; ++ int width = ch_reg_read(hpb_chan, HPB_DMAE_DCR); ++ int i; ++ ++ switch (width & (HPB_DMAE_DCR_SPDS_MASK | HPB_DMAE_DCR_DPDS_MASK)) { ++ case HPB_DMAE_DCR_SPDS_8BIT | HPB_DMAE_DCR_DPDS_8BIT: ++ default: ++ i = XMIT_SZ_8BIT; ++ break; ++ case HPB_DMAE_DCR_SPDS_16BIT | HPB_DMAE_DCR_DPDS_16BIT: ++ i = XMIT_SZ_16BIT; ++ break; ++ case HPB_DMAE_DCR_SPDS_32BIT | HPB_DMAE_DCR_DPDS_32BIT: ++ i = XMIT_SZ_32BIT; ++ break; ++ } ++ return pdata->ts_shift[i]; ++} ++ ++static void hpb_dmae_set_reg(struct hpb_dmae_chan *hpb_chan, ++ struct hpb_dmae_regs *hw, unsigned plane) ++{ ++ ch_reg_write(hpb_chan, hw->sar, ++ plane ? HPB_DMAE_DSAR1 : HPB_DMAE_DSAR0); ++ ch_reg_write(hpb_chan, hw->dar, ++ plane ? HPB_DMAE_DDAR1 : HPB_DMAE_DDAR0); ++ ch_reg_write(hpb_chan, hw->tcr >> hpb_chan->xmit_shift, ++ plane ? HPB_DMAE_DTCR1 : HPB_DMAE_DTCR0); ++} ++ ++static void hpb_dmae_start(struct hpb_dmae_chan *hpb_chan, bool next) ++{ ++ ch_reg_write(hpb_chan, (next ? HPB_DMAE_DCMDR_DNXT : 0) | ++ HPB_DMAE_DCMDR_DMEN, HPB_DMAE_DCMDR); ++} ++ ++static void hpb_dmae_halt(struct shdma_chan *schan) ++{ ++ struct hpb_dmae_chan *chan = to_chan(schan); ++ ++ ch_reg_write(chan, HPB_DMAE_DCMDR_DQEND, HPB_DMAE_DCMDR); ++ ch_reg_write(chan, HPB_DMAE_DSTPR_DMSTP, HPB_DMAE_DSTPR); ++} ++ ++static const struct hpb_dmae_slave_config * ++hpb_dmae_find_slave(struct hpb_dmae_chan *hpb_chan, int slave_id) ++{ ++ struct hpb_dmae_device *hpbdev = to_dev(hpb_chan); ++ struct hpb_dmae_pdata *pdata = hpbdev->pdata; ++ int i; ++ ++ if (slave_id >= HPB_DMA_SLAVE_NUMBER) ++ return NULL; ++ ++ for (i = 0; i < pdata->num_slaves; i++) ++ if (pdata->slaves[i].id == slave_id) ++ return pdata->slaves + i; ++ ++ return NULL; ++} ++ ++static void hpb_dmae_start_xfer(struct shdma_chan *schan, ++ struct shdma_desc *sdesc) ++{ ++ struct hpb_dmae_chan *chan = to_chan(schan); ++ struct hpb_dmae_device *hpbdev = to_dev(chan); ++ struct hpb_desc *desc = to_desc(sdesc); ++ ++ if (chan->cfg->flags & HPB_DMAE_SET_ASYNC_RESET) ++ hpb_dmae_async_reset(hpbdev, chan->cfg->rstr); ++ ++ desc->plane_idx = chan->plane_idx; ++ hpb_dmae_set_reg(chan, &desc->hw, chan->plane_idx); ++ hpb_dmae_start(chan, !chan->first_desc); ++ ++ if (chan->xfer_mode == XFER_DOUBLE) { ++ chan->plane_idx ^= 1; ++ chan->first_desc = false; ++ } ++} ++ ++static bool hpb_dmae_desc_completed(struct shdma_chan *schan, ++ struct shdma_desc *sdesc) ++{ ++ /* ++ * This is correct since we always have at most single ++ * outstanding DMA transfer per channel, and by the time ++ * we get completion interrupt the transfer is completed. ++ * This will change if we ever use alternating DMA ++ * information sets and submit two descriptors at once. ++ */ ++ return true; ++} ++ ++static bool hpb_dmae_chan_irq(struct shdma_chan *schan, int irq) ++{ ++ struct hpb_dmae_chan *chan = to_chan(schan); ++ struct hpb_dmae_device *hpbdev = to_dev(chan); ++ int ch = chan->cfg->dma_ch; ++ ++ /* Check Complete DMA Transfer */ ++ if (dintsr_read(hpbdev, ch)) { ++ /* Clear Interrupt status */ ++ dintcr_write(hpbdev, ch); ++ return true; ++ } ++ return false; ++} ++ ++static int hpb_dmae_desc_setup(struct shdma_chan *schan, ++ struct shdma_desc *sdesc, ++ dma_addr_t src, dma_addr_t dst, size_t *len) ++{ ++ struct hpb_desc *desc = to_desc(sdesc); ++ ++ if (*len > (size_t)HPB_DMA_TCR_MAX) ++ *len = (size_t)HPB_DMA_TCR_MAX; ++ ++ desc->hw.sar = src; ++ desc->hw.dar = dst; ++ desc->hw.tcr = *len; ++ ++ return 0; ++} ++ ++static size_t hpb_dmae_get_partial(struct shdma_chan *schan, ++ struct shdma_desc *sdesc) ++{ ++ struct hpb_desc *desc = to_desc(sdesc); ++ struct hpb_dmae_chan *chan = to_chan(schan); ++ u32 tcr = ch_reg_read(chan, desc->plane_idx ? ++ HPB_DMAE_DTCR1 : HPB_DMAE_DTCR0); ++ ++ return (desc->hw.tcr - tcr) << chan->xmit_shift; ++} ++ ++static bool hpb_dmae_channel_busy(struct shdma_chan *schan) ++{ ++ struct hpb_dmae_chan *chan = to_chan(schan); ++ u32 dstsr = ch_reg_read(chan, HPB_DMAE_DSTSR); ++ ++ return (dstsr & HPB_DMAE_DSTSR_DMSTS) == HPB_DMAE_DSTSR_DMSTS; ++} ++ ++static int ++hpb_dmae_alloc_chan_resources(struct hpb_dmae_chan *hpb_chan, ++ const struct hpb_dmae_slave_config *cfg) ++{ ++ struct hpb_dmae_device *hpbdev = to_dev(hpb_chan); ++ struct hpb_dmae_pdata *pdata = hpbdev->pdata; ++ const struct hpb_dmae_channel *channel = pdata->channels; ++ int slave_id = cfg->id; ++ int i, err; ++ ++ for (i = 0; i < pdata->num_channels; i++, channel++) { ++ if (channel->s_id == slave_id) { ++ struct device *dev = hpb_chan->shdma_chan.dev; ++ ++ hpb_chan->base = hpbdev->chan_reg + ++ HPB_DMAE_CHAN(cfg->dma_ch); ++ ++ dev_dbg(dev, "Detected Slave device\n"); ++ dev_dbg(dev, " -- slave_id : 0x%x\n", slave_id); ++ dev_dbg(dev, " -- cfg->dma_ch : %d\n", cfg->dma_ch); ++ dev_dbg(dev, " -- channel->ch_irq: %d\n", ++ channel->ch_irq); ++ break; ++ } ++ } ++ ++ err = shdma_request_irq(&hpb_chan->shdma_chan, channel->ch_irq, ++ IRQF_SHARED, hpb_chan->dev_id); ++ if (err) { ++ dev_err(hpb_chan->shdma_chan.dev, ++ "DMA channel request_irq %d failed with error %d\n", ++ channel->ch_irq, err); ++ return err; ++ } ++ ++ hpb_chan->plane_idx = 0; ++ hpb_chan->first_desc = true; ++ ++ if ((cfg->dcr & (HPB_DMAE_DCR_CT | HPB_DMAE_DCR_DIP)) == 0) { ++ hpb_chan->xfer_mode = XFER_SINGLE; ++ } else if ((cfg->dcr & (HPB_DMAE_DCR_CT | HPB_DMAE_DCR_DIP)) == ++ (HPB_DMAE_DCR_CT | HPB_DMAE_DCR_DIP)) { ++ hpb_chan->xfer_mode = XFER_DOUBLE; ++ } else { ++ dev_err(hpb_chan->shdma_chan.dev, "DCR setting error"); ++ shdma_free_irq(&hpb_chan->shdma_chan); ++ return -EINVAL; ++ } ++ ++ if (cfg->flags & HPB_DMAE_SET_ASYNC_MODE) ++ hpb_dmae_set_async_mode(hpbdev, cfg->mdm, cfg->mdr); ++ ch_reg_write(hpb_chan, cfg->dcr, HPB_DMAE_DCR); ++ ch_reg_write(hpb_chan, cfg->port, HPB_DMAE_DPTR); ++ hpb_chan->xmit_shift = calc_xmit_shift(hpb_chan); ++ hpb_dmae_enable_int(hpbdev, cfg->dma_ch); ++ ++ return 0; ++} ++ ++static int hpb_dmae_set_slave(struct shdma_chan *schan, int slave_id, bool try) ++{ ++ struct hpb_dmae_chan *chan = to_chan(schan); ++ const struct hpb_dmae_slave_config *sc = ++ hpb_dmae_find_slave(chan, slave_id); ++ ++ if (!sc) ++ return -ENODEV; ++ if (try) ++ return 0; ++ chan->cfg = sc; ++ return hpb_dmae_alloc_chan_resources(chan, sc); ++} ++ ++static void hpb_dmae_setup_xfer(struct shdma_chan *schan, int slave_id) ++{ ++} ++ ++static dma_addr_t hpb_dmae_slave_addr(struct shdma_chan *schan) ++{ ++ struct hpb_dmae_chan *chan = to_chan(schan); ++ ++ return chan->cfg->addr; ++} ++ ++static struct shdma_desc *hpb_dmae_embedded_desc(void *buf, int i) ++{ ++ return &((struct hpb_desc *)buf)[i].shdma_desc; ++} ++ ++static const struct shdma_ops hpb_dmae_ops = { ++ .desc_completed = hpb_dmae_desc_completed, ++ .halt_channel = hpb_dmae_halt, ++ .channel_busy = hpb_dmae_channel_busy, ++ .slave_addr = hpb_dmae_slave_addr, ++ .desc_setup = hpb_dmae_desc_setup, ++ .set_slave = hpb_dmae_set_slave, ++ .setup_xfer = hpb_dmae_setup_xfer, ++ .start_xfer = hpb_dmae_start_xfer, ++ .embedded_desc = hpb_dmae_embedded_desc, ++ .chan_irq = hpb_dmae_chan_irq, ++ .get_partial = hpb_dmae_get_partial, ++}; ++ ++static int hpb_dmae_chan_probe(struct hpb_dmae_device *hpbdev, int id) ++{ ++ struct shdma_dev *sdev = &hpbdev->shdma_dev; ++ struct platform_device *pdev = ++ to_platform_device(hpbdev->shdma_dev.dma_dev.dev); ++ struct hpb_dmae_chan *new_hpb_chan; ++ struct shdma_chan *schan; ++ ++ /* Alloc channel */ ++ new_hpb_chan = devm_kzalloc(&pdev->dev, ++ sizeof(struct hpb_dmae_chan), GFP_KERNEL); ++ if (!new_hpb_chan) { ++ dev_err(hpbdev->shdma_dev.dma_dev.dev, ++ "No free memory for allocating DMA channels!\n"); ++ return -ENOMEM; ++ } ++ ++ schan = &new_hpb_chan->shdma_chan; ++ shdma_chan_probe(sdev, schan, id); ++ ++ if (pdev->id >= 0) ++ snprintf(new_hpb_chan->dev_id, sizeof(new_hpb_chan->dev_id), ++ "hpb-dmae%d.%d", pdev->id, id); ++ else ++ snprintf(new_hpb_chan->dev_id, sizeof(new_hpb_chan->dev_id), ++ "hpb-dma.%d", id); ++ ++ return 0; ++} ++ ++static int hpb_dmae_probe(struct platform_device *pdev) ++{ ++ struct hpb_dmae_pdata *pdata = pdev->dev.platform_data; ++ struct hpb_dmae_device *hpbdev; ++ struct dma_device *dma_dev; ++ struct resource *chan, *comm, *rest, *mode, *irq_res; ++ int err, i; ++ ++ /* Get platform data */ ++ if (!pdata || !pdata->num_channels) ++ return -ENODEV; ++ ++ chan = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ comm = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ rest = platform_get_resource(pdev, IORESOURCE_MEM, 2); ++ mode = platform_get_resource(pdev, IORESOURCE_MEM, 3); ++ ++ irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); ++ if (!irq_res) ++ return -ENODEV; ++ ++ hpbdev = devm_kzalloc(&pdev->dev, sizeof(struct hpb_dmae_device), ++ GFP_KERNEL); ++ if (!hpbdev) { ++ dev_err(&pdev->dev, "Not enough memory\n"); ++ return -ENOMEM; ++ } ++ ++ hpbdev->chan_reg = devm_ioremap_resource(&pdev->dev, chan); ++ if (IS_ERR(hpbdev->chan_reg)) ++ return PTR_ERR(hpbdev->chan_reg); ++ ++ hpbdev->comm_reg = devm_ioremap_resource(&pdev->dev, comm); ++ if (IS_ERR(hpbdev->comm_reg)) ++ return PTR_ERR(hpbdev->comm_reg); ++ ++ hpbdev->reset_reg = devm_ioremap_resource(&pdev->dev, rest); ++ if (IS_ERR(hpbdev->reset_reg)) ++ return PTR_ERR(hpbdev->reset_reg); ++ ++ hpbdev->mode_reg = devm_ioremap_resource(&pdev->dev, mode); ++ if (IS_ERR(hpbdev->mode_reg)) ++ return PTR_ERR(hpbdev->mode_reg); ++ ++ dma_dev = &hpbdev->shdma_dev.dma_dev; ++ ++ spin_lock_init(&hpbdev->reg_lock); ++ ++ /* Platform data */ ++ hpbdev->pdata = pdata; ++ ++ pm_runtime_enable(&pdev->dev); ++ err = pm_runtime_get_sync(&pdev->dev); ++ if (err < 0) ++ dev_err(&pdev->dev, "%s(): GET = %d\n", __func__, err); ++ ++ /* Reset DMA controller */ ++ hpb_dmae_reset(hpbdev); ++ ++ pm_runtime_put(&pdev->dev); ++ ++ dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask); ++ dma_cap_set(DMA_SLAVE, dma_dev->cap_mask); ++ ++ hpbdev->shdma_dev.ops = &hpb_dmae_ops; ++ hpbdev->shdma_dev.desc_size = sizeof(struct hpb_desc); ++ err = shdma_init(&pdev->dev, &hpbdev->shdma_dev, pdata->num_channels); ++ if (err < 0) ++ goto error; ++ ++ /* Create DMA channels */ ++ for (i = 0; i < pdata->num_channels; i++) ++ hpb_dmae_chan_probe(hpbdev, i); ++ ++ platform_set_drvdata(pdev, hpbdev); ++ err = dma_async_device_register(dma_dev); ++ if (!err) ++ return 0; ++ ++ shdma_cleanup(&hpbdev->shdma_dev); ++error: ++ pm_runtime_disable(&pdev->dev); ++ return err; ++} ++ ++static void hpb_dmae_chan_remove(struct hpb_dmae_device *hpbdev) ++{ ++ struct dma_device *dma_dev = &hpbdev->shdma_dev.dma_dev; ++ struct shdma_chan *schan; ++ int i; ++ ++ shdma_for_each_chan(schan, &hpbdev->shdma_dev, i) { ++ BUG_ON(!schan); ++ ++ shdma_free_irq(schan); ++ shdma_chan_remove(schan); ++ } ++ dma_dev->chancnt = 0; ++} ++ ++static int hpb_dmae_remove(struct platform_device *pdev) ++{ ++ struct hpb_dmae_device *hpbdev = platform_get_drvdata(pdev); ++ ++ dma_async_device_unregister(&hpbdev->shdma_dev.dma_dev); ++ ++ pm_runtime_disable(&pdev->dev); ++ ++ hpb_dmae_chan_remove(hpbdev); ++ ++ return 0; ++} ++ ++static void hpb_dmae_shutdown(struct platform_device *pdev) ++{ ++ struct hpb_dmae_device *hpbdev = platform_get_drvdata(pdev); ++ hpb_dmae_ctl_stop(hpbdev); ++} ++ ++static struct platform_driver hpb_dmae_driver = { ++ .probe = hpb_dmae_probe, ++ .remove = hpb_dmae_remove, ++ .shutdown = hpb_dmae_shutdown, ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "hpb-dma-engine", ++ }, ++}; ++module_platform_driver(hpb_dmae_driver); ++ ++MODULE_AUTHOR("Max Filippov <max.filippov@cogentembedded.com>"); ++MODULE_DESCRIPTION("Renesas HPB DMA Engine driver"); ++MODULE_LICENSE("GPL"); +diff --git a/include/linux/platform_data/dma-rcar-hpbdma.h b/include/linux/platform_data/dma-rcar-hpbdma.h +new file mode 100644 +index 000000000000..648b8ea61a22 +--- /dev/null ++++ b/include/linux/platform_data/dma-rcar-hpbdma.h +@@ -0,0 +1,103 @@ ++/* ++ * Copyright (C) 2011-2013 Renesas Electronics Corporation ++ * Copyright (C) 2013 Cogent Embedded, Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 ++ * as published by the Free Software Foundation. ++ */ ++ ++#ifndef __DMA_RCAR_HPBDMA_H ++#define __DMA_RCAR_HPBDMA_H ++ ++#include <linux/bitops.h> ++#include <linux/types.h> ++ ++/* Transmit sizes and respective register values */ ++enum { ++ XMIT_SZ_8BIT = 0, ++ XMIT_SZ_16BIT = 1, ++ XMIT_SZ_32BIT = 2, ++ XMIT_SZ_MAX ++}; ++ ++/* DMA control register (DCR) bits */ ++#define HPB_DMAE_DCR_DTAMD (1u << 26) ++#define HPB_DMAE_DCR_DTAC (1u << 25) ++#define HPB_DMAE_DCR_DTAU (1u << 24) ++#define HPB_DMAE_DCR_DTAU1 (1u << 23) ++#define HPB_DMAE_DCR_SWMD (1u << 22) ++#define HPB_DMAE_DCR_BTMD (1u << 21) ++#define HPB_DMAE_DCR_PKMD (1u << 20) ++#define HPB_DMAE_DCR_CT (1u << 18) ++#define HPB_DMAE_DCR_ACMD (1u << 17) ++#define HPB_DMAE_DCR_DIP (1u << 16) ++#define HPB_DMAE_DCR_SMDL (1u << 13) ++#define HPB_DMAE_DCR_SPDAM (1u << 12) ++#define HPB_DMAE_DCR_SDRMD_MASK (3u << 10) ++#define HPB_DMAE_DCR_SDRMD_MOD (0u << 10) ++#define HPB_DMAE_DCR_SDRMD_AUTO (1u << 10) ++#define HPB_DMAE_DCR_SDRMD_TIMER (2u << 10) ++#define HPB_DMAE_DCR_SPDS_MASK (3u << 8) ++#define HPB_DMAE_DCR_SPDS_8BIT (0u << 8) ++#define HPB_DMAE_DCR_SPDS_16BIT (1u << 8) ++#define HPB_DMAE_DCR_SPDS_32BIT (2u << 8) ++#define HPB_DMAE_DCR_DMDL (1u << 5) ++#define HPB_DMAE_DCR_DPDAM (1u << 4) ++#define HPB_DMAE_DCR_DDRMD_MASK (3u << 2) ++#define HPB_DMAE_DCR_DDRMD_MOD (0u << 2) ++#define HPB_DMAE_DCR_DDRMD_AUTO (1u << 2) ++#define HPB_DMAE_DCR_DDRMD_TIMER (2u << 2) ++#define HPB_DMAE_DCR_DPDS_MASK (3u << 0) ++#define HPB_DMAE_DCR_DPDS_8BIT (0u << 0) ++#define HPB_DMAE_DCR_DPDS_16BIT (1u << 0) ++#define HPB_DMAE_DCR_DPDS_32BIT (2u << 0) ++ ++/* Asynchronous reset register (ASYNCRSTR) bits */ ++#define HPB_DMAE_ASYNCRSTR_ASRST41 BIT(10) ++#define HPB_DMAE_ASYNCRSTR_ASRST40 BIT(9) ++#define HPB_DMAE_ASYNCRSTR_ASRST39 BIT(8) ++#define HPB_DMAE_ASYNCRSTR_ASRST27 BIT(7) ++#define HPB_DMAE_ASYNCRSTR_ASRST26 BIT(6) ++#define HPB_DMAE_ASYNCRSTR_ASRST25 BIT(5) ++#define HPB_DMAE_ASYNCRSTR_ASRST24 BIT(4) ++#define HPB_DMAE_ASYNCRSTR_ASRST23 BIT(3) ++#define HPB_DMAE_ASYNCRSTR_ASRST22 BIT(2) ++#define HPB_DMAE_ASYNCRSTR_ASRST21 BIT(1) ++#define HPB_DMAE_ASYNCRSTR_ASRST20 BIT(0) ++ ++struct hpb_dmae_slave_config { ++ unsigned int id; ++ dma_addr_t addr; ++ u32 dcr; ++ u32 port; ++ u32 rstr; ++ u32 mdr; ++ u32 mdm; ++ u32 flags; ++#define HPB_DMAE_SET_ASYNC_RESET BIT(0) ++#define HPB_DMAE_SET_ASYNC_MODE BIT(1) ++ u32 dma_ch; ++}; ++ ++#define HPB_DMAE_CHANNEL(_irq, _s_id) \ ++{ \ ++ .ch_irq = _irq, \ ++ .s_id = _s_id, \ ++} ++ ++struct hpb_dmae_channel { ++ unsigned int ch_irq; ++ unsigned int s_id; ++}; ++ ++struct hpb_dmae_pdata { ++ const struct hpb_dmae_slave_config *slaves; ++ int num_slaves; ++ const struct hpb_dmae_channel *channels; ++ int num_channels; ++ const unsigned int ts_shift[XMIT_SZ_MAX]; ++ int num_hw_channels; ++}; ++ ++#endif +-- +1.8.5.rc3 + diff --git a/patches.renesas/0045-rcar-hpbdma-remove-shdma_free_irq-calls.patch b/patches.renesas/0045-rcar-hpbdma-remove-shdma_free_irq-calls.patch new file mode 100644 index 00000000000000..b9b47a1fa5e2e4 --- /dev/null +++ b/patches.renesas/0045-rcar-hpbdma-remove-shdma_free_irq-calls.patch @@ -0,0 +1,49 @@ +From 50a504ad989147a7309199d79eda021241858dce Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Date: Thu, 26 Sep 2013 02:28:37 +0400 +Subject: rcar-hpbdma: remove shdma_free_irq() calls + +Commit c1c63a14f4f2419d093acd7164eccdff315baa86 (DMA: shdma: switch to managed +resource allocation) got rid of shdma_free_irq() but unfortunately got merged +later than commit c4f6c41ba790bbbfcebb4c47a709ac8ff1fe1af9 (dma: add driver for +R-Car HPB-DMAC), so that the HPB-DMAC driver retained the calls and got broken: + +drivers/dma/sh/rcar-hpbdma.c: In function `hpb_dmae_alloc_chan_resources': +drivers/dma/sh/rcar-hpbdma.c:435: error: implicit declaration of function +`shdma_free_irq' + +Fix this compilation error by removing the remaining shdma_free_irq() calls. + +Reported-by: Simon Horman <horms@verge.net.au> +Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Tested-by: Simon Horman <horms+renesas@verge.net.au> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> +(cherry picked from commit cdeb5c033f0389c44e5b36cafd623bdf44bbe25c) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/dma/sh/rcar-hpbdma.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/dma/sh/rcar-hpbdma.c b/drivers/dma/sh/rcar-hpbdma.c +index 45a520281ce1..b2f50d8bd755 100644 +--- a/drivers/dma/sh/rcar-hpbdma.c ++++ b/drivers/dma/sh/rcar-hpbdma.c +@@ -432,7 +432,6 @@ hpb_dmae_alloc_chan_resources(struct hpb_dmae_chan *hpb_chan, + hpb_chan->xfer_mode = XFER_DOUBLE; + } else { + dev_err(hpb_chan->shdma_chan.dev, "DCR setting error"); +- shdma_free_irq(&hpb_chan->shdma_chan); + return -EINVAL; + } + +@@ -614,7 +613,6 @@ static void hpb_dmae_chan_remove(struct hpb_dmae_device *hpbdev) + shdma_for_each_chan(schan, &hpbdev->shdma_dev, i) { + BUG_ON(!schan); + +- shdma_free_irq(schan); + shdma_chan_remove(schan); + } + dma_dev->chancnt = 0; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0046-rcar-hpbdma-add-parameter-to-set_slave-method.patch b/patches.renesas/0046-rcar-hpbdma-add-parameter-to-set_slave-method.patch new file mode 100644 index 00000000000000..639ef289095742 --- /dev/null +++ b/patches.renesas/0046-rcar-hpbdma-add-parameter-to-set_slave-method.patch @@ -0,0 +1,70 @@ +From b5ac24346687569d8079b947c2b73bb42c521658 Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Date: Thu, 26 Sep 2013 02:31:37 +0400 +Subject: rcar-hpbdma: add parameter to set_slave() method + +Commit 4981c4dc194efb18f0e9a02f1b43e926f2f0d2bb (DMA: shdma: switch DT mode to +use configuration data from a match table) added a new parameter to set_slave() +method but unfortunately got merged later than commit c4f6c41ba790bbbfcebb4c47a +(dma: add driver for R-Car HPB-DMAC), so that the HPB-DMAC driver retained the +old prototype which caused this warning: + +drivers/dma/sh/rcar-hpbdma.c:485: warning: initialization from incompatible +pointer type + +The newly added parameter is used to override DMA slave address from 'struct +hpb_dmae_slave_config', so we have to add the 'slave_addr' field to 'struct +hpb_dmae_chan', conditionally assign it in set_slave() method, and return in +slave_addr() method. + +Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Tested-by: Simon Horman <horms+renesas@verge.net.au> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> +(cherry picked from commit 08d08bcdee30d3a28426bd60dfbdae44b36250bc) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/dma/sh/rcar-hpbdma.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/dma/sh/rcar-hpbdma.c b/drivers/dma/sh/rcar-hpbdma.c +index b2f50d8bd755..ebad84591a6e 100644 +--- a/drivers/dma/sh/rcar-hpbdma.c ++++ b/drivers/dma/sh/rcar-hpbdma.c +@@ -93,6 +93,7 @@ struct hpb_dmae_chan { + void __iomem *base; + const struct hpb_dmae_slave_config *cfg; + char dev_id[16]; /* unique name per DMAC of channel */ ++ dma_addr_t slave_addr; + }; + + struct hpb_dmae_device { +@@ -445,7 +446,8 @@ hpb_dmae_alloc_chan_resources(struct hpb_dmae_chan *hpb_chan, + return 0; + } + +-static int hpb_dmae_set_slave(struct shdma_chan *schan, int slave_id, bool try) ++static int hpb_dmae_set_slave(struct shdma_chan *schan, int slave_id, ++ dma_addr_t slave_addr, bool try) + { + struct hpb_dmae_chan *chan = to_chan(schan); + const struct hpb_dmae_slave_config *sc = +@@ -456,6 +458,7 @@ static int hpb_dmae_set_slave(struct shdma_chan *schan, int slave_id, bool try) + if (try) + return 0; + chan->cfg = sc; ++ chan->slave_addr = slave_addr ? : sc->addr; + return hpb_dmae_alloc_chan_resources(chan, sc); + } + +@@ -467,7 +470,7 @@ static dma_addr_t hpb_dmae_slave_addr(struct shdma_chan *schan) + { + struct hpb_dmae_chan *chan = to_chan(schan); + +- return chan->cfg->addr; ++ return chan->slave_addr; + } + + static struct shdma_desc *hpb_dmae_embedded_desc(void *buf, int i) +-- +1.8.5.rc3 + diff --git a/patches.renesas/0047-DMA-shdma-cosmetic-don-t-re-calculate-a-pointer.patch b/patches.renesas/0047-DMA-shdma-cosmetic-don-t-re-calculate-a-pointer.patch new file mode 100644 index 00000000000000..187b7832a53544 --- /dev/null +++ b/patches.renesas/0047-DMA-shdma-cosmetic-don-t-re-calculate-a-pointer.patch @@ -0,0 +1,31 @@ +From 7e3ecce2e20c51cc55c659412802e01b627149cc Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Thu, 6 Jun 2013 17:37:13 +0200 +Subject: DMA: shdma: (cosmetic) don't re-calculate a pointer + +Use an existing pointer instead of retrieving it again. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> +(cherry picked from commit fa74326c44767626a5ae794b29d54103e2259e64) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/dma/sh/shdma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c +index b70709b030d8..a5a1887c34b5 100644 +--- a/drivers/dma/sh/shdma.c ++++ b/drivers/dma/sh/shdma.c +@@ -729,7 +729,7 @@ static int sh_dmae_probe(struct platform_device *pdev) + goto eshdma; + + /* platform data */ +- shdev->pdata = pdev->dev.platform_data; ++ shdev->pdata = pdata; + + if (pdata->chcr_offset) + shdev->chcr_offset = pdata->chcr_offset; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0048-DMA-shdma-add-DT-support.patch b/patches.renesas/0048-DMA-shdma-add-DT-support.patch new file mode 100644 index 00000000000000..d916a017e01b98 --- /dev/null +++ b/patches.renesas/0048-DMA-shdma-add-DT-support.patch @@ -0,0 +1,348 @@ +From 3eb36dc9620cca5f185ec2e9af8476526b19c249 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Tue, 18 Jun 2013 18:16:57 +0200 +Subject: DMA: shdma: add DT support + +This patch adds Device Tree support to the shdma driver. No special DT +properties are used, only standard DMA DT bindings are implemented. Since +shdma controllers reside on SoCs, their configuration is SoC-specific and +shall be passed to the driver from the SoC platform data, using the +auxdata procedure. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Acked-by: Arnd Bergmann <arnd@arndb.de> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> +(cherry picked from commit 67eacc1583909d0588c8d5d80c16298c899a6382) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + Documentation/devicetree/bindings/dma/shdma.txt | 75 ++++++++++++++++++++++ + drivers/dma/sh/Makefile | 2 +- + drivers/dma/sh/shdma-base.c | 26 ++++++-- + drivers/dma/sh/shdma-of.c | 82 +++++++++++++++++++++++++ + drivers/dma/sh/shdma.c | 31 ++++++++-- + include/linux/shdma-base.h | 2 + + 6 files changed, 205 insertions(+), 13 deletions(-) + create mode 100644 Documentation/devicetree/bindings/dma/shdma.txt + create mode 100644 drivers/dma/sh/shdma-of.c + +diff --git a/Documentation/devicetree/bindings/dma/shdma.txt b/Documentation/devicetree/bindings/dma/shdma.txt +new file mode 100644 +index 000000000000..c15994aa1939 +--- /dev/null ++++ b/Documentation/devicetree/bindings/dma/shdma.txt +@@ -0,0 +1,75 @@ ++* SHDMA Device Tree bindings ++ ++Sh-/r-mobile and r-car systems often have multiple identical DMA controller ++instances, capable of serving any of a common set of DMA slave devices, using ++the same configuration. To describe this topology we require all compatible ++SHDMA DT nodes to be placed under a DMA multiplexer node. All such compatible ++DMAC instances have the same number of channels and use the same DMA ++descriptors. Therefore respective DMA DT bindings can also all be placed in the ++multiplexer node. Even if there is only one such DMAC instance on a system, it ++still has to be placed under such a multiplexer node. ++ ++* DMA multiplexer ++ ++Required properties: ++- compatible: should be "renesas,shdma-mux" ++- #dma-cells: should be <1>, see "dmas" property below ++ ++Optional properties (currently unused): ++- dma-channels: number of DMA channels ++- dma-requests: number of DMA request signals ++ ++* DMA controller ++ ++Required properties: ++- compatible: should be "renesas,shdma" ++ ++Example: ++ dmac: dma-mux0 { ++ compatible = "renesas,shdma-mux"; ++ #dma-cells = <1>; ++ dma-channels = <6>; ++ dma-requests = <256>; ++ reg = <0 0>; /* Needed for AUXDATA */ ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ dma0: shdma@fe008020 { ++ compatible = "renesas,shdma"; ++ reg = <0xfe008020 0x270>, ++ <0xfe009000 0xc>; ++ interrupt-parent = <&gic>; ++ interrupts = <0 34 4 ++ 0 28 4 ++ 0 29 4 ++ 0 30 4 ++ 0 31 4 ++ 0 32 4 ++ 0 33 4>; ++ interrupt-names = "error", ++ "ch0", "ch1", "ch2", "ch3", ++ "ch4", "ch5"; ++ }; ++ ++ dma1: shdma@fe018020 { ++ ... ++ }; ++ ++ dma2: shdma@fe028020 { ++ ... ++ }; ++ }; ++ ++* DMA client ++ ++Required properties: ++- dmas: a list of <[DMA multiplexer phandle] [MID/RID value]> pairs, ++ where MID/RID values are fixed handles, specified in the SoC ++ manual ++- dma-names: a list of DMA channel names, one per "dmas" entry ++ ++Example: ++ dmas = <&dmac 0xd1 ++ &dmac 0xd2>; ++ dma-names = "tx", "rx"; +diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile +index 3524b3056035..ccf17cb5af10 100644 +--- a/drivers/dma/sh/Makefile ++++ b/drivers/dma/sh/Makefile +@@ -1,4 +1,4 @@ +-obj-$(CONFIG_SH_DMAE_BASE) += shdma-base.o ++obj-$(CONFIG_SH_DMAE_BASE) += shdma-base.o shdma-of.o + obj-$(CONFIG_SH_DMAE) += shdma.o + obj-$(CONFIG_SUDMAC) += sudmac.o + obj-$(CONFIG_RCAR_HPB_DMAE) += rcar-hpbdma.o +diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c +index 4acb85a10250..28ca36121631 100644 +--- a/drivers/dma/sh/shdma-base.c ++++ b/drivers/dma/sh/shdma-base.c +@@ -175,7 +175,18 @@ static int shdma_setup_slave(struct shdma_chan *schan, int slave_id) + { + struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device); + const struct shdma_ops *ops = sdev->ops; +- int ret; ++ int ret, match; ++ ++ if (schan->dev->of_node) { ++ match = schan->hw_req; ++ ret = ops->set_slave(schan, match, true); ++ if (ret < 0) ++ return ret; ++ ++ slave_id = schan->slave_id; ++ } else { ++ match = slave_id; ++ } + + if (slave_id < 0 || slave_id >= slave_num) + return -EINVAL; +@@ -183,7 +194,7 @@ static int shdma_setup_slave(struct shdma_chan *schan, int slave_id) + if (test_and_set_bit(slave_id, shdma_slave_used)) + return -EBUSY; + +- ret = ops->set_slave(schan, slave_id, false); ++ ret = ops->set_slave(schan, match, false); + if (ret < 0) { + clear_bit(slave_id, shdma_slave_used); + return ret; +@@ -206,23 +217,26 @@ static int shdma_setup_slave(struct shdma_chan *schan, int slave_id) + * services would have to provide their own filters, which first would check + * the device driver, similar to how other DMAC drivers, e.g., sa11x0-dma.c, do + * this, and only then, in case of a match, call this common filter. ++ * NOTE 2: This filter function is also used in the DT case by shdma_of_xlate(). ++ * In that case the MID-RID value is used for slave channel filtering and is ++ * passed to this function in the "arg" parameter. + */ + bool shdma_chan_filter(struct dma_chan *chan, void *arg) + { + struct shdma_chan *schan = to_shdma_chan(chan); + struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device); + const struct shdma_ops *ops = sdev->ops; +- int slave_id = (int)arg; ++ int match = (int)arg; + int ret; + +- if (slave_id < 0) ++ if (match < 0) + /* No slave requested - arbitrary channel */ + return true; + +- if (slave_id >= slave_num) ++ if (!schan->dev->of_node && match >= slave_num) + return false; + +- ret = ops->set_slave(schan, slave_id, true); ++ ret = ops->set_slave(schan, match, true); + if (ret < 0) + return false; + +diff --git a/drivers/dma/sh/shdma-of.c b/drivers/dma/sh/shdma-of.c +new file mode 100644 +index 000000000000..11bcb05cd79c +--- /dev/null ++++ b/drivers/dma/sh/shdma-of.c +@@ -0,0 +1,82 @@ ++/* ++ * SHDMA Device Tree glue ++ * ++ * Copyright (C) 2013 Renesas Electronics Inc. ++ * Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de> ++ * ++ * This is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ */ ++ ++#include <linux/dmaengine.h> ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/of_dma.h> ++#include <linux/of_platform.h> ++#include <linux/platform_device.h> ++#include <linux/shdma-base.h> ++ ++#define to_shdma_chan(c) container_of(c, struct shdma_chan, dma_chan) ++ ++static struct dma_chan *shdma_of_xlate(struct of_phandle_args *dma_spec, ++ struct of_dma *ofdma) ++{ ++ u32 id = dma_spec->args[0]; ++ dma_cap_mask_t mask; ++ struct dma_chan *chan; ++ ++ if (dma_spec->args_count != 1) ++ return NULL; ++ ++ dma_cap_zero(mask); ++ /* Only slave DMA channels can be allocated via DT */ ++ dma_cap_set(DMA_SLAVE, mask); ++ ++ chan = dma_request_channel(mask, shdma_chan_filter, (void *)id); ++ if (chan) ++ to_shdma_chan(chan)->hw_req = id; ++ ++ return chan; ++} ++ ++static int shdma_of_probe(struct platform_device *pdev) ++{ ++ const struct of_dev_auxdata *lookup = pdev->dev.platform_data; ++ int ret; ++ ++ if (!lookup) ++ return -EINVAL; ++ ++ ret = of_dma_controller_register(pdev->dev.of_node, ++ shdma_of_xlate, pdev); ++ if (ret < 0) ++ return ret; ++ ++ ret = of_platform_populate(pdev->dev.of_node, NULL, lookup, &pdev->dev); ++ if (ret < 0) ++ of_dma_controller_free(pdev->dev.of_node); ++ ++ return ret; ++} ++ ++static const struct of_device_id shdma_of_match[] = { ++ { .compatible = "renesas,shdma-mux", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, sh_dmae_of_match); ++ ++static struct platform_driver shdma_of = { ++ .driver = { ++ .owner = THIS_MODULE, ++ .name = "shdma-of", ++ .of_match_table = shdma_of_match, ++ }, ++ .probe = shdma_of_probe, ++}; ++ ++module_platform_driver(shdma_of); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("SH-DMA driver DT glue"); ++MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); +diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c +index a5a1887c34b5..b67f45f5c271 100644 +--- a/drivers/dma/sh/shdma.c ++++ b/drivers/dma/sh/shdma.c +@@ -301,20 +301,32 @@ static void sh_dmae_setup_xfer(struct shdma_chan *schan, + } + } + ++/* ++ * Find a slave channel configuration from the contoller list by either a slave ++ * ID in the non-DT case, or by a MID/RID value in the DT case ++ */ + static const struct sh_dmae_slave_config *dmae_find_slave( +- struct sh_dmae_chan *sh_chan, int slave_id) ++ struct sh_dmae_chan *sh_chan, int match) + { + struct sh_dmae_device *shdev = to_sh_dev(sh_chan); + struct sh_dmae_pdata *pdata = shdev->pdata; + const struct sh_dmae_slave_config *cfg; + int i; + +- if (slave_id >= SH_DMA_SLAVE_NUMBER) +- return NULL; ++ if (!sh_chan->shdma_chan.dev->of_node) { ++ if (match >= SH_DMA_SLAVE_NUMBER) ++ return NULL; + +- for (i = 0, cfg = pdata->slave; i < pdata->slave_num; i++, cfg++) +- if (cfg->slave_id == slave_id) +- return cfg; ++ for (i = 0, cfg = pdata->slave; i < pdata->slave_num; i++, cfg++) ++ if (cfg->slave_id == match) ++ return cfg; ++ } else { ++ for (i = 0, cfg = pdata->slave; i < pdata->slave_num; i++, cfg++) ++ if (cfg->mid_rid == match) { ++ sh_chan->shdma_chan.slave_id = cfg->slave_id; ++ return cfg; ++ } ++ } + + return NULL; + } +@@ -920,11 +932,18 @@ static int sh_dmae_remove(struct platform_device *pdev) + return 0; + } + ++static const struct of_device_id sh_dmae_of_match[] = { ++ { .compatible = "renesas,shdma", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, sh_dmae_of_match); ++ + static struct platform_driver sh_dmae_driver = { + .driver = { + .owner = THIS_MODULE, + .pm = &sh_dmae_pm, + .name = SH_DMAE_DRV_NAME, ++ .of_match_table = sh_dmae_of_match, + }, + .remove = sh_dmae_remove, + .shutdown = sh_dmae_shutdown, +diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h +index e212720567b3..5b1c9848124c 100644 +--- a/include/linux/shdma-base.h ++++ b/include/linux/shdma-base.h +@@ -68,6 +68,8 @@ struct shdma_chan { + int id; /* Raw id of this channel */ + int irq; /* Channel IRQ */ + int slave_id; /* Client ID for slave DMA */ ++ int hw_req; /* DMA request line for slave DMA - same ++ * as MID/RID, used with DT */ + enum shdma_pm_state pm_state; + }; + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0049-dma-use-dev_get_platdata.patch b/patches.renesas/0049-dma-use-dev_get_platdata.patch new file mode 100644 index 00000000000000..0f3ca58c6a1dc3 --- /dev/null +++ b/patches.renesas/0049-dma-use-dev_get_platdata.patch @@ -0,0 +1,56 @@ +From 6343032750049bb1fab31d5f41fff22912984ed6 Mon Sep 17 00:00:00 2001 +From: Jingoo Han <jg1.han@samsung.com> +Date: Tue, 30 Jul 2013 17:09:11 +0900 +Subject: dma: use dev_get_platdata() + +Use the wrapper function for retrieving the platform data instead of +accessing dev->platform_data directly. + +Signed-off-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> +(cherry picked from commit d4adcc0160404c3237fe6ffa09dd2dd039dd3975) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + drivers/dma/imx-sdma.c + drivers/dma/iop-adma.c + drivers/dma/mv_xor.c + drivers/dma/pl330.c + drivers/dma/sh/sudmac.c + drivers/dma/ste_dma40.c + drivers/dma/timb_dma.c + drivers/dma/txx9dmac.c +--- + drivers/dma/sh/shdma-of.c | 2 +- + drivers/dma/sh/shdma.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/dma/sh/shdma-of.c b/drivers/dma/sh/shdma-of.c +index 11bcb05cd79c..966aaab0b4d3 100644 +--- a/drivers/dma/sh/shdma-of.c ++++ b/drivers/dma/sh/shdma-of.c +@@ -42,7 +42,7 @@ static struct dma_chan *shdma_of_xlate(struct of_phandle_args *dma_spec, + + static int shdma_of_probe(struct platform_device *pdev) + { +- const struct of_dev_auxdata *lookup = pdev->dev.platform_data; ++ const struct of_dev_auxdata *lookup = dev_get_platdata(&pdev->dev); + int ret; + + if (!lookup) +diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c +index b67f45f5c271..b388b12f078e 100644 +--- a/drivers/dma/sh/shdma.c ++++ b/drivers/dma/sh/shdma.c +@@ -660,7 +660,7 @@ static const struct shdma_ops sh_dmae_shdma_ops = { + + static int sh_dmae_probe(struct platform_device *pdev) + { +- struct sh_dmae_pdata *pdata = pdev->dev.platform_data; ++ struct sh_dmae_pdata *pdata = dev_get_platdata(&pdev->dev); + unsigned long irqflags = IRQF_DISABLED, + chan_flag[SH_DMAE_MAX_CHANNELS] = {}; + int errirq, chan_irq[SH_DMAE_MAX_CHANNELS]; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0050-DMA-shdma-fix-CHCLR-register-address-calculation.patch b/patches.renesas/0050-DMA-shdma-fix-CHCLR-register-address-calculation.patch new file mode 100644 index 00000000000000..4c715deec3cc0e --- /dev/null +++ b/patches.renesas/0050-DMA-shdma-fix-CHCLR-register-address-calculation.patch @@ -0,0 +1,50 @@ +From 95898d642c91b96722bcdc6bed0b6e55d42036e6 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Tue, 2 Jul 2013 17:37:58 +0200 +Subject: DMA: shdma: fix CHCLR register address calculation + +struct sh_dmae_device::chan_reg is a pointer to u32, therefore when adding +offsets to it care should be taken to add offsets in sizeof(u32) units, not +in bytes. This patch corrects such a bug. While at it we also remove the +redundant parameter of the affected function. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> +(cherry picked from commit a28a94e84bca8ba7db66bcc0db1bea51840b08b2) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/dma/sh/shdma.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c +index b388b12f078e..a5356db54959 100644 +--- a/drivers/dma/sh/shdma.c ++++ b/drivers/dma/sh/shdma.c +@@ -49,12 +49,12 @@ + static DEFINE_SPINLOCK(sh_dmae_lock); + static LIST_HEAD(sh_dmae_devices); + +-static void chclr_write(struct sh_dmae_chan *sh_dc, u32 data) ++static void channel_clear(struct sh_dmae_chan *sh_dc) + { + struct sh_dmae_device *shdev = to_sh_dev(sh_dc); + +- __raw_writel(data, shdev->chan_reg + +- shdev->pdata->channel[sh_dc->shdma_chan.id].chclr_offset); ++ __raw_writel(0, shdev->chan_reg + ++ shdev->pdata->channel[sh_dc->shdma_chan.id].chclr_offset / sizeof(u32)); + } + + static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg) +@@ -133,7 +133,7 @@ static int sh_dmae_rst(struct sh_dmae_device *shdev) + for (i = 0; i < shdev->pdata->channel_num; i++) { + struct sh_dmae_chan *sh_chan = shdev->chan[i]; + if (sh_chan) +- chclr_write(sh_chan, 0); ++ channel_clear(sh_chan); + } + } + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0051-DMA-shdma-switch-all-__iomem-pointers-to-void.patch b/patches.renesas/0051-DMA-shdma-switch-all-__iomem-pointers-to-void.patch new file mode 100644 index 00000000000000..2c10f2c44190c0 --- /dev/null +++ b/patches.renesas/0051-DMA-shdma-switch-all-__iomem-pointers-to-void.patch @@ -0,0 +1,133 @@ +From 0dd7196b2112a62655d034259ed7430890e76497 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Tue, 2 Jul 2013 17:46:01 +0200 +Subject: DMA: shdma: switch all __iomem pointers to void + +In the shdma driver __iomem pointers are used to point to hardware +registers. Using typed pointers like "u32 __iomem *" in this case is +inconvenient, because then offsets, added to such pointers, have to be +devided by sizeof(u32) or similar. Switch the driver to use void +pointers, which avoids this clumsiness. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> +(cherry picked from commit 115357e9774ff8d70a84d3c31f271209913637b0) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/dma/sh/shdma.c | 22 +++++++++++----------- + drivers/dma/sh/shdma.h | 6 +++--- + 2 files changed, 14 insertions(+), 14 deletions(-) + +diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c +index a5356db54959..547a4ab69ca0 100644 +--- a/drivers/dma/sh/shdma.c ++++ b/drivers/dma/sh/shdma.c +@@ -54,22 +54,22 @@ static void channel_clear(struct sh_dmae_chan *sh_dc) + struct sh_dmae_device *shdev = to_sh_dev(sh_dc); + + __raw_writel(0, shdev->chan_reg + +- shdev->pdata->channel[sh_dc->shdma_chan.id].chclr_offset / sizeof(u32)); ++ shdev->pdata->channel[sh_dc->shdma_chan.id].chclr_offset); + } + + static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg) + { +- __raw_writel(data, sh_dc->base + reg / sizeof(u32)); ++ __raw_writel(data, sh_dc->base + reg); + } + + static u32 sh_dmae_readl(struct sh_dmae_chan *sh_dc, u32 reg) + { +- return __raw_readl(sh_dc->base + reg / sizeof(u32)); ++ return __raw_readl(sh_dc->base + reg); + } + + static u16 dmaor_read(struct sh_dmae_device *shdev) + { +- u32 __iomem *addr = shdev->chan_reg + DMAOR / sizeof(u32); ++ void __iomem *addr = shdev->chan_reg + DMAOR; + + if (shdev->pdata->dmaor_is_32bit) + return __raw_readl(addr); +@@ -79,7 +79,7 @@ static u16 dmaor_read(struct sh_dmae_device *shdev) + + static void dmaor_write(struct sh_dmae_device *shdev, u16 data) + { +- u32 __iomem *addr = shdev->chan_reg + DMAOR / sizeof(u32); ++ void __iomem *addr = shdev->chan_reg + DMAOR; + + if (shdev->pdata->dmaor_is_32bit) + __raw_writel(data, addr); +@@ -91,14 +91,14 @@ static void chcr_write(struct sh_dmae_chan *sh_dc, u32 data) + { + struct sh_dmae_device *shdev = to_sh_dev(sh_dc); + +- __raw_writel(data, sh_dc->base + shdev->chcr_offset / sizeof(u32)); ++ __raw_writel(data, sh_dc->base + shdev->chcr_offset); + } + + static u32 chcr_read(struct sh_dmae_chan *sh_dc) + { + struct sh_dmae_device *shdev = to_sh_dev(sh_dc); + +- return __raw_readl(sh_dc->base + shdev->chcr_offset / sizeof(u32)); ++ return __raw_readl(sh_dc->base + shdev->chcr_offset); + } + + /* +@@ -242,7 +242,7 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) + struct sh_dmae_device *shdev = to_sh_dev(sh_chan); + struct sh_dmae_pdata *pdata = shdev->pdata; + const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->shdma_chan.id]; +- u16 __iomem *addr = shdev->dmars; ++ void __iomem *addr = shdev->dmars; + unsigned int shift = chan_pdata->dmars_bit; + + if (dmae_is_busy(sh_chan)) +@@ -253,8 +253,8 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) + + /* in the case of a missing DMARS resource use first memory window */ + if (!addr) +- addr = (u16 __iomem *)shdev->chan_reg; +- addr += chan_pdata->dmars / sizeof(u16); ++ addr = shdev->chan_reg; ++ addr += chan_pdata->dmars; + + __raw_writew((__raw_readw(addr) & (0xff00 >> shift)) | (val << shift), + addr); +@@ -517,7 +517,7 @@ static int sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id, + + shdma_chan_probe(sdev, schan, id); + +- sh_chan->base = shdev->chan_reg + chan_pdata->offset / sizeof(u32); ++ sh_chan->base = shdev->chan_reg + chan_pdata->offset; + + /* set up channel irq */ + if (pdev->id >= 0) +diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h +index 9314e93225db..06aae6ebc82b 100644 +--- a/drivers/dma/sh/shdma.h ++++ b/drivers/dma/sh/shdma.h +@@ -28,7 +28,7 @@ struct sh_dmae_chan { + struct shdma_chan shdma_chan; + const struct sh_dmae_slave_config *config; /* Slave DMA configuration */ + int xmit_shift; /* log_2(bytes_per_xfer) */ +- u32 __iomem *base; ++ void __iomem *base; + char dev_id[16]; /* unique name per DMAC of channel */ + int pm_error; + }; +@@ -38,8 +38,8 @@ struct sh_dmae_device { + struct sh_dmae_chan *chan[SH_DMAE_MAX_CHANNELS]; + struct sh_dmae_pdata *pdata; + struct list_head node; +- u32 __iomem *chan_reg; +- u16 __iomem *dmars; ++ void __iomem *chan_reg; ++ void __iomem *dmars; + unsigned int chcr_offset; + u32 chcr_ie_bit; + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0052-DMA-shdma-support-the-new-CHCLR-register-layout.patch b/patches.renesas/0052-DMA-shdma-support-the-new-CHCLR-register-layout.patch new file mode 100644 index 00000000000000..b626b587f32d4b --- /dev/null +++ b/patches.renesas/0052-DMA-shdma-support-the-new-CHCLR-register-layout.patch @@ -0,0 +1,110 @@ +From e24e6f7c2a5ce6be02608f445734223c0170ed93 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Wed, 10 Jul 2013 12:09:47 +0200 +Subject: DMA: shdma: support the new CHCLR register layout + +On newer r-car SoCs the CHCLR register only contains one bit per channel, +to which a 1 has to be written to reset the channel. Older SoC versions had +one CHCLR register per channel, to which a 0 must be written to reset the +channel and clear its buffers. This patch adds support for the newer +layout. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> +(cherry picked from commit ca8b387803072a16baf6d8090591b10bfdf4e253) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/dma/sh/shdma.c | 14 ++++++++++++-- + include/linux/sh_dma.h | 34 +++++++++++++++++++++++++++++++++- + 2 files changed, 45 insertions(+), 3 deletions(-) + +diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c +index 547a4ab69ca0..ba539d8cabee 100644 +--- a/drivers/dma/sh/shdma.c ++++ b/drivers/dma/sh/shdma.c +@@ -49,12 +49,22 @@ + static DEFINE_SPINLOCK(sh_dmae_lock); + static LIST_HEAD(sh_dmae_devices); + ++/* ++ * Different DMAC implementations provide different ways to clear DMA channels: ++ * (1) none - no CHCLR registers are available ++ * (2) one CHCLR register per channel - 0 has to be written to it to clear ++ * channel buffers ++ * (3) one CHCLR per several channels - 1 has to be written to the bit, ++ * corresponding to the specific channel to reset it ++ */ + static void channel_clear(struct sh_dmae_chan *sh_dc) + { + struct sh_dmae_device *shdev = to_sh_dev(sh_dc); ++ const struct sh_dmae_channel *chan_pdata = shdev->pdata->channel + ++ sh_dc->shdma_chan.id; ++ u32 val = shdev->pdata->chclr_bitwise ? 1 << chan_pdata->chclr_bit : 0; + +- __raw_writel(0, shdev->chan_reg + +- shdev->pdata->channel[sh_dc->shdma_chan.id].chclr_offset); ++ __raw_writel(val, shdev->chan_reg + chan_pdata->chclr_offset); + } + + static void sh_dmae_writel(struct sh_dmae_chan *sh_dc, u32 data, u32 reg) +diff --git a/include/linux/sh_dma.h b/include/linux/sh_dma.h +index 4e83f3e034f3..776ed9d682f4 100644 +--- a/include/linux/sh_dma.h ++++ b/include/linux/sh_dma.h +@@ -33,13 +33,44 @@ struct sh_dmae_slave_config { + char mid_rid; + }; + ++/** ++ * struct sh_dmae_channel - DMAC channel platform data ++ * @offset: register offset within the main IOMEM resource ++ * @dmars: channel DMARS register offset ++ * @chclr_offset: channel CHCLR register offset ++ * @dmars_bit: channel DMARS field offset within the register ++ * @chclr_bit: bit position, to be set to reset the channel ++ */ + struct sh_dmae_channel { + unsigned int offset; + unsigned int dmars; +- unsigned int dmars_bit; + unsigned int chclr_offset; ++ unsigned char dmars_bit; ++ unsigned char chclr_bit; + }; + ++/** ++ * struct sh_dmae_pdata - DMAC platform data ++ * @slave: array of slaves ++ * @slave_num: number of slaves in the above array ++ * @channel: array of DMA channels ++ * @channel_num: number of channels in the above array ++ * @ts_low_shift: shift of the low part of the TS field ++ * @ts_low_mask: low TS field mask ++ * @ts_high_shift: additional shift of the high part of the TS field ++ * @ts_high_mask: high TS field mask ++ * @ts_shift: array of Transfer Size shifts, indexed by TS value ++ * @ts_shift_num: number of shifts in the above array ++ * @dmaor_init: DMAOR initialisation value ++ * @chcr_offset: CHCR address offset ++ * @chcr_ie_bit: CHCR Interrupt Enable bit ++ * @dmaor_is_32bit: DMAOR is a 32-bit register ++ * @needs_tend_set: the TEND register has to be set ++ * @no_dmars: DMAC has no DMARS registers ++ * @chclr_present: DMAC has one or several CHCLR registers ++ * @chclr_bitwise: channel CHCLR registers are bitwise ++ * @slave_only: DMAC cannot be used for MEMCPY ++ */ + struct sh_dmae_pdata { + const struct sh_dmae_slave_config *slave; + int slave_num; +@@ -59,6 +90,7 @@ struct sh_dmae_pdata { + unsigned int needs_tend_set:1; + unsigned int no_dmars:1; + unsigned int chclr_present:1; ++ unsigned int chclr_bitwise:1; + unsigned int slave_only:1; + }; + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0053-DMA-shdma-switch-to-managed-resource-allocation.patch b/patches.renesas/0053-DMA-shdma-switch-to-managed-resource-allocation.patch new file mode 100644 index 00000000000000..26aae9dd9567ef --- /dev/null +++ b/patches.renesas/0053-DMA-shdma-switch-to-managed-resource-allocation.patch @@ -0,0 +1,215 @@ +From 5d0330316bfbce0b6819e8842f6c965ad1053d9c Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Tue, 2 Jul 2013 17:45:55 +0200 +Subject: DMA: shdma: switch to managed resource allocation + +Switch shdma to using devm_* managed functions for allocation of memory, +requesting IRQs, mapping IO resources etc. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> +(cherry picked from commit c1c63a14f4f2419d093acd7164eccdff315baa86) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/dma/sh/shdma-base.c | 11 ++------ + drivers/dma/sh/shdma.c | 66 +++++++++------------------------------------ + drivers/dma/sh/sudmac.c | 1 - + include/linux/shdma-base.h | 1 - + 4 files changed, 15 insertions(+), 64 deletions(-) + +diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c +index 28ca36121631..c5ea256c2819 100644 +--- a/drivers/dma/sh/shdma-base.c ++++ b/drivers/dma/sh/shdma-base.c +@@ -831,8 +831,8 @@ static irqreturn_t chan_irqt(int irq, void *dev) + int shdma_request_irq(struct shdma_chan *schan, int irq, + unsigned long flags, const char *name) + { +- int ret = request_threaded_irq(irq, chan_irq, chan_irqt, +- flags, name, schan); ++ int ret = devm_request_threaded_irq(schan->dev, irq, chan_irq, ++ chan_irqt, flags, name, schan); + + schan->irq = ret < 0 ? ret : irq; + +@@ -840,13 +840,6 @@ int shdma_request_irq(struct shdma_chan *schan, int irq, + } + EXPORT_SYMBOL(shdma_request_irq); + +-void shdma_free_irq(struct shdma_chan *schan) +-{ +- if (schan->irq >= 0) +- free_irq(schan->irq, schan); +-} +-EXPORT_SYMBOL(shdma_free_irq); +- + void shdma_chan_probe(struct shdma_dev *sdev, + struct shdma_chan *schan, int id) + { +diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c +index ba539d8cabee..4f24b9d2b5c3 100644 +--- a/drivers/dma/sh/shdma.c ++++ b/drivers/dma/sh/shdma.c +@@ -515,7 +515,8 @@ static int sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id, + struct shdma_chan *schan; + int err; + +- sh_chan = kzalloc(sizeof(struct sh_dmae_chan), GFP_KERNEL); ++ sh_chan = devm_kzalloc(sdev->dma_dev.dev, sizeof(struct sh_dmae_chan), ++ GFP_KERNEL); + if (!sh_chan) { + dev_err(sdev->dma_dev.dev, + "No free memory for allocating dma channels!\n"); +@@ -551,7 +552,6 @@ static int sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id, + err_no_irq: + /* remove from dmaengine device node */ + shdma_chan_remove(schan); +- kfree(sh_chan); + return err; + } + +@@ -562,14 +562,9 @@ static void sh_dmae_chan_remove(struct sh_dmae_device *shdev) + int i; + + shdma_for_each_chan(schan, &shdev->shdma_dev, i) { +- struct sh_dmae_chan *sh_chan = container_of(schan, +- struct sh_dmae_chan, shdma_chan); + BUG_ON(!schan); + +- shdma_free_irq(&sh_chan->shdma_chan); +- + shdma_chan_remove(schan); +- kfree(sh_chan); + } + dma_dev->chancnt = 0; + } +@@ -706,33 +701,22 @@ static int sh_dmae_probe(struct platform_device *pdev) + if (!chan || !errirq_res) + return -ENODEV; + +- if (!request_mem_region(chan->start, resource_size(chan), pdev->name)) { +- dev_err(&pdev->dev, "DMAC register region already claimed\n"); +- return -EBUSY; +- } +- +- if (dmars && !request_mem_region(dmars->start, resource_size(dmars), pdev->name)) { +- dev_err(&pdev->dev, "DMAC DMARS region already claimed\n"); +- err = -EBUSY; +- goto ermrdmars; +- } +- +- err = -ENOMEM; +- shdev = kzalloc(sizeof(struct sh_dmae_device), GFP_KERNEL); ++ shdev = devm_kzalloc(&pdev->dev, sizeof(struct sh_dmae_device), ++ GFP_KERNEL); + if (!shdev) { + dev_err(&pdev->dev, "Not enough memory\n"); +- goto ealloc; ++ return -ENOMEM; + } + + dma_dev = &shdev->shdma_dev.dma_dev; + +- shdev->chan_reg = ioremap(chan->start, resource_size(chan)); +- if (!shdev->chan_reg) +- goto emapchan; ++ shdev->chan_reg = devm_ioremap_resource(&pdev->dev, chan); ++ if (IS_ERR(shdev->chan_reg)) ++ return PTR_ERR(shdev->chan_reg); + if (dmars) { +- shdev->dmars = ioremap(dmars->start, resource_size(dmars)); +- if (!shdev->dmars) +- goto emapdmars; ++ shdev->dmars = devm_ioremap_resource(&pdev->dev, dmars); ++ if (IS_ERR(shdev->dmars)) ++ return PTR_ERR(shdev->dmars); + } + + if (!pdata->slave_only) +@@ -793,8 +777,8 @@ static int sh_dmae_probe(struct platform_device *pdev) + + errirq = errirq_res->start; + +- err = request_irq(errirq, sh_dmae_err, irqflags, +- "DMAC Address Error", shdev); ++ err = devm_request_irq(&pdev->dev, errirq, sh_dmae_err, irqflags, ++ "DMAC Address Error", shdev); + if (err) { + dev_err(&pdev->dev, + "DMA failed requesting irq #%d, error %d\n", +@@ -872,7 +856,6 @@ chan_probe_err: + sh_dmae_chan_remove(shdev); + + #if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE) +- free_irq(errirq, shdev); + eirq_err: + #endif + rst_err: +@@ -886,18 +869,7 @@ rst_err: + platform_set_drvdata(pdev, NULL); + shdma_cleanup(&shdev->shdma_dev); + eshdma: +- if (dmars) +- iounmap(shdev->dmars); +-emapdmars: +- iounmap(shdev->chan_reg); + synchronize_rcu(); +-emapchan: +- kfree(shdev); +-ealloc: +- if (dmars) +- release_mem_region(dmars->start, resource_size(dmars)); +-ermrdmars: +- release_mem_region(chan->start, resource_size(chan)); + + return err; + } +@@ -923,21 +895,9 @@ static int sh_dmae_remove(struct platform_device *pdev) + sh_dmae_chan_remove(shdev); + shdma_cleanup(&shdev->shdma_dev); + +- if (shdev->dmars) +- iounmap(shdev->dmars); +- iounmap(shdev->chan_reg); +- + platform_set_drvdata(pdev, NULL); + + synchronize_rcu(); +- kfree(shdev); +- +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (res) +- release_mem_region(res->start, resource_size(res)); +- res = platform_get_resource(pdev, IORESOURCE_MEM, 1); +- if (res) +- release_mem_region(res->start, resource_size(res)); + + return 0; + } +diff --git a/drivers/dma/sh/sudmac.c b/drivers/dma/sh/sudmac.c +index e7c94bbddb53..347790167e59 100644 +--- a/drivers/dma/sh/sudmac.c ++++ b/drivers/dma/sh/sudmac.c +@@ -302,7 +302,6 @@ static void sudmac_chan_remove(struct sudmac_device *su_dev) + + BUG_ON(!schan); + +- shdma_free_irq(&sc->shdma_chan); + shdma_chan_remove(schan); + } + dma_dev->chancnt = 0; +diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h +index 5b1c9848124c..31cf89fb1d5b 100644 +--- a/include/linux/shdma-base.h ++++ b/include/linux/shdma-base.h +@@ -116,7 +116,6 @@ struct shdma_dev { + + int shdma_request_irq(struct shdma_chan *, int, + unsigned long, const char *); +-void shdma_free_irq(struct shdma_chan *); + bool shdma_reset(struct shdma_dev *sdev); + void shdma_chan_probe(struct shdma_dev *sdev, + struct shdma_chan *schan, int id); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0054-DMA-shdma-make-a-pointer-const.patch b/patches.renesas/0054-DMA-shdma-make-a-pointer-const.patch new file mode 100644 index 00000000000000..2cbee10ce1fafc --- /dev/null +++ b/patches.renesas/0054-DMA-shdma-make-a-pointer-const.patch @@ -0,0 +1,85 @@ +From 474f6b000e652c8c0b1aa49eed14c7b1cfaaefc9 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Fri, 2 Aug 2013 16:18:09 +0200 +Subject: DMA: shdma: make a pointer const + +Platform data shouldn't be changed at run-time, so, pointers to it should +be const. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> +(cherry picked from commit 2833c47e0ecc74b300716e56810143125ad7a3f1) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + drivers/dma/sh/shdma.c +--- + drivers/dma/sh/shdma.c | 10 +++++----- + drivers/dma/sh/shdma.h | 2 +- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c +index 4f24b9d2b5c3..19068a50ce77 100644 +--- a/drivers/dma/sh/shdma.c ++++ b/drivers/dma/sh/shdma.c +@@ -177,7 +177,7 @@ static bool dmae_is_busy(struct sh_dmae_chan *sh_chan) + static unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan, u32 chcr) + { + struct sh_dmae_device *shdev = to_sh_dev(sh_chan); +- struct sh_dmae_pdata *pdata = shdev->pdata; ++ const struct sh_dmae_pdata *pdata = shdev->pdata; + int cnt = ((chcr & pdata->ts_low_mask) >> pdata->ts_low_shift) | + ((chcr & pdata->ts_high_mask) >> pdata->ts_high_shift); + +@@ -190,7 +190,7 @@ static unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan, u32 chcr) + static u32 log2size_to_chcr(struct sh_dmae_chan *sh_chan, int l2size) + { + struct sh_dmae_device *shdev = to_sh_dev(sh_chan); +- struct sh_dmae_pdata *pdata = shdev->pdata; ++ const struct sh_dmae_pdata *pdata = shdev->pdata; + int i; + + for (i = 0; i < pdata->ts_shift_num; i++) +@@ -250,7 +250,7 @@ static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val) + static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val) + { + struct sh_dmae_device *shdev = to_sh_dev(sh_chan); +- struct sh_dmae_pdata *pdata = shdev->pdata; ++ const struct sh_dmae_pdata *pdata = shdev->pdata; + const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->shdma_chan.id]; + void __iomem *addr = shdev->dmars; + unsigned int shift = chan_pdata->dmars_bit; +@@ -319,7 +319,7 @@ static const struct sh_dmae_slave_config *dmae_find_slave( + struct sh_dmae_chan *sh_chan, int match) + { + struct sh_dmae_device *shdev = to_sh_dev(sh_chan); +- struct sh_dmae_pdata *pdata = shdev->pdata; ++ const struct sh_dmae_pdata *pdata = shdev->pdata; + const struct sh_dmae_slave_config *cfg; + int i; + +@@ -665,7 +665,7 @@ static const struct shdma_ops sh_dmae_shdma_ops = { + + static int sh_dmae_probe(struct platform_device *pdev) + { +- struct sh_dmae_pdata *pdata = dev_get_platdata(&pdev->dev); ++ const struct sh_dmae_pdata *pdata = dev_get_platdata(&pdev->dev); + unsigned long irqflags = IRQF_DISABLED, + chan_flag[SH_DMAE_MAX_CHANNELS] = {}; + int errirq, chan_irq[SH_DMAE_MAX_CHANNELS]; +diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h +index 06aae6ebc82b..3d9dca177860 100644 +--- a/drivers/dma/sh/shdma.h ++++ b/drivers/dma/sh/shdma.h +@@ -36,7 +36,7 @@ struct sh_dmae_chan { + struct sh_dmae_device { + struct shdma_dev shdma_dev; + struct sh_dmae_chan *chan[SH_DMAE_MAX_CHANNELS]; +- struct sh_dmae_pdata *pdata; ++ const struct sh_dmae_pdata *pdata; + struct list_head node; + void __iomem *chan_reg; + void __iomem *dmars; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0055-DMA-shdma-switch-DT-mode-to-use-configuration-data-f.patch b/patches.renesas/0055-DMA-shdma-switch-DT-mode-to-use-configuration-data-f.patch new file mode 100644 index 00000000000000..601e816ff3fe80 --- /dev/null +++ b/patches.renesas/0055-DMA-shdma-switch-DT-mode-to-use-configuration-data-f.patch @@ -0,0 +1,336 @@ +From 49f1a1569b4104c5786fdd90278c61b208364139 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Fri, 2 Aug 2013 16:50:36 +0200 +Subject: DMA: shdma: switch DT mode to use configuration data from a match + table + +This facilitates DMAC DT support by eliminating the need in AUXDATA and +avoiding creating complex DT data. This also fits well with DMAC devices, +of which SoCs often have multiple identical copies and it is perfectly +valid to use a single configuration data set for all of them. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> +(cherry picked from commit 4981c4dc194efb18f0e9a02f1b43e926f2f0d2bb) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + drivers/dma/sh/shdmac.c +--- + Documentation/devicetree/bindings/dma/shdma.txt | 61 ++++++++++++++----------- + drivers/dma/sh/Makefile | 2 + + drivers/dma/sh/shdma-base.c | 15 +++--- + drivers/dma/sh/shdma-of.c | 3 -- + drivers/dma/sh/shdma.h | 1 + + drivers/dma/sh/{shdma.c => shdmac.c} | 30 +++++++----- + drivers/dma/sh/sudmac.c | 3 +- + include/linux/shdma-base.h | 2 +- + 8 files changed, 69 insertions(+), 48 deletions(-) + rename drivers/dma/sh/{shdma.c => shdmac.c} (98%) + +diff --git a/Documentation/devicetree/bindings/dma/shdma.txt b/Documentation/devicetree/bindings/dma/shdma.txt +index c15994aa1939..2a3f3b8946b9 100644 +--- a/Documentation/devicetree/bindings/dma/shdma.txt ++++ b/Documentation/devicetree/bindings/dma/shdma.txt +@@ -22,42 +22,51 @@ Optional properties (currently unused): + * DMA controller + + Required properties: +-- compatible: should be "renesas,shdma" ++- compatible: should be of the form "renesas,shdma-<soc>", where <soc> should ++ be replaced with the desired SoC model, e.g. ++ "renesas,shdma-r8a73a4" for the system DMAC on r8a73a4 SoC + + Example: +- dmac: dma-mux0 { ++ dmac: dma-multiplexer@0 { + compatible = "renesas,shdma-mux"; + #dma-cells = <1>; +- dma-channels = <6>; ++ dma-channels = <20>; + dma-requests = <256>; +- reg = <0 0>; /* Needed for AUXDATA */ +- #address-cells = <1>; +- #size-cells = <1>; ++ #address-cells = <2>; ++ #size-cells = <2>; + ranges; + +- dma0: shdma@fe008020 { +- compatible = "renesas,shdma"; +- reg = <0xfe008020 0x270>, +- <0xfe009000 0xc>; ++ dma0: dma-controller@e6700020 { ++ compatible = "renesas,shdma-r8a73a4"; ++ reg = <0 0xe6700020 0 0x89e0>; + interrupt-parent = <&gic>; +- interrupts = <0 34 4 +- 0 28 4 +- 0 29 4 +- 0 30 4 +- 0 31 4 +- 0 32 4 +- 0 33 4>; ++ interrupts = <0 220 4 ++ 0 200 4 ++ 0 201 4 ++ 0 202 4 ++ 0 203 4 ++ 0 204 4 ++ 0 205 4 ++ 0 206 4 ++ 0 207 4 ++ 0 208 4 ++ 0 209 4 ++ 0 210 4 ++ 0 211 4 ++ 0 212 4 ++ 0 213 4 ++ 0 214 4 ++ 0 215 4 ++ 0 216 4 ++ 0 217 4 ++ 0 218 4 ++ 0 219 4>; + interrupt-names = "error", + "ch0", "ch1", "ch2", "ch3", +- "ch4", "ch5"; +- }; +- +- dma1: shdma@fe018020 { +- ... +- }; +- +- dma2: shdma@fe028020 { +- ... ++ "ch4", "ch5", "ch6", "ch7", ++ "ch8", "ch9", "ch10", "ch11", ++ "ch12", "ch13", "ch14", "ch15", ++ "ch16", "ch17", "ch18", "ch19"; + }; + }; + +diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile +index ccf17cb5af10..9187cc98fbe4 100644 +--- a/drivers/dma/sh/Makefile ++++ b/drivers/dma/sh/Makefile +@@ -1,4 +1,6 @@ + obj-$(CONFIG_SH_DMAE_BASE) += shdma-base.o shdma-of.o + obj-$(CONFIG_SH_DMAE) += shdma.o ++shdma-y := shdmac.o ++shdma-objs := $(shdma-y) + obj-$(CONFIG_SUDMAC) += sudmac.o + obj-$(CONFIG_RCAR_HPB_DMAE) += rcar-hpbdma.o +diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c +index c5ea256c2819..d94ab592cc1b 100644 +--- a/drivers/dma/sh/shdma-base.c ++++ b/drivers/dma/sh/shdma-base.c +@@ -171,7 +171,8 @@ static struct shdma_desc *shdma_get_desc(struct shdma_chan *schan) + return NULL; + } + +-static int shdma_setup_slave(struct shdma_chan *schan, int slave_id) ++static int shdma_setup_slave(struct shdma_chan *schan, int slave_id, ++ dma_addr_t slave_addr) + { + struct shdma_dev *sdev = to_shdma_dev(schan->dma_chan.device); + const struct shdma_ops *ops = sdev->ops; +@@ -179,7 +180,7 @@ static int shdma_setup_slave(struct shdma_chan *schan, int slave_id) + + if (schan->dev->of_node) { + match = schan->hw_req; +- ret = ops->set_slave(schan, match, true); ++ ret = ops->set_slave(schan, match, slave_addr, true); + if (ret < 0) + return ret; + +@@ -194,7 +195,7 @@ static int shdma_setup_slave(struct shdma_chan *schan, int slave_id) + if (test_and_set_bit(slave_id, shdma_slave_used)) + return -EBUSY; + +- ret = ops->set_slave(schan, match, false); ++ ret = ops->set_slave(schan, match, slave_addr, false); + if (ret < 0) { + clear_bit(slave_id, shdma_slave_used); + return ret; +@@ -236,7 +237,7 @@ bool shdma_chan_filter(struct dma_chan *chan, void *arg) + if (!schan->dev->of_node && match >= slave_num) + return false; + +- ret = ops->set_slave(schan, match, true); ++ ret = ops->set_slave(schan, match, 0, true); + if (ret < 0) + return false; + +@@ -259,7 +260,7 @@ static int shdma_alloc_chan_resources(struct dma_chan *chan) + */ + if (slave) { + /* Legacy mode: .private is set in filter */ +- ret = shdma_setup_slave(schan, slave->slave_id); ++ ret = shdma_setup_slave(schan, slave->slave_id, 0); + if (ret < 0) + goto esetslave; + } else { +@@ -680,7 +681,9 @@ static int shdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, + * channel, while using it... + */ + config = (struct dma_slave_config *)arg; +- ret = shdma_setup_slave(schan, config->slave_id); ++ ret = shdma_setup_slave(schan, config->slave_id, ++ config->direction == DMA_DEV_TO_MEM ? ++ config->src_addr : config->dst_addr); + if (ret < 0) + return ret; + break; +diff --git a/drivers/dma/sh/shdma-of.c b/drivers/dma/sh/shdma-of.c +index 966aaab0b4d3..06473a05fe4e 100644 +--- a/drivers/dma/sh/shdma-of.c ++++ b/drivers/dma/sh/shdma-of.c +@@ -45,9 +45,6 @@ static int shdma_of_probe(struct platform_device *pdev) + const struct of_dev_auxdata *lookup = dev_get_platdata(&pdev->dev); + int ret; + +- if (!lookup) +- return -EINVAL; +- + ret = of_dma_controller_register(pdev->dev.of_node, + shdma_of_xlate, pdev); + if (ret < 0) +diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h +index 3d9dca177860..ff2f93b612ca 100644 +--- a/drivers/dma/sh/shdma.h ++++ b/drivers/dma/sh/shdma.h +@@ -31,6 +31,7 @@ struct sh_dmae_chan { + void __iomem *base; + char dev_id[16]; /* unique name per DMAC of channel */ + int pm_error; ++ dma_addr_t slave_addr; + }; + + struct sh_dmae_device { +diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdmac.c +similarity index 98% +rename from drivers/dma/sh/shdma.c +rename to drivers/dma/sh/shdmac.c +index 19068a50ce77..a47b70879e05 100644 +--- a/drivers/dma/sh/shdma.c ++++ b/drivers/dma/sh/shdmac.c +@@ -20,6 +20,8 @@ + + #include <linux/init.h> + #include <linux/module.h> ++#include <linux/of.h> ++#include <linux/of_device.h> + #include <linux/slab.h> + #include <linux/interrupt.h> + #include <linux/dmaengine.h> +@@ -333,7 +335,7 @@ static const struct sh_dmae_slave_config *dmae_find_slave( + } else { + for (i = 0, cfg = pdata->slave; i < pdata->slave_num; i++, cfg++) + if (cfg->mid_rid == match) { +- sh_chan->shdma_chan.slave_id = cfg->slave_id; ++ sh_chan->shdma_chan.slave_id = i; + return cfg; + } + } +@@ -342,7 +344,7 @@ static const struct sh_dmae_slave_config *dmae_find_slave( + } + + static int sh_dmae_set_slave(struct shdma_chan *schan, +- int slave_id, bool try) ++ int slave_id, dma_addr_t slave_addr, bool try) + { + struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, + shdma_chan); +@@ -350,8 +352,10 @@ static int sh_dmae_set_slave(struct shdma_chan *schan, + if (!cfg) + return -ENXIO; + +- if (!try) ++ if (!try) { + sh_chan->config = cfg; ++ sh_chan->slave_addr = slave_addr ? : cfg->addr; ++ } + + return 0; + } +@@ -641,7 +645,7 @@ static dma_addr_t sh_dmae_slave_addr(struct shdma_chan *schan) + * This is an exclusive slave DMA operation, may only be called after a + * successful slave configuration. + */ +- return sh_chan->config->addr; ++ return sh_chan->slave_addr; + } + + static struct shdma_desc *sh_dmae_embedded_desc(void *buf, int i) +@@ -663,9 +667,14 @@ static const struct shdma_ops sh_dmae_shdma_ops = { + .get_partial = sh_dmae_get_partial, + }; + ++static const struct of_device_id sh_dmae_of_match[] = { ++ {} ++}; ++MODULE_DEVICE_TABLE(of, sh_dmae_of_match); ++ + static int sh_dmae_probe(struct platform_device *pdev) + { +- const struct sh_dmae_pdata *pdata = dev_get_platdata(&pdev->dev); ++ const struct sh_dmae_pdata *pdata; + unsigned long irqflags = IRQF_DISABLED, + chan_flag[SH_DMAE_MAX_CHANNELS] = {}; + int errirq, chan_irq[SH_DMAE_MAX_CHANNELS]; +@@ -674,6 +683,11 @@ static int sh_dmae_probe(struct platform_device *pdev) + struct dma_device *dma_dev; + struct resource *chan, *dmars, *errirq_res, *chanirq_res; + ++ if (pdev->dev.of_node) ++ pdata = of_match_device(sh_dmae_of_match, &pdev->dev)->data; ++ else ++ pdata = pdev->dev.platform_data; ++ + /* get platform data */ + if (!pdata || !pdata->channel_num) + return -ENODEV; +@@ -902,12 +916,6 @@ static int sh_dmae_remove(struct platform_device *pdev) + return 0; + } + +-static const struct of_device_id sh_dmae_of_match[] = { +- { .compatible = "renesas,shdma", }, +- { } +-}; +-MODULE_DEVICE_TABLE(of, sh_dmae_of_match); +- + static struct platform_driver sh_dmae_driver = { + .driver = { + .owner = THIS_MODULE, +diff --git a/drivers/dma/sh/sudmac.c b/drivers/dma/sh/sudmac.c +index 347790167e59..2a8e3c2ac4b3 100644 +--- a/drivers/dma/sh/sudmac.c ++++ b/drivers/dma/sh/sudmac.c +@@ -150,7 +150,8 @@ static const struct sudmac_slave_config *sudmac_find_slave( + return NULL; + } + +-static int sudmac_set_slave(struct shdma_chan *schan, int slave_id, bool try) ++static int sudmac_set_slave(struct shdma_chan *schan, int slave_id, ++ dma_addr_t slave_addr, bool try) + { + struct sudmac_chan *sc = to_chan(schan); + const struct sudmac_slave_config *cfg = sudmac_find_slave(sc, slave_id); +diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h +index 31cf89fb1d5b..f92c0a43c54c 100644 +--- a/include/linux/shdma-base.h ++++ b/include/linux/shdma-base.h +@@ -96,7 +96,7 @@ struct shdma_ops { + dma_addr_t (*slave_addr)(struct shdma_chan *); + int (*desc_setup)(struct shdma_chan *, struct shdma_desc *, + dma_addr_t, dma_addr_t, size_t *); +- int (*set_slave)(struct shdma_chan *, int, bool); ++ int (*set_slave)(struct shdma_chan *, int, dma_addr_t, bool); + void (*setup_xfer)(struct shdma_chan *, int); + void (*start_xfer)(struct shdma_chan *, struct shdma_desc *); + struct shdma_desc *(*embedded_desc)(void *, int); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0056-DMA-shdma-remove-private-and-unused-defines-from-a-g.patch b/patches.renesas/0056-DMA-shdma-remove-private-and-unused-defines-from-a-g.patch new file mode 100644 index 00000000000000..8d8f57f1299856 --- /dev/null +++ b/patches.renesas/0056-DMA-shdma-remove-private-and-unused-defines-from-a-g.patch @@ -0,0 +1,86 @@ +From cf2789b3dc494b9202172c16e36a6e7a02712b90 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Fri, 2 Aug 2013 16:50:37 +0200 +Subject: DMA: shdma: remove private and unused defines from a global header + +Macros, named like TEND or SAR lack a namespace and are too broadly named +for a global header. Besides, they aren't needed globally. Move them to +where they belong - into the driver. Some other macros aren't used at all, +remove them. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> +(cherry picked from commit 4620ad5419612fcd9ab412410440d3a7e8a9a90a) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/dma/sh/shdmac.c | 9 +++++++++ + include/linux/sh_dma.h | 21 --------------------- + 2 files changed, 9 insertions(+), 21 deletions(-) + +diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c +index a47b70879e05..03efd4ad0f0b 100644 +--- a/drivers/dma/sh/shdmac.c ++++ b/drivers/dma/sh/shdmac.c +@@ -37,6 +37,15 @@ + #include "../dmaengine.h" + #include "shdma.h" + ++/* DMA register */ ++#define SAR 0x00 ++#define DAR 0x04 ++#define TCR 0x08 ++#define CHCR 0x0C ++#define DMAOR 0x40 ++ ++#define TEND 0x18 /* USB-DMAC */ ++ + #define SH_DMAE_DRV_NAME "sh-dma-engine" + + /* Default MEMCPY transfer size = 2^2 = 4 bytes */ +diff --git a/include/linux/sh_dma.h b/include/linux/sh_dma.h +index 776ed9d682f4..b7b43b82231e 100644 +--- a/include/linux/sh_dma.h ++++ b/include/linux/sh_dma.h +@@ -94,39 +94,18 @@ struct sh_dmae_pdata { + unsigned int slave_only:1; + }; + +-/* DMA register */ +-#define SAR 0x00 +-#define DAR 0x04 +-#define TCR 0x08 +-#define CHCR 0x0C +-#define DMAOR 0x40 +- +-#define TEND 0x18 /* USB-DMAC */ +- + /* DMAOR definitions */ + #define DMAOR_AE 0x00000004 + #define DMAOR_NMIF 0x00000002 + #define DMAOR_DME 0x00000001 + + /* Definitions for the SuperH DMAC */ +-#define REQ_L 0x00000000 +-#define REQ_E 0x00080000 +-#define RACK_H 0x00000000 +-#define RACK_L 0x00040000 +-#define ACK_R 0x00000000 +-#define ACK_W 0x00020000 +-#define ACK_H 0x00000000 +-#define ACK_L 0x00010000 + #define DM_INC 0x00004000 + #define DM_DEC 0x00008000 + #define DM_FIX 0x0000c000 + #define SM_INC 0x00001000 + #define SM_DEC 0x00002000 + #define SM_FIX 0x00003000 +-#define RS_IN 0x00000200 +-#define RS_OUT 0x00000300 +-#define TS_BLK 0x00000040 +-#define TM_BUR 0x00000020 + #define CHCR_DE 0x00000001 + #define CHCR_TE 0x00000002 + #define CHCR_IE 0x00000004 +-- +1.8.5.rc3 + diff --git a/patches.renesas/0057-DMA-shdma-add-a-header-with-common-for-ARM-SoCs-defi.patch b/patches.renesas/0057-DMA-shdma-add-a-header-with-common-for-ARM-SoCs-defi.patch new file mode 100644 index 00000000000000..150b02d0e0ed17 --- /dev/null +++ b/patches.renesas/0057-DMA-shdma-add-a-header-with-common-for-ARM-SoCs-defi.patch @@ -0,0 +1,81 @@ +From addb5ef290ff3b57b4c1fe3fd348bfe29bf0623f Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Fri, 2 Aug 2013 16:50:38 +0200 +Subject: DMA: shdma: add a header with common for ARM SoCs defines + +All shdma DMACs on ARM SoCs share certain register layout patterns, which +are currently defined in arch/arm/mach-shmobile/include/mach/dma-register.h. +That header is included by SoC-specific setup-*.c files to be used in DMAC +platform data. That header, however, cannot be directly used by the driver. +This patch copies those defines into a driver-local header to be used by +Device Tree configurations. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> +(cherry picked from commit 8eb742a0914cd79053d092a14bfac5315993dd61) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/dma/sh/shdma-arm.h | 51 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 51 insertions(+) + create mode 100644 drivers/dma/sh/shdma-arm.h + +diff --git a/drivers/dma/sh/shdma-arm.h b/drivers/dma/sh/shdma-arm.h +new file mode 100644 +index 000000000000..a2b8258426c9 +--- /dev/null ++++ b/drivers/dma/sh/shdma-arm.h +@@ -0,0 +1,51 @@ ++/* ++ * Renesas SuperH DMA Engine support ++ * ++ * Copyright (C) 2013 Renesas Electronics, Inc. ++ * ++ * This is free software; you can redistribute it and/or modify it under the ++ * terms of version 2 the GNU General Public License as published by the Free ++ * Software Foundation. ++ */ ++ ++#ifndef SHDMA_ARM_H ++#define SHDMA_ARM_H ++ ++#include "shdma.h" ++ ++/* Transmit sizes and respective CHCR register values */ ++enum { ++ XMIT_SZ_8BIT = 0, ++ XMIT_SZ_16BIT = 1, ++ XMIT_SZ_32BIT = 2, ++ XMIT_SZ_64BIT = 7, ++ XMIT_SZ_128BIT = 3, ++ XMIT_SZ_256BIT = 4, ++ XMIT_SZ_512BIT = 5, ++}; ++ ++/* log2(size / 8) - used to calculate number of transfers */ ++#define SH_DMAE_TS_SHIFT { \ ++ [XMIT_SZ_8BIT] = 0, \ ++ [XMIT_SZ_16BIT] = 1, \ ++ [XMIT_SZ_32BIT] = 2, \ ++ [XMIT_SZ_64BIT] = 3, \ ++ [XMIT_SZ_128BIT] = 4, \ ++ [XMIT_SZ_256BIT] = 5, \ ++ [XMIT_SZ_512BIT] = 6, \ ++} ++ ++#define TS_LOW_BIT 0x3 /* --xx */ ++#define TS_HI_BIT 0xc /* xx-- */ ++ ++#define TS_LOW_SHIFT (3) ++#define TS_HI_SHIFT (20 - 2) /* 2 bits for shifted low TS */ ++ ++#define TS_INDEX2VAL(i) \ ++ ((((i) & TS_LOW_BIT) << TS_LOW_SHIFT) |\ ++ (((i) & TS_HI_BIT) << TS_HI_SHIFT)) ++ ++#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz))) ++#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz))) ++ ++#endif +-- +1.8.5.rc3 + diff --git a/patches.renesas/0058-DMA-shdma-add-r8a73a4-DMAC-data-to-the-device-ID-tab.patch b/patches.renesas/0058-DMA-shdma-add-r8a73a4-DMAC-data-to-the-device-ID-tab.patch new file mode 100644 index 00000000000000..356db96c455498 --- /dev/null +++ b/patches.renesas/0058-DMA-shdma-add-r8a73a4-DMAC-data-to-the-device-ID-tab.patch @@ -0,0 +1,168 @@ +From 07ed3f53fee0e2594a17873673f760b0a2913691 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Fri, 2 Aug 2013 16:50:39 +0200 +Subject: DMA: shdma: add r8a73a4 DMAC data to the device ID table + +This configuration data will be used, when DMAC DT support is added to +r8a73a4. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Vinod Koul <vinod.koul@intel.com> +(cherry picked from commit 1e69653d40f1a280dbfef48b0c62473ac415dd57) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + drivers/dma/sh/Kconfig +--- + drivers/dma/sh/Kconfig | 8 ++--- + drivers/dma/sh/Makefile | 3 ++ + drivers/dma/sh/shdma-r8a73a4.c | 77 ++++++++++++++++++++++++++++++++++++++++++ + drivers/dma/sh/shdma.h | 7 ++++ + drivers/dma/sh/shdmac.c | 1 + + 5 files changed, 91 insertions(+), 5 deletions(-) + create mode 100644 drivers/dma/sh/shdma-r8a73a4.c + +diff --git a/drivers/dma/sh/Kconfig b/drivers/dma/sh/Kconfig +index e2b94d16f41f..d0924b6948e0 100644 +--- a/drivers/dma/sh/Kconfig ++++ b/drivers/dma/sh/Kconfig +@@ -23,8 +23,6 @@ config SUDMAC + help + Enable support for the Renesas SUDMAC controllers. + +-config RCAR_HPB_DMAE +- tristate "Renesas R-Car HPB DMAC support" +- depends on SH_DMAE_BASE +- help +- Enable support for the Renesas R-Car series DMA controllers. ++config SHDMA_R8A73A4 ++ def_bool y ++ depends on ARCH_R8A73A4 && SH_DMAE != n +diff --git a/drivers/dma/sh/Makefile b/drivers/dma/sh/Makefile +index 9187cc98fbe4..e856af23b789 100644 +--- a/drivers/dma/sh/Makefile ++++ b/drivers/dma/sh/Makefile +@@ -1,6 +1,9 @@ + obj-$(CONFIG_SH_DMAE_BASE) += shdma-base.o shdma-of.o + obj-$(CONFIG_SH_DMAE) += shdma.o + shdma-y := shdmac.o ++ifeq ($(CONFIG_OF),y) ++shdma-$(CONFIG_SHDMA_R8A73A4) += shdma-r8a73a4.o ++endif + shdma-objs := $(shdma-y) + obj-$(CONFIG_SUDMAC) += sudmac.o + obj-$(CONFIG_RCAR_HPB_DMAE) += rcar-hpbdma.o +diff --git a/drivers/dma/sh/shdma-r8a73a4.c b/drivers/dma/sh/shdma-r8a73a4.c +new file mode 100644 +index 000000000000..4fb99970a3ea +--- /dev/null ++++ b/drivers/dma/sh/shdma-r8a73a4.c +@@ -0,0 +1,77 @@ ++/* ++ * Renesas SuperH DMA Engine support for r8a73a4 (APE6) SoCs ++ * ++ * Copyright (C) 2013 Renesas Electronics, Inc. ++ * ++ * This is free software; you can redistribute it and/or modify it under the ++ * terms of version 2 the GNU General Public License as published by the Free ++ * Software Foundation. ++ */ ++#include <linux/sh_dma.h> ++ ++#include "shdma-arm.h" ++ ++const unsigned int dma_ts_shift[] = SH_DMAE_TS_SHIFT; ++ ++static const struct sh_dmae_slave_config dma_slaves[] = { ++ { ++ .chcr = CHCR_TX(XMIT_SZ_32BIT), ++ .mid_rid = 0xd1, /* MMC0 Tx */ ++ }, { ++ .chcr = CHCR_RX(XMIT_SZ_32BIT), ++ .mid_rid = 0xd2, /* MMC0 Rx */ ++ }, { ++ .chcr = CHCR_TX(XMIT_SZ_32BIT), ++ .mid_rid = 0xe1, /* MMC1 Tx */ ++ }, { ++ .chcr = CHCR_RX(XMIT_SZ_32BIT), ++ .mid_rid = 0xe2, /* MMC1 Rx */ ++ }, ++}; ++ ++#define DMAE_CHANNEL(a, b) \ ++ { \ ++ .offset = (a) - 0x20, \ ++ .dmars = (a) - 0x20 + 0x40, \ ++ .chclr_bit = (b), \ ++ .chclr_offset = 0x80 - 0x20, \ ++ } ++ ++static const struct sh_dmae_channel dma_channels[] = { ++ DMAE_CHANNEL(0x8000, 0), ++ DMAE_CHANNEL(0x8080, 1), ++ DMAE_CHANNEL(0x8100, 2), ++ DMAE_CHANNEL(0x8180, 3), ++ DMAE_CHANNEL(0x8200, 4), ++ DMAE_CHANNEL(0x8280, 5), ++ DMAE_CHANNEL(0x8300, 6), ++ DMAE_CHANNEL(0x8380, 7), ++ DMAE_CHANNEL(0x8400, 8), ++ DMAE_CHANNEL(0x8480, 9), ++ DMAE_CHANNEL(0x8500, 10), ++ DMAE_CHANNEL(0x8580, 11), ++ DMAE_CHANNEL(0x8600, 12), ++ DMAE_CHANNEL(0x8680, 13), ++ DMAE_CHANNEL(0x8700, 14), ++ DMAE_CHANNEL(0x8780, 15), ++ DMAE_CHANNEL(0x8800, 16), ++ DMAE_CHANNEL(0x8880, 17), ++ DMAE_CHANNEL(0x8900, 18), ++ DMAE_CHANNEL(0x8980, 19), ++}; ++ ++const struct sh_dmae_pdata r8a73a4_dma_pdata = { ++ .slave = dma_slaves, ++ .slave_num = ARRAY_SIZE(dma_slaves), ++ .channel = dma_channels, ++ .channel_num = ARRAY_SIZE(dma_channels), ++ .ts_low_shift = TS_LOW_SHIFT, ++ .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT, ++ .ts_high_shift = TS_HI_SHIFT, ++ .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT, ++ .ts_shift = dma_ts_shift, ++ .ts_shift_num = ARRAY_SIZE(dma_ts_shift), ++ .dmaor_init = DMAOR_DME, ++ .chclr_present = 1, ++ .chclr_bitwise = 1, ++}; +diff --git a/drivers/dma/sh/shdma.h b/drivers/dma/sh/shdma.h +index ff2f93b612ca..758a57b51875 100644 +--- a/drivers/dma/sh/shdma.h ++++ b/drivers/dma/sh/shdma.h +@@ -62,4 +62,11 @@ struct sh_dmae_desc { + #define to_sh_dev(chan) container_of(chan->shdma_chan.dma_chan.device,\ + struct sh_dmae_device, shdma_dev.dma_dev) + ++#ifdef CONFIG_SHDMA_R8A73A4 ++extern const struct sh_dmae_pdata r8a73a4_dma_pdata; ++#define r8a73a4_shdma_devid (&r8a73a4_dma_pdata) ++#else ++#define r8a73a4_shdma_devid NULL ++#endif ++ + #endif /* __DMA_SHDMA_H */ +diff --git a/drivers/dma/sh/shdmac.c b/drivers/dma/sh/shdmac.c +index 03efd4ad0f0b..77de5e4375f2 100644 +--- a/drivers/dma/sh/shdmac.c ++++ b/drivers/dma/sh/shdmac.c +@@ -677,6 +677,7 @@ static const struct shdma_ops sh_dmae_shdma_ops = { + }; + + static const struct of_device_id sh_dmae_of_match[] = { ++ {.compatible = "renesas,shdma-r8a73a4", .data = r8a73a4_shdma_devid,}, + {} + }; + MODULE_DEVICE_TABLE(of, sh_dmae_of_match); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0059-ARM-elf-add-new-hwcap-for-identifying-atomic-ldrd-st.patch b/patches.renesas/0059-ARM-elf-add-new-hwcap-for-identifying-atomic-ldrd-st.patch new file mode 100644 index 00000000000000..72ac3fce9ba6de --- /dev/null +++ b/patches.renesas/0059-ARM-elf-add-new-hwcap-for-identifying-atomic-ldrd-st.patch @@ -0,0 +1,69 @@ +From ee10a5d3f0e1c7edc8c7b96c751806a623d5f3b9 Mon Sep 17 00:00:00 2001 +From: Will Deacon <will.deacon@arm.com> +Date: Mon, 8 Apr 2013 17:13:12 +0100 +Subject: ARM: elf: add new hwcap for identifying atomic ldrd/strd instructions + +CPUs implementing LPAE have atomic ldrd/strd instructions, meaning that +userspace software can avoid having to use the exclusive variants of +these instructions if they wish. + +This patch advertises the atomicity of these instructions via the +hwcaps, so userspace can detect this CPU feature. + +Reported-by: Vladimir Danushevsky <vladimir.danushevsky@oracle.com> +Signed-off-by: Will Deacon <will.deacon@arm.com> +(cherry picked from commit a469abd0f868c902b75532579bf87553dcf1b360) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/include/uapi/asm/hwcap.h | 2 +- + arch/arm/kernel/setup.c | 8 +++++++- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/include/uapi/asm/hwcap.h b/arch/arm/include/uapi/asm/hwcap.h +index 3688fd15a32d..6d34d080372a 100644 +--- a/arch/arm/include/uapi/asm/hwcap.h ++++ b/arch/arm/include/uapi/asm/hwcap.h +@@ -25,6 +25,6 @@ + #define HWCAP_IDIVT (1 << 18) + #define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */ + #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT) +- ++#define HWCAP_LPAE (1 << 20) + + #endif /* _UAPI__ASMARM_HWCAP_H */ +diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c +index b4b1d397592b..6cc3db43e897 100644 +--- a/arch/arm/kernel/setup.c ++++ b/arch/arm/kernel/setup.c +@@ -355,7 +355,7 @@ void __init early_print(const char *str, ...) + + static void __init cpuid_init_hwcaps(void) + { +- unsigned int divide_instrs; ++ unsigned int divide_instrs, vmsa; + + if (cpu_architecture() < CPU_ARCH_ARMv7) + return; +@@ -368,6 +368,11 @@ static void __init cpuid_init_hwcaps(void) + case 1: + elf_hwcap |= HWCAP_IDIVT; + } ++ ++ /* LPAE implies atomic ldrd/strd instructions */ ++ vmsa = (read_cpuid_ext(CPUID_EXT_MMFR0) & 0xf) >> 0; ++ if (vmsa >= 5) ++ elf_hwcap |= HWCAP_LPAE; + } + + static void __init feat_v6_fixup(void) +@@ -872,6 +877,7 @@ static const char *hwcap_str[] = { + "vfpv4", + "idiva", + "idivt", ++ "lpae", + NULL + }; + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0060-ARM-ARM64-arch_timer-add-macros-for-bits-in-control-.patch b/patches.renesas/0060-ARM-ARM64-arch_timer-add-macros-for-bits-in-control-.patch new file mode 100644 index 00000000000000..3f58cc7b944aa4 --- /dev/null +++ b/patches.renesas/0060-ARM-ARM64-arch_timer-add-macros-for-bits-in-control-.patch @@ -0,0 +1,88 @@ +From 319ec37d4a51fa86e25b5185b17ce9c3d4840caa Mon Sep 17 00:00:00 2001 +From: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com> +Date: Tue, 13 Aug 2013 13:43:26 +0100 +Subject: ARM/ARM64: arch_timer: add macros for bits in control register + +Add macros to describe the bitfields in the ARM architected timer +control register to make code easy to understand. + +Reviewed-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> +Reviewed-by: Will Deacon <will.deacon@arm.com> +Acked-by: Catalin Marinas <catalin.marinas@arm.com> +Acked-by: Olof Johansson <olof@lixom.net> +Signed-off-by: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com> +(cherry picked from commit 28061758dc83df445a05af347b5ce55ccd968c03) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/include/asm/arch_timer.h | 9 +++++++-- + arch/arm64/include/asm/arch_timer.h | 12 ++++++++---- + include/clocksource/arm_arch_timer.h | 8 ++++++++ + 3 files changed, 23 insertions(+), 6 deletions(-) + +diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h +index 556094689724..c78c4cbd329e 100644 +--- a/arch/arm/include/asm/arch_timer.h ++++ b/arch/arm/include/asm/arch_timer.h +@@ -93,8 +93,13 @@ static inline void __cpuinit arch_counter_set_user_access(void) + + asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl)); + +- /* disable user access to everything */ +- cntkctl &= ~((3 << 8) | (7 << 0)); ++ /* Disable user access to both physical/virtual counters/timers */ ++ /* Also disable virtual event stream */ ++ cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN ++ | ARCH_TIMER_USR_VT_ACCESS_EN ++ | ARCH_TIMER_VIRT_EVT_EN ++ | ARCH_TIMER_USR_VCT_ACCESS_EN ++ | ARCH_TIMER_USR_PCT_ACCESS_EN); + + asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl)); + } +diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h +index 7181e777c2c5..aaee5f73adae 100644 +--- a/arch/arm64/include/asm/arch_timer.h ++++ b/arch/arm64/include/asm/arch_timer.h +@@ -96,12 +96,16 @@ static inline void __cpuinit arch_counter_set_user_access(void) + { + u32 cntkctl; + +- /* Disable user access to the timers and the physical counter. */ + asm volatile("mrs %0, cntkctl_el1" : "=r" (cntkctl)); +- cntkctl &= ~((3 << 8) | (1 << 0)); + +- /* Enable user access to the virtual counter and frequency. */ +- cntkctl |= (1 << 1); ++ /* Disable user access to the timers and the physical counter */ ++ cntkctl &= ~(ARCH_TIMER_USR_PT_ACCESS_EN ++ | ARCH_TIMER_USR_VT_ACCESS_EN ++ | ARCH_TIMER_USR_PCT_ACCESS_EN); ++ ++ /* Enable user access to the virtual counter */ ++ cntkctl |= ARCH_TIMER_USR_VCT_ACCESS_EN; ++ + asm volatile("msr cntkctl_el1, %0" : : "r" (cntkctl)); + } + +diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h +index f3da817b9b8e..e6bc74f1119c 100644 +--- a/include/clocksource/arm_arch_timer.h ++++ b/include/clocksource/arm_arch_timer.h +@@ -31,6 +31,14 @@ enum arch_timer_reg { + #define ARCH_TIMER_PHYS_ACCESS 0 + #define ARCH_TIMER_VIRT_ACCESS 1 + ++#define ARCH_TIMER_USR_PCT_ACCESS_EN (1 << 0) /* physical counter */ ++#define ARCH_TIMER_USR_VCT_ACCESS_EN (1 << 1) /* virtual counter */ ++#define ARCH_TIMER_VIRT_EVT_EN (1 << 2) ++#define ARCH_TIMER_EVT_TRIGGER_SHIFT (4) ++#define ARCH_TIMER_EVT_TRIGGER_MASK (0xF << ARCH_TIMER_EVT_TRIGGER_SHIFT) ++#define ARCH_TIMER_USR_VT_ACCESS_EN (1 << 8) /* virtual timer registers */ ++#define ARCH_TIMER_USR_PT_ACCESS_EN (1 << 9) /* physical timer registers */ ++ + #ifdef CONFIG_ARM_ARCH_TIMER + + extern u32 arch_timer_get_rate(void); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0061-sh_eth-add-use-RMCR.RNC-bit.patch b/patches.renesas/0061-sh_eth-add-use-RMCR.RNC-bit.patch new file mode 100644 index 00000000000000..694f2d6bc7156c --- /dev/null +++ b/patches.renesas/0061-sh_eth-add-use-RMCR.RNC-bit.patch @@ -0,0 +1,67 @@ +From 84399e3c5faa040a4dac3c464dc94aa2c2307277 Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Date: Wed, 16 Oct 2013 02:29:58 +0400 +Subject: sh_eth: add/use RMCR.RNC bit + +Declare 'enum RMCR_BIT' containing the single member for the RMCR.RNC bit and +replace bare numbers in the driver by this mnemonic. + +Suggested-by: David Miller <davem@davemloft.net> +Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Reviewed-by: Simon Horman <horms+renesas@verge.net.au> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 305a3388b5b3121aff6b10054136b40ca91ab35b) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/net/ethernet/renesas/sh_eth.c | 6 +++--- + drivers/net/ethernet/renesas/sh_eth.h | 3 +++ + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c +index b54bbbd5826a..5ffaf56a0706 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -483,7 +483,7 @@ static struct sh_eth_cpu_data sh7757_data = { + .register_type = SH_ETH_REG_FAST_SH4, + + .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff, +- .rmcr_value = 0x00000001, ++ .rmcr_value = RMCR_RNC, + + .tx_check = EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO, + .eesr_err_check = EESR_TWB | EESR_TABT | EESR_RABT | EESR_RFE | +@@ -561,7 +561,7 @@ static struct sh_eth_cpu_data sh7757_data_giga = { + EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | + EESR_TDE | EESR_ECI, + .fdr_value = 0x0000072f, +- .rmcr_value = 0x00000001, ++ .rmcr_value = RMCR_RNC, + + .irq_flags = IRQF_SHARED, + .apr = 1, +@@ -689,7 +689,7 @@ static struct sh_eth_cpu_data r8a7740_data = { + EESR_RFE | EESR_RDE | EESR_RFRMER | EESR_TFE | + EESR_TDE | EESR_ECI, + .fdr_value = 0x0000070f, +- .rmcr_value = 0x00000001, ++ .rmcr_value = RMCR_RNC, + + .apr = 1, + .mpr = 1, +diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h +index a0db02c63b11..f32c1692d310 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.h ++++ b/drivers/net/ethernet/renesas/sh_eth.h +@@ -321,6 +321,9 @@ enum TD_STS_BIT { + #define TD_TFP (TD_TFP1|TD_TFP0) + + /* RMCR */ ++enum RMCR_BIT { ++ RMCR_RNC = 0x00000001, ++}; + #define DEFAULT_RMCR_VALUE 0x00000000 + + /* ECMR */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0062-sh_eth-check-platform-data-pointer.patch b/patches.renesas/0062-sh_eth-check-platform-data-pointer.patch new file mode 100644 index 00000000000000..2cd219782501a6 --- /dev/null +++ b/patches.renesas/0062-sh_eth-check-platform-data-pointer.patch @@ -0,0 +1,40 @@ +From afb37f872d6e7c43200edfa28e0d2bcc4dee9103 Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Date: Wed, 30 Oct 2013 23:30:19 +0300 +Subject: sh_eth: check platform data pointer + +Check the platform data pointer before dereferencing it and error out of the +probe() method if it's NULL. + +This has additional effect of preventing kernel oops with outdated platform data +containing zero PHY address instead (such as on SolutionEngine7710). + +Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Acked-by: Simon Horman <horms+renesas@verge.net.au> +Signed-off-by: David S. Miller <davem@davemloft.net> +(cherry picked from commit 3b4c5cbf42bda976ab70354e7786a0808265d9d5) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/net/ethernet/renesas/sh_eth.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c +index 5ffaf56a0706..8bced1c44378 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -2663,6 +2663,12 @@ static int sh_eth_drv_probe(struct platform_device *pdev) + pm_runtime_enable(&pdev->dev); + pm_runtime_resume(&pdev->dev); + ++ if (!pd) { ++ dev_err(&pdev->dev, "no platform data\n"); ++ ret = -EINVAL; ++ goto out_release; ++ } ++ + /* get PHY ID */ + mdp->phy_id = pd->phy; + mdp->phy_interface = pd->phy_interface; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0063-gpio-rcar-drop-references-to-virtual-IRQ.patch b/patches.renesas/0063-gpio-rcar-drop-references-to-virtual-IRQ.patch new file mode 100644 index 00000000000000..f703a723c7bf4c --- /dev/null +++ b/patches.renesas/0063-gpio-rcar-drop-references-to-virtual-IRQ.patch @@ -0,0 +1,48 @@ +From bec9700ceea72c20e7f80ae2c716896cc4eb1aa9 Mon Sep 17 00:00:00 2001 +From: Linus Walleij <linus.walleij@linaro.org> +Date: Fri, 11 Oct 2013 19:43:39 +0200 +Subject: gpio: rcar: drop references to "virtual" IRQ + +Rename the argument "virq" to just "irq", this IRQ isn't any +more "virtual" than any other Linux IRQ number, we use "hwirq" +for the actual hw-numbers, "virq" is just bogus. + +Cc: Magnus Damm <damm@opensource.se> +Acked-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +(cherry picked from commit c0d6c1ad0ad8fa1b7c2148ba918fd5d64a51166a) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpio/gpio-rcar.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c +index 0be07f22cb10..ce1c14b16bf3 100644 +--- a/drivers/gpio/gpio-rcar.c ++++ b/drivers/gpio/gpio-rcar.c +@@ -266,16 +266,16 @@ static int gpio_rcar_to_irq(struct gpio_chip *chip, unsigned offset) + return irq_create_mapping(gpio_to_priv(chip)->irq_domain, offset); + } + +-static int gpio_rcar_irq_domain_map(struct irq_domain *h, unsigned int virq, +- irq_hw_number_t hw) ++static int gpio_rcar_irq_domain_map(struct irq_domain *h, unsigned int irq, ++ irq_hw_number_t hwirq) + { + struct gpio_rcar_priv *p = h->host_data; + +- dev_dbg(&p->pdev->dev, "map hw irq = %d, virq = %d\n", (int)hw, virq); ++ dev_dbg(&p->pdev->dev, "map hw irq = %d, irq = %d\n", (int)hwirq, irq); + +- irq_set_chip_data(virq, h->host_data); +- irq_set_chip_and_handler(virq, &p->irq_chip, handle_level_irq); +- set_irq_flags(virq, IRQF_VALID); /* kill me now */ ++ irq_set_chip_data(irq, h->host_data); ++ irq_set_chip_and_handler(irq, &p->irq_chip, handle_level_irq); ++ set_irq_flags(irq, IRQF_VALID); /* kill me now */ + return 0; + } + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0064-gpio-rcar-Include-linux-of.h-header.patch b/patches.renesas/0064-gpio-rcar-Include-linux-of.h-header.patch new file mode 100644 index 00000000000000..118ddf6cb7ec19 --- /dev/null +++ b/patches.renesas/0064-gpio-rcar-Include-linux-of.h-header.patch @@ -0,0 +1,31 @@ +From fdfdc54bb926e1c5771a1ef3fade144d75793f28 Mon Sep 17 00:00:00 2001 +From: Sachin Kamat <sachin.kamat@linaro.org> +Date: Wed, 16 Oct 2013 15:35:02 +0530 +Subject: gpio: rcar: Include linux/of.h header + +'of_match_ptr' is defined in linux/of.h. Include it explicitly to +avoid build breakage in the future. + +Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +(cherry picked from commit bd0bf46844ad79c1360eebc73bf6f1e4c31b39fb) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/gpio/gpio-rcar.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c +index ce1c14b16bf3..11faf316c814 100644 +--- a/drivers/gpio/gpio-rcar.c ++++ b/drivers/gpio/gpio-rcar.c +@@ -22,6 +22,7 @@ + #include <linux/irq.h> + #include <linux/irqdomain.h> + #include <linux/module.h> ++#include <linux/of.h> + #include <linux/pinctrl/consumer.h> + #include <linux/platform_data/gpio-rcar.h> + #include <linux/platform_device.h> +-- +1.8.5.rc3 + diff --git a/patches.renesas/0065-i2c-sh_mobile-Convert-to-clk_prepare-unprepare.patch b/patches.renesas/0065-i2c-sh_mobile-Convert-to-clk_prepare-unprepare.patch new file mode 100644 index 00000000000000..3f40c0fe9d1015 --- /dev/null +++ b/patches.renesas/0065-i2c-sh_mobile-Convert-to-clk_prepare-unprepare.patch @@ -0,0 +1,59 @@ +From bf13ce07d60de51545eb44fbae163ac831937985 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Mon, 28 Oct 2013 23:49:23 +0100 +Subject: i2c: sh_mobile: Convert to clk_prepare/unprepare + +Turn clk_enable() and clk_disable() calls into clk_prepare_enable() and +clk_disable_unprepare() to get ready for the migration to the common +clock framework. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +(cherry picked from commit f887605d25c1514b06b1a0e0477f85f27f23664d) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/i2c/busses/i2c-sh_mobile.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c +index debf745c0268..10a83ca6f8ca 100644 +--- a/drivers/i2c/busses/i2c-sh_mobile.c ++++ b/drivers/i2c/busses/i2c-sh_mobile.c +@@ -236,7 +236,7 @@ static void sh_mobile_i2c_init(struct sh_mobile_i2c_data *pd) + int offset; + + /* Get clock rate after clock is enabled */ +- clk_enable(pd->clk); ++ clk_prepare_enable(pd->clk); + i2c_clk_khz = clk_get_rate(pd->clk) / 1000; + i2c_clk_khz /= pd->clks_per_count; + +@@ -271,14 +271,14 @@ static void sh_mobile_i2c_init(struct sh_mobile_i2c_data *pd) + pd->icic &= ~ICIC_ICCHB8; + + out: +- clk_disable(pd->clk); ++ clk_disable_unprepare(pd->clk); + } + + static void activate_ch(struct sh_mobile_i2c_data *pd) + { + /* Wake up device and enable clock */ + pm_runtime_get_sync(pd->dev); +- clk_enable(pd->clk); ++ clk_prepare_enable(pd->clk); + + /* Enable channel and configure rx ack */ + iic_set_clr(pd, ICCR, ICCR_ICE, 0); +@@ -301,7 +301,7 @@ static void deactivate_ch(struct sh_mobile_i2c_data *pd) + iic_set_clr(pd, ICCR, 0, ICCR_ICE); + + /* Disable clock and mark device as idle */ +- clk_disable(pd->clk); ++ clk_disable_unprepare(pd->clk); + pm_runtime_put_sync(pd->dev); + } + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0066-i2c-rcar-cosmetic-remove-superfluous-parenthesis.patch b/patches.renesas/0066-i2c-rcar-cosmetic-remove-superfluous-parenthesis.patch new file mode 100644 index 00000000000000..1256411645d371 --- /dev/null +++ b/patches.renesas/0066-i2c-rcar-cosmetic-remove-superfluous-parenthesis.patch @@ -0,0 +1,32 @@ +From 601aad4e26bd59aa73e171b48373afd46a9f4ae7 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Thu, 12 Sep 2013 14:36:44 +0200 +Subject: i2c: rcar: (cosmetic) remove superfluous parenthesis + +A recent patch added even more superfluous parenthesis to those, which +already were there. Remove them again. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +(cherry picked from commit 14d32f1794fd559e12f27e8b5c57053073bd75aa) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/i2c/busses/i2c-rcar.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c +index 18e033735113..e295f6044dbb 100644 +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -306,7 +306,7 @@ scgd_find: + /* + * keep icccr value + */ +- priv->icccr = (scgd << (cdf_width) | cdf); ++ priv->icccr = scgd << cdf_width | cdf; + + return 0; + } +-- +1.8.5.rc3 + diff --git a/patches.renesas/0067-i2c-rcar-get-clock-rate-only-once-and-simplify-calcu.patch b/patches.renesas/0067-i2c-rcar-get-clock-rate-only-once-and-simplify-calcu.patch new file mode 100644 index 00000000000000..6e0d62c73e31b6 --- /dev/null +++ b/patches.renesas/0067-i2c-rcar-get-clock-rate-only-once-and-simplify-calcu.patch @@ -0,0 +1,68 @@ +From b90b58f17c718c41bba0d00349e05b03c6bbddb9 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Thu, 12 Sep 2013 14:36:45 +0200 +Subject: i2c: rcar: get clock rate only once and simplify calculation + +There is no need to repeatedly query clock frequency, where it is not +expected to change. The complete loop can also trivially be replaced with +a simple division. A further loop below the one, being simplified, could +also be replaced, but that would get more complicated. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +(cherry picked from commit 8d0494037bb2af32a22563d40703c1263fca318d) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/i2c/busses/i2c-rcar.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c +index e295f6044dbb..39e9739f58b2 100644 +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -231,6 +231,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, + u32 round, ick; + u32 scl; + u32 cdf_width; ++ unsigned long rate; + + if (!clkp) { + dev_err(dev, "there is no peripheral_clk\n"); +@@ -264,15 +265,14 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, + * clkp : peripheral_clk + * F[] : integer up-valuation + */ +- for (cdf = 0; cdf < (1 << cdf_width); cdf++) { +- ick = clk_get_rate(clkp) / (1 + cdf); +- if (ick < 20000000) +- goto ick_find; ++ rate = clk_get_rate(clkp); ++ cdf = rate / 20000000; ++ if (cdf >= 1 << cdf_width) { ++ dev_err(dev, "Input clock %lu too high\n", rate); ++ return -EIO; + } +- dev_err(dev, "there is no best CDF\n"); +- return -EIO; ++ ick = rate / (cdf + 1); + +-ick_find: + /* + * it is impossible to calculate large scale + * number on u32. separate it +@@ -290,6 +290,12 @@ ick_find: + * + * Calculation result (= SCL) should be less than + * bus_speed for hardware safety ++ * ++ * We could use something along the lines of ++ * div = ick / (bus_speed + 1) + 1; ++ * scgd = (div - 20 - round + 7) / 8; ++ * scl = ick / (20 + (scgd * 8) + round); ++ * (not fully verified) but that would get pretty involved + */ + for (scgd = 0; scgd < 0x40; scgd++) { + scl = ick / (20 + (scgd * 8) + round); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0068-i2c-rcar-add-Device-Tree-support.patch b/patches.renesas/0068-i2c-rcar-add-Device-Tree-support.patch new file mode 100644 index 00000000000000..ace552c88a8dd0 --- /dev/null +++ b/patches.renesas/0068-i2c-rcar-add-Device-Tree-support.patch @@ -0,0 +1,112 @@ +From 36a5d169ae8bec8914636b95cb8dc2b508ec456c Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Thu, 12 Sep 2013 14:36:46 +0200 +Subject: i2c: rcar: add Device Tree support + +This patch adds Device Tree support to the i2c-rcar driver and respective +documentation. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +(cherry picked from commit 7679c0e19120ee7839adf1f05904cbfcc7a7c2b9) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + Documentation/devicetree/bindings/i2c/i2c-rcar.txt | 23 ++++++++++++++++++++++ + drivers/i2c/busses/i2c-rcar.c | 21 ++++++++++++++++++-- + 2 files changed, 42 insertions(+), 2 deletions(-) + create mode 100644 Documentation/devicetree/bindings/i2c/i2c-rcar.txt + +diff --git a/Documentation/devicetree/bindings/i2c/i2c-rcar.txt b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt +new file mode 100644 +index 000000000000..897cfcd5ce92 +--- /dev/null ++++ b/Documentation/devicetree/bindings/i2c/i2c-rcar.txt +@@ -0,0 +1,23 @@ ++I2C for R-Car platforms ++ ++Required properties: ++- compatible: Must be one of ++ "renesas,i2c-rcar" ++ "renesas,i2c-r8a7778" ++ "renesas,i2c-r8a7779" ++ "renesas,i2c-r8a7790" ++- reg: physical base address of the controller and length of memory mapped ++ region. ++- interrupts: interrupt specifier. ++ ++Optional properties: ++- clock-frequency: desired I2C bus clock frequency in Hz. The absence of this ++ propoerty indicates the default frequency 100 kHz. ++ ++Examples : ++ ++i2c0: i2c@e6500000 { ++ compatible = "renesas,i2c-rcar-h2"; ++ reg = <0 0xe6500000 0 0x428>; ++ interrupts = <0 174 0x4>; ++}; +diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c +index 39e9739f58b2..056323b0666a 100644 +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -33,6 +33,7 @@ + #include <linux/i2c/i2c-rcar.h> + #include <linux/kernel.h> + #include <linux/module.h> ++#include <linux/of_device.h> + #include <linux/platform_device.h> + #include <linux/pm_runtime.h> + #include <linux/slab.h> +@@ -638,6 +639,15 @@ static const struct i2c_algorithm rcar_i2c_algo = { + .functionality = rcar_i2c_func, + }; + ++static const struct of_device_id rcar_i2c_dt_ids[] = { ++ { .compatible = "renesas,i2c-rcar", .data = (void *)I2C_RCAR_H1 }, ++ { .compatible = "renesas,i2c-r8a7778", .data = (void *)I2C_RCAR_H1 }, ++ { .compatible = "renesas,i2c-r8a7779", .data = (void *)I2C_RCAR_H1 }, ++ { .compatible = "renesas,i2c-r8a7790", .data = (void *)I2C_RCAR_H2 }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids); ++ + static int rcar_i2c_probe(struct platform_device *pdev) + { + struct i2c_rcar_platform_data *pdata = pdev->dev.platform_data; +@@ -661,10 +671,15 @@ static int rcar_i2c_probe(struct platform_device *pdev) + } + + bus_speed = 100000; /* default 100 kHz */ +- if (pdata && pdata->bus_speed) ++ ret = of_property_read_u32(dev->of_node, "clock-frequency", &bus_speed); ++ if (ret < 0 && pdata && pdata->bus_speed) + bus_speed = pdata->bus_speed; + +- priv->devtype = platform_get_device_id(pdev)->driver_data; ++ if (pdev->dev.of_node) ++ priv->devtype = (long)of_match_device(rcar_i2c_dt_ids, ++ dev)->data; ++ else ++ priv->devtype = platform_get_device_id(pdev)->driver_data; + + ret = rcar_i2c_clock_calculate(priv, bus_speed, dev); + if (ret < 0) +@@ -684,6 +699,7 @@ static int rcar_i2c_probe(struct platform_device *pdev) + adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + adap->retries = 3; + adap->dev.parent = dev; ++ adap->dev.of_node = dev->of_node; + i2c_set_adapdata(adap, priv); + strlcpy(adap->name, pdev->name, sizeof(adap->name)); + +@@ -731,6 +747,7 @@ static struct platform_driver rcar_i2c_driver = { + .driver = { + .name = "i2c-rcar", + .owner = THIS_MODULE, ++ .of_match_table = rcar_i2c_dt_ids, + }, + .probe = rcar_i2c_probe, + .remove = rcar_i2c_remove, +-- +1.8.5.rc3 + diff --git a/patches.renesas/0069-i2c-rcar-fix-clk_get-error-handling.patch b/patches.renesas/0069-i2c-rcar-fix-clk_get-error-handling.patch new file mode 100644 index 00000000000000..607e4d2bae807b --- /dev/null +++ b/patches.renesas/0069-i2c-rcar-fix-clk_get-error-handling.patch @@ -0,0 +1,36 @@ +From e222e9e3baa43a0ae2544264ae609241c096885d Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Thu, 12 Sep 2013 14:36:47 +0200 +Subject: i2c: rcar: fix clk_get() error handling + +When clk_get() fails, it returns an error code, not a NULL. This patch +fixes such an error handling bug. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +(cherry picked from commit 330c824a49cd49dd7e61c1e397fa4e7380ba2c68) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/i2c/busses/i2c-rcar.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c +index 056323b0666a..e5e79a031827 100644 +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -234,9 +234,9 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, + u32 cdf_width; + unsigned long rate; + +- if (!clkp) { +- dev_err(dev, "there is no peripheral_clk\n"); +- return -EIO; ++ if (IS_ERR(clkp)) { ++ dev_err(dev, "couldn't get clock\n"); ++ return PTR_ERR(clkp); + } + + switch (priv->devtype) { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0070-i2c-rcar-use-per-device-clock.patch b/patches.renesas/0070-i2c-rcar-use-per-device-clock.patch new file mode 100644 index 00000000000000..41c18d20af01e6 --- /dev/null +++ b/patches.renesas/0070-i2c-rcar-use-per-device-clock.patch @@ -0,0 +1,36 @@ +From 7ba214a56be110e5274f02cd03dd7630bbfaef8b Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Thu, 12 Sep 2013 14:36:48 +0200 +Subject: i2c: rcar: use per-device clock + +Using the same clock for all device instances is non-portable and obtaining +clock references by an ID without using a device pointer is discouraged. +This is also not needed, because on platforms, where this driver is used, +suitable clocks are available for the I2C controllers, that are children of +the peripheral clock and just pass its rate 1-to-1 to controllers. This +patch switches the driver to obtain references to correct clocks. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +(cherry picked from commit 991e7ecf1f1a2e2fa76387066342a5a6c4a28a76) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/i2c/busses/i2c-rcar.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c +index e5e79a031827..37bd2371ddf5 100644 +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -227,7 +227,7 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, + u32 bus_speed, + struct device *dev) + { +- struct clk *clkp = clk_get(NULL, "peripheral_clk"); ++ struct clk *clkp = clk_get(dev, NULL); + u32 scgd, cdf; + u32 round, ick; + u32 scl; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0071-i2c-rcar-fixup-rcar-type-naming.patch b/patches.renesas/0071-i2c-rcar-fixup-rcar-type-naming.patch new file mode 100644 index 00000000000000..4367ea20dd7589 --- /dev/null +++ b/patches.renesas/0071-i2c-rcar-fixup-rcar-type-naming.patch @@ -0,0 +1,82 @@ +From 05a24ff165f09af7687d67f21a8aa51de0814650 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Mon, 21 Oct 2013 01:04:32 -0700 +Subject: i2c: rcar: fixup rcar type naming + +b720423a2627f045133bec39a31fe2bc0dab86f3 +(i2c: rcar: add rcar-H2 support) +added R-Car H2 support on i2c-rcar. + +The R-Car I2C type is based on SoC generation +(Gen1 = E1/M1/H1, Gen2 = E2/M2/H2), +but added naming was H1/H2 instead of Gen1/Gen2. +Gen1/Gen2 is better naming on this driver. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Acked-by: Simon Horman <horms+renesas@verge.net.au> +Signed-off-by: Wolfram Sang <wsa@the-dreams.de> +(cherry picked from commit 043a3f113ce41e3e6fdbb49551df75e82e8c4ae7) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/i2c/busses/i2c-rcar.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-rcar.c b/drivers/i2c/busses/i2c-rcar.c +index 37bd2371ddf5..3e86e4ad9639 100644 +--- a/drivers/i2c/busses/i2c-rcar.c ++++ b/drivers/i2c/busses/i2c-rcar.c +@@ -103,8 +103,8 @@ enum { + #define ID_NACK (1 << 4) + + enum rcar_i2c_type { +- I2C_RCAR_H1, +- I2C_RCAR_H2, ++ I2C_RCAR_GEN1, ++ I2C_RCAR_GEN2, + }; + + struct rcar_i2c_priv { +@@ -240,10 +240,10 @@ static int rcar_i2c_clock_calculate(struct rcar_i2c_priv *priv, + } + + switch (priv->devtype) { +- case I2C_RCAR_H1: ++ case I2C_RCAR_GEN1: + cdf_width = 2; + break; +- case I2C_RCAR_H2: ++ case I2C_RCAR_GEN2: + cdf_width = 3; + break; + default: +@@ -640,10 +640,10 @@ static const struct i2c_algorithm rcar_i2c_algo = { + }; + + static const struct of_device_id rcar_i2c_dt_ids[] = { +- { .compatible = "renesas,i2c-rcar", .data = (void *)I2C_RCAR_H1 }, +- { .compatible = "renesas,i2c-r8a7778", .data = (void *)I2C_RCAR_H1 }, +- { .compatible = "renesas,i2c-r8a7779", .data = (void *)I2C_RCAR_H1 }, +- { .compatible = "renesas,i2c-r8a7790", .data = (void *)I2C_RCAR_H2 }, ++ { .compatible = "renesas,i2c-rcar", .data = (void *)I2C_RCAR_GEN1 }, ++ { .compatible = "renesas,i2c-r8a7778", .data = (void *)I2C_RCAR_GEN1 }, ++ { .compatible = "renesas,i2c-r8a7779", .data = (void *)I2C_RCAR_GEN1 }, ++ { .compatible = "renesas,i2c-r8a7790", .data = (void *)I2C_RCAR_GEN2 }, + {}, + }; + MODULE_DEVICE_TABLE(of, rcar_i2c_dt_ids); +@@ -736,9 +736,9 @@ static int rcar_i2c_remove(struct platform_device *pdev) + } + + static struct platform_device_id rcar_i2c_id_table[] = { +- { "i2c-rcar", I2C_RCAR_H1 }, +- { "i2c-rcar_h1", I2C_RCAR_H1 }, +- { "i2c-rcar_h2", I2C_RCAR_H2 }, ++ { "i2c-rcar", I2C_RCAR_GEN1 }, ++ { "i2c-rcar_gen1", I2C_RCAR_GEN1 }, ++ { "i2c-rcar_gen2", I2C_RCAR_GEN2 }, + {}, + }; + MODULE_DEVICE_TABLE(platform, rcar_i2c_id_table); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0072-media-sh_mobile_ceu_camera-remove-deprecated-IRQF_DI.patch b/patches.renesas/0072-media-sh_mobile_ceu_camera-remove-deprecated-IRQF_DI.patch new file mode 100644 index 00000000000000..48b112e7edbf7c --- /dev/null +++ b/patches.renesas/0072-media-sh_mobile_ceu_camera-remove-deprecated-IRQF_DI.patch @@ -0,0 +1,33 @@ +From 4cfedc8dc9a067c2a08497f0c91b9aa4864a98bc Mon Sep 17 00:00:00 2001 +From: Michael Opdenacker <michael.opdenacker@free-electrons.com> +Date: Sun, 13 Oct 2013 03:01:46 -0300 +Subject: [media] sh_mobile_ceu_camera: remove deprecated IRQF_DISABLED + +This patch proposes to remove the use of the IRQF_DISABLED flag +It's a NOOP since 2.6.35 and it will be removed one day. + +Signed-off-by: Michael Opdenacker <michael.opdenacker@free-electrons.com> +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> +(cherry picked from commit c656ead48fa5ab4af973f8135400b1695184ef31) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +index dc5ce6c1b791..55f80bf0e3c8 100644 +--- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c ++++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +@@ -1791,7 +1791,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev) + + /* request irq */ + err = devm_request_irq(&pdev->dev, pcdev->irq, sh_mobile_ceu_irq, +- IRQF_DISABLED, dev_name(&pdev->dev), pcdev); ++ 0, dev_name(&pdev->dev), pcdev); + if (err) { + dev_err(&pdev->dev, "Unable to register CEU interrupt.\n"); + goto exit_release_mem; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0073-media-media-rcar_vin-Add-preliminary-r8a7790-support.patch b/patches.renesas/0073-media-media-rcar_vin-Add-preliminary-r8a7790-support.patch new file mode 100644 index 00000000000000..c172196892e09a --- /dev/null +++ b/patches.renesas/0073-media-media-rcar_vin-Add-preliminary-r8a7790-support.patch @@ -0,0 +1,47 @@ +From 5ab3ae37de6d787b200f04931c054b998d578a1d Mon Sep 17 00:00:00 2001 +From: Valentine Barshak <valentine.barshak@cogentembedded.com> +Date: Fri, 4 Oct 2013 11:20:52 -0300 +Subject: [media] media: rcar_vin: Add preliminary r8a7790 support + +Signed-off-by: Valentine Barshak <valentine.barshak@cogentembedded.com> +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> +(cherry picked from commit ca0c9f17f3737f4857ec0406a75b26b84b2e8c16) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/media/platform/soc_camera/rcar_vin.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c +index d02a7e0b773f..b21f777f55e7 100644 +--- a/drivers/media/platform/soc_camera/rcar_vin.c ++++ b/drivers/media/platform/soc_camera/rcar_vin.c +@@ -105,6 +105,7 @@ + #define VIN_MAX_HEIGHT 2048 + + enum chip_id { ++ RCAR_H2, + RCAR_H1, + RCAR_M1, + RCAR_E1, +@@ -300,7 +301,8 @@ static int rcar_vin_setup(struct rcar_vin_priv *priv) + dmr = 0; + break; + case V4L2_PIX_FMT_RGB32: +- if (priv->chip == RCAR_H1 || priv->chip == RCAR_E1) { ++ if (priv->chip == RCAR_H2 || priv->chip == RCAR_H1 || ++ priv->chip == RCAR_E1) { + dmr = VNDMR_EXRGB; + break; + } +@@ -1381,6 +1383,7 @@ static struct soc_camera_host_ops rcar_vin_host_ops = { + }; + + static struct platform_device_id rcar_vin_id_table[] = { ++ { "r8a7790-vin", RCAR_H2 }, + { "r8a7779-vin", RCAR_H1 }, + { "r8a7778-vin", RCAR_M1 }, + { "uPD35004-vin", RCAR_E1 }, +-- +1.8.5.rc3 + diff --git a/patches.renesas/0074-media-platform-drivers-Fix-build-on-frv-arch.patch b/patches.renesas/0074-media-platform-drivers-Fix-build-on-frv-arch.patch new file mode 100644 index 00000000000000..0f438d56770c4d --- /dev/null +++ b/patches.renesas/0074-media-platform-drivers-Fix-build-on-frv-arch.patch @@ -0,0 +1,36 @@ +From 2e28b7147baf1454779e3b63a1389e5d98a441b3 Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab <m.chehab@samsung.com> +Date: Fri, 1 Nov 2013 13:59:04 -0300 +Subject: [media] platform drivers: Fix build on frv arch + +On frv, the following errors happen: + drivers/media/platform/soc_camera/rcar_vin.c: In function 'rcar_vin_setup': + drivers/media/platform/soc_camera/rcar_vin.c:284:3: error: implicit declaration of function 'iowrite32' [-Werror=implicit-function-declaration] + drivers/media/platform/soc_camera/rcar_vin.c: In function 'rcar_vin_request_capture_stop': + drivers/media/platform/soc_camera/rcar_vin.c:353:2: error: implicit declaration of function 'ioread32' [-Werror=implicit-function-declaration] +This is because this driver forgot to include linux/io.h. + +Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> +Reviewed-by: Hans Verkuil <hans.verkuil@cisco.com> +Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com> +(cherry picked from commit 3cdcf7369cdb3406c61090e453b78cb8d4882ef8) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/media/platform/soc_camera/rcar_vin.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c +index b21f777f55e7..6866bb4fbebc 100644 +--- a/drivers/media/platform/soc_camera/rcar_vin.c ++++ b/drivers/media/platform/soc_camera/rcar_vin.c +@@ -16,6 +16,7 @@ + + #include <linux/delay.h> + #include <linux/interrupt.h> ++#include <linux/io.h> + #include <linux/kernel.h> + #include <linux/module.h> + #include <linux/platform_data/camera-rcar.h> +-- +1.8.5.rc3 + diff --git a/patches.renesas/0075-mmc-sh_mmcif-Move-away-from-using-deprecated-APIs.patch b/patches.renesas/0075-mmc-sh_mmcif-Move-away-from-using-deprecated-APIs.patch new file mode 100644 index 00000000000000..20bba2501555e4 --- /dev/null +++ b/patches.renesas/0075-mmc-sh_mmcif-Move-away-from-using-deprecated-APIs.patch @@ -0,0 +1,50 @@ +From f14dab096174a8c2b4605d75779c2afbaf70c774 Mon Sep 17 00:00:00 2001 +From: Ulf Hansson <ulf.hansson@linaro.org> +Date: Thu, 26 Sep 2013 10:19:09 +0200 +Subject: mmc: sh_mmcif: Move away from using deprecated APIs + +Suspend and resume of cards are being handled from the protocol layer +and consequently the mmc_suspend|resume_host APIs are deprecated. + +This means we can simplify the suspend|resume callbacks by removing the +use of the deprecated APIs. + +Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> +Signed-off-by: Chris Ball <cjb@laptop.org> +(cherry picked from commit cb3ca1aed991cd67ae76aec682e63633a7bead5b) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/mmc/host/sh_mmcif.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c +index 36629a024aa1..6bffebe6f57a 100644 +--- a/drivers/mmc/host/sh_mmcif.c ++++ b/drivers/mmc/host/sh_mmcif.c +@@ -1542,19 +1542,15 @@ static int sh_mmcif_remove(struct platform_device *pdev) + static int sh_mmcif_suspend(struct device *dev) + { + struct sh_mmcif_host *host = dev_get_drvdata(dev); +- int ret = mmc_suspend_host(host->mmc); + +- if (!ret) +- sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); ++ sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); + +- return ret; ++ return 0; + } + + static int sh_mmcif_resume(struct device *dev) + { +- struct sh_mmcif_host *host = dev_get_drvdata(dev); +- +- return mmc_resume_host(host->mmc); ++ return 0; + } + #else + #define sh_mmcif_suspend NULL +-- +1.8.5.rc3 + diff --git a/patches.renesas/0076-mmc-sh_mmcif-Convert-to-PM-macros-when-defining-dev_.patch b/patches.renesas/0076-mmc-sh_mmcif-Convert-to-PM-macros-when-defining-dev_.patch new file mode 100644 index 00000000000000..424d41d325368e --- /dev/null +++ b/patches.renesas/0076-mmc-sh_mmcif-Convert-to-PM-macros-when-defining-dev_.patch @@ -0,0 +1,55 @@ +From 84d535fe4aeaee78f81f2e8a8e5235185431c247 Mon Sep 17 00:00:00 2001 +From: Ulf Hansson <ulf.hansson@linaro.org> +Date: Tue, 1 Oct 2013 14:01:46 +0200 +Subject: mmc: sh_mmcif: Convert to PM macros when defining dev_pm_ops + +Use SET_SYSTEM_SLEEP_PM_OPS to simplify code. + +Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> +Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Signed-off-by: Chris Ball <cjb@laptop.org> +(cherry picked from commit 51129f31d2e7abcfb4cf35f703a42d1524c45dfa) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/mmc/host/sh_mmcif.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c +index 6bffebe6f57a..32bc4121c965 100644 +--- a/drivers/mmc/host/sh_mmcif.c ++++ b/drivers/mmc/host/sh_mmcif.c +@@ -1538,7 +1538,7 @@ static int sh_mmcif_remove(struct platform_device *pdev) + return 0; + } + +-#ifdef CONFIG_PM ++#ifdef CONFIG_PM_SLEEP + static int sh_mmcif_suspend(struct device *dev) + { + struct sh_mmcif_host *host = dev_get_drvdata(dev); +@@ -1552,10 +1552,7 @@ static int sh_mmcif_resume(struct device *dev) + { + return 0; + } +-#else +-#define sh_mmcif_suspend NULL +-#define sh_mmcif_resume NULL +-#endif /* CONFIG_PM */ ++#endif + + static const struct of_device_id mmcif_of_match[] = { + { .compatible = "renesas,sh-mmcif" }, +@@ -1564,8 +1561,7 @@ static const struct of_device_id mmcif_of_match[] = { + MODULE_DEVICE_TABLE(of, mmcif_of_match); + + static const struct dev_pm_ops sh_mmcif_dev_pm_ops = { +- .suspend = sh_mmcif_suspend, +- .resume = sh_mmcif_resume, ++ SET_SYSTEM_SLEEP_PM_OPS(sh_mmcif_suspend, sh_mmcif_resume) + }; + + static struct platform_driver sh_mmcif_driver = { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0077-mmc-sh_mmcif-Convert-to-clk_prepare-unprepare.patch b/patches.renesas/0077-mmc-sh_mmcif-Convert-to-clk_prepare-unprepare.patch new file mode 100644 index 00000000000000..cd6c3d0589fbde --- /dev/null +++ b/patches.renesas/0077-mmc-sh_mmcif-Convert-to-clk_prepare-unprepare.patch @@ -0,0 +1,79 @@ +From ab55963f97051ba4a7ae0e6a6b7cc0e33a027d96 Mon Sep 17 00:00:00 2001 +From: Ulf Hansson <ulf.hansson@linaro.org> +Date: Tue, 1 Oct 2013 14:56:57 +0200 +Subject: mmc: sh_mmcif: Convert to clk_prepare|unprepare + +Previously only clk_enable|disable were being used. Adapt properly +to the clock API, by also using clk_prepare|unprepare. + +Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> +Acked-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Signed-off-by: Chris Ball <cjb@laptop.org> +(cherry picked from commit ac0a2e98927e4797ae716b7327c3a9c85ba5431c) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/mmc/host/sh_mmcif.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c +index 32bc4121c965..d032b080ac4d 100644 +--- a/drivers/mmc/host/sh_mmcif.c ++++ b/drivers/mmc/host/sh_mmcif.c +@@ -964,7 +964,7 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq) + + static int sh_mmcif_clk_update(struct sh_mmcif_host *host) + { +- int ret = clk_enable(host->hclk); ++ int ret = clk_prepare_enable(host->hclk); + + if (!ret) { + host->clk = clk_get_rate(host->hclk); +@@ -1018,7 +1018,7 @@ static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + } + if (host->power) { + pm_runtime_put_sync(&host->pd->dev); +- clk_disable(host->hclk); ++ clk_disable_unprepare(host->hclk); + host->power = false; + if (ios->power_mode == MMC_POWER_OFF) + sh_mmcif_set_power(host, ios); +@@ -1466,7 +1466,7 @@ static int sh_mmcif_probe(struct platform_device *pdev) + + mutex_init(&host->thread_lock); + +- clk_disable(host->hclk); ++ clk_disable_unprepare(host->hclk); + ret = mmc_add_host(mmc); + if (ret < 0) + goto emmcaddh; +@@ -1487,7 +1487,7 @@ ereqirq1: + ereqirq0: + pm_runtime_suspend(&pdev->dev); + eresume: +- clk_disable(host->hclk); ++ clk_disable_unprepare(host->hclk); + eclkupdate: + clk_put(host->hclk); + eclkget: +@@ -1505,7 +1505,7 @@ static int sh_mmcif_remove(struct platform_device *pdev) + int irq[2]; + + host->dying = true; +- clk_enable(host->hclk); ++ clk_prepare_enable(host->hclk); + pm_runtime_get_sync(&pdev->dev); + + dev_pm_qos_hide_latency_limit(&pdev->dev); +@@ -1530,7 +1530,7 @@ static int sh_mmcif_remove(struct platform_device *pdev) + if (irq[1] >= 0) + free_irq(irq[1], host); + +- clk_disable(host->hclk); ++ clk_disable_unprepare(host->hclk); + mmc_free_host(host->mmc); + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0078-mmc-tmio-Move-away-from-using-deprecated-APIs.patch b/patches.renesas/0078-mmc-tmio-Move-away-from-using-deprecated-APIs.patch new file mode 100644 index 00000000000000..db6a904585465c --- /dev/null +++ b/patches.renesas/0078-mmc-tmio-Move-away-from-using-deprecated-APIs.patch @@ -0,0 +1,52 @@ +From 9177c23cb80dd6f507a0b73e3f5f1141e7892b5e Mon Sep 17 00:00:00 2001 +From: Ulf Hansson <ulf.hansson@linaro.org> +Date: Thu, 26 Sep 2013 10:36:06 +0200 +Subject: mmc: tmio: Move away from using deprecated APIs + +Suspend and resume of cards are being handled from the protocol layer +and consequently the mmc_suspend|resume_host APIs are deprecated. + +This means we can simplify the suspend|resume callbacks by removing the +use of the deprecated APIs. + +Cc: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Cc: Ian Molton <ian@mnementh.co.uk> +Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org> +Signed-off-by: Chris Ball <cjb@laptop.org> +(cherry picked from commit d62c9577f950b1ce9b53200542c251ba8dfff344) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/mmc/host/tmio_mmc_pio.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c +index b3802256f954..f3b2d8ca1eca 100644 +--- a/drivers/mmc/host/tmio_mmc_pio.c ++++ b/drivers/mmc/host/tmio_mmc_pio.c +@@ -1145,12 +1145,9 @@ int tmio_mmc_host_suspend(struct device *dev) + { + struct mmc_host *mmc = dev_get_drvdata(dev); + struct tmio_mmc_host *host = mmc_priv(mmc); +- int ret = mmc_suspend_host(mmc); + +- if (!ret) +- tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL); +- +- return ret; ++ tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL); ++ return 0; + } + EXPORT_SYMBOL(tmio_mmc_host_suspend); + +@@ -1163,7 +1160,7 @@ int tmio_mmc_host_resume(struct device *dev) + + /* The MMC core will perform the complete set up */ + host->resuming = true; +- return mmc_resume_host(mmc); ++ return 0; + } + EXPORT_SYMBOL(tmio_mmc_host_resume); + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0079-sh-pfc-r8a7778-Add-SRU-SSI-pin-support.patch b/patches.renesas/0079-sh-pfc-r8a7778-Add-SRU-SSI-pin-support.patch new file mode 100644 index 00000000000000..ba9d3b4b5e45a4 --- /dev/null +++ b/patches.renesas/0079-sh-pfc-r8a7778-Add-SRU-SSI-pin-support.patch @@ -0,0 +1,201 @@ +From 77df5350f1ea142dde1b4f8cdea3f30d86a3b18b Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Mon, 26 Aug 2013 01:51:22 -0700 +Subject: sh-pfc: r8a7778: Add SRU/SSI pin support + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 3ad8219a50eab201abf89b25d7797d6695b73e4e) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/pinctrl/sh-pfc/pfc-r8a7778.c | 125 +++++++++++++++++++++++++++++++++++ + 1 file changed, 125 insertions(+) + +diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7778.c b/drivers/pinctrl/sh-pfc/pfc-r8a7778.c +index 428d2a6857ef..20b1d0d671a3 100644 +--- a/drivers/pinctrl/sh-pfc/pfc-r8a7778.c ++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7778.c +@@ -1288,6 +1288,22 @@ static struct sh_pfc_pin pinmux_pins[] = { + arg5##_MARK, arg6##_MARK, \ + arg7##_MARK, arg8##_MARK, } + ++/* - AUDIO macro -------------------------------------------------------------*/ ++#define AUDIO_PFC_PIN(name, pin) SH_PFC_PINS(name, pin) ++#define AUDIO_PFC_DAT(name, pin) SH_PFC_MUX1(name, pin) ++ ++/* - AUDIO clock -------------------------------------------------------------*/ ++AUDIO_PFC_PIN(audio_clk_a, RCAR_GP_PIN(2, 22)); ++AUDIO_PFC_DAT(audio_clk_a, AUDIO_CLKA); ++AUDIO_PFC_PIN(audio_clk_b, RCAR_GP_PIN(2, 23)); ++AUDIO_PFC_DAT(audio_clk_b, AUDIO_CLKB); ++AUDIO_PFC_PIN(audio_clk_c, RCAR_GP_PIN(2, 7)); ++AUDIO_PFC_DAT(audio_clk_c, AUDIO_CLKC); ++AUDIO_PFC_PIN(audio_clkout_a, RCAR_GP_PIN(2, 16)); ++AUDIO_PFC_DAT(audio_clkout_a, AUDIO_CLKOUT_A); ++AUDIO_PFC_PIN(audio_clkout_b, RCAR_GP_PIN(1, 16)); ++AUDIO_PFC_DAT(audio_clkout_b, AUDIO_CLKOUT_B); ++ + /* - Ether ------------------------------------------------------------------ */ + SH_PFC_PINS(ether_rmii, RCAR_GP_PIN(4, 10), RCAR_GP_PIN(4, 11), + RCAR_GP_PIN(4, 13), RCAR_GP_PIN(4, 9), +@@ -1577,6 +1593,59 @@ SDHI_PFC_WPPN(sdhi2_wp_a, SD2_WP_A); + SDHI_PFC_PINS(sdhi2_wp_b, RCAR_GP_PIN(3, 28)); + SDHI_PFC_WPPN(sdhi2_wp_b, SD2_WP_B); + ++/* - SSI macro -------------------------------------------------------------- */ ++#define SSI_PFC_PINS(name, args...) SH_PFC_PINS(name, args) ++#define SSI_PFC_CTRL(name, sck, ws) SH_PFC_MUX2(name, sck, ws) ++#define SSI_PFC_DATA(name, d) SH_PFC_MUX1(name, d) ++ ++/* - SSI 0/1/2 -------------------------------------------------------------- */ ++SSI_PFC_PINS(ssi012_ctrl, RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7)); ++SSI_PFC_CTRL(ssi012_ctrl, SSI_SCK012, SSI_WS012); ++SSI_PFC_PINS(ssi0_data, RCAR_GP_PIN(3, 10)); ++SSI_PFC_DATA(ssi0_data, SSI_SDATA0); ++SSI_PFC_PINS(ssi1_a_ctrl, RCAR_GP_PIN(2, 20), RCAR_GP_PIN(2, 21)); ++SSI_PFC_CTRL(ssi1_a_ctrl, SSI_SCK1_A, SSI_WS1_A); ++SSI_PFC_PINS(ssi1_b_ctrl, PIN_NUMBER(3, 20), RCAR_GP_PIN(1, 3)); ++SSI_PFC_CTRL(ssi1_b_ctrl, SSI_SCK1_B, SSI_WS1_B); ++SSI_PFC_PINS(ssi1_data, RCAR_GP_PIN(3, 9)); ++SSI_PFC_DATA(ssi1_data, SSI_SDATA1); ++SSI_PFC_PINS(ssi2_a_ctrl, RCAR_GP_PIN(2, 26), RCAR_GP_PIN(3, 4)); ++SSI_PFC_CTRL(ssi2_a_ctrl, SSI_SCK2_A, SSI_WS2_A); ++SSI_PFC_PINS(ssi2_b_ctrl, RCAR_GP_PIN(2, 6), RCAR_GP_PIN(2, 17)); ++SSI_PFC_CTRL(ssi2_b_ctrl, SSI_SCK2_B, SSI_WS2_B); ++SSI_PFC_PINS(ssi2_data, RCAR_GP_PIN(3, 8)); ++SSI_PFC_DATA(ssi2_data, SSI_SDATA2); ++ ++/* - SSI 3/4 ---------------------------------------------------------------- */ ++SSI_PFC_PINS(ssi34_ctrl, RCAR_GP_PIN(3, 2), RCAR_GP_PIN(3, 3)); ++SSI_PFC_CTRL(ssi34_ctrl, SSI_SCK34, SSI_WS34); ++SSI_PFC_PINS(ssi3_data, RCAR_GP_PIN(3, 5)); ++SSI_PFC_DATA(ssi3_data, SSI_SDATA3); ++SSI_PFC_PINS(ssi4_ctrl, RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 23)); ++SSI_PFC_CTRL(ssi4_ctrl, SSI_SCK4, SSI_WS4); ++SSI_PFC_PINS(ssi4_data, RCAR_GP_PIN(3, 4)); ++SSI_PFC_DATA(ssi4_data, SSI_SDATA4); ++ ++/* - SSI 5 ------------------------------------------------------------------ */ ++SSI_PFC_PINS(ssi5_ctrl, RCAR_GP_PIN(2, 31), RCAR_GP_PIN(3, 0)); ++SSI_PFC_CTRL(ssi5_ctrl, SSI_SCK5, SSI_WS5); ++SSI_PFC_PINS(ssi5_data, RCAR_GP_PIN(3, 1)); ++SSI_PFC_DATA(ssi5_data, SSI_SDATA5); ++ ++/* - SSI 6 ------------------------------------------------------------------ */ ++SSI_PFC_PINS(ssi6_ctrl, RCAR_GP_PIN(2, 28), RCAR_GP_PIN(2, 29)); ++SSI_PFC_CTRL(ssi6_ctrl, SSI_SCK6, SSI_WS6); ++SSI_PFC_PINS(ssi6_data, RCAR_GP_PIN(2, 30)); ++SSI_PFC_DATA(ssi6_data, SSI_SDATA6); ++ ++/* - SSI 7/8 --------------------------------------------------------------- */ ++SSI_PFC_PINS(ssi78_ctrl, RCAR_GP_PIN(2, 24), RCAR_GP_PIN(2, 25)); ++SSI_PFC_CTRL(ssi78_ctrl, SSI_SCK78, SSI_WS78); ++SSI_PFC_PINS(ssi7_data, RCAR_GP_PIN(2, 27)); ++SSI_PFC_DATA(ssi7_data, SSI_SDATA7); ++SSI_PFC_PINS(ssi8_data, RCAR_GP_PIN(2, 26)); ++SSI_PFC_DATA(ssi8_data, SSI_SDATA8); ++ + /* - USB0 ------------------------------------------------------------------- */ + SH_PFC_PINS(usb0, RCAR_GP_PIN(0, 1)); + SH_PFC_MUX1(usb0, PENC0); +@@ -1624,6 +1693,11 @@ VIN_PFC_PINS(vin1_sync, RCAR_GP_PIN(3, 21), RCAR_GP_PIN(3, 22)); + VIN_PFC_SYNC(vin1_sync, VI1_HSYNC, VI1_VSYNC); + + static const struct sh_pfc_pin_group pinmux_groups[] = { ++ SH_PFC_PIN_GROUP(audio_clk_a), ++ SH_PFC_PIN_GROUP(audio_clk_b), ++ SH_PFC_PIN_GROUP(audio_clk_c), ++ SH_PFC_PIN_GROUP(audio_clkout_a), ++ SH_PFC_PIN_GROUP(audio_clkout_b), + SH_PFC_PIN_GROUP(ether_rmii), + SH_PFC_PIN_GROUP(ether_link), + SH_PFC_PIN_GROUP(ether_magic), +@@ -1713,6 +1787,25 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(sdhi2_data4_b), + SH_PFC_PIN_GROUP(sdhi2_wp_a), + SH_PFC_PIN_GROUP(sdhi2_wp_b), ++ SH_PFC_PIN_GROUP(ssi012_ctrl), ++ SH_PFC_PIN_GROUP(ssi0_data), ++ SH_PFC_PIN_GROUP(ssi1_a_ctrl), ++ SH_PFC_PIN_GROUP(ssi1_b_ctrl), ++ SH_PFC_PIN_GROUP(ssi1_data), ++ SH_PFC_PIN_GROUP(ssi2_a_ctrl), ++ SH_PFC_PIN_GROUP(ssi2_b_ctrl), ++ SH_PFC_PIN_GROUP(ssi2_data), ++ SH_PFC_PIN_GROUP(ssi34_ctrl), ++ SH_PFC_PIN_GROUP(ssi3_data), ++ SH_PFC_PIN_GROUP(ssi4_ctrl), ++ SH_PFC_PIN_GROUP(ssi4_data), ++ SH_PFC_PIN_GROUP(ssi5_ctrl), ++ SH_PFC_PIN_GROUP(ssi5_data), ++ SH_PFC_PIN_GROUP(ssi6_ctrl), ++ SH_PFC_PIN_GROUP(ssi6_data), ++ SH_PFC_PIN_GROUP(ssi78_ctrl), ++ SH_PFC_PIN_GROUP(ssi7_data), ++ SH_PFC_PIN_GROUP(ssi8_data), + SH_PFC_PIN_GROUP(usb0), + SH_PFC_PIN_GROUP(usb0_ovc), + SH_PFC_PIN_GROUP(usb1), +@@ -1725,6 +1818,14 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(vin1_sync), + }; + ++static const char * const audio_clk_groups[] = { ++ "audio_clk_a", ++ "audio_clk_b", ++ "audio_clk_c", ++ "audio_clkout_a", ++ "audio_clkout_b", ++}; ++ + static const char * const ether_groups[] = { + "ether_rmii", + "ether_link", +@@ -1875,6 +1976,28 @@ static const char * const sdhi2_groups[] = { + "sdhi2_wp_b", + }; + ++static const char * const ssi_groups[] = { ++ "ssi012_ctrl", ++ "ssi0_data", ++ "ssi1_a_ctrl", ++ "ssi1_b_ctrl", ++ "ssi1_data", ++ "ssi2_a_ctrl", ++ "ssi2_b_ctrl", ++ "ssi2_data", ++ "ssi34_ctrl", ++ "ssi3_data", ++ "ssi4_ctrl", ++ "ssi4_data", ++ "ssi5_ctrl", ++ "ssi5_data", ++ "ssi6_ctrl", ++ "ssi6_data", ++ "ssi78_ctrl", ++ "ssi7_data", ++ "ssi8_data", ++}; ++ + static const char * const usb0_groups[] = { + "usb0", + "usb0_ovc", +@@ -1898,6 +2021,7 @@ static const char * const vin1_groups[] = { + }; + + static const struct sh_pfc_function pinmux_functions[] = { ++ SH_PFC_FUNCTION(audio_clk), + SH_PFC_FUNCTION(ether), + SH_PFC_FUNCTION(hscif0), + SH_PFC_FUNCTION(hscif1), +@@ -1918,6 +2042,7 @@ static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(sdhi0), + SH_PFC_FUNCTION(sdhi1), + SH_PFC_FUNCTION(sdhi2), ++ SH_PFC_FUNCTION(ssi), + SH_PFC_FUNCTION(usb0), + SH_PFC_FUNCTION(usb1), + SH_PFC_FUNCTION(vin0), +-- +1.8.5.rc3 + diff --git a/patches.renesas/0080-sh-pfc-r8a7790-Add-I2C-pin-groups-and-functions.patch b/patches.renesas/0080-sh-pfc-r8a7790-Add-I2C-pin-groups-and-functions.patch new file mode 100644 index 00000000000000..be2401735bba51 --- /dev/null +++ b/patches.renesas/0080-sh-pfc-r8a7790-Add-I2C-pin-groups-and-functions.patch @@ -0,0 +1,132 @@ +From 7a5559da1718ed980540673f92f714bbbdc6bd9d Mon Sep 17 00:00:00 2001 +From: Ulrich Hecht <ulrich.hecht@gmail.com> +Date: Fri, 30 Aug 2013 14:37:41 +0200 +Subject: sh-pfc: r8a7790: Add I2C pin groups and functions + +Adds pinmux for i2c bus 1 and 2. (Pins for 0 and 3 are not multiplexed.) + +Signed-off-by: Ulrich Hecht <ulrich.hecht@gmail.com> +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 70702bfc13c4f96f2f05d4ce2eb110cd1735fef5) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/pinctrl/sh-pfc/pfc-r8a7790.c | 82 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 82 insertions(+) + +diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c +index 64fcc00693b5..5c2657bcc3a4 100644 +--- a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c ++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c +@@ -1990,6 +1990,64 @@ static const unsigned int hscif1_ctrl_b_pins[] = { + static const unsigned int hscif1_ctrl_b_mux[] = { + HRTS1_N_B_MARK, HCTS1_N_B_MARK, + }; ++/* - I2C1 ------------------------------------------------------------------- */ ++static const unsigned int i2c1_pins[] = { ++ /* SCL, SDA */ ++ RCAR_GP_PIN(1, 16), RCAR_GP_PIN(1, 17), ++}; ++static const unsigned int i2c1_mux[] = { ++ I2C1_SCL_MARK, I2C1_SDA_MARK, ++}; ++static const unsigned int i2c1_b_pins[] = { ++ /* SCL, SDA */ ++ RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 7), ++}; ++static const unsigned int i2c1_b_mux[] = { ++ I2C1_SCL_B_MARK, I2C1_SDA_B_MARK, ++}; ++static const unsigned int i2c1_c_pins[] = { ++ /* SCL, SDA */ ++ RCAR_GP_PIN(4, 30), RCAR_GP_PIN(4, 27), ++}; ++static const unsigned int i2c1_c_mux[] = { ++ I2C1_SCL_C_MARK, I2C1_SDA_C_MARK, ++}; ++/* - I2C2 ------------------------------------------------------------------- */ ++static const unsigned int i2c2_pins[] = { ++ /* SCL, SDA */ ++ RCAR_GP_PIN(5, 5), RCAR_GP_PIN(5, 6), ++}; ++static const unsigned int i2c2_mux[] = { ++ I2C2_SCL_MARK, I2C2_SDA_MARK, ++}; ++static const unsigned int i2c2_b_pins[] = { ++ /* SCL, SDA */ ++ RCAR_GP_PIN(4, 0), RCAR_GP_PIN(4, 1), ++}; ++static const unsigned int i2c2_b_mux[] = { ++ I2C2_SCL_B_MARK, I2C2_SDA_B_MARK, ++}; ++static const unsigned int i2c2_c_pins[] = { ++ /* SCL, SDA */ ++ RCAR_GP_PIN(0, 6), RCAR_GP_PIN(0, 7), ++}; ++static const unsigned int i2c2_c_mux[] = { ++ I2C2_SCL_C_MARK, I2C2_SDA_C_MARK, ++}; ++static const unsigned int i2c2_d_pins[] = { ++ /* SCL, SDA */ ++ RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 15), ++}; ++static const unsigned int i2c2_d_mux[] = { ++ I2C2_SCL_D_MARK, I2C2_SDA_D_MARK, ++}; ++static const unsigned int i2c2_e_pins[] = { ++ /* SCL, SDA */ ++ RCAR_GP_PIN(2, 18), RCAR_GP_PIN(2, 19), ++}; ++static const unsigned int i2c2_e_mux[] = { ++ I2C2_SCL_E_MARK, I2C2_SDA_E_MARK, ++}; + /* - INTC ------------------------------------------------------------------- */ + static const unsigned int intc_irq0_pins[] = { + /* IRQ */ +@@ -3047,6 +3105,14 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(hscif1_data_b), + SH_PFC_PIN_GROUP(hscif1_clk_b), + SH_PFC_PIN_GROUP(hscif1_ctrl_b), ++ SH_PFC_PIN_GROUP(i2c1), ++ SH_PFC_PIN_GROUP(i2c1_b), ++ SH_PFC_PIN_GROUP(i2c1_c), ++ SH_PFC_PIN_GROUP(i2c2), ++ SH_PFC_PIN_GROUP(i2c2_b), ++ SH_PFC_PIN_GROUP(i2c2_c), ++ SH_PFC_PIN_GROUP(i2c2_d), ++ SH_PFC_PIN_GROUP(i2c2_e), + SH_PFC_PIN_GROUP(intc_irq0), + SH_PFC_PIN_GROUP(intc_irq1), + SH_PFC_PIN_GROUP(intc_irq2), +@@ -3243,6 +3309,20 @@ static const char * const hscif1_groups[] = { + "hscif1_ctrl_b", + }; + ++static const char * const i2c1_groups[] = { ++ "i2c1", ++ "i2c1_b", ++ "i2c1_c", ++}; ++ ++static const char * const i2c2_groups[] = { ++ "i2c2", ++ "i2c2_b", ++ "i2c2_c", ++ "i2c2_d", ++ "i2c2_e", ++}; ++ + static const char * const intc_groups[] = { + "intc_irq0", + "intc_irq1", +@@ -3469,6 +3549,8 @@ static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(eth), + SH_PFC_FUNCTION(hscif0), + SH_PFC_FUNCTION(hscif1), ++ SH_PFC_FUNCTION(i2c1), ++ SH_PFC_FUNCTION(i2c2), + SH_PFC_FUNCTION(intc), + SH_PFC_FUNCTION(mmc0), + SH_PFC_FUNCTION(mmc1), +-- +1.8.5.rc3 + diff --git a/patches.renesas/0081-sh-pfc-r8a7790-add-pin-definitions-for-the-I2C3-inte.patch b/patches.renesas/0081-sh-pfc-r8a7790-add-pin-definitions-for-the-I2C3-inte.patch new file mode 100644 index 00000000000000..51f0bee2f545c0 --- /dev/null +++ b/patches.renesas/0081-sh-pfc-r8a7790-add-pin-definitions-for-the-I2C3-inte.patch @@ -0,0 +1,105 @@ +From e5d3bba7eb6e23c92639d08703e4b21d17c1743e Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Thu, 26 Sep 2013 19:20:56 +0200 +Subject: sh-pfc: r8a7790: add pin definitions for the I2C3 interface + +There are four I2C interfaces on r8a7790, each of them can be connected to +one of the two respective I2C controllers, e.g. interface #0 can be +configured to work with I2C0 or with IIC0. Additionally some of those +interfaces can also use one of several pin sets. Interface #3 is special, +because it can be used in automatic mode for DVFS. It only has one set +of pins available and those pins cannot be used for anything else, they +also lack the GPIO function. + +This patch uses the sh-pfc ability to configure pins, not associated with +GPIOs and adds support for I2C3 to the r8a7790 PFC set up. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit f6aaaac9995084e496d4ff800d092a8c0cb12641) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/pinctrl/sh-pfc/pfc-r8a7790.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c +index 5c2657bcc3a4..72786fc93958 100644 +--- a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c ++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c +@@ -781,6 +781,8 @@ enum { + ADICS_SAMP_MARK, DU2_CDE_MARK, QPOLB_MARK, SCIFA2_RXD_B_MARK, + USB1_PWEN_MARK, AUDIO_CLKOUT_D_MARK, USB1_OVC_MARK, + TCLK1_B_MARK, ++ ++ I2C3_SCL_MARK, I2C3_SDA_MARK, + PINMUX_MARK_END, + }; + +@@ -1719,10 +1721,22 @@ static const u16 pinmux_data[] = { + PINMUX_IPSR_DATA(IP16_6, AUDIO_CLKOUT_D), + PINMUX_IPSR_DATA(IP16_7, USB1_OVC), + PINMUX_IPSR_MODSEL_DATA(IP16_7, TCLK1_B, SEL_TMU1_1), ++ ++ PINMUX_DATA(I2C3_SCL_MARK, FN_SEL_IICDVFS_1), ++ PINMUX_DATA(I2C3_SDA_MARK, FN_SEL_IICDVFS_1), + }; + ++/* R8A7790 has 6 banks with 32 GPIOs in each = 192 GPIOs */ ++#define ROW_GROUP_A(r) ('Z' - 'A' + 1 + (r)) ++#define PIN_NUMBER(r, c) (((r) - 'A') * 31 + (c) + 200) ++#define PIN_A_NUMBER(r, c) PIN_NUMBER(ROW_GROUP_A(r), c) ++ + static struct sh_pfc_pin pinmux_pins[] = { + PINMUX_GPIO_GP_ALL(), ++ ++ /* Pins not associated with a GPIO port */ ++ SH_PFC_PIN_NAMED(ROW_GROUP_A('J'), 15, AJ15), ++ SH_PFC_PIN_NAMED(ROW_GROUP_A('H'), 15, AH15), + }; + + /* - DU RGB ----------------------------------------------------------------- */ +@@ -2048,6 +2062,14 @@ static const unsigned int i2c2_e_pins[] = { + static const unsigned int i2c2_e_mux[] = { + I2C2_SCL_E_MARK, I2C2_SDA_E_MARK, + }; ++/* - I2C3 ------------------------------------------------------------------- */ ++static const unsigned int i2c3_pins[] = { ++ /* SCL, SDA */ ++ PIN_A_NUMBER('J', 15), PIN_A_NUMBER('H', 15), ++}; ++static const unsigned int i2c3_mux[] = { ++ I2C3_SCL_MARK, I2C3_SDA_MARK, ++}; + /* - INTC ------------------------------------------------------------------- */ + static const unsigned int intc_irq0_pins[] = { + /* IRQ */ +@@ -3113,6 +3135,7 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(i2c2_c), + SH_PFC_PIN_GROUP(i2c2_d), + SH_PFC_PIN_GROUP(i2c2_e), ++ SH_PFC_PIN_GROUP(i2c3), + SH_PFC_PIN_GROUP(intc_irq0), + SH_PFC_PIN_GROUP(intc_irq1), + SH_PFC_PIN_GROUP(intc_irq2), +@@ -3323,6 +3346,10 @@ static const char * const i2c2_groups[] = { + "i2c2_e", + }; + ++static const char * const i2c3_groups[] = { ++ "i2c3", ++}; ++ + static const char * const intc_groups[] = { + "intc_irq0", + "intc_irq1", +@@ -3551,6 +3578,7 @@ static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(hscif1), + SH_PFC_FUNCTION(i2c1), + SH_PFC_FUNCTION(i2c2), ++ SH_PFC_FUNCTION(i2c3), + SH_PFC_FUNCTION(intc), + SH_PFC_FUNCTION(mmc0), + SH_PFC_FUNCTION(mmc1), +-- +1.8.5.rc3 + diff --git a/patches.renesas/0082-sh-pfc-r8a7778-Add-CAN-pin-groups.patch b/patches.renesas/0082-sh-pfc-r8a7778-Add-CAN-pin-groups.patch new file mode 100644 index 00000000000000..00b3a3b73f0cd6 --- /dev/null +++ b/patches.renesas/0082-sh-pfc-r8a7778-Add-CAN-pin-groups.patch @@ -0,0 +1,105 @@ +From e52ffad6f4ec5dcf046cc2947497560bd2efe40e Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Date: Sat, 28 Sep 2013 03:07:21 +0400 +Subject: sh-pfc: r8a7778: Add CAN pin groups + +Add CAN data and clock pin groups to R8A7778 PFC driver. + +Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +(cherry picked from commit 24799c22aea81a8890a66e101cd5a3b175980777) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/pinctrl/sh-pfc/pfc-r8a7778.c | 55 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 55 insertions(+) + +diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7778.c b/drivers/pinctrl/sh-pfc/pfc-r8a7778.c +index 20b1d0d671a3..8b1881c20598 100644 +--- a/drivers/pinctrl/sh-pfc/pfc-r8a7778.c ++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7778.c +@@ -1304,6 +1304,33 @@ AUDIO_PFC_DAT(audio_clkout_a, AUDIO_CLKOUT_A); + AUDIO_PFC_PIN(audio_clkout_b, RCAR_GP_PIN(1, 16)); + AUDIO_PFC_DAT(audio_clkout_b, AUDIO_CLKOUT_B); + ++/* - CAN macro --------_----------------------------------------------------- */ ++#define CAN_PFC_PINS(name, args...) SH_PFC_PINS(name, args) ++#define CAN_PFC_DATA(name, tx, rx) SH_PFC_MUX2(name, tx, rx) ++#define CAN_PFC_CLK(name, clk) SH_PFC_MUX1(name, clk) ++ ++/* - CAN0 ------------------------------------------------------------------- */ ++CAN_PFC_PINS(can0_data_a, RCAR_GP_PIN(1, 30), RCAR_GP_PIN(1, 31)); ++CAN_PFC_DATA(can0_data_a, CAN0_TX_A, CAN0_RX_A); ++CAN_PFC_PINS(can0_data_b, RCAR_GP_PIN(2, 26), RCAR_GP_PIN(2, 27)); ++CAN_PFC_DATA(can0_data_b, CAN0_TX_B, CAN0_RX_B); ++ ++/* - CAN1 ------------------------------------------------------------------- */ ++CAN_PFC_PINS(can1_data_a, RCAR_GP_PIN(4, 20), RCAR_GP_PIN(4, 19)); ++CAN_PFC_DATA(can1_data_a, CAN1_TX_A, CAN1_RX_A); ++CAN_PFC_PINS(can1_data_b, RCAR_GP_PIN(2, 28), RCAR_GP_PIN(2, 29)); ++CAN_PFC_DATA(can1_data_b, CAN1_TX_B, CAN1_RX_B); ++ ++/* - CAN_CLK --------------------------------------------------------------- */ ++CAN_PFC_PINS(can_clk_a, RCAR_GP_PIN(3, 24)); ++CAN_PFC_CLK(can_clk_a, CAN_CLK_A); ++CAN_PFC_PINS(can_clk_b, RCAR_GP_PIN(1, 16)); ++CAN_PFC_CLK(can_clk_b, CAN_CLK_B); ++CAN_PFC_PINS(can_clk_c, RCAR_GP_PIN(4, 24)); ++CAN_PFC_CLK(can_clk_c, CAN_CLK_C); ++CAN_PFC_PINS(can_clk_d, RCAR_GP_PIN(2, 25)); ++CAN_PFC_CLK(can_clk_d, CAN_CLK_D); ++ + /* - Ether ------------------------------------------------------------------ */ + SH_PFC_PINS(ether_rmii, RCAR_GP_PIN(4, 10), RCAR_GP_PIN(4, 11), + RCAR_GP_PIN(4, 13), RCAR_GP_PIN(4, 9), +@@ -1698,6 +1725,14 @@ static const struct sh_pfc_pin_group pinmux_groups[] = { + SH_PFC_PIN_GROUP(audio_clk_c), + SH_PFC_PIN_GROUP(audio_clkout_a), + SH_PFC_PIN_GROUP(audio_clkout_b), ++ SH_PFC_PIN_GROUP(can0_data_a), ++ SH_PFC_PIN_GROUP(can0_data_b), ++ SH_PFC_PIN_GROUP(can1_data_a), ++ SH_PFC_PIN_GROUP(can1_data_b), ++ SH_PFC_PIN_GROUP(can_clk_a), ++ SH_PFC_PIN_GROUP(can_clk_b), ++ SH_PFC_PIN_GROUP(can_clk_c), ++ SH_PFC_PIN_GROUP(can_clk_d), + SH_PFC_PIN_GROUP(ether_rmii), + SH_PFC_PIN_GROUP(ether_link), + SH_PFC_PIN_GROUP(ether_magic), +@@ -1826,6 +1861,24 @@ static const char * const audio_clk_groups[] = { + "audio_clkout_b", + }; + ++static const char * const can0_groups[] = { ++ "can0_data_a", ++ "can0_data_b", ++ "can_clk_a", ++ "can_clk_b", ++ "can_clk_c", ++ "can_clk_d", ++}; ++ ++static const char * const can1_groups[] = { ++ "can1_data_a", ++ "can1_data_b", ++ "can_clk_a", ++ "can_clk_b", ++ "can_clk_c", ++ "can_clk_d", ++}; ++ + static const char * const ether_groups[] = { + "ether_rmii", + "ether_link", +@@ -2022,6 +2075,8 @@ static const char * const vin1_groups[] = { + + static const struct sh_pfc_function pinmux_functions[] = { + SH_PFC_FUNCTION(audio_clk), ++ SH_PFC_FUNCTION(can0), ++ SH_PFC_FUNCTION(can1), + SH_PFC_FUNCTION(ether), + SH_PFC_FUNCTION(hscif0), + SH_PFC_FUNCTION(hscif1), +-- +1.8.5.rc3 + diff --git a/patches.renesas/0083-pinctrl-sh-pfc-r8a7791-PFC-support.patch b/patches.renesas/0083-pinctrl-sh-pfc-r8a7791-PFC-support.patch new file mode 100644 index 00000000000000..b7dd2383e79d65 --- /dev/null +++ b/patches.renesas/0083-pinctrl-sh-pfc-r8a7791-PFC-support.patch @@ -0,0 +1,4320 @@ +From b3f9581382fb45510bcc9fcfc02746dc492712da Mon Sep 17 00:00:00 2001 +From: Hisashi Nakamura <hisashi.nakamura.ak@renesas.com> +Date: Thu, 17 Oct 2013 06:46:05 +0900 +Subject: pinctrl: sh-pfc: r8a7791 PFC support + +Add PFC support for the r8a7791 SoC V2 including pin groups for +on-chip devices such as MSIOF, SCIF, USB, MMC, SDHI, DU. + +Signed-off-by: Hisashi Nakamura <hisashi.nakamura.ak@renesas.com> +Signed-off-by: Kunihito Higashiyama <kunihito.higashiyama.ur@renesas.com> +Signed-off-by: Yoshikazu Fujikawa <yoshikazu.fujikawa.ue@renesas.com> +Signed-off-by: Nobuyuki HIRAI <nobuyuki.hirai.xe@renesas.com> +Signed-off-by: Shinobu Uehara <shinobu.uehara.xc@renesas.com> +Signed-off-by: Koji Matsuoka <koji.matsuoka.xm@renesas.com> +Signed-off-by: Ryo Kataoka <ryo.kataoka.wt@renesas.com> +[damm@opensource.se: Forward ported to upstream, minor fixes] +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> + +(cherry picked from commit 5088451962389924b9f05e22e6956f5c1a515d1a) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/pinctrl/sh-pfc/Kconfig | 5 + + drivers/pinctrl/sh-pfc/Makefile | 1 + + drivers/pinctrl/sh-pfc/core.c | 9 + + drivers/pinctrl/sh-pfc/core.h | 1 + + drivers/pinctrl/sh-pfc/pfc-r8a7791.c | 4214 ++++++++++++++++++++++++++++++++++ + 5 files changed, 4230 insertions(+) + create mode 100644 drivers/pinctrl/sh-pfc/pfc-r8a7791.c + +diff --git a/drivers/pinctrl/sh-pfc/Kconfig b/drivers/pinctrl/sh-pfc/Kconfig +index 636a882b406e..26187aa5cf5b 100644 +--- a/drivers/pinctrl/sh-pfc/Kconfig ++++ b/drivers/pinctrl/sh-pfc/Kconfig +@@ -45,6 +45,11 @@ config PINCTRL_PFC_R8A7790 + depends on ARCH_R8A7790 + select PINCTRL_SH_PFC + ++config PINCTRL_PFC_R8A7791 ++ def_bool y ++ depends on ARCH_R8A7791 ++ select PINCTRL_SH_PFC ++ + config PINCTRL_PFC_SH7203 + def_bool y + depends on CPU_SUBTYPE_SH7203 +diff --git a/drivers/pinctrl/sh-pfc/Makefile b/drivers/pinctrl/sh-pfc/Makefile +index 5e0c222c12d7..ad8f4cf9faaa 100644 +--- a/drivers/pinctrl/sh-pfc/Makefile ++++ b/drivers/pinctrl/sh-pfc/Makefile +@@ -8,6 +8,7 @@ obj-$(CONFIG_PINCTRL_PFC_R8A7740) += pfc-r8a7740.o + obj-$(CONFIG_PINCTRL_PFC_R8A7778) += pfc-r8a7778.o + obj-$(CONFIG_PINCTRL_PFC_R8A7779) += pfc-r8a7779.o + obj-$(CONFIG_PINCTRL_PFC_R8A7790) += pfc-r8a7790.o ++obj-$(CONFIG_PINCTRL_PFC_R8A7791) += pfc-r8a7791.o + obj-$(CONFIG_PINCTRL_PFC_SH7203) += pfc-sh7203.o + obj-$(CONFIG_PINCTRL_PFC_SH7264) += pfc-sh7264.o + obj-$(CONFIG_PINCTRL_PFC_SH7269) += pfc-sh7269.o +diff --git a/drivers/pinctrl/sh-pfc/core.c b/drivers/pinctrl/sh-pfc/core.c +index 738f14f65cff..d77ece5217f0 100644 +--- a/drivers/pinctrl/sh-pfc/core.c ++++ b/drivers/pinctrl/sh-pfc/core.c +@@ -431,6 +431,12 @@ static const struct of_device_id sh_pfc_of_table[] = { + .data = &r8a7790_pinmux_info, + }, + #endif ++#ifdef CONFIG_PINCTRL_PFC_R8A7791 ++ { ++ .compatible = "renesas,pfc-r8a7791", ++ .data = &r8a7791_pinmux_info, ++ }, ++#endif + #ifdef CONFIG_PINCTRL_PFC_SH7372 + { + .compatible = "renesas,pfc-sh7372", +@@ -558,6 +564,9 @@ static const struct platform_device_id sh_pfc_id_table[] = { + #ifdef CONFIG_PINCTRL_PFC_R8A7790 + { "pfc-r8a7790", (kernel_ulong_t)&r8a7790_pinmux_info }, + #endif ++#ifdef CONFIG_PINCTRL_PFC_R8A7791 ++ { "pfc-r8a7791", (kernel_ulong_t)&r8a7791_pinmux_info }, ++#endif + #ifdef CONFIG_PINCTRL_PFC_SH7203 + { "pfc-sh7203", (kernel_ulong_t)&sh7203_pinmux_info }, + #endif +diff --git a/drivers/pinctrl/sh-pfc/core.h b/drivers/pinctrl/sh-pfc/core.h +index a1b23762ac90..11ea87268658 100644 +--- a/drivers/pinctrl/sh-pfc/core.h ++++ b/drivers/pinctrl/sh-pfc/core.h +@@ -69,6 +69,7 @@ extern const struct sh_pfc_soc_info r8a7740_pinmux_info; + extern const struct sh_pfc_soc_info r8a7778_pinmux_info; + extern const struct sh_pfc_soc_info r8a7779_pinmux_info; + extern const struct sh_pfc_soc_info r8a7790_pinmux_info; ++extern const struct sh_pfc_soc_info r8a7791_pinmux_info; + extern const struct sh_pfc_soc_info sh7203_pinmux_info; + extern const struct sh_pfc_soc_info sh7264_pinmux_info; + extern const struct sh_pfc_soc_info sh7269_pinmux_info; +diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7791.c b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c +new file mode 100644 +index 000000000000..bf76a654c02f +--- /dev/null ++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7791.c +@@ -0,0 +1,4214 @@ ++/* ++ * r8a7791 processor support - PFC hardware block. ++ * ++ * Copyright (C) 2013 Renesas Electronics Corporation ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 ++ * as published by the Free Software Foundation. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/platform_data/gpio-rcar.h> ++ ++#include "core.h" ++#include "sh_pfc.h" ++ ++#define CPU_ALL_PORT(fn, sfx) \ ++ PORT_GP_32(0, fn, sfx), \ ++ PORT_GP_32(1, fn, sfx), \ ++ PORT_GP_32(2, fn, sfx), \ ++ PORT_GP_32(3, fn, sfx), \ ++ PORT_GP_32(4, fn, sfx), \ ++ PORT_GP_32(5, fn, sfx), \ ++ PORT_GP_32(6, fn, sfx), \ ++ PORT_GP_32(7, fn, sfx) ++ ++enum { ++ PINMUX_RESERVED = 0, ++ ++ PINMUX_DATA_BEGIN, ++ GP_ALL(DATA), ++ PINMUX_DATA_END, ++ ++ PINMUX_FUNCTION_BEGIN, ++ GP_ALL(FN), ++ ++ /* GPSR0 */ ++ FN_IP0_0, FN_IP0_1, FN_IP0_2, FN_IP0_3, FN_IP0_4, FN_IP0_5, ++ FN_IP0_6, FN_IP0_7, FN_IP0_8, FN_IP0_9, FN_IP0_10, FN_IP0_11, ++ FN_IP0_12, FN_IP0_13, FN_IP0_14, FN_IP0_15, FN_IP0_18_16, FN_IP0_20_19, ++ FN_IP0_22_21, FN_IP0_24_23, FN_IP0_26_25, FN_IP0_28_27, FN_IP0_30_29, ++ FN_IP1_1_0, FN_IP1_3_2, FN_IP1_5_4, FN_IP1_7_6, FN_IP1_10_8, ++ FN_IP1_13_11, FN_IP1_16_14, FN_IP1_19_17, FN_IP1_22_20, ++ ++ /* GPSR1 */ ++ FN_IP1_25_23, FN_IP1_28_26, FN_IP1_31_29, FN_IP2_2_0, FN_IP2_4_3, ++ FN_IP2_6_5, FN_IP2_9_7, FN_IP2_12_10, FN_IP2_15_13, FN_IP2_18_16, ++ FN_IP2_20_19, FN_IP2_22_21, FN_EX_CS0_N, FN_IP2_24_23, FN_IP2_26_25, ++ FN_IP2_29_27, FN_IP3_2_0, FN_IP3_5_3, FN_IP3_8_6, FN_RD_N, ++ FN_IP3_11_9, FN_IP3_13_12, FN_IP3_15_14 , FN_IP3_17_16 , FN_IP3_19_18, ++ FN_IP3_21_20, ++ ++ /* GPSR2 */ ++ FN_IP3_27_25, FN_IP3_30_28, FN_IP4_1_0, FN_IP4_4_2, FN_IP4_7_5, ++ FN_IP4_9_8, FN_IP4_12_10, FN_IP4_15_13, FN_IP4_18_16, FN_IP4_19, ++ FN_IP4_20, FN_IP4_21, FN_IP4_23_22, FN_IP4_25_24, FN_IP4_27_26, ++ FN_IP4_30_28, FN_IP5_2_0, FN_IP5_5_3, FN_IP5_8_6, FN_IP5_11_9, ++ FN_IP5_14_12, FN_IP5_16_15, FN_IP5_19_17, FN_IP5_21_20, FN_IP5_23_22, ++ FN_IP5_25_24, FN_IP5_28_26, FN_IP5_31_29, FN_AUDIO_CLKA, FN_IP6_2_0, ++ FN_IP6_5_3, FN_IP6_7_6, ++ ++ /* GPSR3 */ ++ FN_IP7_5_3, FN_IP7_8_6, FN_IP7_10_9, FN_IP7_12_11, FN_IP7_14_13, ++ FN_IP7_16_15, FN_IP7_18_17, FN_IP7_20_19, FN_IP7_23_21, FN_IP7_26_24, ++ FN_IP7_29_27, FN_IP8_2_0, FN_IP8_5_3, FN_IP8_8_6, FN_IP8_11_9, ++ FN_IP8_14_12, FN_IP8_17_15, FN_IP8_20_18, FN_IP8_23_21, FN_IP8_25_24, ++ FN_IP8_27_26, FN_IP8_30_28, FN_IP9_2_0, FN_IP9_5_3, FN_IP9_6, FN_IP9_7, ++ FN_IP9_10_8, FN_IP9_11, FN_IP9_12, FN_IP9_15_13, FN_IP9_16, ++ FN_IP9_18_17, ++ ++ /* GPSR4 */ ++ FN_VI0_CLK, FN_IP9_20_19, FN_IP9_22_21, FN_IP9_24_23, FN_IP9_26_25, ++ FN_VI0_DATA0_VI0_B0, FN_VI0_DATA1_VI0_B1, FN_VI0_DATA2_VI0_B2, ++ FN_IP9_28_27, FN_VI0_DATA4_VI0_B4, FN_VI0_DATA5_VI0_B5, ++ FN_VI0_DATA6_VI0_B6, FN_VI0_DATA7_VI0_B7, FN_IP9_31_29, FN_IP10_2_0, ++ FN_IP10_5_3, FN_IP10_8_6, FN_IP10_11_9, FN_IP10_14_12, FN_IP10_16_15, ++ FN_IP10_18_17, FN_IP10_21_19, FN_IP10_24_22, FN_IP10_26_25, ++ FN_IP10_28_27, FN_IP10_31_29, FN_IP11_2_0, FN_IP11_5_3, FN_IP11_8_6, ++ FN_IP15_1_0, FN_IP15_3_2, FN_IP15_5_4, ++ ++ /* GPSR5 */ ++ FN_IP11_11_9, FN_IP11_14_12, FN_IP11_16_15, FN_IP11_18_17, FN_IP11_19, ++ FN_IP11_20, FN_IP11_21, FN_IP11_22, FN_IP11_23, FN_IP11_24, ++ FN_IP11_25, FN_IP11_26, FN_IP11_27, FN_IP11_29_28, FN_IP11_31_30, ++ FN_IP12_1_0, FN_IP12_3_2, FN_IP12_6_4, FN_IP12_9_7, FN_IP12_12_10, ++ FN_IP12_15_13, FN_IP12_17_16, FN_IP12_19_18, FN_IP12_21_20, ++ FN_IP12_23_22, FN_IP12_26_24, FN_IP12_29_27, FN_IP13_2_0, FN_IP13_4_3, ++ FN_IP13_6_5, FN_IP13_9_7, FN_IP3_24_22, ++ ++ /* GPSR6 */ ++ FN_IP13_10, FN_IP13_11, FN_IP13_12, FN_IP13_13, FN_IP13_14, ++ FN_IP13_15, FN_IP13_18_16, FN_IP13_21_19, FN_IP13_22, FN_IP13_24_23, ++ FN_IP13_25, FN_IP13_26, FN_IP13_27, FN_IP13_30_28, FN_IP14_1_0, ++ FN_IP14_2, FN_IP14_3, FN_IP14_4, FN_IP14_5, FN_IP14_6, FN_IP14_7, ++ FN_IP14_10_8, FN_IP14_13_11, FN_IP14_16_14, FN_IP14_19_17, ++ FN_IP14_22_20, FN_IP14_25_23, FN_IP14_28_26, FN_IP14_31_29, ++ FN_USB1_OVC, FN_DU0_DOTCLKIN, ++ ++ /* GPSR7 */ ++ FN_IP15_17_15, FN_IP15_20_18, FN_IP15_23_21, FN_IP15_26_24, ++ FN_IP15_29_27, FN_IP16_2_0, FN_IP16_5_3, FN_IP16_7_6, FN_IP16_9_8, ++ FN_IP16_11_10, FN_IP6_9_8, FN_IP6_11_10, FN_IP6_13_12, FN_IP6_15_14, ++ FN_IP6_18_16, FN_IP6_20_19, FN_IP6_23_21, FN_IP6_26_24, FN_IP6_29_27, ++ FN_IP7_2_0, FN_IP15_8_6, FN_IP15_11_9, FN_IP15_14_12, ++ FN_USB0_PWEN, FN_USB0_OVC, FN_USB1_PWEN, ++ ++ /* IPSR0 */ ++ FN_D0, FN_D1, FN_D2, FN_D3, FN_D4, FN_D5, FN_D6, FN_D7, FN_D8, ++ FN_D9, FN_D10, FN_D11, FN_D12, FN_D13, FN_D14, FN_D15, ++ FN_A0, FN_ATAWR0_N_C, FN_MSIOF0_SCK_B, FN_SCL0_C, FN_PWM2_B, ++ FN_A1, FN_MSIOF0_SYNC_B, FN_A2, FN_MSIOF0_SS1_B, ++ FN_A3, FN_MSIOF0_SS2_B, FN_A4, FN_MSIOF0_TXD_B, ++ FN_A5, FN_MSIOF0_RXD_B, FN_A6, FN_MSIOF1_SCK, ++ ++ /* IPSR1 */ ++ FN_A7, FN_MSIOF1_SYNC, FN_A8, FN_MSIOF1_SS1, FN_SCL0, ++ FN_A9, FN_MSIOF1_SS2, FN_SDA0, ++ FN_A10, FN_MSIOF1_TXD, FN_MSIOF1_TXD_D, ++ FN_A11, FN_MSIOF1_RXD, FN_SCL3_D, FN_MSIOF1_RXD_D, ++ FN_A12, FN_FMCLK, FN_SDA3_D, FN_MSIOF1_SCK_D, ++ FN_A13, FN_ATAG0_N_C, FN_BPFCLK, FN_MSIOF1_SS1_D, ++ FN_A14, FN_ATADIR0_N_C, FN_FMIN, FN_FMIN_C, FN_MSIOF1_SYNC_D, ++ FN_A15, FN_BPFCLK_C, ++ FN_A16, FN_DREQ2_B, FN_FMCLK_C, FN_SCIFA1_SCK_B, ++ FN_A17, FN_DACK2_B, FN_SDA0_C, ++ FN_A18, FN_DREQ1, FN_SCIFA1_RXD_C, FN_SCIFB1_RXD_C, ++ ++ /* IPSR2 */ ++ FN_A19, FN_DACK1, FN_SCIFA1_TXD_C, FN_SCIFB1_TXD_C, FN_SCIFB1_SCK_B, ++ FN_A20, FN_SPCLK, ++ FN_A21, FN_ATAWR0_N_B, FN_MOSI_IO0, ++ FN_A22, FN_MISO_IO1, FN_FMCLK_B, FN_TX0, FN_SCIFA0_TXD, ++ FN_A23, FN_IO2, FN_BPFCLK_B, FN_RX0, FN_SCIFA0_RXD, ++ FN_A24, FN_DREQ2, FN_IO3, FN_TX1, FN_SCIFA1_TXD, ++ FN_A25, FN_DACK2, FN_SSL, FN_DREQ1_C, FN_RX1, FN_SCIFA1_RXD, ++ FN_CS0_N, FN_ATAG0_N_B, FN_SCL1, ++ FN_CS1_N_A26, FN_ATADIR0_N_B, FN_SDA1, ++ FN_EX_CS1_N, FN_MSIOF2_SCK, ++ FN_EX_CS2_N, FN_ATAWR0_N, FN_MSIOF2_SYNC, ++ FN_EX_CS3_N, FN_ATADIR0_N, FN_MSIOF2_TXD, FN_ATAG0_N, FN_EX_WAIT1, ++ ++ /* IPSR3 */ ++ FN_EX_CS4_N, FN_ATARD0_N, FN_MSIOF2_RXD, FN_EX_WAIT2, ++ FN_EX_CS5_N, FN_ATACS00_N, FN_MSIOF2_SS1, FN_HRX1_B, ++ FN_SCIFB1_RXD_B, FN_PWM1, FN_TPU_TO1, ++ FN_BS_N, FN_ATACS10_N, FN_MSIOF2_SS2, FN_HTX1_B, ++ FN_SCIFB1_TXD_B, FN_PWM2, FN_TPU_TO2, ++ FN_RD_WR_N, FN_HRX2_B, FN_FMIN_B, FN_SCIFB0_RXD_B, FN_DREQ1_D, ++ FN_WE0_N, FN_HCTS2_N_B, FN_SCIFB0_TXD_B, ++ FN_WE1_N, FN_ATARD0_N_B, FN_HTX2_B, FN_SCIFB0_RTS_N_B, ++ FN_EX_WAIT0, FN_HRTS2_N_B, FN_SCIFB0_CTS_N_B, ++ FN_DREQ0, FN_PWM3, FN_TPU_TO3, ++ FN_DACK0, FN_DRACK0, FN_REMOCON, ++ FN_SPEEDIN, FN_HSCK0_C, FN_HSCK2_C, FN_SCIFB0_SCK_B, ++ FN_SCIFB2_SCK_B, FN_DREQ2_C, FN_HTX2_D, ++ FN_SSI_SCK0129, FN_HRX0_C, FN_HRX2_C, FN_SCIFB0_RXD_C, FN_SCIFB2_RXD_C, ++ FN_SSI_WS0129, FN_HTX0_C, FN_HTX2_C, FN_SCIFB0_TXD_C, FN_SCIFB2_TXD_C, ++ ++ /* IPSR4 */ ++ FN_SSI_SDATA0, FN_SCL0_B, FN_SCL7_B, FN_MSIOF2_SCK_C, ++ FN_SSI_SCK1, FN_SDA0_B, FN_SDA7_B, FN_MSIOF2_SYNC_C, FN_GLO_I0_D, ++ FN_SSI_WS1, FN_SCL1_B, FN_SCL8_B, FN_MSIOF2_TXD_C, FN_GLO_I1_D, ++ FN_SSI_SDATA1, FN_SDA1_B, FN_SDA8_B, FN_MSIOF2_RXD_C, ++ FN_SSI_SCK2, FN_SCL2, FN_GPS_CLK_B, FN_GLO_Q0_D, FN_HSCK1_E, ++ FN_SSI_WS2, FN_SDA2, FN_GPS_SIGN_B, FN_RX2_E, ++ FN_GLO_Q1_D, FN_HCTS1_N_E, ++ FN_SSI_SDATA2, FN_GPS_MAG_B, FN_TX2_E, FN_HRTS1_N_E, ++ FN_SSI_SCK34, FN_SSI_WS34, FN_SSI_SDATA3, ++ FN_SSI_SCK4, FN_GLO_SS_D, ++ FN_SSI_WS4, FN_GLO_RFON_D, ++ FN_SSI_SDATA4, FN_MSIOF2_SCK_D, ++ FN_SSI_SCK5, FN_MSIOF1_SCK_C, FN_TS_SDATA0, FN_GLO_I0, ++ FN_MSIOF2_SYNC_D, FN_VI1_R2_B, ++ ++ /* IPSR5 */ ++ FN_SSI_WS5, FN_MSIOF1_SYNC_C, FN_TS_SCK0, FN_GLO_I1, ++ FN_MSIOF2_TXD_D, FN_VI1_R3_B, ++ FN_SSI_SDATA5, FN_MSIOF1_TXD_C, FN_TS_SDEN0, FN_GLO_Q0, ++ FN_MSIOF2_SS1_D, FN_VI1_R4_B, ++ FN_SSI_SCK6, FN_MSIOF1_RXD_C, FN_TS_SPSYNC0, FN_GLO_Q1, ++ FN_MSIOF2_RXD_D, FN_VI1_R5_B, ++ FN_SSI_WS6, FN_GLO_SCLK, FN_MSIOF2_SS2_D, FN_VI1_R6_B, ++ FN_SSI_SDATA6, FN_STP_IVCXO27_0_B, FN_GLO_SDATA, FN_VI1_R7_B, ++ FN_SSI_SCK78, FN_STP_ISCLK_0_B, FN_GLO_SS, ++ FN_SSI_WS78, FN_TX0_D, FN_STP_ISD_0_B, FN_GLO_RFON, ++ FN_SSI_SDATA7, FN_RX0_D, FN_STP_ISEN_0_B, ++ FN_SSI_SDATA8, FN_TX1_D, FN_STP_ISSYNC_0_B, ++ FN_SSI_SCK9, FN_RX1_D, FN_GLO_SCLK_D, ++ FN_SSI_WS9, FN_TX3_D, FN_CAN0_TX_D, FN_GLO_SDATA_D, ++ FN_SSI_SDATA9, FN_RX3_D, FN_CAN0_RX_D, ++ ++ /* IPSR6 */ ++ FN_AUDIO_CLKB, FN_STP_OPWM_0_B, FN_MSIOF1_SCK_B, ++ FN_SCIF_CLK, FN_BPFCLK_E, ++ FN_AUDIO_CLKC, FN_SCIFB0_SCK_C, FN_MSIOF1_SYNC_B, FN_RX2, ++ FN_SCIFA2_RXD, FN_FMIN_E, ++ FN_AUDIO_CLKOUT, FN_MSIOF1_SS1_B, FN_TX2, FN_SCIFA2_TXD, ++ FN_IRQ0, FN_SCIFB1_RXD_D, FN_INTC_IRQ0_N, ++ FN_IRQ1, FN_SCIFB1_SCK_C, FN_INTC_IRQ1_N, ++ FN_IRQ2, FN_SCIFB1_TXD_D, FN_INTC_IRQ2_N, ++ FN_IRQ3, FN_SCL4_C, FN_MSIOF2_TXD_E, FN_INTC_IRQ3_N, ++ FN_IRQ4, FN_HRX1_C, FN_SDA4_C, FN_MSIOF2_RXD_E, FN_INTC_IRQ4_N, ++ FN_IRQ5, FN_HTX1_C, FN_SCL1_E, FN_MSIOF2_SCK_E, ++ FN_IRQ6, FN_HSCK1_C, FN_MSIOF1_SS2_B, FN_SDA1_E, FN_MSIOF2_SYNC_E, ++ FN_IRQ7, FN_HCTS1_N_C, FN_MSIOF1_TXD_B, FN_GPS_CLK_C, FN_GPS_CLK_D, ++ FN_IRQ8, FN_HRTS1_N_C, FN_MSIOF1_RXD_B, FN_GPS_SIGN_C, FN_GPS_SIGN_D, ++ ++ /* IPSR7 */ ++ FN_IRQ9, FN_DU1_DOTCLKIN_B, FN_CAN_CLK_D, FN_GPS_MAG_C, ++ FN_SCIF_CLK_B, FN_GPS_MAG_D, ++ FN_DU1_DR0, FN_LCDOUT0, FN_VI1_DATA0_B, FN_TX0_B, ++ FN_SCIFA0_TXD_B, FN_MSIOF2_SCK_B, ++ FN_DU1_DR1, FN_LCDOUT1, FN_VI1_DATA1_B, FN_RX0_B, ++ FN_SCIFA0_RXD_B, FN_MSIOF2_SYNC_B, ++ FN_DU1_DR2, FN_LCDOUT2, FN_SSI_SCK0129_B, ++ FN_DU1_DR3, FN_LCDOUT3, FN_SSI_WS0129_B, ++ FN_DU1_DR4, FN_LCDOUT4, FN_SSI_SDATA0_B, ++ FN_DU1_DR5, FN_LCDOUT5, FN_SSI_SCK1_B, ++ FN_DU1_DR6, FN_LCDOUT6, FN_SSI_WS1_B, ++ FN_DU1_DR7, FN_LCDOUT7, FN_SSI_SDATA1_B, ++ FN_DU1_DG0, FN_LCDOUT8, FN_VI1_DATA2_B, FN_TX1_B, ++ FN_SCIFA1_TXD_B, FN_MSIOF2_SS1_B, ++ FN_DU1_DG1, FN_LCDOUT9, FN_VI1_DATA3_B, FN_RX1_B, ++ FN_SCIFA1_RXD_B, FN_MSIOF2_SS2_B, ++ FN_DU1_DG2, FN_LCDOUT10, FN_VI1_DATA4_B, FN_SCIF1_SCK_B, ++ FN_SCIFA1_SCK, FN_SSI_SCK78_B, ++ ++ /* IPSR8 */ ++ FN_DU1_DG3, FN_LCDOUT11, FN_VI1_DATA5_B, FN_SSI_WS78_B, ++ FN_DU1_DG4, FN_LCDOUT12, FN_VI1_DATA6_B, FN_HRX0_B, ++ FN_SCIFB2_RXD_B, FN_SSI_SDATA7_B, ++ FN_DU1_DG5, FN_LCDOUT13, FN_VI1_DATA7_B, FN_HCTS0_N_B, ++ FN_SCIFB2_TXD_B, FN_SSI_SDATA8_B, ++ FN_DU1_DG6, FN_LCDOUT14, FN_HRTS0_N_B, ++ FN_SCIFB2_CTS_N_B, FN_SSI_SCK9_B, ++ FN_DU1_DG7, FN_LCDOUT15, FN_HTX0_B, FN_SCIFB2_RTS_N_B, FN_SSI_WS9_B, ++ FN_DU1_DB0, FN_LCDOUT16, FN_VI1_CLK_B, FN_TX2_B, ++ FN_SCIFA2_TXD_B, FN_MSIOF2_TXD_B, ++ FN_DU1_DB1, FN_LCDOUT17, FN_VI1_HSYNC_N_B, FN_RX2_B, ++ FN_SCIFA2_RXD_B, FN_MSIOF2_RXD_B, ++ FN_DU1_DB2, FN_LCDOUT18, FN_VI1_VSYNC_N_B, FN_SCIF2_SCK_B, ++ FN_SCIFA2_SCK, FN_SSI_SDATA9_B, ++ FN_DU1_DB3, FN_LCDOUT19, FN_VI1_CLKENB_B, ++ FN_DU1_DB4, FN_LCDOUT20, FN_VI1_FIELD_B, FN_CAN1_RX, ++ FN_DU1_DB5, FN_LCDOUT21, FN_TX3, FN_SCIFA3_TXD, FN_CAN1_TX, ++ ++ /* IPSR9 */ ++ FN_DU1_DB6, FN_LCDOUT22, FN_SCL3_C, FN_RX3, FN_SCIFA3_RXD, ++ FN_DU1_DB7, FN_LCDOUT23, FN_SDA3_C, FN_SCIF3_SCK, FN_SCIFA3_SCK, ++ FN_DU1_DOTCLKIN, FN_QSTVA_QVS, ++ FN_DU1_DOTCLKOUT0, FN_QCLK, ++ FN_DU1_DOTCLKOUT1, FN_QSTVB_QVE, FN_CAN0_TX, ++ FN_TX3_B, FN_SCL2_B, FN_PWM4, ++ FN_DU1_EXHSYNC_DU1_HSYNC, FN_QSTH_QHS, ++ FN_DU1_EXVSYNC_DU1_VSYNC, FN_QSTB_QHE, ++ FN_DU1_EXODDF_DU1_ODDF_DISP_CDE, FN_QCPV_QDE, ++ FN_CAN0_RX, FN_RX3_B, FN_SDA2_B, ++ FN_DU1_DISP, FN_QPOLA, ++ FN_DU1_CDE, FN_QPOLB, FN_PWM4_B, ++ FN_VI0_CLKENB, FN_TX4, FN_SCIFA4_TXD, FN_TS_SDATA0_D, ++ FN_VI0_FIELD, FN_RX4, FN_SCIFA4_RXD, FN_TS_SCK0_D, ++ FN_VI0_HSYNC_N, FN_TX5, FN_SCIFA5_TXD, FN_TS_SDEN0_D, ++ FN_VI0_VSYNC_N, FN_RX5, FN_SCIFA5_RXD, FN_TS_SPSYNC0_D, ++ FN_VI0_DATA3_VI0_B3, FN_SCIF3_SCK_B, FN_SCIFA3_SCK_B, ++ FN_VI0_G0, FN_SCL8, FN_STP_IVCXO27_0_C, FN_SCL4, ++ FN_HCTS2_N, FN_SCIFB2_CTS_N, FN_ATAWR1_N, ++ ++ /* IPSR10 */ ++ FN_VI0_G1, FN_SDA8, FN_STP_ISCLK_0_C, FN_SDA4, ++ FN_HRTS2_N, FN_SCIFB2_RTS_N, FN_ATADIR1_N, ++ FN_VI0_G2, FN_VI2_HSYNC_N, FN_STP_ISD_0_C, FN_SCL3_B, ++ FN_HSCK2, FN_SCIFB2_SCK, FN_ATARD1_N, ++ FN_VI0_G3, FN_VI2_VSYNC_N, FN_STP_ISEN_0_C, FN_SDA3_B, ++ FN_HRX2, FN_SCIFB2_RXD, FN_ATACS01_N, ++ FN_VI0_G4, FN_VI2_CLKENB, FN_STP_ISSYNC_0_C, ++ FN_HTX2, FN_SCIFB2_TXD, FN_SCIFB0_SCK_D, ++ FN_VI0_G5, FN_VI2_FIELD, FN_STP_OPWM_0_C, FN_FMCLK_D, ++ FN_CAN0_TX_E, FN_HTX1_D, FN_SCIFB0_TXD_D, ++ FN_VI0_G6, FN_VI2_CLK, FN_BPFCLK_D, ++ FN_VI0_G7, FN_VI2_DATA0, FN_FMIN_D, ++ FN_VI0_R0, FN_VI2_DATA1, FN_GLO_I0_B, ++ FN_TS_SDATA0_C, FN_ATACS11_N, ++ FN_VI0_R1, FN_VI2_DATA2, FN_GLO_I1_B, ++ FN_TS_SCK0_C, FN_ATAG1_N, ++ FN_VI0_R2, FN_VI2_DATA3, FN_GLO_Q0_B, FN_TS_SDEN0_C, ++ FN_VI0_R3, FN_VI2_DATA4, FN_GLO_Q1_B, FN_TS_SPSYNC0_C, ++ FN_VI0_R4, FN_VI2_DATA5, FN_GLO_SCLK_B, FN_TX0_C, FN_SCL1_D, ++ ++ /* IPSR11 */ ++ FN_VI0_R5, FN_VI2_DATA6, FN_GLO_SDATA_B, FN_RX0_C, FN_SDA1_D, ++ FN_VI0_R6, FN_VI2_DATA7, FN_GLO_SS_B, FN_TX1_C, FN_SCL4_B, ++ FN_VI0_R7, FN_GLO_RFON_B, FN_RX1_C, FN_CAN0_RX_E, ++ FN_SDA4_B, FN_HRX1_D, FN_SCIFB0_RXD_D, ++ FN_VI1_HSYNC_N, FN_AVB_RXD0, FN_TS_SDATA0_B, FN_TX4_B, FN_SCIFA4_TXD_B, ++ FN_VI1_VSYNC_N, FN_AVB_RXD1, FN_TS_SCK0_B, FN_RX4_B, FN_SCIFA4_RXD_B, ++ FN_VI1_CLKENB, FN_AVB_RXD2, FN_TS_SDEN0_B, ++ FN_VI1_FIELD, FN_AVB_RXD3, FN_TS_SPSYNC0_B, ++ FN_VI1_CLK, FN_AVB_RXD4, FN_VI1_DATA0, FN_AVB_RXD5, ++ FN_VI1_DATA1, FN_AVB_RXD6, FN_VI1_DATA2, FN_AVB_RXD7, ++ FN_VI1_DATA3, FN_AVB_RX_ER, FN_VI1_DATA4, FN_AVB_MDIO, ++ FN_VI1_DATA5, FN_AVB_RX_DV, FN_VI1_DATA6, FN_AVB_MAGIC, ++ FN_VI1_DATA7, FN_AVB_MDC, ++ FN_ETH_MDIO, FN_AVB_RX_CLK, FN_SCL2_C, ++ FN_ETH_CRS_DV, FN_AVB_LINK, FN_SDA2_C, ++ ++ /* IPSR12 */ ++ FN_ETH_RX_ER, FN_AVB_CRS, FN_SCL3, FN_SCL7, ++ FN_ETH_RXD0, FN_AVB_PHY_INT, FN_SDA3, FN_SDA7, ++ FN_ETH_RXD1, FN_AVB_GTXREFCLK, FN_CAN0_TX_C, ++ FN_SCL2_D, FN_MSIOF1_RXD_E, ++ FN_ETH_LINK, FN_AVB_TXD0, FN_CAN0_RX_C, FN_SDA2_D, FN_MSIOF1_SCK_E, ++ FN_ETH_REFCLK, FN_AVB_TXD1, FN_SCIFA3_RXD_B, ++ FN_CAN1_RX_C, FN_MSIOF1_SYNC_E, ++ FN_ETH_TXD1, FN_AVB_TXD2, FN_SCIFA3_TXD_B, ++ FN_CAN1_TX_C, FN_MSIOF1_TXD_E, ++ FN_ETH_TX_EN, FN_AVB_TXD3, FN_TCLK1_B, FN_CAN_CLK_B, ++ FN_ETH_MAGIC, FN_AVB_TXD4, FN_IETX_C, ++ FN_ETH_TXD0, FN_AVB_TXD5, FN_IECLK_C, ++ FN_ETH_MDC, FN_AVB_TXD6, FN_IERX_C, ++ FN_STP_IVCXO27_0, FN_AVB_TXD7, FN_SCIFB2_TXD_D, ++ FN_ADIDATA_B, FN_MSIOF0_SYNC_C, ++ FN_STP_ISCLK_0, FN_AVB_TX_EN, FN_SCIFB2_RXD_D, ++ FN_ADICS_SAMP_B, FN_MSIOF0_SCK_C, ++ ++ /* IPSR13 */ ++ FN_STP_ISD_0, FN_AVB_TX_ER, FN_SCIFB2_SCK_C, ++ FN_ADICLK_B, FN_MSIOF0_SS1_C, ++ FN_STP_ISEN_0, FN_AVB_TX_CLK, FN_ADICHS0_B, FN_MSIOF0_SS2_C, ++ FN_STP_ISSYNC_0, FN_AVB_COL, FN_ADICHS1_B, FN_MSIOF0_RXD_C, ++ FN_STP_OPWM_0, FN_AVB_GTX_CLK, FN_PWM0_B, ++ FN_ADICHS2_B, FN_MSIOF0_TXD_C, ++ FN_SD0_CLK, FN_SPCLK_B, FN_SD0_CMD, FN_MOSI_IO0_B, ++ FN_SD0_DATA0, FN_MISO_IO1_B, FN_SD0_DATA1, FN_IO2_B, ++ FN_SD0_DATA2, FN_IO3_B, FN_SD0_DATA3, FN_SSL_B, ++ FN_SD0_CD, FN_MMC_D6_B, FN_SIM0_RST_B, FN_CAN0_RX_F, ++ FN_SCIFA5_TXD_B, FN_TX3_C, ++ FN_SD0_WP, FN_MMC_D7_B, FN_SIM0_D_B, FN_CAN0_TX_F, ++ FN_SCIFA5_RXD_B, FN_RX3_C, ++ FN_SD1_CMD, FN_REMOCON_B, FN_SD1_DATA0, FN_SPEEDIN_B, ++ FN_SD1_DATA1, FN_IETX_B, FN_SD1_DATA2, FN_IECLK_B, ++ FN_SD1_DATA3, FN_IERX_B, ++ FN_SD1_CD, FN_PWM0, FN_TPU_TO0, FN_SCL1_C, ++ ++ /* IPSR14 */ ++ FN_SD1_WP, FN_PWM1_B, FN_SDA1_C, ++ FN_SD2_CLK, FN_MMC_CLK, FN_SD2_CMD, FN_MMC_CMD, ++ FN_SD2_DATA0, FN_MMC_D0, FN_SD2_DATA1, FN_MMC_D1, ++ FN_SD2_DATA2, FN_MMC_D2, FN_SD2_DATA3, FN_MMC_D3, ++ FN_SD2_CD, FN_MMC_D4, FN_SCL8_C, FN_TX5_B, FN_SCIFA5_TXD_C, ++ FN_SD2_WP, FN_MMC_D5, FN_SDA8_C, FN_RX5_B, FN_SCIFA5_RXD_C, ++ FN_MSIOF0_SCK, FN_RX2_C, FN_ADIDATA, FN_VI1_CLK_C, FN_VI1_G0_B, ++ FN_MSIOF0_SYNC, FN_TX2_C, FN_ADICS_SAMP, FN_VI1_CLKENB_C, FN_VI1_G1_B, ++ FN_MSIOF0_TXD, FN_ADICLK, FN_VI1_FIELD_C, FN_VI1_G2_B, ++ FN_MSIOF0_RXD, FN_ADICHS0, FN_VI1_DATA0_C, FN_VI1_G3_B, ++ FN_MSIOF0_SS1, FN_MMC_D6, FN_ADICHS1, FN_TX0_E, ++ FN_VI1_HSYNC_N_C, FN_SCL7_C, FN_VI1_G4_B, ++ FN_MSIOF0_SS2, FN_MMC_D7, FN_ADICHS2, FN_RX0_E, ++ FN_VI1_VSYNC_N_C, FN_SDA7_C, FN_VI1_G5_B, ++ ++ /* IPSR15 */ ++ FN_SIM0_RST, FN_IETX, FN_CAN1_TX_D, ++ FN_SIM0_CLK, FN_IECLK, FN_CAN_CLK_C, ++ FN_SIM0_D, FN_IERX, FN_CAN1_RX_D, ++ FN_GPS_CLK, FN_DU1_DOTCLKIN_C, FN_AUDIO_CLKB_B, ++ FN_PWM5_B, FN_SCIFA3_TXD_C, ++ FN_GPS_SIGN, FN_TX4_C, FN_SCIFA4_TXD_C, FN_PWM5, ++ FN_VI1_G6_B, FN_SCIFA3_RXD_C, ++ FN_GPS_MAG, FN_RX4_C, FN_SCIFA4_RXD_C, FN_PWM6, ++ FN_VI1_G7_B, FN_SCIFA3_SCK_C, ++ FN_HCTS0_N, FN_SCIFB0_CTS_N, FN_GLO_I0_C, FN_TCLK1, FN_VI1_DATA1_C, ++ FN_HRTS0_N, FN_SCIFB0_RTS_N, FN_GLO_I1_C, FN_VI1_DATA2_C, ++ FN_HSCK0, FN_SCIFB0_SCK, FN_GLO_Q0_C, FN_CAN_CLK, ++ FN_TCLK2, FN_VI1_DATA3_C, ++ FN_HRX0, FN_SCIFB0_RXD, FN_GLO_Q1_C, FN_CAN0_RX_B, FN_VI1_DATA4_C, ++ FN_HTX0, FN_SCIFB0_TXD, FN_GLO_SCLK_C, FN_CAN0_TX_B, FN_VI1_DATA5_C, ++ ++ /* IPSR16 */ ++ FN_HRX1, FN_SCIFB1_RXD, FN_VI1_R0_B, FN_GLO_SDATA_C, FN_VI1_DATA6_C, ++ FN_HTX1, FN_SCIFB1_TXD, FN_VI1_R1_B, FN_GLO_SS_C, FN_VI1_DATA7_C, ++ FN_HSCK1, FN_SCIFB1_SCK, FN_MLB_CK, FN_GLO_RFON_C, ++ FN_HCTS1_N, FN_SCIFB1_CTS_N, FN_MLB_SIG, FN_CAN1_TX_B, ++ FN_HRTS1_N, FN_SCIFB1_RTS_N, FN_MLB_DAT, FN_CAN1_RX_B, ++ ++ /* MOD_SEL */ ++ FN_SEL_SCIF1_0, FN_SEL_SCIF1_1, FN_SEL_SCIF1_2, FN_SEL_SCIF1_3, ++ FN_SEL_SCIFB_0, FN_SEL_SCIFB_1, FN_SEL_SCIFB_2, FN_SEL_SCIFB_3, ++ FN_SEL_SCIFB2_0, FN_SEL_SCIFB2_1, FN_SEL_SCIFB2_2, FN_SEL_SCIFB2_3, ++ FN_SEL_SCIFB1_0, FN_SEL_SCIFB1_1, FN_SEL_SCIFB1_2, FN_SEL_SCIFB1_3, ++ FN_SEL_SCIFA1_0, FN_SEL_SCIFA1_1, FN_SEL_SCIFA1_2, ++ FN_SEL_SSI9_0, FN_SEL_SSI9_1, ++ FN_SEL_SCFA_0, FN_SEL_SCFA_1, ++ FN_SEL_QSP_0, FN_SEL_QSP_1, ++ FN_SEL_SSI7_0, FN_SEL_SSI7_1, ++ FN_SEL_HSCIF1_0, FN_SEL_HSCIF1_1, FN_SEL_HSCIF1_2, FN_SEL_HSCIF1_3, ++ FN_SEL_HSCIF1_4, ++ FN_SEL_VI1_0, FN_SEL_VI1_1, FN_SEL_VI1_2, ++ FN_SEL_TMU1_0, FN_SEL_TMU1_1, ++ FN_SEL_LBS_0, FN_SEL_LBS_1, FN_SEL_LBS_2, FN_SEL_LBS_3, ++ FN_SEL_TSIF0_0, FN_SEL_TSIF0_1, FN_SEL_TSIF0_2, FN_SEL_TSIF0_3, ++ FN_SEL_SOF0_0, FN_SEL_SOF0_1, FN_SEL_SOF0_2, ++ ++ /* MOD_SEL2 */ ++ FN_SEL_SCIF0_0, FN_SEL_SCIF0_1, FN_SEL_SCIF0_2, FN_SEL_SCIF0_3, ++ FN_SEL_SCIF0_4, ++ FN_SEL_SCIF_0, FN_SEL_SCIF_1, ++ FN_SEL_CAN0_0, FN_SEL_CAN0_1, FN_SEL_CAN0_2, FN_SEL_CAN0_3, ++ FN_SEL_CAN0_4, FN_SEL_CAN0_5, ++ FN_SEL_CAN1_0, FN_SEL_CAN1_1, FN_SEL_CAN1_2, FN_SEL_CAN1_3, ++ FN_SEL_SCIFA2_0, FN_SEL_SCIFA2_1, ++ FN_SEL_SCIF4_0, FN_SEL_SCIF4_1, FN_SEL_SCIF4_2, ++ FN_SEL_ADG_0, FN_SEL_ADG_1, ++ FN_SEL_FM_0, FN_SEL_FM_1, FN_SEL_FM_2, FN_SEL_FM_3, FN_SEL_FM_4, ++ FN_SEL_SCIFA5_0, FN_SEL_SCIFA5_1, FN_SEL_SCIFA5_2, ++ FN_SEL_GPS_0, FN_SEL_GPS_1, FN_SEL_GPS_2, FN_SEL_GPS_3, ++ FN_SEL_SCIFA4_0, FN_SEL_SCIFA4_1, FN_SEL_SCIFA4_2, ++ FN_SEL_SCIFA3_0, FN_SEL_SCIFA3_1, FN_SEL_SCIFA3_2, ++ FN_SEL_SIM_0, FN_SEL_SIM_1, ++ FN_SEL_SSI8_0, FN_SEL_SSI8_1, ++ ++ /* MOD_SEL3 */ ++ FN_SEL_HSCIF2_0, FN_SEL_HSCIF2_1, FN_SEL_HSCIF2_2, FN_SEL_HSCIF2_3, ++ FN_SEL_CANCLK_0, FN_SEL_CANCLK_1, FN_SEL_CANCLK_2, FN_SEL_CANCLK_3, ++ FN_SEL_IIC8_0, FN_SEL_IIC8_1, FN_SEL_IIC8_2, ++ FN_SEL_IIC7_0, FN_SEL_IIC7_1, FN_SEL_IIC7_2, ++ FN_SEL_IIC4_0, FN_SEL_IIC4_1, FN_SEL_IIC4_2, ++ FN_SEL_IIC3_0, FN_SEL_IIC3_1, FN_SEL_IIC3_2, FN_SEL_IIC3_3, ++ FN_SEL_SCIF3_0, FN_SEL_SCIF3_1, FN_SEL_SCIF3_2, FN_SEL_SCIF3_3, ++ FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2, ++ FN_SEL_MMC_0, FN_SEL_MMC_1, ++ FN_SEL_SCIF5_0, FN_SEL_SCIF5_1, ++ FN_SEL_IIC2_0, FN_SEL_IIC2_1, FN_SEL_IIC2_2, FN_SEL_IIC2_3, ++ FN_SEL_IIC1_0, FN_SEL_IIC1_1, FN_SEL_IIC1_2, FN_SEL_IIC1_3, ++ FN_SEL_IIC1_4, ++ FN_SEL_IIC0_0, FN_SEL_IIC0_1, FN_SEL_IIC0_2, ++ ++ /* MOD_SEL4 */ ++ FN_SEL_SOF1_0, FN_SEL_SOF1_1, FN_SEL_SOF1_2, FN_SEL_SOF1_3, ++ FN_SEL_SOF1_4, ++ FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1, FN_SEL_HSCIF0_2, ++ FN_SEL_DIS_0, FN_SEL_DIS_1, FN_SEL_DIS_2, ++ FN_SEL_RAD_0, FN_SEL_RAD_1, ++ FN_SEL_RCN_0, FN_SEL_RCN_1, ++ FN_SEL_RSP_0, FN_SEL_RSP_1, ++ FN_SEL_SCIF2_0, FN_SEL_SCIF2_1, FN_SEL_SCIF2_2, FN_SEL_SCIF2_3, ++ FN_SEL_SCIF2_4, ++ FN_SEL_SOF2_0, FN_SEL_SOF2_1, FN_SEL_SOF2_2, FN_SEL_SOF2_3, ++ FN_SEL_SOF2_4, ++ FN_SEL_SSI1_0, FN_SEL_SSI1_1, ++ FN_SEL_SSI0_0, FN_SEL_SSI0_1, ++ FN_SEL_SSP_0, FN_SEL_SSP_1, FN_SEL_SSP_2, ++ PINMUX_FUNCTION_END, ++ ++ PINMUX_MARK_BEGIN, ++ ++ EX_CS0_N_MARK, RD_N_MARK, ++ ++ AUDIO_CLKA_MARK, ++ ++ VI0_CLK_MARK, VI0_DATA0_VI0_B0_MARK, VI0_DATA1_VI0_B1_MARK, ++ VI0_DATA2_VI0_B2_MARK, VI0_DATA4_VI0_B4_MARK, VI0_DATA5_VI0_B5_MARK, ++ VI0_DATA6_VI0_B6_MARK, VI0_DATA7_VI0_B7_MARK, ++ ++ SD1_CLK_MARK, ++ ++ USB0_PWEN_MARK, USB0_OVC_MARK, USB1_PWEN_MARK, USB1_OVC_MARK, ++ DU0_DOTCLKIN_MARK, ++ ++ /* IPSR0 */ ++ D0_MARK, D1_MARK, D2_MARK, D3_MARK, D4_MARK, D5_MARK, ++ D6_MARK, D7_MARK, D8_MARK, ++ D9_MARK, D10_MARK, D11_MARK, D12_MARK, D13_MARK, D14_MARK, D15_MARK, ++ A0_MARK, ATAWR0_N_C_MARK, MSIOF0_SCK_B_MARK, SCL0_C_MARK, PWM2_B_MARK, ++ A1_MARK, MSIOF0_SYNC_B_MARK, A2_MARK, MSIOF0_SS1_B_MARK, ++ A3_MARK, MSIOF0_SS2_B_MARK, A4_MARK, MSIOF0_TXD_B_MARK, ++ A5_MARK, MSIOF0_RXD_B_MARK, A6_MARK, MSIOF1_SCK_MARK, ++ ++ /* IPSR1 */ ++ A7_MARK, MSIOF1_SYNC_MARK, A8_MARK, MSIOF1_SS1_MARK, SCL0_MARK, ++ A9_MARK, MSIOF1_SS2_MARK, SDA0_MARK, ++ A10_MARK, MSIOF1_TXD_MARK, MSIOF1_TXD_D_MARK, ++ A11_MARK, MSIOF1_RXD_MARK, SCL3_D_MARK, MSIOF1_RXD_D_MARK, ++ A12_MARK, FMCLK_MARK, SDA3_D_MARK, MSIOF1_SCK_D_MARK, ++ A13_MARK, ATAG0_N_C_MARK, BPFCLK_MARK, MSIOF1_SS1_D_MARK, ++ A14_MARK, ATADIR0_N_C_MARK, FMIN_MARK, FMIN_C_MARK, MSIOF1_SYNC_D_MARK, ++ A15_MARK, BPFCLK_C_MARK, ++ A16_MARK, DREQ2_B_MARK, FMCLK_C_MARK, SCIFA1_SCK_B_MARK, ++ A17_MARK, DACK2_B_MARK, SDA0_C_MARK, ++ A18_MARK, DREQ1_MARK, SCIFA1_RXD_C_MARK, SCIFB1_RXD_C_MARK, ++ ++ /* IPSR2 */ ++ A19_MARK, DACK1_MARK, SCIFA1_TXD_C_MARK, ++ SCIFB1_TXD_C_MARK, SCIFB1_SCK_B_MARK, ++ A20_MARK, SPCLK_MARK, ++ A21_MARK, ATAWR0_N_B_MARK, MOSI_IO0_MARK, ++ A22_MARK, MISO_IO1_MARK, FMCLK_B_MARK, TX0_MARK, SCIFA0_TXD_MARK, ++ A23_MARK, IO2_MARK, BPFCLK_B_MARK, RX0_MARK, SCIFA0_RXD_MARK, ++ A24_MARK, DREQ2_MARK, IO3_MARK, TX1_MARK, SCIFA1_TXD_MARK, ++ A25_MARK, DACK2_MARK, SSL_MARK, DREQ1_C_MARK, ++ RX1_MARK, SCIFA1_RXD_MARK, ++ CS0_N_MARK, ATAG0_N_B_MARK, SCL1_MARK, ++ CS1_N_A26_MARK, ATADIR0_N_B_MARK, SDA1_MARK, ++ EX_CS1_N_MARK, MSIOF2_SCK_MARK, ++ EX_CS2_N_MARK, ATAWR0_N_MARK, MSIOF2_SYNC_MARK, ++ EX_CS3_N_MARK, ATADIR0_N_MARK, MSIOF2_TXD_MARK, ++ ATAG0_N_MARK, EX_WAIT1_MARK, ++ ++ /* IPSR3 */ ++ EX_CS4_N_MARK, ATARD0_N_MARK, MSIOF2_RXD_MARK, EX_WAIT2_MARK, ++ EX_CS5_N_MARK, ATACS00_N_MARK, MSIOF2_SS1_MARK, HRX1_B_MARK, ++ SCIFB1_RXD_B_MARK, PWM1_MARK, TPU_TO1_MARK, ++ BS_N_MARK, ATACS10_N_MARK, MSIOF2_SS2_MARK, HTX1_B_MARK, ++ SCIFB1_TXD_B_MARK, PWM2_MARK, TPU_TO2_MARK, ++ RD_WR_N_MARK, HRX2_B_MARK, FMIN_B_MARK, ++ SCIFB0_RXD_B_MARK, DREQ1_D_MARK, ++ WE0_N_MARK, HCTS2_N_B_MARK, SCIFB0_TXD_B_MARK, ++ WE1_N_MARK, ATARD0_N_B_MARK, HTX2_B_MARK, SCIFB0_RTS_N_B_MARK, ++ EX_WAIT0_MARK, HRTS2_N_B_MARK, SCIFB0_CTS_N_B_MARK, ++ DREQ0_MARK, PWM3_MARK, TPU_TO3_MARK, ++ DACK0_MARK, DRACK0_MARK, REMOCON_MARK, ++ SPEEDIN_MARK, HSCK0_C_MARK, HSCK2_C_MARK, SCIFB0_SCK_B_MARK, ++ SCIFB2_SCK_B_MARK, DREQ2_C_MARK, HTX2_D_MARK, ++ SSI_SCK0129_MARK, HRX0_C_MARK, HRX2_C_MARK, ++ SCIFB0_RXD_C_MARK, SCIFB2_RXD_C_MARK, ++ SSI_WS0129_MARK, HTX0_C_MARK, HTX2_C_MARK, ++ SCIFB0_TXD_C_MARK, SCIFB2_TXD_C_MARK, ++ ++ /* IPSR4 */ ++ SSI_SDATA0_MARK, SCL0_B_MARK, SCL7_B_MARK, MSIOF2_SCK_C_MARK, ++ SSI_SCK1_MARK, SDA0_B_MARK, SDA7_B_MARK, ++ MSIOF2_SYNC_C_MARK, GLO_I0_D_MARK, ++ SSI_WS1_MARK, SCL1_B_MARK, SCL8_B_MARK, ++ MSIOF2_TXD_C_MARK, GLO_I1_D_MARK, ++ SSI_SDATA1_MARK, SDA1_B_MARK, SDA8_B_MARK, MSIOF2_RXD_C_MARK, ++ SSI_SCK2_MARK, SCL2_MARK, GPS_CLK_B_MARK, GLO_Q0_D_MARK, HSCK1_E_MARK, ++ SSI_WS2_MARK, SDA2_MARK, GPS_SIGN_B_MARK, RX2_E_MARK, ++ GLO_Q1_D_MARK, HCTS1_N_E_MARK, ++ SSI_SDATA2_MARK, GPS_MAG_B_MARK, TX2_E_MARK, HRTS1_N_E_MARK, ++ SSI_SCK34_MARK, SSI_WS34_MARK, SSI_SDATA3_MARK, ++ SSI_SCK4_MARK, GLO_SS_D_MARK, ++ SSI_WS4_MARK, GLO_RFON_D_MARK, ++ SSI_SDATA4_MARK, MSIOF2_SCK_D_MARK, ++ SSI_SCK5_MARK, MSIOF1_SCK_C_MARK, TS_SDATA0_MARK, GLO_I0_MARK, ++ MSIOF2_SYNC_D_MARK, VI1_R2_B_MARK, ++ ++ /* IPSR5 */ ++ SSI_WS5_MARK, MSIOF1_SYNC_C_MARK, TS_SCK0_MARK, GLO_I1_MARK, ++ MSIOF2_TXD_D_MARK, VI1_R3_B_MARK, ++ SSI_SDATA5_MARK, MSIOF1_TXD_C_MARK, TS_SDEN0_MARK, GLO_Q0_MARK, ++ MSIOF2_SS1_D_MARK, VI1_R4_B_MARK, ++ SSI_SCK6_MARK, MSIOF1_RXD_C_MARK, TS_SPSYNC0_MARK, GLO_Q1_MARK, ++ MSIOF2_RXD_D_MARK, VI1_R5_B_MARK, ++ SSI_WS6_MARK, GLO_SCLK_MARK, MSIOF2_SS2_D_MARK, VI1_R6_B_MARK, ++ SSI_SDATA6_MARK, STP_IVCXO27_0_B_MARK, GLO_SDATA_MARK, VI1_R7_B_MARK, ++ SSI_SCK78_MARK, STP_ISCLK_0_B_MARK, GLO_SS_MARK, ++ SSI_WS78_MARK, TX0_D_MARK, STP_ISD_0_B_MARK, GLO_RFON_MARK, ++ SSI_SDATA7_MARK, RX0_D_MARK, STP_ISEN_0_B_MARK, ++ SSI_SDATA8_MARK, TX1_D_MARK, STP_ISSYNC_0_B_MARK, ++ SSI_SCK9_MARK, RX1_D_MARK, GLO_SCLK_D_MARK, ++ SSI_WS9_MARK, TX3_D_MARK, CAN0_TX_D_MARK, GLO_SDATA_D_MARK, ++ SSI_SDATA9_MARK, RX3_D_MARK, CAN0_RX_D_MARK, ++ ++ /* IPSR6 */ ++ AUDIO_CLKB_MARK, STP_OPWM_0_B_MARK, MSIOF1_SCK_B_MARK, ++ SCIF_CLK_MARK, BPFCLK_E_MARK, ++ AUDIO_CLKC_MARK, SCIFB0_SCK_C_MARK, MSIOF1_SYNC_B_MARK, RX2_MARK, ++ SCIFA2_RXD_MARK, FMIN_E_MARK, ++ AUDIO_CLKOUT_MARK, MSIOF1_SS1_B_MARK, TX2_MARK, SCIFA2_TXD_MARK, ++ IRQ0_MARK, SCIFB1_RXD_D_MARK, INTC_IRQ0_N_MARK, ++ IRQ1_MARK, SCIFB1_SCK_C_MARK, INTC_IRQ1_N_MARK, ++ IRQ2_MARK, SCIFB1_TXD_D_MARK, INTC_IRQ2_N_MARK, ++ IRQ3_MARK, SCL4_C_MARK, MSIOF2_TXD_E_MARK, INTC_IRQ3_N_MARK, ++ IRQ4_MARK, HRX1_C_MARK, SDA4_C_MARK, ++ MSIOF2_RXD_E_MARK, INTC_IRQ4_N_MARK, ++ IRQ5_MARK, HTX1_C_MARK, SCL1_E_MARK, MSIOF2_SCK_E_MARK, ++ IRQ6_MARK, HSCK1_C_MARK, MSIOF1_SS2_B_MARK, ++ SDA1_E_MARK, MSIOF2_SYNC_E_MARK, ++ IRQ7_MARK, HCTS1_N_C_MARK, MSIOF1_TXD_B_MARK, ++ GPS_CLK_C_MARK, GPS_CLK_D_MARK, ++ IRQ8_MARK, HRTS1_N_C_MARK, MSIOF1_RXD_B_MARK, ++ GPS_SIGN_C_MARK, GPS_SIGN_D_MARK, ++ ++ /* IPSR7 */ ++ IRQ9_MARK, DU1_DOTCLKIN_B_MARK, CAN_CLK_D_MARK, GPS_MAG_C_MARK, ++ SCIF_CLK_B_MARK, GPS_MAG_D_MARK, ++ DU1_DR0_MARK, LCDOUT0_MARK, VI1_DATA0_B_MARK, TX0_B_MARK, ++ SCIFA0_TXD_B_MARK, MSIOF2_SCK_B_MARK, ++ DU1_DR1_MARK, LCDOUT1_MARK, VI1_DATA1_B_MARK, RX0_B_MARK, ++ SCIFA0_RXD_B_MARK, MSIOF2_SYNC_B_MARK, ++ DU1_DR2_MARK, LCDOUT2_MARK, SSI_SCK0129_B_MARK, ++ DU1_DR3_MARK, LCDOUT3_MARK, SSI_WS0129_B_MARK, ++ DU1_DR4_MARK, LCDOUT4_MARK, SSI_SDATA0_B_MARK, ++ DU1_DR5_MARK, LCDOUT5_MARK, SSI_SCK1_B_MARK, ++ DU1_DR6_MARK, LCDOUT6_MARK, SSI_WS1_B_MARK, ++ DU1_DR7_MARK, LCDOUT7_MARK, SSI_SDATA1_B_MARK, ++ DU1_DG0_MARK, LCDOUT8_MARK, VI1_DATA2_B_MARK, TX1_B_MARK, ++ SCIFA1_TXD_B_MARK, MSIOF2_SS1_B_MARK, ++ DU1_DG1_MARK, LCDOUT9_MARK, VI1_DATA3_B_MARK, RX1_B_MARK, ++ SCIFA1_RXD_B_MARK, MSIOF2_SS2_B_MARK, ++ DU1_DG2_MARK, LCDOUT10_MARK, VI1_DATA4_B_MARK, SCIF1_SCK_B_MARK, ++ SCIFA1_SCK_MARK, SSI_SCK78_B_MARK, ++ ++ /* IPSR8 */ ++ DU1_DG3_MARK, LCDOUT11_MARK, VI1_DATA5_B_MARK, SSI_WS78_B_MARK, ++ DU1_DG4_MARK, LCDOUT12_MARK, VI1_DATA6_B_MARK, HRX0_B_MARK, ++ SCIFB2_RXD_B_MARK, SSI_SDATA7_B_MARK, ++ DU1_DG5_MARK, LCDOUT13_MARK, VI1_DATA7_B_MARK, HCTS0_N_B_MARK, ++ SCIFB2_TXD_B_MARK, SSI_SDATA8_B_MARK, ++ DU1_DG6_MARK, LCDOUT14_MARK, HRTS0_N_B_MARK, ++ SCIFB2_CTS_N_B_MARK, SSI_SCK9_B_MARK, ++ DU1_DG7_MARK, LCDOUT15_MARK, HTX0_B_MARK, ++ SCIFB2_RTS_N_B_MARK, SSI_WS9_B_MARK, ++ DU1_DB0_MARK, LCDOUT16_MARK, VI1_CLK_B_MARK, TX2_B_MARK, ++ SCIFA2_TXD_B_MARK, MSIOF2_TXD_B_MARK, ++ DU1_DB1_MARK, LCDOUT17_MARK, VI1_HSYNC_N_B_MARK, RX2_B_MARK, ++ SCIFA2_RXD_B_MARK, MSIOF2_RXD_B_MARK, ++ DU1_DB2_MARK, LCDOUT18_MARK, VI1_VSYNC_N_B_MARK, SCIF2_SCK_B_MARK, ++ SCIFA2_SCK_MARK, SSI_SDATA9_B_MARK, ++ DU1_DB3_MARK, LCDOUT19_MARK, VI1_CLKENB_B_MARK, ++ DU1_DB4_MARK, LCDOUT20_MARK, VI1_FIELD_B_MARK, CAN1_RX_MARK, ++ DU1_DB5_MARK, LCDOUT21_MARK, TX3_MARK, SCIFA3_TXD_MARK, CAN1_TX_MARK, ++ ++ /* IPSR9 */ ++ DU1_DB6_MARK, LCDOUT22_MARK, SCL3_C_MARK, RX3_MARK, SCIFA3_RXD_MARK, ++ DU1_DB7_MARK, LCDOUT23_MARK, SDA3_C_MARK, ++ SCIF3_SCK_MARK, SCIFA3_SCK_MARK, ++ DU1_DOTCLKIN_MARK, QSTVA_QVS_MARK, ++ DU1_DOTCLKOUT0_MARK, QCLK_MARK, ++ DU1_DOTCLKOUT1_MARK, QSTVB_QVE_MARK, CAN0_TX_MARK, ++ TX3_B_MARK, SCL2_B_MARK, PWM4_MARK, ++ DU1_EXHSYNC_DU1_HSYNC_MARK, QSTH_QHS_MARK, ++ DU1_EXVSYNC_DU1_VSYNC_MARK, QSTB_QHE_MARK, ++ DU1_EXODDF_DU1_ODDF_DISP_CDE_MARK, QCPV_QDE_MARK, ++ CAN0_RX_MARK, RX3_B_MARK, SDA2_B_MARK, ++ DU1_DISP_MARK, QPOLA_MARK, ++ DU1_CDE_MARK, QPOLB_MARK, PWM4_B_MARK, ++ VI0_CLKENB_MARK, TX4_MARK, SCIFA4_TXD_MARK, TS_SDATA0_D_MARK, ++ VI0_FIELD_MARK, RX4_MARK, SCIFA4_RXD_MARK, TS_SCK0_D_MARK, ++ VI0_HSYNC_N_MARK, TX5_MARK, SCIFA5_TXD_MARK, TS_SDEN0_D_MARK, ++ VI0_VSYNC_N_MARK, RX5_MARK, SCIFA5_RXD_MARK, TS_SPSYNC0_D_MARK, ++ VI0_DATA3_VI0_B3_MARK, SCIF3_SCK_B_MARK, SCIFA3_SCK_B_MARK, ++ VI0_G0_MARK, SCL8_MARK, STP_IVCXO27_0_C_MARK, SCL4_MARK, ++ HCTS2_N_MARK, SCIFB2_CTS_N_MARK, ATAWR1_N_MARK, ++ ++ /* IPSR10 */ ++ VI0_G1_MARK, SDA8_MARK, STP_ISCLK_0_C_MARK, SDA4_MARK, ++ HRTS2_N_MARK, SCIFB2_RTS_N_MARK, ATADIR1_N_MARK, ++ VI0_G2_MARK, VI2_HSYNC_N_MARK, STP_ISD_0_C_MARK, SCL3_B_MARK, ++ HSCK2_MARK, SCIFB2_SCK_MARK, ATARD1_N_MARK, ++ VI0_G3_MARK, VI2_VSYNC_N_MARK, STP_ISEN_0_C_MARK, SDA3_B_MARK, ++ HRX2_MARK, SCIFB2_RXD_MARK, ATACS01_N_MARK, ++ VI0_G4_MARK, VI2_CLKENB_MARK, STP_ISSYNC_0_C_MARK, ++ HTX2_MARK, SCIFB2_TXD_MARK, SCIFB0_SCK_D_MARK, ++ VI0_G5_MARK, VI2_FIELD_MARK, STP_OPWM_0_C_MARK, FMCLK_D_MARK, ++ CAN0_TX_E_MARK, HTX1_D_MARK, SCIFB0_TXD_D_MARK, ++ VI0_G6_MARK, VI2_CLK_MARK, BPFCLK_D_MARK, ++ VI0_G7_MARK, VI2_DATA0_MARK, FMIN_D_MARK, ++ VI0_R0_MARK, VI2_DATA1_MARK, GLO_I0_B_MARK, ++ TS_SDATA0_C_MARK, ATACS11_N_MARK, ++ VI0_R1_MARK, VI2_DATA2_MARK, GLO_I1_B_MARK, ++ TS_SCK0_C_MARK, ATAG1_N_MARK, ++ VI0_R2_MARK, VI2_DATA3_MARK, GLO_Q0_B_MARK, TS_SDEN0_C_MARK, ++ VI0_R3_MARK, VI2_DATA4_MARK, GLO_Q1_B_MARK, TS_SPSYNC0_C_MARK, ++ VI0_R4_MARK, VI2_DATA5_MARK, GLO_SCLK_B_MARK, TX0_C_MARK, SCL1_D_MARK, ++ ++ /* IPSR11 */ ++ VI0_R5_MARK, VI2_DATA6_MARK, GLO_SDATA_B_MARK, RX0_C_MARK, SDA1_D_MARK, ++ VI0_R6_MARK, VI2_DATA7_MARK, GLO_SS_B_MARK, TX1_C_MARK, SCL4_B_MARK, ++ VI0_R7_MARK, GLO_RFON_B_MARK, RX1_C_MARK, CAN0_RX_E_MARK, ++ SDA4_B_MARK, HRX1_D_MARK, SCIFB0_RXD_D_MARK, ++ VI1_HSYNC_N_MARK, AVB_RXD0_MARK, TS_SDATA0_B_MARK, ++ TX4_B_MARK, SCIFA4_TXD_B_MARK, ++ VI1_VSYNC_N_MARK, AVB_RXD1_MARK, TS_SCK0_B_MARK, ++ RX4_B_MARK, SCIFA4_RXD_B_MARK, ++ VI1_CLKENB_MARK, AVB_RXD2_MARK, TS_SDEN0_B_MARK, ++ VI1_FIELD_MARK, AVB_RXD3_MARK, TS_SPSYNC0_B_MARK, ++ VI1_CLK_MARK, AVB_RXD4_MARK, VI1_DATA0_MARK, AVB_RXD5_MARK, ++ VI1_DATA1_MARK, AVB_RXD6_MARK, VI1_DATA2_MARK, AVB_RXD7_MARK, ++ VI1_DATA3_MARK, AVB_RX_ER_MARK, VI1_DATA4_MARK, AVB_MDIO_MARK, ++ VI1_DATA5_MARK, AVB_RX_DV_MARK, VI1_DATA6_MARK, AVB_MAGIC_MARK, ++ VI1_DATA7_MARK, AVB_MDC_MARK, ++ ETH_MDIO_MARK, AVB_RX_CLK_MARK, SCL2_C_MARK, ++ ETH_CRS_DV_MARK, AVB_LINK_MARK, SDA2_C_MARK, ++ ++ /* IPSR12 */ ++ ETH_RX_ER_MARK, AVB_CRS_MARK, SCL3_MARK, SCL7_MARK, ++ ETH_RXD0_MARK, AVB_PHY_INT_MARK, SDA3_MARK, SDA7_MARK, ++ ETH_RXD1_MARK, AVB_GTXREFCLK_MARK, CAN0_TX_C_MARK, ++ SCL2_D_MARK, MSIOF1_RXD_E_MARK, ++ ETH_LINK_MARK, AVB_TXD0_MARK, CAN0_RX_C_MARK, ++ SDA2_D_MARK, MSIOF1_SCK_E_MARK, ++ ETH_REFCLK_MARK, AVB_TXD1_MARK, SCIFA3_RXD_B_MARK, ++ CAN1_RX_C_MARK, MSIOF1_SYNC_E_MARK, ++ ETH_TXD1_MARK, AVB_TXD2_MARK, SCIFA3_TXD_B_MARK, ++ CAN1_TX_C_MARK, MSIOF1_TXD_E_MARK, ++ ETH_TX_EN_MARK, AVB_TXD3_MARK, TCLK1_B_MARK, CAN_CLK_B_MARK, ++ ETH_MAGIC_MARK, AVB_TXD4_MARK, IETX_C_MARK, ++ ETH_TXD0_MARK, AVB_TXD5_MARK, IECLK_C_MARK, ++ ETH_MDC_MARK, AVB_TXD6_MARK, IERX_C_MARK, ++ STP_IVCXO27_0_MARK, AVB_TXD7_MARK, SCIFB2_TXD_D_MARK, ++ ADIDATA_B_MARK, MSIOF0_SYNC_C_MARK, ++ STP_ISCLK_0_MARK, AVB_TX_EN_MARK, SCIFB2_RXD_D_MARK, ++ ADICS_SAMP_B_MARK, MSIOF0_SCK_C_MARK, ++ ++ /* IPSR13 */ ++ STP_ISD_0_MARK, AVB_TX_ER_MARK, SCIFB2_SCK_C_MARK, ++ ADICLK_B_MARK, MSIOF0_SS1_C_MARK, ++ STP_ISEN_0_MARK, AVB_TX_CLK_MARK, ADICHS0_B_MARK, MSIOF0_SS2_C_MARK, ++ STP_ISSYNC_0_MARK, AVB_COL_MARK, ADICHS1_B_MARK, MSIOF0_RXD_C_MARK, ++ STP_OPWM_0_MARK, AVB_GTX_CLK_MARK, PWM0_B_MARK, ++ ADICHS2_B_MARK, MSIOF0_TXD_C_MARK, ++ SD0_CLK_MARK, SPCLK_B_MARK, SD0_CMD_MARK, MOSI_IO0_B_MARK, ++ SD0_DATA0_MARK, MISO_IO1_B_MARK, SD0_DATA1_MARK, IO2_B_MARK, ++ SD0_DATA2_MARK, IO3_B_MARK, SD0_DATA3_MARK, SSL_B_MARK, ++ SD0_CD_MARK, MMC_D6_B_MARK, SIM0_RST_B_MARK, CAN0_RX_F_MARK, ++ SCIFA5_TXD_B_MARK, TX3_C_MARK, ++ SD0_WP_MARK, MMC_D7_B_MARK, SIM0_D_B_MARK, CAN0_TX_F_MARK, ++ SCIFA5_RXD_B_MARK, RX3_C_MARK, ++ SD1_CMD_MARK, REMOCON_B_MARK, SD1_DATA0_MARK, SPEEDIN_B_MARK, ++ SD1_DATA1_MARK, IETX_B_MARK, SD1_DATA2_MARK, IECLK_B_MARK, ++ SD1_DATA3_MARK, IERX_B_MARK, ++ SD1_CD_MARK, PWM0_MARK, TPU_TO0_MARK, SCL1_C_MARK, ++ ++ /* IPSR14 */ ++ SD1_WP_MARK, PWM1_B_MARK, SDA1_C_MARK, ++ SD2_CLK_MARK, MMC_CLK_MARK, SD2_CMD_MARK, MMC_CMD_MARK, ++ SD2_DATA0_MARK, MMC_D0_MARK, SD2_DATA1_MARK, MMC_D1_MARK, ++ SD2_DATA2_MARK, MMC_D2_MARK, SD2_DATA3_MARK, MMC_D3_MARK, ++ SD2_CD_MARK, MMC_D4_MARK, SCL8_C_MARK, TX5_B_MARK, SCIFA5_TXD_C_MARK, ++ SD2_WP_MARK, MMC_D5_MARK, SDA8_C_MARK, RX5_B_MARK, SCIFA5_RXD_C_MARK, ++ MSIOF0_SCK_MARK, RX2_C_MARK, ADIDATA_MARK, ++ VI1_CLK_C_MARK, VI1_G0_B_MARK, ++ MSIOF0_SYNC_MARK, TX2_C_MARK, ADICS_SAMP_MARK, ++ VI1_CLKENB_C_MARK, VI1_G1_B_MARK, ++ MSIOF0_TXD_MARK, ADICLK_MARK, VI1_FIELD_C_MARK, VI1_G2_B_MARK, ++ MSIOF0_RXD_MARK, ADICHS0_MARK, VI1_DATA0_C_MARK, VI1_G3_B_MARK, ++ MSIOF0_SS1_MARK, MMC_D6_MARK, ADICHS1_MARK, TX0_E_MARK, ++ VI1_HSYNC_N_C_MARK, SCL7_C_MARK, VI1_G4_B_MARK, ++ MSIOF0_SS2_MARK, MMC_D7_MARK, ADICHS2_MARK, RX0_E_MARK, ++ VI1_VSYNC_N_C_MARK, SDA7_C_MARK, VI1_G5_B_MARK, ++ ++ /* IPSR15 */ ++ SIM0_RST_MARK, IETX_MARK, CAN1_TX_D_MARK, ++ SIM0_CLK_MARK, IECLK_MARK, CAN_CLK_C_MARK, ++ SIM0_D_MARK, IERX_MARK, CAN1_RX_D_MARK, ++ GPS_CLK_MARK, DU1_DOTCLKIN_C_MARK, AUDIO_CLKB_B_MARK, ++ PWM5_B_MARK, SCIFA3_TXD_C_MARK, ++ GPS_SIGN_MARK, TX4_C_MARK, SCIFA4_TXD_C_MARK, PWM5_MARK, ++ VI1_G6_B_MARK, SCIFA3_RXD_C_MARK, ++ GPS_MAG_MARK, RX4_C_MARK, SCIFA4_RXD_C_MARK, PWM6_MARK, ++ VI1_G7_B_MARK, SCIFA3_SCK_C_MARK, ++ HCTS0_N_MARK, SCIFB0_CTS_N_MARK, GLO_I0_C_MARK, ++ TCLK1_MARK, VI1_DATA1_C_MARK, ++ HRTS0_N_MARK, SCIFB0_RTS_N_MARK, GLO_I1_C_MARK, VI1_DATA2_C_MARK, ++ HSCK0_MARK, SCIFB0_SCK_MARK, GLO_Q0_C_MARK, CAN_CLK_MARK, ++ TCLK2_MARK, VI1_DATA3_C_MARK, ++ HRX0_MARK, SCIFB0_RXD_MARK, GLO_Q1_C_MARK, ++ CAN0_RX_B_MARK, VI1_DATA4_C_MARK, ++ HTX0_MARK, SCIFB0_TXD_MARK, GLO_SCLK_C_MARK, ++ CAN0_TX_B_MARK, VI1_DATA5_C_MARK, ++ ++ /* IPSR16 */ ++ HRX1_MARK, SCIFB1_RXD_MARK, VI1_R0_B_MARK, ++ GLO_SDATA_C_MARK, VI1_DATA6_C_MARK, ++ HTX1_MARK, SCIFB1_TXD_MARK, VI1_R1_B_MARK, ++ GLO_SS_C_MARK, VI1_DATA7_C_MARK, ++ HSCK1_MARK, SCIFB1_SCK_MARK, MLB_CK_MARK, GLO_RFON_C_MARK, ++ HCTS1_N_MARK, SCIFB1_CTS_N_MARK, MLB_SIG_MARK, CAN1_TX_B_MARK, ++ HRTS1_N_MARK, SCIFB1_RTS_N_MARK, MLB_DAT_MARK, CAN1_RX_B_MARK, ++ PINMUX_MARK_END, ++}; ++ ++static const u16 pinmux_data[] = { ++ PINMUX_DATA_GP_ALL(), /* PINMUX_DATA(GP_M_N_DATA, GP_M_N_FN...), */ ++ ++ PINMUX_DATA(EX_CS0_N_MARK, FN_EX_CS0_N), ++ PINMUX_DATA(RD_N_MARK, FN_RD_N), ++ PINMUX_DATA(AUDIO_CLKA_MARK, FN_AUDIO_CLKA), ++ PINMUX_DATA(VI0_CLK_MARK, FN_VI0_CLK), ++ PINMUX_DATA(VI0_DATA0_VI0_B0_MARK, FN_VI0_DATA0_VI0_B0), ++ PINMUX_DATA(VI0_DATA1_VI0_B1_MARK, FN_VI0_DATA1_VI0_B1), ++ PINMUX_DATA(VI0_DATA2_VI0_B2_MARK, FN_VI0_DATA2_VI0_B2), ++ PINMUX_DATA(VI0_DATA4_VI0_B4_MARK, FN_VI0_DATA4_VI0_B4), ++ PINMUX_DATA(VI0_DATA5_VI0_B5_MARK, FN_VI0_DATA5_VI0_B5), ++ PINMUX_DATA(VI0_DATA6_VI0_B6_MARK, FN_VI0_DATA6_VI0_B6), ++ PINMUX_DATA(VI0_DATA7_VI0_B7_MARK, FN_VI0_DATA7_VI0_B7), ++ PINMUX_DATA(USB0_PWEN_MARK, FN_USB0_PWEN), ++ PINMUX_DATA(USB0_OVC_MARK, FN_USB0_OVC), ++ PINMUX_DATA(USB1_PWEN_MARK, FN_USB1_PWEN), ++ PINMUX_DATA(USB1_OVC_MARK, FN_USB1_OVC), ++ PINMUX_DATA(DU0_DOTCLKIN_MARK, FN_DU0_DOTCLKIN), ++ ++ /* IPSR0 */ ++ PINMUX_IPSR_DATA(IP0_0, D0), ++ PINMUX_IPSR_DATA(IP0_1, D1), ++ PINMUX_IPSR_DATA(IP0_2, D2), ++ PINMUX_IPSR_DATA(IP0_3, D3), ++ PINMUX_IPSR_DATA(IP0_4, D4), ++ PINMUX_IPSR_DATA(IP0_5, D5), ++ PINMUX_IPSR_DATA(IP0_6, D6), ++ PINMUX_IPSR_DATA(IP0_7, D7), ++ PINMUX_IPSR_DATA(IP0_8, D8), ++ PINMUX_IPSR_DATA(IP0_9, D9), ++ PINMUX_IPSR_DATA(IP0_10, D10), ++ PINMUX_IPSR_DATA(IP0_11, D11), ++ PINMUX_IPSR_DATA(IP0_12, D12), ++ PINMUX_IPSR_DATA(IP0_13, D13), ++ PINMUX_IPSR_DATA(IP0_14, D14), ++ PINMUX_IPSR_DATA(IP0_15, D15), ++ PINMUX_IPSR_DATA(IP0_18_16, A0), ++ PINMUX_IPSR_MODSEL_DATA(IP0_18_16, ATAWR0_N_C, SEL_LBS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP0_18_16, MSIOF0_SCK_B, SEL_SOF0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP0_18_16, SCL0_C, SEL_IIC0_2), ++ PINMUX_IPSR_DATA(IP0_18_16, PWM2_B), ++ PINMUX_IPSR_DATA(IP0_20_19, A1), ++ PINMUX_IPSR_MODSEL_DATA(IP0_20_19, MSIOF0_SYNC_B, SEL_SOF0_1), ++ PINMUX_IPSR_DATA(IP0_22_21, A2), ++ PINMUX_IPSR_MODSEL_DATA(IP0_22_21, MSIOF0_SS1_B, SEL_SOF0_1), ++ PINMUX_IPSR_DATA(IP0_24_23, A3), ++ PINMUX_IPSR_MODSEL_DATA(IP0_24_23, MSIOF0_SS2_B, SEL_SOF0_1), ++ PINMUX_IPSR_DATA(IP0_26_25, A4), ++ PINMUX_IPSR_MODSEL_DATA(IP0_26_25, MSIOF0_TXD_B, SEL_SOF0_1), ++ PINMUX_IPSR_DATA(IP0_28_27, A5), ++ PINMUX_IPSR_MODSEL_DATA(IP0_28_27, MSIOF0_RXD_B, SEL_SOF0_1), ++ PINMUX_IPSR_DATA(IP0_30_29, A6), ++ PINMUX_IPSR_MODSEL_DATA(IP0_30_29, MSIOF1_SCK, SEL_SOF1_0), ++ ++ /* IPSR1 */ ++ PINMUX_IPSR_DATA(IP1_1_0, A7), ++ PINMUX_IPSR_MODSEL_DATA(IP1_1_0, MSIOF1_SYNC, SEL_SOF1_0), ++ PINMUX_IPSR_DATA(IP1_3_2, A8), ++ PINMUX_IPSR_MODSEL_DATA(IP1_3_2, MSIOF1_SS1, SEL_SOF1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP1_3_2, SCL0, SEL_IIC0_0), ++ PINMUX_IPSR_DATA(IP1_5_4, A9), ++ PINMUX_IPSR_MODSEL_DATA(IP1_5_4, MSIOF1_SS2, SEL_SOF1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP1_5_4, SDA0, SEL_IIC0_0), ++ PINMUX_IPSR_DATA(IP1_7_6, A10), ++ PINMUX_IPSR_MODSEL_DATA(IP1_7_6, MSIOF1_TXD, SEL_SOF1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP1_7_6, MSIOF1_TXD_D, SEL_SOF1_3), ++ PINMUX_IPSR_DATA(IP1_10_8, A11), ++ PINMUX_IPSR_MODSEL_DATA(IP1_10_8, MSIOF1_RXD, SEL_SOF1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP1_10_8, SCL3_D, SEL_IIC3_3), ++ PINMUX_IPSR_MODSEL_DATA(IP1_10_8, MSIOF1_RXD_D, SEL_SOF1_3), ++ PINMUX_IPSR_DATA(IP1_13_11, A12), ++ PINMUX_IPSR_MODSEL_DATA(IP1_13_11, FMCLK, SEL_FM_0), ++ PINMUX_IPSR_MODSEL_DATA(IP1_13_11, SDA3_D, SEL_IIC3_3), ++ PINMUX_IPSR_MODSEL_DATA(IP1_13_11, MSIOF1_SCK_D, SEL_SOF1_3), ++ PINMUX_IPSR_DATA(IP1_16_14, A13), ++ PINMUX_IPSR_MODSEL_DATA(IP1_16_14, ATAG0_N_C, SEL_LBS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP1_16_14, BPFCLK, SEL_FM_0), ++ PINMUX_IPSR_MODSEL_DATA(IP1_16_14, MSIOF1_SS1_D, SEL_SOF1_3), ++ PINMUX_IPSR_DATA(IP1_19_17, A14), ++ PINMUX_IPSR_MODSEL_DATA(IP1_19_17, ATADIR0_N_C, SEL_LBS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP1_19_17, FMIN, SEL_FM_0), ++ PINMUX_IPSR_MODSEL_DATA(IP1_19_17, FMIN_C, SEL_FM_2), ++ PINMUX_IPSR_MODSEL_DATA(IP1_19_17, MSIOF1_SYNC_D, SEL_SOF1_3), ++ PINMUX_IPSR_DATA(IP1_22_20, A15), ++ PINMUX_IPSR_MODSEL_DATA(IP1_22_20, BPFCLK_C, SEL_FM_2), ++ PINMUX_IPSR_DATA(IP1_25_23, A16), ++ PINMUX_IPSR_MODSEL_DATA(IP1_25_23, DREQ2_B, SEL_LBS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP1_25_23, FMCLK_C, SEL_FM_2), ++ PINMUX_IPSR_MODSEL_DATA(IP1_25_23, SCIFA1_SCK_B, SEL_SCIFA1_1), ++ PINMUX_IPSR_DATA(IP1_28_26, A17), ++ PINMUX_IPSR_MODSEL_DATA(IP1_28_26, DACK2_B, SEL_LBS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP1_28_26, SDA0_C, SEL_IIC0_2), ++ PINMUX_IPSR_DATA(IP1_31_29, A18), ++ PINMUX_IPSR_MODSEL_DATA(IP1_31_29, DREQ1, SEL_LBS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP1_31_29, SCIFA1_RXD_C, SEL_SCIFA1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP1_31_29, SCIFB1_RXD_C, SEL_SCIFB1_2), ++ ++ /* IPSR2 */ ++ PINMUX_IPSR_DATA(IP2_2_0, A19), ++ PINMUX_IPSR_DATA(IP2_2_0, DACK1), ++ PINMUX_IPSR_MODSEL_DATA(IP2_2_0, SCIFA1_TXD_C, SEL_SCIFA1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP2_2_0, SCIFB1_TXD_C, SEL_SCIFB1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP2_2_0, SCIFB1_SCK_B, SEL_SCIFB1_0), ++ PINMUX_IPSR_DATA(IP2_2_0, A20), ++ PINMUX_IPSR_MODSEL_DATA(IP2_4_3, SPCLK, SEL_QSP_0), ++ PINMUX_IPSR_DATA(IP2_6_5, A21), ++ PINMUX_IPSR_MODSEL_DATA(IP2_6_5, ATAWR0_N_B, SEL_LBS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP2_6_5, MOSI_IO0, SEL_QSP_0), ++ PINMUX_IPSR_DATA(IP2_9_7, A22), ++ PINMUX_IPSR_MODSEL_DATA(IP2_9_7, MISO_IO1, SEL_QSP_0), ++ PINMUX_IPSR_MODSEL_DATA(IP2_9_7, FMCLK_B, SEL_FM_1), ++ PINMUX_IPSR_MODSEL_DATA(IP2_9_7, TX0, SEL_SCIF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP2_9_7, SCIFA0_TXD, SEL_SCFA_0), ++ PINMUX_IPSR_DATA(IP2_12_10, A23), ++ PINMUX_IPSR_MODSEL_DATA(IP2_12_10, IO2, SEL_QSP_0), ++ PINMUX_IPSR_MODSEL_DATA(IP2_12_10, BPFCLK_B, SEL_FM_1), ++ PINMUX_IPSR_MODSEL_DATA(IP2_12_10, RX0, SEL_SCIF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP2_12_10, SCIFA0_RXD, SEL_SCFA_0), ++ PINMUX_IPSR_DATA(IP2_15_13, A24), ++ PINMUX_IPSR_MODSEL_DATA(IP2_15_13, DREQ2, SEL_LBS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP2_15_13, IO3, SEL_QSP_0), ++ PINMUX_IPSR_MODSEL_DATA(IP2_15_13, TX1, SEL_SCIF1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP2_15_13, SCIFA1_TXD, SEL_SCIFA1_0), ++ PINMUX_IPSR_DATA(IP2_18_16, A25), ++ PINMUX_IPSR_MODSEL_DATA(IP2_18_16, DACK2, SEL_LBS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP2_18_16, SSL, SEL_QSP_0), ++ PINMUX_IPSR_MODSEL_DATA(IP2_18_16, DREQ1_C, SEL_LBS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP2_18_16, RX1, SEL_SCIF1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP2_18_16, SCIFA1_RXD, SEL_SCIFA1_0), ++ PINMUX_IPSR_DATA(IP2_20_19, CS0_N), ++ PINMUX_IPSR_MODSEL_DATA(IP2_20_19, ATAG0_N_B, SEL_LBS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP2_20_19, SCL1, SEL_IIC1_0), ++ PINMUX_IPSR_DATA(IP2_22_21, CS1_N_A26), ++ PINMUX_IPSR_MODSEL_DATA(IP2_22_21, ATADIR0_N_B, SEL_LBS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP2_22_21, SDA1, SEL_IIC1_0), ++ PINMUX_IPSR_DATA(IP2_24_23, EX_CS1_N), ++ PINMUX_IPSR_MODSEL_DATA(IP2_24_23, MSIOF2_SCK, SEL_SOF2_0), ++ PINMUX_IPSR_DATA(IP2_26_25, EX_CS2_N), ++ PINMUX_IPSR_MODSEL_DATA(IP2_26_25, ATAWR0_N, SEL_LBS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP2_26_25, MSIOF2_SYNC, SEL_SOF2_0), ++ PINMUX_IPSR_DATA(IP2_29_27, EX_CS3_N), ++ PINMUX_IPSR_MODSEL_DATA(IP2_29_27, ATADIR0_N, SEL_LBS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP2_29_27, MSIOF2_TXD, SEL_SOF2_0), ++ PINMUX_IPSR_MODSEL_DATA(IP2_29_27, ATAG0_N, SEL_LBS_0), ++ PINMUX_IPSR_DATA(IP2_29_27, EX_WAIT1), ++ ++ /* IPSR3 */ ++ PINMUX_IPSR_DATA(IP3_2_0, EX_CS4_N), ++ PINMUX_IPSR_MODSEL_DATA(IP3_2_0, ATARD0_N, SEL_LBS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP3_2_0, MSIOF2_RXD, SEL_SOF2_0), ++ PINMUX_IPSR_DATA(IP3_2_0, EX_WAIT2), ++ PINMUX_IPSR_DATA(IP3_5_3, EX_CS5_N), ++ PINMUX_IPSR_DATA(IP3_5_3, ATACS00_N), ++ PINMUX_IPSR_MODSEL_DATA(IP3_5_3, MSIOF2_SS1, SEL_SOF2_0), ++ PINMUX_IPSR_MODSEL_DATA(IP3_5_3, HRX1_B, SEL_HSCIF1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP3_5_3, SCIFB1_RXD_B, SEL_SCIFB1_1), ++ PINMUX_IPSR_DATA(IP3_5_3, PWM1), ++ PINMUX_IPSR_DATA(IP3_5_3, TPU_TO1), ++ PINMUX_IPSR_DATA(IP3_8_6, BS_N), ++ PINMUX_IPSR_DATA(IP3_8_6, ATACS10_N), ++ PINMUX_IPSR_MODSEL_DATA(IP3_8_6, MSIOF2_SS2, SEL_SOF2_0), ++ PINMUX_IPSR_MODSEL_DATA(IP3_8_6, HTX1_B, SEL_HSCIF1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP3_8_6, SCIFB1_TXD_B, SEL_SCIFB1_1), ++ PINMUX_IPSR_DATA(IP3_8_6, PWM2), ++ PINMUX_IPSR_DATA(IP3_8_6, TPU_TO2), ++ PINMUX_IPSR_DATA(IP3_11_9, RD_WR_N), ++ PINMUX_IPSR_MODSEL_DATA(IP3_11_9, HRX2_B, SEL_HSCIF2_1), ++ PINMUX_IPSR_MODSEL_DATA(IP3_11_9, FMIN_B, SEL_FM_1), ++ PINMUX_IPSR_MODSEL_DATA(IP3_11_9, SCIFB0_RXD_B, SEL_SCIFB_1), ++ PINMUX_IPSR_MODSEL_DATA(IP3_11_9, DREQ1_D, SEL_LBS_1), ++ PINMUX_IPSR_DATA(IP3_13_12, WE0_N), ++ PINMUX_IPSR_MODSEL_DATA(IP3_13_12, HCTS2_N_B, SEL_HSCIF2_1), ++ PINMUX_IPSR_MODSEL_DATA(IP3_13_12, SCIFB0_TXD_B, SEL_SCIFB_1), ++ PINMUX_IPSR_DATA(IP3_15_14, WE1_N), ++ PINMUX_IPSR_MODSEL_DATA(IP3_15_14, ATARD0_N_B, SEL_LBS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP3_15_14, HTX2_B, SEL_HSCIF2_1), ++ PINMUX_IPSR_MODSEL_DATA(IP3_15_14, SCIFB0_RTS_N_B, SEL_SCIFB_1), ++ PINMUX_IPSR_DATA(IP3_17_16, EX_WAIT0), ++ PINMUX_IPSR_MODSEL_DATA(IP3_17_16, HRTS2_N_B, SEL_HSCIF2_1), ++ PINMUX_IPSR_MODSEL_DATA(IP3_17_16, SCIFB0_CTS_N_B, SEL_SCIFB_1), ++ PINMUX_IPSR_DATA(IP3_19_18, DREQ0), ++ PINMUX_IPSR_DATA(IP3_19_18, PWM3), ++ PINMUX_IPSR_DATA(IP3_19_18, TPU_TO3), ++ PINMUX_IPSR_DATA(IP3_21_20, DACK0), ++ PINMUX_IPSR_DATA(IP3_21_20, DRACK0), ++ PINMUX_IPSR_MODSEL_DATA(IP3_21_20, REMOCON, SEL_RCN_0), ++ PINMUX_IPSR_MODSEL_DATA(IP3_24_22, SPEEDIN, SEL_RSP_0), ++ PINMUX_IPSR_MODSEL_DATA(IP3_24_22, HSCK0_C, SEL_HSCIF0_2), ++ PINMUX_IPSR_MODSEL_DATA(IP3_24_22, HSCK2_C, SEL_HSCIF2_2), ++ PINMUX_IPSR_MODSEL_DATA(IP3_24_22, SCIFB0_SCK_B, SEL_SCIFB_1), ++ PINMUX_IPSR_MODSEL_DATA(IP3_24_22, SCIFB2_SCK_B, SEL_SCIFB2_1), ++ PINMUX_IPSR_MODSEL_DATA(IP3_24_22, DREQ2_C, SEL_LBS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP3_30_28, HTX2_C, SEL_HSCIF2_2), ++ PINMUX_IPSR_MODSEL_DATA(IP3_27_25, SSI_SCK0129, SEL_SSI0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP3_27_25, HRX0_C, SEL_HSCIF0_2), ++ PINMUX_IPSR_MODSEL_DATA(IP3_27_25, HRX2_C, SEL_HSCIF2_2), ++ PINMUX_IPSR_MODSEL_DATA(IP3_27_25, SCIFB0_RXD_C, SEL_SCIFB_2), ++ PINMUX_IPSR_MODSEL_DATA(IP3_27_25, SCIFB2_RXD_C, SEL_SCIFB2_2), ++ PINMUX_IPSR_MODSEL_DATA(IP3_30_28, SSI_WS0129, SEL_SSI0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP3_30_28, HTX0_C, SEL_HSCIF0_2), ++ PINMUX_IPSR_MODSEL_DATA(IP3_30_28, HTX2_C, SEL_HSCIF2_2), ++ PINMUX_IPSR_MODSEL_DATA(IP3_30_28, SCIFB0_TXD_C, SEL_SCIFB_2), ++ PINMUX_IPSR_MODSEL_DATA(IP3_30_28, SCIFB2_TXD_C, SEL_SCIFB2_2), ++ ++ /* IPSR4 */ ++ PINMUX_IPSR_MODSEL_DATA(IP4_1_0, SSI_SDATA0, SEL_SSI0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP4_1_0, SCL0_B, SEL_IIC0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP4_1_0, SCL7_B, SEL_IIC7_1), ++ PINMUX_IPSR_MODSEL_DATA(IP4_1_0, MSIOF2_SCK_C, SEL_SOF2_2), ++ PINMUX_IPSR_MODSEL_DATA(IP4_4_2, SSI_SCK1, SEL_SSI1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP4_4_2, SDA0_B, SEL_IIC0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP4_4_2, SDA7_B, SEL_IIC7_1), ++ PINMUX_IPSR_MODSEL_DATA(IP4_4_2, MSIOF2_SYNC_C, SEL_SOF2_2), ++ PINMUX_IPSR_MODSEL_DATA(IP4_4_2, GLO_I0_D, SEL_GPS_3), ++ PINMUX_IPSR_MODSEL_DATA(IP4_7_5, SSI_WS1, SEL_SSI1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP4_7_5, SCL1_B, SEL_IIC1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP4_7_5, SCL8_B, SEL_IIC8_1), ++ PINMUX_IPSR_MODSEL_DATA(IP4_7_5, MSIOF2_TXD_C, SEL_SOF2_2), ++ PINMUX_IPSR_MODSEL_DATA(IP4_7_5, GLO_I1_D, SEL_GPS_3), ++ PINMUX_IPSR_MODSEL_DATA(IP4_9_8, SSI_SDATA1, SEL_SSI1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP4_9_8, SDA1_B, SEL_IIC1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP4_9_8, SDA8_B, SEL_IIC8_1), ++ PINMUX_IPSR_MODSEL_DATA(IP4_9_8, MSIOF2_RXD_C, SEL_SOF2_2), ++ PINMUX_IPSR_DATA(IP4_12_10, SSI_SCK2), ++ PINMUX_IPSR_MODSEL_DATA(IP4_12_10, SCL2, SEL_IIC2_0), ++ PINMUX_IPSR_MODSEL_DATA(IP4_12_10, GPS_CLK_B, SEL_GPS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP4_12_10, GLO_Q0_D, SEL_GPS_3), ++ PINMUX_IPSR_DATA(IP4_15_13, SSI_WS2), ++ PINMUX_IPSR_MODSEL_DATA(IP4_15_13, SDA2, SEL_IIC2_0), ++ PINMUX_IPSR_MODSEL_DATA(IP4_15_13, GPS_SIGN_B, SEL_GPS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP4_15_13, RX2_E, SEL_SCIF2_4), ++ PINMUX_IPSR_MODSEL_DATA(IP4_15_13, GLO_Q1_D, SEL_GPS_3), ++ PINMUX_IPSR_DATA(IP4_18_16, SSI_SDATA2), ++ PINMUX_IPSR_MODSEL_DATA(IP4_18_16, GPS_MAG_B, SEL_GPS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP4_18_16, TX2_E, SEL_SCIF2_4), ++ PINMUX_IPSR_DATA(IP4_19, SSI_SCK34), ++ PINMUX_IPSR_DATA(IP4_20, SSI_WS34), ++ PINMUX_IPSR_DATA(IP4_21, SSI_SDATA3), ++ PINMUX_IPSR_DATA(IP4_23_22, SSI_SCK4), ++ PINMUX_IPSR_MODSEL_DATA(IP4_23_22, GLO_SS_D, SEL_GPS_3), ++ PINMUX_IPSR_DATA(IP4_25_24, SSI_WS4), ++ PINMUX_IPSR_MODSEL_DATA(IP4_25_24, GLO_RFON_D, SEL_GPS_3), ++ PINMUX_IPSR_DATA(IP4_27_26, SSI_SDATA4), ++ PINMUX_IPSR_MODSEL_DATA(IP4_27_26, MSIOF2_SCK_D, SEL_SOF2_3), ++ PINMUX_IPSR_DATA(IP4_30_28, SSI_SCK5), ++ PINMUX_IPSR_MODSEL_DATA(IP4_30_28, MSIOF1_SCK_C, SEL_SOF1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP4_30_28, TS_SDATA0, SEL_TSIF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP4_30_28, GLO_I0, SEL_GPS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP4_30_28, MSIOF2_SYNC_D, SEL_SOF2_3), ++ PINMUX_IPSR_DATA(IP4_30_28, VI1_R2_B), ++ ++ /* IPSR5 */ ++ PINMUX_IPSR_DATA(IP5_2_0, SSI_WS5), ++ PINMUX_IPSR_MODSEL_DATA(IP5_2_0, MSIOF1_SYNC_C, SEL_SOF1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP5_2_0, TS_SCK0, SEL_TSIF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_2_0, GLO_I1, SEL_GPS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_2_0, MSIOF2_TXD_D, SEL_SOF2_3), ++ PINMUX_IPSR_DATA(IP5_2_0, VI1_R3_B), ++ PINMUX_IPSR_DATA(IP5_5_3, SSI_SDATA5), ++ PINMUX_IPSR_MODSEL_DATA(IP5_5_3, MSIOF1_TXD_C, SEL_SOF1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP5_5_3, TS_SDEN0, SEL_TSIF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_5_3, GLO_Q0, SEL_GPS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_5_3, MSIOF2_SS1_D, SEL_SOF2_3), ++ PINMUX_IPSR_DATA(IP5_5_3, VI1_R4_B), ++ PINMUX_IPSR_DATA(IP5_8_6, SSI_SCK6), ++ PINMUX_IPSR_MODSEL_DATA(IP5_8_6, MSIOF1_RXD_C, SEL_SOF1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP5_8_6, TS_SPSYNC0, SEL_TSIF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_8_6, GLO_Q1, SEL_GPS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_8_6, MSIOF2_RXD_D, SEL_SOF2_3), ++ PINMUX_IPSR_DATA(IP5_8_6, VI1_R5_B), ++ PINMUX_IPSR_DATA(IP5_11_9, SSI_WS6), ++ PINMUX_IPSR_MODSEL_DATA(IP5_11_9, GLO_SCLK, SEL_GPS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_11_9, MSIOF2_SS2_D, SEL_SOF2_3), ++ PINMUX_IPSR_DATA(IP5_11_9, VI1_R6_B), ++ PINMUX_IPSR_DATA(IP5_14_12, SSI_SDATA6), ++ PINMUX_IPSR_MODSEL_DATA(IP5_14_12, STP_IVCXO27_0_B, SEL_SSP_1), ++ PINMUX_IPSR_MODSEL_DATA(IP5_14_12, GLO_SDATA, SEL_GPS_0), ++ PINMUX_IPSR_DATA(IP5_14_12, VI1_R7_B), ++ PINMUX_IPSR_MODSEL_DATA(IP5_16_15, SSI_SCK78, SEL_SSI7_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_16_15, STP_ISCLK_0_B, SEL_SSP_1), ++ PINMUX_IPSR_MODSEL_DATA(IP5_16_15, GLO_SS, SEL_GPS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_19_17, SSI_WS78, SEL_SSI7_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_19_17, TX0_D, SEL_SCIF0_3), ++ PINMUX_IPSR_MODSEL_DATA(IP5_19_17, STP_ISD_0_B, SEL_SSP_1), ++ PINMUX_IPSR_MODSEL_DATA(IP5_19_17, GLO_RFON, SEL_GPS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_21_20, SSI_SDATA7, SEL_SSI7_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_21_20, RX0_D, SEL_SCIF0_3), ++ PINMUX_IPSR_MODSEL_DATA(IP5_21_20, STP_ISEN_0_B, SEL_SSP_1), ++ PINMUX_IPSR_MODSEL_DATA(IP5_23_22, SSI_SDATA8, SEL_SSI8_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_23_22, TX1_D, SEL_SCIF1_3), ++ PINMUX_IPSR_MODSEL_DATA(IP5_23_22, STP_ISSYNC_0_B, SEL_SSP_1), ++ PINMUX_IPSR_MODSEL_DATA(IP5_25_24, SSI_SCK9, SEL_SSI9_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_25_24, RX1_D, SEL_SCIF1_3), ++ PINMUX_IPSR_MODSEL_DATA(IP5_25_24, GLO_SCLK_D, SEL_GPS_3), ++ PINMUX_IPSR_MODSEL_DATA(IP5_28_26, SSI_WS9, SEL_SSI9_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_28_26, TX3_D, SEL_SCIF3_3), ++ PINMUX_IPSR_MODSEL_DATA(IP5_28_26, CAN0_TX_D, SEL_CAN0_3), ++ PINMUX_IPSR_MODSEL_DATA(IP5_28_26, GLO_SDATA_D, SEL_GPS_3), ++ PINMUX_IPSR_MODSEL_DATA(IP5_31_29, SSI_SDATA9, SEL_SSI9_0), ++ PINMUX_IPSR_MODSEL_DATA(IP5_31_29, RX3_D, SEL_SCIF3_3), ++ PINMUX_IPSR_MODSEL_DATA(IP5_31_29, CAN0_RX_D, SEL_CAN0_3), ++ ++ /* IPSR6 */ ++ PINMUX_IPSR_MODSEL_DATA(IP6_2_0, AUDIO_CLKB, SEL_ADG_0), ++ PINMUX_IPSR_MODSEL_DATA(IP6_2_0, STP_OPWM_0_B, SEL_SSP_1), ++ PINMUX_IPSR_MODSEL_DATA(IP6_2_0, MSIOF1_SCK_B, SEL_SOF1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP6_2_0, SCIF_CLK, SEL_SCIF_0), ++ PINMUX_IPSR_MODSEL_DATA(IP6_2_0, BPFCLK_E, SEL_FM_4), ++ PINMUX_IPSR_DATA(IP6_5_3, AUDIO_CLKC), ++ PINMUX_IPSR_MODSEL_DATA(IP6_5_3, SCIFB0_SCK_C, SEL_SCIFB_2), ++ PINMUX_IPSR_MODSEL_DATA(IP6_5_3, MSIOF1_SYNC_B, SEL_SOF1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP6_5_3, RX2, SEL_SCIF2_0), ++ PINMUX_IPSR_MODSEL_DATA(IP6_5_3, SCIFA2_RXD, SEL_SCIFA2_0), ++ PINMUX_IPSR_MODSEL_DATA(IP6_5_3, FMIN_E, SEL_FM_4), ++ PINMUX_IPSR_DATA(IP6_7_6, AUDIO_CLKOUT), ++ PINMUX_IPSR_MODSEL_DATA(IP6_7_6, MSIOF1_SS1_B, SEL_SOF1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP6_5_3, TX2, SEL_SCIF2_0), ++ PINMUX_IPSR_MODSEL_DATA(IP6_7_6, SCIFA2_TXD, SEL_SCIFA2_0), ++ PINMUX_IPSR_DATA(IP6_9_8, IRQ0), ++ PINMUX_IPSR_MODSEL_DATA(IP6_9_8, SCIFB1_RXD_D, SEL_SCIFB1_3), ++ PINMUX_IPSR_DATA(IP6_9_8, INTC_IRQ0_N), ++ PINMUX_IPSR_DATA(IP6_11_10, IRQ1), ++ PINMUX_IPSR_MODSEL_DATA(IP6_11_10, SCIFB1_SCK_C, SEL_SCIFB1_2), ++ PINMUX_IPSR_DATA(IP6_11_10, INTC_IRQ1_N), ++ PINMUX_IPSR_DATA(IP6_13_12, IRQ2), ++ PINMUX_IPSR_MODSEL_DATA(IP6_13_12, SCIFB1_TXD_D, SEL_SCIFB1_3), ++ PINMUX_IPSR_DATA(IP6_13_12, INTC_IRQ2_N), ++ PINMUX_IPSR_DATA(IP6_15_14, IRQ3), ++ PINMUX_IPSR_MODSEL_DATA(IP6_15_14, SCL4_C, SEL_IIC4_2), ++ PINMUX_IPSR_MODSEL_DATA(IP6_15_14, MSIOF2_TXD_E, SEL_SOF2_4), ++ PINMUX_IPSR_DATA(IP6_15_14, INTC_IRQ4_N), ++ PINMUX_IPSR_DATA(IP6_18_16, IRQ4), ++ PINMUX_IPSR_MODSEL_DATA(IP6_18_16, HRX1_C, SEL_HSCIF1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP6_18_16, SDA4_C, SEL_IIC4_2), ++ PINMUX_IPSR_MODSEL_DATA(IP6_18_16, MSIOF2_RXD_E, SEL_SOF2_4), ++ PINMUX_IPSR_DATA(IP6_18_16, INTC_IRQ4_N), ++ PINMUX_IPSR_DATA(IP6_20_19, IRQ5), ++ PINMUX_IPSR_MODSEL_DATA(IP6_20_19, HTX1_C, SEL_HSCIF1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP6_20_19, SCL1_E, SEL_IIC1_4), ++ PINMUX_IPSR_MODSEL_DATA(IP6_20_19, MSIOF2_SCK_E, SEL_SOF2_4), ++ PINMUX_IPSR_DATA(IP6_23_21, IRQ6), ++ PINMUX_IPSR_MODSEL_DATA(IP6_23_21, HSCK1_C, SEL_HSCIF1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP6_23_21, MSIOF1_SS2_B, SEL_SOF1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP6_23_21, SDA1_E, SEL_IIC1_4), ++ PINMUX_IPSR_MODSEL_DATA(IP6_23_21, MSIOF2_SYNC_E, SEL_SOF2_4), ++ PINMUX_IPSR_DATA(IP6_26_24, IRQ7), ++ PINMUX_IPSR_MODSEL_DATA(IP6_26_24, HCTS1_N_C, SEL_HSCIF1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP6_26_24, MSIOF1_TXD_B, SEL_SOF1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP6_26_24, GPS_CLK_C, SEL_GPS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP6_26_24, GPS_CLK_D, SEL_GPS_3), ++ PINMUX_IPSR_DATA(IP6_29_27, IRQ8), ++ PINMUX_IPSR_MODSEL_DATA(IP6_29_27, HRTS1_N_C, SEL_HSCIF1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP6_29_27, MSIOF1_RXD_B, SEL_SOF1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP6_29_27, GPS_SIGN_C, SEL_GPS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP6_29_27, GPS_SIGN_D, SEL_GPS_3), ++ ++ /* IPSR7 */ ++ PINMUX_IPSR_DATA(IP7_2_0, IRQ9), ++ PINMUX_IPSR_MODSEL_DATA(IP7_2_0, DU1_DOTCLKIN_B, SEL_DIS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_2_0, CAN_CLK_D, SEL_CANCLK_3), ++ PINMUX_IPSR_MODSEL_DATA(IP7_2_0, GPS_MAG_C, SEL_GPS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP7_2_0, SCIF_CLK_B, SEL_SCIF_1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_2_0, GPS_MAG_D, SEL_GPS_3), ++ PINMUX_IPSR_DATA(IP7_5_3, DU1_DR0), ++ PINMUX_IPSR_DATA(IP7_5_3, LCDOUT0), ++ PINMUX_IPSR_MODSEL_DATA(IP7_5_3, VI1_DATA0_B, SEL_VI1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_5_3, TX0_B, SEL_SCIF0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_5_3, SCIFA0_TXD_B, SEL_SCFA_1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_5_3, MSIOF2_SCK_B, SEL_SOF2_1), ++ PINMUX_IPSR_DATA(IP7_8_6, DU1_DR1), ++ PINMUX_IPSR_DATA(IP7_8_6, LCDOUT1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_8_6, VI1_DATA1_B, SEL_VI1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_8_6, RX0_B, SEL_SCIF0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_8_6, SCIFA0_RXD_B, SEL_SCFA_1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_8_6, MSIOF2_SYNC_B, SEL_SOF2_1), ++ PINMUX_IPSR_DATA(IP7_10_9, DU1_DR2), ++ PINMUX_IPSR_DATA(IP7_10_9, LCDOUT2), ++ PINMUX_IPSR_MODSEL_DATA(IP7_10_9, SSI_SCK0129_B, SEL_SSI0_1), ++ PINMUX_IPSR_DATA(IP7_12_11, DU1_DR3), ++ PINMUX_IPSR_DATA(IP7_12_11, LCDOUT3), ++ PINMUX_IPSR_MODSEL_DATA(IP7_12_11, SSI_WS0129_B, SEL_SSI0_1), ++ PINMUX_IPSR_DATA(IP7_14_13, DU1_DR4), ++ PINMUX_IPSR_DATA(IP7_14_13, LCDOUT4), ++ PINMUX_IPSR_MODSEL_DATA(IP7_14_13, SSI_SDATA0_B, SEL_SSI0_1), ++ PINMUX_IPSR_DATA(IP7_16_15, DU1_DR5), ++ PINMUX_IPSR_DATA(IP7_16_15, LCDOUT5), ++ PINMUX_IPSR_MODSEL_DATA(IP7_16_15, SSI_SCK1_B, SEL_SSI1_1), ++ PINMUX_IPSR_DATA(IP7_18_17, DU1_DR6), ++ PINMUX_IPSR_DATA(IP7_18_17, LCDOUT6), ++ PINMUX_IPSR_MODSEL_DATA(IP7_18_17, SSI_WS1_B, SEL_SSI1_1), ++ PINMUX_IPSR_DATA(IP7_20_19, DU1_DR7), ++ PINMUX_IPSR_DATA(IP7_20_19, LCDOUT7), ++ PINMUX_IPSR_MODSEL_DATA(IP7_20_19, SSI_SDATA1_B, SEL_SSI1_1), ++ PINMUX_IPSR_DATA(IP7_23_21, DU1_DG0), ++ PINMUX_IPSR_DATA(IP7_23_21, LCDOUT8), ++ PINMUX_IPSR_MODSEL_DATA(IP7_23_21, VI1_DATA2_B, SEL_VI1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_23_21, TX1_B, SEL_SCIF1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_23_21, SCIFA1_TXD_B, SEL_SCIFA1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_23_21, MSIOF2_SS1_B, SEL_SOF2_1), ++ PINMUX_IPSR_DATA(IP7_26_24, DU1_DG1), ++ PINMUX_IPSR_DATA(IP7_26_24, LCDOUT9), ++ PINMUX_IPSR_MODSEL_DATA(IP7_26_24, VI1_DATA3_B, SEL_VI1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_26_24, RX1_B, SEL_SCIF1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_26_24, SCIFA1_RXD_B, SEL_SCIFA1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP7_26_24, MSIOF2_SS2_B, SEL_SOF2_1), ++ PINMUX_IPSR_DATA(IP7_29_27, DU1_DG2), ++ PINMUX_IPSR_DATA(IP7_29_27, LCDOUT10), ++ PINMUX_IPSR_MODSEL_DATA(IP7_29_27, VI1_DATA4_B, SEL_VI1_1), ++ PINMUX_IPSR_DATA(IP7_29_27, SCIF1_SCK_B), ++ PINMUX_IPSR_MODSEL_DATA(IP7_29_27, SCIFA1_SCK, SEL_SCIFA1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP7_29_27, SSI_SCK78_B, SEL_SSI7_1), ++ ++ /* IPSR8 */ ++ PINMUX_IPSR_DATA(IP8_2_0, DU1_DG3), ++ PINMUX_IPSR_DATA(IP8_2_0, LCDOUT11), ++ PINMUX_IPSR_MODSEL_DATA(IP8_2_0, VI1_DATA5_B, SEL_VI1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_2_0, SSI_WS78_B, SEL_SSI7_1), ++ PINMUX_IPSR_DATA(IP8_5_3, DU1_DG4), ++ PINMUX_IPSR_DATA(IP8_5_3, LCDOUT12), ++ PINMUX_IPSR_MODSEL_DATA(IP8_5_3, VI1_DATA6_B, SEL_VI1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_5_3, HRX0_B, SEL_HSCIF0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_5_3, SCIFB2_RXD_B, SEL_SCIFB2_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_5_3, SSI_SDATA7_B, SEL_SSI7_1), ++ PINMUX_IPSR_DATA(IP8_8_6, DU1_DG5), ++ PINMUX_IPSR_DATA(IP8_8_6, LCDOUT13), ++ PINMUX_IPSR_MODSEL_DATA(IP8_8_6, VI1_DATA7_B, SEL_VI1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_8_6, HCTS0_N_B, SEL_HSCIF0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_8_6, SCIFB2_TXD_B, SEL_SCIFB2_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_8_6, SSI_SDATA8_B, SEL_SSI8_1), ++ PINMUX_IPSR_DATA(IP8_11_9, DU1_DG6), ++ PINMUX_IPSR_DATA(IP8_11_9, LCDOUT14), ++ PINMUX_IPSR_MODSEL_DATA(IP8_11_9, HRTS0_N_B, SEL_HSCIF0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_11_9, SCIFB2_CTS_N_B, SEL_SCIFB2_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_11_9, SSI_SCK9_B, SEL_SSI9_1), ++ PINMUX_IPSR_DATA(IP8_14_12, DU1_DG7), ++ PINMUX_IPSR_DATA(IP8_14_12, LCDOUT15), ++ PINMUX_IPSR_MODSEL_DATA(IP8_14_12, HTX0_B, SEL_HSCIF0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_14_12, SCIFB2_RTS_N_B, SEL_SCIFB2_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_14_12, SSI_WS9_B, SEL_SSI9_1), ++ PINMUX_IPSR_DATA(IP8_17_15, DU1_DB0), ++ PINMUX_IPSR_DATA(IP8_17_15, LCDOUT16), ++ PINMUX_IPSR_MODSEL_DATA(IP8_17_15, VI1_CLK_B, SEL_VI1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_17_15, TX2_B, SEL_SCIF2_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_17_15, SCIFA2_TXD_B, SEL_SCIFA2_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_17_15, MSIOF2_TXD_B, SEL_SOF2_1), ++ PINMUX_IPSR_DATA(IP8_20_18, DU1_DB1), ++ PINMUX_IPSR_DATA(IP8_20_18, LCDOUT17), ++ PINMUX_IPSR_MODSEL_DATA(IP8_20_18, VI1_HSYNC_N_B, SEL_VI1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_20_18, RX2_B, SEL_SCIF2_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_20_18, SCIFA2_RXD_B, SEL_SCIFA2_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_20_18, MSIOF2_RXD_B, SEL_SOF2_1), ++ PINMUX_IPSR_DATA(IP8_23_21, DU1_DB2), ++ PINMUX_IPSR_DATA(IP8_23_21, LCDOUT18), ++ PINMUX_IPSR_MODSEL_DATA(IP8_23_21, VI1_VSYNC_N_B, SEL_VI1_1), ++ PINMUX_IPSR_DATA(IP8_23_21, SCIF2_SCK_B), ++ PINMUX_IPSR_MODSEL_DATA(IP8_23_21, SCIFA2_SCK, SEL_SCIFA2_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_23_21, SSI_SDATA9_B, SEL_SSI9_1), ++ PINMUX_IPSR_DATA(IP8_25_24, DU1_DB3), ++ PINMUX_IPSR_DATA(IP8_25_24, LCDOUT19), ++ PINMUX_IPSR_MODSEL_DATA(IP8_25_24, VI1_CLKENB_B, SEL_VI1_1), ++ PINMUX_IPSR_DATA(IP8_27_26, DU1_DB4), ++ PINMUX_IPSR_DATA(IP8_27_26, LCDOUT20), ++ PINMUX_IPSR_MODSEL_DATA(IP8_27_26, VI1_FIELD_B, SEL_VI1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP8_27_26, CAN1_RX, SEL_CAN1_0), ++ PINMUX_IPSR_DATA(IP8_30_28, DU1_DB5), ++ PINMUX_IPSR_DATA(IP8_30_28, LCDOUT21), ++ PINMUX_IPSR_MODSEL_DATA(IP8_30_28, TX3, SEL_SCIF3_0), ++ PINMUX_IPSR_MODSEL_DATA(IP8_30_28, SCIFA3_TXD, SEL_SCIFA3_0), ++ PINMUX_IPSR_MODSEL_DATA(IP8_30_28, CAN1_TX, SEL_CAN1_0), ++ ++ /* IPSR9 */ ++ PINMUX_IPSR_DATA(IP9_2_0, DU1_DB6), ++ PINMUX_IPSR_DATA(IP9_2_0, LCDOUT22), ++ PINMUX_IPSR_MODSEL_DATA(IP9_2_0, SCL3_C, SEL_IIC3_2), ++ PINMUX_IPSR_MODSEL_DATA(IP9_2_0, RX3, SEL_SCIF3_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_2_0, SCIFA3_RXD, SEL_SCIFA3_0), ++ PINMUX_IPSR_DATA(IP9_5_3, DU1_DB7), ++ PINMUX_IPSR_DATA(IP9_5_3, LCDOUT23), ++ PINMUX_IPSR_MODSEL_DATA(IP9_5_3, SDA3_C, SEL_IIC3_2), ++ PINMUX_IPSR_MODSEL_DATA(IP9_5_3, SCIF3_SCK, SEL_SCIF3_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_5_3, SCIFA3_SCK, SEL_SCIFA3_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_6, DU1_DOTCLKIN, SEL_DIS_0), ++ PINMUX_IPSR_DATA(IP9_6, QSTVA_QVS), ++ PINMUX_IPSR_DATA(IP9_7, DU1_DOTCLKOUT0), ++ PINMUX_IPSR_DATA(IP9_7, QCLK), ++ PINMUX_IPSR_DATA(IP9_10_8, DU1_DOTCLKOUT1), ++ PINMUX_IPSR_DATA(IP9_10_8, QSTVB_QVE), ++ PINMUX_IPSR_MODSEL_DATA(IP9_10_8, CAN0_TX, SEL_CAN0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_10_8, TX3_B, SEL_SCIF3_1), ++ PINMUX_IPSR_MODSEL_DATA(IP9_10_8, SCL2_B, SEL_IIC2_1), ++ PINMUX_IPSR_DATA(IP9_10_8, PWM4), ++ PINMUX_IPSR_DATA(IP9_11, DU1_EXHSYNC_DU1_HSYNC), ++ PINMUX_IPSR_DATA(IP9_11, QSTH_QHS), ++ PINMUX_IPSR_DATA(IP9_12, DU1_EXVSYNC_DU1_VSYNC), ++ PINMUX_IPSR_DATA(IP9_12, QSTB_QHE), ++ PINMUX_IPSR_DATA(IP9_15_13, DU1_EXODDF_DU1_ODDF_DISP_CDE), ++ PINMUX_IPSR_DATA(IP9_15_13, QCPV_QDE), ++ PINMUX_IPSR_MODSEL_DATA(IP9_15_13, CAN0_RX, SEL_CAN0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_15_13, RX3_B, SEL_SCIF3_1), ++ PINMUX_IPSR_MODSEL_DATA(IP9_15_13, SDA2_B, SEL_IIC2_1), ++ PINMUX_IPSR_DATA(IP9_16, DU1_DISP), ++ PINMUX_IPSR_DATA(IP9_16, QPOLA), ++ PINMUX_IPSR_DATA(IP9_18_17, DU1_CDE), ++ PINMUX_IPSR_DATA(IP9_18_17, QPOLB), ++ PINMUX_IPSR_DATA(IP9_18_17, PWM4_B), ++ PINMUX_IPSR_DATA(IP9_20_19, VI0_CLKENB), ++ PINMUX_IPSR_MODSEL_DATA(IP9_20_19, TX4, SEL_SCIF4_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_20_19, SCIFA4_TXD, SEL_SCIFA4_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_20_19, TS_SDATA0_D, SEL_TSIF0_3), ++ PINMUX_IPSR_DATA(IP9_22_21, VI0_FIELD), ++ PINMUX_IPSR_MODSEL_DATA(IP9_22_21, RX4, SEL_SCIF4_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_22_21, SCIFA4_RXD, SEL_SCIFA4_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_22_21, TS_SCK0_D, SEL_TSIF0_3), ++ PINMUX_IPSR_DATA(IP9_24_23, VI0_HSYNC_N), ++ PINMUX_IPSR_MODSEL_DATA(IP9_24_23, TX5, SEL_SCIF5_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_24_23, SCIFA5_TXD, SEL_SCIFA5_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_24_23, TS_SDEN0_D, SEL_TSIF0_3), ++ PINMUX_IPSR_DATA(IP9_26_25, VI0_VSYNC_N), ++ PINMUX_IPSR_MODSEL_DATA(IP9_26_25, RX5, SEL_SCIF5_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_26_25, SCIFA5_RXD, SEL_SCIFA5_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_26_25, TS_SPSYNC0_D, SEL_TSIF0_3), ++ PINMUX_IPSR_DATA(IP9_28_27, VI0_DATA3_VI0_B3), ++ PINMUX_IPSR_MODSEL_DATA(IP9_28_27, SCIF3_SCK_B, SEL_SCIF3_1), ++ PINMUX_IPSR_MODSEL_DATA(IP9_28_27, SCIFA3_SCK_B, SEL_SCIFA3_1), ++ PINMUX_IPSR_DATA(IP9_31_29, VI0_G0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_31_29, SCL8, SEL_IIC8_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_31_29, STP_IVCXO27_0_C, SEL_SSP_2), ++ PINMUX_IPSR_MODSEL_DATA(IP9_31_29, SCL4, SEL_IIC4_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_31_29, HCTS2_N, SEL_HSCIF2_0), ++ PINMUX_IPSR_MODSEL_DATA(IP9_31_29, SCIFB2_CTS_N, SEL_SCIFB2_0), ++ PINMUX_IPSR_DATA(IP9_31_29, ATAWR1_N), ++ ++ /* IPSR10 */ ++ PINMUX_IPSR_DATA(IP10_2_0, VI0_G1), ++ PINMUX_IPSR_MODSEL_DATA(IP10_2_0, SDA8, SEL_IIC8_0), ++ PINMUX_IPSR_MODSEL_DATA(IP10_2_0, STP_ISCLK_0_C, SEL_SSP_2), ++ PINMUX_IPSR_MODSEL_DATA(IP10_2_0, SDA4, SEL_IIC4_0), ++ PINMUX_IPSR_MODSEL_DATA(IP10_2_0, HRTS2_N, SEL_HSCIF2_0), ++ PINMUX_IPSR_MODSEL_DATA(IP10_2_0, SCIFB2_RTS_N, SEL_SCIFB2_0), ++ PINMUX_IPSR_DATA(IP10_2_0, ATADIR1_N), ++ PINMUX_IPSR_DATA(IP10_5_3, VI0_G2), ++ PINMUX_IPSR_DATA(IP10_5_3, VI2_HSYNC_N), ++ PINMUX_IPSR_MODSEL_DATA(IP10_5_3, STP_ISD_0_C, SEL_SSP_2), ++ PINMUX_IPSR_MODSEL_DATA(IP10_5_3, SCL3_B, SEL_IIC3_1), ++ PINMUX_IPSR_MODSEL_DATA(IP10_5_3, HSCK2, SEL_HSCIF2_0), ++ PINMUX_IPSR_MODSEL_DATA(IP10_5_3, SCIFB2_SCK, SEL_SCIFB2_0), ++ PINMUX_IPSR_DATA(IP10_5_3, ATARD1_N), ++ PINMUX_IPSR_DATA(IP10_8_6, VI0_G3), ++ PINMUX_IPSR_DATA(IP10_8_6, VI2_VSYNC_N), ++ PINMUX_IPSR_MODSEL_DATA(IP10_8_6, STP_ISEN_0_C, SEL_SSP_2), ++ PINMUX_IPSR_MODSEL_DATA(IP10_8_6, SDA3_B, SEL_IIC3_1), ++ PINMUX_IPSR_MODSEL_DATA(IP10_8_6, HRX2, SEL_HSCIF2_0), ++ PINMUX_IPSR_MODSEL_DATA(IP10_8_6, SCIFB2_RXD, SEL_SCIFB2_0), ++ PINMUX_IPSR_DATA(IP10_8_6, ATACS01_N), ++ PINMUX_IPSR_DATA(IP10_11_9, VI0_G4), ++ PINMUX_IPSR_DATA(IP10_11_9, VI2_CLKENB), ++ PINMUX_IPSR_MODSEL_DATA(IP10_11_9, STP_ISSYNC_0_C, SEL_SSP_2), ++ PINMUX_IPSR_MODSEL_DATA(IP10_11_9, HTX2, SEL_HSCIF2_0), ++ PINMUX_IPSR_MODSEL_DATA(IP10_11_9, SCIFB2_TXD, SEL_SCIFB2_0), ++ PINMUX_IPSR_MODSEL_DATA(IP10_11_9, SCIFB0_SCK_D, SEL_SCIFB_3), ++ PINMUX_IPSR_DATA(IP10_14_12, VI0_G5), ++ PINMUX_IPSR_DATA(IP10_14_12, VI2_FIELD), ++ PINMUX_IPSR_MODSEL_DATA(IP10_14_12, STP_OPWM_0_C, SEL_SSP_2), ++ PINMUX_IPSR_MODSEL_DATA(IP10_14_12, FMCLK_D, SEL_FM_3), ++ PINMUX_IPSR_MODSEL_DATA(IP10_14_12, CAN0_TX_E, SEL_CAN0_4), ++ PINMUX_IPSR_MODSEL_DATA(IP10_14_12, HTX1_D, SEL_HSCIF1_3), ++ PINMUX_IPSR_MODSEL_DATA(IP10_14_12, SCIFB0_TXD_D, SEL_SCIFB_3), ++ PINMUX_IPSR_DATA(IP10_16_15, VI0_G6), ++ PINMUX_IPSR_DATA(IP10_16_15, VI2_CLK), ++ PINMUX_IPSR_MODSEL_DATA(IP10_16_15, BPFCLK_D, SEL_FM_3), ++ PINMUX_IPSR_DATA(IP10_18_17, VI0_G7), ++ PINMUX_IPSR_DATA(IP10_18_17, VI2_DATA0), ++ PINMUX_IPSR_MODSEL_DATA(IP10_18_17, FMIN_D, SEL_FM_3), ++ PINMUX_IPSR_DATA(IP10_21_19, VI0_R0), ++ PINMUX_IPSR_DATA(IP10_21_19, VI2_DATA1), ++ PINMUX_IPSR_MODSEL_DATA(IP10_21_19, GLO_I0_B, SEL_GPS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP10_21_19, TS_SDATA0_C, SEL_TSIF0_2), ++ PINMUX_IPSR_DATA(IP10_21_19, ATACS11_N), ++ PINMUX_IPSR_DATA(IP10_24_22, VI0_R1), ++ PINMUX_IPSR_DATA(IP10_24_22, VI2_DATA2), ++ PINMUX_IPSR_MODSEL_DATA(IP10_24_22, GLO_I1_B, SEL_GPS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP10_24_22, TS_SCK0_C, SEL_TSIF0_2), ++ PINMUX_IPSR_DATA(IP10_24_22, ATAG1_N), ++ PINMUX_IPSR_DATA(IP10_26_25, VI0_R2), ++ PINMUX_IPSR_DATA(IP10_26_25, VI2_DATA3), ++ PINMUX_IPSR_MODSEL_DATA(IP10_26_25, GLO_Q0_B, SEL_GPS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP10_26_25, TS_SDEN0_C, SEL_TSIF0_2), ++ PINMUX_IPSR_DATA(IP10_28_27, VI0_R3), ++ PINMUX_IPSR_DATA(IP10_28_27, VI2_DATA4), ++ PINMUX_IPSR_MODSEL_DATA(IP10_28_27, GLO_Q1_B, SEL_GPS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP10_28_27, TS_SPSYNC0_C, SEL_TSIF0_2), ++ PINMUX_IPSR_DATA(IP10_31_29, VI0_R4), ++ PINMUX_IPSR_DATA(IP10_31_29, VI2_DATA5), ++ PINMUX_IPSR_MODSEL_DATA(IP10_31_29, GLO_SCLK_B, SEL_GPS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP10_31_29, TX0_C, SEL_SCIF0_2), ++ PINMUX_IPSR_MODSEL_DATA(IP10_31_29, SCL1_D, SEL_IIC1_3), ++ ++ /* IPSR11 */ ++ PINMUX_IPSR_DATA(IP11_2_0, VI0_R5), ++ PINMUX_IPSR_DATA(IP11_2_0, VI2_DATA6), ++ PINMUX_IPSR_MODSEL_DATA(IP11_2_0, GLO_SDATA_B, SEL_GPS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP11_2_0, RX0_C, SEL_SCIF0_2), ++ PINMUX_IPSR_MODSEL_DATA(IP11_2_0, SDA1_D, SEL_IIC1_3), ++ PINMUX_IPSR_DATA(IP11_5_3, VI0_R6), ++ PINMUX_IPSR_DATA(IP11_5_3, VI2_DATA7), ++ PINMUX_IPSR_MODSEL_DATA(IP11_5_3, GLO_SS_B, SEL_GPS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP11_5_3, TX1_C, SEL_SCIF1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP11_5_3, SCL4_B, SEL_IIC4_1), ++ PINMUX_IPSR_DATA(IP11_8_6, VI0_R7), ++ PINMUX_IPSR_MODSEL_DATA(IP11_8_6, GLO_RFON_B, SEL_GPS_1), ++ PINMUX_IPSR_MODSEL_DATA(IP11_8_6, RX1_C, SEL_SCIF1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP11_8_6, CAN0_RX_E, SEL_CAN0_4), ++ PINMUX_IPSR_MODSEL_DATA(IP11_8_6, SDA4_B, SEL_IIC4_1), ++ PINMUX_IPSR_MODSEL_DATA(IP11_8_6, HRX1_D, SEL_HSCIF1_3), ++ PINMUX_IPSR_MODSEL_DATA(IP11_8_6, SCIFB0_RXD_D, SEL_SCIFB_3), ++ PINMUX_IPSR_MODSEL_DATA(IP11_11_9, VI1_HSYNC_N, SEL_VI1_0), ++ PINMUX_IPSR_DATA(IP11_11_9, AVB_RXD0), ++ PINMUX_IPSR_MODSEL_DATA(IP11_11_9, TS_SDATA0_B, SEL_TSIF0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP11_11_9, TX4_B, SEL_SCIF4_1), ++ PINMUX_IPSR_MODSEL_DATA(IP11_11_9, SCIFA4_TXD_B, SEL_SCIFA4_1), ++ PINMUX_IPSR_MODSEL_DATA(IP11_14_12, VI1_VSYNC_N, SEL_VI1_0), ++ PINMUX_IPSR_DATA(IP11_14_12, AVB_RXD1), ++ PINMUX_IPSR_MODSEL_DATA(IP11_14_12, TS_SCK0_B, SEL_TSIF0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP11_14_12, RX4_B, SEL_SCIF4_1), ++ PINMUX_IPSR_MODSEL_DATA(IP11_14_12, SCIFA4_RXD_B, SEL_SCIFA4_1), ++ PINMUX_IPSR_MODSEL_DATA(IP11_16_15, VI1_CLKENB, SEL_VI1_0), ++ PINMUX_IPSR_DATA(IP11_16_15, AVB_RXD2), ++ PINMUX_IPSR_MODSEL_DATA(IP11_16_15, TS_SDEN0_B, SEL_TSIF0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP11_18_17, VI1_FIELD, SEL_VI1_0), ++ PINMUX_IPSR_DATA(IP11_18_17, AVB_RXD3), ++ PINMUX_IPSR_MODSEL_DATA(IP11_18_17, TS_SPSYNC0_B, SEL_TSIF0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP11_19, VI1_CLK, SEL_VI1_0), ++ PINMUX_IPSR_DATA(IP11_19, AVB_RXD4), ++ PINMUX_IPSR_MODSEL_DATA(IP11_20, VI1_DATA0, SEL_VI1_0), ++ PINMUX_IPSR_DATA(IP11_20, AVB_RXD5), ++ PINMUX_IPSR_MODSEL_DATA(IP11_21, VI1_DATA1, SEL_VI1_0), ++ PINMUX_IPSR_DATA(IP11_21, AVB_RXD6), ++ PINMUX_IPSR_MODSEL_DATA(IP11_22, VI1_DATA2, SEL_VI1_0), ++ PINMUX_IPSR_DATA(IP11_22, AVB_RXD7), ++ PINMUX_IPSR_MODSEL_DATA(IP11_23, VI1_DATA3, SEL_VI1_0), ++ PINMUX_IPSR_DATA(IP11_23, AVB_RX_ER), ++ PINMUX_IPSR_MODSEL_DATA(IP11_24, VI1_DATA4, SEL_VI1_0), ++ PINMUX_IPSR_DATA(IP11_24, AVB_MDIO), ++ PINMUX_IPSR_MODSEL_DATA(IP11_25, VI1_DATA5, SEL_VI1_0), ++ PINMUX_IPSR_DATA(IP11_25, AVB_RX_DV), ++ PINMUX_IPSR_MODSEL_DATA(IP11_26, VI1_DATA6, SEL_VI1_0), ++ PINMUX_IPSR_DATA(IP11_26, AVB_MAGIC), ++ PINMUX_IPSR_MODSEL_DATA(IP11_27, VI1_DATA7, SEL_VI1_0), ++ PINMUX_IPSR_DATA(IP11_27, AVB_MDC), ++ PINMUX_IPSR_DATA(IP11_29_28, ETH_MDIO), ++ PINMUX_IPSR_DATA(IP11_29_28, AVB_RX_CLK), ++ PINMUX_IPSR_MODSEL_DATA(IP11_29_28, SCL2_C, SEL_IIC2_2), ++ PINMUX_IPSR_DATA(IP11_31_30, ETH_CRS_DV), ++ PINMUX_IPSR_DATA(IP11_31_30, AVB_LINK), ++ PINMUX_IPSR_MODSEL_DATA(IP11_31_30, SDA2_C, SEL_IIC2_2), ++ ++ /* IPSR12 */ ++ PINMUX_IPSR_DATA(IP12_1_0, ETH_RX_ER), ++ PINMUX_IPSR_DATA(IP12_1_0, AVB_CRS), ++ PINMUX_IPSR_MODSEL_DATA(IP12_1_0, SCL3, SEL_IIC3_0), ++ PINMUX_IPSR_MODSEL_DATA(IP12_1_0, SCL7, SEL_IIC7_0), ++ PINMUX_IPSR_DATA(IP12_3_2, ETH_RXD0), ++ PINMUX_IPSR_DATA(IP12_3_2, AVB_PHY_INT), ++ PINMUX_IPSR_MODSEL_DATA(IP12_3_2, SDA3, SEL_IIC3_0), ++ PINMUX_IPSR_MODSEL_DATA(IP12_3_2, SDA7, SEL_IIC7_0), ++ PINMUX_IPSR_DATA(IP12_6_4, ETH_RXD1), ++ PINMUX_IPSR_DATA(IP12_6_4, AVB_GTXREFCLK), ++ PINMUX_IPSR_MODSEL_DATA(IP12_6_4, CAN0_TX_C, SEL_CAN0_2), ++ PINMUX_IPSR_MODSEL_DATA(IP12_6_4, SCL2_D, SEL_IIC2_3), ++ PINMUX_IPSR_MODSEL_DATA(IP12_6_4, MSIOF1_RXD_E, SEL_SOF1_4), ++ PINMUX_IPSR_DATA(IP12_9_7, ETH_LINK), ++ PINMUX_IPSR_DATA(IP12_9_7, AVB_TXD0), ++ PINMUX_IPSR_MODSEL_DATA(IP12_9_7, CAN0_RX_C, SEL_CAN0_2), ++ PINMUX_IPSR_MODSEL_DATA(IP12_9_7, SDA2_D, SEL_IIC2_3), ++ PINMUX_IPSR_MODSEL_DATA(IP12_9_7, MSIOF1_SCK_E, SEL_SOF1_4), ++ PINMUX_IPSR_DATA(IP12_12_10, ETH_REFCLK), ++ PINMUX_IPSR_DATA(IP12_12_10, AVB_TXD1), ++ PINMUX_IPSR_MODSEL_DATA(IP12_12_10, SCIFA3_RXD_B, SEL_SCIFA3_1), ++ PINMUX_IPSR_MODSEL_DATA(IP12_12_10, CAN1_RX_C, SEL_CAN1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP12_12_10, MSIOF1_SYNC_E, SEL_SOF1_4), ++ PINMUX_IPSR_DATA(IP12_15_13, ETH_TXD1), ++ PINMUX_IPSR_DATA(IP12_15_13, AVB_TXD2), ++ PINMUX_IPSR_MODSEL_DATA(IP12_15_13, SCIFA3_TXD_B, SEL_SCIFA3_1), ++ PINMUX_IPSR_MODSEL_DATA(IP12_15_13, CAN1_TX_C, SEL_CAN1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP12_15_13, MSIOF1_TXD_E, SEL_SOF1_4), ++ PINMUX_IPSR_DATA(IP12_17_16, ETH_TX_EN), ++ PINMUX_IPSR_DATA(IP12_17_16, AVB_TXD3), ++ PINMUX_IPSR_MODSEL_DATA(IP12_17_16, TCLK1_B, SEL_TMU1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP12_17_16, CAN_CLK_B, SEL_CANCLK_1), ++ PINMUX_IPSR_DATA(IP12_19_18, ETH_MAGIC), ++ PINMUX_IPSR_DATA(IP12_19_18, AVB_TXD4), ++ PINMUX_IPSR_MODSEL_DATA(IP12_19_18, IETX_C, SEL_IEB_2), ++ PINMUX_IPSR_DATA(IP12_21_20, ETH_TXD0), ++ PINMUX_IPSR_DATA(IP12_21_20, AVB_TXD5), ++ PINMUX_IPSR_MODSEL_DATA(IP12_21_20, IECLK_C, SEL_IEB_2), ++ PINMUX_IPSR_DATA(IP12_23_22, ETH_MDC), ++ PINMUX_IPSR_DATA(IP12_23_22, AVB_TXD6), ++ PINMUX_IPSR_MODSEL_DATA(IP12_23_22, IERX_C, SEL_IEB_2), ++ PINMUX_IPSR_MODSEL_DATA(IP12_26_24, STP_IVCXO27_0, SEL_SSP_0), ++ PINMUX_IPSR_DATA(IP12_26_24, AVB_TXD7), ++ PINMUX_IPSR_MODSEL_DATA(IP12_26_24, SCIFB2_TXD_D, SEL_SCIFB2_3), ++ PINMUX_IPSR_MODSEL_DATA(IP12_26_24, ADIDATA_B, SEL_RAD_1), ++ PINMUX_IPSR_MODSEL_DATA(IP12_26_24, MSIOF0_SYNC_C, SEL_SOF0_2), ++ PINMUX_IPSR_MODSEL_DATA(IP12_29_27, STP_ISCLK_0, SEL_SSP_0), ++ PINMUX_IPSR_DATA(IP12_29_27, AVB_TX_EN), ++ PINMUX_IPSR_MODSEL_DATA(IP12_29_27, SCIFB2_RXD_D, SEL_SCIFB2_3), ++ PINMUX_IPSR_MODSEL_DATA(IP12_29_27, ADICS_SAMP_B, SEL_RAD_1), ++ PINMUX_IPSR_MODSEL_DATA(IP12_29_27, MSIOF0_SCK_C, SEL_SOF0_2), ++ ++ /* IPSR13 */ ++ PINMUX_IPSR_MODSEL_DATA(IP13_2_0, STP_ISD_0, SEL_SSP_0), ++ PINMUX_IPSR_DATA(IP13_2_0, AVB_TX_ER), ++ PINMUX_IPSR_MODSEL_DATA(IP13_2_0, SCIFB2_SCK_C, SEL_SCIFB2_2), ++ PINMUX_IPSR_MODSEL_DATA(IP13_2_0, ADICLK_B, SEL_RAD_1), ++ PINMUX_IPSR_MODSEL_DATA(IP13_2_0, MSIOF0_SS1_C, SEL_SOF0_2), ++ PINMUX_IPSR_MODSEL_DATA(IP13_4_3, STP_ISEN_0, SEL_SSP_0), ++ PINMUX_IPSR_DATA(IP13_4_3, AVB_TX_CLK), ++ PINMUX_IPSR_MODSEL_DATA(IP13_4_3, ADICHS0_B, SEL_RAD_1), ++ PINMUX_IPSR_MODSEL_DATA(IP13_4_3, MSIOF0_SS2_C, SEL_SOF0_2), ++ PINMUX_IPSR_MODSEL_DATA(IP13_6_5, STP_ISSYNC_0, SEL_SSP_0), ++ PINMUX_IPSR_DATA(IP13_6_5, AVB_COL), ++ PINMUX_IPSR_MODSEL_DATA(IP13_6_5, ADICHS1_B, SEL_RAD_1), ++ PINMUX_IPSR_MODSEL_DATA(IP13_6_5, MSIOF0_RXD_C, SEL_SOF0_2), ++ PINMUX_IPSR_MODSEL_DATA(IP13_9_7, STP_OPWM_0, SEL_SSP_0), ++ PINMUX_IPSR_DATA(IP13_9_7, AVB_GTX_CLK), ++ PINMUX_IPSR_DATA(IP13_9_7, PWM0_B), ++ PINMUX_IPSR_MODSEL_DATA(IP13_9_7, ADICHS2_B, SEL_RAD_1), ++ PINMUX_IPSR_MODSEL_DATA(IP13_9_7, MSIOF0_TXD_C, SEL_SOF0_2), ++ PINMUX_IPSR_DATA(IP13_10, SD0_CLK), ++ PINMUX_IPSR_MODSEL_DATA(IP13_10, SPCLK_B, SEL_QSP_1), ++ PINMUX_IPSR_DATA(IP13_11, SD0_CMD), ++ PINMUX_IPSR_MODSEL_DATA(IP13_11, MOSI_IO0_B, SEL_QSP_1), ++ PINMUX_IPSR_DATA(IP13_12, SD0_DATA0), ++ PINMUX_IPSR_MODSEL_DATA(IP13_12, MISO_IO1_B, SEL_QSP_1), ++ PINMUX_IPSR_DATA(IP13_13, SD0_DATA1), ++ PINMUX_IPSR_MODSEL_DATA(IP13_13, IO2_B, SEL_QSP_1), ++ PINMUX_IPSR_DATA(IP13_14, SD0_DATA2), ++ PINMUX_IPSR_MODSEL_DATA(IP13_14, IO3_B, SEL_QSP_1), ++ PINMUX_IPSR_DATA(IP13_15, SD0_DATA3), ++ PINMUX_IPSR_MODSEL_DATA(IP13_15, SSL_B, SEL_QSP_1), ++ PINMUX_IPSR_DATA(IP13_18_16, SD0_CD), ++ PINMUX_IPSR_MODSEL_DATA(IP13_18_16, MMC_D6_B, SEL_MMC_1), ++ PINMUX_IPSR_MODSEL_DATA(IP13_18_16, SIM0_RST_B, SEL_SIM_1), ++ PINMUX_IPSR_MODSEL_DATA(IP13_18_16, CAN0_RX_F, SEL_CAN0_5), ++ PINMUX_IPSR_MODSEL_DATA(IP13_18_16, SCIFA5_TXD_B, SEL_SCIFA5_1), ++ PINMUX_IPSR_MODSEL_DATA(IP13_18_16, TX3_C, SEL_SCIF3_2), ++ PINMUX_IPSR_DATA(IP13_21_19, SD0_WP), ++ PINMUX_IPSR_MODSEL_DATA(IP13_21_19, MMC_D7_B, SEL_MMC_1), ++ PINMUX_IPSR_MODSEL_DATA(IP13_21_19, SIM0_D_B, SEL_SIM_1), ++ PINMUX_IPSR_MODSEL_DATA(IP13_21_19, CAN0_TX_F, SEL_CAN0_5), ++ PINMUX_IPSR_MODSEL_DATA(IP13_21_19, SCIFA5_RXD_B, SEL_SCIFA5_1), ++ PINMUX_IPSR_MODSEL_DATA(IP13_21_19, RX3_C, SEL_SCIF3_2), ++ PINMUX_IPSR_DATA(IP13_22, SD1_CMD), ++ PINMUX_IPSR_MODSEL_DATA(IP13_22, REMOCON_B, SEL_RCN_1), ++ PINMUX_IPSR_DATA(IP13_24_23, SD1_DATA0), ++ PINMUX_IPSR_MODSEL_DATA(IP13_24_23, SPEEDIN_B, SEL_RSP_1), ++ PINMUX_IPSR_DATA(IP13_25, SD1_DATA1), ++ PINMUX_IPSR_MODSEL_DATA(IP13_25, IETX_B, SEL_IEB_1), ++ PINMUX_IPSR_DATA(IP13_26, SD1_DATA2), ++ PINMUX_IPSR_MODSEL_DATA(IP13_26, IECLK_B, SEL_IEB_1), ++ PINMUX_IPSR_DATA(IP13_27, SD1_DATA3), ++ PINMUX_IPSR_MODSEL_DATA(IP13_27, IERX_B, SEL_IEB_1), ++ PINMUX_IPSR_DATA(IP13_30_28, SD1_CD), ++ PINMUX_IPSR_DATA(IP13_30_28, PWM0), ++ PINMUX_IPSR_DATA(IP13_30_28, TPU_TO0), ++ PINMUX_IPSR_MODSEL_DATA(IP13_30_28, SCL1_C, SEL_IIC1_2), ++ ++ /* IPSR14 */ ++ PINMUX_IPSR_DATA(IP14_1_0, SD1_WP), ++ PINMUX_IPSR_DATA(IP14_1_0, PWM1_B), ++ PINMUX_IPSR_MODSEL_DATA(IP14_1_0, SDA1_C, SEL_IIC1_2), ++ PINMUX_IPSR_DATA(IP14_2, SD2_CLK), ++ PINMUX_IPSR_DATA(IP14_2, MMC_CLK), ++ PINMUX_IPSR_DATA(IP14_3, SD2_CMD), ++ PINMUX_IPSR_DATA(IP14_3, MMC_CMD), ++ PINMUX_IPSR_DATA(IP14_4, SD2_DATA0), ++ PINMUX_IPSR_DATA(IP14_4, MMC_D0), ++ PINMUX_IPSR_DATA(IP14_5, SD2_DATA1), ++ PINMUX_IPSR_DATA(IP14_5, MMC_D1), ++ PINMUX_IPSR_DATA(IP14_6, SD2_DATA2), ++ PINMUX_IPSR_DATA(IP14_6, MMC_D2), ++ PINMUX_IPSR_DATA(IP14_7, SD2_DATA3), ++ PINMUX_IPSR_DATA(IP14_7, MMC_D3), ++ PINMUX_IPSR_DATA(IP14_10_8, SD2_CD), ++ PINMUX_IPSR_DATA(IP14_10_8, MMC_D4), ++ PINMUX_IPSR_MODSEL_DATA(IP14_10_8, SCL8_C, SEL_IIC8_2), ++ PINMUX_IPSR_MODSEL_DATA(IP14_10_8, TX5_B, SEL_SCIF5_1), ++ PINMUX_IPSR_MODSEL_DATA(IP14_10_8, SCIFA5_TXD_C, SEL_SCIFA5_2), ++ PINMUX_IPSR_DATA(IP14_13_11, SD2_WP), ++ PINMUX_IPSR_DATA(IP14_13_11, MMC_D5), ++ PINMUX_IPSR_MODSEL_DATA(IP14_13_11, SDA8_C, SEL_IIC8_2), ++ PINMUX_IPSR_MODSEL_DATA(IP14_13_11, RX5_B, SEL_SCIF5_1), ++ PINMUX_IPSR_MODSEL_DATA(IP14_13_11, SCIFA5_RXD_C, SEL_SCIFA5_2), ++ PINMUX_IPSR_MODSEL_DATA(IP14_16_14, MSIOF0_SCK, SEL_SOF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP14_16_14, RX2_C, SEL_SCIF2_2), ++ PINMUX_IPSR_MODSEL_DATA(IP14_16_14, ADIDATA, SEL_RAD_0), ++ PINMUX_IPSR_MODSEL_DATA(IP14_16_14, VI1_CLK_C, SEL_VI1_2), ++ PINMUX_IPSR_DATA(IP14_16_14, VI1_G0_B), ++ PINMUX_IPSR_MODSEL_DATA(IP14_19_17, MSIOF0_SYNC, SEL_SOF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP14_19_17, TX2_C, SEL_SCIF2_2), ++ PINMUX_IPSR_MODSEL_DATA(IP14_19_17, ADICS_SAMP, SEL_RAD_0), ++ PINMUX_IPSR_MODSEL_DATA(IP14_19_17, VI1_CLKENB_C, SEL_VI1_2), ++ PINMUX_IPSR_DATA(IP14_19_17, VI1_G1_B), ++ PINMUX_IPSR_MODSEL_DATA(IP14_22_20, MSIOF0_TXD, SEL_SOF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP14_22_20, ADICLK, SEL_RAD_0), ++ PINMUX_IPSR_MODSEL_DATA(IP14_22_20, VI1_FIELD_C, SEL_VI1_2), ++ PINMUX_IPSR_DATA(IP14_22_20, VI1_G2_B), ++ PINMUX_IPSR_MODSEL_DATA(IP14_25_23, MSIOF0_RXD, SEL_SOF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP14_25_23, ADICHS0, SEL_RAD_0), ++ PINMUX_IPSR_MODSEL_DATA(IP14_25_23, VI1_DATA0_C, SEL_VI1_2), ++ PINMUX_IPSR_DATA(IP14_25_23, VI1_G3_B), ++ PINMUX_IPSR_MODSEL_DATA(IP14_28_26, MSIOF0_SS1, SEL_SOF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP14_28_26, MMC_D6, SEL_MMC_0), ++ PINMUX_IPSR_MODSEL_DATA(IP14_28_26, ADICHS1, SEL_RAD_0), ++ PINMUX_IPSR_MODSEL_DATA(IP14_28_26, TX0_E, SEL_SCIF0_4), ++ PINMUX_IPSR_MODSEL_DATA(IP14_28_26, VI1_HSYNC_N_C, SEL_VI1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP14_28_26, SCL7_C, SEL_IIC7_2), ++ PINMUX_IPSR_DATA(IP14_28_26, VI1_G4_B), ++ PINMUX_IPSR_MODSEL_DATA(IP14_31_29, MSIOF0_SS2, SEL_SOF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP14_31_29, MMC_D7, SEL_MMC_0), ++ PINMUX_IPSR_MODSEL_DATA(IP14_31_29, ADICHS2, SEL_RAD_0), ++ PINMUX_IPSR_MODSEL_DATA(IP14_31_29, RX0_E, SEL_SCIF0_4), ++ PINMUX_IPSR_MODSEL_DATA(IP14_31_29, VI1_VSYNC_N_C, SEL_VI1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP14_31_29, SDA7_C, SEL_IIC7_2), ++ PINMUX_IPSR_DATA(IP14_31_29, VI1_G5_B), ++ ++ /* IPSR15 */ ++ PINMUX_IPSR_MODSEL_DATA(IP15_1_0, SIM0_RST, SEL_SIM_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_1_0, IETX, SEL_IEB_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_1_0, CAN1_TX_D, SEL_CAN1_3), ++ PINMUX_IPSR_DATA(IP15_3_2, SIM0_CLK), ++ PINMUX_IPSR_MODSEL_DATA(IP15_3_2, IECLK, SEL_IEB_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_3_2, CAN_CLK_C, SEL_CANCLK_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_5_4, SIM0_D, SEL_SIM_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_5_4, IERX, SEL_IEB_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_5_4, CAN1_RX_D, SEL_CAN1_3), ++ PINMUX_IPSR_MODSEL_DATA(IP15_8_6, GPS_CLK, SEL_GPS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_8_6, DU1_DOTCLKIN_C, SEL_DIS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_8_6, AUDIO_CLKB_B, SEL_ADG_1), ++ PINMUX_IPSR_DATA(IP15_8_6, PWM5_B), ++ PINMUX_IPSR_MODSEL_DATA(IP15_8_6, SCIFA3_TXD_C, SEL_SCIFA3_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_11_9, GPS_SIGN, SEL_GPS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_11_9, TX4_C, SEL_SCIF4_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_11_9, SCIFA4_TXD_C, SEL_SCIFA4_2), ++ PINMUX_IPSR_DATA(IP15_11_9, PWM5), ++ PINMUX_IPSR_DATA(IP15_11_9, VI1_G6_B), ++ PINMUX_IPSR_MODSEL_DATA(IP15_11_9, SCIFA3_RXD_C, SEL_SCIFA3_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_14_12, GPS_MAG, SEL_GPS_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_14_12, RX4_C, SEL_SCIF4_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_14_12, SCIFA4_RXD_C, SEL_SCIFA4_2), ++ PINMUX_IPSR_DATA(IP15_14_12, PWM6), ++ PINMUX_IPSR_DATA(IP15_14_12, VI1_G7_B), ++ PINMUX_IPSR_MODSEL_DATA(IP15_14_12, SCIFA3_SCK_C, SEL_SCIFA3_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_17_15, HCTS0_N, SEL_HSCIF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_17_15, SCIFB0_CTS_N, SEL_SCIFB_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_17_15, GLO_I0_C, SEL_GPS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_17_15, TCLK1, SEL_TMU1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_17_15, VI1_DATA1_C, SEL_VI1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_20_18, HRTS0_N, SEL_HSCIF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_20_18, SCIFB0_RTS_N, SEL_SCIFB_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_20_18, GLO_I1_C, SEL_GPS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_20_18, VI1_DATA2_C, SEL_VI1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_23_21, HSCK0, SEL_HSCIF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_23_21, SCIFB0_SCK, SEL_SCIFB_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_23_21, GLO_Q0_C, SEL_GPS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_23_21, CAN_CLK, SEL_CANCLK_0), ++ PINMUX_IPSR_DATA(IP15_23_21, TCLK2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_23_21, VI1_DATA3_C, SEL_VI1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_26_24, HRX0, SEL_HSCIF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_26_24, SCIFB0_RXD, SEL_SCIFB_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_26_24, GLO_Q1_C, SEL_GPS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_26_24, CAN0_RX_B, SEL_CAN0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP15_26_24, VI1_DATA4_C, SEL_VI1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_29_27, HTX0, SEL_HSCIF0_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_29_27, SCIFB0_TXD, SEL_SCIFB_0), ++ PINMUX_IPSR_MODSEL_DATA(IP15_29_27, GLO_SCLK_C, SEL_GPS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP15_29_27, CAN0_TX_B, SEL_CAN0_1), ++ PINMUX_IPSR_MODSEL_DATA(IP15_29_27, VI1_DATA5_C, SEL_VI1_2), ++ ++ /* IPSR16 */ ++ PINMUX_IPSR_MODSEL_DATA(IP16_2_0, HRX1, SEL_HSCIF1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP16_2_0, SCIFB1_RXD, SEL_SCIFB1_0), ++ PINMUX_IPSR_DATA(IP16_2_0, VI1_R0_B), ++ PINMUX_IPSR_MODSEL_DATA(IP16_2_0, GLO_SDATA_C, SEL_GPS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP16_2_0, VI1_DATA6_C, SEL_VI1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP16_5_3, HTX1, SEL_HSCIF1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP16_5_3, SCIFB1_TXD, SEL_SCIFB1_0), ++ PINMUX_IPSR_DATA(IP16_5_3, VI1_R1_B), ++ PINMUX_IPSR_MODSEL_DATA(IP16_5_3, GLO_SS_C, SEL_GPS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP16_5_3, VI1_DATA7_C, SEL_VI1_2), ++ PINMUX_IPSR_MODSEL_DATA(IP16_7_6, HSCK1, SEL_HSCIF1_0), ++ PINMUX_IPSR_MODSEL_DATA(IP16_7_6, SCIFB1_SCK, SEL_SCIFB1_0), ++ PINMUX_IPSR_DATA(IP16_7_6, MLB_CK), ++ PINMUX_IPSR_MODSEL_DATA(IP16_7_6, GLO_RFON_C, SEL_GPS_2), ++ PINMUX_IPSR_MODSEL_DATA(IP16_9_8, HCTS1_N, SEL_HSCIF1_0), ++ PINMUX_IPSR_DATA(IP16_9_8, SCIFB1_CTS_N), ++ PINMUX_IPSR_DATA(IP16_9_8, MLB_SIG), ++ PINMUX_IPSR_MODSEL_DATA(IP16_9_8, CAN1_TX_B, SEL_CAN1_1), ++ PINMUX_IPSR_MODSEL_DATA(IP16_11_10, HRTS1_N, SEL_HSCIF1_0), ++ PINMUX_IPSR_DATA(IP16_11_10, SCIFB1_RTS_N), ++ PINMUX_IPSR_DATA(IP16_11_10, MLB_DAT), ++ PINMUX_IPSR_MODSEL_DATA(IP16_11_10, CAN1_RX_B, SEL_CAN1_1), ++}; ++ ++static struct sh_pfc_pin pinmux_pins[] = { ++ PINMUX_GPIO_GP_ALL(), ++}; ++ ++/* - DU --------------------------------------------------------------------- */ ++static const unsigned int du_rgb666_pins[] = { ++ /* R[7:2], G[7:2], B[7:2] */ ++ RCAR_GP_PIN(3, 7), RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 5), ++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 3), RCAR_GP_PIN(3, 2), ++ RCAR_GP_PIN(3, 15), RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 13), ++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 11), RCAR_GP_PIN(3, 10), ++ RCAR_GP_PIN(3, 23), RCAR_GP_PIN(3, 22), RCAR_GP_PIN(3, 21), ++ RCAR_GP_PIN(3, 20), RCAR_GP_PIN(3, 19), RCAR_GP_PIN(3, 18), ++}; ++static const unsigned int du_rgb666_mux[] = { ++ DU1_DR7_MARK, DU1_DR6_MARK, DU1_DR5_MARK, DU1_DR4_MARK, ++ DU1_DR3_MARK, DU1_DR2_MARK, ++ DU1_DG7_MARK, DU1_DG6_MARK, DU1_DG5_MARK, DU1_DG4_MARK, ++ DU1_DG3_MARK, DU1_DG2_MARK, ++ DU1_DB7_MARK, DU1_DB6_MARK, DU1_DB5_MARK, DU1_DB4_MARK, ++ DU1_DB3_MARK, DU1_DB2_MARK, ++}; ++static const unsigned int du_rgb888_pins[] = { ++ /* R[7:0], G[7:0], B[7:0] */ ++ RCAR_GP_PIN(3, 7), RCAR_GP_PIN(3, 6), RCAR_GP_PIN(3, 5), ++ RCAR_GP_PIN(3, 4), RCAR_GP_PIN(3, 3), RCAR_GP_PIN(3, 2), ++ RCAR_GP_PIN(3, 1), RCAR_GP_PIN(3, 0), ++ RCAR_GP_PIN(3, 15), RCAR_GP_PIN(3, 14), RCAR_GP_PIN(3, 13), ++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 11), RCAR_GP_PIN(3, 10), ++ RCAR_GP_PIN(3, 9), RCAR_GP_PIN(3, 8), ++ RCAR_GP_PIN(3, 23), RCAR_GP_PIN(3, 22), RCAR_GP_PIN(3, 21), ++ RCAR_GP_PIN(3, 20), RCAR_GP_PIN(3, 19), RCAR_GP_PIN(3, 18), ++ RCAR_GP_PIN(3, 17), RCAR_GP_PIN(3, 16), ++}; ++static const unsigned int du_rgb888_mux[] = { ++ DU1_DR7_MARK, DU1_DR6_MARK, DU1_DR5_MARK, DU1_DR4_MARK, ++ DU1_DR3_MARK, DU1_DR2_MARK, DU1_DR1_MARK, DU1_DR0_MARK, ++ DU1_DG7_MARK, DU1_DG6_MARK, DU1_DG5_MARK, DU1_DG4_MARK, ++ DU1_DG3_MARK, DU1_DG2_MARK, DU1_DG1_MARK, DU1_DG0_MARK, ++ DU1_DB7_MARK, DU1_DB6_MARK, DU1_DB5_MARK, DU1_DB4_MARK, ++ DU1_DB3_MARK, DU1_DB2_MARK, DU1_DB1_MARK, DU1_DB0_MARK, ++}; ++static const unsigned int du_clk_out_0_pins[] = { ++ /* CLKOUT */ ++ RCAR_GP_PIN(3, 25), ++}; ++static const unsigned int du_clk_out_0_mux[] = { ++ DU1_DOTCLKOUT0_MARK ++}; ++static const unsigned int du_clk_out_1_pins[] = { ++ /* CLKOUT */ ++ RCAR_GP_PIN(3, 26), ++}; ++static const unsigned int du_clk_out_1_mux[] = { ++ DU1_DOTCLKOUT1_MARK ++}; ++static const unsigned int du_sync_1_pins[] = { ++ /* EXVSYNC/VSYNC, EXHSYNC/HSYNC, EXDISP/EXODDF/EXCDE */ ++ RCAR_GP_PIN(3, 29), RCAR_GP_PIN(3, 28), RCAR_GP_PIN(3, 27), ++}; ++static const unsigned int du_sync_1_mux[] = { ++ DU1_EXODDF_DU1_ODDF_DISP_CDE_MARK, ++ DU1_EXVSYNC_DU1_VSYNC_MARK, DU1_EXHSYNC_DU1_HSYNC_MARK ++}; ++static const unsigned int du_cde_disp_pins[] = { ++ /* CDE DISP */ ++ RCAR_GP_PIN(3, 31), RCAR_GP_PIN(3, 30), ++}; ++static const unsigned int du0_clk_in_pins[] = { ++ /* CLKIN */ ++ RCAR_GP_PIN(6, 31), ++}; ++static const unsigned int du0_clk_in_mux[] = { ++ DU0_DOTCLKIN_MARK ++}; ++static const unsigned int du_cde_disp_mux[] = { ++ DU1_CDE_MARK, DU1_DISP_MARK ++}; ++static const unsigned int du1_clk_in_pins[] = { ++ /* CLKIN */ ++ RCAR_GP_PIN(7, 20), RCAR_GP_PIN(7, 19), RCAR_GP_PIN(3, 24), ++}; ++static const unsigned int du1_clk_in_mux[] = { ++ DU1_DOTCLKIN_C_MARK, DU1_DOTCLKIN_B_MARK, DU1_DOTCLKIN_MARK ++}; ++/* - ETH -------------------------------------------------------------------- */ ++static const unsigned int eth_link_pins[] = { ++ /* LINK */ ++ RCAR_GP_PIN(5, 18), ++}; ++static const unsigned int eth_link_mux[] = { ++ ETH_LINK_MARK, ++}; ++static const unsigned int eth_magic_pins[] = { ++ /* MAGIC */ ++ RCAR_GP_PIN(5, 22), ++}; ++static const unsigned int eth_magic_mux[] = { ++ ETH_MAGIC_MARK, ++}; ++static const unsigned int eth_mdio_pins[] = { ++ /* MDC, MDIO */ ++ RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 13), ++}; ++static const unsigned int eth_mdio_mux[] = { ++ ETH_MDC_MARK, ETH_MDIO_MARK, ++}; ++static const unsigned int eth_rmii_pins[] = { ++ /* RXD[0:1], RX_ER, CRS_DV, TXD[0:1], TX_EN, REF_CLK */ ++ RCAR_GP_PIN(5, 16), RCAR_GP_PIN(5, 17), RCAR_GP_PIN(5, 15), ++ RCAR_GP_PIN(5, 14), RCAR_GP_PIN(5, 23), RCAR_GP_PIN(5, 20), ++ RCAR_GP_PIN(5, 21), RCAR_GP_PIN(5, 19), ++}; ++static const unsigned int eth_rmii_mux[] = { ++ ETH_RXD0_MARK, ETH_RXD1_MARK, ETH_RX_ER_MARK, ETH_CRS_DV_MARK, ++ ETH_TXD0_MARK, ETH_TXD1_MARK, ETH_TX_EN_MARK, ETH_REFCLK_MARK, ++}; ++/* - INTC ------------------------------------------------------------------- */ ++static const unsigned int intc_irq0_pins[] = { ++ /* IRQ */ ++ RCAR_GP_PIN(7, 10), ++}; ++static const unsigned int intc_irq0_mux[] = { ++ IRQ0_MARK, ++}; ++static const unsigned int intc_irq1_pins[] = { ++ /* IRQ */ ++ RCAR_GP_PIN(7, 11), ++}; ++static const unsigned int intc_irq1_mux[] = { ++ IRQ1_MARK, ++}; ++static const unsigned int intc_irq2_pins[] = { ++ /* IRQ */ ++ RCAR_GP_PIN(7, 12), ++}; ++static const unsigned int intc_irq2_mux[] = { ++ IRQ2_MARK, ++}; ++static const unsigned int intc_irq3_pins[] = { ++ /* IRQ */ ++ RCAR_GP_PIN(7, 13), ++}; ++static const unsigned int intc_irq3_mux[] = { ++ IRQ3_MARK, ++}; ++/* - MMCIF ------------------------------------------------------------------ */ ++static const unsigned int mmc_data1_pins[] = { ++ /* D[0] */ ++ RCAR_GP_PIN(6, 18), ++}; ++static const unsigned int mmc_data1_mux[] = { ++ MMC_D0_MARK, ++}; ++static const unsigned int mmc_data4_pins[] = { ++ /* D[0:3] */ ++ RCAR_GP_PIN(6, 18), RCAR_GP_PIN(6, 19), ++ RCAR_GP_PIN(6, 20), RCAR_GP_PIN(6, 21), ++}; ++static const unsigned int mmc_data4_mux[] = { ++ MMC_D0_MARK, MMC_D1_MARK, MMC_D2_MARK, MMC_D3_MARK, ++}; ++static const unsigned int mmc_data8_pins[] = { ++ /* D[0:7] */ ++ RCAR_GP_PIN(6, 18), RCAR_GP_PIN(6, 19), ++ RCAR_GP_PIN(6, 20), RCAR_GP_PIN(6, 21), ++ RCAR_GP_PIN(6, 22), RCAR_GP_PIN(6, 23), ++ RCAR_GP_PIN(6, 28), RCAR_GP_PIN(6, 29), ++}; ++static const unsigned int mmc_data8_mux[] = { ++ MMC_D0_MARK, MMC_D1_MARK, MMC_D2_MARK, MMC_D3_MARK, ++ MMC_D4_MARK, MMC_D5_MARK, MMC_D6_MARK, MMC_D7_MARK, ++}; ++static const unsigned int mmc_ctrl_pins[] = { ++ /* CLK, CMD */ ++ RCAR_GP_PIN(6, 16), RCAR_GP_PIN(6, 17), ++}; ++static const unsigned int mmc_ctrl_mux[] = { ++ MMC_CLK_MARK, MMC_CMD_MARK, ++}; ++/* - MSIOF0 ----------------------------------------------------------------- */ ++static const unsigned int msiof0_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(6, 24), ++}; ++static const unsigned int msiof0_clk_mux[] = { ++ MSIOF0_SCK_MARK, ++}; ++static const unsigned int msiof0_sync_pins[] = { ++ /* SYNC */ ++ RCAR_GP_PIN(6, 25), ++}; ++static const unsigned int msiof0_sync_mux[] = { ++ MSIOF0_SYNC_MARK, ++}; ++static const unsigned int msiof0_ss1_pins[] = { ++ /* SS1 */ ++ RCAR_GP_PIN(6, 28), ++}; ++static const unsigned int msiof0_ss1_mux[] = { ++ MSIOF0_SS1_MARK, ++}; ++static const unsigned int msiof0_ss2_pins[] = { ++ /* SS2 */ ++ RCAR_GP_PIN(6, 29), ++}; ++static const unsigned int msiof0_ss2_mux[] = { ++ MSIOF0_SS2_MARK, ++}; ++static const unsigned int msiof0_rx_pins[] = { ++ /* RXD */ ++ RCAR_GP_PIN(6, 27), ++}; ++static const unsigned int msiof0_rx_mux[] = { ++ MSIOF0_RXD_MARK, ++}; ++static const unsigned int msiof0_tx_pins[] = { ++ /* TXD */ ++ RCAR_GP_PIN(6, 26), ++}; ++static const unsigned int msiof0_tx_mux[] = { ++ MSIOF0_TXD_MARK, ++}; ++/* - MSIOF1 ----------------------------------------------------------------- */ ++static const unsigned int msiof1_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(0, 22), ++}; ++static const unsigned int msiof1_clk_mux[] = { ++ MSIOF1_SCK_MARK, ++}; ++static const unsigned int msiof1_sync_pins[] = { ++ /* SYNC */ ++ RCAR_GP_PIN(0, 23), ++}; ++static const unsigned int msiof1_sync_mux[] = { ++ MSIOF1_SYNC_MARK, ++}; ++static const unsigned int msiof1_ss1_pins[] = { ++ /* SS1 */ ++ RCAR_GP_PIN(0, 24), ++}; ++static const unsigned int msiof1_ss1_mux[] = { ++ MSIOF1_SS1_MARK, ++}; ++static const unsigned int msiof1_ss2_pins[] = { ++ /* SS2 */ ++ RCAR_GP_PIN(0, 25), ++}; ++static const unsigned int msiof1_ss2_mux[] = { ++ MSIOF1_SS2_MARK, ++}; ++static const unsigned int msiof1_rx_pins[] = { ++ /* RXD */ ++ RCAR_GP_PIN(0, 27), ++}; ++static const unsigned int msiof1_rx_mux[] = { ++ MSIOF1_RXD_MARK, ++}; ++static const unsigned int msiof1_tx_pins[] = { ++ /* TXD */ ++ RCAR_GP_PIN(0, 26), ++}; ++static const unsigned int msiof1_tx_mux[] = { ++ MSIOF1_TXD_MARK, ++}; ++/* - MSIOF2 ----------------------------------------------------------------- */ ++static const unsigned int msiof2_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(1, 13), ++}; ++static const unsigned int msiof2_clk_mux[] = { ++ MSIOF2_SCK_MARK, ++}; ++static const unsigned int msiof2_sync_pins[] = { ++ /* SYNC */ ++ RCAR_GP_PIN(1, 14), ++}; ++static const unsigned int msiof2_sync_mux[] = { ++ MSIOF2_SYNC_MARK, ++}; ++static const unsigned int msiof2_ss1_pins[] = { ++ /* SS1 */ ++ RCAR_GP_PIN(1, 17), ++}; ++static const unsigned int msiof2_ss1_mux[] = { ++ MSIOF2_SS1_MARK, ++}; ++static const unsigned int msiof2_ss2_pins[] = { ++ /* SS2 */ ++ RCAR_GP_PIN(1, 18), ++}; ++static const unsigned int msiof2_ss2_mux[] = { ++ MSIOF2_SS2_MARK, ++}; ++static const unsigned int msiof2_rx_pins[] = { ++ /* RXD */ ++ RCAR_GP_PIN(1, 16), ++}; ++static const unsigned int msiof2_rx_mux[] = { ++ MSIOF2_RXD_MARK, ++}; ++static const unsigned int msiof2_tx_pins[] = { ++ /* TXD */ ++ RCAR_GP_PIN(1, 15), ++}; ++static const unsigned int msiof2_tx_mux[] = { ++ MSIOF2_TXD_MARK, ++}; ++/* - SCIF0 ------------------------------------------------------------------ */ ++static const unsigned int scif0_data_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 6), ++}; ++static const unsigned int scif0_data_mux[] = { ++ RX0_MARK, TX0_MARK, ++}; ++static const unsigned int scif0_data_b_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(3, 1), RCAR_GP_PIN(3, 0), ++}; ++static const unsigned int scif0_data_b_mux[] = { ++ RX0_B_MARK, TX0_B_MARK, ++}; ++static const unsigned int scif0_data_c_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(4, 26), RCAR_GP_PIN(4, 25), ++}; ++static const unsigned int scif0_data_c_mux[] = { ++ RX0_C_MARK, TX0_C_MARK, ++}; ++static const unsigned int scif0_data_d_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(2, 23), RCAR_GP_PIN(2, 22), ++}; ++static const unsigned int scif0_data_d_mux[] = { ++ RX0_D_MARK, TX0_D_MARK, ++}; ++static const unsigned int scif0_data_e_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(6, 29), RCAR_GP_PIN(6, 28), ++}; ++static const unsigned int scif0_data_e_mux[] = { ++ RX0_E_MARK, TX0_E_MARK, ++}; ++/* - SCIF1 ------------------------------------------------------------------ */ ++static const unsigned int scif1_data_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 8), ++}; ++static const unsigned int scif1_data_mux[] = { ++ RX1_MARK, TX1_MARK, ++}; ++static const unsigned int scif1_data_b_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(3, 9), RCAR_GP_PIN(3, 8), ++}; ++static const unsigned int scif1_data_b_mux[] = { ++ RX1_B_MARK, TX1_B_MARK, ++}; ++static const unsigned int scif1_clk_b_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(3, 10), ++}; ++static const unsigned int scif1_clk_b_mux[] = { ++ SCIF1_SCK_B_MARK, ++}; ++static const unsigned int scif1_data_c_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(4, 28), RCAR_GP_PIN(4, 27), ++}; ++static const unsigned int scif1_data_c_mux[] = { ++ RX1_C_MARK, TX1_C_MARK, ++}; ++static const unsigned int scif1_data_d_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(2, 25), RCAR_GP_PIN(2, 24), ++}; ++static const unsigned int scif1_data_d_mux[] = { ++ RX1_D_MARK, TX1_D_MARK, ++}; ++/* - SCIF2 ------------------------------------------------------------------ */ ++static const unsigned int scif2_data_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(2, 30), RCAR_GP_PIN(2, 31), ++}; ++static const unsigned int scif2_data_mux[] = { ++ RX2_MARK, TX2_MARK, ++}; ++static const unsigned int scif2_data_b_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(3, 17), RCAR_GP_PIN(3, 16), ++}; ++static const unsigned int scif2_data_b_mux[] = { ++ RX2_B_MARK, TX2_B_MARK, ++}; ++static const unsigned int scif2_clk_b_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(3, 18), ++}; ++static const unsigned int scif2_clk_b_mux[] = { ++ SCIF2_SCK_B_MARK, ++}; ++static const unsigned int scif2_data_c_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(6, 24), RCAR_GP_PIN(6, 25), ++}; ++static const unsigned int scif2_data_c_mux[] = { ++ RX2_C_MARK, TX2_C_MARK, ++}; ++static const unsigned int scif2_data_e_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(2, 7), RCAR_GP_PIN(2, 8), ++}; ++static const unsigned int scif2_data_e_mux[] = { ++ RX2_E_MARK, TX2_E_MARK, ++}; ++/* - SCIF3 ------------------------------------------------------------------ */ ++static const unsigned int scif3_data_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(3, 22), RCAR_GP_PIN(3, 21), ++}; ++static const unsigned int scif3_data_mux[] = { ++ RX3_MARK, TX3_MARK, ++}; ++static const unsigned int scif3_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(3, 23), ++}; ++static const unsigned int scif3_clk_mux[] = { ++ SCIF3_SCK_MARK, ++}; ++static const unsigned int scif3_data_b_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(3, 29), RCAR_GP_PIN(3, 26), ++}; ++static const unsigned int scif3_data_b_mux[] = { ++ RX3_B_MARK, TX3_B_MARK, ++}; ++static const unsigned int scif3_clk_b_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(4, 8), ++}; ++static const unsigned int scif3_clk_b_mux[] = { ++ SCIF3_SCK_B_MARK, ++}; ++static const unsigned int scif3_data_c_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(6, 7), RCAR_GP_PIN(6, 6), ++}; ++static const unsigned int scif3_data_c_mux[] = { ++ RX3_C_MARK, TX3_C_MARK, ++}; ++static const unsigned int scif3_data_d_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(2, 27), RCAR_GP_PIN(2, 26), ++}; ++static const unsigned int scif3_data_d_mux[] = { ++ RX3_D_MARK, TX3_D_MARK, ++}; ++/* - SCIF4 ------------------------------------------------------------------ */ ++static const unsigned int scif4_data_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(4, 2), RCAR_GP_PIN(4, 1), ++}; ++static const unsigned int scif4_data_mux[] = { ++ RX4_MARK, TX4_MARK, ++}; ++static const unsigned int scif4_data_b_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 0), ++}; ++static const unsigned int scif4_data_b_mux[] = { ++ RX4_B_MARK, TX4_B_MARK, ++}; ++static const unsigned int scif4_data_c_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(7, 22), RCAR_GP_PIN(7, 21), ++}; ++static const unsigned int scif4_data_c_mux[] = { ++ RX4_C_MARK, TX4_C_MARK, ++}; ++/* - SCIF5 ------------------------------------------------------------------ */ ++static const unsigned int scif5_data_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(4, 4), RCAR_GP_PIN(4, 3), ++}; ++static const unsigned int scif5_data_mux[] = { ++ RX5_MARK, TX5_MARK, ++}; ++static const unsigned int scif5_data_b_pins[] = { ++ /* RX, TX */ ++ RCAR_GP_PIN(6, 23), RCAR_GP_PIN(6, 22), ++}; ++static const unsigned int scif5_data_b_mux[] = { ++ RX5_B_MARK, TX5_B_MARK, ++}; ++/* - SCIFA0 ----------------------------------------------------------------- */ ++static const unsigned int scifa0_data_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(1, 7), RCAR_GP_PIN(1, 6), ++}; ++static const unsigned int scifa0_data_mux[] = { ++ SCIFA0_RXD_MARK, SCIFA0_TXD_MARK, ++}; ++static const unsigned int scifa0_data_b_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(3, 1), RCAR_GP_PIN(3, 0), ++}; ++static const unsigned int scifa0_data_b_mux[] = { ++ SCIFA0_RXD_B_MARK, SCIFA0_TXD_B_MARK ++}; ++/* - SCIFA1 ----------------------------------------------------------------- */ ++static const unsigned int scifa1_data_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(1, 9), RCAR_GP_PIN(1, 8), ++}; ++static const unsigned int scifa1_data_mux[] = { ++ SCIFA1_RXD_MARK, SCIFA1_TXD_MARK, ++}; ++static const unsigned int scifa1_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(3, 10), ++}; ++static const unsigned int scifa1_clk_mux[] = { ++ SCIFA1_SCK_MARK, ++}; ++static const unsigned int scifa1_data_b_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(3, 9), RCAR_GP_PIN(3, 8), ++}; ++static const unsigned int scifa1_data_b_mux[] = { ++ SCIFA1_RXD_B_MARK, SCIFA1_TXD_B_MARK, ++}; ++static const unsigned int scifa1_clk_b_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(1, 0), ++}; ++static const unsigned int scifa1_clk_b_mux[] = { ++ SCIFA1_SCK_B_MARK, ++}; ++static const unsigned int scifa1_data_c_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(1, 2), RCAR_GP_PIN(1, 3), ++}; ++static const unsigned int scifa1_data_c_mux[] = { ++ SCIFA1_RXD_C_MARK, SCIFA1_TXD_C_MARK, ++}; ++/* - SCIFA2 ----------------------------------------------------------------- */ ++static const unsigned int scifa2_data_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(2, 30), RCAR_GP_PIN(2, 31), ++}; ++static const unsigned int scifa2_data_mux[] = { ++ SCIFA2_RXD_MARK, SCIFA2_TXD_MARK, ++}; ++static const unsigned int scifa2_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(3, 18), ++}; ++static const unsigned int scifa2_clk_mux[] = { ++ SCIFA2_SCK_MARK, ++}; ++static const unsigned int scifa2_data_b_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(3, 17), RCAR_GP_PIN(3, 16), ++}; ++static const unsigned int scifa2_data_b_mux[] = { ++ SCIFA2_RXD_B_MARK, SCIFA2_TXD_B_MARK, ++}; ++/* - SCIFA3 ----------------------------------------------------------------- */ ++static const unsigned int scifa3_data_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(3, 22), RCAR_GP_PIN(3, 21), ++}; ++static const unsigned int scifa3_data_mux[] = { ++ SCIFA3_RXD_MARK, SCIFA3_TXD_MARK, ++}; ++static const unsigned int scifa3_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(3, 23), ++}; ++static const unsigned int scifa3_clk_mux[] = { ++ SCIFA3_SCK_MARK, ++}; ++static const unsigned int scifa3_data_b_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(5, 19), RCAR_GP_PIN(5, 20), ++}; ++static const unsigned int scifa3_data_b_mux[] = { ++ SCIFA3_RXD_B_MARK, SCIFA3_TXD_B_MARK, ++}; ++static const unsigned int scifa3_clk_b_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(4, 8), ++}; ++static const unsigned int scifa3_clk_b_mux[] = { ++ SCIFA3_SCK_B_MARK, ++}; ++static const unsigned int scifa3_data_c_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(7, 21), RCAR_GP_PIN(7, 20), ++}; ++static const unsigned int scifa3_data_c_mux[] = { ++ SCIFA3_RXD_C_MARK, SCIFA3_TXD_C_MARK, ++}; ++static const unsigned int scifa3_clk_c_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(7, 22), ++}; ++static const unsigned int scifa3_clk_c_mux[] = { ++ SCIFA3_SCK_C_MARK, ++}; ++/* - SCIFA4 ----------------------------------------------------------------- */ ++static const unsigned int scifa4_data_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(4, 2), RCAR_GP_PIN(4, 1), ++}; ++static const unsigned int scifa4_data_mux[] = { ++ SCIFA4_RXD_MARK, SCIFA4_TXD_MARK, ++}; ++static const unsigned int scifa4_data_b_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(5, 1), RCAR_GP_PIN(5, 0), ++}; ++static const unsigned int scifa4_data_b_mux[] = { ++ SCIFA4_RXD_B_MARK, SCIFA4_TXD_B_MARK, ++}; ++static const unsigned int scifa4_data_c_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(7, 22), RCAR_GP_PIN(7, 21), ++}; ++static const unsigned int scifa4_data_c_mux[] = { ++ SCIFA4_RXD_C_MARK, SCIFA4_TXD_C_MARK, ++}; ++/* - SCIFA5 ----------------------------------------------------------------- */ ++static const unsigned int scifa5_data_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(4, 4), RCAR_GP_PIN(4, 3), ++}; ++static const unsigned int scifa5_data_mux[] = { ++ SCIFA5_RXD_MARK, SCIFA5_TXD_MARK, ++}; ++static const unsigned int scifa5_data_b_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(6, 7), RCAR_GP_PIN(6, 6), ++}; ++static const unsigned int scifa5_data_b_mux[] = { ++ SCIFA5_RXD_B_MARK, SCIFA5_TXD_B_MARK, ++}; ++static const unsigned int scifa5_data_c_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(6, 23), RCAR_GP_PIN(6, 22), ++}; ++static const unsigned int scifa5_data_c_mux[] = { ++ SCIFA5_RXD_C_MARK, SCIFA5_TXD_C_MARK, ++}; ++/* - SCIFB0 ----------------------------------------------------------------- */ ++static const unsigned int scifb0_data_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(7, 3), RCAR_GP_PIN(7, 4), ++}; ++static const unsigned int scifb0_data_mux[] = { ++ SCIFB0_RXD_MARK, SCIFB0_TXD_MARK, ++}; ++static const unsigned int scifb0_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(7, 2), ++}; ++static const unsigned int scifb0_clk_mux[] = { ++ SCIFB0_SCK_MARK, ++}; ++static const unsigned int scifb0_ctrl_pins[] = { ++ /* RTS, CTS */ ++ RCAR_GP_PIN(7, 1), RCAR_GP_PIN(7, 0), ++}; ++static const unsigned int scifb0_ctrl_mux[] = { ++ SCIFB0_RTS_N_MARK, SCIFB0_CTS_N_MARK, ++}; ++static const unsigned int scifb0_data_b_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(1, 20), RCAR_GP_PIN(1, 21), ++}; ++static const unsigned int scifb0_data_b_mux[] = { ++ SCIFB0_RXD_B_MARK, SCIFB0_TXD_B_MARK, ++}; ++static const unsigned int scifb0_clk_b_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(5, 31), ++}; ++static const unsigned int scifb0_clk_b_mux[] = { ++ SCIFB0_SCK_B_MARK, ++}; ++static const unsigned int scifb0_ctrl_b_pins[] = { ++ /* RTS, CTS */ ++ RCAR_GP_PIN(1, 22), RCAR_GP_PIN(1, 23), ++}; ++static const unsigned int scifb0_ctrl_b_mux[] = { ++ SCIFB0_RTS_N_B_MARK, SCIFB0_CTS_N_B_MARK, ++}; ++static const unsigned int scifb0_data_c_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1), ++}; ++static const unsigned int scifb0_data_c_mux[] = { ++ SCIFB0_RXD_C_MARK, SCIFB0_TXD_C_MARK, ++}; ++static const unsigned int scifb0_clk_c_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(2, 30), ++}; ++static const unsigned int scifb0_clk_c_mux[] = { ++ SCIFB0_SCK_C_MARK, ++}; ++static const unsigned int scifb0_data_d_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(4, 28), RCAR_GP_PIN(4, 18), ++}; ++static const unsigned int scifb0_data_d_mux[] = { ++ SCIFB0_RXD_D_MARK, SCIFB0_TXD_D_MARK, ++}; ++static const unsigned int scifb0_clk_d_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(4, 17), ++}; ++static const unsigned int scifb0_clk_d_mux[] = { ++ SCIFB0_SCK_D_MARK, ++}; ++/* - SCIFB1 ----------------------------------------------------------------- */ ++static const unsigned int scifb1_data_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(7, 5), RCAR_GP_PIN(7, 6), ++}; ++static const unsigned int scifb1_data_mux[] = { ++ SCIFB1_RXD_MARK, SCIFB1_TXD_MARK, ++}; ++static const unsigned int scifb1_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(7, 7), ++}; ++static const unsigned int scifb1_clk_mux[] = { ++ SCIFB1_SCK_MARK, ++}; ++static const unsigned int scifb1_ctrl_pins[] = { ++ /* RTS, CTS */ ++ RCAR_GP_PIN(7, 9), RCAR_GP_PIN(7, 8), ++}; ++static const unsigned int scifb1_ctrl_mux[] = { ++ SCIFB1_RTS_N_MARK, SCIFB1_CTS_N_MARK, ++}; ++static const unsigned int scifb1_data_b_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(1, 17), RCAR_GP_PIN(1, 18), ++}; ++static const unsigned int scifb1_data_b_mux[] = { ++ SCIFB1_RXD_B_MARK, SCIFB1_TXD_B_MARK, ++}; ++static const unsigned int scifb1_clk_b_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(1, 3), ++}; ++static const unsigned int scifb1_clk_b_mux[] = { ++ SCIFB1_SCK_B_MARK, ++}; ++static const unsigned int scifb1_data_c_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(1, 2), RCAR_GP_PIN(1, 3), ++}; ++static const unsigned int scifb1_data_c_mux[] = { ++ SCIFB1_RXD_C_MARK, SCIFB1_TXD_C_MARK, ++}; ++static const unsigned int scifb1_clk_c_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(7, 11), ++}; ++static const unsigned int scifb1_clk_c_mux[] = { ++ SCIFB1_SCK_C_MARK, ++}; ++static const unsigned int scifb1_data_d_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(7, 10), RCAR_GP_PIN(7, 12), ++}; ++static const unsigned int scifb1_data_d_mux[] = { ++ SCIFB1_RXD_D_MARK, SCIFB1_TXD_D_MARK, ++}; ++/* - SCIFB2 ----------------------------------------------------------------- */ ++static const unsigned int scifb2_data_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(4, 16), RCAR_GP_PIN(4, 17), ++}; ++static const unsigned int scifb2_data_mux[] = { ++ SCIFB2_RXD_MARK, SCIFB2_TXD_MARK, ++}; ++static const unsigned int scifb2_clk_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(4, 15), ++}; ++static const unsigned int scifb2_clk_mux[] = { ++ SCIFB2_SCK_MARK, ++}; ++static const unsigned int scifb2_ctrl_pins[] = { ++ /* RTS, CTS */ ++ RCAR_GP_PIN(4, 14), RCAR_GP_PIN(4, 13), ++}; ++static const unsigned int scifb2_ctrl_mux[] = { ++ SCIFB2_RTS_N_MARK, SCIFB2_CTS_N_MARK, ++}; ++static const unsigned int scifb2_data_b_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(3, 12), RCAR_GP_PIN(3, 13), ++}; ++static const unsigned int scifb2_data_b_mux[] = { ++ SCIFB2_RXD_B_MARK, SCIFB2_TXD_B_MARK, ++}; ++static const unsigned int scifb2_clk_b_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(5, 31), ++}; ++static const unsigned int scifb2_clk_b_mux[] = { ++ SCIFB2_SCK_B_MARK, ++}; ++static const unsigned int scifb2_ctrl_b_pins[] = { ++ /* RTS, CTS */ ++ RCAR_GP_PIN(3, 15), RCAR_GP_PIN(3, 14), ++}; ++static const unsigned int scifb2_ctrl_b_mux[] = { ++ SCIFB2_RTS_N_B_MARK, SCIFB2_CTS_N_B_MARK, ++}; ++static const unsigned int scifb2_data_c_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(2, 0), RCAR_GP_PIN(2, 1), ++}; ++static const unsigned int scifb2_data_c_mux[] = { ++ SCIFB2_RXD_C_MARK, SCIFB2_TXD_C_MARK, ++}; ++static const unsigned int scifb2_clk_c_pins[] = { ++ /* SCK */ ++ RCAR_GP_PIN(5, 27), ++}; ++static const unsigned int scifb2_clk_c_mux[] = { ++ SCIFB2_SCK_C_MARK, ++}; ++static const unsigned int scifb2_data_d_pins[] = { ++ /* RXD, TXD */ ++ RCAR_GP_PIN(5, 26), RCAR_GP_PIN(5, 25), ++}; ++static const unsigned int scifb2_data_d_mux[] = { ++ SCIFB2_RXD_D_MARK, SCIFB2_TXD_D_MARK, ++}; ++/* - SDHI0 ------------------------------------------------------------------ */ ++static const unsigned int sdhi0_data1_pins[] = { ++ /* D0 */ ++ RCAR_GP_PIN(6, 2), ++}; ++static const unsigned int sdhi0_data1_mux[] = { ++ SD0_DATA0_MARK, ++}; ++static const unsigned int sdhi0_data4_pins[] = { ++ /* D[0:3] */ ++ RCAR_GP_PIN(6, 2), RCAR_GP_PIN(6, 3), ++ RCAR_GP_PIN(6, 4), RCAR_GP_PIN(6, 5), ++}; ++static const unsigned int sdhi0_data4_mux[] = { ++ SD0_DATA0_MARK, SD0_DATA1_MARK, SD0_DATA2_MARK, SD0_DATA3_MARK, ++}; ++static const unsigned int sdhi0_ctrl_pins[] = { ++ /* CLK, CMD */ ++ RCAR_GP_PIN(6, 0), RCAR_GP_PIN(6, 1), ++}; ++static const unsigned int sdhi0_ctrl_mux[] = { ++ SD0_CLK_MARK, SD0_CMD_MARK, ++}; ++static const unsigned int sdhi0_cd_pins[] = { ++ /* CD */ ++ RCAR_GP_PIN(6, 6), ++}; ++static const unsigned int sdhi0_cd_mux[] = { ++ SD0_CD_MARK, ++}; ++static const unsigned int sdhi0_wp_pins[] = { ++ /* WP */ ++ RCAR_GP_PIN(6, 7), ++}; ++static const unsigned int sdhi0_wp_mux[] = { ++ SD0_WP_MARK, ++}; ++/* - SDHI1 ------------------------------------------------------------------ */ ++static const unsigned int sdhi1_data1_pins[] = { ++ /* D0 */ ++ RCAR_GP_PIN(6, 10), ++}; ++static const unsigned int sdhi1_data1_mux[] = { ++ SD1_DATA0_MARK, ++}; ++static const unsigned int sdhi1_data4_pins[] = { ++ /* D[0:3] */ ++ RCAR_GP_PIN(6, 10), RCAR_GP_PIN(6, 11), ++ RCAR_GP_PIN(6, 12), RCAR_GP_PIN(6, 13), ++}; ++static const unsigned int sdhi1_data4_mux[] = { ++ SD1_DATA0_MARK, SD1_DATA1_MARK, SD1_DATA2_MARK, SD1_DATA3_MARK, ++}; ++static const unsigned int sdhi1_ctrl_pins[] = { ++ /* CLK, CMD */ ++ RCAR_GP_PIN(6, 8), RCAR_GP_PIN(6, 9), ++}; ++static const unsigned int sdhi1_ctrl_mux[] = { ++ SD1_CLK_MARK, SD1_CMD_MARK, ++}; ++static const unsigned int sdhi1_cd_pins[] = { ++ /* CD */ ++ RCAR_GP_PIN(6, 14), ++}; ++static const unsigned int sdhi1_cd_mux[] = { ++ SD1_CD_MARK, ++}; ++static const unsigned int sdhi1_wp_pins[] = { ++ /* WP */ ++ RCAR_GP_PIN(6, 15), ++}; ++static const unsigned int sdhi1_wp_mux[] = { ++ SD1_WP_MARK, ++}; ++/* - SDHI2 ------------------------------------------------------------------ */ ++static const unsigned int sdhi2_data1_pins[] = { ++ /* D0 */ ++ RCAR_GP_PIN(6, 18), ++}; ++static const unsigned int sdhi2_data1_mux[] = { ++ SD2_DATA0_MARK, ++}; ++static const unsigned int sdhi2_data4_pins[] = { ++ /* D[0:3] */ ++ RCAR_GP_PIN(6, 18), RCAR_GP_PIN(6, 19), ++ RCAR_GP_PIN(6, 20), RCAR_GP_PIN(6, 21), ++}; ++static const unsigned int sdhi2_data4_mux[] = { ++ SD2_DATA0_MARK, SD2_DATA1_MARK, SD2_DATA2_MARK, SD2_DATA3_MARK, ++}; ++static const unsigned int sdhi2_ctrl_pins[] = { ++ /* CLK, CMD */ ++ RCAR_GP_PIN(6, 16), RCAR_GP_PIN(6, 17), ++}; ++static const unsigned int sdhi2_ctrl_mux[] = { ++ SD2_CLK_MARK, SD2_CMD_MARK, ++}; ++static const unsigned int sdhi2_cd_pins[] = { ++ /* CD */ ++ RCAR_GP_PIN(6, 22), ++}; ++static const unsigned int sdhi2_cd_mux[] = { ++ SD2_CD_MARK, ++}; ++static const unsigned int sdhi2_wp_pins[] = { ++ /* WP */ ++ RCAR_GP_PIN(6, 23), ++}; ++static const unsigned int sdhi2_wp_mux[] = { ++ SD2_WP_MARK, ++}; ++/* - USB0 ------------------------------------------------------------------- */ ++static const unsigned int usb0_pwen_pins[] = { ++ /* PWEN */ ++ RCAR_GP_PIN(7, 23), ++}; ++static const unsigned int usb0_pwen_mux[] = { ++ USB0_PWEN_MARK, ++}; ++static const unsigned int usb0_ovc_pins[] = { ++ /* OVC */ ++ RCAR_GP_PIN(7, 24), ++}; ++static const unsigned int usb0_ovc_mux[] = { ++ USB0_OVC_MARK, ++}; ++/* - USB1 ------------------------------------------------------------------- */ ++static const unsigned int usb1_pwen_pins[] = { ++ /* PWEN */ ++ RCAR_GP_PIN(7, 25), ++}; ++static const unsigned int usb1_pwen_mux[] = { ++ USB1_PWEN_MARK, ++}; ++static const unsigned int usb1_ovc_pins[] = { ++ /* OVC */ ++ RCAR_GP_PIN(6, 30), ++}; ++static const unsigned int usb1_ovc_mux[] = { ++ USB1_OVC_MARK, ++}; ++ ++static const struct sh_pfc_pin_group pinmux_groups[] = { ++ SH_PFC_PIN_GROUP(du_rgb666), ++ SH_PFC_PIN_GROUP(du_rgb888), ++ SH_PFC_PIN_GROUP(du_clk_out_0), ++ SH_PFC_PIN_GROUP(du_clk_out_1), ++ SH_PFC_PIN_GROUP(du_sync_1), ++ SH_PFC_PIN_GROUP(du_cde_disp), ++ SH_PFC_PIN_GROUP(du0_clk_in), ++ SH_PFC_PIN_GROUP(du1_clk_in), ++ SH_PFC_PIN_GROUP(eth_link), ++ SH_PFC_PIN_GROUP(eth_magic), ++ SH_PFC_PIN_GROUP(eth_mdio), ++ SH_PFC_PIN_GROUP(eth_rmii), ++ SH_PFC_PIN_GROUP(intc_irq0), ++ SH_PFC_PIN_GROUP(intc_irq1), ++ SH_PFC_PIN_GROUP(intc_irq2), ++ SH_PFC_PIN_GROUP(intc_irq3), ++ SH_PFC_PIN_GROUP(mmc_data1), ++ SH_PFC_PIN_GROUP(mmc_data4), ++ SH_PFC_PIN_GROUP(mmc_data8), ++ SH_PFC_PIN_GROUP(mmc_ctrl), ++ SH_PFC_PIN_GROUP(msiof0_clk), ++ SH_PFC_PIN_GROUP(msiof0_sync), ++ SH_PFC_PIN_GROUP(msiof0_ss1), ++ SH_PFC_PIN_GROUP(msiof0_ss2), ++ SH_PFC_PIN_GROUP(msiof0_rx), ++ SH_PFC_PIN_GROUP(msiof0_tx), ++ SH_PFC_PIN_GROUP(msiof1_clk), ++ SH_PFC_PIN_GROUP(msiof1_sync), ++ SH_PFC_PIN_GROUP(msiof1_ss1), ++ SH_PFC_PIN_GROUP(msiof1_ss2), ++ SH_PFC_PIN_GROUP(msiof1_rx), ++ SH_PFC_PIN_GROUP(msiof1_tx), ++ SH_PFC_PIN_GROUP(msiof2_clk), ++ SH_PFC_PIN_GROUP(msiof2_sync), ++ SH_PFC_PIN_GROUP(msiof2_ss1), ++ SH_PFC_PIN_GROUP(msiof2_ss2), ++ SH_PFC_PIN_GROUP(msiof2_rx), ++ SH_PFC_PIN_GROUP(msiof2_tx), ++ SH_PFC_PIN_GROUP(scif0_data), ++ SH_PFC_PIN_GROUP(scif0_data_b), ++ SH_PFC_PIN_GROUP(scif0_data_c), ++ SH_PFC_PIN_GROUP(scif0_data_d), ++ SH_PFC_PIN_GROUP(scif0_data_e), ++ SH_PFC_PIN_GROUP(scif1_data), ++ SH_PFC_PIN_GROUP(scif1_data_b), ++ SH_PFC_PIN_GROUP(scif1_clk_b), ++ SH_PFC_PIN_GROUP(scif1_data_c), ++ SH_PFC_PIN_GROUP(scif1_data_d), ++ SH_PFC_PIN_GROUP(scif2_data), ++ SH_PFC_PIN_GROUP(scif2_data_b), ++ SH_PFC_PIN_GROUP(scif2_clk_b), ++ SH_PFC_PIN_GROUP(scif2_data_c), ++ SH_PFC_PIN_GROUP(scif2_data_e), ++ SH_PFC_PIN_GROUP(scif3_data), ++ SH_PFC_PIN_GROUP(scif3_clk), ++ SH_PFC_PIN_GROUP(scif3_data_b), ++ SH_PFC_PIN_GROUP(scif3_clk_b), ++ SH_PFC_PIN_GROUP(scif3_data_c), ++ SH_PFC_PIN_GROUP(scif3_data_d), ++ SH_PFC_PIN_GROUP(scif4_data), ++ SH_PFC_PIN_GROUP(scif4_data_b), ++ SH_PFC_PIN_GROUP(scif4_data_c), ++ SH_PFC_PIN_GROUP(scif5_data), ++ SH_PFC_PIN_GROUP(scif5_data_b), ++ SH_PFC_PIN_GROUP(scifa0_data), ++ SH_PFC_PIN_GROUP(scifa0_data_b), ++ SH_PFC_PIN_GROUP(scifa1_data), ++ SH_PFC_PIN_GROUP(scifa1_clk), ++ SH_PFC_PIN_GROUP(scifa1_data_b), ++ SH_PFC_PIN_GROUP(scifa1_clk_b), ++ SH_PFC_PIN_GROUP(scifa1_data_c), ++ SH_PFC_PIN_GROUP(scifa2_data), ++ SH_PFC_PIN_GROUP(scifa2_clk), ++ SH_PFC_PIN_GROUP(scifa2_data_b), ++ SH_PFC_PIN_GROUP(scifa3_data), ++ SH_PFC_PIN_GROUP(scifa3_clk), ++ SH_PFC_PIN_GROUP(scifa3_data_b), ++ SH_PFC_PIN_GROUP(scifa3_clk_b), ++ SH_PFC_PIN_GROUP(scifa3_data_c), ++ SH_PFC_PIN_GROUP(scifa3_clk_c), ++ SH_PFC_PIN_GROUP(scifa4_data), ++ SH_PFC_PIN_GROUP(scifa4_data_b), ++ SH_PFC_PIN_GROUP(scifa4_data_c), ++ SH_PFC_PIN_GROUP(scifa5_data), ++ SH_PFC_PIN_GROUP(scifa5_data_b), ++ SH_PFC_PIN_GROUP(scifa5_data_c), ++ SH_PFC_PIN_GROUP(scifb0_data), ++ SH_PFC_PIN_GROUP(scifb0_clk), ++ SH_PFC_PIN_GROUP(scifb0_ctrl), ++ SH_PFC_PIN_GROUP(scifb0_data_b), ++ SH_PFC_PIN_GROUP(scifb0_clk_b), ++ SH_PFC_PIN_GROUP(scifb0_ctrl_b), ++ SH_PFC_PIN_GROUP(scifb0_data_c), ++ SH_PFC_PIN_GROUP(scifb0_clk_c), ++ SH_PFC_PIN_GROUP(scifb0_data_d), ++ SH_PFC_PIN_GROUP(scifb0_clk_d), ++ SH_PFC_PIN_GROUP(scifb1_data), ++ SH_PFC_PIN_GROUP(scifb1_clk), ++ SH_PFC_PIN_GROUP(scifb1_ctrl), ++ SH_PFC_PIN_GROUP(scifb1_data_b), ++ SH_PFC_PIN_GROUP(scifb1_clk_b), ++ SH_PFC_PIN_GROUP(scifb1_data_c), ++ SH_PFC_PIN_GROUP(scifb1_clk_c), ++ SH_PFC_PIN_GROUP(scifb1_data_d), ++ SH_PFC_PIN_GROUP(scifb2_data), ++ SH_PFC_PIN_GROUP(scifb2_clk), ++ SH_PFC_PIN_GROUP(scifb2_ctrl), ++ SH_PFC_PIN_GROUP(scifb2_data_b), ++ SH_PFC_PIN_GROUP(scifb2_clk_b), ++ SH_PFC_PIN_GROUP(scifb2_ctrl_b), ++ SH_PFC_PIN_GROUP(scifb2_data_c), ++ SH_PFC_PIN_GROUP(scifb2_clk_c), ++ SH_PFC_PIN_GROUP(scifb2_data_d), ++ SH_PFC_PIN_GROUP(sdhi0_data1), ++ SH_PFC_PIN_GROUP(sdhi0_data4), ++ SH_PFC_PIN_GROUP(sdhi0_ctrl), ++ SH_PFC_PIN_GROUP(sdhi0_cd), ++ SH_PFC_PIN_GROUP(sdhi0_wp), ++ SH_PFC_PIN_GROUP(sdhi1_data1), ++ SH_PFC_PIN_GROUP(sdhi1_data4), ++ SH_PFC_PIN_GROUP(sdhi1_ctrl), ++ SH_PFC_PIN_GROUP(sdhi1_cd), ++ SH_PFC_PIN_GROUP(sdhi1_wp), ++ SH_PFC_PIN_GROUP(sdhi2_data1), ++ SH_PFC_PIN_GROUP(sdhi2_data4), ++ SH_PFC_PIN_GROUP(sdhi2_ctrl), ++ SH_PFC_PIN_GROUP(sdhi2_cd), ++ SH_PFC_PIN_GROUP(sdhi2_wp), ++ SH_PFC_PIN_GROUP(usb0_pwen), ++ SH_PFC_PIN_GROUP(usb0_ovc), ++ SH_PFC_PIN_GROUP(usb1_pwen), ++ SH_PFC_PIN_GROUP(usb1_ovc), ++}; ++ ++static const char * const du_groups[] = { ++ "du_rgb666", ++ "du_rgb888", ++ "du_clk_out_0", ++ "du_clk_out_1", ++ "du_sync_1", ++ "du_cde_disp", ++}; ++ ++static const char * const du0_groups[] = { ++ "du0_clk_in", ++}; ++ ++static const char * const du1_groups[] = { ++ "du1_clk_in", ++}; ++ ++static const char * const eth_groups[] = { ++ "eth_link", ++ "eth_magic", ++ "eth_mdio", ++ "eth_rmii", ++}; ++ ++static const char * const intc_groups[] = { ++ "intc_irq0", ++ "intc_irq1", ++ "intc_irq2", ++ "intc_irq3", ++}; ++ ++static const char * const mmc_groups[] = { ++ "mmc_data1", ++ "mmc_data4", ++ "mmc_data8", ++ "mmc_ctrl", ++}; ++ ++static const char * const msiof0_groups[] = { ++ "msiof0_clk", ++ "msiof0_ctrl", ++ "msiof0_data", ++}; ++ ++static const char * const msiof1_groups[] = { ++ "msiof1_clk", ++ "msiof1_ctrl", ++ "msiof1_data", ++}; ++ ++static const char * const msiof2_groups[] = { ++ "msiof2_clk", ++ "msiof2_ctrl", ++ "msiof2_data", ++}; ++ ++static const char * const scif0_groups[] = { ++ "scif0_data", ++ "scif0_data_b", ++ "scif0_data_c", ++ "scif0_data_d", ++ "scif0_data_e", ++}; ++ ++static const char * const scif1_groups[] = { ++ "scif1_data", ++ "scif1_data_b", ++ "scif1_clk_b", ++ "scif1_data_c", ++ "scif1_data_d", ++}; ++ ++static const char * const scif2_groups[] = { ++ "scif2_data", ++ "scif2_data_b", ++ "scif2_clk_b", ++ "scif2_data_c", ++ "scif2_data_e", ++}; ++static const char * const scif3_groups[] = { ++ "scif3_data", ++ "scif3_clk", ++ "scif3_data_b", ++ "scif3_clk_b", ++ "scif3_data_c", ++ "scif3_data_d", ++}; ++static const char * const scif4_groups[] = { ++ "scif4_data", ++ "scif4_data_b", ++ "scif4_data_c", ++}; ++static const char * const scif5_groups[] = { ++ "scif5_data", ++ "scif5_data_b", ++}; ++static const char * const scifa0_groups[] = { ++ "scifa0_data", ++ "scifa0_data_b", ++}; ++static const char * const scifa1_groups[] = { ++ "scifa1_data", ++ "scifa1_clk", ++ "scifa1_data_b", ++ "scifa1_clk_b", ++ "scifa1_data_c", ++}; ++static const char * const scifa2_groups[] = { ++ "scifa2_data", ++ "scifa2_clk", ++ "scifa2_data_b", ++}; ++static const char * const scifa3_groups[] = { ++ "scifa3_data", ++ "scifa3_clk", ++ "scifa3_data_b", ++ "scifa3_clk_b", ++ "scifa3_data_c", ++ "scifa3_clk_c", ++}; ++static const char * const scifa4_groups[] = { ++ "scifa4_data", ++ "scifa4_data_b", ++ "scifa4_data_c", ++}; ++static const char * const scifa5_groups[] = { ++ "scifa5_data", ++ "scifa5_data_b", ++ "scifa5_data_c", ++}; ++static const char * const scifb0_groups[] = { ++ "scifb0_data", ++ "scifb0_clk", ++ "scifb0_ctrl", ++ "scifb0_data_b", ++ "scifb0_clk_b", ++ "scifb0_ctrl_b", ++ "scifb0_data_c", ++ "scifb0_clk_c", ++ "scifb0_data_d", ++ "scifb0_clk_d", ++}; ++static const char * const scifb1_groups[] = { ++ "scifb1_data", ++ "scifb1_clk", ++ "scifb1_ctrl", ++ "scifb1_data_b", ++ "scifb1_clk_b", ++ "scifb1_data_c", ++ "scifb1_clk_c", ++ "scifb1_data_d", ++}; ++static const char * const scifb2_groups[] = { ++ "scifb2_data", ++ "scifb2_clk", ++ "scifb2_ctrl", ++ "scifb2_data_b", ++ "scifb2_clk_b", ++ "scifb2_ctrl_b", ++ "scifb0_data_c", ++ "scifb2_clk_c", ++ "scifb2_data_d", ++}; ++ ++static const char * const sdhi0_groups[] = { ++ "sdhi0_data1", ++ "sdhi0_data4", ++ "sdhi0_ctrl", ++ "sdhi0_cd", ++ "sdhi0_wp", ++}; ++ ++static const char * const sdhi1_groups[] = { ++ "sdhi1_data1", ++ "sdhi1_data4", ++ "sdhi1_ctrl", ++ "sdhi1_cd", ++ "sdhi1_wp", ++}; ++ ++static const char * const sdhi2_groups[] = { ++ "sdhi2_data1", ++ "sdhi2_data4", ++ "sdhi2_ctrl", ++ "sdhi2_cd", ++ "sdhi2_wp", ++}; ++ ++static const char * const usb0_groups[] = { ++ "usb0_pwen", ++ "usb0_ovc", ++}; ++static const char * const usb1_groups[] = { ++ "usb1_pwen", ++ "usb1_ovc", ++}; ++ ++static const struct sh_pfc_function pinmux_functions[] = { ++ SH_PFC_FUNCTION(du), ++ SH_PFC_FUNCTION(du0), ++ SH_PFC_FUNCTION(du1), ++ SH_PFC_FUNCTION(eth), ++ SH_PFC_FUNCTION(intc), ++ SH_PFC_FUNCTION(mmc), ++ SH_PFC_FUNCTION(msiof0), ++ SH_PFC_FUNCTION(msiof1), ++ SH_PFC_FUNCTION(msiof2), ++ SH_PFC_FUNCTION(scif0), ++ SH_PFC_FUNCTION(scif1), ++ SH_PFC_FUNCTION(scif2), ++ SH_PFC_FUNCTION(scif3), ++ SH_PFC_FUNCTION(scif4), ++ SH_PFC_FUNCTION(scif5), ++ SH_PFC_FUNCTION(scifa0), ++ SH_PFC_FUNCTION(scifa1), ++ SH_PFC_FUNCTION(scifa2), ++ SH_PFC_FUNCTION(scifa3), ++ SH_PFC_FUNCTION(scifa4), ++ SH_PFC_FUNCTION(scifa5), ++ SH_PFC_FUNCTION(scifb0), ++ SH_PFC_FUNCTION(scifb1), ++ SH_PFC_FUNCTION(scifb2), ++ SH_PFC_FUNCTION(sdhi0), ++ SH_PFC_FUNCTION(sdhi1), ++ SH_PFC_FUNCTION(sdhi2), ++ SH_PFC_FUNCTION(usb0), ++ SH_PFC_FUNCTION(usb1), ++}; ++ ++static struct pinmux_cfg_reg pinmux_config_regs[] = { ++ { PINMUX_CFG_REG("GPSR0", 0xE6060004, 32, 1) { ++ GP_0_31_FN, FN_IP1_22_20, ++ GP_0_30_FN, FN_IP1_19_17, ++ GP_0_29_FN, FN_IP1_16_14, ++ GP_0_28_FN, FN_IP1_13_11, ++ GP_0_27_FN, FN_IP1_10_8, ++ GP_0_26_FN, FN_IP1_7_6, ++ GP_0_25_FN, FN_IP1_5_4, ++ GP_0_24_FN, FN_IP1_3_2, ++ GP_0_23_FN, FN_IP1_1_0, ++ GP_0_22_FN, FN_IP0_30_29, ++ GP_0_21_FN, FN_IP0_28_27, ++ GP_0_20_FN, FN_IP0_26_25, ++ GP_0_19_FN, FN_IP0_24_23, ++ GP_0_18_FN, FN_IP0_22_21, ++ GP_0_17_FN, FN_IP0_20_19, ++ GP_0_16_FN, FN_IP0_18_16, ++ GP_0_15_FN, FN_IP0_15, ++ GP_0_14_FN, FN_IP0_14, ++ GP_0_13_FN, FN_IP0_13, ++ GP_0_12_FN, FN_IP0_12, ++ GP_0_11_FN, FN_IP0_11, ++ GP_0_10_FN, FN_IP0_10, ++ GP_0_9_FN, FN_IP0_9, ++ GP_0_8_FN, FN_IP0_8, ++ GP_0_7_FN, FN_IP0_7, ++ GP_0_6_FN, FN_IP0_6, ++ GP_0_5_FN, FN_IP0_5, ++ GP_0_4_FN, FN_IP0_4, ++ GP_0_3_FN, FN_IP0_3, ++ GP_0_2_FN, FN_IP0_2, ++ GP_0_1_FN, FN_IP0_1, ++ GP_0_0_FN, FN_IP0_0, } ++ }, ++ { PINMUX_CFG_REG("GPSR1", 0xE6060008, 32, 1) { ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ GP_1_25_FN, FN_IP3_21_20, ++ GP_1_24_FN, FN_IP3_19_18, ++ GP_1_23_FN, FN_IP3_17_16, ++ GP_1_22_FN, FN_IP3_15_14, ++ GP_1_21_FN, FN_IP3_13_12, ++ GP_1_20_FN, FN_IP3_11_9, ++ GP_1_19_FN, FN_RD_N, ++ GP_1_18_FN, FN_IP3_8_6, ++ GP_1_17_FN, FN_IP3_5_3, ++ GP_1_16_FN, FN_IP3_2_0, ++ GP_1_15_FN, FN_IP2_29_27, ++ GP_1_14_FN, FN_IP2_26_25, ++ GP_1_13_FN, FN_IP2_24_23, ++ GP_1_12_FN, FN_EX_CS0_N, ++ GP_1_11_FN, FN_IP2_22_21, ++ GP_1_10_FN, FN_IP2_20_19, ++ GP_1_9_FN, FN_IP2_18_16, ++ GP_1_8_FN, FN_IP2_15_13, ++ GP_1_7_FN, FN_IP2_12_10, ++ GP_1_6_FN, FN_IP2_9_7, ++ GP_1_5_FN, FN_IP2_6_5, ++ GP_1_4_FN, FN_IP2_4_3, ++ GP_1_3_FN, FN_IP2_2_0, ++ GP_1_2_FN, FN_IP1_31_29, ++ GP_1_1_FN, FN_IP1_28_26, ++ GP_1_0_FN, FN_IP1_25_23, } ++ }, ++ { PINMUX_CFG_REG("GPSR2", 0xE606000C, 32, 1) { ++ GP_2_31_FN, FN_IP6_7_6, ++ GP_2_30_FN, FN_IP6_5_3, ++ GP_2_29_FN, FN_IP6_2_0, ++ GP_2_28_FN, FN_AUDIO_CLKA, ++ GP_2_27_FN, FN_IP5_31_29, ++ GP_2_26_FN, FN_IP5_28_26, ++ GP_2_25_FN, FN_IP5_25_24, ++ GP_2_24_FN, FN_IP5_23_22, ++ GP_2_23_FN, FN_IP5_21_20, ++ GP_2_22_FN, FN_IP5_19_17, ++ GP_2_21_FN, FN_IP5_16_15, ++ GP_2_20_FN, FN_IP5_14_12, ++ GP_2_19_FN, FN_IP5_11_9, ++ GP_2_18_FN, FN_IP5_8_6, ++ GP_2_17_FN, FN_IP5_5_3, ++ GP_2_16_FN, FN_IP5_2_0, ++ GP_2_15_FN, FN_IP4_30_28, ++ GP_2_14_FN, FN_IP4_27_26, ++ GP_2_13_FN, FN_IP4_25_24, ++ GP_2_12_FN, FN_IP4_23_22, ++ GP_2_11_FN, FN_IP4_21, ++ GP_2_10_FN, FN_IP4_20, ++ GP_2_9_FN, FN_IP4_19, ++ GP_2_8_FN, FN_IP4_18_16, ++ GP_2_7_FN, FN_IP4_15_13, ++ GP_2_6_FN, FN_IP4_12_10, ++ GP_2_5_FN, FN_IP4_9_8, ++ GP_2_4_FN, FN_IP4_7_5, ++ GP_2_3_FN, FN_IP4_4_2, ++ GP_2_2_FN, FN_IP4_1_0, ++ GP_2_1_FN, FN_IP3_30_28, ++ GP_2_0_FN, FN_IP3_27_25 } ++ }, ++ { PINMUX_CFG_REG("GPSR3", 0xE6060010, 32, 1) { ++ GP_3_31_FN, FN_IP9_18_17, ++ GP_3_30_FN, FN_IP9_16, ++ GP_3_29_FN, FN_IP9_15_13, ++ GP_3_28_FN, FN_IP9_12, ++ GP_3_27_FN, FN_IP9_11, ++ GP_3_26_FN, FN_IP9_10_8, ++ GP_3_25_FN, FN_IP9_7, ++ GP_3_24_FN, FN_IP9_6, ++ GP_3_23_FN, FN_IP9_5_3, ++ GP_3_22_FN, FN_IP9_2_0, ++ GP_3_21_FN, FN_IP8_30_28, ++ GP_3_20_FN, FN_IP8_27_26, ++ GP_3_19_FN, FN_IP8_25_24, ++ GP_3_18_FN, FN_IP8_23_21, ++ GP_3_17_FN, FN_IP8_20_18, ++ GP_3_16_FN, FN_IP8_17_15, ++ GP_3_15_FN, FN_IP8_14_12, ++ GP_3_14_FN, FN_IP8_11_9, ++ GP_3_13_FN, FN_IP8_8_6, ++ GP_3_12_FN, FN_IP8_5_3, ++ GP_3_11_FN, FN_IP8_2_0, ++ GP_3_10_FN, FN_IP7_29_27, ++ GP_3_9_FN, FN_IP7_26_24, ++ GP_3_8_FN, FN_IP7_23_21, ++ GP_3_7_FN, FN_IP7_20_19, ++ GP_3_6_FN, FN_IP7_18_17, ++ GP_3_5_FN, FN_IP7_16_15, ++ GP_3_4_FN, FN_IP7_14_13, ++ GP_3_3_FN, FN_IP7_12_11, ++ GP_3_2_FN, FN_IP7_10_9, ++ GP_3_1_FN, FN_IP7_8_6, ++ GP_3_0_FN, FN_IP7_5_3 } ++ }, ++ { PINMUX_CFG_REG("GPSR4", 0xE6060014, 32, 1) { ++ GP_4_31_FN, FN_IP15_5_4, ++ GP_4_30_FN, FN_IP15_3_2, ++ GP_4_29_FN, FN_IP15_1_0, ++ GP_4_28_FN, FN_IP11_8_6, ++ GP_4_27_FN, FN_IP11_5_3, ++ GP_4_26_FN, FN_IP11_2_0, ++ GP_4_25_FN, FN_IP10_31_29, ++ GP_4_24_FN, FN_IP10_28_27, ++ GP_4_23_FN, FN_IP10_26_25, ++ GP_4_22_FN, FN_IP10_24_22, ++ GP_4_21_FN, FN_IP10_21_19, ++ GP_4_20_FN, FN_IP10_18_17, ++ GP_4_19_FN, FN_IP10_16_15, ++ GP_4_18_FN, FN_IP10_14_12, ++ GP_4_17_FN, FN_IP10_11_9, ++ GP_4_16_FN, FN_IP10_8_6, ++ GP_4_15_FN, FN_IP10_5_3, ++ GP_4_14_FN, FN_IP10_2_0, ++ GP_4_13_FN, FN_IP9_31_29, ++ GP_4_12_FN, FN_VI0_DATA7_VI0_B7, ++ GP_4_11_FN, FN_VI0_DATA6_VI0_B6, ++ GP_4_10_FN, FN_VI0_DATA5_VI0_B5, ++ GP_4_9_FN, FN_VI0_DATA4_VI0_B4, ++ GP_4_8_FN, FN_IP9_28_27, ++ GP_4_7_FN, FN_VI0_DATA2_VI0_B2, ++ GP_4_6_FN, FN_VI0_DATA1_VI0_B1, ++ GP_4_5_FN, FN_VI0_DATA0_VI0_B0, ++ GP_4_4_FN, FN_IP9_26_25, ++ GP_4_3_FN, FN_IP9_24_23, ++ GP_4_2_FN, FN_IP9_22_21, ++ GP_4_1_FN, FN_IP9_20_19, ++ GP_4_0_FN, FN_VI0_CLK } ++ }, ++ { PINMUX_CFG_REG("GPSR5", 0xE6060018, 32, 1) { ++ GP_5_31_FN, FN_IP3_24_22, ++ GP_5_30_FN, FN_IP13_9_7, ++ GP_5_29_FN, FN_IP13_6_5, ++ GP_5_28_FN, FN_IP13_4_3, ++ GP_5_27_FN, FN_IP13_2_0, ++ GP_5_26_FN, FN_IP12_29_27, ++ GP_5_25_FN, FN_IP12_26_24, ++ GP_5_24_FN, FN_IP12_23_22, ++ GP_5_23_FN, FN_IP12_21_20, ++ GP_5_22_FN, FN_IP12_19_18, ++ GP_5_21_FN, FN_IP12_17_16, ++ GP_5_20_FN, FN_IP12_15_13, ++ GP_5_19_FN, FN_IP12_12_10, ++ GP_5_18_FN, FN_IP12_9_7, ++ GP_5_17_FN, FN_IP12_6_4, ++ GP_5_16_FN, FN_IP12_3_2, ++ GP_5_15_FN, FN_IP12_1_0, ++ GP_5_14_FN, FN_IP11_31_30, ++ GP_5_13_FN, FN_IP11_29_28, ++ GP_5_12_FN, FN_IP11_27, ++ GP_5_11_FN, FN_IP11_26, ++ GP_5_10_FN, FN_IP11_25, ++ GP_5_9_FN, FN_IP11_24, ++ GP_5_8_FN, FN_IP11_23, ++ GP_5_7_FN, FN_IP11_22, ++ GP_5_6_FN, FN_IP11_21, ++ GP_5_5_FN, FN_IP11_20, ++ GP_5_4_FN, FN_IP11_19, ++ GP_5_3_FN, FN_IP11_18_17, ++ GP_5_2_FN, FN_IP11_16_15, ++ GP_5_1_FN, FN_IP11_14_12, ++ GP_5_0_FN, FN_IP11_11_9 } ++ }, ++ { PINMUX_CFG_REG("GPSR6", 0xE606001C, 32, 1) { ++ GP_6_31_FN, FN_DU0_DOTCLKIN, ++ GP_6_30_FN, FN_USB1_OVC, ++ GP_6_29_FN, FN_IP14_31_29, ++ GP_6_28_FN, FN_IP14_28_26, ++ GP_6_27_FN, FN_IP14_25_23, ++ GP_6_26_FN, FN_IP14_22_20, ++ GP_6_25_FN, FN_IP14_19_17, ++ GP_6_24_FN, FN_IP14_16_14, ++ GP_6_23_FN, FN_IP14_13_11, ++ GP_6_22_FN, FN_IP14_10_8, ++ GP_6_21_FN, FN_IP14_7, ++ GP_6_20_FN, FN_IP14_6, ++ GP_6_19_FN, FN_IP14_5, ++ GP_6_18_FN, FN_IP14_4, ++ GP_6_17_FN, FN_IP14_3, ++ GP_6_16_FN, FN_IP14_2, ++ GP_6_15_FN, FN_IP14_1_0, ++ GP_6_14_FN, FN_IP13_30_28, ++ GP_6_13_FN, FN_IP13_27, ++ GP_6_12_FN, FN_IP13_26, ++ GP_6_11_FN, FN_IP13_25, ++ GP_6_10_FN, FN_IP13_24_23, ++ GP_6_9_FN, FN_IP13_22, ++ 0, 0, ++ GP_6_7_FN, FN_IP13_21_19, ++ GP_6_6_FN, FN_IP13_18_16, ++ GP_6_5_FN, FN_IP13_15, ++ GP_6_4_FN, FN_IP13_14, ++ GP_6_3_FN, FN_IP13_13, ++ GP_6_2_FN, FN_IP13_12, ++ GP_6_1_FN, FN_IP13_11, ++ GP_6_0_FN, FN_IP13_10 } ++ }, ++ { PINMUX_CFG_REG("GPSR7", 0xE6060074, 32, 1) { ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ 0, 0, ++ GP_7_25_FN, FN_USB1_PWEN, ++ GP_7_24_FN, FN_USB0_OVC, ++ GP_7_23_FN, FN_USB0_PWEN, ++ GP_7_22_FN, FN_IP15_14_12, ++ GP_7_21_FN, FN_IP15_11_9, ++ GP_7_20_FN, FN_IP15_8_6, ++ GP_7_19_FN, FN_IP7_2_0, ++ GP_7_18_FN, FN_IP6_29_27, ++ GP_7_17_FN, FN_IP6_26_24, ++ GP_7_16_FN, FN_IP6_23_21, ++ GP_7_15_FN, FN_IP6_20_19, ++ GP_7_14_FN, FN_IP6_18_16, ++ GP_7_13_FN, FN_IP6_15_14, ++ GP_7_12_FN, FN_IP6_13_12, ++ GP_7_11_FN, FN_IP6_11_10, ++ GP_7_10_FN, FN_IP6_9_8, ++ GP_7_9_FN, FN_IP16_11_10, ++ GP_7_8_FN, FN_IP16_9_8, ++ GP_7_7_FN, FN_IP16_7_6, ++ GP_7_6_FN, FN_IP16_5_3, ++ GP_7_5_FN, FN_IP16_2_0, ++ GP_7_4_FN, FN_IP15_29_27, ++ GP_7_3_FN, FN_IP15_26_24, ++ GP_7_2_FN, FN_IP15_23_21, ++ GP_7_1_FN, FN_IP15_20_18, ++ GP_7_0_FN, FN_IP15_17_15 } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR0", 0xE6060020, 32, ++ 1, 2, 2, 2, 2, 2, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, ++ 1, 1, 1, 1, 1, 1, 1, 1) { ++ /* IP0_31 [1] */ ++ 0, 0, ++ /* IP0_30_29 [2] */ ++ FN_A6, FN_MSIOF1_SCK, ++ 0, 0, ++ /* IP0_28_27 [2] */ ++ FN_A5, FN_MSIOF0_RXD_B, ++ 0, 0, ++ /* IP0_26_25 [2] */ ++ FN_A4, FN_MSIOF0_TXD_B, ++ 0, 0, ++ /* IP0_24_23 [2] */ ++ FN_A3, FN_MSIOF0_SS2_B, ++ 0, 0, ++ /* IP0_22_21 [2] */ ++ FN_A2, FN_MSIOF0_SS1_B, ++ 0, 0, ++ /* IP0_20_19 [2] */ ++ FN_A1, FN_MSIOF0_SYNC_B, ++ 0, 0, ++ /* IP0_18_16 [3] */ ++ FN_A0, FN_ATAWR0_N_C, FN_MSIOF0_SCK_B, FN_SCL0_C, FN_PWM2_B, ++ 0, 0, 0, ++ /* IP0_15 [1] */ ++ FN_D15, 0, ++ /* IP0_14 [1] */ ++ FN_D14, 0, ++ /* IP0_13 [1] */ ++ FN_D13, 0, ++ /* IP0_12 [1] */ ++ FN_D12, 0, ++ /* IP0_11 [1] */ ++ FN_D11, 0, ++ /* IP0_10 [1] */ ++ FN_D10, 0, ++ /* IP0_9 [1] */ ++ FN_D9, 0, ++ /* IP0_8 [1] */ ++ FN_D8, 0, ++ /* IP0_7 [1] */ ++ FN_D7, 0, ++ /* IP0_6 [1] */ ++ FN_D6, 0, ++ /* IP0_5 [1] */ ++ FN_D5, 0, ++ /* IP0_4 [1] */ ++ FN_D4, 0, ++ /* IP0_3 [1] */ ++ FN_D3, 0, ++ /* IP0_2 [1] */ ++ FN_D2, 0, ++ /* IP0_1 [1] */ ++ FN_D1, 0, ++ /* IP0_0 [1] */ ++ FN_D0, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR1", 0xE6060024, 32, ++ 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2) { ++ /* IP1_31_29 [3] */ ++ FN_A18, FN_DREQ1, FN_SCIFA1_RXD_C, 0, FN_SCIFB1_RXD_C, ++ 0, 0, 0, ++ /* IP1_28_26 [3] */ ++ FN_A17, FN_DACK2_B, 0, FN_SDA0_C, ++ 0, 0, 0, 0, ++ /* IP1_25_23 [3] */ ++ FN_A16, FN_DREQ2_B, FN_FMCLK_C, 0, FN_SCIFA1_SCK_B, ++ 0, 0, 0, ++ /* IP1_22_20 [3] */ ++ FN_A15, FN_BPFCLK_C, ++ 0, 0, 0, 0, 0, 0, ++ /* IP1_19_17 [3] */ ++ FN_A14, FN_ATADIR0_N_C, FN_FMIN, FN_FMIN_C, FN_MSIOF1_SYNC_D, ++ 0, 0, 0, ++ /* IP1_16_14 [3] */ ++ FN_A13, FN_ATAG0_N_C, FN_BPFCLK, FN_MSIOF1_SS1_D, ++ 0, 0, 0, 0, ++ /* IP1_13_11 [3] */ ++ FN_A12, FN_FMCLK, FN_SDA3_D, FN_MSIOF1_SCK_D, ++ 0, 0, 0, 0, ++ /* IP1_10_8 [3] */ ++ FN_A11, FN_MSIOF1_RXD, FN_SCL3_D, FN_MSIOF1_RXD_D, ++ 0, 0, 0, 0, ++ /* IP1_7_6 [2] */ ++ FN_A10, FN_MSIOF1_TXD, 0, FN_MSIOF1_TXD_D, ++ /* IP1_5_4 [2] */ ++ FN_A9, FN_MSIOF1_SS2, FN_SDA0, 0, ++ /* IP1_3_2 [2] */ ++ FN_A8, FN_MSIOF1_SS1, FN_SCL0, 0, ++ /* IP1_1_0 [2] */ ++ FN_A7, FN_MSIOF1_SYNC, ++ 0, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR2", 0xE6060028, 32, ++ 2, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 3) { ++ /* IP2_31_20 [2] */ ++ 0, 0, 0, 0, ++ /* IP2_29_27 [3] */ ++ FN_EX_CS3_N, FN_ATADIR0_N, FN_MSIOF2_TXD, ++ FN_ATAG0_N, 0, FN_EX_WAIT1, ++ 0, 0, ++ /* IP2_26_25 [2] */ ++ FN_EX_CS2_N, FN_ATAWR0_N, FN_MSIOF2_SYNC, 0, ++ /* IP2_24_23 [2] */ ++ FN_EX_CS1_N, FN_MSIOF2_SCK, 0, 0, ++ /* IP2_22_21 [2] */ ++ FN_CS1_N_A26, FN_ATADIR0_N_B, FN_SDA1, 0, ++ /* IP2_20_19 [2] */ ++ FN_CS0_N, FN_ATAG0_N_B, FN_SCL1, 0, ++ /* IP2_18_16 [3] */ ++ FN_A25, FN_DACK2, FN_SSL, FN_DREQ1_C, FN_RX1, FN_SCIFA1_RXD, ++ 0, 0, ++ /* IP2_15_13 [3] */ ++ FN_A24, FN_DREQ2, FN_IO3, FN_TX1, FN_SCIFA1_TXD, ++ 0, 0, 0, ++ /* IP2_12_0 [3] */ ++ FN_A23, FN_IO2, FN_BPFCLK_B, FN_RX0, FN_SCIFA0_RXD, ++ 0, 0, 0, ++ /* IP2_9_7 [3] */ ++ FN_A22, FN_MISO_IO1, FN_FMCLK_B, FN_TX0, FN_SCIFA0_TXD, ++ 0, 0, 0, ++ /* IP2_6_5 [2] */ ++ FN_A21, FN_ATAWR0_N_B, FN_MOSI_IO0, 0, ++ /* IP2_4_3 [2] */ ++ FN_A20, FN_SPCLK, 0, 0, ++ /* IP2_2_0 [3] */ ++ FN_A19, FN_DACK1, FN_SCIFA1_TXD_C, 0, ++ FN_SCIFB1_TXD_C, 0, FN_SCIFB1_SCK_B, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR3", 0xE606002C, 32, ++ 1, 3, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 3) { ++ /* IP3_31 [1] */ ++ 0, 0, ++ /* IP3_30_28 [3] */ ++ FN_SSI_WS0129, FN_HTX0_C, FN_HTX2_C, ++ FN_SCIFB0_TXD_C, FN_SCIFB2_TXD_C, ++ 0, 0, 0, ++ /* IP3_27_25 [3] */ ++ FN_SSI_SCK0129, FN_HRX0_C, FN_HRX2_C, ++ FN_SCIFB0_RXD_C, FN_SCIFB2_RXD_C, ++ 0, 0, 0, ++ /* IP3_24_22 [3] */ ++ FN_SPEEDIN, 0, FN_HSCK0_C, FN_HSCK2_C, FN_SCIFB0_SCK_B, ++ FN_SCIFB2_SCK_B, FN_DREQ2_C, FN_HTX2_D, ++ /* IP3_21_20 [2] */ ++ FN_DACK0, FN_DRACK0, FN_REMOCON, 0, ++ /* IP3_19_18 [2] */ ++ FN_DREQ0, FN_PWM3, FN_TPU_TO3, 0, ++ /* IP3_17_16 [2] */ ++ FN_EX_WAIT0, FN_HRTS2_N_B, FN_SCIFB0_CTS_N_B, 0, ++ /* IP3_15_14 [2] */ ++ FN_WE1_N, FN_ATARD0_N_B, FN_HTX2_B, FN_SCIFB0_RTS_N_B, ++ /* IP3_13_12 [2] */ ++ FN_WE0_N, FN_HCTS2_N_B, FN_SCIFB0_TXD_B, 0, ++ /* IP3_11_9 [3] */ ++ FN_RD_WR_N, FN_HRX2_B, FN_FMIN_B, FN_SCIFB0_RXD_B, FN_DREQ1_D, ++ 0, 0, 0, ++ /* IP3_8_6 [3] */ ++ FN_BS_N, FN_ATACS10_N, FN_MSIOF2_SS2, FN_HTX1_B, ++ FN_SCIFB1_TXD_B, FN_PWM2, FN_TPU_TO2, 0, ++ /* IP3_5_3 [3] */ ++ FN_EX_CS5_N, FN_ATACS00_N, FN_MSIOF2_SS1, FN_HRX1_B, ++ FN_SCIFB1_RXD_B, FN_PWM1, FN_TPU_TO1, 0, ++ /* IP3_2_0 [3] */ ++ FN_EX_CS4_N, FN_ATARD0_N, FN_MSIOF2_RXD, 0, FN_EX_WAIT2, ++ 0, 0, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR4", 0xE6060030, 32, ++ 1, 3, 2, 2, 2, 1, 1, 1, 3, 3, 3, 2, 3, 3, 2) { ++ /* IP4_31 [1] */ ++ 0, 0, ++ /* IP4_30_28 [3] */ ++ FN_SSI_SCK5, FN_MSIOF1_SCK_C, FN_TS_SDATA0, FN_GLO_I0, ++ FN_MSIOF2_SYNC_D, FN_VI1_R2_B, ++ 0, 0, ++ /* IP4_27_26 [2] */ ++ FN_SSI_SDATA4, FN_MSIOF2_SCK_D, 0, 0, ++ /* IP4_25_24 [2] */ ++ FN_SSI_WS4, FN_GLO_RFON_D, 0, 0, ++ /* IP4_23_22 [2] */ ++ FN_SSI_SCK4, FN_GLO_SS_D, 0, 0, ++ /* IP4_21 [1] */ ++ FN_SSI_SDATA3, 0, ++ /* IP4_20 [1] */ ++ FN_SSI_WS34, 0, ++ /* IP4_19 [1] */ ++ FN_SSI_SCK34, 0, ++ /* IP4_18_16 [3] */ ++ FN_SSI_SDATA2, FN_GPS_MAG_B, FN_TX2_E, FN_HRTS1_N_E, ++ 0, 0, 0, 0, ++ /* IP4_15_13 [3] */ ++ FN_SSI_WS2, FN_SDA2, FN_GPS_SIGN_B, FN_RX2_E, ++ FN_GLO_Q1_D, FN_HCTS1_N_E, ++ 0, 0, ++ /* IP4_12_10 [3] */ ++ FN_SSI_SCK2, FN_SCL2, FN_GPS_CLK_B, FN_GLO_Q0_D, FN_HSCK1_E, ++ 0, 0, 0, ++ /* IP4_9_8 [2] */ ++ FN_SSI_SDATA1, FN_SDA1_B, FN_SDA8_B, FN_MSIOF2_RXD_C, ++ /* IP4_7_5 [3] */ ++ FN_SSI_WS1, FN_SCL1_B, FN_SCL8_B, FN_MSIOF2_TXD_C, FN_GLO_I1_D, ++ 0, 0, 0, ++ /* IP4_4_2 [3] */ ++ FN_SSI_SCK1, FN_SDA0_B, FN_SDA7_B, ++ FN_MSIOF2_SYNC_C, FN_GLO_I0_D, ++ 0, 0, 0, ++ /* IP4_1_0 [2] */ ++ FN_SSI_SDATA0, FN_SCL0_B, FN_SCL7_B, FN_MSIOF2_SCK_C, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR5", 0xE6060034, 32, ++ 3, 3, 2, 2, 2, 3, 2, 3, 3, 3, 3, 3) { ++ /* IP5_31_29 [3] */ ++ FN_SSI_SDATA9, FN_RX3_D, FN_CAN0_RX_D, ++ 0, 0, 0, 0, 0, ++ /* IP5_28_26 [3] */ ++ FN_SSI_WS9, FN_TX3_D, FN_CAN0_TX_D, FN_GLO_SDATA_D, ++ 0, 0, 0, 0, ++ /* IP5_25_24 [2] */ ++ FN_SSI_SCK9, FN_RX1_D, FN_GLO_SCLK_D, 0, ++ /* IP5_23_22 [2] */ ++ FN_SSI_SDATA8, FN_TX1_D, FN_STP_ISSYNC_0_B, 0, ++ /* IP5_21_20 [2] */ ++ FN_SSI_SDATA7, FN_RX0_D, FN_STP_ISEN_0_B, 0, ++ /* IP5_19_17 [3] */ ++ FN_SSI_WS78, FN_TX0_D, FN_STP_ISD_0_B, FN_GLO_RFON, ++ 0, 0, 0, 0, ++ /* IP5_16_15 [2] */ ++ FN_SSI_SCK78, FN_STP_ISCLK_0_B, FN_GLO_SS, 0, ++ /* IP5_14_12 [3] */ ++ FN_SSI_SDATA6, FN_STP_IVCXO27_0_B, FN_GLO_SDATA, FN_VI1_R7_B, ++ 0, 0, 0, 0, ++ /* IP5_11_9 [3] */ ++ FN_SSI_WS6, FN_GLO_SCLK, FN_MSIOF2_SS2_D, FN_VI1_R6_B, ++ 0, 0, 0, 0, ++ /* IP5_8_6 [3] */ ++ FN_SSI_SCK6, FN_MSIOF1_RXD_C, FN_TS_SPSYNC0, FN_GLO_Q1, ++ FN_MSIOF2_RXD_D, FN_VI1_R5_B, ++ 0, 0, ++ /* IP5_5_3 [3] */ ++ FN_SSI_SDATA5, FN_MSIOF1_TXD_C, FN_TS_SDEN0, FN_GLO_Q0, ++ FN_MSIOF2_SS1_D, FN_VI1_R4_B, ++ 0, 0, ++ /* IP5_2_0 [3] */ ++ FN_SSI_WS5, FN_MSIOF1_SYNC_C, FN_TS_SCK0, FN_GLO_I1, ++ FN_MSIOF2_TXD_D, FN_VI1_R3_B, ++ 0, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR6", 0xE6060038, 32, ++ 2, 3, 3, 3, 2, 3, 2, 2, 2, 2, 2, 3, 3) { ++ /* IP6_31_30 [2] */ ++ 0, 0, 0, 0, ++ /* IP6_29_27 [3] */ ++ FN_IRQ8, FN_HRTS1_N_C, FN_MSIOF1_RXD_B, ++ FN_GPS_SIGN_C, FN_GPS_SIGN_D, ++ 0, 0, 0, ++ /* IP6_26_24 [3] */ ++ FN_IRQ7, FN_HCTS1_N_C, FN_MSIOF1_TXD_B, ++ FN_GPS_CLK_C, FN_GPS_CLK_D, ++ 0, 0, 0, ++ /* IP6_23_21 [3] */ ++ FN_IRQ6, FN_HSCK1_C, FN_MSIOF1_SS2_B, ++ FN_SDA1_E, FN_MSIOF2_SYNC_E, ++ 0, 0, 0, ++ /* IP6_20_19 [2] */ ++ FN_IRQ5, FN_HTX1_C, FN_SCL1_E, FN_MSIOF2_SCK_E, ++ /* IP6_18_16 [3] */ ++ FN_IRQ4, FN_HRX1_C, FN_SDA4_C, FN_MSIOF2_RXD_E, FN_INTC_IRQ4_N, ++ 0, 0, 0, ++ /* IP6_15_14 [2] */ ++ FN_IRQ3, FN_SCL4_C, FN_MSIOF2_TXD_E, FN_INTC_IRQ3_N, ++ /* IP6_13_12 [2] */ ++ FN_IRQ2, FN_SCIFB1_TXD_D, FN_INTC_IRQ2_N, 0, ++ /* IP6_11_10 [2] */ ++ FN_IRQ1, FN_SCIFB1_SCK_C, FN_INTC_IRQ1_N, 0, ++ /* IP6_9_8 [2] */ ++ FN_IRQ0, FN_SCIFB1_RXD_D, FN_INTC_IRQ0_N, 0, ++ /* IP6_7_6 [2] */ ++ FN_AUDIO_CLKOUT, FN_MSIOF1_SS1_B, FN_TX2, FN_SCIFA2_TXD, ++ /* IP6_5_3 [3] */ ++ FN_AUDIO_CLKC, FN_SCIFB0_SCK_C, FN_MSIOF1_SYNC_B, FN_RX2, ++ FN_SCIFA2_RXD, FN_FMIN_E, ++ 0, 0, ++ /* IP6_2_0 [3] */ ++ FN_AUDIO_CLKB, FN_STP_OPWM_0_B, FN_MSIOF1_SCK_B, ++ FN_SCIF_CLK, 0, FN_BPFCLK_E, ++ 0, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR7", 0xE606003C, 32, ++ 2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 3, 3, 3) { ++ /* IP7_31_30 [2] */ ++ 0, 0, 0, 0, ++ /* IP7_29_27 [3] */ ++ FN_DU1_DG2, FN_LCDOUT10, FN_VI1_DATA4_B, FN_SCIF1_SCK_B, ++ FN_SCIFA1_SCK, FN_SSI_SCK78_B, ++ 0, 0, ++ /* IP7_26_24 [3] */ ++ FN_DU1_DG1, FN_LCDOUT9, FN_VI1_DATA3_B, FN_RX1_B, ++ FN_SCIFA1_RXD_B, FN_MSIOF2_SS2_B, ++ 0, 0, ++ /* IP7_23_21 [3] */ ++ FN_DU1_DG0, FN_LCDOUT8, FN_VI1_DATA2_B, FN_TX1_B, ++ FN_SCIFA1_TXD_B, FN_MSIOF2_SS1_B, ++ 0, 0, ++ /* IP7_20_19 [2] */ ++ FN_DU1_DR7, FN_LCDOUT7, FN_SSI_SDATA1_B, 0, ++ /* IP7_18_17 [2] */ ++ FN_DU1_DR6, FN_LCDOUT6, FN_SSI_WS1_B, 0, ++ /* IP7_16_15 [2] */ ++ FN_DU1_DR5, FN_LCDOUT5, FN_SSI_SCK1_B, 0, ++ /* IP7_14_13 [2] */ ++ FN_DU1_DR4, FN_LCDOUT4, FN_SSI_SDATA0_B, 0, ++ /* IP7_12_11 [2] */ ++ FN_DU1_DR3, FN_LCDOUT3, FN_SSI_WS0129_B, 0, ++ /* IP7_10_9 [2] */ ++ FN_DU1_DR2, FN_LCDOUT2, FN_SSI_SCK0129_B, 0, ++ /* IP7_8_6 [3] */ ++ FN_DU1_DR1, FN_LCDOUT1, FN_VI1_DATA1_B, FN_RX0_B, ++ FN_SCIFA0_RXD_B, FN_MSIOF2_SYNC_B, ++ 0, 0, ++ /* IP7_5_3 [3] */ ++ FN_DU1_DR0, FN_LCDOUT0, FN_VI1_DATA0_B, FN_TX0_B, ++ FN_SCIFA0_TXD_B, FN_MSIOF2_SCK_B, ++ 0, 0, ++ /* IP7_2_0 [3] */ ++ FN_IRQ9, FN_DU1_DOTCLKIN_B, FN_CAN_CLK_D, FN_GPS_MAG_C, ++ FN_SCIF_CLK_B, FN_GPS_MAG_D, ++ 0, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR8", 0xE6060040, 32, ++ 1, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3) { ++ /* IP8_31 [1] */ ++ 0, 0, ++ /* IP8_30_28 [3] */ ++ FN_DU1_DB5, FN_LCDOUT21, FN_TX3, FN_SCIFA3_TXD, FN_CAN1_TX, ++ 0, 0, 0, ++ /* IP8_27_26 [2] */ ++ FN_DU1_DB4, FN_LCDOUT20, FN_VI1_FIELD_B, FN_CAN1_RX, ++ /* IP8_25_24 [2] */ ++ FN_DU1_DB3, FN_LCDOUT19, FN_VI1_CLKENB_B, 0, ++ /* IP8_23_21 [3] */ ++ FN_DU1_DB2, FN_LCDOUT18, FN_VI1_VSYNC_N_B, FN_SCIF2_SCK_B, ++ FN_SCIFA2_SCK, FN_SSI_SDATA9_B, ++ 0, 0, ++ /* IP8_20_18 [3] */ ++ FN_DU1_DB1, FN_LCDOUT17, FN_VI1_HSYNC_N_B, FN_RX2_B, ++ FN_SCIFA2_RXD_B, FN_MSIOF2_RXD_B, ++ 0, 0, ++ /* IP8_17_15 [3] */ ++ FN_DU1_DB0, FN_LCDOUT16, FN_VI1_CLK_B, FN_TX2_B, ++ FN_SCIFA2_TXD_B, FN_MSIOF2_TXD_B, ++ 0, 0, ++ /* IP8_14_12 [3] */ ++ FN_DU1_DG7, FN_LCDOUT15, FN_HTX0_B, ++ FN_SCIFB2_RTS_N_B, FN_SSI_WS9_B, ++ 0, 0, 0, ++ /* IP8_11_9 [3] */ ++ FN_DU1_DG6, FN_LCDOUT14, FN_HRTS0_N_B, ++ FN_SCIFB2_CTS_N_B, FN_SSI_SCK9_B, ++ 0, 0, 0, ++ /* IP8_8_6 [3] */ ++ FN_DU1_DG5, FN_LCDOUT13, FN_VI1_DATA7_B, FN_HCTS0_N_B, ++ FN_SCIFB2_TXD_B, FN_SSI_SDATA8_B, ++ 0, 0, ++ /* IP8_5_3 [3] */ ++ FN_DU1_DG4, FN_LCDOUT12, FN_VI1_DATA6_B, FN_HRX0_B, ++ FN_SCIFB2_RXD_B, FN_SSI_SDATA7_B, ++ 0, 0, ++ /* IP8_2_0 [3] */ ++ FN_DU1_DG3, FN_LCDOUT11, FN_VI1_DATA5_B, 0, FN_SSI_WS78_B, ++ 0, 0, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR9", 0xE6060044, 32, ++ 3, 2, 2, 2, 2, 2, 2, 1, 3, 1, 1, 3, 1, 1, 3, 3) { ++ /* IP9_31_29 [3] */ ++ FN_VI0_G0, FN_SCL8, FN_STP_IVCXO27_0_C, FN_SCL4, ++ FN_HCTS2_N, FN_SCIFB2_CTS_N, FN_ATAWR1_N, 0, ++ /* IP9_28_27 [2] */ ++ FN_VI0_DATA3_VI0_B3, FN_SCIF3_SCK_B, FN_SCIFA3_SCK_B, 0, ++ /* IP9_26_25 [2] */ ++ FN_VI0_VSYNC_N, FN_RX5, FN_SCIFA5_RXD, FN_TS_SPSYNC0_D, ++ /* IP9_24_23 [2] */ ++ FN_VI0_HSYNC_N, FN_TX5, FN_SCIFA5_TXD, FN_TS_SDEN0_D, ++ /* IP9_22_21 [2] */ ++ FN_VI0_FIELD, FN_RX4, FN_SCIFA4_RXD, FN_TS_SCK0_D, ++ /* IP9_20_19 [2] */ ++ FN_VI0_CLKENB, FN_TX4, FN_SCIFA4_TXD, FN_TS_SDATA0_D, ++ /* IP9_18_17 [2] */ ++ FN_DU1_CDE, FN_QPOLB, FN_PWM4_B, 0, ++ /* IP9_16 [1] */ ++ FN_DU1_DISP, FN_QPOLA, ++ /* IP9_15_13 [3] */ ++ FN_DU1_EXODDF_DU1_ODDF_DISP_CDE, FN_QCPV_QDE, ++ FN_CAN0_RX, FN_RX3_B, FN_SDA2_B, ++ 0, 0, 0, ++ /* IP9_12 [1] */ ++ FN_DU1_EXVSYNC_DU1_VSYNC, FN_QSTB_QHE, ++ /* IP9_11 [1] */ ++ FN_DU1_EXHSYNC_DU1_HSYNC, FN_QSTH_QHS, ++ /* IP9_10_8 [3] */ ++ FN_DU1_DOTCLKOUT1, FN_QSTVB_QVE, FN_CAN0_TX, ++ FN_TX3_B, FN_SCL2_B, FN_PWM4, ++ 0, 0, ++ /* IP9_7 [1] */ ++ FN_DU1_DOTCLKOUT0, FN_QCLK, ++ /* IP9_6 [1] */ ++ FN_DU1_DOTCLKIN, FN_QSTVA_QVS, ++ /* IP9_5_3 [3] */ ++ FN_DU1_DB7, FN_LCDOUT23, FN_SDA3_C, ++ FN_SCIF3_SCK, FN_SCIFA3_SCK, ++ 0, 0, 0, ++ /* IP9_2_0 [3] */ ++ FN_DU1_DB6, FN_LCDOUT22, FN_SCL3_C, FN_RX3, FN_SCIFA3_RXD, ++ 0, 0, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR10", 0xE6060048, 32, ++ 3, 2, 2, 3, 3, 2, 2, 3, 3, 3, 3, 3) { ++ /* IP10_31_29 [3] */ ++ FN_VI0_R4, FN_VI2_DATA5, FN_GLO_SCLK_B, FN_TX0_C, FN_SCL1_D, ++ 0, 0, 0, ++ /* IP10_28_27 [2] */ ++ FN_VI0_R3, FN_VI2_DATA4, FN_GLO_Q1_B, FN_TS_SPSYNC0_C, ++ /* IP10_26_25 [2] */ ++ FN_VI0_R2, FN_VI2_DATA3, FN_GLO_Q0_B, FN_TS_SDEN0_C, ++ /* IP10_24_22 [3] */ ++ FN_VI0_R1, FN_VI2_DATA2, FN_GLO_I1_B, FN_TS_SCK0_C, FN_ATAG1_N, ++ 0, 0, 0, ++ /* IP10_21_29 [3] */ ++ FN_VI0_R0, FN_VI2_DATA1, FN_GLO_I0_B, ++ FN_TS_SDATA0_C, FN_ATACS11_N, ++ 0, 0, 0, ++ /* IP10_18_17 [2] */ ++ FN_VI0_G7, FN_VI2_DATA0, FN_FMIN_D, 0, ++ /* IP10_16_15 [2] */ ++ FN_VI0_G6, FN_VI2_CLK, FN_BPFCLK_D, 0, ++ /* IP10_14_12 [3] */ ++ FN_VI0_G5, FN_VI2_FIELD, FN_STP_OPWM_0_C, FN_FMCLK_D, ++ FN_CAN0_TX_E, FN_HTX1_D, FN_SCIFB0_TXD_D, 0, ++ /* IP10_11_9 [3] */ ++ FN_VI0_G4, FN_VI2_CLKENB, FN_STP_ISSYNC_0_C, ++ FN_HTX2, FN_SCIFB2_TXD, FN_SCIFB0_SCK_D, ++ 0, 0, ++ /* IP10_8_6 [3] */ ++ FN_VI0_G3, FN_VI2_VSYNC_N, FN_STP_ISEN_0_C, FN_SDA3_B, ++ FN_HRX2, FN_SCIFB2_RXD, FN_ATACS01_N, 0, ++ /* IP10_5_3 [3] */ ++ FN_VI0_G2, FN_VI2_HSYNC_N, FN_STP_ISD_0_C, FN_SCL3_B, ++ FN_HSCK2, FN_SCIFB2_SCK, FN_ATARD1_N, 0, ++ /* IP10_2_0 [3] */ ++ FN_VI0_G1, FN_SDA8, FN_STP_ISCLK_0_C, FN_SDA4, ++ FN_HRTS2_N, FN_SCIFB2_RTS_N, FN_ATADIR1_N, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR11", 0xE606004C, 32, ++ 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, ++ 3, 3, 3, 3, 3) { ++ /* IP11_31_30 [2] */ ++ FN_ETH_CRS_DV, FN_AVB_LINK, FN_SDA2_C, 0, ++ /* IP11_29_28 [2] */ ++ FN_ETH_MDIO, FN_AVB_RX_CLK, FN_SCL2_C, 0, ++ /* IP11_27 [1] */ ++ FN_VI1_DATA7, FN_AVB_MDC, ++ /* IP11_26 [1] */ ++ FN_VI1_DATA6, FN_AVB_MAGIC, ++ /* IP11_25 [1] */ ++ FN_VI1_DATA5, FN_AVB_RX_DV, ++ /* IP11_24 [1] */ ++ FN_VI1_DATA4, FN_AVB_MDIO, ++ /* IP11_23 [1] */ ++ FN_VI1_DATA3, FN_AVB_RX_ER, ++ /* IP11_22 [1] */ ++ FN_VI1_DATA2, FN_AVB_RXD7, ++ /* IP11_21 [1] */ ++ FN_VI1_DATA1, FN_AVB_RXD6, ++ /* IP11_20 [1] */ ++ FN_VI1_DATA0, FN_AVB_RXD5, ++ /* IP11_19 [1] */ ++ FN_VI1_CLK, FN_AVB_RXD4, ++ /* IP11_18_17 [2] */ ++ FN_VI1_FIELD, FN_AVB_RXD3, FN_TS_SPSYNC0_B, 0, ++ /* IP11_16_15 [2] */ ++ FN_VI1_CLKENB, FN_AVB_RXD2, FN_TS_SDEN0_B, 0, ++ /* IP11_14_12 [3] */ ++ FN_VI1_VSYNC_N, FN_AVB_RXD1, FN_TS_SCK0_B, ++ FN_RX4_B, FN_SCIFA4_RXD_B, ++ 0, 0, 0, ++ /* IP11_11_9 [3] */ ++ FN_VI1_HSYNC_N, FN_AVB_RXD0, FN_TS_SDATA0_B, ++ FN_TX4_B, FN_SCIFA4_TXD_B, ++ 0, 0, 0, ++ /* IP11_8_6 [3] */ ++ FN_VI0_R7, FN_GLO_RFON_B, FN_RX1_C, FN_CAN0_RX_E, ++ FN_SDA4_B, FN_HRX1_D, FN_SCIFB0_RXD_D, 0, ++ /* IP11_5_3 [3] */ ++ FN_VI0_R6, FN_VI2_DATA7, FN_GLO_SS_B, FN_TX1_C, FN_SCL4_B, ++ 0, 0, 0, ++ /* IP11_2_0 [3] */ ++ FN_VI0_R5, FN_VI2_DATA6, FN_GLO_SDATA_B, FN_RX0_C, FN_SDA1_D, ++ 0, 0, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR12", 0xE6060050, 32, ++ 2, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2) { ++ /* IP12_31_30 [2] */ ++ 0, 0, 0, 0, ++ /* IP12_29_27 [3] */ ++ FN_STP_ISCLK_0, FN_AVB_TX_EN, FN_SCIFB2_RXD_D, ++ FN_ADICS_SAMP_B, FN_MSIOF0_SCK_C, ++ 0, 0, 0, ++ /* IP12_26_24 [3] */ ++ FN_STP_IVCXO27_0, FN_AVB_TXD7, FN_SCIFB2_TXD_D, ++ FN_ADIDATA_B, FN_MSIOF0_SYNC_C, ++ 0, 0, 0, ++ /* IP12_23_22 [2] */ ++ FN_ETH_MDC, FN_AVB_TXD6, FN_IERX_C, 0, ++ /* IP12_21_20 [2] */ ++ FN_ETH_TXD0, FN_AVB_TXD5, FN_IECLK_C, 0, ++ /* IP12_19_18 [2] */ ++ FN_ETH_MAGIC, FN_AVB_TXD4, FN_IETX_C, 0, ++ /* IP12_17_16 [2] */ ++ FN_ETH_TX_EN, FN_AVB_TXD3, FN_TCLK1_B, FN_CAN_CLK_B, ++ /* IP12_15_13 [3] */ ++ FN_ETH_TXD1, FN_AVB_TXD2, FN_SCIFA3_TXD_B, ++ FN_CAN1_TX_C, FN_MSIOF1_TXD_E, ++ 0, 0, 0, ++ /* IP12_12_10 [3] */ ++ FN_ETH_REFCLK, FN_AVB_TXD1, FN_SCIFA3_RXD_B, ++ FN_CAN1_RX_C, FN_MSIOF1_SYNC_E, ++ 0, 0, 0, ++ /* IP12_9_7 [3] */ ++ FN_ETH_LINK, FN_AVB_TXD0, FN_CAN0_RX_C, ++ FN_SDA2_D, FN_MSIOF1_SCK_E, ++ 0, 0, 0, ++ /* IP12_6_4 [3] */ ++ FN_ETH_RXD1, FN_AVB_GTXREFCLK, FN_CAN0_TX_C, ++ FN_SCL2_D, FN_MSIOF1_RXD_E, ++ 0, 0, 0, ++ /* IP12_3_2 [2] */ ++ FN_ETH_RXD0, FN_AVB_PHY_INT, FN_SDA3, FN_SDA7, ++ /* IP12_1_0 [2] */ ++ FN_ETH_RX_ER, FN_AVB_CRS, FN_SCL3, FN_SCL7, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR13", 0xE6060054, 32, ++ 1, 3, 1, 1, 1, 2, 1, 3, 3, 1, 1, 1, 1, 1, 1, ++ 3, 2, 2, 3) { ++ /* IP13_31 [1] */ ++ 0, 0, ++ /* IP13_30_28 [3] */ ++ FN_SD1_CD, FN_PWM0, FN_TPU_TO0, FN_SCL1_C, ++ 0, 0, 0, 0, ++ /* IP13_27 [1] */ ++ FN_SD1_DATA3, FN_IERX_B, ++ /* IP13_26 [1] */ ++ FN_SD1_DATA2, FN_IECLK_B, ++ /* IP13_25 [1] */ ++ FN_SD1_DATA1, FN_IETX_B, ++ /* IP13_24_23 [2] */ ++ FN_SD1_DATA0, FN_SPEEDIN_B, 0, 0, ++ /* IP13_22 [1] */ ++ FN_SD1_CMD, FN_REMOCON_B, ++ /* IP13_21_19 [3] */ ++ FN_SD0_WP, FN_MMC_D7_B, FN_SIM0_D_B, FN_CAN0_TX_F, ++ FN_SCIFA5_RXD_B, FN_RX3_C, ++ 0, 0, ++ /* IP13_18_16 [3] */ ++ FN_SD0_CD, FN_MMC_D6_B, FN_SIM0_RST_B, FN_CAN0_RX_F, ++ FN_SCIFA5_TXD_B, FN_TX3_C, ++ 0, 0, ++ /* IP13_15 [1] */ ++ FN_SD0_DATA3, FN_SSL_B, ++ /* IP13_14 [1] */ ++ FN_SD0_DATA2, FN_IO3_B, ++ /* IP13_13 [1] */ ++ FN_SD0_DATA1, FN_IO2_B, ++ /* IP13_12 [1] */ ++ FN_SD0_DATA0, FN_MISO_IO1_B, ++ /* IP13_11 [1] */ ++ FN_SD0_CMD, FN_MOSI_IO0_B, ++ /* IP13_10 [1] */ ++ FN_SD0_CLK, FN_SPCLK_B, ++ /* IP13_9_7 [3] */ ++ FN_STP_OPWM_0, FN_AVB_GTX_CLK, FN_PWM0_B, ++ FN_ADICHS2_B, FN_MSIOF0_TXD_C, ++ 0, 0, 0, ++ /* IP13_6_5 [2] */ ++ FN_STP_ISSYNC_0, FN_AVB_COL, FN_ADICHS1_B, FN_MSIOF0_RXD_C, ++ /* IP13_4_3 [2] */ ++ FN_STP_ISEN_0, FN_AVB_TX_CLK, FN_ADICHS0_B, FN_MSIOF0_SS2_C, ++ /* IP13_2_0 [3] */ ++ FN_STP_ISD_0, FN_AVB_TX_ER, FN_SCIFB2_SCK_C, ++ FN_ADICLK_B, FN_MSIOF0_SS1_C, ++ 0, 0, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR14", 0xE6060058, 32, ++ 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 2) { ++ /* IP14_31_29 [3] */ ++ FN_MSIOF0_SS2, FN_MMC_D7, FN_ADICHS2, FN_RX0_E, ++ FN_VI1_VSYNC_N_C, FN_SDA7_C, FN_VI1_G5_B, 0, ++ /* IP14_28_26 [3] */ ++ FN_MSIOF0_SS1, FN_MMC_D6, FN_ADICHS1, FN_TX0_E, ++ FN_VI1_HSYNC_N_C, FN_SCL7_C, FN_VI1_G4_B, 0, ++ /* IP14_25_23 [3] */ ++ FN_MSIOF0_RXD, FN_ADICHS0, 0, FN_VI1_DATA0_C, FN_VI1_G3_B, ++ 0, 0, 0, ++ /* IP14_22_20 [3] */ ++ FN_MSIOF0_TXD, FN_ADICLK, 0, FN_VI1_FIELD_C, FN_VI1_G2_B, ++ 0, 0, 0, ++ /* IP14_19_17 [3] */ ++ FN_MSIOF0_SYNC, FN_TX2_C, FN_ADICS_SAMP, 0, ++ FN_VI1_CLKENB_C, FN_VI1_G1_B, ++ 0, 0, ++ /* IP14_16_14 [3] */ ++ FN_MSIOF0_SCK, FN_RX2_C, FN_ADIDATA, 0, ++ FN_VI1_CLK_C, FN_VI1_G0_B, ++ 0, 0, ++ /* IP14_13_11 [3] */ ++ FN_SD2_WP, FN_MMC_D5, FN_SDA8_C, FN_RX5_B, FN_SCIFA5_RXD_C, ++ 0, 0, 0, ++ /* IP14_10_8 [3] */ ++ FN_SD2_CD, FN_MMC_D4, FN_SCL8_C, FN_TX5_B, FN_SCIFA5_TXD_C, ++ 0, 0, 0, ++ /* IP14_7 [1] */ ++ FN_SD2_DATA3, FN_MMC_D3, ++ /* IP14_6 [1] */ ++ FN_SD2_DATA2, FN_MMC_D2, ++ /* IP14_5 [1] */ ++ FN_SD2_DATA1, FN_MMC_D1, ++ /* IP14_4 [1] */ ++ FN_SD2_DATA0, FN_MMC_D0, ++ /* IP14_3 [1] */ ++ FN_SD2_CMD, FN_MMC_CMD, ++ /* IP14_2 [1] */ ++ FN_SD2_CLK, FN_MMC_CLK, ++ /* IP14_1_0 [2] */ ++ FN_SD1_WP, FN_PWM1_B, FN_SDA1_C, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR15", 0xE606005C, 32, ++ 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2) { ++ /* IP15_31_30 [2] */ ++ 0, 0, 0, 0, ++ /* IP15_29_27 [3] */ ++ FN_HTX0, FN_SCIFB0_TXD, 0, FN_GLO_SCLK_C, ++ FN_CAN0_TX_B, FN_VI1_DATA5_C, ++ 0, 0, ++ /* IP15_26_24 [3] */ ++ FN_HRX0, FN_SCIFB0_RXD, 0, FN_GLO_Q1_C, ++ FN_CAN0_RX_B, FN_VI1_DATA4_C, ++ 0, 0, ++ /* IP15_23_21 [3] */ ++ FN_HSCK0, FN_SCIFB0_SCK, 0, FN_GLO_Q0_C, FN_CAN_CLK, ++ FN_TCLK2, FN_VI1_DATA3_C, 0, ++ /* IP15_20_18 [3] */ ++ FN_HRTS0_N, FN_SCIFB0_RTS_N, 0, FN_GLO_I1_C, FN_VI1_DATA2_C, ++ 0, 0, 0, ++ /* IP15_17_15 [3] */ ++ FN_HCTS0_N, FN_SCIFB0_CTS_N, 0, FN_GLO_I0_C, ++ FN_TCLK1, FN_VI1_DATA1_C, ++ 0, 0, ++ /* IP15_14_12 [3] */ ++ FN_GPS_MAG, FN_RX4_C, FN_SCIFA4_RXD_C, FN_PWM6, ++ FN_VI1_G7_B, FN_SCIFA3_SCK_C, ++ 0, 0, ++ /* IP15_11_9 [3] */ ++ FN_GPS_SIGN, FN_TX4_C, FN_SCIFA4_TXD_C, FN_PWM5, ++ FN_VI1_G6_B, FN_SCIFA3_RXD_C, ++ 0, 0, ++ /* IP15_8_6 [3] */ ++ FN_GPS_CLK, FN_DU1_DOTCLKIN_C, FN_AUDIO_CLKB_B, ++ FN_PWM5_B, FN_SCIFA3_TXD_C, ++ 0, 0, 0, ++ /* IP15_5_4 [2] */ ++ FN_SIM0_D, FN_IERX, FN_CAN1_RX_D, 0, ++ /* IP15_3_2 [2] */ ++ FN_SIM0_CLK, FN_IECLK, FN_CAN_CLK_C, 0, ++ /* IP15_1_0 [2] */ ++ FN_SIM0_RST, FN_IETX, FN_CAN1_TX_D, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("IPSR16", 0xE6060160, 32, ++ 4, 4, 4, 4, 4, 2, 2, 2, 3, 3) { ++ /* IP16_31_28 [4] */ ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ /* IP16_27_24 [4] */ ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ /* IP16_23_20 [4] */ ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ /* IP16_19_16 [4] */ ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ /* IP16_15_12 [4] */ ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ 0, 0, 0, 0, 0, 0, 0, 0, ++ /* IP16_11_10 [2] */ ++ FN_HRTS1_N, FN_SCIFB1_RTS_N, FN_MLB_DAT, FN_CAN1_RX_B, ++ /* IP16_9_8 [2] */ ++ FN_HCTS1_N, FN_SCIFB1_CTS_N, FN_MLB_SIG, FN_CAN1_TX_B, ++ /* IP16_7_6 [2] */ ++ FN_HSCK1, FN_SCIFB1_SCK, FN_MLB_CK, FN_GLO_RFON_C, ++ /* IP16_5_3 [3] */ ++ FN_HTX1, FN_SCIFB1_TXD, FN_VI1_R1_B, ++ FN_GLO_SS_C, FN_VI1_DATA7_C, ++ 0, 0, 0, ++ /* IP16_2_0 [3] */ ++ FN_HRX1, FN_SCIFB1_RXD, FN_VI1_R0_B, ++ FN_GLO_SDATA_C, FN_VI1_DATA6_C, ++ 0, 0, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("MOD_SEL", 0xE6060090, 32, ++ 1, 2, 2, 2, 3, 2, 1, 1, 1, 1, ++ 3, 2, 2, 2, 1, 2, 2, 2) { ++ /* RESEVED [1] */ ++ 0, 0, ++ /* SEL_SCIF1 [2] */ ++ FN_SEL_SCIF1_0, FN_SEL_SCIF1_1, FN_SEL_SCIF1_2, FN_SEL_SCIF1_3, ++ /* SEL_SCIFB [2] */ ++ FN_SEL_SCIFB_0, FN_SEL_SCIFB_1, FN_SEL_SCIFB_2, FN_SEL_SCIFB_3, ++ /* SEL_SCIFB2 [2] */ ++ FN_SEL_SCIFB2_0, FN_SEL_SCIFB2_1, ++ FN_SEL_SCIFB2_2, FN_SEL_SCIFB2_3, ++ /* SEL_SCIFB1 [3] */ ++ FN_SEL_SCIFB1_0, FN_SEL_SCIFB1_1, ++ FN_SEL_SCIFB1_2, FN_SEL_SCIFB1_3, ++ 0, 0, 0, 0, ++ /* SEL_SCIFA1 [2] */ ++ FN_SEL_SCIFA1_0, FN_SEL_SCIFA1_1, FN_SEL_SCIFA1_2, 0, ++ /* SEL_SSI9 [1] */ ++ FN_SEL_SSI9_0, FN_SEL_SSI9_1, ++ /* SEL_SCFA [1] */ ++ FN_SEL_SCFA_0, FN_SEL_SCFA_1, ++ /* SEL_QSP [1] */ ++ FN_SEL_QSP_0, FN_SEL_QSP_1, ++ /* SEL_SSI7 [1] */ ++ FN_SEL_SSI7_0, FN_SEL_SSI7_1, ++ /* SEL_HSCIF1 [3] */ ++ FN_SEL_HSCIF1_0, FN_SEL_HSCIF1_1, FN_SEL_HSCIF1_2, ++ FN_SEL_HSCIF1_3, FN_SEL_HSCIF1_4, ++ 0, 0, 0, ++ /* RESEVED [2] */ ++ 0, 0, 0, 0, ++ /* SEL_VI1 [2] */ ++ FN_SEL_VI1_0, FN_SEL_VI1_1, FN_SEL_VI1_2, 0, ++ /* RESEVED [2] */ ++ 0, 0, 0, 0, ++ /* SEL_TMU [1] */ ++ FN_SEL_TMU1_0, FN_SEL_TMU1_1, ++ /* SEL_LBS [2] */ ++ FN_SEL_LBS_0, FN_SEL_LBS_1, FN_SEL_LBS_2, FN_SEL_LBS_3, ++ /* SEL_TSIF0 [2] */ ++ FN_SEL_TSIF0_0, FN_SEL_TSIF0_1, FN_SEL_TSIF0_2, FN_SEL_TSIF0_3, ++ /* SEL_SOF0 [2] */ ++ FN_SEL_SOF0_0, FN_SEL_SOF0_1, FN_SEL_SOF0_2, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("MOD_SEL2", 0xE6060094, 32, ++ 3, 1, 1, 3, 2, 1, 1, 2, 2, ++ 1, 3, 2, 1, 2, 2, 2, 1, 1, 1) { ++ /* SEL_SCIF0 [3] */ ++ FN_SEL_SCIF0_0, FN_SEL_SCIF0_1, FN_SEL_SCIF0_2, ++ FN_SEL_SCIF0_3, FN_SEL_SCIF0_4, ++ 0, 0, 0, ++ /* RESEVED [1] */ ++ 0, 0, ++ /* SEL_SCIF [1] */ ++ FN_SEL_SCIF_0, FN_SEL_SCIF_1, ++ /* SEL_CAN0 [3] */ ++ FN_SEL_CAN0_0, FN_SEL_CAN0_1, FN_SEL_CAN0_2, FN_SEL_CAN0_3, ++ FN_SEL_CAN0_4, FN_SEL_CAN0_5, ++ 0, 0, ++ /* SEL_CAN1 [2] */ ++ FN_SEL_CAN1_0, FN_SEL_CAN1_1, FN_SEL_CAN1_2, FN_SEL_CAN1_3, ++ /* RESEVED [1] */ ++ 0, 0, ++ /* SEL_SCIFA2 [1] */ ++ FN_SEL_SCIFA2_0, FN_SEL_SCIFA2_1, ++ /* SEL_SCIF4 [2] */ ++ FN_SEL_SCIF4_0, FN_SEL_SCIF4_1, FN_SEL_SCIF4_2, 0, ++ /* RESEVED [2] */ ++ 0, 0, 0, 0, ++ /* SEL_ADG [1] */ ++ FN_SEL_ADG_0, FN_SEL_ADG_1, ++ /* SEL_FM [3] */ ++ FN_SEL_FM_0, FN_SEL_FM_1, FN_SEL_FM_2, ++ FN_SEL_FM_3, FN_SEL_FM_4, ++ 0, 0, 0, ++ /* SEL_SCIFA5 [2] */ ++ FN_SEL_SCIFA5_0, FN_SEL_SCIFA5_1, FN_SEL_SCIFA5_2, 0, ++ /* RESEVED [1] */ ++ 0, 0, ++ /* SEL_GPS [2] */ ++ FN_SEL_GPS_0, FN_SEL_GPS_1, FN_SEL_GPS_2, FN_SEL_GPS_3, ++ /* SEL_SCIFA4 [2] */ ++ FN_SEL_SCIFA4_0, FN_SEL_SCIFA4_1, FN_SEL_SCIFA4_2, 0, ++ /* SEL_SCIFA3 [2] */ ++ FN_SEL_SCIFA3_0, FN_SEL_SCIFA3_1, FN_SEL_SCIFA3_2, 0, ++ /* SEL_SIM [1] */ ++ FN_SEL_SIM_0, FN_SEL_SIM_1, ++ /* RESEVED [1] */ ++ 0, 0, ++ /* SEL_SSI8 [1] */ ++ FN_SEL_SSI8_0, FN_SEL_SSI8_1, } ++ }, ++ { PINMUX_CFG_REG_VAR("MOD_SEL3", 0xE6060098, 32, ++ 2, 2, 2, 2, 2, 2, 2, 2, ++ 1, 1, 2, 2, 3, 2, 2, 2, 1) { ++ /* SEL_HSCIF2 [2] */ ++ FN_SEL_HSCIF2_0, FN_SEL_HSCIF2_1, ++ FN_SEL_HSCIF2_2, FN_SEL_HSCIF2_3, ++ /* SEL_CANCLK [2] */ ++ FN_SEL_CANCLK_0, FN_SEL_CANCLK_1, ++ FN_SEL_CANCLK_2, FN_SEL_CANCLK_3, ++ /* SEL_IIC8 [2] */ ++ FN_SEL_IIC8_0, FN_SEL_IIC8_1, FN_SEL_IIC8_2, 0, ++ /* SEL_IIC7 [2] */ ++ FN_SEL_IIC7_0, FN_SEL_IIC7_1, FN_SEL_IIC7_2, 0, ++ /* SEL_IIC4 [2] */ ++ FN_SEL_IIC4_0, FN_SEL_IIC4_1, FN_SEL_IIC4_2, 0, ++ /* SEL_IIC3 [2] */ ++ FN_SEL_IIC3_0, FN_SEL_IIC3_1, FN_SEL_IIC3_2, FN_SEL_IIC3_3, ++ /* SEL_SCIF3 [2] */ ++ FN_SEL_SCIF3_0, FN_SEL_SCIF3_1, FN_SEL_SCIF3_2, FN_SEL_SCIF3_3, ++ /* SEL_IEB [2] */ ++ FN_SEL_IEB_0, FN_SEL_IEB_1, FN_SEL_IEB_2, ++ /* SEL_MMC [1] */ ++ FN_SEL_MMC_0, FN_SEL_MMC_1, ++ /* SEL_SCIF5 [1] */ ++ FN_SEL_SCIF5_0, FN_SEL_SCIF5_1, ++ /* RESEVED [2] */ ++ 0, 0, 0, 0, ++ /* SEL_IIC2 [2] */ ++ FN_SEL_IIC2_0, FN_SEL_IIC2_1, FN_SEL_IIC2_2, FN_SEL_IIC2_3, ++ /* SEL_IIC1 [3] */ ++ FN_SEL_IIC1_0, FN_SEL_IIC1_1, FN_SEL_IIC1_2, FN_SEL_IIC1_3, ++ FN_SEL_IIC1_4, ++ 0, 0, 0, ++ /* SEL_IIC0 [2] */ ++ FN_SEL_IIC0_0, FN_SEL_IIC0_1, FN_SEL_IIC0_2, 0, ++ /* RESEVED [2] */ ++ 0, 0, 0, 0, ++ /* RESEVED [2] */ ++ 0, 0, 0, 0, ++ /* RESEVED [1] */ ++ 0, 0, } ++ }, ++ { PINMUX_CFG_REG_VAR("MOD_SEL4", 0xE606009C, 32, ++ 3, 2, 2, 1, 1, 1, 1, 3, 2, ++ 2, 3, 1, 1, 1, 2, 2, 2, 2) { ++ /* SEL_SOF1 [3] */ ++ FN_SEL_SOF1_0, FN_SEL_SOF1_1, FN_SEL_SOF1_2, FN_SEL_SOF1_3, ++ FN_SEL_SOF1_4, ++ 0, 0, 0, ++ /* SEL_HSCIF0 [2] */ ++ FN_SEL_HSCIF0_0, FN_SEL_HSCIF0_1, FN_SEL_HSCIF0_2, 0, ++ /* SEL_DIS [2] */ ++ FN_SEL_DIS_0, FN_SEL_DIS_1, FN_SEL_DIS_2, 0, ++ /* RESEVED [1] */ ++ 0, 0, ++ /* SEL_RAD [1] */ ++ FN_SEL_RAD_0, FN_SEL_RAD_1, ++ /* SEL_RCN [1] */ ++ FN_SEL_RCN_0, FN_SEL_RCN_1, ++ /* SEL_RSP [1] */ ++ FN_SEL_RSP_0, FN_SEL_RSP_1, ++ /* SEL_SCIF2 [3] */ ++ FN_SEL_SCIF2_0, FN_SEL_SCIF2_1, FN_SEL_SCIF2_2, ++ FN_SEL_SCIF2_3, FN_SEL_SCIF2_4, ++ 0, 0, 0, ++ /* RESEVED [2] */ ++ 0, 0, 0, 0, ++ /* RESEVED [2] */ ++ 0, 0, 0, 0, ++ /* SEL_SOF2 [3] */ ++ FN_SEL_SOF2_0, FN_SEL_SOF2_1, FN_SEL_SOF2_2, ++ FN_SEL_SOF2_3, FN_SEL_SOF2_4, ++ 0, 0, 0, ++ /* RESEVED [1] */ ++ 0, 0, ++ /* SEL_SSI1 [1] */ ++ FN_SEL_SSI1_0, FN_SEL_SSI1_1, ++ /* SEL_SSI0 [1] */ ++ FN_SEL_SSI0_0, FN_SEL_SSI0_1, ++ /* SEL_SSP [2] */ ++ FN_SEL_SSP_0, FN_SEL_SSP_1, FN_SEL_SSP_2, 0, ++ /* RESEVED [2] */ ++ 0, 0, 0, 0, ++ /* RESEVED [2] */ ++ 0, 0, 0, 0, ++ /* RESEVED [2] */ ++ 0, 0, 0, 0, } ++ }, ++ { }, ++}; ++ ++const struct sh_pfc_soc_info r8a7791_pinmux_info = { ++ .name = "r8a77910_pfc", ++ .unlock_reg = 0xe6060000, /* PMMR */ ++ ++ .function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END }, ++ ++ .pins = pinmux_pins, ++ .nr_pins = ARRAY_SIZE(pinmux_pins), ++ .groups = pinmux_groups, ++ .nr_groups = ARRAY_SIZE(pinmux_groups), ++ .functions = pinmux_functions, ++ .nr_functions = ARRAY_SIZE(pinmux_functions), ++ ++ .cfg_regs = pinmux_config_regs, ++ ++ .gpio_data = pinmux_data, ++ .gpio_data_size = ARRAY_SIZE(pinmux_data), ++}; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0084-sata_rcar-Convert-to-clk_prepare-unprepare.patch b/patches.renesas/0084-sata_rcar-Convert-to-clk_prepare-unprepare.patch new file mode 100644 index 00000000000000..e4e973dba125b5 --- /dev/null +++ b/patches.renesas/0084-sata_rcar-Convert-to-clk_prepare-unprepare.patch @@ -0,0 +1,70 @@ +From 160526768d55fca2b58f8852e7ad6e8a547f83ca Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Mon, 28 Oct 2013 23:49:21 +0100 +Subject: sata_rcar: Convert to clk_prepare/unprepare + +Turn clk_enable() and clk_disable() calls into clk_prepare_enable() and +clk_disable_unprepare() to get ready for the migration to the common +clock framework. + +Cc: linux-ide@vger.kernel.org +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Tejun Heo <tj@kernel.org> +(cherry picked from commit 329b4287a4fc1d5d98a9f74b6f4f5d986a6c61f4) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/ata/sata_rcar.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/drivers/ata/sata_rcar.c b/drivers/ata/sata_rcar.c +index c2d95e9fb971..1dae9a9009f7 100644 +--- a/drivers/ata/sata_rcar.c ++++ b/drivers/ata/sata_rcar.c +@@ -792,7 +792,7 @@ static int sata_rcar_probe(struct platform_device *pdev) + dev_err(&pdev->dev, "failed to get access to sata clock\n"); + return PTR_ERR(priv->clk); + } +- clk_enable(priv->clk); ++ clk_prepare_enable(priv->clk); + + host = ata_host_alloc(&pdev->dev, 1); + if (!host) { +@@ -822,7 +822,7 @@ static int sata_rcar_probe(struct platform_device *pdev) + return 0; + + cleanup: +- clk_disable(priv->clk); ++ clk_disable_unprepare(priv->clk); + + return ret; + } +@@ -841,7 +841,7 @@ static int sata_rcar_remove(struct platform_device *pdev) + iowrite32(0, base + SATAINTSTAT_REG); + iowrite32(0x7ff, base + SATAINTMASK_REG); + +- clk_disable(priv->clk); ++ clk_disable_unprepare(priv->clk); + + return 0; + } +@@ -861,7 +861,7 @@ static int sata_rcar_suspend(struct device *dev) + /* mask */ + iowrite32(0x7ff, base + SATAINTMASK_REG); + +- clk_disable(priv->clk); ++ clk_disable_unprepare(priv->clk); + } + + return ret; +@@ -873,7 +873,7 @@ static int sata_rcar_resume(struct device *dev) + struct sata_rcar_priv *priv = host->private_data; + void __iomem *base = priv->base; + +- clk_enable(priv->clk); ++ clk_prepare_enable(priv->clk); + + /* ack and mask */ + iowrite32(0, base + SATAINTSTAT_REG); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0085-ARM-gic-add-CPU-migration-support.patch b/patches.renesas/0085-ARM-gic-add-CPU-migration-support.patch new file mode 100644 index 00000000000000..8678bf8f4f099f --- /dev/null +++ b/patches.renesas/0085-ARM-gic-add-CPU-migration-support.patch @@ -0,0 +1,166 @@ +From 714cd44380c8ac53b807bbf4e8fd5ac53b0fdb6f Mon Sep 17 00:00:00 2001 +From: Nicolas Pitre <nicolas.pitre@linaro.org> +Date: Thu, 12 Apr 2012 01:40:31 -0400 +Subject: ARM: gic: add CPU migration support + +This is required by the big.LITTLE switcher code. + +The gic_migrate_target() changes the CPU interface mapping for the +current CPU to redirect SGIs to the specified interface, and it also +updates the target CPU for each interrupts to that CPU interface +if they were targeting the current interface. Finally, pending +SGIs for the current CPU are forwarded to the new interface. + +Because Linux does not use it, the SGI source information for the +forwarded SGIs is not preserved. Neither is the source information +for the SGIs sent by the current CPU to other CPUs adjusted to match +the new CPU interface mapping. The required registers are banked so +only the target CPU could do it. + +Signed-off-by: Nicolas Pitre <nico@linaro.org> +(cherry picked from commit 1a6b69b6548cd0dd82549393f30dd982ceeb79d2) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/irqchip/irq-gic.c | 87 +++++++++++++++++++++++++++++++++++++++-- + include/linux/irqchip/arm-gic.h | 4 ++ + 2 files changed, 88 insertions(+), 3 deletions(-) + +diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c +index fe44d3e2c702..d37e47dec547 100644 +--- a/drivers/irqchip/irq-gic.c ++++ b/drivers/irqchip/irq-gic.c +@@ -253,10 +253,9 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, + if (cpu >= NR_GIC_CPU_IF || cpu >= nr_cpu_ids) + return -EINVAL; + ++ raw_spin_lock(&irq_controller_lock); + mask = 0xff << shift; + bit = gic_cpu_map[cpu] << shift; +- +- raw_spin_lock(&irq_controller_lock); + val = readl_relaxed(reg) & ~mask; + writel_relaxed(val | bit, reg); + raw_spin_unlock(&irq_controller_lock); +@@ -652,7 +651,9 @@ static void __init gic_pm_init(struct gic_chip_data *gic) + void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) + { + int cpu; +- unsigned long map = 0; ++ unsigned long flags, map = 0; ++ ++ raw_spin_lock_irqsave(&irq_controller_lock, flags); + + /* Convert our logical CPU mask into a physical one. */ + for_each_cpu(cpu, mask) +@@ -666,6 +667,86 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) + + /* this always happens on GIC0 */ + writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); ++ ++ raw_spin_unlock_irqrestore(&irq_controller_lock, flags); ++} ++#endif ++ ++#ifdef CONFIG_BL_SWITCHER ++/* ++ * gic_migrate_target - migrate IRQs to another CPU interface ++ * ++ * @new_cpu_id: the CPU target ID to migrate IRQs to ++ * ++ * Migrate all peripheral interrupts with a target matching the current CPU ++ * to the interface corresponding to @new_cpu_id. The CPU interface mapping ++ * is also updated. Targets to other CPU interfaces are unchanged. ++ * This must be called with IRQs locally disabled. ++ */ ++void gic_migrate_target(unsigned int new_cpu_id) ++{ ++ unsigned int cur_cpu_id, gic_irqs, gic_nr = 0; ++ void __iomem *dist_base; ++ int i, ror_val, cpu = smp_processor_id(); ++ u32 val, cur_target_mask, active_mask; ++ ++ if (gic_nr >= MAX_GIC_NR) ++ BUG(); ++ ++ dist_base = gic_data_dist_base(&gic_data[gic_nr]); ++ if (!dist_base) ++ return; ++ gic_irqs = gic_data[gic_nr].gic_irqs; ++ ++ cur_cpu_id = __ffs(gic_cpu_map[cpu]); ++ cur_target_mask = 0x01010101 << cur_cpu_id; ++ ror_val = (cur_cpu_id - new_cpu_id) & 31; ++ ++ raw_spin_lock(&irq_controller_lock); ++ ++ /* Update the target interface for this logical CPU */ ++ gic_cpu_map[cpu] = 1 << new_cpu_id; ++ ++ /* ++ * Find all the peripheral interrupts targetting the current ++ * CPU interface and migrate them to the new CPU interface. ++ * We skip DIST_TARGET 0 to 7 as they are read-only. ++ */ ++ for (i = 8; i < DIV_ROUND_UP(gic_irqs, 4); i++) { ++ val = readl_relaxed(dist_base + GIC_DIST_TARGET + i * 4); ++ active_mask = val & cur_target_mask; ++ if (active_mask) { ++ val &= ~active_mask; ++ val |= ror32(active_mask, ror_val); ++ writel_relaxed(val, dist_base + GIC_DIST_TARGET + i*4); ++ } ++ } ++ ++ raw_spin_unlock(&irq_controller_lock); ++ ++ /* ++ * Now let's migrate and clear any potential SGIs that might be ++ * pending for us (cur_cpu_id). Since GIC_DIST_SGI_PENDING_SET ++ * is a banked register, we can only forward the SGI using ++ * GIC_DIST_SOFTINT. The original SGI source is lost but Linux ++ * doesn't use that information anyway. ++ * ++ * For the same reason we do not adjust SGI source information ++ * for previously sent SGIs by us to other CPUs either. ++ */ ++ for (i = 0; i < 16; i += 4) { ++ int j; ++ val = readl_relaxed(dist_base + GIC_DIST_SGI_PENDING_SET + i); ++ if (!val) ++ continue; ++ writel_relaxed(val, dist_base + GIC_DIST_SGI_PENDING_CLEAR + i); ++ for (j = i; j < i + 4; j++) { ++ if (val & 0xff) ++ writel_relaxed((1 << (new_cpu_id + 16)) | j, ++ dist_base + GIC_DIST_SOFTINT); ++ val >>= 8; ++ } ++ } + } + #endif + +diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h +index 0e5d9ecdb2b6..6fa426856c86 100644 +--- a/include/linux/irqchip/arm-gic.h ++++ b/include/linux/irqchip/arm-gic.h +@@ -31,6 +31,8 @@ + #define GIC_DIST_TARGET 0x800 + #define GIC_DIST_CONFIG 0xc00 + #define GIC_DIST_SOFTINT 0xf00 ++#define GIC_DIST_SGI_PENDING_CLEAR 0xf10 ++#define GIC_DIST_SGI_PENDING_SET 0xf20 + + #define GICH_HCR 0x0 + #define GICH_VTR 0x4 +@@ -74,6 +76,8 @@ static inline void gic_init(unsigned int nr, int start, + gic_init_bases(nr, start, dist, cpu, 0, NULL); + } + ++void gic_migrate_target(unsigned int new_cpu_id); ++ + #endif /* __ASSEMBLY */ + + #endif +-- +1.8.5.rc3 + diff --git a/patches.renesas/0086-ARM-GIC-function-to-retrieve-the-physical-address-of.patch b/patches.renesas/0086-ARM-GIC-function-to-retrieve-the-physical-address-of.patch new file mode 100644 index 00000000000000..5b9f0c49205e6e --- /dev/null +++ b/patches.renesas/0086-ARM-GIC-function-to-retrieve-the-physical-address-of.patch @@ -0,0 +1,81 @@ +From 1b0962cc4f2ed7d431f228afd9d015b0d82e1ece Mon Sep 17 00:00:00 2001 +From: Nicolas Pitre <nicolas.pitre@linaro.org> +Date: Wed, 28 Nov 2012 18:17:25 -0500 +Subject: ARM: GIC: function to retrieve the physical address of the SGIR + +In order to have early assembly code signal other CPUs in the system, +we need to get the physical address for the SGIR register used to +send IPIs. Because the register will be used with a precomputed CPU +interface ID number, there is no need for any locking in the assembly +code where this register is written to. + +Signed-off-by: Nicolas Pitre <nico@linaro.org> +(cherry picked from commit eeb446581ba23a5a36b4f5c7bfa2b1f8f7c9fb66) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/irqchip/irq-gic.c | 29 +++++++++++++++++++++++++++++ + include/linux/irqchip/arm-gic.h | 1 + + 2 files changed, 30 insertions(+) + +diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c +index d37e47dec547..d87bbc03263a 100644 +--- a/drivers/irqchip/irq-gic.c ++++ b/drivers/irqchip/irq-gic.c +@@ -748,6 +748,33 @@ void gic_migrate_target(unsigned int new_cpu_id) + } + } + } ++ ++/* ++ * gic_get_sgir_physaddr - get the physical address for the SGI register ++ * ++ * REturn the physical address of the SGI register to be used ++ * by some early assembly code when the kernel is not yet available. ++ */ ++static unsigned long gic_dist_physaddr; ++ ++unsigned long gic_get_sgir_physaddr(void) ++{ ++ if (!gic_dist_physaddr) ++ return 0; ++ return gic_dist_physaddr + GIC_DIST_SOFTINT; ++} ++ ++void __init gic_init_physaddr(struct device_node *node) ++{ ++ struct resource res; ++ if (of_address_to_resource(node, 0, &res) == 0) { ++ gic_dist_physaddr = res.start; ++ pr_info("GIC physical location is %#lx\n", gic_dist_physaddr); ++ } ++} ++ ++#else ++#define gic_init_physaddr(node) do { } while (0) + #endif + + static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, +@@ -931,6 +958,8 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent) + percpu_offset = 0; + + gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node); ++ if (!gic_cnt) ++ gic_init_physaddr(node); + + if (parent) { + irq = irq_of_parse_and_map(node, 0); +diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h +index 6fa426856c86..f829e00795b3 100644 +--- a/include/linux/irqchip/arm-gic.h ++++ b/include/linux/irqchip/arm-gic.h +@@ -77,6 +77,7 @@ static inline void gic_init(unsigned int nr, int start, + } + + void gic_migrate_target(unsigned int new_cpu_id); ++unsigned long gic_get_sgir_physaddr(void); + + #endif /* __ASSEMBLY */ + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0087-ARM-GIC-interface-to-send-a-SGI-directly.patch b/patches.renesas/0087-ARM-GIC-interface-to-send-a-SGI-directly.patch new file mode 100644 index 00000000000000..ef363d87c42e8c --- /dev/null +++ b/patches.renesas/0087-ARM-GIC-interface-to-send-a-SGI-directly.patch @@ -0,0 +1,62 @@ +From 60c59196f7164af18826c4e78be3c6f3b41ae963 Mon Sep 17 00:00:00 2001 +From: Nicolas Pitre <nicolas.pitre@linaro.org> +Date: Wed, 28 Nov 2012 18:48:19 -0500 +Subject: ARM: GIC: interface to send a SGI directly + +The regular gic_raise_softirq() takes as input a CPU mask which is not +adequate when we need to send an IPI to a CPU which is not represented +in the kernel to GIC mapping. That is the case with the b.L switcher +when GIC migration to the inbound CPU has not yet occurred. + +Signed-off-by: Nicolas Pitre <nico@linaro.org> +(cherry picked from commit 14d2ca615a85e2dbc744c12c296affd35f119fa7) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + drivers/irqchip/irq-gic.c + include/linux/irqchip/arm-gic.h +--- + drivers/irqchip/irq-gic.c | 14 ++++++++++++++ + include/linux/irqchip/arm-gic.h | 1 + + 2 files changed, 15 insertions(+) + +diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c +index d87bbc03263a..70e4a3080029 100644 +--- a/drivers/irqchip/irq-gic.c ++++ b/drivers/irqchip/irq-gic.c +@@ -674,6 +674,20 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) + + #ifdef CONFIG_BL_SWITCHER + /* ++ * gic_send_sgi - send a SGI directly to given CPU interface number ++ * ++ * cpu_id: the ID for the destination CPU interface ++ * irq: the IPI number to send a SGI for ++ */ ++void gic_send_sgi(unsigned int cpu_id, unsigned int irq) ++{ ++ BUG_ON(cpu_id >= NR_GIC_CPU_IF); ++ cpu_id = 1 << cpu_id; ++ /* this always happens on GIC0 */ ++ writel_relaxed((cpu_id << 16) | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT); ++} ++ ++/* + * gic_migrate_target - migrate IRQs to another CPU interface + * + * @new_cpu_id: the CPU target ID to migrate IRQs to +diff --git a/include/linux/irqchip/arm-gic.h b/include/linux/irqchip/arm-gic.h +index f829e00795b3..442f016df62c 100644 +--- a/include/linux/irqchip/arm-gic.h ++++ b/include/linux/irqchip/arm-gic.h +@@ -76,6 +76,7 @@ static inline void gic_init(unsigned int nr, int start, + gic_init_bases(nr, start, dist, cpu, 0, NULL); + } + ++void gic_send_sgi(unsigned int cpu_id, unsigned int irq); + void gic_migrate_target(unsigned int new_cpu_id); + unsigned long gic_get_sgir_physaddr(void); + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0088-ARM-arch_timer-add-support-to-configure-and-enable-e.patch b/patches.renesas/0088-ARM-arch_timer-add-support-to-configure-and-enable-e.patch new file mode 100644 index 00000000000000..6457aa9b028cb2 --- /dev/null +++ b/patches.renesas/0088-ARM-arch_timer-add-support-to-configure-and-enable-e.patch @@ -0,0 +1,104 @@ +From f2cdb0ee7821bd104da55490b74da715ad1a3e9f Mon Sep 17 00:00:00 2001 +From: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com> +Date: Tue, 13 Aug 2013 14:30:32 +0100 +Subject: ARM: arch_timer: add support to configure and enable event stream + +This patch adds support for configuring the event stream frequency +and enabling it. + +It also adds the hwcaps definitions to the user to detect this event +stream feature. + +Cc: Russell King <linux@arm.linux.org.uk> +Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> +Acked-by: Catalin Marinas <catalin.marinas@arm.com> +Acked-by: Will Deacon <will.deacon@arm.com> +Acked-by: Olof Johansson <olof@lixom.net> +Signed-off-by: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com> +(cherry picked from commit e9faebc66ec74f1ab7f267d683b45e80faa69763) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + arch/arm/include/asm/arch_timer.h +--- + arch/arm/include/asm/arch_timer.h | 27 ++++++++++++++++++++++++--- + arch/arm/include/uapi/asm/hwcap.h | 1 + + arch/arm/kernel/setup.c | 1 + + 3 files changed, 26 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/include/asm/arch_timer.h b/arch/arm/include/asm/arch_timer.h +index c78c4cbd329e..0704e0cf5571 100644 +--- a/arch/arm/include/asm/arch_timer.h ++++ b/arch/arm/include/asm/arch_timer.h +@@ -87,11 +87,21 @@ static inline u64 arch_counter_get_cntvct(void) + return cval; + } + +-static inline void __cpuinit arch_counter_set_user_access(void) ++static inline u32 arch_timer_get_cntkctl(void) + { + u32 cntkctl; +- + asm volatile("mrc p15, 0, %0, c14, c1, 0" : "=r" (cntkctl)); ++ return cntkctl; ++} ++ ++static inline void arch_timer_set_cntkctl(u32 cntkctl) ++{ ++ asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl)); ++} ++ ++static inline void arch_counter_set_user_access(void) ++{ ++ u32 cntkctl = arch_timer_get_cntkctl(); + + /* Disable user access to both physical/virtual counters/timers */ + /* Also disable virtual event stream */ +@@ -100,9 +110,20 @@ static inline void __cpuinit arch_counter_set_user_access(void) + | ARCH_TIMER_VIRT_EVT_EN + | ARCH_TIMER_USR_VCT_ACCESS_EN + | ARCH_TIMER_USR_PCT_ACCESS_EN); ++ arch_timer_set_cntkctl(cntkctl); ++} + +- asm volatile("mcr p15, 0, %0, c14, c1, 0" : : "r" (cntkctl)); ++static inline void arch_timer_evtstrm_enable(int divider) ++{ ++ u32 cntkctl = arch_timer_get_cntkctl(); ++ cntkctl &= ~ARCH_TIMER_EVT_TRIGGER_MASK; ++ /* Set the divider and enable virtual event stream */ ++ cntkctl |= (divider << ARCH_TIMER_EVT_TRIGGER_SHIFT) ++ | ARCH_TIMER_VIRT_EVT_EN; ++ arch_timer_set_cntkctl(cntkctl); ++ elf_hwcap |= HWCAP_EVTSTRM; + } ++ + #endif + + #endif +diff --git a/arch/arm/include/uapi/asm/hwcap.h b/arch/arm/include/uapi/asm/hwcap.h +index 6d34d080372a..7dcc10d67253 100644 +--- a/arch/arm/include/uapi/asm/hwcap.h ++++ b/arch/arm/include/uapi/asm/hwcap.h +@@ -26,5 +26,6 @@ + #define HWCAP_VFPD32 (1 << 19) /* set if VFP has 32 regs (not 16) */ + #define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT) + #define HWCAP_LPAE (1 << 20) ++#define HWCAP_EVTSTRM (1 << 21) + + #endif /* _UAPI__ASMARM_HWCAP_H */ +diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c +index 6cc3db43e897..d62772f49907 100644 +--- a/arch/arm/kernel/setup.c ++++ b/arch/arm/kernel/setup.c +@@ -878,6 +878,7 @@ static const char *hwcap_str[] = { + "idiva", + "idivt", + "lpae", ++ "evtstrm", + NULL + }; + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0089-ASoC-add-Renesas-R-Car-module-feature.patch b/patches.renesas/0089-ASoC-add-Renesas-R-Car-module-feature.patch new file mode 100644 index 00000000000000..7413dfb70cdaa5 --- /dev/null +++ b/patches.renesas/0089-ASoC-add-Renesas-R-Car-module-feature.patch @@ -0,0 +1,198 @@ +From 3ce69392154484a529d9951b13e3542ea7ac0ace Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 21 Jul 2013 21:36:03 -0700 +Subject: ASoC: add Renesas R-Car module feature + +Renesas R-Car series sound circuit consists of SSI and its peripheral. +But this peripheral circuit is different between +R-Car Generation1 (E1/M1/H1) and Generation2 (E2/M2/H2) +(Actually, there are many difference in Generation1 chips) + +Gen1 series consists of SRU/SSI/ADG, and +Gen2 series consists of SCU/SSIU/SSI/ADG. + +In order to control these by same method, +these are treated as "mod" on this driver. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit cdaa3cdfb4a710545a53740b1780a683b043618a) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/core.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ + sound/soc/sh/rcar/rsnd.h | 46 ++++++++++++++++++++++++++++ + 2 files changed, 126 insertions(+) + +diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c +index 13b5d50efd06..a47fda2aa600 100644 +--- a/sound/soc/sh/rcar/core.c ++++ b/sound/soc/sh/rcar/core.c +@@ -108,8 +108,73 @@ + + + /* ++ * rsnd_mod functions ++ */ ++char *rsnd_mod_name(struct rsnd_mod *mod) ++{ ++ if (!mod || !mod->ops) ++ return "unknown"; ++ ++ return mod->ops->name; ++} ++ ++void rsnd_mod_init(struct rsnd_priv *priv, ++ struct rsnd_mod *mod, ++ struct rsnd_mod_ops *ops, ++ int id) ++{ ++ mod->priv = priv; ++ mod->id = id; ++ mod->ops = ops; ++ INIT_LIST_HEAD(&mod->list); ++} ++ ++/* + * rsnd_dai functions + */ ++#define rsnd_dai_call(rdai, io, fn) \ ++({ \ ++ struct rsnd_mod *mod, *n; \ ++ int ret = 0; \ ++ for_each_rsnd_mod(mod, n, io) { \ ++ ret = rsnd_mod_call(mod, fn, rdai, io); \ ++ if (ret < 0) \ ++ break; \ ++ } \ ++ ret; \ ++}) ++ ++int rsnd_dai_connect(struct rsnd_dai *rdai, ++ struct rsnd_mod *mod, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ ++ if (!mod) { ++ dev_err(dev, "NULL mod\n"); ++ return -EIO; ++ } ++ ++ if (!list_empty(&mod->list)) { ++ dev_err(dev, "%s%d is not empty\n", ++ rsnd_mod_name(mod), ++ rsnd_mod_id(mod)); ++ return -EIO; ++ } ++ ++ list_add_tail(&mod->list, &io->head); ++ ++ return 0; ++} ++ ++int rsnd_dai_disconnect(struct rsnd_mod *mod) ++{ ++ list_del_init(&mod->list); ++ ++ return 0; ++} ++ + struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id) + { + return priv->rdai + id; +@@ -224,8 +289,23 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, + if (ret < 0) + goto dai_trigger_end; + ++ ret = rsnd_dai_call(rdai, io, init); ++ if (ret < 0) ++ goto dai_trigger_end; ++ ++ ret = rsnd_dai_call(rdai, io, start); ++ if (ret < 0) ++ goto dai_trigger_end; + break; + case SNDRV_PCM_TRIGGER_STOP: ++ ret = rsnd_dai_call(rdai, io, stop); ++ if (ret < 0) ++ goto dai_trigger_end; ++ ++ ret = rsnd_dai_call(rdai, io, quit); ++ if (ret < 0) ++ goto dai_trigger_end; ++ + ret = rsnd_platform_call(priv, dai, stop, ssi_id); + if (ret < 0) + goto dai_trigger_end; +diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h +index 8d04fd0352bd..65d3835cffbc 100644 +--- a/sound/soc/sh/rcar/rsnd.h ++++ b/sound/soc/sh/rcar/rsnd.h +@@ -28,10 +28,53 @@ + * see gen1/gen2 for detail + */ + struct rsnd_priv; ++struct rsnd_mod; + struct rsnd_dai; + struct rsnd_dai_stream; + + /* ++ * R-Car sound mod ++ */ ++ ++struct rsnd_mod_ops { ++ char *name; ++ int (*init)(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io); ++ int (*quit)(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io); ++ int (*start)(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io); ++ int (*stop)(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io); ++}; ++ ++struct rsnd_mod { ++ int id; ++ struct rsnd_priv *priv; ++ struct rsnd_mod_ops *ops; ++ struct list_head list; /* connect to rsnd_dai playback/capture */ ++}; ++ ++#define rsnd_mod_to_priv(mod) ((mod)->priv) ++#define rsnd_mod_id(mod) ((mod)->id) ++#define for_each_rsnd_mod(pos, n, io) \ ++ list_for_each_entry_safe(pos, n, &(io)->head, list) ++#define rsnd_mod_call(mod, func, rdai, io) \ ++ (!(mod) ? -ENODEV : \ ++ !((mod)->ops->func) ? 0 : \ ++ (mod)->ops->func(mod, rdai, io)) ++ ++void rsnd_mod_init(struct rsnd_priv *priv, ++ struct rsnd_mod *mod, ++ struct rsnd_mod_ops *ops, ++ int id); ++char *rsnd_mod_name(struct rsnd_mod *mod); ++ ++/* + * R-Car sound DAI + */ + #define RSND_DAI_NAME_SIZE 16 +@@ -64,6 +107,9 @@ struct rsnd_dai { + i++, (rdai) = rsnd_dai_get(priv, i)) + + struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id); ++int rsnd_dai_disconnect(struct rsnd_mod *mod); ++int rsnd_dai_connect(struct rsnd_dai *rdai, struct rsnd_mod *mod, ++ struct rsnd_dai_stream *io); + int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io); + #define rsnd_dai_get_platform_info(rdai) ((rdai)->info) + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0090-ASoC-add-Renesas-R-Car-Generation-feature.patch b/patches.renesas/0090-ASoC-add-Renesas-R-Car-Generation-feature.patch new file mode 100644 index 00000000000000..a75be9bcfa8272 --- /dev/null +++ b/patches.renesas/0090-ASoC-add-Renesas-R-Car-Generation-feature.patch @@ -0,0 +1,399 @@ +From 6af0566e6b321dbf32134a6b8663ba571db6b9eb Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 21 Jul 2013 21:36:21 -0700 +Subject: ASoC: add Renesas R-Car Generation feature + +Renesas R-Car series sound circuit consists of SSI and its peripheral. +But this peripheral circuit is different between +R-Car Generation1 (E1/M1/H1) and Generation2 (E2/M2/H2) +(Actually, there are many difference in Generation1 chips) + +The main difference between Gen1 and Gen2 are +1) register offset, 2) data path + +In order to control Gen1/Gen2 by same method, +this patch adds gen.c. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 3337744ac41bee00b0068ad5f926dd9c27540809) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + include/sound/rcar_snd.h | 10 +++ + sound/soc/sh/rcar/Makefile | 2 +- + sound/soc/sh/rcar/core.c | 58 ++++++++++++++++- + sound/soc/sh/rcar/gen.c | 154 +++++++++++++++++++++++++++++++++++++++++++++ + sound/soc/sh/rcar/rsnd.h | 47 ++++++++++++++ + 5 files changed, 269 insertions(+), 2 deletions(-) + create mode 100644 sound/soc/sh/rcar/gen.c + +diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h +index 7272b2ea7108..14942a827fe5 100644 +--- a/include/sound/rcar_snd.h ++++ b/include/sound/rcar_snd.h +@@ -22,6 +22,16 @@ struct rsnd_dai_platform_info { + int ssi_id_capture; + }; + ++/* ++ * flags ++ * ++ * 0x0000000A ++ * ++ * A : generation ++ */ ++#define RSND_GEN1 (1 << 0) /* fixme */ ++#define RSND_GEN2 (2 << 0) /* fixme */ ++ + struct rcar_snd_info { + u32 flags; + struct rsnd_dai_platform_info *dai_info; +diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile +index cd8089f20c94..b2d313b1eb94 100644 +--- a/sound/soc/sh/rcar/Makefile ++++ b/sound/soc/sh/rcar/Makefile +@@ -1,2 +1,2 @@ +-snd-soc-rcar-objs := core.o ++snd-soc-rcar-objs := core.o gen.o + obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o +diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c +index a47fda2aa600..bb8959f93a7d 100644 +--- a/sound/soc/sh/rcar/core.c ++++ b/sound/soc/sh/rcar/core.c +@@ -108,6 +108,50 @@ + + + /* ++ * basic function ++ */ ++u32 rsnd_read(struct rsnd_priv *priv, ++ struct rsnd_mod *mod, enum rsnd_reg reg) ++{ ++ void __iomem *base = rsnd_gen_reg_get(priv, mod, reg); ++ ++ BUG_ON(!base); ++ ++ return ioread32(base); ++} ++ ++void rsnd_write(struct rsnd_priv *priv, ++ struct rsnd_mod *mod, ++ enum rsnd_reg reg, u32 data) ++{ ++ void __iomem *base = rsnd_gen_reg_get(priv, mod, reg); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ ++ BUG_ON(!base); ++ ++ dev_dbg(dev, "w %p : %08x\n", base, data); ++ ++ iowrite32(data, base); ++} ++ ++void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, ++ enum rsnd_reg reg, u32 mask, u32 data) ++{ ++ void __iomem *base = rsnd_gen_reg_get(priv, mod, reg); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ u32 val; ++ ++ BUG_ON(!base); ++ ++ val = ioread32(base); ++ val &= ~mask; ++ val |= data & mask; ++ iowrite32(val, base); ++ ++ dev_dbg(dev, "s %p : %08x\n", base, val); ++} ++ ++/* + * rsnd_mod functions + */ + char *rsnd_mod_name(struct rsnd_mod *mod) +@@ -289,6 +333,10 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, + if (ret < 0) + goto dai_trigger_end; + ++ ret = rsnd_gen_path_init(priv, rdai, io); ++ if (ret < 0) ++ goto dai_trigger_end; ++ + ret = rsnd_dai_call(rdai, io, init); + if (ret < 0) + goto dai_trigger_end; +@@ -306,10 +354,13 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, + if (ret < 0) + goto dai_trigger_end; + +- ret = rsnd_platform_call(priv, dai, stop, ssi_id); ++ ret = rsnd_gen_path_exit(priv, rdai, io); + if (ret < 0) + goto dai_trigger_end; + ++ ret = rsnd_platform_call(priv, dai, stop, ssi_id); ++ if (ret < 0) ++ goto dai_trigger_end; + break; + default: + ret = -EINVAL; +@@ -572,6 +623,10 @@ static int rsnd_probe(struct platform_device *pdev) + /* + * init each module + */ ++ ret = rsnd_gen_probe(pdev, info, priv); ++ if (ret < 0) ++ return ret; ++ + ret = rsnd_dai_probe(pdev, info, priv); + if (ret < 0) + return ret; +@@ -615,6 +670,7 @@ static int rsnd_remove(struct platform_device *pdev) + * remove each module + */ + rsnd_dai_remove(pdev, priv); ++ rsnd_gen_remove(pdev, priv); + + return 0; + } +diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c +new file mode 100644 +index 000000000000..ec67a796eca2 +--- /dev/null ++++ b/sound/soc/sh/rcar/gen.c +@@ -0,0 +1,154 @@ ++/* ++ * Renesas R-Car Gen1 SRU/SSI support ++ * ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include "rsnd.h" ++ ++struct rsnd_gen_ops { ++ int (*path_init)(struct rsnd_priv *priv, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io); ++ int (*path_exit)(struct rsnd_priv *priv, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io); ++}; ++ ++struct rsnd_gen_reg_map { ++ int index; /* -1 : not supported */ ++ u32 offset_id; /* offset of ssi0, ssi1, ssi2... */ ++ u32 offset_adr; /* offset of SSICR, SSISR, ... */ ++}; ++ ++struct rsnd_gen { ++ void __iomem *base[RSND_BASE_MAX]; ++ ++ struct rsnd_gen_reg_map reg_map[RSND_REG_MAX]; ++ struct rsnd_gen_ops *ops; ++}; ++ ++#define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) ++ ++#define rsnd_is_gen1(s) ((s)->info->flags & RSND_GEN1) ++#define rsnd_is_gen2(s) ((s)->info->flags & RSND_GEN2) ++ ++/* ++ * Gen2 ++ * will be filled in the future ++ */ ++ ++/* ++ * Gen1 ++ */ ++static int rsnd_gen1_probe(struct platform_device *pdev, ++ struct rcar_snd_info *info, ++ struct rsnd_priv *priv) ++{ ++ return 0; ++} ++ ++static void rsnd_gen1_remove(struct platform_device *pdev, ++ struct rsnd_priv *priv) ++{ ++} ++ ++/* ++ * Gen ++ */ ++int rsnd_gen_path_init(struct rsnd_priv *priv, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_gen *gen = rsnd_priv_to_gen(priv); ++ ++ return gen->ops->path_init(priv, rdai, io); ++} ++ ++int rsnd_gen_path_exit(struct rsnd_priv *priv, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_gen *gen = rsnd_priv_to_gen(priv); ++ ++ return gen->ops->path_exit(priv, rdai, io); ++} ++ ++void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, ++ struct rsnd_mod *mod, ++ enum rsnd_reg reg) ++{ ++ struct rsnd_gen *gen = rsnd_priv_to_gen(priv); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ int index; ++ u32 offset_id, offset_adr; ++ ++ if (reg >= RSND_REG_MAX) { ++ dev_err(dev, "rsnd_reg reg error\n"); ++ return NULL; ++ } ++ ++ index = gen->reg_map[reg].index; ++ offset_id = gen->reg_map[reg].offset_id; ++ offset_adr = gen->reg_map[reg].offset_adr; ++ ++ if (index < 0) { ++ dev_err(dev, "unsupported reg access %d\n", reg); ++ return NULL; ++ } ++ ++ if (offset_id && mod) ++ offset_id *= rsnd_mod_id(mod); ++ ++ /* ++ * index/offset were set on gen1/gen2 ++ */ ++ ++ return gen->base[index] + offset_id + offset_adr; ++} ++ ++int rsnd_gen_probe(struct platform_device *pdev, ++ struct rcar_snd_info *info, ++ struct rsnd_priv *priv) ++{ ++ struct device *dev = rsnd_priv_to_dev(priv); ++ struct rsnd_gen *gen; ++ int i; ++ ++ gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); ++ if (!gen) { ++ dev_err(dev, "GEN allocate failed\n"); ++ return -ENOMEM; ++ } ++ ++ priv->gen = gen; ++ ++ /* ++ * see ++ * rsnd_reg_get() ++ * rsnd_gen_probe() ++ */ ++ for (i = 0; i < RSND_REG_MAX; i++) ++ gen->reg_map[i].index = -1; ++ ++ /* ++ * init each module ++ */ ++ if (rsnd_is_gen1(priv)) ++ return rsnd_gen1_probe(pdev, info, priv); ++ ++ dev_err(dev, "unknown generation R-Car sound device\n"); ++ ++ return -ENODEV; ++} ++ ++void rsnd_gen_remove(struct platform_device *pdev, ++ struct rsnd_priv *priv) ++{ ++ if (rsnd_is_gen1(priv)) ++ rsnd_gen1_remove(pdev, priv); ++} +diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h +index 65d3835cffbc..8cc36416da25 100644 +--- a/sound/soc/sh/rcar/rsnd.h ++++ b/sound/soc/sh/rcar/rsnd.h +@@ -27,12 +27,36 @@ + * This driver uses pseudo register in order to hide it. + * see gen1/gen2 for detail + */ ++enum rsnd_reg { ++ RSND_REG_MAX, ++}; ++ + struct rsnd_priv; + struct rsnd_mod; + struct rsnd_dai; + struct rsnd_dai_stream; + + /* ++ * R-Car basic functions ++ */ ++#define rsnd_mod_read(m, r) \ ++ rsnd_read(rsnd_mod_to_priv(m), m, RSND_REG_##r) ++#define rsnd_mod_write(m, r, d) \ ++ rsnd_write(rsnd_mod_to_priv(m), m, RSND_REG_##r, d) ++#define rsnd_mod_bset(m, r, s, d) \ ++ rsnd_bset(rsnd_mod_to_priv(m), m, RSND_REG_##r, s, d) ++ ++#define rsnd_priv_read(p, r) rsnd_read(p, NULL, RSND_REG_##r) ++#define rsnd_priv_write(p, r, d) rsnd_write(p, NULL, RSND_REG_##r, d) ++#define rsnd_priv_bset(p, r, s, d) rsnd_bset(p, NULL, RSND_REG_##r, s, d) ++ ++u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg); ++void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod, ++ enum rsnd_reg reg, u32 data); ++void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, ++ u32 mask, u32 data); ++ ++/* + * R-Car sound mod + */ + +@@ -117,6 +141,24 @@ void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); + int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); + + /* ++ * R-Car Gen1/Gen2 ++ */ ++int rsnd_gen_probe(struct platform_device *pdev, ++ struct rcar_snd_info *info, ++ struct rsnd_priv *priv); ++void rsnd_gen_remove(struct platform_device *pdev, ++ struct rsnd_priv *priv); ++int rsnd_gen_path_init(struct rsnd_priv *priv, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io); ++int rsnd_gen_path_exit(struct rsnd_priv *priv, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io); ++void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, ++ struct rsnd_mod *mod, ++ enum rsnd_reg reg); ++ ++/* + * R-Car sound priv + */ + struct rsnd_priv { +@@ -126,6 +168,11 @@ struct rsnd_priv { + spinlock_t lock; + + /* ++ * below value will be filled on rsnd_gen_probe() ++ */ ++ void *gen; ++ ++ /* + * below value will be filled on rsnd_dai_probe() + */ + struct snd_soc_dai_driver *daidrv; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0091-ASoC-add-Renesas-R-Car-SCU-feature.patch b/patches.renesas/0091-ASoC-add-Renesas-R-Car-SCU-feature.patch new file mode 100644 index 00000000000000..4f0c9c796944df --- /dev/null +++ b/patches.renesas/0091-ASoC-add-Renesas-R-Car-SCU-feature.patch @@ -0,0 +1,378 @@ +From 5cfb0bb00963de809a1881cfd17161b5d2fd0448 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 21 Jul 2013 21:36:35 -0700 +Subject: ASoC: add Renesas R-Car SCU feature + +Renesas R-Car series sound circuit consists of SSI and its peripheral. +But this peripheral circuit is different between +R-Car Generation1 (E1/M1/H1) and Generation2 (E2/M2/H2) +(Actually, there are many difference in Generation1 chips) + +This patch adds SCU feature on this driver. +But, it defines SCU style only, does nothing at this point. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 07539c1de82cdc0ecbe72b413762b2e920407227) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + include/sound/rcar_snd.h | 11 +++- + sound/soc/sh/rcar/Makefile | 4 +- + sound/soc/sh/rcar/core.c | 5 ++ + sound/soc/sh/rcar/gen.c | 95 ++++++++++++++++++++++++++++++++++ + sound/soc/sh/rcar/rsnd.h | 21 ++++++++ + sound/soc/sh/rcar/scu.c | 125 +++++++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 258 insertions(+), 3 deletions(-) + create mode 100644 sound/soc/sh/rcar/scu.c + +diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h +index 14942a827fe5..01f2e453dcbf 100644 +--- a/include/sound/rcar_snd.h ++++ b/include/sound/rcar_snd.h +@@ -14,8 +14,15 @@ + + #include <linux/sh_clk.h> + ++#define RSND_GEN1_SRU 0 + +-#define RSND_BASE_MAX 0 ++#define RSND_GEN2_SRU 0 ++ ++#define RSND_BASE_MAX 1 ++ ++struct rsnd_scu_platform_info { ++ u32 flags; ++}; + + struct rsnd_dai_platform_info { + int ssi_id_playback; +@@ -34,6 +41,8 @@ struct rsnd_dai_platform_info { + + struct rcar_snd_info { + u32 flags; ++ struct rsnd_scu_platform_info *scu_info; ++ int scu_info_nr; + struct rsnd_dai_platform_info *dai_info; + int dai_info_nr; + int (*start)(int id); +diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile +index b2d313b1eb94..112b2cfd793b 100644 +--- a/sound/soc/sh/rcar/Makefile ++++ b/sound/soc/sh/rcar/Makefile +@@ -1,2 +1,2 @@ +-snd-soc-rcar-objs := core.o gen.o +-obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o ++snd-soc-rcar-objs := core.o gen.o scu.o ++obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o +\ No newline at end of file +diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c +index bb8959f93a7d..02d736bb4f54 100644 +--- a/sound/soc/sh/rcar/core.c ++++ b/sound/soc/sh/rcar/core.c +@@ -631,6 +631,10 @@ static int rsnd_probe(struct platform_device *pdev) + if (ret < 0) + return ret; + ++ ret = rsnd_scu_probe(pdev, info, priv); ++ if (ret < 0) ++ return ret; ++ + /* + * asoc register + */ +@@ -669,6 +673,7 @@ static int rsnd_remove(struct platform_device *pdev) + /* + * remove each module + */ ++ rsnd_scu_remove(pdev, priv); + rsnd_dai_remove(pdev, priv); + rsnd_gen_remove(pdev, priv); + +diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c +index ec67a796eca2..2934c0d731c8 100644 +--- a/sound/soc/sh/rcar/gen.c ++++ b/sound/soc/sh/rcar/gen.c +@@ -45,10 +45,105 @@ struct rsnd_gen { + /* + * Gen1 + */ ++static int rsnd_gen1_path_init(struct rsnd_priv *priv, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_dai_platform_info *info = rsnd_dai_get_platform_info(rdai); ++ struct rsnd_mod *mod; ++ int ret; ++ int id; ++ ++ /* ++ * Gen1 is created by SRU/SSI, and this SRU is base module of ++ * Gen2's SCU/SSIU/SSI. (Gen2 SCU/SSIU came from SRU) ++ * ++ * Easy image is.. ++ * Gen1 SRU = Gen2 SCU + SSIU + etc ++ * ++ * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is ++ * using fixed path. ++ * ++ * Then, SSI id = SCU id here ++ */ ++ ++ if (rsnd_dai_is_play(rdai, io)) ++ id = info->ssi_id_playback; ++ else ++ id = info->ssi_id_capture; ++ ++ /* SCU */ ++ mod = rsnd_scu_mod_get(priv, id); ++ ret = rsnd_dai_connect(rdai, mod, io); ++ ++ return ret; ++} ++ ++static int rsnd_gen1_path_exit(struct rsnd_priv *priv, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_mod *mod, *n; ++ int ret = 0; ++ ++ /* ++ * remove all mod from rdai ++ */ ++ for_each_rsnd_mod(mod, n, io) ++ ret |= rsnd_dai_disconnect(mod); ++ ++ return ret; ++} ++ ++static struct rsnd_gen_ops rsnd_gen1_ops = { ++ .path_init = rsnd_gen1_path_init, ++ .path_exit = rsnd_gen1_path_exit, ++}; ++ ++#define RSND_GEN1_REG_MAP(g, s, i, oi, oa) \ ++ do { \ ++ (g)->reg_map[RSND_REG_##i].index = RSND_GEN1_##s; \ ++ (g)->reg_map[RSND_REG_##i].offset_id = oi; \ ++ (g)->reg_map[RSND_REG_##i].offset_adr = oa; \ ++ } while (0) ++ ++static void rsnd_gen1_reg_map_init(struct rsnd_gen *gen) ++{ ++ RSND_GEN1_REG_MAP(gen, SRU, SSI_MODE0, 0x0, 0xD0); ++ RSND_GEN1_REG_MAP(gen, SRU, SSI_MODE1, 0x0, 0xD4); ++} ++ + static int rsnd_gen1_probe(struct platform_device *pdev, + struct rcar_snd_info *info, + struct rsnd_priv *priv) + { ++ struct device *dev = rsnd_priv_to_dev(priv); ++ struct rsnd_gen *gen = rsnd_priv_to_gen(priv); ++ struct resource *sru_res; ++ ++ /* ++ * map address ++ */ ++ sru_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SRU); ++ if (!sru_res) { ++ dev_err(dev, "Not enough SRU/SSI/ADG platform resources.\n"); ++ return -ENODEV; ++ } ++ ++ gen->ops = &rsnd_gen1_ops; ++ ++ gen->base[RSND_GEN1_SRU] = devm_ioremap_resource(dev, sru_res); ++ if (!gen->base[RSND_GEN1_SRU]) { ++ dev_err(dev, "SRU/SSI/ADG ioremap failed\n"); ++ return -ENODEV; ++ } ++ ++ rsnd_gen1_reg_map_init(gen); ++ ++ dev_dbg(dev, "Gen1 device probed\n"); ++ dev_dbg(dev, "SRU : %08x => %p\n", sru_res->start, ++ gen->base[RSND_GEN1_SRU]); ++ + return 0; + } + +diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h +index 8cc36416da25..95a391ff0627 100644 +--- a/sound/soc/sh/rcar/rsnd.h ++++ b/sound/soc/sh/rcar/rsnd.h +@@ -28,6 +28,10 @@ + * see gen1/gen2 for detail + */ + enum rsnd_reg { ++ /* SRU/SCU */ ++ RSND_REG_SSI_MODE0, ++ RSND_REG_SSI_MODE1, ++ + RSND_REG_MAX, + }; + +@@ -173,6 +177,12 @@ struct rsnd_priv { + void *gen; + + /* ++ * below value will be filled on rsnd_scu_probe() ++ */ ++ void *scu; ++ int scu_nr; ++ ++ /* + * below value will be filled on rsnd_dai_probe() + */ + struct snd_soc_dai_driver *daidrv; +@@ -184,4 +194,15 @@ struct rsnd_priv { + #define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags) + #define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags) + ++/* ++ * R-Car SCU ++ */ ++int rsnd_scu_probe(struct platform_device *pdev, ++ struct rcar_snd_info *info, ++ struct rsnd_priv *priv); ++void rsnd_scu_remove(struct platform_device *pdev, ++ struct rsnd_priv *priv); ++struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id); ++#define rsnd_scu_nr(priv) ((priv)->scu_nr) ++ + #endif +diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c +new file mode 100644 +index 000000000000..c12e65f240a1 +--- /dev/null ++++ b/sound/soc/sh/rcar/scu.c +@@ -0,0 +1,125 @@ ++/* ++ * Renesas R-Car SCU support ++ * ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include "rsnd.h" ++ ++struct rsnd_scu { ++ struct rsnd_scu_platform_info *info; /* rcar_snd.h */ ++ struct rsnd_mod mod; ++}; ++ ++#define rsnd_mod_to_scu(_mod) \ ++ container_of((_mod), struct rsnd_scu, mod) ++ ++#define for_each_rsnd_scu(pos, priv, i) \ ++ for ((i) = 0; \ ++ ((i) < rsnd_scu_nr(priv)) && \ ++ ((pos) = (struct rsnd_scu *)(priv)->scu + i); \ ++ i++) ++ ++static int rsnd_scu_init(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ ++ dev_dbg(dev, "%s.%d init\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); ++ ++ return 0; ++} ++ ++static int rsnd_scu_quit(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ ++ dev_dbg(dev, "%s.%d quit\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); ++ ++ return 0; ++} ++ ++static int rsnd_scu_start(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ ++ dev_dbg(dev, "%s.%d start\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); ++ ++ return 0; ++} ++ ++static int rsnd_scu_stop(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ ++ dev_dbg(dev, "%s.%d stop\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); ++ ++ return 0; ++} ++ ++static struct rsnd_mod_ops rsnd_scu_ops = { ++ .name = "scu", ++ .init = rsnd_scu_init, ++ .quit = rsnd_scu_quit, ++ .start = rsnd_scu_start, ++ .stop = rsnd_scu_stop, ++}; ++ ++struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id) ++{ ++ BUG_ON(id < 0 || id >= rsnd_scu_nr(priv)); ++ ++ return &((struct rsnd_scu *)(priv->scu) + id)->mod; ++} ++ ++int rsnd_scu_probe(struct platform_device *pdev, ++ struct rcar_snd_info *info, ++ struct rsnd_priv *priv) ++{ ++ struct device *dev = rsnd_priv_to_dev(priv); ++ struct rsnd_scu *scu; ++ int i, nr; ++ ++ /* ++ * init SCU ++ */ ++ nr = info->scu_info_nr; ++ scu = devm_kzalloc(dev, sizeof(*scu) * nr, GFP_KERNEL); ++ if (!scu) { ++ dev_err(dev, "SCU allocate failed\n"); ++ return -ENOMEM; ++ } ++ ++ priv->scu_nr = nr; ++ priv->scu = scu; ++ ++ for_each_rsnd_scu(scu, priv, i) { ++ rsnd_mod_init(priv, &scu->mod, ++ &rsnd_scu_ops, i); ++ scu->info = &info->scu_info[i]; ++ } ++ ++ dev_dbg(dev, "scu probed\n"); ++ ++ return 0; ++} ++ ++void rsnd_scu_remove(struct platform_device *pdev, ++ struct rsnd_priv *priv) ++{ ++} +-- +1.8.5.rc3 + diff --git a/patches.renesas/0092-ASoC-add-Renesas-R-Car-ADG-feature.patch b/patches.renesas/0092-ASoC-add-Renesas-R-Car-ADG-feature.patch new file mode 100644 index 00000000000000..82d9a869f68848 --- /dev/null +++ b/patches.renesas/0092-ASoC-add-Renesas-R-Car-ADG-feature.patch @@ -0,0 +1,428 @@ +From 58a1d7f9db87ee18a2f6820efaab78efd184c741 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 21 Jul 2013 21:36:46 -0700 +Subject: ASoC: add Renesas R-Car ADG feature + +Renesas R-Car series sound circuit consists of SSI and its peripheral. +But this peripheral circuit is different between +R-Car Generation1 (E1/M1/H1) and Generation2 (E2/M2/H2) +(Actually, there are many difference in Generation1 chips) + +This patch adds ADG feature which controls sound clock + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit dfc9403b7c1f566bb099a12c58aee20589e390f1) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + include/sound/rcar_snd.h | 4 +- + sound/soc/sh/rcar/Makefile | 2 +- + sound/soc/sh/rcar/adg.c | 234 +++++++++++++++++++++++++++++++++++++++++++++ + sound/soc/sh/rcar/core.c | 5 + + sound/soc/sh/rcar/gen.c | 20 +++- + sound/soc/sh/rcar/rsnd.h | 27 ++++++ + 6 files changed, 288 insertions(+), 4 deletions(-) + create mode 100644 sound/soc/sh/rcar/adg.c + +diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h +index 01f2e453dcbf..6babd6f7b537 100644 +--- a/include/sound/rcar_snd.h ++++ b/include/sound/rcar_snd.h +@@ -15,10 +15,12 @@ + #include <linux/sh_clk.h> + + #define RSND_GEN1_SRU 0 ++#define RSND_GEN1_ADG 1 + + #define RSND_GEN2_SRU 0 ++#define RSND_GEN2_ADG 1 + +-#define RSND_BASE_MAX 1 ++#define RSND_BASE_MAX 2 + + struct rsnd_scu_platform_info { + u32 flags; +diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile +index 112b2cfd793b..c11280cffcfe 100644 +--- a/sound/soc/sh/rcar/Makefile ++++ b/sound/soc/sh/rcar/Makefile +@@ -1,2 +1,2 @@ +-snd-soc-rcar-objs := core.o gen.o scu.o ++snd-soc-rcar-objs := core.o gen.o scu.o adg.o + obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o +\ No newline at end of file +diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c +new file mode 100644 +index 000000000000..d80deb7ccf13 +--- /dev/null ++++ b/sound/soc/sh/rcar/adg.c +@@ -0,0 +1,234 @@ ++/* ++ * Helper routines for R-Car sound ADG. ++ * ++ * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ */ ++#include <linux/sh_clk.h> ++#include <mach/clock.h> ++#include "rsnd.h" ++ ++#define CLKA 0 ++#define CLKB 1 ++#define CLKC 2 ++#define CLKI 3 ++#define CLKMAX 4 ++ ++struct rsnd_adg { ++ struct clk *clk[CLKMAX]; ++ ++ int rate_of_441khz_div_6; ++ int rate_of_48khz_div_6; ++}; ++ ++#define for_each_rsnd_clk(pos, adg, i) \ ++ for (i = 0, (pos) = adg->clk[i]; \ ++ i < CLKMAX; \ ++ i++, (pos) = adg->clk[i]) ++#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg) ++ ++static enum rsnd_reg rsnd_adg_ssi_reg_get(int id) ++{ ++ enum rsnd_reg reg; ++ ++ /* ++ * SSI 8 is not connected to ADG. ++ * it works with SSI 7 ++ */ ++ if (id == 8) ++ return RSND_REG_MAX; ++ ++ if (0 <= id && id <= 3) ++ reg = RSND_REG_AUDIO_CLK_SEL0; ++ else if (4 <= id && id <= 7) ++ reg = RSND_REG_AUDIO_CLK_SEL1; ++ else ++ reg = RSND_REG_AUDIO_CLK_SEL2; ++ ++ return reg; ++} ++ ++int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod) ++{ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ enum rsnd_reg reg; ++ int id; ++ ++ /* ++ * "mod" = "ssi" here. ++ * we can get "ssi id" from mod ++ */ ++ id = rsnd_mod_id(mod); ++ reg = rsnd_adg_ssi_reg_get(id); ++ ++ rsnd_write(priv, mod, reg, 0); ++ ++ return 0; ++} ++ ++int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate) ++{ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ struct rsnd_adg *adg = rsnd_priv_to_adg(priv); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ struct clk *clk; ++ enum rsnd_reg reg; ++ int id, shift, i; ++ u32 data; ++ int sel_table[] = { ++ [CLKA] = 0x1, ++ [CLKB] = 0x2, ++ [CLKC] = 0x3, ++ [CLKI] = 0x0, ++ }; ++ ++ dev_dbg(dev, "request clock = %d\n", rate); ++ ++ /* ++ * find suitable clock from ++ * AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC/AUDIO_CLKI. ++ */ ++ data = 0; ++ for_each_rsnd_clk(clk, adg, i) { ++ if (rate == clk_get_rate(clk)) { ++ data = sel_table[i]; ++ goto found_clock; ++ } ++ } ++ ++ /* ++ * find 1/6 clock from BRGA/BRGB ++ */ ++ if (rate == adg->rate_of_441khz_div_6) { ++ data = 0x10; ++ goto found_clock; ++ } ++ ++ if (rate == adg->rate_of_48khz_div_6) { ++ data = 0x20; ++ goto found_clock; ++ } ++ ++ return -EIO; ++ ++found_clock: ++ ++ /* ++ * This "mod" = "ssi" here. ++ * we can get "ssi id" from mod ++ */ ++ id = rsnd_mod_id(mod); ++ reg = rsnd_adg_ssi_reg_get(id); ++ ++ dev_dbg(dev, "ADG: ssi%d selects clk%d = %d", id, i, rate); ++ ++ /* ++ * Enable SSIx clock ++ */ ++ shift = (id % 4) * 8; ++ ++ rsnd_bset(priv, mod, reg, ++ 0xFF << shift, ++ data << shift); ++ ++ return 0; ++} ++ ++static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg) ++{ ++ struct clk *clk; ++ unsigned long rate; ++ u32 ckr; ++ int i; ++ int brg_table[] = { ++ [CLKA] = 0x0, ++ [CLKB] = 0x1, ++ [CLKC] = 0x4, ++ [CLKI] = 0x2, ++ }; ++ ++ /* ++ * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC ++ * have 44.1kHz or 48kHz base clocks for now. ++ * ++ * SSI itself can divide parent clock by 1/1 - 1/16 ++ * So, BRGA outputs 44.1kHz base parent clock 1/32, ++ * and, BRGB outputs 48.0kHz base parent clock 1/32 here. ++ * see ++ * rsnd_adg_ssi_clk_try_start() ++ */ ++ ckr = 0; ++ adg->rate_of_441khz_div_6 = 0; ++ adg->rate_of_48khz_div_6 = 0; ++ for_each_rsnd_clk(clk, adg, i) { ++ rate = clk_get_rate(clk); ++ ++ if (0 == rate) /* not used */ ++ continue; ++ ++ /* RBGA */ ++ if (!adg->rate_of_441khz_div_6 && (0 == rate % 44100)) { ++ adg->rate_of_441khz_div_6 = rate / 6; ++ ckr |= brg_table[i] << 20; ++ } ++ ++ /* RBGB */ ++ if (!adg->rate_of_48khz_div_6 && (0 == rate % 48000)) { ++ adg->rate_of_48khz_div_6 = rate / 6; ++ ckr |= brg_table[i] << 16; ++ } ++ } ++ ++ rsnd_priv_bset(priv, SSICKR, 0x00FF0000, ckr); ++ rsnd_priv_write(priv, BRRA, 0x00000002); /* 1/6 */ ++ rsnd_priv_write(priv, BRRB, 0x00000002); /* 1/6 */ ++} ++ ++int rsnd_adg_probe(struct platform_device *pdev, ++ struct rcar_snd_info *info, ++ struct rsnd_priv *priv) ++{ ++ struct rsnd_adg *adg; ++ struct device *dev = rsnd_priv_to_dev(priv); ++ struct clk *clk; ++ int i; ++ ++ adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); ++ if (!adg) { ++ dev_err(dev, "ADG allocate failed\n"); ++ return -ENOMEM; ++ } ++ ++ adg->clk[CLKA] = clk_get(NULL, "audio_clk_a"); ++ adg->clk[CLKB] = clk_get(NULL, "audio_clk_b"); ++ adg->clk[CLKC] = clk_get(NULL, "audio_clk_c"); ++ adg->clk[CLKI] = clk_get(NULL, "audio_clk_internal"); ++ for_each_rsnd_clk(clk, adg, i) { ++ if (IS_ERR(clk)) { ++ dev_err(dev, "Audio clock failed\n"); ++ return -EIO; ++ } ++ } ++ ++ rsnd_adg_ssi_clk_init(priv, adg); ++ ++ priv->adg = adg; ++ ++ dev_dbg(dev, "adg probed\n"); ++ ++ return 0; ++} ++ ++void rsnd_adg_remove(struct platform_device *pdev, ++ struct rsnd_priv *priv) ++{ ++ struct rsnd_adg *adg = priv->adg; ++ struct clk *clk; ++ int i; ++ ++ for_each_rsnd_clk(clk, adg, i) ++ clk_put(clk); ++} +diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c +index 02d736bb4f54..e588d8a8ae40 100644 +--- a/sound/soc/sh/rcar/core.c ++++ b/sound/soc/sh/rcar/core.c +@@ -635,6 +635,10 @@ static int rsnd_probe(struct platform_device *pdev) + if (ret < 0) + return ret; + ++ ret = rsnd_adg_probe(pdev, info, priv); ++ if (ret < 0) ++ return ret; ++ + /* + * asoc register + */ +@@ -673,6 +677,7 @@ static int rsnd_remove(struct platform_device *pdev) + /* + * remove each module + */ ++ rsnd_adg_remove(pdev, priv); + rsnd_scu_remove(pdev, priv); + rsnd_dai_remove(pdev, priv); + rsnd_gen_remove(pdev, priv); +diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c +index 2934c0d731c8..ed21a136354f 100644 +--- a/sound/soc/sh/rcar/gen.c ++++ b/sound/soc/sh/rcar/gen.c +@@ -111,6 +111,15 @@ static void rsnd_gen1_reg_map_init(struct rsnd_gen *gen) + { + RSND_GEN1_REG_MAP(gen, SRU, SSI_MODE0, 0x0, 0xD0); + RSND_GEN1_REG_MAP(gen, SRU, SSI_MODE1, 0x0, 0xD4); ++ ++ RSND_GEN1_REG_MAP(gen, ADG, BRRA, 0x0, 0x00); ++ RSND_GEN1_REG_MAP(gen, ADG, BRRB, 0x0, 0x04); ++ RSND_GEN1_REG_MAP(gen, ADG, SSICKR, 0x0, 0x08); ++ RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL0, 0x0, 0x0c); ++ RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL1, 0x0, 0x10); ++ RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL3, 0x0, 0x18); ++ RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL4, 0x0, 0x1c); ++ RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL5, 0x0, 0x20); + } + + static int rsnd_gen1_probe(struct platform_device *pdev, +@@ -120,12 +129,15 @@ static int rsnd_gen1_probe(struct platform_device *pdev, + struct device *dev = rsnd_priv_to_dev(priv); + struct rsnd_gen *gen = rsnd_priv_to_gen(priv); + struct resource *sru_res; ++ struct resource *adg_res; + + /* + * map address + */ + sru_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SRU); +- if (!sru_res) { ++ adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_ADG); ++ if (!sru_res || ++ !adg_res) { + dev_err(dev, "Not enough SRU/SSI/ADG platform resources.\n"); + return -ENODEV; + } +@@ -133,7 +145,9 @@ static int rsnd_gen1_probe(struct platform_device *pdev, + gen->ops = &rsnd_gen1_ops; + + gen->base[RSND_GEN1_SRU] = devm_ioremap_resource(dev, sru_res); +- if (!gen->base[RSND_GEN1_SRU]) { ++ gen->base[RSND_GEN1_ADG] = devm_ioremap_resource(dev, adg_res); ++ if (!gen->base[RSND_GEN1_SRU] || ++ !gen->base[RSND_GEN1_ADG]) { + dev_err(dev, "SRU/SSI/ADG ioremap failed\n"); + return -ENODEV; + } +@@ -143,6 +157,8 @@ static int rsnd_gen1_probe(struct platform_device *pdev, + dev_dbg(dev, "Gen1 device probed\n"); + dev_dbg(dev, "SRU : %08x => %p\n", sru_res->start, + gen->base[RSND_GEN1_SRU]); ++ dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start, ++ gen->base[RSND_GEN1_ADG]); + + return 0; + } +diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h +index 95a391ff0627..344fd59cb7fd 100644 +--- a/sound/soc/sh/rcar/rsnd.h ++++ b/sound/soc/sh/rcar/rsnd.h +@@ -32,6 +32,17 @@ enum rsnd_reg { + RSND_REG_SSI_MODE0, + RSND_REG_SSI_MODE1, + ++ /* ADG */ ++ RSND_REG_BRRA, ++ RSND_REG_BRRB, ++ RSND_REG_SSICKR, ++ RSND_REG_AUDIO_CLK_SEL0, ++ RSND_REG_AUDIO_CLK_SEL1, ++ RSND_REG_AUDIO_CLK_SEL2, ++ RSND_REG_AUDIO_CLK_SEL3, ++ RSND_REG_AUDIO_CLK_SEL4, ++ RSND_REG_AUDIO_CLK_SEL5, ++ + RSND_REG_MAX, + }; + +@@ -163,6 +174,17 @@ void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, + enum rsnd_reg reg); + + /* ++ * R-Car ADG ++ */ ++int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod); ++int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate); ++int rsnd_adg_probe(struct platform_device *pdev, ++ struct rcar_snd_info *info, ++ struct rsnd_priv *priv); ++void rsnd_adg_remove(struct platform_device *pdev, ++ struct rsnd_priv *priv); ++ ++/* + * R-Car sound priv + */ + struct rsnd_priv { +@@ -183,6 +205,11 @@ struct rsnd_priv { + int scu_nr; + + /* ++ * below value will be filled on rsnd_adg_probe() ++ */ ++ void *adg; ++ ++ /* + * below value will be filled on rsnd_dai_probe() + */ + struct snd_soc_dai_driver *daidrv; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0093-ASoC-add-Renesas-R-Car-SSI-feature.patch b/patches.renesas/0093-ASoC-add-Renesas-R-Car-SSI-feature.patch new file mode 100644 index 00000000000000..9e177bcae02b8b --- /dev/null +++ b/patches.renesas/0093-ASoC-add-Renesas-R-Car-SSI-feature.patch @@ -0,0 +1,828 @@ +From c30f538ea1f7b9c6ba47ad29197aef1ea68dfeeb Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 21 Jul 2013 21:36:57 -0700 +Subject: ASoC: add Renesas R-Car SSI feature + +Renesas R-Car series sound circuit consists of SSI and its peripheral. +But this peripheral circuit is different between +R-Car Generation1 (E1/M1/H1) and Generation2 (E2/M2/H2) +(Actually, there are many difference in Generation1 chips) + +As 1st protype, this patch adds SSI feature on this driver. +But, it is PIO sound playback support only at this point. +The DMA transfer, and capture feature will be supported in the future + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit ae5c322303fff50b93d60e34c6563f1264a5941b) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + include/sound/rcar_snd.h | 23 +- + sound/soc/sh/rcar/Makefile | 2 +- + sound/soc/sh/rcar/core.c | 5 + + sound/soc/sh/rcar/gen.c | 24 +- + sound/soc/sh/rcar/rsnd.h | 23 ++ + sound/soc/sh/rcar/ssi.c | 588 +++++++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 661 insertions(+), 4 deletions(-) + create mode 100644 sound/soc/sh/rcar/ssi.c + +diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h +index 6babd6f7b537..99d8dd029906 100644 +--- a/include/sound/rcar_snd.h ++++ b/include/sound/rcar_snd.h +@@ -16,11 +16,30 @@ + + #define RSND_GEN1_SRU 0 + #define RSND_GEN1_ADG 1 ++#define RSND_GEN1_SSI 2 + + #define RSND_GEN2_SRU 0 + #define RSND_GEN2_ADG 1 ++#define RSND_GEN2_SSIU 2 ++#define RSND_GEN2_SSI 3 + +-#define RSND_BASE_MAX 2 ++#define RSND_BASE_MAX 4 ++ ++/* ++ * flags ++ * ++ * 0xA0000000 ++ * ++ * A : clock sharing settings ++ */ ++#define RSND_SSI_CLK_PIN_SHARE (1 << 31) ++#define RSND_SSI_CLK_FROM_ADG (1 << 30) /* clock parent is master */ ++#define RSND_SSI_SYNC (1 << 29) /* SSI34_sync etc */ ++ ++struct rsnd_ssi_platform_info { ++ int pio_irq; ++ u32 flags; ++}; + + struct rsnd_scu_platform_info { + u32 flags; +@@ -43,6 +62,8 @@ struct rsnd_dai_platform_info { + + struct rcar_snd_info { + u32 flags; ++ struct rsnd_ssi_platform_info *ssi_info; ++ int ssi_info_nr; + struct rsnd_scu_platform_info *scu_info; + int scu_info_nr; + struct rsnd_dai_platform_info *dai_info; +diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile +index c11280cffcfe..0ff492df7929 100644 +--- a/sound/soc/sh/rcar/Makefile ++++ b/sound/soc/sh/rcar/Makefile +@@ -1,2 +1,2 @@ +-snd-soc-rcar-objs := core.o gen.o scu.o adg.o ++snd-soc-rcar-objs := core.o gen.o scu.o adg.o ssi.o + obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o +\ No newline at end of file +diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c +index e588d8a8ae40..9a5469d3f352 100644 +--- a/sound/soc/sh/rcar/core.c ++++ b/sound/soc/sh/rcar/core.c +@@ -639,6 +639,10 @@ static int rsnd_probe(struct platform_device *pdev) + if (ret < 0) + return ret; + ++ ret = rsnd_ssi_probe(pdev, info, priv); ++ if (ret < 0) ++ return ret; ++ + /* + * asoc register + */ +@@ -677,6 +681,7 @@ static int rsnd_remove(struct platform_device *pdev) + /* + * remove each module + */ ++ rsnd_ssi_remove(pdev, priv); + rsnd_adg_remove(pdev, priv); + rsnd_scu_remove(pdev, priv); + rsnd_dai_remove(pdev, priv); +diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c +index ed21a136354f..5e4ae0da4352 100644 +--- a/sound/soc/sh/rcar/gen.c ++++ b/sound/soc/sh/rcar/gen.c +@@ -72,6 +72,12 @@ static int rsnd_gen1_path_init(struct rsnd_priv *priv, + else + id = info->ssi_id_capture; + ++ /* SSI */ ++ mod = rsnd_ssi_mod_get(priv, id); ++ ret = rsnd_dai_connect(rdai, mod, io); ++ if (ret < 0) ++ return ret; ++ + /* SCU */ + mod = rsnd_scu_mod_get(priv, id); + ret = rsnd_dai_connect(rdai, mod, io); +@@ -120,6 +126,12 @@ static void rsnd_gen1_reg_map_init(struct rsnd_gen *gen) + RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL3, 0x0, 0x18); + RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL4, 0x0, 0x1c); + RSND_GEN1_REG_MAP(gen, ADG, AUDIO_CLK_SEL5, 0x0, 0x20); ++ ++ RSND_GEN1_REG_MAP(gen, SSI, SSICR, 0x40, 0x00); ++ RSND_GEN1_REG_MAP(gen, SSI, SSISR, 0x40, 0x04); ++ RSND_GEN1_REG_MAP(gen, SSI, SSITDR, 0x40, 0x08); ++ RSND_GEN1_REG_MAP(gen, SSI, SSIRDR, 0x40, 0x0c); ++ RSND_GEN1_REG_MAP(gen, SSI, SSIWSR, 0x40, 0x20); + } + + static int rsnd_gen1_probe(struct platform_device *pdev, +@@ -130,14 +142,17 @@ static int rsnd_gen1_probe(struct platform_device *pdev, + struct rsnd_gen *gen = rsnd_priv_to_gen(priv); + struct resource *sru_res; + struct resource *adg_res; ++ struct resource *ssi_res; + + /* + * map address + */ + sru_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SRU); + adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_ADG); ++ ssi_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SSI); + if (!sru_res || +- !adg_res) { ++ !adg_res || ++ !ssi_res) { + dev_err(dev, "Not enough SRU/SSI/ADG platform resources.\n"); + return -ENODEV; + } +@@ -146,8 +161,10 @@ static int rsnd_gen1_probe(struct platform_device *pdev, + + gen->base[RSND_GEN1_SRU] = devm_ioremap_resource(dev, sru_res); + gen->base[RSND_GEN1_ADG] = devm_ioremap_resource(dev, adg_res); ++ gen->base[RSND_GEN1_SSI] = devm_ioremap_resource(dev, ssi_res); + if (!gen->base[RSND_GEN1_SRU] || +- !gen->base[RSND_GEN1_ADG]) { ++ !gen->base[RSND_GEN1_ADG] || ++ !gen->base[RSND_GEN1_SSI]) { + dev_err(dev, "SRU/SSI/ADG ioremap failed\n"); + return -ENODEV; + } +@@ -159,8 +176,11 @@ static int rsnd_gen1_probe(struct platform_device *pdev, + gen->base[RSND_GEN1_SRU]); + dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start, + gen->base[RSND_GEN1_ADG]); ++ dev_dbg(dev, "SSI : %08x => %p\n", ssi_res->start, ++ gen->base[RSND_GEN1_SSI]); + + return 0; ++ + } + + static void rsnd_gen1_remove(struct platform_device *pdev, +diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h +index 344fd59cb7fd..0e7727cc41db 100644 +--- a/sound/soc/sh/rcar/rsnd.h ++++ b/sound/soc/sh/rcar/rsnd.h +@@ -43,6 +43,13 @@ enum rsnd_reg { + RSND_REG_AUDIO_CLK_SEL4, + RSND_REG_AUDIO_CLK_SEL5, + ++ /* SSI */ ++ RSND_REG_SSICR, ++ RSND_REG_SSISR, ++ RSND_REG_SSITDR, ++ RSND_REG_SSIRDR, ++ RSND_REG_SSIWSR, ++ + RSND_REG_MAX, + }; + +@@ -151,6 +158,7 @@ int rsnd_dai_connect(struct rsnd_dai *rdai, struct rsnd_mod *mod, + struct rsnd_dai_stream *io); + int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io); + #define rsnd_dai_get_platform_info(rdai) ((rdai)->info) ++#define rsnd_io_to_runtime(io) ((io)->substream->runtime) + + void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); + int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); +@@ -210,6 +218,11 @@ struct rsnd_priv { + void *adg; + + /* ++ * below value will be filled on rsnd_ssi_probe() ++ */ ++ void *ssiu; ++ ++ /* + * below value will be filled on rsnd_dai_probe() + */ + struct snd_soc_dai_driver *daidrv; +@@ -232,4 +245,14 @@ void rsnd_scu_remove(struct platform_device *pdev, + struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id); + #define rsnd_scu_nr(priv) ((priv)->scu_nr) + ++/* ++ * R-Car SSI ++ */ ++int rsnd_ssi_probe(struct platform_device *pdev, ++ struct rcar_snd_info *info, ++ struct rsnd_priv *priv); ++void rsnd_ssi_remove(struct platform_device *pdev, ++ struct rsnd_priv *priv); ++struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); ++ + #endif +diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c +new file mode 100644 +index 000000000000..061ac7e88309 +--- /dev/null ++++ b/sound/soc/sh/rcar/ssi.c +@@ -0,0 +1,588 @@ ++/* ++ * Renesas R-Car SSIU/SSI support ++ * ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> ++ * ++ * Based on fsi.c ++ * Kuninori Morimoto <morimoto.kuninori@renesas.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include <linux/delay.h> ++#include "rsnd.h" ++#define RSND_SSI_NAME_SIZE 16 ++ ++/* ++ * SSICR ++ */ ++#define FORCE (1 << 31) /* Fixed */ ++#define UIEN (1 << 27) /* Underflow Interrupt Enable */ ++#define OIEN (1 << 26) /* Overflow Interrupt Enable */ ++#define IIEN (1 << 25) /* Idle Mode Interrupt Enable */ ++#define DIEN (1 << 24) /* Data Interrupt Enable */ ++ ++#define DWL_8 (0 << 19) /* Data Word Length */ ++#define DWL_16 (1 << 19) /* Data Word Length */ ++#define DWL_18 (2 << 19) /* Data Word Length */ ++#define DWL_20 (3 << 19) /* Data Word Length */ ++#define DWL_22 (4 << 19) /* Data Word Length */ ++#define DWL_24 (5 << 19) /* Data Word Length */ ++#define DWL_32 (6 << 19) /* Data Word Length */ ++ ++#define SWL_32 (3 << 16) /* R/W System Word Length */ ++#define SCKD (1 << 15) /* Serial Bit Clock Direction */ ++#define SWSD (1 << 14) /* Serial WS Direction */ ++#define SCKP (1 << 13) /* Serial Bit Clock Polarity */ ++#define SWSP (1 << 12) /* Serial WS Polarity */ ++#define SDTA (1 << 10) /* Serial Data Alignment */ ++#define DEL (1 << 8) /* Serial Data Delay */ ++#define CKDV(v) (v << 4) /* Serial Clock Division Ratio */ ++#define TRMD (1 << 1) /* Transmit/Receive Mode Select */ ++#define EN (1 << 0) /* SSI Module Enable */ ++ ++/* ++ * SSISR ++ */ ++#define UIRQ (1 << 27) /* Underflow Error Interrupt Status */ ++#define OIRQ (1 << 26) /* Overflow Error Interrupt Status */ ++#define IIRQ (1 << 25) /* Idle Mode Interrupt Status */ ++#define DIRQ (1 << 24) /* Data Interrupt Status Flag */ ++ ++struct rsnd_ssi { ++ struct clk *clk; ++ struct rsnd_ssi_platform_info *info; /* rcar_snd.h */ ++ struct rsnd_ssi *parent; ++ struct rsnd_mod mod; ++ ++ struct rsnd_dai *rdai; ++ struct rsnd_dai_stream *io; ++ u32 cr_own; ++ u32 cr_clk; ++ u32 cr_etc; ++ int err; ++ unsigned int usrcnt; ++ unsigned int rate; ++}; ++ ++struct rsnd_ssiu { ++ u32 ssi_mode0; ++ u32 ssi_mode1; ++ ++ int ssi_nr; ++ struct rsnd_ssi *ssi; ++}; ++ ++#define for_each_rsnd_ssi(pos, priv, i) \ ++ for (i = 0; \ ++ (i < rsnd_ssi_nr(priv)) && \ ++ ((pos) = ((struct rsnd_ssiu *)((priv)->ssiu))->ssi + i); \ ++ i++) ++ ++#define rsnd_ssi_nr(priv) (((struct rsnd_ssiu *)((priv)->ssiu))->ssi_nr) ++#define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) ++#define rsnd_ssi_is_pio(ssi) ((ssi)->info->pio_irq > 0) ++#define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent) ++#define rsnd_rdai_is_clk_master(rdai) ((rdai)->clk_master) ++#define rsnd_ssi_mode_flags(p) ((p)->info->flags) ++#define rsnd_ssi_to_ssiu(ssi)\ ++ (((struct rsnd_ssiu *)((ssi) - rsnd_mod_id(&(ssi)->mod))) - 1) ++ ++static void rsnd_ssi_mode_init(struct rsnd_priv *priv, ++ struct rsnd_ssiu *ssiu) ++{ ++ struct rsnd_ssi *ssi; ++ u32 flags; ++ u32 val; ++ int i; ++ ++ /* ++ * SSI_MODE0 ++ */ ++ ssiu->ssi_mode0 = 0; ++ for_each_rsnd_ssi(ssi, priv, i) ++ ssiu->ssi_mode0 |= (1 << i); ++ ++ /* ++ * SSI_MODE1 ++ */ ++#define ssi_parent_set(p, sync, adg, ext) \ ++ do { \ ++ ssi->parent = ssiu->ssi + p; \ ++ if (flags & RSND_SSI_CLK_FROM_ADG) \ ++ val = adg; \ ++ else \ ++ val = ext; \ ++ if (flags & RSND_SSI_SYNC) \ ++ val |= sync; \ ++ } while (0) ++ ++ ssiu->ssi_mode1 = 0; ++ for_each_rsnd_ssi(ssi, priv, i) { ++ flags = rsnd_ssi_mode_flags(ssi); ++ ++ if (!(flags & RSND_SSI_CLK_PIN_SHARE)) ++ continue; ++ ++ val = 0; ++ switch (i) { ++ case 1: ++ ssi_parent_set(0, (1 << 4), (0x2 << 0), (0x1 << 0)); ++ break; ++ case 2: ++ ssi_parent_set(0, (1 << 4), (0x2 << 2), (0x1 << 2)); ++ break; ++ case 4: ++ ssi_parent_set(3, (1 << 20), (0x2 << 16), (0x1 << 16)); ++ break; ++ case 8: ++ ssi_parent_set(7, 0, 0, 0); ++ break; ++ } ++ ++ ssiu->ssi_mode1 |= val; ++ } ++} ++ ++static void rsnd_ssi_mode_set(struct rsnd_ssi *ssi) ++{ ++ struct rsnd_ssiu *ssiu = rsnd_ssi_to_ssiu(ssi); ++ ++ rsnd_mod_write(&ssi->mod, SSI_MODE0, ssiu->ssi_mode0); ++ rsnd_mod_write(&ssi->mod, SSI_MODE1, ssiu->ssi_mode1); ++} ++ ++static void rsnd_ssi_status_check(struct rsnd_mod *mod, ++ u32 bit) ++{ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ u32 status; ++ int i; ++ ++ for (i = 0; i < 1024; i++) { ++ status = rsnd_mod_read(mod, SSISR); ++ if (status & bit) ++ return; ++ ++ udelay(50); ++ } ++ ++ dev_warn(dev, "status check failed\n"); ++} ++ ++static int rsnd_ssi_master_clk_start(struct rsnd_ssi *ssi, ++ unsigned int rate) ++{ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ int i, j, ret; ++ int adg_clk_div_table[] = { ++ 1, 6, /* see adg.c */ ++ }; ++ int ssi_clk_mul_table[] = { ++ 1, 2, 4, 8, 16, 6, 12, ++ }; ++ unsigned int main_rate; ++ ++ /* ++ * Find best clock, and try to start ADG ++ */ ++ for (i = 0; i < ARRAY_SIZE(adg_clk_div_table); i++) { ++ for (j = 0; j < ARRAY_SIZE(ssi_clk_mul_table); j++) { ++ ++ /* ++ * this driver is assuming that ++ * system word is 64fs (= 2 x 32bit) ++ * see rsnd_ssi_start() ++ */ ++ main_rate = rate / adg_clk_div_table[i] ++ * 32 * 2 * ssi_clk_mul_table[j]; ++ ++ ret = rsnd_adg_ssi_clk_try_start(&ssi->mod, main_rate); ++ if (0 == ret) { ++ ssi->rate = rate; ++ ssi->cr_clk = FORCE | SWL_32 | ++ SCKD | SWSD | CKDV(j); ++ ++ dev_dbg(dev, "ssi%d outputs %u Hz\n", ++ rsnd_mod_id(&ssi->mod), rate); ++ ++ return 0; ++ } ++ } ++ } ++ ++ dev_err(dev, "unsupported clock rate\n"); ++ return -EIO; ++} ++ ++static void rsnd_ssi_master_clk_stop(struct rsnd_ssi *ssi) ++{ ++ ssi->rate = 0; ++ ssi->cr_clk = 0; ++ rsnd_adg_ssi_clk_stop(&ssi->mod); ++} ++ ++static void rsnd_ssi_hw_start(struct rsnd_ssi *ssi, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ u32 cr; ++ ++ if (0 == ssi->usrcnt) { ++ clk_enable(ssi->clk); ++ ++ if (rsnd_rdai_is_clk_master(rdai)) { ++ struct snd_pcm_runtime *runtime; ++ ++ runtime = rsnd_io_to_runtime(io); ++ ++ if (rsnd_ssi_clk_from_parent(ssi)) ++ rsnd_ssi_hw_start(ssi->parent, rdai, io); ++ else ++ rsnd_ssi_master_clk_start(ssi, runtime->rate); ++ } ++ } ++ ++ cr = ssi->cr_own | ++ ssi->cr_clk | ++ ssi->cr_etc | ++ EN; ++ ++ rsnd_mod_write(&ssi->mod, SSICR, cr); ++ ++ ssi->usrcnt++; ++ ++ dev_dbg(dev, "ssi%d hw started\n", rsnd_mod_id(&ssi->mod)); ++} ++ ++static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, ++ struct rsnd_dai *rdai) ++{ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(&ssi->mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ u32 cr; ++ ++ if (0 == ssi->usrcnt) /* stop might be called without start */ ++ return; ++ ++ ssi->usrcnt--; ++ ++ if (0 == ssi->usrcnt) { ++ /* ++ * disable all IRQ, ++ * and, wait all data was sent ++ */ ++ cr = ssi->cr_own | ++ ssi->cr_clk; ++ ++ rsnd_mod_write(&ssi->mod, SSICR, cr | EN); ++ rsnd_ssi_status_check(&ssi->mod, DIRQ); ++ ++ /* ++ * disable SSI, ++ * and, wait idle state ++ */ ++ rsnd_mod_write(&ssi->mod, SSICR, cr); /* disabled all */ ++ rsnd_ssi_status_check(&ssi->mod, IIRQ); ++ ++ if (rsnd_rdai_is_clk_master(rdai)) { ++ if (rsnd_ssi_clk_from_parent(ssi)) ++ rsnd_ssi_hw_stop(ssi->parent, rdai); ++ else ++ rsnd_ssi_master_clk_stop(ssi); ++ } ++ ++ clk_disable(ssi->clk); ++ } ++ ++ dev_dbg(dev, "ssi%d hw stopped\n", rsnd_mod_id(&ssi->mod)); ++} ++ ++/* ++ * SSI mod common functions ++ */ ++static int rsnd_ssi_init(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); ++ u32 cr; ++ ++ cr = FORCE; ++ ++ /* ++ * always use 32bit system word for easy clock calculation. ++ * see also rsnd_ssi_master_clk_enable() ++ */ ++ cr |= SWL_32; ++ ++ /* ++ * init clock settings for SSICR ++ */ ++ switch (runtime->sample_bits) { ++ case 16: ++ cr |= DWL_16; ++ break; ++ case 32: ++ cr |= DWL_24; ++ break; ++ default: ++ return -EIO; ++ } ++ ++ if (rdai->bit_clk_inv) ++ cr |= SCKP; ++ if (rdai->frm_clk_inv) ++ cr |= SWSP; ++ if (rdai->data_alignment) ++ cr |= SDTA; ++ if (rdai->sys_delay) ++ cr |= DEL; ++ if (rsnd_dai_is_play(rdai, io)) ++ cr |= TRMD; ++ ++ /* ++ * set ssi parameter ++ */ ++ ssi->rdai = rdai; ++ ssi->io = io; ++ ssi->cr_own = cr; ++ ssi->err = -1; /* ignore 1st error */ ++ ++ rsnd_ssi_mode_set(ssi); ++ ++ dev_dbg(dev, "%s.%d init\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); ++ ++ return 0; ++} ++ ++static int rsnd_ssi_quit(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ ++ dev_dbg(dev, "%s.%d quit\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); ++ ++ if (ssi->err > 0) ++ dev_warn(dev, "ssi under/over flow err = %d\n", ssi->err); ++ ++ ssi->rdai = NULL; ++ ssi->io = NULL; ++ ssi->cr_own = 0; ++ ssi->err = 0; ++ ++ return 0; ++} ++ ++static void rsnd_ssi_record_error(struct rsnd_ssi *ssi, u32 status) ++{ ++ /* under/over flow error */ ++ if (status & (UIRQ | OIRQ)) { ++ ssi->err++; ++ ++ /* clear error status */ ++ rsnd_mod_write(&ssi->mod, SSISR, 0); ++ } ++} ++ ++/* ++ * SSI PIO ++ */ ++static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data) ++{ ++ struct rsnd_ssi *ssi = data; ++ struct rsnd_dai_stream *io = ssi->io; ++ u32 status = rsnd_mod_read(&ssi->mod, SSISR); ++ irqreturn_t ret = IRQ_NONE; ++ ++ if (io && (status & DIRQ)) { ++ struct rsnd_dai *rdai = ssi->rdai; ++ struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); ++ u32 *buf = (u32 *)(runtime->dma_area + ++ rsnd_dai_pointer_offset(io, 0)); ++ ++ rsnd_ssi_record_error(ssi, status); ++ ++ /* ++ * 8/16/32 data can be assesse to TDR/RDR register ++ * directly as 32bit data ++ * see rsnd_ssi_init() ++ */ ++ if (rsnd_dai_is_play(rdai, io)) ++ rsnd_mod_write(&ssi->mod, SSITDR, *buf); ++ else ++ *buf = rsnd_mod_read(&ssi->mod, SSIRDR); ++ ++ rsnd_dai_pointer_update(io, sizeof(*buf)); ++ ++ ret = IRQ_HANDLED; ++ } ++ ++ return ret; ++} ++ ++static int rsnd_ssi_pio_start(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ ++ /* enable PIO IRQ */ ++ ssi->cr_etc = UIEN | OIEN | DIEN; ++ ++ rsnd_ssi_hw_start(ssi, rdai, io); ++ ++ dev_dbg(dev, "%s.%d start\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); ++ ++ return 0; ++} ++ ++static int rsnd_ssi_pio_stop(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); ++ ++ dev_dbg(dev, "%s.%d stop\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); ++ ++ ssi->cr_etc = 0; ++ ++ rsnd_ssi_hw_stop(ssi, rdai); ++ ++ return 0; ++} ++ ++static struct rsnd_mod_ops rsnd_ssi_pio_ops = { ++ .name = "ssi (pio)", ++ .init = rsnd_ssi_init, ++ .quit = rsnd_ssi_quit, ++ .start = rsnd_ssi_pio_start, ++ .stop = rsnd_ssi_pio_stop, ++}; ++ ++/* ++ * Non SSI ++ */ ++static int rsnd_ssi_non(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ ++ dev_dbg(dev, "%s\n", __func__); ++ ++ return 0; ++} ++ ++static struct rsnd_mod_ops rsnd_ssi_non_ops = { ++ .name = "ssi (non)", ++ .init = rsnd_ssi_non, ++ .quit = rsnd_ssi_non, ++ .start = rsnd_ssi_non, ++ .stop = rsnd_ssi_non, ++}; ++ ++/* ++ * ssi mod function ++ */ ++struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) ++{ ++ BUG_ON(id < 0 || id >= rsnd_ssi_nr(priv)); ++ ++ return &(((struct rsnd_ssiu *)(priv->ssiu))->ssi + id)->mod; ++} ++ ++int rsnd_ssi_probe(struct platform_device *pdev, ++ struct rcar_snd_info *info, ++ struct rsnd_priv *priv) ++{ ++ struct rsnd_ssi_platform_info *pinfo; ++ struct device *dev = rsnd_priv_to_dev(priv); ++ struct rsnd_mod_ops *ops; ++ struct clk *clk; ++ struct rsnd_ssiu *ssiu; ++ struct rsnd_ssi *ssi; ++ char name[RSND_SSI_NAME_SIZE]; ++ int i, nr, ret; ++ ++ /* ++ * init SSI ++ */ ++ nr = info->ssi_info_nr; ++ ssiu = devm_kzalloc(dev, sizeof(*ssiu) + (sizeof(*ssi) * nr), ++ GFP_KERNEL); ++ if (!ssiu) { ++ dev_err(dev, "SSI allocate failed\n"); ++ return -ENOMEM; ++ } ++ ++ priv->ssiu = ssiu; ++ ssiu->ssi = (struct rsnd_ssi *)(ssiu + 1); ++ ssiu->ssi_nr = nr; ++ ++ for_each_rsnd_ssi(ssi, priv, i) { ++ pinfo = &info->ssi_info[i]; ++ ++ snprintf(name, RSND_SSI_NAME_SIZE, "ssi.%d", i); ++ ++ clk = clk_get(dev, name); ++ if (IS_ERR(clk)) ++ return PTR_ERR(clk); ++ ++ ssi->info = pinfo; ++ ssi->clk = clk; ++ ++ ops = &rsnd_ssi_non_ops; ++ ++ /* ++ * SSI PIO case ++ */ ++ if (rsnd_ssi_is_pio(ssi)) { ++ ret = devm_request_irq(dev, pinfo->pio_irq, ++ &rsnd_ssi_pio_interrupt, ++ IRQF_SHARED, ++ dev_name(dev), ssi); ++ if (ret) { ++ dev_err(dev, "SSI request interrupt failed\n"); ++ return ret; ++ } ++ ++ ops = &rsnd_ssi_pio_ops; ++ } ++ ++ rsnd_mod_init(priv, &ssi->mod, ops, i); ++ } ++ ++ rsnd_ssi_mode_init(priv, ssiu); ++ ++ dev_dbg(dev, "ssi probed\n"); ++ ++ return 0; ++} ++ ++void rsnd_ssi_remove(struct platform_device *pdev, ++ struct rsnd_priv *priv) ++{ ++ struct rsnd_ssi *ssi; ++ int i; ++ ++ for_each_rsnd_ssi(ssi, priv, i) ++ clk_put(ssi->clk); ++} +-- +1.8.5.rc3 + diff --git a/patches.renesas/0094-ASoC-rcar-fix-return-value-check-in-rsnd_gen1_probe.patch b/patches.renesas/0094-ASoC-rcar-fix-return-value-check-in-rsnd_gen1_probe.patch new file mode 100644 index 00000000000000..975fe513a2a53e --- /dev/null +++ b/patches.renesas/0094-ASoC-rcar-fix-return-value-check-in-rsnd_gen1_probe.patch @@ -0,0 +1,56 @@ +From fa3c1846eb14660b82c1b44745066c6635716135 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun <yongjun_wei@trendmicro.com.cn> +Date: Tue, 30 Jul 2013 07:51:37 +0800 +Subject: ASoC: rcar: fix return value check in rsnd_gen1_probe() + +In case of error, the function devm_ioremap_resource() returns ERR_PTR() +and never returns NULL. The NULL test in the return value check should be +replaced with IS_ERR(), and also remove the dev_err call to avoid redundant +error message. + +Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn> +Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 70263cb474853c116f80713d468f3c17d805921c) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/gen.c | 17 ++++------------- + 1 file changed, 4 insertions(+), 13 deletions(-) + +diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c +index 5e4ae0da4352..61232cd9908f 100644 +--- a/sound/soc/sh/rcar/gen.c ++++ b/sound/soc/sh/rcar/gen.c +@@ -150,25 +150,16 @@ static int rsnd_gen1_probe(struct platform_device *pdev, + sru_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SRU); + adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_ADG); + ssi_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SSI); +- if (!sru_res || +- !adg_res || +- !ssi_res) { +- dev_err(dev, "Not enough SRU/SSI/ADG platform resources.\n"); +- return -ENODEV; +- } +- +- gen->ops = &rsnd_gen1_ops; + + gen->base[RSND_GEN1_SRU] = devm_ioremap_resource(dev, sru_res); + gen->base[RSND_GEN1_ADG] = devm_ioremap_resource(dev, adg_res); + gen->base[RSND_GEN1_SSI] = devm_ioremap_resource(dev, ssi_res); +- if (!gen->base[RSND_GEN1_SRU] || +- !gen->base[RSND_GEN1_ADG] || +- !gen->base[RSND_GEN1_SSI]) { +- dev_err(dev, "SRU/SSI/ADG ioremap failed\n"); ++ if (IS_ERR(gen->base[RSND_GEN1_SRU]) || ++ IS_ERR(gen->base[RSND_GEN1_ADG]) || ++ IS_ERR(gen->base[RSND_GEN1_SSI])) + return -ENODEV; +- } + ++ gen->ops = &rsnd_gen1_ops; + rsnd_gen1_reg_map_init(gen); + + dev_dbg(dev, "Gen1 device probed\n"); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0095-ASoC-rsnd-remove-platform-dai-and-add-dai_id-on-plat.patch b/patches.renesas/0095-ASoC-rsnd-remove-platform-dai-and-add-dai_id-on-plat.patch new file mode 100644 index 00000000000000..e27e973e722865 --- /dev/null +++ b/patches.renesas/0095-ASoC-rsnd-remove-platform-dai-and-add-dai_id-on-plat.patch @@ -0,0 +1,299 @@ +From fd385ea49d8cf5f906210177747267ff88d4bd29 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 28 Jul 2013 18:58:29 -0700 +Subject: ASoC: rsnd: remove platform dai and add dai_id on platform setting + +Current rsnd driver is using struct rsnd_dai_platform_info +so that indicate sound DAI information (playback/capture SSI ID). +But, SSI settings were also required separately. +Thus, platform settings was very un-understandable. +This patch adds dai_id to SSI +settings, and removed rsnd_dai_platform_info. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 4b4dab82340d969521f4f86108441cb597c8595d) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + include/sound/rcar_snd.h | 18 ++++++++------- + sound/soc/sh/rcar/core.c | 60 +++++++++++++++++++++++++++++++++--------------- + sound/soc/sh/rcar/gen.c | 10 ++++---- + sound/soc/sh/rcar/rsnd.h | 3 +++ + sound/soc/sh/rcar/ssi.c | 22 ++++++++++++++++++ + 5 files changed, 82 insertions(+), 31 deletions(-) + +diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h +index 99d8dd029906..33233edd1664 100644 +--- a/include/sound/rcar_snd.h ++++ b/include/sound/rcar_snd.h +@@ -28,15 +28,24 @@ + /* + * flags + * +- * 0xA0000000 ++ * 0xAB000000 + * + * A : clock sharing settings ++ * B : SSI direction + */ + #define RSND_SSI_CLK_PIN_SHARE (1 << 31) + #define RSND_SSI_CLK_FROM_ADG (1 << 30) /* clock parent is master */ + #define RSND_SSI_SYNC (1 << 29) /* SSI34_sync etc */ + ++#define RSND_SSI_PLAY (1 << 24) ++ ++#define RSND_SSI_SET(_dai_id, _pio_irq, _flags) \ ++{ .dai_id = _dai_id, .pio_irq = _pio_irq, .flags = _flags } ++#define RSND_SSI_UNUSED \ ++{ .dai_id = -1, .pio_irq = -1, .flags = 0 } ++ + struct rsnd_ssi_platform_info { ++ int dai_id; + int pio_irq; + u32 flags; + }; +@@ -45,11 +54,6 @@ struct rsnd_scu_platform_info { + u32 flags; + }; + +-struct rsnd_dai_platform_info { +- int ssi_id_playback; +- int ssi_id_capture; +-}; +- + /* + * flags + * +@@ -66,8 +70,6 @@ struct rcar_snd_info { + int ssi_info_nr; + struct rsnd_scu_platform_info *scu_info; + int scu_info_nr; +- struct rsnd_dai_platform_info *dai_info; +- int dai_info_nr; + int (*start)(int id); + int (*stop)(int id); + }; +diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c +index 9a5469d3f352..420d6df9c3d0 100644 +--- a/sound/soc/sh/rcar/core.c ++++ b/sound/soc/sh/rcar/core.c +@@ -219,6 +219,16 @@ int rsnd_dai_disconnect(struct rsnd_mod *mod) + return 0; + } + ++int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai) ++{ ++ int id = rdai - priv->rdai; ++ ++ if ((id < 0) || (id >= rsnd_dai_nr(priv))) ++ return -EINVAL; ++ ++ return id; ++} ++ + struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id) + { + return priv->rdai + id; +@@ -315,9 +325,10 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, + struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai); + struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); + struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); +- struct rsnd_dai_platform_info *info = rsnd_dai_get_platform_info(rdai); +- int ssi_id = rsnd_dai_is_play(rdai, io) ? info->ssi_id_playback : +- info->ssi_id_capture; ++ struct rsnd_mod *mod = rsnd_ssi_mod_get_frm_dai(priv, ++ rsnd_dai_id(priv, rdai), ++ rsnd_dai_is_play(rdai, io)); ++ int ssi_id = rsnd_mod_id(mod); + int ret; + unsigned long flags; + +@@ -439,10 +450,24 @@ static int rsnd_dai_probe(struct platform_device *pdev, + { + struct snd_soc_dai_driver *drv; + struct rsnd_dai *rdai; ++ struct rsnd_mod *pmod, *cmod; + struct device *dev = rsnd_priv_to_dev(priv); +- struct rsnd_dai_platform_info *dai_info; +- int dai_nr = info->dai_info_nr; +- int i, pid, cid; ++ int dai_nr; ++ int i; ++ ++ /* get max dai nr */ ++ for (dai_nr = 0; dai_nr < 32; dai_nr++) { ++ pmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 1); ++ cmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 0); ++ ++ if (!pmod && !cmod) ++ break; ++ } ++ ++ if (!dai_nr) { ++ dev_err(dev, "no dai\n"); ++ return -EIO; ++ } + + drv = devm_kzalloc(dev, sizeof(*drv) * dai_nr, GFP_KERNEL); + rdai = devm_kzalloc(dev, sizeof(*rdai) * dai_nr, GFP_KERNEL); +@@ -452,10 +477,9 @@ static int rsnd_dai_probe(struct platform_device *pdev, + } + + for (i = 0; i < dai_nr; i++) { +- dai_info = &info->dai_info[i]; + +- pid = dai_info->ssi_id_playback; +- cid = dai_info->ssi_id_capture; ++ pmod = rsnd_ssi_mod_get_frm_dai(priv, i, 1); ++ cmod = rsnd_ssi_mod_get_frm_dai(priv, i, 0); + + /* + * init rsnd_dai +@@ -463,8 +487,6 @@ static int rsnd_dai_probe(struct platform_device *pdev, + INIT_LIST_HEAD(&rdai[i].playback.head); + INIT_LIST_HEAD(&rdai[i].capture.head); + +- rdai[i].info = dai_info; +- + snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i); + + /* +@@ -472,20 +494,22 @@ static int rsnd_dai_probe(struct platform_device *pdev, + */ + drv[i].name = rdai[i].name; + drv[i].ops = &rsnd_soc_dai_ops; +- if (pid >= 0) { ++ if (pmod) { + drv[i].playback.rates = RSND_RATES; + drv[i].playback.formats = RSND_FMTS; + drv[i].playback.channels_min = 2; + drv[i].playback.channels_max = 2; + } +- if (cid >= 0) { ++ if (cmod) { + drv[i].capture.rates = RSND_RATES; + drv[i].capture.formats = RSND_FMTS; + drv[i].capture.channels_min = 2; + drv[i].capture.channels_max = 2; + } + +- dev_dbg(dev, "%s (%d, %d) probed", rdai[i].name, pid, cid); ++ dev_dbg(dev, "%s (%s/%s)\n", rdai[i].name, ++ pmod ? "play" : " -- ", ++ cmod ? "capture" : " -- "); + } + + priv->dai_nr = dai_nr; +@@ -627,10 +651,6 @@ static int rsnd_probe(struct platform_device *pdev) + if (ret < 0) + return ret; + +- ret = rsnd_dai_probe(pdev, info, priv); +- if (ret < 0) +- return ret; +- + ret = rsnd_scu_probe(pdev, info, priv); + if (ret < 0) + return ret; +@@ -643,6 +663,10 @@ static int rsnd_probe(struct platform_device *pdev) + if (ret < 0) + return ret; + ++ ret = rsnd_dai_probe(pdev, info, priv); ++ if (ret < 0) ++ return ret; ++ + /* + * asoc register + */ +diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c +index 61232cd9908f..460c57eef267 100644 +--- a/sound/soc/sh/rcar/gen.c ++++ b/sound/soc/sh/rcar/gen.c +@@ -49,7 +49,6 @@ static int rsnd_gen1_path_init(struct rsnd_priv *priv, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) + { +- struct rsnd_dai_platform_info *info = rsnd_dai_get_platform_info(rdai); + struct rsnd_mod *mod; + int ret; + int id; +@@ -67,10 +66,11 @@ static int rsnd_gen1_path_init(struct rsnd_priv *priv, + * Then, SSI id = SCU id here + */ + +- if (rsnd_dai_is_play(rdai, io)) +- id = info->ssi_id_playback; +- else +- id = info->ssi_id_capture; ++ /* get SSI's ID */ ++ mod = rsnd_ssi_mod_get_frm_dai(priv, ++ rsnd_dai_id(priv, rdai), ++ rsnd_dai_is_play(rdai, io)); ++ id = rsnd_mod_id(mod); + + /* SSI */ + mod = rsnd_ssi_mod_get(priv, id); +diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h +index 0e7727cc41db..9243e387104c 100644 +--- a/sound/soc/sh/rcar/rsnd.h ++++ b/sound/soc/sh/rcar/rsnd.h +@@ -157,6 +157,7 @@ int rsnd_dai_disconnect(struct rsnd_mod *mod); + int rsnd_dai_connect(struct rsnd_dai *rdai, struct rsnd_mod *mod, + struct rsnd_dai_stream *io); + int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io); ++int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai); + #define rsnd_dai_get_platform_info(rdai) ((rdai)->info) + #define rsnd_io_to_runtime(io) ((io)->substream->runtime) + +@@ -254,5 +255,7 @@ int rsnd_ssi_probe(struct platform_device *pdev, + void rsnd_ssi_remove(struct platform_device *pdev, + struct rsnd_priv *priv); + struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); ++struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, ++ int dai_id, int is_play); + + #endif +diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c +index 061ac7e88309..c48a6c7cd08e 100644 +--- a/sound/soc/sh/rcar/ssi.c ++++ b/sound/soc/sh/rcar/ssi.c +@@ -87,6 +87,7 @@ struct rsnd_ssiu { + #define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent) + #define rsnd_rdai_is_clk_master(rdai) ((rdai)->clk_master) + #define rsnd_ssi_mode_flags(p) ((p)->info->flags) ++#define rsnd_ssi_dai_id(ssi) ((ssi)->info->dai_id) + #define rsnd_ssi_to_ssiu(ssi)\ + (((struct rsnd_ssiu *)((ssi) - rsnd_mod_id(&(ssi)->mod))) - 1) + +@@ -502,6 +503,27 @@ static struct rsnd_mod_ops rsnd_ssi_non_ops = { + /* + * ssi mod function + */ ++struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, ++ int dai_id, int is_play) ++{ ++ struct rsnd_ssi *ssi; ++ int i, has_play; ++ ++ is_play = !!is_play; ++ ++ for_each_rsnd_ssi(ssi, priv, i) { ++ if (rsnd_ssi_dai_id(ssi) != dai_id) ++ continue; ++ ++ has_play = !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY); ++ ++ if (is_play == has_play) ++ return &ssi->mod; ++ } ++ ++ return NULL; ++} ++ + struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) + { + BUG_ON(id < 0 || id >= rsnd_ssi_nr(priv)); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0096-ASoC-rsnd-add-common-DMAEngine-method.patch b/patches.renesas/0096-ASoC-rsnd-add-common-DMAEngine-method.patch new file mode 100644 index 00000000000000..26dc08400dc749 --- /dev/null +++ b/patches.renesas/0096-ASoC-rsnd-add-common-DMAEngine-method.patch @@ -0,0 +1,230 @@ +From 8580bc44656280e0b71c0afb33279c977880d9bc Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 28 Jul 2013 18:58:50 -0700 +Subject: ASoC: rsnd: add common DMAEngine method + +R-Car Sound driver will support DMA transfer in the future, +then, SSI/SRU/SRC will use it. +Current R-Car can't use soc-dmaengine-pcm.c since its DMAEngine +doesn't support dmaengine_prep_dma_cyclic(), +and SSI needs double plane transfer (which needs special submit) on DMAC. +This patch adds common DMAEngine method for it + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 0a4d94c07ce782e645a8c0484d52221758b4c398) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/core.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++ + sound/soc/sh/rcar/rsnd.h | 32 ++++++++++++ + 2 files changed, 164 insertions(+) + +diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c +index 420d6df9c3d0..a35706028514 100644 +--- a/sound/soc/sh/rcar/core.c ++++ b/sound/soc/sh/rcar/core.c +@@ -174,6 +174,138 @@ void rsnd_mod_init(struct rsnd_priv *priv, + } + + /* ++ * rsnd_dma functions ++ */ ++static void rsnd_dma_continue(struct rsnd_dma *dma) ++{ ++ /* push next A or B plane */ ++ dma->submit_loop = 1; ++ schedule_work(&dma->work); ++} ++ ++void rsnd_dma_start(struct rsnd_dma *dma) ++{ ++ /* push both A and B plane*/ ++ dma->submit_loop = 2; ++ schedule_work(&dma->work); ++} ++ ++void rsnd_dma_stop(struct rsnd_dma *dma) ++{ ++ dma->submit_loop = 0; ++ cancel_work_sync(&dma->work); ++ dmaengine_terminate_all(dma->chan); ++} ++ ++static void rsnd_dma_complete(void *data) ++{ ++ struct rsnd_dma *dma = (struct rsnd_dma *)data; ++ struct rsnd_priv *priv = dma->priv; ++ unsigned long flags; ++ ++ rsnd_lock(priv, flags); ++ ++ dma->complete(dma); ++ ++ if (dma->submit_loop) ++ rsnd_dma_continue(dma); ++ ++ rsnd_unlock(priv, flags); ++} ++ ++static void rsnd_dma_do_work(struct work_struct *work) ++{ ++ struct rsnd_dma *dma = container_of(work, struct rsnd_dma, work); ++ struct rsnd_priv *priv = dma->priv; ++ struct device *dev = rsnd_priv_to_dev(priv); ++ struct dma_async_tx_descriptor *desc; ++ dma_addr_t buf; ++ size_t len; ++ int i; ++ ++ for (i = 0; i < dma->submit_loop; i++) { ++ ++ if (dma->inquiry(dma, &buf, &len) < 0) ++ return; ++ ++ desc = dmaengine_prep_slave_single( ++ dma->chan, buf, len, dma->dir, ++ DMA_PREP_INTERRUPT | DMA_CTRL_ACK); ++ if (!desc) { ++ dev_err(dev, "dmaengine_prep_slave_sg() fail\n"); ++ return; ++ } ++ ++ desc->callback = rsnd_dma_complete; ++ desc->callback_param = dma; ++ ++ if (dmaengine_submit(desc) < 0) { ++ dev_err(dev, "dmaengine_submit() fail\n"); ++ return; ++ } ++ ++ } ++ ++ dma_async_issue_pending(dma->chan); ++} ++ ++int rsnd_dma_available(struct rsnd_dma *dma) ++{ ++ return !!dma->chan; ++} ++ ++static bool rsnd_dma_filter(struct dma_chan *chan, void *param) ++{ ++ chan->private = param; ++ ++ return true; ++} ++ ++int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, ++ int is_play, int id, ++ int (*inquiry)(struct rsnd_dma *dma, ++ dma_addr_t *buf, int *len), ++ int (*complete)(struct rsnd_dma *dma)) ++{ ++ struct device *dev = rsnd_priv_to_dev(priv); ++ dma_cap_mask_t mask; ++ ++ if (dma->chan) { ++ dev_err(dev, "it already has dma channel\n"); ++ return -EIO; ++ } ++ ++ dma_cap_zero(mask); ++ dma_cap_set(DMA_SLAVE, mask); ++ ++ dma->slave.shdma_slave.slave_id = id; ++ ++ dma->chan = dma_request_channel(mask, rsnd_dma_filter, ++ &dma->slave.shdma_slave); ++ if (!dma->chan) { ++ dev_err(dev, "can't get dma channel\n"); ++ return -EIO; ++ } ++ ++ dma->dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; ++ dma->priv = priv; ++ dma->inquiry = inquiry; ++ dma->complete = complete; ++ INIT_WORK(&dma->work, rsnd_dma_do_work); ++ ++ return 0; ++} ++ ++void rsnd_dma_quit(struct rsnd_priv *priv, ++ struct rsnd_dma *dma) ++{ ++ if (dma->chan) ++ dma_release_channel(dma->chan); ++ ++ dma->chan = NULL; ++} ++ ++/* + * rsnd_dai functions + */ + #define rsnd_dai_call(rdai, io, fn) \ +diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h +index 9243e387104c..15dccd598960 100644 +--- a/sound/soc/sh/rcar/rsnd.h ++++ b/sound/soc/sh/rcar/rsnd.h +@@ -13,9 +13,12 @@ + + #include <linux/clk.h> + #include <linux/device.h> ++#include <linux/dma-mapping.h> + #include <linux/io.h> + #include <linux/list.h> + #include <linux/module.h> ++#include <linux/sh_dma.h> ++#include <linux/workqueue.h> + #include <sound/rcar_snd.h> + #include <sound/soc.h> + #include <sound/pcm_params.h> +@@ -79,6 +82,32 @@ void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, + u32 mask, u32 data); + + /* ++ * R-Car DMA ++ */ ++struct rsnd_dma { ++ struct rsnd_priv *priv; ++ struct sh_dmae_slave slave; ++ struct work_struct work; ++ struct dma_chan *chan; ++ enum dma_data_direction dir; ++ int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len); ++ int (*complete)(struct rsnd_dma *dma); ++ ++ int submit_loop; ++}; ++ ++void rsnd_dma_start(struct rsnd_dma *dma); ++void rsnd_dma_stop(struct rsnd_dma *dma); ++int rsnd_dma_available(struct rsnd_dma *dma); ++int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, ++ int is_play, int id, ++ int (*inquiry)(struct rsnd_dma *dma, dma_addr_t *buf, int *len), ++ int (*complete)(struct rsnd_dma *dma)); ++void rsnd_dma_quit(struct rsnd_priv *priv, ++ struct rsnd_dma *dma); ++ ++ ++/* + * R-Car sound mod + */ + +@@ -103,9 +132,12 @@ struct rsnd_mod { + struct rsnd_priv *priv; + struct rsnd_mod_ops *ops; + struct list_head list; /* connect to rsnd_dai playback/capture */ ++ struct rsnd_dma dma; + }; + + #define rsnd_mod_to_priv(mod) ((mod)->priv) ++#define rsnd_mod_to_dma(mod) (&(mod)->dma) ++#define rsnd_dma_to_mod(_dma) container_of((_dma), struct rsnd_mod, dma) + #define rsnd_mod_id(mod) ((mod)->id) + #define for_each_rsnd_mod(pos, n, io) \ + list_for_each_entry_safe(pos, n, &(io)->head, list) +-- +1.8.5.rc3 + diff --git a/patches.renesas/0097-ASoC-rsnd-SSI-supports-DMA-transfer.patch b/patches.renesas/0097-ASoC-rsnd-SSI-supports-DMA-transfer.patch new file mode 100644 index 00000000000000..d3a98762a7fe75 --- /dev/null +++ b/patches.renesas/0097-ASoC-rsnd-SSI-supports-DMA-transfer.patch @@ -0,0 +1,208 @@ +From 72a3557f23b87b9bd6bcc3d03199c65ab0764ae3 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 28 Jul 2013 18:59:02 -0700 +Subject: ASoC: rsnd: SSI supports DMA transfer + +This patch adds DMAEngine transfer on SSI. +But, it transfers sound data from memory to SSI directly +without using HPBIF at this time. +It will be updated soon + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 849fc82a6f4f32b4c8c502bb7c4a68df51170232) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + include/sound/rcar_snd.h | 7 +-- + sound/soc/sh/rcar/ssi.c | 110 +++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 111 insertions(+), 6 deletions(-) + +diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h +index 33233edd1664..a72687dda0cd 100644 +--- a/include/sound/rcar_snd.h ++++ b/include/sound/rcar_snd.h +@@ -39,13 +39,14 @@ + + #define RSND_SSI_PLAY (1 << 24) + +-#define RSND_SSI_SET(_dai_id, _pio_irq, _flags) \ +-{ .dai_id = _dai_id, .pio_irq = _pio_irq, .flags = _flags } ++#define RSND_SSI_SET(_dai_id, _dma_id, _pio_irq, _flags) \ ++{ .dai_id = _dai_id, .dma_id = _dma_id, .pio_irq = _pio_irq, .flags = _flags } + #define RSND_SSI_UNUSED \ +-{ .dai_id = -1, .pio_irq = -1, .flags = 0 } ++{ .dai_id = -1, .dma_id = -1, .pio_irq = -1, .flags = 0 } + + struct rsnd_ssi_platform_info { + int dai_id; ++ int dma_id; + int pio_irq; + u32 flags; + }; +diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c +index c48a6c7cd08e..2079ccf5f322 100644 +--- a/sound/soc/sh/rcar/ssi.c ++++ b/sound/soc/sh/rcar/ssi.c +@@ -19,6 +19,7 @@ + * SSICR + */ + #define FORCE (1 << 31) /* Fixed */ ++#define DMEN (1 << 28) /* DMA Enable */ + #define UIEN (1 << 27) /* Underflow Interrupt Enable */ + #define OIEN (1 << 26) /* Overflow Interrupt Enable */ + #define IIEN (1 << 25) /* Idle Mode Interrupt Enable */ +@@ -51,6 +52,11 @@ + #define IIRQ (1 << 25) /* Idle Mode Interrupt Status */ + #define DIRQ (1 << 24) /* Data Interrupt Status Flag */ + ++/* ++ * SSIWSR ++ */ ++#define CONT (1 << 8) /* WS Continue Function */ ++ + struct rsnd_ssi { + struct clk *clk; + struct rsnd_ssi_platform_info *info; /* rcar_snd.h */ +@@ -63,6 +69,7 @@ struct rsnd_ssi { + u32 cr_clk; + u32 cr_etc; + int err; ++ int dma_offset; + unsigned int usrcnt; + unsigned int rate; + }; +@@ -83,7 +90,10 @@ struct rsnd_ssiu { + + #define rsnd_ssi_nr(priv) (((struct rsnd_ssiu *)((priv)->ssiu))->ssi_nr) + #define rsnd_mod_to_ssi(_mod) container_of((_mod), struct rsnd_ssi, mod) +-#define rsnd_ssi_is_pio(ssi) ((ssi)->info->pio_irq > 0) ++#define rsnd_dma_to_ssi(dma) rsnd_mod_to_ssi(rsnd_dma_to_mod(dma)) ++#define rsnd_ssi_pio_available(ssi) ((ssi)->info->pio_irq > 0) ++#define rsnd_ssi_dma_available(ssi) \ ++ rsnd_dma_available(rsnd_mod_to_dma(&(ssi)->mod)) + #define rsnd_ssi_clk_from_parent(ssi) ((ssi)->parent) + #define rsnd_rdai_is_clk_master(rdai) ((rdai)->clk_master) + #define rsnd_ssi_mode_flags(p) ((p)->info->flags) +@@ -477,6 +487,79 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = { + .stop = rsnd_ssi_pio_stop, + }; + ++static int rsnd_ssi_dma_inquiry(struct rsnd_dma *dma, dma_addr_t *buf, int *len) ++{ ++ struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma); ++ struct rsnd_dai_stream *io = ssi->io; ++ struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); ++ ++ *len = io->byte_per_period; ++ *buf = runtime->dma_addr + ++ rsnd_dai_pointer_offset(io, ssi->dma_offset + *len); ++ ssi->dma_offset = *len; /* it cares A/B plane */ ++ ++ return 0; ++} ++ ++static int rsnd_ssi_dma_complete(struct rsnd_dma *dma) ++{ ++ struct rsnd_ssi *ssi = rsnd_dma_to_ssi(dma); ++ struct rsnd_dai_stream *io = ssi->io; ++ u32 status = rsnd_mod_read(&ssi->mod, SSISR); ++ ++ rsnd_ssi_record_error(ssi, status); ++ ++ rsnd_dai_pointer_update(ssi->io, io->byte_per_period); ++ ++ return 0; ++} ++ ++static int rsnd_ssi_dma_start(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); ++ struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); ++ ++ /* enable DMA transfer */ ++ ssi->cr_etc = DMEN; ++ ssi->dma_offset = 0; ++ ++ rsnd_dma_start(dma); ++ ++ rsnd_ssi_hw_start(ssi, ssi->rdai, io); ++ ++ /* enable WS continue */ ++ if (rsnd_rdai_is_clk_master(rdai)) ++ rsnd_mod_write(&ssi->mod, SSIWSR, CONT); ++ ++ return 0; ++} ++ ++static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); ++ struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); ++ ++ ssi->cr_etc = 0; ++ ++ rsnd_ssi_hw_stop(ssi, rdai); ++ ++ rsnd_dma_stop(dma); ++ ++ return 0; ++} ++ ++static struct rsnd_mod_ops rsnd_ssi_dma_ops = { ++ .name = "ssi (dma)", ++ .init = rsnd_ssi_init, ++ .quit = rsnd_ssi_quit, ++ .start = rsnd_ssi_dma_start, ++ .stop = rsnd_ssi_dma_stop, ++}; ++ + /* + * Non SSI + */ +@@ -574,9 +657,26 @@ int rsnd_ssi_probe(struct platform_device *pdev, + ops = &rsnd_ssi_non_ops; + + /* ++ * SSI DMA case ++ */ ++ if (pinfo->dma_id > 0) { ++ ret = rsnd_dma_init( ++ priv, rsnd_mod_to_dma(&ssi->mod), ++ (rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY), ++ pinfo->dma_id, ++ rsnd_ssi_dma_inquiry, ++ rsnd_ssi_dma_complete); ++ if (ret < 0) ++ dev_info(dev, "SSI DMA failed. try PIO transter\n"); ++ else ++ ops = &rsnd_ssi_dma_ops; ++ } ++ ++ /* + * SSI PIO case + */ +- if (rsnd_ssi_is_pio(ssi)) { ++ if (!rsnd_ssi_dma_available(ssi) && ++ rsnd_ssi_pio_available(ssi)) { + ret = devm_request_irq(dev, pinfo->pio_irq, + &rsnd_ssi_pio_interrupt, + IRQF_SHARED, +@@ -605,6 +705,10 @@ void rsnd_ssi_remove(struct platform_device *pdev, + struct rsnd_ssi *ssi; + int i; + +- for_each_rsnd_ssi(ssi, priv, i) ++ for_each_rsnd_ssi(ssi, priv, i) { + clk_put(ssi->clk); ++ if (rsnd_ssi_dma_available(ssi)) ++ rsnd_dma_quit(priv, rsnd_mod_to_dma(&ssi->mod)); ++ } ++ + } +-- +1.8.5.rc3 + diff --git a/patches.renesas/0098-ASoC-rsnd-SSI-supports-DMA-transfer-via-BUSIF.patch b/patches.renesas/0098-ASoC-rsnd-SSI-supports-DMA-transfer-via-BUSIF.patch new file mode 100644 index 00000000000000..58efa6c35c1ab5 --- /dev/null +++ b/patches.renesas/0098-ASoC-rsnd-SSI-supports-DMA-transfer-via-BUSIF.patch @@ -0,0 +1,346 @@ +From a1616a784d77473c2049e5528e9c76efa3c84b0e Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 28 Jul 2013 18:59:12 -0700 +Subject: ASoC: rsnd: SSI supports DMA transfer via BUSIF + +This patch adds BUSIF support for R-Car sound DMAEngine transfer. +The sound data will be transferred via FIFO which can cover blank time +which will happen when DMA channel is switching. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 374a528111fa07878090bd9694a3e153814de39c) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + include/sound/rcar_snd.h | 6 ++ + sound/soc/sh/rcar/gen.c | 10 ++- + sound/soc/sh/rcar/rsnd.h | 9 +++ + sound/soc/sh/rcar/scu.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++- + sound/soc/sh/rcar/ssi.c | 18 +++++- + 5 files changed, 190 insertions(+), 7 deletions(-) + +diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h +index a72687dda0cd..d35412ae03b3 100644 +--- a/include/sound/rcar_snd.h ++++ b/include/sound/rcar_snd.h +@@ -36,6 +36,7 @@ + #define RSND_SSI_CLK_PIN_SHARE (1 << 31) + #define RSND_SSI_CLK_FROM_ADG (1 << 30) /* clock parent is master */ + #define RSND_SSI_SYNC (1 << 29) /* SSI34_sync etc */ ++#define RSND_SSI_DEPENDENT (1 << 28) /* SSI needs SRU/SCU */ + + #define RSND_SSI_PLAY (1 << 24) + +@@ -51,6 +52,11 @@ struct rsnd_ssi_platform_info { + u32 flags; + }; + ++/* ++ * flags ++ */ ++#define RSND_SCU_USB_HPBIF (1 << 31) /* it needs RSND_SSI_DEPENDENT */ ++ + struct rsnd_scu_platform_info { + u32 flags; + }; +diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c +index 460c57eef267..babb203b43b7 100644 +--- a/sound/soc/sh/rcar/gen.c ++++ b/sound/soc/sh/rcar/gen.c +@@ -34,9 +34,6 @@ struct rsnd_gen { + + #define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) + +-#define rsnd_is_gen1(s) ((s)->info->flags & RSND_GEN1) +-#define rsnd_is_gen2(s) ((s)->info->flags & RSND_GEN2) +- + /* + * Gen2 + * will be filled in the future +@@ -115,8 +112,15 @@ static struct rsnd_gen_ops rsnd_gen1_ops = { + + static void rsnd_gen1_reg_map_init(struct rsnd_gen *gen) + { ++ RSND_GEN1_REG_MAP(gen, SRU, SRC_ROUTE_SEL, 0x0, 0x00); ++ RSND_GEN1_REG_MAP(gen, SRU, SRC_TMG_SEL0, 0x0, 0x08); ++ RSND_GEN1_REG_MAP(gen, SRU, SRC_TMG_SEL1, 0x0, 0x0c); ++ RSND_GEN1_REG_MAP(gen, SRU, SRC_TMG_SEL2, 0x0, 0x10); ++ RSND_GEN1_REG_MAP(gen, SRU, SRC_CTRL, 0x0, 0xc0); + RSND_GEN1_REG_MAP(gen, SRU, SSI_MODE0, 0x0, 0xD0); + RSND_GEN1_REG_MAP(gen, SRU, SSI_MODE1, 0x0, 0xD4); ++ RSND_GEN1_REG_MAP(gen, SRU, BUSIF_MODE, 0x4, 0x20); ++ RSND_GEN1_REG_MAP(gen, SRU, BUSIF_ADINR, 0x40, 0x214); + + RSND_GEN1_REG_MAP(gen, ADG, BRRA, 0x0, 0x00); + RSND_GEN1_REG_MAP(gen, ADG, BRRB, 0x0, 0x04); +diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h +index 15dccd598960..9cc6986a8cfb 100644 +--- a/sound/soc/sh/rcar/rsnd.h ++++ b/sound/soc/sh/rcar/rsnd.h +@@ -32,8 +32,15 @@ + */ + enum rsnd_reg { + /* SRU/SCU */ ++ RSND_REG_SRC_ROUTE_SEL, ++ RSND_REG_SRC_TMG_SEL0, ++ RSND_REG_SRC_TMG_SEL1, ++ RSND_REG_SRC_TMG_SEL2, ++ RSND_REG_SRC_CTRL, + RSND_REG_SSI_MODE0, + RSND_REG_SSI_MODE1, ++ RSND_REG_BUSIF_MODE, ++ RSND_REG_BUSIF_ADINR, + + /* ADG */ + RSND_REG_BRRA, +@@ -213,6 +220,8 @@ int rsnd_gen_path_exit(struct rsnd_priv *priv, + void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, + struct rsnd_mod *mod, + enum rsnd_reg reg); ++#define rsnd_is_gen1(s) ((s)->info->flags & RSND_GEN1) ++#define rsnd_is_gen2(s) ((s)->info->flags & RSND_GEN2) + + /* + * R-Car ADG +diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c +index c12e65f240a1..29837e326bc5 100644 +--- a/sound/soc/sh/rcar/scu.c ++++ b/sound/soc/sh/rcar/scu.c +@@ -15,6 +15,18 @@ struct rsnd_scu { + struct rsnd_mod mod; + }; + ++#define rsnd_scu_mode_flags(p) ((p)->info->flags) ++ ++/* ++ * ADINR ++ */ ++#define OTBL_24 (0 << 16) ++#define OTBL_22 (2 << 16) ++#define OTBL_20 (4 << 16) ++#define OTBL_18 (6 << 16) ++#define OTBL_16 (8 << 16) ++ ++ + #define rsnd_mod_to_scu(_mod) \ + container_of((_mod), struct rsnd_scu, mod) + +@@ -24,6 +36,116 @@ struct rsnd_scu { + ((pos) = (struct rsnd_scu *)(priv)->scu + i); \ + i++) + ++static int rsnd_scu_set_route(struct rsnd_priv *priv, ++ struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct scu_route_config { ++ u32 mask; ++ int shift; ++ } routes[] = { ++ { 0xF, 0, }, /* 0 */ ++ { 0xF, 4, }, /* 1 */ ++ { 0xF, 8, }, /* 2 */ ++ { 0x7, 12, }, /* 3 */ ++ { 0x7, 16, }, /* 4 */ ++ { 0x7, 20, }, /* 5 */ ++ { 0x7, 24, }, /* 6 */ ++ { 0x3, 28, }, /* 7 */ ++ { 0x3, 30, }, /* 8 */ ++ }; ++ ++ u32 mask; ++ u32 val; ++ int shift; ++ int id; ++ ++ /* ++ * Gen1 only ++ */ ++ if (!rsnd_is_gen1(priv)) ++ return 0; ++ ++ id = rsnd_mod_id(mod); ++ if (id < 0 || id > ARRAY_SIZE(routes)) ++ return -EIO; ++ ++ /* ++ * SRC_ROUTE_SELECT ++ */ ++ val = rsnd_dai_is_play(rdai, io) ? 0x1 : 0x2; ++ val = val << routes[id].shift; ++ mask = routes[id].mask << routes[id].shift; ++ ++ rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val); ++ ++ /* ++ * SRC_TIMING_SELECT ++ */ ++ shift = (id % 4) * 8; ++ mask = 0x1F << shift; ++ if (8 == id) /* SRU8 is very special */ ++ val = id << shift; ++ else ++ val = (id + 1) << shift; ++ ++ switch (id / 4) { ++ case 0: ++ rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val); ++ break; ++ case 1: ++ rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val); ++ break; ++ case 2: ++ rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val); ++ break; ++ } ++ ++ return 0; ++} ++ ++static int rsnd_scu_set_mode(struct rsnd_priv *priv, ++ struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ int id = rsnd_mod_id(mod); ++ u32 val; ++ ++ if (rsnd_is_gen1(priv)) { ++ val = (1 << id); ++ rsnd_mod_bset(mod, SRC_CTRL, val, val); ++ } ++ ++ return 0; ++} ++ ++static int rsnd_scu_set_hpbif(struct rsnd_priv *priv, ++ struct rsnd_mod *mod, ++ struct rsnd_dai *rdai, ++ struct rsnd_dai_stream *io) ++{ ++ struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); ++ u32 adinr = runtime->channels; ++ ++ switch (runtime->sample_bits) { ++ case 16: ++ adinr |= OTBL_16; ++ break; ++ case 32: ++ adinr |= OTBL_24; ++ break; ++ default: ++ return -EIO; ++ } ++ ++ rsnd_mod_write(mod, BUSIF_MODE, 1); ++ rsnd_mod_write(mod, BUSIF_ADINR, adinr); ++ ++ return 0; ++} ++ + static int rsnd_scu_init(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) +@@ -53,9 +175,36 @@ static int rsnd_scu_start(struct rsnd_mod *mod, + struct rsnd_dai_stream *io) + { + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ struct rsnd_scu *scu = rsnd_mod_to_scu(mod); + struct device *dev = rsnd_priv_to_dev(priv); ++ u32 flags = rsnd_scu_mode_flags(scu); ++ int ret; ++ ++ /* ++ * SCU will be used if it has RSND_SCU_USB_HPBIF flags ++ */ ++ if (!(flags & RSND_SCU_USB_HPBIF)) { ++ /* it use PIO transter */ ++ dev_dbg(dev, "%s%d is not used\n", ++ rsnd_mod_name(mod), rsnd_mod_id(mod)); ++ ++ return 0; ++ } ++ ++ /* it use DMA transter */ ++ ret = rsnd_scu_set_route(priv, mod, rdai, io); ++ if (ret < 0) ++ return ret; ++ ++ ret = rsnd_scu_set_mode(priv, mod, rdai, io); ++ if (ret < 0) ++ return ret; + +- dev_dbg(dev, "%s.%d start\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); ++ ret = rsnd_scu_set_hpbif(priv, mod, rdai, io); ++ if (ret < 0) ++ return ret; ++ ++ dev_dbg(dev, "%s%d start\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); + + return 0; + } +@@ -112,8 +261,9 @@ int rsnd_scu_probe(struct platform_device *pdev, + rsnd_mod_init(priv, &scu->mod, + &rsnd_scu_ops, i); + scu->info = &info->scu_info[i]; +- } + ++ dev_dbg(dev, "SCU%d probed\n", i); ++ } + dev_dbg(dev, "scu probed\n"); + + return 0; +diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c +index 2079ccf5f322..fae26d3f79d2 100644 +--- a/sound/soc/sh/rcar/ssi.c ++++ b/sound/soc/sh/rcar/ssi.c +@@ -104,6 +104,7 @@ struct rsnd_ssiu { + static void rsnd_ssi_mode_init(struct rsnd_priv *priv, + struct rsnd_ssiu *ssiu) + { ++ struct device *dev = rsnd_priv_to_dev(priv); + struct rsnd_ssi *ssi; + u32 flags; + u32 val; +@@ -113,8 +114,17 @@ static void rsnd_ssi_mode_init(struct rsnd_priv *priv, + * SSI_MODE0 + */ + ssiu->ssi_mode0 = 0; +- for_each_rsnd_ssi(ssi, priv, i) +- ssiu->ssi_mode0 |= (1 << i); ++ for_each_rsnd_ssi(ssi, priv, i) { ++ flags = rsnd_ssi_mode_flags(ssi); ++ ++ /* see also BUSIF_MODE */ ++ if (!(flags & RSND_SSI_DEPENDENT)) { ++ ssiu->ssi_mode0 |= (1 << i); ++ dev_dbg(dev, "SSI%d uses INDEPENDENT mode\n", i); ++ } else { ++ dev_dbg(dev, "SSI%d uses DEPENDENT mode\n", i); ++ } ++ } + + /* + * SSI_MODE1 +@@ -670,6 +680,8 @@ int rsnd_ssi_probe(struct platform_device *pdev, + dev_info(dev, "SSI DMA failed. try PIO transter\n"); + else + ops = &rsnd_ssi_dma_ops; ++ ++ dev_dbg(dev, "SSI%d use DMA transfer\n", i); + } + + /* +@@ -687,6 +699,8 @@ int rsnd_ssi_probe(struct platform_device *pdev, + } + + ops = &rsnd_ssi_pio_ops; ++ ++ dev_dbg(dev, "SSI%d use PIO transfer\n", i); + } + + rsnd_mod_init(priv, &ssi->mod, ops, i); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0099-ASoC-rsnd-gen-rsnd_gen_ops-cares-.probe-and-.remove.patch b/patches.renesas/0099-ASoC-rsnd-gen-rsnd_gen_ops-cares-.probe-and-.remove.patch new file mode 100644 index 00000000000000..dabcd933e1f82a --- /dev/null +++ b/patches.renesas/0099-ASoC-rsnd-gen-rsnd_gen_ops-cares-.probe-and-.remove.patch @@ -0,0 +1,110 @@ +From 18388b5d4f103456263229fdc2e4525ac9e5056e Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 1 Sep 2013 20:31:16 -0700 +Subject: ASoC: rsnd: gen: rsnd_gen_ops cares .probe and .remove + +Current rsnd_gen_ops didn't care about .probe and .remove +functions, but it was not good sense. +This patch tidyup it + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 072188b61c9b7aedaa15c46226b537345644beee) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/gen.c | 41 ++++++++++++++++++++++++----------------- + 1 file changed, 24 insertions(+), 17 deletions(-) + +diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c +index babb203b43b7..331fc558d796 100644 +--- a/sound/soc/sh/rcar/gen.c ++++ b/sound/soc/sh/rcar/gen.c +@@ -11,6 +11,11 @@ + #include "rsnd.h" + + struct rsnd_gen_ops { ++ int (*probe)(struct platform_device *pdev, ++ struct rcar_snd_info *info, ++ struct rsnd_priv *priv); ++ void (*remove)(struct platform_device *pdev, ++ struct rsnd_priv *priv); + int (*path_init)(struct rsnd_priv *priv, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io); +@@ -98,11 +103,6 @@ static int rsnd_gen1_path_exit(struct rsnd_priv *priv, + return ret; + } + +-static struct rsnd_gen_ops rsnd_gen1_ops = { +- .path_init = rsnd_gen1_path_init, +- .path_exit = rsnd_gen1_path_exit, +-}; +- + #define RSND_GEN1_REG_MAP(g, s, i, oi, oa) \ + do { \ + (g)->reg_map[RSND_REG_##i].index = RSND_GEN1_##s; \ +@@ -163,7 +163,6 @@ static int rsnd_gen1_probe(struct platform_device *pdev, + IS_ERR(gen->base[RSND_GEN1_SSI])) + return -ENODEV; + +- gen->ops = &rsnd_gen1_ops; + rsnd_gen1_reg_map_init(gen); + + dev_dbg(dev, "Gen1 device probed\n"); +@@ -183,6 +182,13 @@ static void rsnd_gen1_remove(struct platform_device *pdev, + { + } + ++static struct rsnd_gen_ops rsnd_gen1_ops = { ++ .probe = rsnd_gen1_probe, ++ .remove = rsnd_gen1_remove, ++ .path_init = rsnd_gen1_path_init, ++ .path_exit = rsnd_gen1_path_exit, ++}; ++ + /* + * Gen + */ +@@ -251,6 +257,14 @@ int rsnd_gen_probe(struct platform_device *pdev, + return -ENOMEM; + } + ++ if (rsnd_is_gen1(priv)) ++ gen->ops = &rsnd_gen1_ops; ++ ++ if (!gen->ops) { ++ dev_err(dev, "unknown generation R-Car sound device\n"); ++ return -ENODEV; ++ } ++ + priv->gen = gen; + + /* +@@ -261,20 +275,13 @@ int rsnd_gen_probe(struct platform_device *pdev, + for (i = 0; i < RSND_REG_MAX; i++) + gen->reg_map[i].index = -1; + +- /* +- * init each module +- */ +- if (rsnd_is_gen1(priv)) +- return rsnd_gen1_probe(pdev, info, priv); +- +- dev_err(dev, "unknown generation R-Car sound device\n"); +- +- return -ENODEV; ++ return gen->ops->probe(pdev, info, priv); + } + + void rsnd_gen_remove(struct platform_device *pdev, + struct rsnd_priv *priv) + { +- if (rsnd_is_gen1(priv)) +- rsnd_gen1_remove(pdev, priv); ++ struct rsnd_gen *gen = rsnd_priv_to_gen(priv); ++ ++ gen->ops->remove(pdev, priv); + } +-- +1.8.5.rc3 + diff --git a/patches.renesas/0100-ASoC-rsnd-scu-cleanup-empty-functions.patch b/patches.renesas/0100-ASoC-rsnd-scu-cleanup-empty-functions.patch new file mode 100644 index 00000000000000..79a7d2f7794b9c --- /dev/null +++ b/patches.renesas/0100-ASoC-rsnd-scu-cleanup-empty-functions.patch @@ -0,0 +1,78 @@ +From c1dd06d49881b1e3adca1daa2266a2f9aca948d1 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 28 Jul 2013 18:59:25 -0700 +Subject: ASoC: rsnd: scu: cleanup empty functions + +This patch cleanups empty functions on scu + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 2460719c79854a3bebe569cbfbfa0b1caa1dc434) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/scu.c | 39 --------------------------------------- + 1 file changed, 39 deletions(-) + +diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c +index 29837e326bc5..184d9008cecd 100644 +--- a/sound/soc/sh/rcar/scu.c ++++ b/sound/soc/sh/rcar/scu.c +@@ -146,30 +146,6 @@ static int rsnd_scu_set_hpbif(struct rsnd_priv *priv, + return 0; + } + +-static int rsnd_scu_init(struct rsnd_mod *mod, +- struct rsnd_dai *rdai, +- struct rsnd_dai_stream *io) +-{ +- struct rsnd_priv *priv = rsnd_mod_to_priv(mod); +- struct device *dev = rsnd_priv_to_dev(priv); +- +- dev_dbg(dev, "%s.%d init\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); +- +- return 0; +-} +- +-static int rsnd_scu_quit(struct rsnd_mod *mod, +- struct rsnd_dai *rdai, +- struct rsnd_dai_stream *io) +-{ +- struct rsnd_priv *priv = rsnd_mod_to_priv(mod); +- struct device *dev = rsnd_priv_to_dev(priv); +- +- dev_dbg(dev, "%s.%d quit\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); +- +- return 0; +-} +- + static int rsnd_scu_start(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) +@@ -209,24 +185,9 @@ static int rsnd_scu_start(struct rsnd_mod *mod, + return 0; + } + +-static int rsnd_scu_stop(struct rsnd_mod *mod, +- struct rsnd_dai *rdai, +- struct rsnd_dai_stream *io) +-{ +- struct rsnd_priv *priv = rsnd_mod_to_priv(mod); +- struct device *dev = rsnd_priv_to_dev(priv); +- +- dev_dbg(dev, "%s.%d stop\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); +- +- return 0; +-} +- + static struct rsnd_mod_ops rsnd_scu_ops = { + .name = "scu", +- .init = rsnd_scu_init, +- .quit = rsnd_scu_quit, + .start = rsnd_scu_start, +- .stop = rsnd_scu_stop, + }; + + struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id) +-- +1.8.5.rc3 + diff --git a/patches.renesas/0101-ASoC-rcar-remove-unnecessary-mach-clock.h.patch b/patches.renesas/0101-ASoC-rcar-remove-unnecessary-mach-clock.h.patch new file mode 100644 index 00000000000000..682e12d8efd222 --- /dev/null +++ b/patches.renesas/0101-ASoC-rcar-remove-unnecessary-mach-clock.h.patch @@ -0,0 +1,34 @@ +From 6ee807d457689bf1ca6e3fa96e8ba794de4ae333 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Tue, 24 Sep 2013 01:25:08 -0700 +Subject: ASoC: rcar: remove unnecessary mach/clock.h + +${LINUX}/sound/soc/sh driver can be compiled from +SuperH and ARM. +but, ${LINUX}/sound/soc/sh/rcar driver included +SH-ARM specific header. +This patch removes it + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit d3be689e6a07c00123786659b4429b07cf4272ac) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/adg.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c +index d80deb7ccf13..2935bbf1811b 100644 +--- a/sound/soc/sh/rcar/adg.c ++++ b/sound/soc/sh/rcar/adg.c +@@ -8,7 +8,6 @@ + * for more details. + */ + #include <linux/sh_clk.h> +-#include <mach/clock.h> + #include "rsnd.h" + + #define CLKA 0 +-- +1.8.5.rc3 + diff --git a/patches.renesas/0102-ASoC-rsnd-fixup-flag-name-of-rsnd_scu_platform_info.patch b/patches.renesas/0102-ASoC-rsnd-fixup-flag-name-of-rsnd_scu_platform_info.patch new file mode 100644 index 00000000000000..127c404f27fbed --- /dev/null +++ b/patches.renesas/0102-ASoC-rsnd-fixup-flag-name-of-rsnd_scu_platform_info.patch @@ -0,0 +1,48 @@ +From e66f912c0a82f416b8d96ff8d4e85a45d38aa576 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 8 Sep 2013 21:21:41 -0700 +Subject: ASoC: rsnd: fixup flag name of rsnd_scu_platform_info + +it should be *USE*, not *USB* + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 34e4447515a18e0602f6df1a08b6a6ea63dea14b) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + include/sound/rcar_snd.h | 2 +- + sound/soc/sh/rcar/scu.c | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h +index d35412ae03b3..fe66533e9b7a 100644 +--- a/include/sound/rcar_snd.h ++++ b/include/sound/rcar_snd.h +@@ -55,7 +55,7 @@ struct rsnd_ssi_platform_info { + /* + * flags + */ +-#define RSND_SCU_USB_HPBIF (1 << 31) /* it needs RSND_SSI_DEPENDENT */ ++#define RSND_SCU_USE_HPBIF (1 << 31) /* it needs RSND_SSI_DEPENDENT */ + + struct rsnd_scu_platform_info { + u32 flags; +diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c +index 184d9008cecd..2df2e9150b89 100644 +--- a/sound/soc/sh/rcar/scu.c ++++ b/sound/soc/sh/rcar/scu.c +@@ -157,9 +157,9 @@ static int rsnd_scu_start(struct rsnd_mod *mod, + int ret; + + /* +- * SCU will be used if it has RSND_SCU_USB_HPBIF flags ++ * SCU will be used if it has RSND_SCU_USE_HPBIF flags + */ +- if (!(flags & RSND_SCU_USB_HPBIF)) { ++ if (!(flags & RSND_SCU_USE_HPBIF)) { + /* it use PIO transter */ + dev_dbg(dev, "%s%d is not used\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0103-ASoC-rsnd-remove-rsnd_priv_read-write-bset.patch b/patches.renesas/0103-ASoC-rsnd-remove-rsnd_priv_read-write-bset.patch new file mode 100644 index 00000000000000..0c8a576cd6c4e2 --- /dev/null +++ b/patches.renesas/0103-ASoC-rsnd-remove-rsnd_priv_read-write-bset.patch @@ -0,0 +1,71 @@ +From c3dd63df4d494e80b2e33d62212aa6dc8218a4d8 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Mon, 23 Sep 2013 23:12:17 -0700 +Subject: ASoC: rsnd: remove rsnd_priv_read/write/bset() + +adg.c only used rsnd_priv_read/write/bset() +which is the only user of NULL mod. +but, it can be removed. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit efeb970ee799b80c984a42d5706081af6047e160) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/adg.c | 10 +++++++--- + sound/soc/sh/rcar/rsnd.h | 4 ---- + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c +index 2935bbf1811b..9430097979a5 100644 +--- a/sound/soc/sh/rcar/adg.c ++++ b/sound/soc/sh/rcar/adg.c +@@ -21,6 +21,7 @@ struct rsnd_adg { + + int rate_of_441khz_div_6; + int rate_of_48khz_div_6; ++ u32 ckr; + }; + + #define for_each_rsnd_clk(pos, adg, i) \ +@@ -115,6 +116,11 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate) + + found_clock: + ++ /* see rsnd_adg_ssi_clk_init() */ ++ rsnd_mod_bset(mod, SSICKR, 0x00FF0000, adg->ckr); ++ rsnd_mod_write(mod, BRRA, 0x00000002); /* 1/6 */ ++ rsnd_mod_write(mod, BRRB, 0x00000002); /* 1/6 */ ++ + /* + * This "mod" = "ssi" here. + * we can get "ssi id" from mod +@@ -181,9 +187,7 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg) + } + } + +- rsnd_priv_bset(priv, SSICKR, 0x00FF0000, ckr); +- rsnd_priv_write(priv, BRRA, 0x00000002); /* 1/6 */ +- rsnd_priv_write(priv, BRRB, 0x00000002); /* 1/6 */ ++ adg->ckr = ckr; + } + + int rsnd_adg_probe(struct platform_device *pdev, +diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h +index 9cc6986a8cfb..3868aaf41cc4 100644 +--- a/sound/soc/sh/rcar/rsnd.h ++++ b/sound/soc/sh/rcar/rsnd.h +@@ -78,10 +78,6 @@ struct rsnd_dai_stream; + #define rsnd_mod_bset(m, r, s, d) \ + rsnd_bset(rsnd_mod_to_priv(m), m, RSND_REG_##r, s, d) + +-#define rsnd_priv_read(p, r) rsnd_read(p, NULL, RSND_REG_##r) +-#define rsnd_priv_write(p, r, d) rsnd_write(p, NULL, RSND_REG_##r, d) +-#define rsnd_priv_bset(p, r, s, d) rsnd_bset(p, NULL, RSND_REG_##r, s, d) +- + u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg); + void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod, + enum rsnd_reg reg, u32 data); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0104-ASoC-rcar-fixup-generation-checker.patch b/patches.renesas/0104-ASoC-rcar-fixup-generation-checker.patch new file mode 100644 index 00000000000000..31d258ebd2f96e --- /dev/null +++ b/patches.renesas/0104-ASoC-rcar-fixup-generation-checker.patch @@ -0,0 +1,48 @@ +From 0b9023fbf5f7ccf438450b40fc4e241ede107630 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Fri, 11 Oct 2013 00:07:01 -0700 +Subject: ASoC: rcar: fixup generation checker + +Current rcar is using rsnd_is_gen1/gen2() to checking its +IP generation, but it needs data mask. +This patch fixes it up. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit c5d5a58d7ff977289c4bba8eae447c9afa66516b) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + include/sound/rcar_snd.h | 1 + + sound/soc/sh/rcar/rsnd.h | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h +index fe66533e9b7a..fb0a312bcb81 100644 +--- a/include/sound/rcar_snd.h ++++ b/include/sound/rcar_snd.h +@@ -68,6 +68,7 @@ struct rsnd_scu_platform_info { + * + * A : generation + */ ++#define RSND_GEN_MASK (0xF << 0) + #define RSND_GEN1 (1 << 0) /* fixme */ + #define RSND_GEN2 (2 << 0) /* fixme */ + +diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h +index 3868aaf41cc4..3b71c3f2bfaa 100644 +--- a/sound/soc/sh/rcar/rsnd.h ++++ b/sound/soc/sh/rcar/rsnd.h +@@ -216,8 +216,8 @@ int rsnd_gen_path_exit(struct rsnd_priv *priv, + void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, + struct rsnd_mod *mod, + enum rsnd_reg reg); +-#define rsnd_is_gen1(s) ((s)->info->flags & RSND_GEN1) +-#define rsnd_is_gen2(s) ((s)->info->flags & RSND_GEN2) ++#define rsnd_is_gen1(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN1) ++#define rsnd_is_gen2(s) (((s)->info->flags & RSND_GEN_MASK) == RSND_GEN2) + + /* + * R-Car ADG +-- +1.8.5.rc3 + diff --git a/patches.renesas/0105-ASoC-rcar-fixup-rsnd_platform_call-return-value.patch b/patches.renesas/0105-ASoC-rcar-fixup-rsnd_platform_call-return-value.patch new file mode 100644 index 00000000000000..0af4fe515952ca --- /dev/null +++ b/patches.renesas/0105-ASoC-rcar-fixup-rsnd_platform_call-return-value.patch @@ -0,0 +1,31 @@ +From 34c47dd32ba76be576447dae6bde4b73dbbcbb03 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Fri, 11 Oct 2013 00:06:34 -0700 +Subject: ASoC: rcar: fixup rsnd_platform_call() return value + +Un-implemented platform callback is not error. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 740ad6c328823f066efb8b907576a54ef92aca69) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c +index a35706028514..0fb8bbfb872d 100644 +--- a/sound/soc/sh/rcar/core.c ++++ b/sound/soc/sh/rcar/core.c +@@ -103,7 +103,7 @@ + * rsnd_platform functions + */ + #define rsnd_platform_call(priv, dai, func, param...) \ +- (!(priv->info->func) ? -ENODEV : \ ++ (!(priv->info->func) ? 0 : \ + priv->info->func(param)) + + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0106-ASoC-rcar-add-ID-check-on-rsnd_dai_get.patch b/patches.renesas/0106-ASoC-rcar-add-ID-check-on-rsnd_dai_get.patch new file mode 100644 index 00000000000000..a35d59050f9380 --- /dev/null +++ b/patches.renesas/0106-ASoC-rcar-add-ID-check-on-rsnd_dai_get.patch @@ -0,0 +1,32 @@ +From b90ee952faf28e54939425b3de632851bce12b89 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Fri, 11 Oct 2013 00:07:48 -0700 +Subject: ASoC: rcar: add ID check on rsnd_dai_get() + +checking id in rsnd_dai_get() is good idea + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 2192f81c53a7879c803f0f7d6c49645fdf6c2f6a) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/core.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c +index 0fb8bbfb872d..7c3fa72112ab 100644 +--- a/sound/soc/sh/rcar/core.c ++++ b/sound/soc/sh/rcar/core.c +@@ -363,6 +363,9 @@ int rsnd_dai_id(struct rsnd_priv *priv, struct rsnd_dai *rdai) + + struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id) + { ++ if ((id < 0) || (id >= rsnd_dai_nr(priv))) ++ return NULL; ++ + return priv->rdai + id; + } + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0107-ASoC-rcar-add-rsnd_scu_hpbif_is_enable.patch b/patches.renesas/0107-ASoC-rcar-add-rsnd_scu_hpbif_is_enable.patch new file mode 100644 index 00000000000000..0766643c4649a6 --- /dev/null +++ b/patches.renesas/0107-ASoC-rcar-add-rsnd_scu_hpbif_is_enable.patch @@ -0,0 +1,116 @@ +From 44e54eb94100e8a6cf799acb26a369dac3a08833 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Thu, 17 Oct 2013 22:50:59 -0700 +Subject: ASoC: rcar: add rsnd_scu_hpbif_is_enable() + +Current SSI needs RSND_SSI_DEPENDENT flag to +decide dependent/independent mode. +And SCU needs RSND_SCU_USE_HPBIF flag +to decide HPBIF is enable/disable. +But these 2 means same things. + +This patch adds new rsnd_scu_hpbif_is_enable() +function, and merges above methods. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit cdcfcac968a1ec648434892b6addd80e66a5a892) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + include/sound/rcar_snd.h | 1 - + sound/soc/sh/rcar/rsnd.h | 1 + + sound/soc/sh/rcar/scu.c | 12 +++++++++--- + sound/soc/sh/rcar/ssi.c | 8 +++++--- + 4 files changed, 15 insertions(+), 7 deletions(-) + +diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h +index fb0a312bcb81..12afab18945d 100644 +--- a/include/sound/rcar_snd.h ++++ b/include/sound/rcar_snd.h +@@ -36,7 +36,6 @@ + #define RSND_SSI_CLK_PIN_SHARE (1 << 31) + #define RSND_SSI_CLK_FROM_ADG (1 << 30) /* clock parent is master */ + #define RSND_SSI_SYNC (1 << 29) /* SSI34_sync etc */ +-#define RSND_SSI_DEPENDENT (1 << 28) /* SSI needs SRU/SCU */ + + #define RSND_SSI_PLAY (1 << 24) + +diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h +index 3b71c3f2bfaa..9e463e50e7e6 100644 +--- a/sound/soc/sh/rcar/rsnd.h ++++ b/sound/soc/sh/rcar/rsnd.h +@@ -281,6 +281,7 @@ int rsnd_scu_probe(struct platform_device *pdev, + void rsnd_scu_remove(struct platform_device *pdev, + struct rsnd_priv *priv); + struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id); ++bool rsnd_scu_hpbif_is_enable(struct rsnd_mod *mod); + #define rsnd_scu_nr(priv) ((priv)->scu_nr) + + /* +diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c +index 2df2e9150b89..1ab1bce6be7f 100644 +--- a/sound/soc/sh/rcar/scu.c ++++ b/sound/soc/sh/rcar/scu.c +@@ -146,20 +146,26 @@ static int rsnd_scu_set_hpbif(struct rsnd_priv *priv, + return 0; + } + ++bool rsnd_scu_hpbif_is_enable(struct rsnd_mod *mod) ++{ ++ struct rsnd_scu *scu = rsnd_mod_to_scu(mod); ++ u32 flags = rsnd_scu_mode_flags(scu); ++ ++ return !!(flags & RSND_SCU_USE_HPBIF); ++} ++ + static int rsnd_scu_start(struct rsnd_mod *mod, + struct rsnd_dai *rdai, + struct rsnd_dai_stream *io) + { + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); +- struct rsnd_scu *scu = rsnd_mod_to_scu(mod); + struct device *dev = rsnd_priv_to_dev(priv); +- u32 flags = rsnd_scu_mode_flags(scu); + int ret; + + /* + * SCU will be used if it has RSND_SCU_USE_HPBIF flags + */ +- if (!(flags & RSND_SCU_USE_HPBIF)) { ++ if (!rsnd_scu_hpbif_is_enable(mod)) { + /* it use PIO transter */ + dev_dbg(dev, "%s%d is not used\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); +diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c +index fae26d3f79d2..7613256c9840 100644 +--- a/sound/soc/sh/rcar/ssi.c ++++ b/sound/soc/sh/rcar/ssi.c +@@ -106,6 +106,7 @@ static void rsnd_ssi_mode_init(struct rsnd_priv *priv, + { + struct device *dev = rsnd_priv_to_dev(priv); + struct rsnd_ssi *ssi; ++ struct rsnd_mod *scu; + u32 flags; + u32 val; + int i; +@@ -116,13 +117,14 @@ static void rsnd_ssi_mode_init(struct rsnd_priv *priv, + ssiu->ssi_mode0 = 0; + for_each_rsnd_ssi(ssi, priv, i) { + flags = rsnd_ssi_mode_flags(ssi); ++ scu = rsnd_scu_mod_get(priv, rsnd_mod_id(&ssi->mod)); + + /* see also BUSIF_MODE */ +- if (!(flags & RSND_SSI_DEPENDENT)) { ++ if (rsnd_scu_hpbif_is_enable(scu)) { ++ dev_dbg(dev, "SSI%d uses DEPENDENT mode\n", i); ++ } else { + ssiu->ssi_mode0 |= (1 << i); + dev_dbg(dev, "SSI%d uses INDEPENDENT mode\n", i); +- } else { +- dev_dbg(dev, "SSI%d uses DEPENDENT mode\n", i); + } + } + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0108-ASoC-rcar-remove-RSND_SSI_CLK_FROM_ADG.patch b/patches.renesas/0108-ASoC-rcar-remove-RSND_SSI_CLK_FROM_ADG.patch new file mode 100644 index 00000000000000..77acfe2f3ed1d4 --- /dev/null +++ b/patches.renesas/0108-ASoC-rcar-remove-RSND_SSI_CLK_FROM_ADG.patch @@ -0,0 +1,142 @@ +From d23c54fd3600d943e691b4096680edda52888b06 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Thu, 17 Oct 2013 22:51:40 -0700 +Subject: ASoC: rcar: remove RSND_SSI_CLK_FROM_ADG + +R-Car sound has clock pin for each SSI, and sometimes, +these pins are shared with paired SSI. +It may sometimes become "SSI-A clock pin is master" and +"SSI-B clock pin is slave", but "SSI-A/B clock pins are shared". +SSI-B needs SSI-A clock in this case. + +Current R-Car sound driver is using RSND_SSI_xxx flag +to control this kind of shared pin behavior. + +But, this information, especially clock master setting, +can be got from ASoC set_fmt settings. +This patch removes rsnd_ssi_mode_init() and extend rsnd_ssi_mode_set() +to controlling pin settings via .set_fmt. + +This patch doesn't removes RSND_SSI_CLK_FROM_ADG flag at this point +to avoid conflict branch merging between ASoC <-> SH-ARM. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 92eba04e4bcd469518cc759ac1bf1a49acaa5cc1) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/ssi.c | 52 +++++++++++++++++++------------------------------ + 1 file changed, 20 insertions(+), 32 deletions(-) + +diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c +index 7613256c9840..b71cf9d7dd3f 100644 +--- a/sound/soc/sh/rcar/ssi.c ++++ b/sound/soc/sh/rcar/ssi.c +@@ -101,31 +101,30 @@ struct rsnd_ssiu { + #define rsnd_ssi_to_ssiu(ssi)\ + (((struct rsnd_ssiu *)((ssi) - rsnd_mod_id(&(ssi)->mod))) - 1) + +-static void rsnd_ssi_mode_init(struct rsnd_priv *priv, +- struct rsnd_ssiu *ssiu) ++static void rsnd_ssi_mode_set(struct rsnd_priv *priv, ++ struct rsnd_dai *rdai, ++ struct rsnd_ssi *ssi) + { + struct device *dev = rsnd_priv_to_dev(priv); +- struct rsnd_ssi *ssi; + struct rsnd_mod *scu; ++ struct rsnd_ssiu *ssiu = rsnd_ssi_to_ssiu(ssi); ++ int id = rsnd_mod_id(&ssi->mod); + u32 flags; + u32 val; +- int i; ++ ++ scu = rsnd_scu_mod_get(priv, rsnd_mod_id(&ssi->mod)); + + /* + * SSI_MODE0 + */ +- ssiu->ssi_mode0 = 0; +- for_each_rsnd_ssi(ssi, priv, i) { +- flags = rsnd_ssi_mode_flags(ssi); +- scu = rsnd_scu_mod_get(priv, rsnd_mod_id(&ssi->mod)); +- +- /* see also BUSIF_MODE */ +- if (rsnd_scu_hpbif_is_enable(scu)) { +- dev_dbg(dev, "SSI%d uses DEPENDENT mode\n", i); +- } else { +- ssiu->ssi_mode0 |= (1 << i); +- dev_dbg(dev, "SSI%d uses INDEPENDENT mode\n", i); +- } ++ ++ /* see also BUSIF_MODE */ ++ if (rsnd_scu_hpbif_is_enable(scu)) { ++ ssiu->ssi_mode0 &= ~(1 << id); ++ dev_dbg(dev, "SSI%d uses DEPENDENT mode\n", id); ++ } else { ++ ssiu->ssi_mode0 |= (1 << id); ++ dev_dbg(dev, "SSI%d uses INDEPENDENT mode\n", id); + } + + /* +@@ -134,7 +133,7 @@ static void rsnd_ssi_mode_init(struct rsnd_priv *priv, + #define ssi_parent_set(p, sync, adg, ext) \ + do { \ + ssi->parent = ssiu->ssi + p; \ +- if (flags & RSND_SSI_CLK_FROM_ADG) \ ++ if (rsnd_rdai_is_clk_master(rdai)) \ + val = adg; \ + else \ + val = ext; \ +@@ -142,15 +141,11 @@ static void rsnd_ssi_mode_init(struct rsnd_priv *priv, + val |= sync; \ + } while (0) + +- ssiu->ssi_mode1 = 0; +- for_each_rsnd_ssi(ssi, priv, i) { +- flags = rsnd_ssi_mode_flags(ssi); +- +- if (!(flags & RSND_SSI_CLK_PIN_SHARE)) +- continue; ++ flags = rsnd_ssi_mode_flags(ssi); ++ if (flags & RSND_SSI_CLK_PIN_SHARE) { + + val = 0; +- switch (i) { ++ switch (id) { + case 1: + ssi_parent_set(0, (1 << 4), (0x2 << 0), (0x1 << 0)); + break; +@@ -167,11 +162,6 @@ static void rsnd_ssi_mode_init(struct rsnd_priv *priv, + + ssiu->ssi_mode1 |= val; + } +-} +- +-static void rsnd_ssi_mode_set(struct rsnd_ssi *ssi) +-{ +- struct rsnd_ssiu *ssiu = rsnd_ssi_to_ssiu(ssi); + + rsnd_mod_write(&ssi->mod, SSI_MODE0, ssiu->ssi_mode0); + rsnd_mod_write(&ssi->mod, SSI_MODE1, ssiu->ssi_mode1); +@@ -381,7 +371,7 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, + ssi->cr_own = cr; + ssi->err = -1; /* ignore 1st error */ + +- rsnd_ssi_mode_set(ssi); ++ rsnd_ssi_mode_set(priv, rdai, ssi); + + dev_dbg(dev, "%s.%d init\n", rsnd_mod_name(mod), rsnd_mod_id(mod)); + +@@ -708,8 +698,6 @@ int rsnd_ssi_probe(struct platform_device *pdev, + rsnd_mod_init(priv, &ssi->mod, ops, i); + } + +- rsnd_ssi_mode_init(priv, ssiu); +- + dev_dbg(dev, "ssi probed\n"); + + return 0; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0109-ASoC-rcar-remove-original-filter-from-rsnd_dma_init.patch b/patches.renesas/0109-ASoC-rcar-remove-original-filter-from-rsnd_dma_init.patch new file mode 100644 index 00000000000000..0575c9b5b81aae --- /dev/null +++ b/patches.renesas/0109-ASoC-rcar-remove-original-filter-from-rsnd_dma_init.patch @@ -0,0 +1,96 @@ +From c22d31d1220f24ace731346341aac448ede24853 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Tue, 29 Oct 2013 00:52:19 -0700 +Subject: ASoC: rcar: remove original filter from rsnd_dma_init() + +Remove original filter from rsnd_dma_init(), +and use SH-DMA suitable filter. +This new style can be used from Device Tree. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 9ade09d6c62e48fba6c74ce3958ca1035dfd8427) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/core.c | 31 ++++++++++++++++++++----------- + 1 file changed, 20 insertions(+), 11 deletions(-) + +diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c +index 7c3fa72112ab..839eee3208dc 100644 +--- a/sound/soc/sh/rcar/core.c ++++ b/sound/soc/sh/rcar/core.c +@@ -94,6 +94,7 @@ + * + */ + #include <linux/pm_runtime.h> ++#include <linux/shdma-base.h> + #include "rsnd.h" + + #define RSND_RATES SNDRV_PCM_RATE_8000_96000 +@@ -254,13 +255,6 @@ int rsnd_dma_available(struct rsnd_dma *dma) + return !!dma->chan; + } + +-static bool rsnd_dma_filter(struct dma_chan *chan, void *param) +-{ +- chan->private = param; +- +- return true; +-} +- + int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, + int is_play, int id, + int (*inquiry)(struct rsnd_dma *dma, +@@ -268,7 +262,9 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, + int (*complete)(struct rsnd_dma *dma)) + { + struct device *dev = rsnd_priv_to_dev(priv); ++ struct dma_slave_config cfg; + dma_cap_mask_t mask; ++ int ret; + + if (dma->chan) { + dev_err(dev, "it already has dma channel\n"); +@@ -278,15 +274,23 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + +- dma->slave.shdma_slave.slave_id = id; +- +- dma->chan = dma_request_channel(mask, rsnd_dma_filter, +- &dma->slave.shdma_slave); ++ dma->chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, ++ (void *)id, dev, ++ is_play ? "tx" : "rx"); + if (!dma->chan) { + dev_err(dev, "can't get dma channel\n"); + return -EIO; + } + ++ cfg.slave_id = id; ++ cfg.dst_addr = 0; /* use default addr when playback */ ++ cfg.src_addr = 0; /* use default addr when capture */ ++ cfg.direction = is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM; ++ ++ ret = dmaengine_slave_config(dma->chan, &cfg); ++ if (ret < 0) ++ goto rsnd_dma_init_err; ++ + dma->dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; + dma->priv = priv; + dma->inquiry = inquiry; +@@ -294,6 +298,11 @@ int rsnd_dma_init(struct rsnd_priv *priv, struct rsnd_dma *dma, + INIT_WORK(&dma->work, rsnd_dma_do_work); + + return 0; ++ ++rsnd_dma_init_err: ++ rsnd_dma_quit(priv, dma); ++ ++ return ret; + } + + void rsnd_dma_quit(struct rsnd_priv *priv, +-- +1.8.5.rc3 + diff --git a/patches.renesas/0110-ASoC-rcar-remove-un-needed-select-from-Kconfig.patch b/patches.renesas/0110-ASoC-rcar-remove-un-needed-select-from-Kconfig.patch new file mode 100644 index 00000000000000..6c7e379afa194e --- /dev/null +++ b/patches.renesas/0110-ASoC-rcar-remove-un-needed-select-from-Kconfig.patch @@ -0,0 +1,30 @@ +From b92d5ecdc20e7107301e99e2d25cc8b00077754f Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Wed, 6 Nov 2013 00:06:45 -0800 +Subject: ASoC: rcar: remove un-needed select from Kconfig + +config RCAR_CLK_ADG is not exist + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit a2b4f8a473efd82d634117a057e0ba64443354cf) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/Kconfig | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig +index 56d8ff6a402d..14011d90d70a 100644 +--- a/sound/soc/sh/Kconfig ++++ b/sound/soc/sh/Kconfig +@@ -37,7 +37,6 @@ config SND_SOC_SH4_SIU + config SND_SOC_RCAR + tristate "R-Car series SRU/SCU/SSIU/SSI support" + select SND_SIMPLE_CARD +- select RCAR_CLK_ADG + help + This option enables R-Car SUR/SCU/SSIU/SSI sound support + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0111-ASoC-rcar-Use-WARN_ON-instead-of-BUG_ON.patch b/patches.renesas/0111-ASoC-rcar-Use-WARN_ON-instead-of-BUG_ON.patch new file mode 100644 index 00000000000000..6c239ae43a5b25 --- /dev/null +++ b/patches.renesas/0111-ASoC-rcar-Use-WARN_ON-instead-of-BUG_ON.patch @@ -0,0 +1,48 @@ +From 58c7bf485d795a3ca0283fc3c72f47704a0e0aa0 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai <tiwai@suse.de> +Date: Tue, 5 Nov 2013 18:40:05 +0100 +Subject: ASoC: rcar: Use WARN_ON() instead of BUG_ON() + +Use WARN_ON() and handle the error cases accordingly. + +Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Takashi Iwai <tiwai@suse.de> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 8b14719bebfe022f3637c323e76c88b2bc061a61) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/scu.c | 3 ++- + sound/soc/sh/rcar/ssi.c | 3 ++- + 2 files changed, 4 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c +index 1ab1bce6be7f..f4453e33a847 100644 +--- a/sound/soc/sh/rcar/scu.c ++++ b/sound/soc/sh/rcar/scu.c +@@ -198,7 +198,8 @@ static struct rsnd_mod_ops rsnd_scu_ops = { + + struct rsnd_mod *rsnd_scu_mod_get(struct rsnd_priv *priv, int id) + { +- BUG_ON(id < 0 || id >= rsnd_scu_nr(priv)); ++ if (WARN_ON(id < 0 || id >= rsnd_scu_nr(priv))) ++ id = 0; + + return &((struct rsnd_scu *)(priv->scu) + id)->mod; + } +diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c +index b71cf9d7dd3f..5ac20cd5e006 100644 +--- a/sound/soc/sh/rcar/ssi.c ++++ b/sound/soc/sh/rcar/ssi.c +@@ -611,7 +611,8 @@ struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, + + struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) + { +- BUG_ON(id < 0 || id >= rsnd_ssi_nr(priv)); ++ if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) ++ id = 0; + + return &(((struct rsnd_ssiu *)(priv->ssiu))->ssi + id)->mod; + } +-- +1.8.5.rc3 + diff --git a/patches.renesas/0112-ASoC-rcar-fixup-mod-access-before-checking.patch b/patches.renesas/0112-ASoC-rcar-fixup-mod-access-before-checking.patch new file mode 100644 index 00000000000000..6162ef2e311151 --- /dev/null +++ b/patches.renesas/0112-ASoC-rcar-fixup-mod-access-before-checking.patch @@ -0,0 +1,44 @@ +From c1f3ff3bbdbb555bec65e5892a34b70c208abc5e Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 10 Nov 2013 17:00:42 -0800 +Subject: ASoC: rcar: fixup mod access before checking + +rsnd_dai_connect() is using mod before NULL checking. +This patch fixes it up + +Reported-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 6020779b118f6221e5d067bd1e6b44bab6fc0276) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/core.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c +index 839eee3208dc..ae1a5ed8974e 100644 +--- a/sound/soc/sh/rcar/core.c ++++ b/sound/soc/sh/rcar/core.c +@@ -333,15 +333,13 @@ int rsnd_dai_connect(struct rsnd_dai *rdai, + struct rsnd_mod *mod, + struct rsnd_dai_stream *io) + { +- struct rsnd_priv *priv = rsnd_mod_to_priv(mod); +- struct device *dev = rsnd_priv_to_dev(priv); +- +- if (!mod) { +- dev_err(dev, "NULL mod\n"); ++ if (!mod) + return -EIO; +- } + + if (!list_empty(&mod->list)) { ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); ++ struct device *dev = rsnd_priv_to_dev(priv); ++ + dev_err(dev, "%s%d is not empty\n", + rsnd_mod_name(mod), + rsnd_mod_id(mod)); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0113-ASoC-rcar-off-by-one-in-rsnd_scu_set_route.patch b/patches.renesas/0113-ASoC-rcar-off-by-one-in-rsnd_scu_set_route.patch new file mode 100644 index 00000000000000..886d7b1798528f --- /dev/null +++ b/patches.renesas/0113-ASoC-rcar-off-by-one-in-rsnd_scu_set_route.patch @@ -0,0 +1,33 @@ +From f1a26ba277f1c8ff97e4ee81223dca356e88190c Mon Sep 17 00:00:00 2001 +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Fri, 8 Nov 2013 12:46:10 +0300 +Subject: ASoC: rcar: off by one in rsnd_scu_set_route() + +If "id == ARRAY_SIZE(routes)" then we read one space beyond the end of +the routes[] array. + +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit b5f3d7af286a28e2fcc92debaba40844cb32bfb4) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/scu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/sh/rcar/scu.c b/sound/soc/sh/rcar/scu.c +index f4453e33a847..fa8fa15860b9 100644 +--- a/sound/soc/sh/rcar/scu.c ++++ b/sound/soc/sh/rcar/scu.c +@@ -68,7 +68,7 @@ static int rsnd_scu_set_route(struct rsnd_priv *priv, + return 0; + + id = rsnd_mod_id(mod); +- if (id < 0 || id > ARRAY_SIZE(routes)) ++ if (id < 0 || id >= ARRAY_SIZE(routes)) + return -EIO; + + /* +-- +1.8.5.rc3 + diff --git a/patches.renesas/0114-ASoC-rcar-fixup-dma_async_issue_pending-timing.patch b/patches.renesas/0114-ASoC-rcar-fixup-dma_async_issue_pending-timing.patch new file mode 100644 index 00000000000000..f9da5445a8a4c6 --- /dev/null +++ b/patches.renesas/0114-ASoC-rcar-fixup-dma_async_issue_pending-timing.patch @@ -0,0 +1,33 @@ +From 7b4d99db388ad23d29f3e41559811ab5d85ea27b Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 17 Nov 2013 18:45:16 -0800 +Subject: ASoC: rcar: fixup dma_async_issue_pending() timing + +DMAEngine will stall without this patch + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit a0d32bca511fd6b570e964ca38a0c3dcd9eacafb) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/rcar/core.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c +index ae1a5ed8974e..eb746e74b52d 100644 +--- a/sound/soc/sh/rcar/core.c ++++ b/sound/soc/sh/rcar/core.c +@@ -245,9 +245,8 @@ static void rsnd_dma_do_work(struct work_struct *work) + return; + } + ++ dma_async_issue_pending(dma->chan); + } +- +- dma_async_issue_pending(dma->chan); + } + + int rsnd_dma_available(struct rsnd_dma *dma) +-- +1.8.5.rc3 + diff --git a/patches.renesas/0115-pwm-backlight-Add-optional-enable-GPIO.patch b/patches.renesas/0115-pwm-backlight-Add-optional-enable-GPIO.patch new file mode 100644 index 00000000000000..9227b92cf80d5d --- /dev/null +++ b/patches.renesas/0115-pwm-backlight-Add-optional-enable-GPIO.patch @@ -0,0 +1,48 @@ +From 626358586a945f566db983632d6a0a50dcfc38a3 Mon Sep 17 00:00:00 2001 +From: Thierry Reding <treding@nvidia.com> +Date: Fri, 30 Aug 2013 11:51:22 +0200 +Subject: pwm-backlight: Add optional enable GPIO + +To support a wider variety of backlight setups, introduce an optional +enable GPIO. Legacy users of the platform data already have a means of +supporting GPIOs by using the .init(), .exit() and .notify() hooks. DT +users however cannot use those, so an alternative method is required. + +In order to ease the introduction of the optional enable GPIO, make it +available in the platform data first, so that existing users can be +converted. Once that has happened a second patch will add code to make +use of it in the driver. + +Signed-off-by: Thierry Reding <treding@nvidia.com> +(cherry picked from commit 2b9b1620349e325f184c68cddf3b484499c163c0) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + include/linux/pwm_backlight.h | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h +index 56f4a866539a..2de2e275b2cb 100644 +--- a/include/linux/pwm_backlight.h ++++ b/include/linux/pwm_backlight.h +@@ -6,6 +6,9 @@ + + #include <linux/backlight.h> + ++/* TODO: convert to gpiod_*() API once it has been merged */ ++#define PWM_BACKLIGHT_GPIO_ACTIVE_LOW (1 << 0) ++ + struct platform_pwm_backlight_data { + int pwm_id; + unsigned int max_brightness; +@@ -13,6 +16,8 @@ struct platform_pwm_backlight_data { + unsigned int lth_brightness; + unsigned int pwm_period_ns; + unsigned int *levels; ++ int enable_gpio; ++ unsigned long enable_gpio_flags; + int (*init)(struct device *dev); + int (*notify)(struct device *dev, int brightness); + void (*notify_after)(struct device *dev, int brightness); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0116-pwm-Add-PWM-polarity-flag-macro-for-DT.patch b/patches.renesas/0116-pwm-Add-PWM-polarity-flag-macro-for-DT.patch new file mode 100644 index 00000000000000..74ba3d0364e365 --- /dev/null +++ b/patches.renesas/0116-pwm-Add-PWM-polarity-flag-macro-for-DT.patch @@ -0,0 +1,64 @@ +From 909d7c56d70416b1afabfba6d3d64582795c510a Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 18 Jul 2013 00:54:21 +0200 +Subject: pwm: Add PWM polarity flag macro for DT + +Define a PWM_POLARITY_INVERTED macro in include/dt-bindings/pwm/pwm.h to +be used by device tree sources. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Reviewed-by: Stephen Warren <swarren@nvidia.com> +Signed-off-by: Thierry Reding <thierry.reding@gmail.com> +(cherry picked from commit 9344dade4f9438c26f7eb517caeceee4d52a3a68) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + Documentation/devicetree/bindings/pwm/pwm.txt | 7 ++++--- + include/dt-bindings/pwm/pwm.h | 14 ++++++++++++++ + 2 files changed, 18 insertions(+), 3 deletions(-) + create mode 100644 include/dt-bindings/pwm/pwm.h + +diff --git a/Documentation/devicetree/bindings/pwm/pwm.txt b/Documentation/devicetree/bindings/pwm/pwm.txt +index 06e67247859a..8556263b8502 100644 +--- a/Documentation/devicetree/bindings/pwm/pwm.txt ++++ b/Documentation/devicetree/bindings/pwm/pwm.txt +@@ -43,13 +43,14 @@ because the name "backlight" would be used as fallback anyway. + pwm-specifier typically encodes the chip-relative PWM number and the PWM + period in nanoseconds. + +-Optionally, the pwm-specifier can encode a number of flags in a third cell: +-- bit 0: PWM signal polarity (0: normal polarity, 1: inverse polarity) ++Optionally, the pwm-specifier can encode a number of flags (defined in ++<dt-bindings/pwm/pwm.h>) in a third cell: ++- PWM_POLARITY_INVERTED: invert the PWM signal polarity + + Example with optional PWM specifier for inverse polarity + + bl: backlight { +- pwms = <&pwm 0 5000000 1>; ++ pwms = <&pwm 0 5000000 PWM_POLARITY_INVERTED>; + pwm-names = "backlight"; + }; + +diff --git a/include/dt-bindings/pwm/pwm.h b/include/dt-bindings/pwm/pwm.h +new file mode 100644 +index 000000000000..96f49e82253e +--- /dev/null ++++ b/include/dt-bindings/pwm/pwm.h +@@ -0,0 +1,14 @@ ++/* ++ * This header provides constants for most PWM bindings. ++ * ++ * Most PWM bindings can include a flags cell as part of the PWM specifier. ++ * In most cases, the format of the flags cell uses the standard values ++ * defined in this header. ++ */ ++ ++#ifndef _DT_BINDINGS_PWM_PWM_H ++#define _DT_BINDINGS_PWM_PWM_H ++ ++#define PWM_POLARITY_INVERTED (1 << 0) ++ ++#endif +-- +1.8.5.rc3 + diff --git a/patches.renesas/0117-ARM-shmobile-Rename-to-r8a73a4_init_early.patch b/patches.renesas/0117-ARM-shmobile-Rename-to-r8a73a4_init_early.patch new file mode 100644 index 00000000000000..b5349f93c67dbd --- /dev/null +++ b/patches.renesas/0117-ARM-shmobile-Rename-to-r8a73a4_init_early.patch @@ -0,0 +1,83 @@ +From 294e932056bdaf3e3aa20497f17dbf077a431452 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 8 Aug 2013 07:26:48 +0900 +Subject: ARM: shmobile: Rename to r8a73a4_init_early() + +Rename r8a73a4_init_delay() into r8a73a4_init_early() +to make the function name show that more than just +delay setup may happen in the future. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 0750a54592a2daff70771a1c170f9859d5901d3d) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-ape6evm-reference.c | 2 +- + arch/arm/mach-shmobile/board-ape6evm.c | 2 +- + arch/arm/mach-shmobile/include/mach/r8a73a4.h | 2 +- + arch/arm/mach-shmobile/setup-r8a73a4.c | 4 ++-- + 4 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm/mach-shmobile/board-ape6evm-reference.c b/arch/arm/mach-shmobile/board-ape6evm-reference.c +index a23fa714f7ac..3276afcf3cc9 100644 +--- a/arch/arm/mach-shmobile/board-ape6evm-reference.c ++++ b/arch/arm/mach-shmobile/board-ape6evm-reference.c +@@ -57,7 +57,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = { + }; + + DT_MACHINE_START(APE6EVM_DT, "ape6evm") +- .init_early = r8a73a4_init_delay, ++ .init_early = r8a73a4_init_early, + .init_machine = ape6evm_add_standard_devices, + .dt_compat = ape6evm_boards_compat_dt, + MACHINE_END +diff --git a/arch/arm/mach-shmobile/board-ape6evm.c b/arch/arm/mach-shmobile/board-ape6evm.c +index 24b87eea9da3..d36e23f5d8b7 100644 +--- a/arch/arm/mach-shmobile/board-ape6evm.c ++++ b/arch/arm/mach-shmobile/board-ape6evm.c +@@ -240,7 +240,7 @@ static const char *ape6evm_boards_compat_dt[] __initdata = { + }; + + DT_MACHINE_START(APE6EVM_DT, "ape6evm") +- .init_early = r8a73a4_init_delay, ++ .init_early = r8a73a4_init_early, + .init_machine = ape6evm_add_standard_devices, + .dt_compat = ape6evm_boards_compat_dt, + MACHINE_END +diff --git a/arch/arm/mach-shmobile/include/mach/r8a73a4.h b/arch/arm/mach-shmobile/include/mach/r8a73a4.h +index f3a9b702da56..5214338a6a47 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a73a4.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a73a4.h +@@ -5,6 +5,6 @@ void r8a73a4_add_standard_devices(void); + void r8a73a4_add_dt_devices(void); + void r8a73a4_clock_init(void); + void r8a73a4_pinmux_init(void); +-void r8a73a4_init_delay(void); ++void r8a73a4_init_early(void); + + #endif /* __ASM_R8A73A4_H__ */ +diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c +index 89491700afb7..53a896275cae 100644 +--- a/arch/arm/mach-shmobile/setup-r8a73a4.c ++++ b/arch/arm/mach-shmobile/setup-r8a73a4.c +@@ -207,7 +207,7 @@ void __init r8a73a4_add_standard_devices(void) + r8a73a4_register_thermal(); + } + +-void __init r8a73a4_init_delay(void) ++void __init r8a73a4_init_early(void) + { + #ifndef CONFIG_ARM_ARCH_TIMER + shmobile_setup_delay(1500, 2, 4); /* Cortex-A15 @ 1500MHz */ +@@ -222,7 +222,7 @@ static const char *r8a73a4_boards_compat_dt[] __initdata = { + }; + + DT_MACHINE_START(R8A73A4_DT, "Generic R8A73A4 (Flattened Device Tree)") +- .init_early = r8a73a4_init_delay, ++ .init_early = r8a73a4_init_early, + .dt_compat = r8a73a4_boards_compat_dt, + MACHINE_END + #endif /* CONFIG_USE_OF */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0118-ARM-shmobile-Rename-to-r8a7790_init_early.patch b/patches.renesas/0118-ARM-shmobile-Rename-to-r8a7790_init_early.patch new file mode 100644 index 00000000000000..b8f507b9d80876 --- /dev/null +++ b/patches.renesas/0118-ARM-shmobile-Rename-to-r8a7790_init_early.patch @@ -0,0 +1,84 @@ +From 51bc0c0d91e1ba6c5e6272ff9070951bc3958b81 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 8 Aug 2013 07:27:01 +0900 +Subject: ARM: shmobile: Rename to r8a7790_init_early() + +Rename r8a7790_init_delay() into r8a7790_init_early() +to make the function name show that more than just +delay setup may happen in the future. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 0efd7faa6c611dab4ab8105473d2ffde7918cb69) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-lager-reference.c | 2 +- + arch/arm/mach-shmobile/board-lager.c | 2 +- + arch/arm/mach-shmobile/include/mach/r8a7790.h | 2 +- + arch/arm/mach-shmobile/setup-r8a7790.c | 4 ++-- + 4 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c +index 9c316a1b2e32..2856f51ff8a6 100644 +--- a/arch/arm/mach-shmobile/board-lager-reference.c ++++ b/arch/arm/mach-shmobile/board-lager-reference.c +@@ -38,7 +38,7 @@ static const char *lager_boards_compat_dt[] __initdata = { + }; + + DT_MACHINE_START(LAGER_DT, "lager") +- .init_early = r8a7790_init_delay, ++ .init_early = r8a7790_init_early, + .init_machine = lager_add_standard_devices, + .init_time = r8a7790_timer_init, + .dt_compat = lager_boards_compat_dt, +diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c +index 5930af8d434f..6569491839cf 100644 +--- a/arch/arm/mach-shmobile/board-lager.c ++++ b/arch/arm/mach-shmobile/board-lager.c +@@ -186,7 +186,7 @@ static const char *lager_boards_compat_dt[] __initdata = { + }; + + DT_MACHINE_START(LAGER_DT, "lager") +- .init_early = r8a7790_init_delay, ++ .init_early = r8a7790_init_early, + .init_time = r8a7790_timer_init, + .init_machine = lager_init, + .dt_compat = lager_boards_compat_dt, +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h +index 788d55952091..177a8372abb7 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a7790.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h +@@ -5,7 +5,7 @@ void r8a7790_add_standard_devices(void); + void r8a7790_add_dt_devices(void); + void r8a7790_clock_init(void); + void r8a7790_pinmux_init(void); +-void r8a7790_init_delay(void); ++void r8a7790_init_early(void); + void r8a7790_timer_init(void); + + #define MD(nr) BIT(nr) +diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c +index d0f5c9f9349a..a42d1f6f1f81 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7790.c ++++ b/arch/arm/mach-shmobile/setup-r8a7790.c +@@ -267,7 +267,7 @@ void __init r8a7790_timer_init(void) + clocksource_of_init(); + } + +-void __init r8a7790_init_delay(void) ++void __init r8a7790_init_early(void) + { + #ifndef CONFIG_ARM_ARCH_TIMER + shmobile_setup_delay(1300, 2, 4); /* Cortex-A15 @ 1300MHz */ +@@ -282,7 +282,7 @@ static const char *r8a7790_boards_compat_dt[] __initdata = { + }; + + DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)") +- .init_early = r8a7790_init_delay, ++ .init_early = r8a7790_init_early, + .init_time = r8a7790_timer_init, + .dt_compat = r8a7790_boards_compat_dt, + MACHINE_END +-- +1.8.5.rc3 + diff --git a/patches.renesas/0119-ARM-shmobile-r8a7790-Constify-platform-data-and-reso.patch b/patches.renesas/0119-ARM-shmobile-r8a7790-Constify-platform-data-and-reso.patch new file mode 100644 index 00000000000000..81f445aa0d4376 --- /dev/null +++ b/patches.renesas/0119-ARM-shmobile-r8a7790-Constify-platform-data-and-reso.patch @@ -0,0 +1,104 @@ +From 424339e0e986f12022b701c7ab0564db219d61d8 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 8 Aug 2013 00:34:53 +0200 +Subject: ARM: shmobile: r8a7790: Constify platform data and resources + +Platform data and resources for core devices are kmemdup()ed when the +corresponding devices are registered and can thus be declared as const. +Do so. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit cde214a890f81797a5eee94fffc89c1de21ed991) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/setup-r8a7790.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c +index a42d1f6f1f81..e0d29a265c2d 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7790.c ++++ b/arch/arm/mach-shmobile/setup-r8a7790.c +@@ -31,17 +31,18 @@ + #include <mach/r8a7790.h> + #include <asm/mach/arch.h> + +-static struct resource pfc_resources[] __initdata = { ++static const struct resource pfc_resources[] __initconst = { + DEFINE_RES_MEM(0xe6060000, 0x250), + }; + + #define R8A7790_GPIO(idx) \ +-static struct resource r8a7790_gpio##idx##_resources[] __initdata = { \ ++static const struct resource r8a7790_gpio##idx##_resources[] __initconst = { \ + DEFINE_RES_MEM(0xe6050000 + 0x1000 * (idx), 0x50), \ + DEFINE_RES_IRQ(gic_spi(4 + (idx))), \ + }; \ + \ +-static struct gpio_rcar_config r8a7790_gpio##idx##_platform_data __initdata = { \ ++static const struct gpio_rcar_config \ ++r8a7790_gpio##idx##_platform_data __initconst = { \ + .gpio_base = 32 * (idx), \ + .irq_base = 0, \ + .number_of_pins = 32, \ +@@ -112,7 +113,7 @@ void __init r8a7790_pinmux_init(void) + enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1, + HSCIF0, HSCIF1 }; + +-static struct plat_sci_port scif[] __initdata = { ++static const struct plat_sci_port scif[] __initconst = { + SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */ + SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */ + SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */ +@@ -131,11 +132,11 @@ static inline void r8a7790_register_scif(int idx) + sizeof(struct plat_sci_port)); + } + +-static struct renesas_irqc_config irqc0_data __initdata = { ++static const struct renesas_irqc_config irqc0_data __initconst = { + .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */ + }; + +-static struct resource irqc0_resources[] __initdata = { ++static const struct resource irqc0_resources[] __initconst = { + DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */ + DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */ + DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */ +@@ -150,7 +151,7 @@ static struct resource irqc0_resources[] __initdata = { + &irqc##idx##_data, \ + sizeof(struct renesas_irqc_config)) + +-static struct resource thermal_resources[] __initdata = { ++static const struct resource thermal_resources[] __initconst = { + DEFINE_RES_MEM(0xe61f0000, 0x14), + DEFINE_RES_MEM(0xe61f0100, 0x38), + DEFINE_RES_IRQ(gic_spi(69)), +@@ -161,13 +162,13 @@ static struct resource thermal_resources[] __initdata = { + thermal_resources, \ + ARRAY_SIZE(thermal_resources)) + +-static struct sh_timer_config cmt00_platform_data __initdata = { ++static const struct sh_timer_config cmt00_platform_data __initconst = { + .name = "CMT00", + .timer_bit = 0, + .clockevent_rating = 80, + }; + +-static struct resource cmt00_resources[] __initdata = { ++static const struct resource cmt00_resources[] __initconst = { + DEFINE_RES_MEM(0xffca0510, 0x0c), + DEFINE_RES_MEM(0xffca0500, 0x04), + DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */ +@@ -276,7 +277,7 @@ void __init r8a7790_init_early(void) + + #ifdef CONFIG_USE_OF + +-static const char *r8a7790_boards_compat_dt[] __initdata = { ++static const char * const r8a7790_boards_compat_dt[] __initconst = { + "renesas,r8a7790", + NULL, + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0120-ARM-shmobile-ape6evm-reference-add-MMCIF-and-SDHI-DT.patch b/patches.renesas/0120-ARM-shmobile-ape6evm-reference-add-MMCIF-and-SDHI-DT.patch new file mode 100644 index 00000000000000..b89d8ff8b055c1 --- /dev/null +++ b/patches.renesas/0120-ARM-shmobile-ape6evm-reference-add-MMCIF-and-SDHI-DT.patch @@ -0,0 +1,115 @@ +From e89eca4c66e9f4698be534106d9afc4a481daacd Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Thu, 1 Aug 2013 09:41:21 +0200 +Subject: ARM: shmobile: ape6evm-reference: add MMCIF and SDHI DT nodes + +This patch adds MMCIF0, SDHI0 and SDHI1 DT nodes and a fixed voltage +reglator for them to the ape6evm-reference platform. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit dbffb5a1525dc88f1c871c48574634f14845b43d) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts | 72 +++++++++++++++++++++++++ + 1 file changed, 72 insertions(+) + +diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts b/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts +index f444624eb097..2b49b05ae2f4 100644 +--- a/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts ++++ b/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts +@@ -10,6 +10,7 @@ + + /dts-v1/; + /include/ "r8a73a4.dtsi" ++#include <dt-bindings/gpio/gpio.h> + + / { + model = "APE6EVM"; +@@ -24,6 +25,34 @@ + reg = <0 0x40000000 0 0x40000000>; + }; + ++ vcc_mmc0: regulator@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "MMC0 Vcc"; ++ regulator-min-microvolt = <2800000>; ++ regulator-max-microvolt = <2800000>; ++ regulator-always-on; ++ }; ++ ++ vcc_sdhi0: regulator@1 { ++ compatible = "regulator-fixed"; ++ ++ regulator-name = "SDHI0 Vcc"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ gpio = <&pfc 76 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ }; ++ ++ /* Common 3.3V rail, used by several devices on APE6EVM */ ++ ape6evm_fixed_3v3: regulator@2 { ++ compatible = "regulator-fixed"; ++ regulator-name = "3V3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ }; ++ + lbsc { + compatible = "simple-bus"; + #address-cells = <1>; +@@ -62,4 +91,47 @@ + renesas,groups = "scifa0_data"; + renesas,function = "scifa0"; + }; ++ ++ mmc0_pins: mmcif { ++ renesas,groups = "mmc0_data8", "mmc0_ctrl"; ++ renesas,function = "mmc0"; ++ }; ++ ++ sdhi0_pins: sdhi0 { ++ renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_cd"; ++ renesas,function = "sdhi0"; ++ }; ++ ++ sdhi1_pins: sdhi1 { ++ renesas,groups = "sdhi1_data4", "sdhi1_ctrl"; ++ renesas,function = "sdhi1"; ++ }; ++}; ++ ++&mmcif0 { ++ vmmc-supply = <&vcc_mmc0>; ++ bus-width = <8>; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc0_pins>; ++ status = "okay"; ++}; ++ ++&sdhi0 { ++ vmmc-supply = <&vcc_sdhi0>; ++ bus-width = <4>; ++ toshiba,mmc-wrprotect-disable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdhi0_pins>; ++ status = "okay"; ++}; ++ ++&sdhi1 { ++ vmmc-supply = <&ape6evm_fixed_3v3>; ++ bus-width = <4>; ++ broken-cd; ++ toshiba,mmc-wrprotect-disable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdhi1_pins>; ++ status = "okay"; + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0121-ARM-shmobile-r8a7779-Rename-DU-device-in-clock-looku.patch b/patches.renesas/0121-ARM-shmobile-r8a7779-Rename-DU-device-in-clock-looku.patch new file mode 100644 index 00000000000000..470f2ac492ca31 --- /dev/null +++ b/patches.renesas/0121-ARM-shmobile-r8a7779-Rename-DU-device-in-clock-looku.patch @@ -0,0 +1,33 @@ +From 9b031780c5f1e5313c42c6f2fb12ce2fd73edad2 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 8 Aug 2013 04:25:00 +0200 +Subject: ARM: shmobile: r8a7779: Rename DU device in clock lookups list + +The DU device will be called rcar-du-r8a7779. Rename the clock lookup +entry accordingly. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit acf47ee741c4a5eb8a17438e8858f1cffa1e073a) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/clock-r8a7779.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c +index bd6ad922eb7e..1f7080fab0a5 100644 +--- a/arch/arm/mach-shmobile/clock-r8a7779.c ++++ b/arch/arm/mach-shmobile/clock-r8a7779.c +@@ -200,7 +200,7 @@ static struct clk_lookup lookups[] = { + CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP322]), /* SDHI1 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP321]), /* SDHI2 */ + CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP320]), /* SDHI3 */ +- CLKDEV_DEV_ID("rcar-du.0", &mstp_clks[MSTP103]), /* DU */ ++ CLKDEV_DEV_ID("rcar-du-r8a7779", &mstp_clks[MSTP103]), /* DU */ + }; + + void __init r8a7779_clock_init(void) +-- +1.8.5.rc3 + diff --git a/patches.renesas/0122-ARM-shmobile-r8a7790-Add-DU-and-LVDS-clocks.patch b/patches.renesas/0122-ARM-shmobile-r8a7790-Add-DU-and-LVDS-clocks.patch new file mode 100644 index 00000000000000..f369f327344ade --- /dev/null +++ b/patches.renesas/0122-ARM-shmobile-r8a7790-Add-DU-and-LVDS-clocks.patch @@ -0,0 +1,54 @@ +From a334d931b59164743fe2ed0485b1fbfefb4ba722 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Wed, 17 Apr 2013 11:33:56 +0200 +Subject: ARM: shmobile: r8a7790: Add DU and LVDS clocks + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 9d8907c4e8c97127c562055ac7e1a8ea39ea589c) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/clock-r8a7790.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c +index fc36d3db0b4d..d99b87bc76ea 100644 +--- a/arch/arm/mach-shmobile/clock-r8a7790.c ++++ b/arch/arm/mach-shmobile/clock-r8a7790.c +@@ -182,7 +182,7 @@ static struct clk div6_clks[DIV6_NR] = { + /* MSTP */ + enum { + MSTP813, +- MSTP721, MSTP720, ++ MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720, + MSTP717, MSTP716, + MSTP522, + MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304, +@@ -193,6 +193,11 @@ enum { + + static struct clk mstp_clks[MSTP_NR] = { + [MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */ ++ [MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */ ++ [MSTP725] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 25, 0), /* LVDS1 */ ++ [MSTP724] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 24, 0), /* DU0 */ ++ [MSTP723] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 23, 0), /* DU1 */ ++ [MSTP722] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 22, 0), /* DU2 */ + [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */ + [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */ + [MSTP717] = SH_CLK_MSTP32(&zs_clk, SMSTPCR7, 17, 0), /* HSCIF0 */ +@@ -251,6 +256,11 @@ static struct clk_lookup lookups[] = { + CLKDEV_CON_ID("ssprs", &div6_clks[DIV6_SSPRS]), + + /* MSTP */ ++ CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7790", &mstp_clks[MSTP726]), ++ CLKDEV_ICK_ID("lvds.1", "rcar-du-r8a7790", &mstp_clks[MSTP725]), ++ CLKDEV_ICK_ID("du.0", "rcar-du-r8a7790", &mstp_clks[MSTP724]), ++ CLKDEV_ICK_ID("du.1", "rcar-du-r8a7790", &mstp_clks[MSTP723]), ++ CLKDEV_ICK_ID("du.2", "rcar-du-r8a7790", &mstp_clks[MSTP722]), + CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), + CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), + CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), +-- +1.8.5.rc3 + diff --git a/patches.renesas/0123-ARM-shmobile-r8a7778-add-SSI-SRU-clock-support.patch b/patches.renesas/0123-ARM-shmobile-r8a7778-add-SSI-SRU-clock-support.patch new file mode 100644 index 00000000000000..8a00b7bc4da438 --- /dev/null +++ b/patches.renesas/0123-ARM-shmobile-r8a7778-add-SSI-SRU-clock-support.patch @@ -0,0 +1,115 @@ +From 083e84b0065ca78bd903068d2f6e1f861da1716f Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Mon, 26 Aug 2013 01:51:37 -0700 +Subject: ARM: shmobile: r8a7778: add SSI/SRU clock support + +Add a platform clock for the r8a7778 SRU/SSI sound. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit a93c2aaf18e0e10084c099a0ba2460ab8e3c0e05) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/clock-r8a7778.c | 43 ++++++++++++++++++++++++++++++++-- + 1 file changed, 41 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c +index c4bf2d8fb111..244a8dec4d04 100644 +--- a/arch/arm/mach-shmobile/clock-r8a7778.c ++++ b/arch/arm/mach-shmobile/clock-r8a7778.c +@@ -69,6 +69,15 @@ static struct clk extal_clk = { + .mapping = &cpg_mapping, + }; + ++static struct clk audio_clk_a = { ++}; ++ ++static struct clk audio_clk_b = { ++}; ++ ++static struct clk audio_clk_c = { ++}; ++ + /* + * clock ratio of these clock will be updated + * on r8a7778_clock_init() +@@ -100,18 +109,23 @@ static struct clk *main_clks[] = { + &p_clk, + &g_clk, + &z_clk, ++ &audio_clk_a, ++ &audio_clk_b, ++ &audio_clk_c, + }; + + enum { + MSTP331, + MSTP323, MSTP322, MSTP321, ++ MSTP311, MSTP310, ++ MSTP309, MSTP308, MSTP307, + MSTP114, + MSTP110, MSTP109, + MSTP100, + MSTP030, + MSTP029, MSTP028, MSTP027, MSTP026, MSTP025, MSTP024, MSTP023, MSTP022, MSTP021, +- MSTP016, MSTP015, +- MSTP007, ++ MSTP016, MSTP015, MSTP012, MSTP011, MSTP010, ++ MSTP009, MSTP008, MSTP007, + MSTP_NR }; + + static struct clk mstp_clks[MSTP_NR] = { +@@ -119,6 +133,11 @@ static struct clk mstp_clks[MSTP_NR] = { + [MSTP323] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 23, 0), /* SDHI0 */ + [MSTP322] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 22, 0), /* SDHI1 */ + [MSTP321] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 21, 0), /* SDHI2 */ ++ [MSTP311] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 11, 0), /* SSI4 */ ++ [MSTP310] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 10, 0), /* SSI5 */ ++ [MSTP309] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 9, 0), /* SSI6 */ ++ [MSTP308] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 8, 0), /* SSI7 */ ++ [MSTP307] = SH_CLK_MSTP32(&p_clk, MSTPCR3, 7, 0), /* SSI8 */ + [MSTP114] = SH_CLK_MSTP32(&p_clk, MSTPCR1, 14, 0), /* Ether */ + [MSTP110] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 10, 0), /* VIN0 */ + [MSTP109] = SH_CLK_MSTP32(&s_clk, MSTPCR1, 9, 0), /* VIN1 */ +@@ -135,11 +154,20 @@ static struct clk mstp_clks[MSTP_NR] = { + [MSTP021] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 21, 0), /* SCIF5 */ + [MSTP016] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 16, 0), /* TMU0 */ + [MSTP015] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 15, 0), /* TMU1 */ ++ [MSTP012] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 12, 0), /* SSI0 */ ++ [MSTP011] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 11, 0), /* SSI1 */ ++ [MSTP010] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 10, 0), /* SSI2 */ ++ [MSTP009] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 9, 0), /* SSI3 */ ++ [MSTP008] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 8, 0), /* SRU */ + [MSTP007] = SH_CLK_MSTP32(&p_clk, MSTPCR0, 7, 0), /* HSPI */ + }; + + static struct clk_lookup lookups[] = { + /* main */ ++ CLKDEV_CON_ID("audio_clk_a", &audio_clk_a), ++ CLKDEV_CON_ID("audio_clk_b", &audio_clk_b), ++ CLKDEV_CON_ID("audio_clk_c", &audio_clk_c), ++ CLKDEV_CON_ID("audio_clk_internal", &s1_clk), + CLKDEV_CON_ID("shyway_clk", &s_clk), + CLKDEV_CON_ID("peripheral_clk", &p_clk), + +@@ -168,6 +196,17 @@ static struct clk_lookup lookups[] = { + CLKDEV_DEV_ID("sh-hspi.0", &mstp_clks[MSTP007]), /* HSPI0 */ + CLKDEV_DEV_ID("sh-hspi.1", &mstp_clks[MSTP007]), /* HSPI1 */ + CLKDEV_DEV_ID("sh-hspi.2", &mstp_clks[MSTP007]), /* HSPI2 */ ++ CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP008]), /* SRU */ ++ ++ CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP012]), ++ CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP011]), ++ CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP010]), ++ CLKDEV_ICK_ID("ssi.3", "rcar_sound", &mstp_clks[MSTP009]), ++ CLKDEV_ICK_ID("ssi.4", "rcar_sound", &mstp_clks[MSTP311]), ++ CLKDEV_ICK_ID("ssi.5", "rcar_sound", &mstp_clks[MSTP310]), ++ CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP309]), ++ CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP308]), ++ CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP307]), + }; + + void __init r8a7778_clock_init(void) +-- +1.8.5.rc3 + diff --git a/patches.renesas/0124-ARM-shmobile-marzen-Select-DRM_RCAR_DU-in-defconfig.patch b/patches.renesas/0124-ARM-shmobile-marzen-Select-DRM_RCAR_DU-in-defconfig.patch new file mode 100644 index 00000000000000..ff8bc6b701d432 --- /dev/null +++ b/patches.renesas/0124-ARM-shmobile-marzen-Select-DRM_RCAR_DU-in-defconfig.patch @@ -0,0 +1,33 @@ +From 7293c14f3307fcf77c18da0a560bfaafe243ffd3 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 8 Aug 2013 00:45:12 +0200 +Subject: ARM: shmobile: marzen: Select DRM_RCAR_DU in defconfig + +A R-Car DU DRM device is registered for the Marzen board, select the +corresponding driver in its defconfig. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 7525e87b468a1b2d8e3f0156e36acd8992af673c) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/configs/marzen_defconfig | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/configs/marzen_defconfig b/arch/arm/configs/marzen_defconfig +index 000e9205b2b9..5cc6360340b1 100644 +--- a/arch/arm/configs/marzen_defconfig ++++ b/arch/arm/configs/marzen_defconfig +@@ -92,6 +92,8 @@ CONFIG_SOC_CAMERA=y + CONFIG_VIDEO_RCAR_VIN=y + # CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set + CONFIG_VIDEO_ADV7180=y ++CONFIG_DRM=y ++CONFIG_DRM_RCAR_DU=y + CONFIG_USB=y + CONFIG_USB_RCAR_PHY=y + CONFIG_MMC=y +-- +1.8.5.rc3 + diff --git a/patches.renesas/0125-ARM-shmobile-lager-Select-DRM_RCAR_DU-in-defconfig.patch b/patches.renesas/0125-ARM-shmobile-lager-Select-DRM_RCAR_DU-in-defconfig.patch new file mode 100644 index 00000000000000..baee917a402295 --- /dev/null +++ b/patches.renesas/0125-ARM-shmobile-lager-Select-DRM_RCAR_DU-in-defconfig.patch @@ -0,0 +1,33 @@ +From 2b7a8236ad17a2ed51be0aa1c73e16264f452c6a Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 8 Aug 2013 00:47:57 +0200 +Subject: ARM: shmobile: lager: Select DRM_RCAR_DU in defconfig + +A R-Car DU DRM device is registered for the Lager board, select the +corresponding driver in its defconfig. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 57601184cefb36db8c1959d277918bdabb6b1c64) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/configs/lager_defconfig | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/configs/lager_defconfig b/arch/arm/configs/lager_defconfig +index e777ef22b801..35bff5e0d57a 100644 +--- a/arch/arm/configs/lager_defconfig ++++ b/arch/arm/configs/lager_defconfig +@@ -89,6 +89,8 @@ CONFIG_THERMAL=y + CONFIG_RCAR_THERMAL=y + CONFIG_REGULATOR=y + CONFIG_REGULATOR_FIXED_VOLTAGE=y ++CONFIG_DRM=y ++CONFIG_DRM_RCAR_DU=y + # CONFIG_USB_SUPPORT is not set + CONFIG_MMC=y + CONFIG_MMC_SDHI=y +-- +1.8.5.rc3 + diff --git a/patches.renesas/0126-ARM-shmobile-bockw-defconfig-add-Sound-support.patch b/patches.renesas/0126-ARM-shmobile-bockw-defconfig-add-Sound-support.patch new file mode 100644 index 00000000000000..b735544d8bb3e4 --- /dev/null +++ b/patches.renesas/0126-ARM-shmobile-bockw-defconfig-add-Sound-support.patch @@ -0,0 +1,31 @@ +From 529b90dfdb335ef9baf2b4f5cd97d25ae0724060 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Mon, 26 Aug 2013 01:52:45 -0700 +Subject: ARM: shmobile: bockw defconfig: add Sound support + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit dca778f1e470494019e41e9eef073eb981a64380) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/configs/bockw_defconfig | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm/configs/bockw_defconfig b/arch/arm/configs/bockw_defconfig +index e7e94948d194..b38cd107f82d 100644 +--- a/arch/arm/configs/bockw_defconfig ++++ b/arch/arm/configs/bockw_defconfig +@@ -91,6 +91,10 @@ CONFIG_VIDEO_RCAR_VIN=y + CONFIG_VIDEO_ML86V7667=y + CONFIG_SPI=y + CONFIG_SPI_SH_HSPI=y ++CONFIG_SOUND=y ++CONFIG_SND=y ++CONFIG_SND_SOC=y ++CONFIG_SND_SOC_RCAR=y + CONFIG_USB=y + CONFIG_USB_ANNOUNCE_NEW_DEVICES=y + CONFIG_USB_EHCI_HCD=y +-- +1.8.5.rc3 + diff --git a/patches.renesas/0127-ARM-shmobile-Add-koelsch-defconfig.patch b/patches.renesas/0127-ARM-shmobile-Add-koelsch-defconfig.patch new file mode 100644 index 00000000000000..ba206c0678da80 --- /dev/null +++ b/patches.renesas/0127-ARM-shmobile-Add-koelsch-defconfig.patch @@ -0,0 +1,82 @@ +From 5bc6fa139b7874cb5dfa8a09a4a97f22c7b6fe11 Mon Sep 17 00:00:00 2001 +From: Simon Horman <horms+renesas@verge.net.au> +Date: Wed, 4 Sep 2013 17:04:08 +0900 +Subject: ARM: shmobile: Add koelsch defconfig + +This is intended to be used until multi-arch is able to be +used for the koelsch board at which time a more generic configuration +will be used in place of this one. + +This is based on the lager defconfig. + +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 6bb2e347899b297eea26f2658eac8fdcd633fba5) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/configs/koelsch_defconfig | 54 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 54 insertions(+) + create mode 100644 arch/arm/configs/koelsch_defconfig + +diff --git a/arch/arm/configs/koelsch_defconfig b/arch/arm/configs/koelsch_defconfig +new file mode 100644 +index 000000000000..825c16dee8a0 +--- /dev/null ++++ b/arch/arm/configs/koelsch_defconfig +@@ -0,0 +1,54 @@ ++CONFIG_SYSVIPC=y ++CONFIG_NO_HZ=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_LOG_BUF_SHIFT=16 ++CONFIG_CC_OPTIMIZE_FOR_SIZE=y ++CONFIG_SYSCTL_SYSCALL=y ++CONFIG_EMBEDDED=y ++CONFIG_PERF_EVENTS=y ++CONFIG_SLAB=y ++# CONFIG_BLOCK is not set ++CONFIG_ARCH_SHMOBILE=y ++CONFIG_ARCH_R8A7791=y ++CONFIG_MACH_KOELSCH=y ++# CONFIG_SWP_EMULATE is not set ++CONFIG_CPU_BPREDICT_DISABLE=y ++CONFIG_PL310_ERRATA_588369=y ++CONFIG_ARM_ERRATA_754322=y ++CONFIG_SMP=y ++CONFIG_SCHED_MC=y ++CONFIG_NR_CPUS=8 ++CONFIG_AEABI=y ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_ARM_APPENDED_DTB=y ++CONFIG_KEXEC=y ++CONFIG_AUTO_ZRELADDR=y ++CONFIG_VFP=y ++CONFIG_NEON=y ++# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set ++CONFIG_PM_RUNTIME=y ++CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" ++# CONFIG_INPUT_MOUSEDEV_PSAUX is not set ++# CONFIG_INPUT_MOUSE is not set ++# CONFIG_LEGACY_PTYS is not set ++CONFIG_SERIAL_SH_SCI=y ++CONFIG_SERIAL_SH_SCI_NR_UARTS=20 ++CONFIG_SERIAL_SH_SCI_CONSOLE=y ++# CONFIG_HWMON is not set ++CONFIG_THERMAL=y ++CONFIG_RCAR_THERMAL=y ++# CONFIG_HID is not set ++# CONFIG_USB_SUPPORT is not set ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++# CONFIG_IOMMU_SUPPORT is not set ++# CONFIG_DNOTIFY is not set ++# CONFIG_INOTIFY_USER is not set ++CONFIG_TMPFS=y ++CONFIG_CONFIGFS_FS=y ++# CONFIG_MISC_FILESYSTEMS is not set ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++# CONFIG_ARM_UNWIND is not set +-- +1.8.5.rc3 + diff --git a/patches.renesas/0128-ARM-shmobile-Introduce-shmobile_smp_cpu_disable.patch b/patches.renesas/0128-ARM-shmobile-Introduce-shmobile_smp_cpu_disable.patch new file mode 100644 index 00000000000000..e24a44692bb14f --- /dev/null +++ b/patches.renesas/0128-ARM-shmobile-Introduce-shmobile_smp_cpu_disable.patch @@ -0,0 +1,48 @@ +From 1fa4f5b3348ba0018b47664cc621ca1e71c557c3 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 8 Aug 2013 07:13:30 +0900 +Subject: ARM: shmobile: Introduce shmobile_smp_cpu_disable() + +Introduce the shared CPU Hotplug function shmobile_smp_cpu_disable() +for mach-shmobile. It is useful for the case when all CPUs may be +hotplugged, including CPU 0. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 5c4dfcd663b6e96cc20f02dc2c7c315749ea1bc1) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/include/mach/common.h | 1 + + arch/arm/mach-shmobile/platsmp.c | 7 +++++++ + 2 files changed, 8 insertions(+) + +diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h +index 7b938681e756..1ed155eb3e92 100644 +--- a/arch/arm/mach-shmobile/include/mach/common.h ++++ b/arch/arm/mach-shmobile/include/mach/common.h +@@ -13,6 +13,7 @@ extern void shmobile_smp_boot(void); + extern void shmobile_smp_sleep(void); + extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, + unsigned long arg); ++extern int shmobile_smp_cpu_disable(unsigned int cpu); + extern void shmobile_boot_scu(void); + extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); + extern int shmobile_smp_scu_boot_secondary(unsigned int cpu, +diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c +index d4ae616bcedb..3741562156ed 100644 +--- a/arch/arm/mach-shmobile/platsmp.c ++++ b/arch/arm/mach-shmobile/platsmp.c +@@ -44,3 +44,10 @@ void shmobile_smp_hook(unsigned int cpu, unsigned long fn, unsigned long arg) + shmobile_smp_arg[cpu] = arg; + flush_cache_all(); + } ++ ++#ifdef CONFIG_HOTPLUG_CPU ++int shmobile_smp_cpu_disable(unsigned int cpu) ++{ ++ return 0; /* Hotplug of any CPU is supported */ ++} ++#endif +-- +1.8.5.rc3 + diff --git a/patches.renesas/0129-ARM-shmobile-Use-shmobile_smp_cpu_disable-on-sh73a0.patch b/patches.renesas/0129-ARM-shmobile-Use-shmobile_smp_cpu_disable-on-sh73a0.patch new file mode 100644 index 00000000000000..230a5faa741567 --- /dev/null +++ b/patches.renesas/0129-ARM-shmobile-Use-shmobile_smp_cpu_disable-on-sh73a0.patch @@ -0,0 +1,43 @@ +From 8d9ef994e3a0873b1051fcab3414b2927a9a5d41 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 8 Aug 2013 07:13:39 +0900 +Subject: ARM: shmobile: Use shmobile_smp_cpu_disable() on sh73a0 + +Use shmobile_smp_cpu_disable() on sh73a0 since it +allows CPU Hotplug of any CPU. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit a3b142a1a08af543473ae726e5d96a969c5b02b5) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/smp-sh73a0.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c +index 8b3b9777056b..25ddffc96bcf 100644 +--- a/arch/arm/mach-shmobile/smp-sh73a0.c ++++ b/arch/arm/mach-shmobile/smp-sh73a0.c +@@ -71,18 +71,11 @@ static void __init sh73a0_smp_prepare_cpus(unsigned int max_cpus) + shmobile_smp_scu_prepare_cpus(max_cpus); + } + +-#ifdef CONFIG_HOTPLUG_CPU +-static int sh73a0_cpu_disable(unsigned int cpu) +-{ +- return 0; /* CPU0 and CPU1 supported */ +-} +-#endif /* CONFIG_HOTPLUG_CPU */ +- + struct smp_operations sh73a0_smp_ops __initdata = { + .smp_prepare_cpus = sh73a0_smp_prepare_cpus, + .smp_boot_secondary = sh73a0_boot_secondary, + #ifdef CONFIG_HOTPLUG_CPU +- .cpu_disable = sh73a0_cpu_disable, ++ .cpu_disable = shmobile_smp_cpu_disable, + .cpu_die = shmobile_smp_scu_cpu_die, + .cpu_kill = shmobile_smp_scu_cpu_kill, + #endif +-- +1.8.5.rc3 + diff --git a/patches.renesas/0130-ARM-shmobile-Remove-unused-shmobile_smp_init_cpus.patch b/patches.renesas/0130-ARM-shmobile-Remove-unused-shmobile_smp_init_cpus.patch new file mode 100644 index 00000000000000..37859a41532561 --- /dev/null +++ b/patches.renesas/0130-ARM-shmobile-Remove-unused-shmobile_smp_init_cpus.patch @@ -0,0 +1,63 @@ +From 53f0cf8e1944da224a6d07f6c91b40af98ce142f Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 8 Aug 2013 07:13:49 +0900 +Subject: ARM: shmobile: Remove unused shmobile_smp_init_cpus() + +Remove shmobile_smp_init_cpus() since all SMP platforms in +mach-shmobile now rely on DT for CPU core description instead +of for instance determining number of cores from the SCU. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit c4e1e64d2b6a921a57629ede635f81f5d2882543) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/include/mach/common.h | 1 - + arch/arm/mach-shmobile/platsmp.c | 15 --------------- + 2 files changed, 16 deletions(-) + +diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h +index 1ed155eb3e92..26eaff1429bf 100644 +--- a/arch/arm/mach-shmobile/include/mach/common.h ++++ b/arch/arm/mach-shmobile/include/mach/common.h +@@ -40,7 +40,6 @@ static inline int shmobile_cpuidle_init(void) { return 0; } + #endif + + extern void __iomem *shmobile_scu_base; +-extern void shmobile_smp_init_cpus(unsigned int ncores); + + static inline void __init shmobile_init_late(void) + { +diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c +index 3741562156ed..9ebc246b8d7d 100644 +--- a/arch/arm/mach-shmobile/platsmp.c ++++ b/arch/arm/mach-shmobile/platsmp.c +@@ -11,25 +11,10 @@ + * published by the Free Software Foundation. + */ + #include <linux/init.h> +-#include <linux/smp.h> + #include <asm/cacheflush.h> + #include <asm/smp_plat.h> + #include <mach/common.h> + +-void __init shmobile_smp_init_cpus(unsigned int ncores) +-{ +- unsigned int i; +- +- if (ncores > nr_cpu_ids) { +- pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", +- ncores, nr_cpu_ids); +- ncores = nr_cpu_ids; +- } +- +- for (i = 0; i < ncores; i++) +- set_cpu_possible(i, true); +-} +- + extern unsigned long shmobile_smp_fn[]; + extern unsigned long shmobile_smp_arg[]; + extern unsigned long shmobile_smp_mpidr[]; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0131-ARM-shmobile-Expose-shmobile_invalidate_start.patch b/patches.renesas/0131-ARM-shmobile-Expose-shmobile_invalidate_start.patch new file mode 100644 index 00000000000000..c64a475a110c73 --- /dev/null +++ b/patches.renesas/0131-ARM-shmobile-Expose-shmobile_invalidate_start.patch @@ -0,0 +1,32 @@ +From 8737a9d02e1f0eecedea71db8c24a0909bc53b85 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 8 Aug 2013 07:13:58 +0900 +Subject: ARM: shmobile: Expose shmobile_invalidate_start() + +Expose shmobile_invalidate_start() in common.h for +mach-shmobile. This function will be used for boot of +secondary processors on future non-SCU SMP platforms. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 87a08ca0f7f99b3136c763377c547a89cf6d0996) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/include/mach/common.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h +index 26eaff1429bf..a9df8f3bfda7 100644 +--- a/arch/arm/mach-shmobile/include/mach/common.h ++++ b/arch/arm/mach-shmobile/include/mach/common.h +@@ -14,6 +14,7 @@ extern void shmobile_smp_sleep(void); + extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, + unsigned long arg); + extern int shmobile_smp_cpu_disable(unsigned int cpu); ++extern void shmobile_invalidate_start(void); + extern void shmobile_boot_scu(void); + extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); + extern int shmobile_smp_scu_boot_secondary(unsigned int cpu, +-- +1.8.5.rc3 + diff --git a/patches.renesas/0132-ARM-shmobile-Introduce-shmobile_boot_size.patch b/patches.renesas/0132-ARM-shmobile-Introduce-shmobile_boot_size.patch new file mode 100644 index 00000000000000..7f8a881dc7d217 --- /dev/null +++ b/patches.renesas/0132-ARM-shmobile-Introduce-shmobile_boot_size.patch @@ -0,0 +1,47 @@ +From b7d6022a2aca4c82e15c80a34557accbcd17b4e7 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 8 Aug 2013 07:14:07 +0900 +Subject: ARM: shmobile: Introduce shmobile_boot_size + +Introduce shmobile_boot_size that can be used by +future SMP code to determine the size of the boot +code that needs to be copied to internal SRAM. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit a84a5ab73f77a5dd4f09f0af33f09d8d751d0cc7) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/headsmp.S | 3 +++ + arch/arm/mach-shmobile/include/mach/common.h | 1 + + 2 files changed, 4 insertions(+) + +diff --git a/arch/arm/mach-shmobile/headsmp.S b/arch/arm/mach-shmobile/headsmp.S +index a8cabee4c5ee..289ef8657afa 100644 +--- a/arch/arm/mach-shmobile/headsmp.S ++++ b/arch/arm/mach-shmobile/headsmp.S +@@ -42,6 +42,9 @@ shmobile_boot_fn: + .globl shmobile_boot_arg + shmobile_boot_arg: + 2: .space 4 ++ .globl shmobile_boot_size ++shmobile_boot_size: ++ .long . - shmobile_boot_vector + + /* + * Per-CPU SMP boot function/argument selection code based on MPIDR +diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h +index a9df8f3bfda7..cfe397716fd1 100644 +--- a/arch/arm/mach-shmobile/include/mach/common.h ++++ b/arch/arm/mach-shmobile/include/mach/common.h +@@ -9,6 +9,7 @@ extern void shmobile_setup_console(void); + extern void shmobile_boot_vector(void); + extern unsigned long shmobile_boot_fn; + extern unsigned long shmobile_boot_arg; ++extern unsigned long shmobile_boot_size; + extern void shmobile_smp_boot(void); + extern void shmobile_smp_sleep(void); + extern void shmobile_smp_hook(unsigned int cpu, unsigned long fn, +-- +1.8.5.rc3 + diff --git a/patches.renesas/0133-ARM-shmobile-r8a7778-cleanup-registration-of-vin.patch b/patches.renesas/0133-ARM-shmobile-r8a7778-cleanup-registration-of-vin.patch new file mode 100644 index 00000000000000..edbc91dd6a89c6 --- /dev/null +++ b/patches.renesas/0133-ARM-shmobile-r8a7778-cleanup-registration-of-vin.patch @@ -0,0 +1,146 @@ +From 72e326cb70881c0df16b8d9b9fad12cbd4eac886 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Mon, 23 Sep 2013 23:04:10 -0700 +Subject: ARM: shmobile: r8a7778: cleanup registration of vin + +vin driver which needs platform data at the time of +registration is used from BockW only. +Now, ARM/shmobile aims to support DT, +and the C code base board support will be removed +if DT support is completed. +Current driver registration method which needs platform data +and which is not shared complicates codes. +This means legacy C code cleanup after DT supporting +will be more complicated +This patch registers it on board code as cleanup C code + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit fd131d0d4024a39259c41290451e728515ed7300) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-bockw.c | 32 ++++++++++++++++++++----- + arch/arm/mach-shmobile/include/mach/r8a7778.h | 2 -- + arch/arm/mach-shmobile/setup-r8a7778.c | 34 --------------------------- + 3 files changed, 26 insertions(+), 42 deletions(-) + +diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c +index 6b9faf3908f7..4b696ce0bae6 100644 +--- a/arch/arm/mach-shmobile/board-bockw.c ++++ b/arch/arm/mach-shmobile/board-bockw.c +@@ -162,10 +162,6 @@ static struct sh_mmcif_plat_data sh_mmcif_plat __initdata = { + MMC_CAP_NEEDS_POLL, + }; + +-static struct rcar_vin_platform_data vin_platform_data __initdata = { +- .flags = RCAR_VIN_BT656, +-}; +- + /* In the default configuration both decoders reside on I2C bus 0 */ + #define BOCKW_CAMERA(idx) \ + static struct i2c_board_info camera##idx##_info = { \ +@@ -181,6 +177,30 @@ static struct soc_camera_link iclink##idx##_ml86v7667 __initdata = { \ + BOCKW_CAMERA(0); + BOCKW_CAMERA(1); + ++/* VIN */ ++static struct rcar_vin_platform_data vin_platform_data __initdata = { ++ .flags = RCAR_VIN_BT656, ++}; ++ ++#define R8A7778_VIN(idx) \ ++static struct resource vin##idx##_resources[] __initdata = { \ ++ DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \ ++ DEFINE_RES_IRQ(gic_iid(0x5a)), \ ++}; \ ++ \ ++static struct platform_device_info vin##idx##_info __initdata = { \ ++ .parent = &platform_bus, \ ++ .name = "r8a7778-vin", \ ++ .id = idx, \ ++ .res = vin##idx##_resources, \ ++ .num_res = ARRAY_SIZE(vin##idx##_resources), \ ++ .dma_mask = DMA_BIT_MASK(32), \ ++ .data = &vin_platform_data, \ ++ .size_data = sizeof(vin_platform_data), \ ++} ++R8A7778_VIN(0); ++R8A7778_VIN(1); ++ + static const struct pinctrl_map bockw_pinctrl_map[] = { + /* Ether */ + PIN_MAP_MUX_GROUP_DEFAULT("r8a777x-ether", "pfc-r8a7778", +@@ -236,10 +256,10 @@ static void __init bockw_init(void) + r8a7778_init_irq_extpin(1); + r8a7778_add_standard_devices(); + r8a7778_add_ether_device(ðer_platform_data); +- r8a7778_add_vin_device(0, &vin_platform_data); ++ platform_device_register_full(&vin0_info); + /* VIN1 has a pin conflict with Ether */ + if (!IS_ENABLED(CONFIG_SH_ETH)) +- r8a7778_add_vin_device(1, &vin_platform_data); ++ platform_device_register_full(&vin1_info); + platform_device_register_data(&platform_bus, "soc-camera-pdrv", 0, + &iclink0_ml86v7667, + sizeof(iclink0_ml86v7667)); +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h +index adfcf51b163d..9838608363c2 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a7778.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h +@@ -24,8 +24,6 @@ + extern void r8a7778_add_standard_devices(void); + extern void r8a7778_add_standard_devices_dt(void); + extern void r8a7778_add_ether_device(struct sh_eth_plat_data *pdata); +-extern void r8a7778_add_vin_device(int id, +- struct rcar_vin_platform_data *pdata); + extern void r8a7778_add_dt_devices(void); + + extern void r8a7778_init_late(void); +diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c +index 6a2657ebd197..604cf36b5616 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7778.c ++++ b/arch/arm/mach-shmobile/setup-r8a7778.c +@@ -281,40 +281,6 @@ void __init r8a7778_register_hspi(int id) + hspi_resources + (2 * id), 2); + } + +-/* VIN */ +-#define R8A7778_VIN(idx) \ +-static struct resource vin##idx##_resources[] __initdata = { \ +- DEFINE_RES_MEM(0xffc50000 + 0x1000 * (idx), 0x1000), \ +- DEFINE_RES_IRQ(gic_iid(0x5a)), \ +-}; \ +- \ +-static struct platform_device_info vin##idx##_info __initdata = { \ +- .parent = &platform_bus, \ +- .name = "r8a7778-vin", \ +- .id = idx, \ +- .res = vin##idx##_resources, \ +- .num_res = ARRAY_SIZE(vin##idx##_resources), \ +- .dma_mask = DMA_BIT_MASK(32), \ +-} +- +-R8A7778_VIN(0); +-R8A7778_VIN(1); +- +-static struct platform_device_info *vin_info_table[] __initdata = { +- &vin0_info, +- &vin1_info, +-}; +- +-void __init r8a7778_add_vin_device(int id, struct rcar_vin_platform_data *pdata) +-{ +- BUG_ON(id < 0 || id > 1); +- +- vin_info_table[id]->data = pdata; +- vin_info_table[id]->size_data = sizeof(*pdata); +- +- platform_device_register_full(vin_info_table[id]); +-} +- + void __init r8a7778_add_dt_devices(void) + { + int i; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0134-ARM-shmobile-r8a7778-cleanup-registration-of-sh_eth.patch b/patches.renesas/0134-ARM-shmobile-r8a7778-cleanup-registration-of-sh_eth.patch new file mode 100644 index 00000000000000..8e8a6512e280a1 --- /dev/null +++ b/patches.renesas/0134-ARM-shmobile-r8a7778-cleanup-registration-of-sh_eth.patch @@ -0,0 +1,98 @@ +From 07488c0f5c51f7361f7ec9bb202bdc50c762525d Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Mon, 23 Sep 2013 23:04:21 -0700 +Subject: ARM: shmobile: r8a7778: cleanup registration of sh_eth + +sh_eth driver which needs platform data at the time of +registration is used from BockW only. +Now, ARM/shmobile aims to support DT, +and the C code base board support will be removed +if DT support is completed. +Current driver registration method which needs platform data +and which is not shared complicates codes. +This means legacy C code cleanup after DT supporting +will be more complicated +This patch registers it on board code as cleanup C code + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit cd4ab0420fd6233766fd87fa295d6e3cfb719c01) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-bockw.c | 14 +++++++++++++- + arch/arm/mach-shmobile/include/mach/r8a7778.h | 1 - + arch/arm/mach-shmobile/setup-r8a7778.c | 14 -------------- + 3 files changed, 13 insertions(+), 16 deletions(-) + +diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c +index 4b696ce0bae6..f2bf61bf2521 100644 +--- a/arch/arm/mach-shmobile/board-bockw.c ++++ b/arch/arm/mach-shmobile/board-bockw.c +@@ -101,6 +101,12 @@ static struct resource sdhi0_resources[] __initdata = { + DEFINE_RES_IRQ(gic_iid(0x77)), + }; + ++/* Ether */ ++static struct resource ether_resources[] __initdata = { ++ DEFINE_RES_MEM(0xfde00000, 0x400), ++ DEFINE_RES_IRQ(gic_iid(0x89)), ++}; ++ + static struct sh_eth_plat_data ether_platform_data __initdata = { + .phy = 0x01, + .edmac_endian = EDMAC_LITTLE_ENDIAN, +@@ -255,7 +261,13 @@ static void __init bockw_init(void) + r8a7778_clock_init(); + r8a7778_init_irq_extpin(1); + r8a7778_add_standard_devices(); +- r8a7778_add_ether_device(ðer_platform_data); ++ ++ platform_device_register_resndata(&platform_bus, "r8a777x-ether", -1, ++ ether_resources, ++ ARRAY_SIZE(ether_resources), ++ ðer_platform_data, ++ sizeof(ether_platform_data)); ++ + platform_device_register_full(&vin0_info); + /* VIN1 has a pin conflict with Ether */ + if (!IS_ENABLED(CONFIG_SH_ETH)) +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h +index 9838608363c2..48933def0d55 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a7778.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h +@@ -23,7 +23,6 @@ + + extern void r8a7778_add_standard_devices(void); + extern void r8a7778_add_standard_devices_dt(void); +-extern void r8a7778_add_ether_device(struct sh_eth_plat_data *pdata); + extern void r8a7778_add_dt_devices(void); + + extern void r8a7778_init_late(void); +diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c +index 604cf36b5616..f5e15c926fef 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7778.c ++++ b/arch/arm/mach-shmobile/setup-r8a7778.c +@@ -174,20 +174,6 @@ static struct platform_device_info hci##_info __initdata = { \ + USB_PLATFORM_INFO(ehci); + USB_PLATFORM_INFO(ohci); + +-/* Ether */ +-static struct resource ether_resources[] __initdata = { +- DEFINE_RES_MEM(0xfde00000, 0x400), +- DEFINE_RES_IRQ(gic_iid(0x89)), +-}; +- +-void __init r8a7778_add_ether_device(struct sh_eth_plat_data *pdata) +-{ +- platform_device_register_resndata(&platform_bus, "r8a777x-ether", -1, +- ether_resources, +- ARRAY_SIZE(ether_resources), +- pdata, sizeof(*pdata)); +-} +- + /* PFC/GPIO */ + static struct resource pfc_resources[] __initdata = { + DEFINE_RES_MEM(0xfffc0000, 0x118), +-- +1.8.5.rc3 + diff --git a/patches.renesas/0135-ARM-shmobile-r8a7778-r8a7778_register_hspi-become-st.patch b/patches.renesas/0135-ARM-shmobile-r8a7778-r8a7778_register_hspi-become-st.patch new file mode 100644 index 00000000000000..326fcf2c45d3ef --- /dev/null +++ b/patches.renesas/0135-ARM-shmobile-r8a7778-r8a7778_register_hspi-become-st.patch @@ -0,0 +1,32 @@ +From 8c956d2ac48569c1bc367fedbc6ade1a1929ce9e Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Mon, 23 Sep 2013 23:04:37 -0700 +Subject: ARM: shmobile: r8a7778: r8a7778_register_hspi() become static + +r8a7778_register_hspi() used only from setup-r8a7778.c +it can be static + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 117378e58365a44b568655e5aa49b3f6daf900c4) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/setup-r8a7778.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c +index f5e15c926fef..468ee6551184 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7778.c ++++ b/arch/arm/mach-shmobile/setup-r8a7778.c +@@ -258,7 +258,7 @@ static struct resource hspi_resources[] __initdata = { + DEFINE_RES_IRQ(gic_iid(0x75)), + }; + +-void __init r8a7778_register_hspi(int id) ++static void __init r8a7778_register_hspi(int id) + { + BUG_ON(id < 0 || id > 2); + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0136-ARM-shmobile-Add-r8a7790-CA15-CPU-cores.patch b/patches.renesas/0136-ARM-shmobile-Add-r8a7790-CA15-CPU-cores.patch new file mode 100644 index 00000000000000..80410ebf4897f5 --- /dev/null +++ b/patches.renesas/0136-ARM-shmobile-Add-r8a7790-CA15-CPU-cores.patch @@ -0,0 +1,50 @@ +From b9e2a3aa261d078c81e5c962c5606555f1340793 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 29 Aug 2013 08:22:17 +0900 +Subject: ARM: shmobile: Add r8a7790 CA15 CPU cores + +Add CA15 CPU cores to r8a7790 for a total of 4 x CA15. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit c1f95979baa9c33c5e6c280d7a8742fad0d20326) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a7790.dtsi | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi +index 413b4c29e782..0e4c87081c88 100644 +--- a/arch/arm/boot/dts/r8a7790.dtsi ++++ b/arch/arm/boot/dts/r8a7790.dtsi +@@ -24,6 +24,27 @@ + reg = <0>; + clock-frequency = <1300000000>; + }; ++ ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a15"; ++ reg = <1>; ++ clock-frequency = <1300000000>; ++ }; ++ ++ cpu2: cpu@2 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a15"; ++ reg = <2>; ++ clock-frequency = <1300000000>; ++ }; ++ ++ cpu3: cpu@3 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a15"; ++ reg = <3>; ++ clock-frequency = <1300000000>; ++ }; + }; + + gic: interrupt-controller@f1001000 { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0137-ARM-shmobile-Add-r8a7790-CA7-CPU-cores-to-DTSI.patch b/patches.renesas/0137-ARM-shmobile-Add-r8a7790-CA7-CPU-cores-to-DTSI.patch new file mode 100644 index 00000000000000..c32cb58bc585b1 --- /dev/null +++ b/patches.renesas/0137-ARM-shmobile-Add-r8a7790-CA7-CPU-cores-to-DTSI.patch @@ -0,0 +1,57 @@ +From 797c49eab98ed78fc3986747369aeff9b3b6c531 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Sun, 15 Sep 2013 00:28:58 +0900 +Subject: ARM: shmobile: Add r8a7790 CA7 CPU cores to DTSI + +Add r8a7790 Cortex-A7 CPU information to DTSI. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 2007e74ca3769fd353fe87a7a105c14102d7980c) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a7790.dtsi | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi +index 0e4c87081c88..28fc18c9601b 100644 +--- a/arch/arm/boot/dts/r8a7790.dtsi ++++ b/arch/arm/boot/dts/r8a7790.dtsi +@@ -45,6 +45,34 @@ + reg = <3>; + clock-frequency = <1300000000>; + }; ++ ++ cpu4: cpu@4 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x100>; ++ clock-frequency = <780000000>; ++ }; ++ ++ cpu5: cpu@5 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x101>; ++ clock-frequency = <780000000>; ++ }; ++ ++ cpu6: cpu@6 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x102>; ++ clock-frequency = <780000000>; ++ }; ++ ++ cpu7: cpu@7 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x103>; ++ clock-frequency = <780000000>; ++ }; + }; + + gic: interrupt-controller@f1001000 { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0138-ARM-shmobile-Initial-r8a7791-SoC-support.patch b/patches.renesas/0138-ARM-shmobile-Initial-r8a7791-SoC-support.patch new file mode 100644 index 00000000000000..37e2182abfa985 --- /dev/null +++ b/patches.renesas/0138-ARM-shmobile-Initial-r8a7791-SoC-support.patch @@ -0,0 +1,381 @@ +From 58d6df387825fcc230079ac8c8432849c84355a1 Mon Sep 17 00:00:00 2001 +From: Hisashi Nakamura <hisashi.nakamura.ak@renesas.com> +Date: Wed, 4 Sep 2013 12:45:57 +0900 +Subject: ARM: shmobile: Initial r8a7791 SoC support + +Add initial support for the r8a7791 SoC including: + - Single Cortex-A15 CPU Core + - GIC + +No static virtual mappings are used, all the components +make use of ioremap(). DT_MACHINE_START is still wrapped +in CONFIG_USE_OF to match other mach-shmobile code. + +Signed-off-by: Hisashi Nakamura <hisashi.nakamura.ak@renesas.com> +Signed-off-by: Ryo Kataoka <ryo.kataoka.wt@renesas.com> +[damm@opensource.se: Forward ported to upstream, dropped not-yet-ready code] +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +(cherry picked from commit 0d0771ab2bd5f57a62db91f26bba1e9f522d16cb) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a7791.dtsi | 41 ++++++ + arch/arm/mach-shmobile/Kconfig | 6 + + arch/arm/mach-shmobile/Makefile | 2 + + arch/arm/mach-shmobile/clock-r8a7791.c | 198 ++++++++++++++++++++++++++ + arch/arm/mach-shmobile/include/mach/r8a7791.h | 6 + + arch/arm/mach-shmobile/setup-r8a7791.c | 38 +++++ + 6 files changed, 291 insertions(+) + create mode 100644 arch/arm/boot/dts/r8a7791.dtsi + create mode 100644 arch/arm/mach-shmobile/clock-r8a7791.c + create mode 100644 arch/arm/mach-shmobile/include/mach/r8a7791.h + create mode 100644 arch/arm/mach-shmobile/setup-r8a7791.c + +diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi +new file mode 100644 +index 000000000000..bbed43bd9be9 +--- /dev/null ++++ b/arch/arm/boot/dts/r8a7791.dtsi +@@ -0,0 +1,41 @@ ++/* ++ * Device Tree Source for the r8a7791 SoC ++ * ++ * Copyright (C) 2013 Renesas Electronics Corporation ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++/ { ++ compatible = "renesas,r8a7791"; ++ interrupt-parent = <&gic>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a15"; ++ reg = <0>; ++ clock-frequency = <1300000000>; ++ }; ++ }; ++ ++ gic: interrupt-controller@f1001000 { ++ compatible = "arm,cortex-a15-gic"; ++ #interrupt-cells = <3>; ++ #address-cells = <0>; ++ interrupt-controller; ++ reg = <0 0xf1001000 0 0x1000>, ++ <0 0xf1002000 0 0x1000>, ++ <0 0xf1004000 0 0x2000>, ++ <0 0xf1006000 0 0x2000>; ++ interrupts = <1 9 0xf04>; ++ }; ++}; +diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig +index 1f94c310c477..b45240512ce0 100644 +--- a/arch/arm/mach-shmobile/Kconfig ++++ b/arch/arm/mach-shmobile/Kconfig +@@ -101,6 +101,12 @@ config ARCH_R8A7790 + select SH_CLK_CPG + select RENESAS_IRQC + ++config ARCH_R8A7791 ++ bool "R-Car M2 (R8A77910)" ++ select ARM_GIC ++ select CPU_V7 ++ select SH_CLK_CPG ++ + config ARCH_EMEV2 + bool "Emma Mobile EV2" + select ARCH_WANT_OPTIONAL_GPIOLIB +diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile +index 2705bfa8c113..228193cc9a38 100644 +--- a/arch/arm/mach-shmobile/Makefile ++++ b/arch/arm/mach-shmobile/Makefile +@@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o + obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o + obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o + obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o ++obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o + obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o + + # Clock objects +@@ -27,6 +28,7 @@ obj-$(CONFIG_ARCH_R8A7740) += clock-r8a7740.o + obj-$(CONFIG_ARCH_R8A7778) += clock-r8a7778.o + obj-$(CONFIG_ARCH_R8A7779) += clock-r8a7779.o + obj-$(CONFIG_ARCH_R8A7790) += clock-r8a7790.o ++obj-$(CONFIG_ARCH_R8A7791) += clock-r8a7791.o + obj-$(CONFIG_ARCH_EMEV2) += clock-emev2.o + endif + +diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c +new file mode 100644 +index 000000000000..9929feb1b810 +--- /dev/null ++++ b/arch/arm/mach-shmobile/clock-r8a7791.c +@@ -0,0 +1,198 @@ ++/* ++ * r8a7791 clock framework support ++ * ++ * Copyright (C) 2013 Renesas Electronics Corporation ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * Copyright (C) 2013 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/io.h> ++#include <linux/kernel.h> ++#include <linux/sh_clk.h> ++#include <linux/clkdev.h> ++#include <mach/clock.h> ++#include <mach/common.h> ++ ++/* ++ * MD EXTAL PLL0 PLL1 PLL3 ++ * 14 13 19 (MHz) *1 *1 ++ *--------------------------------------------------- ++ * 0 0 0 15 x 1 x172/2 x208/2 x106 ++ * 0 0 1 15 x 1 x172/2 x208/2 x88 ++ * 0 1 0 20 x 1 x130/2 x156/2 x80 ++ * 0 1 1 20 x 1 x130/2 x156/2 x66 ++ * 1 0 0 26 / 2 x200/2 x240/2 x122 ++ * 1 0 1 26 / 2 x200/2 x240/2 x102 ++ * 1 1 0 30 / 2 x172/2 x208/2 x106 ++ * 1 1 1 30 / 2 x172/2 x208/2 x88 ++ * ++ * *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2) ++ * see "p1 / 2" on R8A7791_CLOCK_ROOT() below ++ */ ++ ++#define MD(nr) (1 << nr) ++ ++#define CPG_BASE 0xe6150000 ++#define CPG_LEN 0x1000 ++ ++#define SMSTPCR1 0xE6150134 ++#define SMSTPCR2 0xe6150138 ++#define SMSTPCR3 0xE615013C ++#define SMSTPCR5 0xE6150144 ++#define SMSTPCR7 0xe615014c ++#define SMSTPCR8 0xE6150990 ++#define SMSTPCR9 0xE6150994 ++#define SMSTPCR10 0xE6150998 ++ ++#define MODEMR 0xE6160060 ++#define SDCKCR 0xE6150074 ++#define SD2CKCR 0xE6150078 ++#define SD3CKCR 0xE615007C ++#define MMC0CKCR 0xE6150240 ++#define MMC1CKCR 0xE6150244 ++#define SSPCKCR 0xE6150248 ++#define SSPRSCKCR 0xE615024C ++ ++static struct clk_mapping cpg_mapping = { ++ .phys = CPG_BASE, ++ .len = CPG_LEN, ++}; ++ ++static struct clk extal_clk = { ++ /* .rate will be updated on r8a7791_clock_init() */ ++ .mapping = &cpg_mapping, ++}; ++ ++static struct sh_clk_ops followparent_clk_ops = { ++ .recalc = followparent_recalc, ++}; ++ ++static struct clk main_clk = { ++ /* .parent will be set r8a73a4_clock_init */ ++ .ops = &followparent_clk_ops, ++}; ++ ++/* ++ * clock ratio of these clock will be updated ++ * on r8a7791_clock_init() ++ */ ++SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1); ++SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1); ++ ++/* fixed ratio clock */ ++SH_FIXED_RATIO_CLK_SET(extal_div2_clk, extal_clk, 1, 2); ++SH_FIXED_RATIO_CLK_SET(cp_clk, extal_clk, 1, 2); ++ ++SH_FIXED_RATIO_CLK_SET(pll1_div2_clk, pll1_clk, 1, 2); ++SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12); ++SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24); ++ ++SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15); ++ ++static struct clk *main_clks[] = { ++ &extal_clk, ++ &extal_div2_clk, ++ &main_clk, ++ &pll1_clk, ++ &pll1_div2_clk, ++ &pll3_clk, ++ &hp_clk, ++ &p_clk, ++ &mp_clk, ++ &cp_clk, ++}; ++ ++/* MSTP */ ++enum { ++ MSTP721, MSTP720, ++/* MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202,*/ ++ MSTP_NR ++}; ++ ++static struct clk mstp_clks[MSTP_NR] = { ++ [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */ ++ [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */ ++}; ++ ++static struct clk_lookup lookups[] = { ++ ++ /* main clocks */ ++ CLKDEV_CON_ID("extal", &extal_clk), ++ CLKDEV_CON_ID("extal_div2", &extal_div2_clk), ++ CLKDEV_CON_ID("main", &main_clk), ++ CLKDEV_CON_ID("pll1", &pll1_clk), ++ CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk), ++ CLKDEV_CON_ID("pll3", &pll3_clk), ++ CLKDEV_CON_ID("hp", &hp_clk), ++ CLKDEV_CON_ID("p", &p_clk), ++ CLKDEV_CON_ID("mp", &mp_clk), ++ CLKDEV_CON_ID("cp", &cp_clk), ++ CLKDEV_CON_ID("peripheral_clk", &hp_clk), ++}; ++ ++#define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ ++ extal_clk.rate = e * 1000 * 1000; \ ++ main_clk.parent = m; \ ++ SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1); \ ++ if (mode & MD(19)) \ ++ SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1); \ ++ else \ ++ SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1) ++ ++ ++void __init r8a7791_clock_init(void) ++{ ++ void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE); ++ u32 mode; ++ int k, ret = 0; ++ ++ BUG_ON(!modemr); ++ mode = ioread32(modemr); ++ iounmap(modemr); ++ ++ switch (mode & (MD(14) | MD(13))) { ++ case 0: ++ R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88); ++ break; ++ case MD(13): ++ R8A7791_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66); ++ break; ++ case MD(14): ++ R8A7791_CLOCK_ROOT(26, &extal_div2_clk, 200, 240, 122, 102); ++ break; ++ case MD(13) | MD(14): ++ R8A7791_CLOCK_ROOT(30, &extal_div2_clk, 172, 208, 106, 88); ++ break; ++ } ++ ++ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) ++ ret = clk_register(main_clks[k]); ++ ++ if (!ret) ++ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); ++ ++ clkdev_add_table(lookups, ARRAY_SIZE(lookups)); ++ ++ if (!ret) ++ shmobile_clk_init(); ++ else ++ goto epanic; ++ ++ return; ++ ++epanic: ++ panic("failed to setup r8a7791 clocks\n"); ++} +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h +new file mode 100644 +index 000000000000..43b7206998da +--- /dev/null ++++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h +@@ -0,0 +1,6 @@ ++#ifndef __ASM_R8A7791_H__ ++#define __ASM_R8A7791_H__ ++ ++void r8a7791_clock_init(void); ++ ++#endif /* __ASM_R8A7791_H__ */ +diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c +new file mode 100644 +index 000000000000..88dcce1a6391 +--- /dev/null ++++ b/arch/arm/mach-shmobile/setup-r8a7791.c +@@ -0,0 +1,38 @@ ++/* ++ * r8a7791 processor support ++ * ++ * Copyright (C) 2013 Renesas Electronics Corporation ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * Copyright (C) 2013 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/irq.h> ++#include <linux/kernel.h> ++#include <linux/of_platform.h> ++#include <mach/common.h> ++#include <mach/r8a7791.h> ++#include <asm/mach/arch.h> ++ ++#ifdef CONFIG_USE_OF ++static const char *r8a7791_boards_compat_dt[] __initdata = { ++ "renesas,r8a7791", ++ NULL, ++}; ++ ++DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)") ++ .dt_compat = r8a7791_boards_compat_dt, ++MACHINE_END ++#endif /* CONFIG_USE_OF */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0139-ARM-shmobile-r8a7791-SCIF-support.patch b/patches.renesas/0139-ARM-shmobile-r8a7791-SCIF-support.patch new file mode 100644 index 00000000000000..936c40cbc0a805 --- /dev/null +++ b/patches.renesas/0139-ARM-shmobile-r8a7791-SCIF-support.patch @@ -0,0 +1,212 @@ +From 392c1954243ab01e46fe09e39b3dc39cc6574edd Mon Sep 17 00:00:00 2001 +From: Yoshikazu Fujikawa <yoshikazu.fujikawa.ue@renesas.com> +Date: Wed, 4 Sep 2013 12:46:08 +0900 +Subject: ARM: shmobile: r8a7791 SCIF support + +Add SCIF serial port support to the r8a7791 SoC by +adding platform devices for SCIFA0 -> SCIFA5 as well +as SCIFB0 -> SCIFB2 and SCIF0 -> SCIF5 together with +clock bindings. DT device description is excluded at +this point since such bindings are still under +development. + +Signed-off-by: Yoshikazu Fujikawa <yoshikazu.fujikawa.ue@renesas.com> +Signed-off-by: Ryo Kataoka <ryo.kataoka.wt@renesas.com> +[damm@opensource.se: Forward ported to upstream, dropped holes in enum] +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +(cherry picked from commit e6491d08ed1d5d1e415d5371f2ff2fed67df83b0) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/clock-r8a7791.c | 36 +++++++++++- + arch/arm/mach-shmobile/include/mach/r8a7791.h | 1 + + arch/arm/mach-shmobile/setup-r8a7791.c | 82 +++++++++++++++++++++++++++ + 3 files changed, 118 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c +index 9929feb1b810..df3122ea4c69 100644 +--- a/arch/arm/mach-shmobile/clock-r8a7791.c ++++ b/arch/arm/mach-shmobile/clock-r8a7791.c +@@ -48,6 +48,7 @@ + #define CPG_BASE 0xe6150000 + #define CPG_LEN 0x1000 + ++#define SMSTPCR0 0xE6150130 + #define SMSTPCR1 0xE6150134 + #define SMSTPCR2 0xe6150138 + #define SMSTPCR3 0xE615013C +@@ -56,6 +57,7 @@ + #define SMSTPCR8 0xE6150990 + #define SMSTPCR9 0xE6150994 + #define SMSTPCR10 0xE6150998 ++#define SMSTPCR11 0xE615099C + + #define MODEMR 0xE6160060 + #define SDCKCR 0xE6150074 +@@ -118,13 +120,28 @@ static struct clk *main_clks[] = { + /* MSTP */ + enum { + MSTP721, MSTP720, +-/* MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202,*/ ++ MSTP719, MSTP718, MSTP715, MSTP714, ++ MSTP216, MSTP207, MSTP206, ++ MSTP204, MSTP203, MSTP202, MSTP1105, MSTP1106, MSTP1107, + MSTP_NR + }; + + static struct clk mstp_clks[MSTP_NR] = { + [MSTP721] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 21, 0), /* SCIF0 */ + [MSTP720] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 20, 0), /* SCIF1 */ ++ [MSTP719] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 19, 0), /* SCIF2 */ ++ [MSTP718] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 18, 0), /* SCIF3 */ ++ [MSTP715] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 15, 0), /* SCIF4 */ ++ [MSTP714] = SH_CLK_MSTP32(&p_clk, SMSTPCR7, 14, 0), /* SCIF5 */ ++ [MSTP216] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 16, 0), /* SCIFB2 */ ++ [MSTP207] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 7, 0), /* SCIFB1 */ ++ [MSTP206] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 6, 0), /* SCIFB0 */ ++ [MSTP204] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 4, 0), /* SCIFA0 */ ++ [MSTP203] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 3, 0), /* SCIFA1 */ ++ [MSTP202] = SH_CLK_MSTP32(&mp_clk, SMSTPCR2, 2, 0), /* SCIFA2 */ ++ [MSTP1105] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 5, 0), /* SCIFA3 */ ++ [MSTP1106] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 6, 0), /* SCIFA4 */ ++ [MSTP1107] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 7, 0), /* SCIFA5 */ + }; + + static struct clk_lookup lookups[] = { +@@ -141,6 +158,23 @@ static struct clk_lookup lookups[] = { + CLKDEV_CON_ID("mp", &mp_clk), + CLKDEV_CON_ID("cp", &cp_clk), + CLKDEV_CON_ID("peripheral_clk", &hp_clk), ++ ++ /* MSTP */ ++ CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */ ++ CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]), /* SCIFA1 */ ++ CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]), /* SCIFB0 */ ++ CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), /* SCIFB1 */ ++ CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), /* SCIFB2 */ ++ CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP202]), /* SCIFA2 */ ++ CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP721]), /* SCIF0 */ ++ CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), /* SCIF1 */ ++ CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP719]), /* SCIF2 */ ++ CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP718]), /* SCIF3 */ ++ CLKDEV_DEV_ID("sh-sci.10", &mstp_clks[MSTP715]), /* SCIF4 */ ++ CLKDEV_DEV_ID("sh-sci.11", &mstp_clks[MSTP714]), /* SCIF5 */ ++ CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1105]), /* SCIFA3 */ ++ CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */ ++ CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */ + }; + + #define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h +index 43b7206998da..d234b8cd9e91 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a7791.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h +@@ -1,6 +1,7 @@ + #ifndef __ASM_R8A7791_H__ + #define __ASM_R8A7791_H__ + ++void r8a7791_add_dt_devices(void); + void r8a7791_clock_init(void); + + #endif /* __ASM_R8A7791_H__ */ +diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c +index 88dcce1a6391..0de6aec3bb63 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7791.c ++++ b/arch/arm/mach-shmobile/setup-r8a7791.c +@@ -22,10 +22,92 @@ + #include <linux/irq.h> + #include <linux/kernel.h> + #include <linux/of_platform.h> ++#include <linux/serial_sci.h> + #include <mach/common.h> ++#include <mach/irqs.h> + #include <mach/r8a7791.h> + #include <asm/mach/arch.h> + ++#define SCIF_COMMON(scif_type, baseaddr, irq) \ ++ .type = scif_type, \ ++ .mapbase = baseaddr, \ ++ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ ++ .irqs = SCIx_IRQ_MUXED(irq) ++ ++#define SCIFA_DATA(index, baseaddr, irq) \ ++[index] = { \ ++ SCIF_COMMON(PORT_SCIFA, baseaddr, irq), \ ++ .scbrr_algo_id = SCBRR_ALGO_4, \ ++ .scscr = SCSCR_RE | SCSCR_TE, \ ++} ++ ++#define SCIFB_DATA(index, baseaddr, irq) \ ++[index] = { \ ++ SCIF_COMMON(PORT_SCIFB, baseaddr, irq), \ ++ .scbrr_algo_id = SCBRR_ALGO_4, \ ++ .scscr = SCSCR_RE | SCSCR_TE, \ ++} ++ ++#define SCIF_DATA(index, baseaddr, irq) \ ++[index] = { \ ++ SCIF_COMMON(PORT_SCIF, baseaddr, irq), \ ++ .scbrr_algo_id = SCBRR_ALGO_2, \ ++ .scscr = SCSCR_RE | SCSCR_TE, \ ++} ++ ++#define HSCIF_DATA(index, baseaddr, irq) \ ++[index] = { \ ++ SCIF_COMMON(PORT_HSCIF, baseaddr, irq), \ ++ .scbrr_algo_id = SCBRR_ALGO_6, \ ++ .scscr = SCSCR_RE | SCSCR_TE, \ ++} ++ ++enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1, ++ SCIF2, SCIF3, SCIF4, SCIF5, SCIFA3, SCIFA4, SCIFA5 }; ++ ++static const struct plat_sci_port scif[] __initconst = { ++ SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */ ++ SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */ ++ SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */ ++ SCIFB_DATA(SCIFB1, 0xe6c30000, gic_spi(149)), /* SCIFB1 */ ++ SCIFB_DATA(SCIFB2, 0xe6ce0000, gic_spi(150)), /* SCIFB2 */ ++ SCIFA_DATA(SCIFA2, 0xe6c60000, gic_spi(151)), /* SCIFA2 */ ++ SCIF_DATA(SCIF0, 0xe6e60000, gic_spi(152)), /* SCIF0 */ ++ SCIF_DATA(SCIF1, 0xe6e68000, gic_spi(153)), /* SCIF1 */ ++ SCIF_DATA(SCIF2, 0xe6e58000, gic_spi(22)), /* SCIF2 */ ++ SCIF_DATA(SCIF3, 0xe6ea8000, gic_spi(23)), /* SCIF3 */ ++ SCIF_DATA(SCIF4, 0xe6ee0000, gic_spi(24)), /* SCIF4 */ ++ SCIF_DATA(SCIF5, 0xe6ee8000, gic_spi(25)), /* SCIF5 */ ++ SCIFA_DATA(SCIFA3, 0xe6c70000, gic_spi(29)), /* SCIFA3 */ ++ SCIFA_DATA(SCIFA4, 0xe6c78000, gic_spi(30)), /* SCIFA4 */ ++ SCIFA_DATA(SCIFA5, 0xe6c80000, gic_spi(31)), /* SCIFA5 */ ++}; ++ ++static inline void r8a7791_register_scif(int idx) ++{ ++ platform_device_register_data(&platform_bus, "sh-sci", idx, &scif[idx], ++ sizeof(struct plat_sci_port)); ++} ++ ++void __init r8a7791_add_dt_devices(void) ++{ ++ r8a7791_register_scif(SCIFA0); ++ r8a7791_register_scif(SCIFA1); ++ r8a7791_register_scif(SCIFB0); ++ r8a7791_register_scif(SCIFB1); ++ r8a7791_register_scif(SCIFB2); ++ r8a7791_register_scif(SCIFA2); ++ r8a7791_register_scif(SCIF0); ++ r8a7791_register_scif(SCIF1); ++ r8a7791_register_scif(SCIF2); ++ r8a7791_register_scif(SCIF3); ++ r8a7791_register_scif(SCIF4); ++ r8a7791_register_scif(SCIF5); ++ r8a7791_register_scif(SCIFA3); ++ r8a7791_register_scif(SCIFA4); ++ r8a7791_register_scif(SCIFA5); ++} ++ + #ifdef CONFIG_USE_OF + static const char *r8a7791_boards_compat_dt[] __initdata = { + "renesas,r8a7791", +-- +1.8.5.rc3 + diff --git a/patches.renesas/0140-ARM-shmobile-r8a7791-CMT-support.patch b/patches.renesas/0140-ARM-shmobile-r8a7791-CMT-support.patch new file mode 100644 index 00000000000000..f7ea6bb5714562 --- /dev/null +++ b/patches.renesas/0140-ARM-shmobile-r8a7791-CMT-support.patch @@ -0,0 +1,150 @@ +From 9cb1c91d8af525275672085b4a778c7aa0801c23 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Wed, 4 Sep 2013 12:46:17 +0900 +Subject: ARM: shmobile: r8a7791 CMT support + +Add r8a7791 CMT support via channel 0 of CMT0. At this +point the CMT is used for clock event operation, but in +the future the arch timer will be the main timer and the +CMT will be used for deep sleep wake up only. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit a7663b88280d00359715817620798e99d54d401c) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 1bebd72a71e4ea1e9f68a9e71faee724c5e8f903) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/clock-r8a7791.c | 7 ++++++- + arch/arm/mach-shmobile/include/mach/r8a7791.h | 1 + + arch/arm/mach-shmobile/setup-r8a7791.c | 29 +++++++++++++++++++++++++++ + 3 files changed, 36 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c +index df3122ea4c69..c9a26f16ce5b 100644 +--- a/arch/arm/mach-shmobile/clock-r8a7791.c ++++ b/arch/arm/mach-shmobile/clock-r8a7791.c +@@ -101,7 +101,7 @@ SH_FIXED_RATIO_CLK_SET(cp_clk, extal_clk, 1, 2); + SH_FIXED_RATIO_CLK_SET(pll1_div2_clk, pll1_clk, 1, 2); + SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12); + SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24); +- ++SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024)); + SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15); + + static struct clk *main_clks[] = { +@@ -113,6 +113,7 @@ static struct clk *main_clks[] = { + &pll3_clk, + &hp_clk, + &p_clk, ++ &rclk_clk, + &mp_clk, + &cp_clk, + }; +@@ -123,6 +124,7 @@ enum { + MSTP719, MSTP718, MSTP715, MSTP714, + MSTP216, MSTP207, MSTP206, + MSTP204, MSTP203, MSTP202, MSTP1105, MSTP1106, MSTP1107, ++ MSTP124, + MSTP_NR + }; + +@@ -142,6 +144,7 @@ static struct clk mstp_clks[MSTP_NR] = { + [MSTP1105] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 5, 0), /* SCIFA3 */ + [MSTP1106] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 6, 0), /* SCIFA4 */ + [MSTP1107] = SH_CLK_MSTP32(&mp_clk, SMSTPCR11, 7, 0), /* SCIFA5 */ ++ [MSTP124] = SH_CLK_MSTP32(&rclk_clk, SMSTPCR1, 24, 0), /* CMT0 */ + }; + + static struct clk_lookup lookups[] = { +@@ -155,6 +158,7 @@ static struct clk_lookup lookups[] = { + CLKDEV_CON_ID("pll3", &pll3_clk), + CLKDEV_CON_ID("hp", &hp_clk), + CLKDEV_CON_ID("p", &p_clk), ++ CLKDEV_CON_ID("rclk", &rclk_clk), + CLKDEV_CON_ID("mp", &mp_clk), + CLKDEV_CON_ID("cp", &cp_clk), + CLKDEV_CON_ID("peripheral_clk", &hp_clk), +@@ -175,6 +179,7 @@ static struct clk_lookup lookups[] = { + CLKDEV_DEV_ID("sh-sci.12", &mstp_clks[MSTP1105]), /* SCIFA3 */ + CLKDEV_DEV_ID("sh-sci.13", &mstp_clks[MSTP1106]), /* SCIFA4 */ + CLKDEV_DEV_ID("sh-sci.14", &mstp_clks[MSTP1107]), /* SCIFA5 */ ++ CLKDEV_DEV_ID("sh_cmt.0", &mstp_clks[MSTP124]), + }; + + #define R8A7791_CLOCK_ROOT(e, m, p0, p1, p30, p31) \ +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h +index d234b8cd9e91..2e6d66131083 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a7791.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h +@@ -3,5 +3,6 @@ + + void r8a7791_add_dt_devices(void); + void r8a7791_clock_init(void); ++void r8a7791_init_early(void); + + #endif /* __ASM_R8A7791_H__ */ +diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c +index 0de6aec3bb63..b56399d2e1de 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7791.c ++++ b/arch/arm/mach-shmobile/setup-r8a7791.c +@@ -23,6 +23,7 @@ + #include <linux/kernel.h> + #include <linux/of_platform.h> + #include <linux/serial_sci.h> ++#include <linux/sh_timer.h> + #include <mach/common.h> + #include <mach/irqs.h> + #include <mach/r8a7791.h> +@@ -89,6 +90,25 @@ static inline void r8a7791_register_scif(int idx) + sizeof(struct plat_sci_port)); + } + ++static const struct sh_timer_config cmt00_platform_data __initconst = { ++ .name = "CMT00", ++ .timer_bit = 0, ++ .clockevent_rating = 80, ++}; ++ ++static const struct resource cmt00_resources[] __initconst = { ++ DEFINE_RES_MEM(0xffca0510, 0x0c), ++ DEFINE_RES_MEM(0xffca0500, 0x04), ++ DEFINE_RES_IRQ(gic_spi(142)), /* CMT0_0 */ ++}; ++ ++#define r8a7791_register_cmt(idx) \ ++ platform_device_register_resndata(&platform_bus, "sh_cmt", \ ++ idx, cmt##idx##_resources, \ ++ ARRAY_SIZE(cmt##idx##_resources), \ ++ &cmt##idx##_platform_data, \ ++ sizeof(struct sh_timer_config)) ++ + void __init r8a7791_add_dt_devices(void) + { + r8a7791_register_scif(SCIFA0); +@@ -106,6 +126,14 @@ void __init r8a7791_add_dt_devices(void) + r8a7791_register_scif(SCIFA3); + r8a7791_register_scif(SCIFA4); + r8a7791_register_scif(SCIFA5); ++ r8a7791_register_cmt(00); ++} ++ ++void __init r8a7791_init_early(void) ++{ ++#ifndef CONFIG_ARM_ARCH_TIMER ++ shmobile_setup_delay(1300, 2, 4); /* Cortex-A15 @ 1300MHz */ ++#endif + } + + #ifdef CONFIG_USE_OF +@@ -115,6 +143,7 @@ static const char *r8a7791_boards_compat_dt[] __initdata = { + }; + + DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)") ++ .init_early = r8a7791_init_early, + .dt_compat = r8a7791_boards_compat_dt, + MACHINE_END + #endif /* CONFIG_USE_OF */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0141-ARM-shmobile-r8a7778-add-USBHS-clock.patch b/patches.renesas/0141-ARM-shmobile-r8a7778-add-USBHS-clock.patch new file mode 100644 index 00000000000000..e7826a92e37f30 --- /dev/null +++ b/patches.renesas/0141-ARM-shmobile-r8a7778-add-USBHS-clock.patch @@ -0,0 +1,30 @@ +From 0844cce78c29efa809746a4eb300ad057f9819cd Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 4 Aug 2013 17:43:19 -0700 +Subject: ARM: shmobile: r8a7778: add USBHS clock + +This patch adds USBHS clock for renesas_usbhs driver + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 84ea52885ebb298231b9577dd8b53fdfa692c0b7) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/clock-r8a7778.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c +index 244a8dec4d04..fb6af83858e3 100644 +--- a/arch/arm/mach-shmobile/clock-r8a7778.c ++++ b/arch/arm/mach-shmobile/clock-r8a7778.c +@@ -181,6 +181,7 @@ static struct clk_lookup lookups[] = { + CLKDEV_DEV_ID("r8a7778-vin.1", &mstp_clks[MSTP109]), /* VIN1 */ + CLKDEV_DEV_ID("ehci-platform", &mstp_clks[MSTP100]), /* USB EHCI port0/1 */ + CLKDEV_DEV_ID("ohci-platform", &mstp_clks[MSTP100]), /* USB OHCI port0/1 */ ++ CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP100]), /* USB FUNC */ + CLKDEV_DEV_ID("i2c-rcar.0", &mstp_clks[MSTP030]), /* I2C0 */ + CLKDEV_DEV_ID("i2c-rcar.1", &mstp_clks[MSTP029]), /* I2C1 */ + CLKDEV_DEV_ID("i2c-rcar.2", &mstp_clks[MSTP028]), /* I2C2 */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0142-ARM-shmobile-r8a7778-add-usb-phy-power-control-funct.patch b/patches.renesas/0142-ARM-shmobile-r8a7778-add-usb-phy-power-control-funct.patch new file mode 100644 index 00000000000000..9520b80a8f1741 --- /dev/null +++ b/patches.renesas/0142-ARM-shmobile-r8a7778-add-usb-phy-power-control-funct.patch @@ -0,0 +1,101 @@ +From b89105896d6547a9b025d673a7167dfb2d472682 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 4 Aug 2013 17:43:01 -0700 +Subject: ARM: shmobile: r8a7778: add usb phy power control function + +USB phy initialisation function is needed from not only +USB Host but also USB Function too. +This patch adds usb phy common control function. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit f39d35fcc2cd7a24ec3128adffd7876953999e1f) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/include/mach/r8a7778.h | 2 ++ + arch/arm/mach-shmobile/setup-r8a7778.c | 37 +++++++++++++++++++-------- + 2 files changed, 28 insertions(+), 11 deletions(-) + +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h +index 48933def0d55..fdbd37df1543 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a7778.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h +@@ -32,4 +32,6 @@ extern void r8a7778_clock_init(void); + extern void r8a7778_init_irq_extpin(int irlm); + extern void r8a7778_pinmux_init(void); + ++extern int r8a7778_usb_phy_power(bool enable); ++ + #endif /* __ASM_R8A7778_H__ */ +diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c +index 468ee6551184..bfeedd169891 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7778.c ++++ b/arch/arm/mach-shmobile/setup-r8a7778.c +@@ -95,29 +95,46 @@ static struct sh_timer_config sh_tmu1_platform_data __initdata = { + &sh_tmu##idx##_platform_data, \ + sizeof(sh_tmu##idx##_platform_data)) + +-/* USB */ +-static struct usb_phy *phy; ++int r8a7778_usb_phy_power(bool enable) ++{ ++ static struct usb_phy *phy = NULL; ++ int ret = 0; ++ ++ if (!phy) ++ phy = usb_get_phy(USB_PHY_TYPE_USB2); ++ ++ if (IS_ERR(phy)) { ++ pr_err("kernel doesn't have usb phy driver\n"); ++ return PTR_ERR(phy); ++ } ++ ++ if (enable) ++ ret = usb_phy_init(phy); ++ else ++ usb_phy_shutdown(phy); + ++ return ret; ++} ++ ++/* USB */ + static int usb_power_on(struct platform_device *pdev) + { +- if (IS_ERR(phy)) +- return PTR_ERR(phy); ++ int ret = r8a7778_usb_phy_power(true); ++ ++ if (ret) ++ return ret; + + pm_runtime_enable(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); + +- usb_phy_init(phy); +- + return 0; + } + + static void usb_power_off(struct platform_device *pdev) + { +- if (IS_ERR(phy)) ++ if (r8a7778_usb_phy_power(false)) + return; + +- usb_phy_shutdown(phy); +- + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); + } +@@ -305,8 +322,6 @@ void __init r8a7778_add_standard_devices(void) + + void __init r8a7778_init_late(void) + { +- phy = usb_get_phy(USB_PHY_TYPE_USB2); +- + platform_device_register_full(&ehci_info); + platform_device_register_full(&ohci_info); + } +-- +1.8.5.rc3 + diff --git a/patches.renesas/0143-ARM-shmobile-marzen-Add-Display-Unit-support.patch b/patches.renesas/0143-ARM-shmobile-marzen-Add-Display-Unit-support.patch new file mode 100644 index 00000000000000..a6d18d96d67a1d --- /dev/null +++ b/patches.renesas/0143-ARM-shmobile-marzen-Add-Display-Unit-support.patch @@ -0,0 +1,124 @@ +From 3c739317bdb2ddecf7be87c157b0ab6205ae0ca9 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Wed, 27 Mar 2013 11:55:35 +0100 +Subject: ARM: shmobile: marzen: Add Display Unit support + +Support the DU0 VGA and DU1 LVDS outputs. DU1 is connected to a +Mitsubishi AA104XD12 panel (10.4" XGA). + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit df83d907348b41f40da83b267242b5dca041d4ef) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-marzen.c | 72 +++++++++++++++++++++++++++++++++++ + 1 file changed, 72 insertions(+) + +diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c +index 3f5044fda4e3..434b213cc738 100644 +--- a/arch/arm/mach-shmobile/board-marzen.c ++++ b/arch/arm/mach-shmobile/board-marzen.c +@@ -30,6 +30,7 @@ + #include <linux/dma-mapping.h> + #include <linux/pinctrl/machine.h> + #include <linux/platform_data/gpio-rcar.h> ++#include <linux/platform_data/rcar-du.h> + #include <linux/platform_data/usb-rcar-phy.h> + #include <linux/regulator/fixed.h> + #include <linux/regulator/machine.h> +@@ -169,6 +170,63 @@ static struct platform_device hspi_device = { + .num_resources = ARRAY_SIZE(hspi_resources), + }; + ++/* ++ * DU ++ * ++ * The panel only specifies the [hv]display and [hv]total values. The position ++ * and width of the sync pulses don't matter, they're copied from VESA timings. ++ */ ++static struct rcar_du_encoder_data du_encoders[] = { ++ { ++ .type = RCAR_DU_ENCODER_VGA, ++ .output = RCAR_DU_OUTPUT_DPAD0, ++ }, { ++ .type = RCAR_DU_ENCODER_LVDS, ++ .output = RCAR_DU_OUTPUT_DPAD1, ++ .connector.lvds.panel = { ++ .width_mm = 210, ++ .height_mm = 158, ++ .mode = { ++ .clock = 65000, ++ .hdisplay = 1024, ++ .hsync_start = 1048, ++ .hsync_end = 1184, ++ .htotal = 1344, ++ .vdisplay = 768, ++ .vsync_start = 771, ++ .vsync_end = 777, ++ .vtotal = 806, ++ .flags = 0, ++ }, ++ }, ++ }, ++}; ++ ++static const struct rcar_du_platform_data du_pdata __initconst = { ++ .encoders = du_encoders, ++ .num_encoders = ARRAY_SIZE(du_encoders), ++}; ++ ++static const struct resource du_resources[] __initconst = { ++ DEFINE_RES_MEM(0xfff80000, 0x40000), ++ DEFINE_RES_IRQ(gic_iid(0x3f)), ++}; ++ ++static void __init marzen_add_du_device(void) ++{ ++ struct platform_device_info info = { ++ .name = "rcar-du-r8a7779", ++ .id = -1, ++ .res = du_resources, ++ .num_res = ARRAY_SIZE(du_resources), ++ .data = &du_pdata, ++ .size_data = sizeof(du_pdata), ++ .dma_mask = DMA_BIT_MASK(32), ++ }; ++ ++ platform_device_register_full(&info); ++} ++ + /* LEDS */ + static struct gpio_led marzen_leds[] = { + { +@@ -237,6 +295,19 @@ static struct platform_device *marzen_devices[] __initdata = { + }; + + static const struct pinctrl_map marzen_pinctrl_map[] = { ++ /* DU (CN10: ARGB0, CN13: LVDS) */ ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", ++ "du0_rgb888", "du0"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", ++ "du0_sync_1", "du0"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", ++ "du0_clk_out_0", "du0"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", ++ "du1_rgb666", "du1"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", ++ "du1_sync_1", "du1"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7779", "pfc-r8a7779", ++ "du1_clk_out", "du1"), + /* HSPI0 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-hspi.0", "pfc-r8a7779", + "hspi0", "hspi0"), +@@ -297,6 +368,7 @@ static void __init marzen_init(void) + r8a7779_add_vin_device(1, &vin_platform_data); + r8a7779_add_vin_device(3, &vin_platform_data); + platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices)); ++ marzen_add_du_device(); + } + + static const char *marzen_boards_compat_dt[] __initdata = { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0144-ARM-shmobile-lager-Constify-platform-data-and-resour.patch b/patches.renesas/0144-ARM-shmobile-lager-Constify-platform-data-and-resour.patch new file mode 100644 index 00000000000000..2b0adc8d172884 --- /dev/null +++ b/patches.renesas/0144-ARM-shmobile-lager-Constify-platform-data-and-resour.patch @@ -0,0 +1,75 @@ +From d6c13c2feab5837fcef4e408d248088fc0745b05 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 8 Aug 2013 00:43:00 +0200 +Subject: ARM: shmobile: lager: Constify platform data and resources + +Platform data and resources for Lager devices are kmemdup()ed when the +corresponding devices are registered and can thus be declared as const. +Do so. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 27113d63daac0aacaa26b1fabfc23391de4284f4) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + arch/arm/mach-shmobile/board-lager.c +--- + arch/arm/mach-shmobile/board-lager.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c +index 6569491839cf..c1075f202602 100644 +--- a/arch/arm/mach-shmobile/board-lager.c ++++ b/arch/arm/mach-shmobile/board-lager.c +@@ -56,7 +56,7 @@ static struct gpio_led lager_leds[] = { + }, + }; + +-static __initdata struct gpio_led_platform_data lager_leds_pdata = { ++static const struct gpio_led_platform_data lager_leds_pdata __initconst = { + .leds = lager_leds, + .num_leds = ARRAY_SIZE(lager_leds), + }; +@@ -72,7 +72,7 @@ static struct gpio_keys_button gpio_buttons[] = { + GPIO_KEY(KEY_1, RCAR_GP_PIN(1, 14), "SW2-pin1"), + }; + +-static __initdata struct gpio_keys_platform_data lager_keys_pdata = { ++static const struct gpio_keys_platform_data lager_keys_pdata __initconst = { + .buttons = gpio_buttons, + .nbuttons = ARRAY_SIZE(gpio_buttons), + }; +@@ -84,24 +84,24 @@ static struct regulator_consumer_supply fixed3v3_power_consumers[] = + }; + + /* MMCIF */ +-static struct sh_mmcif_plat_data mmcif1_pdata __initdata = { ++static const struct sh_mmcif_plat_data mmcif1_pdata __initconst = { + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, + }; + +-static struct resource mmcif1_resources[] __initdata = { ++static const struct resource mmcif1_resources[] __initconst = { + DEFINE_RES_MEM_NAMED(0xee220000, 0x80, "MMCIF1"), + DEFINE_RES_IRQ(gic_spi(170)), + }; + + /* Ether */ +-static struct sh_eth_plat_data ether_pdata __initdata = { ++static const struct sh_eth_plat_data ether_pdata __initconst = { + .phy = 0x1, + .edmac_endian = EDMAC_LITTLE_ENDIAN, + .phy_interface = PHY_INTERFACE_MODE_RMII, + .ether_link_active_low = 1, + }; + +-static struct resource ether_resources[] __initdata = { ++static const struct resource ether_resources[] __initconst = { + DEFINE_RES_MEM(0xee700000, 0x400), + DEFINE_RES_IRQ(gic_spi(162)), + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0145-ARM-shmobile-lager-Add-Display-Unit-support.patch b/patches.renesas/0145-ARM-shmobile-lager-Add-Display-Unit-support.patch new file mode 100644 index 00000000000000..52b2c6d73662d2 --- /dev/null +++ b/patches.renesas/0145-ARM-shmobile-lager-Add-Display-Unit-support.patch @@ -0,0 +1,117 @@ +From a30ea55a9397e1f00a2607a8f95a4e76d3b195af Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Tue, 16 Apr 2013 12:39:11 +0200 +Subject: ARM: shmobile: lager: Add Display Unit support + +Only the VGA output is currently supported. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit c75a5afa44e71c99e1793824121608f0db48f014) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-lager.c | 66 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 66 insertions(+) + +diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c +index c1075f202602..6a0458901010 100644 +--- a/arch/arm/mach-shmobile/board-lager.c ++++ b/arch/arm/mach-shmobile/board-lager.c +@@ -28,6 +28,7 @@ + #include <linux/mmc/sh_mmcif.h> + #include <linux/pinctrl/machine.h> + #include <linux/platform_data/gpio-rcar.h> ++#include <linux/platform_data/rcar-du.h> + #include <linux/platform_device.h> + #include <linux/phy.h> + #include <linux/regulator/fixed.h> +@@ -39,6 +40,62 @@ + #include <asm/mach-types.h> + #include <asm/mach/arch.h> + ++/* DU */ ++static struct rcar_du_encoder_data lager_du_encoders[] = { ++ { ++ .type = RCAR_DU_ENCODER_VGA, ++ .output = RCAR_DU_OUTPUT_DPAD0, ++ }, { ++ .type = RCAR_DU_ENCODER_NONE, ++ .output = RCAR_DU_OUTPUT_LVDS1, ++ .connector.lvds.panel = { ++ .width_mm = 210, ++ .height_mm = 158, ++ .mode = { ++ .clock = 65000, ++ .hdisplay = 1024, ++ .hsync_start = 1048, ++ .hsync_end = 1184, ++ .htotal = 1344, ++ .vdisplay = 768, ++ .vsync_start = 771, ++ .vsync_end = 777, ++ .vtotal = 806, ++ .flags = 0, ++ }, ++ }, ++ }, ++}; ++ ++static const struct rcar_du_platform_data lager_du_pdata __initconst = { ++ .encoders = lager_du_encoders, ++ .num_encoders = ARRAY_SIZE(lager_du_encoders), ++}; ++ ++static const struct resource du_resources[] __initconst = { ++ DEFINE_RES_MEM(0xfeb00000, 0x70000), ++ DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"), ++ DEFINE_RES_MEM_NAMED(0xfeb94000, 0x1c, "lvds.1"), ++ DEFINE_RES_IRQ(gic_spi(256)), ++ DEFINE_RES_IRQ(gic_spi(268)), ++ DEFINE_RES_IRQ(gic_spi(269)), ++}; ++ ++static void __init lager_add_du_device(void) ++{ ++ struct platform_device_info info = { ++ .name = "rcar-du-r8a7790", ++ .id = -1, ++ .res = du_resources, ++ .num_res = ARRAY_SIZE(du_resources), ++ .data = &du_resources, ++ .size_data = sizeof(du_resources), ++ .dma_mask = DMA_BIT_MASK(32), ++ }; ++ ++ platform_device_register_full(&info); ++} ++ + /* LEDS */ + static struct gpio_led lager_leds[] = { + { +@@ -107,6 +164,13 @@ static const struct resource ether_resources[] __initconst = { + }; + + static const struct pinctrl_map lager_pinctrl_map[] = { ++ /* DU (CN10: ARGB0, CN13: LVDS) */ ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790", ++ "du_rgb666", "du"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790", ++ "du_sync_1", "du"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790", ++ "du_clk_out_0", "du"), + /* SCIF0 (CN19: DEBUG SERIAL0) */ + PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.6", "pfc-r8a7790", + "scif0_data", "scif0"), +@@ -154,6 +218,8 @@ static void __init lager_add_standard_devices(void) + ether_resources, + ARRAY_SIZE(ether_resources), + ðer_pdata, sizeof(ether_pdata)); ++ ++ lager_add_du_device(); + } + + /* +-- +1.8.5.rc3 + diff --git a/patches.renesas/0146-ARM-shmobile-ape6evm-update-MMC0-SDHI0-and-SDHI1-wit.patch b/patches.renesas/0146-ARM-shmobile-ape6evm-update-MMC0-SDHI0-and-SDHI1-wit.patch new file mode 100644 index 00000000000000..92863b0d3de289 --- /dev/null +++ b/patches.renesas/0146-ARM-shmobile-ape6evm-update-MMC0-SDHI0-and-SDHI1-wit.patch @@ -0,0 +1,105 @@ +From d5f2c37a6d85518f5297309a90be413728a8c14b Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Thu, 1 Aug 2013 09:41:20 +0200 +Subject: ARM: shmobile: ape6evm: update MMC0, SDHI0 and SDHI1 with correct + regulators + +Currently a dummy fixed always-on regulator is used for all 3 SD/MMC +interfaces on ape6evm. This patch updates the board to use correct supplies +for MMC0, SDHI0 and SDHI1 VDD. SDHI0 VccQ supply regulator should be +implemented in a separate patch. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 8b98126d2ce701c7367deee60739904e17864523) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-ape6evm.c | 54 +++++++++++++++++++++++++++++----- + 1 file changed, 46 insertions(+), 8 deletions(-) + +diff --git a/arch/arm/mach-shmobile/board-ape6evm.c b/arch/arm/mach-shmobile/board-ape6evm.c +index d36e23f5d8b7..7e5765b8fc0e 100644 +--- a/arch/arm/mach-shmobile/board-ape6evm.c ++++ b/arch/arm/mach-shmobile/board-ape6evm.c +@@ -113,16 +113,49 @@ static const struct smsc911x_platform_config lan9220_data __initconst = { + }; + + /* +- * On APE6EVM power is supplied to MMCIF by a tps80032 regulator. For now we +- * model a VDD supply to MMCIF, using a fixed 3.3V regulator. Also use the +- * static power supply for SDHI0 and SDHI1, whereas SDHI0's VccQ is also +- * supplied by the same tps80032 regulator and thus can also be adjusted +- * dynamically. ++ * MMC0 power supplies: ++ * Both Vcc and VccQ to eMMC on APE6EVM are supplied by a tps80032 voltage ++ * regulator. Until support for it is added to this file we simulate the ++ * Vcc supply by a fixed always-on regulator + */ +-static struct regulator_consumer_supply fixed3v3_power_consumers[] = ++static struct regulator_consumer_supply vcc_mmc0_consumers[] = + { + REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), ++}; ++ ++/* ++ * SDHI0 power supplies: ++ * Vcc to SDHI0 on APE6EVM is supplied by a GPIO-switchable regulator. VccQ is ++ * provided by the same tps80032 regulator as both MMC0 voltages - see comment ++ * above ++ */ ++static struct regulator_consumer_supply vcc_sdhi0_consumers[] = ++{ + REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), ++}; ++ ++static struct regulator_init_data vcc_sdhi0_init_data = { ++ .constraints = { ++ .valid_ops_mask = REGULATOR_CHANGE_STATUS, ++ }, ++ .num_consumer_supplies = ARRAY_SIZE(vcc_sdhi0_consumers), ++ .consumer_supplies = vcc_sdhi0_consumers, ++}; ++ ++static const struct fixed_voltage_config vcc_sdhi0_info __initconst = { ++ .supply_name = "SDHI0 Vcc", ++ .microvolts = 3300000, ++ .gpio = 76, ++ .enable_high = 1, ++ .init_data = &vcc_sdhi0_init_data, ++}; ++ ++/* ++ * SDHI1 power supplies: ++ * Vcc and VccQ to SDHI1 on APE6EVM are both fixed at 3.3V ++ */ ++static struct regulator_consumer_supply vcc_sdhi1_consumers[] = ++{ + REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), + }; + +@@ -215,14 +248,19 @@ static void __init ape6evm_add_standard_devices(void) + platform_device_register_resndata(&platform_bus, "smsc911x", -1, + lan9220_res, ARRAY_SIZE(lan9220_res), + &lan9220_data, sizeof(lan9220_data)); +- regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers, +- ARRAY_SIZE(fixed3v3_power_consumers), 3300000); ++ ++ regulator_register_always_on(1, "MMC0 Vcc", vcc_mmc0_consumers, ++ ARRAY_SIZE(vcc_mmc0_consumers), 2800000); + platform_device_register_resndata(&platform_bus, "sh_mmcif", 0, + mmcif0_resources, ARRAY_SIZE(mmcif0_resources), + &mmcif0_pdata, sizeof(mmcif0_pdata)); ++ platform_device_register_data(&platform_bus, "reg-fixed-voltage", 2, ++ &vcc_sdhi0_info, sizeof(vcc_sdhi0_info)); + platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 0, + sdhi0_resources, ARRAY_SIZE(sdhi0_resources), + &sdhi0_pdata, sizeof(sdhi0_pdata)); ++ regulator_register_always_on(3, "SDHI1 Vcc", vcc_sdhi1_consumers, ++ ARRAY_SIZE(vcc_sdhi1_consumers), 3300000); + platform_device_register_resndata(&platform_bus, "sh_mobile_sdhi", 1, + sdhi1_resources, ARRAY_SIZE(sdhi1_resources), + &sdhi1_pdata, sizeof(sdhi1_pdata)); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0147-ARM-shmobile-lager-Fix-Display-Unit-platform-data.patch b/patches.renesas/0147-ARM-shmobile-lager-Fix-Display-Unit-platform-data.patch new file mode 100644 index 00000000000000..9566524241ba1c --- /dev/null +++ b/patches.renesas/0147-ARM-shmobile-lager-Fix-Display-Unit-platform-data.patch @@ -0,0 +1,37 @@ +From f177e751768acb7246592c036ea103374631893c Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 22 Aug 2013 17:55:08 +0200 +Subject: ARM: shmobile: lager: Fix Display Unit platform data + +The DU device erroneously receives the DU resources array as platform +data instead of the DU platform data structure. Fix it. + +This problem was introduced by f631fa0 ("ARM: shmobile: lager: Add Display +Unit support"). + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 37bf8103c51a1508d6323de19a7ae1c13c3ed3f5) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-lager.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c +index 6a0458901010..1caeefa9d114 100644 +--- a/arch/arm/mach-shmobile/board-lager.c ++++ b/arch/arm/mach-shmobile/board-lager.c +@@ -88,8 +88,8 @@ static void __init lager_add_du_device(void) + .id = -1, + .res = du_resources, + .num_res = ARRAY_SIZE(du_resources), +- .data = &du_resources, +- .size_data = sizeof(du_resources), ++ .data = &lager_du_pdata, ++ .size_data = sizeof(lager_du_pdata), + .dma_mask = DMA_BIT_MASK(32), + }; + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0148-ARM-shmobile-bockw-enable-global-use-of-FPGA.patch b/patches.renesas/0148-ARM-shmobile-bockw-enable-global-use-of-FPGA.patch new file mode 100644 index 00000000000000..821eeb50c28710 --- /dev/null +++ b/patches.renesas/0148-ARM-shmobile-bockw-enable-global-use-of-FPGA.patch @@ -0,0 +1,67 @@ +From 35d5534ba78a272751c72b673e32e575c4a6b04e Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Mon, 26 Aug 2013 01:52:23 -0700 +Subject: ARM: shmobile: bockw: enable global use of FPGA + +This patch enables global use of FPGA, +since it will be used from many devices. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 71d7472f63385f4f6fb7c8548450b2e4665dc542) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-bockw.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c +index f2bf61bf2521..97e1f5e9e62f 100644 +--- a/arch/arm/mach-shmobile/board-bockw.c ++++ b/arch/arm/mach-shmobile/board-bockw.c +@@ -38,6 +38,10 @@ + #include <mach/r8a7778.h> + #include <asm/mach/arch.h> + ++#define FPGA 0x18200000 ++#define IRQ0MR 0x30 ++static void __iomem *fpga; ++ + /* + * CN9(Upper side) SCIF/RCAN selection + * +@@ -250,8 +254,6 @@ static const struct pinctrl_map bockw_pinctrl_map[] = { + "vin1_data8", "vin1"), + }; + +-#define FPGA 0x18200000 +-#define IRQ0MR 0x30 + #define PFC 0xfffc0000 + #define PUPR4 0x110 + static void __init bockw_init(void) +@@ -301,8 +303,8 @@ static void __init bockw_init(void) + + + /* for SMSC */ +- base = ioremap_nocache(FPGA, SZ_1M); +- if (base) { ++ fpga = ioremap_nocache(FPGA, SZ_1M); ++ if (fpga) { + /* + * CAUTION + * +@@ -310,10 +312,9 @@ static void __init bockw_init(void) + * it should be cared in the future + * Now, it is assuming IRQ0 was used only from SMSC. + */ +- u16 val = ioread16(base + IRQ0MR); ++ u16 val = ioread16(fpga + IRQ0MR); + val &= ~(1 << 4); /* enable SMSC911x */ +- iowrite16(val, base + IRQ0MR); +- iounmap(base); ++ iowrite16(val, fpga + IRQ0MR); + + regulator_register_fixed(0, dummy_supplies, + ARRAY_SIZE(dummy_supplies)); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0149-ARM-shmobile-bockw-add-R-Car-sound-support-PIO.patch b/patches.renesas/0149-ARM-shmobile-bockw-add-R-Car-sound-support-PIO.patch new file mode 100644 index 00000000000000..fd4eb1b2f9a77f --- /dev/null +++ b/patches.renesas/0149-ARM-shmobile-bockw-add-R-Car-sound-support-PIO.patch @@ -0,0 +1,382 @@ +From 12f0bdd346f66b3ac3aebe5a6b8e6c8bafb44835 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Mon, 26 Aug 2013 01:52:35 -0700 +Subject: ARM: shmobile: bockw: add R-Car sound support (PIO) + +This patch enables R-Car sound, +AK4643 (CN19) and AK4554 (CN20/CN21) codec chip +on Bock-W. + +But, it supports PIO transfer only at this point. +User can check sound settings (Dip-switch/PFC etc) +via this patch, but will get under/over flow error +when playback/capture. +Because PIO transfer via SSI will be interrupted +"sampling rate" times per 1 second. + +DMA transfer will be supported when HPB-DMAC was +enabled on r8a7778. + +You will notice strange ALSA sound card HW +numbering on Bock-W board. +This came from AK4554 strange format on playback/capture. +The format on playback/capture is same on "normal" codec chip, +but AK4554 was different. +Because of that, AK4554 playback/capture are +registered as a different sound card. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +[horms+renesas@verge.net.au: squashed cleanup of SND_SOC_xxx in + Kconfig by Kuninori Morimoto] +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +(cherry picked from commit 688e6a6df880ee70e76f6ec1991dd0f186c25329) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + arch/arm/mach-shmobile/board-bockw.c +--- + arch/arm/mach-shmobile/Kconfig | 2 + + arch/arm/mach-shmobile/board-bockw.c | 274 ++++++++++++++++++++++++++++++++++- + 2 files changed, 275 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig +index b45240512ce0..d01e4276b889 100644 +--- a/arch/arm/mach-shmobile/Kconfig ++++ b/arch/arm/mach-shmobile/Kconfig +@@ -168,6 +168,8 @@ config MACH_BOCKW + select RENESAS_INTC_IRQPIN + select REGULATOR_FIXED_VOLTAGE if REGULATOR + select USE_OF ++ select SND_SOC_AK4554 if SND_SIMPLE_CARD ++ select SND_SOC_AK4642 if SND_SIMPLE_CARD + + config MACH_BOCKW_REFERENCE + bool "BOCK-W - Reference Device Tree Implementation" +diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c +index 97e1f5e9e62f..dffaf6890041 100644 +--- a/arch/arm/mach-shmobile/board-bockw.c ++++ b/arch/arm/mach-shmobile/board-bockw.c +@@ -37,9 +37,12 @@ + #include <mach/irqs.h> + #include <mach/r8a7778.h> + #include <asm/mach/arch.h> ++#include <sound/rcar_snd.h> ++#include <sound/simple_card.h> + + #define FPGA 0x18200000 + #define IRQ0MR 0x30 ++#define COMCTLR 0x101c + static void __iomem *fpga; + + /* +@@ -67,6 +70,35 @@ static void __iomem *fpga; + * SW19 (MMC) 1 pin + */ + ++/* ++ * SSI settings ++ * ++ * SW45: 1-4 side (SSI5 out, ROUT/LOUT CN19 Mid) ++ * SW46: 1101 (SSI6 Recorde) ++ * SW47: 1110 (SSI5 Playback) ++ * SW48: 11 (Recorde power) ++ * SW49: 1 (SSI slave mode) ++ * SW50: 1111 (SSI7, SSI8) ++ * SW51: 1111 (SSI3, SSI4) ++ * SW54: 1pin (ak4554 FPGA control) ++ * SW55: 1 (CLKB is 24.5760MHz) ++ * SW60: 1pin (ak4554 FPGA control) ++ * SW61: 3pin (use X11 clock) ++ * SW78: 3-6 (ak4642 connects I2C0) ++ * ++ * You can use sound as ++ * ++ * hw0: CN19: SSI56-AK4643 ++ * hw1: CN21: SSI3-AK4554(playback) ++ * hw2: CN21: SSI4-AK4554(capture) ++ * hw3: CN20: SSI7-AK4554(playback) ++ * hw4: CN20: SSI8-AK4554(capture) ++ * ++ * this command is required when playback on hw0. ++ * ++ * # amixer set "LINEOUT Mixer DACL" on ++ */ ++ + /* Dummy supplies, where voltage doesn't matter */ + static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x"), +@@ -128,7 +160,9 @@ static struct sh_eth_plat_data ether_platform_data __initdata = { + static struct i2c_board_info i2c0_devices[] = { + { + I2C_BOARD_INFO("rx8581", 0x51), +- }, ++ }, { ++ I2C_BOARD_INFO("ak4643", 0x12), ++ } + }; + + /* HSPI*/ +@@ -211,7 +245,213 @@ static struct platform_device_info vin##idx##_info __initdata = { \ + R8A7778_VIN(0); + R8A7778_VIN(1); + ++/* Sound */ ++static struct resource rsnd_resources[] __initdata = { ++ [RSND_GEN1_SRU] = DEFINE_RES_MEM(0xffd90000, 0x1000), ++ [RSND_GEN1_SSI] = DEFINE_RES_MEM(0xffd91000, 0x1240), ++ [RSND_GEN1_ADG] = DEFINE_RES_MEM(0xfffe0000, 0x24), ++}; ++ ++static struct rsnd_ssi_platform_info rsnd_ssi[] = { ++ RSND_SSI_UNUSED, /* SSI 0 */ ++ RSND_SSI_UNUSED, /* SSI 1 */ ++ RSND_SSI_UNUSED, /* SSI 2 */ ++ RSND_SSI_SET(1, 0, gic_iid(0x85), RSND_SSI_PLAY), ++ RSND_SSI_SET(2, 0, gic_iid(0x85), RSND_SSI_CLK_PIN_SHARE | RSND_SSI_CLK_FROM_ADG), ++ RSND_SSI_SET(0, 0, gic_iid(0x86), RSND_SSI_PLAY), ++ RSND_SSI_SET(0, 0, gic_iid(0x86), 0), ++ RSND_SSI_SET(3, 0, gic_iid(0x86), RSND_SSI_PLAY), ++ RSND_SSI_SET(4, 0, gic_iid(0x86), RSND_SSI_CLK_PIN_SHARE | RSND_SSI_CLK_FROM_ADG), ++}; ++ ++static struct rsnd_scu_platform_info rsnd_scu[9] = { ++ /* no member at this point */ ++}; ++ ++enum { ++ AK4554_34 = 0, ++ AK4643_56, ++ AK4554_78, ++ SOUND_MAX, ++}; ++ ++static int rsnd_codec_power(int id, int enable) ++{ ++ static int sound_user[SOUND_MAX] = {0, 0, 0}; ++ int *usr = NULL; ++ u32 bit; ++ ++ switch (id) { ++ case 3: ++ case 4: ++ usr = sound_user + AK4554_34; ++ bit = (1 << 10); ++ break; ++ case 5: ++ case 6: ++ usr = sound_user + AK4643_56; ++ bit = (1 << 6); ++ break; ++ case 7: ++ case 8: ++ usr = sound_user + AK4554_78; ++ bit = (1 << 7); ++ break; ++ } ++ ++ if (!usr) ++ return -EIO; ++ ++ if (enable) { ++ if (*usr == 0) { ++ u32 val = ioread16(fpga + COMCTLR); ++ val &= ~bit; ++ iowrite16(val, fpga + COMCTLR); ++ } ++ ++ (*usr)++; ++ } else { ++ if (*usr == 0) ++ return 0; ++ ++ (*usr)--; ++ ++ if (*usr == 0) { ++ u32 val = ioread16(fpga + COMCTLR); ++ val |= bit; ++ iowrite16(val, fpga + COMCTLR); ++ } ++ } ++ ++ return 0; ++} ++ ++static int rsnd_start(int id) ++{ ++ return rsnd_codec_power(id, 1); ++} ++ ++static int rsnd_stop(int id) ++{ ++ return rsnd_codec_power(id, 0); ++} ++ ++static struct rcar_snd_info rsnd_info = { ++ .flags = RSND_GEN1, ++ .ssi_info = rsnd_ssi, ++ .ssi_info_nr = ARRAY_SIZE(rsnd_ssi), ++ .scu_info = rsnd_scu, ++ .scu_info_nr = ARRAY_SIZE(rsnd_scu), ++ .start = rsnd_start, ++ .stop = rsnd_stop, ++}; ++ ++static struct asoc_simple_card_info rsnd_card_info[] = { ++ /* SSI5, SSI6 */ ++ { ++ .name = "AK4643", ++ .card = "SSI56-AK4643", ++ .codec = "ak4642-codec.0-0012", ++ .platform = "rcar_sound", ++ .daifmt = SND_SOC_DAIFMT_LEFT_J, ++ .cpu_dai = { ++ .name = "rsnd-dai.0", ++ .fmt = SND_SOC_DAIFMT_CBS_CFS, ++ }, ++ .codec_dai = { ++ .name = "ak4642-hifi", ++ .fmt = SND_SOC_DAIFMT_CBM_CFM, ++ .sysclk = 11289600, ++ }, ++ }, ++ /* SSI3 */ ++ { ++ .name = "AK4554", ++ .card = "SSI3-AK4554(playback)", ++ .codec = "ak4554-adc-dac.0", ++ .platform = "rcar_sound", ++ .cpu_dai = { ++ .name = "rsnd-dai.1", ++ .fmt = SND_SOC_DAIFMT_CBM_CFM | ++ SND_SOC_DAIFMT_RIGHT_J, ++ }, ++ .codec_dai = { ++ .name = "ak4554-hifi", ++ }, ++ }, ++ /* SSI4 */ ++ { ++ .name = "AK4554", ++ .card = "SSI4-AK4554(capture)", ++ .codec = "ak4554-adc-dac.0", ++ .platform = "rcar_sound", ++ .cpu_dai = { ++ .name = "rsnd-dai.2", ++ .fmt = SND_SOC_DAIFMT_CBM_CFM | ++ SND_SOC_DAIFMT_LEFT_J, ++ }, ++ .codec_dai = { ++ .name = "ak4554-hifi", ++ }, ++ }, ++ /* SSI7 */ ++ { ++ .name = "AK4554", ++ .card = "SSI7-AK4554(playback)", ++ .codec = "ak4554-adc-dac.1", ++ .platform = "rcar_sound", ++ .cpu_dai = { ++ .name = "rsnd-dai.3", ++ .fmt = SND_SOC_DAIFMT_CBM_CFM | ++ SND_SOC_DAIFMT_RIGHT_J, ++ }, ++ .codec_dai = { ++ .name = "ak4554-hifi", ++ }, ++ }, ++ /* SSI8 */ ++ { ++ .name = "AK4554", ++ .card = "SSI8-AK4554(capture)", ++ .codec = "ak4554-adc-dac.1", ++ .platform = "rcar_sound", ++ .cpu_dai = { ++ .name = "rsnd-dai.4", ++ .fmt = SND_SOC_DAIFMT_CBM_CFM | ++ SND_SOC_DAIFMT_LEFT_J, ++ }, ++ .codec_dai = { ++ .name = "ak4554-hifi", ++ }, ++ } ++}; ++ + static const struct pinctrl_map bockw_pinctrl_map[] = { ++ /* AUDIO */ ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", ++ "audio_clk_a", "audio_clk"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", ++ "audio_clk_b", "audio_clk"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", ++ "ssi34_ctrl", "ssi"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", ++ "ssi3_data", "ssi"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", ++ "ssi4_data", "ssi"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", ++ "ssi5_ctrl", "ssi"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", ++ "ssi5_data", "ssi"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", ++ "ssi6_ctrl", "ssi"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", ++ "ssi6_data", "ssi"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", ++ "ssi78_ctrl", "ssi"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", ++ "ssi7_data", "ssi"), ++ PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7778", ++ "ssi8_data", "ssi"), + /* Ether */ + PIN_MAP_MUX_GROUP_DEFAULT("r8a777x-ether", "pfc-r8a7778", + "ether_rmii", "ether"), +@@ -259,6 +499,8 @@ static const struct pinctrl_map bockw_pinctrl_map[] = { + static void __init bockw_init(void) + { + void __iomem *base; ++ struct clk *clk; ++ int i; + + r8a7778_clock_init(); + r8a7778_init_irq_extpin(1); +@@ -341,6 +583,36 @@ static void __init bockw_init(void) + sdhi0_resources, ARRAY_SIZE(sdhi0_resources), + &sdhi0_info, sizeof(struct sh_mobile_sdhi_info)); + } ++ ++ /* for Audio */ ++ clk = clk_get(NULL, "audio_clk_b"); ++ clk_set_rate(clk, 24576000); ++ clk_put(clk); ++ rsnd_codec_power(5, 1); /* enable ak4642 */ ++ ++ platform_device_register_simple( ++ "ak4554-adc-dac", 0, NULL, 0); ++ ++ platform_device_register_simple( ++ "ak4554-adc-dac", 1, NULL, 0); ++ ++ platform_device_register_resndata( ++ &platform_bus, "rcar_sound", -1, ++ rsnd_resources, ARRAY_SIZE(rsnd_resources), ++ &rsnd_info, sizeof(rsnd_info)); ++ ++ for (i = 0; i < ARRAY_SIZE(rsnd_card_info); i++) { ++ struct platform_device_info cardinfo = { ++ .parent = &platform_bus, ++ .name = "asoc-simple-card", ++ .id = i, ++ .data = &rsnd_card_info[i], ++ .size_data = sizeof(struct asoc_simple_card_info), ++ .dma_mask = ~0, ++ }; ++ ++ platform_device_register_full(&cardinfo); ++ } + } + + static const char *bockw_boards_compat_dt[] __initdata = { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0150-ARM-shmobile-Koelsch-support.patch b/patches.renesas/0150-ARM-shmobile-Koelsch-support.patch new file mode 100644 index 00000000000000..0c648f30afc609 --- /dev/null +++ b/patches.renesas/0150-ARM-shmobile-Koelsch-support.patch @@ -0,0 +1,171 @@ +From 5965ca866cfdd485558ebd587a73ee92320dbf89 Mon Sep 17 00:00:00 2001 +From: Hisashi Nakamura <hisashi.nakamura.ak@renesas.com> +Date: Wed, 4 Sep 2013 12:46:49 +0900 +Subject: ARM: shmobile: Koelsch support + +Koelsch base board support making use of 2 GiB of memory, +the r8a7791 SoC with the SCIF0 serial port and CA15 with +CMT timer. + +Signed-off-by: Hisashi Nakamura <hisashi.nakamura.ak@renesas.com> +Signed-off-by: Ryo Kataoka <ryo.kataoka.wt@renesas.com> +[damm@opensource.se: Forward ported to upstream, dropped not-yet-ready SMP/PFC] +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +(cherry picked from commit 1f52c65975ba16cdba1830ba216776111197a3ee) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/r8a7791-koelsch.dts | 32 +++++++++++++++++++++++++ + arch/arm/mach-shmobile/Kconfig | 5 ++++ + arch/arm/mach-shmobile/Makefile | 1 + + arch/arm/mach-shmobile/Makefile.boot | 1 + + arch/arm/mach-shmobile/board-koelsch.c | 44 ++++++++++++++++++++++++++++++++++ + 6 files changed, 84 insertions(+) + create mode 100644 arch/arm/boot/dts/r8a7791-koelsch.dts + create mode 100644 arch/arm/mach-shmobile/board-koelsch.c + +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index fa0ae75fd32a..037cf904677b 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -167,6 +167,7 @@ dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \ + r8a7740-armadillo800eva-reference.dtb \ + r8a7779-marzen.dtb \ + r8a7779-marzen-reference.dtb \ ++ r8a7791-koelsch.dtb \ + r8a7790-lager.dtb \ + r8a7790-lager-reference.dtb \ + sh73a0-kzm9g.dtb \ +diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts +new file mode 100644 +index 000000000000..1ce5250ec278 +--- /dev/null ++++ b/arch/arm/boot/dts/r8a7791-koelsch.dts +@@ -0,0 +1,32 @@ ++/* ++ * Device Tree Source for the Koelsch board ++ * ++ * Copyright (C) 2013 Renesas Electronics Corporation ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++/dts-v1/; ++/include/ "r8a7791.dtsi" ++ ++/ { ++ model = "Koelsch"; ++ compatible = "renesas,koelsch", "renesas,r8a7791"; ++ ++ chosen { ++ bootargs = "console=ttySC6,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp"; ++ }; ++ ++ memory@40000000 { ++ device_type = "memory"; ++ reg = <0 0x40000000 0 0x80000000>; ++ }; ++ ++ lbsc { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ }; ++}; +diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig +index d01e4276b889..eda285794961 100644 +--- a/arch/arm/mach-shmobile/Kconfig ++++ b/arch/arm/mach-shmobile/Kconfig +@@ -221,6 +221,11 @@ config MACH_LAGER_REFERENCE + + This is intended to aid developers + ++config MACH_KOELSCH ++ bool "Koelsch board" ++ depends on ARCH_R8A7791 ++ select USE_OF ++ + config MACH_KZM9D + bool "KZM9D board" + depends on ARCH_EMEV2 +diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile +index 228193cc9a38..e552e84b1fae 100644 +--- a/arch/arm/mach-shmobile/Makefile ++++ b/arch/arm/mach-shmobile/Makefile +@@ -61,6 +61,7 @@ obj-$(CONFIG_MACH_LAGER) += board-lager.o + obj-$(CONFIG_MACH_LAGER_REFERENCE) += board-lager-reference.o + obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o + obj-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += board-armadillo800eva-reference.o ++obj-$(CONFIG_MACH_KOELSCH) += board-koelsch.o + obj-$(CONFIG_MACH_KZM9D) += board-kzm9d.o + obj-$(CONFIG_MACH_KZM9D_REFERENCE) += board-kzm9d-reference.o + obj-$(CONFIG_MACH_KZM9G) += board-kzm9g.o +diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot +index 6a504fe7d86c..60e29e6c1126 100644 +--- a/arch/arm/mach-shmobile/Makefile.boot ++++ b/arch/arm/mach-shmobile/Makefile.boot +@@ -6,6 +6,7 @@ loadaddr-$(CONFIG_MACH_ARMADILLO800EVA) += 0x40008000 + loadaddr-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += 0x40008000 + loadaddr-$(CONFIG_MACH_BOCKW) += 0x60008000 + loadaddr-$(CONFIG_MACH_BOCKW_REFERENCE) += 0x60008000 ++loadaddr-$(CONFIG_MACH_KOELSCH) += 0x40008000 + loadaddr-$(CONFIG_MACH_KZM9D) += 0x40008000 + loadaddr-$(CONFIG_MACH_KZM9D_REFERENCE) += 0x40008000 + loadaddr-$(CONFIG_MACH_KZM9G) += 0x41008000 +diff --git a/arch/arm/mach-shmobile/board-koelsch.c b/arch/arm/mach-shmobile/board-koelsch.c +new file mode 100644 +index 000000000000..cc2d5e82b59a +--- /dev/null ++++ b/arch/arm/mach-shmobile/board-koelsch.c +@@ -0,0 +1,44 @@ ++/* ++ * Koelsch board support ++ * ++ * Copyright (C) 2013 Renesas Electronics Corporation ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * Copyright (C) 2013 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/platform_device.h> ++#include <mach/common.h> ++#include <mach/r8a7791.h> ++#include <asm/mach-types.h> ++#include <asm/mach/arch.h> ++ ++static void __init koelsch_add_standard_devices(void) ++{ ++ r8a7791_clock_init(); ++ r8a7791_add_dt_devices(); ++} ++ ++static const char * const koelsch_boards_compat_dt[] __initconst = { ++ "renesas,koelsch", ++ NULL, ++}; ++ ++DT_MACHINE_START(KOELSCH_DT, "koelsch") ++ .init_early = r8a7791_init_early, ++ .init_machine = koelsch_add_standard_devices, ++ .dt_compat = koelsch_boards_compat_dt, ++MACHINE_END +-- +1.8.5.rc3 + diff --git a/patches.renesas/0151-ARM-shmobile-bockw-add-USB-Function-support.patch b/patches.renesas/0151-ARM-shmobile-bockw-add-USB-Function-support.patch new file mode 100644 index 00000000000000..534c2f8b455a29 --- /dev/null +++ b/patches.renesas/0151-ARM-shmobile-bockw-add-USB-Function-support.patch @@ -0,0 +1,151 @@ +From 25ffe3228079915b2379358f5b1de49e2ef455ce Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Sun, 4 Aug 2013 17:43:37 -0700 +Subject: ARM: shmobile: bockw: add USB Function support + +Bock-W USB1 (CN29) can be USB Host/Func by SW98/SW99 settings. +USB Func will be enabled if CONFIG_USB_RENESAS_USBHS_UDC[_MODULE] +was selected on this patch + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 81a0d9062d5c93490b215d2440bbd7deb3918707) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-bockw.c | 81 ++++++++++++++++++++++++++++++++++-- + 1 file changed, 78 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c +index dffaf6890041..0559f217a5fd 100644 +--- a/arch/arm/mach-shmobile/board-bockw.c ++++ b/arch/arm/mach-shmobile/board-bockw.c +@@ -32,6 +32,7 @@ + #include <linux/smsc911x.h> + #include <linux/spi/spi.h> + #include <linux/spi/flash.h> ++#include <linux/usb/renesas_usbhs.h> + #include <media/soc_camera.h> + #include <mach/common.h> + #include <mach/irqs.h> +@@ -99,6 +100,16 @@ static void __iomem *fpga; + * # amixer set "LINEOUT Mixer DACL" on + */ + ++/* ++ * USB ++ * ++ * USB1 (CN29) can be Host/Function ++ * ++ * Host Func ++ * SW98 1 2 ++ * SW99 1 3 ++ */ ++ + /* Dummy supplies, where voltage doesn't matter */ + static struct regulator_consumer_supply dummy_supplies[] = { + REGULATOR_SUPPLY("vddvario", "smsc911x"), +@@ -117,13 +128,71 @@ static struct resource smsc911x_resources[] __initdata = { + DEFINE_RES_IRQ(irq_pin(0)), /* IRQ 0 */ + }; + ++#if IS_ENABLED(CONFIG_USB_RENESAS_USBHS_UDC) ++/* ++ * When USB1 is Func ++ */ ++static int usbhsf_get_id(struct platform_device *pdev) ++{ ++ return USBHS_GADGET; ++} ++ ++#define SUSPMODE 0x102 ++static int usbhsf_power_ctrl(struct platform_device *pdev, ++ void __iomem *base, int enable) ++{ ++ enable = !!enable; ++ ++ r8a7778_usb_phy_power(enable); ++ ++ iowrite16(enable << 14, base + SUSPMODE); ++ ++ return 0; ++} ++ ++static struct resource usbhsf_resources[] __initdata = { ++ DEFINE_RES_MEM(0xffe60000, 0x110), ++ DEFINE_RES_IRQ(gic_iid(0x4f)), ++}; ++ ++static struct renesas_usbhs_platform_info usbhs_info __initdata = { ++ .platform_callback = { ++ .get_id = usbhsf_get_id, ++ .power_ctrl = usbhsf_power_ctrl, ++ }, ++ .driver_param = { ++ .buswait_bwait = 4, ++ }, ++}; ++ ++#define USB_PHY_SETTING {.port1_func = 1, .ovc_pin[1].active_high = 1,} ++#define USB1_DEVICE "renesas_usbhs" ++#define ADD_USB_FUNC_DEVICE_IF_POSSIBLE() \ ++ platform_device_register_resndata( \ ++ &platform_bus, "renesas_usbhs", -1, \ ++ usbhsf_resources, \ ++ ARRAY_SIZE(usbhsf_resources), \ ++ &usbhs_info, sizeof(struct renesas_usbhs_platform_info)) ++ ++#else ++/* ++ * When USB1 is Host ++ */ ++#define USB_PHY_SETTING { } ++#define USB1_DEVICE "ehci-platform" ++#define ADD_USB_FUNC_DEVICE_IF_POSSIBLE() ++ ++#endif ++ + /* USB */ + static struct resource usb_phy_resources[] __initdata = { + DEFINE_RES_MEM(0xffe70800, 0x100), + DEFINE_RES_MEM(0xffe76000, 0x100), + }; + +-static struct rcar_phy_platform_data usb_phy_platform_data __initdata; ++static struct rcar_phy_platform_data usb_phy_platform_data __initdata = ++ USB_PHY_SETTING; ++ + + /* SDHI */ + static struct sh_mobile_sdhi_info sdhi0_info __initdata = { +@@ -471,7 +540,7 @@ static const struct pinctrl_map bockw_pinctrl_map[] = { + /* USB */ + PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform", "pfc-r8a7778", + "usb0", "usb0"), +- PIN_MAP_MUX_GROUP_DEFAULT("ehci-platform", "pfc-r8a7778", ++ PIN_MAP_MUX_GROUP_DEFAULT(USB1_DEVICE, "pfc-r8a7778", + "usb1", "usb1"), + /* SDHI0 */ + PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7778", +@@ -615,6 +684,12 @@ static void __init bockw_init(void) + } + } + ++static void __init bockw_init_late(void) ++{ ++ r8a7778_init_late(); ++ ADD_USB_FUNC_DEVICE_IF_POSSIBLE(); ++} ++ + static const char *bockw_boards_compat_dt[] __initdata = { + "renesas,bockw", + NULL, +@@ -625,5 +700,5 @@ DT_MACHINE_START(BOCKW_DT, "bockw") + .init_irq = r8a7778_init_irq_dt, + .init_machine = bockw_init, + .dt_compat = bockw_boards_compat_dt, +- .init_late = r8a7778_init_late, ++ .init_late = bockw_init_late, + MACHINE_END +-- +1.8.5.rc3 + diff --git a/patches.renesas/0152-ARM-shmobile-ape6evm-disable-MMCIF-Command-Completio.patch b/patches.renesas/0152-ARM-shmobile-ape6evm-disable-MMCIF-Command-Completio.patch new file mode 100644 index 00000000000000..438c97adecb2ab --- /dev/null +++ b/patches.renesas/0152-ARM-shmobile-ape6evm-disable-MMCIF-Command-Completio.patch @@ -0,0 +1,31 @@ +From fd94bbdd8a2bbc36fc9498051e96be2b7381a95c Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Wed, 10 Jul 2013 21:21:16 +0200 +Subject: ARM: shmobile: ape6evm: disable MMCIF Command Completion Signal + +MMCIF on r8a73a4 doesn't support Command Completion Signal, a platform +parameter has to be added to disable it on ape6evm. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit a2eeabcceb3eb2646b0064b55b8ff0eb6f1ae13d) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-ape6evm.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/mach-shmobile/board-ape6evm.c b/arch/arm/mach-shmobile/board-ape6evm.c +index 7e5765b8fc0e..7627385f516e 100644 +--- a/arch/arm/mach-shmobile/board-ape6evm.c ++++ b/arch/arm/mach-shmobile/board-ape6evm.c +@@ -162,6 +162,7 @@ static struct regulator_consumer_supply vcc_sdhi1_consumers[] = + /* MMCIF */ + static const struct sh_mmcif_plat_data mmcif0_pdata __initconst = { + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, ++ .ccs_unsupported = true, + }; + + static const struct resource mmcif0_resources[] __initconst = { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0153-ARM-shmobile-armadillo800eva-disable-MMCIF-Command-C.patch b/patches.renesas/0153-ARM-shmobile-armadillo800eva-disable-MMCIF-Command-C.patch new file mode 100644 index 00000000000000..aba8fefa63c145 --- /dev/null +++ b/patches.renesas/0153-ARM-shmobile-armadillo800eva-disable-MMCIF-Command-C.patch @@ -0,0 +1,32 @@ +From 21470759763d5dea51d61b305907ea36bddcc6b3 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Wed, 10 Jul 2013 21:21:14 +0200 +Subject: ARM: shmobile: armadillo800eva: disable MMCIF Command Completion + Signal + +MMCIF on r8a7740 doesn't support Command Completion Signal, a platform +parameter has to be added to disable it on armadillo800eva. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit fbf3264c046a6cce4cefec6e069fc86c0175f7d3) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-armadillo800eva.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c +index 068025844e99..4a11fd34a6e7 100644 +--- a/arch/arm/mach-shmobile/board-armadillo800eva.c ++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c +@@ -822,6 +822,7 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = { + .caps = MMC_CAP_4_BIT_DATA | + MMC_CAP_8_BIT_DATA | + MMC_CAP_NONREMOVABLE, ++ .ccs_unsupported = true, + .slave_id_tx = SHDMA_SLAVE_MMCIF_TX, + .slave_id_rx = SHDMA_SLAVE_MMCIF_RX, + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0154-ARM-shmobile-kzm9g-disable-MMCIF-Command-Completion-.patch b/patches.renesas/0154-ARM-shmobile-kzm9g-disable-MMCIF-Command-Completion-.patch new file mode 100644 index 00000000000000..b32c6a251a88c8 --- /dev/null +++ b/patches.renesas/0154-ARM-shmobile-kzm9g-disable-MMCIF-Command-Completion-.patch @@ -0,0 +1,31 @@ +From 3e52030ce6ca133c945044201aefacbb6e188730 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Wed, 10 Jul 2013 21:21:15 +0200 +Subject: ARM: shmobile: kzm9g: disable MMCIF Command Completion Signal + +MMCIF on sh73a0 doesn't support Command Completion Signal, a platform +parameter has to be added to disable it on kzm9g. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 58d0bbd1a734831262157f006306f084dda9605d) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-kzm9g.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c +index b30ef47dc769..68af069fda6e 100644 +--- a/arch/arm/mach-shmobile/board-kzm9g.c ++++ b/arch/arm/mach-shmobile/board-kzm9g.c +@@ -365,6 +365,7 @@ static struct resource sh_mmcif_resources[] = { + static struct sh_mmcif_plat_data sh_mmcif_platdata = { + .ocr = MMC_VDD_165_195, + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, ++ .ccs_unsupported = true, + .slave_id_tx = SHDMA_SLAVE_MMCIF_TX, + .slave_id_rx = SHDMA_SLAVE_MMCIF_RX, + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0155-ARM-shmobile-lager-disable-MMCIF-Command-Completion-.patch b/patches.renesas/0155-ARM-shmobile-lager-disable-MMCIF-Command-Completion-.patch new file mode 100644 index 00000000000000..ce15b86e1d928f --- /dev/null +++ b/patches.renesas/0155-ARM-shmobile-lager-disable-MMCIF-Command-Completion-.patch @@ -0,0 +1,34 @@ +From faeaa252b6a4370a09ef192aae4f05838e390a01 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Wed, 10 Jul 2013 21:21:17 +0200 +Subject: ARM: shmobile: lager: disable MMCIF Command Completion Signal, add + CLK_CTRL2 + +MMCIF on r8a7790 doesn't support Command Completion Signal, but it does +implement a CE_CLK_CTRL2 register. Platform parameters have to be added to +account for these features on lager. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit b77c6bcef2082a7cd96124daf15df8da5b670ebe) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-lager.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c +index 1caeefa9d114..245ce5bdbbf2 100644 +--- a/arch/arm/mach-shmobile/board-lager.c ++++ b/arch/arm/mach-shmobile/board-lager.c +@@ -143,6 +143,8 @@ static struct regulator_consumer_supply fixed3v3_power_consumers[] = + /* MMCIF */ + static const struct sh_mmcif_plat_data mmcif1_pdata __initconst = { + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, ++ .clk_ctrl2_present = true, ++ .ccs_unsupported = true, + }; + + static const struct resource mmcif1_resources[] __initconst = { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0156-ARM-shmobile-Shared-APMU-SMP-support-code-without-DT.patch b/patches.renesas/0156-ARM-shmobile-Shared-APMU-SMP-support-code-without-DT.patch new file mode 100644 index 00000000000000..6a90fa17a78519 --- /dev/null +++ b/patches.renesas/0156-ARM-shmobile-Shared-APMU-SMP-support-code-without-DT.patch @@ -0,0 +1,227 @@ +From 9542463afa890c66077635bc6d3ced1d731bc13a Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 29 Aug 2013 08:21:58 +0900 +Subject: ARM: shmobile: Shared APMU SMP support code without DT + +Introduce shared APMU SMP code for mach-shmobile. Both SMP boot up +and CPU Hotplug is supported. This version does not use DT but +if needed this will be added as an incremental feature patch. + +The code is designed around CONFIG_NR_CPUS and should in theory support +any number of APMUs, however due to the current DT-less static design +only a single APMU is supported. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit a112de8c7ae231f396e28160e84d0eab3a79dffc) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/include/mach/common.h | 6 + + arch/arm/mach-shmobile/platsmp-apmu.c | 178 +++++++++++++++++++++++++++ + 2 files changed, 184 insertions(+) + create mode 100644 arch/arm/mach-shmobile/platsmp-apmu.c + +diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h +index cfe397716fd1..3460bb13c988 100644 +--- a/arch/arm/mach-shmobile/include/mach/common.h ++++ b/arch/arm/mach-shmobile/include/mach/common.h +@@ -22,6 +22,12 @@ extern int shmobile_smp_scu_boot_secondary(unsigned int cpu, + struct task_struct *idle); + extern void shmobile_smp_scu_cpu_die(unsigned int cpu); + extern int shmobile_smp_scu_cpu_kill(unsigned int cpu); ++extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus); ++extern int shmobile_smp_apmu_boot_secondary(unsigned int cpu, ++ struct task_struct *idle); ++extern void shmobile_smp_apmu_cpu_die(unsigned int cpu); ++extern int shmobile_smp_apmu_cpu_kill(unsigned int cpu); ++extern void shmobile_invalidate_start(void); + struct clk; + extern int shmobile_clk_init(void); + extern void shmobile_handle_irq_intc(struct pt_regs *); +diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c +new file mode 100644 +index 000000000000..34dc40dacb79 +--- /dev/null ++++ b/arch/arm/mach-shmobile/platsmp-apmu.c +@@ -0,0 +1,178 @@ ++/* ++ * SMP support for SoCs with APMU ++ * ++ * Copyright (C) 2013 Magnus Damm ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ */ ++#include <linux/delay.h> ++#include <linux/init.h> ++#include <linux/io.h> ++#include <linux/ioport.h> ++#include <linux/of_address.h> ++#include <linux/smp.h> ++#include <asm/cacheflush.h> ++#include <asm/cp15.h> ++#include <asm/smp_plat.h> ++#include <mach/common.h> ++ ++static struct { ++ void __iomem *iomem; ++ int bit; ++} apmu_cpus[CONFIG_NR_CPUS]; ++ ++#define WUPCR_OFFS 0x10 ++#define PSTR_OFFS 0x40 ++#define CPUNCR_OFFS(n) (0x100 + (0x10 * (n))) ++ ++static int apmu_power_on(void __iomem *p, int bit) ++{ ++ /* request power on */ ++ writel_relaxed(BIT(bit), p + WUPCR_OFFS); ++ ++ /* wait for APMU to finish */ ++ while (readl_relaxed(p + WUPCR_OFFS) != 0) ++ ; ++ ++ return 0; ++} ++ ++static int apmu_power_off(void __iomem *p, int bit) ++{ ++ /* request Core Standby for next WFI */ ++ writel_relaxed(3, p + CPUNCR_OFFS(bit)); ++ return 0; ++} ++ ++static int apmu_power_off_poll(void __iomem *p, int bit) ++{ ++ int k; ++ ++ for (k = 0; k < 1000; k++) { ++ if (((readl_relaxed(p + PSTR_OFFS) >> (bit * 4)) & 0x03) == 3) ++ return 1; ++ ++ mdelay(1); ++ } ++ ++ return 0; ++} ++ ++static int apmu_wrap(int cpu, int (*fn)(void __iomem *p, int cpu)) ++{ ++ void __iomem *p = apmu_cpus[cpu].iomem; ++ ++ return p ? fn(p, apmu_cpus[cpu].bit) : -EINVAL; ++} ++ ++static void apmu_init_cpu(struct resource *res, int cpu, int bit) ++{ ++ if (apmu_cpus[cpu].iomem) ++ return; ++ ++ apmu_cpus[cpu].iomem = ioremap_nocache(res->start, resource_size(res)); ++ apmu_cpus[cpu].bit = bit; ++ ++ pr_debug("apmu ioremap %d %d 0x%08x 0x%08x\n", cpu, bit, ++ res->start, resource_size(res)); ++} ++ ++static struct { ++ struct resource iomem; ++ int cpus[4]; ++} apmu_config[] = { ++ { ++ .iomem = DEFINE_RES_MEM(0xe6152000, 0x88), ++ .cpus = { 0, 1, 2, 3 }, ++ } ++}; ++ ++static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit)) ++{ ++ u32 id; ++ int k; ++ int bit, index; ++ ++ for (k = 0; k < ARRAY_SIZE(apmu_config); k++) { ++ for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) { ++ id = apmu_config[k].cpus[bit]; ++ if (id >= 0) { ++ index = get_logical_index(id); ++ if (index >= 0) ++ fn(&apmu_config[k].iomem, index, bit); ++ } ++ } ++ } ++} ++ ++void __init shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus) ++{ ++ /* install boot code shared by all CPUs */ ++ shmobile_boot_fn = virt_to_phys(shmobile_smp_boot); ++ shmobile_boot_arg = MPIDR_HWID_BITMASK; ++ ++ /* perform per-cpu setup */ ++ apmu_parse_cfg(apmu_init_cpu); ++} ++ ++int shmobile_smp_apmu_boot_secondary(unsigned int cpu, struct task_struct *idle) ++{ ++ /* For this particular CPU register boot vector */ ++ shmobile_smp_hook(cpu, virt_to_phys(shmobile_invalidate_start), 0); ++ ++ return apmu_wrap(cpu, apmu_power_on); ++} ++ ++#ifdef CONFIG_HOTPLUG_CPU ++/* nicked from arch/arm/mach-exynos/hotplug.c */ ++static inline void cpu_enter_lowpower_a15(void) ++{ ++ unsigned int v; ++ ++ asm volatile( ++ " mrc p15, 0, %0, c1, c0, 0\n" ++ " bic %0, %0, %1\n" ++ " mcr p15, 0, %0, c1, c0, 0\n" ++ : "=&r" (v) ++ : "Ir" (CR_C) ++ : "cc"); ++ ++ flush_cache_louis(); ++ ++ asm volatile( ++ /* ++ * Turn off coherency ++ */ ++ " mrc p15, 0, %0, c1, c0, 1\n" ++ " bic %0, %0, %1\n" ++ " mcr p15, 0, %0, c1, c0, 1\n" ++ : "=&r" (v) ++ : "Ir" (0x40) ++ : "cc"); ++ ++ isb(); ++ dsb(); ++} ++ ++void shmobile_smp_apmu_cpu_die(unsigned int cpu) ++{ ++ /* For this particular CPU deregister boot vector */ ++ shmobile_smp_hook(cpu, 0, 0); ++ ++ /* Select next sleep mode using the APMU */ ++ apmu_wrap(cpu, apmu_power_off); ++ ++ /* Do ARM specific CPU shutdown */ ++ cpu_enter_lowpower_a15(); ++ ++ /* jump to shared mach-shmobile sleep / reset code */ ++ shmobile_smp_sleep(); ++} ++ ++int shmobile_smp_apmu_cpu_kill(unsigned int cpu) ++{ ++ return apmu_wrap(cpu, apmu_power_off_poll); ++} ++#endif +-- +1.8.5.rc3 + diff --git a/patches.renesas/0157-ARM-shmobile-Add-r8a7790-SMP-support-using-APMU-code.patch b/patches.renesas/0157-ARM-shmobile-Add-r8a7790-SMP-support-using-APMU-code.patch new file mode 100644 index 00000000000000..05bb547137e6cc --- /dev/null +++ b/patches.renesas/0157-ARM-shmobile-Add-r8a7790-SMP-support-using-APMU-code.patch @@ -0,0 +1,159 @@ +From 30a3f666271d60017a6233de44ed684203b4ec6d Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 29 Aug 2013 08:22:07 +0900 +Subject: ARM: shmobile: Add r8a7790 SMP support using APMU code + +Add r8a7790 SMP support using the shared APMU code. To enable +SMP the r8a7790 specific DTS needs to be updated to include +CPU cores, and this is happening in a separate patch. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit ad09cb83811b228eb6f98230d307bb837e6a758f) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/Makefile | 1 + + arch/arm/mach-shmobile/board-lager-reference.c | 1 + + arch/arm/mach-shmobile/board-lager.c | 1 + + arch/arm/mach-shmobile/include/mach/r8a7790.h | 1 + + arch/arm/mach-shmobile/setup-r8a7790.c | 1 + + arch/arm/mach-shmobile/smp-r8a7790.c | 67 ++++++++++++++++++++++++++ + 6 files changed, 72 insertions(+) + create mode 100644 arch/arm/mach-shmobile/smp-r8a7790.c + +diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile +index e552e84b1fae..f8f699212984 100644 +--- a/arch/arm/mach-shmobile/Makefile ++++ b/arch/arm/mach-shmobile/Makefile +@@ -36,6 +36,7 @@ endif + smp-y := platsmp.o headsmp.o + smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o platsmp-scu.o + smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o platsmp-scu.o ++smp-$(CONFIG_ARCH_R8A7790) += smp-r8a7790.o platsmp-apmu.o + smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o + + # IRQ objects +diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c +index 2856f51ff8a6..d39a91b3ba48 100644 +--- a/arch/arm/mach-shmobile/board-lager-reference.c ++++ b/arch/arm/mach-shmobile/board-lager-reference.c +@@ -38,6 +38,7 @@ static const char *lager_boards_compat_dt[] __initdata = { + }; + + DT_MACHINE_START(LAGER_DT, "lager") ++ .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, + .init_machine = lager_add_standard_devices, + .init_time = r8a7790_timer_init, +diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c +index 245ce5bdbbf2..ba90fea55156 100644 +--- a/arch/arm/mach-shmobile/board-lager.c ++++ b/arch/arm/mach-shmobile/board-lager.c +@@ -254,6 +254,7 @@ static const char *lager_boards_compat_dt[] __initdata = { + }; + + DT_MACHINE_START(LAGER_DT, "lager") ++ .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, + .init_time = r8a7790_timer_init, + .init_machine = lager_init, +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h +index 177a8372abb7..79e731c83e50 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a7790.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h +@@ -7,6 +7,7 @@ void r8a7790_clock_init(void); + void r8a7790_pinmux_init(void); + void r8a7790_init_early(void); + void r8a7790_timer_init(void); ++extern struct smp_operations r8a7790_smp_ops; + + #define MD(nr) BIT(nr) + u32 r8a7790_read_mode_pins(void); +diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c +index e0d29a265c2d..c7e24eff9ba2 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7790.c ++++ b/arch/arm/mach-shmobile/setup-r8a7790.c +@@ -283,6 +283,7 @@ static const char * const r8a7790_boards_compat_dt[] __initconst = { + }; + + DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)") ++ .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, + .init_time = r8a7790_timer_init, + .dt_compat = r8a7790_boards_compat_dt, +diff --git a/arch/arm/mach-shmobile/smp-r8a7790.c b/arch/arm/mach-shmobile/smp-r8a7790.c +new file mode 100644 +index 000000000000..015e2753de1f +--- /dev/null ++++ b/arch/arm/mach-shmobile/smp-r8a7790.c +@@ -0,0 +1,67 @@ ++/* ++ * SMP support for r8a7790 ++ * ++ * Copyright (C) 2012-2013 Renesas Solutions Corp. ++ * Copyright (C) 2012 Takashi Yoshii <takashi.yoshii.ze@renesas.com> ++ * ++ * 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. ++ */ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/smp.h> ++#include <linux/io.h> ++#include <asm/smp_plat.h> ++#include <mach/common.h> ++ ++#define RST 0xe6160000 ++#define CA15BAR 0x0020 ++#define CA7BAR 0x0030 ++#define CA15RESCNT 0x0040 ++#define CA7RESCNT 0x0044 ++#define MERAM 0xe8080000 ++ ++static void __init r8a7790_smp_prepare_cpus(unsigned int max_cpus) ++{ ++ void __iomem *p; ++ u32 bar; ++ ++ /* let APMU code install data related to shmobile_boot_vector */ ++ shmobile_smp_apmu_prepare_cpus(max_cpus); ++ ++ /* MERAM for jump stub, because BAR requires 256KB aligned address */ ++ p = ioremap_nocache(MERAM, shmobile_boot_size); ++ memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); ++ iounmap(p); ++ ++ /* setup reset vectors */ ++ p = ioremap_nocache(RST, 0x63); ++ bar = (MERAM >> 8) & 0xfffffc00; ++ writel_relaxed(bar, p + CA15BAR); ++ writel_relaxed(bar, p + CA7BAR); ++ writel_relaxed(bar | 0x10, p + CA15BAR); ++ writel_relaxed(bar | 0x10, p + CA7BAR); ++ ++ /* enable clocks to all CPUs */ ++ writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000, ++ p + CA15RESCNT); ++ writel_relaxed((readl_relaxed(p + CA7RESCNT) & ~0x0f) | 0x5a5a0000, ++ p + CA7RESCNT); ++ iounmap(p); ++} ++ ++struct smp_operations r8a7790_smp_ops __initdata = { ++ .smp_prepare_cpus = r8a7790_smp_prepare_cpus, ++ .smp_boot_secondary = shmobile_smp_apmu_boot_secondary, ++#ifdef CONFIG_HOTPLUG_CPU ++ .cpu_disable = shmobile_smp_cpu_disable, ++ .cpu_die = shmobile_smp_apmu_cpu_die, ++ .cpu_kill = shmobile_smp_apmu_cpu_kill, ++#endif ++}; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0158-ARM-shmobile-Add-CPU-notifier-based-SCU-boot-vector-.patch b/patches.renesas/0158-ARM-shmobile-Add-CPU-notifier-based-SCU-boot-vector-.patch new file mode 100644 index 00000000000000..0d061f3d1def4a --- /dev/null +++ b/patches.renesas/0158-ARM-shmobile-Add-CPU-notifier-based-SCU-boot-vector-.patch @@ -0,0 +1,71 @@ +From efd48a2af3bab7ed75a5280b82031db349a919ac Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Sat, 14 Sep 2013 22:46:25 +0900 +Subject: ARM: shmobile: Add CPU notifier based SCU boot vector code + +Add CPU notifiers for the shared mach-shmobile SCU code +to allow removal of the shared SCU boot_secondary code. + +Regarding notifiers, at CPU_UP_PREPARE time the SMP boot +vector is initialized so secondary CPU cores can boot. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 916d6121b5947f162979595cc1c0396192a9aa86) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/platsmp-scu.c | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/arch/arm/mach-shmobile/platsmp-scu.c b/arch/arm/mach-shmobile/platsmp-scu.c +index c96f50160be6..49ae8dfc625d 100644 +--- a/arch/arm/mach-shmobile/platsmp-scu.c ++++ b/arch/arm/mach-shmobile/platsmp-scu.c +@@ -7,6 +7,7 @@ + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ ++#include <linux/cpu.h> + #include <linux/delay.h> + #include <linux/init.h> + #include <linux/io.h> +@@ -16,6 +17,26 @@ + #include <asm/smp_scu.h> + #include <mach/common.h> + ++static int shmobile_smp_scu_notifier_call(struct notifier_block *nfb, ++ unsigned long action, void *hcpu) ++{ ++ unsigned int cpu = (long)hcpu; ++ ++ switch (action) { ++ case CPU_UP_PREPARE: ++ /* For this particular CPU register SCU SMP boot vector */ ++ shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu), ++ (unsigned long)shmobile_scu_base); ++ break; ++ }; ++ ++ return NOTIFY_OK; ++} ++ ++static struct notifier_block shmobile_smp_scu_notifier = { ++ .notifier_call = shmobile_smp_scu_notifier_call, ++}; ++ + void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus) + { + /* install boot code shared by all CPUs */ +@@ -25,6 +46,9 @@ void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus) + /* enable SCU and cache coherency on booting CPU */ + scu_enable(shmobile_scu_base); + scu_power_mode(shmobile_scu_base, SCU_PM_NORMAL); ++ ++ /* Use CPU notifier for reset vector control */ ++ register_cpu_notifier(&shmobile_smp_scu_notifier); + } + + int shmobile_smp_scu_boot_secondary(unsigned int cpu, struct task_struct *idle) +-- +1.8.5.rc3 + diff --git a/patches.renesas/0159-ARM-shmobile-Let-sh73a0-rely-on-SCU-CPU-notifier.patch b/patches.renesas/0159-ARM-shmobile-Let-sh73a0-rely-on-SCU-CPU-notifier.patch new file mode 100644 index 00000000000000..3ada91299c34c7 --- /dev/null +++ b/patches.renesas/0159-ARM-shmobile-Let-sh73a0-rely-on-SCU-CPU-notifier.patch @@ -0,0 +1,36 @@ +From 8f4ba329a647827a3fc2036f05fff70e5d8bf4f6 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Sat, 14 Sep 2013 22:46:34 +0900 +Subject: ARM: shmobile: Let sh73a0 rely on SCU CPU notifier + +Now when CPU notifiers are used for SCU boot vector +setup shmobile_smp_scu_boot_secondary() is no longer +needed. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 344bc8b0c85a63cd2d946376a391e74f4ea0ae46) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/smp-sh73a0.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c +index 25ddffc96bcf..494cd061448e 100644 +--- a/arch/arm/mach-shmobile/smp-sh73a0.c ++++ b/arch/arm/mach-shmobile/smp-sh73a0.c +@@ -46,11 +46,6 @@ void __init sh73a0_register_twd(void) + static int __cpuinit sh73a0_boot_secondary(unsigned int cpu, struct task_struct *idle) + { + unsigned int lcpu = cpu_logical_map(cpu); +- int ret; +- +- ret = shmobile_smp_scu_boot_secondary(cpu, idle); +- if (ret) +- return ret; + + if (((__raw_readl(PSTR) >> (4 * lcpu)) & 3) == 3) + __raw_writel(1 << lcpu, WUPCR); /* wake up */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0160-ARM-shmobile-Let-EMEV2-rely-on-SCU-CPU-notifier.patch b/patches.renesas/0160-ARM-shmobile-Let-EMEV2-rely-on-SCU-CPU-notifier.patch new file mode 100644 index 00000000000000..7b54902312ef6b --- /dev/null +++ b/patches.renesas/0160-ARM-shmobile-Let-EMEV2-rely-on-SCU-CPU-notifier.patch @@ -0,0 +1,37 @@ +From 2cc476e457b47528854abab2af334e87a965c321 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Sat, 14 Sep 2013 22:46:43 +0900 +Subject: ARM: shmobile: Let EMEV2 rely on SCU CPU notifier + +Now when CPU notifiers are used for SCU boot vector +setup shmobile_smp_scu_boot_secondary() is no longer +needed. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 344c62f7a65f9124d5262e34dab66d581081a3a7) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/smp-emev2.c | 6 ------ + 1 file changed, 6 deletions(-) + +diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c +index d1c101db776b..a514dfc21e3b 100644 +--- a/arch/arm/mach-shmobile/smp-emev2.c ++++ b/arch/arm/mach-shmobile/smp-emev2.c +@@ -34,12 +34,6 @@ + + static int __cpuinit emev2_boot_secondary(unsigned int cpu, struct task_struct *idle) + { +- int ret; +- +- ret = shmobile_smp_scu_boot_secondary(cpu, idle); +- if (ret) +- return ret; +- + arch_send_wakeup_ipi_mask(cpumask_of(cpu_logical_map(cpu))); + return 0; + } +-- +1.8.5.rc3 + diff --git a/patches.renesas/0161-ARM-shmobile-Let-r8a7779-rely-on-SCU-CPU-notifier.patch b/patches.renesas/0161-ARM-shmobile-Let-r8a7779-rely-on-SCU-CPU-notifier.patch new file mode 100644 index 00000000000000..7f382c8647bd43 --- /dev/null +++ b/patches.renesas/0161-ARM-shmobile-Let-r8a7779-rely-on-SCU-CPU-notifier.patch @@ -0,0 +1,35 @@ +From 609f3a92ae979c6e5a6bc7132ca5ebcdf7639d8f Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Sat, 14 Sep 2013 22:46:52 +0900 +Subject: ARM: shmobile: Let r8a7779 rely on SCU CPU notifier + +Now when CPU notifiers are used for SCU boot vector +setup shmobile_smp_scu_boot_secondary() is no longer +needed. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit deb4928ea39c5eeef1c9f4562b5cee71f06a31ad) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/smp-r8a7779.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c +index c159964ea56e..7d30fb5eb15f 100644 +--- a/arch/arm/mach-shmobile/smp-r8a7779.c ++++ b/arch/arm/mach-shmobile/smp-r8a7779.c +@@ -87,10 +87,6 @@ static int __cpuinit r8a7779_boot_secondary(unsigned int cpu, struct task_struct + unsigned int lcpu = cpu_logical_map(cpu); + int ret; + +- ret = shmobile_smp_scu_boot_secondary(cpu, idle); +- if (ret) +- return ret; +- + if (lcpu < ARRAY_SIZE(r8a7779_ch_cpu)) + ch = r8a7779_ch_cpu[lcpu]; + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0162-ARM-shmobile-Remove-shmobile_smp_scu_boot_secondary.patch b/patches.renesas/0162-ARM-shmobile-Remove-shmobile_smp_scu_boot_secondary.patch new file mode 100644 index 00000000000000..ee47b7c24ce536 --- /dev/null +++ b/patches.renesas/0162-ARM-shmobile-Remove-shmobile_smp_scu_boot_secondary.patch @@ -0,0 +1,53 @@ +From 965b91050766a1a95a65d32503dd048d30378c04 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Sat, 14 Sep 2013 22:47:02 +0900 +Subject: ARM: shmobile: Remove shmobile_smp_scu_boot_secondary() + +Remove shmobile_smp_scu_boot_secondary() since +it is no longer used. CPU boot vector setup is +instead handled by CPU notifiers. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit e4550216ef8245b1c9892239a2121a7b15ac2e91) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/include/mach/common.h | 2 -- + arch/arm/mach-shmobile/platsmp-scu.c | 8 -------- + 2 files changed, 10 deletions(-) + +diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h +index 3460bb13c988..e31980590eb4 100644 +--- a/arch/arm/mach-shmobile/include/mach/common.h ++++ b/arch/arm/mach-shmobile/include/mach/common.h +@@ -18,8 +18,6 @@ extern int shmobile_smp_cpu_disable(unsigned int cpu); + extern void shmobile_invalidate_start(void); + extern void shmobile_boot_scu(void); + extern void shmobile_smp_scu_prepare_cpus(unsigned int max_cpus); +-extern int shmobile_smp_scu_boot_secondary(unsigned int cpu, +- struct task_struct *idle); + extern void shmobile_smp_scu_cpu_die(unsigned int cpu); + extern int shmobile_smp_scu_cpu_kill(unsigned int cpu); + extern void shmobile_smp_apmu_prepare_cpus(unsigned int max_cpus); +diff --git a/arch/arm/mach-shmobile/platsmp-scu.c b/arch/arm/mach-shmobile/platsmp-scu.c +index 49ae8dfc625d..673ad6e80869 100644 +--- a/arch/arm/mach-shmobile/platsmp-scu.c ++++ b/arch/arm/mach-shmobile/platsmp-scu.c +@@ -51,14 +51,6 @@ void __init shmobile_smp_scu_prepare_cpus(unsigned int max_cpus) + register_cpu_notifier(&shmobile_smp_scu_notifier); + } + +-int shmobile_smp_scu_boot_secondary(unsigned int cpu, struct task_struct *idle) +-{ +- /* For this particular CPU register SCU boot vector */ +- shmobile_smp_hook(cpu, virt_to_phys(shmobile_boot_scu), +- (unsigned long)shmobile_scu_base); +- return 0; +-} +- + #ifdef CONFIG_HOTPLUG_CPU + void shmobile_smp_scu_cpu_die(unsigned int cpu) + { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0163-ARM-shmobile-Extend-APMU-code-to-allow-single-cluste.patch b/patches.renesas/0163-ARM-shmobile-Extend-APMU-code-to-allow-single-cluste.patch new file mode 100644 index 00000000000000..afcd1103b6a411 --- /dev/null +++ b/patches.renesas/0163-ARM-shmobile-Extend-APMU-code-to-allow-single-cluste.patch @@ -0,0 +1,56 @@ +From 1383ffca9f4697366ec18fd24737e01a27e91422 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Sun, 15 Sep 2013 00:29:07 +0900 +Subject: ARM: shmobile: Extend APMU code to allow single cluster only + +Extend the APMU code with a check to only allow boot +of CPU cores that sit in the same cluster as CPU0. + +This makes it possible for people to use the r8a790 +CA7 boot mode with CA7-cores only. The default CA15 +boot mode will enable CA15 cores only. This is an +intentional software limitation to cope with lacking +scheduler support. + +By removing this patch it is possible to run all 8 cores +in parallel, but this is not recommended without out of tree +scheduler modfications or custom user space code to control +the CPU affinitiy. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit ee490bcc4f2d456c40df93236cf6a1bce2d5ddd0) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/platsmp-apmu.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c +index 34dc40dacb79..caaaa35b589f 100644 +--- a/arch/arm/mach-shmobile/platsmp-apmu.c ++++ b/arch/arm/mach-shmobile/platsmp-apmu.c +@@ -94,8 +94,21 @@ static void apmu_parse_cfg(void (*fn)(struct resource *res, int cpu, int bit)) + u32 id; + int k; + int bit, index; ++ bool is_allowed; + + for (k = 0; k < ARRAY_SIZE(apmu_config); k++) { ++ /* only enable the cluster that includes the boot CPU */ ++ is_allowed = false; ++ for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) { ++ id = apmu_config[k].cpus[bit]; ++ if (id >= 0) { ++ if (id == cpu_logical_map(0)) ++ is_allowed = true; ++ } ++ } ++ if (!is_allowed) ++ continue; ++ + for (bit = 0; bit < ARRAY_SIZE(apmu_config[k].cpus); bit++) { + id = apmu_config[k].cpus[bit]; + if (id >= 0) { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0164-ARM-shmobile-Include-CA7-cores-in-APMU-table.patch b/patches.renesas/0164-ARM-shmobile-Include-CA7-cores-in-APMU-table.patch new file mode 100644 index 00000000000000..386b333e9b7d42 --- /dev/null +++ b/patches.renesas/0164-ARM-shmobile-Include-CA7-cores-in-APMU-table.patch @@ -0,0 +1,37 @@ +From 72ce6b83935aefda90c1fbb145556da36cba4db0 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Sun, 15 Sep 2013 00:29:16 +0900 +Subject: ARM: shmobile: Include CA7 cores in APMU table + +Add information to the shared APMU code regarding +the APMU instance used to control the CA7 cores. + +This can be used on r8a7790 and r8a73a4, but should +most likely be converted to DT in the future. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 43651b15de94d6a5e188ea032311e9661ec708d2) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/platsmp-apmu.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm/mach-shmobile/platsmp-apmu.c b/arch/arm/mach-shmobile/platsmp-apmu.c +index caaaa35b589f..1da5a72d9642 100644 +--- a/arch/arm/mach-shmobile/platsmp-apmu.c ++++ b/arch/arm/mach-shmobile/platsmp-apmu.c +@@ -86,6 +86,10 @@ static struct { + { + .iomem = DEFINE_RES_MEM(0xe6152000, 0x88), + .cpus = { 0, 1, 2, 3 }, ++ }, ++ { ++ .iomem = DEFINE_RES_MEM(0xe6151000, 0x88), ++ .cpus = { 0x100, 0x101, 0x102, 0x103 }, + } + }; + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0165-ARM-shmobile-ape6evm-fix-incorrect-placement-of-__in.patch b/patches.renesas/0165-ARM-shmobile-ape6evm-fix-incorrect-placement-of-__in.patch new file mode 100644 index 00000000000000..21a16a27e43dac --- /dev/null +++ b/patches.renesas/0165-ARM-shmobile-ape6evm-fix-incorrect-placement-of-__in.patch @@ -0,0 +1,34 @@ +From 5432fad55ba4199262b6da5e1e3349be6d6d4bc0 Mon Sep 17 00:00:00 2001 +From: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> +Date: Mon, 30 Sep 2013 17:34:36 +0200 +Subject: ARM: shmobile: ape6evm: fix incorrect placement of __initdata tag + +__initdata tag should be placed between the variable name and equal +sign for the variable to be placed in the intended .init.data section. + +Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> +Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> +Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 40fca03cae59cfd9b87142ca327abb8a4d386908) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-ape6evm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/board-ape6evm.c b/arch/arm/mach-shmobile/board-ape6evm.c +index 7627385f516e..3016f2f8e006 100644 +--- a/arch/arm/mach-shmobile/board-ape6evm.c ++++ b/arch/arm/mach-shmobile/board-ape6evm.c +@@ -86,7 +86,7 @@ static struct gpio_keys_button gpio_buttons[] = { + GPIO_KEY(KEY_VOLUMEDOWN, 329, "S21"), + }; + +-static struct __initdata gpio_keys_platform_data ape6evm_keys_pdata = { ++static struct gpio_keys_platform_data ape6evm_keys_pdata __initdata = { + .buttons = gpio_buttons, + .nbuttons = ARRAY_SIZE(gpio_buttons), + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0166-ARM-shmobile-only-enable-used-I2C-interfaces-in-DT-o.patch b/patches.renesas/0166-ARM-shmobile-only-enable-used-I2C-interfaces-in-DT-o.patch new file mode 100644 index 00000000000000..41e22ac37b56a8 --- /dev/null +++ b/patches.renesas/0166-ARM-shmobile-only-enable-used-I2C-interfaces-in-DT-o.patch @@ -0,0 +1,262 @@ +From 975a4951f0c101b50c0c25f2dfb5057f85e8fea3 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Thu, 26 Sep 2013 13:06:01 +0200 +Subject: ARM: shmobile: only enable used I2C interfaces in DT on all Renesas + boards + +Currently all I2C interfaces in all *.dtsi files for various Renesas SoCs +are enabled by default. Switch them all off and only enable populated I2C +interfaces in board-specific *.dts files. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Acked-by: Mark Rutland <mark.rutland@arm.com> +Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit eda3a4fa9529341f2ce23374e5f295764d0b5838) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts | 1 + + arch/arm/boot/dts/r8a73a4-ape6evm.dts | 1 + + arch/arm/boot/dts/r8a73a4.dtsi | 9 +++++++++ + arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts | 1 + + arch/arm/boot/dts/r8a7740.dtsi | 2 ++ + arch/arm/boot/dts/r8a7779.dtsi | 4 ++++ + arch/arm/boot/dts/sh73a0-kzm9g-reference.dts | 2 ++ + arch/arm/boot/dts/sh73a0.dtsi | 5 +++++ + 8 files changed, 25 insertions(+) + +diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts b/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts +index 2b49b05ae2f4..9443e93d3cac 100644 +--- a/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts ++++ b/arch/arm/boot/dts/r8a73a4-ape6evm-reference.dts +@@ -62,6 +62,7 @@ + }; + + &i2c5 { ++ status = "okay"; + vdd_dvfs: max8973@1b { + compatible = "maxim,max8973"; + reg = <0x1b>; +diff --git a/arch/arm/boot/dts/r8a73a4-ape6evm.dts b/arch/arm/boot/dts/r8a73a4-ape6evm.dts +index 72f867e65791..91436b58016f 100644 +--- a/arch/arm/boot/dts/r8a73a4-ape6evm.dts ++++ b/arch/arm/boot/dts/r8a73a4-ape6evm.dts +@@ -52,6 +52,7 @@ + }; + + &i2c5 { ++ status = "okay"; + vdd_dvfs: max8973@1b { + compatible = "maxim,max8973"; + reg = <0x1b>; +diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi +index 658fcc537576..6048825e00c7 100644 +--- a/arch/arm/boot/dts/r8a73a4.dtsi ++++ b/arch/arm/boot/dts/r8a73a4.dtsi +@@ -93,6 +93,7 @@ + reg = <0 0xe6500000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 174 0x4>; ++ status = "disabled"; + }; + + i2c1: i2c@e6510000 { +@@ -102,6 +103,7 @@ + reg = <0 0xe6510000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 175 0x4>; ++ status = "disabled"; + }; + + i2c2: i2c@e6520000 { +@@ -111,6 +113,7 @@ + reg = <0 0xe6520000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 176 0x4>; ++ status = "disabled"; + }; + + i2c3: i2c@e6530000 { +@@ -120,6 +123,7 @@ + reg = <0 0xe6530000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 177 0x4>; ++ status = "disabled"; + }; + + i2c4: i2c@e6540000 { +@@ -129,6 +133,7 @@ + reg = <0 0xe6540000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 178 0x4>; ++ status = "disabled"; + }; + + i2c5: i2c@e60b0000 { +@@ -138,6 +143,7 @@ + reg = <0 0xe60b0000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 179 0x4>; ++ status = "disabled"; + }; + + i2c6: i2c@e6550000 { +@@ -147,6 +153,7 @@ + reg = <0 0xe6550000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 184 0x4>; ++ status = "disabled"; + }; + + i2c7: i2c@e6560000 { +@@ -156,6 +163,7 @@ + reg = <0 0xe6560000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 185 0x4>; ++ status = "disabled"; + }; + + i2c8: i2c@e6570000 { +@@ -165,6 +173,7 @@ + reg = <0 0xe6570000 0 0x428>; + interrupt-parent = <&gic>; + interrupts = <0 173 0x4>; ++ status = "disabled"; + }; + + mmcif0: mmcif@ee200000 { +diff --git a/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts b/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts +index c638e4ab91b8..9fcffc175da2 100644 +--- a/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts ++++ b/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts +@@ -52,6 +52,7 @@ + }; + + &i2c0 { ++ status = "okay"; + touchscreen: st1232@55 { + compatible = "sitronix,st1232"; + reg = <0x55>; +diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi +index 44d3d520e01f..868bdded237c 100644 +--- a/arch/arm/boot/dts/r8a7740.dtsi ++++ b/arch/arm/boot/dts/r8a7740.dtsi +@@ -131,6 +131,7 @@ + 0 202 0x4 + 0 203 0x4 + 0 204 0x4>; ++ status = "disabled"; + }; + + i2c1: i2c@e6c20000 { +@@ -143,6 +144,7 @@ + 0 71 0x4 + 0 72 0x4 + 0 73 0x4>; ++ status = "disabled"; + }; + + pfc: pfc@e6050000 { +diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi +index ebbe507fcbfa..912b3a04901e 100644 +--- a/arch/arm/boot/dts/r8a7779.dtsi ++++ b/arch/arm/boot/dts/r8a7779.dtsi +@@ -156,6 +156,7 @@ + reg = <0xffc70000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 79 0x4>; ++ status = "disabled"; + }; + + i2c1: i2c@ffc71000 { +@@ -165,6 +166,7 @@ + reg = <0xffc71000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 82 0x4>; ++ status = "disabled"; + }; + + i2c2: i2c@ffc72000 { +@@ -174,6 +176,7 @@ + reg = <0xffc72000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 80 0x4>; ++ status = "disabled"; + }; + + i2c3: i2c@ffc73000 { +@@ -183,6 +186,7 @@ + reg = <0xffc73000 0x1000>; + interrupt-parent = <&gic>; + interrupts = <0 81 0x4>; ++ status = "disabled"; + }; + + pfc: pfc@fffc0000 { +diff --git a/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts +index 212230629f27..8ee06dd81799 100644 +--- a/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts ++++ b/arch/arm/boot/dts/sh73a0-kzm9g-reference.dts +@@ -108,6 +108,7 @@ + }; + + &i2c0 { ++ status = "okay"; + as3711@40 { + compatible = "ams,as3711"; + reg = <0x40>; +@@ -183,6 +184,7 @@ + &i2c3 { + pinctrl-0 = <&i2c3_pins>; + pinctrl-names = "default"; ++ status = "okay"; + }; + + &mmcif { +diff --git a/arch/arm/boot/dts/sh73a0.dtsi b/arch/arm/boot/dts/sh73a0.dtsi +index 3955c7606a6f..fcf26889a8a0 100644 +--- a/arch/arm/boot/dts/sh73a0.dtsi ++++ b/arch/arm/boot/dts/sh73a0.dtsi +@@ -135,6 +135,7 @@ + 0 168 0x4 + 0 169 0x4 + 0 170 0x4>; ++ status = "disabled"; + }; + + i2c1: i2c@e6822000 { +@@ -147,6 +148,7 @@ + 0 52 0x4 + 0 53 0x4 + 0 54 0x4>; ++ status = "disabled"; + }; + + i2c2: i2c@e6824000 { +@@ -159,6 +161,7 @@ + 0 172 0x4 + 0 173 0x4 + 0 174 0x4>; ++ status = "disabled"; + }; + + i2c3: i2c@e6826000 { +@@ -171,6 +174,7 @@ + 0 184 0x4 + 0 185 0x4 + 0 186 0x4>; ++ status = "disabled"; + }; + + i2c4: i2c@e6828000 { +@@ -183,6 +187,7 @@ + 0 188 0x4 + 0 189 0x4 + 0 190 0x4>; ++ status = "disabled"; + }; + + mmcif: mmcif@e6bd0000 { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0167-ARM-shmobile-r8a7790-add-I2C-DT-nodes.patch b/patches.renesas/0167-ARM-shmobile-r8a7790-add-I2C-DT-nodes.patch new file mode 100644 index 00000000000000..2b9c5849f93f0d --- /dev/null +++ b/patches.renesas/0167-ARM-shmobile-r8a7790-add-I2C-DT-nodes.patch @@ -0,0 +1,69 @@ +From f7ac6e978b662a92f5108df35e0f9a1b8401ddb3 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Thu, 26 Sep 2013 19:20:58 +0200 +Subject: ARM: shmobile: r8a7790: add I2C DT nodes + +Add DT nodes for the four I2C interfacces on r8a7790. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit edd2b9f4e6ed39032ffe9793e262c8a4b62c2152) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a7790.dtsi | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi +index 28fc18c9601b..ee845fad939b 100644 +--- a/arch/arm/boot/dts/r8a7790.dtsi ++++ b/arch/arm/boot/dts/r8a7790.dtsi +@@ -176,6 +176,46 @@ + interrupts = <0 0 4>, <0 1 4>, <0 2 4>, <0 3 4>; + }; + ++ i2c0: i2c@e6508000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "renesas,i2c-r8a7790"; ++ reg = <0 0xe6508000 0 0x40>; ++ interrupt-parent = <&gic>; ++ interrupts = <0 287 0x4>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@e6518000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "renesas,i2c-r8a7790"; ++ reg = <0 0xe6518000 0 0x40>; ++ interrupt-parent = <&gic>; ++ interrupts = <0 288 0x4>; ++ status = "disabled"; ++ }; ++ ++ i2c2: i2c@e6530000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "renesas,i2c-r8a7790"; ++ reg = <0 0xe6530000 0 0x40>; ++ interrupt-parent = <&gic>; ++ interrupts = <0 286 0x4>; ++ status = "disabled"; ++ }; ++ ++ i2c3: i2c@e6540000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "renesas,i2c-r8a7790"; ++ reg = <0 0xe6540000 0 0x40>; ++ interrupt-parent = <&gic>; ++ interrupts = <0 290 0x4>; ++ status = "disabled"; ++ }; ++ + mmcif0: mmcif@ee200000 { + compatible = "renesas,sh-mmcif"; + reg = <0 0xee200000 0 0x80>; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0168-ARM-shmobile-r8a73a4-add-a-DT-node-for-the-DMAC.patch b/patches.renesas/0168-ARM-shmobile-r8a73a4-add-a-DT-node-for-the-DMAC.patch new file mode 100644 index 00000000000000..b964019cbf14ac --- /dev/null +++ b/patches.renesas/0168-ARM-shmobile-r8a73a4-add-a-DT-node-for-the-DMAC.patch @@ -0,0 +1,75 @@ +From dc4b85701eaea3ba555f2402917cd1458e77291f Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Thu, 26 Sep 2013 19:30:03 +0200 +Subject: ARM: shmobile: r8a73a4: add a DT node for the DMAC + +Add a DT node for the only system DMAC instance on r8a73a4. The RT DMAC +can be added later under the same multiplexer, because they can serve the +same slaves and use the same MID-RID values. Configuration data is +supplied to the driver, using a compatibility match string. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 734e2ce38c6aa3e88f0a339f001d272196f26dfa) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a73a4.dtsi | 43 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 43 insertions(+) + +diff --git a/arch/arm/boot/dts/r8a73a4.dtsi b/arch/arm/boot/dts/r8a73a4.dtsi +index 6048825e00c7..287e047592a0 100644 +--- a/arch/arm/boot/dts/r8a73a4.dtsi ++++ b/arch/arm/boot/dts/r8a73a4.dtsi +@@ -78,6 +78,49 @@ + <0 56 4>, <0 57 4>; + }; + ++ dmac: dma-multiplexer@0 { ++ compatible = "renesas,shdma-mux"; ++ #dma-cells = <1>; ++ dma-channels = <20>; ++ dma-requests = <256>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ dma0: dma-controller@e6700020 { ++ compatible = "renesas,shdma-r8a73a4"; ++ reg = <0 0xe6700020 0 0x89e0>; ++ interrupt-parent = <&gic>; ++ interrupts = <0 220 4 ++ 0 200 4 ++ 0 201 4 ++ 0 202 4 ++ 0 203 4 ++ 0 204 4 ++ 0 205 4 ++ 0 206 4 ++ 0 207 4 ++ 0 208 4 ++ 0 209 4 ++ 0 210 4 ++ 0 211 4 ++ 0 212 4 ++ 0 213 4 ++ 0 214 4 ++ 0 215 4 ++ 0 216 4 ++ 0 217 4 ++ 0 218 4 ++ 0 219 4>; ++ interrupt-names = "error", ++ "ch0", "ch1", "ch2", "ch3", ++ "ch4", "ch5", "ch6", "ch7", ++ "ch8", "ch9", "ch10", "ch11", ++ "ch12", "ch13", "ch14", "ch15", ++ "ch16", "ch17", "ch18", "ch19"; ++ }; ++ }; ++ + thermal@e61f0000 { + compatible = "renesas,rcar-thermal"; + reg = <0 0xe61f0000 0 0x14>, <0 0xe61f0100 0 0x38>, +-- +1.8.5.rc3 + diff --git a/patches.renesas/0169-ARM-shmobile-armadillo-reference-Add-PWM-backlight-n.patch b/patches.renesas/0169-ARM-shmobile-armadillo-reference-Add-PWM-backlight-n.patch new file mode 100644 index 00000000000000..0a1526113260e7 --- /dev/null +++ b/patches.renesas/0169-ARM-shmobile-armadillo-reference-Add-PWM-backlight-n.patch @@ -0,0 +1,58 @@ +From 69bf024e7b7de5714f19e5221c15a16563a80847 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Wed, 11 Sep 2013 13:51:13 +0200 +Subject: ARM: shmobile: armadillo-reference: Add PWM backlight node to DT + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 87b73d88723601636646a69445f89c0e498fff71) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + .../boot/dts/r8a7740-armadillo800eva-reference.dts | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts b/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts +index 9fcffc175da2..8b2aab5c1d3c 100644 +--- a/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts ++++ b/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts +@@ -11,6 +11,7 @@ + /dts-v1/; + /include/ "r8a7740.dtsi" + #include <dt-bindings/gpio/gpio.h> ++#include <dt-bindings/pwm/pwm.h> + + / { + model = "armadillo 800 eva reference"; +@@ -49,6 +50,15 @@ + gpios = <&pfc 177 GPIO_ACTIVE_HIGH>; + }; + }; ++ ++ backlight { ++ compatible = "pwm-backlight"; ++ pwms = <&tpu 2 33333 PWM_POLARITY_INVERTED>; ++ brightness-levels = <0 1 2 4 8 16 32 64 128 255>; ++ default-brightness-level = <9>; ++ pinctrl-0 = <&backlight_pins>; ++ pinctrl-names = "default"; ++ }; + }; + + &i2c0 { +@@ -77,4 +87,13 @@ + renesas,groups = "intc_irq10"; + renesas,function = "intc"; + }; ++ ++ backlight_pins: backlight { ++ renesas,groups = "tpu0_to2_1"; ++ renesas,function = "tpu0"; ++ }; ++}; ++ ++&tpu { ++ status = "okay"; + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0170-ARM-shmobile-armadillo800eva-reference-add-SDHI-and-.patch b/patches.renesas/0170-ARM-shmobile-armadillo800eva-reference-add-SDHI-and-.patch new file mode 100644 index 00000000000000..02db0c6e976eb3 --- /dev/null +++ b/patches.renesas/0170-ARM-shmobile-armadillo800eva-reference-add-SDHI-and-.patch @@ -0,0 +1,144 @@ +From 135e205ced8487ee590852f848a25054d35b77eb Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Fri, 27 Sep 2013 10:02:57 +0200 +Subject: ARM: shmobile: armadillo800eva-reference: add SDHI and MMCIF + interfaces + +Add SDHI0 and MMCIF interfaces to armadillo800eva-reference with +regulators and pin configurations. SDHI1 is not added yet, because the +switch, that connects the interface either to an SD slot or to a WiFi +SDIO card cannot be described in DT yet. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit e99d7963e0b9469f16f434a5a68a7cba3004a2df) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + .../boot/dts/r8a7740-armadillo800eva-reference.dts | 58 ++++++++++++++++++++++ + arch/arm/boot/dts/r8a7740.dtsi | 33 ++++++++++++ + 2 files changed, 91 insertions(+) + +diff --git a/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts b/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts +index 8b2aab5c1d3c..1c56c5e56950 100644 +--- a/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts ++++ b/arch/arm/boot/dts/r8a7740-armadillo800eva-reference.dts +@@ -35,6 +35,33 @@ + regulator-boot-on; + }; + ++ vcc_sdhi0: regulator@1 { ++ compatible = "regulator-fixed"; ++ ++ regulator-name = "SDHI0 Vcc"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ ++ gpio = <&pfc 75 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ }; ++ ++ vccq_sdhi0: regulator@2 { ++ compatible = "regulator-gpio"; ++ ++ regulator-name = "SDHI0 VccQ"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ vin-supply = <&vcc_sdhi0>; ++ ++ enable-gpio = <&pfc 74 GPIO_ACTIVE_HIGH>; ++ gpios = <&pfc 17 GPIO_ACTIVE_HIGH>; ++ states = <3300000 0 ++ 1800000 1>; ++ ++ enable-active-high; ++ }; ++ + leds { + compatible = "gpio-leds"; + led1 { +@@ -92,8 +119,39 @@ + renesas,groups = "tpu0_to2_1"; + renesas,function = "tpu0"; + }; ++ ++ mmc0_pins: mmc0 { ++ renesas,groups = "mmc0_data8_1", "mmc0_ctrl_1"; ++ renesas,function = "mmc0"; ++ }; ++ ++ sdhi0_pins: sdhi0 { ++ renesas,groups = "sdhi0_data4", "sdhi0_ctrl", "sdhi0_wp"; ++ renesas,function = "sdhi0"; ++ }; + }; + + &tpu { + status = "okay"; + }; ++ ++&mmcif0 { ++ pinctrl-0 = <&mmc0_pins>; ++ pinctrl-names = "default"; ++ ++ vmmc-supply = <®_3p3v>; ++ bus-width = <8>; ++ non-removable; ++ status = "okay"; ++}; ++ ++&sdhi0 { ++ pinctrl-0 = <&sdhi0_pins>; ++ pinctrl-names = "default"; ++ ++ vmmc-supply = <&vcc_sdhi0>; ++ vqmmc-supply = <&vccq_sdhi0>; ++ bus-width = <4>; ++ cd-gpios = <&pfc 167 GPIO_ACTIVE_LOW>; ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi +index 868bdded237c..ae1e230f711d 100644 +--- a/arch/arm/boot/dts/r8a7740.dtsi ++++ b/arch/arm/boot/dts/r8a7740.dtsi +@@ -161,4 +161,37 @@ + status = "disabled"; + #pwm-cells = <3>; + }; ++ ++ mmcif0: mmcif@e6bd0000 { ++ compatible = "renesas,sh-mmcif"; ++ reg = <0xe6bd0000 0x100>; ++ interrupt-parent = <&gic>; ++ interrupts = <0 56 4 ++ 0 57 4>; ++ status = "disabled"; ++ }; ++ ++ sdhi0: sdhi@e6850000 { ++ compatible = "renesas,sdhi-r8a7740"; ++ reg = <0xe6850000 0x100>; ++ interrupt-parent = <&gic>; ++ interrupts = <0 117 4 ++ 0 118 4 ++ 0 119 4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ status = "disabled"; ++ }; ++ ++ sdhi1: sdhi@e6860000 { ++ compatible = "renesas,sdhi-r8a7740"; ++ reg = <0xe6860000 0x100>; ++ interrupt-parent = <&gic>; ++ interrupts = <0 121 4 ++ 0 122 4 ++ 0 123 4>; ++ cap-sd-highspeed; ++ cap-sdio-irq; ++ status = "disabled"; ++ }; + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0171-ARM-shmobile-r8a7791-IRQC-device-tree-node.patch b/patches.renesas/0171-ARM-shmobile-r8a7791-IRQC-device-tree-node.patch new file mode 100644 index 00000000000000..c57324ff0c7223 --- /dev/null +++ b/patches.renesas/0171-ARM-shmobile-r8a7791-IRQC-device-tree-node.patch @@ -0,0 +1,46 @@ +From 3337e482febfb626979c95246c043338a4f211b4 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 17:12:29 +0900 +Subject: ARM: shmobile: r8a7791 IRQC device tree node + +Enable a r8a7791 IRQC block by adding a device tree +node for the IRQC hardware and pins IRQ0 to IRQ9. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit d77db73e260fe4b5cca4fa1e5253c21e2d755f58) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a7791.dtsi | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi +index bbed43bd9be9..b70141758de1 100644 +--- a/arch/arm/boot/dts/r8a7791.dtsi ++++ b/arch/arm/boot/dts/r8a7791.dtsi +@@ -38,4 +38,22 @@ + <0 0xf1006000 0 0x2000>; + interrupts = <1 9 0xf04>; + }; ++ ++ irqc0: interrupt-controller@e61c0000 { ++ compatible = "renesas,irqc"; ++ #interrupt-cells = <2>; ++ interrupt-controller; ++ reg = <0 0xe61c0000 0 0x200>; ++ interrupt-parent = <&gic>; ++ interrupts = <0 0 4>, ++ <0 1 4>, ++ <0 2 4>, ++ <0 3 4>, ++ <0 12 4>, ++ <0 13 4>, ++ <0 14 4>, ++ <0 15 4>, ++ <0 16 4>, ++ <0 17 4>; ++ }; + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0172-ARM-shmobile-r8a7791-Arch-timer-device-tree-node.patch b/patches.renesas/0172-ARM-shmobile-r8a7791-Arch-timer-device-tree-node.patch new file mode 100644 index 00000000000000..663dc051743c80 --- /dev/null +++ b/patches.renesas/0172-ARM-shmobile-r8a7791-Arch-timer-device-tree-node.patch @@ -0,0 +1,40 @@ +From 42be4b70f3ece74227b4a063245bfbbf48971987 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 17:12:38 +0900 +Subject: ARM: shmobile: r8a7791 Arch timer device tree node + +Add r8a7791 arch timer device tree information. + +This needs to be used together with r8a7791 support +code that ties in the R-Car Gen2 arch timer workarounds. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 03586acf7808ed65963cd262188b059ff6951d40) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a7791.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi +index b70141758de1..a1a9e5c4813d 100644 +--- a/arch/arm/boot/dts/r8a7791.dtsi ++++ b/arch/arm/boot/dts/r8a7791.dtsi +@@ -39,6 +39,14 @@ + interrupts = <1 9 0xf04>; + }; + ++ timer { ++ compatible = "arm,armv7-timer"; ++ interrupts = <1 13 0xf08>, ++ <1 14 0xf08>, ++ <1 11 0xf08>, ++ <1 10 0xf08>; ++ }; ++ + irqc0: interrupt-controller@e61c0000 { + compatible = "renesas,irqc"; + #interrupt-cells = <2>; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0173-ARM-shmobile-r8a7791-SMP-device-tree-node.patch b/patches.renesas/0173-ARM-shmobile-r8a7791-SMP-device-tree-node.patch new file mode 100644 index 00000000000000..c297743c3fba21 --- /dev/null +++ b/patches.renesas/0173-ARM-shmobile-r8a7791-SMP-device-tree-node.patch @@ -0,0 +1,36 @@ +From c40dd09cc5d2cc49c56cebf7701967cb24c6ff04 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 17:13:07 +0900 +Subject: ARM: shmobile: r8a7791 SMP device tree node + +Add a device node for the r8a7791 secondary CPU core. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 15ab426c0f1935016ea52cfedf0d808f8c79dd1e) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a7791.dtsi | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi +index a1a9e5c4813d..fea5cfef4691 100644 +--- a/arch/arm/boot/dts/r8a7791.dtsi ++++ b/arch/arm/boot/dts/r8a7791.dtsi +@@ -25,6 +25,13 @@ + reg = <0>; + clock-frequency = <1300000000>; + }; ++ ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a15"; ++ reg = <1>; ++ clock-frequency = <1300000000>; ++ }; + }; + + gic: interrupt-controller@f1001000 { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0174-ARM-shmobile-r8a7778-add-renesas_intc_irqpin-support.patch b/patches.renesas/0174-ARM-shmobile-r8a7778-add-renesas_intc_irqpin-support.patch new file mode 100644 index 00000000000000..a9d062701844dc --- /dev/null +++ b/patches.renesas/0174-ARM-shmobile-r8a7778-add-renesas_intc_irqpin-support.patch @@ -0,0 +1,46 @@ +From dbc40f34b80cf1f766d87776b604e530218e1b78 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Wed, 2 Oct 2013 01:32:12 -0700 +Subject: ARM: shmobile: r8a7778: add renesas_intc_irqpin support on DTSI + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 87f1ba80179a75ae1e2e783b890adb39949c7c03) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a7778.dtsi | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/arch/arm/boot/dts/r8a7778.dtsi b/arch/arm/boot/dts/r8a7778.dtsi +index 3577aba82583..a6308a399e2d 100644 +--- a/arch/arm/boot/dts/r8a7778.dtsi ++++ b/arch/arm/boot/dts/r8a7778.dtsi +@@ -33,6 +33,25 @@ + <0xfe430000 0x100>; + }; + ++ /* irqpin: IRQ0 - IRQ3 */ ++ irqpin: irqpin@fe78001c { ++ compatible = "renesas,intc-irqpin"; ++ #interrupt-cells = <2>; ++ interrupt-controller; ++ status = "disabled"; /* default off */ ++ reg = <0xfe78001c 4>, ++ <0xfe780010 4>, ++ <0xfe780024 4>, ++ <0xfe780044 4>, ++ <0xfe780064 4>; ++ interrupt-parent = <&gic>; ++ interrupts = <0 27 0x4 ++ 0 28 0x4 ++ 0 29 0x4 ++ 0 30 0x4>; ++ sense-bitfield-width = <2>; ++ }; ++ + gpio0: gpio@ffc40000 { + compatible = "renesas,gpio-r8a7778", "renesas,gpio-rcar"; + reg = <0xffc40000 0x2c>; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0175-ARM-shmobile-bockw-add-SMSC-support-on-DTS.patch b/patches.renesas/0175-ARM-shmobile-bockw-add-SMSC-support-on-DTS.patch new file mode 100644 index 00000000000000..d00152e2532d8e --- /dev/null +++ b/patches.renesas/0175-ARM-shmobile-bockw-add-SMSC-support-on-DTS.patch @@ -0,0 +1,60 @@ +From 932e0976caafcac6b224f7166f061d825cb5261d Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Wed, 2 Oct 2013 01:34:07 -0700 +Subject: ARM: shmobile: bockw: add SMSC support on DTS + +This patch enables INTC IRQ and SMSC on BockW board via DT. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 1e918e00ea2aa2d23a3e0552e907c1da104cdc39) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a7778-bockw-reference.dts | 27 ++++++++++++++++++++++++++- + 1 file changed, 26 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/r8a7778-bockw-reference.dts b/arch/arm/boot/dts/r8a7778-bockw-reference.dts +index 9bb903a3230d..4425fd2e09f4 100644 +--- a/arch/arm/boot/dts/r8a7778-bockw-reference.dts ++++ b/arch/arm/boot/dts/r8a7778-bockw-reference.dts +@@ -22,11 +22,36 @@ + compatible = "renesas,bockw-reference", "renesas,r8a7778"; + + chosen { +- bootargs = "console=ttySC0,115200 ignore_loglevel rw"; ++ bootargs = "console=ttySC0,115200 ignore_loglevel root=/dev/nfs ip=dhcp rw"; + }; + + memory { + device_type = "memory"; + reg = <0x60000000 0x10000000>; + }; ++ ++ fixedregulator3v3: fixedregulator@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++ ++ lan0@18300000 { ++ compatible = "smsc,lan9220", "smsc,lan9115"; ++ reg = <0x18300000 0x1000>; ++ ++ phy-mode = "mii"; ++ interrupt-parent = <&irqpin>; ++ interrupts = <0 0>; /* IRQ0: hwirq 0 on irqpin */ ++ reg-io-width = <4>; ++ vddvario-supply = <&fixedregulator3v3>; ++ vdd33a-supply = <&fixedregulator3v3>; ++ }; ++}; ++ ++&irqpin { ++ status = "okay"; + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0176-ARM-shmobile-marzen-fixup-SMSC-IRQ-number-on-DTS.patch b/patches.renesas/0176-ARM-shmobile-marzen-fixup-SMSC-IRQ-number-on-DTS.patch new file mode 100644 index 00000000000000..47d1f384b2ab19 --- /dev/null +++ b/patches.renesas/0176-ARM-shmobile-marzen-fixup-SMSC-IRQ-number-on-DTS.patch @@ -0,0 +1,44 @@ +From a60a928bbf1f5f4d9a176ef38d9e3958312e34bf Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Wed, 2 Oct 2013 01:40:20 -0700 +Subject: ARM: shmobile: marzen: fixup SMSC IRQ number on DTS + +This patch fixup miss-setting of SMSC IRQ number. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit bffdd7d1a4249dddf1ded81e412cf3c78d139e38) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a7779-marzen-reference.dts | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/boot/dts/r8a7779-marzen-reference.dts b/arch/arm/boot/dts/r8a7779-marzen-reference.dts +index 6d5508392252..ab4110aa3c3b 100644 +--- a/arch/arm/boot/dts/r8a7779-marzen-reference.dts ++++ b/arch/arm/boot/dts/r8a7779-marzen-reference.dts +@@ -42,8 +42,8 @@ + pinctrl-names = "default"; + + phy-mode = "mii"; +- interrupt-parent = <&gic>; +- interrupts = <0 28 0x4>; ++ interrupt-parent = <&irqpin0>; ++ interrupts = <1 0>; /* IRQ1: hwirq 1 on irqpin0 */ + reg-io-width = <4>; + vddvario-supply = <&fixedregulator3v3>; + vdd33a-supply = <&fixedregulator3v3>; +@@ -63,6 +63,10 @@ + }; + }; + ++&irqpin0 { ++ status = "okay"; ++}; ++ + &pfc { + pinctrl-0 = <&scif2_pins &scif4_pins &sdhi0_pins>; + pinctrl-names = "default"; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0177-ARM-shmobile-r8a7779-add-irqpin-default-status-on-DT.patch b/patches.renesas/0177-ARM-shmobile-r8a7779-add-irqpin-default-status-on-DT.patch new file mode 100644 index 00000000000000..d1382cba563407 --- /dev/null +++ b/patches.renesas/0177-ARM-shmobile-r8a7779-add-irqpin-default-status-on-DT.patch @@ -0,0 +1,32 @@ +From a95eab5bd09f45c3b0680650b18901268ba19ddb Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Wed, 2 Oct 2013 01:39:13 -0700 +Subject: ARM: shmobile: r8a7779: add irqpin default status on DTSI + +r8a7779 INTC needs IRL pin mode settings to determine +behavior of IRQ0 - IRQ3. But it depends on platform. +This patch adds status = "disabled" on r8a7779.dtsi as default + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 84b47dfc1b1638c40257382d2216d1668cfca3d0) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a7779.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/boot/dts/r8a7779.dtsi b/arch/arm/boot/dts/r8a7779.dtsi +index 912b3a04901e..19faeac3fd2e 100644 +--- a/arch/arm/boot/dts/r8a7779.dtsi ++++ b/arch/arm/boot/dts/r8a7779.dtsi +@@ -135,6 +135,7 @@ + irqpin0: irqpin@fe780010 { + compatible = "renesas,intc-irqpin"; + #interrupt-cells = <2>; ++ status = "disabled"; + interrupt-controller; + reg = <0xfe78001c 4>, + <0xfe780010 4>, +-- +1.8.5.rc3 + diff --git a/patches.renesas/0178-ARM-shmobile-r8a73a4-add-a-DMAC-platform-device-and-.patch b/patches.renesas/0178-ARM-shmobile-r8a73a4-add-a-DMAC-platform-device-and-.patch new file mode 100644 index 00000000000000..08afc62bed7aa7 --- /dev/null +++ b/patches.renesas/0178-ARM-shmobile-r8a73a4-add-a-DMAC-platform-device-and-.patch @@ -0,0 +1,186 @@ +From a6b3fc3b40cb06d219e17674652e3822cab4f526 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Fri, 2 Aug 2013 16:50:40 +0200 +Subject: ARM: shmobile: r8a73a4: add a DMAC platform device and clock for it + +Add a DMAC platform device and clock definitions for it on r8a73a4. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 3794c1663491012b10b41699b5ee5175bd75a3f1) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/clock-r8a73a4.c | 4 +- + arch/arm/mach-shmobile/include/mach/r8a73a4.h | 9 +++ + arch/arm/mach-shmobile/setup-r8a73a4.c | 91 +++++++++++++++++++++++++++ + 3 files changed, 103 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c +index 5bd2e851e3c7..e203fc88f9e6 100644 +--- a/arch/arm/mach-shmobile/clock-r8a73a4.c ++++ b/arch/arm/mach-shmobile/clock-r8a73a4.c +@@ -504,7 +504,7 @@ static struct clk div6_clks[DIV6_NR] = { + + /* MSTP */ + enum { +- MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, ++ MSTP218, MSTP217, MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, + MSTP329, MSTP323, MSTP318, MSTP317, MSTP316, + MSTP315, MSTP314, MSTP313, MSTP312, MSTP305, MSTP300, + MSTP411, MSTP410, MSTP409, +@@ -519,6 +519,7 @@ static struct clk mstp_clks[MSTP_NR] = { + [MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 7, 0), /* SCIFB1 */ + [MSTP216] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 16, 0), /* SCIFB2 */ + [MSTP217] = SH_CLK_MSTP32(&div6_clks[DIV6_MP], SMSTPCR2, 17, 0), /* SCIFB3 */ ++ [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC */ + [MSTP300] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 0, 0), /* IIC2 */ + [MSTP305] = SH_CLK_MSTP32(&div6_clks[DIV6_MMC1],SMSTPCR3, 5, 0), /* MMCIF1 */ + [MSTP312] = SH_CLK_MSTP32(&div6_clks[DIV6_SDHI2],SMSTPCR3, 12, 0), /* SDHI2 */ +@@ -578,6 +579,7 @@ static struct clk_lookup lookups[] = { + CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]), + CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), + CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]), ++ CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), + CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), + CLKDEV_DEV_ID("e6520000.i2c", &mstp_clks[MSTP300]), + CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]), +diff --git a/arch/arm/mach-shmobile/include/mach/r8a73a4.h b/arch/arm/mach-shmobile/include/mach/r8a73a4.h +index 5214338a6a47..ce8bdd1d8a8a 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a73a4.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a73a4.h +@@ -1,6 +1,15 @@ + #ifndef __ASM_R8A73A4_H__ + #define __ASM_R8A73A4_H__ + ++/* DMA slave IDs */ ++enum { ++ SHDMA_SLAVE_INVALID, ++ SHDMA_SLAVE_MMCIF0_TX, ++ SHDMA_SLAVE_MMCIF0_RX, ++ SHDMA_SLAVE_MMCIF1_TX, ++ SHDMA_SLAVE_MMCIF1_RX, ++}; ++ + void r8a73a4_add_standard_devices(void); + void r8a73a4_add_dt_devices(void); + void r8a73a4_clock_init(void); +diff --git a/arch/arm/mach-shmobile/setup-r8a73a4.c b/arch/arm/mach-shmobile/setup-r8a73a4.c +index 53a896275cae..b0f2749071be 100644 +--- a/arch/arm/mach-shmobile/setup-r8a73a4.c ++++ b/arch/arm/mach-shmobile/setup-r8a73a4.c +@@ -22,8 +22,10 @@ + #include <linux/of_platform.h> + #include <linux/platform_data/irq-renesas-irqc.h> + #include <linux/serial_sci.h> ++#include <linux/sh_dma.h> + #include <linux/sh_timer.h> + #include <mach/common.h> ++#include <mach/dma-register.h> + #include <mach/irqs.h> + #include <mach/r8a73a4.h> + #include <asm/mach/arch.h> +@@ -199,12 +201,101 @@ void __init r8a73a4_add_dt_devices(void) + r8a7790_register_cmt(10); + } + ++/* DMA */ ++static const struct sh_dmae_slave_config dma_slaves[] = { ++ { ++ .slave_id = SHDMA_SLAVE_MMCIF0_TX, ++ .addr = 0xee200034, ++ .chcr = CHCR_TX(XMIT_SZ_32BIT), ++ .mid_rid = 0xd1, ++ }, { ++ .slave_id = SHDMA_SLAVE_MMCIF0_RX, ++ .addr = 0xee200034, ++ .chcr = CHCR_RX(XMIT_SZ_32BIT), ++ .mid_rid = 0xd2, ++ }, { ++ .slave_id = SHDMA_SLAVE_MMCIF1_TX, ++ .addr = 0xee220034, ++ .chcr = CHCR_TX(XMIT_SZ_32BIT), ++ .mid_rid = 0xe1, ++ }, { ++ .slave_id = SHDMA_SLAVE_MMCIF1_RX, ++ .addr = 0xee220034, ++ .chcr = CHCR_RX(XMIT_SZ_32BIT), ++ .mid_rid = 0xe2, ++ }, ++}; ++ ++#define DMAE_CHANNEL(a, b) \ ++ { \ ++ .offset = (a) - 0x20, \ ++ .dmars = (a) - 0x20 + 0x40, \ ++ .chclr_bit = (b), \ ++ .chclr_offset = 0x80 - 0x20, \ ++ } ++ ++static const struct sh_dmae_channel dma_channels[] = { ++ DMAE_CHANNEL(0x8000, 0), ++ DMAE_CHANNEL(0x8080, 1), ++ DMAE_CHANNEL(0x8100, 2), ++ DMAE_CHANNEL(0x8180, 3), ++ DMAE_CHANNEL(0x8200, 4), ++ DMAE_CHANNEL(0x8280, 5), ++ DMAE_CHANNEL(0x8300, 6), ++ DMAE_CHANNEL(0x8380, 7), ++ DMAE_CHANNEL(0x8400, 8), ++ DMAE_CHANNEL(0x8480, 9), ++ DMAE_CHANNEL(0x8500, 10), ++ DMAE_CHANNEL(0x8580, 11), ++ DMAE_CHANNEL(0x8600, 12), ++ DMAE_CHANNEL(0x8680, 13), ++ DMAE_CHANNEL(0x8700, 14), ++ DMAE_CHANNEL(0x8780, 15), ++ DMAE_CHANNEL(0x8800, 16), ++ DMAE_CHANNEL(0x8880, 17), ++ DMAE_CHANNEL(0x8900, 18), ++ DMAE_CHANNEL(0x8980, 19), ++}; ++ ++static const struct sh_dmae_pdata dma_pdata = { ++ .slave = dma_slaves, ++ .slave_num = ARRAY_SIZE(dma_slaves), ++ .channel = dma_channels, ++ .channel_num = ARRAY_SIZE(dma_channels), ++ .ts_low_shift = TS_LOW_SHIFT, ++ .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT, ++ .ts_high_shift = TS_HI_SHIFT, ++ .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT, ++ .ts_shift = dma_ts_shift, ++ .ts_shift_num = ARRAY_SIZE(dma_ts_shift), ++ .dmaor_init = DMAOR_DME, ++ .chclr_present = 1, ++ .chclr_bitwise = 1, ++}; ++ ++static struct resource dma_resources[] = { ++ DEFINE_RES_MEM(0xe6700020, 0x89e0), ++ DEFINE_RES_IRQ_NAMED(gic_spi(220), "error_irq"), ++ { ++ /* IRQ for channels 0-19 */ ++ .start = gic_spi(200), ++ .end = gic_spi(219), ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++#define r8a73a4_register_dmac() \ ++ platform_device_register_resndata(&platform_bus, "sh-dma-engine", 0, \ ++ dma_resources, ARRAY_SIZE(dma_resources), \ ++ &dma_pdata, sizeof(dma_pdata)) ++ + void __init r8a73a4_add_standard_devices(void) + { + r8a73a4_add_dt_devices(); + r8a73a4_register_irqc(0); + r8a73a4_register_irqc(1); + r8a73a4_register_thermal(); ++ r8a73a4_register_dmac(); + } + + void __init r8a73a4_init_early(void) +-- +1.8.5.rc3 + diff --git a/patches.renesas/0179-ARM-shmobile-r8a7778-add-HPB-DMAC-support.patch b/patches.renesas/0179-ARM-shmobile-r8a7778-add-HPB-DMAC-support.patch new file mode 100644 index 00000000000000..74ed8c46112781 --- /dev/null +++ b/patches.renesas/0179-ARM-shmobile-r8a7778-add-HPB-DMAC-support.patch @@ -0,0 +1,163 @@ +From d106902c5a4fd4bf7fb08f940938e4f5095ce54b Mon Sep 17 00:00:00 2001 +From: Max Filippov <max.filippov@cogentembedded.com> +Date: Sun, 25 Aug 2013 01:35:13 +0400 +Subject: ARM: shmobile: r8a7778: add HPB-DMAC support + +Add HPB-DMAC platform device on R8A7778 SoC along with its slave and channel +configurations (only for SDHI0 so far). + +Signed-off-by: Max Filippov <max.filippov@cogentembedded.com> +[Sergei: moved *enum* declaring HPB-DMAC slave IDs from now removed <mach/dma.h> +to <mach/r8a7778.h>, removed #include <mach/dma.h> from setup-r8a7778.c, removed +SSI-related *enum* values and SSI-related data from hpb_dmae_slaves[] and +hpb_dmae_channels[], moved the comments after the element initializers of +hpb_dmae_channels[].] +Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +(cherry picked from commit 1eb6b5a0e55bfcfb0852b7d0f9442841ff807345) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/include/mach/r8a7778.h | 8 +++ + arch/arm/mach-shmobile/setup-r8a7778.c | 85 +++++++++++++++++++++++++++ + 2 files changed, 93 insertions(+) + +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h +index fdbd37df1543..6d0abb767764 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a7778.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h +@@ -1,6 +1,7 @@ + /* + * Copyright (C) 2013 Renesas Solutions Corp. + * Copyright (C) 2013 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> ++ * Copyright (C) 2013 Cogent Embedded, Inc. + * + * 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 +@@ -21,6 +22,13 @@ + #include <linux/sh_eth.h> + #include <linux/platform_data/camera-rcar.h> + ++/* HPB-DMA slave IDs */ ++enum { ++ HPBDMA_SLAVE_DUMMY, ++ HPBDMA_SLAVE_SDHI0_TX, ++ HPBDMA_SLAVE_SDHI0_RX, ++}; ++ + extern void r8a7778_add_standard_devices(void); + extern void r8a7778_add_standard_devices_dt(void); + extern void r8a7778_add_dt_devices(void); +diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c +index bfeedd169891..460814ea3c94 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7778.c ++++ b/arch/arm/mach-shmobile/setup-r8a7778.c +@@ -24,6 +24,7 @@ + #include <linux/irqchip/arm-gic.h> + #include <linux/of.h> + #include <linux/of_platform.h> ++#include <linux/platform_data/dma-rcar-hpbdma.h> + #include <linux/platform_data/gpio-rcar.h> + #include <linux/platform_data/irq-renesas-intc-irqpin.h> + #include <linux/platform_device.h> +@@ -308,6 +309,88 @@ void __init r8a7778_add_dt_devices(void) + r8a7778_register_tmu(1); + } + ++/* HPB-DMA */ ++ ++/* Asynchronous mode register (ASYNCMDR) bits */ ++#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(2) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(2) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(1) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(1) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */ ++ ++static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = { ++ { ++ .id = HPBDMA_SLAVE_SDHI0_TX, ++ .addr = 0xffe4c000 + 0x30, ++ .dcr = HPB_DMAE_DCR_SPDS_16BIT | ++ HPB_DMAE_DCR_DMDL | ++ HPB_DMAE_DCR_DPDS_16BIT, ++ .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | ++ HPB_DMAE_ASYNCRSTR_ASRST22 | ++ HPB_DMAE_ASYNCRSTR_ASRST23, ++ .mdr = HPB_DMAE_ASYNCMDR_ASMD21_MULTI, ++ .mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK, ++ .port = 0x0D0C, ++ .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, ++ .dma_ch = 21, ++ }, { ++ .id = HPBDMA_SLAVE_SDHI0_RX, ++ .addr = 0xffe4c000 + 0x30, ++ .dcr = HPB_DMAE_DCR_SMDL | ++ HPB_DMAE_DCR_SPDS_16BIT | ++ HPB_DMAE_DCR_DPDS_16BIT, ++ .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | ++ HPB_DMAE_ASYNCRSTR_ASRST22 | ++ HPB_DMAE_ASYNCRSTR_ASRST23, ++ .mdr = HPB_DMAE_ASYNCMDR_ASMD22_MULTI, ++ .mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK, ++ .port = 0x0D0C, ++ .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, ++ .dma_ch = 22, ++ }, ++}; ++ ++static const struct hpb_dmae_channel hpb_dmae_channels[] = { ++ HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */ ++ HPB_DMAE_CHANNEL(0x7e, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */ ++}; ++ ++static struct hpb_dmae_pdata dma_platform_data __initdata = { ++ .slaves = hpb_dmae_slaves, ++ .num_slaves = ARRAY_SIZE(hpb_dmae_slaves), ++ .channels = hpb_dmae_channels, ++ .num_channels = ARRAY_SIZE(hpb_dmae_channels), ++ .ts_shift = { ++ [XMIT_SZ_8BIT] = 0, ++ [XMIT_SZ_16BIT] = 1, ++ [XMIT_SZ_32BIT] = 2, ++ }, ++ .num_hw_channels = 39, ++}; ++ ++static struct resource hpb_dmae_resources[] __initdata = { ++ /* Channel registers */ ++ DEFINE_RES_MEM(0xffc08000, 0x1000), ++ /* Common registers */ ++ DEFINE_RES_MEM(0xffc09000, 0x170), ++ /* Asynchronous reset registers */ ++ DEFINE_RES_MEM(0xffc00300, 4), ++ /* Asynchronous mode registers */ ++ DEFINE_RES_MEM(0xffc00400, 4), ++ /* IRQ for DMA channels */ ++ DEFINE_RES_NAMED(gic_iid(0x7b), 5, NULL, IORESOURCE_IRQ), ++}; ++ ++static void __init r8a7778_register_hpb_dmae(void) ++{ ++ platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1, ++ hpb_dmae_resources, ++ ARRAY_SIZE(hpb_dmae_resources), ++ &dma_platform_data, ++ sizeof(dma_platform_data)); ++} ++ + void __init r8a7778_add_standard_devices(void) + { + r8a7778_add_dt_devices(); +@@ -318,6 +401,8 @@ void __init r8a7778_add_standard_devices(void) + r8a7778_register_hspi(0); + r8a7778_register_hspi(1); + r8a7778_register_hspi(2); ++ ++ r8a7778_register_hpb_dmae(); + } + + void __init r8a7778_init_late(void) +-- +1.8.5.rc3 + diff --git a/patches.renesas/0180-ARM-shmobile-r8a7779-add-HPB-DMAC-support.patch b/patches.renesas/0180-ARM-shmobile-r8a7779-add-HPB-DMAC-support.patch new file mode 100644 index 00000000000000..1504054d94954b --- /dev/null +++ b/patches.renesas/0180-ARM-shmobile-r8a7779-add-HPB-DMAC-support.patch @@ -0,0 +1,227 @@ +From 1a5c45b4631ae8cf1b6dd78df235ae0627c0797f Mon Sep 17 00:00:00 2001 +From: Max Filippov <max.filippov@cogentembedded.com> +Date: Sun, 25 Aug 2013 21:46:23 +0400 +Subject: ARM: shmobile: r8a7779: add HPB-DMAC support + +Add HPB-DMAC platform device on R8A7779 SoC along with its slave and channel +configurations (only for SDHI0 so far). + +Signed-off-by: Max Filippov <max.filippov@cogentembedded.com> +[Sergei: moved *enum* declaring HPB-DMAC slave IDs from now removed <mach/dma.h> +to <mach/r8a7779.h>, removed #include <mach/dma.h> from setup-r8a7779.c, removed +SSI-related *enum* values and SSI-related data from hpb_dmae_slaves[] and +hpb_dmae_channels[], added ASYNCMDR.ASBTMD{20|24|43} and ASYNCMDR.ASMD{20|24|43} +fields/values, fixed comments to ASYNCMDR.ASBTMD2[123] and ASYNCMDR.ASMD2[123] +fields/values, renamed all the bit/field/value #define's to include 'HBP_DMAE_' +prefix to match the driver, moved comments after the element initializers of +hpb_dmae_channels[].] +Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +(cherry picked from commit a43e5bd76a4a3df58167d85e8020a1c9e566ad75) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/include/mach/r8a7779.h | 7 ++ + arch/arm/mach-shmobile/setup-r8a7779.c | 154 ++++++++++++++++++++++++++ + 2 files changed, 161 insertions(+) + +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h +index 11c740047e14..31e87b92a9c3 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a7779.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h +@@ -6,6 +6,13 @@ + #include <linux/sh_eth.h> + #include <linux/platform_data/camera-rcar.h> + ++/* HPB-DMA slave IDs */ ++enum { ++ HPBDMA_SLAVE_DUMMY, ++ HPBDMA_SLAVE_SDHI0_TX, ++ HPBDMA_SLAVE_SDHI0_RX, ++}; ++ + struct platform_device; + + struct r8a7779_pm_ch { +diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c +index ecd0148ee1e1..eacb2f783693 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7779.c ++++ b/arch/arm/mach-shmobile/setup-r8a7779.c +@@ -25,6 +25,7 @@ + #include <linux/irqchip.h> + #include <linux/irqchip/arm-gic.h> + #include <linux/of_platform.h> ++#include <linux/platform_data/dma-rcar-hpbdma.h> + #include <linux/platform_data/gpio-rcar.h> + #include <linux/platform_data/irq-renesas-intc-irqpin.h> + #include <linux/platform_device.h> +@@ -632,6 +633,158 @@ static struct platform_device_info *vin_info_table[] __initdata = { + &vin3_info, + }; + ++/* HPB-DMA */ ++ ++/* Asynchronous mode register bits */ ++#define HPB_DMAE_ASYNCMDR_ASMD43_MASK BIT(23) /* MMC1 */ ++#define HPB_DMAE_ASYNCMDR_ASMD43_SINGLE BIT(23) /* MMC1 */ ++#define HPB_DMAE_ASYNCMDR_ASMD43_MULTI 0 /* MMC1 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD43_MASK BIT(22) /* MMC1 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD43_BURST BIT(22) /* MMC1 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD43_NBURST 0 /* MMC1 */ ++#define HPB_DMAE_ASYNCMDR_ASMD24_MASK BIT(21) /* MMC0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD24_SINGLE BIT(21) /* MMC0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD24_MULTI 0 /* MMC0 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD24_MASK BIT(20) /* MMC0 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD24_BURST BIT(20) /* MMC0 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD24_NBURST 0 /* MMC0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD41_MASK BIT(19) /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASMD41_SINGLE BIT(19) /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASMD41_MULTI 0 /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD41_MASK BIT(18) /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD41_BURST BIT(18) /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD41_NBURST 0 /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASMD40_MASK BIT(17) /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASMD40_SINGLE BIT(17) /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASMD40_MULTI 0 /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD40_MASK BIT(16) /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD40_BURST BIT(16) /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD40_NBURST 0 /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASMD39_MASK BIT(15) /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASMD39_SINGLE BIT(15) /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASMD39_MULTI 0 /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD39_MASK BIT(14) /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD39_BURST BIT(14) /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD39_NBURST 0 /* SDHI3 */ ++#define HPB_DMAE_ASYNCMDR_ASMD27_MASK BIT(13) /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASMD27_SINGLE BIT(13) /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASMD27_MULTI 0 /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD27_MASK BIT(12) /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD27_BURST BIT(12) /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD27_NBURST 0 /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASMD26_MASK BIT(11) /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASMD26_SINGLE BIT(11) /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASMD26_MULTI 0 /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD26_MASK BIT(10) /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD26_BURST BIT(10) /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD26_NBURST 0 /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASMD25_MASK BIT(9) /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASMD25_SINGLE BIT(9) /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASMD25_MULTI 0 /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD25_MASK BIT(8) /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD25_BURST BIT(8) /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD25_NBURST 0 /* SDHI2 */ ++#define HPB_DMAE_ASYNCMDR_ASMD23_MASK BIT(7) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD23_SINGLE BIT(7) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD23_MULTI 0 /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD23_MASK BIT(6) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD23_BURST BIT(6) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD23_NBURST 0 /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD22_MASK BIT(5) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD22_SINGLE BIT(5) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD22_MULTI 0 /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD22_MASK BIT(4) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD22_BURST BIT(4) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST 0 /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD21_MASK BIT(3) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD21_SINGLE BIT(3) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD21_MULTI 0 /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD21_MASK BIT(2) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD21_BURST BIT(2) /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST 0 /* SDHI0 */ ++#define HPB_DMAE_ASYNCMDR_ASMD20_MASK BIT(1) /* SDHI1 */ ++#define HPB_DMAE_ASYNCMDR_ASMD20_SINGLE BIT(1) /* SDHI1 */ ++#define HPB_DMAE_ASYNCMDR_ASMD20_MULTI 0 /* SDHI1 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD20_MASK BIT(0) /* SDHI1 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD20_BURST BIT(0) /* SDHI1 */ ++#define HPB_DMAE_ASYNCMDR_ASBTMD20_NBURST 0 /* SDHI1 */ ++ ++static const struct hpb_dmae_slave_config hpb_dmae_slaves[] = { ++ { ++ .id = HPBDMA_SLAVE_SDHI0_TX, ++ .addr = 0xffe4c000 + 0x30, ++ .dcr = HPB_DMAE_DCR_SPDS_16BIT | ++ HPB_DMAE_DCR_DMDL | ++ HPB_DMAE_DCR_DPDS_16BIT, ++ .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | ++ HPB_DMAE_ASYNCRSTR_ASRST22 | ++ HPB_DMAE_ASYNCRSTR_ASRST23, ++ .mdr = HPB_DMAE_ASYNCMDR_ASMD21_SINGLE | ++ HPB_DMAE_ASYNCMDR_ASBTMD21_NBURST, ++ .mdm = HPB_DMAE_ASYNCMDR_ASMD21_MASK | ++ HPB_DMAE_ASYNCMDR_ASBTMD21_MASK, ++ .port = 0x0D0C, ++ .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, ++ .dma_ch = 21, ++ }, { ++ .id = HPBDMA_SLAVE_SDHI0_RX, ++ .addr = 0xffe4c000 + 0x30, ++ .dcr = HPB_DMAE_DCR_SMDL | ++ HPB_DMAE_DCR_SPDS_16BIT | ++ HPB_DMAE_DCR_DPDS_16BIT, ++ .rstr = HPB_DMAE_ASYNCRSTR_ASRST21 | ++ HPB_DMAE_ASYNCRSTR_ASRST22 | ++ HPB_DMAE_ASYNCRSTR_ASRST23, ++ .mdr = HPB_DMAE_ASYNCMDR_ASMD22_SINGLE | ++ HPB_DMAE_ASYNCMDR_ASBTMD22_NBURST, ++ .mdm = HPB_DMAE_ASYNCMDR_ASMD22_MASK | ++ HPB_DMAE_ASYNCMDR_ASBTMD22_MASK, ++ .port = 0x0D0C, ++ .flags = HPB_DMAE_SET_ASYNC_RESET | HPB_DMAE_SET_ASYNC_MODE, ++ .dma_ch = 22, ++ }, ++}; ++ ++static const struct hpb_dmae_channel hpb_dmae_channels[] = { ++ HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_TX), /* ch. 21 */ ++ HPB_DMAE_CHANNEL(0x93, HPBDMA_SLAVE_SDHI0_RX), /* ch. 22 */ ++}; ++ ++static struct hpb_dmae_pdata dma_platform_data __initdata = { ++ .slaves = hpb_dmae_slaves, ++ .num_slaves = ARRAY_SIZE(hpb_dmae_slaves), ++ .channels = hpb_dmae_channels, ++ .num_channels = ARRAY_SIZE(hpb_dmae_channels), ++ .ts_shift = { ++ [XMIT_SZ_8BIT] = 0, ++ [XMIT_SZ_16BIT] = 1, ++ [XMIT_SZ_32BIT] = 2, ++ }, ++ .num_hw_channels = 44, ++}; ++ ++static struct resource hpb_dmae_resources[] __initdata = { ++ /* Channel registers */ ++ DEFINE_RES_MEM(0xffc08000, 0x1000), ++ /* Common registers */ ++ DEFINE_RES_MEM(0xffc09000, 0x170), ++ /* Asynchronous reset registers */ ++ DEFINE_RES_MEM(0xffc00300, 4), ++ /* Asynchronous mode registers */ ++ DEFINE_RES_MEM(0xffc00400, 4), ++ /* IRQ for DMA channels */ ++ DEFINE_RES_NAMED(gic_iid(0x8e), 12, NULL, IORESOURCE_IRQ), ++}; ++ ++static void __init r8a7779_register_hpb_dmae(void) ++{ ++ platform_device_register_resndata(&platform_bus, "hpb-dma-engine", -1, ++ hpb_dmae_resources, ++ ARRAY_SIZE(hpb_dmae_resources), ++ &dma_platform_data, ++ sizeof(dma_platform_data)); ++} ++ + static struct platform_device *r8a7779_devices_dt[] __initdata = { + &scif0_device, + &scif1_device, +@@ -665,6 +818,7 @@ void __init r8a7779_add_standard_devices(void) + ARRAY_SIZE(r8a7779_devices_dt)); + platform_add_devices(r8a7779_standard_devices, + ARRAY_SIZE(r8a7779_standard_devices)); ++ r8a7779_register_hpb_dmae(); + } + + void __init r8a7779_add_ether_device(struct sh_eth_plat_data *pdata) +-- +1.8.5.rc3 + diff --git a/patches.renesas/0181-ARM-shmobile-r8a7790-add-I2C-clocks-and-aliases-for-.patch b/patches.renesas/0181-ARM-shmobile-r8a7790-add-I2C-clocks-and-aliases-for-.patch new file mode 100644 index 00000000000000..f6afa93fafcaaf --- /dev/null +++ b/patches.renesas/0181-ARM-shmobile-r8a7790-add-I2C-clocks-and-aliases-for-.patch @@ -0,0 +1,61 @@ +From 5872d1d2939eaeede8ac4889d3ebd04577811fae Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Thu, 26 Sep 2013 19:20:57 +0200 +Subject: ARM: shmobile: r8a7790: add I2C clocks and aliases for the DT mode + +This patch adds clock definitions for the 4 I2C interfaces on r8a7790 and +clock aliases, suitable for the DT mode. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 159600807c809bc3773867d3d2b7826063b20c42) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/clock-r8a7790.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c +index d99b87bc76ea..7661e898f376 100644 +--- a/arch/arm/mach-shmobile/clock-r8a7790.c ++++ b/arch/arm/mach-shmobile/clock-r8a7790.c +@@ -52,6 +52,7 @@ + #define SMSTPCR5 0xe6150144 + #define SMSTPCR7 0xe615014c + #define SMSTPCR8 0xe6150990 ++#define SMSTPCR9 0xe6150994 + + #define SDCKCR 0xE6150074 + #define SD2CKCR 0xE6150078 +@@ -181,6 +182,7 @@ static struct clk div6_clks[DIV6_NR] = { + + /* MSTP */ + enum { ++ MSTP931, MSTP930, MSTP929, MSTP928, + MSTP813, + MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720, + MSTP717, MSTP716, +@@ -192,6 +194,10 @@ enum { + }; + + static struct clk mstp_clks[MSTP_NR] = { ++ [MSTP931] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 31, 0), /* I2C0 */ ++ [MSTP930] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 30, 0), /* I2C1 */ ++ [MSTP929] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 29, 0), /* I2C2 */ ++ [MSTP928] = SH_CLK_MSTP32(&hp_clk, SMSTPCR9, 28, 0), /* I2C3 */ + [MSTP813] = SH_CLK_MSTP32(&p_clk, SMSTPCR8, 13, 0), /* Ether */ + [MSTP726] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 26, 0), /* LVDS0 */ + [MSTP725] = SH_CLK_MSTP32(&zx_clk, SMSTPCR7, 25, 0), /* LVDS1 */ +@@ -271,6 +277,10 @@ static struct clk_lookup lookups[] = { + CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]), + CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]), + CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]), ++ CLKDEV_DEV_ID("e6508000.i2c", &mstp_clks[MSTP931]), ++ CLKDEV_DEV_ID("e6518000.i2c", &mstp_clks[MSTP930]), ++ CLKDEV_DEV_ID("e6530000.i2c", &mstp_clks[MSTP929]), ++ CLKDEV_DEV_ID("e6540000.i2c", &mstp_clks[MSTP928]), + CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]), + CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), + CLKDEV_DEV_ID("ee200000.mmcif", &mstp_clks[MSTP315]), +-- +1.8.5.rc3 + diff --git a/patches.renesas/0182-ARM-shmobile-r8a73a4-add-a-clock-alias-for-the-DMAC-.patch b/patches.renesas/0182-ARM-shmobile-r8a73a4-add-a-clock-alias-for-the-DMAC-.patch new file mode 100644 index 00000000000000..0c5b72839c04c6 --- /dev/null +++ b/patches.renesas/0182-ARM-shmobile-r8a73a4-add-a-clock-alias-for-the-DMAC-.patch @@ -0,0 +1,32 @@ +From 9714680781b5745a7c768897123fe4c3411f0c30 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Thu, 26 Sep 2013 19:30:02 +0200 +Subject: ARM: shmobile: r8a73a4: add a clock alias for the DMAC in DT mode + +Devices, initialised from the Device Tree and from platform code usually +have different names. This patch adds a clock alias for DMAC on r8a73a4 +in DT mode. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 8ceea7bd9757cb90f63f16b07a6d2a022e9c45d8) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/clock-r8a73a4.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/mach-shmobile/clock-r8a73a4.c b/arch/arm/mach-shmobile/clock-r8a73a4.c +index e203fc88f9e6..571409b611d3 100644 +--- a/arch/arm/mach-shmobile/clock-r8a73a4.c ++++ b/arch/arm/mach-shmobile/clock-r8a73a4.c +@@ -580,6 +580,7 @@ static struct clk_lookup lookups[] = { + CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]), + CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP217]), + CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), ++ CLKDEV_DEV_ID("e6700020.dma-controller", &mstp_clks[MSTP218]), + CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]), + CLKDEV_DEV_ID("e6520000.i2c", &mstp_clks[MSTP300]), + CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]), +-- +1.8.5.rc3 + diff --git a/patches.renesas/0183-ARM-shmobile-Break-out-R-Car-Gen2-setup-code.patch b/patches.renesas/0183-ARM-shmobile-Break-out-R-Car-Gen2-setup-code.patch new file mode 100644 index 00000000000000..f69c1d212d3cdb --- /dev/null +++ b/patches.renesas/0183-ARM-shmobile-Break-out-R-Car-Gen2-setup-code.patch @@ -0,0 +1,311 @@ +From 83cd0db346fa37b57fdd62d338257ad42b717488 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 12 Sep 2013 09:32:49 +0900 +Subject: ARM: shmobile: Break out R-Car Gen2 setup code + +Move arch timer workaround code and boot mode pin +handling from setup-r8a7790.c to setup-rcar-gen2.c. + +With this in place the same code can be used on +other R-Car Generation 2 devices such as r8a7791. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 629cc70ddac35520688b3a8bd165435c886e78eb) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + arch/arm/mach-shmobile/board-lager.c +--- + arch/arm/mach-shmobile/Makefile | 1 + + arch/arm/mach-shmobile/board-lager-reference.c | 2 +- + arch/arm/mach-shmobile/board-lager.c | 2 +- + arch/arm/mach-shmobile/clock-r8a7790.c | 2 +- + arch/arm/mach-shmobile/include/mach/r8a7790.h | 6 +- + arch/arm/mach-shmobile/include/mach/rcar-gen2.h | 8 +++ + arch/arm/mach-shmobile/setup-r8a7790.c | 68 +----------------- + arch/arm/mach-shmobile/setup-rcar-gen2.c | 91 +++++++++++++++++++++++++ + 8 files changed, 106 insertions(+), 74 deletions(-) + create mode 100644 arch/arm/mach-shmobile/include/mach/rcar-gen2.h + create mode 100644 arch/arm/mach-shmobile/setup-rcar-gen2.c + +diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile +index f8f699212984..d1486e550eae 100644 +--- a/arch/arm/mach-shmobile/Makefile ++++ b/arch/arm/mach-shmobile/Makefile +@@ -15,6 +15,7 @@ obj-$(CONFIG_ARCH_R8A7740) += setup-r8a7740.o + obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o + obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o + obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o ++obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o setup-rcar-gen2.o + obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o + obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o + +diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c +index d39a91b3ba48..1a1a4a888632 100644 +--- a/arch/arm/mach-shmobile/board-lager-reference.c ++++ b/arch/arm/mach-shmobile/board-lager-reference.c +@@ -40,7 +40,7 @@ static const char *lager_boards_compat_dt[] __initdata = { + DT_MACHINE_START(LAGER_DT, "lager") + .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, ++ .init_time = rcar_gen2_timer_init, + .init_machine = lager_add_standard_devices, +- .init_time = r8a7790_timer_init, + .dt_compat = lager_boards_compat_dt, + MACHINE_END +diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c +index ba90fea55156..d83ed6556f7d 100644 +--- a/arch/arm/mach-shmobile/board-lager.c ++++ b/arch/arm/mach-shmobile/board-lager.c +@@ -256,7 +256,7 @@ static const char *lager_boards_compat_dt[] __initdata = { + DT_MACHINE_START(LAGER_DT, "lager") + .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, +- .init_time = r8a7790_timer_init, ++ .init_time = rcar_gen2_timer_init, + .init_machine = lager_init, + .dt_compat = lager_boards_compat_dt, + MACHINE_END +diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c +index 7661e898f376..a64f965c7da1 100644 +--- a/arch/arm/mach-shmobile/clock-r8a7790.c ++++ b/arch/arm/mach-shmobile/clock-r8a7790.c +@@ -310,7 +310,7 @@ static struct clk_lookup lookups[] = { + + void __init r8a7790_clock_init(void) + { +- u32 mode = r8a7790_read_mode_pins(); ++ u32 mode = rcar_gen2_read_mode_pins(); + int k, ret = 0; + + switch (mode & (MD(14) | MD(13))) { +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7790.h b/arch/arm/mach-shmobile/include/mach/r8a7790.h +index 79e731c83e50..5fbfa28b40b6 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a7790.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a7790.h +@@ -1,15 +1,13 @@ + #ifndef __ASM_R8A7790_H__ + #define __ASM_R8A7790_H__ + ++#include <mach/rcar-gen2.h> ++ + void r8a7790_add_standard_devices(void); + void r8a7790_add_dt_devices(void); + void r8a7790_clock_init(void); + void r8a7790_pinmux_init(void); + void r8a7790_init_early(void); +-void r8a7790_timer_init(void); + extern struct smp_operations r8a7790_smp_ops; + +-#define MD(nr) BIT(nr) +-u32 r8a7790_read_mode_pins(void); +- + #endif /* __ASM_R8A7790_H__ */ +diff --git a/arch/arm/mach-shmobile/include/mach/rcar-gen2.h b/arch/arm/mach-shmobile/include/mach/rcar-gen2.h +new file mode 100644 +index 000000000000..43f606eb2d82 +--- /dev/null ++++ b/arch/arm/mach-shmobile/include/mach/rcar-gen2.h +@@ -0,0 +1,8 @@ ++#ifndef __ASM_RCAR_GEN2_H__ ++#define __ASM_RCAR_GEN2_H__ ++ ++void rcar_gen2_timer_init(void); ++#define MD(nr) BIT(nr) ++u32 rcar_gen2_read_mode_pins(void); ++ ++#endif /* __ASM_RCAR_GEN2_H__ */ +diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c +index c7e24eff9ba2..c47bcebbcb00 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7790.c ++++ b/arch/arm/mach-shmobile/setup-r8a7790.c +@@ -18,7 +18,6 @@ + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +-#include <linux/clocksource.h> + #include <linux/irq.h> + #include <linux/kernel.h> + #include <linux/of_platform.h> +@@ -203,71 +202,6 @@ void __init r8a7790_add_standard_devices(void) + r8a7790_register_thermal(); + } + +-#define MODEMR 0xe6160060 +- +-u32 __init r8a7790_read_mode_pins(void) +-{ +- void __iomem *modemr = ioremap_nocache(MODEMR, 4); +- u32 mode; +- +- BUG_ON(!modemr); +- mode = ioread32(modemr); +- iounmap(modemr); +- +- return mode; +-} +- +-#define CNTCR 0 +-#define CNTFID0 0x20 +- +-void __init r8a7790_timer_init(void) +-{ +-#ifdef CONFIG_ARM_ARCH_TIMER +- u32 mode = r8a7790_read_mode_pins(); +- void __iomem *base; +- int extal_mhz = 0; +- u32 freq; +- +- /* At Linux boot time the r8a7790 arch timer comes up +- * with the counter disabled. Moreover, it may also report +- * a potentially incorrect fixed 13 MHz frequency. To be +- * correct these registers need to be updated to use the +- * frequency EXTAL / 2 which can be determined by the MD pins. +- */ +- +- switch (mode & (MD(14) | MD(13))) { +- case 0: +- extal_mhz = 15; +- break; +- case MD(13): +- extal_mhz = 20; +- break; +- case MD(14): +- extal_mhz = 26; +- break; +- case MD(13) | MD(14): +- extal_mhz = 30; +- break; +- } +- +- /* The arch timer frequency equals EXTAL / 2 */ +- freq = extal_mhz * (1000000 / 2); +- +- /* Remap "armgcnt address map" space */ +- base = ioremap(0xe6080000, PAGE_SIZE); +- +- /* Update registers with correct frequency */ +- iowrite32(freq, base + CNTFID0); +- asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq)); +- +- /* make sure arch timer is started by setting bit 0 of CNTCR */ +- iowrite32(1, base + CNTCR); +- iounmap(base); +-#endif /* CONFIG_ARM_ARCH_TIMER */ +- +- clocksource_of_init(); +-} +- + void __init r8a7790_init_early(void) + { + #ifndef CONFIG_ARM_ARCH_TIMER +@@ -285,7 +219,7 @@ static const char * const r8a7790_boards_compat_dt[] __initconst = { + DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)") + .smp = smp_ops(r8a7790_smp_ops), + .init_early = r8a7790_init_early, +- .init_time = r8a7790_timer_init, ++ .init_time = rcar_gen2_timer_init, + .dt_compat = r8a7790_boards_compat_dt, + MACHINE_END + #endif /* CONFIG_USE_OF */ +diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c +new file mode 100644 +index 000000000000..5734c24bf6c7 +--- /dev/null ++++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c +@@ -0,0 +1,91 @@ ++/* ++ * R-Car Generation 2 support ++ * ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * Copyright (C) 2013 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/clocksource.h> ++#include <linux/io.h> ++#include <linux/kernel.h> ++#include <mach/common.h> ++#include <mach/rcar-gen2.h> ++#include <asm/mach/arch.h> ++ ++#define MODEMR 0xe6160060 ++ ++u32 __init rcar_gen2_read_mode_pins(void) ++{ ++ void __iomem *modemr = ioremap_nocache(MODEMR, 4); ++ u32 mode; ++ ++ BUG_ON(!modemr); ++ mode = ioread32(modemr); ++ iounmap(modemr); ++ ++ return mode; ++} ++ ++#define CNTCR 0 ++#define CNTFID0 0x20 ++ ++void __init rcar_gen2_timer_init(void) ++{ ++#ifdef CONFIG_ARM_ARCH_TIMER ++ u32 mode = rcar_gen2_read_mode_pins(); ++ void __iomem *base; ++ int extal_mhz = 0; ++ u32 freq; ++ ++ /* At Linux boot time the r8a7790 arch timer comes up ++ * with the counter disabled. Moreover, it may also report ++ * a potentially incorrect fixed 13 MHz frequency. To be ++ * correct these registers need to be updated to use the ++ * frequency EXTAL / 2 which can be determined by the MD pins. ++ */ ++ ++ switch (mode & (MD(14) | MD(13))) { ++ case 0: ++ extal_mhz = 15; ++ break; ++ case MD(13): ++ extal_mhz = 20; ++ break; ++ case MD(14): ++ extal_mhz = 26; ++ break; ++ case MD(13) | MD(14): ++ extal_mhz = 30; ++ break; ++ } ++ ++ /* The arch timer frequency equals EXTAL / 2 */ ++ freq = extal_mhz * (1000000 / 2); ++ ++ /* Remap "armgcnt address map" space */ ++ base = ioremap(0xe6080000, PAGE_SIZE); ++ ++ /* Update registers with correct frequency */ ++ iowrite32(freq, base + CNTFID0); ++ asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq)); ++ ++ /* make sure arch timer is started by setting bit 0 of CNTCR */ ++ iowrite32(1, base + CNTCR); ++ iounmap(base); ++#endif /* CONFIG_ARM_ARCH_TIMER */ ++ ++ clocksource_of_init(); ++} +-- +1.8.5.rc3 + diff --git a/patches.renesas/0184-ARM-shmobile-Introduce-r8a7791_add_standard_devices.patch b/patches.renesas/0184-ARM-shmobile-Introduce-r8a7791_add_standard_devices.patch new file mode 100644 index 00000000000000..edcb34b727d011 --- /dev/null +++ b/patches.renesas/0184-ARM-shmobile-Introduce-r8a7791_add_standard_devices.patch @@ -0,0 +1,49 @@ +From 8cdbf1b126ce03c2973c4959ef1f7b4462759a3f Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 17:11:53 +0900 +Subject: ARM: shmobile: Introduce r8a7791_add_standard_devices() + +Introduce the function r8a7791_add_standard_devices() that +follows the same style as other mach-shmobile SoC code and +allows C version of board code to add on-chip devices. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 44a268e2a652eab3c21e282b6418a8c9ea279626) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/include/mach/r8a7791.h | 1 + + arch/arm/mach-shmobile/setup-r8a7791.c | 5 +++++ + 2 files changed, 6 insertions(+) + +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h +index 2e6d66131083..2a86a5394672 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a7791.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h +@@ -1,6 +1,7 @@ + #ifndef __ASM_R8A7791_H__ + #define __ASM_R8A7791_H__ + ++void r8a7791_add_standard_devices(void); + void r8a7791_add_dt_devices(void); + void r8a7791_clock_init(void); + void r8a7791_init_early(void); +diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c +index b56399d2e1de..350dfc4918e3 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7791.c ++++ b/arch/arm/mach-shmobile/setup-r8a7791.c +@@ -129,6 +129,11 @@ void __init r8a7791_add_dt_devices(void) + r8a7791_register_cmt(00); + } + ++void __init r8a7791_add_standard_devices(void) ++{ ++ r8a7791_add_dt_devices(); ++} ++ + void __init r8a7791_init_early(void) + { + #ifndef CONFIG_ARM_ARCH_TIMER +-- +1.8.5.rc3 + diff --git a/patches.renesas/0185-ARM-shmobile-r8a7791-IRQC-platform-device-support.patch b/patches.renesas/0185-ARM-shmobile-r8a7791-IRQC-platform-device-support.patch new file mode 100644 index 00000000000000..d0f3272001d85d --- /dev/null +++ b/patches.renesas/0185-ARM-shmobile-r8a7791-IRQC-platform-device-support.patch @@ -0,0 +1,73 @@ +From aed4a442a522663055f79fdfeafa43c2134de4d4 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 17:12:19 +0900 +Subject: ARM: shmobile: r8a7791 IRQC platform device support + +Add a platform device for the r8a7791 IRQC hardware +driving IRQ pins IRQ0 to IRQ9. The Linux interrupt +number is statically assigned to allow board code +written in C to make use of static interrupt numbers. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 1e4953d817712e52616d9a40460435eb8881d32d) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/setup-r8a7791.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c +index 350dfc4918e3..ba4fa3edf44f 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7791.c ++++ b/arch/arm/mach-shmobile/setup-r8a7791.c +@@ -22,6 +22,7 @@ + #include <linux/irq.h> + #include <linux/kernel.h> + #include <linux/of_platform.h> ++#include <linux/platform_data/irq-renesas-irqc.h> + #include <linux/serial_sci.h> + #include <linux/sh_timer.h> + #include <mach/common.h> +@@ -109,6 +110,31 @@ static const struct resource cmt00_resources[] __initconst = { + &cmt##idx##_platform_data, \ + sizeof(struct sh_timer_config)) + ++static struct renesas_irqc_config irqc0_data = { ++ .irq_base = irq_pin(0), /* IRQ0 -> IRQ9 */ ++}; ++ ++static struct resource irqc0_resources[] = { ++ DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */ ++ DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */ ++ DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */ ++ DEFINE_RES_IRQ(gic_spi(2)), /* IRQ2 */ ++ DEFINE_RES_IRQ(gic_spi(3)), /* IRQ3 */ ++ DEFINE_RES_IRQ(gic_spi(12)), /* IRQ4 */ ++ DEFINE_RES_IRQ(gic_spi(13)), /* IRQ5 */ ++ DEFINE_RES_IRQ(gic_spi(14)), /* IRQ6 */ ++ DEFINE_RES_IRQ(gic_spi(15)), /* IRQ7 */ ++ DEFINE_RES_IRQ(gic_spi(16)), /* IRQ8 */ ++ DEFINE_RES_IRQ(gic_spi(17)), /* IRQ9 */ ++}; ++ ++#define r8a7791_register_irqc(idx) \ ++ platform_device_register_resndata(&platform_bus, "renesas_irqc", \ ++ idx, irqc##idx##_resources, \ ++ ARRAY_SIZE(irqc##idx##_resources), \ ++ &irqc##idx##_data, \ ++ sizeof(struct renesas_irqc_config)) ++ + void __init r8a7791_add_dt_devices(void) + { + r8a7791_register_scif(SCIFA0); +@@ -132,6 +158,7 @@ void __init r8a7791_add_dt_devices(void) + void __init r8a7791_add_standard_devices(void) + { + r8a7791_add_dt_devices(); ++ r8a7791_register_irqc(0); + } + + void __init r8a7791_init_early(void) +-- +1.8.5.rc3 + diff --git a/patches.renesas/0186-ARM-shmobile-r8a7791-Arch-timer-workaround.patch b/patches.renesas/0186-ARM-shmobile-r8a7791-Arch-timer-workaround.patch new file mode 100644 index 00000000000000..f1bc1f516723e8 --- /dev/null +++ b/patches.renesas/0186-ARM-shmobile-r8a7791-Arch-timer-workaround.patch @@ -0,0 +1,52 @@ +From 6ad4fa6b33bc5133d76c939f61166d4928e752c5 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 17:12:48 +0900 +Subject: ARM: shmobile: r8a7791 Arch timer workaround + +Make use of the R-Car Gen2 arch timer workaround on r8a7791. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit ca1e6f22a0ab5ae6ec2114993a23d5814f0799c7) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/Makefile | 2 +- + arch/arm/mach-shmobile/setup-r8a7791.c | 2 ++ + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile +index d1486e550eae..623fa207520b 100644 +--- a/arch/arm/mach-shmobile/Makefile ++++ b/arch/arm/mach-shmobile/Makefile +@@ -16,7 +16,7 @@ obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o + obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o + obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o + obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o setup-rcar-gen2.o +-obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o ++obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o setup-rcar-gen2.o + obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o + + # Clock objects +diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c +index ba4fa3edf44f..cb3859b4cc95 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7791.c ++++ b/arch/arm/mach-shmobile/setup-r8a7791.c +@@ -28,6 +28,7 @@ + #include <mach/common.h> + #include <mach/irqs.h> + #include <mach/r8a7791.h> ++#include <mach/rcar-gen2.h> + #include <asm/mach/arch.h> + + #define SCIF_COMMON(scif_type, baseaddr, irq) \ +@@ -176,6 +177,7 @@ static const char *r8a7791_boards_compat_dt[] __initdata = { + + DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)") + .init_early = r8a7791_init_early, ++ .init_time = rcar_gen2_timer_init, + .dt_compat = r8a7791_boards_compat_dt, + MACHINE_END + #endif /* CONFIG_USE_OF */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0187-ARM-shmobile-Initial-r7s72100-SoC-support.patch b/patches.renesas/0187-ARM-shmobile-Initial-r7s72100-SoC-support.patch new file mode 100644 index 00000000000000..556e5d6bc8ff6e --- /dev/null +++ b/patches.renesas/0187-ARM-shmobile-Initial-r7s72100-SoC-support.patch @@ -0,0 +1,374 @@ +From 5124ae6b88ff9fe400999e1d43b9cbbd6dc85e15 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 19 Sep 2013 05:11:11 +0900 +Subject: ARM: shmobile: Initial r7s72100 SoC support + +Add initial support for the r7272100 SoC including: + - Single Cortex-A9 CPU Core + - GIC + +No static virtual mappings are used, all the components +make use of ioremap(). DT_MACHINE_START is still wrapped +in CONFIG_USE_OF to match other mach-shmobile code. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 0086df273cf8c7e270f8930cc42d7dad15060516) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r7s72100.dtsi | 36 +++++ + arch/arm/mach-shmobile/Kconfig | 6 + + arch/arm/mach-shmobile/Makefile | 2 + + arch/arm/mach-shmobile/clock-r7s72100.c | 194 +++++++++++++++++++++++++ + arch/arm/mach-shmobile/include/mach/r7s72100.h | 7 + + arch/arm/mach-shmobile/setup-r7s72100.c | 43 ++++++ + 6 files changed, 288 insertions(+) + create mode 100644 arch/arm/boot/dts/r7s72100.dtsi + create mode 100644 arch/arm/mach-shmobile/clock-r7s72100.c + create mode 100644 arch/arm/mach-shmobile/include/mach/r7s72100.h + create mode 100644 arch/arm/mach-shmobile/setup-r7s72100.c + +diff --git a/arch/arm/boot/dts/r7s72100.dtsi b/arch/arm/boot/dts/r7s72100.dtsi +new file mode 100644 +index 000000000000..46b82aa7dc4e +--- /dev/null ++++ b/arch/arm/boot/dts/r7s72100.dtsi +@@ -0,0 +1,36 @@ ++/* ++ * Device Tree Source for the r7s72100 SoC ++ * ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++/ { ++ compatible = "renesas,r7s72100"; ++ interrupt-parent = <&gic>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ reg = <0>; ++ }; ++ }; ++ ++ gic: interrupt-controller@e8201000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ #address-cells = <0>; ++ interrupt-controller; ++ reg = <0xe8201000 0x1000>, ++ <0xe8202000 0x1000>; ++ }; ++}; +diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig +index eda285794961..6e7d0a9b0be9 100644 +--- a/arch/arm/mach-shmobile/Kconfig ++++ b/arch/arm/mach-shmobile/Kconfig +@@ -113,6 +113,12 @@ config ARCH_EMEV2 + select ARM_GIC + select CPU_V7 + ++config ARCH_R7S72100 ++ bool "RZ/A1H (R7S72100)" ++ select ARM_GIC ++ select CPU_V7 ++ select SH_CLK_CPG ++ + comment "SH-Mobile Board Type" + + config MACH_APE6EVM +diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile +index 623fa207520b..af9e0ee9bea7 100644 +--- a/arch/arm/mach-shmobile/Makefile ++++ b/arch/arm/mach-shmobile/Makefile +@@ -18,6 +18,7 @@ obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o + obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o setup-rcar-gen2.o + obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o setup-rcar-gen2.o + obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o ++obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o + + # Clock objects + ifndef CONFIG_COMMON_CLK +@@ -31,6 +32,7 @@ obj-$(CONFIG_ARCH_R8A7779) += clock-r8a7779.o + obj-$(CONFIG_ARCH_R8A7790) += clock-r8a7790.o + obj-$(CONFIG_ARCH_R8A7791) += clock-r8a7791.o + obj-$(CONFIG_ARCH_EMEV2) += clock-emev2.o ++obj-$(CONFIG_ARCH_R7S72100) += clock-r7s72100.o + endif + + # SMP objects +diff --git a/arch/arm/mach-shmobile/clock-r7s72100.c b/arch/arm/mach-shmobile/clock-r7s72100.c +new file mode 100644 +index 000000000000..1e71094f809d +--- /dev/null ++++ b/arch/arm/mach-shmobile/clock-r7s72100.c +@@ -0,0 +1,194 @@ ++/* ++ * r7a72100 clock framework support ++ * ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * Copyright (C) 2012 Phil Edworthy ++ * 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. ++ */ ++#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> ++#include <mach/r7s72100.h> ++ ++/* registers */ ++#define FRQCR 0xfcfe0010 ++#define FRQCR2 0xfcfe0014 ++#define STBCR3 0xfcfe0420 ++#define STBCR4 0xfcfe0424 ++ ++#define PLL_RATE 30 ++ ++static struct clk_mapping cpg_mapping = { ++ .phys = 0xfcfe0000, ++ .len = 0x1000, ++}; ++ ++/* Fixed 32 KHz root clock for RTC */ ++static struct clk r_clk = { ++ .rate = 32768, ++}; ++ ++/* ++ * Default rate for the root input clock, reset this with clk_set_rate() ++ * from the platform code. ++ */ ++static struct clk extal_clk = { ++ .rate = 13330000, ++ .mapping = &cpg_mapping, ++}; ++ ++static unsigned long pll_recalc(struct clk *clk) ++{ ++ return clk->parent->rate * PLL_RATE; ++} ++ ++static struct sh_clk_ops pll_clk_ops = { ++ .recalc = pll_recalc, ++}; ++ ++static struct clk pll_clk = { ++ .ops = &pll_clk_ops, ++ .parent = &extal_clk, ++ .flags = CLK_ENABLE_ON_INIT, ++}; ++ ++static unsigned long bus_recalc(struct clk *clk) ++{ ++ return clk->parent->rate * 2 / 3; ++} ++ ++static struct sh_clk_ops bus_clk_ops = { ++ .recalc = bus_recalc, ++}; ++ ++static struct clk bus_clk = { ++ .ops = &bus_clk_ops, ++ .parent = &pll_clk, ++ .flags = CLK_ENABLE_ON_INIT, ++}; ++ ++static unsigned long peripheral0_recalc(struct clk *clk) ++{ ++ return clk->parent->rate / 12; ++} ++ ++static struct sh_clk_ops peripheral0_clk_ops = { ++ .recalc = peripheral0_recalc, ++}; ++ ++static struct clk peripheral0_clk = { ++ .ops = &peripheral0_clk_ops, ++ .parent = &pll_clk, ++ .flags = CLK_ENABLE_ON_INIT, ++}; ++ ++static unsigned long peripheral1_recalc(struct clk *clk) ++{ ++ return clk->parent->rate / 6; ++} ++ ++static struct sh_clk_ops peripheral1_clk_ops = { ++ .recalc = peripheral1_recalc, ++}; ++ ++static struct clk peripheral1_clk = { ++ .ops = &peripheral1_clk_ops, ++ .parent = &pll_clk, ++ .flags = CLK_ENABLE_ON_INIT, ++}; ++ ++struct clk *main_clks[] = { ++ &r_clk, ++ &extal_clk, ++ &pll_clk, ++ &bus_clk, ++ &peripheral0_clk, ++ &peripheral1_clk, ++}; ++ ++static int div2[] = { 1, 3, 0, 3 }; /* 1, 2/3, reserve, 1/3 */ ++static int multipliers[] = { 1, 2, 1, 1 }; ++ ++static struct clk_div_mult_table div4_div_mult_table = { ++ .divisors = div2, ++ .nr_divisors = ARRAY_SIZE(div2), ++ .multipliers = multipliers, ++ .nr_multipliers = ARRAY_SIZE(multipliers), ++}; ++ ++static struct clk_div4_table div4_table = { ++ .div_mult_table = &div4_div_mult_table, ++}; ++ ++enum { DIV4_I, ++ DIV4_NR }; ++ ++#define DIV4(_reg, _bit, _mask, _flags) \ ++ SH_CLK_DIV4(&pll_clk, _reg, _bit, _mask, _flags) ++ ++/* The mask field specifies the div2 entries that are valid */ ++struct clk div4_clks[DIV4_NR] = { ++ [DIV4_I] = DIV4(FRQCR, 8, 0xB, CLK_ENABLE_REG_16BIT ++ | CLK_ENABLE_ON_INIT), ++}; ++ ++enum { MSTP47, MSTP46, MSTP45, MSTP44, MSTP43, MSTP42, MSTP41, MSTP40, ++ MSTP33, MSTP_NR }; ++ ++static struct clk mstp_clks[MSTP_NR] = { ++ [MSTP47] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 7, 0), /* SCIF0 */ ++ [MSTP46] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 6, 0), /* SCIF1 */ ++ [MSTP45] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 5, 0), /* SCIF2 */ ++ [MSTP44] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 4, 0), /* SCIF3 */ ++ [MSTP43] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 3, 0), /* SCIF4 */ ++ [MSTP42] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 2, 0), /* SCIF5 */ ++ [MSTP41] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 1, 0), /* SCIF6 */ ++ [MSTP40] = SH_CLK_MSTP8(&peripheral1_clk, STBCR4, 0, 0), /* SCIF7 */ ++ [MSTP33] = SH_CLK_MSTP8(&peripheral0_clk, STBCR3, 3, 0), /* MTU2 */ ++}; ++ ++static struct clk_lookup lookups[] = { ++ /* main clocks */ ++ CLKDEV_CON_ID("rclk", &r_clk), ++ CLKDEV_CON_ID("extal", &extal_clk), ++ CLKDEV_CON_ID("pll_clk", &pll_clk), ++ CLKDEV_CON_ID("peripheral_clk", &peripheral1_clk), ++ ++ /* DIV4 clocks */ ++ CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), ++ ++ /* MSTP clocks */ ++}; ++ ++void __init r7s72100_clock_init(void) ++{ ++ int k, ret = 0; ++ ++ for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++) ++ ret = clk_register(main_clks[k]); ++ ++ clkdev_add_table(lookups, ARRAY_SIZE(lookups)); ++ ++ if (!ret) ++ ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table); ++ ++ if (!ret) ++ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR); ++ ++ if (!ret) ++ shmobile_clk_init(); ++ else ++ panic("failed to setup rza1 clocks\n"); ++} +diff --git a/arch/arm/mach-shmobile/include/mach/r7s72100.h b/arch/arm/mach-shmobile/include/mach/r7s72100.h +new file mode 100644 +index 000000000000..f78062e98bd4 +--- /dev/null ++++ b/arch/arm/mach-shmobile/include/mach/r7s72100.h +@@ -0,0 +1,7 @@ ++#ifndef __ASM_R7S72100_H__ ++#define __ASM_R7S72100_H__ ++ ++void r7s72100_clock_init(void); ++void r7s72100_init_early(void); ++ ++#endif /* __ASM_R7S72100_H__ */ +diff --git a/arch/arm/mach-shmobile/setup-r7s72100.c b/arch/arm/mach-shmobile/setup-r7s72100.c +new file mode 100644 +index 000000000000..c1aded0984a8 +--- /dev/null ++++ b/arch/arm/mach-shmobile/setup-r7s72100.c +@@ -0,0 +1,43 @@ ++/* ++ * r7s72100 processor support ++ * ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * Copyright (C) 2013 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/irq.h> ++#include <linux/kernel.h> ++#include <linux/of_platform.h> ++#include <mach/common.h> ++#include <mach/r7s72100.h> ++#include <asm/mach/arch.h> ++ ++void __init r7s72100_init_early(void) ++{ ++ shmobile_setup_delay(400, 1, 3); /* Cortex-A9 @ 400MHz */ ++} ++ ++#ifdef CONFIG_USE_OF ++static const char *r7s72100_boards_compat_dt[] __initdata = { ++ "renesas,r7s72100", ++ NULL, ++}; ++ ++DT_MACHINE_START(R7S72100_DT, "Generic R7S72100 (Flattened Device Tree)") ++ .init_early = r7s72100_init_early, ++ .dt_compat = r7s72100_boards_compat_dt, ++MACHINE_END ++#endif /* CONFIG_USE_OF */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0188-ARM-shmobile-r7s72100-SCIF-support.patch b/patches.renesas/0188-ARM-shmobile-r7s72100-SCIF-support.patch new file mode 100644 index 00000000000000..21cfdeb93cbc96 --- /dev/null +++ b/patches.renesas/0188-ARM-shmobile-r7s72100-SCIF-support.patch @@ -0,0 +1,115 @@ +From 0a838b8464f7974eb7d58bce9326255953302e45 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 19 Sep 2013 05:11:20 +0900 +Subject: ARM: shmobile: r7s72100 SCIF support + +Add SCIF serial port support to the r7s72100 SoC by +adding platform devices for SCIF0 -> SCIF7 together with +clock bindings. DT device description is excluded at +this point since such bindings are still under +development. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 77df55c66da2ad45ad18111194d192011dbeffb9) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/clock-r7s72100.c | 8 +++++ + arch/arm/mach-shmobile/include/mach/r7s72100.h | 1 + + arch/arm/mach-shmobile/setup-r7s72100.c | 45 ++++++++++++++++++++++++++ + 3 files changed, 54 insertions(+) + +diff --git a/arch/arm/mach-shmobile/clock-r7s72100.c b/arch/arm/mach-shmobile/clock-r7s72100.c +index 1e71094f809d..4aba20ca127e 100644 +--- a/arch/arm/mach-shmobile/clock-r7s72100.c ++++ b/arch/arm/mach-shmobile/clock-r7s72100.c +@@ -170,6 +170,14 @@ static struct clk_lookup lookups[] = { + CLKDEV_CON_ID("cpu_clk", &div4_clks[DIV4_I]), + + /* MSTP clocks */ ++ CLKDEV_ICK_ID("sci_fck", "sh-sci.0", &mstp_clks[MSTP47]), ++ CLKDEV_ICK_ID("sci_fck", "sh-sci.1", &mstp_clks[MSTP46]), ++ CLKDEV_ICK_ID("sci_fck", "sh-sci.2", &mstp_clks[MSTP45]), ++ CLKDEV_ICK_ID("sci_fck", "sh-sci.3", &mstp_clks[MSTP44]), ++ CLKDEV_ICK_ID("sci_fck", "sh-sci.4", &mstp_clks[MSTP43]), ++ CLKDEV_ICK_ID("sci_fck", "sh-sci.5", &mstp_clks[MSTP42]), ++ CLKDEV_ICK_ID("sci_fck", "sh-sci.6", &mstp_clks[MSTP41]), ++ CLKDEV_ICK_ID("sci_fck", "sh-sci.7", &mstp_clks[MSTP40]), + }; + + void __init r7s72100_clock_init(void) +diff --git a/arch/arm/mach-shmobile/include/mach/r7s72100.h b/arch/arm/mach-shmobile/include/mach/r7s72100.h +index f78062e98bd4..5f34b20ecd4a 100644 +--- a/arch/arm/mach-shmobile/include/mach/r7s72100.h ++++ b/arch/arm/mach-shmobile/include/mach/r7s72100.h +@@ -1,6 +1,7 @@ + #ifndef __ASM_R7S72100_H__ + #define __ASM_R7S72100_H__ + ++void r7s72100_add_dt_devices(void); + void r7s72100_clock_init(void); + void r7s72100_init_early(void); + +diff --git a/arch/arm/mach-shmobile/setup-r7s72100.c b/arch/arm/mach-shmobile/setup-r7s72100.c +index c1aded0984a8..d4eb509a1c87 100644 +--- a/arch/arm/mach-shmobile/setup-r7s72100.c ++++ b/arch/arm/mach-shmobile/setup-r7s72100.c +@@ -21,10 +21,55 @@ + #include <linux/irq.h> + #include <linux/kernel.h> + #include <linux/of_platform.h> ++#include <linux/serial_sci.h> + #include <mach/common.h> ++#include <mach/irqs.h> + #include <mach/r7s72100.h> + #include <asm/mach/arch.h> + ++#define SCIF_DATA(index, baseaddr, irq) \ ++[index] = { \ ++ .type = PORT_SCIF, \ ++ .regtype = SCIx_SH2_SCIF_FIFODATA_REGTYPE, \ ++ .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \ ++ .scbrr_algo_id = SCBRR_ALGO_2, \ ++ .scscr = SCSCR_RIE | SCSCR_TIE | SCSCR_RE | SCSCR_TE | \ ++ SCSCR_REIE, \ ++ .mapbase = baseaddr, \ ++ .irqs = { irq + 1, irq + 2, irq + 3, irq }, \ ++} ++ ++enum { SCIF0, SCIF1, SCIF2, SCIF3, SCIF4, SCIF5, SCIF6, SCIF7 }; ++ ++static const struct plat_sci_port scif[] __initconst = { ++ SCIF_DATA(SCIF0, 0xe8007000, gic_iid(221)), /* SCIF0 */ ++ SCIF_DATA(SCIF1, 0xe8007800, gic_iid(225)), /* SCIF1 */ ++ SCIF_DATA(SCIF2, 0xe8008000, gic_iid(229)), /* SCIF2 */ ++ SCIF_DATA(SCIF3, 0xe8008800, gic_iid(233)), /* SCIF3 */ ++ SCIF_DATA(SCIF4, 0xe8009000, gic_iid(237)), /* SCIF4 */ ++ SCIF_DATA(SCIF5, 0xe8009800, gic_iid(241)), /* SCIF5 */ ++ SCIF_DATA(SCIF6, 0xe800a000, gic_iid(245)), /* SCIF6 */ ++ SCIF_DATA(SCIF7, 0xe800a800, gic_iid(249)), /* SCIF7 */ ++}; ++ ++static inline void r7s72100_register_scif(int idx) ++{ ++ platform_device_register_data(&platform_bus, "sh-sci", idx, &scif[idx], ++ sizeof(struct plat_sci_port)); ++} ++ ++void __init r7s72100_add_dt_devices(void) ++{ ++ r7s72100_register_scif(SCIF0); ++ r7s72100_register_scif(SCIF1); ++ r7s72100_register_scif(SCIF2); ++ r7s72100_register_scif(SCIF3); ++ r7s72100_register_scif(SCIF4); ++ r7s72100_register_scif(SCIF5); ++ r7s72100_register_scif(SCIF6); ++ r7s72100_register_scif(SCIF7); ++} ++ + void __init r7s72100_init_early(void) + { + shmobile_setup_delay(400, 1, 3); /* Cortex-A9 @ 400MHz */ +-- +1.8.5.rc3 + diff --git a/patches.renesas/0189-ARM-shmobile-r8a7778-split-r8a7778_init_irq_extpin-f.patch b/patches.renesas/0189-ARM-shmobile-r8a7778-split-r8a7778_init_irq_extpin-f.patch new file mode 100644 index 00000000000000..e142fd9e296147 --- /dev/null +++ b/patches.renesas/0189-ARM-shmobile-r8a7778-split-r8a7778_init_irq_extpin-f.patch @@ -0,0 +1,63 @@ +From 7f2fcbb2707d620ed1cefd60d508367c003c3d9b Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Wed, 2 Oct 2013 01:31:40 -0700 +Subject: ARM: shmobile: r8a7778: split r8a7778_init_irq_extpin() for DT + +r8a7778 INTC needs IRL pin mode settings to determine +behavior of IRQ0 - IRQ3, and r8a7778_init_irq_extpin() +is controlling it via irlm parameter. +But this function registers renesas_intc_irqpin driver +if irlm was set, and this value depends on platform. +This is not good for DT. +This patch splits r8a7778_init_irq_extpin() function +into "mode settings" and "funtion register" parts. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit f564244fb14e0b8b3d8268efbac2e9506644c19f) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/include/mach/r8a7778.h | 1 + + arch/arm/mach-shmobile/setup-r8a7778.c | 6 +++++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7778.h b/arch/arm/mach-shmobile/include/mach/r8a7778.h +index 6d0abb767764..441886c9714b 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a7778.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a7778.h +@@ -38,6 +38,7 @@ extern void r8a7778_init_delay(void); + extern void r8a7778_init_irq_dt(void); + extern void r8a7778_clock_init(void); + extern void r8a7778_init_irq_extpin(int irlm); ++extern void r8a7778_init_irq_extpin_dt(int irlm); + extern void r8a7778_pinmux_init(void); + + extern int r8a7778_usb_phy_power(bool enable); +diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c +index 460814ea3c94..03fcc5974ef9 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7778.c ++++ b/arch/arm/mach-shmobile/setup-r8a7778.c +@@ -428,7 +428,7 @@ static struct resource irqpin_resources[] __initdata = { + DEFINE_RES_IRQ(gic_iid(0x3e)), /* IRQ3 */ + }; + +-void __init r8a7778_init_irq_extpin(int irlm) ++void __init r8a7778_init_irq_extpin_dt(int irlm) + { + void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE); + unsigned long tmp; +@@ -446,7 +446,11 @@ void __init r8a7778_init_irq_extpin(int irlm) + tmp |= (1 << 21); /* LVLMODE = 1 */ + iowrite32(tmp, icr0); + iounmap(icr0); ++} + ++void __init r8a7778_init_irq_extpin(int irlm) ++{ ++ r8a7778_init_irq_extpin_dt(irlm); + if (irlm) + platform_device_register_resndata( + &platform_bus, "renesas_intc_irqpin", -1, +-- +1.8.5.rc3 + diff --git a/patches.renesas/0190-ARM-shmobile-r8a7779-split-r8a7779_init_irq_extpin-f.patch b/patches.renesas/0190-ARM-shmobile-r8a7779-split-r8a7779_init_irq_extpin-f.patch new file mode 100644 index 00000000000000..7a544ef2f381cc --- /dev/null +++ b/patches.renesas/0190-ARM-shmobile-r8a7779-split-r8a7779_init_irq_extpin-f.patch @@ -0,0 +1,63 @@ +From df636971b70b5ecfbb292f6d48aed25017e81a54 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Wed, 2 Oct 2013 01:38:23 -0700 +Subject: ARM: shmobile: r8a7779: split r8a7779_init_irq_extpin() for DT + +r8a7779 INTC needs IRL pin mode settings to determine +behavior of IRQ0 - IRQ3, and r8a7779_init_irq_extpin() +is controlling it via irlm parameter. +But this function registers renesas_intc_irqpin driver +if irlm was set, and this value depends on platform. +This is not good for DT. +This patch splits r8a7779_init_irq_extpin() function +into "mode settings" and "funtion register" parts + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 90e27a05f64b8b4b6021cd996bef957656a8c8ab) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/include/mach/r8a7779.h | 1 + + arch/arm/mach-shmobile/setup-r8a7779.c | 6 +++++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7779.h b/arch/arm/mach-shmobile/include/mach/r8a7779.h +index 31e87b92a9c3..17af34ed89c8 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a7779.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a7779.h +@@ -33,6 +33,7 @@ static inline struct r8a7779_pm_ch *to_r8a7779_ch(struct generic_pm_domain *d) + + extern void r8a7779_init_delay(void); + extern void r8a7779_init_irq_extpin(int irlm); ++extern void r8a7779_init_irq_extpin_dt(int irlm); + extern void r8a7779_init_irq_dt(void); + extern void r8a7779_map_io(void); + extern void r8a7779_earlytimer_init(void); +diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c +index eacb2f783693..13049e9d691c 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7779.c ++++ b/arch/arm/mach-shmobile/setup-r8a7779.c +@@ -98,7 +98,7 @@ static struct resource irqpin0_resources[] __initdata = { + DEFINE_RES_IRQ(gic_spi(30)), /* IRQ3 */ + }; + +-void __init r8a7779_init_irq_extpin(int irlm) ++void __init r8a7779_init_irq_extpin_dt(int irlm) + { + void __iomem *icr0 = ioremap_nocache(0xfe780000, PAGE_SIZE); + u32 tmp; +@@ -116,7 +116,11 @@ void __init r8a7779_init_irq_extpin(int irlm) + tmp |= (1 << 21); /* LVLMODE = 1 */ + iowrite32(tmp, icr0); + iounmap(icr0); ++} + ++void __init r8a7779_init_irq_extpin(int irlm) ++{ ++ r8a7779_init_irq_extpin_dt(irlm); + if (irlm) + platform_device_register_resndata( + &platform_bus, "renesas_intc_irqpin", -1, +-- +1.8.5.rc3 + diff --git a/patches.renesas/0191-ARM-shmobile-r8a7791-SMP-support.patch b/patches.renesas/0191-ARM-shmobile-r8a7791-SMP-support.patch new file mode 100644 index 00000000000000..371ea950d24ba1 --- /dev/null +++ b/patches.renesas/0191-ARM-shmobile-r8a7791-SMP-support.patch @@ -0,0 +1,128 @@ +From 67254fd71e313f20bdc9024401fc64f342b8ec1a Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 17:13:16 +0900 +Subject: ARM: shmobile: r8a7791 SMP support + +Tie in the APMU SMP code on r8a7791. When used together +with the secondary CPU device node and smp_ops in the +board specific code then this will allow use of the +two Cortex-A15 cores in the r8a7791 SoC. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 2349199db55bfb99e2ebdce285a7e297ba63a7ef) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/Makefile | 1 + + arch/arm/mach-shmobile/include/mach/r8a7791.h | 1 + + arch/arm/mach-shmobile/setup-r8a7791.c | 1 + + arch/arm/mach-shmobile/smp-r8a7791.c | 62 +++++++++++++++++++++++++++ + 4 files changed, 65 insertions(+) + create mode 100644 arch/arm/mach-shmobile/smp-r8a7791.c + +diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile +index af9e0ee9bea7..663f8941153a 100644 +--- a/arch/arm/mach-shmobile/Makefile ++++ b/arch/arm/mach-shmobile/Makefile +@@ -40,6 +40,7 @@ smp-y := platsmp.o headsmp.o + smp-$(CONFIG_ARCH_SH73A0) += smp-sh73a0.o headsmp-scu.o platsmp-scu.o + smp-$(CONFIG_ARCH_R8A7779) += smp-r8a7779.o headsmp-scu.o platsmp-scu.o + smp-$(CONFIG_ARCH_R8A7790) += smp-r8a7790.o platsmp-apmu.o ++smp-$(CONFIG_ARCH_R8A7791) += smp-r8a7791.o platsmp-apmu.o + smp-$(CONFIG_ARCH_EMEV2) += smp-emev2.o headsmp-scu.o platsmp-scu.o + + # IRQ objects +diff --git a/arch/arm/mach-shmobile/include/mach/r8a7791.h b/arch/arm/mach-shmobile/include/mach/r8a7791.h +index 2a86a5394672..051ead3c286e 100644 +--- a/arch/arm/mach-shmobile/include/mach/r8a7791.h ++++ b/arch/arm/mach-shmobile/include/mach/r8a7791.h +@@ -5,5 +5,6 @@ void r8a7791_add_standard_devices(void); + void r8a7791_add_dt_devices(void); + void r8a7791_clock_init(void); + void r8a7791_init_early(void); ++extern struct smp_operations r8a7791_smp_ops; + + #endif /* __ASM_R8A7791_H__ */ +diff --git a/arch/arm/mach-shmobile/setup-r8a7791.c b/arch/arm/mach-shmobile/setup-r8a7791.c +index cb3859b4cc95..d9393d61ee27 100644 +--- a/arch/arm/mach-shmobile/setup-r8a7791.c ++++ b/arch/arm/mach-shmobile/setup-r8a7791.c +@@ -176,6 +176,7 @@ static const char *r8a7791_boards_compat_dt[] __initdata = { + }; + + DT_MACHINE_START(R8A7791_DT, "Generic R8A7791 (Flattened Device Tree)") ++ .smp = smp_ops(r8a7791_smp_ops), + .init_early = r8a7791_init_early, + .init_time = rcar_gen2_timer_init, + .dt_compat = r8a7791_boards_compat_dt, +diff --git a/arch/arm/mach-shmobile/smp-r8a7791.c b/arch/arm/mach-shmobile/smp-r8a7791.c +new file mode 100644 +index 000000000000..2df5bd190fe4 +--- /dev/null ++++ b/arch/arm/mach-shmobile/smp-r8a7791.c +@@ -0,0 +1,62 @@ ++/* ++ * SMP support for r8a7791 ++ * ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * Copyright (C) 2013 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. ++ */ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/smp.h> ++#include <linux/io.h> ++#include <asm/smp_plat.h> ++#include <mach/common.h> ++#include <mach/r8a7791.h> ++ ++#define RST 0xe6160000 ++#define CA15BAR 0x0020 ++#define CA15RESCNT 0x0040 ++#define RAM 0xe6300000 ++ ++static void __init r8a7791_smp_prepare_cpus(unsigned int max_cpus) ++{ ++ void __iomem *p; ++ u32 bar; ++ ++ /* let APMU code install data related to shmobile_boot_vector */ ++ shmobile_smp_apmu_prepare_cpus(max_cpus); ++ ++ /* RAM for jump stub, because BAR requires 256KB aligned address */ ++ p = ioremap_nocache(RAM, shmobile_boot_size); ++ memcpy_toio(p, shmobile_boot_vector, shmobile_boot_size); ++ iounmap(p); ++ ++ /* setup reset vectors */ ++ p = ioremap_nocache(RST, 0x63); ++ bar = (RAM >> 8) & 0xfffffc00; ++ writel_relaxed(bar, p + CA15BAR); ++ writel_relaxed(bar | 0x10, p + CA15BAR); ++ ++ /* enable clocks to all CPUs */ ++ writel_relaxed((readl_relaxed(p + CA15RESCNT) & ~0x0f) | 0xa5a50000, ++ p + CA15RESCNT); ++ iounmap(p); ++} ++ ++struct smp_operations r8a7791_smp_ops __initdata = { ++ .smp_prepare_cpus = r8a7791_smp_prepare_cpus, ++ .smp_boot_secondary = shmobile_smp_apmu_boot_secondary, ++#ifdef CONFIG_HOTPLUG_CPU ++ .cpu_disable = shmobile_smp_cpu_disable, ++ .cpu_die = shmobile_smp_apmu_cpu_die, ++ .cpu_kill = shmobile_smp_apmu_cpu_kill, ++#endif ++}; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0192-ARM-shmobile-ape6evm-add-DMA-support-to-MMCIF.patch b/patches.renesas/0192-ARM-shmobile-ape6evm-add-DMA-support-to-MMCIF.patch new file mode 100644 index 00000000000000..d403e7743eca65 --- /dev/null +++ b/patches.renesas/0192-ARM-shmobile-ape6evm-add-DMA-support-to-MMCIF.patch @@ -0,0 +1,31 @@ +From e5642c367c59cc9f21cf24894b33097d1027447c Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Mon, 22 Jul 2013 15:16:16 +0200 +Subject: ARM: shmobile: ape6evm: add DMA support to MMCIF + +Add DMA support for MMCIF on APE6EVM, using the shdma dmaengine driver. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 7a2a7a371145e83ad60482313e8cd7501994df3a) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-ape6evm.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/mach-shmobile/board-ape6evm.c b/arch/arm/mach-shmobile/board-ape6evm.c +index 3016f2f8e006..0fa068e30a30 100644 +--- a/arch/arm/mach-shmobile/board-ape6evm.c ++++ b/arch/arm/mach-shmobile/board-ape6evm.c +@@ -162,6 +162,8 @@ static struct regulator_consumer_supply vcc_sdhi1_consumers[] = + /* MMCIF */ + static const struct sh_mmcif_plat_data mmcif0_pdata __initconst = { + .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE, ++ .slave_id_tx = SHDMA_SLAVE_MMCIF0_TX, ++ .slave_id_rx = SHDMA_SLAVE_MMCIF0_RX, + .ccs_unsupported = true, + }; + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0193-ARM-shmobile-bockw-enable-DMA-for-SDHI0.patch b/patches.renesas/0193-ARM-shmobile-bockw-enable-DMA-for-SDHI0.patch new file mode 100644 index 00000000000000..25c93421d3968b --- /dev/null +++ b/patches.renesas/0193-ARM-shmobile-bockw-enable-DMA-for-SDHI0.patch @@ -0,0 +1,35 @@ +From efb0eb452a645a1fb6b70415aad111aa9048445d Mon Sep 17 00:00:00 2001 +From: Max Filippov <max.filippov@cogentembedded.com> +Date: Sun, 25 Aug 2013 01:36:38 +0400 +Subject: ARM: shmobile: bockw: enable DMA for SDHI0 + +Pass HPB-DMA slave IDs in the SDHI0 platform data to enable DMA in the SDHI +driver. + +Signed-off-by: Max Filippov <max.filippov@cogentembedded.com> +[Sergei: removed #include <mach/dma.h>] +Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +(cherry picked from commit 5d6aa3435275a5308684f90c17424b055ef7f572) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-bockw.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c +index 0559f217a5fd..38611526fe9a 100644 +--- a/arch/arm/mach-shmobile/board-bockw.c ++++ b/arch/arm/mach-shmobile/board-bockw.c +@@ -196,6 +196,8 @@ static struct rcar_phy_platform_data usb_phy_platform_data __initdata = + + /* SDHI */ + static struct sh_mobile_sdhi_info sdhi0_info __initdata = { ++ .dma_slave_tx = HPBDMA_SLAVE_SDHI0_TX, ++ .dma_slave_rx = HPBDMA_SLAVE_SDHI0_RX, + .tmio_caps = MMC_CAP_SD_HIGHSPEED, + .tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34, + .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT, +-- +1.8.5.rc3 + diff --git a/patches.renesas/0194-ARM-shmobile-marzen-enable-DMA-for-SDHI0.patch b/patches.renesas/0194-ARM-shmobile-marzen-enable-DMA-for-SDHI0.patch new file mode 100644 index 00000000000000..ae04265f1dc042 --- /dev/null +++ b/patches.renesas/0194-ARM-shmobile-marzen-enable-DMA-for-SDHI0.patch @@ -0,0 +1,35 @@ +From 8a81ae10b5fe5c72154ad4de6df77bc214ff8b23 Mon Sep 17 00:00:00 2001 +From: Max Filippov <max.filippov@cogentembedded.com> +Date: Sun, 25 Aug 2013 21:47:26 +0400 +Subject: ARM: shmobile: marzen: enable DMA for SDHI0 + +Pass HPB-DMA slave IDs in the SDHI0 platform data to enable DMA in the SDHI +driver. + +Signed-off-by: Max Filippov <max.filippov@cogentembedded.com> +[Sergei: removed #include <mach/dma.h>] +Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +(cherry picked from commit e6a8b11b82fdeaa78dad52552f945b772ee1a5c9) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-marzen.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c +index 434b213cc738..da1352f5f71b 100644 +--- a/arch/arm/mach-shmobile/board-marzen.c ++++ b/arch/arm/mach-shmobile/board-marzen.c +@@ -125,6 +125,8 @@ static struct resource sdhi0_resources[] = { + }; + + static struct sh_mobile_sdhi_info sdhi0_platform_data = { ++ .dma_slave_tx = HPBDMA_SLAVE_SDHI0_TX, ++ .dma_slave_rx = HPBDMA_SLAVE_SDHI0_RX, + .tmio_flags = TMIO_MMC_WRPROTECT_DISABLE | TMIO_MMC_HAS_IDLE_WAIT, + .tmio_caps = MMC_CAP_SD_HIGHSPEED, + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0195-ARM-shmobile-Genmai-support.patch b/patches.renesas/0195-ARM-shmobile-Genmai-support.patch new file mode 100644 index 00000000000000..f2a01996969974 --- /dev/null +++ b/patches.renesas/0195-ARM-shmobile-Genmai-support.patch @@ -0,0 +1,164 @@ +From 8e7db3193804025bb826ca6a8bef0148e3582101 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Thu, 19 Sep 2013 05:11:29 +0900 +Subject: ARM: shmobile: Genmai support + +Genmai base board support making use of 128 MiB of memory, +the r7s7211 SoC with the SCIF2 serial port and CA9 core. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit a4ed412ed5934127ba88ba007b9a00617ae47f75) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/r7s72100-genmai.dts | 31 +++++++++++++++++++++++++ + arch/arm/mach-shmobile/Kconfig | 5 ++++ + arch/arm/mach-shmobile/Makefile | 1 + + arch/arm/mach-shmobile/Makefile.boot | 1 + + arch/arm/mach-shmobile/board-genmai.c | 43 +++++++++++++++++++++++++++++++++++ + 6 files changed, 82 insertions(+) + create mode 100644 arch/arm/boot/dts/r7s72100-genmai.dts + create mode 100644 arch/arm/mach-shmobile/board-genmai.c + +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 037cf904677b..61f8b5143eee 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -161,6 +161,7 @@ dtb-$(CONFIG_ARCH_U8500) += snowball.dtb \ + ccu9540.dtb + dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \ + emev2-kzm9d-reference.dtb \ ++ r7s72100-genmai.dtb \ + r8a7740-armadillo800eva.dtb \ + r8a7778-bockw.dtb \ + r8a7778-bockw-reference.dtb \ +diff --git a/arch/arm/boot/dts/r7s72100-genmai.dts b/arch/arm/boot/dts/r7s72100-genmai.dts +new file mode 100644 +index 000000000000..1fb20f2333cc +--- /dev/null ++++ b/arch/arm/boot/dts/r7s72100-genmai.dts +@@ -0,0 +1,31 @@ ++/* ++ * Device Tree Source for the Genmai board ++ * ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * ++ * This file is licensed under the terms of the GNU General Public License ++ * version 2. This program is licensed "as is" without any warranty of any ++ * kind, whether express or implied. ++ */ ++ ++/dts-v1/; ++/include/ "r7s72100.dtsi" ++ ++/ { ++ model = "Genmai"; ++ compatible = "renesas,genmai", "renesas,r7s72100"; ++ ++ chosen { ++ bootargs = "console=ttySC2,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp"; ++ }; ++ ++ memory { ++ device_type = "memory"; ++ reg = <0x08000000 0x08000000>; ++ }; ++ ++ lbsc { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ }; ++}; +diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig +index 6e7d0a9b0be9..6a684ff62124 100644 +--- a/arch/arm/mach-shmobile/Kconfig ++++ b/arch/arm/mach-shmobile/Kconfig +@@ -191,6 +191,11 @@ config MACH_BOCKW_REFERENCE + + This is intended to aid developers + ++config MACH_GENMAI ++ bool "Genmai board" ++ depends on ARCH_R7S72100 ++ select USE_OF ++ + config MACH_MARZEN + bool "MARZEN board" + depends on ARCH_R8A7779 +diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile +index 663f8941153a..b3840ba1a445 100644 +--- a/arch/arm/mach-shmobile/Makefile ++++ b/arch/arm/mach-shmobile/Makefile +@@ -60,6 +60,7 @@ obj-$(CONFIG_MACH_APE6EVM_REFERENCE) += board-ape6evm-reference.o + obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o + obj-$(CONFIG_MACH_BOCKW) += board-bockw.o + obj-$(CONFIG_MACH_BOCKW_REFERENCE) += board-bockw-reference.o ++obj-$(CONFIG_MACH_GENMAI) += board-genmai.o + obj-$(CONFIG_MACH_MARZEN) += board-marzen.o + obj-$(CONFIG_MACH_MARZEN_REFERENCE) += board-marzen-reference.o + obj-$(CONFIG_MACH_LAGER) += board-lager.o +diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot +index 60e29e6c1126..c690b500eb61 100644 +--- a/arch/arm/mach-shmobile/Makefile.boot ++++ b/arch/arm/mach-shmobile/Makefile.boot +@@ -6,6 +6,7 @@ loadaddr-$(CONFIG_MACH_ARMADILLO800EVA) += 0x40008000 + loadaddr-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += 0x40008000 + loadaddr-$(CONFIG_MACH_BOCKW) += 0x60008000 + loadaddr-$(CONFIG_MACH_BOCKW_REFERENCE) += 0x60008000 ++loadaddr-$(CONFIG_MACH_GENMAI) += 0x8008000 + loadaddr-$(CONFIG_MACH_KOELSCH) += 0x40008000 + loadaddr-$(CONFIG_MACH_KZM9D) += 0x40008000 + loadaddr-$(CONFIG_MACH_KZM9D_REFERENCE) += 0x40008000 +diff --git a/arch/arm/mach-shmobile/board-genmai.c b/arch/arm/mach-shmobile/board-genmai.c +new file mode 100644 +index 000000000000..3e92e3c62d4c +--- /dev/null ++++ b/arch/arm/mach-shmobile/board-genmai.c +@@ -0,0 +1,43 @@ ++/* ++ * Genmai board support ++ * ++ * Copyright (C) 2013 Renesas Solutions Corp. ++ * Copyright (C) 2013 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/platform_device.h> ++#include <mach/common.h> ++#include <mach/r7s72100.h> ++#include <asm/mach-types.h> ++#include <asm/mach/arch.h> ++ ++static void __init genmai_add_standard_devices(void) ++{ ++ r7s72100_clock_init(); ++ r7s72100_add_dt_devices(); ++} ++ ++static const char * const genmai_boards_compat_dt[] __initconst = { ++ "renesas,genmai", ++ NULL, ++}; ++ ++DT_MACHINE_START(GENMAI_DT, "genmai") ++ .init_early = r7s72100_init_early, ++ .init_machine = genmai_add_standard_devices, ++ .dt_compat = genmai_boards_compat_dt, ++MACHINE_END +-- +1.8.5.rc3 + diff --git a/patches.renesas/0196-ARM-shmobile-Use-r8a7791_add_standard_devices-on-Koe.patch b/patches.renesas/0196-ARM-shmobile-Use-r8a7791_add_standard_devices-on-Koe.patch new file mode 100644 index 00000000000000..737dc2321aca10 --- /dev/null +++ b/patches.renesas/0196-ARM-shmobile-Use-r8a7791_add_standard_devices-on-Koe.patch @@ -0,0 +1,32 @@ +From 930238b37b165e0edad16d6c486dfd7642778f27 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 17:12:02 +0900 +Subject: ARM: shmobile: Use r8a7791_add_standard_devices() on Koelsch + +Use r8a7791_add_standard_devices() on Koelsch to let +the C version of the board code add on-chip devices. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 0749bead08db4e01588437a05a126bf4774dae23) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-koelsch.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/mach-shmobile/board-koelsch.c b/arch/arm/mach-shmobile/board-koelsch.c +index cc2d5e82b59a..278f12e88398 100644 +--- a/arch/arm/mach-shmobile/board-koelsch.c ++++ b/arch/arm/mach-shmobile/board-koelsch.c +@@ -29,7 +29,7 @@ + static void __init koelsch_add_standard_devices(void) + { + r8a7791_clock_init(); +- r8a7791_add_dt_devices(); ++ r8a7791_add_standard_devices(); + } + + static const char * const koelsch_boards_compat_dt[] __initconst = { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0197-ARM-shmobile-Use-arch-timer-on-Koelsch.patch b/patches.renesas/0197-ARM-shmobile-Use-arch-timer-on-Koelsch.patch new file mode 100644 index 00000000000000..afb1c5a3a1d6c1 --- /dev/null +++ b/patches.renesas/0197-ARM-shmobile-Use-arch-timer-on-Koelsch.patch @@ -0,0 +1,37 @@ +From c683efffcfcb4d8e1121c2ce75272f31b6d809fa Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 17:12:57 +0900 +Subject: ARM: shmobile: Use arch timer on Koelsch + +Make use of the R-Car Gen2 arch timer workaround on Koelsch. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit f9c9eb7e768d049d2ae360be9e09f6a0be03e317) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-koelsch.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/mach-shmobile/board-koelsch.c b/arch/arm/mach-shmobile/board-koelsch.c +index 278f12e88398..ea5846e2e88c 100644 +--- a/arch/arm/mach-shmobile/board-koelsch.c ++++ b/arch/arm/mach-shmobile/board-koelsch.c +@@ -23,6 +23,7 @@ + #include <linux/platform_device.h> + #include <mach/common.h> + #include <mach/r8a7791.h> ++#include <mach/rcar-gen2.h> + #include <asm/mach-types.h> + #include <asm/mach/arch.h> + +@@ -40,5 +41,6 @@ static const char * const koelsch_boards_compat_dt[] __initconst = { + DT_MACHINE_START(KOELSCH_DT, "koelsch") + .init_early = r8a7791_init_early, + .init_machine = koelsch_add_standard_devices, ++ .init_time = rcar_gen2_timer_init, + .dt_compat = koelsch_boards_compat_dt, + MACHINE_END +-- +1.8.5.rc3 + diff --git a/patches.renesas/0198-ARM-shmobile-Sync-KZM9D-DTS-with-KZM9D-reference-DTS.patch b/patches.renesas/0198-ARM-shmobile-Sync-KZM9D-DTS-with-KZM9D-reference-DTS.patch new file mode 100644 index 00000000000000..703fa9c41b6968 --- /dev/null +++ b/patches.renesas/0198-ARM-shmobile-Sync-KZM9D-DTS-with-KZM9D-reference-DTS.patch @@ -0,0 +1,72 @@ +From 415ca5c0eec06f8195836f73b4b55eb8b8b41bd6 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 19:33:05 +0900 +Subject: ARM: shmobile: Sync KZM9D DTS with KZM9D reference DTS + +Copy the device nodes from KZM9D reference into the KZM9D +device tree file. This will allow us to use a single DTS +file regarless of kernel configuration. In case of legacy +C board code the device nodes may or may not be used, but +in the multiplatform case all the DT device nodes are used. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 9e8b48b61aeb2eb9a02e81021bfb8d89ea4645a4) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/emev2-kzm9d.dts | 33 ++++++++++++++++++++++++++++++++- + 1 file changed, 32 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/emev2-kzm9d.dts b/arch/arm/boot/dts/emev2-kzm9d.dts +index f92e812fdd9f..861aa7d6fc7d 100644 +--- a/arch/arm/boot/dts/emev2-kzm9d.dts ++++ b/arch/arm/boot/dts/emev2-kzm9d.dts +@@ -1,7 +1,7 @@ + /* + * Device Tree Source for the KZM9D board + * +- * Copyright (C) 2012 Renesas Solutions Corp. ++ * Copyright (C) 2013 Renesas Solutions Corp. + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any +@@ -23,4 +23,35 @@ + chosen { + bootargs = "console=ttyS1,115200n81 ignore_loglevel root=/dev/nfs ip=dhcp"; + }; ++ ++ reg_1p8v: regulator@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-1.8V"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ reg_3p3v: regulator@1 { ++ compatible = "regulator-fixed"; ++ regulator-name = "fixed-3.3V"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ regulator-boot-on; ++ }; ++ ++ lan9220@20000000 { ++ compatible = "smsc,lan9220", "smsc,lan9115"; ++ reg = <0x20000000 0x10000>; ++ phy-mode = "mii"; ++ interrupt-parent = <&gpio0>; ++ interrupts = <1 1>; /* active high */ ++ reg-io-width = <4>; ++ smsc,irq-active-high; ++ smsc,irq-push-pull; ++ vddvario-supply = <®_1p8v>; ++ vdd33a-supply = <®_3p3v>; ++ }; + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0199-ARM-shmobile-Use-KZM9D-without-reference-for-multipl.patch b/patches.renesas/0199-ARM-shmobile-Use-KZM9D-without-reference-for-multipl.patch new file mode 100644 index 00000000000000..cab5ec01683e78 --- /dev/null +++ b/patches.renesas/0199-ARM-shmobile-Use-KZM9D-without-reference-for-multipl.patch @@ -0,0 +1,67 @@ +From 2bb71b0d7e9a7b809391a785318bbc1f6c6b5ab7 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 19:33:15 +0900 +Subject: ARM: shmobile: Use KZM9D without reference for multiplatform + +Change the multiplatform kconfig bits for KZM9D from +CONFIG_MACH_KZM9D_REFERENCE into CONFIG_MACH_KZM9D +to match the non-multiplatform case. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 3ae970a688f8f8a74d1b489b8646733a830c904b) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/Kconfig | 10 ++-------- + arch/arm/mach-shmobile/Makefile | 4 ++++ + 2 files changed, 6 insertions(+), 8 deletions(-) + +diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig +index 6a684ff62124..c9c4f15483bd 100644 +--- a/arch/arm/mach-shmobile/Kconfig ++++ b/arch/arm/mach-shmobile/Kconfig +@@ -22,16 +22,10 @@ config ARCH_EMEV2 + + comment "SH-Mobile Board Type" + +-config MACH_KZM9D_REFERENCE +- bool "KZM9D board - Reference Device Tree Implementation" ++config MACH_KZM9D ++ bool "KZM9D board" + depends on ARCH_EMEV2 + select REGULATOR_FIXED_VOLTAGE if REGULATOR +- ---help--- +- Use reference implementation of KZM9D board support +- which makes a greater use of device tree at the expense +- of not supporting a number of devices. +- +- This is intended to aid developers + + comment "SH-Mobile System Configuration" + endif +diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile +index b3840ba1a445..b11466d4d944 100644 +--- a/arch/arm/mach-shmobile/Makefile ++++ b/arch/arm/mach-shmobile/Makefile +@@ -55,6 +55,9 @@ obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o pm-rmobile.o + obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o + + # Board objects ++ifdef CONFIG_ARCH_SHMOBILE_MULTI ++obj-$(CONFIG_MACH_KZM9D) += board-kzm9d-reference.o ++else + obj-$(CONFIG_MACH_APE6EVM) += board-ape6evm.o + obj-$(CONFIG_MACH_APE6EVM_REFERENCE) += board-ape6evm-reference.o + obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o +@@ -72,6 +75,7 @@ obj-$(CONFIG_MACH_KZM9D) += board-kzm9d.o + obj-$(CONFIG_MACH_KZM9D_REFERENCE) += board-kzm9d-reference.o + obj-$(CONFIG_MACH_KZM9G) += board-kzm9g.o + obj-$(CONFIG_MACH_KZM9G_REFERENCE) += board-kzm9g-reference.o ++endif + + # Framework support + obj-$(CONFIG_SMP) += $(smp-y) +-- +1.8.5.rc3 + diff --git a/patches.renesas/0200-ARM-shmobile-Remove-non-multiplatform-KZM9D-referenc.patch b/patches.renesas/0200-ARM-shmobile-Remove-non-multiplatform-KZM9D-referenc.patch new file mode 100644 index 00000000000000..7c5c286fcdb954 --- /dev/null +++ b/patches.renesas/0200-ARM-shmobile-Remove-non-multiplatform-KZM9D-referenc.patch @@ -0,0 +1,77 @@ +From a7b778e8aa30019c730262bbd25049eab93f6f64 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 19:33:24 +0900 +Subject: ARM: shmobile: Remove non-multiplatform KZM9D reference support + +Now when CCF is supported remove the legacy KZM9D reference +Kconfig bits CONFIG_MACH_KZM9D_REFERENCE for the non-multiplatform +case. + +Starting from this commit KZM9D board support is always enabled +via CONFIG_MACH_KZM9D, and CONFIG_ARCH_MULTIPLATFORM is used +to select between board-kzm9d.c and board-kzm9d-reference.c + +The file board-kzm9d-reference.c can no longer be used together +with the legacy sh-clk clock framework, instead CCF is used. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit df8ee58d73ae8590bc4c9ddbe19211e4485f9d17) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/Kconfig | 12 ------------ + arch/arm/mach-shmobile/Makefile | 1 - + arch/arm/mach-shmobile/Makefile.boot | 1 - + 3 files changed, 14 deletions(-) + +diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig +index c9c4f15483bd..a4a4b75109b2 100644 +--- a/arch/arm/mach-shmobile/Kconfig ++++ b/arch/arm/mach-shmobile/Kconfig +@@ -237,18 +237,6 @@ config MACH_KZM9D + select REGULATOR_FIXED_VOLTAGE if REGULATOR + select USE_OF + +-config MACH_KZM9D_REFERENCE +- bool "KZM9D board - Reference Device Tree Implementation" +- depends on ARCH_EMEV2 +- select REGULATOR_FIXED_VOLTAGE if REGULATOR +- select USE_OF +- ---help--- +- Use reference implementation of KZM9D board support +- which makes a greater use of device tree at the expense +- of not supporting a number of devices. +- +- This is intended to aid developers +- + config MACH_KZM9G + bool "KZM-A9-GT board" + depends on ARCH_SH73A0 +diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile +index b11466d4d944..51db2bcafabf 100644 +--- a/arch/arm/mach-shmobile/Makefile ++++ b/arch/arm/mach-shmobile/Makefile +@@ -72,7 +72,6 @@ obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o + obj-$(CONFIG_MACH_ARMADILLO800EVA_REFERENCE) += board-armadillo800eva-reference.o + obj-$(CONFIG_MACH_KOELSCH) += board-koelsch.o + obj-$(CONFIG_MACH_KZM9D) += board-kzm9d.o +-obj-$(CONFIG_MACH_KZM9D_REFERENCE) += board-kzm9d-reference.o + obj-$(CONFIG_MACH_KZM9G) += board-kzm9g.o + obj-$(CONFIG_MACH_KZM9G_REFERENCE) += board-kzm9g-reference.o + endif +diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot +index c690b500eb61..391d72a5536c 100644 +--- a/arch/arm/mach-shmobile/Makefile.boot ++++ b/arch/arm/mach-shmobile/Makefile.boot +@@ -9,7 +9,6 @@ loadaddr-$(CONFIG_MACH_BOCKW_REFERENCE) += 0x60008000 + loadaddr-$(CONFIG_MACH_GENMAI) += 0x8008000 + loadaddr-$(CONFIG_MACH_KOELSCH) += 0x40008000 + loadaddr-$(CONFIG_MACH_KZM9D) += 0x40008000 +-loadaddr-$(CONFIG_MACH_KZM9D_REFERENCE) += 0x40008000 + loadaddr-$(CONFIG_MACH_KZM9G) += 0x41008000 + loadaddr-$(CONFIG_MACH_KZM9G_REFERENCE) += 0x41008000 + loadaddr-$(CONFIG_MACH_LAGER) += 0x40008000 +-- +1.8.5.rc3 + diff --git a/patches.renesas/0201-ARM-shmobile-Let-KZM9D-multiplatform-boot-with-KZM9D.patch b/patches.renesas/0201-ARM-shmobile-Let-KZM9D-multiplatform-boot-with-KZM9D.patch new file mode 100644 index 00000000000000..48913fc86edb20 --- /dev/null +++ b/patches.renesas/0201-ARM-shmobile-Let-KZM9D-multiplatform-boot-with-KZM9D.patch @@ -0,0 +1,32 @@ +From 9ad4df47576164035b87c138bb7c664757b09b29 Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 19:33:34 +0900 +Subject: ARM: shmobile: Let KZM9D multiplatform boot with KZM9D DTB + +Let the multiplatform KZM9D support boot with the +legacy DTS for KZM9D as well as the KZM9D reference DTS. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 91f6c56152c7d8ab874dbbf8146a6727d4dff426) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-kzm9d-reference.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/mach-shmobile/board-kzm9d-reference.c b/arch/arm/mach-shmobile/board-kzm9d-reference.c +index 8f8bb2fab076..054d8d5c8fc1 100644 +--- a/arch/arm/mach-shmobile/board-kzm9d-reference.c ++++ b/arch/arm/mach-shmobile/board-kzm9d-reference.c +@@ -33,6 +33,7 @@ static void __init kzm9d_add_standard_devices(void) + } + + static const char *kzm9d_boards_compat_dt[] __initdata = { ++ "renesas,kzm9d", + "renesas,kzm9d-reference", + NULL, + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0202-ARM-shmobile-Remove-KZM9D-reference-DTS.patch b/patches.renesas/0202-ARM-shmobile-Remove-KZM9D-reference-DTS.patch new file mode 100644 index 00000000000000..085f6f42fd51c4 --- /dev/null +++ b/patches.renesas/0202-ARM-shmobile-Remove-KZM9D-reference-DTS.patch @@ -0,0 +1,107 @@ +From cbb34fc9897519c606de5f618075410ece434f4d Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 19:33:43 +0900 +Subject: ARM: shmobile: Remove KZM9D reference DTS + +Now when the legacy DTS file emev2-kzm9d.dts can be +used with board-kzm9d.c and board-kzm9d-reference.c +proceed with removing emev-kzm9d-reference.dts. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 3d888121512f3d70b46ff67d02b41baf474a3123) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/Makefile | 3 +- + arch/arm/boot/dts/emev2-kzm9d-reference.dts | 57 ----------------------------- + 2 files changed, 1 insertion(+), 59 deletions(-) + delete mode 100644 arch/arm/boot/dts/emev2-kzm9d-reference.dts + +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 61f8b5143eee..5df751b250a1 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -160,7 +160,6 @@ dtb-$(CONFIG_ARCH_U8500) += snowball.dtb \ + hrefv60plus.dtb \ + ccu9540.dtb + dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \ +- emev2-kzm9d-reference.dtb \ + r7s72100-genmai.dtb \ + r8a7740-armadillo800eva.dtb \ + r8a7778-bockw.dtb \ +@@ -176,7 +175,7 @@ dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \ + r8a73a4-ape6evm.dtb \ + r8a73a4-ape6evm-reference.dtb \ + sh7372-mackerel.dtb +-dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += emev2-kzm9d-reference.dtb ++dtb-$(CONFIG_ARCH_SHMOBILE_MULTI) += emev2-kzm9d.dtb + dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_cyclone5.dtb \ + socfpga_vt.dtb + dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \ +diff --git a/arch/arm/boot/dts/emev2-kzm9d-reference.dts b/arch/arm/boot/dts/emev2-kzm9d-reference.dts +deleted file mode 100644 +index cceefda268b6..000000000000 +--- a/arch/arm/boot/dts/emev2-kzm9d-reference.dts ++++ /dev/null +@@ -1,57 +0,0 @@ +-/* +- * Device Tree Source for the KZM9D board +- * +- * Copyright (C) 2013 Renesas Solutions Corp. +- * +- * This file is licensed under the terms of the GNU General Public License +- * version 2. This program is licensed "as is" without any warranty of any +- * kind, whether express or implied. +- */ +-/dts-v1/; +- +-/include/ "emev2.dtsi" +- +-/ { +- model = "EMEV2 KZM9D Board"; +- compatible = "renesas,kzm9d-reference", "renesas,emev2"; +- +- memory { +- device_type = "memory"; +- reg = <0x40000000 0x8000000>; +- }; +- +- chosen { +- bootargs = "console=ttyS1,115200n81 ignore_loglevel root=/dev/nfs ip=dhcp"; +- }; +- +- reg_1p8v: regulator@0 { +- compatible = "regulator-fixed"; +- regulator-name = "fixed-1.8V"; +- regulator-min-microvolt = <1800000>; +- regulator-max-microvolt = <1800000>; +- regulator-always-on; +- regulator-boot-on; +- }; +- +- reg_3p3v: regulator@1 { +- compatible = "regulator-fixed"; +- regulator-name = "fixed-3.3V"; +- regulator-min-microvolt = <3300000>; +- regulator-max-microvolt = <3300000>; +- regulator-always-on; +- regulator-boot-on; +- }; +- +- lan9220@20000000 { +- compatible = "smsc,lan9220", "smsc,lan9115"; +- reg = <0x20000000 0x10000>; +- phy-mode = "mii"; +- interrupt-parent = <&gpio0>; +- interrupts = <1 1>; /* active high */ +- reg-io-width = <4>; +- smsc,irq-active-high; +- smsc,irq-push-pull; +- vddvario-supply = <®_1p8v>; +- vdd33a-supply = <®_3p3v>; +- }; +-}; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0203-ARM-shmobile-Use-SMP-on-Koelsch.patch b/patches.renesas/0203-ARM-shmobile-Use-SMP-on-Koelsch.patch new file mode 100644 index 00000000000000..3c211066a8d651 --- /dev/null +++ b/patches.renesas/0203-ARM-shmobile-Use-SMP-on-Koelsch.patch @@ -0,0 +1,30 @@ +From fb806e5b1776908d9eff71a789de796502f635ce Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 1 Oct 2013 17:13:26 +0900 +Subject: ARM: shmobile: Use SMP on Koelsch + +Enable r8a7791 SMP support code on the Koelsch board. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit b6d5a1b1c3476225e897a2f706c0e7eca7b05984) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-koelsch.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/mach-shmobile/board-koelsch.c b/arch/arm/mach-shmobile/board-koelsch.c +index ea5846e2e88c..ace1711a6cd8 100644 +--- a/arch/arm/mach-shmobile/board-koelsch.c ++++ b/arch/arm/mach-shmobile/board-koelsch.c +@@ -39,6 +39,7 @@ static const char * const koelsch_boards_compat_dt[] __initconst = { + }; + + DT_MACHINE_START(KOELSCH_DT, "koelsch") ++ .smp = smp_ops(r8a7791_smp_ops), + .init_early = r8a7791_init_early, + .init_machine = koelsch_add_standard_devices, + .init_time = rcar_gen2_timer_init, +-- +1.8.5.rc3 + diff --git a/patches.renesas/0204-ARM-shmobile-bockw-add-SMSC-support-on-reference.patch b/patches.renesas/0204-ARM-shmobile-bockw-add-SMSC-support-on-reference.patch new file mode 100644 index 00000000000000..069b10a0f18353 --- /dev/null +++ b/patches.renesas/0204-ARM-shmobile-bockw-add-SMSC-support-on-reference.patch @@ -0,0 +1,58 @@ +From 9f3d934bf8c53c3a67fb69df16531613bf373fec Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Wed, 2 Oct 2013 01:33:36 -0700 +Subject: ARM: shmobile: bockw: add SMSC support on reference + +This patch enables INTC IRQ, and SMSC IRQ. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 90357fcbf2fcb9e50899fd3b2a91a6dc3cfe5ea5) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-bockw-reference.c | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +diff --git a/arch/arm/mach-shmobile/board-bockw-reference.c b/arch/arm/mach-shmobile/board-bockw-reference.c +index 1a7c893e1a52..ae88fdad4b3a 100644 +--- a/arch/arm/mach-shmobile/board-bockw-reference.c ++++ b/arch/arm/mach-shmobile/board-bockw-reference.c +@@ -36,15 +36,35 @@ static const struct pinctrl_map bockw_pinctrl_map[] = { + "scif0_ctrl", "scif0"), + }; + ++#define FPGA 0x18200000 ++#define IRQ0MR 0x30 ++#define COMCTLR 0x101c + static void __init bockw_init(void) + { ++ static void __iomem *fpga; ++ + r8a7778_clock_init(); ++ r8a7778_init_irq_extpin_dt(1); + + pinctrl_register_mappings(bockw_pinctrl_map, + ARRAY_SIZE(bockw_pinctrl_map)); + r8a7778_pinmux_init(); + r8a7778_add_dt_devices(); + ++ fpga = ioremap_nocache(FPGA, SZ_1M); ++ if (fpga) { ++ /* ++ * CAUTION ++ * ++ * IRQ0/1 is cascaded interrupt from FPGA. ++ * it should be cared in the future ++ * Now, it is assuming IRQ0 was used only from SMSC. ++ */ ++ u16 val = ioread16(fpga + IRQ0MR); ++ val &= ~(1 << 4); /* enable SMSC911x */ ++ iowrite16(val, fpga + IRQ0MR); ++ } ++ + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + } + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0205-ARM-shmobile-marzen-enable-INTC-IRQ.patch b/patches.renesas/0205-ARM-shmobile-marzen-enable-INTC-IRQ.patch new file mode 100644 index 00000000000000..7b61904a00ede1 --- /dev/null +++ b/patches.renesas/0205-ARM-shmobile-marzen-enable-INTC-IRQ.patch @@ -0,0 +1,31 @@ +From 3021c348f68ce0a5fd0175b4627bc22a25a95896 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Wed, 2 Oct 2013 01:39:48 -0700 +Subject: ARM: shmobile: marzen: enable INTC IRQ + +This patch adds missing INTC IRQ settings +which is required from SMSC. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 7d4bde88e1135c4a3106b79650d3b85335f35717) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-marzen-reference.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/mach-shmobile/board-marzen-reference.c b/arch/arm/mach-shmobile/board-marzen-reference.c +index 3f4250a2d4eb..2773936bf7dc 100644 +--- a/arch/arm/mach-shmobile/board-marzen-reference.c ++++ b/arch/arm/mach-shmobile/board-marzen-reference.c +@@ -28,6 +28,7 @@ + static void __init marzen_init(void) + { + r8a7779_add_standard_devices_dt(); ++ r8a7779_init_irq_extpin_dt(1); /* IRQ1 as individual interrupt */ + } + + static const char *marzen_boards_compat_dt[] __initdata = { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0206-ARM-shmobile-bockw-fixup-ether-node-naming.patch b/patches.renesas/0206-ARM-shmobile-bockw-fixup-ether-node-naming.patch new file mode 100644 index 00000000000000..b776fc936dca67 --- /dev/null +++ b/patches.renesas/0206-ARM-shmobile-bockw-fixup-ether-node-naming.patch @@ -0,0 +1,33 @@ +From 53982713443f44da4d4513523fc531a55043f40b Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Thu, 3 Oct 2013 18:20:19 -0700 +Subject: ARM: shmobile: bockw: fixup ether node naming + +According to the ePAPR spec, +the node name should be "ethernet", not "lan0". + +Reported-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +(cherry picked from commit 73c79afa61cdee2553461ee714bb4716372bdd55) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/boot/dts/r8a7778-bockw-reference.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/boot/dts/r8a7778-bockw-reference.dts b/arch/arm/boot/dts/r8a7778-bockw-reference.dts +index 4425fd2e09f4..969e386e852c 100644 +--- a/arch/arm/boot/dts/r8a7778-bockw-reference.dts ++++ b/arch/arm/boot/dts/r8a7778-bockw-reference.dts +@@ -39,7 +39,7 @@ + regulator-always-on; + }; + +- lan0@18300000 { ++ ethernet@18300000 { + compatible = "smsc,lan9220", "smsc,lan9115"; + reg = <0x18300000 0x1000>; + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0207-ARM-shmobile-Initialize-PWM-backlight-enable_gpio-fi.patch b/patches.renesas/0207-ARM-shmobile-Initialize-PWM-backlight-enable_gpio-fi.patch new file mode 100644 index 00000000000000..5bb1d37548666c --- /dev/null +++ b/patches.renesas/0207-ARM-shmobile-Initialize-PWM-backlight-enable_gpio-fi.patch @@ -0,0 +1,31 @@ +From bfec1cd6fa82dda8a32e28a9674b63383e3c9d53 Mon Sep 17 00:00:00 2001 +From: Thierry Reding <treding@nvidia.com> +Date: Fri, 30 Aug 2013 12:21:42 +0200 +Subject: ARM: shmobile: Initialize PWM backlight enable_gpio field + +The GPIO API defines 0 as being a valid GPIO number, so this field needs +to be initialized explicitly. + +Acked-by: Simon Horman <horms+renesas@verge.net.au> +Signed-off-by: Thierry Reding <treding@nvidia.com> +(cherry picked from commit bf4d252a2906df097874926bcfff6a3bcef38491) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/mach-shmobile/board-armadillo800eva.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c +index 4a11fd34a6e7..0c8595413b62 100644 +--- a/arch/arm/mach-shmobile/board-armadillo800eva.c ++++ b/arch/arm/mach-shmobile/board-armadillo800eva.c +@@ -422,6 +422,7 @@ static struct platform_pwm_backlight_data pwm_backlight_data = { + .max_brightness = 255, + .dft_brightness = 255, + .pwm_period_ns = 33333, /* 30kHz */ ++ .enable_gpio = -1, + }; + + static struct platform_device pwm_backlight_device = { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0208-spi-use-platform_-get-set-_drvdata.patch b/patches.renesas/0208-spi-use-platform_-get-set-_drvdata.patch new file mode 100644 index 00000000000000..cf8dd98b840f88 --- /dev/null +++ b/patches.renesas/0208-spi-use-platform_-get-set-_drvdata.patch @@ -0,0 +1,58 @@ +From 83d6616d0c940be5181c2e0ea9840b493fe11162 Mon Sep 17 00:00:00 2001 +From: Jingoo Han <jg1.han@samsung.com> +Date: Thu, 23 May 2013 19:20:40 +0900 +Subject: spi: use platform_{get,set}_drvdata() + +Use the wrapper functions for getting and setting the driver data using +platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev, +so we can directly pass a struct platform_device. + +Signed-off-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> +(cherry picked from commit 24b5a82cf5709a4bc577f42fdaa61b23a7f58f08) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + drivers/spi/spi-davinci.c + drivers/spi/spi-fsl-spi.c + drivers/spi/spi-mpc52xx-psc.c + drivers/spi/spi-mpc52xx.c + drivers/spi/spi-omap-100k.c + drivers/spi/spi-omap-uwire.c + drivers/spi/spi-omap2-mcspi.c + drivers/spi/spi-orion.c + drivers/spi/spi-ppc4xx.c + drivers/spi/spi-sh-hspi.c + drivers/spi/spi-sh.c + drivers/spi/spi-tegra114.c + drivers/spi/spi-tegra20-sflash.c + drivers/spi/spi-tegra20-slink.c +--- + drivers/spi/spi-rspi.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c +index 902f2fb902db..b44a6ac3cec9 100644 +--- a/drivers/spi/spi-rspi.c ++++ b/drivers/spi/spi-rspi.c +@@ -719,7 +719,7 @@ static void rspi_release_dma(struct rspi_data *rspi) + + static int rspi_remove(struct platform_device *pdev) + { +- struct rspi_data *rspi = dev_get_drvdata(&pdev->dev); ++ struct rspi_data *rspi = platform_get_drvdata(pdev); + + spi_unregister_master(rspi->master); + rspi_release_dma(rspi); +@@ -759,7 +759,7 @@ static int rspi_probe(struct platform_device *pdev) + } + + rspi = spi_master_get_devdata(master); +- dev_set_drvdata(&pdev->dev, rspi); ++ platform_set_drvdata(pdev, rspi); + + rspi->master = master; + rspi->addr = ioremap(res->start, resource_size(res)); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0209-spi-use-platform_-get-set-_drvdata.patch b/patches.renesas/0209-spi-use-platform_-get-set-_drvdata.patch new file mode 100644 index 00000000000000..d6794b6157b144 --- /dev/null +++ b/patches.renesas/0209-spi-use-platform_-get-set-_drvdata.patch @@ -0,0 +1,335 @@ +From 8861d398bc7bfedbfbd6b9f8b07096731b262f18 Mon Sep 17 00:00:00 2001 +From: Jingoo Han <jg1.han@samsung.com> +Date: Thu, 23 May 2013 19:20:40 +0900 +Subject: spi: use platform_{get,set}_drvdata() + +Use the wrapper functions for getting and setting the driver data using +platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev, +so we can directly pass a struct platform_device. + +Signed-off-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com> +(cherry picked from commit 24b5a82cf5709a4bc577f42fdaa61b23a7f58f08) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/spi/spi-davinci.c | 4 ++-- + drivers/spi/spi-fsl-spi.c | 2 +- + drivers/spi/spi-mpc52xx-psc.c | 2 +- + drivers/spi/spi-mpc52xx.c | 4 ++-- + drivers/spi/spi-omap-100k.c | 4 ++-- + drivers/spi/spi-omap-uwire.c | 4 ++-- + drivers/spi/spi-omap2-mcspi.c | 4 ++-- + drivers/spi/spi-orion.c | 4 ++-- + drivers/spi/spi-ppc4xx.c | 6 ++---- + drivers/spi/spi-sh-hspi.c | 4 ++-- + drivers/spi/spi-sh.c | 4 ++-- + drivers/spi/spi-tegra114.c | 4 ++-- + drivers/spi/spi-tegra20-sflash.c | 4 ++-- + drivers/spi/spi-tegra20-slink.c | 4 ++-- + 14 files changed, 26 insertions(+), 28 deletions(-) + +diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c +index df0aacc6fc3b..7554974189dd 100644 +--- a/drivers/spi/spi-davinci.c ++++ b/drivers/spi/spi-davinci.c +@@ -865,7 +865,7 @@ static int davinci_spi_probe(struct platform_device *pdev) + goto err; + } + +- dev_set_drvdata(&pdev->dev, master); ++ platform_set_drvdata(pdev, master); + + dspi = spi_master_get_devdata(master); + if (dspi == NULL) { +@@ -1044,7 +1044,7 @@ static int davinci_spi_remove(struct platform_device *pdev) + struct spi_master *master; + struct resource *r; + +- master = dev_get_drvdata(&pdev->dev); ++ master = platform_get_drvdata(pdev); + dspi = spi_master_get_devdata(master); + + spi_bitbang_stop(&dspi->bitbang); +diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c +index 14e202ee7036..41e89c3e3edc 100644 +--- a/drivers/spi/spi-fsl-spi.c ++++ b/drivers/spi/spi-fsl-spi.c +@@ -853,7 +853,7 @@ err: + + static int of_fsl_spi_remove(struct platform_device *ofdev) + { +- struct spi_master *master = dev_get_drvdata(&ofdev->dev); ++ struct spi_master *master = platform_get_drvdata(ofdev); + struct mpc8xxx_spi *mpc8xxx_spi = spi_master_get_devdata(master); + int ret; + +diff --git a/drivers/spi/spi-mpc52xx-psc.c b/drivers/spi/spi-mpc52xx-psc.c +index 291120b37dbb..fed0571d4dec 100644 +--- a/drivers/spi/spi-mpc52xx-psc.c ++++ b/drivers/spi/spi-mpc52xx-psc.c +@@ -481,7 +481,7 @@ static int mpc52xx_psc_spi_of_probe(struct platform_device *op) + + static int mpc52xx_psc_spi_of_remove(struct platform_device *op) + { +- struct spi_master *master = spi_master_get(dev_get_drvdata(&op->dev)); ++ struct spi_master *master = spi_master_get(platform_get_drvdata(op)); + struct mpc52xx_psc_spi *mps = spi_master_get_devdata(master); + + flush_workqueue(mps->workqueue); +diff --git a/drivers/spi/spi-mpc52xx.c b/drivers/spi/spi-mpc52xx.c +index 29f77056eedc..7c675fe83101 100644 +--- a/drivers/spi/spi-mpc52xx.c ++++ b/drivers/spi/spi-mpc52xx.c +@@ -438,7 +438,7 @@ static int mpc52xx_spi_probe(struct platform_device *op) + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; + master->dev.of_node = op->dev.of_node; + +- dev_set_drvdata(&op->dev, master); ++ platform_set_drvdata(op, master); + + ms = spi_master_get_devdata(master); + ms->master = master; +@@ -529,7 +529,7 @@ static int mpc52xx_spi_probe(struct platform_device *op) + + static int mpc52xx_spi_remove(struct platform_device *op) + { +- struct spi_master *master = spi_master_get(dev_get_drvdata(&op->dev)); ++ struct spi_master *master = spi_master_get(platform_get_drvdata(op)); + struct mpc52xx_spi *ms = spi_master_get_devdata(master); + int i; + +diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c +index 78d29a18dcc4..9236764861a9 100644 +--- a/drivers/spi/spi-omap-100k.c ++++ b/drivers/spi/spi-omap-100k.c +@@ -510,7 +510,7 @@ static int omap1_spi100k_probe(struct platform_device *pdev) + master->num_chipselect = 2; + master->mode_bits = MODEBITS; + +- dev_set_drvdata(&pdev->dev, master); ++ platform_set_drvdata(pdev, master); + + spi100k = spi_master_get_devdata(master); + spi100k->master = master; +@@ -569,7 +569,7 @@ static int omap1_spi100k_remove(struct platform_device *pdev) + unsigned long flags; + int status = 0; + +- master = dev_get_drvdata(&pdev->dev); ++ master = platform_get_drvdata(pdev); + spi100k = spi_master_get_devdata(master); + + spin_lock_irqsave(&spi100k->lock, flags); +diff --git a/drivers/spi/spi-omap-uwire.c b/drivers/spi/spi-omap-uwire.c +index 102b233b50c4..a6a8f0961750 100644 +--- a/drivers/spi/spi-omap-uwire.c ++++ b/drivers/spi/spi-omap-uwire.c +@@ -495,7 +495,7 @@ static int uwire_probe(struct platform_device *pdev) + return -ENOMEM; + } + +- dev_set_drvdata(&pdev->dev, uwire); ++ platform_set_drvdata(pdev, uwire); + + uwire->ck = clk_get(&pdev->dev, "fck"); + if (IS_ERR(uwire->ck)) { +@@ -538,7 +538,7 @@ static int uwire_probe(struct platform_device *pdev) + + static int uwire_remove(struct platform_device *pdev) + { +- struct uwire_spi *uwire = dev_get_drvdata(&pdev->dev); ++ struct uwire_spi *uwire = platform_get_drvdata(pdev); + int status; + + // FIXME remove all child devices, somewhere ... +diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c +index 86d2158946bb..1a75aefd1504 100644 +--- a/drivers/spi/spi-omap2-mcspi.c ++++ b/drivers/spi/spi-omap2-mcspi.c +@@ -1204,7 +1204,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev) + master->cleanup = omap2_mcspi_cleanup; + master->dev.of_node = node; + +- dev_set_drvdata(&pdev->dev, master); ++ platform_set_drvdata(pdev, master); + + mcspi = spi_master_get_devdata(master); + mcspi->master = master; +@@ -1318,7 +1318,7 @@ static int omap2_mcspi_remove(struct platform_device *pdev) + struct omap2_mcspi *mcspi; + struct omap2_mcspi_dma *dma_channels; + +- master = dev_get_drvdata(&pdev->dev); ++ master = platform_get_drvdata(pdev); + mcspi = spi_master_get_devdata(master); + dma_channels = mcspi->dma_channels; + +diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c +index 66a5f82cf138..5d90bebaa0fa 100644 +--- a/drivers/spi/spi-orion.c ++++ b/drivers/spi/spi-orion.c +@@ -428,7 +428,7 @@ static int orion_spi_probe(struct platform_device *pdev) + master->transfer_one_message = orion_spi_transfer_one_message; + master->num_chipselect = ORION_NUM_CHIPSELECTS; + +- dev_set_drvdata(&pdev->dev, master); ++ platform_set_drvdata(pdev, master); + + spi = spi_master_get_devdata(master); + spi->master = master; +@@ -485,7 +485,7 @@ static int orion_spi_remove(struct platform_device *pdev) + struct resource *r; + struct orion_spi *spi; + +- master = dev_get_drvdata(&pdev->dev); ++ master = platform_get_drvdata(pdev); + spi = spi_master_get_devdata(master); + + clk_disable_unprepare(spi->clk); +diff --git a/drivers/spi/spi-ppc4xx.c b/drivers/spi/spi-ppc4xx.c +index 357f183a4fb7..8548e574749d 100644 +--- a/drivers/spi/spi-ppc4xx.c ++++ b/drivers/spi/spi-ppc4xx.c +@@ -406,7 +406,7 @@ static int spi_ppc4xx_of_probe(struct platform_device *op) + if (master == NULL) + return -ENOMEM; + master->dev.of_node = np; +- dev_set_drvdata(dev, master); ++ platform_set_drvdata(op, master); + hw = spi_master_get_devdata(master); + hw->master = spi_master_get(master); + hw->dev = dev; +@@ -553,7 +553,6 @@ request_mem_error: + free_gpios: + free_gpios(hw); + free_master: +- dev_set_drvdata(dev, NULL); + spi_master_put(master); + + dev_err(dev, "initialization failed\n"); +@@ -562,11 +561,10 @@ free_master: + + static int spi_ppc4xx_of_remove(struct platform_device *op) + { +- struct spi_master *master = dev_get_drvdata(&op->dev); ++ struct spi_master *master = platform_get_drvdata(op); + struct ppc4xx_spi *hw = spi_master_get_devdata(master); + + spi_bitbang_stop(&hw->bitbang); +- dev_set_drvdata(&op->dev, NULL); + release_mem_region(hw->mapbase, hw->mapsize); + free_irq(hw->irqnum, hw); + iounmap(hw->regs); +diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c +index eab593eaaafa..716edf999538 100644 +--- a/drivers/spi/spi-sh-hspi.c ++++ b/drivers/spi/spi-sh-hspi.c +@@ -297,7 +297,7 @@ static int hspi_probe(struct platform_device *pdev) + } + + hspi = spi_master_get_devdata(master); +- dev_set_drvdata(&pdev->dev, hspi); ++ platform_set_drvdata(pdev, hspi); + + /* init hspi */ + hspi->master = master; +@@ -341,7 +341,7 @@ static int hspi_probe(struct platform_device *pdev) + + static int hspi_remove(struct platform_device *pdev) + { +- struct hspi_priv *hspi = dev_get_drvdata(&pdev->dev); ++ struct hspi_priv *hspi = platform_get_drvdata(pdev); + + pm_runtime_disable(&pdev->dev); + +diff --git a/drivers/spi/spi-sh.c b/drivers/spi/spi-sh.c +index 3c3600a994bd..c120a70094f2 100644 +--- a/drivers/spi/spi-sh.c ++++ b/drivers/spi/spi-sh.c +@@ -434,7 +434,7 @@ static irqreturn_t spi_sh_irq(int irq, void *_ss) + + static int spi_sh_remove(struct platform_device *pdev) + { +- struct spi_sh_data *ss = dev_get_drvdata(&pdev->dev); ++ struct spi_sh_data *ss = platform_get_drvdata(pdev); + + spi_unregister_master(ss->master); + destroy_workqueue(ss->workqueue); +@@ -471,7 +471,7 @@ static int spi_sh_probe(struct platform_device *pdev) + } + + ss = spi_master_get_devdata(master); +- dev_set_drvdata(&pdev->dev, ss); ++ platform_set_drvdata(pdev, ss); + + switch (res->flags & IORESOURCE_MEM_TYPE_MASK) { + case IORESOURCE_MEM_8BIT: +diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c +index 598eb45e8008..e8f542ab8935 100644 +--- a/drivers/spi/spi-tegra114.c ++++ b/drivers/spi/spi-tegra114.c +@@ -1041,7 +1041,7 @@ static int tegra_spi_probe(struct platform_device *pdev) + dev_err(&pdev->dev, "master allocation failed\n"); + return -ENOMEM; + } +- dev_set_drvdata(&pdev->dev, master); ++ platform_set_drvdata(pdev, master); + tspi = spi_master_get_devdata(master); + + /* Parse DT */ +@@ -1152,7 +1152,7 @@ exit_free_master: + + static int tegra_spi_remove(struct platform_device *pdev) + { +- struct spi_master *master = dev_get_drvdata(&pdev->dev); ++ struct spi_master *master = platform_get_drvdata(pdev); + struct tegra_spi_data *tspi = spi_master_get_devdata(master); + + free_irq(tspi->irq, tspi); +diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c +index 09df8e22dba0..c1d5d95e70ea 100644 +--- a/drivers/spi/spi-tegra20-sflash.c ++++ b/drivers/spi/spi-tegra20-sflash.c +@@ -480,7 +480,7 @@ static int tegra_sflash_probe(struct platform_device *pdev) + master->num_chipselect = MAX_CHIP_SELECT; + master->bus_num = -1; + +- dev_set_drvdata(&pdev->dev, master); ++ platform_set_drvdata(pdev, master); + tsd = spi_master_get_devdata(master); + tsd->master = master; + tsd->dev = &pdev->dev; +@@ -555,7 +555,7 @@ exit_free_master: + + static int tegra_sflash_remove(struct platform_device *pdev) + { +- struct spi_master *master = dev_get_drvdata(&pdev->dev); ++ struct spi_master *master = platform_get_drvdata(pdev); + struct tegra_sflash_data *tsd = spi_master_get_devdata(master); + + free_irq(tsd->irq, tsd); +diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c +index 3faf88d003de..80490cc11ce5 100644 +--- a/drivers/spi/spi-tegra20-slink.c ++++ b/drivers/spi/spi-tegra20-slink.c +@@ -1089,7 +1089,7 @@ static int tegra_slink_probe(struct platform_device *pdev) + master->num_chipselect = MAX_CHIP_SELECT; + master->bus_num = -1; + +- dev_set_drvdata(&pdev->dev, master); ++ platform_set_drvdata(pdev, master); + tspi = spi_master_get_devdata(master); + tspi->master = master; + tspi->dev = &pdev->dev; +@@ -1193,7 +1193,7 @@ exit_free_master: + + static int tegra_slink_remove(struct platform_device *pdev) + { +- struct spi_master *master = dev_get_drvdata(&pdev->dev); ++ struct spi_master *master = platform_get_drvdata(pdev); + struct tegra_slink_data *tspi = spi_master_get_devdata(master); + + free_irq(tspi->irq, tspi); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0210-spi-rspi-provide-port-addresses-to-dmaengine-driver-.patch b/patches.renesas/0210-spi-rspi-provide-port-addresses-to-dmaengine-driver-.patch new file mode 100644 index 00000000000000..8480b8f4c3b147 --- /dev/null +++ b/patches.renesas/0210-spi-rspi-provide-port-addresses-to-dmaengine-driver-.patch @@ -0,0 +1,58 @@ +From 265c240fa92c74c175dfb5cc4456e2e9b2039668 Mon Sep 17 00:00:00 2001 +From: Guennadi Liakhovetski <g.liakhovetski@gmx.de> +Date: Fri, 2 Aug 2013 15:03:42 +0200 +Subject: spi: rspi: provide port addresses to dmaengine driver via slave + configuration + +Don't rely on shdma dhaengine driver getting DMA slave addresses from its +slave configuration. Instead provide those addresses, using a +dmaengine_slave_config() call. + +Signed-off-by: Guennadi Liakhovetski <g.liakhovetski+renesas@gmail.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit e2b0509908aa5e874a1837a733422b6e8b8502b8) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/spi/spi-rspi.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c +index b44a6ac3cec9..5f122d9d2063 100644 +--- a/drivers/spi/spi-rspi.c ++++ b/drivers/spi/spi-rspi.c +@@ -664,12 +664,13 @@ static irqreturn_t rspi_irq(int irq, void *_sr) + static int rspi_request_dma(struct rspi_data *rspi, + struct platform_device *pdev) + { ++ struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + struct rspi_plat_data *rspi_pd = pdev->dev.platform_data; + dma_cap_mask_t mask; + struct dma_slave_config cfg; + int ret; + +- if (!rspi_pd) ++ if (!res || !rspi_pd) + return 0; /* The driver assumes no error. */ + + rspi->dma_width_16bit = rspi_pd->dma_width_16bit; +@@ -683,6 +684,8 @@ static int rspi_request_dma(struct rspi_data *rspi, + if (rspi->chan_rx) { + cfg.slave_id = rspi_pd->dma_rx_id; + cfg.direction = DMA_DEV_TO_MEM; ++ cfg.dst_addr = 0; ++ cfg.src_addr = res->start + RSPI_SPDR; + ret = dmaengine_slave_config(rspi->chan_rx, &cfg); + if (!ret) + dev_info(&pdev->dev, "Use DMA when rx.\n"); +@@ -698,6 +701,8 @@ static int rspi_request_dma(struct rspi_data *rspi, + if (rspi->chan_tx) { + cfg.slave_id = rspi_pd->dma_tx_id; + cfg.direction = DMA_MEM_TO_DEV; ++ cfg.dst_addr = res->start + RSPI_SPDR; ++ cfg.src_addr = 0; + ret = dmaengine_slave_config(rspi->chan_tx, &cfg); + if (!ret) + dev_info(&pdev->dev, "Use DMA when tx\n"); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0211-spi-spi-rspi-fix-inconsistent-spin_lock_irqsave.patch b/patches.renesas/0211-spi-spi-rspi-fix-inconsistent-spin_lock_irqsave.patch new file mode 100644 index 00000000000000..08ae0a0301f430 --- /dev/null +++ b/patches.renesas/0211-spi-spi-rspi-fix-inconsistent-spin_lock_irqsave.patch @@ -0,0 +1,51 @@ +From 9e95337a302a7e165a7b9b99957fd802b2227007 Mon Sep 17 00:00:00 2001 +From: "Shimoda, Yoshihiro" <yoshihiro.shimoda.uh@renesas.com> +Date: Tue, 27 Aug 2013 11:15:09 +0900 +Subject: spi: spi-rspi: fix inconsistent spin_lock_irqsave + +This patch fixes the following Smatch warning: + + CHECK drivers/spi/spi-rspi.c +drivers/spi/spi-rspi.c:606 rspi_work() warn: inconsistent returns spin_lock:&rspi->lock: locked (602) unlocked (606) +drivers/spi/spi-rspi.c:606 rspi_work() warn: inconsistent returns irqsave:flags: locked (602) unlocked (606) + +Reported-by: Dan Carpenter <dan.carpenter@oracle.com> +Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 8d4d08ce8319ae26227c4dd558405963c14c2037) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/spi/spi-rspi.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c +index 5f122d9d2063..00c32320dce8 100644 +--- a/drivers/spi/spi-rspi.c ++++ b/drivers/spi/spi-rspi.c +@@ -564,8 +564,12 @@ static void rspi_work(struct work_struct *work) + unsigned long flags; + int ret; + +- spin_lock_irqsave(&rspi->lock, flags); +- while (!list_empty(&rspi->queue)) { ++ while (1) { ++ spin_lock_irqsave(&rspi->lock, flags); ++ if (list_empty(&rspi->queue)) { ++ spin_unlock_irqrestore(&rspi->lock, flags); ++ break; ++ } + mesg = list_entry(rspi->queue.next, struct spi_message, queue); + list_del_init(&mesg->queue); + spin_unlock_irqrestore(&rspi->lock, flags); +@@ -595,8 +599,6 @@ static void rspi_work(struct work_struct *work) + + mesg->status = 0; + mesg->complete(mesg->context); +- +- spin_lock_irqsave(&rspi->lock, flags); + } + + return; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0212-spi-use-dev_get_platdata.patch b/patches.renesas/0212-spi-use-dev_get_platdata.patch new file mode 100644 index 00000000000000..4150488e03abcc --- /dev/null +++ b/patches.renesas/0212-spi-use-dev_get_platdata.patch @@ -0,0 +1,62 @@ +From 2c65d775624e44926df53067399e3a2d4a4707e5 Mon Sep 17 00:00:00 2001 +From: Jingoo Han <jg1.han@samsung.com> +Date: Tue, 30 Jul 2013 16:58:59 +0900 +Subject: spi: use dev_get_platdata() + +Use the wrapper function for retrieving the platform data instead of +accessing dev->platform_data directly. + +Signed-off-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 8074cf063e410a2c0cf1704c3b31002e21f5df7c) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + drivers/spi/spi-altera.c + drivers/spi/spi-ath79.c + drivers/spi/spi-au1550.c + drivers/spi/spi-bcm63xx.c + drivers/spi/spi-bfin-sport.c + drivers/spi/spi-bfin-v3.c + drivers/spi/spi-bfin5xx.c + drivers/spi/spi-coldfire-qspi.c + drivers/spi/spi-davinci.c + drivers/spi/spi-ep93xx.c + drivers/spi/spi-fsl-espi.c + drivers/spi/spi-fsl-lib.c + drivers/spi/spi-fsl-spi.c + drivers/spi/spi-gpio.c + drivers/spi/spi-mpc512x-psc.c + drivers/spi/spi-mpc52xx-psc.c + drivers/spi/spi-nuc900.c + drivers/spi/spi-oc-tiny.c + drivers/spi/spi-omap-100k.c + drivers/spi/spi-omap2-mcspi.c + drivers/spi/spi-pl022.c + drivers/spi/spi-rspi.c + drivers/spi/spi-s3c24xx.c + drivers/spi/spi-s3c64xx.c + drivers/spi/spi-sh-msiof.c + drivers/spi/spi-ti-ssp.c + drivers/spi/spi-tle62x0.c + drivers/spi/spi-xilinx.c +--- + drivers/spi/spi-sh-sci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-sh-sci.c b/drivers/spi/spi-sh-sci.c +index 097e506042be..8eefeb6007df 100644 +--- a/drivers/spi/spi-sh-sci.c ++++ b/drivers/spi/spi-sh-sci.c +@@ -130,7 +130,7 @@ static int sh_sci_spi_probe(struct platform_device *dev) + sp = spi_master_get_devdata(master); + + platform_set_drvdata(dev, sp); +- sp->info = dev->dev.platform_data; ++ sp->info = dev_get_platdata(&dev->dev); + + /* setup spi bitbang adaptor */ + sp->bitbang.master = spi_master_get(master); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0213-spi-rspi-Add-spi_master_get-call-to-prevent-use-afte.patch b/patches.renesas/0213-spi-rspi-Add-spi_master_get-call-to-prevent-use-afte.patch new file mode 100644 index 00000000000000..54dd9eb7dd8c5a --- /dev/null +++ b/patches.renesas/0213-spi-rspi-Add-spi_master_get-call-to-prevent-use-afte.patch @@ -0,0 +1,36 @@ +From 2ad7467e4426003e04cf09f24e1f3f9dde374db9 Mon Sep 17 00:00:00 2001 +From: Axel Lin <axel.lin@ingics.com> +Date: Sat, 31 Aug 2013 19:42:56 +0800 +Subject: spi: rspi: Add spi_master_get() call to prevent use after free + +In rspi_remove(), current code dereferences rspi after spi_unregister_master(), +thus add an extra spi_master_get() call is necessary to prevent use after free. + +Current code already has an extra spi_master_put() call in rspi_remove(), so +this patch just adds a spi_master_get() call rather than a spi_master_get() with +spi_master_put() calls. + +Signed-off-by: Axel Lin <axel.lin@ingics.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 9d3405dbbbd8418a095301d495da65bc3bc5f806) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/spi/spi-rspi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c +index 00c32320dce8..49ae72a93087 100644 +--- a/drivers/spi/spi-rspi.c ++++ b/drivers/spi/spi-rspi.c +@@ -726,7 +726,7 @@ static void rspi_release_dma(struct rspi_data *rspi) + + static int rspi_remove(struct platform_device *pdev) + { +- struct rspi_data *rspi = platform_get_drvdata(pdev); ++ struct rspi_data *rspi = spi_master_get(platform_get_drvdata(pdev)); + + spi_unregister_master(rspi->master); + rspi_release_dma(rspi); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0214-spi-rspi-Add-missing-dependency-on-DMAE.patch b/patches.renesas/0214-spi-rspi-Add-missing-dependency-on-DMAE.patch new file mode 100644 index 00000000000000..45b10e3f824695 --- /dev/null +++ b/patches.renesas/0214-spi-rspi-Add-missing-dependency-on-DMAE.patch @@ -0,0 +1,32 @@ +From 17ca0811acc1387b909ab0b6aa0227eb37e3fde0 Mon Sep 17 00:00:00 2001 +From: Mark Brown <broonie@linaro.org> +Date: Fri, 5 Jul 2013 19:37:51 +0100 +Subject: spi/rspi: Add missing dependency on DMAE + +The filter function used by the rspi driver is part of the DMAE controller +driver so if the DMA controller driver is somehow disabled then the rspi +driver will fail to build. + +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 838af505843ca6277b47816e284001dbe7875386) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/spi/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig +index 92a9345d7a6b..a51e4be46ae5 100644 +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -341,7 +341,7 @@ config SPI_PXA2XX_PCI + + config SPI_RSPI + tristate "Renesas RSPI controller" +- depends on SUPERH ++ depends on SUPERH && SH_DMAE_BASE + help + SPI driver for Renesas RSPI blocks. + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0215-spi-drivers-Enable-build-of-drivers-with-COMPILE_TES.patch b/patches.renesas/0215-spi-drivers-Enable-build-of-drivers-with-COMPILE_TES.patch new file mode 100644 index 00000000000000..d6f75b7da31f9f --- /dev/null +++ b/patches.renesas/0215-spi-drivers-Enable-build-of-drivers-with-COMPILE_TES.patch @@ -0,0 +1,35 @@ +From 3ec1db9e6d0ba81e4248db02d52a7d62a8cca80c Mon Sep 17 00:00:00 2001 +From: Mark Brown <broonie@linaro.org> +Date: Fri, 5 Jul 2013 19:42:58 +0100 +Subject: spi/drivers: Enable build of drivers with COMPILE_TEST + +Enable the build of drivers which don't have any real build time +dependency on their architecture or platform with COMPILE_TEST, +providing better build time coverage. + +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 838af505843ca6277b47816e284001dbe7875386) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + drivers/spi/Kconfig +--- + drivers/spi/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig +index a51e4be46ae5..0c19ed6a62f4 100644 +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -385,7 +385,7 @@ config SPI_SH_MSIOF + + config SPI_SH + tristate "SuperH SPI controller" +- depends on SUPERH ++ depends on SUPERH || COMPILE_TEST + help + SPI driver for SuperH SPI blocks. + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0216-spi-rcar-add-Renesas-QSPI-support-on-RSPI.patch b/patches.renesas/0216-spi-rcar-add-Renesas-QSPI-support-on-RSPI.patch new file mode 100644 index 00000000000000..f0b4bb7a2f96f8 --- /dev/null +++ b/patches.renesas/0216-spi-rcar-add-Renesas-QSPI-support-on-RSPI.patch @@ -0,0 +1,333 @@ +From 2dff0ab0360e79e4594fa6b940004d9943bc109b Mon Sep 17 00:00:00 2001 +From: Hiep Cao Minh <cm-hiep@jinso.co.jp> +Date: Tue, 3 Sep 2013 13:10:26 +0900 +Subject: spi: rcar: add Renesas QSPI support on RSPI + +The R8A7790 has QSPI module which is very similar to RSPI. +This patch adds into RSPI module together to supports QSPI module. + +Signed-off-by: Hiep Cao Minh <cm-hiep@jinso.co.jp> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 5ce0ba88650f2606244a761d92e2b725f4ab3583) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/spi/Kconfig | 2 +- + drivers/spi/spi-rspi.c | 181 ++++++++++++++++++++++++++++++++++++----------- + include/linux/spi/rspi.h | 2 + + 3 files changed, 144 insertions(+), 41 deletions(-) + +diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig +index 0c19ed6a62f4..f9f44767c542 100644 +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -341,7 +341,7 @@ config SPI_PXA2XX_PCI + + config SPI_RSPI + tristate "Renesas RSPI controller" +- depends on SUPERH && SH_DMAE_BASE ++ depends on (SUPERH || ARCH_SHMOBILE) && SH_DMAE_BASE + help + SPI driver for Renesas RSPI blocks. + +diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c +index 49ae72a93087..7675a6b25653 100644 +--- a/drivers/spi/spi-rspi.c ++++ b/drivers/spi/spi-rspi.c +@@ -59,6 +59,14 @@ + #define RSPI_SPCMD6 0x1c + #define RSPI_SPCMD7 0x1e + ++/*qspi only */ ++#define QSPI_SPBFCR 0x18 ++#define QSPI_SPBDCR 0x1a ++#define QSPI_SPBMUL0 0x1c ++#define QSPI_SPBMUL1 0x20 ++#define QSPI_SPBMUL2 0x24 ++#define QSPI_SPBMUL3 0x28 ++ + /* SPCR */ + #define SPCR_SPRIE 0x80 + #define SPCR_SPE 0x40 +@@ -126,6 +134,8 @@ + #define SPCMD_LSBF 0x1000 + #define SPCMD_SPB_MASK 0x0f00 + #define SPCMD_SPB_8_TO_16(bit) (((bit - 1) << 8) & SPCMD_SPB_MASK) ++#define SPCMD_SPB_8BIT 0x0000 /* qspi only */ ++#define SPCMD_SPB_16BIT 0x0100 + #define SPCMD_SPB_20BIT 0x0000 + #define SPCMD_SPB_24BIT 0x0100 + #define SPCMD_SPB_32BIT 0x0200 +@@ -135,6 +145,10 @@ + #define SPCMD_CPOL 0x0002 + #define SPCMD_CPHA 0x0001 + ++/* SPBFCR */ ++#define SPBFCR_TXRST 0x80 /* qspi only */ ++#define SPBFCR_RXRST 0x40 /* qspi only */ ++ + struct rspi_data { + void __iomem *addr; + u32 max_speed_hz; +@@ -145,6 +159,7 @@ struct rspi_data { + spinlock_t lock; + struct clk *clk; + unsigned char spsr; ++ const struct spi_ops *ops; + + /* for dmaengine */ + struct dma_chan *chan_tx; +@@ -165,6 +180,11 @@ static void rspi_write16(struct rspi_data *rspi, u16 data, u16 offset) + iowrite16(data, rspi->addr + offset); + } + ++static void rspi_write32(struct rspi_data *rspi, u32 data, u16 offset) ++{ ++ iowrite32(data, rspi->addr + offset); ++} ++ + static u8 rspi_read8(struct rspi_data *rspi, u16 offset) + { + return ioread8(rspi->addr + offset); +@@ -175,17 +195,98 @@ static u16 rspi_read16(struct rspi_data *rspi, u16 offset) + return ioread16(rspi->addr + offset); + } + +-static unsigned char rspi_calc_spbr(struct rspi_data *rspi) ++/* optional functions */ ++struct spi_ops { ++ int (*set_config_register)(struct rspi_data *rspi, int access_size); ++}; ++ ++/* ++ * functions for RSPI ++ */ ++static int rspi_set_config_register(struct rspi_data *rspi, int access_size) + { +- int tmp; +- unsigned char spbr; ++ int spbr; ++ ++ /* Sets output mode(CMOS) and MOSI signal(from previous transfer) */ ++ rspi_write8(rspi, 0x00, RSPI_SPPCR); + +- tmp = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1; +- spbr = clamp(tmp, 0, 255); ++ /* Sets transfer bit rate */ ++ spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz) - 1; ++ rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR); ++ ++ /* Sets number of frames to be used: 1 frame */ ++ rspi_write8(rspi, 0x00, RSPI_SPDCR); + +- return spbr; ++ /* Sets RSPCK, SSL, next-access delay value */ ++ rspi_write8(rspi, 0x00, RSPI_SPCKD); ++ rspi_write8(rspi, 0x00, RSPI_SSLND); ++ rspi_write8(rspi, 0x00, RSPI_SPND); ++ ++ /* Sets parity, interrupt mask */ ++ rspi_write8(rspi, 0x00, RSPI_SPCR2); ++ ++ /* Sets SPCMD */ ++ rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | SPCMD_SSLKP, ++ RSPI_SPCMD0); ++ ++ /* Sets RSPI mode */ ++ rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR); ++ ++ return 0; + } + ++/* ++ * functions for QSPI ++ */ ++static int qspi_set_config_register(struct rspi_data *rspi, int access_size) ++{ ++ u16 spcmd; ++ int spbr; ++ ++ /* Sets output mode(CMOS) and MOSI signal(from previous transfer) */ ++ rspi_write8(rspi, 0x00, RSPI_SPPCR); ++ ++ /* Sets transfer bit rate */ ++ spbr = clk_get_rate(rspi->clk) / (2 * rspi->max_speed_hz); ++ rspi_write8(rspi, clamp(spbr, 0, 255), RSPI_SPBR); ++ ++ /* Sets number of frames to be used: 1 frame */ ++ rspi_write8(rspi, 0x00, RSPI_SPDCR); ++ ++ /* Sets RSPCK, SSL, next-access delay value */ ++ rspi_write8(rspi, 0x00, RSPI_SPCKD); ++ rspi_write8(rspi, 0x00, RSPI_SSLND); ++ rspi_write8(rspi, 0x00, RSPI_SPND); ++ ++ /* Data Length Setting */ ++ if (access_size == 8) ++ spcmd = SPCMD_SPB_8BIT; ++ else if (access_size == 16) ++ spcmd = SPCMD_SPB_16BIT; ++ else if (access_size == 32) ++ spcmd = SPCMD_SPB_32BIT; ++ ++ spcmd |= SPCMD_SCKDEN | SPCMD_SLNDEN | SPCMD_SSLKP | SPCMD_SPNDEN; ++ ++ /* Resets transfer data length */ ++ rspi_write32(rspi, 0, QSPI_SPBMUL0); ++ ++ /* Resets transmit and receive buffer */ ++ rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR); ++ /* Sets buffer to allow normal operation */ ++ rspi_write8(rspi, 0x00, QSPI_SPBFCR); ++ ++ /* Sets SPCMD */ ++ rspi_write16(rspi, spcmd, RSPI_SPCMD0); ++ ++ /* Enables SPI function in a master mode */ ++ rspi_write8(rspi, SPCR_SPE | SPCR_MSTR, RSPI_SPCR); ++ ++ return 0; ++} ++ ++#define set_config_register(spi, n) spi->ops->set_config_register(spi, n) ++ + static void rspi_enable_irq(struct rspi_data *rspi, u8 enable) + { + rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) | enable, RSPI_SPCR); +@@ -220,35 +321,6 @@ static void rspi_negate_ssl(struct rspi_data *rspi) + rspi_write8(rspi, rspi_read8(rspi, RSPI_SPCR) & ~SPCR_SPE, RSPI_SPCR); + } + +-static int rspi_set_config_register(struct rspi_data *rspi, int access_size) +-{ +- /* Sets output mode(CMOS) and MOSI signal(from previous transfer) */ +- rspi_write8(rspi, 0x00, RSPI_SPPCR); +- +- /* Sets transfer bit rate */ +- rspi_write8(rspi, rspi_calc_spbr(rspi), RSPI_SPBR); +- +- /* Sets number of frames to be used: 1 frame */ +- rspi_write8(rspi, 0x00, RSPI_SPDCR); +- +- /* Sets RSPCK, SSL, next-access delay value */ +- rspi_write8(rspi, 0x00, RSPI_SPCKD); +- rspi_write8(rspi, 0x00, RSPI_SSLND); +- rspi_write8(rspi, 0x00, RSPI_SPND); +- +- /* Sets parity, interrupt mask */ +- rspi_write8(rspi, 0x00, RSPI_SPCR2); +- +- /* Sets SPCMD */ +- rspi_write16(rspi, SPCMD_SPB_8_TO_16(access_size) | SPCMD_SSLKP, +- RSPI_SPCMD0); +- +- /* Sets RSPI mode */ +- rspi_write8(rspi, SPCR_MSTR, RSPI_SPCR); +- +- return 0; +-} +- + static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, + struct spi_transfer *t) + { +@@ -616,7 +688,7 @@ static int rspi_setup(struct spi_device *spi) + spi->bits_per_word = 8; + rspi->max_speed_hz = spi->max_speed_hz; + +- rspi_set_config_register(rspi, 8); ++ set_config_register(rspi, 8); + + return 0; + } +@@ -745,7 +817,16 @@ static int rspi_probe(struct platform_device *pdev) + struct rspi_data *rspi; + int ret, irq; + char clk_name[16]; ++ struct rspi_plat_data *rspi_pd = pdev->dev.platform_data; ++ const struct spi_ops *ops; ++ const struct platform_device_id *id_entry = pdev->id_entry; + ++ ops = (struct spi_ops *)id_entry->driver_data; ++ /* ops parameter check */ ++ if (!ops->set_config_register) { ++ dev_err(&pdev->dev, "there is no set_config_register\n"); ++ return -ENODEV; ++ } + /* get base addr */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(res == NULL)) { +@@ -767,7 +848,7 @@ static int rspi_probe(struct platform_device *pdev) + + rspi = spi_master_get_devdata(master); + platform_set_drvdata(pdev, rspi); +- ++ rspi->ops = ops; + rspi->master = master; + rspi->addr = ioremap(res->start, resource_size(res)); + if (rspi->addr == NULL) { +@@ -776,7 +857,7 @@ static int rspi_probe(struct platform_device *pdev) + goto error1; + } + +- snprintf(clk_name, sizeof(clk_name), "rspi%d", pdev->id); ++ snprintf(clk_name, sizeof(clk_name), "%s%d", id_entry->name, pdev->id); + rspi->clk = clk_get(&pdev->dev, clk_name); + if (IS_ERR(rspi->clk)) { + dev_err(&pdev->dev, "cannot get clock\n"); +@@ -790,7 +871,10 @@ static int rspi_probe(struct platform_device *pdev) + INIT_WORK(&rspi->ws, rspi_work); + init_waitqueue_head(&rspi->wait); + +- master->num_chipselect = 2; ++ master->num_chipselect = rspi_pd->num_chipselect; ++ if (!master->num_chipselect) ++ master->num_chipselect = 2; /* default */ ++ + master->bus_num = pdev->id; + master->setup = rspi_setup; + master->transfer = rspi_transfer; +@@ -832,11 +916,28 @@ error1: + return ret; + } + ++static struct spi_ops rspi_ops = { ++ .set_config_register = rspi_set_config_register, ++}; ++ ++static struct spi_ops qspi_ops = { ++ .set_config_register = qspi_set_config_register, ++}; ++ ++static struct platform_device_id spi_driver_ids[] = { ++ { "rspi", (kernel_ulong_t)&rspi_ops }, ++ { "qspi", (kernel_ulong_t)&qspi_ops }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(platform, spi_driver_ids); ++ + static struct platform_driver rspi_driver = { + .probe = rspi_probe, + .remove = rspi_remove, ++ .id_table = spi_driver_ids, + .driver = { +- .name = "rspi", ++ .name = "renesas_spi", + .owner = THIS_MODULE, + }, + }; +diff --git a/include/linux/spi/rspi.h b/include/linux/spi/rspi.h +index 900f0e328235..a25bd6f65e7f 100644 +--- a/include/linux/spi/rspi.h ++++ b/include/linux/spi/rspi.h +@@ -26,6 +26,8 @@ struct rspi_plat_data { + unsigned int dma_rx_id; + + unsigned dma_width_16bit:1; /* DMAC read/write width = 16-bit */ ++ ++ u16 num_chipselect; + }; + + #endif +-- +1.8.5.rc3 + diff --git a/patches.renesas/0217-spi-rspi-Fix-8bit-data-access-clear-buffer.patch b/patches.renesas/0217-spi-rspi-Fix-8bit-data-access-clear-buffer.patch new file mode 100644 index 00000000000000..2332f5efc30704 --- /dev/null +++ b/patches.renesas/0217-spi-rspi-Fix-8bit-data-access-clear-buffer.patch @@ -0,0 +1,178 @@ +From 0c7abc24526705b66ce42dc078646277e97de726 Mon Sep 17 00:00:00 2001 +From: Hiep Cao Minh <cm-hiep@jinso.co.jp> +Date: Thu, 10 Oct 2013 17:14:03 +0900 +Subject: spi/rspi: Fix 8bit data access, clear buffer + +The R8A7790 has QSPI module which added into RSPI together. +The transmit or receive data should be read from or written to +with the longword-, word-, or byte-access width. Modify word- +access to byte-access. In 16-bit data register, QSPI send or +receive datas access from high 8-bit while RSPI send or receive +datas access from low 8-bit on single mode. +Modify to reset transmit-receive buffer data and reading dummy +after data are transmited. RSPI has a TXMD bit on control +register(SPCR) to set transmit-only mode when transmit data or +Full-duplex synchronous mode when receive data. In QSPI the TXMD +bit is not supported, so after transmit data, dummy should be +read and before transmit or receive data the bufer register +should be reset. +This driver is the implementation of send and receive pio only, +DMA is not supported at this time. +Without this patch, it will occur error when transmit and receive + +Signed-off-by: Hiep Cao Minh <cm-hiep@jinso.co.jp> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit cb52c673f8adc4a1cba7b645ff5375b57dae21fa) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/spi/spi-rspi.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 93 insertions(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c +index 7675a6b25653..437e052695a7 100644 +--- a/drivers/spi/spi-rspi.c ++++ b/drivers/spi/spi-rspi.c +@@ -198,6 +198,11 @@ static u16 rspi_read16(struct rspi_data *rspi, u16 offset) + /* optional functions */ + struct spi_ops { + int (*set_config_register)(struct rspi_data *rspi, int access_size); ++ int (*send_pio)(struct rspi_data *rspi, struct spi_message *mesg, ++ struct spi_transfer *t); ++ int (*receive_pio)(struct rspi_data *rspi, struct spi_message *mesg, ++ struct spi_transfer *t); ++ + }; + + /* +@@ -349,6 +354,43 @@ static int rspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, + return 0; + } + ++static int qspi_send_pio(struct rspi_data *rspi, struct spi_message *mesg, ++ struct spi_transfer *t) ++{ ++ int remain = t->len; ++ u8 *data; ++ ++ rspi_write8(rspi, SPBFCR_TXRST, QSPI_SPBFCR); ++ rspi_write8(rspi, 0x00, QSPI_SPBFCR); ++ ++ data = (u8 *)t->tx_buf; ++ while (remain > 0) { ++ ++ if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { ++ dev_err(&rspi->master->dev, ++ "%s: tx empty timeout\n", __func__); ++ return -ETIMEDOUT; ++ } ++ rspi_write8(rspi, *data++, RSPI_SPDR); ++ ++ if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { ++ dev_err(&rspi->master->dev, ++ "%s: receive timeout\n", __func__); ++ return -ETIMEDOUT; ++ } ++ rspi_read8(rspi, RSPI_SPDR); ++ ++ remain--; ++ } ++ ++ /* Waiting for the last transmition */ ++ rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE); ++ ++ return 0; ++} ++ ++#define send_pio(spi, mesg, t) spi->ops->send_pio(spi, mesg, t) ++ + static void rspi_dma_complete(void *arg) + { + struct rspi_data *rspi = arg; +@@ -514,6 +556,51 @@ static int rspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, + return 0; + } + ++static void qspi_receive_init(struct rspi_data *rspi) ++{ ++ unsigned char spsr; ++ ++ spsr = rspi_read8(rspi, RSPI_SPSR); ++ if (spsr & SPSR_SPRF) ++ rspi_read8(rspi, RSPI_SPDR); /* dummy read */ ++ rspi_write8(rspi, SPBFCR_TXRST | SPBFCR_RXRST, QSPI_SPBFCR); ++ rspi_write8(rspi, 0x00, QSPI_SPBFCR); ++} ++ ++static int qspi_receive_pio(struct rspi_data *rspi, struct spi_message *mesg, ++ struct spi_transfer *t) ++{ ++ int remain = t->len; ++ u8 *data; ++ ++ qspi_receive_init(rspi); ++ ++ data = (u8 *)t->rx_buf; ++ while (remain > 0) { ++ ++ if (rspi_wait_for_interrupt(rspi, SPSR_SPTEF, SPCR_SPTIE) < 0) { ++ dev_err(&rspi->master->dev, ++ "%s: tx empty timeout\n", __func__); ++ return -ETIMEDOUT; ++ } ++ /* dummy write for generate clock */ ++ rspi_write8(rspi, 0x00, RSPI_SPDR); ++ ++ if (rspi_wait_for_interrupt(rspi, SPSR_SPRF, SPCR_SPRIE) < 0) { ++ dev_err(&rspi->master->dev, ++ "%s: receive timeout\n", __func__); ++ return -ETIMEDOUT; ++ } ++ /* SPDR allows 8, 16 or 32-bit access */ ++ *data++ = rspi_read8(rspi, RSPI_SPDR); ++ remain--; ++ } ++ ++ return 0; ++} ++ ++#define receive_pio(spi, mesg, t) spi->ops->receive_pio(spi, mesg, t) ++ + static int rspi_receive_dma(struct rspi_data *rspi, struct spi_transfer *t) + { + struct scatterlist sg, sg_dummy; +@@ -653,7 +740,7 @@ static void rspi_work(struct work_struct *work) + if (rspi_is_dma(rspi, t)) + ret = rspi_send_dma(rspi, t); + else +- ret = rspi_send_pio(rspi, mesg, t); ++ ret = send_pio(rspi, mesg, t); + if (ret < 0) + goto error; + } +@@ -661,7 +748,7 @@ static void rspi_work(struct work_struct *work) + if (rspi_is_dma(rspi, t)) + ret = rspi_receive_dma(rspi, t); + else +- ret = rspi_receive_pio(rspi, mesg, t); ++ ret = receive_pio(rspi, mesg, t); + if (ret < 0) + goto error; + } +@@ -918,10 +1005,14 @@ error1: + + static struct spi_ops rspi_ops = { + .set_config_register = rspi_set_config_register, ++ .send_pio = rspi_send_pio, ++ .receive_pio = rspi_receive_pio, + }; + + static struct spi_ops qspi_ops = { + .set_config_register = qspi_set_config_register, ++ .send_pio = qspi_send_pio, ++ .receive_pio = qspi_receive_pio, + }; + + static struct platform_device_id spi_driver_ids[] = { +-- +1.8.5.rc3 + diff --git a/patches.renesas/0218-spi-rspi-use-platform-drvdata-correctly-in-rspi_remo.patch b/patches.renesas/0218-spi-rspi-use-platform-drvdata-correctly-in-rspi_remo.patch new file mode 100644 index 00000000000000..511e49737f2f94 --- /dev/null +++ b/patches.renesas/0218-spi-rspi-use-platform-drvdata-correctly-in-rspi_remo.patch @@ -0,0 +1,41 @@ +From 70b7a5f752b38fd35becb82f4e29a89692089faf Mon Sep 17 00:00:00 2001 +From: Wei Yongjun <yongjun_wei@trendmicro.com.cn> +Date: Fri, 15 Nov 2013 15:44:02 +0800 +Subject: spi: rspi: use platform drvdata correctly in rspi_remove() + +We had set the platform drvdata in rspi_probe() as a type of +struct rspi_data, but use it as struct spi_master in rspi_remove() +Fix by remove the unnecessary spi_master_[get|put]() since rspi->master +is no longer used after spi_unregister_master(). + +Signed-off-by: Wei Yongjun <yongjun_wei@trendmicro.com.cn> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 53063ec6e2cc38000f98a5de557b7e4fed186cfc) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/spi/spi-rspi.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c +index 437e052695a7..0d39fa614da7 100644 +--- a/drivers/spi/spi-rspi.c ++++ b/drivers/spi/spi-rspi.c +@@ -885,14 +885,13 @@ static void rspi_release_dma(struct rspi_data *rspi) + + static int rspi_remove(struct platform_device *pdev) + { +- struct rspi_data *rspi = spi_master_get(platform_get_drvdata(pdev)); ++ struct rspi_data *rspi = platform_get_drvdata(pdev); + + spi_unregister_master(rspi->master); + rspi_release_dma(rspi); + free_irq(platform_get_irq(pdev, 0), rspi); + clk_put(rspi->clk); + iounmap(rspi->addr); +- spi_master_put(rspi->master); + + return 0; + } +-- +1.8.5.rc3 + diff --git a/patches.renesas/0219-spi-sh-msiof-Remove-unneeded-empty-runtime-PM-callba.patch b/patches.renesas/0219-spi-sh-msiof-Remove-unneeded-empty-runtime-PM-callba.patch new file mode 100644 index 00000000000000..7ed3b333cfcb0f --- /dev/null +++ b/patches.renesas/0219-spi-sh-msiof-Remove-unneeded-empty-runtime-PM-callba.patch @@ -0,0 +1,61 @@ +From 9f9c72893ff250d6f5846c862c0454559e9e5005 Mon Sep 17 00:00:00 2001 +From: Mark Brown <broonie@linaro.org> +Date: Sun, 28 Jul 2013 15:36:38 +0100 +Subject: spi/sh-msiof: Remove unneeded empty runtime PM callbacks + +Previously the runtime PM API insisted on having callbacks for everything +but this requirement was removed a while ago so the empty callbacks can +also be removed. + +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 33bf2c0b7d5af73763f41fd10d18f4c1f574c7fb) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/spi/spi-sh-msiof.c | 18 ------------------ + 1 file changed, 18 deletions(-) + +diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c +index 2bc5a6b86300..6688ce78df78 100644 +--- a/drivers/spi/spi-sh-msiof.c ++++ b/drivers/spi/spi-sh-msiof.c +@@ -745,18 +745,6 @@ static int sh_msiof_spi_remove(struct platform_device *pdev) + return ret; + } + +-static int sh_msiof_spi_runtime_nop(struct device *dev) +-{ +- /* Runtime PM callback shared between ->runtime_suspend() +- * and ->runtime_resume(). Simply returns success. +- * +- * This driver re-initializes all registers after +- * pm_runtime_get_sync() anyway so there is no need +- * to save and restore registers here. +- */ +- return 0; +-} +- + #ifdef CONFIG_OF + static const struct of_device_id sh_msiof_match[] = { + { .compatible = "renesas,sh-msiof", }, +@@ -766,18 +754,12 @@ static const struct of_device_id sh_msiof_match[] = { + MODULE_DEVICE_TABLE(of, sh_msiof_match); + #endif + +-static struct dev_pm_ops sh_msiof_spi_dev_pm_ops = { +- .runtime_suspend = sh_msiof_spi_runtime_nop, +- .runtime_resume = sh_msiof_spi_runtime_nop, +-}; +- + static struct platform_driver sh_msiof_spi_drv = { + .probe = sh_msiof_spi_probe, + .remove = sh_msiof_spi_remove, + .driver = { + .name = "spi_sh_msiof", + .owner = THIS_MODULE, +- .pm = &sh_msiof_spi_dev_pm_ops, + .of_match_table = of_match_ptr(sh_msiof_match), + }, + }; +-- +1.8.5.rc3 + diff --git a/patches.renesas/0220-spi-use-dev_get_platdata.patch b/patches.renesas/0220-spi-use-dev_get_platdata.patch new file mode 100644 index 00000000000000..9ad94c7ffcf065 --- /dev/null +++ b/patches.renesas/0220-spi-use-dev_get_platdata.patch @@ -0,0 +1,62 @@ +From 4b9fa38e0d1fc7b02c2ec732d1002ba5e7b33a2d Mon Sep 17 00:00:00 2001 +From: Jingoo Han <jg1.han@samsung.com> +Date: Tue, 30 Jul 2013 16:58:59 +0900 +Subject: spi: use dev_get_platdata() + +Use the wrapper function for retrieving the platform data instead of +accessing dev->platform_data directly. + +Signed-off-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 8074cf063e410a2c0cf1704c3b31002e21f5df7c) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> + +Conflicts: + drivers/spi/spi-altera.c + drivers/spi/spi-ath79.c + drivers/spi/spi-au1550.c + drivers/spi/spi-bcm63xx.c + drivers/spi/spi-bfin-sport.c + drivers/spi/spi-bfin-v3.c + drivers/spi/spi-bfin5xx.c + drivers/spi/spi-coldfire-qspi.c + drivers/spi/spi-davinci.c + drivers/spi/spi-ep93xx.c + drivers/spi/spi-fsl-espi.c + drivers/spi/spi-fsl-lib.c + drivers/spi/spi-fsl-spi.c + drivers/spi/spi-gpio.c + drivers/spi/spi-mpc512x-psc.c + drivers/spi/spi-mpc52xx-psc.c + drivers/spi/spi-nuc900.c + drivers/spi/spi-oc-tiny.c + drivers/spi/spi-omap-100k.c + drivers/spi/spi-omap2-mcspi.c + drivers/spi/spi-pl022.c + drivers/spi/spi-rspi.c + drivers/spi/spi-s3c24xx.c + drivers/spi/spi-s3c64xx.c + drivers/spi/spi-sh-sci.c + drivers/spi/spi-ti-ssp.c + drivers/spi/spi-tle62x0.c + drivers/spi/spi-xilinx.c +--- + drivers/spi/spi-sh-msiof.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c +index 6688ce78df78..2a95435a6a11 100644 +--- a/drivers/spi/spi-sh-msiof.c ++++ b/drivers/spi/spi-sh-msiof.c +@@ -645,7 +645,7 @@ static int sh_msiof_spi_probe(struct platform_device *pdev) + if (pdev->dev.of_node) + p->info = sh_msiof_spi_parse_dt(&pdev->dev); + else +- p->info = pdev->dev.platform_data; ++ p->info = dev_get_platdata(&pdev->dev); + + if (!p->info) { + dev_err(&pdev->dev, "failed to obtain device info\n"); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0221-ARM-7863-1-Let-arm_add_memory-always-use-64-bit-argu.patch b/patches.renesas/0221-ARM-7863-1-Let-arm_add_memory-always-use-64-bit-argu.patch new file mode 100644 index 00000000000000..2d0ebeec4b4148 --- /dev/null +++ b/patches.renesas/0221-ARM-7863-1-Let-arm_add_memory-always-use-64-bit-argu.patch @@ -0,0 +1,63 @@ +From 8a46a984b291fb9753340b18b804fdaa5c31487f Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 22 Oct 2013 17:53:16 +0100 +Subject: ARM: 7863/1: Let arm_add_memory() always use 64-bit arguments + +The DTB and/or the kernel command line may pass +64-bit addresses regardless of kernel configuration, +so update arm_add_memory() to take 64-bit arguments +independently of the phys_addr_t size. + +This allows non-wrapping handling of high memory +banks such as the second memory bank of APE6EVM +(at 0x2_0000_0000) in case of 32-bit phys_addr_t. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> +(cherry picked from commit 6a5014aa037495a14ea083b621ed97fd0c3c7e9e) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/include/asm/setup.h | 2 +- + arch/arm/kernel/setup.c | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h +index c50f05609501..8d6a089dfb76 100644 +--- a/arch/arm/include/asm/setup.h ++++ b/arch/arm/include/asm/setup.h +@@ -49,7 +49,7 @@ extern struct meminfo meminfo; + #define bank_phys_end(bank) ((bank)->start + (bank)->size) + #define bank_phys_size(bank) (bank)->size + +-extern int arm_add_memory(phys_addr_t start, phys_addr_t size); ++extern int arm_add_memory(u64 start, u64 size); + extern void early_print(const char *str, ...); + extern void dump_machine_table(void); + +diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c +index d62772f49907..23497e4c94c6 100644 +--- a/arch/arm/kernel/setup.c ++++ b/arch/arm/kernel/setup.c +@@ -532,7 +532,7 @@ void __init dump_machine_table(void) + /* can't use cpu_relax() here as it may require MMU setup */; + } + +-int __init arm_add_memory(phys_addr_t start, phys_addr_t size) ++int __init arm_add_memory(u64 start, u64 size) + { + struct membank *bank = &meminfo.bank[meminfo.nr_banks]; + +@@ -582,8 +582,8 @@ int __init arm_add_memory(phys_addr_t start, phys_addr_t size) + static int __init early_mem(char *p) + { + static int usermem __initdata = 0; +- phys_addr_t size; +- phys_addr_t start; ++ u64 size; ++ u64 start; + char *endp; + + /* +-- +1.8.5.rc3 + diff --git a/patches.renesas/0222-ARM-7864-1-Handle-64-bit-memory-in-case-of-32-bit-ph.patch b/patches.renesas/0222-ARM-7864-1-Handle-64-bit-memory-in-case-of-32-bit-ph.patch new file mode 100644 index 00000000000000..e3e973889e8c3d --- /dev/null +++ b/patches.renesas/0222-ARM-7864-1-Handle-64-bit-memory-in-case-of-32-bit-ph.patch @@ -0,0 +1,67 @@ +From 4bb68c4956d302847a872dd76a7f4ce1635c3a9d Mon Sep 17 00:00:00 2001 +From: Magnus Damm <damm@opensource.se> +Date: Tue, 22 Oct 2013 17:59:54 +0100 +Subject: ARM: 7864/1: Handle 64-bit memory in case of 32-bit phys_addr_t + +Use CONFIG_ARCH_PHYS_ADDR_T_64BIT to determine +if ignoring or truncating of memory banks is +neccessary. This may be needed in the case of +64-bit memory bank addresses but when phys_addr_t +is kept 32-bit. + +Signed-off-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> +(cherry picked from commit 6d7d5da7d75c6df676c8b72d32b02ff024438f0c) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + arch/arm/kernel/setup.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c +index 23497e4c94c6..4f991e8b9a7d 100644 +--- a/arch/arm/kernel/setup.c ++++ b/arch/arm/kernel/setup.c +@@ -535,6 +535,7 @@ void __init dump_machine_table(void) + int __init arm_add_memory(u64 start, u64 size) + { + struct membank *bank = &meminfo.bank[meminfo.nr_banks]; ++ u64 aligned_start; + + if (meminfo.nr_banks >= NR_BANKS) { + printk(KERN_CRIT "NR_BANKS too low, " +@@ -547,10 +548,16 @@ int __init arm_add_memory(u64 start, u64 size) + * Size is appropriately rounded down, start is rounded up. + */ + size -= start & ~PAGE_MASK; +- bank->start = PAGE_ALIGN(start); ++ aligned_start = PAGE_ALIGN(start); + +-#ifndef CONFIG_ARM_LPAE +- if (bank->start + size < bank->start) { ++#ifndef CONFIG_ARCH_PHYS_ADDR_T_64BIT ++ if (aligned_start > ULONG_MAX) { ++ printk(KERN_CRIT "Ignoring memory at 0x%08llx outside " ++ "32-bit physical address space\n", (long long)start); ++ return -EINVAL; ++ } ++ ++ if (aligned_start + size > ULONG_MAX) { + printk(KERN_CRIT "Truncating memory at 0x%08llx to fit in " + "32-bit physical address space\n", (long long)start); + /* +@@ -558,10 +565,11 @@ int __init arm_add_memory(u64 start, u64 size) + * 32 bits, we use ULONG_MAX as the upper limit rather than 4GB. + * This means we lose a page after masking. + */ +- size = ULONG_MAX - bank->start; ++ size = ULONG_MAX - aligned_start; + } + #endif + ++ bank->start = aligned_start; + bank->size = size & ~(phys_addr_t)(PAGE_SIZE - 1); + + /* +-- +1.8.5.rc3 + diff --git a/patches.renesas/0224-usb-renesas_usbhs-gadget-remove-extra-check-on-udc_s.patch b/patches.renesas/0224-usb-renesas_usbhs-gadget-remove-extra-check-on-udc_s.patch new file mode 100644 index 00000000000000..a4b95213b09516 --- /dev/null +++ b/patches.renesas/0224-usb-renesas_usbhs-gadget-remove-extra-check-on-udc_s.patch @@ -0,0 +1,39 @@ +From fa802a7504fa543f2ea9c379fd9cc8282bd3a950 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Mon, 8 Jul 2013 22:47:37 -0700 +Subject: usb: renesas_usbhs: gadget: remove extra check on udc_stop + +usb_gadget_ops :: udc_stop might be called with driver = NULL since +511f3c5326eabe1ece35202a404c24c0aeacc246 +(usb: gadget: udc-core: fix a regression during gadget driver unbinding) + +Because of that, 2nd times insmod goes fail. +This patch fixes it up. + +Reported-by: Yusuke Goda <yusuke.goda.sx@renesas.com> +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Felipe Balbi <balbi@ti.com> +(cherry picked from commit 8047806e64ea7b33fcede5b93f7276568a6119e8) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/usb/renesas_usbhs/mod_gadget.c | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c +index ed4949faa70d..805940c37353 100644 +--- a/drivers/usb/renesas_usbhs/mod_gadget.c ++++ b/drivers/usb/renesas_usbhs/mod_gadget.c +@@ -855,10 +855,6 @@ static int usbhsg_gadget_stop(struct usb_gadget *gadget, + struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); + struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); + +- if (!driver || +- !driver->unbind) +- return -EINVAL; +- + usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); + gpriv->driver = NULL; + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0225-usb-renesas_usbhs-tidyup-original-usbhsx_for_each_xx.patch b/patches.renesas/0225-usb-renesas_usbhs-tidyup-original-usbhsx_for_each_xx.patch new file mode 100644 index 00000000000000..1d262fa2fd86d4 --- /dev/null +++ b/patches.renesas/0225-usb-renesas_usbhs-tidyup-original-usbhsx_for_each_xx.patch @@ -0,0 +1,77 @@ +From 75873b83413b95a2de7e6362323dacdd062630f7 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Thu, 11 Jul 2013 22:32:31 -0700 +Subject: usb: renesas_usbhs: tidyup original usbhsx_for_each_xxx macro + +Current usbhsx_for_each_xxx macro will read out-of-array's +memory after last loop operation. +It was not good C language operation, and the binary which was +compiled by (at least) gcc 4.8.1 is broken +This patch tidyup these issues + +Reported-by: Yusuke Goda <yusuke.goda.sx@renesas.com> +Reviewed-by: Takashi Yoshii <takashi.yoshii.zj@renesas.com> +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Felipe Balbi <balbi@ti.com> +(cherry picked from commit 925403f425a4a9c503f2fc295652647b1eb10d82) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/usb/renesas_usbhs/mod_gadget.c | 6 +++--- + drivers/usb/renesas_usbhs/mod_host.c | 6 +++--- + drivers/usb/renesas_usbhs/pipe.h | 6 +++--- + 3 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c +index 805940c37353..3385aeb5a364 100644 +--- a/drivers/usb/renesas_usbhs/mod_gadget.c ++++ b/drivers/usb/renesas_usbhs/mod_gadget.c +@@ -77,9 +77,9 @@ struct usbhsg_recip_handle { + struct usbhsg_gpriv, mod) + + #define __usbhsg_for_each_uep(start, pos, g, i) \ +- for (i = start, pos = (g)->uep + i; \ +- i < (g)->uep_size; \ +- i++, pos = (g)->uep + i) ++ for ((i) = start; \ ++ ((i) < (g)->uep_size) && ((pos) = (g)->uep + (i)); \ ++ (i)++) + + #define usbhsg_for_each_uep(pos, gpriv, i) \ + __usbhsg_for_each_uep(1, pos, gpriv, i) +diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c +index b86815421c8d..e40f565004d0 100644 +--- a/drivers/usb/renesas_usbhs/mod_host.c ++++ b/drivers/usb/renesas_usbhs/mod_host.c +@@ -111,9 +111,9 @@ static const char usbhsh_hcd_name[] = "renesas_usbhs host"; + container_of(usbhs_mod_get(priv, USBHS_HOST), struct usbhsh_hpriv, mod) + + #define __usbhsh_for_each_udev(start, pos, h, i) \ +- for (i = start, pos = (h)->udev + i; \ +- i < USBHSH_DEVICE_MAX; \ +- i++, pos = (h)->udev + i) ++ for ((i) = start; \ ++ ((i) < USBHSH_DEVICE_MAX) && ((pos) = (h)->udev + (i)); \ ++ (i)++) + + #define usbhsh_for_each_udev(pos, hpriv, i) \ + __usbhsh_for_each_udev(1, pos, hpriv, i) +diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h +index b476fde955bf..3e5349879838 100644 +--- a/drivers/usb/renesas_usbhs/pipe.h ++++ b/drivers/usb/renesas_usbhs/pipe.h +@@ -54,9 +54,9 @@ struct usbhs_pipe_info { + * pipe list + */ + #define __usbhs_for_each_pipe(start, pos, info, i) \ +- for (i = start, pos = (info)->pipe + i; \ +- i < (info)->size; \ +- i++, pos = (info)->pipe + i) ++ for ((i) = start; \ ++ ((i) < (info)->size) && ((pos) = (info)->pipe + (i)); \ ++ (i)++) + + #define usbhs_for_each_pipe(pos, priv, i) \ + __usbhs_for_each_pipe(1, pos, &((priv)->pipe_info), i) +-- +1.8.5.rc3 + diff --git a/patches.renesas/0226-usb-renesas-use-dev_get_platdata.patch b/patches.renesas/0226-usb-renesas-use-dev_get_platdata.patch new file mode 100644 index 00000000000000..bf2e1131a1f1c2 --- /dev/null +++ b/patches.renesas/0226-usb-renesas-use-dev_get_platdata.patch @@ -0,0 +1,41 @@ +From f3b4d407b140634d39c1a3b42aeb89364dc887b8 Mon Sep 17 00:00:00 2001 +From: Jingoo Han <jg1.han@samsung.com> +Date: Tue, 30 Jul 2013 17:06:20 +0900 +Subject: usb: renesas: use dev_get_platdata() + +Use the wrapper function for retrieving the platform data instead of +accessing dev->platform_data directly. + +Signed-off-by: Jingoo Han <jg1.han@samsung.com> +Signed-off-by: Felipe Balbi <balbi@ti.com> +(cherry picked from commit f074245960e8fec9948eb8022322e43670ace4e5) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/usb/renesas_usbhs/common.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c +index cfd205036aba..3b39757c13bc 100644 +--- a/drivers/usb/renesas_usbhs/common.c ++++ b/drivers/usb/renesas_usbhs/common.c +@@ -416,7 +416,7 @@ static int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev) + */ + static int usbhs_probe(struct platform_device *pdev) + { +- struct renesas_usbhs_platform_info *info = pdev->dev.platform_data; ++ struct renesas_usbhs_platform_info *info = dev_get_platdata(&pdev->dev); + struct renesas_usbhs_driver_callback *dfunc; + struct usbhs_priv *priv; + struct resource *res, *irq_res; +@@ -558,7 +558,7 @@ probe_end_pipe_exit: + static int usbhs_remove(struct platform_device *pdev) + { + struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); +- struct renesas_usbhs_platform_info *info = pdev->dev.platform_data; ++ struct renesas_usbhs_platform_info *info = dev_get_platdata(&pdev->dev); + struct renesas_usbhs_driver_callback *dfunc = &info->driver_callback; + + dev_dbg(&pdev->dev, "usb remove\n"); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0227-usb-renesas_usbhs-use-platform_-get-set-_drvdata.patch b/patches.renesas/0227-usb-renesas_usbhs-use-platform_-get-set-_drvdata.patch new file mode 100644 index 00000000000000..fa9871f6ef2fa6 --- /dev/null +++ b/patches.renesas/0227-usb-renesas_usbhs-use-platform_-get-set-_drvdata.patch @@ -0,0 +1,33 @@ +From 268239ab4b21ea131fcd62f7cbd01dfe8be1d737 Mon Sep 17 00:00:00 2001 +From: Libo Chen <clbchenlibo.chen@huawei.com> +Date: Tue, 27 Aug 2013 16:10:31 +0800 +Subject: usb: renesas_usbhs: use platform_{get,set}_drvdata() + +Use the wrapper functions for getting and setting the driver data using +platform_device instead of using dev_{get,set}_drvdata() with &pdev->dev, +so we can directly pass a struct platform_device. + +Signed-off-by: Libo Chen <libo.chen@huawei.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit c9a0552e8df596b7cc43cbcd161c065c0046744d) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/usb/renesas_usbhs/common.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c +index 3b39757c13bc..17267b0a2e95 100644 +--- a/drivers/usb/renesas_usbhs/common.c ++++ b/drivers/usb/renesas_usbhs/common.c +@@ -499,7 +499,7 @@ static int usbhs_probe(struct platform_device *pdev) + goto probe_end_fifo_exit; + + /* dev_set_drvdata should be called after usbhs_mod_init */ +- dev_set_drvdata(&pdev->dev, priv); ++ platform_set_drvdata(pdev, priv); + + /* + * deviece reset here because +-- +1.8.5.rc3 + diff --git a/patches.renesas/0228-serial8250-em-Convert-to-devm_-managed-helpers.patch b/patches.renesas/0228-serial8250-em-Convert-to-devm_-managed-helpers.patch new file mode 100644 index 00000000000000..32b9114c89c9c5 --- /dev/null +++ b/patches.renesas/0228-serial8250-em-Convert-to-devm_-managed-helpers.patch @@ -0,0 +1,87 @@ +From 001a8b986042a2a63217676ff59215e58fb18066 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Fri, 26 Jul 2013 16:22:02 +0200 +Subject: serial8250-em: Convert to devm_* managed helpers + +Replace kzalloc and clk_get by their managed counterparts to simplify +error and cleanup paths. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +(cherry picked from commit 299a62575a63b19add8206642b340f1b54ec4faf) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/tty/serial/8250/8250_em.c | 27 ++++++++------------------- + 1 file changed, 8 insertions(+), 19 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250_em.c b/drivers/tty/serial/8250/8250_em.c +index 916cc19fbbda..5f3bba12c159 100644 +--- a/drivers/tty/serial/8250/8250_em.c ++++ b/drivers/tty/serial/8250/8250_em.c +@@ -95,25 +95,23 @@ static int serial8250_em_probe(struct platform_device *pdev) + struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + struct serial8250_em_priv *priv; + struct uart_8250_port up; +- int ret = -EINVAL; ++ int ret; + + if (!regs || !irq) { + dev_err(&pdev->dev, "missing registers or irq\n"); +- goto err0; ++ return -EINVAL; + } + +- priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) { + dev_err(&pdev->dev, "unable to allocate private data\n"); +- ret = -ENOMEM; +- goto err0; ++ return -ENOMEM; + } + +- priv->sclk = clk_get(&pdev->dev, "sclk"); ++ priv->sclk = devm_clk_get(&pdev->dev, "sclk"); + if (IS_ERR(priv->sclk)) { + dev_err(&pdev->dev, "unable to get clock\n"); +- ret = PTR_ERR(priv->sclk); +- goto err1; ++ return PTR_ERR(priv->sclk); + } + + memset(&up, 0, sizeof(up)); +@@ -136,20 +134,13 @@ static int serial8250_em_probe(struct platform_device *pdev) + ret = serial8250_register_8250_port(&up); + if (ret < 0) { + dev_err(&pdev->dev, "unable to register 8250 port\n"); +- goto err2; ++ clk_disable(priv->sclk); ++ return ret; + } + + priv->line = ret; + platform_set_drvdata(pdev, priv); + return 0; +- +- err2: +- clk_disable(priv->sclk); +- clk_put(priv->sclk); +- err1: +- kfree(priv); +- err0: +- return ret; + } + + static int serial8250_em_remove(struct platform_device *pdev) +@@ -158,8 +149,6 @@ static int serial8250_em_remove(struct platform_device *pdev) + + serial8250_unregister_port(priv->line); + clk_disable(priv->sclk); +- clk_put(priv->sclk); +- kfree(priv); + return 0; + } + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0229-serial8250-em-convert-to-clk_prepare-unprepare.patch b/patches.renesas/0229-serial8250-em-convert-to-clk_prepare-unprepare.patch new file mode 100644 index 00000000000000..7c16989ac532e1 --- /dev/null +++ b/patches.renesas/0229-serial8250-em-convert-to-clk_prepare-unprepare.patch @@ -0,0 +1,57 @@ +From 1535c7a3b0fb7e70eb8a940402b650b7b346b577 Mon Sep 17 00:00:00 2001 +From: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com> +Date: Tue, 8 Oct 2013 13:24:28 +0900 +Subject: serial8250-em: convert to clk_prepare/unprepare + +Add calls to clk_prepare and unprepare so that EMMA Mobile EV2 can +migrate to the common clock framework. + +Signed-off-by: Shinya Kuribayashi <shinya.kuribayashi.px@renesas.com> +[takashi.yoshii.ze@renesas.com: edited for conflicts] +Signed-off-by: Takashi Yoshii <takashi.yoshii.zj@renesas.com> +Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Acked-by: Magnus Damm <damm@opensource.se> +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> + +(cherry picked from commit 12082ba2cb053e547dd3faef7af4842f2abe7c19) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/tty/serial/8250/8250_em.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/tty/serial/8250/8250_em.c b/drivers/tty/serial/8250/8250_em.c +index 5f3bba12c159..d1a9078003bd 100644 +--- a/drivers/tty/serial/8250/8250_em.c ++++ b/drivers/tty/serial/8250/8250_em.c +@@ -122,7 +122,7 @@ static int serial8250_em_probe(struct platform_device *pdev) + up.port.dev = &pdev->dev; + up.port.private_data = priv; + +- clk_enable(priv->sclk); ++ clk_prepare_enable(priv->sclk); + up.port.uartclk = clk_get_rate(priv->sclk); + + up.port.iotype = UPIO_MEM32; +@@ -134,7 +134,7 @@ static int serial8250_em_probe(struct platform_device *pdev) + ret = serial8250_register_8250_port(&up); + if (ret < 0) { + dev_err(&pdev->dev, "unable to register 8250 port\n"); +- clk_disable(priv->sclk); ++ clk_disable_unprepare(priv->sclk); + return ret; + } + +@@ -148,7 +148,7 @@ static int serial8250_em_remove(struct platform_device *pdev) + struct serial8250_em_priv *priv = platform_get_drvdata(pdev); + + serial8250_unregister_port(priv->line); +- clk_disable(priv->sclk); ++ clk_disable_unprepare(priv->sclk); + return 0; + } + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0230-clocksource-sh_mtu2-Release-clock-when-sh_mtu2_regis.patch b/patches.renesas/0230-clocksource-sh_mtu2-Release-clock-when-sh_mtu2_regis.patch new file mode 100644 index 00000000000000..24410d9f784186 --- /dev/null +++ b/patches.renesas/0230-clocksource-sh_mtu2-Release-clock-when-sh_mtu2_regis.patch @@ -0,0 +1,44 @@ +From 73ba8c1d897a1b0267d7a092f665fb1e40650710 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Fri, 8 Nov 2013 11:07:59 +0100 +Subject: clocksource: sh_mtu2: Release clock when sh_mtu2_register() fails + +Fix the probe error path to release the clock resource when the +sh_mtu2_register() call fails. + +Cc: Daniel Lezcano <daniel.lezcano@linaro.org> +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Simon Horman <horms+renesas@verge.net.au> +Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> +(cherry picked from commit a4a5fc3b64cd553820d97667056506636eaaba77) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/clocksource/sh_mtu2.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c +index 4aac9ee0d0c0..e6cfb328eb2e 100644 +--- a/drivers/clocksource/sh_mtu2.c ++++ b/drivers/clocksource/sh_mtu2.c +@@ -313,8 +313,15 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev) + goto err1; + } + +- return sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev), +- cfg->clockevent_rating); ++ ret = sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev), ++ cfg->clockevent_rating); ++ if (ret < 0) ++ goto err2; ++ ++ return 0; ++ ++ err2: ++ clk_put(p->clk); + err1: + iounmap(p->mapbase); + err0: +-- +1.8.5.rc3 + diff --git a/patches.renesas/0231-clocksource-sh_mtu2-Add-clk_prepare-unprepare-suppor.patch b/patches.renesas/0231-clocksource-sh_mtu2-Add-clk_prepare-unprepare-suppor.patch new file mode 100644 index 00000000000000..aa4167bbb79c2c --- /dev/null +++ b/patches.renesas/0231-clocksource-sh_mtu2-Add-clk_prepare-unprepare-suppor.patch @@ -0,0 +1,47 @@ +From 6369c3db741997997df57df42e093d59f9a2b96b Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Fri, 8 Nov 2013 11:07:59 +0100 +Subject: clocksource: sh_mtu2: Add clk_prepare/unprepare support + +Prepare the clock at probe time, as there is no other appropriate place +in the driver where we're allowed to sleep. + +Cc: Daniel Lezcano <daniel.lezcano@linaro.org> +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Simon Horman <horms+renesas@verge.net.au> +Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> +(cherry picked from commit bd7549308eed47b3750b3dab692034a553e75663) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/clocksource/sh_mtu2.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c +index e6cfb328eb2e..3cf12834681e 100644 +--- a/drivers/clocksource/sh_mtu2.c ++++ b/drivers/clocksource/sh_mtu2.c +@@ -313,13 +313,18 @@ static int sh_mtu2_setup(struct sh_mtu2_priv *p, struct platform_device *pdev) + goto err1; + } + ++ ret = clk_prepare(p->clk); ++ if (ret < 0) ++ goto err2; ++ + ret = sh_mtu2_register(p, (char *)dev_name(&p->pdev->dev), + cfg->clockevent_rating); + if (ret < 0) +- goto err2; ++ goto err3; + + return 0; +- ++ err3: ++ clk_unprepare(p->clk); + err2: + clk_put(p->clk); + err1: +-- +1.8.5.rc3 + diff --git a/patches.renesas/0232-sh-pfc-r8a7740-Fix-pin-bias-setup.patch b/patches.renesas/0232-sh-pfc-r8a7740-Fix-pin-bias-setup.patch new file mode 100644 index 00000000000000..8b07a2b841ff9c --- /dev/null +++ b/patches.renesas/0232-sh-pfc-r8a7740-Fix-pin-bias-setup.patch @@ -0,0 +1,33 @@ +From eae03881e8c5090760e84e87bccf634620842ee9 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 28 Nov 2013 16:20:03 +0100 +Subject: sh-pfc: r8a7740: Fix pin bias setup + +When computing the pin configuration register offset the bias setup code +erroneously compares the pin number range with the loop index instead of +the pin number. Fix it. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +(cherry picked from commit 5d27619498ab468e8c7e67844c640ad0915e8d85) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/pinctrl/sh-pfc/pfc-r8a7740.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +index 009174d07767..bc5eb453a45c 100644 +--- a/drivers/pinctrl/sh-pfc/pfc-r8a7740.c ++++ b/drivers/pinctrl/sh-pfc/pfc-r8a7740.c +@@ -3720,7 +3720,7 @@ static void __iomem *r8a7740_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin) + const struct r8a7740_portcr_group *group = + &r8a7740_portcr_offsets[i]; + +- if (i <= group->end_pin) ++ if (pin <= group->end_pin) + return pfc->window->virt + group->offset + pin; + } + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0233-sh-pfc-sh7372-Fix-pin-bias-setup.patch b/patches.renesas/0233-sh-pfc-sh7372-Fix-pin-bias-setup.patch new file mode 100644 index 00000000000000..92e9e150c3bfcb --- /dev/null +++ b/patches.renesas/0233-sh-pfc-sh7372-Fix-pin-bias-setup.patch @@ -0,0 +1,33 @@ +From a824067d352753324e96d0bed2a81a542e87df14 Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Thu, 28 Nov 2013 16:20:04 +0100 +Subject: sh-pfc: sh7372: Fix pin bias setup + +When computing the pin configuration register offset the bias setup code +erroneously compares the pin number range with the loop index instead of +the pin number. Fix it. + +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +(cherry picked from commit 71493de7e55af589dbe76ce78ae2b762f9cc6f27) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/pinctrl/sh-pfc/pfc-sh7372.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/sh-pfc/pfc-sh7372.c b/drivers/pinctrl/sh-pfc/pfc-sh7372.c +index 70b522d34821..cc097b693820 100644 +--- a/drivers/pinctrl/sh-pfc/pfc-sh7372.c ++++ b/drivers/pinctrl/sh-pfc/pfc-sh7372.c +@@ -2584,7 +2584,7 @@ static void __iomem *sh7372_pinmux_portcr(struct sh_pfc *pfc, unsigned int pin) + const struct sh7372_portcr_group *group = + &sh7372_portcr_offsets[i]; + +- if (i <= group->end_pin) ++ if (pin <= group->end_pin) + return pfc->window->virt + group->offset + pin; + } + +-- +1.8.5.rc3 + diff --git a/patches.renesas/0234-clocksource-sh_tmu-Release-clock-when-sh_tmu_registe.patch b/patches.renesas/0234-clocksource-sh_tmu-Release-clock-when-sh_tmu_registe.patch new file mode 100644 index 00000000000000..87fdf2eb587b20 --- /dev/null +++ b/patches.renesas/0234-clocksource-sh_tmu-Release-clock-when-sh_tmu_registe.patch @@ -0,0 +1,46 @@ +From de5cdaf59e2f36c645321481f86070ebfa93338c Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Fri, 8 Nov 2013 11:07:59 +0100 +Subject: clocksource: sh_tmu: Release clock when sh_tmu_register() fails + +Fix the probe error path to release the clock resource when the +sh_tmu_register() call fails. + +Cc: Daniel Lezcano <daniel.lezcano@linaro.org> +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Simon Horman <horms+renesas@verge.net.au> +Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> +(cherry picked from commit 394a4486f009a184b58fc2f2435d6f5f800870bb) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/clocksource/sh_tmu.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c +index 78b8dae49628..15978372c937 100644 +--- a/drivers/clocksource/sh_tmu.c ++++ b/drivers/clocksource/sh_tmu.c +@@ -475,9 +475,16 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev) + p->cs_enabled = false; + p->enable_count = 0; + +- return sh_tmu_register(p, (char *)dev_name(&p->pdev->dev), +- cfg->clockevent_rating, +- cfg->clocksource_rating); ++ ret = sh_tmu_register(p, (char *)dev_name(&p->pdev->dev), ++ cfg->clockevent_rating, ++ cfg->clocksource_rating); ++ if (ret < 0) ++ goto err2; ++ ++ return 0; ++ ++ err2: ++ clk_put(p->clk); + err1: + iounmap(p->mapbase); + err0: +-- +1.8.5.rc3 + diff --git a/patches.renesas/0235-clocksource-sh_tmu-Add-clk_prepare-unprepare-support.patch b/patches.renesas/0235-clocksource-sh_tmu-Add-clk_prepare-unprepare-support.patch new file mode 100644 index 00000000000000..6ef1edb436c971 --- /dev/null +++ b/patches.renesas/0235-clocksource-sh_tmu-Add-clk_prepare-unprepare-support.patch @@ -0,0 +1,52 @@ +From 1f363ca74418dcabd44f58e503fa9b6935c40b3b Mon Sep 17 00:00:00 2001 +From: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Date: Fri, 8 Nov 2013 11:08:00 +0100 +Subject: clocksource: sh_tmu: Add clk_prepare/unprepare support + +Prepare the clock at probe time, as there is no other appropriate place +in the driver where we're allowed to sleep. + +Cc: Daniel Lezcano <daniel.lezcano@linaro.org> +Cc: linux-kernel@vger.kernel.org +Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@ideasonboard.com> +Acked-by: Simon Horman <horms+renesas@verge.net.au> +Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> +(cherry picked from commit 1c09eb3e2d761ffd152faa6b9d06caf560e7d445) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/clocksource/sh_tmu.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c +index 15978372c937..63557cda0a7d 100644 +--- a/drivers/clocksource/sh_tmu.c ++++ b/drivers/clocksource/sh_tmu.c +@@ -472,6 +472,11 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev) + ret = PTR_ERR(p->clk); + goto err1; + } ++ ++ ret = clk_prepare(p->clk); ++ if (ret < 0) ++ goto err2; ++ + p->cs_enabled = false; + p->enable_count = 0; + +@@ -479,10 +484,12 @@ static int sh_tmu_setup(struct sh_tmu_priv *p, struct platform_device *pdev) + cfg->clockevent_rating, + cfg->clocksource_rating); + if (ret < 0) +- goto err2; ++ goto err3; + + return 0; + ++ err3: ++ clk_unprepare(p->clk); + err2: + clk_put(p->clk); + err1: +-- +1.8.5.rc3 + diff --git a/patches.renesas/0236-irqchip-Gic-fix-boot-for-chained-gics.patch b/patches.renesas/0236-irqchip-Gic-fix-boot-for-chained-gics.patch new file mode 100644 index 00000000000000..ecce6833bab7b6 --- /dev/null +++ b/patches.renesas/0236-irqchip-Gic-fix-boot-for-chained-gics.patch @@ -0,0 +1,55 @@ +From d93f0df4c0b19c686887d865a71f8380d90b3bbf Mon Sep 17 00:00:00 2001 +From: Mark Rutland <mark.rutland@arm.com> +Date: Thu, 28 Nov 2013 14:21:40 +0000 +Subject: irqchip: Gic: fix boot for chained gics + +As of c0114709ed: "irqchip: gic: Perform the gic_secondary_init() call +via CPU notifier", booting on a platform with chained gics (e.g. +Realview EB ARM11MPCore) will result in the gic_cpu_notifier being +registered twice, corrupting the cpu notifier list and rendering the +platform unbootable. + +This patch ensures that we only register the notifier for the first +gic, allowing platforms with chained gics to boot. At the same time we +limit the pointlessly duplicated calls to set_smp_cross_call and +set_handle_irq to the first gic registered. + +Signed-off-by: Mark Rutland <mark.rutland@arm.com> +Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> +Cc: linux-arm-kernel@lists.infradead.org +Cc: marc.zyngier@arm.com +Cc: rob.herring@calxeda.com +Cc: olof@lixom.net +Link: http://lkml.kernel.org/r/1385648500-29048-1-git-send-email-mark.rutland@arm.com +Signed-off-by: Thomas Gleixner <tglx@linutronix.de> +(cherry picked from commit 08332dff8adebb74171e98e008d6c20de6658c42) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + drivers/irqchip/irq-gic.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c +index 70e4a3080029..74e1ffe1cd3d 100644 +--- a/drivers/irqchip/irq-gic.c ++++ b/drivers/irqchip/irq-gic.c +@@ -936,12 +936,13 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start, + if (WARN_ON(!gic->domain)) + return; + ++ if (gic_nr == 0) { + #ifdef CONFIG_SMP +- set_smp_cross_call(gic_raise_softirq); +- register_cpu_notifier(&gic_cpu_notifier); ++ set_smp_cross_call(gic_raise_softirq); ++ register_cpu_notifier(&gic_cpu_notifier); + #endif +- +- set_handle_irq(gic_handle_irq); ++ set_handle_irq(gic_handle_irq); ++ } + + gic_chip.flags |= gic_arch_extn.flags; + gic_dist_init(gic); +-- +1.8.5.rc3 + diff --git a/patches.renesas/0237-ASoC-rcar-select-REGMAP.patch b/patches.renesas/0237-ASoC-rcar-select-REGMAP.patch new file mode 100644 index 00000000000000..4c87ad1bc034c3 --- /dev/null +++ b/patches.renesas/0237-ASoC-rcar-select-REGMAP.patch @@ -0,0 +1,33 @@ +From a559c32f42ab2dc34dbb54937817b248ed5b6173 Mon Sep 17 00:00:00 2001 +From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Date: Thu, 7 Nov 2013 00:56:28 -0800 +Subject: ASoC: rcar: select REGMAP + +55e5b6fd5af04b6d8b0ac6635edf49476ff298ba +(ASoC: rsnd: use regmap instead of original register mapping method) +support regmap/regmap_field on Renesas sound driver. +It needs CONFIG_REGMAP now. + +Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> +Signed-off-by: Mark Brown <broonie@linaro.org> +(cherry picked from commit 0fb50e5539c1525939b89c1813b60cc72f90a3e1) +Signed-off-by: Simon Horman <horms+renesas@verge.net.au> +--- + sound/soc/sh/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig +index 14011d90d70a..ff60e11ecb56 100644 +--- a/sound/soc/sh/Kconfig ++++ b/sound/soc/sh/Kconfig +@@ -37,6 +37,7 @@ config SND_SOC_SH4_SIU + config SND_SOC_RCAR + tristate "R-Car series SRU/SCU/SSIU/SSI support" + select SND_SIMPLE_CARD ++ select REGMAP + help + This option enables R-Car SUR/SCU/SSIU/SSI sound support + +-- +1.8.5.rc3 + @@ -644,6 +644,242 @@ patches.renesas/0593-mmc-SDHI-add-DT-compatibility-strings-for-further-So.patch patches.renesas/0594-Revert-mmc-tmio-mmc-Remove-.set_pwr-callback-from-pl.patch patches.renesas/0595-ARM-shmobile-update-SDHI-DT-compatibility-string-to-.patch +patches.renesas/0001-ASoC-ak4642-Remove-redundant-break.patch +patches.renesas/0003-gpio-use-dev_get_platdata.patch +patches.renesas/0004-gpio-em-Add-pinctrl-support.patch +patches.renesas/0005-drm-gem-Split-drm_gem_mmap-into-object-search-and-ob.patch +patches.renesas/0006-drm-GEM-CMA-Split-object-creation-into-object-alloc-.patch +patches.renesas/0007-drm-GEM-CMA-Split-object-mapping-into-GEM-mapping-an.patch +patches.renesas/0008-drm-GEM-CMA-Add-DRM-PRIME-support.patch +patches.renesas/0009-drm-Renesas-R-Car-Display-Unit-DRM-driver.patch +patches.renesas/0010-drm-rcar-du-Don-t-ignore-rcar_du_crtc_create-return-.patch +patches.renesas/0011-drm-rcar-du-Fix-buffer-pitch-alignment.patch +patches.renesas/0012-drm-rcar-du-Add-missing-alpha-plane-register-definit.patch +patches.renesas/0013-drm-rcar-du-Use-devm_ioremap_resource.patch +patches.renesas/0014-drm-rcar-du-Add-platform-module-device-table.patch +patches.renesas/0015-drm-rcar-du-Support-per-CRTC-clock-and-IRQ.patch +patches.renesas/0016-drm-rcar-du-Clarify-comment-regarding-plane-Y-source.patch +patches.renesas/0017-drm-rcar-du-Split-LVDS-encoder-and-connector.patch +patches.renesas/0018-drm-rcar-du-Split-VGA-encoder-and-connector.patch +patches.renesas/0019-drm-rcar-du-Merge-LVDS-and-VGA-encoder-code.patch +patches.renesas/0020-drm-rcar-du-Rename-platform-data-fields-to-match-wha.patch +patches.renesas/0021-drm-rcar-du-Create-rcar_du_planes-structure.patch +patches.renesas/0022-drm-rcar-du-Rename-rcar_du_plane_-init-register-to-r.patch +patches.renesas/0023-drm-rcar-du-Introduce-CRTCs-groups.patch +patches.renesas/0024-drm-rcar-du-Use-dynamic-number-of-CRTCs-instead-of-C.patch +patches.renesas/0025-drm-rcar-du-Remove-register-definitions-for-the-seco.patch +patches.renesas/0026-drm-rcar-du-Move-output-routing-configuration-to-gro.patch +patches.renesas/0027-drm-rcar-du-Add-support-for-the-R8A7790-DU.patch +patches.renesas/0028-drm-rcar-du-Fix-buffer-pitch-alignment-for-R8A7790-D.patch +patches.renesas/0029-drm-rcar-du-Add-support-for-multiple-groups.patch +patches.renesas/0030-drm-rcar-du-Add-support-for-DEFR8-register.patch +patches.renesas/0031-drm-rcar-du-Rework-output-routing-support.patch +patches.renesas/0032-drm-rcar-du-Configure-RGB-output-routing-to-DPAD0.patch +patches.renesas/0033-drm-rcar-du-Add-internal-LVDS-encoder-support.patch +patches.renesas/0034-drm-rcar-du-Add-FBDEV-emulation-support.patch +patches.renesas/0035-media-v4l-Add-media-format-codes-for-ARGB8888-and-AY.patch +patches.renesas/0036-media-v4l-Add-V4L2_PIX_FMT_NV16M-and-V4L2_PIX_FMT_NV.patch +patches.renesas/0037-media-v4l-Renesas-R-Car-VSP1-driver.patch +patches.renesas/0038-media-vsp1-Fix-lack-of-the-sink-entity-registration-.patch +patches.renesas/0039-media-vsp1-Use-the-maximum-number-of-entities-define.patch +patches.renesas/0040-media-vsp1-Fix-a-sparse-warning.patch +patches.renesas/0041-media-v4l-vsp1-Initialize-media-device-bus_info-fiel.patch +patches.renesas/0042-media-v4l-vsp1-Add-support-for-RT-clock.patch +patches.renesas/0043-media-v4l-vsp1-Fix-mutex-double-lock-at-streamon-tim.patch +patches.renesas/0044-dma-add-driver-for-R-Car-HPB-DMAC.patch +patches.renesas/0045-rcar-hpbdma-remove-shdma_free_irq-calls.patch +patches.renesas/0046-rcar-hpbdma-add-parameter-to-set_slave-method.patch +patches.renesas/0047-DMA-shdma-cosmetic-don-t-re-calculate-a-pointer.patch +patches.renesas/0048-DMA-shdma-add-DT-support.patch +patches.renesas/0049-dma-use-dev_get_platdata.patch +patches.renesas/0050-DMA-shdma-fix-CHCLR-register-address-calculation.patch +patches.renesas/0051-DMA-shdma-switch-all-__iomem-pointers-to-void.patch +patches.renesas/0052-DMA-shdma-support-the-new-CHCLR-register-layout.patch +patches.renesas/0053-DMA-shdma-switch-to-managed-resource-allocation.patch +patches.renesas/0054-DMA-shdma-make-a-pointer-const.patch +patches.renesas/0055-DMA-shdma-switch-DT-mode-to-use-configuration-data-f.patch +patches.renesas/0056-DMA-shdma-remove-private-and-unused-defines-from-a-g.patch +patches.renesas/0057-DMA-shdma-add-a-header-with-common-for-ARM-SoCs-defi.patch +patches.renesas/0058-DMA-shdma-add-r8a73a4-DMAC-data-to-the-device-ID-tab.patch +patches.renesas/0059-ARM-elf-add-new-hwcap-for-identifying-atomic-ldrd-st.patch +patches.renesas/0060-ARM-ARM64-arch_timer-add-macros-for-bits-in-control-.patch +patches.renesas/0061-sh_eth-add-use-RMCR.RNC-bit.patch +patches.renesas/0062-sh_eth-check-platform-data-pointer.patch +patches.renesas/0063-gpio-rcar-drop-references-to-virtual-IRQ.patch +patches.renesas/0064-gpio-rcar-Include-linux-of.h-header.patch +patches.renesas/0065-i2c-sh_mobile-Convert-to-clk_prepare-unprepare.patch +patches.renesas/0066-i2c-rcar-cosmetic-remove-superfluous-parenthesis.patch +patches.renesas/0067-i2c-rcar-get-clock-rate-only-once-and-simplify-calcu.patch +patches.renesas/0068-i2c-rcar-add-Device-Tree-support.patch +patches.renesas/0069-i2c-rcar-fix-clk_get-error-handling.patch +patches.renesas/0070-i2c-rcar-use-per-device-clock.patch +patches.renesas/0071-i2c-rcar-fixup-rcar-type-naming.patch +patches.renesas/0072-media-sh_mobile_ceu_camera-remove-deprecated-IRQF_DI.patch +patches.renesas/0073-media-media-rcar_vin-Add-preliminary-r8a7790-support.patch +patches.renesas/0074-media-platform-drivers-Fix-build-on-frv-arch.patch +patches.renesas/0075-mmc-sh_mmcif-Move-away-from-using-deprecated-APIs.patch +patches.renesas/0076-mmc-sh_mmcif-Convert-to-PM-macros-when-defining-dev_.patch +patches.renesas/0077-mmc-sh_mmcif-Convert-to-clk_prepare-unprepare.patch +patches.renesas/0078-mmc-tmio-Move-away-from-using-deprecated-APIs.patch +patches.renesas/0079-sh-pfc-r8a7778-Add-SRU-SSI-pin-support.patch +patches.renesas/0080-sh-pfc-r8a7790-Add-I2C-pin-groups-and-functions.patch +patches.renesas/0081-sh-pfc-r8a7790-add-pin-definitions-for-the-I2C3-inte.patch +patches.renesas/0082-sh-pfc-r8a7778-Add-CAN-pin-groups.patch +patches.renesas/0083-pinctrl-sh-pfc-r8a7791-PFC-support.patch +patches.renesas/0084-sata_rcar-Convert-to-clk_prepare-unprepare.patch +patches.renesas/0085-ARM-gic-add-CPU-migration-support.patch +patches.renesas/0086-ARM-GIC-function-to-retrieve-the-physical-address-of.patch +patches.renesas/0087-ARM-GIC-interface-to-send-a-SGI-directly.patch +patches.renesas/0088-ARM-arch_timer-add-support-to-configure-and-enable-e.patch +patches.renesas/0089-ASoC-add-Renesas-R-Car-module-feature.patch +patches.renesas/0090-ASoC-add-Renesas-R-Car-Generation-feature.patch +patches.renesas/0091-ASoC-add-Renesas-R-Car-SCU-feature.patch +patches.renesas/0092-ASoC-add-Renesas-R-Car-ADG-feature.patch +patches.renesas/0093-ASoC-add-Renesas-R-Car-SSI-feature.patch +patches.renesas/0094-ASoC-rcar-fix-return-value-check-in-rsnd_gen1_probe.patch +patches.renesas/0095-ASoC-rsnd-remove-platform-dai-and-add-dai_id-on-plat.patch +patches.renesas/0096-ASoC-rsnd-add-common-DMAEngine-method.patch +patches.renesas/0097-ASoC-rsnd-SSI-supports-DMA-transfer.patch +patches.renesas/0098-ASoC-rsnd-SSI-supports-DMA-transfer-via-BUSIF.patch +patches.renesas/0099-ASoC-rsnd-gen-rsnd_gen_ops-cares-.probe-and-.remove.patch +patches.renesas/0100-ASoC-rsnd-scu-cleanup-empty-functions.patch +patches.renesas/0101-ASoC-rcar-remove-unnecessary-mach-clock.h.patch +patches.renesas/0102-ASoC-rsnd-fixup-flag-name-of-rsnd_scu_platform_info.patch +patches.renesas/0103-ASoC-rsnd-remove-rsnd_priv_read-write-bset.patch +patches.renesas/0104-ASoC-rcar-fixup-generation-checker.patch +patches.renesas/0105-ASoC-rcar-fixup-rsnd_platform_call-return-value.patch +patches.renesas/0106-ASoC-rcar-add-ID-check-on-rsnd_dai_get.patch +patches.renesas/0107-ASoC-rcar-add-rsnd_scu_hpbif_is_enable.patch +patches.renesas/0108-ASoC-rcar-remove-RSND_SSI_CLK_FROM_ADG.patch +patches.renesas/0109-ASoC-rcar-remove-original-filter-from-rsnd_dma_init.patch +patches.renesas/0110-ASoC-rcar-remove-un-needed-select-from-Kconfig.patch +patches.renesas/0111-ASoC-rcar-Use-WARN_ON-instead-of-BUG_ON.patch +patches.renesas/0112-ASoC-rcar-fixup-mod-access-before-checking.patch +patches.renesas/0113-ASoC-rcar-off-by-one-in-rsnd_scu_set_route.patch +patches.renesas/0114-ASoC-rcar-fixup-dma_async_issue_pending-timing.patch +patches.renesas/0115-pwm-backlight-Add-optional-enable-GPIO.patch +patches.renesas/0116-pwm-Add-PWM-polarity-flag-macro-for-DT.patch +patches.renesas/0117-ARM-shmobile-Rename-to-r8a73a4_init_early.patch +patches.renesas/0118-ARM-shmobile-Rename-to-r8a7790_init_early.patch +patches.renesas/0119-ARM-shmobile-r8a7790-Constify-platform-data-and-reso.patch +patches.renesas/0120-ARM-shmobile-ape6evm-reference-add-MMCIF-and-SDHI-DT.patch +patches.renesas/0121-ARM-shmobile-r8a7779-Rename-DU-device-in-clock-looku.patch +patches.renesas/0122-ARM-shmobile-r8a7790-Add-DU-and-LVDS-clocks.patch +patches.renesas/0123-ARM-shmobile-r8a7778-add-SSI-SRU-clock-support.patch +patches.renesas/0124-ARM-shmobile-marzen-Select-DRM_RCAR_DU-in-defconfig.patch +patches.renesas/0125-ARM-shmobile-lager-Select-DRM_RCAR_DU-in-defconfig.patch +patches.renesas/0126-ARM-shmobile-bockw-defconfig-add-Sound-support.patch +patches.renesas/0127-ARM-shmobile-Add-koelsch-defconfig.patch +patches.renesas/0128-ARM-shmobile-Introduce-shmobile_smp_cpu_disable.patch +patches.renesas/0129-ARM-shmobile-Use-shmobile_smp_cpu_disable-on-sh73a0.patch +patches.renesas/0130-ARM-shmobile-Remove-unused-shmobile_smp_init_cpus.patch +patches.renesas/0131-ARM-shmobile-Expose-shmobile_invalidate_start.patch +patches.renesas/0132-ARM-shmobile-Introduce-shmobile_boot_size.patch +patches.renesas/0133-ARM-shmobile-r8a7778-cleanup-registration-of-vin.patch +patches.renesas/0134-ARM-shmobile-r8a7778-cleanup-registration-of-sh_eth.patch +patches.renesas/0135-ARM-shmobile-r8a7778-r8a7778_register_hspi-become-st.patch +patches.renesas/0136-ARM-shmobile-Add-r8a7790-CA15-CPU-cores.patch +patches.renesas/0137-ARM-shmobile-Add-r8a7790-CA7-CPU-cores-to-DTSI.patch +patches.renesas/0138-ARM-shmobile-Initial-r8a7791-SoC-support.patch +patches.renesas/0139-ARM-shmobile-r8a7791-SCIF-support.patch +patches.renesas/0140-ARM-shmobile-r8a7791-CMT-support.patch +patches.renesas/0141-ARM-shmobile-r8a7778-add-USBHS-clock.patch +patches.renesas/0142-ARM-shmobile-r8a7778-add-usb-phy-power-control-funct.patch +patches.renesas/0143-ARM-shmobile-marzen-Add-Display-Unit-support.patch +patches.renesas/0144-ARM-shmobile-lager-Constify-platform-data-and-resour.patch +patches.renesas/0145-ARM-shmobile-lager-Add-Display-Unit-support.patch +patches.renesas/0146-ARM-shmobile-ape6evm-update-MMC0-SDHI0-and-SDHI1-wit.patch +patches.renesas/0147-ARM-shmobile-lager-Fix-Display-Unit-platform-data.patch +patches.renesas/0148-ARM-shmobile-bockw-enable-global-use-of-FPGA.patch +patches.renesas/0149-ARM-shmobile-bockw-add-R-Car-sound-support-PIO.patch +patches.renesas/0150-ARM-shmobile-Koelsch-support.patch +patches.renesas/0151-ARM-shmobile-bockw-add-USB-Function-support.patch +patches.renesas/0152-ARM-shmobile-ape6evm-disable-MMCIF-Command-Completio.patch +patches.renesas/0153-ARM-shmobile-armadillo800eva-disable-MMCIF-Command-C.patch +patches.renesas/0154-ARM-shmobile-kzm9g-disable-MMCIF-Command-Completion-.patch +patches.renesas/0155-ARM-shmobile-lager-disable-MMCIF-Command-Completion-.patch +patches.renesas/0156-ARM-shmobile-Shared-APMU-SMP-support-code-without-DT.patch +patches.renesas/0157-ARM-shmobile-Add-r8a7790-SMP-support-using-APMU-code.patch +patches.renesas/0158-ARM-shmobile-Add-CPU-notifier-based-SCU-boot-vector-.patch +patches.renesas/0159-ARM-shmobile-Let-sh73a0-rely-on-SCU-CPU-notifier.patch +patches.renesas/0160-ARM-shmobile-Let-EMEV2-rely-on-SCU-CPU-notifier.patch +patches.renesas/0161-ARM-shmobile-Let-r8a7779-rely-on-SCU-CPU-notifier.patch +patches.renesas/0162-ARM-shmobile-Remove-shmobile_smp_scu_boot_secondary.patch +patches.renesas/0163-ARM-shmobile-Extend-APMU-code-to-allow-single-cluste.patch +patches.renesas/0164-ARM-shmobile-Include-CA7-cores-in-APMU-table.patch +patches.renesas/0165-ARM-shmobile-ape6evm-fix-incorrect-placement-of-__in.patch +patches.renesas/0166-ARM-shmobile-only-enable-used-I2C-interfaces-in-DT-o.patch +patches.renesas/0167-ARM-shmobile-r8a7790-add-I2C-DT-nodes.patch +patches.renesas/0168-ARM-shmobile-r8a73a4-add-a-DT-node-for-the-DMAC.patch +patches.renesas/0169-ARM-shmobile-armadillo-reference-Add-PWM-backlight-n.patch +patches.renesas/0170-ARM-shmobile-armadillo800eva-reference-add-SDHI-and-.patch +patches.renesas/0171-ARM-shmobile-r8a7791-IRQC-device-tree-node.patch +patches.renesas/0172-ARM-shmobile-r8a7791-Arch-timer-device-tree-node.patch +patches.renesas/0173-ARM-shmobile-r8a7791-SMP-device-tree-node.patch +patches.renesas/0174-ARM-shmobile-r8a7778-add-renesas_intc_irqpin-support.patch +patches.renesas/0175-ARM-shmobile-bockw-add-SMSC-support-on-DTS.patch +patches.renesas/0176-ARM-shmobile-marzen-fixup-SMSC-IRQ-number-on-DTS.patch +patches.renesas/0177-ARM-shmobile-r8a7779-add-irqpin-default-status-on-DT.patch +patches.renesas/0178-ARM-shmobile-r8a73a4-add-a-DMAC-platform-device-and-.patch +patches.renesas/0179-ARM-shmobile-r8a7778-add-HPB-DMAC-support.patch +patches.renesas/0180-ARM-shmobile-r8a7779-add-HPB-DMAC-support.patch +patches.renesas/0181-ARM-shmobile-r8a7790-add-I2C-clocks-and-aliases-for-.patch +patches.renesas/0182-ARM-shmobile-r8a73a4-add-a-clock-alias-for-the-DMAC-.patch +patches.renesas/0183-ARM-shmobile-Break-out-R-Car-Gen2-setup-code.patch +patches.renesas/0184-ARM-shmobile-Introduce-r8a7791_add_standard_devices.patch +patches.renesas/0185-ARM-shmobile-r8a7791-IRQC-platform-device-support.patch +patches.renesas/0186-ARM-shmobile-r8a7791-Arch-timer-workaround.patch +patches.renesas/0187-ARM-shmobile-Initial-r7s72100-SoC-support.patch +patches.renesas/0188-ARM-shmobile-r7s72100-SCIF-support.patch +patches.renesas/0189-ARM-shmobile-r8a7778-split-r8a7778_init_irq_extpin-f.patch +patches.renesas/0190-ARM-shmobile-r8a7779-split-r8a7779_init_irq_extpin-f.patch +patches.renesas/0191-ARM-shmobile-r8a7791-SMP-support.patch +patches.renesas/0192-ARM-shmobile-ape6evm-add-DMA-support-to-MMCIF.patch +patches.renesas/0193-ARM-shmobile-bockw-enable-DMA-for-SDHI0.patch +patches.renesas/0194-ARM-shmobile-marzen-enable-DMA-for-SDHI0.patch +patches.renesas/0195-ARM-shmobile-Genmai-support.patch +patches.renesas/0196-ARM-shmobile-Use-r8a7791_add_standard_devices-on-Koe.patch +patches.renesas/0197-ARM-shmobile-Use-arch-timer-on-Koelsch.patch +patches.renesas/0198-ARM-shmobile-Sync-KZM9D-DTS-with-KZM9D-reference-DTS.patch +patches.renesas/0199-ARM-shmobile-Use-KZM9D-without-reference-for-multipl.patch +patches.renesas/0200-ARM-shmobile-Remove-non-multiplatform-KZM9D-referenc.patch +patches.renesas/0201-ARM-shmobile-Let-KZM9D-multiplatform-boot-with-KZM9D.patch +patches.renesas/0202-ARM-shmobile-Remove-KZM9D-reference-DTS.patch +patches.renesas/0203-ARM-shmobile-Use-SMP-on-Koelsch.patch +patches.renesas/0204-ARM-shmobile-bockw-add-SMSC-support-on-reference.patch +patches.renesas/0205-ARM-shmobile-marzen-enable-INTC-IRQ.patch +patches.renesas/0206-ARM-shmobile-bockw-fixup-ether-node-naming.patch +patches.renesas/0207-ARM-shmobile-Initialize-PWM-backlight-enable_gpio-fi.patch +patches.renesas/0208-spi-use-platform_-get-set-_drvdata.patch +patches.renesas/0209-spi-use-platform_-get-set-_drvdata.patch +patches.renesas/0210-spi-rspi-provide-port-addresses-to-dmaengine-driver-.patch +patches.renesas/0211-spi-spi-rspi-fix-inconsistent-spin_lock_irqsave.patch +patches.renesas/0212-spi-use-dev_get_platdata.patch +patches.renesas/0213-spi-rspi-Add-spi_master_get-call-to-prevent-use-afte.patch +patches.renesas/0214-spi-rspi-Add-missing-dependency-on-DMAE.patch +patches.renesas/0215-spi-drivers-Enable-build-of-drivers-with-COMPILE_TES.patch +patches.renesas/0216-spi-rcar-add-Renesas-QSPI-support-on-RSPI.patch +patches.renesas/0217-spi-rspi-Fix-8bit-data-access-clear-buffer.patch +patches.renesas/0218-spi-rspi-use-platform-drvdata-correctly-in-rspi_remo.patch +patches.renesas/0219-spi-sh-msiof-Remove-unneeded-empty-runtime-PM-callba.patch +patches.renesas/0220-spi-use-dev_get_platdata.patch +patches.renesas/0221-ARM-7863-1-Let-arm_add_memory-always-use-64-bit-argu.patch +patches.renesas/0222-ARM-7864-1-Handle-64-bit-memory-in-case-of-32-bit-ph.patch +patches.renesas/0224-usb-renesas_usbhs-gadget-remove-extra-check-on-udc_s.patch +patches.renesas/0225-usb-renesas_usbhs-tidyup-original-usbhsx_for_each_xx.patch +patches.renesas/0226-usb-renesas-use-dev_get_platdata.patch +patches.renesas/0227-usb-renesas_usbhs-use-platform_-get-set-_drvdata.patch +patches.renesas/0228-serial8250-em-Convert-to-devm_-managed-helpers.patch +patches.renesas/0229-serial8250-em-convert-to-clk_prepare-unprepare.patch +patches.renesas/0230-clocksource-sh_mtu2-Release-clock-when-sh_mtu2_regis.patch +patches.renesas/0231-clocksource-sh_mtu2-Add-clk_prepare-unprepare-suppor.patch +patches.renesas/0232-sh-pfc-r8a7740-Fix-pin-bias-setup.patch +patches.renesas/0233-sh-pfc-sh7372-Fix-pin-bias-setup.patch +patches.renesas/0234-clocksource-sh_tmu-Release-clock-when-sh_tmu_registe.patch +patches.renesas/0235-clocksource-sh_tmu-Add-clk_prepare-unprepare-support.patch +patches.renesas/0236-irqchip-Gic-fix-boot-for-chained-gics.patch +patches.renesas/0237-ASoC-rcar-select-REGMAP.patch + ############################################################################# # fixes that go after all of the above |