* Re: [PATCH v2 2/2] clk: hisilicon: Add clock driver for hi3660 SoC
From: zhangfei @ 2017-01-10 1:22 UTC (permalink / raw)
To: Stephen Boyd
Cc: Rob Herring, Arnd Bergmann, haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A,
guodong Xu, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170110002224.GH17126-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
On 2017年01月10日 08:22, Stephen Boyd wrote:
> On 12/29, Zhangfei Gao wrote:
>> Add clock drivers for hi3660 SoC, this driver controls the SoC
>> registers to supply different clocks to different IPs in the SoC.
>>
>> Signed-off-by: Zhangfei Gao <zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>> ---
> Applied to clk-hi3660 and merged into clk-next. I took the
> liberty of using a function pointer in probe though so we don't
> need the enum anymore.
Good idea. It is simplified a lot.
Have verified on hikey960.
Thanks Stephen for the help.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 2/3] arm64: dts: sun50i: add UART1 pin nodes
From: Andre Przywara @ 2017-01-10 1:22 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai
Cc: Rob Herring, Mark Rutland,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1484011353-21480-1-git-send-email-andre.przywara-5wv7dgnIgG8@public.gmane.org>
On many boards UART1 connects to a Bluetooth chip, so add the pinctrl
nodes for the only pins providing access to that UART. That includes
those pins for hardware flow control (RTS/CTS).
Signed-off-by: Andre Przywara <andre.przywara-5wv7dgnIgG8@public.gmane.org>
---
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
index f46ae96..419b0b1 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
@@ -234,6 +234,16 @@
pins = "PB8", "PB9";
function = "uart0";
};
+
+ uart1_pins: uart1_pins {
+ pins = "PG6", "PG7";
+ function = "uart1";
+ };
+
+ uart1_rts_cts_pins: uart1_rts_cts_pins {
+ pins = "PG8", "PG9";
+ function = "uart1";
+ };
};
uart0: serial@1c28000 {
--
2.8.2
^ permalink raw reply related
* [PATCH 1/3] arm64: dts: Pine64: add MMC support
From: Andre Przywara @ 2017-01-10 1:22 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai
Cc: Rob Herring, Mark Rutland,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1484011353-21480-1-git-send-email-andre.przywara-5wv7dgnIgG8@public.gmane.org>
All Pine64 boards connect an micro-SD card slot to the first MMC
controller.
Enable the respective DT node and specify the (always-on) regulator
and card-detect pin.
As a micro-SD slot does not feature a write-protect switch, we disable
this feature.
Signed-off-by: Andre Przywara <andre.przywara-5wv7dgnIgG8@public.gmane.org>
---
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
index cf91051..c680ed3 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
@@ -44,6 +44,8 @@
#include "sun50i-a64.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
/ {
model = "Pine64";
compatible = "pine64,pine64", "allwinner,sun50i-a64";
@@ -55,6 +57,13 @@
chosen {
stdout-path = "serial0:115200n8";
};
+
+ reg_vcc3v3: vcc3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "vcc3v3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
};
&ehci1 {
@@ -71,6 +80,17 @@
bias-pull-up;
};
+&mmc0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>;
+ vmmc-supply = <®_vcc3v3>;
+ cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+ disable-wp;
+ bus-width = <4>;
+ status = "okay";
+};
+
&ohci1 {
status = "okay";
};
--
2.8.2
^ permalink raw reply related
* [PATCH 0/3] arm64: dts: A64 board MMC support
From: Andre Przywara @ 2017-01-10 1:22 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai
Cc: Rob Herring, Mark Rutland,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
These patches here go on top of Maxime's latest A64 MMC series and
enable the MMC controllers on the boards using the A64 SoC.
As the BananaPi-M64 DT now looks different, lets adds support for
that board as well, with one major difference to the Pine64 being the eMMC
chip.
I could't find commit f9ca9b952ee1 Maxime mentioned in his cover letter,
so I applied his patches on top of sunxi/for-next and cherry-picked
b4b8664d29 to fix the arm64 build.
Cheers,
Andre.
Andre Przywara (3):
arm64: dts: Pine64: add MMC support
arm64: dts: sun50i: add UART1 pin nodes
arm64: dts: add BananaPi-M64 support
arch/arm64/boot/dts/allwinner/Makefile | 1 +
.../boot/dts/allwinner/sun50i-a64-bananapi-m64.dts | 120 +++++++++++++++++++++
.../arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 20 ++++
arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 10 ++
4 files changed, 151 insertions(+)
create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
--
2.8.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v7 3/4] drm/panel: Add support for S6E3HA2 panel driver on TM2 board
From: Inki Dae @ 2017-01-10 1:15 UTC (permalink / raw)
To: Andrzej Hajda, Andi Shyti
Cc: Hoegeun Kwon, robh, thierry.reding, airlied, kgene, krzk,
dri-devel, linux-kernel, devicetree, linux-samsung-soc, cw00.choi,
jh80.chung, Donghwa Lee, Hyungwon Hwang
In-Reply-To: <aeab26bc-76a8-0b4d-b5b9-b8602fcf2eb3@samsung.com>
2017년 01월 09일 18:53에 Andrzej Hajda 이(가) 쓴 글:
> On 09.01.2017 10:19, Inki Dae wrote:
>>
>> 2017년 01월 09일 16:37에 Andrzej Hajda 이(가) 쓴 글:
>>> On 06.01.2017 09:36, Inki Dae wrote:
>>>> 2017년 01월 06일 17:18에 Andi Shyti 이(가) 쓴 글:
>>>>> Hi Inki,
>>>>>
>>>>> Thanks for the reply, but...
>>>>>
>>>>>>>> +static const struct drm_display_mode default_mode = {
>>>>>>>> + .clock = 222372,
>>>>>>>> + .hdisplay = 1440,
>>>>>>>> + .hsync_start = 1440 + 1,
>>>>>>>> + .hsync_end = 1440 + 1 + 1,
>>>>>>>> + .htotal = 1440 + 1 + 1 + 1,
>>>>>>>> + .vdisplay = 2560,
>>>>>>>> + .vsync_start = 2560 + 1,
>>>>>>>> + .vsync_end = 2560 + 1 + 1,
>>>>>>>> + .vtotal = 2560 + 1 + 1 + 15,
>>>>>>>> + .vrefresh = 60,
>>>>>>>> + .flags = 0,
>>>>>>>> +};
>>>>>>> how is this working with tm2e? Are these values valid for both
>>>>>>> the boards?
>>>>>> We don't need to consider tm2e board with two reasones,
>>>>>> 1. there is no tm2e board support in mainline
>>>>>> 2. the panel on tm2 would be a little bit different from one on tm2e
>>>>> ... this display in the Tizen Kernel is supported by both:
>>>>> tm2 [1] and tm2e [2]. The only differences are:
>>>> Why tm2e dts file is in mainline? Seems communication miss with Chanwoo. :(
>>>>
>>>>> TM2:
>>>>> clock-frequency = <14874444>;
>>>>> hactive = <1440>;
>>>>>
>>>>> TM2E:
>>>>> clock-frequency = <16523724>;
>>>>> hactive = <1600>;
>>>>>
>>>>> I don't know much about the differences you mention in point 2,
>>>>> but it's a pity to drop support only because we don't want to put
>>>>> in the dts the 'hactive', and 'clock-frequency' properties.
>>>> Anyway, tm2e board is already in mainline so Panel driver may need to identify what kinds of panel is probed to decide porch values. I think there are relevant registers in MCU of the Panel device to check version or similar thing.
>>> I think we can safely use different compatible string for tm2e - it uses
>>> different display IC controller - s6e3hf2, driver will provide timings
>>> based on it.
>> Using compatable string wouldn't be a good idea because Panel is a device not specific to board.
>
> But both panels are different devices:
> TM2 has: AMS567DJ01 panel on S6E3HA2 interface (called LDI/IC)
> TM2E has AMB559DE01 panel on S6E3HF2 interface (called LDI/IC)
>
> Why assigning different compatibles to different devices is not a good idea?
Oops, I didn't know that these two panels are different so I thought using different compatiable string for same panel device is not good idea.
This panel driver is no problem as-is. For tm2e board, it can be considered with a separated patch later.
For this, these two boards have different MCU modules but just a little bit different so we could do either just adding compatible string to tm2e dts file and panel driver - maybe not reasonable due to different hardware name - or creating new panel driver even though source code is duplicated.
Thanks.
>
>>
>>> As far as I examined available specs/docs there is no reliable register
>>> which can be used to safely distinguish it on runtime, but the docs I
>>> have are far from completeness.
>> The data sheet I am seeing says a RDDIDS register describes manufacturer and module version information. With this we could identify the Panel device.
>> Of course, we may need to check the register has really different values according to board.
>>
>> Below is the version information Hoegeun checked,
>>
>> TM2
>> [ 4.908666] panel_s6e3ha2 13900000.dsi.0: Manufacture date: 2014-10-31 06:41
>> [ 5.035768] panel_s6e3ha2 13900000.dsi.0: Id: 50 20 09
>>
>> TM2e
>> [ 4.929265] panel_s6e3ha2 13900000.dsi.0: Manufacture date: 2014-09-03 06:30
>> [ 5.056287] panel_s6e3ha2 13900000.dsi.0: Id: 40 40 14
>
> There is description of ID1, ID2, ID3 registers in specs of both panels,
> I see no reliable bits to distinguish panels.
> And relying on read values of random devices does not seems to me proper
> solution.
>
> Regards
> Andrzej
>
>
>>
>>
>> Thanks.
>>
>>> Regards
>>> Andrzej
>>>
>>>> Thanks.
>>>>
>>>>> Andi
>>>>>
>>>>> [1] https://git.tizen.org/cgit/platform/kernel/linux-exynos/tree/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts?h=tizen#n1284
>>>>> [2] https://git.tizen.org/cgit/platform/kernel/linux-exynos/tree/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts?h=tizen#n1270
>>>>> --
>>>>> To unsubscribe from this list: send the line "unsubscribe devicetree" in
>>>>> the body of a message to majordomo@vger.kernel.org
>>>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>>>>
>>>>> .
>>>>>
>>> --
>>> To unsubscribe from this list: send the line "unsubscribe devicetree" in
>>> the body of a message to majordomo@vger.kernel.org
>>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>>>
>>>
>>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
^ permalink raw reply
* Re: [PATCH v2] arm64: dts: rockchip: add "rockchip,grf" property for RK3399 PMUCRU/CRU
From: Xing Zheng @ 2017-01-10 0:57 UTC (permalink / raw)
To: Doug Anderson
Cc: Heiko Stübner, open list:ARM/Rockchip SoC..., Rob Herring,
Mark Rutland, Catalin Marinas, Will Deacon, Caesar Wang,
Brian Norris, Shawn Lin, Jianqun Xu, Elaine Zhang, David Wu,
William wu, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
In-Reply-To: <CAD=FV=WjzU_2QSLET3Y9_5A5khXjqMYNzB2ifextKhekmvCsjw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Hi Doug,
在 2017年01月10日 02:52, Doug Anderson 写道:
> This looks sane to me, but before you land it you need to first send
> up a (separate) patch that adjusts:
>
> Documentation/devicetree/bindings/clock/rockchip,rk3399-cru.txt
>
> ...it would also be sorta nice if you included an a patch in your
> series that actually uses this new functionality.
Sorry to miss it. Thanks for your reminding me.
--
- Xing Zheng
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 5/6] arm64: allwinner: a64: Add MMC pinctrl nodes
From: André Przywara @ 2017-01-10 0:54 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai, Ulf Hansson
Cc: Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
linux-mmc
In-Reply-To: <f7a004f7905badbd8e6fea7fd8591a498b396b9d.1483980339.git-series.maxime.ripard@free-electrons.com>
On 09/01/17 16:46, Maxime Ripard wrote:
> The A64 only has a single set of pins for each MMC controller. Since we
> already have boards that require all of them, let's add them to the DTSI.
This matches my reworked version from the previous series, so:
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
Cheers,
Andre.
>
> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
> ---
> arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 25 ++++++++++++++++++++-
> 1 file changed, 25 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> index 143e9706438f..8e149498e096 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi
> @@ -205,6 +205,31 @@
> function = "i2c1";
> };
>
> + mmc0_pins: mmc0-pins {
> + pins = "PF0", "PF1", "PF2", "PF3",
> + "PF4", "PF5";
> + function = "mmc0";
> + drive-strength = <30>;
> + bias-pull-up;
> + };
> +
> + mmc1_pins: mmc1-pins {
> + pins = "PG0", "PG1", "PG2", "PG3",
> + "PG4", "PG5";
> + function = "mmc1";
> + drive-strength = <30>;
> + bias-pull-up;
> + };
> +
> + mmc2_pins: mmc2-pins {
> + pins = "PC1", "PC5", "PC6", "PC8", "PC9",
> + "PC10","PC11", "PC12", "PC13",
> + "PC14", "PC15", "PC16";
> + function = "mmc2";
> + drive-strength = <30>;
> + bias-pull-up;
> + };
> +
> uart0_pins_a: uart0@0 {
> pins = "PB8", "PB9";
> function = "uart0";
>
^ permalink raw reply
* Re: [PATCH v2] clk: cdce925: add support for CDCE913, CDCE937, and CDCE949
From: Stephen Boyd @ 2017-01-10 0:40 UTC (permalink / raw)
To: Akinobu Mita; +Cc: linux-clk, devicetree, Mike Looijmans, Michael Turquette
In-Reply-To: <1483207476-10920-1-git-send-email-akinobu.mita@gmail.com>
On 01/01, Akinobu Mita wrote:
> The CDCE925 is a member of the CDCE(L)9xx programmable clock generator
> family. There are also CDCE913, CDCE937, CDCE949 which have different
> number of PLLs and outputs.
>
> The clk-cdce925 driver supports only CDCE925 in the family. This adds
> support for the CDCE913, CDCE937, CDCE949, too.
>
> Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
> Acked-by: Rob Herring <robh@kernel.org>
> Cc: Mike Looijmans <mike.looijmans@topic.nl>
> Cc: Michael Turquette <mturquette@linaro.org>
> Cc: Stephen Boyd <sboyd@codeaurora.org>
> ---
Applied to clk-next
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH v2 04/12] driver: clk: imx: Add clock driver for imx6sll
From: Stephen Boyd @ 2017-01-10 0:37 UTC (permalink / raw)
To: Bai Ping
Cc: shawnguo-DgEjT+Ai2ygdnm+yROfE0A,
mturquette-rdvid1DuHRBWk0Htik3J/w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
kernel-bIcnvbaLZ9MEGnE8C9+IrQ, fabio.estevam-3arQi8VN3Tc,
daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A,
tglx-hfZtesqFncYOwBW4kG4KsQ, p.zabel-bIcnvbaLZ9MEGnE8C9+IrQ,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-gpio-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
jacky.baip-Re5JQEeQqe8AvxtiuMwx3w
In-Reply-To: <1482832070-22668-5-git-send-email-ping.bai-3arQi8VN3Tc@public.gmane.org>
On 12/27, Bai Ping wrote:
> diff --git a/drivers/clk/imx/clk-imx6sll.c b/drivers/clk/imx/clk-imx6sll.c
> new file mode 100644
> index 0000000..73758fe1
> --- /dev/null
> +++ b/drivers/clk/imx/clk-imx6sll.c
> @@ -0,0 +1,369 @@
> +/*
> + * Copyright (C) 2016 Freescale Semiconductor, Inc.
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#include <dt-bindings/clock/imx6sll-clock.h>
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
Is this used?
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
Is this used?
> +#include <linux/types.h>
> +
> +#include "clk.h"
> +
> +#define CCM_ANALOG_PLL_BYPASS (0x1 << 16)
> +#define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16)
> +#define CCDR 0x4
> +#define xPLL_CLR(offset) (offset + 0x8)
> +
> +static const char *pll_bypass_src_sels[] = { "osc", "dummy", };
All these should be const char * const unless something is wrong.
> +static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
> +static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
> +static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
> +static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
> +static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
> +static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
[...]
> + clks[IMX6SLL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
> +
> + /* mask handshake of mmdc */
> + writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR);
> +
> + for (i = 0; i < ARRAY_SIZE(clks); i++)
> + if (IS_ERR(clks[i]))
> + pr_err("i.MX6SLL clk %d: register failed with %ld\n", i, PTR_ERR(clks[i]));
> +
> + clk_data.clks = clks;
> + clk_data.clk_num = ARRAY_SIZE(clks);
> + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
> +
> + /* set perclk to from OSC */
> + clk_set_parent(clks[IMX6SLL_CLK_PERCLK_SEL], clks[IMX6SLL_CLK_OSC]);
Can this be done with assigned-clocks in DT?
> +
> + for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
> + clk_prepare_enable(clks[clks_init_on[i]]);
Critical clocks?
> +
> + if (IS_ENABLED(CONFIG_USB_MXS_PHY)) {
> + clk_prepare_enable(clks[IMX6SLL_CLK_USBPHY1_GATE]);
> + clk_prepare_enable(clks[IMX6SLL_CLK_USBPHY2_GATE]);
The phy driver can't enable these?
> + }
> +
> + /* Lower the AHB clock rate before changing the clock source. */
> + clk_set_rate(clks[IMX6SLL_CLK_AHB], 99000000);
> +
> + /* Change periph_pre clock to pll2_bus to adjust AXI rate to 264MHz */
> + clk_set_parent(clks[IMX6SLL_CLK_PERIPH_CLK2_SEL], clks[IMX6SLL_CLK_PLL3_USB_OTG]);
> + clk_set_parent(clks[IMX6SLL_CLK_PERIPH], clks[IMX6SLL_CLK_PERIPH_CLK2]);
> + clk_set_parent(clks[IMX6SLL_CLK_PERIPH_PRE], clks[IMX6SLL_CLK_PLL2_BUS]);
> + clk_set_parent(clks[IMX6SLL_CLK_PERIPH], clks[IMX6SLL_CLK_PERIPH_PRE]);
> +
> + clk_set_rate(clks[IMX6SLL_CLK_AHB], 132000000);
assigned-clocks for rates now? Or perhaps we shouldn't be
exposing these as clks if they have some sort of complicated rate
sequence switch that we can't guarantee with the clk_ops we have
today.
> +}
> +
> +CLK_OF_DECLARE(imx6sll, "fsl,imx6sll-ccm", imx6sll_clocks_init);
> +
Please drop this extra newline.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFC PATCHv2 2/4] clk: mdm9615: Add EBI2 clock
From: Stephen Boyd @ 2017-01-10 0:33 UTC (permalink / raw)
To: Zoran Markovic
Cc: linux-kernel, Andy Gross, David Brown, Michael Turquette,
Rob Herring, Mark Rutland, Neil Armstrong, linux-arm-msm,
linux-soc, linux-clk, devicetree
In-Reply-To: <1482468884-31027-1-git-send-email-zmarkovic@sierrawireless.com>
On 12/22, Zoran Markovic wrote:
> Add definition of EBI2 clock used by MDM9615 NAND controller.
>
> Cc: Andy Gross <andy.gross@linaro.org>
> Cc: David Brown <david.brown@linaro.org>
> Cc: Michael Turquette <mturquette@baylibre.com>
> Cc: Stephen Boyd <sboyd@codeaurora.org>
> Cc: Rob Herring <robh+dt@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Neil Armstrong <narmstrong@baylibre.com>
> Cc: linux-arm-msm@vger.kernel.org
> Cc: linux-soc@vger.kernel.org
> Cc: linux-clk@vger.kernel.org
> Cc: devicetree@vger.kernel.org
> Signed-off-by: Zoran Markovic <zmarkovic@sierrawireless.com>
> ---
Applied to clk-next + fixed halt bit of ebi2_clk to be 24 not 23.
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH v2 1/6] mmc: sunxi: Always set signal delay to 0 for A64
From: André Przywara @ 2017-01-10 0:30 UTC (permalink / raw)
To: Maxime Ripard, Chen-Yu Tsai, Ulf Hansson
Cc: Rob Herring, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <5eff19eec2b110bb643a38e7fef221208f585589.1483980339.git-series.maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
On 09/01/17 16:46, Maxime Ripard wrote:
> Experience have shown that the using the autocalibration could severely
> degrade the performances of the MMC bus.
>
> Allwinner is using in its BSP a delay set to 0 for all the modes but HS400.
> Remove the calibration code for now, and add comments to document our
> findings.
>
> Signed-off-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> ---
> drivers/mmc/host/sunxi-mmc.c | 50 ++++++++++++-------------------------
> 1 file changed, 17 insertions(+), 33 deletions(-)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index b1d1303389a7..ea9552a0d820 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -683,41 +683,19 @@ static int sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en)
>
> static int sunxi_mmc_calibrate(struct sunxi_mmc_host *host, int reg_off)
> {
> - u32 reg = readl(host->reg_base + reg_off);
> - u32 delay;
> - unsigned long timeout;
> -
> if (!host->cfg->can_calibrate)
> return 0;
>
> - reg &= ~(SDXC_CAL_DL_MASK << SDXC_CAL_DL_SW_SHIFT);
> - reg &= ~SDXC_CAL_DL_SW_EN;
> -
> - writel(reg | SDXC_CAL_START, host->reg_base + reg_off);
> -
> - dev_dbg(mmc_dev(host->mmc), "calibration started\n");
> -
> - timeout = jiffies + HZ * SDXC_CAL_TIMEOUT;
> -
> - while (!((reg = readl(host->reg_base + reg_off)) & SDXC_CAL_DONE)) {
> - if (time_before(jiffies, timeout))
> - cpu_relax();
> - else {
> - reg &= ~SDXC_CAL_START;
> - writel(reg, host->reg_base + reg_off);
> -
> - return -ETIMEDOUT;
> - }
> - }
> -
> - delay = (reg >> SDXC_CAL_DL_SHIFT) & SDXC_CAL_DL_MASK;
> -
> - reg &= ~SDXC_CAL_START;
> - reg |= (delay << SDXC_CAL_DL_SW_SHIFT) | SDXC_CAL_DL_SW_EN;
> -
> - writel(reg, host->reg_base + reg_off);
> -
> - dev_dbg(mmc_dev(host->mmc), "calibration ended, reg is 0x%x\n", reg);
> + /*
> + * FIXME:
> + * This is not clear how the calibration is supposed to work
> + * yet. The best rate have been obtained by simply setting the
> + * delay to 0, as Allwinner does in its BSP.
> + *
> + * The only mode that doesn't have such a delay is HS400, that
> + * is in itself a TODO.
> + */
> + writel(SDXC_CAL_DL_SW_EN, host->reg_base + reg_off);
>
> return 0;
> }
> @@ -806,7 +784,13 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *host,
> if (ret)
> return ret;
>
> - /* TODO: enable calibrate on sdc2 SDXC_REG_DS_DL_REG of A64 */
> + /*
> + * FIXME:
> + *
> + * In HS400 we'll also need to calibrate the data strobe
> + * signal. This should only happen on the MMC2 controller (at
> + * least on the A64 and older SoCs).
Which older SoCs have this calibration register and a DS signal?
Is that supposed to mean "other" SoCs?
Other than that:
Reviewed-by: Andre Przywara <andre.przywara-5wv7dgnIgG8@public.gmane.org>
Cheers,
Andre.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 2/2] clk: hisilicon: Add clock driver for hi3660 SoC
From: Stephen Boyd @ 2017-01-10 0:22 UTC (permalink / raw)
To: Zhangfei Gao
Cc: Rob Herring, Arnd Bergmann, haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A,
guodong Xu, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1482978805-6981-3-git-send-email-zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
On 12/29, Zhangfei Gao wrote:
> Add clock drivers for hi3660 SoC, this driver controls the SoC
> registers to supply different clocks to different IPs in the SoC.
>
> Signed-off-by: Zhangfei Gao <zhangfei.gao-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
Applied to clk-hi3660 and merged into clk-next. I took the
liberty of using a function pointer in probe though so we don't
need the enum anymore.
---8<---
diff --git a/drivers/clk/hisilicon/clk-hi3660.c b/drivers/clk/hisilicon/clk-hi3660.c
index 4e752c632378..96a9697b06cf 100644
--- a/drivers/clk/hisilicon/clk-hi3660.c
+++ b/drivers/clk/hisilicon/clk-hi3660.c
@@ -14,14 +14,6 @@
#include <linux/platform_device.h>
#include "clk.h"
-enum hi3660_clk_type {
- HI3660_CRGCTRL = 1,
- HI3660_PCTRL,
- HI3660_PMUCTRL,
- HI3660_SCTRL,
- HI3660_IOMCU,
-};
-
static const struct hisi_fixed_rate_clock hi3660_fixed_rate_clks[] = {
{ HI3660_CLKIN_SYS, "clkin_sys", NULL, 0, 19200000, },
{ HI3660_CLKIN_REF, "clkin_ref", NULL, 0, 32764, },
@@ -533,15 +525,15 @@ static void hi3660_clk_crgctrl_init(struct device_node *np)
static const struct of_device_id hi3660_clk_match_table[] = {
{ .compatible = "hisilicon,hi3660-crgctrl",
- .data = (void *)HI3660_CRGCTRL },
+ .data = hi3660_clk_crgctrl_init },
{ .compatible = "hisilicon,hi3660-pctrl",
- .data = (void *)HI3660_PCTRL },
+ .data = hi3660_clk_pctrl_init },
{ .compatible = "hisilicon,hi3660-pmuctrl",
- .data = (void *)HI3660_PMUCTRL },
+ .data = hi3660_clk_pmuctrl_init },
{ .compatible = "hisilicon,hi3660-sctrl",
- .data = (void *)HI3660_SCTRL },
+ .data = hi3660_clk_sctrl_init },
{ .compatible = "hisilicon,hi3660-iomcu",
- .data = (void *)HI3660_IOMCU },
+ .data = hi3660_clk_iomcu_init },
{ }
};
@@ -549,31 +541,14 @@ static int hi3660_clk_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = pdev->dev.of_node;
- enum hi3660_clk_type type;
+ void (*init_func)(struct device_node *np);
- type = (enum hi3660_clk_type)of_device_get_match_data(dev);
- if (!type)
+ init_func = of_device_get_match_data(dev);
+ if (!init_func)
return -ENODEV;
- switch (type) {
- case HI3660_CRGCTRL:
- hi3660_clk_crgctrl_init(np);
- break;
- case HI3660_PCTRL:
- hi3660_clk_pctrl_init(np);
- break;
- case HI3660_PMUCTRL:
- hi3660_clk_pmuctrl_init(np);
- break;
- case HI3660_SCTRL:
- hi3660_clk_sctrl_init(np);
- break;
- case HI3660_IOMCU:
- hi3660_clk_iomcu_init(np);
- break;
- default:
- break;
- }
+ init_func(np);
+
return 0;
}
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH v2 1/2] dt-bindings: Document the hi3660 clock bindings
From: Stephen Boyd @ 2017-01-10 0:21 UTC (permalink / raw)
To: Zhangfei Gao
Cc: Rob Herring, Arnd Bergmann, guodong Xu, devicetree,
haojian.zhuang, linux-arm-kernel
In-Reply-To: <1482978805-6981-2-git-send-email-zhangfei.gao@linaro.org>
On 12/29, Zhangfei Gao wrote:
> Add DT bindings documentation for hi3660 SoC clock.
>
> Signed-off-by: Zhangfei Gao <zhangfei.gao@linaro.org>
> ---
Applied to clk-hi3660 and merged into clk-next
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH] Documentation: dt-bindings: Add binding documentation for TI clkctrl clocks
From: Tony Lindgren @ 2017-01-09 23:42 UTC (permalink / raw)
To: Michael Turquette, Stephen Boyd, Tero Kristo
Cc: devicetree, linux-clk, linux-omap, Paul Walmsley, Rob Herring
Texas Instruments omap variant SoCs starting with omap4 have a clkctrl
clock controller instance for each interconnect target module. The clkctrl
controls functional and interface clocks for the module.
The clkctrl clocks are currently handled by arch/arm/mach-omap2 hwmod code.
With this binding and a related clock device driver we can start moving the
clkctrl clock handling to live in drivers/clk/ti.
For hardware reference, see omap4430 TRM "Table 3-1312. L4PER_CM2 Registers
Mapping Summary" for example. It show one instance of a clkctrl clock
controller with multiple clkctrl registers.
Note that this binding allows keeping the clockdomain related parts out of
drivers/clock. The CLKCTCTRL and DYNAMICDEP registers can be handled by
using a separate driver in drivers/soc/ti and genpd. If the clockdomain
driver needs to know it's clocks, we can just set the the clkctrl device
instances to be children of the related clockdomain device.
On omap4 CM_L3INIT_USB_HOST_HS_CLKCTRL on omap5 has eight OPTFCLKEN bits.
So we need to shift the clock index to avoid index conflict for the clock
consumer binding with the next clkctrl offset on omap4.
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Rob Herring <robh@kernel.org>
Signed-off-by: Tony Lindgren <tony@atomide.com>
---
So here's what I was able to come up for the clkctr binding based on
all we've discussed so far. Can you guys please take a look and see
if it looks OK to you before we do the device driver?
Also, does anybody have better suggestions for addressing the optional
clocks in each clkctrl register?
---
.../devicetree/bindings/clock/ti-clkctrl.txt | 56 ++++++++++++++++++++++
1 file changed, 56 insertions(+)
create mode 100644 Documentation/devicetree/bindings/clock/ti-clkctrl.txt
diff --git a/Documentation/devicetree/bindings/clock/ti-clkctrl.txt b/Documentation/devicetree/bindings/clock/ti-clkctrl.txt
new file mode 100644
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti-clkctrl.txt
@@ -0,0 +1,56 @@
+Texas Instruments clkctrl clock binding
+
+Texas Instruments SoCs can have a clkctrl clock controller for each
+interconnect target module. The clkctrl clock controller manages functional
+and interface clocks for each module. Each clkctrl controller can also
+gate one or more optional functional clocks for a module. The clkctrl
+clock controller is typical for omap3 and later variants.
+
+The clock consumers can specify the index of the clkctrl clock using
+the hardware offset from the clkctrl instance register space. The optional
+functional clocks can be specified by clkctrl hardware offset plus the
+index of the optional clock. Please see the Linux clock framework binding
+at Documentation/devicetree/bindings/clock/clock-bindings.txt.
+
+Required properties :
+- compatible : shall be "ti,clkctrl"
+- #clock-cells : shall contain 1
+
+Optional properties :
+- "ti,modulemode-auto" : list of clkctrl offsets using automatic gating
+
+Example: Clock controller node:
+
+&cm_l4per {
+ cm_l4per_clkctrl: clk@20 {
+ compatible = "ti,clkctrl";
+ reg = <0x20 0x1b0>;
+ #clock-cells = 1;
+ ti,modulemode-auto = <OMAP4_GPIO2_CLKCTRL>;
+ };
+};
+
+Example: Preprocessor helper macros in dt-bindings/ti-clkctrl.h
+
+#define OMAP4_CLKCTRL_OFFSET 0x20
+
+#define OMAP_CLKCTRL_INDEX(offset) \
+ (((offset) - OMAP4_CLKCTRL_OFFSET) << 8)
+
+#define OMAP_CLKCTRL_OPT_INDEX(offset, optclk) \
+ (OMAP_CLKCTRL_INDEX(offset) + (optclk))
+
+#define OMAP4_GPTIMER10_CLKTRL OMAP_CLKCTRL_INDEX(0x28)
+#define OMAP4_GPTIMER11_CLKTRL OMAP_CLKCTRL_INDEX(0x30)
+#define OMAP4_GPTIMER2_CLKTRL OMAP_CLKCTRL_INDEX(0x38)
+...
+#define OMAP4_GPIO2_CLKCTRL OMAP_CLKCTRL_INDEX(0x60)
+#define OMAP4_GPIO2_CLKCTRL_DBCLK OMAP_CLKCTRL_OPT_INDEX(0x60, 1)
+...
+
+Example: Clock consumer node for GPIO2:
+
+&gpio2 {
+ clocks = <&cm_l4per_clkctrl OMAP4_GPIO2_CLKCTRL
+ &cm_l4per_clkctrl OMAP4_GPIO2_CLKCTRL_DBCLK>;
+};
--
2.11.0
^ permalink raw reply
* Re: [PATCH v2 6/7] dt-bindings: media: Add Renesas R-Car DRIF binding
From: Laurent Pinchart @ 2017-01-09 23:09 UTC (permalink / raw)
To: Hans Verkuil
Cc: Ramesh Shanmugasundaram, Geert Uytterhoeven, Rob Herring,
Mark Rutland, Mauro Carvalho Chehab, Sakari Ailus,
Antti Palosaari, Chris Paterson, Geert Uytterhoeven,
Linux Media Mailing List,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux-Renesas
In-Reply-To: <cca1ade8-01ef-8eab-f4b1-7dd7f204fdea-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>
Hello Hans,
On Monday 09 Jan 2017 14:36:55 Hans Verkuil wrote:
> On 01/03/2017 04:20 PM, Ramesh Shanmugasundaram wrote:
> >>> On Wednesday 21 Dec 2016 08:10:37 Ramesh Shanmugasundaram wrote:
> >>>> Add binding documentation for Renesas R-Car Digital Radio Interface
> >>>> (DRIF) controller.
> >>>>
> >>>> Signed-off-by: Ramesh Shanmugasundaram
> >>>> <ramesh.shanmugasundaram-kTT6dE0pTRh9uiUsa/gSgQ@public.gmane.org> ---
> >>>>
> >>>> .../devicetree/bindings/media/renesas,drif.txt | 202 +++++++++++++
> >>>> 1 file changed, 202 insertions(+)
> >>>> create mode 100644
> >>>>
> >>>> Documentation/devicetree/bindings/media/renesas,drif.txt
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/media/renesas,drif.txt
> >>>> b/Documentation/devicetree/bindings/media/renesas,drif.txt new file
> >>>> mode 100644
> >>>> index 0000000..1f3feaf
> >>>> --- /dev/null
> >>>> +++ b/Documentation/devicetree/bindings/media/renesas,drif.txt
> >>>>
> >>>> +Optional properties of an internal channel when:
> >>>> + - It is the only enabled channel of the bond (or)
> >>>> + - If it acts as primary among enabled bonds
> >>>> +--------------------------------------------------------
> >>>> +- renesas,syncmd : sync mode
> >>>> + 0 (Frame start sync pulse mode. 1-bit width
> >>>> pulse
> >>>> + indicates start of a frame)
> >>>> + 1 (L/R sync or I2S mode) (default)
> >>>> +- renesas,lsb-first : empty property indicates lsb bit is received
> >>>> first.
> >>>> + When not defined msb bit is received first
> >>>> +(default)
> >>>> +- renesas,syncac-active: Indicates sync signal polarity, 0/1 for
> >>>> low/high
>
> Shouldn't this be 'renesas,sync-active' instead of syncac-active?
>
> I'm not sure if syncac is intended or if it is a typo.
>
> >>>> + respectively. The default is 1 (active high)
> >>>> +- renesas,dtdl : delay between sync signal and start of
> >>>> reception.
> >>>> + The possible values are represented in 0.5 clock
> >>>> + cycle units and the range is 0 to 4. The default
> >>>> + value is 2 (i.e.) 1 clock cycle delay.
> >>>> +- renesas,syncdl : delay between end of reception and sync
> >>>> signal edge.
> >>>> + The possible values are represented in 0.5 clock
> >>>> + cycle units and the range is 0 to 4 & 6. The
> >>>> default
> >>>> + value is 0 (i.e.) no delay.
> >>>
> >>> Most of these properties are pretty similar to the video bus
> >>> properties defined at the endpoint level in
> >>> Documentation/devicetree/bindings/media/video-interfaces.txt. I
> >>> believe it would make sense to use OF graph and try to standardize
> >>> these properties similarly.
>
> Other than sync-active, is there really anything else that is similar? And
> even the sync-active isn't a good fit since here there is only one sync
> signal instead of two for video (h and vsync).
That's why I said similar, not identical :-) My point is that, if we consider
that we could connect multiple sources to the DRIF, using OF graph would make
sense, and the above properties should then be defined per endpoint. If we
define them per endpoint we should then also try standardize the ones that are
not really Renesas-specific (that's at least syncac-active). For the syncmd
and lsb-first properties, it could also make sense to query them from the
connected subdev at runtime, as they're similar in purpose to formats and
media bus configuration (struct v4l2_mbus_config).
I'm not an SDR expert, so I'd like to have your opinion on this.
> >> Note that the last two properties match the those in
> >> Documentation/devicetree/bindings/spi/sh-msiof.txt.
> >> We may want to use one DRIF channel as a plain SPI slave with the
> >> (modified) MSIOF driver in the future.
> >
> > Should I leave it as it is or modify these as in video-interfaces.txt?
> > Shall we conclude on this please?
--
Regards,
Laurent Pinchart
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 0/5] meson-gx: reset RGMII PHYs and configure TX delay
From: Kevin Hilman @ 2017-01-09 22:52 UTC (permalink / raw)
To: Martin Blumenstingl
Cc: linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
carlo-KA+7E9HrN00dnm+yROfE0A,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA, will.deacon-5wv7dgnIgG8,
catalin.marinas-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A
In-Reply-To: <CAFBinCDpBew7wreNPn6=J3jKsw_Ok=Ed9_+Gxsefb661RvUdrA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> writes:
> On Sat, Dec 3, 2016 at 12:47 AM, Martin Blumenstingl
> <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:
>> This partially fixes the 1000Mbit/s ethernet TX throughput issues (on
>> networks which are not affected by the EEE problem, as reported here:
>> [1]).
>> The actual problem for the TX throughput issues was that the TX delay
>> was applied twice:
>> - once "accidentally" by the PHY (this was fixed with [2])
>> - once by the MAC because there was a hardcoded TX delay (of 2ns),
>> this will be configurable with the changes from [0]
>>
>> These are the dts changes which belong to my other series (in v2
>> these patches were part of the other series, upon request of the
>> net maintainers I have split the .dts changes into their own series so
>> we are able to take both through different trees):
>> "[PATCH net-next v3 0/2] stmmac: dwmac-meson8b: configurable
>> RGMII TX delay": [0].
>> Thus this series depends on the ACK for the binding changes in the
>> other series!
>>
>> I based these changes on my other series "[PATCH v2 0/2] GXL and GXM
>> SCPI improvements": [3]
> the DT binding changes for the meson8b-dwmac driver were ACK'ed by Rob
> Herring, so you can proceed with this series once you applied the SCPI
> patches.
Series queued for v4.11,
Thanks,
Kevin
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH linux v1 2/2] drivers: hwmon: hwmon driver for ASPEED AST2400/2500 PWM and Fan tach controller
From: Jaghathiswari Rankappagounder Natarajan @ 2017-01-09 21:59 UTC (permalink / raw)
To: openbmc, joel, jdelvare, linux, linux-hwmon, linux-kernel, corbet,
linux-doc, robh+dt, mark.rutland, devicetree
Cc: Jaghathiswari Rankappagounder Natarajan
In-Reply-To: <20170109215935.30067-1-jaghu@google.com>
The ASPEED AST2400/2500 PWM controller supports 8 PWM output ports.
The ASPEED AST2400/2500 Fan tach controller supports 16 tachometer inputs.
PWM clock types M, N and 0 are three types just to have three independent PWM
sources.
The device driver matches on the device tree node. The configuration values
are read from the device tree and written to the respective registers.
The driver provides a sysfs entries through which the user can
configure the duty-cycle value (ranging from 0 to 100 percent) and read the
fan tach rpm value.
Signed-off-by: Jaghathiswari Rankappagounder Natarajan <jaghu@google.com>
---
Documentation/hwmon/aspeed-pwm-tacho | 22 +
drivers/hwmon/Kconfig | 9 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/aspeed-pwm-tacho.c | 884 +++++++++++++++++++++++++++++++++++
4 files changed, 916 insertions(+)
create mode 100644 Documentation/hwmon/aspeed-pwm-tacho
create mode 100644 drivers/hwmon/aspeed-pwm-tacho.c
diff --git a/Documentation/hwmon/aspeed-pwm-tacho b/Documentation/hwmon/aspeed-pwm-tacho
new file mode 100644
index 000000000000..0e9ec6d5f900
--- /dev/null
+++ b/Documentation/hwmon/aspeed-pwm-tacho
@@ -0,0 +1,22 @@
+Kernel driver aspeed-pwm-tacho
+==============================
+
+Supported chips:
+ ASPEED AST2400/2500
+
+Authors:
+ <jaghu@google.com>
+
+Description:
+------------
+This driver implements support for ASPEED AST2400/2500 PWM and Fan Tacho
+controller. The PWM controller supports upto 8 PWM outputs. The Fan tacho
+controller supports upto 16 tachometer inputs.
+
+The driver provides the following sensor accesses in sysfs:
+
+fanX_input ro provide current fan rotation value in RPM as reported
+ by the fan to the device.
+
+pwmX rw get or set PWM fan control value. This is an integer
+ value between 0(off) and 255(full speed).
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 45cef3d2c75c..757b5b0705bf 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -341,6 +341,15 @@ config SENSORS_ASB100
This driver can also be built as a module. If so, the module
will be called asb100.
+config SENSORS_ASPEED
+ tristate "ASPEED AST2400/AST2500 PWM and Fan tach driver"
+ help
+ This driver provides support for ASPEED AST2400/AST2500 PWM
+ and Fan Tacho controllers.
+
+ This driver can also be built as a module. If so, the module
+ will be called aspeed_pwm_tacho.
+
config SENSORS_ATXP1
tristate "Attansic ATXP1 VID controller"
depends on I2C
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index aecf4ba17460..83025cc9bb45 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_SENSORS_ADT7475) += adt7475.o
obj-$(CONFIG_SENSORS_APPLESMC) += applesmc.o
obj-$(CONFIG_SENSORS_ARM_SCPI) += scpi-hwmon.o
obj-$(CONFIG_SENSORS_ASC7621) += asc7621.o
+obj-$(CONFIG_SENSORS_ASPEED) += aspeed-pwm-tacho.o
obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o
obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o
obj-$(CONFIG_SENSORS_DA9052_ADC)+= da9052-hwmon.o
diff --git a/drivers/hwmon/aspeed-pwm-tacho.c b/drivers/hwmon/aspeed-pwm-tacho.c
new file mode 100644
index 000000000000..93eb3be2e506
--- /dev/null
+++ b/drivers/hwmon/aspeed-pwm-tacho.c
@@ -0,0 +1,884 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 or later as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/gpio/consumer.h>
+#include <linux/delay.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/sysfs.h>
+
+/* ASPEED PWM & FAN Tach Register Definition */
+#define ASPEED_PTCR_CTRL 0x00
+#define ASPEED_PTCR_CLK_CTRL 0x04
+#define ASPEED_PTCR_DUTY0_CTRL 0x08
+#define ASPEED_PTCR_DUTY1_CTRL 0x0c
+#define ASPEED_PTCR_TYPEM_CTRL 0x10
+#define ASPEED_PTCR_TYPEM_CTRL1 0x14
+#define ASPEED_PTCR_TYPEN_CTRL 0x18
+#define ASPEED_PTCR_TYPEN_CTRL1 0x1c
+#define ASPEED_PTCR_TACH_SOURCE 0x20
+#define ASPEED_PTCR_TRIGGER 0x28
+#define ASPEED_PTCR_RESULT 0x2c
+#define ASPEED_PTCR_INTR_CTRL 0x30
+#define ASPEED_PTCR_INTR_STS 0x34
+#define ASPEED_PTCR_TYPEM_LIMIT 0x38
+#define ASPEED_PTCR_TYPEN_LIMIT 0x3C
+#define ASPEED_PTCR_CTRL_EXT 0x40
+#define ASPEED_PTCR_CLK_CTRL_EXT 0x44
+#define ASPEED_PTCR_DUTY2_CTRL 0x48
+#define ASPEED_PTCR_DUTY3_CTRL 0x4c
+#define ASPEED_PTCR_TYPEO_CTRL 0x50
+#define ASPEED_PTCR_TYPEO_CTRL1 0x54
+#define ASPEED_PTCR_TACH_SOURCE_EXT 0x60
+#define ASPEED_PTCR_TYPEO_LIMIT 0x78
+
+/* ASPEED_PTCR_CTRL : 0x00 - General Control Register */
+#define ASPEED_PTCR_CTRL_SET_PWMD_TYPE_PART1 15
+#define ASPEED_PTCR_CTRL_SET_PWMD_TYPE_PART2 6
+#define ASPEED_PTCR_CTRL_SET_PWMD_TYPE_MASK (BIT(7) | BIT(15))
+
+#define ASPEED_PTCR_CTRL_SET_PWMC_TYPE_PART1 14
+#define ASPEED_PTCR_CTRL_SET_PWMC_TYPE_PART2 5
+#define ASPEED_PTCR_CTRL_SET_PWMC_TYPE_MASK (BIT(6) | BIT(14))
+
+#define ASPEED_PTCR_CTRL_SET_PWMB_TYPE_PART1 13
+#define ASPEED_PTCR_CTRL_SET_PWMB_TYPE_PART2 4
+#define ASPEED_PTCR_CTRL_SET_PWMB_TYPE_MASK (BIT(5) | BIT(13))
+
+#define ASPEED_PTCR_CTRL_SET_PWMA_TYPE_PART1 12
+#define ASPEED_PTCR_CTRL_SET_PWMA_TYPE_PART2 3
+#define ASPEED_PTCR_CTRL_SET_PWMA_TYPE_MASK (BIT(4) | BIT(12))
+
+#define ASPEED_PTCR_CTRL_FAN_NUM_EN(x) (0x1 << (16 + (x)))
+
+#define ASPEED_PTCR_CTRL_PWMD_EN (0x1 << 11)
+#define ASPEED_PTCR_CTRL_PWMC_EN (0x1 << 10)
+#define ASPEED_PTCR_CTRL_PWMB_EN (0x1 << 9)
+#define ASPEED_PTCR_CTRL_PWMA_EN (0x1 << 8)
+
+#define ASPEED_PTCR_CTRL_CLK_SRC 0x2
+#define ASPEED_PTCR_CTRL_CLK_EN 0x1
+
+/* ASPEED_PTCR_CLK_CTRL : 0x04 - Clock Control Register */
+/* TYPE N */
+#define ASPEED_PTCR_CLK_CTRL_TYPEN_UNIT 24
+#define ASPEED_PTCR_CLK_CTRL_TYPEN_H 20
+#define ASPEED_PTCR_CLK_CTRL_TYPEN_L 16
+/* TYPE M */
+#define ASPEED_PTCR_CLK_CTRL_TYPEM_UNIT 8
+#define ASPEED_PTCR_CLK_CTRL_TYPEM_H 4
+#define ASPEED_PTCR_CLK_CTRL_TYPEM_L 0
+
+/*
+ * ASPEED_PTCR_DUTY_CTRL/1/2/3 : 0x08/0x0C/0x48/0x4C - PWM-FAN duty control
+ * 0/1/2/3 register
+ */
+#define DUTY_CTRL_PWM2_FALL_POINT 24
+#define DUTY_CTRL_PWM2_RISE_POINT 16
+#define DUTY_CTRL_PWM1_FALL_POINT 8
+#define DUTY_CTRL_PWM1_RISE_POINT 0
+
+/* ASPEED_PTCR_TYPEM_CTRL : 0x10/0x18/0x50 - Type M/N/O Ctrl 0 Register */
+#define TYPE_CTRL_FAN_PERIOD 16
+#define TYPE_CTRL_FAN_MODE 4
+#define TYPE_CTRL_FAN_DIVISION 1
+#define TYPE_CTRL_FAN_TYPE_EN 1
+
+/* ASPEED_PTCR_TACH_SOURCE : 0x20/0x60 - Tach Source Register */
+/* bit [0,1] at 0x20, bit [2] at 0x60 */
+#define TACH_PWM_SOURCE_BIT01(x) ((x) * 2)
+#define TACH_PWM_SOURCE_BIT2(x) ((x) * 2)
+#define TACH_PWM_SOURCE_MASK_BIT01(x) (0x3 << ((x) * 2))
+#define TACH_PWM_SOURCE_MASK_BIT2(x) (0x1 << ((x) * 2))
+
+/* ASPEED_PTCR_TRIGGER : 0x28 - Trigger Register */
+#define TRIGGER_READ_FAN_NUM(x) (0x1 << (x))
+
+/* ASPEED_PTCR_RESULT : 0x2c - Result Register */
+#define RESULT_STATUS 31
+#define RESULT_VALUE_MASK 0xfffff
+
+/* ASPEED_PTCR_CTRL_EXT : 0x40 - General Control Extension #1 Register */
+#define ASPEED_PTCR_CTRL_SET_PWMH_TYPE_PART1 15
+#define ASPEED_PTCR_CTRL_SET_PWMH_TYPE_PART2 6
+#define ASPEED_PTCR_CTRL_SET_PWMH_TYPE_MASK (BIT(7) | BIT(15))
+
+#define ASPEED_PTCR_CTRL_SET_PWMG_TYPE_PART1 14
+#define ASPEED_PTCR_CTRL_SET_PWMG_TYPE_PART2 5
+#define ASPEED_PTCR_CTRL_SET_PWMG_TYPE_MASK (BIT(6) | BIT(14))
+
+#define ASPEED_PTCR_CTRL_SET_PWMF_TYPE_PART1 13
+#define ASPEED_PTCR_CTRL_SET_PWMF_TYPE_PART2 4
+#define ASPEED_PTCR_CTRL_SET_PWMF_TYPE_MASK (BIT(5) | BIT(13))
+
+#define ASPEED_PTCR_CTRL_SET_PWME_TYPE_PART1 12
+#define ASPEED_PTCR_CTRL_SET_PWME_TYPE_PART2 3
+#define ASPEED_PTCR_CTRL_SET_PWME_TYPE_MASK (BIT(4) | BIT(12))
+
+#define ASPEED_PTCR_CTRL_PWMH_EN (0x1 << 11)
+#define ASPEED_PTCR_CTRL_PWMG_EN (0x1 << 10)
+#define ASPEED_PTCR_CTRL_PWMF_EN (0x1 << 9)
+#define ASPEED_PTCR_CTRL_PWME_EN (0x1 << 8)
+
+/* ASPEED_PTCR_CLK_EXT_CTRL : 0x44 - Clock Control Extension #1 Register */
+/* TYPE O */
+#define ASPEED_PTCR_CLK_CTRL_TYPEO_UNIT 8
+#define ASPEED_PTCR_CLK_CTRL_TYPEO_H 4
+#define ASPEED_PTCR_CLK_CTRL_TYPEO_L 0
+
+#define MCLK 1
+#define PWM_MAX 255
+#define MAX_HIGH_LOW_BIT 15
+
+struct aspeed_pwm_tacho_data {
+ void __iomem *base;
+ unsigned long clk_freq;
+ const struct attribute_group *groups[24];
+ u8 type_pwm_clock_unit[3];
+ u8 type_pwm_clock_division_h[3];
+ u8 type_pwm_clock_division_l[3];
+ u8 type_fan_tach_clock_division[3];
+ u16 type_fan_tach_unit[3];
+ u8 pwm_port_type[8];
+ u8 pwm_port_fan_ctrl[8];
+ u8 fan_tach_ch_source[16];
+};
+
+enum type { TYPEM, TYPEN, TYPEO };
+
+struct type_params {
+ u32 l_value;
+ u32 h_value;
+ u32 unit_value;
+ u32 clk_ctrl_reg;
+ u32 ctrl_reg;
+ u32 ctrl_reg1;
+};
+
+static const struct type_params type_params[] = {
+ [TYPEM] = {
+ .l_value = ASPEED_PTCR_CLK_CTRL_TYPEM_L,
+ .h_value = ASPEED_PTCR_CLK_CTRL_TYPEM_H,
+ .unit_value = ASPEED_PTCR_CLK_CTRL_TYPEM_UNIT,
+ .clk_ctrl_reg = ASPEED_PTCR_CLK_CTRL,
+ .ctrl_reg = ASPEED_PTCR_TYPEM_CTRL,
+ .ctrl_reg1 = ASPEED_PTCR_TYPEM_CTRL1,
+ },
+ [TYPEN] = {
+ .l_value = ASPEED_PTCR_CLK_CTRL_TYPEN_L,
+ .h_value = ASPEED_PTCR_CLK_CTRL_TYPEN_H,
+ .unit_value = ASPEED_PTCR_CLK_CTRL_TYPEN_UNIT,
+ .clk_ctrl_reg = ASPEED_PTCR_CLK_CTRL,
+ .ctrl_reg = ASPEED_PTCR_TYPEN_CTRL,
+ .ctrl_reg1 = ASPEED_PTCR_TYPEN_CTRL1,
+ },
+ [TYPEO] = {
+ .l_value = ASPEED_PTCR_CLK_CTRL_TYPEO_L,
+ .h_value = ASPEED_PTCR_CLK_CTRL_TYPEO_H,
+ .unit_value = ASPEED_PTCR_CLK_CTRL_TYPEO_UNIT,
+ .clk_ctrl_reg = ASPEED_PTCR_CLK_CTRL_EXT,
+ .ctrl_reg = ASPEED_PTCR_TYPEO_CTRL,
+ .ctrl_reg1 = ASPEED_PTCR_TYPEO_CTRL1,
+ }
+};
+
+enum pwm_port { PWMA, PWMB, PWMC, PWMD, PWME, PWMF, PWMG, PWMH };
+
+struct pwm_port_params {
+ u32 pwm_en;
+ u32 ctrl_reg;
+ u32 type_part1;
+ u32 type_part2;
+ u32 type_mask;
+ u32 duty_ctrl_rise_point;
+ u32 duty_ctrl_fall_point;
+ u32 duty_ctrl_reg;
+ u8 duty_ctrl_calc_type;
+};
+
+static const struct pwm_port_params pwm_port_params[] = {
+ [PWMA] = {
+ .pwm_en = ASPEED_PTCR_CTRL_PWMA_EN,
+ .ctrl_reg = ASPEED_PTCR_CTRL,
+ .type_part1 = ASPEED_PTCR_CTRL_SET_PWMA_TYPE_PART1,
+ .type_part2 = ASPEED_PTCR_CTRL_SET_PWMA_TYPE_PART2,
+ .type_mask = ASPEED_PTCR_CTRL_SET_PWMA_TYPE_MASK,
+ .duty_ctrl_rise_point = DUTY_CTRL_PWM1_RISE_POINT,
+ .duty_ctrl_fall_point = DUTY_CTRL_PWM1_FALL_POINT,
+ .duty_ctrl_reg = ASPEED_PTCR_DUTY0_CTRL,
+ .duty_ctrl_calc_type = 0,
+ },
+ [PWMB] = {
+ .pwm_en = ASPEED_PTCR_CTRL_PWMB_EN,
+ .ctrl_reg = ASPEED_PTCR_CTRL,
+ .type_part1 = ASPEED_PTCR_CTRL_SET_PWMB_TYPE_PART1,
+ .type_part2 = ASPEED_PTCR_CTRL_SET_PWMB_TYPE_PART2,
+ .type_mask = ASPEED_PTCR_CTRL_SET_PWMB_TYPE_MASK,
+ .duty_ctrl_rise_point = DUTY_CTRL_PWM2_RISE_POINT,
+ .duty_ctrl_fall_point = DUTY_CTRL_PWM2_FALL_POINT,
+ .duty_ctrl_reg = ASPEED_PTCR_DUTY0_CTRL,
+ .duty_ctrl_calc_type = 1,
+ },
+ [PWMC] = {
+ .pwm_en = ASPEED_PTCR_CTRL_PWMC_EN,
+ .ctrl_reg = ASPEED_PTCR_CTRL,
+ .type_part1 = ASPEED_PTCR_CTRL_SET_PWMC_TYPE_PART1,
+ .type_part2 = ASPEED_PTCR_CTRL_SET_PWMC_TYPE_PART2,
+ .type_mask = ASPEED_PTCR_CTRL_SET_PWMC_TYPE_MASK,
+ .duty_ctrl_rise_point = DUTY_CTRL_PWM1_RISE_POINT,
+ .duty_ctrl_fall_point = DUTY_CTRL_PWM1_FALL_POINT,
+ .duty_ctrl_reg = ASPEED_PTCR_DUTY1_CTRL,
+ .duty_ctrl_calc_type = 0,
+ },
+ [PWMD] = {
+ .pwm_en = ASPEED_PTCR_CTRL_PWMD_EN,
+ .ctrl_reg = ASPEED_PTCR_CTRL,
+ .type_part1 = ASPEED_PTCR_CTRL_SET_PWMD_TYPE_PART1,
+ .type_part2 = ASPEED_PTCR_CTRL_SET_PWMD_TYPE_PART2,
+ .type_mask = ASPEED_PTCR_CTRL_SET_PWMD_TYPE_MASK,
+ .duty_ctrl_rise_point = DUTY_CTRL_PWM2_RISE_POINT,
+ .duty_ctrl_fall_point = DUTY_CTRL_PWM2_FALL_POINT,
+ .duty_ctrl_reg = ASPEED_PTCR_DUTY1_CTRL,
+ .duty_ctrl_calc_type = 1,
+ },
+ [PWME] = {
+ .pwm_en = ASPEED_PTCR_CTRL_PWME_EN,
+ .ctrl_reg = ASPEED_PTCR_CTRL_EXT,
+ .type_part1 = ASPEED_PTCR_CTRL_SET_PWME_TYPE_PART1,
+ .type_part2 = ASPEED_PTCR_CTRL_SET_PWME_TYPE_PART2,
+ .type_mask = ASPEED_PTCR_CTRL_SET_PWME_TYPE_MASK,
+ .duty_ctrl_rise_point = DUTY_CTRL_PWM1_RISE_POINT,
+ .duty_ctrl_fall_point = DUTY_CTRL_PWM1_FALL_POINT,
+ .duty_ctrl_reg = ASPEED_PTCR_DUTY2_CTRL,
+ .duty_ctrl_calc_type = 0,
+ },
+ [PWMF] = {
+ .pwm_en = ASPEED_PTCR_CTRL_PWMF_EN,
+ .ctrl_reg = ASPEED_PTCR_CTRL_EXT,
+ .type_part1 = ASPEED_PTCR_CTRL_SET_PWMF_TYPE_PART1,
+ .type_part2 = ASPEED_PTCR_CTRL_SET_PWMF_TYPE_PART2,
+ .type_mask = ASPEED_PTCR_CTRL_SET_PWMF_TYPE_MASK,
+ .duty_ctrl_rise_point = DUTY_CTRL_PWM2_RISE_POINT,
+ .duty_ctrl_fall_point = DUTY_CTRL_PWM2_FALL_POINT,
+ .duty_ctrl_reg = ASPEED_PTCR_DUTY2_CTRL,
+ .duty_ctrl_calc_type = 1,
+ },
+ [PWMG] = {
+ .pwm_en = ASPEED_PTCR_CTRL_PWMG_EN,
+ .ctrl_reg = ASPEED_PTCR_CTRL_EXT,
+ .type_part1 = ASPEED_PTCR_CTRL_SET_PWMG_TYPE_PART1,
+ .type_part2 = ASPEED_PTCR_CTRL_SET_PWMG_TYPE_PART2,
+ .type_mask = ASPEED_PTCR_CTRL_SET_PWMG_TYPE_MASK,
+ .duty_ctrl_rise_point = DUTY_CTRL_PWM1_RISE_POINT,
+ .duty_ctrl_fall_point = DUTY_CTRL_PWM1_FALL_POINT,
+ .duty_ctrl_reg = ASPEED_PTCR_DUTY3_CTRL,
+ .duty_ctrl_calc_type = 0,
+ },
+ [PWMH] = {
+ .pwm_en = ASPEED_PTCR_CTRL_PWMH_EN,
+ .ctrl_reg = ASPEED_PTCR_CTRL_EXT,
+ .type_part1 = ASPEED_PTCR_CTRL_SET_PWMH_TYPE_PART1,
+ .type_part2 = ASPEED_PTCR_CTRL_SET_PWMH_TYPE_PART2,
+ .type_mask = ASPEED_PTCR_CTRL_SET_PWMH_TYPE_MASK,
+ .duty_ctrl_rise_point = DUTY_CTRL_PWM2_RISE_POINT,
+ .duty_ctrl_fall_point = DUTY_CTRL_PWM2_FALL_POINT,
+ .duty_ctrl_reg = ASPEED_PTCR_DUTY3_CTRL,
+ .duty_ctrl_calc_type = 1,
+ }
+};
+
+static void aspeed_set_clock_enable(void __iomem *base, bool val)
+{
+ u32 reg_value = ioread32(base + ASPEED_PTCR_CTRL);
+
+ if (val)
+ reg_value |= ASPEED_PTCR_CTRL_CLK_EN;
+ else
+ reg_value &= ~ASPEED_PTCR_CTRL_CLK_EN;
+
+ iowrite32(reg_value, base + ASPEED_PTCR_CTRL);
+}
+
+static void aspeed_set_clock_source(void __iomem *base, int val)
+{
+ u32 reg_value = ioread32(base + ASPEED_PTCR_CTRL);
+
+ if (val == MCLK)
+ reg_value |= ASPEED_PTCR_CTRL_CLK_SRC;
+ else
+ reg_value &= ~ASPEED_PTCR_CTRL_CLK_SRC;
+
+ iowrite32(reg_value, base + ASPEED_PTCR_CTRL);
+}
+
+static void aspeed_set_pwm_clock_values(void __iomem *base, u8 type,
+ u8 div_high, u8 div_low, u8 unit)
+{
+ u32 reg_offset = type_params[type].clk_ctrl_reg;
+ u32 reg_value = ioread32(base + reg_offset);
+
+ reg_value &= ~((0xF << type_params[type].h_value) |
+ (0xF << type_params[type].l_value) |
+ (0xFF << type_params[type].unit_value));
+ reg_value |= ((div_high << type_params[type].h_value) |
+ (div_low << type_params[type].l_value) |
+ (unit << type_params[type].unit_value));
+
+ iowrite32(reg_value, base + reg_offset);
+}
+
+static void aspeed_set_pwm_port_enable(void __iomem *base, u8 pwm_port,
+ bool enable)
+{
+ u32 reg_offset = pwm_port_params[pwm_port].ctrl_reg;
+ u32 reg_value = ioread32(base + reg_offset);
+
+ if (enable)
+ reg_value |= pwm_port_params[pwm_port].pwm_en;
+ else
+ reg_value &= ~pwm_port_params[pwm_port].pwm_en;
+ iowrite32(reg_value, base + reg_offset);
+}
+
+static void aspeed_set_pwm_port_type(void __iomem *base, u8 pwm_port, u8 type)
+{
+ u32 reg_offset = pwm_port_params[pwm_port].ctrl_reg;
+ u32 reg_value = ioread32(base + reg_offset);
+
+ reg_value &= ~pwm_port_params[pwm_port].type_mask;
+ reg_value |= (type & 0x1) <<
+ pwm_port_params[pwm_port].type_part1;
+ reg_value |= (type & 0x2) <<
+ pwm_port_params[pwm_port].type_part2;
+
+ iowrite32(reg_value, base + reg_offset);
+}
+
+static void aspeed_set_pwm_port_duty_rising_falling(void __iomem *base,
+ u8 pwm_port, u8 rising,
+ u8 falling)
+{
+ u32 reg_offset = pwm_port_params[pwm_port].duty_ctrl_reg;
+ u32 reg_value = ioread32(base + reg_offset);
+
+ reg_value &= ~(0xFF << pwm_port_params[pwm_port].duty_ctrl_rise_point);
+ reg_value &= ~(0xFF << pwm_port_params[pwm_port].duty_ctrl_fall_point);
+
+ if (pwm_port_params[pwm_port].duty_ctrl_calc_type == 0) {
+ reg_value |= rising;
+ } else if (pwm_port_params[pwm_port].duty_ctrl_calc_type == 1) {
+ reg_value |= (rising <<
+ pwm_port_params[pwm_port].duty_ctrl_rise_point);
+ }
+ reg_value |= (falling <<
+ pwm_port_params[pwm_port].duty_ctrl_fall_point);
+
+ iowrite32(reg_value, base + reg_offset);
+}
+
+static void aspeed_set_tacho_type_enable(void __iomem *base, u8 type,
+ bool enable)
+{
+ u32 reg_offset = type_params[type].ctrl_reg;
+ u32 reg_value = ioread32(base + reg_offset);
+
+ if (enable)
+ reg_value |= TYPE_CTRL_FAN_TYPE_EN;
+ else
+ reg_value &= ~TYPE_CTRL_FAN_TYPE_EN;
+
+ iowrite32(reg_value, base + reg_offset);
+}
+
+static void aspeed_set_tacho_type_values(void __iomem *base, u8 type, u8 mode,
+ u16 unit, u8 division)
+{
+ u32 reg_offset = type_params[type].ctrl_reg;
+ u32 reg_offset1 = type_params[type].ctrl_reg1;
+ u32 reg_value = ioread32(base + reg_offset);
+
+ reg_value &= ~((0x3 << TYPE_CTRL_FAN_MODE) |
+ (0xFFFF << TYPE_CTRL_FAN_PERIOD) |
+ (0x7 << TYPE_CTRL_FAN_DIVISION));
+ reg_value |= ((mode << TYPE_CTRL_FAN_MODE) |
+ (unit << TYPE_CTRL_FAN_PERIOD) |
+ (division << TYPE_CTRL_FAN_DIVISION));
+
+ iowrite32(reg_value, base + reg_offset);
+
+ iowrite32(unit << 16, base + reg_offset1);
+}
+
+static void aspeed_set_fan_tach_ch_enable(void __iomem *base, u8 fan_tach_ch,
+ bool enable)
+{
+ u32 reg_value = ioread32(base + ASPEED_PTCR_CTRL);
+
+ if (enable)
+ reg_value |= ASPEED_PTCR_CTRL_FAN_NUM_EN(fan_tach_ch);
+ else
+ reg_value &= ~ASPEED_PTCR_CTRL_FAN_NUM_EN(fan_tach_ch);
+
+ iowrite32(reg_value, base + ASPEED_PTCR_CTRL);
+}
+
+static void aspeed_set_fan_tach_ch_source(void __iomem *base, u8 fan_tach_ch,
+ u8 fan_tach_ch_source)
+{
+ u32 reg_value1 = ioread32(base + ASPEED_PTCR_TACH_SOURCE);
+ u32 reg_value2 = ioread32(base + ASPEED_PTCR_TACH_SOURCE_EXT);
+
+ reg_value1 &= ~(TACH_PWM_SOURCE_MASK_BIT01(fan_tach_ch));
+ reg_value1 |= ((fan_tach_ch_source & 0x3) <<
+ (TACH_PWM_SOURCE_BIT01(fan_tach_ch)));
+
+ reg_value2 &= ~(TACH_PWM_SOURCE_MASK_BIT2(fan_tach_ch));
+ reg_value2 |= (((fan_tach_ch_source & 0x4) >> 2) <<
+ (TACH_PWM_SOURCE_BIT2(fan_tach_ch)));
+
+ iowrite32(reg_value1, base + ASPEED_PTCR_TACH_SOURCE);
+ iowrite32(reg_value2, base + ASPEED_PTCR_TACH_SOURCE_EXT);
+}
+
+static void aspeed_set_pwm_port_fan_ctrl(struct aspeed_pwm_tacho_data *priv,
+ u8 index, u8 fan_ctrl)
+{
+ u16 period;
+ u16 dc_time_on;
+
+ period = priv->type_pwm_clock_unit[priv->pwm_port_type[index]];
+ period += 1;
+ dc_time_on = (fan_ctrl * period) / PWM_MAX;
+
+ if (dc_time_on == 0) {
+ aspeed_set_pwm_port_enable(priv->base, index, false);
+ } else {
+ if (dc_time_on == period)
+ dc_time_on = 0;
+
+ aspeed_set_pwm_port_duty_rising_falling(priv->base, index, 0,
+ dc_time_on);
+ aspeed_set_pwm_port_enable(priv->base, index, true);
+ }
+}
+
+static u32 aspeed_get_fan_tach_ch_measure_period(struct aspeed_pwm_tacho_data
+ *priv, u8 type)
+{
+ u32 clk;
+ u16 tacho_unit;
+ u8 clk_unit, div_h, div_l, tacho_div;
+
+ clk = priv->clk_freq;
+
+ clk_unit = priv->type_pwm_clock_unit[type];
+ div_h = priv->type_pwm_clock_division_h[type];
+ div_h = 0x1 << div_h;
+ div_l = priv->type_pwm_clock_division_l[type];
+ if (div_l == 0)
+ div_l = 1;
+ else
+ div_l = div_l * 2;
+
+ tacho_unit = priv->type_fan_tach_unit[type];
+ tacho_div = priv->type_fan_tach_clock_division[type];
+
+ tacho_div = 0x4 << (tacho_div * 2);
+ return clk / (clk_unit * div_h * div_l * tacho_div * tacho_unit);
+}
+
+static u32 aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tacho_data *priv,
+ u8 fan_tach_ch)
+{
+ u32 raw_data, rpm, tach_div, clk_source, timeout = 0, sec;
+ u8 fan_tach_ch_source, type;
+ void __iomem *base = priv->base;
+
+ iowrite32(0, priv->base + ASPEED_PTCR_TRIGGER);
+ iowrite32(0x1 << fan_tach_ch, priv->base + ASPEED_PTCR_TRIGGER);
+
+ fan_tach_ch_source = priv->fan_tach_ch_source[fan_tach_ch];
+ type = priv->pwm_port_type[fan_tach_ch_source];
+
+ sec = (1000 / aspeed_get_fan_tach_ch_measure_period(priv, type));
+
+ msleep(sec);
+
+ while (!(ioread32(priv->base + ASPEED_PTCR_RESULT) &
+ (0x1 << RESULT_STATUS))) {
+ timeout++;
+ if (timeout > 1)
+ return 0;
+ msleep(sec);
+ };
+
+ raw_data = (ioread32(base + ASPEED_PTCR_RESULT)) &
+ RESULT_VALUE_MASK;
+ tach_div = priv->type_fan_tach_clock_division[type];
+
+ tach_div = 0x4 << (tach_div * 2);
+ clk_source = priv->clk_freq;
+ rpm = (clk_source * 60) / (2 * raw_data * tach_div);
+ return rpm;
+}
+
+static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int index = sensor_attr->index;
+ int ret;
+
+ struct aspeed_pwm_tacho_data *priv = dev_get_drvdata(dev);
+ long fan_ctrl;
+
+ ret = kstrtol(buf, 10, &fan_ctrl);
+ if (ret != 0)
+ return ret;
+
+ if (fan_ctrl < 0 || fan_ctrl > PWM_MAX)
+ return -EINVAL;
+
+ if (priv->pwm_port_fan_ctrl[index] == fan_ctrl)
+ return count;
+
+ priv->pwm_port_fan_ctrl[index] = fan_ctrl;
+ aspeed_set_pwm_port_fan_ctrl(priv, index, fan_ctrl);
+
+ return count;
+}
+
+static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int index = sensor_attr->index;
+
+ struct aspeed_pwm_tacho_data *priv = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", priv->pwm_port_fan_ctrl[index]);
+}
+
+static ssize_t show_rpm(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
+ int index = sensor_attr->index;
+ u32 rpm;
+
+ struct aspeed_pwm_tacho_data *priv = dev_get_drvdata(dev);
+
+ rpm = aspeed_get_fan_tach_ch_rpm(priv, index);
+
+ return sprintf(buf, "%u\n", rpm);
+}
+
+#define pwm_index(index) \
+static SENSOR_DEVICE_ATTR(pwm##index, 0644, \
+ show_pwm, set_pwm, index - 1); \
+ \
+static struct attribute *pwm##index##_dev_attrs[] = { \
+ &sensor_dev_attr_pwm##index.dev_attr.attr, \
+ NULL, \
+}; \
+static const struct attribute_group pwm##index##_dev_groups = { \
+ .attrs = pwm##index##_dev_attrs, \
+}
+
+#define fan_index(index) \
+static SENSOR_DEVICE_ATTR(fan##index##_input, 0444, \
+ show_rpm, NULL, index - 1); \
+ \
+static struct attribute *fan##index##_dev_attrs[] = { \
+ &sensor_dev_attr_fan##index##_input.dev_attr.attr, \
+ NULL, \
+}; \
+static const struct attribute_group fan##index##_dev_groups = { \
+ .attrs = fan##index##_dev_attrs, \
+}
+
+pwm_index(1);
+pwm_index(2);
+pwm_index(3);
+pwm_index(4);
+pwm_index(5);
+pwm_index(6);
+pwm_index(7);
+pwm_index(8);
+
+fan_index(1);
+fan_index(2);
+fan_index(3);
+fan_index(4);
+fan_index(5);
+fan_index(6);
+fan_index(7);
+fan_index(8);
+fan_index(9);
+fan_index(10);
+fan_index(11);
+fan_index(12);
+fan_index(13);
+fan_index(14);
+fan_index(15);
+fan_index(16);
+
+/*
+ * If the clock type is type M then :
+ * The PWM frequency = 24MHz / (type M clock division L bit *
+ * type M clock division H bit * (type M PWM period bit + 1))
+ * Calculate type M clock division L bit and H bits given the other values
+ */
+static int aspeed_create_type(struct device_node *child,
+ struct aspeed_pwm_tacho_data *priv,
+ u8 index)
+{
+ u8 period, div_l, div_h;
+ bool enable;
+ u8 mode, div;
+ u16 unit;
+
+ of_property_read_u8(child, "pwm_period", &period);
+ of_property_read_u8(child, "pwm_clock_division_h", &div_h);
+ of_property_read_u8(child, "pwm_clock_division_l", &div_l);
+ priv->type_pwm_clock_division_h[index] = div_h;
+ priv->type_pwm_clock_division_l[index] = div_l;
+ priv->type_pwm_clock_unit[index] = period;
+ aspeed_set_pwm_clock_values(priv->base, index, div_h, div_l, period);
+
+ enable = of_property_read_bool(child, "fan_tach_enable");
+ aspeed_set_tacho_type_enable(priv->base, index, enable);
+
+ of_property_read_u8(child, "fan_tach_clock_division", &div);
+ priv->type_fan_tach_clock_division[index] = div;
+
+ of_property_read_u8(child, "fan_tach_mode_selection", &mode);
+
+ of_property_read_u16(child, "fan_tach_period", &unit);
+ priv->type_fan_tach_unit[index] = unit;
+ aspeed_set_tacho_type_values(priv->base, index, mode, unit, div);
+
+ return 0;
+}
+
+static int aspeed_create_pwm_port(struct device_node *child,
+ struct aspeed_pwm_tacho_data *priv, u8 index,
+ u8 group_index)
+{
+ u8 val;
+ bool enable;
+
+ switch (index) {
+ case 1:
+ priv->groups[group_index] = &pwm1_dev_groups;
+ break;
+ case 2:
+ priv->groups[group_index] = &pwm2_dev_groups;
+ break;
+ case 3:
+ priv->groups[group_index] = &pwm3_dev_groups;
+ break;
+ case 4:
+ priv->groups[group_index] = &pwm4_dev_groups;
+ break;
+ case 5:
+ priv->groups[group_index] = &pwm5_dev_groups;
+ break;
+ case 6:
+ priv->groups[group_index] = &pwm6_dev_groups;
+ break;
+ case 7:
+ priv->groups[group_index] = &pwm7_dev_groups;
+ break;
+ case 8:
+ priv->groups[group_index] = &pwm8_dev_groups;
+ break;
+ }
+
+ enable = of_property_read_bool(child, "enable");
+ aspeed_set_pwm_port_enable(priv->base, index - 1, enable);
+
+ of_property_read_u8(child, "type", &val);
+ priv->pwm_port_type[index - 1] = val;
+ aspeed_set_pwm_port_type(priv->base, index - 1, val);
+
+ of_property_read_u8(child, "fan_ctrl", &val);
+ priv->pwm_port_fan_ctrl[index - 1] = val;
+ aspeed_set_pwm_port_fan_ctrl(priv, index - 1, val);
+
+ return 0;
+}
+
+static int aspeed_create_fan_tach_channel(struct device *dev,
+ struct device_node *child,
+ struct aspeed_pwm_tacho_data *priv,
+ u8 index, u8 group_index)
+{
+ u8 val;
+ bool enable;
+ struct gpio_desc *fan_ctrl = devm_gpiod_get(dev, "fan-ctrl", GPIOD_IN);
+
+ if (IS_ERR(fan_ctrl))
+ return PTR_ERR(fan_ctrl);
+
+ switch (index) {
+ case 1:
+ priv->groups[group_index] = &fan1_dev_groups;
+ break;
+ case 2:
+ priv->groups[group_index] = &fan2_dev_groups;
+ break;
+ case 3:
+ priv->groups[group_index] = &fan3_dev_groups;
+ break;
+ case 4:
+ priv->groups[group_index] = &fan4_dev_groups;
+ break;
+ case 5:
+ priv->groups[group_index] = &fan5_dev_groups;
+ break;
+ case 6:
+ priv->groups[group_index] = &fan6_dev_groups;
+ break;
+ case 7:
+ priv->groups[group_index] = &fan7_dev_groups;
+ break;
+ case 8:
+ priv->groups[group_index] = &fan8_dev_groups;
+ break;
+ case 9:
+ priv->groups[group_index] = &fan9_dev_groups;
+ break;
+ case 10:
+ priv->groups[group_index] = &fan10_dev_groups;
+ break;
+ case 11:
+ priv->groups[group_index] = &fan11_dev_groups;
+ break;
+ case 12:
+ priv->groups[group_index] = &fan12_dev_groups;
+ break;
+ case 13:
+ priv->groups[group_index] = &fan13_dev_groups;
+ break;
+ case 14:
+ priv->groups[group_index] = &fan14_dev_groups;
+ break;
+ case 15:
+ priv->groups[group_index] = &fan15_dev_groups;
+ break;
+ case 16:
+ priv->groups[group_index] = &fan16_dev_groups;
+ break;
+ }
+
+ enable = of_property_read_bool(child, "enable");
+ aspeed_set_fan_tach_ch_enable(priv->base, index - 1, enable);
+
+ of_property_read_u8(child, "pwm_source", &val);
+ priv->fan_tach_ch_source[index - 1] = val;
+ aspeed_set_fan_tach_ch_source(priv->base, index - 1, val);
+
+ return 0;
+}
+
+static int aspeed_pwm_tacho_probe(struct platform_device *pdev)
+{
+ struct device_node *np, *type_np, *pwm_np, *fan_tach_np, *child;
+ u8 pwm_index = 1, fan_index = 1, type_index = 0, group_index = 0;
+ struct aspeed_pwm_tacho_data *priv;
+ struct resource *res;
+ struct device *hwmon;
+ void __iomem *base;
+ struct clk *clk;
+
+ np = pdev->dev.of_node;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENOENT;
+
+ base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ if (!base)
+ return -ENOMEM;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+ priv->base = base;
+
+ iowrite32(0, base + ASPEED_PTCR_TACH_SOURCE);
+ iowrite32(0, base + ASPEED_PTCR_TACH_SOURCE_EXT);
+
+ clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(clk))
+ return -ENODEV;
+
+ priv->clk_freq = clk_get_rate(clk);
+ aspeed_set_clock_enable(base, true);
+ aspeed_set_clock_source(base, 0);
+
+ type_np = of_get_child_by_name(np, "type_values");
+ for_each_child_of_node(type_np, child) {
+ aspeed_create_type(child, priv, type_index++);
+ of_node_put(child);
+ }
+ of_node_put(type_np);
+ pwm_np = of_get_child_by_name(np, "pwm_port");
+ for_each_child_of_node(pwm_np, child) {
+ aspeed_create_pwm_port(child, priv, pwm_index++,
+ group_index++);
+ of_node_put(child);
+ }
+ of_node_put(pwm_np);
+ fan_tach_np = of_get_child_by_name(np, "fan_tach_channel");
+ for_each_child_of_node(fan_tach_np, child) {
+ aspeed_create_fan_tach_channel(&pdev->dev, child, priv,
+ fan_index++, group_index++);
+ of_node_put(child);
+ }
+ of_node_put(fan_tach_np);
+ of_node_put(np);
+
+ hwmon = devm_hwmon_device_register_with_groups(&pdev->dev,
+ "aspeed_pwm_tacho",
+ priv, priv->groups);
+ if (IS_ERR(hwmon))
+ return PTR_ERR(hwmon);
+
+ return 0;
+}
+
+static const struct of_device_id of_pwm_tacho_match_table[] = {
+ { .compatible = "aspeed,aspeed2400-pwm-tacho", },
+ { .compatible = "aspeed,aspeed2500-pwm-tacho", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, of_pwm_tacho_match_table);
+
+static struct platform_driver aspeed_pwm_tacho_driver = {
+ .probe = aspeed_pwm_tacho_probe,
+ .driver = {
+ .name = "aspeed_pwm_tacho",
+ .owner = THIS_MODULE,
+ .of_match_table = of_pwm_tacho_match_table,
+ },
+};
+
+module_platform_driver(aspeed_pwm_tacho_driver);
+
+MODULE_AUTHOR("Jaghathiswari Rankappagounder Natarajan <jaghu@google.com>");
+MODULE_DESCRIPTION("ASPEED PWM and Fan Tacho device driver");
+MODULE_LICENSE("GPL");
--
2.11.0.390.gc69c2f50cf-goog
^ permalink raw reply related
* [PATCH linux v1 1/2] Documentation: dt-bindings: Document bindings for ASPEED AST2400/AST2500 pwm and fan tach controller device driver
From: Jaghathiswari Rankappagounder Natarajan @ 2017-01-09 21:59 UTC (permalink / raw)
To: openbmc, joel, jdelvare, linux, linux-hwmon, linux-kernel, corbet,
linux-doc, robh+dt, mark.rutland, devicetree
Cc: Jaghathiswari Rankappagounder Natarajan
In-Reply-To: <20170109215935.30067-1-jaghu@google.com>
This binding provides interface for adding values related to ASPEED
AST2400/2500 PWM and Fan tach controller support.
The PWM controller can support upto 8 PWM output ports.
The Fan tach controller can support upto 16 tachometer inputs.
PWM clock types M, N and 0 are three types just to have three independent
PWM sources.
Signed-off-by: Jaghathiswari Rankappagounder Natarajan <jaghu@google.com>
---
.../devicetree/bindings/hwmon/aspeed-pwm-tacho.txt | 153 +++++++++++++++++++++
1 file changed, 153 insertions(+)
create mode 100644 Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt
diff --git a/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt b/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt
new file mode 100644
index 000000000000..8f346409ee8c
--- /dev/null
+++ b/Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt
@@ -0,0 +1,153 @@
+ASPEED AST2400/AST2500 PWM and Fan Tacho controller device driver
+
+The ASPEED PWM controller can support upto 8 PWM outputs. The ASPEED Fan Tacho
+controller can support upto 16 tachometer inputs. The PWM controller supports
+3 types of frequency mode PWM for fan speed control. PWM clock types M, N and 0
+are 3 types of frequency mode PWM just to have 3 independent PWM sources.
+
+Required properties for pwm_tacho node:
+- #address-cells : should be 1.
+
+- #size-cells : should be 1.
+
+- reg : address and length of the register set for the device.
+
+- pinctrl-names : a pinctrl state named "default" must be defined.
+
+- pinctrl-0 : phandle referencing pin configuration of the AST2400/AST2500 PWM
+ ports.
+
+- compatible : should be "aspeed,aspeed2400-pwm-tacho" for AST2400 or
+ "aspeed,aspeed2500-pwm-tacho" for AST2500.
+
+- clocks : a fixed clock providing input clock frequency(PWM
+ and Fan Tach clock)
+
+type_values subnode format:
+===========================
+Under type_values subnode there can be upto 3 child nodes indicating type M/N/O
+values. Atleast one child node is required.
+
+Required properties for the child node(type M/N/O):
+- pwm_period : indicates type M/N/O PWM period, as per the AST2400/AST2500
+ datasheet. integer value in the range 0 to 255.
+
+- pwm_clock_division_l : indicates type M/N/O PWM clock division L value,
+ as per the AST2400/AST2500 datasheet.
+ integer value in the range 0 to 15.
+ 0 here indicates divide 1, 1 indicates divide 2,
+ 2 indicates divide 4, 3 indicates divide 6, and so on
+ till 15 indicates divide 30.
+
+- pwm_clock_division_h : indicates type M/N/O PWM clock division H value,
+ as per the AST2400/AST2500 datasheet.
+ integer value in the range 0 to 15.
+ 0 here indicates divide 1, 1 indicates divide 2,
+ 2 indicates divide 4, 3 indicates divide 8, and so on
+ till 15 indicates divide 32768.
+
+- fan_tach_enable : indicates fan tach enable of type M/N/O as per the
+ AST2400/AST2500 datasheet. boolean value.
+
+- fan_tach_clock_division : indicates fan tach clock division as per the
+ AST2400/AST2500 datasheet.
+ integer value in the range 0 to 7.
+ 0 indicates divide 4, 1 indicates divide 16,
+ 2 indicates divide 64, 3 indicates divide 256
+ and so on till 7 indicates divide 65536.
+
+- fan_tach_mode_selection : indicates fan tach mode mode selection as per the
+ AST2400/AST2500 datasheet. integer value in the
+ range 0 to 2. 0 indicates falling edge, 1 indicates
+ rising edge and 2 indicates both edges.
+
+- fan_tach_period : indicates fan tach period as per the AST2400/AST2500
+ datasheet. integer value (can be upto 16 bits long).
+
+pwm_port subnode format:
+========================
+Under pwm_port subnode there can upto 8 child nodes each indicating values
+for one of the 8 PWM output ports.
+
+Required properties for each child node(starting from PWM A through PWM H):
+- enable : enable PWM #X port, X ranges from A through H. boolean value.
+
+- type : indicates type selection value of PWM #X port, X ranges from A
+ through H. integer value in the range 0 to 2;
+ 0 indicates type M, 1 indicates type N, 2 indicates type O.
+
+- fan_ctrl : set the PWM fan control initial value. integer value between
+ 0(off) and 255(full speed).
+
+fan_tach_channel subnode format:
+================================
+Under fan_tach_channel subnode there can be upto 16 child nodes each indicating
+values for one of the 16 fan tach channels.
+
+Required properties for each child node(starting from fan tach #0 through
+fan tach #16):
+- fan-ctrl-gpios : should specify the tachometer input pin on the hardware.
+
+- enable : enable fan tach #X, X ranges from 0 through 16. boolean value.
+
+- pwm_source : indicates PWM source of fan tach #X, X ranges from 0 through 16.
+ integer value in the range 0 to 7. 0 indicates PWM port A,
+ 1 indicates PWM port B and so on till 7 indicates PWM port H.
+
+Examples:
+
+pwm_tacho_fixed_clk: fixedclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <24000000>;
+}
+
+pwm_tacho: pwm-tacho-controller@1e786000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x1E786000 0x1000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_pwm0_default &pinctrl_pwm1_default>;
+ compatible = "aspeed,aspeed2500-pwm-tacho";
+ clocks = <&pwm_tacho_fixed_clk>;
+ type_values {
+ typem {
+ pwm_period = /bits/ 8 <0x5F>;
+ pwm_clock_division_h = /bits/ 8 <0x00>;
+ pwm_clock_division_l = /bits/ 8 <0x05>;
+ fan_tach_enable;
+ fan_tach_clock_division = /bits/ 8 <0x00>;
+ fan_tach_mode_selection = /bits/ 8 <0x00>;
+ fan_tach_period = /bits/ 16 <0x1000>;
+ };
+ };
+
+ pwm_port {
+ pwm_port0 {
+ enable;
+ type = /bits/ 8 <0x00>;
+ fan_ctrl = /bits/ 8 <0xFF>;
+ };
+
+ pwm_port1 {
+ enable;
+ type = /bits/ 8 <0x00>;
+ fan_ctrl = /bits/ 8 <0xFF>;
+ };
+ };
+
+ fan_tach_channel {
+ fan_tach0 {
+ fan-ctrl-gpios = <&gpio ASPEED_GPIO(O, 0) GPIO_ACTIVE_HIGH>;
+ enable;
+ pwm_source = /bits/ 8 <0x00>;
+ };
+
+ fan_tach1 {
+ fan-ctrl-gpios = <&gpio ASPEED_GPIO(O, 1) GPIO_ACTIVE_HIGH>;
+ enable;
+ pwm_source = /bits/ 8 <0x01>;
+ };
+
+ };
+};
--
2.11.0.390.gc69c2f50cf-goog
^ permalink raw reply related
* [PATCH linux v1 0/2] Support for ASPEED AST2400/AST2500 PWM and Fan Tach driver
From: Jaghathiswari Rankappagounder Natarajan @ 2017-01-09 21:59 UTC (permalink / raw)
To: openbmc-uLR06cmDAlY/bJ5BZ2RsiQ, joel-U3u1mxZcP9KHXe+LvDLADg,
jdelvare-IBi9RG/b67k, linux-0h96xk9xTtrk1uMJSBkQmQ,
linux-hwmon-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, corbet-T1hC0tSOHrs,
linux-doc-u79uwXL29TY76Z2rM5mHXA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: Jaghathiswari Rankappagounder Natarajan
Support for ASPEED AST2400/AST2500 PWM and Fan Tach driver
Support for ASPEED AST2400/AST2500 PWM and Fan Tach driver.
The AST2400/AST2500 PWM controller can support 8 PWM output ports.
The AST2400/AST2500 Fan Tach controller can support 16 tachometer inputs.
There can be three different PWM clock types (Type M, N and O); Those three
types just to have three independent PWM sources.
The driver provides sysfs entries through which the user can configure the
duty cycle for the particular PWM output port and read the fan rpm value for
the particular tachometer input.
Added devicetree binding documentation for AST2400/AST2500 PWM and Fan Tach
support.
Tested on Zaius board (which has AST2500 chip) and observed that when
duty cycle is lowered then the fan speed is lowered and lower fan rpm value(
corresponding to the duty cycle) is reported and when the duty cycle is
increased then the fan speed increases and higher fan rpm value(corresponding
to the duty cycle) is reported.
Tested on AST2500 EVB board and observed the PWM output pulses come
correctly based on the given settings using Logic Saleae Analyzer.
Jaghathiswari Rankappagounder Natarajan (2):
Documentation: dt-bindings: Document bindings for aspeed pwm and fan
tach controller device driver
drivers: hwmon: hwmon driver for ASPEED AST2400/2500 PWM and Fan tach
controller
.../devicetree/bindings/hwmon/aspeed-pwm-tacho.txt | 153 ++++
Documentation/hwmon/aspeed-pwm-tacho | 22 +
drivers/hwmon/Kconfig | 9 +
drivers/hwmon/Makefile | 1 +
drivers/hwmon/aspeed-pwm-tacho.c | 884 +++++++++++++++++++++
5 files changed, 1069 insertions(+)
create mode 100644 Documentation/devicetree/bindings/hwmon/aspeed-pwm-tacho.txt
create mode 100644 Documentation/hwmon/aspeed-pwm-tacho
create mode 100644 drivers/hwmon/aspeed-pwm-tacho.c
--
2.11.0.390.gc69c2f50cf-goog
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 0/5] Reset Controller Nodes for TI Keystone platforms
From: Santosh Shilimkar @ 2017-01-09 20:08 UTC (permalink / raw)
To: Suman Anna, Santosh Shilimkar
Cc: devicetree, Russell King, linux-kernel, Rob Herring,
Philipp Zabel, Andrew Davis, linux-arm-kernel
In-Reply-To: <20170109194358.27271-1-s-anna@ti.com>
On 1/9/2017 11:43 AM, Suman Anna wrote:
> Hi Santosh,
>
> This patch adds the reset controller nodes and the corresponding
> reset data for TI Keystone 66AK2H, 66AK2L and 66AK2E SoCs. These
> resets are for the DSPs on these SoCs, and are the last dependencies
> before the keystone remoteproc driver can be added.
>
> All these SoCs will use the ti-syscon-reset driver which is already
> part of mainline kernel. The bindings for the same can be found in
> Documentation/devicetree/bindings/reset/ti-syscon-reset.txt file.
> Note that the other Keystone 66AK2G SoC will use a different TI-SCI
> based reset driver, so will be submitted separately once the TI-SCI
> dependencies make it into mainline.
>
> Patches are based on top of 4.10-rc1 plus the MSM-RAM DT node series
> that you have already picked up. Patch 1 enable the Reset Framework
> for Keystone platforms, and remaining patches add the required DT
> nodes.
>
Ok. I will let this series be on list for a week or so for any
comments. After that will pick this up and push it out to next.
Regards,
Santosh
^ permalink raw reply
* Re: [PATCH v2 2/3] gpio: Add gpio driver support for ThunderX and OCTEON-TX
From: David Daney @ 2017-01-09 20:02 UTC (permalink / raw)
To: Linus Walleij, David Daney
Cc: Alexandre Courbot, Rob Herring, Mark Rutland,
linux-gpio@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, David Daney, Marc Zyngier
In-Reply-To: <CACRpkdaOQM7=mDTA1K92N5P=jjaCyhsSw5DGL+bnXE_GOYw82Q@mail.gmail.com>
On 01/09/2017 11:35 AM, Linus Walleij wrote:
> On Sat, Jan 7, 2017 at 12:22 AM, David Daney <ddaney.cavm@gmail.com> wrote:
>
>> From: David Daney <david.daney@cavium.com>
>>
>> Cavium ThunderX and OCTEON-TX are arm64 based SoCs. Add driver for
>> the on-chip GPIO pins.
>>
>> Signed-off-by: David Daney <david.daney@cavium.com>
>
> (...)
>> +config GPIO_THUNDERX
>> + tristate "Cavium ThunderX/OCTEON-TX GPIO"
>
> Do you really load this as module? OK then...
The driver does work when loaded as a module. I have tested loading and
unloading it many times.
>
>> +#include <linux/gpio.h>
>
> No.
> #include <linux/gpio/driver.h>
>
> Nothing else.
Right, I will fix that.
>
>> +#define GLITCH_FILTER_400NS ((4ull << GPIO_BIT_CFG_FIL_SEL_SHIFT) | \
>> + (9ull << GPIO_BIT_CFG_FIL_CNT_SHIFT))
>> +
>> +static unsigned int bit_cfg_reg(unsigned int line)
>> +{
>> + return 8 * line + GPIO_BIT_CFG;
>> +}
>> +
>> +static unsigned int intr_reg(unsigned int line)
>> +{
>> + return 8 * line + GPIO_INTR;
>> +}
>
> This looks a bit overzealous, but OK.
>
>> +struct thunderx_gpio;
>> +
>> +struct thunderx_irqdev {
>> + struct thunderx_gpio *gpio;
>> + char *name;
>> + unsigned int line;
>> +};
>> +
>> +struct thunderx_gpio {
>> + struct gpio_chip chip;
>> + u8 __iomem *register_base;
>> + struct msix_entry *msix_entries;
>> + struct thunderx_irqdev *irqdev_entries;
>> + raw_spinlock_t lock;
>> + unsigned long invert_mask[2];
>> + unsigned long od_mask[2];
>> + int base_msi;
>> +};
>
> Why can't you just move the thunderx_irqdev fields
> into thunderx_gpio?
There is a variable length array of them. It is not a single instance
of the structure. Same for the msix_entries.
> It will save very little memory for
> non-irq systems, I do not think footprint warrants it.
>
>> +
>> +static bool thunderx_gpio_is_gpio(struct thunderx_gpio *gpio,
>> + unsigned int line)
>> +{
>> + u64 bit_cfg = readq(gpio->register_base + bit_cfg_reg(line));
>> + bool rv = (bit_cfg & GPIO_BIT_CFG_PIN_SEL_MASK) == 0;
>> +
>> + WARN_RATELIMIT(!rv, "Pin %d not available for GPIO\n", line);
>> +
>> + return rv;
>> +}
>
> Nifty. So this actually has a pin controller back-end?
The hardware does function like a "pin controller"
> I haven't seen the code for that yet, I think.
>
> This seems like a cheap version of
>
> /* External interface to pin control */
> extern int pinctrl_request_gpio(unsigned gpio);
> extern void pinctrl_free_gpio(unsigned gpio);
> extern int pinctrl_gpio_direction_input(unsigned gpio);
> extern int pinctrl_gpio_direction_output(unsigned gpio);
>
> From <linux/pinctrl/consumer.h>
>
> So are you planning pin control support separately in drivers/pinctrl/*
> in the future?
Not at this time. Currently early boot firmware is programming the pin
functions, and we don't see a need to move the complexity of pinctrl
into the kernel, especially as there is not really any ACPI support for
pinctrl at this point, and we must also support ACPI.
> Maybe some comment to replace this with proper pin control
> in the future is warranted?
>
Good idea. I will add a comment about this.
>> +static int thunderx_gpio_dir_in(struct gpio_chip *chip, unsigned int line)
>> +{
>> + struct thunderx_gpio *gpio = container_of(chip, struct thunderx_gpio, chip);
>
> 1. Please use gpiochip_get_data() instead of the container_of() construction,
> utilized devm_gpiochip_add_data() in your probe() call.
>
> 2. Do not call this local variable "gpio" that is superconfusing, at least call
> it txgpio or something.
>
> 1 & 2 applies EVERYWHERE in thid driver.
OK, I will make that change for the next revision of the patch set.
>
>> +static void thunderx_gpio_set(struct gpio_chip *chip, unsigned int line,
>> + int value)
>> +{
>> + struct thunderx_gpio *gpio = container_of(chip, struct thunderx_gpio, chip);
>> + int bank = line / 64;
>> + int bank_bit = line % 64;
>> +
>> + void __iomem *reg = gpio->register_base +
>> + (bank * GPIO_2ND_BANK) + (value ? GPIO_TX_SET : GPIO_TX_CLR);
>> +
>> + writeq(1ull << bank_bit, reg);
>
> Use this:
>
> #include <linus/bitops.h>
>
> writeq(BIT(bank_bit), reg);
>
> Applies EVERYWHERE you use (1ULL << n)
OK.
>
>> +static int thunderx_gpio_set_single_ended(struct gpio_chip *chip,
>> + unsigned int line,
>> + enum single_ended_mode mode)
>
> Thanks for implementing this properly.
>
>> + read_bits >>= bank_bit;
>> +
>> + if (test_bit(line, gpio->invert_mask))
>> + return !(read_bits & 1);
>> + else
>> + return read_bits & 1;
>
> This looks superconvoluted.
>
> Can't you just:
>
> if (test_bit(line, gpio->invert_mask))
> return !(read_bits & BIT(bank_bit));
> else
> return !!(read_bits & BIT(bank_bit));
>
> OK maybe not much clearer but seems clearer to me.
As I really dislike the "!!" idiom, would you settle for:
if (test_bit(line, gpio->invert_mask))
return (read_bits & BIT(bank_bit)) == 0;
else
return (read_bits & BIT(bank_bit)) != 0;
>
>> +static int thunderx_gpio_irq_request_resources(struct irq_data *data)
>> +{
>> + struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
>> + struct thunderx_gpio *gpio = container_of(chip, struct thunderx_gpio, chip);
>> + unsigned int line = data->hwirq;
>> + struct thunderx_irqdev *irqdev;
>> + int err;
>> +
>> + if (!thunderx_gpio_is_gpio(gpio, line))
>> + return -EIO;
>> +
>> + irqdev = gpio->irqdev_entries + line;
>> +
>> + irqdev->gpio = gpio;
>> + irqdev->line = line;
>> + irqdev->name = devm_kasprintf(chip->parent, GFP_KERNEL,
>> + "gpio-%d", line + chip->base);
>> +
>> + writeq(GPIO_INTR_ENA_W1C, gpio->register_base + intr_reg(line));
>> +
>> + err = devm_request_irq(chip->parent, gpio->msix_entries[line].vector,
>> + thunderx_gpio_chain_handler, IRQF_NO_THREAD, irqdev->name, irqdev);
>> + return err;
>> +}
>> +
>> +static void thunderx_gpio_irq_release_resources(struct irq_data *data)
>> +{
>> + struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
>> + struct thunderx_gpio *gpio = container_of(chip, struct thunderx_gpio, chip);
>> + unsigned int line = data->hwirq;
>> + struct thunderx_irqdev *irqdev;
>> +
>> + irqdev = gpio->irqdev_entries + line;
>> +
>> + /*
>> + * The request_resources/release_resources functions may be
>> + * called multiple times in the lifitime of the driver, so we
>> + * need to clean up the devm_* things to avoid a resource
>> + * leak.
>> + */
>> + devm_free_irq(chip->parent, gpio->msix_entries[line].vector, irqdev);
>> +
>> + writeq(GPIO_INTR_ENA_W1C, gpio->register_base + intr_reg(line));
>> +
>> + devm_kfree(chip->parent, irqdev->name);
>> +}
>
> Then just do not use the devm* variants. Explicitly allocate and free instead.
>
> These callbacks should be called on all resources anyways.
Rithe.
>
>> +static void thunderx_gpio_irq_unmask(struct irq_data *data)
>> +{
>> + struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
>> + struct thunderx_gpio *gpio = container_of(chip, struct thunderx_gpio, chip);
>> + unsigned int line = data->hwirq;
>> +
>> + writeq(GPIO_INTR_ENA_W1S, gpio->register_base + intr_reg(line));
>> +}
>> +
>> +static int thunderx_gpio_irq_set_type(struct irq_data *data,
>> + unsigned int flow_type)
>> +{
>> + struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
>> + struct thunderx_gpio *gpio = container_of(chip, struct thunderx_gpio, chip);
>> + unsigned int line = data->hwirq;
>> + u64 bit_cfg;
>> +
>> + irqd_set_trigger_type(data, flow_type);
>> +
>> + bit_cfg = GLITCH_FILTER_400NS | GPIO_BIT_CFG_INT_EN;
>> +
>> + if (flow_type & IRQ_TYPE_EDGE_BOTH) {
>> + irq_set_handler_locked(data, handle_edge_irq);
>> + bit_cfg |= GPIO_BIT_CFG_INT_TYPE;
>> + } else {
>> + irq_set_handler_locked(data, handle_level_irq);
>> + }
>> +
>> + raw_spin_lock(&gpio->lock);
>> + if (flow_type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_LEVEL_LOW)) {
>> + bit_cfg |= GPIO_BIT_CFG_PIN_XOR;
>> + set_bit(line, gpio->invert_mask);
>> + } else {
>> + clear_bit(line, gpio->invert_mask);
>> + }
>> + clear_bit(line, gpio->od_mask);
>> + writeq(bit_cfg, gpio->register_base + bit_cfg_reg(line));
>> + raw_spin_unlock(&gpio->lock);
>> +
>> + return IRQ_SET_MASK_OK;
>> +}
>> +
>> +/*
>> + * Interrupts are chained from underlying MSI-X vectors. We have
>> + * these irq_chip functions to be able to handle level triggering
>> + * semantics and other acknowledgment tasks associated with the GPIO
>> + * mechanism.
>> + */
>> +static struct irq_chip thunderx_gpio_irq_chip = {
>> + .name = "GPIO",
>> + .irq_enable = thunderx_gpio_irq_unmask,
>> + .irq_disable = thunderx_gpio_irq_mask,
>> + .irq_ack = thunderx_gpio_irq_ack,
>> + .irq_mask = thunderx_gpio_irq_mask,
>> + .irq_mask_ack = thunderx_gpio_irq_mask_ack,
>> + .irq_unmask = thunderx_gpio_irq_unmask,
>> + .irq_set_type = thunderx_gpio_irq_set_type,
>> + .irq_request_resources = thunderx_gpio_irq_request_resources,
>> + .irq_release_resources = thunderx_gpio_irq_release_resources,
>> + .flags = IRQCHIP_SET_TYPE_MASKED
>> +};
>
> This looks wrong.
>
> If you're calling devm_request_irq() on *every* *single* *irq* like you
> do here, you are dealing with a hieararchical irqdomain, not a linear one,
> and GPIOLIB_IRQCHIP may not be used.
>
> Look at drivers/gpio/gpio-xgene-sb.c for inspiration. That is the only
> hierarchical GPIO irqdomain I have right now.
>
> Consult Marc Zyngier's IRQ domain lecture if you have time:
> https://www.youtube.com/watch?v=YE8cRHVIM4E
>
> If you have ideas how to combine hierarchical irqdomain and GPIOLIB_IRQCHIP
> pls help out.
>
>> + gpio->irqdev_entries = devm_kzalloc(dev,
>> + sizeof(struct thunderx_irqdev) * ngpio,
>> + GFP_KERNEL);
>> + if (!gpio->irqdev_entries) {
>> + err = -ENOMEM;
>> + goto out;
>> + }
>
> I think this is overkill. Use hierarchical irqdomain.
I will look into it. I suspect it will require more lines of driver
code to implement it than what I have here (that does actually work).
Thanks for looking at this,
David
^ permalink raw reply
* Applied "ASoC: sun4i-codec: Add "Right Mixer" to "Line Out Mono Diff." route" to the asoc tree
From: Mark Brown @ 2017-01-09 20:01 UTC (permalink / raw)
To: Chen-Yu Tsai; +Cc: Maxime Ripard, Mark Brown, Liam Girdwood
In-Reply-To: <20161107100703.5586-4-wens-jdAy2FN1RRM@public.gmane.org>
The patch
ASoC: sun4i-codec: Add "Right Mixer" to "Line Out Mono Diff." route
has been applied to the asoc tree at
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
>From 19426bdedb72b965db0ebf2106e95e9eeb3b5935 Mon Sep 17 00:00:00 2001
From: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
Date: Sun, 8 Jan 2017 02:57:06 +0800
Subject: [PATCH] ASoC: sun4i-codec: Add "Right Mixer" to "Line Out Mono Diff."
route
The mono differential output for "Line Out" downmixes the stereo audio
from the mixer, instead of just taking the left channel.
Add a route from the "Right Mixer" to "Line Out Source Playback Route"
through the "Mono Differential" path, so DAPM doesn't shut down
everything if the left channel is muted.
Fixes: 0f909f98d7cb ("ASoC: sun4i-codec: Add support for A31 Line Out
playback")
Signed-off-by: Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>
Acked-by: Maxime Ripard <maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Signed-off-by: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
---
sound/soc/sunxi/sun4i-codec.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
index 848af01692a0..c3aab10fa085 100644
--- a/sound/soc/sunxi/sun4i-codec.c
+++ b/sound/soc/sunxi/sun4i-codec.c
@@ -1058,6 +1058,7 @@ static const struct snd_soc_dapm_route sun6i_codec_codec_dapm_routes[] = {
{ "Line Out Source Playback Route", "Stereo", "Left Mixer" },
{ "Line Out Source Playback Route", "Stereo", "Right Mixer" },
{ "Line Out Source Playback Route", "Mono Differential", "Left Mixer" },
+ { "Line Out Source Playback Route", "Mono Differential", "Right Mixer" },
{ "LINEOUT", NULL, "Line Out Source Playback Route" },
/* ADC Routes */
--
2.11.0
^ permalink raw reply related
* Re: [PATCH v2 1/3] dt-bindings: gpio: Add binding documentation for gpio-thunderx
From: David Daney @ 2017-01-09 19:44 UTC (permalink / raw)
To: Linus Walleij, David Daney
Cc: Alexandre Courbot, Rob Herring, Mark Rutland,
linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, David Daney
In-Reply-To: <CACRpkdZ0xkhUC7_0A4uHxpGaU7BHgNp8TNuDPuPN9h6dDsQx4g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On 01/09/2017 11:36 AM, Linus Walleij wrote:
> On Sat, Jan 7, 2017 at 12:22 AM, David Daney <ddaney.cavm-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>
>> From: David Daney <david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
>>
>> Signed-off-by: David Daney <david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
> (...)
>
>> +Optional Properties:
>> +- compatible: "cavium,thunder-8890-gpio", unused as PCI driver binding is used.
>> +- interrupt-controller: Marks the device node as an interrupt controller.
>> +- #interrupt-cells: Must be present and have value of 2 if
>> + "interrupt-controller" is present.
>> + - First cell is the GPIO pin number relative to the controller.
>> + - Second cell is triggering flags as defined in interrupts.txt.
>
> AFAICT this device has an optional list of interrupts as well?
> One per pin even?
I'm not sure I understand your question.
The GPIO hardware supports an interrupt on each pin. The underlying
interrupt mechanism is via PCI MSI-X, which are fully discoverable by
the driver, so lack of device tree binding for the these underlying
MSI-X is fully appropriate. On the other hand, users of the GPIO
interrupt pins need this "interrupt-controller" and "#interrupt-cells"
to be able to properly find and configure the proper interrupts.
I said the "interrupt-controller" property was optional, because some
systems don't use GPIO interrupts and can function without specifying
that it is also an interrupt controller.
>
> Yours,
> Linus Walleij
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH 5/5] ARM: dts: keystone-k2e: Add PSC reset controller node
From: Suman Anna @ 2017-01-09 19:43 UTC (permalink / raw)
To: Santosh Shilimkar
Cc: Philipp Zabel, Rob Herring, Russell King,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Andrew Davis, Suman Anna
In-Reply-To: <20170109194358.27271-1-s-anna-l0cyMroinI0@public.gmane.org>
The Power Sleep Controller (PSC) module contains specific
memory-mapped registers that can be used to perform reset
management using specific bits for the DSPs available on the
SoC. The PSC is defined using a syscon node, and the reset
functionality is defined using a child syscon reset controller
node.
Add this syscon reset controller node as well as the reset
control data for the resets it supports for the 66AK2E SoCs.
Signed-off-by: Andrew F. Davis <afd-l0cyMroinI0@public.gmane.org>
Signed-off-by: Suman Anna <s-anna-l0cyMroinI0@public.gmane.org>
---
arch/arm/boot/dts/keystone-k2e.dtsi | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/arch/arm/boot/dts/keystone-k2e.dtsi b/arch/arm/boot/dts/keystone-k2e.dtsi
index 9d1d8a64d10e..c5983418c42c 100644
--- a/arch/arm/boot/dts/keystone-k2e.dtsi
+++ b/arch/arm/boot/dts/keystone-k2e.dtsi
@@ -8,6 +8,8 @@
* published by the Free Software Foundation.
*/
+#include <dt-bindings/reset/ti-syscon.h>
+
/ {
compatible = "ti,k2e", "ti,keystone";
model = "Texas Instruments Keystone 2 Edison SoC";
@@ -94,6 +96,17 @@
};
};
+ psc: power-sleep-controller@02350000 {
+ pscrst: psc-reset-controller {
+ compatible = "ti,k2e-pscrst", "ti,syscon-reset";
+ #reset-cells = <1>;
+
+ ti,reset-bits = <
+ 0xa3c 8 0xa3c 8 0x83c 8 (ASSERT_CLEAR | DEASSERT_SET | STATUS_CLEAR) /* 0: dsp0 */
+ >;
+ };
+ };
+
dspgpio0: keystone_dsp_gpio@02620240 {
compatible = "ti,keystone-dsp-gpio";
gpio-controller;
--
2.10.2
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 4/5] ARM: dts: keystone-k2l: Add PSC reset controller node
From: Suman Anna @ 2017-01-09 19:43 UTC (permalink / raw)
To: Santosh Shilimkar
Cc: devicetree, Russell King, linux-kernel, Rob Herring,
Philipp Zabel, Andrew Davis, linux-arm-kernel
In-Reply-To: <20170109194358.27271-1-s-anna@ti.com>
The Power Sleep Controller (PSC) module contains specific
memory-mapped registers that can be used to perform reset
management using specific bits for the DSPs available on the
SoC. The PSC is defined using a syscon node, and the reset
functionality is defined using a child syscon reset controller
node.
Add this syscon reset controller node as well as the reset
control data for the resets it supports for the 66AK2L SoCs.
Signed-off-by: Andrew F. Davis <afd@ti.com>
Signed-off-by: Suman Anna <s-anna@ti.com>
---
arch/arm/boot/dts/keystone-k2l.dtsi | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/arm/boot/dts/keystone-k2l.dtsi b/arch/arm/boot/dts/keystone-k2l.dtsi
index b58015737a35..4fa368f9ba52 100644
--- a/arch/arm/boot/dts/keystone-k2l.dtsi
+++ b/arch/arm/boot/dts/keystone-k2l.dtsi
@@ -8,6 +8,8 @@
* published by the Free Software Foundation.
*/
+#include <dt-bindings/reset/ti-syscon.h>
+
/ {
compatible = "ti,k2l", "ti,keystone";
model = "Texas Instruments Keystone 2 Lamarr SoC";
@@ -216,6 +218,20 @@
};
};
+ psc: power-sleep-controller@02350000 {
+ pscrst: psc-reset-controller {
+ compatible = "ti,k2l-pscrst", "ti,syscon-reset";
+ #reset-cells = <1>;
+
+ ti,reset-bits = <
+ 0xa3c 8 0xa3c 8 0x83c 8 (ASSERT_CLEAR | DEASSERT_SET | STATUS_CLEAR) /* 0: dsp0 */
+ 0xa40 8 0xa40 8 0x840 8 (ASSERT_CLEAR | DEASSERT_SET | STATUS_CLEAR) /* 1: dsp1 */
+ 0xa44 8 0xa44 8 0x844 8 (ASSERT_CLEAR | DEASSERT_SET | STATUS_CLEAR) /* 2: dsp2 */
+ 0xa48 8 0xa48 8 0x848 8 (ASSERT_CLEAR | DEASSERT_SET | STATUS_CLEAR) /* 3: dsp3 */
+ >;
+ };
+ };
+
dspgpio0: keystone_dsp_gpio@02620240 {
compatible = "ti,keystone-dsp-gpio";
gpio-controller;
--
2.10.2
^ 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