* [PATCH 1/1] iommu/arm-smmu: Fix for ThunderX erratum #27704
From: Tomasz Nowicki @ 2017-01-12 6:41 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <2c048126-a4d6-16af-987a-3174401a3960@arm.com>
On 11.01.2017 13:19, Robin Murphy wrote:
> On 11/01/17 11:51, Tomasz Nowicki wrote:
>> The goal of erratum #27704 workaround was to make sure that ASIDs and VMIDs
>> are unique across all SMMU instances on affected Cavium systems.
>>
>> Currently, the workaround code partitions ASIDs and VMIDs by increasing
>> global cavium_smmu_context_count which in turn becomes the base ASID and VMID
>> value for the given SMMU instance upon the context bank initialization.
>>
>> For systems with multiple SMMU instances this approach implies the risk
>> of crossing 8-bit ASID, like for CN88xx capable of 4 SMMUv2, 128 context bank each:
>> SMMU_0 (0-127 ASID RANGE)
>> SMMU_1 (127-255 ASID RANGE)
>> SMMU_2 (256-383 ASID RANGE) <--- crossing 8-bit ASID
>> SMMU_3 (384-511 ASID RANGE) <--- crossing 8-bit ASID
>
> I could swear that at some point in the original discussion it was said
> that the TLBs were only shared between pairs of SMMUs, so in fact 0/1
> and 2/3 are independent of each other
Indeed TLBs are only shared between pairs of SMMUs but the workaround
makes sure ASIDs are unique across all SMMU instances so we do not have
to bother about SMMUs probe order.
- out of interest, have you
> managed to hit an actual problem in practice or is this patch just by
> inspection?
Except SMMU0/1 devices all other devices under other SMMUs will fail on
guest power off/on. Since we try to invalidate tlb with 16bit ASID but
we actually have 8 bit zero padded 16 bit entry.
>
> Of course, depending on the SMMUs to probe in the right order isn't
> particularly robust, so it's still probably a worthwhile change.
>
>> Since we use 8-bit ASID now we effectively misconfigure ASID[15:8] bits for
>> SMMU_CBn_TTBRm register. Also, we still use non-zero ASID[15:8] bits
>> upon context invalidation. This patch adds 16-bit ASID support for stage-1
>> AArch64 contexts for Cavium SMMUv2 model so that we use ASIDs consistently.
>>
>> Signed-off-by: Tomasz Nowicki <tn@semihalf.com>
>> ---
>> drivers/iommu/arm-smmu.c | 4 ++++
>> 1 file changed, 4 insertions(+)
>>
>> diff --git a/drivers/iommu/arm-smmu.c b/drivers/iommu/arm-smmu.c
>> index a60cded..ae8f059 100644
>> --- a/drivers/iommu/arm-smmu.c
>> +++ b/drivers/iommu/arm-smmu.c
>> @@ -260,6 +260,7 @@ enum arm_smmu_s2cr_privcfg {
>>
>> #define TTBCR2_SEP_SHIFT 15
>> #define TTBCR2_SEP_UPSTREAM (0x7 << TTBCR2_SEP_SHIFT)
>> +#define TTBCR2_AS (1 << 4)
>>
>> #define TTBRn_ASID_SHIFT 48
>>
>> @@ -778,6 +779,9 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
>> reg = pgtbl_cfg->arm_lpae_s1_cfg.tcr;
>> reg2 = pgtbl_cfg->arm_lpae_s1_cfg.tcr >> 32;
>> reg2 |= TTBCR2_SEP_UPSTREAM;
>> + if (smmu->model == CAVIUM_SMMUV2 &&
>
> I'd be inclined to say "smmu->version == ARM_SMMU_V2" there, rather than
> make it Cavium-specific - we enable 16-bit VMID unconditionally where
> supported, so I don't see any reason not to handle 16-bit ASIDs in the
> same manner.
I agree, I will enable 16-bit ASID for ARM_SMMU_V2.
>
>> + cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64)
>> + reg2 |= TTBCR2_AS;
>> }
>> if (smmu->version > ARM_SMMU_V1)
>> writel_relaxed(reg2, cb_base + ARM_SMMU_CB_TTBCR2);
>>
>
> Either way:
>
> Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Thanks Robin!
Tomasz
^ permalink raw reply
* [PATCH v2 3/3] phy: rockchip-inno-usb2: Set EXTCON_USB when EXTCON_CHG_USB_SDP was set
From: Baolin Wang @ 2017-01-12 6:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMz4kuJP9Q7Ly4uRBjCFU32YzbVbnsGyk+wHc+M=g8W=uDBsEQ@mail.gmail.com>
On 3 January 2017 at 13:54, Baolin Wang <baolin.wang@linaro.org> wrote:
> Hi Kison and Heiko,
>
> On 21 December 2016 at 16:12, Baolin Wang <baolin.wang@linaro.org> wrote:
>> According to the documentation, we should set the EXTCON_USB when
>> one SDP charger connector was reported.
>>
>> Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
>> Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
>
> Could you apply this patch if there are no other comments? Thanks.
Ping?
--
Baolin.wang
Best Regards
^ permalink raw reply
* [PATCH] ARM: defconfig: include QCOM_EBI2 in multi_v7
From: Linus Walleij @ 2017-01-12 7:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <cee567ef-adc3-eb3f-81bb-e8a678b35fa8@codeaurora.org>
On Thu, Jan 12, 2017 at 2:01 AM, Stephen Boyd <sboyd@codeaurora.org> wrote:
> On 01/11/2017 07:22 AM, Linus Walleij wrote:
>> On Tue, Jan 10, 2017 at 7:02 PM, Olof Johansson <olof@lixom.net> wrote:
>>> On Tue, Jan 10, 2017 at 2:09 AM, Linus Walleij <linus.walleij@linaro.org> wrote:
>>>> This adds the Qualcomm External Bus Interface 2 to the multi_v7
>>>> defconfig: it is hard for users to realize that this is a
>>>> required driver for getting things like ethernet, and a necessary
>>>> prerequisite to get the external bus discoverable on the
>>>> MSM8660/APQ8060 machines.
>>> Is it the kind of option that should really be selected through
>>> Kconfig instead for those platforms?
>>
>> Stephen Boyd question.
>>
>> AFAIK the ambition is to go with the platform to have zero
>> stuff in mach-qcom/* and thus it all becomes a defconfig
>> thing.
>
> It could be made a 'default ARCH_QCOM' type of thing. Then the config
> doesn't need an update unless you want to turn it off.
OK I will do that.
Olof: let's scrap this patch.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH] bus: qcom_ebi2: default y if ARCH_QCOM
From: Linus Walleij @ 2017-01-12 7:08 UTC (permalink / raw)
To: linux-arm-kernel
Since we want this external bus to be available on multi_v7 builds,
set to default ARCH_QCOM so we get it selected whenever QCOM is
enabled.
Suggested-by: Stephen Boyd <sboyd@codeaurora.org>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
---
Andy: I guess you could queue this to ARM SoC, they seem so manage
drivers/bus from there.
---
drivers/bus/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index b9e8cfc93c7e..0a52da439abf 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -112,6 +112,7 @@ config QCOM_EBI2
bool "Qualcomm External Bus Interface 2 (EBI2)"
depends on HAS_IOMEM
depends on ARCH_QCOM || COMPILE_TEST
+ default ARCH_QCOM
help
Say y here to enable support for the Qualcomm External Bus
Interface 2, which can be used to connect things like NAND Flash,
--
2.9.3
^ permalink raw reply related
* [PATCH v2 5/5] ARM: dts: Add LEGO MINDSTORMS EV3 dts
From: Sekhar Nori @ 2017-01-12 7:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1dd57ac3-554f-7d66-97b0-b76c3ddc7854@lechnology.com>
On Wednesday 11 January 2017 09:55 PM, David Lechner wrote:
>>> +&spi0 {
>>> + status = "okay";
>>> + pinctrl-names = "default";
>>> + pinctrl-0 = <&spi0_pins>, <&spi0_cs0_pin>, <&spi0_cs3_pin>;
>>> +
>>> + flash at 0 {
>>> + compatible = "n25q128a13", "jedec,spi-nor";
>>> + reg = <0>;
>>> + spi-max-frequency = <50000000>;
>>> + ti,spi-wdelay = <8>;
>>> +
>>> + /* Partitions are based on the official firmware from LEGO */
>>> + partitions {
>>> + #address-cells = <1>;
>>> + #size-cells = <1>;
>>> + partition at 0 {
>>> + label = "U-Boot";
>>> + reg = <0 0x40000>;
>>> + };
>>> +
>>> + partition at 40000 {
>>> + label = "U-Boot Env";
>>> + reg = <0x40000 0x10000>;
>>> + };
>>> +
>>> + partition at 50000 {
>>> + label = "Kernel";
>>> + reg = <0x50000 0x200000>;
>>> + };
>>> +
>>> + partition at 250000 {
>>> + label = "Filesystem";
>>> + reg = <0x250000 0xa50000>;
>>> + };
>>> +
>>> + partition at cb0000 {
>>> + label = "Storage";
>>> + reg = <0xcb0000 0x2f0000>;
>>> + };
>>> + };
>>> + };
>>> +
>>> + adc at 3 {
>>> + compatible = "ti-ads7957";
>>
>> So looks like this works because of_register_spi_device() sets up
>> modalias of spi device from compatible string. I am fine with it, just
>> highlighting it here to make sure this is acceptable practice. I did not
>> really find any precedence for using SPI device name as compatible
>> property in existing DTS files.
>
> Indeed. It looks like this sort of "trivial" device binding is just used
> for i2c devices. I will submit some patches to add proper device tree
> bindings and change this to "ti,ads7957".
Alright, if you are going to do that, then I suggest you respin this
patch with the adc node dropped for now. That way we can ensure basic
board support in v4.11. If dependencies pan out, the adc can go in too
as a separate patch.
Thanks,
Sekhar
^ permalink raw reply
* [PATCH v8 00/18] KVM PCIe/MSI passthrough on ARM/ARM64 and IOVA reserved regions
From: Auger Eric @ 2017-01-12 7:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <AM5PR0401MB254547FE747461B3332721FC9A790@AM5PR0401MB2545.eurprd04.prod.outlook.com>
Hi Bharat,
On 12/01/2017 04:59, Bharat Bhushan wrote:
>
>
>> -----Original Message-----
>> From: Eric Auger [mailto:eric.auger at redhat.com]
>> Sent: Wednesday, January 11, 2017 3:12 PM
>> To: eric.auger at redhat.com; eric.auger.pro at gmail.com;
>> christoffer.dall at linaro.org; marc.zyngier at arm.com;
>> robin.murphy at arm.com; alex.williamson at redhat.com;
>> will.deacon at arm.com; joro at 8bytes.org; tglx at linutronix.de;
>> jason at lakedaemon.net; linux-arm-kernel at lists.infradead.org
>> Cc: kvm at vger.kernel.org; drjones at redhat.com; linux-
>> kernel at vger.kernel.org; pranav.sawargaonkar at gmail.com;
>> iommu at lists.linux-foundation.org; punit.agrawal at arm.com; Diana Madalina
>> Craciun <diana.craciun@nxp.com>; gpkulkarni at gmail.com;
>> shankerd at codeaurora.org; Bharat Bhushan <bharat.bhushan@nxp.com>;
>> geethasowjanya.akula at gmail.com
>> Subject: [PATCH v8 00/18] KVM PCIe/MSI passthrough on ARM/ARM64 and
>> IOVA reserved regions
>>
>> Following LPC discussions, we now report reserved regions through the
>> iommu-group sysfs reserved_regions attribute file.
>>
>> Reserved regions are populated through the IOMMU get_resv_region
>> callback (former get_dm_regions), now implemented by amd-iommu, intel-
>> iommu and arm-smmu:
>> - the intel-iommu reports the [0xfee00000 - 0xfeefffff] MSI window
>> as a reserved region and RMRR regions as direct-mapped regions.
>> - the amd-iommu reports device direct mapped regions, the MSI region
>> and HT regions.
>> - the arm-smmu reports the MSI window (arbitrarily located at
>> 0x8000000 and 1MB large).
>>
>> Unsafe interrupt assignment is tested by enumerating all MSI irq domains
>> and checking MSI remapping is supported in the above hierarchy.
>> This check is done in case we detect the iommu translates MSI (an
>> IOMMU_RESV_MSI window exists). Otherwise the IRQ remapping capability
>> is checked at IOMMU level. Obviously this is a defensive IRQ safety
>> assessment: Assuming there are several MSI controllers in the system and at
>> least one does not implement IRQ remapping, the assignment will be
>> considered as unsafe (even if this controller is not acessible from the
>> assigned devices).
>>
>> The series first patch stems from Robin's branch:
>> http://linux-arm.org/git?p=linux-
>> rm.git;a=shortlog;h=refs/heads/iommu/misc
>>
>> Best Regards
>>
>> Eric
>>
>> Git: complete series available at
>> https://github.com/eauger/linux/tree/v4.10-rc3-reserved-v8
>
> This series is tested on NXP platform, if you want you can add my tested by
> Tested-by: Bharat Bhushan <bharat.bhushan@nxp.com>
Thank you for this!
Best Regards
Eric
>
> Thanks
> -Bharat
>
>>
>> istory:
>>
>> PATCHv7 -> PATCHv8
>> - take into account Marc's comments and apply his R-b
>> - remove iommu_group_remove_file call in iommu_group_release
>> - add Will's A-b
>> - removed [PATCH v7 01/19] iommu/dma: Implement PCI allocation
>> optimisation and updated iommu/dma: Allow MSI-only cookies
>> as per Robin's indications
>>
>> PATCHv6 -> PATCHv7:
>> - iommu/dma: Implement PCI allocation optimisation was added to apply
>> iommu/dma: Allow MSI-only cookies
>> - report Intel RMRR as direct-mapped regions
>> - report the type in the iommu group sysfs reserved_regions file
>> - do not merge regions of different types when building the list
>> of reserved regions
>> - intgeration Robin's "iommu/dma: Allow MSI-only cookies" last
>> version
>> - update Documentation/ABI/testing/sysfs-kernel-iommu_groups
>> - rename IOMMU_RESV_NOMAP into IOMMU_RESV_RESERVED
>>
>> PATCHv5 -> PATCHv6
>> - Introduce IRQ_DOMAIN_FLAG_MSI as suggested by Marc
>> - irq_domain_is_msi, irq_domain_is_msi_remap,
>> irq_domain_hierarchical_is_msi_remap,
>> - set IRQ_DOMAIN_FLAG_MSI in msi_create_irq_domain
>> - fix compil issue on i386
>> - rework test at VFIO level
>>
>> RFCv4 -> PATCHv5
>> - fix IRQ security assessment by looking at irq domain parents
>> - check DOMAIN_BUS_FSL_MC_MSI irq domains
>> - AMD MSI and HT regions are exposed in iommu group sysfs
>>
>> RFCv3 -> RFCv4:
>> - arm-smmu driver does not register PCI host bridge windows as
>> reserved regions anymore
>> - Implement reserved region get/put callbacks also in arm-smmuv3
>> - take the iommu_group lock on iommu_get_group_resv_regions
>> - add a type field in iommu_resv_region instead of using prot
>> - init the region list_head in iommu_alloc_resv_region, also
>> add type parameter
>> - iommu_insert_resv_region manage overlaps and sort reserved
>> windows
>> - address IRQ safety assessment by enumerating all the MSI irq
>> domains and checking the MSI_REMAP flag
>> - update Documentation/ABI/testing/sysfs-kernel-iommu_groups
>>
>> RFC v2 -> v3:
>> - switch to an iommu-group sysfs API
>> - use new dummy allocator provided by Robin
>> - dummy allocator initialized by vfio-iommu-type1 after enumerating
>> the reserved regions
>> - at the moment ARM MSI base address/size is left unchanged compared
>> to v2
>> - we currently report reserved regions and not usable IOVA regions as
>> requested by Alex
>>
>> RFC v1 -> v2:
>> - fix intel_add_reserved_regions
>> - add mutex lock/unlock in vfio_iommu_type1
>>
>>
>> Eric Auger (17):
>> iommu: Rename iommu_dm_regions into iommu_resv_regions
>> iommu: Add a new type field in iommu_resv_region
>> iommu: iommu_alloc_resv_region
>> iommu: Only map direct mapped regions
>> iommu: iommu_get_group_resv_regions
>> iommu: Implement reserved_regions iommu-group sysfs file
>> iommu/vt-d: Implement reserved region get/put callbacks
>> iommu/amd: Declare MSI and HT regions as reserved IOVA regions
>> iommu/arm-smmu: Implement reserved region get/put callbacks
>> iommu/arm-smmu-v3: Implement reserved region get/put callbacks
>> irqdomain: Add irq domain MSI and MSI_REMAP flags
>> genirq/msi: Set IRQ_DOMAIN_FLAG_MSI on MSI domain creation
>> irqdomain: irq_domain_check_msi_remap
>> irqchip/gicv3-its: Sets IRQ_DOMAIN_FLAG_MSI_REMAP
>> vfio/type1: Allow transparent MSI IOVA allocation
>> vfio/type1: Check MSI remapping at irq domain level
>> iommu/arm-smmu: Do not advertise IOMMU_CAP_INTR_REMAP anymore
>>
>> Robin Murphy (1):
>> iommu/dma: Allow MSI-only cookies
>>
>> .../ABI/testing/sysfs-kernel-iommu_groups | 12 ++
>> drivers/iommu/amd_iommu.c | 54 ++++---
>> drivers/iommu/arm-smmu-v3.c | 30 +++-
>> drivers/iommu/arm-smmu.c | 30 +++-
>> drivers/iommu/dma-iommu.c | 119 +++++++++++---
>> drivers/iommu/intel-iommu.c | 92 ++++++++---
>> drivers/iommu/iommu.c | 177 +++++++++++++++++++--
>> drivers/irqchip/irq-gic-v3-its.c | 1 +
>> drivers/vfio/vfio_iommu_type1.c | 37 ++++-
>> include/linux/dma-iommu.h | 6 +
>> include/linux/iommu.h | 46 ++++--
>> include/linux/irqdomain.h | 36 +++++
>> kernel/irq/irqdomain.c | 36 +++++
>> kernel/irq/msi.c | 4 +-
>> 14 files changed, 587 insertions(+), 93 deletions(-)
>>
>> --
>> 1.9.1
>
^ permalink raw reply
* [PATCH v2 3/3] phy: rockchip-inno-usb2: Set EXTCON_USB when EXTCON_CHG_USB_SDP was set
From: Kishon Vijay Abraham I @ 2017-01-12 8:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAMz4ku+X8v2HH5L_fS60naNTqR1ZFKYeWuXuHqjg0UsHQq1dsQ@mail.gmail.com>
Hi,
On Thursday 12 January 2017 12:13 PM, Baolin Wang wrote:
> On 3 January 2017 at 13:54, Baolin Wang <baolin.wang@linaro.org> wrote:
>> Hi Kison and Heiko,
>>
>> On 21 December 2016 at 16:12, Baolin Wang <baolin.wang@linaro.org> wrote:
>>> According to the documentation, we should set the EXTCON_USB when
>>> one SDP charger connector was reported.
>>>
>>> Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
>>> Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
>>
>> Could you apply this patch if there are no other comments? Thanks.
Does it fix something? Or else it can go in the next merge window.
Thanks
Kishon
^ permalink raw reply
* [PATCH 0/4] ARM: dts: mt7623: Add initial Geek Force support
From: John Crispin @ 2017-01-12 8:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <3fecb422-8185-7ee0-c203-2bfdc4fd1393@phrozen.org>
Hi Andreas,
had a look last night why the ethernet dtsi was not added and it
obviously was not added as we were waiting for the clk-mt2701 to be
merged. the ethernet dtsi will have phandles pointing at the clk nodes
which did not exist at the time. same is true for the PWM code.
i sat down last night and worked out what pending patches i still have
for mt7623 and out of the ~80 required to get v4.4 working i only need
around 10 for v4.10-rc1.
i started to rebase these patches last night and will have time to test
them tomorrow or early next week. as the pwrap node alone is around 200
lines of devicetree we need to figure out a way to add this to the dts
files without duplicating it. i'll try to post a series early next week
that we can then discuss and rebase your geekboard patches on.
John
^ permalink raw reply
* [PATCH 0/4] video: ARM CLCD: add support of an optional GPIO to enable panel
From: Linus Walleij @ 2017-01-12 8:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <330598fa-d331-3695-b0a2-3590059e2be4@mleia.com>
On Thu, Jan 12, 2017 at 1:05 AM, Vladimir Zapolskiy <vz@mleia.com> wrote:
> On 01/11/2017 05:16 PM, Linus Walleij wrote:
>> On Tue, Jan 10, 2017 at 2:47 PM, Vladimir Murzin
>> <vladimir.murzin@arm.com> wrote:
>>
>>> In another thread Benjamin pointed at patch [1] in drm/kms part for noMMU.
>>>
>>> [1] https://cgit.freedesktop.org/drm/drm-misc/commit/?id=62a0d98a188cc4ebd8ea54b37d274ec20465e464
>>
>> Problem solved?
>>
>> Vladimir: I do not require in any way that you create a CLCD driver for DRM,
>> I just think it would be very very nice...
>>
>
> I have no other option, this series is unreviewed and thus unlikely it will
> be applied, still a panel PCB on my board needs power management support.
Hm I can ACK it I guess, but mergeing it into an unmaintained subsystem
is another issue, just not very optimal. If you get it working on your system
I can look into migrating all the old users to DRM as well.
Yours,
Linus Walleij
^ permalink raw reply
* [PATCH v2 3/3] phy: rockchip-inno-usb2: Set EXTCON_USB when EXTCON_CHG_USB_SDP was set
From: Baolin Wang @ 2017-01-12 8:37 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <58773BC8.2050808@ti.com>
Hi,
On 12 January 2017 at 16:18, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> Hi,
>
> On Thursday 12 January 2017 12:13 PM, Baolin Wang wrote:
>> On 3 January 2017 at 13:54, Baolin Wang <baolin.wang@linaro.org> wrote:
>>> Hi Kison and Heiko,
>>>
>>> On 21 December 2016 at 16:12, Baolin Wang <baolin.wang@linaro.org> wrote:
>>>> According to the documentation, we should set the EXTCON_USB when
>>>> one SDP charger connector was reported.
>>>>
>>>> Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
>>>> Reviewed-by: Chanwoo Choi <cw00.choi@samsung.com>
>>>
>>> Could you apply this patch if there are no other comments? Thanks.
>
> Does it fix something? Or else it can go in the next merge window.
Just fix the correct usage of EXTCON_CHG_USB_SDP connector. It's okay
for me that it can go in the next merge window. Thanks.
--
Baolin.wang
Best Regards
^ permalink raw reply
* [PATCH v5 0/4] drm/dp: Implement CRC debugfs API
From: Tomeu Vizoso @ 2017-01-12 8:58 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
this series builds up on the API for exposing captured CRCs through
debugfs.
It adds new DP helpers for starting and stopping CRC capture and gets
the Rockchip driver to use it.
Also had to add a connector backpointer to the drm_dp_aux struct so we could
wait for the right vblank and store the CRCs afterwards, I will be glad
to hear about better alternatives.
With these patches, tests in IGT such as kms_pipe_crc_basic and
kms_plane do pass on RK3288.
In this v5, "drm/dp: add helpers for capture of frame CRCs" has gone
back to the more explicit way of just retrying once.
Also, I have left the connector back pointer in the AUX structure, as on
IRC nor danvet nor me could find a good reason to change it.
Thanks,
Tomeu
Tomeu Vizoso (4):
drm/bridge: analogix_dp: set connector to drm_dp_aux
drm/dp: add helpers for capture of frame CRCs
drm/bridge: analogix_dp: add helpers for capture of frame CRCs
drm/rockchip: Implement CRC debugfs API
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 34 ++++--
drivers/gpu/drm/drm_dp_helper.c | 124 +++++++++++++++++++++
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 42 +++++++
include/drm/bridge/analogix_dp.h | 3 +
include/drm/drm_dp_helper.h | 7 ++
5 files changed, 202 insertions(+), 8 deletions(-)
--
2.9.3
^ permalink raw reply
* [PATCH v5 4/4] drm/rockchip: Implement CRC debugfs API
From: Tomeu Vizoso @ 2017-01-12 8:58 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170112085844.19878-1-tomeu.vizoso@collabora.com>
Implement the .set_crc_source() callback and call the DP helpers
accordingly to start and stop CRC capture.
This is only done if this CRTC is currently using the eDP connector.
v3: Remove superfluous check on rockchip_crtc_state->output_type
Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
---
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 42 +++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index fb5f001f51c3..6e5eb1aa182a 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -19,6 +19,7 @@
#include <drm/drm_crtc_helper.h>
#include <drm/drm_flip_work.h>
#include <drm/drm_plane_helper.h>
+#include <drm/bridge/analogix_dp.h>
#include <linux/kernel.h>
#include <linux/module.h>
@@ -1105,6 +1106,46 @@ static void vop_crtc_destroy_state(struct drm_crtc *crtc,
kfree(s);
}
+static struct drm_connector *vop_get_edp_connector(struct vop *vop)
+{
+ struct drm_crtc *crtc = &vop->crtc;
+ struct drm_connector *connector;
+
+ mutex_lock(&crtc->dev->mode_config.mutex);
+ drm_for_each_connector(connector, crtc->dev)
+ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+ mutex_unlock(&crtc->dev->mode_config.mutex);
+ return connector;
+ }
+ mutex_unlock(&crtc->dev->mode_config.mutex);
+
+ return NULL;
+}
+
+static int vop_crtc_set_crc_source(struct drm_crtc *crtc,
+ const char *source_name, size_t *values_cnt)
+{
+ struct vop *vop = to_vop(crtc);
+ struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
+ struct drm_connector *connector;
+ int ret;
+
+ connector = vop_get_edp_connector(vop);
+ if (!connector)
+ return -EINVAL;
+
+ *values_cnt = 3;
+
+ if (source_name && strcmp(source_name, "auto") == 0)
+ ret = analogix_dp_start_crc(connector);
+ else if (!source_name)
+ ret = analogix_dp_stop_crc(connector);
+ else
+ ret = -EINVAL;
+
+ return ret;
+}
+
static const struct drm_crtc_funcs vop_crtc_funcs = {
.set_config = drm_atomic_helper_set_config,
.page_flip = drm_atomic_helper_page_flip,
@@ -1112,6 +1153,7 @@ static const struct drm_crtc_funcs vop_crtc_funcs = {
.reset = vop_crtc_reset,
.atomic_duplicate_state = vop_crtc_duplicate_state,
.atomic_destroy_state = vop_crtc_destroy_state,
+ .set_crc_source = vop_crtc_set_crc_source,
};
static void vop_fb_unref_worker(struct drm_flip_work *work, void *val)
--
2.9.3
^ permalink raw reply related
* [PATCH v7 0/4] arm64: arch_timer: Add workaround for hisilicon-161601 erratum
From: Marc Zyngier @ 2017-01-12 9:11 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <6c33e4e9-6472-4738-aea2-55dcaab3a94f@huawei.com>
On 12/01/17 04:23, Ding Tianhong wrote:
> Hi Marc:
>
> How about this v7, if any suggestions very grateful.
It's been less than 5 days since you posted this. I'll get to it once I
finish reviewing all the other patches that are sitting in the queue
right before yours.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCHv3 3/5] pinctrl: mvebu: pinctrl driver for 98DX3236 SoC
From: Chris Packham @ 2017-01-12 9:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <95cb4240-e77b-5eaa-1920-4d9e26028038@gmail.com>
On 12/01/17 09:56, Sebastian Hesselbarth wrote:
> On 01/11/2017 03:44 PM, Linus Walleij wrote:
>> On Fri, Jan 6, 2017 at 5:15 AM, Chris Packham
>> <chris.packham@alliedtelesis.co.nz> wrote:
>>
>>> From: Kalyan Kinthada <kalyan.kinthada@alliedtelesis.co.nz>
>>>
>>> This pinctrl driver supports the 98DX3236, 98DX3336 and 98DX4251 SoCs
>>> from Marvell.
>>>
>>> Signed-off-by: Kalyan Kinthada <kalyan.kinthada@alliedtelesis.co.nz>
>>> Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
>>
>> I am waiting for an ACK or comment from the maintainers on
>> this patch. Sebastian?
>
> Sorry for the ignorance.
>
> I don't have the patch to reply to inline, but:
>
> - In the driver MPP_MODE2, spi0 there is a typo "csk" instead of "sck".
> - MPP_MODE5 binding "dev","bootcs" and driver "dev","bootcs0" differ.
> - MPP_MODE6 binding "gpio" and driver "gpo" differ.
> - MPP_MODE17 binding "dev","clk" and driver "dev","clkout" differ.
> - MPP_MODE19 binding mentiones "dev","rb" but driver does not.
> - MPP_MODE20 binding "gpio" and driver "gpo" differ.
> - MPP_MODE20 binding "dev","we" and driver "dev","we0" differ.
> - MPP_MODE21 through MPP_MODE30 binding "gpio" and driver "gpo" differ.
> - remove spaces before "0, 0" in mv98dx3236_mpp_gpio_ranges.
>
> Most of it is cosmetic stuff, so if you fix it feel free to add my
>
> Acked-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
Hi Sebastian,
Hopefully I can get a v4 out with the above fixed soon.
One point on "gpio" vs "gpo" this one isn't a typo. Some of these pins
can be driven as outputs but can't be used as inputs. From a pinctrl
driver point of view there is no difference but I did want to convey
that from a system design point of view if you really need something to
be an input you shouldn't use one of these pins. This is also noted in
the datasheets so it doesn't necessarily need repeating. If you still
want me to use "gpio" in the code and binding I'm happy to do so.
^ permalink raw reply
* [PATCH v2 00/11] add support for VBUS max current and min voltage limits AXP20X and AXP22X PMICs
From: Maxime Ripard @ 2017-01-12 9:28 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161209110419.28981-1-quentin.schulz@free-electrons.com>
On Fri, Dec 09, 2016 at 12:04:08PM +0100, Quentin Schulz wrote:
> The X-Powers AXP209 and AXP20X PMICs are able to set a limit for the
> VBUS power supply for both max current and min voltage supplied. This
> series of patch adds the possibility to set these limits from sysfs.
>
> Also, the AXP223 PMIC shares most of its behaviour with the AXP221 but
> the former can set the VBUS power supply max current to 100mA, unlike
> the latter. The AXP223 VBUS power supply driver used to probe on the
> AXP221 compatible. This series of patch introduces a new compatible for
> the AXP223 to be able to set the current max limit to 100mA.
>
> With that new compatible, boards having the AXP223 see their DT updated
> to use the VBUS power supply driver with the correct compatible.
>
> This series of patch also migrates from of_device_is_compatible function
> to the data field of of_device_id to identify the compatible used to
> probe. This improves the code readability.
>
> Mostly cosmetic changes in v2 and adding volatile and writeable regs to
> AXP20X and AXP22X MFD cells for the VBUS power supply driver.
Applied all the DT patches. I also fixed all the prefixes. Please make
sure to look at what prefixes are used by a given subsystem next time.
Thanks!
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170112/8fc64b9f/attachment.sig>
^ permalink raw reply
* kvm: deadlock in kvm_vgic_map_resources
From: Marc Zyngier @ 2017-01-12 9:32 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CACT4Y+YRg=H0F-_QTtPf0--o85sQCb__j=V25tPchx9ycYtyKg@mail.gmail.com>
Hi Dmitry,
On 11/01/17 19:01, Dmitry Vyukov wrote:
> Hello,
>
> While running syzkaller fuzzer I've got the following deadlock.
> On commit 9c763584b7c8911106bb77af7e648bef09af9d80.
>
>
> =============================================
> [ INFO: possible recursive locking detected ]
> 4.9.0-rc6-xc2-00056-g08372dd4b91d-dirty #50 Not tainted
> ---------------------------------------------
> syz-executor/20805 is trying to acquire lock:
> (
> &kvm->lock
> ){+.+.+.}
> , at:
> [< inline >] kvm_vgic_dist_destroy
> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:271
> [<ffff2000080ea4bc>] kvm_vgic_destroy+0x34/0x250
> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:294
> but task is already holding lock:
> (&kvm->lock){+.+.+.}, at:
> [<ffff2000080ea7e4>] kvm_vgic_map_resources+0x2c/0x108
> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:343
> other info that might help us debug this:
> Possible unsafe locking scenario:
> CPU0
> ----
> lock(&kvm->lock);
> lock(&kvm->lock);
> *** DEADLOCK ***
> May be due to missing lock nesting notation
> 2 locks held by syz-executor/20805:
> #0:(&vcpu->mutex){+.+.+.}, at:
> [<ffff2000080bcc30>] vcpu_load+0x28/0x1d0
> arch/arm64/kvm/../../../virt/kvm/kvm_main.c:143
> #1:(&kvm->lock){+.+.+.}, at:
> [<ffff2000080ea7e4>] kvm_vgic_map_resources+0x2c/0x108
> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:343
> stack backtrace:
> CPU: 2 PID: 20805 Comm: syz-executor Not tainted
> 4.9.0-rc6-xc2-00056-g08372dd4b91d-dirty #50
> Hardware name: Hardkernel ODROID-C2 (DT)
> Call trace:
> [<ffff200008090560>] dump_backtrace+0x0/0x3c8 arch/arm64/kernel/traps.c:69
> [<ffff200008090948>] show_stack+0x20/0x30 arch/arm64/kernel/traps.c:219
> [< inline >] __dump_stack lib/dump_stack.c:15
> [<ffff200008895840>] dump_stack+0x100/0x150 lib/dump_stack.c:51
> [< inline >] print_deadlock_bug kernel/locking/lockdep.c:1728
> [< inline >] check_deadlock kernel/locking/lockdep.c:1772
> [< inline >] validate_chain kernel/locking/lockdep.c:2250
> [<ffff2000081c8718>] __lock_acquire+0x1938/0x3440 kernel/locking/lockdep.c:3335
> [<ffff2000081caa84>] lock_acquire+0xdc/0x1d8 kernel/locking/lockdep.c:3746
> [< inline >] __mutex_lock_common kernel/locking/mutex.c:521
> [<ffff200009700004>] mutex_lock_nested+0xdc/0x7b8 kernel/locking/mutex.c:621
> [< inline >] kvm_vgic_dist_destroy
> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:271
> [<ffff2000080ea4bc>] kvm_vgic_destroy+0x34/0x250
> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:294
> [<ffff2000080ec290>] vgic_v2_map_resources+0x218/0x430
> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-v2.c:295
> [<ffff2000080ea884>] kvm_vgic_map_resources+0xcc/0x108
> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:348
> [< inline >] kvm_vcpu_first_run_init
> arch/arm64/kvm/../../../arch/arm/kvm/arm.c:505
> [<ffff2000080d2768>] kvm_arch_vcpu_ioctl_run+0xab8/0xce0
> arch/arm64/kvm/../../../arch/arm/kvm/arm.c:591
> [<ffff2000080c1fec>] kvm_vcpu_ioctl+0x434/0xc08
> arch/arm64/kvm/../../../virt/kvm/kvm_main.c:2557
> [< inline >] vfs_ioctl fs/ioctl.c:43
> [<ffff200008450c38>] do_vfs_ioctl+0x128/0xfc0 fs/ioctl.c:679
> [< inline >] SYSC_ioctl fs/ioctl.c:694
> [<ffff200008451b78>] SyS_ioctl+0xa8/0xb8 fs/ioctl.c:685
> [<ffff200008083ef0>] el0_svc_naked+0x24/0x28 arch/arm64/kernel/entry.S:755
Nice catch, and many thanks for reporting this.
The bug is fairly obvious. Christoffer, what do you think? I don't think
we need to hold the kvm->lock all the way, but I'd like another pair of
eyes (the coffee machine is out of order again, and tea doesn't cut it).
Thanks,
M.
>From 93f80b20fb9351a49ee8b74eed3fc59c84651371 Mon Sep 17 00:00:00 2001
From: Marc Zyngier <marc.zyngier@arm.com>
Date: Thu, 12 Jan 2017 09:21:56 +0000
Subject: [PATCH] KVM: arm/arm64: vgic: Fix deadlock on error handling
Dmitry Vyukov reported that the syzkaller fuzzer triggered a
deadlock in the vgic setup code when an error was detected, as
the cleanup code tries to take a lock that is already held by
the setup code.
The fix is pretty obvious: move the cleaup call after having
dropped the lock, since not much can happen at that point.
Cc: stable at vger.kernel.org
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
virt/kvm/arm/vgic/vgic-init.c | 4 ++++
virt/kvm/arm/vgic/vgic-v2.c | 2 --
virt/kvm/arm/vgic/vgic-v3.c | 2 --
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
index 5114391..0e0c295 100644
--- a/virt/kvm/arm/vgic/vgic-init.c
+++ b/virt/kvm/arm/vgic/vgic-init.c
@@ -350,6 +350,10 @@ int kvm_vgic_map_resources(struct kvm *kvm)
ret = vgic_v3_map_resources(kvm);
out:
mutex_unlock(&kvm->lock);
+
+ if (ret)
+ kvm_vgic_destroy(kvm);
+
return ret;
}
diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c
index 9bab867..834137e 100644
--- a/virt/kvm/arm/vgic/vgic-v2.c
+++ b/virt/kvm/arm/vgic/vgic-v2.c
@@ -293,8 +293,6 @@ int vgic_v2_map_resources(struct kvm *kvm)
dist->ready = true;
out:
- if (ret)
- kvm_vgic_destroy(kvm);
return ret;
}
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
index 7df1b90..a4c7fff 100644
--- a/virt/kvm/arm/vgic/vgic-v3.c
+++ b/virt/kvm/arm/vgic/vgic-v3.c
@@ -308,8 +308,6 @@ int vgic_v3_map_resources(struct kvm *kvm)
dist->ready = true;
out:
- if (ret)
- kvm_vgic_destroy(kvm);
return ret;
}
--
2.1.4
--
Jazz is not dead. It just smells funny...
^ permalink raw reply related
* [PATCH 56/62] watchdog: tangox_wdt: Convert to use device managed functions
From: Marc Gonzalez @ 2017-01-12 9:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170111175110.GB22289@roeck-us.net>
On 11/01/2017 18:51, Guenter Roeck wrote:
> However, some other unrelated undefined behavior does not mean that this
> specific behavior is undefined.
True :-)
Let me just give two additional examples of UB that /have/ bitten
Linux kernel devs.
int i;
for (i = 1; i > 0; ++i)
/* do_something(); */
=> optimized into an infinite loop
and
void func(struct foo *p) {
int n = p->field;
if (!p) return;
=> null-pointer check optimized away
> So far we have a claim that a cast to a void * may somehow be different
> to a cast to a different pointer, if used as function argument, and that
> the behavior with such a cast may be undefined. In other words, you claim
> that a function implemented as, say,
>
> void func(int *var) {}
>
> might result in undefined behavior if some header file declares it as
>
> void func(void *);
>
> and it is called as
>
> int var;
>
> func(&var);
>
> That seems really far fetched to me.
Thanks for giving me an opportunity to play the language lawyer :-)
C99 6.3.2.3 sub-clause 8 states:
"A pointer to a function of one type may be converted to a pointer to a function of another
type and back again; the result shall compare equal to the original pointer. If a converted
pointer is used to call a function whose type is not compatible with the pointed-to type,
the behavior is undefined."
So, the behavior is undefined, not when you cast clk_disable_unprepare,
but when clk_disable_unprepare is later called through the devres->action
function pointer.
However, I agree that it will work as expected on typical platforms
(where all pointers are the same size, and the calling convention
treats all pointers the same).
> I do get the message that you do not like this kind of cast. But that doesn't
> mean it is not correct.
If it's already widely used in the kernel, it seems there is no point
fighting it ;-)
Regards.
^ permalink raw reply
* [RFC PATCH] arm64: defconfig: enable SMMUv3 config
From: Catalin Marinas @ 2017-01-12 9:47 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <5876CF7C.8080907@hisilicon.com>
On Thu, Jan 12, 2017 at 08:36:12AM +0800, Zhou Wang wrote:
> On 2017/1/9 19:50, Zhou Wang wrote:
> > Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
> > ---
> > arch/arm64/configs/defconfig | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
> > index 869dded..3520c50 100644
> > --- a/arch/arm64/configs/defconfig
> > +++ b/arch/arm64/configs/defconfig
> > @@ -440,6 +440,7 @@ CONFIG_PLATFORM_MHU=y
> > CONFIG_BCM2835_MBOX=y
> > CONFIG_HI6220_MBOX=y
> > CONFIG_ARM_SMMU=y
> > +CONFIG_ARM_SMMU_V3=y
> > CONFIG_RASPBERRYPI_POWER=y
> > CONFIG_QCOM_SMEM=y
> > CONFIG_QCOM_SMD=y
>
> I just happened to find there is no SMMUv3 config in arm64 defconfig.
>
> Maybe we should add it in defconfig or I miss something.
It looks fine to me but it's usually the arm-soc guys picking the
defconfig patches.
--
Catalin
^ permalink raw reply
* [PATCH v6 23/25] usb: chipidea: Pullup D+ in device mode via phy APIs
From: Peter Chen @ 2017-01-12 9:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <148418039309.32258.7247753739063801774@sboyd-linaro>
On Wed, Jan 11, 2017 at 04:19:53PM -0800, Stephen Boyd wrote:
> Quoting Peter Chen (2017-01-02 22:53:19)
> > On Wed, Dec 28, 2016 at 02:57:09PM -0800, Stephen Boyd wrote:
> > > If the phy supports it, call phy_set_mode() to pull up D+ when
> > > required by setting the mode to PHY_MODE_USB_DEVICE. If we want
> > > to remove the pullup, set the mode to PHY_MODE_USB_HOST.
> > >
> [..]
> > > diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> > > index 0d532a724d48..6d61fa0689b0 100644
> > > --- a/drivers/usb/chipidea/udc.c
> > > +++ b/drivers/usb/chipidea/udc.c
> > > @@ -1609,10 +1610,15 @@ static int ci_udc_pullup(struct usb_gadget *_gadget, int is_on)
> > > return 0;
> > >
> > > pm_runtime_get_sync(&ci->gadget.dev);
> > > - if (is_on)
> > > + if (is_on) {
> > > + if (ci->phy)
> > > + phy_set_mode(ci->phy, PHY_MODE_USB_DEVICE);
> > > hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
> > > - else
> > > + } else {
> > > hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
> > > + if (ci->phy)
> > > + phy_set_mode(ci->phy, PHY_MODE_USB_HOST);
> > > + }
> > > pm_runtime_put_sync(&ci->gadget.dev);
> > >
> > > return 0;
> >
> > Would you describe the use case for it? Why not adding it at
> > role switch routine?
> >
>
> This is about pulling up D+. The phy I have requires that we manually
> pull up D+ by writing a ULPI register before we set the run/stop bit.
Afaik, only controller can pull up dp when it is at device mode by
setting USBCMD_RS. At host mode, clear USBCMD_RS will only stopping
sending SoF from controller side.
I am puzzled why you can pull up D+ by writing an ULPI register, perhaps,
your phy needs DP to change before switching the mode? Would you
double confirm that?
> I
> thought it would be appropriate to do so in ci_udc_pullup(), where we're
> supposed to put that pullup code, unless I'm mistaken?
>
> It's not exactly about putting the phy into device or host mode, so
> phy_set_mode() may not actually be the best API to use. Perhaps we need
> some sort of phy_pullup_usb() API here?
--
Best Regards,
Peter Chen
^ permalink raw reply
* [PATCH v6 11/25] usb: chipidea: vbus event may exist before starting gadget
From: Peter Chen @ 2017-01-12 9:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <148418115431.32258.10648057913784071156@sboyd-linaro>
On Wed, Jan 11, 2017 at 04:32:34PM -0800, Stephen Boyd wrote:
> Quoting Peter Chen (2017-01-03 00:00:31)
> > On Wed, Dec 28, 2016 at 02:56:57PM -0800, Stephen Boyd wrote:
> > > From: Peter Chen <peter.chen@nxp.com>
> > >
> > > At some situations, the vbus may already be there before starting
> > > gadget. So we need to check vbus event after switch to gadget in
> > > order to handle missing vbus event. The typical use cases are plugging
> > > vbus cable before driver load or the vbus has already been there
> > > after stopping host but before starting gadget.
> > >
> > > Signed-off-by: Peter Chen <peter.chen@nxp.com>
> > > Tested-by: Stephen Boyd <stephen.boyd@linaro.org>
> > > Reviewed-by: Stephen Boyd <stephen.boyd@linaro.org>
> > > [sboyd at codeaurora.org: Modify comment text per list discussion]
> > > Signed-off-by: Stephen Boyd <stephen.boyd@linaro.org>
> > > ---
> > > drivers/usb/chipidea/core.c | 4 ----
> > > drivers/usb/chipidea/otg.c | 14 +++++++++-----
> > > drivers/usb/chipidea/udc.c | 2 ++
> > > 3 files changed, 11 insertions(+), 9 deletions(-)
> > >
> > > diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
> > > index 8a020ebbbe2f..37f888e31f10 100644
> > > --- a/drivers/usb/chipidea/core.c
> > > +++ b/drivers/usb/chipidea/core.c
> > > @@ -979,10 +979,6 @@ static int ci_hdrc_probe(struct platform_device *pdev)
> > > }
> > >
> > > if (!ci_otg_is_fsm_mode(ci)) {
> > > - /* only update vbus status for peripheral */
> > > - if (ci->role == CI_ROLE_GADGET)
> > > - ci_handle_vbus_change(ci);
> > > -
> > > ret = ci_role_start(ci, ci->role);
> > > if (ret) {
> > > dev_err(dev, "can't start %s role\n",
> > > diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
> > > index 695f3fe3ae21..c972ed23b8ec 100644
> > > --- a/drivers/usb/chipidea/otg.c
> > > +++ b/drivers/usb/chipidea/otg.c
> > > @@ -134,9 +134,9 @@ void ci_handle_vbus_change(struct ci_hdrc *ci)
> > > if (!ci->is_otg)
> > > return;
> > >
> > > - if (hw_read_otgsc(ci, OTGSC_BSV))
> > > + if (hw_read_otgsc(ci, OTGSC_BSV) && !ci->vbus_active)
> > > usb_gadget_vbus_connect(&ci->gadget);
> > > - else
> > > + else if (!hw_read_otgsc(ci, OTGSC_BSV) && ci->vbus_active)
> > > usb_gadget_vbus_disconnect(&ci->gadget);
> > > }
> > >
> > > @@ -175,10 +175,14 @@ static void ci_handle_id_switch(struct ci_hdrc *ci)
> > >
> > > ci_role_stop(ci);
> > >
> > > - if (role == CI_ROLE_GADGET)
> > > + if (role == CI_ROLE_GADGET &&
> > > + IS_ERR(ci->platdata->vbus_extcon.edev))
> > > /*
> > > - * wait vbus lower than OTGSC_BSV before connecting
> > > - * to host
> > > + * wait vbus lower than OTGSC_BSV before connecting to
> > > + * host. If connecting status is from an external
> > > + * connector instead of register, we don't need to care
> > > + * vbus on the board, since it will not affect external
> > > + * connector status.
> > > */
> > > hw_wait_vbus_lower_bsv(ci);
> > >
> > > diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
> > > index 732b281485de..0db56fb7e9e9 100644
> > > --- a/drivers/usb/chipidea/udc.c
> > > +++ b/drivers/usb/chipidea/udc.c
> > > @@ -1961,6 +1961,8 @@ static int udc_id_switch_for_device(struct ci_hdrc *ci)
> > > /* Clear and enable BSV irq */
> > > hw_write_otgsc(ci, OTGSC_BSVIS | OTGSC_BSVIE,
> > > OTGSC_BSVIS | OTGSC_BSVIE);
> > > + /* vbus change may has already been occurred */
> > > + ci_handle_vbus_change(ci);
> > >
> > > return 0;
> >
> > After thinking more, the above change will affect OTG FSM which calls
> > this API too, but handle vbus change later, see ci_otg_start_host and
> > ci_otg_start_gadget. How about changing patch like below:
>
> Ok. I'll give it a spin but I think that should work too. I don't have
> any hardware to test the OTG FSM to make sure things don't break.
ci_handle_id_switch is only called at non OTG FSM mode, so it will not
affect OTG FSM.
--
Best Regards,
Peter Chen
^ permalink raw reply
* kvm: deadlock in kvm_vgic_map_resources
From: Andre Przywara @ 2017-01-12 9:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <70371c5c-d0c0-b59e-b12c-fd8359392763@arm.com>
Hi,
On 12/01/17 09:32, Marc Zyngier wrote:
> Hi Dmitry,
>
> On 11/01/17 19:01, Dmitry Vyukov wrote:
>> Hello,
>>
>> While running syzkaller fuzzer I've got the following deadlock.
>> On commit 9c763584b7c8911106bb77af7e648bef09af9d80.
>>
>>
>> =============================================
>> [ INFO: possible recursive locking detected ]
>> 4.9.0-rc6-xc2-00056-g08372dd4b91d-dirty #50 Not tainted
>> ---------------------------------------------
>> syz-executor/20805 is trying to acquire lock:
>> (
>> &kvm->lock
>> ){+.+.+.}
>> , at:
>> [< inline >] kvm_vgic_dist_destroy
>> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:271
>> [<ffff2000080ea4bc>] kvm_vgic_destroy+0x34/0x250
>> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:294
>> but task is already holding lock:
>> (&kvm->lock){+.+.+.}, at:
>> [<ffff2000080ea7e4>] kvm_vgic_map_resources+0x2c/0x108
>> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:343
>> other info that might help us debug this:
>> Possible unsafe locking scenario:
>> CPU0
>> ----
>> lock(&kvm->lock);
>> lock(&kvm->lock);
>> *** DEADLOCK ***
>> May be due to missing lock nesting notation
>> 2 locks held by syz-executor/20805:
>> #0:(&vcpu->mutex){+.+.+.}, at:
>> [<ffff2000080bcc30>] vcpu_load+0x28/0x1d0
>> arch/arm64/kvm/../../../virt/kvm/kvm_main.c:143
>> #1:(&kvm->lock){+.+.+.}, at:
>> [<ffff2000080ea7e4>] kvm_vgic_map_resources+0x2c/0x108
>> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:343
>> stack backtrace:
>> CPU: 2 PID: 20805 Comm: syz-executor Not tainted
>> 4.9.0-rc6-xc2-00056-g08372dd4b91d-dirty #50
>> Hardware name: Hardkernel ODROID-C2 (DT)
>> Call trace:
>> [<ffff200008090560>] dump_backtrace+0x0/0x3c8 arch/arm64/kernel/traps.c:69
>> [<ffff200008090948>] show_stack+0x20/0x30 arch/arm64/kernel/traps.c:219
>> [< inline >] __dump_stack lib/dump_stack.c:15
>> [<ffff200008895840>] dump_stack+0x100/0x150 lib/dump_stack.c:51
>> [< inline >] print_deadlock_bug kernel/locking/lockdep.c:1728
>> [< inline >] check_deadlock kernel/locking/lockdep.c:1772
>> [< inline >] validate_chain kernel/locking/lockdep.c:2250
>> [<ffff2000081c8718>] __lock_acquire+0x1938/0x3440 kernel/locking/lockdep.c:3335
>> [<ffff2000081caa84>] lock_acquire+0xdc/0x1d8 kernel/locking/lockdep.c:3746
>> [< inline >] __mutex_lock_common kernel/locking/mutex.c:521
>> [<ffff200009700004>] mutex_lock_nested+0xdc/0x7b8 kernel/locking/mutex.c:621
>> [< inline >] kvm_vgic_dist_destroy
>> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:271
>> [<ffff2000080ea4bc>] kvm_vgic_destroy+0x34/0x250
>> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:294
>> [<ffff2000080ec290>] vgic_v2_map_resources+0x218/0x430
>> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-v2.c:295
>> [<ffff2000080ea884>] kvm_vgic_map_resources+0xcc/0x108
>> arch/arm64/kvm/../../../virt/kvm/arm/vgic/vgic-init.c:348
>> [< inline >] kvm_vcpu_first_run_init
>> arch/arm64/kvm/../../../arch/arm/kvm/arm.c:505
>> [<ffff2000080d2768>] kvm_arch_vcpu_ioctl_run+0xab8/0xce0
>> arch/arm64/kvm/../../../arch/arm/kvm/arm.c:591
>> [<ffff2000080c1fec>] kvm_vcpu_ioctl+0x434/0xc08
>> arch/arm64/kvm/../../../virt/kvm/kvm_main.c:2557
>> [< inline >] vfs_ioctl fs/ioctl.c:43
>> [<ffff200008450c38>] do_vfs_ioctl+0x128/0xfc0 fs/ioctl.c:679
>> [< inline >] SYSC_ioctl fs/ioctl.c:694
>> [<ffff200008451b78>] SyS_ioctl+0xa8/0xb8 fs/ioctl.c:685
>> [<ffff200008083ef0>] el0_svc_naked+0x24/0x28 arch/arm64/kernel/entry.S:755
>
> Nice catch, and many thanks for reporting this.
>
> The bug is fairly obvious. Christoffer, what do you think? I don't think
> we need to hold the kvm->lock all the way, but I'd like another pair of
> eyes (the coffee machine is out of order again, and tea doesn't cut it).
>
> Thanks,
>
> M.
>
> From 93f80b20fb9351a49ee8b74eed3fc59c84651371 Mon Sep 17 00:00:00 2001
> From: Marc Zyngier <marc.zyngier@arm.com>
> Date: Thu, 12 Jan 2017 09:21:56 +0000
> Subject: [PATCH] KVM: arm/arm64: vgic: Fix deadlock on error handling
>
> Dmitry Vyukov reported that the syzkaller fuzzer triggered a
> deadlock in the vgic setup code when an error was detected, as
> the cleanup code tries to take a lock that is already held by
> the setup code.
>
> The fix is pretty obvious: move the cleaup call after having
> dropped the lock, since not much can happen at that point.
^^^^^^^^
Is that really true? If for instance the calls to
vgic_register_dist_iodev() or kvm_phys_addr_ioremap() in
vgic_v2_map_resources() fail, we leave the function with a half
initialized VGIC (because vgic_init() succeeded). Dropping the lock at
this point without having the GIC cleaned up before sounds a bit
suspicious (I may be wrong on this, though).
Can't we just document that kvm_vgic_destroy() needs to be called with
the kvm->lock held and take the lock around the only other caller
(kvm_arch_destroy_vm() in arch/arm/kvm/arm.c)?
We can then keep holding the lock in the map_resources calls.
Though we might still move the calls to kvm_vgic_destroy() into the
wrapper function as a cleanup (as shown below), just before dropping the
lock.
Cheers,
Andre.
> Cc: stable at vger.kernel.org
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
> virt/kvm/arm/vgic/vgic-init.c | 4 ++++
> virt/kvm/arm/vgic/vgic-v2.c | 2 --
> virt/kvm/arm/vgic/vgic-v3.c | 2 --
> 3 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
> index 5114391..0e0c295 100644
> --- a/virt/kvm/arm/vgic/vgic-init.c
> +++ b/virt/kvm/arm/vgic/vgic-init.c
> @@ -350,6 +350,10 @@ int kvm_vgic_map_resources(struct kvm *kvm)
> ret = vgic_v3_map_resources(kvm);
> out:
> mutex_unlock(&kvm->lock);
> +
> + if (ret)
> + kvm_vgic_destroy(kvm);
> +
> return ret;
> }
>
> diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c
> index 9bab867..834137e 100644
> --- a/virt/kvm/arm/vgic/vgic-v2.c
> +++ b/virt/kvm/arm/vgic/vgic-v2.c
> @@ -293,8 +293,6 @@ int vgic_v2_map_resources(struct kvm *kvm)
> dist->ready = true;
>
> out:
> - if (ret)
> - kvm_vgic_destroy(kvm);
> return ret;
> }
>
> diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
> index 7df1b90..a4c7fff 100644
> --- a/virt/kvm/arm/vgic/vgic-v3.c
> +++ b/virt/kvm/arm/vgic/vgic-v3.c
> @@ -308,8 +308,6 @@ int vgic_v3_map_resources(struct kvm *kvm)
> dist->ready = true;
>
> out:
> - if (ret)
> - kvm_vgic_destroy(kvm);
> return ret;
> }
>
>
^ permalink raw reply
* [PATCH 56/62] watchdog: tangox_wdt: Convert to use device managed functions
From: Uwe Kleine-König @ 2017-01-12 9:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <0f68aa11-161b-0435-ea0f-851432464bc1@sigmadesigns.com>
On Thu, Jan 12, 2017 at 10:44:07AM +0100, Marc Gonzalez wrote:
> On 11/01/2017 18:51, Guenter Roeck wrote:
>
> > However, some other unrelated undefined behavior does not mean that this
> > specific behavior is undefined.
>
> True :-)
>
> Let me just give two additional examples of UB that /have/ bitten
> Linux kernel devs.
>
> int i;
> for (i = 1; i > 0; ++i)
> /* do_something(); */
>
> => optimized into an infinite loop
>
> and
>
> void func(struct foo *p) {
> int n = p->field;
> if (!p) return;
>
> => null-pointer check optimized away
>
> > So far we have a claim that a cast to a void * may somehow be different
> > to a cast to a different pointer, if used as function argument, and that
> > the behavior with such a cast may be undefined. In other words, you claim
> > that a function implemented as, say,
> >
> > void func(int *var) {}
> >
> > might result in undefined behavior if some header file declares it as
> >
> > void func(void *);
> >
> > and it is called as
> >
> > int var;
> >
> > func(&var);
> >
> > That seems really far fetched to me.
>
> Thanks for giving me an opportunity to play the language lawyer :-)
>
> C99 6.3.2.3 sub-clause 8 states:
>
> "A pointer to a function of one type may be converted to a pointer to a function of another
> type and back again; the result shall compare equal to the original pointer. If a converted
> pointer is used to call a function whose type is not compatible with the pointed-to type,
> the behavior is undefined."
>
> So, the behavior is undefined, not when you cast clk_disable_unprepare,
> but when clk_disable_unprepare is later called through the devres->action
> function pointer.
>
> However, I agree that it will work as expected on typical platforms
> (where all pointers are the same size, and the calling convention
> treats all pointers the same).
>
> > I do get the message that you do not like this kind of cast. But that doesn't
> > mean it is not correct.
>
> If it's already widely used in the kernel, it seems there is no point
> fighting it ;-)
I'd say +.5 here (where +1 is an ack). My approach would be to push
devm_clk_prepare_enable and use that. It cannot be that hard, can it?
It looks prettier, is well defined, easier to fit into 80 chars per
line. I wonder why not everybody jubilates on this new function.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH v3 2/5] arm64: Work around Falkor erratum 1003
From: Catalin Marinas @ 2017-01-12 9:59 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170111183738.GD29247@leverpostej>
On Wed, Jan 11, 2017 at 06:37:39PM +0000, Mark Rutland wrote:
> On Wed, Jan 11, 2017 at 12:35:55PM -0600, Timur Tabi wrote:
> > On 01/11/2017 12:33 PM, Mark Rutland wrote:
> > >It'll need to affect all lines since the kconfig column needs to expand
> > >by at least one character to fit QCOM_FALKOR_ERRATUM_1003.
> >
> > Or we can make the macro shorter.
>
> The name, as it is, is perfectly descriptive.
>
> Let's not sacrifice legibility over a non-issue.
I agree, I didn't realise that the we expand the last column already.
It's a non-issue indeed.
--
Catalin
^ permalink raw reply
* [PATCH 0/2] Use data tune for CMD line tune
From: Yong Mao @ 2017-01-12 10:04 UTC (permalink / raw)
To: linux-arm-kernel
CMD response CRC error may cause cannot boot up
Change to use data tune for CMD line
Separate cmd internal delay for HS200/HS400 mode
yong mao (2):
mmc: mediatek: Use data tune for CMD line tune
mmc: dt-bindings: update Mediatek MMC bindings
Documentation/devicetree/bindings/mmc/mtk-sd.txt | 6 +
arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 3 +
drivers/mmc/host/mtk-sd.c | 169 ++++++++++++++++++++---
3 files changed, 155 insertions(+), 23 deletions(-)
--
1.8.1.1
^ permalink raw reply
* [PATCH 1/2] mmc: mediatek: Use data tune for CMD line tune
From: Yong Mao @ 2017-01-12 10:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1484215490-7494-1-git-send-email-yong.mao@mediatek.com>
From: yong mao <yong.mao@mediatek.com>
CMD response CRC error may cause cannot boot up
Change to use data tune for CMD line
Separate cmd internal delay for HS200/HS400 mode
Signed-off-by: Yong Mao <yong.mao@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 3 +
drivers/mmc/host/mtk-sd.c | 169 +++++++++++++++++++++++----
2 files changed, 149 insertions(+), 23 deletions(-)
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 0ecaad4..29c3100 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -134,6 +134,9 @@
bus-width = <8>;
max-frequency = <50000000>;
cap-mmc-highspeed;
+ hs200-cmd-int-delay = <26>;
+ hs400-cmd-int-delay = <14>;
+ cmd-resp-sel = <0>; /* 0: rising, 1: falling */
vmmc-supply = <&mt6397_vemc_3v3_reg>;
vqmmc-supply = <&mt6397_vio18_reg>;
non-removable;
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 80ba034..93eb395 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -75,6 +75,7 @@
#define MSDC_PATCH_BIT1 0xb4
#define MSDC_PAD_TUNE 0xec
#define PAD_DS_TUNE 0x188
+#define PAD_CMD_TUNE 0x18c
#define EMMC50_CFG0 0x208
/*--------------------------------------------------------------------------*/
@@ -210,12 +211,17 @@
#define MSDC_PATCH_BIT_SPCPUSH (0x1 << 29) /* RW */
#define MSDC_PATCH_BIT_DECRCTMO (0x1 << 30) /* RW */
-#define MSDC_PAD_TUNE_DATRRDLY (0x1f << 8) /* RW */
-#define MSDC_PAD_TUNE_CMDRDLY (0x1f << 16) /* RW */
+#define MSDC_PAD_TUNE_DATWRDLY (0x1f << 0) /* RW */
+#define MSDC_PAD_TUNE_DATRRDLY (0x1f << 8) /* RW */
+#define MSDC_PAD_TUNE_CMDRDLY (0x1f << 16) /* RW */
+#define MSDC_PAD_TUNE_CMDRRDLY (0x1f << 22) /* RW */
+#define MSDC_PAD_TUNE_CLKTDLY (0x1f << 27) /* RW */
-#define PAD_DS_TUNE_DLY1 (0x1f << 2) /* RW */
-#define PAD_DS_TUNE_DLY2 (0x1f << 7) /* RW */
-#define PAD_DS_TUNE_DLY3 (0x1f << 12) /* RW */
+#define PAD_DS_TUNE_DLY1 (0x1f << 2) /* RW */
+#define PAD_DS_TUNE_DLY2 (0x1f << 7) /* RW */
+#define PAD_DS_TUNE_DLY3 (0x1f << 12) /* RW */
+
+#define PAD_CMD_TUNE_RX_DLY3 (0x1f << 1) /* RW */
#define EMMC50_CFG_PADCMD_LATCHCK (0x1 << 0) /* RW */
#define EMMC50_CFG_CRCSTS_EDGE (0x1 << 3) /* RW */
@@ -236,7 +242,9 @@
#define CMD_TIMEOUT (HZ/10 * 5) /* 100ms x5 */
#define DAT_TIMEOUT (HZ * 5) /* 1000ms x5 */
-#define PAD_DELAY_MAX 32 /* PAD delay cells */
+#define PAD_DELAY_MAX 32 /* PAD delay cells */
+#define ENOUGH_MARGIN_MIN 12 /* Enough Margin */
+#define PREFER_START_POS_MAX 4 /* Prefer start position */
/*--------------------------------------------------------------------------*/
/* Descriptor Structure */
/*--------------------------------------------------------------------------*/
@@ -284,12 +292,14 @@ struct msdc_save_para {
u32 patch_bit0;
u32 patch_bit1;
u32 pad_ds_tune;
+ u32 pad_cmd_tune;
u32 emmc50_cfg0;
};
struct msdc_tune_para {
u32 iocon;
u32 pad_tune;
+ u32 pad_cmd_tune;
};
struct msdc_delay_phase {
@@ -331,6 +341,9 @@ struct msdc_host {
unsigned char timing;
bool vqmmc_enabled;
u32 hs400_ds_delay;
+ u32 hs200_cmd_int_delay; /* cmd internal delay for HS200/SDR104 */
+ u32 hs400_cmd_int_delay; /* cmd internal delay for HS400 */
+ u32 hs200_cmd_resp_sel; /* cmd response sample selection */
bool hs400_mode; /* current eMMC will run@hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -596,12 +609,21 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
*/
if (host->sclk <= 52000000) {
writel(host->def_tune_para.iocon, host->base + MSDC_IOCON);
- writel(host->def_tune_para.pad_tune, host->base + MSDC_PAD_TUNE);
+ writel(host->def_tune_para.pad_tune,
+ host->base + MSDC_PAD_TUNE);
} else {
- writel(host->saved_tune_para.iocon, host->base + MSDC_IOCON);
- writel(host->saved_tune_para.pad_tune, host->base + MSDC_PAD_TUNE);
+ writel(host->saved_tune_para.iocon,
+ host->base + MSDC_IOCON);
+ writel(host->saved_tune_para.pad_tune,
+ host->base + MSDC_PAD_TUNE);
+ writel(host->saved_tune_para.pad_cmd_tune,
+ host->base + PAD_CMD_TUNE);
}
+ if (timing == MMC_TIMING_MMC_HS400)
+ sdr_set_field(host->base + PAD_CMD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs400_cmd_int_delay);
dev_dbg(host->dev, "sclk: %d, timing: %d\n", host->sclk, timing);
}
@@ -1302,7 +1324,8 @@ static struct msdc_delay_phase get_best_delay(struct msdc_host *host, u32 delay)
len_final = len;
}
start += len ? len : 1;
- if (len >= 8 && start_final < 4)
+ if (len >= ENOUGH_MARGIN_MIN &&
+ start_final < PREFER_START_POS_MAX)
break;
}
@@ -1325,48 +1348,128 @@ static int msdc_tune_response(struct mmc_host *mmc, u32 opcode)
struct msdc_host *host = mmc_priv(mmc);
u32 rise_delay = 0, fall_delay = 0;
struct msdc_delay_phase final_rise_delay, final_fall_delay = { 0,};
+ struct msdc_delay_phase internal_delay_phase;
u8 final_delay, final_maxlen;
+ u32 internal_delay = 0;
int cmd_err;
- int i;
+ int i, j;
+ if (mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
+ mmc->ios.timing == MMC_TIMING_UHS_SDR104)
+ sdr_set_field(host->base + MSDC_PAD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs200_cmd_int_delay);
sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
for (i = 0 ; i < PAD_DELAY_MAX; i++) {
sdr_set_field(host->base + MSDC_PAD_TUNE,
MSDC_PAD_TUNE_CMDRDLY, i);
- mmc_send_tuning(mmc, opcode, &cmd_err);
- if (!cmd_err)
- rise_delay |= (1 << i);
+ for (j = 0; j < 3; j++) {
+ mmc_send_tuning(mmc, opcode, &cmd_err);
+ if (!cmd_err) {
+ rise_delay |= (1 << i);
+ } else {
+ rise_delay &= ~(1 << i);
+ break;
+ }
+ }
}
final_rise_delay = get_best_delay(host, rise_delay);
/* if rising edge has enough margin, then do not scan falling edge */
- if (final_rise_delay.maxlen >= 10 ||
- (final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4))
+ if (final_rise_delay.maxlen >= ENOUGH_MARGIN_MIN &&
+ final_rise_delay.start < PREFER_START_POS_MAX)
goto skip_fall;
sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
for (i = 0; i < PAD_DELAY_MAX; i++) {
sdr_set_field(host->base + MSDC_PAD_TUNE,
MSDC_PAD_TUNE_CMDRDLY, i);
- mmc_send_tuning(mmc, opcode, &cmd_err);
- if (!cmd_err)
- fall_delay |= (1 << i);
+ for (j = 0; j < 3; j++) {
+ mmc_send_tuning(mmc, opcode, &cmd_err);
+ if (!cmd_err) {
+ fall_delay |= (1 << i);
+ } else {
+ fall_delay &= ~(1 << i);
+ break;
+ };
+ }
}
final_fall_delay = get_best_delay(host, fall_delay);
skip_fall:
final_maxlen = max(final_rise_delay.maxlen, final_fall_delay.maxlen);
+ if (final_fall_delay.maxlen >= ENOUGH_MARGIN_MIN &&
+ final_fall_delay.start < PREFER_START_POS_MAX)
+ final_maxlen = final_fall_delay.maxlen;
if (final_maxlen == final_rise_delay.maxlen) {
sdr_clr_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
- sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY,
+ sdr_set_field(host->base + MSDC_PAD_TUNE,
+ MSDC_PAD_TUNE_CMDRDLY,
final_rise_delay.final_phase);
final_delay = final_rise_delay.final_phase;
} else {
sdr_set_bits(host->base + MSDC_IOCON, MSDC_IOCON_RSPL);
- sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRDLY,
+ sdr_set_field(host->base + MSDC_PAD_TUNE,
+ MSDC_PAD_TUNE_CMDRDLY,
final_fall_delay.final_phase);
final_delay = final_fall_delay.final_phase;
}
+ if (host->hs200_cmd_int_delay)
+ goto skip_internal;
+ for (i = 0; i < PAD_DELAY_MAX; i++) {
+ sdr_set_field(host->base + MSDC_PAD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY, i);
+ mmc_send_tuning(mmc, opcode, &cmd_err);
+ if (!cmd_err)
+ internal_delay |= (1 << i);
+ }
+ dev_info(host->dev, "Final internal delay: 0x%x\n", internal_delay);
+ internal_delay_phase = get_best_delay(host, internal_delay);
+ sdr_set_field(host->base + MSDC_PAD_TUNE, MSDC_PAD_TUNE_CMDRRDLY,
+ internal_delay_phase.final_phase);
+skip_internal:
+ dev_info(host->dev, "Final cmd pad delay: %x\n", final_delay);
+ return final_delay == 0xff ? -EIO : 0;
+}
+
+static int hs400_tune_response(struct mmc_host *mmc, u32 opcode)
+{
+ struct msdc_host *host = mmc_priv(mmc);
+ u32 cmd_delay = 0;
+ struct msdc_delay_phase final_cmd_delay = { 0,};
+ u8 final_delay;
+ int cmd_err;
+ int i, j;
+
+ /* select EMMC50 PAD CMD tune */
+ sdr_set_bits(host->base + PAD_CMD_TUNE, BIT(0));
+
+ if (mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
+ mmc->ios.timing == MMC_TIMING_UHS_SDR104)
+ sdr_set_field(host->base + MSDC_PAD_TUNE,
+ MSDC_PAD_TUNE_CMDRRDLY,
+ host->hs200_cmd_int_delay);
+ sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_RSPL,
+ host->hs200_cmd_resp_sel);
+ for (i = 0 ; i < PAD_DELAY_MAX; i++) {
+ sdr_set_field(host->base + PAD_CMD_TUNE,
+ PAD_CMD_TUNE_RX_DLY3, i);
+ for (j = 0; j < 3; j++) {
+ mmc_send_tuning(mmc, opcode, &cmd_err);
+ if (!cmd_err) {
+ cmd_delay |= (1 << i);
+ } else {
+ cmd_delay &= ~(1 << i);
+ break;
+ }
+ }
+ }
+ final_cmd_delay = get_best_delay(host, cmd_delay);
+ sdr_set_field(host->base + PAD_CMD_TUNE, PAD_CMD_TUNE_RX_DLY3,
+ final_cmd_delay.final_phase);
+ final_delay = final_cmd_delay.final_phase;
+
+ dev_info(host->dev, "Final cmd pad delay: %x\n", final_delay);
return final_delay == 0xff ? -EIO : 0;
}
@@ -1389,7 +1492,7 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
}
final_rise_delay = get_best_delay(host, rise_delay);
/* if rising edge has enough margin, then do not scan falling edge */
- if (final_rise_delay.maxlen >= 10 ||
+ if (final_rise_delay.maxlen >= ENOUGH_MARGIN_MIN ||
(final_rise_delay.start == 0 && final_rise_delay.maxlen >= 4))
goto skip_fall;
@@ -1422,6 +1525,7 @@ static int msdc_tune_data(struct mmc_host *mmc, u32 opcode)
final_delay = final_fall_delay.final_phase;
}
+ dev_info(host->dev, "Final data pad delay: %x\n", final_delay);
return final_delay == 0xff ? -EIO : 0;
}
@@ -1430,10 +1534,13 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
struct msdc_host *host = mmc_priv(mmc);
int ret;
+ if (host->hs400_mode)
+ ret = hs400_tune_response(mmc, opcode);
+ else
ret = msdc_tune_response(mmc, opcode);
if (ret == -EIO) {
dev_err(host->dev, "Tune response fail!\n");
- return ret;
+ goto out;
}
if (host->hs400_mode == false) {
ret = msdc_tune_data(mmc, opcode);
@@ -1443,6 +1550,8 @@ static int msdc_execute_tuning(struct mmc_host *mmc, u32 opcode)
host->saved_tune_para.iocon = readl(host->base + MSDC_IOCON);
host->saved_tune_para.pad_tune = readl(host->base + MSDC_PAD_TUNE);
+ host->saved_tune_para.pad_cmd_tune = readl(host->base + PAD_CMD_TUNE);
+out:
return ret;
}
@@ -1553,6 +1662,18 @@ static int msdc_drv_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "hs400-ds-delay: %x\n",
host->hs400_ds_delay);
+ if (!of_property_read_u32(pdev->dev.of_node, "hs200-cmd-int-delay",
+ &host->hs200_cmd_int_delay))
+ dev_dbg(&pdev->dev, "host->hs200-cmd-int-delay: %x\n",
+ host->hs200_cmd_int_delay);
+ if (!of_property_read_u32(pdev->dev.of_node, "hs400-cmd-int-delay",
+ &host->hs400_cmd_int_delay))
+ dev_dbg(&pdev->dev, "host->hs400-cmd-int-delay: %x\n",
+ host->hs400_cmd_int_delay);
+ if (!of_property_read_u32(pdev->dev.of_node, "cmd-resp-sel",
+ &host->hs200_cmd_resp_sel))
+ dev_dbg(&pdev->dev, "host->hs200_cmd-resp-sel: %x\n",
+ host->hs200_cmd_resp_sel);
host->dev = &pdev->dev;
host->mmc = mmc;
host->src_clk_freq = clk_get_rate(host->src_clk);
@@ -1663,6 +1784,7 @@ static void msdc_save_reg(struct msdc_host *host)
host->save_para.patch_bit0 = readl(host->base + MSDC_PATCH_BIT);
host->save_para.patch_bit1 = readl(host->base + MSDC_PATCH_BIT1);
host->save_para.pad_ds_tune = readl(host->base + PAD_DS_TUNE);
+ host->save_para.pad_cmd_tune = readl(host->base + PAD_CMD_TUNE);
host->save_para.emmc50_cfg0 = readl(host->base + EMMC50_CFG0);
}
@@ -1675,6 +1797,7 @@ static void msdc_restore_reg(struct msdc_host *host)
writel(host->save_para.patch_bit0, host->base + MSDC_PATCH_BIT);
writel(host->save_para.patch_bit1, host->base + MSDC_PATCH_BIT1);
writel(host->save_para.pad_ds_tune, host->base + PAD_DS_TUNE);
+ writel(host->save_para.pad_cmd_tune, host->base + PAD_CMD_TUNE);
writel(host->save_para.emmc50_cfg0, host->base + EMMC50_CFG0);
}
--
1.7.9.5
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox