Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Use of GICv3/ITS with PCIe host-generic driver - resizing ITS MAPD?
From: Alan Douglas @ 2016-11-03 14:24 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <8637j9iomo.fsf@arm.com>

Hi Marc,
> >> > When setting up bus 0, the ITS device is created, and
> >> > its_build_map_cmd() sets the size of the ITS MAPD based on the
> >> > number of interrupts claimed by bus 0.  When subsequent buses are
> >> > enumerated, the ITS device will be reused, however we do not
> >> > increase the number of supported interrupts to allow for the
> >> > additional interrupts claimed by the additional devices being
> >> > enumerated.  (This can be seen in its_msi_prepare(), which is
> >> > called for each device which has MSI/MSI-X enabled, and will reuse
> >> > an existing ITS. )
> >>
> >> Am I right in understanding that all the PCIe devices in your system
> >> end-up aliasing to the same RequesterID? If so, that's a major issue.
> >> The ITS is designed so that each device exposes its *own* RID, and
> >> have its own Interrupt Translation Table (ITT).
> >>
> >> In your case, you seem to first discover the root port, which is not
> >> upstream of anything, so it doesn't alias with anything at that
> >> point. We allocate the corresponding ITT, and it's all fine. Until we
> >> start probing the rest, and ugly things happen.
> >>
> > Yes, your understanding is correct.  I will dig into this a bit
> > further to see what is wrong then send an update.  I suspect my DTS
> > msi mapping.
> 
> Right. That would explain a lot of what you're seeing. In general, and unless
> you have some funky remapping going on, you're better off having a very
> straightforward msi-map property in your RC node (such as example
> #1 in Documentation/devicetree/bindings/pci/pci-msi.txt).
The problem was that I had an msi-map-mask specified such that all
requester IDs were seen as zero.  Now fixed that and checked that the
requester ID for each device is being correctly provided by HW to the GIC, 
and all is now working correctly with without any patches required.
Thanks for your help.

Alan

^ permalink raw reply

* [PATCH v2] iio: adc: at91: add suspend and resume callback
From: Ludovic Desroches @ 2016-11-03 14:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478078508-24541-1-git-send-email-wenyou.yang@atmel.com>

On Wed, Nov 02, 2016 at 05:21:48PM +0800, Wenyou Yang wrote:
> Add suspend/resume callback, support the pinctrl sleep state when
> the system suspend as well.
> 
> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com>
Acked-by: Ludovic Desroches <ludovic.desroches@atmel.com>

Thanks

> ---
> 
> Changes in v2:
>  - Use CONFIG_PM_SLEEP.
>  - Use SIMPLE_DEV_PM_OPS macro.
> 
>  drivers/iio/adc/at91_adc.c | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c
> index bbdac07..34b928c 100644
> --- a/drivers/iio/adc/at91_adc.c
> +++ b/drivers/iio/adc/at91_adc.c
> @@ -30,6 +30,7 @@
>  #include <linux/iio/trigger.h>
>  #include <linux/iio/trigger_consumer.h>
>  #include <linux/iio/triggered_buffer.h>
> +#include <linux/pinctrl/consumer.h>
>  
>  /* Registers */
>  #define AT91_ADC_CR		0x00		/* Control Register */
> @@ -1347,6 +1348,32 @@ static int at91_adc_remove(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_PM_SLEEP
> +static int at91_adc_suspend(struct device *dev)
> +{
> +	struct iio_dev *idev = platform_get_drvdata(to_platform_device(dev));
> +	struct at91_adc_state *st = iio_priv(idev);
> +
> +	pinctrl_pm_select_sleep_state(dev);
> +	clk_disable_unprepare(st->clk);
> +
> +	return 0;
> +}
> +
> +static int at91_adc_resume(struct device *dev)
> +{
> +	struct iio_dev *idev = platform_get_drvdata(to_platform_device(dev));
> +	struct at91_adc_state *st = iio_priv(idev);
> +
> +	clk_prepare_enable(st->clk);
> +	pinctrl_pm_select_default_state(dev);
> +
> +	return 0;
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(at91_adc_pm_ops, at91_adc_suspend, at91_adc_resume);
> +
>  static struct at91_adc_caps at91sam9260_caps = {
>  	.calc_startup_ticks = calc_startup_ticks_9260,
>  	.num_channels = 4,
> @@ -1441,6 +1468,7 @@ static struct platform_driver at91_adc_driver = {
>  	.driver = {
>  		   .name = DRIVER_NAME,
>  		   .of_match_table = of_match_ptr(at91_adc_dt_ids),
> +		   .pm = &at91_adc_pm_ops,
>  	},
>  };
>  
> -- 
> 2.7.4
> 

^ permalink raw reply

* [PATCH] arm64: errata: Check for --fix-cortex-a53-843419 and --fix-cortex-a53
From: Will Deacon @ 2016-11-03 14:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2d72cbbb-df03-267c-53b0-e3083a746175@gmail.com>

On Wed, Nov 02, 2016 at 02:57:26PM -0700, Florian Fainelli wrote:
> On 11/02/2016 02:41 PM, Markus Mayer wrote:
> > On 2 November 2016 at 14:27, Will Deacon <will.deacon@arm.com> wrote:
> >> On Wed, Nov 02, 2016 at 02:07:17PM -0700, Markus Mayer wrote:
> >>> The question I am asking is: What do we have to lose by supporting both options?
> >>
> >> We end up passing "--fix-cortex-a53" to the linker, without knowing what it
> >> might do in the future.
> > 
> > It seems highly unlikely that such a generic option would be added in
> > the future, both, because the precedent has been set for topic
> > specific options, and because they know it has been used in the past,
> > so they wouldn't add a previously used option to do something
> > completely different. (And if they really did, then that would be a
> > huge binutils bug.)
> > 
> > So, we have a trade-off between a real world problem that does
> > currently exist and avoiding a theoretical issue that may never
> > materialize.
> 
> Agreed, also the way Markus' patch is designed makes it such that we
> first try the full and current option name, and if not supported, try
> the second (and earlier, now obsolete) option name, so I really don't
> see a lot of room for things to go wrong here...

It's not beyond the realms of possibility that ld will grow a
"fix-cortex-a53" option in the future, that enables all of the a53
workarounds. Since ld is the linker supported by the kernel and gold isn't,
I don't want to pass this option down.

If you can't change toolchain and you want this worked around, why can't you
either build gold with it enabled by default, or pass the extra flag on the
command line to the kernel build system?

Will

^ permalink raw reply

* [PATCH v14 14/16] vfio/type1: Check doorbell safety
From: Auger Eric @ 2016-11-03 14:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <HE1PR04MB1321EAD1CE91D2B6FC04BB55FFA30@HE1PR04MB1321.eurprd04.prod.outlook.com>

Hi Diana,

On 03/11/2016 14:45, Diana Madalina Craciun wrote:
> Hi Eric,
> 
> On 10/12/2016 04:23 PM, Eric Auger wrote:
>> On x86 IRQ remapping is abstracted by the IOMMU. On ARM this is abstracted
>> by the msi controller.
>>
>> Since we currently have no way to detect whether the MSI controller is
>> upstream or downstream to the IOMMU we rely on the MSI doorbell information
>> registered by the interrupt controllers. In case at least one doorbell
>> does not implement proper isolation, we state the assignment is unsafe
>> with regard to interrupts. This is a coarse assessment but should allow to
>> wait for a better system description.
>>
>> At this point ARM sMMU still advertises IOMMU_CAP_INTR_REMAP. This is
>> removed in next patch.
>>
>> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>>
>> ---
>> v13 -> v15:
>> - check vfio_msi_resv before checking whether msi doorbell is safe
>>
>> v9 -> v10:
>> - coarse safety assessment based on MSI doorbell info
>>
>> v3 -> v4:
>> - rename vfio_msi_parent_irq_remapping_capable into vfio_safe_irq_domain
>>   and irq_remapping into safe_irq_domains
>>
>> v2 -> v3:
>> - protect vfio_msi_parent_irq_remapping_capable with
>>   CONFIG_GENERIC_MSI_IRQ_DOMAIN
>> ---
>>  drivers/vfio/vfio_iommu_type1.c | 30 +++++++++++++++++++++++++++++-
>>  1 file changed, 29 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
>> index e0c97ef..c18ba9d 100644
>> --- a/drivers/vfio/vfio_iommu_type1.c
>> +++ b/drivers/vfio/vfio_iommu_type1.c
>> @@ -442,6 +442,29 @@ static void vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma)
>>  }
>>  
>>  /**
>> + * vfio_msi_resv - Return whether any VFIO iommu domain requires
>> + * MSI mapping
>> + *
>> + * @iommu: vfio iommu handle
>> + *
>> + * Return: true of MSI mapping is needed, false otherwise
>> + */
>> +static bool vfio_msi_resv(struct vfio_iommu *iommu)
>> +{
>> +	struct iommu_domain_msi_resv msi_resv;
>> +	struct vfio_domain *d;
>> +	int ret;
>> +
>> +	list_for_each_entry(d, &iommu->domain_list, next) {
>> +		ret = iommu_domain_get_attr(d->domain, DOMAIN_ATTR_MSI_RESV,
>> +					    &msi_resv);
>> +		if (!ret)
>> +			return true;
>> +	}
>> +	return false;
>> +}
>> +
>> +/**
>>   * vfio_set_msi_aperture - Sets the msi aperture on all domains
>>   * requesting MSI mapping
>>   *
>> @@ -945,8 +968,13 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
>>  	INIT_LIST_HEAD(&domain->group_list);
>>  	list_add(&group->next, &domain->group_list);
>>  
>> +	/*
>> +	 * to advertise safe interrupts either the IOMMU or the MSI controllers
>> +	 * must support IRQ remapping (aka. interrupt translation)
>> +	 */
>>  	if (!allow_unsafe_interrupts &&
>> -	    !iommu_capable(bus, IOMMU_CAP_INTR_REMAP)) {
>> +	    (!iommu_capable(bus, IOMMU_CAP_INTR_REMAP) &&
>> +		!(vfio_msi_resv(iommu) && iommu_msi_doorbell_safe()))) {
>>  		pr_warn("%s: No interrupt remapping support.  Use the module param \"allow_unsafe_interrupts\" to enable VFIO IOMMU support on this platform\n",
>>  		       __func__);
>>  		ret = -EPERM;
> 
> I understand from the other discussions that you will respin these
> series, but anyway I have tested this version with GICV3 + ITS and it
> stops here. As I have a GICv3 I am not supposed to enable allow unsafe
> interrupts. What I see is that vfio_msi_resv returns false just because
> the iommu->domain_list list is empty. The newly created domain is
> actually added to the domain_list at the end of this function, so it
> seems normal for the list to be empty at this point.

Thanks for reporting the issue. You are fully right. I must have missed
that test. I should just check the current iommu_domain attribute I think.

waiting for a fix, please probe the vfio_iommu_type1 module with
allow_unsafe_interrupts=1

Thanks

Eric
> 
> Thanks,
> 
> Diana
> 
> 

^ permalink raw reply

* [PATCHv2] PCI: QDF2432 32 bit config space accessors
From: Bjorn Helgaas @ 2016-11-03 14:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <3fd26a0d-a5c2-c385-866e-b957dffb7dda@codeaurora.org>

On Wed, Nov 02, 2016 at 12:36:16PM -0400, Sinan Kaya wrote:
> Hi Bjorn,
> 
> On 11/2/2016 12:08 PM, Bjorn Helgaas wrote:
> > On Tue, Nov 01, 2016 at 07:06:31AM -0600, cov at codeaurora.org wrote:
> >> Hi Bjorn,
> >>
> >> On 2016-10-31 15:48, Bjorn Helgaas wrote:
> >>> On Wed, Sep 21, 2016 at 06:38:05PM -0400, Christopher Covington wrote:
> >>>> The Qualcomm Technologies QDF2432 SoC does not support accesses
> >>>> smaller
> >>>> than 32 bits to the PCI configuration space. Register the appropriate
> >>>> quirk.
> >>>>
> >>>> Signed-off-by: Christopher Covington <cov@codeaurora.org>
> >>>
> >>> Hi Christopher,
> >>>
> >>> Can you rebase this against v4.9-rc1?  It no longer applies to my tree.
> >>
> >> I apologize for not being clearer. This patch depends on:
> >>
> >> PCI/ACPI: Extend pci_mcfg_lookup() responsibilities
> >> PCI/ACPI: Check platform-specific ECAM quirks
> >>
> >> These patches from Tomasz Nowicki were previously in your pci/ecam-v6
> >> branch, but that seems to have come and gone. How would you like to
> >> proceed?
> > 
> > Oh yes, that's right, I forgot that connection.  I'm afraid I kind of
> > dropped the ball on that thread, so I went back and read through it
> > again.
> > 
> > I *think* the current state is:
> > 
> >   - I'm OK with the first two patches that add the quirk
> >     infrastructure.
> > 
> >   - My issue with the last three patches that add ThunderX quirks is
> >     that there's no generic description of the ECAM address space.
> > 
> > So if I understand correctly, your Qualcomm patch depends only on the
> > first two patches.
> > 
> > Then the question is how the Qualcomm ECAM address space is described.
> > Your quirk overrides the default pci_generic_ecam_ops with the
> > &pci_32b_ops, but it doesn't touch the address space part, so I assume
> > the bus ranges and corresponding address space in your MCFG is
> > correct.  So far, so good.
> 
> Qualcomm ECAM space includes both the root port and the endpoint address
> space with a single contiguous 256 MB address space described in MCFG table.
> There is no need to describe additional resources like PNP0C02.

This is the crucial point I have failed to communicate clearly: the
PNP0C02 resource is *always* required, even if the MCFG is correct.

The reason is that MCFG is a PCI-specific table, and it should be
possible to boot a kernel with no PCI support.  That kernel will not
look at the MCFG.  The PCI hardware will still be present and will
still consume the ECAM space, so the OS must be able to discover that
the ECAM space is not available for other devices.

The usual way to for the OS to discover that would be via the _CRS of
a PNP0A03 or PNP0A08 host bridge device.  _CRS is what I mean by a
"generic" way to describe this address space, because the ACPI core
can interpret _CRS for all ACPI devices, even if the kernel doesn't
contain drivers for all of those devices.

It turns out that we can't use the _CRS of host bridges because of the
Producer/Consumer bit screwup [1].  So the fallback is to include the
ECAM space in the _CRS of a PNP0C02 device.  This is what the PCI
Firmware spec r3.0, Table 4-2, footnote 2 is talking about.

Bjorn

[1] The original ACPI spec intent was that Consumer resources would be
space like ECAM that is consumed directly by the bridge, and Producer
resources would be the windows forwarded down to PCI.  But BIOSes
didn't use the Producer/Consumer bit consistently, so we have to
assume that all resources in host bridge _CRS are windows, which
leaves us no way to describe the Consumer resources.

^ permalink raw reply

* [PATCH 0/3] fix ohci phy name
From: Axel Haslam @ 2016-11-03 13:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <d72af1ff-52f1-09ea-ee22-110c163d52f8@ti.com>

On Thu, Nov 3, 2016 at 1:00 PM, Sekhar Nori <nsekhar@ti.com> wrote:
> On Thursday 03 November 2016 01:54 PM, Axel Haslam wrote:
>> Hi Sekhar, David,
>>
>> It might make sense to have this patch series,
>> squashed into a single patch, would you agree,
>> or do you prefer it as is: one-per-subsystem?
>
> Patches in the current form are okay. Some coordination is required in
> getting them merged though. I am happy to take the driver patches
> through ARM-SoC with ack from respective maintainers.
>
> I will need to carry the platform patch through my tree because it
> conflicts with other changes I have already queued.
>
> That said, I am unable to review 3/3 since I am unable to find its baseline.
>

ok, ill send v2 fixing Davids comments on the commit messages
and referencing the missing patch that is queued on usb-next.

-Axel
> Thanks,
> Sekhar

^ permalink raw reply

* [crypto] [marvell-cesa] Possible regression after Linux 4.7
From: Romain Perier @ 2016-11-03 13:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <58174e5d.233ac20a.a4335.5656@mx.google.com>

Hello,

Le 31/10/2016 ? 14:59, radioconfusion at gmail.com a ?crit :

> Do you have any improvement for the issue?
> Please let me know if you need any help to resolve it.
>
> Best Regards,
> Jussi
>

Sorry for the delay.
Could you try to revert locally commit 
2786cee8e50bb4b4303dc22665f391b72318fa84 (crypto: marvell - Move SRAM 
I/O operations to step functions) ?

It seems to fix most of the issues I had with curl.
I will continue to investigate, that's just to confirm if it fixes the 
issues for you.

Thanks,
Romain
-- 
Romain Perier, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

^ permalink raw reply

* [PATCH V3 6/6] bus: Add support for Tegra Generic Memory Interface
From: Jon Hunter @ 2016-11-03 13:50 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CALw8SCVu+-h_yhOa7uDuyFBPVvhwjD64S+-MDeYN8EZsGHpXyw@mail.gmail.com>


On 03/11/16 13:08, Mirza Krak wrote:
> 2016-11-03 11:51 GMT+01:00 Jon Hunter <jonathanh@nvidia.com>:
>>
>> On 27/10/16 15:01, Mirza Krak wrote:
>>>
>>> From: Mirza Krak <mirza.krak@gmail.com>
>>>
>>> The Generic Memory Interface bus can be used to connect high-speed
>>> devices such as NOR flash, FPGAs, DSPs...
>>>
>>> Signed-off-by: Mirza Krak <mirza.krak@gmail.com>
>>> Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
>>> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
>>> ---
>>>
>>> Changes in v2:
>>>  - Fixed some checkpatch errors
>>>  - Re-ordered probe to get rid of local variables
>>>  - Moved of_platform_default_populate call to the end of probe
>>>  - Use the timing and configuration properties from the child device
>>>  - Added warning if more then 1 child device exist
>>>
>>> Changes in v3:
>>>  - added helper function to disable the controller which is used in remove
>>> and
>>>  on error.
>>>  - Added logic to parse CS# from "ranges" property with fallback to "reg"
>>>  property
>>>
>>>  drivers/bus/Kconfig     |   8 ++
>>>  drivers/bus/Makefile    |   1 +
>>>  drivers/bus/tegra-gmi.c | 267
>>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>>  3 files changed, 276 insertions(+)
>>>  create mode 100644 drivers/bus/tegra-gmi.c
>>>
>>> diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
>>> index 4ed7d26..2e75a7f 100644
>>> --- a/drivers/bus/Kconfig
>>> +++ b/drivers/bus/Kconfig
>>> @@ -141,6 +141,14 @@ config TEGRA_ACONNECT
>>>           Driver for the Tegra ACONNECT bus which is used to interface
>>> with
>>>           the devices inside the Audio Processing Engine (APE) for
>>> Tegra210.
>>>
>>> +config TEGRA_GMI
>>> +       tristate "Tegra Generic Memory Interface bus driver"
>>> +       depends on ARCH_TEGRA
>>> +       help
>>> +         Driver for the Tegra Generic Memory Interface bus which can be
>>> used
>>> +         to attach devices such as NOR, UART, FPGA and more.
>>> +
>>> +
>>
>>
>> Nit-pick ... only one additional line above is needed to be consistent with
>> the rest of the file.
>
> Will fix that.
>
>>
>>
>>>  config UNIPHIER_SYSTEM_BUS
>>>         tristate "UniPhier System Bus driver"
>>>         depends on ARCH_UNIPHIER && OF
>>> diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
>>> index ac84cc4..34e2bab 100644
>>> --- a/drivers/bus/Makefile
>>> +++ b/drivers/bus/Makefile
>>> @@ -18,5 +18,6 @@ obj-$(CONFIG_OMAP_OCP2SCP)    += omap-ocp2scp.o
>>>  obj-$(CONFIG_SUNXI_RSB)                += sunxi-rsb.o
>>>  obj-$(CONFIG_SIMPLE_PM_BUS)    += simple-pm-bus.o
>>>  obj-$(CONFIG_TEGRA_ACONNECT)   += tegra-aconnect.o
>>> +obj-$(CONFIG_TEGRA_GMI)                += tegra-gmi.o
>>>  obj-$(CONFIG_UNIPHIER_SYSTEM_BUS)      += uniphier-system-bus.o
>>>  obj-$(CONFIG_VEXPRESS_CONFIG)  += vexpress-config.o
>>> diff --git a/drivers/bus/tegra-gmi.c b/drivers/bus/tegra-gmi.c
>>> new file mode 100644
>>> index 0000000..dd9623e
>>> --- /dev/null
>>> +++ b/drivers/bus/tegra-gmi.c
>>> @@ -0,0 +1,267 @@
>>> +/*
>>> + * Driver for NVIDIA Generic Memory Interface
>>> + *
>>> + * Copyright (C) 2016 Host Mobility AB. All rights reserved.
>>> + *
>>> + * 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.
>>> + */
>>> +#include <linux/clk.h>
>>> +#include <linux/delay.h>
>>> +#include <linux/io.h>
>>> +#include <linux/module.h>
>>> +#include <linux/of_device.h>
>>> +#include <linux/reset.h>
>>> +
>>> +#define TEGRA_GMI_CONFIG               0x00
>>> +#define TEGRA_GMI_CONFIG_GO            BIT(31)
>>> +#define TEGRA_GMI_BUS_WIDTH_32BIT      BIT(30)
>>> +#define TEGRA_GMI_MUX_MODE             BIT(28)
>>> +#define TEGRA_GMI_RDY_BEFORE_DATA      BIT(24)
>>> +#define TEGRA_GMI_RDY_ACTIVE_HIGH      BIT(23)
>>> +#define TEGRA_GMI_ADV_ACTIVE_HIGH      BIT(22)
>>> +#define TEGRA_GMI_OE_ACTIVE_HIGH       BIT(21)
>>> +#define TEGRA_GMI_CS_ACTIVE_HIGH       BIT(20)
>>> +#define TEGRA_GMI_CS_SELECT(x)         ((x & 0x7) << 4)
>>> +
>>> +#define TEGRA_GMI_TIMING0              0x10
>>> +#define TEGRA_GMI_MUXED_WIDTH(x)       ((x & 0xf) << 12)
>>> +#define TEGRA_GMI_HOLD_WIDTH(x)                ((x & 0xf) << 8)
>>> +#define TEGRA_GMI_ADV_WIDTH(x)         ((x & 0xf) << 4)
>>> +#define TEGRA_GMI_CE_WIDTH(x)          (x & 0xf)
>>> +
>>> +#define TEGRA_GMI_TIMING1              0x14
>>> +#define TEGRA_GMI_WE_WIDTH(x)          ((x & 0xff) << 16)
>>> +#define TEGRA_GMI_OE_WIDTH(x)          ((x & 0xff) << 8)
>>> +#define TEGRA_GMI_WAIT_WIDTH(x)                (x & 0xff)
>>> +
>>> +struct tegra_gmi_priv {
>>> +       void __iomem *base;
>>> +       struct reset_control *rst;
>>> +       struct clk *clk;
>>> +
>>> +       u32 snor_config;
>>> +       u32 snor_timing0;
>>> +       u32 snor_timing1;
>>> +};
>>> +
>>> +static void tegra_gmi_disable(struct tegra_gmi_priv *priv)
>>> +{
>>> +       u32 config;
>>> +
>>> +       /* stop GMI operation */
>>> +       config = readl(priv->base + TEGRA_GMI_CONFIG);
>>> +       config &= ~TEGRA_GMI_CONFIG_GO;
>>> +       writel(config, priv->base + TEGRA_GMI_CONFIG);
>>> +
>>> +       reset_control_assert(priv->rst);
>>> +       clk_disable_unprepare(priv->clk);
>>> +}
>>> +
>>> +static void tegra_gmi_init(struct device *dev, struct tegra_gmi_priv
>>> *priv)
>>> +{
>>> +       writel(priv->snor_timing0, priv->base + TEGRA_GMI_TIMING0);
>>> +       writel(priv->snor_timing1, priv->base + TEGRA_GMI_TIMING1);
>>> +
>>> +       priv->snor_config |= TEGRA_GMI_CONFIG_GO;
>>> +       writel(priv->snor_config, priv->base + TEGRA_GMI_CONFIG);
>>> +}
>>> +
>>> +static int tegra_gmi_parse_dt(struct device *dev, struct tegra_gmi_priv
>>> *priv)
>>> +{
>>> +       struct device_node *child =
>>> of_get_next_available_child(dev->of_node,
>>> +               NULL);
>>> +       u32 property, ranges[4];
>>> +       int ret;
>>> +
>>> +       if (!child) {
>>> +               dev_warn(dev, "no child nodes found\n");
>>> +               return 0;
>>
>>
>> Don't we want to return an error here? Otherwise, we will call
>> tegra_gmi_init() with an invalid configuration.
>
> True, we probably want that. My thought was that we might accept a
> tegra-gmi node without any child nodes and just print a warning. But
> since it is the child node that holds the bus configuration it makes
> sense to fail probe due to no child nodes.

I was wondering that too, but given that we then program and enable the 
GMI I think it is best to just fail for now.

>>
>>
>>> +       }
>>> +
>>> +       /*
>>> +        * We currently only support one child device due to lack of
>>> +        * chip-select address decoding. Which means that we only have one
>>> +        * chip-select line from the GMI controller.
>>> +        */
>>> +       if (of_get_child_count(dev->of_node) > 1)
>>> +               dev_warn(dev, "only one child device is supported.");
>>> +
>>> +       if (of_property_read_bool(child, "nvidia,snor-data-width-32bit"))
>>> +               priv->snor_config |= TEGRA_GMI_BUS_WIDTH_32BIT;
>>> +
>>> +       if (of_property_read_bool(child, "nvidia,snor-mux-mode"))
>>> +               priv->snor_config |= TEGRA_GMI_MUX_MODE;
>>> +
>>> +       if (of_property_read_bool(child,
>>> "nvidia,snor-rdy-active-before-data"))
>>> +               priv->snor_config |= TEGRA_GMI_RDY_BEFORE_DATA;
>>> +
>>> +       if (of_property_read_bool(child, "nvidia,snor-rdy-inv"))
>>> +               priv->snor_config |= TEGRA_GMI_RDY_ACTIVE_HIGH;
>>> +
>>> +       if (of_property_read_bool(child, "nvidia,snor-adv-inv"))
>>> +               priv->snor_config |= TEGRA_GMI_ADV_ACTIVE_HIGH;
>>> +
>>> +       if (of_property_read_bool(child, "nvidia,snor-oe-inv"))
>>> +               priv->snor_config |= TEGRA_GMI_OE_ACTIVE_HIGH;
>>> +
>>> +       if (of_property_read_bool(child, "nvidia,snor-cs-inv"))
>>> +               priv->snor_config |= TEGRA_GMI_CS_ACTIVE_HIGH;
>>> +
>>> +       /* Decode the CS# */
>>> +       ret = of_property_read_u32_array(child, "ranges", ranges, 4);
>>> +       if (ret < 0) {
>>> +               /* Invalid binding */
>>> +               if (ret == -EOVERFLOW) {
>>> +                       dev_err(dev, "invalid ranges length\n");
>>> +                       goto error_cs_decode;
>>> +               }
>>> +
>>> +               /*
>>> +                * If we reach here it means that the child node has an
>>> empty
>>> +                * ranges or it does not exist at all. Attempt to decode
>>> the
>>> +                * CS# from the reg property instead.
>>> +                */
>>> +               ret = of_property_read_u32(child, "reg", &property);
>>> +               if (ret < 0) {
>>> +                       dev_err(dev, "no reg property found\n");
>>> +                       goto error_cs_decode;
>>> +               }
>>> +       } else {
>>> +               property = ranges[1];
>>> +       }
>>> +
>>> +       priv->snor_config |= TEGRA_GMI_CS_SELECT(property);
>>
>>
>> Should we make sure the CS is a valid value before setting?
>
> The TEGRA_GMI_CS_SELECT(x) macro will truncate any erroneous CS value.
> But yeah we could do a sanity check instead and return an error if it
> is invalid.
>
>>
>>
>>> +
>>> +       /* The default values that are provided below are reset values */
>>> +       if (!of_property_read_u32(child, "nvidia,snor-muxed-width",
>>> &property))
>>> +               priv->snor_timing0 |= TEGRA_GMI_MUXED_WIDTH(property);
>>> +       else
>>> +               priv->snor_timing0 |= TEGRA_GMI_MUXED_WIDTH(1);
>>> +
>>> +       if (!of_property_read_u32(child, "nvidia,snor-hold-width",
>>> &property))
>>> +               priv->snor_timing0 |= TEGRA_GMI_HOLD_WIDTH(property);
>>> +       else
>>> +               priv->snor_timing0 |= TEGRA_GMI_HOLD_WIDTH(1);
>>> +
>>> +       if (!of_property_read_u32(child, "nvidia,snor-adv-width",
>>> &property))
>>> +               priv->snor_timing0 |= TEGRA_GMI_ADV_WIDTH(property);
>>> +       else
>>> +               priv->snor_timing0 |= TEGRA_GMI_ADV_WIDTH(1);
>>> +
>>> +       if (!of_property_read_u32(child, "nvidia,snor-ce-width",
>>> &property))
>>> +               priv->snor_timing0 |= TEGRA_GMI_CE_WIDTH(property);
>>> +       else
>>> +               priv->snor_timing0 |= TEGRA_GMI_CE_WIDTH(4);
>>> +
>>> +       if (!of_property_read_u32(child, "nvidia,snor-we-width",
>>> &property))
>>> +               priv->snor_timing1 |= TEGRA_GMI_WE_WIDTH(property);
>>> +       else
>>> +               priv->snor_timing1 |= TEGRA_GMI_WE_WIDTH(1);
>>> +
>>> +       if (!of_property_read_u32(child, "nvidia,snor-oe-width",
>>> &property))
>>> +               priv->snor_timing1 |= TEGRA_GMI_OE_WIDTH(property);
>>> +       else
>>> +               priv->snor_timing1 |= TEGRA_GMI_OE_WIDTH(1);
>>> +
>>> +       if (!of_property_read_u32(child, "nvidia,snor-wait-width",
>>> &property))
>>> +               priv->snor_timing1 |= TEGRA_GMI_WAIT_WIDTH(property);
>>> +       else
>>> +               priv->snor_timing1 |= TEGRA_GMI_WAIT_WIDTH(3);
>>> +
>>> +error_cs_decode:
>>> +       if (ret < 0)
>>> +               dev_err(dev, "failed to decode chip-select number\n");
>>
>>
>> Nit do we need another error message here? Can we add the "failed to decode
>> CS" part the earlier message?
>
> Does it make sense to drop the two earlier messages instead and keep this one?

I think it is nice to have specific errors so we know where it failed. 
You could just drop the above and when you add the test for making sure 
the CS is valid add another error message for that. Not a big deal 
either way. So I will leave to you to decide.

Cheers
Jon

-- 
nvpublic

^ permalink raw reply

* [PATCH V3 2/6] clk: tegra: add TEGRA30_CLK_NOR to init table
From: Jon Hunter @ 2016-11-03 13:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477576872-2665-3-git-send-email-mirza.krak@gmail.com>


On 27/10/16 15:01, Mirza Krak wrote:
> From: Mirza Krak <mirza.krak@gmail.com>
>
> Add TEGRA30_CLK_NOR to init table and set default rate to 127 MHz which
> is max rate.
>
> The maximum rate value of 127 MHz is pulled from the downstream L4T
> kernel.
>
> Signed-off-by: Mirza Krak <mirza.krak@gmail.com>
> Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board

Acked-by: Jon Hunter <jonathanh@nvidia.com>

Cheers
Jon

-- 
nvpublic

^ permalink raw reply

* [PATCH V3 1/6] clk: tegra: add TEGRA20_CLK_NOR to init table
From: Jon Hunter @ 2016-11-03 13:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477576872-2665-2-git-send-email-mirza.krak@gmail.com>



On 27/10/16 15:01, Mirza Krak wrote:
> From: Mirza Krak <mirza.krak@gmail.com>
>
> Add TEGRA20_CLK_NOR to init table and set default rate to 92 MHz which
> is max rate.
>
> The maximum rate value of 92 MHz is pulled from the downstream L4T
> kernel.
>
> Signed-off-by: Mirza Krak <mirza.krak@gmail.com>
> Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board

Acked-by: Jon Hunter <jonathanh@nvidia.com>

Cheers
Jon

-- 
nvpublic

^ permalink raw reply

* [PATCH v14 14/16] vfio/type1: Check doorbell safety
From: Diana Madalina Craciun @ 2016-11-03 13:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1476278544-3397-15-git-send-email-eric.auger@redhat.com>

Hi Eric,

On 10/12/2016 04:23 PM, Eric Auger wrote:
> On x86 IRQ remapping is abstracted by the IOMMU. On ARM this is abstracted
> by the msi controller.
>
> Since we currently have no way to detect whether the MSI controller is
> upstream or downstream to the IOMMU we rely on the MSI doorbell information
> registered by the interrupt controllers. In case at least one doorbell
> does not implement proper isolation, we state the assignment is unsafe
> with regard to interrupts. This is a coarse assessment but should allow to
> wait for a better system description.
>
> At this point ARM sMMU still advertises IOMMU_CAP_INTR_REMAP. This is
> removed in next patch.
>
> Signed-off-by: Eric Auger <eric.auger@redhat.com>
>
> ---
> v13 -> v15:
> - check vfio_msi_resv before checking whether msi doorbell is safe
>
> v9 -> v10:
> - coarse safety assessment based on MSI doorbell info
>
> v3 -> v4:
> - rename vfio_msi_parent_irq_remapping_capable into vfio_safe_irq_domain
>   and irq_remapping into safe_irq_domains
>
> v2 -> v3:
> - protect vfio_msi_parent_irq_remapping_capable with
>   CONFIG_GENERIC_MSI_IRQ_DOMAIN
> ---
>  drivers/vfio/vfio_iommu_type1.c | 30 +++++++++++++++++++++++++++++-
>  1 file changed, 29 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
> index e0c97ef..c18ba9d 100644
> --- a/drivers/vfio/vfio_iommu_type1.c
> +++ b/drivers/vfio/vfio_iommu_type1.c
> @@ -442,6 +442,29 @@ static void vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma)
>  }
>  
>  /**
> + * vfio_msi_resv - Return whether any VFIO iommu domain requires
> + * MSI mapping
> + *
> + * @iommu: vfio iommu handle
> + *
> + * Return: true of MSI mapping is needed, false otherwise
> + */
> +static bool vfio_msi_resv(struct vfio_iommu *iommu)
> +{
> +	struct iommu_domain_msi_resv msi_resv;
> +	struct vfio_domain *d;
> +	int ret;
> +
> +	list_for_each_entry(d, &iommu->domain_list, next) {
> +		ret = iommu_domain_get_attr(d->domain, DOMAIN_ATTR_MSI_RESV,
> +					    &msi_resv);
> +		if (!ret)
> +			return true;
> +	}
> +	return false;
> +}
> +
> +/**
>   * vfio_set_msi_aperture - Sets the msi aperture on all domains
>   * requesting MSI mapping
>   *
> @@ -945,8 +968,13 @@ static int vfio_iommu_type1_attach_group(void *iommu_data,
>  	INIT_LIST_HEAD(&domain->group_list);
>  	list_add(&group->next, &domain->group_list);
>  
> +	/*
> +	 * to advertise safe interrupts either the IOMMU or the MSI controllers
> +	 * must support IRQ remapping (aka. interrupt translation)
> +	 */
>  	if (!allow_unsafe_interrupts &&
> -	    !iommu_capable(bus, IOMMU_CAP_INTR_REMAP)) {
> +	    (!iommu_capable(bus, IOMMU_CAP_INTR_REMAP) &&
> +		!(vfio_msi_resv(iommu) && iommu_msi_doorbell_safe()))) {
>  		pr_warn("%s: No interrupt remapping support.  Use the module param \"allow_unsafe_interrupts\" to enable VFIO IOMMU support on this platform\n",
>  		       __func__);
>  		ret = -EPERM;

I understand from the other discussions that you will respin these
series, but anyway I have tested this version with GICV3 + ITS and it
stops here. As I have a GICv3 I am not supposed to enable allow unsafe
interrupts. What I see is that vfio_msi_resv returns false just because
the iommu->domain_list list is empty. The newly created domain is
actually added to the domain_list at the end of this function, so it
seems normal for the list to be empty at this point.

Thanks,

Diana

^ permalink raw reply

* [PATCH V3 1/6] clk: tegra: add TEGRA20_CLK_NOR to init table
From: Jon Hunter @ 2016-11-03 13:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CALw8SCWC7RmNLVv4vxO9xw3jHVkgCaevbL61sJcpcva9CiaAVQ@mail.gmail.com>


On 03/11/16 12:30, Mirza Krak wrote:
> 2016-11-03 13:26 GMT+01:00 Mirza Krak <mirza.krak@gmail.com>:
>> 2016-11-03 11:06 GMT+01:00 Jon Hunter <jonathanh@nvidia.com>:
>>> Hi Mirza,
>>>
>>> On 27/10/16 15:01, Mirza Krak wrote:
>>>>
>>>> From: Mirza Krak <mirza.krak@gmail.com>
>>>>
>>>> Add TEGRA20_CLK_NOR to init table and set default rate to 92 MHz which
>>>> is max rate.
>>>>
>>>> The maximum rate value of 92 MHz is pulled from the downstream L4T
>>>> kernel.
>>>
>>>
>>> Thanks for adding this. I assume that this is from an L4T r16 release with a
>>> v3.1 kernel. I had a quick poke through the kernel sources for v3.1 but was
>>> unable to see where this is set. Obviously v3.1 did not have CCF and so
>>> everything seems to be in the arch/arm/mach-tegra directory for setting up
>>> clocks. Can you point me to the appropriate sources so I can ACK this?
>>
>> I use the kernel sources provided by Toradex, and these sources are
>> based on L4T r16 release.
>>
>> http://git.toradex.com/cgit/linux-toradex.git/tree/arch/arm/mach-tegra/tegra2_clocks.c?h=tegra#n2463
>
> Ops, pre-mature send.
>
> I also added Marcel from Toradex on CC.
>
> The link to the source are [1] for Tegra2 and  [2] for Tegra3.
>
> [1]. http://git.toradex.com/cgit/linux-toradex.git/tree/arch/arm/mach-tegra/tegra2_clocks.c?h=tegra#n2463
> [2]. http://git.toradex.com/cgit/linux-toradex.git/tree/arch/arm/mach-tegra/tegra3_clocks.c?h=tegra#n4353

Great. Yes I see the same. Thanks!

Jon

-- 
nvpublic

^ permalink raw reply

* [PATCH] ARM: DTS: r8a7794: alt: Fix PCF names for DU
From: Jacopo Mondi @ 2016-11-03 13:42 UTC (permalink / raw)
  To: linux-arm-kernel

Update the PCF pin groups and function names of DU interface for
r8a7794 ALT board.

The currently specified pin groups and function names prevented PCF and
DU interfaces from being correctly configured:

sh-pfc e6060000.pin-controller: function 'du' not supported
sh-pfc e6060000.pin-controller: invalid function du in map table
sh-pfc e6060000.pin-controller: function 'du' not supported
sh-pfc e6060000.pin-controller: invalid function du in map table
sh-pfc e6060000.pin-controller: function 'du' not supported
sh-pfc e6060000.pin-controller: invalid function du in map table
sh-pfc e6060000.pin-controller: function 'du' not supported
sh-pfc e6060000.pin-controller: invalid function du in map table
rcar-du: probe of feb00000.display failed with error -22

Signed-off-by: Jacopo Mondi <jacopo@jmondi.org>
---

Patch applied against Simon Horman's renesas/master branch.
The PCF pin groups and function renaming was introduced by commit 56ed4bb9 and
DTS for ALT board has never been update accordingly.
Tested displaying frames on VGA interface: the rcar-du driver loads correctly.

 arch/arm/boot/dts/r8a7794-alt.dts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/boot/dts/r8a7794-alt.dts b/arch/arm/boot/dts/r8a7794-alt.dts
index 8d1b35a..9d65fb3 100644
--- a/arch/arm/boot/dts/r8a7794-alt.dts
+++ b/arch/arm/boot/dts/r8a7794-alt.dts
@@ -165,8 +165,8 @@
 	pinctrl-names = "default";
 
 	du_pins: du {
-		groups = "du1_rgb666", "du1_sync", "du1_disp", "du1_dotclkout0";
-		function = "du";
+		groups = "du1_rgb666", "du1_sync", "du1_disp", "du1_clk0_out";
+		function = "du1";
 	};
 
 	scif2_pins: scif2 {
-- 
2.7.4

^ permalink raw reply related

* [PATCH V7 0/4] dmaengine: qcom_hidma: add MSI interrupt support
From: Koul, Vinod @ 2016-11-03 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477067879-23750-1-git-send-email-okaya@codeaurora.org>

On Fri, 2016-10-21 at 12:37 -0400, Sinan Kaya wrote:
> The new version of the HW supports MSI interrupts instead of wired
> interrupts. The MSI interrupts are especially useful for the guest
> machine
> execution. The wired interrupts usually trap to the hypervisor and
> then are
> relayed to the actual interrupt.
> 
> The MSI interrupts can be directly fed into the interrupt controller.
> 
> Adding a new OF compat string (qcom,hidma-1.1) and ACPI string
> (QCOM8062)
> to distinguish newer HW from the older ones.

Applied, thanks

-- 
~Vinod

^ permalink raw reply

* [PATCH] dmaengine: st_fdma: Update st_fdma to 'depends on REMOTEPROC'.
From: Koul, Vinod @ 2016-11-03 13:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1477039465-31121-1-git-send-email-peter.griffin@linaro.org>

On Fri, 2016-10-21 at 09:44 +0100, Peter Griffin wrote:
> During randconfig builds you can get the following warning
> "warning: (ST_FDMA) selects ST_SLIM_REMOTEPROC which has unmet direct
> ?dependencies (REMOTEPROC)"
> 
> randconfig builds should always build without any warnings so
> update fdma to depend on REMOTEPROC so this can not happen.

Applied, thanks

-- 
~Vinod

^ permalink raw reply

* [PATCH V3 6/6] bus: Add support for Tegra Generic Memory Interface
From: Mirza Krak @ 2016-11-03 13:08 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <3cdf7281-840f-1aa0-5a57-fe58501165f4@nvidia.com>

2016-11-03 11:51 GMT+01:00 Jon Hunter <jonathanh@nvidia.com>:
>
> On 27/10/16 15:01, Mirza Krak wrote:
>>
>> From: Mirza Krak <mirza.krak@gmail.com>
>>
>> The Generic Memory Interface bus can be used to connect high-speed
>> devices such as NOR flash, FPGAs, DSPs...
>>
>> Signed-off-by: Mirza Krak <mirza.krak@gmail.com>
>> Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
>> Tested-on: Colibri T20/T30 on EvalBoard V3.x and GMI-Memory Board
>> ---
>>
>> Changes in v2:
>>  - Fixed some checkpatch errors
>>  - Re-ordered probe to get rid of local variables
>>  - Moved of_platform_default_populate call to the end of probe
>>  - Use the timing and configuration properties from the child device
>>  - Added warning if more then 1 child device exist
>>
>> Changes in v3:
>>  - added helper function to disable the controller which is used in remove
>> and
>>  on error.
>>  - Added logic to parse CS# from "ranges" property with fallback to "reg"
>>  property
>>
>>  drivers/bus/Kconfig     |   8 ++
>>  drivers/bus/Makefile    |   1 +
>>  drivers/bus/tegra-gmi.c | 267
>> ++++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 276 insertions(+)
>>  create mode 100644 drivers/bus/tegra-gmi.c
>>
>> diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
>> index 4ed7d26..2e75a7f 100644
>> --- a/drivers/bus/Kconfig
>> +++ b/drivers/bus/Kconfig
>> @@ -141,6 +141,14 @@ config TEGRA_ACONNECT
>>           Driver for the Tegra ACONNECT bus which is used to interface
>> with
>>           the devices inside the Audio Processing Engine (APE) for
>> Tegra210.
>>
>> +config TEGRA_GMI
>> +       tristate "Tegra Generic Memory Interface bus driver"
>> +       depends on ARCH_TEGRA
>> +       help
>> +         Driver for the Tegra Generic Memory Interface bus which can be
>> used
>> +         to attach devices such as NOR, UART, FPGA and more.
>> +
>> +
>
>
> Nit-pick ... only one additional line above is needed to be consistent with
> the rest of the file.

Will fix that.

>
>
>>  config UNIPHIER_SYSTEM_BUS
>>         tristate "UniPhier System Bus driver"
>>         depends on ARCH_UNIPHIER && OF
>> diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
>> index ac84cc4..34e2bab 100644
>> --- a/drivers/bus/Makefile
>> +++ b/drivers/bus/Makefile
>> @@ -18,5 +18,6 @@ obj-$(CONFIG_OMAP_OCP2SCP)    += omap-ocp2scp.o
>>  obj-$(CONFIG_SUNXI_RSB)                += sunxi-rsb.o
>>  obj-$(CONFIG_SIMPLE_PM_BUS)    += simple-pm-bus.o
>>  obj-$(CONFIG_TEGRA_ACONNECT)   += tegra-aconnect.o
>> +obj-$(CONFIG_TEGRA_GMI)                += tegra-gmi.o
>>  obj-$(CONFIG_UNIPHIER_SYSTEM_BUS)      += uniphier-system-bus.o
>>  obj-$(CONFIG_VEXPRESS_CONFIG)  += vexpress-config.o
>> diff --git a/drivers/bus/tegra-gmi.c b/drivers/bus/tegra-gmi.c
>> new file mode 100644
>> index 0000000..dd9623e
>> --- /dev/null
>> +++ b/drivers/bus/tegra-gmi.c
>> @@ -0,0 +1,267 @@
>> +/*
>> + * Driver for NVIDIA Generic Memory Interface
>> + *
>> + * Copyright (C) 2016 Host Mobility AB. All rights reserved.
>> + *
>> + * 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.
>> + */
>> +#include <linux/clk.h>
>> +#include <linux/delay.h>
>> +#include <linux/io.h>
>> +#include <linux/module.h>
>> +#include <linux/of_device.h>
>> +#include <linux/reset.h>
>> +
>> +#define TEGRA_GMI_CONFIG               0x00
>> +#define TEGRA_GMI_CONFIG_GO            BIT(31)
>> +#define TEGRA_GMI_BUS_WIDTH_32BIT      BIT(30)
>> +#define TEGRA_GMI_MUX_MODE             BIT(28)
>> +#define TEGRA_GMI_RDY_BEFORE_DATA      BIT(24)
>> +#define TEGRA_GMI_RDY_ACTIVE_HIGH      BIT(23)
>> +#define TEGRA_GMI_ADV_ACTIVE_HIGH      BIT(22)
>> +#define TEGRA_GMI_OE_ACTIVE_HIGH       BIT(21)
>> +#define TEGRA_GMI_CS_ACTIVE_HIGH       BIT(20)
>> +#define TEGRA_GMI_CS_SELECT(x)         ((x & 0x7) << 4)
>> +
>> +#define TEGRA_GMI_TIMING0              0x10
>> +#define TEGRA_GMI_MUXED_WIDTH(x)       ((x & 0xf) << 12)
>> +#define TEGRA_GMI_HOLD_WIDTH(x)                ((x & 0xf) << 8)
>> +#define TEGRA_GMI_ADV_WIDTH(x)         ((x & 0xf) << 4)
>> +#define TEGRA_GMI_CE_WIDTH(x)          (x & 0xf)
>> +
>> +#define TEGRA_GMI_TIMING1              0x14
>> +#define TEGRA_GMI_WE_WIDTH(x)          ((x & 0xff) << 16)
>> +#define TEGRA_GMI_OE_WIDTH(x)          ((x & 0xff) << 8)
>> +#define TEGRA_GMI_WAIT_WIDTH(x)                (x & 0xff)
>> +
>> +struct tegra_gmi_priv {
>> +       void __iomem *base;
>> +       struct reset_control *rst;
>> +       struct clk *clk;
>> +
>> +       u32 snor_config;
>> +       u32 snor_timing0;
>> +       u32 snor_timing1;
>> +};
>> +
>> +static void tegra_gmi_disable(struct tegra_gmi_priv *priv)
>> +{
>> +       u32 config;
>> +
>> +       /* stop GMI operation */
>> +       config = readl(priv->base + TEGRA_GMI_CONFIG);
>> +       config &= ~TEGRA_GMI_CONFIG_GO;
>> +       writel(config, priv->base + TEGRA_GMI_CONFIG);
>> +
>> +       reset_control_assert(priv->rst);
>> +       clk_disable_unprepare(priv->clk);
>> +}
>> +
>> +static void tegra_gmi_init(struct device *dev, struct tegra_gmi_priv
>> *priv)
>> +{
>> +       writel(priv->snor_timing0, priv->base + TEGRA_GMI_TIMING0);
>> +       writel(priv->snor_timing1, priv->base + TEGRA_GMI_TIMING1);
>> +
>> +       priv->snor_config |= TEGRA_GMI_CONFIG_GO;
>> +       writel(priv->snor_config, priv->base + TEGRA_GMI_CONFIG);
>> +}
>> +
>> +static int tegra_gmi_parse_dt(struct device *dev, struct tegra_gmi_priv
>> *priv)
>> +{
>> +       struct device_node *child =
>> of_get_next_available_child(dev->of_node,
>> +               NULL);
>> +       u32 property, ranges[4];
>> +       int ret;
>> +
>> +       if (!child) {
>> +               dev_warn(dev, "no child nodes found\n");
>> +               return 0;
>
>
> Don't we want to return an error here? Otherwise, we will call
> tegra_gmi_init() with an invalid configuration.

True, we probably want that. My thought was that we might accept a
tegra-gmi node without any child nodes and just print a warning. But
since it is the child node that holds the bus configuration it makes
sense to fail probe due to no child nodes.

>
>
>> +       }
>> +
>> +       /*
>> +        * We currently only support one child device due to lack of
>> +        * chip-select address decoding. Which means that we only have one
>> +        * chip-select line from the GMI controller.
>> +        */
>> +       if (of_get_child_count(dev->of_node) > 1)
>> +               dev_warn(dev, "only one child device is supported.");
>> +
>> +       if (of_property_read_bool(child, "nvidia,snor-data-width-32bit"))
>> +               priv->snor_config |= TEGRA_GMI_BUS_WIDTH_32BIT;
>> +
>> +       if (of_property_read_bool(child, "nvidia,snor-mux-mode"))
>> +               priv->snor_config |= TEGRA_GMI_MUX_MODE;
>> +
>> +       if (of_property_read_bool(child,
>> "nvidia,snor-rdy-active-before-data"))
>> +               priv->snor_config |= TEGRA_GMI_RDY_BEFORE_DATA;
>> +
>> +       if (of_property_read_bool(child, "nvidia,snor-rdy-inv"))
>> +               priv->snor_config |= TEGRA_GMI_RDY_ACTIVE_HIGH;
>> +
>> +       if (of_property_read_bool(child, "nvidia,snor-adv-inv"))
>> +               priv->snor_config |= TEGRA_GMI_ADV_ACTIVE_HIGH;
>> +
>> +       if (of_property_read_bool(child, "nvidia,snor-oe-inv"))
>> +               priv->snor_config |= TEGRA_GMI_OE_ACTIVE_HIGH;
>> +
>> +       if (of_property_read_bool(child, "nvidia,snor-cs-inv"))
>> +               priv->snor_config |= TEGRA_GMI_CS_ACTIVE_HIGH;
>> +
>> +       /* Decode the CS# */
>> +       ret = of_property_read_u32_array(child, "ranges", ranges, 4);
>> +       if (ret < 0) {
>> +               /* Invalid binding */
>> +               if (ret == -EOVERFLOW) {
>> +                       dev_err(dev, "invalid ranges length\n");
>> +                       goto error_cs_decode;
>> +               }
>> +
>> +               /*
>> +                * If we reach here it means that the child node has an
>> empty
>> +                * ranges or it does not exist at all. Attempt to decode
>> the
>> +                * CS# from the reg property instead.
>> +                */
>> +               ret = of_property_read_u32(child, "reg", &property);
>> +               if (ret < 0) {
>> +                       dev_err(dev, "no reg property found\n");
>> +                       goto error_cs_decode;
>> +               }
>> +       } else {
>> +               property = ranges[1];
>> +       }
>> +
>> +       priv->snor_config |= TEGRA_GMI_CS_SELECT(property);
>
>
> Should we make sure the CS is a valid value before setting?

The TEGRA_GMI_CS_SELECT(x) macro will truncate any erroneous CS value.
But yeah we could do a sanity check instead and return an error if it
is invalid.

>
>
>> +
>> +       /* The default values that are provided below are reset values */
>> +       if (!of_property_read_u32(child, "nvidia,snor-muxed-width",
>> &property))
>> +               priv->snor_timing0 |= TEGRA_GMI_MUXED_WIDTH(property);
>> +       else
>> +               priv->snor_timing0 |= TEGRA_GMI_MUXED_WIDTH(1);
>> +
>> +       if (!of_property_read_u32(child, "nvidia,snor-hold-width",
>> &property))
>> +               priv->snor_timing0 |= TEGRA_GMI_HOLD_WIDTH(property);
>> +       else
>> +               priv->snor_timing0 |= TEGRA_GMI_HOLD_WIDTH(1);
>> +
>> +       if (!of_property_read_u32(child, "nvidia,snor-adv-width",
>> &property))
>> +               priv->snor_timing0 |= TEGRA_GMI_ADV_WIDTH(property);
>> +       else
>> +               priv->snor_timing0 |= TEGRA_GMI_ADV_WIDTH(1);
>> +
>> +       if (!of_property_read_u32(child, "nvidia,snor-ce-width",
>> &property))
>> +               priv->snor_timing0 |= TEGRA_GMI_CE_WIDTH(property);
>> +       else
>> +               priv->snor_timing0 |= TEGRA_GMI_CE_WIDTH(4);
>> +
>> +       if (!of_property_read_u32(child, "nvidia,snor-we-width",
>> &property))
>> +               priv->snor_timing1 |= TEGRA_GMI_WE_WIDTH(property);
>> +       else
>> +               priv->snor_timing1 |= TEGRA_GMI_WE_WIDTH(1);
>> +
>> +       if (!of_property_read_u32(child, "nvidia,snor-oe-width",
>> &property))
>> +               priv->snor_timing1 |= TEGRA_GMI_OE_WIDTH(property);
>> +       else
>> +               priv->snor_timing1 |= TEGRA_GMI_OE_WIDTH(1);
>> +
>> +       if (!of_property_read_u32(child, "nvidia,snor-wait-width",
>> &property))
>> +               priv->snor_timing1 |= TEGRA_GMI_WAIT_WIDTH(property);
>> +       else
>> +               priv->snor_timing1 |= TEGRA_GMI_WAIT_WIDTH(3);
>> +
>> +error_cs_decode:
>> +       if (ret < 0)
>> +               dev_err(dev, "failed to decode chip-select number\n");
>
>
> Nit do we need another error message here? Can we add the "failed to decode
> CS" part the earlier message?

Does it make sense to drop the two earlier messages instead and keep this one?

Best Regards
Mirza

^ permalink raw reply

* [PATCH next 1/2] media: mtk-mdp: fix video_device_release argument
From: Hans Verkuil @ 2016-11-03 12:47 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20161028075253.gdy2bbugih6oqncw@romuald.bergerie>

Hi Vincent,

On 28/10/16 09:52, Vincent Stehl? wrote:
> On Thu, Oct 27, 2016 at 10:23:24PM +0200, Vincent Stehl? wrote:
>> video_device_release() takes a pointer to struct video_device as argument.
>> Fix two call sites where the address of the pointer is passed instead.
>
> Sorry, I messed up: please ignore that "fix". The 0day robot made me
> realize this is indeed not a proper fix.
>
> The issue remains, though: we cannot call video_device_release() on the
> vdev structure member, as this will in turn call kfree(). Most probably,
> vdev needs to be dynamically allocated, or the call to
> video_device_release() dropped completely.

I prefer that vdev is dynamically allocated. There are known problems with
embedded video_device structs, so allocating it is preferred.

Minghsiu, can you do that?

Regards,

	Hans

>
> Sorry for the bad patch.
>
> Best regards,
>
> Vincent.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply

* [PATCH 6/6] ARM: dts: rockchip: add rockchip RK1108 Evaluation board
From: Andy Yan @ 2016-11-03 12:43 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478175975-11779-1-git-send-email-andy.yan@rock-chips.com>

RK1108EVB is designed by Rockchip for CVR field.
This patch add basic support for it, which can boot with
initramfs into shell.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
---

 Documentation/devicetree/bindings/arm/rockchip.txt |  3 +
 arch/arm/boot/dts/Makefile                         |  1 +
 arch/arm/boot/dts/rk1108-evb.dts                   | 69 ++++++++++++++++++++++
 3 files changed, 73 insertions(+)
 create mode 100644 arch/arm/boot/dts/rk1108-evb.dts

diff --git a/Documentation/devicetree/bindings/arm/rockchip.txt b/Documentation/devicetree/bindings/arm/rockchip.txt
index 10b92b5..8670181 100644
--- a/Documentation/devicetree/bindings/arm/rockchip.txt
+++ b/Documentation/devicetree/bindings/arm/rockchip.txt
@@ -1,5 +1,8 @@
 Rockchip platforms device tree bindings
 ---------------------------------------
+- Rockchip RK1108 Evaluation board
+    Required root node properties:
+      - compatible = "rockchip,rk1108-evb", "rockchip,rk1108";
 
 - Kylin RK3036 board:
     Required root node properties:
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index e49476a..249dca9 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -635,6 +635,7 @@ dtb-$(CONFIG_ARCH_REALVIEW) += \
 	arm-realview-pba8.dtb \
 	arm-realview-pbx-a9.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += \
+	rk1108-evb.dtb \
 	rk3036-evb.dtb \
 	rk3036-kylin.dtb \
 	rk3066a-bqcurie2.dtb \
diff --git a/arch/arm/boot/dts/rk1108-evb.dts b/arch/arm/boot/dts/rk1108-evb.dts
new file mode 100644
index 0000000..3956cff
--- /dev/null
+++ b/arch/arm/boot/dts/rk1108-evb.dts
@@ -0,0 +1,69 @@
+/*
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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.
+ *
+ *     This file 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.
+ *
+ *  Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/dts-v1/;
+
+#include "rk1108.dtsi"
+
+/ {
+	model = "Rockchip RK1108 Evaluation board";
+	compatible = "rockchip,rk1108-evb", "rockchip,rk1108";
+
+	memory at 60000000 {
+		device_type = "memory";
+		reg = <0x60000000 0x08000000>;
+	};
+
+	chosen {
+		stdout-path = "serial2:1500000n8";
+	};
+};
+
+&uart0 {
+	status = "okay";
+};
+
+&uart1 {
+	status = "okay";
+};
+
+&uart2 {
+	status = "okay";
+};
-- 
2.7.4

^ permalink raw reply related

* [PATCH 5/6] ARM: add low level debug uart for rk1108
From: Andy Yan @ 2016-11-03 12:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478175975-11779-1-git-send-email-andy.yan@rock-chips.com>

RK1108 UARTs are Synopsis DesignWare 8250 compatible.
Only with different register addresses.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
---

 arch/arm/Kconfig.debug | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index d83f7c3..408540f 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -776,6 +776,30 @@ choice
 		  their output to the standard serial port on the RealView
 		  PB1176 platform.
 
+	config DEBUG_RK1108_UART0
+		bool "Kernel low-level debugging messages via Rockchip RK1108 UART0"
+		depends on ARCH_ROCKCHIP
+		select DEBUG_UART_8250
+		help
+		  Say Y here if you want kernel low-level debugging support
+                  on Rockchip RK1108 based platforms.
+
+	config DEBUG_RK1108_UART1
+		bool "Kernel low-level debugging messages via Rockchip RK1108 UART1"
+		depends on ARCH_ROCKCHIP
+		select DEBUG_UART_8250
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on Rockchip RK1108 based platforms.
+
+	config DEBUG_RK1108_UART2
+		bool "Kernel low-level debugging messages via Rockchip RK1108 UART2"
+		depends on ARCH_ROCKCHIP
+		select DEBUG_UART_8250
+		help
+		  Say Y here if you want kernel low-level debugging support
+		  on Rockchip RK1108 based platforms.
+
 	config DEBUG_RK29_UART0
 		bool "Kernel low-level debugging messages via Rockchip RK29 UART0"
 		depends on ARCH_ROCKCHIP
@@ -1465,6 +1489,9 @@ config DEBUG_UART_PHYS
 	default 0x10126000 if DEBUG_RK3X_UART1
 	default 0x101f1000 if DEBUG_VERSATILE
 	default 0x101fb000 if DEBUG_NOMADIK_UART
+	default 0x10210000 if DEBUG_RK1108_UART2
+	default 0x10220000 if DEBUG_RK1108_UART1
+	default 0x10230000 if DEBUG_RK1108_UART0
 	default 0x11002000 if DEBUG_MT8127_UART0
 	default 0x11006000 if DEBUG_MT6589_UART0
 	default 0x11009000 if DEBUG_MT8135_UART3
@@ -1563,6 +1590,9 @@ config DEBUG_UART_PHYS
 
 config DEBUG_UART_VIRT
 	hex "Virtual base address of debug UART"
+	default 0xc881f000 if DEBUG_RK1108_UART2
+	default 0xc8821000 if DEBUG_RK1108_UART1
+	default 0xc8912000 if DEBUG_RK1108_UART0
 	default 0xe0000a00 if DEBUG_NETX_UART
 	default 0xe0010fe0 if ARCH_RPC
 	default 0xf0000be0 if ARCH_EBSA110
-- 
2.7.4

^ permalink raw reply related

* [PATCH] ARM: gr8: evb: Enable SPDIF
From: Maxime Ripard @ 2016-11-03 12:41 UTC (permalink / raw)
  To: linux-arm-kernel

The GR8-EVB has a SPDIF out connector. Enable it.

Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 arch/arm/boot/dts/ntc-gr8-evb.dts | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/arch/arm/boot/dts/ntc-gr8-evb.dts b/arch/arm/boot/dts/ntc-gr8-evb.dts
index 4b622f3b5220..e3b7a6273c61 100644
--- a/arch/arm/boot/dts/ntc-gr8-evb.dts
+++ b/arch/arm/boot/dts/ntc-gr8-evb.dts
@@ -75,6 +75,24 @@
 		brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>;
 		default-brightness-level = <8>;
 	};
+
+	spdif {
+		compatible = "simple-audio-card";
+		simple-audio-card,name = "On-board SPDIF";
+
+		simple-audio-card,cpu {
+			sound-dai = <&spdif>;
+		};
+
+		simple-audio-card,codec {
+			sound-dai = <&spdif_out>;
+		};
+	};
+
+	spdif_out: spdif-out {
+		#sound-dai-cells = <0>;
+		compatible = "linux,spdif-dit";
+	};
 };
 
 &be0 {
-- 
2.10.1

^ permalink raw reply related

* [PATCH 4/6] ARM: dts: add basic support for Rockchip RK1108 SOC
From: Andy Yan @ 2016-11-03 12:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478175975-11779-1-git-send-email-andy.yan@rock-chips.com>

RK1108 is embedded with an ARM Cortex-A7 single core and a DSP core.
It is designed for varies application scenario such as car DVR, sports
DV, secure camera and UAV camera.

This patch add basic support for it with DMAC / UART / CRU / pinctrl
enabled.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
---

 arch/arm/boot/dts/rk1108.dtsi     | 420 ++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-rockchip/rockchip.c |   1 +
 2 files changed, 421 insertions(+)
 create mode 100644 arch/arm/boot/dts/rk1108.dtsi

diff --git a/arch/arm/boot/dts/rk1108.dtsi b/arch/arm/boot/dts/rk1108.dtsi
new file mode 100644
index 0000000..9dccfea
--- /dev/null
+++ b/arch/arm/boot/dts/rk1108.dtsi
@@ -0,0 +1,420 @@
+/*
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file 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.
+ *
+ *     This file 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.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/clock/rk1108-cru.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+/ {
+	#address-cells = <1>;
+	#size-cells = <1>;
+
+	compatible = "rockchip,rk1108";
+
+	interrupt-parent = <&gic>;
+
+	aliases {
+		serial0 = &uart0;
+		serial1 = &uart1;
+		serial2 = &uart2;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		cpu0: cpu at f00 {
+			device_type = "cpu";
+			compatible = "arm,cortex-a7";
+			reg = <0xf00>;
+		};
+
+	};
+
+	amba {
+		compatible = "simple-bus";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		pdma: pdma at 102a0000 {
+			compatible = "arm,pl330", "arm,primecell";
+			reg = <0x102a0000 0x4000>;
+			interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
+			#dma-cells = <1>;
+			arm,pl330-broken-no-flushp;
+			clocks = <&cru ACLK_DMAC>;
+			clock-names = "apb_pclk";
+		};
+	};
+
+	arm-pmu {
+		compatible = "arm,cortex-a7-pmu";
+		interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+
+	timer {
+		compatible = "arm,armv7-timer";
+		interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>,
+			     <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+		clock-frequency = <24000000>;
+	};
+
+	xin24m: oscillator {
+		compatible = "fixed-clock";
+		clock-frequency = <24000000>;
+		clock-output-names = "xin24m";
+		#clock-cells = <0>;
+	};
+
+	bus_intmem at 10080000 {
+		compatible = "mmio-sram";
+		reg = <0x10080000 0x2000>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges = <0 0x10080000 0x2000>;
+	};
+
+	grf: syscon at 10300000 {
+		compatible = "rockchip,rk1108-grf", "syscon";
+		reg = <0x10300000 0x1000>;
+	};
+
+	emmc: dwmmc at 30110000 {
+		compatible = "rockchip,rk1108-dw-mshc", "rockchip,rk3288-dw-mshc";
+		clock-freq-min-max = <400000 150000000>;
+		clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
+			 <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0x30110000 0x4000>;
+		status = "disabled";
+	};
+
+	sdio: dwmmc at 30120000 {
+		compatible = "rockchip,rk1108-dw-mshc", "rockchip,rk3288-dw-mshc";
+		clock-freq-min-max = <400000 150000000>;
+		clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
+			 <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0x30120000 0x4000>;
+		status = "disabled";
+	};
+
+	sdmmc: dwmmc at 30130000 {
+		compatible = "rockchip,rk1108-dw-mshc", "rockchip,rk3288-dw-mshc";
+		clock-freq-min-max = <400000 100000000>;
+		clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
+			 <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
+		clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
+		fifo-depth = <0x100>;
+		interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+		reg = <0x30130000 0x4000>;
+		status = "disabled";
+	};
+
+	uart2: serial at 10210000 {
+		compatible = "rockchip,rk1108-uart", "snps,dw-apb-uart";
+		reg = <0x10210000 0x100>;
+		interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <24000000>;
+		clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>;
+		clock-names = "baudclk", "apb_pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart2m0_xfer>;
+		status = "disabled";
+	};
+
+	uart1: serial at 10220000 {
+		compatible = "rockchip,rk1108-uart", "snps,dw-apb-uart";
+		reg = <0x10220000 0x100>;
+		interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <24000000>;
+		clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>;
+		clock-names = "baudclk", "apb_pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart1_xfer>;
+		status = "disabled";
+	};
+
+	uart0: serial at 10230000 {
+		compatible = "rockchip,rk1108-uart", "snps,dw-apb-uart";
+		reg = <0x10230000 0x100>;
+		interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
+		reg-shift = <2>;
+		reg-io-width = <4>;
+		clock-frequency = <24000000>;
+		clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
+		clock-names = "baudclk", "apb_pclk";
+		pinctrl-names = "default";
+		pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+		status = "disabled";
+	};
+
+	cru: clock-controller at 20200000 {
+		compatible = "rockchip,rk1108-cru";
+		reg = <0x20200000 0x1000>;
+		rockchip,grf = <&grf>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+	};
+
+	gic: interrupt-controller at 32010000 {
+		compatible = "arm,cortex-a15-gic";
+		interrupt-controller;
+		#interrupt-cells = <3>;
+		#address-cells = <0>;
+
+		reg = <0x32011000 0x1000>,
+		      <0x32012000 0x1000>;
+	};
+
+	pinctrl: pinctrl {
+		compatible = "rockchip,rk1108-pinctrl";
+		rockchip,grf = <&grf>;
+		#address-cells = <1>;
+		#size-cells = <1>;
+		ranges;
+
+		gpio0: gpio0 at 20030000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x20030000 0x100>;
+			interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&xin24m>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio1: gpio1 at 10310000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x10310000 0x100>;
+			interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&xin24m>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio2: gpio2 at 10320000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x10320000 0x100>;
+			interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&xin24m>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		gpio3: gpio3 at 10330000 {
+			compatible = "rockchip,gpio-bank";
+			reg = <0x10330000 0x100>;
+			interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+			clocks = <&xin24m>;
+
+			gpio-controller;
+			#gpio-cells = <2>;
+
+			interrupt-controller;
+			#interrupt-cells = <2>;
+		};
+
+		pcfg_pull_up: pcfg-pull-up {
+			bias-pull-up;
+		};
+
+		pcfg_pull_down: pcfg-pull-down {
+			bias-pull-down;
+		};
+
+		pcfg_pull_none: pcfg-pull-none {
+			bias-disable;
+		};
+
+		pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
+			drive-strength = <8>;
+		};
+
+		pcfg_pull_none_drv_12ma: pcfg-pull-none-drv-12ma {
+			drive-strength = <12>;
+		};
+
+		pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma {
+			bias-pull-up;
+			drive-strength = <8>;
+		};
+
+		pcfg_pull_none_drv_4ma: pcfg-pull-none-drv-4ma {
+			drive-strength = <4>;
+		};
+
+		pcfg_pull_up_drv_4ma: pcfg-pull-up-drv-4ma {
+			bias-pull-up;
+			drive-strength = <4>;
+		};
+
+		pcfg_output_high: pcfg-output-high {
+			output-high;
+		};
+
+		pcfg_output_low: pcfg-output-low {
+			output-low;
+		};
+
+		pcfg_input_high: pcfg-input-high {
+			bias-pull-up;
+			input-enable;
+		};
+
+		i2c1 {
+			i2c1_xfer: i2c1-xfer {
+				rockchip,pins = <2 RK_PD3 RK_FUNC_1 &pcfg_pull_up>,
+						<2 RK_PD4 RK_FUNC_1 &pcfg_pull_up>;
+			};
+		};
+
+		i2c2m1 {
+			i2c2m1_xfer: i2c2m1-xfer {
+				rockchip,pins = <0 RK_PC2 RK_FUNC_2 &pcfg_pull_none>,
+						<0 RK_PC6 RK_FUNC_3 &pcfg_pull_none>;
+			};
+
+			i2c2m1_gpio: i2c2m1-gpio {
+				rockchip,pins = <0 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>,
+						<0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
+			};
+		};
+
+		i2c2m05v {
+			i2c2m05v_xfer: i2c2m05v-xfer {
+				rockchip,pins = <1 RK_PD5 RK_FUNC_2 &pcfg_pull_none>,
+						<1 RK_PD4 RK_FUNC_2 &pcfg_pull_none>;
+			};
+
+			i2c2m05v_gpio: i2c2m05v-gpio {
+				rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>,
+						<1 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+			};
+		};
+
+		i2c3 {
+			i2c3_xfer: i2c3-xfer {
+				rockchip,pins = <0 RK_PB6 RK_FUNC_1 &pcfg_pull_none>,
+						<0 RK_PC4 RK_FUNC_2 &pcfg_pull_none>;
+			};
+		};
+
+		uart0 {
+			uart0_xfer: uart0-xfer {
+				rockchip,pins = <3 RK_PA6 RK_FUNC_1 &pcfg_pull_up>,
+						<3 RK_PA5 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart0_cts: uart0-cts {
+				rockchip,pins = <3 RK_PA4 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart0_rts: uart0-rts {
+				rockchip,pins = <3 RK_PA3 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart0_rts_gpio: uart0-rts-gpio {
+				rockchip,pins = <3 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>;
+			};
+		};
+
+		uart1 {
+			uart1_xfer: uart1-xfer {
+				rockchip,pins = <1 RK_PD3 RK_FUNC_1 &pcfg_pull_up>,
+						<1 RK_PD2 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart1_cts: uart1-cts {
+				rockchip,pins = <1 RK_PD0 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart1_rts: uart1-rts {
+				rockchip,pins = <1 RK_PD1 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		uart2m0 {
+			uart2m0_xfer: uart2m0-xfer {
+				rockchip,pins = <2 RK_PD2 RK_FUNC_1 &pcfg_pull_up>,
+						<2 RK_PD1 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+
+		uart2m1 {
+			uart2m1_xfer: uart2m1-xfer {
+				rockchip,pins = <3 RK_PC3 RK_FUNC_2 &pcfg_pull_up>,
+						<3 RK_PC2 RK_FUNC_2 &pcfg_pull_none>;
+			};
+		};
+
+		uart2_5v {
+			uart2_5v_cts: uart2_5v-cts {
+				rockchip,pins = <1 RK_PD4 RK_FUNC_1 &pcfg_pull_none>;
+			};
+
+			uart2_5v_rts: uart2_5v-rts {
+				rockchip,pins = <1 RK_PD5 RK_FUNC_1 &pcfg_pull_none>;
+			};
+		};
+	};
+};
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
index a7ab9ec..e7fdf06 100644
--- a/arch/arm/mach-rockchip/rockchip.c
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -76,6 +76,7 @@ static void __init rockchip_dt_init(void)
 }
 
 static const char * const rockchip_board_dt_compat[] = {
+	"rockchip,rk1108",
 	"rockchip,rk2928",
 	"rockchip,rk3066a",
 	"rockchip,rk3066b",
-- 
2.7.4

^ permalink raw reply related

* [PATCH 3/6] clk: rockchip: add clock controller for rk1108
From: Andy Yan @ 2016-11-03 12:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478175975-11779-1-git-send-email-andy.yan@rock-chips.com>

From: Shawn Lin <shawn.lin@rock-chips.com>

Add the clock tree definition and driver for rk1108 SoC.

Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
---

 drivers/clk/rockchip/Makefile          |   1 +
 drivers/clk/rockchip/clk-rk1108.c      | 463 +++++++++++++++++++++++++++++++++
 drivers/clk/rockchip/clk.h             |  14 +
 include/dt-bindings/clock/rk1108-cru.h | 308 ++++++++++++++++++++++
 4 files changed, 786 insertions(+)
 create mode 100644 drivers/clk/rockchip/clk-rk1108.c
 create mode 100644 include/dt-bindings/clock/rk1108-cru.h

diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile
index b5f2c8e..16e098c 100644
--- a/drivers/clk/rockchip/Makefile
+++ b/drivers/clk/rockchip/Makefile
@@ -11,6 +11,7 @@ obj-y	+= clk-mmc-phase.o
 obj-y	+= clk-ddr.o
 obj-$(CONFIG_RESET_CONTROLLER)	+= softrst.o
 
+obj-y	+= clk-rk1108.o
 obj-y	+= clk-rk3036.o
 obj-y	+= clk-rk3188.o
 obj-y	+= clk-rk3228.o
diff --git a/drivers/clk/rockchip/clk-rk1108.c b/drivers/clk/rockchip/clk-rk1108.c
new file mode 100644
index 0000000..eafc623
--- /dev/null
+++ b/drivers/clk/rockchip/clk-rk1108.c
@@ -0,0 +1,463 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author: Shawn Lin <shawn.lin@rock-chips.com>
+ *         Andy Yan <andy.yan@rock-chips.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.
+ *
+ * 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/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
+#include <dt-bindings/clock/rk1108-cru.h>
+#include "clk.h"
+
+#define RK1108_GRF_SOC_STATUS0	0x480
+
+enum rk1108_plls {
+	apll, dpll, gpll,
+};
+
+static struct rockchip_pll_rate_table rk1108_pll_rates[] = {
+	/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+	RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
+	RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+	RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 984000000, 1, 82, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 960000000, 1, 80, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 936000000, 1, 78, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 912000000, 1, 76, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 900000000, 4, 300, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 888000000, 1, 74, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 864000000, 1, 72, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 840000000, 1, 70, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 816000000, 1, 68, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 800000000, 6, 400, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 700000000, 6, 350, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 696000000, 1, 58, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 600000000, 1, 75, 3, 1, 1, 0),
+	RK3036_PLL_RATE( 594000000, 2, 99, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 504000000, 1, 63, 3, 1, 1, 0),
+	RK3036_PLL_RATE( 500000000, 6, 250, 2, 1, 1, 0),
+	RK3036_PLL_RATE( 408000000, 1, 68, 2, 2, 1, 0),
+	RK3036_PLL_RATE( 312000000, 1, 52, 2, 2, 1, 0),
+	RK3036_PLL_RATE( 216000000, 1, 72, 4, 2, 1, 0),
+	RK3036_PLL_RATE(  96000000, 1, 64, 4, 4, 1, 0),
+	{ /* sentinel */ },
+};
+
+
+#define RK1108_DIV_CORE_MASK		0xf
+#define RK1108_DIV_CORE_SHIFT		4
+
+#define RK1108_CLKSEL0(_core_peri_div)					\
+	{									\
+		.reg = RK1108_CLKSEL_CON(1),					\
+		.val = HIWORD_UPDATE(_core_peri_div, RK1108_DIV_CORE_MASK,	\
+				RK1108_DIV_CORE_SHIFT)				\
+	}
+
+#define RK1108_CPUCLK_RATE(_prate, _core_peri_div)			\
+	{								\
+		.prate = _prate,					\
+		.divs = {						\
+			RK1108_CLKSEL0(_core_peri_div),		\
+		},							\
+	}
+
+static struct rockchip_cpuclk_rate_table rk1108_cpuclk_rates[] __initdata = {
+	RK1108_CPUCLK_RATE(816000000, 4),
+	RK1108_CPUCLK_RATE(600000000, 4),
+	RK1108_CPUCLK_RATE(312000000, 4),
+};
+
+static const struct rockchip_cpuclk_reg_data rk1108_cpuclk_data = {
+	.core_reg = RK1108_CLKSEL_CON(0),
+	.div_core_shift = 0,
+	.div_core_mask = 0x1f,
+	.mux_core_alt = 1,
+	.mux_core_main = 0,
+	.mux_core_shift = 8,
+	.mux_core_mask = 0x1,
+};
+
+PNAME(mux_pll_p)		= { "xin24m", "xin24m"};
+
+PNAME(mux_ddrphy_p)		= { "dpll_ddr", "gpll_ddr", "apll_ddr" };
+PNAME(mux_armclk_p)		= { "apll_core", "gpll_core", "dpll_core" };
+PNAME(mux_pmu_1f)		= { "xin24m", "pmu_24m"};
+PNAME(mux_usb480m_phy_p)	= { "usb480m_phy0", "usb480m_phy1" };
+PNAME(mux_usb480m_p)		= { "usb480m_phy", "xin24m" };
+PNAME(mux_hdmiphy_p)		= { "hdmiphy_phy", "pclk_top_pre", "xin24m" };
+
+PNAME(mux_pll_src_4plls_p)	= { "dpll", "hdmiphy", "gpll", "usb480m" };
+PNAME(mux_pll_src_3plls_p)	= { "apll", "gpll", "dpll" };
+PNAME(mux_pll_src_2plls_p)	= { "dpll", "gpll" };
+
+PNAME(mux_aclk_peri_src_p)	= { "aclk_peri_src_dpll", "aclk_peri_src_gpll" };
+PNAME(mux_aclk_bus_src_p)	= { "aclk_bus_src_gpll", "aclk_bus_src_apll", "aclk_bus_src_dpll" };
+
+PNAME(mux_mmc_src_p)		= { "dpll", "gpll", "xin24m", "usb480m" };
+PNAME(mux_pll_src_dpll_gpll_usb480m_p)	= { "dpll", "gpll", "usb480m" };
+
+
+PNAME(mux_uart0_p)		= { "uart0_src", "uart0_frac", "xin24m" };
+PNAME(mux_uart1_p)		= { "uart1_src", "uart1_frac", "xin24m" };
+PNAME(mux_uart2_p)		= { "uart2_src", "uart2_frac", "xin24m" };
+
+
+static struct rockchip_pll_clock rk1108_pll_clks[] __initdata = {
+	[apll] = PLL(pll_rk3399, RK1108_APLL_ID, "apll", mux_pll_p, 0, RK1108_PLL_CON(0),
+		     RK1108_PLL_CON(3), 8, 31, 0, rk1108_pll_rates),
+	[dpll] = PLL(pll_rk3399, RK1108_DPLL_ID, "dpll", mux_pll_p, 0, RK1108_PLL_CON(8),
+		     RK1108_PLL_CON(11), 8, 31, 0, NULL),
+	[gpll] = PLL(pll_rk3399, RK1108_GPLL_ID, "gpll", mux_pll_p, 0, RK1108_PLL_CON(16),
+		     RK1108_PLL_CON(19), 8, 31, ROCKCHIP_PLL_SYNC_RATE, rk1108_pll_rates),
+};
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+
+static struct rockchip_clk_branch rk1108_uart0_fracmux __initdata =
+	MUX(SCLK_UART0, "sclk_uart0", mux_uart0_p, CLK_SET_RATE_PARENT,
+			RK1108_CLKSEL_CON(13), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk1108_uart1_fracmux __initdata =
+	MUX(SCLK_UART1, "sclk_uart1", mux_uart1_p, CLK_SET_RATE_PARENT,
+			RK1108_CLKSEL_CON(14), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk1108_uart2_fracmux __initdata =
+	MUX(SCLK_UART2, "sclk_uart2", mux_uart2_p, CLK_SET_RATE_PARENT,
+			RK1108_CLKSEL_CON(15), 8, 2, MFLAGS);
+
+static struct rockchip_clk_branch rk1108_clk_branches[] __initdata = {
+	/*
+	 * Clock-Architecture Diagram 2
+	 */
+
+	/* PD_CORE */
+	GATE(0, "dpll_core", "dpll", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(0), 1, GFLAGS),
+	GATE(0, "apll_core", "apll", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(0), 0, GFLAGS),
+	GATE(0, "gpll_core", "gpll", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(0), 2, GFLAGS),
+	COMPOSITE_NOMUX(0, "pclken_dbg", "armclk", CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(1), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK1108_CLKGATE_CON(0), 5, GFLAGS),
+	COMPOSITE_NOMUX(ACLK_ENMCORE, "aclkenm_core", "armclk", CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(1), 0, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
+			RK1108_CLKGATE_CON(0), 4, GFLAGS),
+	GATE(ACLK_CORE, "aclk_core", "aclkenm_core", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(11), 0, GFLAGS),
+	GATE(0, "pclk_dbg", "pclken_dbg", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(11), 1, GFLAGS),
+
+	/* PD_RKVENC */
+
+	/* PD_RKVDEC */
+
+	/* PD_PMU_wrapper */
+	COMPOSITE_NOMUX(0, "pmu_24m_ena", "gpll", CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(38), 0, 5, DFLAGS,
+			RK1108_CLKGATE_CON(8), 12, GFLAGS),
+	GATE(0, "pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(10), 0, GFLAGS),
+	GATE(0, "intmem1", "pmu_24m_ena", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(10), 1, GFLAGS),
+	GATE(0, "gpio0_pmu", "pmu_24m_ena", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(10), 2, GFLAGS),
+	GATE(0, "pmugrf", "pmu_24m_ena", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(10), 3, GFLAGS),
+	GATE(0, "pmu_noc", "pmu_24m_ena", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(10), 4, GFLAGS),
+	GATE(0, "i2c0_pmu_pclk", "pmu_24m_ena", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(10), 5, GFLAGS),
+	GATE(0, "pwm0_pmu_pclk", "pmu_24m_ena", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(10), 6, GFLAGS),
+	COMPOSITE(0, "pwm0_pmu_clk", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(12), 7, 1, MFLAGS, 0, 7, DFLAGS,
+			RK1108_CLKGATE_CON(8), 15, GFLAGS),
+	COMPOSITE(0, "i2c0_pmu_clk", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(19), 7, 1, MFLAGS, 0, 7, DFLAGS,
+			RK1108_CLKGATE_CON(8), 14, GFLAGS),
+	GATE(0, "pvtm_pmu", "xin24m", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(8), 13, GFLAGS),
+
+
+
+	/*
+	 * Clock-Architecture Diagram 4
+	 */
+	COMPOSITE(0, "aclk_vio0_2wrap_occ", mux_pll_src_4plls_p, CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(28), 6, 2, MFLAGS, 0, 5, DFLAGS,
+			RK1108_CLKGATE_CON(6), 0, GFLAGS),
+	GATE(0, "aclk_vio0_pre", "aclk_vio0_2wrap_occ", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(17), 0, GFLAGS),
+	COMPOSITE_NOMUX(0, "hclk_vio_pre", "aclk_vio0_pre", 0,
+			RK1108_CLKSEL_CON(29), 0, 5, DFLAGS,
+			RK1108_CLKGATE_CON(7), 2, GFLAGS),
+	COMPOSITE_NOMUX(0, "pclk_vio_pre", "aclk_vio0_pre", 0,
+			RK1108_CLKSEL_CON(29), 8, 5, DFLAGS,
+			RK1108_CLKGATE_CON(7), 3, GFLAGS),
+
+
+	/*
+	 * Clock-Architecture Diagram 5
+	 */
+
+	/* PD_BUS */
+	GATE(0, "aclk_bus_src_gpll", "gpll", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(1), 0, GFLAGS),
+	GATE(0, "aclk_bus_src_apll", "apll", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(1), 1, GFLAGS),
+	GATE(0, "aclk_bus_src_dpll", "dpll", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(1), 2, GFLAGS),
+	COMPOSITE_NOGATE(ACLK_PRE, "aclk_bus_pre", mux_aclk_bus_src_p, 0,
+			RK1108_CLKSEL_CON(2), 8, 2, MFLAGS, 0, 5, DFLAGS),
+	COMPOSITE_NOMUX(0, "hclk_bus_pre", "aclk_bus_2wrap_occ", 0,
+			RK1108_CLKSEL_CON(3), 0, 5, DFLAGS,
+			RK1108_CLKGATE_CON(1), 4, GFLAGS),
+	COMPOSITE_NOMUX(0, "pclken_bus", "aclk_bus_2wrap_occ", 0,
+			RK1108_CLKSEL_CON(3), 8, 5, DFLAGS,
+			RK1108_CLKGATE_CON(1), 5, GFLAGS),
+	GATE(0, "pclk_bus_pre", "pclken_bus", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(1), 6, GFLAGS),
+	GATE(0, "pclk_top_pre", "pclken_bus", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(1), 7, GFLAGS),
+	GATE(0, "pclk_ddr_pre", "pclken_bus", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(1), 8, GFLAGS),
+	GATE(0, "clk_timer0", "mux_pll_p", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(1), 9, GFLAGS),
+	GATE(0, "clk_timer1", "mux_pll_p", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(1), 10, GFLAGS),
+	GATE(0, "pclk_timer", "pclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(13), 4, GFLAGS),
+
+	COMPOSITE(0, "uart0_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(13), 12, 2, MFLAGS, 0, 7, DFLAGS,
+			RK1108_CLKGATE_CON(3), 1, GFLAGS),
+	COMPOSITE(0, "uart1_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(14), 12, 2, MFLAGS, 0, 7, DFLAGS,
+			RK1108_CLKGATE_CON(3), 3, GFLAGS),
+	COMPOSITE(0, "uart21_src", mux_pll_src_dpll_gpll_usb480m_p, CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(15), 12, 2, MFLAGS, 0, 7, DFLAGS,
+			RK1108_CLKGATE_CON(3), 5, GFLAGS),
+
+	COMPOSITE_FRACMUX(0, "uart0_frac", "uart0_src", CLK_SET_RATE_PARENT,
+			RK1108_CLKSEL_CON(16), 0,
+			RK1108_CLKGATE_CON(3), 2, GFLAGS,
+			&rk1108_uart0_fracmux),
+	COMPOSITE_FRACMUX(0, "uart1_frac", "uart1_src", CLK_SET_RATE_PARENT,
+			RK1108_CLKSEL_CON(17), 0,
+			RK1108_CLKGATE_CON(3), 4, GFLAGS,
+			&rk1108_uart1_fracmux),
+	COMPOSITE_FRACMUX(0, "uart2_frac", "uart2_src", CLK_SET_RATE_PARENT,
+			RK1108_CLKSEL_CON(18), 0,
+			RK1108_CLKGATE_CON(3), 6, GFLAGS,
+			&rk1108_uart2_fracmux),
+	GATE(PCLK_UART0, "pclk_uart0", "pclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(13), 10, GFLAGS),
+	GATE(PCLK_UART1, "pclk_uart1", "pclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(13), 11, GFLAGS),
+	GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(13), 12, GFLAGS),
+
+
+	COMPOSITE(0, "clk_i2c1", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(19), 15, 2, MFLAGS, 8, 7, DFLAGS,
+			RK1108_CLKGATE_CON(3), 7, GFLAGS),
+	COMPOSITE(0, "clk_i2c2", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(20), 7, 2, MFLAGS, 0, 7, DFLAGS,
+			RK1108_CLKGATE_CON(3), 8, GFLAGS),
+	COMPOSITE(0, "clk_i2c3", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(20), 15, 2, MFLAGS, 8, 7, DFLAGS,
+			RK1108_CLKGATE_CON(3), 9, GFLAGS),
+	GATE(0, "pclk_i2c1", "pclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(13), 0, GFLAGS),
+	GATE(0, "pclk_i2c2", "pclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(13), 1, GFLAGS),
+	GATE(0, "pclk_i2c3", "pclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(13), 2, GFLAGS),
+	COMPOSITE(0, "clk_pwm1", mux_pll_src_2plls_p, CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(12), 15, 2, MFLAGS, 8, 7, DFLAGS,
+			RK1108_CLKGATE_CON(3), 10, GFLAGS),
+	GATE(0, "pclk_pwm1", "pclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(13), 6, GFLAGS),
+	GATE(0, "pclk_wdt", "pclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(13), 3, GFLAGS),
+	GATE(0, "pclk_gpio1", "pclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(13), 7, GFLAGS),
+	GATE(0, "pclk_gpio2", "pclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(13), 8, GFLAGS),
+	GATE(0, "pclk_gpio3", "pclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(13), 9, GFLAGS),
+
+	GATE(0, "pclk_grf", "pclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(14), 0, GFLAGS),
+
+	GATE(ACLK_DMAC, "aclk_dmac", "aclk_bus_pre", 0,
+	     RK1108_CLKGATE_CON(12), 2, GFLAGS),
+	GATE(0, "hclk_rom", "hclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(12), 3, GFLAGS),
+	GATE(0, "aclk_intmem", "aclk_bus_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(12), 1, GFLAGS),
+
+	/* PD_DDR */
+	GATE(0, "apll_ddr", "apll", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(0), 8, GFLAGS),
+	GATE(0, "dpll_ddr", "dpll", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(0), 9, GFLAGS),
+	GATE(0, "gpll_ddr", "gpll", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(0), 10, GFLAGS),
+	COMPOSITE(0, "ddrphy4x", mux_ddrphy_p, CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(4), 8, 2, MFLAGS, 0, 3, DFLAGS | CLK_DIVIDER_POWER_OF_TWO,
+			RK1108_CLKGATE_CON(10), 9, GFLAGS),
+	GATE(0, "ddrupctl", "ddrphy_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(12), 4, GFLAGS),
+	GATE(0, "ddrc", "ddrphy", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(12), 5, GFLAGS),
+	GATE(0, "ddrmon", "ddrphy_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(12), 6, GFLAGS),
+	GATE(0, "timer_clk", "xin24m", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(0), 11, GFLAGS),
+
+	/*
+	 * Clock-Architecture Diagram 6
+	 */
+
+	/* PD_PERI */
+	COMPOSITE_NOMUX(0, "pclk_periph_pre", "gpll", 0,
+			RK1108_CLKSEL_CON(23), 10, 5, DFLAGS,
+			RK1108_CLKGATE_CON(4), 5, GFLAGS),
+	GATE(0, "pclk_periph", "pclk_periph_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(15), 13, GFLAGS),
+	COMPOSITE_NOMUX(0, "hclk_periph_pre", "gpll", 0,
+			RK1108_CLKSEL_CON(23), 5, 5, DFLAGS,
+			RK1108_CLKGATE_CON(4), 4, GFLAGS),
+	GATE(0, "hclk_periph", "hclk_periph_pre", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(15), 12, GFLAGS),
+
+	GATE(0, "aclk_peri_src_dpll", "dpll", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(4), 1, GFLAGS),
+	GATE(0, "aclk_peri_src_gpll", "gpll", CLK_IGNORE_UNUSED,
+			RK1108_CLKGATE_CON(4), 2, GFLAGS),
+	COMPOSITE(0, "aclk_periph", mux_aclk_peri_src_p, CLK_IGNORE_UNUSED,
+			RK1108_CLKSEL_CON(23), 15, 2, MFLAGS, 0, 5, DFLAGS,
+			RK1108_CLKGATE_CON(15), 11, GFLAGS),
+
+	COMPOSITE(SCLK_SDMMC, "sclk_sdmmc0", mux_mmc_src_p, 0,
+			RK1108_CLKSEL_CON(25), 8, 2, MFLAGS, 0, 8, DFLAGS,
+			RK1108_CLKGATE_CON(5), 0, GFLAGS),
+
+	COMPOSITE_NODIV(0, "sclk_sdio_src", mux_mmc_src_p, 0,
+			RK1108_CLKSEL_CON(25), 10, 2, MFLAGS,
+			RK1108_CLKGATE_CON(5), 2, GFLAGS),
+	DIV(SCLK_SDIO, "sclk_sdio", "sclk_sdio_src", 0,
+			RK1108_CLKSEL_CON(26), 0, 8, DFLAGS),
+
+	COMPOSITE_NODIV(0, "sclk_emmc_src", mux_mmc_src_p, 0,
+			RK1108_CLKSEL_CON(25), 12, 2, MFLAGS,
+			RK1108_CLKGATE_CON(5), 1, GFLAGS),
+	DIV(SCLK_EMMC, "sclk_emmc", "sclk_emmc_src", 0,
+			RK2928_CLKSEL_CON(26), 8, 8, DFLAGS),
+	GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 0, GFLAGS),
+	GATE(HCLK_SDIO, "hclk_sdio", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 1, GFLAGS),
+	GATE(HCLK_EMMC, "hclk_emmc", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 2, GFLAGS),
+
+	COMPOSITE(SCLK_NANDC, "sclk_nandc", mux_pll_src_2plls_p, 0,
+			RK1108_CLKSEL_CON(27), 14, 2, MFLAGS, 8, 5, DFLAGS,
+			RK1108_CLKGATE_CON(5), 3, GFLAGS),
+	GATE(HCLK_NANDC, "hclk_nandc", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 3, GFLAGS),
+
+	COMPOSITE(SCLK_SFC, "sclk_sfc", mux_pll_src_2plls_p, 0,
+			RK1108_CLKSEL_CON(27), 7, 2, MFLAGS, 0, 7, DFLAGS,
+			RK1108_CLKGATE_CON(5), 4, GFLAGS),
+	GATE(HCLK_SFC, "hclk_sfc", "hclk_periph", 0, RK1108_CLKGATE_CON(15), 10, GFLAGS),
+	MMC(SCLK_SDMMC_DRV,    "sdmmc_drv",    "sclk_sdmmc", RK1108_SDMMC_CON0, 1),
+	MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "sclk_sdmmc", RK1108_SDMMC_CON1, 1),
+
+	MMC(SCLK_SDIO_DRV,     "sdio_drv",     "sclk_sdio",  RK1108_SDIO_CON0,  1),
+	MMC(SCLK_SDIO_SAMPLE,  "sdio_sample",  "sclk_sdio",  RK1108_SDIO_CON1,  1),
+
+	MMC(SCLK_EMMC_DRV,     "emmc_drv",     "sclk_emmc",  RK1108_EMMC_CON0,  1),
+	MMC(SCLK_EMMC_SAMPLE,  "emmc_sample",  "sclk_emmc",  RK1108_EMMC_CON1,  1),
+};
+
+static const char *const rk1108_critical_clocks[] __initconst = {
+	"aclk_core",
+	"aclk_bus_src_gpll",
+	"aclk_periph",
+	"hclk_periph",
+	"pclk_periph",
+};
+
+static void __init rk1108_clk_init(struct device_node *np)
+{
+	struct rockchip_clk_provider *ctx;
+	void __iomem *reg_base;
+
+	reg_base = of_iomap(np, 0);
+	if (!reg_base) {
+		pr_err("%s: could not map cru region\n", __func__);
+		return;
+	}
+
+	ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
+	if (IS_ERR(ctx)) {
+		pr_err("%s: rockchip clk init failed\n", __func__);
+		iounmap(reg_base);
+		return;
+	}
+
+	rockchip_clk_register_plls(ctx, rk1108_pll_clks,
+				   ARRAY_SIZE(rk1108_pll_clks),
+				   RK1108_GRF_SOC_STATUS0);
+	rockchip_clk_register_branches(ctx, rk1108_clk_branches,
+				  ARRAY_SIZE(rk1108_clk_branches));
+	rockchip_clk_protect_critical(rk1108_critical_clocks,
+				      ARRAY_SIZE(rk1108_critical_clocks));
+
+	rockchip_clk_register_armclk(ctx, RK1108_ARMCLK, "armclk",
+			mux_armclk_p, ARRAY_SIZE(mux_armclk_p),
+			&rk1108_cpuclk_data, rk1108_cpuclk_rates,
+			ARRAY_SIZE(rk1108_cpuclk_rates));
+
+	rockchip_register_softrst(np, 13, reg_base + RK1108_SOFTRST_CON(0),
+				  ROCKCHIP_SOFTRST_HIWORD_MASK);
+
+	rockchip_register_restart_notifier(ctx, RK1108_GLB_SRST_FST, NULL);
+
+	rockchip_clk_of_add_provider(np, ctx);
+}
+CLK_OF_DECLARE(rk1108_cru, "rockchip,rk1108-cru", rk1108_clk_init);
diff --git a/drivers/clk/rockchip/clk.h b/drivers/clk/rockchip/clk.h
index 1653edd..90c580a 100644
--- a/drivers/clk/rockchip/clk.h
+++ b/drivers/clk/rockchip/clk.h
@@ -34,6 +34,20 @@ struct clk;
 #define HIWORD_UPDATE(val, mask, shift) \
 		((val) << (shift) | (mask) << ((shift) + 16))
 
+/* register positions shared by RK1108, RK2928, RK3036, RK3066, RK3188 and RK3228 */
+#define RK1108_PLL_CON(x)		((x) * 0x4)
+#define RK1108_CLKSEL_CON(x)		((x) * 0x4 + 0x60)
+#define RK1108_CLKGATE_CON(x)		((x) * 0x4 + 0x120)
+#define RK1108_SOFTRST_CON(x)		((x) * 0x4 + 0x180)
+#define RK1108_GLB_SRST_FST		0x1c0
+#define RK1108_GLB_SRST_SND		0x1c4
+#define RK1108_SDMMC_CON0		0x1d8
+#define RK1108_SDMMC_CON1		0x1dc
+#define RK1108_SDIO_CON0		0x1e0
+#define RK1108_SDIO_CON1		0x1e4
+#define RK1108_EMMC_CON0		0x1e8
+#define RK1108_EMMC_CON1		0x1ec
+
 #define RK2928_PLL_CON(x)		((x) * 0x4)
 #define RK2928_MODE_CON		0x40
 #define RK2928_CLKSEL_CON(x)	((x) * 0x4 + 0x44)
diff --git a/include/dt-bindings/clock/rk1108-cru.h b/include/dt-bindings/clock/rk1108-cru.h
new file mode 100644
index 0000000..e731cc8
--- /dev/null
+++ b/include/dt-bindings/clock/rk1108-cru.h
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2016 Rockchip Electronics Co. Ltd.
+ * Author:
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK1108_H
+#define _DT_BINDINGS_CLK_ROCKCHIP_RK1108_H
+
+/* pll id */
+#define RK1108_APLL_ID			0
+#define RK1108_DPLL_ID			1
+#define RK1108_GPLL_ID			2
+#define RK1108_ARMCLK			3
+#define RK1108_END_PLL_ID		4
+
+/* sclk gates (special clocks) */
+#define SCLK_SPI0			65
+#define SCLK_NANDC			67
+#define SCLK_SDMMC			68
+#define SCLK_SDIO			69
+#define SCLK_EMMC			71
+#define SCLK_UART0			72
+#define SCLK_UART1			73
+#define SCLK_UART2			74
+#define SCLK_I2S0			75
+#define SCLK_I2S1			76
+#define SCLK_I2S2			77
+#define SCLK_TIMER0			78
+#define SCLK_TIMER1			79
+#define SCLK_SFC			80
+#define SCLK_SDMMC_DRV			81
+#define SCLK_SDIO_DRV			82
+#define SCLK_EMMC_DRV			83
+#define SCLK_SDMMC_SAMPLE		84
+#define SCLK_SDIO_SAMPLE		85
+#define SCLK_EMMC_SAMPLE		86
+
+/* aclk gates */
+#define ACLK_DMAC			251
+#define ACLK_PRE			252
+#define ACLK_CORE			253
+#define ACLK_ENMCORE			254
+
+/* pclk gates */
+#define PCLK_GPIO1			321
+#define PCLK_GPIO2			322
+#define PCLK_GPIO3			323
+#define PCLK_GRF			329
+#define PCLK_I2C1			333
+#define PCLK_I2C2			334
+#define PCLK_I2C3			335
+#define PCLK_SPI			338
+#define PCLK_SFC			339
+#define PCLK_UART0			341
+#define PCLK_UART1			342
+#define PCLK_UART2			343
+#define PCLK_TSADC			344
+#define PCLK_PWM			350
+#define PCLK_TIMER			353
+#define PCLK_PERI			363
+
+/* hclk gates */
+#define HCLK_I2S0_8CH			442
+#define HCLK_I2S1_8CH			443
+#define HCLK_I2S2_2CH			444
+#define HCLK_NANDC			453
+#define HCLK_SDMMC			456
+#define HCLK_SDIO			457
+#define HCLK_EMMC			459
+#define HCLK_PERI			478
+#define HCLK_SFC			479
+
+#define CLK_NR_CLKS			(HCLK_SFC + 1)
+
+/* reset id */
+#define SRST_CORE_PO_AD			0
+#define SRST_CORE_AD			1
+#define SRST_L2_AD			2
+#define SRST_CPU_NIU_AD			3
+#define SRST_CORE_PO			4
+#define SRST_CORE			5
+#define SRST_L2				6
+#define RST_0RES7			7
+#define SRST_CORE_DBG			8
+#define PRST_DBG			9
+#define RST_DAP				10
+#define PRST_DBG_NIU			11
+#define RST_0RES12			12
+#define RST_0RES13			13
+#define RST_0RES14			14
+#define ARST_STRC_SYS_AD		15
+
+#define SRST_DDRPHY_CLKDIV		16
+#define SRST_DDRPHY			17
+#define PRST_DDRPHY			18
+#define PRST_HDMIPHY			19
+#define PRST_VDACPHY			20
+#define PRST_VADCPHY			21
+#define PRST_MIPI_CSI_PHY		22
+#define PRST_MIPI_DSI_PHY		23
+#define PRST_ACODEC			24
+#define ARST_BUS_NIU			25
+#define PRST_TOP_NIU			26
+#define ARST_INTMEM			27
+#define HRST_ROM			28
+#define ARST_DMAC			29
+#define SRST_MSCH_NIU			30
+#define PRST_MSCH_NIU			31
+
+#define PRST_DDRUPCTL			32
+#define NRST_DDRUPCTL			33
+#define PRST_DDRMON			34
+#define HRST_I2S0_8CH			35
+#define MRST_I2S0_8CH			36
+#define HRST_I2S1_2CH			37
+#define MRST_IS21_2CH			38
+#define HRST_I2S2_2CH			39
+#define MRST_I2S2_2CH			40
+#define HRST_CRYPTO			41
+#define SRST_CRYPTO			42
+#define PRST_SPI			43
+#define SRST_SPI			44
+#define PRST_UART0			45
+#define PRST_UART1			46
+#define PRST_UART2			47
+
+#define SRST_UART0			48
+#define SRST_UART1			49
+#define SRST_UART2			50
+#define PRST_I2C1			51
+#define PRST_I2C2			52
+#define PRST_I2C3			53
+#define SRST_I2C1			54
+#define SRST_I2C2			55
+#define SRST_I2C3			56
+#define RST_3RES9			57
+#define PRST_PWM1			58
+#define RST_3RES11			59
+#define SRST_PWM1			60
+#define PRST_WDT			61
+#define PRST_GPIO1			62
+#define PRST_GPIO2			63
+
+#define PRST_GPIO3			64
+#define PRST_GRF			65
+#define PRST_EFUSE			66
+#define PRST_EFUSE512			67
+#define PRST_TIMER0			68
+#define SRST_TIMER0			69
+#define SRST_TIMER1			70
+#define PRST_TSADC			71
+#define SRST_TSADC			72
+#define PRST_SARADC			73
+#define SRST_SARADC			74
+#define HRST_SYSBUS			75
+#define PRST_USBGRF			76
+#define RST_4RES13			77
+#define RST_4RES14			78
+#define RST_4RES15			79
+
+#define ARST_PERIPH_NIU			80
+#define HRST_PERIPH_NIU			81
+#define PRST_PERIPH_NIU			82
+#define HRST_PERIPH			83
+#define HRST_SDMMC			84
+#define HRST_SDIO			85
+#define HRST_EMMC			86
+#define HRST_NANDC			87
+#define NRST_NANDC			88
+#define HRST_SFC			89
+#define SRST_SFC			90
+#define ARST_GMAC			91
+#define HRST_OTG			92
+#define SRST_OTG			93
+#define SRST_OTG_ADP			94
+#define HRST_HOST0			95
+
+#define HRST_HOST0_AUX			96
+#define HRST_HOST0_ARB			97
+#define SRST_HOST0_EHCIPHY		98
+#define SRST_HOST0_UTMI			99
+#define SRST_USBPOR			100
+#define SRST_UTMI0			101
+#define SRST_UTMI1			102
+#define RST_6RES7			103
+#define RST_6RES8			104
+#define RST_6RES9			105
+#define RST_6RES10			106
+#define RST_6RES11			107
+#define RST_6RES12			108
+#define RST_6RES13			109
+#define RST_6RES14			110
+#define RST_6RES15			101
+
+#define ARST_VIO0_NIU			102
+#define ARST_VIO1_NIU			103
+#define HRST_VIO_NIU			104
+#define PRST_VIO_NIU			105
+#define ARST_VOP			106
+#define HRST_VOP			107
+#define DRST_VOP			108
+#define ARST_IEP			109
+#define HRST_IEP			110
+#define ARST_RGA			111
+#define HRST_RGA			112
+#define SRST_RGA			113
+#define PRST_CVBS			114
+#define PRST_HDMI			115
+#define SRST_HDMI			116
+#define PRST_MIPI_DSI			117
+
+#define ARST_ISP_NIU			118
+#define HRST_ISP_NIU			119
+#define HRST_ISP			120
+#define SRST_ISP			121
+#define ARST_VIP0			122
+#define HRST_VIP0			123
+#define PRST_VIP0			124
+#define ARST_VIP1			125
+#define HRST_VIP1			126
+#define PRST_VIP1			127
+#define ARST_VIP2			128
+#define HRST_VIP2			129
+#define PRST_VIP2			120
+#define ARST_VIP3			121
+#define HRST_VIP3			122
+#define PRST_VIP4			123
+
+#define PRST_CIF1TO4			124
+#define SRST_CVBS_CLK			125
+#define HRST_CVBS			126
+#define RST_9RES3			127
+#define RST_9RES4			128
+#define RST_9RES5			129
+#define RST_9RES6			130
+#define RST_9RES7			131
+#define RST_9RES8			132
+#define RST_9RES9			133
+#define RST_9RES10			134
+#define RST_9RES11			134
+#define RST_9RES12			136
+#define RST_9RES13			137
+#define RST_9RES14			138
+#define RST_9RES15			139
+
+#define ARST_VPU_NIU			140
+#define HRST_VPU_NIU			141
+#define ARST_VPU			142
+#define HRST_VPU			143
+#define ARST_RKVDEC_NIU			144
+#define HRST_RKVDEC_NIU			145
+#define ARST_RKVDEC			146
+#define HRST_RKVDEC			147
+#define SRST_RKVDEC_CABAC		148
+#define SRST_RKVDEC_CORE		149
+#define ARST_RKVENC_NIU			150
+#define HRST_RKVENC_NIU			151
+#define ARST_RKVENC			152
+#define HRST_RKVENC			153
+#define SRST_RKVENC_CORE		154
+#define RST_10RES15			155
+
+#define SRST_DSP_CORE			156
+#define SRST_DSP_SYS			157
+#define SRST_DSP_GLOBAL			158
+#define SRST_DSP_OECM			159
+#define PRST_DSP_IOP_NIU		160
+#define ARST_DSP_EPP_NIU		161
+#define ARST_DSP_EDP_NIU		162
+#define PRST_DSP_DBG_NIU		163
+#define PRST_DSP_CFG_NIU		164
+#define PRST_DSP_GRF			165
+#define PRST_DSP_MAILBOX		166
+#define PRST_DSP_INTC			167
+#define RST_11RES12			168
+#define PRST_DSP_PFM_MON		169
+#define SRST_DSP_PFM_MON		170
+#define ARST_DSP_EDAP_NIU		171
+
+#define SRST_PMU			172
+#define SRST_PMU_I2C0			173
+#define PRST_PMU_I2C0			174
+#define PRST_PMU_GPIO0			175
+#define PRST_PMU_INTMEM			176
+#define PRST_PMU_PWM0			177
+#define SRST_PMU_PWM0			178
+#define PRST_PMU_GRF			179
+#define SRST_PMU_NIU			180
+#define SRST_PMU_PVTM			181
+#define RST_12RES10			182
+#define RST_12RES11			183
+#define ARST_DSP_EDP_PERF		184
+#define ARST_DSP_EPP_PERF		185
+#define RST_12RES114			186
+#define RST_12RES15			187
+
+#endif /* _DT_BINDINGS_CLK_ROCKCHIP_RK1108_H */
+
-- 
2.7.4

^ permalink raw reply related

* [PATCH 2/6] pinctrl: rockchip: add support for rk1108
From: Andy Yan @ 2016-11-03 12:34 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478175975-11779-1-git-send-email-andy.yan@rock-chips.com>

Add basic support for rk1108 soc

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
---

 drivers/pinctrl/pinctrl-rockchip.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 49bf7dc..9f324b1 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -59,6 +59,7 @@
 #define GPIO_LS_SYNC		0x60
 
 enum rockchip_pinctrl_type {
+	RK1108,
 	RK2928,
 	RK3066B,
 	RK3188,
@@ -1123,6 +1124,7 @@ static int rockchip_get_pull(struct rockchip_pin_bank *bank, int pin_num)
 		return !(data & BIT(bit))
 				? PIN_CONFIG_BIAS_PULL_PIN_DEFAULT
 				: PIN_CONFIG_BIAS_DISABLE;
+	case RK1108:
 	case RK3188:
 	case RK3288:
 	case RK3368:
@@ -1169,6 +1171,7 @@ static int rockchip_set_pull(struct rockchip_pin_bank *bank,
 
 		spin_unlock_irqrestore(&bank->slock, flags);
 		break;
+	case RK1108:
 	case RK3188:
 	case RK3288:
 	case RK3368:
@@ -1358,6 +1361,7 @@ static bool rockchip_pinconf_pull_valid(struct rockchip_pin_ctrl *ctrl,
 					pull == PIN_CONFIG_BIAS_DISABLE);
 	case RK3066B:
 		return pull ? false : true;
+	case RK1108:
 	case RK3188:
 	case RK3288:
 	case RK3368:
@@ -1385,7 +1389,6 @@ static int rockchip_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
 	for (i = 0; i < num_configs; i++) {
 		param = pinconf_to_config_param(configs[i]);
 		arg = pinconf_to_config_argument(configs[i]);
-
 		switch (param) {
 		case PIN_CONFIG_BIAS_DISABLE:
 			rc =  rockchip_set_pull(bank, pin - bank->pin_base,
@@ -2455,6 +2458,26 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev)
 	return 0;
 }
 
+static struct rockchip_pin_bank rk1108_pin_banks[] = {
+	PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU,
+					     IOMUX_SOURCE_PMU,
+					     IOMUX_SOURCE_PMU,
+					     IOMUX_SOURCE_PMU),
+	PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", 0, 0, 0, 0),
+	PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", 0, 0, 0, 0),
+	PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", 0, 0, 0, 0),
+};
+
+static struct rockchip_pin_ctrl rk1108_pin_ctrl = {
+	.pin_banks		= rk1108_pin_banks,
+	.nr_banks		= ARRAY_SIZE(rk1108_pin_banks),
+	.label			= "RK1108-GPIO",
+	.type			= RK1108,
+	.grf_mux_offset		= 0x10,
+	.pmu_mux_offset		= 0x0,
+	.pull_calc_reg          = rk3288_calc_pull_reg_and_bit,
+};
+
 static struct rockchip_pin_bank rk2928_pin_banks[] = {
 	PIN_BANK(0, 32, "gpio0"),
 	PIN_BANK(1, 32, "gpio1"),
@@ -2684,6 +2707,8 @@ static struct rockchip_pin_ctrl rk3399_pin_ctrl = {
 };
 
 static const struct of_device_id rockchip_pinctrl_dt_match[] = {
+	{ .compatible = "rockchip,rk1108-pinctrl",
+		.data = (void *)&rk1108_pin_ctrl },
 	{ .compatible = "rockchip,rk2928-pinctrl",
 		.data = (void *)&rk2928_pin_ctrl },
 	{ .compatible = "rockchip,rk3036-pinctrl",
-- 
2.7.4

^ permalink raw reply related

* [PATCH 1/6] dt-bindings: rockchip-dw-mshc: add RK1108 dw-mshc description
From: Andy Yan @ 2016-11-03 12:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1478175975-11779-1-git-send-email-andy.yan@rock-chips.com>

From: Shawn Lin <shawn.lin@rock-chips.com>

Add "rockchip,rk1108-dw-mshc", "rockchip,rk3288-dw-mshc" for
dwmmc on rk1108 platform.

Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
---

 Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
index 07184e8..ea9c1c9 100644
--- a/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
+++ b/Documentation/devicetree/bindings/mmc/rockchip-dw-mshc.txt
@@ -13,6 +13,7 @@ Required Properties:
 	- "rockchip,rk2928-dw-mshc": for Rockchip RK2928 and following,
 							before RK3288
 	- "rockchip,rk3288-dw-mshc": for Rockchip RK3288
+	- "rockchip,rk1108-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK1108
 	- "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3036
 	- "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3368
 	- "rockchip,rk3399-dw-mshc", "rockchip,rk3288-dw-mshc": for Rockchip RK3399
-- 
2.7.4

^ permalink raw reply related

* [PATCH V3 1/6] clk: tegra: add TEGRA20_CLK_NOR to init table
From: Mirza Krak @ 2016-11-03 12:30 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CALw8SCWyLAw=yZ-W_nAFuDAazpa4HJfZuzqLDKQKYLWjV5JzYw@mail.gmail.com>

2016-11-03 13:26 GMT+01:00 Mirza Krak <mirza.krak@gmail.com>:
> 2016-11-03 11:06 GMT+01:00 Jon Hunter <jonathanh@nvidia.com>:
>> Hi Mirza,
>>
>> On 27/10/16 15:01, Mirza Krak wrote:
>>>
>>> From: Mirza Krak <mirza.krak@gmail.com>
>>>
>>> Add TEGRA20_CLK_NOR to init table and set default rate to 92 MHz which
>>> is max rate.
>>>
>>> The maximum rate value of 92 MHz is pulled from the downstream L4T
>>> kernel.
>>
>>
>> Thanks for adding this. I assume that this is from an L4T r16 release with a
>> v3.1 kernel. I had a quick poke through the kernel sources for v3.1 but was
>> unable to see where this is set. Obviously v3.1 did not have CCF and so
>> everything seems to be in the arch/arm/mach-tegra directory for setting up
>> clocks. Can you point me to the appropriate sources so I can ACK this?
>
> I use the kernel sources provided by Toradex, and these sources are
> based on L4T r16 release.
>
> http://git.toradex.com/cgit/linux-toradex.git/tree/arch/arm/mach-tegra/tegra2_clocks.c?h=tegra#n2463

Ops, pre-mature send.

I also added Marcel from Toradex on CC.

The link to the source are [1] for Tegra2 and  [2] for Tegra3.

[1]. http://git.toradex.com/cgit/linux-toradex.git/tree/arch/arm/mach-tegra/tegra2_clocks.c?h=tegra#n2463
[2]. http://git.toradex.com/cgit/linux-toradex.git/tree/arch/arm/mach-tegra/tegra3_clocks.c?h=tegra#n4353

Best Regards
Mirza

^ permalink raw reply


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