* Re: [PATCH 15/22] ARM: dts: apalis-imx6: Add some optional I2C devices
From: Fabio Estevam @ 2019-07-30 20:43 UTC (permalink / raw)
To: Philippe Schenker
Cc: Marcel Ziswiler, Max Krummenacher, Stefan Agner,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
Rob Herring, Shawn Guo, Mark Rutland, Philippe Schenker,
linux-kernel,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Pengutronix Kernel Team, NXP Linux Team, Sascha Hauer
In-Reply-To: <20190730144649.19022-16-dev@pschenker.ch>
Hi Philippe,
On Tue, Jul 30, 2019 at 11:57 AM Philippe Schenker <dev@pschenker.ch> wrote:
> +&mipi_csi {
> + ipu_id = <0>;
> + csi_id = <1>;
> + v_channel = <0>;
> + lanes = <2>;
None of these properties are valid upstream.
^ permalink raw reply
* Re: [PATCH 12/22] ARM: dts: imx6: Add touchscreens used on Toradex eval boards
From: Fabio Estevam @ 2019-07-30 20:46 UTC (permalink / raw)
To: Philippe Schenker
Cc: Marcel Ziswiler, Max Krummenacher, Stefan Agner,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
Rob Herring, Shawn Guo, Mark Rutland, Philippe Schenker,
linux-kernel,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Pengutronix Kernel Team, NXP Linux Team, Sascha Hauer
In-Reply-To: <20190730144649.19022-13-dev@pschenker.ch>
On Tue, Jul 30, 2019 at 11:57 AM Philippe Schenker <dev@pschenker.ch> wrote:
> + /* Atmel maxtouch controller */
> + atmel_mxt_ts: atmel_mxt_ts@4a {
Generic node names, please:
touchscreen@4a
> + compatible = "atmel,maxtouch";
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_pcap_1>;
> + reg = <0x4a>;
> + interrupt-parent = <&gpio1>;
> + interrupts = <9 IRQ_TYPE_EDGE_FALLING>; /* SODIMM 28 */
> + reset-gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>; /* SODIMM 30 */
> + status = "disabled";
> + };
> +
> + /*
> + * the PCAPs use SODIMM 28/30, also used for PWM<B>, PWM<C>, aka pwm1,
> + * pwm4. So if you enable one of the PCAP controllers disable the pwms.
> + */
> + pcap: pcap@10 {
touchscreen@10
> + /* TouchRevolution Fusion 7 and 10 multi-touch controller */
> + compatible = "touchrevolution,fusion-f0710a";
I do not find this binding documented.
^ permalink raw reply
* Re: [PATCH v8 00/14] Rockchip ISP1 Driver
From: Helen Koike @ 2019-07-30 20:50 UTC (permalink / raw)
To: Hans Verkuil, linux-rockchip
Cc: devicetree, eddie.cai.linux, mchehab, heiko, jacob2.chen,
jeffy.chen, zyc, linux-kernel, tfiga, hans.verkuil,
laurent.pinchart, sakari.ailus, kernel, ezequiel, linux-media,
linux-arm-kernel, zhengsq
In-Reply-To: <dbdfed3e-7bb6-bf1f-64b9-ab7298193e2d@xs4all.nl>
On 7/30/19 5:15 PM, Hans Verkuil wrote:
> On 7/30/19 8:42 PM, Helen Koike wrote:
>> Hello,
>>
>> I'm re-sending a new version of ISP(Camera) v4l2 driver for rockchip
>> rk3399 SoC.
>>
>> I didn't change much from the last version, just applying the
>> suggestions made in the previous one.
>>
>> This patchset is also available at:
>> https://gitlab.collabora.com/koike/linux/tree/rockchip/isp/v8
>>
>> Libcamera patched to work with this version:
>> https://gitlab.collabora.com/koike/libcamera
>> (also sent to the mailing list)
>>
>> I tested on the rockpi 4 with a rpi v1.3 sensor and also with the
>> Scarlet Chromebook.
>>
>> Known issues (same as in v7):
>> -------------
>> - Reloading the module doesn't work (there is some missing cleanup when
>> unloading)
>> - When capturing in bayer format, changing the size doesn't seem to
>> affect the image.
>> - crop needs more tests
>> - v4l2-compliance error:
>> fail: v4l2-test-controls.cpp(824): subscribe event for control 'Image Processing Controls' failed
>> test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: FAIL
>
> Can you mail me the full v4l2-compliance output?
Sure, please check here: http://ix.io/1Q5u
I updated v4l-utils with the latest version and I re-ran bootstrap/configure/make,
but for some reason the hash from the link above is not the latest commit, probably some
old configuration somewhere. I'll resend this log as soon as I get v4l2-compliance
properly updated.
Thanks
Helen
>
> Regards,
>
> Hans
>
>> It seems that if controls are supported, v4l2-compliance says that
>> controls of type 'Image Processing Controls' are mandatory, is this
>> correct?
>> - It seems there are still some issues with interrupts, but I couldn't
>> isolate them yet.
>>
>> Previous changelog:
>> -------------------
>>
>> changes in V6:
>> - add mipi txrx phy support
>> - remove bool and enum from uapi header
>> - add buf_prepare op
>> - correct some spelling problems
>> - return all queued buffers when starting stream failed
>>
>> changes in V5: Sync with local changes,
>> - fix the SP height limit
>> - speed up the second stream capture
>> - the second stream can't force sync for rsz when start/stop streaming
>> - add frame id to param vb2 buf
>> - enable luminance maximum threshold
>>
>> changes in V4:
>> - fix some bugs during development
>> - move quantization settings to rkisp1 subdev
>> - correct some spelling problems
>> - describe ports in dt-binding documents
>>
>> changes in V3:
>> - add some comments
>> - fix wrong use of v4l2_async_subdev_notifier_register
>> - optimize two paths capture at a time
>> - remove compose
>> - re-struct headers
>> - add a tmp wiki page: http://opensource.rock-chips.com/wiki_Rockchip-isp1
>>
>> changes in V2:
>> mipi-phy:
>> - use async probing
>> - make it be a child device of the GRF
>> isp:
>> - add dummy buffer
>> - change the way to get bus configuration, which make it possible to
>> add parallel sensor support in the future(without mipi-phy driver).
>>
>> ------------------
>>
>> Changes in v8:
>> - Add SPDX in the header
>> - Remove emacs configs
>> - Fix doc style
>> - Remove boiler plate license text
>>
>> Changes in v7:
>> - s/IPU3/RK_ISP1
>> - s/correspond/corresponding
>> - s/use/uses
>> - s/docuemnt/document
>> - Fix checkpatch errors (lines over 80 and SPDX)
>> - Add TODO to improve docs
>> - Migrate dphy specific code from
>> drivers/media/platform/rockchip/isp1/mipi_dphy_sy.c
>> to drivers/phy/rockchip/phy-rockchip-dphy.c
>> - Drop support for rk3288
>> - Drop support for dphy txrx
>> - code styling and checkpatch fixes
>> - fixed warning because of unknown entity type
>> - fixed v4l2-compliance errors regarding rkisp1 formats, try formats
>> and default values
>> - fix typo riksp1/rkisp1
>> - redesign: remove mipi/csi subdevice, sensors connect directly to the
>> isp subdevice in the media topology now. As a consequence, remove the
>> hack in mipidphy_g_mbus_config() where information from the sensor was
>> being propagated through the topology.
>> - From the old dphy:
>> * cache get_remote_sensor() in s_stream
>> * use V4L2_CID_PIXEL_RATE instead of V4L2_CID_LINK_FREQ
>> - Replace stream state with a boolean
>> - code styling and checkpatch fixes
>> - fix stop_stream (return after calling stop, do not reenable the stream)
>> - fix rkisp1_isp_sd_get_selection when V4L2_SUBDEV_FORMAT_TRY is set
>> - fix get format in output (isp_sd->out_fmt.mbus_code was being ignored)
>> - s/intput/input
>> - remove #define sd_to_isp_sd(_sd), add a static inline as it will be
>> reused by the capture
>> - s/strlcpy/strscpy
>> - sort out the locks in isp stats
>> - code styling and checkpatch fixes
>> - s/strlcpy/strscpy
>> - s/strcpy/strscpy
>> - fix config lsc error
>> LSC data table size is 17x17, but when configuring data to ISP,
>> should be aligned to 18x17. That means every last data of last
>> line should be filled with 0, and not filled with the data of
>> next line.
>> - Update new ISP parameters immediately
>> For those sub modules that have shadow registers in core isp, the
>> new programing parameters would not be active if both
>> CIF_ISP_CTRL_ISP_CFG_UPD_PERMANENT and CFG_UPD are not set. Now
>> we configure CFG_UPD to force update the shadow registers when new
>> ISP parameters are configured.
>> - fix some ISP parameters config error
>> Some ISP parameter config functions may override the old enable
>> bit value, because the enable bits of these modules are in the
>> same registers with parameters. So we should save the old enable
>> bits firstly.
>> - code styling and checkpatch fixes
>> - s/strlcpy/strscpy
>> - Fix v4l2-compliance issues:
>> * remove input ioctls
>> media api can be used to define the topology, this input api is not
>> required. Besides it, if an input is enumerated, v4l2-compliance is not
>> happy with G_FMT returning the default colorspace instead of something
>> more specific.
>> * return the pixelformat to the userspace
>> G_/S_/TRY_ FORMAT should return a valid pixelformat to the user, even if
>> the user gave an invalid one
>> * add missing default colorspace and ycbcr
>> * fix wrong pixformat in mp_fmts[] table
>> * add buf type check in s_/g_selection
>> * queue_setup - check sizes
>> * normalize bus_info name
>> * fix field any v4l2-compliance -s complain - set field none
>> when streaming
>> - Fix compiling error: s/vidioc_enum_fmt_vid_cap_mplane/vidioc_enum_fmt_vid_cap
>> - Replace stream state with a boolean
>> The rkisp1_state enum consists only of 3 entries, where 1 is completely
>> unused and the other two respectively mean not streaming or streaming.
>> Replace it with a boolean called "streaming".
>> - Simplify MI interrupt handling
>> Rather than adding unnecessary indirection, just use stream index to
>> handle MI interrupt enable/disable/clear, since the stream index matches
>> the order of bits now, thanks to previous patch. While at it, remove
>> some dead code.
>> - code styling and checkpatch fixes
>> - add link_validate: don't allow a link with bayer/non-bayer mismatch
>> - VIDEO_ROCKCHIP_ISP1 selects VIDEOBUF2_VMALLOC
>> - add PHY_ROCKCHIP_DPHY as a dependency for VIDEO_ROCKCHIP_ISP1
>> - Fix compilation and runtime errors due to bitrotting
>> The code has bit-rotten since March 2018, fix compilation errors.
>> The new V4L2 async notifier API requires notifiers to be initialized by
>> a call to v4l2_async_notifier_init() before being used, do so.
>> - Add missing module device table
>> - use clk_bulk framework
>> - add missing notifiers cleanups
>> - s/strlcpy/strscpy
>> - normalize bus_info name
>> - fix s_stream error path, stream_cnt wans't being decremented properly
>> - use devm_platform_ioremap_resource() helper
>> - s/deice/device
>> - redesign: remove mipi/csi subdevice, sensors connect directly to the
>> isp subdevice in the media topology now.
>> - remove "saved_state" member from rkisp1_stream struct
>> - Reverse the order of MIs
>> - Simplify MI interrupt handling
>> Rather than adding unnecessary indirection, just use stream index to
>> handle MI interrupt enable/disable/clear, since the stream index matches
>> the order of bits now, thanks to previous patch. While at it, remove
>> some dead code.
>> - code styling and checkpatch fixes
>> - update document with new design and tested example
>> - updated doc with new design and tested example
>> - add phy properties
>> - add ports
>> - add phy-cells
>>
>> Helen Koike (1):
>> MAINTAINERS: add entry for Rockchip ISP1 driver
>>
>> Jacob Chen (9):
>> media: doc: add document for rkisp1 meta buffer format
>> media: rkisp1: add Rockchip MIPI Synopsys DPHY driver
>> media: rkisp1: add Rockchip ISP1 subdev driver
>> media: rkisp1: add ISP1 statistics driver
>> media: rkisp1: add ISP1 params driver
>> media: rkisp1: add capture device driver
>> media: rkisp1: add rockchip isp1 core driver
>> dt-bindings: Document the Rockchip ISP1 bindings
>> dt-bindings: Document the Rockchip MIPI RX D-PHY bindings
>>
>> Jeffy Chen (1):
>> media: rkisp1: Add user space ABI definitions
>>
>> Shunqian Zheng (3):
>> media: videodev2.h, v4l2-ioctl: add rkisp1 meta buffer format
>> arm64: dts: rockchip: add isp0 node for rk3399
>> arm64: dts: rockchip: add rx0 mipi-phy for rk3399
>>
>> .../bindings/media/rockchip-isp1.txt | 71 +
>> .../bindings/media/rockchip-mipi-dphy.txt | 38 +
>> Documentation/media/uapi/v4l/meta-formats.rst | 2 +
>> .../uapi/v4l/pixfmt-meta-rkisp1-params.rst | 23 +
>> .../uapi/v4l/pixfmt-meta-rkisp1-stat.rst | 22 +
>> MAINTAINERS | 8 +
>> arch/arm64/boot/dts/rockchip/rk3399.dtsi | 36 +
>> drivers/media/platform/Kconfig | 12 +
>> drivers/media/platform/Makefile | 1 +
>> drivers/media/platform/rockchip/isp1/Makefile | 7 +
>> .../media/platform/rockchip/isp1/capture.c | 1754 +++++++++++++++++
>> .../media/platform/rockchip/isp1/capture.h | 164 ++
>> drivers/media/platform/rockchip/isp1/common.h | 101 +
>> drivers/media/platform/rockchip/isp1/dev.c | 675 +++++++
>> drivers/media/platform/rockchip/isp1/dev.h | 97 +
>> .../media/platform/rockchip/isp1/isp_params.c | 1604 +++++++++++++++
>> .../media/platform/rockchip/isp1/isp_params.h | 50 +
>> .../media/platform/rockchip/isp1/isp_stats.c | 508 +++++
>> .../media/platform/rockchip/isp1/isp_stats.h | 60 +
>> drivers/media/platform/rockchip/isp1/regs.c | 223 +++
>> drivers/media/platform/rockchip/isp1/regs.h | 1525 ++++++++++++++
>> drivers/media/platform/rockchip/isp1/rkisp1.c | 1286 ++++++++++++
>> drivers/media/platform/rockchip/isp1/rkisp1.h | 111 ++
>> drivers/media/v4l2-core/v4l2-ioctl.c | 2 +
>> drivers/phy/rockchip/Kconfig | 8 +
>> drivers/phy/rockchip/Makefile | 1 +
>> drivers/phy/rockchip/phy-rockchip-dphy.c | 408 ++++
>> include/uapi/linux/rkisp1-config.h | 816 ++++++++
>> include/uapi/linux/videodev2.h | 4 +
>> 29 files changed, 9617 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/media/rockchip-isp1.txt
>> create mode 100644 Documentation/devicetree/bindings/media/rockchip-mipi-dphy.txt
>> create mode 100644 Documentation/media/uapi/v4l/pixfmt-meta-rkisp1-params.rst
>> create mode 100644 Documentation/media/uapi/v4l/pixfmt-meta-rkisp1-stat.rst
>> create mode 100644 drivers/media/platform/rockchip/isp1/Makefile
>> create mode 100644 drivers/media/platform/rockchip/isp1/capture.c
>> create mode 100644 drivers/media/platform/rockchip/isp1/capture.h
>> create mode 100644 drivers/media/platform/rockchip/isp1/common.h
>> create mode 100644 drivers/media/platform/rockchip/isp1/dev.c
>> create mode 100644 drivers/media/platform/rockchip/isp1/dev.h
>> create mode 100644 drivers/media/platform/rockchip/isp1/isp_params.c
>> create mode 100644 drivers/media/platform/rockchip/isp1/isp_params.h
>> create mode 100644 drivers/media/platform/rockchip/isp1/isp_stats.c
>> create mode 100644 drivers/media/platform/rockchip/isp1/isp_stats.h
>> create mode 100644 drivers/media/platform/rockchip/isp1/regs.c
>> create mode 100644 drivers/media/platform/rockchip/isp1/regs.h
>> create mode 100644 drivers/media/platform/rockchip/isp1/rkisp1.c
>> create mode 100644 drivers/media/platform/rockchip/isp1/rkisp1.h
>> create mode 100644 drivers/phy/rockchip/phy-rockchip-dphy.c
>> create mode 100644 include/uapi/linux/rkisp1-config.h
>>
>
^ permalink raw reply
* Re: [PATCH v1 1/1] i2c: iproc: Fix i2c master read more than 63 bytes
From: Ray Jui @ 2019-07-30 20:53 UTC (permalink / raw)
To: Rayagonda Kokatanur, Wolfram Sang, Rob Herring, Mark Rutland
Cc: linux-i2c, devicetree, linux-arm-kernel, linux-kernel,
bcm-kernel-feedback-list, Florian Fainelli
In-Reply-To: <1563956907-21255-1-git-send-email-rayagonda.kokatanur@broadcom.com>
Hi Rayagonda,
On 7/24/2019 1:28 AM, Rayagonda Kokatanur wrote:
> Use SMBUS_MASTER_DATA_READ.MASTER_RD_STATUS bit to check for RX
> FIFO empty condition because SMBUS_MASTER_FIFO_CONTROL.MASTER_RX_PKT_COUNT
> is not updated for read >= 64 bytes. This fixes the issue when trying to
> read from the I2C slave more than 63 bytes.
>
> Fixes: c24b8d574b7c ("i2c: iproc: Extend I2C read up to 255 bytes")
>
> Signed-off-by: Rayagonda Kokatanur <rayagonda.kokatanur@broadcom.com>
> ---
> drivers/i2c/busses/i2c-bcm-iproc.c | 10 ++++++----
> 1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c
> index 2c7f145..d7fd76b 100644
> --- a/drivers/i2c/busses/i2c-bcm-iproc.c
> +++ b/drivers/i2c/busses/i2c-bcm-iproc.c
> @@ -392,16 +392,18 @@ static bool bcm_iproc_i2c_slave_isr(struct bcm_iproc_i2c_dev *iproc_i2c,
> static void bcm_iproc_i2c_read_valid_bytes(struct bcm_iproc_i2c_dev *iproc_i2c)
> {
> struct i2c_msg *msg = iproc_i2c->msg;
> + uint32_t val;
>
> /* Read valid data from RX FIFO */
> while (iproc_i2c->rx_bytes < msg->len) {
> - if (!((iproc_i2c_rd_reg(iproc_i2c, M_FIFO_CTRL_OFFSET) >> M_FIFO_RX_CNT_SHIFT)
> - & M_FIFO_RX_CNT_MASK))
> + val = iproc_i2c_rd_reg(iproc_i2c, M_RX_OFFSET);
> +
> + /* rx fifo empty */
> + if (!((val >> M_RX_STATUS_SHIFT) & M_RX_STATUS_MASK))
> break;
>
> msg->buf[iproc_i2c->rx_bytes] =
> - (iproc_i2c_rd_reg(iproc_i2c, M_RX_OFFSET) >>
> - M_RX_DATA_SHIFT) & M_RX_DATA_MASK;
> + (val >> M_RX_DATA_SHIFT) & M_RX_DATA_MASK;
> iproc_i2c->rx_bytes++;
> }
> }
>
Thanks for the fix. This fix looks good to me!
Reviewed-by: Ray Jui <ray.jui@broadcom.com>
^ permalink raw reply
* Re: [PATCH 14/22] ARM: dts: apalis-imx6: Add some example I2C devices
From: Fabio Estevam @ 2019-07-30 20:53 UTC (permalink / raw)
To: Philippe Schenker
Cc: Marcel Ziswiler, Max Krummenacher, Stefan Agner,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
Rob Herring, Shawn Guo, Mark Rutland, Philippe Schenker,
linux-kernel,
moderated list:ARM/FREESCALE IMX / MXC ARM ARCHITECTURE,
Pengutronix Kernel Team, NXP Linux Team, Sascha Hauer
In-Reply-To: <20190730144649.19022-15-dev@pschenker.ch>
On Tue, Jul 30, 2019 at 11:57 AM Philippe Schenker <dev@pschenker.ch> wrote:
> &backlight {
> @@ -204,6 +228,77 @@
> */
> &i2c3 {
> status = "okay";
> +
> + adv7280: adv7280@21 {
> + compatible = "adv7280";
> + reg = <0x21>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
> + clocks = <&clks 200>;
Please replace this 200 with a proper clock label.
> + clock-names = "csi_mclk";
> + DOVDD-supply = <®_3p3v>;
> + AVDD-supply = <®_3p3v>;
> + DVDD-supply = <®_3p3v>;
> + PVDD-supply = <®_3p3v>;
> + csi_id = <0>;
This is not a valid property upstream.
It seems you just ported it from a downstream vendor kernel. Please
make sure you test with the dt-bindings from mainline.
> + mclk = <24000000>;
> + mclk_source = <1>;
> + status = "okay";
> + };
> +
> + /* Video ADC on Analog Camera Module */
> + adv7180: adv7180@21 {
> + compatible = "adv,adv7180";
> + reg = <0x21>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pinctrl_ipu1_csi0 &pinctrl_cam_mclk>;
> + clocks = <&clks 200>;
clock label, please.
> + clock-names = "csi_mclk";
> + DOVDD-supply = <®_3p3v>; /* 3.3v */
> + AVDD-supply = <®_3p3v>; /* 1.8v */
> + DVDD-supply = <®_3p3v>; /* 1.8v */
> + PVDD-supply = <®_3p3v>; /* 1.8v */
> + csi_id = <0>;
Same here
> + mclk = <24000000>;
> + mclk_source = <1>;
> + cvbs = <1>;
> + status = "disabled";
> + };
> +
> + max9526: max9526@20 {
> + compatible = "maxim,max9526";
This is not documented in mainline.
^ permalink raw reply
* [PATCH v2] ARM: dts: vf610-bk4: Fix qspi node description
From: Lukasz Majewski @ 2019-07-30 21:48 UTC (permalink / raw)
To: Shawn Guo, Fabio Estevam
Cc: Sascha Hauer, Stefan Agner, Rob Herring, Mark Rutland,
linux-arm-kernel, devicetree, linux-kernel, Lukasz Majewski
Before this change the device tree description of qspi node for
second memory on BK4 board was wrong (applicable to old, removed
fsl-quadspi.c driver).
As a result this memory was not recognized correctly when used
with the new spi-fsl-qspi.c driver.
>From the dt-bindings:
"Required SPI slave node properties:
- reg: There are two buses (A and B) with two chip selects each.
This encodes to which bus and CS the flash is connected:
<0>: Bus A, CS 0
<1>: Bus A, CS 1
<2>: Bus B, CS 0
<3>: Bus B, CS 1"
According to above with new driver the second SPI-NOR memory shall
have reg=<2> as it is connected to Bus B, CS 0.
Signed-off-by: Lukasz Majewski <lukma@denx.de>
Suggested-by: Fabio Estevam <festevam@gmail.com>
Fixes: a67d2c52a82f ("ARM: dts: Add support for Liebherr's BK4 device
(vf610 based)")
---
Changes for v2:
- Add proper Suggested-by tag as Fabio was the one who pointed out the
the issue with wrong reg number assignment for the second SPI-NOR memory
- Add Fixes: tag, so the patch could be added to LTS kernels
- Fix the subject line to more appropriate
---
arch/arm/boot/dts/vf610-bk4.dts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/vf610-bk4.dts b/arch/arm/boot/dts/vf610-bk4.dts
index 3fa0cbe456db..0f3870d3b099 100644
--- a/arch/arm/boot/dts/vf610-bk4.dts
+++ b/arch/arm/boot/dts/vf610-bk4.dts
@@ -246,13 +246,13 @@
reg = <0>;
};
- n25q128a13_2: flash@1 {
+ n25q128a13_2: flash@2 {
compatible = "n25q128a13", "jedec,spi-nor";
#address-cells = <1>;
#size-cells = <1>;
spi-max-frequency = <66000000>;
spi-rx-bus-width = <2>;
- reg = <1>;
+ reg = <2>;
};
};
--
2.11.0
^ permalink raw reply related
* Re: [PATCH v7 2/4] soc: qcom: Add AOSS QMP driver
From: Stephen Boyd @ 2019-07-30 22:49 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Doug Anderson, Andy Gross, David Brown, Rob Herring, Mark Rutland,
linux-arm-msm, devicetree, LKML
In-Reply-To: <20190523190925.GU31438@minitux>
Quoting Bjorn Andersson (2019-05-23 12:09:25)
>
> I had to read through the clock code to conclude that this was indeed
> the design, so I'm happy with your patch of ensuring that this is
> followed. Perhaps add a statement in the kerneldoc for struct clk_hw as
> well to state that init won't be accessed past the return of
> clk_register.
>
I noticed that I had a branch for this that didn't go away this rebase.
I've thrown this on my todo list now.
I added the comment to the code, but I'm afraid I can't just merge this
patch to clk-next yet because various drivers access hw->init after
calling clk_register() and friends. I'll have to go through and find the
users by looking at git grep '->init' -- drivers/clk/ results. This is a
pain.
^ permalink raw reply
* Re: [PATCH v3 2/6] OPP: Add support for bandwidth OPP tables
From: Saravana Kannan @ 2019-07-30 23:20 UTC (permalink / raw)
To: Amit Kucheria
Cc: Georgi Djakov, Rob Herring, Mark Rutland, Viresh Kumar,
Nishanth Menon, Stephen Boyd, Rafael J. Wysocki, Vincent Guittot,
Sweeney, Sean, David Dai, Rajendra Nayak, Sibi Sankar,
Bjorn Andersson, Evan Green, Android Kernel Team, Linux PM list,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS, LKML
In-Reply-To: <CAHLCerP81Eotae5s4-Qye77SSF6-BbqFhckvkTEQWBD9biwzbw@mail.gmail.com>
On Tue, Jul 30, 2019 at 3:57 AM Amit Kucheria <amit.kucheria@linaro.org> wrote:
>
> On Wed, Jul 3, 2019 at 6:40 AM Saravana Kannan <saravanak@google.com> wrote:
> >
> > Not all devices quantify their performance points in terms of frequency.
> > Devices like interconnects quantify their performance points in terms of
> > bandwidth. We need a way to represent these bandwidth levels in OPP. So,
> > add support for parsing bandwidth OPPs from DT.
> >
> > Signed-off-by: Saravana Kannan <saravanak@google.com>
> > ---
> > drivers/opp/of.c | 34 ++++++++++++++++++++++++++++++++--
> > drivers/opp/opp.h | 4 +++-
> > 2 files changed, 35 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/opp/of.c b/drivers/opp/of.c
> > index c10c782d15aa..54fa70ed2adc 100644
> > --- a/drivers/opp/of.c
> > +++ b/drivers/opp/of.c
> > @@ -552,6 +552,35 @@ void dev_pm_opp_of_remove_table(struct device *dev)
> > }
> > EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table);
> >
> > +static int _read_opp_key(struct dev_pm_opp *new_opp, struct device_node *np)
> > +{
> > + int ret;
> > + u64 rate;
> > + u32 bw;
> > +
> > + ret = of_property_read_u64(np, "opp-hz", &rate);
> > + if (!ret) {
> > + /*
> > + * Rate is defined as an unsigned long in clk API, and so
> > + * casting explicitly to its type. Must be fixed once rate is 64
> > + * bit guaranteed in clk API.
> > + */
> > + new_opp->rate = (unsigned long)rate;
> > + return 0;
> > + }
> > +
> > + ret = of_property_read_u32(np, "opp-peak-KBps", &bw);
> > + if (ret)
> > + return ret;
> > + new_opp->rate = (unsigned long) &bw;
> > +
> > + ret = of_property_read_u32(np, "opp-avg-KBps", &bw);
> > + if (!ret)
> > + new_opp->avg_bw = (unsigned long) &bw;
> > +
> > + return 0;
> > +}
> > +
> > /**
> > * _opp_add_static_v2() - Allocate static OPPs (As per 'v2' DT bindings)
> > * @opp_table: OPP table
> > @@ -589,11 +618,12 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table,
> > if (!new_opp)
> > return ERR_PTR(-ENOMEM);
> >
> > - ret = of_property_read_u64(np, "opp-hz", &rate);
> > + ret = _read_opp_key(new_opp, np);
> > if (ret < 0) {
> > /* "opp-hz" is optional for devices like power domains. */
> > if (!opp_table->is_genpd) {
> > - dev_err(dev, "%s: opp-hz not found\n", __func__);
> > + dev_err(dev, "%s: opp-hz or opp-peak-bw not found\n",
> > + __func__);
> > goto free_opp;
> > }
> >
> > diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h
> > index 569b3525aa67..ead2cdafe957 100644
> > --- a/drivers/opp/opp.h
> > +++ b/drivers/opp/opp.h
> > @@ -59,7 +59,8 @@ extern struct list_head opp_tables;
> > * @turbo: true if turbo (boost) OPP
> > * @suspend: true if suspend OPP
> > * @pstate: Device's power domain's performance state.
> > - * @rate: Frequency in hertz
> > + * @rate: Frequency in hertz OR Peak bandwidth in kilobytes per second
>
> rate is most often used for clk rates. Let us not overload this just
> to save one struct member. IMO, you should introduce a peak_bw member
> and then have an error check if the DT provides both rate and peak_bw
> during parsing.
This is not about saving space. It avoids having to rewrite a lot of
helper functions. If you want, I can rename this to "key" but I'm not
going to create a different field.
-Saravana
^ permalink raw reply
* Re: [v6 1/2] dt-bindings: gpio: aspeed: Add SGPIO support
From: Andrew Jeffery @ 2019-07-30 23:58 UTC (permalink / raw)
To: Hongwei Zhang, Linus Walleij, Joel Stanley, devicetree
Cc: Rob Herring, Bartosz Golaszewski, linux-aspeed, linux-kernel,
linux-arm-kernel, linux-gpio
In-Reply-To: <1564500268-2627-2-git-send-email-hongweiz@ami.com>
On Wed, 31 Jul 2019, at 00:55, Hongwei Zhang wrote:
> Add bindings to support SGPIO on AST2400 or AST2500.
>
> Signed-off-by: Hongwei Zhang <hongweiz@ami.com>
> ---
> .../devicetree/bindings/gpio/sgpio-aspeed.txt | 55 ++++++++++++++++++++++
> 1 file changed, 55 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt
>
> diff --git a/Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt
> b/Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt
> new file mode 100644
> index 0000000..f9ed438
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/gpio/sgpio-aspeed.txt
> @@ -0,0 +1,55 @@
> +Aspeed SGPIO controller Device Tree Bindings
> +-------------------------------------------
> +
> +This SGPIO controller is for ASPEED AST2500 SoC, it supports up to 80
> full
> +featured Serial GPIOs. Each of the Serial GPIO pins can be programmed
> to
> +support the following options:
> +- Support interrupt option for each input port and various interrupt
> + sensitivity option (level-high, level-low, edge-high, edge-low)
> +- Support reset tolerance option for each output port
> +- Directly connected to APB bus and its shift clock is from APB bus
> clock
> + divided by a programmable value.
> +- Co-work with external signal-chained TTL components (74LV165/74LV595)
> +
> +
> +Required properties:
> +
> +- compatible : Either "aspeed,ast2400-sgpio" or "aspeed,ast2500-sgpio"
> +
> +- #gpio-cells : Should be two
> + - First cell is the GPIO line number
> + - Second cell is used to specify optional
> + parameters (unused)
> +
> +- reg : Address and length of the register set for the device
> +- gpio-controller : Marks the device node as a GPIO controller
> +- interrupts : Interrupt specifier (see interrupt bindings for
> + details)
> +
> +- interrupt-controller : Mark the GPIO controller as an
> interrupt-controller
> +
> +- ngpios : number of GPIO pins to serialise.
> + (should be multiple of 8, up to 80 pins)
> +
> +- clocks : A phandle to the APB clock for SGPM clock
> division
> +
> +- bus-frequency : SGPM CLK frequency
> +
> +
> +The sgpio and interrupt properties are further described in their
> respective bindings documentation:
> +
> +- Documentation/devicetree/bindings/sgpio/gpio.txt
This isn't a file? This one is (s/sgpio/gpio/):
Documentation/devicetree/bindings/gpio/gpio.txt
I assume this was the result of a stray search/replace?
With that fixed you can add: Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
Andrew
> +- Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
> +
> + Example:
> + sgpio: sgpio@1e780200 {
> + #gpio-cells = <2>;
> + compatible = "aspeed,ast2500-sgpio";
> + gpio-controller;
> + interrupts = <40>;
> + reg = <0x1e780200 0x0100>;
> + clocks = <&syscon ASPEED_CLK_APB>;
> + interrupt-controller;
> + ngpios = <8>;
> + bus-frequency = <12000000>;
> + };
> --
> 2.7.4
>
>
^ permalink raw reply
* Re: [PATCH v8 00/14] Rockchip ISP1 Driver
From: Helen Koike @ 2019-07-31 0:08 UTC (permalink / raw)
To: Hans Verkuil, linux-rockchip
Cc: devicetree, eddie.cai.linux, mchehab, heiko, jeffy.chen, zyc,
linux-kernel, tfiga, hans.verkuil, laurent.pinchart, sakari.ailus,
kernel, ezequiel, linux-media, linux-arm-kernel, zhengsq
In-Reply-To: <41e7e574-2708-eb4c-ea30-e6a1ac9c073e@collabora.com>
On 7/30/19 5:50 PM, Helen Koike wrote:
>
>
> On 7/30/19 5:15 PM, Hans Verkuil wrote:
>> On 7/30/19 8:42 PM, Helen Koike wrote:
>>> Hello,
>>>
>>> I'm re-sending a new version of ISP(Camera) v4l2 driver for rockchip
>>> rk3399 SoC.
>>>
>>> I didn't change much from the last version, just applying the
>>> suggestions made in the previous one.
>>>
>>> This patchset is also available at:
>>> https://gitlab.collabora.com/koike/linux/tree/rockchip/isp/v8
>>>
>>> Libcamera patched to work with this version:
>>> https://gitlab.collabora.com/koike/libcamera
>>> (also sent to the mailing list)
>>>
>>> I tested on the rockpi 4 with a rpi v1.3 sensor and also with the
>>> Scarlet Chromebook.
>>>
>>> Known issues (same as in v7):
>>> -------------
>>> - Reloading the module doesn't work (there is some missing cleanup when
>>> unloading)
>>> - When capturing in bayer format, changing the size doesn't seem to
>>> affect the image.
>>> - crop needs more tests
>>> - v4l2-compliance error:
>>> fail: v4l2-test-controls.cpp(824): subscribe event for control 'Image Processing Controls' failed
>>> test VIDIOC_(UN)SUBSCRIBE_EVENT/DQEVENT: FAIL
>>
>> Can you mail me the full v4l2-compliance output?
>
> Sure, please check here: http://ix.io/1Q5u
> I updated v4l-utils with the latest version and I re-ran bootstrap/configure/make,
> but for some reason the hash from the link above is not the latest commit, probably some
> old configuration somewhere. I'll resend this log as soon as I get v4l2-compliance
> properly updated.
Please see the output of v4l2-compliance here with an updated v4l-utils: http://ix.io/1Q6A
>
> Thanks
> Helen
>
>>
>> Regards,
>>
>> Hans
>>
>>> It seems that if controls are supported, v4l2-compliance says that
>>> controls of type 'Image Processing Controls' are mandatory, is this
>>> correct?
>>> - It seems there are still some issues with interrupts, but I couldn't
>>> isolate them yet.
>>>
>>> Previous changelog:
>>> -------------------
>>>
>>> changes in V6:
>>> - add mipi txrx phy support
>>> - remove bool and enum from uapi header
>>> - add buf_prepare op
>>> - correct some spelling problems
>>> - return all queued buffers when starting stream failed
>>>
>>> changes in V5: Sync with local changes,
>>> - fix the SP height limit
>>> - speed up the second stream capture
>>> - the second stream can't force sync for rsz when start/stop streaming
>>> - add frame id to param vb2 buf
>>> - enable luminance maximum threshold
>>>
>>> changes in V4:
>>> - fix some bugs during development
>>> - move quantization settings to rkisp1 subdev
>>> - correct some spelling problems
>>> - describe ports in dt-binding documents
>>>
>>> changes in V3:
>>> - add some comments
>>> - fix wrong use of v4l2_async_subdev_notifier_register
>>> - optimize two paths capture at a time
>>> - remove compose
>>> - re-struct headers
>>> - add a tmp wiki page: http://opensource.rock-chips.com/wiki_Rockchip-isp1
>>>
>>> changes in V2:
>>> mipi-phy:
>>> - use async probing
>>> - make it be a child device of the GRF
>>> isp:
>>> - add dummy buffer
>>> - change the way to get bus configuration, which make it possible to
>>> add parallel sensor support in the future(without mipi-phy driver).
>>>
>>> ------------------
>>>
>>> Changes in v8:
>>> - Add SPDX in the header
>>> - Remove emacs configs
>>> - Fix doc style
>>> - Remove boiler plate license text
>>>
>>> Changes in v7:
>>> - s/IPU3/RK_ISP1
>>> - s/correspond/corresponding
>>> - s/use/uses
>>> - s/docuemnt/document
>>> - Fix checkpatch errors (lines over 80 and SPDX)
>>> - Add TODO to improve docs
>>> - Migrate dphy specific code from
>>> drivers/media/platform/rockchip/isp1/mipi_dphy_sy.c
>>> to drivers/phy/rockchip/phy-rockchip-dphy.c
>>> - Drop support for rk3288
>>> - Drop support for dphy txrx
>>> - code styling and checkpatch fixes
>>> - fixed warning because of unknown entity type
>>> - fixed v4l2-compliance errors regarding rkisp1 formats, try formats
>>> and default values
>>> - fix typo riksp1/rkisp1
>>> - redesign: remove mipi/csi subdevice, sensors connect directly to the
>>> isp subdevice in the media topology now. As a consequence, remove the
>>> hack in mipidphy_g_mbus_config() where information from the sensor was
>>> being propagated through the topology.
>>> - From the old dphy:
>>> * cache get_remote_sensor() in s_stream
>>> * use V4L2_CID_PIXEL_RATE instead of V4L2_CID_LINK_FREQ
>>> - Replace stream state with a boolean
>>> - code styling and checkpatch fixes
>>> - fix stop_stream (return after calling stop, do not reenable the stream)
>>> - fix rkisp1_isp_sd_get_selection when V4L2_SUBDEV_FORMAT_TRY is set
>>> - fix get format in output (isp_sd->out_fmt.mbus_code was being ignored)
>>> - s/intput/input
>>> - remove #define sd_to_isp_sd(_sd), add a static inline as it will be
>>> reused by the capture
>>> - s/strlcpy/strscpy
>>> - sort out the locks in isp stats
>>> - code styling and checkpatch fixes
>>> - s/strlcpy/strscpy
>>> - s/strcpy/strscpy
>>> - fix config lsc error
>>> LSC data table size is 17x17, but when configuring data to ISP,
>>> should be aligned to 18x17. That means every last data of last
>>> line should be filled with 0, and not filled with the data of
>>> next line.
>>> - Update new ISP parameters immediately
>>> For those sub modules that have shadow registers in core isp, the
>>> new programing parameters would not be active if both
>>> CIF_ISP_CTRL_ISP_CFG_UPD_PERMANENT and CFG_UPD are not set. Now
>>> we configure CFG_UPD to force update the shadow registers when new
>>> ISP parameters are configured.
>>> - fix some ISP parameters config error
>>> Some ISP parameter config functions may override the old enable
>>> bit value, because the enable bits of these modules are in the
>>> same registers with parameters. So we should save the old enable
>>> bits firstly.
>>> - code styling and checkpatch fixes
>>> - s/strlcpy/strscpy
>>> - Fix v4l2-compliance issues:
>>> * remove input ioctls
>>> media api can be used to define the topology, this input api is not
>>> required. Besides it, if an input is enumerated, v4l2-compliance is not
>>> happy with G_FMT returning the default colorspace instead of something
>>> more specific.
>>> * return the pixelformat to the userspace
>>> G_/S_/TRY_ FORMAT should return a valid pixelformat to the user, even if
>>> the user gave an invalid one
>>> * add missing default colorspace and ycbcr
>>> * fix wrong pixformat in mp_fmts[] table
>>> * add buf type check in s_/g_selection
>>> * queue_setup - check sizes
>>> * normalize bus_info name
>>> * fix field any v4l2-compliance -s complain - set field none
>>> when streaming
>>> - Fix compiling error: s/vidioc_enum_fmt_vid_cap_mplane/vidioc_enum_fmt_vid_cap
>>> - Replace stream state with a boolean
>>> The rkisp1_state enum consists only of 3 entries, where 1 is completely
>>> unused and the other two respectively mean not streaming or streaming.
>>> Replace it with a boolean called "streaming".
>>> - Simplify MI interrupt handling
>>> Rather than adding unnecessary indirection, just use stream index to
>>> handle MI interrupt enable/disable/clear, since the stream index matches
>>> the order of bits now, thanks to previous patch. While at it, remove
>>> some dead code.
>>> - code styling and checkpatch fixes
>>> - add link_validate: don't allow a link with bayer/non-bayer mismatch
>>> - VIDEO_ROCKCHIP_ISP1 selects VIDEOBUF2_VMALLOC
>>> - add PHY_ROCKCHIP_DPHY as a dependency for VIDEO_ROCKCHIP_ISP1
>>> - Fix compilation and runtime errors due to bitrotting
>>> The code has bit-rotten since March 2018, fix compilation errors.
>>> The new V4L2 async notifier API requires notifiers to be initialized by
>>> a call to v4l2_async_notifier_init() before being used, do so.
>>> - Add missing module device table
>>> - use clk_bulk framework
>>> - add missing notifiers cleanups
>>> - s/strlcpy/strscpy
>>> - normalize bus_info name
>>> - fix s_stream error path, stream_cnt wans't being decremented properly
>>> - use devm_platform_ioremap_resource() helper
>>> - s/deice/device
>>> - redesign: remove mipi/csi subdevice, sensors connect directly to the
>>> isp subdevice in the media topology now.
>>> - remove "saved_state" member from rkisp1_stream struct
>>> - Reverse the order of MIs
>>> - Simplify MI interrupt handling
>>> Rather than adding unnecessary indirection, just use stream index to
>>> handle MI interrupt enable/disable/clear, since the stream index matches
>>> the order of bits now, thanks to previous patch. While at it, remove
>>> some dead code.
>>> - code styling and checkpatch fixes
>>> - update document with new design and tested example
>>> - updated doc with new design and tested example
>>> - add phy properties
>>> - add ports
>>> - add phy-cells
>>>
>>> Helen Koike (1):
>>> MAINTAINERS: add entry for Rockchip ISP1 driver
>>>
>>> Jacob Chen (9):
>>> media: doc: add document for rkisp1 meta buffer format
>>> media: rkisp1: add Rockchip MIPI Synopsys DPHY driver
>>> media: rkisp1: add Rockchip ISP1 subdev driver
>>> media: rkisp1: add ISP1 statistics driver
>>> media: rkisp1: add ISP1 params driver
>>> media: rkisp1: add capture device driver
>>> media: rkisp1: add rockchip isp1 core driver
>>> dt-bindings: Document the Rockchip ISP1 bindings
>>> dt-bindings: Document the Rockchip MIPI RX D-PHY bindings
>>>
>>> Jeffy Chen (1):
>>> media: rkisp1: Add user space ABI definitions
>>>
>>> Shunqian Zheng (3):
>>> media: videodev2.h, v4l2-ioctl: add rkisp1 meta buffer format
>>> arm64: dts: rockchip: add isp0 node for rk3399
>>> arm64: dts: rockchip: add rx0 mipi-phy for rk3399
>>>
>>> .../bindings/media/rockchip-isp1.txt | 71 +
>>> .../bindings/media/rockchip-mipi-dphy.txt | 38 +
>>> Documentation/media/uapi/v4l/meta-formats.rst | 2 +
>>> .../uapi/v4l/pixfmt-meta-rkisp1-params.rst | 23 +
>>> .../uapi/v4l/pixfmt-meta-rkisp1-stat.rst | 22 +
>>> MAINTAINERS | 8 +
>>> arch/arm64/boot/dts/rockchip/rk3399.dtsi | 36 +
>>> drivers/media/platform/Kconfig | 12 +
>>> drivers/media/platform/Makefile | 1 +
>>> drivers/media/platform/rockchip/isp1/Makefile | 7 +
>>> .../media/platform/rockchip/isp1/capture.c | 1754 +++++++++++++++++
>>> .../media/platform/rockchip/isp1/capture.h | 164 ++
>>> drivers/media/platform/rockchip/isp1/common.h | 101 +
>>> drivers/media/platform/rockchip/isp1/dev.c | 675 +++++++
>>> drivers/media/platform/rockchip/isp1/dev.h | 97 +
>>> .../media/platform/rockchip/isp1/isp_params.c | 1604 +++++++++++++++
>>> .../media/platform/rockchip/isp1/isp_params.h | 50 +
>>> .../media/platform/rockchip/isp1/isp_stats.c | 508 +++++
>>> .../media/platform/rockchip/isp1/isp_stats.h | 60 +
>>> drivers/media/platform/rockchip/isp1/regs.c | 223 +++
>>> drivers/media/platform/rockchip/isp1/regs.h | 1525 ++++++++++++++
>>> drivers/media/platform/rockchip/isp1/rkisp1.c | 1286 ++++++++++++
>>> drivers/media/platform/rockchip/isp1/rkisp1.h | 111 ++
>>> drivers/media/v4l2-core/v4l2-ioctl.c | 2 +
>>> drivers/phy/rockchip/Kconfig | 8 +
>>> drivers/phy/rockchip/Makefile | 1 +
>>> drivers/phy/rockchip/phy-rockchip-dphy.c | 408 ++++
>>> include/uapi/linux/rkisp1-config.h | 816 ++++++++
>>> include/uapi/linux/videodev2.h | 4 +
>>> 29 files changed, 9617 insertions(+)
>>> create mode 100644 Documentation/devicetree/bindings/media/rockchip-isp1.txt
>>> create mode 100644 Documentation/devicetree/bindings/media/rockchip-mipi-dphy.txt
>>> create mode 100644 Documentation/media/uapi/v4l/pixfmt-meta-rkisp1-params.rst
>>> create mode 100644 Documentation/media/uapi/v4l/pixfmt-meta-rkisp1-stat.rst
>>> create mode 100644 drivers/media/platform/rockchip/isp1/Makefile
>>> create mode 100644 drivers/media/platform/rockchip/isp1/capture.c
>>> create mode 100644 drivers/media/platform/rockchip/isp1/capture.h
>>> create mode 100644 drivers/media/platform/rockchip/isp1/common.h
>>> create mode 100644 drivers/media/platform/rockchip/isp1/dev.c
>>> create mode 100644 drivers/media/platform/rockchip/isp1/dev.h
>>> create mode 100644 drivers/media/platform/rockchip/isp1/isp_params.c
>>> create mode 100644 drivers/media/platform/rockchip/isp1/isp_params.h
>>> create mode 100644 drivers/media/platform/rockchip/isp1/isp_stats.c
>>> create mode 100644 drivers/media/platform/rockchip/isp1/isp_stats.h
>>> create mode 100644 drivers/media/platform/rockchip/isp1/regs.c
>>> create mode 100644 drivers/media/platform/rockchip/isp1/regs.h
>>> create mode 100644 drivers/media/platform/rockchip/isp1/rkisp1.c
>>> create mode 100644 drivers/media/platform/rockchip/isp1/rkisp1.h
>>> create mode 100644 drivers/phy/rockchip/phy-rockchip-dphy.c
>>> create mode 100644 include/uapi/linux/rkisp1-config.h
>>>
>>
^ permalink raw reply
* [PATCH v7 00/20] SC7 entry and exit support for Tegra210
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
This patch series includes Tegra210 deepsleep (SC7) support with RTC alarm
wake event.
This series also includes save and restore of PLLs, clocks, OSC contexts
for deepsleep exit to normal operation.
This patch series doesn't support 100% suspend/resume to allow fully
functional state upon resume and we are working on some more drivers suspend
and resume implementations.
[V7]: Changes between V6 & V7 are
- V6 feedback fixes
- Removed patch-0001 from V6 which keeps COP IRQ enabled. Looking
more into ATF FW, it loads SC7 entry FW into IRAM and sets the
COP reset vector to SC7 FW load address and resets COP. So, COP
IRQ can be cleared during suspend.
Note:
Below patch is also needed for SC7 support as GPIO restore need
to happen prior to pinctrl.
https://patchwork.kernel.org/patch/11012077/
[V6]: Changes between V5 & V6 are
- V5 feedback fixes
- DFLL suspend and resume moved to DFLL clock driver
- Add suspend and resume support for CPUFreq driver to explicitly
switch source to safe source of PLLP and disable DFLL clock.
- Fix to super clock driver to enable PLLP branch to CPU before
source switch to PLLP.
- Added save and restore support for super clock driver.
[V5]: Changes between V4 & V5 are
- V4 feedback fixes
[V4]: Changes between V3 & V4 are
- V3 feedback fixes
- Removed park bits clear for EMMC pads in pinctrl-tegra driver
function tegra_pinctrl_clear_parked_bits as based on V3 feedback
parked_bit is updated to parked_bitmask to use with DRV_PINGROUP
as well and thierry posted patch series for this.
- Implemented all peripheral clocks save and restore through their
corresponding clk_ops save_context and restore_context and removed
all direct registers store and restore in clk-tegra210 driver.
- Created separate patch for fence_delay update during PLLU init based
on V3 feedback.
- Added more comments in tegra210_clk_resume regarding dfll restore
sequence and its dependency on peripheral clocks restore.
[V3]: Changes between V2 & V3 are
- V2 feedback fixes
- GPIO restore should happen prior to Pinctrl restore to prevent
glitch on GPIO lines. So using resume_noirq for gpio tegra to allow
gpio resume prior to pinctrl resume.
- Implemented save_context and restore_context callbacks for clock
plls, pll outs and dividers in corresponding drivers.
Note: Peripheral clocks and clock enable and reset need to be in
Tegra210 clock suspend/resume as they need to be in proper sequence
w.r.t DFLL resume for restoring CPU clock.
- Removed gpio-tegra changes for hierarchical support to have PMC as
parent to GPIOs for GPIO wake event support. Thierry is working on
gpiolib for some cleanup before adding hierarchical support. So
holding on to GPIO wake support for now.
[V2] : V1 feedback fixes
Patch 0002: This version still using syscore. Thierry suggest not to
use syscore and waiting on suggestion from Linux Walleij for any better
way of storing current state of pins before suspend entry and restoring
them on resume at very early stage. So left this the same way as V1 and
will address once I get more feedback on this.
Also need to findout and implement proper way of forcing resume order
between pinctrl and gpio driver.
[V1]: Tegra210 SC7 entry and exit thru RTC wake and Power button GPIO wake
using hierarchical IRQ with PMC as parent to GPIO.
Sowjanya Komatineni (20):
pinctrl: tegra: Add suspend and resume support
pinctrl: tegra210: Add Tegra210 pinctrl pm ops
clk: tegra: divider: Save and restore divider rate
clk: tegra: pllout: Save and restore pllout context
clk: tegra: pll: Save and restore pll context
clk: tegra: Support for OSC context save and restore
clk: tegra: clk-periph: Add save and restore support
clk: tegra: clk-super: Fix to enable PLLP branches to CPU
clk: tegra: clk-super: Add save and restore support
clk: tegra: clk-dfll: Add suspend and resume support
cpufreq: tegra124: Add suspend and resume support
clk: tegra210: Use fence_udelay during PLLU init
clk: tegra210: Add suspend and resume support
soc/tegra: pmc: Allow to support more tegras wake
soc/tegra: pmc: Add pmc wake support for tegra210
arm64: tegra: Enable wake from deep sleep on RTC alarm
soc/tegra: pmc: Configure core power request polarity
soc/tegra: pmc: Configure deep sleep control settings
arm64: dts: tegra210-p2180: Jetson TX1 SC7 timings
arm64: dts: tegra210-p3450: Jetson Nano SC7 timings
arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi | 7 ++
arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts | 7 ++
arch/arm64/boot/dts/nvidia/tegra210.dtsi | 5 +-
drivers/clk/tegra/clk-dfll.c | 56 +++++++++
drivers/clk/tegra/clk-dfll.h | 2 +
drivers/clk/tegra/clk-divider.c | 11 ++
drivers/clk/tegra/clk-periph-fixed.c | 33 ++++++
drivers/clk/tegra/clk-periph-gate.c | 34 ++++++
drivers/clk/tegra/clk-periph.c | 37 ++++++
drivers/clk/tegra/clk-pll-out.c | 26 +++++
drivers/clk/tegra/clk-pll.c | 112 +++++++++++++-----
drivers/clk/tegra/clk-sdmmc-mux.c | 28 +++++
drivers/clk/tegra/clk-super.c | 53 +++++++++
drivers/clk/tegra/clk-tegra-fixed.c | 15 +++
drivers/clk/tegra/clk-tegra-super-gen4.c | 2 +-
drivers/clk/tegra/clk-tegra124-dfll-fcpu.c | 1 +
drivers/clk/tegra/clk-tegra210.c | 86 ++++++++++++--
drivers/clk/tegra/clk.c | 14 +++
drivers/clk/tegra/clk.h | 26 +++++
drivers/cpufreq/tegra124-cpufreq.c | 60 ++++++++++
drivers/pinctrl/tegra/pinctrl-tegra.c | 59 ++++++++++
drivers/pinctrl/tegra/pinctrl-tegra.h | 3 +
drivers/pinctrl/tegra/pinctrl-tegra210.c | 1 +
drivers/soc/tegra/pmc.c | 129 ++++++++++++++++++++-
24 files changed, 759 insertions(+), 48 deletions(-)
--
2.7.4
^ permalink raw reply
* [PATCH v7 01/20] pinctrl: tegra: Add suspend and resume support
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
In-Reply-To: <1564532424-10449-1-git-send-email-skomatineni@nvidia.com>
This patch adds support for Tegra pinctrl driver suspend and resume.
During suspend, context of all pinctrl registers are stored and
on resume they are all restored to have all the pinmux and pad
configuration for normal operation.
Acked-by: Thierry Reding <treding@nvidia.com>
Reviewed-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/pinctrl/tegra/pinctrl-tegra.c | 59 +++++++++++++++++++++++++++++++++++
drivers/pinctrl/tegra/pinctrl-tegra.h | 3 ++
2 files changed, 62 insertions(+)
diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.c b/drivers/pinctrl/tegra/pinctrl-tegra.c
index 186ef98e7b2b..e3a237534281 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra.c
+++ b/drivers/pinctrl/tegra/pinctrl-tegra.c
@@ -631,6 +631,58 @@ static void tegra_pinctrl_clear_parked_bits(struct tegra_pmx *pmx)
}
}
+static size_t tegra_pinctrl_get_bank_size(struct device *dev,
+ unsigned int bank_id)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct resource *res;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, bank_id);
+
+ return resource_size(res) / 4;
+}
+
+static int tegra_pinctrl_suspend(struct device *dev)
+{
+ struct tegra_pmx *pmx = dev_get_drvdata(dev);
+ u32 *backup_regs = pmx->backup_regs;
+ u32 *regs;
+ size_t bank_size;
+ unsigned int i, k;
+
+ for (i = 0; i < pmx->nbanks; i++) {
+ bank_size = tegra_pinctrl_get_bank_size(dev, i);
+ regs = pmx->regs[i];
+ for (k = 0; k < bank_size; k++)
+ *backup_regs++ = readl_relaxed(regs++);
+ }
+
+ return pinctrl_force_sleep(pmx->pctl);
+}
+
+static int tegra_pinctrl_resume(struct device *dev)
+{
+ struct tegra_pmx *pmx = dev_get_drvdata(dev);
+ u32 *backup_regs = pmx->backup_regs;
+ u32 *regs;
+ size_t bank_size;
+ unsigned int i, k;
+
+ for (i = 0; i < pmx->nbanks; i++) {
+ bank_size = tegra_pinctrl_get_bank_size(dev, i);
+ regs = pmx->regs[i];
+ for (k = 0; k < bank_size; k++)
+ writel_relaxed(*backup_regs++, regs++);
+ }
+
+ return 0;
+}
+
+const struct dev_pm_ops tegra_pinctrl_pm = {
+ .suspend = &tegra_pinctrl_suspend,
+ .resume = &tegra_pinctrl_resume
+};
+
static bool gpio_node_has_range(const char *compatible)
{
struct device_node *np;
@@ -655,6 +707,7 @@ int tegra_pinctrl_probe(struct platform_device *pdev,
int i;
const char **group_pins;
int fn, gn, gfn;
+ unsigned long backup_regs_size = 0;
pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
if (!pmx)
@@ -707,6 +760,7 @@ int tegra_pinctrl_probe(struct platform_device *pdev,
res = platform_get_resource(pdev, IORESOURCE_MEM, i);
if (!res)
break;
+ backup_regs_size += resource_size(res);
}
pmx->nbanks = i;
@@ -715,6 +769,11 @@ int tegra_pinctrl_probe(struct platform_device *pdev,
if (!pmx->regs)
return -ENOMEM;
+ pmx->backup_regs = devm_kzalloc(&pdev->dev, backup_regs_size,
+ GFP_KERNEL);
+ if (!pmx->backup_regs)
+ return -ENOMEM;
+
for (i = 0; i < pmx->nbanks; i++) {
res = platform_get_resource(pdev, IORESOURCE_MEM, i);
pmx->regs[i] = devm_ioremap_resource(&pdev->dev, res);
diff --git a/drivers/pinctrl/tegra/pinctrl-tegra.h b/drivers/pinctrl/tegra/pinctrl-tegra.h
index 105309774079..0fc82eea9cf1 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra.h
+++ b/drivers/pinctrl/tegra/pinctrl-tegra.h
@@ -17,6 +17,7 @@ struct tegra_pmx {
int nbanks;
void __iomem **regs;
+ u32 *backup_regs;
};
enum tegra_pinconf_param {
@@ -193,6 +194,8 @@ struct tegra_pinctrl_soc_data {
bool drvtype_in_mux;
};
+extern const struct dev_pm_ops tegra_pinctrl_pm;
+
int tegra_pinctrl_probe(struct platform_device *pdev,
const struct tegra_pinctrl_soc_data *soc_data);
#endif
--
2.7.4
^ permalink raw reply related
* [PATCH v7 02/20] pinctrl: tegra210: Add Tegra210 pinctrl pm ops
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
In-Reply-To: <1564532424-10449-1-git-send-email-skomatineni@nvidia.com>
This patch adds suspend and resume functionality to Tegra210 pinctrl.
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/pinctrl/tegra/pinctrl-tegra210.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/pinctrl/tegra/pinctrl-tegra210.c b/drivers/pinctrl/tegra/pinctrl-tegra210.c
index 39ab6480a941..fc072a36deb3 100644
--- a/drivers/pinctrl/tegra/pinctrl-tegra210.c
+++ b/drivers/pinctrl/tegra/pinctrl-tegra210.c
@@ -1571,6 +1571,7 @@ static struct platform_driver tegra210_pinctrl_driver = {
.driver = {
.name = "tegra210-pinctrl",
.of_match_table = tegra210_pinctrl_of_match,
+ .pm = &tegra_pinctrl_pm,
},
.probe = tegra210_pinctrl_probe,
};
--
2.7.4
^ permalink raw reply related
* [PATCH v7 03/20] clk: tegra: divider: Save and restore divider rate
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
In-Reply-To: <1564532424-10449-1-git-send-email-skomatineni@nvidia.com>
This patch implements context restore for clock divider.
During system suspend, core power goes off and looses the settings
of the Tegra CAR controller registers.
So on resume, clock dividers are restored back for normal operation.
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-divider.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/clk/tegra/clk-divider.c b/drivers/clk/tegra/clk-divider.c
index e76731fb7d69..ca0de5f11f84 100644
--- a/drivers/clk/tegra/clk-divider.c
+++ b/drivers/clk/tegra/clk-divider.c
@@ -109,10 +109,21 @@ static int clk_frac_div_set_rate(struct clk_hw *hw, unsigned long rate,
return 0;
}
+static void clk_divider_restore_context(struct clk_hw *hw)
+{
+ struct clk_hw *parent = clk_hw_get_parent(hw);
+ unsigned long parent_rate = clk_hw_get_rate(parent);
+ unsigned long rate = clk_hw_get_rate(hw);
+
+ if (clk_frac_div_set_rate(hw, rate, parent_rate) < 0)
+ WARN_ON(1);
+}
+
const struct clk_ops tegra_clk_frac_div_ops = {
.recalc_rate = clk_frac_div_recalc_rate,
.set_rate = clk_frac_div_set_rate,
.round_rate = clk_frac_div_round_rate,
+ .restore_context = clk_divider_restore_context,
};
struct clk *tegra_clk_register_divider(const char *name,
--
2.7.4
^ permalink raw reply related
* [PATCH v7 04/20] clk: tegra: pllout: Save and restore pllout context
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
In-Reply-To: <1564532424-10449-1-git-send-email-skomatineni@nvidia.com>
This patch implements save and restore of pllout context.
During system suspend, core power goes off and looses the settings
of the Tegra CAR controller registers.
So during suspend entry the state of pllout is saved and on resume
it is restored back to have pllout in same state as before suspend.
pllout rate is saved and restore in clock divider so it will be at
same rate as before suspend when pllout state is restored.
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-pll-out.c | 26 ++++++++++++++++++++++++++
drivers/clk/tegra/clk-tegra210.c | 3 ++-
drivers/clk/tegra/clk.h | 9 +++++++++
3 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/tegra/clk-pll-out.c b/drivers/clk/tegra/clk-pll-out.c
index 35f2bf00e1e6..312a3e8ef398 100644
--- a/drivers/clk/tegra/clk-pll-out.c
+++ b/drivers/clk/tegra/clk-pll-out.c
@@ -69,10 +69,36 @@ static void clk_pll_out_disable(struct clk_hw *hw)
spin_unlock_irqrestore(pll_out->lock, flags);
}
+static int tegra_clk_pll_out_save_context(struct clk_hw *hw)
+{
+ struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
+
+ if (pll_out->flags & TEGRA_PLLRE_OUT)
+ pll_out->pllout_ctx = readl_relaxed(pll_out->reg);
+
+ return 0;
+}
+
+static void tegra_clk_pll_out_restore_context(struct clk_hw *hw)
+{
+ struct tegra_clk_pll_out *pll_out = to_clk_pll_out(hw);
+
+ if (pll_out->flags & TEGRA_PLLRE_OUT) {
+ writel_relaxed(pll_out->pllout_ctx, pll_out->reg);
+ } else {
+ if (!__clk_get_enable_count(hw->clk))
+ clk_pll_out_disable(hw);
+ else
+ clk_pll_out_enable(hw);
+ }
+}
+
const struct clk_ops tegra_clk_pll_out_ops = {
.is_enabled = clk_pll_out_is_enabled,
.enable = clk_pll_out_enable,
.disable = clk_pll_out_disable,
+ .save_context = tegra_clk_pll_out_save_context,
+ .restore_context = tegra_clk_pll_out_restore_context,
};
struct clk *tegra_clk_register_pll_out(const char *name,
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index df172d5772d7..4721ee030d1c 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -3200,7 +3200,8 @@ static void __init tegra210_pll_init(void __iomem *clk_base,
8, 8, 1, NULL);
clk = tegra_clk_register_pll_out("pll_re_out1", "pll_re_out1_div",
clk_base + PLLRE_OUT1, 1, 0,
- CLK_SET_RATE_PARENT, 0, NULL);
+ CLK_SET_RATE_PARENT, TEGRA_PLLRE_OUT,
+ NULL);
clks[TEGRA210_CLK_PLL_RE_OUT1] = clk;
/* PLLE */
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 905bf1096558..230c05d8eef0 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -437,6 +437,12 @@ struct clk *tegra_clk_register_pllu_tegra210(const char *name,
* @rst_bit_idx: bit to reset PLL divider
* @lock: register lock
* @flags: hardware-specific flags
+ * @pllout_ctx: pllout context to save and restore during suspend
+ * and resume
+ *
+ * Flags:
+ * TEGRA_PLLRE_OUT - This flag indicates that it is PLLRE_OUT and is used to
+ * identify PLLRE_OUT during clk_pll_out save and restore.
*/
struct tegra_clk_pll_out {
struct clk_hw hw;
@@ -445,8 +451,11 @@ struct tegra_clk_pll_out {
u8 rst_bit_idx;
spinlock_t *lock;
u8 flags;
+ u32 pllout_ctx;
};
+#define TEGRA_PLLRE_OUT BIT(0)
+
#define to_clk_pll_out(_hw) container_of(_hw, struct tegra_clk_pll_out, hw)
extern const struct clk_ops tegra_clk_pll_out_ops;
--
2.7.4
^ permalink raw reply related
* [PATCH v7 05/20] clk: tegra: pll: Save and restore pll context
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
In-Reply-To: <1564532424-10449-1-git-send-email-skomatineni@nvidia.com>
This patch implements save and restore of PLL context.
During system suspend, core power goes off and looses the settings
of the Tegra CAR controller registers.
So during suspend entry pll context is stored and on resume it is
restored back along with its state.
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-pll.c | 112 +++++++++++++++++++++++++++++++-------------
drivers/clk/tegra/clk.h | 4 ++
2 files changed, 84 insertions(+), 32 deletions(-)
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index 1583f5fc992f..344605135a70 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -1008,6 +1008,50 @@ static unsigned long clk_plle_recalc_rate(struct clk_hw *hw,
return rate;
}
+static int tegra_clk_pll_save_context(struct clk_hw *hw)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ u32 val = 0;
+
+ if (pll->params->flags & TEGRA_PLLMB)
+ val = pll_readl_base(pll);
+ else if (pll->params->flags & TEGRA_PLLRE)
+ val = pll_readl_base(pll) & divp_mask_shifted(pll);
+
+ pll->pllbase_ctx = val;
+ return 0;
+}
+
+static void tegra_clk_pll_restore_context(struct clk_hw *hw)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ struct clk_hw *parent = clk_hw_get_parent(hw);
+ unsigned long parent_rate = clk_hw_get_rate(parent);
+ unsigned long rate = clk_hw_get_rate(hw);
+ u32 val;
+
+ if (clk_pll_is_enabled(hw))
+ return;
+
+ if (pll->params->flags & TEGRA_PLLMB) {
+ pll_writel_base(pll->pllbase_ctx, pll);
+ } else if (pll->params->flags & TEGRA_PLLRE) {
+ val = pll_readl_base(pll);
+ val &= ~(divp_mask_shifted(pll));
+ pll_writel_base(pll->pllbase_ctx | val, pll);
+ }
+
+ if (pll->params->set_defaults)
+ pll->params->set_defaults(pll);
+
+ clk_pll_set_rate(hw, rate, parent_rate);
+
+ if (!__clk_get_enable_count(hw->clk))
+ clk_pll_disable(hw);
+ else
+ clk_pll_enable(hw);
+}
+
const struct clk_ops tegra_clk_pll_ops = {
.is_enabled = clk_pll_is_enabled,
.enable = clk_pll_enable,
@@ -1015,6 +1059,8 @@ const struct clk_ops tegra_clk_pll_ops = {
.recalc_rate = clk_pll_recalc_rate,
.round_rate = clk_pll_round_rate,
.set_rate = clk_pll_set_rate,
+ .save_context = tegra_clk_pll_save_context,
+ .restore_context = tegra_clk_pll_restore_context,
};
const struct clk_ops tegra_clk_plle_ops = {
@@ -1802,6 +1848,27 @@ static int clk_pllu_tegra114_enable(struct clk_hw *hw)
return ret;
}
+
+static void _clk_plle_tegra_init_parent(struct tegra_clk_pll *pll)
+{
+ u32 val, val_aux;
+
+ /* ensure parent is set to pll_ref */
+ val = pll_readl_base(pll);
+ val_aux = pll_readl(pll->params->aux_reg, pll);
+
+ if (val & PLL_BASE_ENABLE) {
+ if ((val_aux & PLLE_AUX_PLLRE_SEL) ||
+ (val_aux & PLLE_AUX_PLLP_SEL))
+ WARN(1, "pll_e enabled with unsupported parent %s\n",
+ (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" :
+ "pll_re_vco");
+ } else {
+ val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL);
+ pll_writel(val_aux, pll->params->aux_reg, pll);
+ fence_udelay(1, pll->clk_base);
+ }
+}
#endif
static struct tegra_clk_pll *_tegra_init_pll(void __iomem *clk_base,
@@ -2214,27 +2281,12 @@ struct clk *tegra_clk_register_plle_tegra114(const char *name,
{
struct tegra_clk_pll *pll;
struct clk *clk;
- u32 val, val_aux;
pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
- /* ensure parent is set to pll_re_vco */
-
- val = pll_readl_base(pll);
- val_aux = pll_readl(pll_params->aux_reg, pll);
-
- if (val & PLL_BASE_ENABLE) {
- if ((val_aux & PLLE_AUX_PLLRE_SEL) ||
- (val_aux & PLLE_AUX_PLLP_SEL))
- WARN(1, "pll_e enabled with unsupported parent %s\n",
- (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" :
- "pll_re_vco");
- } else {
- val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL);
- pll_writel(val_aux, pll_params->aux_reg, pll);
- }
+ _clk_plle_tegra_init_parent(pll);
clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
&tegra_clk_plle_tegra114_ops);
@@ -2276,6 +2328,8 @@ static const struct clk_ops tegra_clk_pllss_ops = {
.recalc_rate = clk_pll_recalc_rate,
.round_rate = clk_pll_ramp_round_rate,
.set_rate = clk_pllxc_set_rate,
+ .save_context = tegra_clk_pll_save_context,
+ .restore_context = tegra_clk_pll_restore_context,
};
struct clk *tegra_clk_register_pllss(const char *name, const char *parent_name,
@@ -2375,6 +2429,7 @@ struct clk *tegra_clk_register_pllre_tegra210(const char *name,
pll_params->vco_min = pll_params->adjust_vco(pll_params,
parent_rate);
+ pll_params->flags |= TEGRA_PLLRE;
pll = _tegra_init_pll(clk_base, pmc, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
@@ -2520,11 +2575,19 @@ static void clk_plle_tegra210_disable(struct clk_hw *hw)
spin_unlock_irqrestore(pll->lock, flags);
}
+static void tegra_clk_plle_t210_restore_context(struct clk_hw *hw)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+
+ _clk_plle_tegra_init_parent(pll);
+}
+
static const struct clk_ops tegra_clk_plle_tegra210_ops = {
.is_enabled = clk_plle_tegra210_is_enabled,
.enable = clk_plle_tegra210_enable,
.disable = clk_plle_tegra210_disable,
.recalc_rate = clk_pll_recalc_rate,
+ .restore_context = tegra_clk_plle_t210_restore_context,
};
struct clk *tegra_clk_register_plle_tegra210(const char *name,
@@ -2535,27 +2598,12 @@ struct clk *tegra_clk_register_plle_tegra210(const char *name,
{
struct tegra_clk_pll *pll;
struct clk *clk;
- u32 val, val_aux;
pll = _tegra_init_pll(clk_base, NULL, pll_params, lock);
if (IS_ERR(pll))
return ERR_CAST(pll);
- /* ensure parent is set to pll_re_vco */
-
- val = pll_readl_base(pll);
- val_aux = pll_readl(pll_params->aux_reg, pll);
-
- if (val & PLLE_BASE_ENABLE) {
- if ((val_aux & PLLE_AUX_PLLRE_SEL) ||
- (val_aux & PLLE_AUX_PLLP_SEL))
- WARN(1, "pll_e enabled with unsupported parent %s\n",
- (val_aux & PLLE_AUX_PLLP_SEL) ? "pllp_out0" :
- "pll_re_vco");
- } else {
- val_aux &= ~(PLLE_AUX_PLLRE_SEL | PLLE_AUX_PLLP_SEL);
- pll_writel(val_aux, pll_params->aux_reg, pll);
- }
+ _clk_plle_tegra_init_parent(pll);
clk = _tegra_clk_register_pll(pll, name, parent_name, flags,
&tegra_clk_plle_tegra210_ops);
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index 230c05d8eef0..f1ef6ae8c979 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -233,6 +233,7 @@ struct tegra_clk_pll;
* TEGRA_PLLMB - PLLMB has should be treated similar to PLLM. This
* flag indicated that it is PLLMB.
* TEGRA_PLL_VCO_OUT - Used to indicate that the PLL has a VCO output
+ * TEGRA_PLLRE - Used to indicate that it is PLLRE
*/
struct tegra_clk_pll_params {
unsigned long input_min;
@@ -299,6 +300,7 @@ struct tegra_clk_pll_params {
#define TEGRA_MDIV_NEW BIT(11)
#define TEGRA_PLLMB BIT(12)
#define TEGRA_PLL_VCO_OUT BIT(13)
+#define TEGRA_PLLRE BIT(14)
/**
* struct tegra_clk_pll - Tegra PLL clock
@@ -308,6 +310,7 @@ struct tegra_clk_pll_params {
* @pmc: address of PMC, required to read override bits
* @lock: register lock
* @params: PLL parameters
+ * @pllbase_ctx: pll base register value during suspend and resume
*/
struct tegra_clk_pll {
struct clk_hw hw;
@@ -315,6 +318,7 @@ struct tegra_clk_pll {
void __iomem *pmc;
spinlock_t *lock;
struct tegra_clk_pll_params *params;
+ u32 pllbase_ctx;
};
#define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw)
--
2.7.4
^ permalink raw reply related
* [PATCH v7 06/20] clk: tegra: Support for OSC context save and restore
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
In-Reply-To: <1564532424-10449-1-git-send-email-skomatineni@nvidia.com>
This patch adds support for saving OSC clock frequency and the
drive-strength during OSC clock init and creates an API to restore
OSC control register value from the saved context.
This API is invoked by Tegra210 clock driver during system resume
to restore the OSC clock settings.
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-tegra-fixed.c | 15 +++++++++++++++
drivers/clk/tegra/clk.h | 1 +
2 files changed, 16 insertions(+)
diff --git a/drivers/clk/tegra/clk-tegra-fixed.c b/drivers/clk/tegra/clk-tegra-fixed.c
index 8d91b2b191cf..7c6c8abfcde6 100644
--- a/drivers/clk/tegra/clk-tegra-fixed.c
+++ b/drivers/clk/tegra/clk-tegra-fixed.c
@@ -17,6 +17,10 @@
#define OSC_CTRL 0x50
#define OSC_CTRL_OSC_FREQ_SHIFT 28
#define OSC_CTRL_PLL_REF_DIV_SHIFT 26
+#define OSC_CTRL_MASK (0x3f2 | \
+ (0xf << OSC_CTRL_OSC_FREQ_SHIFT))
+
+static u32 osc_ctrl_ctx;
int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
unsigned long *input_freqs, unsigned int num,
@@ -29,6 +33,7 @@ int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
unsigned osc_idx;
val = readl_relaxed(clk_base + OSC_CTRL);
+ osc_ctrl_ctx = val & OSC_CTRL_MASK;
osc_idx = val >> OSC_CTRL_OSC_FREQ_SHIFT;
if (osc_idx < num)
@@ -96,3 +101,13 @@ void __init tegra_fixed_clk_init(struct tegra_clk *tegra_clks)
*dt_clk = clk;
}
}
+
+void tegra_clk_osc_resume(void __iomem *clk_base)
+{
+ u32 val;
+
+ val = readl_relaxed(clk_base + OSC_CTRL) & ~OSC_CTRL_MASK;
+ val |= osc_ctrl_ctx;
+ writel_relaxed(val, clk_base + OSC_CTRL);
+ fence_udelay(2, clk_base);
+}
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index f1ef6ae8c979..abba6d8a04cd 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -842,6 +842,7 @@ u16 tegra_pll_get_fixed_mdiv(struct clk_hw *hw, unsigned long input_rate);
int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div);
int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
u8 frac_width, u8 flags);
+void tegra_clk_osc_resume(void __iomem *clk_base);
/* Combined read fence with delay */
--
2.7.4
^ permalink raw reply related
* [PATCH v7 07/20] clk: tegra: clk-periph: Add save and restore support
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
In-Reply-To: <1564532424-10449-1-git-send-email-skomatineni@nvidia.com>
This patch implements save and restore context for peripheral fixed
clock ops, peripheral gate clock ops, sdmmc mux clock ops, and
peripheral clock ops.
During system suspend, core power goes off and looses the settings
of the Tegra CAR controller registers.
So during suspend entry clock and reset state of peripherals is saved
and on resume they are restored to have clocks back to same rate and
state as before suspend.
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-periph-fixed.c | 33 ++++++++++++++++++++++++++++++++
drivers/clk/tegra/clk-periph-gate.c | 34 +++++++++++++++++++++++++++++++++
drivers/clk/tegra/clk-periph.c | 37 ++++++++++++++++++++++++++++++++++++
drivers/clk/tegra/clk-sdmmc-mux.c | 28 +++++++++++++++++++++++++++
drivers/clk/tegra/clk.h | 6 ++++++
5 files changed, 138 insertions(+)
diff --git a/drivers/clk/tegra/clk-periph-fixed.c b/drivers/clk/tegra/clk-periph-fixed.c
index c088e7a280df..21b24530fa00 100644
--- a/drivers/clk/tegra/clk-periph-fixed.c
+++ b/drivers/clk/tegra/clk-periph-fixed.c
@@ -60,11 +60,44 @@ tegra_clk_periph_fixed_recalc_rate(struct clk_hw *hw,
return (unsigned long)rate;
}
+static int tegra_clk_periph_fixed_save_context(struct clk_hw *hw)
+{
+ struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw);
+ u32 mask = 1 << (fixed->num % 32);
+
+ fixed->enb_ctx = readl_relaxed(fixed->base + fixed->regs->enb_reg) &
+ mask;
+ fixed->rst_ctx = readl_relaxed(fixed->base + fixed->regs->rst_reg) &
+ mask;
+
+ return 0;
+}
+
+static void tegra_clk_periph_fixed_restore_context(struct clk_hw *hw)
+{
+ struct tegra_clk_periph_fixed *fixed = to_tegra_clk_periph_fixed(hw);
+ u32 mask = 1 << (fixed->num % 32);
+
+ if (fixed->enb_ctx)
+ writel_relaxed(mask, fixed->base + fixed->regs->enb_set_reg);
+ else
+ writel_relaxed(mask, fixed->base + fixed->regs->enb_clr_reg);
+
+ udelay(2);
+
+ if (!fixed->rst_ctx) {
+ udelay(5); /* reset propogation delay */
+ writel_relaxed(mask, fixed->base + fixed->regs->rst_reg);
+ }
+}
+
static const struct clk_ops tegra_clk_periph_fixed_ops = {
.is_enabled = tegra_clk_periph_fixed_is_enabled,
.enable = tegra_clk_periph_fixed_enable,
.disable = tegra_clk_periph_fixed_disable,
.recalc_rate = tegra_clk_periph_fixed_recalc_rate,
+ .save_context = tegra_clk_periph_fixed_save_context,
+ .restore_context = tegra_clk_periph_fixed_restore_context,
};
struct clk *tegra_clk_register_periph_fixed(const char *name,
diff --git a/drivers/clk/tegra/clk-periph-gate.c b/drivers/clk/tegra/clk-periph-gate.c
index 4b31beefc9fc..6ba5b08e0787 100644
--- a/drivers/clk/tegra/clk-periph-gate.c
+++ b/drivers/clk/tegra/clk-periph-gate.c
@@ -25,6 +25,8 @@ static DEFINE_SPINLOCK(periph_ref_lock);
#define read_rst(gate) \
readl_relaxed(gate->clk_base + (gate->regs->rst_reg))
+#define write_rst_set(val, gate) \
+ writel_relaxed(val, gate->clk_base + (gate->regs->rst_set_reg))
#define write_rst_clr(val, gate) \
writel_relaxed(val, gate->clk_base + (gate->regs->rst_clr_reg))
@@ -110,10 +112,42 @@ static void clk_periph_disable(struct clk_hw *hw)
spin_unlock_irqrestore(&periph_ref_lock, flags);
}
+static int clk_periph_gate_save_context(struct clk_hw *hw)
+{
+ struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw);
+
+ gate->clk_state_ctx = read_enb(gate) & periph_clk_to_bit(gate);
+ gate->rst_state_ctx = read_rst(gate) & periph_clk_to_bit(gate);
+
+ return 0;
+}
+
+static void clk_periph_gate_restore_context(struct clk_hw *hw)
+{
+ struct tegra_clk_periph_gate *gate = to_clk_periph_gate(hw);
+
+ if (gate->clk_state_ctx)
+ write_enb_set(periph_clk_to_bit(gate), gate);
+ else
+ write_enb_clr(periph_clk_to_bit(gate), gate);
+
+ udelay(5);
+
+ if (!(gate->flags & TEGRA_PERIPH_NO_RESET) &&
+ !(gate->flags & TEGRA_PERIPH_MANUAL_RESET)) {
+ if (gate->rst_state_ctx)
+ write_rst_set(periph_clk_to_bit(gate), gate);
+ else
+ write_rst_clr(periph_clk_to_bit(gate), gate);
+ }
+}
+
const struct clk_ops tegra_clk_periph_gate_ops = {
.is_enabled = clk_periph_is_enabled,
.enable = clk_periph_enable,
.disable = clk_periph_disable,
+ .save_context = clk_periph_gate_save_context,
+ .restore_context = clk_periph_gate_restore_context,
};
struct clk *tegra_clk_register_periph_gate(const char *name,
diff --git a/drivers/clk/tegra/clk-periph.c b/drivers/clk/tegra/clk-periph.c
index 58437da25156..06fb62955768 100644
--- a/drivers/clk/tegra/clk-periph.c
+++ b/drivers/clk/tegra/clk-periph.c
@@ -99,6 +99,37 @@ static void clk_periph_disable(struct clk_hw *hw)
gate_ops->disable(gate_hw);
}
+static int clk_periph_save_context(struct clk_hw *hw)
+{
+ struct tegra_clk_periph *periph = to_clk_periph(hw);
+ const struct clk_ops *gate_ops = periph->gate_ops;
+ struct clk_hw *gate_hw = &periph->gate.hw;
+
+ if (!(periph->gate.flags & TEGRA_PERIPH_NO_GATE))
+ gate_ops->save_context(gate_hw);
+
+ periph->parent_ctx = clk_periph_get_parent(hw);
+
+ return 0;
+}
+
+static void clk_periph_restore_context(struct clk_hw *hw)
+{
+ struct tegra_clk_periph *periph = to_clk_periph(hw);
+ const struct clk_ops *gate_ops = periph->gate_ops;
+ struct clk_hw *gate_hw = &periph->gate.hw;
+ const struct clk_ops *div_ops = periph->div_ops;
+ struct clk_hw *div_hw = &periph->divider.hw;
+
+ clk_periph_set_parent(hw, periph->parent_ctx);
+
+ if (!(periph->gate.flags & TEGRA_PERIPH_NO_DIV))
+ div_ops->restore_context(div_hw);
+
+ if (!(periph->gate.flags & TEGRA_PERIPH_NO_GATE))
+ gate_ops->restore_context(gate_hw);
+}
+
const struct clk_ops tegra_clk_periph_ops = {
.get_parent = clk_periph_get_parent,
.set_parent = clk_periph_set_parent,
@@ -108,6 +139,8 @@ const struct clk_ops tegra_clk_periph_ops = {
.is_enabled = clk_periph_is_enabled,
.enable = clk_periph_enable,
.disable = clk_periph_disable,
+ .save_context = clk_periph_save_context,
+ .restore_context = clk_periph_restore_context,
};
static const struct clk_ops tegra_clk_periph_nodiv_ops = {
@@ -116,6 +149,8 @@ static const struct clk_ops tegra_clk_periph_nodiv_ops = {
.is_enabled = clk_periph_is_enabled,
.enable = clk_periph_enable,
.disable = clk_periph_disable,
+ .save_context = clk_periph_save_context,
+ .restore_context = clk_periph_restore_context,
};
static const struct clk_ops tegra_clk_periph_no_gate_ops = {
@@ -124,6 +159,8 @@ static const struct clk_ops tegra_clk_periph_no_gate_ops = {
.recalc_rate = clk_periph_recalc_rate,
.round_rate = clk_periph_round_rate,
.set_rate = clk_periph_set_rate,
+ .save_context = clk_periph_save_context,
+ .restore_context = clk_periph_restore_context,
};
static struct clk *_tegra_clk_register_periph(const char *name,
diff --git a/drivers/clk/tegra/clk-sdmmc-mux.c b/drivers/clk/tegra/clk-sdmmc-mux.c
index a5cd3e31dbae..48da9d7fea80 100644
--- a/drivers/clk/tegra/clk-sdmmc-mux.c
+++ b/drivers/clk/tegra/clk-sdmmc-mux.c
@@ -194,6 +194,32 @@ static void clk_sdmmc_mux_disable(struct clk_hw *hw)
gate_ops->disable(gate_hw);
}
+static int clk_sdmmc_mux_save_context(struct clk_hw *hw)
+{
+ struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw);
+ const struct clk_ops *gate_ops = sdmmc_mux->gate_ops;
+ struct clk_hw *gate_hw = &sdmmc_mux->gate.hw;
+
+ sdmmc_mux->parent_ctx = clk_sdmmc_mux_get_parent(hw);
+ gate_ops->save_context(gate_hw);
+
+ return 0;
+}
+
+static void clk_sdmmc_mux_restore_context(struct clk_hw *hw)
+{
+ struct tegra_sdmmc_mux *sdmmc_mux = to_clk_sdmmc_mux(hw);
+ const struct clk_ops *gate_ops = sdmmc_mux->gate_ops;
+ struct clk_hw *gate_hw = &sdmmc_mux->gate.hw;
+ struct clk_hw *parent = clk_hw_get_parent(hw);
+ unsigned long parent_rate = clk_hw_get_rate(parent);
+ unsigned long rate = clk_hw_get_rate(hw);
+
+ clk_sdmmc_mux_set_parent(hw, sdmmc_mux->parent_ctx);
+ clk_sdmmc_mux_set_rate(hw, rate, parent_rate);
+ gate_ops->restore_context(gate_hw);
+}
+
static const struct clk_ops tegra_clk_sdmmc_mux_ops = {
.get_parent = clk_sdmmc_mux_get_parent,
.set_parent = clk_sdmmc_mux_set_parent,
@@ -203,6 +229,8 @@ static const struct clk_ops tegra_clk_sdmmc_mux_ops = {
.is_enabled = clk_sdmmc_mux_is_enabled,
.enable = clk_sdmmc_mux_enable,
.disable = clk_sdmmc_mux_disable,
+ .save_context = clk_sdmmc_mux_save_context,
+ .restore_context = clk_sdmmc_mux_restore_context,
};
struct clk *tegra_clk_register_sdmmc_mux_div(const char *name,
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index abba6d8a04cd..d61e61eebf4a 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -517,6 +517,8 @@ struct tegra_clk_periph_gate {
int clk_num;
int *enable_refcnt;
const struct tegra_clk_periph_regs *regs;
+ bool clk_state_ctx;
+ bool rst_state_ctx;
};
#define to_clk_periph_gate(_hw) \
@@ -543,6 +545,8 @@ struct tegra_clk_periph_fixed {
unsigned int mul;
unsigned int div;
unsigned int num;
+ bool enb_ctx;
+ bool rst_ctx;
};
struct clk *tegra_clk_register_periph_fixed(const char *name,
@@ -575,6 +579,7 @@ struct tegra_clk_periph {
const struct clk_ops *mux_ops;
const struct clk_ops *div_ops;
const struct clk_ops *gate_ops;
+ u8 parent_ctx;
};
#define to_clk_periph(_hw) container_of(_hw, struct tegra_clk_periph, hw)
@@ -726,6 +731,7 @@ struct tegra_sdmmc_mux {
const struct clk_ops *gate_ops;
struct tegra_clk_periph_gate gate;
u8 div_flags;
+ u8 parent_ctx;
};
#define to_clk_sdmmc_mux(_hw) container_of(_hw, struct tegra_sdmmc_mux, hw)
--
2.7.4
^ permalink raw reply related
* [PATCH v7 08/20] clk: tegra: clk-super: Fix to enable PLLP branches to CPU
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
In-Reply-To: <1564532424-10449-1-git-send-email-skomatineni@nvidia.com>
This patch has a fix to enable PLLP branches to CPU before changing
the CPU clusters clock source to PLLP for Gen5 Super clock and
disables PLLP branches to CPU when not in use.
During system suspend entry and exit, CPU source will be switched
to PLLP and this needs PLLP branches to be enabled to CPU prior to
the switch.
On system resume, warmboot code enables PLLP branches to CPU and
powers up the CPU with PLLP clock source.
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-super.c | 14 ++++++++++++++
drivers/clk/tegra/clk-tegra-super-gen4.c | 2 +-
drivers/clk/tegra/clk.c | 14 ++++++++++++++
drivers/clk/tegra/clk.h | 5 +++++
4 files changed, 34 insertions(+), 1 deletion(-)
diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
index 39ef31b46df5..e2a1e95a8db7 100644
--- a/drivers/clk/tegra/clk-super.c
+++ b/drivers/clk/tegra/clk-super.c
@@ -28,6 +28,9 @@
#define super_state_to_src_shift(m, s) ((m->width * s))
#define super_state_to_src_mask(m) (((1 << m->width) - 1))
+#define CCLK_SRC_PLLP_OUT0 4
+#define CCLK_SRC_PLLP_OUT4 5
+
static u8 clk_super_get_parent(struct clk_hw *hw)
{
struct tegra_clk_super_mux *mux = to_clk_super_mux(hw);
@@ -97,12 +100,23 @@ static int clk_super_set_parent(struct clk_hw *hw, u8 index)
if (index == mux->div2_index)
index = mux->pllx_index;
}
+
+ /* enable PLLP branches to CPU before selecting PLLP source */
+ if ((mux->flags & TEGRA210_CPU_CLK) &&
+ (index == CCLK_SRC_PLLP_OUT0 || index == CCLK_SRC_PLLP_OUT4))
+ tegra_clk_set_pllp_out_cpu(true);
+
val &= ~((super_state_to_src_mask(mux)) << shift);
val |= (index & (super_state_to_src_mask(mux))) << shift;
writel_relaxed(val, mux->reg);
udelay(2);
+ /* disable PLLP branches to CPU if not used */
+ if ((mux->flags & TEGRA210_CPU_CLK) &&
+ index != CCLK_SRC_PLLP_OUT0 && index != CCLK_SRC_PLLP_OUT4)
+ tegra_clk_set_pllp_out_cpu(false);
+
out:
if (mux->lock)
spin_unlock_irqrestore(mux->lock, flags);
diff --git a/drivers/clk/tegra/clk-tegra-super-gen4.c b/drivers/clk/tegra/clk-tegra-super-gen4.c
index cdfe7c9697e1..888d76b01c75 100644
--- a/drivers/clk/tegra/clk-tegra-super-gen4.c
+++ b/drivers/clk/tegra/clk-tegra-super-gen4.c
@@ -180,7 +180,7 @@ static void __init tegra_super_clk_init(void __iomem *clk_base,
gen_info->num_cclk_g_parents,
CLK_SET_RATE_PARENT,
clk_base + CCLKG_BURST_POLICY,
- 0, 4, 8, 0, NULL);
+ TEGRA210_CPU_CLK, 4, 8, 0, NULL);
} else {
clk = tegra_clk_register_super_mux("cclk_g",
gen_info->cclk_g_parents,
diff --git a/drivers/clk/tegra/clk.c b/drivers/clk/tegra/clk.c
index 573e3c967ae1..eb08047fd02f 100644
--- a/drivers/clk/tegra/clk.c
+++ b/drivers/clk/tegra/clk.c
@@ -23,6 +23,7 @@
#define CLK_OUT_ENB_W 0x364
#define CLK_OUT_ENB_X 0x280
#define CLK_OUT_ENB_Y 0x298
+#define CLK_ENB_PLLP_OUT_CPU BIT(31)
#define CLK_OUT_ENB_SET_L 0x320
#define CLK_OUT_ENB_CLR_L 0x324
#define CLK_OUT_ENB_SET_H 0x328
@@ -199,6 +200,19 @@ const struct tegra_clk_periph_regs *get_reg_bank(int clkid)
}
}
+void tegra_clk_set_pllp_out_cpu(bool enable)
+{
+ u32 val;
+
+ val = readl_relaxed(clk_base + CLK_OUT_ENB_Y);
+ if (enable)
+ val |= CLK_ENB_PLLP_OUT_CPU;
+ else
+ val &= ~CLK_ENB_PLLP_OUT_CPU;
+
+ writel_relaxed(val, clk_base + CLK_OUT_ENB_Y);
+}
+
struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks)
{
clk_base = regs;
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index d61e61eebf4a..f8de447f505b 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -687,6 +687,9 @@ struct clk *tegra_clk_register_periph_data(void __iomem *clk_base,
* Flags:
* TEGRA_DIVIDER_2 - LP cluster has additional divider. This flag indicates
* that this is LP cluster clock.
+ * TEGRA210_CPU_CLK - This flag indicates this is CPU cluster clock. To use
+ * PLLP for CPU clock source, need to enable PLLP branches to CPU by setting
+ * additional bit PLLP_OUT_CPU for gen5 super clock.
*/
struct tegra_clk_super_mux {
struct clk_hw hw;
@@ -703,6 +706,7 @@ struct tegra_clk_super_mux {
#define to_clk_super_mux(_hw) container_of(_hw, struct tegra_clk_super_mux, hw)
#define TEGRA_DIVIDER_2 BIT(0)
+#define TEGRA210_CPU_CLK BIT(1)
extern const struct clk_ops tegra_clk_super_ops;
struct clk *tegra_clk_register_super_mux(const char *name,
@@ -849,6 +853,7 @@ int tegra_pll_p_div_to_hw(struct tegra_clk_pll *pll, u8 p_div);
int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
u8 frac_width, u8 flags);
void tegra_clk_osc_resume(void __iomem *clk_base);
+void tegra_clk_set_pllp_out_cpu(bool enable);
/* Combined read fence with delay */
--
2.7.4
^ permalink raw reply related
* [PATCH v7 09/20] clk: tegra: clk-super: Add save and restore support
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
In-Reply-To: <1564532424-10449-1-git-send-email-skomatineni@nvidia.com>
This patch implements save and restore context for clk_super_mux
and clk_super.
During system supend, core power goes off the and context of Tegra
CAR registers is lost.
So during suspend entry, context of super clock registers are saved
through save_context clk_ops and are restored through restore_context
clk_ops to have them in same state as before suspend.
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-super.c | 39 +++++++++++++++++++++++++++++++++++++++
drivers/clk/tegra/clk.h | 1 +
2 files changed, 40 insertions(+)
diff --git a/drivers/clk/tegra/clk-super.c b/drivers/clk/tegra/clk-super.c
index e2a1e95a8db7..be0551cb5587 100644
--- a/drivers/clk/tegra/clk-super.c
+++ b/drivers/clk/tegra/clk-super.c
@@ -124,9 +124,27 @@ static int clk_super_set_parent(struct clk_hw *hw, u8 index)
return err;
}
+static int clk_super_mux_save_context(struct clk_hw *hw)
+{
+ struct tegra_clk_super_mux *mux = to_clk_super_mux(hw);
+
+ mux->parent_index_ctx = clk_super_get_parent(hw);
+
+ return 0;
+}
+
+static void clk_super_mux_restore_context(struct clk_hw *hw)
+{
+ struct tegra_clk_super_mux *mux = to_clk_super_mux(hw);
+
+ clk_super_set_parent(hw, mux->parent_index_ctx);
+}
+
static const struct clk_ops tegra_clk_super_mux_ops = {
.get_parent = clk_super_get_parent,
.set_parent = clk_super_set_parent,
+ .save_context = clk_super_mux_save_context,
+ .restore_context = clk_super_mux_restore_context,
};
static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate,
@@ -162,12 +180,33 @@ static int clk_super_set_rate(struct clk_hw *hw, unsigned long rate,
return super->div_ops->set_rate(div_hw, rate, parent_rate);
}
+static int clk_super_save_context(struct clk_hw *hw)
+{
+ struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
+
+ super->parent_index_ctx = clk_super_get_parent(hw);
+
+ return 0;
+}
+
+static void clk_super_restore_context(struct clk_hw *hw)
+{
+ struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
+ struct clk_hw *div_hw = &super->frac_div.hw;
+
+ clk_super_set_parent(hw, super->parent_index_ctx);
+
+ super->div_ops->restore_context(div_hw);
+}
+
const struct clk_ops tegra_clk_super_ops = {
.get_parent = clk_super_get_parent,
.set_parent = clk_super_set_parent,
.set_rate = clk_super_set_rate,
.round_rate = clk_super_round_rate,
.recalc_rate = clk_super_recalc_rate,
+ .save_context = clk_super_save_context,
+ .restore_context = clk_super_restore_context,
};
struct clk *tegra_clk_register_super_mux(const char *name,
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index f8de447f505b..d397dda7c6d0 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -701,6 +701,7 @@ struct tegra_clk_super_mux {
u8 div2_index;
u8 pllx_index;
spinlock_t *lock;
+ u8 parent_index_ctx;
};
#define to_clk_super_mux(_hw) container_of(_hw, struct tegra_clk_super_mux, hw)
--
2.7.4
^ permalink raw reply related
* [PATCH v7 10/20] clk: tegra: clk-dfll: Add suspend and resume support
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
In-Reply-To: <1564532424-10449-1-git-send-email-skomatineni@nvidia.com>
This patch implements DFLL suspend and resume operation.
During system suspend entry, CPU clock will switch CPU to safe
clock source of PLLP and disables DFLL clock output.
DFLL driver suspend confirms DFLL disable state and errors out on
being active.
DFLL is re-initialized during the DFLL driver resume as it goes
through complete reset during suspend entry.
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-dfll.c | 56 ++++++++++++++++++++++++++++++
drivers/clk/tegra/clk-dfll.h | 2 ++
drivers/clk/tegra/clk-tegra124-dfll-fcpu.c | 1 +
3 files changed, 59 insertions(+)
diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c
index f8688c2ddf1a..9900097ec2aa 100644
--- a/drivers/clk/tegra/clk-dfll.c
+++ b/drivers/clk/tegra/clk-dfll.c
@@ -1513,6 +1513,62 @@ static int dfll_init(struct tegra_dfll *td)
return ret;
}
+/**
+ * tegra_dfll_suspend - check DFLL is disabled
+ * @dev: DFLL device *
+ *
+ * DFLL clock should be disabled by the CPUFreq driver. So, make
+ * sure it is disabled and disable all clocks needed by the DFLL.
+ */
+int tegra_dfll_suspend(struct device *dev)
+{
+ struct tegra_dfll *td = dev_get_drvdata(dev);
+
+ if (dfll_is_running(td)) {
+ dev_err(td->dev, "dfll is enabled while shouldn't be\n");
+ return -EBUSY;
+ }
+
+ reset_control_assert(td->dvco_rst);
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_dfll_suspend);
+
+/**
+ * tegra_dfll_resume - reinitialize DFLL on resume
+ * @dev: DFLL instance
+ *
+ * DFLL is disabled and reset during suspend and resume.
+ * So, reinitialize the DFLL IP block back for use.
+ * DFLL clock is enabled later in closed loop mode by CPUFreq
+ * driver before switching its clock source to DFLL output.
+ */
+int tegra_dfll_resume(struct device *dev)
+{
+ struct tegra_dfll *td = dev_get_drvdata(dev);
+
+ reset_control_deassert(td->dvco_rst);
+
+ pm_runtime_irq_safe(td->dev);
+ pm_runtime_get_sync(td->dev);
+
+ dfll_set_mode(td, DFLL_DISABLED);
+ dfll_set_default_params(td);
+
+ if (td->soc->init_clock_trimmers)
+ td->soc->init_clock_trimmers();
+
+ dfll_set_open_loop_config(td);
+
+ dfll_init_out_if(td);
+
+ pm_runtime_put_sync(td->dev);
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_dfll_resume);
+
/*
* DT data fetch
*/
diff --git a/drivers/clk/tegra/clk-dfll.h b/drivers/clk/tegra/clk-dfll.h
index 1b14ebe7268b..fb209eb5f365 100644
--- a/drivers/clk/tegra/clk-dfll.h
+++ b/drivers/clk/tegra/clk-dfll.h
@@ -42,5 +42,7 @@ int tegra_dfll_register(struct platform_device *pdev,
struct tegra_dfll_soc_data *tegra_dfll_unregister(struct platform_device *pdev);
int tegra_dfll_runtime_suspend(struct device *dev);
int tegra_dfll_runtime_resume(struct device *dev);
+int tegra_dfll_suspend(struct device *dev);
+int tegra_dfll_resume(struct device *dev);
#endif /* __DRIVERS_CLK_TEGRA_CLK_DFLL_H */
diff --git a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
index e84b6d52cbbd..2ac2679d696d 100644
--- a/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
+++ b/drivers/clk/tegra/clk-tegra124-dfll-fcpu.c
@@ -631,6 +631,7 @@ static int tegra124_dfll_fcpu_remove(struct platform_device *pdev)
static const struct dev_pm_ops tegra124_dfll_pm_ops = {
SET_RUNTIME_PM_OPS(tegra_dfll_runtime_suspend,
tegra_dfll_runtime_resume, NULL)
+ SET_SYSTEM_SLEEP_PM_OPS(tegra_dfll_suspend, tegra_dfll_resume)
};
static struct platform_driver tegra124_dfll_fcpu_driver = {
--
2.7.4
^ permalink raw reply related
* [PATCH v7 11/20] cpufreq: tegra124: Add suspend and resume support
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
In-Reply-To: <1564532424-10449-1-git-send-email-skomatineni@nvidia.com>
This patch adds suspend and resume pm ops for cpufreq driver.
PLLP is the safe clock source for CPU during system suspend and
resume as PLLP rate is below the CPU Fmax at Vmin.
CPUFreq driver suspend switches the CPU clock source to PLLP and
disables the DFLL clock.
During system resume, warmboot code powers up the CPU with PLLP
clock source. So CPUFreq driver resume enabled DFLL clock and
switches CPU back to DFLL clock source.
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/cpufreq/tegra124-cpufreq.c | 60 ++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/drivers/cpufreq/tegra124-cpufreq.c b/drivers/cpufreq/tegra124-cpufreq.c
index 4f0c637b3b49..e979a3370988 100644
--- a/drivers/cpufreq/tegra124-cpufreq.c
+++ b/drivers/cpufreq/tegra124-cpufreq.c
@@ -6,6 +6,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/clk.h>
+#include <linux/cpufreq.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
@@ -128,8 +129,67 @@ static int tegra124_cpufreq_probe(struct platform_device *pdev)
return ret;
}
+static int __maybe_unused tegra124_cpufreq_suspend(struct device *dev)
+{
+ struct tegra124_cpufreq_priv *priv = dev_get_drvdata(dev);
+ int err;
+
+ /*
+ * PLLP rate 408Mhz is below the CPU Fmax at Vmin and is safe to
+ * use during suspend and resume. So, switch the CPU clock source
+ * to PLLP and disable DFLL.
+ */
+ err = clk_set_parent(priv->cpu_clk, priv->pllp_clk);
+ if (err < 0) {
+ dev_err(dev, "failed to reparent to PLLP: %d\n", err);
+ return err;
+ }
+
+ /* disable DFLL clock */
+ clk_disable_unprepare(priv->dfll_clk);
+
+ return 0;
+}
+
+static int __maybe_unused tegra124_cpufreq_resume(struct device *dev)
+{
+ struct tegra124_cpufreq_priv *priv = dev_get_drvdata(dev);
+ int err;
+
+ /*
+ * Warmboot code powers up the CPU with PLLP clock source.
+ * Enable DFLL clock and switch CPU clock source back to DFLL.
+ */
+ err = clk_prepare_enable(priv->dfll_clk);
+ if (err < 0) {
+ dev_err(dev, "failed to enable DFLL clock for CPU: %d\n", err);
+ goto disable_cpufreq;
+ }
+
+ err = clk_set_parent(priv->cpu_clk, priv->dfll_clk);
+ if (err < 0) {
+ dev_err(dev, "failed to reparent to DFLL clock: %d\n", err);
+ goto disable_dfll;
+ }
+
+ return 0;
+
+disable_dfll:
+ clk_disable_unprepare(priv->dfll_clk);
+disable_cpufreq:
+ disable_cpufreq();
+
+ return err;
+}
+
+static const struct dev_pm_ops tegra124_cpufreq_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(tegra124_cpufreq_suspend,
+ tegra124_cpufreq_resume)
+};
+
static struct platform_driver tegra124_cpufreq_platdrv = {
.driver.name = "cpufreq-tegra124",
+ .driver.pm = &tegra124_cpufreq_pm_ops,
.probe = tegra124_cpufreq_probe,
};
--
2.7.4
^ permalink raw reply related
* [PATCH v7 12/20] clk: tegra210: Use fence_udelay during PLLU init
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
In-Reply-To: <1564532424-10449-1-git-send-email-skomatineni@nvidia.com>
This patch uses fence_udelay rather than udelay during PLLU
initialization to ensure writes to clock registers happens before
waiting for specified delay.
Acked-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-tegra210.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index 4721ee030d1c..998bf60b219a 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -2841,7 +2841,7 @@ static int tegra210_enable_pllu(void)
reg = readl_relaxed(clk_base + pllu.params->ext_misc_reg[0]);
reg &= ~BIT(pllu.params->iddq_bit_idx);
writel_relaxed(reg, clk_base + pllu.params->ext_misc_reg[0]);
- udelay(5);
+ fence_udelay(5, clk_base);
reg = readl_relaxed(clk_base + PLLU_BASE);
reg &= ~GENMASK(20, 0);
@@ -2849,7 +2849,7 @@ static int tegra210_enable_pllu(void)
reg |= fentry->n << 8;
reg |= fentry->p << 16;
writel(reg, clk_base + PLLU_BASE);
- udelay(1);
+ fence_udelay(1, clk_base);
reg |= PLL_ENABLE;
writel(reg, clk_base + PLLU_BASE);
@@ -2895,12 +2895,12 @@ static int tegra210_init_pllu(void)
reg = readl_relaxed(clk_base + XUSB_PLL_CFG0);
reg &= ~XUSB_PLL_CFG0_PLLU_LOCK_DLY_MASK;
writel_relaxed(reg, clk_base + XUSB_PLL_CFG0);
- udelay(1);
+ fence_udelay(1, clk_base);
reg = readl_relaxed(clk_base + PLLU_HW_PWRDN_CFG0);
reg |= PLLU_HW_PWRDN_CFG0_SEQ_ENABLE;
writel_relaxed(reg, clk_base + PLLU_HW_PWRDN_CFG0);
- udelay(1);
+ fence_udelay(1, clk_base);
reg = readl_relaxed(clk_base + PLLU_BASE);
reg &= ~PLLU_BASE_CLKENABLE_USB;
--
2.7.4
^ permalink raw reply related
* [PATCH v7 13/20] clk: tegra210: Add suspend and resume support
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
In-Reply-To: <1564532424-10449-1-git-send-email-skomatineni@nvidia.com>
This patch adds support for clk: tegra210: suspend-resume.
All the CAR controller settings are lost on suspend when core
power goes off.
This patch has implementation for saving and restoring all PLLs
and clocks context during system suspend and resume to have the
clocks back to same state for normal operation.
Clock driver suspend and resume are registered as syscore_ops as clocks
restore need to happen before the other drivers resume to have all their
clocks back to the same state as before suspend.
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/clk/tegra/clk-tegra210.c | 75 +++++++++++++++++++++++++++++++++++++---
1 file changed, 71 insertions(+), 4 deletions(-)
diff --git a/drivers/clk/tegra/clk-tegra210.c b/drivers/clk/tegra/clk-tegra210.c
index 998bf60b219a..14ea9f373a84 100644
--- a/drivers/clk/tegra/clk-tegra210.c
+++ b/drivers/clk/tegra/clk-tegra210.c
@@ -9,13 +9,13 @@
#include <linux/clkdev.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/syscore_ops.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/mutex.h>
#include <linux/clk/tegra.h>
#include <dt-bindings/clock/tegra210-car.h>
#include <dt-bindings/reset/tegra210-car.h>
-#include <linux/iopoll.h>
#include <linux/sizes.h>
#include <soc/tegra/pmc.h>
@@ -220,11 +220,15 @@
#define CLK_M_DIVISOR_SHIFT 2
#define CLK_M_DIVISOR_MASK 0x3
+#define CLK_MASK_ARM 0x44
+#define MISC_CLK_ENB 0x48
+
#define RST_DFLL_DVCO 0x2f4
#define DVFS_DFLL_RESET_SHIFT 0
#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
+#define CPU_SOFTRST_CTRL 0x380
#define LVL2_CLK_GATE_OVRA 0xf8
#define LVL2_CLK_GATE_OVRC 0x3a0
@@ -2825,6 +2829,7 @@ static int tegra210_enable_pllu(void)
struct tegra_clk_pll_freq_table *fentry;
struct tegra_clk_pll pllu;
u32 reg;
+ int ret;
for (fentry = pll_u_freq_table; fentry->input_rate; fentry++) {
if (fentry->input_rate == pll_ref_freq)
@@ -2853,9 +2858,14 @@ static int tegra210_enable_pllu(void)
reg |= PLL_ENABLE;
writel(reg, clk_base + PLLU_BASE);
- readl_relaxed_poll_timeout_atomic(clk_base + PLLU_BASE, reg,
- reg & PLL_BASE_LOCK, 2, 1000);
- if (!(reg & PLL_BASE_LOCK)) {
+ /*
+ * During clock resume syscore operation, same PLLU init and enable
+ * routines gets invoked. So, readx_poll_timeout_atomic can't be used
+ * here as it uses ktime_get() and timekeeping resume doesn't happen
+ * by that time. So, using tegra210_wait_for_mask for PLL LOCK.
+ */
+ ret = tegra210_wait_for_mask(&pllu, PLLU_BASE, PLL_BASE_LOCK);
+ if (ret) {
pr_err("Timed out waiting for PLL_U to lock\n");
return -ETIMEDOUT;
}
@@ -3288,6 +3298,56 @@ static void tegra210_disable_cpu_clock(u32 cpu)
}
#ifdef CONFIG_PM_SLEEP
+#define car_readl(_base, _off) readl_relaxed(clk_base + (_base) + ((_off) * 4))
+#define car_writel(_val, _base, _off) \
+ writel_relaxed(_val, clk_base + (_base) + ((_off) * 4))
+
+static u32 spare_reg_ctx, misc_clk_enb_ctx, clk_msk_arm_ctx;
+static u32 cpu_softrst_ctx[3];
+
+static int tegra210_clk_suspend(void)
+{
+ unsigned int i;
+
+ clk_save_context();
+
+ /*
+ * Save the bootloader configured clock registers SPARE_REG0,
+ * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL.
+ */
+ spare_reg_ctx = readl_relaxed(clk_base + SPARE_REG0);
+ misc_clk_enb_ctx = readl_relaxed(clk_base + MISC_CLK_ENB);
+ clk_msk_arm_ctx = readl_relaxed(clk_base + CLK_MASK_ARM);
+
+ for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++)
+ cpu_softrst_ctx[i] = car_readl(CPU_SOFTRST_CTRL, i);
+
+ return 0;
+}
+
+static void tegra210_clk_resume(void)
+{
+ unsigned int i;
+
+ tegra_clk_osc_resume(clk_base);
+
+ /*
+ * Restore the bootloader configured clock registers SPARE_REG0,
+ * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL from saved context.
+ */
+ writel_relaxed(spare_reg_ctx, clk_base + SPARE_REG0);
+ writel_relaxed(misc_clk_enb_ctx, clk_base + MISC_CLK_ENB);
+ writel_relaxed(clk_msk_arm_ctx, clk_base + CLK_MASK_ARM);
+
+ for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++)
+ car_writel(cpu_softrst_ctx[i], CPU_SOFTRST_CTRL, i);
+
+ fence_udelay(5, clk_base);
+
+ tegra210_init_pllu();
+ clk_restore_context();
+}
+
static void tegra210_cpu_clock_suspend(void)
{
/* switch coresite to clk_m, save off original source */
@@ -3303,6 +3363,11 @@ static void tegra210_cpu_clock_resume(void)
}
#endif
+static struct syscore_ops tegra_clk_syscore_ops = {
+ .suspend = tegra210_clk_suspend,
+ .resume = tegra210_clk_resume,
+};
+
static struct tegra_cpu_car_ops tegra210_cpu_car_ops = {
.wait_for_reset = tegra210_wait_cpu_in_reset,
.disable_clock = tegra210_disable_cpu_clock,
@@ -3587,5 +3652,7 @@ static void __init tegra210_clock_init(struct device_node *np)
tegra210_mbist_clk_init();
tegra_cpu_car_ops = &tegra210_cpu_car_ops;
+
+ register_syscore_ops(&tegra_clk_syscore_ops);
}
CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init);
--
2.7.4
^ permalink raw reply related
* [PATCH v7 14/20] soc/tegra: pmc: Allow to support more tegras wake
From: Sowjanya Komatineni @ 2019-07-31 0:20 UTC (permalink / raw)
To: thierry.reding, jonathanh, tglx, jason, marc.zyngier,
linus.walleij, stefan, mark.rutland
Cc: pdeschrijver, pgaikwad, sboyd, linux-clk, linux-gpio, jckuo,
josephl, talho, skomatineni, linux-tegra, linux-kernel,
mperttunen, spatra, robh+dt, digetx, devicetree
In-Reply-To: <1564532424-10449-1-git-send-email-skomatineni@nvidia.com>
This patch allows to create separate irq_set_wake and irq_set_type
implementations for different tegra designs PMC that has different
wake models which require difference wake registers and different
programming sequence.
AOWAKE model support is available for Tegra186 and Tegra194 only
and it resides within PMC and supports tiered wake architecture.
Tegra210 and prior tegra designs uses PMC directly to receive wake
events and coordinate the wake sequence.
Signed-off-by: Sowjanya Komatineni <skomatineni@nvidia.com>
---
drivers/soc/tegra/pmc.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c
index 9f9c1c677cf4..91c84d0e66ae 100644
--- a/drivers/soc/tegra/pmc.c
+++ b/drivers/soc/tegra/pmc.c
@@ -226,6 +226,8 @@ struct tegra_pmc_soc {
void (*setup_irq_polarity)(struct tegra_pmc *pmc,
struct device_node *np,
bool invert);
+ int (*irq_set_wake)(struct irq_data *data, unsigned int on);
+ int (*irq_set_type)(struct irq_data *data, unsigned int type);
const char * const *reset_sources;
unsigned int num_reset_sources;
@@ -1920,7 +1922,7 @@ static const struct irq_domain_ops tegra_pmc_irq_domain_ops = {
.alloc = tegra_pmc_irq_alloc,
};
-static int tegra_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
+static int tegra186_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
{
struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
unsigned int offset, bit;
@@ -1952,7 +1954,7 @@ static int tegra_pmc_irq_set_wake(struct irq_data *data, unsigned int on)
return 0;
}
-static int tegra_pmc_irq_set_type(struct irq_data *data, unsigned int type)
+static int tegra186_pmc_irq_set_type(struct irq_data *data, unsigned int type)
{
struct tegra_pmc *pmc = irq_data_get_irq_chip_data(data);
u32 value;
@@ -2006,8 +2008,8 @@ static int tegra_pmc_irq_init(struct tegra_pmc *pmc)
pmc->irq.irq_unmask = irq_chip_unmask_parent;
pmc->irq.irq_eoi = irq_chip_eoi_parent;
pmc->irq.irq_set_affinity = irq_chip_set_affinity_parent;
- pmc->irq.irq_set_type = tegra_pmc_irq_set_type;
- pmc->irq.irq_set_wake = tegra_pmc_irq_set_wake;
+ pmc->irq.irq_set_type = pmc->soc->irq_set_type;
+ pmc->irq.irq_set_wake = pmc->soc->irq_set_wake;
pmc->domain = irq_domain_add_hierarchy(parent, 0, 96, pmc->dev->of_node,
&tegra_pmc_irq_domain_ops, pmc);
@@ -2680,6 +2682,8 @@ static const struct tegra_pmc_soc tegra186_pmc_soc = {
.regs = &tegra186_pmc_regs,
.init = NULL,
.setup_irq_polarity = tegra186_pmc_setup_irq_polarity,
+ .irq_set_wake = tegra186_pmc_irq_set_wake,
+ .irq_set_type = tegra186_pmc_irq_set_type,
.reset_sources = tegra186_reset_sources,
.num_reset_sources = ARRAY_SIZE(tegra186_reset_sources),
.reset_levels = tegra186_reset_levels,
--
2.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox