Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/2] arm64: dts: exynos: Remove unneeded DSI and DECON address/size cells in Exynos5433
From: Andrzej Hajda @ 2018-06-21  5:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180620193407.gk5e5ecolo5bel3c@kozik-lap>

On 20.06.2018 21:34, Krzysztof Kozlowski wrote:
> On Tue, Jun 19, 2018 at 09:59:04AM +0200, Krzysztof Kozlowski wrote:
>> On 19 June 2018 at 09:26, Marek Szyprowski <m.szyprowski@samsung.com> wrote:
>>> Hi Krzysztof,
>>>
>>> On 2018-06-18 19:42, Krzysztof Kozlowski wrote:
>>>> The decon, decon_tv and dsi nodes have only one child port so
>>>> address/size mappings are not necessary.  This fixes DTC warnings like:
>>>>
>>>>      Warning (graph_child_address): /soc/decon at 13800000/ports:
>>>>          graph node has single child node 'port at 0', #address-cells/#size-cells are not necessary
>>>>
>>>> Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
>>> Works fine with current Exynos DRM Decon/MIC/DSI drivers.
>>>
>>> Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
>> Thanks for review and testing!
> I have second thoughs whether this patch is correct. AFAIU, the drivers
> get the remote endpoints by reg==0 (for example the
> of_graph_get_remote_node() in exynos_dsi_parse_dt()). If the port shall
> be ignored, then reg==-1 should be passed.

All this is about purity, DECON bindings says explicitly that there
should be a port with reg=0.
So your patch and DTC warnings are incorrect from bindings PoV.
On the other side graph bindings are too bloated ( so many lines to
describe one connection ) so I am happy if there are shrinking attempts :)
Functionally nothing changes, of graph helpers assume reg=0 if it is not
present in port/endpoint node.

And regarding real issues, DECON could have more ports, possible candidates:
- GSCALER0/1/2,
- GSD/DSD - interconnect between GSCALERs and DECONs,
- SMIES - image enhancer (not implemented),
- MIC0/1 - image enhancers,
- DSIM0/1 - DSI encoders,
- HDMI - HDMI encoder.

But since all these connections can be configured dynamically, and more
importantly are inside specific SoC I dont think they need of_graphs. In
fact I think current of graph is also not necessary, but this is
different story, removal is on my long TODO list :)

Regards
Andrzej

>
> Best regards,
> Krzysztof
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" 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 0/5] arm64: Initial support Texas Instrument's AM654 Platform
From: Tony Lindgren @ 2018-06-21  5:40 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180619194253.27288-1-nm@ti.com>

* Nishanth Menon <nm@ti.com> [180619 19:46]:
> Hi,
> This is an update from RFC posted earlier:
>         https://marc.info/?l=linux-arm-kernel&m=152817866312732&w=2
> 
> The following series enables support for newest addition in TI's SoC
> portfolio - AM654 SoC.
> 
> The series is based off v4.18-rc1, also available here:
> https://github.com/nmenon/linux-2.6-playground/tree/upstream/v4.18-rc1/k3-1-am6-base
> 
> Key changes since RFC are indicated in respective patches:
> * dt bindings updates (from review comments)
> * device tree is split up to incorporate ranges and bus segments
> * Cosmetic fixes including renaming the base dts to prevent confusion
> * UART has been split out

Other than the cbass to interrconnect naming, looks good to me now:

Reviewed-by: Tony Lindgren <tony@atomide.com>

^ permalink raw reply

* [PATCH 3/5] arm64: dts: ti: Add Support for AM654 SoC
From: Tony Lindgren @ 2018-06-21  5:37 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180619194253.27288-4-nm@ti.com>

* Nishanth Menon <nm@ti.com> [180619 19:46]:
> +	cbass_main: cbass at 100000 {
> +		compatible = "simple-bus";
> +		#address-cells = <1>;
> +		#size-cells = <1>;
> +		ranges = <0x00100000 0x00 0x00100000 0x00020000>, /* ctrl mmr */
> +			 <0x00600000 0x00 0x00600000 0x00001100>, /* GPIO */
> +			 <0x00900000 0x00 0x00900000 0x00012000>, /* serdes */
> +			 <0x01000000 0x00 0x01000000 0x0af02400>, /* Most peripherals */
> +			 <0x30800000 0x00 0x30800000 0x0bc00000>, /* MAIN NAVSS */
> +			 /* MCUSS Range */
> +			 <0x28380000 0x00 0x28380000 0x03880000>,
> +			 <0x40200000 0x00 0x40200000 0x00900100>,
> +			 <0x42040000 0x00 0x42040000 0x03ac2400>,
> +			 <0x45100000 0x00 0x45100000 0x00c24000>,
> +			 <0x46000000 0x00 0x46000000 0x00200000>,
> +			 <0x47000000 0x00 0x47000000 0x00068400>;
> +
> +		cbass_mcu: cbass at 28380000 {
> +			compatible = "simple-bus";
> +			#address-cells = <1>;
> +			#size-cells = <1>;
> +			ranges = <0x28380000 0x28380000 0x03880000>, /* MCU NAVSS*/
> +				 <0x40200000 0x40200000 0x00900100>, /* First peripheral window */
> +				 <0x42040000 0x42040000 0x03ac2400>, /* WKUP */
> +				 <0x45100000 0x45100000 0x00c24000>, /* MMRs, remaining NAVSS */
> +				 <0x46000000 0x46000000 0x00200000>, /* CPSW */
> +				 <0x47000000 0x47000000 0x00068400>; /* OSPI space 1 */
> +
> +			cbass_wakeup: cbass at 42040000 {
> +				compatible = "simple-bus";
> +				#address-cells = <1>;
> +				#size-cells = <1>;
> +				/* WKUP  Basic peripherals */
> +				ranges = <0x42040000 0x42040000 0x03ac2400>;
> +			};
> +		};
> +	};
> +};

You should use cbass_main: interconnect at 1000000 and so on here.
Other than that looks good to me, thanks for updating it.

Regards,

Tony

^ permalink raw reply

* [PATCH v2 0/5] crypto: ccree: cleanup, fixes and R-Car enabling
From: Gilad Ben-Yossef @ 2018-06-21  5:00 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180620085145.7bxfbu7bi45sftnk@verge.net.au>

On Wed, Jun 20, 2018 at 11:51 AM, Simon Horman <horms@verge.net.au> wrote:
> On Tue, Jun 19, 2018 at 04:57:15PM +0300, Gilad Ben-Yossef wrote:
>> On Tue, Jun 19, 2018 at 3:58 PM, Geert Uytterhoeven
>> <geert@linux-m68k.org> wrote:
>> > Hi Gilad,
>> >
>> > On Thu, May 24, 2018 at 4:19 PM Gilad Ben-Yossef <gilad@benyossef.com> wrote:
>> >> The patch set enables the use of CryptoCell found in some Renesas R-Car
>> >> Salvator-X boards and fixes some driver issues uncovered that prevented
>> >> to work properly.
>> >
>> > With DEBUG enabled on R-Car H3, I see lots of
>> >
>> >     ccree e6601000.crypto: IRR includes unknown cause bits (0x00000098)
>> >     ccree e6601000.crypto: IRR includes unknown cause bits (0x000000C0)
>> >     ccree e6601000.crypto: IRR includes unknown cause bits (0x000000D0)
>> >     ccree e6601000.crypto: IRR includes unknown cause bits (0x000000D8)
>> >     ccree e6601000.crypto: IRR includes unknown cause bits (0x000000E0)
>> >     ccree e6601000.crypto: IRR includes unknown cause bits (0x000000F0)
>> >     ccree e6601000.crypto: IRR includes unknown cause bits (0x000000F8)
>> >
>> > during boot. Is that expected?
>>
>> Yes. The condition itself it is reporting is not necessarily bad. It
>> means that driver
>> did not act on certain HW notification during interrupts and that's
>> OK, we don't act on all of them
>> depending on configuration - e.g. if you have CONFIG_FIPS enabled and
>> an active TEE module or not.
>>
>> I can rate_limit the message if it bothers you but other than that it
>> is a harmless debug print.
>
> Rate limiting sounds like an excellent idea to me.

Will do.

Thanks!
Gilad



-- 
Gilad Ben-Yossef
Chief Coffee Drinker

values of ? will give rise to dom!

^ permalink raw reply

* [PATCH V2 5/5] PCI: Unify slot and bus reset API
From: kbuild test robot @ 2018-06-21  4:58 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1529467995-28780-5-git-send-email-okaya@codeaurora.org>

Hi Sinan,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pci/next]
[also build test WARNING on v4.18-rc1 next-20180620]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Sinan-Kaya/PCI-handle-error-return-from-pci_reset_bridge_secondary_bus/20180620-121648
base:   https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git next
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

>> drivers/infiniband/hw/hfi1/pcie.c:908:33: sparse: incorrect type in argument 1 (different base types) @@    expected struct pci_dev *dev @@    got struct pci_dev *dev @@
   drivers/infiniband/hw/hfi1/pcie.c:908:33:    expected struct pci_dev *dev
   drivers/infiniband/hw/hfi1/pcie.c:908:33:    got struct pci_bus *bus
   drivers/infiniband/hw/hfi1/pcie.c: In function 'trigger_sbr':
   drivers/infiniband/hw/hfi1/pcie.c:908:23: error: passing argument 1 of 'pci_reset_bus' from incompatible pointer type [-Werror=incompatible-pointer-types]
     return pci_reset_bus(dev->bus);
                          ^~~
   In file included from drivers/infiniband/hw/hfi1/pcie.c:48:0:
   include/linux/pci.h:1099:5: note: expected 'struct pci_dev *' but argument is of type 'struct pci_bus *'
    int pci_reset_bus(struct pci_dev *dev);
        ^~~~~~~~~~~~~
   cc1: some warnings being treated as errors

vim +908 drivers/infiniband/hw/hfi1/pcie.c

77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  873  
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  874  /*
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  875   * Trigger a secondary bus reset (SBR) on ourselves using our parent.
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  876   *
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  877   * Based on pci_parent_bus_reset() which is not exported by the
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  878   * kernel core.
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  879   */
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  880  static int trigger_sbr(struct hfi1_devdata *dd)
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  881  {
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  882  	struct pci_dev *dev = dd->pcidev;
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  883  	struct pci_dev *pdev;
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  884  
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  885  	/* need a parent */
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  886  	if (!dev->bus->self) {
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  887  		dd_dev_err(dd, "%s: no parent device\n", __func__);
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  888  		return -ENOTTY;
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  889  	}
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  890  
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  891  	/* should not be anyone else on the bus */
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  892  	list_for_each_entry(pdev, &dev->bus->devices, bus_list)
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  893  		if (pdev != dev) {
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  894  			dd_dev_err(dd,
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  895  				   "%s: another device is on the same bus\n",
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  896  				   __func__);
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  897  			return -ENOTTY;
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  898  		}
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  899  
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  900  	/*
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  901  	 * A secondary bus reset (SBR) issues a hot reset to our device.
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  902  	 * The following routine does a 1s wait after the reset is dropped
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  903  	 * per PCI Trhfa (recovery time).  PCIe 3.0 section 6.6.1 -
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  904  	 * Conventional Reset, paragraph 3, line 35 also says that a 1s
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  905  	 * delay after a reset is required.  Per spec requirements,
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  906  	 * the link is either working or not after that point.
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  907  	 */
f001109e drivers/infiniband/hw/hfi1/pcie.c Sinan Kaya       2018-06-20 @908  	return pci_reset_bus(dev->bus);
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  909  }
77241056 drivers/staging/rdma/hfi1/pcie.c  Mike Marciniszyn 2015-07-30  910  

:::::: The code at line 908 was first introduced by commit
:::::: f001109e94b74baebb3621ce1c7ba114a858adb3 IB/hfi1: use pci_reset_bus() for initiating pci secondary bus reset

:::::: TO: Sinan Kaya <okaya@codeaurora.org>
:::::: CC: 0day robot <lkp@intel.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

^ permalink raw reply

* [PATCH v4] ARM: dts: imx51-zii-rdu1: fix touchscreen pinctrl
From: Chris Healy @ 2018-06-21  4:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180620203500.28309-1-nick@shmanahar.org>

On Wed, Jun 20, 2018 at 1:35 PM, Nick Dyer <nick@shmanahar.org> wrote:
> The pinctrl settings were incorrect for the touchscreen interrupt line, causing
> an interrupt storm. This change has been tested with both the atmel_mxt_ts and
> RMI4 drivers on the RDU1 units.
>
> The value 0x4 comes from the value of register IOMUXC_SW_PAD_CTL_PAD_CSI1_D8
> from the old vendor kernel.
>
> Signed-off-by: Nick Dyer <nick@shmanahar.org>
> Fixes: ceef0396f367 ("ARM: dts: imx: add ZII RDU1 board")
> Cc: <stable@vger.kernel.org> # 4.15+
> Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
> ---
> Changes in v4:
> - Add reviewed by Fabio
> Changes in v3:
> - Update commit message to add source of 0x4 value, fixes tag and CC stable
> Changes in v2:
> - Use hex, only alter IRQ line config

Tested on an RDU1 with Synaptics touchscreen successfully.  No
interrupt store any longer...

Tested-by: Chris Healy <cphealy@gmail.com>

^ permalink raw reply

* [PATCH 0/7 v5] Support for fsl-mc bus and its devices in SMMU
From: Nipun Gupta @ 2018-06-21  3:59 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1526824191-7000-1-git-send-email-nipun.gupta@nxp.com>

Hi Robin/Greg k-h,

Will this patch-set be taken for the next kernel release (and via which tree)?

Thanks,
Nipun

> -----Original Message-----
> From: Nipun Gupta
> Sent: Sunday, May 20, 2018 7:20 PM
> To: robin.murphy at arm.com; will.deacon at arm.com; robh+dt at kernel.org;
> robh at kernel.org; mark.rutland at arm.com; catalin.marinas at arm.com;
> gregkh at linuxfoundation.org; Laurentiu Tudor <laurentiu.tudor@nxp.com>;
> bhelgaas at google.com
> Cc: hch at lst.de; joro at 8bytes.org; m.szyprowski at samsung.com;
> shawnguo at kernel.org; frowand.list at gmail.com; iommu at lists.linux-
> foundation.org; linux-kernel at vger.kernel.org; devicetree at vger.kernel.org;
> linux-arm-kernel at lists.infradead.org; linuxppc-dev at lists.ozlabs.org; linux-
> pci at vger.kernel.org; Bharat Bhushan <bharat.bhushan@nxp.com>;
> stuyoder at gmail.com; Leo Li <leoyang.li@nxp.com>; Nipun Gupta
> <nipun.gupta@nxp.com>
> Subject: [PATCH 0/7 v5] Support for fsl-mc bus and its devices in SMMU
> 
> This patchset defines IOMMU DT binding for fsl-mc bus and adds
> support in SMMU for fsl-mc bus.
> 
> The patch series is based on top of dma-mapping tree (for-next branch):
> http://git.infradead.org/users/hch/dma-mapping.git
> 
> These patches
>   - Define property 'iommu-map' for fsl-mc bus (patch 1)
>   - Integrates the fsl-mc bus with the SMMU using this
>     IOMMU binding (patch 2,3,4)
>   - Adds the dma configuration support for fsl-mc bus (patch 5, 6)
>   - Updates the fsl-mc device node with iommu/dma related changes (patch 7)
> 
> Changes in v2:
>   - use iommu-map property for fsl-mc bus
>   - rebase over patchset https://patchwork.kernel.org/patch/10317337/
>     and make corresponding changes for dma configuration of devices on
>     fsl-mc bus
> 
> Changes in v3:
>   - move of_map_rid in drivers/of/address.c
> 
> Changes in v4:
>   - move of_map_rid in drivers/of/base.c
> 
> Changes in v5:
>   - break patch 5 in two separate patches (now patch 5/7 and patch 6/7)
>   - add changelog text in patch 3/7 and patch 5/7
>   - typo fix
> 
> Nipun Gupta (7):
>   Docs: dt: add fsl-mc iommu-map device-tree binding
>   iommu: of: make of_pci_map_rid() available for other devices too
>   iommu: support iommu configuration for fsl-mc devices
>   iommu: arm-smmu: Add support for the fsl-mc bus
>   bus: fsl-mc: support dma configure for devices on fsl-mc bus
>   bus: fsl-mc: set coherent dma mask for devices on fsl-mc bus
>   arm64: dts: ls208xa: comply with the iommu map binding for fsl_mc
> 
>  .../devicetree/bindings/misc/fsl,qoriq-mc.txt      |  39 ++++++++
>  arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi     |   6 +-
>  drivers/bus/fsl-mc/fsl-mc-bus.c                    |  16 +++-
>  drivers/iommu/arm-smmu.c                           |   7 ++
>  drivers/iommu/iommu.c                              |  21 +++++
>  drivers/iommu/of_iommu.c                           |  25 ++++-
>  drivers/of/base.c                                  | 102 +++++++++++++++++++++
>  drivers/of/irq.c                                   |   5 +-
>  drivers/pci/of.c                                   | 101 --------------------
>  include/linux/fsl/mc.h                             |   8 ++
>  include/linux/iommu.h                              |   2 +
>  include/linux/of.h                                 |  11 +++
>  include/linux/of_pci.h                             |  10 --
>  13 files changed, 231 insertions(+), 122 deletions(-)
> 
> --
> 1.9.1

^ permalink raw reply

* [PATCH V2 3/4] dt-bindings: arm: fsl: add scu binding doc
From: A.s. Dong @ 2018-06-21  3:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180620194438.GA3494@rob-hp-laptop>

Hi Rob,

> -----Original Message-----
> From: Rob Herring [mailto:robh at kernel.org]
> Sent: Thursday, June 21, 2018 3:45 AM
> To: A.s. Dong <aisheng.dong@nxp.com>
> Cc: linux-arm-kernel at lists.infradead.org; dongas86 at gmail.com;
> kernel at pengutronix.de; shawnguo at kernel.org; Fabio Estevam
> <fabio.estevam@nxp.com>; dl-linux-imx <linux-imx@nxp.com>; Mark
> Rutland <mark.rutland@arm.com>; devicetree at vger.kernel.org
> Subject: Re: [PATCH V2 3/4] dt-bindings: arm: fsl: add scu binding doc
> 
> On Sun, Jun 17, 2018 at 08:49:48PM +0800, Dong Aisheng wrote:
> > The System Controller Firmware (SCFW) is a low-level system function
> > which runs on a dedicated Cortex-M core to provide power, clock, and
> > resource management. It exists on some i.MX8 processors. e.g. i.MX8QM
> > (QM, QP), and i.MX8QX (QXP, DX).
> >
> > Cc: Shawn Guo <shawnguo@kernel.org>
> > Cc: Sascha Hauer <kernel@pengutronix.de>
> > Cc: Fabio Estevam <fabio.estevam@nxp.com>
> > Cc: Rob Herring <robh+dt@kernel.org>
> > Cc: Mark Rutland <mark.rutland@arm.com>
> > Cc: devicetree at vger.kernel.org
> > Signed-off-by: Dong Aisheng <aisheng.dong@nxp.com>
> > ---
> > v1->v2:
> >  * remove status
> >  * changed to mu1
> > ---
> >  .../devicetree/bindings/arm/freescale/fsl,scu.txt  | 38
> > ++++++++++++++++++++++
> >  1 file changed, 38 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> >
> > diff --git
> > a/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> > b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> > new file mode 100644
> > index 0000000..9b7c9fe
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/arm/freescale/fsl,scu.txt
> > @@ -0,0 +1,38 @@
> > +NXP i.MX System Controller Firmware (SCFW)
> > +--------------------------------------------------------------------
> > +
> > +The System Controller Firmware (SCFW) is a low-level system function
> > +which runs on a dedicated Cortex-M core to provide power, clock, and
> > +resource management. It exists on some i.MX8 processors. e.g. i.MX8QM
> > +(QM, QP), and i.MX8QX (QXP, DX).
> > +
> > +The AP communicates with the SC using a multi-ported MU module found
> > +in the LSIO subsystem. The current definition of this MU module
> > +provides
> > +5 remote AP connections to the SC to support up to 5 execution
> > +environments (TZ, HV, standard Linux, etc.). The SC side of this MU
> > +module interfaces with the LSIO DSC IP bus. The SC firmware will
> > +communicate with this MU using the MSI bus.
> > +
> > +System Controller Device Node:
> > +=============================
> > +
> > +Required properties:
> > +-------------------
> > +- compatible: should be "fsl,imx8qxp-scu" or "fsl,imx8qm-scu"
> > +- fsl,mu: a phandle to the Message Unit used by SCU. Should be
> > +	  one of LSIO MU0~M4 for imx8qxp and imx8qm. Users need
> > +	  to make sure not use the one which is conflict with
> > +	  other execution environments. e.g. ATF.
> 
> Use the mailbox binding even if you don't use the mailbox subsystem.
> 

Looks reasonable. Will change it.

BTW as I said before, the current mailbox binding fixed #mbox-cells to be
at least 1 which is not suitable for i.MX SCU MU as it has only one physical
channel.

I will cook a patch to update it to allow #mbox-cells = <0>.

If any issue please let me know.

Regards
Dong Aisheng

> > +
> > +Examples:
> > +--------
> > +lsio_mu1: mu at 5d1c0000 {
> > +	compatible = "fsl,imx8qxp-mu";
> > +	reg = <0x0 0x5d1c0000 0x0 0x10000>;
> > +	interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>; };
> > +
> > +scu {
> > +	compatible = "fsl,imx8qxp-scu";
> > +	fsl,mu = <&lsio_mu1>;
> > +};
> > --
> > 2.7.4
> >

^ permalink raw reply

* [PATCH v3] media: dvb-frontends: add Socionext SC1501A ISDB-S/T demodulator driver
From: Katsuhiro Suzuki @ 2018-06-21  3:17 UTC (permalink / raw)
  To: linux-arm-kernel

This patch adds a frontend driver for the Socionext SC1501A series
and Socionext MN88443x ISDB-S/T demodulators.

The maximum and minimum frequency of Socionext SC1501A comes from
ISDB-S and ISDB-T so frequency range is the following:
  - ISDB-S (BS/CS110 IF frequency in kHz, Local freq 10.678GHz)
    - Min: BS-1: 1032000 => 1032.23MHz
    - Max: ND24: 2701000 => 2070.25MHz
  - ISDB-T (in Hz)
    - Min: ch13: 470000000 => 470.357857MHz
    - Max: ch62: 770000000 => 769.927857MHz

Signed-off-by: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>

---

Changes since v2:
  - Fix frequency max and min

Changes since v1:
  - Fix sparse warning about type of constant
  - Use div_s64() instead of divide operator
---
 drivers/media/dvb-frontends/Kconfig   |  10 +
 drivers/media/dvb-frontends/Makefile  |   1 +
 drivers/media/dvb-frontends/sc1501a.c | 802 ++++++++++++++++++++++++++
 drivers/media/dvb-frontends/sc1501a.h |  27 +
 4 files changed, 840 insertions(+)
 create mode 100644 drivers/media/dvb-frontends/sc1501a.c
 create mode 100644 drivers/media/dvb-frontends/sc1501a.h

diff --git a/drivers/media/dvb-frontends/Kconfig b/drivers/media/dvb-frontends/Kconfig
index 9ecaa9d0744a..097ae3c834f2 100644
--- a/drivers/media/dvb-frontends/Kconfig
+++ b/drivers/media/dvb-frontends/Kconfig
@@ -739,6 +739,16 @@ config DVB_TC90522
 	  Toshiba TC90522 2xISDB-S 8PSK + 2xISDB-T OFDM demodulator.
 	  Say Y when you want to support this frontend.
 
+config DVB_SC1501A
+	tristate "Socionext SC1501A"
+	depends on DVB_CORE && I2C
+	select REGMAP_I2C
+	default m if !MEDIA_SUBDRV_AUTOSELECT
+	help
+	  A driver for Socionext SC1501A and Panasonic MN88443x
+	  ISDB-S + ISDB-T demodulator.
+	  Say Y when you want to support this frontend.
+
 comment "Digital terrestrial only tuners/PLL"
 	depends on DVB_CORE
 
diff --git a/drivers/media/dvb-frontends/Makefile b/drivers/media/dvb-frontends/Makefile
index 67a783fd5ed0..e204502347ed 100644
--- a/drivers/media/dvb-frontends/Makefile
+++ b/drivers/media/dvb-frontends/Makefile
@@ -125,6 +125,7 @@ obj-$(CONFIG_DVB_AF9033) += af9033.o
 obj-$(CONFIG_DVB_AS102_FE) += as102_fe.o
 obj-$(CONFIG_DVB_GP8PSK_FE) += gp8psk-fe.o
 obj-$(CONFIG_DVB_TC90522) += tc90522.o
+obj-$(CONFIG_DVB_SC1501A) += sc1501a.o
 obj-$(CONFIG_DVB_HORUS3A) += horus3a.o
 obj-$(CONFIG_DVB_ASCOT2E) += ascot2e.o
 obj-$(CONFIG_DVB_HELENE) += helene.o
