* [PATCH] drm/panel: simple: Add Sharp LQ035Q7DB03 panel support
From: Vladimir Zapolskiy @ 2018-05-21 23:23 UTC (permalink / raw)
To: Thierry Reding, Rob Herring; +Cc: David Airlie, devicetree, dri-devel
The change adds support for Sharp LQ035Q7DB03 3.5" QVGA panel.
Note that this aged panel is already found in the kernel sources,
for instance in board mach files mach-mx21ads.c, mach-mx27ads.c,
mach-pcm043.c, lpd270.c and imx27-phytec-phycore-rdk.dts.
Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
---
.../bindings/display/panel/sharp,lq035q7db03.txt | 7 ++++++
drivers/gpu/drm/panel/panel-simple.c | 27 ++++++++++++++++++++++
2 files changed, 34 insertions(+)
create mode 100644 Documentation/devicetree/bindings/display/panel/sharp,lq035q7db03.txt
diff --git a/Documentation/devicetree/bindings/display/panel/sharp,lq035q7db03.txt b/Documentation/devicetree/bindings/display/panel/sharp,lq035q7db03.txt
new file mode 100644
index 0000000..42027e5
--- /dev/null
+++ b/Documentation/devicetree/bindings/display/panel/sharp,lq035q7db03.txt
@@ -0,0 +1,7 @@
+Sharp LQ035Q7DB03 3.5" QVGA TFT LCD panel
+
+Required properties:
+- compatible: should be "sharp,lq035q7db03"
+
+This binding is compatible with the simple-panel binding, which is specified
+in simple-panel.txt in this directory.
diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
index cbf1ab4..8970261 100644
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -1764,6 +1764,30 @@ static const struct panel_desc samsung_ltn140at29_301 = {
},
};
+static const struct drm_display_mode sharp_lq035q7db03_mode = {
+ .clock = 5500,
+ .hdisplay = 240,
+ .hsync_start = 240 + 16,
+ .hsync_end = 240 + 16 + 7,
+ .htotal = 240 + 16 + 7 + 5,
+ .vdisplay = 320,
+ .vsync_start = 320 + 9,
+ .vsync_end = 320 + 9 + 1,
+ .vtotal = 320 + 9 + 1 + 7,
+ .vrefresh = 60,
+};
+
+static const struct panel_desc sharp_lq035q7db03 = {
+ .modes = &sharp_lq035q7db03_mode,
+ .num_modes = 1,
+ .bpc = 6,
+ .size = {
+ .width = 54,
+ .height = 72,
+ },
+ .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
+};
+
static const struct display_timing sharp_lq101k1ly04_timing = {
.pixelclock = { 60000000, 65000000, 80000000 },
.hactive = { 1280, 1280, 1280 },
@@ -2236,6 +2260,9 @@ static const struct of_device_id platform_of_match[] = {
.compatible = "samsung,ltn140at29-301",
.data = &samsung_ltn140at29_301,
}, {
+ .compatible = "sharp,lq035q7db03",
+ .data = &sharp_lq035q7db03,
+ }, {
.compatible = "sharp,lq101k1ly04",
.data = &sharp_lq101k1ly04,
}, {
--
2.10.2
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply related
* [PATCH v3] of: unittest: for strings, account for trailing \0 in property length field
From: Stefan M Schaeckeler @ 2018-05-21 23:26 UTC (permalink / raw)
To: Rob Herring, Frank Rowand, devicetree@vger.kernel.org
For strings, account for trailing \0 in property length field:
This is consistent with how dtc builds string properties.
Function __of_prop_dup() would misbehave on such properties as it duplicates
properties based on the property length field creating new string values
without trailing \0s.
Signed-off-by: Stefan M Schaeckeler <sschaeck@cisco.com>
Reviewed-by: Frank Rowand <frank.rowand@sony.com>
Tested-by: Frank Rowand <frank.rowand@sony.com>
---
Changes in v3:
- forgot one string in v2.
Changes in v2:
- fixed spacing around + sign.
drivers/of/unittest.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c
index 6bb37c1..ecee50d 100644
--- a/drivers/of/unittest.c
+++ b/drivers/of/unittest.c
@@ -165,20 +165,20 @@ static void __init of_unittest_dynamic(void)
/* Add a new property - should pass*/
prop->name = "new-property";
prop->value = "new-property-data";
- prop->length = strlen(prop->value);
+ prop->length = strlen(prop->value) + 1;
unittest(of_add_property(np, prop) == 0, "Adding a new property failed\n");
/* Try to add an existing property - should fail */
prop++;
prop->name = "new-property";
prop->value = "new-property-data-should-fail";
- prop->length = strlen(prop->value);
+ prop->length = strlen(prop->value) + 1;
unittest(of_add_property(np, prop) != 0,
"Adding an existing property should have failed\n");
/* Try to modify an existing property - should pass */
prop->value = "modify-property-data-should-pass";
- prop->length = strlen(prop->value);
+ prop->length = strlen(prop->value) + 1;
unittest(of_update_property(np, prop) == 0,
"Updating an existing property should have passed\n");
@@ -186,7 +186,7 @@ static void __init of_unittest_dynamic(void)
prop++;
prop->name = "modify-property";
prop->value = "modify-missing-property-data-should-pass";
- prop->length = strlen(prop->value);
+ prop->length = strlen(prop->value) + 1;
unittest(of_update_property(np, prop) == 0,
"Updating a missing property should have passed\n");
--
2.10.3.dirty
^ permalink raw reply related
* Re: [PATCH v3 1/2] regulator: dt-bindings: add QCOM RPMh regulator bindings
From: David Collins @ 2018-05-22 0:00 UTC (permalink / raw)
To: Doug Anderson
Cc: Mark Brown, Liam Girdwood, Rob Herring, Mark Rutland,
linux-arm-msm, Linux ARM, devicetree, LKML, Rajendra Nayak,
Stephen Boyd
In-Reply-To: <CAD=FV=XfSGs14VB464cvMGDNwGS4yvSXjN8itZLffm+Sj-D=ww@mail.gmail.com>
On 05/21/2018 11:01 AM, Doug Anderson wrote:
> On Fri, May 18, 2018 at 5:46 PM, David Collins <collinsd@codeaurora.org> wrote:
...
>> Something to keep in mind about the downstream rpmh-regulator driver is
>> that it caches the initial voltages specified in device tree and only
>> sends them after a consumer driver makes a regulator framework call. This
>> saves time during boot and ensures that requests are not made for
>> regulators that no Linux consumer cares about.
>
> You're saying that in the downstream driver you'd specify
> "initial-voltage" in the device tree and:
>
> * This voltage would be reported by any subsequent get_voltage() calls
>
> * This voltage would _not_ be communicated to RPMh.
>
> That seems really strange because you're essentially going to be
> returning something from get_voltage() that could be a lie. You don't
> know if the BIOS actually set the value or not but you'll claim that
> it did. It also doesn't seem to match what I see in the downstream
> driver. There I see it read "qcom,init-voltage" and then do a
> "rpmh_regulator_set_reg()". Thus my reading of the downstream driver
> is that it should do the same requests that you're doing.
In the downstream rpmh-regulator driver [1], the value specified via the
"qcom,init-voltage" DT property is only sent to RPMh at probe time if the
"qcom,send-defaults" property is also specified. "qcom,send-defaults" is
currently specified only for PMI8998 BOB. The rpmh_regulator_set_reg()
function only updates the cached RPMh request value to be sent in the next
request. The rpmh_regulator_send_aggregate_requests() function must be
called to actually issue the request.
Returning the cached (but not sent) initial voltage equal to the min
constraint voltage in get_voltage() calls should not cause any problems.
This represents the highest voltage that is guaranteed to be output by the
regulator. Consumer's should call regulator_set_voltage() to specify
their voltage needs. If they simply call regulator_enable(), then the
cached voltage will be sent along with the enable request.
>> It is generally not safe to request all regulators to be set to the
>> minimum allowed voltage. Special care will be needed with the upstream
>> qcom-rpmh-regulator driver to avoid disrupting the boot up state of
>> regulators that are needed by other subsystems. Therefore, I would like
>> to keep the initial voltage feature supported.
>
> I was asking for specific examples. Do you have any?
I was able to track down an example that requires initialization at a
non-minimum voltage: PM8998 LDO 13 on SDM845 MTP. This regulator supplies
the microSD card with a voltage in the range 1.8 V to 2.96 V. The boot
loader leaves this regulator enabled at 2.96 V. It is only guaranteed to
be safe to reduce the voltage to 1.8 V on UHS type cards and only after
following the proper SD identification and command sequence.
> BTW: have I already said how terrible of a design it is that you can't
> read back the voltages that the BIOS set? If we could just read back
> what the BIOS set then everything would work great and we could stop
> talking about this.
Even if such reading were feasible, it would not help the situation
substantially. Very few requests are made via the AP RSC before Linux
kernel boot, so 0 V values would still be read back for most regulators.
Additionally, reading the true hardware state (as opposed to what AP RSC
voted before Linux boot) would also not be helpful. For example, if a
regulator was physically enabled due to a vote via modem RSC and
qcom-rpmh-regulator returned is_enabled() == true inside of a
regulator_enable() call, then no enable request would be made via the AP
RSC which would result in the regulator turning off unexpectedly later
when the modem requests to disable the regulator.
Take care,
David
[1]:
https://source.codeaurora.org/quic/la/kernel/msm-4.9/tree/drivers/regulator/rpmh-regulator.c?h=msm-4.9
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* Re: [PATCH RFC 03/24] arm64/dts: add switch-delay for meson mali
From: Qiang Yu @ 2018-05-22 0:48 UTC (permalink / raw)
To: Neil Armstrong
Cc: Simon Shields, devicetree, Connor Abbott, Marek Vasut,
Andrei Paulau, dri-devel, Vasily Khoruzhick,
open list:ARM/Amlogic Meson..., Erico Nunes
In-Reply-To: <70ef1af2-beff-04a1-063f-cfe430c4fdf9@baylibre.com>
Hi Neil,
OK, I'll resend these patches.
Regards,
Qiang
On Mon, May 21, 2018 at 10:16 PM, Neil Armstrong
<narmstrong@baylibre.com> wrote:
> Hi Yuq,
>
> On 18/05/2018 11:27, Qiang Yu wrote:
>> Meson mali GPU operate in high clock frequency, need
>> this value be high to work in a stable state.
>>
>> Signed-off-by: Qiang Yu <yuq825@gmail.com>
>> ---
>> arch/arm64/boot/dts/amlogic/meson-gxl-mali.dtsi | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-mali.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl-mali.dtsi
>> index eb327664a4d8..8bed15267c9c 100644
>> --- a/arch/arm64/boot/dts/amlogic/meson-gxl-mali.dtsi
>> +++ b/arch/arm64/boot/dts/amlogic/meson-gxl-mali.dtsi
>> @@ -23,6 +23,7 @@
>> "pp2", "ppmmu2";
>> clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>;
>> clock-names = "bus", "core";
>> + switch-delay = <0xffff>;
>>
>> /*
>> * Mali clocking is provided by two identical clock paths
>>
>
> Please CC : linux-amlogic@lists.infradead.org
> to have these amlogic DT patches reviewed and applied.
>
> Same for cover-letter to have context.
>
> Thanks,
> Neil
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH v6 5/5] drm/rockchip: support dp training outside dp firmware
From: hl @ 2018-05-22 1:08 UTC (permalink / raw)
To: Enric Balletbo Serra
Cc: Sean Paul, David Airlie, Chris Zhong, Kishon Vijay Abraham I,
Doug Anderson, Brian Norris, open list:ARM/Rockchip SoC...,
Heiko Stübner, daniel.vetter, jani.nikula, dri-devel,
Linux ARM, linux-kernel, Rob Herring, devicetree@vger.kernel.org
In-Reply-To: <CAFqH_50w7NoUTaYpmCFDsuafie2a4v5Dirs5KbsV26ff5xEpGg@mail.gmail.com>
Hi Enric,
On Monday, May 21, 2018 11:22 PM, Enric Balletbo Serra wrote:
> Hi Lin,
>
> 2018-05-21 11:37 GMT+02:00 Lin Huang <hl@rock-chips.com>:
>> 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>
>> Reviewed-by: Sean Paul <seanpaul@chromium.org>
>> ---
>> 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
>> Changes in v6:
>> - None
>>
>> 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) {
> You don't need to compare to true. Simply do:
>
> if (dp->use_fw_training)
>
>> + 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) {
> if (dp->use_fw_training)
>
>> + 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);
>> +
>> + 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;
>> + }
> If I understand correctly you are changing current behavior. Before
> this patch, we use always firmware link training, and after this
> patch, we always use software link training. If fails we use the
> firmware link training.
>
> AFAIK my Samsung Chromebook Plus works well with firmware link
> training, so there are any benefits of use software link training
> instead of firmware link training?
>
> Looks to me that we should only do software link training on these
> platforms that need it, so on those that define the phy-config
> property in their DT and use by default firmware link training.
Sean and me have discussed about that, and we all agree to use sw
training instead the
fw training to keep training process consistent, and we do not need add
a varialbe in
struct rockchip_typec_phy(like use_sw_training before) to distinguish sw
and fw training.
If training process implement correctly, sw training not different with
fw training, and as my
test so far, sw training work well on Kevin, ofcourse, we need keep
testing it.
>> + 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
* Re: [PATCH 05/15] drm/sun4i: Add TCON TOP driver
From: kbuild test robot @ 2018-05-22 2:25 UTC (permalink / raw)
To: Jernej Skrabec
Cc: kbuild-all-JC7UmRfGjtg, maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ,
wens-jdAy2FN1RRM, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw
In-Reply-To: <20180519183127.2718-6-jernej.skrabec-gGgVlfcn5nU@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 1773 bytes --]
Hi Jernej,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on drm/drm-next]
[also build test ERROR on v4.17-rc6 next-20180517]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Jernej-Skrabec/Add-support-for-R40-HDMI-pipeline/20180521-131839
base: git://people.freedesktop.org/~airlied/linux.git drm-next
config: arm-multi_v7_defconfig (attached as .config)
compiler: arm-linux-gnueabi-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=arm
All errors (new ones prefixed by >>):
drivers/gpu/drm/sun4i/sun8i_tcon_top.o: In function `init_module':
>> sun8i_tcon_top.c:(.init.text+0x0): multiple definition of `init_module'
drivers/gpu/drm/sun4i/sun8i_mixer.o:sun8i_mixer.c:(.init.text+0x0): first defined here
drivers/gpu/drm/sun4i/sun8i_tcon_top.o: In function `cleanup_module':
>> sun8i_tcon_top.c:(.exit.text+0x0): multiple definition of `cleanup_module'
drivers/gpu/drm/sun4i/sun8i_mixer.o:sun8i_mixer.c:(.exit.text+0x0): first defined here
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
--
You received this message because you are subscribed to the Google Groups "linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to linux-sunxi+unsubscribe-/JYPxA39Uh5TLH3MbocFF+G/Ez6ZCGd0@public.gmane.org
For more options, visit https://groups.google.com/d/optout.
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 43346 bytes --]
^ permalink raw reply
* [PATCH 1/2] clk: imx6ul: add GPIO clock gates
From: Anson Huang @ 2018-05-22 3:25 UTC (permalink / raw)
To: shawnguo, kernel, fabio.estevam, robh+dt, mark.rutland,
mturquette, sboyd, michael, matteo.lisi
Cc: Linux-imx, linux-arm-kernel, devicetree, linux-kernel, linux-clk
i.MX6UL has GPIO clock gates in CCM CCGR, add
them into clock tree for clock management.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
drivers/clk/imx/clk-imx6ul.c | 5 +++++
include/dt-bindings/clock/imx6ul-clock.h | 31 ++++++++++++++++++-------------
2 files changed, 23 insertions(+), 13 deletions(-)
diff --git a/drivers/clk/imx/clk-imx6ul.c b/drivers/clk/imx/clk-imx6ul.c
index ba563ba..3ea2d97 100644
--- a/drivers/clk/imx/clk-imx6ul.c
+++ b/drivers/clk/imx/clk-imx6ul.c
@@ -360,6 +360,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_CLK_UART2_SERIAL] = imx_clk_gate2("uart2_serial", "uart_podf", base + 0x68, 28);
if (clk_on_imx6ull())
clks[IMX6UL_CLK_AIPSTZ3] = imx_clk_gate2("aips_tz3", "ahb", base + 0x80, 18);
+ clks[IMX6UL_CLK_GPIO2] = imx_clk_gate2("gpio2", "ipg", base + 0x68, 30);
/* CCGR1 */
clks[IMX6UL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0);
@@ -376,6 +377,8 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_CLK_GPT1_SERIAL] = imx_clk_gate2("gpt1_serial", "perclk", base + 0x6c, 22);
clks[IMX6UL_CLK_UART4_IPG] = imx_clk_gate2("uart4_ipg", "ipg", base + 0x6c, 24);
clks[IMX6UL_CLK_UART4_SERIAL] = imx_clk_gate2("uart4_serial", "uart_podf", base + 0x6c, 24);
+ clks[IMX6UL_CLK_GPIO1] = imx_clk_gate2("gpio1", "ipg", base + 0x6c, 26);
+ clks[IMX6UL_CLK_GPIO5] = imx_clk_gate2("gpio5", "ipg", base + 0x6c, 30);
/* CCGR2 */
if (clk_on_imx6ull()) {
@@ -389,6 +392,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
clks[IMX6UL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12);
clks[IMX6UL_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif_podf", base + 0x70, 14);
+ clks[IMX6UL_CLK_GPIO3] = imx_clk_gate2("gpio3", "ipg", base + 0x70, 26);
clks[IMX6UL_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "axi", base + 0x70, 28);
clks[IMX6UL_CLK_PXP] = imx_clk_gate2("pxp", "axi", base + 0x70, 30);
@@ -405,6 +409,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_CLK_UART6_IPG] = imx_clk_gate2("uart6_ipg", "ipg", base + 0x74, 6);
clks[IMX6UL_CLK_UART6_SERIAL] = imx_clk_gate2("uart6_serial", "uart_podf", base + 0x74, 6);
clks[IMX6UL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_podf", base + 0x74, 10);
+ clks[IMX6UL_CLK_GPIO4] = imx_clk_gate2("gpio4", "ipg", base + 0x74, 12);
clks[IMX6UL_CLK_QSPI] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14);
clks[IMX6UL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16);
clks[IMX6UL_CLK_MMDC_P0_FAST] = imx_clk_gate("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20);
diff --git a/include/dt-bindings/clock/imx6ul-clock.h b/include/dt-bindings/clock/imx6ul-clock.h
index 9564597..1291328 100644
--- a/include/dt-bindings/clock/imx6ul-clock.h
+++ b/include/dt-bindings/clock/imx6ul-clock.h
@@ -242,20 +242,25 @@
#define IMX6UL_CLK_CKO2_PODF 229
#define IMX6UL_CLK_CKO2 230
#define IMX6UL_CLK_CKO 231
+#define IMX6UL_CLK_GPIO1 232
+#define IMX6UL_CLK_GPIO2 233
+#define IMX6UL_CLK_GPIO3 234
+#define IMX6UL_CLK_GPIO4 235
+#define IMX6UL_CLK_GPIO5 236
/* For i.MX6ULL */
-#define IMX6ULL_CLK_ESAI_PRED 232
-#define IMX6ULL_CLK_ESAI_PODF 233
-#define IMX6ULL_CLK_ESAI_EXTAL 234
-#define IMX6ULL_CLK_ESAI_MEM 235
-#define IMX6ULL_CLK_ESAI_IPG 236
-#define IMX6ULL_CLK_DCP_CLK 237
-#define IMX6ULL_CLK_EPDC_PRE_SEL 238
-#define IMX6ULL_CLK_EPDC_SEL 239
-#define IMX6ULL_CLK_EPDC_PODF 240
-#define IMX6ULL_CLK_EPDC_ACLK 241
-#define IMX6ULL_CLK_EPDC_PIX 242
-#define IMX6ULL_CLK_ESAI_SEL 243
-#define IMX6UL_CLK_END 244
+#define IMX6ULL_CLK_ESAI_PRED 237
+#define IMX6ULL_CLK_ESAI_PODF 238
+#define IMX6ULL_CLK_ESAI_EXTAL 239
+#define IMX6ULL_CLK_ESAI_MEM 240
+#define IMX6ULL_CLK_ESAI_IPG 241
+#define IMX6ULL_CLK_DCP_CLK 242
+#define IMX6ULL_CLK_EPDC_PRE_SEL 243
+#define IMX6ULL_CLK_EPDC_SEL 244
+#define IMX6ULL_CLK_EPDC_PODF 245
+#define IMX6ULL_CLK_EPDC_ACLK 246
+#define IMX6ULL_CLK_EPDC_PIX 247
+#define IMX6ULL_CLK_ESAI_SEL 248
+#define IMX6UL_CLK_END 249
#endif /* __DT_BINDINGS_CLOCK_IMX6UL_H */
--
2.7.4
^ permalink raw reply related
* [PATCH 2/2] ARM: dts: imx6ul: add GPIO clocks
From: Anson Huang @ 2018-05-22 3:26 UTC (permalink / raw)
To: shawnguo, kernel, fabio.estevam, robh+dt, mark.rutland,
mturquette, sboyd, michael, matteo.lisi
Cc: Linux-imx, linux-arm-kernel, devicetree, linux-kernel, linux-clk
In-Reply-To: <1526959560-6014-1-git-send-email-Anson.Huang@nxp.com>
i.MX6UL has GPIO clock gates in CCM CCGR, add
clock property for GPIO driver to make sure all
GPIO banks work as expected.
Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
---
arch/arm/boot/dts/imx6ul.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/boot/dts/imx6ul.dtsi b/arch/arm/boot/dts/imx6ul.dtsi
index 1241972..405e068 100644
--- a/arch/arm/boot/dts/imx6ul.dtsi
+++ b/arch/arm/boot/dts/imx6ul.dtsi
@@ -437,6 +437,7 @@
reg = <0x0209c000 0x4000>;
interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_GPIO1>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -450,6 +451,7 @@
reg = <0x020a0000 0x4000>;
interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_GPIO2>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -462,6 +464,7 @@
reg = <0x020a4000 0x4000>;
interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_GPIO3>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -474,6 +477,7 @@
reg = <0x020a8000 0x4000>;
interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_GPIO4>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
@@ -486,6 +490,7 @@
reg = <0x020ac000 0x4000>;
interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&clks IMX6UL_CLK_GPIO5>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
--
2.7.4
^ permalink raw reply related
* [PATCH RFC 1/3] scsi: ufs: set the device reference clock setting
From: Sayali Lokhande @ 2018-05-22 4:21 UTC (permalink / raw)
To: subhashj, cang, vivek.gautam, rnayak, vinholikatti, jejb,
martin.petersen, asutoshd
Cc: linux-scsi, Sayali Lokhande, Rob Herring, Mark Rutland,
Mathieu Malaterre,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
open list
In-Reply-To: <1526962900-20683-1-git-send-email-sayalil@codeaurora.org>
From: Subhash Jadavani <subhashj@codeaurora.org>
UFS host supplies the reference clock to UFS device and UFS device
specification allows host to provide one of the 4 frequencies (19.2 MHz,
26 MHz, 38.4 MHz, 52 MHz) for reference clock. Host should set the
device reference clock frequency setting in the device based on what
frequency it is supplying to UFS device.
Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
[cang@codeaurora.org: Resolved trivial merge conflicts]
Signed-off-by: Can Guo <cang@codeaurora.org>
Signed-off-by: Sayali Lokhande <sayalil@codeaurora.org>
---
.../devicetree/bindings/ufs/ufshcd-pltfrm.txt | 8 +++
drivers/scsi/ufs/ufs.h | 9 ++++
drivers/scsi/ufs/ufshcd-pltfrm.c | 20 ++++++++
drivers/scsi/ufs/ufshcd.c | 60 ++++++++++++++++++++++
drivers/scsi/ufs/ufshcd.h | 2 +
5 files changed, 99 insertions(+)
diff --git a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
index c39dfef..ac94220 100644
--- a/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
+++ b/Documentation/devicetree/bindings/ufs/ufshcd-pltfrm.txt
@@ -41,6 +41,12 @@ Optional properties:
-lanes-per-direction : number of lanes available per direction - either 1 or 2.
Note that it is assume same number of lanes is used both
directions at once. If not specified, default is 2 lanes per direction.
+- dev-ref-clk-freq : Specify the device reference clock frequency, must be one of the following:
+ 0: 19.2 MHz
+ 1: 26 MHz
+ 2: 38.4 MHz
+ 3: 52 MHz
+ Defaults to 26 MHz if not specified.
Note: If above properties are not defined it can be assumed that the supply
regulators or clocks are always on.
@@ -66,4 +72,6 @@ Example:
freq-table-hz = <100000000 200000000>, <0 0>, <0 0>;
phys = <&ufsphy1>;
phy-names = "ufsphy";
+ dev-ref-clk-freq = <0>; /* reference clock freq: 19.2 MHz */
};
+
diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 14e5bf7..e15deb0 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -378,6 +378,15 @@ enum query_opcode {
UPIU_QUERY_OPCODE_TOGGLE_FLAG = 0x8,
};
+/* bRefClkFreq attribute values */
+enum ref_clk_freq {
+ REF_CLK_FREQ_19_2_MHZ = 0x0,
+ REF_CLK_FREQ_26_MHZ = 0x1,
+ REF_CLK_FREQ_38_4_MHZ = 0x2,
+ REF_CLK_FREQ_52_MHZ = 0x3,
+ REF_CLK_FREQ_MAX = REF_CLK_FREQ_52_MHZ,
+};
+
/* Query response result code */
enum {
QUERY_RESULT_SUCCESS = 0x00,
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
index e82bde0..b70838b 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
@@ -221,6 +221,24 @@ static int ufshcd_parse_regulator_info(struct ufs_hba *hba)
return err;
}
+static void ufshcd_parse_dev_ref_clk_freq(struct ufs_hba *hba)
+{
+ struct device *dev = hba->dev;
+ struct device_node *np = dev->of_node;
+ int ret;
+
+ if (!np)
+ return;
+
+ ret = of_property_read_u32(np, "dev-ref-clk-freq",
+ &hba->dev_ref_clk_freq);
+ if (ret ||
+ (hba->dev_ref_clk_freq < 0) ||
+ (hba->dev_ref_clk_freq > REF_CLK_FREQ_52_MHZ))
+ /* default setting */
+ hba->dev_ref_clk_freq = REF_CLK_FREQ_26_MHZ;
+}
+
#ifdef CONFIG_PM
/**
* ufshcd_pltfrm_suspend - suspend power management function
@@ -343,6 +361,8 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
+ ufshcd_parse_dev_ref_clk_freq(hba);
+
ufshcd_init_lanes_per_dir(hba);
err = ufshcd_init(hba, mmio_base, irq);
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index c5b1bf1..1ab882f 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -6297,6 +6297,61 @@ static void ufshcd_def_desc_sizes(struct ufs_hba *hba)
}
/**
+ * ufshcd_set_dev_ref_clk - set the device bRefClkFreq
+ * @hba: per-adapter instance
+ *
+ * Read the current value of the bRefClkFreq attribute from device and update it
+ * if host is supplying different reference clock frequency than one mentioned
+ * in bRefClkFreq attribute.
+ *
+ * Returns zero on success, non-zero error value on failure.
+ */
+static int ufshcd_set_dev_ref_clk(struct ufs_hba *hba)
+{
+ int err = 0;
+ int ref_clk = -1;
+ static const char * const ref_clk_freqs[] = {"19.2 MHz", "26 MHz",
+ "38.4 MHz", "52 MHz"};
+
+ err = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR,
+ QUERY_ATTR_IDN_REF_CLK_FREQ, 0, 0, &ref_clk);
+
+ if (err) {
+ dev_err(hba->dev, "%s: failed reading bRefClkFreq. err = %d\n",
+ __func__, err);
+ goto out;
+ }
+
+ if ((ref_clk < 0) || (ref_clk > REF_CLK_FREQ_52_MHZ)) {
+ dev_err(hba->dev, "%s: invalid ref_clk setting = %d\n",
+ __func__, ref_clk);
+ err = -EINVAL;
+ goto out;
+ }
+
+ if (ref_clk == hba->dev_ref_clk_freq)
+ goto out; /* nothing to update */
+
+ err = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR,
+ QUERY_ATTR_IDN_REF_CLK_FREQ, 0, 0,
+ &hba->dev_ref_clk_freq);
+
+ if (err)
+ dev_err(hba->dev, "%s: bRefClkFreq setting to %s failed\n",
+ __func__, ref_clk_freqs[hba->dev_ref_clk_freq]);
+ else
+ /*
+ * It is good to print this out here to debug any later failures
+ * related to gear switch.
+ */
+ dev_info(hba->dev, "%s: bRefClkFreq setting to %s succeeded\n",
+ __func__, ref_clk_freqs[hba->dev_ref_clk_freq]);
+
+out:
+ return err;
+}
+
+/**
* ufshcd_probe_hba - probe hba to detect device and initialize
* @hba: per-adapter instance
*
@@ -6361,6 +6416,11 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
"%s: Failed getting max supported power mode\n",
__func__);
} else {
+ /*
+ * Set the right value to bRefClkFreq before attempting to
+ * switch to HS gears.
+ */
+ ufshcd_set_dev_ref_clk(hba);
ret = ufshcd_config_pwr_mode(hba, &hba->max_pwr_info.info);
if (ret) {
dev_err(hba->dev, "%s: Failed setting power mode, err = %d\n",
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 8110dcd..0dcf113 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -549,6 +549,8 @@ struct ufs_hba {
unsigned int irq;
bool is_irq_enabled;
+ u32 dev_ref_clk_freq;
+
/* Interrupt aggregation support is broken */
#define UFSHCD_QUIRK_BROKEN_INTR_AGGR 0x1
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related
* Re: [PATCH v5 3/8] remoteproc: Move proxy unvote to handover irq handler
From: Bjorn Andersson @ 2018-05-22 4:35 UTC (permalink / raw)
To: Sibi Sankar
Cc: p.zabel, robh+dt, linux-remoteproc, linux-kernel, devicetree,
georgi.djakov, jassisinghbrar, ohad, mark.rutland, kyan,
sricharan, akdwived, linux-arm-msm, tsoni
In-Reply-To: <20180521172714.8551-4-sibis@codeaurora.org>
On Mon 21 May 10:27 PDT 2018, Sibi Sankar wrote:
> Introduce interrupt handler for smp2p ready interrupt to
> handle start completion. Move the proxy votes for clocks
> and regulators to the handover interrupt context.
>
> Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
I added the "synchronization logic" of patch 4 to this one, to make it
functional and after testing on db820c I merged patch 3 through 8 into
rproc-next.
I skipped the remainder of patch 4, as I think the ready_irq should be
included and I wonder if irq management can remove the need for the
"running" variable.
I also moved the enable_irq before we actually start the core, since
it's been shown downstream that the smp2p irq might fire fast enough for
us to miss it (and the smp2p driver does not redeliver interrupts).
Regards,
Bjorn
> ---
> drivers/remoteproc/qcom_q6v5_pil.c | 29 +++++++++++++++++++++++------
> 1 file changed, 23 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c
> index 76a0c00aa04a..6333bdcd9448 100644
> --- a/drivers/remoteproc/qcom_q6v5_pil.c
> +++ b/drivers/remoteproc/qcom_q6v5_pil.c
> @@ -809,11 +809,6 @@ static int q6v5_start(struct rproc *rproc)
> "Failed to reclaim mba buffer system may become unstable\n");
> qproc->running = true;
>
> - q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
> - qproc->proxy_clk_count);
> - q6v5_regulator_disable(qproc, qproc->proxy_regs,
> - qproc->proxy_reg_count);
> -
> return 0;
>
> reclaim_mpss:
> @@ -892,6 +887,12 @@ static int q6v5_stop(struct rproc *rproc)
> WARN_ON(ret);
>
> reset_control_assert(qproc->mss_restart);
> +
> + q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
> + qproc->proxy_clk_count);
> + q6v5_regulator_disable(qproc, qproc->proxy_regs,
> + qproc->proxy_reg_count);
> +
> q6v5_clk_disable(qproc->dev, qproc->active_clks,
> qproc->active_clk_count);
> q6v5_regulator_disable(qproc, qproc->active_regs,
> @@ -959,7 +960,7 @@ static irqreturn_t q6v5_fatal_interrupt(int irq, void *dev)
> return IRQ_HANDLED;
> }
>
> -static irqreturn_t q6v5_handover_interrupt(int irq, void *dev)
> +static irqreturn_t q6v5_ready_interrupt(int irq, void *dev)
> {
> struct q6v5 *qproc = dev;
>
> @@ -967,6 +968,18 @@ static irqreturn_t q6v5_handover_interrupt(int irq, void *dev)
> return IRQ_HANDLED;
> }
>
> +static irqreturn_t q6v5_handover_interrupt(int irq, void *dev)
> +{
> + struct q6v5 *qproc = dev;
> +
> + q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
> + qproc->proxy_clk_count);
> + q6v5_regulator_disable(qproc, qproc->proxy_regs,
> + qproc->proxy_reg_count);
> +
> + return IRQ_HANDLED;
> +}
> +
> static irqreturn_t q6v5_stop_ack_interrupt(int irq, void *dev)
> {
> struct q6v5 *qproc = dev;
> @@ -1194,6 +1207,10 @@ static int q6v5_probe(struct platform_device *pdev)
> if (ret < 0)
> goto free_rproc;
>
> + ret = q6v5_request_irq(qproc, pdev, "ready", q6v5_ready_interrupt);
> + if (ret < 0)
> + goto free_rproc;
> +
> ret = q6v5_request_irq(qproc, pdev, "handover", q6v5_handover_interrupt);
> if (ret < 0)
> goto free_rproc;
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>
^ permalink raw reply
* Re: [PATCH net-next 1/7] net: dsa: qca8k: Add QCA8334 binding documentation
From: Michal Vokáč @ 2018-05-22 5:16 UTC (permalink / raw)
To: Andrew Lunn
Cc: netdev, michal.vokac, linux-kernel, devicetree, f.fainelli,
vivien.didelot, mark.rutland, robh+dt, davem
In-Reply-To: <20180521144711.GE8077@lunn.ch>
On 21.5.2018 16:47, Andrew Lunn wrote:
> On Mon, May 21, 2018 at 03:28:07PM +0200, Michal Vokáč wrote:
>> Signed-off-by: Michal Vokáč <michal.vokac@ysoft.com>
>
> Hi Michal
>
> It would be good to document that fixed-link can be used.
OK, I will document that and add a commit message as well as you
mentioned before.
Thanks,
Michal
^ permalink raw reply
* Re: [PATCH net-next 3/7] net: dsa: qca8k: Enable RXMAC when bringing up a port
From: Michal Vokáč @ 2018-05-22 5:28 UTC (permalink / raw)
To: Florian Fainelli, netdev
Cc: michal.vokac, linux-kernel, devicetree, vivien.didelot, andrew,
mark.rutland, robh+dt, davem
In-Reply-To: <0e72750c-5567-d12c-8d9c-5a25520ab104@gmail.com>
On 21.5.2018 17:17, Florian Fainelli wrote:
>
> On 05/21/2018 06:28 AM, Michal Vokáč wrote:
>> When a port is brought up/down do not enable/disable only the TXMAC
>> but the RXMAC as well. This is essential for the CPU port to work.
>>
>> Signed-off-by: Michal Vokáč <michal.vokac@ysoft.com>
>
> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
>
> Should this have:
>
> Fixes: 6b93fb46480a ("net-next: dsa: add new driver for qca8xxx family")?
Yes, I think it is a good idea to can add this. Will do it in v2.
Thanks,
Michal
^ permalink raw reply
* Re: [PATCH net-next 4/7] net: dsa: qca8k: Force CPU port to its highest bandwidth
From: Michal Vokáč @ 2018-05-22 5:30 UTC (permalink / raw)
To: Florian Fainelli, netdev
Cc: michal.vokac, linux-kernel, devicetree, vivien.didelot, andrew,
mark.rutland, robh+dt, davem
In-Reply-To: <7d73f1b8-453a-fcbe-a1b8-41ced652deb0@gmail.com>
On 21.5.2018 17:19, Florian Fainelli wrote:
>
> On 05/21/2018 06:28 AM, Michal Vokáč wrote:
>> By default autonegotiation is enabled to configure MAC on all ports.
>> For the CPU port autonegotiation can not be used so we need to set
>> some sensible defaults manually.
>>
>> This patch forces the default setting of the CPU port to 1000Mbps/full
>> duplex which is the chip maximum capability.
>>
>> Also correct size of the bit field used to configure link speed.
>>
>> Signed-off-by: Michal Vokáč <michal.vokac@ysoft.com>
>
> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
>
> Likewise, would not we want to have a:
>
> Fixes: 6b93fb46480a ("net-next: dsa: add new driver for qca8xxx family")
>
> tag here as well?
Good point, I will add this in v2.
Thanks,
Michal
^ permalink raw reply
* Re: [PATCH] ARM: dts: da850-evm: Enable SATA port
From: Sekhar Nori @ 2018-05-22 5:46 UTC (permalink / raw)
To: Adam Ford, linux-arm-kernel; +Cc: devicetree, adam.ford, khilman
In-Reply-To: <20180518204339.14298-1-aford173@gmail.com>
On Saturday 19 May 2018 02:13 AM, Adam Ford wrote:
> The DA850-EVM from Logic PD has a SATA port and the module that went
> with the kit support it as well. This patch will enable the SATA
> controller.
>
> Signed-off-by: Adam Ford <aford173@gmail.com>
Applied for v4.19
Thanks,
Sekhar
^ permalink raw reply
* Re: [PATCH net-next 6/7] net: dsa: qca8k: Replace GPL boilerplate by SPDX
From: Michal Vokáč @ 2018-05-22 5:49 UTC (permalink / raw)
To: Florian Fainelli, netdev
Cc: michal.vokac, linux-kernel, devicetree, vivien.didelot, andrew,
mark.rutland, robh+dt, davem
In-Reply-To: <200f2431-63c1-bafe-8802-3a117fbf8433@gmail.com>
On 21.5.2018 17:20, Florian Fainelli wrote:
>
> On 05/21/2018 06:28 AM, Michal Vokáč wrote:
>> Signed-off-by: Michal Vokáč <michal.vokac@ysoft.com>
>
> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
>
> I don't know if we need all people who contributed to that driver to
> agree on that, this is not a license change, so it should be okay I presume?
I did that with the same idea on my mind, that this is not a license change.
Prior to the change I also went through the log and reviewed few commits that
did exactly the same thing and did not receive Ack or something from the
original authors nor further contributors.
Just one example:
4ac0d3f ("eeprom: at24: use SPDX identifier instead of GPL boiler-plate")
Thanks,
Michal
^ permalink raw reply
* Re: [PATCH net-next 7/7] net: dsa: qca8k: Remove rudundant parentheses
From: Michal Vokáč @ 2018-05-22 5:52 UTC (permalink / raw)
To: Florian Fainelli, netdev
Cc: michal.vokac, linux-kernel, devicetree, vivien.didelot, andrew,
mark.rutland, robh+dt, davem
In-Reply-To: <708a634a-167f-4e96-be97-aca059724374@gmail.com>
On 21.5.2018 17:21, Florian Fainelli wrote:
>
> On 05/21/2018 06:28 AM, Michal Vokáč wrote:
>> Fix warning reported by checkpatch.
>
> Nit in the subject: should be redundant, with that:
>
> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Thanks, I will fix it.
Michal
^ permalink raw reply
* [PATCH v3 1/3] cpufreq: imx6q: check speed grades for i.MX6ULL
From: Sébastien Szymanski @ 2018-05-22 6:28 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Mark Rutland, devicetree, linux-pm, Viresh Kumar,
Rafael J . Wysocki, linux-kernel, Stefan Agner, Rob Herring,
Sascha Hauer, Fabio Estevam, Shawn Guo
Check the max speed supported from the fuses for i.MX6ULL and update the
operating points table accordingly.
Signed-off-by: Sébastien Szymanski <sebastien.szymanski@armadeus.com>
---
Changes for v3:
- none
Changes for v2:
- none
drivers/cpufreq/imx6q-cpufreq.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/drivers/cpufreq/imx6q-cpufreq.c b/drivers/cpufreq/imx6q-cpufreq.c
index 83cf631fc9bc..f094687cae52 100644
--- a/drivers/cpufreq/imx6q-cpufreq.c
+++ b/drivers/cpufreq/imx6q-cpufreq.c
@@ -266,6 +266,8 @@ static void imx6q_opp_check_speed_grading(struct device *dev)
}
#define OCOTP_CFG3_6UL_SPEED_696MHZ 0x2
+#define OCOTP_CFG3_6ULL_SPEED_792MHZ 0x2
+#define OCOTP_CFG3_6ULL_SPEED_900MHZ 0x3
static void imx6ul_opp_check_speed_grading(struct device *dev)
{
@@ -287,16 +289,30 @@ static void imx6ul_opp_check_speed_grading(struct device *dev)
* Speed GRADING[1:0] defines the max speed of ARM:
* 2b'00: Reserved;
* 2b'01: 528000000Hz;
- * 2b'10: 696000000Hz;
- * 2b'11: Reserved;
+ * 2b'10: 696000000Hz on i.MX6UL, 792000000Hz on i.MX6ULL;
+ * 2b'11: 900000000Hz on i.MX6ULL only;
* We need to set the max speed of ARM according to fuse map.
*/
val = readl_relaxed(base + OCOTP_CFG3);
val >>= OCOTP_CFG3_SPEED_SHIFT;
val &= 0x3;
- if (val != OCOTP_CFG3_6UL_SPEED_696MHZ)
- if (dev_pm_opp_disable(dev, 696000000))
- dev_warn(dev, "failed to disable 696MHz OPP\n");
+
+ if (of_machine_is_compatible("fsl,imx6ul")) {
+ if (val != OCOTP_CFG3_6UL_SPEED_696MHZ)
+ if (dev_pm_opp_disable(dev, 696000000))
+ dev_warn(dev, "failed to disable 696MHz OPP\n");
+ }
+
+ if (of_machine_is_compatible("fsl,imx6ull")) {
+ if (val != OCOTP_CFG3_6ULL_SPEED_792MHZ)
+ if (dev_pm_opp_disable(dev, 792000000))
+ dev_warn(dev, "failed to disable 792MHz OPP\n");
+
+ if (val != OCOTP_CFG3_6ULL_SPEED_900MHZ)
+ if (dev_pm_opp_disable(dev, 900000000))
+ dev_warn(dev, "failed to disable 900MHz OPP\n");
+ }
+
iounmap(base);
put_node:
of_node_put(np);
@@ -356,7 +372,8 @@ static int imx6q_cpufreq_probe(struct platform_device *pdev)
goto put_reg;
}
- if (of_machine_is_compatible("fsl,imx6ul"))
+ if (of_machine_is_compatible("fsl,imx6ul") ||
+ of_machine_is_compatible("fsl,imx6ull"))
imx6ul_opp_check_speed_grading(cpu_dev);
else
imx6q_opp_check_speed_grading(cpu_dev);
--
2.16.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 2/3] ARM: dts: imx6ull: add operating points
From: Sébastien Szymanski @ 2018-05-22 6:28 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Mark Rutland, devicetree, linux-pm, Viresh Kumar,
Rafael J . Wysocki, linux-kernel, Stefan Agner, Rob Herring,
Sascha Hauer, Fabio Estevam, Shawn Guo
In-Reply-To: <20180522062853.24799-1-sebastien.szymanski@armadeus.com>
i.MX6ULL has different operating ranges than i.MX6UL so add the
operating points for the i.MX6ULL. A 25mV offset is added to the minimum
allowed values like for the i.MX6UL.
Signed-off-by: Sébastien Szymanski <sebastien.szymanski@armadeus.com>
---
Changes for v3:
- none
Changes for v2:
- Fix soc-operating-points voltage for 792MHz and 900MHz
arch/arm/boot/dts/imx6ull.dtsi | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/arm/boot/dts/imx6ull.dtsi b/arch/arm/boot/dts/imx6ull.dtsi
index 571ddd71cdba..530d5526b890 100644
--- a/arch/arm/boot/dts/imx6ull.dtsi
+++ b/arch/arm/boot/dts/imx6ull.dtsi
@@ -46,6 +46,25 @@
/* Delete UART8 in AIPS-1 (i.MX6UL specific) */
/delete-node/ &uart8;
+&cpu0 {
+ operating-points = <
+ /* kHz uV */
+ 900000 1275000
+ 792000 1225000
+ 528000 1175000
+ 396000 1025000
+ 198000 950000
+ >;
+ fsl,soc-operating-points = <
+ /* KHz uV */
+ 900000 1175000
+ 792000 1175000
+ 528000 1175000
+ 396000 1175000
+ 198000 1175000
+ >;
+};
+
/ {
soc {
aips3: aips-bus@2200000 {
--
2.16.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 3/3] ARM: dts: imx6ull-colibri-wifi: remove operating points
From: Sébastien Szymanski @ 2018-05-22 6:28 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Mark Rutland, devicetree, linux-pm, Viresh Kumar,
Rafael J . Wysocki, linux-kernel, Stefan Agner, Rob Herring,
Sascha Hauer, Fabio Estevam, Shawn Guo
In-Reply-To: <20180522062853.24799-1-sebastien.szymanski@armadeus.com>
Operating points are now defined in the imx6ull.dtsi file so remove
them from board device trees.
Signed-off-by: Sébastien Szymanski <sebastien.szymanski@armadeus.com>
---
arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi b/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi
index 3dffbcd50bf6..183193e8580d 100644
--- a/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi
+++ b/arch/arm/boot/dts/imx6ull-colibri-wifi.dtsi
@@ -20,20 +20,6 @@
&cpu0 {
clock-frequency = <792000000>;
- operating-points = <
- /* kHz uV */
- 792000 1225000
- 528000 1175000
- 396000 1025000
- 198000 950000
- >;
- fsl,soc-operating-points = <
- /* KHz uV */
- 792000 1175000
- 528000 1175000
- 396000 1175000
- 198000 1175000
- >;
};
&iomuxc {
--
2.16.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v5 3/8] remoteproc: Move proxy unvote to handover irq handler
From: Sibi S @ 2018-05-22 6:31 UTC (permalink / raw)
To: Bjorn Andersson
Cc: p.zabel, robh+dt, linux-remoteproc, linux-kernel, devicetree,
georgi.djakov, jassisinghbrar, ohad, mark.rutland, kyan,
sricharan, akdwived, linux-arm-msm, tsoni
In-Reply-To: <20180522043511.GW14924@minitux>
Hi Bjorn,
Thanks for the review.
On 05/22/2018 10:05 AM, Bjorn Andersson wrote:
> On Mon 21 May 10:27 PDT 2018, Sibi Sankar wrote:
>
>> Introduce interrupt handler for smp2p ready interrupt to
>> handle start completion. Move the proxy votes for clocks
>> and regulators to the handover interrupt context.
>>
>> Signed-off-by: Sibi Sankar <sibis@codeaurora.org>
>
> I added the "synchronization logic" of patch 4 to this one, to make it
> functional and after testing on db820c I merged patch 3 through 8 into
> rproc-next.
>
making the q6v5_request_irq return the irq number seems more elegant
unlike the approach I took earlier.
> I skipped the remainder of patch 4, as I think the ready_irq should be
> included and I wonder if irq management can remove the need for the
> "running" variable.
>
will include the ready_irq as well. I think we may need to keep
"running" for coredump but will check if it can substituted with
irq management.
> I also moved the enable_irq before we actually start the core, since
> it's been shown downstream that the smp2p irq might fire fast enough for
> us to miss it (and the smp2p driver does not redeliver interrupts).
>
> Regards,
> Bjorn
>
>> ---
>> drivers/remoteproc/qcom_q6v5_pil.c | 29 +++++++++++++++++++++++------
>> 1 file changed, 23 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/remoteproc/qcom_q6v5_pil.c b/drivers/remoteproc/qcom_q6v5_pil.c
>> index 76a0c00aa04a..6333bdcd9448 100644
>> --- a/drivers/remoteproc/qcom_q6v5_pil.c
>> +++ b/drivers/remoteproc/qcom_q6v5_pil.c
>> @@ -809,11 +809,6 @@ static int q6v5_start(struct rproc *rproc)
>> "Failed to reclaim mba buffer system may become unstable\n");
>> qproc->running = true;
>>
>> - q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
>> - qproc->proxy_clk_count);
>> - q6v5_regulator_disable(qproc, qproc->proxy_regs,
>> - qproc->proxy_reg_count);
>> -
>> return 0;
>>
>> reclaim_mpss:
>> @@ -892,6 +887,12 @@ static int q6v5_stop(struct rproc *rproc)
>> WARN_ON(ret);
>>
>> reset_control_assert(qproc->mss_restart);
>> +
>> + q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
>> + qproc->proxy_clk_count);
>> + q6v5_regulator_disable(qproc, qproc->proxy_regs,
>> + qproc->proxy_reg_count);
>> +
>> q6v5_clk_disable(qproc->dev, qproc->active_clks,
>> qproc->active_clk_count);
>> q6v5_regulator_disable(qproc, qproc->active_regs,
>> @@ -959,7 +960,7 @@ static irqreturn_t q6v5_fatal_interrupt(int irq, void *dev)
>> return IRQ_HANDLED;
>> }
>>
>> -static irqreturn_t q6v5_handover_interrupt(int irq, void *dev)
>> +static irqreturn_t q6v5_ready_interrupt(int irq, void *dev)
>> {
>> struct q6v5 *qproc = dev;
>>
>> @@ -967,6 +968,18 @@ static irqreturn_t q6v5_handover_interrupt(int irq, void *dev)
>> return IRQ_HANDLED;
>> }
>>
>> +static irqreturn_t q6v5_handover_interrupt(int irq, void *dev)
>> +{
>> + struct q6v5 *qproc = dev;
>> +
>> + q6v5_clk_disable(qproc->dev, qproc->proxy_clks,
>> + qproc->proxy_clk_count);
>> + q6v5_regulator_disable(qproc, qproc->proxy_regs,
>> + qproc->proxy_reg_count);
>> +
>> + return IRQ_HANDLED;
>> +}
>> +
>> static irqreturn_t q6v5_stop_ack_interrupt(int irq, void *dev)
>> {
>> struct q6v5 *qproc = dev;
>> @@ -1194,6 +1207,10 @@ static int q6v5_probe(struct platform_device *pdev)
>> if (ret < 0)
>> goto free_rproc;
>>
>> + ret = q6v5_request_irq(qproc, pdev, "ready", q6v5_ready_interrupt);
>> + if (ret < 0)
>> + goto free_rproc;
>> +
>> ret = q6v5_request_irq(qproc, pdev, "handover", q6v5_handover_interrupt);
>> if (ret < 0)
>> goto free_rproc;
>> --
>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
>> a Linux Foundation Collaborative Project
>>
>
--
Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc, is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* RE: [PATCH] cpufreq: Add Kryo CPU scaling driver
From: ilialin @ 2018-05-22 6:56 UTC (permalink / raw)
To: 'Sudeep Holla', mturquette, sboyd, robh, mark.rutland,
viresh.kumar, nm, lgirdwood, broonie, andy.gross, david.brown,
catalin.marinas, will.deacon, rjw, linux-clk
Cc: devicetree, linux-kernel, linux-pm, linux-arm-msm, linux-soc,
linux-arm-kernel, rnayak, amit.kucheria, nicolas.dechesne,
celster, tfinkel
In-Reply-To: <2ace10bc-e1c4-2060-94d3-eb71e966ffbe@arm.com>
> -----Original Message-----
> From: Sudeep Holla <sudeep.holla@arm.com>
> Sent: Monday, May 21, 2018 16:05
> To: ilialin@codeaurora.org; mturquette@baylibre.com; sboyd@kernel.org;
> robh@kernel.org; mark.rutland@arm.com; viresh.kumar@linaro.org;
> nm@ti.com; lgirdwood@gmail.com; broonie@kernel.org;
> andy.gross@linaro.org; david.brown@linaro.org; catalin.marinas@arm.com;
> will.deacon@arm.com; rjw@rjwysocki.net; linux-clk@vger.kernel.org
> Cc: Sudeep Holla <sudeep.holla@arm.com>; devicetree@vger.kernel.org;
> linux-kernel@vger.kernel.org; linux-pm@vger.kernel.org; linux-arm-
> msm@vger.kernel.org; linux-soc@vger.kernel.org; linux-arm-
> kernel@lists.infradead.org; rnayak@codeaurora.org;
> amit.kucheria@linaro.org; nicolas.dechesne@linaro.org;
> celster@codeaurora.org; tfinkel@codeaurora.org
> Subject: Re: [PATCH] cpufreq: Add Kryo CPU scaling driver
>
>
>
> On 21/05/18 13:57, ilialin@codeaurora.org wrote:
> >
> [...]
>
> >>> +#include <linux/cpu.h>
> >>> +#include <linux/err.h>
> >>> +#include <linux/init.h>
> >>> +#include <linux/kernel.h>
> >>> +#include <linux/module.h>
> >>> +#include <linux/nvmem-consumer.h>
> >>> +#include <linux/of.h>
> >>> +#include <linux/platform_device.h>
> >>> +#include <linux/pm_opp.h>
> >>> +#include <linux/slab.h>
> >>> +#include <linux/soc/qcom/smem.h>
> >>> +
> >>> +#define MSM_ID_SMEM 137
> >>> +#define SILVER_LEAD 0
> >>> +#define GOLD_LEAD 2
> >>> +
> >>
> >> So I gather form other emails, that these are physical cpu number(not
> >> even unique identifier like MPIDR). Will this work on parts or
> >> platforms that need to boot in GOLD LEAD cpus.
> >
> > The driver is for Kryo CPU, which (and AFAIK all multicore MSMs)
> > always boots on the CPU0.
>
>
> That may be true and I am not that bothered about it. But assuming physical
> ordering from the logical cpu number is *incorrect* and will break if kernel
> decides to change the allocation algorithm. Kernel provides no guarantee on
> that, so you need to depend on some physical ID or may be DT to achieve
> what your want. But the current code as it stands is wrong.
Got your point. In fact CPUs are numbered 0-3 and ordered into 2 clusters in the DT:
cpus {
#address-cells = <2>;
#size-cells = <0>;
CPU0: cpu@0 {
...
reg = <0x0 0x0>;
...
};
CPU1: cpu@1 {
...
reg = <0x0 0x1>;
...
};
CPU2: cpu@100 {
...
reg = <0x0 0x100>;
...
};
CPU3: cpu@101 {
...
reg = <0x0 0x101>;
...
};
cpu-map {
cluster0 {
core0 {
cpu = <&CPU0>;
};
core1 {
cpu = <&CPU1>;
};
};
cluster1 {
core0 {
cpu = <&CPU2>;
};
core1 {
cpu = <&CPU3>;
};
};
};
};
As far, as I understand, they are probed in the same order. However, to be certain that the physical CPU is the one I intend to configure, I have to fetch the device structure pointer for the cpu-map -> clusterX -> core0 -> cpu path. Could you suggest a kernel API to do that?
>
> --
> Regards,
> Sudeep
^ permalink raw reply
* Re: [PATCH 6/7 v5] bus: fsl-mc: set coherent dma mask for devices on fsl-mc bus
From: Laurentiu Tudor @ 2018-05-22 7:03 UTC (permalink / raw)
To: Nipun Gupta, robin.murphy-5wv7dgnIgG8@public.gmane.org,
will.deacon-5wv7dgnIgG8@public.gmane.org,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
mark.rutland-5wv7dgnIgG8@public.gmane.org,
catalin.marinas-5wv7dgnIgG8@public.gmane.org,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
stuyoder-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
shawnguo-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Leo Li,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
linux-pci-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
frowand.list-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org,
hch-jcswGhMUV9g@public.gmane.org,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <1526824191-7000-7-git-send-email-nipun.gupta-3arQi8VN3Tc@public.gmane.org>
On 05/20/2018 04:49 PM, Nipun Gupta wrote:
> of_dma_configure() API expects coherent_dma_mask to be correctly
> set in the devices. This patch does the needful.
>
> Signed-off-by: Nipun Gupta <nipun.gupta-3arQi8VN3Tc@public.gmane.org>
Acked-by: Laurentiu Tudor <laurentiu.tudor-3arQi8VN3Tc@public.gmane.org>
---
Best Regards, Laurentiu
> ---
> drivers/bus/fsl-mc/fsl-mc-bus.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c
> index fa43c7d..624828b 100644
> --- a/drivers/bus/fsl-mc/fsl-mc-bus.c
> +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
> @@ -627,6 +627,7 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc,
> mc_dev->icid = parent_mc_dev->icid;
> mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK;
> mc_dev->dev.dma_mask = &mc_dev->dma_mask;
> + mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask;
> dev_set_msi_domain(&mc_dev->dev,
> dev_get_msi_domain(&parent_mc_dev->dev));
> }
>
^ permalink raw reply
* Re: [PATCH v2 4/7] Bluetooth: Add new quirk for non-persistent setup settings
From: Marcel Holtmann @ 2018-05-22 7:21 UTC (permalink / raw)
To: sean.wang
Cc: Rob Herring, Mark Rutland, Johan Hedberg, devicetree,
BlueZ development, linux-arm-kernel, linux-mediatek, linux-kernel
In-Reply-To: <1d6097f538b3182b2876ad48225ecd6e2d1b128c.1526374087.git.sean.wang@mediatek.com>
Hi Sean,
> Add a new quirk HCI_QUIRK_NON_PERSISTENT_SETUP allowing that a quirk that
> runs setup() after every open() and not just after the first open().
>
> Signed-off-by: Sean Wang <sean.wang@mediatek.com>
> ---
> include/net/bluetooth/hci.h | 9 +++++++++
> net/bluetooth/hci_core.c | 3 ++-
> 2 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
> index 1668211..b37d973 100644
> --- a/include/net/bluetooth/hci.h
> +++ b/include/net/bluetooth/hci.h
> @@ -183,6 +183,15 @@ enum {
> * during the hdev->setup vendor callback.
> */
> HCI_QUIRK_NON_PERSISTENT_DIAG,
> +
> + /* When this quirk is set, setup() would be run after every
> + * open() and not just after the first open().
> + *
> + * This quirk can be set before hci_register_dev is called or
> + * during the hdev->setup vendor callback.
> + *
> + */
> + HCI_QUIRK_NON_PERSISTENT_SETUP,
> };
>
> /* HCI device flags */
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index 40d260f..7de712e2 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -1377,7 +1377,8 @@ static int hci_dev_do_open(struct hci_dev *hdev)
> atomic_set(&hdev->cmd_cnt, 1);
> set_bit(HCI_INIT, &hdev->flags);
>
> - if (hci_dev_test_flag(hdev, HCI_SETUP)) {
> + if (hci_dev_test_flag(hdev, HCI_SETUP) ||
> + test_bit(HCI_QUIRK_NON_PERSISTENT_SETUP, &hdev->quirks)) {
> hci_sock_dev_event(hdev, HCI_DEV_SETUP);
I am not 100% sure that we want to send the HCI_DEV_SETUP event also multiple times. That is a userspace change that I would need to think about. We need to check create_monitor_event() and see what the btmon trace for this looks like. Can you send me a btmon -w trace.log when this change is active.
Regards
Marcel
^ permalink raw reply
* Re: [PATCH v6 5/5] drm/rockchip: support dp training outside dp firmware
From: Enric Balletbo Serra @ 2018-05-22 7:41 UTC (permalink / raw)
To: hl
Cc: devicetree@vger.kernel.org, David Airlie, linux-kernel,
Brian Norris, Doug Anderson, Kishon Vijay Abraham I,
open list:ARM/Rockchip SoC..., Rob Herring, dri-devel,
Chris Zhong, daniel.vetter, Linux ARM
In-Reply-To: <f3d7e6c7-0291-b909-4f0e-a55bc0cad603@rock-chips.com>
Hi Lin
2018-05-22 3:08 GMT+02:00 hl <hl@rock-chips.com>:
> Hi Enric,
>
>
>
>
> On Monday, May 21, 2018 11:22 PM, Enric Balletbo Serra wrote:
>>
>> Hi Lin,
>>
>> 2018-05-21 11:37 GMT+02:00 Lin Huang <hl@rock-chips.com>:
>>>
>>> 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>
>>> Reviewed-by: Sean Paul <seanpaul@chromium.org>
>>> ---
>>> 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
>>> Changes in v6:
>>> - None
>>>
>>> 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) {
>>
>> You don't need to compare to true. Simply do:
>>
>> if (dp->use_fw_training)
>>
>>> + 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) {
>>
>> if (dp->use_fw_training)
>>
>>> + 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);
>>> +
>>> + 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;
>>> + }
>>
>> If I understand correctly you are changing current behavior. Before
>> this patch, we use always firmware link training, and after this
>> patch, we always use software link training. If fails we use the
>> firmware link training.
>>
>> AFAIK my Samsung Chromebook Plus works well with firmware link
>> training, so there are any benefits of use software link training
>> instead of firmware link training?
>>
>> Looks to me that we should only do software link training on these
>> platforms that need it, so on those that define the phy-config
>> property in their DT and use by default firmware link training.
>
> Sean and me have discussed about that, and we all agree to use sw training
> instead the
> fw training to keep training process consistent, and we do not need add a
> varialbe in
> struct rockchip_typec_phy(like use_sw_training before) to distinguish sw and
> fw training.
> If training process implement correctly, sw training not different with fw
> training, and as my
> test so far, sw training work well on Kevin, ofcourse, we need keep testing
> it.
>
Ok, I can also confirm that software training works well on kevin.
Could you mention this change of behavior in the commit message? I
think that after these patches the firmware training is unlikely to
happen.
Thanks,
Enric
>>> + 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
>>>
>>
>>
>
>
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH V2 1/2] dt-bindings: mtd: document Broadcom's BCM47xx partitions
From: Rafał Miłecki @ 2018-05-22 7:46 UTC (permalink / raw)
To: Brian Norris, David Woodhouse, Boris Brezillon, Marek Vasut,
Richard Weinberger, Cyrille Pitchen, Rob Herring
Cc: Mark Rutland, devicetree, linux-mtd, Rafał Miłecki,
Jonas Gorski
In-Reply-To: <20180509081729.28347-1-zajec5@gmail.com>
Hi Rob,
On 09.05.2018 10:17, Rafał Miłecki wrote:
> From: Rafał Miłecki <rafal@milecki.pl>
>
> Broadcom based home router devices use partitions which have to be
> discovered in a specific way. They are not fixed and there is not any
> standard partition table. This commit adds and describes a new custom
> binding for such devices.
>
> Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
> ---
> This commit documents a new binding for describing partitions. Just as a
> reminder: we agreed to use "compatible" for that purpose to avoid
> /guessing/. There are too many cases, devices and /formats/ to just
> blindly try every possible parser.
>
> This was e.g. described by Boris in his patchset 2+ years ago:
> [RFC PATCH 0/7] mtd: partitions: add of_match_table support
> http://lists.infradead.org/pipermail/linux-mtd/2015-December/064076.html
>
> Quote:
>> (2) we can't just scan for all supported parsers (like the block system does), since
>> there is a wide diversity of "formats" (no standardization), and it is not
>> always safe or efficient to attempt to do so, particularly since many of
>> them allow their data structures to be placed anywhere on the flash, and
>> so require scanning the entire flash device to find them.
>
> I believe this solution was also acked back then by Rob:
> [RFC PATCH 3/7] doc: dt: mtd: partition: add on-flash format binding
> http://lists.infradead.org/pipermail/linux-mtd/2015-December/064100.html
>
> V2: Move documentation to the new brcm,bcm947xx-cfe-partitions.txt file
> as suggested by Rob (we don't want to bloat partition.txt).
> Slightly update commit message.
I sent this V2 per your request from V1:
On 8 May 2018 at 18:25, Rob Herring <robh@kernel.org> wrote:
> I guess this is fine. Can you resend as I don't have the original patch.
>
> I think it should be a separate file though as partition.txt would
> become very long if every vendor partitioning was added there.
Would you find a moment to review/nack/ack it, please?
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply
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