* [PATCH v3 2/2] regulator: add QCOM RPMh regulator driver
From: David Collins @ 2018-05-18 0:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAD=FV=UiZEFTAtO9C0UbRO=ow5=dv6zNG-XMqhHm1Fmp2GwVcA@mail.gmail.com>
On 05/17/2018 02:23 PM, Doug Anderson wrote:
> On Fri, May 11, 2018 at 7:28 PM, David Collins <collinsd@codeaurora.org> wrote:
>> + /*
>> + * Default the voltage selector to an error value in the
>> + * case that qcom,regulator-initial-microvolt is not
>> + * specified in device tree since the true voltage is
>> + * not known. Note that this value causes
>> + * devm_regulator_register() to fail in the case that
>> + * regulator-min-microvolt and regulator-max-microvolt
>> + * are specified in device tree due to
>> + * machine_constraints_voltage() bailing when the
>> + * get_voltage_sel() callback returns this error value.
>> + */
>> + vreg->voltage_selector = -EINVAL;
>
> As per comments in other threads, adjust this comment and use
> -ENOTRECOVERABLE now.
I'll make this change.
Take care,
David
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH] ARM: davinci_all_defconfig: set CONFIG_BACKLIGHT_PWM=m
From: Adam Ford @ 2018-05-18 0:43 UTC (permalink / raw)
To: linux-arm-kernel
The da850-evm came with an LCD with a backlight tied to a pwm. This
enables CONFIG_BACKLIGHT_PWM as a module so the PWM backlight can be
used to maintain brightness control of the backlight.
Note: make savedefconfig changed the order of one of the config options
Signed-off-by: Adam Ford <aford173@gmail.com>
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig
index 21b2d7791df4..63c5808a1055 100644
--- a/arch/arm/configs/davinci_all_defconfig
+++ b/arch/arm/configs/davinci_all_defconfig
@@ -7,9 +7,9 @@ CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
CONFIG_CGROUPS=y
-CONFIG_CHECKPOINT_RESTORE=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
+CONFIG_CHECKPOINT_RESTORE=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
@@ -153,6 +153,7 @@ CONFIG_TINYDRM_ST7586=m
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_DA8XX=y
+CONFIG_BACKLIGHT_PWM=m
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_LOGO=y
CONFIG_SOUND=m
--
2.17.0
^ permalink raw reply related
* [PATCH V4] ARM: dts: da850-evm: Enable LCD and Backlight
From: Adam Ford @ 2018-05-18 0:49 UTC (permalink / raw)
To: linux-arm-kernel
When using the board files the LCD works, but not with the DT.
This adds enables the original da850-evm to work with the same
LCD in device tree mode.
The EVM has a gpio for the regulator and a PWM for dimming the
backlight. The LCD and the vpif display pins are mutually
exclusive, so if using the LCD, do not load the vpif driver.
Signed-off-by: Adam Ford <aford173@gmail.com>
---
V4: Move the backlight to PWM, so the driver can control the regulator allowing the
regulator to power down and enabling the ability to change the brightness of the
backlight
V3: Fix errant GPIO, label GPIO pins, and rename the regulator to be more explict to
backlight which better matches the schematic. Updated the description to explain
that it cannot be used at the same time as the vpif driver.
V2: Add regulator and GPIO enable pins. Remove PWM backlight and replace with GPIO
diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts
index f6a5497d9c97..7be31372bbc2 100644
--- a/arch/arm/boot/dts/da850-evm.dts
+++ b/arch/arm/boot/dts/da850-evm.dts
@@ -27,9 +27,14 @@
spi0 = &spi1;
};
- backlight {
- compatible = "gpio-backlight";
- gpios = <&gpio 7 GPIO_ACTIVE_HIGH>; /* lcd_pwm0 */
+ backlight:backlight-pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ecap2_pins>;
+ power-supply = <&backlight_reg>;
+ compatible = "pwm-backlight";
+ pwms = <&ecap2 0 50000 0>;
+ brightness-levels = <0 10 20 30 40 50 60 70 80 90 99>;
+ default-brightness-level = <7>;
};
panel {
@@ -88,7 +93,6 @@
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
gpio = <&gpio 47 GPIO_ACTIVE_HIGH>; /* lcd_backlight_pwr */
- regulator-always-on;
enable-active-high;
};
@@ -120,6 +124,10 @@
};
};
+&ecap2 {
+ status = "okay";
+};
+
&pmx_core {
status = "okay";
--
2.17.0
^ permalink raw reply related
* [PATCH V5] ARM: dts: da850-evm: Enable LCD and Backlight
From: Adam Ford @ 2018-05-18 0:59 UTC (permalink / raw)
To: linux-arm-kernel
When using the board files the LCD works, but not with the DT.
This adds enables the original da850-evm to work with the same
LCD in device tree mode.
The EVM has a gpio for the regulator and a PWM for dimming the
backlight. The LCD and the vpif display pins are mutually
exclusive, so if using the LCD, do not load the vpif driver.
Signed-off-by: Adam Ford <aford173@gmail.com>
---
V5: Resync against v4.18/dt
V4: Move the backlight to PWM, so the driver can control the regulator allowing the
regulator to power down and enabling the ability to change the brightness of the
backlight
V3: Fix errant GPIO, label GPIO pins, and rename the regulator to be more explict to
backlight which better matches the schematic. Updated the description to explain
that it cannot be used at the same time as the vpif driver.
V2: Add regulator and GPIO enable pins. Remove PWM backlight and replace with GPIO
diff --git a/arch/arm/boot/dts/da850-evm.dts b/arch/arm/boot/dts/da850-evm.dts
index 0e82bb988fde..5bf6ea513b12 100644
--- a/arch/arm/boot/dts/da850-evm.dts
+++ b/arch/arm/boot/dts/da850-evm.dts
@@ -27,6 +27,58 @@
spi0 = &spi1;
};
+ backlight:backlight-pwm {
+ pinctrl-names = "default";
+ pinctrl-0 = <&ecap2_pins>;
+ power-supply = <&backlight_reg>;
+ compatible = "pwm-backlight";
+ pwms = <&ecap2 0 50000 0>;
+ brightness-levels = <0 10 20 30 40 50 60 70 80 90 99>;
+ default-brightness-level = <7>;
+ };
+
+ panel {
+ compatible = "ti,tilcdc,panel";
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pins>;
+ /* The vpif and the LCD are mutually exclusive.
+ * To enable VPIF, change the status below to 'disabled' then
+ * then change the status of the vpif below to 'okay' */
+ status = "okay";
+ enable-gpios = <&gpio 40 GPIO_ACTIVE_HIGH>; /* lcd_panel_pwr */
+
+ panel-info {
+ ac-bias = <255>;
+ ac-bias-intrpt = <0>;
+ dma-burst-sz = <16>;
+ bpp = <16>;
+ fdd = <0x80>;
+ sync-edge = <0>;
+ sync-ctrl = <1>;
+ raster-order = <0>;
+ fifo-th = <0>;
+ };
+
+ display-timings {
+ native-mode = <&timing0>;
+ timing0: 480x272 {
+ clock-frequency = <9000000>;
+ hactive = <480>;
+ vactive = <272>;
+ hfront-porch = <3>;
+ hback-porch = <2>;
+ hsync-len = <42>;
+ vback-porch = <3>;
+ vfront-porch = <4>;
+ vsync-len = <11>;
+ hsync-active = <0>;
+ vsync-active = <0>;
+ de-active = <1>;
+ pixelclk-active = <1>;
+ };
+ };
+ };
+
vbat: fixedregulator0 {
compatible = "regulator-fixed";
regulator-name = "vbat";
@@ -35,6 +87,15 @@
regulator-boot-on;
};
+ backlight_reg: backlight-regulator {
+ compatible = "regulator-fixed";
+ regulator-name = "lcd_backlight_pwr";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&gpio 47 GPIO_ACTIVE_HIGH>; /* lcd_backlight_pwr */
+ enable-active-high;
+ };
+
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "DA850/OMAP-L138 EVM";
@@ -63,6 +124,10 @@
};
};
+&ecap2 {
+ status = "okay";
+};
+
&pmx_core {
status = "okay";
@@ -109,6 +174,10 @@
status = "okay";
};
+&lcdc {
+ status = "okay";
+};
+
&i2c0 {
status = "okay";
clock-frequency = <100000>;
@@ -336,5 +405,8 @@
&vpif {
pinctrl-names = "default";
pinctrl-0 = <&vpif_capture_pins>, <&vpif_display_pins>;
- status = "okay";
+ /* The vpif and the LCD are mutually exclusive.
+ * To enable VPIF, disable the ti,tilcdc,panel then
+ * changed the status below to 'okay' */
+ status = "disabled";
};
--
2.17.0
^ permalink raw reply related
* [PATCH V2 1/3] clk: imx7d: correct enet phy ref clock gates
From: Anson Huang @ 2018-05-18 1:01 UTC (permalink / raw)
To: linux-arm-kernel
IMX7D_ENET_PHY_REF_ROOT_DIV supplies clock for PHY directly,
there is no clock gate after it, rename it to
IMX7D_ENET_PHY_REF_ROOT_CLK to avoid device tree change.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
drivers/clk/imx/clk-imx7d.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
index 975a20d..23d5090a 100644
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -738,7 +738,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_ENET1_TIME_ROOT_DIV] = imx_clk_divider2("enet1_time_post_div", "enet1_time_pre_div", base + 0xa780, 0, 6);
clks[IMX7D_ENET2_REF_ROOT_DIV] = imx_clk_divider2("enet2_ref_post_div", "enet2_ref_pre_div", base + 0xa800, 0, 6);
clks[IMX7D_ENET2_TIME_ROOT_DIV] = imx_clk_divider2("enet2_time_post_div", "enet2_time_pre_div", base + 0xa880, 0, 6);
- clks[IMX7D_ENET_PHY_REF_ROOT_DIV] = imx_clk_divider2("enet_phy_ref_post_div", "enet_phy_ref_pre_div", base + 0xa900, 0, 6);
+ clks[IMX7D_ENET_PHY_REF_ROOT_CLK] = imx_clk_divider2("enet_phy_ref_root_clk", "enet_phy_ref_pre_div", base + 0xa900, 0, 6);
clks[IMX7D_EIM_ROOT_DIV] = imx_clk_divider2("eim_post_div", "eim_pre_div", base + 0xa980, 0, 6);
clks[IMX7D_NAND_ROOT_CLK] = imx_clk_divider2("nand_root_clk", "nand_pre_div", base + 0xaa00, 0, 6);
clks[IMX7D_QSPI_ROOT_DIV] = imx_clk_divider2("qspi_post_div", "qspi_pre_div", base + 0xaa80, 0, 6);
@@ -816,7 +816,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate4("enet1_time_root_clk", "enet1_time_post_div", base + 0x44f0, 0);
clks[IMX7D_ENET2_REF_ROOT_CLK] = imx_clk_gate4("enet2_ref_root_clk", "enet2_ref_post_div", base + 0x4500, 0);
clks[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_gate4("enet2_time_root_clk", "enet2_time_post_div", base + 0x4510, 0);
- clks[IMX7D_ENET_PHY_REF_ROOT_CLK] = imx_clk_gate4("enet_phy_ref_root_clk", "enet_phy_ref_post_div", base + 0x4520, 0);
clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate4("eim_root_clk", "eim_post_div", base + 0x4160, 0);
clks[IMX7D_NAND_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_rawnand_clk", "nand_root_clk", base + 0x4140, 0, &share_count_nand);
clks[IMX7D_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_root_clk", base + 0x4140, 0, &share_count_nand);
--
2.7.4
^ permalink raw reply related
* [PATCH V2 2/3] clk: imx7d: correct enet clock CCGR registers
From: Anson Huang @ 2018-05-18 1:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526605266-18464-1-git-send-email-Anson.Huang@nxp.com>
Correct enet clock gates as below:
CCGR6: IMX7D_ENET_AXI_ROOT_CLK (enet1 and enet2 bus clocks)
CCGR112: IMX7D_ENET1_TIME_ROOT_CLK, IMX7D_ENET1_IPG_ROOT_CLK
CCGR113: IMX7D_ENET2_TIME_ROOT_CLK, IMX7D_ENET2_IPG_ROOT_CLK
Just rename unused IMX7D_ENETx_REF_ROOT_CLK for
IMX7D_ENETx_IPG_ROOT_CLK instead of adding new clocks.
Based on Andy Duan's patch from the NXP kernel tree.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
drivers/clk/imx/clk-imx7d.c | 10 ++++++----
include/dt-bindings/clock/imx7d-clock.h | 4 ++--
2 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
index 23d5090a..d4936b9 100644
--- a/drivers/clk/imx/clk-imx7d.c
+++ b/drivers/clk/imx/clk-imx7d.c
@@ -26,6 +26,8 @@ static u32 share_count_sai1;
static u32 share_count_sai2;
static u32 share_count_sai3;
static u32 share_count_nand;
+static u32 share_count_enet1;
+static u32 share_count_enet2;
static const struct clk_div_table test_div_table[] = {
{ .val = 3, .div = 1, },
@@ -805,6 +807,10 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate4("mipi_dsi_root_clk", "mipi_dsi_post_div", base + 0x4650, 0);
clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate4("mipi_csi_root_clk", "mipi_csi_post_div", base + 0x4640, 0);
clks[IMX7D_MIPI_DPHY_ROOT_CLK] = imx_clk_gate4("mipi_dphy_root_clk", "mipi_dphy_post_div", base + 0x4660, 0);
+ clks[IMX7D_ENET1_IPG_ROOT_CLK] = imx_clk_gate2_shared2("enet1_ipg_root_clk", "enet_axi_post_div", base + 0x4700, 0, &share_count_enet1);
+ clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate2_shared2("enet1_time_root_clk", "enet1_time_post_div", base + 0x4700, 0, &share_count_enet1);
+ clks[IMX7D_ENET2_IPG_ROOT_CLK] = imx_clk_gate2_shared2("enet2_ipg_root_clk", "enet_axi_post_div", base + 0x4710, 0, &share_count_enet2);
+ clks[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_gate2_shared2("enet2_time_root_clk", "enet2_time_post_div", base + 0x4710, 0, &share_count_enet2);
clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate2_shared2("sai1_root_clk", "sai1_post_div", base + 0x48c0, 0, &share_count_sai1);
clks[IMX7D_SAI1_IPG_CLK] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_root_clk", base + 0x48c0, 0, &share_count_sai1);
clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate2_shared2("sai2_root_clk", "sai2_post_div", base + 0x48d0, 0, &share_count_sai2);
@@ -812,10 +818,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate2_shared2("sai3_root_clk", "sai3_post_div", base + 0x48e0, 0, &share_count_sai3);
clks[IMX7D_SAI3_IPG_CLK] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_root_clk", base + 0x48e0, 0, &share_count_sai3);
clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate4("spdif_root_clk", "spdif_post_div", base + 0x44d0, 0);
- clks[IMX7D_ENET1_REF_ROOT_CLK] = imx_clk_gate4("enet1_ref_root_clk", "enet1_ref_post_div", base + 0x44e0, 0);
- clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate4("enet1_time_root_clk", "enet1_time_post_div", base + 0x44f0, 0);
- clks[IMX7D_ENET2_REF_ROOT_CLK] = imx_clk_gate4("enet2_ref_root_clk", "enet2_ref_post_div", base + 0x4500, 0);
- clks[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_gate4("enet2_time_root_clk", "enet2_time_post_div", base + 0x4510, 0);
clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate4("eim_root_clk", "eim_post_div", base + 0x4160, 0);
clks[IMX7D_NAND_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_rawnand_clk", "nand_root_clk", base + 0x4140, 0, &share_count_nand);
clks[IMX7D_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_root_clk", base + 0x4140, 0, &share_count_nand);
diff --git a/include/dt-bindings/clock/imx7d-clock.h b/include/dt-bindings/clock/imx7d-clock.h
index b2325d3e2..0d67f53 100644
--- a/include/dt-bindings/clock/imx7d-clock.h
+++ b/include/dt-bindings/clock/imx7d-clock.h
@@ -168,7 +168,7 @@
#define IMX7D_SPDIF_ROOT_SRC 155
#define IMX7D_SPDIF_ROOT_CG 156
#define IMX7D_SPDIF_ROOT_DIV 157
-#define IMX7D_ENET1_REF_ROOT_CLK 158
+#define IMX7D_ENET1_IPG_ROOT_CLK 158
#define IMX7D_ENET1_REF_ROOT_SRC 159
#define IMX7D_ENET1_REF_ROOT_CG 160
#define IMX7D_ENET1_REF_ROOT_DIV 161
@@ -176,7 +176,7 @@
#define IMX7D_ENET1_TIME_ROOT_SRC 163
#define IMX7D_ENET1_TIME_ROOT_CG 164
#define IMX7D_ENET1_TIME_ROOT_DIV 165
-#define IMX7D_ENET2_REF_ROOT_CLK 166
+#define IMX7D_ENET2_IPG_ROOT_CLK 166
#define IMX7D_ENET2_REF_ROOT_SRC 167
#define IMX7D_ENET2_REF_ROOT_CG 168
#define IMX7D_ENET2_REF_ROOT_DIV 169
--
2.7.4
^ permalink raw reply related
* [PATCH V2 3/3] ARM: dts: imx7: correct enet ipg clock
From: Anson Huang @ 2018-05-18 1:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526605266-18464-1-git-send-email-Anson.Huang@nxp.com>
ENET "ipg" clock should be IMX7D_ENETx_IPG_ROOT_CLK
rather than IMX7D_ENET_AXI_ROOT_CLK which is for ENET bus
clock.
Based on Andy Duan's patch from the NXP kernel tree.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
arch/arm/boot/dts/imx7d.dtsi | 2 +-
arch/arm/boot/dts/imx7s.dtsi | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/imx7d.dtsi b/arch/arm/boot/dts/imx7d.dtsi
index 200714e..d74dd7f 100644
--- a/arch/arm/boot/dts/imx7d.dtsi
+++ b/arch/arm/boot/dts/imx7d.dtsi
@@ -120,7 +120,7 @@
<GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
+ clocks = <&clks IMX7D_ENET2_IPG_ROOT_CLK>,
<&clks IMX7D_ENET_AXI_ROOT_CLK>,
<&clks IMX7D_ENET2_TIME_ROOT_CLK>,
<&clks IMX7D_PLL_ENET_MAIN_125M_CLK>,
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 4d42335..b90769d 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -1091,7 +1091,7 @@
<GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&clks IMX7D_ENET_AXI_ROOT_CLK>,
+ clocks = <&clks IMX7D_ENET1_IPG_ROOT_CLK>,
<&clks IMX7D_ENET_AXI_ROOT_CLK>,
<&clks IMX7D_ENET1_TIME_ROOT_CLK>,
<&clks IMX7D_PLL_ENET_MAIN_125M_CLK>,
--
2.7.4
^ permalink raw reply related
* [PATCH v3 1/2] regulator: dt-bindings: add QCOM RPMh regulator bindings
From: Doug Anderson @ 2018-05-18 1:01 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <869aad59-1cc5-28ef-1fb5-4ef846696c40@codeaurora.org>
Hi,
On Thu, May 17, 2018 at 5:16 PM, David Collins <collinsd@codeaurora.org> wrote:
> On 05/17/2018 02:22 PM, Doug Anderson wrote:
>> On Fri, May 11, 2018 at 7:28 PM, David Collins <collinsd@codeaurora.org> wrote:
>>> +- qcom,regulator-initial-microvolt
>>> + Usage: optional; VRM regulators only
>>> + Value type: <u32>
>>> + Definition: Specifies the initial voltage in microvolts to request for a
>>> + VRM regulator.
>>
>> Now that Mark has landed the patch adding support for the
>> -ENOTRECOVERABLE error code from get_voltage() / get_voltage_sel(), do
>> we still need the qcom,regulator-initial-microvolt property?
>
> Yes, this is still needed. The -ENOTRECOVERABLE patch ensures that
> qcom-rpmh-regulator devices can be registered even if
> qcom,regulator-initial-microvolt is not specified. However, that will
> result in the regulators being configured for the minimum voltage
> supported in the DT specified min/max range. The
> qcom,regulator-initial-microvolt property allows us to set a specific
> voltage that is larger than the min constraint.
Ah, OK. In the device tree fragment I saw the initial was always
equal to the min, so I wasn't sure if this was really needed in
practice. I presume it would only be important if a voltage was left
high by the bootloader for some peripheral that needs to continue to
function (and use the existing higher voltage) until a real device
claims it. For all other voltages, it should be fine if it's set to
the min until a real device claims it. Do you have real examples of
devices like this in boards using sdm845?
>> If this is really still needed, can it be moved to the regulator core?
>
> I'm not opposed to the idea, but I think that Mark is [1]:
Oh right. The downside of weeks between spins I guess. If Mark is
fine with the private property I won't fight it.
>>> +- regulator-initial-mode
>>> + Usage: optional; VRM regulators only
>>> + Value type: <u32>
>>> + Definition: Specifies the initial mode to request for a VRM regulator.
>>> + Supported values are RPMH_REGULATOR_MODE_* which are defined
>>> + in [1] (i.e. 0 to 3). This property may be specified even
>>> + if the regulator-allow-set-load property is not specified.
>>
>> Every time I read the above I wonder why you're documenting a standard
>> regulator regulator property in your bindings. ...then I realize it's
>> because you're doing it because you want to explicitly document what
>> the valid modes are. I wonder if it makes sense to just put a
>> reference somewhere else in this document to go look at the header
>> file where these are all nicely documented.
>
> Isn't that what the [1] in the above snippet is currently doing. Further
> down in qcom,rpmh-regulator.txt is this line:
>
> +[1] include/dt-bindings/regulator/qcom,rpmh-regulator.h
Right, but I want to move it so it doesn't look like you're defining a
property that's already defined in the common bindings. AKA get rid
of the "regulator-initial-mode" property description. Then add above
Examples:
========================
Regulator Modes
========================
RPMh regulators are designed to work with the standard regulator mode
bindings, using properties like "regulator-initial-mode". See
include/dt-bindings/regulator/qcom,rpmh-regulator.h for information on
the modes relevant to RPMh regulators.
Some RPMh regulators (BOB regulators only) also support bypass using
the standard "regulator-allow-bypass" binding.
...feel fee to reword, but basically the idea is to document it but
not make it look like you're defining a novel property.
>> Speaking of documenting things like that, it might be worth finding
>> somewhere in this doc to mention that the "bob" regulator on PMI8998
>> can support "regulator-allow-bypass". That tidbit got lost when we
>> moved to the standard regulator bindings for bypass.
>
> I suppose that I could add something like this:
>
> +- regulator-allow-bypass
> + Usage: optional; BOB type VRM regulators only
> + Value type: <empty>
> + Definition: See [2] for details.
> ...
> +[2]: Documentation/devicetree/bindings/regulator.txt
>
> However, I don't want the patch to get NACKed because it is defining a
> property that is already defined in the common regulator.txt file.
See above for my suggestion.
>>> +- qcom,allowed-drms-modes
>>> + Usage: required if regulator-allow-set-load is specified;
>>> + VRM regulators only
>>> + Value type: <prop-encoded-array>
>>> + Definition: A list of integers specifying the PMIC regulator modes which
>>> + can be configured at runtime based upon consumer load needs.
>>> + Supported values are RPMH_REGULATOR_MODE_* which are defined
>>> + in [1] (i.e. 0 to 3).
>>
>> Why is this still here? You moved it to the core regulator framework,
>> right? It's still in your examples too. Shouldn't this be removed?
>> It looks like the driver still needs this and it needs to be an exact
>> duplicate of the common binding. That doesn't seem right...
>
> The qcom,allowed-drms-modes property supports a different feature than the
> regulator-allowed-modes property accepted in [2]. The latter specifies
> the modes that may be used at all (e.g. in regulator_set_mode() calls) and
> it lists the mode values in an unordered fashion.
>
> qcom,allowed-drms-modes defines a specific subset of the possible allowed
> modes that should be set based on DRMS (e.g. in regulator_set_load()
> calls). Its values are listed in a specific order and must match 1-to-1
> with qcom,drms-mode-max-microamps entries.
>
> It would probably be good to change the name of the property from
> qcom,allowed-drms-modes to qcom,regulator-drms-modes.
Ah, I see. It's unfortunate that now we need to effectively list all
modes twice. Have you seen real-life examples where these sets of
modes need to be different, or is this just theoretical? If not can
we start with one property (that controls both things) and if we
really see that we need to specify different sets of modes for the two
cases we can add a separate property? ...actually, even if you do
have real-life examples of where these need to be different, if 90% of
the time they are the same it would still be nice to just have one
property apply to both cases.
>>> +- qcom,drms-mode-max-microamps
>>> + Usage: required if regulator-allow-set-load is specified;
>>> + VRM regulators only
>>> + Value type: <prop-encoded-array>
>>> + Definition: A list of integers specifying the maximum allowed load
>>> + current in microamps for each of the modes listed in
>>> + qcom,allowed-drms-modes (matched 1-to-1 in order). Elements
>>> + must be specified in order from lowest to highest value.
>>
>> Any reason this can't go into the regulator core? You'd basically
>> just take the existing concept of rpmh_regulator_vrm_set_load() and
>> put it in the core.
>
> This could be implemented in the core via new constraint elements parsed
> in of_regulator and a helper function to specify in regulator_ops.
> However, I'm not sure about the wide-spread applicability of this feature.
> I'd prefer to leave it in the driver unless Mark would like me to add it
> into the core.
You're already using pre-existing APIs around specifying the current
and having the regulator core call you to map the total current into a
mode. That implies that this is applicable to others. Adding this
tiny amount of code to the core makes the pre-existing APIs generally
useful.
>>> +- qcom,headroom-microvolt
>>> + Usage: optional; VRM regulators only
>>> + Value type: <u32>
>>> + Definition: Specifies the headroom voltage in microvolts to request for
>>> + a VRM regulator. RPMh hardware automatically ensures that
>>> + the parent of this regulator outputs a voltage high enough
>>> + to satisfy the requested headroom. Supported values are
>>> + 0 to 511000.
>>
>> I'm curious: is this a voted-for value, or a global value?
>>
>> Said another way: the whole point of RPMh is that there may be more
>> than one processor that needs the same rails, right? So the AP might
>> request 1.1 V for a rail and the modem might request 1.3 V. RPMh
>> would decide to pick the higher of those two (1.3 V), but if the modem
>> said it no longer needs the rail it will drop down to 1.1 V.
>>
>> ...and as an example of why the headroom needs to be in hardware, if
>> the source voltage was normally 1.4 V and the headroom was 200 mV then
>> the hardware would need to know to bump up the source voltage to 1.5V
>> during the period of of time that the modem wants the rail at 1.3V.
>>
>> So my question is: do the AP and modem in the above situation
>> separately vote for headroom? How is it aggregated? ...or is it a
>> global value and this sets the headroom for all clients of RPMh? It
>> would be interesting to document this as it might help with figuring
>> out how this value should be set.
>
> The headroom voltage voting is supported in hardware per-regulator and
> per-master (AP, modem, etc). The headroom voltage and output voltage are
> each aggregated (using max) per-regulator across masters. If the
> aggregated enable state for a regulator is on, then the aggregated output
> voltage and headroom voltage are added together and applied as a min
> constraint on the parent's output voltage (if there is a parent).
Ah, interesting. I'm not 100% convinced that the RPMh API is at the
right abstraction level here. I guess you increase the headroom
voltage if you expect a lot of current and need the regulator to still
give a clean signal? If you truly wanted to aggregate then if both
the modem and AP wanted to draw a lot of current they would both need
to increase the headroom and then the headroom should maybe not be the
max but something slightly more (you wouldn't want to add, but ...)
Since it's just a max, in theory it seems like you get 99% of the way
there by just using the Linux APIs to deal with dropout voltage. If
Linux was managing it in software then if it needed to account for
extra headroom it would just increase the supply voltage. That should
play just fine with the modem (which might be using the hardware
headroom feature) since it will be making its own completely separate
requests and they should be aggregated OK.
In another thread you said you'd be OK dropping the headroom voltage
since it wasn't needed on SDM845. Maybe we should do that? ...and if
someone later needs to account for a larger dropout they can figure
out how to hookup the standard linux min_dropout_uV?
^ permalink raw reply
* [PATCH 1/2] clk: imx7d: correct enet clock CCGR register offset
From: Anson Huang @ 2018-05-18 1:06 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <96f2ab49e1a9c03ccd477346b8285c76@agner.ch>
Hi, Stefan
Anson Huang
Best Regards!
> -----Original Message-----
> From: Stefan Agner [mailto:stefan at agner.ch]
> Sent: Thursday, May 17, 2018 7:22 PM
> To: Anson Huang <anson.huang@nxp.com>
> Cc: shawnguo at kernel.org; kernel at pengutronix.de; Fabio Estevam
> <fabio.estevam@nxp.com>; robh+dt at kernel.org; mark.rutland at arm.com;
> mturquette at baylibre.com; sboyd at kernel.org; Adriana Reus
> <adriana.reus@nxp.com>; rui.silva at linaro.org; dl-linux-imx
> <linux-imx@nxp.com>; linux-arm-kernel at lists.infradead.org;
> devicetree at vger.kernel.org; linux-kernel at vger.kernel.org;
> linux-clk at vger.kernel.org
> Subject: Re: [PATCH 1/2] clk: imx7d: correct enet clock CCGR register offset
>
> On 17.05.2018 10:40, Anson Huang wrote:
> > Correct enet clock CCGR register offset.
> >
> > CCGR6: IMX7D_ENET_AXI_ROOT_CLK (enet1 and enet2 bus clocks)
> > CCGR112: IMX7D_ENET1_TIME_ROOT_CLK, IMX7D_ENET1_IPG_ROOT_CLK
> > CCGR113: IMX7D_ENET2_TIME_ROOT_CLK, IMX7D_ENET2_IPG_ROOT_CLK
> >
> > IMX7D_ENET_PHY_REF_ROOT_DIV supplies clock for PHY, no gate after this
> > clock, its parent clock root has gate.
> > IMX7D_ENET1_REF_ROOT_DIV/IMX7D_ENET2_REF_ROOT_DIV supplies
> clocks for
> > enet IPG_CLK_RMII, no gate after the clock, its parent clock root has
> > gate.
> >
> > IMX7D_PLL_ENET_MAIN_125M_CLK (anatop pll) supplies clock for enet
> > RGMII tx_clk.
>
> As far as I can tell there are two changes here in one patch:
>
> 1. The non existing IMX7D_ENET_PHY_REF_ROOT_CLK gate is removed
>
> 2. Shared clock gate for the enet time/ipg clock is taken into account.
>
>
> I would rather prefer to have separate patches. The device tree change also
> does two things, so this would lead to 4 patches total.
>
> We can avoid the device tree change for the PHY clk and even maintain
> backward compatibility for that part by renaming
> IMX7D_ENET_PHY_REF_ROOT_DIV to IMX7D_ENET_PHY_REF_ROOT_CLK.
>
>
> So this would end up with the following first patch to address the PHY_ROOT
> clock issue:
>
> --- a/drivers/clk/imx/clk-imx7d.c
> +++ b/drivers/clk/imx/clk-imx7d.c
> @@ -738,7 +738,7 @@ static void __init imx7d_clocks_init(struct device_node
> *ccm_node)
> clks[IMX7D_ENET1_TIME_ROOT_DIV] =
> imx_clk_divider2("enet1_time_post_div", "enet1_time_pre_div", base +
> 0xa780, 0, 6);
> clks[IMX7D_ENET2_REF_ROOT_DIV] =
> imx_clk_divider2("enet2_ref_post_div", "enet2_ref_pre_div", base + 0xa800, 0,
> 6);
> clks[IMX7D_ENET2_TIME_ROOT_DIV] =
> imx_clk_divider2("enet2_time_post_div", "enet2_time_pre_div", base +
> 0xa880, 0, 6);
> - clks[IMX7D_ENET_PHY_REF_ROOT_DIV] =
> imx_clk_divider2("enet_phy_ref_post_div", "enet_phy_ref_pre_div", base +
> 0xa900, 0, 6);
> + clks[IMX7D_ENET_PHY_REF_ROOT_CLK] =
> imx_clk_divider2("enet_phy_ref_root_clk", "enet_phy_ref_pre_div", base +
> 0xa900, 0, 6);
> clks[IMX7D_EIM_ROOT_DIV] = imx_clk_divider2("eim_post_div",
> "eim_pre_div", base + 0xa980, 0, 6);
> clks[IMX7D_NAND_ROOT_CLK] = imx_clk_divider2("nand_root_clk",
> "nand_pre_div", base + 0xaa00, 0, 6);
> clks[IMX7D_QSPI_ROOT_DIV] = imx_clk_divider2("qspi_post_div",
> "qspi_pre_div", base + 0xaa80, 0, 6); @@ -816,7 +816,6 @@ static void __init
> imx7d_clocks_init(struct device_node *ccm_node)
> clks[IMX7D_ENET1_TIME_ROOT_CLK] =
> imx_clk_gate4("enet1_time_root_clk", "enet1_time_post_div", base + 0x44f0,
> 0);
> clks[IMX7D_ENET2_REF_ROOT_CLK] =
> imx_clk_gate4("enet2_ref_root_clk", "enet2_ref_post_div", base + 0x4500, 0);
> clks[IMX7D_ENET2_TIME_ROOT_CLK] =
> imx_clk_gate4("enet2_time_root_clk", "enet2_time_post_div", base + 0x4510,
> 0);
> - clks[IMX7D_ENET_PHY_REF_ROOT_CLK] =
> imx_clk_gate4("enet_phy_ref_root_clk", "enet_phy_ref_post_div", base +
> 0x4520, 0);
> clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate4("eim_root_clk",
> "eim_post_div", base + 0x4160, 0);
> clks[IMX7D_NAND_RAWNAND_CLK] =
> imx_clk_gate2_shared2("nand_rawnand_clk", "nand_root_clk", base + 0x4140,
> 0, &share_count_nand);
> clks[IMX7D_NAND_USDHC_BUS_RAWNAND_CLK] =
> imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_root_clk",
> base + 0x4140, 0, &share_count_nand);
>
>
> A second patch would then fix the clock gate issue and the third the
> unavoidable device tree change for the ipg clock.
>
> --
> Stefan
I follow your suggestion and re-structure the patch set to 3 patches, please help review it, thanks!
Anson.
>
>
> >
> > Based on Andy Duan's patch from the NXP kernel tree.
> >
> > Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
> > ---
> > drivers/clk/imx/clk-imx7d.c | 11 ++++++-----
> > include/dt-bindings/clock/imx7d-clock.h | 4 +++-
> > 2 files changed, 9 insertions(+), 6 deletions(-)
> >
> > diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
> > index 975a20d..485ab49 100644
> > --- a/drivers/clk/imx/clk-imx7d.c
> > +++ b/drivers/clk/imx/clk-imx7d.c
> > @@ -26,6 +26,8 @@ static u32 share_count_sai1; static u32
> > share_count_sai2; static u32 share_count_sai3; static u32
> > share_count_nand;
> > +static u32 share_count_enet1;
> > +static u32 share_count_enet2;
> >
> > static const struct clk_div_table test_div_table[] = {
> > { .val = 3, .div = 1, },
> > @@ -805,6 +807,10 @@ static void __init imx7d_clocks_init(struct
> > device_node *ccm_node)
> > clks[IMX7D_MIPI_DSI_ROOT_CLK] = imx_clk_gate4("mipi_dsi_root_clk",
> > "mipi_dsi_post_div", base + 0x4650, 0);
> > clks[IMX7D_MIPI_CSI_ROOT_CLK] = imx_clk_gate4("mipi_csi_root_clk",
> > "mipi_csi_post_div", base + 0x4640, 0);
> > clks[IMX7D_MIPI_DPHY_ROOT_CLK] =
> imx_clk_gate4("mipi_dphy_root_clk",
> > "mipi_dphy_post_div", base + 0x4660, 0);
> > + clks[IMX7D_ENET1_IPG_ROOT_CLK] =
> > imx_clk_gate2_shared2("enet1_ipg_root_clk", "enet_axi_post_div", base
> > + 0x4700, 0, &share_count_enet1);
> > + clks[IMX7D_ENET1_TIME_ROOT_CLK] =
> > imx_clk_gate2_shared2("enet1_time_root_clk", "enet1_time_post_div",
> > base + 0x4700, 0, &share_count_enet1);
> > + clks[IMX7D_ENET2_IPG_ROOT_CLK] =
> > imx_clk_gate2_shared2("enet2_ipg_root_clk", "enet_axi_post_div", base
> > + 0x4710, 0, &share_count_enet2);
> > + clks[IMX7D_ENET2_TIME_ROOT_CLK] =
> > imx_clk_gate2_shared2("enet2_time_root_clk", "enet2_time_post_div",
> > base + 0x4710, 0, &share_count_enet2);
> > clks[IMX7D_SAI1_ROOT_CLK] = imx_clk_gate2_shared2("sai1_root_clk",
> > "sai1_post_div", base + 0x48c0, 0, &share_count_sai1);
> > clks[IMX7D_SAI1_IPG_CLK] = imx_clk_gate2_shared2("sai1_ipg_clk",
> > "ipg_root_clk", base + 0x48c0, 0, &share_count_sai1);
> > clks[IMX7D_SAI2_ROOT_CLK] = imx_clk_gate2_shared2("sai2_root_clk",
> > "sai2_post_div", base + 0x48d0, 0, &share_count_sai2); @@ -812,11
> > +818,6 @@ static void __init imx7d_clocks_init(struct device_node
> > *ccm_node)
> > clks[IMX7D_SAI3_ROOT_CLK] = imx_clk_gate2_shared2("sai3_root_clk",
> > "sai3_post_div", base + 0x48e0, 0, &share_count_sai3);
> > clks[IMX7D_SAI3_IPG_CLK] = imx_clk_gate2_shared2("sai3_ipg_clk",
> > "ipg_root_clk", base + 0x48e0, 0, &share_count_sai3);
> > clks[IMX7D_SPDIF_ROOT_CLK] = imx_clk_gate4("spdif_root_clk",
> > "spdif_post_div", base + 0x44d0, 0);
> > - clks[IMX7D_ENET1_REF_ROOT_CLK] =
> imx_clk_gate4("enet1_ref_root_clk",
> > "enet1_ref_post_div", base + 0x44e0, 0);
> > - clks[IMX7D_ENET1_TIME_ROOT_CLK] =
> > imx_clk_gate4("enet1_time_root_clk", "enet1_time_post_div", base +
> > 0x44f0, 0);
> > - clks[IMX7D_ENET2_REF_ROOT_CLK] =
> imx_clk_gate4("enet2_ref_root_clk",
> > "enet2_ref_post_div", base + 0x4500, 0);
> > - clks[IMX7D_ENET2_TIME_ROOT_CLK] =
> > imx_clk_gate4("enet2_time_root_clk", "enet2_time_post_div", base +
> > 0x4510, 0);
> > - clks[IMX7D_ENET_PHY_REF_ROOT_CLK] =
> > imx_clk_gate4("enet_phy_ref_root_clk", "enet_phy_ref_post_div", base +
> > 0x4520, 0);
> > clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate4("eim_root_clk",
> > "eim_post_div", base + 0x4160, 0);
> > clks[IMX7D_NAND_RAWNAND_CLK] =
> > imx_clk_gate2_shared2("nand_rawnand_clk", "nand_root_clk", base +
> > 0x4140, 0, &share_count_nand);
> > clks[IMX7D_NAND_USDHC_BUS_RAWNAND_CLK] =
> > imx_clk_gate2_shared2("nand_usdhc_rawnand_clk",
> "nand_usdhc_root_clk",
> > base + 0x4140, 0, &share_count_nand); diff --git
> > a/include/dt-bindings/clock/imx7d-clock.h
> > b/include/dt-bindings/clock/imx7d-clock.h
> > index b2325d3e2..fef0647 100644
> > --- a/include/dt-bindings/clock/imx7d-clock.h
> > +++ b/include/dt-bindings/clock/imx7d-clock.h
> > @@ -455,5 +455,7 @@
> > #define IMX7D_SNVS_CLK 442
> > #define IMX7D_CAAM_CLK 443
> > #define IMX7D_KPP_ROOT_CLK 444
> > -#define IMX7D_CLK_END 445
> > +#define IMX7D_ENET1_IPG_ROOT_CLK 445
> > +#define IMX7D_ENET2_IPG_ROOT_CLK 446
> > +#define IMX7D_CLK_END 447
> > #endif /* __DT_BINDINGS_CLOCK_IMX7D_H */
^ permalink raw reply
* [PATCH 1/6] coresight: remove CORESIGHT_LINKS_AND_SINKS dependencies and selections
From: Kim Phillips @ 2018-05-18 1:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180517070643.GC13919@kroah.com>
A coresight topology doesn't need to include links, i.e., a source can
be directly connected to a sink. As such, selecting and/or depending on
LINKS_AND_SINKS is no longer needed.
Suggested-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Kim Phillips <kim.phillips@arm.com>
---
drivers/hwtracing/coresight/Kconfig | 7 -------
1 file changed, 7 deletions(-)
diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index ef9cb3c164e1..83fb78651ef9 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -23,7 +23,6 @@ config CORESIGHT_LINKS_AND_SINKS
config CORESIGHT_LINK_AND_SINK_TMC
bool "Coresight generic TMC driver"
- depends on CORESIGHT_LINKS_AND_SINKS
help
This enables support for the Trace Memory Controller driver.
Depending on its configuration the device can act as a link (embedded
@@ -33,7 +32,6 @@ config CORESIGHT_LINK_AND_SINK_TMC
config CORESIGHT_SINK_TPIU
bool "Coresight generic TPIU driver"
- depends on CORESIGHT_LINKS_AND_SINKS
help
This enables support for the Trace Port Interface Unit driver,
responsible for bridging the gap between the on-chip coresight
@@ -44,7 +42,6 @@ config CORESIGHT_SINK_TPIU
config CORESIGHT_SINK_ETBV10
bool "Coresight ETBv1.0 driver"
- depends on CORESIGHT_LINKS_AND_SINKS
help
This enables support for the Embedded Trace Buffer version 1.0 driver
that complies with the generic implementation of the component without
@@ -53,7 +50,6 @@ config CORESIGHT_SINK_ETBV10
config CORESIGHT_SOURCE_ETM3X
bool "CoreSight Embedded Trace Macrocell 3.x driver"
depends on !ARM64
- select CORESIGHT_LINKS_AND_SINKS
help
This driver provides support for processor ETM3.x and PTM1.x modules,
which allows tracing the instructions that a processor is executing
@@ -63,7 +59,6 @@ config CORESIGHT_SOURCE_ETM3X
config CORESIGHT_SOURCE_ETM4X
bool "CoreSight Embedded Trace Macrocell 4.x driver"
depends on ARM64
- select CORESIGHT_LINKS_AND_SINKS
help
This driver provides support for the ETM4.x tracer module, tracing the
instructions that a processor is executing. This is primarily useful
@@ -72,7 +67,6 @@ config CORESIGHT_SOURCE_ETM4X
config CORESIGHT_DYNAMIC_REPLICATOR
bool "CoreSight Programmable Replicator driver"
- depends on CORESIGHT_LINKS_AND_SINKS
help
This enables support for dynamic CoreSight replicator link driver.
The programmable ATB replicator allows independent filtering of the
@@ -81,7 +75,6 @@ config CORESIGHT_DYNAMIC_REPLICATOR
config CORESIGHT_STM
bool "CoreSight System Trace Macrocell driver"
depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
- select CORESIGHT_LINKS_AND_SINKS
select STM
help
This driver provides support for hardware assisted software
--
2.17.0
^ permalink raw reply related
* [PATCH 2/6] coresight: fix CORESIGHT_STM -- STM dependency
From: Kim Phillips @ 2018-05-18 1:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518012024.22645-1-kim.phillips@arm.com>
coresight-stm unconditionally calls stm_register_device. This
patch makes it therefore depend on STM instead of just selecting STM.
Signed-off-by: Kim Phillips <kim.phillips@arm.com>
---
drivers/hwtracing/coresight/Kconfig | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index 83fb78651ef9..f9abdef5b0d9 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -74,8 +74,7 @@ config CORESIGHT_DYNAMIC_REPLICATOR
config CORESIGHT_STM
bool "CoreSight System Trace Macrocell driver"
- depends on (ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64
- select STM
+ depends on STM && ((ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64)
help
This driver provides support for hardware assisted software
instrumentation based tracing. This is primarily used for
--
2.17.0
^ permalink raw reply related
* [PATCH 3/6] coresight: use IS_ENABLED for CONFIGs that may be modules
From: Kim Phillips @ 2018-05-18 1:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518012024.22645-1-kim.phillips@arm.com>
Checking for CONFIG_x fails if CONFIG_x=m, use IS_ENABLED that is
true for built-ins and modules instead. Required when building
various coresight components as modules.
Signed-off-by: Kim Phillips <kim.phillips@arm.com>
---
drivers/hwtracing/coresight/coresight-etm-perf.h | 2 +-
drivers/hwtracing/coresight/coresight-priv.h | 2 +-
include/linux/coresight.h | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.h b/drivers/hwtracing/coresight/coresight-etm-perf.h
index 4197df4faf5e..539b250df455 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.h
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.h
@@ -43,7 +43,7 @@ struct etm_filters {
};
-#ifdef CONFIG_CORESIGHT
+#if IS_ENABLED(CONFIG_CORESIGHT)
int etm_perf_symlink(struct coresight_device *csdev, bool link);
#else
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 0e5a74dae6a6..83a6f5b7a683 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -136,7 +136,7 @@ struct list_head *coresight_build_path(struct coresight_device *csdev,
struct coresight_device *sink);
void coresight_release_path(struct list_head *path);
-#ifdef CONFIG_CORESIGHT_SOURCE_ETM3X
+#if IS_ENABLED(CONFIG_CORESIGHT_SOURCE_ETM3X)
extern int etm_readl_cp14(u32 off, unsigned int *val);
extern int etm_writel_cp14(u32 off, u32 val);
#else
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index e5421b83e4e6..548fa56b29bd 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -236,7 +236,7 @@ struct coresight_ops {
const struct coresight_ops_source *source_ops;
};
-#ifdef CONFIG_CORESIGHT
+#if IS_ENABLED(CONFIG_CORESIGHT)
extern struct coresight_device *
coresight_register(struct coresight_desc *desc);
extern void coresight_unregister(struct coresight_device *csdev);
--
2.17.0
^ permalink raw reply related
* [PATCH 4/6] coresight: move shared barrier_pkt[] to coresight_priv.h
From: Kim Phillips @ 2018-05-18 1:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518012024.22645-1-kim.phillips@arm.com>
barrier_pkt[] is used in various coresight components.
Change barrier_pkt[] to a static definition in the coresight
private header. Needed prior to allowing coresight to be
built as modules.
Suggested-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: Kim Phillips <kim.phillips@arm.com>
---
drivers/hwtracing/coresight/coresight-priv.h | 9 ++++++++-
drivers/hwtracing/coresight/coresight.c | 8 --------
2 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 83a6f5b7a683..45de8c15b687 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -57,7 +57,14 @@ static DEVICE_ATTR_RO(name)
#define coresight_simple_reg64(type, name, lo_off, hi_off) \
__coresight_simple_func(type, NULL, name, lo_off, hi_off)
-extern const u32 barrier_pkt[5];
+/*
+ * When losing synchronisation a new barrier packet needs to be inserted at the
+ * beginning of the data collected in a buffer. That way the decoder knows that
+ * it needs to look for another sync sequence.
+ */
+static const u32 barrier_pkt[5] = {0x7fffffff, 0x7fffffff,
+ 0x7fffffff, 0x7fffffff, 0x0};
+
enum etm_addr_type {
ETM_ADDR_TYPE_NONE,
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index 29e834aab539..0cbc2948defc 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -46,14 +46,6 @@ static DEFINE_PER_CPU(struct list_head *, tracer_path);
*/
static struct list_head *stm_path;
-/*
- * When losing synchronisation a new barrier packet needs to be inserted at the
- * beginning of the data collected in a buffer. That way the decoder knows that
- * it needs to look for another sync sequence.
- */
-const u32 barrier_pkt[5] = {0x7fffffff, 0x7fffffff,
- 0x7fffffff, 0x7fffffff, 0x0};
-
static int coresight_id_match(struct device *dev, void *data)
{
int trace_id, i_trace_id;
--
2.17.0
^ permalink raw reply related
* [PATCH 5/6] coresight: populate MODULE_AUTHOR, DESCRIPTION, and LICENSEs
From: Kim Phillips @ 2018-05-18 1:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518012024.22645-1-kim.phillips@arm.com>
Necessary prior to enabling to be built as modules.
Signed-off-by: Kim Phillips <kim.phillips@arm.com>
---
drivers/hwtracing/coresight/coresight-dynamic-replicator.c | 4 ++++
drivers/hwtracing/coresight/coresight-etb10.c | 5 +++++
drivers/hwtracing/coresight/coresight-etm-cp14.c | 4 ++++
drivers/hwtracing/coresight/coresight-etm-perf.c | 4 ++++
drivers/hwtracing/coresight/coresight-etm3x-sysfs.c | 5 +++++
drivers/hwtracing/coresight/coresight-etm3x.c | 5 +++++
drivers/hwtracing/coresight/coresight-etm4x-sysfs.c | 4 ++++
drivers/hwtracing/coresight/coresight-etm4x.c | 5 +++++
drivers/hwtracing/coresight/coresight-funnel.c | 4 ++++
drivers/hwtracing/coresight/coresight-replicator.c | 5 +++++
drivers/hwtracing/coresight/coresight-stm.c | 4 ++++
drivers/hwtracing/coresight/coresight-tmc-etf.c | 4 ++++
drivers/hwtracing/coresight/coresight-tmc-etr.c | 4 ++++
drivers/hwtracing/coresight/coresight-tmc.c | 4 ++++
drivers/hwtracing/coresight/coresight-tpiu.c | 5 +++++
drivers/hwtracing/coresight/coresight.c | 4 ++++
16 files changed, 70 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-dynamic-replicator.c b/drivers/hwtracing/coresight/coresight-dynamic-replicator.c
index f6d0571ab9dd..fc742215ab05 100644
--- a/drivers/hwtracing/coresight/coresight-dynamic-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-dynamic-replicator.c
@@ -210,3 +210,7 @@ static struct amba_driver replicator_driver = {
.id_table = replicator_ids,
};
builtin_amba_driver(replicator_driver);
+
+MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
+MODULE_DESCRIPTION("ARM Coresight Dynamic Replicator Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index 9b6c55523c58..a3dac5a8b37c 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -758,3 +758,8 @@ static struct amba_driver etb_driver = {
.id_table = etb_ids,
};
builtin_amba_driver(etb_driver);
+
+MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
+MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
+MODULE_DESCRIPTION("Arm CoreSight Embedded Trace Buffer driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight-etm-cp14.c b/drivers/hwtracing/coresight/coresight-etm-cp14.c
index 4174a8d355d2..68ca423aa088 100644
--- a/drivers/hwtracing/coresight/coresight-etm-cp14.c
+++ b/drivers/hwtracing/coresight/coresight-etm-cp14.c
@@ -582,3 +582,7 @@ int etm_writel_cp14(u32 reg, u32 val)
return 0;
}
+
+MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
+MODULE_DESCRIPTION("Arm CoreSight ETM CP14 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index 677695635211..ad0ef8d27111 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -494,3 +494,7 @@ static int __init etm_perf_init(void)
return ret;
}
device_initcall(etm_perf_init);
+
+MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
+MODULE_DESCRIPTION("Arm CoreSight tracer perf driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
index 75487b3fad86..91a2a23143d8 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
@@ -1294,3 +1294,8 @@ const struct attribute_group *coresight_etm_groups[] = {
&coresight_etm_mgmt_group,
NULL,
};
+
+MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
+MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
+MODULE_DESCRIPTION("Arm CoreSight Program Flow Trace sysfs driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c
index 7c74263c333d..7ca73a15c735 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x.c
@@ -935,3 +935,8 @@ static struct amba_driver etm_driver = {
.id_table = etm_ids,
};
builtin_amba_driver(etm_driver);
+
+MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
+MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
+MODULE_DESCRIPTION("Arm CoreSight Program Flow Trace driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index a0365e23678e..577a38673444 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -2173,3 +2173,7 @@ const struct attribute_group *coresight_etmv4_groups[] = {
&coresight_etmv4_trcidr_group,
NULL,
};
+
+MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
+MODULE_DESCRIPTION("Arm CoreSight Program Flow Trace v4 sysfs driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index 9bc04c50d45b..ba10f5302a55 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -1073,3 +1073,8 @@ static struct amba_driver etm4x_driver = {
.id_table = etm4_ids,
};
builtin_amba_driver(etm4x_driver);
+
+MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
+MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
+MODULE_DESCRIPTION("Arm CoreSight Program Flow Trace v4 driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 448145a36675..1e497a75b956 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -261,3 +261,7 @@ static struct amba_driver funnel_driver = {
.id_table = funnel_ids,
};
builtin_amba_driver(funnel_driver);
+
+MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
+MODULE_DESCRIPTION("ARM Coresight Funnel Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 8d2eaaab6c2f..9ef539893eaa 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -154,3 +154,8 @@ static struct platform_driver replicator_driver = {
},
};
builtin_platform_driver(replicator_driver);
+
+MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
+MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
+MODULE_DESCRIPTION("ARM Coresight Replicator Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index c46c70aec1d5..30eae52a8757 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -934,3 +934,7 @@ static struct amba_driver stm_driver = {
};
builtin_amba_driver(stm_driver);
+
+MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
+MODULE_DESCRIPTION("Arm CoreSight System Trace Macrocell driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etf.c b/drivers/hwtracing/coresight/coresight-tmc-etf.c
index 61d849b11c26..94cd6c00fcc9 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etf.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etf.c
@@ -617,3 +617,7 @@ int tmc_read_unprepare_etb(struct tmc_drvdata *drvdata)
return 0;
}
+
+MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
+MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller ETB/ETF mode driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight-tmc-etr.c b/drivers/hwtracing/coresight/coresight-tmc-etr.c
index 02f747afa2ba..e612896e92a7 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-etr.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-etr.c
@@ -330,3 +330,7 @@ int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
return 0;
}
+
+MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
+MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller ETR mode driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c
index 456f122df74f..176a5aeab20e 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.c
+++ b/drivers/hwtracing/coresight/coresight-tmc.c
@@ -463,3 +463,7 @@ static struct amba_driver tmc_driver = {
.id_table = tmc_ids,
};
builtin_amba_driver(tmc_driver);
+
+MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
+MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index 01b7457fe8fc..f3b154e150b3 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -218,3 +218,8 @@ static struct amba_driver tpiu_driver = {
.id_table = tpiu_ids,
};
builtin_amba_driver(tpiu_driver);
+
+MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
+MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
+MODULE_DESCRIPTION("Arm CoreSight TPIU (Trace Port Interface Unit) driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index 0cbc2948defc..406899f316e4 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -1041,3 +1041,7 @@ void coresight_unregister(struct coresight_device *csdev)
device_unregister(&csdev->dev);
}
EXPORT_SYMBOL_GPL(coresight_unregister);
+
+MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
+MODULE_DESCRIPTION("ARM Coresight Driver");
+MODULE_LICENSE("GPL v2");
--
2.17.0
^ permalink raw reply related
* [PATCH 6/6] coresight: allow to build as modules
From: Kim Phillips @ 2018-05-18 1:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518012024.22645-1-kim.phillips@arm.com>
Allow to build coresight as modules. This greatly enhances developer
efficiency by allowing the development to take place exclusively on the
target, and without needing to reboot in between changes.
- Kconfig bools become tristates, to allow =m
- use -objs to denote merge object directives in Makefile, adds a
coresight-core nomenclature for the base module.
- Export core functions so as to be able to be used by
non-core modules.
- add a coresight_exit() that unregisters the coresight bus, add
remove fns for most others.
- fix up modules with ID tables for autoloading on boot
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Kim Phillips <kim.phillips@arm.com>
---
drivers/hwtracing/coresight/Kconfig | 48 +++++++++++++++----
drivers/hwtracing/coresight/Makefile | 28 +++++++----
.../hwtracing/coresight/coresight-cpu-debug.c | 2 +
.../coresight/coresight-dynamic-replicator.c | 26 ++++++++--
drivers/hwtracing/coresight/coresight-etb10.c | 27 +++++++++--
.../hwtracing/coresight/coresight-etm-perf.c | 9 +++-
.../coresight/coresight-etm3x-sysfs.c | 1 +
drivers/hwtracing/coresight/coresight-etm3x.c | 32 +++++++++++--
.../coresight/coresight-etm4x-sysfs.c | 1 +
drivers/hwtracing/coresight/coresight-etm4x.c | 33 +++++++++++--
.../hwtracing/coresight/coresight-funnel.c | 26 ++++++++--
drivers/hwtracing/coresight/coresight-priv.h | 1 -
.../coresight/coresight-replicator.c | 28 +++++++++--
drivers/hwtracing/coresight/coresight-stm.c | 23 ++++++++-
drivers/hwtracing/coresight/coresight-tmc.c | 18 ++++++-
drivers/hwtracing/coresight/coresight-tpiu.c | 26 ++++++++--
drivers/hwtracing/coresight/coresight.c | 14 ++++++
17 files changed, 299 insertions(+), 44 deletions(-)
diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index f9abdef5b0d9..4512885f7a3e 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -2,7 +2,7 @@
# Coresight configuration
#
menuconfig CORESIGHT
- bool "CoreSight Tracing Support"
+ tristate "CoreSight Tracing Support"
select ARM_AMBA
select PERF_EVENTS
help
@@ -12,17 +12,23 @@ menuconfig CORESIGHT
specification and configure the right series of components when a
trace source gets enabled.
+ To compile this code as a module, choose M here: the
+ module will be called coresight-core.
+
if CORESIGHT
config CORESIGHT_LINKS_AND_SINKS
- bool "CoreSight Link and Sink drivers"
+ tristate "CoreSight Link and Sink drivers"
help
This enables support for CoreSight link and sink drivers that are
responsible for transporting and collecting the trace data
respectively. Link and sinks are dynamically aggregated with a trace
entity at run time to form a complete trace path.
+ To compile this code as modules, choose M here: the
+ modules will be called coresight-funnel and coresight-replicator.
+
config CORESIGHT_LINK_AND_SINK_TMC
- bool "Coresight generic TMC driver"
+ tristate "Coresight generic TMC driver"
help
This enables support for the Trace Memory Controller driver.
Depending on its configuration the device can act as a link (embedded
@@ -30,8 +36,11 @@ config CORESIGHT_LINK_AND_SINK_TMC
complies with the generic implementation of the component without
special enhancement or added features.
+ To compile this code as a module, choose M here: the
+ module will be called coresight-tmc-core.
+
config CORESIGHT_SINK_TPIU
- bool "Coresight generic TPIU driver"
+ tristate "Coresight generic TPIU driver"
help
This enables support for the Trace Port Interface Unit driver,
responsible for bridging the gap between the on-chip coresight
@@ -40,15 +49,21 @@ config CORESIGHT_SINK_TPIU
connected to an external host for use case capturing more traces than
the on-board coresight memory can handle.
+ To compile this code as a module, choose M here: the
+ module will be called coresight-tpiu.
+
config CORESIGHT_SINK_ETBV10
- bool "Coresight ETBv1.0 driver"
+ tristate "Coresight ETBv1.0 driver"
help
This enables support for the Embedded Trace Buffer version 1.0 driver
that complies with the generic implementation of the component without
special enhancement or added features.
+ To compile this code as a module, choose M here: the
+ module will be called coresight-etb10.
+
config CORESIGHT_SOURCE_ETM3X
- bool "CoreSight Embedded Trace Macrocell 3.x driver"
+ tristate "CoreSight Embedded Trace Macrocell 3.x driver"
depends on !ARM64
help
This driver provides support for processor ETM3.x and PTM1.x modules,
@@ -56,8 +71,11 @@ config CORESIGHT_SOURCE_ETM3X
This is primarily useful for instruction level tracing. Depending
the ETM version data tracing may also be available.
+ To compile this code as a module, choose M here: the
+ module will be called coresight-etm3x-core.
+
config CORESIGHT_SOURCE_ETM4X
- bool "CoreSight Embedded Trace Macrocell 4.x driver"
+ tristate "CoreSight Embedded Trace Macrocell 4.x driver"
depends on ARM64
help
This driver provides support for the ETM4.x tracer module, tracing the
@@ -65,15 +83,21 @@ config CORESIGHT_SOURCE_ETM4X
for instruction level tracing. Depending on the implemented version
data tracing may also be available.
+ To compile this code as a module, choose M here: the
+ module will be called coresight-etm4x-core.
+
config CORESIGHT_DYNAMIC_REPLICATOR
- bool "CoreSight Programmable Replicator driver"
+ tristate "CoreSight Programmable Replicator driver"
help
This enables support for dynamic CoreSight replicator link driver.
The programmable ATB replicator allows independent filtering of the
trace data based on the traceid.
+ To compile this code as a module, choose M here: the
+ module will be called coresight-dynamic-replicator.
+
config CORESIGHT_STM
- bool "CoreSight System Trace Macrocell driver"
+ tristate "CoreSight System Trace Macrocell driver"
depends on STM && ((ARM && !(CPU_32v3 || CPU_32v4 || CPU_32v4T)) || ARM64)
help
This driver provides support for hardware assisted software
@@ -81,6 +105,9 @@ config CORESIGHT_STM
logging useful software events or data coming from various entities
in the system, possibly running different OSs
+ To compile this code as a module, choose M here: the
+ module will be called coresight-stm.
+
config CORESIGHT_CPU_DEBUG
tristate "CoreSight CPU Debug driver"
depends on ARM || ARM64
@@ -95,4 +122,7 @@ config CORESIGHT_CPU_DEBUG
properly, please refer Documentation/trace/coresight-cpu-debug.txt
for detailed description and the example for usage.
+ To compile this code as a module, choose M here: the
+ module will be called coresight-cpu-debug.
+
endif
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index 61db9dd0d571..5990710289c2 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -2,19 +2,29 @@
#
# Makefile for CoreSight drivers.
#
-obj-$(CONFIG_CORESIGHT) += coresight.o coresight-etm-perf.o
-obj-$(CONFIG_OF) += of_coresight.o
-obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc.o \
- coresight-tmc-etf.o \
- coresight-tmc-etr.o
+obj-$(CONFIG_CORESIGHT) += coresight-core.o
+coresight-core-objs := coresight.o \
+ of_coresight.o
+
+obj-$(CONFIG_CORESIGHT) += coresight-etm-perf.o
+
+obj-$(CONFIG_CORESIGHT_LINK_AND_SINK_TMC) += coresight-tmc-core.o
+coresight-tmc-core-objs := coresight-tmc.o \
+ coresight-tmc-etf.o \
+ coresight-tmc-etr.o
obj-$(CONFIG_CORESIGHT_SINK_TPIU) += coresight-tpiu.o
obj-$(CONFIG_CORESIGHT_SINK_ETBV10) += coresight-etb10.o
obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \
coresight-replicator.o
-obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o coresight-etm-cp14.o \
- coresight-etm3x-sysfs.o
-obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o \
- coresight-etm4x-sysfs.o
+
+obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x-core.o
+coresight-etm3x-core-objs := coresight-etm3x.o \
+ coresight-etm-cp14.o \
+ coresight-etm3x-sysfs.o
+
+obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x-core.o
+coresight-etm4x-core-objs := coresight-etm4x.o coresight-etm4x-sysfs.o
+
obj-$(CONFIG_CORESIGHT_DYNAMIC_REPLICATOR) += coresight-dynamic-replicator.o
obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o
obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index 45b2460f3166..1efe9626eb6c 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -671,6 +671,8 @@ static const struct amba_id debug_ids[] = {
{ 0, 0 },
};
+MODULE_DEVICE_TABLE(amba, debug_ids);
+
static struct amba_driver debug_driver = {
.drv = {
.name = "coresight-cpu-debug",
diff --git a/drivers/hwtracing/coresight/coresight-dynamic-replicator.c b/drivers/hwtracing/coresight/coresight-dynamic-replicator.c
index fc742215ab05..bc42b8022556 100644
--- a/drivers/hwtracing/coresight/coresight-dynamic-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-dynamic-replicator.c
@@ -37,7 +37,12 @@ struct replicator_state {
static int replicator_enable(struct coresight_device *csdev, int inport,
int outport)
{
- struct replicator_state *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct replicator_state *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
+
+ if (!try_module_get(module))
+ return -ENODEV;
CS_UNLOCK(drvdata->base);
@@ -63,7 +68,9 @@ static int replicator_enable(struct coresight_device *csdev, int inport,
static void replicator_disable(struct coresight_device *csdev, int inport,
int outport)
{
- struct replicator_state *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct replicator_state *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
CS_UNLOCK(drvdata->base);
@@ -75,6 +82,7 @@ static void replicator_disable(struct coresight_device *csdev, int inport,
CS_LOCK(drvdata->base);
+ module_put(module);
dev_info(drvdata->dev, "REPLICATOR disabled\n");
}
@@ -159,6 +167,15 @@ static int replicator_probe(struct amba_device *adev, const struct amba_id *id)
return PTR_ERR_OR_ZERO(drvdata->csdev);
}
+static int __exit replicator_remove(struct amba_device *adev)
+{
+ struct replicator_state *drvdata = dev_get_drvdata(&adev->dev);
+
+ coresight_unregister(drvdata->csdev);
+
+ return 0;
+}
+
#ifdef CONFIG_PM
static int replicator_runtime_suspend(struct device *dev)
{
@@ -200,6 +217,8 @@ static const struct amba_id replicator_ids[] = {
{ 0, 0 },
};
+MODULE_DEVICE_TABLE(amba, replicator_ids);
+
static struct amba_driver replicator_driver = {
.drv = {
.name = "coresight-dynamic-replicator",
@@ -207,9 +226,10 @@ static struct amba_driver replicator_driver = {
.suppress_bind_attrs = true,
},
.probe = replicator_probe,
+ .remove = replicator_remove,
.id_table = replicator_ids,
};
-builtin_amba_driver(replicator_driver);
+module_amba_driver(replicator_driver);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_DESCRIPTION("ARM Coresight Dynamic Replicator Driver");
diff --git a/drivers/hwtracing/coresight/coresight-etb10.c b/drivers/hwtracing/coresight/coresight-etb10.c
index a3dac5a8b37c..8825a3e4e47a 100644
--- a/drivers/hwtracing/coresight/coresight-etb10.c
+++ b/drivers/hwtracing/coresight/coresight-etb10.c
@@ -135,7 +135,12 @@ static int etb_enable(struct coresight_device *csdev, u32 mode)
{
u32 val;
unsigned long flags;
- struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct etb_drvdata *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
+
+ if (!try_module_get(module))
+ return -ENODEV;
val = local_cmpxchg(&drvdata->mode,
CS_MODE_DISABLED, mode);
@@ -256,7 +261,9 @@ static void etb_dump_hw(struct etb_drvdata *drvdata)
static void etb_disable(struct coresight_device *csdev)
{
- struct etb_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct etb_drvdata *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
unsigned long flags;
spin_lock_irqsave(&drvdata->spinlock, flags);
@@ -266,6 +273,7 @@ static void etb_disable(struct coresight_device *csdev)
local_set(&drvdata->mode, CS_MODE_DISABLED);
+ module_put(module);
dev_info(drvdata->dev, "ETB disabled\n");
}
@@ -712,6 +720,16 @@ static int etb_probe(struct amba_device *adev, const struct amba_id *id)
return ret;
}
+static int __exit etb_remove(struct amba_device *adev)
+{
+ struct etb_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+
+ misc_deregister(&drvdata->miscdev);
+ coresight_unregister(drvdata->csdev);
+
+ return 0;
+}
+
#ifdef CONFIG_PM
static int etb_runtime_suspend(struct device *dev)
{
@@ -746,6 +764,8 @@ static const struct amba_id etb_ids[] = {
{ 0, 0},
};
+MODULE_DEVICE_TABLE(amba, etb_ids);
+
static struct amba_driver etb_driver = {
.drv = {
.name = "coresight-etb10",
@@ -755,9 +775,10 @@ static struct amba_driver etb_driver = {
},
.probe = etb_probe,
+ .remove = etb_remove,
.id_table = etb_ids,
};
-builtin_amba_driver(etb_driver);
+module_amba_driver(etb_driver);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
diff --git a/drivers/hwtracing/coresight/coresight-etm-perf.c b/drivers/hwtracing/coresight/coresight-etm-perf.c
index ad0ef8d27111..feb287083ba5 100644
--- a/drivers/hwtracing/coresight/coresight-etm-perf.c
+++ b/drivers/hwtracing/coresight/coresight-etm-perf.c
@@ -466,6 +466,7 @@ int etm_perf_symlink(struct coresight_device *csdev, bool link)
return 0;
}
+EXPORT_SYMBOL_GPL(etm_perf_symlink);
static int __init etm_perf_init(void)
{
@@ -493,7 +494,13 @@ static int __init etm_perf_init(void)
return ret;
}
-device_initcall(etm_perf_init);
+module_init(etm_perf_init);
+
+static void __exit etm_perf_exit(void)
+{
+ perf_pmu_unregister(&etm_pmu);
+}
+module_exit(etm_perf_exit);
MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
MODULE_DESCRIPTION("Arm CoreSight tracer perf driver");
diff --git a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
index 91a2a23143d8..84fa5e0fe07b 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x-sysfs.c
@@ -7,6 +7,7 @@
#include <linux/pid_namespace.h>
#include <linux/pm_runtime.h>
#include <linux/sysfs.h>
+#include <linux/coresight.h>
#include "coresight-etm.h"
#include "coresight-priv.h"
diff --git a/drivers/hwtracing/coresight/coresight-etm3x.c b/drivers/hwtracing/coresight/coresight-etm3x.c
index 7ca73a15c735..a2357b26b3a2 100644
--- a/drivers/hwtracing/coresight/coresight-etm3x.c
+++ b/drivers/hwtracing/coresight/coresight-etm3x.c
@@ -514,7 +514,12 @@ static int etm_enable(struct coresight_device *csdev,
{
int ret;
u32 val;
- struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct etm_drvdata *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
+
+ if (!try_module_get(module))
+ return -ENODEV;
val = local_cmpxchg(&drvdata->mode, CS_MODE_DISABLED, mode);
@@ -611,7 +616,9 @@ static void etm_disable(struct coresight_device *csdev,
struct perf_event *event)
{
u32 mode;
- struct etm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct etm_drvdata *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
/*
* For as long as the tracer isn't disabled another entity can't
@@ -636,6 +643,8 @@ static void etm_disable(struct coresight_device *csdev,
if (mode)
local_set(&drvdata->mode, CS_MODE_DISABLED);
+
+ module_put(module);
}
static const struct coresight_ops_source etm_source_ops = {
@@ -864,6 +873,20 @@ static int etm_probe(struct amba_device *adev, const struct amba_id *id)
return ret;
}
+static int __exit etm_remove(struct amba_device *adev)
+{
+ struct etm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+
+ etm_perf_symlink(drvdata->csdev, false);
+
+ cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING);
+ cpuhp_remove_state_nocalls(hp_online);
+
+ coresight_unregister(drvdata->csdev);
+
+ return 0;
+}
+
#ifdef CONFIG_PM
static int etm_runtime_suspend(struct device *dev)
{
@@ -924,6 +947,8 @@ static const struct amba_id etm_ids[] = {
{ 0, 0},
};
+MODULE_DEVICE_TABLE(amba, etm_ids);
+
static struct amba_driver etm_driver = {
.drv = {
.name = "coresight-etm3x",
@@ -932,9 +957,10 @@ static struct amba_driver etm_driver = {
.suppress_bind_attrs = true,
},
.probe = etm_probe,
+ .remove = etm_remove,
.id_table = etm_ids,
};
-builtin_amba_driver(etm_driver);
+module_amba_driver(etm_driver);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
index 577a38673444..ee0cbada45d6 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
@@ -2173,6 +2173,7 @@ const struct attribute_group *coresight_etmv4_groups[] = {
&coresight_etmv4_trcidr_group,
NULL,
};
+EXPORT_SYMBOL_GPL(coresight_etmv4_groups);
MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
MODULE_DESCRIPTION("Arm CoreSight Program Flow Trace v4 sysfs driver");
diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
index ba10f5302a55..a6ff152ab61d 100644
--- a/drivers/hwtracing/coresight/coresight-etm4x.c
+++ b/drivers/hwtracing/coresight/coresight-etm4x.c
@@ -280,7 +280,12 @@ static int etm4_enable(struct coresight_device *csdev,
{
int ret;
u32 val;
- struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
+
+ if (!try_module_get(module))
+ return -ENODEV;
val = local_cmpxchg(&drvdata->mode, CS_MODE_DISABLED, mode);
@@ -387,7 +392,9 @@ static void etm4_disable(struct coresight_device *csdev,
struct perf_event *event)
{
u32 mode;
- struct etmv4_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
/*
* For as long as the tracer isn't disabled another entity can't
@@ -409,6 +416,8 @@ static void etm4_disable(struct coresight_device *csdev,
if (mode)
local_set(&drvdata->mode, CS_MODE_DISABLED);
+
+ module_put(module);
}
static const struct coresight_ops_source etm4_source_ops = {
@@ -1045,6 +1054,20 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id)
return ret;
}
+static int __exit etm4_remove(struct amba_device *adev)
+{
+ struct etmv4_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+
+ etm_perf_symlink(drvdata->csdev, false);
+
+ cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CORESIGHT_STARTING);
+ cpuhp_remove_state_nocalls(hp_online);
+
+ coresight_unregister(drvdata->csdev);
+
+ return 0;
+}
+
static const struct amba_id etm4_ids[] = {
{ /* ETM 4.0 - Cortex-A53 */
.id = 0x000bb95d,
@@ -1064,15 +1087,19 @@ static const struct amba_id etm4_ids[] = {
{ 0, 0},
};
+MODULE_DEVICE_TABLE(amba, etm4_ids);
+
static struct amba_driver etm4x_driver = {
.drv = {
.name = "coresight-etm4x",
+ .owner = THIS_MODULE,
.suppress_bind_attrs = true,
},
.probe = etm4_probe,
+ .remove = etm4_remove,
.id_table = etm4_ids,
};
-builtin_amba_driver(etm4x_driver);
+module_amba_driver(etm4x_driver);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 1e497a75b956..c355a66bcc51 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -61,7 +61,12 @@ static void funnel_enable_hw(struct funnel_drvdata *drvdata, int port)
static int funnel_enable(struct coresight_device *csdev, int inport,
int outport)
{
- struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct funnel_drvdata *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
+
+ if (!try_module_get(module))
+ return -ENODEV;
funnel_enable_hw(drvdata, inport);
@@ -85,10 +90,13 @@ static void funnel_disable_hw(struct funnel_drvdata *drvdata, int inport)
static void funnel_disable(struct coresight_device *csdev, int inport,
int outport)
{
- struct funnel_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct funnel_drvdata *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
funnel_disable_hw(drvdata, inport);
+ module_put(module);
dev_info(drvdata->dev, "FUNNEL inport %d disabled\n", inport);
}
@@ -211,6 +219,15 @@ static int funnel_probe(struct amba_device *adev, const struct amba_id *id)
return PTR_ERR_OR_ZERO(drvdata->csdev);
}
+static int __exit funnel_remove(struct amba_device *adev)
+{
+ struct funnel_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+
+ coresight_unregister(drvdata->csdev);
+
+ return 0;
+}
+
#ifdef CONFIG_PM
static int funnel_runtime_suspend(struct device *dev)
{
@@ -250,6 +267,8 @@ static const struct amba_id funnel_ids[] = {
{ 0, 0},
};
+MODULE_DEVICE_TABLE(amba, funnel_ids);
+
static struct amba_driver funnel_driver = {
.drv = {
.name = "coresight-funnel",
@@ -258,9 +277,10 @@ static struct amba_driver funnel_driver = {
.suppress_bind_attrs = true,
},
.probe = funnel_probe,
+ .remove = funnel_remove,
.id_table = funnel_ids,
};
-builtin_amba_driver(funnel_driver);
+module_amba_driver(funnel_driver);
MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
MODULE_DESCRIPTION("ARM Coresight Funnel Driver");
diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h
index 45de8c15b687..896958c2dd44 100644
--- a/drivers/hwtracing/coresight/coresight-priv.h
+++ b/drivers/hwtracing/coresight/coresight-priv.h
@@ -65,7 +65,6 @@ static DEVICE_ATTR_RO(name)
static const u32 barrier_pkt[5] = {0x7fffffff, 0x7fffffff,
0x7fffffff, 0x7fffffff, 0x0};
-
enum etm_addr_type {
ETM_ADDR_TYPE_NONE,
ETM_ADDR_TYPE_SINGLE,
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index 9ef539893eaa..6f16dcd7e107 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -33,7 +33,12 @@ struct replicator_drvdata {
static int replicator_enable(struct coresight_device *csdev, int inport,
int outport)
{
- struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct replicator_drvdata *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
+
+ if (!try_module_get(module))
+ return -ENODEV;
dev_info(drvdata->dev, "REPLICATOR enabled\n");
return 0;
@@ -42,8 +47,11 @@ static int replicator_enable(struct coresight_device *csdev, int inport,
static void replicator_disable(struct coresight_device *csdev, int inport,
int outport)
{
- struct replicator_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct replicator_drvdata *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
+ module_put(module);
dev_info(drvdata->dev, "REPLICATOR disabled\n");
}
@@ -112,6 +120,17 @@ static int replicator_probe(struct platform_device *pdev)
return ret;
}
+static int __exit replicator_remove(struct platform_device *pdev)
+{
+ struct replicator_drvdata *drvdata = dev_get_drvdata(&pdev->dev);
+
+ coresight_unregister(drvdata->csdev);
+
+ pm_runtime_disable(&pdev->dev);
+
+ return 0;
+}
+
#ifdef CONFIG_PM
static int replicator_runtime_suspend(struct device *dev)
{
@@ -144,8 +163,11 @@ static const struct of_device_id replicator_match[] = {
{}
};
+MODULE_DEVICE_TABLE(of, replicator_match);
+
static struct platform_driver replicator_driver = {
.probe = replicator_probe,
+ .remove = replicator_remove,
.driver = {
.name = "coresight-replicator",
.of_match_table = replicator_match,
@@ -153,7 +175,7 @@ static struct platform_driver replicator_driver = {
.suppress_bind_attrs = true,
},
};
-builtin_platform_driver(replicator_driver);
+module_platform_driver(replicator_driver);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index 30eae52a8757..9997ba0dbd54 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -194,7 +194,12 @@ static int stm_enable(struct coresight_device *csdev,
struct perf_event *event, u32 mode)
{
u32 val;
- struct stm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct stm_drvdata *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
+
+ if (!try_module_get(module))
+ return -ENODEV;
if (mode != CS_MODE_SYSFS)
return -EINVAL;
@@ -882,6 +887,17 @@ static int stm_probe(struct amba_device *adev, const struct amba_id *id)
return ret;
}
+static int __exit stm_remove(struct amba_device *adev)
+{
+ struct stm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+
+ coresight_unregister(drvdata->csdev);
+
+ stm_unregister_device(&drvdata->stm);
+
+ return 0;
+}
+
#ifdef CONFIG_PM
static int stm_runtime_suspend(struct device *dev)
{
@@ -922,6 +938,8 @@ static const struct amba_id stm_ids[] = {
{ 0, 0},
};
+MODULE_DEVICE_TABLE(amba, stm_ids);
+
static struct amba_driver stm_driver = {
.drv = {
.name = "coresight-stm",
@@ -930,10 +948,11 @@ static struct amba_driver stm_driver = {
.suppress_bind_attrs = true,
},
.probe = stm_probe,
+ .remove = stm_remove,
.id_table = stm_ids,
};
-builtin_amba_driver(stm_driver);
+module_amba_driver(stm_driver);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_DESCRIPTION("Arm CoreSight System Trace Macrocell driver");
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c
index 176a5aeab20e..eb3cdb832f84 100644
--- a/drivers/hwtracing/coresight/coresight-tmc.c
+++ b/drivers/hwtracing/coresight/coresight-tmc.c
@@ -429,6 +429,19 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
return ret;
}
+static int __exit tmc_remove(struct amba_device *adev)
+{
+ struct tmc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+
+ /* free ETB/ETF or ETR memory */
+ tmc_read_unprepare(drvdata);
+
+ misc_deregister(&drvdata->miscdev);
+ coresight_unregister(drvdata->csdev);
+
+ return 0;
+}
+
static const struct amba_id tmc_ids[] = {
{
.id = 0x000bb961,
@@ -453,6 +466,8 @@ static const struct amba_id tmc_ids[] = {
{ 0, 0},
};
+MODULE_DEVICE_TABLE(amba, tmc_ids);
+
static struct amba_driver tmc_driver = {
.drv = {
.name = "coresight-tmc",
@@ -460,9 +475,10 @@ static struct amba_driver tmc_driver = {
.suppress_bind_attrs = true,
},
.probe = tmc_probe,
+ .remove = tmc_remove,
.id_table = tmc_ids,
};
-builtin_amba_driver(tmc_driver);
+module_amba_driver(tmc_driver);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_DESCRIPTION("Arm CoreSight Trace Memory Controller driver");
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index f3b154e150b3..9622f2a5a451 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -69,7 +69,12 @@ static void tpiu_enable_hw(struct tpiu_drvdata *drvdata)
static int tpiu_enable(struct coresight_device *csdev, u32 mode)
{
- struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct tpiu_drvdata *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
+
+ if (!try_module_get(module))
+ return -ENODEV;
tpiu_enable_hw(drvdata);
@@ -95,10 +100,13 @@ static void tpiu_disable_hw(struct tpiu_drvdata *drvdata)
static void tpiu_disable(struct coresight_device *csdev)
{
- struct tpiu_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+ struct device *parent_dev = csdev->dev.parent;
+ struct tpiu_drvdata *drvdata = dev_get_drvdata(parent_dev);
+ struct module *module = parent_dev->driver->owner;
tpiu_disable_hw(drvdata);
+ module_put(module);
dev_info(drvdata->dev, "TPIU disabled\n");
}
@@ -164,6 +172,15 @@ static int tpiu_probe(struct amba_device *adev, const struct amba_id *id)
return PTR_ERR_OR_ZERO(drvdata->csdev);
}
+static int __exit tpiu_remove(struct amba_device *adev)
+{
+ struct tpiu_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+
+ coresight_unregister(drvdata->csdev);
+
+ return 0;
+}
+
#ifdef CONFIG_PM
static int tpiu_runtime_suspend(struct device *dev)
{
@@ -207,6 +224,8 @@ static const struct amba_id tpiu_ids[] = {
{ 0, 0},
};
+MODULE_DEVICE_TABLE(amba, tpiu_ids);
+
static struct amba_driver tpiu_driver = {
.drv = {
.name = "coresight-tpiu",
@@ -215,9 +234,10 @@ static struct amba_driver tpiu_driver = {
.suppress_bind_attrs = true,
},
.probe = tpiu_probe,
+ .remove = tpiu_remove,
.id_table = tpiu_ids,
};
-builtin_amba_driver(tpiu_driver);
+module_amba_driver(tpiu_driver);
MODULE_AUTHOR("Pratik Patel <pratikp@codeaurora.org>");
MODULE_AUTHOR("Mathieu Poirier <mathieu.poirier@linaro.org>");
diff --git a/drivers/hwtracing/coresight/coresight.c b/drivers/hwtracing/coresight/coresight.c
index 406899f316e4..c00229b0db52 100644
--- a/drivers/hwtracing/coresight/coresight.c
+++ b/drivers/hwtracing/coresight/coresight.c
@@ -302,6 +302,7 @@ void coresight_disable_path(struct list_head *path)
}
}
}
+EXPORT_SYMBOL_GPL(coresight_disable_path);
int coresight_enable_path(struct list_head *path, u32 mode)
{
@@ -353,6 +354,7 @@ int coresight_enable_path(struct list_head *path, u32 mode)
coresight_disable_path(path);
goto out;
}
+EXPORT_SYMBOL_GPL(coresight_enable_path);
struct coresight_device *coresight_get_sink(struct list_head *path)
{
@@ -368,6 +370,7 @@ struct coresight_device *coresight_get_sink(struct list_head *path)
return csdev;
}
+EXPORT_SYMBOL_GPL(coresight_get_sink);
static int coresight_enabled_sink(struct device *dev, void *data)
{
@@ -392,6 +395,7 @@ static int coresight_enabled_sink(struct device *dev, void *data)
return 0;
}
+EXPORT_SYMBOL_GPL(coresight_enabled_sink);
/**
* coresight_get_enabled_sink - returns the first enabled sink found on the bus
@@ -414,6 +418,7 @@ struct coresight_device *coresight_get_enabled_sink(bool deactivate)
return dev ? to_coresight_device(dev) : NULL;
}
+EXPORT_SYMBOL_GPL(coresight_get_enabled_sink);
/**
* _coresight_build_path - recursively build a path from a @csdev to a sink.
@@ -493,6 +498,7 @@ struct list_head *coresight_build_path(struct coresight_device *source,
return path;
}
+EXPORT_SYMBOL_GPL(coresight_build_path);
/**
* coresight_release_path - release a previously built path.
@@ -517,6 +523,7 @@ void coresight_release_path(struct list_head *path)
kfree(path);
path = NULL;
}
+EXPORT_SYMBOL_GPL(coresight_release_path);
/** coresight_validate_source - make sure a source has the right credentials
* @csdev: the device structure for a source.
@@ -933,6 +940,7 @@ int coresight_timeout(void __iomem *addr, u32 offset, int position, int value)
return -EAGAIN;
}
+EXPORT_SYMBOL_GPL(coresight_timeout);
struct bus_type coresight_bustype = {
.name = "coresight",
@@ -944,6 +952,12 @@ static int __init coresight_init(void)
}
postcore_initcall(coresight_init);
+static void __exit coresight_exit(void)
+{
+ bus_unregister(&coresight_bustype);
+}
+module_exit(coresight_exit);
+
struct coresight_device *coresight_register(struct coresight_desc *desc)
{
int i;
--
2.17.0
^ permalink raw reply related
* [PATCH] ARM: davinci: board-da850-evm: fix WP pin polarity for MMC/SD
From: Adam Ford @ 2018-05-18 1:20 UTC (permalink / raw)
To: linux-arm-kernel
When booting from MMC/SD in rw mode, the system crashes because
the write protect pin should be active high and not active low.
This patch fixes the polarity of the WP pin.
Fixes: 67c6b6ff221f ("ARM: davinci: board-da850-evm: fix GPIO
lookup for MMC/SD")
Signed-off-by: Adam Ford <aford173@gmail.com>
diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c
index e22fb40e34bc..6d5beb11bd96 100644
--- a/arch/arm/mach-davinci/board-da850-evm.c
+++ b/arch/arm/mach-davinci/board-da850-evm.c
@@ -774,7 +774,7 @@ static struct gpiod_lookup_table mmc_gpios_table = {
GPIO_LOOKUP("davinci_gpio.0", DA850_MMCSD_CD_PIN, "cd",
GPIO_ACTIVE_LOW),
GPIO_LOOKUP("davinci_gpio.0", DA850_MMCSD_WP_PIN, "wp",
- GPIO_ACTIVE_LOW),
+ GPIO_ACTIVE_HIGH),
},
};
--
2.17.0
^ permalink raw reply related
* [PATCH v9 04/11] arm64: kexec_file: allocate memory walking through memblock list
From: Baoquan He @ 2018-05-18 1:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <d9b8a3ca-93bc-87f9-1316-f45c0dfe47ae@arm.com>
On 05/17/18 at 07:04pm, James Morse wrote:
> Hi Baoquan,
>
> On 17/05/18 03:15, Baoquan He wrote:
> > On 05/17/18 at 10:10am, Baoquan He wrote:
> >> On 05/07/18 at 02:59pm, AKASHI Takahiro wrote:
> >>> On Tue, May 01, 2018 at 06:46:09PM +0100, James Morse wrote:
> >>>> On 25/04/18 07:26, AKASHI Takahiro wrote:
> >>>>> We need to prevent firmware-reserved memory regions, particularly EFI
> >>>>> memory map as well as ACPI tables, from being corrupted by loading
> >>>>> kernel/initrd (or other kexec buffers). We also want to support memory
> >>>>> allocation in top-down manner in addition to default bottom-up.
> >>>>> So let's have arm64 specific arch_kexec_walk_mem() which will search
> >>>>> for available memory ranges in usable memblock list,
> >>>>> i.e. !NOMAP & !reserved,
> >>>>
> >>>>> instead of system resource tree.
> >>>>
> >>>> Didn't we try to fix the system-resource-tree in order to fix regular-kexec to
> >>>> be safe in the EFI-memory-map/ACPI-tables case?
> >>>>
> >>>> It would be good to avoid having two ways of doing this, and I would like to
> >>>> avoid having extra arch code...
> >>>
> >>> I know what you mean.
> >>> /proc/iomem or system resource is, in my opinion, not the best place to
> >>> describe memory usage of kernel but rather to describe *physical* hardware
> >>> layout. As we are still discussing about "reserved" memory, I don't want
> >>> to depend on it.
> >>> Along with memblock list, we will have more accurate control over memory
> >>> usage.
> >>
> >> In kexec-tools, we see any usable memory as candidate which can be used
> >
> > Here I said 'any', it's not accurate. Those memory which need be passed
> > to 2nd kernel for use need be excluded, just as we have done in
> > kexec-tools.
> >
> >> to load kexec kernel image/initrd etc. However kexec loading is a
> >> preparation work, it just books those position for later kexec kernel
> >> jumping after "kexec -e", that is why we need kexec_buf to remember
> >> them and do the real content copy of kernel/initrd.
>
> The problem we have on arm64 is /proc/iomem is being used for two things.
> 1) Kexec's this is memory I can book for the new kernel.
> 2) Kdump's this is memory I must describe for vmcore.
>
> We get the memory map from UEFI via the EFI stub, and leave it in
> memblock_reserved() memory. A new kexec kernel needs this to boot: it mustn't
> overwrite it. The same goes for the ACPI tables, they could be reclaimed and
> used as memory, but the new kexec kernel needs them to boot, they are
> memblock_reserved() too.
Thanks for these details. Seems arm64 is different. In x86 64 memblock
is used as bootmem allocator and will be released when buddy takes over.
Mainly, using memblock may bring concern that kexec kernel
will jump to a unfixed position. This creates an unexpected effect as
KASLR is doing, namely kernel could be put at a random position. As we
know, kexec was invented for fast kernel dev testing by bypassing
firmware reset, and has been taken to reboot those huge server with
thousands of devices and large memory for business currently. This extra
unpected KASLR effect may cause annoyance even though people have
disabled KASLR explicitly for a specific testing purpose.
Besides, discarding the /proc/iomem scanning but taking memblock instead
in kernel space works for kexec loading for the time being, the flaw of
/proc/iomem still exists and cause problem for user space kexec-tools,
as pointed out. Do we have a plan for that?
>
> If we knock all memblock_reserved() regions out of /proc/iomem then kdump
> doesn't work, because /proc/iomem is only generated once. Its a snapshot. The
> initcode/data is an example of memory we release from memblock_reserve() after
> this, then gets used for data we need in the vmcore.
Hmm, I'm a little confused here. We have defined different iores type
for different memory region. If acpi need be reused by kdump/kexec, we
can change to not reclaim it, and add them into /proc/iomem in order to
notify components which rely on them to process.
enum {
IORES_DESC_NONE = 0,
IORES_DESC_CRASH_KERNEL = 1,
IORES_DESC_ACPI_TABLES = 2,
IORES_DESC_ACPI_NV_STORAGE = 3,
IORES_DESC_PERSISTENT_MEMORY = 4,
IORES_DESC_PERSISTENT_MEMORY_LEGACY = 5,
IORES_DESC_DEVICE_PRIVATE_MEMORY = 6,
IORES_DESC_DEVICE_PUBLIC_MEMORY = 7,
};
Just walk around and talk about it, limited by poor arm64 knowledge, I
may not have a complete view. If it's not like what I think about, I
will stop, and can come back when I get more background knowledge.
Thanks
Baoquan
>
> Ideally we would describe all this in /proc/iomem with:
> | 8001e80000-83ff186fff : System RAM
> | 8002080000-8002feffff : [Data you really need to boot]
>
> kexec-tools should not overwrite 'data you really need to boot' unless it knows
> what it is, and that the system will never need it again. (examples: overwrite
> the ACPI tables when booting a non-acpi kernel, overwrite the UEFI memory map if
> the DT has been regenerated for a non-uefi kernel)
>
> But, kexec-tools doesn't parse those second level entries properly. We have a
> bug in user-space, and a bug in the kernel.
>
> Because /proc/iomem is being used for two things, and kexec-tools only parses
> one level, I don't think we can fix this in the kernel without breaking one of
> the use-cases. I think Akashi's fix user-space too approach is the most
> pragmatic approach.
>
>
> >> Here you use
> >> memblock to search available memory, isn't it deviating too far away
> >> from the original design in kexec-tools. Assume kexec loading and
> >> kexec_file loading should be consistent on loading even though they are
> >> done in different space, kernel space and user space.
>
> Its much easier for us to parse memblock in the kernel as the helpers step over
> the regions we know we don't want. For the resource list we would need to
> strcmp(), and a bunch of handling for the second level entries.
>
>
> Thanks,
>
> James
^ permalink raw reply
* [PATCH v5 4/4] drm/rockchip: support dp training outside dp firmware
From: hl @ 2018-05-18 1:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180517135136.GD3373@art_vandelay>
+ Kishon
On Thursday, May 17, 2018 09:51 PM, Sean Paul wrote:
> On Thu, May 17, 2018 at 05:18:00PM +0800, Lin Huang wrote:
>> DP firmware uses fixed phy config values to do training, but some
>> boards need to adjust these values to fit for their unique hardware
>> design. So get phy config values from dts and use software link training
>> instead of relying on firmware, if software training fail, keep firmware
>> training as a fallback if sw training fails.
>>
>> Signed-off-by: Chris Zhong <zyw@rock-chips.com>
>> Signed-off-by: Lin Huang <hl@rock-chips.com>
>> ---
>> Changes in v2:
>> - update patch following Enric suggest
>> Changes in v3:
>> - use variable fw_training instead sw_training_success
>> - base on DP SPCE, if training fail use lower link rate to retry training
>> Changes in v4:
>> - improve cdn_dp_get_lower_link_rate() and cdn_dp_software_train_link() follow Sean suggest
>> Changes in v5:
>> - fix some whitespcae issue
>>
>> drivers/gpu/drm/rockchip/Makefile | 3 +-
>> drivers/gpu/drm/rockchip/cdn-dp-core.c | 24 +-
>> drivers/gpu/drm/rockchip/cdn-dp-core.h | 2 +
>> drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 420 ++++++++++++++++++++++++
>> drivers/gpu/drm/rockchip/cdn-dp-reg.c | 31 +-
>> drivers/gpu/drm/rockchip/cdn-dp-reg.h | 38 ++-
>> 6 files changed, 505 insertions(+), 13 deletions(-)
>> create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-link-training.c
>>
>> diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile
>> index a314e21..b932f62 100644
>> --- a/drivers/gpu/drm/rockchip/Makefile
>> +++ b/drivers/gpu/drm/rockchip/Makefile
>> @@ -9,7 +9,8 @@ rockchipdrm-y := rockchip_drm_drv.o rockchip_drm_fb.o \
>> rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o
>>
>> rockchipdrm-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o
>> -rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o
>> +rockchipdrm-$(CONFIG_ROCKCHIP_CDN_DP) += cdn-dp-core.o cdn-dp-reg.o \
>> + cdn-dp-link-training.o
>> rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o
>> rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o
>> rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
>> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c
>> index cce64c1..d9d0d4d 100644
>> --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c
>> +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c
>> @@ -629,11 +629,13 @@ static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
>> goto out;
>> }
>> }
>> -
>> - ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
>> - if (ret) {
>> - DRM_DEV_ERROR(dp->dev, "Failed to idle video %d\n", ret);
>> - goto out;
>> + if (dp->use_fw_training == true) {
>> + ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_IDLE);
>> + if (ret) {
>> + DRM_DEV_ERROR(dp->dev,
>> + "Failed to idle video %d\n", ret);
>> + goto out;
>> + }
>> }
>>
>> ret = cdn_dp_config_video(dp);
>> @@ -642,11 +644,15 @@ static void cdn_dp_encoder_enable(struct drm_encoder *encoder)
>> goto out;
>> }
>>
>> - ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
>> - if (ret) {
>> - DRM_DEV_ERROR(dp->dev, "Failed to valid video %d\n", ret);
>> - goto out;
>> + if (dp->use_fw_training == true) {
>> + ret = cdn_dp_set_video_status(dp, CONTROL_VIDEO_VALID);
>> + if (ret) {
>> + DRM_DEV_ERROR(dp->dev,
>> + "Failed to valid video %d\n", ret);
>> + goto out;
>> + }
>> }
>> +
>> out:
>> mutex_unlock(&dp->lock);
>> }
>> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.h b/drivers/gpu/drm/rockchip/cdn-dp-core.h
>> index 46159b2..77a9793 100644
>> --- a/drivers/gpu/drm/rockchip/cdn-dp-core.h
>> +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.h
>> @@ -84,6 +84,7 @@ struct cdn_dp_device {
>> bool connected;
>> bool active;
>> bool suspended;
>> + bool use_fw_training;
>>
>> const struct firmware *fw; /* cdn dp firmware */
>> unsigned int fw_version; /* cdn fw version */
>> @@ -106,6 +107,7 @@ struct cdn_dp_device {
>> u8 ports;
>> u8 lanes;
>> int active_port;
>> + u8 train_set[4];
>>
>> u8 dpcd[DP_RECEIVER_CAP_SIZE];
>> bool sink_has_audio;
>> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
>> new file mode 100644
>> index 0000000..73c3290
>> --- /dev/null
>> +++ b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
>> @@ -0,0 +1,420 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
>> + * Author: Chris Zhong <zyw@rock-chips.com>
>> + */
>> +
>> +#include <linux/device.h>
>> +#include <linux/delay.h>
>> +#include <linux/phy/phy.h>
>> +#include <soc/rockchip/rockchip_phy_typec.h>
>> +
>> +#include "cdn-dp-core.h"
>> +#include "cdn-dp-reg.h"
>> +
>> +static void cdn_dp_set_signal_levels(struct cdn_dp_device *dp)
>> +{
>> + struct cdn_dp_port *port = dp->port[dp->active_port];
>> + struct rockchip_typec_phy *tcphy = phy_get_drvdata(port->phy);
> You ignored Brian's comment on the previous patch:
> This is still antithetical to the PHY framework; you're assuming that
> this is a particular type of PHY here.
>
> FWIW, the mediatek drm driver also assumes a certain PHY type. A quick grep of
> drivers/ shows that the only other non-phy/ driver using this function
> (pinctrl-tegra-xusb.c) also casts it.
>
> Sean
Thanks Sean, except phy framework have new API to handle it, i have not
idea how to do it in a better way.
>> +
>> + int rate = drm_dp_bw_code_to_link_rate(dp->link.rate);
>> + u8 swing = (dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) >>
>> + DP_TRAIN_VOLTAGE_SWING_SHIFT;
>> + u8 pre_emphasis = (dp->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK)
>> + >> DP_TRAIN_PRE_EMPHASIS_SHIFT;
>> +
>> + tcphy->typec_phy_config(port->phy, rate, dp->link.num_lanes,
>> + swing, pre_emphasis);
>> +}
>> +
>> +static int cdn_dp_set_pattern(struct cdn_dp_device *dp, uint8_t dp_train_pat)
>> +{
>> + u32 phy_config, global_config;
>> + int ret;
>> + uint8_t pattern = dp_train_pat & DP_TRAINING_PATTERN_MASK;
>> +
>> + global_config = NUM_LANES(dp->link.num_lanes - 1) | SST_MODE |
>> + GLOBAL_EN | RG_EN | ENC_RST_DIS | WR_VHSYNC_FALL;
>> +
>> + phy_config = DP_TX_PHY_ENCODER_BYPASS(0) |
>> + DP_TX_PHY_SKEW_BYPASS(0) |
>> + DP_TX_PHY_DISPARITY_RST(0) |
>> + DP_TX_PHY_LANE0_SKEW(0) |
>> + DP_TX_PHY_LANE1_SKEW(1) |
>> + DP_TX_PHY_LANE2_SKEW(2) |
>> + DP_TX_PHY_LANE3_SKEW(3) |
>> + DP_TX_PHY_10BIT_ENABLE(0);
>> +
>> + if (pattern != DP_TRAINING_PATTERN_DISABLE) {
>> + global_config |= NO_VIDEO;
>> + phy_config |= DP_TX_PHY_TRAINING_ENABLE(1) |
>> + DP_TX_PHY_SCRAMBLER_BYPASS(1) |
>> + DP_TX_PHY_TRAINING_PATTERN(pattern);
>> + }
>> +
>> + ret = cdn_dp_reg_write(dp, DP_FRAMER_GLOBAL_CONFIG, global_config);
>> + if (ret) {
>> + DRM_ERROR("fail to set DP_FRAMER_GLOBAL_CONFIG, error: %d\n",
>> + ret);
>> + return ret;
>> + }
>> +
>> + ret = cdn_dp_reg_write(dp, DP_TX_PHY_CONFIG_REG, phy_config);
>> + if (ret) {
>> + DRM_ERROR("fail to set DP_TX_PHY_CONFIG_REG, error: %d\n",
>> + ret);
>> + return ret;
>> + }
>> +
>> + ret = cdn_dp_reg_write(dp, DPTX_LANE_EN, BIT(dp->link.num_lanes) - 1);
>> + if (ret) {
>> + DRM_ERROR("fail to set DPTX_LANE_EN, error: %d\n", ret);
>> + return ret;
>> + }
>> +
>> + if (drm_dp_enhanced_frame_cap(dp->dpcd))
>> + ret = cdn_dp_reg_write(dp, DPTX_ENHNCD, 1);
>> + else
>> + ret = cdn_dp_reg_write(dp, DPTX_ENHNCD, 0);
>> + if (ret)
>> + DRM_ERROR("failed to set DPTX_ENHNCD, error: %x\n", ret);
>> +
>> + return ret;
>> +}
>> +
>> +static u8 cdn_dp_pre_emphasis_max(u8 voltage_swing)
>> +{
>> + switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
>> + case DP_TRAIN_VOLTAGE_SWING_LEVEL_0:
>> + return DP_TRAIN_PRE_EMPH_LEVEL_3;
>> + case DP_TRAIN_VOLTAGE_SWING_LEVEL_1:
>> + return DP_TRAIN_PRE_EMPH_LEVEL_2;
>> + case DP_TRAIN_VOLTAGE_SWING_LEVEL_2:
>> + return DP_TRAIN_PRE_EMPH_LEVEL_1;
>> + default:
>> + return DP_TRAIN_PRE_EMPH_LEVEL_0;
>> + }
>> +}
>> +
>> +static void cdn_dp_get_adjust_train(struct cdn_dp_device *dp,
>> + uint8_t link_status[DP_LINK_STATUS_SIZE])
>> +{
>> + int i;
>> + uint8_t v = 0, p = 0;
>> + uint8_t preemph_max;
>> +
>> + for (i = 0; i < dp->link.num_lanes; i++) {
>> + v = max(v, drm_dp_get_adjust_request_voltage(link_status, i));
>> + p = max(p, drm_dp_get_adjust_request_pre_emphasis(link_status,
>> + i));
>> + }
>> +
>> + if (v >= VOLTAGE_LEVEL_2)
>> + v = VOLTAGE_LEVEL_2 | DP_TRAIN_MAX_SWING_REACHED;
>> +
>> + preemph_max = cdn_dp_pre_emphasis_max(v);
>> + if (p >= preemph_max)
>> + p = preemph_max | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
>> +
>> + for (i = 0; i < dp->link.num_lanes; i++)
>> + dp->train_set[i] = v | p;
>> +}
>> +
>> +/*
>> + * Pick training pattern for channel equalization. Training Pattern 3 for HBR2
>> + * or 1.2 devices that support it, Training Pattern 2 otherwise.
>> + */
>> +static u32 cdn_dp_select_chaneq_pattern(struct cdn_dp_device *dp)
>> +{
>> + u32 training_pattern = DP_TRAINING_PATTERN_2;
>> +
>> + /*
>> + * cdn dp support HBR2 also support TPS3. TPS3 support is also mandatory
>> + * for downstream devices that support HBR2. However, not all sinks
>> + * follow the spec.
>> + */
>> + if (drm_dp_tps3_supported(dp->dpcd))
>> + training_pattern = DP_TRAINING_PATTERN_3;
>> + else
>> + DRM_DEBUG_KMS("5.4 Gbps link rate without sink TPS3 support\n");
>> +
>> + return training_pattern;
>> +}
>> +
>> +
>> +static bool cdn_dp_link_max_vswing_reached(struct cdn_dp_device *dp)
>> +{
>> + int lane;
>> +
>> + for (lane = 0; lane < dp->link.num_lanes; lane++)
>> + if ((dp->train_set[lane] & DP_TRAIN_MAX_SWING_REACHED) == 0)
>> + return false;
>> +
>> + return true;
>> +}
>> +
>> +static int cdn_dp_update_link_train(struct cdn_dp_device *dp)
>> +{
>> + int ret;
>> +
>> + cdn_dp_set_signal_levels(dp);
>> +
>> + ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET,
>> + dp->train_set, dp->link.num_lanes);
>> + if (ret != dp->link.num_lanes)
>> + return -EINVAL;
>> +
>> + return 0;
>> +}
>> +
>> +static int cdn_dp_set_link_train(struct cdn_dp_device *dp,
>> + uint8_t dp_train_pat)
>> +{
>> + uint8_t buf[sizeof(dp->train_set) + 1];
>> + int ret, len;
>> +
>> + buf[0] = dp_train_pat;
>> + if ((dp_train_pat & DP_TRAINING_PATTERN_MASK) ==
>> + DP_TRAINING_PATTERN_DISABLE) {
>> + /* don't write DP_TRAINING_LANEx_SET on disable */
>> + len = 1;
>> + } else {
>> + /* DP_TRAINING_LANEx_SET follow DP_TRAINING_PATTERN_SET */
>> + memcpy(buf + 1, dp->train_set, dp->link.num_lanes);
>> + len = dp->link.num_lanes + 1;
>> + }
>> +
>> + ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_PATTERN_SET,
>> + buf, len);
>> + if (ret != len)
>> + return -EINVAL;
>> +
>> + return 0;
>> +}
>> +
>> +static int cdn_dp_reset_link_train(struct cdn_dp_device *dp,
>> + uint8_t dp_train_pat)
>> +{
>> + int ret;
>> +
>> + memset(dp->train_set, 0, sizeof(dp->train_set));
>> +
>> + cdn_dp_set_signal_levels(dp);
>> +
>> + ret = cdn_dp_set_pattern(dp, dp_train_pat);
>> + if (ret)
>> + return ret;
>> +
>> + return cdn_dp_set_link_train(dp, dp_train_pat);
>> +}
>> +
>> +/* Enable corresponding port and start training pattern 1 */
>> +static int cdn_dp_link_training_clock_recovery(struct cdn_dp_device *dp)
>> +{
>> + u8 voltage;
>> + u8 link_status[DP_LINK_STATUS_SIZE];
>> + u32 voltage_tries, max_vswing_tries;
>> + int ret;
>> +
>> + /* clock recovery */
>> + ret = cdn_dp_reset_link_train(dp, DP_TRAINING_PATTERN_1 |
>> + DP_LINK_SCRAMBLING_DISABLE);
>> + if (ret) {
>> + DRM_ERROR("failed to start link train\n");
>> + return ret;
>> + }
>> +
>> + voltage_tries = 1;
>> + max_vswing_tries = 0;
>> + for (;;) {
>> + drm_dp_link_train_clock_recovery_delay(dp->dpcd);
>> + if (drm_dp_dpcd_read_link_status(&dp->aux, link_status) !=
>> + DP_LINK_STATUS_SIZE) {
>> + DRM_ERROR("failed to get link status\n");
>> + return -EINVAL;
>> + }
>> +
>> + if (drm_dp_clock_recovery_ok(link_status, dp->link.num_lanes)) {
>> + DRM_DEBUG_KMS("clock recovery OK\n");
>> + return 0;
>> + }
>> +
>> + if (voltage_tries >= 5) {
>> + DRM_DEBUG_KMS("Same voltage tried 5 times\n");
>> + return -EINVAL;
>> + }
>> +
>> + if (max_vswing_tries >= 1) {
>> + DRM_DEBUG_KMS("Max Voltage Swing reached\n");
>> + return -EINVAL;
>> + }
>> +
>> + voltage = dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
>> +
>> + /* Update training set as requested by target */
>> + cdn_dp_get_adjust_train(dp, link_status);
>> + if (cdn_dp_update_link_train(dp)) {
>> + DRM_ERROR("failed to update link training\n");
>> + return -EINVAL;
>> + }
>> +
>> + if ((dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) ==
>> + voltage)
>> + ++voltage_tries;
>> + else
>> + voltage_tries = 1;
>> +
>> + if (cdn_dp_link_max_vswing_reached(dp))
>> + ++max_vswing_tries;
>> + }
>> +}
>> +
>> +static int cdn_dp_link_training_channel_equalization(struct cdn_dp_device *dp)
>> +{
>> + int tries, ret;
>> + u32 training_pattern;
>> + uint8_t link_status[DP_LINK_STATUS_SIZE];
>> +
>> + training_pattern = cdn_dp_select_chaneq_pattern(dp);
>> + training_pattern |= DP_LINK_SCRAMBLING_DISABLE;
>> +
>> + ret = cdn_dp_set_pattern(dp, training_pattern);
>> + if (ret)
>> + return ret;
>> +
>> + ret = cdn_dp_set_link_train(dp, training_pattern);
>> + if (ret) {
>> + DRM_ERROR("failed to start channel equalization\n");
>> + return ret;
>> + }
>> +
>> + for (tries = 0; tries < 5; tries++) {
>> + drm_dp_link_train_channel_eq_delay(dp->dpcd);
>> + if (drm_dp_dpcd_read_link_status(&dp->aux, link_status) !=
>> + DP_LINK_STATUS_SIZE) {
>> + DRM_ERROR("failed to get link status\n");
>> + break;
>> + }
>> +
>> + /* Make sure clock is still ok */
>> + if (!drm_dp_clock_recovery_ok(link_status,
>> + dp->link.num_lanes)) {
>> + DRM_DEBUG_KMS("Clock recovery check failed\n");
>> + break;
>> + }
>> +
>> + if (drm_dp_channel_eq_ok(link_status, dp->link.num_lanes)) {
>> + DRM_DEBUG_KMS("Channel EQ done\n");
>> + return 0;
>> + }
>> +
>> + /* Update training set as requested by target */
>> + cdn_dp_get_adjust_train(dp, link_status);
>> + if (cdn_dp_update_link_train(dp)) {
>> + DRM_ERROR("failed to update link training\n");
>> + break;
>> + }
>> + }
>> +
>> + /* Try 5 times, else fail and try at lower BW */
>> + if (tries == 5)
>> + DRM_DEBUG_KMS("Channel equalization failed 5 times\n");
>> +
>> + return -EINVAL;
>> +}
>> +
>> +static int cdn_dp_stop_link_train(struct cdn_dp_device *dp)
>> +{
>> + int ret = cdn_dp_set_pattern(dp, DP_TRAINING_PATTERN_DISABLE);
>> +
>> + if (ret)
>> + return ret;
>> +
>> + return cdn_dp_set_link_train(dp, DP_TRAINING_PATTERN_DISABLE);
>> +}
>> +
>> +static int cdn_dp_get_lower_link_rate(struct cdn_dp_device *dp)
>> +{
>> + switch (dp->link.rate) {
>> + case DP_LINK_BW_1_62:
>> + return -EINVAL;
>> + case DP_LINK_BW_2_7:
>> + dp->link.rate = DP_LINK_BW_1_62;
>> + break;
>> + case DP_LINK_BW_5_4:
>> + dp->link.rate = DP_LINK_BW_2_7;
>> + break;
>> + default:
>> + dp->link.rate = DP_LINK_BW_5_4;
>> + break;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +int cdn_dp_software_train_link(struct cdn_dp_device *dp)
>> +{
>> + int ret, stop_err;
>> + u8 link_config[2];
>> + u32 rate, sink_max, source_max;
>> +
>> + ret = drm_dp_dpcd_read(&dp->aux, DP_DPCD_REV, dp->dpcd,
>> + sizeof(dp->dpcd));
>> + if (ret < 0) {
>> + DRM_DEV_ERROR(dp->dev, "Failed to get caps %d\n", ret);
>> + return ret;
>> + }
>> +
>> + source_max = dp->lanes;
>> + sink_max = drm_dp_max_lane_count(dp->dpcd);
>> + dp->link.num_lanes = min(source_max, sink_max);
>> +
>> + source_max = drm_dp_bw_code_to_link_rate(CDN_DP_MAX_LINK_RATE);
>> + sink_max = drm_dp_max_link_rate(dp->dpcd);
>> + rate = min(source_max, sink_max);
>> + dp->link.rate = drm_dp_link_rate_to_bw_code(rate);
>> +
>> + link_config[0] = 0;
>> + link_config[1] = 0;
>> + if (dp->dpcd[DP_MAIN_LINK_CHANNEL_CODING] & 0x01)
>> + link_config[1] = DP_SET_ANSI_8B10B;
>> + drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, link_config, 2);
>> +
>> + while (true) {
>> +
>> + /* Write the link configuration data */
>> + link_config[0] = dp->link.rate;
>> + link_config[1] = dp->link.num_lanes;
>> + if (drm_dp_enhanced_frame_cap(dp->dpcd))
>> + link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
>> + drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, link_config, 2);
>> +
>> + ret = cdn_dp_link_training_clock_recovery(dp);
>> + if (ret) {
>> + if (!cdn_dp_get_lower_link_rate(dp))
>> + continue;
>> +
>> + DRM_ERROR("training clock recovery failed: %d\n", ret);
>> + break;
>> + }
>> +
>> + ret = cdn_dp_link_training_channel_equalization(dp);
>> + if (ret) {
>> + if (!cdn_dp_get_lower_link_rate(dp))
>> + continue;
>> +
>> + DRM_ERROR("training channel eq failed: %d\n", ret);
>> + break;
>> + }
>> +
>> + break;
>> + }
>> +
>> + stop_err = cdn_dp_stop_link_train(dp);
>> + if (stop_err) {
>> + DRM_ERROR("stop training fail, error: %d\n", stop_err);
>> + return stop_err;
>> + }
>> +
>> + return ret;
>> +}
>> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.c b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
>> index 979355d..e1273e6 100644
>> --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.c
>> +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.c
>> @@ -17,7 +17,9 @@
>> #include <linux/delay.h>
>> #include <linux/io.h>
>> #include <linux/iopoll.h>
>> +#include <linux/phy/phy.h>
>> #include <linux/reset.h>
>> +#include <soc/rockchip/rockchip_phy_typec.h>
>>
>> #include "cdn-dp-core.h"
>> #include "cdn-dp-reg.h"
>> @@ -189,7 +191,7 @@ static int cdn_dp_mailbox_send(struct cdn_dp_device *dp, u8 module_id,
>> return 0;
>> }
>>
>> -static int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
>> +int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val)
>> {
>> u8 msg[6];
>>
>> @@ -609,6 +611,31 @@ int cdn_dp_train_link(struct cdn_dp_device *dp)
>> {
>> int ret;
>>
>> + /*
>> + * DP firmware uses fixed phy config values to do training, but some
>> + * boards need to adjust these values to fit for their unique hardware
>> + * design. So if the phy is using custom config values, do software
>> + * link training instead of relying on firmware, if software training
>> + * fail, keep firmware training as a fallback if sw training fails.
>> + */
>> + ret = cdn_dp_software_train_link(dp);
>> + if (ret) {
>> + DRM_DEV_ERROR(dp->dev,
>> + "Failed to do software training %d\n", ret);
>> + goto do_fw_training;
>> + }
>> + ret = cdn_dp_reg_write(dp, SOURCE_HDTX_CAR, 0xf);
>> + if (ret) {
>> + DRM_DEV_ERROR(dp->dev,
>> + "Failed to write SOURCE_HDTX_CAR register %d\n", ret);
>> + goto do_fw_training;
>> + }
>> + dp->use_fw_training = false;
>> + return 0;
>> +
>> +do_fw_training:
>> + dp->use_fw_training = true;
>> + DRM_DEV_DEBUG_KMS(dp->dev, "use fw training\n");
>> ret = cdn_dp_training_start(dp);
>> if (ret) {
>> DRM_DEV_ERROR(dp->dev, "Failed to start training %d\n", ret);
>> @@ -623,7 +650,7 @@ int cdn_dp_train_link(struct cdn_dp_device *dp)
>>
>> DRM_DEV_DEBUG_KMS(dp->dev, "rate:0x%x, lanes:%d\n", dp->link.rate,
>> dp->link.num_lanes);
>> - return ret;
>> + return 0;
>> }
>>
>> int cdn_dp_set_video_status(struct cdn_dp_device *dp, int active)
>> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-reg.h b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
>> index 6580b11..3420771 100644
>> --- a/drivers/gpu/drm/rockchip/cdn-dp-reg.h
>> +++ b/drivers/gpu/drm/rockchip/cdn-dp-reg.h
>> @@ -137,7 +137,7 @@
>> #define HPD_EVENT_MASK 0x211c
>> #define HPD_EVENT_DET 0x2120
>>
>> -/* dpyx framer addr */
>> +/* dptx framer addr */
>> #define DP_FRAMER_GLOBAL_CONFIG 0x2200
>> #define DP_SW_RESET 0x2204
>> #define DP_FRAMER_TU 0x2208
>> @@ -431,6 +431,40 @@
>> /* Reference cycles when using lane clock as reference */
>> #define LANE_REF_CYC 0x8000
>>
>> +/* register CM_VID_CTRL */
>> +#define LANE_VID_REF_CYC(x) (((x) & (BIT(24) - 1)) << 0)
>> +#define NMVID_MEAS_TOLERANCE(x) (((x) & 0xf) << 24)
>> +
>> +/* register DP_TX_PHY_CONFIG_REG */
>> +#define DP_TX_PHY_TRAINING_ENABLE(x) ((x) & 1)
>> +#define DP_TX_PHY_TRAINING_TYPE_PRBS7 (0 << 1)
>> +#define DP_TX_PHY_TRAINING_TYPE_TPS1 (1 << 1)
>> +#define DP_TX_PHY_TRAINING_TYPE_TPS2 (2 << 1)
>> +#define DP_TX_PHY_TRAINING_TYPE_TPS3 (3 << 1)
>> +#define DP_TX_PHY_TRAINING_TYPE_TPS4 (4 << 1)
>> +#define DP_TX_PHY_TRAINING_TYPE_PLTPAT (5 << 1)
>> +#define DP_TX_PHY_TRAINING_TYPE_D10_2 (6 << 1)
>> +#define DP_TX_PHY_TRAINING_TYPE_HBR2CPAT (8 << 1)
>> +#define DP_TX_PHY_TRAINING_PATTERN(x) ((x) << 1)
>> +#define DP_TX_PHY_SCRAMBLER_BYPASS(x) (((x) & 1) << 5)
>> +#define DP_TX_PHY_ENCODER_BYPASS(x) (((x) & 1) << 6)
>> +#define DP_TX_PHY_SKEW_BYPASS(x) (((x) & 1) << 7)
>> +#define DP_TX_PHY_DISPARITY_RST(x) (((x) & 1) << 8)
>> +#define DP_TX_PHY_LANE0_SKEW(x) (((x) & 7) << 9)
>> +#define DP_TX_PHY_LANE1_SKEW(x) (((x) & 7) << 12)
>> +#define DP_TX_PHY_LANE2_SKEW(x) (((x) & 7) << 15)
>> +#define DP_TX_PHY_LANE3_SKEW(x) (((x) & 7) << 18)
>> +#define DP_TX_PHY_10BIT_ENABLE(x) (((x) & 1) << 21)
>> +
>> +/* register DP_FRAMER_GLOBAL_CONFIG */
>> +#define NUM_LANES(x) ((x) & 3)
>> +#define SST_MODE (0 << 2)
>> +#define RG_EN (0 << 4)
>> +#define GLOBAL_EN BIT(3)
>> +#define NO_VIDEO BIT(5)
>> +#define ENC_RST_DIS BIT(6)
>> +#define WR_VHSYNC_FALL BIT(7)
>> +
>> enum voltage_swing_level {
>> VOLTAGE_LEVEL_0,
>> VOLTAGE_LEVEL_1,
>> @@ -476,6 +510,7 @@ int cdn_dp_set_host_cap(struct cdn_dp_device *dp, u8 lanes, bool flip);
>> int cdn_dp_event_config(struct cdn_dp_device *dp);
>> u32 cdn_dp_get_event(struct cdn_dp_device *dp);
>> int cdn_dp_get_hpd_status(struct cdn_dp_device *dp);
>> +int cdn_dp_reg_write(struct cdn_dp_device *dp, u16 addr, u32 val);
>> ssize_t cdn_dp_dpcd_write(struct cdn_dp_device *dp, u32 addr,
>> u8 *data, u16 len);
>> ssize_t cdn_dp_dpcd_read(struct cdn_dp_device *dp, u32 addr,
>> @@ -489,4 +524,5 @@ int cdn_dp_config_video(struct cdn_dp_device *dp);
>> int cdn_dp_audio_stop(struct cdn_dp_device *dp, struct audio_info *audio);
>> int cdn_dp_audio_mute(struct cdn_dp_device *dp, bool enable);
>> int cdn_dp_audio_config(struct cdn_dp_device *dp, struct audio_info *audio);
>> +int cdn_dp_software_train_link(struct cdn_dp_device *dp);
>> #endif /* _CDN_DP_REG_H */
>> --
>> 2.7.4
>>
^ permalink raw reply
* [PATCH v8 10/15] cpufreq: Add Kryo CPU scaling driver
From: Viresh Kumar @ 2018-05-18 1:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1526555955-29960-11-git-send-email-ilialin@codeaurora.org>
On 17-05-18, 14:19, Ilia Lin wrote:
> +static int __init qcom_cpufreq_kryo_driver_init(void)
> +{
> + size_t len;
> + int ret = 0;
> + u32 versions;
> + enum _msm8996_version msm8996_version;
> + u8 *speedbin;
> + struct device *cpu_dev_silver, *cpu_dev_gold;
> + struct device_node *np;
> + struct nvmem_cell *speedbin_nvmem;
> + struct platform_device *pdev;
> + struct opp_table *opp_silver = NULL;
> + struct opp_table *opp_gold = NULL;
No need to initialize them and you may want to arrange all above in
decreasing order of their length.
> +
> + cpu_dev_silver = get_cpu_device(SILVER_LEAD);
> + if (IS_ERR_OR_NULL(cpu_dev_silver))
> + return PTR_ERR(cpu_dev_silver);
> +
> + cpu_dev_gold = get_cpu_device(SILVER_LEAD);
> + if (IS_ERR_OR_NULL(cpu_dev_gold))
> + return PTR_ERR(cpu_dev_gold);
> +
> + msm8996_version = qcom_cpufreq_kryo_get_msm_id();
> + if (NUM_OF_MSM8996_VERSIONS == msm8996_version) {
> + dev_err(cpu_dev_silver, "Not Snapdragon 820/821!");
> + return -ENODEV;
> + }
> +
> + np = dev_pm_opp_of_get_opp_desc_node(cpu_dev_silver);
> + if (IS_ERR_OR_NULL(np))
> + return PTR_ERR(np);
> +
> + if (!of_device_is_compatible(np, "operating-points-v2-kryo-cpu")) {
> + ret = -ENOENT;
> + goto free_np;
> + }
> +
> + speedbin_nvmem = of_nvmem_cell_get(np, NULL);
> + if (IS_ERR(speedbin_nvmem)) {
> + ret = PTR_ERR(speedbin_nvmem);
> + dev_err(cpu_dev_silver, "Could not get nvmem cell: %d\n", ret);
> + goto free_np;
> + }
> +
> + speedbin = nvmem_cell_read(speedbin_nvmem, &len);
> + nvmem_cell_put(speedbin_nvmem);
> +
> + switch (msm8996_version) {
> + case MSM8996_V3:
> + versions = 1 << (unsigned int)(*speedbin);
> + break;
> + case MSM8996_SG:
> + versions = 1 << ((unsigned int)(*speedbin) + 4);
> + break;
> + default:
> + BUG();
> + break;
> + }
> +
> + opp_silver = dev_pm_opp_set_supported_hw(cpu_dev_silver,&versions,1);
> + if (IS_ERR_OR_NULL(opp_silver)) {
This API doesn't return NULL and so IS_ERR() would be sufficient.
> + dev_err(cpu_dev_silver, "Failed to set supported hardware\n");
> + ret = PTR_ERR(opp_silver);
> + goto free_np;
> + }
> +
> + opp_gold = dev_pm_opp_set_supported_hw(cpu_dev_gold,&versions,1);
> + if (IS_ERR_OR_NULL(opp_gold)) {
same here.
> + dev_err(cpu_dev_gold, "Failed to set supported hardware\n");
> + ret = PTR_ERR(opp_gold);
> + goto free_opp_silver;
> + }
> +
> + pdev = platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
> + if (!IS_ERR_OR_NULL(pdev))
> + goto out;
Simply return from here and remove the useless label out.
> +
> + ret = PTR_ERR(pdev);
> + dev_err(cpu_dev_silver, "Failed to register platform device\n");
> + dev_pm_opp_put_supported_hw(opp_gold);
> +
> +free_opp_silver:
> + dev_pm_opp_put_supported_hw(opp_silver);
> +
> +free_np:
> + of_node_put(np);
> +
> +out:
> + return ret;
> +}
> +late_initcall(qcom_cpufreq_kryo_driver_init);
Please resend only this patch now or just paste the new code in a mail
here so that I can review it quickly and then you can resend the final
version. Most of the patches aren't changing anyway.
--
viresh
^ permalink raw reply
* [PATCH v5 4/4] drm/rockchip: support dp training outside dp firmware
From: Brian Norris @ 2018-05-18 1:45 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <d4c38236-7455-ccd5-a1d9-a000b7d78be9@rock-chips.com>
On Thu, May 17, 2018 at 6:41 PM, hl <hl@rock-chips.com> wrote:
> On Thursday, May 17, 2018 09:51 PM, Sean Paul wrote:
>> On Thu, May 17, 2018 at 05:18:00PM +0800, Lin Huang wrote:
>>> DP firmware uses fixed phy config values to do training, but some
>>> boards need to adjust these values to fit for their unique hardware
>>> design. So get phy config values from dts and use software link training
>>> instead of relying on firmware, if software training fail, keep firmware
>>> training as a fallback if sw training fails.
>>>
>>> Signed-off-by: Chris Zhong <zyw@rock-chips.com>
>>> Signed-off-by: Lin Huang <hl@rock-chips.com>
>>> ---
>>> Changes in v2:
>>> - update patch following Enric suggest
>>> Changes in v3:
>>> - use variable fw_training instead sw_training_success
>>> - base on DP SPCE, if training fail use lower link rate to retry training
>>> Changes in v4:
>>> - improve cdn_dp_get_lower_link_rate() and cdn_dp_software_train_link() follow Sean suggest
>>> Changes in v5:
>>> - fix some whitespcae issue
>>>
>>> drivers/gpu/drm/rockchip/Makefile | 3 +-
>>> drivers/gpu/drm/rockchip/cdn-dp-core.c | 24 +-
>>> drivers/gpu/drm/rockchip/cdn-dp-core.h | 2 +
>>> drivers/gpu/drm/rockchip/cdn-dp-link-training.c | 420 ++++++++++++++++++++++++
>>> drivers/gpu/drm/rockchip/cdn-dp-reg.c | 31 +-
>>> drivers/gpu/drm/rockchip/cdn-dp-reg.h | 38 ++-
>>> 6 files changed, 505 insertions(+), 13 deletions(-)
>>> create mode 100644 drivers/gpu/drm/rockchip/cdn-dp-link-training.c
>>>
...
>>> diff --git a/drivers/gpu/drm/rockchip/cdn-dp-link-training.c b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
>>> new file mode 100644
>>> index 0000000..73c3290
>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/rockchip/cdn-dp-link-training.c
>>> @@ -0,0 +1,420 @@
>>> +// SPDX-License-Identifier: GPL-2.0
>>> +/*
>>> + * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
>>> + * Author: Chris Zhong <zyw@rock-chips.com>
>>> + */
>>> +
>>> +#include <linux/device.h>
>>> +#include <linux/delay.h>
>>> +#include <linux/phy/phy.h>
>>> +#include <soc/rockchip/rockchip_phy_typec.h>
>>> +
>>> +#include "cdn-dp-core.h"
>>> +#include "cdn-dp-reg.h"
>>> +
>>> +static void cdn_dp_set_signal_levels(struct cdn_dp_device *dp)
>>> +{
>>> + struct cdn_dp_port *port = dp->port[dp->active_port];
>>> + struct rockchip_typec_phy *tcphy = phy_get_drvdata(port->phy);
>>
>> You ignored Brian's comment on the previous patch:
>> This is still antithetical to the PHY framework; you're assuming that
>> this is a particular type of PHY here.
>>
>> FWIW, the mediatek drm driver also assumes a certain PHY type. A quick grep of
>> drivers/ shows that the only other non-phy/ driver using this function
>> (pinctrl-tegra-xusb.c) also casts it.
>>
>> Sean
>
> Thanks Sean, except phy framework have new API to handle it, i have not
> idea how to do it in a better way.
Well, if Mediatek can do it for their MIPI and HDMI, then maybe we just do it...
Brian
^ permalink raw reply
* [PATCH] KVM: arm/arm64: add WARN_ON if size is not PAGE_SIZE aligned in unmap_stage2_range
From: Jia He @ 2018-05-18 1:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <25dbb8c1-631f-c810-4d75-349a0b291cf8@arm.com>
Hi Suzuki
On 5/17/2018 11:03 PM, Suzuki K Poulose Wrote:
> On 17/05/18 13:46, Jia He wrote:
>> Hi Suzuki
>>
>> On 5/17/2018 4:17 PM, Suzuki K Poulose Wrote:
>>>
>>> Hi Jia,
>>>
>>> On 17/05/18 07:11, Jia He wrote:
>>>> I ever met a panic under memory pressure tests(start 20 guests and run
>>>> memhog in the host).
>>>
>>> Please avoid using "I" in the commit description and preferably stick to
>>> an objective description.
>>
>> Thanks for the pointing
>>
>>>
>>>>
>>>> The root cause might be what I fixed at [1]. But from arm kvm points of
>>>> view, it would be better we caught the exception earlier and clearer.
>>>>
>>>> If the size is not PAGE_SIZE aligned, unmap_stage2_range might unmap the
>>>> wrong(more or less) page range. Hence it caused the "BUG: Bad page
>>>> state"
>>>
>>> I don't see why we should ever panic with a "positive" size value. Anyways,
>>> the unmap requests must be in units of pages. So this check might be useful.
>>>
>>>
>>
>> good question,
>>
>> After further digging, maybe we need to harden the break condition as below?
>> diff --git a/virt/kvm/arm/mmu.c b/virt/kvm/arm/mmu.c
>> index 7f6a944..dac9b2e 100644
>> --- a/virt/kvm/arm/mmu.c
>> +++ b/virt/kvm/arm/mmu.c
>> @@ -217,7 +217,7 @@ static void unmap_stage2_ptes(struct kvm *kvm, pmd_t *pmd,
>>
>> ???????????????????????? put_page(virt_to_page(pte));
>> ???????????????? }
>> -?????? } while (pte++, addr += PAGE_SIZE, addr != end);
>> +?????? } while (pte++, addr += PAGE_SIZE, addr < end);
>
> I don't think this change is need as stage2_pgd_addr_end(addr, end) must return
> the smaller of the next entry or end. Thus we can't miss "addr" == "end".
If it passes addr=202920000,size=fe00 to unmap_stage2_range->
...->unmap_stage2_ptes
unmap_stage2_ptes will get addr=202920000,end=20292fe00
after first while loop addr=202930000, end=20292fe00, then addr!=end
Thus it will touch another pages by put_pages() in the 2nd loop.
--
Cheers,
Jia
^ permalink raw reply
* [PATCH 0/5] Add gpio support for Action Semi S900 SoC
From: Manivannan Sadhasivam @ 2018-05-18 2:30 UTC (permalink / raw)
To: linux-arm-kernel
This patchset adds gpio support for Actions Semi S900 SoC by extending
the pinctrl driver. There were previous patches submitted for adding a
standalone gpio driver based on gpiolib. But later on it has been realised
that the gpio functionality is closely tied with pinctrl subsystem for this
OWL family processors. So, having a separate gpio driver will make it hard
to add further functionalities in future. Hence, we decided to drop the
previous patches below adding a standalone gpio support:
dt-bindings: gpio: Add gpio nodes for Actions S900 SoC
arm64: dts: actions: Add S900 gpio nodes
arm64: dts: actions: Add gpio line names to Bubblegum-96 board
gpio: Add gpio driver for Actions OWL S900 SoC
MAINTAINERS: Add Actions Semi S900 pinctrl and gpio entries
This patchset consits of incremental patches which will apply with the
previous pinctrl series: Add Actions Semi S900 pinctrl and gpio support,
excluding the dropped patches mentioned above.
Thanks,
Mani
Manivannan Sadhasivam (5):
dt-bindings: pinctrl: Add gpio bindings for Actions S900 SoC
arm64: dts: actions: Add gpio properties to pinctrl node for S900
arm64: dts: actions: Add gpio line names to Bubblegum-96 board
pinctrl: actions: Add gpio support for Actions S900 SoC
MAINTAINERS: Add Actions Semi S900 pinctrl entries
.../bindings/pinctrl/actions,s900-pinctrl.txt | 13 ++
MAINTAINERS | 2 +
arch/arm64/boot/dts/actions/s900-bubblegum-96.dts | 175 +++++++++++++++++
arch/arm64/boot/dts/actions/s900.dtsi | 2 +
drivers/pinctrl/actions/Kconfig | 1 +
drivers/pinctrl/actions/pinctrl-owl.c | 206 +++++++++++++++++++++
drivers/pinctrl/actions/pinctrl-owl.h | 20 ++
drivers/pinctrl/actions/pinctrl-s900.c | 29 ++-
8 files changed, 447 insertions(+), 1 deletion(-)
--
2.14.1
^ permalink raw reply
* [PATCH 1/5] dt-bindings: pinctrl: Add gpio bindings for Actions S900 SoC
From: Manivannan Sadhasivam @ 2018-05-18 2:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518023056.7869-1-manivannan.sadhasivam@linaro.org>
Add gpio bindings for Actions Semi S900 SoC.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
.../devicetree/bindings/pinctrl/actions,s900-pinctrl.txt | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
index fb87c7d74f2e..300a50783aab 100644
--- a/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/actions,s900-pinctrl.txt
@@ -8,6 +8,15 @@ Required Properties:
- reg: Should contain the register base address and size of
the pin controller.
- clocks: phandle of the clock feeding the pin controller
+- gpio-controller: Marks the device node as a GPIO controller.
+- #gpio-cells: Should be two. The first cell is the gpio pin number
+ and the second cell is used for optional parameters.
+- interrupt-controller: Marks the device node as an interrupt controller.
+- #interrupt-cells: Specifies the number of cells needed to encode an
+ interrupt. Shall be set to 2. The first cell
+ defines the interrupt number, the second encodes
+ the trigger flags described in
+ bindings/interrupt-controller/interrupts.txt
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
@@ -164,6 +173,10 @@ Example:
compatible = "actions,s900-pinctrl";
reg = <0x0 0xe01b0000 0x0 0x1000>;
clocks = <&cmu CLK_GPIO>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
uart2-default: uart2-default {
pinmux {
--
2.14.1
^ permalink raw reply related
* [PATCH 2/5] arm64: dts: actions: Add gpio properties to pinctrl node for S900
From: Manivannan Sadhasivam @ 2018-05-18 2:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518023056.7869-1-manivannan.sadhasivam@linaro.org>
Add gpio properties to pinctrl node for Actions Semi S900 SoC.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
arch/arm64/boot/dts/actions/s900.dtsi | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/boot/dts/actions/s900.dtsi b/arch/arm64/boot/dts/actions/s900.dtsi
index 0156483f0f4d..05f31a954733 100644
--- a/arch/arm64/boot/dts/actions/s900.dtsi
+++ b/arch/arm64/boot/dts/actions/s900.dtsi
@@ -178,6 +178,8 @@
compatible = "actions,s900-pinctrl";
reg = <0x0 0xe01b0000 0x0 0x1000>;
clocks = <&cmu CLK_GPIO>;
+ gpio-controller;
+ #gpio-cells = <2>;
};
timer: timer at e0228000 {
--
2.14.1
^ permalink raw reply related
* [PATCH 3/5] arm64: dts: actions: Add gpio line names to Bubblegum-96 board
From: Manivannan Sadhasivam @ 2018-05-18 2:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20180518023056.7869-1-manivannan.sadhasivam@linaro.org>
Add gpio line names to Actions Semi S900 based Bubblegum-96 board.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
arch/arm64/boot/dts/actions/s900-bubblegum-96.dts | 175 ++++++++++++++++++++++
1 file changed, 175 insertions(+)
diff --git a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
index ff043c961d75..d0ba35df9015 100644
--- a/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
+++ b/arch/arm64/boot/dts/actions/s900-bubblegum-96.dts
@@ -34,3 +34,178 @@
status = "okay";
clocks = <&cmu CLK_UART5>;
};
+
+/*
+ * GPIO name legend: proper name = the GPIO line is used as GPIO
+ * NC = not connected (pin out but not routed from the chip to
+ * anything the board)
+ * "[PER]" = pin is muxed for [peripheral] (not GPIO)
+ * LSEC = Low Speed External Connector
+ * HSEC = High Speed External Connector
+ *
+ * Line names are taken from the schematic "Schematics Bubblegum96"
+ * version v1.0
+ *
+ * For the lines routed to the external connectors the
+ * lines are named after the 96Boards CE Specification 1.0,
+ * Appendix "Expansion Connector Signal Description".
+ *
+ * When the 96Boards naming of a line and the schematic name of
+ * the same line are in conflict, the 96Boards specification
+ * takes precedence, which means that the external UART on the
+ * LSEC is named UART0 while the schematic and SoC names this
+ * UART2. Only exception is the I2C lines for which the schematic
+ * naming has been preferred. This is only for the informational
+ * lines i.e. "[FOO]", the GPIO named lines "GPIO-A" thru "GPIO-L"
+ * are the only ones actually used for GPIO.
+ */
+
+&pinctrl {
+ gpio-line-names =
+ "GPIO-A", /* GPIO_0, LSEC pin 23 */
+ "GPIO-B", /* GPIO_1, LSEC pin 24 */
+ "GPIO-C", /* GPIO_2, LSEC pin 25 */
+ "GPIO-D", /* GPIO_3, LSEC pin 26 */
+ "GPIO-E", /* GPIO_4, LSEC pin 27 */
+ "GPIO-F", /* GPIO_5, LSEC pin 28 */
+ "GPIO-G", /* GPIO_6, LSEC pin 29 */
+ "GPIO-H", /* GPIO_7, LSEC pin 30 */
+ "GPIO-I", /* GPIO_8, LSEC pin 31 */
+ "GPIO-J", /* GPIO_9, LSEC pin 32 */
+ "NC", /* GPIO_10 */
+ "NC", /* GPIO_11 */
+ "SIRQ2_1V8", /* GPIO_12 */
+ "PCM0_OUT", /* GPIO_13 */
+ "WIFI_LED", /* GPIO_14 */
+ "PCM0_SYNC", /* GPIO_15 */
+ "PCM0_CLK", /* GPIO_16 */
+ "PCM0_IN", /* GPIO_17 */
+ "BT_LED", /* GPIO_18 */
+ "LED0", /* GPIO_19 */
+ "LED1", /* GPIO_20 */
+ "JTAG_TCK", /* GPIO_21 */
+ "JTAG_TMS", /* GPIO_22 */
+ "JTAG_TDI", /* GPIO_23 */
+ "JTAG_TDO", /* GPIO_24 */
+ "[UART1_RxD]", /* GPIO_25, LSEC pin 13 */
+ "NC", /* GPIO_26 */
+ "[UART1_TxD]", /* GPIO_27, LSEC pin 11 */
+ "SD0_D0", /* GPIO_28 */
+ "SD0_D1", /* GPIO_29 */
+ "SD0_D2", /* GPIO_30 */
+ "SD0_D3", /* GPIO_31 */
+ "SD1_D0", /* GPIO_32 */
+ "SD1_D1", /* GPIO_33 */
+ "SD1_D2", /* GPIO_34 */
+ "SD1_D3", /* GPIO_35 */
+ "SD0_CMD", /* GPIO_36 */
+ "SD0_CLK", /* GPIO_37 */
+ "SD1_CMD", /* GPIO_38 */
+ "SD1_CLK", /* GPIO_39 */
+ "SPI0_SCLK", /* GPIO_40, LSEC pin 8 */
+ "SPI0_CS", /* GPIO_41, LSEC pin 12 */
+ "SPI0_DIN", /* GPIO_42, LSEC pin 10 */
+ "SPI0_DOUT", /* GPIO_43, LSEC pin 14 */
+ "I2C5_SDATA", /* GPIO_44, HSEC pin 36 */
+ "I2C5_SCLK", /* GPIO_45, HSEC pin 38 */
+ "UART0_RX", /* GPIO_46, LSEC pin 7 */
+ "UART0_TX", /* GPIO_47, LSEC pin 5 */
+ "UART0_RTSB", /* GPIO_48, LSEC pin 9 */
+ "UART0_CTSB", /* GPIO_49, LSEC pin 3 */
+ "I2C4_SCLK", /* GPIO_50, HSEC pin 32 */
+ "I2C4_SDATA", /* GPIO_51, HSEC pin 34 */
+ "I2C0_SCLK", /* GPIO_52 */
+ "I2C0_SDATA", /* GPIO_53 */
+ "I2C1_SCLK", /* GPIO_54, LSEC pin 15 */
+ "I2C1_SDATA", /* GPIO_55, LSEC pin 17 */
+ "I2C2_SCLK", /* GPIO_56, LSEC pin 19 */
+ "I2C2_SDATA", /* GPIO_57, LSEC pin 21 */
+ "CSI0_DN0", /* GPIO_58, HSEC pin 10 */
+ "CSI0_DP0", /* GPIO_59, HSEC pin 8 */
+ "CSI0_DN1", /* GPIO_60, HSEC pin 16 */
+ "CSI0_DP1", /* GPIO_61, HSEC pin 14 */
+ "CSI0_CN", /* GPIO_62, HSEC pin 4 */
+ "CSI0_CP", /* GPIO_63, HSEC pin 2 */
+ "CSI0_DN2", /* GPIO_64, HSEC pin 22 */
+ "CSI0_DP2", /* GPIO_65, HSEC pin 20 */
+ "CSI0_DN3", /* GPIO_66, HSEC pin 28 */
+ "CSI0_DP3", /* GPIO_67, HSEC pin 26 */
+ "[CLK0]", /* GPIO_68, HSEC pin 15 */
+ "CSI1_DN0", /* GPIO_69, HSEC pin 44 */
+ "CSI1_DP0", /* GPIO_70, HSEC pin 42 */
+ "CSI1_DN1", /* GPIO_71, HSEC pin 50 */
+ "CSI1_DP1", /* GPIO_72, HSEC pin 48 */
+ "CSI1_CN", /* GPIO_73, HSEC pin 56 */
+ "CSI1_CP", /* GPIO_74, HSEC pin 54 */
+ "[CLK1]", /* GPIO_75, HSEC pin 17 */
+ "[GPIOD0]", /* GPIO_76 */
+ "[GPIOD1]", /* GPIO_77 */
+ "BT_RST_N", /* GPIO_78 */
+ "EXT_DC_EN", /* GPIO_79 */
+ "[PCM_DI]", /* GPIO_80, LSEC pin 22 */
+ "[PCM_DO]", /* GPIO_81, LSEC pin 20 */
+ "[PCM_CLK]", /* GPIO_82, LSEC pin 18 */
+ "[PCM_FS]", /* GPIO_83, LSEC pin 16 */
+ "WAKE_BT", /* GPIO_84 */
+ "WL_REG_ON", /* GPIO_85 */
+ "NC", /* GPIO_86 */
+ "NC", /* GPIO_87 */
+ "NC", /* GPIO_88 */
+ "NC", /* GPIO_89 */
+ "NC", /* GPIO_90 */
+ "WIFI_WAKE", /* GPIO_91 */
+ "BT_WAKE", /* GPIO_92 */
+ "NC", /* GPIO_93 */
+ "OTG_EN2", /* GPIO_94 */
+ "OTG_EN", /* GPIO_95 */
+ "DSI_DP3", /* GPIO_96, HSEC pin 45 */
+ "DSI_DN3", /* GPIO_97, HSEC pin 47 */
+ "DSI_DP1", /* GPIO_98, HSEC pin 33 */
+ "DSI_DN1", /* GPIO_99, HSEC pin 35 */
+ "DSI_CP", /* GPIO_100, HSEC pin 21 */
+ "DSI_CN", /* GPIO_101, HSEC pin 23 */
+ "DSI_DP0", /* GPIO_102, HSEC pin 27 */
+ "DSI_DN0", /* GPIO_103, HSEC pin 29 */
+ "DSI_DP2", /* GPIO_104, HSEC pin 39 */
+ "DSI_DN2", /* GPIO_105, HSEC pin 41 */
+ "N0_D0", /* GPIO_106 */
+ "N0_D1", /* GPIO_107 */
+ "N0_D2", /* GPIO_108 */
+ "N0_D3", /* GPIO_109 */
+ "N0_D4", /* GPIO_110 */
+ "N0_D5", /* GPIO_111 */
+ "N0_D6", /* GPIO_112 */
+ "N0_D7", /* GPIO_113 */
+ "N0_DQS", /* GPIO_114 */
+ "N0_DQSN", /* GPIO_115 */
+ "NC", /* GPIO_116 */
+ "NC", /* GPIO_117 */
+ "NC", /* GPIO_118 */
+ "N0_CEB1", /* GPIO_119 */
+ "CARD_DT", /* GPIO_120 */
+ "N0_CEB3", /* GPIO_121 */
+ "SD_DAT0", /* GPIO_122, HSEC pin 1 */
+ "SD_DAT1", /* GPIO_123, HSEC pin 3 */
+ "SD_DAT2", /* GPIO_124, HSEC pin 5 */
+ "SD_DAT3", /* GPIO_125, HSEC pin 7 */
+ "NC", /* GPIO_126 */
+ "NC", /* GPIO_127 */
+ "[PWR_BTN_N]", /* GPIO_128, LSEC pin 4 */
+ "[RST_BTN_N]", /* GPIO_129, LSEC pin 6 */
+ "NC", /* GPIO_130 */
+ "SD_CMD", /* GPIO_131 */
+ "GPIO-L", /* GPIO_132, LSEC pin 34 */
+ "GPIO-K", /* GPIO_133, LSEC pin 33 */
+ "NC", /* GPIO_134 */
+ "SD_SCLK", /* GPIO_135 */
+ "NC", /* GPIO_136 */
+ "JTAG_TRST", /* GPIO_137 */
+ "I2C3_SCLK", /* GPIO_138 */
+ "LED2", /* GPIO_139 */
+ "LED3", /* GPIO_140 */
+ "I2C3_SDATA", /* GPIO_141 */
+ "UART3_RX", /* GPIO_142 */
+ "UART3_TX", /* GPIO_143 */
+ "UART3_RTSB", /* GPIO_144 */
+ "UART3_CTSB"; /* GPIO_145 */
+};
--
2.14.1
^ 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