diff --git a/drivers/media/dvb-frontends/sc1501a.c b/drivers/media/dvb-frontends/sc1501a.c
new file mode 100644
index 000000000000..705529007abe
--- /dev/null
+++ b/drivers/media/dvb-frontends/sc1501a.c
@@ -0,0 +1,802 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Socionext SC1501A series demodulator driver for ISDB-S/ISDB-T.
+//
+// Copyright (c) 2018 Socionext Inc.
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio/consumer.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <media/dvb_math.h>
+
+#include "sc1501a.h"
+
+/* ISDB-S registers */
+#define ATSIDU_S                                    0x2f
+#define ATSIDL_S                                    0x30
+#define TSSET_S                                     0x31
+#define AGCREAD_S                                   0x5a
+#define CPMON1_S                                    0x5e
+#define   CPMON1_S_FSYNC                              BIT(5)
+#define   CPMON1_S_ERRMON                             BIT(4)
+#define   CPMON1_S_SIGOFF                             BIT(3)
+#define   CPMON1_S_W2LOCK                             BIT(2)
+#define   CPMON1_S_W1LOCK                             BIT(1)
+#define   CPMON1_S_DW1LOCK                            BIT(0)
+#define TRMON_S                                     0x60
+#define BERCNFLG_S                                  0x68
+#define   BERCNFLG_S_BERVRDY                          BIT(5)
+#define   BERCNFLG_S_BERVCHK                          BIT(4)
+#define   BERCNFLG_S_BERDRDY                          BIT(3)
+#define   BERCNFLG_S_BERDCHK                          BIT(2)
+#define CNRDXU_S                                    0x69
+#define CNRDXL_S                                    0x6a
+#define CNRDYU_S                                    0x6b
+#define CNRDYL_S                                    0x6c
+#define BERVRDU_S                                   0x71
+#define BERVRDL_S                                   0x72
+#define DOSET1_S                                    0x73
+
+/* Primary ISDB-T */
+#define PLLASET1                                    0x00
+#define PLLASET2                                    0x01
+#define PLLBSET1                                    0x02
+#define PLLBSET2                                    0x03
+#define PLLSET                                      0x04
+#define OUTCSET                                     0x08
+#define   OUTCSET_CHDRV_8MA                           0xff
+#define   OUTCSET_CHDRV_4MA                           0x00
+#define PLDWSET                                     0x09
+#define   PLDWSET_NORMAL                             0x00
+#define   PLDWSET_PULLDOWN                           0xff
+#define HIZSET1                                     0x0a
+#define HIZSET2                                     0x0b
+
+/* Secondary ISDB-T (for MN884434 only) */
+#define RCVSET                                      0x00
+#define TSSET1_M                                    0x01
+#define TSSET2_M                                    0x02
+#define TSSET3_M                                    0x03
+#define INTACSET                                    0x08
+#define HIZSET3                                     0x0b
+
+/* ISDB-T registers */
+#define TSSET1                                      0x05
+#define   TSSET1_TSASEL_MASK                          GENMASK(4, 3)
+#define   TSSET1_TSASEL_ISDBT                         (0x0 << 3)
+#define   TSSET1_TSASEL_ISDBS                         (0x1 << 3)
+#define   TSSET1_TSASEL_NONE                          (0x2 << 3)
+#define   TSSET1_TSBSEL_MASK                          GENMASK(2, 1)
+#define   TSSET1_TSBSEL_ISDBS                         (0x0 << 1)
+#define   TSSET1_TSBSEL_ISDBT                         (0x1 << 1)
+#define   TSSET1_TSBSEL_NONE                          (0x2 << 1)
+#define TSSET2                                      0x06
+#define TSSET3                                      0x07
+#define   TSSET3_INTASEL_MASK                         GENMASK(7, 6)
+#define   TSSET3_INTASEL_T                            (0x0 << 6)
+#define   TSSET3_INTASEL_S                            (0x1 << 6)
+#define   TSSET3_INTASEL_NONE                         (0x2 << 6)
+#define   TSSET3_INTBSEL_MASK                         GENMASK(5, 4)
+#define   TSSET3_INTBSEL_S                            (0x0 << 4)
+#define   TSSET3_INTBSEL_T                            (0x1 << 4)
+#define   TSSET3_INTBSEL_NONE                         (0x2 << 4)
+#define OUTSET2                                     0x0d
+#define PWDSET                                      0x0f
+#define   PWDSET_OFDMPD_MASK                          GENMASK(3, 2)
+#define   PWDSET_OFDMPD_DOWN                          BIT(3)
+#define   PWDSET_PSKPD_MASK                           GENMASK(1, 0)
+#define   PWDSET_PSKPD_DOWN                           BIT(1)
+#define CLKSET1_T                                   0x11
+#define MDSET_T                                     0x13
+#define   MDSET_T_MDAUTO_MASK                         GENMASK(7, 4)
+#define   MDSET_T_MDAUTO_AUTO                         (0xf << 4)
+#define   MDSET_T_MDAUTO_MANUAL                       (0x0 << 4)
+#define   MDSET_T_FFTS_MASK                           GENMASK(3, 2)
+#define   MDSET_T_FFTS_MODE1                          (0x0 << 2)
+#define   MDSET_T_FFTS_MODE2                          (0x1 << 2)
+#define   MDSET_T_FFTS_MODE3                          (0x2 << 2)
+#define   MDSET_T_GI_MASK                             GENMASK(1, 0)
+#define   MDSET_T_GI_1_32                             (0x0 << 0)
+#define   MDSET_T_GI_1_16                             (0x1 << 0)
+#define   MDSET_T_GI_1_8                              (0x2 << 0)
+#define   MDSET_T_GI_1_4                              (0x3 << 0)
+#define MDASET_T                                    0x14
+#define ADCSET1_T                                   0x20
+#define   ADCSET1_T_REFSEL_MASK                       GENMASK(1, 0)
+#define   ADCSET1_T_REFSEL_2V                         (0x3 << 0)
+#define   ADCSET1_T_REFSEL_1_5V                       (0x2 << 0)
+#define   ADCSET1_T_REFSEL_1V                         (0x1 << 0)
+#define NCOFREQU_T                                  0x24
+#define NCOFREQM_T                                  0x25
+#define NCOFREQL_T                                  0x26
+#define FADU_T                                      0x27
+#define FADM_T                                      0x28
+#define FADL_T                                      0x29
+#define AGCSET2_T                                   0x2c
+#define   AGCSET2_T_IFPOLINV_INC                      BIT(0)
+#define   AGCSET2_T_RFPOLINV_INC                      BIT(1)
+#define AGCV3_T                                     0x3e
+#define MDRD_T                                      0xa2
+#define   MDRD_T_SEGID_MASK                           GENMASK(5, 4)
+#define   MDRD_T_SEGID_13                             (0x0 << 4)
+#define   MDRD_T_SEGID_1                              (0x1 << 4)
+#define   MDRD_T_SEGID_3                              (0x2 << 4)
+#define   MDRD_T_FFTS_MASK                            GENMASK(3, 2)
+#define   MDRD_T_FFTS_MODE1                           (0x0 << 2)
+#define   MDRD_T_FFTS_MODE2                           (0x1 << 2)
+#define   MDRD_T_FFTS_MODE3                           (0x2 << 2)
+#define   MDRD_T_GI_MASK                              GENMASK(1, 0)
+#define   MDRD_T_GI_1_32                              (0x0 << 0)
+#define   MDRD_T_GI_1_16                              (0x1 << 0)
+#define   MDRD_T_GI_1_8                               (0x2 << 0)
+#define   MDRD_T_GI_1_4                               (0x3 << 0)
+#define SSEQRD_T                                    0xa3
+#define   SSEQRD_T_SSEQSTRD_MASK                      GENMASK(3, 0)
+#define   SSEQRD_T_SSEQSTRD_RESET                     (0x0 << 0)
+#define   SSEQRD_T_SSEQSTRD_TUNING                    (0x1 << 0)
+#define   SSEQRD_T_SSEQSTRD_AGC                       (0x2 << 0)
+#define   SSEQRD_T_SSEQSTRD_SEARCH                    (0x3 << 0)
+#define   SSEQRD_T_SSEQSTRD_CLOCK_SYNC                (0x4 << 0)
+#define   SSEQRD_T_SSEQSTRD_FREQ_SYNC                 (0x8 << 0)
+#define   SSEQRD_T_SSEQSTRD_FRAME_SYNC                (0x9 << 0)
+#define   SSEQRD_T_SSEQSTRD_SYNC                      (0xa << 0)
+#define   SSEQRD_T_SSEQSTRD_LOCK                      (0xb << 0)
+#define AGCRDU_T                                    0xa8
+#define AGCRDL_T                                    0xa9
+#define CNRDU_T                                     0xbe
+#define CNRDL_T                                     0xbf
+#define BERFLG_T                                    0xc0
+#define   BERFLG_T_BERDRDY                            BIT(7)
+#define   BERFLG_T_BERDCHK                            BIT(6)
+#define   BERFLG_T_BERVRDYA                           BIT(5)
+#define   BERFLG_T_BERVCHKA                           BIT(4)
+#define   BERFLG_T_BERVRDYB                           BIT(3)
+#define   BERFLG_T_BERVCHKB                           BIT(2)
+#define   BERFLG_T_BERVRDYC                           BIT(1)
+#define   BERFLG_T_BERVCHKC                           BIT(0)
+#define BERRDU_T                                    0xc1
+#define BERRDM_T                                    0xc2
+#define BERRDL_T                                    0xc3
+#define BERLENRDU_T                                 0xc4
+#define BERLENRDL_T                                 0xc5
+#define ERRFLG_T                                    0xc6
+#define   ERRFLG_T_BERDOVF                            BIT(7)
+#define   ERRFLG_T_BERVOVFA                           BIT(6)
+#define   ERRFLG_T_BERVOVFB                           BIT(5)
+#define   ERRFLG_T_BERVOVFC                           BIT(4)
+#define   ERRFLG_T_NERRFA                             BIT(3)
+#define   ERRFLG_T_NERRFB                             BIT(2)
+#define   ERRFLG_T_NERRFC                             BIT(1)
+#define   ERRFLG_T_NERRF                              BIT(0)
+#define DOSET1_T                                    0xcf
+
+#define CLK_LOW            4000000
+#define CLK_DIRECT         20200000
+#define CLK_MAX            25410000
+
+#define S_T_FREQ           8126984 /* 512 / 63 MHz */
+
+struct sc1501a_spec {
+	bool primary;
+};
+
+struct sc1501a_priv {
+	const struct sc1501a_spec *spec;
+
+	struct dvb_frontend fe;
+	struct clk *mclk;
+	struct gpio_desc *reset_gpio;
+	u32 clk_freq;
+	u32 if_freq;
+
+	/* Common */
+	bool use_clkbuf;
+
+	/* ISDB-S */
+	struct i2c_client *client_s;
+	struct regmap *regmap_s;
+
+	/* ISDB-T */
+	struct i2c_client *client_t;
+	struct regmap *regmap_t;
+};
+
+static void sc1501a_cmn_power_on(struct sc1501a_priv *chip)
+{
+	struct regmap *r_t = chip->regmap_t;
+
+	clk_prepare_enable(chip->mclk);
+
+	gpiod_set_value_cansleep(chip->reset_gpio, 1);
+	usleep_range(100, 1000);
+	gpiod_set_value_cansleep(chip->reset_gpio, 0);
+
+	if (chip->spec->primary) {
+		regmap_write(r_t, OUTCSET, OUTCSET_CHDRV_8MA);
+		regmap_write(r_t, PLDWSET, PLDWSET_NORMAL);
+		regmap_write(r_t, HIZSET1, 0x80);
+		regmap_write(r_t, HIZSET2, 0xe0);
+	} else {
+		regmap_write(r_t, HIZSET3, 0x8f);
+	}
+}
+
+static void sc1501a_cmn_power_off(struct sc1501a_priv *chip)
+{
+	gpiod_set_value_cansleep(chip->reset_gpio, 1);
+
+	clk_disable_unprepare(chip->mclk);
+}
+
+static void sc1501a_s_sleep(struct sc1501a_priv *chip)
+{
+	struct regmap *r_t = chip->regmap_t;
+
+	regmap_update_bits(r_t, PWDSET, PWDSET_PSKPD_MASK,
+			   PWDSET_PSKPD_DOWN);
+}
+
+static void sc1501a_s_wake(struct sc1501a_priv *chip)
+{
+	struct regmap *r_t = chip->regmap_t;
+
+	regmap_update_bits(r_t, PWDSET, PWDSET_PSKPD_MASK, 0);
+}
+
+static void sc1501a_s_tune(struct sc1501a_priv *chip,
+			   struct dtv_frontend_properties *c)
+{
+	struct regmap *r_s = chip->regmap_s;
+
+	regmap_write(r_s, ATSIDU_S, c->stream_id >> 8);
+	regmap_write(r_s, ATSIDL_S, c->stream_id);
+	regmap_write(r_s, TSSET_S, 0);
+}
+
+static int sc1501a_s_read_status(struct sc1501a_priv *chip,
+				 struct dtv_frontend_properties *c,
+				 enum fe_status *status)
+{
+	struct regmap *r_s = chip->regmap_s;
+	u32 cpmon, tmpu, tmpl, flg;
+	u64 tmp;
+
+	/* Sync detection */
+	regmap_read(r_s, CPMON1_S, &cpmon);
+
+	*status = 0;
+	if (cpmon & CPMON1_S_FSYNC)
+		*status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+	if (cpmon & CPMON1_S_W2LOCK)
+		*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+
+	/* Signal strength */
+	c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+	if (*status & FE_HAS_SIGNAL) {
+		u32 agc;
+
+		regmap_read(r_s, AGCREAD_S, &tmpu);
+		agc = tmpu << 8;
+
+		c->strength.len = 1;
+		c->strength.stat[0].scale = FE_SCALE_RELATIVE;
+		c->strength.stat[0].uvalue = agc;
+	}
+
+	/* C/N rate */
+	c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+	if (*status & FE_HAS_VITERBI) {
+		u32 cnr = 0, x, y, d;
+		u64 d_3 = 0;
+
+		regmap_read(r_s, CNRDXU_S, &tmpu);
+		regmap_read(r_s, CNRDXL_S, &tmpl);
+		x = (tmpu << 8) | tmpl;
+		regmap_read(r_s, CNRDYU_S, &tmpu);
+		regmap_read(r_s, CNRDYL_S, &tmpl);
+		y = (tmpu << 8) | tmpl;
+
+		/* CNR[dB]: 10 * log10(D) - 30.74 / D^3 - 3 */
+		/*   D = x^2 / (2^15 * y - x^2) */
+		d = (y << 15) - x * x;
+		if (d > 0) {
+			/* (2^4 * D)^3 = 2^12 * D^3 */
+			/* 3.074 * 2^(12 + 24) = 211243671486 */
+			d_3 = div_u64(16 * x * x, d);
+			d_3 = d_3 * d_3 * d_3;
+			if (d_3)
+				d_3 = div_u64(211243671486ULL, d_3);
+		}
+
+		if (d_3) {
+			/* 0.3 * 2^24 = 5033164 */
+			tmp = (s64)2 * intlog10(x) - intlog10(abs(d)) - d_3
+				- 5033164;
+			cnr = div_u64(tmp * 10000, 1 << 24);
+		}
+
+		if (cnr) {
+			c->cnr.len = 1;
+			c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+			c->cnr.stat[0].uvalue = cnr;
+		}
+	}
+
+	/* BER */
+	c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+	regmap_read(r_s, BERCNFLG_S, &flg);
+
+	if ((*status & FE_HAS_VITERBI) && (flg & BERCNFLG_S_BERVRDY)) {
+		u32 bit_err, bit_cnt;
+
+		regmap_read(r_s, BERVRDU_S, &tmpu);
+		regmap_read(r_s, BERVRDL_S, &tmpl);
+		bit_err = (tmpu << 8) | tmpl;
+		bit_cnt = (1 << 13) * 204;
+
+		if (bit_cnt) {
+			c->post_bit_error.len = 1;
+			c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+			c->post_bit_error.stat[0].uvalue = bit_err;
+			c->post_bit_count.len = 1;
+			c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+			c->post_bit_count.stat[0].uvalue = bit_cnt;
+		}
+	}
+
+	return 0;
+}
+
+static void sc1501a_t_sleep(struct sc1501a_priv *chip)
+{
+	struct regmap *r_t = chip->regmap_t;
+
+	regmap_update_bits(r_t, PWDSET, PWDSET_OFDMPD_MASK,
+			   PWDSET_OFDMPD_DOWN);
+}
+
+static void sc1501a_t_wake(struct sc1501a_priv *chip)
+{
+	struct regmap *r_t = chip->regmap_t;
+
+	regmap_update_bits(r_t, PWDSET, PWDSET_OFDMPD_MASK, 0);
+}
+
+static bool sc1501a_t_is_valid_clk(u32 adckt, u32 if_freq)
+{
+	if (if_freq == DIRECT_IF_57MHZ) {
+		if (adckt >= CLK_DIRECT && adckt <= 21000000)
+			return true;
+		if (adckt >= 25300000 && adckt <= CLK_MAX)
+			return true;
+	} else if (if_freq == DIRECT_IF_44MHZ) {
+		if (adckt >= 25000000 && adckt <= CLK_MAX)
+			return true;
+	} else if (if_freq >= LOW_IF_4MHZ && if_freq < DIRECT_IF_44MHZ) {
+		if (adckt >= CLK_DIRECT && adckt <= CLK_MAX)
+			return true;
+	}
+
+	return false;
+}
+
+static int sc1501a_t_set_freq(struct sc1501a_priv *chip)
+{
+	struct device *dev = &chip->client_s->dev;
+	struct regmap *r_t = chip->regmap_t;
+	s64 adckt, nco, ad_t;
+	u32 m, v;
+
+	/* Clock buffer (but not supported) or XTAL */
+	if (chip->clk_freq >= CLK_LOW && chip->clk_freq < CLK_DIRECT) {
+		chip->use_clkbuf = true;
+		regmap_write(r_t, CLKSET1_T, 0x07);
+
+		adckt = 0;
+	} else {
+		chip->use_clkbuf = false;
+		regmap_write(r_t, CLKSET1_T, 0x00);
+
+		adckt = chip->clk_freq;
+	}
+	if (!sc1501a_t_is_valid_clk(adckt, chip->if_freq)) {
+		dev_err(dev, "Invalid clock, CLK:%d, ADCKT:%lld, IF:%d\n",
+			chip->clk_freq, adckt, chip->if_freq);
+		return -EINVAL;
+	}
+
+	/* Direct IF or Low IF */
+	if (chip->if_freq == DIRECT_IF_57MHZ ||
+	    chip->if_freq == DIRECT_IF_44MHZ)
+		nco = adckt * 2 - chip->if_freq;
+	else
+		nco = -((s64)chip->if_freq);
+	nco = div_s64(nco << 24, adckt);
+	ad_t = div_s64(adckt << 22, S_T_FREQ);
+
+	regmap_write(r_t, NCOFREQU_T, nco >> 16);
+	regmap_write(r_t, NCOFREQM_T, nco >> 8);
+	regmap_write(r_t, NCOFREQL_T, nco);
+	regmap_write(r_t, FADU_T, ad_t >> 16);
+	regmap_write(r_t, FADM_T, ad_t >> 8);
+	regmap_write(r_t, FADL_T, ad_t);
+
+	/* Level of IF */
+	m = ADCSET1_T_REFSEL_MASK;
+	v = ADCSET1_T_REFSEL_1_5V;
+	regmap_update_bits(r_t, ADCSET1_T, m, v);
+
+	/* Polarity of AGC */
+	v = AGCSET2_T_IFPOLINV_INC | AGCSET2_T_RFPOLINV_INC;
+	regmap_update_bits(r_t, AGCSET2_T, v, v);
+
+	/* Lower output level of AGC */
+	regmap_write(r_t, AGCV3_T, 0x00);
+
+	regmap_write(r_t, MDSET_T, 0xfa);
+
+	return 0;
+}
+
+static void sc1501a_t_tune(struct sc1501a_priv *chip,
+			   struct dtv_frontend_properties *c)
+{
+	struct regmap *r_t = chip->regmap_t;
+	u32 m, v;
+
+	m = MDSET_T_MDAUTO_MASK | MDSET_T_FFTS_MASK | MDSET_T_GI_MASK;
+	v = MDSET_T_MDAUTO_AUTO | MDSET_T_FFTS_MODE3 | MDSET_T_GI_1_8;
+	regmap_update_bits(r_t, MDSET_T, m, v);
+
+	regmap_write(r_t, MDASET_T, 0);
+}
+
+static int sc1501a_t_read_status(struct sc1501a_priv *chip,
+				 struct dtv_frontend_properties *c,
+				 enum fe_status *status)
+{
+	struct regmap *r_t = chip->regmap_t;
+	u32 seqrd, st, flg, tmpu, tmpm, tmpl;
+	u64 tmp;
+
+	/* Sync detection */
+	regmap_read(r_t, SSEQRD_T, &seqrd);
+	st = seqrd & SSEQRD_T_SSEQSTRD_MASK;
+
+	*status = 0;
+	if (st >= SSEQRD_T_SSEQSTRD_SYNC)
+		*status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+	if (st >= SSEQRD_T_SSEQSTRD_FRAME_SYNC)
+		*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
+
+	/* Signal strength */
+	c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+	if (*status & FE_HAS_SIGNAL) {
+		u32 agc;
+
+		regmap_read(r_t, AGCRDU_T, &tmpu);
+		regmap_read(r_t, AGCRDL_T, &tmpl);
+		agc = (tmpu << 8) | tmpl;
+
+		c->strength.len = 1;
+		c->strength.stat[0].scale = FE_SCALE_RELATIVE;
+		c->strength.stat[0].uvalue = agc;
+	}
+
+	/* C/N rate */
+	c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+	if (*status & FE_HAS_VITERBI) {
+		u32 cnr;
+
+		regmap_read(r_t, CNRDU_T, &tmpu);
+		regmap_read(r_t, CNRDL_T, &tmpl);
+
+		if (tmpu || tmpl) {
+			/* CNR[dB]: 10 * (log10(65536 / value) + 0.2) */
+			/* intlog10(65536) = 80807124, 0.2 * 2^24 = 3355443 */
+			tmp = (u64)80807124 - intlog10((tmpu << 8) | tmpl)
+				+ 3355443;
+			cnr = div_u64(tmp * 10000, 1 << 24);
+		} else {
+			cnr = 0;
+		}
+
+		c->cnr.len = 1;
+		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
+		c->cnr.stat[0].uvalue = cnr;
+	}
+
+	/* BER */
+	c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+	c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
+
+	regmap_read(r_t, BERFLG_T, &flg);
+
+	if ((*status & FE_HAS_VITERBI) && (flg & BERFLG_T_BERVRDYA)) {
+		u32 bit_err, bit_cnt;
+
+		regmap_read(r_t, BERRDU_T, &tmpu);
+		regmap_read(r_t, BERRDM_T, &tmpm);
+		regmap_read(r_t, BERRDL_T, &tmpl);
+		bit_err = (tmpu << 16) | (tmpm << 8) | tmpl;
+
+		regmap_read(r_t, BERLENRDU_T, &tmpu);
+		regmap_read(r_t, BERLENRDL_T, &tmpl);
+		bit_cnt = ((tmpu << 8) | tmpl) * 203 * 8;
+
+		if (bit_cnt) {
+			c->post_bit_error.len = 1;
+			c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
+			c->post_bit_error.stat[0].uvalue = bit_err;
+			c->post_bit_count.len = 1;
+			c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
+			c->post_bit_count.stat[0].uvalue = bit_cnt;
+		}
+	}
+
+	return 0;
+}
+
+static int sc1501a_sleep(struct dvb_frontend *fe)
+{
+	struct sc1501a_priv *chip = fe->demodulator_priv;
+
+	sc1501a_s_sleep(chip);
+	sc1501a_t_sleep(chip);
+
+	return 0;
+}
+
+static int sc1501a_set_frontend(struct dvb_frontend *fe)
+{
+	struct sc1501a_priv *chip = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	struct regmap *r_s = chip->regmap_s;
+	struct regmap *r_t = chip->regmap_t;
+	u8 tssel = 0, intsel = 0;
+
+	if (c->delivery_system == SYS_ISDBS) {
+		sc1501a_s_wake(chip);
+		sc1501a_t_sleep(chip);
+
+		tssel = TSSET1_TSASEL_ISDBS;
+		intsel = TSSET3_INTASEL_S;
+	} else if (c->delivery_system == SYS_ISDBT) {
+		sc1501a_s_sleep(chip);
+		sc1501a_t_wake(chip);
+
+		sc1501a_t_set_freq(chip);
+
+		tssel = TSSET1_TSASEL_ISDBT;
+		intsel = TSSET3_INTASEL_T;
+	}
+
+	regmap_update_bits(r_t, TSSET1,
+			   TSSET1_TSASEL_MASK | TSSET1_TSBSEL_MASK,
+			   tssel | TSSET1_TSBSEL_NONE);
+	regmap_write(r_t, TSSET2, 0);
+	regmap_update_bits(r_t, TSSET3,
+			   TSSET3_INTASEL_MASK | TSSET3_INTBSEL_MASK,
+			   intsel | TSSET3_INTBSEL_NONE);
+
+	regmap_write(r_t, DOSET1_T, 0x95);
+	regmap_write(r_s, DOSET1_S, 0x80);
+
+	if (c->delivery_system == SYS_ISDBS)
+		sc1501a_s_tune(chip, c);
+	else if (c->delivery_system == SYS_ISDBT)
+		sc1501a_t_tune(chip, c);
+
+	if (fe->ops.tuner_ops.set_params) {
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 1);
+		fe->ops.tuner_ops.set_params(fe);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+	}
+
+	return 0;
+}
+
+static int sc1501a_get_tune_settings(struct dvb_frontend *fe,
+				     struct dvb_frontend_tune_settings *s)
+{
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+	s->min_delay_ms = 850;
+
+	if (c->delivery_system == SYS_ISDBS) {
+		s->max_drift = 30000 * 2 + 1;
+		s->step_size = 30000;
+	} else if (c->delivery_system == SYS_ISDBT) {
+		s->max_drift = 142857 * 2 + 1;
+		s->step_size = 142857 * 2;
+	}
+
+	return 0;
+}
+
+static int sc1501a_read_status(struct dvb_frontend *fe, enum fe_status *status)
+{
+	struct sc1501a_priv *chip = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+	if (c->delivery_system == SYS_ISDBS)
+		return sc1501a_s_read_status(chip, c, status);
+
+	if (c->delivery_system == SYS_ISDBT)
+		return sc1501a_t_read_status(chip, c, status);
+
+	return -EINVAL;
+}
+
+static const struct dvb_frontend_ops sc1501a_ops = {
+	.delsys = { SYS_ISDBS, SYS_ISDBT },
+	.info = {
+		.name          = "Socionext SC1501A",
+		.frequency_min = 1032000,
+		.frequency_max = 770000000,
+		.caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
+			FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
+			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
+	},
+
+	.sleep                   = sc1501a_sleep,
+	.set_frontend            = sc1501a_set_frontend,
+	.get_tune_settings       = sc1501a_get_tune_settings,
+	.read_status             = sc1501a_read_status,
+};
+
+static const struct regmap_config regmap_config = {
+	.reg_bits   = 8,
+	.val_bits   = 8,
+	.cache_type = REGCACHE_NONE,
+};
+
+static int sc1501a_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	struct sc1501a_config *conf = client->dev.platform_data;
+	struct sc1501a_priv *chip;
+	struct device *dev = &client->dev;
+	int ret;
+
+	chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	if (dev->of_node)
+		chip->spec = of_device_get_match_data(dev);
+	else
+		chip->spec = (struct sc1501a_spec *)id->driver_data;
+	if (!chip->spec)
+		return -EINVAL;
+
+	chip->mclk = devm_clk_get(dev, "mclk");
+	if (IS_ERR(chip->mclk) && !conf) {
+		dev_err(dev, "Failed to request mclk: %ld\n",
+			PTR_ERR(chip->mclk));
+		return PTR_ERR(chip->mclk);
+	}
+
+	ret = of_property_read_u32(dev->of_node, "if-frequency",
+				   &chip->if_freq);
+	if (ret && !conf) {
+		dev_err(dev, "Failed to load IF frequency: %d.\n", ret);
+		return ret;
+	}
+
+	chip->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+						   GPIOD_OUT_HIGH);
+	if (IS_ERR(chip->reset_gpio)) {
+		dev_err(dev, "Failed to request reset_gpio: %ld\n",
+			PTR_ERR(chip->reset_gpio));
+		return PTR_ERR(chip->reset_gpio);
+	}
+
+	if (conf) {
+		chip->mclk = conf->mclk;
+		chip->if_freq = conf->if_freq;
+		chip->reset_gpio = conf->reset_gpio;
+
+		*conf->fe = &chip->fe;
+	}
+
+	chip->client_s = client;
+	chip->regmap_s = devm_regmap_init_i2c(chip->client_s, &regmap_config);
+	if (IS_ERR(chip->regmap_s))
+		return PTR_ERR(chip->regmap_s);
+
+	/*
+	 * Chip has two I2C addresses for each satellite/terrestrial system.
+	 * ISDB-T uses address ISDB-S + 4, so we register a dummy client.
+	 */
+	chip->client_t = i2c_new_dummy(client->adapter, client->addr + 4);
+	if (!chip->client_t)
+		return -ENODEV;
+
+	chip->regmap_t = devm_regmap_init_i2c(chip->client_t, &regmap_config);
+	if (IS_ERR(chip->regmap_t)) {
+		ret = PTR_ERR(chip->regmap_t);
+		goto err_i2c_t;
+	}
+
+	chip->clk_freq = clk_get_rate(chip->mclk);
+
+	memcpy(&chip->fe.ops, &sc1501a_ops, sizeof(sc1501a_ops));
+	chip->fe.demodulator_priv = chip;
+	i2c_set_clientdata(client, chip);
+
+	sc1501a_cmn_power_on(chip);
+	sc1501a_s_sleep(chip);
+	sc1501a_t_sleep(chip);
+
+	return 0;
+
+err_i2c_t:
+	i2c_unregister_device(chip->client_t);
+
+	return ret;
+}
+
+static int sc1501a_remove(struct i2c_client *client)
+{
+	struct sc1501a_priv *chip = i2c_get_clientdata(client);
+
+	sc1501a_cmn_power_off(chip);
+
+	i2c_unregister_device(chip->client_t);
+
+	return 0;
+}
+
+static const struct sc1501a_spec sc1501a_spec_pri = {
+	.primary = true,
+};
+
+static const struct sc1501a_spec sc1501a_spec_sec = {
+	.primary = false,
+};
+
+static const struct of_device_id sc1501a_of_match[] = {
+	{ .compatible = "socionext,mn884433",   .data = &sc1501a_spec_pri, },
+	{ .compatible = "socionext,mn884434-0", .data = &sc1501a_spec_pri, },
+	{ .compatible = "socionext,mn884434-1", .data = &sc1501a_spec_sec, },
+	{ .compatible = "socionext,sc1501a",    .data = &sc1501a_spec_pri, },
+	{}
+};
+MODULE_DEVICE_TABLE(of, sc1501a_of_match);
+
+static const struct i2c_device_id sc1501a_i2c_id[] = {
+	{ "mn884433",   (kernel_ulong_t)&sc1501a_spec_pri },
+	{ "mn884434-0", (kernel_ulong_t)&sc1501a_spec_pri },
+	{ "mn884434-1", (kernel_ulong_t)&sc1501a_spec_sec },
+	{ "sc1501a",    (kernel_ulong_t)&sc1501a_spec_pri },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, sc1501a_i2c_id);
+
+static struct i2c_driver sc1501a_driver = {
+	.driver = {
+		.name = "sc1501a",
+		.of_match_table = of_match_ptr(sc1501a_of_match),
+	},
+	.probe    = sc1501a_probe,
+	.remove   = sc1501a_remove,
+	.id_table = sc1501a_i2c_id,
+};
+
+module_i2c_driver(sc1501a_driver);
+
+MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>");
+MODULE_DESCRIPTION("Socionext SC1501A series demodulator driver.");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/dvb-frontends/sc1501a.h b/drivers/media/dvb-frontends/sc1501a.h
new file mode 100644
index 000000000000..7e247d44e4ac
--- /dev/null
+++ b/drivers/media/dvb-frontends/sc1501a.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Socionext SC1501A series demodulator driver for ISDB-S/ISDB-T.
+ *
+ * Copyright (c) 2018 Socionext Inc.
+ */
+
+#ifndef SC1501A_H
+#define SC1501A_H
+
+#include <media/dvb_frontend.h>
+
+/* ISDB-T IF frequency */
+#define DIRECT_IF_57MHZ    57000000
+#define DIRECT_IF_44MHZ    44000000
+#define LOW_IF_4MHZ        4000000
+
+struct sc1501a_config {
+	struct clk *mclk;
+	u32 if_freq;
+	struct gpio_desc *reset_gpio;
+
+	/* Everything after that is returned by the driver. */
+	struct dvb_frontend **fe;
+};
+
+#endif /* SC1501A_H */
-- 
2.17.1

^ permalink raw reply related

* [RESEND PATCH] media: helene: fix xtal frequency setting at power on
From: Katsuhiro Suzuki @ 2018-06-21  3:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180529010920.20320-1-suzuki.katsuhiro@socionext.com>

Hello Mauro,

Ping...

If I got some mistake, please comment it...

Regards,
--
Katsuhiro Suzuki


> -----Original Message-----
> From: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>
> Sent: Tuesday, May 29, 2018 10:09 AM
> To: Abylay Ospan <aospan@netup.ru>; Mauro Carvalho Chehab
> <mchehab+samsung@kernel.org>; linux-media at vger.kernel.org
> Cc: Masami Hiramatsu <masami.hiramatsu@linaro.org>; Jassi Brar
> <jaswinder.singh@linaro.org>; linux-arm-kernel at lists.infradead.org;
> linux-kernel at vger.kernel.org; Suzuki, Katsuhiro/?? ??
> <suzuki.katsuhiro@socionext.com>
> Subject: [RESEND PATCH] media: helene: fix xtal frequency setting at power on
> 
> This patch fixes crystal frequency setting when power on this device.
> 
> Signed-off-by: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>
> Acked-by: Abylay Ospan <aospan@netup.ru>
> 
> ---
> 
> Changes from before:
>   - Add Abylay's Ack
> 
> ---
>  drivers/media/dvb-frontends/helene.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/media/dvb-frontends/helene.c
> b/drivers/media/dvb-frontends/helene.c
> index 0a4f312c4368..8fcf7a00782a 100644
> --- a/drivers/media/dvb-frontends/helene.c
> +++ b/drivers/media/dvb-frontends/helene.c
> @@ -924,7 +924,10 @@ static int helene_x_pon(struct helene_priv *priv)
>  	helene_write_regs(priv, 0x99, cdata, sizeof(cdata));
> 
>  	/* 0x81 - 0x94 */
> -	data[0] = 0x18; /* xtal 24 MHz */
> +	if (priv->xtal == SONY_HELENE_XTAL_16000)
> +		data[0] = 0x10; /* xtal 16 MHz */
> +	else
> +		data[0] = 0x18; /* xtal 24 MHz */
>  	data[1] = (uint8_t)(0x80 | (0x04 & 0x1F)); /* 4 x 25 = 100uA */
>  	data[2] = (uint8_t)(0x80 | (0x26 & 0x7F)); /* 38 x 0.25 = 9.5pF */
>  	data[3] = 0x80; /* REFOUT signal output 500mVpp */
> --
> 2.17.0

^ permalink raw reply

* [PATCH v2] ASoC: uniphier: remove redundant check of PLL ID
From: Katsuhiro Suzuki @ 2018-06-21  2:56 UTC (permalink / raw)
  To: linux-arm-kernel

This patch removes redudant check of PLL ID. struct uniphier_aio_pll
enable member has already been checked at is_valid_pll().

Signed-off-by: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>

---

Changes from v1:

  - Remove unused variable 'dev'
---
 sound/soc/uniphier/aio-cpu.c | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/sound/soc/uniphier/aio-cpu.c b/sound/soc/uniphier/aio-cpu.c
index 2d9b7dde2ffa..ee90e6c3937c 100644
--- a/sound/soc/uniphier/aio-cpu.c
+++ b/sound/soc/uniphier/aio-cpu.c
@@ -219,15 +219,10 @@ static int uniphier_aio_set_pll(struct snd_soc_dai *dai, int pll_id,
 				unsigned int freq_out)
 {
 	struct uniphier_aio *aio = uniphier_priv(dai);
-	struct device *dev = &aio->chip->pdev->dev;
 	int ret;
 
 	if (!is_valid_pll(aio->chip, pll_id))
 		return -EINVAL;
-	if (!aio->chip->plls[pll_id].enable) {
-		dev_err(dev, "PLL(%d) is not implemented\n", pll_id);
-		return -ENOTSUPP;
-	}
 
 	ret = aio_chip_set_pll(aio->chip, pll_id, freq_out);
 	if (ret < 0)
-- 
2.17.1

^ permalink raw reply related

* [PATCH v4] PCI: mediatek: Add system pm support for MT2712
From: honghui.zhang at mediatek.com @ 2018-06-21  2:55 UTC (permalink / raw)
  To: linux-arm-kernel

From: Honghui Zhang <honghui.zhang@mediatek.com>

The MTCMOS of PCIe Host for MT2712 will be off when system suspend, and all
the internal control register will be reset after system resume. The PCIe
link should be re-established and the related control register values
should be re-set after system resume.

Signed-off-by: Honghui Zhang <honghui.zhang@mediatek.com>
CC: Ryder Lee <ryder.lee@mediatek.com>
---
 drivers/pci/controller/pcie-mediatek.c | 60 ++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

Change since v3:
 - rebase to v4.18-rc1.

diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
index 0baabe3..1ed2ef0 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -134,12 +134,14 @@ struct mtk_pcie_port;
 /**
  * struct mtk_pcie_soc - differentiate between host generations
  * @need_fix_class_id: whether this host's class ID needed to be fixed or not
+ * @pm_support: whether the host's MTCMOS will be off when suspend
  * @ops: pointer to configuration access functions
  * @startup: pointer to controller setting functions
  * @setup_irq: pointer to initialize IRQ functions
  */
 struct mtk_pcie_soc {
 	bool need_fix_class_id;
+	bool pm_support;
 	struct pci_ops *ops;
 	int (*startup)(struct mtk_pcie_port *port);
 	int (*setup_irq)(struct mtk_pcie_port *port, struct device_node *node);
@@ -1181,12 +1183,69 @@ static int mtk_pcie_probe(struct platform_device *pdev)
 	return err;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int mtk_pcie_suspend_noirq(struct device *dev)
+{
+	struct mtk_pcie *pcie = dev_get_drvdata(dev);
+	const struct mtk_pcie_soc *soc = pcie->soc;
+	struct mtk_pcie_port *port;
+
+	if (!soc->pm_support)
+		return 0;
+
+	list_for_each_entry(port, &pcie->ports, list) {
+		clk_disable_unprepare(port->ahb_ck);
+		clk_disable_unprepare(port->sys_ck);
+		phy_power_off(port->phy);
+	}
+
+	return 0;
+}
+
+static int mtk_pcie_resume_noirq(struct device *dev)
+{
+	struct mtk_pcie *pcie = dev_get_drvdata(dev);
+	const struct mtk_pcie_soc *soc = pcie->soc;
+	struct mtk_pcie_port *port;
+	int ret;
+
+	if (!soc->pm_support)
+		return 0;
+
+	list_for_each_entry(port, &pcie->ports, list) {
+		phy_power_on(port->phy);
+		clk_prepare_enable(port->sys_ck);
+		clk_prepare_enable(port->ahb_ck);
+
+		ret = soc->startup(port);
+		if (ret) {
+			dev_err(dev, "Port%d link down\n", port->slot);
+			phy_power_off(port->phy);
+			clk_disable_unprepare(port->sys_ck);
+			clk_disable_unprepare(port->ahb_ck);
+			return ret;
+		}
+
+		if (IS_ENABLED(CONFIG_PCI_MSI))
+			mtk_pcie_enable_msi(port);
+	}
+
+	return 0;
+}
+#endif
+
+static const struct dev_pm_ops mtk_pcie_pm_ops = {
+	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(mtk_pcie_suspend_noirq,
+				      mtk_pcie_resume_noirq)
+};
+
 static const struct mtk_pcie_soc mtk_pcie_soc_v1 = {
 	.ops = &mtk_pcie_ops,
 	.startup = mtk_pcie_startup_port,
 };
 
 static const struct mtk_pcie_soc mtk_pcie_soc_mt2712 = {
+	.pm_support = true,
 	.ops = &mtk_pcie_ops_v2,
 	.startup = mtk_pcie_startup_port_v2,
 	.setup_irq = mtk_pcie_setup_irq,
@@ -1213,6 +1272,7 @@ static struct platform_driver mtk_pcie_driver = {
 		.name = "mtk-pcie",
 		.of_match_table = mtk_pcie_ids,
 		.suppress_bind_attrs = true,
+		.pm = &mtk_pcie_pm_ops,
 	},
 };
 builtin_platform_driver(mtk_pcie_driver);
-- 
2.6.4

^ permalink raw reply related

* [PATCH] ASoC: uniphier: remove redundant check of PLL ID
From: Katsuhiro Suzuki @ 2018-06-21  2:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180621024346.13131-1-suzuki.katsuhiro@socionext.com>

Hello,

I got mistake (forget to remove unused variable).
I'll send v2. Sorry for confusing.

Regards,
--
Katsuhiro Suzuki


> -----Original Message-----
> From: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>
> Sent: Thursday, June 21, 2018 11:44 AM
> To: Mark Brown <broonie@kernel.org>; alsa-devel at alsa-project.org
> Cc: Masami Hiramatsu <masami.hiramatsu@linaro.org>; Jassi Brar
> <jaswinder.singh@linaro.org>; linux-arm-kernel at lists.infradead.org;
> linux-kernel at vger.kernel.org; Suzuki, Katsuhiro/?? ??
> <suzuki.katsuhiro@socionext.com>
> Subject: [PATCH] ASoC: uniphier: remove redundant check of PLL ID
> 
> This patch removes redudant check of PLL ID. struct uniphier_aio_pll
> enable member has already been checked at is_valid_pll().
> 
> Signed-off-by: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>
> ---
>  sound/soc/uniphier/aio-cpu.c | 4 ----
>  1 file changed, 4 deletions(-)
> 
> diff --git a/sound/soc/uniphier/aio-cpu.c b/sound/soc/uniphier/aio-cpu.c
> index 2d9b7dde2ffa..cfe69ab44b63 100644
> --- a/sound/soc/uniphier/aio-cpu.c
> +++ b/sound/soc/uniphier/aio-cpu.c
> @@ -224,10 +224,6 @@ static int uniphier_aio_set_pll(struct snd_soc_dai *dai,
int
> pll_id,
> 
>  	if (!is_valid_pll(aio->chip, pll_id))
>  		return -EINVAL;
> -	if (!aio->chip->plls[pll_id].enable) {
> -		dev_err(dev, "PLL(%d) is not implemented\n", pll_id);
> -		return -ENOTSUPP;
> -	}
> 
>  	ret = aio_chip_set_pll(aio->chip, pll_id, freq_out);
>  	if (ret < 0)
> --
> 2.17.1

^ permalink raw reply

* [PATCH 1/1] arm64/mm: move {idmap_pg_dir,tramp_pg_dir,swapper_pg_dir} to .rodata section
From: Jun Yao @ 2018-06-21  2:51 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAKv+Gu8_=uTJFDXr0GpGMc=9WZ9tbz305CE6i=qbnqRB=suRVA@mail.gmail.com>

Hi Ard,

On Wed, Jun 20, 2018 at 12:09:49PM +0200, Ard Biesheuvel wrote:
> On 20 June 2018 at 10:57, Jun Yao <yaojun8558363@gmail.com> wrote:
> > Move {idmap_pg_dir,tramp_pg_dir,swapper_pg_dir} to .rodata
> > section. And update the swapper_pg_dir by fixmap.
> >
> 
> I think we may be able to get away with not mapping idmap_pg_dir and
> tramp_pg_dir at all.

I think we need to move tramp_pg_dir to .rodata. The attacker can write
a block-mapping(AP=01) to tramp_pg_dir and then he can access kernel
memory.

> As for swapper_pg_dir, it would indeed be nice if we could keep those
> mappings read-only most of the time, but I'm not sure how useful this
> is if we apply it to the root level only.

The purpose of it is to make 'KSMA' harder, where an single arbitrary
write is used to add a block mapping to the page-tables, giving the
attacker full access to kernel memory. That's why we just apply it to
the root level only. If the attacker can arbitrary write multiple times,
I think it's hard to defend.

> > @@ -417,12 +421,22 @@ static void __init __map_memblock(pgd_t *pgdp, phys_addr_t start,
> >
> >  void __init mark_linear_text_alias_ro(void)
> >  {
> > +       unsigned long size;
> > +
> >         /*
> >          * Remove the write permissions from the linear alias of .text/.rodata
> > +        *
> > +        * We free some pages in .rodata at paging_init(), which generates a
> > +        * hole. And the hole splits .rodata into two pieces.
> >          */
> > +       size = (unsigned long)swapper_pg_dir + PAGE_SIZE - (unsigned long)_text;
> >         update_mapping_prot(__pa_symbol(_text), (unsigned long)lm_alias(_text),
> > -                           (unsigned long)__init_begin - (unsigned long)_text,
> > -                           PAGE_KERNEL_RO);
> > +                           size, PAGE_KERNEL_RO);
> > +
> > +       size = (unsigned long)__init_begin - (unsigned long)swapper_pg_end;
> > +       update_mapping_prot(__pa_symbol(swapper_pg_end),
> > +                           (unsigned long)lm_alias(swapper_pg_end),
> > +                           size, PAGE_KERNEL_RO);
> 
> I don't think this is necessary. Even if some pages are freed, it
> doesn't harm to keep a read-only alias of them here since the new
> owner won't access them via this mapping anyway. So we can keep
> .rodata as a single region.

To be honest, I didn't think of this issue at first. I later found a
problem when testing the code on qemu:

[    7.027935] Unable to handle kernel write to read-only memory at virtual address ffff800000f42c00
[    7.028388] Mem abort info:
[    7.028495]   ESR = 0x9600004f
[    7.028602]   Exception class = DABT (current EL), IL = 32 bits
[    7.028749]   SET = 0, FnV = 0
[    7.028837]   EA = 0, S1PTW = 0
[    7.028930] Data abort info:
[    7.029017]   ISV = 0, ISS = 0x0000004f
[    7.029120]   CM = 0, WnR = 1
[    7.029253] swapper pgtable: 4k pages, 48-bit VAs, pgdp =         (ptrval)
[    7.029418] [ffff800000f42c00] pgd=00000000beff6803, pud=00000000beff5803, pmd=00000000beff3803, pte=00e0000040f42f93
[    7.029807] Internal error: Oops: 9600004f [#1] PREEMPT SMP
[    7.030027] Modules linked in:
[    7.030256] CPU: 0 PID: 1321 Comm: jbd2/vda-8 Not tainted 4.17.0-rc4-02908-g0fe42512b2f0-dirty #71
[    7.030486] Hardware name: linux,dummy-virt (DT)
[    7.030708] pstate: 40400005 (nZcv daif +PAN -UAO)
[    7.030880] pc : __memset+0x16c/0x1c0
[    7.030993] lr : jbd2_journal_get_descriptor_buffer+0x7c/0xfc
[    7.031134] sp : ffff00000a8ebbe0
[    7.031264] x29: ffff00000a8ebbe0 x28: ffff80007c104800
[    7.031430] x27: ffff00000a8ebd98 x26: ffff80007c4410d0
[    7.031567] x25: ffff80007c441118 x24: 00000000ffffffff
[    7.031704] x23: ffff80007c41b000 x22: ffff0000090d9000
[    7.031838] x21: 0000000002000000 x20: ffff80007bcee800
[    7.031973] x19: ffff80007c4413a8 x18: 0000000000000727
[    7.032107] x17: 0000ffff89eba028 x16: ffff0000080e2c38
[    7.032286] x15: ffff7e0000000000 x14: 0000000000048018
[    7.032424] x13: 0000000048018c00 x12: ffff80007bc65788
[    7.032558] x11: ffff00000a8eba68 x10: 0000000000000040
[    7.032709] x9 : 0000000000000000 x8 : ffff800000f42c00
[    7.032849] x7 : 0000000000000000 x6 : 000000000000003f
[    7.032984] x5 : 0000000000000040 x4 : 0000000000000000
[    7.033119] x3 : 0000000000000004 x2 : 00000000000003c0
[    7.033254] x1 : 0000000000000000 x0 : ffff800000f42c00
[    7.033414] Process jbd2/vda-8 (pid: 1321, stack limit = 0x        (ptrval))
[    7.033633] Call trace:
[    7.033757]  __memset+0x16c/0x1c0
[    7.033858]  journal_submit_commit_record+0x60/0x174
[    7.033985]  jbd2_journal_commit_transaction+0xf38/0x1330
[    7.034115]  kjournald2+0xcc/0x250
[    7.034207]  kthread+0xfc/0x128
[    7.034295]  ret_from_fork+0x10/0x18
[    7.034718] Code: 91010108 54ffff4a 8b040108 cb050042 (d50b7428)
[    7.035104] ---[ end trace 26d65a14ae983167 ]---

/sys/kernel/debug/kernel_page_tables shows that:

---[ Linear Mapping ]---
0xffff800000000000-0xffff800000080000         512K PTE       RW NX SHD AF NG CON     UXN MEM/NORMAL
0xffff800000080000-0xffff800000200000        1536K PTE       ro NX SHD AF NG         UXN MEM/NORMAL
0xffff800000200000-0xffff800000e00000          12M PMD       RW NX SHD AF NG     BLK UXN MEM/NORMAL
0xffff800000e00000-0xffff800000fb0000        1728K PTE       ro NX SHD AF NG         UXN MEM/NORMAL

So I split it into pieces.

Thanks,

Jun

^ permalink raw reply

* [PATCH] ASoC: uniphier: remove redundant check of PLL ID
From: Katsuhiro Suzuki @ 2018-06-21  2:43 UTC (permalink / raw)
  To: linux-arm-kernel

This patch removes redudant check of PLL ID. struct uniphier_aio_pll
enable member has already been checked at is_valid_pll().

Signed-off-by: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>
---
 sound/soc/uniphier/aio-cpu.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/sound/soc/uniphier/aio-cpu.c b/sound/soc/uniphier/aio-cpu.c
index 2d9b7dde2ffa..cfe69ab44b63 100644
--- a/sound/soc/uniphier/aio-cpu.c
+++ b/sound/soc/uniphier/aio-cpu.c
@@ -224,10 +224,6 @@ static int uniphier_aio_set_pll(struct snd_soc_dai *dai, int pll_id,
 
 	if (!is_valid_pll(aio->chip, pll_id))
 		return -EINVAL;
-	if (!aio->chip->plls[pll_id].enable) {
-		dev_err(dev, "PLL(%d) is not implemented\n", pll_id);
-		return -ENOTSUPP;
-	}
 
 	ret = aio_chip_set_pll(aio->chip, pll_id, freq_out);
 	if (ret < 0)
-- 
2.17.1

^ permalink raw reply related

* Dynamic ftrace self test broken on ARM
From: Steven Rostedt @ 2018-06-21  1:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180620230734.GO17671@n2100.armlinux.org.uk>

On Thu, 21 Jun 2018 00:07:34 +0100
Russell King - ARM Linux <linux@armlinux.org.uk> wrote:


> > Any input from ARM folks?  
> 
> The same issues must exist on other architectures as ARM is not the only
> architecture to implement read-only kernel text and dynamic ftrace, so
> surely this problem isn't unique to ARM.

Probably because of the way set_kernel_text_ro() is implemented in
other archs. For example, in x86, we have:

void set_kernel_text_ro(void)
{
	unsigned long start = PFN_ALIGN(_text);
	unsigned long end = PFN_ALIGN(__stop___ex_table);

	if (!kernel_set_to_readonly)
		return;

	/*
	 * Set the kernel identity mapping for text RO.
	 */
	set_memory_ro(start, (end - start) >> PAGE_SHIFT);
}

and arm has:

void set_kernel_text_ro(void)
{
	set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), true,
				current->active_mm);
}

Where x86's set_kernel_text_ro() is a nop until the
kernel_set_to_readonly is set.

Perhaps this may fix things?

[ Not even compiled tested ]

-- Steve

diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index c186474422f3..0cc8e04295a4 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -736,20 +736,29 @@ static int __mark_rodata_ro(void *unused)
 	return 0;
 }
 
+static int kernel_set_to_readonly __read_mostly;
+
 void mark_rodata_ro(void)
 {
+	kernel_set_to_readonly = 1;
 	stop_machine(__mark_rodata_ro, NULL, NULL);
 	debug_checkwx();
 }
 
 void set_kernel_text_rw(void)
 {
+	if (!kernel_set_to_readonly)
+		return;
+
 	set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), false,
 				current->active_mm);
 }
 
 void set_kernel_text_ro(void)
 {
+	if (!kernel_set_to_readonly)
+		return;
+
 	set_section_perms(ro_perms, ARRAY_SIZE(ro_perms), true,
 				current->active_mm);
 }

^ permalink raw reply related

* [linux-sunxi] Re: [PATCH v2 11/27] drm/sun4i: tcon: Add support for tcon-top gate
From: Chen-Yu Tsai @ 2018-06-21  1:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <2581098.bNJirayF9O@jernej-laptop>

On Thu, Jun 21, 2018 at 3:37 AM, Jernej ?krabec <jernej.skrabec@siol.net> wrote:
> Dne sobota, 16. junij 2018 ob 07:48:38 CEST je Chen-Yu Tsai napisal(a):
>> On Sat, Jun 16, 2018 at 1:33 AM, Jernej ?krabec <jernej.skrabec@siol.net>
> wrote:
>> > Dne petek, 15. junij 2018 ob 19:13:17 CEST je Chen-Yu Tsai napisal(a):
>> >> On Sat, Jun 16, 2018 at 12:41 AM, Jernej ?krabec
>> >>
>> >> <jernej.skrabec@siol.net> wrote:
>> >> > Hi,
>> >> >
>> >> > Dne petek, 15. junij 2018 ob 10:31:10 CEST je Maxime Ripard napisal(a):
>> >> >> Hi,
>> >> >>
>> >> >> On Tue, Jun 12, 2018 at 10:00:20PM +0200, Jernej Skrabec wrote:
>> >> >> > TV TCONs connected to TCON TOP have to enable additional gate in
>> >> >> > order
>> >> >> > to work.
>> >> >> >
>> >> >> > Add support for such TCONs.
>> >> >> >
>> >> >> > Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
>> >> >> > ---
>> >> >> >
>> >> >> >  drivers/gpu/drm/sun4i/sun4i_tcon.c | 11 +++++++++++
>> >> >> >  drivers/gpu/drm/sun4i/sun4i_tcon.h |  4 ++++
>> >> >> >  2 files changed, 15 insertions(+)
>> >> >> >
>> >> >> > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
>> >> >> > b/drivers/gpu/drm/sun4i/sun4i_tcon.c index
>> >> >> > 08747fc3ee71..0afb5a94a414
>> >> >> > 100644
>> >> >> > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
>> >> >> > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
>> >> >> > @@ -688,6 +688,16 @@ static int sun4i_tcon_init_clocks(struct device
>> >> >> > *dev,
>> >> >> >
>> >> >> >             dev_err(dev, "Couldn't get the TCON bus clock\n");
>> >> >> >             return PTR_ERR(tcon->clk);
>> >> >> >
>> >> >> >     }
>> >> >> >
>> >> >> > +
>> >> >> > +   if (tcon->quirks->has_tcon_top_gate) {
>> >> >> > +           tcon->top_clk = devm_clk_get(dev, "tcon-top");
>> >> >> > +           if (IS_ERR(tcon->top_clk)) {
>> >> >> > +                   dev_err(dev, "Couldn't get the TCON TOP bus
>> >> >> > clock\n");
>> >> >> > +                   return PTR_ERR(tcon->top_clk);
>> >> >> > +           }
>> >> >> > +           clk_prepare_enable(tcon->top_clk);
>> >> >> > +   }
>> >> >> > +
>> >> >>
>> >> >> Is it required for the TCON itself to operate, or does the TCON
>> >> >> requires the TCON TOP, which in turn requires that clock to be
>> >> >> functional?
>> >> >>
>> >> >> I find it quite odd to have a clock that isn't meant for a particular
>> >> >> device to actually be wired to another device. I'm not saying this
>> >> >> isn't the case, but it would be a first.
>> >> >
>> >> > Documentation doesn't say much about that gate. I did few tests and
>> >> > TCON
>> >> > registers can be read and written even if TCON TOP TV TCON gate is
>> >> > disabled. However, there is no image, as expected.
>> >>
>> >> The R40 manual does include it in the diagram, on page 504. There's also
>> >> a
>> >> mux to select whether the clock comes directly from the CCU or the TV
>> >> encoder (a feedback mode?). I assume this is the gate you are referring
>> >> to
>> >> here, in which case it is not a bus clock, but rather the TCON module or
>> >> channel clock, strangely routed.
>> >>
>> >> > More interestingly, I enabled test pattern directly in TCON to
>> >> > eliminate
>> >> > influence of the mixer. As soon as I disabled that gate, test pattern
>> >> > on
>> >> > HDMI screen was gone, which suggest that this gate influences something
>> >> > inside TCON.
>> >> >
>> >> > Another test I did was that I moved enable/disable gate code to
>> >> > sun4i_tcon_channel_set_status() and it worked just as well.
>> >> >
>> >> > I'll ask AW engineer what that gate actually does, but from what I saw,
>> >> > I
>> >> > would say that most appropriate location to enable/disable TCON TOP TV
>> >> > TCON
>> >> > gate is TCON driver. Alternatively, TCON TOP driver could check if any
>> >> > TV
>> >> > TCON is in use and enable appropriate gate. However, that doesn't sound
>> >> > right to me for some reason.
>> >>
>> >> If what I said above it true, then yes, the appropriate location to
>> >> enable
>> >> it is the TCON driver, but moreover, the representation of the clock tree
>> >> should be fixed such that the TCON takes the clock from the TCON TOP as
>> >> its
>> >> channel/ module clock instead. That way you don't need this patch, but
>> >> you'd add another for all the clock routing.
>> >
>> > Can you be more specific? I not sure what you mean here.
>>
>> For clock related properties in the device tree:
>>
>> &tcon_top {
>>     clocks = <&ccu CLK_BUS_TCON_TOP>,
>>              <&ccu CLK_TCON_TV0>,
>>              <&tve0>,
>>              <&ccu CLK_TCON_TV1>,
>>              <&tve1>;
>>     clock-names = "bus", "tcon-tv0", "tve0", "tcon-tv1", "tve1";
>>     clock-output-names = "tcon-top-tv0", "tcon-top-tv1";
>> };
>>
>> &tcon_tv0 {
>>     clocks = <&ccu CLK_BUS_TCON_TV0>, <&tcon_top 0>'
>>     clock-names = "ahb", "tcon-ch1";
>> };
>>
>> A diagram would look like:
>>                    | This part is TCON TOP |
>>
>>                    v                       v
>> CCU CLK_TCON_TV0 --|----\                  |
>>
>>                    |     mux ---- gate ----|-- TCON_TV0
>>
>> TVE0 --------------|----/                  |
>>
>> And the same goes for TCON_TV1 and TVE1.
>>
>> The user manual is a bit lacking on how TVE outputs a clock though.
>
> I didn't yet received any response on HW details from AW till now, but I would
> like to post new version of patches soon.
>
> While chaining like you described could be implemented easily, I don't think
> it really represents HW as it is. Tests showed that these two clocks are
> independent, otherwise register writes/reads wouldn't be possible with tcon-
> top gate disabled. I chose tcon-top bus clock as a parent becase if it is not
> enabled, it simply won't work.

AFAIK with the TCONs, even when the TCON channel clock (not the bus clock) is
disabled, register accesses still work. I'm saying that the TCON TOP gate
is downstream from the TCON channel clock in the CCU. These are not related
to the TCON bus clock in the CCU, which affects register access.

Did Allwinner provide any information regarding the hierarchy of the clocks?

> However, if everyone feels chaining is the best way to implement it, I'll do
> it.

I would like to get it right and match actual hardware. My proposal is
based on my understanding from the diagrams in the user manual.

Regards
ChenYu

^ permalink raw reply

* [PATCH 1/1] arm64: dts: rockchip: correct voltage selector Firefly-RK3399
From: Heinrich Schuchardt @ 2018-06-21  0:57 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <cd7447bc-1c3d-29ca-9671-144b1f474711@gmx.de>

On 06/20/2018 09:57 PM, Heinrich Schuchardt wrote:
> On 06/20/2018 11:15 AM, Heiko St?bner wrote:
>> Hi Heinrich,
>>
>> Am Mittwoch, 20. Juni 2018, 07:59:34 CEST schrieb Heinrich Schuchardt:
>>> On 06/20/2018 01:21 AM, Heiko Stuebner wrote:
>>>> Am Donnerstag, 14. Juni 2018, 14:55:27 CEST schrieb Heiko Stuebner:
>>>>> Am Montag, 4. Juni 2018, 19:15:23 CEST schrieb Heinrich Schuchardt:
>>>>>> Without this patch the Firefly-RK3399 board boot process hangs after
>>>>>> these
>>>>>>
>>>>>> lines:
>>>>>>    fan53555-regulator 0-0040: FAN53555 Option[8] Rev[1] Detected!
>>>>>>    fan53555-reg: supplied by vcc_sys
>>>>>>    vcc1v8_s3: supplied by vcc_1v8
>>>>>>
>>>>>> Blacklisting driver fan53555 allows booting.
>>>>>>
>>>>>> The device tree uses a value of fcs,suspend-voltage-selector different
>>>>>> to
>>>>>> any other board.
>>>>>>
>>>>>> Changing this setting to the usual value is sufficient to enable
>>>>>> booting.
>>>>>>
>>>>>> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
>>>>>
>>>>> applied for 4.19.
>>>>
>>>> and dropped again.
>>>>
>>>> Sadly it looks like the patch causes conflicts with at least one firefly
>>>> board in a kernelci lab. My own is currently not ready to use, so I cannot
>>>> look myself right now.
>>>>
>>>> The issue kernelci people described sounded quite a lot like the one
>>>> in your commit message, so my current theory is that the
>>>> suspend-voltage-selector must in some form corespond to the
>>>> cpu_b_sleep_h gpio setting we're currently not handling at all, which
>>>> would therefore depend on how the bootloader sets this up.
>>>
>>> please, provide a link to the log displaying the issue and the contact
>>> who can provide the exact setup.
>>>
>>> I have been testing with U-Boot as boot loader.
>>
>> failing boot can be found on
>> https://kernelci.org/boot/id/5b2a053d59b514569079a872/
>>
>> As this board is sitting in the "lab-baylibre-seattle", I guess
>> Kevin Hilman (Cc'ed now) is the one that can say a bit more about the
>> board setup.
>>
>>
>> The more interesting question would be how to make sure we don't
>> die with possible different bootloader versions. As I don't really thing 
>> "upgrade your bootloader" is an always valid option.
>>
>>
>> Heiko
>>
> 
> Hi Kevin,
> 
> the RK3399-Firefly was booted on lab-baylibre-seattle with
> U-Boot 2017.05-rc3-00131-gf79fd58d5f5c-dirty
> 
> f79fd58d5f5c is not a commit in U-Boot master.
> The version number tells us it is 131 patches ahead of U-Boot 2017.05-rc3.
> Dirty means the source contained uncommitted changes.
> 
> Unfortunately this is not a reproducible test environment.
> Could you, please, provide the build recipe to reproduce the U-Boot
> BayLibre is using?
> Would it be possible to use mainline U-Boot in kernelci for this board?
> 
> Best regards
> 
> Heinrich
> 

I have now built the last available release of U-Boot (v2018.05)
according to the following recipe:

git clone https://github.com/xypron/u-boot-build.git
cd u-boot-build/
git checkout firefly-rk3399-rkloader
# commit 251b12fb4f0eabfff2d0552d0807d8ddc44ae2aa
# tag firefly-rk3399-rkloader-v2018.05
make
make install DESTDIR=foo
cd foo/usr/lib/u-boot/firefly-rk3399/
# be careful to specify your SD card as device!
./sd_fusing /dev/sdX

# in U-Boot 2018.05 (Jun 21 2018 - 02:33:12 +0200)
load mmc 1:1 ${fdt_addr_r} 2018-06-20/rk3399-firefly.dtb
load mmc 1:1 ${kernel_addr_r} 2018-06-20/Image
booti ${kernel_addr_r} - ${fdt_addr_r}

The error observed in kernelci when initializing the FAN53555 driver
does not occur.

The console log is here:
https://gist.github.com/xypron/34b6485deabfc8172f978b5a99705466

Best regards

Heinrich

^ permalink raw reply

* Dynamic ftrace self test broken on ARM
From: Russell King - ARM Linux @ 2018-06-20 23:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <ac0178fb75658a8d7d7b1931691c7755@agner.ch>

On Thu, Jun 21, 2018 at 12:45:04AM +0200, Stefan Agner wrote:
> On 20.06.2018 23:32, Stefan Agner wrote:
> > On 20.06.2018 21:06, Stefan Agner wrote:
> >> On 20.06.2018 16:13, Steven Rostedt wrote:
> >>> On Wed, 20 Jun 2018 15:51:55 +0200
> >>> Stefan Agner <stefan@agner.ch> wrote:
> >>>
> >>>
> >>>> v4.9 seems to work, so I started bisecting. It turned out that commit
> >>>> 6f05d0761af6 ("ARM: 8668/1: ftrace: Fix dynamic ftrace with DEBUG_RODATA
> >>>> and !FRAME_POINTER") broke it, introduced during the v4.12 merge window.
> >>>
> >>> That patch doesn't appear to be the cause. It could have been a failed
> >>> bisect. Does the commit before that commit work? Does that commit fail?
> >>
> >> Pretty sure it is that one. Reverting it on top of v4.18-rc1 fixes it...
> >>
> >>>
> >>> It may be due to some other RODATA change though. That is actually one
> >>> of my thoughts when looking at the bug.
> >>
> >> CONFIG_STRICT_KERNEL_RWX=y is set, will test without.
> > 
> > Compiling without CONFIG_STRICT_KERNEL_RWX fixes the issue too. So seems
> > to be a RODATA issue...
> 
> Ok, I understand the issue now:
> 
> In ARM ftrace we set kernel text to RW and back to RO in
> arch_ftrace_update_code.
> 
> ARM sets the kernel at free_initmem to RO. So using ftrace selftest sets
> the kernel text to RO much earlier, which seems to cause issues.
> 
> Reverting the above commit actually fixes selftests during boot, but it
> breaks ftrace at runtime...
> 
> This resolves the issue:
> 
> +static int __ftrace_modify_code_boot(void *data)
> +{
> +       int *command = data;
> +
> +       ftrace_modify_all_code(*command);
> +
> +       return 0;
> +}
> +
>  void arch_ftrace_update_code(int command)
>  {
> -       stop_machine(__ftrace_modify_code, &command, NULL);
> +       if (system_state < SYSTEM_RUNNING)
> +               stop_machine(__ftrace_modify_code_boot, &command, NULL);
> +       else
> +               stop_machine(__ftrace_modify_code, &command, NULL);
>  }
> 
> Using system_state to indicate whether fix_kernmem_perms has been called
> is rather brittle...
> 
> Any input from ARM folks?

The same issues must exist on other architectures as ARM is not the only
architecture to implement read-only kernel text and dynamic ftrace, so
surely this problem isn't unique to ARM.

It looks to me like x86 sets ARCH_HAS_STRICT_KERNEL_RWX, so surely the
kernel text there is protected against modification of the kernel text.
x86 seems to use probe_kernel_write() in the ftrace code, but I don't
see how that would succeed with ARCH_HAS_STRICT_KERNEL_RWX.  Does
dynamic ftrace work on x86, if so, how?

It looks like powerpc also supports the combination, but again I don't
see anything obvious that suggests how it gets around the kernel text
read-only-ness.

-- 
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up

^ permalink raw reply

* [PATCH v2 2/4] dt-bindings: misc: Aspeed coprocessor interrupt controller
From: Benjamin Herrenschmidt @ 2018-06-20 23:05 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180620194937.GA5088@rob-hp-laptop>

On Wed, 2018-06-20 at 13:49 -0600, Rob Herring wrote:
> On Mon, Jun 18, 2018 at 02:59:00PM +1000, Benjamin Herrenschmidt wrote:
> > Add the device-tree binding definition for the AST2400
> > and AST2500 coprocessor interrupt controller
> > 
> > Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > ---
> >  .../devicetree/bindings/misc/aspeed,cvic.txt  | 35 +++++++++++++++++++
> >  1 file changed, 35 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/misc/aspeed,cvic.txt
> > 
> > diff --git a/Documentation/devicetree/bindings/misc/aspeed,cvic.txt b/Documentation/devicetree/bindings/misc/aspeed,cvic.txt
> > new file mode 100644
> > index 000000000000..2562e2991e4d
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/misc/aspeed,cvic.txt
> > @@ -0,0 +1,35 @@
> > +* Aspeed AST2400 and AST2500 coprocessor interrupt controller
> > +
> > +This file describes the bindings for the interrupt controller present
> > +in the AST2400 and AST2500 BMC SoCs which provides interrupt to the
> > +ColdFire coprocessor.
> > +
> > +It is not a normal interrupt controller and it would be rather
> > +inconvenient to create an interrupt tree for it as it somewhat shares
> > +some of the same sources as the main ARM interrupt controller but with
> > +different numbers.
> > +
> > +The AST2500 supports a SW generated interrupt
> > +
> > +Required properties:
> > +- reg: address and length of the register for the device.
> > +- compatible: "aspeed,cvic" and one of:
> > +		"aspeed,ast2400-cvic"
> > +	      or
> > +		"aspeed,ast2500-cvic"
> > +
> > +- valid-sources: One cell, bitmap of supported sources for the implementation
> 
> aspeed,valid-sources
> 
> This could use a better description. I thought this was which bits to 
> use for s/w irq, but then I read the next property...
> 
> Alternatively, why can't this be implied by the compatible?

It could, I'm happy to drop it, I don't actually use it in SW.

Cheers,
Ben.

> > +
> > +Optional properties;
> > +- copro-sw-interrupts: List of interrupt numbers that can be used as
> > +		       SW interrupts from the ARM to the coprocessor.
> > +		       (AST2500 only)
> > +
> > +Example:
> > +
> > +	cvic: copro-interrupt-controller at 1e6c2000 {
> > +		compatible = "aspeed,ast2500-cvic";
> > +		valid-sources = <0xffffffff>;
> > +		copro-sw-interrupts = <1>;
> > +		reg = <0x1e6c2000 0x80>;
> > +	};
> > -- 
> > 2.17.1
> > 
> > 
> > _______________________________________________
> > linux-arm-kernel mailing list
> > linux-arm-kernel at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply

* Dynamic ftrace self test broken on ARM
From: Stefan Agner @ 2018-06-20 22:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <e4181ae694d44913a8eba4618477bd3b@agner.ch>

On 20.06.2018 23:32, Stefan Agner wrote:
> On 20.06.2018 21:06, Stefan Agner wrote:
>> On 20.06.2018 16:13, Steven Rostedt wrote:
>>> On Wed, 20 Jun 2018 15:51:55 +0200
>>> Stefan Agner <stefan@agner.ch> wrote:
>>>
>>>
>>>> v4.9 seems to work, so I started bisecting. It turned out that commit
>>>> 6f05d0761af6 ("ARM: 8668/1: ftrace: Fix dynamic ftrace with DEBUG_RODATA
>>>> and !FRAME_POINTER") broke it, introduced during the v4.12 merge window.
>>>
>>> That patch doesn't appear to be the cause. It could have been a failed
>>> bisect. Does the commit before that commit work? Does that commit fail?
>>
>> Pretty sure it is that one. Reverting it on top of v4.18-rc1 fixes it...
>>
>>>
>>> It may be due to some other RODATA change though. That is actually one
>>> of my thoughts when looking at the bug.
>>
>> CONFIG_STRICT_KERNEL_RWX=y is set, will test without.
> 
> Compiling without CONFIG_STRICT_KERNEL_RWX fixes the issue too. So seems
> to be a RODATA issue...

Ok, I understand the issue now:

In ARM ftrace we set kernel text to RW and back to RO in
arch_ftrace_update_code.

ARM sets the kernel at free_initmem to RO. So using ftrace selftest sets
the kernel text to RO much earlier, which seems to cause issues.

Reverting the above commit actually fixes selftests during boot, but it
breaks ftrace at runtime...

This resolves the issue:

+static int __ftrace_modify_code_boot(void *data)
+{
+       int *command = data;
+
+       ftrace_modify_all_code(*command);
+
+       return 0;
+}
+
 void arch_ftrace_update_code(int command)
 {
-       stop_machine(__ftrace_modify_code, &command, NULL);
+       if (system_state < SYSTEM_RUNNING)
+               stop_machine(__ftrace_modify_code_boot, &command, NULL);
+       else
+               stop_machine(__ftrace_modify_code, &command, NULL);
 }

Using system_state to indicate whether fix_kernmem_perms has been called
is rather brittle...

Any input from ARM folks?

--
Stefan

^ permalink raw reply

* [PATCH] usb: chipidea: Fix ULPI on imx51
From: Fabio Estevam @ 2018-06-20 22:22 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAOMZO5AyAegbvUtX42by99mU8yQfi91bmhJfd9iqu1Ak0dEHiw@mail.gmail.com>

On Wed, Jun 20, 2018 at 7:07 PM, Fabio Estevam <festevam@gmail.com> wrote:

> This patches causes a regression on a imx51-babbage running 4.18-rc1:
> I get a kernel hang.
>
> If I revert it on top of 4.18-rc1, then it boots fine and USB host is
> functional.
>
> I understand this patch fixes a kernel hang for you, so which commit
> is responsible for the hang you observe?
>
> It seems this commit fixes a hang for you and causes another hang for me :-)
>
> Any ideas?

I am able to boot again if I skip passing the CI_HDRC_OVERRIDE_PHY_CONTROL flag:

--- a/drivers/usb/chipidea/ci_hdrc_imx.c
+++ b/drivers/usb/chipidea/ci_hdrc_imx.c
@@ -294,7 +294,6 @@ static int ci_hdrc_imx_probe(struct platform_device *pdev)
        if ((of_device_is_compatible(np, "fsl,imx53-usb") ||
             of_device_is_compatible(np, "fsl,imx51-usb")) && pdata.usb_phy &&
            of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) {
-               pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL;
                data->override_phy_control = true;
                usb_phy_init(pdata.usb_phy);
        }

^ permalink raw reply

* [PATCH] usb: chipidea: Fix ULPI on imx51
From: Fabio Estevam @ 2018-06-20 22:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20180530173414.6121-1-andrew.smirnov@gmail.com>

Hi Andrey,

On Wed, May 30, 2018 at 2:34 PM, Andrey Smirnov
<andrew.smirnov@gmail.com> wrote:
> Workaround introduced for i.MX53 in be9cae2479f48 ("usb: chipidea:
> imx: Fix ULPI on imx53") seems to be applicable in case of i.MX51 as
> well. Running latest kernel on ZII RDU1 Board (imx51-zii-rdu1.dts)
> exhibits a kernel frozen on PORTSC access and applying the workaround
> resolves the issue.
>
> Cc: Peter Chen <peter.chen@nxp.com>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
> Cc: Fabio Estevam <fabio.estevam@nxp.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>
> Cc: Chris Healy <cphealy@gmail.com>
> Cc: linux-arm-kernel at lists.infradead.org
> Cc: linux-kernel at vger.kernel.org
> Cc: linux-usb at vger.kernel.org
> Signed-off-by: Andrey Smirnov <andrew.smirnov@gmail.com>

This patches causes a regression on a imx51-babbage running 4.18-rc1:
I get a kernel hang.

If I revert it on top of 4.18-rc1, then it boots fine and USB host is
functional.

I understand this patch fixes a kernel hang for you, so which commit
is responsible for the hang you observe?

It seems this commit fixes a hang for you and causes another hang for me :-)

Any ideas?

Thanks

^ permalink raw reply

* [PATCH 3/6] coresight: Introduce support for Coresight Address Translation Unit
From: Mathieu Poirier @ 2018-06-20 21:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1529319379-17895-4-git-send-email-suzuki.poulose@arm.com>

Hi Suzuki,

On Mon, Jun 18, 2018 at 11:56:16AM +0100, Suzuki K Poulose wrote:
> Add the initial support for Coresight Address Translation Unit, which
> augments the TMC in Coresight SoC-600 by providing an improved Scatter
> Gather mechanism. CATU is always connected to a single TMC-ETR and
> converts the AXI address with a translated address (from a given SG
> table with specific format). The CATU should be programmed in pass
> through mode and enabled if the ETR doesn't translation by CATU.

To me this sentence look broken.

> 
> This patch provides mechanism to enable/disable the CATU always in the
> pass through mode.
> 
> We reuse the existing ports mechanism to link the TMC-ETR to the
> connected CATU.
> 
> i.e, TMC-ETR:output_port0 -> CATU:input_port0
> 
> Reference manual for CATU component is avilable in version r2p0 of :
> "Arm Coresight System-on-Chip SoC-600 Technical Reference Manual".
> 
> Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> ---
>  drivers/hwtracing/coresight/Kconfig             |  11 ++
>  drivers/hwtracing/coresight/Makefile            |   1 +
>  drivers/hwtracing/coresight/coresight-catu.c    | 214 ++++++++++++++++++++++++
>  drivers/hwtracing/coresight/coresight-catu.h    |  85 ++++++++++
>  drivers/hwtracing/coresight/coresight-tmc-etr.c |  52 ++++++
>  include/linux/coresight.h                       |   1 +
>  6 files changed, 364 insertions(+)
>  create mode 100644 drivers/hwtracing/coresight/coresight-catu.c
>  create mode 100644 drivers/hwtracing/coresight/coresight-catu.h
> 
> diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
> index ef9cb3c..ad34380 100644
> --- a/drivers/hwtracing/coresight/Kconfig
> +++ b/drivers/hwtracing/coresight/Kconfig
> @@ -31,6 +31,17 @@ config CORESIGHT_LINK_AND_SINK_TMC
>  	  complies with the generic implementation of the component without
>  	  special enhancement or added features.
>  
> +config CORESIGHT_CATU
> +	bool "Coresight Address Translation Unit (CATU) driver"
> +	depends on CORESIGHT_LINK_AND_SINK_TMC
> +	help
> +	   Enable support for the Coresight Address Translation Unit (CATU).
> +	   CATU supports a scatter gather table of 4K pages, with forward/backward
> +	   lookup. CATU helps TMC ETR to use a large physically non-contiguous trace
> +	   buffer by translating the addresses used by ETR to the physical address
> +	   by looking up the provided table. CATU can also be used in pass-through
> +	   mode where the address is not translated.
> +
>  config CORESIGHT_SINK_TPIU
>  	bool "Coresight generic TPIU driver"
>  	depends on CORESIGHT_LINKS_AND_SINKS
> diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
> index 61db9dd..41870de 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -18,3 +18,4 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o \
>  obj-$(CONFIG_CORESIGHT_DYNAMIC_REPLICATOR) += coresight-dynamic-replicator.o
>  obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
>  obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
> +obj-$(CONFIG_CORESIGHT_CATU) += coresight-catu.o
> diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
> new file mode 100644
> index 0000000..11c84cb
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-catu.c
> @@ -0,0 +1,214 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2018 Arm Limited. All rights reserved.
> + *
> + * Coresight Address Translation Unit support
> + *
> + * Author: Suzuki K Poulose <suzuki.poulose@arm.com>
> + */
> +
> +#include <linux/amba/bus.h>
> +#include <linux/device.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +
> +#include "coresight-catu.h"
> +#include "coresight-priv.h"
> +
> +#define csdev_to_catu_drvdata(csdev)	\
> +	dev_get_drvdata(csdev->dev.parent)
> +
> +coresight_simple_reg32(struct catu_drvdata, devid, CORESIGHT_DEVID);
> +coresight_simple_reg32(struct catu_drvdata, control, CATU_CONTROL);
> +coresight_simple_reg32(struct catu_drvdata, status, CATU_STATUS);
> +coresight_simple_reg32(struct catu_drvdata, mode, CATU_MODE);
> +coresight_simple_reg32(struct catu_drvdata, axictrl, CATU_AXICTRL);
> +coresight_simple_reg32(struct catu_drvdata, irqen, CATU_IRQEN);
> +coresight_simple_reg64(struct catu_drvdata, sladdr,
> +		       CATU_SLADDRLO, CATU_SLADDRHI);
> +coresight_simple_reg64(struct catu_drvdata, inaddr,
> +		       CATU_INADDRLO, CATU_INADDRHI);
> +
> +static struct attribute *catu_mgmt_attrs[] = {
> +	&dev_attr_devid.attr,
> +	&dev_attr_control.attr,
> +	&dev_attr_status.attr,
> +	&dev_attr_mode.attr,
> +	&dev_attr_axictrl.attr,
> +	&dev_attr_irqen.attr,
> +	&dev_attr_sladdr.attr,
> +	&dev_attr_inaddr.attr,
> +	NULL,
> +};
> +
> +static const struct attribute_group catu_mgmt_group = {
> +	.attrs = catu_mgmt_attrs,
> +	.name = "mgmt",
> +};
> +
> +static const struct attribute_group *catu_groups[] = {
> +	&catu_mgmt_group,
> +	NULL,
> +};
> +
> +
> +static inline int catu_wait_for_ready(struct catu_drvdata *drvdata)
> +{
> +	return coresight_timeout(drvdata->base,
> +				 CATU_STATUS, CATU_STATUS_READY, 1);
> +}
> +
> +static int catu_enable_hw(struct catu_drvdata *drvdata, void *__unused)
> +{
> +	u32 control;
> +
> +	if (catu_wait_for_ready(drvdata))
> +		dev_warn(drvdata->dev, "Timeout while waiting for READY\n");
> +
> +	control = catu_read_control(drvdata);
> +	if (control & BIT(CATU_CONTROL_ENABLE)) {
> +		dev_warn(drvdata->dev, "CATU is already enabled\n");
> +		return -EBUSY;
> +	}
> +
> +	control |= BIT(CATU_CONTROL_ENABLE);
> +	catu_write_mode(drvdata, CATU_MODE_PASS_THROUGH);
> +	catu_write_control(drvdata, control);
> +	dev_dbg(drvdata->dev, "Enabled in Pass through mode\n");
> +	return 0;
> +}
> +
> +static int catu_enable(struct coresight_device *csdev, void *data)
> +{
> +	int rc;
> +	struct catu_drvdata *catu_drvdata = csdev_to_catu_drvdata(csdev);
> +
> +	CS_UNLOCK(catu_drvdata->base);
> +	rc = catu_enable_hw(catu_drvdata, data);
> +	CS_LOCK(catu_drvdata->base);
> +	return rc;
> +}
> +
> +static int catu_disable_hw(struct catu_drvdata *drvdata)
> +{
> +	int rc = 0;
> +
> +	if (catu_wait_for_ready(drvdata)) {
> +		dev_info(drvdata->dev, "Timeout while waiting for READY\n");
> +		rc = -EAGAIN;
> +	}
> +
> +	catu_write_control(drvdata, 0);

Is waiting for the ready bit before switching the component off comes from
experimentation with the HW (i.e FPGA)?  From what the reference manual
indicate, CONTROL.ENABLE should be set to 0 first, and then wait for
STATUS.READY. 

Thanks,
Mathieu

> +	dev_dbg(drvdata->dev, "Disabled\n");
> +	return rc;
> +}
> +
> +static int catu_disable(struct coresight_device *csdev, void *__unused)
> +{
> +	int rc;
> +	struct catu_drvdata *catu_drvdata = csdev_to_catu_drvdata(csdev);
> +
> +	CS_UNLOCK(catu_drvdata->base);
> +	rc = catu_disable_hw(catu_drvdata);
> +	CS_LOCK(catu_drvdata->base);
> +	return rc;
> +}
> +
> +const struct coresight_ops_helper catu_helper_ops = {
> +	.enable = catu_enable,
> +	.disable = catu_disable,
> +};
> +
> +const struct coresight_ops catu_ops = {
> +	.helper_ops = &catu_helper_ops,
> +};
> +
> +static int catu_probe(struct amba_device *adev, const struct amba_id *id)
> +{
> +	int ret = 0;
> +	u32 dma_mask;
> +	struct catu_drvdata *drvdata;
> +	struct coresight_desc catu_desc;
> +	struct coresight_platform_data *pdata = NULL;
> +	struct device *dev = &adev->dev;
> +	struct device_node *np = dev->of_node;
> +	void __iomem *base;
> +
> +	if (np) {
> +		pdata = of_get_coresight_platform_data(dev, np);
> +		if (IS_ERR(pdata)) {
> +			ret = PTR_ERR(pdata);
> +			goto out;
> +		}
> +		dev->platform_data = pdata;
> +	}
> +
> +	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> +	if (!drvdata) {
> +		ret = -ENOMEM;
> +		goto out;
> +	}
> +
> +	drvdata->dev = dev;
> +	dev_set_drvdata(dev, drvdata);
> +	base = devm_ioremap_resource(dev, &adev->res);
> +	if (IS_ERR(base)) {
> +		ret = PTR_ERR(base);
> +		goto out;
> +	}
> +
> +	/* Setup dma mask for the device */
> +	dma_mask = readl_relaxed(base + CORESIGHT_DEVID) & 0x3f;
> +	switch (dma_mask) {
> +	case 32:
> +	case 40:
> +	case 44:
> +	case 48:
> +	case 52:
> +	case 56:
> +	case 64:
> +		break;
> +	default:
> +		/* Default to the 40bits as supported by TMC-ETR */
> +		dma_mask = 40;
> +	}
> +	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(dma_mask));
> +	if (ret)
> +		goto out;
> +
> +	drvdata->base = base;
> +	catu_desc.pdata = pdata;
> +	catu_desc.dev = dev;
> +	catu_desc.groups = catu_groups;
> +	catu_desc.type = CORESIGHT_DEV_TYPE_HELPER;
> +	catu_desc.subtype.helper_subtype = CORESIGHT_DEV_SUBTYPE_HELPER_CATU;
> +	catu_desc.ops = &catu_ops;
> +	drvdata->csdev = coresight_register(&catu_desc);
> +	if (IS_ERR(drvdata->csdev))
> +		ret = PTR_ERR(drvdata->csdev);
> +out:
> +	pm_runtime_put(&adev->dev);
> +	return ret;
> +}
> +
> +static struct amba_id catu_ids[] = {
> +	{
> +		.id	= 0x000bb9ee,
> +		.mask	= 0x000fffff,
> +	},
> +	{},
> +};
> +
> +static struct amba_driver catu_driver = {
> +	.drv = {
> +		.name			= "coresight-catu",
> +		.owner			= THIS_MODULE,
> +		.suppress_bind_attrs	= true,
> +	},
> +	.probe				= catu_probe,
> +	.id_table			= catu_ids,
> +};
> +
> +builtin_amba_driver(catu_driver);
> diff --git a/drivers/hwtracing/coresight/coresight-catu.h b/drivers/hwtracing/coresight/coresight-catu.h
> new file mode 100644
> index 0000000..05da33d
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-catu.h
> @@ -0,0 +1,85 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2018 Arm Limited. All rights reserved.
> + *
> + * Author: Suzuki K Poulose <suzuki.poulose@arm.com>
> + */
> +
> +#ifndef _CORESIGHT_CATU_H
> +#define _CORESIGHT_CATU_H
> +
> +#include "coresight-priv.h"
> +
> +/* Register offset from base */
> +#define CATU_CONTROL		0x000
> +#define CATU_MODE		0x004
> +#define CATU_AXICTRL		0x008
> +#define CATU_IRQEN		0x00c
> +#define CATU_SLADDRLO		0x020
> +#define CATU_SLADDRHI		0x024
> +#define CATU_INADDRLO		0x028
> +#define CATU_INADDRHI		0x02c
> +#define CATU_STATUS		0x100
> +#define CATU_DEVARCH		0xfbc
> +
> +#define CATU_CONTROL_ENABLE	0
> +
> +#define CATU_MODE_PASS_THROUGH	0U
> +#define CATU_MODE_TRANSLATE	1U
> +
> +#define CATU_STATUS_READY	8
> +#define CATU_STATUS_ADRERR	0
> +#define CATU_STATUS_AXIERR	4
> +
> +#define CATU_IRQEN_ON		0x1
> +#define CATU_IRQEN_OFF		0x0
> +
> +struct catu_drvdata {
> +	struct device *dev;
> +	void __iomem *base;
> +	struct coresight_device *csdev;
> +	int irq;
> +};
> +
> +#define CATU_REG32(name, offset)					\
> +static inline u32							\
> +catu_read_##name(struct catu_drvdata *drvdata)				\
> +{									\
> +	return coresight_read_reg_pair(drvdata->base, offset, -1);	\
> +}									\
> +static inline void							\
> +catu_write_##name(struct catu_drvdata *drvdata, u32 val)		\
> +{									\
> +	coresight_write_reg_pair(drvdata->base, val, offset, -1);	\
> +}
> +
> +#define CATU_REG_PAIR(name, lo_off, hi_off)				\
> +static inline u64							\
> +catu_read_##name(struct catu_drvdata *drvdata)				\
> +{									\
> +	return coresight_read_reg_pair(drvdata->base, lo_off, hi_off);	\
> +}									\
> +static inline void							\
> +catu_write_##name(struct catu_drvdata *drvdata, u64 val)		\
> +{									\
> +	coresight_write_reg_pair(drvdata->base, val, lo_off, hi_off);	\
> +}
> +
> +CATU_REG32(control, CATU_CONTROL);
> +CATU_REG32(mode, CATU_MODE);
> +CATU_REG_PAIR(sladdr, CATU_SLADDRLO, CATU_SLADDRHI)
> +CATU_REG_PAIR(inaddr, CATU_INADDRLO, CATU_INADDRHI)
> +
> +static inline bool coresight_is_catu_device(struct coresight_device *csdev)
> +{
> +	enum coresight_dev_subtype_helper subtype;
> +
> +	/* Make the checkpatch happy */
> +	subtype = csdev->subtype.helper_subtype;
> +
> +	return IS_ENABLED(CONFIG_CORESIGHT_CATU) &&
> +	       csdev->type == CORESIGHT_DEV_TYPE_HELPER &&
> +	       subtype == CORESIGHT_DEV_SUBTYPE_HELPER_CATU;
> +}
> +
> +#endif
> diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> index 8af4512..e37923a 100644
> --- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
> +++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
> @@ -9,6 +9,7 @@
>  #include <linux/iommu.h>
>  #include <linux/slab.h>
>  #include <linux/vmalloc.h>
> +#include "coresight-catu.h"
>  #include "coresight-priv.h"
>  #include "coresight-tmc.h"
>  
> @@ -701,6 +702,48 @@ static const struct etr_buf_operations etr_sg_buf_ops = {
>  	.get_data = tmc_etr_get_data_sg_buf,
>  };
>  
> +/*
> + * TMC ETR could be connected to a CATU device, which can provide address
> + * translation service. This is represented by the Output port of the TMC
> + * (ETR) connected to the input port of the CATU.
> + *
> + * Returns	: coresight_device ptr for the CATU device if a CATU is found.
> + *		: NULL otherwise.
> + */
> +static inline struct coresight_device *
> +tmc_etr_get_catu_device(struct tmc_drvdata *drvdata)
> +{
> +	int i;
> +	struct coresight_device *tmp, *etr = drvdata->csdev;
> +
> +	if (!IS_ENABLED(CONFIG_CORESIGHT_CATU))
> +		return NULL;
> +
> +	for (i = 0; i < etr->nr_outport; i++) {
> +		tmp = etr->conns[i].child_dev;
> +		if (tmp && coresight_is_catu_device(tmp))
> +			return tmp;
> +	}
> +
> +	return NULL;
> +}
> +
> +static inline void tmc_etr_enable_catu(struct tmc_drvdata *drvdata)
> +{
> +	struct coresight_device *catu = tmc_etr_get_catu_device(drvdata);
> +
> +	if (catu && helper_ops(catu)->enable)
> +		helper_ops(catu)->enable(catu, NULL);
> +}
> +
> +static inline void tmc_etr_disable_catu(struct tmc_drvdata *drvdata)
> +{
> +	struct coresight_device *catu = tmc_etr_get_catu_device(drvdata);
> +
> +	if (catu && helper_ops(catu)->disable)
> +		helper_ops(catu)->disable(catu, NULL);
> +}
> +
>  static const struct etr_buf_operations *etr_buf_ops[] = {
>  	[ETR_MODE_FLAT] = &etr_flat_buf_ops,
>  	[ETR_MODE_ETR_SG] = &etr_sg_buf_ops,
> @@ -844,6 +887,12 @@ static void tmc_etr_enable_hw(struct tmc_drvdata *drvdata)
>  	u32 axictl, sts;
>  	struct etr_buf *etr_buf = drvdata->etr_buf;
>  
> +	/*
> +	 * If this ETR is connected to a CATU, enable it before we turn
> +	 * this on
> +	 */
> +	tmc_etr_enable_catu(drvdata);
> +
>  	CS_UNLOCK(drvdata->base);
>  
>  	/* Wait for TMCSReady bit to be set */
> @@ -952,6 +1001,9 @@ static void tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
>  	tmc_disable_hw(drvdata);
>  
>  	CS_LOCK(drvdata->base);
> +
> +	/* Disable CATU device if this ETR is connected to one */
> +	tmc_etr_disable_catu(drvdata);
>  }
>  
>  static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev)
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index 3d40a2b..d828a6e 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
>  
>  enum coresight_dev_subtype_helper {
>  	CORESIGHT_DEV_SUBTYPE_HELPER_NONE,
> +	CORESIGHT_DEV_SUBTYPE_HELPER_CATU,
>  };
>  
>  /**
> -- 
> 2.7.4
> 

^ permalink raw reply

* Dynamic ftrace self test broken on ARM
From: Stefan Agner @ 2018-06-20 21:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <7904ed3fe9f59a54526d64f366915b43@agner.ch>

On 20.06.2018 21:06, Stefan Agner wrote:
> On 20.06.2018 16:13, Steven Rostedt wrote:
>> On Wed, 20 Jun 2018 15:51:55 +0200
>> Stefan Agner <stefan@agner.ch> wrote:
>>
>>
>>> v4.9 seems to work, so I started bisecting. It turned out that commit
>>> 6f05d0761af6 ("ARM: 8668/1: ftrace: Fix dynamic ftrace with DEBUG_RODATA
>>> and !FRAME_POINTER") broke it, introduced during the v4.12 merge window.
>>
>> That patch doesn't appear to be the cause. It could have been a failed
>> bisect. Does the commit before that commit work? Does that commit fail?
> 
> Pretty sure it is that one. Reverting it on top of v4.18-rc1 fixes it...
> 
>>
>> It may be due to some other RODATA change though. That is actually one
>> of my thoughts when looking at the bug.
> 
> CONFIG_STRICT_KERNEL_RWX=y is set, will test without.

Compiling without CONFIG_STRICT_KERNEL_RWX fixes the issue too. So seems
to be a RODATA issue...

--
Stefan

^ 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